summaryrefslogtreecommitdiff
path: root/chromium/net
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net')
-rw-r--r--chromium/net/BUILD.gn176
-rw-r--r--chromium/net/DEPS22
-rw-r--r--chromium/net/OWNERS7
-rw-r--r--chromium/net/android/BUILD.gn89
-rw-r--r--chromium/net/android/android_private_key.cc25
-rw-r--r--chromium/net/android/android_private_key.h27
-rw-r--r--chromium/net/android/dummy_spnego_authenticator.cc16
-rw-r--r--chromium/net/android/dummy_spnego_authenticator.h19
-rw-r--r--chromium/net/android/http_auth_negotiate_android.cc21
-rw-r--r--chromium/net/android/http_auth_negotiate_android.h15
-rw-r--r--chromium/net/android/http_auth_negotiate_android_unittest.cc26
-rw-r--r--chromium/net/android/keystore.cc41
-rw-r--r--chromium/net/android/keystore.h2
-rw-r--r--chromium/net/android/keystore_openssl.cc77
-rw-r--r--chromium/net/android/keystore_unittest.cc2
-rw-r--r--chromium/net/android/network_change_notifier_android.cc68
-rw-r--r--chromium/net/android/network_change_notifier_android.h13
-rw-r--r--chromium/net/android/network_change_notifier_android_unittest.cc291
-rw-r--r--chromium/net/android/network_change_notifier_delegate_android.cc210
-rw-r--r--chromium/net/android/network_change_notifier_delegate_android.h83
-rw-r--r--chromium/net/android/network_library.cc1
-rw-r--r--chromium/net/android/network_library.h1
-rw-r--r--chromium/net/android/traffic_stats_unittest.cc8
-rw-r--r--chromium/net/base/address_family.cc36
-rw-r--r--chromium/net/base/address_family.h9
-rw-r--r--chromium/net/base/address_family_unittest.cc22
-rw-r--r--chromium/net/base/address_list.cc12
-rw-r--r--chromium/net/base/address_list.h9
-rw-r--r--chromium/net/base/address_list_unittest.cc2
-rw-r--r--chromium/net/base/address_tracker_linux.cc18
-rw-r--r--chromium/net/base/address_tracker_linux.h10
-rw-r--r--chromium/net/base/address_tracker_linux_unittest.cc54
-rw-r--r--chromium/net/base/backoff_entry.cc13
-rw-r--r--chromium/net/base/backoff_entry.h2
-rw-r--r--chromium/net/base/backoff_entry_serializer.cc4
-rw-r--r--chromium/net/base/chunked_upload_data_stream.cc9
-rw-r--r--chromium/net/base/chunked_upload_data_stream.h6
-rw-r--r--chromium/net/base/completion_callback.h2
-rw-r--r--chromium/net/base/crypto_module.h1
-rw-r--r--chromium/net/base/data_url.cc1
-rw-r--r--chromium/net/base/data_url_unittest.cc1
-rw-r--r--chromium/net/base/directory_lister.cc9
-rw-r--r--chromium/net/base/directory_listing.cc (renamed from chromium/net/base/net_util_icu.cc)27
-rw-r--r--chromium/net/base/directory_listing.h44
-rw-r--r--chromium/net/base/directory_listing_unittest.cc (renamed from chromium/net/base/net_util_icu_unittest.cc)9
-rw-r--r--chromium/net/base/elements_upload_data_stream.cc27
-rw-r--r--chromium/net/base/elements_upload_data_stream.h17
-rw-r--r--chromium/net/base/elements_upload_data_stream_unittest.cc232
-rw-r--r--chromium/net/base/escape.h3
-rw-r--r--chromium/net/base/escape_unittest.cc1
-rw-r--r--chromium/net/base/expiring_cache.h4
-rw-r--r--chromium/net/base/file_stream.cc5
-rw-r--r--chromium/net/base/file_stream.h3
-rw-r--r--chromium/net/base/file_stream_context.cc24
-rw-r--r--chromium/net/base/file_stream_context.h10
-rw-r--r--chromium/net/base/file_stream_context_posix.cc7
-rw-r--r--chromium/net/base/file_stream_unittest.cc26
-rw-r--r--chromium/net/base/filename_util_internal.cc89
-rw-r--r--chromium/net/base/filename_util_unittest.cc649
-rw-r--r--chromium/net/base/hash_value.cc22
-rw-r--r--chromium/net/base/hash_value.h16
-rw-r--r--chromium/net/base/host_mapping_rules.h3
-rw-r--r--chromium/net/base/host_port_pair.h9
-rw-r--r--chromium/net/base/int128.cc10
-rw-r--r--chromium/net/base/int128.h101
-rw-r--r--chromium/net/base/int128_unittest.cc17
-rw-r--r--chromium/net/base/io_buffer.h2
-rw-r--r--chromium/net/base/iovec.h2
-rw-r--r--chromium/net/base/ip_address.cc73
-rw-r--r--chromium/net/base/ip_address.h94
-rw-r--r--chromium/net/base/ip_address_number.cc2
-rw-r--r--chromium/net/base/ip_address_number.h11
-rw-r--r--chromium/net/base/ip_address_number_unittest.cc2
-rw-r--r--chromium/net/base/ip_address_unittest.cc150
-rw-r--r--chromium/net/base/ip_endpoint.cc85
-rw-r--r--chromium/net/base/ip_endpoint.h7
-rw-r--r--chromium/net/base/ip_endpoint_unittest.cc40
-rw-r--r--chromium/net/base/ip_pattern.cc7
-rw-r--r--chromium/net/base/ip_pattern.h9
-rw-r--r--chromium/net/base/keygen_handler_nss.cc6
-rw-r--r--chromium/net/base/keygen_handler_unittest.cc9
-rw-r--r--chromium/net/base/keygen_handler_win.cc3
-rw-r--r--chromium/net/base/layered_network_delegate.cc38
-rw-r--r--chromium/net/base/layered_network_delegate.h15
-rw-r--r--chromium/net/base/layered_network_delegate_unittest.cc22
-rw-r--r--chromium/net/base/linked_hash_map.h2
-rw-r--r--chromium/net/base/load_timing_info.h3
-rw-r--r--chromium/net/base/lookup_string_in_fixed_set.cc152
-rw-r--r--chromium/net/base/lookup_string_in_fixed_set.h40
-rw-r--r--chromium/net/base/lookup_string_in_fixed_set_unittest.cc162
-rw-r--r--chromium/net/base/mime_sniffer.h2
-rw-r--r--chromium/net/base/mime_util.cc177
-rw-r--r--chromium/net/base/mime_util.h6
-rw-r--r--chromium/net/base/mime_util_unittest.cc29
-rw-r--r--chromium/net/base/mock_file_stream.cc7
-rw-r--r--chromium/net/base/mock_file_stream.h3
-rw-r--r--chromium/net/base/net_error_details.h30
-rw-r--r--chromium/net/base/net_error_list.h11
-rw-r--r--chromium/net/base/net_errors.h1
-rw-r--r--chromium/net/base/net_module.h2
-rw-r--r--chromium/net/base/net_util.cc262
-rw-r--r--chromium/net/base/net_util.h175
-rw-r--r--chromium/net/base/net_util_unittest.cc211
-rw-r--r--chromium/net/base/network_activity_monitor.h4
-rw-r--r--chromium/net/base/network_change_notifier.cc111
-rw-r--r--chromium/net/base/network_change_notifier.h109
-rw-r--r--chromium/net/base/network_change_notifier_linux.cc1
-rw-r--r--chromium/net/base/network_change_notifier_linux.h2
-rw-r--r--chromium/net/base/network_change_notifier_mac.cc4
-rw-r--r--chromium/net/base/network_change_notifier_mac.h2
-rw-r--r--chromium/net/base/network_change_notifier_win.cc3
-rw-r--r--chromium/net/base/network_change_notifier_win.h2
-rw-r--r--chromium/net/base/network_change_notifier_win_unittest.cc10
-rw-r--r--chromium/net/base/network_config_watcher_mac.cc1
-rw-r--r--chromium/net/base/network_config_watcher_mac.h2
-rw-r--r--chromium/net/base/network_delegate.cc18
-rw-r--r--chromium/net/base/network_delegate.h42
-rw-r--r--chromium/net/base/network_delegate_impl.cc12
-rw-r--r--chromium/net/base/network_delegate_impl.h18
-rw-r--r--chromium/net/base/network_interfaces.h46
-rw-r--r--chromium/net/base/network_interfaces_unittest.cc5
-rw-r--r--chromium/net/base/network_interfaces_win.cc42
-rw-r--r--chromium/net/base/network_interfaces_win.h1
-rw-r--r--chromium/net/base/network_quality_estimator.cc71
-rw-r--r--chromium/net/base/network_quality_estimator.h12
-rw-r--r--chromium/net/base/network_quality_estimator_unittest.cc42
-rw-r--r--chromium/net/base/openssl_private_key_store.h2
-rw-r--r--chromium/net/base/openssl_private_key_store_memory.cc1
-rw-r--r--chromium/net/base/port_util.h4
-rw-r--r--chromium/net/base/prioritized_dispatcher.h3
-rw-r--r--chromium/net/base/prioritized_dispatcher_unittest.cc122
-rw-r--r--chromium/net/base/priority_queue.h5
-rw-r--r--chromium/net/base/registry_controlled_domains/BUILD.gn2
-rw-r--r--chromium/net/base/registry_controlled_domains/effective_tld_names.dat99
-rw-r--r--chromium/net/base/registry_controlled_domains/effective_tld_names.gperf52
-rw-r--r--chromium/net/base/registry_controlled_domains/registry_controlled_domain.cc149
-rw-r--r--chromium/net/base/registry_controlled_domains/registry_controlled_domain.h3
-rw-r--r--chromium/net/base/sdch_dictionary.h2
-rw-r--r--chromium/net/base/sdch_manager.cc50
-rw-r--r--chromium/net/base/sdch_manager.h5
-rw-r--r--chromium/net/base/sdch_manager_unittest.cc5
-rw-r--r--chromium/net/base/sdch_net_log_params.cc6
-rw-r--r--chromium/net/base/sockaddr_storage.cc27
-rw-r--r--chromium/net/base/sockaddr_storage.h35
-rw-r--r--chromium/net/base/socket_performance_watcher.cc34
-rw-r--r--chromium/net/base/socket_performance_watcher.h25
-rw-r--r--chromium/net/base/socket_performance_watcher_factory.h35
-rw-r--r--chromium/net/base/stale_while_revalidate_experiment_domains.cc74
-rw-r--r--chromium/net/base/stale_while_revalidate_experiment_domains.gperf116
-rw-r--r--chromium/net/base/stale_while_revalidate_experiment_domains.h24
-rw-r--r--chromium/net/base/stale_while_revalidate_experiment_domains_unittest.cc63
-rw-r--r--chromium/net/base/static_cookie_policy.h2
-rw-r--r--chromium/net/base/sys_addrinfo.h1
-rw-r--r--chromium/net/base/test_completion_callback.h3
-rw-r--r--chromium/net/base/test_completion_callback_unittest.cc1
-rw-r--r--chromium/net/base/upload_bytes_element_reader.cc4
-rw-r--r--chromium/net/base/upload_bytes_element_reader.h4
-rw-r--r--chromium/net/base/upload_bytes_element_reader_unittest.cc1
-rw-r--r--chromium/net/base/upload_data_stream.cc2
-rw-r--r--chromium/net/base/upload_data_stream.h11
-rw-r--r--chromium/net/base/upload_element_reader.h4
-rw-r--r--chromium/net/base/upload_file_element_reader.h3
-rw-r--r--chromium/net/base/upload_file_element_reader_unittest.cc20
-rw-r--r--chromium/net/base/upload_progress.h2
-rw-r--r--chromium/net/base/url_util.cc21
-rw-r--r--chromium/net/base/url_util.h14
-rw-r--r--chromium/net/base/url_util_unittest.cc77
-rw-r--r--chromium/net/base/winsock_util.h4
-rw-r--r--chromium/net/base/zap.cc2
-rw-r--r--chromium/net/base/zap.h3
-rw-r--r--chromium/net/cert/asn1_util.cc285
-rw-r--r--chromium/net/cert/asn1_util.h44
-rw-r--r--chromium/net/cert/cert_database_nss.cc33
-rw-r--r--chromium/net/cert/cert_net_fetcher.h3
-rw-r--r--chromium/net/cert/cert_verifier.cc3
-rw-r--r--chromium/net/cert/cert_verify_proc.cc102
-rw-r--r--chromium/net/cert/cert_verify_proc.h1
-rw-r--r--chromium/net/cert/cert_verify_proc_android.cc2
-rw-r--r--chromium/net/cert/cert_verify_proc_mac.cc79
-rw-r--r--chromium/net/cert/cert_verify_proc_nss.cc5
-rw-r--r--chromium/net/cert/cert_verify_proc_openssl.cc2
-rw-r--r--chromium/net/cert/cert_verify_proc_unittest.cc163
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist.cc492
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist.h1
-rw-r--r--chromium/net/cert/cert_verify_proc_win.cc12
-rw-r--r--chromium/net/cert/cert_verify_result.cc1
-rw-r--r--chromium/net/cert/cert_verify_result.h1
-rw-r--r--chromium/net/cert/crl_set.h3
-rw-r--r--chromium/net/cert/ct_known_logs.cc43
-rw-r--r--chromium/net/cert/ct_known_logs.h8
-rw-r--r--chromium/net/cert/ct_known_logs_static.h13
-rw-r--r--chromium/net/cert/ct_log_response_parser.cc52
-rw-r--r--chromium/net/cert/ct_log_response_parser.h7
-rw-r--r--chromium/net/cert/ct_log_response_parser_unittest.cc51
-rw-r--r--chromium/net/cert/ct_log_verifier.cc141
-rw-r--r--chromium/net/cert/ct_log_verifier.h34
-rw-r--r--chromium/net/cert/ct_log_verifier_nss.cc2
-rw-r--r--chromium/net/cert/ct_log_verifier_openssl.cc2
-rw-r--r--chromium/net/cert/ct_log_verifier_unittest.cc427
-rw-r--r--chromium/net/cert/ct_log_verifier_util.cc36
-rw-r--r--chromium/net/cert/ct_log_verifier_util.h30
-rw-r--r--chromium/net/cert/ct_objects_extractor_nss.cc14
-rw-r--r--chromium/net/cert/ct_objects_extractor_unittest.cc4
-rw-r--r--chromium/net/cert/ct_policy_enforcer.cc (renamed from chromium/net/cert/cert_policy_enforcer.cc)65
-rw-r--r--chromium/net/cert/ct_policy_enforcer.h (renamed from chromium/net/cert/cert_policy_enforcer.h)12
-rw-r--r--chromium/net/cert/ct_policy_enforcer_unittest.cc (renamed from chromium/net/cert/cert_policy_enforcer_unittest.cc)106
-rw-r--r--chromium/net/cert/ct_serialization.cc4
-rw-r--r--chromium/net/cert/ct_serialization_unittest.cc2
-rw-r--r--chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc5
-rw-r--r--chromium/net/cert/ct_verifier.h3
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.cc5
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.h1
-rw-r--r--chromium/net/cert/internal/certificate_policies.cc178
-rw-r--r--chromium/net/cert/internal/certificate_policies.h36
-rw-r--r--chromium/net/cert/internal/certificate_policies_unittest.cc150
-rw-r--r--chromium/net/cert/internal/name_constraints.cc569
-rw-r--r--chromium/net/cert/internal/name_constraints.h138
-rw-r--r--chromium/net/cert/internal/name_constraints_unittest.cc1276
-rw-r--r--chromium/net/cert/internal/parse_certificate.cc247
-rw-r--r--chromium/net/cert/internal/parse_certificate.h156
-rw-r--r--chromium/net/cert/internal/parse_certificate_unittest.cc493
-rw-r--r--chromium/net/cert/internal/signature_algorithm.cc37
-rw-r--r--chromium/net/cert/internal/signature_algorithm.h8
-rw-r--r--chromium/net/cert/internal/signature_algorithm_unittest.cc100
-rw-r--r--chromium/net/cert/internal/signature_policy.h2
-rw-r--r--chromium/net/cert/internal/test_helpers.cc16
-rw-r--r--chromium/net/cert/internal/test_helpers.h12
-rw-r--r--chromium/net/cert/internal/verify_certificate_chain.cc549
-rw-r--r--chromium/net/cert/internal/verify_certificate_chain.h86
-rw-r--r--chromium/net/cert/internal/verify_certificate_chain_unittest.cc246
-rw-r--r--chromium/net/cert/internal/verify_name_match.cc73
-rw-r--r--chromium/net/cert/internal/verify_name_match.h20
-rw-r--r--chromium/net/cert/internal/verify_name_match_unittest.cc100
-rw-r--r--chromium/net/cert/internal/verify_signed_data_unittest.cc13
-rw-r--r--chromium/net/cert/jwk_serializer_nss.cc6
-rw-r--r--chromium/net/cert/jwk_serializer_openssl.cc8
-rw-r--r--chromium/net/cert/jwk_serializer_unittest.cc33
-rw-r--r--chromium/net/cert/merkle_consistency_proof.cc27
-rw-r--r--chromium/net/cert/merkle_consistency_proof.h45
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.cc2
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.h10
-rw-r--r--chromium/net/cert/multi_log_ct_verifier_unittest.cc4
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.cc41
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.h6
-rw-r--r--chromium/net/cert/nss_cert_database.cc18
-rw-r--r--chromium/net/cert/nss_cert_database.h6
-rw-r--r--chromium/net/cert/nss_cert_database_chromeos.cc8
-rw-r--r--chromium/net/cert/nss_cert_database_chromeos.h1
-rw-r--r--chromium/net/cert/nss_profile_filter_chromeos.cc8
-rw-r--r--chromium/net/cert/nss_profile_filter_chromeos_unittest.cc6
-rw-r--r--chromium/net/cert/pem_tokenizer.h3
-rw-r--r--chromium/net/cert/signed_certificate_timestamp.h1
-rw-r--r--chromium/net/cert/signed_tree_head.h2
-rw-r--r--chromium/net/cert/test_root_certs.h1
-rw-r--r--chromium/net/cert/test_root_certs_nss.cc1
-rw-r--r--chromium/net/cert/test_root_certs_win.cc6
-rw-r--r--chromium/net/cert/x509_cert_types.h1
-rw-r--r--chromium/net/cert/x509_certificate.cc8
-rw-r--r--chromium/net/cert/x509_certificate.h19
-rw-r--r--chromium/net/cert/x509_certificate_ios.cc16
-rw-r--r--chromium/net/cert/x509_certificate_known_roots_mac.h560
-rw-r--r--chromium/net/cert/x509_certificate_known_roots_win.h2701
-rw-r--r--chromium/net/cert/x509_certificate_mac.cc11
-rw-r--r--chromium/net/cert/x509_certificate_net_log_param.cc5
-rw-r--r--chromium/net/cert/x509_certificate_nss.cc20
-rw-r--r--chromium/net/cert/x509_certificate_openssl.cc18
-rw-r--r--chromium/net/cert/x509_certificate_unittest.cc2
-rw-r--r--chromium/net/cert/x509_certificate_win.cc22
-rw-r--r--chromium/net/cert/x509_util.h9
-rw-r--r--chromium/net/cert/x509_util_android.cc12
-rw-r--r--chromium/net/cert/x509_util_nss.cc13
-rw-r--r--chromium/net/cert/x509_util_nss.h4
-rw-r--r--chromium/net/cert/x509_util_nss_certs.cc10
-rw-r--r--chromium/net/cert/x509_util_openssl.cc35
-rw-r--r--chromium/net/cert/x509_util_openssl_unittest.cc41
-rw-r--r--chromium/net/cert_net/cert_net_fetcher_impl.cc29
-rw-r--r--chromium/net/cert_net/cert_net_fetcher_impl.h1
-rw-r--r--chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc78
-rw-r--r--chromium/net/cert_net/nss_ocsp.cc14
-rw-r--r--chromium/net/cert_net/nss_ocsp_unittest.cc6
-rw-r--r--chromium/net/cookies/canonical_cookie.cc90
-rw-r--r--chromium/net/cookies/canonical_cookie.h43
-rw-r--r--chromium/net/cookies/canonical_cookie_unittest.cc334
-rw-r--r--chromium/net/cookies/cookie_constants_unittest.cc2
-rw-r--r--chromium/net/cookies/cookie_monster.cc251
-rw-r--r--chromium/net/cookies/cookie_monster.h98
-rw-r--r--chromium/net/cookies/cookie_monster_perftest.cc4
-rw-r--r--chromium/net/cookies/cookie_monster_store_test.cc35
-rw-r--r--chromium/net/cookies/cookie_monster_store_test.h23
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc1101
-rw-r--r--chromium/net/cookies/cookie_options.cc3
-rw-r--r--chromium/net/cookies/cookie_options.h36
-rw-r--r--chromium/net/cookies/cookie_store.h1
-rw-r--r--chromium/net/cookies/cookie_store_test_callbacks.cc4
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.cc41
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.h21
-rw-r--r--chromium/net/cookies/cookie_store_unittest.h439
-rw-r--r--chromium/net/cookies/cookie_util.cc15
-rw-r--r--chromium/net/cookies/cookie_util_unittest.cc1
-rw-r--r--chromium/net/cookies/parsed_cookie.h4
-rw-r--r--chromium/net/data/certificate_policies_unittest/anypolicy.pem6
-rw-r--r--chromium/net/data/certificate_policies_unittest/anypolicy_with_qualifier.pem10
-rwxr-xr-xchromium/net/data/certificate_policies_unittest/generate_policies.py176
-rw-r--r--chromium/net/data/certificate_policies_unittest/invalid-anypolicy_with_custom_qualifier.pem10
-rw-r--r--chromium/net/data/certificate_policies_unittest/invalid-empty.pem4
-rw-r--r--chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_dupe.pem12
-rw-r--r--chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyinformation_unconsumed_data.pem7
-rw-r--r--chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyqualifierinfo_unconsumed_data.pem12
-rw-r--r--chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_with_empty_qualifiers_sequence.pem7
-rw-r--r--chromium/net/data/certificate_policies_unittest/invalid-policy_identifier_not_oid.pem6
-rw-r--r--chromium/net/data/certificate_policies_unittest/policy_1_2_3.pem6
-rw-r--r--chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4.pem8
-rw-r--r--chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4_with_qualifiers.pem17
-rw-r--r--chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_custom_qualifier.pem10
-rw-r--r--chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_qualifier.pem10
-rw-r--r--chromium/net/data/filter_unittests/google.brbin0 -> 1041 bytes
-rw-r--r--chromium/net/data/ftp/dir-listing-ls-334
-rw-r--r--chromium/net/data/ftp/dir-listing-ls-33.expected26
-rw-r--r--chromium/net/data/name_constraints_unittest/directoryname-excludeall.pem14
-rw-r--r--chromium/net/data/name_constraints_unittest/directoryname-excluded.pem15
-rw-r--r--chromium/net/data/name_constraints_unittest/directoryname.pem55
-rw-r--r--chromium/net/data/name_constraints_unittest/directoryname_and_dnsname.pem73
-rw-r--r--chromium/net/data/name_constraints_unittest/directoryname_and_dnsname_and_ipaddress.pem97
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-exclude_dot.pem10
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-excludeall.pem10
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-excluded.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-permitted_with_leading_dot.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-with_max.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-with_min_0.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-with_min_0_and_max.pem9
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-with_min_1.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname-with_min_1_and_max.pem9
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname.pem24
-rw-r--r--chromium/net/data/name_constraints_unittest/dnsname2.pem10
-rw-r--r--chromium/net/data/name_constraints_unittest/edipartyname-excluded.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/edipartyname-permitted.pem8
-rwxr-xr-xchromium/net/data/name_constraints_unittest/generate_name_constraints.py533
-rw-r--r--chromium/net/data/name_constraints_unittest/invalid-empty_excluded_subtree.pem5
-rw-r--r--chromium/net/data/name_constraints_unittest/invalid-empty_permitted_subtree.pem5
-rw-r--r--chromium/net/data/name_constraints_unittest/invalid-no_subtrees.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-excludeall.pem15
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-excluded.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-invalid_addr.pem9
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_1.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_2.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_3.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_4.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-permit_all.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix1.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix31.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress-permit_singlehost.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/ipaddress.pem30
-rw-r--r--chromium/net/data/name_constraints_unittest/name-ca.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/name-de.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/name-empty.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/name-jp-tokyo.pem12
-rw-r--r--chromium/net/data/name_constraints_unittest/name-jp.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-arizona-1.1.1.1.pem16
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-arizona-192.168.1.1.pem16
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-arizona-email.pem17
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-arizona-foo.com.pem16
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-arizona-ipv6.pem17
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-arizona-permitted.example.com.pem17
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-arizona.pem12
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-california-192.168.1.1.pem17
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-california-mountain_view.pem17
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-california-permitted.example.com.pem17
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us-california.pem12
-rw-r--r--chromium/net/data/name_constraints_unittest/name-us.pem8
-rw-r--r--chromium/net/data/name_constraints_unittest/othername-excluded.pem9
-rw-r--r--chromium/net/data/name_constraints_unittest/othername-permitted.pem9
-rw-r--r--chromium/net/data/name_constraints_unittest/registeredid-excluded.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/registeredid-permitted.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/rfc822name-excluded.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/rfc822name-permitted.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/san-edipartyname.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/san-excluded-directoryname.pem6
-rw-r--r--chromium/net/data/name_constraints_unittest/san-excluded-dnsname.pem6
-rw-r--r--chromium/net/data/name_constraints_unittest/san-excluded-ipaddress.pem5
-rw-r--r--chromium/net/data/name_constraints_unittest/san-invalid-empty.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/san-invalid-ipaddress.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/san-othername.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/san-permitted.pem5
-rw-r--r--chromium/net/data/name_constraints_unittest/san-registeredid.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/san-rfc822name.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/san-uri.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/san-x400address.pem4
-rw-r--r--chromium/net/data/name_constraints_unittest/uri-excluded.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/uri-permitted.pem7
-rw-r--r--chromium/net/data/name_constraints_unittest/x400address-excluded.pem10
-rw-r--r--chromium/net/data/name_constraints_unittest/x400address-permitted.pem10
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_ca_false.pem7
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_ca_no_path.pem7
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_ca_path_9.pem8
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_negative_path.pem8
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_not_ca.pem6
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_path_too_large.pem8
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_255.pem8
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_256.pem8
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_not_ca.pem7
-rw-r--r--chromium/net/data/parse_certificate_unittest/basic_constraints_unconsumed_data.pem7
-rw-r--r--chromium/net/data/parse_certificate_unittest/extension_critical.pem12
-rw-r--r--chromium/net/data/parse_certificate_unittest/extension_critical_0.pem15
-rw-r--r--chromium/net/data/parse_certificate_unittest/extension_critical_3.pem15
-rw-r--r--chromium/net/data/parse_certificate_unittest/extension_not_critical.pem12
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_basic_constraints.pem16
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_data_after_sequence.pem11
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_duplicate_key_usage.pem14
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_empty_sequence.pem6
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_extended_key_usage.pem20
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_key_usage.pem16
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_not_sequence.pem6
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_policies.pem25
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_real.pem35
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_subject_alt_name.pem16
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_unknown_critical.pem10
-rw-r--r--chromium/net/data/parse_certificate_unittest/extensions_unknown_non_critical.pem9
-rw-r--r--chromium/net/data/ssl/certificates/README8
-rw-r--r--chromium/net/data/ssl/certificates/large_key.pem278
-rw-r--r--chromium/net/data/ssl/certificates/name_constraint_bad.pem152
-rw-r--r--chromium/net/data/ssl/certificates/name_constraint_good.pem161
-rw-r--r--chromium/net/data/ssl/certificates/quic_test.example.com.key.sct1
-rw-r--r--chromium/net/data/ssl/certificates/sha1_dec_2015.pem82
-rw-r--r--chromium/net/data/ssl/certificates/sha1_jan_2016.pem82
-rw-r--r--chromium/net/data/ssl/certificates/wildcard.pem110
-rw-r--r--chromium/net/data/ssl/scripts/ca.cnf2
-rw-r--r--chromium/net/data/ssl/scripts/ee.cnf6
-rwxr-xr-xchromium/net/data/ssl/scripts/generate-test-certs.sh48
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/README29
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem370
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/common.py417
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/expired-intermediary.pem280
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem280
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/expired-target.pem280
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-all.sh16
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py35
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-expired-intermediary.py29
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py28
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-expired-target.py28
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-ca-false.py28
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-not-critical.py28
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-basic-constraints.py27
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-signing-key-usage.py28
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-intermediary-signed-with-md5.py27
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-critical-extension.py29
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-non-critical-extension.py28
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-and-intermediary.py25
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py30
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py29
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py26
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py27
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py26
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py26
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py29
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py32
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-unknown-root.py26
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py34
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-ca-false.pem281
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-not-critical.pem282
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-basic-constraints.pem278
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-signing-key-usage.pem281
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/intermediary-signed-with-md5.pem281
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-critical-extension.pem284
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-non-critical-extension.pem284
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem284
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem464
-rwxr-xr-xchromium/net/data/verify_certificate_chain_unittest/openssl_conf.py136
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-and-intermediary.pem280
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem282
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem283
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem280
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem248
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem252
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem280
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem284
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem281
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/unknown-root.pem192
-rw-r--r--chromium/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem370
-rwxr-xr-xchromium/net/data/verify_name_match_unittest/scripts/generate_names.py (renamed from chromium/net/data/verify_name_match_unittest/scripts/generate-names.py)10
-rw-r--r--chromium/net/der/input.cc17
-rw-r--r--chromium/net/der/input.h27
-rw-r--r--chromium/net/der/input_unittest.cc14
-rw-r--r--chromium/net/der/parse_values.cc54
-rw-r--r--chromium/net/der/parse_values.h15
-rw-r--r--chromium/net/der/parse_values_unittest.cc50
-rw-r--r--chromium/net/der/parser.h5
-rw-r--r--chromium/net/der/tag.cc8
-rw-r--r--chromium/net/der/tag.h6
-rw-r--r--chromium/net/disk_cache/backend_unittest.cc107
-rw-r--r--chromium/net/disk_cache/blockfile/addr.h33
-rw-r--r--chromium/net/disk_cache/blockfile/addr_unittest.cc2
-rw-r--r--chromium/net/disk_cache/blockfile/backend_impl.cc125
-rw-r--r--chromium/net/disk_cache/blockfile/backend_impl.h34
-rw-r--r--chromium/net/disk_cache/blockfile/backend_impl_v3.cc77
-rw-r--r--chromium/net/disk_cache/blockfile/backend_impl_v3.h22
-rw-r--r--chromium/net/disk_cache/blockfile/backend_worker_v3.cc10
-rw-r--r--chromium/net/disk_cache/blockfile/backend_worker_v3.h1
-rw-r--r--chromium/net/disk_cache/blockfile/bitmap.cc33
-rw-r--r--chromium/net/disk_cache/blockfile/bitmap.h21
-rw-r--r--chromium/net/disk_cache/blockfile/bitmap_unittest.cc6
-rw-r--r--chromium/net/disk_cache/blockfile/block_bitmaps_v3.cc2
-rw-r--r--chromium/net/disk_cache/blockfile/block_bitmaps_v3.h1
-rw-r--r--chromium/net/disk_cache/blockfile/block_bitmaps_v3_unittest.cc4
-rw-r--r--chromium/net/disk_cache/blockfile/block_files.cc38
-rw-r--r--chromium/net/disk_cache/blockfile/block_files.h5
-rw-r--r--chromium/net/disk_cache/blockfile/block_files_unittest.cc2
-rw-r--r--chromium/net/disk_cache/blockfile/disk_cache_perftest.cc1
-rw-r--r--chromium/net/disk_cache/blockfile/disk_format.h71
-rw-r--r--chromium/net/disk_cache/blockfile/disk_format_base.h57
-rw-r--r--chromium/net/disk_cache/blockfile/disk_format_v3.h112
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl.cc52
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl.h37
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl_v3.cc62
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl_v3.h25
-rw-r--r--chromium/net/disk_cache/blockfile/eviction.cc8
-rw-r--r--chromium/net/disk_cache/blockfile/eviction.h2
-rw-r--r--chromium/net/disk_cache/blockfile/eviction_v3.cc8
-rw-r--r--chromium/net/disk_cache/blockfile/eviction_v3.h2
-rw-r--r--chromium/net/disk_cache/blockfile/experiments.h1
-rw-r--r--chromium/net/disk_cache/blockfile/file.h3
-rw-r--r--chromium/net/disk_cache/blockfile/file_block.h2
-rw-r--r--chromium/net/disk_cache/blockfile/file_ios.cc28
-rw-r--r--chromium/net/disk_cache/blockfile/file_lock.h4
-rw-r--r--chromium/net/disk_cache/blockfile/file_posix.cc33
-rw-r--r--chromium/net/disk_cache/blockfile/file_win.cc2
-rw-r--r--chromium/net/disk_cache/blockfile/in_flight_backend_io.cc55
-rw-r--r--chromium/net/disk_cache/blockfile/in_flight_backend_io.h42
-rw-r--r--chromium/net/disk_cache/blockfile/in_flight_io.h1
-rw-r--r--chromium/net/disk_cache/blockfile/index_table_v3.cc133
-rw-r--r--chromium/net/disk_cache/blockfile/index_table_v3.h60
-rw-r--r--chromium/net/disk_cache/blockfile/index_table_v3_unittest.cc39
-rw-r--r--chromium/net/disk_cache/blockfile/mapped_file.h3
-rw-r--r--chromium/net/disk_cache/blockfile/mapped_file_unittest.cc1
-rw-r--r--chromium/net/disk_cache/blockfile/rankings.cc9
-rw-r--r--chromium/net/disk_cache/blockfile/rankings.h1
-rw-r--r--chromium/net/disk_cache/blockfile/sparse_control.cc21
-rw-r--r--chromium/net/disk_cache/blockfile/sparse_control.h15
-rw-r--r--chromium/net/disk_cache/blockfile/sparse_control_v3.cc19
-rw-r--r--chromium/net/disk_cache/blockfile/sparse_control_v3.h15
-rw-r--r--chromium/net/disk_cache/blockfile/stats.cc18
-rw-r--r--chromium/net/disk_cache/blockfile/stats.h15
-rw-r--r--chromium/net/disk_cache/blockfile/storage_block-inl.h8
-rw-r--r--chromium/net/disk_cache/blockfile/storage_block.h6
-rw-r--r--chromium/net/disk_cache/blockfile/trace.h2
-rw-r--r--chromium/net/disk_cache/cache_creator.cc14
-rw-r--r--chromium/net/disk_cache/cache_util.cc18
-rw-r--r--chromium/net/disk_cache/cache_util.h5
-rw-r--r--chromium/net/disk_cache/disk_cache.h25
-rw-r--r--chromium/net/disk_cache/disk_cache_test_base.cc24
-rw-r--r--chromium/net/disk_cache/disk_cache_test_base.h23
-rw-r--r--chromium/net/disk_cache/disk_cache_test_util.cc9
-rw-r--r--chromium/net/disk_cache/disk_cache_test_util.h9
-rw-r--r--chromium/net/disk_cache/entry_unittest.cc55
-rw-r--r--chromium/net/disk_cache/memory/mem_backend_impl.cc23
-rw-r--r--chromium/net/disk_cache/memory/mem_backend_impl.h16
-rw-r--r--chromium/net/disk_cache/memory/mem_entry_impl.cc38
-rw-r--r--chromium/net/disk_cache/memory/mem_entry_impl.h25
-rw-r--r--chromium/net/disk_cache/memory/mem_rankings.h2
-rw-r--r--chromium/net/disk_cache/net_log_parameters.cc30
-rw-r--r--chromium/net/disk_cache/net_log_parameters.h8
-rw-r--r--chromium/net/disk_cache/simple/simple_backend_impl.cc127
-rw-r--r--chromium/net/disk_cache/simple/simple_backend_impl.h36
-rw-r--r--chromium/net/disk_cache/simple/simple_backend_version.h6
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_format.h31
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_format_history.h21
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.cc94
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.h40
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_operation.cc25
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_operation.h22
-rw-r--r--chromium/net/disk_cache/simple/simple_index.cc74
-rw-r--r--chromium/net/disk_cache/simple/simple_index.h51
-rw-r--r--chromium/net/disk_cache/simple/simple_index_delegate.h4
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file.cc29
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file.h21
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file_unittest.cc51
-rw-r--r--chromium/net/disk_cache/simple/simple_index_unittest.cc58
-rw-r--r--chromium/net/disk_cache/simple/simple_net_log_parameters.cc6
-rw-r--r--chromium/net/disk_cache/simple/simple_synchronous_entry.cc142
-rw-r--r--chromium/net/disk_cache/simple/simple_synchronous_entry.h84
-rw-r--r--chromium/net/disk_cache/simple/simple_test_util.h3
-rw-r--r--chromium/net/disk_cache/simple/simple_util.cc30
-rw-r--r--chromium/net/disk_cache/simple/simple_util.h28
-rw-r--r--chromium/net/disk_cache/simple/simple_util_unittest.cc2
-rw-r--r--chromium/net/disk_cache/simple/simple_version_upgrade.cc4
-rw-r--r--chromium/net/disk_cache/simple/simple_version_upgrade.h11
-rw-r--r--chromium/net/disk_cache/simple/simple_version_upgrade_unittest.cc13
-rw-r--r--chromium/net/dns/address_sorter.h2
-rw-r--r--chromium/net/dns/address_sorter_posix.cc12
-rw-r--r--chromium/net/dns/address_sorter_posix.h1
-rw-r--r--chromium/net/dns/address_sorter_posix_unittest.cc16
-rw-r--r--chromium/net/dns/address_sorter_win.cc8
-rw-r--r--chromium/net/dns/dns_client.cc8
-rw-r--r--chromium/net/dns/dns_config_service.cc4
-rw-r--r--chromium/net/dns/dns_config_service.h8
-rw-r--r--chromium/net/dns/dns_config_service_posix.cc54
-rw-r--r--chromium/net/dns/dns_config_service_posix.h3
-rw-r--r--chromium/net/dns/dns_config_service_posix_unittest.cc29
-rw-r--r--chromium/net/dns/dns_config_service_unittest.cc5
-rw-r--r--chromium/net/dns/dns_config_service_win.cc3
-rw-r--r--chromium/net/dns/dns_config_service_win.h1
-rw-r--r--chromium/net/dns/dns_config_service_win_unittest.cc7
-rw-r--r--chromium/net/dns/dns_hosts.cc5
-rw-r--r--chromium/net/dns/dns_hosts.h3
-rw-r--r--chromium/net/dns/dns_protocol.h75
-rw-r--r--chromium/net/dns/dns_query.cc52
-rw-r--r--chromium/net/dns/dns_query.h30
-rw-r--r--chromium/net/dns/dns_query_unittest.cc31
-rw-r--r--chromium/net/dns/dns_reloader.cc (renamed from chromium/net/base/dns_reloader.cc)4
-rw-r--r--chromium/net/dns/dns_reloader.h (renamed from chromium/net/base/dns_reloader.h)6
-rw-r--r--chromium/net/dns/dns_response.cc41
-rw-r--r--chromium/net/dns/dns_response.h17
-rw-r--r--chromium/net/dns/dns_response_unittest.cc356
-rw-r--r--chromium/net/dns/dns_session.cc30
-rw-r--r--chromium/net/dns/dns_session.h8
-rw-r--r--chromium/net/dns/dns_session_unittest.cc4
-rw-r--r--chromium/net/dns/dns_socket_pool.cc3
-rw-r--r--chromium/net/dns/dns_socket_pool.h1
-rw-r--r--chromium/net/dns/dns_test_util.cc18
-rw-r--r--chromium/net/dns/dns_test_util.h156
-rw-r--r--chromium/net/dns/dns_transaction.cc79
-rw-r--r--chromium/net/dns/dns_transaction.h7
-rw-r--r--chromium/net/dns/dns_transaction_unittest.cc157
-rw-r--r--chromium/net/dns/dns_util.cc (renamed from chromium/net/base/dns_util.cc)75
-rw-r--r--chromium/net/dns/dns_util.h (renamed from chromium/net/base/dns_util.h)13
-rw-r--r--chromium/net/dns/dns_util_unittest.cc (renamed from chromium/net/base/dns_util_unittest.cc)3
-rw-r--r--chromium/net/dns/host_cache.h13
-rw-r--r--chromium/net/dns/host_resolver.cc5
-rw-r--r--chromium/net/dns/host_resolver.h14
-rw-r--r--chromium/net/dns/host_resolver_impl.cc77
-rw-r--r--chromium/net/dns/host_resolver_impl.h11
-rw-r--r--chromium/net/dns/host_resolver_impl_unittest.cc41
-rw-r--r--chromium/net/dns/host_resolver_mojo.cc8
-rw-r--r--chromium/net/dns/host_resolver_mojo.h1
-rw-r--r--chromium/net/dns/host_resolver_mojo_unittest.cc28
-rw-r--r--chromium/net/dns/host_resolver_proc.cc4
-rw-r--r--chromium/net/dns/host_resolver_proc.h1
-rw-r--r--chromium/net/dns/mapped_host_resolver.cc8
-rw-r--r--chromium/net/dns/mapped_host_resolver.h2
-rw-r--r--chromium/net/dns/mapped_host_resolver_unittest.cc10
-rw-r--r--chromium/net/dns/mdns_cache.cc50
-rw-r--r--chromium/net/dns/mdns_cache.h8
-rw-r--r--chromium/net/dns/mdns_cache_unittest.cc207
-rw-r--r--chromium/net/dns/mdns_client.cc7
-rw-r--r--chromium/net/dns/mdns_client.h22
-rw-r--r--chromium/net/dns/mdns_client_impl.cc68
-rw-r--r--chromium/net/dns/mdns_client_impl.h35
-rw-r--r--chromium/net/dns/mdns_client_unittest.cc600
-rw-r--r--chromium/net/dns/mock_host_resolver.h3
-rw-r--r--chromium/net/dns/mock_mdns_socket_factory.cc12
-rw-r--r--chromium/net/dns/mock_mdns_socket_factory.h17
-rw-r--r--chromium/net/dns/mojo_host_resolver_impl.cc7
-rw-r--r--chromium/net/dns/mojo_host_resolver_impl_unittest.cc27
-rw-r--r--chromium/net/dns/mojo_host_type_converters.cc10
-rw-r--r--chromium/net/dns/notify_watcher_mac.h1
-rw-r--r--chromium/net/dns/record_parsed.cc31
-rw-r--r--chromium/net/dns/record_parsed.h21
-rw-r--r--chromium/net/dns/record_parsed_unittest.cc27
-rw-r--r--chromium/net/dns/record_rdata.cc34
-rw-r--r--chromium/net/dns/record_rdata.h48
-rw-r--r--chromium/net/dns/record_rdata_unittest.cc70
-rw-r--r--chromium/net/dns/serial_worker.h1
-rw-r--r--chromium/net/dns/single_request_host_resolver.h3
-rw-r--r--chromium/net/dns/single_request_host_resolver_unittest.cc1
-rw-r--r--chromium/net/docs/bug-triage-labels.md12
-rw-r--r--chromium/net/docs/bug-triage-suggested-workflow.md17
-rw-r--r--chromium/net/docs/bug-triage.md13
-rw-r--r--chromium/net/docs/crash-course-in-net-internals.md183
-rw-r--r--chromium/net/extras/sqlite/sqlite_channel_id_store.cc26
-rw-r--r--chromium/net/extras/sqlite/sqlite_channel_id_store_unittest.cc43
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc12
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store.h1
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc1
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc3
-rw-r--r--chromium/net/filter/brotli_filter.cc190
-rw-r--r--chromium/net/filter/brotli_filter.h17
-rw-r--r--chromium/net/filter/brotli_filter_disabled.cc13
-rw-r--r--chromium/net/filter/brotli_filter_unittest.cc269
-rw-r--r--chromium/net/filter/filter.cc21
-rw-r--r--chromium/net/filter/filter.h9
-rw-r--r--chromium/net/filter/filter_unittest.cc14
-rw-r--r--chromium/net/filter/gzip_filter.cc1
-rw-r--r--chromium/net/filter/gzip_filter.h2
-rw-r--r--chromium/net/filter/gzip_filter_unittest.cc1
-rw-r--r--chromium/net/filter/gzip_header.cc15
-rw-r--r--chromium/net/filter/gzip_header.h10
-rw-r--r--chromium/net/filter/mock_filter_context.cc4
-rw-r--r--chromium/net/filter/mock_filter_context.h7
-rw-r--r--chromium/net/filter/sdch_filter.cc5
-rw-r--r--chromium/net/filter/sdch_filter.h3
-rw-r--r--chromium/net/filter/sdch_filter_unittest.cc8
-rw-r--r--chromium/net/ftp/ftp_auth_cache.h2
-rw-r--r--chromium/net/ftp/ftp_ctrl_response_buffer.cc6
-rw-r--r--chromium/net/ftp/ftp_ctrl_response_buffer.h3
-rw-r--r--chromium/net/ftp/ftp_directory_listing_parser.h5
-rw-r--r--chromium/net/ftp/ftp_directory_listing_parser_ls.cc7
-rw-r--r--chromium/net/ftp/ftp_directory_listing_parser_unittest.cc3
-rw-r--r--chromium/net/ftp/ftp_directory_listing_parser_unittest.h4
-rw-r--r--chromium/net/ftp/ftp_directory_listing_parser_vms.cc7
-rw-r--r--chromium/net/ftp/ftp_directory_listing_parser_vms_unittest.cc25
-rw-r--r--chromium/net/ftp/ftp_network_layer.cc8
-rw-r--r--chromium/net/ftp/ftp_network_layer.h4
-rw-r--r--chromium/net/ftp/ftp_network_transaction.cc10
-rw-r--r--chromium/net/ftp/ftp_network_transaction.h7
-rw-r--r--chromium/net/ftp/ftp_network_transaction_unittest.cc3
-rw-r--r--chromium/net/ftp/ftp_response_info.h4
-rw-r--r--chromium/net/ftp/ftp_transaction.h4
-rw-r--r--chromium/net/ftp/ftp_transaction_factory.h3
-rw-r--r--chromium/net/ftp/ftp_util.cc1
-rw-r--r--chromium/net/ftp/ftp_util_unittest.cc1
-rw-r--r--chromium/net/http/bidirectional_stream.cc224
-rw-r--r--chromium/net/http/bidirectional_stream.h212
-rw-r--r--chromium/net/http/bidirectional_stream_job.cc17
-rw-r--r--chromium/net/http/bidirectional_stream_job.h140
-rw-r--r--chromium/net/http/bidirectional_stream_request_info.cc14
-rw-r--r--chromium/net/http/bidirectional_stream_request_info.h40
-rw-r--r--chromium/net/http/bidirectional_stream_unittest.cc1196
-rw-r--r--chromium/net/http/des.cc8
-rw-r--r--chromium/net/http/des.h10
-rw-r--r--chromium/net/http/des_unittest.cc24
-rw-r--r--chromium/net/http/disk_based_cert_cache.h3
-rw-r--r--chromium/net/http/disk_cache_based_quic_server_info.cc2
-rw-r--r--chromium/net/http/disk_cache_based_quic_server_info.h1
-rw-r--r--chromium/net/http/disk_cache_based_quic_server_info_unittest.cc37
-rw-r--r--chromium/net/http/failing_http_transaction_factory.cc15
-rw-r--r--chromium/net/http/http_auth.cc11
-rw-r--r--chromium/net/http/http_auth_cache.h2
-rw-r--r--chromium/net/http/http_auth_controller.cc2
-rw-r--r--chromium/net/http/http_auth_controller.h1
-rw-r--r--chromium/net/http/http_auth_filter.h1
-rw-r--r--chromium/net/http/http_auth_filter_unittest.cc1
-rw-r--r--chromium/net/http/http_auth_gssapi_posix.cc10
-rw-r--r--chromium/net/http/http_auth_gssapi_posix.h1
-rw-r--r--chromium/net/http/http_auth_gssapi_posix_unittest.cc1
-rw-r--r--chromium/net/http/http_auth_handler_basic.cc3
-rw-r--r--chromium/net/http/http_auth_handler_basic_unittest.cc1
-rw-r--r--chromium/net/http/http_auth_handler_digest.cc5
-rw-r--r--chromium/net/http/http_auth_handler_digest.h2
-rw-r--r--chromium/net/http/http_auth_handler_digest_unittest.cc1
-rw-r--r--chromium/net/http/http_auth_handler_factory.cc167
-rw-r--r--chromium/net/http/http_auth_handler_factory.h63
-rw-r--r--chromium/net/http/http_auth_handler_factory_unittest.cc9
-rw-r--r--chromium/net/http/http_auth_handler_mock.cc6
-rw-r--r--chromium/net/http/http_auth_handler_mock.h6
-rw-r--r--chromium/net/http/http_auth_handler_negotiate.cc58
-rw-r--r--chromium/net/http/http_auth_handler_negotiate.h50
-rw-r--r--chromium/net/http/http_auth_handler_negotiate_unittest.cc32
-rw-r--r--chromium/net/http/http_auth_handler_ntlm.cc5
-rw-r--r--chromium/net/http/http_auth_handler_ntlm.h19
-rw-r--r--chromium/net/http/http_auth_handler_ntlm_portable.cc121
-rw-r--r--chromium/net/http/http_auth_handler_ntlm_win.cc19
-rw-r--r--chromium/net/http/http_auth_preferences.cc82
-rw-r--r--chromium/net/http/http_auth_preferences.h84
-rw-r--r--chromium/net/http/http_auth_preferences_unittest.cc114
-rw-r--r--chromium/net/http/http_auth_scheme.cc15
-rw-r--r--chromium/net/http/http_auth_scheme.h17
-rw-r--r--chromium/net/http/http_auth_sspi_win_unittest.cc5
-rw-r--r--chromium/net/http/http_auth_unittest.cc9
-rw-r--r--chromium/net/http/http_basic_state.cc5
-rw-r--r--chromium/net/http/http_basic_state.h2
-rw-r--r--chromium/net/http/http_basic_stream.cc4
-rw-r--r--chromium/net/http/http_basic_stream.h4
-rw-r--r--chromium/net/http/http_byte_range.cc12
-rw-r--r--chromium/net/http/http_byte_range.h31
-rw-r--r--chromium/net/http/http_byte_range_unittest.cc19
-rw-r--r--chromium/net/http/http_cache.cc90
-rw-r--r--chromium/net/http/http_cache.h37
-rw-r--r--chromium/net/http/http_cache_transaction.cc46
-rw-r--r--chromium/net/http/http_cache_transaction.h9
-rw-r--r--chromium/net/http/http_cache_unittest.cc143
-rw-r--r--chromium/net/http/http_chunked_decoder.h2
-rw-r--r--chromium/net/http/http_chunked_decoder_unittest.cc1
-rw-r--r--chromium/net/http/http_content_disposition.cc1
-rw-r--r--chromium/net/http/http_content_disposition.h2
-rw-r--r--chromium/net/http/http_log_util.cc18
-rw-r--r--chromium/net/http/http_log_util.h7
-rw-r--r--chromium/net/http/http_log_util_unittest.cc10
-rw-r--r--chromium/net/http/http_network_layer.cc16
-rw-r--r--chromium/net/http/http_network_layer.h7
-rw-r--r--chromium/net/http/http_network_layer_unittest.cc9
-rw-r--r--chromium/net/http/http_network_session.cc86
-rw-r--r--chromium/net/http/http_network_session.h88
-rw-r--r--chromium/net/http/http_network_session_peer.cc3
-rw-r--r--chromium/net/http/http_network_session_peer.h7
-rw-r--r--chromium/net/http/http_network_transaction.cc73
-rw-r--r--chromium/net/http/http_network_transaction.h21
-rw-r--r--chromium/net/http/http_network_transaction_ssl_unittest.cc20
-rw-r--r--chromium/net/http/http_network_transaction_unittest.cc2885
-rw-r--r--chromium/net/http/http_proxy_client_socket.cc108
-rw-r--r--chromium/net/http/http_proxy_client_socket.h19
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool.cc320
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool.h54
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool_unittest.cc109
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper.cc636
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper.h214
-rw-r--r--chromium/net/http/http_request_headers.cc16
-rw-r--r--chromium/net/http/http_request_headers.h2
-rw-r--r--chromium/net/http/http_request_info.h1
-rw-r--r--chromium/net/http/http_response_body_drainer.h2
-rw-r--r--chromium/net/http/http_response_body_drainer_unittest.cc7
-rw-r--r--chromium/net/http/http_response_headers.cc87
-rw-r--r--chromium/net/http/http_response_headers.h31
-rw-r--r--chromium/net/http/http_response_headers_unittest.cc651
-rw-r--r--chromium/net/http/http_response_info.cc14
-rw-r--r--chromium/net/http/http_response_info.h8
-rw-r--r--chromium/net/http/http_security_headers.cc37
-rw-r--r--chromium/net/http/http_security_headers.h5
-rw-r--r--chromium/net/http/http_security_headers_unittest.cc26
-rw-r--r--chromium/net/http/http_server_properties.cc23
-rw-r--r--chromium/net/http/http_server_properties.h64
-rw-r--r--chromium/net/http/http_server_properties_impl.cc186
-rw-r--r--chromium/net/http/http_server_properties_impl.h19
-rw-r--r--chromium/net/http/http_server_properties_impl_unittest.cc448
-rw-r--r--chromium/net/http/http_server_properties_manager.cc461
-rw-r--r--chromium/net/http/http_server_properties_manager.h41
-rw-r--r--chromium/net/http/http_server_properties_manager_unittest.cc488
-rw-r--r--chromium/net/http/http_status_line_validator.h4
-rw-r--r--chromium/net/http/http_stream.h8
-rw-r--r--chromium/net/http/http_stream_factory.cc25
-rw-r--r--chromium/net/http/http_stream_factory.h23
-rw-r--r--chromium/net/http/http_stream_factory_impl.cc172
-rw-r--r--chromium/net/http/http_stream_factory_impl.h19
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.cc154
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.h22
-rw-r--r--chromium/net/http/http_stream_factory_impl_request.cc46
-rw-r--r--chromium/net/http/http_stream_factory_impl_request.h37
-rw-r--r--chromium/net/http/http_stream_factory_impl_request_unittest.cc31
-rw-r--r--chromium/net/http/http_stream_factory_impl_unittest.cc342
-rw-r--r--chromium/net/http/http_stream_parser.cc14
-rw-r--r--chromium/net/http/http_stream_parser.h7
-rw-r--r--chromium/net/http/http_stream_parser_unittest.cc99
-rw-r--r--chromium/net/http/http_transaction.h6
-rw-r--r--chromium/net/http/http_transaction_test_util.cc16
-rw-r--r--chromium/net/http/http_transaction_test_util.h6
-rw-r--r--chromium/net/http/http_util.cc24
-rw-r--r--chromium/net/http/http_util.h7
-rw-r--r--chromium/net/http/http_util_unittest.cc30
-rw-r--r--chromium/net/http/http_version.h14
-rw-r--r--chromium/net/http/md4.cc4
-rw-r--r--chromium/net/http/md4.h4
-rw-r--r--chromium/net/http/mock_allow_http_auth_preferences.cc29
-rw-r--r--chromium/net/http/mock_allow_http_auth_preferences.h29
-rw-r--r--chromium/net/http/mock_allow_url_security_manager.cc22
-rw-r--r--chromium/net/http/mock_allow_url_security_manager.h28
-rw-r--r--chromium/net/http/mock_http_cache.cc41
-rw-r--r--chromium/net/http/mock_http_cache.h18
-rw-r--r--chromium/net/http/mock_sspi_library_win.cc2
-rw-r--r--chromium/net/http/partial_data.cc37
-rw-r--r--chromium/net/http/partial_data.h14
-rw-r--r--chromium/net/http/proxy_client_socket.cc4
-rw-r--r--chromium/net/http/proxy_client_socket.h1
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.cc5
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.h1
-rw-r--r--chromium/net/http/transport_security_persister.cc6
-rw-r--r--chromium/net/http/transport_security_persister.h1
-rw-r--r--chromium/net/http/transport_security_state.cc279
-rw-r--r--chromium/net/http/transport_security_state.h65
-rw-r--r--chromium/net/http/transport_security_state_static.certs203
-rw-r--r--chromium/net/http/transport_security_state_static.h7208
-rw-r--r--chromium/net/http/transport_security_state_static.json2144
-rw-r--r--chromium/net/http/transport_security_state_unittest.cc191
-rw-r--r--chromium/net/http/url_security_manager.cc23
-rw-r--r--chromium/net/http/url_security_manager.h46
-rw-r--r--chromium/net/http/url_security_manager_posix.cc6
-rw-r--r--chromium/net/http/url_security_manager_unittest.cc19
-rw-r--r--chromium/net/http/url_security_manager_win.cc35
-rw-r--r--chromium/net/interfaces/BUILD.gn2
-rw-r--r--chromium/net/log/net_log.cc52
-rw-r--r--chromium/net/log/net_log.h22
-rw-r--r--chromium/net/log/net_log_capture_mode.cc5
-rw-r--r--chromium/net/log/net_log_capture_mode.h3
-rw-r--r--chromium/net/log/net_log_event_type_list.h93
-rw-r--r--chromium/net/log/net_log_source_type_list.h2
-rw-r--r--chromium/net/log/net_log_unittest.cc20
-rw-r--r--chromium/net/log/net_log_util.cc63
-rw-r--r--chromium/net/log/net_log_util_unittest.cc21
-rw-r--r--chromium/net/log/test_net_log.cc13
-rw-r--r--chromium/net/log/test_net_log.h4
-rw-r--r--chromium/net/log/test_net_log_entry.cc4
-rw-r--r--chromium/net/log/test_net_log_util.h2
-rw-r--r--chromium/net/log/trace_net_log_observer.cc11
-rw-r--r--chromium/net/log/trace_net_log_observer_unittest.cc2
-rw-r--r--chromium/net/log/write_to_file_net_log_observer.cc4
-rw-r--r--chromium/net/log/write_to_file_net_log_observer_unittest.cc18
-rw-r--r--chromium/net/net.gyp223
-rw-r--r--chromium/net/net.gypi214
-rw-r--r--chromium/net/net_common.gypi12
-rw-r--r--chromium/net/net_unittests_apk.isolate25
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h3
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc12
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher.h2
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc2
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher_factory.h2
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher_win.cc8
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher_win.h6
-rw-r--r--chromium/net/proxy/in_process_mojo_proxy_resolver_factory.cc4
-rw-r--r--chromium/net/proxy/mock_proxy_resolver.cc31
-rw-r--r--chromium/net/proxy/mock_proxy_resolver.h1
-rw-r--r--chromium/net/proxy/mock_proxy_script_fetcher.cc2
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_factory.h2
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_factory_impl.cc25
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_factory_impl.h3
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc16
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_impl.cc12
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_impl.h1
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_impl_unittest.cc21
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings.h4
-rw-r--r--chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings_unittest.cc1
-rw-r--r--chromium/net/proxy/mojo_proxy_type_converters.cc2
-rw-r--r--chromium/net/proxy/mojo_proxy_type_converters.h2
-rw-r--r--chromium/net/proxy/multi_threaded_proxy_resolver.cc17
-rw-r--r--chromium/net/proxy/multi_threaded_proxy_resolver.h3
-rw-r--r--chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc15
-rw-r--r--chromium/net/proxy/network_delegate_error_observer.cc1
-rw-r--r--chromium/net/proxy/network_delegate_error_observer.h1
-rw-r--r--chromium/net/proxy/polling_proxy_config_service.h1
-rw-r--r--chromium/net/proxy/proxy_bypass_rules.h1
-rw-r--r--chromium/net/proxy/proxy_config.cc8
-rw-r--r--chromium/net/proxy/proxy_config.h4
-rw-r--r--chromium/net/proxy/proxy_config_service_android.cc27
-rw-r--r--chromium/net/proxy/proxy_config_service_android.h19
-rw-r--r--chromium/net/proxy/proxy_config_service_ios.h1
-rw-r--r--chromium/net/proxy/proxy_config_service_linux.cc7
-rw-r--r--chromium/net/proxy/proxy_config_service_linux.h4
-rw-r--r--chromium/net/proxy/proxy_config_service_mac.h2
-rw-r--r--chromium/net/proxy/proxy_config_source.cc1
-rw-r--r--chromium/net/proxy/proxy_list.cc2
-rw-r--r--chromium/net/proxy/proxy_list.h2
-rw-r--r--chromium/net/proxy/proxy_resolver.h1
-rw-r--r--chromium/net/proxy/proxy_resolver_error_observer.h2
-rw-r--r--chromium/net/proxy/proxy_resolver_factory.h1
-rw-r--r--chromium/net/proxy/proxy_resolver_factory_mojo.cc33
-rw-r--r--chromium/net/proxy/proxy_resolver_factory_mojo.h3
-rw-r--r--chromium/net/proxy/proxy_resolver_factory_mojo_unittest.cc44
-rw-r--r--chromium/net/proxy/proxy_resolver_mac.h1
-rw-r--r--chromium/net/proxy/proxy_resolver_perftest.cc26
-rw-r--r--chromium/net/proxy/proxy_resolver_v8.cc17
-rw-r--r--chromium/net/proxy/proxy_resolver_v8.h3
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing.cc22
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing.h2
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc7
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.cc12
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.h2
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc4
-rw-r--r--chromium/net/proxy/proxy_resolver_winhttp.cc1
-rw-r--r--chromium/net/proxy/proxy_resolver_winhttp.h1
-rw-r--r--chromium/net/proxy/proxy_script_decider.cc4
-rw-r--r--chromium/net/proxy/proxy_script_decider.h3
-rw-r--r--chromium/net/proxy/proxy_script_decider_unittest.cc1
-rw-r--r--chromium/net/proxy/proxy_script_fetcher_impl.h4
-rw-r--r--chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc53
-rw-r--r--chromium/net/proxy/proxy_server.cc3
-rw-r--r--chromium/net/proxy/proxy_server.h7
-rw-r--r--chromium/net/proxy/proxy_server_unittest.cc2
-rw-r--r--chromium/net/proxy/proxy_service.cc40
-rw-r--r--chromium/net/proxy/proxy_service.h5
-rw-r--r--chromium/net/proxy/proxy_service_mojo.cc10
-rw-r--r--chromium/net/proxy/proxy_service_mojo.h1
-rw-r--r--chromium/net/proxy/proxy_service_mojo_unittest.cc5
-rw-r--r--chromium/net/proxy/proxy_service_unittest.cc1
-rw-r--r--chromium/net/proxy/proxy_service_v8.cc6
-rw-r--r--chromium/net/proxy/proxy_service_v8.h1
-rw-r--r--chromium/net/quic/congestion_control/cubic.cc59
-rw-r--r--chromium/net/quic/congestion_control/cubic.h10
-rw-r--r--chromium/net/quic/congestion_control/cubic_bytes.cc17
-rw-r--r--chromium/net/quic/congestion_control/cubic_bytes.h6
-rw-r--r--chromium/net/quic/congestion_control/cubic_bytes_test.cc3
-rw-r--r--chromium/net/quic/congestion_control/cubic_test.cc12
-rw-r--r--chromium/net/quic/congestion_control/general_loss_algorithm.cc122
-rw-r--r--chromium/net/quic/congestion_control/general_loss_algorithm.h61
-rw-r--r--chromium/net/quic/congestion_control/general_loss_algorithm_test.cc307
-rw-r--r--chromium/net/quic/congestion_control/hybrid_slow_start.cc20
-rw-r--r--chromium/net/quic/congestion_control/hybrid_slow_start.h10
-rw-r--r--chromium/net/quic/congestion_control/hybrid_slow_start_test.cc5
-rw-r--r--chromium/net/quic/congestion_control/loss_detection_interface.cc5
-rw-r--r--chromium/net/quic/congestion_control/loss_detection_interface.h8
-rw-r--r--chromium/net/quic/congestion_control/pacing_sender.cc17
-rw-r--r--chromium/net/quic/congestion_control/pacing_sender.h11
-rw-r--r--chromium/net/quic/congestion_control/pacing_sender_test.cc26
-rw-r--r--chromium/net/quic/congestion_control/prr_sender.cc5
-rw-r--r--chromium/net/quic/congestion_control/prr_sender.h2
-rw-r--r--chromium/net/quic/congestion_control/prr_sender_test.cc2
-rw-r--r--chromium/net/quic/congestion_control/rtt_stats.cc27
-rw-r--r--chromium/net/quic/congestion_control/rtt_stats.h47
-rw-r--r--chromium/net/quic/congestion_control/rtt_stats_test.cc79
-rw-r--r--chromium/net/quic/congestion_control/send_algorithm_interface.cc2
-rw-r--r--chromium/net/quic/congestion_control/send_algorithm_interface.h6
-rw-r--r--chromium/net/quic/congestion_control/send_algorithm_simulator.cc101
-rw-r--r--chromium/net/quic/congestion_control/send_algorithm_simulator.h25
-rw-r--r--chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.cc84
-rw-r--r--chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.h20
-rw-r--r--chromium/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc168
-rw-r--r--chromium/net/quic/congestion_control/tcp_cubic_sender.cc80
-rw-r--r--chromium/net/quic/congestion_control/tcp_cubic_sender.h20
-rw-r--r--chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc279
-rw-r--r--chromium/net/quic/congestion_control/tcp_loss_algorithm.cc10
-rw-r--r--chromium/net/quic/congestion_control/tcp_loss_algorithm.h8
-rw-r--r--chromium/net/quic/congestion_control/tcp_loss_algorithm_test.cc27
-rw-r--r--chromium/net/quic/congestion_control/time_loss_algorithm.cc10
-rw-r--r--chromium/net/quic/congestion_control/time_loss_algorithm.h9
-rw-r--r--chromium/net/quic/congestion_control/time_loss_algorithm_test.cc23
-rw-r--r--chromium/net/quic/crypto/aead_base_decrypter.h3
-rw-r--r--chromium/net/quic/crypto/aead_base_decrypter_nss.cc4
-rw-r--r--chromium/net/quic/crypto/aead_base_decrypter_openssl.cc9
-rw-r--r--chromium/net/quic/crypto/aead_base_encrypter.h3
-rw-r--r--chromium/net/quic/crypto/aead_base_encrypter_nss.cc35
-rw-r--r--chromium/net/quic/crypto/aead_base_encrypter_openssl.cc26
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_decrypter.h6
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc5
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_decrypter_openssl.cc6
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc262
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h3
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc3
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc4
-rw-r--r--chromium/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc186
-rw-r--r--chromium/net/quic/crypto/cert_compressor.cc361
-rw-r--r--chromium/net/quic/crypto/cert_compressor.h2
-rw-r--r--chromium/net/quic/crypto/cert_compressor_test.cc33
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_decrypter.h9
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc7
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_decrypter_openssl.cc15
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_decrypter_test.cc67
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_encrypter.h6
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_encrypter_nss.cc5
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_encrypter_openssl.cc9
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_encrypter_test.cc21
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h56
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc50
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc43
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc178
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h51
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_nss.cc42
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc34
-rw-r--r--chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc178
-rw-r--r--chromium/net/quic/crypto/channel_id.h1
-rw-r--r--chromium/net/quic/crypto/channel_id_chromium.cc28
-rw-r--r--chromium/net/quic/crypto/channel_id_chromium.h6
-rw-r--r--chromium/net/quic/crypto/channel_id_nss.cc18
-rw-r--r--chromium/net/quic/crypto/channel_id_openssl.cc15
-rw-r--r--chromium/net/quic/crypto/channel_id_test.cc325
-rw-r--r--chromium/net/quic/crypto/common_cert_set.cc44
-rw-r--r--chromium/net/quic/crypto/common_cert_set.h9
-rw-r--r--chromium/net/quic/crypto/common_cert_set_1.c4
-rw-r--r--chromium/net/quic/crypto/common_cert_set_2.c129
-rw-r--r--chromium/net/quic/crypto/common_cert_set_2a.inc5627
-rw-r--r--chromium/net/quic/crypto/common_cert_set_2b.inc5744
-rw-r--r--chromium/net/quic/crypto/common_cert_set_test.cc291
-rw-r--r--chromium/net/quic/crypto/crypto_framer.cc38
-rw-r--r--chromium/net/quic/crypto/crypto_framer.h11
-rw-r--r--chromium/net/quic/crypto/crypto_framer_test.cc418
-rw-r--r--chromium/net/quic/crypto/crypto_handshake.cc7
-rw-r--r--chromium/net/quic/crypto/crypto_handshake.h18
-rw-r--r--chromium/net/quic/crypto/crypto_handshake_message.cc47
-rw-r--r--chromium/net/quic/crypto/crypto_handshake_message.h18
-rw-r--r--chromium/net/quic/crypto/crypto_handshake_message_test.cc44
-rw-r--r--chromium/net/quic/crypto/crypto_protocol.h22
-rw-r--r--chromium/net/quic/crypto/crypto_secret_boxer.cc10
-rw-r--r--chromium/net/quic/crypto/crypto_secret_boxer.h3
-rw-r--r--chromium/net/quic/crypto/crypto_secret_boxer_test.cc7
-rw-r--r--chromium/net/quic/crypto/crypto_server_config_protobuf.cc4
-rw-r--r--chromium/net/quic/crypto/crypto_server_config_protobuf.h60
-rw-r--r--chromium/net/quic/crypto/crypto_server_test.cc507
-rw-r--r--chromium/net/quic/crypto/crypto_utils.cc133
-rw-r--r--chromium/net/quic/crypto/crypto_utils.h33
-rw-r--r--chromium/net/quic/crypto/crypto_utils_test.cc164
-rw-r--r--chromium/net/quic/crypto/curve25519_key_exchange.cc18
-rw-r--r--chromium/net/quic/crypto/curve25519_key_exchange.h6
-rw-r--r--chromium/net/quic/crypto/local_strike_register_client.cc20
-rw-r--r--chromium/net/quic/crypto/local_strike_register_client.h10
-rw-r--r--chromium/net/quic/crypto/local_strike_register_client_test.cc21
-rw-r--r--chromium/net/quic/crypto/null_decrypter.cc27
-rw-r--r--chromium/net/quic/crypto/null_decrypter.h10
-rw-r--r--chromium/net/quic/crypto/null_decrypter_test.cc31
-rw-r--r--chromium/net/quic/crypto/null_encrypter.cc25
-rw-r--r--chromium/net/quic/crypto/null_encrypter.h3
-rw-r--r--chromium/net/quic/crypto/null_encrypter_test.cc14
-rw-r--r--chromium/net/quic/crypto/p256_key_exchange.h9
-rw-r--r--chromium/net/quic/crypto/p256_key_exchange_nss.cc59
-rw-r--r--chromium/net/quic/crypto/p256_key_exchange_openssl.cc22
-rw-r--r--chromium/net/quic/crypto/p256_key_exchange_test.cc1
-rw-r--r--chromium/net/quic/crypto/proof_source.h7
-rw-r--r--chromium/net/quic/crypto/proof_source_chromium.h12
-rw-r--r--chromium/net/quic/crypto/proof_source_chromium_nss.cc6
-rw-r--r--chromium/net/quic/crypto/proof_source_chromium_openssl.cc36
-rw-r--r--chromium/net/quic/crypto/proof_test.cc259
-rw-r--r--chromium/net/quic/crypto/proof_verifier.h1
-rw-r--r--chromium/net/quic/crypto/proof_verifier_chromium.cc118
-rw-r--r--chromium/net/quic/crypto/proof_verifier_chromium.h17
-rw-r--r--chromium/net/quic/crypto/proof_verifier_chromium_test.cc380
-rw-r--r--chromium/net/quic/crypto/properties_based_quic_server_info.cc68
-rw-r--r--chromium/net/quic/crypto/properties_based_quic_server_info.h64
-rw-r--r--chromium/net/quic/crypto/properties_based_quic_server_info_test.cc101
-rw-r--r--chromium/net/quic/crypto/quic_crypto_client_config.cc243
-rw-r--r--chromium/net/quic/crypto/quic_crypto_client_config.h32
-rw-r--r--chromium/net/quic/crypto/quic_crypto_client_config_test.cc186
-rw-r--r--chromium/net/quic/crypto/quic_crypto_server_config.cc548
-rw-r--r--chromium/net/quic/crypto/quic_crypto_server_config.h99
-rw-r--r--chromium/net/quic/crypto/quic_crypto_server_config_test.cc233
-rw-r--r--chromium/net/quic/crypto/quic_decrypter.cc3
-rw-r--r--chromium/net/quic/crypto/quic_decrypter.h5
-rw-r--r--chromium/net/quic/crypto/quic_encrypter.cc3
-rw-r--r--chromium/net/quic/crypto/quic_encrypter.h13
-rw-r--r--chromium/net/quic/crypto/quic_random.cc13
-rw-r--r--chromium/net/quic/crypto/quic_random.h4
-rw-r--r--chromium/net/quic/crypto/quic_random_test.cc4
-rw-r--r--chromium/net/quic/crypto/quic_server_info.cc14
-rw-r--r--chromium/net/quic/crypto/quic_server_info.h10
-rw-r--r--chromium/net/quic/crypto/scoped_evp_aead_ctx.h2
-rw-r--r--chromium/net/quic/crypto/strike_register.cc188
-rw-r--r--chromium/net/quic/crypto/strike_register.h73
-rw-r--r--chromium/net/quic/crypto/strike_register_client.h9
-rw-r--r--chromium/net/quic/crypto/strike_register_test.cc115
-rw-r--r--chromium/net/quic/interval_set.h1
-rw-r--r--chromium/net/quic/interval_set_test.cc36
-rw-r--r--chromium/net/quic/interval_test.cc61
-rw-r--r--chromium/net/quic/iovector.h20
-rw-r--r--chromium/net/quic/iovector_test.cc19
-rw-r--r--chromium/net/quic/network_connection.cc3
-rw-r--r--chromium/net/quic/network_connection.h2
-rw-r--r--chromium/net/quic/p2p/quic_p2p_crypto_stream.cc6
-rw-r--r--chromium/net/quic/p2p/quic_p2p_crypto_stream.h1
-rw-r--r--chromium/net/quic/p2p/quic_p2p_session.cc9
-rw-r--r--chromium/net/quic/p2p/quic_p2p_session.h5
-rw-r--r--chromium/net/quic/p2p/quic_p2p_session_test.cc64
-rw-r--r--chromium/net/quic/p2p/quic_p2p_stream.cc2
-rw-r--r--chromium/net/quic/p2p/quic_p2p_stream.h5
-rw-r--r--chromium/net/quic/port_suggester.cc7
-rw-r--r--chromium/net/quic/port_suggester.h12
-rw-r--r--chromium/net/quic/port_suggester_unittest.cc29
-rw-r--r--chromium/net/quic/quic_ack_listener_interface.h38
-rw-r--r--chromium/net/quic/quic_ack_notifier.cc69
-rw-r--r--chromium/net/quic/quic_ack_notifier.h83
-rw-r--r--chromium/net/quic/quic_ack_notifier_manager.cc117
-rw-r--r--chromium/net/quic/quic_ack_notifier_manager.h75
-rw-r--r--chromium/net/quic/quic_ack_notifier_manager_test.cc172
-rw-r--r--chromium/net/quic/quic_ack_notifier_test.cc88
-rw-r--r--chromium/net/quic/quic_address_mismatch_test.cc60
-rw-r--r--chromium/net/quic/quic_alarm.cc6
-rw-r--r--chromium/net/quic/quic_alarm.h1
-rw-r--r--chromium/net/quic/quic_alarm_test.cc13
-rw-r--r--chromium/net/quic/quic_bandwidth.cc30
-rw-r--r--chromium/net/quic/quic_bandwidth.h36
-rw-r--r--chromium/net/quic/quic_bandwidth_test.cc16
-rw-r--r--chromium/net/quic/quic_blocked_writer_interface.h2
-rw-r--r--chromium/net/quic/quic_bug_tracker.h10
-rw-r--r--chromium/net/quic/quic_chromium_client_session.cc193
-rw-r--r--chromium/net/quic/quic_chromium_client_session.h52
-rw-r--r--chromium/net/quic/quic_chromium_client_session_test.cc434
-rw-r--r--chromium/net/quic/quic_chromium_client_stream.cc (renamed from chromium/net/quic/quic_reliable_client_stream.cc)65
-rw-r--r--chromium/net/quic/quic_chromium_client_stream.h (renamed from chromium/net/quic/quic_reliable_client_stream.h)23
-rw-r--r--chromium/net/quic/quic_chromium_client_stream_test.cc (renamed from chromium/net/quic/quic_reliable_client_stream_test.cc)66
-rw-r--r--chromium/net/quic/quic_chromium_connection_helper.cc (renamed from chromium/net/quic/quic_connection_helper.cc)28
-rw-r--r--chromium/net/quic/quic_chromium_connection_helper.h (renamed from chromium/net/quic/quic_connection_helper.h)22
-rw-r--r--chromium/net/quic/quic_chromium_connection_helper_test.cc (renamed from chromium/net/quic/quic_connection_helper_test.cc)34
-rw-r--r--chromium/net/quic/quic_client_session_base.cc37
-rw-r--r--chromium/net/quic/quic_client_session_base.h22
-rw-r--r--chromium/net/quic/quic_clock.cc6
-rw-r--r--chromium/net/quic/quic_clock.h2
-rw-r--r--chromium/net/quic/quic_clock_test.cc4
-rw-r--r--chromium/net/quic/quic_config.cc151
-rw-r--r--chromium/net/quic/quic_config.h69
-rw-r--r--chromium/net/quic/quic_config_test.cc22
-rw-r--r--chromium/net/quic/quic_connection.cc815
-rw-r--r--chromium/net/quic/quic_connection.h191
-rw-r--r--chromium/net/quic/quic_connection_logger.cc186
-rw-r--r--chromium/net/quic/quic_connection_logger.h12
-rw-r--r--chromium/net/quic/quic_connection_logger_unittest.cc3
-rw-r--r--chromium/net/quic/quic_connection_stats.cc3
-rw-r--r--chromium/net/quic/quic_connection_stats.h15
-rw-r--r--chromium/net/quic/quic_connection_test.cc1891
-rw-r--r--chromium/net/quic/quic_crypto_client_stream.cc170
-rw-r--r--chromium/net/quic/quic_crypto_client_stream.h42
-rw-r--r--chromium/net/quic/quic_crypto_client_stream_factory.cc39
-rw-r--r--chromium/net/quic/quic_crypto_client_stream_factory.h6
-rw-r--r--chromium/net/quic/quic_crypto_client_stream_test.cc162
-rw-r--r--chromium/net/quic/quic_crypto_server_stream.cc109
-rw-r--r--chromium/net/quic/quic_crypto_server_stream.h116
-rw-r--r--chromium/net/quic/quic_crypto_server_stream_test.cc209
-rw-r--r--chromium/net/quic/quic_crypto_stream.cc26
-rw-r--r--chromium/net/quic/quic_crypto_stream.h8
-rw-r--r--chromium/net/quic/quic_crypto_stream_test.cc21
-rw-r--r--chromium/net/quic/quic_data_reader.cc20
-rw-r--r--chromium/net/quic/quic_data_reader.h13
-rw-r--r--chromium/net/quic/quic_data_stream.cc137
-rw-r--r--chromium/net/quic/quic_data_stream.h142
-rw-r--r--chromium/net/quic/quic_data_writer.cc43
-rw-r--r--chromium/net/quic/quic_data_writer.h23
-rw-r--r--chromium/net/quic/quic_data_writer_test.cc173
-rw-r--r--chromium/net/quic/quic_default_packet_writer.cc6
-rw-r--r--chromium/net/quic/quic_default_packet_writer.h12
-rw-r--r--chromium/net/quic/quic_end_to_end_unittest.cc110
-rw-r--r--chromium/net/quic/quic_fec_group.cc123
-rw-r--r--chromium/net/quic/quic_fec_group.h77
-rw-r--r--chromium/net/quic/quic_fec_group_interface.cc49
-rw-r--r--chromium/net/quic/quic_fec_group_interface.h84
-rw-r--r--chromium/net/quic/quic_fec_group_test.cc193
-rw-r--r--chromium/net/quic/quic_flags.cc112
-rw-r--r--chromium/net/quic/quic_flags.h40
-rw-r--r--chromium/net/quic/quic_flow_controller.cc29
-rw-r--r--chromium/net/quic/quic_flow_controller.h3
-rw-r--r--chromium/net/quic/quic_flow_controller_test.cc18
-rw-r--r--chromium/net/quic/quic_frame_list.cc249
-rw-r--r--chromium/net/quic/quic_frame_list.h82
-rw-r--r--chromium/net/quic/quic_framer.cc699
-rw-r--r--chromium/net/quic/quic_framer.h109
-rw-r--r--chromium/net/quic/quic_framer_test.cc1507
-rw-r--r--chromium/net/quic/quic_headers_stream.cc185
-rw-r--r--chromium/net/quic/quic_headers_stream.h73
-rw-r--r--chromium/net/quic/quic_headers_stream_test.cc388
-rw-r--r--chromium/net/quic/quic_http_stream.cc74
-rw-r--r--chromium/net/quic/quic_http_stream.h19
-rw-r--r--chromium/net/quic/quic_http_stream_test.cc300
-rw-r--r--chromium/net/quic/quic_http_utils.cc18
-rw-r--r--chromium/net/quic/quic_http_utils.h11
-rw-r--r--chromium/net/quic/quic_http_utils_test.cc8
-rw-r--r--chromium/net/quic/quic_multipath_received_packet_manager.cc147
-rw-r--r--chromium/net/quic/quic_multipath_received_packet_manager.h78
-rw-r--r--chromium/net/quic/quic_multipath_received_packet_manager_test.cc184
-rw-r--r--chromium/net/quic/quic_multipath_transmissions_map.cc70
-rw-r--r--chromium/net/quic/quic_multipath_transmissions_map.h65
-rw-r--r--chromium/net/quic/quic_multipath_transmissions_map_test.cc114
-rw-r--r--chromium/net/quic/quic_network_transaction_unittest.cc1435
-rw-r--r--chromium/net/quic/quic_packet_creator.cc523
-rw-r--r--chromium/net/quic/quic_packet_creator.h302
-rw-r--r--chromium/net/quic/quic_packet_creator_test.cc1172
-rw-r--r--chromium/net/quic/quic_packet_generator.cc329
-rw-r--r--chromium/net/quic/quic_packet_generator.h129
-rw-r--r--chromium/net/quic/quic_packet_generator_test.cc178
-rw-r--r--chromium/net/quic/quic_packet_reader.cc5
-rw-r--r--chromium/net/quic/quic_packet_reader.h6
-rw-r--r--chromium/net/quic/quic_packet_writer.h10
-rw-r--r--chromium/net/quic/quic_protocol.cc571
-rw-r--r--chromium/net/quic/quic_protocol.h428
-rw-r--r--chromium/net/quic/quic_protocol_test.cc35
-rw-r--r--chromium/net/quic/quic_received_packet_manager.cc75
-rw-r--r--chromium/net/quic/quic_received_packet_manager.h31
-rw-r--r--chromium/net/quic/quic_received_packet_manager_test.cc72
-rw-r--r--chromium/net/quic/quic_sent_entropy_manager.h1
-rw-r--r--chromium/net/quic/quic_sent_entropy_manager_test.cc16
-rw-r--r--chromium/net/quic/quic_sent_packet_manager.cc284
-rw-r--r--chromium/net/quic/quic_sent_packet_manager.h66
-rw-r--r--chromium/net/quic/quic_sent_packet_manager_test.cc215
-rw-r--r--chromium/net/quic/quic_server_id.cc59
-rw-r--r--chromium/net/quic/quic_server_id.h25
-rw-r--r--chromium/net/quic/quic_server_id_test.cc234
-rw-r--r--chromium/net/quic/quic_session.cc310
-rw-r--r--chromium/net/quic/quic_session.h147
-rw-r--r--chromium/net/quic/quic_session_test.cc522
-rw-r--r--chromium/net/quic/quic_simple_buffer_allocator.cc17
-rw-r--r--chromium/net/quic/quic_simple_buffer_allocator.h20
-rw-r--r--chromium/net/quic/quic_simple_buffer_allocator_test.cc35
-rw-r--r--chromium/net/quic/quic_socket_address_coder.cc21
-rw-r--r--chromium/net/quic/quic_socket_address_coder.h13
-rw-r--r--chromium/net/quic/quic_socket_address_coder_test.cc51
-rw-r--r--chromium/net/quic/quic_spdy_session.cc56
-rw-r--r--chromium/net/quic/quic_spdy_session.h56
-rw-r--r--chromium/net/quic/quic_spdy_stream.cc264
-rw-r--r--chromium/net/quic/quic_spdy_stream.h194
-rw-r--r--chromium/net/quic/quic_spdy_stream_test.cc (renamed from chromium/net/quic/quic_data_stream_test.cc)439
-rw-r--r--chromium/net/quic/quic_stream_factory.cc614
-rw-r--r--chromium/net/quic/quic_stream_factory.h132
-rw-r--r--chromium/net/quic/quic_stream_factory_test.cc2570
-rw-r--r--chromium/net/quic/quic_stream_sequencer.cc290
-rw-r--r--chromium/net/quic/quic_stream_sequencer.h78
-rw-r--r--chromium/net/quic/quic_stream_sequencer_buffer_interface.h78
-rw-r--r--chromium/net/quic/quic_stream_sequencer_test.cc405
-rw-r--r--chromium/net/quic/quic_sustained_bandwidth_recorder.h11
-rw-r--r--chromium/net/quic/quic_sustained_bandwidth_recorder_test.cc2
-rw-r--r--chromium/net/quic/quic_time.cc172
-rw-r--r--chromium/net/quic/quic_time.h155
-rw-r--r--chromium/net/quic/quic_time_test.cc28
-rw-r--r--chromium/net/quic/quic_types.cc19
-rw-r--r--chromium/net/quic/quic_types.h7
-rw-r--r--chromium/net/quic/quic_unacked_packet_map.cc205
-rw-r--r--chromium/net/quic/quic_unacked_packet_map.h54
-rw-r--r--chromium/net/quic/quic_unacked_packet_map_test.cc182
-rw-r--r--chromium/net/quic/quic_utils.cc120
-rw-r--r--chromium/net/quic/quic_utils.h14
-rw-r--r--chromium/net/quic/quic_utils_chromium.h25
-rw-r--r--chromium/net/quic/quic_utils_test.cc97
-rw-r--r--chromium/net/quic/quic_write_blocked_list.cc11
-rw-r--r--chromium/net/quic/quic_write_blocked_list.h133
-rw-r--r--chromium/net/quic/quic_write_blocked_list_test.cc104
-rw-r--r--chromium/net/quic/reliable_quic_stream.cc172
-rw-r--r--chromium/net/quic/reliable_quic_stream.h93
-rw-r--r--chromium/net/quic/reliable_quic_stream_test.cc279
-rw-r--r--chromium/net/quic/spdy_utils.cc130
-rw-r--r--chromium/net/quic/spdy_utils.h42
-rw-r--r--chromium/net/quic/spdy_utils_test.cc140
-rw-r--r--chromium/net/quic/stream_sequencer_buffer.cc453
-rw-r--r--chromium/net/quic/stream_sequencer_buffer.h203
-rw-r--r--chromium/net/quic/stream_sequencer_buffer_test.cc981
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils.cc219
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils.h60
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils_chromium.cc178
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils_openssl.cc16
-rw-r--r--chromium/net/quic/test_tools/delayed_verify_strike_register_client.cc23
-rw-r--r--chromium/net/quic/test_tools/delayed_verify_strike_register_client.h18
-rw-r--r--chromium/net/quic/test_tools/mock_clock.cc8
-rw-r--r--chromium/net/quic/test_tools/mock_clock.h1
-rw-r--r--chromium/net/quic/test_tools/mock_crypto_client_stream.cc16
-rw-r--r--chromium/net/quic/test_tools/mock_crypto_client_stream.h14
-rw-r--r--chromium/net/quic/test_tools/mock_crypto_client_stream_factory.cc7
-rw-r--r--chromium/net/quic/test_tools/mock_crypto_client_stream_factory.h8
-rw-r--r--chromium/net/quic/test_tools/mock_quic_dispatcher.cc8
-rw-r--r--chromium/net/quic/test_tools/mock_quic_dispatcher.h9
-rw-r--r--chromium/net/quic/test_tools/mock_random.cc19
-rw-r--r--chromium/net/quic/test_tools/mock_random.h14
-rw-r--r--chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.cc15
-rw-r--r--chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.h26
-rw-r--r--chromium/net/quic/test_tools/quic_chromium_client_session_peer.cc9
-rw-r--r--chromium/net/quic/test_tools/quic_chromium_client_session_peer.h6
-rw-r--r--chromium/net/quic/test_tools/quic_config_peer.cc8
-rw-r--r--chromium/net/quic/test_tools/quic_config_peer.h12
-rw-r--r--chromium/net/quic/test_tools/quic_connection_peer.cc22
-rw-r--r--chromium/net/quic/test_tools/quic_connection_peer.h12
-rw-r--r--chromium/net/quic/test_tools/quic_data_stream_peer.h29
-rw-r--r--chromium/net/quic/test_tools/quic_flow_controller_peer.cc4
-rw-r--r--chromium/net/quic/test_tools/quic_flow_controller_peer.h1
-rw-r--r--chromium/net/quic/test_tools/quic_framer_peer.cc33
-rw-r--r--chromium/net/quic/test_tools/quic_framer_peer.h10
-rw-r--r--chromium/net/quic/test_tools/quic_packet_creator_peer.cc70
-rw-r--r--chromium/net/quic/test_tools/quic_packet_creator_peer.h26
-rw-r--r--chromium/net/quic/test_tools/quic_packet_generator_peer.cc6
-rw-r--r--chromium/net/quic/test_tools/quic_packet_generator_peer.h2
-rw-r--r--chromium/net/quic/test_tools/quic_received_packet_manager_peer.h1
-rw-r--r--chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc19
-rw-r--r--chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h7
-rw-r--r--chromium/net/quic/test_tools/quic_session_peer.cc35
-rw-r--r--chromium/net/quic/test_tools/quic_session_peer.h17
-rw-r--r--chromium/net/quic/test_tools/quic_spdy_session_peer.h1
-rw-r--r--chromium/net/quic/test_tools/quic_spdy_stream_peer.cc (renamed from chromium/net/quic/test_tools/quic_data_stream_peer.cc)6
-rw-r--r--chromium/net/quic/test_tools/quic_spdy_stream_peer.h29
-rw-r--r--chromium/net/quic/test_tools/quic_stream_factory_peer.cc165
-rw-r--r--chromium/net/quic/test_tools/quic_stream_factory_peer.h95
-rw-r--r--chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc13
-rw-r--r--chromium/net/quic/test_tools/quic_stream_sequencer_peer.h9
-rw-r--r--chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc6
-rw-r--r--chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h9
-rw-r--r--chromium/net/quic/test_tools/quic_test_packet_maker.cc287
-rw-r--r--chromium/net/quic/test_tools/quic_test_packet_maker.h70
-rw-r--r--chromium/net/quic/test_tools/quic_test_utils.cc374
-rw-r--r--chromium/net/quic/test_tools/quic_test_utils.h326
-rw-r--r--chromium/net/quic/test_tools/reliable_quic_stream_peer.cc31
-rw-r--r--chromium/net/quic/test_tools/reliable_quic_stream_peer.h15
-rw-r--r--chromium/net/quic/test_tools/rtt_stats_peer.h1
-rw-r--r--chromium/net/quic/test_tools/simple_quic_framer.cc74
-rw-r--r--chromium/net/quic/test_tools/simple_quic_framer.h9
-rw-r--r--chromium/net/quic/test_tools/test_task_runner.cc16
-rw-r--r--chromium/net/quic/test_tools/test_task_runner.h2
-rw-r--r--chromium/net/sdch/README.md5
-rw-r--r--chromium/net/sdch/sdch_owner.cc132
-rw-r--r--chromium/net/sdch/sdch_owner.h7
-rw-r--r--chromium/net/sdch/sdch_owner_unittest.cc152
-rw-r--r--chromium/net/server/http_connection.cc9
-rw-r--r--chromium/net/server/http_connection.h2
-rw-r--r--chromium/net/server/http_server.cc31
-rw-r--r--chromium/net/server/http_server.h8
-rw-r--r--chromium/net/server/http_server_response_info.h2
-rw-r--r--chromium/net/server/http_server_unittest.cc18
-rw-r--r--chromium/net/server/web_socket.h2
-rw-r--r--chromium/net/server/web_socket_encoder.cc32
-rw-r--r--chromium/net/server/web_socket_encoder.h6
-rw-r--r--chromium/net/server/web_socket_encoder_unittest.cc11
-rw-r--r--chromium/net/socket/client_socket_factory.cc9
-rw-r--r--chromium/net/socket/client_socket_factory.h1
-rw-r--r--chromium/net/socket/client_socket_handle.cc8
-rw-r--r--chromium/net/socket/client_socket_handle.h1
-rw-r--r--chromium/net/socket/client_socket_pool.cc4
-rw-r--r--chromium/net/socket/client_socket_pool.h2
-rw-r--r--chromium/net/socket/client_socket_pool_base.cc46
-rw-r--r--chromium/net/socket/client_socket_pool_base.h11
-rw-r--r--chromium/net/socket/client_socket_pool_base_unittest.cc29
-rw-r--r--chromium/net/socket/client_socket_pool_manager.cc13
-rw-r--r--chromium/net/socket/client_socket_pool_manager_impl.cc68
-rw-r--r--chromium/net/socket/client_socket_pool_manager_impl.h6
-rw-r--r--chromium/net/socket/deterministic_socket_data_unittest.cc621
-rw-r--r--chromium/net/socket/mock_client_socket_pool_manager.h2
-rw-r--r--chromium/net/socket/next_proto.cc10
-rw-r--r--chromium/net/socket/next_proto.h6
-rw-r--r--chromium/net/socket/nss_ssl_util.cc35
-rw-r--r--chromium/net/socket/sequenced_socket_data_unittest.cc169
-rw-r--r--chromium/net/socket/server_socket.cc2
-rw-r--r--chromium/net/socket/server_socket.h6
-rw-r--r--chromium/net/socket/socket.h6
-rw-r--r--chromium/net/socket/socket_descriptor.cc24
-rw-r--r--chromium/net/socket/socket_descriptor.h17
-rw-r--r--chromium/net/socket/socket_net_log_params.cc16
-rw-r--r--chromium/net/socket/socket_posix.cc14
-rw-r--r--chromium/net/socket/socket_posix.h8
-rw-r--r--chromium/net/socket/socket_test_util.cc886
-rw-r--r--chromium/net/socket/socket_test_util.h472
-rw-r--r--chromium/net/socket/socks5_client_socket.cc36
-rw-r--r--chromium/net/socket/socks5_client_socket.h16
-rw-r--r--chromium/net/socket/socks5_client_socket_unittest.cc8
-rw-r--r--chromium/net/socket/socks_client_socket.cc41
-rw-r--r--chromium/net/socket/socks_client_socket.h10
-rw-r--r--chromium/net/socket/socks_client_socket_pool.cc17
-rw-r--r--chromium/net/socket/socks_client_socket_pool.h2
-rw-r--r--chromium/net/socket/socks_client_socket_pool_unittest.cc4
-rw-r--r--chromium/net/socket/socks_client_socket_unittest.cc8
-rw-r--r--chromium/net/socket/ssl_client_socket.cc40
-rw-r--r--chromium/net/socket/ssl_client_socket.h38
-rw-r--r--chromium/net/socket/ssl_client_socket_nss.cc145
-rw-r--r--chromium/net/socket/ssl_client_socket_nss.h16
-rw-r--r--chromium/net/socket/ssl_client_socket_openssl.cc435
-rw-r--r--chromium/net/socket/ssl_client_socket_openssl.h36
-rw-r--r--chromium/net/socket/ssl_client_socket_openssl_unittest.cc22
-rw-r--r--chromium/net/socket/ssl_client_socket_pool.cc22
-rw-r--r--chromium/net/socket/ssl_client_socket_pool.h5
-rw-r--r--chromium/net/socket/ssl_client_socket_pool_unittest.cc8
-rw-r--r--chromium/net/socket/ssl_client_socket_unittest.cc1582
-rw-r--r--chromium/net/socket/ssl_server_socket.h10
-rw-r--r--chromium/net/socket/ssl_server_socket_nss.cc56
-rw-r--r--chromium/net/socket/ssl_server_socket_nss.h15
-rw-r--r--chromium/net/socket/ssl_server_socket_openssl.cc56
-rw-r--r--chromium/net/socket/ssl_server_socket_openssl.h16
-rw-r--r--chromium/net/socket/ssl_server_socket_unittest.cc42
-rw-r--r--chromium/net/socket/ssl_socket.h1
-rw-r--r--chromium/net/socket/stream_socket.h9
-rw-r--r--chromium/net/socket/tcp_client_socket.cc41
-rw-r--r--chromium/net/socket/tcp_client_socket.h14
-rw-r--r--chromium/net/socket/tcp_server_socket.cc12
-rw-r--r--chromium/net/socket/tcp_server_socket.h7
-rw-r--r--chromium/net/socket/tcp_server_socket_unittest.cc2
-rw-r--r--chromium/net/socket/tcp_socket_posix.cc12
-rw-r--r--chromium/net/socket/tcp_socket_posix.h13
-rw-r--r--chromium/net/socket/tcp_socket_unittest.cc5
-rw-r--r--chromium/net/socket/tcp_socket_win.cc27
-rw-r--r--chromium/net/socket/tcp_socket_win.h12
-rw-r--r--chromium/net/socket/transport_client_socket_pool.cc9
-rw-r--r--chromium/net/socket/transport_client_socket_pool.h2
-rw-r--r--chromium/net/socket/transport_client_socket_pool_test_util.cc35
-rw-r--r--chromium/net/socket/transport_client_socket_pool_unittest.cc5
-rw-r--r--chromium/net/socket/transport_client_socket_unittest.cc19
-rw-r--r--chromium/net/socket/unix_domain_client_socket_posix.cc14
-rw-r--r--chromium/net/socket/unix_domain_client_socket_posix.h8
-rw-r--r--chromium/net/socket/unix_domain_client_socket_posix_unittest.cc4
-rw-r--r--chromium/net/socket/unix_domain_server_socket_posix.cc8
-rw-r--r--chromium/net/socket/unix_domain_server_socket_posix.h4
-rw-r--r--chromium/net/socket/websocket_endpoint_lock_manager.h2
-rw-r--r--chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc11
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool.cc19
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool.h2
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc4
-rw-r--r--chromium/net/socket/websocket_transport_connect_sub_job.h5
-rw-r--r--chromium/net/spdy/bidirectional_stream_spdy_job.cc280
-rw-r--r--chromium/net/spdy/bidirectional_stream_spdy_job.h102
-rw-r--r--chromium/net/spdy/buffered_spdy_framer.cc95
-rw-r--r--chromium/net/spdy/buffered_spdy_framer.h58
-rw-r--r--chromium/net/spdy/buffered_spdy_framer_unittest.cc88
-rw-r--r--chromium/net/spdy/fuzzing/hpack_fuzz_mutator.cc5
-rw-r--r--chromium/net/spdy/fuzzing/hpack_fuzz_util.cc34
-rw-r--r--chromium/net/spdy/fuzzing/hpack_fuzz_util.h5
-rw-r--r--chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc8
-rw-r--r--chromium/net/spdy/hpack/hpack_constants.h19
-rw-r--r--chromium/net/spdy/hpack/hpack_decoder.cc56
-rw-r--r--chromium/net/spdy/hpack/hpack_decoder.h51
-rw-r--r--chromium/net/spdy/hpack/hpack_decoder_test.cc129
-rw-r--r--chromium/net/spdy/hpack/hpack_encoder.cc54
-rw-r--r--chromium/net/spdy/hpack/hpack_encoder.h26
-rw-r--r--chromium/net/spdy/hpack/hpack_encoder_test.cc94
-rw-r--r--chromium/net/spdy/hpack/hpack_entry.h3
-rw-r--r--chromium/net/spdy/hpack/hpack_header_table.h20
-rw-r--r--chromium/net/spdy/hpack/hpack_header_table_test.cc9
-rw-r--r--chromium/net/spdy/hpack/hpack_huffman_decoder.cc410
-rw-r--r--chromium/net/spdy/hpack/hpack_huffman_decoder.h70
-rw-r--r--chromium/net/spdy/hpack/hpack_huffman_decoder_test.cc292
-rw-r--r--chromium/net/spdy/hpack/hpack_huffman_table.cc63
-rw-r--r--chromium/net/spdy/hpack/hpack_huffman_table.h51
-rw-r--r--chromium/net/spdy/hpack/hpack_huffman_table_test.cc128
-rw-r--r--chromium/net/spdy/hpack/hpack_input_stream.cc80
-rw-r--r--chromium/net/spdy/hpack/hpack_input_stream.h35
-rw-r--r--chromium/net/spdy/hpack/hpack_input_stream_test.cc172
-rw-r--r--chromium/net/spdy/hpack/hpack_output_stream.cc10
-rw-r--r--chromium/net/spdy/hpack/hpack_output_stream.h8
-rw-r--r--chromium/net/spdy/hpack/hpack_output_stream_test.cc3
-rw-r--r--chromium/net/spdy/hpack/hpack_round_trip_test.cc12
-rw-r--r--chromium/net/spdy/hpack/hpack_static_table.cc9
-rw-r--r--chromium/net/spdy/hpack/hpack_static_table.h2
-rw-r--r--chromium/net/spdy/mock_spdy_framer_visitor.h11
-rw-r--r--chromium/net/spdy/priority_write_scheduler.h261
-rw-r--r--chromium/net/spdy/priority_write_scheduler_test.cc262
-rw-r--r--chromium/net/spdy/spdy_alt_svc_wire_format.cc99
-rw-r--r--chromium/net/spdy/spdy_alt_svc_wire_format.h73
-rw-r--r--chromium/net/spdy/spdy_alt_svc_wire_format_test.cc166
-rw-r--r--chromium/net/spdy/spdy_buffer.cc6
-rw-r--r--chromium/net/spdy/spdy_buffer.h2
-rw-r--r--chromium/net/spdy/spdy_buffer_producer.cc6
-rw-r--r--chromium/net/spdy/spdy_buffer_producer.h2
-rw-r--r--chromium/net/spdy/spdy_buffer_unittest.cc1
-rw-r--r--chromium/net/spdy/spdy_frame_builder.cc25
-rw-r--r--chromium/net/spdy/spdy_frame_builder.h36
-rw-r--r--chromium/net/spdy/spdy_frame_builder_test.cc5
-rw-r--r--chromium/net/spdy/spdy_frame_reader.cc40
-rw-r--r--chromium/net/spdy/spdy_frame_reader.h16
-rw-r--r--chromium/net/spdy/spdy_frame_reader_test.cc85
-rw-r--r--chromium/net/spdy/spdy_framer.cc342
-rw-r--r--chromium/net/spdy/spdy_framer.h68
-rw-r--r--chromium/net/spdy/spdy_framer_test.cc888
-rw-r--r--chromium/net/spdy/spdy_header_block.cc31
-rw-r--r--chromium/net/spdy/spdy_header_block.h10
-rw-r--r--chromium/net/spdy/spdy_header_block_test.cc26
-rw-r--r--chromium/net/spdy/spdy_headers_block_parser.cc32
-rw-r--r--chromium/net/spdy/spdy_headers_block_parser.h11
-rw-r--r--chromium/net/spdy/spdy_headers_block_parser_test.cc23
-rw-r--r--chromium/net/spdy/spdy_headers_handler_interface.h2
-rw-r--r--chromium/net/spdy/spdy_http_stream.cc120
-rw-r--r--chromium/net/spdy/spdy_http_stream.h17
-rw-r--r--chromium/net/spdy/spdy_http_stream_unittest.cc47
-rw-r--r--chromium/net/spdy/spdy_http_utils.cc21
-rw-r--r--chromium/net/spdy/spdy_http_utils_unittest.cc58
-rw-r--r--chromium/net/spdy/spdy_network_transaction_unittest.cc1100
-rw-r--r--chromium/net/spdy/spdy_pinnable_buffer_piece.h2
-rw-r--r--chromium/net/spdy/spdy_prefixed_buffer_reader.h2
-rw-r--r--chromium/net/spdy/spdy_priority_tree.h2
-rw-r--r--chromium/net/spdy/spdy_priority_tree_test.cc3
-rw-r--r--chromium/net/spdy/spdy_protocol.cc147
-rw-r--r--chromium/net/spdy/spdy_protocol.h106
-rw-r--r--chromium/net/spdy/spdy_protocol_test.cc37
-rw-r--r--chromium/net/spdy/spdy_proxy_client_socket.cc25
-rw-r--r--chromium/net/spdy/spdy_proxy_client_socket.h14
-rw-r--r--chromium/net/spdy/spdy_proxy_client_socket_unittest.cc407
-rw-r--r--chromium/net/spdy/spdy_read_queue.h2
-rw-r--r--chromium/net/spdy/spdy_session.cc455
-rw-r--r--chromium/net/spdy/spdy_session.h100
-rw-r--r--chromium/net/spdy/spdy_session_key.cc12
-rw-r--r--chromium/net/spdy/spdy_session_pool.cc9
-rw-r--r--chromium/net/spdy/spdy_session_pool.h4
-rw-r--r--chromium/net/spdy/spdy_session_pool_unittest.cc86
-rw-r--r--chromium/net/spdy/spdy_session_test_util.h7
-rw-r--r--chromium/net/spdy/spdy_session_unittest.cc789
-rw-r--r--chromium/net/spdy/spdy_stream.cc157
-rw-r--r--chromium/net/spdy/spdy_stream.h36
-rw-r--r--chromium/net/spdy/spdy_stream_test_util.cc3
-rw-r--r--chromium/net/spdy/spdy_stream_unittest.cc363
-rw-r--r--chromium/net/spdy/spdy_test_util_common.cc242
-rw-r--r--chromium/net/spdy/spdy_test_util_common.h108
-rw-r--r--chromium/net/spdy/spdy_test_utils.cc17
-rw-r--r--chromium/net/spdy/spdy_test_utils.h12
-rw-r--r--chromium/net/spdy/spdy_write_queue.h2
-rw-r--r--chromium/net/spdy/spdy_write_queue_unittest.cc61
-rw-r--r--chromium/net/spdy/write_blocked_list.h97
-rw-r--r--chromium/net/spdy/write_blocked_list_test.cc28
-rw-r--r--chromium/net/ssl/channel_id_service.cc24
-rw-r--r--chromium/net/ssl/channel_id_service.h20
-rw-r--r--chromium/net/ssl/channel_id_service_unittest.cc1
-rw-r--r--chromium/net/ssl/channel_id_store.cc8
-rw-r--r--chromium/net/ssl/client_cert_store.h2
-rw-r--r--chromium/net/ssl/client_cert_store_mac.h2
-rw-r--r--chromium/net/ssl/client_cert_store_nss.cc3
-rw-r--r--chromium/net/ssl/client_cert_store_win.cc41
-rw-r--r--chromium/net/ssl/client_cert_store_win.h20
-rw-r--r--chromium/net/ssl/client_key_store.cc7
-rw-r--r--chromium/net/ssl/client_key_store.h7
-rw-r--r--chromium/net/ssl/default_channel_id_store.cc33
-rw-r--r--chromium/net/ssl/default_channel_id_store.h7
-rw-r--r--chromium/net/ssl/default_channel_id_store_unittest.cc10
-rw-r--r--chromium/net/ssl/openssl_client_key_store.h2
-rw-r--r--chromium/net/ssl/openssl_ssl_util.cc42
-rw-r--r--chromium/net/ssl/openssl_ssl_util.h2
-rw-r--r--chromium/net/ssl/ssl_cipher_suite_names.cc31
-rw-r--r--chromium/net/ssl/ssl_cipher_suite_names.h22
-rw-r--r--chromium/net/ssl/ssl_cipher_suite_names_unittest.cc85
-rw-r--r--chromium/net/ssl/ssl_client_auth_cache.cc15
-rw-r--r--chromium/net/ssl/ssl_client_auth_cache.h20
-rw-r--r--chromium/net/ssl/ssl_client_auth_cache_unittest.cc94
-rw-r--r--chromium/net/ssl/ssl_client_session_cache_openssl.cc6
-rw-r--r--chromium/net/ssl/ssl_client_session_cache_openssl.h7
-rw-r--r--chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc70
-rw-r--r--chromium/net/ssl/ssl_config.cc3
-rw-r--r--chromium/net/ssl/ssl_config.h66
-rw-r--r--chromium/net/ssl/ssl_config_service_defaults.h1
-rw-r--r--chromium/net/ssl/ssl_config_service_unittest.cc3
-rw-r--r--chromium/net/ssl/ssl_connection_status_flags.h8
-rw-r--r--chromium/net/ssl/ssl_connection_status_flags_unittest.cc2
-rw-r--r--chromium/net/ssl/ssl_info.cc20
-rw-r--r--chromium/net/ssl/ssl_info.h19
-rw-r--r--chromium/net/ssl/ssl_key_logger.cc69
-rw-r--r--chromium/net/ssl/ssl_key_logger.h50
-rw-r--r--chromium/net/ssl/ssl_platform_key.h12
-rw-r--r--chromium/net/ssl/ssl_platform_key_android.cc41
-rw-r--r--chromium/net/ssl/ssl_platform_key_mac.cc15
-rw-r--r--chromium/net/ssl/ssl_platform_key_nss.cc30
-rw-r--r--chromium/net/ssl/ssl_platform_key_task_runner.cc31
-rw-r--r--chromium/net/ssl/ssl_platform_key_task_runner.h33
-rw-r--r--chromium/net/ssl/ssl_platform_key_win.cc23
-rw-r--r--chromium/net/ssl/ssl_private_key.h10
-rw-r--r--chromium/net/ssl/ssl_server_config.cc20
-rw-r--r--chromium/net/ssl/ssl_server_config.h63
-rw-r--r--chromium/net/ssl/threaded_ssl_private_key.cc15
-rw-r--r--chromium/net/ssl/threaded_ssl_private_key.h5
-rw-r--r--chromium/net/test/android/javatests/AndroidManifest.xml27
-rw-r--r--chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl41
-rw-r--r--chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerInterface.aidl5
-rw-r--r--chromium/net/test/android/net_test_entry_point.cc14
-rw-r--r--chromium/net/test/cert_test_util_nss.cc8
-rw-r--r--chromium/net/test/ct_test_util.cc64
-rw-r--r--chromium/net/test/ct_test_util.h20
-rw-r--r--chromium/net/test/embedded_test_server/OWNERS1
-rw-r--r--chromium/net/test/embedded_test_server/android/embedded_test_server_android.cc31
-rw-r--r--chromium/net/test/embedded_test_server/android/embedded_test_server_android.h22
-rw-r--r--chromium/net/test/embedded_test_server/default_handlers.cc639
-rw-r--r--chromium/net/test/embedded_test_server/default_handlers.h23
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.cc470
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.h215
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server_connection_listener.h9
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc272
-rw-r--r--chromium/net/test/embedded_test_server/http_connection.cc73
-rw-r--r--chromium/net/test/embedded_test_server/http_connection.h41
-rw-r--r--chromium/net/test/embedded_test_server/http_request.cc34
-rw-r--r--chromium/net/test/embedded_test_server/http_request.h22
-rw-r--r--chromium/net/test/embedded_test_server/http_response.cc32
-rw-r--r--chromium/net/test/embedded_test_server/http_response.h47
-rw-r--r--chromium/net/test/embedded_test_server/request_handler_util.cc229
-rw-r--r--chromium/net/test/embedded_test_server/request_handler_util.h63
-rw-r--r--chromium/net/test/embedded_test_server/stream_listen_socket.cc330
-rw-r--r--chromium/net/test/embedded_test_server/stream_listen_socket.h151
-rw-r--r--chromium/net/test/embedded_test_server/tcp_listen_socket.cc118
-rw-r--r--chromium/net/test/embedded_test_server/tcp_listen_socket.h57
-rw-r--r--chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.cc312
-rw-r--r--chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.h131
-rw-r--r--chromium/net/test/net_test_suite.cc5
-rw-r--r--chromium/net/test/net_test_suite.h5
-rw-r--r--chromium/net/test/python_utils_unittest.cc2
-rw-r--r--chromium/net/test/scoped_disable_exit_on_dfatal.h2
-rw-r--r--chromium/net/test/spawned_test_server/base_test_server.cc11
-rw-r--r--chromium/net/test/spawned_test_server/base_test_server.h9
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server.h1
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server_posix.cc12
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server_win.cc12
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server.cc11
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server.h1
-rw-r--r--chromium/net/test/spawned_test_server/spawner_communicator.cc16
-rw-r--r--chromium/net/test/spawned_test_server/spawner_communicator.h10
-rw-r--r--chromium/net/test/test_certificate_data.h234
-rw-r--r--chromium/net/test/url_request/ssl_certificate_error_job.cc1
-rw-r--r--chromium/net/test/url_request/url_request_failed_job.cc51
-rw-r--r--chromium/net/test/url_request/url_request_failed_job.h4
-rw-r--r--chromium/net/test/url_request/url_request_mock_data_job.cc55
-rw-r--r--chromium/net/test/url_request/url_request_mock_data_job.h18
-rw-r--r--chromium/net/test/url_request/url_request_mock_http_job.cc14
-rw-r--r--chromium/net/test/url_request/url_request_mock_http_job.h5
-rw-r--r--chromium/net/test/url_request/url_request_slow_download_job.cc28
-rw-r--r--chromium/net/test/url_request/url_request_slow_download_job.h4
-rw-r--r--chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp32
-rw-r--r--chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h2
-rw-r--r--chromium/net/third_party/mozilla_security_manager/nsPKCS12Blob.h2
-rw-r--r--chromium/net/third_party/nss/README.chromium14
-rw-r--r--chromium/net/third_party/nss/patches/aesgcmchromium.patch18
-rwxr-xr-xchromium/net/third_party/nss/patches/applypatches.sh6
-rw-r--r--chromium/net/third_party/nss/patches/cachecerts.patch38
-rw-r--r--chromium/net/third_party/nss/patches/cachelocks.patch42
-rw-r--r--chromium/net/third_party/nss/patches/chacha20poly1305.patch108
-rw-r--r--chromium/net/third_party/nss/patches/channelid.patch181
-rw-r--r--chromium/net/third_party/nss/patches/cipherorder.patch46
-rw-r--r--chromium/net/third_party/nss/patches/clientauth.patch94
-rw-r--r--chromium/net/third_party/nss/patches/dh1024.patch14
-rw-r--r--chromium/net/third_party/nss/patches/didhandshakeresume.patch20
-rw-r--r--chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch48
-rw-r--r--chromium/net/third_party/nss/patches/norenegotiatelock.patch15
-rw-r--r--chromium/net/third_party/nss/patches/nssrwlock.patch56
-rw-r--r--chromium/net/third_party/nss/patches/removebuildmetadata.patch27
-rw-r--r--chromium/net/third_party/nss/patches/reorderextensions.patch14
-rw-r--r--chromium/net/third_party/nss/patches/restartclientauth.patch40
-rw-r--r--chromium/net/third_party/nss/patches/secitemarray.patch20
-rw-r--r--chromium/net/third_party/nss/patches/secretexporterlocks.patch14
-rw-r--r--chromium/net/third_party/nss/patches/sessioncache.patch30
-rw-r--r--chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch171
-rw-r--r--chromium/net/third_party/nss/patches/suitebonly.patch12
-rw-r--r--chromium/net/third_party/nss/patches/tls12chromium.patch33
-rw-r--r--chromium/net/third_party/nss/patches/tlsunique.patch53
-rw-r--r--chromium/net/third_party/nss/ssl/SSLerrs.h24
-rw-r--r--chromium/net/third_party/nss/ssl/derive.c2
-rw-r--r--chromium/net/third_party/nss/ssl/dhe-param.c413
-rw-r--r--chromium/net/third_party/nss/ssl/dtlscon.c10
-rw-r--r--chromium/net/third_party/nss/ssl/ssl.h115
-rw-r--r--chromium/net/third_party/nss/ssl/ssl3con.c1803
-rw-r--r--chromium/net/third_party/nss/ssl/ssl3ecc.c48
-rw-r--r--chromium/net/third_party/nss/ssl/ssl3ext.c341
-rw-r--r--chromium/net/third_party/nss/ssl/ssl3gthr.c4
-rw-r--r--chromium/net/third_party/nss/ssl/ssl3prot.h30
-rw-r--r--chromium/net/third_party/nss/ssl/sslauth.c3
-rw-r--r--chromium/net/third_party/nss/ssl/sslcon.c40
-rw-r--r--chromium/net/third_party/nss/ssl/sslenum.c3
-rw-r--r--chromium/net/third_party/nss/ssl/sslerr.h16
-rw-r--r--chromium/net/third_party/nss/ssl/sslimpl.h79
-rw-r--r--chromium/net/third_party/nss/ssl/sslinfo.c49
-rw-r--r--chromium/net/third_party/nss/ssl/sslmutex.c2
-rw-r--r--chromium/net/third_party/nss/ssl/sslmutex.h9
-rw-r--r--chromium/net/third_party/nss/ssl/sslproto.h2
-rw-r--r--chromium/net/third_party/nss/ssl/sslsecur.c22
-rw-r--r--chromium/net/third_party/nss/ssl/sslsnce.c88
-rw-r--r--chromium/net/third_party/nss/ssl/sslsock.c261
-rw-r--r--chromium/net/third_party/nss/ssl/sslt.h61
-rw-r--r--chromium/net/third_party/nss/ssl/sslver.c17
-rw-r--r--chromium/net/tools/balsa/balsa_frame.cc2
-rw-r--r--chromium/net/tools/balsa/balsa_frame.h19
-rw-r--r--chromium/net/tools/balsa/balsa_headers.h2
-rw-r--r--chromium/net/tools/balsa/noop_balsa_visitor.h3
-rw-r--r--chromium/net/tools/balsa/simple_buffer.h1
-rw-r--r--chromium/net/tools/balsa/string_piece_utils.h2
-rw-r--r--chromium/net/tools/dafsa/PRESUBMIT.py (renamed from chromium/net/tools/tld_cleanup/PRESUBMIT.py)6
-rwxr-xr-xchromium/net/tools/dafsa/make_dafsa.py (renamed from chromium/net/tools/tld_cleanup/make_dafsa.py)0
-rwxr-xr-xchromium/net/tools/dafsa/make_dafsa_unittest.py (renamed from chromium/net/tools/tld_cleanup/make_dafsa_unittest.py)0
-rw-r--r--chromium/net/tools/disk_cache_memory_test/disk_cache_memory_test.cc40
-rw-r--r--chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc26
-rw-r--r--chromium/net/tools/dump_cache/dump_files.cc15
-rw-r--r--chromium/net/tools/epoll_server/epoll_server.cc58
-rw-r--r--chromium/net/tools/epoll_server/epoll_server.h46
-rw-r--r--chromium/net/tools/flip_server/acceptor_thread.cc1
-rw-r--r--chromium/net/tools/flip_server/create_listener.cc1
-rw-r--r--chromium/net/tools/flip_server/flip_in_mem_edsm_server.cc5
-rw-r--r--chromium/net/tools/flip_server/flip_test_utils.h22
-rw-r--r--chromium/net/tools/flip_server/http_interface.cc41
-rw-r--r--chromium/net/tools/flip_server/http_interface.h52
-rw-r--r--chromium/net/tools/flip_server/http_interface_test.cc12
-rw-r--r--chromium/net/tools/flip_server/loadtime_measurement.h97
-rw-r--r--chromium/net/tools/flip_server/mem_cache.cc25
-rw-r--r--chromium/net/tools/flip_server/mem_cache.h13
-rw-r--r--chromium/net/tools/flip_server/output_ordering.cc16
-rw-r--r--chromium/net/tools/flip_server/output_ordering.h17
-rw-r--r--chromium/net/tools/flip_server/sm_connection.cc6
-rw-r--r--chromium/net/tools/flip_server/sm_connection.h1
-rw-r--r--chromium/net/tools/flip_server/sm_interface.h27
-rw-r--r--chromium/net/tools/flip_server/spdy_interface.cc143
-rw-r--r--chromium/net/tools/flip_server/spdy_interface.h67
-rw-r--r--chromium/net/tools/flip_server/spdy_interface_test.cc42
-rw-r--r--chromium/net/tools/flip_server/streamer_interface.cc7
-rw-r--r--chromium/net/tools/flip_server/streamer_interface.h46
-rw-r--r--chromium/net/tools/flip_server/url_to_filename_encoder.cc27
-rw-r--r--chromium/net/tools/flip_server/url_to_filename_encoder.h2
-rw-r--r--chromium/net/tools/gdig/file_net_log.h1
-rw-r--r--chromium/net/tools/gdig/gdig.cc12
-rw-r--r--chromium/net/tools/get_server_time/get_server_time.cc22
-rwxr-xr-xchromium/net/tools/net_docs/net_docs.py3
-rw-r--r--chromium/net/tools/net_watcher/net_watcher.cc4
-rw-r--r--chromium/net/tools/quic/end_to_end_test.cc596
-rw-r--r--chromium/net/tools/quic/quic_client.cc77
-rw-r--r--chromium/net/tools/quic/quic_client.h30
-rw-r--r--chromium/net/tools/quic/quic_client_base.cc19
-rw-r--r--chromium/net/tools/quic/quic_client_base.h32
-rw-r--r--chromium/net/tools/quic/quic_client_bin.cc151
-rw-r--r--chromium/net/tools/quic/quic_client_session.cc37
-rw-r--r--chromium/net/tools/quic/quic_client_session.h26
-rw-r--r--chromium/net/tools/quic/quic_client_session_test.cc79
-rw-r--r--chromium/net/tools/quic/quic_client_test.cc17
-rw-r--r--chromium/net/tools/quic/quic_default_packet_writer.cc7
-rw-r--r--chromium/net/tools/quic/quic_default_packet_writer.h8
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.cc129
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.h88
-rw-r--r--chromium/net/tools/quic/quic_dispatcher_test.cc217
-rw-r--r--chromium/net/tools/quic/quic_epoll_clock.cc8
-rw-r--r--chromium/net/tools/quic/quic_epoll_clock.h8
-rw-r--r--chromium/net/tools/quic/quic_epoll_clock_test.cc29
-rw-r--r--chromium/net/tools/quic/quic_epoll_connection_helper.cc15
-rw-r--r--chromium/net/tools/quic/quic_epoll_connection_helper.h4
-rw-r--r--chromium/net/tools/quic/quic_in_memory_cache.cc118
-rw-r--r--chromium/net/tools/quic/quic_in_memory_cache.h84
-rw-r--r--chromium/net/tools/quic/quic_in_memory_cache_test.cc137
-rw-r--r--chromium/net/tools/quic/quic_packet_reader.cc20
-rw-r--r--chromium/net/tools/quic/quic_packet_reader.h10
-rw-r--r--chromium/net/tools/quic/quic_packet_writer_wrapper.h3
-rw-r--r--chromium/net/tools/quic/quic_per_connection_packet_writer.cc14
-rw-r--r--chromium/net/tools/quic/quic_per_connection_packet_writer.h13
-rw-r--r--chromium/net/tools/quic/quic_server.cc58
-rw-r--r--chromium/net/tools/quic/quic_server.h21
-rw-r--r--chromium/net/tools/quic/quic_server_bin.cc25
-rw-r--r--chromium/net/tools/quic/quic_server_session_base.cc (renamed from chromium/net/tools/quic/quic_server_session.cc)70
-rw-r--r--chromium/net/tools/quic/quic_server_session_base.h (renamed from chromium/net/tools/quic/quic_server_session.h)75
-rw-r--r--chromium/net/tools/quic/quic_server_session_base_test.cc (renamed from chromium/net/tools/quic/quic_server_session_test.cc)288
-rw-r--r--chromium/net/tools/quic/quic_server_test.cc7
-rw-r--r--chromium/net/tools/quic/quic_simple_client.cc75
-rw-r--r--chromium/net/tools/quic/quic_simple_client.h27
-rw-r--r--chromium/net/tools/quic/quic_simple_client_bin.cc139
-rw-r--r--chromium/net/tools/quic/quic_simple_client_test.cc9
-rw-r--r--chromium/net/tools/quic/quic_simple_per_connection_packet_writer.cc16
-rw-r--r--chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h9
-rw-r--r--chromium/net/tools/quic/quic_simple_server.cc95
-rw-r--r--chromium/net/tools/quic/quic_simple_server.h17
-rw-r--r--chromium/net/tools/quic/quic_simple_server_bin.cc25
-rw-r--r--chromium/net/tools/quic/quic_simple_server_packet_writer.cc15
-rw-r--r--chromium/net/tools/quic/quic_simple_server_packet_writer.h6
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session.cc186
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session.h154
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session_test.cc504
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream.cc247
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream.h81
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream_test.cc601
-rw-r--r--chromium/net/tools/quic/quic_simple_server_test.cc29
-rw-r--r--chromium/net/tools/quic/quic_socket_utils.cc42
-rw-r--r--chromium/net/tools/quic/quic_socket_utils.h3
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream.cc100
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream.h41
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream_test.cc103
-rw-r--r--chromium/net/tools/quic/quic_spdy_server_stream.cc199
-rw-r--r--chromium/net/tools/quic/quic_spdy_server_stream.h76
-rw-r--r--chromium/net/tools/quic/quic_spdy_server_stream_test.cc315
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.cc84
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.h50
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager_test.cc130
-rw-r--r--chromium/net/tools/quic/spdy_balsa_utils.cc122
-rw-r--r--chromium/net/tools/quic/spdy_balsa_utils.h16
-rw-r--r--chromium/net/tools/quic/spdy_balsa_utils_test.cc23
-rw-r--r--chromium/net/tools/quic/synchronous_host_resolver.cc14
-rw-r--r--chromium/net/tools/quic/test_tools/http_message.cc36
-rw-r--r--chromium/net/tools/quic/test_tools/http_message.h8
-rw-r--r--chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h4
-rw-r--r--chromium/net/tools/quic/test_tools/mock_epoll_server.cc24
-rw-r--r--chromium/net/tools/quic/test_tools/mock_epoll_server.h24
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_server_session_visitor.h3
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc5
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h7
-rw-r--r--chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc42
-rw-r--r--chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h32
-rw-r--r--chromium/net/tools/quic/test_tools/quic_client_peer.h2
-rw-r--r--chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc13
-rw-r--r--chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h8
-rw-r--r--chromium/net/tools/quic/test_tools/quic_in_memory_cache_peer.h1
-rw-r--r--chromium/net/tools/quic/test_tools/quic_server_peer.cc4
-rw-r--r--chromium/net/tools/quic/test_tools/quic_server_peer.h2
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.cc168
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.h74
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_server.cc171
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_server.h102
-rw-r--r--chromium/net/tools/quic/test_tools/server_thread.cc7
-rw-r--r--chromium/net/tools/quic/test_tools/server_thread.h2
-rw-r--r--chromium/net/tools/quic/test_tools/simple_client.cc8
-rw-r--r--chromium/net/tools/quic/test_tools/simple_client.h11
-rw-r--r--chromium/net/tools/stress_cache/stress_cache.cc2
-rw-r--r--chromium/net/tools/testserver/testserver.isolate15
-rwxr-xr-xchromium/net/tools/testserver/testserver.py149
-rw-r--r--chromium/net/udp/datagram_client_socket.h17
-rw-r--r--chromium/net/udp/datagram_server_socket.h10
-rw-r--r--chromium/net/udp/diff_serv_code_point.h42
-rw-r--r--chromium/net/udp/udp_client_socket.cc46
-rw-r--r--chromium/net/udp/udp_client_socket.h11
-rw-r--r--chromium/net/udp/udp_net_log_parameters.cc6
-rw-r--r--chromium/net/udp/udp_server_socket.cc6
-rw-r--r--chromium/net/udp/udp_server_socket.h11
-rw-r--r--chromium/net/udp/udp_socket_perftest.cc5
-rw-r--r--chromium/net/udp/udp_socket_posix.cc64
-rw-r--r--chromium/net/udp/udp_socket_posix.h21
-rw-r--r--chromium/net/udp/udp_socket_unittest.cc39
-rw-r--r--chromium/net/udp/udp_socket_win.cc25
-rw-r--r--chromium/net/udp/udp_socket_win.h20
-rw-r--r--chromium/net/url_request/certificate_report_sender.cc4
-rw-r--r--chromium/net/url_request/data_protocol_handler.h2
-rw-r--r--chromium/net/url_request/file_protocol_handler.h2
-rw-r--r--chromium/net/url_request/ftp_protocol_handler.h2
-rw-r--r--chromium/net/url_request/http_user_agent_settings.h2
-rw-r--r--chromium/net/url_request/sdch_dictionary_fetcher.cc1
-rw-r--r--chromium/net/url_request/sdch_dictionary_fetcher_unittest.cc19
-rw-r--r--chromium/net/url_request/static_http_user_agent_settings.h2
-rw-r--r--chromium/net/url_request/test_url_fetcher_factory.cc33
-rw-r--r--chromium/net/url_request/test_url_fetcher_factory.h11
-rw-r--r--chromium/net/url_request/test_url_request_interceptor.cc1
-rw-r--r--chromium/net/url_request/test_url_request_interceptor.h2
-rw-r--r--chromium/net/url_request/url_fetcher.h14
-rw-r--r--chromium/net/url_request/url_fetcher_core.cc48
-rw-r--r--chromium/net/url_request/url_fetcher_core.h34
-rw-r--r--chromium/net/url_request/url_fetcher_delegate.cc10
-rw-r--r--chromium/net/url_request/url_fetcher_delegate.h9
-rw-r--r--chromium/net/url_request/url_fetcher_impl.cc13
-rw-r--r--chromium/net/url_request/url_fetcher_impl.h9
-rw-r--r--chromium/net/url_request/url_fetcher_impl_unittest.cc104
-rw-r--r--chromium/net/url_request/url_fetcher_response_writer.h2
-rw-r--r--chromium/net/url_request/url_request.cc139
-rw-r--r--chromium/net/url_request/url_request.h77
-rw-r--r--chromium/net/url_request/url_request_backoff_manager.cc8
-rw-r--r--chromium/net/url_request/url_request_backoff_manager.h10
-rw-r--r--chromium/net/url_request/url_request_context.cc2
-rw-r--r--chromium/net/url_request/url_request_context.h1
-rw-r--r--chromium/net/url_request/url_request_context_builder.cc130
-rw-r--r--chromium/net/url_request/url_request_context_builder.h98
-rw-r--r--chromium/net/url_request/url_request_context_builder_unittest.cc53
-rw-r--r--chromium/net/url_request/url_request_context_storage.cc37
-rw-r--r--chromium/net/url_request/url_request_context_storage.h15
-rw-r--r--chromium/net/url_request/url_request_data_job.h1
-rw-r--r--chromium/net/url_request/url_request_data_job_unittest.cc2
-rw-r--r--chromium/net/url_request/url_request_error_job.cc5
-rw-r--r--chromium/net/url_request/url_request_error_job.h1
-rw-r--r--chromium/net/url_request/url_request_file_dir_job.cc56
-rw-r--r--chromium/net/url_request/url_request_file_dir_job.h9
-rw-r--r--chromium/net/url_request/url_request_file_job.cc68
-rw-r--r--chromium/net/url_request/url_request_file_job.h19
-rw-r--r--chromium/net/url_request/url_request_file_job_unittest.cc179
-rw-r--r--chromium/net/url_request/url_request_filter.cc22
-rw-r--r--chromium/net/url_request/url_request_filter.h9
-rw-r--r--chromium/net/url_request/url_request_filter_unittest.cc9
-rw-r--r--chromium/net/url_request/url_request_ftp_job.cc42
-rw-r--r--chromium/net/url_request/url_request_ftp_job.h3
-rw-r--r--chromium/net/url_request/url_request_ftp_job_unittest.cc110
-rw-r--r--chromium/net/url_request/url_request_http_job.cc182
-rw-r--r--chromium/net/url_request/url_request_http_job.h17
-rw-r--r--chromium/net/url_request/url_request_http_job_unittest.cc213
-rw-r--r--chromium/net/url_request/url_request_intercepting_job_factory.cc7
-rw-r--r--chromium/net/url_request/url_request_intercepting_job_factory.h2
-rw-r--r--chromium/net/url_request/url_request_job.cc467
-rw-r--r--chromium/net/url_request/url_request_job.h135
-rw-r--r--chromium/net/url_request/url_request_job_factory.h2
-rw-r--r--chromium/net/url_request/url_request_job_factory_impl.cc7
-rw-r--r--chromium/net/url_request/url_request_job_factory_impl.h4
-rw-r--r--chromium/net/url_request/url_request_job_manager.h1
-rw-r--r--chromium/net/url_request/url_request_job_unittest.cc132
-rw-r--r--chromium/net/url_request/url_request_netlog_params.cc6
-rw-r--r--chromium/net/url_request/url_request_netlog_params.h4
-rw-r--r--chromium/net/url_request/url_request_redirect_job.cc4
-rw-r--r--chromium/net/url_request/url_request_redirect_job.h4
-rw-r--r--chromium/net/url_request/url_request_simple_job.cc36
-rw-r--r--chromium/net/url_request/url_request_simple_job.h7
-rw-r--r--chromium/net/url_request/url_request_simple_job_unittest.cc20
-rw-r--r--chromium/net/url_request/url_request_status.cc15
-rw-r--r--chromium/net/url_request/url_request_status.h8
-rw-r--r--chromium/net/url_request/url_request_test_job.cc68
-rw-r--r--chromium/net/url_request/url_request_test_job.h12
-rw-r--r--chromium/net/url_request/url_request_test_util.cc58
-rw-r--r--chromium/net/url_request/url_request_test_util.h26
-rw-r--r--chromium/net/url_request/url_request_throttler_entry.cc5
-rw-r--r--chromium/net/url_request/url_request_throttler_entry.h6
-rw-r--r--chromium/net/url_request/url_request_throttler_entry_interface.h6
-rw-r--r--chromium/net/url_request/url_request_throttler_manager.h2
-rw-r--r--chromium/net/url_request/url_request_throttler_simulation_unittest.cc26
-rw-r--r--chromium/net/url_request/url_request_unittest.cc1914
-rw-r--r--chromium/net/url_request/view_cache_helper.h3
-rw-r--r--chromium/net/url_request/view_cache_helper_unittest.cc5
-rw-r--r--chromium/net/websockets/websocket_basic_handshake_stream.cc14
-rw-r--r--chromium/net/websockets/websocket_basic_handshake_stream.h2
-rw-r--r--chromium/net/websockets/websocket_basic_stream.cc78
-rw-r--r--chromium/net/websockets/websocket_basic_stream.h16
-rw-r--r--chromium/net/websockets/websocket_basic_stream_test.cc20
-rw-r--r--chromium/net/websockets/websocket_channel.cc146
-rw-r--r--chromium/net/websockets/websocket_channel.h96
-rw-r--r--chromium/net/websockets/websocket_channel_test.cc335
-rw-r--r--chromium/net/websockets/websocket_deflate_parameters.h1
-rw-r--r--chromium/net/websockets/websocket_deflate_predictor.h9
-rw-r--r--chromium/net/websockets/websocket_deflate_predictor_impl.cc2
-rw-r--r--chromium/net/websockets/websocket_deflate_predictor_impl.h10
-rw-r--r--chromium/net/websockets/websocket_deflate_predictor_impl_test.cc9
-rw-r--r--chromium/net/websockets/websocket_deflate_stream.cc84
-rw-r--r--chromium/net/websockets/websocket_deflate_stream.h30
-rw-r--r--chromium/net/websockets/websocket_deflate_stream_test.cc211
-rw-r--r--chromium/net/websockets/websocket_deflater.h4
-rw-r--r--chromium/net/websockets/websocket_end_to_end_test.cc43
-rw-r--r--chromium/net/websockets/websocket_event_interface.h8
-rw-r--r--chromium/net/websockets/websocket_extension_parser.h3
-rw-r--r--chromium/net/websockets/websocket_frame.cc67
-rw-r--r--chromium/net/websockets/websocket_frame.h8
-rw-r--r--chromium/net/websockets/websocket_frame_parser.cc52
-rw-r--r--chromium/net/websockets/websocket_frame_parser.h10
-rw-r--r--chromium/net/websockets/websocket_frame_parser_test.cc75
-rw-r--r--chromium/net/websockets/websocket_frame_perftest.cc8
-rw-r--r--chromium/net/websockets/websocket_frame_test.cc10
-rw-r--r--chromium/net/websockets/websocket_handshake_constants.h3
-rw-r--r--chromium/net/websockets/websocket_handshake_request_info.h1
-rw-r--r--chromium/net/websockets/websocket_handshake_response_info.h1
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_base.h2
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_create_helper.cc12
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_create_helper.h1
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc6
-rw-r--r--chromium/net/websockets/websocket_inflater.h4
-rw-r--r--chromium/net/websockets/websocket_stream.cc30
-rw-r--r--chromium/net/websockets/websocket_stream.h7
-rw-r--r--chromium/net/websockets/websocket_stream_cookie_test.cc4
-rw-r--r--chromium/net/websockets/websocket_stream_create_test_base.cc20
-rw-r--r--chromium/net/websockets/websocket_stream_create_test_base.h4
-rw-r--r--chromium/net/websockets/websocket_stream_test.cc51
-rw-r--r--chromium/net/websockets/websocket_test_util.cc41
-rw-r--r--chromium/net/websockets/websocket_test_util.h10
1968 files changed, 105538 insertions, 47061 deletions
diff --git a/chromium/net/BUILD.gn b/chromium/net/BUILD.gn
index 073c296380d..129003a5935 100644
--- a/chromium/net/BUILD.gn
+++ b/chromium/net/BUILD.gn
@@ -2,22 +2,17 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/buildflag_header.gni")
import("//build/config/chromecast_build.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/crypto.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
-import("//build/module_args/v8.gni")
+import("//build_overrides/v8.gni")
import("//testing/test.gni")
import("//third_party/icu/config.gni")
import("//third_party/protobuf/proto_library.gni")
-
-# TODO(cjhopman): //build/config/android/rules.gni also imports grit_rule.gni.
-# Currently, that file can't be imported multiple times. Make this always
-# imported when http://crbug.com/393704 is fixed.
-if (!is_android) {
- import("//tools/grit/grit_rule.gni")
-}
+import("//tools/grit/grit_rule.gni")
if (is_android) {
import("//build/config/android/config.gni")
@@ -32,9 +27,9 @@ gypi_values = exec_script("//build/gypi_to_gn.py",
"scope",
[ "net.gypi" ])
-# Disable Kerberos on ChromeOS, Android, iOS, and Chromecast, at least for now.
+# Disable Kerberos on ChromeOS, iOS, Chromecast and headless, at least for now.
# It needs configuration (krb5.conf and so on).
-use_kerberos = !is_chromeos && !is_android && !is_ios && !is_chromecast
+use_kerberos = !is_chromeos && !is_ios && !is_chromecast && !is_headless
# The way the cache uses mmap() is inefficient on some Android devices. If
# this flag is set, we hackily avoid using mmap() in the disk cache. We are
@@ -43,15 +38,20 @@ use_kerberos = !is_chromeos && !is_android && !is_ios && !is_chromecast
# So enable it for x86 only for now.
posix_avoid_mmap = is_android && current_cpu != "x86"
-# WebSockets and socket stream code are used everywhere except iOS.
-enable_websockets = !is_ios
use_v8_in_net = !is_ios
enable_built_in_dns = !is_ios
-disable_ftp_support = is_ios
declare_args() {
# Disables support for file URLs. File URL support requires use of icu.
disable_file_support = false
+
+ # Enables BidirectionalStream; Used in cronet, disabled by default.
+ enable_bidirectional_stream = false
+
+ # WebSockets and socket stream code are not used on iOS and are optional in
+ # cronet.
+ enable_websockets = !is_ios
+ disable_ftp_support = is_ios
}
config("net_config") {
@@ -62,6 +62,9 @@ config("net_config") {
if (disable_file_support) {
defines += [ "DISABLE_FILE_SUPPORT" ]
}
+ if (disable_ftp_support) {
+ defines += [ "DISABLE_FTP_SUPPORT=1" ]
+ }
}
# net_internal_config is shared with net and net_small.
@@ -102,6 +105,7 @@ net_shared_configs = [
]
net_shared_public_deps = [
+ ":features",
":net_quic_proto",
"//crypto",
"//crypto:platform",
@@ -165,6 +169,8 @@ if (!is_nacl) {
"quic/crypto/aes_128_gcm_12_encrypter_nss.cc",
"quic/crypto/chacha20_poly1305_decrypter_nss.cc",
"quic/crypto/chacha20_poly1305_encrypter_nss.cc",
+ "quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc",
+ "quic/crypto/chacha20_poly1305_rfc7539_encrypter_nss.cc",
"quic/crypto/channel_id_nss.cc",
"quic/crypto/p256_key_exchange_nss.cc",
"quic/crypto/proof_source_chromium_nss.cc",
@@ -198,6 +204,8 @@ if (!is_nacl) {
"quic/crypto/aes_128_gcm_12_encrypter_openssl.cc",
"quic/crypto/chacha20_poly1305_decrypter_openssl.cc",
"quic/crypto/chacha20_poly1305_encrypter_openssl.cc",
+ "quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc",
+ "quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc",
"quic/crypto/channel_id_openssl.cc",
"quic/crypto/p256_key_exchange_openssl.cc",
"quic/crypto/proof_source_chromium_openssl.cc",
@@ -211,7 +219,11 @@ if (!is_nacl) {
"ssl/openssl_ssl_util.h",
"ssl/ssl_client_session_cache_openssl.cc",
"ssl/ssl_client_session_cache_openssl.h",
+ "ssl/ssl_key_logger.cc",
+ "ssl/ssl_key_logger.h",
"ssl/ssl_platform_key.h",
+ "ssl/ssl_platform_key_task_runner.cc",
+ "ssl/ssl_platform_key_task_runner.h",
"ssl/threaded_ssl_private_key.cc",
"ssl/threaded_ssl_private_key.h",
]
@@ -242,11 +254,13 @@ if (!is_nacl) {
"cert/cert_database_openssl.cc",
"cert/cert_verify_proc_openssl.cc",
"cert/test_root_certs_openssl.cc",
+ "http/http_auth_gssapi_posix.cc",
+ "http/http_auth_gssapi_posix.h",
]
}
}
- if (use_glib && !is_chromeos) {
+ if (use_glib && use_gconf && !is_chromeos) {
net_shared_configs += [ "//build/config/linux:gconf" ]
net_shared_deps += [ "//build/linux:gio" ]
}
@@ -420,6 +434,10 @@ component("net") {
sources += gypi_values.net_ftp_support_sources
}
+ if (enable_bidirectional_stream) {
+ sources += gypi_values.net_bidirectional_stream_sources
+ }
+
if (enable_websockets) {
sources += gypi_values.net_websockets_sources
}
@@ -432,13 +450,17 @@ component("net") {
sources += [
"base/filename_util_icu.cc",
"base/net_string_util_icu.cc",
- "base/net_util_icu.cc",
]
+
+ # Brotli support.
+ deps += [ "//third_party/brotli" ]
+ sources += [ "filter/brotli_filter.cc" ]
}
}
if (is_android) {
- # Same as net, but with ICU, file, ftp, and websocket support stripped.
+ # Same as net, but with brotli encoding, ICU, file, ftp, and websocket
+ # support stripped.
component("net_small") {
sources = net_shared_sources
@@ -467,6 +489,13 @@ if (is_android) {
"base/net_string_util_icu_alternatives_android.cc",
"base/net_string_util_icu_alternatives_android.h",
]
+
+ # Disable Brotli support.
+ sources += [ "filter/brotli_filter_disabled.cc" ]
+
+ if (enable_bidirectional_stream) {
+ sources += gypi_values.net_bidirectional_stream_sources
+ }
}
}
@@ -570,6 +599,7 @@ source_set("test_support") {
"cookies/cookie_store_test_callbacks.h",
"cookies/cookie_store_test_helpers.cc",
"cookies/cookie_store_test_helpers.h",
+ "cookies/cookie_store_unittest.h",
"disk_cache/disk_cache_test_base.cc",
"disk_cache/disk_cache_test_base.h",
"disk_cache/disk_cache_test_util.cc",
@@ -603,6 +633,8 @@ source_set("test_support") {
"test/channel_id_test_util.h",
"test/ct_test_util.cc",
"test/ct_test_util.h",
+ "test/embedded_test_server/default_handlers.cc",
+ "test/embedded_test_server/default_handlers.h",
"test/embedded_test_server/embedded_test_server.cc",
"test/embedded_test_server/embedded_test_server.h",
"test/embedded_test_server/http_connection.cc",
@@ -611,15 +643,14 @@ source_set("test_support") {
"test/embedded_test_server/http_request.h",
"test/embedded_test_server/http_response.cc",
"test/embedded_test_server/http_response.h",
- "test/embedded_test_server/stream_listen_socket.cc",
- "test/embedded_test_server/stream_listen_socket.h",
- "test/embedded_test_server/tcp_listen_socket.cc",
- "test/embedded_test_server/tcp_listen_socket.h",
+ "test/embedded_test_server/request_handler_util.cc",
+ "test/embedded_test_server/request_handler_util.h",
"test/event_waiter.h",
"test/net_test_suite.cc",
"test/net_test_suite.h",
"test/python_utils.cc",
"test/python_utils.h",
+ "test/test_certificate_data.h",
"test/url_request/ssl_certificate_error_job.cc",
"test/url_request/ssl_certificate_error_job.h",
"test/url_request/url_request_failed_job.cc",
@@ -747,9 +778,11 @@ if (use_v8_in_net) {
]
defines = [ "NET_IMPLEMENTATION" ]
+
configs += [
"//build/config/compiler:no_size_t_to_int_warning",
"//build/config/compiler:wexit_time_destructors",
+ "//v8:external_startup_data",
]
public_deps = [
@@ -780,11 +813,11 @@ if (use_v8_in_net && !is_android) {
public_deps = [
":mojo_type_converters",
- ":net",
+ ":net_with_v8",
"//base",
"//mojo/common",
+ "//mojo/public/cpp/bindings",
"//net/interfaces",
- "//third_party/mojo/src/mojo/public/cpp/bindings",
# NOTE(amistry): As long as we support in-process Mojo v8 PAC, we need
# this dependency since in_process_mojo_proxy_resolver_factory creates
@@ -804,8 +837,9 @@ if (use_v8_in_net && !is_android) {
public_deps = [
":net",
+ "//base",
+ "//mojo/public/cpp/bindings",
"//net/interfaces",
- "//third_party/mojo/src/mojo/public/cpp/bindings",
]
}
@@ -822,14 +856,15 @@ if (use_v8_in_net && !is_android) {
deps = [
":net_with_v8",
+ "//base",
]
public_deps = [
":mojo_type_converters",
":net",
"//mojo/common",
+ "//mojo/public/cpp/bindings",
"//net/interfaces",
- "//third_party/mojo/src/mojo/public/cpp/bindings",
]
}
}
@@ -969,7 +1004,7 @@ if (!is_ios && !is_android) {
"//build/config/sanitizers:deps",
]
- if (is_desktop_linux && use_gconf) {
+ if (is_desktop_linux && use_gconf && use_glib) {
configs += [
"//build/config/linux:gconf",
"//build/config/linux:glib",
@@ -1049,7 +1084,6 @@ if (is_linux) {
"tools/flip_server/flip_config.h",
"tools/flip_server/http_interface.cc",
"tools/flip_server/http_interface.h",
- "tools/flip_server/loadtime_measurement.h",
"tools/flip_server/mem_cache.cc",
"tools/flip_server/mem_cache.h",
"tools/flip_server/output_ordering.cc",
@@ -1099,8 +1133,8 @@ if (is_linux) {
":net",
":test_support",
"//build/config/sanitizers:deps",
- "//testing/gtest",
"//testing/gmock",
+ "//testing/gtest",
"//third_party/boringssl",
]
}
@@ -1142,6 +1176,7 @@ if (is_linux) {
":balsa",
":epoll_server",
":net",
+ ":simple_quic_tools",
"//base",
"//base/third_party/dynamic_annotations",
"//crypto",
@@ -1156,8 +1191,8 @@ if (is_linux) {
]
deps = [
":balsa",
- ":epoll_server",
":epoll_quic_tools",
+ ":epoll_server",
":net",
":simple_quic_tools",
"//base",
@@ -1172,8 +1207,8 @@ if (is_linux) {
]
deps = [
":balsa",
- ":epoll_server",
":epoll_quic_tools",
+ ":epoll_server",
":net",
":simple_quic_tools",
"//base",
@@ -1189,7 +1224,6 @@ if (is_android) {
"android/java/src/org/chromium/net/AndroidCertVerifyResult.java",
"android/java/src/org/chromium/net/AndroidKeyStore.java",
"android/java/src/org/chromium/net/AndroidNetworkLibrary.java",
- "android/java/src/org/chromium/net/AndroidPrivateKey.java",
"android/java/src/org/chromium/net/AndroidTrafficStats.java",
"android/java/src/org/chromium/net/GURLUtils.java",
"android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java",
@@ -1204,6 +1238,7 @@ if (is_android) {
sources = [
"android/javatests/src/org/chromium/net/AndroidKeyStoreTestUtil.java",
"test/android/javatests/src/org/chromium/net/test/DummySpnegoAuthenticator.java",
+ "test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java",
]
jni_package = "net/test"
}
@@ -1235,8 +1270,8 @@ source_set("simple_quic_tools") {
"tools/quic/quic_in_memory_cache.h",
"tools/quic/quic_per_connection_packet_writer.cc",
"tools/quic/quic_per_connection_packet_writer.h",
- "tools/quic/quic_server_session.cc",
- "tools/quic/quic_server_session.h",
+ "tools/quic/quic_server_session_base.cc",
+ "tools/quic/quic_server_session_base.h",
"tools/quic/quic_simple_client.cc",
"tools/quic/quic_simple_client.h",
"tools/quic/quic_simple_per_connection_packet_writer.cc",
@@ -1245,16 +1280,19 @@ source_set("simple_quic_tools") {
"tools/quic/quic_simple_server.h",
"tools/quic/quic_simple_server_packet_writer.cc",
"tools/quic/quic_simple_server_packet_writer.h",
+ "tools/quic/quic_simple_server_session.cc",
+ "tools/quic/quic_simple_server_session.h",
+ "tools/quic/quic_simple_server_stream.cc",
+ "tools/quic/quic_simple_server_stream.h",
"tools/quic/quic_spdy_client_stream.cc",
"tools/quic/quic_spdy_client_stream.h",
- "tools/quic/quic_spdy_server_stream.cc",
- "tools/quic/quic_spdy_server_stream.h",
"tools/quic/quic_time_wait_list_manager.cc",
"tools/quic/quic_time_wait_list_manager.h",
"tools/quic/synchronous_host_resolver.cc",
"tools/quic/synchronous_host_resolver.h",
]
deps = [
+ ":balsa",
":net",
"//base",
"//base/third_party/dynamic_annotations",
@@ -1262,6 +1300,34 @@ source_set("simple_quic_tools") {
]
}
+action_foreach("stale_while_revalidate_experiment_domains_dafsa") {
+ script = "//net/tools/dafsa/make_dafsa.py"
+ sources = [
+ "base/stale_while_revalidate_experiment_domains.gperf",
+ ]
+ outputs = [
+ "${target_gen_dir}/base/{{source_name_part}}-inc.cc",
+ ]
+ args = [
+ "{{source}}",
+ rebase_path("${target_gen_dir}/base/{{source_name_part}}-inc.cc",
+ root_build_dir),
+ ]
+}
+
+source_set("stale_while_revalidate_experiment_domains") {
+ sources = [
+ "base/stale_while_revalidate_experiment_domains.cc",
+ "base/stale_while_revalidate_experiment_domains.h",
+ ]
+ deps = [
+ ":net",
+ ":stale_while_revalidate_experiment_domains_dafsa",
+ "//base",
+ ]
+ configs += net_shared_configs
+}
+
if (!is_ios) {
executable("quic_client") {
sources = [
@@ -1324,6 +1390,7 @@ test("net_unittests") {
":http_server",
":net",
":simple_quic_tools",
+ ":stale_while_revalidate_experiment_domains",
":test_support",
"//base",
"//base:i18n",
@@ -1403,14 +1470,9 @@ test("net_unittests") {
}
if (use_openssl) {
- # When building for OpenSSL, we need to exclude NSS specific tests
- # or functionality not supported by OpenSSL yet.
- # TODO(bulach): Add equivalent tests when the underlying
- # functionality is ported to OpenSSL.
sources -= [ "quic/test_tools/crypto_test_utils_nss.cc" ]
} else {
sources -= [
- "cert/x509_util_openssl_unittest.cc",
"quic/test_tools/crypto_test_utils_openssl.cc",
"socket/ssl_client_socket_openssl_unittest.cc",
"ssl/ssl_client_session_cache_openssl_unittest.cc",
@@ -1434,7 +1496,7 @@ test("net_unittests") {
sources -= [ "http/http_auth_handler_negotiate_unittest.cc" ]
}
- if (use_openssl || (!is_desktop_linux && !is_chromeos && !is_ios)) {
+ if (!use_nss_certs && !is_ios) {
# Only include this test when on Posix and using NSS for
# cert verification or on iOS (which also uses NSS for certs).
sources -= [ "cert_net/nss_ocsp_unittest.cc" ]
@@ -1452,12 +1514,14 @@ test("net_unittests") {
"server/web_socket_encoder_unittest.cc",
"websockets/websocket_basic_stream_test.cc",
"websockets/websocket_channel_test.cc",
+ "websockets/websocket_deflate_parameters_test.cc",
"websockets/websocket_deflate_predictor_impl_test.cc",
"websockets/websocket_deflate_stream_test.cc",
"websockets/websocket_deflater_test.cc",
"websockets/websocket_end_to_end_test.cc",
"websockets/websocket_errors_test.cc",
"websockets/websocket_extension_parser_test.cc",
+ "websockets/websocket_extension_test.cc",
"websockets/websocket_frame_parser_test.cc",
"websockets/websocket_frame_test.cc",
"websockets/websocket_handshake_challenge_test.cc",
@@ -1473,6 +1537,7 @@ test("net_unittests") {
if (disable_file_support) {
sources -= [
"base/directory_lister_unittest.cc",
+ "base/directory_listing_unittest.cc",
"url_request/url_request_file_job_unittest.cc",
]
}
@@ -1492,6 +1557,9 @@ test("net_unittests") {
]
}
+ if (!enable_bidirectional_stream) {
+ sources -= [ "http/bidirectional_stream_unittest.cc" ]
+ }
if (!enable_built_in_dns) {
sources -= [
"dns/address_sorter_posix_unittest.cc",
@@ -1544,11 +1612,14 @@ test("net_unittests") {
# 'action_name': 'copy_test_data',
# 'variables': {
# 'test_data_files': [
+ # 'data/certificate_policies_unittest/',
+ # 'data/name_constraints_unittest/',
+ # 'data/parse_certificate_unittest/',
# 'data/ssl/certificates/',
# 'data/test.html',
# 'data/url_request_unittest/',
+ # 'data/verify_certificate_chain_unittest/',
# 'data/verify_name_match_unittest/names/',
- # 'data/parse_certificate_unittest/',
# ],
# 'test_data_prefix': 'net',
# },
@@ -1564,6 +1635,7 @@ test("net_unittests") {
"disk_cache/blockfile/block_files_unittest.cc",
# Need to read input data files.
+ "filter/brotli_filter_unittest.cc",
"filter/gzip_filter_unittest.cc",
"socket/ssl_server_socket_unittest.cc",
"spdy/fuzzing/hpack_fuzz_util_test.cc",
@@ -1590,17 +1662,23 @@ test("net_unittests") {
}
if (is_android) {
- sources -= [
- # See bug http://crbug.com/344533.
- "disk_cache/blockfile/index_table_v3_unittest.cc",
- "dns/dns_config_service_posix_unittest.cc",
- ]
deps += [
":net_test_jni_headers",
+ "//base:base_java_unittest_support",
+ "//net/android:net_java",
+ "//net/android:net_java_test_support",
+ "//net/android:net_javatests",
+ "//net/android:net_unittests_apk_resources",
# TODO(mmenke): This depends on test_support_base, which depends on
# icu. Figure out a way to remove that dependency.
"//testing/android/native_test:native_test_native_code",
+ "//v8:v8_external_startup_data_assets",
+ ]
+ android_manifest = "//net/android/unittest_support/AndroidManifest.xml"
+ sources -= [
+ # See bug http://crbug.com/344533.
+ "disk_cache/blockfile/index_table_v3_unittest.cc",
]
set_sources_assignment_filter([])
sources += [ "base/address_tracker_linux_unittest.cc" ]
@@ -1655,3 +1733,9 @@ executable("net_perftests") {
sources -= [ "proxy/proxy_resolver_perftest.cc" ]
}
}
+
+buildflag_header("features") {
+ header = "net_features.h"
+
+ flags = [ "ENABLE_BIDIRECTIONAL_STREAM=$enable_bidirectional_stream" ]
+}
diff --git a/chromium/net/DEPS b/chromium/net/DEPS
index fd0fd480cde..6f3c3d3c972 100644
--- a/chromium/net/DEPS
+++ b/chromium/net/DEPS
@@ -3,17 +3,18 @@ include_rules = [
"+gin",
"+jni",
"+mojo/common",
+ "+mojo/public",
"+third_party/apple_apsl",
- "+third_party/mojo/src/mojo/public",
"+third_party/nss",
"+third_party/protobuf/src/google/protobuf",
"+third_party/zlib",
"+sdch/open-vcdiff",
"+v8",
- # Most of net should not depend on icu, to keep size down when built as a
- # library.
+ # Most of net should not depend on icu, and brotli to keep size down when
+ # built as a library.
"-base/i18n",
+ "-third_party/brotli",
"-third_party/icu",
]
@@ -23,17 +24,16 @@ specific_include_rules = {
"+base/i18n",
],
+ # Functions largely not used by the rest of net.
+ "directory_listing\.cc": [
+ "+base/i18n",
+ ],
+
# Within net, only used by file: requests.
"filename_util_icu\.cc": [
"+base/i18n/file_util_icu.h",
],
- # Functions largely not used by the rest of net.
- "net_util_icu\.cc": [
- "+base/i18n",
- "+third_party/icu",
- ],
-
# Consolidated string functions that depend on icu.
"net_string_util_icu\.cc": [
"+base/i18n/i18n_constants.h",
@@ -56,6 +56,10 @@ specific_include_rules = {
"run_all_unittests\.cc": [
"+third_party/mojo/src/mojo/edk",
],
+
+ "brotli_filter\.cc": [
+ "+third_party/brotli",
+ ],
}
skip_child_includes = [
diff --git a/chromium/net/OWNERS b/chromium/net/OWNERS
index a2863ba26e3..808c8631344 100644
--- a/chromium/net/OWNERS
+++ b/chromium/net/OWNERS
@@ -1,8 +1,8 @@
agl@chromium.org
asanka@chromium.org
+bnc@chromium.org
cbentzel@chromium.org
davidben@chromium.org
-ellyjones@chromium.org
eroman@chromium.org
gavinp@chromium.org
jar@chromium.org
@@ -20,8 +20,3 @@ xunjieli@chromium.org
per-file *.isolate=maruel@chromium.org
per-file *.isolate=tandrii@chromium.org
per-file *.isolate=vadimsh@chromium.org
-
-# Don't use as a reviewer for new CLs, but still here
-# so he can continue to review some already in-progress
-# work.
-szym@chromium.org
diff --git a/chromium/net/android/BUILD.gn b/chromium/net/android/BUILD.gn
index 0003962fb89..a1c23f4e320 100644
--- a/chromium/net/android/BUILD.gn
+++ b/chromium/net/android/BUILD.gn
@@ -13,35 +13,82 @@ android_library("net_java") {
srcjar_deps = [
":net_errors_java",
":net_android_java_enums_srcjar",
- ":remote_android_keystore_aidl",
]
}
-android_aidl("remote_android_keystore_aidl") {
- interface_file =
- "java/src/org/chromium/net/IRemoteAndroidKeyStoreInterface.aidl"
+android_aidl("embedded_test_server_aidl") {
+ interface_file = "../test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerInterface.aidl"
sources = [
- "java/src/org/chromium/net/IRemoteAndroidKeyStore.aidl",
- "java/src/org/chromium/net/IRemoteAndroidKeyStoreCallbacks.aidl",
+ "../test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl",
]
}
android_library("net_java_test_support") {
+ testonly = true
DEPRECATED_java_in_dir = "../test/android/javatests/src"
deps = [
+ ":net_java",
"//base:base_java",
+ "//base:base_java_test_support",
"//third_party/android_tools:legacy_http_javalib",
- ":net_java",
]
- srcjar_deps = [ ":net_java_test_support_enums_srcjar" ]
+ srcjar_deps = [
+ ":embedded_test_server_aidl",
+ ":net_java_test_support_enums_srcjar",
+ ]
+}
+
+source_set("java_test_native_support") {
+ testonly = true
+ sources = [
+ "../test/android/net_test_entry_point.cc",
+ "../test/android/net_test_jni_onload.cc",
+ "../test/android/net_test_jni_onload.h",
+ "../test/embedded_test_server/android/embedded_test_server_android.cc",
+ "../test/embedded_test_server/android/embedded_test_server_android.h",
+ ]
+
+ deps = [
+ "//net:test_support",
+ ]
+ public_deps = [
+ "//net:net_test_jni_headers",
+ ]
+}
+
+shared_library("net_java_test_native_support") {
+ testonly = true
+ deps = [
+ ":java_test_native_support",
+ "//net:test_support",
+ ]
+}
+
+android_apk("net_test_support_apk") {
+ testonly = true
+ deps = [
+ ":net_java_test_native_support",
+ ":net_java_test_support",
+ "//base:base_java",
+ ]
+ android_manifest = "../test/android/javatests/AndroidManifest.xml"
+ apk_name = "ChromiumNetTestSupport"
+ native_libs = [ "libnet_java_test_native_support.so" ]
+}
+
+android_resources("net_unittests_apk_resources") {
+ resource_dirs = [ "unittest_support/res" ]
+ custom_package = "org.chromium.native_test"
}
android_library("net_javatests") {
+ testonly = true
DEPRECATED_java_in_dir = "javatests/src"
deps = [
+ ":net_java",
+ ":net_java_test_support",
"//base:base_java",
"//base:base_java_test_support",
- ":net_java",
]
}
@@ -59,9 +106,6 @@ java_cpp_enum("net_java_test_support_enums_srcjar") {
sources = [
"../test/url_request/url_request_failed_job.h",
]
- outputs = [
- "org/chromium/net/test/FailurePhase.java",
- ]
}
java_cpp_enum("net_android_java_enums_srcjar") {
@@ -70,16 +114,9 @@ java_cpp_enum("net_android_java_enums_srcjar") {
"../base/network_change_notifier.h",
"cert_verify_result_android.h",
"keystore.h",
+ "network_change_notifier_android.cc",
"traffic_stats.cc",
]
- outputs = [
- "org/chromium/net/CertificateMimeType.java",
- "org/chromium/net/CertVerifyStatusAndroid.java",
- "org/chromium/net/ConnectionSubtype.java",
- "org/chromium/net/ConnectionType.java",
- "org/chromium/net/PrivateKeyType.java",
- "org/chromium/net/TrafficStatsError.java",
- ]
}
junit_binary("net_junit_tests") {
@@ -93,15 +130,3 @@ junit_binary("net_junit_tests") {
"//third_party/junit:hamcrest",
]
}
-
-# TODO(GYP)
-if (false) {
- unittest_apk("net_unittests_apk") {
- deps = [
- ":net_java",
- ":net_javatests",
- "//net:net_unittests",
- ]
- unittests_dep = "//net:net_unittests"
- }
-}
diff --git a/chromium/net/android/android_private_key.cc b/chromium/net/android/android_private_key.cc
deleted file mode 100644
index 8f56085ad7c..00000000000
--- a/chromium/net/android/android_private_key.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014 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/android/android_private_key.h"
-
-#include <vector>
-#include "jni/AndroidPrivateKey_jni.h"
-
-namespace net {
-namespace android {
-
-base::android::ScopedJavaLocalRef<jobject> GetKeyStore(
- jobject private_key_ref) {
- JNIEnv* env = base::android::AttachCurrentThread();
- return Java_AndroidPrivateKey_getKeyStore(
- env, private_key_ref);
-}
-
-bool RegisterAndroidPrivateKey(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-} // namespace android
-} // namespace net
diff --git a/chromium/net/android/android_private_key.h b/chromium/net/android/android_private_key.h
deleted file mode 100644
index 24f4f45e71f..00000000000
--- a/chromium/net/android/android_private_key.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 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_ANDROID_ANDROID_PRIVATE_KEY_H
-#define NET_ANDROID_ANDROID_PRIVATE_KEY_H
-
-#include <jni.h>
-
-#include "base/android/scoped_java_ref.h"
-#include "net/base/net_export.h"
-
-
-namespace net {
-namespace android {
-
-// Returns the KeyStore associated with a given AndroidPrivateKey
-NET_EXPORT base::android::ScopedJavaLocalRef<jobject> GetKeyStore(
- jobject private_key);
-
-// Register JNI methods
-NET_EXPORT bool RegisterAndroidPrivateKey(JNIEnv* env);
-
-} // namespace android
-} // namespace net
-
-#endif // NET_ANDROID_ANDROID_PRIVATE_KEY_H
diff --git a/chromium/net/android/dummy_spnego_authenticator.cc b/chromium/net/android/dummy_spnego_authenticator.cc
index d42f64c5f41..2bb4ef450bb 100644
--- a/chromium/net/android/dummy_spnego_authenticator.cc
+++ b/chromium/net/android/dummy_spnego_authenticator.cc
@@ -135,18 +135,19 @@ DummySpnegoAuthenticator::SecurityContextQuery::~SecurityContextQuery() {
base::android::ScopedJavaLocalRef<jstring>
DummySpnegoAuthenticator::SecurityContextQuery::GetTokenToReturn(
JNIEnv* env,
- jobject /*obj*/) {
+ const JavaParamRef<jobject>& /*obj*/) {
return base::android::ConvertUTF8ToJavaString(env, output_token.c_str());
}
-int DummySpnegoAuthenticator::SecurityContextQuery::GetResult(JNIEnv* /*env*/,
- jobject /*obj*/) {
+int DummySpnegoAuthenticator::SecurityContextQuery::GetResult(
+ JNIEnv* /*env*/,
+ const JavaParamRef<jobject>& /*obj*/) {
return response_code;
}
void DummySpnegoAuthenticator::SecurityContextQuery::CheckGetTokenArguments(
JNIEnv* env,
- jobject /*obj*/,
- jstring j_incoming_token) {
+ const JavaParamRef<jobject>& /*obj*/,
+ const JavaParamRef<jstring>& j_incoming_token) {
std::string incoming_token =
base::android::ConvertJavaStringToUTF8(env, j_incoming_token);
EXPECT_EQ(expected_input_token, incoming_token);
@@ -188,8 +189,9 @@ bool DummySpnegoAuthenticator::RegisterJni(JNIEnv* env) {
return RegisterNativesImpl(env);
}
-long DummySpnegoAuthenticator::GetNextQuery(JNIEnv* /*env*/,
- jobject /* obj */) {
+long DummySpnegoAuthenticator::GetNextQuery(
+ JNIEnv* /*env*/,
+ const JavaParamRef<jobject>& /* obj */) {
CheckQueueNotEmpty();
current_query_ = expected_security_queries_.front();
expected_security_queries_.pop_front();
diff --git a/chromium/net/android/dummy_spnego_authenticator.h b/chromium/net/android/dummy_spnego_authenticator.h
index a7d4a97f2d9..1f37bd37ddc 100644
--- a/chromium/net/android/dummy_spnego_authenticator.h
+++ b/chromium/net/android/dummy_spnego_authenticator.h
@@ -6,6 +6,8 @@
#define NET_ANDROID_DUMMY_SPNEGO_AUTHENTICATOR_H_
#include <jni.h>
+#include <stdint.h>
+
#include <cstdint>
#include <list>
#include <string>
@@ -93,16 +95,18 @@ class DummySpnegoAuthenticator {
std::string output_token;
// Java callable members
- base::android::ScopedJavaLocalRef<jstring> GetTokenToReturn(JNIEnv* env,
- jobject obj);
- int GetResult(JNIEnv* env, jobject obj);
+ base::android::ScopedJavaLocalRef<jstring> GetTokenToReturn(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+ int GetResult(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
// Called from Java to check the arguments passed to the GetToken. Has to
// be in C++ since these tests are driven by googletest, and can only report
// failures through the googletest C++ API.
- void CheckGetTokenArguments(JNIEnv* env,
- jobject obj,
- jstring incoming_token);
+ void CheckGetTokenArguments(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jstring>& incoming_token);
};
DummySpnegoAuthenticator();
@@ -121,7 +125,8 @@ class DummySpnegoAuthenticator {
static void EnsureTestAccountExists();
static void RemoveTestAccounts();
- long GetNextQuery(JNIEnv* env, jobject obj);
+ long GetNextQuery(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
private:
// Abandon the test if the query queue is empty. Has to be a void function to
diff --git a/chromium/net/android/http_auth_negotiate_android.cc b/chromium/net/android/http_auth_negotiate_android.cc
index a8e9cc3009a..907cff3aec8 100644
--- a/chromium/net/android/http_auth_negotiate_android.cc
+++ b/chromium/net/android/http_auth_negotiate_android.cc
@@ -15,6 +15,7 @@
#include "net/base/net_errors.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_multi_round_parse.h"
+#include "net/http/http_auth_preferences.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
@@ -35,9 +36,9 @@ JavaNegotiateResultWrapper::~JavaNegotiateResultWrapper() {
}
void JavaNegotiateResultWrapper::SetResult(JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
int result,
- jstring token) {
+ const JavaParamRef<jstring>& token) {
// This will be called on the UI thread, so we have to post a task back to the
// correct thread to actually save the result
std::string raw_token = ConvertJavaStringToUTF8(env, token);
@@ -54,16 +55,17 @@ void JavaNegotiateResultWrapper::SetResult(JNIEnv* env,
}
HttpAuthNegotiateAndroid::HttpAuthNegotiateAndroid(
- const std::string& account_type)
- : account_type_(account_type),
+ const HttpAuthPreferences* prefs)
+ : prefs_(prefs),
can_delegate_(false),
first_challenge_(true),
auth_token_(nullptr),
weak_factory_(this) {
- DCHECK(!account_type.empty());
JNIEnv* env = AttachCurrentThread();
java_authenticator_.Reset(Java_HttpNegotiateAuthenticator_create(
- env, ConvertUTF8ToJavaString(env, account_type).obj()));
+ env,
+ ConvertUTF8ToJavaString(env, prefs->AuthAndroidNegotiateAccountType())
+ .obj()));
}
HttpAuthNegotiateAndroid::~HttpAuthNegotiateAndroid() {
@@ -101,6 +103,11 @@ int HttpAuthNegotiateAndroid::GenerateAuthToken(
const std::string& spn,
std::string* auth_token,
const net::CompletionCallback& callback) {
+ if (prefs_->AuthAndroidNegotiateAccountType().empty()) {
+ // This can happen if there is a policy change, removing the account type,
+ // in the middle of a negotiation.
+ return ERR_UNSUPPORTED_AUTH_SCHEME;
+ }
DCHECK(auth_token);
DCHECK(completion_callback_.is_null());
DCHECK(!callback.is_null());
@@ -117,7 +124,7 @@ int HttpAuthNegotiateAndroid::GenerateAuthToken(
ConvertUTF8ToJavaString(env, server_auth_token_);
ScopedJavaLocalRef<jstring> java_spn = ConvertUTF8ToJavaString(env, spn);
ScopedJavaLocalRef<jstring> java_account_type =
- ConvertUTF8ToJavaString(env, account_type_);
+ ConvertUTF8ToJavaString(env, prefs_->AuthAndroidNegotiateAccountType());
// It is intentional that callback_wrapper is not owned or deleted by the
// HttpAuthNegotiateAndroid object. The Java code will call the callback
diff --git a/chromium/net/android/http_auth_negotiate_android.h b/chromium/net/android/http_auth_negotiate_android.h
index 56990cee900..1b337261fcd 100644
--- a/chromium/net/android/http_auth_negotiate_android.h
+++ b/chromium/net/android/http_auth_negotiate_android.h
@@ -19,6 +19,7 @@
namespace net {
class HttpAuthChallengeTokenizer;
+class HttpAuthPreferences;
namespace android {
@@ -40,7 +41,10 @@ class NET_EXPORT_PRIVATE JavaNegotiateResultWrapper {
const base::Callback<void(int, const std::string&)>&
thread_safe_callback);
- void SetResult(JNIEnv* env, jobject obj, int result, jstring token);
+ void SetResult(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ int result,
+ const base::android::JavaParamRef<jstring>& token);
private:
// Class is only allowed to delete itself, nobody else is allowed to delete.
@@ -55,9 +59,10 @@ class NET_EXPORT_PRIVATE JavaNegotiateResultWrapper {
// for the full details.
class NET_EXPORT_PRIVATE HttpAuthNegotiateAndroid {
public:
- // Creates an object for one negotiation session. |account_type| is the
- // Android account type, used by Android to find the correct authenticator.
- explicit HttpAuthNegotiateAndroid(const std::string& account_type);
+ // Creates an object for one negotiation session. |prefs| are the
+ // authentication preferences. In particular they include the Android account
+ // type, which is used to connect to the correct Android Authenticator.
+ explicit HttpAuthNegotiateAndroid(const HttpAuthPreferences* prefs);
~HttpAuthNegotiateAndroid();
// Register the JNI for this class.
@@ -113,7 +118,7 @@ class NET_EXPORT_PRIVATE HttpAuthNegotiateAndroid {
private:
void SetResultInternal(int result, const std::string& token);
- std::string account_type_;
+ const HttpAuthPreferences* prefs_;
bool can_delegate_;
bool first_challenge_;
std::string server_auth_token_;
diff --git a/chromium/net/android/http_auth_negotiate_android_unittest.cc b/chromium/net/android/http_auth_negotiate_android_unittest.cc
index b1e178f588d..8e3de79485c 100644
--- a/chromium/net/android/http_auth_negotiate_android_unittest.cc
+++ b/chromium/net/android/http_auth_negotiate_android_unittest.cc
@@ -8,6 +8,7 @@
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_auth_challenge_tokenizer.h"
+#include "net/http/mock_allow_http_auth_preferences.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -23,7 +24,10 @@ TEST(HttpAuthNegotiateAndroidTest, GenerateAuthToken) {
authenticator.ExpectSecurityContext("Negotiate", GSS_S_COMPLETE, 0,
mockContext, "", "DummyToken");
- HttpAuthNegotiateAndroid auth("org.chromium.test.DummySpnegoAuthenticator");
+ MockAllowHttpAuthPreferences prefs;
+ prefs.set_auth_android_negotiate_account_type(
+ "org.chromium.test.DummySpnegoAuthenticator");
+ HttpAuthNegotiateAndroid auth(&prefs);
EXPECT_TRUE(auth.Init());
TestCompletionCallback callback;
@@ -37,7 +41,10 @@ TEST(HttpAuthNegotiateAndroidTest, GenerateAuthToken) {
TEST(HttpAuthNegotiateAndroidTest, ParseChallenge_FirstRound) {
// The first round should just consist of an unadorned "Negotiate" header.
- HttpAuthNegotiateAndroid auth("org.chromium.test.DummySpnegoAuthenticator");
+ MockAllowHttpAuthPreferences prefs;
+ prefs.set_auth_android_negotiate_account_type(
+ "org.chromium.test.DummySpnegoAuthenticator");
+ HttpAuthNegotiateAndroid auth(&prefs);
std::string challenge_text = "Negotiate";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end());
@@ -48,7 +55,10 @@ TEST(HttpAuthNegotiateAndroidTest, ParseChallenge_FirstRound) {
TEST(HttpAuthNegotiateAndroidTest, ParseChallenge_UnexpectedTokenFirstRound) {
// If the first round challenge has an additional authentication token, it
// should be treated as an invalid challenge from the server.
- HttpAuthNegotiateAndroid auth("org.chromium.test.DummySpnegoAuthenticator");
+ MockAllowHttpAuthPreferences prefs;
+ prefs.set_auth_android_negotiate_account_type(
+ "org.chromium.test.DummySpnegoAuthenticator");
+ HttpAuthNegotiateAndroid auth(&prefs);
std::string challenge_text = "Negotiate Zm9vYmFy";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end());
@@ -59,7 +69,10 @@ TEST(HttpAuthNegotiateAndroidTest, ParseChallenge_UnexpectedTokenFirstRound) {
TEST(HttpAuthNegotiateAndroidTest, ParseChallenge_TwoRounds) {
// The first round should just have "Negotiate", and the second round should
// have a valid base64 token associated with it.
- HttpAuthNegotiateAndroid auth("org.chromium.test.DummySpnegoAuthenticator");
+ MockAllowHttpAuthPreferences prefs;
+ prefs.set_auth_android_negotiate_account_type(
+ "org.chromium.test.DummySpnegoAuthenticator");
+ HttpAuthNegotiateAndroid auth(&prefs);
std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end());
@@ -76,7 +89,10 @@ TEST(HttpAuthNegotiateAndroidTest, ParseChallenge_TwoRounds) {
TEST(HttpAuthNegotiateAndroidTest, ParseChallenge_MissingTokenSecondRound) {
// If a later-round challenge is simply "Negotiate", it should be treated as
// an authentication challenge rejection from the server or proxy.
- HttpAuthNegotiateAndroid auth("org.chromium.test.DummySpnegoAuthenticator");
+ MockAllowHttpAuthPreferences prefs;
+ prefs.set_auth_android_negotiate_account_type(
+ "org.chromium.test.DummySpnegoAuthenticator");
+ HttpAuthNegotiateAndroid auth(&prefs);
std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end());
diff --git a/chromium/net/android/keystore.cc b/chromium/net/android/keystore.cc
index 4fa8dbf6329..fc16ae42b81 100644
--- a/chromium/net/android/keystore.cc
+++ b/chromium/net/android/keystore.cc
@@ -10,7 +10,6 @@
#include "base/android/jni_array.h"
#include "base/logging.h"
#include "jni/AndroidKeyStore_jni.h"
-#include "net/android/android_private_key.h"
using base::android::AttachCurrentThread;
using base::android::HasException;
@@ -26,9 +25,7 @@ bool GetRSAKeyModulus(jobject private_key_ref, std::vector<uint8_t>* result) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jbyteArray> modulus_ref =
- Java_AndroidKeyStore_getRSAKeyModulus(env,
- GetKeyStore(private_key_ref).obj(),
- private_key_ref);
+ Java_AndroidKeyStore_getRSAKeyModulus(env, private_key_ref);
if (modulus_ref.is_null())
return false;
@@ -40,10 +37,7 @@ bool GetECKeyOrder(jobject private_key_ref, std::vector<uint8_t>* result) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jbyteArray> order_ref =
- Java_AndroidKeyStore_getECKeyOrder(
- env,
- GetKeyStore(private_key_ref).obj(),
- private_key_ref);
+ Java_AndroidKeyStore_getECKeyOrder(env, private_key_ref);
if (order_ref.is_null())
return false;
@@ -64,11 +58,8 @@ bool RawSignDigestWithPrivateKey(jobject private_key_ref,
// Invoke platform API
ScopedJavaLocalRef<jbyteArray> signature_ref =
- Java_AndroidKeyStore_rawSignDigestWithPrivateKey(
- env,
- GetKeyStore(private_key_ref).obj(),
- private_key_ref,
- digest_ref.obj());
+ Java_AndroidKeyStore_rawSignDigestWithPrivateKey(env, private_key_ref,
+ digest_ref.obj());
if (HasException(env) || signature_ref.is_null())
return false;
@@ -79,10 +70,7 @@ bool RawSignDigestWithPrivateKey(jobject private_key_ref,
PrivateKeyType GetPrivateKeyType(jobject private_key_ref) {
JNIEnv* env = AttachCurrentThread();
- int type = Java_AndroidKeyStore_getPrivateKeyType(
- env,
- GetKeyStore(private_key_ref).obj(),
- private_key_ref);
+ int type = Java_AndroidKeyStore_getPrivateKeyType(env, private_key_ref);
return static_cast<PrivateKeyType>(type);
}
@@ -96,10 +84,8 @@ AndroidEVP_PKEY* GetOpenSSLSystemHandleForPrivateKey(jobject private_key_ref) {
// Given that this routine shall only be called on Android < 4.2,
// this won't be a problem in the far future (e.g. when Android gets
// ported to 64-bit environments, if ever).
- long pkey = Java_AndroidKeyStore_getOpenSSLHandleForPrivateKey(
- env,
- GetKeyStore(private_key_ref).obj(),
- private_key_ref);
+ long pkey =
+ Java_AndroidKeyStore_getOpenSSLHandleForPrivateKey(env, private_key_ref);
return reinterpret_cast<AndroidEVP_PKEY*>(pkey);
}
@@ -107,21 +93,10 @@ ScopedJavaLocalRef<jobject> GetOpenSSLEngineForPrivateKey(
jobject private_key_ref) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> engine =
- Java_AndroidKeyStore_getOpenSSLEngineForPrivateKey(
- env,
- GetKeyStore(private_key_ref).obj(),
- private_key_ref);
+ Java_AndroidKeyStore_getOpenSSLEngineForPrivateKey(env, private_key_ref);
return engine;
}
-void ReleaseKey(jobject private_key_ref) {
- JNIEnv* env = AttachCurrentThread();
- Java_AndroidKeyStore_releaseKey(env,
- GetKeyStore(private_key_ref).obj(),
- private_key_ref);
- env->DeleteGlobalRef(private_key_ref);
-}
-
bool RegisterKeyStore(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/chromium/net/android/keystore.h b/chromium/net/android/keystore.h
index b79479901a4..df804d7154d 100644
--- a/chromium/net/android/keystore.h
+++ b/chromium/net/android/keystore.h
@@ -101,8 +101,6 @@ AndroidEVP_PKEY* GetOpenSSLSystemHandleForPrivateKey(jobject private_key);
base::android::ScopedJavaLocalRef<jobject> GetOpenSSLEngineForPrivateKey(
jobject private_key);
-NET_EXPORT void ReleaseKey(jobject private_key);
-
// Register JNI methods
NET_EXPORT bool RegisterKeyStore(JNIEnv* env);
diff --git a/chromium/net/android/keystore_openssl.cc b/chromium/net/android/keystore_openssl.cc
index fb0365c6a8d..611b926cfd8 100644
--- a/chromium/net/android/keystore_openssl.cc
+++ b/chromium/net/android/keystore_openssl.cc
@@ -14,7 +14,6 @@
#include <stdint.h>
#include "base/android/build_info.h"
-#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
@@ -72,7 +71,7 @@ extern const ECDSA_METHOD android_ecdsa_method;
// EC_KEY objects that are created to wrap Android system keys.
struct KeyExData {
// private_key contains a reference to a Java, private-key object.
- jobject private_key;
+ ScopedJavaGlobalRef<jobject> private_key;
// legacy_rsa, if not NULL, points to an RSA* in the system's OpenSSL (which
// might not be ABI compatible with Chromium).
AndroidRSA* legacy_rsa;
@@ -104,10 +103,7 @@ void ExDataFree(void* parent,
// Ensure the global JNI reference created with this wrapper is
// properly destroyed with it.
KeyExData *ex_data = reinterpret_cast<KeyExData*>(ptr);
- if (ex_data != NULL) {
- ReleaseKey(ex_data->private_key);
- delete ex_data;
- }
+ delete ex_data;
}
// BoringSSLEngine is a BoringSSL ENGINE that implements RSA and ECDSA by
@@ -202,7 +198,7 @@ int RsaMethodSignRaw(RSA* rsa,
// Retrieve private key JNI reference.
const KeyExData *ex_data = RsaGetExData(rsa);
- if (!ex_data || !ex_data->private_key) {
+ if (!ex_data || !ex_data->private_key.obj()) {
LOG(WARNING) << "Null JNI reference passed to RsaMethodSignRaw!";
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
return 0;
@@ -232,7 +228,8 @@ int RsaMethodSignRaw(RSA* rsa,
std::vector<uint8_t> result;
// For RSA keys, this function behaves as RSA_private_encrypt with
// PKCS#1 padding.
- if (!RawSignDigestWithPrivateKey(ex_data->private_key, from_piece, &result)) {
+ if (!RawSignDigestWithPrivateKey(ex_data->private_key.obj(), from_piece,
+ &result)) {
LOG(WARNING) << "Could not sign message in RsaMethodSignRaw!";
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
return 0;
@@ -326,32 +323,28 @@ crypto::ScopedEVP_PKEY CreateRsaPkeyWrapper(
crypto::ScopedRSA rsa(
RSA_new_method(global_boringssl_engine.Get().engine()));
- ScopedJavaGlobalRef<jobject> global_key;
- global_key.Reset(NULL, private_key);
- if (global_key.is_null()) {
- LOG(ERROR) << "Could not create global JNI reference";
- return crypto::ScopedEVP_PKEY();
- }
-
std::vector<uint8_t> modulus;
if (!GetRSAKeyModulus(private_key, &modulus)) {
LOG(ERROR) << "Failed to get private key modulus";
- return crypto::ScopedEVP_PKEY();
+ return nullptr;
}
- KeyExData* ex_data = new KeyExData;
- ex_data->private_key = global_key.Release();
+ scoped_ptr<KeyExData> ex_data(new KeyExData);
+ ex_data->private_key.Reset(nullptr, private_key);
+ if (ex_data->private_key.is_null()) {
+ LOG(ERROR) << "Could not create global JNI reference";
+ return nullptr;
+ }
ex_data->legacy_rsa = legacy_rsa;
ex_data->cached_size = VectorBignumSize(modulus);
- RSA_set_ex_data(
- rsa.get(), global_boringssl_engine.Get().rsa_ex_index(), ex_data);
+
+ RSA_set_ex_data(rsa.get(), global_boringssl_engine.Get().rsa_ex_index(),
+ ex_data.release());
crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
- if (!pkey ||
- !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) {
- return crypto::ScopedEVP_PKEY();
- }
- return pkey.Pass();
+ if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get()))
+ return nullptr;
+ return pkey;
}
// On Android < 4.2, the libkeystore.so ENGINE uses CRYPTO_EX_DATA and is not
@@ -435,7 +428,7 @@ crypto::ScopedEVP_PKEY GetRsaPkeyWrapper(jobject private_key) {
jobject EcKeyGetKey(const EC_KEY* ec_key) {
KeyExData* ex_data = reinterpret_cast<KeyExData*>(EC_KEY_get_ex_data(
ec_key, global_boringssl_engine.Get().ec_key_ex_index()));
- return ex_data->private_key;
+ return ex_data->private_key.obj();
}
size_t EcdsaMethodGroupOrderSize(const EC_KEY* ec_key) {
@@ -500,33 +493,29 @@ crypto::ScopedEVP_PKEY GetEcdsaPkeyWrapper(jobject private_key) {
crypto::ScopedEC_KEY ec_key(
EC_KEY_new_method(global_boringssl_engine.Get().engine()));
- ScopedJavaGlobalRef<jobject> global_key;
- global_key.Reset(NULL, private_key);
- if (global_key.is_null()) {
- LOG(ERROR) << "Can't create global JNI reference";
- return crypto::ScopedEVP_PKEY();
- }
-
std::vector<uint8_t> order;
if (!GetECKeyOrder(private_key, &order)) {
LOG(ERROR) << "Can't extract order parameter from EC private key";
- return crypto::ScopedEVP_PKEY();
+ return nullptr;
}
- KeyExData* ex_data = new KeyExData;
- ex_data->private_key = global_key.Release();
- ex_data->legacy_rsa = NULL;
+ scoped_ptr<KeyExData> ex_data(new KeyExData);
+ ex_data->private_key.Reset(nullptr, private_key);
+ if (ex_data->private_key.is_null()) {
+ LOG(ERROR) << "Can't create global JNI reference";
+ return nullptr;
+ }
+ ex_data->legacy_rsa = nullptr;
ex_data->cached_size = VectorBignumSize(order);
- EC_KEY_set_ex_data(
- ec_key.get(), global_boringssl_engine.Get().ec_key_ex_index(), ex_data);
+ EC_KEY_set_ex_data(ec_key.get(),
+ global_boringssl_engine.Get().ec_key_ex_index(),
+ ex_data.release());
crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
- if (!pkey ||
- !EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get())) {
- return crypto::ScopedEVP_PKEY();
- }
- return pkey.Pass();
+ if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()))
+ return nullptr;
+ return pkey;
}
const ECDSA_METHOD android_ecdsa_method = {
diff --git a/chromium/net/android/keystore_unittest.cc b/chromium/net/android/keystore_unittest.cc
index b7eb083b39d..4faa2458cec 100644
--- a/chromium/net/android/keystore_unittest.cc
+++ b/chromium/net/android/keystore_unittest.cc
@@ -408,7 +408,7 @@ void DoKeySigningWithWrapper(EVP_PKEY* wrapper_key,
} // namespace
-TEST(AndroidKeyStore,GetRSAKeyModulus) {
+TEST(AndroidKeyStore, GetRSAKeyModulus) {
crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
InitEnv();
diff --git a/chromium/net/android/network_change_notifier_android.cc b/chromium/net/android/network_change_notifier_android.cc
index a967b85a35d..a7655adbe8c 100644
--- a/chromium/net/android/network_change_notifier_android.cc
+++ b/chromium/net/android/network_change_notifier_android.cc
@@ -59,12 +59,25 @@
#include "net/android/network_change_notifier_android.h"
+#include "base/android/build_info.h"
+#include "base/macros.h"
#include "base/threading/thread.h"
#include "net/base/address_tracker_linux.h"
#include "net/dns/dns_config_service_posix.h"
namespace net {
+// Expose kInvalidNetworkHandle out to Java as NetId.INVALID. The notion of
+// a NetID is an Android framework one, see android.net.Network.netId.
+// NetworkChangeNotifierAndroid implements NetworkHandle to simply be the NetID.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
+enum NetId {
+ // Cannot use |kInvalidNetworkHandle| here as the Java generator fails,
+ // instead enforce their equality with CHECK in
+ // NetworkChangeNotifierAndroid().
+ INVALID = -1
+};
+
// Thread on which we can run DnsConfigService, which requires a TYPE_IO
// message loop to monitor /system/etc/hosts.
class NetworkChangeNotifierAndroid::DnsConfigServiceThread
@@ -151,6 +164,34 @@ void NetworkChangeNotifierAndroid::GetCurrentMaxBandwidthAndConnectionType(
connection_type);
}
+void NetworkChangeNotifierAndroid::ForceNetworkHandlesSupportedForTesting() {
+ force_network_handles_supported_for_testing_ = true;
+}
+
+bool NetworkChangeNotifierAndroid::AreNetworkHandlesCurrentlySupported() const {
+ // Notifications for API using NetworkHandles and querying using
+ // NetworkHandles only implemented for Android versions >= L.
+ return force_network_handles_supported_for_testing_ ||
+ (base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_LOLLIPOP);
+}
+
+void NetworkChangeNotifierAndroid::GetCurrentConnectedNetworks(
+ NetworkChangeNotifier::NetworkList* networks) const {
+ delegate_->GetCurrentlyConnectedNetworks(networks);
+}
+
+NetworkChangeNotifier::ConnectionType
+NetworkChangeNotifierAndroid::GetCurrentNetworkConnectionType(
+ NetworkHandle network) const {
+ return delegate_->GetNetworkConnectionType(network);
+}
+
+NetworkChangeNotifier::NetworkHandle
+NetworkChangeNotifierAndroid::GetCurrentDefaultNetwork() const {
+ return delegate_->GetCurrentDefaultNetwork();
+}
+
void NetworkChangeNotifierAndroid::OnConnectionTypeChanged() {
DnsConfigServiceThread::NotifyNetworkChangeNotifierObservers();
}
@@ -162,6 +203,28 @@ void NetworkChangeNotifierAndroid::OnMaxBandwidthChanged(
type);
}
+void NetworkChangeNotifierAndroid::OnNetworkConnected(NetworkHandle network) {
+ NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
+ NetworkChangeType::CONNECTED, network);
+}
+
+void NetworkChangeNotifierAndroid::OnNetworkSoonToDisconnect(
+ NetworkHandle network) {
+ NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
+ NetworkChangeType::SOON_TO_DISCONNECT, network);
+}
+
+void NetworkChangeNotifierAndroid::OnNetworkDisconnected(
+ NetworkHandle network) {
+ NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
+ NetworkChangeType::DISCONNECTED, network);
+}
+
+void NetworkChangeNotifierAndroid::OnNetworkMadeDefault(NetworkHandle network) {
+ NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
+ NetworkChangeType::MADE_DEFAULT, network);
+}
+
// static
bool NetworkChangeNotifierAndroid::Register(JNIEnv* env) {
return NetworkChangeNotifierDelegateAndroid::Register(env);
@@ -173,7 +236,10 @@ NetworkChangeNotifierAndroid::NetworkChangeNotifierAndroid(
: NetworkChangeNotifier(NetworkChangeCalculatorParamsAndroid()),
delegate_(delegate),
dns_config_service_thread_(
- new DnsConfigServiceThread(dns_config_for_testing)) {
+ new DnsConfigServiceThread(dns_config_for_testing)),
+ force_network_handles_supported_for_testing_(false) {
+ CHECK_EQ(NetId::INVALID, NetworkChangeNotifier::kInvalidNetworkHandle)
+ << "kInvalidNetworkHandle doesn't match NetId::INVALID";
delegate_->AddObserver(this);
dns_config_service_thread_->StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
diff --git a/chromium/net/android/network_change_notifier_android.h b/chromium/net/android/network_change_notifier_android.h
index 61bec5368c3..89e7f19ee95 100644
--- a/chromium/net/android/network_change_notifier_android.h
+++ b/chromium/net/android/network_change_notifier_android.h
@@ -52,11 +52,20 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierAndroid
void GetCurrentMaxBandwidthAndConnectionType(
double* max_bandwidth_mbps,
ConnectionType* connection_type) const override;
+ bool AreNetworkHandlesCurrentlySupported() const override;
+ void GetCurrentConnectedNetworks(NetworkList* network_list) const override;
+ ConnectionType GetCurrentNetworkConnectionType(
+ NetworkHandle network) const override;
+ NetworkHandle GetCurrentDefaultNetwork() const override;
// NetworkChangeNotifierDelegateAndroid::Observer:
void OnConnectionTypeChanged() override;
void OnMaxBandwidthChanged(double max_bandwidth_mbps,
ConnectionType type) override;
+ void OnNetworkConnected(NetworkHandle network) override;
+ void OnNetworkSoonToDisconnect(NetworkHandle network) override;
+ void OnNetworkDisconnected(NetworkHandle network) override;
+ void OnNetworkMadeDefault(NetworkHandle network) override;
static bool Register(JNIEnv* env);
@@ -70,6 +79,9 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierAndroid
class DnsConfigServiceThread;
+ // Enable NetworkHandles support for tests.
+ void ForceNetworkHandlesSupportedForTesting();
+
NetworkChangeNotifierAndroid(NetworkChangeNotifierDelegateAndroid* delegate,
const DnsConfig* dns_config_for_testing);
@@ -77,6 +89,7 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierAndroid
NetworkChangeNotifierDelegateAndroid* const delegate_;
scoped_ptr<DnsConfigServiceThread> dns_config_service_thread_;
+ bool force_network_handles_supported_for_testing_;
DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierAndroid);
};
diff --git a/chromium/net/android/network_change_notifier_android_unittest.cc b/chromium/net/android/network_change_notifier_android_unittest.cc
index d3fe04d5786..e07a89eaf14 100644
--- a/chromium/net/android/network_change_notifier_android_unittest.cc
+++ b/chromium/net/android/network_change_notifier_android_unittest.cc
@@ -19,9 +19,23 @@ namespace net {
namespace {
+// Types of network changes. See similarly named functions in
+// NetworkChangeNotifier::NetworkObserver for descriptions.
+enum ChangeType {
+ NONE,
+ CONNECTED,
+ SOON_TO_DISCONNECT,
+ DISCONNECTED,
+ MADE_DEFAULT,
+};
+
class NetworkChangeNotifierDelegateAndroidObserver
: public NetworkChangeNotifierDelegateAndroid::Observer {
public:
+ typedef NetworkChangeNotifier::ConnectionType ConnectionType;
+ typedef NetworkChangeNotifier::NetworkHandle NetworkHandle;
+ typedef NetworkChangeNotifier::NetworkList NetworkList;
+
NetworkChangeNotifierDelegateAndroidObserver()
: type_notifications_count_(0), max_bandwidth_notifications_count_(0) {}
@@ -34,6 +48,14 @@ class NetworkChangeNotifierDelegateAndroidObserver
max_bandwidth_notifications_count_++;
}
+ void OnNetworkConnected(NetworkHandle network) override {}
+
+ void OnNetworkSoonToDisconnect(NetworkHandle network) override {}
+
+ void OnNetworkDisconnected(NetworkHandle network) override {}
+
+ void OnNetworkMadeDefault(NetworkHandle network) override {}
+
int type_notifications_count() const { return type_notifications_count_; }
int bandwidth_notifications_count() const {
return max_bandwidth_notifications_count_;
@@ -49,7 +71,7 @@ class NetworkChangeNotifierObserver
public:
NetworkChangeNotifierObserver() : notifications_count_(0) {}
- // NetworkChangeNotifier::Observer:
+ // NetworkChangeNotifier::ConnectionTypeObserver:
void OnConnectionTypeChanged(
NetworkChangeNotifier::ConnectionType connection_type) override {
notifications_count_++;
@@ -63,6 +85,22 @@ class NetworkChangeNotifierObserver
int notifications_count_;
};
+class NetworkChangeNotifierMaxBandwidthObserver
+ : public NetworkChangeNotifier::MaxBandwidthObserver {
+ public:
+ // NetworkChangeNotifier::MaxBandwidthObserver:
+ void OnMaxBandwidthChanged(
+ double max_bandwidth_mbps,
+ NetworkChangeNotifier::ConnectionType type) override {
+ notifications_count_++;
+ }
+
+ int notifications_count() const { return notifications_count_; }
+
+ private:
+ int notifications_count_ = 0;
+};
+
class DNSChangeObserver : public NetworkChangeNotifier::DNSObserver {
public:
DNSChangeObserver()
@@ -73,7 +111,7 @@ class DNSChangeObserver : public NetworkChangeNotifier::DNSObserver {
void OnInitialDNSConfigRead() override {
initial_notifications_count_++;
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
int change_notifications_count() const { return change_notifications_count_; }
@@ -87,6 +125,55 @@ class DNSChangeObserver : public NetworkChangeNotifier::DNSObserver {
int initial_notifications_count_;
};
+// A NetworkObserver used for verifying correct notifications are sent.
+class TestNetworkObserver : public NetworkChangeNotifier::NetworkObserver {
+ public:
+ TestNetworkObserver() { Clear(); }
+
+ void ExpectChange(ChangeType change,
+ NetworkChangeNotifier::NetworkHandle network) {
+ EXPECT_EQ(last_change_type_, change);
+ EXPECT_EQ(last_network_changed_, network);
+ Clear();
+ }
+
+ private:
+ void Clear() {
+ last_change_type_ = NONE;
+ last_network_changed_ = NetworkChangeNotifier::kInvalidNetworkHandle;
+ }
+
+ // NetworkChangeNotifier::NetworkObserver implementation:
+ void OnNetworkConnected(
+ NetworkChangeNotifier::NetworkHandle network) override {
+ ExpectChange(NONE, NetworkChangeNotifier::kInvalidNetworkHandle);
+ last_change_type_ = CONNECTED;
+ last_network_changed_ = network;
+ }
+ void OnNetworkSoonToDisconnect(
+ NetworkChangeNotifier::NetworkHandle network) override {
+ ExpectChange(NONE, NetworkChangeNotifier::kInvalidNetworkHandle);
+ last_change_type_ = SOON_TO_DISCONNECT;
+ last_network_changed_ = network;
+ }
+ void OnNetworkDisconnected(
+ NetworkChangeNotifier::NetworkHandle network) override {
+ ExpectChange(NONE, NetworkChangeNotifier::kInvalidNetworkHandle);
+ last_change_type_ = DISCONNECTED;
+ last_network_changed_ = network;
+ }
+ void OnNetworkMadeDefault(
+ NetworkChangeNotifier::NetworkHandle network) override {
+ // Cannot test for Clear()ed state as we receive CONNECTED immediately prior
+ // to MADE_DEFAULT.
+ last_change_type_ = MADE_DEFAULT;
+ last_network_changed_ = network;
+ }
+
+ ChangeType last_change_type_;
+ NetworkChangeNotifier::NetworkHandle last_network_changed_;
+};
+
} // namespace
class BaseNetworkChangeNotifierAndroidTest : public testing::Test {
@@ -135,6 +222,42 @@ class BaseNetworkChangeNotifierAndroidTest : public testing::Test {
base::MessageLoop::current()->RunUntilIdle();
}
+ void FakeMaxBandwidthChange(double max_bandwidth_mbps) {
+ delegate_.FakeMaxBandwidthChanged(max_bandwidth_mbps);
+ base::MessageLoop::current()->RunUntilIdle();
+ }
+
+ void FakeNetworkChange(ChangeType change,
+ NetworkChangeNotifier::NetworkHandle network,
+ ConnectionType type) {
+ switch (change) {
+ case CONNECTED:
+ delegate_.FakeNetworkConnected(network, type);
+ break;
+ case SOON_TO_DISCONNECT:
+ delegate_.FakeNetworkSoonToBeDisconnected(network);
+ break;
+ case DISCONNECTED:
+ delegate_.FakeNetworkDisconnected(network);
+ break;
+ case MADE_DEFAULT:
+ delegate_.FakeDefaultNetwork(network, type);
+ break;
+ case NONE:
+ NOTREACHED();
+ break;
+ }
+ // See comment above.
+ base::MessageLoop::current()->RunUntilIdle();
+ }
+
+ void FakeUpdateActiveNetworkList(
+ NetworkChangeNotifier::NetworkList networks) {
+ delegate_.FakeUpdateActiveNetworkList(networks);
+ // See comment above.
+ base::MessageLoop::current()->RunUntilIdle();
+ }
+
NetworkChangeNotifierDelegateAndroid delegate_;
};
@@ -166,9 +289,37 @@ TEST_F(BaseNetworkChangeNotifierAndroidTest,
other_delegate->GetCurrentConnectionType());
}
-class NetworkChangeNotifierDelegateAndroidTest
+class NetworkChangeNotifierAndroidTest
: public BaseNetworkChangeNotifierAndroidTest {
protected:
+ void SetUp() override {
+ IPAddressNumber dns_number;
+ ASSERT_TRUE(ParseIPLiteralToNumber("8.8.8.8", &dns_number));
+ dns_config_.nameservers.push_back(
+ IPEndPoint(dns_number, dns_protocol::kDefaultPort));
+ notifier_.reset(new NetworkChangeNotifierAndroid(&delegate_, &dns_config_));
+ NetworkChangeNotifier::AddConnectionTypeObserver(
+ &connection_type_observer_);
+ NetworkChangeNotifier::AddConnectionTypeObserver(
+ &other_connection_type_observer_);
+ NetworkChangeNotifier::AddMaxBandwidthObserver(&max_bandwidth_observer_);
+ }
+
+ void ForceNetworkHandlesSupportedForTesting() {
+ notifier_->ForceNetworkHandlesSupportedForTesting();
+ }
+
+ NetworkChangeNotifierObserver connection_type_observer_;
+ NetworkChangeNotifierMaxBandwidthObserver max_bandwidth_observer_;
+ NetworkChangeNotifierObserver other_connection_type_observer_;
+ NetworkChangeNotifier::DisableForTest disable_for_test_;
+ DnsConfig dns_config_;
+ scoped_ptr<NetworkChangeNotifierAndroid> notifier_;
+};
+
+class NetworkChangeNotifierDelegateAndroidTest
+ : public NetworkChangeNotifierAndroidTest {
+ protected:
NetworkChangeNotifierDelegateAndroidTest() {
delegate_.AddObserver(&delegate_observer_);
delegate_.AddObserver(&other_delegate_observer_);
@@ -200,27 +351,6 @@ TEST_F(NetworkChangeNotifierDelegateAndroidTest, DelegateObserverNotified) {
other_delegate_observer_.type_notifications_count());
}
-class NetworkChangeNotifierAndroidTest
- : public BaseNetworkChangeNotifierAndroidTest {
- protected:
- void SetUp() override {
- IPAddressNumber dns_number;
- ASSERT_TRUE(ParseIPLiteralToNumber("8.8.8.8", &dns_number));
- dns_config_.nameservers.push_back(
- IPEndPoint(dns_number, dns_protocol::kDefaultPort));
- notifier_.reset(new NetworkChangeNotifierAndroid(&delegate_, &dns_config_));
- NetworkChangeNotifier::AddConnectionTypeObserver(
- &connection_type_observer_);
- NetworkChangeNotifier::AddConnectionTypeObserver(
- &other_connection_type_observer_);
- }
-
- NetworkChangeNotifierObserver connection_type_observer_;
- NetworkChangeNotifierObserver other_connection_type_observer_;
- NetworkChangeNotifier::DisableForTest disable_for_test_;
- DnsConfig dns_config_;
- scoped_ptr<NetworkChangeNotifierAndroid> notifier_;
-};
// When a NetworkChangeNotifierAndroid is observing a
// NetworkChangeNotifierDelegateAndroid for network state changes, and the
@@ -264,6 +394,22 @@ TEST_F(NetworkChangeNotifierAndroidTest, MaxBandwidth) {
EXPECT_EQ(0.0, max_bandwidth_mbps);
}
+TEST_F(NetworkChangeNotifierDelegateAndroidTest, MaxBandwidthCallbackNotifier) {
+ // The bandwidth notification should always be forwarded, even if the value
+ // doesn't change (because the type might have changed).
+ FakeMaxBandwidthChange(100.0);
+ EXPECT_EQ(1, delegate_observer_.bandwidth_notifications_count());
+ EXPECT_EQ(1, max_bandwidth_observer_.notifications_count());
+
+ FakeMaxBandwidthChange(100.0);
+ EXPECT_EQ(2, delegate_observer_.bandwidth_notifications_count());
+ EXPECT_EQ(2, max_bandwidth_observer_.notifications_count());
+
+ FakeMaxBandwidthChange(101.0);
+ EXPECT_EQ(3, delegate_observer_.bandwidth_notifications_count());
+ EXPECT_EQ(3, max_bandwidth_observer_.notifications_count());
+}
+
TEST_F(NetworkChangeNotifierDelegateAndroidTest,
MaxBandwidthNotifiedOnConnectionChange) {
EXPECT_EQ(0, delegate_observer_.bandwidth_notifications_count());
@@ -284,4 +430,101 @@ TEST_F(NetworkChangeNotifierAndroidTest, InitialSignal) {
NetworkChangeNotifier::RemoveDNSObserver(&dns_change_observer);
}
+TEST_F(NetworkChangeNotifierAndroidTest, NetworkCallbacks) {
+ ForceNetworkHandlesSupportedForTesting();
+
+ TestNetworkObserver network_observer;
+ NetworkChangeNotifier::AddNetworkObserver(&network_observer);
+
+ // Test empty values
+ EXPECT_EQ(NetworkChangeNotifier::kInvalidNetworkHandle,
+ NetworkChangeNotifier::GetDefaultNetwork());
+ EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN,
+ NetworkChangeNotifier::GetNetworkConnectionType(100));
+ NetworkChangeNotifier::NetworkList network_list;
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ EXPECT_EQ(0u, network_list.size());
+ // Test connecting network
+ FakeNetworkChange(CONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
+ network_observer.ExpectChange(CONNECTED, 100);
+ EXPECT_EQ(NetworkChangeNotifier::kInvalidNetworkHandle,
+ NetworkChangeNotifier::GetDefaultNetwork());
+ // Test GetConnectedNetworks()
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ EXPECT_EQ(1u, network_list.size());
+ EXPECT_EQ(100, network_list[0]);
+ // Test GetNetworkConnectionType()
+ EXPECT_EQ(NetworkChangeNotifier::CONNECTION_WIFI,
+ NetworkChangeNotifier::GetNetworkConnectionType(100));
+ // Test deduplication of connecting signal
+ FakeNetworkChange(CONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
+ network_observer.ExpectChange(NONE,
+ NetworkChangeNotifier::kInvalidNetworkHandle);
+ // Test connecting another network
+ FakeNetworkChange(CONNECTED, 101, NetworkChangeNotifier::CONNECTION_3G);
+ network_observer.ExpectChange(CONNECTED, 101);
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ EXPECT_EQ(2u, network_list.size());
+ EXPECT_EQ(100, network_list[0]);
+ EXPECT_EQ(101, network_list[1]);
+ EXPECT_EQ(NetworkChangeNotifier::CONNECTION_WIFI,
+ NetworkChangeNotifier::GetNetworkConnectionType(100));
+ EXPECT_EQ(NetworkChangeNotifier::CONNECTION_3G,
+ NetworkChangeNotifier::GetNetworkConnectionType(101));
+ // Test lingering network
+ FakeNetworkChange(SOON_TO_DISCONNECT, 100,
+ NetworkChangeNotifier::CONNECTION_WIFI);
+ network_observer.ExpectChange(SOON_TO_DISCONNECT, 100);
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ EXPECT_EQ(2u, network_list.size());
+ EXPECT_EQ(100, network_list[0]);
+ EXPECT_EQ(101, network_list[1]);
+ // Test disconnecting network
+ FakeNetworkChange(DISCONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
+ network_observer.ExpectChange(DISCONNECTED, 100);
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ EXPECT_EQ(1u, network_list.size());
+ EXPECT_EQ(101, network_list[0]);
+ // Test deduplication of disconnecting signal
+ FakeNetworkChange(DISCONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
+ network_observer.ExpectChange(NONE,
+ NetworkChangeNotifier::kInvalidNetworkHandle);
+ // Test delay of default network signal until connect signal
+ FakeNetworkChange(MADE_DEFAULT, 100, NetworkChangeNotifier::CONNECTION_WIFI);
+ network_observer.ExpectChange(NONE,
+ NetworkChangeNotifier::kInvalidNetworkHandle);
+ FakeNetworkChange(CONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
+ network_observer.ExpectChange(MADE_DEFAULT, 100);
+ EXPECT_EQ(100, NetworkChangeNotifier::GetDefaultNetwork());
+ // Test change of default
+ FakeNetworkChange(MADE_DEFAULT, 101, NetworkChangeNotifier::CONNECTION_3G);
+ network_observer.ExpectChange(MADE_DEFAULT, 101);
+ EXPECT_EQ(101, NetworkChangeNotifier::GetDefaultNetwork());
+ // Test deduplication default signal
+ FakeNetworkChange(MADE_DEFAULT, 101, NetworkChangeNotifier::CONNECTION_3G);
+ network_observer.ExpectChange(NONE,
+ NetworkChangeNotifier::kInvalidNetworkHandle);
+ // Test that networks can change type
+ FakeNetworkChange(CONNECTED, 101, NetworkChangeNotifier::CONNECTION_4G);
+ network_observer.ExpectChange(NONE,
+ NetworkChangeNotifier::kInvalidNetworkHandle);
+ EXPECT_EQ(NetworkChangeNotifier::CONNECTION_4G,
+ NetworkChangeNotifier::GetNetworkConnectionType(101));
+ // Test purging the network list
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ EXPECT_EQ(2u, network_list.size());
+ EXPECT_EQ(100, network_list[0]);
+ EXPECT_EQ(101, network_list[1]);
+ network_list.erase(network_list.begin() + 1); // Remove network 101
+ FakeUpdateActiveNetworkList(network_list);
+ network_observer.ExpectChange(DISCONNECTED, 101);
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ EXPECT_EQ(1u, network_list.size());
+ EXPECT_EQ(100, network_list[0]);
+ EXPECT_EQ(NetworkChangeNotifier::kInvalidNetworkHandle,
+ NetworkChangeNotifier::GetDefaultNetwork());
+
+ NetworkChangeNotifier::RemoveNetworkObserver(&network_observer);
+}
+
} // namespace net
diff --git a/chromium/net/android/network_change_notifier_delegate_android.cc b/chromium/net/android/network_change_notifier_delegate_android.cc
index be4c6b18e11..ff072979606 100644
--- a/chromium/net/android/network_change_notifier_delegate_android.cc
+++ b/chromium/net/android/network_change_notifier_delegate_android.cc
@@ -4,6 +4,8 @@
#include "net/android/network_change_notifier_delegate_android.h"
+#include "base/android/context_utils.h"
+#include "base/android/jni_array.h"
#include "base/logging.h"
#include "jni/NetworkChangeNotifier_jni.h"
#include "net/android/network_change_notifier_android.h"
@@ -44,6 +46,21 @@ NetworkChangeNotifier::ConnectionSubtype ConvertConnectionSubtype(
} // namespace
+// static
+void NetworkChangeNotifierDelegateAndroid::JavaIntArrayToNetworkMap(
+ JNIEnv* env,
+ jintArray int_array,
+ NetworkMap* network_map) {
+ std::vector<int> int_list;
+ base::android::JavaIntArrayToIntVector(env, int_array, &int_list);
+ network_map->clear();
+ for (auto i = int_list.begin(); i != int_list.end(); ++i) {
+ NetworkChangeNotifier::NetworkHandle network_handle = *i;
+ CHECK(++i != int_list.end());
+ (*network_map)[network_handle] = static_cast<ConnectionType>(*i);
+ }
+}
+
jdouble GetMaxBandwidthForConnectionSubtype(JNIEnv* env,
const JavaParamRef<jclass>& caller,
jint subtype) {
@@ -67,6 +84,14 @@ NetworkChangeNotifierDelegateAndroid::NetworkChangeNotifierDelegateAndroid()
SetCurrentMaxBandwidth(
Java_NetworkChangeNotifier_getCurrentMaxBandwidthInMbps(
env, java_network_change_notifier_.obj()));
+ SetCurrentDefaultNetwork(Java_NetworkChangeNotifier_getCurrentDefaultNetId(
+ env, java_network_change_notifier_.obj()));
+ NetworkMap network_map;
+ ScopedJavaLocalRef<jintArray> networks_and_types =
+ Java_NetworkChangeNotifier_getCurrentNetworksAndTypes(
+ env, java_network_change_notifier_.obj());
+ JavaIntArrayToNetworkMap(env, networks_and_types.obj(), &network_map);
+ SetCurrentNetworksAndTypes(network_map);
}
NetworkChangeNotifierDelegateAndroid::~NetworkChangeNotifierDelegateAndroid() {
@@ -93,14 +118,60 @@ void NetworkChangeNotifierDelegateAndroid::
*max_bandwidth_mbps = connection_max_bandwidth_;
}
+NetworkChangeNotifier::ConnectionType
+NetworkChangeNotifierDelegateAndroid::GetNetworkConnectionType(
+ NetworkChangeNotifier::NetworkHandle network) const {
+ base::AutoLock auto_lock(connection_lock_);
+ auto network_entry = network_map_.find(network);
+ if (network_entry == network_map_.end())
+ return ConnectionType::CONNECTION_UNKNOWN;
+ return network_entry->second;
+}
+
+NetworkChangeNotifier::NetworkHandle
+NetworkChangeNotifierDelegateAndroid::GetCurrentDefaultNetwork() const {
+ base::AutoLock auto_lock(connection_lock_);
+ return default_network_;
+}
+
+void NetworkChangeNotifierDelegateAndroid::GetCurrentlyConnectedNetworks(
+ NetworkList* network_list) const {
+ network_list->clear();
+ base::AutoLock auto_lock(connection_lock_);
+ for (auto i : network_map_)
+ network_list->push_back(i.first);
+}
+
void NetworkChangeNotifierDelegateAndroid::NotifyConnectionTypeChanged(
JNIEnv* env,
- jobject obj,
- jint new_connection_type) {
+ const JavaParamRef<jobject>& obj,
+ jint new_connection_type,
+ jint default_netid) {
DCHECK(thread_checker_.CalledOnValidThread());
const ConnectionType actual_connection_type = ConvertConnectionType(
new_connection_type);
SetCurrentConnectionType(actual_connection_type);
+ NetworkHandle default_network = default_netid;
+ if (default_network != GetCurrentDefaultNetwork()) {
+ SetCurrentDefaultNetwork(default_network);
+ bool default_exists;
+ {
+ base::AutoLock auto_lock(connection_lock_);
+ // |default_network| may be an invalid value (i.e. -1) in cases where
+ // the device is disconnected or when run on Android versions prior to L,
+ // in which case |default_exists| will correctly be false and no
+ // OnNetworkMadeDefault notification will be sent.
+ default_exists = network_map_.find(default_network) != network_map_.end();
+ }
+ // Android Lollipop had race conditions where CONNECTIVITY_ACTION intents
+ // were sent out before the network was actually made the default.
+ // Delay sending the OnNetworkMadeDefault notification until we are
+ // actually notified that the network connected in NotifyOfNetworkConnect.
+ if (default_exists) {
+ observers_->Notify(FROM_HERE, &Observer::OnNetworkMadeDefault,
+ default_network);
+ }
+ }
observers_->Notify(FROM_HERE, &Observer::OnConnectionTypeChanged);
}
@@ -112,7 +183,7 @@ jint NetworkChangeNotifierDelegateAndroid::GetConnectionType(JNIEnv*,
void NetworkChangeNotifierDelegateAndroid::NotifyMaxBandwidthChanged(
JNIEnv* env,
- jobject obj,
+ const JavaParamRef<jobject>& obj,
jdouble new_max_bandwidth) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -121,6 +192,88 @@ void NetworkChangeNotifierDelegateAndroid::NotifyMaxBandwidthChanged(
new_max_bandwidth, GetCurrentConnectionType());
}
+void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkConnect(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint net_id,
+ jint connection_type) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NetworkHandle network = net_id;
+ bool already_exists;
+ {
+ base::AutoLock auto_lock(connection_lock_);
+ already_exists = network_map_.find(network) != network_map_.end();
+ network_map_[network] = static_cast<ConnectionType>(connection_type);
+ }
+ // Android Lollipop would send many duplicate notifications.
+ // This was later fixed in Android Marshmallow.
+ // Deduplicate them here by avoiding sending duplicate notifications.
+ if (!already_exists) {
+ observers_->Notify(FROM_HERE, &Observer::OnNetworkConnected, network);
+ if (network == GetCurrentDefaultNetwork()) {
+ observers_->Notify(FROM_HERE, &Observer::OnNetworkMadeDefault, network);
+ }
+ }
+}
+
+void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkSoonToDisconnect(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint net_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NetworkHandle network = net_id;
+ {
+ base::AutoLock auto_lock(connection_lock_);
+ if (network_map_.find(network) == network_map_.end())
+ return;
+ }
+ observers_->Notify(FROM_HERE, &Observer::OnNetworkSoonToDisconnect, network);
+}
+
+void NetworkChangeNotifierDelegateAndroid::NotifyOfNetworkDisconnect(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint net_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NetworkHandle network = net_id;
+ {
+ base::AutoLock auto_lock(connection_lock_);
+ if (network == default_network_)
+ default_network_ = NetworkChangeNotifier::kInvalidNetworkHandle;
+ if (network_map_.erase(network) == 0)
+ return;
+ }
+ observers_->Notify(FROM_HERE, &Observer::OnNetworkDisconnected, network);
+}
+
+void NetworkChangeNotifierDelegateAndroid::NotifyUpdateActiveNetworkList(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jintArray>& active_networks) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NetworkList active_network_list;
+ base::android::JavaIntArrayToIntVector(env, active_networks,
+ &active_network_list);
+ NetworkList disconnected_networks;
+ {
+ base::AutoLock auto_lock(connection_lock_);
+ for (auto i : network_map_) {
+ bool found = false;
+ for (auto j : active_network_list) {
+ if (j == i.first) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ disconnected_networks.push_back(i.first);
+ }
+ }
+ }
+ for (auto disconnected_network : disconnected_networks)
+ NotifyOfNetworkDisconnect(env, obj, disconnected_network);
+}
+
void NetworkChangeNotifierDelegateAndroid::AddObserver(
Observer* observer) {
observers_->AddObserver(observer);
@@ -148,6 +301,18 @@ void NetworkChangeNotifierDelegateAndroid::SetCurrentMaxBandwidth(
connection_max_bandwidth_ = max_bandwidth;
}
+void NetworkChangeNotifierDelegateAndroid::SetCurrentDefaultNetwork(
+ NetworkHandle default_network) {
+ base::AutoLock auto_lock(connection_lock_);
+ default_network_ = default_network;
+}
+
+void NetworkChangeNotifierDelegateAndroid::SetCurrentNetworksAndTypes(
+ NetworkMap network_map) {
+ base::AutoLock auto_lock(connection_lock_);
+ network_map_ = network_map;
+}
+
void NetworkChangeNotifierDelegateAndroid::SetOnline() {
JNIEnv* env = base::android::AttachCurrentThread();
Java_NetworkChangeNotifier_forceConnectivityState(env, true);
@@ -158,4 +323,43 @@ void NetworkChangeNotifierDelegateAndroid::SetOffline() {
Java_NetworkChangeNotifier_forceConnectivityState(env, false);
}
+void NetworkChangeNotifierDelegateAndroid::FakeNetworkConnected(
+ NetworkChangeNotifier::NetworkHandle network,
+ ConnectionType type) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_NetworkChangeNotifier_fakeNetworkConnected(env, network, type);
+}
+
+void NetworkChangeNotifierDelegateAndroid::FakeNetworkSoonToBeDisconnected(
+ NetworkChangeNotifier::NetworkHandle network) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_NetworkChangeNotifier_fakeNetworkSoonToBeDisconnected(env, network);
+}
+
+void NetworkChangeNotifierDelegateAndroid::FakeNetworkDisconnected(
+ NetworkChangeNotifier::NetworkHandle network) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_NetworkChangeNotifier_fakeNetworkDisconnected(env, network);
+}
+
+void NetworkChangeNotifierDelegateAndroid::FakeUpdateActiveNetworkList(
+ NetworkChangeNotifier::NetworkList networks) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_NetworkChangeNotifier_fakeUpdateActiveNetworkList(
+ env, base::android::ToJavaIntArray(env, networks).obj());
+}
+
+void NetworkChangeNotifierDelegateAndroid::FakeDefaultNetwork(
+ NetworkChangeNotifier::NetworkHandle network,
+ ConnectionType type) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_NetworkChangeNotifier_fakeDefaultNetwork(env, network, type);
+}
+
+void NetworkChangeNotifierDelegateAndroid::FakeMaxBandwidthChanged(
+ double max_bandwidth_mbps) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_NetworkChangeNotifier_fakeMaxBandwidthChanged(env, max_bandwidth_mbps);
+}
+
} // namespace net
diff --git a/chromium/net/android/network_change_notifier_delegate_android.h b/chromium/net/android/network_change_notifier_delegate_android.h
index e1f874ab267..a9f18d51d7c 100644
--- a/chromium/net/android/network_change_notifier_delegate_android.h
+++ b/chromium/net/android/network_change_notifier_delegate_android.h
@@ -5,6 +5,8 @@
#ifndef NET_ANDROID_NETWORK_CHANGE_NOTIFIER_DELEGATE_ANDROID_H_
#define NET_ANDROID_NETWORK_CHANGE_NOTIFIER_DELEGATE_ANDROID_H_
+#include <string>
+
#include "base/android/jni_android.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -23,13 +25,15 @@ namespace net {
class NET_EXPORT_PRIVATE NetworkChangeNotifierDelegateAndroid {
public:
typedef NetworkChangeNotifier::ConnectionType ConnectionType;
+ typedef NetworkChangeNotifier::NetworkHandle NetworkHandle;
+ typedef NetworkChangeNotifier::NetworkList NetworkList;
// Observer interface implemented by NetworkChangeNotifierAndroid which
// subscribes to network change notifications fired by the delegate (and
// initiated by the Java side).
- class Observer {
+ class Observer : public NetworkChangeNotifier::NetworkObserver {
public:
- virtual ~Observer() {}
+ ~Observer() override {}
// Updates the current connection type.
virtual void OnConnectionTypeChanged() = 0;
@@ -42,35 +46,66 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierDelegateAndroid {
NetworkChangeNotifierDelegateAndroid();
~NetworkChangeNotifierDelegateAndroid();
- // Called from NetworkChangeNotifierAndroid.java on the JNI thread whenever
+ // Called from NetworkChangeNotifier.java on the JNI thread whenever
// the connection type changes. This updates the current connection type seen
// by this class and forwards the notification to the observers that
// subscribed through AddObserver().
- void NotifyConnectionTypeChanged(JNIEnv* env,
- jobject obj,
- jint new_connection_type);
+ void NotifyConnectionTypeChanged(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint new_connection_type,
+ jint default_netid);
jint GetConnectionType(JNIEnv* env, jobject obj) const;
- // Called from NetworkChangeNotifierAndroid.java on the JNI thread whenever
+ // Called from NetworkChangeNotifier.java on the JNI thread whenever
// the maximum bandwidth of the connection changes. This updates the current
// max bandwidth seen by this class and forwards the notification to the
// observers that subscribed through AddObserver().
- void NotifyMaxBandwidthChanged(JNIEnv* env,
- jobject obj,
- jdouble new_max_bandwidth);
+ void NotifyMaxBandwidthChanged(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jdouble new_max_bandwidth);
+
+ // Called from NetworkChangeNotifier.java on the JNI thread to push
+ // down notifications of network connectivity events. These functions in
+ // turn:
+ // 1) Update |network_map_| and |default_network_|.
+ // 2) Push notifications to NetworkChangeNotifier which in turn pushes
+ // notifications to its NetworkObservers. Note that these functions
+ // perform valuable transformations on the signals like deduplicating.
+ // For descriptions of what individual calls mean, see
+ // NetworkChangeNotifierAutoDetect.Observer functions of the same names.
+ void NotifyOfNetworkConnect(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint net_id,
+ jint connection_type);
+ void NotifyOfNetworkSoonToDisconnect(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint net_id);
+ void NotifyOfNetworkDisconnect(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint net_id);
+ void NotifyUpdateActiveNetworkList(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jintArray>& active_networks);
// These methods can be called on any thread. Note that the provided observer
// will be notified on the thread AddObserver() is called on.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
- // Can be called from any thread.
+ // These methods are simply implementations of NetworkChangeNotifier APIs of
+ // the same name. They can be called from any thread.
ConnectionType GetCurrentConnectionType() const;
-
- // Can be called from any thread.
void GetCurrentMaxBandwidthAndConnectionType(
double* max_bandwidth_mbps,
ConnectionType* connection_type) const;
+ ConnectionType GetNetworkConnectionType(NetworkHandle network) const;
+ NetworkHandle GetCurrentDefaultNetwork() const;
+ void GetCurrentlyConnectedNetworks(NetworkList* network_list) const;
// Initializes JNI bindings.
static bool Register(JNIEnv* env);
@@ -78,20 +113,40 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierDelegateAndroid {
private:
friend class BaseNetworkChangeNotifierAndroidTest;
+ // Map of active connected networks and their connection type.
+ typedef std::map<NetworkHandle, ConnectionType> NetworkMap;
+
+ // Converts a Java int[] into a NetworkMap. Expects int[] to contain
+ // repeated instances of: NetworkHandle, ConnectionType
+ static void JavaIntArrayToNetworkMap(JNIEnv* env,
+ jintArray int_array,
+ NetworkMap* network_map);
+
+ // Setters that grab appropriate lock.
void SetCurrentConnectionType(ConnectionType connection_type);
void SetCurrentMaxBandwidth(double max_bandwidth);
+ void SetCurrentDefaultNetwork(NetworkHandle default_network);
+ void SetCurrentNetworksAndTypes(NetworkMap network_map);
// Methods calling the Java side exposed for testing.
void SetOnline();
void SetOffline();
+ void FakeNetworkConnected(NetworkHandle network, ConnectionType type);
+ void FakeNetworkSoonToBeDisconnected(NetworkHandle network);
+ void FakeNetworkDisconnected(NetworkHandle network);
+ void FakeUpdateActiveNetworkList(NetworkList networks);
+ void FakeDefaultNetwork(NetworkHandle network, ConnectionType type);
+ void FakeMaxBandwidthChanged(double max_bandwidth_mbps);
base::ThreadChecker thread_checker_;
scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;
- scoped_refptr<base::SingleThreadTaskRunner> jni_task_runner_;
base::android::ScopedJavaGlobalRef<jobject> java_network_change_notifier_;
+
mutable base::Lock connection_lock_; // Protects the state below.
ConnectionType connection_type_;
double connection_max_bandwidth_;
+ NetworkHandle default_network_;
+ NetworkMap network_map_;
DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierDelegateAndroid);
};
diff --git a/chromium/net/android/network_library.cc b/chromium/net/android/network_library.cc
index f4bda87f856..eb2376e77e9 100644
--- a/chromium/net/android/network_library.cc
+++ b/chromium/net/android/network_library.cc
@@ -4,6 +4,7 @@
#include "net/android/network_library.h"
+#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
diff --git a/chromium/net/android/network_library.h b/chromium/net/android/network_library.h
index 5befcdf4683..ddfb5e92eee 100644
--- a/chromium/net/android/network_library.h
+++ b/chromium/net/android/network_library.h
@@ -6,6 +6,7 @@
#define NET_ANDROID_NETWORK_LIBRARY_H_
#include <jni.h>
+#include <stddef.h>
#include <stdint.h>
#include <string>
diff --git a/chromium/net/android/traffic_stats_unittest.cc b/chromium/net/android/traffic_stats_unittest.cc
index 0d53c24658c..de49ec53d2b 100644
--- a/chromium/net/android/traffic_stats_unittest.cc
+++ b/chromium/net/android/traffic_stats_unittest.cc
@@ -15,10 +15,10 @@ namespace net {
namespace {
TEST(TrafficStatsAndroidTest, BasicsTest) {
- test_server::EmbeddedTestServer embedded_test_server;
+ EmbeddedTestServer embedded_test_server;
embedded_test_server.ServeFilesFromDirectory(
base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
- ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server.Start());
int64_t tx_bytes_before_request = -1;
int64_t rx_bytes_before_request = -1;
@@ -48,10 +48,10 @@ TEST(TrafficStatsAndroidTest, BasicsTest) {
}
TEST(TrafficStatsAndroidTest, UIDBasicsTest) {
- test_server::EmbeddedTestServer embedded_test_server;
+ EmbeddedTestServer embedded_test_server;
embedded_test_server.ServeFilesFromDirectory(
base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
- ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady());
+ ASSERT_TRUE(embedded_test_server.Start());
int64_t tx_bytes_before_request = -1;
int64_t rx_bytes_before_request = -1;
diff --git a/chromium/net/base/address_family.cc b/chromium/net/base/address_family.cc
new file mode 100644
index 00000000000..1af5e001065
--- /dev/null
+++ b/chromium/net/base/address_family.cc
@@ -0,0 +1,36 @@
+// Copyright 2015 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/address_family.h"
+
+#include "base/logging.h"
+#include "net/base/sys_addrinfo.h"
+
+namespace net {
+
+AddressFamily GetAddressFamily(const IPAddressNumber& address) {
+ switch (address.size()) {
+ case kIPv4AddressSize:
+ return ADDRESS_FAMILY_IPV4;
+ case kIPv6AddressSize:
+ return ADDRESS_FAMILY_IPV6;
+ default:
+ return ADDRESS_FAMILY_UNSPECIFIED;
+ }
+}
+
+int ConvertAddressFamily(AddressFamily address_family) {
+ switch (address_family) {
+ case ADDRESS_FAMILY_UNSPECIFIED:
+ return AF_UNSPEC;
+ case ADDRESS_FAMILY_IPV4:
+ return AF_INET;
+ case ADDRESS_FAMILY_IPV6:
+ return AF_INET6;
+ }
+ NOTREACHED();
+ return AF_UNSPEC;
+}
+
+} // namespace net
diff --git a/chromium/net/base/address_family.h b/chromium/net/base/address_family.h
index eb87ae3bf32..57ec48db839 100644
--- a/chromium/net/base/address_family.h
+++ b/chromium/net/base/address_family.h
@@ -5,6 +5,9 @@
#ifndef NET_BASE_ADDRESS_FAMILY_H_
#define NET_BASE_ADDRESS_FAMILY_H_
+#include "net/base/ip_address_number.h"
+#include "net/base/net_export.h"
+
namespace net {
// Enum wrapper around the address family types supported by host resolver
@@ -30,6 +33,12 @@ enum {
};
typedef int HostResolverFlags;
+// Returns AddressFamily for |address|.
+NET_EXPORT AddressFamily GetAddressFamily(const IPAddressNumber& address);
+
+// Maps the given AddressFamily to either AF_INET, AF_INET6 or AF_UNSPEC.
+NET_EXPORT int ConvertAddressFamily(AddressFamily address_family);
+
} // namespace net
#endif // NET_BASE_ADDRESS_FAMILY_H_
diff --git a/chromium/net/base/address_family_unittest.cc b/chromium/net/base/address_family_unittest.cc
new file mode 100644
index 00000000000..6668ea24a1a
--- /dev/null
+++ b/chromium/net/base/address_family_unittest.cc
@@ -0,0 +1,22 @@
+// Copyright 2015 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/address_family.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+TEST(AddressFamilyTest, GetAddressFamily) {
+ IPAddressNumber number;
+ EXPECT_EQ(ADDRESS_FAMILY_UNSPECIFIED, GetAddressFamily(number));
+ EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &number));
+ EXPECT_EQ(ADDRESS_FAMILY_IPV4, GetAddressFamily(number));
+ EXPECT_TRUE(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number));
+ EXPECT_EQ(ADDRESS_FAMILY_IPV6, GetAddressFamily(number));
+}
+
+} // namespace
+} // namespace net
diff --git a/chromium/net/base/address_list.cc b/chromium/net/base/address_list.cc
index 98704edd3c3..5b4fe34ac03 100644
--- a/chromium/net/base/address_list.cc
+++ b/chromium/net/base/address_list.cc
@@ -4,6 +4,8 @@
#include "net/base/address_list.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/values.h"
@@ -25,8 +27,8 @@ scoped_ptr<base::Value> NetLogAddressListCallback(
list->Append(new base::StringValue(it->ToString()));
}
- dict->Set("address_list", list.Pass());
- return dict.Pass();
+ dict->Set("address_list", std::move(list));
+ return std::move(dict);
}
} // namespace
@@ -46,6 +48,12 @@ AddressList AddressList::CreateFromIPAddress(const IPAddressNumber& address,
}
// static
+AddressList AddressList::CreateFromIPAddress(const IPAddress& address,
+ uint16_t port) {
+ return AddressList(IPEndPoint(address, port));
+}
+
+// static
AddressList AddressList::CreateFromIPAddressList(
const IPAddressList& addresses,
const std::string& canonical_name) {
diff --git a/chromium/net/base/address_list.h b/chromium/net/base/address_list.h
index 0f9080090d1..72e0a43d5d8 100644
--- a/chromium/net/base/address_list.h
+++ b/chromium/net/base/address_list.h
@@ -5,10 +5,11 @@
#ifndef NET_BASE_ADDRESS_LIST_H_
#define NET_BASE_ADDRESS_LIST_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "net/base/ip_address_number.h"
#include "net/base/ip_endpoint.h"
@@ -19,6 +20,8 @@ struct addrinfo;
namespace net {
+class IPAddress;
+
class NET_EXPORT AddressList
: NON_EXPORTED_BASE(private std::vector<IPEndPoint>) {
public:
@@ -28,9 +31,13 @@ class NET_EXPORT AddressList
// Creates an address list for a single IP literal.
explicit AddressList(const IPEndPoint& endpoint);
+ // DEPRECATED(crbug.com/496258): Use the method below that takes IPAddress.
static AddressList CreateFromIPAddress(const IPAddressNumber& address,
uint16_t port);
+ static AddressList CreateFromIPAddress(const IPAddress& address,
+ uint16_t port);
+
static AddressList CreateFromIPAddressList(
const IPAddressList& addresses,
const std::string& canonical_name);
diff --git a/chromium/net/base/address_list_unittest.cc b/chromium/net/base/address_list_unittest.cc
index cdf7fa8c8cd..44955a96736 100644
--- a/chromium/net/base/address_list_unittest.cc
+++ b/chromium/net/base/address_list_unittest.cc
@@ -6,7 +6,7 @@
#include "base/strings/string_util.h"
#include "base/sys_byteorder.h"
-#include "net/base/net_util.h"
+#include "net/base/sockaddr_storage.h"
#include "net/base/sys_addrinfo.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/base/address_tracker_linux.cc b/chromium/net/base/address_tracker_linux.cc
index 58a122f5c2e..a9983f49d6e 100644
--- a/chromium/net/base/address_tracker_linux.cc
+++ b/chromium/net/base/address_tracker_linux.cc
@@ -119,7 +119,8 @@ AddressTrackerLinux::AddressTrackerLinux()
connection_type_initialized_(false),
connection_type_initialized_cv_(&connection_type_lock_),
current_connection_type_(NetworkChangeNotifier::CONNECTION_NONE),
- tracking_(false) {
+ tracking_(false),
+ threads_waiting_for_connection_type_initialization_(0) {
}
AddressTrackerLinux::AddressTrackerLinux(
@@ -136,7 +137,8 @@ AddressTrackerLinux::AddressTrackerLinux(
connection_type_initialized_(false),
connection_type_initialized_cv_(&connection_type_lock_),
current_connection_type_(NetworkChangeNotifier::CONNECTION_NONE),
- tracking_(true) {
+ tracking_(true),
+ threads_waiting_for_connection_type_initialization_(0) {
DCHECK(!address_callback.is_null());
DCHECK(!link_callback.is_null());
}
@@ -221,7 +223,7 @@ void AddressTrackerLinux::Init() {
{
AddressTrackerAutoLock lock(*this, connection_type_lock_);
connection_type_initialized_ = true;
- connection_type_initialized_cv_.Signal();
+ connection_type_initialized_cv_.Broadcast();
}
if (tracking_) {
@@ -240,7 +242,7 @@ void AddressTrackerLinux::AbortAndForceOnline() {
AddressTrackerAutoLock lock(*this, connection_type_lock_);
current_connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN;
connection_type_initialized_ = true;
- connection_type_initialized_cv_.Signal();
+ connection_type_initialized_cv_.Broadcast();
}
AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const {
@@ -268,9 +270,11 @@ AddressTrackerLinux::GetCurrentConnectionType() {
base::ThreadRestrictions::ScopedAllowWait allow_wait;
AddressTrackerAutoLock lock(*this, connection_type_lock_);
// Make sure the initial connection type is set before returning.
+ threads_waiting_for_connection_type_initialization_++;
while (!connection_type_initialized_) {
connection_type_initialized_cv_.Wait();
}
+ threads_waiting_for_connection_type_initialization_--;
return current_connection_type_;
}
@@ -467,6 +471,12 @@ void AddressTrackerLinux::UpdateCurrentConnectionType() {
current_connection_type_ = type;
}
+int AddressTrackerLinux::GetThreadsWaitingForConnectionTypeInitForTesting()
+{
+ AddressTrackerAutoLock lock(*this, connection_type_lock_);
+ return threads_waiting_for_connection_type_initialization_;
+}
+
AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock(
const AddressTrackerLinux& tracker,
base::Lock& lock)
diff --git a/chromium/net/base/address_tracker_linux.h b/chromium/net/base/address_tracker_linux.h
index 172179923ff..da5c8934e0d 100644
--- a/chromium/net/base/address_tracker_linux.h
+++ b/chromium/net/base/address_tracker_linux.h
@@ -10,18 +10,19 @@
#define net net_kernel
#include <linux/rtnetlink.h>
#undef net
+#include <stddef.h>
#include <map>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
-#include "net/base/net_util.h"
+#include "net/base/ip_address_number.h"
#include "net/base/network_change_notifier.h"
namespace net {
@@ -138,6 +139,10 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
// Updates current_connection_type_ based on the network list.
void UpdateCurrentConnectionType();
+ // Used by AddressTrackerLinuxTest, returns the number of threads waiting
+ // for |connection_type_initialized_cv_|.
+ int GetThreadsWaitingForConnectionTypeInitForTesting();
+
// Gets the name of an interface given the interface index |interface_index|.
// May return empty string if it fails but should not return NULL. This is
// overridden by tests.
@@ -165,6 +170,7 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
base::ConditionVariable connection_type_initialized_cv_;
NetworkChangeNotifier::ConnectionType current_connection_type_;
bool tracking_;
+ int threads_waiting_for_connection_type_initialization_;
// Used to verify single-threaded access in non-tracking mode.
base::ThreadChecker thread_checker_;
diff --git a/chromium/net/base/address_tracker_linux_unittest.cc b/chromium/net/base/address_tracker_linux_unittest.cc
index 694c091de37..53c478d7eec 100644
--- a/chromium/net/base/address_tracker_linux_unittest.cc
+++ b/chromium/net/base/address_tracker_linux_unittest.cc
@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "base/memory/scoped_ptr.h"
+#include "base/synchronization/spin_wait.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/simple_thread.h"
#include "net/base/address_tracker_linux.h"
#include <linux/if.h>
@@ -105,6 +108,10 @@ class AddressTrackerLinuxTest : public testing::Test {
ignored_interfaces_.insert(interface_name);
}
+ int GetThreadsWaitingForConnectionTypeInit() {
+ return tracker_->GetThreadsWaitingForConnectionTypeInitForTesting();
+ }
+
base::hash_set<std::string> ignored_interfaces_;
scoped_ptr<AddressTrackerLinux> tracker_;
AddressTrackerLinux::GetInterfaceNameFunction original_get_interface_name_;
@@ -678,6 +685,53 @@ TEST_F(AddressTrackerLinuxTest, NonTrackingModeInit) {
tracker.Init();
}
+class GetCurrentConnectionTypeRunner
+ : public base::DelegateSimpleThread::Delegate {
+ public:
+ explicit GetCurrentConnectionTypeRunner(AddressTrackerLinux* tracker,
+ const std::string& thread_name)
+ : tracker_(tracker), done_(true, false), thread_(this, thread_name) {
+ }
+ ~GetCurrentConnectionTypeRunner() override {}
+
+ void Run() override {
+ tracker_->GetCurrentConnectionType();
+ done_.Signal();
+ }
+
+ void Start() {
+ thread_.Start();
+ }
+
+ void VerifyCompletes() {
+ EXPECT_TRUE(done_.TimedWait(base::TimeDelta::FromSeconds(5)));
+ thread_.Join();
+ }
+
+ private:
+ AddressTrackerLinux* const tracker_;
+ base::WaitableEvent done_;
+ base::DelegateSimpleThread thread_;
+};
+
+TEST_F(AddressTrackerLinuxTest, BroadcastInit) {
+ InitializeAddressTracker(true);
+
+ GetCurrentConnectionTypeRunner runner1(tracker_.get(), "waiter_thread_1");
+ GetCurrentConnectionTypeRunner runner2(tracker_.get(), "waiter_thread_2");
+
+ runner1.Start();
+ runner2.Start();
+
+ SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(
+ GetThreadsWaitingForConnectionTypeInit() == 2);
+
+ tracker_->Init();
+
+ runner1.VerifyCompletes();
+ runner2.VerifyCompletes();
+}
+
} // namespace
} // namespace internal
diff --git a/chromium/net/base/backoff_entry.cc b/chromium/net/base/backoff_entry.cc
index ac4882c9a28..64125721c57 100644
--- a/chromium/net/base/backoff_entry.cc
+++ b/chromium/net/base/backoff_entry.cc
@@ -8,7 +8,6 @@
#include <cmath>
#include <limits>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/rand_util.h"
@@ -145,7 +144,7 @@ base::TimeTicks BackoffEntry::CalculateReleaseTime() const {
base::internal::CheckedNumeric<int64_t> backoff_duration_us = delay_ms + 0.5;
backoff_duration_us *= base::Time::kMicrosecondsPerMillisecond;
base::TimeDelta backoff_duration = base::TimeDelta::FromMicroseconds(
- backoff_duration_us.ValueOrDefault(kint64max));
+ backoff_duration_us.ValueOrDefault(std::numeric_limits<int64_t>::max()));
base::TimeTicks release_time = BackoffDurationToReleaseTime(backoff_duration);
// Never reduce previously set release horizon, e.g. due to Retry-After
@@ -162,7 +161,8 @@ base::TimeTicks BackoffEntry::BackoffDurationToReleaseTime(
backoff_duration.InMicroseconds();
calculated_release_time_us += kTimeTicksNowUs;
- base::internal::CheckedNumeric<int64_t> maximum_release_time_us = kint64max;
+ base::internal::CheckedNumeric<int64_t> maximum_release_time_us =
+ std::numeric_limits<int64_t>::max();
if (policy_->maximum_backoff_ms >= 0) {
maximum_release_time_us = policy_->maximum_backoff_ms;
maximum_release_time_us *= base::Time::kMicrosecondsPerMillisecond;
@@ -171,9 +171,10 @@ base::TimeTicks BackoffEntry::BackoffDurationToReleaseTime(
// Decide between maximum release time and calculated release time, accounting
// for overflow with both.
- int64_t release_time_us =
- std::min(calculated_release_time_us.ValueOrDefault(kint64max),
- maximum_release_time_us.ValueOrDefault(kint64max));
+ int64_t release_time_us = std::min(calculated_release_time_us.ValueOrDefault(
+ std::numeric_limits<int64_t>::max()),
+ maximum_release_time_us.ValueOrDefault(
+ std::numeric_limits<int64_t>::max()));
return base::TimeTicks() + base::TimeDelta::FromMicroseconds(release_time_us);
}
diff --git a/chromium/net/base/backoff_entry.h b/chromium/net/base/backoff_entry.h
index 2aa3a96aca8..3efd32cee01 100644
--- a/chromium/net/base/backoff_entry.h
+++ b/chromium/net/base/backoff_entry.h
@@ -5,6 +5,8 @@
#ifndef NET_BASE_BACKOFF_ENTRY_H_
#define NET_BASE_BACKOFF_ENTRY_H_
+#include <stdint.h>
+
#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
diff --git a/chromium/net/base/backoff_entry_serializer.cc b/chromium/net/base/backoff_entry_serializer.cc
index 1467553182b..e7366851f7c 100644
--- a/chromium/net/base/backoff_entry_serializer.cc
+++ b/chromium/net/base/backoff_entry_serializer.cc
@@ -4,6 +4,8 @@
#include "net/base/backoff_entry_serializer.h"
+#include <utility>
+
#include "base/strings/string_number_conversions.h"
#include "base/time/tick_clock.h"
#include "base/values.h"
@@ -34,7 +36,7 @@ scoped_ptr<base::Value> BackoffEntrySerializer::SerializeToValue(
serialized->AppendString(
base::Int64ToString(absolute_release_time.ToInternalValue()));
- return serialized.Pass();
+ return std::move(serialized);
}
scoped_ptr<BackoffEntry> BackoffEntrySerializer::DeserializeFromValue(
diff --git a/chromium/net/base/chunked_upload_data_stream.cc b/chromium/net/base/chunked_upload_data_stream.cc
index 6ba40c585bf..2b9c4807c7a 100644
--- a/chromium/net/base/chunked_upload_data_stream.cc
+++ b/chromium/net/base/chunked_upload_data_stream.cc
@@ -5,7 +5,6 @@
#include "net/base/chunked_upload_data_stream.h"
#include "base/logging.h"
-#include "base/stl_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -28,7 +27,8 @@ void ChunkedUploadDataStream::AppendData(
DCHECK(data_len > 0 || is_done);
if (data_len > 0) {
DCHECK(data);
- upload_data_.push_back(new std::vector<char>(data, data + data_len));
+ upload_data_.push_back(
+ make_scoped_ptr(new std::vector<char>(data, data + data_len)));
}
all_data_appended_ = is_done;
@@ -74,12 +74,11 @@ int ChunkedUploadDataStream::ReadChunk(IOBuffer* buf, int buf_len) {
// Copy as much data as possible from |upload_data_| to |buf|.
int bytes_read = 0;
while (read_index_ < upload_data_.size() && bytes_read < buf_len) {
- std::vector<char>* data = upload_data_[read_index_];
+ std::vector<char>* data = upload_data_[read_index_].get();
size_t bytes_to_read =
std::min(static_cast<size_t>(buf_len - bytes_read),
data->size() - read_offset_);
- memcpy(buf->data() + bytes_read,
- vector_as_array(data) + read_offset_,
+ memcpy(buf->data() + bytes_read, data->data() + read_offset_,
bytes_to_read);
bytes_read += bytes_to_read;
read_offset_ += bytes_to_read;
diff --git a/chromium/net/base/chunked_upload_data_stream.h b/chromium/net/base/chunked_upload_data_stream.h
index b79108cad4d..7b5e2dfecb6 100644
--- a/chromium/net/base/chunked_upload_data_stream.h
+++ b/chromium/net/base/chunked_upload_data_stream.h
@@ -5,11 +5,13 @@
#ifndef NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
#define NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/base/upload_data_stream.h"
@@ -48,7 +50,7 @@ class NET_EXPORT ChunkedUploadDataStream : public UploadDataStream {
// True once all data has been appended to the stream.
bool all_data_appended_;
- ScopedVector<std::vector<char>> upload_data_;
+ std::vector<scoped_ptr<std::vector<char>>> upload_data_;
// Buffer to write the next read's data to. Only set when a call to
// ReadInternal reads no data.
diff --git a/chromium/net/base/completion_callback.h b/chromium/net/base/completion_callback.h
index 3b3e6055a21..a41caa55cb5 100644
--- a/chromium/net/base/completion_callback.h
+++ b/chromium/net/base/completion_callback.h
@@ -5,6 +5,8 @@
#ifndef NET_BASE_COMPLETION_CALLBACK_H__
#define NET_BASE_COMPLETION_CALLBACK_H__
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/cancelable_callback.h"
diff --git a/chromium/net/base/crypto_module.h b/chromium/net/base/crypto_module.h
index 164df3c778e..e3765e96f7d 100644
--- a/chromium/net/base/crypto_module.h
+++ b/chromium/net/base/crypto_module.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/data_url.cc b/chromium/net/base/data_url.cc
index 26720c548d1..07b8fb00bb5 100644
--- a/chromium/net/base/data_url.cc
+++ b/chromium/net/base/data_url.cc
@@ -9,7 +9,6 @@
#include "net/base/data_url.h"
#include "base/base64.h"
-#include "base/basictypes.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "net/base/escape.h"
diff --git a/chromium/net/base/data_url_unittest.cc b/chromium/net/base/data_url_unittest.cc
index fb7dc76d954..4bd02519883 100644
--- a/chromium/net/base/data_url_unittest.cc
+++ b/chromium/net/base/data_url_unittest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
#include "net/base/data_url.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
diff --git a/chromium/net/base/directory_lister.cc b/chromium/net/base/directory_lister.cc
index efdc53c4a7b..6b06ca62e11 100644
--- a/chromium/net/base/directory_lister.cc
+++ b/chromium/net/base/directory_lister.cc
@@ -5,6 +5,7 @@
#include "net/base/directory_lister.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/files/file_enumerator.h"
@@ -121,9 +122,9 @@ void DirectoryLister::Core::Start() {
if (!base::DirectoryExists(dir_)) {
origin_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&Core::DoneOnOriginThread, this,
- base::Passed(directory_list.Pass()), ERR_FILE_NOT_FOUND));
+ FROM_HERE, base::Bind(&Core::DoneOnOriginThread, this,
+ base::Passed(std::move(directory_list)),
+ ERR_FILE_NOT_FOUND));
return;
}
@@ -169,7 +170,7 @@ void DirectoryLister::Core::Start() {
origin_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::DoneOnOriginThread, this,
- base::Passed(directory_list.Pass()), OK));
+ base::Passed(std::move(directory_list)), OK));
}
bool DirectoryLister::Core::IsCancelled() const {
diff --git a/chromium/net/base/net_util_icu.cc b/chromium/net/base/directory_listing.cc
index c174c92087b..25d98bc6811 100644
--- a/chromium/net/base/net_util_icu.cc
+++ b/chromium/net/base/directory_listing.cc
@@ -1,17 +1,40 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2015 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/net_util.h"
+#include "net/base/directory_listing.h"
#include "base/i18n/time_formatting.h"
#include "base/json/string_escape.h"
+#include "base/logging.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
#include "net/base/escape.h"
+#include "net/base/net_module.h"
+#include "net/grit/net_resources.h"
namespace net {
+std::string GetDirectoryListingHeader(const base::string16& title) {
+ static const base::StringPiece header(
+ NetModule::GetResource(IDR_DIR_HEADER_HTML));
+ // This can be null in unit tests.
+ DLOG_IF(WARNING, header.empty())
+ << "Missing resource: directory listing header";
+
+ std::string result;
+ if (!header.empty())
+ result.assign(header.data(), header.size());
+
+ result.append("<script>start(");
+ base::EscapeJSONString(title, true, &result);
+ result.append(");</script>\n");
+
+ return result;
+}
+
std::string GetDirectoryListingEntry(const base::string16& name,
const std::string& raw_bytes,
bool is_dir,
diff --git a/chromium/net/base/directory_listing.h b/chromium/net/base/directory_listing.h
new file mode 100644
index 00000000000..7f6301ad318
--- /dev/null
+++ b/chromium/net/base/directory_listing.h
@@ -0,0 +1,44 @@
+// Copyright 2015 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_DIRECTORY_LISTING_H_
+#define NET_BASE_DIRECTORY_LISTING_H_
+
+#include <stdint.h>
+#include <string>
+
+#include "base/strings/string16.h"
+#include "net/base/net_export.h"
+
+namespace base {
+class Time;
+}
+
+namespace net {
+
+// Call these functions to get the html snippet for a directory listing.
+// The return values of both functions are in UTF-8.
+NET_EXPORT std::string GetDirectoryListingHeader(const base::string16& title);
+
+// Given the name of a file in a directory (ftp or local) and
+// other information (is_dir, size, modification time), it returns
+// the html snippet to add the entry for the file to the directory listing.
+// Currently, it's a script tag containing a call to a Javascript function
+// |addRow|.
+//
+// |name| is the file name to be displayed. |raw_bytes| will be used
+// as the actual target of the link (so for example, ftp links should use
+// server's encoding). If |raw_bytes| is an empty string, UTF-8 encoded |name|
+// will be used.
+//
+// Both |name| and |raw_bytes| are escaped internally.
+NET_EXPORT std::string GetDirectoryListingEntry(const base::string16& name,
+ const std::string& raw_bytes,
+ bool is_dir,
+ int64_t size,
+ base::Time modified);
+
+} // namespace net
+
+#endif // NET_BASE_DIRECTORY_LISTING_H_
diff --git a/chromium/net/base/net_util_icu_unittest.cc b/chromium/net/base/directory_listing_unittest.cc
index cac922f58fe..7470c2ab9e1 100644
--- a/chromium/net/base/net_util_icu_unittest.cc
+++ b/chromium/net/base/directory_listing_unittest.cc
@@ -2,16 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/base/net_util.h"
-
-#include <stdint.h>
-
-#include <string>
+#include "net/base/directory_listing.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
namespace net {
@@ -26,7 +21,7 @@ struct GetDirectoryListingEntryCase {
const char* const expected;
};
-TEST(NetUtilTest, GetDirectoryListingEntry) {
+TEST(DirectoryListingTest, GetDirectoryListingEntry) {
const GetDirectoryListingEntryCase test_cases[] = {
{L"Foo",
"",
diff --git a/chromium/net/base/elements_upload_data_stream.cc b/chromium/net/base/elements_upload_data_stream.cc
index e23f632ab38..29b77babb11 100644
--- a/chromium/net/base/elements_upload_data_stream.cc
+++ b/chromium/net/base/elements_upload_data_stream.cc
@@ -15,14 +15,13 @@
namespace net {
ElementsUploadDataStream::ElementsUploadDataStream(
- ScopedVector<UploadElementReader> element_readers,
+ std::vector<scoped_ptr<UploadElementReader>> element_readers,
int64_t identifier)
: UploadDataStream(false, identifier),
- element_readers_(element_readers.Pass()),
+ element_readers_(std::move(element_readers)),
element_index_(0),
read_failed_(false),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
ElementsUploadDataStream::~ElementsUploadDataStream() {
}
@@ -30,10 +29,10 @@ ElementsUploadDataStream::~ElementsUploadDataStream() {
scoped_ptr<UploadDataStream> ElementsUploadDataStream::CreateWithReader(
scoped_ptr<UploadElementReader> reader,
int64_t identifier) {
- ScopedVector<UploadElementReader> readers;
- readers.push_back(reader.Pass());
+ std::vector<scoped_ptr<UploadElementReader>> readers;
+ readers.push_back(std::move(reader));
return scoped_ptr<UploadDataStream>(
- new ElementsUploadDataStream(readers.Pass(), identifier));
+ new ElementsUploadDataStream(std::move(readers), identifier));
}
int ElementsUploadDataStream::InitInternal() {
@@ -48,14 +47,14 @@ int ElementsUploadDataStream::ReadInternal(
}
bool ElementsUploadDataStream::IsInMemory() const {
- for (size_t i = 0; i < element_readers_.size(); ++i) {
- if (!element_readers_[i]->IsInMemory())
+ for (const scoped_ptr<UploadElementReader>& it : element_readers_) {
+ if (!it->IsInMemory())
return false;
}
return true;
}
-const ScopedVector<UploadElementReader>*
+const std::vector<scoped_ptr<UploadElementReader>>*
ElementsUploadDataStream::GetElementReaders() const {
return &element_readers_;
}
@@ -69,7 +68,7 @@ void ElementsUploadDataStream::ResetInternal() {
int ElementsUploadDataStream::InitElements(size_t start_index) {
// Call Init() for all elements.
for (size_t i = start_index; i < element_readers_.size(); ++i) {
- UploadElementReader* reader = element_readers_[i];
+ UploadElementReader* reader = element_readers_[i].get();
// When new_result is ERR_IO_PENDING, InitInternal() will be called
// with start_index == i + 1 when reader->Init() finishes.
int result = reader->Init(
@@ -83,8 +82,8 @@ int ElementsUploadDataStream::InitElements(size_t start_index) {
}
uint64_t total_size = 0;
- for (size_t i = 0; i < element_readers_.size(); ++i) {
- total_size += element_readers_[i]->GetContentLength();
+ for (const scoped_ptr<UploadElementReader>& it : element_readers_) {
+ total_size += it->GetContentLength();
}
SetSize(total_size);
return OK;
@@ -105,7 +104,7 @@ void ElementsUploadDataStream::OnInitElementCompleted(size_t index,
int ElementsUploadDataStream::ReadElements(
const scoped_refptr<DrainableIOBuffer>& buf) {
while (!read_failed_ && element_index_ < element_readers_.size()) {
- UploadElementReader* reader = element_readers_[element_index_];
+ UploadElementReader* reader = element_readers_[element_index_].get();
if (reader->BytesRemaining() == 0) {
++element_index_;
diff --git a/chromium/net/base/elements_upload_data_stream.h b/chromium/net/base/elements_upload_data_stream.h
index c65c3c61b67..c3221c2c154 100644
--- a/chromium/net/base/elements_upload_data_stream.h
+++ b/chromium/net/base/elements_upload_data_stream.h
@@ -5,11 +5,14 @@
#ifndef NET_BASE_ELEMENTS_UPLOAD_DATA_STREAM_H_
#define NET_BASE_ELEMENTS_UPLOAD_DATA_STREAM_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"
#include "net/base/upload_data_stream.h"
@@ -23,8 +26,9 @@ class UploadElementReader;
// A non-chunked UploadDataStream consisting of one or more UploadElements.
class NET_EXPORT ElementsUploadDataStream : public UploadDataStream {
public:
- ElementsUploadDataStream(ScopedVector<UploadElementReader> element_readers,
- int64_t identifier);
+ ElementsUploadDataStream(
+ std::vector<scoped_ptr<UploadElementReader>> element_readers,
+ int64_t identifier);
~ElementsUploadDataStream() override;
@@ -37,7 +41,8 @@ class NET_EXPORT ElementsUploadDataStream : public UploadDataStream {
private:
// UploadDataStream implementation.
bool IsInMemory() const override;
- const ScopedVector<UploadElementReader>* GetElementReaders() const override;
+ const std::vector<scoped_ptr<UploadElementReader>>* GetElementReaders()
+ const override;
int InitInternal() override;
int ReadInternal(IOBuffer* buf, int buf_len) override;
void ResetInternal() override;
@@ -65,7 +70,7 @@ class NET_EXPORT ElementsUploadDataStream : public UploadDataStream {
void ProcessReadResult(const scoped_refptr<DrainableIOBuffer>& buf,
int result);
- ScopedVector<UploadElementReader> element_readers_;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers_;
// Index of the current upload element (i.e. the element currently being
// read). The index is used as a cursor to iterate over elements in
diff --git a/chromium/net/base/elements_upload_data_stream_unittest.cc b/chromium/net/base/elements_upload_data_stream_unittest.cc
index 8c72054190a..1671ce7e654 100644
--- a/chromium/net/base/elements_upload_data_stream_unittest.cc
+++ b/chromium/net/base/elements_upload_data_stream_unittest.cc
@@ -4,10 +4,12 @@
#include "net/base/elements_upload_data_stream.h"
+#include <stdint.h>
+
#include <algorithm>
+#include <limits>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -142,12 +144,12 @@ class ElementsUploadDataStreamTest : public PlatformTest {
bool error_expected);
base::ScopedTempDir temp_dir_;
- ScopedVector<UploadElementReader> element_readers_;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers_;
};
TEST_F(ElementsUploadDataStreamTest, EmptyUploadData) {
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
ASSERT_EQ(OK, stream->Init(CompletionCallback()));
EXPECT_TRUE(stream->IsInMemory());
EXPECT_EQ(0U, stream->size());
@@ -156,10 +158,10 @@ TEST_F(ElementsUploadDataStreamTest, EmptyUploadData) {
}
TEST_F(ElementsUploadDataStreamTest, ConsumeAllBytes) {
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
+ element_readers_.push_back(
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
ASSERT_EQ(OK, stream->Init(CompletionCallback()));
EXPECT_TRUE(stream->IsInMemory());
EXPECT_EQ(kTestDataSize, stream->size());
@@ -182,13 +184,13 @@ TEST_F(ElementsUploadDataStreamTest, File) {
ASSERT_EQ(static_cast<int>(kTestDataSize),
base::WriteFile(temp_file_path, kTestData, kTestDataSize));
- element_readers_.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
TestCompletionCallback init_callback;
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
ASSERT_EQ(OK, init_callback.WaitForResult());
EXPECT_FALSE(stream->IsInMemory());
@@ -218,13 +220,13 @@ TEST_F(ElementsUploadDataStreamTest, FileSmallerThanLength) {
UploadFileElementReader::ScopedOverridingContentLengthForTests
overriding_content_length(kFakeSize);
- element_readers_.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
TestCompletionCallback init_callback;
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
ASSERT_EQ(OK, init_callback.WaitForResult());
EXPECT_FALSE(stream->IsInMemory());
@@ -251,18 +253,18 @@ TEST_F(ElementsUploadDataStreamTest, FileSmallerThanLength) {
TEST_F(ElementsUploadDataStreamTest, ReadErrorSync) {
// This element cannot be read.
- MockUploadElementReader* reader =
- new MockUploadElementReader(kTestDataSize, true);
+ scoped_ptr<MockUploadElementReader> reader(
+ new MockUploadElementReader(kTestDataSize, true));
EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
reader->SetReadExpectation(ERR_FAILED);
- element_readers_.push_back(reader);
+ element_readers_.push_back(std::move(reader));
// This element is ignored because of the error from the previous reader.
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
+ element_readers_.push_back(
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
// Run Init().
ASSERT_EQ(OK, stream->Init(CompletionCallback()));
@@ -287,18 +289,18 @@ TEST_F(ElementsUploadDataStreamTest, ReadErrorSync) {
TEST_F(ElementsUploadDataStreamTest, ReadErrorAsync) {
// This element cannot be read.
- MockUploadElementReader* reader =
- new MockUploadElementReader(kTestDataSize, false);
+ scoped_ptr<MockUploadElementReader> reader(
+ new MockUploadElementReader(kTestDataSize, false));
reader->SetAsyncInitExpectation(OK);
reader->SetReadExpectation(ERR_FAILED);
- element_readers_.push_back(reader);
+ element_readers_.push_back(std::move(reader));
// This element is ignored because of the error from the previous reader.
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
+ element_readers_.push_back(
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
// Run Init().
TestCompletionCallback init_callback;
@@ -334,17 +336,17 @@ TEST_F(ElementsUploadDataStreamTest, FileAndBytes) {
const uint64_t kFileRangeOffset = 1;
const uint64_t kFileRangeLength = 4;
- element_readers_.push_back(new UploadFileElementReader(
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
base::ThreadTaskRunnerHandle::Get().get(), temp_file_path,
- kFileRangeOffset, kFileRangeLength, base::Time()));
+ kFileRangeOffset, kFileRangeLength, base::Time())));
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
+ element_readers_.push_back(
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
const uint64_t kStreamSize = kTestDataSize + kFileRangeLength;
TestCompletionCallback init_callback;
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
ASSERT_EQ(OK, init_callback.WaitForResult());
EXPECT_FALSE(stream->IsInMemory());
@@ -367,30 +369,33 @@ TEST_F(ElementsUploadDataStreamTest, FileAndBytes) {
// Init() with on-memory and not-on-memory readers.
TEST_F(ElementsUploadDataStreamTest, InitAsync) {
// Create UploadDataStream with mock readers.
- MockUploadElementReader* reader = NULL;
-
- reader = new MockUploadElementReader(kTestDataSize, true);
+ scoped_ptr<MockUploadElementReader> reader(
+ new MockUploadElementReader(kTestDataSize, true));
EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
- element_readers_.push_back(reader);
+ element_readers_.push_back(std::move(reader));
- reader = new MockUploadElementReader(kTestDataSize, true);
- EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
- element_readers_.push_back(reader);
+ scoped_ptr<MockUploadElementReader> reader2(
+ new MockUploadElementReader(kTestDataSize, true));
+ EXPECT_CALL(*reader2, Init(_)).WillOnce(Return(OK));
+ element_readers_.push_back(std::move(reader2));
- reader = new MockUploadElementReader(kTestDataSize, false);
- reader->SetAsyncInitExpectation(OK);
- element_readers_.push_back(reader);
+ scoped_ptr<MockUploadElementReader> reader3(
+ new MockUploadElementReader(kTestDataSize, false));
+ reader3->SetAsyncInitExpectation(OK);
+ element_readers_.push_back(std::move(reader3));
- reader = new MockUploadElementReader(kTestDataSize, false);
- reader->SetAsyncInitExpectation(OK);
- element_readers_.push_back(reader);
+ scoped_ptr<MockUploadElementReader> reader4(
+ new MockUploadElementReader(kTestDataSize, false));
+ reader4->SetAsyncInitExpectation(OK);
+ element_readers_.push_back(std::move(reader4));
- reader = new MockUploadElementReader(kTestDataSize, true);
- EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
- element_readers_.push_back(reader);
+ scoped_ptr<MockUploadElementReader> reader5(
+ new MockUploadElementReader(kTestDataSize, true));
+ EXPECT_CALL(*reader5, Init(_)).WillOnce(Return(OK));
+ element_readers_.push_back(std::move(reader5));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
// Run Init().
TestCompletionCallback callback;
@@ -401,14 +406,13 @@ TEST_F(ElementsUploadDataStreamTest, InitAsync) {
// Init() of a reader fails asynchronously.
TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureAsync) {
// Create UploadDataStream with a mock reader.
- MockUploadElementReader* reader = NULL;
-
- reader = new MockUploadElementReader(kTestDataSize, false);
+ scoped_ptr<MockUploadElementReader> reader(
+ new MockUploadElementReader(kTestDataSize, false));
reader->SetAsyncInitExpectation(ERR_FAILED);
- element_readers_.push_back(reader);
+ element_readers_.push_back(std::move(reader));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
// Run Init().
TestCompletionCallback callback;
@@ -419,18 +423,18 @@ TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureAsync) {
// Init() of a reader fails synchronously.
TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureSync) {
// Create UploadDataStream with mock readers.
- MockUploadElementReader* reader = NULL;
-
- reader = new MockUploadElementReader(kTestDataSize, false);
+ scoped_ptr<MockUploadElementReader> reader(
+ new MockUploadElementReader(kTestDataSize, false));
reader->SetAsyncInitExpectation(OK);
- element_readers_.push_back(reader);
+ element_readers_.push_back(std::move(reader));
- reader = new MockUploadElementReader(kTestDataSize, true);
- EXPECT_CALL(*reader, Init(_)).WillOnce(Return(ERR_FAILED));
- element_readers_.push_back(reader);
+ scoped_ptr<MockUploadElementReader> reader2(
+ new MockUploadElementReader(kTestDataSize, true));
+ EXPECT_CALL(*reader2, Init(_)).WillOnce(Return(ERR_FAILED));
+ element_readers_.push_back(std::move(reader2));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
// Run Init().
TestCompletionCallback callback;
@@ -440,10 +444,10 @@ TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureSync) {
// Read with a buffer whose size is same as the data.
TEST_F(ElementsUploadDataStreamTest, ReadAsyncWithExactSizeBuffer) {
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
+ element_readers_.push_back(
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
ASSERT_EQ(OK, stream->Init(CompletionCallback()));
EXPECT_TRUE(stream->IsInMemory());
@@ -460,30 +464,32 @@ TEST_F(ElementsUploadDataStreamTest, ReadAsyncWithExactSizeBuffer) {
// Async Read() with on-memory and not-on-memory readers.
TEST_F(ElementsUploadDataStreamTest, ReadAsync) {
// Create UploadDataStream with mock readers.
- MockUploadElementReader* reader = NULL;
-
- reader = new MockUploadElementReader(kTestDataSize, true);
- EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
- reader->SetReadExpectation(kTestDataSize);
- element_readers_.push_back(reader);
-
- reader = new MockUploadElementReader(kTestDataSize, false);
- reader->SetAsyncInitExpectation(OK);
- reader->SetReadExpectation(kTestDataSize);
- element_readers_.push_back(reader);
-
- reader = new MockUploadElementReader(kTestDataSize, true);
+ scoped_ptr<MockUploadElementReader> reader(
+ new MockUploadElementReader(kTestDataSize, true));
EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
reader->SetReadExpectation(kTestDataSize);
- element_readers_.push_back(reader);
-
- reader = new MockUploadElementReader(kTestDataSize, false);
- reader->SetAsyncInitExpectation(OK);
- reader->SetReadExpectation(kTestDataSize);
- element_readers_.push_back(reader);
+ element_readers_.push_back(std::move(reader));
+
+ scoped_ptr<MockUploadElementReader> reader2(
+ new MockUploadElementReader(kTestDataSize, false));
+ reader2->SetAsyncInitExpectation(OK);
+ reader2->SetReadExpectation(kTestDataSize);
+ element_readers_.push_back(std::move(reader2));
+
+ scoped_ptr<MockUploadElementReader> reader3(
+ new MockUploadElementReader(kTestDataSize, true));
+ EXPECT_CALL(*reader3, Init(_)).WillOnce(Return(OK));
+ reader3->SetReadExpectation(kTestDataSize);
+ element_readers_.push_back(std::move(reader3));
+
+ scoped_ptr<MockUploadElementReader> reader4(
+ new MockUploadElementReader(kTestDataSize, false));
+ reader4->SetAsyncInitExpectation(OK);
+ reader4->SetReadExpectation(kTestDataSize);
+ element_readers_.push_back(std::move(reader4));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
// Run Init().
TestCompletionCallback init_callback;
@@ -520,13 +526,13 @@ void ElementsUploadDataStreamTest::FileChangedHelper(
bool error_expected) {
// Don't use element_readers_ here, as this function is called twice, and
// reusing element_readers_ is wrong.
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadFileElementReader(
- base::ThreadTaskRunnerHandle::Get().get(), file_path, 1, 2, time));
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), file_path, 1, 2, time)));
TestCompletionCallback init_callback;
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
int error_code = init_callback.WaitForResult();
if (error_expected)
@@ -562,13 +568,13 @@ TEST_F(ElementsUploadDataStreamTest, MultipleInit) {
base::WriteFile(temp_file_path, kTestData, kTestDataSize));
// Prepare data.
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
element_readers_.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
std::string expected_data(kTestData, kTestData + kTestDataSize);
expected_data += expected_data;
@@ -605,13 +611,13 @@ TEST_F(ElementsUploadDataStreamTest, MultipleInitAsync) {
TestCompletionCallback test_callback;
// Prepare data.
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
element_readers_.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
std::string expected_data(kTestData, kTestData + kTestDataSize);
expected_data += expected_data;
@@ -645,13 +651,13 @@ TEST_F(ElementsUploadDataStreamTest, InitToReset) {
base::WriteFile(temp_file_path, kTestData, kTestDataSize));
// Prepare data.
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
element_readers_.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
expected_data.insert(expected_data.end(), kTestData,
@@ -701,13 +707,13 @@ TEST_F(ElementsUploadDataStreamTest, InitDuringAsyncInit) {
base::WriteFile(temp_file_path, kTestData, kTestDataSize));
// Prepare data.
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
element_readers_.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
expected_data.insert(expected_data.end(), kTestData,
@@ -747,13 +753,13 @@ TEST_F(ElementsUploadDataStreamTest, InitDuringAsyncRead) {
base::WriteFile(temp_file_path, kTestData, kTestDataSize));
// Prepare data.
- element_readers_.push_back(new UploadBytesElementReader(
- kTestData, kTestDataSize));
element_readers_.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
+ make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+ element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
scoped_ptr<UploadDataStream> stream(
- new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers_), 0));
std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
expected_data.insert(expected_data.end(), kTestData,
diff --git a/chromium/net/base/escape.h b/chromium/net/base/escape.h
index 9c500b09896..c31dcf9aa22 100644
--- a/chromium/net/base/escape.h
+++ b/chromium/net/base/escape.h
@@ -5,10 +5,11 @@
#ifndef NET_BASE_ESCAPE_H_
#define NET_BASE_ESCAPE_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "base/strings/utf_offset_string_conversions.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/escape_unittest.cc b/chromium/net/base/escape_unittest.cc
index b6f022918ae..cec7f32d1e5 100644
--- a/chromium/net/base/escape_unittest.cc
+++ b/chromium/net/base/escape_unittest.cc
@@ -7,7 +7,6 @@
#include "net/base/escape.h"
-#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chromium/net/base/expiring_cache.h b/chromium/net/base/expiring_cache.h
index 3fbde6594ff..a22497b76e5 100644
--- a/chromium/net/base/expiring_cache.h
+++ b/chromium/net/base/expiring_cache.h
@@ -5,11 +5,13 @@
#ifndef NET_BASE_EXPIRING_CACHE_H_
#define NET_BASE_EXPIRING_CACHE_H_
+#include <stddef.h>
+
#include <map>
#include <utility>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/time/time.h"
namespace net {
diff --git a/chromium/net/base/file_stream.cc b/chromium/net/base/file_stream.cc
index 81e14ae5482..6826e808971 100644
--- a/chromium/net/base/file_stream.cc
+++ b/chromium/net/base/file_stream.cc
@@ -4,6 +4,8 @@
#include "net/base/file_stream.h"
+#include <utility>
+
#include "base/profiler/scoped_tracker.h"
#include "net/base/file_stream_context.h"
#include "net/base/net_errors.h"
@@ -16,8 +18,7 @@ FileStream::FileStream(const scoped_refptr<base::TaskRunner>& task_runner)
FileStream::FileStream(base::File file,
const scoped_refptr<base::TaskRunner>& task_runner)
- : context_(new Context(file.Pass(), task_runner)) {
-}
+ : context_(new Context(std::move(file), task_runner)) {}
FileStream::~FileStream() {
context_.release()->Orphan();
diff --git a/chromium/net/base/file_stream.h b/chromium/net/base/file_stream.h
index f0408e45b4a..64a34354808 100644
--- a/chromium/net/base/file_stream.h
+++ b/chromium/net/base/file_stream.h
@@ -10,7 +10,10 @@
#ifndef NET_BASE_FILE_STREAM_H_
#define NET_BASE_FILE_STREAM_H_
+#include <stdint.h>
+
#include "base/files/file.h"
+#include "base/macros.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/file_stream_context.cc b/chromium/net/base/file_stream_context.cc
index 3ddf4bbf508..7da28a99f2e 100644
--- a/chromium/net/base/file_stream_context.cc
+++ b/chromium/net/base/file_stream_context.cc
@@ -4,6 +4,8 @@
#include "net/base/file_stream_context.h"
+#include <utility>
+
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/profiler/scoped_tracker.h"
@@ -50,21 +52,15 @@ FileStream::Context::OpenResult::OpenResult() {
FileStream::Context::OpenResult::OpenResult(base::File file,
IOResult error_code)
- : file(file.Pass()),
- error_code(error_code) {
-}
+ : file(std::move(file)), error_code(error_code) {}
-FileStream::Context::OpenResult::OpenResult(RValue other)
- : file(other.object->file.Pass()),
- error_code(other.object->error_code) {
-}
+FileStream::Context::OpenResult::OpenResult(OpenResult&& other)
+ : file(std::move(other.file)), error_code(other.error_code) {}
FileStream::Context::OpenResult& FileStream::Context::OpenResult::operator=(
- RValue other) {
- if (this != other.object) {
- file = other.object->file.Pass();
- error_code = other.object->error_code;
- }
+ OpenResult&& other) {
+ file = std::move(other.file);
+ error_code = other.error_code;
return *this;
}
@@ -176,7 +172,7 @@ FileStream::Context::OpenResult FileStream::Context::OpenFileImpl(
return OpenResult(base::File(),
IOResult::FromOSError(logging::GetLastSystemErrorCode()));
- return OpenResult(file.Pass(), IOResult(OK, 0));
+ return OpenResult(std::move(file), IOResult(OK, 0));
}
FileStream::Context::IOResult FileStream::Context::CloseFileImpl() {
@@ -193,7 +189,7 @@ FileStream::Context::IOResult FileStream::Context::FlushFileImpl() {
void FileStream::Context::OnOpenCompleted(const CompletionCallback& callback,
OpenResult open_result) {
- file_ = open_result.file.Pass();
+ file_ = std::move(open_result.file);
if (file_.IsValid() && !orphaned_)
OnFileOpened();
diff --git a/chromium/net/base/file_stream_context.h b/chromium/net/base/file_stream_context.h
index c1846c460d3..32703d808ce 100644
--- a/chromium/net/base/file_stream_context.h
+++ b/chromium/net/base/file_stream_context.h
@@ -27,7 +27,10 @@
#ifndef NET_BASE_FILE_STREAM_CONTEXT_H_
#define NET_BASE_FILE_STREAM_CONTEXT_H_
+#include <stdint.h>
+
#include "base/files/file.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/move.h"
@@ -110,13 +113,12 @@ class FileStream::Context {
};
struct OpenResult {
- MOVE_ONLY_TYPE_FOR_CPP_03(OpenResult, RValue)
+ MOVE_ONLY_TYPE_FOR_CPP_03(OpenResult)
public:
OpenResult();
OpenResult(base::File file, IOResult error_code);
- // C++03 move emulation of this type.
- OpenResult(RValue other);
- OpenResult& operator=(RValue other);
+ OpenResult(OpenResult&& other);
+ OpenResult& operator=(OpenResult&& other);
base::File file;
IOResult error_code;
diff --git a/chromium/net/base/file_stream_context_posix.cc b/chromium/net/base/file_stream_context_posix.cc
index 9991c69c986..af98c7825fe 100644
--- a/chromium/net/base/file_stream_context_posix.cc
+++ b/chromium/net/base/file_stream_context_posix.cc
@@ -5,8 +5,8 @@
#include "net/base/file_stream_context.h"
#include <errno.h>
+#include <utility>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
@@ -30,11 +30,10 @@ FileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
FileStream::Context::Context(base::File file,
const scoped_refptr<base::TaskRunner>& task_runner)
- : file_(file.Pass()),
+ : file_(std::move(file)),
async_in_progress_(false),
orphaned_(false),
- task_runner_(task_runner) {
-}
+ task_runner_(task_runner) {}
FileStream::Context::~Context() {
}
diff --git a/chromium/net/base/file_stream_unittest.cc b/chromium/net/base/file_stream_unittest.cc
index d1985a8ace5..a67a91cae1d 100644
--- a/chromium/net/base/file_stream_unittest.cc
+++ b/chromium/net/base/file_stream_unittest.cc
@@ -4,18 +4,21 @@
#include "net/base/file_stream.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/sequenced_worker_pool_owner.h"
#include "base/test/test_timeouts.h"
#include "base/thread_task_runner_handle.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -116,7 +119,7 @@ TEST_F(FileStreamTest, UseFileHandle) {
// Seek to the beginning of the file and read.
scoped_ptr<FileStream> read_stream(
- new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
+ new FileStream(std::move(file), base::ThreadTaskRunnerHandle::Get()));
ASSERT_EQ(ERR_IO_PENDING, read_stream->Seek(0, callback64.callback()));
ASSERT_EQ(0, callback64.WaitForResult());
// Read into buffer and compare.
@@ -134,7 +137,7 @@ TEST_F(FileStreamTest, UseFileHandle) {
file.Initialize(temp_file_path(), flags);
scoped_ptr<FileStream> write_stream(
- new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
+ new FileStream(std::move(file), base::ThreadTaskRunnerHandle::Get()));
ASSERT_EQ(ERR_IO_PENDING, write_stream->Seek(0, callback64.callback()));
ASSERT_EQ(0, callback64.WaitForResult());
scoped_refptr<IOBufferWithSize> write_buffer = CreateTestDataBuffer();
@@ -557,7 +560,7 @@ class TestWriteReadCompletionCallback {
result_ = *total_bytes_written_;
have_result_ = true;
if (waiting_for_result_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
int result_;
@@ -665,7 +668,7 @@ class TestWriteCloseCompletionCallback {
result_ = *total_bytes_written_;
have_result_ = true;
if (waiting_for_result_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
int result_;
@@ -714,11 +717,10 @@ TEST_F(FileStreamTest, WriteClose) {
}
TEST_F(FileStreamTest, OpenAndDelete) {
- scoped_refptr<base::SequencedWorkerPool> pool(
- new base::SequencedWorkerPool(1, "StreamTest"));
+ base::SequencedWorkerPoolOwner pool_owner(1, "StreamTest");
bool prev = base::ThreadRestrictions::SetIOAllowed(false);
- scoped_ptr<FileStream> stream(new FileStream(pool.get()));
+ scoped_ptr<FileStream> stream(new FileStream(pool_owner.pool()));
int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
base::File::FLAG_ASYNC;
TestCompletionCallback open_callback;
@@ -730,14 +732,12 @@ TEST_F(FileStreamTest, OpenAndDelete) {
stream.reset();
// Force an operation through the pool.
- scoped_ptr<FileStream> stream2(new FileStream(pool.get()));
+ scoped_ptr<FileStream> stream2(new FileStream(pool_owner.pool()));
TestCompletionCallback open_callback2;
rv = stream2->Open(temp_file_path(), flags, open_callback2.callback());
EXPECT_EQ(OK, open_callback2.GetResult(rv));
stream2.reset();
- pool->Shutdown();
-
// open_callback won't be called.
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(open_callback.have_result());
@@ -754,7 +754,7 @@ TEST_F(FileStreamTest, WriteError) {
ASSERT_TRUE(file.IsValid());
scoped_ptr<FileStream> stream(
- new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
+ new FileStream(std::move(file), base::ThreadTaskRunnerHandle::Get()));
scoped_refptr<IOBuffer> buf = new IOBuffer(1);
buf->data()[0] = 0;
@@ -779,7 +779,7 @@ TEST_F(FileStreamTest, ReadError) {
ASSERT_TRUE(file.IsValid());
scoped_ptr<FileStream> stream(
- new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
+ new FileStream(std::move(file), base::ThreadTaskRunnerHandle::Get()));
scoped_refptr<IOBuffer> buf = new IOBuffer(1);
TestCompletionCallback callback;
diff --git a/chromium/net/base/filename_util_internal.cc b/chromium/net/base/filename_util_internal.cc
index 8b57d7921b6..2f038ad4028 100644
--- a/chromium/net/base/filename_util_internal.cc
+++ b/chromium/net/base/filename_util_internal.cc
@@ -6,6 +6,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
@@ -19,6 +20,61 @@
namespace net {
+namespace {
+
+// Examines the current extension in |file_name| and tries to return the correct
+// extension the file should actually be using. Used by EnsureSafeExtension.
+// All other code should use EnsureSafeExtension, as it includes additional
+// safety checks.
+base::FilePath::StringType GetCorrectedExtensionUnsafe(
+ const std::string& mime_type,
+ bool ignore_extension,
+ const base::FilePath& file_name) {
+ // See if the file name already contains an extension.
+ base::FilePath::StringType extension = file_name.Extension();
+ if (!extension.empty())
+ extension.erase(extension.begin()); // Erase preceding '.'.
+
+ // Nothing to do if there's no mime type.
+ if (mime_type.empty())
+ return extension;
+
+ // Nothing to do there's an extension, unless |ignore_extension| is true.
+ if (!extension.empty() && !ignore_extension)
+ return extension;
+
+ // Don't do anything if there's not a preferred extension for the mime
+ // type.
+ base::FilePath::StringType preferred_mime_extension;
+ if (!GetPreferredExtensionForMimeType(mime_type, &preferred_mime_extension))
+ return extension;
+
+ // If the existing extension is in the list of valid extensions for the
+ // given type, use it. This avoids doing things like pointlessly renaming
+ // "foo.jpg" to "foo.jpeg".
+ std::vector<base::FilePath::StringType> all_mime_extensions;
+ GetExtensionsForMimeType(mime_type, &all_mime_extensions);
+ if (ContainsValue(all_mime_extensions, extension))
+ return extension;
+
+ // Get the "final" extension. In most cases, this is the same as the
+ // |extension|, but in cases like "foo.tar.gz", it's "gz" while
+ // |extension| is "tar.gz".
+ base::FilePath::StringType final_extension = file_name.FinalExtension();
+ // Erase preceding '.'.
+ if (!final_extension.empty())
+ final_extension.erase(final_extension.begin());
+
+ // If there's a double extension, and the second extension is in the
+ // list of valid extensions for the given type, keep the double extension.
+ // This avoids renaming things like "foo.tar.gz" to "foo.gz".
+ if (ContainsValue(all_mime_extensions, final_extension))
+ return extension;
+ return preferred_mime_extension;
+}
+
+} // namespace
+
void SanitizeGeneratedFileName(base::FilePath::StringType* filename,
bool replace_trailing) {
const base::FilePath::CharType kReplace[] = FILE_PATH_LITERAL("-");
@@ -30,7 +86,12 @@ void SanitizeGeneratedFileName(base::FilePath::StringType* filename,
size_t length = filename->size();
size_t pos = filename->find_last_not_of(FILE_PATH_LITERAL(" ."));
filename->resize((pos == std::string::npos) ? 0 : (pos + 1));
+#if defined(OS_WIN)
base::TrimWhitespace(*filename, base::TRIM_TRAILING, filename);
+#else
+ base::TrimWhitespaceASCII(*filename, base::TRIM_TRAILING, filename);
+#endif
+
if (filename->empty())
return;
size_t trimmed = length - filename->size();
@@ -123,37 +184,19 @@ bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
void EnsureSafeExtension(const std::string& mime_type,
bool ignore_extension,
base::FilePath* file_name) {
- // See if our file name already contains an extension.
- base::FilePath::StringType extension = file_name->Extension();
- if (!extension.empty())
- extension.erase(extension.begin()); // Erase preceding '.'.
-
- if ((ignore_extension || extension.empty()) && !mime_type.empty()) {
- base::FilePath::StringType preferred_mime_extension;
- std::vector<base::FilePath::StringType> all_mime_extensions;
- GetPreferredExtensionForMimeType(mime_type, &preferred_mime_extension);
- GetExtensionsForMimeType(mime_type, &all_mime_extensions);
- // If the existing extension is in the list of valid extensions for the
- // given type, use it. This avoids doing things like pointlessly renaming
- // "foo.jpg" to "foo.jpeg".
- if (std::find(all_mime_extensions.begin(),
- all_mime_extensions.end(),
- extension) != all_mime_extensions.end()) {
- // leave |extension| alone
- } else if (!preferred_mime_extension.empty()) {
- extension = preferred_mime_extension;
- }
- }
+ DCHECK(file_name);
+ base::FilePath::StringType extension =
+ GetCorrectedExtensionUnsafe(mime_type, ignore_extension, *file_name);
#if defined(OS_WIN)
- static const base::FilePath::CharType default_extension[] =
+ const base::FilePath::CharType kDefaultExtension[] =
FILE_PATH_LITERAL("download");
// Rename shell-integrated extensions.
// TODO(asanka): Consider stripping out the bad extension and replacing it
// with the preferred extension for the MIME type if one is available.
if (IsShellIntegratedExtension(extension))
- extension.assign(default_extension);
+ extension = kDefaultExtension;
#endif
*file_name = file_name->ReplaceExtension(extension);
diff --git a/chromium/net/base/filename_util_unittest.cc b/chromium/net/base/filename_util_unittest.cc
index 453106c6aad..5e3fb7e1c9f 100644
--- a/chromium/net/base/filename_util_unittest.cc
+++ b/chromium/net/base/filename_util_unittest.cc
@@ -792,407 +792,150 @@ TEST(FilenameUtilTest, GenerateFileName) {
// a correct extension should be added if necessary.
const GenerateFilenameCase generation_tests[] = {
// Dotfiles. Ensures preceeding period(s) stripped.
- {__LINE__,
- "http://www.google.com/.test.html",
- "",
- "",
- "",
- "",
- L"",
+ {__LINE__, "http://www.google.com/.test.html", "", "", "", "", L"",
L"test.html"},
{__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__, "http://www.evil.com/my_download.txt",
+ "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",
+ __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"},
{// 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__, "http://www.evil.com/my_download.txt",
+ "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",
+ __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__, "http://www.truncated.com/path/", "", "", "", "text/plain",
+ L"download", L"download" TXT_EXT},
{// 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__, "http://www.evil.com/get/malware/here",
+ "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://blah.google.com/misc/2.avi", "", "", "",
+ "video/x-msvideo", L"download", L"2.avi"},
{// 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"},
+ __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"},
{// 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"},
+ __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"},
+ {__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",
+ {__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-"},
+ {__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",
+ {__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__, "http://www.evil.com/trailing.", "filename=trailing.", "", "",
+ "text/plain", L"download",
#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",
- L"download",
- L"download"},
+ {__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",
+ 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"},
+ __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"},
// Reserved words on Windows
- {__LINE__,
- "http://www.goodguy.com/COM1",
- "filename=COM1",
- "",
- "",
- "application/foo-bar",
- L"download",
+ {__LINE__, "http://www.goodguy.com/COM1", "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__, "http://www.goodguy.com/COM4.txt", "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__, "http://www.goodguy.com/lpt1.TXT", "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__, "http://www.goodguy.com/clock$.txt", "filename=clock$.txt", "",
+ "", "text/plain", L"download",
#if defined(OS_WIN)
L"_clock$.txt"
#else
@@ -1200,46 +943,26 @@ 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__, "http://www.goodguy.com/blah$.txt", "filename=clock$.txt", "",
+ "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",
+ {__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",
#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",
+ {__LINE__, "http://www.badguy.com/Setup.exe.local",
+ "filename=Setup.exe.local.local", "", "", "application/foo-bar",
L"download",
#if defined(OS_WIN)
L"Setup.exe.local.download"
@@ -1247,159 +970,79 @@ TEST(FilenameUtilTest, GenerateFileName) {
L"Setup.exe.local.local"
#endif
},
- {__LINE__,
- "http://www.badguy.com/Setup.exe.lnk",
- "filename=Setup.exe.lnk",
- "",
- "",
- "application/foo-bar",
- L"download",
+ {__LINE__, "http://www.badguy.com/Setup.exe.lnk", "filename=Setup.exe.lnk",
+ "", "", "application/foo-bar", 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__, "http://www.badguy.com/Desktop.ini", "filename=Desktop.ini", "",
+ "", "application/foo-bar", 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__, "http://www.badguy.com/Thumbs.db", "filename=Thumbs.db", "", "",
+ "application/foo-bar", 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"},
+ {__LINE__, "http://www.hotmail.com", "filename=source.jpg", "", "",
+ "application/x-javascript", L"download", L"source.jpg"},
{// http://crbug.com/5772.
- __LINE__,
- "http://www.example.com/foo.tar.gz",
- "",
- "",
- "",
- "application/x-tar",
- L"download",
- L"foo.tar.gz"},
+ __LINE__, "http://www.example.com/foo.tar.gz", "", "", "",
+ "application/x-tar", L"download", L"foo.tar.gz"},
{// http://crbug.com/52250.
- __LINE__,
- "http://www.example.com/foo.tgz",
- "",
- "",
- "",
- "application/x-tar",
- L"download",
- L"foo.tgz"},
+ __LINE__, "http://www.example.com/foo.tgz", "", "", "",
+ "application/x-tar", L"download", L"foo.tgz"},
{// http://crbug.com/7337.
- __LINE__,
- "http://maged.lordaeron.org/blank.reg",
- "",
- "",
- "",
- "text/x-registry",
- L"download",
- L"blank.reg"},
- {__LINE__,
- "http://www.example.com/bar.tar",
- "",
- "",
- "",
- "application/x-tar",
- L"download",
- L"bar.tar"},
- {__LINE__,
- "http://www.example.com/bar.bogus",
- "",
- "",
- "",
- "application/x-tar",
- L"download",
- L"bar.bogus"},
+ __LINE__, "http://maged.lordaeron.org/blank.reg", "", "", "",
+ "text/x-registry", L"download", L"blank.reg"},
+ {__LINE__, "http://www.example.com/bar.tar", "", "", "",
+ "application/x-tar", L"download", L"bar.tar"},
+ {__LINE__, "http://www.example.com/bar.bogus", "", "", "",
+ "application/x-tar", L"download", L"bar.bogus"},
{// http://crbug.com/20337
- __LINE__,
- "http://www.example.com/.download.txt",
- "filename=.download.txt",
- "",
- "",
- "text/plain",
- L"-download",
- L"download.txt"},
+ __LINE__, "http://www.example.com/.download.txt", "filename=.download.txt",
+ "", "", "text/plain", L"-download", L"download.txt"},
{// http://crbug.com/56855.
- __LINE__,
- "http://www.example.com/bar.sh",
- "",
- "",
- "",
- "application/x-sh",
- L"download",
- L"bar.sh"},
+ __LINE__, "http://www.example.com/bar.sh", "", "", "", "application/x-sh",
+ 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},
+ __LINE__, "http://www.example.com/npdf.php?fn=foobar.pdf", "", "", "",
+ "text/plain", L"download", L"npdf" TXT_EXT},
{// 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"},
+ __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},
- {__LINE__,
- "http://www.example.com/image.aspx?id=blargh",
- "",
- "",
- " .foo",
- "",
- L"download",
- L"-.foo"},
+ __LINE__, "http://www.example.com/image.aspx?id=blargh", "", "", "",
+ "image/jpeg", L"download", L"image" JPEG_EXT},
+ {__LINE__, "http://www.example.com/image.aspx?id=blargh", "", "", " .foo",
+ "", L"download", L"-.foo"},
+
+ // Note that the next 4 tests will not fail on all platforms on regression.
+ // They only fail if application/[x-]gzip has a default extension, which
+ // can vary across platforms (And even by OS install).
+ {__LINE__, "http://www.example.com/goat.tar.gz?wearing_hat=true", "", "",
+ "", "application/gzip", L"", L"goat.tar.gz"},
+ {__LINE__, "http://www.example.com/goat.tar.gz?wearing_hat=true", "", "",
+ "", "application/x-gzip", L"", L"goat.tar.gz"},
+ {__LINE__, "http://www.example.com/goat.tgz?wearing_hat=true", "", "", "",
+ "application/gzip", L"", L"goat.tgz"},
+ {__LINE__, "http://www.example.com/goat.tgz?wearing_hat=true", "", "", "",
+ "application/x-gzip", L"", L"goat.tgz"},
+
#if defined(OS_CHROMEOS)
{// http://crosbug.com/26028
- __LINE__,
- "http://www.example.com/fooa%cc%88.txt",
- "",
- "",
- "",
- "image/jpeg",
- L"foo\xe4",
- L"foo\xe4.txt"},
+ __LINE__, "http://www.example.com/fooa%cc%88.txt", "", "", "",
+ "image/jpeg", L"foo\xe4", L"foo\xe4.txt"},
#endif
};
diff --git a/chromium/net/base/hash_value.cc b/chromium/net/base/hash_value.cc
index 2a751cd2192..9a91a93b4be 100644
--- a/chromium/net/base/hash_value.cc
+++ b/chromium/net/base/hash_value.cc
@@ -9,6 +9,7 @@
#include "base/sha1.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "crypto/sha2.h"
namespace net {
@@ -31,6 +32,15 @@ bool SHA256HashValue::Equals(const SHA256HashValue& other) const {
return memcmp(data, other.data, sizeof(data)) == 0;
}
+HashValue::HashValue(const SHA1HashValue& hash) : HashValue(HASH_VALUE_SHA1) {
+ fingerprint.sha1 = hash;
+}
+
+HashValue::HashValue(const SHA256HashValue& hash)
+ : HashValue(HASH_VALUE_SHA256) {
+ fingerprint.sha256 = hash;
+}
+
bool HashValue::Equals(const HashValue& other) const {
if (tag != other.tag)
return false;
@@ -111,12 +121,12 @@ const unsigned char* HashValue::data() const {
}
}
-bool IsSHA1HashInSortedArray(const SHA1HashValue& hash,
- const uint8_t* array,
- size_t array_byte_len) {
- DCHECK_EQ(0u, array_byte_len % base::kSHA1Length);
- const size_t arraylen = array_byte_len / base::kSHA1Length;
- return NULL != bsearch(hash.data, array, arraylen, base::kSHA1Length,
+bool IsSHA256HashInSortedArray(const SHA256HashValue& hash,
+ const uint8_t* array,
+ size_t array_byte_len) {
+ DCHECK_EQ(0u, array_byte_len % crypto::kSHA256Length);
+ const size_t arraylen = array_byte_len / crypto::kSHA256Length;
+ return NULL != bsearch(hash.data, array, arraylen, crypto::kSHA256Length,
CompareSHA1Hashes);
}
diff --git a/chromium/net/base/hash_value.h b/chromium/net/base/hash_value.h
index a9e0b63a831..a0e1d84d400 100644
--- a/chromium/net/base/hash_value.h
+++ b/chromium/net/base/hash_value.h
@@ -5,12 +5,13 @@
#ifndef NET_BASE_HASH_VALUE_H_
#define NET_BASE_HASH_VALUE_H_
+#include <stddef.h>
+#include <stdint.h>
#include <string.h>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
@@ -36,6 +37,8 @@ enum HashValueTag {
class NET_EXPORT HashValue {
public:
+ explicit HashValue(const SHA1HashValue& hash);
+ explicit HashValue(const SHA256HashValue& hash);
explicit HashValue(HashValueTag tag) : tag(tag) {}
HashValue() : tag(HASH_VALUE_SHA1) {}
@@ -110,12 +113,11 @@ class HashValuesEqual {
const HashValue& fingerprint_;
};
-
-// IsSHA1HashInSortedArray returns true iff |hash| is in |array|, a sorted
-// array of SHA1 hashes.
-bool IsSHA1HashInSortedArray(const SHA1HashValue& hash,
- const uint8_t* array,
- size_t array_byte_len);
+// IsSHA256HashInSortedArray returns true iff |hash| is in |array|, a sorted
+// array of SHA256 hashes.
+bool IsSHA256HashInSortedArray(const SHA256HashValue& hash,
+ const uint8_t* array,
+ size_t array_byte_len);
} // namespace net
diff --git a/chromium/net/base/host_mapping_rules.h b/chromium/net/base/host_mapping_rules.h
index e1d2cd29d0a..8c7bc0bf92e 100644
--- a/chromium/net/base/host_mapping_rules.h
+++ b/chromium/net/base/host_mapping_rules.h
@@ -7,7 +7,8 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
+
+#include "base/macros.h"
#include "net/base/net_export.h"
namespace net {
diff --git a/chromium/net/base/host_port_pair.h b/chromium/net/base/host_port_pair.h
index 9b1df5697b0..8fa9b3e143a 100644
--- a/chromium/net/base/host_port_pair.h
+++ b/chromium/net/base/host_port_pair.h
@@ -5,8 +5,11 @@
#ifndef NET_BASE_HOST_PORT_PAIR_H_
#define NET_BASE_HOST_PORT_PAIR_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include <tuple>
+
#include "net/base/net_export.h"
class GURL;
@@ -34,9 +37,7 @@ class NET_EXPORT HostPortPair {
// TODO(willchan): Define a functor instead.
// Comparator function so this can be placed in a std::map.
bool operator<(const HostPortPair& other) const {
- if (port_ != other.port_)
- return port_ < other.port_;
- return host_ < other.host_;
+ return std::tie(port_, host_) < std::tie(other.port_, other.host_);
}
// Equality test of contents. (Probably another violation of style guide).
diff --git a/chromium/net/base/int128.cc b/chromium/net/base/int128.cc
index 94275eb6ecb..0657ad98494 100644
--- a/chromium/net/base/int128.cc
+++ b/chromium/net/base/int128.cc
@@ -2,14 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <iostream>
-#include "base/basictypes.h"
#include "net/base/int128.h"
-const uint128_pod kuint128max = {
- static_cast<uint64>(0xFFFFFFFFFFFFFFFFULL),
- static_cast<uint64>(0xFFFFFFFFFFFFFFFFULL)
-};
+#include <ostream>
+
+const uint128_pod kuint128max = {static_cast<uint64_t>(0xFFFFFFFFFFFFFFFFULL),
+ static_cast<uint64_t>(0xFFFFFFFFFFFFFFFFULL)};
std::ostream& operator<<(std::ostream& o, const uint128& b) {
return (o << b.hi_ << "::" << b.lo_);
diff --git a/chromium/net/base/int128.h b/chromium/net/base/int128.h
index b17801be575..57501fb8c83 100644
--- a/chromium/net/base/int128.h
+++ b/chromium/net/base/int128.h
@@ -5,24 +5,26 @@
#ifndef NET_BASE_INT128_H_
#define NET_BASE_INT128_H_
+#include <stdint.h>
+
#include <iosfwd>
-#include "base/basictypes.h"
+
#include "net/base/net_export.h"
struct uint128_pod;
// An unsigned 128-bit integer type. Thread-compatible.
class uint128 {
-public:
+ public:
uint128(); // Sets to 0, but don't trust on this behavior.
- uint128(uint64 top, uint64 bottom);
+ uint128(uint64_t top, uint64_t bottom);
uint128(int bottom);
- uint128(uint32 bottom); // Top 96 bits = 0
- uint128(uint64 bottom); // hi_ = 0
+ uint128(uint32_t bottom); // Top 96 bits = 0
+ uint128(uint64_t bottom); // hi_ = 0
uint128(const uint128 &val);
uint128(const uint128_pod &val);
- void Initialize(uint64 top, uint64 bottom);
+ void Initialize(uint64_t top, uint64_t bottom);
uint128& operator=(const uint128& b);
@@ -41,23 +43,23 @@ public:
uint128& operator++();
uint128& operator--();
- friend uint64 Uint128Low64(const uint128& v);
- friend uint64 Uint128High64(const uint128& v);
+ friend uint64_t Uint128Low64(const uint128& v);
+ friend uint64_t Uint128High64(const uint128& v);
// We add "std::" to avoid including all of port.h.
friend NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& o,
const uint128& b);
-private:
+ private:
// Little-endian memory order optimizations can benefit from
// having lo_ first, hi_ last.
// See util/endian/endian.h and Load128/Store128 for storing a uint128.
- uint64 lo_;
- uint64 hi_;
+ uint64_t lo_;
+ uint64_t hi_;
// Not implemented, just declared for catching automatic type conversions.
- uint128(uint8);
- uint128(uint16);
+ uint128(uint8_t);
+ uint128(uint16_t);
uint128(float v);
uint128(double v);
};
@@ -70,8 +72,8 @@ struct uint128_pod {
// of static instances, which is the primary reason for this struct in the
// first place. This does not seem to defeat any optimizations wrt
// operations involving this struct.
- uint64 hi;
- uint64 lo;
+ uint64_t hi;
+ uint64_t lo;
};
NET_EXPORT_PRIVATE extern const uint128_pod kuint128max;
@@ -83,8 +85,12 @@ NET_EXPORT_PRIVATE extern std::ostream& operator<<(std::ostream& o,
// Methods to access low and high pieces of 128-bit value.
// Defined externally from uint128 to facilitate conversion
// to native 128-bit types when compilers support them.
-inline uint64 Uint128Low64(const uint128& v) { return v.lo_; }
-inline uint64 Uint128High64(const uint128& v) { return v.hi_; }
+inline uint64_t Uint128Low64(const uint128& v) {
+ return v.lo_;
+}
+inline uint64_t Uint128High64(const uint128& v) {
+ return v.hi_;
+}
// TODO: perhaps it would be nice to have int128, a signed 128-bit type?
@@ -105,17 +111,18 @@ inline uint128& uint128::operator=(const uint128& b) {
}
inline uint128::uint128(): lo_(0), hi_(0) { }
-inline uint128::uint128(uint64 top, uint64 bottom) : lo_(bottom), hi_(top) { }
+inline uint128::uint128(uint64_t top, uint64_t bottom)
+ : lo_(bottom), hi_(top) {}
inline uint128::uint128(const uint128 &v) : lo_(v.lo_), hi_(v.hi_) { }
inline uint128::uint128(const uint128_pod &v) : lo_(v.lo), hi_(v.hi) { }
-inline uint128::uint128(uint64 bottom) : lo_(bottom), hi_(0) { }
-inline uint128::uint128(uint32 bottom) : lo_(bottom), hi_(0) { }
+inline uint128::uint128(uint64_t bottom) : lo_(bottom), hi_(0) {}
+inline uint128::uint128(uint32_t bottom) : lo_(bottom), hi_(0) {}
inline uint128::uint128(int bottom) : lo_(bottom), hi_(0) {
if (bottom < 0) {
--hi_;
}
}
-inline void uint128::Initialize(uint64 top, uint64 bottom) {
+inline void uint128::Initialize(uint64_t top, uint64_t bottom) {
hi_ = top;
lo_ = bottom;
}
@@ -139,9 +146,9 @@ CMP128(<=)
// Unary operators
inline uint128 operator-(const uint128& val) {
- const uint64 hi_flip = ~Uint128High64(val);
- const uint64 lo_flip = ~Uint128Low64(val);
- const uint64 lo_add = lo_flip + 1;
+ const uint64_t hi_flip = ~Uint128High64(val);
+ const uint64_t lo_flip = ~Uint128Low64(val);
+ const uint64_t lo_add = lo_flip + 1;
if (lo_add < lo_flip) {
return uint128(hi_flip + 1, lo_add);
}
@@ -186,14 +193,15 @@ LOGICASSIGN128(^=)
// Shift operators.
inline uint128 operator<<(const uint128& val, int amount) {
- // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ // uint64_t shifts of >= 64 are undefined, so we will need some
+ // special-casing.
if (amount < 64) {
if (amount == 0) {
return val;
}
- uint64 new_hi = (Uint128High64(val) << amount) |
- (Uint128Low64(val) >> (64 - amount));
- uint64 new_lo = Uint128Low64(val) << amount;
+ uint64_t new_hi =
+ (Uint128High64(val) << amount) | (Uint128Low64(val) >> (64 - amount));
+ uint64_t new_lo = Uint128Low64(val) << amount;
return uint128(new_hi, new_lo);
} else if (amount < 128) {
return uint128(Uint128Low64(val) << (amount - 64), 0);
@@ -203,14 +211,15 @@ inline uint128 operator<<(const uint128& val, int amount) {
}
inline uint128 operator>>(const uint128& val, int amount) {
- // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ // uint64_t shifts of >= 64 are undefined, so we will need some
+ // special-casing.
if (amount < 64) {
if (amount == 0) {
return val;
}
- uint64 new_hi = Uint128High64(val) >> amount;
- uint64 new_lo = (Uint128Low64(val) >> amount) |
- (Uint128High64(val) << (64 - amount));
+ uint64_t new_hi = Uint128High64(val) >> amount;
+ uint64_t new_lo =
+ (Uint128Low64(val) >> amount) | (Uint128High64(val) << (64 - amount));
return uint128(new_hi, new_lo);
} else if (amount < 128) {
return uint128(0, Uint128High64(val) >> (amount - 64));
@@ -220,7 +229,8 @@ inline uint128 operator>>(const uint128& val, int amount) {
}
inline uint128& uint128::operator<<=(int amount) {
- // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ // uint64_t shifts of >= 64 are undefined, so we will need some
+ // special-casing.
if (amount < 64) {
if (amount != 0) {
hi_ = (hi_ << amount) | (lo_ >> (64 - amount));
@@ -237,7 +247,8 @@ inline uint128& uint128::operator<<=(int amount) {
}
inline uint128& uint128::operator>>=(int amount) {
- // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ // uint64_t shifts of >= 64 are undefined, so we will need some
+ // special-casing.
if (amount < 64) {
if (amount != 0) {
lo_ = (lo_ >> amount) | (hi_ << (64 - amount));
@@ -267,7 +278,7 @@ inline uint128 operator*(const uint128& lhs, const uint128& rhs) {
inline uint128& uint128::operator+=(const uint128& b) {
hi_ += b.hi_;
- uint64 lolo = lo_ + b.lo_;
+ uint64_t lolo = lo_ + b.lo_;
if (lolo < lo_)
++hi_;
lo_ = lolo;
@@ -283,19 +294,19 @@ inline uint128& uint128::operator-=(const uint128& b) {
}
inline uint128& uint128::operator*=(const uint128& b) {
- uint64 a96 = hi_ >> 32;
- uint64 a64 = hi_ & 0xffffffffu;
- uint64 a32 = lo_ >> 32;
- uint64 a00 = lo_ & 0xffffffffu;
- uint64 b96 = b.hi_ >> 32;
- uint64 b64 = b.hi_ & 0xffffffffu;
- uint64 b32 = b.lo_ >> 32;
- uint64 b00 = b.lo_ & 0xffffffffu;
+ uint64_t a96 = hi_ >> 32;
+ uint64_t a64 = hi_ & 0xffffffffu;
+ uint64_t a32 = lo_ >> 32;
+ uint64_t a00 = lo_ & 0xffffffffu;
+ uint64_t b96 = b.hi_ >> 32;
+ uint64_t b64 = b.hi_ & 0xffffffffu;
+ uint64_t b32 = b.lo_ >> 32;
+ uint64_t b00 = b.lo_ & 0xffffffffu;
// multiply [a96 .. a00] x [b96 .. b00]
// terms higher than c96 disappear off the high side
// terms c96 and c64 are safe to ignore carry bit
- uint64 c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
- uint64 c64 = a64 * b00 + a32 * b32 + a00 * b64;
+ uint64_t c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
+ uint64_t c64 = a64 * b00 + a32 * b32 + a00 * b64;
this->hi_ = (c96 << 32) + c64;
this->lo_ = 0;
// add terms after this one at a time to capture carry
diff --git a/chromium/net/base/int128_unittest.cc b/chromium/net/base/int128_unittest.cc
index 957038bffd3..40e01c95825 100644
--- a/chromium/net/base/int128_unittest.cc
+++ b/chromium/net/base/int128_unittest.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "base/logging.h"
#include "net/base/int128.h"
#include "testing/gtest/include/gtest/gtest.h"
-
TEST(Int128, AllTests) {
uint128 zero(0);
uint128 one(1);
@@ -19,7 +21,7 @@ TEST(Int128, AllTests) {
uint128 bigger(2001, 1);
uint128 biggest(kuint128max);
uint128 high_low(1, 0);
- uint128 low_high(0, kuint64max);
+ uint128 low_high(0, std::numeric_limits<uint64_t>::max());
EXPECT_LT(one, two);
EXPECT_GT(two, one);
EXPECT_LT(one, big);
@@ -58,8 +60,8 @@ TEST(Int128, AllTests) {
EXPECT_EQ(zero, (one >> 80) << 80);
EXPECT_EQ(zero, big >> 128);
EXPECT_EQ(zero, big << 128);
- EXPECT_EQ(Uint128High64(biggest), kuint64max);
- EXPECT_EQ(Uint128Low64(biggest), kuint64max);
+ EXPECT_EQ(Uint128High64(biggest), std::numeric_limits<uint64_t>::max());
+ EXPECT_EQ(Uint128Low64(biggest), std::numeric_limits<uint64_t>::max());
EXPECT_EQ(zero + one, one);
EXPECT_EQ(one + one, two);
EXPECT_EQ(big_minus_one + one, big);
@@ -68,13 +70,14 @@ TEST(Int128, AllTests) {
EXPECT_EQ(zero - one, biggest);
EXPECT_EQ(big - big, zero);
EXPECT_EQ(big - one, big_minus_one);
- EXPECT_EQ(big + kuint64max, bigger);
+ EXPECT_EQ(big + std::numeric_limits<uint64_t>::max(), bigger);
EXPECT_EQ(biggest + 1, zero);
EXPECT_EQ(zero - 1, biggest);
EXPECT_EQ(high_low - one, low_high);
EXPECT_EQ(low_high + one, high_low);
EXPECT_EQ(Uint128High64((uint128(1) << 64) - 1), 0u);
- EXPECT_EQ(Uint128Low64((uint128(1) << 64) - 1), kuint64max);
+ EXPECT_EQ(Uint128Low64((uint128(1) << 64) - 1),
+ std::numeric_limits<uint64_t>::max());
EXPECT_TRUE(!!one);
EXPECT_TRUE(!!high_low);
EXPECT_FALSE(!!zero);
diff --git a/chromium/net/base/io_buffer.h b/chromium/net/base/io_buffer.h
index d157963e6f9..5e9ff21d6b8 100644
--- a/chromium/net/base/io_buffer.h
+++ b/chromium/net/base/io_buffer.h
@@ -5,6 +5,8 @@
#ifndef NET_BASE_IO_BUFFER_H_
#define NET_BASE_IO_BUFFER_H_
+#include <stddef.h>
+
#include <string>
#include "base/memory/ref_counted.h"
diff --git a/chromium/net/base/iovec.h b/chromium/net/base/iovec.h
index 8c709128ad7..a98ed212148 100644
--- a/chromium/net/base/iovec.h
+++ b/chromium/net/base/iovec.h
@@ -5,6 +5,8 @@
#ifndef NET_BASE_IOVEC_H_
#define NET_BASE_IOVEC_H_
+#include <stddef.h>
+
#if defined(OS_POSIX) && !defined(OS_NACL)
#include <sys/uio.h>
#else
diff --git a/chromium/net/base/ip_address.cc b/chromium/net/base/ip_address.cc
new file mode 100644
index 00000000000..060477ea7d4
--- /dev/null
+++ b/chromium/net/base/ip_address.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2015 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/ip_address.h"
+
+#include "net/base/ip_address_number.h"
+#include "url/gurl.h"
+#include "url/url_canon_ip.h"
+
+namespace net {
+
+const size_t IPAddress::kIPv4AddressSize = 4;
+const size_t IPAddress::kIPv6AddressSize = 16;
+
+IPAddress::IPAddress() {}
+
+IPAddress::IPAddress(const IPAddressNumber& address) : ip_address_(address) {}
+
+IPAddress::IPAddress(const uint8_t* address, size_t address_len)
+ : ip_address_(address, address + address_len) {}
+
+IPAddress::~IPAddress() {}
+
+bool IPAddress::IsIPv4() const {
+ return ip_address_.size() == kIPv4AddressSize;
+}
+
+bool IPAddress::IsIPv6() const {
+ return ip_address_.size() == kIPv6AddressSize;
+}
+
+bool IPAddress::IsValid() const {
+ return IsIPv4() || IsIPv6();
+}
+
+bool IPAddress::IsReserved() const {
+ return IsIPAddressReserved(ip_address_);
+}
+
+bool IPAddress::IsIPv4Mapped() const {
+ return net::IsIPv4Mapped(ip_address_);
+}
+
+std::string IPAddress::ToString() const {
+ return IPAddressToString(ip_address_);
+}
+
+// static
+bool IPAddress::FromIPLiteral(const base::StringPiece& ip_literal,
+ IPAddress* ip_address) {
+ std::vector<uint8_t> number;
+ if (!ParseIPLiteralToNumber(ip_literal, &number))
+ return false;
+
+ std::swap(number, ip_address->ip_address_);
+ return true;
+}
+
+bool IPAddress::operator==(const IPAddress& that) const {
+ return ip_address_ == that.ip_address_;
+}
+
+bool IPAddress::operator<(const IPAddress& that) const {
+ // Sort IPv4 before IPv6.
+ if (ip_address_.size() != that.ip_address_.size()) {
+ return ip_address_.size() < that.ip_address_.size();
+ }
+
+ return ip_address_ < that.ip_address_;
+}
+
+} // namespace net
diff --git a/chromium/net/base/ip_address.h b/chromium/net/base/ip_address.h
new file mode 100644
index 00000000000..69e6696fd6d
--- /dev/null
+++ b/chromium/net/base/ip_address.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2015 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_IP_ADDRESS_NET_H_
+#define NET_BASE_IP_ADDRESS_NET_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/strings/string_piece.h"
+#include "net/base/ip_address_number.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class NET_EXPORT IPAddress {
+ public:
+ static const size_t kIPv4AddressSize;
+ static const size_t kIPv6AddressSize;
+
+ // Creates a zero-sized, invalid address.
+ IPAddress();
+
+ // Creates an IP address from a deprecated IPAddressNumber.
+ explicit IPAddress(const IPAddressNumber& address);
+
+ // Copies the input address to |ip_address_|. The input is expected to be in
+ // network byte order.
+ template <size_t N>
+ IPAddress(const uint8_t(&address)[N])
+ : IPAddress(address, N) {}
+
+ // Copies the input address to |ip_address_| taking an additional length
+ // parameter. The input is expected to be in network byte order.
+ IPAddress(const uint8_t* address, size_t address_len);
+
+ ~IPAddress();
+
+ // Returns true if the IP has |kIPv4AddressSize| elements.
+ bool IsIPv4() const;
+
+ // Returns true if the IP has |kIPv6AddressSize| elements.
+ bool IsIPv6() const;
+
+ // Returns true if the IP is either an IPv4 or IPv6 address. This function
+ // only checks the address length.
+ bool IsValid() const;
+
+ // Returns true if an IP address hostname 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.
+ bool IsReserved() const;
+
+ // Returns true if |ip_address_| is an IPv4-mapped IPv6 address.
+ bool IsIPv4Mapped() const;
+
+ // The size in bytes of |ip_address_|.
+ size_t size() const { return ip_address_.size(); }
+
+ // Returns true if the IP is an empty, zero-sized (invalid) address.
+ bool empty() const { return ip_address_.empty(); }
+
+ // Returns the canonical string representation of an IP address.
+ // For example: "192.168.0.1" or "::1". The IP address must be
+ // valid, calling this on an invalid address will result in a crash.
+ std::string ToString() const;
+
+ // 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.
+ static bool FromIPLiteral(const base::StringPiece& ip_literal,
+ IPAddress* ip_address) WARN_UNUSED_RESULT;
+
+ // Returns the underlying byte vector.
+ const std::vector<uint8_t>& bytes() const { return ip_address_; };
+
+ bool operator==(const IPAddress& that) const;
+ bool operator<(const IPAddress& that) const;
+
+ private:
+ // IPv4 addresses will have length kIPv4AddressSize, whereas IPv6 address
+ // will have length kIPv6AddressSize.
+ std::vector<uint8_t> ip_address_;
+
+ // This class is copyable and assignable.
+};
+
+} // namespace net
+
+#endif // NET_BASE_IP_ADDRESS_NET_H_
diff --git a/chromium/net/base/ip_address_number.cc b/chromium/net/base/ip_address_number.cc
index 61af0679529..1e44b7d3b1e 100644
--- a/chromium/net/base/ip_address_number.cc
+++ b/chromium/net/base/ip_address_number.cc
@@ -4,6 +4,8 @@
#include "net/base/ip_address_number.h"
+#include <limits.h>
+
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
diff --git a/chromium/net/base/ip_address_number.h b/chromium/net/base/ip_address_number.h
index b1058758d9d..2671a24d653 100644
--- a/chromium/net/base/ip_address_number.h
+++ b/chromium/net/base/ip_address_number.h
@@ -5,10 +5,12 @@
#ifndef NET_BASE_IP_ADDRESS_NUMBER_H_
#define NET_BASE_IP_ADDRESS_NUMBER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -19,8 +21,11 @@ namespace net {
// network byte ordering.
//
// IPv4 addresses will have length 4, whereas IPv6 address will have length 16.
-typedef std::vector<unsigned char>
- IPAddressNumber; // This is also duplicated in net_util.h
+//
+// TODO(Martijnc): Remove the IPAddressNumber typedef. New code should use
+// IPAddress instead and existing code should be switched over.
+// https://crbug.com/496258
+typedef std::vector<unsigned char> IPAddressNumber;
typedef std::vector<IPAddressNumber> IPAddressList;
static const size_t kIPv4AddressSize = 4;
diff --git a/chromium/net/base/ip_address_number_unittest.cc b/chromium/net/base/ip_address_number_unittest.cc
index 2ee7bed264e..0b37bfac39f 100644
--- a/chromium/net/base/ip_address_number_unittest.cc
+++ b/chromium/net/base/ip_address_number_unittest.cc
@@ -122,7 +122,7 @@ TEST(IpAddressNumberTest, IsIPv4Mapped) {
EXPECT_FALSE(IsIPv4Mapped(ipv4_number));
IPAddressNumber ipv6_number;
- EXPECT_TRUE(ParseIPLiteralToNumber("::1", &ipv4_number));
+ EXPECT_TRUE(ParseIPLiteralToNumber("::1", &ipv6_number));
EXPECT_FALSE(IsIPv4Mapped(ipv6_number));
IPAddressNumber ipv4mapped_number;
diff --git a/chromium/net/base/ip_address_unittest.cc b/chromium/net/base/ip_address_unittest.cc
new file mode 100644
index 00000000000..35c9cc93e98
--- /dev/null
+++ b/chromium/net/base/ip_address_unittest.cc
@@ -0,0 +1,150 @@
+// Copyright (c) 2015 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/ip_address.h"
+
+#include <vector>
+
+#include "base/strings/string_number_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+// Helper to stringize an IP number (used to define expectations).
+std::string DumpIPAddress(const IPAddress& v) {
+ std::string out;
+ for (size_t i = 0; i < v.bytes().size(); ++i) {
+ if (i != 0)
+ out.append(",");
+ out.append(base::UintToString(v.bytes()[i]));
+ }
+ return out;
+}
+
+TEST(IPAddressTest, IsIPVersion) {
+ uint8_t addr1[4] = {192, 168, 0, 1};
+ IPAddress ip_address1(addr1);
+ EXPECT_TRUE(ip_address1.IsIPv4());
+ EXPECT_FALSE(ip_address1.IsIPv6());
+
+ uint8_t addr2[16] = {0xFE, 0xDC, 0xBA, 0x98};
+ IPAddress ip_address2(addr2);
+ EXPECT_TRUE(ip_address2.IsIPv6());
+ EXPECT_FALSE(ip_address2.IsIPv4());
+
+ IPAddress ip_address3;
+ EXPECT_FALSE(ip_address3.IsIPv6());
+ EXPECT_FALSE(ip_address3.IsIPv4());
+}
+
+TEST(IPAddressTest, IsValid) {
+ uint8_t addr1[4] = {192, 168, 0, 1};
+ IPAddress ip_address1(addr1);
+ EXPECT_TRUE(ip_address1.IsValid());
+ EXPECT_FALSE(ip_address1.empty());
+
+ uint8_t addr2[16] = {0xFE, 0xDC, 0xBA, 0x98};
+ IPAddress ip_address2(addr2);
+ EXPECT_TRUE(ip_address2.IsValid());
+ EXPECT_FALSE(ip_address2.empty());
+
+ uint8_t addr3[5] = {0xFE, 0xDC, 0xBA, 0x98};
+ IPAddress ip_address3(addr3);
+ EXPECT_FALSE(ip_address3.IsValid());
+ EXPECT_FALSE(ip_address3.empty());
+
+ IPAddress ip_address4;
+ EXPECT_FALSE(ip_address4.IsValid());
+ EXPECT_TRUE(ip_address4.empty());
+}
+
+TEST(IPAddressTest, ToString) {
+ uint8_t addr1[4] = {0, 0, 0, 0};
+ IPAddress ip_address1(addr1);
+ EXPECT_EQ("0.0.0.0", ip_address1.ToString());
+
+ uint8_t addr2[4] = {192, 168, 0, 1};
+ IPAddress ip_address2(addr2);
+ EXPECT_EQ("192.168.0.1", ip_address2.ToString());
+
+ uint8_t addr3[16] = {0xFE, 0xDC, 0xBA, 0x98};
+ IPAddress ip_address3(addr3);
+ EXPECT_EQ("fedc:ba98::", ip_address3.ToString());
+}
+
+// Test that invalid IP literals fail to parse.
+TEST(IPAddressTest, FromIPLiteral_FailParse) {
+ IPAddress address;
+
+ EXPECT_FALSE(IPAddress::FromIPLiteral("bad value", &address));
+ EXPECT_FALSE(IPAddress::FromIPLiteral("bad:value", &address));
+ EXPECT_FALSE(IPAddress::FromIPLiteral(std::string(), &address));
+ EXPECT_FALSE(IPAddress::FromIPLiteral("192.168.0.1:30", &address));
+ EXPECT_FALSE(IPAddress::FromIPLiteral(" 192.168.0.1 ", &address));
+ EXPECT_FALSE(IPAddress::FromIPLiteral("[::1]", &address));
+}
+
+// Test parsing an IPv4 literal.
+TEST(IPAddressTest, FromIPLiteral_IPv4) {
+ IPAddress address;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("192.168.0.1", &address));
+ EXPECT_EQ("192,168,0,1", DumpIPAddress(address));
+ EXPECT_EQ("192.168.0.1", address.ToString());
+}
+
+// Test parsing an IPv6 literal.
+TEST(IPAddressTest, FromIPLiteral_IPv6) {
+ IPAddress address;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("1:abcd::3:4:ff", &address));
+ EXPECT_EQ("0,1,171,205,0,0,0,0,0,0,0,3,0,4,0,255", DumpIPAddress(address));
+ EXPECT_EQ("1:abcd::3:4:ff", address.ToString());
+}
+
+TEST(IPAddressTest, IsIPv4Mapped) {
+ IPAddress ipv4_address;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("192.168.0.1", &ipv4_address));
+ EXPECT_FALSE(ipv4_address.IsIPv4Mapped());
+
+ IPAddress ipv6_address;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("::1", &ipv4_address));
+ EXPECT_FALSE(ipv6_address.IsIPv4Mapped());
+
+ IPAddress ipv4mapped_address;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("::ffff:0101:1", &ipv4mapped_address));
+ EXPECT_TRUE(ipv4mapped_address.IsIPv4Mapped());
+}
+
+TEST(IPAddressTest, IsEqual) {
+ IPAddress ip_address1;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address1));
+ IPAddress ip_address2;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("2001:db8:0::42", &ip_address2));
+ IPAddress ip_address3;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address3));
+
+ EXPECT_FALSE(ip_address1 == ip_address2);
+ EXPECT_TRUE(ip_address1 == ip_address3);
+}
+
+TEST(IPAddressTest, LessThan) {
+ // IPv4 vs IPv6
+ IPAddress ip_address1;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address1));
+ IPAddress ip_address2;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("2001:db8:0::42", &ip_address2));
+ EXPECT_TRUE(ip_address1 < ip_address2);
+ EXPECT_FALSE(ip_address2 < ip_address1);
+
+ // Compare equivalent addresses.
+ IPAddress ip_address3;
+ EXPECT_TRUE(IPAddress::FromIPLiteral("127.0.0.1", &ip_address3));
+ EXPECT_FALSE(ip_address1 < ip_address3);
+ EXPECT_FALSE(ip_address3 < ip_address1);
+}
+
+} // anonymous namespace
+
+} // namespace net
diff --git a/chromium/net/base/ip_endpoint.cc b/chromium/net/base/ip_endpoint.cc
index 78348493d98..c88ae2ec723 100644
--- a/chromium/net/base/ip_endpoint.cc
+++ b/chromium/net/base/ip_endpoint.cc
@@ -4,24 +4,82 @@
#include "net/base/ip_endpoint.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/sys_byteorder.h"
+#include "build/build_config.h"
+
#if defined(OS_WIN)
#include <winsock2.h>
+#include <ws2bth.h>
#elif defined(OS_POSIX)
#include <netinet/in.h>
#endif
-#include "net/base/net_util.h"
+
+#include <tuple>
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/sys_byteorder.h"
+#include "net/base/ip_address.h"
+
+#if defined(OS_WIN)
+#include "net/base/winsock_util.h"
+#endif
namespace net {
namespace {
+
// By definition, socklen_t is large enough to hold both sizes.
const socklen_t kSockaddrInSize = sizeof(struct sockaddr_in);
const socklen_t kSockaddrIn6Size = sizeof(struct sockaddr_in6);
+
+// Extracts the address and port portions of a sockaddr.
+bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr,
+ socklen_t sock_addr_len,
+ const uint8_t** address,
+ size_t* address_len,
+ uint16_t* port) {
+ if (sock_addr->sa_family == AF_INET) {
+ if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in)))
+ return false;
+ const struct sockaddr_in* addr =
+ reinterpret_cast<const struct sockaddr_in*>(sock_addr);
+ *address = reinterpret_cast<const uint8_t*>(&addr->sin_addr);
+ *address_len = kIPv4AddressSize;
+ if (port)
+ *port = base::NetToHost16(addr->sin_port);
+ return true;
+ }
+
+ if (sock_addr->sa_family == AF_INET6) {
+ if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in6)))
+ return false;
+ const struct sockaddr_in6* addr =
+ reinterpret_cast<const struct sockaddr_in6*>(sock_addr);
+ *address = reinterpret_cast<const uint8_t*>(&addr->sin6_addr);
+ *address_len = kIPv6AddressSize;
+ if (port)
+ *port = base::NetToHost16(addr->sin6_port);
+ return true;
+ }
+
+#if defined(OS_WIN)
+ if (sock_addr->sa_family == AF_BTH) {
+ if (sock_addr_len < static_cast<socklen_t>(sizeof(SOCKADDR_BTH)))
+ return false;
+ const SOCKADDR_BTH* addr = reinterpret_cast<const SOCKADDR_BTH*>(sock_addr);
+ *address = reinterpret_cast<const uint8_t*>(&addr->btAddr);
+ *address_len = kBluetoothAddressSize;
+ if (port)
+ *port = static_cast<uint16_t>(addr->port);
+ return true;
+ }
+#endif
+
+ return false; // Unrecognized |sa_family|.
}
+} // namespace
+
IPEndPoint::IPEndPoint() : port_(0) {}
IPEndPoint::~IPEndPoint() {}
@@ -30,6 +88,10 @@ IPEndPoint::IPEndPoint(const IPAddressNumber& address, uint16_t port)
: address_(address), port_(port) {
}
+IPEndPoint::IPEndPoint(const IPAddress& address, uint16_t port)
+ : address_(address.bytes()), port_(port) {
+}
+
IPEndPoint::IPEndPoint(const IPEndPoint& endpoint) {
address_ = endpoint.address_;
port_ = endpoint.port_;
@@ -110,19 +172,16 @@ std::string IPEndPoint::ToStringWithoutPort() const {
return IPAddressToString(address_);
}
-bool IPEndPoint::operator<(const IPEndPoint& that) const {
+bool IPEndPoint::operator<(const IPEndPoint& other) const {
// Sort IPv4 before IPv6.
- if (address_.size() != that.address_.size()) {
- return address_.size() < that.address_.size();
- }
- if (address_ != that.address_) {
- return address_ < that.address_;
+ if (address_.size() != other.address_.size()) {
+ return address_.size() < other.address_.size();
}
- return port_ < that.port_;
+ return std::tie(address_, port_) < std::tie(other.address_, other.port_);
}
-bool IPEndPoint::operator==(const IPEndPoint& that) const {
- return address_ == that.address_ && port_ == that.port_;
+bool IPEndPoint::operator==(const IPEndPoint& other) const {
+ return address_ == other.address_ && port_ == other.port_;
}
} // namespace net
diff --git a/chromium/net/base/ip_endpoint.h b/chromium/net/base/ip_endpoint.h
index 784ee031ed1..07ef3841d1e 100644
--- a/chromium/net/base/ip_endpoint.h
+++ b/chromium/net/base/ip_endpoint.h
@@ -5,9 +5,10 @@
#ifndef NET_BASE_IP_ENDPOINT_H_
#define NET_BASE_IP_ENDPOINT_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "net/base/address_family.h"
#include "net/base/ip_address_number.h"
@@ -18,6 +19,8 @@ struct sockaddr;
namespace net {
+class IPAddress;
+
// An IPEndPoint represents the address of a transport endpoint:
// * IP address (either v4 or v6)
// * Port
@@ -25,7 +28,9 @@ class NET_EXPORT IPEndPoint {
public:
IPEndPoint();
~IPEndPoint();
+ // DEPRECATED(crbug.com/496258): Use the ctor that takes IPAddress instead.
IPEndPoint(const IPAddressNumber& address, uint16_t port);
+ IPEndPoint(const IPAddress& address, uint16_t port);
IPEndPoint(const IPEndPoint& endpoint);
const IPAddressNumber& address() const { return address_; }
diff --git a/chromium/net/base/ip_endpoint_unittest.cc b/chromium/net/base/ip_endpoint_unittest.cc
index 5266ea6644f..a2b647c8723 100644
--- a/chromium/net/base/ip_endpoint_unittest.cc
+++ b/chromium/net/base/ip_endpoint_unittest.cc
@@ -4,20 +4,52 @@
#include "net/base/ip_endpoint.h"
-#include "base/strings/string_number_conversions.h"
-#include "net/base/net_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
+#include "build/build_config.h"
+
#if defined(OS_WIN)
#include <winsock2.h>
#elif defined(OS_POSIX)
#include <netinet/in.h>
#endif
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/sys_byteorder.h"
+#include "net/base/sockaddr_storage.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
namespace net {
namespace {
+// Retuns the port field of the |sockaddr|.
+const uint16_t* GetPortFieldFromSockaddr(const struct sockaddr* address,
+ socklen_t address_len) {
+ if (address->sa_family == AF_INET) {
+ DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len));
+ const struct sockaddr_in* sockaddr =
+ reinterpret_cast<const struct sockaddr_in*>(address);
+ return &sockaddr->sin_port;
+ } else if (address->sa_family == AF_INET6) {
+ DCHECK_LE(sizeof(sockaddr_in6), static_cast<size_t>(address_len));
+ const struct sockaddr_in6* sockaddr =
+ reinterpret_cast<const struct sockaddr_in6*>(address);
+ return &sockaddr->sin6_port;
+ } else {
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+// Returns the value of port in |sockaddr| (in host byte ordering).
+int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
+ const uint16_t* port_field = GetPortFieldFromSockaddr(address, address_len);
+ if (!port_field)
+ return -1;
+ return base::NetToHost16(*port_field);
+}
+
struct TestData {
std::string host;
std::string host_normalized;
diff --git a/chromium/net/base/ip_pattern.cc b/chromium/net/base/ip_pattern.cc
index 61c8c2e4df8..0dbbe13d78d 100644
--- a/chromium/net/base/ip_pattern.cc
+++ b/chromium/net/base/ip_pattern.cc
@@ -7,6 +7,7 @@
#include <string>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -54,9 +55,7 @@ bool IPPattern::ComponentPattern::Match(uint32_t value) const {
IPPattern::IPPattern() : is_ipv4_(true) {}
-IPPattern::~IPPattern() {
- STLDeleteElements(&component_patterns_);
-}
+IPPattern::~IPPattern() {}
bool IPPattern::Match(const IPAddressNumber& address) const {
if (ip_mask_.empty())
@@ -134,7 +133,7 @@ bool IPPattern::ParsePattern(const std::string& ip_pattern) {
return false;
}
ip_mask_.push_back(false);
- component_patterns_.push_back(component_pattern.release());
+ component_patterns_.push_back(std::move(component_pattern));
}
return true;
}
diff --git a/chromium/net/base/ip_pattern.h b/chromium/net/base/ip_pattern.h
index 28919279222..c30fd4c449a 100644
--- a/chromium/net/base/ip_pattern.h
+++ b/chromium/net/base/ip_pattern.h
@@ -5,10 +5,13 @@
#ifndef NET_BASE_IP_PATTERN_H_
#define NET_BASE_IP_PATTERN_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/ip_address_number.h"
#include "net/base/net_export.h"
@@ -33,8 +36,8 @@ class NET_EXPORT IPPattern {
private:
class ComponentPattern;
- typedef std::vector<std::string> Strings;
- typedef std::vector<ComponentPattern*> ComponentPatternList;
+ using Strings = std::vector<std::string>;
+ using ComponentPatternList = std::vector<scoped_ptr<ComponentPattern>>;
// IPv6 addresses have 8 components, while IPv4 addresses have 4 components.
// ComponentPattern is used to define patterns to match individual components.
diff --git a/chromium/net/base/keygen_handler_nss.cc b/chromium/net/base/keygen_handler_nss.cc
index 661dabc7710..849f7872673 100644
--- a/chromium/net/base/keygen_handler_nss.cc
+++ b/chromium/net/base/keygen_handler_nss.cc
@@ -4,6 +4,8 @@
#include "net/base/keygen_handler.h"
+#include <utility>
+
#include "base/logging.h"
#include "crypto/nss_crypto_module_delegate.h"
#include "crypto/nss_util.h"
@@ -20,7 +22,7 @@ std::string KeygenHandler::GenKeyAndSignChallenge() {
crypto::ScopedPK11Slot slot;
if (crypto_module_delegate_) {
- slot = crypto_module_delegate_->RequestSlot().Pass();
+ slot = crypto_module_delegate_->RequestSlot();
} else {
LOG(ERROR) << "Could not get an NSS key slot.";
return std::string();
@@ -40,7 +42,7 @@ std::string KeygenHandler::GenKeyAndSignChallenge() {
void KeygenHandler::set_crypto_module_delegate(
scoped_ptr<crypto::NSSCryptoModuleDelegate> delegate) {
- crypto_module_delegate_ = delegate.Pass();
+ crypto_module_delegate_ = std::move(delegate);
}
} // namespace net
diff --git a/chromium/net/base/keygen_handler_unittest.cc b/chromium/net/base/keygen_handler_unittest.cc
index 74d91467eba..c1b5fe44e00 100644
--- a/chromium/net/base/keygen_handler_unittest.cc
+++ b/chromium/net/base/keygen_handler_unittest.cc
@@ -5,14 +5,15 @@
#include "net/base/keygen_handler.h"
#include <string>
+#include <utility>
#include "base/base64.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
-#include "base/threading/worker_pool.h"
-#include "base/threading/thread_restrictions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/threading/worker_pool.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -30,7 +31,7 @@ namespace {
class StubCryptoModuleDelegate : public crypto::NSSCryptoModuleDelegate {
public:
explicit StubCryptoModuleDelegate(crypto::ScopedPK11Slot slot)
- : slot_(slot.Pass()) {}
+ : slot_(std::move(slot)) {}
std::string RequestPassword(const std::string& slot_name,
bool retry,
@@ -61,7 +62,7 @@ class KeygenHandlerTest : public ::testing::Test {
new StubCryptoModuleDelegate(crypto::ScopedPK11Slot(
PK11_ReferenceSlot(test_nss_db_.slot())))));
#endif
- return handler.Pass();
+ return handler;
}
private:
diff --git a/chromium/net/base/keygen_handler_win.cc b/chromium/net/base/keygen_handler_win.cc
index 44365fa136d..d7eacd852db 100644
--- a/chromium/net/base/keygen_handler_win.cc
+++ b/chromium/net/base/keygen_handler_win.cc
@@ -12,7 +12,6 @@
#include <vector>
#include "base/base64.h"
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
@@ -183,7 +182,7 @@ std::string KeygenHandler::GenKeyAndSignChallenge() {
CRYPT_SILENT | CRYPT_NEWKEYSET))
break;
- if (GetLastError() != NTE_BAD_KEYSET) {
+ if (GetLastError() != static_cast<DWORD>(NTE_BAD_KEYSET)) {
LOG(ERROR) << "Keygen failed: Couldn't acquire a CryptoAPI provider "
"context: " << GetLastError();
return std::string();
diff --git a/chromium/net/base/layered_network_delegate.cc b/chromium/net/base/layered_network_delegate.cc
index d384d5eae6e..9fe37196ccd 100644
--- a/chromium/net/base/layered_network_delegate.cc
+++ b/chromium/net/base/layered_network_delegate.cc
@@ -4,12 +4,13 @@
#include "net/base/layered_network_delegate.h"
+#include <utility>
+
namespace net {
LayeredNetworkDelegate::LayeredNetworkDelegate(
scoped_ptr<NetworkDelegate> nested_network_delegate)
- : nested_network_delegate_(nested_network_delegate.Pass()) {
-}
+ : nested_network_delegate_(std::move(nested_network_delegate)) {}
LayeredNetworkDelegate::~LayeredNetworkDelegate() {
}
@@ -138,25 +139,24 @@ void LayeredNetworkDelegate::OnResponseStarted(URLRequest* request) {
void LayeredNetworkDelegate::OnResponseStartedInternal(URLRequest* request) {
}
-void LayeredNetworkDelegate::OnNetworkBytesReceived(const URLRequest& request,
+void LayeredNetworkDelegate::OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) {
OnNetworkBytesReceivedInternal(request, bytes_received);
nested_network_delegate_->NotifyNetworkBytesReceived(request, bytes_received);
}
void LayeredNetworkDelegate::OnNetworkBytesReceivedInternal(
- const URLRequest& request,
+ URLRequest* request,
int64_t bytes_received) {}
-void LayeredNetworkDelegate::OnNetworkBytesSent(const URLRequest& request,
+void LayeredNetworkDelegate::OnNetworkBytesSent(URLRequest* request,
int64_t bytes_sent) {
OnNetworkBytesSentInternal(request, bytes_sent);
nested_network_delegate_->NotifyNetworkBytesSent(request, bytes_sent);
}
-void LayeredNetworkDelegate::OnNetworkBytesSentInternal(
- const URLRequest& request,
- int64_t bytes_sent) {}
+void LayeredNetworkDelegate::OnNetworkBytesSentInternal(URLRequest* request,
+ int64_t bytes_sent) {}
void LayeredNetworkDelegate::OnCompleted(URLRequest* request, bool started) {
OnCompletedInternal(request, started);
@@ -176,12 +176,6 @@ void LayeredNetworkDelegate::OnURLRequestDestroyedInternal(
URLRequest* request) {
}
-void LayeredNetworkDelegate::OnURLRequestJobOrphaned(URLRequest* request) {
- // This hook is only added to debug https://crbug.com/289715, so there is no
- // need for a OnURLRequestJobOrphanedInternal hook.
- nested_network_delegate_->NotifyURLRequestJobOrphaned(request);
-}
-
void LayeredNetworkDelegate::OnPACScriptError(int line_number,
const base::string16& error) {
OnPACScriptErrorInternal(line_number, error);
@@ -258,15 +252,21 @@ void LayeredNetworkDelegate::OnCanEnablePrivacyModeInternal(
const GURL& first_party_for_cookies) const {
}
-bool LayeredNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const {
- OnFirstPartyOnlyCookieExperimentEnabledInternal();
- return nested_network_delegate_->FirstPartyOnlyCookieExperimentEnabled();
+bool LayeredNetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
+ OnAreExperimentalCookieFeaturesEnabledInternal();
+ return nested_network_delegate_->AreExperimentalCookieFeaturesEnabled();
}
-void LayeredNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabledInternal()
- const {
+bool LayeredNetworkDelegate::OnAreStrictSecureCookiesEnabled() const {
+ OnAreStrictSecureCookiesEnabledInternal();
+ return nested_network_delegate_->AreStrictSecureCookiesEnabled();
}
+void LayeredNetworkDelegate::OnAreExperimentalCookieFeaturesEnabledInternal()
+ const {}
+
+void LayeredNetworkDelegate::OnAreStrictSecureCookiesEnabledInternal() const {}
+
bool LayeredNetworkDelegate::
OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const URLRequest& request,
diff --git a/chromium/net/base/layered_network_delegate.h b/chromium/net/base/layered_network_delegate.h
index dabe681af47..9f0928e7d1b 100644
--- a/chromium/net/base/layered_network_delegate.h
+++ b/chromium/net/base/layered_network_delegate.h
@@ -64,12 +64,11 @@ class NET_EXPORT LayeredNetworkDelegate : public NetworkDelegate {
GURL* allowed_unsafe_redirect_url) final;
void OnBeforeRedirect(URLRequest* request, const GURL& new_location) final;
void OnResponseStarted(URLRequest* request) final;
- void OnNetworkBytesReceived(const URLRequest& request,
+ void OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) final;
- void OnNetworkBytesSent(const URLRequest& request, int64_t bytes_sent) final;
+ void OnNetworkBytesSent(URLRequest* request, int64_t bytes_sent) final;
void OnCompleted(URLRequest* request, bool started) final;
void OnURLRequestDestroyed(URLRequest* request) final;
- void OnURLRequestJobOrphaned(URLRequest* request) final;
void OnPACScriptError(int line_number, const base::string16& error) final;
AuthRequiredResponse OnAuthRequired(URLRequest* request,
const AuthChallengeInfo& auth_info,
@@ -84,7 +83,8 @@ class NET_EXPORT LayeredNetworkDelegate : public NetworkDelegate {
const base::FilePath& path) const final;
bool OnCanEnablePrivacyMode(const GURL& url,
const GURL& first_party_for_cookies) const final;
- bool OnFirstPartyOnlyCookieExperimentEnabled() const final;
+ bool OnAreExperimentalCookieFeaturesEnabled() const final;
+ bool OnAreStrictSecureCookiesEnabled() const final;
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const URLRequest& request,
const GURL& target_url,
@@ -126,10 +126,10 @@ class NET_EXPORT LayeredNetworkDelegate : public NetworkDelegate {
virtual void OnResponseStartedInternal(URLRequest* request);
- virtual void OnNetworkBytesReceivedInternal(const URLRequest& request,
+ virtual void OnNetworkBytesReceivedInternal(URLRequest* request,
int64_t bytes_received);
- virtual void OnNetworkBytesSentInternal(const URLRequest& request,
+ virtual void OnNetworkBytesSentInternal(URLRequest* request,
int64_t bytes_sent);
virtual void OnCompletedInternal(URLRequest* request, bool started);
@@ -158,7 +158,8 @@ class NET_EXPORT LayeredNetworkDelegate : public NetworkDelegate {
const GURL& url,
const GURL& first_party_for_cookies) const;
- virtual void OnFirstPartyOnlyCookieExperimentEnabledInternal() const;
+ virtual void OnAreExperimentalCookieFeaturesEnabledInternal() const;
+ virtual void OnAreStrictSecureCookiesEnabledInternal() const;
virtual void OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal(
const URLRequest& request,
diff --git a/chromium/net/base/layered_network_delegate_unittest.cc b/chromium/net/base/layered_network_delegate_unittest.cc
index bfdbe7b827b..6ca77a5015d 100644
--- a/chromium/net/base/layered_network_delegate_unittest.cc
+++ b/chromium/net/base/layered_network_delegate_unittest.cc
@@ -5,6 +5,7 @@
#include "net/base/layered_network_delegate.h"
#include <map>
+#include <utility>
#include "base/bind.h"
#include "base/files/file_path.h"
@@ -93,13 +94,12 @@ class TestNetworkDelegateImpl : public NetworkDelegateImpl {
IncrementAndCompareCounter("on_response_started_count");
}
- void OnNetworkBytesReceived(const URLRequest& request,
+ void OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) override {
IncrementAndCompareCounter("on_network_bytes_received_count");
}
- void OnNetworkBytesSent(const URLRequest& request,
- int64_t bytes_sent) override {
+ void OnNetworkBytesSent(URLRequest* request, int64_t bytes_sent) override {
IncrementAndCompareCounter("on_network_bytes_sent_count");
}
@@ -175,7 +175,7 @@ class TestLayeredNetworkDelegate : public LayeredNetworkDelegate {
public:
TestLayeredNetworkDelegate(scoped_ptr<NetworkDelegate> network_delegate,
CountersMap* counters)
- : LayeredNetworkDelegate(network_delegate.Pass()),
+ : LayeredNetworkDelegate(std::move(network_delegate)),
context_(true),
counters_(counters) {
context_.Init();
@@ -202,11 +202,11 @@ class TestLayeredNetworkDelegate : public LayeredNetworkDelegate {
request_headers.get()));
OnBeforeSendProxyHeaders(NULL, ProxyInfo(), request_headers.get());
OnSendHeaders(NULL, *request_headers);
- OnNetworkBytesSent(*request, 42);
+ OnNetworkBytesSent(request.get(), 42);
EXPECT_EQ(OK, OnHeadersReceived(NULL, completion_callback.callback(),
response_headers.get(), NULL, NULL));
OnResponseStarted(request.get());
- OnNetworkBytesReceived(*request, 42);
+ OnNetworkBytesReceived(request.get(), 42);
OnCompleted(request.get(), false);
OnURLRequestDestroyed(request.get());
OnPACScriptError(0, base::string16());
@@ -284,13 +284,13 @@ class TestLayeredNetworkDelegate : public LayeredNetworkDelegate {
EXPECT_EQ(1, (*counters_)["on_response_started_count"]);
}
- void OnNetworkBytesReceivedInternal(const URLRequest& request,
+ void OnNetworkBytesReceivedInternal(URLRequest* request,
int64_t bytes_received) override {
++(*counters_)["on_network_bytes_received_count"];
EXPECT_EQ(1, (*counters_)["on_network_bytes_received_count"]);
}
- void OnNetworkBytesSentInternal(const URLRequest& request,
+ void OnNetworkBytesSentInternal(URLRequest* request,
int64_t bytes_sent) override {
++(*counters_)["on_network_bytes_sent_count"];
EXPECT_EQ(1, (*counters_)["on_network_bytes_sent_count"]);
@@ -374,9 +374,9 @@ class LayeredNetworkDelegateTest : public testing::Test {
scoped_ptr<TestNetworkDelegateImpl> test_network_delegate(
new TestNetworkDelegateImpl(&layered_network_delegate_counters));
test_network_delegate_ = test_network_delegate.get();
- layered_network_delegate_ =
- scoped_ptr<TestLayeredNetworkDelegate>(new TestLayeredNetworkDelegate(
- test_network_delegate.Pass(), &layered_network_delegate_counters));
+ layered_network_delegate_ = scoped_ptr<TestLayeredNetworkDelegate>(
+ new TestLayeredNetworkDelegate(std::move(test_network_delegate),
+ &layered_network_delegate_counters));
}
CountersMap layered_network_delegate_counters;
diff --git a/chromium/net/base/linked_hash_map.h b/chromium/net/base/linked_hash_map.h
index 9a39439f78d..b86654bdeeb 100644
--- a/chromium/net/base/linked_hash_map.h
+++ b/chromium/net/base/linked_hash_map.h
@@ -15,6 +15,8 @@
#ifndef UTIL_GTL_LINKED_HASH_MAP_H_
#define UTIL_GTL_LINKED_HASH_MAP_H_
+#include <stddef.h>
+
#include <list>
#include <utility>
diff --git a/chromium/net/base/load_timing_info.h b/chromium/net/base/load_timing_info.h
index 4714222123b..22a59082f54 100644
--- a/chromium/net/base/load_timing_info.h
+++ b/chromium/net/base/load_timing_info.h
@@ -5,7 +5,8 @@
#ifndef NET_BASE_LOAD_TIMING_INFO_H_
#define NET_BASE_LOAD_TIMING_INFO_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/time/time.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/lookup_string_in_fixed_set.cc b/chromium/net/base/lookup_string_in_fixed_set.cc
new file mode 100644
index 00000000000..46497f3c47b
--- /dev/null
+++ b/chromium/net/base/lookup_string_in_fixed_set.cc
@@ -0,0 +1,152 @@
+// Copyright 2015 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/lookup_string_in_fixed_set.h"
+
+#include "base/logging.h"
+
+namespace net {
+
+namespace {
+
+// Read next offset from pos.
+// Returns true if an offset could be read, false otherwise.
+bool GetNextOffset(const unsigned char** pos,
+ const unsigned char* end,
+ const unsigned char** offset) {
+ if (*pos == end)
+ return false;
+
+ // When reading an offset the byte array must always contain at least
+ // three more bytes to consume. First the offset to read, then a node
+ // to skip over and finally a destination node. No object can be smaller
+ // than one byte.
+ CHECK_LT(*pos + 2, end);
+ size_t bytes_consumed;
+ switch (**pos & 0x60) {
+ case 0x60: // Read three byte offset
+ *offset += (((*pos)[0] & 0x1F) << 16) | ((*pos)[1] << 8) | (*pos)[2];
+ bytes_consumed = 3;
+ break;
+ case 0x40: // Read two byte offset
+ *offset += (((*pos)[0] & 0x1F) << 8) | (*pos)[1];
+ bytes_consumed = 2;
+ break;
+ default:
+ *offset += (*pos)[0] & 0x3F;
+ bytes_consumed = 1;
+ }
+ if ((**pos & 0x80) != 0) {
+ *pos = end;
+ } else {
+ *pos += bytes_consumed;
+ }
+ return true;
+}
+
+// Check if byte at offset is last in label.
+bool IsEOL(const unsigned char* offset, const unsigned char* end) {
+ CHECK_LT(offset, end);
+ return (*offset & 0x80) != 0;
+}
+
+// Check if byte at offset matches first character in key.
+// This version matches characters not last in label.
+bool IsMatch(const unsigned char* offset,
+ const unsigned char* end,
+ const char* key) {
+ CHECK_LT(offset, end);
+ return *offset == *key;
+}
+
+// Check if byte at offset matches first character in key.
+// This version matches characters last in label.
+bool IsEndCharMatch(const unsigned char* offset,
+ const unsigned char* end,
+ const char* key) {
+ CHECK_LT(offset, end);
+ return *offset == (*key | 0x80);
+}
+
+// Read return value at offset.
+// Returns true if a return value could be read, false otherwise.
+bool GetReturnValue(const unsigned char* offset,
+ const unsigned char* end,
+ int* return_value) {
+ CHECK_LT(offset, end);
+ if ((*offset & 0xE0) == 0x80) {
+ *return_value = *offset & 0x0F;
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+// Lookup a domain key in a byte array generated by make_dafsa.py.
+// The rule type is returned if key is found, otherwise kDafsaNotFound is
+// returned.
+int LookupStringInFixedSet(const unsigned char* graph,
+ size_t length,
+ const char* key,
+ size_t key_length) {
+ const unsigned char* pos = graph;
+ const unsigned char* end = graph + length;
+ const unsigned char* offset = pos;
+ const char* key_end = key + key_length;
+ while (GetNextOffset(&pos, end, &offset)) {
+ // char <char>+ end_char offsets
+ // char <char>+ return value
+ // char end_char offsets
+ // char return value
+ // end_char offsets
+ // return_value
+ bool did_consume = false;
+ if (key != key_end && !IsEOL(offset, end)) {
+ // Leading <char> is not a match. Don't dive into this child
+ if (!IsMatch(offset, end, key))
+ continue;
+ did_consume = true;
+ ++offset;
+ ++key;
+ // Possible matches at this point:
+ // <char>+ end_char offsets
+ // <char>+ return value
+ // end_char offsets
+ // return value
+ // Remove all remaining <char> nodes possible
+ while (!IsEOL(offset, end) && key != key_end) {
+ if (!IsMatch(offset, end, key))
+ return kDafsaNotFound;
+ ++key;
+ ++offset;
+ }
+ }
+ // Possible matches at this point:
+ // end_char offsets
+ // return_value
+ // If one or more <char> elements were consumed, a failure
+ // to match is terminal. Otherwise, try the next node.
+ if (key == key_end) {
+ int return_value;
+ if (GetReturnValue(offset, end, &return_value))
+ return return_value;
+ // The DAFSA guarantees that if the first char is a match, all
+ // remaining char elements MUST match if the key is truly present.
+ if (did_consume)
+ return kDafsaNotFound;
+ continue;
+ }
+ if (!IsEndCharMatch(offset, end, key)) {
+ if (did_consume)
+ return kDafsaNotFound; // Unexpected
+ continue;
+ }
+ ++key;
+ pos = ++offset; // Dive into child
+ }
+ return kDafsaNotFound; // No match
+}
+
+} // namespace net
diff --git a/chromium/net/base/lookup_string_in_fixed_set.h b/chromium/net/base/lookup_string_in_fixed_set.h
new file mode 100644
index 00000000000..793a782ed14
--- /dev/null
+++ b/chromium/net/base/lookup_string_in_fixed_set.h
@@ -0,0 +1,40 @@
+// Copyright 2015 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_LOOKUP_STRING_IN_FIXED_SET_H_
+#define NET_BASE_LOOKUP_STRING_IN_FIXED_SET_H_
+
+#include <stddef.h>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+enum {
+ kDafsaNotFound = -1, // key is not in set
+ kDafsaFound = 0, // key is in set
+ // The following return values are used by the implementation of
+ // GetDomainAndRegistry() and are probably not generally useful.
+ kDafsaExceptionRule = 1, // key excluded from set via exception
+ kDafsaWildcardRule = 2, // key matched a wildcard rule
+ kDafsaPrivateRule = 4, // key matched a private rule
+};
+
+// Looks up the string |key| with length |key_length| in a fixed set of
+// strings. The set of strings must be known at compile time. It is converted to
+// a graph structure named a DAFSA (Deterministic Acyclic Finite State
+// Automaton) by the script make_dafsa.py during compilation. This permits
+// efficient (in time and space) lookup. The graph generated by make_dafsa.py
+// takes the form of a constant byte array which should be supplied via the
+// |graph| and |length| parameters. The return value is kDafsaNotFound,
+// kDafsaFound, or a bitmap consisting of one or more of kDafsaExceptionRule,
+// kDafsaWildcardRule and kDafsaPrivateRule ORed together.
+NET_EXPORT int LookupStringInFixedSet(const unsigned char* graph,
+ size_t length,
+ const char* key,
+ size_t key_length);
+
+} // namespace net
+
+#endif // NET_BASE_LOOKUP_STRING_IN_FIXED_SET_H_
diff --git a/chromium/net/base/lookup_string_in_fixed_set_unittest.cc b/chromium/net/base/lookup_string_in_fixed_set_unittest.cc
new file mode 100644
index 00000000000..82e6c22d84b
--- /dev/null
+++ b/chromium/net/base/lookup_string_in_fixed_set_unittest.cc
@@ -0,0 +1,162 @@
+// Copyright 2015 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/lookup_string_in_fixed_set.h"
+
+#include <string.h>
+#include <ostream>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+namespace test1 {
+#include "net/base/registry_controlled_domains/effective_tld_names_unittest1-inc.cc"
+}
+namespace test3 {
+#include "net/base/registry_controlled_domains/effective_tld_names_unittest3-inc.cc"
+}
+namespace test4 {
+#include "net/base/registry_controlled_domains/effective_tld_names_unittest4-inc.cc"
+}
+namespace test5 {
+#include "net/base/registry_controlled_domains/effective_tld_names_unittest5-inc.cc"
+}
+namespace test6 {
+#include "net/base/registry_controlled_domains/effective_tld_names_unittest6-inc.cc"
+}
+
+struct Expectation {
+ const char* const key;
+ int value;
+};
+
+void PrintTo(const Expectation& expectation, std::ostream* os) {
+ *os << "{\"" << expectation.key << "\", " << expectation.value << "}";
+}
+
+class LookupStringInFixedSetTest : public testing::TestWithParam<Expectation> {
+ protected:
+ template <size_t N>
+ int LookupInGraph(const unsigned char(&graph)[N], const char* key) {
+ return LookupStringInFixedSet(graph, N, key, strlen(key));
+ }
+};
+
+class Dafsa1Test : public LookupStringInFixedSetTest {};
+
+TEST_P(Dafsa1Test, BasicTest) {
+ const Expectation& param = GetParam();
+ EXPECT_EQ(param.value, LookupInGraph(test1::kDafsa, param.key));
+}
+
+const Expectation kBasicTestCases[] = {
+ {"", -1}, {"j", -1}, {"jp", 0}, {"jjp", -1}, {"jpp", -1},
+ {"bar.jp", 2}, {"pref.bar.jp", 1}, {"c", 2}, {"b.c", 1}, {"priv.no", 4},
+};
+
+INSTANTIATE_TEST_CASE_P(LookupStringInFixedSetTest,
+ Dafsa1Test,
+ ::testing::ValuesIn(kBasicTestCases));
+
+class Dafsa3Test : public LookupStringInFixedSetTest {};
+
+// This DAFSA is constructed so that labels begin and end with unique
+// characters, which makes it impossible to merge labels. Each inner node
+// is about 100 bytes and a one byte offset can at most add 64 bytes to
+// previous offset. Thus the paths must go over two byte offsets.
+TEST_P(Dafsa3Test, TestDafsaTwoByteOffsets) {
+ const Expectation& param = GetParam();
+ EXPECT_EQ(param.value, LookupInGraph(test3::kDafsa, param.key));
+}
+
+const Expectation kTwoByteOffsetTestCases[] = {
+ {"0________________________________________________________________________"
+ "____________________________0",
+ 0},
+ {"7________________________________________________________________________"
+ "____________________________7",
+ 4},
+ {"a________________________________________________________________________"
+ "____________________________8",
+ -1},
+};
+
+INSTANTIATE_TEST_CASE_P(LookupStringInFixedSetTest,
+ Dafsa3Test,
+ ::testing::ValuesIn(kTwoByteOffsetTestCases));
+
+class Dafsa4Test : public LookupStringInFixedSetTest {};
+
+// This DAFSA is constructed so that labels begin and end with unique
+// characters, which makes it impossible to merge labels. The byte array
+// has a size of ~54k. A two byte offset can add at most add 8k to the
+// previous offset. Since we can skip only forward in memory, the nodes
+// representing the return values must be located near the end of the byte
+// array. The probability that we can reach from an arbitrary inner node to
+// a return value without using a three byte offset is small (but not zero).
+// The test is repeated with some different keys and with a reasonable
+// probability at least one of the tested paths has go over a three byte
+// offset.
+TEST_P(Dafsa4Test, TestDafsaThreeByteOffsets) {
+ const Expectation& param = GetParam();
+ EXPECT_EQ(param.value, LookupInGraph(test4::kDafsa, param.key));
+}
+
+const Expectation kThreeByteOffsetTestCases[] = {
+ {"Z6_______________________________________________________________________"
+ "_____________________________Z6",
+ 0},
+ {"Z7_______________________________________________________________________"
+ "_____________________________Z7",
+ 4},
+ {"Za_______________________________________________________________________"
+ "_____________________________Z8",
+ -1},
+};
+
+INSTANTIATE_TEST_CASE_P(LookupStringInFixedSetTest,
+ Dafsa4Test,
+ ::testing::ValuesIn(kThreeByteOffsetTestCases));
+
+class Dafsa5Test : public LookupStringInFixedSetTest {};
+
+// This DAFSA is constructed from words with similar prefixes but distinct
+// suffixes. The DAFSA will then form a trie with the implicit source node
+// as root.
+TEST_P(Dafsa5Test, TestDafsaJoinedPrefixes) {
+ const Expectation& param = GetParam();
+ EXPECT_EQ(param.value, LookupInGraph(test5::kDafsa, param.key));
+}
+
+const Expectation kJoinedPrefixesTestCases[] = {
+ {"ai", 0}, {"bj", 4}, {"aak", 0}, {"bbl", 4},
+ {"aaa", -1}, {"bbb", -1}, {"aaaam", 0}, {"bbbbn", 0},
+};
+
+INSTANTIATE_TEST_CASE_P(LookupStringInFixedSetTest,
+ Dafsa5Test,
+ ::testing::ValuesIn(kJoinedPrefixesTestCases));
+
+class Dafsa6Test : public LookupStringInFixedSetTest {};
+
+// This DAFSA is constructed from words with similar suffixes but distinct
+// prefixes. The DAFSA will then form a trie with the implicit sink node as
+// root.
+TEST_P(Dafsa6Test, TestDafsaJoinedSuffixes) {
+ const Expectation& param = GetParam();
+ EXPECT_EQ(param.value, LookupInGraph(test6::kDafsa, param.key));
+}
+
+const Expectation kJoinedSuffixesTestCases[] = {
+ {"ia", 0}, {"jb", 4}, {"kaa", 0}, {"lbb", 4},
+ {"aaa", -1}, {"bbb", -1}, {"maaaa", 0}, {"nbbbb", 0},
+};
+
+INSTANTIATE_TEST_CASE_P(LookupStringInFixedSetTest,
+ Dafsa6Test,
+ ::testing::ValuesIn(kJoinedSuffixesTestCases));
+
+} // namespace
+} // namespace net
diff --git a/chromium/net/base/mime_sniffer.h b/chromium/net/base/mime_sniffer.h
index 371a3309ad3..3c938150951 100644
--- a/chromium/net/base/mime_sniffer.h
+++ b/chromium/net/base/mime_sniffer.h
@@ -5,6 +5,8 @@
#ifndef NET_BASE_MIME_SNIFFER_H__
#define NET_BASE_MIME_SNIFFER_H__
+#include <stddef.h>
+
#include <string>
#include "net/base/net_export.h"
diff --git a/chromium/net/base/mime_util.cc b/chromium/net/base/mime_util.cc
index 0d511201fd0..6463ff13c8a 100644
--- a/chromium/net/base/mime_util.cc
+++ b/chromium/net/base/mime_util.cc
@@ -7,9 +7,11 @@
#include <map>
#include <string>
+#include "base/base64.h"
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -59,54 +61,54 @@ class MimeUtil : public PlatformMimeUtil {
static base::LazyInstance<MimeUtil>::Leaky g_mime_util =
LAZY_INSTANCE_INITIALIZER;
-static const MimeInfo primary_mappings[] = {
- { "text/html", "html,htm,shtml,shtm" },
- { "text/css", "css" },
- { "text/xml", "xml" },
- { "image/gif", "gif" },
- { "image/jpeg", "jpeg,jpg" },
- { "image/webp", "webp" },
- { "image/png", "png" },
- { "video/mp4", "mp4,m4v" },
- { "audio/x-m4a", "m4a" },
- { "audio/mp3", "mp3" },
- { "video/ogg", "ogv,ogm" },
- { "audio/ogg", "ogg,oga,opus" },
- { "video/webm", "webm" },
- { "audio/webm", "webm" },
- { "audio/wav", "wav" },
- { "audio/flac", "flac" },
- { "application/xhtml+xml", "xhtml,xht,xhtm" },
- { "application/x-chrome-extension", "crx" },
- { "multipart/related", "mhtml,mht" }
-};
-
-static const MimeInfo secondary_mappings[] = {
- { "application/octet-stream", "exe,com,bin" },
- { "application/gzip", "gz" },
- { "application/pdf", "pdf" },
- { "application/postscript", "ps,eps,ai" },
- { "application/javascript", "js" },
- { "application/font-woff", "woff" },
- { "image/bmp", "bmp" },
- { "image/x-icon", "ico" },
- { "image/vnd.microsoft.icon", "ico" },
- { "image/jpeg", "jfif,pjpeg,pjp" },
- { "image/tiff", "tiff,tif" },
- { "image/x-xbitmap", "xbm" },
- { "image/svg+xml", "svg,svgz" },
- { "image/x-png", "png"},
- { "message/rfc822", "eml" },
- { "text/plain", "txt,text" },
- { "text/html", "ehtml" },
- { "application/rss+xml", "rss" },
- { "application/rdf+xml", "rdf" },
- { "text/xml", "xsl,xbl,xslt" },
- { "application/vnd.mozilla.xul+xml", "xul" },
- { "application/x-shockwave-flash", "swf,swl" },
- { "application/pkcs7-mime", "p7m,p7c,p7z" },
- { "application/pkcs7-signature", "p7s" },
- { "application/x-mpegurl", "m3u8" },
+static const MimeInfo kPrimaryMappings[] = {
+ {"text/html", "html,htm,shtml,shtm"},
+ {"text/css", "css"},
+ {"text/xml", "xml"},
+ {"image/gif", "gif"},
+ {"image/jpeg", "jpeg,jpg"},
+ {"image/webp", "webp"},
+ {"image/png", "png"},
+ {"video/mp4", "mp4,m4v"},
+ {"audio/x-m4a", "m4a"},
+ {"audio/mp3", "mp3"},
+ {"video/ogg", "ogv,ogm"},
+ {"audio/ogg", "ogg,oga,opus"},
+ {"video/webm", "webm"},
+ {"audio/webm", "webm"},
+ {"audio/wav", "wav"},
+ {"audio/flac", "flac"},
+ {"application/xhtml+xml", "xhtml,xht,xhtm"},
+ {"application/x-chrome-extension", "crx"},
+ {"multipart/related", "mhtml,mht"}};
+
+static const MimeInfo kSecondaryMappings[] = {
+ {"application/octet-stream", "exe,com,bin"},
+ {"application/gzip", "gz,tgz"},
+ {"application/x-gzip", "gz,tgz"},
+ {"application/pdf", "pdf"},
+ {"application/postscript", "ps,eps,ai"},
+ {"application/javascript", "js"},
+ {"application/font-woff", "woff"},
+ {"image/bmp", "bmp"},
+ {"image/x-icon", "ico"},
+ {"image/vnd.microsoft.icon", "ico"},
+ {"image/jpeg", "jfif,pjpeg,pjp"},
+ {"image/tiff", "tiff,tif"},
+ {"image/x-xbitmap", "xbm"},
+ {"image/svg+xml", "svg,svgz"},
+ {"image/x-png", "png"},
+ {"message/rfc822", "eml"},
+ {"text/plain", "txt,text"},
+ {"text/html", "ehtml"},
+ {"application/rss+xml", "rss"},
+ {"application/rdf+xml", "rdf"},
+ {"text/xml", "xsl,xbl,xslt"},
+ {"application/vnd.mozilla.xul+xml", "xul"},
+ {"application/x-shockwave-flash", "swf,swl"},
+ {"application/pkcs7-mime", "p7m,p7c,p7z"},
+ {"application/pkcs7-signature", "p7s"},
+ {"application/x-mpegurl", "m3u8"},
};
const char* FindMimeType(const MimeInfo* mappings,
@@ -174,7 +176,7 @@ bool MimeUtil::GetMimeTypeFromExtensionHelper(
base::FilePath path_ext(ext);
const string ext_narrow_str = path_ext.AsUTF8Unsafe();
const char* mime_type = FindMimeType(
- primary_mappings, arraysize(primary_mappings), ext_narrow_str);
+ kPrimaryMappings, arraysize(kPrimaryMappings), ext_narrow_str);
if (mime_type) {
*result = mime_type;
return true;
@@ -183,7 +185,7 @@ bool MimeUtil::GetMimeTypeFromExtensionHelper(
if (include_platform_types && GetPlatformMimeTypeFromExtension(ext, result))
return true;
- mime_type = FindMimeType(secondary_mappings, arraysize(secondary_mappings),
+ mime_type = FindMimeType(kSecondaryMappings, arraysize(kSecondaryMappings),
ext_narrow_str);
if (mime_type) {
*result = mime_type;
@@ -490,15 +492,13 @@ void GetExtensionsHelper(
// Also look up the extensions from hard-coded mappings in case that some
// supported extensions are not registered in the system registry, like ogg.
- GetExtensionsFromHardCodedMappings(primary_mappings,
- arraysize(primary_mappings),
- leading_mime_type,
- extensions);
-
- GetExtensionsFromHardCodedMappings(secondary_mappings,
- arraysize(secondary_mappings),
- leading_mime_type,
- extensions);
+ GetExtensionsFromHardCodedMappings(kPrimaryMappings,
+ arraysize(kPrimaryMappings),
+ leading_mime_type, extensions);
+
+ GetExtensionsFromHardCodedMappings(kSecondaryMappings,
+ arraysize(kSecondaryMappings),
+ leading_mime_type, extensions);
}
// Note that the elements in the source set will be appended to the target
@@ -513,6 +513,19 @@ void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) {
(*target)[old_target_size + i] = *iter;
}
+// Characters to be used for mime multipart boundary.
+//
+// TODO(rsleevi): crbug.com/575779: Follow the spec or fix the spec.
+// The RFC 2046 spec says the alphanumeric characters plus the
+// following characters are legal for boundaries: '()+_,-./:=?
+// However the following characters, though legal, cause some sites
+// to fail: (),./:=+
+const char kMimeBoundaryCharacters[] =
+ "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+// Size of mime multipart boundary.
+const size_t kMimeBoundarySize = 69;
+
} // namespace
void GetExtensionsForMimeType(
@@ -547,20 +560,54 @@ void GetExtensionsForMimeType(
// Also look up the extensions from hard-coded mappings in case that some
// supported extensions are not registered in the system registry, like ogg.
- GetExtensionsFromHardCodedMappings(primary_mappings,
- arraysize(primary_mappings),
- mime_type,
+ GetExtensionsFromHardCodedMappings(kPrimaryMappings,
+ arraysize(kPrimaryMappings), mime_type,
&unique_extensions);
- GetExtensionsFromHardCodedMappings(secondary_mappings,
- arraysize(secondary_mappings),
- mime_type,
+ GetExtensionsFromHardCodedMappings(kSecondaryMappings,
+ arraysize(kSecondaryMappings), mime_type,
&unique_extensions);
}
HashSetToVector(&unique_extensions, extensions);
}
+NET_EXPORT std::string GenerateMimeMultipartBoundary() {
+ // Based on RFC 1341, section "7.2.1 Multipart: The common syntax":
+ // Because encapsulation boundaries must not appear in the body parts being
+ // encapsulated, a user agent must exercise care to choose a unique
+ // boundary. The boundary in the example above could have been the result of
+ // an algorithm designed to produce boundaries with a very low probability
+ // of already existing in the data to be encapsulated without having to
+ // prescan the data.
+ // [...]
+ // the boundary parameter [...] consists of 1 to 70 characters from a set of
+ // characters known to be very robust through email gateways, and NOT ending
+ // with white space.
+ // [...]
+ // boundary := 0*69<bchars> bcharsnospace
+ // bchars := bcharsnospace / " "
+ // bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / "+" /
+ // "_" / "," / "-" / "." / "/" / ":" / "=" / "?"
+
+ std::string result;
+ result.reserve(kMimeBoundarySize);
+ result.append("----MultipartBoundary--");
+ while (result.size() < (kMimeBoundarySize - 4)) {
+ // Subtract 2 from the array size to 1) exclude '\0', and 2) turn the size
+ // into the last index.
+ const int last_char_index = sizeof(kMimeBoundaryCharacters) - 2;
+ char c = kMimeBoundaryCharacters[base::RandInt(0, last_char_index)];
+ result.push_back(c);
+ }
+ result.append("----");
+
+ // Not a strict requirement - documentation only.
+ DCHECK_EQ(kMimeBoundarySize, result.size());
+
+ return result;
+}
+
void AddMultipartValueForUpload(const std::string& value_name,
const std::string& value,
const std::string& mime_boundary,
diff --git a/chromium/net/base/mime_util.h b/chromium/net/base/mime_util.h
index 34fcedafaa3..48b9a648af6 100644
--- a/chromium/net/base/mime_util.h
+++ b/chromium/net/base/mime_util.h
@@ -17,6 +17,8 @@
// All constants in mime_util.cc must be written in lower case, except parameter
// values, which can be any case.
+#include <stddef.h>
+
#include <string>
#include <vector>
@@ -98,6 +100,10 @@ enum CertificateMimeType {
CERTIFICATE_MIME_TYPE_PKCS12_ARCHIVE,
};
+// Generates a random MIME multipart boundary.
+// The returned string is guaranteed to be at most 70 characters long.
+NET_EXPORT std::string GenerateMimeMultipartBoundary();
+
// Prepares one value as part of a multi-part upload request.
NET_EXPORT void AddMultipartValueForUpload(const std::string& value_name,
const std::string& value,
diff --git a/chromium/net/base/mime_util_unittest.cc b/chromium/net/base/mime_util_unittest.cc
index 440582be25c..0787d8cda50 100644
--- a/chromium/net/base/mime_util_unittest.cc
+++ b/chromium/net/base/mime_util_unittest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
@@ -274,6 +273,34 @@ TEST(MimeUtilTest, TestGetExtensionsForMimeType) {
}
}
+TEST(MimeUtilTest, TestGenerateMimeMultipartBoundary) {
+ std::string boundary1 = GenerateMimeMultipartBoundary();
+ std::string boundary2 = GenerateMimeMultipartBoundary();
+
+ // RFC 1341 says: the boundary parameter [...] consists of 1 to 70 characters.
+ EXPECT_GE(70u, boundary1.size());
+ EXPECT_GE(70u, boundary2.size());
+
+ // RFC 1341 asks to: exercise care to choose a unique boundary.
+ EXPECT_NE(boundary1, boundary2);
+ ASSERT_LE(16u, boundary1.size());
+ ASSERT_LE(16u, boundary2.size());
+
+ // Expect that we don't pick '\0' character from the array/string
+ // where we take the characters from.
+ EXPECT_EQ(std::string::npos, boundary1.find('\0'));
+ EXPECT_EQ(std::string::npos, boundary2.find('\0'));
+
+ // Asserts below are not RFC 1341 requirements, but are here
+ // to improve readability of generated MIME documents and to
+ // try to preserve some aspects of the old boundary generation code.
+ EXPECT_EQ("--", boundary1.substr(0, 2));
+ EXPECT_EQ("--", boundary2.substr(0, 2));
+ EXPECT_NE(std::string::npos, boundary1.find("MultipartBoundary"));
+ EXPECT_NE(std::string::npos, boundary2.find("MultipartBoundary"));
+ EXPECT_EQ("--", boundary1.substr(boundary1.size() - 2, 2));
+ EXPECT_EQ("--", boundary2.substr(boundary2.size() - 2, 2));
+}
TEST(MimeUtilTest, TestAddMultipartValueForUpload) {
const char ref_output[] =
diff --git a/chromium/net/base/mock_file_stream.cc b/chromium/net/base/mock_file_stream.cc
index c699b463d59..66495329a31 100644
--- a/chromium/net/base/mock_file_stream.cc
+++ b/chromium/net/base/mock_file_stream.cc
@@ -4,6 +4,8 @@
#include "net/base/mock_file_stream.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
@@ -25,12 +27,11 @@ MockFileStream::MockFileStream(
MockFileStream::MockFileStream(
base::File file,
const scoped_refptr<base::TaskRunner>& task_runner)
- : FileStream(file.Pass(), task_runner),
+ : FileStream(std::move(file), task_runner),
forced_error_(OK),
async_error_(false),
throttled_(false),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
MockFileStream::~MockFileStream() {
}
diff --git a/chromium/net/base/mock_file_stream.h b/chromium/net/base/mock_file_stream.h
index 0d188849178..ca5e03063a0 100644
--- a/chromium/net/base/mock_file_stream.h
+++ b/chromium/net/base/mock_file_stream.h
@@ -7,7 +7,8 @@
#ifndef NET_BASE_MOCK_FILE_STREAM_H_
#define NET_BASE_MOCK_FILE_STREAM_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/net/base/net_error_details.h b/chromium/net/base/net_error_details.h
new file mode 100644
index 00000000000..940394efbee
--- /dev/null
+++ b/chromium/net/base/net_error_details.h
@@ -0,0 +1,30 @@
+// Copyright 2015 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_NET_ERROR_DETAILS_H_
+#define NET_BASE_NET_ERROR_DETAILS_H_
+
+#include "net/quic/quic_protocol.h"
+
+namespace net {
+
+// A record of net errors with granular error specification generated by
+// net stack.
+struct NET_EXPORT NetErrorDetails {
+ NetErrorDetails()
+ : quic_broken(false), quic_connection_error(QUIC_NO_ERROR) {}
+
+ NetErrorDetails(bool quic_broken, QuicErrorCode quic_connection_error)
+ : quic_broken(quic_broken),
+ quic_connection_error(quic_connection_error) {}
+
+ // True if all QUIC alternative services are marked broken for the origin.
+ bool quic_broken;
+ // QUIC granular error info.
+ QuicErrorCode quic_connection_error;
+};
+
+} // namespace net
+
+#endif
diff --git a/chromium/net/base/net_error_list.h b/chromium/net/base/net_error_list.h
index ad2c830235a..296024b2b94 100644
--- a/chromium/net/base/net_error_list.h
+++ b/chromium/net/base/net_error_list.h
@@ -357,6 +357,12 @@ NET_ERROR(CT_STH_PARSING_FAILED, -168)
// OK but was missing some of the fields.
NET_ERROR(CT_STH_INCOMPLETE, -169)
+// The attempt to reuse a connection to send proxy auth credentials failed
+// before the AuthController was used to generate credentials. The caller should
+// reuse the controller with a new connection. This error is only used
+// internally by the network stack.
+NET_ERROR(UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH, -170)
+
// Certificate error codes
//
// The values of certificate error codes must be consecutive.
@@ -620,8 +626,9 @@ NET_ERROR(RESPONSE_HEADERS_TRUNCATED, -357)
// to read any requests sent, so they may be resent.
NET_ERROR(QUIC_HANDSHAKE_FAILED, -358)
-// An https resource was requested over an insecure QUIC connection.
-NET_ERROR(REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC, -359)
+// Obsolete. Kept here to avoid reuse, as the old error can still appear on
+// histograms.
+// NET_ERROR(REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC, -359)
// Transport security is inadequate for the SPDY version.
NET_ERROR(SPDY_INADEQUATE_TRANSPORT_SECURITY, -360)
diff --git a/chromium/net/base/net_errors.h b/chromium/net/base/net_errors.h
index a3b6040e853..27a2e51c79f 100644
--- a/chromium/net/base/net_errors.h
+++ b/chromium/net/base/net_errors.h
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file.h"
#include "base/logging.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/net_module.h b/chromium/net/base/net_module.h
index 4ac8ab3a965..40359b25ca4 100644
--- a/chromium/net/base/net_module.h
+++ b/chromium/net/base/net_module.h
@@ -5,7 +5,7 @@
#ifndef NET_BASE_NET_MODULE_H__
#define NET_BASE_NET_MODULE_H__
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/net_util.cc b/chromium/net/base/net_util.cc
index f4dc03b1c08..f89cc991b6d 100644
--- a/chromium/net/base/net_util.cc
+++ b/chromium/net/base/net_util.cc
@@ -4,10 +4,7 @@
#include "net/base/net_util.h"
-#include <errno.h>
-
#include <algorithm>
-#include <limits>
#include <string>
#include "build/build_config.h"
@@ -16,46 +13,27 @@
#include <windows.h>
#include <iphlpapi.h>
#include <winsock2.h>
-#include <ws2bth.h>
#pragma comment(lib, "iphlpapi.lib")
#elif defined(OS_POSIX)
#include <fcntl.h>
#include <netdb.h>
-#include <netinet/in.h>
#include <unistd.h>
-#if !defined(OS_NACL)
-#include <net/if.h>
-#if !defined(OS_ANDROID)
-#include <ifaddrs.h>
-#endif // !defined(OS_NACL)
-#endif // !defined(OS_ANDROID)
#endif // defined(OS_POSIX)
-#include "base/basictypes.h"
-#include "base/json/string_escape.h"
#include "base/logging.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
-#include "base/values.h"
#include "net/base/address_list.h"
-#include "net/base/dns_util.h"
#include "net/base/ip_address_number.h"
-#include "net/base/net_module.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "net/grit/net_resources.h"
-#include "net/http/http_content_disposition.h"
+#include "net/base/url_util.h"
#include "url/gurl.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_canon.h"
#include "url/url_canon_ip.h"
-#if defined(OS_ANDROID)
-#include "net/android/network_library.h"
-#endif
#if defined(OS_WIN)
#include "net/base/winsock_init.h"
#endif
@@ -110,24 +88,6 @@ std::string CanonicalizeHost(const std::string& host,
return canon_host;
}
-std::string GetDirectoryListingHeader(const base::string16& title) {
- static const base::StringPiece header(
- NetModule::GetResource(IDR_DIR_HEADER_HTML));
- // This can be null in unit tests.
- DLOG_IF(WARNING, header.empty()) <<
- "Missing resource: directory listing header";
-
- std::string result;
- if (!header.empty())
- result.assign(header.data(), header.size());
-
- result.append("<script>start(");
- base::EscapeJSONString(title, true, &result);
- result.append(");</script>\n");
-
- return result;
-}
-
inline bool IsHostCharAlphanumeric(char c) {
// We can just check lowercase because uppercase characters have already been
// normalized.
@@ -160,29 +120,6 @@ bool IsCanonicalizedHostCompliant(const std::string& host) {
return most_recent_component_started_alphanumeric;
}
-base::string16 StripWWW(const base::string16& text) {
- const base::string16 www(base::ASCIIToUTF16("www."));
- return base::StartsWith(text, www, base::CompareCase::SENSITIVE)
- ? text.substr(www.length()) : text;
-}
-
-base::string16 StripWWWFromHost(const GURL& url) {
- DCHECK(url.is_valid());
- return StripWWW(base::ASCIIToUTF16(url.host_piece()));
-}
-
-int SetNonBlocking(int fd) {
-#if defined(OS_WIN)
- unsigned long no_block = 1;
- return ioctlsocket(fd, FIONBIO, &no_block);
-#elif defined(OS_POSIX)
- int flags = fcntl(fd, F_GETFL, 0);
- if (-1 == flags)
- return flags;
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-#endif
-}
-
bool ParseHostAndPort(std::string::const_iterator host_and_port_begin,
std::string::const_iterator host_and_port_end,
std::string* host,
@@ -315,90 +252,6 @@ bool IsHostnameNonUnique(const std::string& hostname) {
registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
}
-SockaddrStorage::SockaddrStorage(const SockaddrStorage& other)
- : addr_len(other.addr_len),
- addr(reinterpret_cast<struct sockaddr*>(&addr_storage)) {
- memcpy(addr, other.addr, addr_len);
-}
-
-void SockaddrStorage::operator=(const SockaddrStorage& other) {
- addr_len = other.addr_len;
- // addr is already set to &this->addr_storage by default ctor.
- memcpy(addr, other.addr, addr_len);
-}
-
-// Extracts the address and port portions of a sockaddr.
-bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr,
- socklen_t sock_addr_len,
- const uint8_t** address,
- size_t* address_len,
- uint16_t* port) {
- if (sock_addr->sa_family == AF_INET) {
- if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in)))
- return false;
- const struct sockaddr_in* addr =
- reinterpret_cast<const struct sockaddr_in*>(sock_addr);
- *address = reinterpret_cast<const uint8_t*>(&addr->sin_addr);
- *address_len = kIPv4AddressSize;
- if (port)
- *port = base::NetToHost16(addr->sin_port);
- return true;
- }
-
- if (sock_addr->sa_family == AF_INET6) {
- if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in6)))
- return false;
- const struct sockaddr_in6* addr =
- reinterpret_cast<const struct sockaddr_in6*>(sock_addr);
- *address = reinterpret_cast<const uint8_t*>(&addr->sin6_addr);
- *address_len = kIPv6AddressSize;
- if (port)
- *port = base::NetToHost16(addr->sin6_port);
- return true;
- }
-
-#if defined(OS_WIN)
- if (sock_addr->sa_family == AF_BTH) {
- if (sock_addr_len < static_cast<socklen_t>(sizeof(SOCKADDR_BTH)))
- return false;
- const SOCKADDR_BTH* addr =
- reinterpret_cast<const SOCKADDR_BTH*>(sock_addr);
- *address = reinterpret_cast<const uint8_t*>(&addr->btAddr);
- *address_len = kBluetoothAddressSize;
- if (port)
- *port = static_cast<uint16_t>(addr->port);
- return true;
- }
-#endif
-
- return false; // Unrecognized |sa_family|.
-}
-
-std::string NetAddressToString(const struct sockaddr* sa,
- socklen_t sock_addr_len) {
- const uint8_t* address;
- size_t address_len;
- if (!GetIPAddressFromSockAddr(sa, sock_addr_len, &address,
- &address_len, NULL)) {
- NOTREACHED();
- return std::string();
- }
- return IPAddressToString(address, address_len);
-}
-
-std::string NetAddressToStringWithPort(const struct sockaddr* sa,
- socklen_t sock_addr_len) {
- const uint8_t* address;
- size_t address_len;
- uint16_t port;
- if (!GetIPAddressFromSockAddr(sa, sock_addr_len, &address,
- &address_len, &port)) {
- NOTREACHED();
- return std::string();
- }
- return IPAddressToStringWithPort(address, address_len, port);
-}
-
std::string GetHostName() {
#if defined(OS_NACL)
NOTIMPLEMENTED();
@@ -419,15 +272,6 @@ std::string GetHostName() {
#endif // !defined(OS_NACL)
}
-void GetIdentityFromURL(const GURL& url,
- base::string16* username,
- base::string16* password) {
- UnescapeRule::Type flags =
- UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS;
- *username = UnescapeAndDecodeUTF8URLComponent(url.username(), flags);
- *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags);
-}
-
std::string GetHostOrSpecFromURL(const GURL& url) {
return url.has_host() ? TrimEndingDot(url.host_piece()) : url.spec();
}
@@ -441,106 +285,6 @@ GURL SimplifyUrlForRequest(const GURL& url) {
return url.ReplaceComponents(replacements);
}
-bool HaveOnlyLoopbackAddresses() {
-#if defined(OS_ANDROID)
- return android::HaveOnlyLoopbackAddresses();
-#elif defined(OS_NACL)
- NOTIMPLEMENTED();
- return false;
-#elif defined(OS_POSIX)
- struct ifaddrs* interface_addr = NULL;
- int rv = getifaddrs(&interface_addr);
- if (rv != 0) {
- DVLOG(1) << "getifaddrs() failed with errno = " << errno;
- return false;
- }
-
- bool result = true;
- for (struct ifaddrs* interface = interface_addr;
- interface != NULL;
- interface = interface->ifa_next) {
- if (!(IFF_UP & interface->ifa_flags))
- continue;
- if (IFF_LOOPBACK & interface->ifa_flags)
- continue;
- const struct sockaddr* addr = interface->ifa_addr;
- if (!addr)
- continue;
- if (addr->sa_family == AF_INET6) {
- // Safe cast since this is AF_INET6.
- const struct sockaddr_in6* addr_in6 =
- reinterpret_cast<const struct sockaddr_in6*>(addr);
- const struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
- if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr))
- continue;
- }
- if (addr->sa_family != AF_INET6 && addr->sa_family != AF_INET)
- continue;
-
- result = false;
- break;
- }
- freeifaddrs(interface_addr);
- return result;
-#elif defined(OS_WIN)
- // TODO(wtc): implement with the GetAdaptersAddresses function.
- NOTIMPLEMENTED();
- return false;
-#else
- NOTIMPLEMENTED();
- return false;
-#endif // defined(various platforms)
-}
-
-AddressFamily GetAddressFamily(const IPAddressNumber& address) {
- switch (address.size()) {
- case kIPv4AddressSize:
- return ADDRESS_FAMILY_IPV4;
- case kIPv6AddressSize:
- return ADDRESS_FAMILY_IPV6;
- default:
- return ADDRESS_FAMILY_UNSPECIFIED;
- }
-}
-
-int ConvertAddressFamily(AddressFamily address_family) {
- switch (address_family) {
- case ADDRESS_FAMILY_UNSPECIFIED:
- return AF_UNSPEC;
- case ADDRESS_FAMILY_IPV4:
- return AF_INET;
- case ADDRESS_FAMILY_IPV6:
- return AF_INET6;
- }
- NOTREACHED();
- return AF_UNSPEC;
-}
-
-const uint16_t* GetPortFieldFromSockaddr(const struct sockaddr* address,
- socklen_t address_len) {
- if (address->sa_family == AF_INET) {
- DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len));
- const struct sockaddr_in* sockaddr =
- reinterpret_cast<const struct sockaddr_in*>(address);
- return &sockaddr->sin_port;
- } else if (address->sa_family == AF_INET6) {
- DCHECK_LE(sizeof(sockaddr_in6), static_cast<size_t>(address_len));
- const struct sockaddr_in6* sockaddr =
- reinterpret_cast<const struct sockaddr_in6*>(address);
- return &sockaddr->sin6_port;
- } else {
- NOTREACHED();
- return NULL;
- }
-}
-
-int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
- const uint16_t* port_field = GetPortFieldFromSockaddr(address, address_len);
- if (!port_field)
- return -1;
- return base::NetToHost16(*port_field);
-}
-
bool ResolveLocalHostname(base::StringPiece host,
uint16_t port,
AddressList* address_list) {
@@ -602,10 +346,6 @@ bool IsLocalhost(base::StringPiece host) {
return false;
}
-bool IsLocalhostTLD(base::StringPiece host) {
- return IsNormalizedLocalhostTLD(NormalizeHostname(host));
-}
-
bool HasGoogleHost(const GURL& url) {
static const char* kGoogleHostSuffixes[] = {
".google.com",
diff --git a/chromium/net/base/net_util.h b/chromium/net/base/net_util.h
index 837d9e2a750..1bf6510122c 100644
--- a/chromium/net/base/net_util.h
+++ b/chromium/net/base/net_util.h
@@ -5,51 +5,25 @@
#ifndef NET_BASE_NET_UTIL_H_
#define NET_BASE_NET_UTIL_H_
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#include <ws2tcpip.h>
-#elif defined(OS_POSIX)
-#include <sys/types.h>
-#include <sys/socket.h>
-#endif
+#include <stddef.h>
+#include <stdint.h>
#include <string>
#include <vector>
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_offset_string_conversions.h"
-#include "net/base/address_family.h"
-#include "net/base/escape.h"
+#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
-#include "net/base/network_change_notifier.h"
class GURL;
-namespace base {
-class Time;
-}
-
namespace url {
struct CanonHostInfo;
-struct Parsed;
}
namespace net {
class AddressList;
-// This is a "forward declaration" to avoid including ip_address_number.h
-// Keep this in sync.
-typedef std::vector<unsigned char> IPAddressNumber;
-
-#if defined(OS_WIN)
-// Bluetooth address size. Windows Bluetooth is supported via winsock.
-static const size_t kBluetoothAddressSize = 6;
-#endif
-
// Splits an input of the form <host>[":"<port>] into its consitituent parts.
// Saves the result into |*host| and |*port|. If the input did not have
// the optional port, sets |*port| to -1.
@@ -75,52 +49,16 @@ NET_EXPORT std::string GetHostAndPort(const GURL& url);
// Returns a host[:port] string for the given URL, where the port is omitted
// if it is the default for the URL's scheme.
-NET_EXPORT_PRIVATE std::string GetHostAndOptionalPort(const GURL& url);
+NET_EXPORT std::string GetHostAndOptionalPort(const GURL& url);
// 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.
NET_EXPORT bool IsHostnameNonUnique(const std::string& hostname);
-// Convenience struct for when you need a |struct sockaddr|.
-struct SockaddrStorage {
- SockaddrStorage() : addr_len(sizeof(addr_storage)),
- addr(reinterpret_cast<struct sockaddr*>(&addr_storage)) {}
- SockaddrStorage(const SockaddrStorage& other);
- void operator=(const SockaddrStorage& other);
-
- struct sockaddr_storage addr_storage;
- socklen_t addr_len;
- struct sockaddr* const addr;
-};
-
-// Extracts the IP address and port portions of a sockaddr. |port| is optional,
-// and will not be filled in if NULL.
-bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr,
- socklen_t sock_addr_len,
- const unsigned char** address,
- size_t* address_len,
- uint16_t* port);
-
-// Same as IPAddressToString() but for a sockaddr. This output will not include
-// the IPv6 scope ID.
-NET_EXPORT std::string NetAddressToString(const struct sockaddr* sa,
- socklen_t sock_addr_len);
-
-// Same as IPAddressToStringWithPort() but for a sockaddr. This output will not
-// include the IPv6 scope ID.
-NET_EXPORT std::string NetAddressToStringWithPort(const struct sockaddr* sa,
- socklen_t sock_addr_len);
-
// Returns the hostname of the current system. Returns empty string on failure.
NET_EXPORT std::string GetHostName();
-// Extracts the unescaped username/password from |url|, saving the results
-// into |*username| and |*password|.
-NET_EXPORT_PRIVATE void GetIdentityFromURL(const GURL& url,
- base::string16* username,
- base::string16* password);
-
// Returns either the host from |url|, or, if the host is empty, the full spec.
NET_EXPORT std::string GetHostOrSpecFromURL(const GURL& url);
@@ -141,61 +79,10 @@ NET_EXPORT std::string CanonicalizeHost(const std::string& host,
// CanonicalizeHost(), or you may not get accurate results.
NET_EXPORT bool IsCanonicalizedHostCompliant(const std::string& host);
-// Call these functions to get the html snippet for a directory listing.
-// The return values of both functions are in UTF-8.
-NET_EXPORT std::string GetDirectoryListingHeader(const base::string16& title);
-
-// Given the name of a file in a directory (ftp or local) and
-// other information (is_dir, size, modification time), it returns
-// the html snippet to add the entry for the file to the directory listing.
-// Currently, it's a script tag containing a call to a Javascript function
-// |addRow|.
-//
-// |name| is the file name to be displayed. |raw_bytes| will be used
-// as the actual target of the link (so for example, ftp links should use
-// server's encoding). If |raw_bytes| is an empty string, UTF-8 encoded |name|
-// will be used.
-//
-// Both |name| and |raw_bytes| are escaped internally.
-NET_EXPORT std::string GetDirectoryListingEntry(const base::string16& name,
- const std::string& raw_bytes,
- bool is_dir,
- int64_t size,
- base::Time modified);
-
-// If text starts with "www." it is removed, otherwise text is returned
-// unmodified.
-NET_EXPORT base::string16 StripWWW(const base::string16& text);
-
-// Runs |url|'s host through StripWWW(). |url| must be valid.
-NET_EXPORT base::string16 StripWWWFromHost(const GURL& url);
-
-// Set socket to non-blocking mode
-NET_EXPORT int SetNonBlocking(int fd);
-
// Strip the portions of |url| that aren't core to the network request.
// - user name / password
// - reference section
-NET_EXPORT_PRIVATE GURL SimplifyUrlForRequest(const GURL& url);
-
-// Returns true if it can determine that only loopback addresses are configured.
-// i.e. if only 127.0.0.1 and ::1 are routable.
-// Also returns false if it cannot determine this.
-bool HaveOnlyLoopbackAddresses();
-
-// Returns AddressFamily of the address.
-NET_EXPORT_PRIVATE AddressFamily GetAddressFamily(
- const IPAddressNumber& address);
-
-// Maps the given AddressFamily to either AF_INET, AF_INET6 or AF_UNSPEC.
-NET_EXPORT_PRIVATE int ConvertAddressFamily(AddressFamily address_family);
-
-// Retuns the port field of the |sockaddr|.
-const uint16_t* GetPortFieldFromSockaddr(const struct sockaddr* address,
- socklen_t address_len);
-// Returns the value of port in |sockaddr| (in host byte ordering).
-NET_EXPORT_PRIVATE int GetPortFromSockaddr(const struct sockaddr* address,
- socklen_t address_len);
+NET_EXPORT GURL SimplifyUrlForRequest(const GURL& url);
// Resolves a local hostname (such as "localhost" or "localhost6") into
// IP endpoints with the given port. Returns true if |host| is a local
@@ -212,62 +99,12 @@ NET_EXPORT_PRIVATE bool ResolveLocalHostname(base::StringPiece host,
// Note that this function does not check for IP addresses other than
// the above, although other IP addresses may point to the local
// machine.
-NET_EXPORT_PRIVATE bool IsLocalhost(base::StringPiece host);
-
-NET_EXPORT_PRIVATE bool IsLocalhostTLD(base::StringPiece host);
+NET_EXPORT bool IsLocalhost(base::StringPiece host);
// Returns true if the url's host is a Google server. This should only be used
// for histograms and shouldn't be used to affect behavior.
NET_EXPORT_PRIVATE bool HasGoogleHost(const GURL& url);
-// A subset of IP address attributes which are actionable by the
-// application layer. Currently unimplemented for all hosts;
-// IP_ADDRESS_ATTRIBUTE_NONE is always returned.
-enum IPAddressAttributes {
- IP_ADDRESS_ATTRIBUTE_NONE = 0,
-
- // A temporary address is dynamic by nature and will not contain MAC
- // address. Presence of MAC address in IPv6 addresses can be used to
- // track an endpoint and cause privacy concern. Please refer to
- // RFC4941.
- IP_ADDRESS_ATTRIBUTE_TEMPORARY = 1 << 0,
-
- // A temporary address could become deprecated once the preferred
- // lifetime is reached. It is still valid but shouldn't be used to
- // create new connections.
- IP_ADDRESS_ATTRIBUTE_DEPRECATED = 1 << 1,
-};
-
-// Differentiated Services Code Point.
-// See http://tools.ietf.org/html/rfc2474 for details.
-enum DiffServCodePoint {
- DSCP_NO_CHANGE = -1,
- DSCP_FIRST = DSCP_NO_CHANGE,
- DSCP_DEFAULT = 0, // Same as DSCP_CS0
- DSCP_CS0 = 0, // The default
- DSCP_CS1 = 8, // Bulk/background traffic
- DSCP_AF11 = 10,
- DSCP_AF12 = 12,
- DSCP_AF13 = 14,
- DSCP_CS2 = 16,
- DSCP_AF21 = 18,
- DSCP_AF22 = 20,
- DSCP_AF23 = 22,
- DSCP_CS3 = 24,
- DSCP_AF31 = 26,
- DSCP_AF32 = 28,
- DSCP_AF33 = 30,
- DSCP_CS4 = 32,
- DSCP_AF41 = 34, // Video
- DSCP_AF42 = 36, // Video
- DSCP_AF43 = 38, // Video
- DSCP_CS5 = 40, // Video
- DSCP_EF = 46, // Voice
- DSCP_CS6 = 48, // Voice
- DSCP_CS7 = 56, // Control messages
- DSCP_LAST = DSCP_CS7
-};
-
} // namespace net
#endif // NET_BASE_NET_UTIL_H_
diff --git a/chromium/net/base/net_util_unittest.cc b/chromium/net/base/net_util_unittest.cc
index fdb49a3c020..b92244a74c6 100644
--- a/chromium/net/base/net_util_unittest.cc
+++ b/chromium/net/base/net_util_unittest.cc
@@ -4,21 +4,16 @@
#include "net/base/net_util.h"
-#include <string.h>
-
#include <ostream>
-#include "base/files/file_path.h"
#include "base/format_macros.h"
-#include "base/scoped_native_library.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/sys_byteorder.h"
-#include "base/time/time.h"
#include "net/base/address_list.h"
#include "net/base/ip_endpoint.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
#if !defined(OS_NACL) && !defined(OS_WIN)
#include <net/if.h>
@@ -30,58 +25,20 @@
#endif // !OS_IOS
#endif // OS_MACOSX
#endif // !OS_NACL && !OS_WIN
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-#if defined(OS_WIN)
-#include <iphlpapi.h>
-#include <objbase.h>
-#include "base/win/windows_version.h"
-#endif // OS_WIN
#if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_WIN)
#include "net/base/address_tracker_linux.h"
#endif // !OS_MACOSX && !OS_NACL && !OS_WIN
-using base::ASCIIToUTF16;
-using base::WideToUTF16;
-
namespace net {
namespace {
-struct HeaderCase {
- const char* const header_name;
- const char* const expected;
-};
-
const unsigned char kLocalhostIPv4[] = {127, 0, 0, 1};
const unsigned char kLocalhostIPv6[] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
const uint16_t kLocalhostLookupPort = 80;
-// Fills in sockaddr for the given 32-bit address (IPv4.)
-// |bytes| should be an array of length 4.
-void MakeIPv4Address(const uint8_t* bytes, int port, SockaddrStorage* storage) {
- memset(&storage->addr_storage, 0, sizeof(storage->addr_storage));
- storage->addr_len = sizeof(struct sockaddr_in);
- struct sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(storage->addr);
- addr4->sin_port = base::HostToNet16(port);
- addr4->sin_family = AF_INET;
- memcpy(&addr4->sin_addr, bytes, 4);
-}
-
-// Fills in sockaddr for the given 128-bit address (IPv6.)
-// |bytes| should be an array of length 16.
-void MakeIPv6Address(const uint8_t* bytes, int port, SockaddrStorage* storage) {
- memset(&storage->addr_storage, 0, sizeof(storage->addr_storage));
- storage->addr_len = sizeof(struct sockaddr_in6);
- struct sockaddr_in6* addr6 = reinterpret_cast<sockaddr_in6*>(storage->addr);
- addr6->sin6_port = base::HostToNet16(port);
- addr6->sin6_family = AF_INET6;
- memcpy(&addr6->sin6_addr, bytes, 16);
-}
-
bool HasEndpoint(const IPEndPoint& endpoint, const AddressList& addresses) {
for (const auto& address : addresses) {
if (endpoint == address)
@@ -121,84 +78,11 @@ void TestIPv6LoopbackOnly(const std::string& host) {
} // anonymous namespace
-TEST(NetUtilTest, GetIdentityFromURL) {
- struct {
- const char* const input_url;
- const char* const expected_username;
- const char* const expected_password;
- } tests[] = {
- {
- "http://username:password@google.com",
- "username",
- "password",
- },
- { // Test for http://crbug.com/19200
- "http://username:p@ssword@google.com",
- "username",
- "p@ssword",
- },
- { // Special URL characters should be unescaped.
- "http://username:p%3fa%26s%2fs%23@google.com",
- "username",
- "p?a&s/s#",
- },
- { // Username contains %20.
- "http://use rname:password@google.com",
- "use rname",
- "password",
- },
- { // Keep %00 as is.
- "http://use%00rname:password@google.com",
- "use%00rname",
- "password",
- },
- { // Use a '+' in the username.
- "http://use+rname:password@google.com",
- "use+rname",
- "password",
- },
- { // Use a '&' in the password.
- "http://username:p&ssword@google.com",
- "username",
- "p&ssword",
- },
- };
- for (size_t i = 0; i < arraysize(tests); ++i) {
- SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
- tests[i].input_url));
- GURL url(tests[i].input_url);
-
- base::string16 username, password;
- GetIdentityFromURL(url, &username, &password);
-
- EXPECT_EQ(ASCIIToUTF16(tests[i].expected_username), username);
- EXPECT_EQ(ASCIIToUTF16(tests[i].expected_password), password);
- }
-}
-
-// Try extracting a username which was encoded with UTF8.
-TEST(NetUtilTest, GetIdentityFromURL_UTF8) {
- GURL url(WideToUTF16(L"http://foo:\x4f60\x597d@blah.com"));
-
- EXPECT_EQ("foo", url.username());
- EXPECT_EQ("%E4%BD%A0%E5%A5%BD", url.password());
-
- // Extract the unescaped identity.
- base::string16 username, password;
- GetIdentityFromURL(url, &username, &password);
-
- // Verify that it was decoded as UTF8.
- EXPECT_EQ(ASCIIToUTF16("foo"), username);
- EXPECT_EQ(WideToUTF16(L"\x4f60\x597d"), password);
-}
-
TEST(NetUtilTest, CompliantHost) {
- struct CompliantHostCase {
+ struct {
const char* const host;
bool expected_output;
- };
-
- const CompliantHostCase compliant_host_cases[] = {
+ } compliant_host_cases[] = {
{"", false},
{"a", true},
{"-", false},
@@ -327,66 +211,6 @@ TEST(NetUtilTest, GetHostAndOptionalPort) {
}
}
-TEST(NetUtilTest, NetAddressToString_IPv4) {
- const struct {
- uint8_t addr[4];
- const char* const result;
- } tests[] = {
- {{0, 0, 0, 0}, "0.0.0.0"},
- {{127, 0, 0, 1}, "127.0.0.1"},
- {{192, 168, 0, 1}, "192.168.0.1"},
- };
-
- for (size_t i = 0; i < arraysize(tests); ++i) {
- SockaddrStorage storage;
- MakeIPv4Address(tests[i].addr, 80, &storage);
- std::string result = NetAddressToString(storage.addr, storage.addr_len);
- EXPECT_EQ(std::string(tests[i].result), result);
- }
-}
-
-TEST(NetUtilTest, NetAddressToString_IPv6) {
- const struct {
- uint8_t addr[16];
- const char* const result;
- } tests[] = {
- {{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA,
- 0x98, 0x76, 0x54, 0x32, 0x10},
- "fedc:ba98:7654:3210:fedc:ba98:7654:3210"},
- };
-
- for (size_t i = 0; i < arraysize(tests); ++i) {
- SockaddrStorage storage;
- MakeIPv6Address(tests[i].addr, 80, &storage);
- EXPECT_EQ(std::string(tests[i].result),
- NetAddressToString(storage.addr, storage.addr_len));
- }
-}
-
-TEST(NetUtilTest, NetAddressToStringWithPort_IPv4) {
- uint8_t addr[] = {127, 0, 0, 1};
- SockaddrStorage storage;
- MakeIPv4Address(addr, 166, &storage);
- std::string result = NetAddressToStringWithPort(storage.addr,
- storage.addr_len);
- EXPECT_EQ("127.0.0.1:166", result);
-}
-
-TEST(NetUtilTest, NetAddressToStringWithPort_IPv6) {
- uint8_t addr[] = {
- 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA,
- 0x98, 0x76, 0x54, 0x32, 0x10
- };
- SockaddrStorage storage;
- MakeIPv6Address(addr, 361, &storage);
- std::string result = NetAddressToStringWithPort(storage.addr,
- storage.addr_len);
-
- // May fail on systems that don't support IPv6.
- if (!result.empty())
- EXPECT_EQ("[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:361", result);
-}
-
TEST(NetUtilTest, GetHostName) {
// We can't check the result of GetHostName() directly, since the result
// will differ across machines. Our goal here is to simply exercise the
@@ -449,14 +273,6 @@ TEST(NetUtilTest, GetHostOrSpecFromURL) {
GetHostOrSpecFromURL(GURL("file:///tmp/test.html")));
}
-TEST(NetUtilTest, GetAddressFamily) {
- IPAddressNumber number;
- EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &number));
- EXPECT_EQ(ADDRESS_FAMILY_IPV4, GetAddressFamily(number));
- EXPECT_TRUE(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number));
- EXPECT_EQ(ADDRESS_FAMILY_IPV6, GetAddressFamily(number));
-}
-
TEST(NetUtilTest, IsLocalhost) {
EXPECT_TRUE(IsLocalhost("localhost"));
EXPECT_TRUE(IsLocalhost("localHosT"));
@@ -479,6 +295,8 @@ TEST(NetUtilTest, IsLocalhost) {
EXPECT_TRUE(IsLocalhost("0:0:0:0:0:0:0:1"));
EXPECT_TRUE(IsLocalhost("foo.localhost"));
EXPECT_TRUE(IsLocalhost("foo.localhost."));
+ EXPECT_TRUE(IsLocalhost("foo.localhoST"));
+ EXPECT_TRUE(IsLocalhost("foo.localhoST."));
EXPECT_FALSE(IsLocalhost("localhostx"));
EXPECT_FALSE(IsLocalhost("localhost.x"));
@@ -496,6 +314,7 @@ TEST(NetUtilTest, IsLocalhost) {
EXPECT_FALSE(IsLocalhost("0:0:0:0:0:0:0:0:1"));
EXPECT_FALSE(IsLocalhost("foo.localhost.com"));
EXPECT_FALSE(IsLocalhost("foo.localhoste"));
+ EXPECT_FALSE(IsLocalhost("foo.localhos"));
}
TEST(NetUtilTest, ResolveLocalHostname) {
@@ -556,23 +375,11 @@ TEST(NetUtilTest, ResolveLocalHostname) {
ResolveLocalHostname("foo.localhoste", kLocalhostLookupPort, &addresses));
}
-TEST(NetUtilTest, IsLocalhostTLD) {
- EXPECT_TRUE(IsLocalhostTLD("foo.localhost"));
- EXPECT_TRUE(IsLocalhostTLD("foo.localhoST"));
- EXPECT_TRUE(IsLocalhostTLD("foo.localhost."));
- EXPECT_TRUE(IsLocalhostTLD("foo.localhoST."));
- EXPECT_FALSE(IsLocalhostTLD("foo.localhos"));
- EXPECT_FALSE(IsLocalhostTLD("foo.localhost.com"));
- EXPECT_FALSE(IsLocalhost("foo.localhoste"));
-}
-
TEST(NetUtilTest, GoogleHost) {
- struct GoogleHostCase {
+ struct {
GURL url;
bool expected_output;
- };
-
- const GoogleHostCase google_host_cases[] = {
+ } google_host_cases[] = {
{GURL("http://.google.com"), true},
{GURL("http://.youtube.com"), true},
{GURL("http://.gmail.com"), true},
diff --git a/chromium/net/base/network_activity_monitor.h b/chromium/net/base/network_activity_monitor.h
index 53194773201..7f3dbedb046 100644
--- a/chromium/net/base/network_activity_monitor.h
+++ b/chromium/net/base/network_activity_monitor.h
@@ -5,8 +5,10 @@
#ifndef NET_BASE_NETWORK_ACTIVITY_MONITOR_H_
#define NET_BASE_NETWORK_ACTIVITY_MONITOR_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/network_change_notifier.cc b/chromium/net/base/network_change_notifier.cc
index b86b79c90d5..52e5ce34c21 100644
--- a/chromium/net/base/network_change_notifier.cc
+++ b/chromium/net/base/network_change_notifier.cc
@@ -6,6 +6,7 @@
#include <limits>
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
@@ -56,6 +57,9 @@ class MockNetworkChangeNotifier : public NetworkChangeNotifier {
// static
bool NetworkChangeNotifier::test_notifications_only_ = false;
+// static
+const NetworkChangeNotifier::NetworkHandle
+ NetworkChangeNotifier::kInvalidNetworkHandle = -1;
// The main observer class that records UMAs for network events.
class HistogramWatcher
@@ -631,6 +635,43 @@ double NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype(
}
// static
+bool NetworkChangeNotifier::AreNetworkHandlesSupported() {
+ if (g_network_change_notifier) {
+ return g_network_change_notifier->AreNetworkHandlesCurrentlySupported();
+ }
+ return false;
+}
+
+// static
+void NetworkChangeNotifier::GetConnectedNetworks(NetworkList* network_list) {
+ DCHECK(AreNetworkHandlesSupported());
+ if (g_network_change_notifier) {
+ g_network_change_notifier->GetCurrentConnectedNetworks(network_list);
+ } else {
+ network_list->clear();
+ }
+}
+
+// static
+NetworkChangeNotifier::ConnectionType
+NetworkChangeNotifier::GetNetworkConnectionType(NetworkHandle network) {
+ DCHECK(AreNetworkHandlesSupported());
+ return g_network_change_notifier
+ ? g_network_change_notifier->GetCurrentNetworkConnectionType(
+ network)
+ : CONNECTION_UNKNOWN;
+}
+
+// static
+NetworkChangeNotifier::NetworkHandle
+NetworkChangeNotifier::GetDefaultNetwork() {
+ DCHECK(AreNetworkHandlesSupported());
+ return g_network_change_notifier
+ ? g_network_change_notifier->GetCurrentDefaultNetwork()
+ : kInvalidNetworkHandle;
+}
+
+// static
void NetworkChangeNotifier::GetDnsConfig(DnsConfig* config) {
if (!g_network_change_notifier) {
*config = DnsConfig();
@@ -808,6 +849,13 @@ void NetworkChangeNotifier::AddMaxBandwidthObserver(
}
}
+void NetworkChangeNotifier::AddNetworkObserver(NetworkObserver* observer) {
+ DCHECK(AreNetworkHandlesSupported());
+ if (g_network_change_notifier) {
+ g_network_change_notifier->network_observer_list_->AddObserver(observer);
+ }
+}
+
void NetworkChangeNotifier::RemoveIPAddressObserver(
IPAddressObserver* observer) {
if (g_network_change_notifier) {
@@ -847,6 +895,13 @@ void NetworkChangeNotifier::RemoveMaxBandwidthObserver(
}
}
+void NetworkChangeNotifier::RemoveNetworkObserver(NetworkObserver* observer) {
+ DCHECK(AreNetworkHandlesSupported());
+ if (g_network_change_notifier) {
+ g_network_change_notifier->network_observer_list_->RemoveObserver(observer);
+ }
+}
+
// static
void NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests() {
if (g_network_change_notifier)
@@ -908,6 +963,8 @@ NetworkChangeNotifier::NetworkChangeNotifier(
max_bandwidth_observer_list_(new base::ObserverListThreadSafe<
MaxBandwidthObserver>(
base::ObserverListBase<MaxBandwidthObserver>::NOTIFY_EXISTING_ONLY)),
+ network_observer_list_(new base::ObserverListThreadSafe<NetworkObserver>(
+ base::ObserverListBase<NetworkObserver>::NOTIFY_EXISTING_ONLY)),
network_state_(new NetworkState()),
network_change_calculator_(new NetworkChangeCalculator(params)) {
DCHECK(!g_network_change_notifier);
@@ -935,6 +992,26 @@ void NetworkChangeNotifier::GetCurrentMaxBandwidthAndConnectionType(
: GetMaxBandwidthForConnectionSubtype(SUBTYPE_UNKNOWN);
}
+bool NetworkChangeNotifier::AreNetworkHandlesCurrentlySupported() const {
+ return false;
+}
+
+void NetworkChangeNotifier::GetCurrentConnectedNetworks(
+ NetworkList* network_list) const {
+ network_list->clear();
+}
+
+NetworkChangeNotifier::ConnectionType
+NetworkChangeNotifier::GetCurrentNetworkConnectionType(
+ NetworkHandle network) const {
+ return CONNECTION_UNKNOWN;
+}
+
+NetworkChangeNotifier::NetworkHandle
+NetworkChangeNotifier::GetCurrentDefaultNetwork() const {
+ return kInvalidNetworkHandle;
+}
+
// static
void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() {
if (g_network_change_notifier &&
@@ -989,6 +1066,17 @@ void NetworkChangeNotifier::NotifyObserversOfInitialDNSConfigRead() {
}
// static
+void NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
+ NetworkChangeType type,
+ NetworkHandle network) {
+ if (g_network_change_notifier &&
+ !NetworkChangeNotifier::test_notifications_only_) {
+ g_network_change_notifier->NotifyObserversOfSpecificNetworkChangeImpl(
+ type, network);
+ }
+}
+
+// static
void NetworkChangeNotifier::SetDnsConfig(const DnsConfig& config) {
if (!g_network_change_notifier)
return;
@@ -1044,6 +1132,29 @@ void NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChangeImpl(
max_bandwidth_mbps, type);
}
+void NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChangeImpl(
+ NetworkChangeType type,
+ NetworkHandle network) {
+ switch (type) {
+ case CONNECTED:
+ network_observer_list_->Notify(
+ FROM_HERE, &NetworkObserver::OnNetworkConnected, network);
+ break;
+ case DISCONNECTED:
+ network_observer_list_->Notify(
+ FROM_HERE, &NetworkObserver::OnNetworkDisconnected, network);
+ break;
+ case SOON_TO_DISCONNECT:
+ network_observer_list_->Notify(
+ FROM_HERE, &NetworkObserver::OnNetworkSoonToDisconnect, network);
+ break;
+ case MADE_DEFAULT:
+ network_observer_list_->Notify(
+ FROM_HERE, &NetworkObserver::OnNetworkMadeDefault, network);
+ break;
+ }
+}
+
NetworkChangeNotifier::DisableForTest::DisableForTest()
: network_change_notifier_(g_network_change_notifier) {
DCHECK(g_network_change_notifier);
diff --git a/chromium/net/base/network_change_notifier.h b/chromium/net/base/network_change_notifier.h
index 143abdcb6a7..f532889b0af 100644
--- a/chromium/net/base/network_change_notifier.h
+++ b/chromium/net/base/network_change_notifier.h
@@ -5,9 +5,11 @@
#ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
#define NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/observer_list_threadsafe.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
@@ -202,12 +204,49 @@ class NET_EXPORT NetworkChangeNotifier {
DISALLOW_COPY_AND_ASSIGN(MaxBandwidthObserver);
};
- virtual ~NetworkChangeNotifier();
+ // Opaque handle for device-wide connection to a particular network. For
+ // example an association with a particular WiFi network with a particular
+ // SSID or a connection to particular cellular network.
+ // The meaning of this handle is target-dependent. On Android NetworkHandles
+ // are equivalent to the framework's concept of NetIDs (e.g. Network.netId).
+ typedef int32_t NetworkHandle;
+
+ // A list of networks.
+ typedef std::vector<NetworkHandle> NetworkList;
+
+ // An interface that when implemented and added via AddNeworkObserver(),
+ // provides notifications when networks come and go.
+ // Only implemented for Android (Lollipop and newer), no callbacks issued when
+ // unimplemented.
+ class NET_EXPORT NetworkObserver {
+ public:
+ // Called when device connects to |network|. For example device associates
+ // with a WiFi access point. This does not imply the network has Internet
+ // access as it may well be behind a captive portal.
+ virtual void OnNetworkConnected(NetworkHandle network) = 0;
+ // Called when device disconnects from |network|.
+ virtual void OnNetworkDisconnected(NetworkHandle network) = 0;
+ // Called when device determines the connection to |network| is no longer
+ // preferred, for example when a device transitions from cellular to WiFi
+ // it might deem the cellular connection no longer preferred. The device
+ // will disconnect from |network| in a period of time (30s on Android),
+ // allowing network communications via |network| to wrap up.
+ virtual void OnNetworkSoonToDisconnect(NetworkHandle network) = 0;
+ // Called when |network| is made the default network for communication.
+ virtual void OnNetworkMadeDefault(NetworkHandle network) = 0;
- // See the description of NetworkChangeNotifier::GetConnectionType().
- // Implementations must be thread-safe. Implementations must also be
- // cheap as it is called often.
- virtual ConnectionType GetCurrentConnectionType() const = 0;
+ protected:
+ NetworkObserver() {}
+ virtual ~NetworkObserver() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkObserver);
+ };
+
+ // An invalid NetworkHandle.
+ static const NetworkHandle kInvalidNetworkHandle;
+
+ virtual ~NetworkChangeNotifier();
// Replaces the default class factory instance of NetworkChangeNotifier class.
// The method will take over the ownership of |factory| object.
@@ -253,6 +292,36 @@ class NET_EXPORT NetworkChangeNotifier {
// TODO(jkarlin): Rename to GetMaxBandwidthMbpsForConnectionSubtype.
static double GetMaxBandwidthForConnectionSubtype(ConnectionSubtype subtype);
+ // Returns true if the platform supports use of APIs based on NetworkHandles.
+ // Public methods that use NetworkHandles are GetNetworkConnectionType(),
+ // GetNetworkConnectionType(), GetDefaultNetwork(), AddNetworkObserver(),
+ // RemoveNetworkObserver(), and all public NetworkObserver methods.
+ static bool AreNetworkHandlesSupported();
+
+ // Sets |network_list| to a list of all networks that are currently connected.
+ // Only implemented for Android (Lollipop and newer), leaves |network_list|
+ // empty when unimplemented. Requires NetworkHandles support, see
+ // AreNetworkHandlesSupported().
+ static void GetConnectedNetworks(NetworkList* network_list);
+
+ // Returns the type of connection |network| uses. Note that this may vary
+ // slightly over time (e.g. CONNECTION_2G to CONNECTION_3G). If |network|
+ // is no longer connected, it will return CONNECTION_UNKNOWN.
+ // Only implemented for Android (Lollipop and newer), returns
+ // CONNECTION_UNKNOWN when unimplemented. Requires NetworkHandles support,
+ // see AreNetworkHandlesSupported().
+ static ConnectionType GetNetworkConnectionType(NetworkHandle network);
+
+ // Returns the device's current default network connection. This is the
+ // network used for newly created socket communication for sockets that are
+ // not explicitly bound to a particular network (e.g. via
+ // DatagramClientSocket.BindToNetwork). Returns |kInvalidNetworkHandle| if
+ // there is no default connected network.
+ // Only implemented for Android (Lollipop and newer), returns
+ // |kInvalidNetworkHandle| when unimplemented.
+ // Requires NetworkHandles support, see AreNetworkHandlesSupported().
+ static NetworkHandle GetDefaultNetwork();
+
// Retrieve the last read DnsConfig. This could be expensive if the system has
// a large HOSTS file.
static void GetDnsConfig(DnsConfig* config);
@@ -300,6 +369,7 @@ class NET_EXPORT NetworkChangeNotifier {
static void AddDNSObserver(DNSObserver* observer);
static void AddNetworkChangeObserver(NetworkChangeObserver* observer);
static void AddMaxBandwidthObserver(MaxBandwidthObserver* observer);
+ static void AddNetworkObserver(NetworkObserver* observer);
// Unregisters |observer| from receiving notifications. This must be called
// on the same thread on which AddObserver() was called. Like AddObserver(),
@@ -313,6 +383,7 @@ class NET_EXPORT NetworkChangeNotifier {
static void RemoveDNSObserver(DNSObserver* observer);
static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer);
static void RemoveMaxBandwidthObserver(MaxBandwidthObserver* observer);
+ static void RemoveNetworkObserver(NetworkObserver* observer);
// Allow unit tests to trigger notifications.
static void NotifyObserversOfIPAddressChangeForTests();
@@ -370,6 +441,15 @@ class NET_EXPORT NetworkChangeNotifier {
};
protected:
+ // Types of network changes specified to
+ // NotifyObserversOfSpecificNetworkChange.
+ enum NetworkChangeType {
+ CONNECTED,
+ DISCONNECTED,
+ SOON_TO_DISCONNECT,
+ MADE_DEFAULT
+ };
+
// NetworkChanged signal is calculated from the IPAddressChanged and
// ConnectionTypeChanged signals. Delay parameters control how long to delay
// producing NetworkChanged signal after particular input signals so as to
@@ -403,12 +483,19 @@ class NET_EXPORT NetworkChangeNotifier {
GetAddressTrackerInternal() const;
#endif
- // See the description of NetworkChangeNotifier::GetMaxBandwidth().
+ // These are the actual implementations of the static queryable APIs.
+ // See the description of the corresponding functions named without "Current".
// Implementations must be thread-safe. Implementations must also be
- // cheap as it is called often.
+ // cheap as they are called often.
+ virtual ConnectionType GetCurrentConnectionType() const = 0;
virtual void GetCurrentMaxBandwidthAndConnectionType(
double* max_bandwidth_mbps,
ConnectionType* connection_type) const;
+ virtual bool AreNetworkHandlesCurrentlySupported() const;
+ virtual void GetCurrentConnectedNetworks(NetworkList* network_list) const;
+ virtual ConnectionType GetCurrentNetworkConnectionType(
+ NetworkHandle network) const;
+ virtual NetworkHandle GetCurrentDefaultNetwork() const;
// Broadcasts a notification to all registered observers. Note that this
// happens asynchronously, even for observers on the current thread, even in
@@ -420,6 +507,8 @@ class NET_EXPORT NetworkChangeNotifier {
static void NotifyObserversOfNetworkChange(ConnectionType type);
static void NotifyObserversOfMaxBandwidthChange(double max_bandwidth_mbps,
ConnectionType type);
+ static void NotifyObserversOfSpecificNetworkChange(NetworkChangeType type,
+ NetworkHandle network);
// Stores |config| in NetworkState and notifies OnDNSChanged observers.
static void SetDnsConfig(const DnsConfig& config);
@@ -443,6 +532,8 @@ class NET_EXPORT NetworkChangeNotifier {
void NotifyObserversOfNetworkChangeImpl(ConnectionType type);
void NotifyObserversOfMaxBandwidthChangeImpl(double max_bandwidth_mbps,
ConnectionType type);
+ void NotifyObserversOfSpecificNetworkChangeImpl(NetworkChangeType type,
+ NetworkHandle network);
const scoped_refptr<base::ObserverListThreadSafe<IPAddressObserver>>
ip_address_observer_list_;
@@ -454,6 +545,8 @@ class NET_EXPORT NetworkChangeNotifier {
network_change_observer_list_;
const scoped_refptr<base::ObserverListThreadSafe<MaxBandwidthObserver>>
max_bandwidth_observer_list_;
+ const scoped_refptr<base::ObserverListThreadSafe<NetworkObserver>>
+ network_observer_list_;
// The current network state. Hosts DnsConfig, exposed via GetDnsConfig.
scoped_ptr<NetworkState> network_state_;
diff --git a/chromium/net/base/network_change_notifier_linux.cc b/chromium/net/base/network_change_notifier_linux.cc
index 40099676cf8..e1e7de02508 100644
--- a/chromium/net/base/network_change_notifier_linux.cc
+++ b/chromium/net/base/network_change_notifier_linux.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/threading/thread.h"
#include "net/base/address_tracker_linux.h"
#include "net/dns/dns_config_service.h"
diff --git a/chromium/net/base/network_change_notifier_linux.h b/chromium/net/base/network_change_notifier_linux.h
index 0da7d0c695c..85238cf9688 100644
--- a/chromium/net/base/network_change_notifier_linux.h
+++ b/chromium/net/base/network_change_notifier_linux.h
@@ -5,8 +5,8 @@
#ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_LINUX_H_
#define NET_BASE_NETWORK_CHANGE_NOTIFIER_LINUX_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
diff --git a/chromium/net/base/network_change_notifier_mac.cc b/chromium/net/base/network_change_notifier_mac.cc
index 4468c0bc226..4105159c590 100644
--- a/chromium/net/base/network_change_notifier_mac.cc
+++ b/chromium/net/base/network_change_notifier_mac.cc
@@ -7,7 +7,7 @@
#include <netinet/in.h>
#include <resolv.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "net/dns/dns_config_service.h"
@@ -157,7 +157,7 @@ void NetworkChangeNotifierMac::SetInitialConnectionType() {
base::AutoLock lock(connection_type_lock_);
connection_type_ = connection_type;
connection_type_initialized_ = true;
- initial_connection_type_cv_.Signal();
+ initial_connection_type_cv_.Broadcast();
}
}
diff --git a/chromium/net/base/network_change_notifier_mac.h b/chromium/net/base/network_change_notifier_mac.h
index 6f340872fc1..28228b1e1fb 100644
--- a/chromium/net/base/network_change_notifier_mac.h
+++ b/chromium/net/base/network_change_notifier_mac.h
@@ -7,9 +7,9 @@
#include <SystemConfiguration/SystemConfiguration.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/mac/scoped_cftyperef.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
diff --git a/chromium/net/base/network_change_notifier_win.cc b/chromium/net/base/network_change_notifier_win.cc
index e76835204c7..1c4052246cc 100644
--- a/chromium/net/base/network_change_notifier_win.cc
+++ b/chromium/net/base/network_change_notifier_win.cc
@@ -9,10 +9,12 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "net/base/winsock_init.h"
+#include "net/base/winsock_util.h"
#include "net/dns/dns_config_service.h"
#pragma comment(lib, "iphlpapi.lib")
@@ -291,6 +293,7 @@ bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() {
base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
}
+ ResetEventIfSignaled(addr_overlapped_.hEvent);
HANDLE handle = NULL;
DWORD ret = NotifyAddrChange(&handle, &addr_overlapped_);
if (ret != ERROR_IO_PENDING)
diff --git a/chromium/net/base/network_change_notifier_win.h b/chromium/net/base/network_change_notifier_win.h
index 113de9f9767..d3a010bd177 100644
--- a/chromium/net/base/network_change_notifier_win.h
+++ b/chromium/net/base/network_change_notifier_win.h
@@ -7,8 +7,8 @@
#include <windows.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
diff --git a/chromium/net/base/network_change_notifier_win_unittest.cc b/chromium/net/base/network_change_notifier_win_unittest.cc
index 04b19e6e6d2..083a744c702 100644
--- a/chromium/net/base/network_change_notifier_win_unittest.cc
+++ b/chromium/net/base/network_change_notifier_win_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_change_notifier_factory.h"
@@ -60,7 +61,7 @@ class TestIPAddressObserver : public NetworkChangeNotifier::IPAddressObserver {
};
bool ExitMessageLoopAndReturnFalse() {
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
return false;
}
@@ -164,9 +165,10 @@ class NetworkChangeNotifierWinTest : public testing::Test {
EXPECT_FALSE(network_change_notifier_.is_watching());
EXPECT_LT(0, network_change_notifier_.sequential_failures());
- EXPECT_CALL(test_ip_address_observer_, OnIPAddressChanged()).Times(1)
- .WillOnce(
- Invoke(base::MessageLoop::current(), &base::MessageLoop::Quit));
+ EXPECT_CALL(test_ip_address_observer_, OnIPAddressChanged())
+ .Times(1)
+ .WillOnce(Invoke(base::MessageLoop::current(),
+ &base::MessageLoop::QuitWhenIdle));
EXPECT_CALL(network_change_notifier_, WatchForAddressChangeInternal())
.Times(1).WillOnce(Return(true));
diff --git a/chromium/net/base/network_config_watcher_mac.cc b/chromium/net/base/network_config_watcher_mac.cc
index bdf75c39ad2..07dc2dfdcef 100644
--- a/chromium/net/base/network_config_watcher_mac.cc
+++ b/chromium/net/base/network_config_watcher_mac.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
diff --git a/chromium/net/base/network_config_watcher_mac.h b/chromium/net/base/network_config_watcher_mac.h
index 850ad8a1c10..ef09f544b71 100644
--- a/chromium/net/base/network_config_watcher_mac.h
+++ b/chromium/net/base/network_config_watcher_mac.h
@@ -7,8 +7,8 @@
#include <SystemConfiguration/SCDynamicStore.h>
-#include "base/basictypes.h"
#include "base/mac/scoped_cftyperef.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
namespace base {
diff --git a/chromium/net/base/network_delegate.cc b/chromium/net/base/network_delegate.cc
index 15380281237..ff4ee88fa0b 100644
--- a/chromium/net/base/network_delegate.cc
+++ b/chromium/net/base/network_delegate.cc
@@ -89,14 +89,14 @@ void NetworkDelegate::NotifyResponseStarted(URLRequest* request) {
OnResponseStarted(request);
}
-void NetworkDelegate::NotifyNetworkBytesReceived(const URLRequest& request,
+void NetworkDelegate::NotifyNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) {
DCHECK(CalledOnValidThread());
DCHECK_GT(bytes_received, 0);
OnNetworkBytesReceived(request, bytes_received);
}
-void NetworkDelegate::NotifyNetworkBytesSent(const URLRequest& request,
+void NetworkDelegate::NotifyNetworkBytesSent(URLRequest* request,
int64_t bytes_sent) {
DCHECK(CalledOnValidThread());
DCHECK_GT(bytes_sent, 0);
@@ -125,12 +125,6 @@ void NetworkDelegate::NotifyURLRequestDestroyed(URLRequest* request) {
OnURLRequestDestroyed(request);
}
-void NetworkDelegate::NotifyURLRequestJobOrphaned(URLRequest* request) {
- DCHECK(CalledOnValidThread());
- DCHECK(request);
- OnURLRequestJobOrphaned(request);
-}
-
void NetworkDelegate::NotifyPACScriptError(int line_number,
const base::string16& error) {
DCHECK(CalledOnValidThread());
@@ -174,8 +168,12 @@ bool NetworkDelegate::CanEnablePrivacyMode(
return OnCanEnablePrivacyMode(url, first_party_for_cookies);
}
-bool NetworkDelegate::FirstPartyOnlyCookieExperimentEnabled() const {
- return OnFirstPartyOnlyCookieExperimentEnabled();
+bool NetworkDelegate::AreExperimentalCookieFeaturesEnabled() const {
+ return OnAreExperimentalCookieFeaturesEnabled();
+}
+
+bool NetworkDelegate::AreStrictSecureCookiesEnabled() const {
+ return OnAreStrictSecureCookiesEnabled();
}
bool NetworkDelegate::CancelURLRequestWithPolicyViolatingReferrerHeader(
diff --git a/chromium/net/base/network_delegate.h b/chromium/net/base/network_delegate.h
index cad221e99db..07371371054 100644
--- a/chromium/net/base/network_delegate.h
+++ b/chromium/net/base/network_delegate.h
@@ -87,12 +87,10 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
void NotifyBeforeRedirect(URLRequest* request,
const GURL& new_location);
void NotifyResponseStarted(URLRequest* request);
- void NotifyNetworkBytesReceived(const URLRequest& request,
- int64_t bytes_received);
- void NotifyNetworkBytesSent(const URLRequest& request, int64_t bytes_sent);
+ void NotifyNetworkBytesReceived(URLRequest* request, int64_t bytes_received);
+ void NotifyNetworkBytesSent(URLRequest* request, int64_t bytes_sent);
void NotifyCompleted(URLRequest* request, bool started);
void NotifyURLRequestDestroyed(URLRequest* request);
- void NotifyURLRequestJobOrphaned(URLRequest* request);
void NotifyPACScriptError(int line_number, const base::string16& error);
AuthRequiredResponse NotifyAuthRequired(URLRequest* request,
const AuthChallengeInfo& auth_info,
@@ -109,8 +107,12 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
const GURL& first_party_for_cookies) const;
// TODO(mkwst): Remove this once we decide whether or not we wish to ship
- // first-party cookies. https://crbug.com/459154
- bool FirstPartyOnlyCookieExperimentEnabled() const;
+ // first-party cookies and setting secure cookies require
+ // secure scheme. https://crbug.com/459154, https://crbug.com/541511,
+ // https://crbug.com/546820
+ bool AreExperimentalCookieFeaturesEnabled() const;
+ // TODO(jww): Remove this once we ship strict secure cookies.
+ bool AreStrictSecureCookiesEnabled() const;
bool CancelURLRequestWithPolicyViolatingReferrerHeader(
const URLRequest& request,
@@ -211,7 +213,7 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
// greater than 0.
// Currently, this is only implemented for HTTP transactions, and
// |bytes_received| does not include TLS overhead or TCP retransmits.
- virtual void OnNetworkBytesReceived(const URLRequest& request,
+ virtual void OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) = 0;
// Called when bytes are sent over the network, such as when sending request
@@ -221,8 +223,7 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
// OnNetworkBytesSent was called. |bytes_sent| will always be greater than 0.
// Currently, this is only implemented for HTTP transactions, and |bytes_sent|
// does not include TLS overhead or TCP retransmits.
- virtual void OnNetworkBytesSent(const URLRequest& request,
- int64_t bytes_sent) = 0;
+ virtual void OnNetworkBytesSent(URLRequest* request, int64_t bytes_sent) = 0;
// Indicates that the URL request has been completed or failed.
// |started| indicates whether the request has been started. If false,
@@ -234,13 +235,6 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
// a virtual method call.
virtual void OnURLRequestDestroyed(URLRequest* request) = 0;
- // Called when the current job for |request| is orphaned. This is a temporary
- // callback to diagnose https://crbug.com/289715 and may not be used for other
- // purposes. Note that it may be called after OnURLRequestDestroyed.
- //
- // TODO(davidben): Remove this once data has been gathered.
- virtual void OnURLRequestJobOrphaned(URLRequest* request) = 0;
-
// Corresponds to ProxyResolverJSBindings::OnError.
virtual void OnPACScriptError(int line_number,
const base::string16& error) = 0;
@@ -294,12 +288,20 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
const GURL& url,
const GURL& first_party_for_cookies) const = 0;
- // Returns true if the embedder has enabled the "first-party" cookie
- // experiment, and false otherwise.
+ // Returns true if the embedder has enabled the experimental features, and
+ // false otherwise.
//
// TODO(mkwst): Remove this once we decide whether or not we wish to ship
- // first-party cookies. https://crbug.com/459154
- virtual bool OnFirstPartyOnlyCookieExperimentEnabled() const = 0;
+ // first-party cookies, cookie prefixes, and setting secure cookies require
+ // secure scheme. https://crbug.com/459154, https://crbug.com/541511,
+ // https://crbug.com/546820
+ virtual bool OnAreExperimentalCookieFeaturesEnabled() const = 0;
+
+ // Returns true if the embedder has enabled experimental features or
+ // specifically strict secure cookies, and false otherwise.
+ //
+ // TODO(jww): Remove this once we ship strict secure cookies.
+ virtual bool OnAreStrictSecureCookiesEnabled() const = 0;
// Called when the |referrer_url| for requesting |target_url| during handling
// of the |request| is does not comply with the referrer policy (e.g. a
diff --git a/chromium/net/base/network_delegate_impl.cc b/chromium/net/base/network_delegate_impl.cc
index af4d708647b..5e94543b303 100644
--- a/chromium/net/base/network_delegate_impl.cc
+++ b/chromium/net/base/network_delegate_impl.cc
@@ -56,10 +56,10 @@ void NetworkDelegateImpl::OnBeforeRedirect(URLRequest* request,
void NetworkDelegateImpl::OnResponseStarted(URLRequest* request) {
}
-void NetworkDelegateImpl::OnNetworkBytesReceived(const URLRequest& request,
+void NetworkDelegateImpl::OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) {}
-void NetworkDelegateImpl::OnNetworkBytesSent(const URLRequest& request,
+void NetworkDelegateImpl::OnNetworkBytesSent(URLRequest* request,
int64_t bytes_sent) {}
void NetworkDelegateImpl::OnCompleted(URLRequest* request, bool started) {
@@ -68,8 +68,6 @@ void NetworkDelegateImpl::OnCompleted(URLRequest* request, bool started) {
void NetworkDelegateImpl::OnURLRequestDestroyed(URLRequest* request) {
}
-void NetworkDelegateImpl::OnURLRequestJobOrphaned(URLRequest* request) {}
-
void NetworkDelegateImpl::OnPACScriptError(int line_number,
const base::string16& error) {
}
@@ -104,7 +102,11 @@ bool NetworkDelegateImpl::OnCanEnablePrivacyMode(
return false;
}
-bool NetworkDelegateImpl::OnFirstPartyOnlyCookieExperimentEnabled() const {
+bool NetworkDelegateImpl::OnAreExperimentalCookieFeaturesEnabled() const {
+ return false;
+}
+
+bool NetworkDelegateImpl::OnAreStrictSecureCookiesEnabled() const {
return false;
}
diff --git a/chromium/net/base/network_delegate_impl.h b/chromium/net/base/network_delegate_impl.h
index b0345dd062a..8a0b007f3d8 100644
--- a/chromium/net/base/network_delegate_impl.h
+++ b/chromium/net/base/network_delegate_impl.h
@@ -125,7 +125,7 @@ class NET_EXPORT NetworkDelegateImpl : public NetworkDelegate {
// greater than 0.
// Currently, this is only implemented for HTTP transactions, and
// |bytes_received| does not include TLS overhead or TCP retransmits.
- void OnNetworkBytesReceived(const URLRequest& request,
+ void OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) override;
// Called when bytes are sent over the network, such as when sending request
@@ -135,8 +135,7 @@ class NET_EXPORT NetworkDelegateImpl : public NetworkDelegate {
// OnNetworkBytesSent was called. |bytes_sent| will always be greater than 0.
// Currently, this is only implemented for HTTP transactions, and |bytes_sent|
// does not include TLS overhead or TCP retransmits.
- void OnNetworkBytesSent(const URLRequest& request,
- int64_t bytes_sent) override;
+ void OnNetworkBytesSent(URLRequest* request, int64_t bytes_sent) override;
// Indicates that the URL request has been completed or failed.
// |started| indicates whether the request has been started. If false,
@@ -148,13 +147,6 @@ class NET_EXPORT NetworkDelegateImpl : public NetworkDelegate {
// a virtual method call.
void OnURLRequestDestroyed(URLRequest* request) override;
- // Called when the current job for |request| is orphaned. This is a temporary
- // callback to diagnose https://crbug.com/289715 and may not be used for other
- // purposes. Note that it may be called after OnURLRequestDestroyed.
- //
- // TODO(davidben): Remove this once data has been gathered.
- void OnURLRequestJobOrphaned(URLRequest* request) override;
-
// Corresponds to ProxyResolverJSBindings::OnError.
void OnPACScriptError(int line_number, const base::string16& error) override;
@@ -210,8 +202,10 @@ class NET_EXPORT NetworkDelegateImpl : public NetworkDelegate {
// experiment, and false otherwise.
//
// TODO(mkwst): Remove this once we decide whether or not we wish to ship
- // first-party cookies. https://crbug.com/459154
- bool OnFirstPartyOnlyCookieExperimentEnabled() const override;
+ // first-party cookies and cookie prefixes. https://crbug.com/459154,
+ // https://crbug.com/541511
+ bool OnAreExperimentalCookieFeaturesEnabled() const override;
+ bool OnAreStrictSecureCookiesEnabled() const override;
// Called when the |referrer_url| for requesting |target_url| during handling
// of the |request| is does not comply with the referrer policy (e.g. a
diff --git a/chromium/net/base/network_interfaces.h b/chromium/net/base/network_interfaces.h
index 73ad09a23f7..ed98abb5d84 100644
--- a/chromium/net/base/network_interfaces.h
+++ b/chromium/net/base/network_interfaces.h
@@ -5,41 +5,37 @@
#ifndef NET_BASE_NETWORK_INTERFACES_H_
#define NET_BASE_NETWORK_INTERFACES_H_
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#include <ws2tcpip.h>
-#elif defined(OS_POSIX)
-#include <sys/types.h>
-#include <sys/socket.h>
-#endif
+#include <stdint.h>
#include <string>
#include <vector>
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_offset_string_conversions.h"
-#include "net/base/address_family.h"
-#include "net/base/escape.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "net/base/ip_address_number.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
-class GURL;
-
-namespace base {
-class Time;
-}
-
-namespace url {
-struct CanonHostInfo;
-struct Parsed;
-}
-
namespace net {
+// A subset of IP address attributes which are actionable by the
+// application layer. Currently unimplemented for all hosts;
+// IP_ADDRESS_ATTRIBUTE_NONE is always returned.
+enum IPAddressAttributes {
+ IP_ADDRESS_ATTRIBUTE_NONE = 0,
+
+ // A temporary address is dynamic by nature and will not contain MAC
+ // address. Presence of MAC address in IPv6 addresses can be used to
+ // track an endpoint and cause privacy concern. Please refer to
+ // RFC4941.
+ IP_ADDRESS_ATTRIBUTE_TEMPORARY = 1 << 0,
+
+ // A temporary address could become deprecated once the preferred
+ // lifetime is reached. It is still valid but shouldn't be used to
+ // create new connections.
+ IP_ADDRESS_ATTRIBUTE_DEPRECATED = 1 << 1,
+};
+
// struct that is used by GetNetworkList() to represent a network
// interface.
struct NET_EXPORT NetworkInterface {
diff --git a/chromium/net/base/network_interfaces_unittest.cc b/chromium/net/base/network_interfaces_unittest.cc
index 06ffb07ee41..470295f0218 100644
--- a/chromium/net/base/network_interfaces_unittest.cc
+++ b/chromium/net/base/network_interfaces_unittest.cc
@@ -163,9 +163,10 @@ TEST(NetUtilTest, GetNetworkList) {
if (interface_to_luid && luid_to_guid) {
NET_LUID luid;
- EXPECT_EQ(interface_to_luid(it->interface_index, &luid), NO_ERROR);
+ EXPECT_EQ(static_cast<DWORD>(NO_ERROR),
+ interface_to_luid(it->interface_index, &luid));
GUID guid;
- EXPECT_EQ(luid_to_guid(&luid, &guid), NO_ERROR);
+ EXPECT_EQ(static_cast<DWORD>(NO_ERROR), luid_to_guid(&luid, &guid));
LPOLESTR name;
StringFromCLSID(guid, &name);
EXPECT_STREQ(base::UTF8ToWide(it->name).c_str(), name);
diff --git a/chromium/net/base/network_interfaces_win.cc b/chromium/net/base/network_interfaces_win.cc
index 6cb8fec7a06..e451211161e 100644
--- a/chromium/net/base/network_interfaces_win.cc
+++ b/chromium/net/base/network_interfaces_win.cc
@@ -2,17 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/base/net_util.h"
+#include "net/base/network_interfaces_win.h"
-#include <iphlpapi.h>
-#include <wlanapi.h>
+#pragma comment(lib, "iphlpapi.lib")
#include <algorithm>
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
@@ -23,7 +21,7 @@
#include "net/base/escape.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/network_interfaces_win.h"
+#include "net/base/net_util.h"
#include "url/gurl.h"
namespace net {
@@ -54,27 +52,23 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>
GetConnectionAttributes() {
const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
+ scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>
+ wlan_connection_attributes;
if (!wlanapi.initialized)
- return scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>();
+ return wlan_connection_attributes.Pass();
internal::WlanHandle client;
DWORD cur_version = 0;
const DWORD kMaxClientVersion = 2;
- {
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is
- // fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION("422516 OpenHandle()"));
- DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client);
- if (result != ERROR_SUCCESS)
- return scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>();
- }
+ DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client);
+ if (result != ERROR_SUCCESS)
+ return wlan_connection_attributes.Pass();
WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
- DWORD result =
+ result =
wlanapi.enum_interfaces_func(client.Get(), NULL, &interface_list_ptr);
if (result != ERROR_SUCCESS)
- return scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>();
+ return wlan_connection_attributes.Pass();
scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list(
interface_list_ptr);
@@ -89,7 +83,7 @@ GetConnectionAttributes() {
}
if (info == NULL)
- return scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>();
+ return wlan_connection_attributes.Pass();
WLAN_CONNECTION_ATTRIBUTES* conn_info_ptr = nullptr;
DWORD conn_info_size = 0;
@@ -98,12 +92,12 @@ GetConnectionAttributes() {
client.Get(), &info->InterfaceGuid, wlan_intf_opcode_current_connection,
NULL, &conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr),
&op_code);
- if (result != ERROR_SUCCESS)
- return scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>();
-
- DCHECK(conn_info_ptr);
- return scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter>(
- conn_info_ptr);
+ wlan_connection_attributes.reset(conn_info_ptr);
+ if (result == ERROR_SUCCESS)
+ DCHECK(conn_info_ptr);
+ else
+ wlan_connection_attributes.reset();
+ return wlan_connection_attributes.Pass();
}
} // namespace
diff --git a/chromium/net/base/network_interfaces_win.h b/chromium/net/base/network_interfaces_win.h
index 353dda4eb16..9d6941876b0 100644
--- a/chromium/net/base/network_interfaces_win.h
+++ b/chromium/net/base/network_interfaces_win.h
@@ -8,6 +8,7 @@
// This file is only used to expose some of the internals
// of network_interfaces_win.cc to tests.
+#include <winsock2.h>
#include <iphlpapi.h>
#include <wlanapi.h>
diff --git a/chromium/net/base/network_quality_estimator.cc b/chromium/net/base/network_quality_estimator.cc
index c3380958008..c67b641101a 100644
--- a/chromium/net/base/network_quality_estimator.cc
+++ b/chromium/net/base/network_quality_estimator.cc
@@ -8,6 +8,7 @@
#include <algorithm>
#include <cmath>
#include <limits>
+#include <utility>
#include <vector>
#include "base/logging.h"
@@ -28,44 +29,6 @@
namespace {
-// Implements SocketPerformanceWatcher for TCP sockets.
-class SocketPerformanceWatcherTCP : public net::SocketPerformanceWatcher {
- public:
- SocketPerformanceWatcherTCP() {}
-
- ~SocketPerformanceWatcherTCP() override {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
-
- // net::SocketPerformanceWatcher implementation:
- void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
- DCHECK(thread_checker_.CalledOnValidThread());
- // TODO(tbansal): Notify any relevant observers.
- }
-
- private:
- base::ThreadChecker thread_checker_;
-};
-
-// Implements SocketPerformanceWatcher for UDP sockets.
-class SocketPerformanceWatcherUDP : public net::SocketPerformanceWatcher {
- public:
- SocketPerformanceWatcherUDP() {}
-
- ~SocketPerformanceWatcherUDP() override {
- DCHECK(thread_checker_.CalledOnValidThread());
- }
-
- // net::SocketPerformanceWatcher implementation:
- void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
- DCHECK(thread_checker_.CalledOnValidThread());
- // TODO(tbansal): Notify any relevant observers.
- }
-
- private:
- base::ThreadChecker thread_checker_;
-};
-
// Default value of the half life (in seconds) for computing time weighted
// percentiles. Every half life, the weight of all observations reduces by
// half. Lowering the half life would reduce the weight of older values faster.
@@ -159,7 +122,7 @@ const int32_t NetworkQualityEstimator::kInvalidThroughput = 0;
NetworkQualityEstimator::NetworkQualityEstimator(
scoped_ptr<ExternalEstimateProvider> external_estimates_provider,
const std::map<std::string, std::string>& variation_params)
- : NetworkQualityEstimator(external_estimates_provider.Pass(),
+ : NetworkQualityEstimator(std::move(external_estimates_provider),
variation_params,
false,
false) {}
@@ -178,7 +141,7 @@ NetworkQualityEstimator::NetworkQualityEstimator(
downstream_throughput_kbps_observations_(
GetWeightMultiplierPerSecond(variation_params)),
rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)),
- external_estimate_provider_(external_estimates_provider.Pass()) {
+ external_estimate_provider_(std::move(external_estimates_provider)) {
static_assert(kMinRequestDurationMicroseconds > 0,
"Minimum request duration must be > 0");
static_assert(kDefaultHalfLifeSeconds > 0,
@@ -440,7 +403,7 @@ void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec,
if (actual_value_msec == 0)
return;
- int32 ratio = (estimated_value_msec * 100) / actual_value_msec;
+ int32_t ratio = (estimated_value_msec * 100) / actual_value_msec;
// Record the accuracy of estimation by recording the ratio of estimated
// value to the actual value.
@@ -958,17 +921,31 @@ void NetworkQualityEstimator::CacheNetworkQualityEstimate() {
}
scoped_ptr<SocketPerformanceWatcher>
-NetworkQualityEstimator::CreateTCPSocketPerformanceWatcher() const {
+NetworkQualityEstimator::CreateSocketPerformanceWatcher(
+ const Protocol protocol) {
DCHECK(thread_checker_.CalledOnValidThread());
+
return scoped_ptr<SocketPerformanceWatcher>(
- new SocketPerformanceWatcherTCP());
+ new SocketPerformanceWatcher(protocol, this));
}
-scoped_ptr<SocketPerformanceWatcher>
-NetworkQualityEstimator::CreateUDPSocketPerformanceWatcher() const {
+void NetworkQualityEstimator::OnUpdatedRTTAvailable(
+ const Protocol protocol,
+ const base::TimeDelta& rtt) {
DCHECK(thread_checker_.CalledOnValidThread());
- return scoped_ptr<SocketPerformanceWatcher>(
- new SocketPerformanceWatcherUDP());
+
+ switch (protocol) {
+ case PROTOCOL_TCP:
+ NotifyObserversOfRTT(
+ Observation(rtt.InMilliseconds(), base::TimeTicks::Now(), TCP));
+ return;
+ case PROTOCOL_QUIC:
+ NotifyObserversOfRTT(
+ Observation(rtt.InMilliseconds(), base::TimeTicks::Now(), QUIC));
+ return;
+ default:
+ NOTREACHED();
+ }
}
void NetworkQualityEstimator::NotifyObserversOfRTT(
diff --git a/chromium/net/base/network_quality_estimator.h b/chromium/net/base/network_quality_estimator.h
index d14c5cdd685..ad10d3249b2 100644
--- a/chromium/net/base/network_quality_estimator.h
+++ b/chromium/net/base/network_quality_estimator.h
@@ -5,11 +5,13 @@
#ifndef NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
#define NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
+#include <stddef.h>
#include <stdint.h>
#include <deque>
#include <map>
#include <string>
+#include <tuple>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -159,10 +161,10 @@ class NET_EXPORT_PRIVATE NetworkQualityEstimator
int32_t* kbps) const;
// SocketPerformanceWatcherFactory implementation:
- scoped_ptr<SocketPerformanceWatcher> CreateTCPSocketPerformanceWatcher()
- const override;
- scoped_ptr<SocketPerformanceWatcher> CreateUDPSocketPerformanceWatcher()
- const override;
+ scoped_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
+ const Protocol protocol) override;
+ void OnUpdatedRTTAvailable(const Protocol protocol,
+ const base::TimeDelta& rtt) override;
// Adds |rtt_observer| to the list of round trip time observers. Must be
// called on the IO thread.
@@ -201,7 +203,7 @@ class NET_EXPORT_PRIVATE NetworkQualityEstimator
// Overloaded because NetworkID is used as key in a map.
bool operator<(const NetworkID& other) const {
- return type < other.type || (type == other.type && id < other.id);
+ return std::tie(type, id) < std::tie(other.type, other.id);
}
// Connection type of the network.
diff --git a/chromium/net/base/network_quality_estimator_unittest.cc b/chromium/net/base/network_quality_estimator_unittest.cc
index ba23d4a3b6f..cf1197f501a 100644
--- a/chromium/net/base/network_quality_estimator_unittest.cc
+++ b/chromium/net/base/network_quality_estimator_unittest.cc
@@ -5,14 +5,14 @@
#include "net/base/network_quality_estimator.h"
#include <stdint.h>
-
#include <limits>
#include <map>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_samples.h"
#include "base/run_loop.h"
@@ -39,14 +39,14 @@ class TestNetworkQualityEstimator : public net::NetworkQualityEstimator {
TestNetworkQualityEstimator(
const std::map<std::string, std::string>& variation_params,
scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider)
- : NetworkQualityEstimator(external_estimate_provider.Pass(),
+ : NetworkQualityEstimator(std::move(external_estimate_provider),
variation_params,
true,
true) {
// Set up embedded test server.
embedded_test_server_.ServeFilesFromDirectory(
base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
- EXPECT_TRUE(embedded_test_server_.InitializeAndWaitUntilReady());
+ EXPECT_TRUE(embedded_test_server_.Start());
embedded_test_server_.RegisterRequestHandler(base::Bind(
&TestNetworkQualityEstimator::HandleRequest, base::Unretained(this)));
}
@@ -76,7 +76,7 @@ class TestNetworkQualityEstimator : public net::NetworkQualityEstimator {
http_response->set_code(net::HTTP_OK);
http_response->set_content("hello");
http_response->set_content_type("text/plain");
- return http_response.Pass();
+ return std::move(http_response);
}
// Returns a GURL hosted at embedded test server.
@@ -99,7 +99,7 @@ class TestNetworkQualityEstimator : public net::NetworkQualityEstimator {
std::string current_network_id_;
// Embedded server used for testing.
- net::test_server::EmbeddedTestServer embedded_test_server_;
+ net::EmbeddedTestServer embedded_test_server_;
DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator);
};
@@ -716,8 +716,8 @@ TEST(NetworkQualityEstimatorTest, TestGetMedianRTTSince) {
std::map<std::string, std::string> variation_params;
TestNetworkQualityEstimator estimator(variation_params);
base::TimeTicks now = base::TimeTicks::Now();
- base::TimeTicks old =
- base::TimeTicks::Now() - base::TimeDelta::FromMilliseconds(1);
+ base::TimeTicks old = now - base::TimeDelta::FromMilliseconds(1);
+ ASSERT_NE(old, now);
// First sample has very old timestamp.
estimator.downstream_throughput_kbps_observations_.AddObservation(
@@ -808,7 +808,7 @@ TEST(NetworkQualityEstimatorTest, InvalidExternalEstimateProvider) {
invalid_external_estimate_provider);
TestNetworkQualityEstimator estimator(std::map<std::string, std::string>(),
- external_estimate_provider.Pass());
+ std::move(external_estimate_provider));
base::TimeDelta rtt;
int32_t kbps;
@@ -906,7 +906,7 @@ TEST(NetworkQualityEstimatorTest, TestExternalEstimateProvider) {
test_external_estimate_provider);
std::map<std::string, std::string> variation_params;
TestNetworkQualityEstimator estimator(variation_params,
- external_estimate_provider.Pass());
+ std::move(external_estimate_provider));
base::TimeDelta rtt;
int32_t kbps;
@@ -981,7 +981,7 @@ TEST(NetworkQualityEstimatorTest, TestExternalEstimateProviderMergeEstimates) {
std::map<std::string, std::string> variation_params;
TestNetworkQualityEstimator estimator(variation_params,
- external_estimate_provider.Pass());
+ std::move(external_estimate_provider));
base::TimeDelta rtt;
// Estimate provided by network quality estimator should match the estimate
@@ -1058,6 +1058,26 @@ TEST(NetworkQualityEstimatorTest, TestObservers) {
EXPECT_LE(0, (observation.timestamp - then).InMilliseconds());
EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source);
}
+
+ // Verify that observations from TCP and QUIC are passed on to the observers.
+ base::TimeDelta tcp_rtt(base::TimeDelta::FromMilliseconds(1));
+ base::TimeDelta quic_rtt(base::TimeDelta::FromMilliseconds(2));
+
+ scoped_ptr<SocketPerformanceWatcher> tcp_watcher =
+ estimator.CreateSocketPerformanceWatcher(
+ SocketPerformanceWatcherFactory::PROTOCOL_TCP);
+ scoped_ptr<SocketPerformanceWatcher> quic_watcher =
+ estimator.CreateSocketPerformanceWatcher(
+ SocketPerformanceWatcherFactory::PROTOCOL_QUIC);
+ tcp_watcher->OnUpdatedRTTAvailable(tcp_rtt);
+ quic_watcher->OnUpdatedRTTAvailable(quic_rtt);
+
+ EXPECT_EQ(4U, rtt_observer.observations().size());
+ EXPECT_EQ(2U, throughput_observer.observations().size());
+
+ EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms);
+ EXPECT_EQ(quic_rtt.InMilliseconds(),
+ rtt_observer.observations().at(3).rtt_ms);
}
} // namespace net
diff --git a/chromium/net/base/openssl_private_key_store.h b/chromium/net/base/openssl_private_key_store.h
index 0ad3b1a99c0..ee4bc35f9bb 100644
--- a/chromium/net/base/openssl_private_key_store.h
+++ b/chromium/net/base/openssl_private_key_store.h
@@ -10,7 +10,7 @@
// Avoid including <openssl/evp.h>
typedef struct evp_pkey_st EVP_PKEY;
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
class GURL;
diff --git a/chromium/net/base/openssl_private_key_store_memory.cc b/chromium/net/base/openssl_private_key_store_memory.cc
index e258eb5ce67..49e6e1d89d6 100644
--- a/chromium/net/base/openssl_private_key_store_memory.cc
+++ b/chromium/net/base/openssl_private_key_store_memory.cc
@@ -9,6 +9,7 @@
#include <openssl/evp.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
diff --git a/chromium/net/base/port_util.h b/chromium/net/base/port_util.h
index 85e9160da37..99a1ec484e3 100644
--- a/chromium/net/base/port_util.h
+++ b/chromium/net/base/port_util.h
@@ -5,9 +5,11 @@
#ifndef NET_BASE_NET_PORT_UTIL_
#define NET_BASE_NET_PORT_UTIL_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
namespace net {
diff --git a/chromium/net/base/prioritized_dispatcher.h b/chromium/net/base/prioritized_dispatcher.h
index e4f1019d76c..8da8a1a668a 100644
--- a/chromium/net/base/prioritized_dispatcher.h
+++ b/chromium/net/base/prioritized_dispatcher.h
@@ -5,8 +5,11 @@
#ifndef NET_BASE_PRIORITIZED_DISPATCHER_H_
#define NET_BASE_PRIORITIZED_DISPATCHER_H_
+#include <stddef.h>
+
#include <vector>
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/base/priority_queue.h"
diff --git a/chromium/net/base/prioritized_dispatcher_unittest.cc b/chromium/net/base/prioritized_dispatcher_unittest.cc
index 185937fd104..56489dfebb1 100644
--- a/chromium/net/base/prioritized_dispatcher_unittest.cc
+++ b/chromium/net/base/prioritized_dispatcher_unittest.cc
@@ -8,7 +8,6 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/prioritized_dispatcher.h"
#include "net/base/request_priority.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -139,16 +138,16 @@ class PrioritizedDispatcherTest : public testing::Test {
dispatcher_.reset(new PrioritizedDispatcher(limits));
}
- TestJob* AddJob(char data, Priority priority) {
- TestJob* job = new TestJob(dispatcher_.get(), data, priority, &log_);
- jobs_.push_back(job);
+ scoped_ptr<TestJob> AddJob(char data, Priority priority) {
+ scoped_ptr<TestJob> job(
+ new TestJob(dispatcher_.get(), data, priority, &log_));
job->Add(false);
return job;
}
- TestJob* AddJobAtHead(char data, Priority priority) {
- TestJob* job = new TestJob(dispatcher_.get(), data, priority, &log_);
- jobs_.push_back(job);
+ scoped_ptr<TestJob> AddJobAtHead(char data, Priority priority) {
+ scoped_ptr<TestJob> job(
+ new TestJob(dispatcher_.get(), data, priority, &log_));
job->Add(true);
return job;
}
@@ -162,7 +161,6 @@ class PrioritizedDispatcherTest : public testing::Test {
std::string log_;
scoped_ptr<PrioritizedDispatcher> dispatcher_;
- ScopedVector<TestJob> jobs_;
};
TEST_F(PrioritizedDispatcherTest, GetLimits) {
@@ -204,10 +202,10 @@ TEST_F(PrioritizedDispatcherTest, AddAFIFO) {
PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', IDLE);
- TestJob* job_c = AddJob('c', IDLE);
- TestJob* job_d = AddJob('d', IDLE);
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', IDLE);
+ scoped_ptr<TestJob> job_c = AddJob('c', IDLE);
+ scoped_ptr<TestJob> job_d = AddJob('d', IDLE);
ASSERT_TRUE(job_a->running());
job_a->Finish();
@@ -225,11 +223,11 @@ TEST_F(PrioritizedDispatcherTest, AddPriority) {
PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', MEDIUM);
- TestJob* job_c = AddJob('c', HIGHEST);
- TestJob* job_d = AddJob('d', HIGHEST);
- TestJob* job_e = AddJob('e', MEDIUM);
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', MEDIUM);
+ scoped_ptr<TestJob> job_c = AddJob('c', HIGHEST);
+ scoped_ptr<TestJob> job_d = AddJob('d', HIGHEST);
+ scoped_ptr<TestJob> job_e = AddJob('e', MEDIUM);
ASSERT_TRUE(job_a->running());
job_a->Finish();
@@ -249,12 +247,12 @@ TEST_F(PrioritizedDispatcherTest, AddAtHead) {
PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
Prepare(limits);
- TestJob* job_a = AddJob('a', MEDIUM);
- TestJob* job_b = AddJobAtHead('b', MEDIUM);
- TestJob* job_c = AddJobAtHead('c', HIGHEST);
- TestJob* job_d = AddJobAtHead('d', HIGHEST);
- TestJob* job_e = AddJobAtHead('e', MEDIUM);
- TestJob* job_f = AddJob('f', MEDIUM);
+ scoped_ptr<TestJob> job_a = AddJob('a', MEDIUM);
+ scoped_ptr<TestJob> job_b = AddJobAtHead('b', MEDIUM);
+ scoped_ptr<TestJob> job_c = AddJobAtHead('c', HIGHEST);
+ scoped_ptr<TestJob> job_d = AddJobAtHead('d', HIGHEST);
+ scoped_ptr<TestJob> job_e = AddJobAtHead('e', MEDIUM);
+ scoped_ptr<TestJob> job_f = AddJob('f', MEDIUM);
ASSERT_TRUE(job_a->running());
job_a->Finish();
@@ -280,14 +278,14 @@ TEST_F(PrioritizedDispatcherTest, EnforceLimits) {
limits.reserved_slots[LOW] = 1;
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE); // Uses unreserved slot.
- TestJob* job_b = AddJob('b', IDLE); // Uses unreserved slot.
- TestJob* job_c = AddJob('c', LOWEST); // Must wait.
- TestJob* job_d = AddJob('d', LOW); // Uses reserved slot.
- TestJob* job_e = AddJob('e', MEDIUM); // Must wait.
- TestJob* job_f = AddJob('f', HIGHEST); // Uses reserved slot.
- TestJob* job_g = AddJob('g', HIGHEST); // Uses reserved slot.
- TestJob* job_h = AddJob('h', HIGHEST); // Must wait.
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE); // Uses unreserved slot.
+ scoped_ptr<TestJob> job_b = AddJob('b', IDLE); // Uses unreserved slot.
+ scoped_ptr<TestJob> job_c = AddJob('c', LOWEST); // Must wait.
+ scoped_ptr<TestJob> job_d = AddJob('d', LOW); // Uses reserved slot.
+ scoped_ptr<TestJob> job_e = AddJob('e', MEDIUM); // Must wait.
+ scoped_ptr<TestJob> job_f = AddJob('f', HIGHEST); // Uses reserved slot.
+ scoped_ptr<TestJob> job_g = AddJob('g', HIGHEST); // Uses reserved slot.
+ scoped_ptr<TestJob> job_h = AddJob('h', HIGHEST); // Must wait.
EXPECT_EQ(5u, dispatcher_->num_running_jobs());
EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
@@ -320,11 +318,11 @@ TEST_F(PrioritizedDispatcherTest, ChangePriority) {
limits.reserved_slots[HIGHEST] = 1;
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', LOW);
- TestJob* job_c = AddJob('c', MEDIUM);
- TestJob* job_d = AddJob('d', MEDIUM);
- TestJob* job_e = AddJob('e', IDLE);
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', LOW);
+ scoped_ptr<TestJob> job_c = AddJob('c', MEDIUM);
+ scoped_ptr<TestJob> job_d = AddJob('d', MEDIUM);
+ scoped_ptr<TestJob> job_e = AddJob('e', IDLE);
ASSERT_FALSE(job_b->running());
ASSERT_FALSE(job_c->running());
@@ -355,11 +353,11 @@ TEST_F(PrioritizedDispatcherTest, Cancel) {
PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', IDLE);
- TestJob* job_c = AddJob('c', IDLE);
- TestJob* job_d = AddJob('d', IDLE);
- TestJob* job_e = AddJob('e', IDLE);
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', IDLE);
+ scoped_ptr<TestJob> job_c = AddJob('c', IDLE);
+ scoped_ptr<TestJob> job_d = AddJob('d', IDLE);
+ scoped_ptr<TestJob> job_e = AddJob('e', IDLE);
ASSERT_FALSE(job_b->running());
ASSERT_FALSE(job_d->running());
@@ -380,14 +378,14 @@ TEST_F(PrioritizedDispatcherTest, Evict) {
PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', LOW);
- TestJob* job_c = AddJob('c', HIGHEST);
- TestJob* job_d = AddJob('d', LOW);
- TestJob* job_e = AddJob('e', HIGHEST);
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', LOW);
+ scoped_ptr<TestJob> job_c = AddJob('c', HIGHEST);
+ scoped_ptr<TestJob> job_d = AddJob('d', LOW);
+ scoped_ptr<TestJob> job_e = AddJob('e', HIGHEST);
- EXPECT_EQ(job_b, dispatcher_->EvictOldestLowest());
- EXPECT_EQ(job_d, dispatcher_->EvictOldestLowest());
+ EXPECT_EQ(job_b.get(), dispatcher_->EvictOldestLowest());
+ EXPECT_EQ(job_d.get(), dispatcher_->EvictOldestLowest());
ASSERT_TRUE(job_a->running());
job_a->Finish();
@@ -410,9 +408,9 @@ TEST_F(PrioritizedDispatcherTest, AddWhileZeroLimits) {
Prepare(limits);
dispatcher_->SetLimitsToZero();
- TestJob* job_a = AddJob('a', LOW);
- TestJob* job_b = AddJob('b', MEDIUM);
- TestJob* job_c = AddJobAtHead('c', MEDIUM);
+ scoped_ptr<TestJob> job_a = AddJob('a', LOW);
+ scoped_ptr<TestJob> job_b = AddJob('b', MEDIUM);
+ scoped_ptr<TestJob> job_c = AddJobAtHead('c', MEDIUM);
EXPECT_EQ(0u, dispatcher_->num_running_jobs());
EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
@@ -437,11 +435,11 @@ TEST_F(PrioritizedDispatcherTest, ReduceLimitsWhileJobQueued) {
PrioritizedDispatcher::Limits initial_limits(NUM_PRIORITIES, 2);
Prepare(initial_limits);
- TestJob* job_a = AddJob('a', MEDIUM);
- TestJob* job_b = AddJob('b', MEDIUM);
- TestJob* job_c = AddJob('c', MEDIUM);
- TestJob* job_d = AddJob('d', MEDIUM);
- TestJob* job_e = AddJob('e', MEDIUM);
+ scoped_ptr<TestJob> job_a = AddJob('a', MEDIUM);
+ scoped_ptr<TestJob> job_b = AddJob('b', MEDIUM);
+ scoped_ptr<TestJob> job_c = AddJob('c', MEDIUM);
+ scoped_ptr<TestJob> job_d = AddJob('d', MEDIUM);
+ scoped_ptr<TestJob> job_e = AddJob('e', MEDIUM);
EXPECT_EQ(2u, dispatcher_->num_running_jobs());
EXPECT_EQ(3u, dispatcher_->num_queued_jobs());
@@ -481,9 +479,9 @@ TEST_F(PrioritizedDispatcherTest, ZeroLimitsThenCancel) {
PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', IDLE);
- TestJob* job_c = AddJob('c', IDLE);
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', IDLE);
+ scoped_ptr<TestJob> job_c = AddJob('c', IDLE);
dispatcher_->SetLimitsToZero();
ASSERT_TRUE(job_a->running());
@@ -511,8 +509,8 @@ TEST_F(PrioritizedDispatcherTest, ZeroLimitsThenIncreasePriority) {
limits.reserved_slots[HIGHEST] = 1;
Prepare(limits);
- TestJob* job_a = AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', IDLE);
+ scoped_ptr<TestJob> job_a = AddJob('a', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', IDLE);
EXPECT_TRUE(job_a->running());
EXPECT_FALSE(job_b->running());
dispatcher_->SetLimitsToZero();
@@ -537,7 +535,7 @@ TEST_F(PrioritizedDispatcherTest, CancelMissing) {
PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1);
Prepare(limits);
AddJob('a', IDLE);
- TestJob* job_b = AddJob('b', IDLE);
+ scoped_ptr<TestJob> job_b = AddJob('b', IDLE);
PrioritizedDispatcher::Handle handle = job_b->handle();
ASSERT_FALSE(handle.is_null());
dispatcher_->Cancel(handle);
diff --git a/chromium/net/base/priority_queue.h b/chromium/net/base/priority_queue.h
index 6b53ecc4fe8..a955e6a3689 100644
--- a/chromium/net/base/priority_queue.h
+++ b/chromium/net/base/priority_queue.h
@@ -5,11 +5,14 @@
#ifndef NET_BASE_PRIORITY_QUEUE_H_
#define NET_BASE_PRIORITY_QUEUE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/registry_controlled_domains/BUILD.gn b/chromium/net/base/registry_controlled_domains/BUILD.gn
index d231ac1a389..d8aa971c1bd 100644
--- a/chromium/net/base/registry_controlled_domains/BUILD.gn
+++ b/chromium/net/base/registry_controlled_domains/BUILD.gn
@@ -3,7 +3,7 @@
# found in the LICENSE file.
action_foreach("registry_controlled_domains") {
- script = "//net/tools/tld_cleanup/make_dafsa.py"
+ script = "//net/tools/dafsa/make_dafsa.py"
sources = [
"effective_tld_names.gperf",
"effective_tld_names_unittest1.gperf",
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 ce9ad58c7fe..3f8c10bbac1 100644
--- a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
+++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
@@ -92,7 +92,6 @@ leasing.aero
logistics.aero
magazine.aero
maintenance.aero
-marketplace.aero
media.aero
microlight.aero
modelling.aero
@@ -115,7 +114,6 @@ show.aero
skydiving.aero
software.aero
student.aero
-taxi.aero
trader.aero
trading.aero
trainer.aero
@@ -158,13 +156,6 @@ org.al
// am : http://en.wikipedia.org/wiki/.am
am
-// an : http://www.una.an/an_domreg/default.asp
-an
-com.an
-net.an
-org.an
-edu.an
-
// ao : http://en.wikipedia.org/wiki/.ao
// http://www.dns.ao/REGISTR.DOC
ao
@@ -1160,7 +1151,7 @@ tv.im
// in : http://en.wikipedia.org/wiki/.in
// see also: https://registry.in/Policies
-// Please note, that nic.in is not an offical eTLD, but used by most
+// Please note, that nic.in is not an official eTLD, but used by most
// government institutions.
in
co.in
@@ -4440,8 +4431,21 @@ gov.ng
mil.ng
mobi.ng
-// ni : http://www.nic.ni/dominios.htm
-*.ni
+// ni : http://www.nic.ni/
+com.ni
+gob.ni
+edu.ni
+org.ni
+nom.ni
+net.ni
+mil.ni
+co.ni
+biz.ni
+web.ni
+int.ni
+ac.ni
+in.ni
+info.ni
// nl : http://en.wikipedia.org/wiki/.nl
// https://www.sidn.nl/
@@ -5786,7 +5790,6 @@ kms.ru
k-uralsk.ru
kustanai.ru
kuzbass.ru
-magnitka.ru
mytis.ru
nakhodka.ru
nkz.ru
@@ -6575,8 +6578,8 @@ lib.wi.us
// lib.wv.us Bug 941670 - Removed at request of Larry W Arnold <arnold@wvlc.lib.wv.us>
lib.wy.us
// k12.ma.us contains school districts in Massachusetts. The 4LDs are
-// managed indepedently except for private (PVT), charter (CHTR) and
-// parochial (PAROCH) schools. Those are delegated dorectly to the
+// managed independently except for private (PVT), charter (CHTR) and
+// parochial (PAROCH) schools. Those are delegated directly to the
// 5LD operators. <k12-ma-hostmaster _ at _ rsuc.gweep.net>
pvt.k12.ma.us
chtr.k12.ma.us
@@ -6930,7 +6933,7 @@ web.za
*.zw
-// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2015-11-12T22:43:48Z
+// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2016-01-04T22:39:54Z
// aaa : 2015-02-26 American Automobile Association, Inc.
aaa
@@ -7103,6 +7106,9 @@ apple
// aquarelle : 2014-07-24 Aquarelle.com
aquarelle
+// arab : 2015-11-12 League of Arab States
+arab
+
// aramco : 2014-11-20 Aramco Services Company
aramco
@@ -7229,6 +7235,9 @@ bcn
// beats : 2015-05-14 Beats Electronics, LLC
beats
+// beauty : 2015-12-03 L'Oréal
+beauty
+
// beer : 2014-01-09 Top Level Domain Holdings Limited
beer
@@ -7334,12 +7343,18 @@ bosch
// bostik : 2015-05-28 Bostik SA
bostik
+// boston : 2015-12-10 Boston Globe Media Partners, LLC
+boston
+
// bot : 2014-12-18 Amazon EU S.à r.l.
bot
// boutique : 2013-11-14 Over Galley, LLC
boutique
+// box : 2015-11-12 NS1 Limited
+box
+
// bradesco : 2014-12-18 Banco Bradesco S.A.
bradesco
@@ -7670,6 +7685,9 @@ crown
// crs : 2014-04-03 Federated Co-operatives Limited
crs
+// cruise : 2015-12-10 Viking River Cruises (Bermuda) Ltd.
+cruise
+
// cruises : 2013-12-05 Spring Way, LLC
cruises
@@ -8066,6 +8084,9 @@ foundation
// fox : 2015-09-11 FOX Registry, LLC
fox
+// free : 2015-12-10 Amazon EU S.à r.l.
+free
+
// fresenius : 2015-07-30 Fresenius Immobilien-Verwaltungs-GmbH
fresenius
@@ -8255,6 +8276,9 @@ guitars
// guru : 2013-08-27 Pioneer Cypress, LLC
guru
+// hair : 2015-12-03 L'Oréal
+hair
+
// hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH
hamburg
@@ -8303,7 +8327,7 @@ hisamitsu
// hitachi : 2014-10-31 Hitachi, Ltd.
hitachi
-// hiv : 2014-03-13 dotHIV gemeinnuetziger e.V.
+// hiv : 2014-03-13
hiv
// hkt : 2015-05-14 PCCW-HKT DataCom Services Limited
@@ -9308,7 +9332,7 @@ prof
// progressive : 2015-07-23 Progressive Casualty Insurance Company
progressive
-// promo : 2014-12-18 Play.PROMO Oy
+// promo : 2014-12-18
promo
// properties : 2013-12-05 Big Pass, LLC
@@ -9443,6 +9467,9 @@ rio
// rip : 2014-07-10 United TLD Holdco Ltd.
rip
+// rmit : 2015-11-19 Royal Melbourne Institute of Technology
+rmit
+
// rocher : 2014-12-18 Ferrero Trading Lux S.A.
rocher
@@ -10085,6 +10112,9 @@ vodka
// volkswagen : 2015-05-14 Volkswagen Group of America Inc.
volkswagen
+// volvo : 2015-11-12 Volvo Holding Sverige Aktiebolag
+volvo
+
// vote : 2013-11-21 Monolith Registry LLC
vote
@@ -10430,6 +10460,9 @@ xin
// xn--ngbe9e0a : 2014-12-04 Kuwait Finance House
بيتك
+// xn--ngbrx : 2015-11-12 League of Arab States
+عرب
+
// xn--nqv7f : 2013-11-14 Public Interest Registry
机构
@@ -11152,6 +11185,7 @@ blogspot.td
blogspot.tw
blogspot.ug
blogspot.vn
+cloudfunctions.net
codespot.com
googleapis.com
googlecode.com
@@ -11159,6 +11193,10 @@ pagespeedmobilizer.com
withgoogle.com
withyoutube.com
+// Hashbang : https://hashbang.sh
+// Hashbang is a non-profit that provides shells and various other services.
+hashbang.sh
+
// Heroku : https://www.heroku.com/
// Submitted by Tom Maher <tmaher@heroku.com> 2013-05-02
herokuapp.com
@@ -11213,6 +11251,10 @@ operaunite.com
// Submitted by Duarte Santos <domain-admin@outsystemscloud.com> 2014-03-11
outsystemscloud.com
+// Pagefront : https://www.pagefronthq.com/
+// Submitted by Jason Kriss <jason@pagefronthq.com> 2015-12-02
+pagefrontapp.com
+
// .pl domains (grandfathered)
art.pl
gliwice.pl
@@ -11234,6 +11276,11 @@ priv.at
// Submitted by Daniel Dent (https://www.danieldent.com/) 2015-07-16
qa2.com
+// Rackmaze LLC : https://www.rackmaze.com
+// Submitted by Kirill Pertsev <kika@rackmaze.com> 2015-12-02
+rackmaze.com
+rackmaze.net
+
// Red Hat, Inc. OpenShift : https://openshift.redhat.com/
// Submitted by Tim Kramer <tkramer@rhcloud.com> 2012-10-24
rhcloud.com
@@ -11254,6 +11301,22 @@ sinaapp.com
vipsinaapp.com
1kapp.com
+// Synology, Inc. : https://www.synology.com/
+// Submitted by Rony Weng <ronyweng@synology.com> 2015-12-02
+synology.me
+diskstation.me
+i234.me
+myds.me
+dscloud.biz
+dscloud.me
+dscloud.mobi
+dsmynas.com
+dsmynas.net
+dsmynas.org
+familyds.com
+familyds.net
+familyds.org
+
// TASK geographical domains (www.task.gda.pl/uslugi/dns)
gda.pl
gdansk.pl
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 94ba5c0ba75..793479d3f54 100644
--- a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
+++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
@@ -70,6 +70,7 @@ ac.ma, 0
ac.me, 0
ac.mu, 0
ac.mw, 0
+ac.ni, 0
ac.nz, 0
ac.pa, 0
ac.pr, 0
@@ -245,7 +246,6 @@ amsterdam.museum, 0
amur.ru, 0
amursk.ru, 0
amusement.aero, 0
-an, 0
an.it, 0
analytics, 0
anamizu.ishikawa.jp, 0
@@ -301,6 +301,7 @@ ar, 0
ar.com, 4
ar.it, 0
ar.us, 0
+arab, 0
arai.shizuoka.jp, 0
arakawa.saitama.jp, 0
arakawa.tokyo.jp, 0
@@ -540,6 +541,7 @@ be.eu.org, 4
bearalvahki.no, 0
beardu.no, 0
beats, 0
+beauty, 0
beauxarts.museum, 0
bedzin.pl, 0
beeldengeluid.museum, 0
@@ -612,6 +614,7 @@ biz.id, 0
biz.ki, 0
biz.mv, 0
biz.mw, 0
+biz.ni, 0
biz.nr, 0
biz.pk, 0
biz.pl, 0
@@ -747,6 +750,7 @@ booking, 0
boots, 0
bosch, 0
bostik, 0
+boston, 0
boston.museum, 0
bot, 0
botanical.museum, 0
@@ -754,6 +758,7 @@ botanicalgarden.museum, 0
botanicgarden.museum, 0
botany.museum, 0
boutique, 0
+box, 0
bozen.it, 0
br, 0
br.com, 4
@@ -1090,6 +1095,7 @@ cloudapp.net, 4
cloudcontrolapp.com, 4
cloudcontrolled.com, 4
cloudfront.net, 4
+cloudfunctions.net, 4
club, 0
club.aero, 0
club.tw, 0
@@ -1140,6 +1146,7 @@ co.mg, 0
co.mu, 0
co.mw, 0
co.na, 0
+co.ni, 0
co.nl, 4
co.no, 4
co.nz, 0
@@ -1185,7 +1192,6 @@ com.af, 0
com.ag, 0
com.ai, 0
com.al, 0
-com.an, 0
com.ar, 0
com.au, 0
com.aw, 0
@@ -1263,6 +1269,7 @@ com.my, 0
com.na, 0
com.nf, 0
com.ng, 0
+com.ni, 0
com.nr, 0
com.om, 0
com.pa, 0
@@ -1384,6 +1391,7 @@ crimea.ua, 0
crotone.it, 0
crown, 0
crs, 0
+cruise, 0
cruises, 0
cs.it, 0
csc, 0
@@ -1485,6 +1493,7 @@ discount, 0
discover, 0
discovery.museum, 0
dish, 0
+diskstation.me, 4
divtasvuodna.no, 0
divttasvuotna.no, 0
diy, 0
@@ -1536,6 +1545,12 @@ drangedal.no, 0
dreamhosters.com, 4
drive, 0
drobak.no, 0
+dscloud.biz, 4
+dscloud.me, 4
+dscloud.mobi, 4
+dsmynas.com, 4
+dsmynas.net, 4
+dsmynas.org, 4
dstv, 0
dtv, 0
dubai, 0
@@ -1604,7 +1619,6 @@ edu, 0
edu.ac, 0
edu.af, 0
edu.al, 0
-edu.an, 0
edu.ar, 0
edu.au, 0
edu.az, 0
@@ -1675,6 +1689,7 @@ edu.mw, 0
edu.mx, 0
edu.my, 0
edu.ng, 0
+edu.ni, 0
edu.nr, 0
edu.om, 0
edu.pa, 0
@@ -1846,6 +1861,9 @@ faith, 0
fam.pk, 0
family, 0
family.museum, 0
+familyds.com, 4
+familyds.net, 4
+familyds.org, 4
fan, 0
fans, 0
far.br, 0
@@ -1987,6 +2005,7 @@ francaise.museum, 0
frankfurt.museum, 0
franziskaner.museum, 0
fredrikstad.no, 0
+free, 0
freemasonry.museum, 0
frei.no, 0
freiburg.museum, 0
@@ -2264,6 +2283,7 @@ gob.es, 0
gob.gt, 0
gob.hn, 0
gob.mx, 0
+gob.ni, 0
gob.pa, 0
gob.pe, 0
gob.pk, 0
@@ -2536,6 +2556,7 @@ haga.tochigi.jp, 0
hagebostad.no, 0
hagi.yamaguchi.jp, 0
haibara.shizuoka.jp, 0
+hair, 0
hakata.fukuoka.jp, 0
hakodate.hokkaido.jp, 0
hakone.kanagawa.jp, 0
@@ -2577,6 +2598,7 @@ harstad.no, 0
harvestcelebration.museum, 0
hasama.oita.jp, 0
hasami.nagasaki.jp, 0
+hashbang.sh, 4
hashikami.aomori.jp, 0
hashima.gifu.jp, 0
hashimoto.wakayama.jp, 0
@@ -2805,6 +2827,7 @@ hyundai, 0
i.bg, 0
i.ph, 0
i.se, 0
+i234.me, 4
ia.us, 0
iamallama.com, 4
ibara.okayama.jp, 0
@@ -2892,6 +2915,7 @@ in-the-band.net, 4
in.eu.org, 4
in.na, 0
in.net, 4
+in.ni, 0
in.rs, 0
in.th, 0
in.ua, 0
@@ -2940,6 +2964,7 @@ info.la, 0
info.mv, 0
info.na, 0
info.nf, 0
+info.ni, 0
info.nr, 0
info.pk, 0
info.pl, 0
@@ -2973,6 +2998,7 @@ int.la, 0
int.lk, 0
int.mv, 0
int.mw, 0
+int.ni, 0
int.pt, 0
int.ru, 0
int.rw, 0
@@ -3978,7 +4004,6 @@ madrid.museum, 0
maebashi.gunma.jp, 0
magadan.ru, 0
magazine.aero, 0
-magnitka.ru, 0
maibara.shiga.jp, 0
maif, 0
mail.pl, 0
@@ -4018,7 +4043,6 @@ maritimo.museum, 0
marker.no, 0
market, 0
marketing, 0
-marketplace.aero, 0
markets, 0
marnardal.no, 0
marriott, 0
@@ -4188,6 +4212,7 @@ mil.mg, 0
mil.mv, 0
mil.my, 0
mil.ng, 0
+mil.ni, 0
mil.no, 0
mil.nz, 0
mil.pe, 0
@@ -4455,6 +4480,7 @@ mx.na, 0
my, 0
my.eu.org, 4
my.id, 0
+myds.me, 4
mykolaiv.ua, 0
myoko.niigata.jp, 0
mypets.ws, 4
@@ -4631,7 +4657,6 @@ net.af, 0
net.ag, 0
net.ai, 0
net.al, 0
-net.an, 0
net.ar, 0
net.au, 0
net.az, 0
@@ -4704,6 +4729,7 @@ net.mx, 0
net.my, 0
net.nf, 0
net.ng, 0
+net.ni, 0
net.nr, 0
net.nz, 0
net.om, 0
@@ -4782,7 +4808,7 @@ ngrok.io, 4
nh.us, 0
nhk, 0
nhs.uk, 0
-ni, 2
+ni, 0
nic.in, 0
nic.tj, 0
nichinan.miyazaki.jp, 0
@@ -4864,6 +4890,7 @@ nom.es, 0
nom.fr, 0
nom.km, 0
nom.mg, 0
+nom.ni, 0
nom.pa, 0
nom.pe, 0
nom.pl, 0
@@ -5117,7 +5144,6 @@ org.af, 0
org.ag, 0
org.ai, 0
org.al, 0
-org.an, 0
org.ar, 0
org.au, 0
org.az, 0
@@ -5198,6 +5224,7 @@ org.mx, 0
org.my, 0
org.na, 0
org.ng, 0
+org.ni, 0
org.nr, 0
org.nz, 0
org.om, 0
@@ -5337,6 +5364,7 @@ paderborn.museum, 0
padova.it, 0
padua.it, 0
page, 0
+pagefrontapp.com, 4
pagespeedmobilizer.com, 4
palace.museum, 0
palana.ru, 0
@@ -5598,6 +5626,8 @@ r.cdn77.net, 4
r.se, 0
ra.it, 0
racing, 0
+rackmaze.com, 4
+rackmaze.net, 4
rade.no, 0
radio.br, 0
radom.pl, 0
@@ -5703,6 +5733,7 @@ ritto.shiga.jp, 0
rivne.ua, 0
rl.no, 0
rm.it, 0
+rmit, 0
rn.it, 0
rnd.ru, 0
rnrt.tn, 0
@@ -6398,6 +6429,7 @@ sydney, 0
sydney.museum, 0
sykkylven.no, 0
symantec, 0
+synology.me, 4
systems, 0
syzran.ru, 0
sz, 0
@@ -6514,7 +6546,6 @@ tattoo, 0
tawaramoto.nara.jp, 0
tax, 0
taxi, 0
-taxi.aero, 0
taxi.br, 0
tc, 0
tci, 0
@@ -7093,6 +7124,7 @@ volkenkunde.museum, 0
volkswagen, 0
vologda.ru, 0
vologda.su, 0
+volvo, 0
volyn.ua, 0
voronezh.ru, 0
voss.no, 0
@@ -7157,6 +7189,7 @@ web.do, 0
web.id, 0
web.lk, 0
web.nf, 0
+web.ni, 0
web.pk, 0
web.tj, 0
web.tr, 0
@@ -7500,6 +7533,7 @@ xn--mxtq1m, 0
xn--mxtq1m.hk, 0
xn--ngbc5azd, 0
xn--ngbe9e0a, 0
+xn--ngbrx, 0
xn--nit225k.jp, 0
xn--nmesjevuemie-tcba.no, 0
xn--nnx388a, 0
diff --git a/chromium/net/base/registry_controlled_domains/registry_controlled_domain.cc b/chromium/net/base/registry_controlled_domains/registry_controlled_domain.cc
index 778e858a159..7e6231663dc 100644
--- a/chromium/net/base/registry_controlled_domains/registry_controlled_domain.cc
+++ b/chromium/net/base/registry_controlled_domains/registry_controlled_domain.cc
@@ -48,6 +48,7 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "net/base/lookup_string_in_fixed_set.h"
#include "net/base/net_module.h"
#include "net/base/net_util.h"
#include "url/gurl.h"
@@ -64,141 +65,6 @@ namespace {
const unsigned char* g_graph = kDafsa;
size_t g_graph_length = sizeof(kDafsa);
-const int kNotFound = -1;
-const int kExceptionRule = 1;
-const int kWildcardRule = 2;
-const int kPrivateRule = 4;
-
-// Read next offset from pos.
-// Returns true if an offset could be read, false otherwise.
-bool GetNextOffset(const unsigned char** pos, const unsigned char* end,
- const unsigned char** offset) {
- if (*pos == end)
- return false;
-
- // When reading an offset the byte array must always contain at least
- // three more bytes to consume. First the offset to read, then a node
- // to skip over and finally a destination node. No object can be smaller
- // than one byte.
- CHECK_LT(*pos + 2, end);
- size_t bytes_consumed;
- switch (**pos & 0x60) {
- case 0x60: // Read three byte offset
- *offset += (((*pos)[0] & 0x1F) << 16) | ((*pos)[1] << 8) | (*pos)[2];
- bytes_consumed = 3;
- break;
- case 0x40: // Read two byte offset
- *offset += (((*pos)[0] & 0x1F) << 8) | (*pos)[1];
- bytes_consumed = 2;
- break;
- default:
- *offset += (*pos)[0] & 0x3F;
- bytes_consumed = 1;
- }
- if ((**pos & 0x80) != 0) {
- *pos = end;
- } else {
- *pos += bytes_consumed;
- }
- return true;
-}
-
-// Check if byte at offset is last in label.
-bool IsEOL(const unsigned char* offset, const unsigned char* end) {
- CHECK_LT(offset, end);
- return (*offset & 0x80) != 0;
-}
-
-// Check if byte at offset matches first character in key.
-// This version matches characters not last in label.
-bool IsMatch(const unsigned char* offset, const unsigned char* end,
- const char* key) {
- CHECK_LT(offset, end);
- return *offset == *key;
-}
-
-// Check if byte at offset matches first character in key.
-// This version matches characters last in label.
-bool IsEndCharMatch(const unsigned char* offset, const unsigned char* end,
- const char* key) {
- CHECK_LT(offset, end);
- return *offset == (*key | 0x80);
-}
-
-// Read return value at offset.
-// Returns true if a return value could be read, false otherwise.
-bool GetReturnValue(const unsigned char* offset, const unsigned char* end,
- int* return_value) {
- CHECK_LT(offset, end);
- if ((*offset & 0xE0) == 0x80) {
- *return_value = *offset & 0x0F;
- return true;
- }
- return false;
-}
-
-// Lookup a domain key in a byte array generated by make_dafsa.py.
-// The rule type is returned if key is found, otherwise kNotFound is returned.
-int LookupString(const unsigned char* graph, size_t length, const char* key,
- size_t key_length) {
- const unsigned char* pos = graph;
- const unsigned char* end = graph + length;
- const unsigned char* offset = pos;
- const char* key_end = key + key_length;
- while (GetNextOffset(&pos, end, &offset)) {
- // char <char>+ end_char offsets
- // char <char>+ return value
- // char end_char offsets
- // char return value
- // end_char offsets
- // return_value
- bool did_consume = false;
- if (key != key_end && !IsEOL(offset, end)) {
- // Leading <char> is not a match. Don't dive into this child
- if (!IsMatch(offset, end, key))
- continue;
- did_consume = true;
- ++offset;
- ++key;
- // Possible matches at this point:
- // <char>+ end_char offsets
- // <char>+ return value
- // end_char offsets
- // return value
- // Remove all remaining <char> nodes possible
- while (!IsEOL(offset, end) && key != key_end) {
- if (!IsMatch(offset, end, key))
- return kNotFound;
- ++key;
- ++offset;
- }
- }
- // Possible matches at this point:
- // end_char offsets
- // return_value
- // If one or more <char> elements were consumed, a failure
- // to match is terminal. Otherwise, try the next node.
- if (key == key_end) {
- int return_value;
- if (GetReturnValue(offset, end, &return_value))
- return return_value;
- // The DAFSA guarantees that if the first char is a match, all
- // remaining char elements MUST match if the key is truly present.
- if (did_consume)
- return kNotFound;
- continue;
- }
- if (!IsEndCharMatch(offset, end, key)) {
- if (did_consume)
- return kNotFound; // Unexpected
- continue;
- }
- ++key;
- pos = ++offset; // Dive into child
- }
- return kNotFound; // No match
-}
-
size_t GetRegistryLengthImpl(
const std::string& host,
UnknownRegistryFilter unknown_filter,
@@ -231,24 +97,25 @@ size_t GetRegistryLengthImpl(
while (1) {
const char* domain_str = host.data() + curr_start;
size_t domain_length = host_check_len - curr_start;
- int type = LookupString(g_graph, g_graph_length, domain_str, domain_length);
- bool do_check =
- type != kNotFound && (!(type & kPrivateRule) ||
- private_filter == INCLUDE_PRIVATE_REGISTRIES);
+ int type = LookupStringInFixedSet(g_graph, g_graph_length, domain_str,
+ domain_length);
+ bool do_check = type != kDafsaNotFound &&
+ (!(type & kDafsaPrivateRule) ||
+ private_filter == INCLUDE_PRIVATE_REGISTRIES);
// If the apparent match is a private registry and we're not including
// those, it can't be an actual match.
if (do_check) {
// Exception rules override wildcard rules when the domain is an exact
// match, but wildcards take precedence when there's a subdomain.
- if (type & kWildcardRule && (prev_start != std::string::npos)) {
+ if (type & kDafsaWildcardRule && (prev_start != std::string::npos)) {
// If prev_start == host_check_begin, then the host is the registry
// itself, so return 0.
return (prev_start == host_check_begin) ? 0
: (host.length() - prev_start);
}
- if (type & kExceptionRule) {
+ if (type & kDafsaExceptionRule) {
if (next_dot == std::string::npos) {
// If we get here, we had an exception rule with no dots (e.g.
// "!foo"). This would only be valid if we had a corresponding
diff --git a/chromium/net/base/registry_controlled_domains/registry_controlled_domain.h b/chromium/net/base/registry_controlled_domains/registry_controlled_domain.h
index efca00fbde1..67f5e3805c2 100644
--- a/chromium/net/base/registry_controlled_domains/registry_controlled_domain.h
+++ b/chromium/net/base/registry_controlled_domains/registry_controlled_domain.h
@@ -113,9 +113,10 @@
#ifndef NET_BASE_REGISTRY_CONTROLLED_DOMAINS_REGISTRY_CONTROLLED_DOMAIN_H_
#define NET_BASE_REGISTRY_CONTROLLED_DOMAINS_REGISTRY_CONTROLLED_DOMAIN_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
class GURL;
diff --git a/chromium/net/base/sdch_dictionary.h b/chromium/net/base/sdch_dictionary.h
index f7c370672db..fcbecdc4862 100644
--- a/chromium/net/base/sdch_dictionary.h
+++ b/chromium/net/base/sdch_dictionary.h
@@ -5,6 +5,8 @@
#ifndef NET_BASE_SDCH_DICTIONARY_H_
#define NET_BASE_SDCH_DICTIONARY_H_
+#include <stddef.h>
+
#include <set>
#include <string>
diff --git a/chromium/net/base/sdch_manager.cc b/chromium/net/base/sdch_manager.cc
index cc8596d02f8..a8272700d95 100644
--- a/chromium/net/base/sdch_manager.cc
+++ b/chromium/net/base/sdch_manager.cc
@@ -4,7 +4,11 @@
#include "net/base/sdch_manager.h"
-#include "base/base64.h"
+#include <limits.h>
+
+#include <utility>
+
+#include "base/base64url.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
@@ -247,7 +251,7 @@ SdchManager::GetDictionarySet(const GURL& target_url) {
UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
- return result.Pass();
+ return result;
}
scoped_ptr<SdchManager::DictionarySet>
@@ -260,15 +264,15 @@ SdchManager::GetDictionarySetByHash(
*problem_code = SDCH_DICTIONARY_HASH_NOT_FOUND;
const auto& it = dictionaries_.find(server_hash);
if (it == dictionaries_.end())
- return result.Pass();
+ return result;
*problem_code = it->second->data.CanUse(target_url);
if (*problem_code != SDCH_OK)
- return result.Pass();
+ return result;
result.reset(new DictionarySet);
result->AddDictionary(it->first, it->second);
- return result.Pass();
+ return result;
}
// static
@@ -277,10 +281,14 @@ void SdchManager::GenerateHash(const std::string& dictionary_text,
char binary_hash[32];
crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash));
- std::string first_48_bits(&binary_hash[0], 6);
- std::string second_48_bits(&binary_hash[6], 6);
- UrlSafeBase64Encode(first_48_bits, client_hash);
- UrlSafeBase64Encode(second_48_bits, server_hash);
+ base::StringPiece first_48_bits(&binary_hash[0], 6);
+ base::StringPiece second_48_bits(&binary_hash[6], 6);
+
+ base::Base64UrlEncode(
+ first_48_bits, base::Base64UrlEncodePolicy::INCLUDE_PADDING, client_hash);
+ base::Base64UrlEncode(second_48_bits,
+ base::Base64UrlEncodePolicy::INCLUDE_PADDING,
+ server_hash);
DCHECK_EQ(server_hash->length(), 8u);
DCHECK_EQ(client_hash->length(), 8u);
@@ -427,17 +435,7 @@ SdchProblemCode SdchManager::RemoveSdchDictionary(
// static
scoped_ptr<SdchManager::DictionarySet>
SdchManager::CreateEmptyDictionarySetForTesting() {
- return scoped_ptr<DictionarySet>(new DictionarySet).Pass();
-}
-
-// static
-void SdchManager::UrlSafeBase64Encode(const std::string& input,
- std::string* output) {
- // Since this is only done during a dictionary load, and hashes are only 8
- // characters, we just do the simple fixup, rather than rewriting the encoder.
- base::Base64Encode(input, output);
- std::replace(output->begin(), output->end(), '+', '-');
- std::replace(output->begin(), output->end(), '/', '_');
+ return scoped_ptr<DictionarySet>(new DictionarySet);
}
scoped_ptr<base::Value> SdchManager::SdchInfoToValue() const {
@@ -458,11 +456,11 @@ scoped_ptr<base::Value> SdchManager::SdchInfoToValue() const {
port_it != entry.second->data.ports().end(); ++port_it) {
port_list->AppendInteger(*port_it);
}
- entry_dict->Set("ports", port_list.Pass());
+ entry_dict->Set("ports", std::move(port_list));
entry_dict->SetString("server_hash", entry.first);
- entry_list->Append(entry_dict.Pass());
+ entry_list->Append(std::move(entry_dict));
}
- value->Set("dictionaries", entry_list.Pass());
+ value->Set("dictionaries", std::move(entry_list));
entry_list.reset(new base::ListValue());
for (DomainBlacklistInfo::const_iterator it = blacklisted_domains_.begin();
@@ -474,11 +472,11 @@ scoped_ptr<base::Value> SdchManager::SdchInfoToValue() const {
if (it->second.count != INT_MAX)
entry_dict->SetInteger("tries", it->second.count);
entry_dict->SetInteger("reason", it->second.reason);
- entry_list->Append(entry_dict.Pass());
+ entry_list->Append(std::move(entry_dict));
}
- value->Set("blacklisted", entry_list.Pass());
+ value->Set("blacklisted", std::move(entry_list));
- return value.Pass();
+ return std::move(value);
}
} // namespace net
diff --git a/chromium/net/base/sdch_manager.h b/chromium/net/base/sdch_manager.h
index 7eec4e0c596..b06bfeffb9f 100644
--- a/chromium/net/base/sdch_manager.h
+++ b/chromium/net/base/sdch_manager.h
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
@@ -216,10 +217,6 @@ class NET_EXPORT SdchManager {
// Support SDCH compression, by advertising in headers.
static bool g_sdch_enabled_;
- // A simple implementation of a RFC 3548 "URL safe" base64 encoder.
- static void UrlSafeBase64Encode(const std::string& input,
- std::string* output);
-
DictionaryMap dictionaries_;
// List domains where decode failures have required disabling sdch.
diff --git a/chromium/net/base/sdch_manager_unittest.cc b/chromium/net/base/sdch_manager_unittest.cc
index 0dfcb54029f..6ae186f090f 100644
--- a/chromium/net/base/sdch_manager_unittest.cc
+++ b/chromium/net/base/sdch_manager_unittest.cc
@@ -7,6 +7,7 @@
#include <string>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_clock.h"
@@ -568,8 +569,8 @@ TEST_F(SdchManagerTest, ExpirationCheckedProperly) {
// It should be visible if looked up by hash whether expired or not.
SdchProblemCode problem_code;
scoped_ptr<SdchManager::DictionarySet> hash_set(
- sdch_manager()->GetDictionarySetByHash(
- target_gurl, server_hash, &problem_code).Pass());
+ sdch_manager()->GetDictionarySetByHash(target_gurl, server_hash,
+ &problem_code));
ASSERT_TRUE(hash_set);
ASSERT_EQ(SDCH_OK, problem_code);
diff --git a/chromium/net/base/sdch_net_log_params.cc b/chromium/net/base/sdch_net_log_params.cc
index 81f84760d81..c8027427d3a 100644
--- a/chromium/net/base/sdch_net_log_params.cc
+++ b/chromium/net/base/sdch_net_log_params.cc
@@ -4,6 +4,8 @@
#include "net/base/sdch_net_log_params.h"
+#include <utility>
+
#include "base/values.h"
#include "net/base/net_errors.h"
#include "url/gurl.h"
@@ -16,7 +18,7 @@ scoped_ptr<base::Value> NetLogSdchResourceProblemCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("sdch_problem_code", problem);
dict->SetInteger("net_error", ERR_FAILED);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSdchDictionaryFetchProblemCallback(
@@ -29,7 +31,7 @@ scoped_ptr<base::Value> NetLogSdchDictionaryFetchProblemCallback(
dict->SetString("dictionary_url", url.spec());
if (is_error)
dict->SetInteger("net_error", ERR_FAILED);
- return dict.Pass();
+ return std::move(dict);
}
} // namespace net
diff --git a/chromium/net/base/sockaddr_storage.cc b/chromium/net/base/sockaddr_storage.cc
new file mode 100644
index 00000000000..2822e07a707
--- /dev/null
+++ b/chromium/net/base/sockaddr_storage.cc
@@ -0,0 +1,27 @@
+// 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/sockaddr_storage.h"
+
+#include <string.h>
+
+namespace net {
+
+SockaddrStorage::SockaddrStorage()
+ : addr_len(sizeof(addr_storage)),
+ addr(reinterpret_cast<struct sockaddr*>(&addr_storage)) {}
+
+SockaddrStorage::SockaddrStorage(const SockaddrStorage& other)
+ : addr_len(other.addr_len),
+ addr(reinterpret_cast<struct sockaddr*>(&addr_storage)) {
+ memcpy(addr, other.addr, addr_len);
+}
+
+void SockaddrStorage::operator=(const SockaddrStorage& other) {
+ addr_len = other.addr_len;
+ // addr is already set to &this->addr_storage by default ctor.
+ memcpy(addr, other.addr, addr_len);
+}
+
+} // namespace net
diff --git a/chromium/net/base/sockaddr_storage.h b/chromium/net/base/sockaddr_storage.h
new file mode 100644
index 00000000000..cc312316d55
--- /dev/null
+++ b/chromium/net/base/sockaddr_storage.h
@@ -0,0 +1,35 @@
+// 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_SOCKADDR_STORAGE_H_
+#define NET_BASE_SOCKADDR_STORAGE_H_
+
+#include "build/build_config.h"
+
+#if defined(OS_POSIX)
+#include <sys/socket.h>
+#include <sys/types.h>
+#elif defined(OS_WIN)
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+// Convenience struct for when you need a |struct sockaddr|.
+struct NET_EXPORT SockaddrStorage {
+ SockaddrStorage();
+ SockaddrStorage(const SockaddrStorage& other);
+ void operator=(const SockaddrStorage& other);
+
+ struct sockaddr_storage addr_storage;
+ socklen_t addr_len;
+ struct sockaddr* const addr;
+};
+
+} // namespace net
+
+#endif // NET_BASE_SOCKADDR_STORAGE_H_
diff --git a/chromium/net/base/socket_performance_watcher.cc b/chromium/net/base/socket_performance_watcher.cc
new file mode 100644
index 00000000000..aa0dab3b03c
--- /dev/null
+++ b/chromium/net/base/socket_performance_watcher.cc
@@ -0,0 +1,34 @@
+// Copyright 2015 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/socket_performance_watcher.h"
+
+#include "base/logging.h"
+
+namespace net {
+
+SocketPerformanceWatcher::SocketPerformanceWatcher(
+ const SocketPerformanceWatcherFactory::Protocol protocol,
+ SocketPerformanceWatcherFactory* socket_performance_watcher_factory)
+ : protocol_(protocol),
+ socket_performance_watcher_factory_(socket_performance_watcher_factory) {
+ DCHECK(socket_performance_watcher_factory_);
+
+ switch (protocol) {
+ case SocketPerformanceWatcherFactory::PROTOCOL_TCP:
+ case SocketPerformanceWatcherFactory::PROTOCOL_QUIC:
+ return;
+ default:
+ NOTREACHED();
+ }
+}
+
+SocketPerformanceWatcher::~SocketPerformanceWatcher() {}
+
+void SocketPerformanceWatcher::OnUpdatedRTTAvailable(
+ const base::TimeDelta& rtt) const {
+ socket_performance_watcher_factory_->OnUpdatedRTTAvailable(protocol_, rtt);
+}
+
+} // namespace net
diff --git a/chromium/net/base/socket_performance_watcher.h b/chromium/net/base/socket_performance_watcher.h
index 6034e4473a5..e0e76327ce6 100644
--- a/chromium/net/base/socket_performance_watcher.h
+++ b/chromium/net/base/socket_performance_watcher.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "net/base/net_export.h"
+#include "net/base/socket_performance_watcher_factory.h"
namespace base {
class TimeDelta;
@@ -18,18 +19,28 @@ namespace net {
// socket statistics.
class NET_EXPORT_PRIVATE SocketPerformanceWatcher {
public:
- virtual ~SocketPerformanceWatcher() {}
+ // |socket_performance_watcher_factory| is the factory that constructed
+ // |this| watcher.
+ SocketPerformanceWatcher(
+ const SocketPerformanceWatcherFactory::Protocol protocol,
+ SocketPerformanceWatcherFactory* socket_performance_watcher_factory);
+
+ virtual ~SocketPerformanceWatcher();
// Called when updated transport layer RTT information is available. This
// must be the transport layer RTT from this device to the remote transport
- // layer endpoint. If the request goes through a HTTP proxy, it should
- // provide the RTT to the proxy.
- virtual void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) = 0;
-
- protected:
- SocketPerformanceWatcher() {}
+ // layer endpoint. This method is called immediately after the observation is
+ // made, hence no timestamp.
+ void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) const;
private:
+ // Transport layer protocol used by the socket that |this| is watching.
+ const SocketPerformanceWatcherFactory::Protocol protocol_;
+
+ // |socket_performance_watcher_factory_| is the factory that created
+ // |this| watcher.
+ SocketPerformanceWatcherFactory* socket_performance_watcher_factory_;
+
DISALLOW_COPY_AND_ASSIGN(SocketPerformanceWatcher);
};
diff --git a/chromium/net/base/socket_performance_watcher_factory.h b/chromium/net/base/socket_performance_watcher_factory.h
index fc4767cb5b2..cbd607ab336 100644
--- a/chromium/net/base/socket_performance_watcher_factory.h
+++ b/chromium/net/base/socket_performance_watcher_factory.h
@@ -9,29 +9,38 @@
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
+namespace base {
+class TimeDelta;
+} // namespace base
+
namespace net {
-class SocketRecorder;
+class SocketPerformanceWatcher;
// SocketPerformanceWatcherFactory creates socket performance watcher for
// different type of sockets.
class NET_EXPORT_PRIVATE SocketPerformanceWatcherFactory {
public:
- virtual ~SocketPerformanceWatcherFactory() {}
+ // Transport layer protocol used by the socket that are supported by
+ // |SocketPerformanceWatcherFactory|.
+ enum Protocol { PROTOCOL_TCP, PROTOCOL_QUIC };
- // Creates a socket performance watcher that will record statistics for a
- // single TCP socket. Implementations must return a valid, unique
- // SocketRecorder for every call; recorders must not be shared across calls
- // or objects, nor is nullptr valid.
- virtual scoped_ptr<SocketPerformanceWatcher>
- CreateTCPSocketPerformanceWatcher() const = 0;
+ virtual ~SocketPerformanceWatcherFactory() {}
// Creates a socket performance watcher that will record statistics for a
- // single UDP socket. Implementations must return a valid, unique
- // SocketRecorder for every call; recorders must not be shared across calls
- // or objects, nor is nullptr valid.
- virtual scoped_ptr<SocketPerformanceWatcher>
- CreateUDPSocketPerformanceWatcher() const = 0;
+ // single socket that uses |protocol| as the transport layer protocol.
+ // Implementations must return a valid, unique SocketRecorder for every call;
+ // recorders must not be shared across calls or objects, nor is nullptr valid.
+ virtual scoped_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
+ const Protocol protocol) = 0;
+
+ // Called when updated transport layer RTT information is available from one
+ // of the watchers created by |this|. |protocol| is the protocol that was used
+ // by the watcher. |rtt| must be the transport layer RTT from this device to
+ // the remote transport layer endpoint. These methods are called immediately
+ // after the observation is made, hence no timestamp.
+ virtual void OnUpdatedRTTAvailable(const Protocol protocol,
+ const base::TimeDelta& rtt) = 0;
protected:
SocketPerformanceWatcherFactory() {}
diff --git a/chromium/net/base/stale_while_revalidate_experiment_domains.cc b/chromium/net/base/stale_while_revalidate_experiment_domains.cc
new file mode 100644
index 00000000000..1e295b15eac
--- /dev/null
+++ b/chromium/net/base/stale_while_revalidate_experiment_domains.cc
@@ -0,0 +1,74 @@
+// Copyright 2015 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/stale_while_revalidate_experiment_domains.h"
+
+#include <stddef.h>
+
+#include "base/logging.h"
+#include "net/base/lookup_string_in_fixed_set.h"
+
+namespace net {
+
+namespace {
+
+#include "net/base/stale_while_revalidate_experiment_domains-inc.cc"
+
+// The maximum number of dots in any domain in the list. This is used to ignore
+// parts of the host name that are irrelevant, and so must be correct.
+const int kMaxDots = 2;
+
+// The minimum number of dots in a host necessary for it to be considered a
+// match.
+const int kMinDots = 1;
+
+bool LookupTail(const base::StringPiece& host, size_t pos) {
+ DCHECK_LT(pos, host.size());
+ return LookupStringInFixedSet(kDafsa, sizeof(kDafsa), host.data() + pos,
+ host.size() - pos) == 0;
+}
+
+bool LookupTrimmedHost(const base::StringPiece& trimmed) {
+ // |trimmed| contains at least one non-dot. The maximum number of dots we want
+ // to look for is kMaxInterestingDots; any dots before that will not affect
+ // the outcome of the match.
+ const int kMaxInterestingDots = kMaxDots + 1;
+
+ // Scan |trimmed| from the right for up to kMaxInterestingDots dots, checking
+ // for a domain match at each position.
+ int found_dots = 0;
+ size_t pos = base::StringPiece::npos;
+ while (found_dots < kMaxInterestingDots) {
+ pos = trimmed.find_last_of('.', pos);
+ if (pos == base::StringPiece::npos)
+ break;
+ ++found_dots;
+ if (found_dots > kMinDots && LookupTail(trimmed, pos + 1))
+ return true;
+ if (pos == 0)
+ return false;
+ --pos;
+ }
+
+ if (found_dots >= kMinDots && found_dots <= kMaxDots) {
+ // We might have an exact match.
+ return LookupTail(trimmed, 0);
+ }
+
+ return false;
+}
+
+} // namespace
+
+bool IsHostInStaleWhileRevalidateExperimentDomain(
+ const base::StringPiece& host) {
+ // Ignore trailing dots.
+ size_t last_interesting_pos = host.find_last_not_of('.');
+ if (last_interesting_pos == base::StringPiece::npos)
+ return false;
+
+ return LookupTrimmedHost(host.substr(0, last_interesting_pos + 1));
+}
+
+} // namespace net
diff --git a/chromium/net/base/stale_while_revalidate_experiment_domains.gperf b/chromium/net/base/stale_while_revalidate_experiment_domains.gperf
new file mode 100644
index 00000000000..06917432b4c
--- /dev/null
+++ b/chromium/net/base/stale_while_revalidate_experiment_domains.gperf
@@ -0,0 +1,116 @@
+%{
+
+// List of top 100 domains which are expected to benefit from the implementation
+// of the stale-while-revalidate Cache-Control directive. This list
+// is only used to generate histograms to measure the effectiveness of the
+// feature. These domains are given no special treatment.
+//
+// This file is temporary for the duration of the evaluation of the
+// stale-while-revalidate feature. crbug.com/564517
+
+// This file is converted to a DAFSA by make_dafsa.py.
+
+%}
+
+%%
+123rf.com, 0
+academia.edu, 0
+avclub.com, 0
+baixaki.com.br, 0
+bgr.com, 0
+britannica.com, 0
+buenastareas.com, 0
+buscape.com.br, 0
+cbslocal.com, 0
+cbssports.com, 0
+ccm.net, 0
+chegg.com, 0
+clarin.com, 0
+commentcamarche.net, 0
+coursehero.com, 0
+crunchbase.com, 0
+deadline.com, 0
+dicionarioinformal.com.br, 0
+digitaltrends.com, 0
+dropbox.com, 0
+encyclopedia.com, 0
+enotes.com, 0
+eonline.com, 0
+express.co.uk, 0
+extradeportes.net, 0
+firstpost.com, 0
+food.com, 0
+foxnews.com, 0
+giphy.com, 0
+gmailblog.blogspot.com, 0
+goodreads.com, 0
+googleapps.com, 0
+googleblog.blogspot.com, 0
+guiamais.com.br, 0
+gumtree.com, 0
+haberler.com, 0
+heavy.com, 0
+history.com, 0
+hollywoodlife.com, 0
+howtogeek.com, 0
+ibtimes.co.in, 0
+ilpost.it, 0
+iltalehti.fi, 0
+iltasanomat.fi, 0
+instructables.com, 0
+journaldesfemmes.com, 0
+kekanto.com.br, 0
+lavanguardia.com, 0
+legacy.com, 0
+liberoquotidiano.it, 0
+linternaute.com, 0
+livescience.com, 0
+lolking.net, 0
+marmiton.org, 0
+meinestadt.de, 0
+merriam-webster.com, 0
+miniclip.com, 0
+mmajunkie.com, 0
+mobile01.com, 0
+moviepilot.de, 0
+mymovies.it, 0
+naszemiasto.pl, 0
+natemat.pl, 0
+ndtv.com, 0
+nesn.com, 0
+paginegialle.it, 0
+parismatch.com, 0
+popsugar.com, 0
+prezi.com, 0
+programme-tv.net, 0
+purepeople.com, 0
+qz.com, 0
+radaronline.com, 0
+shmoop.com, 0
+slate.fr, 0
+sondakika.com, 0
+songtexte.com, 0
+study.com, 0
+superpages.com, 0
+techtimes.com, 0
+tecmundo.com.br, 0
+telegraaf.nl, 0
+tf1.fr, 0
+tv.com, 0
+tvline.com, 0
+variety.com, 0
+venturebeat.com, 0
+vocabulary.com, 0
+wattpad.com, 0
+weather.com, 0
+weebly.com, 0
+whitepages.com, 0
+wordpress.com, 0
+wordpress.org, 0
+xda-developers.com, 0
+yourdictionary.com, 0
+zadane.pl, 0
+zillow.com, 0
+znanija.com, 0
+zoopla.co.uk, 0
+%%
diff --git a/chromium/net/base/stale_while_revalidate_experiment_domains.h b/chromium/net/base/stale_while_revalidate_experiment_domains.h
new file mode 100644
index 00000000000..1f2f35a9629
--- /dev/null
+++ b/chromium/net/base/stale_while_revalidate_experiment_domains.h
@@ -0,0 +1,24 @@
+// Copyright 2015 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_STALE_WHILE_REVALIDATE_EXPERIMENT_DOMAINS_H_
+#define NET_BASE_STALE_WHILE_REVALIDATE_EXPERIMENT_DOMAINS_H_
+
+#include "base/strings/string_piece.h"
+
+namespace net {
+
+// Returns true if |host| matches one of the domains of interest for
+// stale-while-revalidate histograms. If "example.com" was in the list, then
+// "example.com" would match, as would "www.example.com" and "a.b.example.com",
+// but not "com" or "an-example.com". Trailing '.' characters on |host| are
+// ignored. |host| is expected to be canonicalised to lowercase (as performed by
+// GURL).
+// TODO(ricea): Remove this in April 2016 or before. crbug.com/348877
+bool IsHostInStaleWhileRevalidateExperimentDomain(
+ const base::StringPiece& host);
+
+} // namespace net
+
+#endif // NET_BASE_STALE_WHILE_REVALIDATE_EXPERIMENT_DOMAINS_H_
diff --git a/chromium/net/base/stale_while_revalidate_experiment_domains_unittest.cc b/chromium/net/base/stale_while_revalidate_experiment_domains_unittest.cc
new file mode 100644
index 00000000000..9b6b844b9fd
--- /dev/null
+++ b/chromium/net/base/stale_while_revalidate_experiment_domains_unittest.cc
@@ -0,0 +1,63 @@
+// Copyright 2015 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/stale_while_revalidate_experiment_domains.h"
+
+#include <iosfwd>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+using ::testing::TestWithParam;
+using ::testing::ValuesIn;
+
+const struct Expectation {
+ const char* host;
+ bool result;
+} kExpectations[] = {
+ {"wordpress.com", true},
+ {"tf1.fr", true},
+ {"wordpress.com.", true},
+ {"www.wordpress.com", true},
+ {"www.wordpress.com.", true},
+ {"a.b.wordpress.com", true},
+ {"a.b.c.d.wordpress.com", true},
+ {"www..wordpress.com", true},
+ {"www.wordpress..com", false},
+ {"a-b-wordpress.com", false},
+ {"com", false},
+ {".", false},
+ {"", false},
+ {"..", false},
+ {"ordpress.com", false},
+ {"wordpress.co", false},
+ {"a", false},
+ {"a.b", false},
+ {"a.b.c", false},
+ {"a.b.c.d.e", false},
+};
+
+void PrintTo(const Expectation& expectation, std::ostream* os) {
+ *os << "{\"" << expectation.host << "\" ," << std::boolalpha
+ << expectation.result << "}";
+}
+
+class MatchTest : public TestWithParam<Expectation> {};
+
+TEST_P(MatchTest, CheckExpectation) {
+ const Expectation& expectation = GetParam();
+ EXPECT_EQ(expectation.result,
+ IsHostInStaleWhileRevalidateExperimentDomain(expectation.host));
+}
+
+INSTANTIATE_TEST_CASE_P(StaleWhileRevalidateExperimentDomainsTest,
+ MatchTest,
+ ValuesIn(kExpectations));
+
+} // namespace
+
+} // namespace net
diff --git a/chromium/net/base/static_cookie_policy.h b/chromium/net/base/static_cookie_policy.h
index 023153199db..5adc194684b 100644
--- a/chromium/net/base/static_cookie_policy.h
+++ b/chromium/net/base/static_cookie_policy.h
@@ -5,7 +5,7 @@
#ifndef NET_BASE_STATIC_COOKIE_POLICY_H_
#define NET_BASE_STATIC_COOKIE_POLICY_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
class GURL;
diff --git a/chromium/net/base/sys_addrinfo.h b/chromium/net/base/sys_addrinfo.h
index 62a6317e887..78f491c0263 100644
--- a/chromium/net/base/sys_addrinfo.h
+++ b/chromium/net/base/sys_addrinfo.h
@@ -10,6 +10,7 @@
// getaddrinfo()
// freeaddrinfo()
// AI_*
+// AF_*
//
// Prefer including this file instead of directly writing the #if / #else,
// since it avoids duplicating the platform-specific selections.
diff --git a/chromium/net/base/test_completion_callback.h b/chromium/net/base/test_completion_callback.h
index 236c9b3f758..631dc5c2c79 100644
--- a/chromium/net/base/test_completion_callback.h
+++ b/chromium/net/base/test_completion_callback.h
@@ -5,8 +5,11 @@
#ifndef NET_BASE_TEST_COMPLETION_CALLBACK_H_
#define NET_BASE_TEST_COMPLETION_CALLBACK_H_
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"
diff --git a/chromium/net/base/test_completion_callback_unittest.cc b/chromium/net/base/test_completion_callback_unittest.cc
index 454da5dc727..9a40b240fe2 100644
--- a/chromium/net/base/test_completion_callback_unittest.cc
+++ b/chromium/net/base/test_completion_callback_unittest.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/worker_pool.h"
diff --git a/chromium/net/base/upload_bytes_element_reader.cc b/chromium/net/base/upload_bytes_element_reader.cc
index fd74dd80e55..b8b0f0103fb 100644
--- a/chromium/net/base/upload_bytes_element_reader.cc
+++ b/chromium/net/base/upload_bytes_element_reader.cc
@@ -5,7 +5,6 @@
#include "net/base/upload_bytes_element_reader.h"
#include "base/logging.h"
-#include "base/stl_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -59,10 +58,9 @@ int UploadBytesElementReader::Read(IOBuffer* buf,
return num_bytes_to_read;
}
-
UploadOwnedBytesElementReader::UploadOwnedBytesElementReader(
std::vector<char>* data)
- : UploadBytesElementReader(vector_as_array(data), data->size()) {
+ : UploadBytesElementReader(data->data(), data->size()) {
data_.swap(*data);
}
diff --git a/chromium/net/base/upload_bytes_element_reader.h b/chromium/net/base/upload_bytes_element_reader.h
index a5ee8a707ca..90148ec0571 100644
--- a/chromium/net/base/upload_bytes_element_reader.h
+++ b/chromium/net/base/upload_bytes_element_reader.h
@@ -5,11 +5,13 @@
#ifndef NET_BASE_UPLOAD_BYTES_ELEMENT_READER_H_
#define NET_BASE_UPLOAD_BYTES_ELEMENT_READER_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/base/upload_element_reader.h"
diff --git a/chromium/net/base/upload_bytes_element_reader_unittest.cc b/chromium/net/base/upload_bytes_element_reader_unittest.cc
index 1d2f52ffb2c..1dce3fb5c77 100644
--- a/chromium/net/base/upload_bytes_element_reader_unittest.cc
+++ b/chromium/net/base/upload_bytes_element_reader_unittest.cc
@@ -4,7 +4,6 @@
#include "net/base/upload_bytes_element_reader.h"
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
diff --git a/chromium/net/base/upload_data_stream.cc b/chromium/net/base/upload_data_stream.cc
index c2d88f9742a..23c760ea0a4 100644
--- a/chromium/net/base/upload_data_stream.cc
+++ b/chromium/net/base/upload_data_stream.cc
@@ -88,7 +88,7 @@ bool UploadDataStream::IsInMemory() const {
return false;
}
-const ScopedVector<UploadElementReader>*
+const std::vector<scoped_ptr<UploadElementReader>>*
UploadDataStream::GetElementReaders() const {
return NULL;
}
diff --git a/chromium/net/base/upload_data_stream.h b/chromium/net/base/upload_data_stream.h
index a4573eae6d5..2d06b44762d 100644
--- a/chromium/net/base/upload_data_stream.h
+++ b/chromium/net/base/upload_data_stream.h
@@ -5,9 +5,12 @@
#ifndef NET_BASE_UPLOAD_DATA_STREAM_H_
#define NET_BASE_UPLOAD_DATA_STREAM_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <vector>
+
#include "base/macros.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -86,8 +89,8 @@ class NET_EXPORT UploadDataStream {
virtual bool IsInMemory() const;
// Returns a list of element readers owned by |this|, if it has any.
- virtual const ScopedVector<UploadElementReader>*
- GetElementReaders() const;
+ virtual const std::vector<scoped_ptr<UploadElementReader>>*
+ GetElementReaders() const;
protected:
// Must be called by subclasses when InitInternal and ReadInternal complete
diff --git a/chromium/net/base/upload_element_reader.h b/chromium/net/base/upload_element_reader.h
index 2814efa33f1..049f38ef607 100644
--- a/chromium/net/base/upload_element_reader.h
+++ b/chromium/net/base/upload_element_reader.h
@@ -5,7 +5,9 @@
#ifndef NET_BASE_UPLOAD_ELEMENT_READER_H_
#define NET_BASE_UPLOAD_ELEMENT_READER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/base/upload_file_element_reader.h b/chromium/net/base/upload_file_element_reader.h
index bf46350e7bd..f246553d421 100644
--- a/chromium/net/base/upload_file_element_reader.h
+++ b/chromium/net/base/upload_file_element_reader.h
@@ -5,10 +5,13 @@
#ifndef NET_BASE_UPLOAD_FILE_ELEMENT_READER_H_
#define NET_BASE_UPLOAD_FILE_ELEMENT_READER_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/net/base/upload_file_element_reader_unittest.cc b/chromium/net/base/upload_file_element_reader_unittest.cc
index 2a61dc622f5..abffc2a6e76 100644
--- a/chromium/net/base/upload_file_element_reader_unittest.cc
+++ b/chromium/net/base/upload_file_element_reader_unittest.cc
@@ -4,6 +4,10 @@
#include "net/base/upload_file_element_reader.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
@@ -34,7 +38,7 @@ class UploadFileElementReaderTest : public PlatformTest {
reader_.reset(new UploadFileElementReader(
base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_, 0,
- kuint64max, base::Time()));
+ std::numeric_limits<uint64_t>::max(), base::Time()));
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING, reader_->Init(callback.callback()));
EXPECT_EQ(OK, callback.WaitForResult());
@@ -205,8 +209,8 @@ TEST_F(UploadFileElementReaderTest, FileChanged) {
const base::Time expected_modification_time =
info.last_modified - base::TimeDelta::FromSeconds(1);
reader_.reset(new UploadFileElementReader(
- base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_, 0, kuint64max,
- expected_modification_time));
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_, 0,
+ std::numeric_limits<uint64_t>::max(), expected_modification_time));
TestCompletionCallback init_callback;
ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult());
@@ -219,8 +223,8 @@ TEST_F(UploadFileElementReaderTest, InexactExpectedTimeStamp) {
const base::Time expected_modification_time =
info.last_modified - base::TimeDelta::FromMilliseconds(900);
reader_.reset(new UploadFileElementReader(
- base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_, 0, kuint64max,
- expected_modification_time));
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_, 0,
+ std::numeric_limits<uint64_t>::max(), expected_modification_time));
TestCompletionCallback init_callback;
ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(OK, init_callback.WaitForResult());
@@ -228,9 +232,9 @@ TEST_F(UploadFileElementReaderTest, InexactExpectedTimeStamp) {
TEST_F(UploadFileElementReaderTest, WrongPath) {
const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path"));
- reader_.reset(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- wrong_path, 0, kuint64max, base::Time()));
+ reader_.reset(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), wrong_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time()));
TestCompletionCallback init_callback;
ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(ERR_FILE_NOT_FOUND, init_callback.WaitForResult());
diff --git a/chromium/net/base/upload_progress.h b/chromium/net/base/upload_progress.h
index 1389ecc2ad7..25194aa1504 100644
--- a/chromium/net/base/upload_progress.h
+++ b/chromium/net/base/upload_progress.h
@@ -5,7 +5,7 @@
#ifndef NET_BASE_UPLOAD_PROGRESS_H_
#define NET_BASE_UPLOAD_PROGRESS_H_
-#include "base/basictypes.h"
+#include <stdint.h>
namespace net {
diff --git a/chromium/net/base/url_util.cc b/chromium/net/base/url_util.cc
index 791f1258fba..a5818075ca5 100644
--- a/chromium/net/base/url_util.cc
+++ b/chromium/net/base/url_util.cc
@@ -4,10 +4,7 @@
#include "net/base/url_util.h"
-#include <utility>
-
#include "base/logging.h"
-#include "base/strings/string_piece.h"
#include "net/base/escape.h"
#include "url/gurl.h"
@@ -132,4 +129,22 @@ bool GetValueForKeyInQuery(const GURL& url,
return false;
}
+std::string TrimEndingDot(const base::StringPiece& host) {
+ base::StringPiece host_trimmed = host;
+ size_t len = host_trimmed.length();
+ if (len > 1 && host_trimmed[len - 1] == '.') {
+ host_trimmed.remove_suffix(1);
+ }
+ return host_trimmed.as_string();
+}
+
+void GetIdentityFromURL(const GURL& url,
+ base::string16* username,
+ base::string16* password) {
+ UnescapeRule::Type flags =
+ UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS;
+ *username = UnescapeAndDecodeUTF8URLComponent(url.username(), flags);
+ *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags);
+}
+
} // namespace net
diff --git a/chromium/net/base/url_util.h b/chromium/net/base/url_util.h
index 533c908e553..239a93cd4d7 100644
--- a/chromium/net/base/url_util.h
+++ b/chromium/net/base/url_util.h
@@ -7,7 +7,9 @@
#include <string>
-#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "url/third_party/mozilla/url_parse.h"
@@ -77,6 +79,16 @@ NET_EXPORT bool GetValueForKeyInQuery(const GURL& url,
const std::string& search_key,
std::string* out_value);
+
+// Returns the hostname by trimming the ending dot, if one exists.
+NET_EXPORT std::string TrimEndingDot(const base::StringPiece& host);
+
+// Extracts the unescaped username/password from |url|, saving the results
+// into |*username| and |*password|.
+NET_EXPORT_PRIVATE void GetIdentityFromURL(const GURL& url,
+ base::string16* username,
+ base::string16* password);
+
} // namespace net
#endif // NET_BASE_URL_UTIL_H_
diff --git a/chromium/net/base/url_util_unittest.cc b/chromium/net/base/url_util_unittest.cc
index 158e2740306..863e5528721 100644
--- a/chromium/net/base/url_util_unittest.cc
+++ b/chromium/net/base/url_util_unittest.cc
@@ -4,9 +4,15 @@
#include "net/base/url_util.h"
+#include "base/format_macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/strings/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+using base::ASCIIToUTF16;
+using base::WideToUTF16;
+
namespace net {
namespace {
@@ -159,5 +165,76 @@ TEST(UrlUtilTest, ParseQueryInvalidURL) {
EXPECT_TRUE(it.IsAtEnd());
}
+TEST(NetUtilTest, GetIdentityFromURL) {
+ struct {
+ const char* const input_url;
+ const char* const expected_username;
+ const char* const expected_password;
+ } tests[] = {
+ {
+ "http://username:password@google.com",
+ "username",
+ "password",
+ },
+ { // Test for http://crbug.com/19200
+ "http://username:p@ssword@google.com",
+ "username",
+ "p@ssword",
+ },
+ { // Special URL characters should be unescaped.
+ "http://username:p%3fa%26s%2fs%23@google.com",
+ "username",
+ "p?a&s/s#",
+ },
+ { // Username contains %20.
+ "http://use rname:password@google.com",
+ "use rname",
+ "password",
+ },
+ { // Keep %00 as is.
+ "http://use%00rname:password@google.com",
+ "use%00rname",
+ "password",
+ },
+ { // Use a '+' in the username.
+ "http://use+rname:password@google.com",
+ "use+rname",
+ "password",
+ },
+ { // Use a '&' in the password.
+ "http://username:p&ssword@google.com",
+ "username",
+ "p&ssword",
+ },
+ };
+ for (size_t i = 0; i < arraysize(tests); ++i) {
+ SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
+ tests[i].input_url));
+ GURL url(tests[i].input_url);
+
+ base::string16 username, password;
+ GetIdentityFromURL(url, &username, &password);
+
+ EXPECT_EQ(ASCIIToUTF16(tests[i].expected_username), username);
+ EXPECT_EQ(ASCIIToUTF16(tests[i].expected_password), password);
+ }
+}
+
+// Try extracting a username which was encoded with UTF8.
+TEST(UrlUtilTest, GetIdentityFromURL_UTF8) {
+ GURL url(WideToUTF16(L"http://foo:\x4f60\x597d@blah.com"));
+
+ EXPECT_EQ("foo", url.username());
+ EXPECT_EQ("%E4%BD%A0%E5%A5%BD", url.password());
+
+ // Extract the unescaped identity.
+ base::string16 username, password;
+ GetIdentityFromURL(url, &username, &password);
+
+ // Verify that it was decoded as UTF8.
+ EXPECT_EQ(ASCIIToUTF16("foo"), username);
+ EXPECT_EQ(WideToUTF16(L"\x4f60\x597d"), password);
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/base/winsock_util.h b/chromium/net/base/winsock_util.h
index 36d670b1a2d..80edc3faf1a 100644
--- a/chromium/net/base/winsock_util.h
+++ b/chromium/net/base/winsock_util.h
@@ -5,12 +5,16 @@
#ifndef NET_BASE_WINSOCK_UTIL_H_
#define NET_BASE_WINSOCK_UTIL_H_
+#include <stddef.h>
#include <winsock2.h>
#include "net/base/net_export.h"
namespace net {
+// Bluetooth address size. Windows Bluetooth is supported via winsock.
+static const size_t kBluetoothAddressSize = 6;
+
// Assert that the (manual-reset) event object is not signaled.
void AssertEventNotSignaled(WSAEVENT hEvent);
diff --git a/chromium/net/base/zap.cc b/chromium/net/base/zap.cc
index 331d696557f..6bc2d350129 100644
--- a/chromium/net/base/zap.cc
+++ b/chromium/net/base/zap.cc
@@ -4,6 +4,8 @@
#include "net/base/zap.h"
+#include <string.h>
+
namespace net {
void ZapBuf(void* buf, size_t buf_len) {
diff --git a/chromium/net/base/zap.h b/chromium/net/base/zap.h
index 5be113add3f..be60828b963 100644
--- a/chromium/net/base/zap.h
+++ b/chromium/net/base/zap.h
@@ -5,7 +5,10 @@
#ifndef NET_BASE_ZAP_H_
#define NET_BASE_ZAP_H_
+#include <stddef.h>
+
#include <string>
+
#include "base/strings/string16.h"
namespace net {
diff --git a/chromium/net/cert/asn1_util.cc b/chromium/net/cert/asn1_util.cc
index 4bc37a67757..315ca75e648 100644
--- a/chromium/net/cert/asn1_util.cc
+++ b/chromium/net/cert/asn1_util.cc
@@ -4,98 +4,20 @@
#include "net/cert/asn1_util.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+
namespace net {
namespace asn1 {
-bool ParseElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out,
- unsigned *out_header_len) {
- const uint8_t* data = reinterpret_cast<const uint8_t*>(in->data());
-
- // We don't support kAny and kOptional at the same time.
- if ((tag_value & kAny) && (tag_value & kOptional))
- return false;
-
- if (in->empty() && (tag_value & kOptional)) {
- if (out_header_len)
- *out_header_len = 0;
- if (out)
- *out = base::StringPiece();
- return true;
- }
-
- if (in->size() < 2)
- return false;
-
- if (tag_value != kAny &&
- static_cast<unsigned char>(data[0]) != (tag_value & 0xff)) {
- if (tag_value & kOptional) {
- if (out_header_len)
- *out_header_len = 0;
- if (out)
- *out = base::StringPiece();
- return true;
- }
- return false;
- }
-
- size_t len = 0;
- if ((data[1] & 0x80) == 0) {
- // short form length
- if (out_header_len)
- *out_header_len = 2;
- len = static_cast<size_t>(data[1]) + 2;
- } else {
- // long form length
- const unsigned num_bytes = data[1] & 0x7f;
- if (num_bytes == 0 || num_bytes > 2)
- return false;
- if (in->size() < 2 + num_bytes)
- return false;
- len = data[2];
- if (num_bytes == 2) {
- if (len == 0) {
- // the length encoding must be minimal.
- return false;
- }
- len <<= 8;
- len += data[3];
- }
- if (len < 128) {
- // the length should have been encoded in short form. This distinguishes
- // DER from BER encoding.
- return false;
- }
- if (out_header_len)
- *out_header_len = 2 + num_bytes;
- len += 2 + num_bytes;
- }
-
- if (in->size() < len)
- return false;
- if (out)
- *out = base::StringPiece(in->data(), len);
- in->remove_prefix(len);
- return true;
-}
+namespace {
-bool GetElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out) {
- unsigned header_len;
- if (!ParseElement(in, tag_value, out, &header_len))
- return false;
- if (out)
- out->remove_prefix(header_len);
- return true;
-}
-
-// SeekToSPKI changes |cert| so that it points to a suffix of the
-// TBSCertificate where the suffix begins at the start of the ASN.1
-// SubjectPublicKeyInfo value.
-static bool SeekToSPKI(base::StringPiece* cert) {
+// Parses input |in| which should point to the beginning of a Certificate, and
+// sets |*tbs_certificate| ready to parse the SubjectPublicKeyInfo. If parsing
+// fails, this function returns false and |*tbs_certificate| is left in an
+// undefined state.
+bool SeekToSPKI(der::Input in, der::Parser* tbs_certificate) {
// From RFC 5280, section 4.1
// Certificate ::= SEQUENCE {
// tbsCertificate TBSCertificate,
@@ -110,50 +32,55 @@ static bool SeekToSPKI(base::StringPiece* cert) {
// validity Validity,
// subject Name,
// subjectPublicKeyInfo SubjectPublicKeyInfo,
+ // ... }
- base::StringPiece certificate;
- if (!GetElement(cert, kSEQUENCE, &certificate))
+ der::Parser parser(in);
+ der::Parser certificate;
+ if (!parser.ReadSequence(&certificate))
return false;
// We don't allow junk after the certificate.
- if (!cert->empty())
+ if (parser.HasMore())
return false;
- base::StringPiece tbs_certificate;
- if (!GetElement(&certificate, kSEQUENCE, &tbs_certificate))
+ if (!certificate.ReadSequence(tbs_certificate))
return false;
- if (!GetElement(&tbs_certificate,
- kOptional | kConstructed | kContextSpecific | 0,
- NULL)) {
+ bool unused;
+ if (!tbs_certificate->SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 0, &unused)) {
return false;
}
// serialNumber
- if (!GetElement(&tbs_certificate, kINTEGER, NULL))
+ if (!tbs_certificate->SkipTag(der::kInteger))
return false;
// signature
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
// issuer
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
// validity
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
// subject
- if (!GetElement(&tbs_certificate, kSEQUENCE, NULL))
+ if (!tbs_certificate->SkipTag(der::kSequence))
return false;
- *cert = tbs_certificate;
return true;
}
+} // namespace
+
bool ExtractSPKIFromDERCert(base::StringPiece cert,
base::StringPiece* spki_out) {
- if (!SeekToSPKI(&cert))
+ der::Parser parser;
+ if (!SeekToSPKI(der::Input(cert), &parser))
return false;
- if (!ParseElement(&cert, kSEQUENCE, spki_out, NULL))
+ der::Input spki;
+ if (!parser.ReadRawTLV(&spki))
return false;
+ *spki_out = spki.AsStringPiece();
return true;
}
@@ -169,18 +96,20 @@ bool ExtractSubjectPublicKeyFromSPKI(base::StringPiece spki,
// parameters ANY DEFINED BY algorithm OPTIONAL }
// Step into SubjectPublicKeyInfo sequence.
- base::StringPiece spki_contents;
- if (!asn1::GetElement(&spki, asn1::kSEQUENCE, &spki_contents))
+ der::Parser parser((der::Input(spki)));
+ der::Parser spki_parser;
+ if (!parser.ReadSequence(&spki_parser))
return false;
// Step over algorithm field (a SEQUENCE).
- base::StringPiece algorithm;
- if (!asn1::GetElement(&spki_contents, asn1::kSEQUENCE, &algorithm))
+ if (!spki_parser.SkipTag(der::kSequence))
return false;
// Extract the subjectPublicKey field.
- if (!asn1::GetElement(&spki_contents, asn1::kBITSTRING, spk_out))
+ der::Input spk;
+ if (!spki_parser.ReadTag(der::kBitString, &spk))
return false;
+ *spk_out = spk.AsStringPiece();
return true;
}
@@ -190,7 +119,9 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
urls_out->clear();
std::vector<base::StringPiece> tmp_urls_out;
- if (!SeekToSPKI(&cert))
+ bool present;
+ der::Parser tbs_cert_parser;
+ if (!SeekToSPKI(der::Input(cert), &tbs_cert_parser))
return false;
// From RFC 5280, section 4.1
@@ -199,63 +130,71 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
// subjectPublicKeyInfo SubjectPublicKeyInfo,
// issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
// subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- // extensions [3] EXPLICIT Extensions OPTIONAL
+ // extensions [3] EXPLICIT Extensions OPTIONAL }
// subjectPublicKeyInfo
- if (!GetElement(&cert, kSEQUENCE, NULL))
+ if (!tbs_cert_parser.SkipTag(der::kSequence))
return false;
// issuerUniqueID
- if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 1, NULL))
+ if (!tbs_cert_parser.SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 1, &present)) {
return false;
+ }
// subjectUniqueID
- if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 2, NULL))
+ if (!tbs_cert_parser.SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 2, &present)) {
return false;
+ }
- base::StringPiece extensions_seq;
- if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 3,
- &extensions_seq)) {
+ der::Input extensions;
+ if (!tbs_cert_parser.ReadOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 3, &extensions,
+ &present)) {
return false;
}
- if (extensions_seq.empty())
+ if (!present)
return true;
// Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
// Extension ::= SEQUENCE {
// extnID OBJECT IDENTIFIER,
// critical BOOLEAN DEFAULT FALSE,
- // extnValue OCTET STRING
+ // extnValue OCTET STRING }
- // |extensions_seq| was EXPLICITly tagged, so we still need to remove the
+ // |extensions| was EXPLICITly tagged, so we still need to remove the
// ASN.1 SEQUENCE header.
- base::StringPiece extensions;
- if (!GetElement(&extensions_seq, kSEQUENCE, &extensions))
+ der::Parser explicit_extensions_parser(extensions);
+ der::Parser extensions_parser;
+ if (!explicit_extensions_parser.ReadSequence(&extensions_parser))
return false;
- while (extensions.size() > 0) {
- base::StringPiece extension;
- if (!GetElement(&extensions, kSEQUENCE, &extension))
+ if (explicit_extensions_parser.HasMore())
+ return false;
+
+ while (extensions_parser.HasMore()) {
+ der::Parser extension_parser;
+ if (!extensions_parser.ReadSequence(&extension_parser))
return false;
- base::StringPiece oid;
- if (!GetElement(&extension, kOID, &oid))
+ der::Input oid;
+ if (!extension_parser.ReadTag(der::kOid, &oid))
return false;
// kCRLDistributionPointsOID is the DER encoding of the OID for the X.509
// CRL Distribution Points extension.
static const uint8_t kCRLDistributionPointsOID[] = {0x55, 0x1d, 0x1f};
- if (oid.size() != sizeof(kCRLDistributionPointsOID) ||
- memcmp(oid.data(), kCRLDistributionPointsOID, oid.size()) != 0) {
+ if (!oid.Equals(der::Input(kCRLDistributionPointsOID)))
continue;
- }
// critical
- GetElement(&extension, kBOOLEAN, NULL);
+ if (!extension_parser.SkipOptionalTag(der::kBool, &present))
+ return false;
// extnValue
- base::StringPiece extension_value;
- if (!GetElement(&extension, kOCTETSTRING, &extension_value))
+ der::Input extension_value;
+ if (!extension_parser.ReadTag(der::kOctetString, &extension_value))
return false;
// RFC 5280, section 4.2.1.13.
@@ -267,56 +206,80 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
// reasons [1] ReasonFlags OPTIONAL,
// cRLIssuer [2] GeneralNames OPTIONAL }
- base::StringPiece distribution_points;
- if (!GetElement(&extension_value, kSEQUENCE, &distribution_points))
+ der::Parser extension_value_parser(extension_value);
+ der::Parser distribution_points_parser;
+ if (!extension_value_parser.ReadSequence(&distribution_points_parser))
+ return false;
+ if (extension_value_parser.HasMore())
return false;
- while (distribution_points.size() > 0) {
- base::StringPiece distrib_point;
- if (!GetElement(&distribution_points, kSEQUENCE, &distrib_point))
+ while (distribution_points_parser.HasMore()) {
+ der::Parser distrib_point_parser;
+ if (!distribution_points_parser.ReadSequence(&distrib_point_parser))
return false;
- base::StringPiece name;
- if (!GetElement(&distrib_point, kContextSpecific | kConstructed | 0,
- &name)) {
- // If it doesn't contain a name then we skip it.
- continue;
+ der::Input name;
+ if (!distrib_point_parser.ReadOptionalTag(
+ der::kTagContextSpecific | der::kTagConstructed | 0, &name,
+ &present)) {
+ return false;
}
-
- if (GetElement(&distrib_point, kContextSpecific | 1, NULL)) {
- // If it contains a subset of reasons then we skip it. We aren't
- // interested in subsets of CRLs and the RFC states that there MUST be
- // a CRL that covers all reasons.
+ // If it doesn't contain a name then we skip it.
+ if (!present)
continue;
- }
- if (GetElement(&distrib_point,
- kContextSpecific | kConstructed | 2, NULL)) {
- // If it contains a alternative issuer, then we skip it.
+ if (!distrib_point_parser.SkipOptionalTag(der::kTagContextSpecific | 1,
+ &present)) {
+ return false;
+ }
+ // If it contains a subset of reasons then we skip it. We aren't
+ // interested in subsets of CRLs and the RFC states that there MUST be
+ // a CRL that covers all reasons.
+ if (present)
continue;
+
+ if (!distrib_point_parser.SkipOptionalTag(
+ der::kTagContextSpecific | der::kTagConstructed | 2, &present)) {
+ return false;
}
+ // If it contains a alternative issuer, then we skip it.
+ if (present)
+ continue;
// DistributionPointName ::= CHOICE {
// fullName [0] GeneralNames,
// nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
- base::StringPiece general_names;
- if (!GetElement(&name,
- kContextSpecific | kConstructed | 0, &general_names)) {
- continue;
+ der::Input general_names;
+ if (!der::Parser(name).ReadOptionalTag(
+ der::kTagContextSpecific | der::kTagConstructed | 0,
+ &general_names, &present)) {
+ return false;
}
+ if (!present)
+ continue;
// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
// GeneralName ::= CHOICE {
// ...
// uniformResourceIdentifier [6] IA5String,
- // ...
- while (general_names.size() > 0) {
- base::StringPiece url;
- if (GetElement(&general_names, kContextSpecific | 6, &url)) {
- tmp_urls_out.push_back(url);
+ // ... }
+ der::Parser general_names_parser(general_names);
+ while (general_names_parser.HasMore()) {
+ der::Input url;
+ if (!general_names_parser.ReadOptionalTag(der::kTagContextSpecific | 6,
+ &url, &present)) {
+ return false;
+ }
+ if (present) {
+ // This does not validate that |url| is a valid IA5String.
+ tmp_urls_out.push_back(url.AsStringPiece());
} else {
- if (!GetElement(&general_names, kAny, NULL))
+ der::Tag unused_tag;
+ der::Input unused_value;
+ if (!general_names_parser.ReadTagAndValue(&unused_tag,
+ &unused_value)) {
return false;
+ }
}
}
}
diff --git a/chromium/net/cert/asn1_util.h b/chromium/net/cert/asn1_util.h
index fdd765d8ed8..23bc2d2cf90 100644
--- a/chromium/net/cert/asn1_util.h
+++ b/chromium/net/cert/asn1_util.h
@@ -14,50 +14,6 @@ namespace net {
namespace asn1 {
-// These are the DER encodings of the tag byte for ASN.1 objects.
-static const unsigned kBOOLEAN = 0x01;
-static const unsigned kINTEGER = 0x02;
-static const unsigned kBITSTRING = 0x03;
-static const unsigned kOCTETSTRING = 0x04;
-static const unsigned kOID = 0x06;
-static const unsigned kENUMERATED = 0x0A;
-static const unsigned kSEQUENCE = 0x30;
-
-// These are flags that can be ORed with the above tag numbers.
-static const unsigned kContextSpecific = 0x80;
-static const unsigned kConstructed = 0x20;
-
-// kAny matches any tag value;
-static const unsigned kAny = 0x10000;
-// kOptional denotes an optional element.
-static const unsigned kOptional = 0x20000;
-
-// ParseElement parses a DER encoded ASN1 element from |in|, requiring that
-// it have the given |tag_value|. It returns true on success. The following
-// limitations are imposed:
-// 1) tag numbers > 31 are not permitted.
-// 2) lengths > 65535 are not permitted.
-// On successful return:
-// |in| is advanced over the element
-// |out| contains the element, including the tag and length bytes.
-// |out_header_len| contains the length of the tag and length bytes in |out|.
-//
-// If |tag_value & kOptional| is true then *out_header_len can be zero after a
-// true return value if the element was not found.
-bool ParseElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out,
- unsigned *out_header_len);
-
-// GetElement performs the same actions as ParseElement, except that the header
-// bytes are not included in the output.
-//
-// If |tag_value & kOptional| is true then this function cannot distinguish
-// between a missing optional element and an empty one.
-NET_EXPORT_PRIVATE bool GetElement(base::StringPiece* in,
- unsigned tag_value,
- base::StringPiece* out);
-
// ExtractSPKIFromDERCert parses the DER encoded certificate in |cert| and
// extracts the bytes of the SubjectPublicKeyInfo. On successful return,
// |spki_out| is set to contain the SPKI, pointing into |cert|.
diff --git a/chromium/net/cert/cert_database_nss.cc b/chromium/net/cert/cert_database_nss.cc
index 49d27f2b07c..1ff8862e20d 100644
--- a/chromium/net/cert/cert_database_nss.cc
+++ b/chromium/net/cert/cert_database_nss.cc
@@ -8,6 +8,8 @@
#include <pk11pub.h>
#include <secmod.h>
+#include <vector>
+
#include "base/logging.h"
#include "base/observer_list_threadsafe.h"
#include "crypto/nss_util.h"
@@ -15,6 +17,10 @@
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_nss.h"
+#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
+
+// PSM = Mozilla's Personal Security Manager.
+namespace psm = mozilla_security_manager;
namespace net {
@@ -49,30 +55,9 @@ int CertDatabase::CheckUserCert(X509Certificate* cert_obj) {
}
int CertDatabase::AddUserCert(X509Certificate* cert_obj) {
- CERTCertificate* cert = cert_obj->os_cert_handle();
- CK_OBJECT_HANDLE key;
- crypto::ScopedPK11Slot slot(PK11_KeyForCertExists(cert, &key, NULL));
- if (!slot.get())
- return ERR_NO_PRIVATE_KEY_FOR_CERT;
-
- std::string nickname = x509_util::GetUniqueNicknameForSlot(
- cert_obj->GetDefaultNickname(USER_CERT),
- &cert->derSubject,
- slot.get());
-
- SECStatus rv;
- {
- crypto::AutoNSSWriteLock lock;
- rv = PK11_ImportCert(slot.get(), cert, key, nickname.c_str(), PR_FALSE);
- }
-
- if (rv != SECSuccess) {
- LOG(ERROR) << "Couldn't import user certificate. " << PORT_GetError();
- return ERR_ADD_USER_CERT_FAILED;
- }
-
- NotifyObserversOfCertAdded(cert_obj);
- return OK;
+ CertificateList cert_list;
+ cert_list.push_back(cert_obj);
+ return psm::ImportUserCert(cert_list);
}
} // namespace net
diff --git a/chromium/net/cert/cert_net_fetcher.h b/chromium/net/cert/cert_net_fetcher.h
index 2d19e14a27e..afe878e2a03 100644
--- a/chromium/net/cert/cert_net_fetcher.h
+++ b/chromium/net/cert/cert_net_fetcher.h
@@ -5,9 +5,12 @@
#ifndef NET_CERT_CERT_NET_FETCHER_H_
#define NET_CERT_CERT_NET_FETCHER_H_
+#include <stdint.h>
+
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/cert_verifier.cc b/chromium/net/cert/cert_verifier.cc
index 3cd4a78a341..79bd0ef6bec 100644
--- a/chromium/net/cert/cert_verifier.cc
+++ b/chromium/net/cert/cert_verifier.cc
@@ -25,8 +25,7 @@ scoped_ptr<CertVerifier> CertVerifier::CreateDefault() {
return scoped_ptr<CertVerifier>();
#else
return make_scoped_ptr(
- new MultiThreadedCertVerifier(CertVerifyProc::CreateDefault()))
- .Pass();
+ new MultiThreadedCertVerifier(CertVerifyProc::CreateDefault()));
#endif
}
diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc
index bb379ff000c..bdb4b871b4d 100644
--- a/chromium/net/cert/cert_verify_proc.cc
+++ b/chromium/net/cert/cert_verify_proc.cc
@@ -9,6 +9,7 @@
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -165,6 +166,18 @@ bool ExaminePublicKeys(const scoped_refptr<X509Certificate>& cert,
return weak_key;
}
+// Beginning with Ballot 118, ratified in the Baseline Requirements v1.2.1,
+// CAs MUST NOT issue SHA-1 certificates beginning on 1 January 2016.
+bool IsPastSHA1DeprecationDate(const X509Certificate& cert) {
+ const base::Time& start = cert.valid_start();
+ if (start.is_max() || start.is_null())
+ return true;
+ // 2016-01-01 00:00:00 UTC.
+ const base::Time kSHA1DeprecationDate =
+ base::Time::FromInternalValue(INT64_C(13096080000000000));
+ return start >= kSHA1DeprecationDate;
+}
+
} // namespace
// static
@@ -262,8 +275,19 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
+ if (verify_result->has_sha1)
+ verify_result->cert_status |= CERT_STATUS_SHA1_SIGNATURE_PRESENT;
+
// Flag certificates using weak signature algorithms.
- if (verify_result->has_md5) {
+ // The CA/Browser Forum Baseline Requirements (beginning with v1.2.1)
+ // prohibits SHA-1 certificates from being issued beginning on
+ // 1 January 2016. Ideally, all of SHA-1 in new certificates would be
+ // disabled on this date, but enterprises need more time to transition.
+ // As the risk is greatest for publicly trusted certificates, prevent
+ // those certificates from being trusted from that date forward.
+ if (verify_result->has_md5 ||
+ (verify_result->has_sha1_leaf && verify_result->is_issued_by_known_root &&
+ IsPastSHA1DeprecationDate(*cert))) {
verify_result->cert_status |= CERT_STATUS_WEAK_SIGNATURE_ALGORITHM;
// Avoid replacing a more serious error, such as an OS/library failure,
// by ensuring that if verification failed, it failed with a certificate
@@ -272,9 +296,6 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
- if (verify_result->has_sha1)
- verify_result->cert_status |= CERT_STATUS_SHA1_SIGNATURE_PRESENT;
-
// Flag certificates from publicly-trusted CAs that are issued to intranet
// hosts. While the CA/Browser Forum Baseline Requirements (v1.1) permit
// these to be issued until 1 November 2015, they represent a real risk for
@@ -537,7 +558,8 @@ static bool CheckNameConstraints(const std::vector<std::string>& dns_names,
if (i->size() <= (1 /* period before domain */ + domain_length))
continue;
- const char* suffix = &dns_name[i->size() - domain_length - 1];
+ std::string suffix =
+ base::ToLowerASCII(&(*i)[i->size() - domain_length - 1]);
if (suffix[0] != '.')
continue;
if (memcmp(&suffix[1], domains[j], domain_length) != 0)
@@ -601,41 +623,41 @@ bool CertVerifyProc::HasNameConstraintsViolation(
};
static const PublicKeyDomainLimitation kLimits[] = {
- // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI,
- // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr
- {
- {0x79, 0x23, 0xd5, 0x8d, 0x0f, 0xe0, 0x3c, 0xe6, 0xab, 0xad,
- 0xae, 0x27, 0x1a, 0x6d, 0x94, 0xf4, 0x14, 0xd1, 0xa8, 0x73},
- kDomainsANSSI,
- },
- // C=IN, O=India PKI, CN=CCA India 2007
- // Expires: July 4th 2015.
- {
- {0xfe, 0xe3, 0x95, 0x21, 0x2d, 0x5f, 0xea, 0xfc, 0x7e, 0xdc,
- 0xcf, 0x88, 0x3f, 0x1e, 0xc0, 0x58, 0x27, 0xd8, 0xb8, 0xe4},
- kDomainsIndiaCCA,
- },
- // C=IN, O=India PKI, CN=CCA India 2011
- // Expires: March 11 2016.
- {
- {0xf1, 0x42, 0xf6, 0xa2, 0x7d, 0x29, 0x3e, 0xa8, 0xf9, 0x64,
- 0x52, 0x56, 0xed, 0x07, 0xa8, 0x63, 0xf2, 0xdb, 0x1c, 0xdf},
- kDomainsIndiaCCA,
- },
- // C=IN, O=India PKI, CN=CCA India 2014
- // Expires: March 5 2024.
- {
- {0x36, 0x8c, 0x4a, 0x1e, 0x2d, 0xb7, 0x81, 0xe8, 0x6b, 0xed,
- 0x5a, 0x0a, 0x42, 0xb8, 0xc5, 0xcf, 0x6d, 0xb3, 0x57, 0xe1},
- kDomainsIndiaCCA,
- },
- // Not a real certificate - just for testing. This is the SPKI hash of
- // the keys used in net/data/ssl/certificates/name_constraint_*.crt.
- {
- {0x61, 0xec, 0x82, 0x8b, 0xdb, 0x5c, 0x78, 0x2a, 0x8f, 0xcc,
- 0x4f, 0x0f, 0x14, 0xbb, 0x85, 0x31, 0x93, 0x9f, 0xf7, 0x3d},
- kDomainsTest,
- },
+ // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI,
+ // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr
+ {
+ {0x79, 0x23, 0xd5, 0x8d, 0x0f, 0xe0, 0x3c, 0xe6, 0xab, 0xad, 0xae,
+ 0x27, 0x1a, 0x6d, 0x94, 0xf4, 0x14, 0xd1, 0xa8, 0x73},
+ kDomainsANSSI,
+ },
+ // C=IN, O=India PKI, CN=CCA India 2007
+ // Expires: July 4th 2015.
+ {
+ {0xfe, 0xe3, 0x95, 0x21, 0x2d, 0x5f, 0xea, 0xfc, 0x7e, 0xdc, 0xcf,
+ 0x88, 0x3f, 0x1e, 0xc0, 0x58, 0x27, 0xd8, 0xb8, 0xe4},
+ kDomainsIndiaCCA,
+ },
+ // C=IN, O=India PKI, CN=CCA India 2011
+ // Expires: March 11 2016.
+ {
+ {0xf1, 0x42, 0xf6, 0xa2, 0x7d, 0x29, 0x3e, 0xa8, 0xf9, 0x64, 0x52,
+ 0x56, 0xed, 0x07, 0xa8, 0x63, 0xf2, 0xdb, 0x1c, 0xdf},
+ kDomainsIndiaCCA,
+ },
+ // C=IN, O=India PKI, CN=CCA India 2014
+ // Expires: March 5 2024.
+ {
+ {0x36, 0x8c, 0x4a, 0x1e, 0x2d, 0xb7, 0x81, 0xe8, 0x6b, 0xed, 0x5a,
+ 0x0a, 0x42, 0xb8, 0xc5, 0xcf, 0x6d, 0xb3, 0x57, 0xe1},
+ kDomainsIndiaCCA,
+ },
+ // Not a real certificate - just for testing. This is the SPKI hash of
+ // the keys used in net/data/ssl/certificates/name_constraint_*.crt.
+ {
+ {0x48, 0x49, 0x4a, 0xc5, 0x5a, 0x3e, 0xcd, 0xc5, 0x62, 0x9f, 0xef,
+ 0x23, 0x14, 0xad, 0x05, 0xa9, 0x2a, 0x5c, 0x39, 0xc0},
+ kDomainsTest,
+ },
};
for (unsigned i = 0; i < arraysize(kLimits); ++i) {
diff --git a/chromium/net/cert/cert_verify_proc.h b/chromium/net/cert/cert_verify_proc.h
index fdc1205b849..629fde8bf38 100644
--- a/chromium/net/cert/cert_verify_proc.h
+++ b/chromium/net/cert/cert_verify_proc.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/x509_cert_types.h"
diff --git a/chromium/net/cert/cert_verify_proc_android.cc b/chromium/net/cert/cert_verify_proc_android.cc
index d35f10863e0..3825b20a475 100644
--- a/chromium/net/cert/cert_verify_proc_android.cc
+++ b/chromium/net/cert/cert_verify_proc_android.cc
@@ -101,6 +101,8 @@ bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes,
sig_alg == NID_dsaWithSHA1_2 || sig_alg == NID_sha1WithRSA ||
sig_alg == NID_ecdsa_with_SHA1) {
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
}
}
diff --git a/chromium/net/cert/cert_verify_proc_mac.cc b/chromium/net/cert/cert_verify_proc_mac.cc
index c0eb0683ffa..c4e0c41ba92 100644
--- a/chromium/net/cert/cert_verify_proc_mac.cc
+++ b/chromium/net/cert/cert_verify_proc_mac.cc
@@ -8,9 +8,11 @@
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
+#include <set>
#include <string>
#include <vector>
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/mac/scoped_cftyperef.h"
@@ -19,6 +21,7 @@
#include "base/synchronization/lock.h"
#include "crypto/mac_security_services_lock.h"
#include "crypto/sha2.h"
+#include "net/base/hash_value.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_status_flags.h"
@@ -27,7 +30,6 @@
#include "net/cert/crl_set.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
-#include "net/cert/x509_certificate_known_roots_mac.h"
#include "net/cert/x509_util_mac.h"
// From 10.7.2 libsecurity_keychain-55035/lib/SecTrustPriv.h, for use with
@@ -190,6 +192,7 @@ void GetCertChainInfo(CFArrayRef cert_chain,
verify_result->has_md4 = false;
verify_result->has_md5 = false;
verify_result->has_sha1 = false;
+ verify_result->has_sha1_leaf = false;
SecCertificateRef verified_cert = NULL;
std::vector<SecCertificateRef> verified_chain;
@@ -250,8 +253,10 @@ void GetCertChainInfo(CFArrayRef cert_chain,
CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) {
verify_result->has_sha1 = true;
- if (i == 0)
+ if (i == 0) {
+ verify_result->has_sha1_leaf = true;
*leaf_is_weak = true;
+ }
}
}
if (!verified_cert) {
@@ -353,20 +358,6 @@ bool CheckRevocationWithCRLSet(CFArrayRef chain, CRLSet* crl_set) {
return true;
}
-// IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA
-// that we recognise as a standard root.
-// static
-bool IsIssuedByKnownRoot(CFArrayRef chain) {
- int n = CFArrayGetCount(chain);
- if (n < 1)
- return false;
- SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>(
- const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1)));
- SHA1HashValue hash = X509Certificate::CalculateFingerprint(root_ref);
- return IsSHA1HashInSortedArray(
- hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes));
-}
-
// Builds and evaluates a SecTrustRef for the certificate chain contained
// in |cert_array|, using the verification policies in |trust_policies|. On
// success, returns OK, and updates |trust_ref|, |trust_result|,
@@ -466,6 +457,59 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array,
return OK;
}
+// Helper class for managing the set of OS X Known Roots. This is only safe
+// to initialize while the crypto::GetMacSecurityServicesLock() is held, due
+// to calling into Security.framework functions; however, once initialized,
+// it can be called at any time.
+// In practice, due to lazy initialization, it's best to just always guard
+// accesses with the lock.
+class OSXKnownRootHelper {
+ public:
+ // IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA
+ // that we recognise as a standard root.
+ bool IsIssuedByKnownRoot(CFArrayRef chain) {
+ // If there are no known roots, then an API failure occurred. For safety,
+ // assume that all certificates are issued by known roots.
+ if (known_roots_.empty())
+ return true;
+
+ CFIndex n = CFArrayGetCount(chain);
+ if (n < 1)
+ return false;
+ SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1)));
+ SHA256HashValue hash = X509Certificate::CalculateFingerprint256(root_ref);
+ return known_roots_.find(hash) != known_roots_.end();
+ }
+
+ private:
+ friend struct base::DefaultLazyInstanceTraits<OSXKnownRootHelper>;
+
+ OSXKnownRootHelper() {
+ CFArrayRef cert_array = NULL;
+ OSStatus rv = SecTrustSettingsCopyCertificates(
+ kSecTrustSettingsDomainSystem, &cert_array);
+ if (rv != noErr) {
+ LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are "
+ << "trusted! Error " << rv;
+ return;
+ }
+ base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array);
+ for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) {
+ SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i)));
+ known_roots_.insert(X509Certificate::CalculateFingerprint256(cert));
+ }
+ }
+
+ ~OSXKnownRootHelper() {}
+
+ std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_;
+};
+
+base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots =
+ LAZY_INSTANCE_INITIALIZER;
+
} // namespace
CertVerifyProcMac::CertVerifyProcMac() {}
@@ -743,7 +787,8 @@ int CertVerifyProcMac::VerifyInternal(
verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM;
AppendPublicKeyHashes(completed_chain, &verify_result->public_key_hashes);
- verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(completed_chain);
+ verify_result->is_issued_by_known_root =
+ g_known_roots.Get().IsIssuedByKnownRoot(completed_chain);
if (IsCertStatusError(verify_result->cert_status))
return MapCertStatusToNetError(verify_result->cert_status);
diff --git a/chromium/net/cert/cert_verify_proc_nss.cc b/chromium/net/cert/cert_verify_proc_nss.cc
index 9ee65ee4b34..ca8e8116f0e 100644
--- a/chromium/net/cert/cert_verify_proc_nss.cc
+++ b/chromium/net/cert/cert_verify_proc_nss.cc
@@ -15,6 +15,7 @@
#include <sslerr.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "build/build_config.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
@@ -165,7 +166,7 @@ void GetCertChainInfo(CERTCertList* cert_list,
CERTCertificate* verified_cert = NULL;
std::vector<CERTCertificate*> verified_chain;
- int i = 0;
+ size_t i = 0;
for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
!CERT_LIST_END(node, cert_list);
node = CERT_LIST_NEXT(node), ++i) {
@@ -215,6 +216,8 @@ void GetCertChainInfo(CERTCertList* cert_list,
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
break;
default:
break;
diff --git a/chromium/net/cert/cert_verify_proc_openssl.cc b/chromium/net/cert/cert_verify_proc_openssl.cc
index 286b21b98bb..824a95cdc45 100644
--- a/chromium/net/cert/cert_verify_proc_openssl.cc
+++ b/chromium/net/cert/cert_verify_proc_openssl.cc
@@ -125,6 +125,8 @@ void GetCertChainInfo(X509_STORE_CTX* store_ctx,
sig_alg == NID_dsaWithSHA1_2 || sig_alg == NID_sha1WithRSA ||
sig_alg == NID_ecdsa_with_SHA1) {
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
}
}
}
diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc
index 502cfb5bb71..bdeec339d02 100644
--- a/chromium/net/cert/cert_verify_proc_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_unittest.cc
@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/sha2.h"
@@ -46,21 +47,18 @@ unsigned char paypal_null_fingerprint[] = {
0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
};
-// Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root|
-// for all certificates that are Verified.
-class WellKnownCaCertVerifyProc : public CertVerifyProc {
+// Mock CertVerifyProc that sets the CertVerifyResult to a given value for
+// all certificates that are Verify()'d
+class MockCertVerifyProc : public CertVerifyProc {
public:
- // Initialize a CertVerifyProc that will set
- // |verify_result->is_issued_by_known_root| to |is_well_known|.
- explicit WellKnownCaCertVerifyProc(bool is_well_known)
- : is_well_known_(is_well_known) {}
-
+ explicit MockCertVerifyProc(const CertVerifyResult& result)
+ : result_(result) {}
// CertVerifyProc implementation:
bool SupportsAdditionalTrustAnchors() const override { return false; }
bool SupportsOCSPStapling() const override { return false; }
protected:
- ~WellKnownCaCertVerifyProc() override {}
+ ~MockCertVerifyProc() override {}
private:
int VerifyInternal(X509Certificate* cert,
@@ -71,12 +69,12 @@ class WellKnownCaCertVerifyProc : public CertVerifyProc {
const CertificateList& additional_trust_anchors,
CertVerifyResult* verify_result) override;
- const bool is_well_known_;
+ const CertVerifyResult result_;
- DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc);
+ DISALLOW_COPY_AND_ASSIGN(MockCertVerifyProc);
};
-int WellKnownCaCertVerifyProc::VerifyInternal(
+int MockCertVerifyProc::VerifyInternal(
X509Certificate* cert,
const std::string& hostname,
const std::string& ocsp_response,
@@ -84,7 +82,8 @@ int WellKnownCaCertVerifyProc::VerifyInternal(
CRLSet* crl_set,
const CertificateList& additional_trust_anchors,
CertVerifyResult* verify_result) {
- verify_result->is_issued_by_known_root = is_well_known_;
+ *verify_result = result_;
+ verify_result->verified_cert = cert;
return OK;
}
@@ -580,6 +579,11 @@ TEST_F(CertVerifyProcTest, NameConstraintsOk) {
&verify_result);
EXPECT_EQ(OK, error);
EXPECT_EQ(0U, verify_result.cert_status);
+
+ error = Verify(leaf.get(), "foo.test2.example.com", flags, NULL,
+ empty_cert_list_, &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_EQ(0U, verify_result.cert_status);
}
TEST_F(CertVerifyProcTest, NameConstraintsFailure) {
@@ -841,20 +845,102 @@ TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
int error = 0;
// Intranet names for public CAs should be flagged:
- verify_proc_ = new WellKnownCaCertVerifyProc(true);
+ CertVerifyResult dummy_result;
+ dummy_result.is_issued_by_known_root = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
error =
Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
EXPECT_EQ(OK, error);
EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
// However, if the CA is not well known, these should not be flagged:
- verify_proc_ = new WellKnownCaCertVerifyProc(false);
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = false;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
error =
Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
EXPECT_EQ(OK, error);
EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
}
+// Test that a SHA-1 certificate from a publicly trusted CA issued after
+// 1 January 2016 is rejected, but those issued before that date, or with
+// SHA-1 in the intermediate, is not rejected.
+TEST_F(CertVerifyProcTest, VerifyRejectsSHA1AfterDeprecation) {
+ CertVerifyResult dummy_result;
+ CertVerifyResult verify_result;
+ int error = 0;
+ scoped_refptr<X509Certificate> cert;
+
+ // Publicly trusted SHA-1 leaf certificates issued before 1 January 2016
+ // are accepted.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_dec_2015.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+
+ // Publicly trusted SHA-1 leaf certificates issued on/after 1 January 2016
+ // are rejected.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_jan_2016.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
+
+ // Enterprise issued SHA-1 leaf certificates issued on/after 1 January 2016
+ // remain accepted until SHA-1 is disabled.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = false;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = true;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_jan_2016.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+
+ // Publicly trusted SHA-1 intermediates issued on/after 1 January 2016 are,
+ // unfortunately, accepted. This can arise due to OS path building quirks.
+ verify_result.Reset();
+ dummy_result.Reset();
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.has_sha1 = true;
+ dummy_result.has_sha1_leaf = false;
+ verify_proc_ = new MockCertVerifyProc(dummy_result);
+ cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "sha1_jan_2016.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+ error = Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+}
+
// Test that the certificate returned in CertVerifyResult is able to reorder
// certificates that are not ordered from end-entity to root. While this is
// a protocol violation if sent during a TLS handshake, if multiple sources
@@ -1280,7 +1366,8 @@ enum ExpectedAlgorithms {
EXPECT_MD2 = 1 << 0,
EXPECT_MD4 = 1 << 1,
EXPECT_MD5 = 1 << 2,
- EXPECT_SHA1 = 1 << 3
+ EXPECT_SHA1 = 1 << 3,
+ EXPECT_SHA1_LEAF = 1 << 4,
};
struct WeakDigestTestData {
@@ -1348,6 +1435,8 @@ TEST_P(CertVerifyProcWeakDigestTest, Verify) {
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD4), verify_result.has_md4);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD5), verify_result.has_md5);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1), verify_result.has_sha1);
+ EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1_LEAF),
+ verify_result.has_sha1_leaf);
EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
@@ -1393,15 +1482,15 @@ TEST_P(CertVerifyProcWeakDigestTest, Verify) {
// The signature algorithm of the root CA should not matter.
const WeakDigestTestData kVerifyRootCATestData[] = {
- { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_SHA1 },
+ {"weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
- { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_SHA1 },
+ // MD4 is not supported by OS X / NSS
+ {"weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#endif
- { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_SHA1 },
+ {"weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
#if defined(OS_ANDROID)
#define MAYBE_VerifyRoot DISABLED_VerifyRoot
@@ -1414,15 +1503,15 @@ INSTANTIATE_TEST_CASE_P(MAYBE_VerifyRoot,
// The signature algorithm of intermediates should be properly detected.
const WeakDigestTestData kVerifyIntermediateCATestData[] = {
- { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_MD5 | EXPECT_SHA1 },
+ {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
- { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_MD4 | EXPECT_SHA1 },
+ // MD4 is not supported by OS X / NSS
+ {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#endif
- { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
- "weak_digest_sha1_ee.pem", EXPECT_MD2 | EXPECT_SHA1 },
+ {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
+ "weak_digest_sha1_ee.pem", EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
// Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
@@ -1461,15 +1550,15 @@ WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity,
// Incomplete chains should still report the status of the intermediate.
const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
- { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD5 | EXPECT_SHA1 },
+ {NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
+ EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
- { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD4 | EXPECT_SHA1 },
+ // MD4 is not supported by OS X / NSS
+ {NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
+ EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
#endif
- { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD2 | EXPECT_SHA1 },
+ {NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
+ EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
// Disabled on NSS - libpkix does not return constructed chains on error,
// preventing us from detecting/inspecting the verified chain.
diff --git a/chromium/net/cert/cert_verify_proc_whitelist.cc b/chromium/net/cert/cert_verify_proc_whitelist.cc
index 99623278590..c2437f8c4de 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist.cc
+++ b/chromium/net/cert/cert_verify_proc_whitelist.cc
@@ -22,10 +22,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa0, 0xa8, 0xbb, 0xa5, 0x0a, 0x72, 0xd4, 0xe1,
0x83, 0x9a, 0x94, 0xfb, 0x1a, 0x58, 0x5a, 0xd7,
0x2a, 0x7a, 0xac, 0x3c, 0x72, 0x56, 0x1f, 0xc0 },
- { 0x00, 0xc6, 0x81, 0x13, 0x16, 0xbd, 0x9c, 0x91,
- 0x98, 0x6e, 0xa9, 0x7e, 0x2c, 0x30, 0xab, 0xef,
- 0xa0, 0xd5, 0x68, 0x04, 0x89, 0x0d, 0x65, 0x8d,
- 0xff, 0x08, 0x59, 0x11, 0x6e, 0xb4, 0xc2, 0x32 },
{ 0x00, 0xde, 0xff, 0x68, 0x2e, 0x35, 0x10, 0x22,
0xcc, 0x3b, 0xbb, 0x4e, 0xb5, 0x88, 0x0a, 0x97,
0x27, 0x88, 0x0a, 0xf3, 0x52, 0xfb, 0xbe, 0x2f,
@@ -78,10 +74,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4d, 0x8e, 0x3b, 0xc9, 0xc8, 0x7c, 0x02, 0x4e,
0x4b, 0xb7, 0x0d, 0xc6, 0x30, 0x1b, 0xcd, 0xe3,
0x24, 0x12, 0xb4, 0xce, 0x8c, 0x0c, 0x14, 0x58 },
- { 0x03, 0xde, 0x42, 0xaf, 0x1f, 0x30, 0x9f, 0x95,
- 0xf6, 0xc8, 0x91, 0x03, 0xea, 0x98, 0x7e, 0x84,
- 0xd3, 0x18, 0x6b, 0x60, 0x65, 0xf9, 0x60, 0x7a,
- 0x06, 0x6a, 0x30, 0x2b, 0x58, 0x05, 0xeb, 0x3b },
{ 0x03, 0xe0, 0x6e, 0x0b, 0x7a, 0x2c, 0xba, 0xe4,
0xb6, 0x8b, 0xce, 0x5f, 0x83, 0xe7, 0xa9, 0x31,
0x6e, 0xd7, 0x82, 0x3e, 0x8d, 0x94, 0x85, 0x38,
@@ -102,10 +94,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x55, 0xdf, 0xe2, 0x54, 0xc8, 0x20, 0xa0, 0x77,
0xff, 0x11, 0xca, 0xfc, 0x83, 0xb5, 0x0e, 0x0a,
0x13, 0xf1, 0x3d, 0x59, 0xd3, 0xca, 0x6c, 0xaf },
- { 0x04, 0x71, 0x57, 0x2c, 0x03, 0x03, 0x7d, 0xee,
- 0x2b, 0x40, 0x09, 0x6e, 0xe8, 0xaa, 0x37, 0x82,
- 0xc6, 0xfa, 0x81, 0x42, 0xcc, 0xa2, 0x68, 0x19,
- 0x09, 0xda, 0xe8, 0xc4, 0x66, 0xd0, 0x58, 0x4e },
{ 0x04, 0x80, 0x71, 0x3a, 0x76, 0x91, 0x7e, 0xb1,
0x7f, 0xb5, 0x4c, 0x93, 0xee, 0xd3, 0xfd, 0x8a,
0x98, 0x2b, 0xd9, 0x06, 0x9c, 0x69, 0xab, 0xea,
@@ -254,10 +242,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x23, 0x4a, 0x86, 0xc7, 0x0d, 0x49, 0x8c, 0x62,
0x60, 0x7f, 0x37, 0x44, 0xea, 0x71, 0xf1, 0x83,
0x1d, 0xcf, 0xca, 0xf3, 0xaf, 0x15, 0x56, 0x9c },
- { 0x0f, 0x43, 0xfc, 0x12, 0x47, 0x01, 0xfe, 0x29,
- 0xb7, 0x14, 0xf3, 0x05, 0xe2, 0x61, 0xb6, 0x32,
- 0x04, 0x82, 0xc0, 0x09, 0x6f, 0xfe, 0xad, 0x35,
- 0xe1, 0xf8, 0xe6, 0x32, 0xc6, 0x4d, 0x7b, 0x20 },
{ 0x0f, 0x57, 0xed, 0x67, 0x2b, 0xac, 0x50, 0x14,
0x89, 0xe4, 0xf4, 0xab, 0x4b, 0x1d, 0xb1, 0x75,
0x81, 0xfe, 0xb8, 0x76, 0x0f, 0xfb, 0xc0, 0x8a,
@@ -298,14 +282,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x5f, 0xdc, 0xac, 0x20, 0xa2, 0x36, 0xf8, 0x6e,
0x94, 0xe5, 0xee, 0x58, 0x59, 0xd8, 0xfd, 0x45,
0xe9, 0xe9, 0xc5, 0xa6, 0xc5, 0xc0, 0xa4, 0x13 },
- { 0x13, 0xbd, 0x07, 0x7b, 0x8a, 0x9f, 0x46, 0xff,
- 0x8f, 0x2f, 0xfd, 0x23, 0x6e, 0x53, 0xa7, 0x2c,
- 0x3b, 0x87, 0xf3, 0x4c, 0xc9, 0xdb, 0xb5, 0x81,
- 0x7e, 0x4d, 0xba, 0x1b, 0xd3, 0xbc, 0x9e, 0x5f },
- { 0x13, 0xe0, 0x1b, 0xe5, 0x72, 0xdc, 0x11, 0xfa,
- 0xc3, 0xb4, 0x7a, 0xe6, 0x8f, 0x92, 0xdc, 0x00,
- 0xf1, 0x00, 0xbf, 0x77, 0x53, 0x7b, 0x89, 0x47,
- 0xf4, 0xc1, 0x1c, 0x25, 0xa0, 0xb6, 0xf9, 0xf6 },
{ 0x14, 0x21, 0x28, 0xa6, 0x65, 0x1c, 0xdc, 0x18,
0x70, 0xc2, 0x67, 0x5e, 0xc0, 0xb0, 0xef, 0x32,
0xb5, 0xd4, 0xc1, 0x55, 0x35, 0x8e, 0x7e, 0xd9,
@@ -334,14 +310,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xbf, 0x2f, 0x83, 0xc2, 0x80, 0xd1, 0x24, 0x6d,
0xce, 0x02, 0xa6, 0x28, 0x31, 0x26, 0xc6, 0x17,
0xe4, 0x17, 0xd2, 0xb7, 0xea, 0xc1, 0x19, 0x24 },
- { 0x15, 0x75, 0x93, 0x18, 0x80, 0x19, 0x6d, 0xe8,
- 0x0d, 0x97, 0xfe, 0xf1, 0x85, 0xd2, 0x7a, 0xf6,
- 0xad, 0x6b, 0x5b, 0x04, 0x0d, 0x87, 0x6c, 0xdf,
- 0x4a, 0x39, 0xb5, 0xb7, 0x8e, 0x96, 0xb7, 0xd5 },
- { 0x15, 0xb0, 0xd9, 0xbe, 0xd6, 0x2b, 0xd8, 0x96,
- 0x11, 0x59, 0xfe, 0x7e, 0x88, 0x92, 0xf8, 0xe8,
- 0xeb, 0xb0, 0xce, 0x81, 0xe6, 0x8d, 0xea, 0xdd,
- 0x29, 0x0f, 0xdd, 0xce, 0xd0, 0x9d, 0xe7, 0xf1 },
{ 0x15, 0xcf, 0x2f, 0x78, 0xe6, 0x79, 0x62, 0x2c,
0x06, 0x78, 0xdc, 0x5b, 0xa8, 0x03, 0x84, 0x7a,
0xbd, 0xb5, 0xea, 0x64, 0x31, 0x65, 0x3e, 0xc2,
@@ -362,18 +330,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xfd, 0x9a, 0x79, 0xf2, 0xfb, 0xba, 0x9a, 0xca,
0x46, 0xce, 0xad, 0x95, 0x43, 0x05, 0xfe, 0xe5,
0xb1, 0x3b, 0x5d, 0x53, 0xdb, 0x7c, 0x1d, 0xb1 },
- { 0x17, 0x29, 0xb3, 0x34, 0x7a, 0x7d, 0x93, 0x73,
- 0x17, 0xe3, 0xda, 0x5c, 0xc7, 0xf7, 0xb0, 0xd8,
- 0xfd, 0x97, 0x72, 0x24, 0x7a, 0x57, 0x99, 0x93,
- 0x9a, 0x44, 0xd3, 0xa9, 0x7a, 0x50, 0xb9, 0xd9 },
{ 0x17, 0x3d, 0xe2, 0x60, 0xe2, 0x2d, 0x76, 0x9d,
0x2d, 0x54, 0x99, 0xc8, 0x22, 0x0d, 0x86, 0xed,
0xe3, 0x48, 0xda, 0x1e, 0x57, 0xc1, 0xe7, 0xc8,
0x15, 0x07, 0xfb, 0x3e, 0x6b, 0xd7, 0x3b, 0x7f },
- { 0x17, 0x46, 0x68, 0x4e, 0x66, 0x21, 0x77, 0x68,
- 0x70, 0xde, 0x55, 0x65, 0xdf, 0xd3, 0x3a, 0x30,
- 0x92, 0x77, 0x18, 0x59, 0x6c, 0x01, 0x30, 0xf8,
- 0x77, 0x4b, 0xe9, 0x9c, 0xd2, 0xa2, 0x51, 0x06 },
{ 0x17, 0x59, 0x7e, 0x00, 0x45, 0x6c, 0x38, 0x32,
0xe1, 0x85, 0x1c, 0x30, 0x0c, 0xd5, 0x52, 0xc2,
0xe7, 0x73, 0x35, 0x8c, 0xf0, 0xf6, 0x88, 0x58,
@@ -442,10 +402,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x38, 0x5d, 0xe1, 0xde, 0x16, 0xb2, 0x22, 0x6e,
0x88, 0x3d, 0x9c, 0x34, 0x66, 0x3e, 0x1b, 0x64,
0xe8, 0x5b, 0x98, 0x0e, 0xaf, 0xf0, 0xb9, 0xd3 },
- { 0x1c, 0x74, 0xba, 0x75, 0xe5, 0x1b, 0x48, 0x29,
- 0x54, 0xc3, 0x8b, 0xf4, 0xd5, 0x1e, 0xfc, 0x70,
- 0xa0, 0xa0, 0x4d, 0x41, 0x3a, 0xc1, 0xff, 0x8e,
- 0xb9, 0x90, 0x39, 0x9d, 0x1f, 0x1a, 0xa9, 0xc4 },
{ 0x1c, 0x76, 0xbb, 0xca, 0x37, 0x71, 0x77, 0x5b,
0xb9, 0xb0, 0xc3, 0x33, 0x71, 0x70, 0x32, 0x69,
0x06, 0x16, 0x77, 0xca, 0x7b, 0x18, 0x99, 0xef,
@@ -474,10 +430,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x85, 0xa7, 0x9b, 0xba, 0x45, 0xce, 0x76, 0x4b,
0x2d, 0xa8, 0x1f, 0x99, 0x1f, 0x5f, 0x01, 0xd9,
0xeb, 0x7e, 0x3c, 0x99, 0x9b, 0x78, 0x75, 0x0e },
- { 0x1f, 0x7d, 0x37, 0x52, 0x93, 0x22, 0x7d, 0x04,
- 0x97, 0x5b, 0x78, 0x97, 0xdc, 0x17, 0x25, 0x39,
- 0x64, 0xdc, 0xd7, 0xd0, 0x06, 0x7e, 0x84, 0xc6,
- 0xd8, 0x47, 0x9d, 0xfa, 0x27, 0x6e, 0xbe, 0xd0 },
{ 0x1f, 0xc7, 0xf8, 0x10, 0x4e, 0x27, 0xff, 0x2a,
0x45, 0x56, 0xf9, 0x1e, 0x05, 0x42, 0x17, 0xc5,
0x8f, 0x69, 0x3f, 0x70, 0x36, 0x25, 0x9e, 0x39,
@@ -486,10 +438,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xcc, 0xd4, 0xe6, 0xad, 0xe1, 0xcb, 0x75, 0x13,
0x8d, 0xd6, 0xd9, 0x06, 0xfe, 0xf3, 0x49, 0xc0,
0xc9, 0x86, 0xa5, 0x1b, 0x29, 0xb9, 0xe5, 0x2d },
- { 0x20, 0x15, 0x60, 0x8b, 0x8e, 0x86, 0xba, 0x63,
- 0x12, 0x01, 0xc2, 0x12, 0x20, 0x99, 0x57, 0xaf,
- 0xcb, 0x6e, 0xdf, 0x27, 0x22, 0xc6, 0x1b, 0x00,
- 0xe2, 0xfc, 0x92, 0x46, 0xa8, 0xd5, 0x20, 0x4e },
{ 0x20, 0xf1, 0x85, 0xbc, 0x7f, 0xa7, 0x61, 0x16,
0x6e, 0xa3, 0xa9, 0x98, 0x8f, 0xb1, 0x0b, 0x24,
0xc7, 0x01, 0xef, 0xdd, 0xab, 0xe4, 0x74, 0x05,
@@ -518,10 +466,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf7, 0x8d, 0xa6, 0xc8, 0xb1, 0xd7, 0x2c, 0x3b,
0xa8, 0x31, 0x9a, 0x46, 0xf8, 0x19, 0x2d, 0x1e,
0x19, 0xb9, 0xe2, 0x9a, 0xba, 0x18, 0xee, 0x87 },
- { 0x22, 0x2e, 0xc2, 0x75, 0xe6, 0x8a, 0x31, 0x7d,
- 0x60, 0x80, 0x67, 0x9d, 0xdf, 0x56, 0x78, 0x6a,
- 0xbd, 0x2b, 0x11, 0xf2, 0x5a, 0x17, 0x15, 0x33,
- 0xcf, 0xbd, 0x59, 0xee, 0x0d, 0xfa, 0x4e, 0xe4 },
{ 0x22, 0x7a, 0x2b, 0xff, 0xab, 0xde, 0xe1, 0x8c,
0x2c, 0x54, 0xe6, 0xe9, 0xb5, 0x8a, 0xbd, 0xbf,
0x93, 0x07, 0xa4, 0x06, 0x2e, 0xda, 0x97, 0xd4,
@@ -542,10 +486,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x16, 0x2a, 0x9c, 0xa0, 0x6e, 0x88, 0x01, 0xe1,
0x19, 0xbd, 0xff, 0x54, 0x35, 0x4a, 0x3f, 0x68,
0x43, 0xcf, 0x2a, 0x2f, 0xa6, 0x01, 0x75, 0x8e },
- { 0x23, 0xf0, 0xdd, 0xd8, 0x9b, 0x42, 0x82, 0xa6,
- 0x7f, 0xd0, 0x57, 0x56, 0xfd, 0xc5, 0xd1, 0x8c,
- 0x1e, 0x5d, 0xcc, 0xef, 0xcf, 0x42, 0x65, 0x06,
- 0x6d, 0xfb, 0x4a, 0xbd, 0x30, 0xd9, 0xe9, 0x77 },
{ 0x23, 0xf7, 0xe4, 0xa3, 0x5b, 0xcc, 0xe7, 0x40,
0x36, 0xd9, 0xc8, 0x6f, 0x7f, 0x61, 0x1d, 0x85,
0xf3, 0x7c, 0xb6, 0x2c, 0x43, 0x24, 0x7d, 0x13,
@@ -570,10 +510,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x74, 0xe5, 0xe3, 0xd4, 0x3b, 0x27, 0xad, 0x66,
0x62, 0x0b, 0x90, 0xcb, 0x91, 0x62, 0xc4, 0x68,
0x5f, 0xa2, 0x6d, 0x85, 0xf5, 0xa4, 0x3a, 0xa0 },
- { 0x25, 0x8c, 0x68, 0x91, 0xf0, 0x89, 0xb5, 0x09,
- 0x4b, 0xe3, 0x3d, 0x6c, 0x82, 0x21, 0x5e, 0x72,
- 0x65, 0xac, 0xa9, 0x3f, 0x7c, 0x9b, 0x41, 0x45,
- 0xd0, 0x8a, 0xff, 0x1f, 0x48, 0x30, 0x58, 0xaa },
{ 0x26, 0x03, 0xcb, 0xdf, 0x69, 0x75, 0xe3, 0x68,
0x83, 0x7f, 0x95, 0x1a, 0x00, 0x49, 0xfd, 0xc3,
0xc4, 0xb2, 0x39, 0xf0, 0x82, 0xf6, 0xbf, 0x89,
@@ -618,10 +554,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe6, 0xa6, 0xa3, 0x5a, 0x9d, 0x40, 0x00, 0x0a,
0x31, 0x8d, 0x7d, 0xdf, 0x5f, 0x5a, 0x2f, 0x4d,
0x3d, 0x18, 0xbe, 0xba, 0xd3, 0x96, 0x91, 0xec },
- { 0x29, 0x7a, 0xc8, 0x25, 0xc1, 0x98, 0x06, 0xfb,
- 0x88, 0x1f, 0xd9, 0x1c, 0x61, 0x2d, 0x6c, 0xc2,
- 0x1b, 0x28, 0xe4, 0xa5, 0x72, 0xcf, 0xb7, 0x16,
- 0x04, 0xe5, 0x54, 0x41, 0x4d, 0xfd, 0xea, 0xdc },
{ 0x29, 0xa8, 0x28, 0x26, 0x64, 0x3d, 0x5a, 0x98,
0xc4, 0x7d, 0xf3, 0xa7, 0x8f, 0xbb, 0x84, 0x49,
0xb3, 0xe6, 0xd3, 0xcc, 0xe6, 0x2c, 0xf4, 0x57,
@@ -630,18 +562,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x39, 0xa4, 0x04, 0xde, 0x35, 0xac, 0x84, 0xab,
0x81, 0xaf, 0xec, 0x36, 0x17, 0xe7, 0xe1, 0xbf,
0x34, 0x67, 0xd4, 0x19, 0x25, 0x5d, 0xd8, 0x17 },
- { 0x2a, 0x6b, 0x9f, 0x6f, 0xdc, 0x43, 0xbf, 0x65,
- 0xe2, 0xa1, 0x0e, 0xde, 0x36, 0x64, 0xc8, 0x3f,
- 0xcb, 0xec, 0x13, 0x9a, 0x6e, 0x6c, 0xc5, 0xc8,
- 0x32, 0xd3, 0x27, 0x89, 0x5b, 0x52, 0x0e, 0xa2 },
{ 0x2a, 0xa6, 0x47, 0x8c, 0xc7, 0x5d, 0x67, 0xa8,
0xca, 0x55, 0xb2, 0xe1, 0x63, 0xfd, 0xbb, 0xbc,
0x9d, 0x74, 0xb4, 0xe5, 0xf3, 0x7b, 0x7d, 0xbd,
0x13, 0xc9, 0x4e, 0x85, 0x8d, 0x40, 0xda, 0xd0 },
- { 0x2a, 0xc0, 0x65, 0xae, 0x39, 0x6b, 0x87, 0x54,
- 0x9c, 0x3f, 0x09, 0xe5, 0x8f, 0x16, 0x4b, 0x24,
- 0x2e, 0xc5, 0x9d, 0x13, 0x92, 0xb1, 0xb2, 0x50,
- 0x14, 0xbf, 0x47, 0x94, 0xac, 0x13, 0x01, 0xb0 },
{ 0x2b, 0xf1, 0xe3, 0xf0, 0x37, 0x5a, 0x9a, 0x21,
0xc0, 0x7a, 0x92, 0x18, 0x04, 0x2f, 0x18, 0x77,
0x3f, 0x43, 0xea, 0xb0, 0xf5, 0xc0, 0x00, 0x26,
@@ -662,10 +586,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xc3, 0x73, 0x58, 0xcd, 0x5f, 0x71, 0xd1, 0x23,
0xbb, 0x19, 0x77, 0x28, 0x85, 0x87, 0xc7, 0x3f,
0x84, 0xb0, 0x8f, 0xf8, 0xaa, 0x01, 0x9a, 0x69 },
- { 0x2d, 0xb5, 0x36, 0x48, 0xa6, 0x14, 0x69, 0x57,
- 0x01, 0xc7, 0xc5, 0x1e, 0x35, 0xff, 0x38, 0xd6,
- 0x4f, 0x27, 0xa2, 0x7d, 0x55, 0xdf, 0xf4, 0xb1,
- 0x4a, 0xc4, 0x50, 0xc7, 0x5e, 0xb1, 0x18, 0x6e },
{ 0x2d, 0xd5, 0xe6, 0xd3, 0x73, 0x36, 0x34, 0x2f,
0x01, 0x1e, 0xb9, 0x7a, 0x2b, 0x77, 0x38, 0x9d,
0xe6, 0xd2, 0x23, 0x8d, 0x87, 0x69, 0x65, 0x08,
@@ -674,10 +594,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xad, 0xe6, 0x7e, 0x9c, 0xa7, 0x05, 0xeb, 0xb4,
0xc2, 0xe9, 0x40, 0xae, 0x1b, 0x9d, 0x62, 0x35,
0x72, 0x18, 0x04, 0x58, 0x31, 0xe9, 0x8f, 0xde },
- { 0x2e, 0x43, 0x2a, 0x54, 0x5d, 0xfe, 0x2d, 0xa3,
- 0xad, 0x00, 0xcc, 0x87, 0x89, 0x23, 0xa1, 0x85,
- 0xd6, 0xa3, 0xf9, 0x67, 0x5c, 0x36, 0xdc, 0x3c,
- 0xd3, 0x70, 0x2a, 0xef, 0xeb, 0x27, 0x0c, 0x85 },
{ 0x2e, 0x5d, 0xd2, 0x55, 0x09, 0x6d, 0x64, 0x83,
0x10, 0x5c, 0xb6, 0x03, 0x6c, 0x59, 0x17, 0x57,
0xfd, 0x98, 0x49, 0x70, 0x66, 0x05, 0x3f, 0x83,
@@ -690,10 +606,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x01, 0x7c, 0x6c, 0x79, 0x90, 0xe3, 0xf9, 0xa4,
0x0d, 0x46, 0x9f, 0x76, 0x50, 0x59, 0x81, 0xc8,
0x6f, 0x95, 0x55, 0x4f, 0x48, 0x7a, 0x52, 0x76 },
- { 0x2f, 0x79, 0xd6, 0xf6, 0xa3, 0x2f, 0x1b, 0xee,
- 0x22, 0x37, 0xa0, 0x18, 0xe6, 0xae, 0xc4, 0xf4,
- 0x9e, 0x2c, 0x5c, 0x3c, 0xdb, 0xb6, 0x99, 0xe1,
- 0x6f, 0x8e, 0xf4, 0x14, 0xee, 0xff, 0x8d, 0xa3 },
{ 0x2f, 0xef, 0xa7, 0xcb, 0x12, 0x6b, 0x81, 0xc9,
0x47, 0x4d, 0x3e, 0x2c, 0x9b, 0x97, 0x3a, 0x83,
0x69, 0xbb, 0x08, 0x43, 0x41, 0xd3, 0x82, 0xd3,
@@ -718,10 +630,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x74, 0x2d, 0x6b, 0xe8, 0x40, 0x0a, 0xde, 0x51,
0xb2, 0x09, 0x83, 0xf6, 0x83, 0xa2, 0xaa, 0xee,
0xb2, 0x5f, 0x58, 0xdf, 0x98, 0x1b, 0xde, 0x0d },
- { 0x31, 0xed, 0x8a, 0x8c, 0xc6, 0xee, 0x5e, 0x88,
- 0x4f, 0x21, 0x4f, 0x26, 0x7f, 0xe3, 0xa2, 0x27,
- 0xd4, 0xe6, 0xed, 0x36, 0xa7, 0x7f, 0xa2, 0x24,
- 0x6f, 0x0a, 0xd0, 0x77, 0x8a, 0x6b, 0x3f, 0x97 },
{ 0x32, 0x36, 0x98, 0x50, 0x9d, 0x8f, 0x8b, 0xfb,
0xd4, 0xf9, 0x04, 0xbd, 0x1d, 0x84, 0x64, 0x12,
0xc5, 0x27, 0xb7, 0x70, 0x06, 0x2a, 0xad, 0xdf,
@@ -742,10 +650,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb9, 0xe6, 0x63, 0x0d, 0x9f, 0xe7, 0x1f, 0x17,
0xb6, 0xc2, 0x25, 0xa6, 0x5c, 0x76, 0x08, 0x15,
0xe4, 0x08, 0x74, 0x6c, 0x33, 0x1a, 0xb4, 0xf6 },
- { 0x33, 0xc9, 0x15, 0x03, 0xbc, 0x7e, 0xbe, 0x5a,
- 0x5d, 0xd0, 0xcf, 0xbb, 0x37, 0x52, 0x64, 0xdd,
- 0x5a, 0x31, 0x1e, 0x48, 0xf4, 0x26, 0x6b, 0x32,
- 0x50, 0x8a, 0x02, 0x5d, 0x04, 0xfa, 0xdf, 0x38 },
{ 0x33, 0xd1, 0x6c, 0xd9, 0xe8, 0x2e, 0xdf, 0xfd,
0x0b, 0x3a, 0xfb, 0x46, 0xa6, 0x84, 0xc5, 0xa0,
0xd1, 0x2f, 0x2b, 0x40, 0x58, 0x6d, 0x53, 0x2f,
@@ -798,18 +702,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x44, 0xd6, 0xab, 0x39, 0xb7, 0xa8, 0x18, 0xf8,
0x17, 0x6e, 0x65, 0x20, 0xdc, 0x86, 0x3d, 0xce,
0x43, 0xb3, 0x98, 0xc3, 0x0b, 0x5e, 0xdb, 0x09 },
- { 0x37, 0x07, 0x9d, 0x98, 0x72, 0x7c, 0x42, 0xa4,
- 0x1d, 0x66, 0x18, 0xfc, 0xcd, 0xc6, 0xff, 0xa1,
- 0x5e, 0xd3, 0xb2, 0xfe, 0xc7, 0xac, 0x0a, 0x09,
- 0x7b, 0x74, 0xc5, 0x72, 0xbb, 0xcd, 0xa8, 0xd7 },
{ 0x37, 0x87, 0x37, 0xcd, 0x85, 0x19, 0xba, 0xc5,
0x32, 0x2f, 0xdb, 0x28, 0xf4, 0x4a, 0x43, 0xc5,
0x09, 0xa5, 0x44, 0x7a, 0xd2, 0x68, 0x3b, 0xa1,
0x90, 0x05, 0xe3, 0x1b, 0x0d, 0x54, 0x8c, 0x6d },
- { 0x37, 0x99, 0x0f, 0x5b, 0x5c, 0x71, 0x11, 0x89,
- 0x98, 0xf9, 0xc8, 0xe1, 0x54, 0x65, 0x69, 0x16,
- 0x1a, 0x82, 0xbb, 0xfb, 0x4b, 0x4f, 0xc4, 0xca,
- 0xa3, 0xf4, 0xb7, 0xe7, 0x4a, 0xf5, 0x15, 0xfe },
{ 0x37, 0xc9, 0x7a, 0x48, 0xf5, 0xee, 0x3e, 0x68,
0xcc, 0x24, 0xb5, 0x4e, 0x7c, 0x4d, 0x9f, 0x91,
0xc7, 0xd1, 0x8b, 0x8d, 0xb6, 0x1e, 0x04, 0xee,
@@ -846,10 +742,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x82, 0xd5, 0x85, 0xd5, 0xe0, 0x82, 0xc4, 0xb3,
0xad, 0x03, 0xcd, 0xb6, 0xb5, 0x05, 0xca, 0x80,
0x47, 0x19, 0x88, 0xec, 0x4c, 0x58, 0x99, 0x9e },
- { 0x3a, 0xd4, 0x7c, 0xb3, 0x47, 0x3f, 0x59, 0x51,
- 0x5b, 0xac, 0x6a, 0xfa, 0x30, 0x44, 0x8f, 0xb9,
- 0x5d, 0x7f, 0x4b, 0xf1, 0x14, 0x48, 0x53, 0x87,
- 0xd0, 0x4c, 0x50, 0x15, 0x19, 0xbb, 0x77, 0xc3 },
{ 0x3a, 0xea, 0x2c, 0xef, 0xae, 0x63, 0x44, 0xff,
0xae, 0x67, 0x49, 0x4c, 0x68, 0x4e, 0x1e, 0xbf,
0x87, 0x95, 0x40, 0xb5, 0x3d, 0x40, 0xf5, 0x16,
@@ -858,10 +750,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xca, 0x6c, 0x31, 0xb3, 0x78, 0x39, 0xc9, 0x50,
0x76, 0x63, 0x70, 0xd7, 0xf4, 0xb6, 0x4a, 0xd0,
0x18, 0x55, 0xca, 0xcf, 0xe3, 0x51, 0x2f, 0xc3 },
- { 0x3b, 0x4a, 0x9f, 0x55, 0x6c, 0xca, 0xc7, 0x0c,
- 0xa1, 0xf3, 0x3a, 0xf6, 0xde, 0xcc, 0x66, 0xca,
- 0xfd, 0x2d, 0x30, 0x1d, 0x49, 0x7b, 0x49, 0x0b,
- 0x30, 0x80, 0x46, 0x35, 0xba, 0xd2, 0x56, 0x94 },
{ 0x3b, 0x6e, 0x3b, 0xb7, 0x00, 0x04, 0xbd, 0x78,
0xc9, 0x69, 0xa7, 0xfb, 0xd5, 0x11, 0x33, 0xa2,
0xb3, 0xc4, 0xdf, 0xb6, 0xba, 0x38, 0x5d, 0xce,
@@ -890,22 +778,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf8, 0x91, 0x85, 0x31, 0xa7, 0x7c, 0xf9, 0xbf,
0x5c, 0xa1, 0x85, 0x0c, 0x82, 0x02, 0x69, 0xd7,
0xb2, 0xc8, 0xec, 0xd0, 0x54, 0x3a, 0x61, 0x65 },
- { 0x3e, 0x6f, 0x37, 0x53, 0xf1, 0xab, 0x10, 0x62,
- 0x60, 0xdb, 0xef, 0xa6, 0x8e, 0xc5, 0x85, 0x01,
- 0x29, 0x1d, 0x1e, 0xb4, 0x00, 0x28, 0x8f, 0x06,
- 0xed, 0xf2, 0x9f, 0x8f, 0x8f, 0x66, 0xb0, 0x1a },
{ 0x3e, 0x8e, 0x9b, 0xad, 0x8e, 0xd9, 0xb5, 0x72,
0x38, 0x2e, 0x59, 0x8d, 0x2d, 0x73, 0x67, 0xe1,
0xfd, 0x6a, 0xf6, 0x95, 0x25, 0x00, 0x9d, 0x67,
0xb4, 0xe8, 0xaf, 0x80, 0xd9, 0x15, 0x85, 0x49 },
- { 0x3e, 0xc1, 0xc3, 0x43, 0xc6, 0x60, 0x05, 0x10,
- 0x57, 0x97, 0x47, 0xa7, 0x1a, 0xea, 0xb3, 0x04,
- 0x1a, 0x71, 0x8e, 0x4f, 0xc6, 0xe2, 0x96, 0xfe,
- 0xb7, 0x50, 0xa3, 0x12, 0x38, 0x72, 0x6e, 0xa5 },
- { 0x3e, 0xd6, 0x85, 0x47, 0x65, 0x07, 0x91, 0x35,
- 0xaa, 0xee, 0xb7, 0xd8, 0xa3, 0x79, 0x17, 0xdc,
- 0x71, 0x74, 0x5e, 0xa6, 0x0f, 0xa9, 0x62, 0x1b,
- 0xaa, 0x30, 0x7f, 0xbe, 0x71, 0xa7, 0x3c, 0x43 },
{ 0x3f, 0x27, 0xbd, 0xca, 0x9b, 0x0e, 0x42, 0xf3,
0xf6, 0xd0, 0x91, 0x2c, 0x92, 0xe2, 0xda, 0x65,
0xcb, 0x35, 0x8f, 0x0b, 0x8f, 0x80, 0x5b, 0xec,
@@ -938,10 +814,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x65, 0xa7, 0x39, 0xa0, 0x0c, 0x85, 0xf3, 0x44,
0x58, 0x79, 0xd6, 0x5e, 0x1d, 0x42, 0x2e, 0xed,
0x07, 0x65, 0x5a, 0x8e, 0x3e, 0xc3, 0x18, 0xcf },
- { 0x41, 0x1e, 0x5a, 0x18, 0x2a, 0x48, 0x3c, 0x67,
- 0x0f, 0x89, 0xac, 0xee, 0xa6, 0xda, 0xa1, 0xf9,
- 0xa6, 0x22, 0x7e, 0xdf, 0x04, 0x9c, 0x05, 0xe3,
- 0xc4, 0xcf, 0xf7, 0x28, 0x42, 0x45, 0x9a, 0xa2 },
{ 0x41, 0x29, 0x6b, 0x9f, 0xaa, 0xd6, 0x41, 0x33,
0xfc, 0xcb, 0xa6, 0xba, 0x74, 0x54, 0x11, 0xec,
0xc9, 0x11, 0xfd, 0x8e, 0xd5, 0x41, 0x90, 0x0f,
@@ -990,14 +862,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4a, 0x58, 0x1f, 0x4f, 0x10, 0x91, 0xab, 0xef,
0x33, 0x2d, 0x8a, 0x7c, 0xef, 0x60, 0xe6, 0x8d,
0xaf, 0x84, 0x13, 0x23, 0x26, 0x12, 0x90, 0xf0 },
- { 0x44, 0xc2, 0x00, 0x2e, 0xea, 0xbe, 0x55, 0xaa,
- 0x9b, 0xf9, 0x7c, 0xf3, 0xef, 0xd4, 0xfb, 0x06,
- 0xec, 0xe5, 0x10, 0xb4, 0xab, 0xe9, 0xac, 0xb8,
- 0x2c, 0x36, 0xef, 0x23, 0x5b, 0x9d, 0xc8, 0xa1 },
- { 0x45, 0x60, 0xdb, 0xdb, 0x1c, 0x43, 0x68, 0x50,
- 0xef, 0xb0, 0x03, 0x1e, 0xf8, 0x2b, 0x9f, 0x70,
- 0x88, 0x21, 0x9e, 0xce, 0xd2, 0x69, 0x56, 0x1f,
- 0xb4, 0xd1, 0xb0, 0x18, 0x3c, 0x44, 0xc2, 0xb5 },
{ 0x45, 0x63, 0xcf, 0x13, 0xc2, 0x49, 0x2c, 0xaa,
0x92, 0xf5, 0x5b, 0x17, 0x26, 0x3a, 0xdd, 0x72,
0x04, 0xa8, 0x0f, 0xe6, 0x24, 0x0c, 0x4d, 0x63,
@@ -1010,10 +874,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xd5, 0xda, 0xfc, 0x05, 0xeb, 0x0c, 0x53, 0x65,
0x82, 0x3a, 0x91, 0xa9, 0x8b, 0x7d, 0xbe, 0x81,
0xab, 0x5f, 0x17, 0x8b, 0x2d, 0xa4, 0xad, 0x9e },
- { 0x45, 0xcc, 0x74, 0xa3, 0xdb, 0xcb, 0x59, 0xa1,
- 0x35, 0x35, 0x39, 0xfa, 0x5b, 0x1a, 0xf9, 0x74,
- 0x6b, 0xa5, 0xc7, 0xf0, 0xf1, 0x6f, 0x7c, 0xc1,
- 0xf7, 0x0c, 0x71, 0x32, 0x38, 0x82, 0x7e, 0x37 },
{ 0x46, 0x9b, 0xd8, 0x04, 0xe9, 0x98, 0xae, 0x27,
0x9a, 0xc3, 0xfe, 0x1b, 0x52, 0x88, 0x46, 0xe7,
0xae, 0xc7, 0x6c, 0x56, 0xb8, 0x0b, 0x40, 0xf3,
@@ -1034,18 +894,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8b, 0xf5, 0xdd, 0xa4, 0xc3, 0xe9, 0x9e, 0x7f,
0xa3, 0x10, 0x9b, 0x67, 0xbd, 0x0c, 0x9b, 0x1f,
0x40, 0x75, 0x96, 0x65, 0xb9, 0xec, 0x3f, 0xf2 },
- { 0x48, 0x09, 0x80, 0xfc, 0xeb, 0x50, 0xeb, 0x37,
- 0x4c, 0x91, 0x6c, 0xb2, 0xa4, 0x3a, 0xfb, 0xd5,
- 0x35, 0x21, 0x1a, 0xea, 0x9b, 0x12, 0xb7, 0xa4,
- 0x5a, 0xaf, 0x90, 0xba, 0x9c, 0xa4, 0x70, 0x0f },
- { 0x48, 0x4b, 0x8b, 0xc1, 0xe6, 0xcb, 0xba, 0x3f,
- 0x01, 0xf7, 0xa9, 0x34, 0x5a, 0x88, 0x4c, 0xf5,
- 0xf1, 0x5d, 0x82, 0xda, 0x56, 0x98, 0xb6, 0xb3,
- 0x71, 0xe4, 0xdc, 0x6b, 0xbd, 0x6c, 0x8a, 0xe8 },
- { 0x48, 0x5c, 0xf2, 0xb0, 0xa5, 0xe6, 0x9a, 0x0a,
- 0x9a, 0xab, 0x03, 0xff, 0x82, 0xbd, 0x6b, 0x7b,
- 0x2e, 0xdf, 0x8e, 0x1b, 0x54, 0x45, 0x8e, 0x14,
- 0x2a, 0xeb, 0x88, 0xba, 0xa8, 0x84, 0x0e, 0x5b },
{ 0x48, 0xc5, 0xd4, 0xff, 0x5d, 0x08, 0x4a, 0xc1,
0x95, 0xb1, 0xa6, 0xa2, 0x19, 0xf8, 0x1b, 0xbd,
0xf9, 0xd2, 0xe5, 0xc0, 0x70, 0xec, 0x97, 0xdf,
@@ -1126,10 +974,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa9, 0xaa, 0x3b, 0x7b, 0x02, 0x7d, 0x71, 0x4c,
0x0f, 0x76, 0x07, 0xc3, 0x56, 0x73, 0x3b, 0xa2,
0x21, 0xaa, 0xe4, 0x09, 0x47, 0xf7, 0xfa, 0xcb },
- { 0x4d, 0x25, 0x2e, 0x6e, 0x1a, 0x15, 0x9a, 0xc2,
- 0x22, 0xb3, 0x2e, 0x9d, 0xd0, 0x31, 0x56, 0x7b,
- 0x69, 0x31, 0x4b, 0xe8, 0xe8, 0x21, 0x1c, 0x1f,
- 0xb3, 0xc8, 0xb5, 0x3c, 0x26, 0x0a, 0x74, 0xe5 },
{ 0x4d, 0x54, 0x4d, 0x4e, 0x41, 0xc0, 0xfb, 0x15,
0x5f, 0x04, 0x7d, 0x7f, 0xb1, 0xef, 0x29, 0xd1,
0x1b, 0xdf, 0xec, 0xa9, 0xd4, 0x11, 0xaf, 0x8b,
@@ -1142,18 +986,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x81, 0x79, 0x67, 0x53, 0xdd, 0x20, 0x20, 0xb1,
0x10, 0x54, 0x09, 0x32, 0xf7, 0x4f, 0x97, 0x41,
0xd9, 0x6c, 0x1d, 0xb9, 0x50, 0x5d, 0x5f, 0xf1 },
- { 0x4e, 0x33, 0x78, 0xec, 0x23, 0x7c, 0x01, 0xa3,
- 0xcd, 0x85, 0x9e, 0x1d, 0xc9, 0x29, 0xd6, 0xa6,
- 0xef, 0xb6, 0x36, 0x7a, 0x72, 0x58, 0x41, 0xcf,
- 0x54, 0x13, 0x25, 0xc0, 0x61, 0xf8, 0xbf, 0xd4 },
{ 0x4e, 0x48, 0xc1, 0x6c, 0x9d, 0x0d, 0xe5, 0xdd,
0x8c, 0x9c, 0x36, 0x37, 0x35, 0xdd, 0xfb, 0xc3,
0xdb, 0xd2, 0x6e, 0xa0, 0xae, 0xcd, 0xe1, 0xc7,
0x62, 0xbb, 0x56, 0xbb, 0x3f, 0xe4, 0xfa, 0x74 },
- { 0x4e, 0x6e, 0x0a, 0x27, 0x52, 0x69, 0x22, 0x88,
- 0x98, 0x02, 0xb5, 0x98, 0x9e, 0xf0, 0x8a, 0xe1,
- 0x67, 0x02, 0x62, 0x0e, 0x8d, 0x12, 0x90, 0xb9,
- 0x36, 0x9e, 0xf0, 0x32, 0x9a, 0xdb, 0xa6, 0x8c },
{ 0x4f, 0x19, 0xdd, 0x12, 0x92, 0x4c, 0xe0, 0xc1,
0x4f, 0x82, 0xc0, 0x56, 0xc7, 0xd4, 0x2b, 0xac,
0x43, 0xd0, 0x13, 0x3a, 0xaf, 0x89, 0xc1, 0xef,
@@ -1234,10 +1070,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x08, 0x60, 0x96, 0x78, 0xc4, 0x3b, 0xdd, 0xab,
0x90, 0x28, 0xba, 0x6c, 0x17, 0x68, 0x4c, 0x51,
0x22, 0x42, 0x62, 0x43, 0xcb, 0x61, 0x2a, 0x29 },
- { 0x53, 0xed, 0x84, 0xe5, 0xc9, 0xad, 0x2b, 0xd1,
- 0xcb, 0x2c, 0xc8, 0x36, 0x52, 0xea, 0x0c, 0xc3,
- 0x71, 0xcd, 0x53, 0x4b, 0xd5, 0x97, 0xce, 0x7e,
- 0x07, 0x37, 0xa0, 0xab, 0x10, 0x65, 0x73, 0xaa },
{ 0x54, 0x41, 0xfb, 0xb0, 0x5d, 0x6d, 0x4a, 0xed,
0xe0, 0x3b, 0x48, 0x2f, 0x51, 0x95, 0x1c, 0x7e,
0xf0, 0x73, 0x45, 0x53, 0xce, 0xc7, 0x80, 0xfb,
@@ -1262,10 +1094,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x58, 0x4d, 0x9e, 0x7b, 0x57, 0x92, 0xa4, 0x03,
0xc2, 0x1d, 0x39, 0xd6, 0xe1, 0xf5, 0xe8, 0xed,
0x37, 0xb9, 0x3f, 0xa6, 0x1d, 0x88, 0x35, 0x16 },
- { 0x56, 0x65, 0xc2, 0xe5, 0x64, 0x33, 0x29, 0x85,
- 0xb8, 0xd2, 0xc4, 0xfb, 0x61, 0x14, 0x57, 0xd8,
- 0xd5, 0x65, 0x9a, 0xe0, 0x05, 0x87, 0x4c, 0x6f,
- 0x30, 0x34, 0xd2, 0x9f, 0x2a, 0x9a, 0x78, 0x32 },
{ 0x56, 0x96, 0x18, 0xd5, 0x4e, 0x3c, 0x61, 0x1b,
0x79, 0x7e, 0xeb, 0x01, 0xdf, 0x9c, 0x1c, 0x5c,
0x14, 0x6d, 0x87, 0xb3, 0xb1, 0x29, 0xba, 0x42,
@@ -1282,10 +1110,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x62, 0x9c, 0x3c, 0x7c, 0x78, 0xef, 0xbe, 0xf2,
0x75, 0x06, 0x56, 0x65, 0xb2, 0x41, 0x1c, 0x0e,
0x5f, 0xcf, 0xbc, 0x7e, 0xb4, 0xbe, 0x34, 0x0b },
- { 0x58, 0x36, 0x98, 0x46, 0xc0, 0x25, 0x15, 0x0e,
- 0xcf, 0xb2, 0x2c, 0xce, 0xb8, 0xe4, 0xde, 0x9a,
- 0xc3, 0xd0, 0x2d, 0x9e, 0x23, 0x6c, 0x02, 0xef,
- 0xb5, 0x5f, 0x63, 0xeb, 0xaf, 0xea, 0xf7, 0x5b },
{ 0x59, 0x43, 0x09, 0x51, 0x02, 0x8b, 0x87, 0x78,
0x01, 0x67, 0xc9, 0x56, 0x47, 0x9a, 0x81, 0x5f,
0x91, 0xbc, 0x6c, 0x00, 0xc2, 0xe5, 0x0c, 0x35,
@@ -1378,10 +1202,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x79, 0x92, 0xc5, 0x8f, 0xac, 0x32, 0xe3, 0x0c,
0x01, 0x9e, 0xaf, 0x41, 0xe0, 0xb3, 0x85, 0x7e,
0xa9, 0x00, 0xa1, 0x61, 0x08, 0xeb, 0x34, 0xde },
- { 0x60, 0x28, 0x6b, 0x5f, 0xb1, 0xa4, 0x7f, 0x8c,
- 0x79, 0x3e, 0xbe, 0x0a, 0x4f, 0x9e, 0xa0, 0xef,
- 0xb6, 0xff, 0xf7, 0xd0, 0x1c, 0x79, 0x10, 0xef,
- 0xf7, 0x4e, 0xd3, 0xb2, 0x88, 0xf4, 0xe6, 0x27 },
{ 0x60, 0xca, 0x81, 0xe3, 0x5b, 0x9a, 0x6f, 0x07,
0xe1, 0x3c, 0x02, 0xae, 0x41, 0x15, 0xb0, 0x00,
0x54, 0x30, 0xcf, 0x46, 0x0e, 0xfc, 0x7d, 0xba,
@@ -1406,18 +1226,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4d, 0xf9, 0x1e, 0x31, 0x32, 0x2e, 0x57, 0x74,
0x69, 0x1e, 0x0c, 0x41, 0xfa, 0x0d, 0x2f, 0x25,
0x7a, 0xd7, 0xf9, 0xf0, 0x25, 0x98, 0x14, 0x45 },
- { 0x63, 0x65, 0xeb, 0x4e, 0x37, 0xea, 0x23, 0x8b,
- 0xbc, 0x40, 0xa7, 0x65, 0x1e, 0xdd, 0x9a, 0x1c,
- 0x65, 0xfc, 0x54, 0xe3, 0xb8, 0x8f, 0xa7, 0xa0,
- 0x6d, 0x92, 0xc6, 0x13, 0xae, 0xde, 0xd6, 0x5d },
{ 0x63, 0x6a, 0x25, 0xbd, 0xdb, 0xb6, 0x5e, 0x7c,
0xc0, 0xe6, 0x1f, 0x91, 0xca, 0xfe, 0xb1, 0xfe,
0x5d, 0xd2, 0x67, 0xac, 0x67, 0x32, 0x25, 0xcc,
0x81, 0x8e, 0xa0, 0x2b, 0x9c, 0xc9, 0x4b, 0xe2 },
- { 0x64, 0x87, 0xc9, 0x20, 0xb1, 0x30, 0x16, 0xf4,
- 0xa0, 0xaa, 0xd3, 0x9f, 0xe1, 0x97, 0x8b, 0xec,
- 0xe9, 0xf4, 0xfa, 0x13, 0xed, 0x0c, 0x42, 0x4d,
- 0xaa, 0x41, 0x6b, 0xaa, 0x75, 0x89, 0x62, 0x01 },
{ 0x64, 0xd4, 0x92, 0x41, 0x6e, 0xe0, 0x55, 0x57,
0x9c, 0x46, 0x3b, 0x21, 0x1a, 0xfe, 0xf7, 0x46,
0xc3, 0x30, 0xca, 0x05, 0xf4, 0x4d, 0x85, 0x90,
@@ -1434,10 +1246,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x38, 0x07, 0x1a, 0xee, 0xde, 0xf8, 0xe1, 0x83,
0xe2, 0x37, 0x38, 0x46, 0x97, 0x26, 0xeb, 0x99,
0x68, 0x0c, 0xd2, 0x44, 0x72, 0x73, 0x6b, 0xec },
- { 0x66, 0x49, 0xe0, 0x34, 0xc6, 0x9d, 0x14, 0x24,
- 0xd2, 0x8c, 0x42, 0x68, 0xba, 0x95, 0x1e, 0xe1,
- 0xb4, 0x8a, 0xe1, 0x5f, 0xeb, 0xe7, 0xd6, 0xbe,
- 0x9d, 0x75, 0xf6, 0xa4, 0xac, 0x7a, 0xc2, 0x53 },
{ 0x66, 0x50, 0xb2, 0xea, 0x64, 0x4c, 0x3f, 0x4e,
0x8c, 0x9e, 0x3c, 0x46, 0xac, 0xea, 0xc4, 0x52,
0x33, 0xd8, 0x66, 0xe3, 0x98, 0xff, 0x90, 0xeb,
@@ -1566,14 +1374,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8c, 0xc5, 0x2a, 0x48, 0x0a, 0xc0, 0x6d, 0x69,
0x71, 0xc5, 0xa3, 0xda, 0x97, 0xcf, 0x3e, 0xf0,
0x1a, 0xf2, 0x9d, 0x74, 0x72, 0x62, 0x31, 0xe2 },
- { 0x6e, 0xb8, 0xa7, 0xba, 0x7f, 0xc2, 0x1c, 0x62,
- 0x40, 0x3f, 0x63, 0x76, 0xbb, 0x10, 0x44, 0x82,
- 0x48, 0x8d, 0xa9, 0xc1, 0x41, 0x4a, 0xe3, 0xab,
- 0x06, 0xe0, 0x1e, 0xd7, 0x32, 0x42, 0xab, 0xd7 },
- { 0x6e, 0xeb, 0x39, 0xda, 0xd7, 0x3f, 0xc5, 0x99,
- 0x72, 0x42, 0x17, 0xcf, 0xf0, 0x21, 0xd5, 0xac,
- 0x4e, 0x7e, 0x2b, 0xf4, 0x76, 0xea, 0xf4, 0xfd,
- 0x4d, 0x7b, 0xfb, 0x6e, 0x4f, 0x18, 0xc1, 0x73 },
{ 0x6f, 0x3b, 0xb3, 0x4b, 0x5d, 0x32, 0x91, 0xdf,
0xb3, 0xe4, 0x12, 0x71, 0xa1, 0xd7, 0x30, 0xcd,
0xbc, 0xff, 0xc1, 0x0b, 0x68, 0x05, 0x9d, 0xcc,
@@ -1622,10 +1422,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x0e, 0xdf, 0xa3, 0x41, 0x1f, 0xbc, 0x9b, 0xad,
0x31, 0x65, 0xbe, 0x66, 0x0f, 0x34, 0x0a, 0xa2,
0x30, 0x8a, 0x5a, 0x33, 0x23, 0xfa, 0xbf, 0xa7 },
- { 0x73, 0x46, 0x99, 0x89, 0x4a, 0xd4, 0xb5, 0xa8,
- 0xa2, 0xdd, 0x9a, 0xb4, 0xfd, 0x5f, 0x63, 0x25,
- 0x30, 0x3b, 0x49, 0x16, 0x4c, 0xa8, 0xd8, 0xe7,
- 0xba, 0x99, 0x77, 0x81, 0x7e, 0x4a, 0xe2, 0x4f },
{ 0x73, 0x9d, 0x17, 0x23, 0x23, 0xf2, 0xb2, 0x84,
0x07, 0x0a, 0xce, 0x43, 0x09, 0x8c, 0x8b, 0x21,
0xc4, 0x7a, 0x53, 0xf9, 0x98, 0x5f, 0x2f, 0xad,
@@ -1646,10 +1442,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x00, 0xb4, 0x14, 0x73, 0xca, 0x44, 0xe6, 0x87,
0x96, 0x38, 0x74, 0x3d, 0x8f, 0xee, 0x66, 0xee,
0x71, 0x8c, 0x18, 0xd8, 0xf1, 0x12, 0x15, 0xd1 },
- { 0x75, 0xbb, 0x15, 0x25, 0x09, 0xb7, 0x19, 0x04,
- 0xe4, 0x40, 0x0f, 0xb4, 0x23, 0xa5, 0x80, 0xaa,
- 0xe1, 0xdd, 0xb7, 0x68, 0xf6, 0xfd, 0x36, 0xe6,
- 0x30, 0x94, 0xeb, 0xe3, 0x92, 0x15, 0xf3, 0x90 },
{ 0x75, 0xe9, 0xa1, 0x5d, 0x94, 0x88, 0x0c, 0x66,
0x14, 0x82, 0xcf, 0xc1, 0x96, 0x4c, 0xbc, 0xe2,
0xb1, 0xca, 0x7a, 0x9f, 0x81, 0xd4, 0x07, 0x30,
@@ -1666,10 +1458,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x83, 0x98, 0x71, 0x0f, 0x02, 0x20, 0xfa, 0xf3,
0x30, 0x1d, 0x54, 0x49, 0x38, 0xfb, 0x24, 0x19,
0x2d, 0xec, 0x32, 0xf7, 0x44, 0xe4, 0x22, 0x10 },
- { 0x76, 0xcd, 0xf0, 0x78, 0xa8, 0x89, 0x1f, 0x1b,
- 0x3d, 0x0a, 0xa7, 0x1d, 0x6e, 0x18, 0xd7, 0x6a,
- 0x4d, 0x20, 0x7a, 0xaf, 0x84, 0xc6, 0x12, 0x95,
- 0x0e, 0xdf, 0xcd, 0x92, 0x82, 0xa1, 0x11, 0x44 },
{ 0x77, 0x95, 0x6b, 0x48, 0xcd, 0xd9, 0x15, 0x0b,
0xd8, 0x7d, 0x8d, 0x81, 0x50, 0x60, 0xac, 0x8c,
0x84, 0x81, 0x3a, 0x53, 0x87, 0x1a, 0x58, 0x6a,
@@ -1682,10 +1470,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x7e, 0xd5, 0x33, 0xc9, 0x9c, 0xc8, 0x25, 0x08,
0xeb, 0xa6, 0xac, 0x3a, 0x0b, 0xe5, 0xbc, 0xbf,
0x7a, 0xc9, 0x94, 0x95, 0x2b, 0x6d, 0x35, 0x07 },
- { 0x77, 0xb9, 0x6a, 0x00, 0x77, 0x15, 0xa0, 0x8c,
- 0x6a, 0x22, 0xdb, 0x14, 0xc7, 0xf4, 0xf1, 0xd7,
- 0xf4, 0xa7, 0x41, 0xce, 0x47, 0x32, 0xec, 0xf8,
- 0x3e, 0x74, 0xc1, 0xc9, 0x63, 0x22, 0x83, 0xcd },
{ 0x77, 0xdd, 0xc8, 0x1b, 0xd2, 0x8b, 0x9d, 0x46,
0x1e, 0x7d, 0x3c, 0xd4, 0xa8, 0x12, 0x2a, 0xa9,
0x8a, 0x24, 0x60, 0xfb, 0xa0, 0x8f, 0x1b, 0x7b,
@@ -1746,14 +1530,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf8, 0xa9, 0xb4, 0xd9, 0x8e, 0xa2, 0x9a, 0xe4,
0xa5, 0xa4, 0x24, 0x72, 0xf5, 0x91, 0xca, 0x11,
0xfb, 0x5e, 0x11, 0x21, 0x06, 0x28, 0x63, 0x96 },
- { 0x7c, 0x63, 0xb8, 0x8e, 0x58, 0x19, 0x07, 0x0f,
- 0xc1, 0x4a, 0xdb, 0x67, 0xd6, 0xda, 0xa1, 0x29,
- 0x83, 0x14, 0x30, 0x4a, 0x9c, 0x05, 0x30, 0x18,
- 0x02, 0x7d, 0xf8, 0x36, 0x91, 0x4d, 0x73, 0xd4 },
- { 0x7c, 0xa0, 0x86, 0x8b, 0xeb, 0xae, 0x8a, 0xca,
- 0x9d, 0x0f, 0x75, 0x38, 0x65, 0xc3, 0x2a, 0x0d,
- 0x2d, 0xd4, 0xf1, 0x48, 0x6e, 0x37, 0x34, 0xa6,
- 0xa3, 0x71, 0x0e, 0xcc, 0x3e, 0x57, 0xf9, 0xed },
{ 0x7c, 0xf9, 0x2f, 0x75, 0xbb, 0xe7, 0xa1, 0x4d,
0x86, 0x93, 0xf9, 0x93, 0xc3, 0xd1, 0xa6, 0x08,
0xdb, 0xe0, 0xd1, 0x8f, 0x80, 0x8e, 0x21, 0x2d,
@@ -1766,10 +1542,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xdd, 0xd6, 0x03, 0xb1, 0x75, 0xc9, 0xb2, 0x05,
0xac, 0x0b, 0x55, 0x3a, 0x4b, 0xf5, 0xfb, 0x08,
0xc2, 0x46, 0xec, 0xf9, 0xc8, 0x49, 0xdb, 0x28 },
- { 0x7f, 0x86, 0xd3, 0xaa, 0x7e, 0xa7, 0x5c, 0x18,
- 0x03, 0x9d, 0x6a, 0xf9, 0x9c, 0xef, 0x75, 0x04,
- 0xce, 0x7b, 0x05, 0x05, 0x9b, 0xbf, 0xe7, 0x3f,
- 0xcd, 0xec, 0xfc, 0x71, 0xb2, 0x53, 0x8d, 0x72 },
{ 0x7f, 0x95, 0x9b, 0x06, 0x34, 0xda, 0x94, 0xfa,
0xca, 0xda, 0xb0, 0x21, 0xcf, 0x94, 0x20, 0x78,
0x16, 0x00, 0x36, 0x13, 0xef, 0x09, 0xeb, 0x54,
@@ -1834,10 +1606,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x95, 0xe2, 0x5f, 0x91, 0xa5, 0xfb, 0x0f, 0x2a,
0xfc, 0xba, 0x7e, 0x09, 0xb2, 0x17, 0x27, 0xee,
0xd8, 0x13, 0x0c, 0xde, 0x8f, 0x08, 0x0f, 0xca },
- { 0x82, 0xd1, 0x9b, 0xd8, 0x0a, 0x88, 0x6b, 0x28,
- 0x61, 0xc3, 0x09, 0x97, 0x4c, 0x1c, 0x99, 0x3d,
- 0xbe, 0xc3, 0x7e, 0x30, 0x85, 0xc1, 0x47, 0xc4,
- 0x1f, 0x23, 0xd9, 0xf1, 0x20, 0xd8, 0x9b, 0x68 },
{ 0x82, 0xe1, 0xbd, 0xb3, 0xdc, 0x4f, 0x02, 0x36,
0x3a, 0x79, 0x6b, 0x60, 0xa8, 0x8e, 0x4e, 0x71,
0xbd, 0x33, 0xb0, 0xbe, 0x4c, 0xc5, 0xb8, 0x33,
@@ -1866,10 +1634,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xcf, 0x81, 0xb7, 0xd5, 0xff, 0x51, 0xa7, 0xa5,
0x6a, 0x84, 0x78, 0x3a, 0x2d, 0xf7, 0x43, 0x61,
0xff, 0x2e, 0xee, 0x0f, 0x92, 0x12, 0xc1, 0x59 },
- { 0x84, 0x26, 0xbc, 0x06, 0xdb, 0xb5, 0x18, 0x71,
- 0x34, 0x66, 0xc7, 0x6a, 0xea, 0x52, 0x1b, 0xce,
- 0x39, 0xd3, 0x91, 0xa8, 0x89, 0xcb, 0xba, 0x9b,
- 0x7b, 0x72, 0xdc, 0xda, 0x89, 0xf3, 0x46, 0x55 },
{ 0x84, 0x7b, 0x5f, 0x1e, 0xeb, 0x2a, 0x44, 0x13,
0xc8, 0xfa, 0x37, 0x98, 0x21, 0x97, 0x37, 0xe1,
0x92, 0xba, 0x72, 0x72, 0xa1, 0x08, 0xb7, 0x17,
@@ -1914,14 +1678,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe8, 0x1c, 0x27, 0xd1, 0xca, 0xf2, 0x74, 0xb1,
0x7d, 0x72, 0x0d, 0xf8, 0x07, 0x8b, 0x6f, 0x2a,
0x5c, 0x3b, 0xb8, 0xd8, 0xdf, 0xf0, 0x55, 0x00 },
- { 0x87, 0xeb, 0xcb, 0xb0, 0x73, 0x7a, 0xe3, 0x27,
- 0xc6, 0xbe, 0x9d, 0x3f, 0xa2, 0xc7, 0x5d, 0x1e,
- 0xea, 0x0a, 0xe6, 0x6d, 0x20, 0xd3, 0x8a, 0xf6,
- 0xed, 0x76, 0xe6, 0xb1, 0x49, 0x9c, 0x83, 0x1f },
- { 0x88, 0x51, 0x76, 0x78, 0x61, 0xc9, 0x72, 0x7d,
- 0x92, 0x77, 0x63, 0x62, 0x78, 0xfb, 0x94, 0x1b,
- 0x88, 0x85, 0xd9, 0x99, 0x02, 0x48, 0xbf, 0x91,
- 0x45, 0x9e, 0x52, 0x7c, 0xe7, 0xf0, 0x6c, 0xf6 },
{ 0x88, 0x76, 0x88, 0xdc, 0x6e, 0x9f, 0xe3, 0xdb,
0x05, 0x05, 0x7f, 0xc6, 0x38, 0xeb, 0x8b, 0x29,
0x4c, 0x3d, 0x8e, 0x0a, 0xae, 0x17, 0x51, 0xf7,
@@ -2002,10 +1758,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x81, 0x0d, 0x6e, 0x19, 0xf5, 0xf8, 0x8e, 0xa2,
0xc6, 0x5d, 0xb7, 0xa2, 0xe8, 0xa5, 0x06, 0xf7,
0xdf, 0x99, 0x55, 0x81, 0x7d, 0xdd, 0xeb, 0xc8 },
- { 0x8d, 0x74, 0xc0, 0xd6, 0x6b, 0xb2, 0xee, 0xb2,
- 0x6b, 0x9a, 0x55, 0x74, 0x38, 0x5d, 0xa7, 0xb4,
- 0x14, 0x0a, 0xf0, 0x70, 0x47, 0xd2, 0xfe, 0x64,
- 0x3d, 0x1d, 0x1a, 0xe5, 0xb1, 0x96, 0x90, 0x43 },
{ 0x8d, 0x85, 0xda, 0x44, 0x6f, 0x5c, 0x79, 0x54,
0xbd, 0xf7, 0x6c, 0x09, 0x0c, 0xd2, 0x46, 0x68,
0xff, 0x23, 0x3c, 0xcd, 0xf6, 0x6b, 0x94, 0xda,
@@ -2182,10 +1934,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x60, 0x71, 0xd3, 0x82, 0x18, 0x1a, 0xf6, 0xcb,
0x25, 0xbd, 0xc5, 0x87, 0x5e, 0x29, 0xf0, 0xf4,
0xd7, 0x19, 0xa9, 0xd3, 0x5b, 0x5b, 0xd6, 0xbf },
- { 0x99, 0xb1, 0x38, 0xbb, 0x53, 0xc5, 0x4d, 0x1c,
- 0x7a, 0xc2, 0x9a, 0x57, 0x85, 0xc8, 0xb1, 0x9f,
- 0xdd, 0xc3, 0x7d, 0x99, 0x4a, 0x3e, 0x6c, 0x31,
- 0xf7, 0x50, 0xa1, 0xbf, 0xeb, 0xe9, 0xfe, 0xf9 },
{ 0x99, 0xb4, 0x6c, 0x68, 0x90, 0x62, 0x37, 0x40,
0x23, 0xdb, 0x68, 0x19, 0xf8, 0x89, 0xd3, 0xc1,
0xbb, 0x8a, 0x83, 0x8c, 0x6b, 0x51, 0x7e, 0x32,
@@ -2258,18 +2006,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xfe, 0x1f, 0xd8, 0xdf, 0x2d, 0x36, 0xdd, 0xef,
0x00, 0xc8, 0xfc, 0x7b, 0xf7, 0xb7, 0xfd, 0x7e,
0x8d, 0x45, 0x92, 0xab, 0xf3, 0xc4, 0x21, 0xde },
- { 0x9e, 0x85, 0xd4, 0xac, 0x8b, 0x36, 0x0e, 0x4d,
- 0xb2, 0xed, 0x37, 0x34, 0x10, 0x16, 0xe3, 0x7b,
- 0xd5, 0x5c, 0x2d, 0x59, 0x79, 0x5d, 0x0a, 0x7c,
- 0x26, 0xa4, 0x4e, 0x7e, 0x80, 0x98, 0x3e, 0x75 },
{ 0x9e, 0x98, 0xf7, 0xda, 0x04, 0x74, 0xd4, 0x86,
0x5a, 0xc7, 0x05, 0xd4, 0xd7, 0xab, 0xbe, 0xb7,
0x1a, 0xef, 0xba, 0x2c, 0xf2, 0xe0, 0x82, 0xf0,
0x5f, 0xed, 0x53, 0x62, 0x41, 0x4b, 0xd3, 0x93 },
- { 0x9e, 0xea, 0x28, 0xdf, 0x01, 0x4d, 0x91, 0x24,
- 0x4f, 0xf9, 0x31, 0x4f, 0x43, 0x4a, 0x84, 0x7b,
- 0x65, 0x89, 0xc1, 0xf2, 0x03, 0x58, 0x33, 0x9d,
- 0x79, 0xfc, 0xa6, 0x76, 0x63, 0x2d, 0xff, 0xfe },
{ 0x9f, 0x24, 0x5c, 0x0a, 0x0e, 0xc6, 0x3a, 0xaa,
0xcb, 0xf9, 0x69, 0xc6, 0xfc, 0x24, 0xa1, 0x07,
0x15, 0x83, 0xb7, 0x79, 0xa5, 0x8a, 0xb6, 0x23,
@@ -2282,18 +2022,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb6, 0x2f, 0xa6, 0xe3, 0x23, 0x95, 0xeb, 0xe8,
0x33, 0x34, 0x46, 0x00, 0x43, 0x6d, 0xac, 0xc9,
0xb5, 0x69, 0x21, 0x4e, 0xeb, 0x8c, 0x0a, 0xf0 },
- { 0x9f, 0xf9, 0x38, 0x40, 0xb0, 0x1f, 0x96, 0xb6,
- 0xf3, 0xc3, 0x10, 0xa0, 0x21, 0x90, 0xad, 0xc3,
- 0x3a, 0x15, 0x69, 0x39, 0x5b, 0xbc, 0xee, 0x11,
- 0x6a, 0x15, 0xe1, 0x58, 0xa6, 0x2b, 0xa5, 0x0b },
{ 0xa0, 0x05, 0x20, 0xb9, 0x68, 0xbf, 0xcb, 0x63,
0x40, 0x87, 0x9f, 0xa8, 0x43, 0x82, 0x0c, 0xec,
0x95, 0x45, 0x86, 0x0f, 0xe2, 0x9e, 0x2f, 0x8f,
0xee, 0x00, 0xb0, 0x0f, 0xf8, 0x43, 0x42, 0x74 },
- { 0xa0, 0x44, 0xf2, 0xc0, 0x41, 0xf4, 0x18, 0x5b,
- 0xc0, 0xfe, 0x1a, 0xd3, 0xe0, 0xa3, 0xe0, 0xc2,
- 0x7e, 0x24, 0xf4, 0x58, 0xdc, 0xb7, 0xd9, 0x07,
- 0x39, 0xb6, 0x4a, 0x68, 0x94, 0x45, 0xd4, 0xb6 },
{ 0xa0, 0x77, 0x42, 0xd5, 0xb2, 0x99, 0x96, 0x65,
0x06, 0x76, 0x2e, 0x02, 0xe4, 0x20, 0xf1, 0xa9,
0xc4, 0xab, 0x73, 0x29, 0xae, 0x29, 0x5f, 0x01,
@@ -2306,10 +2038,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x37, 0x14, 0xd5, 0xb3, 0x44, 0x5d, 0x88, 0xbe,
0x81, 0xff, 0x5e, 0x1d, 0x16, 0x07, 0x3d, 0xc1,
0x16, 0x6b, 0xb5, 0x44, 0x8f, 0xf6, 0x52, 0xdf },
- { 0xa0, 0xc8, 0xa5, 0x3f, 0xd7, 0x58, 0x3e, 0x43,
- 0x91, 0xbe, 0xb8, 0xd0, 0xfe, 0xd8, 0x43, 0x1f,
- 0x61, 0xb8, 0x52, 0xc1, 0xbe, 0x43, 0xab, 0x91,
- 0x61, 0x4b, 0xbb, 0xeb, 0x3b, 0x4f, 0x47, 0x4e },
{ 0xa1, 0x50, 0x03, 0x2f, 0x4e, 0xf5, 0xd4, 0xfe,
0xb0, 0xae, 0x4a, 0xe1, 0xcd, 0x54, 0x35, 0xba,
0x04, 0xa9, 0xb6, 0xa0, 0xf9, 0x0e, 0x2f, 0x3c,
@@ -2354,18 +2082,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4f, 0xdc, 0x08, 0x15, 0xb8, 0x6e, 0xa3, 0x03,
0x34, 0x3c, 0xf8, 0xc1, 0x0f, 0x37, 0x27, 0x83,
0x27, 0x14, 0x86, 0xb9, 0xc9, 0x3b, 0x63, 0x67 },
- { 0xa5, 0xdb, 0xaf, 0x01, 0xd3, 0xd5, 0x79, 0xee,
- 0x8a, 0x48, 0x8e, 0xe8, 0xd7, 0x44, 0x09, 0x58,
- 0xf7, 0xbf, 0x97, 0xa2, 0xbc, 0xa8, 0xd9, 0x71,
- 0xf6, 0xf8, 0x97, 0x10, 0xbc, 0x2d, 0x10, 0x6f },
{ 0xa6, 0x21, 0xae, 0x36, 0x54, 0xac, 0xfd, 0x17,
0x23, 0x30, 0x70, 0xe9, 0xb1, 0x8d, 0xfd, 0x91,
0x6a, 0x55, 0x2e, 0x6a, 0x8b, 0x82, 0x42, 0xbd,
0x57, 0xbb, 0xcd, 0xf4, 0xe6, 0x5e, 0x99, 0x76 },
- { 0xa6, 0x26, 0x87, 0xde, 0x88, 0x0c, 0xf3, 0x35,
- 0xae, 0x42, 0x4d, 0x4a, 0xde, 0x29, 0xc7, 0xec,
- 0x33, 0xbf, 0xb9, 0xf8, 0x6e, 0xc7, 0xfc, 0xaf,
- 0x61, 0x9d, 0x71, 0x7c, 0x86, 0xb8, 0xfb, 0xbc },
{ 0xa6, 0x33, 0x5d, 0xf3, 0xab, 0xa5, 0xea, 0xdf,
0xbd, 0xc9, 0xc2, 0xdc, 0x9d, 0x6b, 0xe6, 0x0b,
0xb6, 0x2d, 0xf2, 0xfe, 0x24, 0xec, 0x7b, 0xa7,
@@ -2402,10 +2122,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x32, 0xed, 0xb3, 0xc8, 0xd6, 0x8c, 0xe1, 0x35,
0x1a, 0x48, 0xb5, 0x6f, 0x70, 0x11, 0xbb, 0x99,
0x20, 0xcf, 0xca, 0x75, 0x7e, 0x57, 0xc6, 0xc4 },
- { 0xa7, 0x86, 0x18, 0xd8, 0xa7, 0xf0, 0x08, 0xaf,
- 0xdc, 0x72, 0x44, 0x98, 0x2c, 0x11, 0x34, 0xc5,
- 0xdc, 0x91, 0xec, 0x94, 0x25, 0xbf, 0xef, 0xc8,
- 0xcc, 0x0a, 0xf8, 0xf8, 0xc7, 0x59, 0x61, 0xc2 },
{ 0xa8, 0x53, 0xad, 0xc1, 0xc2, 0x18, 0x59, 0xaf,
0x7c, 0x46, 0x2b, 0x4a, 0xa0, 0xa5, 0x74, 0xca,
0x9f, 0xee, 0xfb, 0x18, 0x5a, 0x1f, 0xdb, 0xb6,
@@ -2414,10 +2130,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x11, 0x6f, 0x6a, 0x8b, 0x01, 0xe2, 0x95, 0xcd,
0x60, 0x72, 0x69, 0x5a, 0xb1, 0x65, 0x4b, 0x7b,
0xf9, 0xc4, 0x7e, 0x06, 0x20, 0x25, 0x6f, 0x81 },
- { 0xa8, 0xc6, 0xb0, 0x72, 0x2a, 0x0d, 0x13, 0xdc,
- 0x8b, 0x7f, 0xbb, 0x20, 0xbc, 0x66, 0xe6, 0x03,
- 0x0e, 0x4b, 0xde, 0x99, 0xea, 0xca, 0x9c, 0x96,
- 0x5d, 0x34, 0x65, 0xc9, 0xab, 0xff, 0x64, 0x11 },
{ 0xa8, 0xdf, 0xf0, 0x6a, 0x17, 0x35, 0xb4, 0x6d,
0x17, 0xda, 0xeb, 0xc3, 0x43, 0x43, 0x18, 0x31,
0x3b, 0x2d, 0x9e, 0x7c, 0x3e, 0xf4, 0x8f, 0x28,
@@ -2430,18 +2142,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x56, 0x21, 0x2d, 0xb3, 0xab, 0x34, 0x89, 0x6e,
0x91, 0x70, 0x93, 0x11, 0x3e, 0x47, 0xca, 0x35,
0x96, 0x2e, 0xac, 0xca, 0x9c, 0xb3, 0x86, 0xf0 },
- { 0xa9, 0x20, 0x6f, 0x6d, 0x45, 0x43, 0xed, 0x74,
- 0x4a, 0x5f, 0x15, 0x4a, 0xcb, 0x44, 0x50, 0x89,
- 0x6b, 0x62, 0x5d, 0x7e, 0x32, 0x33, 0x85, 0xa9,
- 0xfd, 0x25, 0x63, 0x93, 0x2f, 0x9c, 0xcc, 0x1b },
- { 0xa9, 0x4c, 0xc9, 0xde, 0x55, 0x52, 0xa6, 0xd9,
- 0x6f, 0xe4, 0x10, 0xbe, 0x03, 0x97, 0x6f, 0x6b,
- 0x0d, 0x4d, 0xa0, 0x5d, 0x73, 0x7a, 0xd2, 0xa3,
- 0x1e, 0x0b, 0xad, 0x90, 0x82, 0xa5, 0x77, 0xb1 },
- { 0xa9, 0x5c, 0x06, 0x3e, 0x9e, 0x35, 0x84, 0xe5,
- 0x99, 0x88, 0xf0, 0x73, 0x86, 0x4c, 0x18, 0x76,
- 0xb5, 0xdf, 0x9b, 0x44, 0xc6, 0x1b, 0x4a, 0x8b,
- 0xe4, 0x83, 0xbe, 0x05, 0xcf, 0xd1, 0xa1, 0xa6 },
{ 0xa9, 0x71, 0x2f, 0x85, 0xed, 0x2e, 0x25, 0xad,
0xa5, 0x7d, 0xc1, 0xf0, 0xf8, 0x6d, 0xe1, 0x07,
0xb5, 0xe2, 0xf0, 0x36, 0x09, 0x53, 0xf1, 0xed,
@@ -2470,10 +2170,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xec, 0xce, 0x7f, 0x5e, 0x61, 0x59, 0x9a, 0xf5,
0x26, 0x69, 0xbf, 0x59, 0x50, 0x7f, 0x8e, 0xf1,
0x99, 0x13, 0xc4, 0x2e, 0xe1, 0x29, 0xda, 0xf0 },
- { 0xab, 0xa7, 0x8e, 0x90, 0xf3, 0x24, 0x17, 0xae,
- 0xc2, 0x8e, 0xea, 0x30, 0x22, 0xa2, 0xe2, 0xb7,
- 0x66, 0x1a, 0xc7, 0x23, 0xc8, 0x7e, 0x0d, 0xbc,
- 0xe2, 0x33, 0xe2, 0x16, 0x8f, 0xcf, 0x91, 0xb3 },
{ 0xab, 0xeb, 0x6a, 0xa0, 0xd1, 0xb0, 0xe0, 0x49,
0xd6, 0x9d, 0xf8, 0x3a, 0xdd, 0x19, 0xf7, 0x26,
0x8a, 0x38, 0xde, 0x6c, 0x00, 0x72, 0x60, 0x68,
@@ -2486,10 +2182,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x5a, 0xd4, 0xa3, 0xba, 0x3d, 0x4b, 0x01, 0x84,
0x91, 0xf3, 0x66, 0x1a, 0x37, 0x9b, 0x3d, 0xfe,
0xdd, 0x6f, 0xd3, 0xc3, 0x2e, 0xfa, 0x84, 0x7d },
- { 0xac, 0x8c, 0x6f, 0x03, 0xe4, 0xba, 0xcf, 0x72,
- 0x20, 0x25, 0xdb, 0x54, 0xd0, 0xfa, 0xae, 0x7d,
- 0xbe, 0x51, 0x37, 0x97, 0x37, 0x39, 0x45, 0x05,
- 0xf0, 0x86, 0xaa, 0x89, 0xe2, 0xd4, 0xf7, 0x3b },
{ 0xac, 0x90, 0x98, 0xf6, 0x4f, 0xe1, 0x03, 0xc8,
0xc1, 0x40, 0x30, 0xdb, 0xce, 0xdd, 0x63, 0xd1,
0xd1, 0x7c, 0x33, 0x8e, 0xbd, 0x1d, 0x7d, 0xe5,
@@ -2610,10 +2302,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa0, 0x49, 0xfe, 0x83, 0xf3, 0xd2, 0x9b, 0x38,
0x5b, 0x90, 0xd3, 0xd0, 0x0b, 0xa8, 0x57, 0xd6,
0x2f, 0x19, 0x67, 0x81, 0xdd, 0xa3, 0xd1, 0x85 },
- { 0xb4, 0x2c, 0x64, 0xf0, 0x25, 0xdf, 0x8f, 0x37,
- 0x0e, 0xb7, 0xa4, 0x69, 0x94, 0x2b, 0x97, 0xe2,
- 0xf8, 0xb5, 0xf4, 0xbf, 0xac, 0xc4, 0xcf, 0x17,
- 0xd2, 0xa0, 0x8f, 0xca, 0x57, 0xbb, 0xc4, 0x9b },
{ 0xb4, 0xae, 0x2a, 0x6b, 0xfc, 0xa5, 0x31, 0xc9,
0x9c, 0x69, 0xb3, 0x5a, 0xfe, 0x67, 0x54, 0xfc,
0x49, 0x27, 0x5b, 0x6c, 0xca, 0xcd, 0xc8, 0x26,
@@ -2666,14 +2354,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4f, 0x2b, 0x81, 0xf7, 0xf7, 0x21, 0x06, 0x73,
0xe9, 0x73, 0x08, 0xaf, 0xf1, 0x24, 0x3f, 0x26,
0x99, 0x5a, 0x25, 0xfa, 0x23, 0x0c, 0xfe, 0x4c },
- { 0xb7, 0x45, 0x85, 0x05, 0xc5, 0x17, 0x90, 0x14,
- 0x9c, 0x5e, 0x98, 0x00, 0xfd, 0x22, 0x74, 0x8a,
- 0x1d, 0x44, 0x66, 0x5f, 0x68, 0x34, 0xba, 0x84,
- 0x4e, 0x9a, 0x0c, 0x32, 0x31, 0x4a, 0x57, 0x21 },
- { 0xb7, 0x9f, 0xca, 0x4d, 0x47, 0x92, 0xec, 0x5e,
- 0x5a, 0x74, 0x06, 0x59, 0x81, 0x3a, 0x0f, 0x46,
- 0x08, 0xea, 0xf9, 0xba, 0x9c, 0xbb, 0xa8, 0xa0,
- 0xf8, 0xda, 0xe1, 0xdd, 0xbb, 0xe6, 0x1e, 0x77 },
{ 0xb7, 0xa2, 0xae, 0x06, 0x06, 0xaa, 0x2c, 0xfb,
0x27, 0x01, 0xb3, 0xb2, 0x77, 0xf4, 0xd7, 0x12,
0x54, 0x70, 0x48, 0x7e, 0xfd, 0x94, 0x05, 0x85,
@@ -2694,10 +2374,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x62, 0xb6, 0x2f, 0x36, 0x50, 0xdb, 0x00, 0xa3,
0x45, 0xf4, 0x6a, 0x0e, 0x8e, 0x01, 0x1a, 0x20,
0x01, 0x3f, 0xd8, 0xed, 0xce, 0x25, 0x27, 0x0d },
- { 0xb9, 0xcc, 0x92, 0xf7, 0x8c, 0x2c, 0x19, 0x57,
- 0xdb, 0xb6, 0xc4, 0xa5, 0xe4, 0x25, 0x44, 0x68,
- 0xfb, 0xcd, 0x88, 0xb1, 0xfd, 0x9f, 0x98, 0xfa,
- 0x6d, 0x76, 0x08, 0x70, 0x9e, 0xbe, 0x92, 0x8d },
{ 0xba, 0x18, 0x2c, 0x1b, 0x75, 0xd8, 0xdf, 0xd1,
0x18, 0x92, 0xe4, 0x77, 0x59, 0x59, 0xad, 0x8a,
0x8c, 0x78, 0x2c, 0xef, 0x60, 0xec, 0xea, 0xbe,
@@ -2714,10 +2390,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x51, 0x61, 0x13, 0x55, 0x2c, 0x17, 0xab, 0x77,
0x82, 0xa7, 0xeb, 0xba, 0xea, 0x0b, 0xe3, 0x9f,
0x58, 0x92, 0x84, 0x1f, 0x1f, 0x74, 0xd2, 0x98 },
- { 0xbb, 0x13, 0xdf, 0x73, 0xb6, 0xe8, 0x89, 0x77,
- 0x7c, 0x4d, 0x85, 0xec, 0x93, 0xb8, 0x3e, 0xa8,
- 0xbb, 0x95, 0x43, 0xf9, 0xfc, 0x08, 0xc2, 0xb3,
- 0x1c, 0x02, 0xac, 0x72, 0xb3, 0x1a, 0x09, 0x0d },
{ 0xbb, 0x5c, 0xb3, 0x78, 0xb7, 0xb9, 0x48, 0x7f,
0xa6, 0x1b, 0xc0, 0x91, 0x3d, 0xa1, 0xdf, 0x26,
0xa1, 0xcf, 0xef, 0xf7, 0x45, 0x2d, 0x9b, 0xa3,
@@ -2734,14 +2406,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8c, 0xa8, 0xbc, 0x2c, 0x62, 0xfb, 0xcc, 0x40,
0x17, 0xff, 0x24, 0x96, 0x98, 0xbe, 0xed, 0xfb,
0x1e, 0xf3, 0x6f, 0x37, 0x5f, 0xb3, 0x9f, 0x72 },
- { 0xbc, 0x1a, 0x3b, 0x83, 0x46, 0xa5, 0x18, 0x4e,
- 0x8f, 0xe2, 0xa9, 0x36, 0xd6, 0xd9, 0xce, 0x2c,
- 0xbe, 0x3a, 0x92, 0x05, 0x54, 0xe0, 0x60, 0xf9,
- 0x07, 0x97, 0xf9, 0x8f, 0xee, 0x62, 0xa8, 0x52 },
- { 0xbc, 0x98, 0x39, 0xc8, 0xb9, 0x22, 0xf6, 0x54,
- 0x57, 0x67, 0xa2, 0xba, 0x46, 0x5a, 0x5b, 0xea,
- 0x9a, 0xa1, 0x84, 0x11, 0x52, 0x99, 0x4a, 0x6c,
- 0xf4, 0x67, 0x83, 0xae, 0x49, 0x98, 0xaf, 0xcc },
{ 0xbd, 0x2e, 0x2f, 0x37, 0xc9, 0x66, 0xc3, 0x86,
0xd9, 0x70, 0x44, 0xfd, 0xe3, 0xe3, 0xf9, 0x00,
0xfb, 0x1a, 0x0b, 0x04, 0x03, 0xb5, 0x81, 0x72,
@@ -2750,10 +2414,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x2a, 0xa7, 0xa7, 0x5f, 0x77, 0x63, 0xa8, 0x38,
0xcf, 0x4b, 0xa1, 0x7f, 0xb3, 0x64, 0x72, 0xba,
0x12, 0x69, 0x8c, 0x45, 0xdf, 0x88, 0xe8, 0x46 },
- { 0xbe, 0x2e, 0x88, 0xc5, 0xee, 0x30, 0x7b, 0xa5,
- 0x41, 0x73, 0xa6, 0x00, 0x2b, 0x99, 0x16, 0x92,
- 0xc8, 0xbd, 0x1d, 0x40, 0x8a, 0x59, 0x2f, 0x70,
- 0x7b, 0xb1, 0xaf, 0x56, 0xf5, 0xb9, 0xd7, 0x42 },
{ 0xbe, 0x41, 0x0a, 0x51, 0xd3, 0x44, 0x17, 0x76,
0x91, 0xb3, 0x42, 0x64, 0x10, 0xa4, 0x41, 0xaf,
0xd1, 0xc9, 0x40, 0xb1, 0xb2, 0x7c, 0xf5, 0x29,
@@ -2762,10 +2422,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb6, 0x20, 0x4f, 0x20, 0x13, 0x1b, 0x01, 0xff,
0x28, 0xb7, 0xdd, 0xff, 0x36, 0x2e, 0x42, 0x9b,
0xfd, 0xf8, 0x8f, 0x36, 0x37, 0x58, 0x24, 0x51 },
- { 0xbe, 0xac, 0x00, 0x60, 0x68, 0x7e, 0xb2, 0x5a,
- 0x9b, 0xed, 0x21, 0xa1, 0x99, 0x97, 0xaf, 0xff,
- 0x67, 0x7c, 0x89, 0x61, 0xdc, 0x00, 0xe2, 0x3b,
- 0x4c, 0x1e, 0x27, 0x7f, 0xf8, 0x58, 0xc0, 0x92 },
{ 0xbe, 0xb9, 0x09, 0x0c, 0x92, 0xd1, 0x6b, 0xd0,
0x5a, 0xf3, 0x91, 0x5a, 0x39, 0xcc, 0x2a, 0xfa,
0x9f, 0x6a, 0x8a, 0x6f, 0xbe, 0xd4, 0xfe, 0x54,
@@ -2814,10 +2470,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf7, 0xbd, 0x38, 0x95, 0x54, 0x60, 0xc3, 0xfc,
0x43, 0x55, 0x0d, 0x97, 0x7f, 0x25, 0xe3, 0x43,
0xd4, 0x9c, 0xd4, 0xaf, 0xad, 0xf2, 0x09, 0x3c },
- { 0xc0, 0xd3, 0xdc, 0x9a, 0x2d, 0x13, 0x9d, 0x38,
- 0xce, 0x02, 0xc0, 0x78, 0xf3, 0xc2, 0x92, 0x5d,
- 0x89, 0x1d, 0x24, 0xe4, 0x36, 0x13, 0xcb, 0xee,
- 0x3f, 0x18, 0xa2, 0xc8, 0x60, 0x98, 0x84, 0xb2 },
{ 0xc0, 0xfe, 0xb7, 0x2a, 0x5f, 0x33, 0x16, 0x5c,
0x0d, 0xc7, 0xc4, 0x24, 0x7e, 0x23, 0xf3, 0x8c,
0xc6, 0x1f, 0x25, 0x24, 0x42, 0xb2, 0xf6, 0x13,
@@ -2938,10 +2590,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8a, 0x88, 0x16, 0x10, 0x63, 0x70, 0x86, 0xf8,
0x8d, 0x9a, 0x11, 0x5e, 0x00, 0x92, 0x46, 0xd2,
0x7f, 0x48, 0x9f, 0xa7, 0x18, 0x51, 0x88, 0xa8 },
- { 0xc7, 0xf8, 0x85, 0xe4, 0x1a, 0xa5, 0x3b, 0x8c,
- 0xb8, 0xe4, 0xe5, 0x59, 0xc4, 0x04, 0x3a, 0x87,
- 0xda, 0xfb, 0x78, 0x7a, 0x0d, 0x2b, 0x2e, 0xf1,
- 0xbc, 0xc0, 0x55, 0x71, 0xb7, 0x5d, 0x4e, 0x29 },
{ 0xc7, 0xff, 0x8e, 0xfd, 0xec, 0xdf, 0x00, 0xd1,
0xfc, 0x8d, 0x55, 0x2d, 0x2a, 0x70, 0x70, 0xe5,
0xe3, 0x3d, 0x42, 0xe5, 0x90, 0xf5, 0x86, 0xc6,
@@ -2974,10 +2622,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb6, 0x1b, 0x90, 0x92, 0xa9, 0xaa, 0x96, 0x81,
0x62, 0x36, 0x55, 0xa6, 0x6f, 0x4f, 0xcb, 0xc4,
0xd3, 0xa6, 0x7e, 0xfd, 0x56, 0x72, 0x48, 0x30 },
- { 0xc9, 0x7e, 0x4d, 0x81, 0xe7, 0x4e, 0x3d, 0x0a,
- 0x5e, 0xe0, 0x9c, 0x6f, 0x76, 0x9b, 0x95, 0x7e,
- 0x70, 0x04, 0xad, 0x2c, 0x9f, 0xc6, 0x66, 0x8a,
- 0x69, 0xd6, 0xca, 0x29, 0xe0, 0x66, 0xe7, 0xfe },
{ 0xca, 0x55, 0x6f, 0x82, 0xc9, 0x68, 0x4c, 0x9a,
0xf3, 0x55, 0x7d, 0x3e, 0x2d, 0x88, 0xaf, 0x92,
0xed, 0x25, 0x9c, 0x20, 0xff, 0xd1, 0xdd, 0xe9,
@@ -3014,10 +2658,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x49, 0xc8, 0xb7, 0xa8, 0x14, 0x8f, 0x26, 0xd7,
0x71, 0x08, 0x3e, 0xc5, 0x18, 0xf9, 0xb6, 0x6f,
0xf5, 0x47, 0xf2, 0x82, 0x2d, 0x11, 0x93, 0x6d },
- { 0xcc, 0x4e, 0x09, 0x63, 0x13, 0xdf, 0xa0, 0xcc,
- 0x24, 0x77, 0xa3, 0xa5, 0xb7, 0x9a, 0xef, 0x0a,
- 0x45, 0x54, 0x58, 0x69, 0xa7, 0xf8, 0x8a, 0x29,
- 0x14, 0x96, 0x06, 0x4b, 0x69, 0x76, 0xe1, 0x4d },
{ 0xcc, 0x65, 0xcd, 0xc5, 0x33, 0x62, 0xd4, 0x21,
0x62, 0x7e, 0xae, 0xf5, 0xd0, 0xc8, 0xe4, 0xc4,
0xe2, 0x40, 0xad, 0xe0, 0xc9, 0xd4, 0x20, 0xbe,
@@ -3054,10 +2694,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x85, 0xf5, 0xb6, 0x4e, 0x65, 0x22, 0x8d, 0x03,
0xfc, 0x77, 0x93, 0xd9, 0x49, 0x42, 0xf8, 0x8a,
0x1c, 0x72, 0xbb, 0x7b, 0x61, 0x14, 0x51, 0xd5 },
- { 0xcf, 0x03, 0x40, 0x17, 0x5b, 0x25, 0x03, 0xc8,
- 0xfa, 0x5d, 0x52, 0xed, 0x42, 0x5b, 0xf3, 0x7e,
- 0x69, 0xc1, 0x80, 0xe5, 0x75, 0xad, 0xc1, 0xa2,
- 0x6a, 0x47, 0x81, 0x97, 0x71, 0xb6, 0x8f, 0x7d },
{ 0xcf, 0x92, 0x77, 0xce, 0xea, 0x50, 0x1a, 0x49,
0x66, 0x04, 0x3e, 0xf2, 0xb0, 0xf8, 0x86, 0x2a,
0xc9, 0x00, 0x93, 0x89, 0x78, 0x08, 0x26, 0x22,
@@ -3082,14 +2718,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xbb, 0x8b, 0xaf, 0x57, 0xf5, 0xc4, 0x5b, 0x69,
0x16, 0x8c, 0x3a, 0x6e, 0xe3, 0xfb, 0xcd, 0xf3,
0xec, 0x2a, 0x77, 0xe8, 0x7c, 0x7c, 0x50, 0x09 },
- { 0xd1, 0xfa, 0xd9, 0xa8, 0xe6, 0x2e, 0x06, 0xcf,
- 0x9b, 0x40, 0x3a, 0xdf, 0x51, 0xed, 0x60, 0x75,
- 0xec, 0xe7, 0x61, 0xa1, 0x0d, 0xd6, 0xa4, 0xd8,
- 0xde, 0x08, 0x82, 0x2f, 0xbb, 0x08, 0x22, 0xfd },
- { 0xd2, 0x3f, 0xeb, 0x93, 0x47, 0x60, 0xb8, 0xdf,
- 0x4e, 0xe6, 0xb0, 0xe8, 0xbb, 0x4f, 0x5d, 0x31,
- 0x5d, 0x40, 0x5b, 0xf0, 0x56, 0x18, 0x2e, 0x5d,
- 0x5f, 0x70, 0x20, 0x31, 0x94, 0x61, 0x8a, 0x05 },
{ 0xd2, 0x56, 0x79, 0xcb, 0x58, 0x3b, 0xa0, 0x10,
0x8f, 0x74, 0x97, 0xe3, 0x21, 0xc6, 0x5c, 0x4d,
0xc2, 0xca, 0x0f, 0x28, 0x20, 0xc7, 0xfc, 0xdb,
@@ -3102,18 +2730,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4c, 0x2d, 0xfe, 0x94, 0xcb, 0x44, 0x50, 0x37,
0x1e, 0x72, 0x36, 0xbd, 0xbd, 0x1c, 0x81, 0x13,
0xff, 0x36, 0x0f, 0xa4, 0xa1, 0x58, 0x1e, 0xfc },
- { 0xd2, 0xd1, 0x84, 0xca, 0x5b, 0x97, 0xac, 0x7b,
- 0xd3, 0x4e, 0x78, 0x42, 0x4c, 0xa0, 0xc2, 0xb3,
- 0x9c, 0x35, 0x08, 0x52, 0xcc, 0xb1, 0x33, 0xe5,
- 0xa1, 0x87, 0xf7, 0x61, 0x7d, 0x00, 0xb0, 0x2c },
{ 0xd2, 0xe8, 0xa1, 0x23, 0x7a, 0x93, 0xf5, 0x78,
0xd1, 0xba, 0x8f, 0x09, 0xe4, 0xff, 0x10, 0x7b,
0x62, 0x35, 0x78, 0x85, 0x42, 0xaa, 0x61, 0x83,
0xd1, 0x76, 0xdb, 0xf1, 0xc8, 0x8d, 0xcf, 0xb6 },
- { 0xd3, 0x10, 0x0b, 0xc8, 0x42, 0x8b, 0xa2, 0x3a,
- 0xe1, 0x3b, 0x41, 0xea, 0xa2, 0x95, 0xbf, 0xbf,
- 0xd6, 0x97, 0xf5, 0x0b, 0x81, 0xca, 0xef, 0x6a,
- 0x30, 0xa4, 0xd1, 0x99, 0x47, 0x1b, 0x9f, 0x32 },
{ 0xd3, 0x22, 0xe0, 0xc4, 0x4e, 0xa7, 0x92, 0xc0,
0x00, 0x13, 0x01, 0xa6, 0x32, 0xa1, 0x1d, 0x50,
0x6e, 0xa9, 0x17, 0xde, 0xed, 0xca, 0x8e, 0xd0,
@@ -3134,10 +2754,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x3b, 0xb9, 0x9f, 0x80, 0x68, 0xcf, 0xee, 0x86,
0xa4, 0xb9, 0xf0, 0x89, 0xe0, 0x2d, 0x0c, 0x6c,
0xb6, 0xd4, 0xa3, 0x94, 0x6c, 0x6b, 0x16, 0x7a },
- { 0xd5, 0x50, 0xb9, 0xa6, 0xd5, 0xc3, 0xf5, 0x25,
- 0x7c, 0x99, 0xb9, 0x94, 0x43, 0x69, 0x88, 0x3d,
- 0xa1, 0x1d, 0xbe, 0x23, 0xb9, 0x6e, 0x19, 0x34,
- 0xed, 0xed, 0x52, 0x1b, 0x73, 0x55, 0xe4, 0x44 },
{ 0xd5, 0x83, 0x94, 0x96, 0xcd, 0xc8, 0x5b, 0xe3,
0xd1, 0xf1, 0xac, 0x65, 0x2e, 0xfa, 0x92, 0xbe,
0xa3, 0xb0, 0x61, 0xc1, 0x3d, 0xad, 0x5a, 0x82,
@@ -3154,10 +2770,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xaa, 0x7e, 0x87, 0x8e, 0x6a, 0x85, 0x09, 0x1b,
0xaa, 0x07, 0x8d, 0x26, 0x8b, 0xbd, 0xb4, 0x9f,
0x09, 0x67, 0x94, 0x08, 0x61, 0x2d, 0x1e, 0xfe },
- { 0xd6, 0x46, 0x08, 0xb1, 0x5f, 0x71, 0xfc, 0x3b,
- 0x91, 0x90, 0xa2, 0x00, 0xee, 0x3c, 0xb5, 0xbc,
- 0xd9, 0xfc, 0x5b, 0x99, 0xfb, 0x67, 0x74, 0x9d,
- 0x18, 0x87, 0xd9, 0x17, 0xd8, 0x50, 0x01, 0x0b },
{ 0xd6, 0x83, 0xd0, 0x6e, 0xb9, 0x28, 0x74, 0x43,
0xe5, 0x01, 0xec, 0xf7, 0x1d, 0xad, 0xa6, 0x80,
0x35, 0x88, 0x71, 0xd1, 0x2a, 0x53, 0xfb, 0xcc,
@@ -3190,10 +2802,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x0b, 0x84, 0xd9, 0xa1, 0x7b, 0x1e, 0x90, 0x24,
0xf6, 0x27, 0xc1, 0xec, 0xc3, 0x5e, 0xc7, 0xe6,
0x71, 0xc1, 0x42, 0x92, 0xa7, 0xb8, 0x8b, 0x43 },
- { 0xd8, 0x55, 0x49, 0xfc, 0xd2, 0x4d, 0x36, 0xcb,
- 0x3f, 0x7c, 0x18, 0x06, 0x3f, 0x97, 0x5a, 0x16,
- 0x9f, 0xe3, 0xa1, 0xfb, 0x8d, 0x0a, 0x35, 0x9f,
- 0xd3, 0x5c, 0x28, 0x7b, 0xb2, 0xaf, 0x50, 0xca },
{ 0xd8, 0x7a, 0x9d, 0xf7, 0x19, 0x1e, 0x29, 0xc8,
0x04, 0x1e, 0x4c, 0x19, 0x3c, 0x03, 0xa8, 0xa7,
0x12, 0x5f, 0x16, 0x6e, 0xa6, 0xcb, 0x21, 0x1f,
@@ -3218,10 +2826,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x4a, 0x3e, 0xd7, 0xfc, 0x55, 0x8c, 0x58, 0x45,
0x64, 0x51, 0x60, 0xda, 0xb3, 0x53, 0x85, 0xc1,
0x38, 0xbc, 0x89, 0x9c, 0x4d, 0xad, 0x8b, 0x36 },
- { 0xd9, 0xd0, 0xd9, 0x6e, 0xb3, 0x28, 0xe0, 0xc1,
- 0x77, 0x8b, 0x56, 0xa9, 0x2f, 0x71, 0x24, 0x3b,
- 0x6c, 0x0d, 0xb4, 0x5c, 0x62, 0x51, 0x32, 0xdd,
- 0x82, 0xca, 0x11, 0xa0, 0x97, 0xe7, 0x91, 0xc6 },
{ 0xd9, 0xe8, 0xcc, 0xda, 0x78, 0xfb, 0x8d, 0x5d,
0xbc, 0xe6, 0x94, 0x15, 0x57, 0x61, 0xf4, 0xd0,
0x2c, 0x30, 0xcc, 0x8d, 0x7a, 0xea, 0x0e, 0x11,
@@ -3242,22 +2846,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe5, 0x38, 0x9a, 0x26, 0x08, 0x1c, 0x99, 0x8b,
0x5f, 0xfa, 0x67, 0xdd, 0x45, 0x97, 0xf8, 0xca,
0x67, 0xef, 0x10, 0x6a, 0xd7, 0x5f, 0x34, 0x9f },
- { 0xdb, 0xa1, 0x23, 0x67, 0x1f, 0xed, 0x4b, 0x28,
- 0x70, 0x33, 0xa4, 0xb0, 0x06, 0x8f, 0xc7, 0x14,
- 0xa5, 0xfc, 0x9c, 0x02, 0x6e, 0xf5, 0x65, 0x0b,
- 0x42, 0xde, 0x25, 0x85, 0x9a, 0x12, 0x6a, 0xd1 },
{ 0xdb, 0xa2, 0x21, 0xc2, 0xab, 0x44, 0xb5, 0x2c,
0x0b, 0x83, 0x36, 0xc4, 0x69, 0xfa, 0xa8, 0x56,
0xd6, 0xc3, 0xec, 0xdc, 0x6c, 0x24, 0x6b, 0xe3,
0xca, 0xc7, 0xe0, 0xf6, 0x28, 0x4b, 0x5b, 0xda },
- { 0xdc, 0x3d, 0x81, 0xc3, 0x01, 0xbc, 0xde, 0xc5,
- 0x38, 0xef, 0xc7, 0xfa, 0x6a, 0x4e, 0x5a, 0x13,
- 0xe5, 0x17, 0xd2, 0xa4, 0x61, 0x22, 0x2d, 0xed,
- 0x98, 0x3e, 0x75, 0x56, 0x4d, 0x0e, 0x68, 0x84 },
- { 0xdc, 0x42, 0x4a, 0x70, 0x87, 0x80, 0x95, 0x98,
- 0x7a, 0x5b, 0xcd, 0x17, 0x1a, 0xa5, 0x13, 0x67,
- 0x7b, 0xda, 0x56, 0xdf, 0x35, 0xb6, 0x81, 0xc7,
- 0x07, 0x84, 0x0f, 0xdc, 0xea, 0xc5, 0xe4, 0x0f },
{ 0xdc, 0x90, 0x90, 0x55, 0x0c, 0x93, 0x42, 0xe2,
0xfa, 0xe2, 0x42, 0x26, 0xa4, 0xf9, 0xb3, 0xf6,
0x93, 0xf4, 0xd1, 0x46, 0x52, 0x79, 0xc3, 0x7b,
@@ -3274,10 +2866,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xf0, 0xfd, 0xdb, 0x6b, 0x37, 0xfe, 0x00, 0x28,
0xde, 0x8b, 0x7d, 0x3c, 0xe5, 0x79, 0x1b, 0x45,
0x0d, 0xd2, 0x83, 0xb2, 0x0a, 0xdb, 0x05, 0xd2 },
- { 0xde, 0x45, 0x46, 0xc0, 0x24, 0x51, 0xa5, 0xb5,
- 0xad, 0x85, 0xea, 0x53, 0x2f, 0x09, 0x6f, 0xdf,
- 0x1e, 0x2b, 0x41, 0x71, 0xd9, 0x6a, 0x1d, 0xc3,
- 0x93, 0x6a, 0x19, 0x74, 0xf0, 0x58, 0xf0, 0xb2 },
{ 0xde, 0x5c, 0x3d, 0x09, 0x58, 0xa6, 0x12, 0xbd,
0x6d, 0x48, 0x09, 0x15, 0x03, 0x3d, 0x97, 0x15,
0x58, 0xdf, 0x35, 0xce, 0xb1, 0xc9, 0x18, 0xe6,
@@ -3314,26 +2902,14 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xc4, 0xba, 0x83, 0x99, 0xd4, 0xd8, 0xd5, 0xa0,
0xd1, 0x98, 0x57, 0x8f, 0x42, 0x99, 0xfd, 0xfd,
0xaf, 0xf7, 0x8c, 0x3f, 0x67, 0x71, 0xf3, 0x94 },
- { 0xe0, 0x65, 0x19, 0x10, 0x41, 0x74, 0x08, 0xbe,
- 0x2b, 0x0c, 0xfd, 0x3d, 0x9e, 0xaa, 0xeb, 0xca,
- 0x32, 0x1f, 0x61, 0x6d, 0xda, 0x48, 0xcb, 0x4f,
- 0x09, 0x10, 0x9d, 0x67, 0x19, 0x45, 0xa1, 0x1c },
{ 0xe0, 0x8b, 0x2c, 0xc2, 0x7a, 0xe8, 0xe2, 0xef,
0x1a, 0x33, 0x01, 0x7a, 0x9a, 0xc2, 0x5d, 0xda,
0xfb, 0x5e, 0xa1, 0x12, 0xc9, 0x56, 0xb0, 0x02,
0xfe, 0x6c, 0x79, 0x80, 0x14, 0xaa, 0x90, 0x65 },
- { 0xe0, 0xa0, 0x7b, 0x39, 0x6d, 0x25, 0x7f, 0xab,
- 0xb4, 0xe3, 0x22, 0xd8, 0x79, 0x94, 0x88, 0x37,
- 0x28, 0x7a, 0xaa, 0x99, 0xad, 0x14, 0xd7, 0x8d,
- 0x3a, 0x2f, 0x9d, 0xfe, 0x5c, 0x97, 0x28, 0xbf },
{ 0xe0, 0xa9, 0xd9, 0x63, 0x6e, 0xfa, 0x36, 0xa7,
0x72, 0xac, 0xb5, 0xd0, 0x22, 0xfc, 0xa9, 0x73,
0x71, 0xb4, 0x4f, 0x7b, 0x80, 0x4b, 0x03, 0x97,
0xfb, 0x6c, 0x37, 0x1a, 0x22, 0x5b, 0xda, 0x78 },
- { 0xe0, 0xbb, 0xef, 0x7e, 0xe4, 0x37, 0xb0, 0x59,
- 0xe0, 0x3b, 0x52, 0x9b, 0xe6, 0xb4, 0x09, 0x6d,
- 0x56, 0xc7, 0x4e, 0x90, 0x67, 0xb0, 0x5f, 0x87,
- 0xaa, 0x6a, 0x5a, 0x61, 0x93, 0x40, 0xa7, 0xc3 },
{ 0xe0, 0xdd, 0xe1, 0x29, 0xd2, 0x60, 0xc3, 0xda,
0xb6, 0x91, 0xd8, 0x1d, 0xab, 0xad, 0x73, 0x4c,
0x9a, 0xdc, 0x61, 0xd2, 0x0c, 0x1a, 0xe1, 0xb6,
@@ -3374,10 +2950,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x7e, 0x1f, 0x45, 0x5b, 0x85, 0xc0, 0x6f, 0x0d,
0x80, 0x9e, 0x75, 0xa5, 0x5c, 0x6b, 0x05, 0x48,
0x16, 0xe0, 0x19, 0x89, 0x9a, 0x3a, 0x02, 0xff },
- { 0xe3, 0x1f, 0xa0, 0xbd, 0xe8, 0x58, 0x9e, 0xdd,
- 0xda, 0x1c, 0x5d, 0x1a, 0xa9, 0xc5, 0x81, 0x86,
- 0xc3, 0x14, 0x36, 0x85, 0x67, 0xbd, 0xf9, 0xdc,
- 0xd5, 0x37, 0xaa, 0xe3, 0xcf, 0xf8, 0x77, 0x52 },
{ 0xe3, 0xc8, 0xfc, 0x63, 0x7b, 0x7b, 0xb0, 0xcc,
0x67, 0x4a, 0x5a, 0x4c, 0x3b, 0x4d, 0x35, 0x62,
0xeb, 0x8a, 0xa0, 0x0d, 0x7a, 0xd2, 0xc8, 0xa9,
@@ -3426,18 +2998,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xfa, 0x2b, 0xfb, 0x76, 0xc2, 0x2d, 0xfa, 0x71,
0xbc, 0x3d, 0xa4, 0x8f, 0x67, 0x1e, 0xf7, 0x7c,
0x00, 0xaa, 0x8e, 0x45, 0x9b, 0x7c, 0xc8, 0x2a },
- { 0xe8, 0x1a, 0x87, 0x45, 0xad, 0x86, 0xf6, 0x5f,
- 0xa0, 0xd8, 0x51, 0xfc, 0xb7, 0x2e, 0x3e, 0xf5,
- 0x4d, 0x51, 0xbc, 0x60, 0xb9, 0x68, 0x0c, 0xb2,
- 0x5e, 0xb2, 0xf3, 0xac, 0x44, 0xea, 0xa7, 0xa4 },
{ 0xe8, 0x21, 0x3c, 0x45, 0x51, 0x81, 0x61, 0xbc,
0x36, 0x37, 0x3d, 0xcd, 0x2d, 0x4b, 0x21, 0xb7,
0x6a, 0x7c, 0x06, 0x6d, 0xf5, 0x52, 0x6e, 0x88,
0x8b, 0x6e, 0xed, 0x09, 0xa9, 0xee, 0xd0, 0x62 },
- { 0xe8, 0x6e, 0xe6, 0x9d, 0x51, 0xbe, 0x64, 0xf8,
- 0x28, 0xfc, 0x22, 0xcc, 0xe5, 0xbc, 0xc1, 0x1d,
- 0x24, 0xa5, 0xf1, 0x77, 0xf9, 0xba, 0x99, 0x51,
- 0x92, 0x71, 0xa4, 0xf3, 0x9f, 0x0c, 0x51, 0x7c },
{ 0xe8, 0xa6, 0x09, 0xec, 0x44, 0xf9, 0x3c, 0x12,
0xe0, 0x81, 0xe5, 0x94, 0x3b, 0x5e, 0xa0, 0x48,
0x68, 0x14, 0x48, 0x33, 0x32, 0x5d, 0xaa, 0x64,
@@ -3470,10 +3034,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x5a, 0x76, 0x07, 0x64, 0x3e, 0x15, 0x26, 0x0d,
0x1c, 0x93, 0xfd, 0x9b, 0xe0, 0xfa, 0xb1, 0x0b,
0x76, 0xdc, 0x96, 0x86, 0xf6, 0x54, 0xc6, 0xe5 },
- { 0xec, 0x01, 0x78, 0xd1, 0xca, 0x3b, 0x94, 0x52,
- 0xaa, 0x5c, 0xd5, 0xd3, 0x75, 0x45, 0x6b, 0xab,
- 0xf0, 0xdc, 0x0e, 0xd2, 0x29, 0x91, 0x5d, 0x1a,
- 0x8f, 0x49, 0x6d, 0xf2, 0xa2, 0xa0, 0x98, 0x71 },
{ 0xec, 0x27, 0x05, 0x63, 0xb0, 0x5a, 0x06, 0xe5,
0xaa, 0xa5, 0xe6, 0xd5, 0xbb, 0xcc, 0x17, 0xcd,
0x1c, 0xb5, 0xb2, 0xa9, 0x4d, 0x93, 0x84, 0x75,
@@ -3534,10 +3094,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x51, 0x6b, 0xf6, 0x39, 0x5d, 0xbd, 0x29, 0x33,
0x7c, 0xfc, 0xb7, 0xd4, 0x26, 0x64, 0x10, 0xa1,
0xf5, 0xda, 0x08, 0x08, 0xe0, 0x96, 0xf4, 0x55 },
- { 0xef, 0x7e, 0x8c, 0xcd, 0x7b, 0xcf, 0xb7, 0x1d,
- 0x2a, 0xa7, 0xbc, 0xdd, 0x8f, 0xd2, 0xd2, 0xd1,
- 0x55, 0x77, 0x9d, 0xe8, 0x68, 0x43, 0x20, 0x44,
- 0x35, 0x1e, 0x98, 0x02, 0xcc, 0xa2, 0x90, 0xaf },
{ 0xef, 0xaf, 0xca, 0x84, 0x90, 0x30, 0x7b, 0x0f,
0x62, 0x2b, 0xf4, 0x3a, 0x0e, 0xb3, 0xc5, 0x1a,
0xcb, 0xdd, 0xde, 0xdc, 0x23, 0x92, 0xf1, 0x61,
@@ -3554,10 +3110,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8d, 0x77, 0x2e, 0xba, 0xfa, 0x5b, 0xf5, 0x32,
0x92, 0x47, 0x77, 0x88, 0xdc, 0x12, 0x80, 0x32,
0x76, 0xb0, 0x00, 0xc4, 0x41, 0x91, 0x03, 0xf0 },
- { 0xf0, 0x15, 0x95, 0xf5, 0xa4, 0x66, 0x88, 0x78,
- 0xf6, 0xc7, 0x98, 0xa5, 0xd2, 0xf1, 0x35, 0x23,
- 0xf3, 0xaf, 0xb2, 0x0e, 0xf7, 0x6f, 0xe5, 0x77,
- 0x6f, 0xce, 0x47, 0xd3, 0x40, 0x9d, 0xf3, 0xc2 },
{ 0xf0, 0x2f, 0x9d, 0xa4, 0x5d, 0x9e, 0xb9, 0x86,
0x19, 0x4e, 0x06, 0xf5, 0xe6, 0x18, 0x95, 0x45,
0x12, 0xc9, 0x02, 0x6e, 0x7c, 0xa7, 0xb5, 0x1e,
@@ -3586,10 +3138,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x26, 0xaa, 0x5a, 0x6b, 0xf5, 0xc4, 0xde, 0x59,
0x1c, 0xf1, 0x65, 0x0f, 0xa8, 0x22, 0xf1, 0x34,
0xd9, 0x2d, 0x54, 0x8f, 0x15, 0x77, 0x73, 0xd6 },
- { 0xf2, 0x06, 0x59, 0x72, 0x49, 0x8d, 0x5e, 0x12,
- 0x79, 0x8e, 0x1e, 0x1f, 0xf3, 0xe1, 0x1d, 0xe4,
- 0x23, 0x3a, 0xbb, 0xbd, 0x30, 0x8a, 0x58, 0x07,
- 0x60, 0x58, 0x48, 0x18, 0x6e, 0x44, 0x11, 0x7f },
{ 0xf2, 0x54, 0x76, 0xf3, 0xab, 0x8e, 0x5e, 0x0b,
0x9b, 0xb6, 0x1d, 0x4c, 0xe4, 0x50, 0x7f, 0xa3,
0x52, 0x93, 0xc6, 0x64, 0x15, 0xd7, 0xd1, 0x91,
@@ -3634,10 +3182,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xd3, 0xc5, 0x60, 0x17, 0x6f, 0x3d, 0x77, 0xfd,
0xc5, 0x1e, 0x5f, 0x57, 0xb5, 0xe4, 0x8a, 0xe7,
0xa4, 0xb9, 0x70, 0x0a, 0x11, 0xd4, 0x69, 0x3a },
- { 0xf6, 0x41, 0xe7, 0xe0, 0x1b, 0xf4, 0xf2, 0xb0,
- 0xd0, 0xc4, 0x8b, 0xa6, 0x38, 0xa0, 0x2e, 0x26,
- 0xbd, 0xdb, 0xd7, 0x7b, 0xc5, 0xe9, 0x72, 0x61,
- 0x94, 0xdb, 0x1a, 0xea, 0x4f, 0x2f, 0xd7, 0x71 },
{ 0xf6, 0x54, 0x6b, 0x2f, 0xfe, 0x2b, 0xae, 0xf7,
0x35, 0xe8, 0x25, 0x67, 0xa6, 0xe2, 0x36, 0x75,
0x03, 0x94, 0xc1, 0x19, 0x14, 0x09, 0x87, 0x0c,
@@ -3698,10 +3242,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xad, 0x25, 0x74, 0x25, 0xaa, 0xe7, 0x20, 0x01,
0x40, 0x05, 0xb4, 0x15, 0x91, 0x2d, 0xbb, 0x8c,
0x0b, 0xc9, 0x99, 0xaf, 0x48, 0x48, 0xcf, 0xe5 },
- { 0xf9, 0x0e, 0x7c, 0x21, 0x81, 0xba, 0x53, 0x4d,
- 0xcf, 0x5b, 0xb6, 0xdb, 0xf7, 0xf9, 0xad, 0xa3,
- 0xff, 0x98, 0xde, 0x50, 0x0c, 0xbd, 0x42, 0x12,
- 0xc0, 0xd1, 0xfa, 0x05, 0x82, 0x80, 0xfd, 0x57 },
{ 0xf9, 0xa7, 0xdd, 0xd3, 0xff, 0x51, 0xaf, 0x30,
0x7f, 0x95, 0x4f, 0x7b, 0x44, 0xdb, 0xd2, 0x42,
0x83, 0xcf, 0x97, 0xb6, 0x25, 0xbe, 0x76, 0x6b,
@@ -3714,10 +3254,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa7, 0x9b, 0x05, 0x48, 0x67, 0x6c, 0x18, 0x48,
0x5a, 0xf1, 0x10, 0x4c, 0xca, 0x9b, 0xb6, 0xb8,
0xdd, 0x9b, 0x5a, 0x54, 0x3c, 0xb6, 0xc6, 0x2e },
- { 0xfa, 0xe4, 0x72, 0x1e, 0x39, 0x47, 0xa5, 0x0d,
- 0xd0, 0x4d, 0x16, 0xac, 0xef, 0xf3, 0x55, 0xc0,
- 0x87, 0xb7, 0xe2, 0x24, 0x6b, 0xe6, 0x0f, 0xbc,
- 0x26, 0x2a, 0x53, 0x52, 0xad, 0xac, 0x18, 0x01 },
{ 0xfb, 0x44, 0x15, 0x70, 0x4c, 0x1d, 0x61, 0x55,
0x10, 0x6d, 0x88, 0xf3, 0xb2, 0x0f, 0xec, 0x9f,
0x6e, 0x82, 0x0c, 0x82, 0x24, 0xfe, 0xe3, 0x5e,
@@ -3750,10 +3286,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xd0, 0xa9, 0xdf, 0xcc, 0xe9, 0x03, 0x12, 0xc7,
0x52, 0xe1, 0xb5, 0x2e, 0xb6, 0x54, 0xc4, 0x2c,
0x36, 0x94, 0x4b, 0x90, 0x2a, 0x30, 0x41, 0x07 },
- { 0xfc, 0x55, 0x86, 0x91, 0xda, 0xff, 0xe1, 0xe3,
- 0x53, 0x8d, 0x38, 0xa6, 0xd3, 0xa9, 0xe6, 0xe7,
- 0xc9, 0x9d, 0x24, 0x0c, 0x86, 0x89, 0x66, 0x73,
- 0x56, 0x27, 0x99, 0x72, 0xfb, 0x4f, 0x30, 0x85 },
{ 0xfc, 0x56, 0xdb, 0xa1, 0xe7, 0xaf, 0xbd, 0xaa,
0x07, 0x33, 0xc6, 0x91, 0x1c, 0x5f, 0x1f, 0x18,
0x28, 0xcb, 0x12, 0x98, 0x31, 0x40, 0x1a, 0x3c,
@@ -3832,14 +3364,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xaf, 0x3f, 0x5c, 0xf4, 0x22, 0x5a, 0x8e, 0xaf },
};
const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
- { 0x0e, 0x56, 0x71, 0x6d, 0xd3, 0xc1, 0x83, 0xaa,
- 0x5d, 0xe0, 0xd3, 0x96, 0x89, 0x88, 0x94, 0xf0,
- 0x03, 0xaa, 0xff, 0x06, 0x2e, 0x15, 0x82, 0x33,
- 0xef, 0xfb, 0x5b, 0xc9, 0xe8, 0x33, 0x71, 0x4b },
- { 0x0f, 0x07, 0xaa, 0xd7, 0xac, 0x55, 0x6f, 0x85,
- 0x86, 0xcb, 0xf3, 0x47, 0x8f, 0x2e, 0xc0, 0xb5,
- 0x29, 0xca, 0x46, 0x5b, 0x19, 0x3f, 0xc2, 0xa6,
- 0xe1, 0x93, 0x28, 0x3a, 0xd8, 0xd7, 0xa5, 0x50 },
{ 0x23, 0x86, 0x51, 0xab, 0x70, 0xb7, 0x11, 0xa0,
0x65, 0x55, 0x4e, 0x5d, 0x63, 0x6a, 0x34, 0x2c,
0x8a, 0x6b, 0xfe, 0x46, 0x0e, 0x4e, 0x7b, 0x4c,
@@ -3852,18 +3376,10 @@ const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
0xaa, 0x33, 0x43, 0x60, 0xa6, 0x6a, 0xc3, 0xa7,
0x3f, 0xa8, 0xd8, 0xd3, 0x60, 0x0d, 0x89, 0x4e,
0xb0, 0xc7, 0xd2, 0x84, 0x23, 0xc6, 0x78, 0x57 },
- { 0x61, 0xa7, 0x62, 0xef, 0x47, 0xbc, 0xa4, 0xee,
- 0x77, 0xa5, 0xc8, 0xaf, 0x03, 0x98, 0x9a, 0x9d,
- 0xea, 0xca, 0x4d, 0x82, 0x8a, 0x53, 0xd9, 0x23,
- 0xe7, 0x0b, 0xfb, 0xc7, 0x25, 0x4a, 0xc7, 0x70 },
{ 0x63, 0x80, 0x65, 0xec, 0x95, 0xf1, 0xea, 0x81,
0xd9, 0x5b, 0xa4, 0xdb, 0x9e, 0xa9, 0xa2, 0xef,
0xe2, 0xd6, 0xcd, 0x78, 0x75, 0x88, 0x67, 0x04,
0x5c, 0x06, 0xb6, 0x48, 0xa5, 0xda, 0x89, 0xb2 },
- { 0x67, 0xc3, 0xc0, 0xa1, 0x60, 0xe9, 0x28, 0x5e,
- 0x35, 0xa4, 0x22, 0xbb, 0x43, 0x4b, 0xff, 0xff,
- 0xee, 0x28, 0x79, 0xc6, 0xc0, 0xa5, 0x69, 0x36,
- 0x56, 0xe7, 0x73, 0xa6, 0xdd, 0x68, 0x5f, 0x0e },
{ 0x80, 0xf3, 0xeb, 0x58, 0xea, 0x6a, 0xa2, 0x85,
0x11, 0xb0, 0x9b, 0x68, 0xf2, 0xde, 0xf9, 0xb4,
0xaf, 0xa9, 0x9c, 0x97, 0x44, 0xc0, 0xbe, 0x4e,
@@ -3880,10 +3396,6 @@ const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
0xb2, 0x7c, 0x6a, 0x62, 0xe3, 0xc4, 0x23, 0x5b,
0xd8, 0x3c, 0xc5, 0xe0, 0x06, 0xe9, 0x2a, 0x55,
0xe4, 0xa9, 0x86, 0xe6, 0x30, 0x53, 0x57, 0xe3 },
- { 0xaf, 0xbb, 0x40, 0x3c, 0xad, 0x0d, 0x19, 0xcc,
- 0x26, 0xae, 0x5b, 0x1e, 0x31, 0x0a, 0xc1, 0xae,
- 0x79, 0x47, 0x1b, 0xad, 0x2b, 0xd7, 0x7b, 0xe4,
- 0x0f, 0x12, 0x50, 0x4c, 0x42, 0xe5, 0x22, 0x0b },
{ 0xb2, 0xba, 0x3b, 0x49, 0xb8, 0xe5, 0x84, 0x51,
0x81, 0x6b, 0x10, 0x83, 0x6c, 0x4f, 0x1c, 0xa6,
0xa3, 0x39, 0x37, 0xce, 0xb8, 0xf0, 0xc0, 0x4b,
@@ -3908,10 +3420,6 @@ const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
0x23, 0xb9, 0xa9, 0x60, 0xb5, 0xe9, 0x67, 0x0c,
0xcc, 0x34, 0x6d, 0x89, 0x93, 0x8f, 0xfa, 0x5d,
0xf7, 0x98, 0x65, 0xe4, 0x13, 0xd6, 0x31, 0x54 },
- { 0xee, 0x3d, 0x0b, 0xc5, 0xa6, 0x5a, 0xf5, 0x8d,
- 0x43, 0x2d, 0x08, 0x63, 0x7b, 0xe0, 0xb7, 0xba,
- 0x49, 0xc2, 0x32, 0x61, 0x8d, 0xa9, 0xc8, 0x97,
- 0x3f, 0x88, 0x56, 0x8c, 0x88, 0x89, 0xd1, 0xad },
{ 0xf3, 0xcb, 0x8e, 0xa4, 0xe8, 0xf2, 0xa7, 0x00,
0x9c, 0x23, 0x3a, 0x64, 0x88, 0x71, 0xdb, 0x46,
0x04, 0xd5, 0x45, 0x4b, 0xc5, 0x55, 0x9e, 0x9b,
diff --git a/chromium/net/cert/cert_verify_proc_whitelist.h b/chromium/net/cert/cert_verify_proc_whitelist.h
index c4a5aae0c6a..47ce9831848 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist.h
+++ b/chromium/net/cert/cert_verify_proc_whitelist.h
@@ -5,6 +5,7 @@
#ifndef NET_CERT_CERT_VERIFY_PROC_WHITELIST_H_
#define NET_CERT_CERT_VERIFY_PROC_WHITELIST_H_
+#include <stddef.h>
#include <stdint.h>
#include "crypto/sha2.h"
diff --git a/chromium/net/cert/cert_verify_proc_win.cc b/chromium/net/cert/cert_verify_proc_win.cc
index 4eada6f4b49..cb1db7d9b84 100644
--- a/chromium/net/cert/cert_verify_proc_win.cc
+++ b/chromium/net/cert/cert_verify_proc_win.cc
@@ -281,9 +281,9 @@ bool IsIssuedByKnownRoot(PCCERT_CHAIN_CONTEXT chain_context) {
PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement;
PCCERT_CONTEXT cert = element[num_elements - 1]->pCertContext;
- SHA1HashValue hash = X509Certificate::CalculateFingerprint(cert);
- return IsSHA1HashInSortedArray(
- hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes));
+ SHA256HashValue hash = X509Certificate::CalculateFingerprint256(cert);
+ return IsSHA256HashInSortedArray(hash, &kKnownRootCertSHA256Hashes[0][0],
+ sizeof(kKnownRootCertSHA256Hashes));
}
// Saves some information about the certificate chain |chain_context| in
@@ -295,7 +295,7 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
return;
PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0];
- int num_elements = first_chain->cElement;
+ DWORD num_elements = first_chain->cElement;
PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement;
PCCERT_CONTEXT verified_cert = NULL;
@@ -316,7 +316,7 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
num_elements -= 1;
}
- for (int i = 0; i < num_elements; ++i) {
+ for (DWORD i = 0; i < num_elements; ++i) {
PCCERT_CONTEXT cert = element[i]->pCertContext;
if (i == 0) {
verified_cert = cert;
@@ -341,6 +341,8 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
// id-dsa-with-sha1: 1.2.840.10040.4.3
// ecdsa-with-SHA1: 1.2.840.10045.4.1
verify_result->has_sha1 = true;
+ if (i == 0)
+ verify_result->has_sha1_leaf = true;
}
}
diff --git a/chromium/net/cert/cert_verify_result.cc b/chromium/net/cert/cert_verify_result.cc
index b2413e6755d..2a418938e71 100644
--- a/chromium/net/cert/cert_verify_result.cc
+++ b/chromium/net/cert/cert_verify_result.cc
@@ -22,6 +22,7 @@ void CertVerifyResult::Reset() {
has_md4 = false;
has_md5 = false;
has_sha1 = false;
+ has_sha1_leaf = false;
is_issued_by_known_root = false;
is_issued_by_additional_trust_anchor = false;
common_name_fallback_used = false;
diff --git a/chromium/net/cert/cert_verify_result.h b/chromium/net/cert/cert_verify_result.h
index 9e673255293..104fc6eec46 100644
--- a/chromium/net/cert/cert_verify_result.h
+++ b/chromium/net/cert/cert_verify_result.h
@@ -48,6 +48,7 @@ class NET_EXPORT CertVerifyResult {
bool has_md4;
bool has_md5;
bool has_sha1;
+ bool has_sha1_leaf;
// If the certificate was successfully verified then this contains the
// hashes, in several hash algorithms, of the SubjectPublicKeyInfos of the
diff --git a/chromium/net/cert/crl_set.h b/chromium/net/cert/crl_set.h
index f54e346b460..2a84d2ae17c 100644
--- a/chromium/net/cert/crl_set.h
+++ b/chromium/net/cert/crl_set.h
@@ -5,6 +5,9 @@
#ifndef NET_CERT_CRL_SET_H_
#define NET_CERT_CRL_SET_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <utility>
#include <vector>
diff --git a/chromium/net/cert/ct_known_logs.cc b/chromium/net/cert/ct_known_logs.cc
index 381d4dd1013..eddeb55a8a9 100644
--- a/chromium/net/cert/ct_known_logs.cc
+++ b/chromium/net/cert/ct_known_logs.cc
@@ -4,28 +4,63 @@
#include "net/cert/ct_known_logs.h"
-#include <string>
+#include <algorithm>
+#include "base/logging.h"
#include "base/macros.h"
-#include "base/strings/string_piece.h"
+#include "crypto/sha2.h"
#include "net/cert/ct_known_logs_static.h"
+
+#if !defined(OS_NACL)
#include "net/cert/ct_log_verifier.h"
+#endif
namespace net {
namespace ct {
-std::vector<scoped_refptr<CTLogVerifier>> CreateLogVerifiersForKnownLogs() {
- std::vector<scoped_refptr<CTLogVerifier>> verifiers;
+namespace {
+
+int log_ids_compare(const char* log_id, const char* lookup_id) {
+ return strncmp(log_id, lookup_id, crypto::kSHA256Length) < 0;
+}
+
+} // namespace
+
+#if !defined(OS_NACL)
+std::vector<scoped_refptr<const CTLogVerifier>>
+CreateLogVerifiersForKnownLogs() {
+ std::vector<scoped_refptr<const CTLogVerifier>> verifiers;
for (size_t i = 0; i < arraysize(kCTLogList); ++i) {
const CTLogInfo& log(kCTLogList[i]);
base::StringPiece key(log.log_key, log.log_key_length);
verifiers.push_back(CTLogVerifier::Create(key, log.log_name, log.log_url));
+ // Make sure no null logs enter verifiers. Parsing of all known logs should
+ // succeed.
+ CHECK(verifiers.back().get());
}
return verifiers;
}
+#endif
+
+bool IsLogOperatedByGoogle(base::StringPiece log_id) {
+ // No callers should provide a log_id that's not of the expected length
+ // (log IDs are SHA-256 hashes of the key and are always 32 bytes).
+ // Without this DCHECK (i.e. in production) this function would always
+ // return false.
+ DCHECK_EQ(log_id.size(), arraysize(kGoogleLogIDs[0]) - 1);
+
+ auto p = std::lower_bound(kGoogleLogIDs, kGoogleLogIDs + kNumGoogleLogs,
+ log_id.data(), &log_ids_compare);
+ if ((p == kGoogleLogIDs + kNumGoogleLogs) ||
+ log_id != base::StringPiece(*p, crypto::kSHA256Length)) {
+ return false;
+ }
+
+ return true;
+}
} // namespace ct
diff --git a/chromium/net/cert/ct_known_logs.h b/chromium/net/cert/ct_known_logs.h
index e6bbfc15b85..48904c2cc54 100644
--- a/chromium/net/cert/ct_known_logs.h
+++ b/chromium/net/cert/ct_known_logs.h
@@ -8,6 +8,8 @@
#include <vector>
#include "base/memory/ref_counted.h"
+#include "base/strings/string_piece.h"
+#include "build/build_config.h"
#include "net/base/net_export.h"
namespace net {
@@ -16,10 +18,14 @@ class CTLogVerifier;
namespace ct {
+#if !defined(OS_NACL)
// CreateLogVerifiersForKnownLogs returns a vector of CT logs for all the known
// and trusted logs.
-NET_EXPORT std::vector<scoped_refptr<CTLogVerifier>>
+NET_EXPORT std::vector<scoped_refptr<const CTLogVerifier>>
CreateLogVerifiersForKnownLogs();
+#endif
+
+NET_EXPORT bool IsLogOperatedByGoogle(base::StringPiece log_id);
} // namespace ct
diff --git a/chromium/net/cert/ct_known_logs_static.h b/chromium/net/cert/ct_known_logs_static.h
index d67b9fd72e5..a1e30f1fc6d 100644
--- a/chromium/net/cert/ct_known_logs_static.h
+++ b/chromium/net/cert/ct_known_logs_static.h
@@ -6,6 +6,8 @@
#ifndef NET_CERT_CT_KNOWN_LOGS_STATIC_H_
#define NET_CERT_CT_KNOWN_LOGS_STATIC_H_
+#include <stddef.h>
+
struct CTLogInfo {
const char* const log_key;
const size_t log_key_length;
@@ -101,4 +103,15 @@ const CTLogInfo kCTLogList[] = {
const size_t kNumKnownCTLogs = 8;
+// The list is sorted.
+const char kGoogleLogIDs[][33] = {
+ "\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71"
+ "\x51\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\xfb\xc4",
+ "\xa4\xb9\x09\x90\xb4\x18\x58\x14\x87\xbb\x13\xa2\xcc\x67\x70\x0a\x3c"
+ "\x35\x98\x04\xf9\x1b\xdf\xb8\xe3\x77\xcd\x0e\xc8\x0d\xdc\x10",
+ "\xee\x4b\xbd\xb7\x75\xce\x60\xba\xe1\x42\x69\x1f\xab\xe1\x9e\x66\xa3"
+ "\x0f\x7e\x5f\xb0\x72\xd8\x83\x00\xc4\x7b\x89\x7a\xa8\xfd\xcb"};
+
+const size_t kNumGoogleLogs = 3;
+
#endif // NET_CERT_CT_KNOWN_LOGS_STATIC_H_
diff --git a/chromium/net/cert/ct_log_response_parser.cc b/chromium/net/cert/ct_log_response_parser.cc
index 0069fc70848..628eef286be 100644
--- a/chromium/net/cert/ct_log_response_parser.cc
+++ b/chromium/net/cert/ct_log_response_parser.cc
@@ -7,6 +7,7 @@
#include "base/base64.h"
#include "base/json/json_value_converter.h"
#include "base/logging.h"
+#include "base/memory/scoped_vector.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -101,6 +102,33 @@ bool IsJsonSTHStructurallyValid(const JsonSignedTreeHead& sth) {
return true;
}
+// Structure for making JSON decoding easier. The string fields
+// are base64-encoded so will require further decoding.
+struct JsonConsistencyProof {
+ ScopedVector<std::string> proof_nodes;
+
+ static void RegisterJSONConverter(
+ base::JSONValueConverter<JsonConsistencyProof>* converter);
+};
+
+bool ConvertIndividualProofNode(const base::Value* value, std::string* result) {
+ std::string b64_encoded_node;
+ if (!value->GetAsString(&b64_encoded_node))
+ return false;
+
+ if (!ConvertSHA256RootHash(b64_encoded_node, result))
+ return false;
+
+ return true;
+}
+
+void JsonConsistencyProof::RegisterJSONConverter(
+ base::JSONValueConverter<JsonConsistencyProof>* converter) {
+ converter->RegisterRepeatedCustomValue<std::string>(
+ "consistency", &JsonConsistencyProof::proof_nodes,
+ &ConvertIndividualProofNode);
+}
+
} // namespace
bool FillSignedTreeHead(const base::Value& json_signed_tree_head,
@@ -127,6 +155,30 @@ bool FillSignedTreeHead(const base::Value& json_signed_tree_head,
return true;
}
+bool FillConsistencyProof(const base::Value& json_consistency_proof,
+ std::vector<std::string>* consistency_proof) {
+ JsonConsistencyProof parsed_proof;
+ base::JSONValueConverter<JsonConsistencyProof> converter;
+ if (!converter.Convert(json_consistency_proof, &parsed_proof)) {
+ DVLOG(1) << "Invalid consistency proof.";
+ return false;
+ }
+
+ const base::DictionaryValue* dict_value = NULL;
+ if (!json_consistency_proof.GetAsDictionary(&dict_value) ||
+ !dict_value->HasKey("consistency")) {
+ DVLOG(1) << "Missing consistency field.";
+ return false;
+ }
+
+ consistency_proof->reserve(parsed_proof.proof_nodes.size());
+ for (std::string* proof_node : parsed_proof.proof_nodes) {
+ consistency_proof->push_back(*proof_node);
+ }
+
+ return true;
+}
+
} // namespace ct
} // namespace net
diff --git a/chromium/net/cert/ct_log_response_parser.h b/chromium/net/cert/ct_log_response_parser.h
index b7a012bde05..403f8bfb050 100644
--- a/chromium/net/cert/ct_log_response_parser.h
+++ b/chromium/net/cert/ct_log_response_parser.h
@@ -5,6 +5,9 @@
#ifndef NET_CERT_CT_LOG_RESPONSE_PARSER_H_
#define NET_CERT_CT_LOG_RESPONSE_PARSER_H_
+#include <string>
+#include <vector>
+
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -24,6 +27,10 @@ struct SignedTreeHead;
NET_EXPORT bool FillSignedTreeHead(const base::Value& json_signed_tree_head,
SignedTreeHead* signed_tree_head);
+NET_EXPORT bool FillConsistencyProof(
+ const base::Value& json_signed_tree_head,
+ std::vector<std::string>* consistency_proof);
+
} // namespace ct
} // namespace net
diff --git a/chromium/net/cert/ct_log_response_parser_unittest.cc b/chromium/net/cert/ct_log_response_parser_unittest.cc
index 9f02699d744..fad759019ac 100644
--- a/chromium/net/cert/ct_log_response_parser_unittest.cc
+++ b/chromium/net/cert/ct_log_response_parser_unittest.cc
@@ -23,7 +23,7 @@ namespace ct {
namespace {
scoped_ptr<base::Value> ParseJson(const std::string& json) {
base::JSONReader json_reader;
- return json_reader.Read(json).Pass();
+ return json_reader.Read(json);
}
}
@@ -33,7 +33,7 @@ TEST(CTLogResponseParserTest, ParsesValidJsonSTH) {
EXPECT_TRUE(FillSignedTreeHead(*sample_sth_json.get(), &tree_head));
SignedTreeHead sample_sth;
- GetSampleSignedTreeHead(&sample_sth);
+ ASSERT_TRUE(GetSampleSignedTreeHead(&sample_sth));
ASSERT_EQ(SignedTreeHead::V1, tree_head.version);
ASSERT_EQ(sample_sth.timestamp, tree_head.timestamp);
@@ -95,6 +95,53 @@ TEST(CTLogResponseParserTest, FailsToParseIncorrectLengthRootHash) {
ASSERT_FALSE(FillSignedTreeHead(*too_short_hash_json.get(), &tree_head));
}
+TEST(CTLogResponseParserTest, ParsesConsistencyProofSuccessfully) {
+ std::string first(32, 'a');
+ std::string second(32, 'b');
+ std::string third(32, 'c');
+
+ std::vector<std::string> raw_nodes;
+ raw_nodes.push_back(first);
+ raw_nodes.push_back(second);
+ raw_nodes.push_back(third);
+ scoped_ptr<base::Value> sample_consistency_proof =
+ ParseJson(CreateConsistencyProofJsonString(raw_nodes));
+
+ std::vector<std::string> output;
+
+ ASSERT_TRUE(FillConsistencyProof(*sample_consistency_proof.get(), &output));
+
+ EXPECT_EQ(output[0], first);
+ EXPECT_EQ(output[1], second);
+ EXPECT_EQ(output[2], third);
+}
+
+TEST(CTLogResponseParserTest, FailsOnInvalidProofJson) {
+ std::vector<std::string> output;
+
+ scoped_ptr<base::Value> badly_encoded =
+ ParseJson(std::string("{\"consistency\": [\"notbase64\"]}"));
+ EXPECT_FALSE(FillConsistencyProof(*badly_encoded.get(), &output));
+
+ scoped_ptr<base::Value> not_a_string =
+ ParseJson(std::string("{\"consistency\": [42, 16]}"));
+ EXPECT_FALSE(FillConsistencyProof(*badly_encoded.get(), &output));
+
+ scoped_ptr<base::Value> missing_consistency = ParseJson(std::string("{}"));
+ EXPECT_FALSE(FillConsistencyProof(*missing_consistency.get(), &output));
+
+ scoped_ptr<base::Value> not_a_dict = ParseJson(std::string("[]"));
+ EXPECT_FALSE(FillConsistencyProof(*not_a_dict.get(), &output));
+}
+
+TEST(CTLogResponseParserTest, ParsesProofJsonWithExtraFields) {
+ std::vector<std::string> output;
+
+ scoped_ptr<base::Value> badly_encoded =
+ ParseJson(std::string("{\"consistency\": [], \"somethingelse\": 3}"));
+ EXPECT_TRUE(FillConsistencyProof(*badly_encoded.get(), &output));
+}
+
} // namespace ct
} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier.cc b/chromium/net/cert/ct_log_verifier.cc
index 7dbde12c4b2..0f70678add0 100644
--- a/chromium/net/cert/ct_log_verifier.cc
+++ b/chromium/net/cert/ct_log_verifier.cc
@@ -4,14 +4,32 @@
#include "net/cert/ct_log_verifier.h"
+#include <string.h>
+
#include "base/logging.h"
+#include "net/cert/ct_log_verifier_util.h"
#include "net/cert/ct_serialization.h"
+#include "net/cert/merkle_consistency_proof.h"
#include "net/cert/signed_tree_head.h"
namespace net {
+namespace {
+
+// The SHA-256 hash of the empty string.
+const unsigned char kSHA256EmptyStringHash[ct::kSthRootHashLength] = {
+ 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};
+
+bool IsPowerOfTwo(uint64_t n) {
+ return n != 0 && (n & (n - 1)) == 0;
+}
+
+} // namespace
+
// static
-scoped_refptr<CTLogVerifier> CTLogVerifier::Create(
+scoped_refptr<const CTLogVerifier> CTLogVerifier::Create(
const base::StringPiece& public_key,
const base::StringPiece& description,
const base::StringPiece& url) {
@@ -35,7 +53,7 @@ CTLogVerifier::CTLogVerifier(const base::StringPiece& description,
}
bool CTLogVerifier::Verify(const ct::LogEntry& entry,
- const ct::SignedCertificateTimestamp& sct) {
+ const ct::SignedCertificateTimestamp& sct) const {
if (sct.log_id != key_id()) {
DVLOG(1) << "SCT is not signed by this log.";
return false;
@@ -60,7 +78,7 @@ bool CTLogVerifier::Verify(const ct::LogEntry& entry,
}
bool CTLogVerifier::VerifySignedTreeHead(
- const ct::SignedTreeHead& signed_tree_head) {
+ const ct::SignedTreeHead& signed_tree_head) const {
if (!SignatureParametersMatch(signed_tree_head.signature))
return false;
@@ -68,13 +86,18 @@ bool CTLogVerifier::VerifySignedTreeHead(
ct::EncodeTreeHeadSignature(signed_tree_head, &serialized_data);
if (VerifySignature(serialized_data,
signed_tree_head.signature.signature_data)) {
+ if (signed_tree_head.tree_size == 0) {
+ // Root hash must equate SHA256 hash of the empty string.
+ return (memcmp(signed_tree_head.sha256_root_hash, kSHA256EmptyStringHash,
+ ct::kSthRootHashLength) == 0);
+ }
return true;
}
return false;
}
bool CTLogVerifier::SignatureParametersMatch(
- const ct::DigitallySigned& signature) {
+ const ct::DigitallySigned& signature) const {
if (!signature.SignatureParametersMatch(hash_algorithm_,
signature_algorithm_)) {
DVLOG(1) << "Mismatched hash or signature algorithm. Hash: "
@@ -87,4 +110,114 @@ bool CTLogVerifier::SignatureParametersMatch(
return true;
}
+bool CTLogVerifier::VerifyConsistencyProof(
+ const ct::MerkleConsistencyProof& proof,
+ const std::string& old_tree_hash,
+ const std::string& new_tree_hash) const {
+ // Proof does not originate from this log.
+ if (key_id_ != proof.log_id)
+ return false;
+
+ // Cannot prove consistency from a tree of a certain size to a tree smaller
+ // than that - only the other way around.
+ if (proof.first_tree_size > proof.second_tree_size)
+ return false;
+
+ // If the proof is between trees of the same size, then the 'proof'
+ // is really just a statement that the tree hasn't changed. If this
+ // is the case, there should be no proof nodes, and both the old
+ // and new hash should be equivalent.
+ if (proof.first_tree_size == proof.second_tree_size)
+ return proof.nodes.empty() && old_tree_hash == new_tree_hash;
+
+ // It is possible to call this method to prove consistency between the
+ // initial state of a log (i.e. an empty tree) and a later root. In that
+ // case, the only valid proof is an empty proof.
+ if (proof.first_tree_size == 0)
+ return proof.nodes.empty();
+
+ // Implement the algorithm described in
+ // https://tools.ietf.org/html/draft-ietf-trans-rfc6962-bis-11#section-9.4.2
+ //
+ // It maintains a pair of hashes |fr| and |sr|, initialized to the same
+ // value. Each node in |proof| will be hashed to the left of both |fr| and
+ // |sr| or to the right of only |sr|. The proof is then valid if |fr| is
+ // |old_tree_hash| and |sr| is |new_tree_hash|, proving that tree nodes which
+ // make up |old_tree_hash| are a prefix of |new_tree_hash|.
+
+ // At this point, the algorithm's preconditions must be satisfied.
+ DCHECK_LT(0u, proof.first_tree_size);
+ DCHECK_LT(proof.first_tree_size, proof.second_tree_size);
+
+ // 1. If "first" is an exact power of 2, then prepend "first_hash" to the
+ // "consistency_path" array.
+ base::StringPiece first_proof_node = old_tree_hash;
+ std::vector<std::string>::const_iterator iter = proof.nodes.begin();
+ if (!IsPowerOfTwo(proof.first_tree_size)) {
+ if (iter == proof.nodes.end())
+ return false;
+ first_proof_node = *iter;
+ ++iter;
+ }
+ // iter now points to the second node in the modified proof.nodes.
+
+ // 2. Set "fn" to "first - 1" and "sn" to "second - 1".
+ uint64_t fn = proof.first_tree_size - 1;
+ uint64_t sn = proof.second_tree_size - 1;
+
+ // 3. If "LSB(fn)" is set, then right-shift both "fn" and "sn" equally until
+ // "LSB(fn)" is not set.
+ while (fn & 1) {
+ fn >>= 1;
+ sn >>= 1;
+ }
+
+ // 4. Set both "fr" and "sr" to the first value in the "consistency_path"
+ // array.
+ std::string fr = first_proof_node.as_string();
+ std::string sr = first_proof_node.as_string();
+
+ // 5. For each subsequent value "c" in the "consistency_path" array:
+ for (; iter != proof.nodes.end(); ++iter) {
+ // The proof should end exactly when |sn| becomes zero. This check is
+ // missing from the draft specification. It and the additional check below
+ // ensure the proof is consistent with the tree sizes but is not necessary
+ // to ensure |old_tree_hash| is a prefix of |new_tree_hash|.
+ if (sn == 0)
+ return false;
+ // If "LSB(fn)" is set, or if "fn" is equal to "sn", then:
+ if ((fn & 1) || fn == sn) {
+ // 1. Set "fr" to "HASH(0x01 || c || fr)"
+ // Set "sr" to "HASH(0x01 || c || sr)"
+ fr = ct::internal::HashNodes(*iter, fr);
+ sr = ct::internal::HashNodes(*iter, sr);
+
+ // 2. If "LSB(fn)" is not set, then right-shift both "fn" and "sn" equally
+ // until either "LSB(fn)" is set or "fn" is "0".
+ while (!(fn & 1) && fn != 0) {
+ fn >>= 1;
+ sn >>= 1;
+ }
+ } else { // Otherwise:
+ // Set "sr" to "HASH(0x01 || sr || c)"
+ sr = ct::internal::HashNodes(sr, *iter);
+ }
+
+ // Finally, right-shift both "fn" and "sn" one time.
+ fn >>= 1;
+ sn >>= 1;
+ }
+
+ // 6. After completing iterating through the "consistency_path" array as
+ // described above, verify that the "fr" calculated is equal to the
+ // "first_hash" supplied and that the "sr" calculated is equal to the
+ // "second_hash" supplied.
+ //
+ // The proof should also end exactly when |sn| becomes zero. This check is
+ // missing from the draft specification. It and the additional check above
+ // ensure the proof is consistent with the tree sizes but is not necessary to
+ // ensure |old_tree_hash| is a prefix of |new_tree_hash|.
+ return fr == old_tree_hash && sr == new_tree_hash && sn == 0;
+}
+
} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier.h b/chromium/net/cert/ct_log_verifier.h
index 0a9b3eff03d..9f50c1423a6 100644
--- a/chromium/net/cert/ct_log_verifier.h
+++ b/chromium/net/cert/ct_log_verifier.h
@@ -25,11 +25,18 @@ typedef struct SECKEYPublicKeyStr SECKEYPublicKey;
namespace net {
namespace ct {
+
struct SignedTreeHead;
+struct MerkleConsistencyProof;
+
} // namespace ct
-// Class for verifying Signed Certificate Timestamps (SCTs) provided by a
-// specific log (whose identity is provided during construction).
+// Class for verifying signatures of a single Certificate Transparency
+// log, whose identity is provided during construction.
+// Currently can verify Signed Certificate Timestamp (SCT) and Signed
+// Tree Head (STH) signatures.
+// Immutable: Does not hold any state beyond the log information it was
+// initialized with.
class NET_EXPORT CTLogVerifier
: public base::RefCountedThreadSafe<CTLogVerifier> {
public:
@@ -37,7 +44,7 @@ class NET_EXPORT CTLogVerifier
// using |public_key|, which is a DER-encoded SubjectPublicKeyInfo.
// If |public_key| refers to an unsupported public key, returns NULL.
// |description| is a textual description of the log.
- static scoped_refptr<CTLogVerifier> Create(
+ static scoped_refptr<const CTLogVerifier> Create(
const base::StringPiece& public_key,
const base::StringPiece& description,
const base::StringPiece& url);
@@ -49,12 +56,21 @@ class NET_EXPORT CTLogVerifier
// Returns the log's URL
const GURL& url() const { return url_; }
- // Verifies that |sct| contains a valid signature for |entry|.
+ // Verifies that |sct| is valid for |entry| and was signed by this log.
bool Verify(const ct::LogEntry& entry,
- const ct::SignedCertificateTimestamp& sct);
+ const ct::SignedCertificateTimestamp& sct) const;
+
+ // Verifies that |signed_tree_head| is a valid Signed Tree Head (RFC 6962,
+ // Section 3.5) for this log.
+ bool VerifySignedTreeHead(const ct::SignedTreeHead& signed_tree_head) const;
- // Returns true if the signature in |signed_tree_head| verifies.
- bool VerifySignedTreeHead(const ct::SignedTreeHead& signed_tree_head);
+ // Verifies that |proof| is a valid consistency proof (RFC 6962, Section
+ // 2.1.2) for this log, and which proves that |old_tree_hash| has
+ // been fully incorporated into the Merkle tree represented by
+ // |new_tree_hash|.
+ bool VerifyConsistencyProof(const ct::MerkleConsistencyProof& proof,
+ const std::string& old_tree_hash,
+ const std::string& new_tree_hash) const;
private:
FRIEND_TEST_ALL_PREFIXES(CTLogVerifierTest, VerifySignature);
@@ -70,11 +86,11 @@ class NET_EXPORT CTLogVerifier
// that |signature| contains the raw signature data (eg: without any
// DigitallySigned struct encoding).
bool VerifySignature(const base::StringPiece& data_to_sign,
- const base::StringPiece& signature);
+ const base::StringPiece& signature) const;
// Returns true if the signature and hash algorithms in |signature|
// match those of the log
- bool SignatureParametersMatch(const ct::DigitallySigned& signature);
+ bool SignatureParametersMatch(const ct::DigitallySigned& signature) const;
std::string key_id_;
std::string description_;
diff --git a/chromium/net/cert/ct_log_verifier_nss.cc b/chromium/net/cert/ct_log_verifier_nss.cc
index 75a87d610f6..fec7dc832da 100644
--- a/chromium/net/cert/ct_log_verifier_nss.cc
+++ b/chromium/net/cert/ct_log_verifier_nss.cc
@@ -117,7 +117,7 @@ bool CTLogVerifier::Init(const base::StringPiece& public_key) {
}
bool CTLogVerifier::VerifySignature(const base::StringPiece& data_to_sign,
- const base::StringPiece& signature) {
+ const base::StringPiece& signature) const {
SECItem sig_data;
sig_data.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
signature.data()));
diff --git a/chromium/net/cert/ct_log_verifier_openssl.cc b/chromium/net/cert/ct_log_verifier_openssl.cc
index af875a58738..5fe41fd7769 100644
--- a/chromium/net/cert/ct_log_verifier_openssl.cc
+++ b/chromium/net/cert/ct_log_verifier_openssl.cc
@@ -86,7 +86,7 @@ bool CTLogVerifier::Init(const base::StringPiece& public_key) {
}
bool CTLogVerifier::VerifySignature(const base::StringPiece& data_to_sign,
- const base::StringPiece& signature) {
+ const base::StringPiece& signature) const {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
const EVP_MD* hash_alg = GetEvpAlg(hash_algorithm_);
diff --git a/chromium/net/cert/ct_log_verifier_unittest.cc b/chromium/net/cert/ct_log_verifier_unittest.cc
index 4f0fdcccc7e..3ee926353af 100644
--- a/chromium/net/cert/ct_log_verifier_unittest.cc
+++ b/chromium/net/cert/ct_log_verifier_unittest.cc
@@ -4,9 +4,16 @@
#include "net/cert/ct_log_verifier.h"
+#include <stdint.h>
+
#include <string>
+#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
+#include "crypto/secure_hash.h"
+#include "net/base/hash_value.h"
+#include "net/cert/ct_log_verifier_util.h"
+#include "net/cert/merkle_consistency_proof.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/signed_tree_head.h"
#include "net/test/ct_test_util.h"
@@ -14,20 +21,222 @@
namespace net {
+namespace {
+
+// Calculate the power of two nearest to, but less than, |n|.
+// |n| must be at least 2.
+uint64_t CalculateNearestPowerOfTwo(uint64_t n) {
+ DCHECK_GT(n, 1u);
+
+ uint64_t ret = UINT64_C(1) << 63;
+ while (ret >= n)
+ ret >>= 1;
+
+ return ret;
+}
+
+// The following structures, TestVector and ProofTestVector are used for
+// definining test proofs later on.
+
+// A single hash node.
+struct TestVector {
+ const char* const str;
+ size_t length_bytes;
+};
+
+// A single consistency proof. Contains the old and new tree sizes
+// (snapshot1 and snapshot2), the length of the proof (proof_length) and
+// at most 3 proof nodes (all test proofs will be for a tree of size 8).
+struct ProofTestVector {
+ uint64_t snapshot1;
+ uint64_t snapshot2;
+ size_t proof_length;
+ TestVector proof[3];
+};
+
+// All test data replicated from
+// https://github.com/google/certificate-transparency/blob/c41b090ecc14ddd6b3531dc7e5ce36b21e253fdd/cpp/merkletree/merkle_tree_test.cc
+// A hash of the empty string.
+const TestVector kSHA256EmptyTreeHash = {
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 32};
+
+// Node hashes for a sample tree of size 8 (each element in this array is
+// a node hash, not leaf data; order represents order of the nodes in the tree).
+const TestVector kSHA256Roots[8] = {
+ {"6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", 32},
+ {"fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125", 32},
+ {"aeb6bcfe274b70a14fb067a5e5578264db0fa9b51af5e0ba159158f329e06e77", 32},
+ {"d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7", 32},
+ {"4e3bbb1f7b478dcfe71fb631631519a3bca12c9aefca1612bfce4c13a86264d4", 32},
+ {"76e67dadbcdf1e10e1b74ddc608abd2f98dfb16fbce75277b5232a127f2087ef", 32},
+ {"ddb89be403809e325750d3d263cd78929c2942b7942a34b77e122c9594a74c8c", 32},
+ {"5dc9da79a70659a9ad559cb701ded9a2ab9d823aad2f4960cfe370eff4604328", 32}};
+
+// A collection of consistency proofs between various sub-trees of the tree
+// defined by |kSHA256Roots|.
+const ProofTestVector kSHA256Proofs[4] = {
+ // Empty consistency proof between trees of the same size (1).
+ {1, 1, 0, {{"", 0}, {"", 0}, {"", 0}}},
+ // Consistency proof between tree of size 1 and tree of size 8, with 3
+ // nodes in the proof.
+ {1,
+ 8,
+ 3,
+ {{"96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7", 32},
+ {"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", 32},
+ {"6b47aaf29ee3c2af9af889bc1fb9254dabd31177f16232dd6aab035ca39bf6e4",
+ 32}}},
+ // Consistency proof between tree of size 6 and tree of size 8, with 3
+ // nodes in the proof.
+ {6,
+ 8,
+ 3,
+ {{"0ebc5d3437fbe2db158b9f126a1d118e308181031d0a949f8dededebc558ef6a", 32},
+ {"ca854ea128ed050b41b35ffc1b87b8eb2bde461e9e3b5596ece6b9d5975a0ae0", 32},
+ {"d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7",
+ 32}}},
+ // Consistency proof between tree of size 2 and tree of size 5, with 2
+ // nodes in the proof.
+ {2,
+ 5,
+ 2,
+ {{"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", 32},
+ {"bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b", 32},
+ {"", 0}}}};
+
+// Decodes a hexadecimal string into the binary data it represents.
+std::string HexToBytes(const char* hex_data, size_t hex_data_length) {
+ std::vector<uint8_t> output;
+ std::string result;
+ std::string hex_data_input(hex_data, hex_data_length);
+ if (base::HexStringToBytes(hex_data, &output))
+ result.assign(reinterpret_cast<const char*>(&output[0]), output.size());
+ return result;
+}
+
+std::string GetEmptyTreeHash() {
+ return HexToBytes(kSHA256EmptyTreeHash.str,
+ kSHA256EmptyTreeHash.length_bytes);
+}
+
+// Creates a ct::MerkleConsistencyProof and returns the result of
+// calling log->VerifyConsistencyProof with that proof and snapshots.
+bool VerifyConsistencyProof(scoped_refptr<const CTLogVerifier> log,
+ uint64_t old_tree_size,
+ const std::string& old_tree_root,
+ uint64_t new_tree_size,
+ const std::string& new_tree_root,
+ const std::vector<std::string>& proof) {
+ return log->VerifyConsistencyProof(
+ ct::MerkleConsistencyProof(log->key_id(), proof, old_tree_size,
+ new_tree_size),
+ old_tree_root, new_tree_root);
+}
+
class CTLogVerifierTest : public ::testing::Test {
public:
CTLogVerifierTest() {}
void SetUp() override {
log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog",
- "https://ct.example.com").Pass();
+ "https://ct.example.com");
ASSERT_TRUE(log_);
ASSERT_EQ(log_->key_id(), ct::GetTestPublicKeyId());
}
+ // Given a consistency proof between two snapshots of the tree, asserts that
+ // it verifies and no other combination of snapshots and proof nodes verifies.
+ void VerifierConsistencyCheck(int snapshot1,
+ int snapshot2,
+ const std::string& root1,
+ const std::string& root2,
+ const std::vector<std::string>& proof) {
+ // Verify the original consistency proof.
+ EXPECT_TRUE(
+ VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, root2, proof))
+ << " " << snapshot1 << " " << snapshot2;
+
+ if (proof.empty()) {
+ // For simplicity test only non-trivial proofs that have root1 != root2
+ // snapshot1 != 0 and snapshot1 != snapshot2.
+ return;
+ }
+
+ // Wrong snapshot index: The proof checking code should not accept
+ // as a valid proof a proof for a tree size different than the original
+ // size it was produced for.
+ // Test that this is not the case for off-by-one changes.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 - 1, root1, snapshot2,
+ root2, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 + 1, root1, snapshot2,
+ root2, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 ^ 2, root1, snapshot2,
+ root2, proof));
+
+ // Test that the proof is not accepted for trees with wrong tree height.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2 * 2,
+ root2, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2 / 2,
+ root2, proof));
+
+ // Test that providing the wrong input root fails checking an
+ // otherwise-valid proof.
+ const std::string wrong_root("WrongRoot");
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ wrong_root, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, wrong_root, snapshot2,
+ root2, proof));
+ // Test that swapping roots fails checking an otherwise-valid proof (that
+ // the right root is used for each calculation).
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root2, snapshot2,
+ root1, proof));
+
+ // Variations of wrong proofs, all of which should be rejected.
+ std::vector<std::string> wrong_proof;
+ // Empty proof.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+
+ // Modify a single element in the proof.
+ for (size_t j = 0; j < proof.size(); ++j) {
+ wrong_proof = proof;
+ wrong_proof[j] = GetEmptyTreeHash();
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ }
+
+ // Add garbage at the end of the proof.
+ wrong_proof = proof;
+ wrong_proof.push_back(std::string());
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ wrong_proof.pop_back();
+
+ wrong_proof.push_back(proof.back());
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ wrong_proof.pop_back();
+
+ // Remove a node from the end.
+ wrong_proof.pop_back();
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+
+ // Add garbage in the beginning of the proof.
+ wrong_proof.clear();
+ wrong_proof.push_back(std::string());
+ wrong_proof.insert(wrong_proof.end(), proof.begin(), proof.end());
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+
+ wrong_proof[0] = proof[0];
+ EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
+ root2, wrong_proof));
+ }
+
protected:
- scoped_refptr<CTLogVerifier> log_;
+ scoped_refptr<const CTLogVerifier> log_;
};
TEST_F(CTLogVerifierTest, VerifiesCertSCT) {
@@ -77,17 +286,29 @@ TEST_F(CTLogVerifierTest, FailsInvalidLogID) {
EXPECT_FALSE(log_->Verify(cert_entry, *cert_sct.get()));
}
-TEST_F(CTLogVerifierTest, SetsValidSTH) {
+TEST_F(CTLogVerifierTest, VerifiesValidSTH) {
ct::SignedTreeHead sth;
- ct::GetSampleSignedTreeHead(&sth);
- ASSERT_TRUE(log_->VerifySignedTreeHead(sth));
+ ASSERT_TRUE(ct::GetSampleSignedTreeHead(&sth));
+ EXPECT_TRUE(log_->VerifySignedTreeHead(sth));
}
-TEST_F(CTLogVerifierTest, DoesNotSetInvalidSTH) {
+TEST_F(CTLogVerifierTest, DoesNotVerifyInvalidSTH) {
ct::SignedTreeHead sth;
- ct::GetSampleSignedTreeHead(&sth);
+ ASSERT_TRUE(ct::GetSampleSignedTreeHead(&sth));
sth.sha256_root_hash[0] = '\x0';
- ASSERT_FALSE(log_->VerifySignedTreeHead(sth));
+ EXPECT_FALSE(log_->VerifySignedTreeHead(sth));
+}
+
+TEST_F(CTLogVerifierTest, VerifiesValidEmptySTH) {
+ ct::SignedTreeHead sth;
+ ASSERT_TRUE(ct::GetSampleEmptySignedTreeHead(&sth));
+ EXPECT_TRUE(log_->VerifySignedTreeHead(sth));
+}
+
+TEST_F(CTLogVerifierTest, DoesNotVerifyInvalidEmptySTH) {
+ ct::SignedTreeHead sth;
+ ASSERT_TRUE(ct::GetBadEmptySignedTreeHead(&sth));
+ EXPECT_FALSE(log_->VerifySignedTreeHead(sth));
}
// Test that excess data after the public key is rejected.
@@ -95,9 +316,197 @@ TEST_F(CTLogVerifierTest, ExcessDataInPublicKey) {
std::string key = ct::GetTestPublicKey();
key += "extra";
- scoped_refptr<CTLogVerifier> log =
+ scoped_refptr<const CTLogVerifier> log =
CTLogVerifier::Create(key, "testlog", "https://ct.example.com");
EXPECT_FALSE(log);
}
+TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_EmptyProof) {
+ std::vector<std::string> empty_proof;
+ std::string root1(GetEmptyTreeHash()), root2(GetEmptyTreeHash());
+
+ // Snapshots that are always consistent, because they are either
+ // from an empty tree to a non-empty one or for trees of the same
+ // size.
+ EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 0, root2, empty_proof));
+ EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 1, root2, empty_proof));
+ EXPECT_TRUE(VerifyConsistencyProof(log_, 1, root1, 1, root2, empty_proof));
+
+ // Invalid consistency proofs.
+ // Time travel to the past.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 0, root2, empty_proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 2, root1, 1, root2, empty_proof));
+ // Proof between two trees of different size can never be empty.
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 2, root2, empty_proof));
+}
+
+TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_MismatchingRoots) {
+ std::vector<std::string> empty_proof;
+ std::string root2;
+ const std::string empty_tree_hash(GetEmptyTreeHash());
+
+ // Roots don't match.
+ EXPECT_FALSE(
+ VerifyConsistencyProof(log_, 0, empty_tree_hash, 0, root2, empty_proof));
+ EXPECT_FALSE(
+ VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, root2, empty_proof));
+}
+
+TEST_F(CTLogVerifierTest,
+ VerifiesConsistencyProofEdgeCases_MatchingRootsNonEmptyProof) {
+ const std::string empty_tree_hash(GetEmptyTreeHash());
+
+ std::vector<std::string> proof;
+ proof.push_back(empty_tree_hash);
+
+ // Roots match and the tree size is either the same or the old tree size is 0,
+ // but the proof is not empty (the verification code should not accept
+ // proofs with redundant nodes in this case).
+ proof.push_back(empty_tree_hash);
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 0,
+ empty_tree_hash, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 1,
+ empty_tree_hash, proof));
+ EXPECT_FALSE(VerifyConsistencyProof(log_, 1, empty_tree_hash, 1,
+ empty_tree_hash, proof));
+}
+
+TEST_F(CTLogVerifierTest, VerifiesValidConsistencyProofs) {
+ std::vector<std::string> proof;
+ std::string root1, root2;
+
+ // Known good proofs.
+ for (size_t i = 0; i < arraysize(kSHA256Proofs); ++i) {
+ proof.clear();
+ for (size_t j = 0; j < kSHA256Proofs[i].proof_length; ++j) {
+ const TestVector& v = kSHA256Proofs[i].proof[j];
+ proof.push_back(HexToBytes(v.str, v.length_bytes));
+ }
+ const uint64_t snapshot1 = kSHA256Proofs[i].snapshot1;
+ const uint64_t snapshot2 = kSHA256Proofs[i].snapshot2;
+ const TestVector& old_root = kSHA256Roots[snapshot1 - 1];
+ const TestVector& new_root = kSHA256Roots[snapshot2 - 1];
+ VerifierConsistencyCheck(
+ snapshot1, snapshot2, HexToBytes(old_root.str, old_root.length_bytes),
+ HexToBytes(new_root.str, new_root.length_bytes), proof);
+ }
+}
+
+const char kLeafPrefix[] = {'\x00'};
+
+// Reference implementation of RFC6962.
+// This allows generation of arbitrary-sized Merkle trees and consistency
+// proofs between them for testing the consistency proof validation
+// code.
+class TreeHasher {
+ public:
+ static std::string HashEmpty() {
+ return HexToBytes(kSHA256EmptyTreeHash.str,
+ kSHA256EmptyTreeHash.length_bytes);
+ }
+
+ static std::string HashLeaf(const std::string& leaf) {
+ SHA256HashValue sha256;
+ memset(sha256.data, 0, sizeof(sha256.data));
+
+ scoped_ptr<crypto::SecureHash> hash(
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+ hash->Update(kLeafPrefix, 1);
+ hash->Update(leaf.data(), leaf.size());
+ hash->Finish(sha256.data, sizeof(sha256.data));
+
+ return std::string(reinterpret_cast<const char*>(sha256.data),
+ sizeof(sha256.data));
+ }
+};
+
+// Reference implementation of Merkle hash, for cross-checking.
+// Recursively calculates the hash of the root given the leaf data
+// specified in |inputs|.
+std::string ReferenceMerkleTreeHash(std::string* inputs, uint64_t input_size) {
+ if (!input_size)
+ return TreeHasher::HashEmpty();
+ if (input_size == 1)
+ return TreeHasher::HashLeaf(inputs[0]);
+
+ const uint64_t split = CalculateNearestPowerOfTwo(input_size);
+
+ return ct::internal::HashNodes(
+ ReferenceMerkleTreeHash(&inputs[0], split),
+ ReferenceMerkleTreeHash(&inputs[split], input_size - split));
+}
+
+// Reference implementation of snapshot consistency. Returns a
+// consistency proof between two snapshots of the tree designated
+// by |inputs|.
+// Call with have_root1 = true.
+std::vector<std::string> ReferenceSnapshotConsistency(std::string* inputs,
+ uint64_t snapshot2,
+ uint64_t snapshot1,
+ bool have_root1) {
+ std::vector<std::string> proof;
+ if (snapshot1 == 0 || snapshot1 > snapshot2)
+ return proof;
+ if (snapshot1 == snapshot2) {
+ // Consistency proof for two equal subtrees is empty.
+ if (!have_root1) {
+ // Record the hash of this subtree unless it's the root for which
+ // the proof was originally requested. (This happens when the snapshot1
+ // tree is balanced.)
+ proof.push_back(ReferenceMerkleTreeHash(inputs, snapshot1));
+ }
+ return proof;
+ }
+
+ // 0 < snapshot1 < snapshot2
+ const uint64_t split = CalculateNearestPowerOfTwo(snapshot2);
+
+ std::vector<std::string> subproof;
+ if (snapshot1 <= split) {
+ // Root of snapshot1 is in the left subtree of snapshot2.
+ // Prove that the left subtrees are consistent.
+ subproof =
+ ReferenceSnapshotConsistency(inputs, split, snapshot1, have_root1);
+ proof.insert(proof.end(), subproof.begin(), subproof.end());
+ // Record the hash of the right subtree (only present in snapshot2).
+ proof.push_back(ReferenceMerkleTreeHash(&inputs[split], snapshot2 - split));
+ } else {
+ // Snapshot1 root is at the same level as snapshot2 root.
+ // Prove that the right subtrees are consistent. The right subtree
+ // doesn't contain the root of snapshot1, so set have_root1 = false.
+ subproof = ReferenceSnapshotConsistency(&inputs[split], snapshot2 - split,
+ snapshot1 - split, false);
+ proof.insert(proof.end(), subproof.begin(), subproof.end());
+ // Record the hash of the left subtree (equal in both trees).
+ proof.push_back(ReferenceMerkleTreeHash(&inputs[0], split));
+ }
+ return proof;
+}
+
+// "brute-force" test generating a tree of 256 entries, generating
+// a consistency proof for each snapshot of each sub-tree up to that
+// size and making sure it verifies.
+TEST_F(CTLogVerifierTest,
+ VerifiesValidConsistencyProofsFromReferenceGenerator) {
+ std::vector<std::string> data;
+ for (int i = 0; i < 256; ++i)
+ data.push_back(std::string(1, i));
+
+ std::vector<std::string> proof;
+ std::string root1, root2;
+ // More tests with reference proof generator.
+ for (size_t tree_size = 1; tree_size <= data.size() / 2; ++tree_size) {
+ root2 = ReferenceMerkleTreeHash(data.data(), tree_size);
+ // Repeat for each snapshot in range.
+ for (size_t snapshot = 1; snapshot <= tree_size; ++snapshot) {
+ proof =
+ ReferenceSnapshotConsistency(data.data(), tree_size, snapshot, true);
+ root1 = ReferenceMerkleTreeHash(data.data(), snapshot);
+ VerifierConsistencyCheck(snapshot, tree_size, root1, root2, proof);
+ }
+ }
+}
+
+} // namespace
+
} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier_util.cc b/chromium/net/cert/ct_log_verifier_util.cc
new file mode 100644
index 00000000000..9e8097f5133
--- /dev/null
+++ b/chromium/net/cert/ct_log_verifier_util.cc
@@ -0,0 +1,36 @@
+// Copyright 2015 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/ct_log_verifier_util.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_util.h"
+#include "crypto/secure_hash.h"
+#include "crypto/sha2.h"
+
+namespace net {
+
+namespace ct {
+
+namespace internal {
+
+std::string HashNodes(const std::string& lh, const std::string& rh) {
+ scoped_ptr<crypto::SecureHash> hash(
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+
+ hash->Update("\01", 1);
+ hash->Update(lh.data(), lh.size());
+ hash->Update(rh.data(), rh.size());
+
+ std::string result;
+ hash->Finish(base::WriteInto(&result, crypto::kSHA256Length + 1),
+ crypto::kSHA256Length);
+ return result;
+}
+
+} // namespace internal
+
+} // namespace ct
+
+} // namespace net
diff --git a/chromium/net/cert/ct_log_verifier_util.h b/chromium/net/cert/ct_log_verifier_util.h
new file mode 100644
index 00000000000..9894afe59ea
--- /dev/null
+++ b/chromium/net/cert/ct_log_verifier_util.h
@@ -0,0 +1,30 @@
+// Copyright 2015 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_CT_LOG_VERIFIER_UTIL_H_
+#define NET_CERT_CT_LOG_VERIFIER_UTIL_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace ct {
+
+namespace internal {
+
+// Hash |lh| and |rh| to produce a node hash according to
+// http://tools.ietf.org/html/rfc6962#section-2.1
+NET_EXPORT std::string HashNodes(const std::string& lh, const std::string& rh);
+
+} // namespace internal
+
+} // namespace ct
+
+} // namespace net
+
+#endif
diff --git a/chromium/net/cert/ct_objects_extractor_nss.cc b/chromium/net/cert/ct_objects_extractor_nss.cc
index b4c1da3dfe6..76a3be51d2e 100644
--- a/chromium/net/cert/ct_objects_extractor_nss.cc
+++ b/chromium/net/cert/ct_objects_extractor_nss.cc
@@ -10,12 +10,15 @@
#include <secoid.h>
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/sha1.h"
#include "crypto/scoped_nss_types.h"
#include "crypto/sha2.h"
#include "net/cert/asn1_util.h"
#include "net/cert/scoped_nss_types.h"
#include "net/cert/signed_certificate_timestamp.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
namespace net {
@@ -147,14 +150,13 @@ bool GetCertOctetStringExtension(CERTCertificate* cert,
if (rv != SECSuccess)
return false;
- base::StringPiece raw_data(reinterpret_cast<char*>(extension.data),
- extension.len);
- base::StringPiece parsed_data;
- if (!asn1::GetElement(&raw_data, asn1::kOCTETSTRING, &parsed_data) ||
- raw_data.size() > 0) { // Decoding failure or raw data left
+ der::Parser parser(der::Input(extension.data, extension.len));
+ der::Input parsed_extension;
+ if (!parser.ReadTag(der::kOctetString, &parsed_extension) ||
+ parser.HasMore()) { // Decoding failure or raw data left
rv = SECFailure;
} else {
- parsed_data.CopyToString(extension_data);
+ *extension_data = parsed_extension.AsString();
}
SECITEM_FreeItem(&extension, PR_FALSE);
diff --git a/chromium/net/cert/ct_objects_extractor_unittest.cc b/chromium/net/cert/ct_objects_extractor_unittest.cc
index 7640e5bdb0d..5bb59ba3db0 100644
--- a/chromium/net/cert/ct_objects_extractor_unittest.cc
+++ b/chromium/net/cert/ct_objects_extractor_unittest.cc
@@ -32,7 +32,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
der_test_cert.length());
log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog",
- "https://ct.example.com").Pass();
+ "https://ct.example.com");
ASSERT_TRUE(log_);
}
@@ -52,7 +52,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
protected:
CertificateList precert_chain_;
scoped_refptr<X509Certificate> test_cert_;
- scoped_refptr<CTLogVerifier> log_;
+ scoped_refptr<const CTLogVerifier> log_;
};
// Test that an SCT can be extracted and the extracted SCT contains the
diff --git a/chromium/net/cert/cert_policy_enforcer.cc b/chromium/net/cert/ct_policy_enforcer.cc
index 070f8691ee6..d9c92421bf8 100644
--- a/chromium/net/cert/cert_policy_enforcer.cc
+++ b/chromium/net/cert/ct_policy_enforcer.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/cert/cert_policy_enforcer.h"
+#include "net/cert/ct_policy_enforcer.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/build_time.h"
@@ -13,9 +14,11 @@
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "base/version.h"
#include "net/cert/ct_ev_whitelist.h"
+#include "net/cert/ct_known_logs.h"
#include "net/cert/ct_verify_result.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/x509_certificate.h"
@@ -43,6 +46,11 @@ bool IsBuildTimely() {
#endif
}
+bool IsGoogleIssuedSCT(
+ const scoped_refptr<ct::SignedCertificateTimestamp>& sct) {
+ return ct::IsLogOperatedByGoogle(sct->log_id);
+}
+
// Returns a rounded-down months difference of |start| and |end|,
// together with an indication of whether the last month was
// a full month, because the range starts specified in the policy
@@ -75,12 +83,10 @@ void RoundedDownMonthDifference(const base::Time& start,
bool HasRequiredNumberOfSCTs(const X509Certificate& cert,
const ct::CTVerifyResult& ct_result) {
- // TODO(eranm): Count the number of *independent* SCTs once the information
- // about log operators is available, crbug.com/425174
size_t num_valid_scts = ct_result.verified_scts.size();
- size_t num_embedded_scts =
+ size_t num_embedded_scts = base::checked_cast<size_t>(
std::count_if(ct_result.verified_scts.begin(),
- ct_result.verified_scts.end(), IsEmbeddedSCT);
+ ct_result.verified_scts.end(), IsEmbeddedSCT));
size_t num_non_embedded_scts = num_valid_scts - num_embedded_scts;
// If at least two valid SCTs were delivered by means other than embedding
@@ -117,10 +123,22 @@ bool HasRequiredNumberOfSCTs(const X509Certificate& cert,
return num_embedded_scts >= num_required_embedded_scts;
}
+// Returns true if |verified_scts| contains SCTs from at least one log that is
+// operated by Google and at least one log that is not operated by Google. This
+// is required for SCTs after July 1st, 2015, as documented at
+// http://dev.chromium.org/Home/chromium-security/root-ca-policy/EVCTPlanMay2015edition.pdf
+bool HasEnoughDiverseSCTs(const ct::SCTList& verified_scts) {
+ size_t num_google_issued_scts = base::checked_cast<size_t>(std::count_if(
+ verified_scts.begin(), verified_scts.end(), IsGoogleIssuedSCT));
+ return (num_google_issued_scts > 0) &&
+ (verified_scts.size() != num_google_issued_scts);
+}
+
enum CTComplianceStatus {
CT_NOT_COMPLIANT = 0,
CT_IN_WHITELIST = 1,
CT_ENOUGH_SCTS = 2,
+ CT_NOT_ENOUGH_DIVERSE_SCTS = 3,
CT_COMPLIANCE_MAX,
};
@@ -135,6 +153,9 @@ const char* ComplianceStatusToString(CTComplianceStatus status) {
case CT_ENOUGH_SCTS:
return "ENOUGH_SCTS";
break;
+ case CT_NOT_ENOUGH_DIVERSE_SCTS:
+ return "NOT_ENOUGH_DIVERSE_SCTS";
+ break;
case CT_COMPLIANCE_MAX:
break;
}
@@ -203,7 +224,24 @@ scoped_ptr<base::Value> NetLogComplianceCheckResultCallback(
details->whitelist_version.GetString());
}
}
- return dict.Pass();
+ return std::move(dict);
+}
+
+// Returns true if all SCTs in |verified_scts| were issued on, or after, the
+// date specified in kDiverseSCTRequirementStartDate
+bool AllSCTsPastDistinctSCTRequirementEnforcementDate(
+ const ct::SCTList& verified_scts) {
+ // The date when diverse SCTs requirement is effective from.
+ // 2015-07-01 00:00:00 UTC.
+ base::Time kDiverseSCTRequirementStartDate =
+ base::Time::FromInternalValue(13080182400000000);
+
+ for (const auto& it : verified_scts) {
+ if (it->timestamp < kDiverseSCTRequirementStartDate)
+ return false;
+ }
+
+ return true;
}
bool IsCertificateInWhitelist(const X509Certificate& cert,
@@ -241,17 +279,24 @@ void CheckCTEVPolicyCompliance(X509Certificate* cert,
return;
}
- if (HasRequiredNumberOfSCTs(*cert, ct_result)) {
- result->status = CT_ENOUGH_SCTS;
+ if (!HasRequiredNumberOfSCTs(*cert, ct_result)) {
+ result->status = CT_NOT_COMPLIANT;
+ return;
+ }
+
+ if (AllSCTsPastDistinctSCTRequirementEnforcementDate(
+ ct_result.verified_scts) &&
+ !HasEnoughDiverseSCTs(ct_result.verified_scts)) {
+ result->status = CT_NOT_ENOUGH_DIVERSE_SCTS;
return;
}
- result->status = CT_NOT_COMPLIANT;
+ result->status = CT_ENOUGH_SCTS;
}
} // namespace
-bool CertPolicyEnforcer::DoesConformToCTEVPolicy(
+bool CTPolicyEnforcer::DoesConformToCTEVPolicy(
X509Certificate* cert,
const ct::EVCertsWhitelist* ev_whitelist,
const ct::CTVerifyResult& ct_result,
diff --git a/chromium/net/cert/cert_policy_enforcer.h b/chromium/net/cert/ct_policy_enforcer.h
index ea24dbd91f1..8c29da5ecb3 100644
--- a/chromium/net/cert/cert_policy_enforcer.h
+++ b/chromium/net/cert/ct_policy_enforcer.h
@@ -1,8 +1,8 @@
// Copyright 2014 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_CERT_POLICY_ENFORCER_H
-#define NET_CERT_CERT_POLICY_ENFORCER_H
+#ifndef NET_CERT_CT_POLICY_ENFORCER_H
+#define NET_CERT_CT_POLICY_ENFORCER_H
#include <stddef.h>
@@ -22,10 +22,10 @@ class X509Certificate;
// Class for checking that a given certificate conforms to security-related
// policies.
-class NET_EXPORT CertPolicyEnforcer {
+class NET_EXPORT CTPolicyEnforcer {
public:
- CertPolicyEnforcer() {}
- virtual ~CertPolicyEnforcer() {}
+ CTPolicyEnforcer() {}
+ virtual ~CTPolicyEnforcer() {}
// Returns true if the collection of SCTs for the given certificate
// conforms with the CT/EV policy. Conformance details are logged to
@@ -41,4 +41,4 @@ class NET_EXPORT CertPolicyEnforcer {
} // namespace net
-#endif // NET_CERT_CERT_POLICY_ENFORCER_H
+#endif // NET_CERT_CT_POLICY_ENFORCER_H
diff --git a/chromium/net/cert/cert_policy_enforcer_unittest.cc b/chromium/net/cert/ct_policy_enforcer_unittest.cc
index bf706dd9b94..43552529333 100644
--- a/chromium/net/cert/cert_policy_enforcer_unittest.cc
+++ b/chromium/net/cert/ct_policy_enforcer_unittest.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/cert/cert_policy_enforcer.h"
+#include "net/cert/ct_policy_enforcer.h"
#include <string>
#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
#include "base/version.h"
+#include "crypto/sha2.h"
#include "net/base/test_data_directory.h"
#include "net/cert/ct_ev_whitelist.h"
#include "net/cert/ct_verify_result.h"
@@ -44,29 +46,72 @@ class DummyEVCertsWhitelist : public ct::EVCertsWhitelist {
bool canned_contains_response_;
};
-class CertPolicyEnforcerTest : public ::testing::Test {
+const char kGoogleAviatorLogID[] =
+ "\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71\x51"
+ "\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\xfb\xc4";
+static_assert(arraysize(kGoogleAviatorLogID) - 1 == crypto::kSHA256Length,
+ "Incorrect log ID length.");
+
+class CTPolicyEnforcerTest : public ::testing::Test {
public:
void SetUp() override {
- policy_enforcer_.reset(new CertPolicyEnforcer);
+ policy_enforcer_.reset(new CTPolicyEnforcer);
std::string der_test_cert(ct::GetDerEncodedX509Cert());
chain_ = X509Certificate::CreateFromBytes(der_test_cert.data(),
der_test_cert.size());
ASSERT_TRUE(chain_.get());
+ google_log_id_ = std::string(kGoogleAviatorLogID, crypto::kSHA256Length);
+ non_google_log_id_.assign(crypto::kSHA256Length, 'A');
}
void FillResultWithSCTsOfOrigin(
ct::SignedCertificateTimestamp::Origin desired_origin,
- int num_scts,
+ size_t num_scts,
+ const std::vector<std::string>& desired_log_keys,
+ bool timestamp_past_enforcement_date,
ct::CTVerifyResult* result) {
- for (int i = 0; i < num_scts; ++i) {
+ for (size_t i = 0; i < num_scts; ++i) {
scoped_refptr<ct::SignedCertificateTimestamp> sct(
new ct::SignedCertificateTimestamp());
sct->origin = desired_origin;
+ if (i < desired_log_keys.size())
+ sct->log_id = desired_log_keys[i];
+ else
+ sct->log_id = non_google_log_id_;
+
+ if (timestamp_past_enforcement_date)
+ sct->timestamp =
+ base::Time::FromUTCExploded({2015, 8, 0, 15, 0, 0, 0, 0});
+ else
+ sct->timestamp =
+ base::Time::FromUTCExploded({2015, 6, 0, 15, 0, 0, 0, 0});
+
result->verified_scts.push_back(sct);
}
}
+ void FillResultWithSCTsOfOrigin(
+ ct::SignedCertificateTimestamp::Origin desired_origin,
+ size_t num_scts,
+ ct::CTVerifyResult* result) {
+ std::vector<std::string> desired_log_ids;
+ desired_log_ids.push_back(google_log_id_);
+ FillResultWithSCTsOfOrigin(desired_origin, num_scts, desired_log_ids, true,
+ result);
+ }
+
+ void FillResultWithRepeatedLogID(const std::string& desired_id,
+ size_t num_scts,
+ bool timestamp_past_enforcement_date,
+ ct::CTVerifyResult* result) {
+ std::vector<std::string> desired_log_ids(num_scts, desired_id);
+
+ FillResultWithSCTsOfOrigin(
+ ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, num_scts,
+ desired_log_ids, timestamp_past_enforcement_date, result);
+ }
+
void CheckCertificateCompliesWithExactNumberOfEmbeddedSCTs(
const base::Time& start,
const base::Time& end,
@@ -74,16 +119,17 @@ class CertPolicyEnforcerTest : public ::testing::Test {
scoped_refptr<X509Certificate> cert(
new X509Certificate("subject", "issuer", start, end));
ct::CTVerifyResult result;
+
for (size_t i = 0; i < required_scts - 1; ++i) {
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED,
- 1, &result);
+ 1, std::vector<std::string>(), false, &result);
EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
cert.get(), nullptr, result, BoundNetLog()))
<< " for: " << (end - start).InDays() << " and " << required_scts
<< " scts=" << result.verified_scts.size() << " i=" << i;
}
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
- &result);
+ std::vector<std::string>(), false, &result);
EXPECT_TRUE(policy_enforcer_->DoesConformToCTEVPolicy(
cert.get(), nullptr, result, BoundNetLog()))
<< " for: " << (end - start).InDays() << " and " << required_scts
@@ -91,11 +137,39 @@ class CertPolicyEnforcerTest : public ::testing::Test {
}
protected:
- scoped_ptr<CertPolicyEnforcer> policy_enforcer_;
+ scoped_ptr<CTPolicyEnforcer> policy_enforcer_;
scoped_refptr<X509Certificate> chain_;
+ std::string google_log_id_;
+ std::string non_google_log_id_;
};
-TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) {
+TEST_F(CTPolicyEnforcerTest,
+ DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle) {
+ ct::CTVerifyResult result;
+ FillResultWithRepeatedLogID(google_log_id_, 2, true, &result);
+
+ EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
+ chain_.get(), nullptr, result, BoundNetLog()));
+}
+
+TEST_F(CTPolicyEnforcerTest,
+ DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllNonGoogle) {
+ ct::CTVerifyResult result;
+ FillResultWithRepeatedLogID(non_google_log_id_, 2, true, &result);
+
+ EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
+ chain_.get(), nullptr, result, BoundNetLog()));
+}
+
+TEST_F(CTPolicyEnforcerTest, ConformsToCTEVPolicyIfSCTBeforeEnforcementDate) {
+ ct::CTVerifyResult result;
+ FillResultWithRepeatedLogID(non_google_log_id_, 2, false, &result);
+
+ EXPECT_TRUE(policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr,
+ result, BoundNetLog()));
+}
+
+TEST_F(CTPolicyEnforcerTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) {
ct::CTVerifyResult result;
FillResultWithSCTsOfOrigin(
ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, 2, &result);
@@ -104,7 +178,7 @@ TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) {
result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithEmbeddedSCTs) {
+TEST_F(CTPolicyEnforcerTest, ConformsToCTEVPolicyWithEmbeddedSCTs) {
// This chain_ is valid for 10 years - over 121 months - so requires 5 SCTs.
ct::CTVerifyResult result;
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 5,
@@ -114,7 +188,7 @@ TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithEmbeddedSCTs) {
result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) {
+TEST_F(CTPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) {
scoped_refptr<ct::EVCertsWhitelist> non_including_whitelist(
new DummyEVCertsWhitelist(true, false));
// This chain_ is valid for 10 years - over 121 months - so requires 5 SCTs.
@@ -134,7 +208,7 @@ TEST_F(CertPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, DoesNotConformToPolicyInvalidDates) {
+TEST_F(CTPolicyEnforcerTest, DoesNotConformToPolicyInvalidDates) {
scoped_refptr<X509Certificate> no_valid_dates_cert(new X509Certificate(
"subject", "issuer", base::Time(), base::Time::Now()));
ct::CTVerifyResult result;
@@ -149,7 +223,7 @@ TEST_F(CertPolicyEnforcerTest, DoesNotConformToPolicyInvalidDates) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest,
+TEST_F(CTPolicyEnforcerTest,
ConformsToPolicyExactNumberOfSCTsForValidityPeriod) {
// Test multiple validity periods
const struct TestData {
@@ -193,7 +267,7 @@ TEST_F(CertPolicyEnforcerTest,
}
}
-TEST_F(CertPolicyEnforcerTest, ConformsToPolicyByEVWhitelistPresence) {
+TEST_F(CTPolicyEnforcerTest, ConformsToPolicyByEVWhitelistPresence) {
scoped_refptr<ct::EVCertsWhitelist> whitelist(
new DummyEVCertsWhitelist(true, true));
@@ -204,7 +278,7 @@ TEST_F(CertPolicyEnforcerTest, ConformsToPolicyByEVWhitelistPresence) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, IgnoresInvalidEVWhitelist) {
+TEST_F(CTPolicyEnforcerTest, IgnoresInvalidEVWhitelist) {
scoped_refptr<ct::EVCertsWhitelist> whitelist(
new DummyEVCertsWhitelist(false, true));
@@ -215,7 +289,7 @@ TEST_F(CertPolicyEnforcerTest, IgnoresInvalidEVWhitelist) {
chain_.get(), whitelist.get(), result, BoundNetLog()));
}
-TEST_F(CertPolicyEnforcerTest, IgnoresNullEVWhitelist) {
+TEST_F(CTPolicyEnforcerTest, IgnoresNullEVWhitelist) {
ct::CTVerifyResult result;
FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
&result);
diff --git a/chromium/net/cert/ct_serialization.cc b/chromium/net/cert/ct_serialization.cc
index 6ea3cedc20f..235d37e65ad 100644
--- a/chromium/net/cert/ct_serialization.cc
+++ b/chromium/net/cert/ct_serialization.cc
@@ -6,6 +6,8 @@
#include <stdint.h>
+#include <limits>
+
#include "base/logging.h"
namespace net {
@@ -360,7 +362,7 @@ bool DecodeSignedCertificateTimestamp(
return false;
}
- if (timestamp > static_cast<uint64_t>(kint64max)) {
+ if (timestamp > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
DVLOG(1) << "Timestamp value too big to cast to int64_t: " << timestamp;
return false;
}
diff --git a/chromium/net/cert/ct_serialization_unittest.cc b/chromium/net/cert/ct_serialization_unittest.cc
index 28ed04c7d18..74cc0e900d8 100644
--- a/chromium/net/cert/ct_serialization_unittest.cc
+++ b/chromium/net/cert/ct_serialization_unittest.cc
@@ -164,7 +164,7 @@ TEST_F(CtSerializationTest, FailsDecodingInvalidSignedCertificateTimestamp) {
TEST_F(CtSerializationTest, EncodesValidSignedTreeHead) {
ct::SignedTreeHead signed_tree_head;
- GetSampleSignedTreeHead(&signed_tree_head);
+ ASSERT_TRUE(GetSampleSignedTreeHead(&signed_tree_head));
std::string encoded;
ct::EncodeTreeHeadSignature(signed_tree_head, &encoded);
diff --git a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
index 01efa0ab7d5..042f59fa16b 100644
--- a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
+++ b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <string>
+#include <utility>
#include "base/base64.h"
#include "base/strings/string_number_conversions.h"
@@ -139,7 +140,7 @@ scoped_ptr<base::Value> NetLogSignedCertificateTimestampCallback(
dict->Set("unknown_logs_scts",
SCTListToPrintableValues(ct_result->unknown_logs_scts));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogRawSignedCertificateTimestampCallback(
@@ -154,7 +155,7 @@ scoped_ptr<base::Value> NetLogRawSignedCertificateTimestampCallback(
SetBinaryData("scts_from_tls_extension", *sct_list_from_tls_extension,
dict.get());
- return dict.Pass();
+ return std::move(dict);
}
} // namespace net
diff --git a/chromium/net/cert/ct_verifier.h b/chromium/net/cert/ct_verifier.h
index 40631048ac3..46a811a7960 100644
--- a/chromium/net/cert/ct_verifier.h
+++ b/chromium/net/cert/ct_verifier.h
@@ -21,6 +21,7 @@ class CTLogVerifier;
class X509Certificate;
// Interface for verifying Signed Certificate Timestamps over a certificate.
+// The only known (non-test) implementation currently is MultiLogCTVerifier.
class NET_EXPORT CTVerifier {
public:
class NET_EXPORT Observer {
@@ -30,6 +31,8 @@ class NET_EXPORT CTVerifier {
// Signed Certificate Timestamp, |cert| is the certificate it applies to.
// The certificate is needed to calculate the hash of the log entry,
// necessary for checking inclusion in the log.
+ // Note: The observer (whose implementation is expected to exist outside
+ // net/) may store the observed |cert| and |sct|.
virtual void OnSCTVerified(X509Certificate* cert,
const ct::SignedCertificateTimestamp* sct) = 0;
};
diff --git a/chromium/net/cert/ev_root_ca_metadata.cc b/chromium/net/cert/ev_root_ca_metadata.cc
index 8dd55f4e8c4..a5ac6e2231e 100644
--- a/chromium/net/cert/ev_root_ca_metadata.cc
+++ b/chromium/net/cert/ev_root_ca_metadata.cc
@@ -443,11 +443,6 @@ static const EVMetadata ev_root_ca_metadata[] = {
0x6c, 0x51, 0xf7, 0x0e, 0xe9, 0x0d, 0xda, 0xb9, 0xad, 0x8e } },
{"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
},
- // UTN - DATACorp SGC
- { { { 0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd,
- 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4 } },
- {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
- },
// UTN-USERFirst-Hardware
{ { { 0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87,
0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7 } },
diff --git a/chromium/net/cert/ev_root_ca_metadata.h b/chromium/net/cert/ev_root_ca_metadata.h
index 10227a2536c..508e188b132 100644
--- a/chromium/net/cert/ev_root_ca_metadata.h
+++ b/chromium/net/cert/ev_root_ca_metadata.h
@@ -16,6 +16,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
diff --git a/chromium/net/cert/internal/certificate_policies.cc b/chromium/net/cert/internal/certificate_policies.cc
new file mode 100644
index 00000000000..4ff3a3a6595
--- /dev/null
+++ b/chromium/net/cert/internal/certificate_policies.cc
@@ -0,0 +1,178 @@
+// Copyright 2015 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 <algorithm>
+
+#include "net/cert/internal/certificate_policies.h"
+
+#include "net/der/input.h"
+#include "net/der/parser.h"
+#include "net/der/tag.h"
+
+namespace net {
+
+namespace {
+
+// -- policyQualifierIds for Internet policy qualifiers
+//
+// id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+// id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+//
+// In dotted decimal form: 1.3.6.1.5.5.7.2.1
+const der::Input CpsPointerId() {
+ static const uint8_t cps_pointer_id[] = {0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x01};
+ return der::Input(cps_pointer_id);
+}
+
+// id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+//
+// In dotted decimal form: 1.3.6.1.5.5.7.2.2
+const der::Input UserNoticeId() {
+ static const uint8_t user_notice_id[] = {0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x02};
+ return der::Input(user_notice_id);
+}
+
+// Ignores the policyQualifiers, but does some minimal correctness checking.
+// TODO(mattm): parse and return the policyQualifiers, since the cert viewer
+// still needs to display them.
+bool ParsePolicyQualifiers(const der::Input& policy_oid,
+ der::Parser* policy_qualifiers_sequence_parser) {
+ // If it is present, the policyQualifiers sequence should have at least 1
+ // element.
+ if (!policy_qualifiers_sequence_parser->HasMore())
+ return false;
+ while (policy_qualifiers_sequence_parser->HasMore()) {
+ der::Parser policy_information_parser;
+ if (!policy_qualifiers_sequence_parser->ReadSequence(
+ &policy_information_parser)) {
+ return false;
+ }
+ der::Input qualifier_oid;
+ if (!policy_information_parser.ReadTag(der::kOid, &qualifier_oid))
+ return false;
+ // RFC 5280 section 4.2.1.4: When qualifiers are used with the special
+ // policy anyPolicy, they MUST be limited to the qualifiers identified in
+ // this section.
+ if (policy_oid.Equals(AnyPolicy()) &&
+ !qualifier_oid.Equals(CpsPointerId()) &&
+ !qualifier_oid.Equals(UserNoticeId())) {
+ return false;
+ }
+ der::Tag tag;
+ der::Input value;
+ if (!policy_information_parser.ReadTagAndValue(&tag, &value))
+ return false;
+ // Should not have trailing data after qualifier.
+ if (policy_information_parser.HasMore())
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+const der::Input AnyPolicy() {
+ // id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
+ //
+ // id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+ //
+ // anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
+ //
+ // In dotted decimal form: 2.5.29.32.0
+ static const uint8_t any_policy[] = {0x55, 0x1D, 0x20, 0x00};
+ return der::Input(any_policy);
+}
+
+// RFC 5280 section 4.2.1.4. Certificate Policies:
+//
+// certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+//
+// PolicyInformation ::= SEQUENCE {
+// policyIdentifier CertPolicyId,
+// policyQualifiers SEQUENCE SIZE (1..MAX) OF
+// PolicyQualifierInfo OPTIONAL }
+//
+// CertPolicyId ::= OBJECT IDENTIFIER
+//
+// PolicyQualifierInfo ::= SEQUENCE {
+// policyQualifierId PolicyQualifierId,
+// qualifier ANY DEFINED BY policyQualifierId }
+//
+// PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+//
+// Qualifier ::= CHOICE {
+// cPSuri CPSuri,
+// userNotice UserNotice }
+//
+// CPSuri ::= IA5String
+//
+// UserNotice ::= SEQUENCE {
+// noticeRef NoticeReference OPTIONAL,
+// explicitText DisplayText OPTIONAL }
+//
+// NoticeReference ::= SEQUENCE {
+// organization DisplayText,
+// noticeNumbers SEQUENCE OF INTEGER }
+//
+// DisplayText ::= CHOICE {
+// ia5String IA5String (SIZE (1..200)),
+// visibleString VisibleString (SIZE (1..200)),
+// bmpString BMPString (SIZE (1..200)),
+// utf8String UTF8String (SIZE (1..200)) }
+bool ParseCertificatePoliciesExtension(const der::Input& extension_value,
+ std::vector<der::Input>* policies) {
+ der::Parser extension_parser(extension_value);
+ der::Parser policies_sequence_parser;
+ if (!extension_parser.ReadSequence(&policies_sequence_parser))
+ return false;
+ // Should not have trailing data after certificatePolicies sequence.
+ if (extension_parser.HasMore())
+ return false;
+ // The certificatePolicies sequence should have at least 1 element.
+ if (!policies_sequence_parser.HasMore())
+ return false;
+
+ policies->clear();
+
+ while (policies_sequence_parser.HasMore()) {
+ der::Parser policy_information_parser;
+ if (!policies_sequence_parser.ReadSequence(&policy_information_parser))
+ return false;
+ der::Input policy_oid;
+ if (!policy_information_parser.ReadTag(der::kOid, &policy_oid))
+ return false;
+
+ // Build the |policies| vector in sorted order (sorted on DER encoded policy
+ // OID). Use a binary search to check whether a duplicate policy is present,
+ // and if not, where to insert the policy to maintain the sorted order.
+ std::vector<der::Input>::iterator i =
+ std::lower_bound(policies->begin(), policies->end(), policy_oid);
+ // RFC 5280 section 4.2.1.4: A certificate policy OID MUST NOT appear more
+ // than once in a certificate policies extension.
+ if (i != policies->end() && i->Equals(policy_oid))
+ return false;
+
+ policies->insert(i, policy_oid);
+
+ if (!policy_information_parser.HasMore())
+ continue;
+
+ der::Parser policy_qualifiers_sequence_parser;
+ if (!policy_information_parser.ReadSequence(
+ &policy_qualifiers_sequence_parser)) {
+ return false;
+ }
+ // Should not have trailing data after policyQualifiers sequence.
+ if (policy_information_parser.HasMore())
+ return false;
+ if (!ParsePolicyQualifiers(policy_oid, &policy_qualifiers_sequence_parser))
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/certificate_policies.h b/chromium/net/cert/internal/certificate_policies.h
new file mode 100644
index 00000000000..e2ac13fd4e0
--- /dev/null
+++ b/chromium/net/cert/internal/certificate_policies.h
@@ -0,0 +1,36 @@
+// Copyright 2015 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_INTERNAL_CERTIFICATE_POLICIES_H_
+#define NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_
+
+#include <vector>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace der {
+class Input;
+} // namespace der
+
+// Returns the DER-encoded OID, without tag or length, of the anyPolicy
+// certificate policy defined in RFC 5280 section 4.2.1.4.
+NET_EXPORT const der::Input AnyPolicy();
+
+// Parses a certificatePolicies extension and stores the policy OIDs in
+// |*policies|, in sorted order. If policyQualifiers are present,
+// they are ignored. (RFC 5280 section 4.2.1.4 says "optional qualifiers, which
+// MAY be present, are not expected to change the definition of the policy.",
+// furthermore policyQualifiers do not affect the success or failure of the
+// section 6 Certification Path Validation algorithm.)
+//
+// The returned values is only valid as long as |extension_value| is.
+NET_EXPORT bool ParseCertificatePoliciesExtension(
+ const der::Input& extension_value,
+ std::vector<der::Input>* policies);
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_
diff --git a/chromium/net/cert/internal/certificate_policies_unittest.cc b/chromium/net/cert/internal/certificate_policies_unittest.cc
new file mode 100644
index 00000000000..71137cb1f3e
--- /dev/null
+++ b/chromium/net/cert/internal/certificate_policies_unittest.cc
@@ -0,0 +1,150 @@
+// Copyright 2015 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/internal/certificate_policies.h"
+
+#include "net/cert/internal/test_helpers.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+::testing::AssertionResult LoadTestData(const std::string& name,
+ std::string* result) {
+ std::string path = "net/data/certificate_policies_unittest/" + name;
+
+ const PemBlockMapping mappings[] = {
+ {"CERTIFICATE POLICIES", result},
+ };
+
+ return ReadTestDataFromPemFile(path, mappings);
+}
+
+const uint8_t policy_1_2_3_der[] = {0x2A, 0x03};
+const uint8_t policy_1_2_4_der[] = {0x2A, 0x04};
+
+} // namespace
+
+TEST(ParseCertificatePoliciesTest, InvalidEmpty) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("invalid-empty.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidIdentifierNotOid) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("invalid-policy_identifier_not_oid.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, AnyPolicy) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("anypolicy.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(AnyPolicy(), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, AnyPolicyWithQualifier) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("anypolicy_with_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(AnyPolicy(), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidAnyPolicyWithCustomQualifier) {
+ std::string der;
+ ASSERT_TRUE(
+ LoadTestData("invalid-anypolicy_with_custom_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, OnePolicy) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, OnePolicyWithQualifier) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_with_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, OnePolicyWithCustomQualifier) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_with_custom_qualifier.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(1U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidPolicyWithDuplicatePolicyOid) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("invalid-policy_1_2_3_dupe.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidPolicyWithEmptyQualifiersSequence) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData(
+ "invalid-policy_1_2_3_with_empty_qualifiers_sequence.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, InvalidPolicyInformationHasUnconsumedData) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData(
+ "invalid-policy_1_2_3_policyinformation_unconsumed_data.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest,
+ InvalidPolicyQualifierInfoHasUnconsumedData) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData(
+ "invalid-policy_1_2_3_policyqualifierinfo_unconsumed_data.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_FALSE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+}
+
+TEST(ParseCertificatePoliciesTest, TwoPolicies) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_and_1_2_4.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(2U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+ EXPECT_EQ(der::Input(policy_1_2_4_der), policies[1]);
+}
+
+TEST(ParseCertificatePoliciesTest, TwoPoliciesWithQualifiers) {
+ std::string der;
+ ASSERT_TRUE(LoadTestData("policy_1_2_3_and_1_2_4_with_qualifiers.pem", &der));
+ std::vector<der::Input> policies;
+ EXPECT_TRUE(ParseCertificatePoliciesExtension(der::Input(&der), &policies));
+ ASSERT_EQ(2U, policies.size());
+ EXPECT_EQ(der::Input(policy_1_2_3_der), policies[0]);
+ EXPECT_EQ(der::Input(policy_1_2_4_der), policies[1]);
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/name_constraints.cc b/chromium/net/cert/internal/name_constraints.cc
new file mode 100644
index 00000000000..ade43a776ee
--- /dev/null
+++ b/chromium/net/cert/internal/name_constraints.cc
@@ -0,0 +1,569 @@
+// Copyright 2015 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/internal/name_constraints.h"
+
+#include <limits.h>
+
+#include "base/strings/string_util.h"
+#include "net/cert/internal/verify_name_match.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+#include "net/der/tag.h"
+
+namespace net {
+
+namespace {
+
+// The name types of GeneralName that are fully supported in name constraints.
+//
+// (The other types will have the minimal checking described by RFC 5280
+// section 4.2.1.10: If a name constraints extension that is marked as critical
+// imposes constraints on a particular name form, and an instance of
+// that name form appears in the subject field or subjectAltName
+// extension of a subsequent certificate, then the application MUST
+// either process the constraint or reject the certificate.)
+const int kSupportedNameTypes = GENERAL_NAME_DNS_NAME |
+ GENERAL_NAME_DIRECTORY_NAME |
+ GENERAL_NAME_IP_ADDRESS;
+
+// Controls wildcard handling of DNSNameMatches.
+// If WildcardMatchType is WILDCARD_PARTIAL_MATCH "*.bar.com" is considered to
+// match the constraint "foo.bar.com". If it is WILDCARD_FULL_MATCH, "*.bar.com"
+// will match "bar.com" but not "foo.bar.com".
+enum WildcardMatchType { WILDCARD_PARTIAL_MATCH, WILDCARD_FULL_MATCH };
+
+// Returns true if |name| falls in the subtree defined by |dns_constraint|.
+// RFC 5280 section 4.2.1.10:
+// DNS name restrictions are expressed as host.example.com. Any DNS
+// name that can be constructed by simply adding zero or more labels
+// to the left-hand side of the name satisfies the name constraint. For
+// example, www.host.example.com would satisfy the constraint but
+// host1.example.com would not.
+//
+// |wildcard_matching| controls handling of wildcard names (|name| starts with
+// "*."). Wildcard handling is not specified by RFC 5280, but certificate
+// verification allows it, name constraints must check it similarly.
+bool DNSNameMatches(base::StringPiece name,
+ base::StringPiece dns_constraint,
+ WildcardMatchType wildcard_matching) {
+ // Everything matches the empty DNS name constraint.
+ if (dns_constraint.empty())
+ return true;
+
+ // Normalize absolute DNS names by removing the trailing dot, if any.
+ if (!name.empty() && *name.rbegin() == '.')
+ name.remove_suffix(1);
+ if (!dns_constraint.empty() && *dns_constraint.rbegin() == '.')
+ dns_constraint.remove_suffix(1);
+
+ // Wildcard partial-match handling ("*.bar.com" matching name constraint
+ // "foo.bar.com"). This only handles the case where the the dnsname and the
+ // constraint match after removing the leftmost label, otherwise it is handled
+ // by falling through to the check of whether the dnsname is fully within or
+ // fully outside of the constraint.
+ if (wildcard_matching == WILDCARD_PARTIAL_MATCH && name.size() > 2 &&
+ name[0] == '*' && name[1] == '.') {
+ size_t dns_constraint_dot_pos = dns_constraint.find('.');
+ if (dns_constraint_dot_pos != std::string::npos) {
+ base::StringPiece dns_constraint_domain(
+ dns_constraint.begin() + dns_constraint_dot_pos + 1,
+ dns_constraint.size() - dns_constraint_dot_pos - 1);
+ base::StringPiece wildcard_domain(name.begin() + 2, name.size() - 2);
+ if (base::EqualsCaseInsensitiveASCII(wildcard_domain,
+ dns_constraint_domain)) {
+ return true;
+ }
+ }
+ }
+
+ if (!base::EndsWith(name, dns_constraint,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return false;
+ }
+ // Exact match.
+ if (name.size() == dns_constraint.size())
+ return true;
+ // Subtree match.
+ if (name.size() > dns_constraint.size() &&
+ name[name.size() - dns_constraint.size() - 1] == '.') {
+ return true;
+ }
+ // Trailing text matches, but not in a subtree (e.g., "foobar.com" is not a
+ // match for "bar.com").
+ return false;
+}
+
+// Return true if the bitmask |mask| contains only zeros after the first
+// |prefix_length| bits.
+bool IsSuffixZero(const std::vector<uint8_t>& mask, unsigned prefix_length) {
+ size_t zero_bits = mask.size() * CHAR_BIT - prefix_length;
+ size_t zero_bytes = zero_bits / CHAR_BIT;
+ std::vector<uint8_t> zeros(zero_bytes, 0);
+ if (memcmp(zeros.data(), mask.data() + mask.size() - zero_bytes, zero_bytes))
+ return false;
+ size_t leftover_bits = zero_bits % CHAR_BIT;
+ if (leftover_bits) {
+ uint8_t b = mask[mask.size() - zero_bytes - 1];
+ for (size_t i = 0; i < leftover_bits; ++i) {
+ if (b & (1 << i))
+ return false;
+ }
+ }
+ return true;
+}
+
+// Controls handling of unsupported name types in ParseGeneralName. (Unsupported
+// types are those not in kSupportedNameTypes.)
+// RECORD_UNSUPPORTED causes unsupported types to be recorded in
+// |present_name_types|.
+// IGNORE_UNSUPPORTED causes unsupported types to not be recorded.
+enum ParseGeneralNameUnsupportedTypeBehavior {
+ RECORD_UNSUPPORTED,
+ IGNORE_UNSUPPORTED,
+};
+
+// Controls parsing of iPAddress names in ParseGeneralName.
+// IP_ADDRESS_ONLY parses the iPAddress names as a 4 or 16 byte IP address.
+// IP_ADDRESS_AND_NETMASK parses the iPAddress names as 8 or 32 bytes containing
+// an IP address followed by a netmask.
+enum ParseGeneralNameIPAddressType {
+ IP_ADDRESS_ONLY,
+ IP_ADDRESS_AND_NETMASK,
+};
+
+// Parses a GeneralName value and adds it to |subtrees|.
+WARN_UNUSED_RESULT bool ParseGeneralName(
+ const der::Input& input,
+ ParseGeneralNameUnsupportedTypeBehavior unsupported_type_behavior,
+ ParseGeneralNameIPAddressType ip_address_type,
+ NameConstraints::GeneralNames* subtrees) {
+ der::Parser parser(input);
+ der::Tag tag;
+ der::Input value;
+ if (!parser.ReadTagAndValue(&tag, &value))
+ return false;
+ if (!der::IsContextSpecific(tag))
+ return false;
+ GeneralNameTypes name_type = GENERAL_NAME_NONE;
+ // GeneralName ::= CHOICE {
+ switch (der::GetTagNumber(tag)) {
+ // otherName [0] OtherName,
+ case 0:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_OTHER_NAME;
+ break;
+ // rfc822Name [1] IA5String,
+ case 1:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_RFC822_NAME;
+ break;
+ // dNSName [2] IA5String,
+ case 2: {
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_DNS_NAME;
+ const std::string s = value.AsString();
+ if (!base::IsStringASCII(s))
+ return false;
+ subtrees->dns_names.push_back(s);
+ break;
+ }
+ // x400Address [3] ORAddress,
+ case 3:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_X400_ADDRESS;
+ break;
+ // directoryName [4] Name,
+ case 4:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_DIRECTORY_NAME;
+ subtrees->directory_names.push_back(std::vector<uint8_t>(
+ value.UnsafeData(), value.UnsafeData() + value.Length()));
+ break;
+ // ediPartyName [5] EDIPartyName,
+ case 5:
+ if (!der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_EDI_PARTY_NAME;
+ break;
+ // uniformResourceIdentifier [6] IA5String,
+ case 6:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER;
+ break;
+ // iPAddress [7] OCTET STRING,
+ case 7:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_IP_ADDRESS;
+ if (ip_address_type == IP_ADDRESS_ONLY) {
+ // RFC 5280 section 4.2.1.6:
+ // When the subjectAltName extension contains an iPAddress, the address
+ // MUST be stored in the octet string in "network byte order", as
+ // specified in [RFC791]. The least significant bit (LSB) of each octet
+ // is the LSB of the corresponding byte in the network address. For IP
+ // version 4, as specified in [RFC791], the octet string MUST contain
+ // exactly four octets. For IP version 6, as specified in [RFC2460],
+ // the octet string MUST contain exactly sixteen octets.
+ if ((value.Length() != kIPv4AddressSize &&
+ value.Length() != kIPv6AddressSize)) {
+ return false;
+ }
+ subtrees->ip_addresses.push_back(std::vector<uint8_t>(
+ value.UnsafeData(), value.UnsafeData() + value.Length()));
+ } else {
+ DCHECK_EQ(ip_address_type, IP_ADDRESS_AND_NETMASK);
+ // RFC 5280 section 4.2.1.10:
+ // The syntax of iPAddress MUST be as described in Section 4.2.1.6 with
+ // the following additions specifically for name constraints. For IPv4
+ // addresses, the iPAddress field of GeneralName MUST contain eight (8)
+ // octets, encoded in the style of RFC 4632 (CIDR) to represent an
+ // address range [RFC4632]. For IPv6 addresses, the iPAddress field
+ // MUST contain 32 octets similarly encoded. For example, a name
+ // constraint for "class C" subnet 192.0.2.0 is represented as the
+ // octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
+ // 192.0.2.0/24 (mask 255.255.255.0).
+ if (value.Length() != kIPv4AddressSize * 2 &&
+ value.Length() != kIPv6AddressSize * 2) {
+ return false;
+ }
+ const std::vector<uint8_t> mask(value.UnsafeData() + value.Length() / 2,
+ value.UnsafeData() + value.Length());
+ const unsigned mask_prefix_length = MaskPrefixLength(mask);
+ if (!IsSuffixZero(mask, mask_prefix_length))
+ return false;
+ subtrees->ip_address_ranges.push_back(std::make_pair(
+ std::vector<uint8_t>(value.UnsafeData(),
+ value.UnsafeData() + value.Length() / 2),
+ mask_prefix_length));
+ }
+ break;
+ // registeredID [8] OBJECT IDENTIFIER }
+ case 8:
+ if (der::IsConstructed(tag))
+ return false;
+ name_type = GENERAL_NAME_REGISTERED_ID;
+ break;
+ default:
+ return false;
+ }
+ DCHECK_NE(GENERAL_NAME_NONE, name_type);
+ if ((name_type & kSupportedNameTypes) ||
+ unsupported_type_behavior == RECORD_UNSUPPORTED) {
+ subtrees->present_name_types |= name_type;
+ }
+ return true;
+}
+
+// Parses a GeneralSubtrees |value| and store the contents in |subtrees|.
+// The individual values stored into |subtrees| are not validated by this
+// function.
+// NOTE: |subtrees| will be modified regardless of the return.
+WARN_UNUSED_RESULT bool ParseGeneralSubtrees(
+ const der::Input& value,
+ bool is_critical,
+ NameConstraints::GeneralNames* subtrees) {
+ // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+ //
+ // GeneralSubtree ::= SEQUENCE {
+ // base GeneralName,
+ // minimum [0] BaseDistance DEFAULT 0,
+ // maximum [1] BaseDistance OPTIONAL }
+ //
+ // BaseDistance ::= INTEGER (0..MAX)
+ der::Parser sequence_parser(value);
+ // The GeneralSubtrees sequence should have at least 1 element.
+ if (!sequence_parser.HasMore())
+ return false;
+ while (sequence_parser.HasMore()) {
+ der::Parser subtree_sequence;
+ if (!sequence_parser.ReadSequence(&subtree_sequence))
+ return false;
+
+ der::Input raw_general_name;
+ if (!subtree_sequence.ReadRawTLV(&raw_general_name))
+ return false;
+
+ if (!ParseGeneralName(raw_general_name,
+ is_critical ? RECORD_UNSUPPORTED : IGNORE_UNSUPPORTED,
+ IP_ADDRESS_AND_NETMASK, subtrees)) {
+ return false;
+ }
+
+ // RFC 5280 section 4.2.1.10:
+ // Within this profile, the minimum and maximum fields are not used with any
+ // name forms, thus, the minimum MUST be zero, and maximum MUST be absent.
+ // However, if an application encounters a critical name constraints
+ // extension that specifies other values for minimum or maximum for a name
+ // form that appears in a subsequent certificate, the application MUST
+ // either process these fields or reject the certificate.
+
+ // Note that technically failing here isn't required: rather only need to
+ // fail if a name of this type actually appears in a subsequent cert and
+ // this extension was marked critical. However the minimum and maximum
+ // fields appear uncommon enough that implementing that isn't useful.
+ if (subtree_sequence.HasMore())
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+NameConstraints::GeneralNames::GeneralNames() {}
+
+NameConstraints::GeneralNames::~GeneralNames() {}
+
+NameConstraints::~NameConstraints() {}
+
+// static
+scoped_ptr<NameConstraints> NameConstraints::CreateFromDer(
+ const der::Input& extension_value,
+ bool is_critical) {
+ scoped_ptr<NameConstraints> name_constraints(new NameConstraints());
+ if (!name_constraints->Parse(extension_value, is_critical))
+ return nullptr;
+ return name_constraints;
+}
+
+bool NameConstraints::Parse(const der::Input& extension_value,
+ bool is_critical) {
+ der::Parser extension_parser(extension_value);
+ der::Parser sequence_parser;
+
+ // NameConstraints ::= SEQUENCE {
+ // permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ // excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+ if (!extension_parser.ReadSequence(&sequence_parser))
+ return false;
+ if (extension_parser.HasMore())
+ return false;
+
+ bool had_permitted_subtrees = false;
+ der::Input permitted_subtrees_value;
+ if (!sequence_parser.ReadOptionalTag(der::ContextSpecificConstructed(0),
+ &permitted_subtrees_value,
+ &had_permitted_subtrees)) {
+ return false;
+ }
+ if (had_permitted_subtrees &&
+ !ParseGeneralSubtrees(permitted_subtrees_value, is_critical,
+ &permitted_subtrees_)) {
+ return false;
+ }
+
+ bool had_excluded_subtrees = false;
+ der::Input excluded_subtrees_value;
+ if (!sequence_parser.ReadOptionalTag(der::ContextSpecificConstructed(1),
+ &excluded_subtrees_value,
+ &had_excluded_subtrees)) {
+ return false;
+ }
+ if (had_excluded_subtrees &&
+ !ParseGeneralSubtrees(excluded_subtrees_value, is_critical,
+ &excluded_subtrees_)) {
+ return false;
+ }
+
+ // RFC 5280 section 4.2.1.10:
+ // Conforming CAs MUST NOT issue certificates where name constraints is an
+ // empty sequence. That is, either the permittedSubtrees field or the
+ // excludedSubtrees MUST be present.
+ if (!had_permitted_subtrees && !had_excluded_subtrees)
+ return false;
+
+ if (sequence_parser.HasMore())
+ return false;
+
+ return true;
+}
+
+bool NameConstraints::IsPermittedCert(
+ const der::Input& subject_rdn_sequence,
+ const der::Input& subject_alt_name_extnvalue_tlv) const {
+ // Subject Alternative Name handling:
+ //
+ // RFC 5280 section 4.2.1.6:
+ // id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+ //
+ // SubjectAltName ::= GeneralNames
+ //
+ // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+ GeneralNames san_names;
+ if (subject_alt_name_extnvalue_tlv.Length()) {
+ der::Parser extnvalue_parser(subject_alt_name_extnvalue_tlv);
+ der::Input subject_alt_name_tlv;
+ if (!extnvalue_parser.ReadTag(der::kOctetString, &subject_alt_name_tlv))
+ return false;
+
+ der::Parser subject_alt_name_parser(subject_alt_name_tlv);
+ der::Parser san_sequence_parser;
+ if (!subject_alt_name_parser.ReadSequence(&san_sequence_parser))
+ return false;
+ // Should not have trailing data after subjectAltName sequence.
+ if (subject_alt_name_parser.HasMore())
+ return false;
+ // The subjectAltName sequence should have at least 1 element.
+ if (!san_sequence_parser.HasMore())
+ return false;
+
+ while (san_sequence_parser.HasMore()) {
+ der::Input raw_general_name;
+ if (!san_sequence_parser.ReadRawTLV(&raw_general_name))
+ return false;
+
+ if (!ParseGeneralName(raw_general_name, RECORD_UNSUPPORTED,
+ IP_ADDRESS_ONLY, &san_names))
+ return false;
+ }
+
+ // Check unsupported name types:
+ // ConstrainedNameTypes for the unsupported types will only be true if that
+ // type of name was present in a name constraint that was marked critical.
+ //
+ // RFC 5280 section 4.2.1.10:
+ // If a name constraints extension that is marked as critical
+ // imposes constraints on a particular name form, and an instance of
+ // that name form appears in the subject field or subjectAltName
+ // extension of a subsequent certificate, then the application MUST
+ // either process the constraint or reject the certificate.
+ if (ConstrainedNameTypes() & san_names.present_name_types &
+ ~kSupportedNameTypes) {
+ return false;
+ }
+
+ // Check supported name types:
+ for (const auto& dns_name : san_names.dns_names) {
+ if (!IsPermittedDNSName(dns_name))
+ return false;
+ }
+
+ for (const auto& directory_name : san_names.directory_names) {
+ if (!IsPermittedDirectoryName(
+ der::Input(directory_name.data(), directory_name.size()))) {
+ return false;
+ }
+ }
+
+ for (const auto& ip_address : san_names.ip_addresses) {
+ if (!IsPermittedIP(ip_address))
+ return false;
+ }
+ }
+
+ // Subject handling:
+
+ // RFC 5280 section 4.2.1.10:
+ // Legacy implementations exist where an electronic mail address is embedded
+ // in the subject distinguished name in an attribute of type emailAddress
+ // (Section 4.1.2.6). When constraints are imposed on the rfc822Name name
+ // form, but the certificate does not include a subject alternative name, the
+ // rfc822Name constraint MUST be applied to the attribute of type emailAddress
+ // in the subject distinguished name.
+ if (!subject_alt_name_extnvalue_tlv.Length() &&
+ (ConstrainedNameTypes() & GENERAL_NAME_RFC822_NAME)) {
+ bool contained_email_address = false;
+ if (!NameContainsEmailAddress(subject_rdn_sequence,
+ &contained_email_address)) {
+ return false;
+ }
+ if (contained_email_address)
+ return false;
+ }
+
+ // RFC 5280 4.1.2.6:
+ // If subject naming information is present only in the subjectAltName
+ // extension (e.g., a key bound only to an email address or URI), then the
+ // subject name MUST be an empty sequence and the subjectAltName extension
+ // MUST be critical.
+ // This code assumes that criticality condition is checked by the caller, and
+ // therefore only needs to avoid the IsPermittedDirectoryName check against an
+ // empty subject in such a case.
+ if (subject_alt_name_extnvalue_tlv.Length() &&
+ subject_rdn_sequence.Length() == 0) {
+ return true;
+ }
+
+ return IsPermittedDirectoryName(subject_rdn_sequence);
+}
+
+bool NameConstraints::IsPermittedDNSName(const std::string& name) const {
+ // If there are no name constraints for DNS names, all names are accepted.
+ if (!(ConstrainedNameTypes() & GENERAL_NAME_DNS_NAME))
+ return true;
+
+ for (const std::string& excluded_name : excluded_subtrees_.dns_names) {
+ // When matching wildcard hosts against excluded subtrees, consider it a
+ // match if the constraint would match any expansion of the wildcard. Eg,
+ // *.bar.com should match a constraint of foo.bar.com.
+ if (DNSNameMatches(name, excluded_name, WILDCARD_PARTIAL_MATCH))
+ return false;
+ }
+ for (const std::string& permitted_name : permitted_subtrees_.dns_names) {
+ // When matching wildcard hosts against permitted subtrees, consider it a
+ // match only if the constraint would match all expansions of the wildcard.
+ // Eg, *.bar.com should match a constraint of bar.com, but not foo.bar.com.
+ if (DNSNameMatches(name, permitted_name, WILDCARD_FULL_MATCH))
+ return true;
+ }
+
+ return false;
+}
+
+bool NameConstraints::IsPermittedDirectoryName(
+ const der::Input& name_rdn_sequence) const {
+ // If there are no name constraints for directory names, all names are
+ // accepted.
+ if (!(ConstrainedNameTypes() & GENERAL_NAME_DIRECTORY_NAME))
+ return true;
+
+ for (const auto& excluded_name : excluded_subtrees_.directory_names) {
+ if (VerifyNameInSubtree(
+ name_rdn_sequence,
+ der::Input(excluded_name.data(), excluded_name.size()))) {
+ return false;
+ }
+ }
+ for (const auto& permitted_name : permitted_subtrees_.directory_names) {
+ if (VerifyNameInSubtree(
+ name_rdn_sequence,
+ der::Input(permitted_name.data(), permitted_name.size()))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool NameConstraints::IsPermittedIP(const IPAddressNumber& ip) const {
+ // If there are no name constraints for IP Address names, all names are
+ // accepted.
+ if (!(ConstrainedNameTypes() & GENERAL_NAME_IP_ADDRESS))
+ return true;
+
+ for (const auto& excluded_ip : excluded_subtrees_.ip_address_ranges) {
+ if (IPNumberMatchesPrefix(ip, excluded_ip.first, excluded_ip.second))
+ return false;
+ }
+ for (const auto& permitted_ip : permitted_subtrees_.ip_address_ranges) {
+ if (IPNumberMatchesPrefix(ip, permitted_ip.first, permitted_ip.second))
+ return true;
+ }
+
+ return false;
+}
+
+int NameConstraints::ConstrainedNameTypes() const {
+ return (permitted_subtrees_.present_name_types |
+ excluded_subtrees_.present_name_types);
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/name_constraints.h b/chromium/net/cert/internal/name_constraints.h
new file mode 100644
index 00000000000..46cb0dade74
--- /dev/null
+++ b/chromium/net/cert/internal/name_constraints.h
@@ -0,0 +1,138 @@
+// Copyright 2015 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_INTERNAL_NAME_CONSTRAINTS_H_
+#define NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/ip_address_number.h"
+
+namespace net {
+
+namespace der {
+class Input;
+} // namespace der
+
+// Bitfield values for the GeneralName types defined in RFC 5280. The ordering
+// and exact values are not important, but match the order from the RFC for
+// convenience.
+enum GeneralNameTypes {
+ GENERAL_NAME_NONE = 0,
+ GENERAL_NAME_OTHER_NAME = 1 << 0,
+ GENERAL_NAME_RFC822_NAME = 1 << 1,
+ GENERAL_NAME_DNS_NAME = 1 << 2,
+ GENERAL_NAME_X400_ADDRESS = 1 << 3,
+ GENERAL_NAME_DIRECTORY_NAME = 1 << 4,
+ GENERAL_NAME_EDI_PARTY_NAME = 1 << 5,
+ GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER = 1 << 6,
+ GENERAL_NAME_IP_ADDRESS = 1 << 7,
+ GENERAL_NAME_REGISTERED_ID = 1 << 8,
+};
+
+// Parses a NameConstraints extension value and allows testing whether names are
+// allowed under those constraints as defined by RFC 5280 section 4.2.1.10.
+class NET_EXPORT NameConstraints {
+ public:
+ // Represents a GeneralNames structure. When processing GeneralNames, it is
+ // often necessary to know which types of names were present, and to check
+ // all the names of a certain type. Therefore, a bitfield of all the name
+ // types is kept, and the names are split into members for each type. Only
+ // name types that are handled by this code are stored (though all types are
+ // recorded in the bitfield.)
+ // TODO(mattm): This may need to be split out into a public class, since
+ // GeneralNames is used other places in a certificate also...
+ struct GeneralNames {
+ GeneralNames();
+ ~GeneralNames();
+
+ // ASCII hostnames.
+ std::vector<std::string> dns_names;
+
+ // DER-encoded Name values (not including the Sequence tag).
+ std::vector<std::vector<uint8_t>> directory_names;
+
+ // iPAddresses as sequences of octets in network byte order. This will be
+ // populated if the GeneralNames represents a Subject Alternative Name.
+ std::vector<std::vector<uint8_t>> ip_addresses;
+
+ // iPAddress ranges, as <IP, prefix length> pairs. This will be populated
+ // if the GeneralNames represents a Name Constraints.
+ std::vector<std::pair<std::vector<uint8_t>, unsigned>> ip_address_ranges;
+
+ // Which name types were present, as a bitfield of GeneralNameTypes.
+ // Includes both the supported and unsupported types (although unsupported
+ // ones may not be recorded depending on the context, like non-critical name
+ // constraints.)
+ int present_name_types = GENERAL_NAME_NONE;
+ };
+
+ ~NameConstraints();
+
+ // Parses a DER-encoded NameConstraints extension and initializes this object.
+ // |extension_value| should be the extnValue from the extension (not including
+ // the OCTET STRING tag). |is_critical| should be true if the extension was
+ // marked critical. Returns nullptr if parsing the the extension failed.
+ // The object lifetime is not bound to the lifetime of |extension_value| data.
+ static scoped_ptr<NameConstraints> CreateFromDer(
+ const der::Input& extension_value,
+ bool is_critical);
+
+ // Tests if a certificate is allowed by the name constraints.
+ // |subject_rdn_sequence| should be the DER-encoded value of the subject's
+ // RDNSequence (not including Sequence tag), and may be an empty ASN.1
+ // sequence. |subject_alt_name_extnvalue_tlv| should be the extnValue of the
+ // subjectAltName extension (including the OCTET STRING tag & length), or
+ // empty if the cert did not have a subjectAltName extension.
+ // Note that this method does not check hostname or IP address in commonName,
+ // which is deprecated (crbug.com/308330).
+ bool IsPermittedCert(const der::Input& subject_rdn_sequence,
+ const der::Input& subject_alt_name_extnvalue_tlv) const;
+
+ // Returns true if the ASCII hostname |name| is permitted.
+ // |name| may be a wildcard hostname (starts with "*."). Eg, "*.bar.com"
+ // would not be permitted if "bar.com" is permitted and "foo.bar.com" is
+ // excluded, while "*.baz.com" would only be permitted if "baz.com" is
+ // permitted.
+ bool IsPermittedDNSName(const std::string& name) const;
+
+ // Returns true if the directoryName |name_rdn_sequence| is permitted.
+ // |name_rdn_sequence| should be the DER-encoded RDNSequence value (not
+ // including the Sequence tag.)
+ bool IsPermittedDirectoryName(const der::Input& name_rdn_sequence) const;
+
+ // Returns true if the iPAddress |ip| is permitted.
+ bool IsPermittedIP(const IPAddressNumber& ip) const;
+
+ // Returns a bitfield of GeneralNameTypes of all the types constrained by this
+ // NameConstraints. Name types that aren't supported will only be present if
+ // the name constraint they appeared in was marked critical.
+ //
+ // RFC 5280 section 4.2.1.10 says:
+ // Applications conforming to this profile MUST be able to process name
+ // constraints that are imposed on the directoryName name form and SHOULD be
+ // able to process name constraints that are imposed on the rfc822Name,
+ // uniformResourceIdentifier, dNSName, and iPAddress name forms.
+ // If a name constraints extension that is marked as critical
+ // imposes constraints on a particular name form, and an instance of
+ // that name form appears in the subject field or subjectAltName
+ // extension of a subsequent certificate, then the application MUST
+ // either process the constraint or reject the certificate.
+ int ConstrainedNameTypes() const;
+
+ private:
+ bool Parse(const der::Input& extension_value,
+ bool is_critical) WARN_UNUSED_RESULT;
+
+ GeneralNames permitted_subtrees_;
+ GeneralNames excluded_subtrees_;
+};
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_
diff --git a/chromium/net/cert/internal/name_constraints_unittest.cc b/chromium/net/cert/internal/name_constraints_unittest.cc
new file mode 100644
index 00000000000..8b550f7fc94
--- /dev/null
+++ b/chromium/net/cert/internal/name_constraints_unittest.cc
@@ -0,0 +1,1276 @@
+// Copyright 2015 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/internal/name_constraints.h"
+
+#include "net/cert/internal/test_helpers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+::testing::AssertionResult LoadTestData(const char* token,
+ const std::string& basename,
+ std::string* result) {
+ std::string path = "net/data/name_constraints_unittest/" + basename;
+
+ const PemBlockMapping mappings[] = {
+ {token, result},
+ };
+
+ return ReadTestDataFromPemFile(path, mappings);
+}
+
+::testing::AssertionResult LoadTestName(const std::string& basename,
+ std::string* result) {
+ return LoadTestData("NAME", basename, result);
+}
+
+::testing::AssertionResult LoadTestNameConstraint(const std::string& basename,
+ std::string* result) {
+ return LoadTestData("NAME CONSTRAINTS", basename, result);
+}
+
+::testing::AssertionResult LoadTestSubjectAltName(const std::string& basename,
+ std::string* result) {
+ return LoadTestData("SUBJECT ALTERNATIVE NAME", basename, result);
+}
+
+} // namespace
+
+class ParseNameConstraints
+ : public ::testing::TestWithParam<::testing::tuple<bool>> {
+ public:
+ bool is_critical() const { return ::testing::get<0>(GetParam()); }
+};
+
+// Run the tests with the name constraints marked critical and non-critical. For
+// supported name types, the results should be the same for both.
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+ ParseNameConstraints,
+ ::testing::Values(true, false));
+
+TEST_P(ParseNameConstraints, DNSNames) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example.com."));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("a.permitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("apermitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("apermitted.example.com."));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("alsopermitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("excluded.permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("a.excluded.permitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(
+ "stillnotpermitted.excluded.permitted.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(
+ "a.stillnotpermitted.excluded.permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("extraneousexclusion.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(
+ "a.extraneousexclusion.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("other.example.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("other.com"));
+
+ // Wildcard names:
+ // Pattern could match excluded.permitted.example.com, thus should not be
+ // allowed.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.permitted.example.com"));
+ // Entirely within excluded name, obviously not allowed.
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("*.excluded.permitted.example.com"));
+ // Within permitted.example.com and cannot match any exclusion, thus these are
+ // allowed.
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("*.foo.permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("*.alsopermitted.example.com"));
+ // Matches permitted.example2.com, but also matches other .example2.com names
+ // which are not in either permitted or excluded, so not allowed.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.example2.com"));
+ // Partial wildcards are not supported, so these name are permitted even if
+ // it seems like they shouldn't be. It's fine, since certificate verification
+ // won't treat them as wildcard names either.
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("*xcluded.permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("exclude*.permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("excl*ded.permitted.example.com"));
+ // Garbage wildcard data.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*."));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.*"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(".*"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*"));
+ // Matches SAN with trailing dot.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example3.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example3.com."));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("a.permitted.example3.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("a.permitted.example3.com."));
+
+ EXPECT_EQ(GENERAL_NAME_DNS_NAME, name_constraints->ConstrainedNameTypes());
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-permitted.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname.pem", &san));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints,
+ DNSNamesWithMultipleLevelsBetweenExcludedAndPermitted) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname2.pem", &a));
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Matches permitted exactly.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("com"));
+ // Contained within permitted and doesn't match excluded (foo.bar.com).
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("bar.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("baz.bar.com"));
+ // Matches excluded exactly.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.bar.com"));
+ // Contained within excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("baz.foo.bar.com"));
+
+ // Cannot match anything within excluded.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("*.baz.bar.com"));
+ // Wildcard hostnames only match a single label, so cannot match excluded
+ // which has two labels before .com.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("*.com"));
+
+ // Partial match of foo.bar.com.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.bar.com"));
+ // All expansions of wildcard are within excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.foo.bar.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesWithLeadingDot) {
+ std::string a;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("dnsname-permitted_with_leading_dot.pem", &a));
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // dNSName constraints should be specified as a host. A dNSName constraint
+ // with a leading "." doesn't make sense, though some certs include it
+ // (probably confusing it with the rules for uniformResourceIdentifier
+ // constraints). It should not match anything.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("bar.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.bar.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesExcludeOnly) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-excluded.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Only "excluded.permitted.example.com" is excluded, but since no dNSNames
+ // are permitted, everything is excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(""));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("excluded.permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("a.excluded.permitted.example.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesExcludeAll) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-excludeall.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // "permitted.example.com" is in the permitted section, but since "" is
+ // excluded, nothing is permitted.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName(""));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedDNSName("foo.permitted.example.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesExcludeDot) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-exclude_dot.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // "." is excluded, which should match nothing.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("permitted.example.com"));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedDNSName("foo.permitted.example.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesFailOnInvalidIA5String) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname.pem", &a));
+
+ size_t replace_location = a.find("permitted.example2.com");
+ ASSERT_NE(std::string::npos, replace_location);
+ a.replace(replace_location, 1, 1, -1);
+
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+}
+
+TEST_P(ParseNameConstraints, DirectoryNames) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("directoryname.pem", &constraints_der));
+
+ std::string name_us;
+ ASSERT_TRUE(LoadTestName("name-us.pem", &name_us));
+ std::string name_us_ca;
+ ASSERT_TRUE(LoadTestName("name-us-california.pem", &name_us_ca));
+ std::string name_us_ca_mountain_view;
+ ASSERT_TRUE(LoadTestName("name-us-california-mountain_view.pem",
+ &name_us_ca_mountain_view));
+ std::string name_us_az;
+ ASSERT_TRUE(LoadTestName("name-us-arizona.pem", &name_us_az));
+ std::string name_jp;
+ ASSERT_TRUE(LoadTestName("name-jp.pem", &name_jp));
+ std::string name_jp_tokyo;
+ ASSERT_TRUE(LoadTestName("name-jp-tokyo.pem", &name_jp_tokyo));
+ std::string name_de;
+ ASSERT_TRUE(LoadTestName("name-de.pem", &name_de));
+ std::string name_ca;
+ ASSERT_TRUE(LoadTestName("name-ca.pem", &name_ca));
+
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Not in any permitted subtree.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_ca)));
+ // Within the permitted C=US subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us)));
+ // Within the permitted C=US subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_az)));
+ // Within the permitted C=US subtree, however the excluded C=US,ST=California
+ // subtree takes priority.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca)));
+ // Within the permitted C=US subtree as well as the permitted
+ // C=US,ST=California,L=Mountain View subtree, however the excluded
+ // C=US,ST=California subtree still takes priority.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca_mountain_view)));
+ // Not in any permitted subtree, and also inside the extraneous excluded C=DE
+ // subtree.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_de)));
+ // Not in any permitted subtree.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_jp)));
+ // Within the permitted C=JP,ST=Tokyo subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_jp_tokyo)));
+
+ EXPECT_EQ(GENERAL_NAME_DIRECTORY_NAME,
+ name_constraints->ConstrainedNameTypes());
+
+ // Within the permitted C=US subtree.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us), der::Input()));
+ // Within the permitted C=US subtree, however the excluded C=US,ST=California
+ // subtree takes priority.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_ca), der::Input()));
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-permitted.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname.pem", &san));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, DirectoryNamesExcludeOnly) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("directoryname-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_empty;
+ ASSERT_TRUE(LoadTestName("name-empty.pem", &name_empty));
+ std::string name_us;
+ ASSERT_TRUE(LoadTestName("name-us.pem", &name_us));
+ std::string name_us_ca;
+ ASSERT_TRUE(LoadTestName("name-us-california.pem", &name_us_ca));
+ std::string name_us_ca_mountain_view;
+ ASSERT_TRUE(LoadTestName("name-us-california-mountain_view.pem",
+ &name_us_ca_mountain_view));
+
+ // Only "C=US,ST=California" is excluded, but since no directoryNames are
+ // permitted, everything is excluded.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_empty)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca_mountain_view)));
+}
+
+TEST_P(ParseNameConstraints, DirectoryNamesExcludeAll) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("directoryname-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_empty;
+ ASSERT_TRUE(LoadTestName("name-empty.pem", &name_empty));
+ std::string name_us;
+ ASSERT_TRUE(LoadTestName("name-us.pem", &name_us));
+ std::string name_us_ca;
+ ASSERT_TRUE(LoadTestName("name-us-california.pem", &name_us_ca));
+ std::string name_us_ca_mountain_view;
+ ASSERT_TRUE(LoadTestName("name-us-california-mountain_view.pem",
+ &name_us_ca_mountain_view));
+ std::string name_jp;
+ ASSERT_TRUE(LoadTestName("name-jp.pem", &name_jp));
+
+ // "C=US" is in the permitted section, but since an empty
+ // directoryName is excluded, nothing is permitted.
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_empty)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_us_ca)));
+ EXPECT_FALSE(name_constraints->IsPermittedDirectoryName(
+ SequenceValueFromString(&name_jp)));
+}
+
+TEST_P(ParseNameConstraints, IPAdresses) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // IPv4 tests:
+ {
+ // Not in any permitted range.
+ const uint8_t ip4[] = {192, 169, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.168.0.0/255.255.0.0 range.
+ const uint8_t ip4[] = {192, 168, 0, 1};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.168.0.0/255.255.0.0 range, however the
+ // excluded 192.168.5.0/255.255.255.0 takes priority.
+ const uint8_t ip4[] = {192, 168, 5, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.168.0.0/255.255.0.0 range as well as the
+ // permitted 192.168.5.32/255.255.255.224 range, however the excluded
+ // 192.168.5.0/255.255.255.0 still takes priority.
+ const uint8_t ip4[] = {192, 168, 5, 33};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 192.167.5.32/255.255.255.224 range.)
+ const uint8_t ip4[] = {192, 167, 5, 31};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.167.5.32/255.255.255.224 range.
+ const uint8_t ip4[] = {192, 167, 5, 32};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Within the permitted 192.167.5.32/255.255.255.224 range.
+ const uint8_t ip4[] = {192, 167, 5, 63};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 192.167.5.32/255.255.255.224 range.)
+ const uint8_t ip4[] = {192, 167, 5, 64};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ // Not in any permitted range, and also inside the extraneous excluded
+ // 192.166.5.32/255.255.255.224 range.
+ const uint8_t ip4[] = {192, 166, 5, 32};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+
+ // IPv6 tests:
+ {
+ // Not in any permitted range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 1};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range, however
+ // the excluded
+ // 102:304:506:708:90a:b0c:500:0/ffff:ffff:ffff:ffff:ffff:ffff:ff00:0 takes
+ // priority.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range as well
+ // as the permitted
+ // 102:304:506:708:90a:b0c:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0,
+ // however the excluded
+ // 102:304:506:708:90a:b0c:500:0/ffff:ffff:ffff:ffff:ffff:ffff:ff00:0 takes
+ // priority.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 33, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0
+ // range.)
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 11, 5, 31, 255, 255};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 5, 32, 0, 0};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Within the permitted
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 11, 5, 63, 255, 255};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Not in any permitted range. (Just outside the
+ // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0
+ // range.)
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 5, 64, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ // Not in any permitted range, and also inside the extraneous excluded
+ // 102:304:506:708:90a:b0a:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 10, 5, 33, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+
+ EXPECT_EQ(GENERAL_NAME_IP_ADDRESS, name_constraints->ConstrainedNameTypes());
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-permitted.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname.pem", &san));
+ EXPECT_TRUE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+
+ ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress.pem", &san));
+ EXPECT_FALSE(
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, IPAdressesExcludeOnly) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-excluded.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // Only 192.168.5.0/255.255.255.0 is excluded, but since no iPAddresses
+ // are permitted, everything is excluded.
+ {
+ const uint8_t ip4[] = {192, 168, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 5, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesExcludeAll) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-excludeall.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // 192.168.0.0/255.255.0.0 and
+ // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: are permitted,
+ // but since 0.0.0.0/0 and ::/0 are excluded nothing is permitted.
+ {
+ const uint8_t ip4[] = {192, 168, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {1, 1, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip6[] = {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+ {
+ const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip6, ip6 + arraysize(ip6))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitSingleHost) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_singlehost.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 2};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 3};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 4};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {255, 255, 255, 255};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitPrefixLen31) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_prefix31.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 1};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 2};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 3};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 4};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 5};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {255, 255, 255, 255};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitPrefixLen1) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_prefix1.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {0x7F, 0xFF, 0xFF, 0xFF};
+ EXPECT_FALSE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {0x80, 0, 0, 0};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {0xFF, 0xFF, 0xFF, 0xFF};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesNetmaskPermitAll) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-permit_all.pem", &a));
+
+ scoped_ptr<NameConstraints> name_constraints(
+ NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ {
+ const uint8_t ip4[] = {0, 0, 0, 0};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {192, 168, 1, 1};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+ {
+ const uint8_t ip4[] = {255, 255, 255, 255};
+ EXPECT_TRUE(name_constraints->IsPermittedIP(
+ IPAddressNumber(ip4, ip4 + arraysize(ip4))));
+ }
+}
+
+TEST_P(ParseNameConstraints, IPAdressesFailOnInvalidAddr) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress-invalid_addr.pem", &a));
+
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+}
+
+TEST_P(ParseNameConstraints, IPAdressesFailOnInvalidMaskNotContiguous) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_1.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_2.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_3.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "ipaddress-invalid_mask_not_contiguous_4.pem", &a));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&a), is_critical()));
+}
+
+TEST_P(ParseNameConstraints, OtherNamesInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("othername-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_OTHER_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-othername.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, OtherNamesInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("othername-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_OTHER_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-othername.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, Rfc822NamesInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("rfc822name-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_RFC822_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-rfc822name.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, Rfc822NamesInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("rfc822name-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_RFC822_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-rfc822name.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, X400AddresssInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("x400address-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_X400_ADDRESS,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-x400address.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, X400AddresssInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("x400address-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_X400_ADDRESS,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-x400address.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, EdiPartyNamesInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("edipartyname-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_EDI_PARTY_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-edipartyname.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, EdiPartyNamesInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("edipartyname-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_EDI_PARTY_NAME,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-edipartyname.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, URIsInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("uri-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-uri.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, URIsInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("uri-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-uri.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, RegisteredIDsInPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("registeredid-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_REGISTERED_ID,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-registeredid.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, RegisteredIDsInExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("registeredid-excluded.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ if (is_critical()) {
+ EXPECT_EQ(GENERAL_NAME_REGISTERED_ID,
+ name_constraints->ConstrainedNameTypes());
+ } else {
+ EXPECT_EQ(0, name_constraints->ConstrainedNameTypes());
+ }
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-registeredid.pem", &san));
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(der::Input(), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints,
+ failsOnGeneralSubtreeWithMinimumZeroEncodedUnnecessarily) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("dnsname-with_min_0.pem", &constraints_der));
+ // The value should not be in the DER encoding if it is the default. But this
+ // could be changed to allowed if there are buggy encoders out there that
+ // include it anyway.
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnGeneralSubtreeWithMinimum) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("dnsname-with_min_1.pem", &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints,
+ failsOnGeneralSubtreeWithMinimumZeroEncodedUnnecessarilyAndMaximum) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_min_0_and_max.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnGeneralSubtreeWithMinimumAndMaximum) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_min_1_and_max.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnGeneralSubtreeWithMaximum) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_max.pem", &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnEmptyExtensionValue) {
+ std::string constraints_der = "";
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnNoPermittedAndExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("invalid-no_subtrees.pem", &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnEmptyPermitted) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("invalid-empty_permitted_subtree.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, FailsOnEmptyExcluded) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("invalid-empty_excluded_subtree.pem",
+ &constraints_der));
+ EXPECT_FALSE(NameConstraints::CreateFromDer(der::Input(&constraints_der),
+ is_critical()));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectEmailAddressIsOk) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("directoryname.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_arizona_email;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-email.pem", &name_us_arizona_email));
+
+ // Name constraints don't contain rfc822Name, so emailAddress in subject is
+ // allowed regardless.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_arizona_email), der::Input()));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectEmailAddressIsNotOk) {
+ std::string constraints_der;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("rfc822name-permitted.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_arizona_email;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-email.pem", &name_us_arizona_email));
+
+ // Name constraints contain rfc822Name, so emailAddress in subject is not
+ // allowed if the constraints were critical.
+ EXPECT_EQ(!is_critical(),
+ name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_arizona_email), der::Input()));
+}
+
+// Hostname in commonName is not allowed (crbug.com/308330), so these are tests
+// are not particularly interesting, just verifying that the commonName is
+// ignored for dNSName constraints.
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectDnsNames) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("directoryname_and_dnsname.pem",
+ &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az_foocom;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-foo.com.pem", &name_us_az_foocom));
+ // The subject is within permitted directoryName constraints, so permitted.
+ // (The commonName hostname is not within permitted dNSName constraints, so
+ // this would not be permitted if hostnames in commonName were checked.)
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_foocom), der::Input()));
+
+ std::string name_us_az_permitted;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-permitted.example.com.pem",
+ &name_us_az_permitted));
+ // The subject is in permitted directoryName and the commonName is within
+ // permitted dNSName constraints, so this should be permitted regardless if
+ // hostnames in commonName are checked or not.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_permitted), der::Input()));
+
+ std::string name_us_ca_permitted;
+ ASSERT_TRUE(LoadTestName("name-us-california-permitted.example.com.pem",
+ &name_us_ca_permitted));
+ // The subject is within the excluded C=US,ST=California directoryName, so
+ // this should not be allowed, regardless of checking the
+ // permitted.example.com in commonName.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_ca_permitted), der::Input()));
+}
+
+// IP addresses in commonName are not allowed (crbug.com/308330), so these are
+// tests are not particularly interesting, just verifying that the commonName is
+// ignored for iPAddress constraints.
+TEST_P(ParseNameConstraints, IsPermittedCertSubjectIpAddresses) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint(
+ "directoryname_and_dnsname_and_ipaddress.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az_1_1_1_1;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-1.1.1.1.pem", &name_us_az_1_1_1_1));
+ // The subject is within permitted directoryName constraints, so permitted.
+ // (The commonName IP address is not within permitted iPAddresses constraints,
+ // so this would not be permitted if IP addresses in commonName were checked.)
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_1_1_1_1), der::Input()));
+
+ std::string name_us_az_192_168_1_1;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-192.168.1.1.pem", &name_us_az_192_168_1_1));
+ // The subject is in permitted directoryName and the commonName is within
+ // permitted iPAddress constraints, so this should be permitted regardless if
+ // IP addresses in commonName are checked or not.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_192_168_1_1), der::Input()));
+
+ std::string name_us_ca_192_168_1_1;
+ ASSERT_TRUE(LoadTestName("name-us-california-192.168.1.1.pem",
+ &name_us_ca_192_168_1_1));
+ // The subject is within the excluded C=US,ST=California directoryName, so
+ // this should not be allowed, regardless of checking the
+ // IP address in commonName.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_ca_192_168_1_1), der::Input()));
+
+ std::string name_us_az_ipv6;
+ ASSERT_TRUE(LoadTestName("name-us-arizona-ipv6.pem", &name_us_az_ipv6));
+ // The subject is within permitted directoryName constraints, so permitted.
+ // (The commonName is an ipv6 address which wasn't supported in the past, but
+ // since commonName checking is ignored entirely, this is permitted.)
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_ipv6), der::Input()));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertFailsOnEmptySubjectAltName) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az;
+ ASSERT_TRUE(LoadTestName("name-us-arizona.pem", &name_us_az));
+
+ // No constraints on directoryName type, so name_us_az should be allowed when
+ // subjectAltName is not present.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az), der::Input()));
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-invalid-empty.pem", &san));
+ // Should fail if subjectAltName is present but empty.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az), der::Input(&san)));
+}
+
+TEST_P(ParseNameConstraints, IsPermittedCertFailsOnInvalidIpInSubjectAltName) {
+ std::string constraints_der;
+ ASSERT_TRUE(LoadTestNameConstraint("ipaddress.pem", &constraints_der));
+ scoped_ptr<NameConstraints> name_constraints(NameConstraints::CreateFromDer(
+ der::Input(&constraints_der), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ std::string name_us_az_192_168_1_1;
+ ASSERT_TRUE(
+ LoadTestName("name-us-arizona-192.168.1.1.pem", &name_us_az_192_168_1_1));
+
+ // Without the invalid subjectAltName, it passes.
+ EXPECT_TRUE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_192_168_1_1), der::Input()));
+
+ std::string san;
+ ASSERT_TRUE(LoadTestSubjectAltName("san-invalid-ipaddress.pem", &san));
+ // Should fail if subjectAltName contains an invalid ip address.
+ EXPECT_FALSE(name_constraints->IsPermittedCert(
+ SequenceValueFromString(&name_us_az_192_168_1_1), der::Input(&san)));
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/parse_certificate.cc b/chromium/net/cert/internal/parse_certificate.cc
index 9535459bb8a..74222e8fde0 100644
--- a/chromium/net/cert/internal/parse_certificate.cc
+++ b/chromium/net/cert/internal/parse_certificate.cc
@@ -4,6 +4,8 @@
#include "net/cert/internal/parse_certificate.h"
+#include <utility>
+
#include "net/der/input.h"
#include "net/der/parse_values.h"
#include "net/der/parser.h"
@@ -172,6 +174,17 @@ bool ParseValidity(const der::Input& validity_tlv,
return true;
}
+// Returns true if every bit in |bits| is zero (including empty).
+WARN_UNUSED_RESULT bool BitStringIsAllZeros(const der::BitString& bits) {
+ // Note that it is OK to read from the unused bits, since BitString parsing
+ // guarantees they are all zero.
+ for (size_t i = 0; i < bits.bytes().Length(); ++i) {
+ if (bits.bytes().UnsafeData()[i] != 0)
+ return false;
+ }
+ return true;
+}
+
} // namespace
ParsedTbsCertificate::ParsedTbsCertificate() {}
@@ -353,4 +366,238 @@ bool ParseTbsCertificate(const der::Input& tbs_tlv, ParsedTbsCertificate* out) {
return true;
}
+// From RFC 5280:
+//
+// Extension ::= SEQUENCE {
+// extnID OBJECT IDENTIFIER,
+// critical BOOLEAN DEFAULT FALSE,
+// extnValue OCTET STRING
+// -- contains the DER encoding of an ASN.1 value
+// -- corresponding to the extension type identified
+// -- by extnID
+// }
+bool ParseExtension(const der::Input& extension_tlv, ParsedExtension* out) {
+ der::Parser parser(extension_tlv);
+
+ // Extension ::= SEQUENCE {
+ der::Parser extension_parser;
+ if (!parser.ReadSequence(&extension_parser))
+ return false;
+
+ // extnID OBJECT IDENTIFIER,
+ if (!extension_parser.ReadTag(der::kOid, &out->oid))
+ return false;
+
+ // critical BOOLEAN DEFAULT FALSE,
+ out->critical = false;
+ bool has_critical;
+ der::Input critical;
+ if (!extension_parser.ReadOptionalTag(der::kBool, &critical, &has_critical))
+ return false;
+ if (has_critical) {
+ if (!der::ParseBool(critical, &out->critical))
+ return false;
+ if (!out->critical)
+ return false; // DER-encoding requires DEFAULT values be omitted.
+ }
+
+ // extnValue OCTET STRING
+ if (!extension_parser.ReadTag(der::kOctetString, &out->value))
+ return false;
+
+ // The Extension type does not have an extension point (everything goes in
+ // extnValue).
+ if (extension_parser.HasMore())
+ return false;
+
+ // By definition the input was a single Extension sequence, so there shouldn't
+ // be unconsumed data.
+ if (parser.HasMore())
+ return false;
+
+ return true;
+}
+
+der::Input KeyUsageOid() {
+ // From RFC 5280:
+ //
+ // id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+ //
+ // In dotted notation: 2.5.29.15
+ static const uint8_t oid[] = {0x55, 0x1d, 0x0f};
+ return der::Input(oid);
+}
+
+der::Input SubjectAltNameOid() {
+ // From RFC 5280:
+ //
+ // id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+ //
+ // In dotted notation: 2.5.29.17
+ static const uint8_t oid[] = {0x55, 0x1d, 0x11};
+ return der::Input(oid);
+}
+
+der::Input BasicConstraintsOid() {
+ // From RFC 5280:
+ //
+ // id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+ //
+ // In dotted notation: 2.5.29.19
+ static const uint8_t oid[] = {0x55, 0x1d, 0x13};
+ return der::Input(oid);
+}
+
+der::Input NameConstraintsOid() {
+ // From RFC 5280:
+ //
+ // id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+ //
+ // In dotted notation: 2.5.29.30
+ static const uint8_t oid[] = {0x55, 0x1d, 0x1e};
+ return der::Input(oid);
+}
+
+der::Input CertificatePoliciesOid() {
+ // From RFC 5280:
+ //
+ // id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+ //
+ // In dotted notation: 2.5.29.32
+ static const uint8_t oid[] = {0x55, 0x1d, 0x20};
+ return der::Input(oid);
+}
+
+der::Input PolicyConstraintsOid() {
+ // From RFC 5280:
+ //
+ // id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+ //
+ // In dotted notation: 2.5.29.36
+ static const uint8_t oid[] = {0x55, 0x1d, 0x24};
+ return der::Input(oid);
+}
+
+der::Input ExtKeyUsageOid() {
+ // From RFC 5280:
+ //
+ // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
+ //
+ // In dotted notation: 2.5.29.37
+ static const uint8_t oid[] = {0x55, 0x1d, 0x25};
+ return der::Input(oid);
+}
+
+NET_EXPORT bool ParseExtensions(
+ const der::Input& extensions_tlv,
+ std::map<der::Input, ParsedExtension>* extensions) {
+ der::Parser parser(extensions_tlv);
+
+ // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ der::Parser extensions_parser;
+ if (!parser.ReadSequence(&extensions_parser))
+ return false;
+
+ // The Extensions SEQUENCE must contains at least 1 element (otherwise it
+ // should have been omitted).
+ if (!extensions_parser.HasMore())
+ return false;
+
+ extensions->clear();
+
+ while (extensions_parser.HasMore()) {
+ ParsedExtension extension;
+
+ der::Input extension_tlv;
+ if (!extensions_parser.ReadRawTLV(&extension_tlv))
+ return false;
+
+ if (!ParseExtension(extension_tlv, &extension))
+ return false;
+
+ bool is_duplicate =
+ !extensions->insert(std::make_pair(extension.oid, extension)).second;
+
+ // RFC 5280 says that an extension should not appear more than once.
+ if (is_duplicate)
+ return false;
+ }
+
+ // By definition the input was a single Extensions sequence, so there
+ // shouldn't be unconsumed data.
+ if (parser.HasMore())
+ return false;
+
+ return true;
+}
+
+bool ParseBasicConstraints(const der::Input& basic_constraints_tlv,
+ ParsedBasicConstraints* out) {
+ der::Parser parser(basic_constraints_tlv);
+
+ // BasicConstraints ::= SEQUENCE {
+ der::Parser sequence_parser;
+ if (!parser.ReadSequence(&sequence_parser))
+ return false;
+
+ // cA BOOLEAN DEFAULT FALSE,
+ out->is_ca = false;
+ bool has_ca;
+ der::Input ca;
+ if (!sequence_parser.ReadOptionalTag(der::kBool, &ca, &has_ca))
+ return false;
+ if (has_ca) {
+ if (!der::ParseBool(ca, &out->is_ca))
+ return false;
+ // TODO(eroman): Should reject if CA was set to false, since
+ // DER-encoding requires DEFAULT values be omitted. In
+ // practice however there are a lot of certificates that use
+ // the broken encoding.
+ }
+
+ // pathLenConstraint INTEGER (0..MAX) OPTIONAL }
+ der::Input encoded_path_len;
+ if (!sequence_parser.ReadOptionalTag(der::kInteger, &encoded_path_len,
+ &out->has_path_len)) {
+ return false;
+ }
+ if (out->has_path_len) {
+ if (!der::ParseUint8(encoded_path_len, &out->path_len))
+ return false;
+ } else {
+ // Default initialize to 0 as a precaution.
+ out->path_len = 0;
+ }
+
+ // There shouldn't be any unconsumed data in the extension.
+ if (sequence_parser.HasMore())
+ return false;
+
+ // By definition the input was a single BasicConstraints sequence, so there
+ // shouldn't be unconsumed data.
+ if (parser.HasMore())
+ return false;
+
+ return true;
+}
+
+bool ParseKeyUsage(const der::Input& key_usage_tlv, der::BitString* key_usage) {
+ der::Parser parser(key_usage_tlv);
+ if (!parser.ReadBitString(key_usage))
+ return false;
+
+ // By definition the input was a single BIT STRING.
+ if (parser.HasMore())
+ return false;
+
+ // RFC 5280 section 4.2.1.3:
+ //
+ // When the keyUsage extension appears in a certificate, at least
+ // one of the bits MUST be set to 1.
+ if (BitStringIsAllZeros(*key_usage))
+ return false;
+
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/cert/internal/parse_certificate.h b/chromium/net/cert/internal/parse_certificate.h
index 0f6b0bb0773..e7a1670af1b 100644
--- a/chromium/net/cert/internal/parse_certificate.h
+++ b/chromium/net/cert/internal/parse_certificate.h
@@ -5,7 +5,10 @@
#ifndef NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_
#define NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <map>
+
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/der/input.h"
@@ -214,6 +217,157 @@ struct NET_EXPORT ParsedTbsCertificate {
der::Input extensions_tlv;
};
+// ParsedExtension represents a parsed "Extension" from RFC 5280. It contains
+// der:Inputs which are not owned so the associated data must be kept alive.
+//
+// Extension ::= SEQUENCE {
+// extnID OBJECT IDENTIFIER,
+// critical BOOLEAN DEFAULT FALSE,
+// extnValue OCTET STRING
+// -- contains the DER encoding of an ASN.1 value
+// -- corresponding to the extension type identified
+// -- by extnID
+// }
+struct NET_EXPORT ParsedExtension {
+ der::Input oid;
+ // |value| will contain the contents of the OCTET STRING. For instance for
+ // basicConstraints it will be the TLV for a SEQUENCE.
+ der::Input value;
+ bool critical = false;
+};
+
+// Parses a DER-encoded "Extension" as specified by RFC 5280. Returns true on
+// success and sets the results in |out|.
+//
+// Note that on success |out| aliases data from the input |extension_tlv|.
+// Hence the fields of the ParsedExtension are only valid as long as
+// |extension_tlv| remains valid.
+//
+// On failure |out| has an undefined state. Some of its fields may have been
+// updated during parsing, whereas others may not have been changed.
+NET_EXPORT bool ParseExtension(const der::Input& extension_tlv,
+ ParsedExtension* out) WARN_UNUSED_RESULT;
+
+// From RFC 5280:
+//
+// id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+//
+// In dotted notation: 2.5.29.15
+NET_EXPORT der::Input KeyUsageOid();
+
+// From RFC 5280:
+//
+// id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+//
+// In dotted notation: 2.5.29.17
+NET_EXPORT der::Input SubjectAltNameOid();
+
+// From RFC 5280:
+//
+// id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+//
+// In dotted notation: 2.5.29.19
+NET_EXPORT der::Input BasicConstraintsOid();
+
+// From RFC 5280:
+//
+// id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+//
+// In dotted notation: 2.5.29.30
+NET_EXPORT der::Input NameConstraintsOid();
+
+// From RFC 5280:
+//
+// id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+//
+// In dotted notation: 2.5.29.32
+NET_EXPORT der::Input CertificatePoliciesOid();
+
+// From RFC 5280:
+//
+// id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+//
+// In dotted notation: 2.5.29.36
+NET_EXPORT der::Input PolicyConstraintsOid();
+
+// From RFC 5280:
+//
+// id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
+//
+// In dotted notation: 2.5.29.37
+NET_EXPORT der::Input ExtKeyUsageOid();
+
+// Parses the Extensions sequence as defined by RFC 5280. Extensions are added
+// to the map |extensions| keyed by the OID. Parsing guarantees that each OID
+// is unique. Note that certificate verification must consume each extension
+// marked as critical.
+//
+// Returns true on success and fills |extensions|. The output will reference
+// bytes in |extensions_tlv|, so that data must be kept alive.
+// On failure |extensions| may be partially written to and should not be used.
+NET_EXPORT bool ParseExtensions(
+ const der::Input& extensions_tlv,
+ std::map<der::Input, ParsedExtension>* extensions) WARN_UNUSED_RESULT;
+
+struct ParsedBasicConstraints {
+ bool is_ca = false;
+ bool has_path_len = false;
+ uint8_t path_len = 0;
+};
+
+// Parses the BasicConstraints extension as defined by RFC 5280:
+//
+// BasicConstraints ::= SEQUENCE {
+// cA BOOLEAN DEFAULT FALSE,
+// pathLenConstraint INTEGER (0..MAX) OPTIONAL }
+//
+// The maximum allowed value of pathLenConstraints will be whatever can fit
+// into a uint8_t.
+NET_EXPORT bool ParseBasicConstraints(const der::Input& basic_constraints_tlv,
+ ParsedBasicConstraints* out)
+ WARN_UNUSED_RESULT;
+
+// KeyUsageBit contains the index for a particular key usage. The index is
+// measured from the most significant bit of a bit string.
+//
+// From RFC 5280 section 4.2.1.3:
+//
+// KeyUsage ::= BIT STRING {
+// digitalSignature (0),
+// nonRepudiation (1), -- recent editions of X.509 have
+// -- renamed this bit to contentCommitment
+// keyEncipherment (2),
+// dataEncipherment (3),
+// keyAgreement (4),
+// keyCertSign (5),
+// cRLSign (6),
+// encipherOnly (7),
+// decipherOnly (8) }
+enum KeyUsageBit {
+ KEY_USAGE_BIT_DIGITAL_SIGNATURE = 0,
+ KEY_USAGE_BIT_NON_REPUDIATION = 1,
+ KEY_USAGE_BIT_KEY_ENCIPHERMENT = 2,
+ KEY_USAGE_BIT_DATA_ENCIPHERMENT = 3,
+ KEY_USAGE_BIT_KEY_AGREEMENT = 4,
+ KEY_USAGE_BIT_KEY_CERT_SIGN = 5,
+ KEY_USAGE_BIT_CRL_SIGN = 6,
+ KEY_USAGE_BIT_ENCIPHER_ONLY = 7,
+ KEY_USAGE_BIT_DECIPHER_ONLY = 8,
+};
+
+// Parses the KeyUsage extension as defined by RFC 5280. Returns true on
+// success, and |key_usage| will alias data in |key_usage_tlv|. On failure
+// returns false, and |key_usage| may have been modified.
+//
+// In addition to validating that key_usage_tlv is a BIT STRING, this does
+// additional KeyUsage specific validations such as requiring at least 1 bit to
+// be set.
+//
+// To test if a particular key usage is set, call, e.g.:
+// key_usage->AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE);
+NET_EXPORT bool ParseKeyUsage(const der::Input& key_usage_tlv,
+ der::BitString* key_usage) WARN_UNUSED_RESULT;
+
} // namespace net
#endif // NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_
diff --git a/chromium/net/cert/internal/parse_certificate_unittest.cc b/chromium/net/cert/internal/parse_certificate_unittest.cc
index cf6da4afc82..eea4d4024be 100644
--- a/chromium/net/cert/internal/parse_certificate_unittest.cc
+++ b/chromium/net/cert/internal/parse_certificate_unittest.cc
@@ -46,16 +46,14 @@ void EnsureParsingCertificateSucceeds(const std::string& file_name) {
// Parsing the certificate should succeed.
ParsedCertificate parsed;
- ASSERT_TRUE(ParseCertificate(InputFromString(&data), &parsed));
+ ASSERT_TRUE(ParseCertificate(der::Input(&data), &parsed));
// Ensure that the ParsedCertificate matches expectations.
EXPECT_EQ(0, parsed.signature_value.unused_bits());
- EXPECT_EQ(InputFromString(&expected_signature),
- parsed.signature_value.bytes());
- EXPECT_EQ(InputFromString(&expected_signature_algorithm),
+ EXPECT_EQ(der::Input(&expected_signature), parsed.signature_value.bytes());
+ EXPECT_EQ(der::Input(&expected_signature_algorithm),
parsed.signature_algorithm_tlv);
- EXPECT_EQ(InputFromString(&expected_tbs_certificate),
- parsed.tbs_certificate_tlv);
+ EXPECT_EQ(der::Input(&expected_tbs_certificate), parsed.tbs_certificate_tlv);
}
// Loads certificate data from the PEM file |file_name| and verifies that the
@@ -71,7 +69,7 @@ void EnsureParsingCertificateFails(const std::string& file_name) {
// Parsing the Certificate should fail.
ParsedCertificate parsed;
- ASSERT_FALSE(ParseCertificate(InputFromString(&data), &parsed));
+ ASSERT_FALSE(ParseCertificate(der::Input(&data), &parsed));
}
// Tests parsing a Certificate.
@@ -153,33 +151,33 @@ void EnsureParsingTbsSucceeds(const std::string& file_name,
// Parsing the TBSCertificate should succeed.
ParsedTbsCertificate parsed;
- ASSERT_TRUE(ParseTbsCertificate(InputFromString(&data), &parsed));
+ ASSERT_TRUE(ParseTbsCertificate(der::Input(&data), &parsed));
// Ensure that the ParsedTbsCertificate matches expectations.
EXPECT_EQ(expected_version, parsed.version);
- EXPECT_EQ(InputFromString(&expected_serial_number), parsed.serial_number);
- EXPECT_EQ(InputFromString(&expected_signature_algorithm),
+ EXPECT_EQ(der::Input(&expected_serial_number), parsed.serial_number);
+ EXPECT_EQ(der::Input(&expected_signature_algorithm),
parsed.signature_algorithm_tlv);
- EXPECT_EQ(InputFromString(&expected_issuer), parsed.issuer_tlv);
+ EXPECT_EQ(der::Input(&expected_issuer), parsed.issuer_tlv);
// In the test expectations PEM file, validity is described as a
// textual string of the parsed value (rather than as DER).
EXPECT_EQ(expected_validity_not_before, ToString(parsed.validity_not_before));
EXPECT_EQ(expected_validity_not_after, ToString(parsed.validity_not_after));
- EXPECT_EQ(InputFromString(&expected_subject), parsed.subject_tlv);
- EXPECT_EQ(InputFromString(&expected_spki), parsed.spki_tlv);
+ EXPECT_EQ(der::Input(&expected_subject), parsed.subject_tlv);
+ EXPECT_EQ(der::Input(&expected_spki), parsed.spki_tlv);
- EXPECT_EQ(InputFromString(&expected_issuer_unique_id),
+ EXPECT_EQ(der::Input(&expected_issuer_unique_id),
parsed.issuer_unique_id.bytes());
EXPECT_EQ(!expected_issuer_unique_id.empty(), parsed.has_issuer_unique_id);
- EXPECT_EQ(InputFromString(&expected_subject_unique_id),
+ EXPECT_EQ(der::Input(&expected_subject_unique_id),
parsed.subject_unique_id.bytes());
EXPECT_EQ(!expected_subject_unique_id.empty(), parsed.has_subject_unique_id);
- EXPECT_EQ(InputFromString(&expected_extensions), parsed.extensions_tlv);
+ EXPECT_EQ(der::Input(&expected_extensions), parsed.extensions_tlv);
EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions);
}
@@ -196,7 +194,7 @@ void EnsureParsingTbsFails(const std::string& file_name) {
// Parsing the TBSCertificate should fail.
ParsedTbsCertificate parsed;
- ASSERT_FALSE(ParseTbsCertificate(InputFromString(&data), &parsed));
+ ASSERT_FALSE(ParseTbsCertificate(der::Input(&data), &parsed));
}
// Tests parsing a TBSCertificate for v3 that contains no optional fields.
@@ -326,6 +324,467 @@ TEST(ParseTbsCertificateTest, ValidityRelaxed) {
EnsureParsingTbsFails("tbs_validity_relaxed.pem");
}
+// Reads a PEM file containing a block "EXTENSION". This input will be
+// passed to ParseExtension, and the results filled in |out|.
+bool ParseExtensionFromFile(const std::string& file_name,
+ ParsedExtension* out,
+ std::string* data) {
+ const PemBlockMapping mappings[] = {
+ {"EXTENSION", data},
+ };
+
+ EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ return ParseExtension(der::Input(data), out);
+}
+
+// Parses an Extension whose critical field is true (255).
+TEST(ParseExtensionTest, Critical) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_TRUE(
+ ParseExtensionFromFile("extension_critical.pem", &extension, &data));
+
+ EXPECT_TRUE(extension.critical);
+
+ const uint8_t kExpectedOid[] = {0x55, 0x1d, 0x13};
+ EXPECT_EQ(der::Input(kExpectedOid), extension.oid);
+
+ const uint8_t kExpectedValue[] = {0x30, 0x00};
+ EXPECT_EQ(der::Input(kExpectedValue), extension.value);
+}
+
+// Parses an Extension whose critical field is false (omitted).
+TEST(ParseExtensionTest, NotCritical) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_TRUE(
+ ParseExtensionFromFile("extension_not_critical.pem", &extension, &data));
+
+ EXPECT_FALSE(extension.critical);
+
+ const uint8_t kExpectedOid[] = {0x55, 0x1d, 0x13};
+ EXPECT_EQ(der::Input(kExpectedOid), extension.oid);
+
+ const uint8_t kExpectedValue[] = {0x30, 0x00};
+ EXPECT_EQ(der::Input(kExpectedValue), extension.value);
+}
+
+// Parses an Extension whose critical field is 0. This is in one sense FALSE,
+// however because critical has DEFAULT of false this is in fact invalid
+// DER-encoding.
+TEST(ParseExtensionTest, Critical0) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_FALSE(
+ ParseExtensionFromFile("extension_critical_0.pem", &extension, &data));
+}
+
+// Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN
+// values must an octet of either all zero bits, or all 1 bits, so this is not
+// valid.
+TEST(ParseExtensionTest, Critical3) {
+ std::string data;
+ ParsedExtension extension;
+ ASSERT_FALSE(
+ ParseExtensionFromFile("extension_critical_3.pem", &extension, &data));
+}
+
+// Runs a test for extensions parsing. The input file is a PEM file which
+// contains a DER-encoded Extensions sequence, as well as the expected value
+// for each contained extension.
+void EnsureParsingExtensionsSucceeds(
+ const std::string& file_name,
+ std::map<der::Input, ParsedExtension>* extensions,
+ std::string* data) {
+ const PemBlockMapping mappings[] = {
+ // Test Input.
+ {"EXTENSIONS", data},
+ };
+
+ ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ ASSERT_TRUE(ParseExtensions(der::Input(data), extensions));
+}
+
+// Runs a test that verifies extensions parsing fails. The input file is a PEM
+// file which contains a DER-encoded Extensions sequence.
+void EnsureParsingExtensionsFails(const std::string& file_name) {
+ std::string data;
+
+ const PemBlockMapping mappings[] = {
+ {"EXTENSIONS", &data},
+ };
+
+ std::map<der::Input, ParsedExtension> extensions;
+ ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ ASSERT_FALSE(ParseExtensions(der::Input(&data), &extensions));
+}
+
+// Parses an Extensions that is an empty sequence.
+TEST(ParseExtensionsTest, EmptySequence) {
+ EnsureParsingExtensionsFails("extensions_empty_sequence.pem");
+}
+
+// Parses an Extensions that is not a sequence.
+TEST(ParseExtensionsTest, NotSequence) {
+ EnsureParsingExtensionsFails("extensions_not_sequence.pem");
+}
+
+// Parses an Extensions that has data after the sequence.
+TEST(ParseExtensionsTest, DataAfterSequence) {
+ EnsureParsingExtensionsFails("extensions_data_after_sequence.pem");
+}
+
+// Parses an Extensions that contains duplicated key usages.
+TEST(ParseExtensionsTest, DuplicateKeyUsage) {
+ EnsureParsingExtensionsFails("extensions_duplicate_key_usage.pem");
+}
+
+// Parses an Extensions that contains an unknown critical extension.
+TEST(ParseExtensionsTest, UnknownCritical) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_unknown_critical.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+ // This OID corresponds with
+ // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid)
+ const uint8_t oid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12,
+ 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
+
+ auto iter = extensions.find(der::Input(oid));
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains an unknown non-critical extension.
+TEST(ParseExtensionsTest, UnknownNonCritical) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_unknown_non_critical.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+ // This OID corresponds with
+ // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid)
+ const uint8_t oid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12,
+ 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
+
+ auto iter = extensions.find(der::Input(oid));
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a basic constraints.
+TEST(ParseExtensionsTest, BasicConstraints) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_basic_constraints.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(BasicConstraintsOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(2u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains an extended key usages.
+TEST(ParseExtensionsTest, ExtendedKeyUsage) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_extended_key_usage.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(ExtKeyUsageOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(45u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a key usage.
+TEST(ParseExtensionsTest, KeyUsage) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_key_usage.pem", &extensions,
+ &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(KeyUsageOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a policies extension.
+TEST(ParseExtensionsTest, Policies) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_policies.pem", &extensions,
+ &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(CertificatePoliciesOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(95u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a subjectaltname extension.
+TEST(ParseExtensionsTest, SubjectAltName) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_subject_alt_name.pem",
+ &extensions, &data);
+
+ ASSERT_EQ(1u, extensions.size());
+
+ auto iter = extensions.find(SubjectAltNameOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(23u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains multiple extensions, sourced from a
+// real-world certificate.
+TEST(ParseExtensionsTest, Real) {
+ std::string data;
+ std::map<der::Input, ParsedExtension> extensions;
+ EnsureParsingExtensionsSucceeds("extensions_real.pem", &extensions, &data);
+
+ ASSERT_EQ(7u, extensions.size());
+
+ auto iter = extensions.find(KeyUsageOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(4u, iter->second.value.Length());
+
+ iter = extensions.find(BasicConstraintsOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_TRUE(iter->second.critical);
+ EXPECT_EQ(8u, iter->second.value.Length());
+
+ iter = extensions.find(CertificatePoliciesOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(16u, iter->second.value.Length());
+
+ // TODO(eroman): Verify the other 4 extensions' values.
+}
+
+// Reads a PEM file containing a block "BASIC CONSTRAINTS". This input will
+// be passed to ParseExtension, and the results filled in |out|.
+bool ParseBasicConstraintsFromFile(const std::string& file_name,
+ ParsedBasicConstraints* out) {
+ std::string data;
+ const PemBlockMapping mappings[] = {
+ {"BASIC CONSTRAINTS", &data},
+ };
+
+ EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
+ return ParseBasicConstraints(der::Input(&data), out);
+}
+
+// Parses a BasicConstraints with no CA or pathlen.
+TEST(ParseBasicConstraintsTest, NotCa) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_not_ca.pem",
+ &constraints));
+ EXPECT_FALSE(constraints.is_ca);
+ EXPECT_FALSE(constraints.has_path_len);
+}
+
+// Parses a BasicConstraints with CA but no pathlen.
+TEST(ParseBasicConstraintsTest, CaNoPath) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_no_path.pem",
+ &constraints));
+ EXPECT_TRUE(constraints.is_ca);
+ EXPECT_FALSE(constraints.has_path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 9.
+TEST(ParseBasicConstraintsTest, CaPath9) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_path_9.pem",
+ &constraints));
+ EXPECT_TRUE(constraints.is_ca);
+ EXPECT_TRUE(constraints.has_path_len);
+ EXPECT_EQ(9u, constraints.path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size).
+TEST(ParseBasicConstraintsTest, Pathlen255) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_pathlen_255.pem",
+ &constraints));
+ EXPECT_TRUE(constraints.is_ca);
+ EXPECT_TRUE(constraints.has_path_len);
+ EXPECT_EQ(255, constraints.path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 256 (too large).
+TEST(ParseBasicConstraintsTest, Pathlen256) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_pathlen_256.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA and a negative pathlen.
+TEST(ParseBasicConstraintsTest, NegativePath) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_negative_path.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA and pathlen that is very large (and
+// couldn't fit in a 64-bit integer).
+TEST(ParseBasicConstraintsTest, PathTooLarge) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_path_too_large.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA explicitly set to false. This violates
+// DER-encoding rules, however is commonly used, so it is accepted.
+TEST(ParseBasicConstraintsTest, CaFalse) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_false.pem",
+ &constraints));
+ EXPECT_FALSE(constraints.is_ca);
+ EXPECT_FALSE(constraints.has_path_len);
+}
+
+// Parses a BasicConstraints with CA set to true and an unexpected NULL at
+// the end.
+TEST(ParseBasicConstraintsTest, UnconsumedData) {
+ ParsedBasicConstraints constraints;
+ ASSERT_FALSE(ParseBasicConstraintsFromFile(
+ "basic_constraints_unconsumed_data.pem", &constraints));
+}
+
+// Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1.
+// This is valid DER for the ASN.1, however is not valid when interpreting the
+// BasicConstraints at a higher level.
+TEST(ParseBasicConstraintsTest, PathLenButNotCa) {
+ ParsedBasicConstraints constraints;
+ ASSERT_TRUE(ParseBasicConstraintsFromFile(
+ "basic_constraints_pathlen_not_ca.pem", &constraints));
+ EXPECT_FALSE(constraints.is_ca);
+ EXPECT_TRUE(constraints.has_path_len);
+ EXPECT_EQ(1u, constraints.path_len);
+}
+
+// Parses a KeyUsage with a single 0 bit.
+TEST(ParseKeyUsageTest, OneBitAllZeros) {
+ const uint8_t der[] = {
+ 0x03, 0x02, // BIT STRING
+ 0x07, // Number of unused bits
+ 0x00, // bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
+}
+
+// Parses a KeyUsage with 32 bits that are all 0.
+TEST(ParseKeyUsageTest, 32BitsAllZeros) {
+ const uint8_t der[] = {
+ 0x03, 0x05, // BIT STRING
+ 0x00, // Number of unused bits
+ 0x00, 0x00, 0x00, 0x00,
+ };
+
+ der::BitString key_usage;
+ ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
+}
+
+// Parses a KeyUsage with 32 bits, one of which is 1 (but not in recognized
+// set).
+TEST(ParseKeyUsageTest, 32BitsOneSet) {
+ const uint8_t der[] = {
+ 0x03, 0x05, // BIT STRING
+ 0x00, // Number of unused bits
+ 0x00, 0x00, 0x00, 0x02,
+ };
+
+ der::BitString key_usage;
+ ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));
+
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
+}
+
+// Parses a KeyUsage containing bit string 101.
+TEST(ParseKeyUsageTest, ThreeBits) {
+ const uint8_t der[] = {
+ 0x03, 0x02, // BIT STRING
+ 0x05, // Number of unused bits
+ 0xA0, // bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));
+
+ EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
+ EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
+}
+
+// Parses a KeyUsage containing DECIPHER_ONLY, which is the
+// only bit that doesn't fit in the first byte.
+TEST(ParseKeyUsageTest, DecipherOnly) {
+ const uint8_t der[] = {
+ 0x03, 0x03, // BIT STRING
+ 0x07, // Number of unused bits
+ 0x00, 0x80, // bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_TRUE(ParseKeyUsage(der::Input(der), &key_usage));
+
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_NON_REPUDIATION));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_DATA_ENCIPHERMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_AGREEMENT));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_CRL_SIGN));
+ EXPECT_FALSE(key_usage.AssertsBit(KEY_USAGE_BIT_ENCIPHER_ONLY));
+ EXPECT_TRUE(key_usage.AssertsBit(KEY_USAGE_BIT_DECIPHER_ONLY));
+}
+
+// Parses an empty KeyUsage.
+TEST(ParseKeyUsageTest, Empty) {
+ const uint8_t der[] = {
+ 0x03, 0x01, // BIT STRING
+ 0x00, // Number of unused bits
+ };
+
+ der::BitString key_usage;
+ ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/cert/internal/signature_algorithm.cc b/chromium/net/cert/internal/signature_algorithm.cc
index 468fa16c3a6..38158fce771 100644
--- a/chromium/net/cert/internal/signature_algorithm.cc
+++ b/chromium/net/cert/internal/signature_algorithm.cc
@@ -4,6 +4,8 @@
#include "net/cert/internal/signature_algorithm.h"
+#include <utility>
+
#include "base/numerics/safe_math.h"
#include "net/der/input.h"
#include "net/der/parse_values.h"
@@ -540,10 +542,6 @@ RsaPssParameters::RsaPssParameters(DigestAlgorithm mgf1_hash,
: mgf1_hash_(mgf1_hash), salt_length_(salt_length) {
}
-bool RsaPssParameters::Equals(const RsaPssParameters* other) const {
- return mgf1_hash_ == other->mgf1_hash_ && salt_length_ == other->salt_length_;
-}
-
SignatureAlgorithm::~SignatureAlgorithm() {
}
@@ -611,34 +609,6 @@ scoped_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateRsaPss(
make_scoped_ptr(new RsaPssParameters(mgf1_hash, salt_length))));
}
-bool SignatureAlgorithm::Equals(const SignatureAlgorithm& other) const {
- if (algorithm_ != other.algorithm_)
- return false;
-
- if (digest_ != other.digest_)
- return false;
-
- // Check that the parameters are equal.
- switch (algorithm_) {
- case SignatureAlgorithmId::RsaPss: {
- const RsaPssParameters* params1 = ParamsForRsaPss();
- const RsaPssParameters* params2 = other.ParamsForRsaPss();
- if (!params1 || !params2 || !params1->Equals(params2))
- return false;
- break;
- }
-
- // There shouldn't be any parameters.
- case SignatureAlgorithmId::RsaPkcs1:
- case SignatureAlgorithmId::Ecdsa:
- if (params_ || other.params_)
- return false;
- break;
- }
-
- return true;
-}
-
const RsaPssParameters* SignatureAlgorithm::ParamsForRsaPss() const {
if (algorithm_ == SignatureAlgorithmId::RsaPss)
return static_cast<RsaPssParameters*>(params_.get());
@@ -649,7 +619,6 @@ SignatureAlgorithm::SignatureAlgorithm(
SignatureAlgorithmId algorithm,
DigestAlgorithm digest,
scoped_ptr<SignatureAlgorithmParameters> params)
- : algorithm_(algorithm), digest_(digest), params_(params.Pass()) {
-}
+ : algorithm_(algorithm), digest_(digest), params_(std::move(params)) {}
} // namespace net
diff --git a/chromium/net/cert/internal/signature_algorithm.h b/chromium/net/cert/internal/signature_algorithm.h
index 9ecf252d671..de35a297473 100644
--- a/chromium/net/cert/internal/signature_algorithm.h
+++ b/chromium/net/cert/internal/signature_algorithm.h
@@ -7,8 +7,8 @@
#include <stdint.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -53,8 +53,6 @@ class NET_EXPORT RsaPssParameters : public SignatureAlgorithmParameters {
public:
RsaPssParameters(DigestAlgorithm mgf1_hash, uint32_t salt_length);
- bool Equals(const RsaPssParameters* other) const;
-
DigestAlgorithm mgf1_hash() const { return mgf1_hash_; }
uint32_t salt_length() const { return salt_length_; }
@@ -84,10 +82,6 @@ class NET_EXPORT SignatureAlgorithm {
DigestAlgorithm mgf1_hash,
uint32_t salt_length);
- // Returns true if |*this| is equivalent to |other|. This compares both the
- // algorithm ID and each parameter for equality.
- bool Equals(const SignatureAlgorithm& other) const WARN_UNUSED_RESULT;
-
// The following methods retrieve the parameters for the signature algorithm.
//
// The correct parameters should be chosen based on the algorithm ID. For
diff --git a/chromium/net/cert/internal/signature_algorithm_unittest.cc b/chromium/net/cert/internal/signature_algorithm_unittest.cc
index 8cc5517b3e9..32f5a0fc629 100644
--- a/chromium/net/cert/internal/signature_algorithm_unittest.cc
+++ b/chromium/net/cert/internal/signature_algorithm_unittest.cc
@@ -485,106 +485,6 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA512NullParams) {
ASSERT_FALSE(ParseDer(kData, &algorithm));
}
-// Tests that two RSA algorithms with different digests are not equal.
-TEST(SignatureAlgorithmTest, EqualsRsaWithDifferentDigest) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha1);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha256);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two ECDSA algorithms with different digests are not equal.
-TEST(SignatureAlgorithmTest, EqualsEcdsaWithDifferentDigest) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha1);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that an ECDSA algorithm is not equal to an RSA algorithm (even though
-// digests match).
-TEST(SignatureAlgorithmTest, EqualsEcdsaNotEqualRsa) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha256);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two identical ECDSA algorithms are equal - both use SHA-256.
-TEST(SignatureAlgorithmTest, EqualsEcdsaMatch) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha256);
-
- ASSERT_TRUE(alg1->Equals(*alg2));
-}
-
-// Tests that two identical RSA algorithms are equal - both use SHA-512
-TEST(SignatureAlgorithmTest, EqualsRsaPkcs1Match) {
- scoped_ptr<SignatureAlgorithm> alg1 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha512);
-
- scoped_ptr<SignatureAlgorithm> alg2 =
- SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha512);
-
- ASSERT_TRUE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms are equal.
-TEST(SignatureAlgorithmTest, EqualsRsaPssMatch) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 21);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 21);
-
- ASSERT_TRUE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms with different hashes are not equal.
-TEST(SignatureAlgorithmTest, EqualsRsaPssWithDifferentDigest) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha1, DigestAlgorithm::Sha1, 20);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 20);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms with different mask gens are not equal.
-TEST(SignatureAlgorithmTest, EqualsRsaPssWithDifferentMaskGen) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha1, 20);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha256, DigestAlgorithm::Sha256, 20);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
-// Tests that two RSASSA-PSS algorithms with different salts
-TEST(SignatureAlgorithmTest, EqualsRsaPssWithDifferentSalt) {
- scoped_ptr<SignatureAlgorithm> alg1 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha1, DigestAlgorithm::Sha1, 20);
-
- scoped_ptr<SignatureAlgorithm> alg2 = SignatureAlgorithm::CreateRsaPss(
- DigestAlgorithm::Sha1, DigestAlgorithm::Sha1, 16);
-
- ASSERT_FALSE(alg1->Equals(*alg2));
-}
-
// Tests that the parmeters returned for an ECDSA algorithm are null for
// non-ECDSA algorithms.
TEST(SignatureAlgorithmTest, ParamsAreNullForWrongTypeEcdsa) {
diff --git a/chromium/net/cert/internal/signature_policy.h b/chromium/net/cert/internal/signature_policy.h
index 72ff945ed2c..3acf17b9ea6 100644
--- a/chromium/net/cert/internal/signature_policy.h
+++ b/chromium/net/cert/internal/signature_policy.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_INTERNAL_SIGNATURE_POLICY_H_
#define NET_CERT_INTERNAL_SIGNATURE_POLICY_H_
+#include <stddef.h>
+
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/cert/internal/signature_algorithm.h"
diff --git a/chromium/net/cert/internal/test_helpers.cc b/chromium/net/cert/internal/test_helpers.cc
index 0b5363d8acc..4194ae3e6a4 100644
--- a/chromium/net/cert/internal/test_helpers.cc
+++ b/chromium/net/cert/internal/test_helpers.cc
@@ -9,6 +9,8 @@
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "net/cert/pem_tokenizer.h"
+#include "net/der/parser.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -30,8 +32,18 @@ bool operator==(const Input& a, const Input& b) {
} // namespace der
-der::Input InputFromString(const std::string* s) {
- return der::Input(reinterpret_cast<const uint8_t*>(s->data()), s->size());
+der::Input SequenceValueFromString(const std::string* s) {
+ der::Parser parser((der::Input(s)));
+ der::Input data;
+ if (!parser.ReadTag(der::kSequence, &data)) {
+ ADD_FAILURE();
+ return der::Input();
+ }
+ if (parser.HasMore()) {
+ ADD_FAILURE();
+ return der::Input();
+ }
+ return data;
}
::testing::AssertionResult ReadTestDataFromPemFile(
diff --git a/chromium/net/cert/internal/test_helpers.h b/chromium/net/cert/internal/test_helpers.h
index d10148191a4..a1b3d8045ee 100644
--- a/chromium/net/cert/internal/test_helpers.h
+++ b/chromium/net/cert/internal/test_helpers.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_INTERNAL_TEST_HELPERS_H_
#define NET_CERT_INTERNAL_TEST_HELPERS_H_
+#include <stddef.h>
+
#include <ostream>
#include <string>
#include <vector>
@@ -23,15 +25,13 @@ bool operator==(const Input& a, const Input& b);
} // namespace der
-// Creates a der::Input from an std::string. The lifetimes are a bit subtle
-// when using this function:
+// Parses |s| as a DER SEQUENCE TLV and returns a der::Input corresponding to
+// the value portion. On error returns an empty der::Input and adds a gtest
+// failure.
//
// The returned der::Input() is only valid so long as the input string is alive
// and is not mutated.
-//
-// Note that the input parameter has been made a pointer to prevent callers
-// from accidentally passing an r-value.
-der::Input InputFromString(const std::string* s);
+der::Input SequenceValueFromString(const std::string* s);
// Helper structure that maps a PEM block header (for instance "CERTIFICATE") to
// the destination where the value for that block should be written.
diff --git a/chromium/net/cert/internal/verify_certificate_chain.cc b/chromium/net/cert/internal/verify_certificate_chain.cc
new file mode 100644
index 00000000000..524de925d3e
--- /dev/null
+++ b/chromium/net/cert/internal/verify_certificate_chain.cc
@@ -0,0 +1,549 @@
+// Copyright 2015 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/internal/verify_certificate_chain.h"
+
+#include "base/logging.h"
+#include "net/cert/internal/parse_certificate.h"
+#include "net/cert/internal/signature_algorithm.h"
+#include "net/cert/internal/signature_policy.h"
+#include "net/cert/internal/verify_name_match.h"
+#include "net/cert/internal/verify_signed_data.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+
+namespace net {
+
+namespace {
+
+// Map from OID to ParsedExtension.
+using ExtensionsMap = std::map<der::Input, ParsedExtension>;
+
+// Describes all parsed properties of a certificate that are relevant for
+// certificate verification.
+struct FullyParsedCert {
+ ParsedCertificate cert;
+ ParsedTbsCertificate tbs;
+
+ scoped_ptr<SignatureAlgorithm> signature_algorithm;
+
+ // Standard extensions that were parsed.
+ bool has_basic_constraints = false;
+ ParsedBasicConstraints basic_constraints;
+
+ bool has_key_usage = false;
+ der::BitString key_usage;
+
+ // The remaining extensions (excludes the standard ones above).
+ ExtensionsMap unconsumed_extensions;
+};
+
+// Removes the extension with OID |oid| from |unconsumed_extensions| and fills
+// |extension| with the matching extension value. If there was no extension
+// matching |oid| then returns |false|.
+WARN_UNUSED_RESULT bool ConsumeExtension(const der::Input& oid,
+ ExtensionsMap* unconsumed_extensions,
+ ParsedExtension* extension) {
+ auto it = unconsumed_extensions->find(oid);
+ if (it == unconsumed_extensions->end())
+ return false;
+
+ *extension = it->second;
+ unconsumed_extensions->erase(it);
+ return true;
+}
+
+// Returns true if the certificate does not contain any unconsumed _critical_
+// extensions.
+WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions(
+ const FullyParsedCert& cert) {
+ for (const auto& entry : cert.unconsumed_extensions) {
+ if (entry.second.critical)
+ return false;
+ }
+ return true;
+}
+
+// Parses an X.509 Certificate fully (including the TBSCertificate and
+// standard extensions), saving all the properties to |out_|.
+WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv,
+ FullyParsedCert* out) {
+ // Parse the outer Certificate.
+ if (!ParseCertificate(cert_tlv, &out->cert))
+ return false;
+
+ // Parse the signature algorithm contained in the Certificate (there is
+ // another one in the TBSCertificate, which is checked later by
+ // VerifySignatureAlgorithmsMatch)
+ out->signature_algorithm =
+ SignatureAlgorithm::CreateFromDer(out->cert.signature_algorithm_tlv);
+ if (!out->signature_algorithm)
+ return false;
+
+ // Parse the TBSCertificate.
+ if (!ParseTbsCertificate(out->cert.tbs_certificate_tlv, &out->tbs))
+ return false;
+
+ // Reset state relating to extensions (which may not get overwritten). This is
+ // just a precaution, since in practice |out| will already be default
+ // initialize.
+ out->has_basic_constraints = false;
+ out->has_key_usage = false;
+ out->unconsumed_extensions.clear();
+
+ // Parse the standard X.509 extensions and remove them from
+ // |unconsumed_extensions|.
+ if (out->tbs.has_extensions) {
+ // ParseExtensions() ensures there are no duplicates, and maps the (unique)
+ // OID to the extension value.
+ if (!ParseExtensions(out->tbs.extensions_tlv, &out->unconsumed_extensions))
+ return false;
+
+ ParsedExtension extension;
+
+ // Basic constraints.
+ if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions,
+ &extension)) {
+ out->has_basic_constraints = true;
+ if (!ParseBasicConstraints(extension.value, &out->basic_constraints))
+ return false;
+ }
+
+ // KeyUsage.
+ if (ConsumeExtension(KeyUsageOid(), &out->unconsumed_extensions,
+ &extension)) {
+ out->has_key_usage = true;
+ if (!ParseKeyUsage(extension.value, &out->key_usage))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
+ der::Input* value) {
+ der::Parser parser(tlv);
+ return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
+}
+
+// Returns true if |name1_tlv| matches |name2_tlv|. The two inputs must be
+// tag-length-value for RFC 5280's Name.
+WARN_UNUSED_RESULT bool NameMatches(const der::Input& name1_tlv,
+ const der::Input& name2_tlv) {
+ der::Input name1_value;
+ der::Input name2_value;
+
+ // Assume that the Name is an RDNSequence. VerifyNameMatch() expects the
+ // value from a SEQUENCE, so strip off the tag.
+ if (!GetSequenceValue(name1_tlv, &name1_value) ||
+ !GetSequenceValue(name2_tlv, &name2_value)) {
+ return false;
+ }
+
+ return VerifyNameMatch(name1_value, name2_value);
+}
+
+// Returns true if |cert| was self-issued. The definition of self-issuance
+// comes from RFC 5280 section 6.1:
+//
+// A certificate is self-issued if the same DN appears in the subject
+// and issuer fields (the two DNs are the same if they match according
+// to the rules specified in Section 7.1). In general, the issuer and
+// subject of the certificates that make up a path are different for
+// each certificate. However, a CA may issue a certificate to itself to
+// support key rollover or changes in certificate policies. These
+// self-issued certificates are not counted when evaluating path length
+// or name constraints.
+WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) {
+ return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv);
+}
+
+// Finds a trust anchor that matches |name| in |trust_store| or returns
+// nullptr. The returned pointer references data in |trust_store|.
+//
+// TODO(eroman): This implementation is linear in the size of the trust store,
+// and also presumes that all names are unique. In practice it is possible to
+// have multiple SPKIs with the same name. Also this mechanism of
+// searching is fairly primitive, and does not take advantage of other
+// properties like the authority key id.
+WARN_UNUSED_RESULT const TrustAnchor* FindTrustAnchorByName(
+ const TrustStore& trust_store,
+ const der::Input& name) {
+ for (const auto& anchor : trust_store.anchors) {
+ if (NameMatches(name, der::Input(&anchor.name)))
+ return &anchor;
+ }
+ return nullptr;
+}
+
+// Returns true if |cert| is valid at time |time|.
+//
+// The certificate's validity requirements are described by RFC 5280 section
+// 4.1.2.5:
+//
+// The validity period for a certificate is the period of time from
+// notBefore through notAfter, inclusive.
+WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert,
+ const der::GeneralizedTime time) {
+ return !(time < cert.tbs.validity_not_before) &&
+ !(cert.tbs.validity_not_after < time);
+}
+
+// Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for
+// RSA with SHA1.
+WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm(
+ const der::Input& signature_algorithm_tlv) {
+ scoped_ptr<SignatureAlgorithm> algorithm =
+ SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv);
+
+ return algorithm &&
+ algorithm->algorithm() == SignatureAlgorithmId::RsaPkcs1 &&
+ algorithm->digest() == DigestAlgorithm::Sha1;
+}
+
+// Returns true if |cert| has internally consistent signature algorithms.
+//
+// X.509 certificates contain two different signature algorithms:
+// (1) The signatureAlgorithm field of Certificate
+// (2) The signature field of TBSCertificate
+//
+// According to RFC 5280 section 4.1.1.2 and 4.1.2.3 these two fields must be
+// equal:
+//
+// This field MUST contain the same algorithm identifier as the
+// signature field in the sequence tbsCertificate (Section 4.1.2.3).
+//
+// The spec is not explicit about what "the same algorithm identifier" means.
+// Our interpretation is that the two DER-encoded fields must be byte-for-byte
+// identical.
+//
+// In practice however there are certificates which use different encodings for
+// specifying RSA with SHA1 (different OIDs). This is special-cased for
+// compatibility sake.
+WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch(
+ const FullyParsedCert& cert) {
+ const der::Input& alg1_tlv = cert.cert.signature_algorithm_tlv;
+ const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv;
+
+ // Ensure that the two DER-encoded signature algorithms are byte-for-byte
+ // equal, but make a compatibility concession for RSA with SHA1.
+ return alg1_tlv.Equals(alg2_tlv) ||
+ (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) &&
+ IsRsaWithSha1SignatureAlgorithm(alg2_tlv));
+}
+
+// This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate
+// Processing" procedure.
+WARN_UNUSED_RESULT bool BasicCertificateProcessing(
+ const FullyParsedCert& cert,
+ const SignaturePolicy* signature_policy,
+ const der::GeneralizedTime& time,
+ const der::Input& working_spki,
+ const der::Input& working_issuer_name) {
+ // Check that the signature algorithms in Certificate vs TBSCertificate
+ // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by
+ // sections 4.1.1.2 and 4.1.2.3.
+ if (!VerifySignatureAlgorithmsMatch(cert))
+ return false;
+
+ // Verify the digital signature using the previous certificate's (or trust
+ // anchor's) key (RFC 5280 section 6.1.3 step a.1).
+ if (!VerifySignedData(
+ *cert.signature_algorithm, cert.cert.tbs_certificate_tlv,
+ cert.cert.signature_value, working_spki, signature_policy)) {
+ return false;
+ }
+
+ // Check the time range for the certificate's validity, ensuring it is valid
+ // at |time|.
+ // (RFC 5280 section 6.1.3 step a.2)
+ if (!VerifyTimeValidity(cert, time))
+ return false;
+
+ // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3)
+
+ // Verify the certificate's issuer name matches the issuing certificate's (or
+ // trust anchor's) subject name. (RFC 5280 section 6.1.3 step a.4)
+ if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name))
+ return false;
+
+ // TODO(eroman): Steps b-f are omitted, as policy/name constraints are not yet
+ // implemented.
+
+ return true;
+}
+
+// This function corresponds to RFC 5280 section 6.1.4's "Preparation for
+// Certificate i+1" procedure. |cert| is expected to be an intermediary.
+WARN_UNUSED_RESULT bool PrepareForNextCertificate(
+ const FullyParsedCert& cert,
+ size_t* max_path_length_ptr,
+ der::Input* working_spki,
+ der::Input* working_issuer_name) {
+ // TODO(eroman): Steps a-b are omitted, as policy/name constraints are not yet
+ // implemented.
+
+ // From RFC 5280 section 6.1.4 step c:
+ //
+ // Assign the certificate subject name to working_issuer_name.
+ *working_issuer_name = cert.tbs.subject_tlv;
+
+ // From RFC 5280 section 6.1.4 step d:
+ //
+ // Assign the certificate subjectPublicKey to working_public_key.
+ *working_spki = cert.tbs.spki_tlv;
+
+ // Note that steps e and f are omitted as they are handled by
+ // the assignment to |working_spki| above. See the definition
+ // of |working_spki|.
+
+ // TODO(eroman): Steps g-j are omitted as policy/name constraints are not yet
+ // implemented.
+
+ // From RFC 5280 section 6.1.4 step k:
+ //
+ // If certificate i is a version 3 certificate, verify that the
+ // basicConstraints extension is present and that cA is set to
+ // TRUE. (If certificate i is a version 1 or version 2
+ // certificate, then the application MUST either verify that
+ // certificate i is a CA certificate through out-of-band means
+ // or reject the certificate. Conforming implementations may
+ // choose to reject all version 1 and version 2 intermediate
+ // certificates.)
+ //
+ // This code implicitly rejects non version 3 intermediaries, since they
+ // can't contain a BasicConstraints extension.
+ if (!cert.has_basic_constraints || !cert.basic_constraints.is_ca)
+ return false;
+
+ // From RFC 5280 section 6.1.4 step l:
+ //
+ // If the certificate was not self-issued, verify that
+ // max_path_length is greater than zero and decrement
+ // max_path_length by 1.
+ if (!IsSelfIssued(cert)) {
+ if (*max_path_length_ptr == 0)
+ return false;
+ --(*max_path_length_ptr);
+ }
+
+ // From RFC 5280 section 6.1.4 step m:
+ //
+ // If pathLenConstraint is present in the certificate and is
+ // less than max_path_length, set max_path_length to the value
+ // of pathLenConstraint.
+ if (cert.basic_constraints.has_path_len &&
+ cert.basic_constraints.path_len < *max_path_length_ptr) {
+ *max_path_length_ptr = cert.basic_constraints.path_len;
+ }
+
+ // From RFC 5280 section 6.1.4 step n:
+ //
+ // If a key usage extension is present, verify that the
+ // keyCertSign bit is set.
+ if (cert.has_key_usage &&
+ !cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) {
+ return false;
+ }
+
+ // From RFC 5280 section 6.1.4 step o:
+ //
+ // Recognize and process any other critical extension present in
+ // the certificate. Process any other recognized non-critical
+ // extension present in the certificate that is relevant to path
+ // processing.
+ if (!VerifyNoUnconsumedCriticalExtensions(cert))
+ return false;
+
+ return true;
+}
+
+// Checks that if the target certificate has properties that only a CA should
+// have (keyCertSign, CA=true, pathLenConstraint), then its other properties
+// are consistent with being a CA.
+//
+// This follows from some requirements in RFC 5280 section 4.2.1.9. In
+// particular:
+//
+// CAs MUST NOT include the pathLenConstraint field unless the cA
+// boolean is asserted and the key usage extension asserts the
+// keyCertSign bit.
+//
+// And:
+//
+// If the cA boolean is not asserted, then the keyCertSign bit in the key
+// usage extension MUST NOT be asserted.
+//
+// TODO(eroman): Strictly speaking the first requirement is on CAs and not the
+// certificate client, so could be skipped.
+//
+// TODO(eroman): I don't believe Firefox enforces the keyCertSign restriction
+// for compatibility reasons. Investigate if we need to similarly relax this
+// constraint.
+WARN_UNUSED_RESULT bool VerifyTargetCertHasConsistentCaBits(
+ const FullyParsedCert& cert) {
+ // Check if the certificate contains any property specific to CAs.
+ bool has_ca_property =
+ (cert.has_basic_constraints &&
+ (cert.basic_constraints.is_ca || cert.basic_constraints.has_path_len)) ||
+ (cert.has_key_usage &&
+ cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+
+ // If it "looks" like a CA because it has a CA-only property, then check that
+ // it sets ALL the properties expected of a CA.
+ if (has_ca_property) {
+ return cert.has_basic_constraints && cert.basic_constraints.is_ca &&
+ (!cert.has_key_usage ||
+ cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
+ }
+
+ return true;
+}
+
+// This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure".
+// It does processing for the final certificate (the target cert).
+WARN_UNUSED_RESULT bool WrapUp(const FullyParsedCert& cert) {
+ // TODO(eroman): Steps a-c are omitted as policy/name constraints are not yet
+ // implemented.
+
+ // Note step c-e are omitted the verification function does
+ // not output the working public key.
+
+ // From RFC 5280 section 6.1.5 step f:
+ //
+ // Recognize and process any other critical extension present in
+ // the certificate n. Process any other recognized non-critical
+ // extension present in certificate n that is relevant to path
+ // processing.
+ //
+ // Note that this is duplicated by PrepareForNextCertificate() so as to
+ // directly match the procedures in RFC 5280's section 6.1.
+ if (!VerifyNoUnconsumedCriticalExtensions(cert))
+ return false;
+
+ // TODO(eroman): Step g is omitted, as policy constraints are not yet
+ // implemented.
+
+ // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure",
+ // however is implied by RFC 5280 section 4.2.1.9.
+ if (!VerifyTargetCertHasConsistentCaBits(cert))
+ return false;
+
+ return true;
+}
+
+} // namespace
+
+TrustAnchor::~TrustAnchor() {}
+
+TrustStore::TrustStore() {}
+TrustStore::~TrustStore() {}
+
+// This implementation is structured to mimic the description of certificate
+// path verification given by RFC 5280 section 6.1.
+bool VerifyCertificateChain(const std::vector<der::Input>& certs_der,
+ const TrustStore& trust_store,
+ const SignaturePolicy* signature_policy,
+ const der::GeneralizedTime& time) {
+ // An empty chain is necessarily invalid.
+ if (certs_der.empty())
+ return false;
+
+ // |working_spki| is an amalgamation of 3 separate variables from RFC 5280:
+ // * working_public_key
+ // * working_public_key_algorithm
+ // * working_public_key_parameters
+ //
+ // They are combined for simplicity since the signature verification takes an
+ // SPKI, and the parameter inheritence is not applicable for the supported
+ // key types.
+ //
+ // An approximate explanation of |working_spki| is this description from RFC
+ // 5280 section 6.1.2:
+ //
+ // working_public_key: the public key used to verify the
+ // signature of a certificate. The working_public_key is
+ // initialized from the trusted public key provided in the trust
+ // anchor information.
+ der::Input working_spki;
+
+ // |working_issuer_name| corresponds with the same named variable in RFC 5280
+ // section 6.1.2:
+ //
+ // working_issuer_name: the issuer distinguished name expected
+ // in the next certificate in the chain. The
+ // working_issuer_name is initialized to the trusted issuer name
+ // provided in the trust anchor information.
+ der::Input working_issuer_name;
+
+ // |max_path_length| corresponds with the same named variable in RFC 5280
+ // section 6.1.2:
+ //
+ // max_path_length: this integer is initialized to n, is
+ // decremented for each non-self-issued certificate in the path,
+ // and may be reduced to the value in the path length constraint
+ // field within the basic constraints extension of a CA
+ // certificate.
+ size_t max_path_length = certs_der.size();
+
+ // Iterate over all the certificates in the reverse direction: starting from
+ // the trust anchor and progressing towards the target certificate.
+ //
+ // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based.
+ //
+ // * i=0 : Certificate signed by a trust anchor.
+ // * i=N-1 : Target certificate.
+ for (size_t i = 0; i < certs_der.size(); ++i) {
+ const size_t index_into_certs_der = certs_der.size() - i - 1;
+ const bool is_target_cert = index_into_certs_der == 0;
+
+ // Parse the current certificate into |cert|.
+ FullyParsedCert cert;
+ const der::Input& cert_der = certs_der[index_into_certs_der];
+ if (!FullyParseCertificate(cert_der, &cert))
+ return false;
+
+ // When processing the first certificate, initialize |working_spki|
+ // and |working_issuer_name| to the trust anchor per RFC 5280 section 6.1.2.
+ // This is done inside the loop in order to have access to the parsed
+ // certificate.
+ if (i == 0) {
+ const TrustAnchor* trust_anchor =
+ FindTrustAnchorByName(trust_store, cert.tbs.issuer_tlv);
+ if (!trust_anchor)
+ return false;
+ working_spki = der::Input(&trust_anchor->spki);
+ working_issuer_name = der::Input(&trust_anchor->name);
+ }
+
+ // Per RFC 5280 section 6.1:
+ // * Do basic processing for each certificate
+ // * If it is the last certificate in the path (target certificate)
+ // - Then run "Wrap up"
+ // - Otherwise run "Prepare for Next cert"
+ if (!BasicCertificateProcessing(cert, signature_policy, time, working_spki,
+ working_issuer_name)) {
+ return false;
+ }
+ if (!is_target_cert) {
+ if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki,
+ &working_issuer_name)) {
+ return false;
+ }
+ } else {
+ if (!WrapUp(cert))
+ return false;
+ }
+ }
+
+ // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
+ //
+ // A certificate MUST NOT appear more than once in a prospective
+ // certification path.
+
+ return true;
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/verify_certificate_chain.h b/chromium/net/cert/internal/verify_certificate_chain.h
new file mode 100644
index 00000000000..8f7e21f8ad6
--- /dev/null
+++ b/chromium/net/cert/internal/verify_certificate_chain.h
@@ -0,0 +1,86 @@
+// Copyright 2015 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_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_
+#define NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace der {
+class Input;
+struct GeneralizedTime;
+}
+
+class SignaturePolicy;
+
+struct NET_EXPORT TrustAnchor {
+ ~TrustAnchor();
+
+ // DER-encoded SubjectPublicKeyInfo for the trusted key.
+ std::string spki;
+
+ // DER-encoded "Name" corresponding to the key.
+ std::string name;
+};
+
+// A very simple implementation of a TrustStore, which contains mappings from
+// names to trusted public keys.
+struct NET_EXPORT TrustStore {
+ TrustStore();
+ ~TrustStore();
+
+ std::vector<TrustAnchor> anchors;
+};
+
+// VerifyCertificateChain() verifies a certificate path (chain) based on the
+// rules in RFC 5280.
+//
+// WARNING: This implementation is in progress, and is currently
+// incomplete. DO NOT USE IT unless its limitations are acceptable for your use.
+//
+// ---------
+// Inputs
+// ---------
+//
+// cert_chain:
+// A non-empty chain of N DER-encoded certificates, listed in the
+// "forward" direction.
+//
+// * cert_chain[0] is the target certificate to verify.
+// * cert_chain[i+1] holds the certificate that issued cert_chain[i].
+// * cert_chain[N-1] must have been issued by a trust anchor
+//
+// trust_store:
+// Contains the set of trusted public keys (and their names).
+//
+// signature_policy:
+// The policy to use when verifying signatures (what hash algorithms are
+// allowed, what length keys, what named curves, etc).
+//
+// time:
+// The UTC time to use for expiration checks.
+//
+// ---------
+// Outputs
+// ---------
+//
+// Returns true if the target certificate can be verified.
+NET_EXPORT bool VerifyCertificateChain(const std::vector<der::Input>& certs_der,
+ const TrustStore& trust_store,
+ const SignaturePolicy* signature_policy,
+ const der::GeneralizedTime& time)
+ WARN_UNUSED_RESULT;
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_
diff --git a/chromium/net/cert/internal/verify_certificate_chain_unittest.cc b/chromium/net/cert/internal/verify_certificate_chain_unittest.cc
new file mode 100644
index 00000000000..c997f5386ef
--- /dev/null
+++ b/chromium/net/cert/internal/verify_certificate_chain_unittest.cc
@@ -0,0 +1,246 @@
+// Copyright 2015 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/internal/verify_certificate_chain.h"
+
+#include "base/base_paths.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "net/cert/internal/parse_certificate.h"
+#include "net/cert/internal/signature_policy.h"
+#include "net/cert/internal/test_helpers.h"
+#include "net/cert/pem_tokenizer.h"
+#include "net/der/input.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// TODO(eroman): Because VerifySignedData() is only implemented for BoringSSL
+// these tests also depend on BoringSSL.
+#if defined(USE_OPENSSL)
+
+namespace net {
+
+namespace {
+
+// Reads a data file from the unit-test data.
+std::string ReadTestFileToString(const std::string& file_name) {
+ // Compute the full path, relative to the src/ directory.
+ base::FilePath src_root;
+ PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
+ base::FilePath filepath = src_root.AppendASCII(
+ std::string("net/data/verify_certificate_chain_unittest/") + file_name);
+
+ // Read the full contents of the file.
+ std::string file_data;
+ if (!base::ReadFileToString(filepath, &file_data)) {
+ ADD_FAILURE() << "Couldn't read file: " << filepath.value();
+ return std::string();
+ }
+
+ return file_data;
+}
+
+// Adds the certificate |cert_der| as a trust anchor to |trust_store|.
+void AddCertificateToTrustStore(const std::string& cert_der,
+ TrustStore* trust_store) {
+ ParsedCertificate cert;
+ ASSERT_TRUE(ParseCertificate(der::Input(&cert_der), &cert));
+
+ ParsedTbsCertificate tbs;
+ ASSERT_TRUE(ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs));
+ TrustAnchor anchor = {tbs.spki_tlv.AsString(), tbs.subject_tlv.AsString()};
+ trust_store->anchors.push_back(anchor);
+}
+
+// Reads a test case from |file_name|. Test cases are comprised of a
+// certificate chain, trust store, a timestamp to validate at, and the
+// expected result of verification.
+void ReadTestFromFile(const std::string& file_name,
+ std::vector<std::string>* chain,
+ TrustStore* trust_store,
+ der::GeneralizedTime* time,
+ bool* verify_result) {
+ chain->clear();
+ *trust_store = TrustStore();
+
+ std::string file_data = ReadTestFileToString(file_name);
+
+ std::vector<std::string> pem_headers;
+
+ const char kCertificateHeader[] = "CERTIFICATE";
+ const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE";
+ const char kTimeHeader[] = "TIME";
+ const char kResultHeader[] = "VERIFY_RESULT";
+
+ pem_headers.push_back(kCertificateHeader);
+ pem_headers.push_back(kTrustedCertificateHeader);
+ pem_headers.push_back(kTimeHeader);
+ pem_headers.push_back(kResultHeader);
+
+ bool has_time = false;
+ bool has_result = false;
+
+ PEMTokenizer pem_tokenizer(file_data, pem_headers);
+ while (pem_tokenizer.GetNext()) {
+ const std::string& block_type = pem_tokenizer.block_type();
+ const std::string& block_data = pem_tokenizer.data();
+
+ if (block_type == kCertificateHeader) {
+ chain->push_back(block_data);
+ } else if (block_type == kTrustedCertificateHeader) {
+ AddCertificateToTrustStore(block_data, trust_store);
+ } else if (block_type == kTimeHeader) {
+ ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader;
+ has_time = true;
+ ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time));
+ } else if (block_type == kResultHeader) {
+ ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader;
+ ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL")
+ << "Unrecognized result: " << block_data;
+ has_result = true;
+ *verify_result = block_data == "SUCCESS";
+ }
+ }
+
+ ASSERT_TRUE(has_time);
+ ASSERT_TRUE(has_result);
+}
+
+void RunTest(const char* file_name) {
+ std::vector<std::string> chain;
+ TrustStore trust_store;
+ der::GeneralizedTime time;
+ bool expected_result;
+
+ ReadTestFromFile(file_name, &chain, &trust_store, &time, &expected_result);
+
+ std::vector<der::Input> input_chain;
+ for (const auto& cert_str : chain)
+ input_chain.push_back(der::Input(&cert_str));
+
+ SimpleSignaturePolicy signature_policy(1024);
+
+ bool result =
+ VerifyCertificateChain(input_chain, trust_store, &signature_policy, time);
+
+ ASSERT_EQ(expected_result, result);
+}
+
+TEST(VerifyCertificateChainTest, TargetAndIntermediary) {
+ RunTest("target-and-intermediary.pem");
+}
+
+TEST(VerifyCertificateChainTest, UnknownRoot) {
+ RunTest("unknown-root.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryLacksBasicConstraints) {
+ RunTest("intermediary-lacks-basic-constraints.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsCaFalse) {
+ RunTest("intermediary-basic-constraints-ca-false.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsNotCritical) {
+ RunTest("intermediary-basic-constraints-not-critical.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryLacksSigningKeyUsage) {
+ RunTest("intermediary-lacks-signing-key-usage.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryUnknownCriticalExtension) {
+ RunTest("intermediary-unknown-critical-extension.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediaryUnknownNonCriticalExtension) {
+ RunTest("intermediary-unknown-non-critical-extension.pem");
+}
+
+TEST(VerifyCertificateChainTest, ViolatesBasicConstraintsPathlen0) {
+ RunTest("violates-basic-constraints-pathlen-0.pem");
+}
+
+TEST(VerifyCertificateChainTest, BasicConstraintsPathlen0SelfIssued) {
+ RunTest("basic-constraints-pathlen-0-self-issued.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetSignedWithMd5) {
+ RunTest("target-signed-with-md5.pem");
+}
+
+TEST(VerifyCertificateChainTest, IntermediarySignedWithMd5) {
+ RunTest("intermediary-signed-with-md5.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetWrongSignature) {
+ RunTest("target-wrong-signature.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetSignedBy512bitRsa) {
+ RunTest("target-signed-by-512bit-rsa.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetSignedUsingEcdsa) {
+ RunTest("target-signed-using-ecdsa.pem");
+}
+
+TEST(VerifyCertificateChainTest, ExpiredIntermediary) {
+ RunTest("expired-intermediary.pem");
+}
+
+TEST(VerifyCertificateChainTest, ExpiredTarget) {
+ RunTest("expired-target.pem");
+}
+
+TEST(VerifyCertificateChainTest, ExpiredTargetNotBefore) {
+ RunTest("expired-target-notBefore.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetNotEndEntity) {
+ RunTest("target-not-end-entity.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetHasKeyCertSignButNotCa) {
+ RunTest("target-has-keycertsign-but-not-ca.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetHasPathlenButNotCa) {
+ RunTest("target-has-pathlen-but-not-ca.pem");
+}
+
+TEST(VerifyCertificateChainTest, TargetUnknownCriticalExtension) {
+ RunTest("target-unknown-critical-extension.pem");
+}
+
+TEST(VerifyCertificateChainTest, IssuerAndSubjectNotByteForByteEqual) {
+ RunTest("issuer-and-subject-not-byte-for-byte-equal.pem");
+}
+
+TEST(VerifyCertificateChainTest, IssuerAndSubjectNotByteForByteEqualAnchor) {
+ RunTest("issuer-and-subject-not-byte-for-byte-equal-anchor.pem");
+}
+
+// Tests that verifying a chain with no certificates fails.
+TEST(VerifyCertificateChainTest, EmptyChainIsInvalid) {
+ TrustStore trust_store;
+ der::GeneralizedTime time;
+ std::vector<der::Input> chain;
+ SimpleSignaturePolicy signature_policy(2048);
+
+ ASSERT_FALSE(
+ VerifyCertificateChain(chain, trust_store, &signature_policy, time));
+}
+
+// TODO(eroman): Add test that invalidate validity dates where the day or month
+// ordinal not in range, like "March 39, 2016" are rejected.
+
+} // namespace
+
+} // namespace net
+
+#endif
diff --git a/chromium/net/cert/internal/verify_name_match.cc b/chromium/net/cert/internal/verify_name_match.cc
index 5b6cf4cbf2a..00d1fb5c113 100644
--- a/chromium/net/cert/internal/verify_name_match.cc
+++ b/chromium/net/cert/internal/verify_name_match.cc
@@ -6,7 +6,6 @@
#include <string.h>
-#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversion_utils.h"
@@ -22,6 +21,17 @@ namespace net {
namespace {
+// RFC 5280 section A.1:
+//
+// pkcs-9 OBJECT IDENTIFIER ::=
+// { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+//
+// id-emailAddress AttributeType ::= { pkcs-9 1 }
+//
+// In dotted form: 1.2.840.113549.1.9.1
+const uint8_t kOidEmailAddress[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
+ 0x0D, 0x01, 0x09, 0x01};
+
// Types of character set checking that NormalizeDirectoryString can perform.
enum CharsetEnforcement {
NO_ENFORCEMENT,
@@ -202,7 +212,7 @@ WARN_UNUSED_RESULT bool NormalizeUniversalStringValue(const der::Input& in,
std::vector<uint32_t> in_32bit(in.Length() / 4);
if (in.Length())
- memcpy(vector_as_array(&in_32bit), in.UnsafeData(), in.Length());
+ memcpy(in_32bit.data(), in.UnsafeData(), in.Length());
for (const uint32_t c : in_32bit) {
// UniversalString is UCS-4 in big-endian order.
uint32_t codepoint = base::NetToHost32(c);
@@ -389,8 +399,16 @@ bool VerifyRdnMatch(der::Parser* a_parser, der::Parser* b_parser) {
return true;
}
-} // namespace
+enum NameMatchType {
+ EXACT_MATCH,
+ SUBTREE_MATCH,
+};
+// Verify that |a| matches |b|. If |match_type| is EXACT_MATCH, returns true if
+// they are an exact match as defined by RFC 5280 7.1. If |match_type| is
+// SUBTREE_MATCH, returns true if |a| is within the subtree defined by |b| as
+// defined by RFC 5280 7.1.
+//
// |a| and |b| are ASN.1 RDNSequence values (not including the Sequence tag),
// defined in RFC 5280 section 4.1.2.4:
//
@@ -401,7 +419,9 @@ bool VerifyRdnMatch(der::Parser* a_parser, der::Parser* b_parser) {
//
// RelativeDistinguishedName ::=
// SET SIZE (1..MAX) OF AttributeTypeAndValue
-bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
+bool VerifyNameMatchInternal(const der::Input& a,
+ const der::Input& b,
+ NameMatchType match_type) {
// Empty Names are allowed. RFC 5280 section 4.1.2.4 requires "The issuer
// field MUST contain a non-empty distinguished name (DN)", while section
// 4.1.2.6 allows for the Subject to be empty in certain cases. The caller is
@@ -421,7 +441,12 @@ bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
return false;
}
}
- if (a_rdn_sequence_counter.HasMore() || b_rdn_sequence_counter.HasMore())
+ // If doing exact match and either of the sequences has more elements than the
+ // other, not a match. If doing a subtree match, the first Name may have more
+ // RDNs than the second.
+ if (b_rdn_sequence_counter.HasMore())
+ return false;
+ if (match_type == EXACT_MATCH && a_rdn_sequence_counter.HasMore())
return false;
// Same number of RDNs, now check if they match.
@@ -440,4 +465,42 @@ bool VerifyNameMatch(const der::Input& a, const der::Input& b) {
return true;
}
+} // namespace
+
+bool VerifyNameMatch(const der::Input& a_rdn_sequence,
+ const der::Input& b_rdn_sequence) {
+ return VerifyNameMatchInternal(a_rdn_sequence, b_rdn_sequence, EXACT_MATCH);
+}
+
+bool VerifyNameInSubtree(const der::Input& name_rdn_sequence,
+ const der::Input& parent_rdn_sequence) {
+ return VerifyNameMatchInternal(name_rdn_sequence, parent_rdn_sequence,
+ SUBTREE_MATCH);
+}
+
+bool NameContainsEmailAddress(const der::Input& name_rdn_sequence,
+ bool* contained_email_address) {
+ der::Parser rdn_sequence_parser(name_rdn_sequence);
+
+ while (rdn_sequence_parser.HasMore()) {
+ der::Parser rdn_parser;
+ if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser))
+ return false;
+
+ std::vector<AttributeTypeAndValue> type_and_values;
+ if (!ReadRdn(&rdn_parser, &type_and_values))
+ return false;
+
+ for (const auto& type_and_value : type_and_values) {
+ if (type_and_value.type.Equals(der::Input(kOidEmailAddress))) {
+ *contained_email_address = true;
+ return true;
+ }
+ }
+ }
+
+ *contained_email_address = false;
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/cert/internal/verify_name_match.h b/chromium/net/cert/internal/verify_name_match.h
index 99d09f0e107..5cca36ad2db 100644
--- a/chromium/net/cert/internal/verify_name_match.h
+++ b/chromium/net/cert/internal/verify_name_match.h
@@ -5,6 +5,7 @@
#ifndef NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_
#define NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_
+#include "base/compiler_specific.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -14,13 +15,30 @@ namespace der {
class Input;
} // namespace der
-// Compare DER-encoded X.501 Name values according to RFC 5280 rules.
+// Compares DER-encoded X.501 Name values according to RFC 5280 rules.
// |a_rdn_sequence| and |b_rdn_sequence| should be the DER-encoded RDNSequence
// values (not including the Sequence tag).
// Returns true if |a_rdn_sequence| and |b_rdn_sequence| match.
NET_EXPORT bool VerifyNameMatch(const der::Input& a_rdn_sequence,
const der::Input& b_rdn_sequence);
+// Compares |name_rdn_sequence| and |parent_rdn_sequence| and return true if
+// |name_rdn_sequence| is within the subtree defined by |parent_rdn_sequence| as
+// defined by RFC 5280 section 7.1. |name_rdn_sequence| and
+// |parent_rdn_sequence| should be the DER-encoded sequence values (not
+// including the Sequence tag).
+NET_EXPORT bool VerifyNameInSubtree(const der::Input& name_rdn_sequence,
+ const der::Input& parent_rdn_sequence);
+
+// Helper functions:
+
+// Checks if |name_rdn_sequence| contains an emailAddress attribute type.
+// If the return value is true, |*contained_email_address| will be set to
+// indicate whether an emailAddress attribute was present.
+// Returns false if there was a parsing error.
+bool NameContainsEmailAddress(const der::Input& name_rdn_sequence,
+ bool* contained_email_address) WARN_UNUSED_RESULT;
+
} // namespace net
#endif // NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_
diff --git a/chromium/net/cert/internal/verify_name_match_unittest.cc b/chromium/net/cert/internal/verify_name_match_unittest.cc
index d6dc3884dcb..2bdf82efb68 100644
--- a/chromium/net/cert/internal/verify_name_match_unittest.cc
+++ b/chromium/net/cert/internal/verify_name_match_unittest.cc
@@ -7,27 +7,11 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "net/cert/internal/test_helpers.h"
-#include "net/der/input.h"
-#include "net/der/parser.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
-der::Input SequenceValueFromString(const std::string* s) {
- der::Parser parser(InputFromString(s));
- der::Input data;
- if (!parser.ReadTag(der::kSequence, &data)) {
- ADD_FAILURE();
- return der::Input();
- }
- if (parser.HasMore()) {
- ADD_FAILURE();
- return der::Input();
- }
- return data;
-}
-
// Loads test data from file. The filename is constructed from the parameters:
// |prefix| describes the type of data being tested, e.g. "ascii",
// "unicode_bmp", "unicode_supplementary", and "invalid".
@@ -232,6 +216,58 @@ TEST_P(VerifyNameMatchDifferingTypesTest, NormalizableTypesAreEqual) {
}
}
+TEST_P(VerifyNameMatchDifferingTypesTest, NormalizableTypesInSubtrees) {
+ std::string der_1;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled", &der_1));
+ std::string der_1_extra_rdn;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled-extra_rdn",
+ &der_1_extra_rdn));
+ std::string der_1_extra_attr;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled-extra_attr",
+ &der_1_extra_attr));
+ std::string der_2;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled", &der_2));
+ std::string der_2_extra_rdn;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled-extra_rdn",
+ &der_2_extra_rdn));
+ std::string der_2_extra_attr;
+ ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled-extra_attr",
+ &der_2_extra_attr));
+
+ if (TypesAreComparable(value_type_1(), value_type_2())) {
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2)));
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1)));
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_1_extra_rdn),
+ SequenceValueFromString(&der_2)));
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&der_2_extra_rdn),
+ SequenceValueFromString(&der_1)));
+ } else {
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1_extra_rdn),
+ SequenceValueFromString(&der_2)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2_extra_rdn),
+ SequenceValueFromString(&der_1)));
+ }
+
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2_extra_rdn)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1_extra_rdn)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1_extra_attr),
+ SequenceValueFromString(&der_2)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2_extra_attr),
+ SequenceValueFromString(&der_1)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_1),
+ SequenceValueFromString(&der_2_extra_attr)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&der_2),
+ SequenceValueFromString(&der_1_extra_attr)));
+}
+
// Runs VerifyNameMatchDifferingTypesTest for all combinations of value types in
// value_type1 and value_type_2.
INSTANTIATE_TEST_CASE_P(InstantiationName,
@@ -459,4 +495,36 @@ TEST(VerifyNameMatchRDNSorting, DuplicateTypes) {
SequenceValueFromString(&a)));
}
+TEST(VerifyNameInSubtreeInvalidDataTest, FailOnEmptyRdn) {
+ std::string valid;
+ ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &valid));
+ std::string invalid;
+ ASSERT_TRUE(LoadTestData("invalid", "RDN", "empty", &invalid));
+ // For both |name| and |parent|, a RelativeDistinguishedName must have at
+ // least one AttributeTypeAndValue.
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&valid),
+ SequenceValueFromString(&invalid)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&invalid),
+ SequenceValueFromString(&valid)));
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&invalid),
+ SequenceValueFromString(&invalid)));
+}
+
+TEST(VerifyNameInSubtreeTest, EmptyNameMatching) {
+ std::string empty;
+ ASSERT_TRUE(LoadTestData("valid", "Name", "empty", &empty));
+ std::string non_empty;
+ ASSERT_TRUE(
+ LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &non_empty));
+ // Empty name is in the subtree defined by empty name.
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&empty),
+ SequenceValueFromString(&empty)));
+ // Any non-empty name is in the subtree defined by empty name.
+ EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(&non_empty),
+ SequenceValueFromString(&empty)));
+ // Empty name is not in the subtree defined by non-empty name.
+ EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(&empty),
+ SequenceValueFromString(&non_empty)));
+}
+
} // namespace net
diff --git a/chromium/net/cert/internal/verify_signed_data_unittest.cc b/chromium/net/cert/internal/verify_signed_data_unittest.cc
index a718c779a51..d7e822869cd 100644
--- a/chromium/net/cert/internal/verify_signed_data_unittest.cc
+++ b/chromium/net/cert/internal/verify_signed_data_unittest.cc
@@ -61,21 +61,20 @@ void RunTestCaseUsingPolicy(VerifyResult expected_result,
ASSERT_TRUE(ReadTestDataFromPemFile(path, mappings));
scoped_ptr<SignatureAlgorithm> signature_algorithm =
- SignatureAlgorithm::CreateFromDer(InputFromString(&algorithm));
+ SignatureAlgorithm::CreateFromDer(der::Input(&algorithm));
ASSERT_TRUE(signature_algorithm);
der::BitString signature_value_bit_string;
- der::Parser signature_value_parser(InputFromString(&signature_value));
+ der::Parser signature_value_parser((der::Input(&signature_value)));
ASSERT_TRUE(signature_value_parser.ReadBitString(&signature_value_bit_string))
<< "The signature value is not a valid BIT STRING";
bool expected_result_bool = expected_result == SUCCESS;
- EXPECT_EQ(
- expected_result_bool,
- VerifySignedData(*signature_algorithm, InputFromString(&signed_data),
- signature_value_bit_string, InputFromString(&public_key),
- policy));
+ EXPECT_EQ(expected_result_bool,
+ VerifySignedData(*signature_algorithm, der::Input(&signed_data),
+ signature_value_bit_string,
+ der::Input(&public_key), policy));
}
// RunTestCase() is the same as RunTestCaseUsingPolicy(), only it uses a
diff --git a/chromium/net/cert/jwk_serializer_nss.cc b/chromium/net/cert/jwk_serializer_nss.cc
index 1db65f705ba..441a98ff4f9 100644
--- a/chromium/net/cert/jwk_serializer_nss.cc
+++ b/chromium/net/cert/jwk_serializer_nss.cc
@@ -8,7 +8,7 @@
#include <keyhi.h>
#include <nss.h>
-#include "base/base64.h"
+#include "base/base64url.h"
#include "base/values.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
@@ -37,7 +37,7 @@ bool ConvertEcPrime256v1PublicKeyInfoToJwk(
reinterpret_cast<char*>(spki->subjectPublicKey.data + 1),
kPrime256v1PublicKeyLength / 2);
std::string x_b64;
- base::Base64Encode(x, &x_b64);
+ base::Base64UrlEncode(x, base::Base64UrlEncodePolicy::OMIT_PADDING, &x_b64);
public_key_jwk->SetString("x", x_b64);
base::StringPiece y(
@@ -45,7 +45,7 @@ bool ConvertEcPrime256v1PublicKeyInfoToJwk(
kPrime256v1PublicKeyLength / 2),
kPrime256v1PublicKeyLength / 2);
std::string y_b64;
- base::Base64Encode(y, &y_b64);
+ base::Base64UrlEncode(y, base::Base64UrlEncodePolicy::OMIT_PADDING, &y_b64);
public_key_jwk->SetString("y", y_b64);
return true;
}
diff --git a/chromium/net/cert/jwk_serializer_openssl.cc b/chromium/net/cert/jwk_serializer_openssl.cc
index 67683fbc56d..f5afd4fb734 100644
--- a/chromium/net/cert/jwk_serializer_openssl.cc
+++ b/chromium/net/cert/jwk_serializer_openssl.cc
@@ -10,7 +10,7 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
-#include "base/base64.h"
+#include "base/base64url.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/values.h"
@@ -74,11 +74,13 @@ bool ConvertEcKeyToJwk(EVP_PKEY* pkey,
public_key_jwk->SetString("crv", curve_name);
std::string x_b64;
- base::Base64Encode(x_bytes, &x_b64);
+ base::Base64UrlEncode(x_bytes, base::Base64UrlEncodePolicy::OMIT_PADDING,
+ &x_b64);
public_key_jwk->SetString("x", x_b64);
std::string y_b64;
- base::Base64Encode(y_bytes, &y_b64);
+ base::Base64UrlEncode(y_bytes, base::Base64UrlEncodePolicy::OMIT_PADDING,
+ &y_b64);
public_key_jwk->SetString("y", y_b64);
return true;
diff --git a/chromium/net/cert/jwk_serializer_unittest.cc b/chromium/net/cert/jwk_serializer_unittest.cc
index 6fa318f3637..ec974175c1c 100644
--- a/chromium/net/cert/jwk_serializer_unittest.cc
+++ b/chromium/net/cert/jwk_serializer_unittest.cc
@@ -4,12 +4,14 @@
#include "net/cert/jwk_serializer.h"
-#include "base/base64.h"
+#include "base/base64url.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
+namespace {
+
// This is the ASN.1 prefix for a P-256 public key. Specifically it's:
// SEQUENCE
// SEQUENCE
@@ -60,6 +62,15 @@ static const unsigned char kSpkiEcWithLeadingZero[] = {
0xc9, 0x1e, 0x31, 0x89, 0xe2, 0x62, 0xcb, 0x3f
};
+// Section 2 of RFC 7515 defines that an URL-safe base64 encoding must be used
+// with all trailing '=' characters omitted. Returns whether the |input|
+// contains any of the forbidden base64 characters (+, -, =).
+bool ContainsNonUrlSafeBase64Characters(base::StringPiece input) {
+ return input.find_first_of("+-=") != std::string::npos;
+}
+
+} // namespace
+
TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
base::StringPiece spki;
base::DictionaryValue public_key_jwk;
@@ -78,8 +89,11 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
EXPECT_STREQ("P-256", string_value.c_str());
EXPECT_TRUE(public_key_jwk.GetString("x", &string_value));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
std::string decoded_coordinate;
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0,
memcmp(decoded_coordinate.data(),
@@ -87,7 +101,10 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
kEcCoordinateSize));
EXPECT_TRUE(public_key_jwk.GetString("y", &string_value));
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0,
memcmp(decoded_coordinate.data(),
@@ -106,7 +123,10 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
EXPECT_STREQ("P-256", string_value.c_str());
EXPECT_TRUE(public_key_jwk.GetString("x", &string_value));
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0,
memcmp(decoded_coordinate.data(),
@@ -114,7 +134,10 @@ TEST(JwkSerializerTest, ConvertSpkiFromDerToJwkEc) {
kEcCoordinateSize));
EXPECT_TRUE(public_key_jwk.GetString("y", &string_value));
- EXPECT_TRUE(base::Base64Decode(string_value, &decoded_coordinate));
+ EXPECT_FALSE(ContainsNonUrlSafeBase64Characters(string_value));
+ EXPECT_TRUE(base::Base64UrlDecode(
+ string_value, base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+ &decoded_coordinate));
EXPECT_EQ(kEcCoordinateSize, decoded_coordinate.size());
EXPECT_EQ(0, memcmp(
decoded_coordinate.data(),
diff --git a/chromium/net/cert/merkle_consistency_proof.cc b/chromium/net/cert/merkle_consistency_proof.cc
new file mode 100644
index 00000000000..02f2b181a3d
--- /dev/null
+++ b/chromium/net/cert/merkle_consistency_proof.cc
@@ -0,0 +1,27 @@
+// Copyright 2015 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/merkle_consistency_proof.h"
+
+namespace net {
+
+namespace ct {
+
+MerkleConsistencyProof::MerkleConsistencyProof() {}
+
+MerkleConsistencyProof::MerkleConsistencyProof(
+ const std::string& log_id,
+ const std::vector<std::string>& proof_nodes,
+ uint64_t old_size,
+ uint64_t new_size)
+ : log_id(log_id),
+ nodes(proof_nodes),
+ first_tree_size(old_size),
+ second_tree_size(new_size) {}
+
+MerkleConsistencyProof::~MerkleConsistencyProof() {}
+
+} // namespace ct
+
+} // namespace net
diff --git a/chromium/net/cert/merkle_consistency_proof.h b/chromium/net/cert/merkle_consistency_proof.h
new file mode 100644
index 00000000000..48a70dc5eaa
--- /dev/null
+++ b/chromium/net/cert/merkle_consistency_proof.h
@@ -0,0 +1,45 @@
+// Copyright 2015 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_MERKLE_CONSISTENCY_PROOF_H_
+#define NET_CERT_MERKLE_CONSISTENCY_PROOF_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace ct {
+
+// Consistency proof between two STHs as defined in section 2.1.2. of RFC6962.
+struct NET_EXPORT MerkleConsistencyProof {
+ MerkleConsistencyProof();
+ MerkleConsistencyProof(const std::string& log_id,
+ const std::vector<std::string>& proof_nodes,
+ uint64_t old_size,
+ uint64_t new_size);
+ ~MerkleConsistencyProof();
+
+ // The origin of this proof.
+ std::string log_id;
+
+ // Consistency proof nodes.
+ std::vector<std::string> nodes;
+
+ // Size of the older tree.
+ uint64_t first_tree_size = 0;
+
+ // Size of the newer tree.
+ uint64_t second_tree_size = 0;
+};
+
+} // namespace ct
+
+} // namespace net
+
+#endif // NET_CERT_MERKLE_CONSISTENCY_PROOF_H_
diff --git a/chromium/net/cert/multi_log_ct_verifier.cc b/chromium/net/cert/multi_log_ct_verifier.cc
index 7e421b2980b..d3ff7375a9c 100644
--- a/chromium/net/cert/multi_log_ct_verifier.cc
+++ b/chromium/net/cert/multi_log_ct_verifier.cc
@@ -62,7 +62,7 @@ MultiLogCTVerifier::MultiLogCTVerifier() : observer_(nullptr) {
MultiLogCTVerifier::~MultiLogCTVerifier() { }
void MultiLogCTVerifier::AddLogs(
- const std::vector<scoped_refptr<CTLogVerifier>>& log_verifiers) {
+ const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers) {
for (const auto& log_verifier : log_verifiers) {
VLOG(1) << "Adding CT log: " << log_verifier->description();
logs_[log_verifier->key_id()] = log_verifier;
diff --git a/chromium/net/cert/multi_log_ct_verifier.h b/chromium/net/cert/multi_log_ct_verifier.h
index 4546606112d..0d8667e6e7e 100644
--- a/chromium/net/cert/multi_log_ct_verifier.h
+++ b/chromium/net/cert/multi_log_ct_verifier.h
@@ -8,6 +8,7 @@
#include <map>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/ct_verifier.h"
@@ -23,15 +24,14 @@ class CTLogVerifier;
// A Certificate Transparency verifier that can verify Signed Certificate
// Timestamps from multiple logs.
-// There should be a global instance of this class and for all known logs,
-// AddLog should be called with a CTLogVerifier (which is created from the
-// log's public key).
+// It must be initialized with a list of logs by calling AddLogs.
class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
public:
MultiLogCTVerifier();
~MultiLogCTVerifier() override;
- void AddLogs(const std::vector<scoped_refptr<CTLogVerifier>>& log_verifiers);
+ void AddLogs(
+ const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers);
// CTVerifier implementation:
int Verify(X509Certificate* cert,
@@ -61,7 +61,7 @@ class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
// Mapping from a log's ID to the verifier for this log.
// A log's ID is the SHA-256 of the log's key, as defined in section 3.2.
// of RFC6962.
- std::map<std::string, scoped_refptr<CTLogVerifier>> logs_;
+ std::map<std::string, scoped_refptr<const CTLogVerifier>> logs_;
Observer* observer_;
diff --git a/chromium/net/cert/multi_log_ct_verifier_unittest.cc b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
index 492c21a06d4..d5d609a8ec4 100644
--- a/chromium/net/cert/multi_log_ct_verifier_unittest.cc
+++ b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
@@ -50,7 +50,7 @@ class MockSCTObserver : public CTVerifier::Observer {
class MultiLogCTVerifierTest : public ::testing::Test {
public:
void SetUp() override {
- scoped_refptr<CTLogVerifier> log(CTLogVerifier::Create(
+ scoped_refptr<const CTLogVerifier> log(CTLogVerifier::Create(
ct::GetTestPublicKey(), kLogDescription, "https://ct.example.com"));
ASSERT_TRUE(log);
log_verifiers_.push_back(log);
@@ -206,7 +206,7 @@ class MultiLogCTVerifierTest : public ::testing::Test {
scoped_ptr<MultiLogCTVerifier> verifier_;
scoped_refptr<X509Certificate> chain_;
scoped_refptr<X509Certificate> embedded_sct_chain_;
- std::vector<scoped_refptr<CTLogVerifier>> log_verifiers_;
+ std::vector<scoped_refptr<const CTLogVerifier>> log_verifiers_;
};
TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCT) {
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.cc b/chromium/net/cert/multi_threaded_cert_verifier.cc
index aef8a75288d..23f1d874ec8 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier.cc
@@ -5,6 +5,7 @@
#include "net/cert/multi_threaded_cert_verifier.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -106,9 +107,9 @@ scoped_ptr<base::Value> CertVerifyResultCallback(
++it) {
hashes->AppendString(it->ToString());
}
- results->Set("public_key_hashes", hashes.Pass());
+ results->Set("public_key_hashes", std::move(hashes));
- return results.Pass();
+ return std::move(results);
}
} // namespace
@@ -329,7 +330,7 @@ class CertVerifierJob {
net_log_.source().ToEventParametersCallback());
requests_.Append(request.get());
- return request.Pass();
+ return request;
}
private:
@@ -468,7 +469,7 @@ int MultiThreadedCertVerifier::Verify(X509Certificate* cert,
scoped_ptr<CertVerifierRequest> request =
job->CreateRequest(callback, verify_result, net_log);
- *out_req = request.Pass();
+ *out_req = std::move(request);
return ERR_IO_PENDING;
}
@@ -483,7 +484,7 @@ MultiThreadedCertVerifier::RequestParams::RequestParams(
const std::string& ocsp_response_arg,
int flags_arg,
const CertificateList& additional_trust_anchors)
- : hostname(hostname_arg), flags(flags_arg) {
+ : hostname(hostname_arg), flags(flags_arg), start_time(base::Time::Now()) {
hash_values.reserve(3 + additional_trust_anchors.size());
SHA1HashValue ocsp_hash;
base::SHA1HashBytes(
@@ -522,10 +523,34 @@ void MultiThreadedCertVerifier::SaveResultToCache(const RequestParams& key,
const CachedResult& result) {
DCHECK(CalledOnValidThread());
- base::Time now = base::Time::Now();
+ // When caching, this uses the time that validation started as the
+ // beginning of the validity, rather than the time that it ended (aka
+ // base::Time::Now()), to account for the fact that during validation,
+ // the clock may have changed.
+ //
+ // If the clock has changed significantly, then this result will ideally
+ // be evicted and the next time the certificate is encountered, it will
+ // be revalidated.
+ //
+ // Because of this, it's possible for situations to arise where the
+ // clock was correct at the start of validation, changed to an
+ // incorrect time during validation (such as too far in the past or
+ // future), and then was reset to the correct time. If this happens,
+ // it's likely that the result will not be a valid/correct result,
+ // but will still be used from the cache because the clock was reset
+ // to the correct time after the (bad) validation result completed.
+ //
+ // However, this solution optimizes for the case where the clock is
+ // bad at the start of validation, and subsequently is corrected. In
+ // that situation, the result is also incorrect, but because the clock
+ // was corrected after validation, if the cache validity period was
+ // computed at the end of validation, it would continue to serve an
+ // invalid result for kTTLSecs.
+ const base::Time start_time = key.start_time;
cache_.Put(
- key, result, CacheValidityPeriod(now),
- CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs)));
+ key, result, CacheValidityPeriod(start_time),
+ CacheValidityPeriod(start_time,
+ start_time + base::TimeDelta::FromSeconds(kTTLSecs)));
}
scoped_ptr<CertVerifierJob> MultiThreadedCertVerifier::RemoveJob(
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.h b/chromium/net/cert/multi_threaded_cert_verifier.h
index 96329702415..30234ff9bc2 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.h
+++ b/chromium/net/cert/multi_threaded_cert_verifier.h
@@ -5,7 +5,9 @@
#ifndef NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_
#define NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_
+#include <stddef.h>
#include <stdint.h>
+
#include <set>
#include <string>
#include <vector>
@@ -97,6 +99,10 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier
std::string hostname;
int flags;
std::vector<SHA1HashValue> hash_values;
+ // The time when verification started.
+ // Note: This uses base::Time, rather than base::TimeTicks, to
+ // account for system clock changes.
+ base::Time start_time;
};
// CachedResult contains the result of a certificate verification.
diff --git a/chromium/net/cert/nss_cert_database.cc b/chromium/net/cert/nss_cert_database.cc
index c9f013324a8..53ea7c79fc5 100644
--- a/chromium/net/cert/nss_cert_database.cc
+++ b/chromium/net/cert/nss_cert_database.cc
@@ -9,10 +9,12 @@
#include <keyhi.h>
#include <pk11pub.h>
#include <secmod.h>
+#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/task_runner.h"
@@ -80,8 +82,8 @@ NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {}
NSSCertDatabase::NSSCertDatabase(crypto::ScopedPK11Slot public_slot,
crypto::ScopedPK11Slot private_slot)
- : public_slot_(public_slot.Pass()),
- private_slot_(private_slot.Pass()),
+ : public_slot_(std::move(public_slot)),
+ private_slot_(std::move(private_slot)),
observer_list_(new base::ObserverListThreadSafe<Observer>),
weak_factory_(this) {
CHECK(public_slot_);
@@ -227,6 +229,18 @@ X509Certificate* NSSCertDatabase::FindRootInList(
return cert0;
}
+int NSSCertDatabase::ImportUserCert(const std::string& data) {
+ CertificateList certificates =
+ X509Certificate::CreateCertificateListFromBytes(
+ data.c_str(), data.size(), net::X509Certificate::FORMAT_AUTO);
+ int result = psm::ImportUserCert(certificates);
+
+ if (result == OK)
+ NotifyObserversOfCertAdded(NULL);
+
+ return result;
+}
+
bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates,
TrustBits trust_bits,
ImportCertFailureList* not_imported) {
diff --git a/chromium/net/cert/nss_cert_database.h b/chromium/net/cert/nss_cert_database.h
index 42447f95a73..ff96af029d4 100644
--- a/chromium/net/cert/nss_cert_database.h
+++ b/chromium/net/cert/nss_cert_database.h
@@ -6,6 +6,7 @@
#define NET_CERT_NSS_CERT_DATABASE_H_
#include <stdint.h>
+
#include <string>
#include <vector>
@@ -192,6 +193,11 @@ class NET_EXPORT NSSCertDatabase {
// TODO(mattm): improve this to handle any order.
X509Certificate* FindRootInList(const CertificateList& certificates) const;
+ // Import a user certificate. The private key for the user certificate must
+ // already be installed, otherwise we return ERR_NO_PRIVATE_KEY_FOR_CERT.
+ // Returns OK or a network error code.
+ int ImportUserCert(const std::string& data);
+
// Import CA certificates.
// Tries to import all the certificates given. The root will be trusted
// according to |trust_bits|. Any certificates that could not be imported
diff --git a/chromium/net/cert/nss_cert_database_chromeos.cc b/chromium/net/cert/nss_cert_database_chromeos.cc
index 63d969cd7ea..fda5307f4e3 100644
--- a/chromium/net/cert/nss_cert_database_chromeos.cc
+++ b/chromium/net/cert/nss_cert_database_chromeos.cc
@@ -6,8 +6,8 @@
#include <cert.h>
#include <pk11pub.h>
-
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/callback.h"
@@ -21,7 +21,7 @@ namespace net {
NSSCertDatabaseChromeOS::NSSCertDatabaseChromeOS(
crypto::ScopedPK11Slot public_slot,
crypto::ScopedPK11Slot private_slot)
- : NSSCertDatabase(public_slot.Pass(), private_slot.Pass()) {
+ : NSSCertDatabase(std::move(public_slot), std::move(private_slot)) {
// By default, don't use a system slot. Only if explicitly set by
// SetSystemSlot, the system slot will be used.
profile_filter_.Init(GetPublicSlot(),
@@ -33,7 +33,7 @@ NSSCertDatabaseChromeOS::~NSSCertDatabaseChromeOS() {}
void NSSCertDatabaseChromeOS::SetSystemSlot(
crypto::ScopedPK11Slot system_slot) {
- system_slot_ = system_slot.Pass();
+ system_slot_ = std::move(system_slot);
profile_filter_.Init(GetPublicSlot(), GetPrivateSlot(), GetSystemSlot());
}
@@ -42,7 +42,7 @@ void NSSCertDatabaseChromeOS::ListCertsSync(CertificateList* certs) {
}
void NSSCertDatabaseChromeOS::ListCerts(
- const base::Callback<void(scoped_ptr<CertificateList> certs)>& callback) {
+ const NSSCertDatabase::ListCertsCallback& callback) {
scoped_ptr<CertificateList> certs(new CertificateList());
// base::Pased will NULL out |certs|, so cache the underlying pointer here.
diff --git a/chromium/net/cert/nss_cert_database_chromeos.h b/chromium/net/cert/nss_cert_database_chromeos.h
index 930f9f23e28..4eb27a7fd48 100644
--- a/chromium/net/cert/nss_cert_database_chromeos.h
+++ b/chromium/net/cert/nss_cert_database_chromeos.h
@@ -6,6 +6,7 @@
#define NET_CERT_NSS_CERT_DATABASE_CHROMEOS_
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "crypto/scoped_nss_types.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/nss_profile_filter_chromeos.cc b/chromium/net/cert/nss_profile_filter_chromeos.cc
index 8e4167a6e9b..40502e350f2 100644
--- a/chromium/net/cert/nss_profile_filter_chromeos.cc
+++ b/chromium/net/cert/nss_profile_filter_chromeos.cc
@@ -4,6 +4,8 @@
#include "net/cert/nss_profile_filter_chromeos.h"
+#include <utility>
+
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "net/cert/x509_certificate.h"
@@ -71,11 +73,11 @@ void NSSProfileFilterChromeOS::Init(crypto::ScopedPK11Slot public_slot,
// not release its reference, and the receiving object won't free
// its copy.
if (public_slot_.get() != public_slot.get())
- public_slot_ = public_slot.Pass();
+ public_slot_ = std::move(public_slot);
if (private_slot_.get() != private_slot.get())
- private_slot_ = private_slot.Pass();
+ private_slot_ = std::move(private_slot);
if (system_slot_.get() != system_slot.get())
- system_slot_ = system_slot.Pass();
+ system_slot_ = std::move(system_slot);
}
bool NSSProfileFilterChromeOS::IsModuleAllowed(PK11SlotInfo* slot) const {
diff --git a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
index d4051af1197..f0243d843da 100644
--- a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
+++ b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
@@ -7,6 +7,7 @@
#include <cert.h>
#include <pk11pub.h>
#include <secmod.h>
+#include <utility>
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"
@@ -75,8 +76,7 @@ class NSSProfileFilterChromeOSTest : public testing::Test {
ASSERT_TRUE(private_slot_1.get());
profile_filter_1_.Init(
crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()),
- private_slot_1.Pass(),
- get_system_slot());
+ std::move(private_slot_1), get_system_slot());
profile_filter_1_copy_ = profile_filter_1_;
@@ -86,7 +86,7 @@ class NSSProfileFilterChromeOSTest : public testing::Test {
ASSERT_TRUE(private_slot_2.get());
profile_filter_2_.Init(
crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()),
- private_slot_2.Pass(),
+ std::move(private_slot_2),
crypto::ScopedPK11Slot() /* no system slot */);
certs_ = CreateCertificateListFromFile(GetTestCertsDirectory(),
diff --git a/chromium/net/cert/pem_tokenizer.h b/chromium/net/cert/pem_tokenizer.h
index bb41c446db7..808acbd34e8 100644
--- a/chromium/net/cert/pem_tokenizer.h
+++ b/chromium/net/cert/pem_tokenizer.h
@@ -5,9 +5,12 @@
#ifndef NET_CERT_PEM_TOKENIZER_H_
#define NET_CERT_PEM_TOKENIZER_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/signed_certificate_timestamp.h b/chromium/net/cert/signed_certificate_timestamp.h
index 671c250fdc8..02697dc7a1f 100644
--- a/chromium/net/cert/signed_certificate_timestamp.h
+++ b/chromium/net/cert/signed_certificate_timestamp.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/base/hash_value.h"
diff --git a/chromium/net/cert/signed_tree_head.h b/chromium/net/cert/signed_tree_head.h
index fdbcdc48499..161373607b2 100644
--- a/chromium/net/cert/signed_tree_head.h
+++ b/chromium/net/cert/signed_tree_head.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_SIGNED_TREE_HEAD_H_
#define NET_CERT_SIGNED_TREE_HEAD_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
diff --git a/chromium/net/cert/test_root_certs.h b/chromium/net/cert/test_root_certs.h
index 32eb999ec81..a7d0fd212de 100644
--- a/chromium/net/cert/test_root_certs.h
+++ b/chromium/net/cert/test_root_certs.h
@@ -6,6 +6,7 @@
#define NET_CERT_TEST_ROOT_CERTS_H_
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/cert/test_root_certs_nss.cc b/chromium/net/cert/test_root_certs_nss.cc
index f7d855c54b1..bcd4add1e86 100644
--- a/chromium/net/cert/test_root_certs_nss.cc
+++ b/chromium/net/cert/test_root_certs_nss.cc
@@ -7,6 +7,7 @@
#include <cert.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/stl_util.h"
#include "crypto/nss_util.h"
#include "net/cert/x509_certificate.h"
diff --git a/chromium/net/cert/test_root_certs_win.cc b/chromium/net/cert/test_root_certs_win.cc
index a83ac047905..67bf1b09f75 100644
--- a/chromium/net/cert/test_root_certs_win.cc
+++ b/chromium/net/cert/test_root_certs_win.cc
@@ -100,8 +100,8 @@ BOOL WINAPI InterceptedOpenStoreW(LPCSTR store_provider,
// If the high word is all zeroes, then |store_provider| is a numeric ID.
// Otherwise, it's a pointer to a null-terminated ASCII string. See the
// documentation for CryptGetOIDFunctionAddress for more information.
- uint32_t store_as_uint = reinterpret_cast<uint32_t>(store_provider);
- if (store_as_uint > 0xFFFF || store_provider != CERT_STORE_PROV_SYSTEM_W ||
+ uintptr_t store_as_uintptr = reinterpret_cast<uintptr_t>(store_provider);
+ if (store_as_uintptr > 0xFFFF || store_provider != CERT_STORE_PROV_SYSTEM_W ||
!g_capi_injector.Get().original_function)
return FALSE;
@@ -148,7 +148,7 @@ bool TestRootCerts::Add(X509Certificate* certificate) {
CERT_STORE_ADD_NEW, NULL);
if (!ok) {
// If the certificate is already added, return successfully.
- return GetLastError() == CRYPT_E_EXISTS;
+ return GetLastError() == static_cast<DWORD>(CRYPT_E_EXISTS);
}
empty_ = false;
diff --git a/chromium/net/cert/x509_cert_types.h b/chromium/net/cert/x509_cert_types.h
index 4e9340a4c0d..d2a55fe4b54 100644
--- a/chromium/net/cert/x509_cert_types.h
+++ b/chromium/net/cert/x509_cert_types.h
@@ -5,6 +5,7 @@
#ifndef NET_CERT_X509_CERT_TYPES_H_
#define NET_CERT_X509_CERT_TYPES_H_
+#include <stddef.h>
#include <string.h>
#include <map>
diff --git a/chromium/net/cert/x509_certificate.cc b/chromium/net/cert/x509_certificate.cc
index dc3cd80c7fd..d925ce6b490 100644
--- a/chromium/net/cert/x509_certificate.cc
+++ b/chromium/net/cert/x509_certificate.cc
@@ -4,6 +4,7 @@
#include "net/cert/x509_certificate.h"
+#include <limits.h>
#include <stdlib.h>
#include <algorithm>
@@ -14,6 +15,7 @@
#include "base/base64.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram_macros.h"
@@ -301,7 +303,7 @@ X509Certificate* X509Certificate::CreateFromDERCertChain(
// static
X509Certificate* X509Certificate::CreateFromBytes(const char* data,
- int length) {
+ size_t length) {
OSCertHandle cert_handle = CreateOSCertHandleFromBytes(data, length);
if (!cert_handle)
return NULL;
@@ -399,7 +401,9 @@ X509Certificate* X509Certificate::CreateFromPickle(
// static
CertificateList X509Certificate::CreateCertificateListFromBytes(
- const char* data, int length, int format) {
+ const char* data,
+ size_t length,
+ int format) {
OSCertHandles certificates;
// Check to see if it is in a PEM-encoded form. This check is performed
diff --git a/chromium/net/cert/x509_certificate.h b/chromium/net/cert/x509_certificate.h
index 3cd1ad77a4d..c22a0d50d24 100644
--- a/chromium/net/cert/x509_certificate.h
+++ b/chromium/net/cert/x509_certificate.h
@@ -5,12 +5,14 @@
#ifndef NET_CERT_X509_CERTIFICATE_H_
#define NET_CERT_X509_CERTIFICATE_H_
+#include <stddef.h>
#include <string.h>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
@@ -155,7 +157,7 @@ class NET_EXPORT X509Certificate
// Returns NULL on failure.
//
// The returned pointer must be stored in a scoped_refptr<X509Certificate>.
- static X509Certificate* CreateFromBytes(const char* data, int length);
+ static X509Certificate* CreateFromBytes(const char* data, size_t length);
#if defined(USE_NSS_CERTS)
// Create an X509Certificate from the DER-encoded representation.
@@ -166,7 +168,7 @@ class NET_EXPORT X509Certificate
// This function differs from CreateFromBytes in that it takes a
// nickname that will be used when the certificate is imported into PKCS#11.
static X509Certificate* CreateFromBytesWithNickname(const char* data,
- int length,
+ size_t length,
const char* nickname);
// The default nickname of the certificate, based on the certificate type
@@ -189,7 +191,7 @@ class NET_EXPORT X509Certificate
// certificates may have been serialized as. If an error occurs, an empty
// collection will be returned.
static CertificateList CreateCertificateListFromBytes(const char* data,
- int length,
+ size_t length,
int format);
// Appends a representation of this object to the given pickle.
@@ -362,7 +364,7 @@ class NET_EXPORT X509Certificate
// Creates an OS certificate handle from the DER-encoded representation.
// Returns NULL on failure.
static OSCertHandle CreateOSCertHandleFromBytes(const char* data,
- int length);
+ size_t length);
#if defined(USE_NSS_CERTS)
// Creates an OS certificate handle from the DER-encoded representation.
@@ -370,16 +372,15 @@ class NET_EXPORT X509Certificate
// non-NULL.
static OSCertHandle CreateOSCertHandleFromBytesWithNickname(
const char* data,
- int length,
+ size_t length,
const char* nickname);
#endif
// Creates all possible OS certificate handles from |data| encoded in a
// specific |format|. Returns an empty collection on failure.
- static OSCertHandles CreateOSCertHandlesFromBytes(
- const char* data,
- int length,
- Format format);
+ static OSCertHandles CreateOSCertHandlesFromBytes(const char* data,
+ size_t length,
+ Format format);
// Duplicates (or adds a reference to) an OS certificate handle.
static OSCertHandle DupOSCertHandle(OSCertHandle cert_handle);
diff --git a/chromium/net/cert/x509_certificate_ios.cc b/chromium/net/cert/x509_certificate_ios.cc
index 9c3b333724e..d458589872d 100644
--- a/chromium/net/cert/x509_certificate_ios.cc
+++ b/chromium/net/cert/x509_certificate_ios.cc
@@ -24,6 +24,7 @@
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/time/time.h"
#include "crypto/nss_util.h"
@@ -131,18 +132,19 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
+ const char* data,
+ size_t length) {
ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy(
- kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data), length,
- kCFAllocatorNull));
+ kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
+ base::checked_cast<CFIndex>(length), kCFAllocatorNull));
if (!cert_data)
- return NULL;
+ return nullptr;
OSCertHandle cert_handle = SecCertificateCreateWithData(NULL, cert_data);
if (!cert_handle)
- return NULL;
+ return nullptr;
if (!IsValidOSCertHandle(cert_handle)) {
CFRelease(cert_handle);
- return NULL;
+ return nullptr;
}
return cert_handle;
}
@@ -150,7 +152,7 @@ X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
Format format) {
return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
}
diff --git a/chromium/net/cert/x509_certificate_known_roots_mac.h b/chromium/net/cert/x509_certificate_known_roots_mac.h
deleted file mode 100644
index fb5d0f5b9b6..00000000000
--- a/chromium/net/cert/x509_certificate_known_roots_mac.h
+++ /dev/null
@@ -1,560 +0,0 @@
-// Copyright (c) 2011 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_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_
-#define NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_
-
-// This is the set of Apple trusted roots from OS X 10.6.0 to
-// OS X 10.10.1, available at http://opensource.apple.com
-//
-// Note that these *are not* trust anchors for Chromium. They are only used to
-// distinguish `real' root CAs from roots that were user-installed.
-static uint8_t kKnownRootCertSHA1Hashes[][20] = {
- {0x01, 0x68, 0x97, 0xe1, 0xa0, 0xb8, 0xf2, 0xc3, 0xb1, 0x34,
- 0x66, 0x5c, 0x20, 0xa7, 0x27, 0xb7, 0xa1, 0x58, 0xe2, 0x8f},
- {0x02, 0x72, 0x68, 0x29, 0x3e, 0x5f, 0x5d, 0x17, 0xaa, 0xa4,
- 0xb3, 0xc3, 0xe6, 0x36, 0x1e, 0x1f, 0x92, 0x57, 0x5e, 0xaa},
- {0x02, 0xfa, 0xf3, 0xe2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78,
- 0x57, 0x69, 0x4d, 0xf5, 0xe4, 0x5b, 0x68, 0x85, 0x18, 0x68},
- {0x03, 0x9e, 0xed, 0xb8, 0x0b, 0xe7, 0xa0, 0x3c, 0x69, 0x53,
- 0x89, 0x3b, 0x20, 0xd2, 0xd9, 0x32, 0x3a, 0x4c, 0x2a, 0xfd},
- {0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87,
- 0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7},
- {0x05, 0x63, 0xb8, 0x63, 0x0d, 0x62, 0xd7, 0x5a, 0xbb, 0xc8,
- 0xab, 0x1e, 0x4b, 0xdf, 0xb5, 0xa8, 0x99, 0xb2, 0x4d, 0x43},
- {0x06, 0x08, 0x3f, 0x59, 0x3f, 0x15, 0xa1, 0x04, 0xa0, 0x69,
- 0xa4, 0x6b, 0xa9, 0x03, 0xd0, 0x06, 0xb7, 0x97, 0x09, 0x91},
- {0x07, 0x47, 0x22, 0x01, 0x99, 0xce, 0x74, 0xb9, 0x7c, 0xb0,
- 0x3d, 0x79, 0xb2, 0x64, 0xa2, 0xc8, 0x55, 0xe9, 0x33, 0xff},
- {0x07, 0xe0, 0x32, 0xe0, 0x20, 0xb7, 0x2c, 0x3f, 0x19, 0x2f,
- 0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e},
- {0x08, 0x64, 0x18, 0xe9, 0x06, 0xce, 0xe8, 0x9c, 0x23, 0x53,
- 0xb6, 0xe2, 0x7f, 0xbd, 0x9e, 0x74, 0x39, 0xf7, 0x63, 0x16},
- {0x09, 0x3c, 0x61, 0xf3, 0x8b, 0x8b, 0xdc, 0x7d, 0x55, 0xdf,
- 0x75, 0x38, 0x02, 0x05, 0x00, 0xe1, 0x25, 0xf5, 0xc8, 0x36},
- {0x0b, 0x77, 0xbe, 0xbb, 0xcb, 0x7a, 0xa2, 0x47, 0x05, 0xde,
- 0xcc, 0x0f, 0xbd, 0x6a, 0x02, 0xfc, 0x7a, 0xbd, 0x9b, 0x52},
- {0x0b, 0x97, 0x2c, 0x9e, 0xa6, 0xe7, 0xcc, 0x58, 0xd9, 0x3b,
- 0x20, 0xbf, 0x71, 0xec, 0x41, 0x2e, 0x72, 0x09, 0xfa, 0xbf},
- {0x0c, 0x08, 0xb8, 0x4a, 0x1f, 0x26, 0xf5, 0x05, 0x49, 0xda,
- 0xab, 0x36, 0x33, 0x08, 0xd3, 0x56, 0x52, 0x68, 0xf1, 0x60},
- {0x10, 0x1d, 0xfa, 0x3f, 0xd5, 0x0b, 0xcb, 0xbb, 0x9b, 0xb5,
- 0x60, 0x0c, 0x19, 0x55, 0xa4, 0x1a, 0xf4, 0x73, 0x3a, 0x04},
- {0x10, 0xf1, 0x93, 0xf3, 0x40, 0xac, 0x91, 0xd6, 0xde, 0x5f,
- 0x1e, 0xdc, 0x00, 0x62, 0x47, 0xc4, 0xf2, 0x5d, 0x96, 0x71},
- {0x12, 0x1f, 0x9f, 0xac, 0x62, 0x9f, 0xf1, 0x33, 0x88, 0x7c,
- 0x1b, 0x45, 0x64, 0x0c, 0x1a, 0x03, 0x4f, 0x03, 0xf2, 0x8f},
- {0x13, 0x2d, 0x0d, 0x45, 0x53, 0x4b, 0x69, 0x97, 0xcd, 0xb2,
- 0xd5, 0xc3, 0x39, 0xe2, 0x55, 0x76, 0x60, 0x9b, 0x5c, 0xc6},
- {0x14, 0x69, 0x89, 0x89, 0xbf, 0xb2, 0x95, 0x09, 0x21, 0xa4,
- 0x24, 0x52, 0x64, 0x6d, 0x37, 0xb5, 0x0a, 0xf0, 0x17, 0xe2},
- {0x17, 0xc0, 0xc5, 0x9a, 0xb5, 0xd8, 0xd5, 0x85, 0x20, 0x43,
- 0xe8, 0xec, 0x69, 0x2c, 0x40, 0x9d, 0x80, 0x62, 0xaa, 0x53},
- {0x1b, 0x4b, 0x39, 0x61, 0x26, 0x27, 0x6b, 0x64, 0x91, 0xa2,
- 0x68, 0x6d, 0xd7, 0x02, 0x43, 0x21, 0x2d, 0x1f, 0x1d, 0x96},
- {0x1b, 0x8e, 0xea, 0x57, 0x96, 0x29, 0x1a, 0xc9, 0x39, 0xea,
- 0xb8, 0x0a, 0x81, 0x1a, 0x73, 0x73, 0xc0, 0x93, 0x79, 0x67},
- {0x1f, 0x24, 0xc6, 0x30, 0xcd, 0xa4, 0x18, 0xef, 0x20, 0x69,
- 0xff, 0xad, 0x4f, 0xdd, 0x5f, 0x46, 0x3a, 0x1b, 0x69, 0xaa},
- {0x1f, 0x49, 0x14, 0xf7, 0xd8, 0x74, 0x95, 0x1d, 0xdd, 0xae,
- 0x02, 0xc0, 0xbe, 0xfd, 0x3a, 0x2d, 0x82, 0x75, 0x51, 0x85},
- {0x20, 0x42, 0x85, 0xdc, 0xf7, 0xeb, 0x76, 0x41, 0x95, 0x57,
- 0x8e, 0x13, 0x6b, 0xd4, 0xb7, 0xd1, 0xe9, 0x8e, 0x46, 0xa5},
- {0x20, 0x99, 0x00, 0xb6, 0x3d, 0x95, 0x57, 0x28, 0x14, 0x0c,
- 0xd1, 0x36, 0x22, 0xd8, 0xc6, 0x87, 0xa4, 0xeb, 0x00, 0x85},
- {0x20, 0xce, 0xb1, 0xf0, 0xf5, 0x1c, 0x0e, 0x19, 0xa9, 0xf3,
- 0x8d, 0xb1, 0xaa, 0x8e, 0x03, 0x8c, 0xaa, 0x7a, 0xc7, 0x01},
- {0x20, 0xd8, 0x06, 0x40, 0xdf, 0x9b, 0x25, 0xf5, 0x12, 0x25,
- 0x3a, 0x11, 0xea, 0xf7, 0x59, 0x8a, 0xeb, 0x14, 0xb5, 0x47},
- {0x21, 0xfc, 0xbd, 0x8e, 0x7f, 0x6c, 0xaf, 0x05, 0x1b, 0xd1,
- 0xb3, 0x43, 0xec, 0xa8, 0xe7, 0x61, 0x47, 0xf2, 0x0f, 0x8a},
- {0x22, 0xd5, 0xd8, 0xdf, 0x8f, 0x02, 0x31, 0xd1, 0x8d, 0xf7,
- 0x9d, 0xb7, 0xcf, 0x8a, 0x2d, 0x64, 0xc9, 0x3f, 0x6c, 0x3a},
- {0x23, 0xe5, 0x94, 0x94, 0x51, 0x95, 0xf2, 0x41, 0x48, 0x03,
- 0xb4, 0xd5, 0x64, 0xd2, 0xa3, 0xa3, 0xf5, 0xd8, 0x8b, 0x8c},
- {0x25, 0x01, 0x90, 0x19, 0xcf, 0xfb, 0xd9, 0x99, 0x1c, 0xb7,
- 0x68, 0x25, 0x74, 0x8d, 0x94, 0x5f, 0x30, 0x93, 0x95, 0x42},
- {0x25, 0x3f, 0x77, 0x5b, 0x0e, 0x77, 0x97, 0xab, 0x64, 0x5f,
- 0x15, 0x91, 0x55, 0x97, 0xc3, 0x9e, 0x26, 0x36, 0x31, 0xd1},
- {0x26, 0xa1, 0x6c, 0x23, 0x5a, 0x24, 0x72, 0x22, 0x9b, 0x23,
- 0x62, 0x80, 0x25, 0xbc, 0x80, 0x97, 0xc8, 0x85, 0x24, 0xa1},
- {0x26, 0xca, 0xff, 0x09, 0xa7, 0xaf, 0xba, 0xe9, 0x68, 0x10,
- 0xcf, 0xff, 0x82, 0x1a, 0x94, 0x32, 0x6d, 0x28, 0x45, 0xaa},
- {0x27, 0x0c, 0x50, 0x0c, 0xc6, 0xc8, 0x6e, 0xcb, 0x19, 0x80,
- 0xbc, 0x13, 0x05, 0x43, 0x9e, 0xd2, 0x82, 0x48, 0x0b, 0xe3},
- {0x27, 0x3e, 0xe1, 0x24, 0x57, 0xfd, 0xc4, 0xf9, 0x0c, 0x55,
- 0xe8, 0x2b, 0x56, 0x16, 0x7f, 0x62, 0xf5, 0x32, 0xe5, 0x47},
- {0x27, 0x96, 0xba, 0xe6, 0x3f, 0x18, 0x01, 0xe2, 0x77, 0x26,
- 0x1b, 0xa0, 0xd7, 0x77, 0x70, 0x02, 0x8f, 0x20, 0xee, 0xe4},
- {0x29, 0x36, 0x21, 0x02, 0x8b, 0x20, 0xed, 0x02, 0xf5, 0x66,
- 0xc5, 0x32, 0xd1, 0xd6, 0xed, 0x90, 0x9f, 0x45, 0x00, 0x2f},
- {0x29, 0x64, 0xb6, 0x86, 0x13, 0x5b, 0x5d, 0xfd, 0xdd, 0x32,
- 0x53, 0xa8, 0x9b, 0xbc, 0x24, 0xd7, 0x4b, 0x08, 0xc6, 0x4d},
- {0x2a, 0xb6, 0x28, 0x48, 0x5e, 0x78, 0xfb, 0xf3, 0xad, 0x9e,
- 0x79, 0x10, 0xdd, 0x6b, 0xdf, 0x99, 0x72, 0x2c, 0x96, 0xe5},
- {0x2a, 0xc8, 0xd5, 0x8b, 0x57, 0xce, 0xbf, 0x2f, 0x49, 0xaf,
- 0xf2, 0xfc, 0x76, 0x8f, 0x51, 0x14, 0x62, 0x90, 0x7a, 0x41},
- {0x2b, 0x84, 0xbf, 0xbb, 0x34, 0xee, 0x2e, 0xf9, 0x49, 0xfe,
- 0x1c, 0xbe, 0x30, 0xaa, 0x02, 0x64, 0x16, 0xeb, 0x22, 0x16},
- {0x2c, 0xeb, 0x05, 0x34, 0xad, 0x59, 0x27, 0x18, 0x0d, 0x34,
- 0x8c, 0x5f, 0x0e, 0x05, 0x6d, 0x38, 0x2b, 0x50, 0x82, 0x87},
- {0x2d, 0xc7, 0xab, 0xf6, 0x7e, 0x9e, 0x63, 0x9a, 0x22, 0xdb,
- 0xdf, 0x4e, 0xee, 0x9b, 0xc5, 0x2a, 0x48, 0xa2, 0xcc, 0x2d},
- {0x2d, 0xff, 0x63, 0x36, 0xe3, 0x3a, 0x48, 0x29, 0xaa, 0x00,
- 0x9f, 0x01, 0xa1, 0x80, 0x1e, 0xe7, 0xeb, 0xa5, 0x82, 0xbb},
- {0x2e, 0x14, 0xda, 0xec, 0x28, 0xf0, 0xfa, 0x1e, 0x8e, 0x38,
- 0x9a, 0x4e, 0xab, 0xeb, 0x26, 0xc0, 0x0a, 0xd3, 0x83, 0xc3},
- {0x2e, 0xf6, 0x4b, 0xba, 0x77, 0xdd, 0x37, 0x79, 0xe9, 0x1f,
- 0xbd, 0x5a, 0x4e, 0xee, 0x63, 0x3c, 0x8a, 0x36, 0xa5, 0xb1},
- {0x2f, 0x17, 0x3f, 0x7d, 0xe9, 0x96, 0x67, 0xaf, 0xa5, 0x7a,
- 0xf8, 0x0a, 0xa2, 0xd1, 0xb1, 0x2f, 0xac, 0x83, 0x03, 0x38},
- {0x2f, 0x78, 0x3d, 0x25, 0x52, 0x18, 0xa7, 0x4a, 0x65, 0x39,
- 0x71, 0xb5, 0x2c, 0xa2, 0x9c, 0x45, 0x15, 0x6f, 0xe9, 0x19},
- {0x30, 0x77, 0x9e, 0x93, 0x15, 0x02, 0x2e, 0x94, 0x85, 0x6a,
- 0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd},
- {0x31, 0x7a, 0x2a, 0xd0, 0x7f, 0x2b, 0x33, 0x5e, 0xf5, 0xa1,
- 0xc3, 0x4e, 0x4b, 0x57, 0xe8, 0xb7, 0xd8, 0xf1, 0xfc, 0xa6},
- {0x31, 0xf1, 0xfd, 0x68, 0x22, 0x63, 0x20, 0xee, 0xc6, 0x3b,
- 0x3f, 0x9d, 0xea, 0x4a, 0x3e, 0x53, 0x7c, 0x7c, 0x39, 0x17},
- {0x32, 0x3c, 0x11, 0x8e, 0x1b, 0xf7, 0xb8, 0xb6, 0x52, 0x54,
- 0xe2, 0xe2, 0x10, 0x0d, 0xd6, 0x02, 0x90, 0x37, 0xf0, 0x96},
- {0x33, 0x9b, 0x6b, 0x14, 0x50, 0x24, 0x9b, 0x55, 0x7a, 0x01,
- 0x87, 0x72, 0x84, 0xd9, 0xe0, 0x2f, 0xc3, 0xd2, 0xd8, 0xe9},
- {0x36, 0x79, 0xca, 0x35, 0x66, 0x87, 0x72, 0x30, 0x4d, 0x30,
- 0xa5, 0xfb, 0x87, 0x3b, 0x0f, 0xa7, 0x7b, 0xb7, 0x0d, 0x54},
- {0x36, 0x7d, 0x4b, 0x3b, 0x4f, 0xcb, 0xbc, 0x0b, 0x76, 0x7b,
- 0x2e, 0xc0, 0xcd, 0xb2, 0xa3, 0x6e, 0xab, 0x71, 0xa4, 0xeb},
- {0x36, 0x86, 0x35, 0x63, 0xfd, 0x51, 0x28, 0xc7, 0xbe, 0xa6,
- 0xf0, 0x05, 0xcf, 0xe9, 0xb4, 0x36, 0x68, 0x08, 0x6c, 0xce},
- {0x36, 0xb1, 0x2b, 0x49, 0xf9, 0x81, 0x9e, 0xd7, 0x4c, 0x9e,
- 0xbc, 0x38, 0x0f, 0xc6, 0x56, 0x8f, 0x5d, 0xac, 0xb2, 0xf7},
- {0x37, 0xf7, 0x6d, 0xe6, 0x07, 0x7c, 0x90, 0xc5, 0xb1, 0x3e,
- 0x93, 0x1a, 0xb7, 0x41, 0x10, 0xb4, 0xf2, 0xe4, 0x9a, 0x27},
- {0x39, 0x21, 0xc1, 0x15, 0xc1, 0x5d, 0x0e, 0xca, 0x5c, 0xcb,
- 0x5b, 0xc4, 0xf0, 0x7d, 0x21, 0xd8, 0x05, 0x0b, 0x56, 0x6a},
- {0x39, 0x4f, 0xf6, 0x85, 0x0b, 0x06, 0xbe, 0x52, 0xe5, 0x18,
- 0x56, 0xcc, 0x10, 0xe1, 0x80, 0xe8, 0x82, 0xb3, 0x85, 0xcc},
- {0x3a, 0x32, 0xef, 0x7b, 0x9a, 0xb8, 0x36, 0xf8, 0x37, 0x18,
- 0x1a, 0x4c, 0xef, 0xa3, 0x55, 0xc6, 0x46, 0x67, 0xac, 0xbf},
- {0x3a, 0x44, 0x73, 0x5a, 0xe5, 0x81, 0x90, 0x1f, 0x24, 0x86,
- 0x61, 0x46, 0x1e, 0x3b, 0x9c, 0xc4, 0x5f, 0xf5, 0x3a, 0x1b},
- {0x3b, 0x16, 0x6c, 0x3b, 0x7d, 0xc4, 0xb7, 0x51, 0xc9, 0xfe,
- 0x2a, 0xfa, 0xb9, 0x13, 0x56, 0x41, 0xe3, 0x88, 0xe1, 0x86},
- {0x3b, 0xc0, 0x38, 0x0b, 0x33, 0xc3, 0xf6, 0xa6, 0x0c, 0x86,
- 0x15, 0x22, 0x93, 0xd9, 0xdf, 0xf5, 0x4b, 0x81, 0xc0, 0x04},
- {0x3b, 0xc4, 0x9f, 0x48, 0xf8, 0xf3, 0x73, 0xa0, 0x9c, 0x1e,
- 0xbd, 0xf8, 0x5b, 0xb1, 0xc3, 0x65, 0xc7, 0xd8, 0x11, 0xb3},
- {0x3e, 0x2b, 0xf7, 0xf2, 0x03, 0x1b, 0x96, 0xf3, 0x8c, 0xe6,
- 0xc4, 0xd8, 0xa8, 0x5d, 0x3e, 0x2d, 0x58, 0x47, 0x6a, 0x0f},
- {0x3e, 0x5d, 0x35, 0x8f, 0x28, 0x3a, 0x0f, 0x64, 0x7c, 0x1c,
- 0x92, 0x7f, 0xfb, 0xaa, 0xd4, 0x85, 0x2d, 0x99, 0x72, 0x56},
- {0x3f, 0x01, 0x8e, 0x6f, 0xe3, 0x36, 0x09, 0x6a, 0x79, 0x1b,
- 0x81, 0xe7, 0x69, 0xbe, 0x70, 0x1a, 0xaf, 0x21, 0xe3, 0x07},
- {0x40, 0x54, 0xda, 0x6f, 0x1c, 0x3f, 0x40, 0x74, 0xac, 0xed,
- 0x0f, 0xec, 0xcd, 0xdb, 0x79, 0xd1, 0x53, 0xfb, 0x90, 0x1d},
- {0x40, 0x9d, 0x4b, 0xd9, 0x17, 0xb5, 0x5c, 0x27, 0xb6, 0x9b,
- 0x64, 0xcb, 0x98, 0x22, 0x44, 0x0d, 0xcd, 0x09, 0xb8, 0x89},
- {0x40, 0xaa, 0x38, 0x73, 0x1b, 0xd1, 0x89, 0xf9, 0xcd, 0xb5,
- 0xb9, 0xdc, 0x35, 0xe2, 0x13, 0x6f, 0x38, 0x77, 0x7a, 0xf4},
- {0x40, 0xb3, 0x31, 0xa0, 0xe9, 0xbf, 0xe8, 0x55, 0xbc, 0x39,
- 0x93, 0xca, 0x70, 0x4f, 0x4e, 0xc2, 0x51, 0xd4, 0x1d, 0x8f},
- {0x40, 0xe7, 0x8c, 0x1d, 0x52, 0x3d, 0x1c, 0xd9, 0x95, 0x4f,
- 0xac, 0x1a, 0x1a, 0xb3, 0xbd, 0x3c, 0xba, 0xa1, 0x5b, 0xfc},
- {0x42, 0xf8, 0x18, 0xe8, 0x33, 0x06, 0x3b, 0xf5, 0x16, 0xc6,
- 0x61, 0x8c, 0x1e, 0x60, 0xfd, 0x0f, 0x35, 0xc4, 0x76, 0x21},
- {0x43, 0x13, 0xbb, 0x96, 0xf1, 0xd5, 0x86, 0x9b, 0xc1, 0x4e,
- 0x6a, 0x92, 0xf6, 0xcf, 0xf6, 0x34, 0x69, 0x87, 0x82, 0x37},
- {0x43, 0xd9, 0xbc, 0xb5, 0x68, 0xe0, 0x39, 0xd0, 0x73, 0xa7,
- 0x4a, 0x71, 0xd8, 0x51, 0x1f, 0x74, 0x76, 0x08, 0x9c, 0xc3},
- {0x43, 0xf9, 0xb1, 0x10, 0xd5, 0xba, 0xfd, 0x48, 0x22, 0x52,
- 0x31, 0xb0, 0xd0, 0x08, 0x2b, 0x37, 0x2f, 0xef, 0x9a, 0x54},
- {0x47, 0xbe, 0xab, 0xc9, 0x22, 0xea, 0xe8, 0x0e, 0x78, 0x78,
- 0x34, 0x62, 0xa7, 0x9f, 0x45, 0xc2, 0x54, 0xfd, 0xe6, 0x8b},
- {0x48, 0x12, 0xbd, 0x92, 0x3c, 0xa8, 0xc4, 0x39, 0x06, 0xe7,
- 0x30, 0x6d, 0x27, 0x96, 0xe6, 0xa4, 0xcf, 0x22, 0x2e, 0x7d},
- {0x49, 0x0a, 0x75, 0x74, 0xde, 0x87, 0x0a, 0x47, 0xfe, 0x58,
- 0xee, 0xf6, 0xc7, 0x6b, 0xeb, 0xc6, 0x0b, 0x12, 0x40, 0x99},
- {0x4a, 0x3f, 0x8d, 0x6b, 0xdc, 0x0e, 0x1e, 0xcf, 0xcd, 0x72,
- 0xe3, 0x77, 0xde, 0xf2, 0xd7, 0xff, 0x92, 0xc1, 0x9b, 0xc7},
- {0x4a, 0x65, 0xd5, 0xf4, 0x1d, 0xef, 0x39, 0xb8, 0xb8, 0x90,
- 0x4a, 0x4a, 0xd3, 0x64, 0x81, 0x33, 0xcf, 0xc7, 0xa1, 0xd1},
- {0x4a, 0xbd, 0xee, 0xec, 0x95, 0x0d, 0x35, 0x9c, 0x89, 0xae,
- 0xc7, 0x52, 0xa1, 0x2c, 0x5b, 0x29, 0xf6, 0xd6, 0xaa, 0x0c},
- {0x4a, 0xd4, 0x4d, 0x4d, 0x81, 0x2e, 0x42, 0x23, 0x2f, 0xe0,
- 0x38, 0x76, 0x4c, 0x7b, 0x0c, 0xeb, 0x46, 0x6e, 0xef, 0x96},
- {0x4c, 0xab, 0x31, 0xa1, 0x28, 0x34, 0x02, 0x52, 0xbc, 0xb4,
- 0x67, 0xd6, 0x2a, 0x99, 0x63, 0x1b, 0x21, 0x77, 0x20, 0x50},
- {0x4d, 0x23, 0x78, 0xec, 0x91, 0x95, 0x39, 0xb5, 0x00, 0x7f,
- 0x75, 0x8f, 0x03, 0x3b, 0x21, 0x1e, 0xc5, 0x4d, 0x8b, 0xcf},
- {0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58,
- 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5},
- {0x4f, 0x99, 0xaa, 0x93, 0xfb, 0x2b, 0xd1, 0x37, 0x26, 0xa1,
- 0x99, 0x4a, 0xce, 0x7f, 0xf0, 0x05, 0xf2, 0x93, 0x5d, 0x1e},
- {0x50, 0x30, 0x06, 0x09, 0x1d, 0x97, 0xd4, 0xf5, 0xae, 0x39,
- 0xf7, 0xcb, 0xe7, 0x92, 0x7d, 0x7d, 0x65, 0x2d, 0x34, 0x31},
- {0x51, 0x7f, 0x61, 0x1e, 0x29, 0x91, 0x6b, 0x53, 0x82, 0xfb,
- 0x72, 0xe7, 0x44, 0xd9, 0x8d, 0xc3, 0xcc, 0x53, 0x6d, 0x64},
- {0x51, 0xa4, 0x4c, 0x28, 0xf3, 0x13, 0xe3, 0xf9, 0xcb, 0x5e,
- 0x7c, 0x0a, 0x1e, 0x0e, 0x0d, 0xd2, 0x84, 0x37, 0x58, 0xae},
- {0x51, 0xc3, 0x24, 0x7d, 0x60, 0xf3, 0x56, 0xc7, 0xca, 0x3b,
- 0xaf, 0x4c, 0x3f, 0x42, 0x9d, 0xac, 0x93, 0xee, 0x7b, 0x74},
- {0x51, 0xc6, 0xe7, 0x08, 0x49, 0x06, 0x6e, 0xf3, 0x92, 0xd4,
- 0x5c, 0xa0, 0x0d, 0x6d, 0xa3, 0x62, 0x8f, 0xc3, 0x52, 0x39},
- {0x51, 0xcc, 0xa0, 0x71, 0x0a, 0xf7, 0x73, 0x3d, 0x34, 0xac,
- 0xdc, 0x19, 0x45, 0x09, 0x9f, 0x43, 0x5c, 0x7f, 0xc5, 0x9f},
- {0x55, 0xa6, 0x72, 0x3e, 0xcb, 0xf2, 0xec, 0xcd, 0xc3, 0x23,
- 0x74, 0x70, 0x19, 0x9d, 0x2a, 0xbe, 0x11, 0xe3, 0x81, 0xd1},
- {0x56, 0x4b, 0x6f, 0x8c, 0x56, 0x38, 0xdc, 0x05, 0x5b, 0xba,
- 0x2b, 0xa1, 0x39, 0x0f, 0x7e, 0x31, 0x95, 0x4a, 0x55, 0x50},
- {0x56, 0xe0, 0xfa, 0xc0, 0x3b, 0x8f, 0x18, 0x23, 0x55, 0x18,
- 0xe5, 0xd3, 0x11, 0xca, 0xe8, 0xc2, 0x43, 0x31, 0xab, 0x66},
- {0x57, 0xf0, 0x3d, 0xce, 0xfb, 0x45, 0x69, 0x4c, 0x1c, 0x25,
- 0xe6, 0xee, 0xa0, 0x2c, 0x43, 0xd7, 0x52, 0x38, 0xd3, 0xc4},
- {0x58, 0x0f, 0x80, 0x47, 0x92, 0xab, 0xc6, 0x3b, 0xbb, 0x80,
- 0x15, 0x4d, 0x4d, 0xfd, 0xdd, 0x8b, 0x2e, 0xf2, 0x67, 0x4e},
- {0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd,
- 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4},
- {0x58, 0xd5, 0x2d, 0xb9, 0x33, 0x01, 0xa4, 0xfd, 0x29, 0x1a,
- 0x8c, 0x96, 0x45, 0xa0, 0x8f, 0xee, 0x7f, 0x52, 0x92, 0x82},
- {0x58, 0xe8, 0xab, 0xb0, 0x36, 0x15, 0x33, 0xfb, 0x80, 0xf7,
- 0x9b, 0x1b, 0x6d, 0x29, 0xd3, 0xff, 0x8d, 0x5f, 0x00, 0xf0},
- {0x59, 0x0d, 0x2d, 0x7d, 0x88, 0x4f, 0x40, 0x2e, 0x61, 0x7e,
- 0xa5, 0x62, 0x32, 0x17, 0x65, 0xcf, 0x17, 0xd8, 0x94, 0xe9},
- {0x59, 0x22, 0xa1, 0xe1, 0x5a, 0xea, 0x16, 0x35, 0x21, 0xf8,
- 0x98, 0x39, 0x6a, 0x46, 0x46, 0xb0, 0x44, 0x1b, 0x0f, 0xa9},
- {0x59, 0xaf, 0x82, 0x79, 0x91, 0x86, 0xc7, 0xb4, 0x75, 0x07,
- 0xcb, 0xcf, 0x03, 0x57, 0x46, 0xeb, 0x04, 0xdd, 0xb7, 0x16},
- {0x5a, 0x4d, 0x0e, 0x8b, 0x5f, 0xdc, 0xfd, 0xf6, 0x4e, 0x72,
- 0x99, 0xa3, 0x6c, 0x06, 0x0d, 0xb2, 0x22, 0xca, 0x78, 0xe4},
- {0x5c, 0xfb, 0x1f, 0x5d, 0xb7, 0x32, 0xe4, 0x08, 0x4c, 0x0d,
- 0xd4, 0x97, 0x85, 0x74, 0xe0, 0xcb, 0xc0, 0x93, 0xbe, 0xb3},
- {0x5d, 0x98, 0x9c, 0xdb, 0x15, 0x96, 0x11, 0x36, 0x51, 0x65,
- 0x64, 0x1b, 0x56, 0x0f, 0xdb, 0xea, 0x2a, 0xc2, 0x3e, 0xf1},
- {0x5d, 0xe8, 0x3e, 0xe8, 0x2a, 0xc5, 0x09, 0x0a, 0xea, 0x9d,
- 0x6a, 0xc4, 0xe7, 0xa6, 0xe2, 0x13, 0xf9, 0x46, 0xe1, 0x79},
- {0x5f, 0x3a, 0xfc, 0x0a, 0x8b, 0x64, 0xf6, 0x86, 0x67, 0x34,
- 0x74, 0xdf, 0x7e, 0xa9, 0xa2, 0xfe, 0xf9, 0xfa, 0x7a, 0x51},
- {0x5f, 0x3b, 0x8c, 0xf2, 0xf8, 0x10, 0xb3, 0x7d, 0x78, 0xb4,
- 0xce, 0xec, 0x19, 0x19, 0xc3, 0x73, 0x34, 0xb9, 0xc7, 0x74},
- {0x5f, 0x4e, 0x1f, 0xcf, 0x31, 0xb7, 0x91, 0x3b, 0x85, 0x0b,
- 0x54, 0xf6, 0xe5, 0xff, 0x50, 0x1a, 0x2b, 0x6f, 0xc6, 0xcf},
- {0x5f, 0xb7, 0xee, 0x06, 0x33, 0xe2, 0x59, 0xdb, 0xad, 0x0c,
- 0x4c, 0x9a, 0xe6, 0xd3, 0x8f, 0x1a, 0x61, 0xc7, 0xdc, 0x25},
- {0x61, 0x1e, 0x5b, 0x66, 0x2c, 0x59, 0x3a, 0x08, 0xff, 0x58,
- 0xd1, 0x4a, 0xe2, 0x24, 0x52, 0xd1, 0x98, 0xdf, 0x6c, 0x60},
- {0x61, 0x57, 0x3a, 0x11, 0xdf, 0x0e, 0xd8, 0x7e, 0xd5, 0x92,
- 0x65, 0x22, 0xea, 0xd0, 0x56, 0xd7, 0x44, 0xb3, 0x23, 0x71},
- {0x61, 0xef, 0x43, 0xd7, 0x7f, 0xca, 0xd4, 0x61, 0x51, 0xbc,
- 0x98, 0xe0, 0xc3, 0x59, 0x12, 0xaf, 0x9f, 0xeb, 0x63, 0x11},
- {0x62, 0x52, 0xdc, 0x40, 0xf7, 0x11, 0x43, 0xa2, 0x2f, 0xde,
- 0x9e, 0xf7, 0x34, 0x8e, 0x06, 0x42, 0x51, 0xb1, 0x81, 0x18},
- {0x62, 0x7f, 0x8d, 0x78, 0x27, 0x65, 0x63, 0x99, 0xd2, 0x7d,
- 0x7f, 0x90, 0x44, 0xc9, 0xfe, 0xb3, 0xf3, 0x3e, 0xfa, 0x9a},
- {0x66, 0x31, 0xbf, 0x9e, 0xf7, 0x4f, 0x9e, 0xb6, 0xc9, 0xd5,
- 0xa6, 0x0c, 0xba, 0x6a, 0xbe, 0xd1, 0xf7, 0xbd, 0xef, 0x7b},
- {0x67, 0x24, 0x90, 0x2e, 0x48, 0x01, 0xb0, 0x22, 0x96, 0x40,
- 0x10, 0x46, 0xb4, 0xb1, 0x67, 0x2c, 0xa9, 0x75, 0xfd, 0x2b},
- {0x67, 0x65, 0x0d, 0xf1, 0x7e, 0x8e, 0x7e, 0x5b, 0x82, 0x40,
- 0xa4, 0xf4, 0x56, 0x4b, 0xcf, 0xe2, 0x3d, 0x69, 0xc6, 0xf0},
- {0x67, 0x82, 0xaa, 0xe0, 0xed, 0xee, 0xe2, 0x1a, 0x58, 0x39,
- 0xd3, 0xc0, 0xcd, 0x14, 0x68, 0x0a, 0x4f, 0x60, 0x14, 0x2a},
- {0x67, 0x9a, 0x4f, 0x81, 0xfc, 0x70, 0x5d, 0xde, 0xc4, 0x19,
- 0x77, 0x8d, 0xd2, 0xeb, 0xd8, 0x75, 0xf4, 0xc2, 0x42, 0xc6},
- {0x69, 0x69, 0x56, 0x2e, 0x40, 0x80, 0xf4, 0x24, 0xa1, 0xe7,
- 0x19, 0x9f, 0x14, 0xba, 0xf3, 0xee, 0x58, 0xab, 0x6a, 0xbb},
- {0x69, 0xbd, 0x8c, 0xf4, 0x9c, 0xd3, 0x00, 0xfb, 0x59, 0x2e,
- 0x17, 0x93, 0xca, 0x55, 0x6a, 0xf3, 0xec, 0xaa, 0x35, 0xfb},
- {0x6a, 0x84, 0xfe, 0x62, 0x7e, 0xcc, 0x49, 0xa1, 0xbe, 0x02,
- 0xe9, 0x18, 0xfa, 0xc9, 0xe1, 0xf7, 0x32, 0x80, 0x3a, 0x62},
- {0x6b, 0x2f, 0x34, 0xad, 0x89, 0x58, 0xbe, 0x62, 0xfd, 0xb0,
- 0x6b, 0x5c, 0xce, 0xbb, 0x9d, 0xd9, 0x4f, 0x4e, 0x39, 0xf3},
- {0x6b, 0x81, 0x44, 0x6a, 0x5c, 0xdd, 0xf4, 0x74, 0xa0, 0xf8,
- 0x00, 0xff, 0xbe, 0x69, 0xfd, 0x0d, 0xb6, 0x28, 0x75, 0x16},
- {0x6e, 0x3a, 0x55, 0xa4, 0x19, 0x0c, 0x19, 0x5c, 0x93, 0x84,
- 0x3c, 0xc0, 0xdb, 0x72, 0x2e, 0x31, 0x30, 0x61, 0xf0, 0xb1},
- {0x70, 0x17, 0x9b, 0x86, 0x8c, 0x00, 0xa4, 0xfa, 0x60, 0x91,
- 0x52, 0x22, 0x3f, 0x9f, 0x3e, 0x32, 0xbd, 0xe0, 0x05, 0x62},
- {0x70, 0x43, 0x2d, 0xe4, 0x3c, 0x9d, 0x1e, 0x79, 0xc1, 0x13,
- 0x25, 0x20, 0xbc, 0x58, 0x43, 0xf7, 0xbb, 0x7d, 0x92, 0x95},
- {0x74, 0x20, 0x74, 0x41, 0x72, 0x9c, 0xdd, 0x92, 0xec, 0x79,
- 0x31, 0xd8, 0x23, 0x10, 0x8d, 0xc2, 0x81, 0x92, 0xe2, 0xbb},
- {0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45,
- 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2},
- {0x74, 0x54, 0x53, 0x5c, 0x24, 0xa3, 0xa7, 0x58, 0x20, 0x7e,
- 0x3e, 0x3e, 0xd3, 0x24, 0xf8, 0x16, 0xfb, 0x21, 0x16, 0x49},
- {0x74, 0xa2, 0x66, 0xf0, 0x95, 0xa9, 0xa4, 0xeb, 0x95, 0x22,
- 0x19, 0xd6, 0x05, 0xda, 0x93, 0x63, 0xf5, 0x14, 0xfa, 0xf9},
- {0x74, 0xf8, 0xa3, 0xc3, 0xef, 0xe7, 0xb3, 0x90, 0x06, 0x4b,
- 0x83, 0x90, 0x3c, 0x21, 0x64, 0x60, 0x20, 0xe5, 0xdf, 0xce},
- {0x75, 0xe0, 0xab, 0xb6, 0x13, 0x85, 0x12, 0x27, 0x1c, 0x04,
- 0xf8, 0x5f, 0xdd, 0xde, 0x38, 0xe4, 0xb7, 0x24, 0x2e, 0xfe},
- {0x76, 0xe2, 0x7e, 0xc1, 0x4f, 0xdb, 0x82, 0xc1, 0xc0, 0xa6,
- 0x75, 0xb5, 0x05, 0xbe, 0x3d, 0x29, 0xb4, 0xed, 0xdb, 0xbb},
- {0x77, 0x47, 0x4f, 0xc6, 0x30, 0xe4, 0x0f, 0x4c, 0x47, 0x64,
- 0x3f, 0x84, 0xba, 0xb8, 0xc6, 0x95, 0x4a, 0x8a, 0x41, 0xec},
- {0x78, 0x6a, 0x74, 0xac, 0x76, 0xab, 0x14, 0x7f, 0x9c, 0x6a,
- 0x30, 0x50, 0xba, 0x9e, 0xa8, 0x7e, 0xfe, 0x9a, 0xce, 0x3c},
- {0x79, 0x98, 0xa3, 0x08, 0xe1, 0x4d, 0x65, 0x85, 0xe6, 0xc2,
- 0x1e, 0x15, 0x3a, 0x71, 0x9f, 0xba, 0x5a, 0xd3, 0x4a, 0xd9},
- {0x7e, 0x04, 0xde, 0x89, 0x6a, 0x3e, 0x66, 0x6d, 0x00, 0xe6,
- 0x87, 0xd3, 0x3f, 0xfa, 0xd9, 0x3b, 0xe8, 0x3d, 0x34, 0x9e},
- {0x7e, 0x78, 0x4a, 0x10, 0x1c, 0x82, 0x65, 0xcc, 0x2d, 0xe1,
- 0xf1, 0x6d, 0x47, 0xb4, 0x40, 0xca, 0xd9, 0x0a, 0x19, 0x45},
- {0x7f, 0x8a, 0xb0, 0xcf, 0xd0, 0x51, 0x87, 0x6a, 0x66, 0xf3,
- 0x36, 0x0f, 0x47, 0xc8, 0x8d, 0x8c, 0xd3, 0x35, 0xfc, 0x74},
- {0x80, 0x1d, 0x62, 0xd0, 0x7b, 0x44, 0x9d, 0x5c, 0x5c, 0x03,
- 0x5c, 0x98, 0xea, 0x61, 0xfa, 0x44, 0x3c, 0x2a, 0x58, 0xfe},
- {0x80, 0x25, 0xef, 0xf4, 0x6e, 0x70, 0xc8, 0xd4, 0x72, 0x24,
- 0x65, 0x84, 0xfe, 0x40, 0x3b, 0x8a, 0x8d, 0x6a, 0xdb, 0xf5},
- {0x82, 0x50, 0xbe, 0xd5, 0xa2, 0x14, 0x43, 0x3a, 0x66, 0x37,
- 0x7c, 0xbc, 0x10, 0xef, 0x83, 0xf6, 0x69, 0xda, 0x3a, 0x67},
- {0x82, 0x68, 0x99, 0x3e, 0xda, 0xeb, 0xb1, 0xe4, 0xfb, 0x77,
- 0x91, 0x0f, 0x12, 0xcb, 0xd6, 0xc6, 0x70, 0xf0, 0x7c, 0xea},
- {0x84, 0xf2, 0xe3, 0xdd, 0x83, 0x13, 0x3e, 0xa9, 0x1d, 0x19,
- 0x52, 0x7f, 0x02, 0xd7, 0x29, 0xbf, 0xc1, 0x5f, 0xe6, 0x67},
- {0x85, 0x37, 0x1c, 0xa6, 0xe5, 0x50, 0x14, 0x3d, 0xce, 0x28,
- 0x03, 0x47, 0x1b, 0xde, 0x3a, 0x09, 0xe8, 0xf8, 0x77, 0x0f},
- {0x85, 0xa4, 0x08, 0xc0, 0x9c, 0x19, 0x3e, 0x5d, 0x51, 0x58,
- 0x7d, 0xcd, 0xd6, 0x13, 0x30, 0xfd, 0x8c, 0xde, 0x37, 0xbf},
- {0x85, 0xb5, 0xff, 0x67, 0x9b, 0x0c, 0x79, 0x96, 0x1f, 0xc8,
- 0x6e, 0x44, 0x22, 0x00, 0x46, 0x13, 0xdb, 0x17, 0x92, 0x84},
- {0x86, 0xe8, 0x17, 0xc8, 0x1a, 0x5c, 0xa6, 0x72, 0xfe, 0x00,
- 0x0f, 0x36, 0xf8, 0x78, 0xc1, 0x95, 0x18, 0xd6, 0xf8, 0x44},
- {0x87, 0x81, 0xc2, 0x5a, 0x96, 0xbd, 0xc2, 0xfb, 0x4c, 0x65,
- 0x06, 0x4f, 0xf9, 0x39, 0x0b, 0x26, 0x04, 0x8a, 0x0e, 0x01},
- {0x87, 0x82, 0xc6, 0xc3, 0x04, 0x35, 0x3b, 0xcf, 0xd2, 0x96,
- 0x92, 0xd2, 0x59, 0x3e, 0x7d, 0x44, 0xd9, 0x34, 0xff, 0x11},
- {0x87, 0x9f, 0x4b, 0xee, 0x05, 0xdf, 0x98, 0x58, 0x3b, 0xe3,
- 0x60, 0xd6, 0x33, 0xe7, 0x0d, 0x3f, 0xfe, 0x98, 0x71, 0xaf},
- {0x89, 0xdf, 0x74, 0xfe, 0x5c, 0xf4, 0x0f, 0x4a, 0x80, 0xf9,
- 0xe3, 0x37, 0x7d, 0x54, 0xda, 0x91, 0xe1, 0x01, 0x31, 0x8e},
- {0x8b, 0xaf, 0x4c, 0x9b, 0x1d, 0xf0, 0x2a, 0x92, 0xf7, 0xda,
- 0x12, 0x8e, 0xb9, 0x1b, 0xac, 0xf4, 0x98, 0x60, 0x4b, 0x6f},
- {0x8c, 0x94, 0x1b, 0x34, 0xea, 0x1e, 0xa6, 0xed, 0x9a, 0xe2,
- 0xbc, 0x54, 0xcf, 0x68, 0x72, 0x52, 0xb4, 0xc9, 0xb5, 0x61},
- {0x8c, 0x96, 0xba, 0xeb, 0xdd, 0x2b, 0x07, 0x07, 0x48, 0xee,
- 0x30, 0x32, 0x66, 0xa0, 0xf3, 0x98, 0x6e, 0x7c, 0xae, 0x58},
- {0x8c, 0xc4, 0x30, 0x7b, 0xc6, 0x07, 0x55, 0xe7, 0xb2, 0x2d,
- 0xd9, 0xf7, 0xfe, 0xa2, 0x45, 0x93, 0x6c, 0x7c, 0xf2, 0x88},
- {0x8c, 0xf4, 0x27, 0xfd, 0x79, 0x0c, 0x3a, 0xd1, 0x66, 0x06,
- 0x8d, 0xe8, 0x1e, 0x57, 0xef, 0xbb, 0x93, 0x22, 0x72, 0xd4},
- {0x8d, 0x17, 0x84, 0xd5, 0x37, 0xf3, 0x03, 0x7d, 0xec, 0x70,
- 0xfe, 0x57, 0x8b, 0x51, 0x9a, 0x99, 0xe6, 0x10, 0xd7, 0xb0},
- {0x8e, 0x1c, 0x74, 0xf8, 0xa6, 0x20, 0xb9, 0xe5, 0x8a, 0xf4,
- 0x61, 0xfa, 0xec, 0x2b, 0x47, 0x56, 0x51, 0x1a, 0x52, 0xc6},
- {0x8e, 0x5b, 0xd5, 0x0d, 0x6a, 0xe6, 0x86, 0xd6, 0x52, 0x52,
- 0xf8, 0x43, 0xa9, 0xd4, 0xb9, 0x6d, 0x19, 0x77, 0x30, 0xab},
- {0x90, 0x5f, 0x94, 0x2f, 0xd9, 0xf2, 0x8f, 0x67, 0x9b, 0x37,
- 0x81, 0x80, 0xfd, 0x4f, 0x84, 0x63, 0x47, 0xf6, 0x45, 0xc1},
- {0x90, 0xae, 0xa2, 0x69, 0x85, 0xff, 0x14, 0x80, 0x4c, 0x43,
- 0x49, 0x52, 0xec, 0xe9, 0x60, 0x84, 0x77, 0xaf, 0x55, 0x6f},
- {0x91, 0xc6, 0xd6, 0xee, 0x3e, 0x8a, 0xc8, 0x63, 0x84, 0xe5,
- 0x48, 0xc2, 0x99, 0x29, 0x5c, 0x75, 0x6c, 0x81, 0x7b, 0x81},
- {0x92, 0x5a, 0x8f, 0x8d, 0x2c, 0x6d, 0x04, 0xe0, 0x66, 0x5f,
- 0x59, 0x6a, 0xff, 0x22, 0xd8, 0x63, 0xe8, 0x25, 0x6f, 0x3f},
- {0x93, 0xe6, 0xab, 0x22, 0x03, 0x03, 0xb5, 0x23, 0x28, 0xdc,
- 0xda, 0x56, 0x9e, 0xba, 0xe4, 0xd1, 0xd1, 0xcc, 0xfb, 0x65},
- {0x94, 0x32, 0xbd, 0x9a, 0xec, 0x1d, 0x75, 0xd1, 0x70, 0x5c,
- 0x54, 0x3a, 0xa3, 0x4c, 0x4a, 0xf6, 0xa5, 0x26, 0xc1, 0x3d},
- {0x96, 0x56, 0xcd, 0x7b, 0x57, 0x96, 0x98, 0x95, 0xd0, 0xe1,
- 0x41, 0x46, 0x68, 0x06, 0xfb, 0xb8, 0xc6, 0x11, 0x06, 0x87},
- {0x96, 0x83, 0x38, 0xf1, 0x13, 0xe3, 0x6a, 0x7b, 0xab, 0xdd,
- 0x08, 0xf7, 0x77, 0x63, 0x91, 0xa6, 0x87, 0x36, 0x58, 0x2e},
- {0x96, 0xc9, 0x1b, 0x0b, 0x95, 0xb4, 0x10, 0x98, 0x42, 0xfa,
- 0xd0, 0xd8, 0x22, 0x79, 0xfe, 0x60, 0xfa, 0xb9, 0x16, 0x83},
- {0x97, 0x81, 0x79, 0x50, 0xd8, 0x1c, 0x96, 0x70, 0xcc, 0x34,
- 0xd8, 0x09, 0xcf, 0x79, 0x44, 0x31, 0x36, 0x7e, 0xf4, 0x74},
- {0x98, 0x45, 0xa4, 0x31, 0xd5, 0x19, 0x59, 0xca, 0xf2, 0x25,
- 0x32, 0x2b, 0x4a, 0x4f, 0xe9, 0xf2, 0x23, 0xce, 0x6d, 0x15},
- {0x99, 0xa6, 0x9b, 0xe6, 0x1a, 0xfe, 0x88, 0x6b, 0x4d, 0x2b,
- 0x82, 0x00, 0x7c, 0xb8, 0x54, 0xfc, 0x31, 0x7e, 0x15, 0x39},
- {0x9b, 0xaa, 0xe5, 0x9f, 0x56, 0xee, 0x21, 0xcb, 0x43, 0x5a,
- 0xbe, 0x25, 0x93, 0xdf, 0xa7, 0xf0, 0x40, 0xd1, 0x1d, 0xcb},
- {0x9c, 0xbb, 0x48, 0x53, 0xf6, 0xa4, 0xf6, 0xd3, 0x52, 0xa4,
- 0xe8, 0x32, 0x52, 0x55, 0x60, 0x13, 0xf5, 0xad, 0xaf, 0x65},
- {0x9d, 0x70, 0xbb, 0x01, 0xa5, 0xa4, 0xa0, 0x18, 0x11, 0x2e,
- 0xf7, 0x1c, 0x01, 0xb9, 0x32, 0xc5, 0x34, 0xe7, 0x88, 0xa8},
- {0x9f, 0xad, 0x91, 0xa6, 0xce, 0x6a, 0xc6, 0xc5, 0x00, 0x47,
- 0xc4, 0x4e, 0xc9, 0xd4, 0xa5, 0x0d, 0x92, 0xd8, 0x49, 0x79},
- {0xa0, 0xa1, 0xab, 0x90, 0xc9, 0xfc, 0x84, 0x7b, 0x3b, 0x12,
- 0x61, 0xe8, 0x97, 0x7d, 0x5f, 0xd3, 0x22, 0x61, 0xd3, 0xcc},
- {0xa1, 0x4b, 0x48, 0xd9, 0x43, 0xee, 0x0a, 0x0e, 0x40, 0x90,
- 0x4f, 0x3c, 0xe0, 0xa4, 0xc0, 0x91, 0x93, 0x51, 0x5d, 0x3f},
- {0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55,
- 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b},
- {0xa2, 0x48, 0x41, 0xab, 0xd6, 0xa0, 0xca, 0x5c, 0xcd, 0x2a,
- 0xa3, 0xb1, 0x90, 0x70, 0x1e, 0xd6, 0x4b, 0x39, 0xfe, 0x53},
- {0xa3, 0xf1, 0x33, 0x3f, 0xe2, 0x42, 0xbf, 0xcf, 0xc5, 0xd1,
- 0x4e, 0x8f, 0x39, 0x42, 0x98, 0x40, 0x68, 0x10, 0xd1, 0xa0},
- {0xa6, 0x76, 0xdb, 0xf1, 0x92, 0x48, 0xf5, 0x2c, 0x57, 0x53,
- 0xd0, 0xda, 0xc1, 0x4c, 0x53, 0xc4, 0x74, 0xa4, 0x83, 0x5e},
- {0xa6, 0x9a, 0x91, 0xfd, 0x05, 0x7f, 0x13, 0x6a, 0x42, 0x63,
- 0x0b, 0xb1, 0x76, 0x0d, 0x2d, 0x51, 0x12, 0x0c, 0x16, 0x50},
- {0xa8, 0x98, 0x5d, 0x3a, 0x65, 0xe5, 0xe5, 0xc4, 0xb2, 0xd7,
- 0xd6, 0x6d, 0x40, 0xc6, 0xdd, 0x2f, 0xb1, 0x9c, 0x54, 0x36},
- {0xaa, 0xdb, 0xbc, 0x22, 0x23, 0x8f, 0xc4, 0x01, 0xa1, 0x27,
- 0xbb, 0x38, 0xdd, 0xf4, 0x1d, 0xdb, 0x08, 0x9e, 0xf0, 0x12},
- {0xac, 0xed, 0x5f, 0x65, 0x53, 0xfd, 0x25, 0xce, 0x01, 0x5f,
- 0x1f, 0x7a, 0x48, 0x3b, 0x6a, 0x74, 0x9f, 0x61, 0x78, 0xc6},
- {0xad, 0x7e, 0x1c, 0x28, 0xb0, 0x64, 0xef, 0x8f, 0x60, 0x03,
- 0x40, 0x20, 0x14, 0xc3, 0xd0, 0xe3, 0x37, 0x0e, 0xb5, 0x8a},
- {0xae, 0x3b, 0x31, 0xbf, 0x8f, 0xd8, 0x91, 0x07, 0x9c, 0xf1,
- 0xdf, 0x34, 0xcb, 0xce, 0x6e, 0x70, 0xd3, 0x7f, 0xb5, 0xb0},
- {0xae, 0x50, 0x83, 0xed, 0x7c, 0xf4, 0x5c, 0xbc, 0x8f, 0x61,
- 0xc6, 0x21, 0xfe, 0x68, 0x5d, 0x79, 0x42, 0x21, 0x15, 0x6e},
- {0xae, 0xc5, 0xfb, 0x3f, 0xc8, 0xe1, 0xbf, 0xc4, 0xe5, 0x4f,
- 0x03, 0x07, 0x5a, 0x9a, 0xe8, 0x00, 0xb7, 0xf7, 0xb6, 0xfa},
- {0xb0, 0x91, 0xaa, 0x91, 0x38, 0x47, 0xf3, 0x13, 0xd7, 0x27,
- 0xbc, 0xef, 0xc8, 0x17, 0x9f, 0x08, 0x6f, 0x3a, 0x8c, 0x0f},
- {0xb1, 0x2e, 0x13, 0x63, 0x45, 0x86, 0xa4, 0x6f, 0x1a, 0xb2,
- 0x60, 0x68, 0x37, 0x58, 0x2d, 0xc4, 0xac, 0xfd, 0x94, 0x97},
- {0xb1, 0x72, 0xb1, 0xa5, 0x6d, 0x95, 0xf9, 0x1f, 0xe5, 0x02,
- 0x87, 0xe1, 0x4d, 0x37, 0xea, 0x6a, 0x44, 0x63, 0x76, 0x8a},
- {0xb1, 0xbc, 0x96, 0x8b, 0xd4, 0xf4, 0x9d, 0x62, 0x2a, 0xa8,
- 0x9a, 0x81, 0xf2, 0x15, 0x01, 0x52, 0xa4, 0x1d, 0x82, 0x9c},
- {0xb3, 0x1e, 0xb1, 0xb7, 0x40, 0xe3, 0x6c, 0x84, 0x02, 0xda,
- 0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9},
- {0xb3, 0xea, 0xc4, 0x47, 0x76, 0xc9, 0xc8, 0x1c, 0xea, 0xf2,
- 0x9d, 0x95, 0xb6, 0xcc, 0xa0, 0x08, 0x1b, 0x67, 0xec, 0x9d},
- {0xb4, 0x35, 0xd4, 0xe1, 0x11, 0x9d, 0x1c, 0x66, 0x90, 0xa7,
- 0x49, 0xeb, 0xb3, 0x94, 0xbd, 0x63, 0x7b, 0xa7, 0x82, 0xb7},
- {0xb4, 0x57, 0x12, 0x1e, 0x63, 0x45, 0xff, 0x93, 0x5d, 0x6b,
- 0x1c, 0xa2, 0xdd, 0xf4, 0x52, 0x3c, 0xc6, 0xd0, 0xef, 0x6b},
- {0xb5, 0x1c, 0x06, 0x7c, 0xee, 0x2b, 0x0c, 0x3d, 0xf8, 0x55,
- 0xab, 0x2d, 0x92, 0xf4, 0xfe, 0x39, 0xd4, 0xe7, 0x0f, 0x0e},
- {0xb5, 0x2c, 0xb0, 0x2f, 0xd5, 0x67, 0xe0, 0x35, 0x9f, 0xe8,
- 0xfa, 0x4d, 0x4c, 0x41, 0x03, 0x79, 0x70, 0xfe, 0x01, 0xb0},
- {0xb5, 0x61, 0xeb, 0xea, 0xa4, 0xde, 0xe4, 0x25, 0x4b, 0x69,
- 0x1a, 0x98, 0xa5, 0x57, 0x47, 0xc2, 0x34, 0xc7, 0xd9, 0x71},
- {0xb6, 0xca, 0x21, 0x5b, 0x83, 0x6c, 0x35, 0x10, 0x1d, 0xaf,
- 0x74, 0x63, 0x90, 0x0a, 0x93, 0x68, 0x80, 0x76, 0x7a, 0xa6},
- {0xb8, 0x01, 0x86, 0xd1, 0xeb, 0x9c, 0x86, 0xa5, 0x41, 0x04,
- 0xcf, 0x30, 0x54, 0xf3, 0x4c, 0x52, 0xb7, 0xe5, 0x58, 0xc6},
- {0xb8, 0x23, 0x6b, 0x00, 0x2f, 0x1d, 0x16, 0x86, 0x53, 0x01,
- 0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb},
- {0xb8, 0x6e, 0x79, 0x16, 0x20, 0xf7, 0x59, 0xf1, 0x7b, 0x8d,
- 0x25, 0xe3, 0x8c, 0xa8, 0xbe, 0x32, 0xe7, 0xd5, 0xea, 0xc2},
- {0xba, 0x29, 0x41, 0x60, 0x77, 0x98, 0x3f, 0xf4, 0xf3, 0xef,
- 0xf2, 0x31, 0x05, 0x3b, 0x2e, 0xea, 0x6d, 0x4d, 0x45, 0xfd},
- {0xc0, 0x60, 0xed, 0x44, 0xcb, 0xd8, 0x81, 0xbd, 0x0e, 0xf8,
- 0x6c, 0x0b, 0xa2, 0x87, 0xdd, 0xcf, 0x81, 0x67, 0x47, 0x8c},
- {0xc8, 0xec, 0x8c, 0x87, 0x92, 0x69, 0xcb, 0x4b, 0xab, 0x39,
- 0xe9, 0x8d, 0x7e, 0x57, 0x67, 0xf3, 0x14, 0x95, 0x73, 0x9d},
- {0xc9, 0xa8, 0xb9, 0xe7, 0x55, 0x80, 0x5e, 0x58, 0xe3, 0x53,
- 0x77, 0xa7, 0x25, 0xeb, 0xaf, 0xc3, 0x7b, 0x27, 0xcc, 0xd7},
- {0xca, 0x39, 0xd8, 0xea, 0x48, 0x22, 0x13, 0x7f, 0x33, 0x8d,
- 0xca, 0x79, 0x56, 0x6e, 0xdd, 0xf0, 0x54, 0x7e, 0xce, 0xa7},
- {0xca, 0x3a, 0xfb, 0xcf, 0x12, 0x40, 0x36, 0x4b, 0x44, 0xb2,
- 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7c, 0xf7},
- {0xcb, 0x44, 0xa0, 0x97, 0x85, 0x7c, 0x45, 0xfa, 0x18, 0x7e,
- 0xd9, 0x52, 0x08, 0x6c, 0xb9, 0x84, 0x1f, 0x2d, 0x51, 0xb5},
- {0xcb, 0x65, 0x82, 0x64, 0xea, 0x8c, 0xda, 0x18, 0x6e, 0x17,
- 0x52, 0xfb, 0x52, 0xc3, 0x97, 0x36, 0x7e, 0xa3, 0x87, 0xbe},
- {0xcb, 0xa1, 0xc5, 0xf8, 0xb0, 0xe3, 0x5e, 0xb8, 0xb9, 0x45,
- 0x12, 0xd3, 0xf9, 0x34, 0xa2, 0xe9, 0x06, 0x10, 0xd3, 0x36},
- {0xcc, 0xab, 0x0e, 0xa0, 0x4c, 0x23, 0x01, 0xd6, 0x69, 0x7b,
- 0xdd, 0x37, 0x9f, 0xcd, 0x12, 0xeb, 0x24, 0xe3, 0x94, 0x9d},
- {0xce, 0x6a, 0x64, 0xa3, 0x09, 0xe4, 0x2f, 0xbb, 0xd9, 0x85,
- 0x1c, 0x45, 0x3e, 0x64, 0x09, 0xea, 0xe8, 0x7d, 0x60, 0xf1},
- {0xcf, 0x9e, 0x87, 0x6d, 0xd3, 0xeb, 0xfc, 0x42, 0x26, 0x97,
- 0xa3, 0xb5, 0xa3, 0x7a, 0xa0, 0x76, 0xa9, 0x06, 0x23, 0x48},
- {0xd1, 0xeb, 0x23, 0xa4, 0x6d, 0x17, 0xd6, 0x8f, 0xd9, 0x25,
- 0x64, 0xc2, 0xf1, 0xf1, 0x60, 0x17, 0x64, 0xd8, 0xe3, 0x49},
- {0xd2, 0x32, 0x09, 0xad, 0x23, 0xd3, 0x14, 0x23, 0x21, 0x74,
- 0xe4, 0x0d, 0x7f, 0x9d, 0x62, 0x13, 0x97, 0x86, 0x63, 0x3a},
- {0xd2, 0x44, 0x1a, 0xa8, 0xc2, 0x03, 0xae, 0xca, 0xa9, 0x6e,
- 0x50, 0x1f, 0x12, 0x4d, 0x52, 0xb6, 0x8f, 0xe4, 0xc3, 0x75},
- {0xd3, 0xc0, 0x63, 0xf2, 0x19, 0xed, 0x07, 0x3e, 0x34, 0xad,
- 0x5d, 0x75, 0x0b, 0x32, 0x76, 0x29, 0xff, 0xd5, 0x9a, 0xf2},
- {0xd3, 0xee, 0xfb, 0xcb, 0xbc, 0xf4, 0x98, 0x67, 0x83, 0x86,
- 0x26, 0xe2, 0x3b, 0xb5, 0x9c, 0xa0, 0x1e, 0x30, 0x5d, 0xb7},
- {0xd4, 0x37, 0x19, 0xb5, 0x1b, 0x57, 0xca, 0x4b, 0xb8, 0x74,
- 0x16, 0x7d, 0x47, 0x95, 0x23, 0x1d, 0x34, 0x34, 0xfd, 0xa8},
- {0xd4, 0xde, 0x20, 0xd0, 0x5e, 0x66, 0xfc, 0x53, 0xfe, 0x1a,
- 0x50, 0x88, 0x2c, 0x78, 0xdb, 0x28, 0x52, 0xca, 0xe4, 0x74},
- {0xd6, 0x9b, 0x56, 0x11, 0x48, 0xf0, 0x1c, 0x77, 0xc5, 0x45,
- 0x78, 0xc1, 0x09, 0x26, 0xdf, 0x5b, 0x85, 0x69, 0x76, 0xad},
- {0xd6, 0xda, 0xa8, 0x20, 0x8d, 0x09, 0xd2, 0x15, 0x4d, 0x24,
- 0xb5, 0x2f, 0xcb, 0x34, 0x6e, 0xb2, 0x58, 0xb2, 0x8a, 0x58},
- {0xd8, 0xa6, 0x33, 0x2c, 0xe0, 0x03, 0x6f, 0xb1, 0x85, 0xf6,
- 0x63, 0x4f, 0x7d, 0x6a, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27},
- {0xd8, 0xc5, 0x38, 0x8a, 0xb7, 0x30, 0x1b, 0x1b, 0x6e, 0xd4,
- 0x7a, 0xe6, 0x45, 0x25, 0x3a, 0x6f, 0x9f, 0x1a, 0x27, 0x61},
- {0xda, 0x40, 0x18, 0x8b, 0x91, 0x89, 0xa3, 0xed, 0xee, 0xae,
- 0xda, 0x97, 0xfe, 0x2f, 0x9d, 0xf5, 0xb7, 0xd1, 0x8a, 0x41},
- {0xda, 0xc9, 0x02, 0x4f, 0x54, 0xd8, 0xf6, 0xdf, 0x94, 0x93,
- 0x5f, 0xb1, 0x73, 0x26, 0x38, 0xca, 0x6a, 0xd7, 0x7c, 0x13},
- {0xda, 0xfa, 0xf7, 0xfa, 0x66, 0x84, 0xec, 0x06, 0x8f, 0x14,
- 0x50, 0xbd, 0xc7, 0xc2, 0x81, 0xa5, 0xbc, 0xa9, 0x64, 0x57},
- {0xdd, 0xfb, 0x16, 0xcd, 0x49, 0x31, 0xc9, 0x73, 0xa2, 0x03,
- 0x7d, 0x3f, 0xc8, 0x3a, 0x4d, 0x7d, 0x77, 0x5d, 0x05, 0xe4},
- {0xde, 0x28, 0xf4, 0xa4, 0xff, 0xe5, 0xb9, 0x2f, 0xa3, 0xc5,
- 0x03, 0xd1, 0xa3, 0x49, 0xa7, 0xf9, 0x96, 0x2a, 0x82, 0x12},
- {0xde, 0x3f, 0x40, 0xbd, 0x50, 0x93, 0xd3, 0x9b, 0x6c, 0x60,
- 0xf6, 0xda, 0xbc, 0x07, 0x62, 0x01, 0x00, 0x89, 0x76, 0xc9},
- {0xde, 0x99, 0x0c, 0xed, 0x99, 0xe0, 0x43, 0x1f, 0x60, 0xed,
- 0xc3, 0x93, 0x7e, 0x7c, 0xd5, 0xbf, 0x0e, 0xd9, 0xe5, 0xfa},
- {0xdf, 0x3c, 0x24, 0xf9, 0xbf, 0xd6, 0x66, 0x76, 0x1b, 0x26,
- 0x80, 0x73, 0xfe, 0x06, 0xd1, 0xcc, 0x8d, 0x4f, 0x82, 0xa4},
- {0xdf, 0x71, 0x7e, 0xaa, 0x4a, 0xd9, 0x4e, 0xc9, 0x55, 0x84,
- 0x99, 0x60, 0x2d, 0x48, 0xde, 0x5f, 0xbc, 0xf0, 0x3a, 0x25},
- {0xdf, 0xdf, 0xac, 0x89, 0x47, 0xbd, 0xf7, 0x52, 0x64, 0xa9,
- 0x23, 0x3a, 0xc1, 0x0e, 0xe3, 0xd1, 0x28, 0x33, 0xda, 0xcc},
- {0xe0, 0x5f, 0x7c, 0x22, 0x59, 0x8c, 0x12, 0x56, 0xa7, 0xb9,
- 0x4d, 0x92, 0xd3, 0xd1, 0x94, 0x50, 0x8c, 0x8c, 0xba, 0x71},
- {0xe0, 0xab, 0x05, 0x94, 0x20, 0x72, 0x54, 0x93, 0x05, 0x60,
- 0x62, 0x02, 0x36, 0x70, 0xf7, 0xcd, 0x2e, 0xfc, 0x66, 0x66},
- {0xe1, 0x2d, 0xfb, 0x4b, 0x41, 0xd7, 0xd9, 0xc3, 0x2b, 0x30,
- 0x51, 0x4b, 0xac, 0x1d, 0x81, 0xd8, 0x38, 0x5e, 0x2d, 0x46},
- {0xe1, 0x9f, 0xe3, 0x0e, 0x8b, 0x84, 0x60, 0x9e, 0x80, 0x9b,
- 0x17, 0x0d, 0x72, 0xa8, 0xc5, 0xba, 0x6e, 0x14, 0x09, 0xbd},
- {0xe1, 0xa4, 0x5b, 0x14, 0x1a, 0x21, 0xda, 0x1a, 0x79, 0xf4,
- 0x1a, 0x42, 0xa9, 0x61, 0xd6, 0x69, 0xcd, 0x06, 0x34, 0xc1},
- {0xe3, 0x92, 0x51, 0x2f, 0x0a, 0xcf, 0xf5, 0x05, 0xdf, 0xf6,
- 0xde, 0x06, 0x7f, 0x75, 0x37, 0xe1, 0x65, 0xea, 0x57, 0x4b},
- {0xe5, 0xdf, 0x74, 0x3c, 0xb6, 0x01, 0xc4, 0x9b, 0x98, 0x43,
- 0xdc, 0xab, 0x8c, 0xe8, 0x6a, 0x81, 0x10, 0x9f, 0xe4, 0x8e},
- {0xe6, 0x18, 0x83, 0xae, 0x84, 0xca, 0xc1, 0xc1, 0xcd, 0x52,
- 0xad, 0xe8, 0xe9, 0x25, 0x2b, 0x45, 0xa6, 0x4f, 0xb7, 0xe2},
- {0xe6, 0x19, 0xd2, 0x5b, 0x38, 0x0b, 0x7b, 0x13, 0xfd, 0xa3,
- 0x3e, 0x8a, 0x58, 0xcd, 0x82, 0xd8, 0xa8, 0x8e, 0x05, 0x15},
- {0xe7, 0xa1, 0x90, 0x29, 0xd3, 0xd5, 0x52, 0xdc, 0x0d, 0x0f,
- 0xc6, 0x92, 0xd3, 0xea, 0x88, 0x0d, 0x15, 0x2e, 0x1a, 0x6b},
- {0xe7, 0xb4, 0xf6, 0x9d, 0x61, 0xec, 0x90, 0x69, 0xdb, 0x7e,
- 0x90, 0xa7, 0x40, 0x1a, 0x3c, 0xf4, 0x7d, 0x4f, 0xe8, 0xee},
- {0xee, 0xef, 0xaa, 0x0b, 0xcd, 0x11, 0xaf, 0x5c, 0x02, 0xfa,
- 0x96, 0x20, 0x6a, 0xc5, 0xc6, 0x2b, 0xa7, 0x24, 0xd6, 0x0a},
- {0xf0, 0x0f, 0xc3, 0x7d, 0x6a, 0x1c, 0x92, 0x61, 0xfb, 0x6b,
- 0xc1, 0xc2, 0x18, 0x49, 0x8c, 0x5a, 0xa4, 0xdc, 0x51, 0xfb},
- {0xf1, 0x7f, 0x6f, 0xb6, 0x31, 0xdc, 0x99, 0xe3, 0xa3, 0xc8,
- 0x7f, 0xfe, 0x1c, 0xf1, 0x81, 0x10, 0x88, 0xd9, 0x60, 0x33},
- {0xf1, 0x8b, 0x53, 0x8d, 0x1b, 0xe9, 0x03, 0xb6, 0xa6, 0xf0,
- 0x56, 0x43, 0x5b, 0x17, 0x15, 0x89, 0xca, 0xf3, 0x6b, 0xf2},
- {0xf3, 0x73, 0xb3, 0x87, 0x06, 0x5a, 0x28, 0x84, 0x8a, 0xf2,
- 0xf3, 0x4a, 0xce, 0x19, 0x2b, 0xdd, 0xc7, 0x8e, 0x9c, 0xac},
- {0xf5, 0x17, 0xa2, 0x4f, 0x9a, 0x48, 0xc6, 0xc9, 0xf8, 0xa2,
- 0x00, 0x26, 0x9f, 0xdc, 0x0f, 0x48, 0x2c, 0xab, 0x30, 0x89},
- {0xf7, 0x4d, 0xac, 0xb2, 0x14, 0x14, 0xdc, 0xba, 0xab, 0x0b,
- 0x94, 0x7c, 0x8a, 0x25, 0x7c, 0x32, 0x5c, 0xa8, 0x85, 0x50},
- {0xf8, 0xa5, 0x4e, 0x03, 0xaa, 0xdc, 0x56, 0x92, 0xb8, 0x50,
- 0x49, 0x6a, 0x4c, 0x46, 0x30, 0xff, 0xea, 0xa2, 0x9d, 0x83},
- {0xf9, 0xb5, 0xb6, 0x32, 0x45, 0x5f, 0x9c, 0xbe, 0xec, 0x57,
- 0x5f, 0x80, 0xdc, 0xe9, 0x6e, 0x2c, 0xc7, 0xb2, 0x78, 0xb7},
- {0xf9, 0xcd, 0x0e, 0x2c, 0xda, 0x76, 0x24, 0xc1, 0x8f, 0xbd,
- 0xf0, 0xf0, 0xab, 0xb6, 0x45, 0xb8, 0xf7, 0xfe, 0xd5, 0x7a},
- {0xfa, 0xa7, 0xd9, 0xfb, 0x31, 0xb7, 0x46, 0xf2, 0x00, 0xa8,
- 0x5e, 0x65, 0x79, 0x76, 0x13, 0xd8, 0x16, 0xe0, 0x63, 0xb5},
- {0xfa, 0xb7, 0xee, 0x36, 0x97, 0x26, 0x62, 0xfb, 0x2d, 0xb0,
- 0x2a, 0xf6, 0xbf, 0x03, 0xfd, 0xe8, 0x7c, 0x4b, 0x2f, 0x9b},
- {0xfc, 0x21, 0x9a, 0x76, 0x11, 0x2f, 0x76, 0xc1, 0xc5, 0x08,
- 0x83, 0x3c, 0x9a, 0x2f, 0xa2, 0xba, 0x84, 0xac, 0x08, 0x7a},
- {0xfe, 0x45, 0x65, 0x9b, 0x79, 0x03, 0x5b, 0x98, 0xa1, 0x61,
- 0xb5, 0x51, 0x2e, 0xac, 0xda, 0x58, 0x09, 0x48, 0x22, 0x4d},
- {0xfe, 0xb8, 0xc4, 0x32, 0xdc, 0xf9, 0x76, 0x9a, 0xce, 0xae,
- 0x3d, 0xd8, 0x90, 0x8f, 0xfd, 0x28, 0x86, 0x65, 0x64, 0x7d},
- {0xff, 0xad, 0x0e, 0x26, 0xf0, 0x5b, 0xbc, 0xd8, 0x06, 0x3c,
- 0xce, 0x1d, 0xfa, 0x60, 0x24, 0x5e, 0x14, 0x3d, 0x53, 0x80},
-};
-
-#endif // NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_
diff --git a/chromium/net/cert/x509_certificate_known_roots_win.h b/chromium/net/cert/x509_certificate_known_roots_win.h
index ce7dce86e86..f914ec865d7 100644
--- a/chromium/net/cert/x509_certificate_known_roots_win.h
+++ b/chromium/net/cert/x509_certificate_known_roots_win.h
@@ -5,8 +5,10 @@
#ifndef NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_
#define NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_
-// This is a union of Microsoft trust roots over time, from 29 April
-// 2013 through 15 May 2015.
+#include <stdint.h>
+
+// This is a union of Microsoft trust roots over time, from 01 January
+// 2007 through 24 November 2015.
//
// Extracted from
// http://www.download.windowsupdate.com/msdownload/update/v3/
@@ -14,829 +16,1878 @@
//
// Note that these *are not* trust anchors for Chromium. They are only used to
// distinguish `real' root CAs from roots that were user-installed.
-static uint8_t kKnownRootCertSHA1Hashes[][20] = {
- {0x00, 0x48, 0xf8, 0xd3, 0x7b, 0x15, 0x3f, 0x6e, 0xa2, 0x79,
- 0x8c, 0x32, 0x3e, 0xf4, 0xf3, 0x18, 0xa5, 0x62, 0x4a, 0x9e},
- {0x00, 0xea, 0x52, 0x2c, 0x8a, 0x9c, 0x06, 0xaa, 0x3e, 0xcc,
- 0xe0, 0xb4, 0xfa, 0x6c, 0xdc, 0x21, 0xd9, 0x2e, 0x80, 0x99},
- {0x01, 0x68, 0x97, 0xe1, 0xa0, 0xb8, 0xf2, 0xc3, 0xb1, 0x34,
- 0x66, 0x5c, 0x20, 0xa7, 0x27, 0xb7, 0xa1, 0x58, 0xe2, 0x8f},
- {0x02, 0x72, 0x68, 0x29, 0x3e, 0x5f, 0x5d, 0x17, 0xaa, 0xa4,
- 0xb3, 0xc3, 0xe6, 0x36, 0x1e, 0x1f, 0x92, 0x57, 0x5e, 0xaa},
- {0x02, 0xfa, 0xf3, 0xe2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78,
- 0x57, 0x69, 0x4d, 0xf5, 0xe4, 0x5b, 0x68, 0x85, 0x18, 0x68},
- {0x03, 0x9e, 0xed, 0xb8, 0x0b, 0xe7, 0xa0, 0x3c, 0x69, 0x53,
- 0x89, 0x3b, 0x20, 0xd2, 0xd9, 0x32, 0x3a, 0x4c, 0x2a, 0xfd},
- {0x04, 0x09, 0x56, 0x5b, 0x77, 0xda, 0x58, 0x2e, 0x64, 0x95,
- 0xac, 0x00, 0x60, 0xa7, 0x23, 0x54, 0xe6, 0x4b, 0x01, 0x92},
- {0x04, 0x46, 0xc8, 0xbb, 0x9a, 0x69, 0x83, 0xc9, 0x5c, 0x8a,
- 0x2e, 0x54, 0x64, 0x68, 0x7c, 0x11, 0x15, 0xaa, 0xb7, 0x4a},
- {0x04, 0x56, 0xf2, 0x3d, 0x1e, 0x9c, 0x43, 0xae, 0xcb, 0x0d,
- 0x80, 0x7f, 0x1c, 0x06, 0x47, 0x55, 0x1a, 0x05, 0xf4, 0x56},
- {0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87,
- 0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7},
- {0x04, 0x98, 0x11, 0x05, 0x6a, 0xfe, 0x9f, 0xd0, 0xf5, 0xbe,
- 0x01, 0x68, 0x5a, 0xac, 0xe6, 0xa5, 0xd1, 0xc4, 0x45, 0x4c},
- {0x05, 0x60, 0xa2, 0xc7, 0x38, 0xff, 0x98, 0xd1, 0x17, 0x2a,
- 0x94, 0xfe, 0x45, 0xfb, 0x8a, 0x47, 0xd6, 0x65, 0x37, 0x1e},
- {0x05, 0x63, 0xb8, 0x63, 0x0d, 0x62, 0xd7, 0x5a, 0xbb, 0xc8,
- 0xab, 0x1e, 0x4b, 0xdf, 0xb5, 0xa8, 0x99, 0xb2, 0x4d, 0x43},
- {0x06, 0x08, 0x3f, 0x59, 0x3f, 0x15, 0xa1, 0x04, 0xa0, 0x69,
- 0xa4, 0x6b, 0xa9, 0x03, 0xd0, 0x06, 0xb7, 0x97, 0x09, 0x91},
- {0x06, 0x14, 0x31, 0x51, 0xe0, 0x2b, 0x45, 0xdd, 0xba, 0xdd,
- 0x5d, 0x8e, 0x56, 0x53, 0x0d, 0xaa, 0xe3, 0x28, 0xcf, 0x90},
- {0x07, 0x47, 0x22, 0x01, 0x99, 0xce, 0x74, 0xb9, 0x7c, 0xb0,
- 0x3d, 0x79, 0xb2, 0x64, 0xa2, 0xc8, 0x55, 0xe9, 0x33, 0xff},
- {0x07, 0xe0, 0x32, 0xe0, 0x20, 0xb7, 0x2c, 0x3f, 0x19, 0x2f,
- 0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e},
- {0x08, 0x64, 0x18, 0xe9, 0x06, 0xce, 0xe8, 0x9c, 0x23, 0x53,
- 0xb6, 0xe2, 0x7f, 0xbd, 0x9e, 0x74, 0x39, 0xf7, 0x63, 0x16},
- {0x09, 0x3c, 0x61, 0xf3, 0x8b, 0x8b, 0xdc, 0x7d, 0x55, 0xdf,
- 0x75, 0x38, 0x02, 0x05, 0x00, 0xe1, 0x25, 0xf5, 0xc8, 0x36},
- {0x0b, 0x71, 0x99, 0xa1, 0xc7, 0xf3, 0xad, 0xdf, 0x7b, 0xa7,
- 0xea, 0xb8, 0xeb, 0x57, 0x4a, 0xe8, 0x0d, 0x60, 0xdd, 0xde},
- {0x0b, 0x77, 0xbe, 0xbb, 0xcb, 0x7a, 0xa2, 0x47, 0x05, 0xde,
- 0xcc, 0x0f, 0xbd, 0x6a, 0x02, 0xfc, 0x7a, 0xbd, 0x9b, 0x52},
- {0x0b, 0x97, 0x2c, 0x9e, 0xa6, 0xe7, 0xcc, 0x58, 0xd9, 0x3b,
- 0x20, 0xbf, 0x71, 0xec, 0x41, 0x2e, 0x72, 0x09, 0xfa, 0xbf},
- {0x0c, 0x62, 0x8f, 0x5c, 0x55, 0x70, 0xb1, 0xc9, 0x57, 0xfa,
- 0xfd, 0x38, 0x3f, 0xb0, 0x3d, 0x7b, 0x7d, 0xd7, 0xb9, 0xc6},
- {0x0c, 0xfd, 0x83, 0xdb, 0xae, 0x44, 0xb9, 0xa0, 0xc8, 0xf6,
- 0x76, 0xf3, 0xb5, 0x70, 0x65, 0x0b, 0x94, 0xb6, 0x9d, 0xbf},
- {0x10, 0x1d, 0xfa, 0x3f, 0xd5, 0x0b, 0xcb, 0xbb, 0x9b, 0xb5,
- 0x60, 0x0c, 0x19, 0x55, 0xa4, 0x1a, 0xf4, 0x73, 0x3a, 0x04},
- {0x11, 0xc5, 0xb5, 0xf7, 0x55, 0x52, 0xb0, 0x11, 0x66, 0x9c,
- 0x2e, 0x97, 0x17, 0xde, 0x6d, 0x9b, 0xff, 0x5f, 0xa8, 0x10},
- {0x11, 0xe1, 0x9b, 0xbc, 0x74, 0x7b, 0x1a, 0xed, 0x0d, 0xb8,
- 0x33, 0xc9, 0x4c, 0xac, 0x6c, 0x3f, 0x85, 0xbd, 0xeb, 0xdb},
- {0x13, 0x2d, 0x0d, 0x45, 0x53, 0x4b, 0x69, 0x97, 0xcd, 0xb2,
- 0xd5, 0xc3, 0x39, 0xe2, 0x55, 0x76, 0x60, 0x9b, 0x5c, 0xc6},
- {0x15, 0x03, 0x32, 0xa5, 0x8d, 0xc5, 0x91, 0xfc, 0x42, 0xd4,
- 0xc8, 0x73, 0xff, 0x9f, 0x1f, 0x0f, 0x81, 0xd5, 0x97, 0xc9},
- {0x16, 0x32, 0x47, 0x8d, 0x89, 0xf9, 0x21, 0x3a, 0x92, 0x00,
- 0x85, 0x63, 0xf5, 0xa4, 0xa7, 0xd3, 0x12, 0x40, 0x8a, 0xd6},
- {0x16, 0xd8, 0x66, 0x35, 0xaf, 0x13, 0x41, 0xcd, 0x34, 0x79,
- 0x94, 0x45, 0xeb, 0x60, 0x3e, 0x27, 0x37, 0x02, 0x96, 0x5d},
- {0x18, 0xf7, 0xc1, 0xfc, 0xc3, 0x09, 0x02, 0x03, 0xfd, 0x5b,
- 0xaa, 0x2f, 0x86, 0x1a, 0x75, 0x49, 0x76, 0xc8, 0xdd, 0x25},
- {0x1a, 0xc9, 0x2f, 0x09, 0xea, 0x89, 0xe2, 0x8b, 0x12, 0x6d,
- 0xfa, 0xc5, 0x1e, 0x3a, 0xf7, 0xea, 0x90, 0x95, 0xa3, 0xee},
- {0x1b, 0x4b, 0x39, 0x61, 0x26, 0x27, 0x6b, 0x64, 0x91, 0xa2,
- 0x68, 0x6d, 0xd7, 0x02, 0x43, 0x21, 0x2d, 0x1f, 0x1d, 0x96},
- {0x1b, 0x8e, 0xea, 0x57, 0x96, 0x29, 0x1a, 0xc9, 0x39, 0xea,
- 0xb8, 0x0a, 0x81, 0x1a, 0x73, 0x73, 0xc0, 0x93, 0x79, 0x67},
- {0x1f, 0x24, 0xc6, 0x30, 0xcd, 0xa4, 0x18, 0xef, 0x20, 0x69,
- 0xff, 0xad, 0x4f, 0xdd, 0x5f, 0x46, 0x3a, 0x1b, 0x69, 0xaa},
- {0x1f, 0x49, 0x14, 0xf7, 0xd8, 0x74, 0x95, 0x1d, 0xdd, 0xae,
- 0x02, 0xc0, 0xbe, 0xfd, 0x3a, 0x2d, 0x82, 0x75, 0x51, 0x85},
- {0x20, 0x42, 0x85, 0xdc, 0xf7, 0xeb, 0x76, 0x41, 0x95, 0x57,
- 0x8e, 0x13, 0x6b, 0xd4, 0xb7, 0xd1, 0xe9, 0x8e, 0x46, 0xa5},
- {0x20, 0x99, 0x00, 0xb6, 0x3d, 0x95, 0x57, 0x28, 0x14, 0x0c,
- 0xd1, 0x36, 0x22, 0xd8, 0xc6, 0x87, 0xa4, 0xeb, 0x00, 0x85},
- {0x20, 0xcb, 0x59, 0x4f, 0xb4, 0xed, 0xd8, 0x95, 0x76, 0x3f,
- 0xd5, 0x25, 0x4e, 0x95, 0x9a, 0x66, 0x74, 0xc6, 0xee, 0xb2},
- {0x20, 0xd8, 0x06, 0x40, 0xdf, 0x9b, 0x25, 0xf5, 0x12, 0x25,
- 0x3a, 0x11, 0xea, 0xf7, 0x59, 0x8a, 0xeb, 0x14, 0xb5, 0x47},
- {0x21, 0x11, 0x65, 0xca, 0x37, 0x9f, 0xbb, 0x5e, 0xd8, 0x01,
- 0xe3, 0x1c, 0x43, 0x0a, 0x62, 0xaa, 0xc1, 0x09, 0xbc, 0xb4},
- {0x21, 0x6b, 0x2a, 0x29, 0xe6, 0x2a, 0x00, 0xce, 0x82, 0x01,
- 0x46, 0xd8, 0x24, 0x41, 0x41, 0xb9, 0x25, 0x11, 0xb2, 0x79},
- {0x21, 0xfc, 0xbd, 0x8e, 0x7f, 0x6c, 0xaf, 0x05, 0x1b, 0xd1,
- 0xb3, 0x43, 0xec, 0xa8, 0xe7, 0x61, 0x47, 0xf2, 0x0f, 0x8a},
- {0x22, 0xd5, 0xd8, 0xdf, 0x8f, 0x02, 0x31, 0xd1, 0x8d, 0xf7,
- 0x9d, 0xb7, 0xcf, 0x8a, 0x2d, 0x64, 0xc9, 0x3f, 0x6c, 0x3a},
- {0x23, 0x88, 0xc9, 0xd3, 0x71, 0xcc, 0x9e, 0x96, 0x3d, 0xff,
- 0x7d, 0x3c, 0xa7, 0xce, 0xfc, 0xd6, 0x25, 0xec, 0x19, 0x0d},
- {0x23, 0xe5, 0x94, 0x94, 0x51, 0x95, 0xf2, 0x41, 0x48, 0x03,
- 0xb4, 0xd5, 0x64, 0xd2, 0xa3, 0xa3, 0xf5, 0xd8, 0x8b, 0x8c},
- {0x23, 0xe8, 0x33, 0x23, 0x3e, 0x7d, 0x0c, 0xc9, 0x2b, 0x7c,
- 0x42, 0x79, 0xac, 0x19, 0xc2, 0xf4, 0x74, 0xd6, 0x04, 0xca},
- {0x24, 0x5c, 0x97, 0xdf, 0x75, 0x14, 0xe7, 0xcf, 0x2d, 0xf8,
- 0xbe, 0x72, 0xae, 0x95, 0x7b, 0x9e, 0x04, 0x74, 0x1e, 0x85},
- {0x24, 0xa4, 0x0a, 0x1f, 0x57, 0x36, 0x43, 0xa6, 0x7f, 0x0a,
- 0x4b, 0x07, 0x49, 0xf6, 0xa2, 0x2b, 0xf2, 0x8a, 0xbb, 0x6b},
- {0x24, 0xba, 0x6d, 0x6c, 0x8a, 0x5b, 0x58, 0x37, 0xa4, 0x8d,
- 0xb5, 0xfa, 0xe9, 0x19, 0xea, 0x67, 0x5c, 0x94, 0xd2, 0x17},
- {0x25, 0x01, 0x90, 0x19, 0xcf, 0xfb, 0xd9, 0x99, 0x1c, 0xb7,
- 0x68, 0x25, 0x74, 0x8d, 0x94, 0x5f, 0x30, 0x93, 0x95, 0x42},
- {0x25, 0x3f, 0x77, 0x5b, 0x0e, 0x77, 0x97, 0xab, 0x64, 0x5f,
- 0x15, 0x91, 0x55, 0x97, 0xc3, 0x9e, 0x26, 0x36, 0x31, 0xd1},
- {0x26, 0xa1, 0x6c, 0x23, 0x5a, 0x24, 0x72, 0x22, 0x9b, 0x23,
- 0x62, 0x80, 0x25, 0xbc, 0x80, 0x97, 0xc8, 0x85, 0x24, 0xa1},
- {0x27, 0x3e, 0xe1, 0x24, 0x57, 0xfd, 0xc4, 0xf9, 0x0c, 0x55,
- 0xe8, 0x2b, 0x56, 0x16, 0x7f, 0x62, 0xf5, 0x32, 0xe5, 0x47},
- {0x27, 0x96, 0xba, 0xe6, 0x3f, 0x18, 0x01, 0xe2, 0x77, 0x26,
- 0x1b, 0xa0, 0xd7, 0x77, 0x70, 0x02, 0x8f, 0x20, 0xee, 0xe4},
- {0x28, 0x90, 0x3a, 0x63, 0x5b, 0x52, 0x80, 0xfa, 0xe6, 0x77,
- 0x4c, 0x0b, 0x6d, 0xa7, 0xd6, 0xba, 0xa6, 0x4a, 0xf2, 0xe8},
- {0x29, 0x36, 0x21, 0x02, 0x8b, 0x20, 0xed, 0x02, 0xf5, 0x66,
- 0xc5, 0x32, 0xd1, 0xd6, 0xed, 0x90, 0x9f, 0x45, 0x00, 0x2f},
- {0x29, 0x64, 0xb6, 0x86, 0x13, 0x5b, 0x5d, 0xfd, 0xdd, 0x32,
- 0x53, 0xa8, 0x9b, 0xbc, 0x24, 0xd7, 0x4b, 0x08, 0xc6, 0x4d},
- {0x2a, 0xc8, 0xd5, 0x8b, 0x57, 0xce, 0xbf, 0x2f, 0x49, 0xaf,
- 0xf2, 0xfc, 0x76, 0x8f, 0x51, 0x14, 0x62, 0x90, 0x7a, 0x41},
- {0x2b, 0x8f, 0x1b, 0x57, 0x33, 0x0d, 0xbb, 0xa2, 0xd0, 0x7a,
- 0x6c, 0x51, 0xf7, 0x0e, 0xe9, 0x0d, 0xda, 0xb9, 0xad, 0x8e},
- {0x2b, 0xb1, 0xf5, 0x3e, 0x55, 0x0c, 0x1d, 0xc5, 0xf1, 0xd4,
- 0xe6, 0xb7, 0x6a, 0x46, 0x4b, 0x55, 0x06, 0x02, 0xac, 0x21},
- {0x2e, 0x14, 0xda, 0xec, 0x28, 0xf0, 0xfa, 0x1e, 0x8e, 0x38,
- 0x9a, 0x4e, 0xab, 0xeb, 0x26, 0xc0, 0x0a, 0xd3, 0x83, 0xc3},
- {0x2e, 0x66, 0xc9, 0x84, 0x11, 0x81, 0xc0, 0x8f, 0xb1, 0xdf,
- 0xab, 0xd4, 0xff, 0x8d, 0x5c, 0xc7, 0x2b, 0xe0, 0x8f, 0x02},
- {0x30, 0x70, 0xf8, 0x83, 0x3e, 0x4a, 0xa6, 0x80, 0x3e, 0x09,
- 0xa6, 0x46, 0xae, 0x3f, 0x7d, 0x8a, 0xe1, 0xfd, 0x16, 0x54},
- {0x30, 0x77, 0x9e, 0x93, 0x15, 0x02, 0x2e, 0x94, 0x85, 0x6a,
- 0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd},
- {0x31, 0x7a, 0x2a, 0xd0, 0x7f, 0x2b, 0x33, 0x5e, 0xf5, 0xa1,
- 0xc3, 0x4e, 0x4b, 0x57, 0xe8, 0xb7, 0xd8, 0xf1, 0xfc, 0xa6},
- {0x31, 0xe2, 0xc5, 0x2c, 0xe1, 0x08, 0x9b, 0xef, 0xfd, 0xda,
- 0xdb, 0x26, 0xdd, 0x7c, 0x78, 0x2e, 0xbc, 0x40, 0x37, 0xbd},
- {0x31, 0xf1, 0xfd, 0x68, 0x22, 0x63, 0x20, 0xee, 0xc6, 0x3b,
- 0x3f, 0x9d, 0xea, 0x4a, 0x3e, 0x53, 0x7c, 0x7c, 0x39, 0x17},
- {0x32, 0x3c, 0x11, 0x8e, 0x1b, 0xf7, 0xb8, 0xb6, 0x52, 0x54,
- 0xe2, 0xe2, 0x10, 0x0d, 0xd6, 0x02, 0x90, 0x37, 0xf0, 0x96},
- {0x33, 0x5a, 0x7f, 0xf0, 0x09, 0x27, 0xcf, 0x2d, 0xf2, 0x78,
- 0xe2, 0xc9, 0x19, 0x2f, 0x7a, 0x4d, 0x55, 0x34, 0xf8, 0x0c},
- {0x33, 0x9b, 0x6b, 0x14, 0x50, 0x24, 0x9b, 0x55, 0x7a, 0x01,
- 0x87, 0x72, 0x84, 0xd9, 0xe0, 0x2f, 0xc3, 0xd2, 0xd8, 0xe9},
- {0x34, 0x2c, 0xd9, 0xd3, 0x06, 0x2d, 0xa4, 0x8c, 0x34, 0x69,
- 0x65, 0x29, 0x7f, 0x08, 0x1e, 0xbc, 0x2e, 0xf6, 0x8f, 0xdc},
- {0x34, 0xd4, 0x99, 0x42, 0x6f, 0x9f, 0xc2, 0xbb, 0x27, 0xb0,
- 0x75, 0xba, 0xb6, 0x82, 0xaa, 0xe5, 0xef, 0xfc, 0xba, 0x74},
- {0x36, 0x79, 0xca, 0x35, 0x66, 0x87, 0x72, 0x30, 0x4d, 0x30,
- 0xa5, 0xfb, 0x87, 0x3b, 0x0f, 0xa7, 0x7b, 0xb7, 0x0d, 0x54},
- {0x36, 0x86, 0x35, 0x63, 0xfd, 0x51, 0x28, 0xc7, 0xbe, 0xa6,
- 0xf0, 0x05, 0xcf, 0xe9, 0xb4, 0x36, 0x68, 0x08, 0x6c, 0xce},
- {0x36, 0xb1, 0x2b, 0x49, 0xf9, 0x81, 0x9e, 0xd7, 0x4c, 0x9e,
- 0xbc, 0x38, 0x0f, 0xc6, 0x56, 0x8f, 0x5d, 0xac, 0xb2, 0xf7},
- {0x37, 0x9a, 0x19, 0x7b, 0x41, 0x85, 0x45, 0x35, 0x0c, 0xa6,
- 0x03, 0x69, 0xf3, 0x3c, 0x2e, 0xaf, 0x47, 0x4f, 0x20, 0x79},
- {0x37, 0xf7, 0x6d, 0xe6, 0x07, 0x7c, 0x90, 0xc5, 0xb1, 0x3e,
- 0x93, 0x1a, 0xb7, 0x41, 0x10, 0xb4, 0xf2, 0xe4, 0x9a, 0x27},
- {0x38, 0xdd, 0x76, 0x59, 0xc7, 0x35, 0x10, 0x0b, 0x00, 0xa2,
- 0x37, 0xe4, 0x91, 0xb7, 0xbc, 0x0f, 0xfc, 0xd2, 0x31, 0x6c},
- {0x39, 0x13, 0x85, 0x3e, 0x45, 0xc4, 0x39, 0xa2, 0xda, 0x71,
- 0x8c, 0xdf, 0xb6, 0xf3, 0xe0, 0x33, 0xe0, 0x4f, 0xee, 0x71},
- {0x39, 0x21, 0xc1, 0x15, 0xc1, 0x5d, 0x0e, 0xca, 0x5c, 0xcb,
- 0x5b, 0xc4, 0xf0, 0x7d, 0x21, 0xd8, 0x05, 0x0b, 0x56, 0x6a},
- {0x39, 0x41, 0x0b, 0xc2, 0x30, 0x37, 0x48, 0x06, 0x60, 0x69,
- 0xa7, 0x2a, 0x66, 0x4d, 0xe4, 0xc7, 0x43, 0x48, 0x12, 0x96},
- {0x39, 0x4f, 0xf6, 0x85, 0x0b, 0x06, 0xbe, 0x52, 0xe5, 0x18,
- 0x56, 0xcc, 0x10, 0xe1, 0x80, 0xe8, 0x82, 0xb3, 0x85, 0xcc},
- {0x39, 0x8e, 0xbe, 0x9c, 0x0f, 0x46, 0xc0, 0x79, 0xc3, 0xc7,
- 0xaf, 0xe0, 0x7a, 0x2f, 0xdd, 0x9f, 0xae, 0x5f, 0x8a, 0x5c},
- {0x3a, 0x44, 0x73, 0x5a, 0xe5, 0x81, 0x90, 0x1f, 0x24, 0x86,
- 0x61, 0x46, 0x1e, 0x3b, 0x9c, 0xc4, 0x5f, 0xf5, 0x3a, 0x1b},
- {0x3b, 0x1e, 0xfd, 0x3a, 0x66, 0xea, 0x28, 0xb1, 0x66, 0x97,
- 0x39, 0x47, 0x03, 0xa7, 0x2c, 0xa3, 0x40, 0xa0, 0x5b, 0xd5},
- {0x3b, 0xc0, 0x38, 0x0b, 0x33, 0xc3, 0xf6, 0xa6, 0x0c, 0x86,
- 0x15, 0x22, 0x93, 0xd9, 0xdf, 0xf5, 0x4b, 0x81, 0xc0, 0x04},
- {0x3b, 0xc4, 0x9f, 0x48, 0xf8, 0xf3, 0x73, 0xa0, 0x9c, 0x1e,
- 0xbd, 0xf8, 0x5b, 0xb1, 0xc3, 0x65, 0xc7, 0xd8, 0x11, 0xb3},
- {0x3c, 0x71, 0xd7, 0x0e, 0x35, 0xa5, 0xda, 0xa8, 0xb2, 0xe3,
- 0x81, 0x2d, 0xc3, 0x67, 0x74, 0x17, 0xf5, 0x99, 0x0d, 0xf3},
- {0x3e, 0x2b, 0xf7, 0xf2, 0x03, 0x1b, 0x96, 0xf3, 0x8c, 0xe6,
- 0xc4, 0xd8, 0xa8, 0x5d, 0x3e, 0x2d, 0x58, 0x47, 0x6a, 0x0f},
- {0x3e, 0x42, 0xa1, 0x87, 0x06, 0xbd, 0x0c, 0x9c, 0xcf, 0x59,
- 0x47, 0x50, 0xd2, 0xe4, 0xd6, 0xab, 0x00, 0x48, 0xfd, 0xc4},
- {0x3e, 0x5d, 0x35, 0x8f, 0x28, 0x3a, 0x0f, 0x64, 0x7c, 0x1c,
- 0x92, 0x7f, 0xfb, 0xaa, 0xd4, 0x85, 0x2d, 0x99, 0x72, 0x56},
- {0x3e, 0x84, 0xd3, 0xbc, 0xc5, 0x44, 0xc0, 0xf6, 0xfa, 0x19,
- 0x43, 0x5c, 0x85, 0x1f, 0x3f, 0x2f, 0xcb, 0xa8, 0xe8, 0x14},
- {0x3e, 0xe2, 0x2a, 0xdc, 0x26, 0x7d, 0xde, 0x0e, 0xb0, 0x23,
- 0x17, 0x45, 0xf6, 0xcf, 0x9d, 0x6e, 0xab, 0xd3, 0x3c, 0x19},
- {0x3f, 0x85, 0xf2, 0xbb, 0x4a, 0x62, 0xb0, 0xb5, 0x8b, 0xe1,
- 0x61, 0x4a, 0xbb, 0x0d, 0x46, 0x31, 0xb4, 0xbe, 0xf8, 0xba},
- {0x40, 0x54, 0xda, 0x6f, 0x1c, 0x3f, 0x40, 0x74, 0xac, 0xed,
- 0x0f, 0xec, 0xcd, 0xdb, 0x79, 0xd1, 0x53, 0xfb, 0x90, 0x1d},
- {0x40, 0x9d, 0x4b, 0xd9, 0x17, 0xb5, 0x5c, 0x27, 0xb6, 0x9b,
- 0x64, 0xcb, 0x98, 0x22, 0x44, 0x0d, 0xcd, 0x09, 0xb8, 0x89},
- {0x40, 0xe7, 0x8c, 0x1d, 0x52, 0x3d, 0x1c, 0xd9, 0x95, 0x4f,
- 0xac, 0x1a, 0x1a, 0xb3, 0xbd, 0x3c, 0xba, 0xa1, 0x5b, 0xfc},
- {0x42, 0xef, 0xdd, 0xe6, 0xbf, 0xf3, 0x5e, 0xd0, 0xba, 0xe6,
- 0xac, 0xdd, 0x20, 0x4c, 0x50, 0xae, 0x86, 0xc4, 0xf4, 0xfa},
- {0x43, 0x13, 0xbb, 0x96, 0xf1, 0xd5, 0x86, 0x9b, 0xc1, 0x4e,
- 0x6a, 0x92, 0xf6, 0xcf, 0xf6, 0x34, 0x69, 0x87, 0x82, 0x37},
- {0x43, 0x94, 0xce, 0x31, 0x26, 0xff, 0x1a, 0x22, 0x4c, 0xdd,
- 0x4d, 0xee, 0xb4, 0xf4, 0xec, 0x1d, 0xa3, 0x68, 0xef, 0x6a},
- {0x43, 0xf9, 0xb1, 0x10, 0xd5, 0xba, 0xfd, 0x48, 0x22, 0x52,
- 0x31, 0xb0, 0xd0, 0x08, 0x2b, 0x37, 0x2f, 0xef, 0x9a, 0x54},
- {0x44, 0x63, 0xc5, 0x31, 0xd7, 0xcc, 0xc1, 0x00, 0x67, 0x94,
- 0x61, 0x2b, 0xb6, 0x56, 0xd3, 0xbf, 0x82, 0x57, 0x84, 0x6f},
- {0x47, 0xbe, 0xab, 0xc9, 0x22, 0xea, 0xe8, 0x0e, 0x78, 0x78,
- 0x34, 0x62, 0xa7, 0x9f, 0x45, 0xc2, 0x54, 0xfd, 0xe6, 0x8b},
- {0x48, 0x12, 0xbd, 0x92, 0x3c, 0xa8, 0xc4, 0x39, 0x06, 0xe7,
- 0x30, 0x6d, 0x27, 0x96, 0xe6, 0xa4, 0xcf, 0x22, 0x2e, 0x7d},
- {0x49, 0x0a, 0x75, 0x74, 0xde, 0x87, 0x0a, 0x47, 0xfe, 0x58,
- 0xee, 0xf6, 0xc7, 0x6b, 0xeb, 0xc6, 0x0b, 0x12, 0x40, 0x99},
- {0x4a, 0x05, 0x8f, 0xdf, 0xd7, 0x61, 0xdb, 0x21, 0xb0, 0xc2,
- 0xee, 0x48, 0x57, 0x9b, 0xe2, 0x7f, 0x42, 0xa4, 0xda, 0x1c},
- {0x4a, 0x3f, 0x8d, 0x6b, 0xdc, 0x0e, 0x1e, 0xcf, 0xcd, 0x72,
- 0xe3, 0x77, 0xde, 0xf2, 0xd7, 0xff, 0x92, 0xc1, 0x9b, 0xc7},
- {0x4a, 0xbd, 0xee, 0xec, 0x95, 0x0d, 0x35, 0x9c, 0x89, 0xae,
- 0xc7, 0x52, 0xa1, 0x2c, 0x5b, 0x29, 0xf6, 0xd6, 0xaa, 0x0c},
- {0x4b, 0x6b, 0xd2, 0xd3, 0x88, 0x4e, 0x46, 0xc8, 0x0c, 0xe2,
- 0xb9, 0x62, 0xbc, 0x59, 0x8c, 0xd9, 0xd5, 0xd8, 0x40, 0x13},
- {0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58,
- 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5},
- {0x4e, 0xfc, 0xed, 0x9c, 0x6b, 0xdd, 0x0c, 0x98, 0x5c, 0xa3,
- 0xc7, 0xd2, 0x53, 0x06, 0x3c, 0x5b, 0xe6, 0xfc, 0x62, 0x0c},
- {0x4f, 0x55, 0x5c, 0xe2, 0x0d, 0xcd, 0x33, 0x64, 0xe0, 0xdc,
- 0x7c, 0x41, 0xef, 0xdd, 0x40, 0xf5, 0x03, 0x56, 0xc1, 0x22},
- {0x4f, 0x65, 0x56, 0x63, 0x36, 0xdb, 0x65, 0x98, 0x58, 0x1d,
- 0x58, 0x4a, 0x59, 0x6c, 0x87, 0x93, 0x4d, 0x5f, 0x2a, 0xb4},
- {0x4f, 0x99, 0xaa, 0x93, 0xfb, 0x2b, 0xd1, 0x37, 0x26, 0xa1,
- 0x99, 0x4a, 0xce, 0x7f, 0xf0, 0x05, 0xf2, 0x93, 0x5d, 0x1e},
- {0x50, 0x30, 0x06, 0x09, 0x1d, 0x97, 0xd4, 0xf5, 0xae, 0x39,
- 0xf7, 0xcb, 0xe7, 0x92, 0x7d, 0x7d, 0x65, 0x2d, 0x34, 0x31},
- {0x51, 0xa4, 0x4c, 0x28, 0xf3, 0x13, 0xe3, 0xf9, 0xcb, 0x5e,
- 0x7c, 0x0a, 0x1e, 0x0e, 0x0d, 0xd2, 0x84, 0x37, 0x58, 0xae},
- {0x51, 0xc6, 0xe7, 0x08, 0x49, 0x06, 0x6e, 0xf3, 0x92, 0xd4,
- 0x5c, 0xa0, 0x0d, 0x6d, 0xa3, 0x62, 0x8f, 0xc3, 0x52, 0x39},
- {0x52, 0x41, 0x2b, 0xd6, 0x7b, 0x5a, 0x6c, 0x69, 0x52, 0x82,
- 0x38, 0x60, 0x26, 0xf0, 0xb0, 0x53, 0xdd, 0x40, 0x0e, 0xfc},
- {0x53, 0x5b, 0x00, 0x16, 0x72, 0xab, 0xbf, 0x7b, 0x6c, 0xc2,
- 0x54, 0x05, 0xae, 0x4d, 0x24, 0xfe, 0x03, 0x3f, 0xd1, 0xcc},
- {0x54, 0xf9, 0xc1, 0x63, 0x75, 0x9f, 0x19, 0x04, 0x51, 0x21,
- 0xa3, 0x19, 0xf6, 0x4c, 0x2d, 0x05, 0x55, 0xb7, 0xe0, 0x73},
- {0x55, 0xa6, 0x72, 0x3e, 0xcb, 0xf2, 0xec, 0xcd, 0xc3, 0x23,
- 0x74, 0x70, 0x19, 0x9d, 0x2a, 0xbe, 0x11, 0xe3, 0x81, 0xd1},
- {0x55, 0xc8, 0x6f, 0x74, 0x14, 0xac, 0x8b, 0xdd, 0x68, 0x14,
- 0xf4, 0xd8, 0x6a, 0xf1, 0x5f, 0x37, 0x10, 0xe1, 0x04, 0xd0},
- {0x56, 0xe0, 0xfa, 0xc0, 0x3b, 0x8f, 0x18, 0x23, 0x55, 0x18,
- 0xe5, 0xd3, 0x11, 0xca, 0xe8, 0xc2, 0x43, 0x31, 0xab, 0x66},
- {0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd,
- 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4},
- {0x58, 0x5f, 0x78, 0x75, 0xbe, 0xe7, 0x43, 0x3e, 0xb0, 0x79,
- 0xea, 0xab, 0x7d, 0x05, 0xbb, 0x0f, 0x7a, 0xf2, 0xbc, 0xcc},
- {0x58, 0xd5, 0x2d, 0xb9, 0x33, 0x01, 0xa4, 0xfd, 0x29, 0x1a,
- 0x8c, 0x96, 0x45, 0xa0, 0x8f, 0xee, 0x7f, 0x52, 0x92, 0x82},
- {0x58, 0xe8, 0xab, 0xb0, 0x36, 0x15, 0x33, 0xfb, 0x80, 0xf7,
- 0x9b, 0x1b, 0x6d, 0x29, 0xd3, 0xff, 0x8d, 0x5f, 0x00, 0xf0},
- {0x59, 0x0d, 0x2d, 0x7d, 0x88, 0x4f, 0x40, 0x2e, 0x61, 0x7e,
- 0xa5, 0x62, 0x32, 0x17, 0x65, 0xcf, 0x17, 0xd8, 0x94, 0xe9},
- {0x59, 0x22, 0xa1, 0xe1, 0x5a, 0xea, 0x16, 0x35, 0x21, 0xf8,
- 0x98, 0x39, 0x6a, 0x46, 0x46, 0xb0, 0x44, 0x1b, 0x0f, 0xa9},
- {0x59, 0xaf, 0x82, 0x79, 0x91, 0x86, 0xc7, 0xb4, 0x75, 0x07,
- 0xcb, 0xcf, 0x03, 0x57, 0x46, 0xeb, 0x04, 0xdd, 0xb7, 0x16},
- {0x5a, 0x4d, 0x0e, 0x8b, 0x5f, 0xdc, 0xfd, 0xf6, 0x4e, 0x72,
- 0x99, 0xa3, 0x6c, 0x06, 0x0d, 0xb2, 0x22, 0xca, 0x78, 0xe4},
- {0x5a, 0x5a, 0x4d, 0xaf, 0x78, 0x61, 0x26, 0x7c, 0x4b, 0x1f,
- 0x1e, 0x67, 0x58, 0x6b, 0xae, 0x6e, 0xd4, 0xfe, 0xb9, 0x3f},
- {0x5b, 0xb5, 0x99, 0x20, 0xd1, 0x1b, 0x39, 0x14, 0x79, 0x46,
- 0x3a, 0xdd, 0x51, 0x00, 0xdb, 0x1d, 0x52, 0xf4, 0x3a, 0xd4},
- {0x5d, 0x00, 0x38, 0x60, 0xf0, 0x02, 0xed, 0x82, 0x9d, 0xea,
- 0xa4, 0x18, 0x68, 0xf7, 0x88, 0x18, 0x6d, 0x62, 0x12, 0x7f},
- {0x5d, 0x98, 0x9c, 0xdb, 0x15, 0x96, 0x11, 0x36, 0x51, 0x65,
- 0x64, 0x1b, 0x56, 0x0f, 0xdb, 0xea, 0x2a, 0xc2, 0x3e, 0xf1},
- {0x5f, 0x3a, 0xfc, 0x0a, 0x8b, 0x64, 0xf6, 0x86, 0x67, 0x34,
- 0x74, 0xdf, 0x7e, 0xa9, 0xa2, 0xfe, 0xf9, 0xfa, 0x7a, 0x51},
- {0x5f, 0x3b, 0x8c, 0xf2, 0xf8, 0x10, 0xb3, 0x7d, 0x78, 0xb4,
- 0xce, 0xec, 0x19, 0x19, 0xc3, 0x73, 0x34, 0xb9, 0xc7, 0x74},
- {0x5f, 0x43, 0xe5, 0xb1, 0xbf, 0xf8, 0x78, 0x8c, 0xac, 0x1c,
- 0xc7, 0xca, 0x4a, 0x9a, 0xc6, 0x22, 0x2b, 0xcc, 0x34, 0xc6},
- {0x5f, 0x4e, 0x1f, 0xcf, 0x31, 0xb7, 0x91, 0x3b, 0x85, 0x0b,
- 0x54, 0xf6, 0xe5, 0xff, 0x50, 0x1a, 0x2b, 0x6f, 0xc6, 0xcf},
- {0x5f, 0xb7, 0xee, 0x06, 0x33, 0xe2, 0x59, 0xdb, 0xad, 0x0c,
- 0x4c, 0x9a, 0xe6, 0xd3, 0x8f, 0x1a, 0x61, 0xc7, 0xdc, 0x25},
- {0x60, 0xd6, 0x89, 0x74, 0xb5, 0xc2, 0x65, 0x9e, 0x8a, 0x0f,
- 0xc1, 0x88, 0x7c, 0x88, 0xd2, 0x46, 0x69, 0x1b, 0x18, 0x2c},
- {0x61, 0x57, 0x3a, 0x11, 0xdf, 0x0e, 0xd8, 0x7e, 0xd5, 0x92,
- 0x65, 0x22, 0xea, 0xd0, 0x56, 0xd7, 0x44, 0xb3, 0x23, 0x71},
- {0x61, 0xef, 0x43, 0xd7, 0x7f, 0xca, 0xd4, 0x61, 0x51, 0xbc,
- 0x98, 0xe0, 0xc3, 0x59, 0x12, 0xaf, 0x9f, 0xeb, 0x63, 0x11},
- {0x62, 0x52, 0xdc, 0x40, 0xf7, 0x11, 0x43, 0xa2, 0x2f, 0xde,
- 0x9e, 0xf7, 0x34, 0x8e, 0x06, 0x42, 0x51, 0xb1, 0x81, 0x18},
- {0x62, 0x7f, 0x8d, 0x78, 0x27, 0x65, 0x63, 0x99, 0xd2, 0x7d,
- 0x7f, 0x90, 0x44, 0xc9, 0xfe, 0xb3, 0xf3, 0x3e, 0xfa, 0x9a},
- {0x64, 0x90, 0x2a, 0xd7, 0x27, 0x7a, 0xf3, 0xe3, 0x2c, 0xd8,
- 0xcc, 0x1d, 0xc7, 0x9d, 0xe1, 0xfd, 0x7f, 0x80, 0x69, 0xea},
- {0x67, 0x24, 0x89, 0x80, 0xde, 0x77, 0x5d, 0x2c, 0x9b, 0x04,
- 0xe4, 0x03, 0x07, 0x94, 0x0b, 0xad, 0xb3, 0x51, 0xf3, 0x95},
- {0x67, 0x65, 0x0d, 0xf1, 0x7e, 0x8e, 0x7e, 0x5b, 0x82, 0x40,
- 0xa4, 0xf4, 0x56, 0x4b, 0xcf, 0xe2, 0x3d, 0x69, 0xc6, 0xf0},
- {0x67, 0x82, 0xaa, 0xe0, 0xed, 0xee, 0xe2, 0x1a, 0x58, 0x39,
- 0xd3, 0xc0, 0xcd, 0x14, 0x68, 0x0a, 0x4f, 0x60, 0x14, 0x2a},
- {0x67, 0x9a, 0x4f, 0x81, 0xfc, 0x70, 0x5d, 0xde, 0xc4, 0x19,
- 0x77, 0x8d, 0xd2, 0xeb, 0xd8, 0x75, 0xf4, 0xc2, 0x42, 0xc6},
- {0x67, 0xeb, 0x33, 0x7b, 0x68, 0x4c, 0xeb, 0x0e, 0xc2, 0xb0,
- 0x76, 0x0a, 0xb4, 0x88, 0x27, 0x8c, 0xdd, 0x95, 0x97, 0xdd},
- {0x68, 0x8b, 0x6e, 0xb8, 0x07, 0xe8, 0xed, 0xa5, 0xc7, 0xb1,
- 0x7c, 0x43, 0x93, 0xd0, 0x79, 0x5f, 0x0f, 0xae, 0x15, 0x5f},
- {0x68, 0xed, 0x18, 0xb3, 0x09, 0xcd, 0x52, 0x91, 0xc0, 0xd3,
- 0x35, 0x7c, 0x1d, 0x11, 0x41, 0xbf, 0x88, 0x38, 0x66, 0xb1},
- {0x69, 0x69, 0x56, 0x2e, 0x40, 0x80, 0xf4, 0x24, 0xa1, 0xe7,
- 0x19, 0x9f, 0x14, 0xba, 0xf3, 0xee, 0x58, 0xab, 0x6a, 0xbb},
- {0x69, 0xbd, 0x8c, 0xf4, 0x9c, 0xd3, 0x00, 0xfb, 0x59, 0x2e,
- 0x17, 0x93, 0xca, 0x55, 0x6a, 0xf3, 0xec, 0xaa, 0x35, 0xfb},
- {0x6a, 0x17, 0x45, 0x70, 0xa9, 0x16, 0xfb, 0xe8, 0x44, 0x53,
- 0xee, 0xd3, 0xd0, 0x70, 0xa1, 0xd8, 0xda, 0x44, 0x28, 0x29},
- {0x6a, 0x6f, 0x2a, 0x8b, 0x6e, 0x26, 0x15, 0x08, 0x8d, 0xf5,
- 0x9c, 0xd2, 0x4c, 0x40, 0x24, 0x18, 0xae, 0x42, 0xa3, 0xf1},
- {0x6a, 0xd2, 0x3b, 0x9d, 0xc4, 0x8e, 0x37, 0x5f, 0x85, 0x9a,
- 0xd9, 0xca, 0xb5, 0x85, 0x32, 0x5c, 0x23, 0x89, 0x40, 0x71},
- {0x6b, 0x2f, 0x34, 0xad, 0x89, 0x58, 0xbe, 0x62, 0xfd, 0xb0,
- 0x6b, 0x5c, 0xce, 0xbb, 0x9d, 0xd9, 0x4f, 0x4e, 0x39, 0xf3},
- {0x6b, 0x81, 0x44, 0x6a, 0x5c, 0xdd, 0xf4, 0x74, 0xa0, 0xf8,
- 0x00, 0xff, 0xbe, 0x69, 0xfd, 0x0d, 0xb6, 0x28, 0x75, 0x16},
- {0x6d, 0xc5, 0xe5, 0x62, 0xa9, 0xfd, 0x64, 0xd4, 0xbb, 0x2f,
- 0x63, 0x1c, 0xcd, 0x04, 0x1e, 0x9a, 0xa6, 0xff, 0x60, 0xf1},
- {0x6e, 0x3a, 0x55, 0xa4, 0x19, 0x0c, 0x19, 0x5c, 0x93, 0x84,
- 0x3c, 0xc0, 0xdb, 0x72, 0x2e, 0x31, 0x30, 0x61, 0xf0, 0xb1},
- {0x6f, 0x38, 0x84, 0x56, 0x8e, 0x99, 0xc8, 0xc6, 0xac, 0x0e,
- 0x5d, 0xde, 0x2d, 0xb2, 0x02, 0xdd, 0x00, 0x2e, 0x36, 0x63},
- {0x6f, 0x62, 0xde, 0xb8, 0x6c, 0x85, 0x58, 0x5a, 0xe4, 0x2e,
- 0x47, 0x8d, 0xb4, 0xd7, 0x6d, 0xb3, 0x67, 0x58, 0x5a, 0xe6},
- {0x70, 0x17, 0x9b, 0x86, 0x8c, 0x00, 0xa4, 0xfa, 0x60, 0x91,
- 0x52, 0x22, 0x3f, 0x9f, 0x3e, 0x32, 0xbd, 0xe0, 0x05, 0x62},
- {0x70, 0x30, 0xaa, 0xbf, 0x84, 0x32, 0xa8, 0x00, 0x66, 0x6c,
- 0xcc, 0xc4, 0x2a, 0x88, 0x7e, 0x42, 0xb7, 0x55, 0x3e, 0x2b},
- {0x70, 0x5d, 0x2b, 0x45, 0x65, 0xc7, 0x04, 0x7a, 0x54, 0x06,
- 0x94, 0xa7, 0x9a, 0xf7, 0xab, 0xb8, 0x42, 0xbd, 0xc1, 0x61},
- {0x71, 0x89, 0x9a, 0x67, 0xbf, 0x33, 0xaf, 0x31, 0xbe, 0xfd,
- 0xc0, 0x71, 0xf8, 0xf7, 0x33, 0xb1, 0x83, 0x85, 0x63, 0x32},
- {0x72, 0x0f, 0xc1, 0x5d, 0xdc, 0x27, 0xd4, 0x56, 0xd0, 0x98,
- 0xfa, 0xbf, 0x3c, 0xdd, 0x78, 0xd3, 0x1e, 0xf5, 0xa8, 0xda},
- {0x74, 0x20, 0x74, 0x41, 0x72, 0x9c, 0xdd, 0x92, 0xec, 0x79,
- 0x31, 0xd8, 0x23, 0x10, 0x8d, 0xc2, 0x81, 0x92, 0xe2, 0xbb},
- {0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45,
- 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2},
- {0x74, 0x2c, 0xdf, 0x15, 0x94, 0x04, 0x9c, 0xbf, 0x17, 0xa2,
- 0x04, 0x6c, 0xc6, 0x39, 0xbb, 0x38, 0x88, 0xe0, 0x2e, 0x33},
- {0x75, 0x02, 0x51, 0xb2, 0xc6, 0x32, 0x53, 0x6f, 0x9d, 0x91,
- 0x72, 0x79, 0x54, 0x3c, 0x13, 0x7c, 0xd7, 0x21, 0xc6, 0xe0},
- {0x75, 0xe0, 0xab, 0xb6, 0x13, 0x85, 0x12, 0x27, 0x1c, 0x04,
- 0xf8, 0x5f, 0xdd, 0xde, 0x38, 0xe4, 0xb7, 0x24, 0x2e, 0xfe},
- {0x76, 0x12, 0xed, 0x9e, 0x49, 0xb3, 0x65, 0xb4, 0xda, 0xd3,
- 0x12, 0x0c, 0x01, 0xe6, 0x03, 0x74, 0x8d, 0xae, 0x8c, 0xf0},
- {0x76, 0x39, 0xc7, 0x18, 0x47, 0xe1, 0x51, 0xb5, 0xc7, 0xea,
- 0x01, 0xc7, 0x58, 0xfb, 0xf1, 0x2a, 0xba, 0x29, 0x8f, 0x7a},
- {0x76, 0xb7, 0x60, 0x96, 0xdd, 0x14, 0x56, 0x29, 0xac, 0x75,
- 0x85, 0xd3, 0x70, 0x63, 0xc1, 0xbc, 0x47, 0x86, 0x1c, 0x8b},
- {0x76, 0xe2, 0x7e, 0xc1, 0x4f, 0xdb, 0x82, 0xc1, 0xc0, 0xa6,
- 0x75, 0xb5, 0x05, 0xbe, 0x3d, 0x29, 0xb4, 0xed, 0xdb, 0xbb},
- {0x77, 0x47, 0x4f, 0xc6, 0x30, 0xe4, 0x0f, 0x4c, 0x47, 0x64,
- 0x3f, 0x84, 0xba, 0xb8, 0xc6, 0x95, 0x4a, 0x8a, 0x41, 0xec},
- {0x78, 0x6a, 0x74, 0xac, 0x76, 0xab, 0x14, 0x7f, 0x9c, 0x6a,
- 0x30, 0x50, 0xba, 0x9e, 0xa8, 0x7e, 0xfe, 0x9a, 0xce, 0x3c},
- {0x78, 0xe9, 0xdd, 0x06, 0x50, 0x62, 0x4d, 0xb9, 0xcb, 0x36,
- 0xb5, 0x07, 0x67, 0xf2, 0x09, 0xb8, 0x43, 0xbe, 0x15, 0xb3},
- {0x79, 0x98, 0xa3, 0x08, 0xe1, 0x4d, 0x65, 0x85, 0xe6, 0xc2,
- 0x1e, 0x15, 0x3a, 0x71, 0x9f, 0xba, 0x5a, 0xd3, 0x4a, 0xd9},
- {0x7a, 0x1c, 0xdd, 0xe3, 0xd2, 0x19, 0x7e, 0x71, 0x37, 0x43,
- 0x3d, 0x3f, 0x99, 0xc0, 0xb3, 0x69, 0xf7, 0x06, 0xc7, 0x49},
- {0x7a, 0x74, 0x41, 0x0f, 0xb0, 0xcd, 0x5c, 0x97, 0x2a, 0x36,
- 0x4b, 0x71, 0xbf, 0x03, 0x1d, 0x88, 0xa6, 0x51, 0x0e, 0x9e},
- {0x7a, 0xc5, 0xff, 0xf8, 0xdc, 0xbc, 0x55, 0x83, 0x17, 0x68,
- 0x77, 0x07, 0x3b, 0xf7, 0x51, 0x73, 0x5e, 0x9b, 0xd3, 0x58},
- {0x7e, 0x04, 0xde, 0x89, 0x6a, 0x3e, 0x66, 0x6d, 0x00, 0xe6,
- 0x87, 0xd3, 0x3f, 0xfa, 0xd9, 0x3b, 0xe8, 0x3d, 0x34, 0x9e},
- {0x7e, 0x20, 0x69, 0x39, 0xcc, 0x5f, 0xa8, 0x83, 0x63, 0x5f,
- 0x64, 0xc7, 0x50, 0xeb, 0xf5, 0xfd, 0xa9, 0xae, 0xe6, 0x53},
- {0x7e, 0x78, 0x4a, 0x10, 0x1c, 0x82, 0x65, 0xcc, 0x2d, 0xe1,
- 0xf1, 0x6d, 0x47, 0xb4, 0x40, 0xca, 0xd9, 0x0a, 0x19, 0x45},
- {0x7e, 0xb1, 0xa0, 0x42, 0x9b, 0xe5, 0xf4, 0x28, 0xac, 0x2b,
- 0x93, 0x97, 0x1d, 0x7c, 0x84, 0x48, 0xa5, 0x36, 0x07, 0x0c},
- {0x7f, 0x88, 0xcd, 0x72, 0x23, 0xf3, 0xc8, 0x13, 0x81, 0x8c,
- 0x99, 0x46, 0x14, 0xa8, 0x9c, 0x99, 0xfa, 0x3b, 0x52, 0x47},
- {0x7f, 0x8a, 0x77, 0x83, 0x6b, 0xdc, 0x6d, 0x06, 0x8f, 0x8b,
- 0x07, 0x37, 0xfc, 0xc5, 0x72, 0x54, 0x13, 0x06, 0x8c, 0xa4},
- {0x7f, 0x8a, 0xb0, 0xcf, 0xd0, 0x51, 0x87, 0x6a, 0x66, 0xf3,
- 0x36, 0x0f, 0x47, 0xc8, 0x8d, 0x8c, 0xd3, 0x35, 0xfc, 0x74},
- {0x7f, 0xb9, 0xe2, 0xc9, 0x95, 0xc9, 0x7a, 0x93, 0x9f, 0x9e,
- 0x81, 0xa0, 0x7a, 0xea, 0x9b, 0x4d, 0x70, 0x46, 0x34, 0x96},
- {0x7f, 0xbb, 0x6a, 0xcd, 0x7e, 0x0a, 0xb4, 0x38, 0xda, 0xaf,
- 0x6f, 0xd5, 0x02, 0x10, 0xd0, 0x07, 0xc6, 0xc0, 0x82, 0x9c},
- {0x80, 0x25, 0xef, 0xf4, 0x6e, 0x70, 0xc8, 0xd4, 0x72, 0x24,
- 0x65, 0x84, 0xfe, 0x40, 0x3b, 0x8a, 0x8d, 0x6a, 0xdb, 0xf5},
- {0x80, 0xbf, 0x3d, 0xe9, 0xa4, 0x1d, 0x76, 0x8d, 0x19, 0x4b,
- 0x29, 0x3c, 0x85, 0x63, 0x2c, 0xdb, 0xc8, 0xea, 0x8c, 0xf7},
- {0x81, 0x96, 0x8b, 0x3a, 0xef, 0x1c, 0xdc, 0x70, 0xf5, 0xfa,
- 0x32, 0x69, 0xc2, 0x92, 0xa3, 0x63, 0x5b, 0xd1, 0x23, 0xd3},
- {0x82, 0x50, 0xbe, 0xd5, 0xa2, 0x14, 0x43, 0x3a, 0x66, 0x37,
- 0x7c, 0xbc, 0x10, 0xef, 0x83, 0xf6, 0x69, 0xda, 0x3a, 0x67},
- {0x83, 0x51, 0x50, 0x9b, 0x7d, 0xf8, 0xcf, 0xe8, 0x7b, 0xae,
- 0x62, 0xae, 0xb9, 0xb0, 0x3a, 0x52, 0xf4, 0xe6, 0x2c, 0x79},
- {0x83, 0x8e, 0x30, 0xf7, 0x7f, 0xdd, 0x14, 0xaa, 0x38, 0x5e,
- 0xd1, 0x45, 0x00, 0x9c, 0x0e, 0x22, 0x36, 0x49, 0x4f, 0xaa},
- {0x84, 0x42, 0x9d, 0x9f, 0xe2, 0xe7, 0x3a, 0x0d, 0xc8, 0xaa,
- 0x0a, 0xe0, 0xa9, 0x02, 0xf2, 0x74, 0x99, 0x33, 0xfe, 0x02},
- {0x85, 0x37, 0x1c, 0xa6, 0xe5, 0x50, 0x14, 0x3d, 0xce, 0x28,
- 0x03, 0x47, 0x1b, 0xde, 0x3a, 0x09, 0xe8, 0xf8, 0x77, 0x0f},
- {0x85, 0xa4, 0x08, 0xc0, 0x9c, 0x19, 0x3e, 0x5d, 0x51, 0x58,
- 0x7d, 0xcd, 0xd6, 0x13, 0x30, 0xfd, 0x8c, 0xde, 0x37, 0xbf},
- {0x85, 0xb5, 0xff, 0x67, 0x9b, 0x0c, 0x79, 0x96, 0x1f, 0xc8,
- 0x6e, 0x44, 0x22, 0x00, 0x46, 0x13, 0xdb, 0x17, 0x92, 0x84},
- {0x87, 0x81, 0xc2, 0x5a, 0x96, 0xbd, 0xc2, 0xfb, 0x4c, 0x65,
- 0x06, 0x4f, 0xf9, 0x39, 0x0b, 0x26, 0x04, 0x8a, 0x0e, 0x01},
- {0x87, 0x82, 0xc6, 0xc3, 0x04, 0x35, 0x3b, 0xcf, 0xd2, 0x96,
- 0x92, 0xd2, 0x59, 0x3e, 0x7d, 0x44, 0xd9, 0x34, 0xff, 0x11},
- {0x87, 0x9f, 0x4b, 0xee, 0x05, 0xdf, 0x98, 0x58, 0x3b, 0xe3,
- 0x60, 0xd6, 0x33, 0xe7, 0x0d, 0x3f, 0xfe, 0x98, 0x71, 0xaf},
- {0x89, 0xc3, 0x2e, 0x6b, 0x52, 0x4e, 0x4d, 0x65, 0x38, 0x8b,
- 0x9e, 0xce, 0xdc, 0x63, 0x71, 0x34, 0xed, 0x41, 0x93, 0xa3},
- {0x89, 0xdf, 0x74, 0xfe, 0x5c, 0xf4, 0x0f, 0x4a, 0x80, 0xf9,
- 0xe3, 0x37, 0x7d, 0x54, 0xda, 0x91, 0xe1, 0x01, 0x31, 0x8e},
- {0x8a, 0x5c, 0x8c, 0xee, 0xa5, 0x03, 0xe6, 0x05, 0x56, 0xba,
- 0xd8, 0x1b, 0xd4, 0xf6, 0xc9, 0xb0, 0xed, 0xe5, 0x2f, 0xe0},
- {0x8b, 0x1a, 0x11, 0x06, 0xb8, 0xe2, 0x6b, 0x23, 0x29, 0x80,
- 0xfd, 0x65, 0x2e, 0x61, 0x81, 0x37, 0x64, 0x41, 0xfd, 0x11},
- {0x8b, 0xaf, 0x4c, 0x9b, 0x1d, 0xf0, 0x2a, 0x92, 0xf7, 0xda,
- 0x12, 0x8e, 0xb9, 0x1b, 0xac, 0xf4, 0x98, 0x60, 0x4b, 0x6f},
- {0x8c, 0x96, 0xba, 0xeb, 0xdd, 0x2b, 0x07, 0x07, 0x48, 0xee,
- 0x30, 0x32, 0x66, 0xa0, 0xf3, 0x98, 0x6e, 0x7c, 0xae, 0x58},
- {0x8c, 0xc4, 0x30, 0x7b, 0xc6, 0x07, 0x55, 0xe7, 0xb2, 0x2d,
- 0xd9, 0xf7, 0xfe, 0xa2, 0x45, 0x93, 0x6c, 0x7c, 0xf2, 0x88},
- {0x8c, 0xf4, 0x27, 0xfd, 0x79, 0x0c, 0x3a, 0xd1, 0x66, 0x06,
- 0x8d, 0xe8, 0x1e, 0x57, 0xef, 0xbb, 0x93, 0x22, 0x72, 0xd4},
- {0x8d, 0x08, 0xfc, 0x43, 0xc0, 0x77, 0x0c, 0xa8, 0x4f, 0x4d,
- 0xcc, 0xb2, 0xd4, 0x1a, 0x5d, 0x95, 0x6d, 0x78, 0x6d, 0xc4},
- {0x8d, 0x17, 0x84, 0xd5, 0x37, 0xf3, 0x03, 0x7d, 0xec, 0x70,
- 0xfe, 0x57, 0x8b, 0x51, 0x9a, 0x99, 0xe6, 0x10, 0xd7, 0xb0},
- {0x8e, 0x10, 0x32, 0xe9, 0x24, 0x59, 0x44, 0xf8, 0x47, 0x91,
- 0x98, 0x3e, 0xc9, 0xe8, 0x29, 0xcb, 0x10, 0x59, 0xb4, 0xd3},
- {0x8e, 0x1c, 0x74, 0xf8, 0xa6, 0x20, 0xb9, 0xe5, 0x8a, 0xf4,
- 0x61, 0xfa, 0xec, 0x2b, 0x47, 0x56, 0x51, 0x1a, 0x52, 0xc6},
- {0x8e, 0xb0, 0x3f, 0xc3, 0xcf, 0x7b, 0xb2, 0x92, 0x86, 0x62,
- 0x68, 0xb7, 0x51, 0x22, 0x3d, 0xb5, 0x10, 0x34, 0x05, 0xcb},
- {0x8e, 0xfd, 0xca, 0xbc, 0x93, 0xe6, 0x1e, 0x92, 0x5d, 0x4d,
- 0x1d, 0xed, 0x18, 0x1a, 0x43, 0x20, 0xa4, 0x67, 0xa1, 0x39},
- {0x8f, 0x43, 0x28, 0x8a, 0xd2, 0x72, 0xf3, 0x10, 0x3b, 0x6f,
- 0xb1, 0x42, 0x84, 0x85, 0xea, 0x30, 0x14, 0xc0, 0xbc, 0xfe},
- {0x90, 0x5f, 0x94, 0x2f, 0xd9, 0xf2, 0x8f, 0x67, 0x9b, 0x37,
- 0x81, 0x80, 0xfd, 0x4f, 0x84, 0x63, 0x47, 0xf6, 0x45, 0xc1},
- {0x90, 0x78, 0xc5, 0xa2, 0x8f, 0x9a, 0x43, 0x25, 0xc2, 0xa7,
- 0xc7, 0x38, 0x13, 0xcd, 0xfe, 0x13, 0xc2, 0x0f, 0x93, 0x4e},
- {0x90, 0xae, 0xa2, 0x69, 0x85, 0xff, 0x14, 0x80, 0x4c, 0x43,
- 0x49, 0x52, 0xec, 0xe9, 0x60, 0x84, 0x77, 0xaf, 0x55, 0x6f},
- {0x90, 0xde, 0xce, 0x77, 0xf8, 0xc8, 0x25, 0x34, 0x0e, 0x62,
- 0xeb, 0xd6, 0x35, 0xe1, 0xbe, 0x20, 0xcf, 0x73, 0x27, 0xdd},
- {0x90, 0xde, 0xde, 0x9e, 0x4c, 0x4e, 0x9f, 0x6f, 0xd8, 0x86,
- 0x17, 0x57, 0x9d, 0xd3, 0x91, 0xbc, 0x65, 0xa6, 0x89, 0x64},
- {0x91, 0x21, 0x98, 0xee, 0xf2, 0x3d, 0xca, 0xc4, 0x09, 0x39,
- 0x31, 0x2f, 0xee, 0x97, 0xdd, 0x56, 0x0b, 0xae, 0x49, 0xb1},
- {0x91, 0x58, 0xc5, 0xef, 0x98, 0x73, 0x01, 0xa8, 0x90, 0x3c,
- 0xfd, 0xab, 0x03, 0xd7, 0x2d, 0xa1, 0xd8, 0x89, 0x09, 0xc9},
- {0x91, 0xc6, 0xd6, 0xee, 0x3e, 0x8a, 0xc8, 0x63, 0x84, 0xe5,
- 0x48, 0xc2, 0x99, 0x29, 0x5c, 0x75, 0x6c, 0x81, 0x7b, 0x81},
- {0x92, 0x5a, 0x8f, 0x8d, 0x2c, 0x6d, 0x04, 0xe0, 0x66, 0x5f,
- 0x59, 0x6a, 0xff, 0x22, 0xd8, 0x63, 0xe8, 0x25, 0x6f, 0x3f},
- {0x93, 0x05, 0x7a, 0x88, 0x15, 0xc6, 0x4f, 0xce, 0x88, 0x2f,
- 0xfa, 0x91, 0x16, 0x52, 0x28, 0x78, 0xbc, 0x53, 0x64, 0x17},
- {0x93, 0xe6, 0xab, 0x22, 0x03, 0x03, 0xb5, 0x23, 0x28, 0xdc,
- 0xda, 0x56, 0x9e, 0xba, 0xe4, 0xd1, 0xd1, 0xcc, 0xfb, 0x65},
- {0x93, 0xf7, 0xf4, 0x8b, 0x12, 0x61, 0x94, 0x3f, 0x6a, 0x78,
- 0x21, 0x0c, 0x52, 0xe6, 0x26, 0xdf, 0xbf, 0xbb, 0xe2, 0x60},
- {0x96, 0x56, 0xcd, 0x7b, 0x57, 0x96, 0x98, 0x95, 0xd0, 0xe1,
- 0x41, 0x46, 0x68, 0x06, 0xfb, 0xb8, 0xc6, 0x11, 0x06, 0x87},
- {0x96, 0x83, 0x38, 0xf1, 0x13, 0xe3, 0x6a, 0x7b, 0xab, 0xdd,
- 0x08, 0xf7, 0x77, 0x63, 0x91, 0xa6, 0x87, 0x36, 0x58, 0x2e},
- {0x96, 0x97, 0x4c, 0xd6, 0xb6, 0x63, 0xa7, 0x18, 0x45, 0x26,
- 0xb1, 0xd6, 0x48, 0xad, 0x81, 0x5c, 0xf5, 0x1e, 0x80, 0x1a},
- {0x96, 0xc9, 0x1b, 0x0b, 0x95, 0xb4, 0x10, 0x98, 0x42, 0xfa,
- 0xd0, 0xd8, 0x22, 0x79, 0xfe, 0x60, 0xfa, 0xb9, 0x16, 0x83},
- {0x97, 0x1d, 0x34, 0x86, 0xfc, 0x1e, 0x8e, 0x63, 0x15, 0xf7,
- 0xc6, 0xf2, 0xe1, 0x29, 0x67, 0xc7, 0x24, 0x34, 0x22, 0x14},
- {0x97, 0x22, 0x6a, 0xae, 0x4a, 0x7a, 0x64, 0xa5, 0x9b, 0xd1,
- 0x67, 0x87, 0xf2, 0x7f, 0x84, 0x1c, 0x0a, 0x00, 0x1f, 0xd0},
- {0x97, 0x81, 0x79, 0x50, 0xd8, 0x1c, 0x96, 0x70, 0xcc, 0x34,
- 0xd8, 0x09, 0xcf, 0x79, 0x44, 0x31, 0x36, 0x7e, 0xf4, 0x74},
- {0x97, 0xe2, 0xe9, 0x96, 0x36, 0xa5, 0x47, 0x55, 0x4f, 0x83,
- 0x8f, 0xba, 0x38, 0xb8, 0x2e, 0x74, 0xf8, 0x9a, 0x83, 0x0a},
- {0x99, 0x57, 0xc5, 0x3f, 0xc5, 0x9f, 0xb8, 0xe7, 0x39, 0xf7,
- 0xa4, 0xb7, 0xa7, 0x0e, 0x9b, 0x8e, 0x65, 0x9f, 0x20, 0x8c},
- {0x99, 0xa6, 0x9b, 0xe6, 0x1a, 0xfe, 0x88, 0x6b, 0x4d, 0x2b,
- 0x82, 0x00, 0x7c, 0xb8, 0x54, 0xfc, 0x31, 0x7e, 0x15, 0x39},
- {0x9b, 0xaa, 0xe5, 0x9f, 0x56, 0xee, 0x21, 0xcb, 0x43, 0x5a,
- 0xbe, 0x25, 0x93, 0xdf, 0xa7, 0xf0, 0x40, 0xd1, 0x1d, 0xcb},
- {0x9c, 0x61, 0x5c, 0x4d, 0x4d, 0x85, 0x10, 0x3a, 0x53, 0x26,
- 0xc2, 0x4d, 0xba, 0xea, 0xe4, 0xa2, 0xd2, 0xd5, 0xcc, 0x97},
- {0x9c, 0xbb, 0x48, 0x53, 0xf6, 0xa4, 0xf6, 0xd3, 0x52, 0xa4,
- 0xe8, 0x32, 0x52, 0x55, 0x60, 0x13, 0xf5, 0xad, 0xaf, 0x65},
- {0x9c, 0xde, 0x26, 0xd0, 0x7b, 0xb6, 0x8d, 0xe3, 0x50, 0xc8,
- 0x35, 0xe7, 0x95, 0x0e, 0xe8, 0x1c, 0xde, 0x97, 0x87, 0xf5},
- {0x9d, 0x70, 0xbb, 0x01, 0xa5, 0xa4, 0xa0, 0x18, 0x11, 0x2e,
- 0xf7, 0x1c, 0x01, 0xb9, 0x32, 0xc5, 0x34, 0xe7, 0x88, 0xa8},
- {0x9e, 0xd1, 0x80, 0x28, 0xfb, 0x1e, 0x8a, 0x97, 0x01, 0x48,
- 0x0a, 0x78, 0x90, 0xa5, 0x9a, 0xcd, 0x73, 0xdf, 0xf8, 0x71},
- {0x9f, 0x74, 0x4e, 0x9f, 0x2b, 0x4d, 0xba, 0xec, 0x0f, 0x31,
- 0x2c, 0x50, 0xb6, 0x56, 0x3b, 0x8e, 0x2d, 0x93, 0xc3, 0x11},
- {0x9f, 0xad, 0x91, 0xa6, 0xce, 0x6a, 0xc6, 0xc5, 0x00, 0x47,
- 0xc4, 0x4e, 0xc9, 0xd4, 0xa5, 0x0d, 0x92, 0xd8, 0x49, 0x79},
- {0x9f, 0xc7, 0x96, 0xe8, 0xf8, 0x52, 0x4f, 0x86, 0x3a, 0xe1,
- 0x49, 0x6d, 0x38, 0x12, 0x42, 0x10, 0x5f, 0x1b, 0x78, 0xf5},
- {0xa0, 0x73, 0xe5, 0xc5, 0xbd, 0x43, 0x61, 0x0d, 0x86, 0x4c,
- 0x21, 0x13, 0x0a, 0x85, 0x58, 0x57, 0xcc, 0x9c, 0xea, 0x46},
- {0xa0, 0xa1, 0xab, 0x90, 0xc9, 0xfc, 0x84, 0x7b, 0x3b, 0x12,
- 0x61, 0xe8, 0x97, 0x7d, 0x5f, 0xd3, 0x22, 0x61, 0xd3, 0xcc},
- {0xa0, 0xf8, 0xdb, 0x3f, 0x0b, 0xf4, 0x17, 0x69, 0x3b, 0x28,
- 0x2e, 0xb7, 0x4a, 0x6a, 0xd8, 0x6d, 0xf9, 0xd4, 0x48, 0xa3},
- {0xa1, 0x4b, 0x48, 0xd9, 0x43, 0xee, 0x0a, 0x0e, 0x40, 0x90,
- 0x4f, 0x3c, 0xe0, 0xa4, 0xc0, 0x91, 0x93, 0x51, 0x5d, 0x3f},
- {0xa1, 0x58, 0x51, 0x87, 0x15, 0x65, 0x86, 0xce, 0xf9, 0xc4,
- 0x54, 0xe2, 0x2a, 0xb1, 0x5c, 0x58, 0x74, 0x56, 0x07, 0xb4},
- {0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55,
- 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b},
- {0xa1, 0xe7, 0xc6, 0x00, 0xaa, 0x41, 0x70, 0xe5, 0xb7, 0x4b,
- 0xc9, 0x4f, 0x9b, 0x97, 0x03, 0xed, 0xc2, 0x61, 0xb4, 0xb9},
- {0xa3, 0x99, 0xf7, 0x6f, 0x0c, 0xbf, 0x4c, 0x9d, 0xa5, 0x5e,
- 0x4a, 0xc2, 0x4e, 0x89, 0x60, 0x98, 0x4b, 0x29, 0x05, 0xb6},
- {0xa3, 0xe3, 0x1e, 0x20, 0xb2, 0xe4, 0x6a, 0x32, 0x85, 0x20,
- 0x47, 0x2d, 0x0c, 0xde, 0x95, 0x23, 0xe7, 0x26, 0x0c, 0x6d},
- {0xa4, 0x34, 0x89, 0x15, 0x9a, 0x52, 0x0f, 0x0d, 0x93, 0xd0,
- 0x32, 0xcc, 0xaf, 0x37, 0xe7, 0xfe, 0x20, 0xa8, 0xb4, 0x19},
- {0xa5, 0x9c, 0x9b, 0x10, 0xec, 0x73, 0x57, 0x51, 0x5a, 0xbb,
- 0x66, 0x0c, 0x4d, 0x94, 0xf7, 0x3b, 0x9e, 0x6e, 0x92, 0x72},
- {0xa5, 0xec, 0x73, 0xd4, 0x8c, 0x34, 0xfc, 0xbe, 0xf1, 0x00,
- 0x5a, 0xeb, 0x85, 0x84, 0x35, 0x24, 0xbb, 0xfa, 0xb7, 0x27},
- {0xa6, 0x9a, 0x91, 0xfd, 0x05, 0x7f, 0x13, 0x6a, 0x42, 0x63,
- 0x0b, 0xb1, 0x76, 0x0d, 0x2d, 0x51, 0x12, 0x0c, 0x16, 0x50},
- {0xa7, 0xf8, 0x39, 0x0b, 0xa5, 0x77, 0x05, 0x09, 0x6f, 0xd3,
- 0x69, 0x41, 0xd4, 0x2e, 0x71, 0x98, 0xc6, 0xd4, 0xd9, 0xd5},
- {0xa8, 0x98, 0x5d, 0x3a, 0x65, 0xe5, 0xe5, 0xc4, 0xb2, 0xd7,
- 0xd6, 0x6d, 0x40, 0xc6, 0xdd, 0x2f, 0xb1, 0x9c, 0x54, 0x36},
- {0xa9, 0x62, 0x8f, 0x4b, 0x98, 0xa9, 0x1b, 0x48, 0x35, 0xba,
- 0xd2, 0xc1, 0x46, 0x32, 0x86, 0xbb, 0x66, 0x64, 0x6a, 0x8c},
- {0xa9, 0x82, 0x2e, 0x6c, 0x69, 0x33, 0xc6, 0x3c, 0x14, 0x8c,
- 0x2d, 0xca, 0xa4, 0x4a, 0x5c, 0xf1, 0xaa, 0xd2, 0xc4, 0x2e},
- {0xa9, 0xe9, 0x78, 0x08, 0x14, 0x37, 0x58, 0x88, 0xf2, 0x05,
- 0x19, 0xb0, 0x6d, 0x2b, 0x0d, 0x2b, 0x60, 0x16, 0x90, 0x7d},
- {0xaa, 0xdb, 0xbc, 0x22, 0x23, 0x8f, 0xc4, 0x01, 0xa1, 0x27,
- 0xbb, 0x38, 0xdd, 0xf4, 0x1d, 0xdb, 0x08, 0x9e, 0xf0, 0x12},
- {0xab, 0x16, 0xdd, 0x14, 0x4e, 0xcd, 0xc0, 0xfc, 0x4b, 0xaa,
- 0xb6, 0x2e, 0xcf, 0x04, 0x08, 0x89, 0x6f, 0xde, 0x52, 0xb7},
- {0xab, 0x48, 0xf3, 0x33, 0xdb, 0x04, 0xab, 0xb9, 0xc0, 0x72,
- 0xda, 0x5b, 0x0c, 0xc1, 0xd0, 0x57, 0xf0, 0x36, 0x9b, 0x46},
- {0xab, 0x9d, 0x58, 0xc0, 0x3f, 0x54, 0xb1, 0xda, 0xe3, 0xf7,
- 0xc2, 0xd4, 0xc6, 0xc1, 0xec, 0x36, 0x94, 0x55, 0x9c, 0x37},
- {0xac, 0xed, 0x5f, 0x65, 0x53, 0xfd, 0x25, 0xce, 0x01, 0x5f,
- 0x1f, 0x7a, 0x48, 0x3b, 0x6a, 0x74, 0x9f, 0x61, 0x78, 0xc6},
- {0xad, 0x7e, 0x1c, 0x28, 0xb0, 0x64, 0xef, 0x8f, 0x60, 0x03,
- 0x40, 0x20, 0x14, 0xc3, 0xd0, 0xe3, 0x37, 0x0e, 0xb5, 0x8a},
- {0xae, 0x3b, 0x31, 0xbf, 0x8f, 0xd8, 0x91, 0x07, 0x9c, 0xf1,
- 0xdf, 0x34, 0xcb, 0xce, 0x6e, 0x70, 0xd3, 0x7f, 0xb5, 0xb0},
- {0xae, 0x50, 0x83, 0xed, 0x7c, 0xf4, 0x5c, 0xbc, 0x8f, 0x61,
- 0xc6, 0x21, 0xfe, 0x68, 0x5d, 0x79, 0x42, 0x21, 0x15, 0x6e},
- {0xae, 0xc5, 0xfb, 0x3f, 0xc8, 0xe1, 0xbf, 0xc4, 0xe5, 0x4f,
- 0x03, 0x07, 0x5a, 0x9a, 0xe8, 0x00, 0xb7, 0xf7, 0xb6, 0xfa},
- {0xaf, 0xe5, 0xd2, 0x44, 0xa8, 0xd1, 0x19, 0x42, 0x30, 0xff,
- 0x47, 0x9f, 0xe2, 0xf8, 0x97, 0xbb, 0xcd, 0x7a, 0x8c, 0xb4},
- {0xb0, 0x91, 0xaa, 0x91, 0x38, 0x47, 0xf3, 0x13, 0xd7, 0x27,
- 0xbc, 0xef, 0xc8, 0x17, 0x9f, 0x08, 0x6f, 0x3a, 0x8c, 0x0f},
- {0xb1, 0x2e, 0x13, 0x63, 0x45, 0x86, 0xa4, 0x6f, 0x1a, 0xb2,
- 0x60, 0x68, 0x37, 0x58, 0x2d, 0xc4, 0xac, 0xfd, 0x94, 0x97},
- {0xb1, 0x72, 0xb1, 0xa5, 0x6d, 0x95, 0xf9, 0x1f, 0xe5, 0x02,
- 0x87, 0xe1, 0x4d, 0x37, 0xea, 0x6a, 0x44, 0x63, 0x76, 0x8a},
- {0xb1, 0x9d, 0xd0, 0x96, 0xdc, 0xd4, 0xe3, 0xe0, 0xfd, 0x67,
- 0x68, 0x85, 0x50, 0x5a, 0x67, 0x2c, 0x43, 0x8d, 0x4e, 0x9c},
- {0xb1, 0xb2, 0x36, 0x4f, 0xd4, 0xd4, 0xf5, 0x2e, 0x89, 0xb2,
- 0xd0, 0xfa, 0xf3, 0x3e, 0x4d, 0x62, 0xbd, 0x96, 0x99, 0x21},
- {0xb1, 0xbc, 0x96, 0x8b, 0xd4, 0xf4, 0x9d, 0x62, 0x2a, 0xa8,
- 0x9a, 0x81, 0xf2, 0x15, 0x01, 0x52, 0xa4, 0x1d, 0x82, 0x9c},
- {0xb1, 0xea, 0xc3, 0xe5, 0xb8, 0x24, 0x76, 0xe9, 0xd5, 0x0b,
- 0x1e, 0xc6, 0x7d, 0x2c, 0xc1, 0x1e, 0x12, 0xe0, 0xb4, 0x91},
- {0xb2, 0xbd, 0x90, 0x31, 0xaa, 0x6d, 0x0e, 0x14, 0xf4, 0xc5,
- 0x7f, 0xd5, 0x48, 0x25, 0x8f, 0x37, 0xb1, 0xfb, 0x39, 0xe4},
- {0xb3, 0x1e, 0xb1, 0xb7, 0x40, 0xe3, 0x6c, 0x84, 0x02, 0xda,
- 0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9},
- {0xb3, 0x8f, 0xec, 0xec, 0x0b, 0x14, 0x8a, 0xa6, 0x86, 0xc3,
- 0xd0, 0x0f, 0x01, 0xec, 0xc8, 0x84, 0x8e, 0x80, 0x85, 0xeb},
- {0xb3, 0xea, 0xc4, 0x47, 0x76, 0xc9, 0xc8, 0x1c, 0xea, 0xf2,
- 0x9d, 0x95, 0xb6, 0xcc, 0xa0, 0x08, 0x1b, 0x67, 0xec, 0x9d},
- {0xb4, 0x2c, 0x86, 0xc9, 0x57, 0xfd, 0x39, 0x20, 0x0c, 0x45,
- 0xbb, 0xe3, 0x76, 0xc0, 0x8c, 0xd0, 0xf4, 0xd5, 0x86, 0xdb},
- {0xb4, 0x35, 0xd4, 0xe1, 0x11, 0x9d, 0x1c, 0x66, 0x90, 0xa7,
- 0x49, 0xeb, 0xb3, 0x94, 0xbd, 0x63, 0x7b, 0xa7, 0x82, 0xb7},
- {0xb5, 0x1c, 0x06, 0x7c, 0xee, 0x2b, 0x0c, 0x3d, 0xf8, 0x55,
- 0xab, 0x2d, 0x92, 0xf4, 0xfe, 0x39, 0xd4, 0xe7, 0x0f, 0x0e},
- {0xb5, 0x61, 0xeb, 0xea, 0xa4, 0xde, 0xe4, 0x25, 0x4b, 0x69,
- 0x1a, 0x98, 0xa5, 0x57, 0x47, 0xc2, 0x34, 0xc7, 0xd9, 0x71},
- {0xb7, 0x2f, 0xff, 0x92, 0xd2, 0xce, 0x43, 0xde, 0x0a, 0x8d,
- 0x4c, 0x54, 0x8c, 0x50, 0x37, 0x26, 0xa8, 0x1e, 0x2b, 0x93},
- {0xb8, 0x01, 0x86, 0xd1, 0xeb, 0x9c, 0x86, 0xa5, 0x41, 0x04,
- 0xcf, 0x30, 0x54, 0xf3, 0x4c, 0x52, 0xb7, 0xe5, 0x58, 0xc6},
- {0xb8, 0x23, 0x6b, 0x00, 0x2f, 0x1d, 0x16, 0x86, 0x53, 0x01,
- 0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb},
- {0xb8, 0x65, 0x13, 0x0b, 0xed, 0xca, 0x38, 0xd2, 0x7f, 0x69,
- 0x92, 0x94, 0x20, 0x77, 0x0b, 0xed, 0x86, 0xef, 0xbc, 0x10},
- {0xb9, 0x42, 0x94, 0xbf, 0x91, 0xea, 0x8f, 0xb6, 0x4b, 0xe6,
- 0x10, 0x97, 0xc7, 0xfb, 0x00, 0x13, 0x59, 0xb6, 0x76, 0xcb},
- {0xb9, 0xcd, 0x0c, 0xf6, 0x98, 0x35, 0xea, 0xbf, 0x3f, 0x13,
- 0x7f, 0x20, 0x49, 0xe4, 0xc9, 0x24, 0x87, 0x84, 0x77, 0xdb},
- {0xba, 0x29, 0x41, 0x60, 0x77, 0x98, 0x3f, 0xf4, 0xf3, 0xef,
- 0xf2, 0x31, 0x05, 0x3b, 0x2e, 0xea, 0x6d, 0x4d, 0x45, 0xfd},
- {0xbc, 0x7b, 0x3c, 0x6f, 0xef, 0x26, 0xb9, 0xf7, 0xab, 0x10,
- 0xd7, 0xa1, 0xf6, 0xb6, 0x7c, 0x5e, 0xd2, 0xa1, 0x2d, 0x3d},
- {0xbc, 0x92, 0x19, 0xdd, 0xc9, 0x8e, 0x14, 0xbf, 0x1a, 0x78,
- 0x1f, 0x6e, 0x28, 0x0b, 0x04, 0xc2, 0x7f, 0x90, 0x27, 0x12},
- {0xbe, 0x1a, 0xf2, 0x85, 0xf7, 0x86, 0xcd, 0xdb, 0xc4, 0x30,
- 0x38, 0x2e, 0xef, 0xf2, 0xa6, 0x6d, 0xfb, 0xcd, 0x5d, 0xd0},
- {0xbe, 0x36, 0xa4, 0x56, 0x2f, 0xb2, 0xee, 0x05, 0xdb, 0xb3,
- 0xd3, 0x23, 0x23, 0xad, 0xf4, 0x45, 0x08, 0x4e, 0xd6, 0x56},
- {0xbe, 0xb5, 0xa9, 0x95, 0x74, 0x6b, 0x9e, 0xdf, 0x73, 0x8b,
- 0x56, 0xe6, 0xdf, 0x43, 0x7a, 0x77, 0xbe, 0x10, 0x6b, 0x81},
- {0xbe, 0xd5, 0x25, 0xd1, 0xac, 0x63, 0xa7, 0xfc, 0x6a, 0x66,
- 0x0b, 0xa7, 0xa8, 0x95, 0x81, 0x8d, 0x5e, 0x8d, 0xd5, 0x64},
- {0xc0, 0x9a, 0xb0, 0xc8, 0xad, 0x71, 0x14, 0x71, 0x4e, 0xd5,
- 0xe2, 0x1a, 0x5a, 0x27, 0x6a, 0xdc, 0xd5, 0xe7, 0xef, 0xcb},
- {0xc0, 0xdb, 0x57, 0x81, 0x57, 0xe9, 0xee, 0x82, 0xb5, 0x91,
- 0x7d, 0xf0, 0xdd, 0x6d, 0x82, 0xee, 0x90, 0x39, 0xc4, 0xe2},
- {0xc1, 0x82, 0x11, 0x32, 0x8a, 0x92, 0xb3, 0xb2, 0x38, 0x09,
- 0xb9, 0xb5, 0xe2, 0x74, 0x0a, 0x07, 0xfb, 0x12, 0xeb, 0x5e},
- {0xc4, 0x18, 0xf6, 0x4d, 0x46, 0xd1, 0xdf, 0x00, 0x3d, 0x27,
- 0x30, 0x13, 0x72, 0x43, 0xa9, 0x12, 0x11, 0xc6, 0x75, 0xfb},
- {0xc4, 0x67, 0x4d, 0xdc, 0x6c, 0xe2, 0x96, 0x7f, 0xf9, 0xc9,
- 0x2e, 0x07, 0x2e, 0xf8, 0xe8, 0xa7, 0xfb, 0xd6, 0xa1, 0x31},
- {0xc7, 0x30, 0x26, 0xe3, 0x25, 0xfe, 0x21, 0x91, 0x6b, 0x55,
- 0xc4, 0xb5, 0x3a, 0x56, 0xb1, 0x3d, 0xca, 0xf3, 0xd6, 0x25},
- {0xc7, 0xf7, 0xcb, 0xe2, 0x02, 0x36, 0x66, 0xf9, 0x86, 0x02,
- 0x5d, 0x4a, 0x3e, 0x31, 0x3f, 0x29, 0xeb, 0x0c, 0x5b, 0x38},
- {0xc8, 0x60, 0xa3, 0x18, 0xfc, 0xf5, 0xb7, 0x13, 0x0b, 0x10,
- 0x07, 0xad, 0x7f, 0x61, 0x4a, 0x40, 0xff, 0xff, 0x18, 0x5f},
- {0xc8, 0xec, 0x8c, 0x87, 0x92, 0x69, 0xcb, 0x4b, 0xab, 0x39,
- 0xe9, 0x8d, 0x7e, 0x57, 0x67, 0xf3, 0x14, 0x95, 0x73, 0x9d},
- {0xc9, 0x32, 0x1d, 0xe6, 0xb5, 0xa8, 0x26, 0x66, 0xcf, 0x69,
- 0x71, 0xa1, 0x8a, 0x56, 0xf2, 0xd3, 0xa8, 0x67, 0x56, 0x02},
- {0xc9, 0x3c, 0x34, 0xea, 0x90, 0xd9, 0x13, 0x0c, 0x0f, 0x03,
- 0x00, 0x4b, 0x98, 0xbd, 0x8b, 0x35, 0x70, 0x91, 0x56, 0x11},
- {0xc9, 0xa8, 0xb9, 0xe7, 0x55, 0x80, 0x5e, 0x58, 0xe3, 0x53,
- 0x77, 0xa7, 0x25, 0xeb, 0xaf, 0xc3, 0x7b, 0x27, 0xcc, 0xd7},
- {0xca, 0x3a, 0xfb, 0xcf, 0x12, 0x40, 0x36, 0x4b, 0x44, 0xb2,
- 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7c, 0xf7},
- {0xca, 0xbb, 0x51, 0x67, 0x24, 0x00, 0x58, 0x8e, 0x64, 0x19,
- 0xf1, 0xd4, 0x08, 0x78, 0xd0, 0x40, 0x3a, 0xa2, 0x02, 0x64},
- {0xcb, 0x44, 0xa0, 0x97, 0x85, 0x7c, 0x45, 0xfa, 0x18, 0x7e,
- 0xd9, 0x52, 0x08, 0x6c, 0xb9, 0x84, 0x1f, 0x2d, 0x51, 0xb5},
- {0xcb, 0x65, 0x82, 0x64, 0xea, 0x8c, 0xda, 0x18, 0x6e, 0x17,
- 0x52, 0xfb, 0x52, 0xc3, 0x97, 0x36, 0x7e, 0xa3, 0x87, 0xbe},
- {0xcb, 0xa1, 0xc5, 0xf8, 0xb0, 0xe3, 0x5e, 0xb8, 0xb9, 0x45,
- 0x12, 0xd3, 0xf9, 0x34, 0xa2, 0xe9, 0x06, 0x10, 0xd3, 0x36},
- {0xcc, 0x7e, 0xa2, 0x92, 0xaf, 0x87, 0x15, 0xd7, 0x4c, 0xa4,
- 0xb4, 0x15, 0xf3, 0x20, 0x15, 0x4b, 0x24, 0xf5, 0x65, 0xfd},
- {0xcd, 0x78, 0x7a, 0x3d, 0x5c, 0xba, 0x82, 0x07, 0x08, 0x28,
- 0x48, 0x36, 0x5e, 0x9a, 0xcd, 0xe9, 0x68, 0x33, 0x64, 0xd8},
- {0xcd, 0xd4, 0xee, 0xae, 0x60, 0x00, 0xac, 0x7f, 0x40, 0xc3,
- 0x80, 0x2c, 0x17, 0x1e, 0x30, 0x14, 0x80, 0x30, 0xc0, 0x72},
- {0xce, 0x6a, 0x64, 0xa3, 0x09, 0xe4, 0x2f, 0xbb, 0xd9, 0x85,
- 0x1c, 0x45, 0x3e, 0x64, 0x09, 0xea, 0xe8, 0x7d, 0x60, 0xf1},
- {0xce, 0xa9, 0x89, 0x0d, 0x85, 0xd8, 0x07, 0x53, 0xa6, 0x26,
- 0x28, 0x6c, 0xda, 0xd7, 0x8c, 0xb5, 0x66, 0xd7, 0x0c, 0xf2},
- {0xcf, 0x9e, 0x87, 0x6d, 0xd3, 0xeb, 0xfc, 0x42, 0x26, 0x97,
- 0xa3, 0xb5, 0xa3, 0x7a, 0xa0, 0x76, 0xa9, 0x06, 0x23, 0x48},
- {0xcf, 0xde, 0xfe, 0x10, 0x2f, 0xda, 0x05, 0xbb, 0xe4, 0xc7,
- 0x8d, 0x2e, 0x44, 0x23, 0x58, 0x90, 0x05, 0xb2, 0x57, 0x1d},
- {0xcf, 0xe4, 0x31, 0x3d, 0xba, 0x05, 0xb8, 0xa7, 0xc3, 0x00,
- 0x63, 0x99, 0x5a, 0x9e, 0xb7, 0xc2, 0x47, 0xad, 0x8f, 0xd5},
- {0xcf, 0xf3, 0x60, 0xf5, 0x24, 0xcb, 0x20, 0xf1, 0xfe, 0xad,
- 0x89, 0x00, 0x6f, 0x7f, 0x58, 0x6a, 0x28, 0x5b, 0x2d, 0x5b},
- {0xcf, 0xf8, 0x10, 0xfb, 0x2c, 0x4f, 0xfc, 0x01, 0x56, 0xbf,
- 0xe1, 0xe1, 0xfa, 0xbc, 0xb4, 0x18, 0xc6, 0x8d, 0x31, 0xc5},
- {0xd1, 0xcb, 0xca, 0x5d, 0xb2, 0xd5, 0x2a, 0x7f, 0x69, 0x3b,
- 0x67, 0x4d, 0xe5, 0xf0, 0x5a, 0x1d, 0x0c, 0x95, 0x7d, 0xf0},
- {0xd1, 0xeb, 0x23, 0xa4, 0x6d, 0x17, 0xd6, 0x8f, 0xd9, 0x25,
- 0x64, 0xc2, 0xf1, 0xf1, 0x60, 0x17, 0x64, 0xd8, 0xe3, 0x49},
- {0xd2, 0x32, 0x09, 0xad, 0x23, 0xd3, 0x14, 0x23, 0x21, 0x74,
- 0xe4, 0x0d, 0x7f, 0x9d, 0x62, 0x13, 0x97, 0x86, 0x63, 0x3a},
- {0xd2, 0x44, 0x1a, 0xa8, 0xc2, 0x03, 0xae, 0xca, 0xa9, 0x6e,
- 0x50, 0x1f, 0x12, 0x4d, 0x52, 0xb6, 0x8f, 0xe4, 0xc3, 0x75},
- {0xd2, 0x9f, 0x6c, 0x98, 0xbe, 0xfc, 0x6d, 0x98, 0x65, 0x21,
- 0x54, 0x3e, 0xe8, 0xbe, 0x56, 0xce, 0xbc, 0x28, 0x8c, 0xf3},
- {0xd2, 0xed, 0xf8, 0x8b, 0x41, 0xb6, 0xfe, 0x01, 0x46, 0x1d,
- 0x6e, 0x28, 0x34, 0xec, 0x7c, 0x8f, 0x6c, 0x77, 0x72, 0x1e},
- {0xd3, 0xc0, 0x63, 0xf2, 0x19, 0xed, 0x07, 0x3e, 0x34, 0xad,
- 0x5d, 0x75, 0x0b, 0x32, 0x76, 0x29, 0xff, 0xd5, 0x9a, 0xf2},
- {0xd3, 0xee, 0xfb, 0xcb, 0xbc, 0xf4, 0x98, 0x67, 0x83, 0x86,
- 0x26, 0xe2, 0x3b, 0xb5, 0x9c, 0xa0, 0x1e, 0x30, 0x5d, 0xb7},
- {0xd4, 0xde, 0x20, 0xd0, 0x5e, 0x66, 0xfc, 0x53, 0xfe, 0x1a,
- 0x50, 0x88, 0x2c, 0x78, 0xdb, 0x28, 0x52, 0xca, 0xe4, 0x74},
- {0xd6, 0x9b, 0x56, 0x11, 0x48, 0xf0, 0x1c, 0x77, 0xc5, 0x45,
- 0x78, 0xc1, 0x09, 0x26, 0xdf, 0x5b, 0x85, 0x69, 0x76, 0xad},
- {0xd6, 0xbf, 0x79, 0x94, 0xf4, 0x2b, 0xe5, 0xfa, 0x29, 0xda,
- 0x0b, 0xd7, 0x58, 0x7b, 0x59, 0x1f, 0x47, 0xa4, 0x4f, 0x22},
- {0xd6, 0xda, 0xa8, 0x20, 0x8d, 0x09, 0xd2, 0x15, 0x4d, 0x24,
- 0xb5, 0x2f, 0xcb, 0x34, 0x6e, 0xb2, 0x58, 0xb2, 0x8a, 0x58},
- {0xd8, 0xa6, 0x33, 0x2c, 0xe0, 0x03, 0x6f, 0xb1, 0x85, 0xf6,
- 0x63, 0x4f, 0x7d, 0x6a, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27},
- {0xd8, 0xc5, 0x38, 0x8a, 0xb7, 0x30, 0x1b, 0x1b, 0x6e, 0xd4,
- 0x7a, 0xe6, 0x45, 0x25, 0x3a, 0x6f, 0x9f, 0x1a, 0x27, 0x61},
- {0xd8, 0xeb, 0x6b, 0x41, 0x51, 0x92, 0x59, 0xe0, 0xf3, 0xe7,
- 0x85, 0x00, 0xc0, 0x3d, 0xb6, 0x88, 0x97, 0xc9, 0xee, 0xfc},
- {0xd9, 0x04, 0x08, 0x0a, 0x49, 0x29, 0xc8, 0x38, 0xe9, 0xf1,
- 0x85, 0xec, 0xf7, 0xa2, 0x2d, 0xef, 0x99, 0x34, 0x24, 0x07},
- {0xda, 0x40, 0x18, 0x8b, 0x91, 0x89, 0xa3, 0xed, 0xee, 0xae,
- 0xda, 0x97, 0xfe, 0x2f, 0x9d, 0xf5, 0xb7, 0xd1, 0x8a, 0x41},
- {0xda, 0x8b, 0x65, 0x67, 0xef, 0x3f, 0x6e, 0x1e, 0xa2, 0x6a,
- 0xb1, 0x46, 0xe3, 0x6c, 0xcb, 0x57, 0x28, 0x04, 0x18, 0x46},
- {0xda, 0xc9, 0x02, 0x4f, 0x54, 0xd8, 0xf6, 0xdf, 0x94, 0x93,
- 0x5f, 0xb1, 0x73, 0x26, 0x38, 0xca, 0x6a, 0xd7, 0x7c, 0x13},
- {0xda, 0xfa, 0xf7, 0xfa, 0x66, 0x84, 0xec, 0x06, 0x8f, 0x14,
- 0x50, 0xbd, 0xc7, 0xc2, 0x81, 0xa5, 0xbc, 0xa9, 0x64, 0x57},
- {0xdb, 0x2b, 0x7b, 0x43, 0x4d, 0xfb, 0x7f, 0xc1, 0xcb, 0x59,
- 0x26, 0xec, 0x5d, 0x95, 0x21, 0xfe, 0x35, 0x0f, 0xf2, 0x79},
- {0xdb, 0xac, 0x3c, 0x7a, 0xa4, 0x25, 0x4d, 0xa1, 0xaa, 0x5c,
- 0xaa, 0xd6, 0x84, 0x68, 0xcb, 0x88, 0xee, 0xdd, 0xee, 0xa8},
- {0xdd, 0x83, 0xc5, 0x19, 0xd4, 0x34, 0x81, 0xfa, 0xd4, 0xc2,
- 0x2c, 0x03, 0xd7, 0x02, 0xfe, 0x9f, 0x3b, 0x22, 0xf5, 0x17},
- {0xdd, 0xe1, 0xd2, 0xa9, 0x01, 0x80, 0x2e, 0x1d, 0x87, 0x5e,
- 0x84, 0xb3, 0x80, 0x7e, 0x4b, 0xb1, 0xfd, 0x99, 0x41, 0x34},
- {0xdd, 0xfb, 0x16, 0xcd, 0x49, 0x31, 0xc9, 0x73, 0xa2, 0x03,
- 0x7d, 0x3f, 0xc8, 0x3a, 0x4d, 0x7d, 0x77, 0x5d, 0x05, 0xe4},
- {0xde, 0x28, 0xf4, 0xa4, 0xff, 0xe5, 0xb9, 0x2f, 0xa3, 0xc5,
- 0x03, 0xd1, 0xa3, 0x49, 0xa7, 0xf9, 0x96, 0x2a, 0x82, 0x12},
- {0xde, 0x3f, 0x40, 0xbd, 0x50, 0x93, 0xd3, 0x9b, 0x6c, 0x60,
- 0xf6, 0xda, 0xbc, 0x07, 0x62, 0x01, 0x00, 0x89, 0x76, 0xc9},
- {0xde, 0x99, 0x0c, 0xed, 0x99, 0xe0, 0x43, 0x1f, 0x60, 0xed,
- 0xc3, 0x93, 0x7e, 0x7c, 0xd5, 0xbf, 0x0e, 0xd9, 0xe5, 0xfa},
- {0xdf, 0x3c, 0x24, 0xf9, 0xbf, 0xd6, 0x66, 0x76, 0x1b, 0x26,
- 0x80, 0x73, 0xfe, 0x06, 0xd1, 0xcc, 0x8d, 0x4f, 0x82, 0xa4},
- {0xdf, 0x64, 0x6d, 0xcb, 0x7b, 0x0f, 0xd3, 0xa9, 0x6a, 0xee,
- 0x88, 0xc6, 0x4e, 0x2d, 0x67, 0x67, 0x11, 0xff, 0x9d, 0x5f},
- {0xdf, 0x71, 0x7e, 0xaa, 0x4a, 0xd9, 0x4e, 0xc9, 0x55, 0x84,
- 0x99, 0x60, 0x2d, 0x48, 0xde, 0x5f, 0xbc, 0xf0, 0x3a, 0x25},
- {0xe0, 0x92, 0x5e, 0x18, 0xc7, 0x76, 0x5e, 0x22, 0xda, 0xbd,
- 0x94, 0x27, 0x52, 0x9d, 0xa6, 0xaf, 0x4e, 0x06, 0x64, 0x28},
- {0xe0, 0x98, 0xec, 0xf3, 0x55, 0xc1, 0x99, 0x53, 0x27, 0x4d,
- 0x84, 0x77, 0x2a, 0x1c, 0xec, 0x96, 0xdc, 0x33, 0x56, 0xca},
- {0xe0, 0xab, 0x05, 0x94, 0x20, 0x72, 0x54, 0x93, 0x05, 0x60,
- 0x62, 0x02, 0x36, 0x70, 0xf7, 0xcd, 0x2e, 0xfc, 0x66, 0x66},
- {0xe0, 0xb4, 0x32, 0x2e, 0xb2, 0xf6, 0xa5, 0x68, 0xb6, 0x54,
- 0x53, 0x84, 0x48, 0x18, 0x4a, 0x50, 0x36, 0x87, 0x43, 0x84},
- {0xe1, 0x2d, 0xfb, 0x4b, 0x41, 0xd7, 0xd9, 0xc3, 0x2b, 0x30,
- 0x51, 0x4b, 0xac, 0x1d, 0x81, 0xd8, 0x38, 0x5e, 0x2d, 0x46},
- {0xe1, 0xa4, 0x5b, 0x14, 0x1a, 0x21, 0xda, 0x1a, 0x79, 0xf4,
- 0x1a, 0x42, 0xa9, 0x61, 0xd6, 0x69, 0xcd, 0x06, 0x34, 0xc1},
- {0xe2, 0xb8, 0x29, 0x4b, 0x55, 0x84, 0xab, 0x6b, 0x58, 0xc2,
- 0x90, 0x46, 0x6c, 0xac, 0x3f, 0xb8, 0x39, 0x8f, 0x84, 0x83},
- {0xe3, 0x92, 0x51, 0x2f, 0x0a, 0xcf, 0xf5, 0x05, 0xdf, 0xf6,
- 0xde, 0x06, 0x7f, 0x75, 0x37, 0xe1, 0x65, 0xea, 0x57, 0x4b},
- {0xe3, 0xd7, 0x36, 0x06, 0x99, 0x6c, 0xdf, 0xef, 0x61, 0xfa,
- 0x04, 0xc3, 0x35, 0xe9, 0x8e, 0xa9, 0x61, 0x04, 0x26, 0x4a},
- {0xe5, 0xdf, 0x74, 0x3c, 0xb6, 0x01, 0xc4, 0x9b, 0x98, 0x43,
- 0xdc, 0xab, 0x8c, 0xe8, 0x6a, 0x81, 0x10, 0x9f, 0xe4, 0x8e},
- {0xe6, 0x19, 0xd2, 0x5b, 0x38, 0x0b, 0x7b, 0x13, 0xfd, 0xa3,
- 0x3e, 0x8a, 0x58, 0xcd, 0x82, 0xd8, 0xa8, 0x8e, 0x05, 0x15},
- {0xe6, 0x21, 0xf3, 0x35, 0x43, 0x79, 0x05, 0x9a, 0x4b, 0x68,
- 0x30, 0x9d, 0x8a, 0x2f, 0x74, 0x22, 0x15, 0x87, 0xec, 0x79},
- {0xe7, 0x07, 0x15, 0xf6, 0xf7, 0x28, 0x36, 0x5b, 0x51, 0x90,
- 0xe2, 0x71, 0xde, 0xe4, 0xc6, 0x5e, 0xbe, 0xea, 0xca, 0xf3},
- {0xe7, 0xa1, 0x90, 0x29, 0xd3, 0xd5, 0x52, 0xdc, 0x0d, 0x0f,
- 0xc6, 0x92, 0xd3, 0xea, 0x88, 0x0d, 0x15, 0x2e, 0x1a, 0x6b},
- {0xe7, 0xb4, 0xf6, 0x9d, 0x61, 0xec, 0x90, 0x69, 0xdb, 0x7e,
- 0x90, 0xa7, 0x40, 0x1a, 0x3c, 0xf4, 0x7d, 0x4f, 0xe8, 0xee},
- {0xea, 0xbd, 0xa2, 0x40, 0x44, 0x0a, 0xbb, 0xd6, 0x94, 0x93,
- 0x0a, 0x01, 0xd0, 0x97, 0x64, 0xc6, 0xc2, 0xd7, 0x79, 0x66},
- {0xec, 0x0c, 0x37, 0x16, 0xea, 0x9e, 0xdf, 0xad, 0xd3, 0x5d,
- 0xfb, 0xd5, 0x56, 0x08, 0xe6, 0x0a, 0x05, 0xd3, 0xcb, 0xf3},
- {0xec, 0x93, 0xde, 0x08, 0x3c, 0x93, 0xd9, 0x33, 0xa9, 0x86,
- 0xb3, 0xd5, 0xcd, 0xe2, 0x5a, 0xcb, 0x2f, 0xee, 0xcf, 0x8e},
- {0xed, 0x8d, 0xc8, 0x38, 0x6c, 0x48, 0x86, 0xae, 0xee, 0x07,
- 0x91, 0x58, 0xaa, 0xc3, 0xbf, 0xe6, 0x58, 0xe3, 0x94, 0xb4},
- {0xed, 0xb3, 0xcb, 0x5f, 0xb4, 0x19, 0xa1, 0x85, 0x06, 0x62,
- 0x67, 0xe5, 0x79, 0x15, 0x54, 0xe1, 0xe2, 0x8b, 0x63, 0x99},
- {0xee, 0x29, 0xd6, 0xea, 0x98, 0xe6, 0x32, 0xc6, 0xe5, 0x27,
- 0xe0, 0x90, 0x6f, 0x02, 0x80, 0x68, 0x8b, 0xdf, 0x44, 0xdc},
- {0xee, 0x86, 0x93, 0x87, 0xff, 0xfd, 0x83, 0x49, 0xab, 0x5a,
- 0xd1, 0x43, 0x22, 0x58, 0x87, 0x89, 0xa4, 0x57, 0xb0, 0x12},
- {0xf0, 0x0f, 0xc3, 0x7d, 0x6a, 0x1c, 0x92, 0x61, 0xfb, 0x6b,
- 0xc1, 0xc2, 0x18, 0x49, 0x8c, 0x5a, 0xa4, 0xdc, 0x51, 0xfb},
- {0xf1, 0x38, 0xa3, 0x30, 0xa4, 0xea, 0x98, 0x6b, 0xeb, 0x52,
- 0x0b, 0xb1, 0x10, 0x35, 0x87, 0x6e, 0xfb, 0x9d, 0x7f, 0x1c},
- {0xf1, 0x7f, 0x6f, 0xb6, 0x31, 0xdc, 0x99, 0xe3, 0xa3, 0xc8,
- 0x7f, 0xfe, 0x1c, 0xf1, 0x81, 0x10, 0x88, 0xd9, 0x60, 0x33},
- {0xf1, 0x8b, 0x53, 0x8d, 0x1b, 0xe9, 0x03, 0xb6, 0xa6, 0xf0,
- 0x56, 0x43, 0x5b, 0x17, 0x15, 0x89, 0xca, 0xf3, 0x6b, 0xf2},
- {0xf3, 0x73, 0xb3, 0x87, 0x06, 0x5a, 0x28, 0x84, 0x8a, 0xf2,
- 0xf3, 0x4a, 0xce, 0x19, 0x2b, 0xdd, 0xc7, 0x8e, 0x9c, 0xac},
- {0xf4, 0x40, 0x95, 0xc2, 0x38, 0xac, 0x73, 0xfc, 0x4f, 0x77,
- 0xbf, 0x8f, 0x98, 0xdf, 0x70, 0xf8, 0xf0, 0x91, 0xbc, 0x52},
- {0xf4, 0x8b, 0x11, 0xbf, 0xde, 0xab, 0xbe, 0x94, 0x54, 0x20,
- 0x71, 0xe6, 0x41, 0xde, 0x6b, 0xbe, 0x88, 0x2b, 0x40, 0xb9},
- {0xf5, 0x17, 0xa2, 0x4f, 0x9a, 0x48, 0xc6, 0xc9, 0xf8, 0xa2,
- 0x00, 0x26, 0x9f, 0xdc, 0x0f, 0x48, 0x2c, 0xab, 0x30, 0x89},
- {0xf5, 0xc2, 0x7c, 0xf5, 0xff, 0xf3, 0x02, 0x9a, 0xcf, 0x1a,
- 0x1a, 0x4b, 0xec, 0x7e, 0xe1, 0x96, 0x4c, 0x77, 0xd7, 0x84},
- {0xf9, 0xb5, 0xb6, 0x32, 0x45, 0x5f, 0x9c, 0xbe, 0xec, 0x57,
- 0x5f, 0x80, 0xdc, 0xe9, 0x6e, 0x2c, 0xc7, 0xb2, 0x78, 0xb7},
- {0xf9, 0xcd, 0x0e, 0x2c, 0xda, 0x76, 0x24, 0xc1, 0x8f, 0xbd,
- 0xf0, 0xf0, 0xab, 0xb6, 0x45, 0xb8, 0xf7, 0xfe, 0xd5, 0x7a},
- {0xf9, 0xdd, 0x19, 0x26, 0x6b, 0x20, 0x43, 0xf1, 0xfe, 0x4b,
- 0x3d, 0xcb, 0x01, 0x90, 0xaf, 0xf1, 0x1f, 0x31, 0xa6, 0x9d},
- {0xfa, 0x08, 0x82, 0x59, 0x5f, 0x9c, 0xa6, 0xa1, 0x1e, 0xcc,
- 0xbe, 0xaf, 0x65, 0xc7, 0x64, 0xc0, 0xcc, 0xc3, 0x11, 0xd0},
- {0xfa, 0xa7, 0xd9, 0xfb, 0x31, 0xb7, 0x46, 0xf2, 0x00, 0xa8,
- 0x5e, 0x65, 0x79, 0x76, 0x13, 0xd8, 0x16, 0xe0, 0x63, 0xb5},
- {0xfa, 0xaa, 0x27, 0xb8, 0xca, 0xf5, 0xfd, 0xf5, 0xcd, 0xa9,
- 0x8a, 0xc3, 0x37, 0x85, 0x72, 0xe0, 0x4c, 0xe8, 0xf2, 0xe0},
- {0xfa, 0xb7, 0xee, 0x36, 0x97, 0x26, 0x62, 0xfb, 0x2d, 0xb0,
- 0x2a, 0xf6, 0xbf, 0x03, 0xfd, 0xe8, 0x7c, 0x4b, 0x2f, 0x9b},
- {0xfd, 0x1e, 0xd1, 0xe2, 0x02, 0x1b, 0x0b, 0x9f, 0x73, 0xe8,
- 0xeb, 0x75, 0xce, 0x23, 0x43, 0x6b, 0xbc, 0xc7, 0x46, 0xeb},
- {0xfe, 0x45, 0x65, 0x9b, 0x79, 0x03, 0x5b, 0x98, 0xa1, 0x61,
- 0xb5, 0x51, 0x2e, 0xac, 0xda, 0x58, 0x09, 0x48, 0x22, 0x4d},
- {0xfe, 0xb8, 0xc4, 0x32, 0xdc, 0xf9, 0x76, 0x9a, 0xce, 0xae,
- 0x3d, 0xd8, 0x90, 0x8f, 0xfd, 0x28, 0x86, 0x65, 0x64, 0x7d},
- {0xff, 0xb7, 0xe0, 0x8f, 0x66, 0xe1, 0xd0, 0xc2, 0x58, 0x2f,
- 0x02, 0x45, 0xc4, 0x97, 0x02, 0x92, 0xa4, 0x6e, 0x88, 0x03},
+static uint8_t kKnownRootCertSHA256Hashes[][32] = {
+ // C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate
+ // Authority
+ {0x00, 0x16, 0x86, 0xCD, 0x18, 0x1F, 0x83, 0xA1, 0xB1, 0x21, 0x7D, 0x30,
+ 0x5B, 0x36, 0x5C, 0x41, 0xE3, 0x47, 0x0A, 0x78, 0xA1, 0xD3, 0x7B, 0x13,
+ 0x4A, 0x98, 0xCD, 0x54, 0x7B, 0x92, 0xDA, 0xB3},
+ // C=SI, O=POSTA, OU=POSTArCA
+ {0x00, 0x7E, 0x45, 0x2F, 0xD5, 0xCF, 0x83, 0x89, 0x46, 0x69, 0x6D, 0xFE,
+ 0x37, 0xA2, 0xDB, 0x2E, 0xF3, 0x99, 0x14, 0x36, 0xD2, 0x7B, 0xCB, 0xAB,
+ 0x45, 0x92, 0x20, 0x53, 0xC1, 0x5A, 0x87, 0xA8},
+ // C=ES, O=Agencia Notarial de Certificacion S.L. Unipersonal - CIF
+ // B83395988, CN=ANCERT Certificados Notariales
+ {0x00, 0xAB, 0x44, 0x4A, 0xBD, 0x6B, 0xDB, 0xA3, 0x3D, 0xA8, 0xDE, 0x56,
+ 0x9A, 0xC4, 0xEC, 0xDE, 0x32, 0x6D, 0x1B, 0xE1, 0xA6, 0x14, 0x42, 0xD5,
+ 0xEE, 0xC3, 0x97, 0x5A, 0x0C, 0x24, 0x3F, 0x04},
+ // C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012
+ // Entrust, Inc. - for authorized use only, CN=Entrust Root Certification
+ // Authority - EC1
+ {0x02, 0xED, 0x0E, 0xB2, 0x8C, 0x14, 0xDA, 0x45, 0x16, 0x5C, 0x56, 0x67,
+ 0x91, 0x70, 0x0D, 0x64, 0x51, 0xD7, 0xFB, 0x56, 0xF0, 0xB2, 0xAB, 0x1D,
+ 0x3B, 0x8E, 0xB0, 0x70, 0xE5, 0x6E, 0xDF, 0xF5},
+ // C=US, O=Wells Fargo, OU=Wells Fargo Certification Authority, CN=Wells
+ // Fargo Root Certificate Authority
+ {0x03, 0x45, 0x8B, 0x6A, 0xBE, 0xEC, 0xC2, 0x14, 0x95, 0x3D, 0x97, 0x14,
+ 0x9A, 0xF4, 0x53, 0x91, 0x69, 0x1D, 0xE9, 0xF9, 0xCD, 0xCC, 0x26, 0x47,
+ 0x86, 0x3A, 0x3D, 0x67, 0xC9, 0x5C, 0x24, 0x3B},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Commercial
+ {0x03, 0x76, 0xAB, 0x1D, 0x54, 0xC5, 0xF9, 0x80, 0x3C, 0xE4, 0xB2, 0xE2,
+ 0x01, 0xA0, 0xEE, 0x7E, 0xEF, 0x7B, 0x57, 0xB6, 0x36, 0xE8, 0xA9, 0x3C,
+ 0x9B, 0x8D, 0x48, 0x60, 0xC9, 0x6F, 0x5F, 0xA7},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=Root CA
+ {0x03, 0x78, 0xB2, 0x02, 0xCC, 0xAB, 0xBA, 0x99, 0xA1, 0x2E, 0x56, 0x9A,
+ 0x11, 0xA0, 0x77, 0xDB, 0x1E, 0xDB, 0x39, 0x48, 0x20, 0x61, 0xC7, 0x5D,
+ 0x00, 0x73, 0x05, 0x9D, 0x9A, 0xB5, 0xB5, 0x13},
+ // CN=ACEDICOM Root, OU=PKI, O=EDICOM, C=ES
+ {0x03, 0x95, 0x0F, 0xB4, 0x9A, 0x53, 0x1F, 0x3E, 0x19, 0x91, 0x94, 0x23,
+ 0x98, 0xDF, 0xA9, 0xE0, 0xEA, 0x32, 0xD7, 0xBA, 0x1C, 0xDD, 0x9B, 0xC8,
+ 0x5D, 0xB5, 0x7E, 0xD9, 0x40, 0x0B, 0x43, 0x4A},
+ // C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
+ {0x04, 0x04, 0x80, 0x28, 0xBF, 0x1F, 0x28, 0x64, 0xD4, 0x8F, 0x9A, 0xD4,
+ 0xD8, 0x32, 0x94, 0x36, 0x6A, 0x82, 0x88, 0x56, 0x55, 0x3F, 0x3B, 0x14,
+ 0x30, 0x3F, 0x90, 0x14, 0x7F, 0x5D, 0x40, 0xEF},
+ // C=us, O=U.S. Government, OU=FBCA, CN=Common Policy
+ {0x04, 0xAC, 0xFB, 0x3B, 0x24, 0x79, 0x3F, 0x30, 0x0F, 0x67, 0xEF, 0x87,
+ 0xE4, 0x4D, 0xD7, 0x2C, 0xB9, 0xB2, 0x8B, 0x20, 0x4F, 0x38, 0x9A, 0x7C,
+ 0xD5, 0xAE, 0x28, 0x78, 0x5C, 0x7D, 0x42, 0xCD},
+ // C=LT, O=VI Registru Centras - I.k. 124110246, OU=Registru Centro
+ // Sertifikavimo Centras, CN=VI Registru Centras RCSC (RootCA)
+ {0x05, 0x36, 0x80, 0x1F, 0xBB, 0x44, 0x3B, 0x3E, 0x90, 0x5F, 0xD6, 0xD7,
+ 0x0D, 0x8C, 0x81, 0xEB, 0x88, 0x55, 0x1B, 0xE8, 0x06, 0x12, 0x99, 0x11,
+ 0x0D, 0x2B, 0x4F, 0x82, 0xE6, 0x4C, 0xAD, 0xE1},
+ // C=BE, O=Certipost s.a./n.v., CN=Certipost E-Trust Primary Qualified CA
+ {0x05, 0x8A, 0x40, 0x32, 0x3E, 0xC8, 0xC4, 0x62, 0x62, 0xC3, 0x05, 0x2A,
+ 0x5D, 0x35, 0x7B, 0x91, 0xAC, 0x24, 0xD3, 0xDA, 0x26, 0x35, 0x1B, 0x3F,
+ 0xF4, 0x40, 0x7E, 0x99, 0xF7, 0xA4, 0xE9, 0xB4},
+ // C=EU, L=Madrid (see current address at
+ // www.camerfirma.com/address)/serialNumber=A82743287, O=AC Camerfirma S.A.,
+ // CN=Chambers of Commerce Root - 2008
+ {0x06, 0x3E, 0x4A, 0xFA, 0xC4, 0x91, 0xDF, 0xD3, 0x32, 0xF3, 0x08, 0x9B,
+ 0x85, 0x42, 0xE9, 0x46, 0x17, 0xD8, 0x93, 0xD7, 0xFE, 0x94, 0x4E, 0x10,
+ 0xA7, 0x93, 0x7E, 0xE2, 0x9D, 0x96, 0x93, 0xC0},
+ // O=Digital Signature Trust Co., CN=DST Root CA X3
+ {0x06, 0x87, 0x26, 0x03, 0x31, 0xA7, 0x24, 0x03, 0xD9, 0x09, 0xF1, 0x05,
+ 0xE6, 0x9B, 0xCF, 0x0D, 0x32, 0xE1, 0xBD, 0x24, 0x93, 0xFF, 0xC6, 0xD9,
+ 0x20, 0x6D, 0x11, 0xBC, 0xD6, 0x77, 0x07, 0x39},
+ // C=JP, O=LGPKI, OU=Application CA G2
+ {0x06, 0xDB, 0x3A, 0xF2, 0xDB, 0x7B, 0xAE, 0xE0, 0x0C, 0x03, 0xB9, 0x57,
+ 0x82, 0x88, 0xBB, 0xDE, 0x54, 0x1D, 0x90, 0x6E, 0xB0, 0x06, 0x93, 0x27,
+ 0x41, 0x32, 0x95, 0xFF, 0xB4, 0x86, 0x00, 0x8E},
+ // C=IE, O=An Post, OU=Post.Trust Ltd., CN=Post.Trust Root CA
+ {0x07, 0x45, 0x3D, 0x53, 0x79, 0x3B, 0xF4, 0x18, 0x19, 0xA5, 0x25, 0x1C,
+ 0x69, 0xF8, 0x8E, 0x2B, 0xB3, 0x44, 0xB5, 0x9C, 0xA8, 0x28, 0xB5, 0xA5,
+ 0x43, 0x78, 0x15, 0x99, 0xEA, 0xF3, 0xD6, 0x02},
+ // C=IL, O=PersonalID Ltd., OU=Certificate Services, CN=PersonalID
+ // Trustworthy RootCA 2011
+ {0x07, 0x5B, 0xFC, 0xCA, 0x2D, 0x55, 0xAE, 0x6E, 0x35, 0x74, 0x2C, 0x32,
+ 0xAF, 0xD0, 0xCA, 0x8E, 0xA4, 0xC9, 0x58, 0xFE, 0xEF, 0xC2, 0x32, 0x24,
+ 0x99, 0x95, 0x41, 0xC0, 0x33, 0xD6, 0x9C, 0x8D},
+ // C=CN, O=CFCA GT CA
+ {0x07, 0x71, 0x92, 0x0C, 0x8C, 0xB8, 0x74, 0xD5, 0xC5, 0xA4, 0xDC, 0x0D,
+ 0x6A, 0x51, 0xA2, 0xD4, 0x95, 0xD3, 0x8C, 0x4D, 0xE2, 0xCD, 0x5B, 0x83,
+ 0xD2, 0xA0, 0x6F, 0xAA, 0x05, 0x19, 0x35, 0xF6},
+ // C=US, O=Equifax, OU=Equifax Secure Certificate Authority
+ {0x08, 0x29, 0x7A, 0x40, 0x47, 0xDB, 0xA2, 0x36, 0x80, 0xC7, 0x31, 0xDB,
+ 0x6E, 0x31, 0x76, 0x53, 0xCA, 0x78, 0x48, 0xE1, 0xBE, 0xBD, 0x3A, 0x0B,
+ 0x01, 0x79, 0xA7, 0x07, 0xF9, 0x2C, 0xF1, 0x78},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Networking
+ {0x0A, 0x81, 0xEC, 0x5A, 0x92, 0x97, 0x77, 0xF1, 0x45, 0x90, 0x4A, 0xF3,
+ 0x8D, 0x5D, 0x50, 0x9F, 0x66, 0xB5, 0xE2, 0xC5, 0x8F, 0xCD, 0xB5, 0x31,
+ 0x05, 0x8B, 0x0E, 0x17, 0xF3, 0xF0, 0xB4, 0x1B},
+ // C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok,
+ // CN=NetLock Expressz (Class C) Tanusitvanykiado
+ {0x0B, 0x5E, 0xED, 0x4E, 0x84, 0x64, 0x03, 0xCF, 0x55, 0xE0, 0x65, 0x84,
+ 0x84, 0x40, 0xED, 0x2A, 0x82, 0x75, 0x8B, 0xF5, 0xB9, 0xAA, 0x1F, 0x25,
+ 0x3D, 0x46, 0x13, 0xCF, 0xA0, 0x80, 0xFF, 0x3F},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=Certification Authority,
+ // CN=SSC Root CA B
+ {0x0B, 0x9F, 0x26, 0xDF, 0xCA, 0x68, 0x4C, 0x2C, 0xFC, 0xE2, 0x3E, 0x4E,
+ 0x4D, 0xD5, 0x67, 0xC8, 0x86, 0xBA, 0x25, 0x9E, 0x1D, 0xB2, 0x67, 0xF9,
+ 0x80, 0x6F, 0x0C, 0x5A, 0x09, 0x97, 0x11, 0xF2},
+ // C=EU, O=AC Camerfirma SA CIF A82743287, OU=http://www.chambersign.org,
+ // CN=Chambers of Commerce Root
+ {0x0C, 0x25, 0x8A, 0x12, 0xA5, 0x67, 0x4A, 0xEF, 0x25, 0xF2, 0x8B, 0xA7,
+ 0xDC, 0xFA, 0xEC, 0xEE, 0xA3, 0x48, 0xE5, 0x41, 0xE6, 0xF5, 0xCC, 0x4E,
+ 0xE6, 0x3B, 0x71, 0xB3, 0x61, 0x60, 0x6A, 0xC3},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // Certification Authority
+ {0x0C, 0x2C, 0xD6, 0x3D, 0xF7, 0x80, 0x6F, 0xA3, 0x99, 0xED, 0xE8, 0x09,
+ 0x11, 0x6B, 0x57, 0x5B, 0xF8, 0x79, 0x89, 0xF0, 0x65, 0x18, 0xF9, 0x80,
+ 0x8C, 0x86, 0x05, 0x03, 0x17, 0x8B, 0xAF, 0x66},
+ // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
+ {0x0D, 0x13, 0x6E, 0x43, 0x9F, 0x0A, 0xB6, 0xE9, 0x7F, 0x3A, 0x02, 0xA5,
+ 0x40, 0xDA, 0x9F, 0x06, 0x41, 0xAA, 0x55, 0x4E, 0x1D, 0x66, 0xEA, 0x51,
+ 0xAE, 0x29, 0x20, 0xD5, 0x1B, 0x2F, 0x72, 0x17},
+ // CN=Autoridad de Certificacion Raiz del Estado Venezolano, C=VE,
+ // L=Caracas, ST=Distrito Capital, O=Sistema Nacional de Certificacion
+ // Electronica, OU=Superintendencia de Servicios de Certificacion
+ // Electronica/emailAddress=acraiz@suscerte.gob.ve
+ {0x0E, 0x88, 0xEB, 0x6E, 0xA2, 0x56, 0xE1, 0x9E, 0xF8, 0xD3, 0xAB, 0xD6,
+ 0x1A, 0x24, 0xD3, 0x8D, 0xBA, 0xD6, 0x32, 0x81, 0x6D, 0xD9, 0x57, 0x29,
+ 0x44, 0x27, 0xE4, 0x72, 0x4D, 0x81, 0xA3, 0x86},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 2 CA 1
+ {0x0F, 0x4E, 0x9C, 0xDD, 0x26, 0x4B, 0x02, 0x55, 0x50, 0xD1, 0x70, 0x80,
+ 0x63, 0x40, 0x21, 0x4F, 0xE9, 0x44, 0x34, 0xC9, 0xB0, 0x2F, 0x69, 0x7E,
+ 0xC7, 0x10, 0xFC, 0x5F, 0xEA, 0xFB, 0x5E, 0x38},
+ // C=FR, O=Certplus, CN=Class 2 Primary CA
+ {0x0F, 0x99, 0x3C, 0x8A, 0xEF, 0x97, 0xBA, 0xAF, 0x56, 0x87, 0x14, 0x0E,
+ 0xD5, 0x9A, 0xD1, 0x82, 0x1B, 0xB4, 0xAF, 0xAC, 0xF0, 0xAA, 0x9A, 0x58,
+ 0xB5, 0xD5, 0x7A, 0x33, 0x8A, 0x3A, 0xFB, 0xCB},
+ // C=JP, O=Japanese Government, OU=GPKI, CN=ApplicationCA2 Root
+ {0x12, 0x6B, 0xF0, 0x1C, 0x10, 0x94, 0xD2, 0xF0, 0xCA, 0x2E, 0x35, 0x23,
+ 0x80, 0xB3, 0xC7, 0x24, 0x29, 0x45, 0x46, 0xCC, 0xC6, 0x55, 0x97, 0xBE,
+ 0xF7, 0xF1, 0x2D, 0x8A, 0x17, 0x1F, 0x19, 0x84},
+ // C=si, O=state-institutions, OU=sigen-ca
+ {0x12, 0xD4, 0x80, 0xC1, 0xA3, 0xC6, 0x64, 0x78, 0x1B, 0x99, 0xD9, 0xDF,
+ 0x0E, 0x9F, 0xAF, 0x3F, 0x1C, 0xAC, 0xEE, 0x1B, 0x3C, 0x30, 0xC3, 0x12,
+ 0x3A, 0x33, 0x7A, 0x4A, 0x45, 0x4F, 0xFE, 0xD2},
+ // C=EU, L=Madrid (see current address at
+ // www.camerfirma.com/address)/serialNumber=A82743287, O=AC Camerfirma S.A.,
+ // CN=Global Chambersign Root - 2008
+ {0x13, 0x63, 0x35, 0x43, 0x93, 0x34, 0xA7, 0x69, 0x80, 0x16, 0xA0, 0xD3,
+ 0x24, 0xDE, 0x72, 0x28, 0x4E, 0x07, 0x9D, 0x7B, 0x52, 0x20, 0xBB, 0x8F,
+ 0xBD, 0x74, 0x78, 0x16, 0xEE, 0xBE, 0xBA, 0xCA},
+ // C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification
+ // Authority
+ {0x14, 0x65, 0xFA, 0x20, 0x53, 0x97, 0xB8, 0x76, 0xFA, 0xA6, 0xF0, 0xA9,
+ 0x95, 0x8E, 0x55, 0x90, 0xE4, 0x0F, 0xCC, 0x7F, 0xAA, 0x4F, 0xB7, 0xC2,
+ 0xC8, 0x67, 0x75, 0x21, 0xFB, 0x5F, 0xB6, 0x58},
+ // C=FR, O=Certplus, CN=Certplus Root CA G1
+ {0x15, 0x2A, 0x40, 0x2B, 0xFC, 0xDF, 0x2C, 0xD5, 0x48, 0x05, 0x4D, 0x22,
+ 0x75, 0xB3, 0x9C, 0x7F, 0xCA, 0x3E, 0xC0, 0x97, 0x80, 0x78, 0xB0, 0xF0,
+ 0xEA, 0x76, 0xE5, 0x61, 0xA6, 0xC7, 0x43, 0x3E},
+ // C=es, O=Servicio de Certificacion del Colegio de Registradores (SCR),
+ // OU=Certificado Propio, OU=Certificado Raiz, CN=Certificado de la Clave
+ // Principal/street=Principe de Vergara 72 28006
+ // Madrid/emailAddress=scr@registradores.org
+ {0x15, 0x94, 0xCB, 0x5B, 0x82, 0x6C, 0x31, 0x5D, 0xE3, 0xBC, 0x93, 0x2C,
+ 0x56, 0x89, 0x5F, 0xF2, 0x3A, 0x3A, 0x98, 0x8B, 0x5D, 0xC1, 0xF0, 0x34,
+ 0xD2, 0x14, 0xDF, 0xD8, 0x58, 0xD8, 0x9E, 0xE8},
+ // C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate
+ // Authority
+ {0x15, 0xF0, 0xBA, 0x00, 0xA3, 0xAC, 0x7A, 0xF3, 0xAC, 0x88, 0x4C, 0x07,
+ 0x2B, 0x10, 0x11, 0xA0, 0x77, 0xBD, 0x77, 0xC0, 0x97, 0xF4, 0x01, 0x64,
+ 0xB2, 0xF8, 0x59, 0x8A, 0xBD, 0x83, 0x86, 0x0C},
+ // C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
+ {0x16, 0xAF, 0x57, 0xA9, 0xF6, 0x76, 0xB0, 0xAB, 0x12, 0x60, 0x95, 0xAA,
+ 0x5E, 0xBA, 0xDE, 0xF2, 0x2A, 0xB3, 0x11, 0x19, 0xD6, 0x44, 0xAC, 0x95,
+ 0xCD, 0x4B, 0x93, 0xDB, 0xF3, 0xF2, 0x6A, 0xEB},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // ECC Certification Authority
+ {0x17, 0x93, 0x92, 0x7A, 0x06, 0x14, 0x54, 0x97, 0x89, 0xAD, 0xCE, 0x2F,
+ 0x8F, 0x34, 0xF7, 0xF0, 0xB6, 0x6D, 0x0F, 0x3A, 0xE3, 0xA3, 0xB8, 0x4D,
+ 0x21, 0xEC, 0x15, 0xDB, 0xBA, 0x4F, 0xAD, 0xC7},
+ // OU=GlobalSign ECC Root CA - R5, O=GlobalSign, CN=GlobalSign
+ {0x17, 0x9F, 0xBC, 0x14, 0x8A, 0x3D, 0xD0, 0x0F, 0xD2, 0x4E, 0xA1, 0x34,
+ 0x58, 0xCC, 0x43, 0xBF, 0xA7, 0xF5, 0x9C, 0x81, 0x82, 0xD7, 0x83, 0xA5,
+ 0x13, 0xF6, 0xEB, 0xEC, 0x10, 0x0C, 0x89, 0x24},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3
+ {0x18, 0xF1, 0xFC, 0x7F, 0x20, 0x5D, 0xF8, 0xAD, 0xDD, 0xEB, 0x7F, 0xE0,
+ 0x07, 0xDD, 0x57, 0xE3, 0xAF, 0x37, 0x5A, 0x9C, 0x4D, 0x8D, 0x73, 0x54,
+ 0x6B, 0xF4, 0xF1, 0xFE, 0xD1, 0xE1, 0x8D, 0x35},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // Certification Authority
+ {0x1A, 0x0D, 0x20, 0x44, 0x5D, 0xE5, 0xBA, 0x18, 0x62, 0xD1, 0x9E, 0xF8,
+ 0x80, 0x85, 0x8C, 0xBC, 0xE5, 0x01, 0x02, 0xB3, 0x6E, 0x8F, 0x0A, 0x04,
+ 0x0C, 0x3C, 0x69, 0xE7, 0x45, 0x22, 0xFE, 0x6E},
+ // C=ZA, ST=Western Cape, L=Somerset West, O=South African Post Office
+ // Limited, OU=SAPO Trust Centre, CN=SAPO Class 3 Root
+ // CA/emailAddress=pkiadmin@trustcentre.co.za
+ {0x1A, 0x25, 0x12, 0xCD, 0xA6, 0x74, 0x4A, 0xBE, 0xA1, 0x14, 0x32, 0xA2,
+ 0xFD, 0xC9, 0xF8, 0xC0, 0x88, 0xDB, 0x5A, 0x98, 0xC8, 0x9E, 0x13, 0x35,
+ 0x25, 0x74, 0xCD, 0xE4, 0xD9, 0xE8, 0x0C, 0xDD},
+ // C=CN, O=China Internet Network Information Center, CN=China Internet
+ // Network Information Center EV Certificates Root
+ {0x1C, 0x01, 0xC6, 0xF4, 0xDB, 0xB2, 0xFE, 0xFC, 0x22, 0x55, 0x8B, 0x2B,
+ 0xCA, 0x32, 0x56, 0x3F, 0x49, 0x84, 0x4A, 0xCF, 0xC3, 0x2B, 0x7B, 0xE4,
+ 0xB0, 0xFF, 0x59, 0x9F, 0x9E, 0x8C, 0x7A, 0xF7},
+ // C=TN, O=ANCE, OU=Certification & PKI, CN=Agence Nationale de
+ // Certification Electronique/emailAddress=ance@certification.tn
+ {0x1D, 0x4F, 0x05, 0x96, 0xFC, 0xA2, 0x61, 0x1D, 0x09, 0xF8, 0x4C, 0x78,
+ 0xF2, 0xEA, 0x56, 0x5E, 0xF2, 0xEA, 0xB9, 0xCF, 0xC2, 0x72, 0xA1, 0x71,
+ 0x8B, 0xD3, 0x36, 0xE6, 0xE0, 0xAE, 0x02, 0x1A},
+ // C=FR, O=ANSSI, OU=0002 130007669, CN=IGC/A AC racine Etat francais
+ {0x1E, 0x1A, 0x69, 0x84, 0xB4, 0xE7, 0x6B, 0xD7, 0x09, 0xAE, 0xE3, 0xE9,
+ 0xC9, 0xCF, 0x31, 0x18, 0xEA, 0xC0, 0x96, 0xDA, 0xB9, 0xCC, 0x20, 0xDC,
+ 0x25, 0xFA, 0xAB, 0x67, 0x29, 0x7E, 0x96, 0x5A},
+ // C=CH, O=SwissSign AG, CN=SwissSign Silver Root CA - G3
+ {0x1E, 0x49, 0xAC, 0x5D, 0xC6, 0x9E, 0x86, 0xD0, 0x56, 0x5D, 0xA2, 0xC1,
+ 0x30, 0x5C, 0x41, 0x93, 0x30, 0xB0, 0xB7, 0x81, 0xBF, 0xEC, 0x50, 0xE5,
+ 0x4A, 0x1B, 0x35, 0xAF, 0x7F, 0xDD, 0xD5, 0x01},
+ // C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root CA 1
+ {0x21, 0xDB, 0x20, 0x12, 0x36, 0x60, 0xBB, 0x2E, 0xD4, 0x18, 0x20, 0x5D,
+ 0xA1, 0x1E, 0xE7, 0xA8, 0x5A, 0x65, 0xE2, 0xBC, 0x6E, 0x55, 0xB5, 0xAF,
+ 0x7E, 0x78, 0x99, 0xC8, 0xA2, 0x66, 0xD9, 0x2E},
+ // C=US, O=Cisco Systems, CN=Cisco RXC-R2
+ {0x22, 0x9C, 0xCC, 0x19, 0x6D, 0x32, 0xC9, 0x84, 0x21, 0xCC, 0x11, 0x9E,
+ 0x78, 0x48, 0x6E, 0xEB, 0xEF, 0x60, 0x3A, 0xEC, 0xD5, 0x25, 0xC6, 0xB8,
+ 0x8B, 0x47, 0xAB, 0xB7, 0x40, 0x69, 0x2B, 0x96},
+ // C=US, O=Digital Signature Trust Co., OU=DST-Entrust GTI CA
+ {0x22, 0xE0, 0xD1, 0x1D, 0xC9, 0x20, 0x7E, 0x16, 0xC9, 0x2B, 0x2E, 0xE1,
+ 0x8C, 0xFD, 0xB2, 0xC2, 0xE9, 0x40, 0x62, 0x68, 0x47, 0x92, 0x1F, 0xC5,
+ 0x28, 0xCE, 0xDD, 0x2F, 0x79, 0x32, 0xF7, 0x14},
+ // C=ES, O=IZENPE S.A., CN=Izenpe.com
+ {0x23, 0x80, 0x42, 0x03, 0xCA, 0x45, 0xD8, 0xCD, 0xE7, 0x16, 0xB8, 0xC1,
+ 0x3B, 0xF3, 0xB4, 0x48, 0x45, 0x7F, 0xA0, 0x6C, 0xC1, 0x02, 0x50, 0x99,
+ 0x7F, 0xA0, 0x14, 0x58, 0x31, 0x7C, 0x41, 0xE5},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Universal Root Certification
+ // Authority
+ {0x23, 0x99, 0x56, 0x11, 0x27, 0xA5, 0x71, 0x25, 0xDE, 0x8C, 0xEF, 0xEA,
+ 0x61, 0x0D, 0xDF, 0x2F, 0xA0, 0x78, 0xB5, 0xC8, 0x06, 0x7F, 0x4E, 0x82,
+ 0x82, 0x90, 0xBF, 0xB8, 0x60, 0xE8, 0x4B, 0x3C},
+ // C=US, ST=Utah, L=Salt Lake City, O=Xcert EZ by DST, CN=Xcert EZ by
+ // DST/emailAddress=ca@digsigtrust.com
+ {0x26, 0x02, 0xD2, 0x1E, 0x81, 0x27, 0x7A, 0x83, 0xF6, 0x04, 0x81, 0x28,
+ 0xF6, 0x1D, 0x79, 0x4A, 0x06, 0xF4, 0x74, 0xE1, 0xF7, 0x5E, 0x49, 0x74,
+ 0x0A, 0x81, 0x7C, 0x26, 0x66, 0xF6, 0x22, 0x11},
+ // CN=ComSign Global Root CA, O=ComSign Ltd., C=IL
+ {0x26, 0x05, 0x87, 0x5A, 0xFC, 0xC1, 0x76, 0xB2, 0xD6, 0x6D, 0xD6, 0x6A,
+ 0x99, 0x5D, 0x7F, 0x8D, 0x5E, 0xBB, 0x86, 0xCE, 0x12, 0x0D, 0x0E, 0x7E,
+ 0x9E, 0x7C, 0x6E, 0xF2, 0x94, 0xA2, 0x7D, 0x4C},
+ // C=FR, O=OpenTrust, CN=OpenTrust Root CA G2
+ {0x27, 0x99, 0x58, 0x29, 0xFE, 0x6A, 0x75, 0x15, 0xC1, 0xBF, 0xE8, 0x48,
+ 0xF9, 0xC4, 0x76, 0x1D, 0xB1, 0x6C, 0x22, 0x59, 0x29, 0x25, 0x7B, 0xF4,
+ 0x0D, 0x08, 0x94, 0xF2, 0x9E, 0xA8, 0xBA, 0xF2},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC
+ // TrustCenter Universal CA II
+ {0x28, 0x34, 0x99, 0x1C, 0xF6, 0x77, 0x46, 0x6D, 0x22, 0xBA, 0xAC, 0x3B,
+ 0x00, 0x55, 0xE5, 0xB9, 0x11, 0xD9, 0xA9, 0xE5, 0x5F, 0x5B, 0x85, 0xBA,
+ 0x02, 0xDC, 0x56, 0x67, 0x82, 0xC3, 0x0E, 0x8A},
+ // C=US, O=RSA Data Security, Inc., OU=Secure Server Certification Authority
+ {0x29, 0x30, 0xBD, 0x09, 0xA0, 0x71, 0x26, 0xBD, 0xC1, 0x72, 0x88, 0xD4,
+ 0xF2, 0xAD, 0x84, 0x64, 0x5E, 0xC9, 0x48, 0x60, 0x79, 0x07, 0xA9, 0x7B,
+ 0x5E, 0xD0, 0xB0, 0xB0, 0x58, 0x79, 0xEF, 0x69},
+ // C=NL, O=DigiNotar, CN=DigiNotar Root CA G2/emailAddress=info@diginotar.nl
+ {0x29, 0x4F, 0x55, 0xEF, 0x3B, 0xD7, 0x24, 0x4C, 0x6F, 0xF8, 0xA6, 0x8A,
+ 0xB7, 0x97, 0xE9, 0x18, 0x6E, 0xC2, 0x75, 0x82, 0x75, 0x1A, 0x79, 0x15,
+ 0x15, 0xE3, 0x29, 0x2E, 0x48, 0x37, 0x2D, 0x61},
+ // C=FR, O=Certinomis, OU=0002 433998903, CN=Certinomis - Root CA
+ {0x2A, 0x99, 0xF5, 0xBC, 0x11, 0x74, 0xB7, 0x3C, 0xBB, 0x1D, 0x62, 0x08,
+ 0x84, 0xE0, 0x1C, 0x34, 0xE5, 0x1C, 0xCB, 0x39, 0x78, 0xDA, 0x12, 0x5F,
+ 0x0E, 0x33, 0x26, 0x88, 0x83, 0xBF, 0x41, 0x58},
+ // C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc.,
+ // CN=Starfield Root Certificate Authority - G2
+ {0x2C, 0xE1, 0xCB, 0x0B, 0xF9, 0xD2, 0xF9, 0xE1, 0x02, 0x99, 0x3F, 0xBE,
+ 0x21, 0x51, 0x52, 0xC3, 0xB2, 0xDD, 0x0C, 0xAB, 0xDE, 0x1C, 0x68, 0xE5,
+ 0x31, 0x9B, 0x83, 0x91, 0x54, 0xDB, 0xB7, 0xF5},
+ // C=JP, O=Japanese Government, OU=ApplicationCA
+ {0x2D, 0x47, 0x43, 0x7D, 0xE1, 0x79, 0x51, 0x21, 0x5A, 0x12, 0xF3, 0xC5,
+ 0x8E, 0x51, 0xC7, 0x29, 0xA5, 0x80, 0x26, 0xEF, 0x1F, 0xCC, 0x0A, 0x5F,
+ 0xB3, 0xD9, 0xDC, 0x01, 0x2F, 0x60, 0x0D, 0x19},
+ // C=IN, O=India PKI, CN=CCA India 2011
+ {0x2D, 0x66, 0xA7, 0x02, 0xAE, 0x81, 0xBA, 0x03, 0xAF, 0x8C, 0xFF, 0x55,
+ 0xAB, 0x31, 0x8A, 0xFA, 0x91, 0x90, 0x39, 0xD9, 0xF3, 0x1B, 0x4D, 0x64,
+ 0x38, 0x86, 0x80, 0xF8, 0x13, 0x11, 0xB6, 0x5A},
+ // C=AT, ST=Austria, L=Vienna, O=ARGE DATEN - Austrian Society for Data
+ // Protection, OU=A-CERT Certification Service, CN=A-CERT
+ // ADVANCED/emailAddress=info@a-cert.at
+ {0x2D, 0xC6, 0x2C, 0x3F, 0x6C, 0x0C, 0xC9, 0x02, 0x0B, 0xBA, 0x77, 0xE1,
+ 0xC5, 0x11, 0x51, 0x10, 0x24, 0xB9, 0x43, 0xEE, 0x59, 0x88, 0x56, 0xDA,
+ 0x5A, 0x22, 0xE2, 0x22, 0xB7, 0x27, 0x7A, 0x20},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Root-05, CN=A-Trust-Root-05
+ {0x2D, 0xDE, 0x9D, 0x0C, 0x0A, 0x90, 0xE7, 0xB3, 0x2B, 0x5A, 0xBC, 0x01,
+ 0xF4, 0x17, 0x99, 0xD4, 0x2E, 0x95, 0xA1, 0xE3, 0xC3, 0x1C, 0x3B, 0x39,
+ 0x37, 0x3B, 0xB8, 0x14, 0x1E, 0xA5, 0x44, 0x71},
+ // C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE
+ // CyberTrust Root
+ {0x2D, 0xFC, 0xBA, 0xCA, 0xDF, 0x22, 0xA6, 0xFF, 0x10, 0x7A, 0x51, 0xFD,
+ 0x3E, 0x8B, 0x9E, 0x17, 0x85, 0x80, 0x28, 0x87, 0x9B, 0x13, 0xF7, 0xC3,
+ 0xB5, 0x7B, 0x3E, 0x1B, 0xD2, 0x31, 0x58, 0x09},
+ // C=US, O=Equifax Secure, OU=Equifax Secure eBusiness CA-2
+ {0x2F, 0x27, 0x4E, 0x48, 0xAB, 0xA4, 0xAC, 0x7B, 0x76, 0x59, 0x33, 0x10,
+ 0x17, 0x75, 0x50, 0x6D, 0xC3, 0x0E, 0xE3, 0x8E, 0xF6, 0xAC, 0xD5, 0xC0,
+ 0x49, 0x32, 0xCF, 0xE0, 0x41, 0x23, 0x42, 0x20},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC
+ // TrustCenter Universal CA III
+ {0x30, 0x9B, 0x4A, 0x87, 0xF6, 0xCA, 0x56, 0xC9, 0x31, 0x69, 0xAA, 0xA9,
+ 0x9C, 0x6D, 0x98, 0x88, 0x54, 0xD7, 0x89, 0x2B, 0xD5, 0x43, 0x7E, 0x2D,
+ 0x07, 0xB2, 0x9C, 0xBE, 0xDA, 0x55, 0xD3, 0x5D},
+ // C=US, O=IdenTrust, CN=IdenTrust Public Sector Root CA 1
+ {0x30, 0xD0, 0x89, 0x5A, 0x9A, 0x44, 0x8A, 0x26, 0x20, 0x91, 0x63, 0x55,
+ 0x22, 0xD1, 0xF5, 0x20, 0x10, 0xB5, 0x86, 0x7A, 0xCA, 0xE1, 0x2C, 0x78,
+ 0xEF, 0x95, 0x8F, 0xD4, 0xF4, 0x38, 0x9F, 0x2F},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3
+ {0x31, 0xAD, 0x66, 0x48, 0xF8, 0x10, 0x41, 0x38, 0xC7, 0x38, 0xF3, 0x9E,
+ 0xA4, 0x32, 0x01, 0x33, 0x39, 0x3E, 0x3A, 0x18, 0xCC, 0x02, 0x29, 0x6E,
+ 0xF9, 0x7C, 0x2A, 0xC9, 0xEF, 0x67, 0x31, 0xD0},
+ // C=BR, ST=Rio de Janeiro, L=Rio de Janeiro, O=Certisign Certificadora
+ // Digital Ltda., OU=Certisign Autoridade Certificadora AC3S
+ {0x31, 0xEA, 0xCE, 0x9B, 0x4C, 0x9C, 0x71, 0x73, 0x4A, 0x18, 0x56, 0x80,
+ 0xBC, 0x24, 0x86, 0x6C, 0xA6, 0xCB, 0xD8, 0x2B, 0x3C, 0xB6, 0x1B, 0xCC,
+ 0x87, 0x06, 0x26, 0x1B, 0x59, 0xCE, 0x10, 0x73},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 4 CA, CN=TC
+ // TrustCenter Class 4 CA II
+ {0x32, 0x66, 0x96, 0x7E, 0x59, 0xCD, 0x68, 0x00, 0x8D, 0x9D, 0xD3, 0x20,
+ 0x81, 0x11, 0x85, 0xC7, 0x04, 0x20, 0x5E, 0x8D, 0x95, 0xFD, 0xD8, 0x4F,
+ 0x1C, 0x7B, 0x31, 0x1E, 0x67, 0x04, 0xFC, 0x32},
+ // C=HU, L=Budapest, O=Microsec Ltd., OU=e-Szigno CA, CN=Microsec e-Szigno
+ // Root CA
+ {0x32, 0x7A, 0x3D, 0x76, 0x1A, 0xBA, 0xDE, 0xA0, 0x34, 0xEB, 0x99, 0x84,
+ 0x06, 0x27, 0x5C, 0xB1, 0xA4, 0x77, 0x6E, 0xFD, 0xAE, 0x2F, 0xDF, 0x6D,
+ 0x01, 0x68, 0xEA, 0x1C, 0x4F, 0x55, 0x67, 0xD0},
+ // C=SA, O=National Center for Digital Certification, OU=Saudi National Root
+ // CA
+ {0x34, 0xBB, 0x34, 0xE1, 0x4F, 0xAE, 0xD0, 0xD3, 0x39, 0x2F, 0x2F, 0xC4,
+ 0x41, 0xC0, 0xEC, 0xD5, 0xFD, 0x88, 0xAD, 0x88, 0x11, 0x8D, 0xF2, 0xD1,
+ 0xBA, 0x76, 0xCD, 0xEC, 0x1E, 0xEA, 0x10, 0xB8},
+ // CN=EBG Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, O=EBG Bili\xC5\x9Fim
+ // Teknolojileri ve Hizmetleri A.\xC5\x9E., C=TR
+ {0x35, 0xAE, 0x5B, 0xDD, 0xD8, 0xF7, 0xAE, 0x63, 0x5C, 0xFF, 0xBA, 0x56,
+ 0x82, 0xA8, 0xF0, 0x0B, 0x95, 0xF4, 0x84, 0x62, 0xC7, 0x10, 0x8E, 0xE9,
+ 0xA0, 0xE5, 0x29, 0x2B, 0x07, 0x4A, 0xAF, 0xB2},
+ // C=ES, O=Agencia Notarial de Certificacion S.L. Unipersonal - CIF
+ // B83395988, CN=ANCERT Corporaciones de Derecho Publico
+ {0x36, 0x54, 0x4D, 0x2F, 0xCE, 0x03, 0xC6, 0xC7, 0x2B, 0x70, 0xEB, 0x1A,
+ 0x80, 0x64, 0x26, 0x4D, 0xC1, 0x51, 0x17, 0x68, 0xC2, 0xD8, 0xF7, 0x6A,
+ 0x8B, 0x9F, 0x1F, 0x2B, 0xBD, 0x15, 0x3B, 0x7D},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
+ {0x37, 0xD5, 0x10, 0x06, 0xC5, 0x12, 0xEA, 0xAB, 0x62, 0x64, 0x21, 0xF1,
+ 0xEC, 0x8C, 0x92, 0x01, 0x3F, 0xC5, 0xF8, 0x2A, 0xE9, 0x8E, 0xE5, 0x33,
+ 0xEB, 0x46, 0x19, 0xB8, 0xDE, 0xB4, 0xD0, 0x6C},
+ // C=HU, L=Budapest, O=NetLock Halozatbiztonsagi Kft., OU=Tanusitvanykiadok,
+ // CN=NetLock Uzleti (Class B) Tanusitvanykiado
+ {0x39, 0xDF, 0x7B, 0x68, 0x2B, 0x7B, 0x93, 0x8F, 0x84, 0x71, 0x54, 0x81,
+ 0xCC, 0xDE, 0x8D, 0x60, 0xD8, 0xF2, 0x2E, 0xC5, 0x98, 0x87, 0x7D, 0x0A,
+ 0xAA, 0xC1, 0x2B, 0x59, 0x18, 0x2B, 0x03, 0x12},
+ // C=IE, O=An Post, OU=Post.Trust Ltd., CN=Post.Trust Root CA
+ {0x39, 0xF6, 0x03, 0x3C, 0xA6, 0x64, 0xCE, 0xDB, 0x21, 0x67, 0x44, 0xD3,
+ 0xC6, 0xF2, 0xB2, 0xE8, 0xE3, 0xCE, 0xBD, 0x68, 0x69, 0xF7, 0xDF, 0xF4,
+ 0x7E, 0x0D, 0xB9, 0x1A, 0x79, 0xC4, 0x16, 0xF8},
+ // C=CH, O=SwissSign AG, CN=SwissSign Platinum CA - G2
+ {0x3B, 0x22, 0x2E, 0x56, 0x67, 0x11, 0xE9, 0x92, 0x30, 0x0D, 0xC0, 0xB1,
+ 0x5A, 0xB9, 0x47, 0x3D, 0xAF, 0xDE, 0xF8, 0xC8, 0x4D, 0x0C, 0xEF, 0x7D,
+ 0x33, 0x17, 0xB4, 0xC1, 0x82, 0x1D, 0x14, 0x36},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA - G3
+ {0x3C, 0x4F, 0xB0, 0xB9, 0x5A, 0xB8, 0xB3, 0x00, 0x32, 0xF4, 0x32, 0xB8,
+ 0x6F, 0x53, 0x5F, 0xE1, 0x72, 0xC1, 0x85, 0xD0, 0xFD, 0x39, 0x86, 0x58,
+ 0x37, 0xCF, 0x36, 0x18, 0x7F, 0xA6, 0xF4, 0x28},
+ // C=HU, L=Budapest, O=Microsec Ltd., CN=Microsec e-Szigno Root CA
+ // 2009/emailAddress=info@e-szigno.hu
+ {0x3C, 0x5F, 0x81, 0xFE, 0xA5, 0xFA, 0xB8, 0x2C, 0x64, 0xBF, 0xA2, 0xEA,
+ 0xEC, 0xAF, 0xCD, 0xE8, 0xE0, 0x77, 0xFC, 0x86, 0x20, 0xA7, 0xCA, 0xE5,
+ 0x37, 0x16, 0x3D, 0xF3, 0x6E, 0xDB, 0xF3, 0x78},
+ // CN=ComSign Advanced Security CA
+ {0x3C, 0xCC, 0x3C, 0xCF, 0xE4, 0x54, 0x96, 0xD0, 0x7B, 0x62, 0x0D, 0xBF,
+ 0x13, 0x28, 0xE8, 0xA1, 0x49, 0x00, 0x18, 0xF4, 0x86, 0x33, 0xC8, 0xA2,
+ 0x8A, 0x99, 0x5C, 0xA6, 0x04, 0x08, 0xB0, 0xBE},
+ // C=AT, O=A-Trust Ges. f\xFCr Sicherheitssysteme im elektr. Datenverkehr
+ // GmbH, OU=A-Trust-Qual-01, CN=A-Trust-Qual-01
+ {0x3D, 0xEA, 0xE6, 0xAE, 0x97, 0x52, 0x84, 0xE0, 0xE6, 0xFA, 0x2E, 0xB7,
+ 0x6C, 0xE4, 0x6E, 0x12, 0x44, 0x18, 0x69, 0xA2, 0xA7, 0xD4, 0xE6, 0x7D,
+ 0xC7, 0xAB, 0x86, 0x64, 0xFE, 0xFD, 0xBB, 0xB0},
+ // C=EE, O=AS Sertifitseerimiskeskus, CN=EE Certification Centre Root
+ // CA/emailAddress=pki@sk.ee
+ {0x3E, 0x84, 0xBA, 0x43, 0x42, 0x90, 0x85, 0x16, 0xE7, 0x75, 0x73, 0xC0,
+ 0x99, 0x2F, 0x09, 0x79, 0xCA, 0x08, 0x4E, 0x46, 0x85, 0x68, 0x1F, 0xF1,
+ 0x95, 0xCC, 0xBA, 0x8A, 0x22, 0x9B, 0x8A, 0x76},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
+ {0x3E, 0x90, 0x99, 0xB5, 0x01, 0x5E, 0x8F, 0x48, 0x6C, 0x00, 0xBC, 0xEA,
+ 0x9D, 0x11, 0x1E, 0xE7, 0x21, 0xFA, 0xBA, 0x35, 0x5A, 0x89, 0xBC, 0xF1,
+ 0xDF, 0x69, 0x56, 0x1E, 0x3D, 0xC6, 0x32, 0x5C},
+ // C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=Trusted
+ // Certificate Services
+ {0x3F, 0x06, 0xE5, 0x56, 0x81, 0xD4, 0x96, 0xF5, 0xBE, 0x16, 0x9E, 0xB5,
+ 0x38, 0x9F, 0x9F, 0x2B, 0x8F, 0xF6, 0x1E, 0x17, 0x08, 0xDF, 0x68, 0x81,
+ 0x72, 0x48, 0x49, 0xCD, 0x5D, 0x27, 0xCB, 0x69},
+ // C=GB, O=Trustis Limited, OU=Trustis EVS Root CA
+ {0x3F, 0x9D, 0xA4, 0x74, 0x4E, 0xC9, 0x67, 0x6C, 0xD3, 0x8B, 0x53, 0x0E,
+ 0x50, 0x0A, 0x46, 0x3F, 0xBC, 0xB1, 0x81, 0x65, 0x97, 0x7F, 0xF0, 0xDA,
+ 0x6D, 0x59, 0x93, 0xC3, 0xFE, 0x5F, 0xAB, 0x7C},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Premium Server
+ // CA/emailAddress=premium-server@thawte.com
+ {0x3F, 0x9F, 0x27, 0xD5, 0x83, 0x20, 0x4B, 0x9E, 0x09, 0xC8, 0xA3, 0xD2,
+ 0x06, 0x6C, 0x4B, 0x57, 0xD3, 0xA2, 0x47, 0x9C, 0x36, 0x93, 0x65, 0x08,
+ 0x80, 0x50, 0x56, 0x98, 0x10, 0x5D, 0xBC, 0xE9},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=GPKIRootCA1
+ {0x40, 0x7C, 0x27, 0x6B, 0xEA, 0xD2, 0xE4, 0xAF, 0x06, 0x61, 0xEF, 0x66,
+ 0x97, 0x34, 0x1D, 0xEC, 0x0A, 0x1F, 0x94, 0x34, 0xE4, 0xEA, 0xFB, 0x2D,
+ 0x3D, 0x32, 0xA9, 0x05, 0x49, 0xD9, 0xDE, 0x4A},
+ // C=NL, O=Digidentity B.V., CN=Digidentity L3 Root CA - G2
+ {0x41, 0x7D, 0xCF, 0x31, 0x80, 0xF4, 0xED, 0x1A, 0x37, 0x47, 0xAC, 0xF1,
+ 0x17, 0x93, 0x16, 0xCD, 0x48, 0xCB, 0x05, 0xC5, 0x78, 0x84, 0x35, 0x16,
+ 0x8A, 0xED, 0x98, 0xC9, 0x8C, 0xDC, 0xB6, 0x15},
+ // C=CH, O=WISeKey, OU=Copyright (c) 2005, OU=OISTE Foundation Endorsed,
+ // CN=OISTE WISeKey Global Root GA CA
+ {0x41, 0xC9, 0x23, 0x86, 0x6A, 0xB4, 0xCA, 0xD6, 0xB7, 0xAD, 0x57, 0x80,
+ 0x81, 0x58, 0x2E, 0x02, 0x07, 0x97, 0xA6, 0xCB, 0xDF, 0x4F, 0xFF, 0x78,
+ 0xCE, 0x83, 0x96, 0xB3, 0x89, 0x37, 0xD7, 0xF5},
+ // C=US, O=SecureTrust Corporation, CN=Secure Global CA
+ {0x42, 0x00, 0xF5, 0x04, 0x3A, 0xC8, 0x59, 0x0E, 0xBB, 0x52, 0x7D, 0x20,
+ 0x9E, 0xD1, 0x50, 0x30, 0x29, 0xFB, 0xCB, 0xD4, 0x1C, 0xA1, 0xB5, 0x06,
+ 0xEC, 0x27, 0xF1, 0x5A, 0xDE, 0x7D, 0xAC, 0x69},
+ // C=FR, O=KEYNECTIS, OU=ROOT, CN=KEYNECTIS ROOT CA
+ {0x42, 0x10, 0xF1, 0x99, 0x49, 0x9A, 0x9A, 0xC3, 0x3C, 0x8D, 0xE0, 0x2B,
+ 0xA6, 0xDB, 0xAA, 0x14, 0x40, 0x8B, 0xDD, 0x8A, 0x6E, 0x32, 0x46, 0x89,
+ 0xC1, 0x92, 0x2D, 0x06, 0x97, 0x15, 0xA3, 0x32},
+ // C=FR, O=Certeurope, OU=0002 434202180, CN=Certeurope Root CA 2
+ {0x42, 0x14, 0x3A, 0x51, 0x1A, 0x3A, 0xFC, 0xDD, 0x80, 0xD5, 0x55, 0xDE,
+ 0xBB, 0x41, 0x91, 0xEC, 0x6B, 0xB2, 0x85, 0xEE, 0x66, 0xE6, 0x2E, 0xC6,
+ 0x57, 0xED, 0x20, 0xAD, 0xF7, 0xD5, 0x5F, 0xAA},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ {0x43, 0x48, 0xA0, 0xE9, 0x44, 0x4C, 0x78, 0xCB, 0x26, 0x5E, 0x05, 0x8D,
+ 0x5E, 0x89, 0x44, 0xB4, 0xD8, 0x4F, 0x96, 0x62, 0xBD, 0x26, 0xDB, 0x25,
+ 0x7F, 0x89, 0x34, 0xA4, 0x43, 0xC7, 0x01, 0x61},
+ // C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009
+ // Entrust, Inc. - for authorized use only, CN=Entrust Root Certification
+ // Authority - G2
+ {0x43, 0xDF, 0x57, 0x74, 0xB0, 0x3E, 0x7F, 0xEF, 0x5F, 0xE4, 0x0D, 0x93,
+ 0x1A, 0x7B, 0xED, 0xF1, 0xBB, 0x2E, 0x6B, 0x42, 0x73, 0x8C, 0x4E, 0x6D,
+ 0x38, 0x41, 0x10, 0x3D, 0x3A, 0xA7, 0xF3, 0x39},
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, C=TR, L=ANKARA, O=(c) 2005
+ // T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim
+ // G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.
+ {0x44, 0x04, 0xE3, 0x3B, 0x5E, 0x14, 0x0D, 0xCF, 0x99, 0x80, 0x51, 0xFD,
+ 0xFC, 0x80, 0x28, 0xC7, 0xC8, 0x16, 0x15, 0xC5, 0xEE, 0x73, 0x7B, 0x11,
+ 0x1B, 0x58, 0x82, 0x33, 0xA9, 0xB5, 0x35, 0xA0},
+ // C=US, O=VeriSign, Inc., OU=Class 4 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x44, 0x64, 0x0A, 0x0A, 0x0E, 0x4D, 0x00, 0x0F, 0xBD, 0x57, 0x4D, 0x2B,
+ 0x8A, 0x07, 0xBD, 0xB4, 0xD1, 0xDF, 0xED, 0x3B, 0x45, 0xBA, 0xAB, 0xA7,
+ 0x6F, 0x78, 0x57, 0x78, 0xC7, 0x01, 0x19, 0x61},
+ // C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert.
+ // Authority, CN=Hellenic Academic and Research Institutions ECC RootCA 2015
+ {0x44, 0xB5, 0x45, 0xAA, 0x8A, 0x25, 0xE6, 0x5A, 0x73, 0xCA, 0x15, 0xDC,
+ 0x27, 0xFC, 0x36, 0xD2, 0x4C, 0x1C, 0xB9, 0x95, 0x3A, 0x06, 0x65, 0x39,
+ 0xB1, 0x15, 0x82, 0xDC, 0x48, 0x7B, 0x48, 0x33},
+ // C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root
+ // Certificate Authority - G2
+ {0x45, 0x14, 0x0B, 0x32, 0x47, 0xEB, 0x9C, 0xC8, 0xC5, 0xB4, 0xF0, 0xD7,
+ 0xB5, 0x30, 0x91, 0xF7, 0x32, 0x92, 0x08, 0x9E, 0x6E, 0x5A, 0x63, 0xE2,
+ 0x74, 0x9D, 0xD3, 0xAC, 0xA9, 0x19, 0x8E, 0xDA},
+ // C=UY, O=ADMINISTRACION NACIONAL DE CORREOS, OU=SERVICIOS ELECTRONICOS,
+ // CN=Correo Uruguayo - Root CA
+ {0x46, 0x27, 0x32, 0x85, 0x61, 0x5D, 0x96, 0xE5, 0x2D, 0xA9, 0xFC, 0x2E,
+ 0xD8, 0xC0, 0x36, 0xF1, 0x0A, 0xF3, 0xD9, 0xF6, 0x28, 0x0F, 0x8D, 0x28,
+ 0x87, 0x06, 0xC5, 0x2B, 0x20, 0x11, 0xB4, 0xDA},
+ // C=PT, O=SCEE, CN=ECRaizEstado
+ {0x48, 0x8E, 0x13, 0x4F, 0x30, 0xC5, 0xDB, 0x56, 0xB7, 0x64, 0x73, 0xE6,
+ 0x08, 0x08, 0x68, 0x42, 0xBF, 0x21, 0xAF, 0x8A, 0xB3, 0xCD, 0x7A, 0xC6,
+ 0x7E, 0xBD, 0xF1, 0x25, 0xD5, 0x31, 0x83, 0x4E},
+ // C=PA, ST=Panama, L=Panama City, O=TrustCor Systems S. de R.L.,
+ // OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-1
+ {0x48, 0x8F, 0xCA, 0x18, 0x9E, 0xAA, 0xDF, 0x54, 0xA3, 0xF9, 0x20, 0xED,
+ 0x39, 0xE5, 0x87, 0x18, 0x3B, 0xA5, 0x12, 0x23, 0x29, 0x99, 0xFA, 0xE3,
+ 0xE4, 0xA2, 0x85, 0xFE, 0x98, 0xE2, 0x98, 0xD1},
+ // C=DK, O=TDC Internet, OU=TDC Internet Root CA
+ {0x48, 0x98, 0xC6, 0x88, 0x8C, 0x0C, 0xFF, 0xB0, 0xD3, 0xE3, 0x1A, 0xCA,
+ 0x8A, 0x37, 0xD4, 0xE3, 0x51, 0x5F, 0xF7, 0x46, 0xD0, 0x26, 0x35, 0xD8,
+ 0x66, 0x46, 0xCF, 0xA0, 0xA3, 0x18, 0x5A, 0xE7},
+ // C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.,
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H5
+ {0x49, 0x35, 0x1B, 0x90, 0x34, 0x44, 0xC1, 0x85, 0xCC, 0xDC, 0x5C, 0x69,
+ 0x3D, 0x24, 0xD8, 0x55, 0x5C, 0xB2, 0x08, 0xD6, 0xA8, 0x14, 0x13, 0x07,
+ 0x69, 0x9F, 0x4A, 0xF0, 0x63, 0x19, 0x9D, 0x78},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co.,
+ // OU=National Retail Federation, CN=DST (NRF)
+ // RootCA/emailAddress=ca@digsigtrust.com
+ {0x49, 0xC8, 0x17, 0x5A, 0x98, 0x15, 0xE0, 0x8B, 0xEF, 0x12, 0x9A, 0x92,
+ 0x9D, 0xE1, 0xBA, 0xCA, 0xD0, 0x4E, 0x4D, 0xB6, 0x7A, 0x8C, 0x83, 0x92,
+ 0x93, 0x95, 0x3E, 0x50, 0x31, 0xC8, 0x1C, 0xA0},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 2009
+ {0x49, 0xE7, 0xA4, 0x42, 0xAC, 0xF0, 0xEA, 0x62, 0x87, 0x05, 0x00, 0x54,
+ 0xB5, 0x25, 0x64, 0xB6, 0x50, 0xE4, 0xF4, 0x9E, 0x42, 0xE3, 0x48, 0xD6,
+ 0xAA, 0x38, 0xE0, 0x39, 0xE9, 0x57, 0xB1, 0xC1},
+ // C=US, O=Digital Signature Trust Co., CN=Baltimore EZ by
+ // DST/mail=ca@digsigtrust.com
+ {0x49, 0xF7, 0x4F, 0x82, 0x4F, 0x2E, 0x05, 0x9F, 0xE9, 0x9C, 0x98, 0xAF,
+ 0x32, 0x19, 0xEC, 0x0D, 0x9A, 0x00, 0x4D, 0x1B, 0x64, 0xDD, 0x2F, 0xD1,
+ 0x45, 0x26, 0x16, 0x31, 0x8A, 0xB8, 0x06, 0xC0},
+ // C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008
+ // thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
+ {0x4B, 0x03, 0xF4, 0x58, 0x07, 0xAD, 0x70, 0xF2, 0x1B, 0xFC, 0x2C, 0xAE,
+ 0x71, 0xC9, 0xFD, 0xE4, 0x60, 0x4C, 0x06, 0x4C, 0xF5, 0xFF, 0xB6, 0x86,
+ 0xBA, 0xE5, 0xDB, 0xAA, 0xD7, 0xFD, 0xD3, 0x4C},
+ // C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
+ {0x4B, 0x22, 0xD5, 0xA6, 0xAE, 0xC9, 0x9F, 0x3C, 0xDB, 0x79, 0xAA, 0x5E,
+ 0xC0, 0x68, 0x38, 0x47, 0x9C, 0xD5, 0xEC, 0xBA, 0x71, 0x64, 0xF7, 0xF2,
+ 0x2D, 0xC1, 0xD6, 0x5F, 0x63, 0xD8, 0x57, 0x08},
+ // C=BR, O=Certisign Certificadora Digital Ltda., OU=Certisign - Autoridade
+ // Certificadora - AC4
+ {0x4B, 0xDB, 0x74, 0x18, 0xBD, 0xF7, 0xFF, 0xE3, 0x3B, 0xA0, 0x88, 0x4A,
+ 0xFA, 0x7C, 0x0C, 0x61, 0xFD, 0x85, 0xA1, 0x53, 0x97, 0x2F, 0x65, 0xF7,
+ 0xD0, 0x1C, 0xB3, 0xEC, 0x7E, 0xB4, 0x07, 0x3C},
+ // C=ES, O=Agencia Notarial de Certificacion S.L.U. - CIF B83395988,
+ // CN=ANCERT Certificados Notariales V2
+ {0x4B, 0xE8, 0xB5, 0xA1, 0xC7, 0x6C, 0x6A, 0xEA, 0xD0, 0x61, 0x19, 0x18,
+ 0xFC, 0xCF, 0x9D, 0xBD, 0x39, 0x8B, 0x67, 0xFB, 0x12, 0x29, 0x47, 0x58,
+ 0xBD, 0xF9, 0x94, 0xD0, 0xF9, 0x68, 0x2F, 0x60},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden EV Root CA
+ {0x4D, 0x24, 0x91, 0x41, 0x4C, 0xFE, 0x95, 0x67, 0x46, 0xEC, 0x4C, 0xEF,
+ 0xA6, 0xCF, 0x6F, 0x72, 0xE2, 0x8A, 0x13, 0x29, 0x43, 0x2F, 0x9D, 0x8A,
+ 0x90, 0x7A, 0xC4, 0xCB, 0x5D, 0xAD, 0xC1, 0x5A},
+ // C=ES, O=FNMT-RCM, OU=AC RAIZ FNMT-RCM
+ {0x4D, 0x9E, 0xBB, 0x28, 0x82, 0x5C, 0x96, 0x43, 0xAB, 0x15, 0xD5, 0x4E,
+ 0x5F, 0x96, 0x14, 0xF1, 0x3C, 0xB3, 0xE9, 0x5D, 0xE3, 0xCF, 0x4E, 0xAC,
+ 0x97, 0x13, 0x01, 0xF3, 0x20, 0xF9, 0x22, 0x6E},
+ // C=AT, O=Telekom-Control-Kommission, CN=Telekom-Control-Kommission Top 1
+ {0x4D, 0xBB, 0x01, 0x57, 0xA6, 0x91, 0xFA, 0x73, 0x82, 0x28, 0x9D, 0x65,
+ 0xC0, 0x33, 0x2D, 0xDB, 0x1D, 0xCB, 0x64, 0x0B, 0x40, 0xAD, 0x10, 0xF0,
+ 0x10, 0xA4, 0x3E, 0x20, 0xF3, 0xAF, 0xED, 0x1E},
+ // C=AT, ST=Austria, L=Vienna, O=Arge Daten Oesterreichische Gesellschaft
+ // fuer Datenschutz/emailAddress=a-cert@argedaten.at
+ {0x4E, 0x74, 0x80, 0xAD, 0x70, 0x2A, 0x37, 0x9D, 0xC5, 0x89, 0xAD, 0xB4,
+ 0xFA, 0xA6, 0x25, 0xE6, 0xA5, 0x99, 0x3F, 0x87, 0xEF, 0x23, 0x75, 0xD5,
+ 0x43, 0x7F, 0xFE, 0x3B, 0x79, 0xBE, 0x4E, 0x96},
+ // C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust
+ // ECC Certification Authority
+ {0x4F, 0xF4, 0x60, 0xD5, 0x4B, 0x9C, 0x86, 0xDA, 0xBF, 0xBC, 0xFC, 0x57,
+ 0x12, 0xE0, 0x40, 0x0D, 0x2B, 0xED, 0x3F, 0xBC, 0x4D, 0x4F, 0xBD, 0xAA,
+ 0x86, 0xE0, 0x6A, 0xDC, 0xD2, 0xA9, 0xAD, 0x7A},
+ // CN=ComSign Secured CA, O=ComSign, C=IL
+ {0x50, 0x79, 0x41, 0xC7, 0x44, 0x60, 0xA0, 0xB4, 0x70, 0x86, 0x22, 0x0D,
+ 0x4E, 0x99, 0x32, 0x57, 0x2A, 0xB5, 0xD1, 0xB5, 0xBB, 0xCB, 0x89, 0x80,
+ 0xAB, 0x1C, 0xB1, 0x76, 0x51, 0xA8, 0x44, 0xD2},
+ // C=JP, O=SECOM Trust Systems CO.,LTD., OU=Security Communication RootCA2
+ {0x51, 0x3B, 0x2C, 0xEC, 0xB8, 0x10, 0xD4, 0xCD, 0xE5, 0xDD, 0x85, 0x39,
+ 0x1A, 0xDF, 0xC6, 0xC2, 0xDD, 0x60, 0xD8, 0x7B, 0xB7, 0x36, 0xD2, 0xB5,
+ 0x21, 0x48, 0x4A, 0xA4, 0x7A, 0x0E, 0xBE, 0xF6},
+ // O=eSign Australia, OU=Public Secure Services, CN=eSign Imperito Primary
+ // Root CA
+ {0x52, 0x7A, 0x42, 0x26, 0x7D, 0xAE, 0xA8, 0xD8, 0xF5, 0x4E, 0x91, 0xD2,
+ 0x82, 0xD5, 0xC2, 0x5B, 0x61, 0x5B, 0xC0, 0xDC, 0x73, 0xDC, 0x63, 0xA5,
+ 0x8F, 0x91, 0x6C, 0x4E, 0xD5, 0xBF, 0x59, 0xAC},
+ // C=US, O=GTE Corporation, CN=GTE CyberTrust Root
+ {0x52, 0x7B, 0x05, 0x05, 0x27, 0xDF, 0x52, 0x9C, 0x0F, 0x7A, 0xD0, 0x0C,
+ 0xEF, 0x1E, 0x7B, 0xA4, 0x21, 0x78, 0x81, 0x82, 0x61, 0x5C, 0x32, 0x6C,
+ 0x8B, 0x6D, 0x1A, 0x20, 0x61, 0xA0, 0xBD, 0x7C},
+ // C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO
+ // RSA Certification Authority
+ {0x52, 0xF0, 0xE1, 0xC4, 0xE5, 0x8E, 0xC6, 0x29, 0x29, 0x1B, 0x60, 0x31,
+ 0x7F, 0x07, 0x46, 0x71, 0xB8, 0x5D, 0x7E, 0xA8, 0x0D, 0x5B, 0x07, 0x27,
+ 0x34, 0x63, 0x53, 0x4B, 0x32, 0xB4, 0x02, 0x34},
+ // C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec
+ // Class 3 Public Primary Certification Authority - G4
+ {0x53, 0xDF, 0xDF, 0xA4, 0xE2, 0x97, 0xFC, 0xFE, 0x07, 0x59, 0x4E, 0x8C,
+ 0x62, 0xD5, 0xB8, 0xAB, 0x06, 0xB3, 0x2C, 0x75, 0x49, 0xF3, 0x8A, 0x16,
+ 0x30, 0x94, 0xFD, 0x64, 0x29, 0xD5, 0xDA, 0x43},
+ // C=JP, O=LGPKI, CN=Application CA G3 Root
+ {0x54, 0xB4, 0xFC, 0x43, 0xD4, 0x4A, 0xA4, 0xCA, 0x9F, 0xC0, 0x3C, 0xA7,
+ 0xE9, 0x94, 0x9F, 0xBA, 0xE2, 0x67, 0xA0, 0x64, 0xD0, 0x2D, 0xA2, 0x18,
+ 0x52, 0x41, 0x2A, 0x38, 0x1B, 0x5D, 0x15, 0x37},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4
+ {0x55, 0x2F, 0x7B, 0xDC, 0xF1, 0xA7, 0xAF, 0x9E, 0x6C, 0xE6, 0x72, 0x01,
+ 0x7F, 0x4F, 0x12, 0xAB, 0xF7, 0x72, 0x40, 0xC7, 0x8E, 0x76, 0x1A, 0xC2,
+ 0x03, 0xD1, 0xD9, 0xD2, 0x0A, 0xC8, 0x99, 0x88},
+ // CN=Autoridad Certificadora Ra\xC3\xADz Nacional de Uruguay, O=AGESIC,
+ // C=UY
+ {0x55, 0x33, 0xA0, 0x40, 0x1F, 0x61, 0x2C, 0x68, 0x8E, 0xBC, 0xE5, 0xBF,
+ 0x53, 0xF2, 0xEC, 0x14, 0xA7, 0x34, 0xEB, 0x17, 0x8B, 0xFA, 0xE0, 0x0E,
+ 0x50, 0xE8, 0x5D, 0xAE, 0x67, 0x23, 0x07, 0x8A},
+ // C=IT, L=Milan, O=Actalis S.p.A./03358520967, CN=Actalis Authentication
+ // Root CA
+ {0x55, 0x92, 0x60, 0x84, 0xEC, 0x96, 0x3A, 0x64, 0xB9, 0x6E, 0x2A, 0xBE,
+ 0x01, 0xCE, 0x0B, 0xA8, 0x6A, 0x64, 0xFB, 0xFE, 0xBC, 0xC7, 0xAA, 0xB5,
+ 0xAF, 0xC1, 0x55, 0xB3, 0x7F, 0xD7, 0x60, 0x66},
+ // C=ES, O=Consejo General de la Abogacia NIF:Q-2863006I, CN=Autoridad de
+ // Certificacion de la Abogacia
+ {0x56, 0x07, 0xE2, 0x60, 0x16, 0x3F, 0x49, 0xC8, 0xEA, 0x41, 0x75, 0xA1,
+ 0xC0, 0xA5, 0x3B, 0x13, 0x19, 0x5C, 0xB7, 0xD0, 0x78, 0x45, 0x61, 0x1E,
+ 0x94, 0x3A, 0x2F, 0xF5, 0x07, 0x03, 0x68, 0x34},
+ // C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc.,
+ // CN=Starfield Services Root Certificate Authority - G2
+ {0x56, 0x8D, 0x69, 0x05, 0xA2, 0xC8, 0x87, 0x08, 0xA4, 0xB3, 0x02, 0x51,
+ 0x90, 0xED, 0xCF, 0xED, 0xB1, 0x97, 0x4A, 0x60, 0x6A, 0x13, 0xC6, 0xE5,
+ 0x29, 0x0F, 0xCB, 0x2A, 0xE6, 0x3E, 0xDA, 0xB5},
+ // C=FR, O=OpenTrust, CN=OpenTrust Root CA G1
+ {0x56, 0xC7, 0x71, 0x28, 0xD9, 0x8C, 0x18, 0xD9, 0x1B, 0x4C, 0xFD, 0xFF,
+ 0xBC, 0x25, 0xEE, 0x91, 0x03, 0xD4, 0x75, 0x8E, 0xA2, 0xAB, 0xAD, 0x82,
+ 0x6A, 0x90, 0xF3, 0x45, 0x7D, 0x46, 0x0E, 0xB4},
+ // CN=T\xC3\x9CRKTRUST Elektronik \xC4\xB0\xC5\x9Flem Hizmetleri, C=TR,
+ // L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E. (c)
+ // Kas\xC4\xB1m 2005
+ {0x56, 0xCE, 0x34, 0x7C, 0xC6, 0xDF, 0x4C, 0x35, 0x94, 0x3D, 0xFD, 0xEA,
+ 0xEE, 0x02, 0x3F, 0x97, 0x39, 0xA3, 0xF1, 0xCE, 0xDE, 0xEE, 0x0C, 0xD8,
+ 0x8D, 0xC2, 0x38, 0x6B, 0xC8, 0xA9, 0x1E, 0xAF},
+ // L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2
+ // Policy Validation Authority,
+ // CN=http://www.valicert.com//emailAddress=info@valicert.com
+ {0x58, 0xD0, 0x17, 0x27, 0x9C, 0xD4, 0xDC, 0x63, 0xAB, 0xDD, 0xB1, 0x96,
+ 0xA6, 0xC9, 0x90, 0x6C, 0x30, 0xC4, 0xE0, 0x87, 0x83, 0xEA, 0xE8, 0xC1,
+ 0x60, 0x99, 0x54, 0xD6, 0x93, 0x55, 0x59, 0x6B},
+ // C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Global Root CA
+ {0x59, 0x76, 0x90, 0x07, 0xF7, 0x68, 0x5D, 0x0F, 0xCD, 0x50, 0x87, 0x2F,
+ 0x9F, 0x95, 0xD5, 0x75, 0x5A, 0x5B, 0x2B, 0x45, 0x7D, 0x81, 0xF3, 0x69,
+ 0x2B, 0x61, 0x0A, 0x98, 0x67, 0x2F, 0x0E, 0x1B},
+ // C=CH, O=SwissSign AG, CN=SwissSign Platinum Root CA - G3
+ {0x59, 0xB3, 0x82, 0x9F, 0x1F, 0xF4, 0x43, 0x34, 0x49, 0x58, 0xFA, 0xE8,
+ 0xBF, 0xF6, 0x21, 0xB6, 0x84, 0xC8, 0x48, 0xCF, 0xBF, 0x7E, 0xAD, 0x6B,
+ 0x63, 0xA6, 0xCA, 0x50, 0xF2, 0x79, 0x4F, 0x89},
+ // C=SI, O=Halcom, CN=Halcom CA FO
+ {0x5A, 0x1B, 0x5D, 0x6B, 0xC6, 0x55, 0x23, 0xB4, 0x0A, 0x6D, 0xEF, 0xFA,
+ 0x45, 0xB4, 0x8E, 0x42, 0x88, 0xAE, 0x8D, 0xD8, 0x6D, 0xD7, 0x0A, 0x5B,
+ 0x85, 0x8D, 0x4A, 0x5A, 0xFF, 0xC9, 0x4F, 0x71},
+ // CN=AC1 RAIZ MTIN/serialNumber=S2819001E, OU=PRESTADOR DE SERVICIOS DE
+ // CERTIFICACION MTIN, OU=SUBDIRECCION GENERAL DE PROCESO DE DATOS,
+ // O=MINISTERIO DE TRABAJO E INMIGRACION, L=MADRID, C=ES
+ {0x5B, 0x1D, 0x9D, 0x24, 0xDE, 0x0A, 0xFE, 0xA8, 0xB3, 0x5B, 0xA0, 0x4A,
+ 0x1C, 0x3E, 0x25, 0xD0, 0x81, 0x2C, 0xDF, 0x7C, 0x46, 0x25, 0xDE, 0x0A,
+ 0x89, 0xAF, 0x9F, 0xE4, 0xBB, 0xD1, 0xBB, 0x15},
+ // C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority,
+ // CN=Certum Trusted Network CA
+ {0x5C, 0x58, 0x46, 0x8D, 0x55, 0xF5, 0x8E, 0x49, 0x7E, 0x74, 0x39, 0x82,
+ 0xD2, 0xB5, 0x00, 0x10, 0xB6, 0xD1, 0x65, 0x37, 0x4A, 0xCF, 0x83, 0xA7,
+ 0xD4, 0xA3, 0x2D, 0xB7, 0x68, 0xC4, 0x40, 0x8E},
+ // C=CN, O=China Financial Certification Authority, CN=CFCA EV ROOT
+ {0x5C, 0xC3, 0xD7, 0x8E, 0x4E, 0x1D, 0x5E, 0x45, 0x54, 0x7A, 0x04, 0xE6,
+ 0x87, 0x3E, 0x64, 0xF9, 0x0C, 0xF9, 0x53, 0x6D, 0x1C, 0xCC, 0x2E, 0xF8,
+ 0x00, 0xF3, 0x55, 0xC4, 0xC5, 0xFD, 0x70, 0xFD},
+ // C=US, O=IdenTrust, CN=IdenTrust Commercial Root CA 1
+ {0x5D, 0x56, 0x49, 0x9B, 0xE4, 0xD2, 0xE0, 0x8B, 0xCF, 0xCA, 0xD0, 0x8A,
+ 0x3E, 0x38, 0x72, 0x3D, 0x50, 0x50, 0x3B, 0xDE, 0x70, 0x69, 0x48, 0xE4,
+ 0x2F, 0x55, 0x60, 0x30, 0x19, 0xE5, 0x28, 0xAE},
+ // C=AT, L=Vienna, ST=Austria, O=ARGE DATEN - Austrian Society for Data
+ // Protection, OU=GLOBALTRUST Certification Service,
+ // CN=GLOBALTRUST/emailAddress=info@globaltrust.info
+ {0x5E, 0x35, 0x71, 0xF3, 0x3F, 0x45, 0xA7, 0xDF, 0x15, 0x37, 0xA6, 0x8B,
+ 0x5F, 0xFB, 0x9E, 0x03, 0x6A, 0xF9, 0xD2, 0xF5, 0xBC, 0x4C, 0x97, 0x17,
+ 0x13, 0x0D, 0xC4, 0x3D, 0x71, 0x75, 0xAA, 0xC7},
+ // C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use
+ // only, CN=GeoTrust Primary Certification Authority - G2
+ {0x5E, 0xDB, 0x7A, 0xC4, 0x3B, 0x82, 0xA0, 0x6A, 0x87, 0x61, 0xE8, 0xD7,
+ 0xBE, 0x49, 0x79, 0xEB, 0xF2, 0x61, 0x1F, 0x7D, 0xD7, 0x9B, 0xF9, 0x1C,
+ 0x1C, 0x6B, 0x56, 0x6A, 0x21, 0x9E, 0xD7, 0x66},
+ // C=US, O=Equifax Secure Inc., CN=Equifax Secure Global eBusiness CA-1
+ {0x5F, 0x0B, 0x62, 0xEA, 0xB5, 0xE3, 0x53, 0xEA, 0x65, 0x21, 0x65, 0x16,
+ 0x58, 0xFB, 0xB6, 0x53, 0x59, 0xF4, 0x43, 0x28, 0x0A, 0x4A, 0xFB, 0xD1,
+ 0x04, 0xD7, 0x7D, 0x10, 0xF9, 0xF0, 0x4C, 0x07},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA1
+ {0x5F, 0x96, 0x0E, 0xEB, 0xD7, 0x16, 0xDB, 0xCB, 0x4D, 0x8A, 0x78, 0xB9,
+ 0x96, 0xE6, 0x80, 0xEC, 0x25, 0x47, 0x44, 0x1E, 0x69, 0xB4, 0xE4, 0x4E,
+ 0x98, 0xA5, 0x95, 0x50, 0x2E, 0x28, 0xA0, 0x02},
+ // C=PT, O=MULTICERT - Servi\xC3\xA7os de Certifica\xC3\xA7\xC3\xA3o
+ // Electr\xC3\xB3nica S.A., CN=MULTICERT Root Certification Authority 01
+ {0x60, 0x4D, 0x32, 0xD0, 0x36, 0x89, 0x5A, 0xED, 0x3B, 0xFE, 0xFA, 0xEB,
+ 0x72, 0x7C, 0x00, 0x9E, 0xC0, 0xF2, 0xB3, 0xCD, 0xFA, 0x42, 0xA1, 0xC7,
+ 0x17, 0x30, 0xE6, 0xA7, 0x2C, 0x3B, 0xE9, 0xD4},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=GPKIRootCA
+ {0x60, 0x62, 0x23, 0xD9, 0xDB, 0x80, 0xDF, 0x39, 0x39, 0x60, 0x1E, 0x74,
+ 0xB7, 0xE8, 0x28, 0xE2, 0x80, 0x0C, 0xCE, 0x42, 0x73, 0xF7, 0x6F, 0x27,
+ 0x6A, 0xA6, 0x2D, 0xB0, 0xA8, 0xE3, 0xB6, 0xC1},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 1
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x61, 0x4F, 0xD1, 0x8D, 0xA1, 0x49, 0x05, 0x60, 0xCD, 0xAD, 0x11, 0x96,
+ 0xE2, 0x49, 0x2A, 0xB7, 0x06, 0x2E, 0xAB, 0x1A, 0x67, 0xB3, 0xA3, 0x0F,
+ 0x1D, 0x05, 0x85, 0xA7, 0xD6, 0xBA, 0x68, 0x24},
+ // C=US, O=VeriSign, Inc., OU=Class 4 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x61, 0xDC, 0x0C, 0x03, 0x91, 0x69, 0x4C, 0x65, 0x52, 0x00, 0xC1, 0x50,
+ 0x5E, 0xBC, 0xC9, 0xE4, 0xE2, 0x16, 0xBC, 0x31, 0xA5, 0xC5, 0x1A, 0x36,
+ 0x11, 0x28, 0x34, 0x23, 0xC1, 0xD8, 0x9E, 0x37},
+ // C=ES, O=FNMT, OU=FNMT Clase 2 CA
+ {0x62, 0xB9, 0x26, 0x72, 0x66, 0x21, 0x28, 0x32, 0xA8, 0xE2, 0x2D, 0xAB,
+ 0x93, 0x3D, 0x91, 0xC7, 0x01, 0x12, 0x74, 0xAC, 0xF7, 0x17, 0x03, 0xF9,
+ 0xCC, 0x97, 0x83, 0x37, 0x51, 0xA6, 0xE9, 0x4F},
+ // C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2
+ {0x62, 0xDD, 0x0B, 0xE9, 0xB9, 0xF5, 0x0A, 0x16, 0x3E, 0xA0, 0xF8, 0xE7,
+ 0x5C, 0x05, 0x3B, 0x1E, 0xCA, 0x57, 0xEA, 0x55, 0xC8, 0x68, 0x8F, 0x64,
+ 0x7C, 0x68, 0x81, 0xF2, 0xC8, 0x35, 0x7B, 0x95},
+ // C=US, O=Entrust.net, OU=www.entrust.net/CPS incorp. by ref. (limits
+ // liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Secure Server
+ // Certification Authority
+ {0x62, 0xF2, 0x40, 0x27, 0x8C, 0x56, 0x4C, 0x4D, 0xD8, 0xBF, 0x7D, 0x9D,
+ 0x4F, 0x6F, 0x36, 0x6E, 0xA8, 0x94, 0xD2, 0x2F, 0x5F, 0x34, 0xD9, 0x89,
+ 0xA9, 0x83, 0xAC, 0xEC, 0x2F, 0xFF, 0xED, 0x50},
+ // C=US, O=Digital Signature Trust Co., OU=DSTCA E1
+ {0x63, 0x04, 0x19, 0xAE, 0xC4, 0x78, 0xCB, 0xB4, 0xBB, 0x80, 0x83, 0xDE,
+ 0x9D, 0x9C, 0xF2, 0x79, 0x75, 0x2F, 0x03, 0x9D, 0xEF, 0x16, 0xE4, 0x64,
+ 0x71, 0xB6, 0x79, 0xCA, 0x93, 0x00, 0x2D, 0xB0},
+ // C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Root Certification Authority
+ {0x63, 0x2D, 0x80, 0xBB, 0x09, 0x6D, 0x20, 0x96, 0x77, 0xD1, 0x73, 0x4E,
+ 0x5B, 0x35, 0xEA, 0x9D, 0x30, 0x19, 0xB9, 0xC4, 0x4F, 0x8F, 0xCB, 0x26,
+ 0x40, 0xC8, 0x79, 0x03, 0x9A, 0xC9, 0x4E, 0xE8},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA - G2
+ {0x66, 0x8C, 0x83, 0x94, 0x7D, 0xA6, 0x3B, 0x72, 0x4B, 0xEC, 0xE1, 0x74,
+ 0x3C, 0x31, 0xA0, 0xE6, 0xAE, 0xD0, 0xDB, 0x8E, 0xC5, 0xB3, 0x1B, 0xE3,
+ 0x77, 0xBB, 0x78, 0x4F, 0x91, 0xB6, 0x71, 0x6F},
+ // O=eSign Australia, OU=Gatekeeper PKI, CN=Gatekeeper Root CA
+ {0x67, 0xEC, 0x20, 0x59, 0xFB, 0xF5, 0x2D, 0x2E, 0x6A, 0xB5, 0x1A, 0x5A,
+ 0x9B, 0x3F, 0xC2, 0xE1, 0xDC, 0xD6, 0x58, 0xA1, 0xEF, 0x3A, 0x8F, 0x31,
+ 0x10, 0x7B, 0xC9, 0x80, 0x28, 0xB4, 0x94, 0xA2},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ {0x68, 0x72, 0x58, 0x62, 0x19, 0xC3, 0x49, 0xD8, 0x5A, 0xAA, 0x45, 0x86,
+ 0xA1, 0x44, 0x51, 0xF2, 0x45, 0x1A, 0xE3, 0xB6, 0x09, 0x2D, 0xBB, 0x1E,
+ 0xFF, 0xB0, 0x14, 0x7C, 0x33, 0xBF, 0x0F, 0xD4},
+ // C=BR, O=ICP-Brasil, OU=Instituto Nacional de Tecnologia da Informacao -
+ // ITI, L=Brasilia, ST=DF, CN=Autoridade Certificadora Raiz Brasileira
+ {0x68, 0x7E, 0xA8, 0x90, 0x89, 0x30, 0x9D, 0x2C, 0xFE, 0x10, 0x7D, 0xB0,
+ 0x59, 0xFB, 0x10, 0xD6, 0x76, 0xF4, 0x5D, 0x32, 0x83, 0xAE, 0xE0, 0x56,
+ 0x90, 0x3E, 0xEA, 0x0C, 0xF3, 0xC1, 0x88, 0xF8},
+ // C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust
+ // External CA Root
+ {0x68, 0x7F, 0xA4, 0x51, 0x38, 0x22, 0x78, 0xFF, 0xF0, 0xC8, 0xB1, 0x1F,
+ 0x8D, 0x43, 0xD5, 0x76, 0x67, 0x1C, 0x6E, 0xB2, 0xBC, 0xEA, 0xB4, 0x13,
+ 0xFB, 0x83, 0xD9, 0x65, 0xD0, 0x6D, 0x2F, 0xF2},
+ // C=US, O=Verizon Business, OU=OmniRoot, CN=Verizon Global Root CA
+ {0x68, 0xAD, 0x50, 0x90, 0x9B, 0x04, 0x36, 0x3C, 0x60, 0x5E, 0xF1, 0x35,
+ 0x81, 0xA9, 0x39, 0xFF, 0x2C, 0x96, 0x37, 0x2E, 0x3F, 0x12, 0x32, 0x5B,
+ 0x0A, 0x68, 0x61, 0xE1, 0xD5, 0x9F, 0x66, 0x03},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2007 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary
+ // Certification Authority - G4
+ {0x69, 0xDD, 0xD7, 0xEA, 0x90, 0xBB, 0x57, 0xC9, 0x3E, 0x13, 0x5D, 0xC8,
+ 0x5E, 0xA6, 0xFC, 0xD5, 0x48, 0x0B, 0x60, 0x32, 0x39, 0xBD, 0xC4, 0x54,
+ 0xFC, 0x75, 0x8B, 0x2A, 0x26, 0xCF, 0x7F, 0x79},
+ // C=US, O=VISA, OU=Visa International Service Association, CN=Visa
+ // eCommerce Root
+ {0x69, 0xFA, 0xC9, 0xBD, 0x55, 0xFB, 0x0A, 0xC7, 0x8D, 0x53, 0xBB, 0xEE,
+ 0x5C, 0xF1, 0xD5, 0x97, 0x98, 0x9F, 0xD0, 0xAA, 0xAB, 0x20, 0xA2, 0x51,
+ 0x51, 0xBD, 0xF1, 0x73, 0x3E, 0xE7, 0xD1, 0x22},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Qual-03, CN=A-Trust-Qual-03
+ {0x6B, 0xAF, 0x50, 0xAE, 0x34, 0x67, 0xEF, 0xF3, 0xC3, 0x5F, 0xEF, 0xDC,
+ 0x76, 0xA0, 0x2A, 0x97, 0xFA, 0xB6, 0x26, 0x77, 0x23, 0xED, 0xA9, 0x1E,
+ 0x99, 0xF1, 0xB3, 0xDC, 0x2B, 0x28, 0xF8, 0x2E},
+ // C=HU, L=Budapest, O=NetLock Kft.,
+ // OU=Tan\xC3\xBAs\xC3\xADtv\xC3\xA1nykiad\xC3\xB3k (Certification
+ // Services), CN=NetLock Arany (Class Gold)
+ // F\xC5\x91tan\xC3\xBAs\xC3\xADtv\xC3\xA1ny
+ {0x6C, 0x61, 0xDA, 0xC3, 0xA2, 0xDE, 0xF0, 0x31, 0x50, 0x6B, 0xE0, 0x36,
+ 0xD2, 0xA6, 0xFE, 0x40, 0x19, 0x94, 0xFB, 0xD1, 0x3D, 0xF9, 0xC8, 0xD4,
+ 0x66, 0x59, 0x92, 0x74, 0xC4, 0x46, 0xEC, 0x98},
+ // C=FR, O=Certplus, CN=Certplus Root CA G2
+ {0x6C, 0xC0, 0x50, 0x41, 0xE6, 0x44, 0x5E, 0x74, 0x69, 0x6C, 0x4C, 0xFB,
+ 0xC9, 0xF8, 0x0F, 0x54, 0x3B, 0x7E, 0xAB, 0xBB, 0x44, 0xB4, 0xCE, 0x6F,
+ 0x78, 0x7C, 0x6A, 0x99, 0x71, 0xC4, 0x2F, 0x17},
+ // C=AU, O=GOV, OU=DoD, OU=PKI, OU=CAs, CN=ADOCA02
+ {0x6C, 0xCF, 0xD3, 0x02, 0xFC, 0x44, 0xBF, 0x45, 0x99, 0x32, 0x9B, 0x97,
+ 0x50, 0x87, 0x8E, 0xA4, 0x4E, 0x7E, 0x85, 0x66, 0x56, 0x4B, 0xCB, 0xD5,
+ 0x86, 0x16, 0x97, 0x62, 0xDD, 0x10, 0xC7, 0x4E},
+ // O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits
+ // liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification
+ // Authority (2048)
+ {0x6D, 0xC4, 0x71, 0x72, 0xE0, 0x1C, 0xBC, 0xB0, 0xBF, 0x62, 0x58, 0x0D,
+ 0x89, 0x5F, 0xE2, 0xB8, 0xAC, 0x9A, 0xD4, 0xF8, 0x73, 0x80, 0x1E, 0x0C,
+ 0x10, 0xB9, 0xC8, 0x37, 0xD2, 0x1E, 0xB1, 0x77},
+ // C=ES, ST=Madrid, L=Madrid, O=IPS Certification Authority s.l. ipsCA,
+ // OU=ipsCA, CN=ipsCA Global CA Root/emailAddress=global01@ipsca.com
+ {0x6D, 0xEA, 0x86, 0xA1, 0xE6, 0x66, 0x20, 0xA0, 0x40, 0xC3, 0xC5, 0x94,
+ 0x3C, 0xB2, 0x15, 0xD2, 0xCA, 0x87, 0xFB, 0x6A, 0xC0, 0x9B, 0x59, 0x70,
+ 0x7E, 0x29, 0xD2, 0xFA, 0xCB, 0xD6, 0x6B, 0x4E},
+ // C=us, O=U.S. Government, OU=FBCA, CN=Common Policy
+ {0x6E, 0x5E, 0x93, 0xAE, 0x86, 0x7F, 0xD3, 0xE3, 0xE7, 0x83, 0x04, 0xE0,
+ 0x54, 0xD1, 0xA6, 0xAE, 0xAE, 0xD0, 0x29, 0x5D, 0x58, 0xC0, 0xE3, 0xFC,
+ 0x4C, 0x9F, 0xFE, 0x31, 0x0A, 0x34, 0x88, 0xCC},
+ // C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network,
+ // OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware
+ {0x6E, 0xA5, 0x47, 0x41, 0xD0, 0x04, 0x66, 0x7E, 0xED, 0x1B, 0x48, 0x16,
+ 0x63, 0x4A, 0xA3, 0xA7, 0x9E, 0x6E, 0x4B, 0x96, 0x95, 0x0F, 0x82, 0x79,
+ 0xDA, 0xFC, 0x8D, 0x9B, 0xD8, 0x81, 0x21, 0x37},
+ // C=CH, O=The Federal Authorities of the Swiss Confederation, OU=Services,
+ // OU=Certification Authorities, CN=Swiss Government Root CA I
+ {0x6E, 0xC6, 0x61, 0x4E, 0x9A, 0x8E, 0xFD, 0x47, 0xD6, 0x31, 0x8F, 0xFD,
+ 0xFD, 0x0B, 0xF6, 0x5B, 0x49, 0x3A, 0x14, 0x1F, 0x77, 0xC3, 0x8D, 0x0B,
+ 0x31, 0x9B, 0xE1, 0xBB, 0xBC, 0x05, 0x3D, 0xD2},
+ // C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 1
+ {0x6F, 0xDB, 0x3F, 0x76, 0xC8, 0xB8, 0x01, 0xA7, 0x53, 0x38, 0xD8, 0xA5,
+ 0x0A, 0x7C, 0x02, 0x87, 0x9F, 0x61, 0x98, 0xB5, 0x7E, 0x59, 0x4D, 0x31,
+ 0x8D, 0x38, 0x32, 0x90, 0x0F, 0xED, 0xCD, 0x79},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Premium
+ {0x70, 0xA7, 0x3F, 0x7F, 0x37, 0x6B, 0x60, 0x07, 0x42, 0x48, 0x90, 0x45,
+ 0x34, 0xB1, 0x14, 0x82, 0xD5, 0xBF, 0x0E, 0x69, 0x8E, 0xCC, 0x49, 0x8D,
+ 0xF5, 0x25, 0x77, 0xEB, 0xF2, 0xE9, 0x3B, 0x9A},
+ // C=TW, O=Government Root Certification Authority
+ {0x70, 0xB9, 0x22, 0xBF, 0xDA, 0x0E, 0x3F, 0x4A, 0x34, 0x2E, 0x4E, 0xE2,
+ 0x2D, 0x57, 0x9A, 0xE5, 0x98, 0xD0, 0x71, 0xCC, 0x5E, 0xC9, 0xC3, 0x0F,
+ 0x12, 0x36, 0x80, 0x34, 0x03, 0x88, 0xAE, 0xA5},
+ // C=PL, O=Telekomunikacja Polska S.A., OU=Signet Certification Authority,
+ // CN=Signet Root CA
+ {0x72, 0x86, 0xCE, 0x24, 0x9F, 0xE9, 0xE3, 0x2B, 0xD4, 0x75, 0x22, 0x57,
+ 0xC1, 0x7C, 0xD8, 0xF6, 0x99, 0x1A, 0x9C, 0x1E, 0x6F, 0x1A, 0x3C, 0xC7,
+ 0x33, 0x04, 0xED, 0x02, 0x3E, 0x6A, 0xE4, 0xEB},
+ // C=NL, O=PTT Post, OU=KeyMail, CN=PTT Post Root CA/mail=ca@ptt-post.nl
+ {0x73, 0x0B, 0x61, 0x9E, 0xAA, 0x75, 0x98, 0x63, 0xC6, 0x53, 0x60, 0xB7,
+ 0x41, 0x2E, 0x14, 0x57, 0xEC, 0xA9, 0x68, 0x44, 0xEF, 0x2F, 0x16, 0xD9,
+ 0x1F, 0xCF, 0x2E, 0xFE, 0x46, 0xA6, 0x47, 0xE9},
+ // C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=E-GUVEN Kok Elektronik
+ // Sertifika Hizmet Saglayicisi S2
+ {0x73, 0x2F, 0xF5, 0xBC, 0x47, 0x3C, 0x33, 0xEF, 0xAA, 0xD9, 0xB1, 0x87,
+ 0xFB, 0x45, 0x9A, 0x73, 0x2F, 0xFB, 0xEE, 0xA5, 0x9D, 0xF0, 0xFD, 0xFB,
+ 0x8E, 0x2F, 0xB5, 0xDE, 0xF4, 0x03, 0x2A, 0xFE},
+ // C=ES, O=DIRECCION GENERAL DE LA POLICIA, OU=DNIE, CN=AC RAIZ DNIE
+ {0x73, 0x97, 0x10, 0xC5, 0x24, 0x5E, 0x33, 0xEC, 0x8A, 0x24, 0x3A, 0x1B,
+ 0x20, 0x04, 0x8F, 0xC9, 0xD5, 0xF4, 0x52, 0x85, 0x99, 0x21, 0x38, 0x45,
+ 0xC1, 0x64, 0xD0, 0x04, 0xB8, 0xB6, 0x67, 0xF9},
+ // C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by
+ // reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification
+ // Authority
+ {0x73, 0xC1, 0x76, 0x43, 0x4F, 0x1B, 0xC6, 0xD5, 0xAD, 0xF4, 0x5B, 0x0E,
+ 0x76, 0xE7, 0x27, 0x28, 0x7C, 0x8D, 0xE5, 0x76, 0x16, 0xC1, 0xE6, 0xE6,
+ 0x14, 0x1A, 0x2B, 0x2C, 0xBC, 0x7D, 0x8E, 0x4C},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV
+ // Root CA
+ {0x74, 0x31, 0xE5, 0xF4, 0xC3, 0xC1, 0xCE, 0x46, 0x90, 0x77, 0x4F, 0x0B,
+ 0x61, 0xE0, 0x54, 0x40, 0x88, 0x3B, 0xA9, 0xA0, 0x1E, 0xD0, 0x0B, 0xA6,
+ 0xAB, 0xD7, 0x80, 0x6E, 0xD3, 0xB1, 0x18, 0xCF},
+ // C=PA, ST=Panama, L=Panama City, O=TrustCor Systems S. de R.L.,
+ // OU=TrustCor Certificate Authority, CN=TrustCor ECA-1
+ {0x74, 0x4B, 0x11, 0x47, 0xB4, 0xA9, 0xA6, 0x9C, 0x32, 0x78, 0x5E, 0x9E,
+ 0x37, 0xC3, 0x32, 0x32, 0x41, 0xEF, 0x29, 0xF6, 0x3E, 0x76, 0xF1, 0x60,
+ 0x3D, 0x67, 0x61, 0xA7, 0x83, 0xD8, 0xA0, 0xFE},
+ // C=si, O=state-institutions, OU=sigov-ca
+ {0x74, 0xCB, 0x3A, 0x4E, 0xA7, 0x91, 0xAF, 0xB0, 0xA2, 0xD1, 0xA0, 0xB1,
+ 0x33, 0x01, 0xB3, 0xBE, 0xE0, 0xE5, 0x0A, 0xD5, 0xC7, 0x9A, 0x1A, 0x6F,
+ 0x2C, 0x66, 0x3E, 0x6F, 0x4E, 0xE7, 0xA4, 0x84},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Qual-02, CN=A-Trust-Qual-02
+ {0x75, 0xC9, 0xD4, 0x36, 0x1C, 0xB9, 0x6E, 0x99, 0x3A, 0xBD, 0x96, 0x20,
+ 0xCF, 0x04, 0x3B, 0xE9, 0x40, 0x7A, 0x46, 0x33, 0xF2, 0x02, 0xF0, 0xF4,
+ 0xC0, 0xE1, 0x78, 0x51, 0xCC, 0x60, 0x89, 0xCD},
+ // C=TW, O=Government Root Certification Authority
+ {0x76, 0x00, 0x29, 0x5E, 0xEF, 0xE8, 0x5B, 0x9E, 0x1F, 0xD6, 0x24, 0xDB,
+ 0x76, 0x06, 0x2A, 0xAA, 0xAE, 0x59, 0x81, 0x8A, 0x54, 0xD2, 0x77, 0x4C,
+ 0xD4, 0xC0, 0xB2, 0xC0, 0x11, 0x31, 0xE1, 0xB3},
+ // C=US, O=Digital Signature Trust, OU=DST ACES, CN=DST ACES CA X6
+ {0x76, 0x7C, 0x95, 0x5A, 0x76, 0x41, 0x2C, 0x89, 0xAF, 0x68, 0x8E, 0x90,
+ 0xA1, 0xC7, 0x0F, 0x55, 0x6C, 0xFD, 0x6B, 0x60, 0x25, 0xDB, 0xEA, 0x10,
+ 0x41, 0x6D, 0x7E, 0xB6, 0x83, 0x1F, 0x8C, 0x40},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 3
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x76, 0xEF, 0x47, 0x62, 0xE5, 0x73, 0x20, 0x60, 0x06, 0xCB, 0xC3, 0x38,
+ 0xB1, 0x7C, 0xA4, 0xBC, 0x20, 0x05, 0x74, 0xA1, 0x19, 0x28, 0xD9, 0x0C,
+ 0x3E, 0xF3, 0x1C, 0x5E, 0x80, 0x3E, 0x6C, 0x6F},
+ // L=Alvaro Obregon, ST=Distrito Federal,
+ // C=MX/postalCode=01030/street=Insurgentes Sur 1940, CN=Autoridad
+ // Certificadora Raiz de la Secretaria de Economia, OU=Direccion General de
+ // Normatividad Mercantil, O=Secretaria de
+ // Economia/emailAddress=acrse@economia.gob.mx
+ {0x77, 0xE0, 0x4C, 0x9A, 0x75, 0x1C, 0x73, 0xF2, 0x3E, 0x2A, 0x13, 0x36,
+ 0x11, 0x2E, 0xC8, 0xD5, 0x15, 0x3D, 0x38, 0x2A, 0x15, 0x2F, 0xED, 0x89,
+ 0xD7, 0x53, 0x2C, 0x31, 0x02, 0x77, 0x1F, 0x3C},
+ // C=SG, O=Netrust Certificate Authority 1, OU=Netrust CA1
+ {0x78, 0x1D, 0x64, 0xDF, 0xA7, 0x7B, 0x00, 0xF2, 0xC0, 0x06, 0x70, 0x0B,
+ 0x1F, 0xDA, 0x86, 0xBF, 0x68, 0xB8, 0x65, 0xA6, 0x03, 0xC7, 0xA6, 0x56,
+ 0xF9, 0x2E, 0x90, 0xC0, 0x42, 0xCA, 0x28, 0x73},
+ // C=FI, O=Sonera, CN=Sonera Class2 CA
+ {0x79, 0x08, 0xB4, 0x03, 0x14, 0xC1, 0x38, 0x10, 0x0B, 0x51, 0x8D, 0x07,
+ 0x35, 0x80, 0x7F, 0xFB, 0xFC, 0xF8, 0x51, 0x8A, 0x00, 0x95, 0x33, 0x71,
+ 0x05, 0xBA, 0x38, 0x6B, 0x15, 0x3D, 0xD9, 0x27},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-nQual-03, CN=A-Trust-nQual-03
+ {0x79, 0x3C, 0xBF, 0x45, 0x59, 0xB9, 0xFD, 0xE3, 0x8A, 0xB2, 0x2D, 0xF1,
+ 0x68, 0x69, 0xF6, 0x98, 0x81, 0xAE, 0x14, 0xC4, 0xB0, 0x13, 0x9A, 0xC7,
+ 0x88, 0xA7, 0x8A, 0x1A, 0xFC, 0xCA, 0x02, 0xFB},
+ // C=ZA, ST=Western Cape, L=Somerset West, O=South African Post Office
+ // Limited, OU=SAPO Trust Centre, CN=SAPO Class 3 Root
+ // CA/emailAddress=pkiadmin@trustcentre.co.za
+ {0x79, 0x6B, 0x93, 0xD0, 0xA3, 0xBA, 0x22, 0xE1, 0x91, 0xF2, 0x49, 0x5F,
+ 0x15, 0x0A, 0x5F, 0x9B, 0xFE, 0xE2, 0xCE, 0x15, 0x03, 0xDA, 0x21, 0x7B,
+ 0x74, 0xB8, 0xA9, 0x84, 0x68, 0x51, 0x10, 0xF1},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x79, 0x7E, 0x51, 0xF8, 0x83, 0xE8, 0x55, 0xD0, 0x21, 0xE5, 0xC7, 0x70,
+ 0x56, 0x66, 0x92, 0x99, 0x94, 0x07, 0x89, 0x55, 0x93, 0x23, 0x5D, 0xEF,
+ 0x52, 0xA0, 0x11, 0xF7, 0x16, 0xF8, 0xB6, 0xBF},
+ // C=US, ST=MN, L=Minneapolis, O=Open Access Technology International Inc,
+ // CN=OATI WebCARES Root CA
+ {0x7A, 0x77, 0xC6, 0xC6, 0x1E, 0xEE, 0xB9, 0xAA, 0x65, 0xC4, 0xEA, 0x41,
+ 0x0D, 0x65, 0xD8, 0x95, 0xB2, 0x6A, 0x81, 0x12, 0x32, 0x83, 0x00, 0x9D,
+ 0xB1, 0x04, 0xB4, 0x8D, 0xE8, 0x0B, 0x24, 0x79},
+ // C=CH, O=SwissSign AG, CN=SwissSign Gold Root CA - G3
+ {0x7A, 0xF6, 0xEA, 0x9F, 0x75, 0x3A, 0x1E, 0x70, 0x9B, 0xD6, 0x4D, 0x0B,
+ 0xEB, 0x86, 0x7C, 0x11, 0xE8, 0xC2, 0x95, 0xA5, 0x6E, 0x24, 0xA6, 0xE0,
+ 0x47, 0x14, 0x59, 0xDC, 0xCD, 0xAA, 0x15, 0x58},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co., OU=DSTCA
+ // X1, CN=DST RootCA X1/emailAddress=ca@digsigtrust.com
+ {0x7B, 0x1A, 0x15, 0xD7, 0xE5, 0xE1, 0x30, 0xC5, 0x79, 0xE6, 0x8F, 0xCA,
+ 0x18, 0x92, 0x57, 0xF8, 0x37, 0xB5, 0xC1, 0x88, 0xF1, 0xB2, 0xB2, 0xA7,
+ 0x91, 0xE9, 0x67, 0xCC, 0x88, 0xCC, 0x65, 0x28},
+ // C=AT, O=A-Trust, OU=A-Trust-nQual-01, CN=A-Trust-nQual-01
+ {0x7B, 0x1F, 0x8D, 0x8E, 0xFF, 0x5D, 0x73, 0x49, 0xFE, 0xDB, 0x7E, 0xAE,
+ 0x89, 0xC2, 0x9A, 0xAC, 0xC4, 0x17, 0x04, 0xF1, 0x50, 0x3A, 0xE3, 0xC8,
+ 0xC2, 0xEB, 0xA1, 0x02, 0x25, 0xD0, 0xF5, 0x68},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G2
+ {0x7D, 0x05, 0xEB, 0xB6, 0x82, 0x33, 0x9F, 0x8C, 0x94, 0x51, 0xEE, 0x09,
+ 0x4E, 0xEB, 0xFE, 0xFA, 0x79, 0x53, 0xA1, 0x14, 0xED, 0xB2, 0xF4, 0x49,
+ 0x49, 0x45, 0x2F, 0xAB, 0x7D, 0x2F, 0xC1, 0x85},
+ // C=ES, O=Colegio de Registradores de la Propiedad y Mercantiles de
+ // Espa\xC3\xB1a, OU=Certificado Propio, CN=Registradores de Espa\xC3\xB1a -
+ // CA Ra\xC3\xADz
+ {0x7D, 0x2B, 0xF3, 0x48, 0x9E, 0xBC, 0x9A, 0xD3, 0x44, 0x8B, 0x8B, 0x08,
+ 0x27, 0x71, 0x5A, 0x3C, 0xBF, 0xE3, 0xD5, 0x23, 0xE3, 0xB5, 0x6A, 0x9B,
+ 0x5F, 0xC1, 0xD2, 0xA2, 0xDA, 0x2F, 0x20, 0xFE},
+ // C=US, O=America Online Inc., CN=America Online Root Certification
+ // Authority 2
+ {0x7D, 0x3B, 0x46, 0x5A, 0x60, 0x14, 0xE5, 0x26, 0xC0, 0xAF, 0xFC, 0xEE,
+ 0x21, 0x27, 0xD2, 0x31, 0x17, 0x27, 0xAD, 0x81, 0x1C, 0x26, 0x84, 0x2D,
+ 0x00, 0x6A, 0xF3, 0x73, 0x06, 0xCC, 0x80, 0xBD},
+ // C=FR, O=Certplus, CN=Class 1 Primary CA
+ {0x7D, 0x8C, 0xE8, 0x22, 0x22, 0x2B, 0x90, 0xC0, 0xB1, 0x43, 0x42, 0xC7,
+ 0xA8, 0x14, 0x5D, 0x1F, 0x24, 0x35, 0x1F, 0x4D, 0x1A, 0x1F, 0xE0, 0xED,
+ 0xFD, 0x31, 0x2E, 0xE7, 0x3F, 0xB0, 0x01, 0x49},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G3
+ {0x7E, 0x37, 0xCB, 0x8B, 0x4C, 0x47, 0x09, 0x0C, 0xAB, 0x36, 0x55, 0x1B,
+ 0xA6, 0xF4, 0x5D, 0xB8, 0x40, 0x68, 0x0F, 0xBA, 0x16, 0x6A, 0x95, 0x2D,
+ 0xB1, 0x00, 0x71, 0x7F, 0x43, 0x05, 0x3F, 0xC2},
+ // C=HU, ST=Hungary, L=Budapest, O=NetLock Halozatbiztonsagi Kft.,
+ // OU=Tanusitvanykiadok, CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado
+ {0x7F, 0x12, 0xCD, 0x5F, 0x7E, 0x5E, 0x29, 0x0E, 0xC7, 0xD8, 0x51, 0x79,
+ 0xD5, 0xB7, 0x2C, 0x20, 0xA5, 0xBE, 0x75, 0x08, 0xFF, 0xDB, 0x5B, 0xF8,
+ 0x1A, 0xB9, 0x68, 0x4A, 0x7F, 0xC9, 0xF6, 0x67},
+ // C=ES, O=Agencia Notarial de Certificacion S.L. Unipersonal - CIF
+ // B83395988, CN=ANCERT Certificados CGN
+ {0x81, 0x77, 0xD1, 0xA8, 0x2B, 0xA5, 0x01, 0xAF, 0xDD, 0x1E, 0x94, 0x83,
+ 0xAD, 0x7D, 0xA9, 0x12, 0xEE, 0x1E, 0x9F, 0xCB, 0x2A, 0x5A, 0x06, 0x1F,
+ 0xA3, 0xC4, 0x79, 0xFA, 0x80, 0x4C, 0xE6, 0xBA},
+ // C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=E-GUVEN Kok Elektronik
+ // Sertifika Hizmet Saglayicisi S3
+ {0x82, 0xD4, 0x2D, 0xB3, 0xD6, 0x57, 0xF1, 0x94, 0x4E, 0x65, 0xC1, 0x92,
+ 0xB1, 0xDD, 0x58, 0xDB, 0x8D, 0xF8, 0x41, 0x7B, 0x89, 0x16, 0x5B, 0x04,
+ 0x5F, 0x5C, 0x6A, 0x70, 0xC5, 0xF8, 0x93, 0x9E},
+ // O=Cisco Systems, CN=Cisco Root CA 2048
+ {0x83, 0x27, 0xBC, 0x8C, 0x9D, 0x69, 0x94, 0x7B, 0x3D, 0xE3, 0xC2, 0x75,
+ 0x11, 0x53, 0x72, 0x67, 0xF5, 0x9C, 0x21, 0xB9, 0xFA, 0x7B, 0x61, 0x3F,
+ 0xAF, 0xBC, 0xCD, 0x53, 0xB7, 0x02, 0x40, 0x00},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ // - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign
+ // Trust Network
+ {0x83, 0xCE, 0x3C, 0x12, 0x29, 0x68, 0x8A, 0x59, 0x3D, 0x48, 0x5F, 0x81,
+ 0x97, 0x3C, 0x0F, 0x91, 0x95, 0x43, 0x1E, 0xDA, 0x37, 0xCC, 0x5E, 0x36,
+ 0x43, 0x0E, 0x79, 0xC7, 0xA8, 0x88, 0x63, 0x8B},
+ // C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft
+ // Root Certificate Authority 2011
+ {0x84, 0x7D, 0xF6, 0xA7, 0x84, 0x97, 0x94, 0x3F, 0x27, 0xFC, 0x72, 0xEB,
+ 0x93, 0xF9, 0xA6, 0x37, 0x32, 0x0A, 0x02, 0xB5, 0x61, 0xD0, 0xA9, 0x1B,
+ 0x09, 0xE8, 0x7A, 0x78, 0x07, 0xED, 0x7C, 0x61},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2
+ {0x85, 0xA0, 0xDD, 0x7D, 0xD7, 0x20, 0xAD, 0xB7, 0xFF, 0x05, 0xF8, 0x3D,
+ 0x54, 0x2B, 0x20, 0x9D, 0xC7, 0xFF, 0x45, 0x28, 0xF7, 0xD6, 0x77, 0xB1,
+ 0x83, 0x89, 0xFE, 0xA5, 0xE5, 0xC4, 0x9E, 0x86},
+ // C=BR, O=Certisign Certificadora Digital Ltda., OU=Certisign Autoridade
+ // Certificadora AC1S
+ {0x85, 0xE0, 0xDF, 0xAE, 0x3E, 0x55, 0xA8, 0x43, 0x19, 0x5F, 0x8B, 0x08,
+ 0xC8, 0x34, 0x90, 0x50, 0xE4, 0x68, 0x93, 0x72, 0xF6, 0xE1, 0x33, 0xAD,
+ 0x0D, 0x19, 0x9A, 0xF9, 0x6E, 0x95, 0xCC, 0x08},
+ // C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network,
+ // OU=http://www.usertrust.com, CN=UTN - DATACorp SGC
+ {0x85, 0xFB, 0x2F, 0x91, 0xDD, 0x12, 0x27, 0x5A, 0x01, 0x45, 0xB6, 0x36,
+ 0x53, 0x4F, 0x84, 0x02, 0x4A, 0xD6, 0x8B, 0x69, 0xB8, 0xEE, 0x88, 0x68,
+ 0x4F, 0xF7, 0x11, 0x37, 0x58, 0x05, 0xB3, 0x48},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-nQual-03, CN=A-Trust-nQual-03
+ {0x86, 0x88, 0xE5, 0x8F, 0x4C, 0x7A, 0x94, 0x5F, 0xAD, 0xCE, 0x7F, 0x62,
+ 0xBF, 0xEF, 0x52, 0x1B, 0x82, 0xDA, 0x7D, 0xC3, 0x8B, 0xFD, 0xB0, 0x16,
+ 0x34, 0x78, 0xA5, 0xFE, 0x42, 0xE5, 0x78, 0x70},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Server
+ // CA/emailAddress=server-certs@thawte.com
+ {0x87, 0xC6, 0x78, 0xBF, 0xB8, 0xB2, 0x5F, 0x38, 0xF7, 0xE9, 0x7B, 0x33,
+ 0x69, 0x56, 0xBB, 0xCF, 0x14, 0x4B, 0xBA, 0xCA, 0xA5, 0x36, 0x47, 0xE6,
+ 0x1A, 0x23, 0x25, 0xBC, 0x10, 0x55, 0x31, 0x6B},
+ // C=ES, O=Agencia Catalana de Certificacio (NIF Q-0801176-I), OU=Serveis
+ // Publics de Certificacio, OU=Vegeu https://www.catcert.net/verarrel (c)03,
+ // OU=Jerarquia Entitats de Certificacio Catalanes, CN=EC-ACC
+ {0x88, 0x49, 0x7F, 0x01, 0x60, 0x2F, 0x31, 0x54, 0x24, 0x6A, 0xE2, 0x8C,
+ 0x4D, 0x5A, 0xEF, 0x10, 0xF1, 0xD8, 0x7E, 0xBB, 0x76, 0x62, 0x6F, 0x4A,
+ 0xE0, 0xB7, 0xF9, 0x5B, 0xA7, 0x96, 0x87, 0x99},
+ // DC=com, DC=microsoft, CN=Microsoft Root Certificate Authority
+ {0x88, 0x5D, 0xE6, 0x4C, 0x34, 0x0E, 0x3E, 0xA7, 0x06, 0x58, 0xF0, 0x1E,
+ 0x11, 0x45, 0xF9, 0x57, 0xFC, 0xDA, 0x27, 0xAA, 0xBE, 0xEA, 0x1A, 0xB9,
+ 0xFA, 0xA9, 0xFD, 0xB0, 0x10, 0x2D, 0x40, 0x77},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 G3
+ {0x88, 0xEF, 0x81, 0xDE, 0x20, 0x2E, 0xB0, 0x18, 0x45, 0x2E, 0x43, 0xF8,
+ 0x64, 0x72, 0x5C, 0xEA, 0x5F, 0xBD, 0x1F, 0xC2, 0xD9, 0xD2, 0x05, 0x73,
+ 0x07, 0x09, 0xC5, 0xD8, 0xB8, 0x69, 0x0F, 0x46},
+ // C=SI, O=ACNLB
+ {0x89, 0x4C, 0xE6, 0xDD, 0xB0, 0x12, 0xCB, 0x3F, 0x73, 0x69, 0x54, 0x66,
+ 0x8D, 0xE6, 0x3F, 0x43, 0x60, 0x80, 0xE9, 0x5F, 0x17, 0xB7, 0xA8, 0x1B,
+ 0xD9, 0x24, 0xEB, 0x21, 0xBE, 0xE9, 0xE4, 0x40},
+ // C=US, O=U.S. Government, OU=FPKI, CN=Federal Common Policy CA
+ {0x89, 0x4E, 0xBC, 0x0B, 0x23, 0xDA, 0x2A, 0x50, 0xC0, 0x18, 0x6B, 0x7F,
+ 0x8F, 0x25, 0xEF, 0x1F, 0x6B, 0x29, 0x35, 0xAF, 0x32, 0xA9, 0x45, 0x84,
+ 0xEF, 0x80, 0xAA, 0xF8, 0x77, 0xA3, 0xA0, 0x6E},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 1 G3
+ {0x8A, 0x86, 0x6F, 0xD1, 0xB2, 0x76, 0xB5, 0x7E, 0x57, 0x8E, 0x92, 0x1C,
+ 0x65, 0x82, 0x8A, 0x2B, 0xED, 0x58, 0xE9, 0xF2, 0xF2, 0x88, 0x05, 0x41,
+ 0x34, 0xB7, 0xF1, 0xF4, 0xBF, 0xC9, 0xCC, 0x74},
+ // C=SI, O=Halcom, CN=Halcom Root CA
+ {0x8B, 0x3F, 0xDB, 0x15, 0x1A, 0xF7, 0x59, 0xC5, 0x66, 0x14, 0x3E, 0x07,
+ 0xC9, 0x50, 0xED, 0xE4, 0xF9, 0xE8, 0xC7, 0xCF, 0x80, 0x84, 0x53, 0xD3,
+ 0x3B, 0xCB, 0x78, 0xE5, 0x2A, 0x40, 0x0A, 0xF9},
+ // C=CN, O=WoSign CA Limited, CN=CA WoSign ECC Root
+ {0x8B, 0x45, 0xDA, 0x1C, 0x06, 0xF7, 0x91, 0xEB, 0x0C, 0xAB, 0xF2, 0x6B,
+ 0xE5, 0x88, 0xF5, 0xFB, 0x23, 0x16, 0x5C, 0x2E, 0x61, 0x4B, 0xF8, 0x85,
+ 0x56, 0x2D, 0x0D, 0xCE, 0x50, 0xB2, 0x9B, 0x02},
+ // C=ES, O=Generalitat Valenciana, OU=PKIGVA, CN=Root CA Generalitat
+ // Valenciana
+ {0x8C, 0x4E, 0xDF, 0xD0, 0x43, 0x48, 0xF3, 0x22, 0x96, 0x9E, 0x7E, 0x29,
+ 0xA4, 0xCD, 0x4D, 0xCA, 0x00, 0x46, 0x55, 0x06, 0x1C, 0x16, 0xE1, 0xB0,
+ 0x76, 0x42, 0x2E, 0xF3, 0x42, 0xAD, 0x63, 0x0E},
+ // C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006
+ // thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
+ {0x8D, 0x72, 0x2F, 0x81, 0xA9, 0xC1, 0x13, 0xC0, 0x79, 0x1D, 0xF1, 0x36,
+ 0xA2, 0x96, 0x6D, 0xB2, 0x6C, 0x95, 0x0A, 0x97, 0x1D, 0xB4, 0x6B, 0x41,
+ 0x99, 0xF4, 0xEA, 0x54, 0xB7, 0x8B, 0xFB, 0x9F},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 2 CA 2007
+ {0x8D, 0xA7, 0x5F, 0x13, 0x27, 0x21, 0x7C, 0x88, 0x06, 0x0F, 0xD2, 0x52,
+ 0x9E, 0xFF, 0x28, 0x16, 0xE5, 0x0B, 0x0C, 0x74, 0x54, 0x1E, 0xA4, 0xEA,
+ 0x3D, 0xFC, 0xEE, 0x66, 0xA7, 0x1E, 0xFE, 0x09},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 4
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x8D, 0xBB, 0x5A, 0x7C, 0x06, 0xC2, 0x0E, 0xF6, 0x2D, 0xD9, 0x12, 0xA3,
+ 0x67, 0x40, 0x99, 0x2F, 0xF6, 0xE1, 0xE8, 0x58, 0x3D, 0x42, 0xED, 0xE2,
+ 0x57, 0xC3, 0xAF, 0xFD, 0x7C, 0x76, 0x93, 0x99},
+ // C=TR, L=Ankara, O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.,
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 H6
+ {0x8D, 0xE7, 0x86, 0x55, 0xE1, 0xBE, 0x7F, 0x78, 0x47, 0x80, 0x0B, 0x93,
+ 0xF6, 0x94, 0xD2, 0x1D, 0x36, 0x8C, 0xC0, 0x6E, 0x03, 0x3E, 0x7F, 0xAB,
+ 0x04, 0xBB, 0x5E, 0xB9, 0x9D, 0xA6, 0xB7, 0x00},
+ // C=HU, L=Budapest, O=Microsec Ltd., CN=Microsec e-Szigno Root CA
+ // 2009/emailAddress=info@e-szigno.hu
+ {0x8E, 0x8C, 0x6E, 0xBF, 0x77, 0xDC, 0x73, 0xDB, 0x3E, 0x38, 0xE9, 0x3F,
+ 0x48, 0x03, 0xE6, 0x2B, 0x6B, 0x59, 0x33, 0xBE, 0xB5, 0x1E, 0xE4, 0x15,
+ 0x2F, 0x68, 0xD7, 0xAA, 0x14, 0x42, 0x6B, 0x31},
+ // CN=SG TRUST SERVICES RACINE, OU=0002 43525289500022, O=SG TRUST SERVICES,
+ // C=FR
+ {0x8F, 0x1E, 0xCD, 0xAF, 0x29, 0xBC, 0xD5, 0x6E, 0xDD, 0xD6, 0xB5, 0xD5,
+ 0x6A, 0x07, 0xFC, 0xAC, 0x2B, 0x74, 0xD4, 0xBC, 0xD1, 0x79, 0x17, 0x91,
+ 0x44, 0xA0, 0x36, 0x5C, 0x27, 0xDC, 0xF1, 0x4B},
+ // C=US, O=Digital Signature Trust Co., OU=DSTCA E2
+ {0x8F, 0x62, 0xD7, 0x73, 0x6F, 0x99, 0xDB, 0xD3, 0x3E, 0xE0, 0x0E, 0x10,
+ 0xC7, 0xE3, 0x29, 0x33, 0x9C, 0x98, 0x8A, 0x5B, 0x47, 0xEF, 0x25, 0xF4,
+ 0x08, 0x29, 0x3C, 0xF2, 0x42, 0x6B, 0x4D, 0x44},
+ // C=US, O=First Data Digital Certificates Inc., CN=First Data Digital
+ // Certificates Inc. Certification Authority
+ {0x8F, 0x63, 0x3D, 0xF0, 0x19, 0x1A, 0x41, 0x7D, 0xCD, 0x4F, 0x63, 0x31,
+ 0xF0, 0xE9, 0x0E, 0xB9, 0x47, 0x15, 0x8C, 0x8A, 0x3E, 0xA5, 0x9B, 0xFE,
+ 0x81, 0x42, 0x00, 0x41, 0x31, 0x5E, 0xAC, 0x6C},
+ // C=DE, ST=Hamburg, L=Hamburg, O=TC TrustCenter for Security in Data
+ // Networks GmbH, OU=TC TrustCenter Class 2
+ // CA/emailAddress=certificate@trustcenter.de
+ {0x8F, 0x9E, 0x27, 0x51, 0xDC, 0xD5, 0x74, 0xE9, 0xBA, 0x90, 0xE7, 0x44,
+ 0xEA, 0x92, 0x58, 0x1F, 0xD0, 0xAF, 0x64, 0x0A, 0xE8, 0x6A, 0xC1, 0xCE,
+ 0x21, 0x98, 0xC9, 0x0F, 0x96, 0xB4, 0x48, 0x23},
+ // C=KR, O=KISA, OU=Korea Certification Authority Central, CN=KISA RootCA 3
+ {0x8F, 0xDD, 0x29, 0x8D, 0x1C, 0x93, 0xB2, 0x2B, 0xFC, 0x42, 0xAA, 0xB1,
+ 0xC3, 0xA1, 0x5F, 0x0D, 0x01, 0x83, 0x2C, 0xA0, 0xA1, 0xAE, 0xF2, 0x8D,
+ 0x56, 0x80, 0xF0, 0x6E, 0x6C, 0x7F, 0xD4, 0xEF},
+ // C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 G3
+ {0x8F, 0xE4, 0xFB, 0x0A, 0xF9, 0x3A, 0x4D, 0x0D, 0x67, 0xDB, 0x0B, 0xEB,
+ 0xB2, 0x3E, 0x37, 0xC7, 0x1B, 0xF3, 0x25, 0xDC, 0xBC, 0xDD, 0x24, 0x0E,
+ 0xA0, 0x4D, 0xAF, 0x58, 0xB4, 0x7E, 0x18, 0x40},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2007
+ {0x90, 0xF3, 0xE0, 0x53, 0x96, 0x99, 0x5F, 0xF2, 0x09, 0x22, 0xC4, 0x45,
+ 0x92, 0xDB, 0x62, 0xD7, 0x84, 0x5E, 0x1B, 0xF6, 0x4A, 0xEF, 0x51, 0x2C,
+ 0xCA, 0x75, 0xBC, 0x66, 0x9C, 0xAA, 0x24, 0x79},
+ // C=PA, ST=Panama, L=Panama City, O=TrustCor Systems S. de R.L.,
+ // OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-2
+ {0x91, 0x11, 0x24, 0x07, 0x47, 0xE1, 0xF6, 0x52, 0xF6, 0x6D, 0x1F, 0x71,
+ 0x2A, 0x11, 0xF6, 0x98, 0x96, 0x3B, 0x49, 0x17, 0x02, 0xE3, 0x12, 0xF7,
+ 0x51, 0x3D, 0xA3, 0xD0, 0xFC, 0x1E, 0x5A, 0x28},
+ // C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center,
+ // CN=T-TeleSec GlobalRoot Class 2
+ {0x91, 0xE2, 0xF5, 0x78, 0x8D, 0x58, 0x10, 0xEB, 0xA7, 0xBA, 0x58, 0x73,
+ 0x7D, 0xE1, 0x54, 0x8A, 0x8E, 0xCA, 0xCD, 0x01, 0x45, 0x98, 0xBC, 0x0B,
+ 0x14, 0x3E, 0x04, 0x1B, 0x17, 0x05, 0x25, 0x52},
+ // C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig
+ {0x92, 0xBF, 0x51, 0x19, 0xAB, 0xEC, 0xCA, 0xD0, 0xB1, 0x33, 0x2D, 0xC4,
+ 0xE1, 0xD0, 0x5F, 0xBA, 0x75, 0xB5, 0x67, 0x90, 0x44, 0xEE, 0x0C, 0xA2,
+ 0x6E, 0x93, 0x1F, 0x74, 0x4F, 0x2F, 0x33, 0xCF},
+ // C=CN, O=UniTrust, CN=UCA Root
+ {0x93, 0xE6, 0x5E, 0xC7, 0x62, 0xF0, 0x55, 0xDC, 0x71, 0x8A, 0x33, 0x25,
+ 0x82, 0xC4, 0x1A, 0x04, 0x43, 0x0D, 0x72, 0xE3, 0xCB, 0x87, 0xE8, 0xB8,
+ 0x97, 0xB6, 0x75, 0x16, 0xF0, 0xD1, 0xAA, 0x39},
+ // C=KR, O=KISA, OU=ROOTCA, CN=CertRSA01
+ {0x95, 0x60, 0x57, 0x51, 0x7F, 0xF3, 0xBB, 0x35, 0x04, 0x93, 0x42, 0x28,
+ 0x8C, 0x1C, 0x9D, 0xCE, 0x85, 0x2D, 0xAC, 0xA6, 0x52, 0xB4, 0x65, 0xE9,
+ 0x74, 0x72, 0x53, 0xB5, 0xF9, 0x3B, 0x1F, 0x5E},
+ // O=Cybertrust, Inc, CN=Cybertrust Global Root
+ {0x96, 0x0A, 0xDF, 0x00, 0x63, 0xE9, 0x63, 0x56, 0x75, 0x0C, 0x29, 0x65,
+ 0xDD, 0x0A, 0x08, 0x67, 0xDA, 0x0B, 0x9C, 0xBD, 0x6E, 0x77, 0x71, 0x4A,
+ 0xEA, 0xFB, 0x23, 0x49, 0xAB, 0x39, 0x3D, 0xA3},
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, C=TR, L=Ankara,
+ // O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim
+ // G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E. (c) Aral\xC4\xB1k 2007
+ {0x97, 0x8C, 0xD9, 0x66, 0xF2, 0xFA, 0xA0, 0x7B, 0xA7, 0xAA, 0x95, 0x00,
+ 0xD9, 0xC0, 0x2E, 0x9D, 0x77, 0xF2, 0xCD, 0xAD, 0xA6, 0xAD, 0x6B, 0xA7,
+ 0x4A, 0xF4, 0xB9, 0x1C, 0x66, 0x59, 0x3C, 0x50},
+ // C=DE, O=Deutsche Telekom AG, OU=T-TeleSec Trust Center, CN=Deutsche
+ // Telekom Root CA 1
+ {0x98, 0x06, 0xAB, 0x85, 0x09, 0xE2, 0xF3, 0x5E, 0x19, 0x2F, 0x27, 0x5F,
+ 0x0C, 0x30, 0x8B, 0x94, 0x09, 0xB4, 0x25, 0x12, 0xF9, 0x0C, 0x65, 0x95,
+ 0x98, 0xC2, 0x2B, 0xE6, 0x13, 0x96, 0x22, 0x72},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 2 Root CA
+ {0x9A, 0x11, 0x40, 0x25, 0x19, 0x7C, 0x5B, 0xB9, 0x5D, 0x94, 0xE6, 0x3D,
+ 0x55, 0xCD, 0x43, 0x79, 0x08, 0x47, 0xB6, 0x46, 0xB2, 0x3C, 0xDF, 0x11,
+ 0xAD, 0xA4, 0xA0, 0x0E, 0xFF, 0x15, 0xFB, 0x48},
+ // CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
+ {0x9A, 0x6E, 0xC0, 0x12, 0xE1, 0xA7, 0xDA, 0x9D, 0xBE, 0x34, 0x19, 0x4D,
+ 0x47, 0x8A, 0xD7, 0xC0, 0xDB, 0x18, 0x22, 0xFB, 0x07, 0x1D, 0xF1, 0x29,
+ 0x81, 0x49, 0x6E, 0xD1, 0x04, 0x38, 0x41, 0x13},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary
+ // Certification Authority - G5
+ {0x9A, 0xCF, 0xAB, 0x7E, 0x43, 0xC8, 0xD8, 0x80, 0xD0, 0x6B, 0x26, 0x2A,
+ 0x94, 0xDE, 0xEE, 0xE4, 0xB4, 0x65, 0x99, 0x89, 0xC3, 0xD0, 0xCA, 0xF1,
+ 0x9B, 0xAF, 0x64, 0x05, 0xE4, 0x1A, 0xB7, 0xDF},
+ // C=SE, O=Swedish Social Insurance Agency, CN=Swedish Government Root
+ // Authority v2
+ {0x9C, 0xEF, 0xB0, 0xCB, 0x7B, 0x74, 0xE6, 0x42, 0x93, 0x25, 0x32, 0x83,
+ 0x1E, 0x0D, 0xC8, 0xF4, 0xD6, 0x8A, 0xD4, 0x14, 0x26, 0x1F, 0xC3, 0xF4,
+ 0x74, 0xB7, 0x95, 0xE7, 0x2A, 0x16, 0x4E, 0x57},
+ // C=EU, O=AC Camerfirma SA CIF A82743287, OU=http://www.chambersign.org,
+ // CN=Public Notary Root
+ {0x9D, 0xB9, 0x30, 0xA7, 0xBC, 0xED, 0x5A, 0x59, 0x9D, 0xA6, 0x73, 0xD0,
+ 0xBB, 0x12, 0xC4, 0xC6, 0xC7, 0xAB, 0x5B, 0x3F, 0x88, 0xF3, 0x9C, 0x24,
+ 0xEE, 0x20, 0xA2, 0x47, 0x16, 0xB3, 0x79, 0xDF},
+ // C=US, O=Digital Signature Trust Co., OU=DST (ANX Network) CA
+ {0x9D, 0xF0, 0xEC, 0x44, 0xF5, 0x5B, 0x36, 0xD7, 0x9D, 0x4B, 0x53, 0xC2,
+ 0x08, 0xBE, 0xF8, 0xCB, 0x63, 0xD7, 0x8D, 0xCC, 0x8F, 0xCA, 0xFD, 0xE1,
+ 0x66, 0x23, 0x12, 0xF2, 0x12, 0x20, 0x4A, 0x37},
+ // C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority,
+ // CN=Certum Trusted Network CA 2
+ {0x9F, 0x8B, 0x05, 0x13, 0x7F, 0x20, 0xAC, 0xDE, 0x9B, 0x99, 0x64, 0x10,
+ 0xF4, 0xD0, 0xBF, 0x79, 0x71, 0xA1, 0x00, 0x6D, 0xC9, 0x9E, 0x09, 0x4C,
+ 0x34, 0x6D, 0x27, 0x9B, 0x93, 0xCF, 0xF7, 0xAE},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Universal CA 2
+ {0xA0, 0x23, 0x4F, 0x3B, 0xC8, 0x52, 0x7C, 0xA5, 0x62, 0x8E, 0xEC, 0x81,
+ 0xAD, 0x5D, 0x69, 0x89, 0x5D, 0xA5, 0x68, 0x0D, 0xC9, 0x1D, 0x1C, 0xB8,
+ 0x47, 0x7F, 0x33, 0xF8, 0x78, 0xB9, 0x5B, 0x0B},
+ // C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert.
+ // Authority, CN=Hellenic Academic and Research Institutions RootCA 2015
+ {0xA0, 0x40, 0x92, 0x9A, 0x02, 0xCE, 0x53, 0xB4, 0xAC, 0xF4, 0xF2, 0xFF,
+ 0xC6, 0x98, 0x1C, 0xE4, 0x49, 0x6F, 0x75, 0x5E, 0x6D, 0x45, 0xFE, 0x0B,
+ 0x2A, 0x69, 0x2B, 0xCD, 0x52, 0x52, 0x3F, 0x36},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Universal CA
+ {0xA0, 0x45, 0x9B, 0x9F, 0x63, 0xB2, 0x25, 0x59, 0xF5, 0xFA, 0x5D, 0x4C,
+ 0x6D, 0xB3, 0xF9, 0xF7, 0x2F, 0xF1, 0x93, 0x42, 0x03, 0x35, 0x78, 0xF0,
+ 0x73, 0xBF, 0x1D, 0x1B, 0x46, 0xCB, 0xB9, 0x12},
+ // C=LU, O=LuxTrust s.a., CN=LuxTrust Global Root
+ {0xA1, 0xB2, 0xDB, 0xEB, 0x64, 0xE7, 0x06, 0xC6, 0x16, 0x9E, 0x3C, 0x41,
+ 0x18, 0xB2, 0x3B, 0xAA, 0x09, 0x01, 0x8A, 0x84, 0x27, 0x66, 0x6D, 0x8B,
+ 0xF0, 0xE2, 0x88, 0x91, 0xEC, 0x05, 0x19, 0x50},
+ // C=CN, O=UniTrust, CN=UCA Global Root
+ {0xA1, 0xF0, 0x5C, 0xCB, 0x80, 0xC2, 0xD7, 0x10, 0xEC, 0x7D, 0x47, 0x9A,
+ 0xBD, 0xCB, 0xB8, 0x79, 0xE5, 0x8D, 0x7E, 0xDB, 0x71, 0x49, 0xFE, 0x78,
+ 0xA8, 0x78, 0x84, 0xE3, 0xD0, 0xBA, 0xD0, 0xF9},
+ // C=JP, O=SECOM Trust Systems CO.,LTD., OU=Security Communication EV
+ // RootCA1
+ {0xA2, 0x2D, 0xBA, 0x68, 0x1E, 0x97, 0x37, 0x6E, 0x2D, 0x39, 0x7D, 0x72,
+ 0x8A, 0xAE, 0x3A, 0x9B, 0x62, 0x96, 0xB9, 0xFD, 0xBA, 0x60, 0xBC, 0x2E,
+ 0x11, 0xF6, 0x47, 0xF2, 0xC6, 0x75, 0xFB, 0x37},
+ // C=ch, O=admin, OU=Services, OU=Certification Authorities,
+ // CN=Admin-Root-CA
+ {0xA3, 0x1F, 0x09, 0x30, 0x53, 0xBD, 0x12, 0xC1, 0xF5, 0xC3, 0xC6, 0xEF,
+ 0xD4, 0x98, 0x02, 0x3F, 0xD2, 0x91, 0x4D, 0x77, 0x58, 0xD0, 0x5D, 0x69,
+ 0x8C, 0xE0, 0x84, 0xB5, 0x06, 0x26, 0xE0, 0xE5},
+ // C=CH, O=The Federal Authorities of the Swiss Confederation, OU=Services,
+ // OU=Certification Authorities, CN=Swiss Government Root CA II
+ {0xA3, 0xD7, 0x43, 0x5A, 0x18, 0xC4, 0x6B, 0x23, 0xB6, 0xA4, 0xF8, 0x92,
+ 0x9C, 0xD5, 0x90, 0x50, 0xC9, 0x16, 0x8B, 0x03, 0xA7, 0xFA, 0xD5, 0x32,
+ 0x62, 0x6F, 0x29, 0x7C, 0xAC, 0x53, 0x56, 0xE4},
+ // C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only,
+ // CN=thawte Primary Root CA - G2
+ {0xA4, 0x31, 0x0D, 0x50, 0xAF, 0x18, 0xA6, 0x44, 0x71, 0x90, 0x37, 0x2A,
+ 0x86, 0xAF, 0xAF, 0x8B, 0x95, 0x1F, 0xFB, 0x43, 0x1D, 0x83, 0x7F, 0x1E,
+ 0x56, 0x88, 0xB4, 0x59, 0x71, 0xED, 0x15, 0x57},
+ // C=BM, O=QuoVadis Limited, OU=Root Certification Authority, CN=QuoVadis
+ // Root Certification Authority
+ {0xA4, 0x5E, 0xDE, 0x3B, 0xBB, 0xF0, 0x9C, 0x8A, 0xE1, 0x5C, 0x72, 0xEF,
+ 0xC0, 0x72, 0x68, 0xD6, 0x93, 0xA2, 0x1C, 0x99, 0x6F, 0xD5, 0x1E, 0x67,
+ 0xCA, 0x07, 0x94, 0x60, 0xFD, 0x6D, 0x88, 0x73},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ {0xA4, 0xB6, 0xB3, 0x99, 0x6F, 0xC2, 0xF3, 0x06, 0xB3, 0xFD, 0x86, 0x81,
+ 0xBD, 0x63, 0x41, 0x3D, 0x8C, 0x50, 0x09, 0xCC, 0x4F, 0xA3, 0x29, 0xC2,
+ 0xCC, 0xF0, 0xE2, 0xFA, 0x1B, 0x14, 0x03, 0x05},
+ // C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE
+ // CyberTrust Global Root
+ {0xA5, 0x31, 0x25, 0x18, 0x8D, 0x21, 0x10, 0xAA, 0x96, 0x4B, 0x02, 0xC7,
+ 0xB7, 0xC6, 0xDA, 0x32, 0x03, 0x17, 0x08, 0x94, 0xE5, 0xFB, 0x71, 0xFF,
+ 0xFB, 0x66, 0x67, 0xD5, 0xE6, 0x81, 0x0A, 0x36},
+ // C=US, O=Wells Fargo WellsSecure, OU=Wells Fargo Bank NA, CN=WellsSecure
+ // Public Root Certificate Authority
+ {0xA7, 0x12, 0x72, 0xAE, 0xAA, 0xA3, 0xCF, 0xE8, 0x72, 0x7F, 0x7F, 0xB3,
+ 0x9F, 0x0F, 0xB3, 0xD1, 0xE5, 0x42, 0x6E, 0x90, 0x60, 0xB0, 0x6E, 0xE6,
+ 0xF1, 0x3E, 0x9A, 0x3C, 0x58, 0x33, 0xCD, 0x43},
+ // C=GR, O=Athens Exchange S.A., CN=ATHEX Root CA
+ {0xA7, 0x35, 0x63, 0xE8, 0x59, 0xCB, 0xCF, 0xA1, 0x73, 0xCF, 0x32, 0x85,
+ 0xDE, 0xBF, 0x25, 0x78, 0xED, 0xE1, 0x5D, 0x47, 0xA3, 0xBE, 0xE3, 0x85,
+ 0x86, 0x1A, 0xB7, 0xA4, 0xFB, 0x6D, 0x7B, 0x6E},
+ // C=TN, O=ANCE, OU=ANCE WEB, CN=Agence Nationale de Certification
+ // Electronique/emailAddress=ance@certification.tn
+ {0xA7, 0x98, 0xA1, 0xC7, 0x0E, 0x9B, 0x6D, 0x50, 0xEA, 0xA5, 0x72, 0x4A,
+ 0x26, 0xFA, 0xC7, 0x99, 0x18, 0x48, 0xED, 0xC6, 0x1B, 0xF4, 0x8D, 0x79,
+ 0x81, 0x6B, 0xCA, 0xFB, 0x66, 0x97, 0x21, 0x28},
+ // C=US, ST=DC, L=Washington, O=ABA.ECOM, INC., CN=ABA.ECOM Root
+ // CA/emailAddress=admin@digsigtrust.com
+ {0xA9, 0xA9, 0xCA, 0x22, 0x89, 0x0D, 0x69, 0x49, 0x19, 0xC0, 0x95, 0xBB,
+ 0x80, 0x64, 0xCB, 0xC4, 0xA5, 0x25, 0xA5, 0xDB, 0xFA, 0xF8, 0x01, 0xEC,
+ 0x93, 0x5D, 0xBC, 0xCC, 0x07, 0xC8, 0xBA, 0xEE},
+ // C=my, O=TM, OU=TM Applied Business Certification Authority, CN=TM Applied
+ // Business Root Certificate
+ {0xA9, 0xC7, 0x7A, 0xF1, 0xBC, 0xDF, 0xAA, 0x37, 0x39, 0x44, 0x2B, 0x0B,
+ 0x27, 0x34, 0xC6, 0x8E, 0xAF, 0x2E, 0x98, 0x33, 0xF0, 0xD7, 0x66, 0xFB,
+ 0xCA, 0xA6, 0xF2, 0xAE, 0xB4, 0x2D, 0xEC, 0x02},
+ // C=LV, O=VAS Latvijas Pasts - Vien.reg.Nr.40003052790, OU=Sertifikacijas
+ // pakalpojumi, CN=VAS Latvijas Pasts SSI(RCA)
+ {0xAA, 0xD9, 0xCE, 0xED, 0x5A, 0xA6, 0xB1, 0xCE, 0xA2, 0x85, 0x96, 0xA8,
+ 0xE4, 0xE1, 0xAB, 0xED, 0x93, 0x86, 0xD6, 0xEB, 0xC9, 0xD4, 0xAA, 0xD9,
+ 0xAC, 0xDE, 0x0F, 0xA3, 0x6B, 0xA0, 0x69, 0xD0},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Premium Server
+ // CA/emailAddress=premium-server@thawte.com
+ {0xAB, 0x70, 0x36, 0x36, 0x5C, 0x71, 0x54, 0xAA, 0x29, 0xC2, 0xC2, 0x9F,
+ 0x5D, 0x41, 0x91, 0x16, 0x3B, 0x16, 0x2A, 0x22, 0x25, 0x01, 0x13, 0x57,
+ 0xD5, 0x6D, 0x07, 0xFF, 0xA7, 0xBC, 0x1F, 0x72},
+ // C=CZ, O=\xC4\x8Cesk\xC3\xA1 po\xC5\xA1ta, s.p. [I\xC4\x8C 47114983],
+ // CN=PostSignum Root QCA 2
+ {0xAD, 0x01, 0x6F, 0x95, 0x80, 0x50, 0xE0, 0xE7, 0xE4, 0x6F, 0xAE, 0x7D,
+ 0xCC, 0x50, 0x19, 0x7E, 0xD8, 0xE3, 0xFF, 0x0A, 0x4B, 0x26, 0x2E, 0x5D,
+ 0xDC, 0xDB, 0x3E, 0xDD, 0xDC, 0x7D, 0x65, 0x78},
+ // C=US, O=Wells Fargo WellsSecure, OU=Wells Fargo Bank NA, CN=WellsSecure
+ // Public Root Certification Authority 01 G2
+ {0xAD, 0x75, 0x39, 0xE5, 0xCD, 0xC9, 0x85, 0xFA, 0x95, 0x24, 0x40, 0x55,
+ 0xA9, 0x20, 0x2D, 0x63, 0x46, 0x0E, 0xC9, 0x21, 0x46, 0x7D, 0x03, 0x4C,
+ 0xFD, 0xBE, 0x87, 0xEC, 0x6D, 0x00, 0xFE, 0xDC},
+ // C=AT, O=A-Trust, OU=A-Trust-nQual-01, CN=A-Trust-nQual-01
+ {0xAE, 0x2F, 0xEC, 0x82, 0x91, 0x18, 0xA2, 0x45, 0x5A, 0xD6, 0xA4, 0x15,
+ 0xE7, 0x18, 0x23, 0xEB, 0x9B, 0x7B, 0x6E, 0x35, 0x78, 0xA5, 0x1A, 0xC8,
+ 0xA5, 0x14, 0x46, 0xEA, 0xDB, 0xB0, 0x97, 0x9C},
+ // CN=ComSign CA, O=ComSign, C=IL
+ {0xAE, 0x44, 0x57, 0xB4, 0x0D, 0x9E, 0xDA, 0x96, 0x67, 0x7B, 0x0D, 0x3C,
+ 0x92, 0xD5, 0x7B, 0x51, 0x77, 0xAB, 0xD7, 0xAC, 0x10, 0x37, 0x95, 0x83,
+ 0x56, 0xD1, 0xE0, 0x94, 0x51, 0x8B, 0xE5, 0xF2},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA3
+ {0xAE, 0x92, 0xE9, 0x00, 0x00, 0x54, 0x1A, 0x9E, 0xBC, 0x10, 0x1B, 0x70,
+ 0xB6, 0xC3, 0x3A, 0x62, 0xF5, 0xA5, 0x3A, 0x55, 0xBA, 0x81, 0x5E, 0x81,
+ 0xD3, 0x1A, 0xBD, 0xDF, 0x03, 0x50, 0x7F, 0x5D},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA2
+ {0xAF, 0x6D, 0x08, 0xEE, 0xF3, 0xCA, 0xC4, 0xE1, 0x58, 0x4A, 0xBC, 0x63,
+ 0xC8, 0xA9, 0x47, 0x2A, 0xC5, 0x29, 0xAF, 0x99, 0xF3, 0xF7, 0x91, 0x31,
+ 0x9A, 0x43, 0x77, 0x60, 0x63, 0xF5, 0x8D, 0xCA},
+ // L=Bogota AV Calle 26 N 68D-35, C=CO, O=Entidad de Certificacion Digital
+ // Abierta Certicamara S.A., CN=CERTICAMARA S.A.
+ {0xAF, 0x71, 0xA3, 0xBC, 0xA3, 0x22, 0xE5, 0x22, 0x4D, 0xF5, 0x46, 0x89,
+ 0x56, 0x96, 0xCE, 0x44, 0x9A, 0x8B, 0xD2, 0xBD, 0x13, 0x0F, 0x7A, 0x7A,
+ 0xE4, 0x57, 0x76, 0x7F, 0x5C, 0x23, 0xD8, 0xF8},
+ // O=RSA Security Inc, OU=RSA Security 2048 V3
+ {0xAF, 0x8B, 0x67, 0x62, 0xA1, 0xE5, 0x28, 0x22, 0x81, 0x61, 0xA9, 0x5D,
+ 0x5C, 0x55, 0x9E, 0xE2, 0x66, 0x27, 0x8F, 0x75, 0xD7, 0x9E, 0x83, 0x01,
+ 0x89, 0xA5, 0x03, 0x50, 0x6A, 0xBD, 0x6B, 0x4C},
+ // C=IT, L=Milano, O=Actalis S.p.A./03358520967, CN=Actalis Authentication
+ // CA G1
+ {0xAF, 0xE8, 0x0A, 0x97, 0xEA, 0x11, 0x15, 0x91, 0x90, 0xE9, 0x27, 0xE0,
+ 0x8E, 0xC2, 0xE6, 0x0C, 0x59, 0xA4, 0x05, 0x59, 0x48, 0x3A, 0x3F, 0xEE,
+ 0x83, 0x8A, 0x85, 0x32, 0x1B, 0x3A, 0xEA, 0xAD},
+ // O=eSign Australia, OU=Public Secure Services, CN=Primary Utility Root CA
+ {0xB0, 0x4D, 0x70, 0x8F, 0x1A, 0xE0, 0x45, 0x62, 0x65, 0xDD, 0x1B, 0x66,
+ 0x90, 0x7A, 0x26, 0x91, 0xA2, 0x86, 0x80, 0xB8, 0x53, 0xE0, 0x31, 0xDF,
+ 0x3D, 0xF9, 0x08, 0x3A, 0xF7, 0x16, 0x14, 0xD7},
+ // C=ES, O=IZENPE S.A. - CIF A-01337260-RMerc.Vitoria-Gasteiz T1055 F62 S8,
+ // L=Avda del Mediterraneo Etorbidea 3 - 01010 Vitoria-Gasteiz,
+ // CN=Izenpe.com/emailAddress=Info@izenpe.com
+ {0xB0, 0x87, 0x7A, 0xEE, 0x2D, 0x39, 0x27, 0x4D, 0xF8, 0x31, 0xF6, 0x6F,
+ 0xDE, 0xEB, 0x77, 0x17, 0x55, 0x7C, 0x25, 0x8F, 0xC9, 0xEB, 0x55, 0x23,
+ 0x1A, 0x9F, 0x8A, 0x64, 0x7A, 0x75, 0x43, 0x3F},
+ // C=TR, L=Ankara, O=E-Tu\xC4\x9Fra EBG Bili\xC5\x9Fim Teknolojileri ve
+ // Hizmetleri A.\xC5\x9E., OU=E-Tugra Sertifikasyon Merkezi, CN=E-Tugra
+ // Certification Authority
+ {0xB0, 0xBF, 0xD5, 0x2B, 0xB0, 0xD7, 0xD9, 0xBD, 0x92, 0xBF, 0x5D, 0x4D,
+ 0xC1, 0x3D, 0xA2, 0x55, 0xC0, 0x2C, 0x54, 0x2F, 0x37, 0x83, 0x65, 0xEA,
+ 0x89, 0x39, 0x11, 0xF5, 0x5E, 0x55, 0xF2, 0x3C},
+ // C=FR, O=NATIXIS, OU=0002 542044524, CN=CESAM
+ {0xB2, 0x25, 0x99, 0x96, 0xFF, 0xF7, 0x35, 0xAB, 0x35, 0x01, 0x4E, 0xF6,
+ 0x3F, 0x3D, 0x41, 0x31, 0x90, 0x07, 0x9D, 0xD0, 0x3A, 0x09, 0x62, 0x43,
+ 0x26, 0x35, 0xA8, 0x69, 0x5F, 0x99, 0x53, 0x05},
+ // C=SE, O=Carelink, CN=SITHS CA v3
+ {0xB2, 0xF3, 0xC4, 0x21, 0x6A, 0xF7, 0xAF, 0xF7, 0x24, 0x62, 0x46, 0x6D,
+ 0xC1, 0x3C, 0xD2, 0x81, 0x0D, 0xB8, 0xEE, 0xD8, 0x53, 0xEA, 0xBB, 0x9A,
+ 0x06, 0x3A, 0x60, 0x8E, 0xFC, 0x18, 0xFB, 0xE8},
+ // C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec
+ // Class 3 Public Primary Certification Authority - G6
+ {0xB3, 0x23, 0x96, 0x74, 0x64, 0x53, 0x44, 0x2F, 0x35, 0x3E, 0x61, 0x62,
+ 0x92, 0xBB, 0x20, 0xBB, 0xAA, 0x5D, 0x23, 0xB5, 0x46, 0x45, 0x0F, 0xDB,
+ 0x9C, 0x54, 0xB8, 0x38, 0x61, 0x67, 0xD5, 0x29},
+ // C=au, O=SecureNet CA Class B
+ {0xB3, 0xC9, 0x62, 0xD3, 0x40, 0x19, 0xFB, 0x38, 0xAB, 0x9F, 0xE9, 0xC6,
+ 0x23, 0x99, 0x74, 0x2A, 0xB2, 0x6C, 0x43, 0xC2, 0xD1, 0x8C, 0xE3, 0xF2,
+ 0xB1, 0x3C, 0x14, 0x32, 0x1E, 0x52, 0x96, 0x4B},
+ // x500UniqueIdentifier=SEC-830101-9V9, L=Alvaro Obregon, ST=Distrito
+ // Federal, C=MX/postalCode=01030/street=Insurgentes Sur 1940, CN=Autoridad
+ // Certificadora Raiz de la Secretaria de Economia, OU=Direccion General de
+ // Normatividad Mercantil, O=Secretaria de
+ // Economia/emailAddress=acrse@economia.gob.mx
+ {0xB4, 0x1D, 0x51, 0x6A, 0x53, 0x51, 0xD4, 0x2D, 0xEE, 0xA1, 0x91, 0xFA,
+ 0x6E, 0xDF, 0x2A, 0x67, 0xDE, 0xE2, 0xF3, 0x6D, 0xC9, 0x69, 0x01, 0x2C,
+ 0x76, 0x66, 0x9E, 0x61, 0x6B, 0x90, 0x0D, 0xDF},
+ // C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc,
+ // OU=Certification Services Division, CN=Thawte Server
+ // CA/emailAddress=server-certs@thawte.com
+ {0xB4, 0x41, 0x0B, 0x73, 0xE2, 0xE6, 0xEA, 0xCA, 0x47, 0xFB, 0xC4, 0x2F,
+ 0x8F, 0xA4, 0x01, 0x8A, 0xF4, 0x38, 0x1D, 0xC5, 0x4C, 0xFA, 0xA8, 0x44,
+ 0x50, 0x46, 0x1E, 0xED, 0x09, 0x45, 0x4D, 0xE9},
+ // C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use
+ // only, CN=GeoTrust Primary Certification Authority - G3
+ {0xB4, 0x78, 0xB8, 0x12, 0x25, 0x0D, 0xF8, 0x78, 0x63, 0x5C, 0x2A, 0xA7,
+ 0xEC, 0x7D, 0x15, 0x5E, 0xAA, 0x62, 0x5E, 0xE8, 0x29, 0x16, 0xE2, 0xCD,
+ 0x29, 0x43, 0x61, 0x88, 0x6C, 0xD1, 0xFB, 0xD4},
+ // C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc.,
+ // OU=http://certificates.starfieldtech.com/repository/, CN=Starfield
+ // Services Root Certificate Authority
+ {0xB5, 0xBD, 0x2C, 0xB7, 0x9C, 0xBD, 0x19, 0x07, 0x29, 0x8D, 0x6B, 0xDF,
+ 0x48, 0x42, 0xE5, 0x16, 0xD8, 0xC7, 0x8F, 0xA6, 0xFC, 0x96, 0xD2, 0x5F,
+ 0x71, 0xAF, 0x81, 0x4E, 0x16, 0xCC, 0x24, 0x5E},
+ // C=DE, O=Deutsche Telekom AG, OU=T-TeleSec Trust Center, CN=Deutsche
+ // Telekom Root CA 2
+ {0xB6, 0x19, 0x1A, 0x50, 0xD0, 0xC3, 0x97, 0x7F, 0x7D, 0xA9, 0x9B, 0xCD,
+ 0xAA, 0xC8, 0x6A, 0x22, 0x7D, 0xAE, 0xB9, 0x67, 0x9E, 0xC7, 0x0B, 0xA3,
+ 0xB0, 0xC9, 0xD9, 0x22, 0x71, 0xC1, 0x70, 0xD3},
+ // C=ES, ST=Barcelona, L=Barcelona (see current address at
+ // https://www.anf.es/address/), O=ANF Autoridad de Certificaci\xC3\xB3n,
+ // OU=ANF Clase 1 CA/serialNumber=G63287510, CN=ANF Server CA
+ {0xB6, 0x44, 0xD9, 0x55, 0xFF, 0xF2, 0x9B, 0x74, 0xE3, 0xB5, 0x68, 0x7E,
+ 0x90, 0x8E, 0xE7, 0xC3, 0xC9, 0x19, 0x7B, 0xA3, 0x33, 0x6C, 0xC6, 0x32,
+ 0x85, 0x31, 0xF6, 0xC0, 0x57, 0xD6, 0x77, 0xFD},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 CA 1
+ {0xB7, 0xB1, 0x2B, 0x17, 0x1F, 0x82, 0x1D, 0xAA, 0x99, 0x0C, 0xD0, 0xFE,
+ 0x50, 0x87, 0xB1, 0x28, 0x44, 0x8B, 0xA8, 0xE5, 0x18, 0x4F, 0x84, 0xC5,
+ 0x1E, 0x02, 0xB5, 0xC8, 0xFB, 0x96, 0x2B, 0x24},
+ // C=FR, O=OpenTrust, CN=OpenTrust Root CA G3
+ {0xB7, 0xC3, 0x62, 0x31, 0x70, 0x6E, 0x81, 0x07, 0x8C, 0x36, 0x7C, 0xB8,
+ 0x96, 0x19, 0x8F, 0x1E, 0x32, 0x08, 0xDD, 0x92, 0x69, 0x49, 0xDD, 0x8F,
+ 0x57, 0x09, 0xA4, 0x10, 0xF7, 0x5B, 0x62, 0x92},
+ // C=MO, O=Macao Post, CN=Macao Post eSignTrust Root Certification Authority
+ {0xB8, 0xBB, 0xE5, 0x23, 0xBF, 0xCA, 0x3B, 0x11, 0xD5, 0x0F, 0x73, 0xF7,
+ 0xF1, 0x0B, 0x3E, 0xC8, 0xEC, 0x95, 0x8A, 0xA1, 0xDC, 0x86, 0xF6, 0x6D,
+ 0x95, 0x41, 0x90, 0x7F, 0xF1, 0xA1, 0x10, 0xEF},
+ // C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI,
+ // CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr
+ {0xB9, 0xBE, 0xA7, 0x86, 0x0A, 0x96, 0x2E, 0xA3, 0x61, 0x1D, 0xAB, 0x97,
+ 0xAB, 0x6D, 0xA3, 0xE2, 0x1C, 0x10, 0x68, 0xB9, 0x7D, 0x55, 0x57, 0x5E,
+ 0xD0, 0xE1, 0x12, 0x79, 0xC1, 0x1C, 0x89, 0x32},
+ // C=GR, O=Hellenic Academic and Research Institutions Cert. Authority,
+ // CN=Hellenic Academic and Research Institutions RootCA 2011
+ {0xBC, 0x10, 0x4F, 0x15, 0xA4, 0x8B, 0xE7, 0x09, 0xDC, 0xA5, 0x42, 0xA7,
+ 0xE1, 0xD4, 0xB9, 0xDF, 0x6F, 0x05, 0x45, 0x27, 0xE8, 0x02, 0xEA, 0xA9,
+ 0x2D, 0x59, 0x54, 0x44, 0x25, 0x8A, 0xFE, 0x71},
+ // L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 3
+ // Policy Validation Authority,
+ // CN=http://www.valicert.com//emailAddress=info@valicert.com
+ {0xBC, 0x23, 0xF9, 0x8A, 0x31, 0x3C, 0xB9, 0x2D, 0xE3, 0xBB, 0xFC, 0x3A,
+ 0x5A, 0x9F, 0x44, 0x61, 0xAC, 0x39, 0x49, 0x4C, 0x4A, 0xE1, 0x5A, 0x9E,
+ 0x9D, 0xF1, 0x31, 0xE9, 0x9B, 0x73, 0x01, 0x9A},
+ // C=HK, O=Hongkong Post, CN=Hongkong Post Root CA
+ {0xBC, 0xDD, 0x8D, 0xF4, 0x27, 0x63, 0x66, 0xD7, 0xFF, 0x4B, 0x68, 0x8D,
+ 0xC8, 0x15, 0x00, 0xD8, 0xE9, 0x82, 0x52, 0xC0, 0x49, 0xC8, 0xFF, 0x1E,
+ 0x8C, 0x82, 0xF2, 0xBA, 0xEC, 0x9D, 0x5C, 0x16},
+ // C=US, O=AffirmTrust, CN=AffirmTrust Premium ECC
+ {0xBD, 0x71, 0xFD, 0xF6, 0xDA, 0x97, 0xE4, 0xCF, 0x62, 0xD1, 0x64, 0x7A,
+ 0xDD, 0x25, 0x81, 0xB0, 0x7D, 0x79, 0xAD, 0xF8, 0x39, 0x7E, 0xB4, 0xEC,
+ 0xBA, 0x9C, 0x5E, 0x84, 0x88, 0x82, 0x14, 0x23},
+ // C=CH, O=SwissSign AG, CN=SwissSign Silver CA - G2
+ {0xBE, 0x6C, 0x4D, 0xA2, 0xBB, 0xB9, 0xBA, 0x59, 0xB6, 0xF3, 0x93, 0x97,
+ 0x68, 0x37, 0x42, 0x46, 0xC3, 0xC0, 0x05, 0x99, 0x3F, 0xA9, 0x8F, 0x02,
+ 0x0D, 0x1D, 0xED, 0xBE, 0xD4, 0x8A, 0x81, 0xD5},
+ // OU=GlobalSign ECC Root CA - R4, O=GlobalSign, CN=GlobalSign
+ {0xBE, 0xC9, 0x49, 0x11, 0xC2, 0x95, 0x56, 0x76, 0xDB, 0x6C, 0x0A, 0x55,
+ 0x09, 0x86, 0xD7, 0x6E, 0x3B, 0xA0, 0x05, 0x66, 0x7C, 0x44, 0x2C, 0x97,
+ 0x62, 0xB4, 0xFB, 0xB7, 0x73, 0xDE, 0x22, 0x8C},
+ // C=JP, O=Japan Certification Services, Inc., CN=SecureSign RootCA11
+ {0xBF, 0x0F, 0xEE, 0xFB, 0x9E, 0x3A, 0x58, 0x1A, 0xD5, 0xF9, 0xE9, 0xDB,
+ 0x75, 0x89, 0x98, 0x57, 0x43, 0xD2, 0x61, 0x08, 0x5C, 0x4D, 0x31, 0x4F,
+ 0x6F, 0x5D, 0x72, 0x59, 0xAA, 0x42, 0x16, 0x12},
+ // C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Root Certification Authority
+ {0xBF, 0xD8, 0x8F, 0xE1, 0x10, 0x1C, 0x41, 0xAE, 0x3E, 0x80, 0x1B, 0xF8,
+ 0xBE, 0x56, 0x35, 0x0E, 0xE9, 0xBA, 0xD1, 0xA6, 0xB9, 0xBD, 0x51, 0x5E,
+ 0xDC, 0x5C, 0x6D, 0x5B, 0x87, 0x11, 0xAC, 0x44},
+ // C=CN, O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD., CN=GDCA TrustAUTH R5
+ // ROOT
+ {0xBF, 0xFF, 0x8F, 0xD0, 0x44, 0x33, 0x48, 0x7D, 0x6A, 0x8A, 0xA6, 0x0C,
+ 0x1A, 0x29, 0x76, 0x7A, 0x9F, 0xC2, 0xBB, 0xB0, 0x5E, 0x42, 0x0F, 0x71,
+ 0x3A, 0x13, 0xB9, 0x92, 0x89, 0x1D, 0x38, 0x93},
+ // C=TW, O=Chunghwa Telecom Co., Ltd., OU=ePKI Root Certification Authority
+ {0xC0, 0xA6, 0xF4, 0xDC, 0x63, 0xA2, 0x4B, 0xFD, 0xCF, 0x54, 0xEF, 0x2A,
+ 0x6A, 0x08, 0x2A, 0x0A, 0x72, 0xDE, 0x35, 0x80, 0x3E, 0x2F, 0xF5, 0xFF,
+ 0x52, 0x7A, 0xE5, 0xD8, 0x72, 0x06, 0xDF, 0xD5},
+ // C=CL, ST=Region Metropolitana, L=Santiago, O=E-CERTCHILE, OU=Autoridad
+ // Certificadora/emailAddress=sclientes@ccs.cl, CN=E-CERT ROOT CA
+ {0xC1, 0x09, 0xE0, 0xD1, 0xB6, 0x40, 0x00, 0xB0, 0x1E, 0x89, 0x4B, 0xDA,
+ 0xA9, 0x55, 0xE1, 0xFF, 0x91, 0xB6, 0xD0, 0x84, 0xA8, 0x38, 0xD9, 0x0E,
+ 0x04, 0x4B, 0x9E, 0x3F, 0xCD, 0x2A, 0x8B, 0xFA},
+ // C=FR, O=Certplus, CN=Class 3 Primary CA
+ {0xC1, 0xB1, 0x2F, 0x48, 0x00, 0x20, 0x33, 0x6E, 0x5B, 0x04, 0xF5, 0x20,
+ 0xBC, 0x19, 0xC2, 0xE2, 0xE1, 0x0A, 0xB4, 0x2C, 0x9D, 0x92, 0x35, 0xF0,
+ 0x5C, 0xBE, 0xC3, 0x3F, 0xFA, 0x4D, 0x4D, 0xEA},
+ // C=GB, O=Trustis Limited, OU=Trustis FPS Root CA
+ {0xC1, 0xB4, 0x82, 0x99, 0xAB, 0xA5, 0x20, 0x8F, 0xE9, 0x63, 0x0A, 0xCE,
+ 0x55, 0xCA, 0x68, 0xA0, 0x3E, 0xDA, 0x5A, 0x51, 0x9C, 0x88, 0x02, 0xA0,
+ 0xD3, 0xA6, 0x73, 0xBE, 0x8F, 0x8E, 0x55, 0x7D},
+ // C=ES, L=C/ Muntaner 244 Barcelona, CN=Autoridad de Certificacion
+ // Firmaprofesional CIF A62634068/emailAddress=ca@firmaprofesional.com
+ {0xC1, 0xCF, 0x0B, 0x52, 0x09, 0x64, 0x35, 0xE3, 0xF1, 0xB7, 0x1D, 0xAA,
+ 0xEC, 0x45, 0x5A, 0x23, 0x11, 0xC8, 0x40, 0x4F, 0x55, 0x83, 0xA9, 0xE2,
+ 0x13, 0xC6, 0x9D, 0x85, 0x7D, 0x94, 0x33, 0x05},
+ // C=HU, L=Budapest, O=NISZ Nemzeti Infokommunik\xC3\xA1ci\xC3\xB3s
+ // Szolg\xC3\xA1ltat\xC3\xB3 Zrt.,
+ // CN=F\xC5\x91tan\xC3\xBAs\xC3\xADtv\xC3\xA1nykiad\xC3\xB3 -
+ // Korm\xC3\xA1nyzati Hiteles\xC3\xADt\xC3\xA9s Szolg\xC3\xA1ltat\xC3\xB3
+ {0xC2, 0x15, 0x73, 0x09, 0xD9, 0xAE, 0xE1, 0x7B, 0xF3, 0x4F, 0x4D, 0xF5,
+ 0xE8, 0x8D, 0xBA, 0xEB, 0xA5, 0x7E, 0x03, 0x61, 0xEB, 0x81, 0x4C, 0xBC,
+ 0x23, 0x9F, 0x4D, 0x54, 0xD3, 0x29, 0xA3, 0x8D},
+ // C=CO, L=Carrera 9 16-21 Bogota, O=Certicamara S.A. Entidad de
+ // Certificacion, CN=Certificado Empresarial Clase-A
+ {0xC2, 0x95, 0x9D, 0xB8, 0x33, 0x9E, 0x8D, 0xBC, 0xF6, 0x40, 0x9C, 0xA9,
+ 0x2A, 0x66, 0xC4, 0x9F, 0xD2, 0xE3, 0x24, 0x94, 0x94, 0x0A, 0x90, 0x11,
+ 0x43, 0xBD, 0x7E, 0xB7, 0x28, 0x27, 0xDE, 0xC2},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=CA ROOT Services, CN=SSC
+ // GDL CA Root B
+ {0xC3, 0x1E, 0xEF, 0x56, 0x82, 0xAB, 0xB5, 0x51, 0xEB, 0xC8, 0x28, 0xDE,
+ 0xD8, 0x40, 0x98, 0x51, 0x8A, 0x67, 0x68, 0x52, 0x6D, 0x15, 0x2E, 0xE1,
+ 0x64, 0xCF, 0xB9, 0x72, 0xA1, 0x42, 0x5D, 0x53},
+ // C=IN, O=India PKI, CN=CCA India 2015 SPL
+ {0xC3, 0x4C, 0x5D, 0xF5, 0x30, 0x80, 0x07, 0x8F, 0xFE, 0x45, 0xB2, 0x1A,
+ 0x7F, 0x60, 0x04, 0x69, 0x91, 0x72, 0x04, 0xF4, 0xF0, 0x29, 0x3F, 0x1D,
+ 0x72, 0x09, 0x39, 0x3E, 0x52, 0x65, 0xC0, 0x4F},
+ // C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification
+ // Authority
+ {0xC3, 0x84, 0x6B, 0xF2, 0x4B, 0x9E, 0x93, 0xCA, 0x64, 0x27, 0x4C, 0x0E,
+ 0xC6, 0x7C, 0x1E, 0xCC, 0x5E, 0x02, 0x4F, 0xFC, 0xAC, 0xD2, 0xD7, 0x40,
+ 0x19, 0x35, 0x0E, 0x81, 0xFE, 0x54, 0x6A, 0xE4},
+ // C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network,
+ // OU=http://www.usertrust.com, CN=UTN-USERFirst-Network Applications
+ {0xC3, 0x8D, 0xCB, 0x38, 0x95, 0x93, 0x93, 0x35, 0x86, 0x91, 0xEA, 0x4D,
+ 0x4F, 0x3C, 0xE4, 0x95, 0xCE, 0x74, 0x89, 0x96, 0xE6, 0x4E, 0xD1, 0x89,
+ 0x1D, 0x89, 0x7A, 0x0F, 0xC4, 0xDD, 0x55, 0xC6},
+ // CN=T\xC3\x9CRKTRUST Elektronik Sertifika Hizmet
+ // Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1, C=TR, L=Ankara,
+ // O=T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve Bili\xC5\x9Fim
+ // G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E. (c) Kas\xC4\xB1m 2005
+ {0xC4, 0x70, 0xCF, 0x54, 0x7E, 0x23, 0x02, 0xB9, 0x77, 0xFB, 0x29, 0xDD,
+ 0x71, 0xA8, 0x9A, 0x7B, 0x6C, 0x1F, 0x60, 0x77, 0x7B, 0x03, 0x29, 0xF5,
+ 0x60, 0x17, 0xF3, 0x28, 0xBF, 0x4F, 0x6B, 0xE6},
+ // CN=T\xC3\x9CRKTRUST Elektronik \xC4\xB0\xC5\x9Flem Hizmetleri, C=TR,
+ // L=ANKARA, O=(c) 2005 T\xC3\x9CRKTRUST Bilgi \xC4\xB0leti\xC5\x9Fim ve
+ // Bili\xC5\x9Fim G\xC3\xBCvenli\xC4\x9Fi Hizmetleri A.\xC5\x9E.
+ {0xC4, 0x99, 0xF6, 0xCE, 0xCC, 0x5D, 0xA4, 0xD6, 0x1F, 0x14, 0xED, 0x04,
+ 0x05, 0x27, 0x0C, 0x52, 0x49, 0xD0, 0xE7, 0x96, 0x15, 0xB0, 0xDA, 0x42,
+ 0x65, 0x9E, 0xD2, 0xD7, 0xFF, 0xEF, 0x8A, 0x40},
+ // C=US, O=VISA, OU=Visa International Service Association, CN=Visa
+ // Information Delivery Root CA
+ {0xC5, 0x7A, 0x3A, 0xCB, 0xE8, 0xC0, 0x6B, 0xA1, 0x98, 0x8A, 0x83, 0x48,
+ 0x5B, 0xF3, 0x26, 0xF2, 0x44, 0x87, 0x75, 0x37, 0x98, 0x49, 0xDE, 0x01,
+ 0xCA, 0x43, 0x57, 0x1A, 0xF3, 0x57, 0xE7, 0x4B},
+ // C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom
+ // Certification Authority
+ {0xC7, 0x66, 0xA9, 0xBE, 0xF2, 0xD4, 0x07, 0x1C, 0x86, 0x3A, 0x31, 0xAA,
+ 0x49, 0x20, 0xE8, 0x13, 0xB2, 0xD1, 0x98, 0x60, 0x8C, 0xB7, 0xB7, 0xCF,
+ 0xE2, 0x11, 0x43, 0xB8, 0x36, 0xDF, 0x09, 0xEA},
+ // C=TN, CN=Tunisian Root Certificate Authority - TunRootCA2, O=National
+ // Digital Certification Agency
+ {0xC7, 0x95, 0xFF, 0x8F, 0xF2, 0x0C, 0x96, 0x66, 0x88, 0xF0, 0x64, 0xA1,
+ 0xE0, 0x91, 0x42, 0x1D, 0x31, 0x10, 0xA3, 0x45, 0x6C, 0x17, 0xEC, 0x24,
+ 0x04, 0xB9, 0x98, 0x73, 0x87, 0x41, 0xF6, 0x22},
+ // C=IL, O=StartCom Ltd., CN=StartCom Certification Authority G2
+ {0xC7, 0xBA, 0x65, 0x67, 0xDE, 0x93, 0xA7, 0x98, 0xAE, 0x1F, 0xAA, 0x79,
+ 0x1E, 0x71, 0x2D, 0x37, 0x8F, 0xAE, 0x1F, 0x93, 0xC4, 0x39, 0x7F, 0xEA,
+ 0x44, 0x1B, 0xB7, 0xCB, 0xE6, 0xFD, 0x59, 0x95},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Global CA 2
+ {0xCA, 0x2D, 0x82, 0xA0, 0x86, 0x77, 0x07, 0x2F, 0x8A, 0xB6, 0x76, 0x4F,
+ 0xF0, 0x35, 0x67, 0x6C, 0xFE, 0x3E, 0x5E, 0x32, 0x5E, 0x01, 0x21, 0x72,
+ 0xDF, 0x3F, 0x92, 0x09, 0x6D, 0xB7, 0x9B, 0x85},
+ // OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
+ {0xCA, 0x42, 0xDD, 0x41, 0x74, 0x5F, 0xD0, 0xB8, 0x1E, 0xB9, 0x02, 0x36,
+ 0x2C, 0xF9, 0xD8, 0xBF, 0x71, 0x9D, 0xA1, 0xBD, 0x1B, 0x1E, 0xFC, 0x94,
+ 0x6F, 0x5B, 0x4C, 0x99, 0xF4, 0x2C, 0x1B, 0x9E},
+ // CN=Autoridad de Certificacion Raiz del Estado Venezolano, C=VE,
+ // L=Caracas, ST=Distrito Capital, O=Sistema Nacional de Certificacion
+ // Electronica, OU=Superintendencia de Servicios de Certificacion
+ // Electronica/emailAddress=acraiz@suscerte.gob.ve
+ {0xCA, 0x7A, 0x5E, 0x68, 0xC5, 0x3D, 0x2C, 0x51, 0xF7, 0x2F, 0x6B, 0x46,
+ 0x5D, 0x3E, 0xD7, 0x53, 0xF5, 0x90, 0x3E, 0xC7, 0x90, 0x1C, 0x8D, 0x0F,
+ 0x55, 0xD8, 0x68, 0x33, 0x7C, 0x81, 0x97, 0x5A},
+ // C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
+ {0xCB, 0x3C, 0xCB, 0xB7, 0x60, 0x31, 0xE5, 0xE0, 0x13, 0x8F, 0x8D, 0xD3,
+ 0x9A, 0x23, 0xF9, 0xDE, 0x47, 0xFF, 0xC3, 0x5E, 0x43, 0xC1, 0x14, 0x4C,
+ 0xEA, 0x27, 0xD4, 0x6A, 0x5A, 0xB1, 0xCB, 0x5F},
+ // OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign
+ {0xCB, 0xB5, 0x22, 0xD7, 0xB7, 0xF1, 0x27, 0xAD, 0x6A, 0x01, 0x13, 0x86,
+ 0x5B, 0xDF, 0x1C, 0xD4, 0x10, 0x2E, 0x7D, 0x07, 0x59, 0xAF, 0x63, 0x5A,
+ 0x7C, 0xF4, 0x72, 0x0D, 0xC9, 0x63, 0xC5, 0x3B},
+ // C=BR, O=ICP-Brasil, OU=Instituto Nacional de Tecnologia da Informacao -
+ // ITI, CN=Autoridade Certificadora Raiz Brasileira v1
+ {0xCB, 0xD8, 0xED, 0x38, 0xD4, 0xA2, 0xD6, 0x77, 0xD4, 0x53, 0xD7, 0x0D,
+ 0xD8, 0x89, 0x0A, 0xF4, 0xF6, 0x37, 0x4C, 0xBA, 0x62, 0x99, 0x94, 0x3F,
+ 0x1A, 0xB3, 0xA6, 0x93, 0x6C, 0x6F, 0xD7, 0x95},
+ // C=FR, O=Certplus, CN=Class 3P Primary CA
+ {0xCC, 0xC8, 0x94, 0x89, 0x37, 0x1B, 0xAD, 0x11, 0x1C, 0x90, 0x61, 0x9B,
+ 0xEA, 0x24, 0x0A, 0x2E, 0x6D, 0xAD, 0xD9, 0x9F, 0x9F, 0x6E, 0x1D, 0x4D,
+ 0x41, 0xE5, 0x8E, 0xD6, 0xDE, 0x3D, 0x02, 0x85},
+ // C=LV, OU=Sertifikacijas pakalpojumu dala, CN=E-ME SSI (RCA)
+ {0xCD, 0x0B, 0x3B, 0x2A, 0xA1, 0x74, 0xB5, 0x5F, 0x18, 0xC7, 0x50, 0x2F,
+ 0x3C, 0x3A, 0x76, 0xF2, 0x19, 0x81, 0x75, 0xCE, 0x45, 0x63, 0x73, 0x70,
+ 0xCF, 0x4F, 0x48, 0xB9, 0xC2, 0xCE, 0x4F, 0xBF},
+ // DC=rs, DC=posta, DC=ca, CN=Configuration, CN=Services, CN=Public Key
+ // Services, CN=AIA, CN=Posta CA Root
+ {0xCD, 0x20, 0x12, 0x56, 0xFE, 0x5C, 0xED, 0x0B, 0xFF, 0xF8, 0xDF, 0x59,
+ 0x5F, 0xFF, 0x36, 0xB1, 0x41, 0x6D, 0x53, 0x13, 0xA9, 0x99, 0xF5, 0x32,
+ 0xEF, 0x4A, 0x99, 0x15, 0xDF, 0x96, 0xDE, 0xE0},
+ // C=FR, O=Certplus, CN=Class 3TS Primary CA
+ {0xCE, 0x7D, 0xD0, 0x96, 0xC8, 0xFD, 0xE2, 0xBF, 0x5C, 0x43, 0x8E, 0xDB,
+ 0x57, 0x4B, 0xD6, 0x45, 0x43, 0x85, 0x33, 0x4E, 0xE8, 0xFF, 0x10, 0x6C,
+ 0x0F, 0x93, 0xD5, 0x05, 0x1B, 0xE6, 0xBA, 0xC3},
+ // C=US, OU=www.xrampsecurity.com, O=XRamp Security Services Inc, CN=XRamp
+ // Global Certification Authority
+ {0xCE, 0xCD, 0xDC, 0x90, 0x50, 0x99, 0xD8, 0xDA, 0xDF, 0xC5, 0xB1, 0xD2,
+ 0x09, 0xB7, 0x37, 0xCB, 0xE2, 0xC1, 0x8C, 0xFB, 0x2C, 0x10, 0xC0, 0xFF,
+ 0x0B, 0xCF, 0x0D, 0x32, 0x86, 0xFC, 0x1A, 0xA2},
+ // C=US, O=Equifax Secure Inc., CN=Equifax Secure eBusiness CA-1
+ {0xCF, 0x56, 0xFF, 0x46, 0xA4, 0xA1, 0x86, 0x10, 0x9D, 0xD9, 0x65, 0x84,
+ 0xB5, 0xEE, 0xB5, 0x8A, 0x51, 0x0C, 0x42, 0x75, 0xB0, 0xE5, 0xF9, 0x4F,
+ 0x40, 0xBB, 0xAE, 0x86, 0x5E, 0x19, 0xF6, 0x73},
+ // O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits
+ // liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification
+ // Authority (2048)
+ {0xD1, 0xC3, 0x39, 0xEA, 0x27, 0x84, 0xEB, 0x87, 0x0F, 0x93, 0x4F, 0xC5,
+ 0x63, 0x4E, 0x4A, 0xA9, 0xAD, 0x55, 0x05, 0x01, 0x64, 0x01, 0xF2, 0x64,
+ 0x65, 0xD3, 0x7A, 0x57, 0x46, 0x63, 0x35, 0x9F},
+ // C=CZ, O=Prvn\xC3\xAD certifika\xC4\x8Dn\xC3\xAD autorita, a.s., CN=I.CA
+ // Root CA/RSA/serialNumber=NTRCZ-26439395
+ {0xD3, 0xD6, 0x07, 0xA9, 0xFF, 0x24, 0xA1, 0x95, 0x23, 0xB6, 0xDA, 0x9D,
+ 0x2C, 0x64, 0x94, 0x46, 0xF8, 0x78, 0x8C, 0xB9, 0x6D, 0x9F, 0xD1, 0x30,
+ 0x97, 0x2E, 0x12, 0x0C, 0x13, 0x67, 0x77, 0x30},
+ // C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden Root CA
+ {0xD4, 0x1D, 0x82, 0x9E, 0x8C, 0x16, 0x59, 0x82, 0x2A, 0xF9, 0x3F, 0xCE,
+ 0x62, 0xBF, 0xFC, 0xDE, 0x26, 0x4F, 0xC8, 0x4E, 0x8B, 0x95, 0x0C, 0x5F,
+ 0xF2, 0x75, 0xD0, 0x52, 0x35, 0x46, 0x95, 0xA3},
+ // C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign G2
+ {0xD4, 0x87, 0xA5, 0x6F, 0x83, 0xB0, 0x74, 0x82, 0xE8, 0x5E, 0x96, 0x33,
+ 0x94, 0xC1, 0xEC, 0xC2, 0xC9, 0xE5, 0x1D, 0x09, 0x03, 0xEE, 0x94, 0x6B,
+ 0x02, 0xC3, 0x01, 0x58, 0x1E, 0xD9, 0x9E, 0x16},
+ // C=CN, O=WoSign CA Limited, CN=CA
+ // \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6
+ {0xD6, 0xF0, 0x34, 0xBD, 0x94, 0xAA, 0x23, 0x3F, 0x02, 0x97, 0xEC, 0xA4,
+ 0x24, 0x5B, 0x28, 0x39, 0x73, 0xE4, 0x47, 0xAA, 0x59, 0x0F, 0x31, 0x0C,
+ 0x77, 0xF4, 0x8F, 0xDF, 0x83, 0x11, 0x22, 0x54},
+ // C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA
+ // Certificate Services
+ {0xD7, 0xA7, 0xA0, 0xFB, 0x5D, 0x7E, 0x27, 0x31, 0xD7, 0x71, 0xE9, 0x48,
+ 0x4E, 0xBC, 0xDE, 0xF7, 0x1D, 0x5F, 0x0C, 0x3E, 0x0A, 0x29, 0x48, 0x78,
+ 0x2B, 0xC8, 0x3E, 0xE0, 0xEA, 0x69, 0x9E, 0xF4},
+ // C=DE, O=Deutscher Sparkassen Verlag GmbH, OU=S-TRUST Certification
+ // Services, CN=S-TRUST Universal Root CA
+ {0xD8, 0x0F, 0xEF, 0x91, 0x0A, 0xE3, 0xF1, 0x04, 0x72, 0x3B, 0x04, 0x5C,
+ 0xEC, 0x2D, 0x01, 0x9F, 0x44, 0x1C, 0xE6, 0x21, 0x3A, 0xDF, 0x15, 0x67,
+ 0x91, 0xE7, 0x0C, 0x17, 0x90, 0x11, 0x0A, 0x31},
+ // C=PL, O=Unizeto Sp. z o.o., CN=Certum CA
+ {0xD8, 0xE0, 0xFE, 0xBC, 0x1D, 0xB2, 0xE3, 0x8D, 0x00, 0x94, 0x0F, 0x37,
+ 0xD2, 0x7D, 0x41, 0x34, 0x4D, 0x99, 0x3E, 0x73, 0x4B, 0x99, 0xD5, 0x65,
+ 0x6D, 0x97, 0x78, 0xD4, 0xD8, 0x14, 0x36, 0x24},
+ // C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root EV CA
+ // 2
+ {0xD9, 0x5F, 0xEA, 0x3C, 0xA4, 0xEE, 0xDC, 0xE7, 0x4C, 0xD7, 0x6E, 0x75,
+ 0xFC, 0x6D, 0x1F, 0xF6, 0x2C, 0x44, 0x1F, 0x0F, 0xA8, 0xBC, 0x77, 0xF0,
+ 0x34, 0xB1, 0x9E, 0x5D, 0xB2, 0x58, 0x01, 0x5D},
+ // O=TeliaSonera, CN=TeliaSonera Root CA v1
+ {0xDD, 0x69, 0x36, 0xFE, 0x21, 0xF8, 0xF0, 0x77, 0xC1, 0x23, 0xA1, 0xA5,
+ 0x21, 0xC1, 0x22, 0x24, 0xF7, 0x22, 0x55, 0xB7, 0x3E, 0x03, 0xA7, 0x26,
+ 0x06, 0x93, 0xE8, 0xA2, 0x4B, 0x0F, 0xA3, 0x89},
+ // C=BE, O=Certipost s.a./n.v., CN=Certipost E-Trust TOP Root CA
+ {0xDD, 0xFF, 0x53, 0xEC, 0xD7, 0x74, 0x3B, 0x60, 0xBB, 0x7B, 0x27, 0x95,
+ 0xFF, 0x57, 0x32, 0xFA, 0x78, 0x5F, 0x9A, 0x14, 0xDF, 0x11, 0x20, 0xFB,
+ 0x40, 0xA3, 0x8C, 0xF8, 0x4C, 0xA2, 0xA5, 0x66},
+ // C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft
+ // Root Certificate Authority 2010
+ {0xDF, 0x54, 0x5B, 0xF9, 0x19, 0xA2, 0x43, 0x9C, 0x36, 0x98, 0x3B, 0x54,
+ 0xCD, 0xFC, 0x90, 0x3D, 0xFA, 0x4F, 0x37, 0xD3, 0x99, 0x6D, 0x8D, 0x84,
+ 0xB4, 0xC3, 0x1E, 0xEC, 0x6F, 0x3C, 0x16, 0x3E},
+ // C=ES, ST=Barcelona, L=Barcelona (see current address at
+ // http://www.anf.es/es/address-direccion.html ), O=ANF Autoridad de
+ // Certificacion, OU=ANF Clase 1
+ // CA/emailAddress=info@anf.es/serialNumber=G63287510, CN=ANF Global Root CA
+ {0xE0, 0xE1, 0x7A, 0xEA, 0x06, 0xCF, 0x9C, 0xE1, 0x2A, 0xAE, 0x81, 0x90,
+ 0x34, 0x5A, 0x2C, 0x59, 0x72, 0x01, 0x30, 0xA7, 0xD8, 0xFF, 0x72, 0xF3,
+ 0x74, 0x5A, 0xD7, 0x5D, 0xBA, 0xA3, 0x65, 0xB6},
+ // C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig Root R2
+ {0xE2, 0x3D, 0x4A, 0x03, 0x6D, 0x7B, 0x70, 0xE9, 0xF5, 0x95, 0xB1, 0x42,
+ 0x20, 0x79, 0xD2, 0xB9, 0x1E, 0xDF, 0xBB, 0x1F, 0xB6, 0x51, 0xA0, 0x63,
+ 0x3E, 0xAA, 0x8A, 0x9D, 0xC5, 0xF8, 0x07, 0x03},
+ // C=CN, O=CNNIC, CN=CNNIC ROOT
+ {0xE2, 0x83, 0x93, 0x77, 0x3D, 0xA8, 0x45, 0xA6, 0x79, 0xF2, 0x08, 0x0C,
+ 0xC7, 0xFB, 0x44, 0xA3, 0xB7, 0xA1, 0xC3, 0x79, 0x2C, 0xB7, 0xEB, 0x77,
+ 0x29, 0xFD, 0xCB, 0x6A, 0x8D, 0x99, 0xAE, 0xA7},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 4 Public Primary
+ // Certification Authority - G3
+ {0xE3, 0x89, 0x36, 0x0D, 0x0F, 0xDB, 0xAE, 0xB3, 0xD2, 0x50, 0x58, 0x4B,
+ 0x47, 0x30, 0x31, 0x4E, 0x22, 0x2F, 0x39, 0xC1, 0x56, 0xA0, 0x20, 0x14,
+ 0x4E, 0x8D, 0x96, 0x05, 0x61, 0x79, 0x15, 0x06},
+ // C=FR, O=Dhimyotis, CN=Certigna
+ {0xE3, 0xB6, 0xA2, 0xDB, 0x2E, 0xD7, 0xCE, 0x48, 0x84, 0x2F, 0x7A, 0xC5,
+ 0x32, 0x41, 0xC7, 0xB7, 0x1D, 0x54, 0x14, 0x4B, 0xFB, 0x40, 0xC1, 0x1F,
+ 0x3F, 0x1D, 0x0B, 0x42, 0xF5, 0xEE, 0xA1, 0x2D},
+ // C=TR, L=Gebze - Kocaeli, O=T\xC3\xBCrkiye Bilimsel ve Teknolojik
+ // Ara\xC5\x9Ft\xC4\xB1rma Kurumu - T\xC3\x9CB\xC4\xB0TAK, OU=Ulusal
+ // Elektronik ve Kriptoloji Ara\xC5\x9Ft\xC4\xB1rma Enstit\xC3\xBCs\xC3\xBC
+ // - UEKAE, OU=Kamu Sertifikasyon Merkezi, CN=T\xC3\x9CB\xC4\xB0TAK UEKAE
+ // K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xC4\xB1c\xC4\xB1s\xC4\xB1 -
+ // S\xC3\xBCr\xC3\xBCm 3
+ {0xE4, 0xC7, 0x34, 0x30, 0xD7, 0xA5, 0xB5, 0x09, 0x25, 0xDF, 0x43, 0x37,
+ 0x0A, 0x0D, 0x21, 0x6E, 0x9A, 0x79, 0xB9, 0xD6, 0xDB, 0x83, 0x73, 0xA0,
+ 0xC6, 0x9E, 0xB1, 0xCC, 0x31, 0xC7, 0xC5, 0x2A},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co., OU=DSTCA
+ // X2, CN=DST RootCA X2/emailAddress=ca@digsigtrust.com
+ {0xE5, 0x72, 0x10, 0xAB, 0x81, 0x2C, 0x8D, 0xF3, 0x08, 0x26, 0x7C, 0xB4,
+ 0x29, 0x1B, 0x98, 0xE9, 0x56, 0x59, 0x7C, 0xA3, 0x6E, 0xC2, 0xB9, 0x51,
+ 0x89, 0xEF, 0x17, 0x23, 0x39, 0x6B, 0xCA, 0xC8},
+ // C=BR, O=Serasa S.A., OU=Serasa CA III, CN=Serasa Certificate Authority
+ // III
+ {0xE5, 0xBD, 0xA8, 0x20, 0xE5, 0xCE, 0x15, 0xBF, 0xD0, 0x7B, 0xA1, 0x1F,
+ 0xFB, 0x1C, 0x7C, 0x8A, 0x59, 0x10, 0xCE, 0x1B, 0x90, 0x17, 0x5C, 0x34,
+ 0x30, 0x8B, 0xC2, 0x50, 0x04, 0x53, 0xCC, 0xDC},
+ // C=KR, O=Government of Korea, OU=GPKI, CN=Root CA
+ {0xE5, 0xC0, 0x1C, 0xB4, 0x09, 0x32, 0x79, 0xFA, 0xA1, 0x9F, 0xCF, 0xA2,
+ 0x4E, 0xA4, 0x3E, 0xB1, 0xB2, 0x6D, 0x07, 0xA6, 0x15, 0xAD, 0xF7, 0x24,
+ 0x01, 0x84, 0xA1, 0xE7, 0x16, 0xB7, 0x61, 0xC9},
+ // C=TR, O=Elektronik Bilgi Guvenligi A.S., CN=e-Guven Kok Elektronik
+ // Sertifika Hizmet Saglayicisi
+ {0xE6, 0x09, 0x07, 0x84, 0x65, 0xA4, 0x19, 0x78, 0x0C, 0xB6, 0xAC, 0x4C,
+ 0x1C, 0x0B, 0xFB, 0x46, 0x53, 0xD9, 0xD9, 0xCC, 0x6E, 0xB3, 0x94, 0x6E,
+ 0xB7, 0xF3, 0xD6, 0x99, 0x97, 0xBA, 0xD5, 0x98},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Class 2 CA, CN=TC
+ // TrustCenter Class 2 CA II
+ {0xE6, 0xB8, 0xF8, 0x76, 0x64, 0x85, 0xF8, 0x07, 0xAE, 0x7F, 0x8D, 0xAC,
+ 0x16, 0x70, 0x46, 0x1F, 0x07, 0xC0, 0xA1, 0x3E, 0xEF, 0x3A, 0x1F, 0xF7,
+ 0x17, 0x53, 0x8D, 0x7A, 0xBA, 0xD3, 0x91, 0xB4},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=Certification Authority,
+ // CN=SSC Root CA C
+ {0xE6, 0xE4, 0xA9, 0x51, 0xEC, 0xBF, 0x7D, 0x8E, 0xDC, 0x01, 0xBC, 0x87,
+ 0x3F, 0x7B, 0x6F, 0xD3, 0x58, 0x68, 0xBD, 0xB1, 0x0E, 0xD7, 0x86, 0xF3,
+ 0xA1, 0xB1, 0xEE, 0x16, 0xD8, 0xCE, 0xC3, 0xE9},
+ // C=JP, O=SECOM Trust.net, OU=Security Communication RootCA1
+ {0xE7, 0x5E, 0x72, 0xED, 0x9F, 0x56, 0x0E, 0xEC, 0x6E, 0xB4, 0x80, 0x00,
+ 0x73, 0xA4, 0x3F, 0xC3, 0xAD, 0x19, 0x19, 0x5A, 0x39, 0x22, 0x82, 0x01,
+ 0x78, 0x95, 0x97, 0x4A, 0x99, 0x02, 0x6B, 0x6C},
+ // C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ {0xE7, 0x68, 0x56, 0x34, 0xEF, 0xAC, 0xF6, 0x9A, 0xCE, 0x93, 0x9A, 0x6B,
+ 0x25, 0x5B, 0x7B, 0x4F, 0xAB, 0xEF, 0x42, 0x93, 0x5B, 0x50, 0xA2, 0x65,
+ 0xAC, 0xB5, 0xCB, 0x60, 0x27, 0xE4, 0x4E, 0x70},
+ // C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust
+ // RSA Certification Authority
+ {0xE7, 0x93, 0xC9, 0xB0, 0x2F, 0xD8, 0xAA, 0x13, 0xE2, 0x1C, 0x31, 0x22,
+ 0x8A, 0xCC, 0xB0, 0x81, 0x19, 0x64, 0x3B, 0x74, 0x9C, 0x89, 0x89, 0x64,
+ 0xB1, 0x74, 0x6D, 0x46, 0xC3, 0xD4, 0xCB, 0xD2},
+ // C=us, ST=Utah, L=Salt Lake City, O=Digital Signature Trust Co., OU=United
+ // Parcel Service, CN=DST (UPS) RootCA/emailAddress=ca@digsigtrust.com
+ {0xE8, 0x73, 0xD4, 0x08, 0x2A, 0x7B, 0x46, 0x32, 0x93, 0x4F, 0x48, 0xA5,
+ 0xCC, 0x1E, 0xE5, 0x00, 0x93, 0x2F, 0x66, 0x1E, 0x56, 0xC3, 0x46, 0x7C,
+ 0x5C, 0x84, 0xD3, 0x14, 0x47, 0x47, 0x6B, 0x0C},
+ // C=AT, O=A-Trust Ges. f\xFCr Sicherheitssysteme im elektr. Datenverkehr
+ // GmbH, OU=A-Trust-Qual-01, CN=A-Trust-Qual-01
+ {0xE8, 0xA2, 0xF4, 0x41, 0x65, 0x76, 0x78, 0x97, 0x5F, 0x2B, 0x97, 0xD7,
+ 0x75, 0x71, 0x9C, 0x7D, 0x49, 0xD9, 0x22, 0x34, 0x55, 0x45, 0x40, 0xEC,
+ 0x14, 0xD9, 0x2E, 0x16, 0xFE, 0x27, 0xD2, 0xCB},
+ // C=BR, O=Certisign Certificadora Digital Ltda., OU=Certisign - Autoridade
+ // Certificadora - AC2
+ {0xE8, 0xB2, 0x8D, 0x2A, 0x3D, 0x81, 0xF6, 0x3B, 0x4E, 0x44, 0x67, 0xC2,
+ 0x19, 0x0A, 0x63, 0x1F, 0xC0, 0x62, 0x35, 0x3B, 0x5F, 0x2D, 0x25, 0x85,
+ 0x1D, 0xDA, 0x6B, 0x64, 0x4A, 0xC7, 0x8B, 0x3F},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Qualified Root CA 1 2007:PN
+ {0xE8, 0xC6, 0xAA, 0x6B, 0x5F, 0x58, 0xA8, 0xF2, 0xA6, 0x36, 0x5C, 0xF9,
+ 0x8E, 0x65, 0x69, 0x35, 0x63, 0xA3, 0x8B, 0x7B, 0x2F, 0x32, 0xCF, 0x1B,
+ 0xE0, 0x6F, 0x2D, 0x22, 0x29, 0xD4, 0xBF, 0x59},
+ // C=BG, O=InfoNotary PLC, DC=root-ca, CN=InfoNotary CSP Root, OU=InfoNotary
+ // CSP Root/emailAddress=csp@infonotary.com
+ {0xEA, 0x7E, 0x31, 0x2E, 0xCE, 0x48, 0x7B, 0x4C, 0x0A, 0xA6, 0x3C, 0xC8,
+ 0x0A, 0xB9, 0xFC, 0xB3, 0x3C, 0x72, 0x05, 0x73, 0xF8, 0x94, 0x5F, 0x77,
+ 0x61, 0x74, 0x5F, 0xC6, 0x38, 0x63, 0xD3, 0x9D},
+ // C=RO, O=certSIGN, OU=certSIGN ROOT CA
+ {0xEA, 0xA9, 0x62, 0xC4, 0xFA, 0x4A, 0x6B, 0xAF, 0xEB, 0xE4, 0x15, 0x19,
+ 0x6D, 0x35, 0x1C, 0xCD, 0x88, 0x8D, 0x4F, 0x53, 0xF3, 0xFA, 0x8A, 0xE6,
+ 0xD7, 0xC4, 0x66, 0xA9, 0x4E, 0x60, 0x42, 0xBB},
+ // C=CH, O=admin, OU=Services, OU=Certification Authorities,
+ // CN=AdminCA-CD-T01
+ {0xEA, 0xC0, 0x22, 0x0C, 0x5C, 0x9F, 0xEC, 0xC5, 0x12, 0x1D, 0x37, 0x20,
+ 0x87, 0x2D, 0x06, 0x70, 0x7B, 0x52, 0x66, 0xBE, 0x25, 0xD4, 0xEB, 0xB5,
+ 0x6A, 0xB8, 0x04, 0xBB, 0xBF, 0x85, 0xFE, 0x03},
+ // C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign,
+ // Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary
+ // Certification Authority - G3
+ {0xEB, 0x04, 0xCF, 0x5E, 0xB1, 0xF3, 0x9A, 0xFA, 0x76, 0x2F, 0x2B, 0xB1,
+ 0x20, 0xF2, 0x96, 0xCB, 0xA5, 0x20, 0xC1, 0xB9, 0x7D, 0xB1, 0x58, 0x95,
+ 0x65, 0xB8, 0x1C, 0xB9, 0xA1, 0x7B, 0x72, 0x44},
+ // C=HU, L=Budapest, O=NetLock Kft.,
+ // OU=Tan\xC3\xBAs\xC3\xADtv\xC3\xA1nykiad\xC3\xB3k (Certification
+ // Services), CN=NetLock Platina (Class Platinum)
+ // F\xC5\x91tan\xC3\xBAs\xC3\xADtv\xC3\xA1ny
+ {0xEB, 0x7E, 0x05, 0xAA, 0x58, 0xE7, 0xBD, 0x32, 0x8A, 0x28, 0x2B, 0xF8,
+ 0x86, 0x70, 0x33, 0xF3, 0xC0, 0x35, 0x34, 0x2B, 0x51, 0x6E, 0xE8, 0x5C,
+ 0x01, 0x67, 0x3D, 0xFF, 0xFF, 0xBB, 0xFE, 0x58},
+ // C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
+ {0xEB, 0xD4, 0x10, 0x40, 0xE4, 0xBB, 0x3E, 0xC7, 0x42, 0xC9, 0xE3, 0x81,
+ 0xD3, 0x1E, 0xF2, 0xA4, 0x1A, 0x48, 0xB6, 0x68, 0x5C, 0x96, 0xE7, 0xCE,
+ 0xF3, 0xC1, 0xDF, 0x6C, 0xD4, 0x33, 0x1C, 0x99},
+ // C=DE, O=TC TrustCenter GmbH, OU=TC TrustCenter Universal CA, CN=TC
+ // TrustCenter Universal CA I
+ {0xEB, 0xF3, 0xC0, 0x2A, 0x87, 0x89, 0xB1, 0xFB, 0x7D, 0x51, 0x19, 0x95,
+ 0xD6, 0x63, 0xB7, 0x29, 0x06, 0xD9, 0x13, 0xCE, 0x0D, 0x5E, 0x10, 0x56,
+ 0x8A, 0x8A, 0x77, 0xE2, 0x58, 0x61, 0x67, 0xE7},
+ // emailAddress=pki@sk.ee, C=EE, O=AS Sertifitseerimiskeskus, CN=Juur-SK
+ {0xEC, 0xC3, 0xE9, 0xC3, 0x40, 0x75, 0x03, 0xBE, 0xE0, 0x91, 0xAA, 0x95,
+ 0x2F, 0x41, 0x34, 0x8F, 0xF8, 0x8B, 0xAA, 0x86, 0x3B, 0x22, 0x64, 0xBE,
+ 0xFA, 0xC8, 0x07, 0x90, 0x15, 0x74, 0xE9, 0x39},
+ // C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 Root CA
+ {0xED, 0xF7, 0xEB, 0xBC, 0xA2, 0x7A, 0x2A, 0x38, 0x4D, 0x38, 0x7B, 0x7D,
+ 0x40, 0x10, 0xC6, 0x66, 0xE2, 0xED, 0xB4, 0x84, 0x3E, 0x4C, 0x29, 0xB4,
+ 0xAE, 0x1D, 0x5B, 0x93, 0x32, 0xE6, 0xB2, 0x4D},
+ // C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 EV 2009
+ {0xEE, 0xC5, 0x49, 0x6B, 0x98, 0x8C, 0xE9, 0x86, 0x25, 0xB9, 0x34, 0x09,
+ 0x2E, 0xEC, 0x29, 0x08, 0xBE, 0xD0, 0xB0, 0xF3, 0x16, 0xC2, 0xD4, 0x73,
+ 0x0C, 0x84, 0xEA, 0xF1, 0xF3, 0xD3, 0x48, 0x81},
+ // C=ES, ST=Madrid, L=Madrid, O=IPS Certification Authority s.l. ipsCA,
+ // OU=ipsCA, CN=ipsCA Main CA Root/emailAddress=main01@ipsca.com
+ {0xEE, 0xFC, 0xA8, 0x88, 0xDB, 0x44, 0x2C, 0xEA, 0x1F, 0x03, 0xFA, 0xC5,
+ 0xDE, 0x5B, 0x1A, 0xF2, 0x10, 0xAE, 0x03, 0xF5, 0xE1, 0x65, 0x8D, 0xDB,
+ 0x88, 0x0C, 0x64, 0x5E, 0x78, 0x62, 0x45, 0x46},
+ // C=EU, O=AC Camerfirma SA CIF A82743287, OU=http://www.chambersign.org,
+ // CN=Global Chambersign Root
+ {0xEF, 0x3C, 0xB4, 0x17, 0xFC, 0x8E, 0xBF, 0x6F, 0x97, 0x87, 0x6C, 0x9E,
+ 0x4E, 0xCE, 0x39, 0xDE, 0x1E, 0xA5, 0xFE, 0x64, 0x91, 0x41, 0xD1, 0x02,
+ 0x8B, 0x7D, 0x11, 0xC0, 0xB2, 0x29, 0x8C, 0xED},
+ // C=BE, O=Certipost s.a./n.v., CN=Certipost E-Trust Primary Normalised CA
+ {0xF0, 0x03, 0x55, 0xEE, 0xF1, 0x01, 0xC7, 0xDF, 0x4E, 0x46, 0xCC, 0xE6,
+ 0x41, 0x7D, 0xFF, 0xCE, 0x3D, 0xB8, 0x2D, 0xBB, 0x13, 0x69, 0xC3, 0xB4,
+ 0x39, 0xC4, 0xE3, 0x3B, 0xEE, 0x44, 0x5C, 0x42},
+ // C=FI, ST=Finland, O=Vaestorekisterikeskus CA, OU=Certification Authority
+ // Services, OU=Varmennepalvelut, CN=VRK Gov. Root CA
+ {0xF0, 0x08, 0x73, 0x3E, 0xC5, 0x00, 0xDC, 0x49, 0x87, 0x63, 0xCC, 0x92,
+ 0x64, 0xC6, 0xFC, 0xEA, 0x40, 0xEC, 0x22, 0x00, 0x0E, 0x92, 0x7D, 0x05,
+ 0x3C, 0xE9, 0xC9, 0x0B, 0xFA, 0x04, 0x6C, 0xB2},
+ // C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root CA 2
+ {0xF0, 0x9B, 0x12, 0x2C, 0x71, 0x14, 0xF4, 0xA0, 0x9B, 0xD4, 0xEA, 0x4F,
+ 0x4A, 0x99, 0xD5, 0x58, 0xB4, 0x6E, 0x4C, 0x25, 0xCD, 0x81, 0x14, 0x0D,
+ 0x29, 0xC0, 0x56, 0x13, 0x91, 0x4C, 0x38, 0x41},
+ // C=LT, O=Skaitmeninio sertifikavimo centras, OU=Certification Authority,
+ // CN=SSC Root CA A
+ {0xF1, 0xB1, 0x3F, 0x5C, 0x9A, 0x32, 0x64, 0x03, 0xB0, 0xF3, 0x1B, 0xBE,
+ 0x76, 0x99, 0xCD, 0x17, 0xC7, 0xD1, 0xC0, 0xB9, 0x81, 0x58, 0x6D, 0xD1,
+ 0xA7, 0xB2, 0x19, 0xC5, 0x25, 0x08, 0xFE, 0x99},
+ // C=US, O=SecureTrust Corporation, CN=SecureTrust CA
+ {0xF1, 0xC1, 0xB5, 0x0A, 0xE5, 0xA2, 0x0D, 0xD8, 0x03, 0x0E, 0xC9, 0xF6,
+ 0xBC, 0x24, 0x82, 0x3D, 0xD3, 0x67, 0xB5, 0x25, 0x57, 0x59, 0xB4, 0xE7,
+ 0x1B, 0x61, 0xFC, 0xE9, 0xF7, 0x37, 0x5D, 0x73},
+ // C=ES, ST=BARCELONA, L=BARCELONA, O=IPS Seguridad CA, OU=Certificaciones,
+ // CN=IPS SERVIDORES/emailAddress=ips@mail.ips.es
+ {0xF1, 0xF3, 0xCC, 0x20, 0x7A, 0x6D, 0x47, 0x94, 0x7B, 0x8C, 0xB9, 0xC3,
+ 0x04, 0x22, 0x22, 0x9D, 0xE0, 0xD7, 0x1F, 0xB8, 0x67, 0xE0, 0xB9, 0xA3,
+ 0xED, 0xA0, 0x8E, 0x0E, 0x17, 0x36, 0xBC, 0x28},
+ // C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,
+ // OU=A-Trust-Qual-02, CN=A-Trust-Qual-02
+ {0xF2, 0x86, 0x30, 0xBA, 0xBF, 0x25, 0x6E, 0x56, 0x7B, 0x58, 0x21, 0x06,
+ 0x9F, 0xCF, 0x13, 0x14, 0x8A, 0xB9, 0xA2, 0x3E, 0x28, 0xFC, 0x0D, 0x70,
+ 0x61, 0x5A, 0xAE, 0x6E, 0xD2, 0x84, 0xF4, 0xC8},
+ // CN=Atos TrustedRoot 2011, O=Atos, C=DE
+ {0xF3, 0x56, 0xBE, 0xA2, 0x44, 0xB7, 0xA9, 0x1E, 0xB3, 0x5D, 0x53, 0xCA,
+ 0x9A, 0xD7, 0x86, 0x4A, 0xCE, 0x01, 0x8E, 0x2D, 0x35, 0xD5, 0xF8, 0xF9,
+ 0x6D, 0xDF, 0x68, 0xA6, 0xF4, 0x1A, 0xA4, 0x74},
+ // C=IN, O=India PKI, CN=CCA India 2007
+ {0xF3, 0x75, 0xE2, 0xF7, 0x7A, 0x10, 0x8B, 0xAC, 0xC4, 0x23, 0x48, 0x94,
+ 0xA9, 0xAF, 0x30, 0x8E, 0xDE, 0xCA, 0x1A, 0xCD, 0x8F, 0xBD, 0xE0, 0xE7,
+ 0xAA, 0xA9, 0x63, 0x4E, 0x9D, 0xAF, 0x7E, 0x1C},
+ // OU=Copyright (c) 1997 Microsoft Corp., OU=Microsoft Corporation,
+ // CN=Microsoft Root Authority
+ {0xF3, 0x84, 0x06, 0xE5, 0x40, 0xD7, 0xA9, 0xD9, 0x0C, 0xB4, 0xA9, 0x47,
+ 0x92, 0x99, 0x64, 0x0F, 0xFB, 0x6D, 0xF9, 0xE2, 0x24, 0xEC, 0xC7, 0xA0,
+ 0x1C, 0x0D, 0x95, 0x58, 0xD8, 0xDA, 0xD7, 0x7D},
+ // C=ES, O=Agencia Notarial de Certificacion S.L.U. - CIF B83395988,
+ // CN=ANCERT Certificados CGN V2
+ {0xF4, 0x33, 0x6B, 0xC2, 0xAC, 0x75, 0x95, 0x0B, 0xEC, 0xCF, 0x1C, 0x1F,
+ 0x2F, 0x9D, 0xA6, 0xDD, 0xDA, 0xFD, 0x1F, 0x41, 0x16, 0x1C, 0xA7, 0x1F,
+ 0x59, 0xC7, 0x68, 0x89, 0xBD, 0x47, 0x40, 0x33},
+ // L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 1
+ // Policy Validation Authority,
+ // CN=http://www.valicert.com//emailAddress=info@valicert.com
+ {0xF4, 0xC1, 0x49, 0x55, 0x1A, 0x30, 0x13, 0xA3, 0x5B, 0xC7, 0xBF, 0xFE,
+ 0x17, 0xA7, 0xF3, 0x44, 0x9B, 0xC1, 0xAB, 0x5B, 0x5A, 0x0A, 0xE7, 0x4B,
+ 0x06, 0xC2, 0x3B, 0x90, 0x00, 0x4C, 0x01, 0x04},
+ // C=IT, O=SIA S.p.A., L=Milano, CN=SIA Secure Server CA
+ {0xF5, 0x63, 0xC5, 0xC3, 0xE5, 0x12, 0xE6, 0x3B, 0x97, 0xB5, 0x43, 0x8F,
+ 0x2B, 0xD4, 0xA9, 0xAE, 0x78, 0xA4, 0xF9, 0xEA, 0xD9, 0x2B, 0xCC, 0x34,
+ 0xFE, 0x97, 0x3B, 0xDC, 0x7C, 0x6D, 0x21, 0x48},
+ // C=SE, O=Swedish Social Insurance Agency, CN=Swedish Government Root
+ // Authority v1
+ {0xF6, 0x57, 0xA6, 0x33, 0xEE, 0xB9, 0xBC, 0x5D, 0x15, 0xA4, 0x61, 0x75,
+ 0x17, 0x49, 0xEA, 0x4B, 0x31, 0x67, 0x27, 0xDC, 0xF1, 0xA9, 0xF9, 0x86,
+ 0xB5, 0x45, 0x84, 0x45, 0xF6, 0x48, 0x5D, 0xDE},
+ // C=UY, O=ADMINISTRACION NACIONAL DE CORREOS, OU=SERVICIOS ELECTRONICOS,
+ // CN=SERVICIOS DE CERTIFICACION - A.N.C./mail=correo_cert@correo.com.uy
+ {0xF7, 0x73, 0xBC, 0x65, 0x65, 0x9F, 0x1B, 0xC5, 0x90, 0x87, 0xBF, 0x21,
+ 0x4E, 0xEA, 0xD8, 0x64, 0x01, 0x0D, 0x58, 0x87, 0xCD, 0x2C, 0xD8, 0x4E,
+ 0x4F, 0x1B, 0xA7, 0x52, 0x3F, 0xE5, 0x56, 0x40},
+ // C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig Root R1
+ {0xF9, 0x6F, 0x23, 0xF4, 0xC3, 0xE7, 0x9C, 0x07, 0x7A, 0x46, 0x98, 0x8D,
+ 0x5A, 0xF5, 0x90, 0x06, 0x76, 0xA0, 0xF0, 0x39, 0xCB, 0x64, 0x5D, 0xD1,
+ 0x75, 0x49, 0xB2, 0x16, 0xC8, 0x24, 0x40, 0xCE},
+ // C=HK, O=Hongkong Post, CN=Hongkong Post Root CA 1
+ {0xF9, 0xE6, 0x7D, 0x33, 0x6C, 0x51, 0x00, 0x2A, 0xC0, 0x54, 0xC6, 0x32,
+ 0x02, 0x2D, 0x66, 0xDD, 0xA2, 0xE7, 0xE3, 0xFF, 0xF1, 0x0A, 0xD0, 0x61,
+ 0xED, 0x31, 0xD8, 0xBB, 0xB4, 0x10, 0xCF, 0xB2},
+ // C=PL, O=Krajowa Izba Rozliczeniowa S.A., CN=SZAFIR ROOT CA
+ {0xFA, 0xBC, 0xF5, 0x19, 0x7C, 0xDD, 0x7F, 0x45, 0x8A, 0xC3, 0x38, 0x32,
+ 0xD3, 0x28, 0x40, 0x21, 0xDB, 0x24, 0x25, 0xFD, 0x6B, 0xEA, 0x7A, 0x2E,
+ 0x69, 0xB7, 0x48, 0x6E, 0x8F, 0x51, 0xF9, 0xCC},
+ // C=BR, O=ICP-Brasil, OU=Instituto Nacional de Tecnologia da Informacao -
+ // ITI, CN=Autoridade Certificadora Raiz Brasileira v2
+ {0xFB, 0x47, 0xD9, 0x2A, 0x99, 0x09, 0xFD, 0x4F, 0xA9, 0xBE, 0xC0, 0x27,
+ 0x37, 0x54, 0x3E, 0x1F, 0x35, 0x14, 0xCE, 0xD7, 0x47, 0x40, 0x7A, 0x8D,
+ 0x9C, 0xFA, 0x39, 0x7B, 0x09, 0x15, 0x06, 0x7C},
+ // C=IT, O=SIA S.p.A., L=Milano, CN=SIA Secure Client CA
+ {0xFC, 0x0A, 0x0F, 0xE2, 0x7C, 0x9D, 0xC1, 0x3C, 0x81, 0x23, 0x8A, 0x59,
+ 0x13, 0xA1, 0xDA, 0xF8, 0x18, 0x41, 0x68, 0xBE, 0xB7, 0xE5, 0xA4, 0x51,
+ 0x2A, 0x77, 0x1F, 0xD4, 0xF4, 0x53, 0x65, 0x1D},
+ // C=SE, O=Inera AB, CN=SITHS Root CA v1
+ {0xFC, 0x50, 0xB2, 0x6B, 0xDC, 0x4A, 0x8F, 0xDF, 0x13, 0x44, 0xCC, 0x80,
+ 0x15, 0x7A, 0xE1, 0x3A, 0xC6, 0x71, 0xE2, 0x70, 0x6F, 0xAC, 0xFC, 0x06,
+ 0x05, 0xFE, 0x34, 0xE2, 0x49, 0xEB, 0x72, 0xD6},
+ // C=FR, O=Certinomis, OU=0002 433998903, CN=Certinomis - Autorit\xC3\xA9
+ // Racine
+ {0xFC, 0xBF, 0xE2, 0x88, 0x62, 0x06, 0xF7, 0x2B, 0x27, 0x59, 0x3C, 0x8B,
+ 0x07, 0x02, 0x97, 0xE1, 0x2D, 0x76, 0x9E, 0xD1, 0x0E, 0xD7, 0x93, 0x07,
+ 0x05, 0xA8, 0x09, 0x8E, 0xFF, 0xC1, 0x4D, 0x17},
+ // C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center,
+ // CN=T-TeleSec GlobalRoot Class 3
+ {0xFD, 0x73, 0xDA, 0xD3, 0x1C, 0x64, 0x4F, 0xF1, 0xB4, 0x3B, 0xEF, 0x0C,
+ 0xCD, 0xDA, 0x96, 0x71, 0x0B, 0x9C, 0xD9, 0x87, 0x5E, 0xCA, 0x7E, 0x31,
+ 0x70, 0x7A, 0xF3, 0xE9, 0x6D, 0x52, 0x2B, 0xBD},
+ // C=SI, O=Halcom, CN=Halcom CA PO 2
+ {0xFE, 0x71, 0x14, 0xD0, 0x7A, 0x14, 0x77, 0x59, 0x89, 0x1F, 0xF3, 0x7B,
+ 0x4F, 0x53, 0xEB, 0x43, 0x56, 0x82, 0x96, 0xBC, 0x3B, 0xF8, 0x9B, 0xC1,
+ 0x2C, 0xAF, 0xB1, 0x86, 0x98, 0x5E, 0xF2, 0x8D},
+ // C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ {0xFF, 0x85, 0x6A, 0x2D, 0x25, 0x1D, 0xCD, 0x88, 0xD3, 0x66, 0x56, 0xF4,
+ 0x50, 0x12, 0x67, 0x98, 0xCF, 0xAB, 0xAA, 0xDE, 0x40, 0x79, 0x9C, 0x72,
+ 0x2D, 0xE4, 0xD2, 0xB5, 0xDB, 0x36, 0xA7, 0x3A},
+ // C=BR, O=Serasa S.A., OU=Serasa CA II, CN=Serasa Certificate Authority II
+ {0xFF, 0xCE, 0xF2, 0x22, 0x4E, 0x29, 0xB0, 0xB3, 0x6E, 0xC8, 0x31, 0x4E,
+ 0x68, 0x68, 0x22, 0xF3, 0xAC, 0x0F, 0x1C, 0x5E, 0x0C, 0x2D, 0x5C, 0x0E,
+ 0xB2, 0x48, 0x4C, 0xE7, 0xE2, 0x54, 0x0F, 0xD0},
};
#endif // NET_CERT_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_
diff --git a/chromium/net/cert/x509_certificate_mac.cc b/chromium/net/cert/x509_certificate_mac.cc
index 64457e4d7e1..e27576ab265 100644
--- a/chromium/net/cert/x509_certificate_mac.cc
+++ b/chromium/net/cert/x509_certificate_mac.cc
@@ -148,8 +148,8 @@ void AddCertificatesFromBytes(const char* data, size_t length,
X509Certificate::OSCertHandles* output) {
SecExternalFormat input_format = format;
ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy(
- kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), length,
- kCFAllocatorNull));
+ kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
+ base::checked_cast<CFIndex>(length), kCFAllocatorNull));
CFArrayRef items = NULL;
OSStatus status;
@@ -298,7 +298,8 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
+ const char* data,
+ size_t length) {
CSSM_DATA cert_data;
cert_data.Data = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(data));
cert_data.Length = length;
@@ -319,7 +320,9 @@ X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
- const char* data, int length, Format format) {
+ const char* data,
+ size_t length,
+ Format format) {
OSCertHandles results;
switch (format) {
diff --git a/chromium/net/cert/x509_certificate_net_log_param.cc b/chromium/net/cert/x509_certificate_net_log_param.cc
index 72b1e919aa7..0a1bc8ed85b 100644
--- a/chromium/net/cert/x509_certificate_net_log_param.cc
+++ b/chromium/net/cert/x509_certificate_net_log_param.cc
@@ -5,6 +5,7 @@
#include "net/cert/x509_certificate_net_log_param.h"
#include <string>
+#include <utility>
#include <vector>
#include "base/values.h"
@@ -21,8 +22,8 @@ scoped_ptr<base::Value> NetLogX509CertificateCallback(
certificate->GetPEMEncodedChain(&encoded_chain);
for (size_t i = 0; i < encoded_chain.size(); ++i)
certs->Append(new base::StringValue(encoded_chain[i]));
- dict->Set("certificates", certs.Pass());
- return dict.Pass();
+ dict->Set("certificates", std::move(certs));
+ return std::move(dict);
}
} // namespace net
diff --git a/chromium/net/cert/x509_certificate_nss.cc b/chromium/net/cert/x509_certificate_nss.cc
index f8646cb0369..1c5359198bc 100644
--- a/chromium/net/cert/x509_certificate_nss.cc
+++ b/chromium/net/cert/x509_certificate_nss.cc
@@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
@@ -41,7 +42,7 @@ void X509Certificate::Initialize() {
// static
X509Certificate* X509Certificate::CreateFromBytesWithNickname(
const char* data,
- int length,
+ size_t length,
const char* nickname) {
OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data,
length,
@@ -160,19 +161,16 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
+ const char* data,
+ size_t length) {
return CreateOSCertHandleFromBytesWithNickname(data, length, NULL);
}
// static
X509Certificate::OSCertHandle
-X509Certificate::CreateOSCertHandleFromBytesWithNickname(
- const char* data,
- int length,
- const char* nickname) {
- if (length < 0)
- return NULL;
-
+X509Certificate::CreateOSCertHandleFromBytesWithNickname(const char* data,
+ size_t length,
+ const char* nickname) {
crypto::EnsureNSSInit();
if (!NSS_IsInitialized())
@@ -180,7 +178,7 @@ X509Certificate::CreateOSCertHandleFromBytesWithNickname(
SECItem der_cert;
der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
- der_cert.len = length;
+ der_cert.len = base::checked_cast<unsigned>(length);
der_cert.type = siDERCertBuffer;
// Parse into a certificate structure.
@@ -192,7 +190,7 @@ X509Certificate::CreateOSCertHandleFromBytesWithNickname(
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
Format format) {
return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
}
diff --git a/chromium/net/cert/x509_certificate_openssl.cc b/chromium/net/cert/x509_certificate_openssl.cc
index 6e803619db7..ec31e6e371b 100644
--- a/chromium/net/cert/x509_certificate_openssl.cc
+++ b/chromium/net/cert/x509_certificate_openssl.cc
@@ -13,7 +13,9 @@
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
+#include "base/macros.h"
#include "base/memory/singleton.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
@@ -38,7 +40,8 @@ using ScopedGENERAL_NAMES =
crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
void CreateOSCertHandlesFromPKCS7Bytes(
- const char* data, int length,
+ const char* data,
+ size_t length,
X509Certificate::OSCertHandles* handles) {
crypto::EnsureOpenSSLInit();
crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
@@ -260,24 +263,23 @@ SHA1HashValue X509Certificate::CalculateCAFingerprint(
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
- if (length < 0)
- return NULL;
+ const char* data,
+ size_t length) {
crypto::EnsureOpenSSLInit();
const unsigned char* d2i_data =
reinterpret_cast<const unsigned char*>(data);
// Don't cache this data for x509_util::GetDER as this wire format
// may be not be identical from the i2d_X509 roundtrip.
- X509* cert = d2i_X509(NULL, &d2i_data, length);
+ X509* cert = d2i_X509(NULL, &d2i_data, base::checked_cast<long>(length));
return cert;
}
// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
- const char* data, int length, Format format) {
+ const char* data,
+ size_t length,
+ Format format) {
OSCertHandles results;
- if (length < 0)
- return results;
switch (format) {
case FORMAT_SINGLE_CERTIFICATE: {
diff --git a/chromium/net/cert/x509_certificate_unittest.cc b/chromium/net/cert/x509_certificate_unittest.cc
index ec9342ac852..362f7ff0991 100644
--- a/chromium/net/cert/x509_certificate_unittest.cc
+++ b/chromium/net/cert/x509_certificate_unittest.cc
@@ -1175,7 +1175,7 @@ const struct PublicKeyInfoTestData {
// need to be renegerated with a larger key. See https://crbug.com/472291.
{"large_key.pem", 0, X509Certificate::kPublicKeyTypeUnknown},
#else
- {"large_key.pem", 4104, X509Certificate::kPublicKeyTypeRSA},
+ {"large_key.pem", 8200, X509Certificate::kPublicKeyTypeRSA},
#endif
};
diff --git a/chromium/net/cert/x509_certificate_win.cc b/chromium/net/cert/x509_certificate_win.cc
index 808a2847f9b..d2077821b8c 100644
--- a/chromium/net/cert/x509_certificate_win.cc
+++ b/chromium/net/cert/x509_certificate_win.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/sha1.h"
#include "base/strings/string_util.h"
@@ -94,7 +95,7 @@ void AddCertsFromStore(HCERTSTORE store,
X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) {
X509Certificate::OSCertHandles results;
CERT_BLOB data_blob;
- data_blob.cbData = length;
+ data_blob.cbData = base::checked_cast<DWORD>(length);
data_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(data));
HCERTSTORE out_store = NULL;
@@ -250,18 +251,25 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
- const char* data, int length) {
- OSCertHandle cert_handle = NULL;
+ const char* data,
+ size_t length) {
+ if (!base::IsValueInRangeForNumericType<DWORD>(length))
+ return nullptr;
+ OSCertHandle cert_handle = nullptr;
if (!CertAddEncodedCertificateToStore(
- NULL, X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(data),
- length, CERT_STORE_ADD_USE_EXISTING, &cert_handle))
- return NULL;
+ NULL, X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(data),
+ base::checked_cast<DWORD>(length), CERT_STORE_ADD_USE_EXISTING,
+ &cert_handle)) {
+ return nullptr;
+ }
return cert_handle;
}
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
- const char* data, int length, Format format) {
+ const char* data,
+ size_t length,
+ Format format) {
OSCertHandles results;
switch (format) {
case FORMAT_SINGLE_CERTIFICATE: {
diff --git a/chromium/net/cert/x509_util.h b/chromium/net/cert/x509_util.h
index a1c29689468..fb8c20f080d 100644
--- a/chromium/net/cert/x509_util.h
+++ b/chromium/net/cert/x509_util.h
@@ -6,6 +6,7 @@
#define NET_CERT_X509_UTIL_H_
#include <stdint.h>
+
#include <string>
#include "base/memory/ref_counted.h"
@@ -30,14 +31,6 @@ enum DigestAlgorithm {
DIGEST_SHA256
};
-// Returns true if the times can be used to create an X.509 certificate.
-// Certificates can accept dates from Jan 1st, 1 to Dec 31, 9999. A bug in NSS
-// limited the range to 1950-9999
-// (https://bugzilla.mozilla.org/show_bug.cgi?id=786531). This function will
-// return whether it is supported by the currently used crypto library.
-NET_EXPORT_PRIVATE bool IsSupportedValidityRange(base::Time not_valid_before,
- base::Time not_valid_after);
-
// Creates a public-private keypair and a self-signed certificate.
// Subject, serial number and validity period are given as parameters.
// The certificate is signed by the private key in |key|. The key length and
diff --git a/chromium/net/cert/x509_util_android.cc b/chromium/net/cert/x509_util_android.cc
index 2a91f4a2792..ee47845f57e 100644
--- a/chromium/net/cert/x509_util_android.cc
+++ b/chromium/net/cert/x509_util_android.cc
@@ -5,7 +5,7 @@
#include "net/cert/x509_util_android.h"
#include "base/android/build_info.h"
-#include "base/android/jni_android.h"
+#include "base/android/context_utils.h"
#include "base/metrics/histogram_macros.h"
#include "jni/X509Util_jni.h"
#include "net/cert/cert_database.h"
@@ -27,16 +27,6 @@ void RecordCertVerifyCapabilitiesHistogram(JNIEnv* env,
}
}
-ScopedJavaLocalRef<jobject> GetApplicationContext(
- JNIEnv* env,
- const JavaParamRef<jclass>& clazz) {
- ScopedJavaLocalRef<jobject> r;
- // Must use Reset to force creation of a new local ref, instead of trying to
- // adopt the global-ref'ed jobject as a local ref as the constructor would.
- r.Reset(env, base::android::GetApplicationContext());
- return r;
-}
-
bool RegisterX509Util(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/chromium/net/cert/x509_util_nss.cc b/chromium/net/cert/x509_util_nss.cc
index fa6dc1c652a..2dbff2c76fc 100644
--- a/chromium/net/cert/x509_util_nss.cc
+++ b/chromium/net/cert/x509_util_nss.cc
@@ -180,19 +180,6 @@ bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
return true;
}
-bool IsSupportedValidityRange(base::Time not_valid_before,
- base::Time not_valid_after) {
- CERTValidity* validity = CERT_CreateValidity(
- crypto::BaseTimeToPRTime(not_valid_before),
- crypto::BaseTimeToPRTime(not_valid_after));
-
- if (!validity)
- return false;
-
- CERT_DestroyValidity(validity);
- return true;
-}
-
} // namespace x509_util
} // namespace net
diff --git a/chromium/net/cert/x509_util_nss.h b/chromium/net/cert/x509_util_nss.h
index bb9bed955cd..55e562effba 100644
--- a/chromium/net/cert/x509_util_nss.h
+++ b/chromium/net/cert/x509_util_nss.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_X509_UTIL_NSS_H_
#define NET_CERT_X509_UTIL_NSS_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
@@ -47,7 +49,7 @@ void GetSubjectAltName(CERTCertificate* cert_handle,
// |format|. Returns an empty collection on failure.
X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
X509Certificate::Format format);
// Reads a single certificate from |pickle_iter| and returns a platform-specific
diff --git a/chromium/net/cert/x509_util_nss_certs.cc b/chromium/net/cert/x509_util_nss_certs.cc
index 78112b44f59..1ec360d31e6 100644
--- a/chromium/net/cert/x509_util_nss_certs.cc
+++ b/chromium/net/cert/x509_util_nss_certs.cc
@@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
+#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "crypto/ec_private_key.h"
@@ -201,11 +202,9 @@ void GetSubjectAltName(CERTCertificate* cert_handle,
X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
const char* data,
- int length,
+ size_t length,
X509Certificate::Format format) {
X509Certificate::OSCertHandles results;
- if (length < 0)
- return results;
crypto::EnsureNSSInit();
@@ -224,8 +223,9 @@ X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
// Make a copy since CERT_DecodeCertPackage may modify it
std::vector<char> data_copy(data, data + length);
- SECStatus result = CERT_DecodeCertPackage(&data_copy[0], length,
- CollectCertsCallback, &results);
+ SECStatus result = CERT_DecodeCertPackage(
+ data_copy.data(), base::checked_cast<int>(data_copy.size()),
+ CollectCertsCallback, &results);
if (result != SECSuccess)
results.clear();
break;
diff --git a/chromium/net/cert/x509_util_openssl.cc b/chromium/net/cert/x509_util_openssl.cc
index baf7d127613..c81a3a49b39 100644
--- a/chromium/net/cert/x509_util_openssl.cc
+++ b/chromium/net/cert/x509_util_openssl.cc
@@ -4,6 +4,7 @@
#include "net/cert/x509_util_openssl.h"
+#include <limits.h>
#include <openssl/asn1.h>
#include <openssl/mem.h>
@@ -11,6 +12,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "crypto/ec_private_key.h"
@@ -197,39 +199,6 @@ base::LazyInstance<DERCacheInitSingleton>::Leaky g_der_cache_singleton =
} // namespace
-bool IsSupportedValidityRange(base::Time not_valid_before,
- base::Time not_valid_after) {
- if (not_valid_before > not_valid_after)
- return false;
-
- // The validity field of a certificate can only encode years 1-9999.
-
- // Compute the base::Time values corresponding to Jan 1st,0001 and
- // Jan 1st, 10000 respectively. Done by using the pre-computed numbers
- // of days between these dates and the Unix epoch, i.e. Jan 1st, 1970,
- // using the following Python script:
- //
- // from datetime import date as D
- // print (D(1970,1,1)-D(1,1,1)) # -> 719162 days
- // print (D(9999,12,31)-D(1970,1,1)) # -> 2932896 days
- //
- // Note: This ignores leap seconds, but should be enough in practice.
- //
- const int64_t kDaysFromYear0001ToUnixEpoch = 719162;
- const int64_t kDaysFromUnixEpochToYear10000 = 2932896 + 1;
- const base::Time kEpoch = base::Time::UnixEpoch();
- const base::Time kYear0001 = kEpoch -
- base::TimeDelta::FromDays(kDaysFromYear0001ToUnixEpoch);
- const base::Time kYear10000 = kEpoch +
- base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000);
-
- if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 ||
- not_valid_after < kYear0001 || not_valid_after >= kYear10000)
- return false;
-
- return true;
-}
-
bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
DigestAlgorithm alg,
const std::string& common_name,
diff --git a/chromium/net/cert/x509_util_openssl_unittest.cc b/chromium/net/cert/x509_util_openssl_unittest.cc
deleted file mode 100644
index 9eebff8a32e..00000000000
--- a/chromium/net/cert/x509_util_openssl_unittest.cc
+++ /dev/null
@@ -1,41 +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 "base/memory/scoped_ptr.h"
-#include "crypto/ec_private_key.h"
-#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
-#include "net/cert/x509_util.h"
-#include "net/cert/x509_util_openssl.h"
-#include "net/ssl/scoped_openssl_types.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-TEST(X509UtilOpenSSLTest, IsSupportedValidityRange) {
- base::Time now = base::Time::Now();
- EXPECT_TRUE(x509_util::IsSupportedValidityRange(now, now));
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(
- now, now - base::TimeDelta::FromSeconds(1)));
-
- // See x509_util_openssl.cc to see how these were computed.
- const int64_t kDaysFromYear0001ToUnixEpoch = 719162;
- const int64_t kDaysFromUnixEpochToYear10000 = 2932896 + 1;
-
- // When computing too_old / too_late, add one day to account for
- // possible leap seconds.
- base::Time too_old = base::Time::UnixEpoch() -
- base::TimeDelta::FromDays(kDaysFromYear0001ToUnixEpoch + 1);
-
- base::Time too_late = base::Time::UnixEpoch() +
- base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000 + 1);
-
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_old, too_old));
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_old, now));
-
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(now, too_late));
- EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_late, too_late));
-}
-
-} // namespace net
diff --git a/chromium/net/cert_net/cert_net_fetcher_impl.cc b/chromium/net/cert_net/cert_net_fetcher_impl.cc
index bf7623b9cd4..e80aa1b4c1a 100644
--- a/chromium/net/cert_net/cert_net_fetcher_impl.cc
+++ b/chromium/net/cert_net/cert_net_fetcher_impl.cc
@@ -4,9 +4,13 @@
#include "net/cert_net/cert_net_fetcher_impl.h"
+#include <tuple>
+#include <utility>
+
#include "base/callback_helpers.h"
#include "base/containers/linked_list.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "base/timer/timer.h"
@@ -133,13 +137,9 @@ CertNetFetcherImpl::RequestParams::RequestParams()
bool CertNetFetcherImpl::RequestParams::operator<(
const RequestParams& other) const {
- if (url != other.url)
- return url < other.url;
- if (http_method != other.http_method)
- return http_method < other.http_method;
- if (max_response_bytes != other.max_response_bytes)
- return max_response_bytes < other.max_response_bytes;
- return timeout < other.timeout;
+ return std::tie(url, http_method, max_response_bytes, timeout) <
+ std::tie(other.url, other.http_method, other.max_response_bytes,
+ other.timeout);
}
// CertNetFetcherImpl::Job tracks an outstanding URLRequest as well as all of
@@ -232,10 +232,9 @@ CertNetFetcherImpl::RequestImpl::~RequestImpl() {
CertNetFetcherImpl::Job::Job(scoped_ptr<RequestParams> request_params,
CertNetFetcherImpl* parent)
- : request_params_(request_params.Pass()),
+ : request_params_(std::move(request_params)),
result_net_error_(ERR_IO_PENDING),
- parent_(parent) {
-}
+ parent_(parent) {}
CertNetFetcherImpl::Job::~Job() {
Cancel();
@@ -262,7 +261,7 @@ scoped_ptr<CertNetFetcher::Request> CertNetFetcherImpl::Job::CreateRequest(
const FetchCallback& callback) {
scoped_ptr<RequestImpl> request(new RequestImpl(this, callback));
requests_.Append(request.get());
- return request.Pass();
+ return std::move(request);
}
void CertNetFetcherImpl::Job::DetachRequest(RequestImpl* request) {
@@ -451,7 +450,7 @@ scoped_ptr<CertNetFetcher::Request> CertNetFetcherImpl::FetchCaIssuers(
request_params->max_response_bytes =
GetMaxResponseBytes(max_response_bytes, kMaxResponseSizeInBytesForAia);
- return Fetch(request_params.Pass(), callback);
+ return Fetch(std::move(request_params), callback);
}
scoped_ptr<CertNetFetcher::Request> CertNetFetcherImpl::FetchCrl(
@@ -467,7 +466,7 @@ scoped_ptr<CertNetFetcher::Request> CertNetFetcherImpl::FetchCrl(
request_params->max_response_bytes =
GetMaxResponseBytes(max_response_bytes, kMaxResponseSizeInBytesForCrl);
- return Fetch(request_params.Pass(), callback);
+ return Fetch(std::move(request_params), callback);
}
scoped_ptr<CertNetFetcher::Request> CertNetFetcherImpl::FetchOcsp(
@@ -483,7 +482,7 @@ scoped_ptr<CertNetFetcher::Request> CertNetFetcherImpl::FetchOcsp(
request_params->max_response_bytes =
GetMaxResponseBytes(max_response_bytes, kMaxResponseSizeInBytesForAia);
- return Fetch(request_params.Pass(), callback);
+ return Fetch(std::move(request_params), callback);
}
bool CertNetFetcherImpl::JobComparator::operator()(const Job* job1,
@@ -501,7 +500,7 @@ scoped_ptr<CertNetFetcher::Request> CertNetFetcherImpl::Fetch(
Job* job = FindJob(*request_params);
if (!job) {
- job = new Job(request_params.Pass(), this);
+ job = new Job(std::move(request_params), this);
jobs_.insert(job);
job->StartURLRequest(context_);
}
diff --git a/chromium/net/cert_net/cert_net_fetcher_impl.h b/chromium/net/cert_net/cert_net_fetcher_impl.h
index ac5cd90afef..c3a1fb68b31 100644
--- a/chromium/net/cert_net/cert_net_fetcher_impl.h
+++ b/chromium/net/cert_net/cert_net_fetcher_impl.h
@@ -8,6 +8,7 @@
#include <set>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "net/base/net_errors.h"
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 16988557eff..311e93aee01 100644
--- a/chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc
+++ b/chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc
@@ -5,13 +5,14 @@
#include "net/cert_net/cert_net_fetcher_impl.h"
#include <string>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/run_loop.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_server_properties_impl.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -49,12 +50,11 @@ class RequestContext : public URLRequestContext {
params.proxy_service = proxy_service();
params.ssl_config_service = ssl_config_service();
params.http_server_properties = http_server_properties();
- scoped_refptr<HttpNetworkSession> network_session(
- new HttpNetworkSession(params));
- storage_.set_http_transaction_factory(
- make_scoped_ptr(new HttpCache(network_session.get(),
- HttpCache::DefaultBackend::InMemory(0)))
- .Pass());
+ storage_.set_http_network_session(
+ make_scoped_ptr(new HttpNetworkSession(params)));
+ storage_.set_http_transaction_factory(make_scoped_ptr(new HttpCache(
+ storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
+ false /* set_up_quic_server_info */)));
storage_.set_job_factory(make_scoped_ptr(new URLRequestJobFactoryImpl()));
}
@@ -103,7 +103,7 @@ class TestFetchCallback {
run_loop.Run();
quit_closure_.Reset();
}
- return result_.Pass();
+ return std::move(result_);
}
bool HasResult() const { return result_.get(); }
@@ -136,15 +136,13 @@ class TestFetchCallback {
class CertNetFetcherImplTest : public PlatformTest {
public:
- CertNetFetcherImplTest()
- : test_server_(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath(kDocRoot)) {
+ CertNetFetcherImplTest() {
+ test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
context_.set_network_delegate(&network_delegate_);
}
protected:
- SpawnedTestServer test_server_;
+ EmbeddedTestServer test_server_;
TestNetworkDelegate network_delegate_;
RequestContext context_;
};
@@ -169,17 +167,17 @@ TEST_F(CertNetFetcherImplTest, ParallelFetchNoDuplicates) {
TestFetchCallback callback3;
// Request a URL with Content-Type "application/pkix-cert"
- GURL url1 = test_server_.GetURL("files/cert.crt");
+ GURL url1 = test_server_.GetURL("/cert.crt");
scoped_ptr<CertNetFetcher::Request> request1 =
StartRequest(&fetcher, url1, callback1);
// Request a URL with Content-Type "application/pkix-crl"
- GURL url2 = test_server_.GetURL("files/root.crl");
+ GURL url2 = test_server_.GetURL("/root.crl");
scoped_ptr<CertNetFetcher::Request> request2 =
StartRequest(&fetcher, url2, callback2);
// Request a URL with Content-Type "application/pkcs7-mime"
- GURL url3 = test_server_.GetURL("files/certs.p7c");
+ GURL url3 = test_server_.GetURL("/certs.p7c");
scoped_ptr<CertNetFetcher::Request> request3 =
StartRequest(&fetcher, url3, callback3);
@@ -206,7 +204,7 @@ TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) {
CertNetFetcherImpl fetcher(&context_);
TestFetchCallback callback;
- GURL url = test_server_.GetURL("files/foo.txt");
+ GURL url = test_server_.GetURL("/foo.txt");
scoped_ptr<CertNetFetcher::Request> request =
StartRequest(&fetcher, url, callback);
scoped_ptr<FetchResult> result = callback.WaitForResult();
@@ -223,7 +221,7 @@ TEST_F(CertNetFetcherImplTest, HttpStatusCode) {
// Response was HTTP status 404.
{
TestFetchCallback callback;
- GURL url = test_server_.GetURL("files/404.html");
+ GURL url = test_server_.GetURL("/404.html");
scoped_ptr<CertNetFetcher::Request> request =
StartRequest(&fetcher, url, callback);
scoped_ptr<FetchResult> result = callback.WaitForResult();
@@ -233,7 +231,7 @@ TEST_F(CertNetFetcherImplTest, HttpStatusCode) {
// Response was HTTP status 500.
{
TestFetchCallback callback;
- GURL url = test_server_.GetURL("files/500.html");
+ GURL url = test_server_.GetURL("/500.html");
scoped_ptr<CertNetFetcher::Request> request =
StartRequest(&fetcher, url, callback);
scoped_ptr<FetchResult> result = callback.WaitForResult();
@@ -248,7 +246,7 @@ TEST_F(CertNetFetcherImplTest, ContentDisposition) {
CertNetFetcherImpl fetcher(&context_);
TestFetchCallback callback;
- GURL url = test_server_.GetURL("files/downloadable.js");
+ GURL url = test_server_.GetURL("/downloadable.js");
scoped_ptr<CertNetFetcher::Request> request =
StartRequest(&fetcher, url, callback);
scoped_ptr<FetchResult> result = callback.WaitForResult();
@@ -263,7 +261,7 @@ TEST_F(CertNetFetcherImplTest, Cache) {
CertNetFetcherImpl fetcher(&context_);
// Fetch a URL whose HTTP headers make it cacheable for 1 hour.
- GURL url(test_server_.GetURL("files/cacheable_1hr.crt"));
+ GURL url(test_server_.GetURL("/cacheable_1hr.crt"));
{
TestFetchCallback callback;
@@ -276,7 +274,7 @@ TEST_F(CertNetFetcherImplTest, Cache) {
EXPECT_EQ(1, network_delegate_.created_requests());
// Kill the HTTP server.
- ASSERT_TRUE(test_server_.Stop());
+ ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
// Fetch again -- will fail unless served from cache.
{
@@ -299,7 +297,7 @@ TEST_F(CertNetFetcherImplTest, TooLarge) {
// This file has a response body 12 bytes long. So setting the maximum to 11
// bytes will cause it to fail.
- GURL url(test_server_.GetURL("files/certs.p7c"));
+ GURL url(test_server_.GetURL("/certs.p7c"));
TestFetchCallback callback;
scoped_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers(
url, CertNetFetcher::DEFAULT, 11, callback.callback());
@@ -315,7 +313,7 @@ TEST_F(CertNetFetcherImplTest, Hang) {
CertNetFetcherImpl fetcher(&context_);
- GURL url(test_server_.GetURL("slow/certs.p7c?5"));
+ GURL url(test_server_.GetURL("/slow/certs.p7c?5"));
TestFetchCallback callback;
scoped_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers(
url, 10, CertNetFetcher::DEFAULT, callback.callback());
@@ -330,7 +328,7 @@ TEST_F(CertNetFetcherImplTest, Gzip) {
CertNetFetcherImpl fetcher(&context_);
- GURL url(test_server_.GetURL("files/gzipped_crl"));
+ GURL url(test_server_.GetURL("/gzipped_crl"));
TestFetchCallback callback;
scoped_ptr<CertNetFetcher::Request> request =
StartRequest(&fetcher, url, callback);
@@ -364,7 +362,7 @@ TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) {
CertNetFetcherImpl fetcher(&context_);
- GURL url(test_server_.GetURL("files/redirect_https"));
+ GURL url(test_server_.GetURL("/redirect_https"));
TestFetchCallback callback;
scoped_ptr<CertNetFetcher::Request> request =
@@ -410,15 +408,15 @@ TEST_F(CertNetFetcherImplTest, CancelBeforeRunningMessageLoop) {
TestFetchCallback callback2;
TestFetchCallback callback3;
- GURL url1 = test_server_.GetURL("files/cert.crt");
+ GURL url1 = test_server_.GetURL("/cert.crt");
scoped_ptr<CertNetFetcher::Request> request1 =
StartRequest(&fetcher, url1, callback1);
- GURL url2 = test_server_.GetURL("files/root.crl");
+ GURL url2 = test_server_.GetURL("/root.crl");
scoped_ptr<CertNetFetcher::Request> request2 =
StartRequest(&fetcher, url2, callback2);
- GURL url3 = test_server_.GetURL("files/certs.p7c");
+ GURL url3 = test_server_.GetURL("/certs.p7c");
scoped_ptr<CertNetFetcher::Request> request3 =
StartRequest(&fetcher, url3, callback3);
@@ -462,12 +460,12 @@ TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) {
TestFetchCallback callback2;
TestFetchCallback callback3;
- GURL url1 = test_server_.GetURL("files/cert.crt");
+ GURL url1 = test_server_.GetURL("/cert.crt");
scoped_ptr<CertNetFetcher::Request> request1 =
StartRequest(&fetcher, url1, callback1);
- GURL url2 = test_server_.GetURL("files/certs.p7c");
+ GURL url2 = test_server_.GetURL("/certs.p7c");
scoped_ptr<CertNetFetcher::Request> request2 =
StartRequest(&fetcher, url2, callback2);
@@ -500,7 +498,7 @@ TEST_F(CertNetFetcherImplTest, DeleteCancels) {
scoped_ptr<CertNetFetcherImpl> fetcher(new CertNetFetcherImpl(&context_));
- GURL url(test_server_.GetURL("slow/certs.p7c?20"));
+ GURL url(test_server_.GetURL("/slow/certs.p7c?20"));
TestFetchCallback callback;
scoped_ptr<CertNetFetcher::Request> request =
StartRequest(fetcher.get(), url, callback);
@@ -516,8 +514,8 @@ TEST_F(CertNetFetcherImplTest, ParallelFetchDuplicates) {
CertNetFetcherImpl fetcher(&context_);
- GURL url1 = test_server_.GetURL("files/cert.crt");
- GURL url2 = test_server_.GetURL("files/root.crl");
+ GURL url1 = test_server_.GetURL("/cert.crt");
+ GURL url2 = test_server_.GetURL("/root.crl");
// Issue 3 requests for url1, and 3 requests for url2
TestFetchCallback callback1;
@@ -579,7 +577,7 @@ TEST_F(CertNetFetcherImplTest, CancelThenStart) {
TestFetchCallback callback2;
TestFetchCallback callback3;
- GURL url = test_server_.GetURL("files/cert.crt");
+ GURL url = test_server_.GetURL("/cert.crt");
scoped_ptr<CertNetFetcher::Request> request1 =
StartRequest(&fetcher, url, callback1);
@@ -612,7 +610,7 @@ TEST_F(CertNetFetcherImplTest, CancelAll) {
TestFetchCallback callback[3];
scoped_ptr<CertNetFetcher::Request> request[3];
- GURL url = test_server_.GetURL("files/cert.crt");
+ GURL url = test_server_.GetURL("/cert.crt");
for (size_t i = 0; i < arraysize(callback); ++i) {
request[i] = StartRequest(&fetcher, url, callback[i]);
@@ -639,7 +637,7 @@ TEST_F(CertNetFetcherImplTest, DeleteWithinCallback) {
// Deleted by callback2.
CertNetFetcher* fetcher = new CertNetFetcherImpl(&context_);
- GURL url = test_server_.GetURL("files/cert.crt");
+ GURL url = test_server_.GetURL("/cert.crt");
TestFetchCallback callback[4];
scoped_ptr<CertNetFetcher::Request> reqs[4];
@@ -671,7 +669,7 @@ TEST_F(CertNetFetcherImplTest, FetchWithinCallback) {
CertNetFetcherImpl fetcher(&context_);
- GURL url = test_server_.GetURL("files/cert.crt");
+ GURL url = test_server_.GetURL("/cert.crt");
TestFetchCallback callback[5];
scoped_ptr<CertNetFetcher::Request> req[5];
@@ -703,7 +701,7 @@ TEST_F(CertNetFetcherImplTest, CancelWithinCallback) {
CertNetFetcherImpl fetcher(&context_);
- GURL url = test_server_.GetURL("files/cert.crt");
+ GURL url = test_server_.GetURL("/cert.crt");
TestFetchCallback callback[4];
scoped_ptr<CertNetFetcher::Request> request[4];
@@ -735,7 +733,7 @@ TEST_F(CertNetFetcherImplTest, CancelLastRequestWithinCallback) {
CertNetFetcherImpl fetcher(&context_);
- GURL url = test_server_.GetURL("files/cert.crt");
+ GURL url = test_server_.GetURL("/cert.crt");
TestFetchCallback callback1;
scoped_ptr<CertNetFetcher::Request> request1 =
diff --git a/chromium/net/cert_net/nss_ocsp.cc b/chromium/net/cert_net/nss_ocsp.cc
index 835993f8a9c..40b79da9523 100644
--- a/chromium/net/cert_net/nss_ocsp.cc
+++ b/chromium/net/cert_net/nss_ocsp.cc
@@ -6,21 +6,21 @@
#include <certt.h>
#include <certdb.h>
-#include <ocsp.h>
#include <nspr.h>
#include <nss.h>
+#include <ocsp.h>
#include <pthread.h>
#include <secerr.h>
-
#include <algorithm>
#include <string>
+#include <utility>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
@@ -171,7 +171,7 @@ class OCSPNSSInitialization {
DISALLOW_COPY_AND_ASSIGN(OCSPNSSInitialization);
};
-base::LazyInstance<OCSPNSSInitialization> g_ocsp_nss_initialization =
+base::LazyInstance<OCSPNSSInitialization>::Leaky g_ocsp_nss_initialization =
LAZY_INSTANCE_INITIALIZER;
// Concrete class for SEC_HTTP_REQUEST_SESSION.
@@ -410,7 +410,7 @@ class OCSPRequestSession
scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader(
upload_content_.data(), upload_content_.size()));
request_->set_upload(
- ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
}
if (!extra_request_headers_.IsEmpty())
request_->SetExtraRequestHeaders(extra_request_headers_);
@@ -594,10 +594,6 @@ OCSPNSSInitialization::OCSPNSSInitialization() {
}
OCSPNSSInitialization::~OCSPNSSInitialization() {
- SECStatus status = CERT_RegisterAlternateOCSPAIAInfoCallBack(NULL, NULL);
- if (status != SECSuccess) {
- LOG(ERROR) << "Error unregistering OCSP: " << PR_GetError();
- }
}
diff --git a/chromium/net/cert_net/nss_ocsp_unittest.cc b/chromium/net/cert_net/nss_ocsp_unittest.cc
index 29adebc1a9d..e4367cc30bf 100644
--- a/chromium/net/cert_net/nss_ocsp_unittest.cc
+++ b/chromium/net/cert_net/nss_ocsp_unittest.cc
@@ -5,10 +5,12 @@
#include "net/cert_net/nss_ocsp.h"
#include <string>
+#include <utility>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
@@ -90,8 +92,8 @@ class NssHttpTest : public ::testing::Test {
new AiaResponseHandler(kAiaHeaders, file_contents));
handler_ = handler.get();
- URLRequestFilter::GetInstance()->AddHostnameInterceptor(
- "http", kAiaHost, handler.Pass());
+ URLRequestFilter::GetInstance()->AddHostnameInterceptor("http", kAiaHost,
+ std::move(handler));
SetURLRequestContextForNSSHttpIO(&context_);
EnsureNSSHttpIOInit();
diff --git a/chromium/net/cookies/canonical_cookie.cc b/chromium/net/cookies/canonical_cookie.cc
index fcc8e3d9f4a..15287e0b8b5 100644
--- a/chromium/net/cookies/canonical_cookie.cc
+++ b/chromium/net/cookies/canonical_cookie.cc
@@ -44,9 +44,9 @@
#include "net/cookies/canonical_cookie.h"
-#include "base/basictypes.h"
#include "base/format_macros.h"
#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
@@ -193,7 +193,7 @@ Time CanonicalCookie::CanonExpiration(const ParsedCookie& pc,
const Time& current,
const Time& server_time) {
// First, try the Max-Age attribute.
- uint64 max_age = 0;
+ uint64_t max_age = 0;
if (pc.HasMaxAge() &&
#ifdef COMPILER_MSVC
sscanf_s(
@@ -235,6 +235,18 @@ CanonicalCookie* CanonicalCookie::Create(const GURL& url,
std::string cookie_domain;
if (!GetCookieDomain(url, parsed_cookie, &cookie_domain)) {
+ VLOG(kVlogSetCookies) << "Create() failed to get a cookie domain";
+ return NULL;
+ }
+
+ // Per 3.2.1 of "Deprecate modification of 'secure' cookies from non-secure
+ // origins", if the cookie's "secure-only-flag" is "true" and the requesting
+ // URL does not have a secure scheme, the cookie should be thrown away.
+ // https://tools.ietf.org/html/draft-west-leave-secure-cookies-alone
+ if (options.enforce_strict_secure() && parsed_cookie.IsSecure() &&
+ !url.SchemeIsCryptographic()) {
+ VLOG(kVlogSetCookies)
+ << "Create() is trying to create a secure cookie from an insecure URL";
return NULL;
}
@@ -247,6 +259,16 @@ CanonicalCookie* CanonicalCookie::Create(const GURL& url,
creation_time,
server_time);
+ CookiePrefix prefix = CanonicalCookie::GetCookiePrefix(parsed_cookie.Name());
+ bool is_cookie_valid =
+ CanonicalCookie::IsCookiePrefixValid(prefix, url, parsed_cookie);
+ CanonicalCookie::RecordCookiePrefixMetrics(prefix, is_cookie_valid);
+ if (!is_cookie_valid) {
+ VLOG(kVlogSetCookies)
+ << "Create() failed because the cookie violated prefix rules.";
+ return nullptr;
+ }
+
return new CanonicalCookie(
url, parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain,
cookie_path, creation_time, cookie_expires, creation_time,
@@ -264,6 +286,7 @@ CanonicalCookie* CanonicalCookie::Create(const GURL& url,
bool secure,
bool http_only,
bool first_party_only,
+ bool enforce_strict_secure,
CookiePriority priority) {
// Expect valid attribute tokens and values, as defined by the ParsedCookie
// logic, otherwise don't create the cookie.
@@ -283,6 +306,9 @@ CanonicalCookie* CanonicalCookie::Create(const GURL& url,
return NULL;
}
+ if (enforce_strict_secure && secure && !url.SchemeIsCryptographic())
+ return NULL;
+
std::string parsed_path = ParsedCookie::ParseValueString(path);
if (parsed_path != path)
return NULL;
@@ -390,25 +416,18 @@ bool CanonicalCookie::IncludeForRequestURL(const GURL& url,
// match the cookie-path.
if (!IsOnPath(url.path()))
return false;
-
- // Include first-party-only cookies iff |options| tells us to include all of
- // them, or if a first-party URL is set and its origin matches the origin of
- // |url|.
- if (IsFirstPartyOnly() && !options.include_first_party_only() &&
- options.first_party_url().GetOrigin() != url.GetOrigin()) {
+ // Don't include first-party-only cookies for non-first-party requests.
+ if (IsFirstPartyOnly() && !options.include_first_party_only_cookies())
return false;
- }
return true;
}
std::string CanonicalCookie::DebugString() const {
return base::StringPrintf(
- "name: %s value: %s domain: %s path: %s creation: %"
- PRId64,
- name_.c_str(), value_.c_str(),
- domain_.c_str(), path_.c_str(),
- static_cast<int64>(creation_date_.ToTimeT()));
+ "name: %s value: %s domain: %s path: %s creation: %" PRId64,
+ name_.c_str(), value_.c_str(), domain_.c_str(), path_.c_str(),
+ static_cast<int64_t>(creation_date_.ToTimeT()));
}
bool CanonicalCookie::PartialCompare(const CanonicalCookie& other) const {
@@ -446,4 +465,47 @@ bool CanonicalCookie::FullCompare(const CanonicalCookie& other) const {
return Priority() < other.Priority();
}
+// static
+CanonicalCookie::CookiePrefix CanonicalCookie::GetCookiePrefix(
+ const std::string& name) {
+ const char kSecurePrefix[] = "__Secure-";
+ const char kHostPrefix[] = "__Host-";
+ if (name.find(kSecurePrefix) == 0)
+ return CanonicalCookie::COOKIE_PREFIX_SECURE;
+ if (name.find(kHostPrefix) == 0)
+ return CanonicalCookie::COOKIE_PREFIX_HOST;
+ return CanonicalCookie::COOKIE_PREFIX_NONE;
+}
+
+// static
+void CanonicalCookie::RecordCookiePrefixMetrics(
+ CanonicalCookie::CookiePrefix prefix,
+ bool is_cookie_valid) {
+ const char kCookiePrefixHistogram[] = "Cookie.CookiePrefix";
+ const char kCookiePrefixBlockedHistogram[] = "Cookie.CookiePrefixBlocked";
+ UMA_HISTOGRAM_ENUMERATION(kCookiePrefixHistogram, prefix,
+ CanonicalCookie::COOKIE_PREFIX_LAST);
+ if (!is_cookie_valid) {
+ UMA_HISTOGRAM_ENUMERATION(kCookiePrefixBlockedHistogram, prefix,
+ CanonicalCookie::COOKIE_PREFIX_LAST);
+ }
+}
+
+// Returns true if the cookie does not violate any constraints imposed
+// by the cookie name's prefix, as described in
+// https://tools.ietf.org/html/draft-west-cookie-prefixes
+//
+// static
+bool CanonicalCookie::IsCookiePrefixValid(CanonicalCookie::CookiePrefix prefix,
+ const GURL& url,
+ const ParsedCookie& parsed_cookie) {
+ if (prefix == CanonicalCookie::COOKIE_PREFIX_SECURE)
+ return parsed_cookie.IsSecure() && url.SchemeIsCryptographic();
+ if (prefix == CanonicalCookie::COOKIE_PREFIX_HOST) {
+ return parsed_cookie.IsSecure() && url.SchemeIsCryptographic() &&
+ !parsed_cookie.HasDomain() && parsed_cookie.Path() == "/";
+ }
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/cookies/canonical_cookie.h b/chromium/net/cookies/canonical_cookie.h
index 30ddcabf645..9c3a1c9c04b 100644
--- a/chromium/net/cookies/canonical_cookie.h
+++ b/chromium/net/cookies/canonical_cookie.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/cookies/cookie_constants.h"
@@ -51,7 +51,7 @@ class NET_EXPORT CanonicalCookie {
// Creates a new |CanonicalCookie| from the |cookie_line| and the
// |creation_time|. Canonicalizes and validates inputs. May return NULL if
- // an attribut value is invalid.
+ // an attribute value is invalid.
static CanonicalCookie* Create(const GURL& url,
const std::string& cookie_line,
const base::Time& creation_time,
@@ -70,6 +70,7 @@ class NET_EXPORT CanonicalCookie {
bool secure,
bool http_only,
bool first_party_only,
+ bool enforce_strict_secure,
CookiePriority priority);
const GURL& Source() const { return source_; }
@@ -107,6 +108,18 @@ class NET_EXPORT CanonicalCookie {
&& path_ == ecc.Path());
}
+ // Checks if two cookies have the same name and domain-match per RFC 6265.
+ // Note that this purposefully ignores paths, and that this function is
+ // guaranteed to return |true| for a superset of the inputs that
+ // IsEquivalent() above returns |true| for.
+ //
+ // This is needed for the updates to RFC6265 as per
+ // https://tools.ietf.org/html/draft-west-leave-secure-cookies-alone.
+ bool IsEquivalentForSecureCookieMatching(const CanonicalCookie& ecc) const {
+ return (name_ == ecc.Name() && (ecc.IsDomainMatch(Source().host()) ||
+ IsDomainMatch(ecc.Source().host())));
+ }
+
void SetLastAccessDate(const base::Time& date) {
last_access_date_ = date;
}
@@ -146,6 +159,32 @@ class NET_EXPORT CanonicalCookie {
bool FullCompare(const CanonicalCookie& other) const;
private:
+ FRIEND_TEST_ALL_PREFIXES(CanonicalCookieTest, TestPrefixHistograms);
+
+ // The special cookie prefixes as defined in
+ // https://tools.ietf.org/html/draft-west-cookie-prefixes
+ //
+ // This enum is being histogrammed; do not reorder or remove values.
+ enum CookiePrefix {
+ COOKIE_PREFIX_NONE = 0,
+ COOKIE_PREFIX_SECURE,
+ COOKIE_PREFIX_HOST,
+ COOKIE_PREFIX_LAST
+ };
+
+ // Returns the CookiePrefix (or COOKIE_PREFIX_NONE if none) that
+ // applies to the given cookie |name|.
+ static CookiePrefix GetCookiePrefix(const std::string& name);
+ // Records histograms to measure how often cookie prefixes appear in
+ // the wild and how often they would be blocked.
+ static void RecordCookiePrefixMetrics(CookiePrefix prefix,
+ bool is_cookie_valid);
+ // Returns true if a prefixed cookie does not violate any of the rules
+ // for that cookie.
+ static bool IsCookiePrefixValid(CookiePrefix prefix,
+ const GURL& url,
+ const ParsedCookie& parsed_cookie);
+
// The source member of a canonical cookie is the origin of the URL that tried
// to set this cookie. This field is not persistent though; its only used in
// the in-tab cookies dialog to show the user the source URL. This is used for
diff --git a/chromium/net/cookies/canonical_cookie_unittest.cc b/chromium/net/cookies/canonical_cookie_unittest.cc
index 9b10d13ff3b..2a01d9742a2 100644
--- a/chromium/net/cookies/canonical_cookie_unittest.cc
+++ b/chromium/net/cookies/canonical_cookie_unittest.cc
@@ -5,6 +5,7 @@
#include "net/cookies/canonical_cookie.h"
#include "base/memory/scoped_ptr.h"
+#include "base/test/histogram_tester.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_options.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -84,7 +85,7 @@ TEST(CanonicalCookieTest, Create) {
// Test creating http only cookies.
CookieOptions first_party_options;
- first_party_options.set_first_party_url(url);
+ first_party_options.set_include_first_party_only_cookies();
cookie.reset(CanonicalCookie::Create(url, "A=2; First-Party-Only",
creation_time, httponly_options));
EXPECT_TRUE(cookie.get());
@@ -94,7 +95,7 @@ TEST(CanonicalCookieTest, Create) {
// string.
cookie.reset(CanonicalCookie::Create(
url, "A", "2", "www.example.com", "/test", creation_time, base::Time(),
- false, false, false, COOKIE_PRIORITY_DEFAULT));
+ false, false, false, false, COOKIE_PRIORITY_DEFAULT));
EXPECT_EQ(url.GetOrigin(), cookie->Source());
EXPECT_EQ("A", cookie->Name());
EXPECT_EQ("2", cookie->Value());
@@ -106,7 +107,7 @@ TEST(CanonicalCookieTest, Create) {
cookie.reset(CanonicalCookie::Create(
url, "A", "2", ".www.example.com", "/test", creation_time, base::Time(),
- false, false, false, COOKIE_PRIORITY_DEFAULT));
+ false, false, false, false, COOKIE_PRIORITY_DEFAULT));
EXPECT_EQ(url.GetOrigin(), cookie->Source());
EXPECT_EQ("A", cookie->Name());
EXPECT_EQ("2", cookie->Value());
@@ -240,6 +241,104 @@ TEST(CanonicalCookieTest, IsEquivalent) {
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
}
+TEST(CanonicalCookieTest, IsEquivalentForSecureCookieMatching) {
+ GURL url("http://www.example.com/");
+ std::string cookie_name = "A";
+ std::string cookie_value = "2EDA-EF";
+ std::string cookie_domain = ".www.example.com";
+ std::string cookie_path = "/";
+ base::Time creation_time = base::Time::Now();
+ base::Time last_access_time = creation_time;
+ base::Time expiration_time = creation_time + base::TimeDelta::FromDays(2);
+ bool secure(false);
+ bool httponly(false);
+ bool firstparty(false);
+
+ // Test that a cookie is equivalent to itself.
+ scoped_ptr<CanonicalCookie> cookie(new CanonicalCookie(
+ url, cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
+ expiration_time, last_access_time, secure, httponly, firstparty,
+ COOKIE_PRIORITY_MEDIUM));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*cookie));
+
+ // Test that two identical cookies are equivalent.
+ scoped_ptr<CanonicalCookie> other_cookie(new CanonicalCookie(
+ url, cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
+ expiration_time, last_access_time, secure, httponly, firstparty,
+ COOKIE_PRIORITY_MEDIUM));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ // Tests that use different variations of attribute values that
+ // DON'T affect cookie equivalence. Differs from the IsEquivalent tests above
+ // as follows:
+ // * Should return true even if paths differ.
+ // * Should return true if the domains "domain-match" (but are not
+ // identical).
+ other_cookie.reset(
+ new CanonicalCookie(url, cookie_name, "2", cookie_domain, cookie_path,
+ creation_time, expiration_time, last_access_time,
+ secure, httponly, firstparty, COOKIE_PRIORITY_HIGH));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ base::Time other_creation_time =
+ creation_time + base::TimeDelta::FromMinutes(2);
+ other_cookie.reset(new CanonicalCookie(
+ url, cookie_name, "2", cookie_domain, cookie_path, other_creation_time,
+ expiration_time, last_access_time, secure, httponly, firstparty,
+ COOKIE_PRIORITY_MEDIUM));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ other_cookie.reset(new CanonicalCookie(
+ url, cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
+ expiration_time, last_access_time, true, httponly, firstparty,
+ COOKIE_PRIORITY_LOW));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ other_cookie.reset(new CanonicalCookie(
+ url, cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
+ expiration_time, last_access_time, secure, true, firstparty,
+ COOKIE_PRIORITY_LOW));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ other_cookie.reset(new CanonicalCookie(
+ url, cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
+ expiration_time, last_access_time, secure, httponly, true,
+ COOKIE_PRIORITY_LOW));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ // The following 3 tests' expected results differ from their IsEquivalent
+ // counterparts above.
+ other_cookie.reset(new CanonicalCookie(
+ url, cookie_name, cookie_value, cookie_domain, "/test/0", creation_time,
+ expiration_time, last_access_time, secure, httponly, firstparty,
+ COOKIE_PRIORITY_MEDIUM));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ other_cookie.reset(new CanonicalCookie(
+ url, cookie_name, cookie_value, "www.example.com", cookie_path,
+ creation_time, expiration_time, last_access_time, secure, httponly,
+ firstparty, COOKIE_PRIORITY_MEDIUM));
+ EXPECT_TRUE(cookie->IsDomainCookie());
+ EXPECT_FALSE(other_cookie->IsDomainCookie());
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ other_cookie.reset(new CanonicalCookie(
+ url, cookie_name, cookie_value, ".example.com", cookie_path,
+ creation_time, expiration_time, last_access_time, secure, httponly,
+ firstparty, COOKIE_PRIORITY_MEDIUM));
+ EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+
+ // Tests that use different variations of attribute values that
+ // DO affect cookie equivalence. Note that unlike the IsEquivalent tests
+ // above, this does *not* include tests for differing paths or domains that
+ // "domain-match".
+ other_cookie.reset(new CanonicalCookie(
+ url, "B", cookie_value, cookie_domain, cookie_path, creation_time,
+ expiration_time, last_access_time, secure, httponly, firstparty,
+ COOKIE_PRIORITY_MEDIUM));
+ EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
+}
+
TEST(CanonicalCookieTest, IsDomainMatch) {
GURL url("http://www.example.com/test/foo.html");
base::Time creation_time = base::Time::Now();
@@ -347,43 +446,37 @@ TEST(CanonicalCookieTest, IncludeFirstPartyForFirstPartyURL) {
CookieOptions options;
scoped_ptr<CanonicalCookie> cookie;
- // First-party-only cookies are not inlcuded if a top-level URL is unset.
+ // First-party-only cookies are not included for non-first-party requests,
+ // even if other properties match:
cookie.reset(CanonicalCookie::Create(secure_url, "A=2; First-Party-Only",
creation_time, options));
EXPECT_TRUE(cookie->IsFirstPartyOnly());
- options.set_first_party_url(GURL());
EXPECT_FALSE(cookie->IncludeForRequestURL(secure_url, options));
-
- // First-party-only cookies are included only if the cookie's origin matches
- // the
- // first-party origin.
- options.set_first_party_url(secure_url);
- EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url, options));
- options.set_first_party_url(insecure_url);
+ cookie.reset(CanonicalCookie::Create(
+ secure_url, "A=2; Secure; First-Party-Only", creation_time, options));
+ EXPECT_TRUE(cookie->IsFirstPartyOnly());
EXPECT_FALSE(cookie->IncludeForRequestURL(secure_url, options));
- options.set_first_party_url(third_party_url);
+ cookie.reset(CanonicalCookie::Create(secure_url_with_path,
+ "A=2; First-Party-Only; path=/foo/bar",
+ creation_time, options));
+ EXPECT_TRUE(cookie->IsFirstPartyOnly());
EXPECT_FALSE(cookie->IncludeForRequestURL(secure_url, options));
- // "First-Party-Only" doesn't override the 'secure' flag.
+ // First-party-only cookies are included for first-party requests:
+ options.set_include_first_party_only_cookies();
+ cookie.reset(CanonicalCookie::Create(secure_url, "A=2; First-Party-Only",
+ creation_time, options));
+ EXPECT_TRUE(cookie->IsFirstPartyOnly());
+ EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url, options));
cookie.reset(CanonicalCookie::Create(
secure_url, "A=2; Secure; First-Party-Only", creation_time, options));
- options.set_first_party_url(secure_url);
+ EXPECT_TRUE(cookie->IsFirstPartyOnly());
EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url, options));
- EXPECT_FALSE(cookie->IncludeForRequestURL(insecure_url, options));
- options.set_first_party_url(insecure_url);
- EXPECT_FALSE(cookie->IncludeForRequestURL(secure_url, options));
- EXPECT_FALSE(cookie->IncludeForRequestURL(insecure_url, options));
-
- // "First-Party-Only" doesn't override the 'path' flag.
cookie.reset(CanonicalCookie::Create(secure_url_with_path,
"A=2; First-Party-Only; path=/foo/bar",
creation_time, options));
- options.set_first_party_url(secure_url_with_path);
- EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url_with_path, options));
- EXPECT_FALSE(cookie->IncludeForRequestURL(secure_url, options));
- options.set_first_party_url(secure_url);
+ EXPECT_TRUE(cookie->IsFirstPartyOnly());
EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url_with_path, options));
- EXPECT_FALSE(cookie->IncludeForRequestURL(secure_url, options));
}
TEST(CanonicalCookieTest, PartialCompare) {
@@ -449,4 +542,193 @@ TEST(CanonicalCookieTest, FullCompare) {
check_consistency(*cookie_different_path, *cookie_different_value);
}
+TEST(CanonicalCookieTest, SecureCookiePrefix) {
+ GURL https_url("https://www.example.test");
+ GURL http_url("http://www.example.test");
+ base::Time creation_time = base::Time::Now();
+ CookieOptions options;
+
+ // A __Secure- cookie must be Secure.
+ EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Secure-A=B", creation_time, options)));
+ EXPECT_EQ(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Secure-A=B; httponly", creation_time, options)));
+
+ // A typoed prefix does not have to be Secure.
+ EXPECT_NE(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__secure-A=B; Secure", creation_time, options)));
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__secure-A=C;", creation_time, options)));
+ EXPECT_NE(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__SecureA=B; Secure", creation_time, options)));
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__SecureA=C;", creation_time, options)));
+
+ // A __Secure- cookie can't be set on a non-secure origin.
+ EXPECT_EQ(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ http_url, "__Secure-A=B; Secure", creation_time, options)));
+}
+
+TEST(CanonicalCookieTest, HostCookiePrefix) {
+ GURL https_url("https://www.example.test");
+ GURL http_url("http://www.example.test");
+ base::Time creation_time = base::Time::Now();
+ CookieOptions options;
+ std::string domain = https_url.host();
+
+ // A __Host- cookie must be Secure.
+ EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B;", creation_time, options)));
+ EXPECT_EQ(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Domain=" + domain + "; Path=/;",
+ creation_time, options)));
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Path=/; Secure;",
+ creation_time, options)));
+
+ // A __Host- cookie must be set from a secure scheme.
+ EXPECT_EQ(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ http_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
+ creation_time, options)));
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Path=/; Secure;",
+ creation_time, options)));
+
+ // A __Host- cookie can't have a Domain.
+ EXPECT_EQ(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
+ creation_time, options)));
+ EXPECT_EQ(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Domain=" + domain + "; Secure;",
+ creation_time, options)));
+
+ // A __Host- cookie must have a Path of "/".
+ EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Path=/foo; Secure;",
+ creation_time, options)));
+ EXPECT_EQ(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Secure;", creation_time, options)));
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Secure; Path=/;",
+ creation_time, options)));
+
+ // Rules don't apply for a typoed prefix.
+ EXPECT_NE(nullptr,
+ make_scoped_ptr(CanonicalCookie::Create(
+ http_url, "__host-A=B; Domain=" + domain + "; Path=/; Secure;",
+ creation_time, options)));
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__HostA=B; Domain=" + domain + "; Secure;",
+ creation_time, options)));
+}
+
+TEST(CanonicalCookieTest, EnforceSecureCookiesRequireSecureScheme) {
+ GURL http_url("http://www.example.com");
+ GURL https_url("https://www.example.com");
+ base::Time creation_time = base::Time::Now();
+ CookieOptions options;
+ options.set_enforce_strict_secure();
+
+ scoped_ptr<CanonicalCookie> http_cookie_no_secure(
+ CanonicalCookie::Create(http_url, "a=b", creation_time, options));
+ scoped_ptr<CanonicalCookie> http_cookie_secure(
+ CanonicalCookie::Create(http_url, "a=b; Secure", creation_time, options));
+ scoped_ptr<CanonicalCookie> https_cookie_no_secure(
+ CanonicalCookie::Create(https_url, "a=b", creation_time, options));
+ scoped_ptr<CanonicalCookie> https_cookie_secure(CanonicalCookie::Create(
+ https_url, "a=b; Secure", creation_time, options));
+
+ EXPECT_TRUE(http_cookie_no_secure.get());
+ EXPECT_FALSE(http_cookie_secure.get());
+ EXPECT_TRUE(https_cookie_no_secure.get());
+ EXPECT_TRUE(https_cookie_secure.get());
+
+ scoped_ptr<CanonicalCookie> http_cookie_no_secure_extended(
+ CanonicalCookie::Create(http_url, "a", "b", "", "", creation_time,
+ creation_time, false, false, false, true,
+ COOKIE_PRIORITY_DEFAULT));
+ scoped_ptr<CanonicalCookie> http_cookie_secure_extended(
+ CanonicalCookie::Create(http_url, "a", "b", "", "", creation_time,
+ creation_time, true, false, false, true,
+ COOKIE_PRIORITY_DEFAULT));
+ scoped_ptr<CanonicalCookie> https_cookie_no_secure_extended(
+ CanonicalCookie::Create(https_url, "a", "b", "", "", creation_time,
+ creation_time, false, false, false, true,
+ COOKIE_PRIORITY_DEFAULT));
+ scoped_ptr<CanonicalCookie> https_cookie_secure_extended(
+ CanonicalCookie::Create(https_url, "a", "b", "", "", creation_time,
+ creation_time, true, false, false, true,
+ COOKIE_PRIORITY_DEFAULT));
+
+ EXPECT_TRUE(http_cookie_no_secure_extended.get());
+ EXPECT_FALSE(http_cookie_secure_extended.get());
+ EXPECT_TRUE(https_cookie_no_secure_extended.get());
+ EXPECT_TRUE(https_cookie_secure_extended.get());
+}
+
+TEST(CanonicalCookieTest, TestPrefixHistograms) {
+ base::HistogramTester histograms;
+ const char kCookiePrefixHistogram[] = "Cookie.CookiePrefix";
+ const char kCookiePrefixBlockedHistogram[] = "Cookie.CookiePrefixBlocked";
+ GURL https_url("https://www.example.test");
+ base::Time creation_time = base::Time::Now();
+ CookieOptions options;
+
+ scoped_ptr<CanonicalCookie> cookie1 = make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B;", creation_time, options));
+ EXPECT_EQ(nullptr, cookie1);
+
+ histograms.ExpectBucketCount(kCookiePrefixHistogram,
+ CanonicalCookie::COOKIE_PREFIX_HOST, 1);
+ histograms.ExpectBucketCount(kCookiePrefixBlockedHistogram,
+ CanonicalCookie::COOKIE_PREFIX_HOST, 1);
+
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Host-A=B; Path=/; Secure", creation_time,
+ options)));
+ histograms.ExpectBucketCount(kCookiePrefixHistogram,
+ CanonicalCookie::COOKIE_PREFIX_HOST, 2);
+ histograms.ExpectBucketCount(kCookiePrefixBlockedHistogram,
+ CanonicalCookie::COOKIE_PREFIX_HOST, 1);
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__HostA=B; Path=/; Secure", creation_time,
+ options)));
+ histograms.ExpectBucketCount(kCookiePrefixHistogram,
+ CanonicalCookie::COOKIE_PREFIX_HOST, 2);
+ histograms.ExpectBucketCount(kCookiePrefixBlockedHistogram,
+ CanonicalCookie::COOKIE_PREFIX_HOST, 1);
+
+ scoped_ptr<CanonicalCookie> cookie2 = make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Secure-A=B;", creation_time, options));
+ EXPECT_EQ(nullptr, cookie2);
+
+ histograms.ExpectBucketCount(kCookiePrefixHistogram,
+ CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
+ histograms.ExpectBucketCount(kCookiePrefixBlockedHistogram,
+ CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__Secure-A=B; Path=/; Secure",
+ creation_time, options)));
+ histograms.ExpectBucketCount(kCookiePrefixHistogram,
+ CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
+ histograms.ExpectBucketCount(kCookiePrefixBlockedHistogram,
+ CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
+ EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+ https_url, "__SecureA=B; Path=/; Secure",
+ creation_time, options)));
+ histograms.ExpectBucketCount(kCookiePrefixHistogram,
+ CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
+ histograms.ExpectBucketCount(kCookiePrefixBlockedHistogram,
+ CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
+}
+
} // namespace net
diff --git a/chromium/net/cookies/cookie_constants_unittest.cc b/chromium/net/cookies/cookie_constants_unittest.cc
index 87fa1c1b107..53cdc523c6e 100644
--- a/chromium/net/cookies/cookie_constants_unittest.cc
+++ b/chromium/net/cookies/cookie_constants_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 "base/basictypes.h"
+#include "base/macros.h"
#include "net/cookies/cookie_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/cookies/cookie_monster.cc b/chromium/net/cookies/cookie_monster.cc
index 2292f8c25a7..15e4f7ee8e1 100644
--- a/chromium/net/cookies/cookie_monster.cc
+++ b/chromium/net/cookies/cookie_monster.cc
@@ -48,11 +48,11 @@
#include <functional>
#include <set>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
@@ -65,6 +65,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
+#include "url/origin.h"
using base::Time;
using base::TimeDelta;
@@ -232,6 +233,23 @@ void SortLeastRecentlyAccessed(CookieMonster::CookieItVector::iterator it_begin,
std::partial_sort(it_begin, it_begin + num_sort + 1, it_end, LRACookieSorter);
}
+// Given a single cookie vector |cookie_its|, pushs all of the secure cookies in
+// |cookie_its| into |secure_cookie_its| and all of the non-secure cookies into
+// |non_secure_cookie_its|. Both |secure_cookie_its| and |non_secure_cookie_its|
+// must be non-NULL.
+void SplitCookieVectorIntoSecureAndNonSecure(
+ const CookieMonster::CookieItVector& cookie_its,
+ CookieMonster::CookieItVector* secure_cookie_its,
+ CookieMonster::CookieItVector* non_secure_cookie_its) {
+ DCHECK(secure_cookie_its && non_secure_cookie_its);
+ for (const auto& curit : cookie_its) {
+ if (curit->second->IsSecure())
+ secure_cookie_its->push_back(curit);
+ else
+ non_secure_cookie_its->push_back(curit);
+ }
+}
+
// Predicate to support PartitionCookieByPriority().
struct CookiePriorityEqualsTo
: std::unary_function<const CookieMonster::CookieMap::iterator, bool> {
@@ -305,6 +323,8 @@ ChangeCausePair ChangeCauseMapping[] = {
{CookieMonsterDelegate::CHANGE_COOKIE_EXPIRED_OVERWRITE, true},
// DELETE_COOKIE_CONTROL_CHAR
{CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true},
+ // DELETE_COOKIE_NON_SECURE
+ {CookieMonsterDelegate::CHANGE_COOKIE_EVICTED, true},
// DELETE_COOKIE_LAST_ENTRY
{CookieMonsterDelegate::CHANGE_COOKIE_EXPLICIT, false}};
@@ -439,6 +459,8 @@ class CookieMonster::SetCookieWithDetailsTask : public CookieMonsterTask {
bool secure,
bool http_only,
bool first_party_only,
+ bool enforce_prefixes,
+ bool enforce_strict_secure,
CookiePriority priority,
const SetCookiesCallback& callback)
: CookieMonsterTask(cookie_monster),
@@ -451,6 +473,8 @@ class CookieMonster::SetCookieWithDetailsTask : public CookieMonsterTask {
secure_(secure),
http_only_(http_only),
first_party_only_(first_party_only),
+ enforce_prefixes_(enforce_prefixes),
+ enforce_strict_secure_(enforce_strict_secure),
priority_(priority),
callback_(callback) {}
@@ -470,6 +494,8 @@ class CookieMonster::SetCookieWithDetailsTask : public CookieMonsterTask {
bool secure_;
bool http_only_;
bool first_party_only_;
+ bool enforce_prefixes_;
+ bool enforce_strict_secure_;
CookiePriority priority_;
SetCookiesCallback callback_;
@@ -479,7 +505,8 @@ class CookieMonster::SetCookieWithDetailsTask : public CookieMonsterTask {
void CookieMonster::SetCookieWithDetailsTask::Run() {
bool success = this->cookie_monster()->SetCookieWithDetails(
url_, name_, value_, domain_, path_, expiration_time_, secure_,
- http_only_, first_party_only_, priority_);
+ http_only_, first_party_only_, enforce_prefixes_, enforce_strict_secure_,
+ priority_);
if (!callback_.is_null()) {
this->InvokeCallback(base::Bind(&SetCookiesCallback::Run,
base::Unretained(&callback_), success));
@@ -928,11 +955,14 @@ void CookieMonster::SetCookieWithDetailsAsync(
bool secure,
bool http_only,
bool first_party_only,
+ bool enforce_prefixes,
+ bool enforce_strict_secure,
CookiePriority priority,
const SetCookiesCallback& callback) {
scoped_refptr<SetCookieWithDetailsTask> task = new SetCookieWithDetailsTask(
this, url, name, value, domain, path, expiration_time, secure, http_only,
- first_party_only, priority, callback);
+ first_party_only, enforce_prefixes, enforce_strict_secure, priority,
+ callback);
DoCookieTaskForURL(task, url);
}
@@ -957,7 +987,7 @@ void CookieMonster::GetAllCookiesForURLAsync(
const GetCookieListCallback& callback) {
CookieOptions options;
options.set_include_httponly();
- options.set_include_first_party_only();
+ options.set_include_first_party_only_cookies();
scoped_refptr<GetAllCookiesForURLWithOptionsTask> task =
new GetAllCookiesForURLWithOptionsTask(this, url, options, callback);
@@ -1112,6 +1142,8 @@ bool CookieMonster::SetCookieWithDetails(const GURL& url,
bool secure,
bool http_only,
bool first_party_only,
+ bool enforce_prefixes,
+ bool enforce_strict_secure,
CookiePriority priority) {
base::AutoLock autolock(lock_);
@@ -1122,16 +1154,18 @@ bool CookieMonster::SetCookieWithDetails(const GURL& url,
last_time_seen_ = creation_time;
scoped_ptr<CanonicalCookie> cc;
- cc.reset(CanonicalCookie::Create(url, name, value, domain, path,
- creation_time, expiration_time, secure,
- http_only, first_party_only, priority));
+ cc.reset(CanonicalCookie::Create(
+ url, name, value, domain, path, creation_time, expiration_time, secure,
+ http_only, first_party_only, enforce_strict_secure, priority));
if (!cc.get())
return false;
CookieOptions options;
options.set_include_httponly();
- options.set_include_first_party_only();
+ options.set_include_first_party_only_cookies();
+ if (enforce_strict_secure)
+ options.set_enforce_strict_secure();
return SetCanonicalCookie(&cc, creation_time, options);
}
@@ -1145,7 +1179,7 @@ bool CookieMonster::ImportCookies(const CookieList& list) {
scoped_ptr<CanonicalCookie> cookie(new CanonicalCookie(*iter));
CookieOptions options;
options.set_include_httponly();
- options.set_include_first_party_only();
+ options.set_include_first_party_only_cookies();
if (!SetCanonicalCookie(&cookie, cookie->CreationDate(), options))
return false;
}
@@ -1201,14 +1235,6 @@ CookieList CookieMonster::GetAllCookiesForURLWithOptions(
return cookies;
}
-CookieList CookieMonster::GetAllCookiesForURL(const GURL& url) {
- CookieOptions options;
- options.set_include_httponly();
- options.set_first_party_url(url);
-
- return GetAllCookiesForURLWithOptions(url, options);
-}
-
int CookieMonster::DeleteAll(bool sync_to_store) {
base::AutoLock autolock(lock_);
@@ -1366,7 +1392,7 @@ void CookieMonster::DeleteCookie(const GURL& url,
CookieOptions options;
options.set_include_httponly();
- options.set_include_first_party_only();
+ options.set_include_first_party_only_cookies();
// Get the cookies for this host and its domain(s).
std::vector<CanonicalCookie*> cookies;
FindCookiesForHostAndDomain(url, options, true, &cookies);
@@ -1547,7 +1573,7 @@ void CookieMonster::StoreLoadedCookies(
for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin();
it != cookies.end(); ++it) {
- int64 cookie_creation_time = (*it)->CreationDate().ToInternalValue();
+ int64_t cookie_creation_time = (*it)->CreationDate().ToInternalValue();
if (creation_times_.insert(cookie_creation_time).second) {
CookieMap::iterator inserted =
@@ -1776,25 +1802,57 @@ void CookieMonster::FindCookiesForKey(const std::string& key,
bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key,
const CanonicalCookie& ecc,
bool skip_httponly,
- bool already_expired) {
+ bool already_expired,
+ bool enforce_strict_secure) {
lock_.AssertAcquired();
bool found_equivalent_cookie = false;
bool skipped_httponly = false;
+ bool skipped_secure_cookie = false;
+
+ histogram_cookie_delete_equivalent_->Add(COOKIE_DELETE_EQUIVALENT_ATTEMPT);
+
for (CookieMapItPair its = cookies_.equal_range(key);
its.first != its.second;) {
CookieMap::iterator curit = its.first;
CanonicalCookie* cc = curit->second;
++its.first;
- if (ecc.IsEquivalent(*cc)) {
+ // If strict secure cookies is being enforced, then the equivalency
+ // requirements are looser. If the cookie is being set from an insecure
+ // scheme, then if a cookie already exists with the same name and it is
+ // Secure, then the cookie should *not* be updated if they domain-match and
+ // ignoring the path attribute.
+ //
+ // See: https://tools.ietf.org/html/draft-west-leave-secure-cookies-alone
+ if (enforce_strict_secure && !ecc.Source().SchemeIsCryptographic() &&
+ ecc.IsEquivalentForSecureCookieMatching(*cc) && cc->IsSecure()) {
+ skipped_secure_cookie = true;
+ histogram_cookie_delete_equivalent_->Add(
+ COOKIE_DELETE_EQUIVALENT_SKIPPING_SECURE);
+ // If the cookie is equivalent to the new cookie and wouldn't have been
+ // skipped for being HTTP-only, record that it is a skipped secure cookie
+ // that would have been deleted otherwise.
+ if (ecc.IsEquivalent(*cc)) {
+ found_equivalent_cookie = true;
+
+ if (!skip_httponly || !cc->IsHttpOnly()) {
+ histogram_cookie_delete_equivalent_->Add(
+ COOKIE_DELETE_EQUIVALENT_WOULD_HAVE_DELETED);
+ }
+ }
+ } else if (ecc.IsEquivalent(*cc)) {
// We should never have more than one equivalent cookie, since they should
- // overwrite each other.
+ // overwrite each other, unless secure cookies require secure scheme is
+ // being enforced. In that case, cookies with different paths might exist
+ // and be considered equivalent.
CHECK(!found_equivalent_cookie)
<< "Duplicate equivalent cookies found, cookie store is corrupted.";
if (skip_httponly && cc->IsHttpOnly()) {
skipped_httponly = true;
} else {
+ histogram_cookie_delete_equivalent_->Add(
+ COOKIE_DELETE_EQUIVALENT_FOUND);
InternalDeleteCookie(curit, true, already_expired
? DELETE_COOKIE_EXPIRED_OVERWRITE
: DELETE_COOKIE_OVERWRITE);
@@ -1802,7 +1860,7 @@ bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key,
found_equivalent_cookie = true;
}
}
- return skipped_httponly;
+ return skipped_httponly || skipped_secure_cookie;
}
CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
@@ -1889,8 +1947,18 @@ bool CookieMonster::SetCanonicalCookie(scoped_ptr<CanonicalCookie>* cc,
bool already_expired = (*cc)->IsExpired(creation_time);
if (DeleteAnyEquivalentCookie(key, **cc, options.exclude_httponly(),
- already_expired)) {
- VLOG(kVlogSetCookies) << "SetCookie() not clobbering httponly cookie";
+ already_expired,
+ options.enforce_strict_secure())) {
+ std::string error;
+ if (options.enforce_strict_secure()) {
+ error =
+ "SetCookie() not clobbering httponly cookie or secure cookie for "
+ "insecure scheme";
+ } else {
+ error = "SetCookie() not clobbering httponly cookie";
+ }
+
+ VLOG(kVlogSetCookies) << error;
return false;
}
@@ -1919,7 +1987,7 @@ bool CookieMonster::SetCanonicalCookie(scoped_ptr<CanonicalCookie>* cc,
// make sure that we garbage collect... We can also make the assumption that
// if a cookie was set, in the common case it will be used soon after,
// and we will purge the expired cookies in GetCookies().
- GarbageCollect(creation_time, key);
+ GarbageCollect(creation_time, key, options.enforce_strict_secure());
return true;
}
@@ -1991,33 +2059,69 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
delete cc;
}
+size_t CookieMonster::GarbageCollectLeastRecentlyAccessed(
+ const base::Time& current,
+ const base::Time& safe_date,
+ size_t purge_goal,
+ CookieItVector cookie_its) {
+ // Sorts up to *and including* |cookie_its[purge_goal]|, so
+ // |earliest_access_time| will be properly assigned even if
+ // |global_purge_it| == |cookie_its.begin() + purge_goal|.
+ SortLeastRecentlyAccessed(cookie_its.begin(), cookie_its.end(), purge_goal);
+ // Find boundary to cookies older than safe_date.
+ CookieItVector::iterator global_purge_it = LowerBoundAccessDate(
+ cookie_its.begin(), cookie_its.begin() + purge_goal, safe_date);
+ // Only delete the old cookies, and if strict secure is enabled, delete
+ // non-secure ones first.
+ size_t num_deleted =
+ GarbageCollectDeleteRange(current, DELETE_COOKIE_EVICTED_GLOBAL,
+ cookie_its.begin(), global_purge_it);
+ // Set access day to the oldest cookie that wasn't deleted.
+ earliest_access_time_ = (*global_purge_it)->second->LastAccessDate();
+ return num_deleted;
+}
+
// Domain expiry behavior is unchanged by key/expiry scheme (the
// meaning of the key is different, but that's not visible to this routine).
-int CookieMonster::GarbageCollect(const Time& current, const std::string& key) {
+size_t CookieMonster::GarbageCollect(const Time& current,
+ const std::string& key,
+ bool enforce_strict_secure) {
lock_.AssertAcquired();
- int num_deleted = 0;
+ size_t num_deleted = 0;
Time safe_date(Time::Now() - TimeDelta::FromDays(kSafeFromGlobalPurgeDays));
// Collect garbage for this key, minding cookie priorities.
if (cookies_.count(key) > kDomainMaxCookies) {
VLOG(kVlogGarbageCollection) << "GarbageCollect() key: " << key;
- CookieItVector cookie_its;
+ CookieItVector* cookie_its;
+
+ CookieItVector non_expired_cookie_its;
+ cookie_its = &non_expired_cookie_its;
num_deleted +=
- GarbageCollectExpired(current, cookies_.equal_range(key), &cookie_its);
- if (cookie_its.size() > kDomainMaxCookies) {
+ GarbageCollectExpired(current, cookies_.equal_range(key), cookie_its);
+
+ CookieItVector secure_cookie_its;
+ if (enforce_strict_secure && cookie_its->size() > kDomainMaxCookies) {
+ VLOG(kVlogGarbageCollection) << "Garbage collecting non-Secure cookies.";
+ num_deleted +=
+ GarbageCollectNonSecure(non_expired_cookie_its, &secure_cookie_its);
+ cookie_its = &secure_cookie_its;
+ }
+
+ if (cookie_its->size() > kDomainMaxCookies) {
VLOG(kVlogGarbageCollection) << "Deep Garbage Collect domain.";
size_t purge_goal =
- cookie_its.size() - (kDomainMaxCookies - kDomainPurgeCookies);
+ cookie_its->size() - (kDomainMaxCookies - kDomainPurgeCookies);
DCHECK(purge_goal > kDomainPurgeCookies);
// Boundary iterators into |cookie_its| for different priorities.
CookieItVector::iterator it_bdd[4];
// Intialize |it_bdd| while sorting |cookie_its| by priorities.
// Schematic: [MLLHMHHLMM] => [LLL|MMMM|HHH], with 4 boundaries.
- it_bdd[0] = cookie_its.begin();
- it_bdd[3] = cookie_its.end();
+ it_bdd[0] = cookie_its->begin();
+ it_bdd[3] = cookie_its->end();
it_bdd[1] =
PartitionCookieByPriority(it_bdd[0], it_bdd[3], COOKIE_PRIORITY_LOW);
it_bdd[2] = PartitionCookieByPriority(it_bdd[1], it_bdd[3],
@@ -2071,36 +2175,47 @@ int CookieMonster::GarbageCollect(const Time& current, const std::string& key) {
if (cookies_.size() > kMaxCookies && earliest_access_time_ < safe_date) {
VLOG(kVlogGarbageCollection) << "GarbageCollect() everything";
CookieItVector cookie_its;
+
num_deleted += GarbageCollectExpired(
current, CookieMapItPair(cookies_.begin(), cookies_.end()),
&cookie_its);
+
if (cookie_its.size() > kMaxCookies) {
VLOG(kVlogGarbageCollection) << "Deep Garbage Collect everything.";
size_t purge_goal = cookie_its.size() - (kMaxCookies - kPurgeCookies);
DCHECK(purge_goal > kPurgeCookies);
- // Sorts up to *and including* |cookie_its[purge_goal]|, so
- // |earliest_access_time| will be properly assigned even if
- // |global_purge_it| == |cookie_its.begin() + purge_goal|.
- SortLeastRecentlyAccessed(cookie_its.begin(), cookie_its.end(),
- purge_goal);
- // Find boundary to cookies older than safe_date.
- CookieItVector::iterator global_purge_it = LowerBoundAccessDate(
- cookie_its.begin(), cookie_its.begin() + purge_goal, safe_date);
- // Only delete the old cookies.
- num_deleted +=
- GarbageCollectDeleteRange(current, DELETE_COOKIE_EVICTED_GLOBAL,
- cookie_its.begin(), global_purge_it);
- // Set access day to the oldest cookie that wasn't deleted.
- earliest_access_time_ = (*global_purge_it)->second->LastAccessDate();
+
+ if (enforce_strict_secure) {
+ CookieItVector secure_cookie_its;
+ CookieItVector non_secure_cookie_its;
+ SplitCookieVectorIntoSecureAndNonSecure(cookie_its, &secure_cookie_its,
+ &non_secure_cookie_its);
+ size_t non_secure_purge_goal =
+ std::min<size_t>(purge_goal, non_secure_cookie_its.size() - 1);
+
+ size_t just_deleted = GarbageCollectLeastRecentlyAccessed(
+ current, safe_date, non_secure_purge_goal, non_secure_cookie_its);
+ num_deleted += just_deleted;
+
+ if (just_deleted < purge_goal) {
+ size_t secure_purge_goal = std::min<size_t>(
+ purge_goal - just_deleted, secure_cookie_its.size() - 1);
+ num_deleted += GarbageCollectLeastRecentlyAccessed(
+ current, safe_date, secure_purge_goal, secure_cookie_its);
+ }
+ } else {
+ num_deleted += GarbageCollectLeastRecentlyAccessed(
+ current, safe_date, purge_goal, cookie_its);
+ }
}
}
return num_deleted;
}
-int CookieMonster::GarbageCollectExpired(const Time& current,
- const CookieMapItPair& itpair,
- CookieItVector* cookie_its) {
+size_t CookieMonster::GarbageCollectExpired(const Time& current,
+ const CookieMapItPair& itpair,
+ CookieItVector* cookie_its) {
if (keep_expired_cookies_)
return 0;
@@ -2122,10 +2237,29 @@ int CookieMonster::GarbageCollectExpired(const Time& current,
return num_deleted;
}
-int CookieMonster::GarbageCollectDeleteRange(const Time& current,
- DeletionCause cause,
- CookieItVector::iterator it_begin,
- CookieItVector::iterator it_end) {
+size_t CookieMonster::GarbageCollectNonSecure(
+ const CookieItVector& valid_cookies,
+ CookieItVector* cookie_its) {
+ lock_.AssertAcquired();
+
+ size_t num_deleted = 0;
+ for (const auto& curr_cookie_it : valid_cookies) {
+ if (!curr_cookie_it->second->IsSecure()) {
+ InternalDeleteCookie(curr_cookie_it, true, DELETE_COOKIE_NON_SECURE);
+ ++num_deleted;
+ } else if (cookie_its) {
+ cookie_its->push_back(curr_cookie_it);
+ }
+ }
+
+ return num_deleted;
+}
+
+size_t CookieMonster::GarbageCollectDeleteRange(
+ const Time& current,
+ DeletionCause cause,
+ CookieItVector::iterator it_begin,
+ CookieItVector::iterator it_end) {
for (CookieItVector::iterator it = it_begin; it != it_end; it++) {
histogram_evicted_last_access_minutes_->Add(
(current - (*it)->second->LastAccessDate()).InMinutes());
@@ -2263,6 +2397,11 @@ void CookieMonster::InitializeHistograms() {
histogram_cookie_source_scheme_ = base::LinearHistogram::FactoryGet(
"Cookie.CookieSourceScheme", 1, COOKIE_SOURCE_LAST_ENTRY - 1,
COOKIE_SOURCE_LAST_ENTRY, base::Histogram::kUmaTargetedHistogramFlag);
+ histogram_cookie_delete_equivalent_ = base::LinearHistogram::FactoryGet(
+ "Cookie.CookieDeleteEquivalent", 1,
+ COOKIE_DELETE_EQUIVALENT_LAST_ENTRY - 1,
+ COOKIE_DELETE_EQUIVALENT_LAST_ENTRY,
+ base::Histogram::kUmaTargetedHistogramFlag);
// From UMA_HISTOGRAM_{CUSTOM_,}TIMES
histogram_time_blocked_on_load_ = base::Histogram::FactoryTimeGet(
@@ -2345,7 +2484,7 @@ void CookieMonster::RunCallbacks(const CanonicalCookie& cookie, bool removed) {
lock_.AssertAcquired();
CookieOptions opts;
opts.set_include_httponly();
- opts.set_include_first_party_only();
+ opts.set_include_first_party_only_cookies();
// Note that the callbacks in hook_map_ are wrapped with MakeAsync(), so they
// are guaranteed to not take long - they just post a RunAsync task back to
// the appropriate thread's message loop and return. It is important that this
diff --git a/chromium/net/cookies/cookie_monster.h b/chromium/net/cookies/cookie_monster.h
index ced1c235f7f..94c3813b4a2 100644
--- a/chromium/net/cookies/cookie_monster.h
+++ b/chromium/net/cookies/cookie_monster.h
@@ -7,6 +7,9 @@
#ifndef NET_COOKIES_COOKIE_MONSTER_H_
#define NET_COOKIES_COOKIE_MONSTER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <map>
#include <queue>
@@ -15,9 +18,9 @@
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -67,7 +70,6 @@ class ParsedCookie;
class NET_EXPORT CookieMonster : public CookieStore {
public:
class PersistentCookieStore;
- typedef CookieMonsterDelegate Delegate;
// Terminology:
// * The 'top level domain' (TLD) of an internet domain name is
@@ -168,6 +170,8 @@ class NET_EXPORT CookieMonster : public CookieStore {
bool secure,
bool http_only,
bool first_party,
+ bool enforce_prefixes,
+ bool enforce_strict_secure,
CookiePriority priority,
const SetCookiesCallback& callback);
@@ -363,6 +367,15 @@ class NET_EXPORT CookieMonster : public CookieStore {
// For CookieSource histogram enum.
FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, CookieSourceHistogram);
+ // For kSafeFromGlobalPurgeDays in CookieStore.
+ FRIEND_TEST_ALL_PREFIXES(CookieMonsterStrictSecureTest, EvictSecureCookies);
+
+ // For CookieDeleteEquivalent histogram enum.
+ FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
+ CookieDeleteEquivalentHistogramTest);
+ FRIEND_TEST_ALL_PREFIXES(CookieMonsterStrictSecureTest,
+ CookieDeleteEquivalentHistogramTest);
+
// Internal reasons for deletion, used to populate informative histograms
// and to provide a public cause for onCookieChange notifications.
//
@@ -399,6 +412,10 @@ class NET_EXPORT CookieMonster : public CookieStore {
// cookies as we load them. See http://crbug.com/238041.
DELETE_COOKIE_CONTROL_CHAR,
+ // When strict secure cookies is enabled, non-secure cookies are evicted
+ // right after expired cookies.
+ DELETE_COOKIE_NON_SECURE,
+
DELETE_COOKIE_LAST_ENTRY
};
@@ -433,6 +450,25 @@ class NET_EXPORT CookieMonster : public CookieStore {
COOKIE_SOURCE_LAST_ENTRY
};
+ // Used to populate a histogram for cookie setting in the "delete equivalent"
+ // step. Measures total attempts to delete an equivalent cookie as well as if
+ // a cookie is found to delete, if a cookie is skipped because it is secure,
+ // and if it is skipped for being secure but would have been deleted
+ // otherwise. The last two are only possible if strict secure cookies is
+ // turned on and if an insecure origin attempts to a set a cookie where a
+ // cookie with the same name and secure attribute already exists.
+ //
+ // Enum for UMA. Do no reorder or remove entries. New entries must be place
+ // directly before COOKIE_DELETE_EQUIVALENT_LAST_ENTRY and histograms.xml must
+ // be updated accordingly.
+ enum CookieDeleteEquivalent {
+ COOKIE_DELETE_EQUIVALENT_ATTEMPT = 0,
+ COOKIE_DELETE_EQUIVALENT_FOUND,
+ COOKIE_DELETE_EQUIVALENT_SKIPPING_SECURE,
+ COOKIE_DELETE_EQUIVALENT_WOULD_HAVE_DELETED,
+ COOKIE_DELETE_EQUIVALENT_LAST_ENTRY
+ };
+
// The strategy for fetching cookies. Controlled by Finch experiment.
enum FetchStrategy {
// Fetches all cookies only when they're needed.
@@ -465,6 +501,8 @@ class NET_EXPORT CookieMonster : public CookieStore {
bool secure,
bool http_only,
bool first_party,
+ bool enforce_prefixes,
+ bool enforce_strict_secure,
CookiePriority priority);
CookieList GetAllCookies();
@@ -472,8 +510,6 @@ class NET_EXPORT CookieMonster : public CookieStore {
CookieList GetAllCookiesForURLWithOptions(const GURL& url,
const CookieOptions& options);
- CookieList GetAllCookiesForURL(const GURL& url);
-
int DeleteAll(bool sync_to_store);
int DeleteAllCreatedBetween(const base::Time& delete_begin,
@@ -564,14 +600,17 @@ class NET_EXPORT CookieMonster : public CookieStore {
// Delete any cookies that are equivalent to |ecc| (same path, domain, etc).
// If |skip_httponly| is true, httponly cookies will not be deleted. The
- // return value with be true if |skip_httponly| skipped an httponly cookie.
- // |key| is the key to find the cookie in cookies_; see the comment before
- // the CookieMap typedef for details.
+ // return value will be true if |skip_httponly| skipped an httponly cookie or
+ // |enforce_strict_secure| is true and the cookie to
+ // delete was Secure and the scheme of |ecc| is insecure. |key| is the key to
+ // find the cookie in cookies_; see the comment before the CookieMap typedef
+ // for details.
// NOTE: There should never be more than a single matching equivalent cookie.
bool DeleteAnyEquivalentCookie(const std::string& key,
const CanonicalCookie& ecc,
bool skip_httponly,
- bool already_expired);
+ bool already_expired,
+ bool enforce_strict_secure);
// Takes ownership of *cc. Returns an iterator that points to the inserted
// cookie in cookies_. Guarantee: all iterators to cookies_ remain valid.
@@ -613,23 +652,41 @@ class NET_EXPORT CookieMonster : public CookieStore {
// constants for details.
//
// Returns the number of cookies deleted (useful for debugging).
- int GarbageCollect(const base::Time& current, const std::string& key);
+ size_t GarbageCollect(const base::Time& current,
+ const std::string& key,
+ bool enforce_strict_secure);
- // Helper for GarbageCollect(); can be called directly as well. Deletes
- // all expired cookies in |itpair|. If |cookie_its| is non-NULL, it is
- // populated with all the non-expired cookies from |itpair|.
+ // Helper for GarbageCollect(); can be called directly as well. Deletes all
+ // expired cookies in |itpair|. If |cookie_its| is non-NULL, all the
+ // non-expired cookies from |itpair| are appended to |cookie_its|.
//
// Returns the number of cookies deleted.
- int GarbageCollectExpired(const base::Time& current,
- const CookieMapItPair& itpair,
- std::vector<CookieMap::iterator>* cookie_its);
+ size_t GarbageCollectExpired(const base::Time& current,
+ const CookieMapItPair& itpair,
+ CookieItVector* cookie_its);
+
+ // Helper for GarbageCollect(). Deletes all cookies not marked Secure in
+ // |valid_cookies_its|. If |cookie_its| is non-NULL, all the Secure cookies
+ // from |itpair| are appended to |cookie_its|.
+ //
+ // Returns the numeber of cookies deleted.
+ size_t GarbageCollectNonSecure(const CookieItVector& valid_cookies,
+ CookieItVector* cookie_its);
// Helper for GarbageCollect(). Deletes all cookies in the range specified by
// [|it_begin|, |it_end|). Returns the number of cookies deleted.
- int GarbageCollectDeleteRange(const base::Time& current,
- DeletionCause cause,
- CookieItVector::iterator cookie_its_begin,
- CookieItVector::iterator cookie_its_end);
+ size_t GarbageCollectDeleteRange(const base::Time& current,
+ DeletionCause cause,
+ CookieItVector::iterator cookie_its_begin,
+ CookieItVector::iterator cookie_its_end);
+
+ // Helper for GarbageCollect(). Deletes cookies in |cookie_its| from least to
+ // most recently used, but only before |safe_date|. Also will stop deleting
+ // when the number of remaining cookies hits |purge_goal|.
+ size_t GarbageCollectLeastRecentlyAccessed(const base::Time& current,
+ const base::Time& safe_date,
+ size_t purge_goal,
+ CookieItVector cookie_its);
// Find the key (for lookup in cookies_) based on the given domain.
// See comment on keys before the CookieMap typedef.
@@ -682,6 +739,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
base::HistogramBase* histogram_cookie_deletion_cause_;
base::HistogramBase* histogram_cookie_type_;
base::HistogramBase* histogram_cookie_source_scheme_;
+ base::HistogramBase* histogram_cookie_delete_equivalent_;
base::HistogramBase* histogram_time_blocked_on_load_;
CookieMap cookies_;
@@ -732,7 +790,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
// 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> creation_times_;
+ std::set<int64_t> creation_times_;
std::vector<std::string> cookieable_schemes_;
diff --git a/chromium/net/cookies/cookie_monster_perftest.cc b/chromium/net/cookies/cookie_monster_perftest.cc
index 0214f68f4a8..dd35638ead3 100644
--- a/chromium/net/cookies/cookie_monster_perftest.cc
+++ b/chromium/net/cookies/cookie_monster_perftest.cc
@@ -284,7 +284,7 @@ TEST_F(CookieMonsterTest, TestImport) {
// We want to setup a fairly large backing store, with 300 domains of 50
// cookies each. Creation times must be unique.
- int64 time_tick(base::Time::Now().ToInternalValue());
+ int64_t time_tick(base::Time::Now().ToInternalValue());
for (int domain_num = 0; domain_num < 300; domain_num++) {
std::string domain_name(base::StringPrintf(".Domain_%d.com", domain_num));
@@ -371,7 +371,7 @@ TEST_F(CookieMonsterTest, TestGCTimes) {
for (int ci = 0; ci < static_cast<int>(arraysize(test_cases)); ++ci) {
const TestCase& test_case(test_cases[ci]);
scoped_refptr<CookieMonster> cm(CreateMonsterFromStoreForGC(
- test_case.num_cookies, test_case.num_old_cookies,
+ test_case.num_cookies, test_case.num_old_cookies, 0, 0,
CookieMonster::kSafeFromGlobalPurgeDays * 2));
GURL gurl("http://google.com");
diff --git a/chromium/net/cookies/cookie_monster_store_test.cc b/chromium/net/cookies/cookie_monster_store_test.cc
index bf422eddc88..8c004ef6140 100644
--- a/chromium/net/cookies/cookie_monster_store_test.cc
+++ b/chromium/net/cookies/cookie_monster_store_test.cc
@@ -93,7 +93,7 @@ MockCookieMonsterDelegate::MockCookieMonsterDelegate() {
void MockCookieMonsterDelegate::OnCookieChanged(
const CanonicalCookie& cookie,
bool removed,
- CookieMonster::Delegate::ChangeCause cause) {
+ CookieMonsterDelegate::ChangeCause cause) {
CookieNotification notification(cookie, removed);
changes_.push_back(notification);
}
@@ -168,21 +168,21 @@ void MockSimplePersistentCookieStore::LoadCookiesForKey(
}
void MockSimplePersistentCookieStore::AddCookie(const CanonicalCookie& cookie) {
- int64 creation_time = cookie.CreationDate().ToInternalValue();
+ int64_t creation_time = cookie.CreationDate().ToInternalValue();
EXPECT_TRUE(cookies_.find(creation_time) == cookies_.end());
cookies_[creation_time] = cookie;
}
void MockSimplePersistentCookieStore::UpdateCookieAccessTime(
const CanonicalCookie& cookie) {
- int64 creation_time = cookie.CreationDate().ToInternalValue();
+ int64_t creation_time = cookie.CreationDate().ToInternalValue();
ASSERT_TRUE(cookies_.find(creation_time) != cookies_.end());
cookies_[creation_time].SetLastAccessDate(base::Time::Now());
}
void MockSimplePersistentCookieStore::DeleteCookie(
const CanonicalCookie& cookie) {
- int64 creation_time = cookie.CreationDate().ToInternalValue();
+ int64_t creation_time = cookie.CreationDate().ToInternalValue();
CanonicalCookieMap::iterator it = cookies_.find(creation_time);
ASSERT_TRUE(it != cookies_.end());
cookies_.erase(it);
@@ -196,25 +196,40 @@ void MockSimplePersistentCookieStore::Flush(const base::Closure& callback) {
void MockSimplePersistentCookieStore::SetForceKeepSessionState() {
}
-CookieMonster* CreateMonsterFromStoreForGC(int num_cookies,
- int num_old_cookies,
+CookieMonster* CreateMonsterFromStoreForGC(int num_secure_cookies,
+ int num_old_secure_cookies,
+ int num_non_secure_cookies,
+ int num_old_non_secure_cookies,
int days_old) {
base::Time current(base::Time::Now());
base::Time past_creation(base::Time::Now() - base::TimeDelta::FromDays(1000));
scoped_refptr<MockSimplePersistentCookieStore> store(
new MockSimplePersistentCookieStore);
+ int total_cookies = num_secure_cookies + num_non_secure_cookies;
+ int base = 0;
// Must expire to be persistent
- for (int i = 0; i < num_cookies; i++) {
+ for (int i = 0; i < total_cookies; i++) {
+ int num_old_cookies;
+ bool secure;
+ if (i < num_secure_cookies) {
+ num_old_cookies = num_old_secure_cookies;
+ secure = true;
+ } else {
+ base = num_secure_cookies;
+ num_old_cookies = num_old_non_secure_cookies;
+ secure = false;
+ }
base::Time creation_time =
past_creation + base::TimeDelta::FromMicroseconds(i);
base::Time expiration_time = current + base::TimeDelta::FromDays(30);
base::Time last_access_time =
- (i < num_old_cookies) ? current - base::TimeDelta::FromDays(days_old)
- : current;
+ ((i - base) < num_old_cookies)
+ ? current - base::TimeDelta::FromDays(days_old)
+ : current;
CanonicalCookie cc(GURL(), "a", "1", base::StringPrintf("h%05d.izzle", i),
"/path", creation_time, expiration_time,
- last_access_time, false, false, false,
+ last_access_time, secure, false, false,
COOKIE_PRIORITY_DEFAULT);
store->AddCookie(cc);
}
diff --git a/chromium/net/cookies/cookie_monster_store_test.h b/chromium/net/cookies/cookie_monster_store_test.h
index 4e3d58bc184..686bb07afdb 100644
--- a/chromium/net/cookies/cookie_monster_store_test.h
+++ b/chromium/net/cookies/cookie_monster_store_test.h
@@ -10,10 +10,14 @@
#ifndef NET_COOKIES_COOKIE_MONSTER_STORE_TEST_H_
#define NET_COOKIES_COOKIE_MONSTER_STORE_TEST_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <utility>
#include <vector>
+
+#include "base/macros.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_monster.h"
@@ -166,7 +170,7 @@ class MockSimplePersistentCookieStore
~MockSimplePersistentCookieStore() override;
private:
- typedef std::map<int64, CanonicalCookie> CanonicalCookieMap;
+ typedef std::map<int64_t, CanonicalCookie> CanonicalCookieMap;
CanonicalCookieMap cookies_;
@@ -178,13 +182,16 @@ class MockSimplePersistentCookieStore
// Helper function for creating a CookieMonster backed by a
// MockSimplePersistentCookieStore for garbage collection testing.
//
-// Fill the store through import with |num_cookies| cookies, |num_old_cookies|
-// with access time Now()-days_old, the rest with access time Now().
-// Do two SetCookies(). Return whether each of the two SetCookies() took
-// longer than |gc_perf_micros| to complete, and how many cookie were
-// left in the store afterwards.
-CookieMonster* CreateMonsterFromStoreForGC(int num_cookies,
- int num_old_cookies,
+// Fill the store through import with |num_*_cookies| cookies,
+// |num_old_*_cookies| with access time Now()-days_old, the rest with access
+// time Now(). Cookies made by |num_secure_cookies| and |num_non_secure_cookies|
+// will be marked secure and non-secure, respectively. Do two SetCookies().
+// Return whether each of the two SetCookies() took longer than |gc_perf_micros|
+// to complete, and how many cookie were left in the store afterwards.
+CookieMonster* CreateMonsterFromStoreForGC(int num_secure_cookies,
+ int num_old_secure_cookies,
+ int num_non_secure_cookies,
+ int num_old_non_secure_cookies,
int days_old);
} // namespace net
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index c4df76558d7..efeadd96d58 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
@@ -70,7 +69,6 @@ const char kTopLevelDomainPlus2[] = "http://www.math.harvard.edu";
const char kTopLevelDomainPlus2Secure[] = "https://www.math.harvard.edu";
const char kTopLevelDomainPlus3[] = "http://www.bourbaki.math.harvard.edu";
const char kOtherDomain[] = "http://www.mit.edu";
-const char kUrlGoogleSpecific[] = "http://www.gmail.google.izzle";
class GetCookieListCallback : public CookieCallback {
public:
@@ -101,6 +99,22 @@ struct CookieMonsterTestTraits {
static const bool filters_schemes = true;
static const bool has_path_prefix_bug = false;
static const int creation_time_granularity_in_ms = 0;
+ static const bool enforce_strict_secure = false;
+};
+
+struct CookieMonsterEnforcingStrictSecure {
+ static scoped_refptr<CookieStore> Create() {
+ return new CookieMonster(NULL, NULL);
+ }
+
+ static const bool is_cookie_monster = true;
+ static const bool supports_http_only = true;
+ static const bool supports_non_dotted_domains = true;
+ static const bool preserves_trailing_dots = true;
+ static const bool filters_schemes = true;
+ static const bool has_path_prefix_bug = false;
+ static const int creation_time_granularity_in_ms = 0;
+ static const bool enforce_strict_secure = true;
};
INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
@@ -111,8 +125,20 @@ INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
MultiThreadedCookieStoreTest,
CookieMonsterTestTraits);
-class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
+INSTANTIATE_TYPED_TEST_CASE_P(CookieMonsterStrictSecure,
+ CookieStoreTest,
+ CookieMonsterEnforcingStrictSecure);
+
+template <typename T>
+class CookieMonsterTestBase : public CookieStoreTest<T> {
+ public:
+ using CookieStoreTest<T>::RunFor;
+ using CookieStoreTest<T>::SetCookie;
+
protected:
+ using CookieStoreTest<T>::http_www_google_;
+ using CookieStoreTest<T>::https_www_google_;
+
CookieList GetAllCookies(CookieMonster* cm) {
DCHECK(cm);
GetCookieListCallback callback;
@@ -161,7 +187,8 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
ResultSavingCookieCallback<bool> callback;
cm->SetCookieWithDetailsAsync(
url, name, value, domain, path, expiration_time, secure, http_only,
- first_party_only, priority,
+ first_party_only, false /* enforce prefixes */,
+ false /* enforces strict secure cookies */, priority,
base::Bind(&ResultSavingCookieCallback<bool>::Run,
base::Unretained(&callback)));
RunFor(kTimeout);
@@ -359,8 +386,9 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
for (int i = 0; i < more_than_enough_cookies; ++i) {
std::string cookie = base::StringPrintf("a%03d=b", i);
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, cookie));
- std::string cookies = this->GetCookies(cm.get(), url_google_);
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), cookie));
+ std::string cookies =
+ this->GetCookies(cm.get(), http_www_google_.url());
// Make sure we find it in the cookies.
EXPECT_NE(cookies.find(cookie), std::string::npos);
// Count the number of cookies.
@@ -371,15 +399,17 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
// Add a bunch of cookies on multiple hosts within a single eTLD.
// Should keep at least kDomainMaxCookies - kDomainPurgeCookies
// between them. We shouldn't go above kDomainMaxCookies for both together.
- GURL url_google_specific(kUrlGoogleSpecific);
+ GURL url_google_specific(http_www_google_.Format("http://www.gmail.%D"));
{
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
for (int i = 0; i < more_than_enough_cookies; ++i) {
std::string cookie_general = base::StringPrintf("a%03d=b", i);
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, cookie_general));
+ EXPECT_TRUE(
+ SetCookie(cm.get(), http_www_google_.url(), cookie_general));
std::string cookie_specific = base::StringPrintf("c%03d=b", i);
EXPECT_TRUE(SetCookie(cm.get(), url_google_specific, cookie_specific));
- std::string cookies_general = this->GetCookies(cm.get(), url_google_);
+ std::string cookies_general =
+ this->GetCookies(cm.get(), http_www_google_.url());
EXPECT_NE(cookies_general.find(cookie_general), std::string::npos);
std::string cookies_specific =
this->GetCookies(cm.get(), url_google_specific);
@@ -390,7 +420,8 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
}
// After all this, there should be at least
// kDomainMaxCookies - kDomainPurgeCookies for both URLs.
- std::string cookies_general = this->GetCookies(cm.get(), url_google_);
+ std::string cookies_general =
+ this->GetCookies(cm.get(), http_www_google_.url());
std::string cookies_specific =
this->GetCookies(cm.get(), url_google_specific);
int total_cookies = (CountInString(cookies_general, '=') +
@@ -413,8 +444,8 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
return COOKIE_PRIORITY_DEFAULT;
}
- // Instantiates a CookieMonster, adds multiple cookies (to url_google_) with
- // priorities specified by |coded_priority_str|, and tests priority-aware
+ // Instantiates a CookieMonster, adds multiple cookies (to http_www_google_)
+ // with priorities specified by |coded_priority_str|, and tests priority-aware
// domain cookie eviction.
// |coded_priority_str| specifies a run-length-encoded string of priorities.
// Example: "2M 3L M 4H" means "MMLLLMHHHH", and speicifies sequential (i.e.,
@@ -453,7 +484,7 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
for (; rep > 0; --rep, ++next_cookie_id) {
std::string cookie = base::StringPrintf(
"a%d=b;priority=%s", next_cookie_id, priority_str.c_str());
- EXPECT_TRUE(SetCookie(cm, url_google_, cookie));
+ EXPECT_TRUE(SetCookie(cm, http_www_google_.url(), cookie));
priority_list.push_back(priority);
id_list[priority].push_back(next_cookie_id);
}
@@ -463,7 +494,7 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
std::vector<int> surviving_id_list[3]; // Indexed by CookiePriority.
// Parse the list of cookies
- std::string cookie_str = this->GetCookies(cm, url_google_);
+ std::string cookie_str = this->GetCookies(cm, http_www_google_.url());
for (const std::string& token : base::SplitString(
cookie_str, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
// Assuming *it is "a#=b", so extract and parse "#" portion.
@@ -493,6 +524,68 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
}
}
+ // Represents a number of cookies to create, if they are Secure cookies, and
+ // a url to add them to.
+ struct CookiesEntry {
+ size_t num_cookies;
+ bool is_secure;
+ };
+ // A number of secure and a number of non-secure alternative hosts to create
+ // for testing.
+ typedef std::pair<size_t, size_t> AltHosts;
+ // Takes an array of CookieEntries which specify the number, type, and order
+ // of cookies to create. Cookies are created in the order they appear in
+ // cookie_entries. The value of cookie_entries[x].num_cookies specifies how
+ // many cookies of that type to create consecutively, while if
+ // cookie_entries[x].is_secure is |true|, those cookies will be marke as
+ // Secure.
+ void TestSecureCookieEviction(const CookiesEntry* cookie_entries,
+ size_t num_cookie_entries,
+ size_t expected_secure_cookies,
+ size_t expected_non_secure_cookies,
+ const AltHosts* alt_host_entries) {
+ scoped_refptr<CookieMonster> cm;
+
+ if (alt_host_entries == nullptr) {
+ cm = new CookieMonster(nullptr, nullptr);
+ } else {
+ // When generating all of these cookies on alternate hosts, they need to
+ // be all older than the max "safe" date for GC, which is currently 30
+ // days, so we set them to 60.
+ cm = CreateMonsterFromStoreForGC(
+ alt_host_entries->first, alt_host_entries->first,
+ alt_host_entries->second, alt_host_entries->second, 60);
+ }
+
+ int next_cookie_id = 0;
+ for (size_t i = 0; i < num_cookie_entries; i++) {
+ for (size_t j = 0; j < cookie_entries[i].num_cookies; j++) {
+ std::string cookie;
+ if (cookie_entries[i].is_secure)
+ cookie = base::StringPrintf("a%d=b; Secure", next_cookie_id);
+ else
+ cookie = base::StringPrintf("a%d=b", next_cookie_id);
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), cookie));
+ ++next_cookie_id;
+ }
+ }
+
+ CookieList cookies = this->GetAllCookies(cm.get());
+ EXPECT_EQ(expected_secure_cookies + expected_non_secure_cookies,
+ cookies.size());
+ size_t total_secure_cookies = 0;
+ size_t total_non_secure_cookies = 0;
+ for (const auto& cookie : cookies) {
+ if (cookie.IsSecure())
+ ++total_secure_cookies;
+ else
+ ++total_non_secure_cookies;
+ }
+
+ EXPECT_EQ(expected_secure_cookies, total_secure_cookies);
+ EXPECT_EQ(expected_non_secure_cookies, total_non_secure_cookies);
+ }
+
void TestPriorityAwareGarbageCollectHelper() {
// Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
@@ -572,6 +665,10 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
}
};
+using CookieMonsterTest = CookieMonsterTestBase<CookieMonsterTestTraits>;
+using CookieMonsterStrictSecureTest =
+ CookieMonsterTestBase<CookieMonsterEnforcingStrictSecure>;
+
// TODO(erikwright): Replace the other callbacks and synchronous helper methods
// in this test suite with these Mocks.
template <typename T, typename C>
@@ -637,7 +734,7 @@ struct CookiesInputInfo {
ACTION(QuitCurrentMessageLoop) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
// TODO(erikwright): When the synchronous helpers 'GetCookies' etc. are removed,
@@ -667,8 +764,9 @@ ACTION_P4(DeleteAllCreatedBetweenAction,
ACTION_P3(SetCookieWithDetailsAction, cookie_monster, cc, callback) {
cookie_monster->SetCookieWithDetailsAsync(
cc.url, cc.name, cc.value, cc.domain, cc.path, cc.expiration_time,
- cc.secure, cc.http_only, cc.first_party_only, cc.priority,
- callback->AsCallback());
+ cc.secure, cc.http_only, cc.first_party_only,
+ false /* enforce prefixes */, false /* enforces strict secure cookies */,
+ cc.priority, callback->AsCallback());
}
ACTION_P2(GetAllCookiesAction, cookie_monster, callback) {
@@ -816,20 +914,21 @@ class DeferredCookieTaskTest : public CookieMonsterTest {
};
TEST_F(DeferredCookieTaskTest, DeferredGetCookies) {
- DeclareLoadedCookie("www.google.izzle",
+ DeclareLoadedCookie(http_www_google_.host(),
"X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
Time::Now() + TimeDelta::FromDays(3));
MockGetCookiesCallback get_cookies_callback;
BeginWithForDomainKey(
- "google.izzle",
- GetCookiesAction(&cookie_monster(), url_google_, &get_cookies_callback));
+ http_www_google_.domain(),
+ GetCookiesAction(&cookie_monster(), http_www_google_.url(),
+ &get_cookies_callback));
WaitForLoadCall();
EXPECT_CALL(get_cookies_callback, Invoke("X=1"))
- .WillOnce(GetCookiesAction(&cookie_monster(), url_google_,
+ .WillOnce(GetCookiesAction(&cookie_monster(), http_www_google_.url(),
&get_cookies_callback));
EXPECT_CALL(get_cookies_callback, Invoke("X=1"))
.WillOnce(QuitCurrentMessageLoop());
@@ -840,15 +939,16 @@ TEST_F(DeferredCookieTaskTest, DeferredGetCookies) {
TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
MockSetCookiesCallback set_cookies_callback;
- BeginWithForDomainKey("google.izzle",
- SetCookieAction(&cookie_monster(), url_google_, "A=B",
- &set_cookies_callback));
+ BeginWithForDomainKey(
+ http_www_google_.domain(),
+ SetCookieAction(&cookie_monster(), http_www_google_.url(), "A=B",
+ &set_cookies_callback));
WaitForLoadCall();
EXPECT_CALL(set_cookies_callback, Invoke(true))
- .WillOnce(SetCookieAction(&cookie_monster(), url_google_, "X=Y",
- &set_cookies_callback));
+ .WillOnce(SetCookieAction(&cookie_monster(), http_www_google_.url(),
+ "X=Y", &set_cookies_callback));
EXPECT_CALL(set_cookies_callback, Invoke(true))
.WillOnce(QuitCurrentMessageLoop());
@@ -858,10 +958,12 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
MockSetCookiesCallback set_cookies_callback;
CookieList list;
- list.push_back(CanonicalCookie(url_google_, "A", "B", "google.izzle", "/",
+ list.push_back(CanonicalCookie(http_www_google_.url(), "A", "B",
+ http_www_google_.domain(), "/",
base::Time::Now(), base::Time(), base::Time(),
false, true, false, COOKIE_PRIORITY_DEFAULT));
- list.push_back(CanonicalCookie(url_google_, "C", "D", "google.izzle", "/",
+ list.push_back(CanonicalCookie(http_www_google_.url(), "C", "D",
+ http_www_google_.domain(), "/",
base::Time::Now(), base::Time(), base::Time(),
false, true, false, COOKIE_PRIORITY_DEFAULT));
@@ -882,15 +984,16 @@ TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
TEST_F(DeferredCookieTaskTest, DeferredDeleteCookie) {
MockClosure delete_cookie_callback;
- BeginWithForDomainKey("google.izzle",
- DeleteCookieAction(&cookie_monster(), url_google_, "A",
- &delete_cookie_callback));
+ BeginWithForDomainKey(
+ http_www_google_.domain(),
+ DeleteCookieAction(&cookie_monster(), http_www_google_.url(), "A",
+ &delete_cookie_callback));
WaitForLoadCall();
EXPECT_CALL(delete_cookie_callback, Invoke())
- .WillOnce(DeleteCookieAction(&cookie_monster(), url_google_, "X",
- &delete_cookie_callback));
+ .WillOnce(DeleteCookieAction(&cookie_monster(), http_www_google_.url(),
+ "X", &delete_cookie_callback));
EXPECT_CALL(delete_cookie_callback, Invoke())
.WillOnce(QuitCurrentMessageLoop());
@@ -900,7 +1003,7 @@ TEST_F(DeferredCookieTaskTest, DeferredDeleteCookie) {
TEST_F(DeferredCookieTaskTest, DeferredSetCookieWithDetails) {
MockSetCookiesCallback set_cookies_callback;
- CookiesInputInfo cookie_info = {url_google_foo_,
+ CookiesInputInfo cookie_info = {www_google_foo_.url(),
"A",
"B",
std::string(),
@@ -911,12 +1014,13 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookieWithDetails) {
false,
COOKIE_PRIORITY_DEFAULT};
BeginWithForDomainKey(
- "google.izzle", SetCookieWithDetailsAction(&cookie_monster(), cookie_info,
- &set_cookies_callback));
+ http_www_google_.domain(),
+ SetCookieWithDetailsAction(&cookie_monster(), cookie_info,
+ &set_cookies_callback));
WaitForLoadCall();
- CookiesInputInfo cookie_info_exp = {url_google_foo_,
+ CookiesInputInfo cookie_info_exp = {www_google_foo_.url(),
"A",
"B",
std::string(),
@@ -936,7 +1040,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookieWithDetails) {
}
TEST_F(DeferredCookieTaskTest, DeferredGetAllCookies) {
- DeclareLoadedCookie("www.google.izzle",
+ DeclareLoadedCookie(http_www_google_.host(),
"X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
Time::Now() + TimeDelta::FromDays(3));
@@ -956,20 +1060,22 @@ TEST_F(DeferredCookieTaskTest, DeferredGetAllCookies) {
}
TEST_F(DeferredCookieTaskTest, DeferredGetAllForUrlCookies) {
- DeclareLoadedCookie("www.google.izzle",
+ DeclareLoadedCookie(http_www_google_.host(),
"X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
Time::Now() + TimeDelta::FromDays(3));
MockGetCookieListCallback get_cookie_list_callback;
BeginWithForDomainKey(
- "google.izzle", GetAllCookiesForUrlAction(&cookie_monster(), url_google_,
- &get_cookie_list_callback));
+ http_www_google_.domain(),
+ GetAllCookiesForUrlAction(&cookie_monster(), http_www_google_.url(),
+ &get_cookie_list_callback));
WaitForLoadCall();
EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
- .WillOnce(GetAllCookiesForUrlAction(&cookie_monster(), url_google_,
+ .WillOnce(GetAllCookiesForUrlAction(&cookie_monster(),
+ http_www_google_.url(),
&get_cookie_list_callback));
EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
.WillOnce(QuitCurrentMessageLoop());
@@ -978,21 +1084,23 @@ TEST_F(DeferredCookieTaskTest, DeferredGetAllForUrlCookies) {
}
TEST_F(DeferredCookieTaskTest, DeferredGetAllForUrlWithOptionsCookies) {
- DeclareLoadedCookie("www.google.izzle",
+ DeclareLoadedCookie(http_www_google_.host(),
"X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
Time::Now() + TimeDelta::FromDays(3));
MockGetCookieListCallback get_cookie_list_callback;
- BeginWithForDomainKey("google.izzle", GetAllCookiesForUrlWithOptionsAction(
- &cookie_monster(), url_google_,
- &get_cookie_list_callback));
+ BeginWithForDomainKey(http_www_google_.domain(),
+ GetAllCookiesForUrlWithOptionsAction(
+ &cookie_monster(), http_www_google_.url(),
+ &get_cookie_list_callback));
WaitForLoadCall();
EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
.WillOnce(GetAllCookiesForUrlWithOptionsAction(
- &cookie_monster(), url_google_, &get_cookie_list_callback));
+ &cookie_monster(), http_www_google_.url(),
+ &get_cookie_list_callback));
EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
.WillOnce(QuitCurrentMessageLoop());
@@ -1036,14 +1144,15 @@ TEST_F(DeferredCookieTaskTest, DeferredDeleteAllForHostCookies) {
MockDeleteCallback delete_callback;
BeginWithForDomainKey(
- "google.izzle",
- DeleteAllForHostAction(&cookie_monster(), url_google_, &delete_callback));
+ http_www_google_.domain(),
+ DeleteAllForHostAction(&cookie_monster(), http_www_google_.url(),
+ &delete_callback));
WaitForLoadCall();
EXPECT_CALL(delete_callback, Invoke(false))
- .WillOnce(DeleteAllForHostAction(&cookie_monster(), url_google_,
- &delete_callback));
+ .WillOnce(DeleteAllForHostAction(
+ &cookie_monster(), http_www_google_.url(), &delete_callback));
EXPECT_CALL(delete_callback, Invoke(false))
.WillOnce(QuitCurrentMessageLoop());
@@ -1052,8 +1161,8 @@ TEST_F(DeferredCookieTaskTest, DeferredDeleteAllForHostCookies) {
TEST_F(DeferredCookieTaskTest, DeferredDeleteCanonicalCookie) {
std::vector<CanonicalCookie*> cookies;
- CanonicalCookie cookie =
- BuildCanonicalCookie("www.google.com", "X=1; path=/", base::Time::Now());
+ CanonicalCookie cookie = BuildCanonicalCookie(
+ http_www_google_.host(), "X=1; path=/", base::Time::Now());
MockDeleteCookieCallback delete_cookie_callback;
@@ -1091,7 +1200,7 @@ TEST_F(DeferredCookieTaskTest, DeferredDeleteSessionCookies) {
// the backing store and that new tasks received while the queued tasks are
// being dispatched go to the end of the queue.
TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
- DeclareLoadedCookie("www.google.izzle",
+ DeclareLoadedCookie(http_www_google_.host(),
"X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
Time::Now() + TimeDelta::FromDays(3));
@@ -1100,17 +1209,18 @@ TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
MockGetCookiesCallback get_cookies_callback_deferred;
EXPECT_CALL(*this, Begin())
- .WillOnce(testing::DoAll(GetCookiesAction(&cookie_monster(), url_google_,
- &get_cookies_callback),
- SetCookieAction(&cookie_monster(), url_google_,
- "A=B", &set_cookies_callback)));
+ .WillOnce(testing::DoAll(
+ GetCookiesAction(&cookie_monster(), http_www_google_.url(),
+ &get_cookies_callback),
+ SetCookieAction(&cookie_monster(), http_www_google_.url(), "A=B",
+ &set_cookies_callback)));
ExpectLoadCall();
- ExpectLoadForKeyCall("google.izzle", false);
+ ExpectLoadForKeyCall(http_www_google_.domain(), false);
Begin();
WaitForLoadCall();
EXPECT_CALL(get_cookies_callback, Invoke("X=1"))
- .WillOnce(GetCookiesAction(&cookie_monster(), url_google_,
+ .WillOnce(GetCookiesAction(&cookie_monster(), http_www_google_.url(),
&get_cookies_callback_deferred));
EXPECT_CALL(set_cookies_callback, Invoke(true));
EXPECT_CALL(get_cookies_callback_deferred, Invoke("A=B; X=1"))
@@ -1125,20 +1235,22 @@ TEST_F(CookieMonsterTest, TestCookieDeleteAll) {
CookieOptions options;
options.set_include_httponly();
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, kValidCookieLine));
- EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), kValidCookieLine));
+ EXPECT_EQ("A=B", GetCookies(cm.get(), http_www_google_.url()));
- EXPECT_TRUE(
- SetCookieWithOptions(cm.get(), url_google_, "C=D; httponly", options));
- EXPECT_EQ("A=B; C=D", GetCookiesWithOptions(cm.get(), url_google_, options));
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_google_.url(),
+ "C=D; httponly", options));
+ EXPECT_EQ("A=B; C=D",
+ GetCookiesWithOptions(cm.get(), http_www_google_.url(), options));
EXPECT_EQ(2, DeleteAll(cm.get()));
- EXPECT_EQ("", GetCookiesWithOptions(cm.get(), url_google_, options));
+ EXPECT_EQ("",
+ GetCookiesWithOptions(cm.get(), http_www_google_.url(), options));
EXPECT_EQ(0u, store->commands().size());
// Create a persistent cookie.
EXPECT_TRUE(SetCookie(
- cm.get(), url_google_,
+ cm.get(), http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
ASSERT_EQ(1u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
@@ -1147,7 +1259,8 @@ TEST_F(CookieMonsterTest, TestCookieDeleteAll) {
ASSERT_EQ(2u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
- EXPECT_EQ("", GetCookiesWithOptions(cm.get(), url_google_, options));
+ EXPECT_EQ("",
+ GetCookiesWithOptions(cm.get(), http_www_google_.url(), options));
}
TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedBetweenTimestamps) {
@@ -1159,15 +1272,16 @@ TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedBetweenTimestamps) {
Time()));
// Create 3 cookies with creation date of today, yesterday and the day before.
- EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-0=Now", now));
- EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-1=Yesterday",
- now - TimeDelta::FromDays(1)));
- EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-2=DayBefore",
- now - TimeDelta::FromDays(2)));
- EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-3=ThreeDays",
- now - TimeDelta::FromDays(3)));
- EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-7=LastWeek",
- now - TimeDelta::FromDays(7)));
+ EXPECT_TRUE(
+ cm->SetCookieWithCreationTime(http_www_google_.url(), "T-0=Now", now));
+ EXPECT_TRUE(cm->SetCookieWithCreationTime(
+ http_www_google_.url(), "T-1=Yesterday", now - TimeDelta::FromDays(1)));
+ EXPECT_TRUE(cm->SetCookieWithCreationTime(
+ http_www_google_.url(), "T-2=DayBefore", now - TimeDelta::FromDays(2)));
+ EXPECT_TRUE(cm->SetCookieWithCreationTime(
+ http_www_google_.url(), "T-3=ThreeDays", now - TimeDelta::FromDays(3)));
+ EXPECT_TRUE(cm->SetCookieWithCreationTime(
+ http_www_google_.url(), "T-7=LastWeek", now - TimeDelta::FromDays(7)));
// Try to delete threedays and the daybefore.
EXPECT_EQ(2, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(3),
@@ -1195,18 +1309,18 @@ TEST_F(CookieMonsterTest, TestLastAccess) {
scoped_refptr<CookieMonster> cm(
new CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
const Time last_access_date(GetFirstCookieAccessDate(cm.get()));
// Reading the cookie again immediately shouldn't update the access date,
// since we're inside the threshold.
- EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));
+ EXPECT_EQ("A=B", GetCookies(cm.get(), http_www_google_.url()));
EXPECT_TRUE(last_access_date == GetFirstCookieAccessDate(cm.get()));
// Reading after a short wait should update the access date.
base::PlatformThread::Sleep(
base::TimeDelta::FromMilliseconds(kAccessDelayMs));
- EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));
+ EXPECT_EQ("A=B", GetCookies(cm.get(), http_www_google_.url()));
EXPECT_FALSE(last_access_date == GetFirstCookieAccessDate(cm.get()));
}
@@ -1221,16 +1335,17 @@ TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollection) {
TEST_F(CookieMonsterTest, TestDeleteSingleCookie) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "C=D"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "E=F"));
- EXPECT_EQ("A=B; C=D; E=F", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "C=D"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "E=F"));
+ EXPECT_EQ("A=B; C=D; E=F", GetCookies(cm.get(), http_www_google_.url()));
- EXPECT_TRUE(FindAndDeleteCookie(cm.get(), url_google_.host(), "C"));
- EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(
+ FindAndDeleteCookie(cm.get(), http_www_google_.url().host(), "C"));
+ EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), http_www_google_.url()));
EXPECT_FALSE(FindAndDeleteCookie(cm.get(), "random.host", "E"));
- EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));
+ EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), http_www_google_.url()));
}
TEST_F(CookieMonsterTest, SetCookieableSchemes) {
@@ -1258,13 +1373,14 @@ TEST_F(CookieMonsterTest, GetAllCookiesForURL) {
CookieOptions options;
options.set_include_httponly();
- EXPECT_TRUE(
- SetCookieWithOptions(cm.get(), url_google_, "A=B; httponly", options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_,
- "C=D; domain=.google.izzle", options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_secure_,
- "E=F; domain=.google.izzle; secure",
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_google_.url(),
+ "A=B; httponly", options));
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_google_.url(),
+ http_www_google_.Format("C=D; domain=.%D"),
options));
+ EXPECT_TRUE(SetCookieWithOptions(
+ cm.get(), https_www_google_.url(),
+ http_www_google_.Format("E=F; domain=.%D; secure"), options));
const Time last_access_date(GetFirstCookieAccessDate(cm.get()));
@@ -1272,44 +1388,44 @@ TEST_F(CookieMonsterTest, GetAllCookiesForURL) {
base::TimeDelta::FromMilliseconds(kAccessDelayMs));
// Check cookies for url.
- CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_);
+ CookieList cookies = GetAllCookiesForURL(cm.get(), http_www_google_.url());
CookieList::iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it != cookies.end());
- EXPECT_EQ(".google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.Format(".%D"), it->Domain());
EXPECT_EQ("C", it->Name());
ASSERT_TRUE(++it == cookies.end());
// Check cookies for url excluding http-only cookies.
- cookies =
- GetAllCookiesForURLWithOptions(cm.get(), url_google_, CookieOptions());
+ cookies = GetAllCookiesForURLWithOptions(cm.get(), http_www_google_.url(),
+ CookieOptions());
it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
- EXPECT_EQ(".google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.Format(".%D"), it->Domain());
EXPECT_EQ("C", it->Name());
ASSERT_TRUE(++it == cookies.end());
// Test secure cookies.
- cookies = GetAllCookiesForURL(cm.get(), url_google_secure_);
+ cookies = GetAllCookiesForURL(cm.get(), https_www_google_.url());
it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it != cookies.end());
- EXPECT_EQ(".google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.Format(".%D"), it->Domain());
EXPECT_EQ("C", it->Name());
ASSERT_TRUE(++it != cookies.end());
- EXPECT_EQ(".google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.Format(".%D"), it->Domain());
EXPECT_EQ("E", it->Name());
ASSERT_TRUE(++it == cookies.end());
@@ -1322,13 +1438,14 @@ TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
CookieOptions options;
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_foo_, "A=B; path=/foo;",
- options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_bar_, "C=D; path=/bar;",
- options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "E=F;", options));
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), www_google_foo_.url(),
+ "A=B; path=/foo;", options));
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), www_google_bar_.url(),
+ "C=D; path=/bar;", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "E=F;", options));
- CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_foo_);
+ CookieList cookies = GetAllCookiesForURL(cm.get(), www_google_foo_.url());
CookieList::iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
@@ -1341,7 +1458,7 @@ TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) {
ASSERT_TRUE(++it == cookies.end());
- cookies = GetAllCookiesForURL(cm.get(), url_google_bar_);
+ cookies = GetAllCookiesForURL(cm.get(), www_google_bar_.url());
it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
@@ -1358,15 +1475,18 @@ TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) {
TEST_F(CookieMonsterTest, CookieSorting) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B1; path=/"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B2; path=/foo"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B3; path=/foo/bar"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A1; path=/"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A2; path=/foo"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A3; path=/foo/bar"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B1; path=/"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B2; path=/foo"));
+ EXPECT_TRUE(
+ SetCookie(cm.get(), http_www_google_.url(), "B=B3; path=/foo/bar"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A1; path=/"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A2; path=/foo"));
+ EXPECT_TRUE(
+ SetCookie(cm.get(), http_www_google_.url(), "A=A3; path=/foo/bar"));
// Re-set cookie which should not change sort order.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B3; path=/foo/bar"));
+ EXPECT_TRUE(
+ SetCookie(cm.get(), http_www_google_.url(), "B=B3; path=/foo/bar"));
CookieList cookies = GetAllCookies(cm.get());
ASSERT_EQ(6u, cookies.size());
@@ -1385,14 +1505,14 @@ TEST_F(CookieMonsterTest, CookieSorting) {
TEST_F(CookieMonsterTest, DeleteCookieByName) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A1; path=/"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A2; path=/foo"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A3; path=/bar"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B1; path=/"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B2; path=/foo"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B3; path=/bar"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A1; path=/"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A2; path=/foo"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=A3; path=/bar"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B1; path=/"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B2; path=/foo"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=B3; path=/bar"));
- DeleteCookie(cm.get(), GURL(std::string(kUrlGoogle) + "/foo/bar"), "A");
+ DeleteCookie(cm.get(), http_www_google_.AppendPath("foo/bar"), "A");
CookieList cookies = GetAllCookies(cm.get());
size_t expected_size = 4;
@@ -1407,11 +1527,12 @@ TEST_F(CookieMonsterTest, ImportCookiesFromCookieMonster) {
scoped_refptr<CookieMonster> cm_1(new CookieMonster(NULL, NULL));
CookieOptions options;
- EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), url_google_foo_,
+ EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), www_google_foo_.url(),
"A1=B; path=/foo;", options));
- EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), url_google_bar_,
+ EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), www_google_bar_.url(),
"A2=D; path=/bar;", options));
- EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), url_google_, "A3=F;", options));
+ EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), http_www_google_.url(), "A3=F;",
+ options));
CookieList cookies_1 = GetAllCookies(cm_1.get());
scoped_refptr<CookieMonster> cm_2(new CookieMonster(NULL, NULL));
@@ -1559,47 +1680,53 @@ TEST_F(CookieMonsterTest, CookieMonsterDelegate) {
scoped_refptr<CookieMonster> cm(
new CookieMonster(store.get(), delegate.get()));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "C=D"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "E=F"));
- EXPECT_EQ("A=B; C=D; E=F", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "C=D"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "E=F"));
+ EXPECT_EQ("A=B; C=D; E=F", GetCookies(cm.get(), http_www_google_.url()));
ASSERT_EQ(3u, delegate->changes().size());
EXPECT_FALSE(delegate->changes()[0].second);
- EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
+ EXPECT_EQ(http_www_google_.url().host(),
+ delegate->changes()[0].first.Domain());
EXPECT_EQ("A", delegate->changes()[0].first.Name());
EXPECT_EQ("B", delegate->changes()[0].first.Value());
- EXPECT_EQ(url_google_.host(), delegate->changes()[1].first.Domain());
+ EXPECT_EQ(http_www_google_.url().host(),
+ delegate->changes()[1].first.Domain());
EXPECT_FALSE(delegate->changes()[1].second);
EXPECT_EQ("C", delegate->changes()[1].first.Name());
EXPECT_EQ("D", delegate->changes()[1].first.Value());
- EXPECT_EQ(url_google_.host(), delegate->changes()[2].first.Domain());
+ EXPECT_EQ(http_www_google_.url().host(),
+ delegate->changes()[2].first.Domain());
EXPECT_FALSE(delegate->changes()[2].second);
EXPECT_EQ("E", delegate->changes()[2].first.Name());
EXPECT_EQ("F", delegate->changes()[2].first.Value());
delegate->reset();
- EXPECT_TRUE(FindAndDeleteCookie(cm.get(), url_google_.host(), "C"));
- EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(
+ FindAndDeleteCookie(cm.get(), http_www_google_.url().host(), "C"));
+ EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), http_www_google_.url()));
ASSERT_EQ(1u, delegate->changes().size());
- EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
+ EXPECT_EQ(http_www_google_.url().host(),
+ delegate->changes()[0].first.Domain());
EXPECT_TRUE(delegate->changes()[0].second);
EXPECT_EQ("C", delegate->changes()[0].first.Name());
EXPECT_EQ("D", delegate->changes()[0].first.Value());
delegate->reset();
EXPECT_FALSE(FindAndDeleteCookie(cm.get(), "random.host", "E"));
- EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));
+ EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), http_www_google_.url()));
EXPECT_EQ(0u, delegate->changes().size());
// Insert a cookie "a" for path "/path1"
- EXPECT_TRUE(SetCookie(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(),
"a=val1; path=/path1; "
"expires=Mon, 18-Apr-22 22:50:13 GMT"));
ASSERT_EQ(1u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
ASSERT_EQ(1u, delegate->changes().size());
EXPECT_FALSE(delegate->changes()[0].second);
- EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
+ EXPECT_EQ(http_www_google_.url().host(),
+ delegate->changes()[0].first.Domain());
EXPECT_EQ("a", delegate->changes()[0].first.Name());
EXPECT_EQ("val1", delegate->changes()[0].first.Value());
delegate->reset();
@@ -1608,7 +1735,7 @@ TEST_F(CookieMonsterTest, CookieMonsterDelegate) {
// overwrite the non-http-only version.
CookieOptions allow_httponly;
allow_httponly.set_include_httponly();
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_google_.url(),
"a=val2; path=/path1; httponly; "
"expires=Mon, 18-Apr-22 22:50:14 GMT",
allow_httponly));
@@ -1616,11 +1743,13 @@ TEST_F(CookieMonsterTest, CookieMonsterDelegate) {
EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
ASSERT_EQ(2u, delegate->changes().size());
- EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
+ EXPECT_EQ(http_www_google_.url().host(),
+ delegate->changes()[0].first.Domain());
EXPECT_TRUE(delegate->changes()[0].second);
EXPECT_EQ("a", delegate->changes()[0].first.Name());
EXPECT_EQ("val1", delegate->changes()[0].first.Value());
- EXPECT_EQ(url_google_.host(), delegate->changes()[1].first.Domain());
+ EXPECT_EQ(http_www_google_.url().host(),
+ delegate->changes()[1].first.Domain());
EXPECT_FALSE(delegate->changes()[1].second);
EXPECT_EQ("a", delegate->changes()[1].first.Name());
EXPECT_EQ("val2", delegate->changes()[1].first.Value());
@@ -1630,40 +1759,40 @@ TEST_F(CookieMonsterTest, CookieMonsterDelegate) {
TEST_F(CookieMonsterTest, SetCookieWithDetails) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookieWithDetails(cm.get(), url_google_foo_, "A", "B",
+ EXPECT_TRUE(SetCookieWithDetails(cm.get(), www_google_foo_.url(), "A", "B",
std::string(), "/foo", base::Time(), false,
false, false, COOKIE_PRIORITY_DEFAULT));
- EXPECT_TRUE(SetCookieWithDetails(cm.get(), url_google_bar_, "C", "D",
- "google.izzle", "/bar", base::Time(), false,
- true, false, COOKIE_PRIORITY_DEFAULT));
EXPECT_TRUE(SetCookieWithDetails(
- cm.get(), url_google_, "E", "F", std::string(), std::string(),
+ cm.get(), www_google_bar_.url(), "C", "D", www_google_bar_.domain(),
+ "/bar", base::Time(), false, true, false, COOKIE_PRIORITY_DEFAULT));
+ EXPECT_TRUE(SetCookieWithDetails(
+ cm.get(), http_www_google_.url(), "E", "F", std::string(), std::string(),
base::Time(), true, false, false, COOKIE_PRIORITY_DEFAULT));
// Test that malformed attributes fail to set the cookie.
- EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, " A", "B",
+ EXPECT_FALSE(SetCookieWithDetails(cm.get(), www_google_foo_.url(), " A", "B",
std::string(), "/foo", base::Time(), false,
false, false, COOKIE_PRIORITY_DEFAULT));
- EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, "A;", "B",
+ EXPECT_FALSE(SetCookieWithDetails(cm.get(), www_google_foo_.url(), "A;", "B",
std::string(), "/foo", base::Time(), false,
false, false, COOKIE_PRIORITY_DEFAULT));
- EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, "A=", "B",
+ EXPECT_FALSE(SetCookieWithDetails(cm.get(), www_google_foo_.url(), "A=", "B",
std::string(), "/foo", base::Time(), false,
false, false, COOKIE_PRIORITY_DEFAULT));
EXPECT_FALSE(SetCookieWithDetails(
- cm.get(), url_google_foo_, "A", "B", "google.ozzzzzzle", "foo",
+ cm.get(), www_google_foo_.url(), "A", "B", "google.ozzzzzzle", "foo",
base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
- EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, "A=", "B",
+ EXPECT_FALSE(SetCookieWithDetails(cm.get(), www_google_foo_.url(), "A=", "B",
std::string(), "foo", base::Time(), false,
false, false, COOKIE_PRIORITY_DEFAULT));
- CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_foo_);
+ CookieList cookies = GetAllCookiesForURL(cm.get(), www_google_foo_.url());
CookieList::iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
EXPECT_EQ("A", it->Name());
EXPECT_EQ("B", it->Value());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(www_google_foo_.host(), it->Domain());
EXPECT_EQ("/foo", it->Path());
EXPECT_FALSE(it->IsPersistent());
EXPECT_FALSE(it->IsSecure());
@@ -1671,27 +1800,27 @@ TEST_F(CookieMonsterTest, SetCookieWithDetails) {
ASSERT_TRUE(++it == cookies.end());
- cookies = GetAllCookiesForURL(cm.get(), url_google_bar_);
+ cookies = GetAllCookiesForURL(cm.get(), www_google_bar_.url());
it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
EXPECT_EQ("C", it->Name());
EXPECT_EQ("D", it->Value());
- EXPECT_EQ(".google.izzle", it->Domain());
+ EXPECT_EQ(www_google_bar_.Format(".%D"), it->Domain());
EXPECT_EQ("/bar", it->Path());
EXPECT_FALSE(it->IsSecure());
EXPECT_TRUE(it->IsHttpOnly());
ASSERT_TRUE(++it == cookies.end());
- cookies = GetAllCookiesForURL(cm.get(), url_google_secure_);
+ cookies = GetAllCookiesForURL(cm.get(), https_www_google_.url());
it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
EXPECT_EQ("E", it->Name());
EXPECT_EQ("F", it->Value());
EXPECT_EQ("/", it->Path());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(https_www_google_.host(), it->Domain());
EXPECT_TRUE(it->IsSecure());
EXPECT_FALSE(it->IsHttpOnly());
@@ -1779,35 +1908,38 @@ TEST_F(CookieMonsterTest, UniqueCreationTime) {
// SetCookie, SetCookieWithOptions, SetCookieWithDetails
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "SetCookie1=A"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "SetCookie2=A"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "SetCookie3=A"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "SetCookie1=A"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "SetCookie2=A"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "SetCookie3=A"));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_google_.url(),
"setCookieWithOptions1=A", options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_google_.url(),
"setCookieWithOptions2=A", options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_google_.url(),
"setCookieWithOptions3=A", options));
EXPECT_TRUE(SetCookieWithDetails(
- cm.get(), url_google_, "setCookieWithDetails1", "A", ".google.izzle", "/",
- Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
+ cm.get(), http_www_google_.url(), "setCookieWithDetails1", "A",
+ http_www_google_.Format(".%D"), "/", Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT));
EXPECT_TRUE(SetCookieWithDetails(
- cm.get(), url_google_, "setCookieWithDetails2", "A", ".google.izzle", "/",
- Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
+ cm.get(), http_www_google_.url(), "setCookieWithDetails2", "A",
+ http_www_google_.Format(".%D"), "/", Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT));
EXPECT_TRUE(SetCookieWithDetails(
- cm.get(), url_google_, "setCookieWithDetails3", "A", ".google.izzle", "/",
- Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
+ cm.get(), http_www_google_.url(), "setCookieWithDetails3", "A",
+ http_www_google_.Format(".%D"), "/", Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT));
// Now we check
CookieList cookie_list(GetAllCookies(cm.get()));
EXPECT_EQ(9u, cookie_list.size());
- typedef std::map<int64, CanonicalCookie> TimeCookieMap;
+ typedef std::map<int64_t, CanonicalCookie> TimeCookieMap;
TimeCookieMap check_map;
for (CookieList::const_iterator it = cookie_list.begin();
it != cookie_list.end(); it++) {
- const int64 creation_date = it->CreationDate().ToInternalValue();
+ const int64_t creation_date = it->CreationDate().ToInternalValue();
TimeCookieMap::const_iterator existing_cookie_it(
check_map.find(creation_date));
EXPECT_TRUE(existing_cookie_it == check_map.end())
@@ -2038,7 +2170,7 @@ TEST_F(CookieMonsterTest, MAYBE_GarbageCollectionTriggers) {
for (int ci = 0; ci < static_cast<int>(arraysize(test_cases)); ++ci) {
const TestCase* test_case = &test_cases[ci];
scoped_refptr<CookieMonster> cm(CreateMonsterFromStoreForGC(
- test_case->num_cookies, test_case->num_old_cookies,
+ test_case->num_cookies, test_case->num_old_cookies, 0, 0,
CookieMonster::kSafeFromGlobalPurgeDays * 2));
EXPECT_EQ(test_case->expected_initial_cookies,
GetAllCookies(cm.get()).size())
@@ -2059,7 +2191,7 @@ TEST_F(CookieMonsterTest, KeepExpiredCookies) {
// Set a persistent cookie.
ASSERT_TRUE(SetCookieWithOptions(
- cm.get(), url_google_,
+ cm.get(), http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT",
options));
@@ -2069,7 +2201,7 @@ TEST_F(CookieMonsterTest, KeepExpiredCookies) {
// Use a past expiry date to delete the cookie.
ASSERT_TRUE(SetCookieWithOptions(
- cm.get(), url_google_,
+ cm.get(), http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
options));
@@ -2194,19 +2326,21 @@ TEST_F(CookieMonsterTest, SetAllCookies) {
scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
cm->SetPersistSessionCookies(true);
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "U=V; path=/"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "W=X; path=/foo"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "Y=Z; path=/"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "U=V; path=/"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "W=X; path=/foo"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "Y=Z; path=/"));
CookieList list;
- list.push_back(CanonicalCookie(url_google_, "A", "B", url_google_.host(), "/",
+ list.push_back(CanonicalCookie(http_www_google_.url(), "A", "B",
+ http_www_google_.url().host(), "/",
base::Time::Now(), base::Time(), base::Time(),
false, false, false, COOKIE_PRIORITY_DEFAULT));
- list.push_back(CanonicalCookie(url_google_, "W", "X", url_google_.host(),
- "/bar", base::Time::Now(), base::Time(),
- base::Time(), false, false, false,
- COOKIE_PRIORITY_DEFAULT));
- list.push_back(CanonicalCookie(url_google_, "Y", "Z", url_google_.host(), "/",
+ list.push_back(CanonicalCookie(http_www_google_.url(), "W", "X",
+ http_www_google_.url().host(), "/bar",
+ base::Time::Now(), base::Time(), base::Time(),
+ false, false, false, COOKIE_PRIORITY_DEFAULT));
+ list.push_back(CanonicalCookie(http_www_google_.url(), "Y", "Z",
+ http_www_google_.url().host(), "/",
base::Time::Now(), base::Time(), base::Time(),
false, false, false, COOKIE_PRIORITY_DEFAULT));
@@ -2240,39 +2374,49 @@ TEST_F(CookieMonsterTest, ComputeCookieDiff) {
base::Time now = base::Time::Now();
base::Time creation_time = now - base::TimeDelta::FromSeconds(1);
- CanonicalCookie cookie1(url_google_, "A", "B", url_google_.host(), "/",
- creation_time, base::Time(), base::Time(), false,
- false, false, COOKIE_PRIORITY_DEFAULT);
- CanonicalCookie cookie2(url_google_, "C", "D", url_google_.host(), "/",
- creation_time, base::Time(), base::Time(), false,
- false, false, COOKIE_PRIORITY_DEFAULT);
- CanonicalCookie cookie3(url_google_, "E", "F", url_google_.host(), "/",
- creation_time, base::Time(), base::Time(), false,
- false, false, COOKIE_PRIORITY_DEFAULT);
- CanonicalCookie cookie4(url_google_, "G", "H", url_google_.host(), "/",
- creation_time, base::Time(), base::Time(), false,
- false, false, COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie1(http_www_google_.url(), "A", "B",
+ http_www_google_.url().host(), "/", creation_time,
+ base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie2(http_www_google_.url(), "C", "D",
+ http_www_google_.url().host(), "/", creation_time,
+ base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie3(http_www_google_.url(), "E", "F",
+ http_www_google_.url().host(), "/", creation_time,
+ base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie4(http_www_google_.url(), "G", "H",
+ http_www_google_.url().host(), "/", creation_time,
+ base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
CanonicalCookie cookie4_with_new_value(
- url_google_, "G", "iamnew", url_google_.host(), "/", creation_time,
- base::Time(), base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);
- CanonicalCookie cookie5(url_google_, "I", "J", url_google_.host(), "/",
- creation_time, base::Time(), base::Time(), false,
- false, false, COOKIE_PRIORITY_DEFAULT);
+ http_www_google_.url(), "G", "iamnew", http_www_google_.url().host(), "/",
+ creation_time, base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie5(http_www_google_.url(), "I", "J",
+ http_www_google_.url().host(), "/", creation_time,
+ base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
CanonicalCookie cookie5_with_new_creation_time(
- url_google_, "I", "J", url_google_.host(), "/", now, base::Time(),
- base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);
- CanonicalCookie cookie6(url_google_, "K", "L", url_google_.host(), "/foo",
- creation_time, base::Time(), base::Time(), false,
- false, false, COOKIE_PRIORITY_DEFAULT);
- CanonicalCookie cookie6_with_new_path(
- url_google_, "K", "L", url_google_.host(), "/bar", creation_time,
+ http_www_google_.url(), "I", "J", http_www_google_.url().host(), "/", now,
base::Time(), base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);
- CanonicalCookie cookie7(url_google_, "M", "N", url_google_.host(), "/foo",
- creation_time, base::Time(), base::Time(), false,
- false, false, COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie6(http_www_google_.url(), "K", "L",
+ http_www_google_.url().host(), "/foo", creation_time,
+ base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie6_with_new_path(
+ http_www_google_.url(), "K", "L", http_www_google_.url().host(), "/bar",
+ creation_time, base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie7(http_www_google_.url(), "M", "N",
+ http_www_google_.url().host(), "/foo", creation_time,
+ base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
CanonicalCookie cookie7_with_new_path(
- url_google_, "M", "N", url_google_.host(), "/bar", creation_time,
- base::Time(), base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);
+ http_www_google_.url(), "M", "N", http_www_google_.url().host(), "/bar",
+ creation_time, base::Time(), base::Time(), false, false, false,
+ COOKIE_PRIORITY_DEFAULT);
CookieList old_cookies;
old_cookies.push_back(cookie1);
@@ -2345,7 +2489,7 @@ TEST_F(CookieMonsterTest, DeleteAll) {
scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
cm->SetPersistSessionCookies(true);
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "X=Y; path=/"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "X=Y; path=/"));
ASSERT_EQ(0, store->flush_count());
EXPECT_EQ(1, DeleteAll(cm.get()));
@@ -2373,7 +2517,7 @@ TEST_F(CookieMonsterTest, HistogramCheck) {
EXPECT_EQ(samples1->TotalCount() + 1, samples2->TotalCount());
// kValidCookieLine creates a session cookie.
- ASSERT_TRUE(SetCookie(cm.get(), url_google_, kValidCookieLine));
+ ASSERT_TRUE(SetCookie(cm.get(), http_www_google_.url(), kValidCookieLine));
scoped_ptr<base::HistogramSamples> samples3(
expired_histogram->SnapshotSamples());
@@ -2426,7 +2570,8 @@ class MultiThreadedCookieMonsterTest : public CookieMonsterTest {
CookiePriority priority = COOKIE_PRIORITY_DEFAULT;
cm->SetCookieWithDetailsAsync(
url, name, value, domain, path, expiration_time, secure, http_only,
- first_party_only, priority,
+ first_party_only, false /* enforce prefixes */,
+ false /* enforces strict secure cookies */, priority,
base::Bind(&ResultSavingCookieCallback<bool>::Run,
base::Unretained(callback)));
}
@@ -2484,11 +2629,11 @@ class MultiThreadedCookieMonsterTest : public CookieMonsterTest {
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookies) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
CookieList cookies = GetAllCookies(cm.get());
CookieList::const_iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it == cookies.end());
GetCookieListCallback callback(&other_thread_);
@@ -2499,66 +2644,66 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookies) {
EXPECT_TRUE(callback.did_run());
it = callback.cookies().begin();
ASSERT_TRUE(it != callback.cookies().end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it == callback.cookies().end());
}
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookiesForURL) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
- CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_);
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
+ CookieList cookies = GetAllCookiesForURL(cm.get(), http_www_google_.url());
CookieList::const_iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it == cookies.end());
GetCookieListCallback callback(&other_thread_);
base::Closure task =
base::Bind(&MultiThreadedCookieMonsterTest::GetAllCookiesForURLTask,
- base::Unretained(this), cm, url_google_, &callback);
+ base::Unretained(this), cm, http_www_google_.url(), &callback);
RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
it = callback.cookies().begin();
ASSERT_TRUE(it != callback.cookies().end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it == callback.cookies().end());
}
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookiesForURLWithOpt) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
CookieOptions options;
CookieList cookies =
- GetAllCookiesForURLWithOptions(cm.get(), url_google_, options);
+ GetAllCookiesForURLWithOptions(cm.get(), http_www_google_.url(), options);
CookieList::const_iterator it = cookies.begin();
ASSERT_TRUE(it != cookies.end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it == cookies.end());
GetCookieListCallback callback(&other_thread_);
base::Closure task = base::Bind(
&MultiThreadedCookieMonsterTest::GetAllCookiesForURLWithOptionsTask,
- base::Unretained(this), cm, url_google_, options, &callback);
+ base::Unretained(this), cm, http_www_google_.url(), options, &callback);
RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
it = callback.cookies().begin();
ASSERT_TRUE(it != callback.cookies().end());
- EXPECT_EQ("www.google.izzle", it->Domain());
+ EXPECT_EQ(http_www_google_.host(), it->Domain());
EXPECT_EQ("A", it->Name());
ASSERT_TRUE(++it == callback.cookies().end());
}
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckSetCookieWithDetails) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
- EXPECT_TRUE(SetCookieWithDetails(cm.get(), url_google_foo_, "A", "B",
+ EXPECT_TRUE(SetCookieWithDetails(cm.get(), www_google_foo_.url(), "A", "B",
std::string(), "/foo", base::Time(), false,
false, false, COOKIE_PRIORITY_DEFAULT));
ResultSavingCookieCallback<bool> callback(&other_thread_);
base::Closure task =
base::Bind(&MultiThreadedCookieMonsterTest::SetCookieWithDetailsTask,
- base::Unretained(this), cm, url_google_foo_, &callback);
+ base::Unretained(this), cm, www_google_foo_.url(), &callback);
RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
EXPECT_TRUE(callback.result());
@@ -2568,10 +2713,12 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteAllCreatedBetween) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
CookieOptions options;
Time now = Time::Now();
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
EXPECT_EQ(1, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(99),
Time()));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
ResultSavingCookieCallback<int> callback(&other_thread_);
base::Closure task =
base::Bind(&MultiThreadedCookieMonsterTest::DeleteAllCreatedBetweenTask,
@@ -2585,13 +2732,15 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteAllCreatedBetween) {
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteAllForHost) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
CookieOptions options;
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
- EXPECT_EQ(1, DeleteAllForHost(cm.get(), url_google_));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
+ EXPECT_EQ(1, DeleteAllForHost(cm.get(), http_www_google_.url()));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
ResultSavingCookieCallback<int> callback(&other_thread_);
base::Closure task =
base::Bind(&MultiThreadedCookieMonsterTest::DeleteAllForHostTask,
- base::Unretained(this), cm, url_google_, &callback);
+ base::Unretained(this), cm, http_www_google_.url(), &callback);
RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
EXPECT_EQ(1, callback.result());
@@ -2610,29 +2759,35 @@ TEST_F(MultiThreadedCookieMonsterTest,
Time ago3 = now - TimeDelta::FromDays(99);
// These 3 cookies match the first deletion.
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "C=D", options));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "Y=Z", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "C=D", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "Y=Z", options));
// This cookie does not match host.
EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_not_google, "E=F", options));
// This cookie does not match time range: [ago3, inf], for first deletion, but
// matches for the second deletion.
- EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "G=H", ago2));
+ EXPECT_TRUE(
+ cm->SetCookieWithCreationTime(http_www_google_.url(), "G=H", ago2));
// 1. First set of deletions.
- EXPECT_EQ(
- 3, // Deletes A=B, C=D, Y=Z
- DeleteAllCreatedBetweenForHost(cm.get(), ago3, Time::Max(), url_google_));
+ EXPECT_EQ(3, // Deletes A=B, C=D, Y=Z
+ DeleteAllCreatedBetweenForHost(cm.get(), ago3, Time::Max(),
+ http_www_google_.url()));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
ResultSavingCookieCallback<int> callback(&other_thread_);
// 2. Second set of deletions.
base::Closure task = base::Bind(
&MultiThreadedCookieMonsterTest::DeleteAllCreatedBetweenForHostTask,
- base::Unretained(this), cm, ago1, Time(), url_google_, &callback);
+ base::Unretained(this), cm, ago1, Time(), http_www_google_.url(),
+ &callback);
RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
EXPECT_EQ(2, callback.result()); // Deletes A=B, G=H.
@@ -2641,12 +2796,14 @@ TEST_F(MultiThreadedCookieMonsterTest,
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteCanonicalCookie) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
CookieOptions options;
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
CookieList cookies = GetAllCookies(cm.get());
CookieList::iterator it = cookies.begin();
EXPECT_TRUE(DeleteCanonicalCookie(cm.get(), *it));
- EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
+ EXPECT_TRUE(
+ SetCookieWithOptions(cm.get(), http_www_google_.url(), "A=B", options));
ResultSavingCookieCallback<bool> callback(&other_thread_);
cookies = GetAllCookies(cm.get());
it = cookies.begin();
@@ -2665,8 +2822,8 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteCanonicalCookie) {
TEST_F(MultiThreadedCookieMonsterTest, GetAllCookiesForURLEffectiveDomain) {
std::vector<CanonicalCookie*> cookies;
// This cookie will be freed by the CookieMonster.
- cookies.push_back(CanonicalCookie::Create(url_google_, kValidCookieLine,
- Time::Now(), CookieOptions()));
+ cookies.push_back(CanonicalCookie::Create(
+ http_www_google_.url(), kValidCookieLine, Time::Now(), CookieOptions()));
CanonicalCookie cookie = *cookies[0];
scoped_refptr<NewMockPersistentCookieStore> store(
new NewMockPersistentCookieStore);
@@ -2674,8 +2831,8 @@ TEST_F(MultiThreadedCookieMonsterTest, GetAllCookiesForURLEffectiveDomain) {
CookieMonster::PersistentCookieStore::LoadedCallback loaded_callback;
::testing::StrictMock<::testing::MockFunction<void(int)>> checkpoint;
- const std::string key =
- cookie_util::GetEffectiveDomain(url_google_.scheme(), url_google_.host());
+ const std::string key = cookie_util::GetEffectiveDomain(
+ http_www_google_.url().scheme(), http_www_google_.url().host());
::testing::InSequence s;
EXPECT_CALL(checkpoint, Call(0));
@@ -2690,7 +2847,7 @@ TEST_F(MultiThreadedCookieMonsterTest, GetAllCookiesForURLEffectiveDomain) {
GetCookieListCallback callback;
checkpoint.Call(0);
- GetAllCookiesForURLTask(cm.get(), url_google_, &callback);
+ GetAllCookiesForURLTask(cm.get(), http_www_google_.url(), &callback);
checkpoint.Call(1);
ASSERT_FALSE(callback.did_run());
// Pass the cookies to the CookieMonster.
@@ -2703,10 +2860,8 @@ TEST_F(MultiThreadedCookieMonsterTest, GetAllCookiesForURLEffectiveDomain) {
// All urls in |urls| should share the same cookie domain.
const GURL kUrls[] = {
- url_google_,
- url_google_secure_,
- GURL(kUrlGoogleWebSocket),
- GURL(kUrlGoogleWebSocketSecure),
+ http_www_google_.url(), https_www_google_.url(), ws_www_google_.url(),
+ wss_www_google_.url(),
};
for (const GURL& url : kUrls) {
// Call the function with |url| and verify it is done synchronously without
@@ -2723,7 +2878,7 @@ TEST_F(CookieMonsterTest, InvalidExpiryTime) {
std::string cookie_line =
std::string(kValidCookieLine) + "; expires=Blarg arg arg";
scoped_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
- url_google_, cookie_line, Time::Now(), CookieOptions()));
+ http_www_google_.url(), cookie_line, Time::Now(), CookieOptions()));
ASSERT_FALSE(cookie->IsPersistent());
}
@@ -2735,8 +2890,8 @@ TEST_F(CookieMonsterTest, PersistSessionCookies) {
cm->SetPersistSessionCookies(true);
// All cookies set with SetCookie are session cookies.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
- EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B"));
+ EXPECT_EQ("A=B", GetCookies(cm.get(), http_www_google_.url()));
// The cookie was written to the backing store.
EXPECT_EQ(1u, store->commands().size());
@@ -2745,8 +2900,8 @@ TEST_F(CookieMonsterTest, PersistSessionCookies) {
EXPECT_EQ("B", store->commands()[0].cookie.Value());
// Modify the cookie.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=C"));
- EXPECT_EQ("A=C", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=C"));
+ EXPECT_EQ("A=C", GetCookies(cm.get(), http_www_google_.url()));
EXPECT_EQ(3u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
EXPECT_EQ("A", store->commands()[1].cookie.Name());
@@ -2756,8 +2911,8 @@ TEST_F(CookieMonsterTest, PersistSessionCookies) {
EXPECT_EQ("C", store->commands()[2].cookie.Value());
// Delete the cookie.
- DeleteCookie(cm.get(), url_google_, "A");
- EXPECT_EQ("", GetCookies(cm.get(), url_google_));
+ DeleteCookie(cm.get(), http_www_google_.url(), "A");
+ EXPECT_EQ("", GetCookies(cm.get(), http_www_google_.url()));
EXPECT_EQ(4u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
EXPECT_EQ("A", store->commands()[3].cookie.Name());
@@ -2770,35 +2925,37 @@ TEST_F(CookieMonsterTest, PersisentCookieStorageTest) {
scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
// Add a cookie.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(),
"A=B; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", GetCookies(cm.get(), url_google_));
+ this->MatchCookieLines("A=B", GetCookies(cm.get(), http_www_google_.url()));
ASSERT_EQ(1u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
// Remove it.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B; max-age=0"));
- this->MatchCookieLines(std::string(), GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B; max-age=0"));
+ this->MatchCookieLines(std::string(),
+ GetCookies(cm.get(), http_www_google_.url()));
ASSERT_EQ(2u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
// Add a cookie.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(),
"A=B; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", GetCookies(cm.get(), url_google_));
+ this->MatchCookieLines("A=B", GetCookies(cm.get(), http_www_google_.url()));
ASSERT_EQ(3u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
// Overwrite it.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(),
"A=Foo; expires=Mon, 18-Apr-22 22:50:14 GMT"));
- this->MatchCookieLines("A=Foo", GetCookies(cm.get(), url_google_));
+ this->MatchCookieLines("A=Foo", GetCookies(cm.get(), http_www_google_.url()));
ASSERT_EQ(5u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[4].type);
// Create some non-persistent cookies and check that they don't go to the
// persistent storage.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=Bar"));
- this->MatchCookieLines("A=Foo; B=Bar", GetCookies(cm.get(), url_google_));
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "B=Bar"));
+ this->MatchCookieLines("A=Foo; B=Bar",
+ GetCookies(cm.get(), http_www_google_.url()));
EXPECT_EQ(5u, store->commands().size());
}
@@ -2849,30 +3006,33 @@ TEST_F(CookieMonsterTest, CookieSourceHistogram) {
histograms.ExpectTotalCount(cookie_source_histogram, 0);
- // Set a Secure cookie on a cryptographic scheme.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_secure_, "A=B; path=/; Secure"));
+ // Set a secure cookie on a cryptographic scheme.
+ EXPECT_TRUE(
+ SetCookie(cm.get(), https_www_google_.url(), "A=B; path=/; Secure"));
histograms.ExpectTotalCount(cookie_source_histogram, 1);
histograms.ExpectBucketCount(
cookie_source_histogram,
CookieMonster::COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME, 1);
- // Set a non-Secure cookie on a cryptographic scheme.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_secure_, "C=D; path=/;"));
+ // Set a non-secure cookie on a cryptographic scheme.
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "C=D; path=/;"));
histograms.ExpectTotalCount(cookie_source_histogram, 2);
histograms.ExpectBucketCount(
cookie_source_histogram,
CookieMonster::COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME, 1);
- // Set a Secure cookie on a non-cryptographic scheme.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "D=E; path=/; Secure"));
+ // Set a secure cookie on a non-cryptographic scheme.
+ EXPECT_TRUE(
+ SetCookie(cm.get(), http_www_google_.url(), "D=E; path=/; Secure"));
histograms.ExpectTotalCount(cookie_source_histogram, 3);
histograms.ExpectBucketCount(
cookie_source_histogram,
CookieMonster::COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 1);
- // Overwrite a Secure cookie (set by a cryptographic scheme) on a
+ // Overwrite a secure cookie (set by a cryptographic scheme) on a
// non-cryptographic scheme.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B; path=/; Secure"));
+ EXPECT_TRUE(
+ SetCookie(cm.get(), http_www_google_.url(), "A=B; path=/; Secure"));
histograms.ExpectTotalCount(cookie_source_histogram, 4);
histograms.ExpectBucketCount(
cookie_source_histogram,
@@ -2881,26 +3041,387 @@ TEST_F(CookieMonsterTest, CookieSourceHistogram) {
cookie_source_histogram,
CookieMonster::COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 2);
- // Test that clearing a Secure cookie on a http:// URL does not get
+ // Test that clearing a secure cookie on a http:// URL does not get
// counted.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_secure_, "F=G; path=/; Secure"));
+ EXPECT_TRUE(
+ SetCookie(cm.get(), https_www_google_.url(), "F=G; path=/; Secure"));
histograms.ExpectTotalCount(cookie_source_histogram, 5);
- std::string cookies1 = GetCookies(cm.get(), url_google_secure_);
+ std::string cookies1 = GetCookies(cm.get(), https_www_google_.url());
EXPECT_NE(std::string::npos, cookies1.find("F=G"));
- EXPECT_TRUE(SetCookie(cm.get(), url_google_,
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(),
"F=G; path=/; Expires=Thu, 01-Jan-1970 00:00:01 GMT"));
- std::string cookies2 = GetCookies(cm.get(), url_google_secure_);
+ std::string cookies2 = GetCookies(cm.get(), https_www_google_.url());
EXPECT_EQ(std::string::npos, cookies2.find("F=G"));
histograms.ExpectTotalCount(cookie_source_histogram, 5);
- // Set a non-Secure cookie on a non-cryptographic scheme.
- EXPECT_TRUE(SetCookie(cm.get(), url_google_, "H=I; path=/"));
+ // Set a non-secure cookie on a non-cryptographic scheme.
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "H=I; path=/"));
histograms.ExpectTotalCount(cookie_source_histogram, 6);
histograms.ExpectBucketCount(
cookie_source_histogram,
CookieMonster::COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 1);
}
+// Test that cookie delete equivalent histograms are recorded correctly when
+// strict secure cookies are not enabled.
+TEST_F(CookieMonsterTest, CookieDeleteEquivalentHistogramTest) {
+ base::HistogramTester histograms;
+ const std::string cookie_source_histogram = "Cookie.CookieDeleteEquivalent";
+
+ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
+ scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+
+ // Set a secure cookie from a secure origin
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "A=B; Secure"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 1);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 1);
+
+ // Set a new cookie with a different name from a variety of origins (including
+ // the same one).
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "B=A;"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 2);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 2);
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "C=A;"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 3);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 3);
+
+ // Set a non-secure cookie from an insecure origin that matches the name of an
+ // already existing cookie and additionally is equivalent to the existing
+ // cookie.
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "A=B;"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 5);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 4);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_FOUND,
+ 1);
+
+ // Set a non-secure cookie from an insecure origin that matches the name of an
+ // already existing cookie but is not equivalent.
+ EXPECT_TRUE(
+ SetCookie(cm.get(), http_www_google_.url(), "A=C; path=/some/path"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 6);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 5);
+
+ // Set a secure cookie from a secure origin that matches the name of an
+ // already existing cookies and is equivalent.
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "A=D; secure"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 8);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 6);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_FOUND,
+ 2);
+
+ // Set a secure cookie from a secure origin that matches the name of an
+ // already existing cookie and is not equivalent.
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(),
+ "A=E; secure; path=/some/other/path"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 9);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 7);
+}
+
+TEST_F(CookieMonsterStrictSecureTest, SetSecureCookies) {
+ scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+ GURL http_url("http://www.google.com");
+ GURL http_superdomain_url("http://google.com");
+ GURL https_url("https://www.google.com");
+
+ // A non-secure cookie can be created from either a URL with a secure or
+ // insecure scheme.
+ EXPECT_TRUE(SetCookie(cm.get(), http_url, "A=C;"));
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B;"));
+
+ // A secure cookie cannot be created from a URL with an insecure scheme.
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=B; Secure"));
+
+ // A secure cookie can be created from a URL with a secure scheme.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure"));
+
+ // If a non-secure cookie is created from a URL with an insecure scheme, and a
+ // secure cookie with the same name already exists, do not update the cookie.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C;"));
+
+ // If a non-secure cookie is created from a URL with an secure scheme, and a
+ // secure cookie with the same name already exists, update the cookie.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure"));
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=C;"));
+
+ // If a non-secure cookie is created from a URL with an insecure scheme, and
+ // a secure cookie with the same name already exists, no matter what the path
+ // is, do not update the cookie.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C; path=/"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C; path=/my/path"));
+
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure; path=/my/path"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C; path=/"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C; path=/my/path"));
+
+ // If a non-secure cookie is created from a URL with an insecure scheme, and
+ // a secure cookie with the same name already exists, if the domain strings
+ // domain-match, do not update the cookie.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C; domain=google.com"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=C; domain=www.google.com"));
+
+ // Since A=B was set above with no domain string, set a different cookie here
+ // so the insecure examples aren't trying to overwrite the one above.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "B=C; Secure; domain=google.com"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "B=D; domain=google.com"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "B=D"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_superdomain_url, "B=D"));
+
+ // Verify that if an httponly version of the cookie exists, adding a Secure
+ // version of the cookie still does not overwrite it.
+ CookieOptions include_httponly;
+ include_httponly.set_include_httponly();
+ include_httponly.set_enforce_strict_secure();
+ EXPECT_TRUE(SetCookieWithOptions(cm.get(), https_url, "C=D; httponly",
+ include_httponly));
+ // Note that the lack of an explicit options object below uses the default,
+ // which in this case includes "exclude_httponly = true".
+ EXPECT_FALSE(SetCookie(cm.get(), https_url, "C=E; Secure"));
+}
+
+// Tests for behavior if strict secure cookies is enabled.
+TEST_F(CookieMonsterStrictSecureTest, EvictSecureCookies) {
+ // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
+ DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
+ DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
+ CookieMonster::kDomainPurgeCookies);
+ DCHECK_EQ(3300U, CookieMonster::kMaxCookies);
+ DCHECK_EQ(30, CookieMonster::kSafeFromGlobalPurgeDays);
+
+ // If secure cookies for one domain hit the per domain limit (180), a
+ // non-secure cookie will not evict them (and, in fact, the non-secure cookie
+ // will be removed right after creation).
+ const CookiesEntry test1[] = {{180U, true}, {1U, false}};
+ TestSecureCookieEviction(test1, arraysize(test1), 180U, 0U, nullptr);
+
+ // If non-secure cookies for one domain hit the per domain limit (180), the
+ // creation of secure cookies will evict all of the non-secure cookies, and
+ // the secure cookies will still be created.
+ const CookiesEntry test2[] = {{180U, false}, {20U, true}};
+ TestSecureCookieEviction(test2, arraysize(test2), 20U, 0U, nullptr);
+
+ // If secure cookies for one domain go past the per domain limit (180), they
+ // will be evicted as normal by the per domain purge amount (30) down to a
+ // lower amount (150), and then will continue to create the remaining cookies
+ // (19 more to 169).
+ const CookiesEntry test3[] = {{200U, true}};
+ TestSecureCookieEviction(test3, arraysize(test3), 169U, 0U, nullptr);
+
+ // If a non-secure cookie is created, and a number of secure cookies exceeds
+ // the per domain limit (18), the total cookies will be evicted down to a
+ // lower amount (150), enforcing the eviction of the non-secure cookie, and
+ // the remaining secure cookies will be created (another 18 to 168).
+ const CookiesEntry test4[] = {{1U, false}, {199U, true}};
+ TestSecureCookieEviction(test4, arraysize(test4), 168U, 0U, nullptr);
+
+ // If an even number of non-secure and secure cookies are created below the
+ // per-domain limit (180), all will be created and none evicted.
+ const CookiesEntry test5[] = {{75U, false}, {75U, true}};
+ TestSecureCookieEviction(test5, arraysize(test5), 75U, 75U, nullptr);
+
+ // If the same number of secure and non-secure cookies are created (50 each)
+ // below the per domain limit (180), and then another set of secure cookies
+ // are created to bring the total above the per-domain limit, all of the
+ // non-secure cookies will be evicted but none of the secure ones will be
+ // evicted.
+ const CookiesEntry test6[] = {{50U, true}, {50U, false}, {81U, true}};
+ TestSecureCookieEviction(test6, arraysize(test6), 131U, 0U, nullptr);
+
+ // If the same number of non-secure and secure cookies are created (50 each)
+ // below the per domain limit (180), and then another set of non-secure
+ // cookies are created to bring the total above the per-domain limit, all of
+ // the non-secure cookies will be evicted but none of the secure ones will be
+ // evicted.
+ const CookiesEntry test7[] = {{50U, false}, {50U, true}, {81U, false}};
+ TestSecureCookieEviction(test7, arraysize(test7), 50U, 0U, nullptr);
+
+ // If the same number of non-secure and secure cookies are created (50 each)
+ // below the per domain limit (180), and then another set of non-secure
+ // cookies are created to bring the total above the per-domain limit, all of
+ // the non-secure cookies will be evicted but none of the secure ones will be
+ // evicted, and then the remaining non-secure cookies will be created (9).
+ const CookiesEntry test8[] = {{50U, false}, {50U, true}, {90U, false}};
+ TestSecureCookieEviction(test8, arraysize(test8), 50U, 9U, nullptr);
+
+ // If a number of non-secure cookies are created on other hosts (20) and are
+ // past the global 'safe' date, and then the number of non-secure cookies for
+ // a single domain are brought to the per-domain limit (180), followed by
+ // another set of secure cookies on that same domain (20), all of the
+ // non-secure cookies for that domain should be evicted, but the non-secure
+ // cookies for other domains should remain, as should the secure cookies for
+ // that domain.
+ const CookiesEntry test9[] = {{180U, false}, {20U, true}};
+ const AltHosts test9_alt_hosts(0, 20);
+ TestSecureCookieEviction(test9, arraysize(test9), 20U, 20U, &test9_alt_hosts);
+
+ // If a number of secure cookies are created on other hosts and hit the global
+ // cookie limit (3300) and are past the global 'safe' date, and then a single
+ // non-secure cookie is created now, the secure cookies are removed so that
+ // the global total number of cookies is at the global purge goal (3000), but
+ // the non-secure cookie is not evicted since it is too young.
+ const CookiesEntry test10[] = {{1U, false}};
+ const AltHosts test10_alt_hosts(3300, 0);
+ TestSecureCookieEviction(test10, arraysize(test10), 2999U, 1U,
+ &test10_alt_hosts);
+
+ // If a number of non-secure cookies are created on other hosts and hit the
+ // global cookie limit (3300) and are past the global 'safe' date, and then a
+ // single non-secure cookie is created now, the non-secure cookies are removed
+ // so that the global total number of cookies is at the global purge goal
+ // (3000).
+ const CookiesEntry test11[] = {{1U, false}};
+ const AltHosts test11_alt_hosts(0, 3300);
+ TestSecureCookieEviction(test11, arraysize(test11), 0U, 3000U,
+ &test11_alt_hosts);
+
+ // If a number of non-secure cookies are created on other hosts and hit the
+ // global cookie limit (3300) and are past the global 'safe' date, and then a
+ // single ecure cookie is created now, the non-secure cookies are removed so
+ // that the global total number of cookies is at the global purge goal (3000),
+ // but the secure cookie is not evicted.
+ const CookiesEntry test12[] = {{1U, true}};
+ const AltHosts test12_alt_hosts(0, 3300);
+ TestSecureCookieEviction(test12, arraysize(test12), 1U, 2999U,
+ &test12_alt_hosts);
+
+ // If a total number of secure and non-secure cookies are created on other
+ // hosts and hit the global cookie limit (3300) and are past the global 'safe'
+ // date, and then a single non-secure cookie is created now, the global
+ // non-secure cookies are removed so that the global total number of cookies
+ // is at the global purge goal (3000), but the secure cookies are not evicted.
+ const CookiesEntry test13[] = {{1U, false}};
+ const AltHosts test13_alt_hosts(1500, 1800);
+ TestSecureCookieEviction(test13, arraysize(test13), 1500U, 1500,
+ &test13_alt_hosts);
+
+ // If a total number of secure and non-secure cookies are created on other
+ // hosts and hit the global cookie limit (3300) and are past the global 'safe'
+ // date, and then a single secure cookie is created now, the global non-secure
+ // cookies are removed so that the global total number of cookies is at the
+ // global purge goal (3000), but the secure cookies are not evicted.
+ const CookiesEntry test14[] = {{1U, true}};
+ const AltHosts test14_alt_hosts(1500, 1800);
+ TestSecureCookieEviction(test14, arraysize(test14), 1501U, 1499,
+ &test14_alt_hosts);
+}
+
+// Tests that strict secure cookies doesn't trip equivalent cookie checks
+// accidentally. Regression test for https://crbug.com/569943.
+TEST_F(CookieMonsterStrictSecureTest, EquivalentCookies) {
+ scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
+ GURL http_url("http://www.google.com");
+ GURL http_superdomain_url("http://google.com");
+ GURL https_url("https://www.google.com");
+
+ // Tests that non-equivalent cookies because of the path attribute can be set
+ // successfully.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure"));
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=C; path=/some/other/path"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=D; path=/some/other/path"));
+
+ // Tests that non-equivalent cookies because of the domain attribute can be
+ // set successfully.
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=B; Secure"));
+ EXPECT_TRUE(SetCookie(cm.get(), https_url, "A=C; domain=google.com"));
+ EXPECT_FALSE(SetCookie(cm.get(), http_url, "A=D; domain=google.com"));
+}
+
+// Test that cookie delete equivalent histograms are recorded correctly for
+// strict secure cookies.
+TEST_F(CookieMonsterStrictSecureTest, CookieDeleteEquivalentHistogramTest) {
+ base::HistogramTester histograms;
+ const std::string cookie_source_histogram = "Cookie.CookieDeleteEquivalent";
+
+ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
+ scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
+
+ // Set a secure cookie from a secure origin
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "A=B; Secure"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 1);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 1);
+
+ // Set a new cookie with a different name from a variety of origins (including
+ // the same one).
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "B=A;"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 2);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 2);
+ EXPECT_TRUE(SetCookie(cm.get(), http_www_google_.url(), "C=A;"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 3);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 3);
+
+ // Set a non-secure cookie from an insecure origin that matches the name of an
+ // already existing cookie and additionally is equivalent to the existing
+ // cookie.
+ EXPECT_FALSE(SetCookie(cm.get(), http_www_google_.url(), "A=B;"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 6);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 4);
+ histograms.ExpectBucketCount(
+ cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_SKIPPING_SECURE, 1);
+ histograms.ExpectBucketCount(
+ cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_WOULD_HAVE_DELETED, 1);
+
+ // Set a non-secure cookie from an insecure origin that matches the name of an
+ // already existing cookie but is not equivalent.
+ EXPECT_FALSE(
+ SetCookie(cm.get(), http_www_google_.url(), "A=B; path=/some/path"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 8);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 5);
+ histograms.ExpectBucketCount(
+ cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_SKIPPING_SECURE, 2);
+
+ // Set a secure cookie from a secure origin that matches the name of an
+ // already existing cookies and is equivalent.
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "A=B; secure"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 10);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 6);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_FOUND,
+ 1);
+
+ // Set a secure cookie from a secure origin that matches the name of an
+ // already existing cookie and is not equivalent.
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(),
+ "A=C; secure; path=/some/path"));
+ histograms.ExpectTotalCount(cookie_source_histogram, 11);
+ histograms.ExpectBucketCount(cookie_source_histogram,
+ CookieMonster::COOKIE_DELETE_EQUIVALENT_ATTEMPT,
+ 7);
+}
+
class CookieMonsterNotificationTest : public CookieMonsterTest {
public:
CookieMonsterNotificationTest()
diff --git a/chromium/net/cookies/cookie_options.cc b/chromium/net/cookies/cookie_options.cc
index 5cacb6bb77d..d29d51186f1 100644
--- a/chromium/net/cookies/cookie_options.cc
+++ b/chromium/net/cookies/cookie_options.cc
@@ -10,7 +10,8 @@ namespace net {
CookieOptions::CookieOptions()
: exclude_httponly_(true),
- include_first_party_only_(false),
+ include_first_party_only_cookies_(false),
+ enforce_strict_secure_(false),
server_time_() {}
} // namespace net
diff --git a/chromium/net/cookies/cookie_options.h b/chromium/net/cookies/cookie_options.h
index d3d7fd056b7..4d2a774c1bc 100644
--- a/chromium/net/cookies/cookie_options.h
+++ b/chromium/net/cookies/cookie_options.h
@@ -15,25 +15,35 @@ namespace net {
class NET_EXPORT CookieOptions {
public:
- // Default is to exclude httponly completely, and exclude first-party from
- // being read, which means:
- // - reading operations will not return httponly or first-party cookies.
- // - writing operations will not write httponly cookies (first-party will be
- // written).
+ // Creates a CookieOptions object which:
//
- // If a first-party URL is set, then first-party cookies which match that URL
- // will be returned.
+ // * Excludes HttpOnly cookies
+ // * Excludes First-Party-Only cookies
+ // * Does not enforce prefix restrictions (e.g. "$Secure-*")
+ //
+ // These settings can be altered by calling:
+ //
+ // * |set_{include,exclude}_httponly()|
+ // * |set_include_first_party_only_cookies()|
+ // * |set_enforce_prefixes()|
CookieOptions();
void set_exclude_httponly() { exclude_httponly_ = true; }
void set_include_httponly() { exclude_httponly_ = false; }
bool exclude_httponly() const { return exclude_httponly_; }
- void set_include_first_party_only() { include_first_party_only_ = true; }
- bool include_first_party_only() const { return include_first_party_only_; }
+ // Default is to exclude 'first-party-only' cookies.
+ void set_include_first_party_only_cookies() {
+ include_first_party_only_cookies_ = true;
+ }
+ bool include_first_party_only_cookies() const {
+ return include_first_party_only_cookies_;
+ }
- void set_first_party_url(const GURL& url) { first_party_url_ = url; }
- GURL first_party_url() const { return first_party_url_; }
+ // TODO(jww): Remove once we decide whether to ship modifying 'secure' cookies
+ // only from secure schemes. https://crbug.com/546820
+ void set_enforce_strict_secure() { enforce_strict_secure_ = true; }
+ bool enforce_strict_secure() const { return enforce_strict_secure_; }
// |server_time| indicates what the server sending us the Cookie thought the
// current time was when the cookie was produced. This is used to adjust for
@@ -46,8 +56,8 @@ class NET_EXPORT CookieOptions {
private:
bool exclude_httponly_;
- bool include_first_party_only_;
- GURL first_party_url_;
+ bool include_first_party_only_cookies_;
+ bool enforce_strict_secure_;
base::Time server_time_;
};
diff --git a/chromium/net/cookies/cookie_store.h b/chromium/net/cookies/cookie_store.h
index 9f5e1f191be..e2e24406365 100644
--- a/chromium/net/cookies/cookie_store.h
+++ b/chromium/net/cookies/cookie_store.h
@@ -10,7 +10,6 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/callback_list.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/net/cookies/cookie_store_test_callbacks.cc b/chromium/net/cookies/cookie_store_test_callbacks.cc
index afb05d15146..491fe0e8bf9 100644
--- a/chromium/net/cookies/cookie_store_test_callbacks.cc
+++ b/chromium/net/cookies/cookie_store_test_callbacks.cc
@@ -38,8 +38,8 @@ void CookieCallback::CallbackEpilogue() {
did_run_ = true;
EXPECT_EQ(expected_loop, base::MessageLoop::current());
- loop_to_quit_->task_runner()->PostTask(FROM_HERE,
- base::MessageLoop::QuitClosure());
+ loop_to_quit_->task_runner()->PostTask(
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
StringResultCookieCallback::StringResultCookieCallback() {}
diff --git a/chromium/net/cookies/cookie_store_test_helpers.cc b/chromium/net/cookies/cookie_store_test_helpers.cc
index 49f9d9ac83d..e75039c1484 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.cc
+++ b/chromium/net/cookies/cookie_store_test_helpers.cc
@@ -7,7 +7,27 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+
+using net::registry_controlled_domains::GetDomainAndRegistry;
+using net::registry_controlled_domains::GetRegistryLength;
+using net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES;
+using net::registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES;
+
+namespace {
+
+std::string GetRegistry(const GURL& url) {
+ size_t registry_length = GetRegistryLength(url, INCLUDE_UNKNOWN_REGISTRIES,
+ INCLUDE_PRIVATE_REGISTRIES);
+ if (registry_length == 0)
+ return std::string();
+ return std::string(url.host(), url.host().length() - registry_length,
+ registry_length);
+}
+
+} // namespace
namespace net {
@@ -143,4 +163,25 @@ DelayedCookieMonster::AddCallbackForCookie(
return scoped_ptr<CookieStore::CookieChangedSubscription>();
}
+//
+// CookieURLHelper
+//
+CookieURLHelper::CookieURLHelper(const std::string& url_string)
+ : url_(url_string),
+ registry_(GetRegistry(url_)),
+ domain_and_registry_(
+ GetDomainAndRegistry(url_, INCLUDE_PRIVATE_REGISTRIES)) {}
+
+const GURL CookieURLHelper::AppendPath(const std::string& path) const {
+ return GURL(url_.spec() + path);
+}
+
+std::string CookieURLHelper::Format(const std::string& format_string) const {
+ std::string new_string = format_string;
+ base::ReplaceSubstringsAfterOffset(&new_string, 0, "%D",
+ domain_and_registry_);
+ base::ReplaceSubstringsAfterOffset(&new_string, 0, "%R", registry_);
+ return new_string;
+}
+
} // namespace net
diff --git a/chromium/net/cookies/cookie_store_test_helpers.h b/chromium/net/cookies/cookie_store_test_helpers.h
index 760b847846c..1750c7f07bd 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.h
+++ b/chromium/net/cookies/cookie_store_test_helpers.h
@@ -70,7 +70,6 @@ class DelayedCookieMonster : public CookieStore {
const CookieChangedCallback& callback) override;
private:
-
// Be called immediately from CookieMonster.
void SetCookiesInternalCallback(bool result);
@@ -96,6 +95,26 @@ class DelayedCookieMonster : public CookieStore {
std::string cookie_line_;
};
+class CookieURLHelper {
+ public:
+ explicit CookieURLHelper(const std::string& url_string);
+
+ const std::string& domain() const { return domain_and_registry_; }
+ std::string host() const { return url_.host(); }
+ const GURL& url() const { return url_; }
+ const GURL AppendPath(const std::string& path) const;
+
+ // Return a new string with the following substitutions:
+ // 1. "%R" -> Domain registry (i.e. "com")
+ // 2. "%D" -> Domain + registry (i.e. "google.com")
+ std::string Format(const std::string& format_string) const;
+
+ private:
+ const GURL url_;
+ const std::string registry_;
+ const std::string domain_and_registry_;
+};
+
} // 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 ee135242f89..fb78d89bbbc 100644
--- a/chromium/net/cookies/cookie_store_unittest.h
+++ b/chromium/net/cookies/cookie_store_unittest.h
@@ -5,6 +5,10 @@
#ifndef NET_COOKIES_COOKIE_STORE_UNITTEST_H_
#define NET_COOKIES_COOKIE_STORE_UNITTEST_H_
+#include <set>
+#include <string>
+#include <vector>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
@@ -15,6 +19,7 @@
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_test_callbacks.h"
+#include "net/cookies/cookie_store_test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -32,15 +37,7 @@ using base::Thread;
const int kTimeout = 1000;
-const char kUrlFtp[] = "ftp://ftp.google.izzle/";
-const char kUrlGoogle[] = "http://www.google.izzle";
-const char kUrlGoogleFoo[] = "http://www.google.izzle/foo";
-const char kUrlGoogleBar[] = "http://www.google.izzle/bar";
-const char kUrlGoogleSecure[] = "https://www.google.izzle";
-const char kUrlGoogleWebSocket[] = "ws://www.google.izzle";
-const char kUrlGoogleWebSocketSecure[] = "wss://www.google.izzle";
const char kValidCookieLine[] = "A=B; path=/";
-const char kValidDomainCookieLine[] = "A=B; path=/; domain=google.izzle";
// The CookieStoreTestTraits must have the following members:
// struct CookieStoreTestTraits {
@@ -72,16 +69,22 @@ const char kValidDomainCookieLine[] = "A=B; path=/; domain=google.izzle";
// // Time to wait between two cookie insertions to ensure that cookies have
// // different creation times.
// static const int creation_time_granularity_in_ms;
+//
+// // The cookie store enforces secure flag requires a secure scheme.
+// static const bool enforce_strict_secure;
// };
template <class CookieStoreTestTraits>
class CookieStoreTest : public testing::Test {
protected:
CookieStoreTest()
- : url_google_(kUrlGoogle),
- url_google_secure_(kUrlGoogleSecure),
- url_google_foo_(kUrlGoogleFoo),
- url_google_bar_(kUrlGoogleBar) {
+ : http_www_google_("http://www.google.izzle"),
+ https_www_google_("https://www.google.izzle"),
+ ftp_google_("ftp://ftp.google.izzle/"),
+ ws_www_google_("ws://www.google.izzle"),
+ wss_www_google_("wss://www.google.izzle"),
+ www_google_foo_("http://www.google.izzle/foo"),
+ www_google_bar_("http://www.google.izzle/bar") {
// This test may be used outside of the net test suite, and thus may not
// have a message loop.
if (!base::MessageLoop::current())
@@ -155,6 +158,8 @@ class CookieStoreTest : public testing::Test {
CookieOptions options;
if (!CookieStoreTestTraits::supports_http_only)
options.set_include_httponly();
+ if (CookieStoreTestTraits::enforce_strict_secure)
+ options.set_enforce_strict_secure();
return SetCookieWithOptions(cs, url, cookie_line, options);
}
@@ -216,8 +221,8 @@ class CookieStoreTest : public testing::Test {
void RunFor(int ms) {
// Runs the test thread message loop for up to |ms| milliseconds.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&base::MessageLoop::Quit, weak_factory_->GetWeakPtr()),
+ FROM_HERE, base::Bind(&base::MessageLoop::QuitWhenIdle,
+ weak_factory_->GetWeakPtr()),
base::TimeDelta::FromMilliseconds(ms));
base::MessageLoop::current()->Run();
weak_factory_->InvalidateWeakPtrs();
@@ -252,10 +257,13 @@ class CookieStoreTest : public testing::Test {
<< "\" does not match \"" << line << "\"";
}
- GURL url_google_;
- GURL url_google_secure_;
- GURL url_google_foo_;
- GURL url_google_bar_;
+ const CookieURLHelper http_www_google_;
+ const CookieURLHelper https_www_google_;
+ const CookieURLHelper ftp_google_;
+ const CookieURLHelper ws_www_google_;
+ const CookieURLHelper wss_www_google_;
+ const CookieURLHelper www_google_foo_;
+ const CookieURLHelper www_google_bar_;
scoped_ptr<base::WeakPtrFactory<base::MessageLoop> > weak_factory_;
scoped_ptr<base::MessageLoop> message_loop_;
@@ -282,55 +290,69 @@ TYPED_TEST_P(CookieStoreTest, TypeTest) {
TYPED_TEST_P(CookieStoreTest, DomainTest) {
scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "A=B"));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
- EXPECT_TRUE(this->SetCookie(
- cs.get(), this->url_google_, "C=D; domain=.google.izzle"));
- this->MatchCookieLines("A=B; C=D",
- this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+ EXPECT_TRUE(
+ this->SetCookie(cs.get(), this->http_www_google_.url(),
+ this->http_www_google_.Format("C=D; domain=.%D")));
+ this->MatchCookieLines(
+ "A=B; C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Verify that A=B was set as a host cookie rather than a domain
// cookie -- should not be accessible from a sub sub-domain.
this->MatchCookieLines(
- "C=D", this->GetCookies(cs.get(), GURL("http://foo.www.google.izzle")));
+ "C=D",
+ this->GetCookies(
+ cs.get(), GURL(this->http_www_google_.Format("http://foo.www.%D"))));
// Test and make sure we find domain cookies on the same domain.
- EXPECT_TRUE(this->SetCookie(
- cs.get(), this->url_google_, "E=F; domain=.www.google.izzle"));
- this->MatchCookieLines("A=B; C=D; E=F",
- this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_TRUE(
+ this->SetCookie(cs.get(), this->http_www_google_.url(),
+ this->http_www_google_.Format("E=F; domain=.www.%D")));
+ this->MatchCookieLines(
+ "A=B; C=D; E=F",
+ this->GetCookies(cs.get(), this->http_www_google_.url()));
// Test setting a domain= that doesn't start w/ a dot, should
// treat it as a domain cookie, as if there was a pre-pended dot.
- EXPECT_TRUE(this->SetCookie(
- cs.get(), this->url_google_, "G=H; domain=www.google.izzle"));
- this->MatchCookieLines("A=B; C=D; E=F; G=H",
- this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_TRUE(
+ this->SetCookie(cs.get(), this->http_www_google_.url(),
+ this->http_www_google_.Format("G=H; domain=www.%D")));
+ this->MatchCookieLines(
+ "A=B; C=D; E=F; G=H",
+ this->GetCookies(cs.get(), this->http_www_google_.url()));
// Test domain enforcement, should fail on a sub-domain or something too deep.
EXPECT_FALSE(
- this->SetCookie(cs.get(), this->url_google_, "I=J; domain=.izzle"));
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), GURL("http://a.izzle")));
+ this->SetCookie(cs.get(), this->http_www_google_.url(),
+ this->http_www_google_.Format("I=J; domain=.%R")));
+ this->MatchCookieLines(
+ std::string(),
+ this->GetCookies(cs.get(),
+ GURL(this->http_www_google_.Format("http://a.%R"))));
EXPECT_FALSE(this->SetCookie(
- cs.get(), this->url_google_, "K=L; domain=.bla.www.google.izzle"));
+ cs.get(), this->http_www_google_.url(),
+ this->http_www_google_.Format("K=L; domain=.bla.www.%D")));
this->MatchCookieLines(
"C=D; E=F; G=H",
- this->GetCookies(cs.get(), GURL("http://bla.www.google.izzle")));
- this->MatchCookieLines("A=B; C=D; E=F; G=H",
- this->GetCookies(cs.get(), this->url_google_));
+ this->GetCookies(
+ cs.get(), GURL(this->http_www_google_.Format("http://bla.www.%D"))));
+ this->MatchCookieLines(
+ "A=B; C=D; E=F; G=H",
+ this->GetCookies(cs.get(), this->http_www_google_.url()));
}
// FireFox recognizes domains containing trailing periods as valid.
// IE and Safari do not. Assert the expected policy here.
TYPED_TEST_P(CookieStoreTest, DomainWithTrailingDotTest) {
scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_FALSE(this->SetCookie(
- cs.get(), this->url_google_, "a=1; domain=.www.google.com."));
- EXPECT_FALSE(this->SetCookie(
- cs.get(), this->url_google_, "b=2; domain=.www.google.com.."));
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_FALSE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+ "a=1; domain=.www.google.com."));
+ EXPECT_FALSE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+ "b=2; domain=.www.google.com.."));
+ this->MatchCookieLines(
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
}
// Test that cookies can bet set on higher level domains.
@@ -487,23 +509,38 @@ TYPED_TEST_P(CookieStoreTest, TestIpAddress) {
// Test host cookies, and setting of cookies on TLD.
TYPED_TEST_P(CookieStoreTest, TestNonDottedAndTLD) {
- {
+ if (TypeParam::supports_non_dotted_domains) {
scoped_refptr<CookieStore> cs(this->GetCookieStore());
GURL url("http://com/");
// Allow setting on "com", (but only as a host cookie).
EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1"));
EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=.com"));
- EXPECT_FALSE(this->SetCookie(cs.get(), url, "c=3; domain=com"));
+
this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
// Make sure it doesn't show up for a normal .com, it should be a host
// not a domain cookie.
this->MatchCookieLines(
std::string(),
this->GetCookies(cs.get(), GURL("http://hopefully-no-cookies.com/")));
- if (TypeParam::supports_non_dotted_domains) {
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), GURL("http://.com/")));
- }
+ this->MatchCookieLines(std::string(),
+ this->GetCookies(cs.get(), GURL("http://.com/")));
+ }
+
+ if (TypeParam::supports_non_dotted_domains) {
+ // Exact matches between the domain attribute and the host are treated as
+ // host cookies, not domain cookies.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://com/");
+ EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1; domain=com"));
+
+ this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
+ // Make sure it doesn't show up for a normal .com, it should be a host
+ // not a domain cookie.
+ this->MatchCookieLines(
+ std::string(),
+ this->GetCookies(cs.get(), GURL("http://hopefully-no-cookies.com/")));
+ this->MatchCookieLines(std::string(),
+ this->GetCookies(cs.get(), GURL("http://.com/")));
}
{
@@ -553,9 +590,25 @@ TYPED_TEST_P(CookieStoreTest, TestNonDottedAndTLD) {
GURL url("http://b");
EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1"));
EXPECT_FALSE(this->SetCookie(cs.get(), url, "b=2; domain=.b"));
- EXPECT_FALSE(this->SetCookie(cs.get(), url, "c=3; domain=b"));
this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
}
+
+ if (TypeParam::supports_non_dotted_domains) {
+ // Exact matches between the domain attribute and an intranet host are
+ // treated as host cookies, not domain cookies.
+ scoped_refptr<CookieStore> cs(this->GetCookieStore());
+ GURL url("http://b/");
+ EXPECT_TRUE(this->SetCookie(cs.get(), url, "a=1; domain=b"));
+
+ this->MatchCookieLines("a=1", this->GetCookies(cs.get(), url));
+ // Make sure it doesn't show up for an intranet subdomain, it should be a
+ // host not a domain cookie.
+ this->MatchCookieLines(
+ std::string(),
+ this->GetCookies(cs.get(), GURL("http://hopefully-no-cookies.b/")));
+ this->MatchCookieLines(std::string(),
+ this->GetCookies(cs.get(), GURL("http://.b/")));
+ }
}
// Test reading/writing cookies when the domain ends with a period,
@@ -599,18 +652,22 @@ TYPED_TEST_P(CookieStoreTest, InvalidScheme) {
return;
scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_FALSE(this->SetCookie(cs.get(), GURL(kUrlFtp), kValidCookieLine));
+ EXPECT_FALSE(
+ this->SetCookie(cs.get(), this->ftp_google_.url(), kValidCookieLine));
}
TYPED_TEST_P(CookieStoreTest, InvalidScheme_Read) {
if (!TypeParam::filters_schemes)
return;
+ const std::string kValidDomainCookieLine =
+ this->http_www_google_.Format("A=B; path=/; domain=%D");
+
scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(
- this->SetCookie(cs.get(), GURL(kUrlGoogle), kValidDomainCookieLine));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+ kValidDomainCookieLine));
this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), GURL(kUrlFtp)));
+ this->GetCookies(cs.get(), this->ftp_google_.url()));
}
TYPED_TEST_P(CookieStoreTest, PathTest) {
@@ -671,117 +728,124 @@ TYPED_TEST_P(CookieStoreTest, HttpOnlyTest) {
options.set_include_httponly();
// Create a httponly cookie.
- EXPECT_TRUE(this->SetCookieWithOptions(
- cs.get(), this->url_google_, "A=B; httponly", options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "A=B; httponly", options));
// Check httponly read protection.
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
this->MatchCookieLines(
- "A=B", this->GetCookiesWithOptions(cs.get(), this->url_google_, options));
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+ this->MatchCookieLines(
+ "A=B", this->GetCookiesWithOptions(cs.get(), this->http_www_google_.url(),
+ options));
// Check httponly overwrite protection.
- EXPECT_FALSE(this->SetCookie(cs.get(), this->url_google_, "A=C"));
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_FALSE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=C"));
this->MatchCookieLines(
- "A=B", this->GetCookiesWithOptions(cs.get(), this->url_google_, options));
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs.get(), this->url_google_, "A=C", options));
- this->MatchCookieLines("A=C", this->GetCookies(cs.get(), this->url_google_));
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
+ this->MatchCookieLines(
+ "A=B", this->GetCookiesWithOptions(cs.get(), this->http_www_google_.url(),
+ options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "A=C", options));
+ this->MatchCookieLines(
+ "A=C", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Check httponly create protection.
- EXPECT_FALSE(this->SetCookie(cs.get(), this->url_google_, "B=A; httponly"));
+ EXPECT_FALSE(
+ this->SetCookie(cs.get(), this->http_www_google_.url(), "B=A; httponly"));
this->MatchCookieLines(
- "A=C", this->GetCookiesWithOptions(cs.get(), this->url_google_, options));
- EXPECT_TRUE(this->SetCookieWithOptions(
- cs.get(), this->url_google_, "B=A; httponly", options));
+ "A=C", this->GetCookiesWithOptions(cs.get(), this->http_www_google_.url(),
+ options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "B=A; httponly", options));
+ this->MatchCookieLines("A=C; B=A",
+ this->GetCookiesWithOptions(
+ cs.get(), this->http_www_google_.url(), options));
this->MatchCookieLines(
- "A=C; B=A",
- this->GetCookiesWithOptions(cs.get(), this->url_google_, options));
- this->MatchCookieLines("A=C", this->GetCookies(cs.get(), this->url_google_));
+ "A=C", this->GetCookies(cs.get(), this->http_www_google_.url()));
}
TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) {
scoped_refptr<CookieStore> cs(this->GetCookieStore());
// Create a session cookie.
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, kValidCookieLine));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+ kValidCookieLine));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Delete it via Max-Age.
- EXPECT_TRUE(this->SetCookie(cs.get(),
- this->url_google_,
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) + "; max-age=0"));
- this->MatchCookieLineWithTimeout(cs.get(), this->url_google_, std::string());
+ this->MatchCookieLineWithTimeout(cs.get(), this->http_www_google_.url(),
+ std::string());
// Create a session cookie.
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, kValidCookieLine));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+ kValidCookieLine));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Delete it via Expires.
- EXPECT_TRUE(this->SetCookie(cs.get(),
- this->url_google_,
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) +
"; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
// Create a persistent cookie.
EXPECT_TRUE(this->SetCookie(
- cs.get(),
- this->url_google_,
+ cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Delete it via Max-Age.
- EXPECT_TRUE(this->SetCookie(cs.get(),
- this->url_google_,
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) + "; max-age=0"));
- this->MatchCookieLineWithTimeout(cs.get(), this->url_google_, std::string());
+ this->MatchCookieLineWithTimeout(cs.get(), this->http_www_google_.url(),
+ std::string());
// Create a persistent cookie.
EXPECT_TRUE(this->SetCookie(
- cs.get(),
- this->url_google_,
+ cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Delete it via Expires.
- EXPECT_TRUE(this->SetCookie(cs.get(),
- this->url_google_,
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) +
"; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
// Create a persistent cookie.
EXPECT_TRUE(this->SetCookie(
- cs.get(),
- this->url_google_,
+ cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Check that it is not deleted with significant enough clock skew.
base::Time server_time;
EXPECT_TRUE(base::Time::FromString("Sun, 17-Apr-1977 22:50:13 GMT",
&server_time));
EXPECT_TRUE(this->SetCookieWithServerTime(
- cs.get(),
- this->url_google_,
+ cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
server_time));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Create a persistent cookie.
EXPECT_TRUE(this->SetCookie(
- cs.get(),
- this->url_google_,
+ cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Delete it via Expires, with a unix epoch of 0.
- EXPECT_TRUE(this->SetCookie(cs.get(),
- this->url_google_,
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
std::string(kValidCookieLine) +
"; expires=Thu, 1-Jan-1970 00:00:00 GMT"));
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
}
TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetween) {
@@ -796,32 +860,35 @@ TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetween) {
base::TimeDelta::FromDays(30);
// Add a cookie.
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "A=B"));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
// Check that the cookie is in the store.
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Remove cookies in empty intervals.
EXPECT_EQ(0, this->DeleteCreatedBetween(cs.get(), last_month, last_minute));
EXPECT_EQ(0, this->DeleteCreatedBetween(cs.get(), next_minute, next_month));
// Check that the cookie is still there.
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Remove the cookie with an interval defined by two dates.
EXPECT_EQ(1, this->DeleteCreatedBetween(cs.get(), last_minute, next_minute));
// Check that the cookie disappeared.
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
// Add another cookie.
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "C=D"));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "C=D"));
// Check that the cookie is in the store.
- this->MatchCookieLines("C=D", this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ "C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Remove the cookie with a null ending time.
EXPECT_EQ(1, this->DeleteCreatedBetween(cs.get(), last_minute, base::Time()));
// Check that the cookie disappeared.
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
+ this->MatchCookieLines(
+ std::string(), this->GetCookies(cs.get(), this->http_www_google_.url()));
}
TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetweenForHost) {
@@ -830,9 +897,9 @@ TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetweenForHost) {
base::Time now = base::Time::Now();
// These 3 cookies match the time range and host.
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "A=B"));
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "C=D"));
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "Y=Z"));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "C=D"));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "Y=Z"));
// This cookie does not match host.
EXPECT_TRUE(this->SetCookie(cs.get(), url_not_google, "E=F"));
@@ -840,39 +907,43 @@ TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetweenForHost) {
// Delete cookies.
EXPECT_EQ(
3, // Deletes A=B, C=D, Y=Z
- this->DeleteAllCreatedBetweenForHost(
- cs.get(), now, base::Time::Max(), this->url_google_));
+ this->DeleteAllCreatedBetweenForHost(cs.get(), now, base::Time::Max(),
+ this->http_www_google_.url()));
}
TYPED_TEST_P(CookieStoreTest, TestSecure) {
scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "A=B"));
- this->MatchCookieLines("A=B",
- this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
this->MatchCookieLines(
- "A=B", this->GetCookies(cs.get(), this->url_google_secure_));
+ "A=B", this->GetCookies(cs.get(), this->https_www_google_.url()));
- EXPECT_TRUE(
- this->SetCookie(cs.get(), this->url_google_secure_, "A=B; secure"));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->https_www_google_.url(),
+ "A=B; secure"));
// The secure should overwrite the non-secure.
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
- this->MatchCookieLines("A=B",
- this->GetCookies(cs.get(), this->url_google_secure_));
+ this->MatchCookieLines(
+ std::string(),
+ this->GetCookies(cs.get(), this->http_www_google_.url()));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->https_www_google_.url()));
- EXPECT_TRUE(
- this->SetCookie(cs.get(), this->url_google_secure_, "D=E; secure"));
- this->MatchCookieLines(std::string(),
- this->GetCookies(cs.get(), this->url_google_));
- this->MatchCookieLines("A=B; D=E",
- this->GetCookies(cs.get(), this->url_google_secure_));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->https_www_google_.url(),
+ "D=E; secure"));
+ this->MatchCookieLines(
+ std::string(),
+ this->GetCookies(cs.get(), this->http_www_google_.url()));
+ this->MatchCookieLines(
+ "A=B; D=E", this->GetCookies(cs.get(), this->https_www_google_.url()));
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_secure_, "A=B"));
+ EXPECT_TRUE(
+ this->SetCookie(cs.get(), this->https_www_google_.url(), "A=B"));
// The non-secure should overwrite the secure.
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
- this->MatchCookieLines("D=E; A=B",
- this->GetCookies(cs.get(), this->url_google_secure_));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
+ this->MatchCookieLines(
+ "D=E; A=B", this->GetCookies(cs.get(), this->https_www_google_.url()));
}
static const int kLastAccessThresholdMilliseconds = 200;
@@ -993,18 +1064,18 @@ TYPED_TEST_P(CookieStoreTest, CookieOrdering) {
TYPED_TEST_P(CookieStoreTest, DeleteSessionCookie) {
scoped_refptr<CookieStore> cs(this->GetCookieStore());
// Create a session cookie and a persistent cookie.
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(),
+ std::string(kValidCookieLine)));
EXPECT_TRUE(this->SetCookie(
- cs.get(), this->url_google_, std::string(kValidCookieLine)));
- EXPECT_TRUE(this->SetCookie(cs.get(),
- this->url_google_,
- "C=D; path=/; domain=google.izzle;"
- "expires=Mon, 18-Apr-22 22:50:13 GMT"));
- this->MatchCookieLines("A=B; C=D",
- this->GetCookies(cs.get(), this->url_google_));
+ cs.get(), this->http_www_google_.url(),
+ this->http_www_google_.Format("C=D; path=/; domain=%D;"
+ "expires=Mon, 18-Apr-22 22:50:13 GMT")));
+ this->MatchCookieLines(
+ "A=B; C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
// Delete the session cookie.
this->DeleteSessionCookies(cs.get());
// Check that the session cookie has been deleted but not the persistent one.
- EXPECT_EQ("C=D", this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_EQ("C=D", this->GetCookies(cs.get(), this->http_www_google_.url()));
}
REGISTER_TYPED_TEST_CASE_P(CookieStoreTest,
@@ -1110,12 +1181,13 @@ TYPED_TEST_CASE_P(MultiThreadedCookieStoreTest);
// thread).
TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookies) {
scoped_refptr<CookieStore> cs(this->GetCookieStore());
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "A=B"));
- this->MatchCookieLines("A=B", this->GetCookies(cs.get(), this->url_google_));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
+ this->MatchCookieLines(
+ "A=B", this->GetCookies(cs.get(), this->http_www_google_.url()));
StringResultCookieCallback callback(&this->other_thread_);
- base::Closure task =
- base::Bind(&MultiThreadedCookieStoreTest<TypeParam>::GetCookiesTask,
- base::Unretained(this), cs, this->url_google_, &callback);
+ base::Closure task = base::Bind(
+ &MultiThreadedCookieStoreTest<TypeParam>::GetCookiesTask,
+ base::Unretained(this), cs, this->http_www_google_.url(), &callback);
this->RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
EXPECT_EQ("A=B", callback.result());
@@ -1126,13 +1198,15 @@ TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookiesWithOptions) {
CookieOptions options;
if (!TypeParam::supports_http_only)
options.set_include_httponly();
- EXPECT_TRUE(this->SetCookie(cs.get(), this->url_google_, "A=B"));
+ EXPECT_TRUE(this->SetCookie(cs.get(), this->http_www_google_.url(), "A=B"));
this->MatchCookieLines(
- "A=B", this->GetCookiesWithOptions(cs.get(), this->url_google_, options));
+ "A=B", this->GetCookiesWithOptions(cs.get(), this->http_www_google_.url(),
+ options));
StringResultCookieCallback callback(&this->other_thread_);
base::Closure task = base::Bind(
&MultiThreadedCookieStoreTest<TypeParam>::GetCookiesWithOptionsTask,
- base::Unretained(this), cs, this->url_google_, options, &callback);
+ base::Unretained(this), cs, this->http_www_google_.url(), options,
+ &callback);
this->RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
EXPECT_EQ("A=B", callback.result());
@@ -1143,12 +1217,13 @@ TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckSetCookieWithOptions) {
CookieOptions options;
if (!TypeParam::supports_http_only)
options.set_include_httponly();
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs.get(), this->url_google_, "A=B", options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "A=B", options));
ResultSavingCookieCallback<bool> callback(&this->other_thread_);
base::Closure task = base::Bind(
&MultiThreadedCookieStoreTest<TypeParam>::SetCookieWithOptionsTask,
- base::Unretained(this), cs, this->url_google_, "A=B", options, &callback);
+ base::Unretained(this), cs, this->http_www_google_.url(), "A=B", options,
+ &callback);
this->RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
EXPECT_TRUE(callback.result());
@@ -1159,15 +1234,15 @@ TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckDeleteCookie) {
CookieOptions options;
if (!TypeParam::supports_http_only)
options.set_include_httponly();
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs.get(), this->url_google_, "A=B", options));
- this->DeleteCookie(cs.get(), this->url_google_, "A");
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs.get(), this->url_google_, "A=B", options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "A=B", options));
+ this->DeleteCookie(cs.get(), this->http_www_google_.url(), "A");
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "A=B", options));
NoResultCookieCallback callback(&this->other_thread_);
- base::Closure task =
- base::Bind(&MultiThreadedCookieStoreTest<TypeParam>::DeleteCookieTask,
- base::Unretained(this), cs, this->url_google_, "A", &callback);
+ base::Closure task = base::Bind(
+ &MultiThreadedCookieStoreTest<TypeParam>::DeleteCookieTask,
+ base::Unretained(this), cs, this->http_www_google_.url(), "A", &callback);
this->RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
}
@@ -1177,17 +1252,15 @@ TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckDeleteSessionCookies) {
CookieOptions options;
if (!TypeParam::supports_http_only)
options.set_include_httponly();
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs.get(), this->url_google_, "A=B", options));
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs.get(),
- this->url_google_,
- "B=C; expires=Mon, 18-Apr-22 22:50:13 GMT",
- options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "A=B", options));
+ EXPECT_TRUE(this->SetCookieWithOptions(
+ cs.get(), this->http_www_google_.url(),
+ "B=C; expires=Mon, 18-Apr-22 22:50:13 GMT", options));
EXPECT_EQ(1, this->DeleteSessionCookies(cs.get()));
EXPECT_EQ(0, this->DeleteSessionCookies(cs.get()));
- EXPECT_TRUE(
- this->SetCookieWithOptions(cs.get(), this->url_google_, "A=B", options));
+ EXPECT_TRUE(this->SetCookieWithOptions(cs.get(), this->http_www_google_.url(),
+ "A=B", options));
ResultSavingCookieCallback<int> callback(&this->other_thread_);
base::Closure task = base::Bind(
&MultiThreadedCookieStoreTest<TypeParam>::DeleteSessionCookiesTask,
diff --git a/chromium/net/cookies/cookie_util.cc b/chromium/net/cookies/cookie_util.cc
index b9c7e8d601f..4071e6fd380 100644
--- a/chromium/net/cookies/cookie_util.cc
+++ b/chromium/net/cookies/cookie_util.cc
@@ -63,8 +63,19 @@ bool GetCookieDomainWithString(const GURL& url,
const std::string url_scheme(url.scheme());
const std::string url_domain_and_registry(
GetEffectiveDomain(url_scheme, url_host));
- if (url_domain_and_registry.empty())
- return false; // IP addresses/intranet hosts can't set domain cookies.
+ if (url_domain_and_registry.empty()) {
+ // We match IE/Firefox by treating an exact match between the domain
+ // attribute and the request host to be treated as a host cookie.
+ if (url_host == domain_string) {
+ *result = url_host;
+ DCHECK(DomainIsHostOnly(*result));
+ return true;
+ }
+
+ // Otherwise, IP addresses/intranet hosts/public suffixes can't set
+ // domain cookies.
+ return false;
+ }
const std::string cookie_domain_and_registry(
GetEffectiveDomain(url_scheme, cookie_domain));
if (url_domain_and_registry != cookie_domain_and_registry)
diff --git a/chromium/net/cookies/cookie_util_unittest.cc b/chromium/net/cookies/cookie_util_unittest.cc
index e76d8c92fe2..5414be1e4dd 100644
--- a/chromium/net/cookies/cookie_util_unittest.cc
+++ b/chromium/net/cookies/cookie_util_unittest.cc
@@ -5,7 +5,6 @@
#include <string>
#include <utility>
-#include "base/basictypes.h"
#include "base/strings/string_split.h"
#include "net/cookies/cookie_util.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/cookies/parsed_cookie.h b/chromium/net/cookies/parsed_cookie.h
index 029728df149..8317609be5f 100644
--- a/chromium/net/cookies/parsed_cookie.h
+++ b/chromium/net/cookies/parsed_cookie.h
@@ -5,10 +5,12 @@
#ifndef NET_COOKIES_PARSED_COOKIE_H_
#define NET_COOKIES_PARSED_COOKIE_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/cookies/cookie_constants.h"
diff --git a/chromium/net/data/certificate_policies_unittest/anypolicy.pem b/chromium/net/data/certificate_policies_unittest/anypolicy.pem
new file mode 100644
index 00000000000..104ed45e0e7
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/anypolicy.pem
@@ -0,0 +1,6 @@
+ 0:d=0 hl=2 l= 8 cons: SEQUENCE
+ 2:d=1 hl=2 l= 6 cons: SEQUENCE
+ 4:d=2 hl=2 l= 4 prim: OBJECT :X509v3 Any Policy
+-----BEGIN CERTIFICATE POLICIES-----
+MAgwBgYEVR0gAA==
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/anypolicy_with_qualifier.pem b/chromium/net/data/certificate_policies_unittest/anypolicy_with_qualifier.pem
new file mode 100644
index 00000000000..6ecc6d1b85b
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/anypolicy_with_qualifier.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 49 cons: SEQUENCE
+ 2:d=1 hl=2 l= 47 cons: SEQUENCE
+ 4:d=2 hl=2 l= 4 prim: OBJECT :X509v3 Any Policy
+ 10:d=2 hl=2 l= 39 cons: SEQUENCE
+ 12:d=3 hl=2 l= 37 cons: SEQUENCE
+ 14:d=4 hl=2 l= 8 prim: OBJECT :Policy Qualifier CPS
+ 24:d=4 hl=2 l= 25 prim: IA5STRING :https://example.com/1_2_3
+-----BEGIN CERTIFICATE POLICIES-----
+MDEwLwYEVR0gADAnMCUGCCsGAQUFBwIBFhlodHRwczovL2V4YW1wbGUuY29tLzFfMl8z
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/generate_policies.py b/chromium/net/data/certificate_policies_unittest/generate_policies.py
new file mode 100755
index 00000000000..20232e4517f
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/generate_policies.py
@@ -0,0 +1,176 @@
+#!/usr/bin/env python
+# Copyright 2015 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 base64
+import copy
+import os
+import random
+import subprocess
+import sys
+import tempfile
+
+
+def generate(token, s, out_fn):
+ with tempfile.NamedTemporaryFile() as der_tmpfile:
+ with tempfile.NamedTemporaryFile() as conf_tempfile:
+ conf_tempfile.write(str(s))
+ conf_tempfile.flush()
+ description_tmpfile = tempfile.NamedTemporaryFile()
+ subprocess.check_call(["openssl", "asn1parse", "-genconf",
+ conf_tempfile.name, "-i", "-out",
+ der_tmpfile.name],
+ stdout=description_tmpfile)
+
+ with open(out_fn, "w") as output_file:
+ description_tmpfile.seek(0)
+ output_file.write(description_tmpfile.read())
+ output_file.write("-----BEGIN %s-----\n" % token)
+ output_file.write(base64.encodestring(der_tmpfile.read()))
+ output_file.write("-----END %s-----\n" % token)
+
+
+class CertificatePoliciesGenerator:
+ def __init__(self):
+ self.policies = []
+
+ def generate(self, out_fn):
+ generate("CERTIFICATE POLICIES", self, out_fn)
+
+ def add_policy(self, policy):
+ self.policies.append(policy)
+
+ def __str__(self):
+ s = "asn1 = SEQUENCE:certificatePoliciesSequence\n"
+ s += "[certificatePoliciesSequence]\n"
+ s_suffix = ""
+ for n, policy in enumerate(self.policies):
+ n1, n2 = (str(policy) + "\n").split("\n", 1)
+ if n2:
+ s_suffix += n2 + "\n"
+ s += "%s%s\n" % (n, n1)
+
+ return s + s_suffix
+
+
+def policy_qualifier(qualifier_id, qualifier):
+ i = random.randint(0, sys.maxint)
+ s = "asn1 = SEQUENCE:PolicyQualifierInfoSequence%i\n" % i
+ s += "[PolicyQualifierInfoSequence%i]\n" % i
+ s += "policyQualifierId = %s\n" % qualifier_id
+ s += qualifier
+ return s
+
+
+def cps_uri_qualifier(url):
+ return policy_qualifier("OID:id-qt-cps", "cPSUri = IA5STRING:%s\n" % url)
+
+
+def policy_information(policy_id, qualifiers):
+ i = random.randint(0, sys.maxint)
+ s = "policyInformation = SEQUENCE:PolicyInformationSequence%i\n" % i
+ s += "[PolicyInformationSequence%i]\n" % i
+ s += "policyIdentifier = OID:%s\n" % policy_id
+ s_suffix = ""
+ if qualifiers is not None:
+ s += "policyQualifiers = SEQUENCE:PolicyQualifiersSequence%i\n" % i
+ s += "[PolicyQualifiersSequence%i]\n" % i
+ for n, qualifier in enumerate(qualifiers):
+ n1, n2 = (str(qualifier) + "\n").split("\n", 1)
+ if n2:
+ s_suffix += n2 + "\n"
+ s += "%s%s\n" % (n, n1)
+
+ return s + s_suffix
+
+
+def main():
+ p = CertificatePoliciesGenerator()
+ p.generate("invalid-empty.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("anyPolicy", None))
+ p.generate("anypolicy.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("anyPolicy", [
+ cps_uri_qualifier("https://example.com/1_2_3")]))
+ p.generate("anypolicy_with_qualifier.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("anyPolicy", [
+ policy_qualifier("OID:1.2.3.4", 'foo = UTF8:"hi"')]))
+ p.generate("invalid-anypolicy_with_custom_qualifier.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("1.2.3", None))
+ p.generate("policy_1_2_3.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("1.2.3", [
+ cps_uri_qualifier("https://example.com/1_2_3")]))
+ p.generate("policy_1_2_3_with_qualifier.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("1.2.3", [
+ policy_qualifier("OID:1.2.3.4", 'foo = UTF8:"hi"')]))
+ p.generate("policy_1_2_3_with_custom_qualifier.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("1.2.3", None))
+ p.add_policy(policy_information("1.2.3", [
+ cps_uri_qualifier("https://example.com/1_2_3")]))
+ p.generate("invalid-policy_1_2_3_dupe.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("1.2.3", []))
+ p.generate("invalid-policy_1_2_3_with_empty_qualifiers_sequence.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("1.2.3", None))
+ p.add_policy(policy_information("1.2.4", None))
+ p.generate("policy_1_2_3_and_1_2_4.pem")
+
+ p = CertificatePoliciesGenerator()
+ p.add_policy(policy_information("1.2.3", [
+ cps_uri_qualifier("https://example.com/1_2_3")]))
+ p.add_policy(policy_information("1.2.4", [
+ cps_uri_qualifier("http://example.com/1_2_4")]))
+ p.generate("policy_1_2_3_and_1_2_4_with_qualifiers.pem")
+
+ generate("CERTIFICATE POLICIES",
+ "asn1 = SEQUENCE:certificatePoliciesSequence\n"
+ "[certificatePoliciesSequence]\n"
+ "policyInformation = SEQUENCE:PolicyInformationSequence\n"
+ 'extradata = IA5STRING:"unconsumed data"\n'
+ "[PolicyInformationSequence]\n"
+ "policyIdentifier = OID:1.2.3\n",
+ "invalid-policy_1_2_3_policyinformation_unconsumed_data.pem")
+
+ generate("CERTIFICATE POLICIES",
+ "asn1 = SEQUENCE:certificatePoliciesSequence\n"
+ "[certificatePoliciesSequence]\n"
+ "policyInformation = SEQUENCE:PolicyInformationSequence\n"
+ "[PolicyInformationSequence]\n"
+ "policyIdentifier = OID:1.2.3\n"
+ "policyQualifiers = SEQUENCE:PolicyQualifiersSequence\n"
+ "[PolicyQualifiersSequence]\n"
+ "policyQualifierInfo = SEQUENCE:PolicyQualifierInfoSequence\n"
+ "[PolicyQualifierInfoSequence]\n"
+ "policyQualifierId = OID:id-qt-cps\n"
+ "cPSUri = IA5STRING:https://example.com/1_2_3\n"
+ 'extradata = IA5STRING:"unconsumed data"\n',
+ "invalid-policy_1_2_3_policyqualifierinfo_unconsumed_data.pem")
+
+ generate("CERTIFICATE POLICIES",
+ "asn1 = SEQUENCE:certificatePoliciesSequence\n"
+ "[certificatePoliciesSequence]\n"
+ "policyInformation = SEQUENCE:PolicyInformationSequence\n"
+ "[PolicyInformationSequence]\n"
+ 'policyIdentifier = IA5STRING:"1.2.3"\n',
+ "invalid-policy_identifier_not_oid.pem")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/chromium/net/data/certificate_policies_unittest/invalid-anypolicy_with_custom_qualifier.pem b/chromium/net/data/certificate_policies_unittest/invalid-anypolicy_with_custom_qualifier.pem
new file mode 100644
index 00000000000..f60dc1af775
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/invalid-anypolicy_with_custom_qualifier.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 21 cons: SEQUENCE
+ 2:d=1 hl=2 l= 19 cons: SEQUENCE
+ 4:d=2 hl=2 l= 4 prim: OBJECT :X509v3 Any Policy
+ 10:d=2 hl=2 l= 11 cons: SEQUENCE
+ 12:d=3 hl=2 l= 9 cons: SEQUENCE
+ 14:d=4 hl=2 l= 3 prim: OBJECT :1.2.3.4
+ 19:d=4 hl=2 l= 2 prim: UTF8STRING :hi
+-----BEGIN CERTIFICATE POLICIES-----
+MBUwEwYEVR0gADALMAkGAyoDBAwCaGk=
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/invalid-empty.pem b/chromium/net/data/certificate_policies_unittest/invalid-empty.pem
new file mode 100644
index 00000000000..186d6dedb5e
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/invalid-empty.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 0 cons: SEQUENCE
+-----BEGIN CERTIFICATE POLICIES-----
+MAA=
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_dupe.pem b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_dupe.pem
new file mode 100644
index 00000000000..b6671848004
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_dupe.pem
@@ -0,0 +1,12 @@
+ 0:d=0 hl=2 l= 53 cons: SEQUENCE
+ 2:d=1 hl=2 l= 4 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=1 hl=2 l= 45 cons: SEQUENCE
+ 10:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 14:d=2 hl=2 l= 39 cons: SEQUENCE
+ 16:d=3 hl=2 l= 37 cons: SEQUENCE
+ 18:d=4 hl=2 l= 8 prim: OBJECT :Policy Qualifier CPS
+ 28:d=4 hl=2 l= 25 prim: IA5STRING :https://example.com/1_2_3
+-----BEGIN CERTIFICATE POLICIES-----
+MDUwBAYCKgMwLQYCKgMwJzAlBggrBgEFBQcCARYZaHR0cHM6Ly9leGFtcGxlLmNvbS8xXzJfMw==
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyinformation_unconsumed_data.pem b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyinformation_unconsumed_data.pem
new file mode 100644
index 00000000000..689caf191a9
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyinformation_unconsumed_data.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 23 cons: SEQUENCE
+ 2:d=1 hl=2 l= 4 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=1 hl=2 l= 15 prim: IA5STRING :unconsumed data
+-----BEGIN CERTIFICATE POLICIES-----
+MBcwBAYCKgMWD3VuY29uc3VtZWQgZGF0YQ==
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyqualifierinfo_unconsumed_data.pem b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyqualifierinfo_unconsumed_data.pem
new file mode 100644
index 00000000000..c595faf8267
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_policyqualifierinfo_unconsumed_data.pem
@@ -0,0 +1,12 @@
+ 0:d=0 hl=2 l= 64 cons: SEQUENCE
+ 2:d=1 hl=2 l= 62 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=2 hl=2 l= 56 cons: SEQUENCE
+ 10:d=3 hl=2 l= 54 cons: SEQUENCE
+ 12:d=4 hl=2 l= 8 prim: OBJECT :Policy Qualifier CPS
+ 22:d=4 hl=2 l= 25 prim: IA5STRING :https://example.com/1_2_3
+ 49:d=4 hl=2 l= 15 prim: IA5STRING :unconsumed data
+-----BEGIN CERTIFICATE POLICIES-----
+MEAwPgYCKgMwODA2BggrBgEFBQcCARYZaHR0cHM6Ly9leGFtcGxlLmNvbS8xXzJfMxYPdW5jb25z
+dW1lZCBkYXRh
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_with_empty_qualifiers_sequence.pem b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_with_empty_qualifiers_sequence.pem
new file mode 100644
index 00000000000..b370a8863c4
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/invalid-policy_1_2_3_with_empty_qualifiers_sequence.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 8 cons: SEQUENCE
+ 2:d=1 hl=2 l= 6 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=2 hl=2 l= 0 cons: SEQUENCE
+-----BEGIN CERTIFICATE POLICIES-----
+MAgwBgYCKgMwAA==
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/invalid-policy_identifier_not_oid.pem b/chromium/net/data/certificate_policies_unittest/invalid-policy_identifier_not_oid.pem
new file mode 100644
index 00000000000..4cd5eacac09
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/invalid-policy_identifier_not_oid.pem
@@ -0,0 +1,6 @@
+ 0:d=0 hl=2 l= 9 cons: SEQUENCE
+ 2:d=1 hl=2 l= 7 cons: SEQUENCE
+ 4:d=2 hl=2 l= 5 prim: IA5STRING :1.2.3
+-----BEGIN CERTIFICATE POLICIES-----
+MAkwBxYFMS4yLjM=
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/policy_1_2_3.pem b/chromium/net/data/certificate_policies_unittest/policy_1_2_3.pem
new file mode 100644
index 00000000000..a67b60ed312
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/policy_1_2_3.pem
@@ -0,0 +1,6 @@
+ 0:d=0 hl=2 l= 6 cons: SEQUENCE
+ 2:d=1 hl=2 l= 4 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+-----BEGIN CERTIFICATE POLICIES-----
+MAYwBAYCKgM=
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4.pem b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4.pem
new file mode 100644
index 00000000000..8372efc5612
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 12 cons: SEQUENCE
+ 2:d=1 hl=2 l= 4 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=1 hl=2 l= 4 cons: SEQUENCE
+ 10:d=2 hl=2 l= 2 prim: OBJECT :1.2.4
+-----BEGIN CERTIFICATE POLICIES-----
+MAwwBAYCKgMwBAYCKgQ=
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4_with_qualifiers.pem b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4_with_qualifiers.pem
new file mode 100644
index 00000000000..ceb01c2a8ed
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_and_1_2_4_with_qualifiers.pem
@@ -0,0 +1,17 @@
+ 0:d=0 hl=2 l= 93 cons: SEQUENCE
+ 2:d=1 hl=2 l= 45 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=2 hl=2 l= 39 cons: SEQUENCE
+ 10:d=3 hl=2 l= 37 cons: SEQUENCE
+ 12:d=4 hl=2 l= 8 prim: OBJECT :Policy Qualifier CPS
+ 22:d=4 hl=2 l= 25 prim: IA5STRING :https://example.com/1_2_3
+ 49:d=1 hl=2 l= 44 cons: SEQUENCE
+ 51:d=2 hl=2 l= 2 prim: OBJECT :1.2.4
+ 55:d=2 hl=2 l= 38 cons: SEQUENCE
+ 57:d=3 hl=2 l= 36 cons: SEQUENCE
+ 59:d=4 hl=2 l= 8 prim: OBJECT :Policy Qualifier CPS
+ 69:d=4 hl=2 l= 24 prim: IA5STRING :http://example.com/1_2_4
+-----BEGIN CERTIFICATE POLICIES-----
+MF0wLQYCKgMwJzAlBggrBgEFBQcCARYZaHR0cHM6Ly9leGFtcGxlLmNvbS8xXzJfMzAsBgIqBDAm
+MCQGCCsGAQUFBwIBFhhodHRwOi8vZXhhbXBsZS5jb20vMV8yXzQ=
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_custom_qualifier.pem b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_custom_qualifier.pem
new file mode 100644
index 00000000000..18a27cc312a
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_custom_qualifier.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 19 cons: SEQUENCE
+ 2:d=1 hl=2 l= 17 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=2 hl=2 l= 11 cons: SEQUENCE
+ 10:d=3 hl=2 l= 9 cons: SEQUENCE
+ 12:d=4 hl=2 l= 3 prim: OBJECT :1.2.3.4
+ 17:d=4 hl=2 l= 2 prim: UTF8STRING :hi
+-----BEGIN CERTIFICATE POLICIES-----
+MBMwEQYCKgMwCzAJBgMqAwQMAmhp
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_qualifier.pem b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_qualifier.pem
new file mode 100644
index 00000000000..f2e6cedc467
--- /dev/null
+++ b/chromium/net/data/certificate_policies_unittest/policy_1_2_3_with_qualifier.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 47 cons: SEQUENCE
+ 2:d=1 hl=2 l= 45 cons: SEQUENCE
+ 4:d=2 hl=2 l= 2 prim: OBJECT :1.2.3
+ 8:d=2 hl=2 l= 39 cons: SEQUENCE
+ 10:d=3 hl=2 l= 37 cons: SEQUENCE
+ 12:d=4 hl=2 l= 8 prim: OBJECT :Policy Qualifier CPS
+ 22:d=4 hl=2 l= 25 prim: IA5STRING :https://example.com/1_2_3
+-----BEGIN CERTIFICATE POLICIES-----
+MC8wLQYCKgMwJzAlBggrBgEFBQcCARYZaHR0cHM6Ly9leGFtcGxlLmNvbS8xXzJfMw==
+-----END CERTIFICATE POLICIES-----
diff --git a/chromium/net/data/filter_unittests/google.br b/chromium/net/data/filter_unittests/google.br
new file mode 100644
index 00000000000..223a8c364ac
--- /dev/null
+++ b/chromium/net/data/filter_unittests/google.br
Binary files differ
diff --git a/chromium/net/data/ftp/dir-listing-ls-33 b/chromium/net/data/ftp/dir-listing-ls-33
new file mode 100644
index 00000000000..2a2e6a28f2d
--- /dev/null
+++ b/chromium/net/data/ftp/dir-listing-ls-33
@@ -0,0 +1,4 @@
+total -9560322322989056
+-rw-r--r-- 1 stadmin stgroup 4310450 Nov 17 13:12 01643.001.862.TestPermission-DUP0001.zip
+-rw-r--r-- 1 stadmin stgroup 2496430080 Nov 13 14:46 I_Base_01_RSE_R720.iso
+-rw-r--r-- 1 stadmin stgroup 478576612 Nov 13 08:11 I_Base_01_RSE_R720.zip
diff --git a/chromium/net/data/ftp/dir-listing-ls-33.expected b/chromium/net/data/ftp/dir-listing-ls-33.expected
new file mode 100644
index 00000000000..42ae5f932ec
--- /dev/null
+++ b/chromium/net/data/ftp/dir-listing-ls-33.expected
@@ -0,0 +1,26 @@
+-
+01643.001.862.TestPermission-DUP0001.zip
+4310450
+1993
+11
+17
+13
+12
+
+-
+I_Base_01_RSE_R720.iso
+2496430080
+1994
+11
+13
+14
+46
+
+-
+I_Base_01_RSE_R720.zip
+478576612
+1994
+11
+13
+8
+11
diff --git a/chromium/net/data/name_constraints_unittest/directoryname-excludeall.pem b/chromium/net/data/name_constraints_unittest/directoryname-excludeall.pem
new file mode 100644
index 00000000000..4f8bdb2e9d4
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/directoryname-excludeall.pem
@@ -0,0 +1,14 @@
+ 0:d=0 hl=2 l= 25 cons: SEQUENCE
+ 2:d=1 hl=2 l= 17 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 15 cons: SEQUENCE
+ 6:d=3 hl=2 l= 13 cons: cont [ 4 ]
+ 8:d=4 hl=2 l= 11 cons: SET
+ 10:d=5 hl=2 l= 9 cons: SEQUENCE
+ 12:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 17:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 21:d=1 hl=2 l= 4 cons: cont [ 1 ]
+ 23:d=2 hl=2 l= 2 cons: SEQUENCE
+ 25:d=3 hl=2 l= 0 cons: cont [ 4 ]
+-----BEGIN NAME CONSTRAINTS-----
+MBmgETAPpA0xCzAJBgNVBAYTAlVToQQwAqQA
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/directoryname-excluded.pem b/chromium/net/data/name_constraints_unittest/directoryname-excluded.pem
new file mode 100644
index 00000000000..b55c8687bc3
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/directoryname-excluded.pem
@@ -0,0 +1,15 @@
+ 0:d=0 hl=2 l= 40 cons: SEQUENCE
+ 2:d=1 hl=2 l= 38 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 36 cons: SEQUENCE
+ 6:d=3 hl=2 l= 34 cons: cont [ 4 ]
+ 8:d=4 hl=2 l= 11 cons: SET
+ 10:d=5 hl=2 l= 9 cons: SEQUENCE
+ 12:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 17:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 21:d=4 hl=2 l= 19 cons: SET
+ 23:d=5 hl=2 l= 17 cons: SEQUENCE
+ 25:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 30:d=6 hl=2 l= 10 prim: UTF8STRING :California
+-----BEGIN NAME CONSTRAINTS-----
+MCihJjAkpCIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/directoryname.pem b/chromium/net/data/name_constraints_unittest/directoryname.pem
new file mode 100644
index 00000000000..d79e691bc9a
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/directoryname.pem
@@ -0,0 +1,55 @@
+ 0:d=0 hl=3 l= 172 cons: SEQUENCE
+ 3:d=1 hl=2 l= 113 cons: cont [ 0 ]
+ 5:d=2 hl=2 l= 15 cons: SEQUENCE
+ 7:d=3 hl=2 l= 13 cons: cont [ 4 ]
+ 9:d=4 hl=2 l= 11 cons: SET
+ 11:d=5 hl=2 l= 9 cons: SEQUENCE
+ 13:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 18:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 22:d=2 hl=2 l= 60 cons: SEQUENCE
+ 24:d=3 hl=2 l= 58 cons: cont [ 4 ]
+ 26:d=4 hl=2 l= 11 cons: SET
+ 28:d=5 hl=2 l= 9 cons: SEQUENCE
+ 30:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 35:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 39:d=4 hl=2 l= 19 cons: SET
+ 41:d=5 hl=2 l= 17 cons: SEQUENCE
+ 43:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 48:d=6 hl=2 l= 10 prim: UTF8STRING :California
+ 60:d=4 hl=2 l= 22 cons: SET
+ 62:d=5 hl=2 l= 20 cons: SEQUENCE
+ 64:d=6 hl=2 l= 3 prim: OBJECT :localityName
+ 69:d=6 hl=2 l= 13 prim: UTF8STRING :Mountain View
+ 84:d=2 hl=2 l= 32 cons: SEQUENCE
+ 86:d=3 hl=2 l= 30 cons: cont [ 4 ]
+ 88:d=4 hl=2 l= 11 cons: SET
+ 90:d=5 hl=2 l= 9 cons: SEQUENCE
+ 92:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 97:d=6 hl=2 l= 2 prim: PRINTABLESTRING :JP
+ 101:d=4 hl=2 l= 15 cons: SET
+ 103:d=5 hl=2 l= 13 cons: SEQUENCE
+ 105:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 110:d=6 hl=2 l= 6 prim: UTF8STRING :東京
+ 118:d=1 hl=2 l= 55 cons: cont [ 1 ]
+ 120:d=2 hl=2 l= 36 cons: SEQUENCE
+ 122:d=3 hl=2 l= 34 cons: cont [ 4 ]
+ 124:d=4 hl=2 l= 11 cons: SET
+ 126:d=5 hl=2 l= 9 cons: SEQUENCE
+ 128:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 133:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 137:d=4 hl=2 l= 19 cons: SET
+ 139:d=5 hl=2 l= 17 cons: SEQUENCE
+ 141:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 146:d=6 hl=2 l= 10 prim: UTF8STRING :California
+ 158:d=2 hl=2 l= 15 cons: SEQUENCE
+ 160:d=3 hl=2 l= 13 cons: cont [ 4 ]
+ 162:d=4 hl=2 l= 11 cons: SET
+ 164:d=5 hl=2 l= 9 cons: SEQUENCE
+ 166:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 171:d=6 hl=2 l= 2 prim: PRINTABLESTRING :DE
+-----BEGIN NAME CONSTRAINTS-----
+MIGsoHEwD6QNMQswCQYDVQQGEwJVUzA8pDoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y
+bmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MCCkHjELMAkGA1UEBhMCSlAxDzANBgNVBAgMBuad
+seS6rKE3MCSkIjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEwD6QNMQswCQYDVQQG
+EwJERQ==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/directoryname_and_dnsname.pem b/chromium/net/data/name_constraints_unittest/directoryname_and_dnsname.pem
new file mode 100644
index 00000000000..9d4a84155f8
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/directoryname_and_dnsname.pem
@@ -0,0 +1,73 @@
+ 0:d=0 hl=4 l= 402 cons: SEQUENCE
+ 4:d=1 hl=4 l= 272 cons: cont [ 0 ]
+ 8:d=2 hl=2 l= 15 cons: SEQUENCE
+ 10:d=3 hl=2 l= 13 cons: cont [ 4 ]
+ 12:d=4 hl=2 l= 11 cons: SET
+ 14:d=5 hl=2 l= 9 cons: SEQUENCE
+ 16:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 21:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 25:d=2 hl=2 l= 60 cons: SEQUENCE
+ 27:d=3 hl=2 l= 58 cons: cont [ 4 ]
+ 29:d=4 hl=2 l= 11 cons: SET
+ 31:d=5 hl=2 l= 9 cons: SEQUENCE
+ 33:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 38:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 42:d=4 hl=2 l= 19 cons: SET
+ 44:d=5 hl=2 l= 17 cons: SEQUENCE
+ 46:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 51:d=6 hl=2 l= 10 prim: UTF8STRING :California
+ 63:d=4 hl=2 l= 22 cons: SET
+ 65:d=5 hl=2 l= 20 cons: SEQUENCE
+ 67:d=6 hl=2 l= 3 prim: OBJECT :localityName
+ 72:d=6 hl=2 l= 13 prim: UTF8STRING :Mountain View
+ 87:d=2 hl=2 l= 32 cons: SEQUENCE
+ 89:d=3 hl=2 l= 30 cons: cont [ 4 ]
+ 91:d=4 hl=2 l= 11 cons: SET
+ 93:d=5 hl=2 l= 9 cons: SEQUENCE
+ 95:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 100:d=6 hl=2 l= 2 prim: PRINTABLESTRING :JP
+ 104:d=4 hl=2 l= 15 cons: SET
+ 106:d=5 hl=2 l= 13 cons: SEQUENCE
+ 108:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 113:d=6 hl=2 l= 6 prim: UTF8STRING :東京
+ 121:d=2 hl=2 l= 23 cons: SEQUENCE
+ 123:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 146:d=2 hl=2 l= 24 cons: SEQUENCE
+ 148:d=3 hl=2 l= 22 prim: cont [ 2 ]
+ 172:d=2 hl=2 l= 25 cons: SEQUENCE
+ 174:d=3 hl=2 l= 23 prim: cont [ 2 ]
+ 199:d=2 hl=2 l= 27 cons: SEQUENCE
+ 201:d=3 hl=2 l= 25 prim: cont [ 2 ]
+ 228:d=2 hl=2 l= 50 cons: SEQUENCE
+ 230:d=3 hl=2 l= 48 prim: cont [ 2 ]
+ 280:d=1 hl=2 l= 124 cons: cont [ 1 ]
+ 282:d=2 hl=2 l= 36 cons: SEQUENCE
+ 284:d=3 hl=2 l= 34 cons: cont [ 4 ]
+ 286:d=4 hl=2 l= 11 cons: SET
+ 288:d=5 hl=2 l= 9 cons: SEQUENCE
+ 290:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 295:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 299:d=4 hl=2 l= 19 cons: SET
+ 301:d=5 hl=2 l= 17 cons: SEQUENCE
+ 303:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 308:d=6 hl=2 l= 10 prim: UTF8STRING :California
+ 320:d=2 hl=2 l= 15 cons: SEQUENCE
+ 322:d=3 hl=2 l= 13 cons: cont [ 4 ]
+ 324:d=4 hl=2 l= 11 cons: SET
+ 326:d=5 hl=2 l= 9 cons: SEQUENCE
+ 328:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 333:d=6 hl=2 l= 2 prim: PRINTABLESTRING :DE
+ 337:d=2 hl=2 l= 32 cons: SEQUENCE
+ 339:d=3 hl=2 l= 30 prim: cont [ 2 ]
+ 371:d=2 hl=2 l= 33 cons: SEQUENCE
+ 373:d=3 hl=2 l= 31 prim: cont [ 2 ]
+-----BEGIN NAME CONSTRAINTS-----
+MIIBkqCCARAwD6QNMQswCQYDVQQGEwJVUzA8pDoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
+Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MCCkHjELMAkGA1UEBhMCSlAxDzANBgNVBAgM
+BuadseS6rDAXghVwZXJtaXR0ZWQuZXhhbXBsZS5jb20wGIIWcGVybWl0dGVkLmV4YW1wbGUyLmNv
+bTAZghdwZXJtaXR0ZWQuZXhhbXBsZTMuY29tLjAbghlhbHNvcGVybWl0dGVkLmV4YW1wbGUuY29t
+MDKCMHN0aWxsbm90cGVybWl0dGVkLmV4Y2x1ZGVkLnBlcm1pdHRlZC5leGFtcGxlLmNvbaF8MCSk
+IjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEwD6QNMQswCQYDVQQGEwJERTAggh5l
+eGNsdWRlZC5wZXJtaXR0ZWQuZXhhbXBsZS5jb20wIYIfZXh0cmFuZW91c2V4Y2x1c2lvbi5leGFt
+cGxlLmNvbQ==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/directoryname_and_dnsname_and_ipaddress.pem b/chromium/net/data/name_constraints_unittest/directoryname_and_dnsname_and_ipaddress.pem
new file mode 100644
index 00000000000..93fc4705df6
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/directoryname_and_dnsname_and_ipaddress.pem
@@ -0,0 +1,97 @@
+ 0:d=0 hl=4 l= 643 cons: SEQUENCE
+ 4:d=1 hl=4 l= 416 cons: cont [ 0 ]
+ 8:d=2 hl=2 l= 15 cons: SEQUENCE
+ 10:d=3 hl=2 l= 13 cons: cont [ 4 ]
+ 12:d=4 hl=2 l= 11 cons: SET
+ 14:d=5 hl=2 l= 9 cons: SEQUENCE
+ 16:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 21:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 25:d=2 hl=2 l= 60 cons: SEQUENCE
+ 27:d=3 hl=2 l= 58 cons: cont [ 4 ]
+ 29:d=4 hl=2 l= 11 cons: SET
+ 31:d=5 hl=2 l= 9 cons: SEQUENCE
+ 33:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 38:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 42:d=4 hl=2 l= 19 cons: SET
+ 44:d=5 hl=2 l= 17 cons: SEQUENCE
+ 46:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 51:d=6 hl=2 l= 10 prim: UTF8STRING :California
+ 63:d=4 hl=2 l= 22 cons: SET
+ 65:d=5 hl=2 l= 20 cons: SEQUENCE
+ 67:d=6 hl=2 l= 3 prim: OBJECT :localityName
+ 72:d=6 hl=2 l= 13 prim: UTF8STRING :Mountain View
+ 87:d=2 hl=2 l= 32 cons: SEQUENCE
+ 89:d=3 hl=2 l= 30 cons: cont [ 4 ]
+ 91:d=4 hl=2 l= 11 cons: SET
+ 93:d=5 hl=2 l= 9 cons: SEQUENCE
+ 95:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 100:d=6 hl=2 l= 2 prim: PRINTABLESTRING :JP
+ 104:d=4 hl=2 l= 15 cons: SET
+ 106:d=5 hl=2 l= 13 cons: SEQUENCE
+ 108:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 113:d=6 hl=2 l= 6 prim: UTF8STRING :東京
+ 121:d=2 hl=2 l= 23 cons: SEQUENCE
+ 123:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 146:d=2 hl=2 l= 24 cons: SEQUENCE
+ 148:d=3 hl=2 l= 22 prim: cont [ 2 ]
+ 172:d=2 hl=2 l= 25 cons: SEQUENCE
+ 174:d=3 hl=2 l= 23 prim: cont [ 2 ]
+ 199:d=2 hl=2 l= 27 cons: SEQUENCE
+ 201:d=3 hl=2 l= 25 prim: cont [ 2 ]
+ 228:d=2 hl=2 l= 50 cons: SEQUENCE
+ 230:d=3 hl=2 l= 48 prim: cont [ 2 ]
+ 280:d=2 hl=2 l= 10 cons: SEQUENCE
+ 282:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 292:d=2 hl=2 l= 10 cons: SEQUENCE
+ 294:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 304:d=2 hl=2 l= 10 cons: SEQUENCE
+ 306:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 316:d=2 hl=2 l= 34 cons: SEQUENCE
+ 318:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 352:d=2 hl=2 l= 34 cons: SEQUENCE
+ 354:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 388:d=2 hl=2 l= 34 cons: SEQUENCE
+ 390:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 424:d=1 hl=3 l= 220 cons: cont [ 1 ]
+ 427:d=2 hl=2 l= 36 cons: SEQUENCE
+ 429:d=3 hl=2 l= 34 cons: cont [ 4 ]
+ 431:d=4 hl=2 l= 11 cons: SET
+ 433:d=5 hl=2 l= 9 cons: SEQUENCE
+ 435:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 440:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 444:d=4 hl=2 l= 19 cons: SET
+ 446:d=5 hl=2 l= 17 cons: SEQUENCE
+ 448:d=6 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 453:d=6 hl=2 l= 10 prim: UTF8STRING :California
+ 465:d=2 hl=2 l= 15 cons: SEQUENCE
+ 467:d=3 hl=2 l= 13 cons: cont [ 4 ]
+ 469:d=4 hl=2 l= 11 cons: SET
+ 471:d=5 hl=2 l= 9 cons: SEQUENCE
+ 473:d=6 hl=2 l= 3 prim: OBJECT :countryName
+ 478:d=6 hl=2 l= 2 prim: PRINTABLESTRING :DE
+ 482:d=2 hl=2 l= 32 cons: SEQUENCE
+ 484:d=3 hl=2 l= 30 prim: cont [ 2 ]
+ 516:d=2 hl=2 l= 33 cons: SEQUENCE
+ 518:d=3 hl=2 l= 31 prim: cont [ 2 ]
+ 551:d=2 hl=2 l= 10 cons: SEQUENCE
+ 553:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 563:d=2 hl=2 l= 10 cons: SEQUENCE
+ 565:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 575:d=2 hl=2 l= 34 cons: SEQUENCE
+ 577:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 611:d=2 hl=2 l= 34 cons: SEQUENCE
+ 613:d=3 hl=2 l= 32 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MIICg6CCAaAwD6QNMQswCQYDVQQGEwJVUzA8pDoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
+Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MCCkHjELMAkGA1UEBhMCSlAxDzANBgNVBAgM
+BuadseS6rDAXghVwZXJtaXR0ZWQuZXhhbXBsZS5jb20wGIIWcGVybWl0dGVkLmV4YW1wbGUyLmNv
+bTAZghdwZXJtaXR0ZWQuZXhhbXBsZTMuY29tLjAbghlhbHNvcGVybWl0dGVkLmV4YW1wbGUuY29t
+MDKCMHN0aWxsbm90cGVybWl0dGVkLmV4Y2x1ZGVkLnBlcm1pdHRlZC5leGFtcGxlLmNvbTAKhwjA
+qAAA//8AADAKhwjAqAUg////4DAKhwjApwUg////4DAihyABAgMEBQYHCAkKCwwAAAAA////////
+////////AAAAADAihyABAgMEBQYHCAkKCwwFIAAA/////////////////+AAADAihyABAgMEBQYH
+CAkKCwsFIAAA/////////////////+AAAKGB3DAkpCIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD
+YWxpZm9ybmlhMA+kDTELMAkGA1UEBhMCREUwIIIeZXhjbHVkZWQucGVybWl0dGVkLmV4YW1wbGUu
+Y29tMCGCH2V4dHJhbmVvdXNleGNsdXNpb24uZXhhbXBsZS5jb20wCocIwKgFAP///wAwCocIwKYF
+IP///+AwIocgAQIDBAUGBwgJCgsMBQAAAP////////////////8AAAAwIocgAQIDBAUGBwgJCgsK
+BSAAAP/////////////////gAAA=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-exclude_dot.pem b/chromium/net/data/name_constraints_unittest/dnsname-exclude_dot.pem
new file mode 100644
index 00000000000..7d3f179396f
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-exclude_dot.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 34 cons: SEQUENCE
+ 2:d=1 hl=2 l= 25 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 23 cons: SEQUENCE
+ 6:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 29:d=1 hl=2 l= 5 cons: cont [ 1 ]
+ 31:d=2 hl=2 l= 3 cons: SEQUENCE
+ 33:d=3 hl=2 l= 1 prim: cont [ 2 ]
+-----BEGIN NAME CONSTRAINTS-----
+MCKgGTAXghVwZXJtaXR0ZWQuZXhhbXBsZS5jb22hBTADggEu
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-excludeall.pem b/chromium/net/data/name_constraints_unittest/dnsname-excludeall.pem
new file mode 100644
index 00000000000..daf37aa99dd
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-excludeall.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 33 cons: SEQUENCE
+ 2:d=1 hl=2 l= 25 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 23 cons: SEQUENCE
+ 6:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 29:d=1 hl=2 l= 4 cons: cont [ 1 ]
+ 31:d=2 hl=2 l= 2 cons: SEQUENCE
+ 33:d=3 hl=2 l= 0 prim: cont [ 2 ]
+-----BEGIN NAME CONSTRAINTS-----
+MCGgGTAXghVwZXJtaXR0ZWQuZXhhbXBsZS5jb22hBDACggA=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-excluded.pem b/chromium/net/data/name_constraints_unittest/dnsname-excluded.pem
new file mode 100644
index 00000000000..2335c5f53dc
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-excluded.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 36 cons: SEQUENCE
+ 2:d=1 hl=2 l= 34 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 32 cons: SEQUENCE
+ 6:d=3 hl=2 l= 30 prim: cont [ 2 ]
+-----BEGIN NAME CONSTRAINTS-----
+MCShIjAggh5leGNsdWRlZC5wZXJtaXR0ZWQuZXhhbXBsZS5jb20=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-permitted_with_leading_dot.pem b/chromium/net/data/name_constraints_unittest/dnsname-permitted_with_leading_dot.pem
new file mode 100644
index 00000000000..93160a9158a
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-permitted_with_leading_dot.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 2 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKggguYmFyLmNvbQ==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-with_max.pem b/chromium/net/data/name_constraints_unittest/dnsname-with_max.pem
new file mode 100644
index 00000000000..1eec7e4ad2b
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-with_max.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 30 cons: SEQUENCE
+ 2:d=1 hl=2 l= 28 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 26 cons: SEQUENCE
+ 6:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 29:d=3 hl=2 l= 1 prim: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MB6gHDAaghVwZXJtaXR0ZWQuZXhhbXBsZS5jb22BAQI=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-with_min_0.pem b/chromium/net/data/name_constraints_unittest/dnsname-with_min_0.pem
new file mode 100644
index 00000000000..a8c8dd289fe
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-with_min_0.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 30 cons: SEQUENCE
+ 2:d=1 hl=2 l= 28 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 26 cons: SEQUENCE
+ 6:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 29:d=3 hl=2 l= 1 prim: cont [ 0 ]
+-----BEGIN NAME CONSTRAINTS-----
+MB6gHDAaghVwZXJtaXR0ZWQuZXhhbXBsZS5jb22AAQA=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-with_min_0_and_max.pem b/chromium/net/data/name_constraints_unittest/dnsname-with_min_0_and_max.pem
new file mode 100644
index 00000000000..10f31542e87
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-with_min_0_and_max.pem
@@ -0,0 +1,9 @@
+ 0:d=0 hl=2 l= 33 cons: SEQUENCE
+ 2:d=1 hl=2 l= 31 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 29 cons: SEQUENCE
+ 6:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 29:d=3 hl=2 l= 1 prim: cont [ 0 ]
+ 32:d=3 hl=2 l= 1 prim: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MCGgHzAdghVwZXJtaXR0ZWQuZXhhbXBsZS5jb22AAQCBAQI=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-with_min_1.pem b/chromium/net/data/name_constraints_unittest/dnsname-with_min_1.pem
new file mode 100644
index 00000000000..ee5fd789dde
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-with_min_1.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 30 cons: SEQUENCE
+ 2:d=1 hl=2 l= 28 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 26 cons: SEQUENCE
+ 6:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 29:d=3 hl=2 l= 1 prim: cont [ 0 ]
+-----BEGIN NAME CONSTRAINTS-----
+MB6gHDAaghVwZXJtaXR0ZWQuZXhhbXBsZS5jb22AAQE=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname-with_min_1_and_max.pem b/chromium/net/data/name_constraints_unittest/dnsname-with_min_1_and_max.pem
new file mode 100644
index 00000000000..152141fb72f
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname-with_min_1_and_max.pem
@@ -0,0 +1,9 @@
+ 0:d=0 hl=2 l= 33 cons: SEQUENCE
+ 2:d=1 hl=2 l= 31 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 29 cons: SEQUENCE
+ 6:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 29:d=3 hl=2 l= 1 prim: cont [ 0 ]
+ 32:d=3 hl=2 l= 1 prim: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MCGgHzAdghVwZXJtaXR0ZWQuZXhhbXBsZS5jb22AAQGBAQI=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname.pem b/chromium/net/data/name_constraints_unittest/dnsname.pem
new file mode 100644
index 00000000000..ead8c92a495
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname.pem
@@ -0,0 +1,24 @@
+ 0:d=0 hl=3 l= 233 cons: SEQUENCE
+ 3:d=1 hl=3 l= 159 cons: cont [ 0 ]
+ 6:d=2 hl=2 l= 23 cons: SEQUENCE
+ 8:d=3 hl=2 l= 21 prim: cont [ 2 ]
+ 31:d=2 hl=2 l= 24 cons: SEQUENCE
+ 33:d=3 hl=2 l= 22 prim: cont [ 2 ]
+ 57:d=2 hl=2 l= 25 cons: SEQUENCE
+ 59:d=3 hl=2 l= 23 prim: cont [ 2 ]
+ 84:d=2 hl=2 l= 27 cons: SEQUENCE
+ 86:d=3 hl=2 l= 25 prim: cont [ 2 ]
+ 113:d=2 hl=2 l= 50 cons: SEQUENCE
+ 115:d=3 hl=2 l= 48 prim: cont [ 2 ]
+ 165:d=1 hl=2 l= 69 cons: cont [ 1 ]
+ 167:d=2 hl=2 l= 32 cons: SEQUENCE
+ 169:d=3 hl=2 l= 30 prim: cont [ 2 ]
+ 201:d=2 hl=2 l= 33 cons: SEQUENCE
+ 203:d=3 hl=2 l= 31 prim: cont [ 2 ]
+-----BEGIN NAME CONSTRAINTS-----
+MIHpoIGfMBeCFXBlcm1pdHRlZC5leGFtcGxlLmNvbTAYghZwZXJtaXR0ZWQuZXhhbXBsZTIuY29t
+MBmCF3Blcm1pdHRlZC5leGFtcGxlMy5jb20uMBuCGWFsc29wZXJtaXR0ZWQuZXhhbXBsZS5jb20w
+MoIwc3RpbGxub3RwZXJtaXR0ZWQuZXhjbHVkZWQucGVybWl0dGVkLmV4YW1wbGUuY29toUUwIIIe
+ZXhjbHVkZWQucGVybWl0dGVkLmV4YW1wbGUuY29tMCGCH2V4dHJhbmVvdXNleGNsdXNpb24uZXhh
+bXBsZS5jb20=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/dnsname2.pem b/chromium/net/data/name_constraints_unittest/dnsname2.pem
new file mode 100644
index 00000000000..0d5edbd193e
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/dnsname2.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 26 cons: SEQUENCE
+ 2:d=1 hl=2 l= 7 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 5 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: cont [ 2 ]
+ 11:d=1 hl=2 l= 15 cons: cont [ 1 ]
+ 13:d=2 hl=2 l= 13 cons: SEQUENCE
+ 15:d=3 hl=2 l= 11 prim: cont [ 2 ]
+-----BEGIN NAME CONSTRAINTS-----
+MBqgBzAFggNjb22hDzANggtmb28uYmFyLmNvbQ==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/edipartyname-excluded.pem b/chromium/net/data/name_constraints_unittest/edipartyname-excluded.pem
new file mode 100644
index 00000000000..4163d4471b5
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/edipartyname-excluded.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 11 cons: SEQUENCE
+ 2:d=1 hl=2 l= 9 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 7 cons: SEQUENCE
+ 6:d=3 hl=2 l= 5 cons: cont [ 5 ]
+ 8:d=4 hl=2 l= 3 prim: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MAuhCTAHpQWBA2Zvbw==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/edipartyname-permitted.pem b/chromium/net/data/name_constraints_unittest/edipartyname-permitted.pem
new file mode 100644
index 00000000000..e677fd86aa0
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/edipartyname-permitted.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 11 cons: SEQUENCE
+ 2:d=1 hl=2 l= 9 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 7 cons: SEQUENCE
+ 6:d=3 hl=2 l= 5 cons: cont [ 5 ]
+ 8:d=4 hl=2 l= 3 prim: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MAugCTAHpQWBA2Zvbw==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/generate_name_constraints.py b/chromium/net/data/name_constraints_unittest/generate_name_constraints.py
new file mode 100755
index 00000000000..5f9fa4d7d7a
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/generate_name_constraints.py
@@ -0,0 +1,533 @@
+#!/usr/bin/env python
+# Copyright 2015 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 base64
+import copy
+import os
+import random
+import subprocess
+import sys
+import tempfile
+
+sys.path += [os.path.join('..', 'verify_name_match_unittest', 'scripts')]
+
+import generate_names
+
+
+def generate(s, out_fn):
+ conf_tempfile = tempfile.NamedTemporaryFile()
+ conf_tempfile.write(str(s))
+ conf_tempfile.flush()
+ der_tmpfile = tempfile.NamedTemporaryFile()
+ description_tmpfile = tempfile.NamedTemporaryFile()
+ subprocess.check_call(['openssl', 'asn1parse', '-genconf', conf_tempfile.name,
+ '-i', '-out', der_tmpfile.name],
+ stdout=description_tmpfile)
+ conf_tempfile.close()
+
+ output_file = open(out_fn, 'w')
+ description_tmpfile.seek(0)
+ output_file.write(description_tmpfile.read())
+ output_file.write('-----BEGIN %s-----\n' % s.token())
+ output_file.write(base64.encodestring(der_tmpfile.read()))
+ output_file.write('-----END %s-----\n' % s.token())
+ output_file.close()
+
+
+class SubjectAltNameGenerator:
+ def __init__(self):
+ self.names = []
+
+ def token(self):
+ return "SUBJECT ALTERNATIVE NAME"
+
+ def add_name(self, general_name):
+ self.names.append(general_name)
+
+ def __str__(self):
+ s = "asn1 = OCTWRAP,SEQUENCE:subjectAltNameSequence\n"
+ s += "[subjectAltNameSequence]\n"
+ s_suffix = ""
+ for n, name in enumerate(self.names):
+ n1, n2 = (str(name) + '\n').split('\n', 1)
+ if n2:
+ s_suffix += n2 + '\n'
+ s += '%s%s\n' % (n, n1)
+
+ return s + s_suffix
+
+
+class NameConstraintsGenerator:
+ def __init__(self,
+ force_permitted_sequence=False,
+ force_excluded_sequence=False):
+ self.permitted = []
+ self.excluded = []
+ self.force_permitted_sequence = force_permitted_sequence
+ self.force_excluded_sequence = force_excluded_sequence
+
+ def token(self):
+ return "NAME CONSTRAINTS"
+
+ def union_from(self, c):
+ self.permitted.extend(c.permitted)
+ self.excluded.extend(c.excluded)
+
+ def add_permitted(self, general_name):
+ self.permitted.append(general_name)
+
+ def add_excluded(self, general_name):
+ self.excluded.append(general_name)
+
+ def __str__(self):
+ s = "asn1 = SEQUENCE:nameConstraintsSequence\n[nameConstraintsSequence]\n"
+
+ if self.permitted or self.force_permitted_sequence:
+ s += "permittedSubtrees = IMPLICIT:0,SEQUENCE:permittedSubtreesSequence\n"
+ if self.excluded or self.force_excluded_sequence:
+ s += "excludedSubtrees = IMPLICIT:1,SEQUENCE:excludedSubtreesSequence\n"
+
+ if self.permitted or self.force_permitted_sequence:
+ s += "[permittedSubtreesSequence]\n"
+ for n, subtree in enumerate(self.permitted):
+ s += 'subtree%i = SEQUENCE:permittedSubtree%i\n' % (n, n)
+
+ if self.excluded or self.force_excluded_sequence:
+ s += "[excludedSubtreesSequence]\n"
+ for n, subtree in enumerate(self.excluded):
+ s += 'subtree%i = SEQUENCE:excludedSubtree%i\n' % (n, n)
+
+ for n, subtree in enumerate(self.permitted):
+ s += '[permittedSubtree%i]\n%s\n' % (n, subtree)
+
+ for n, subtree in enumerate(self.excluded):
+ s += '[excludedSubtree%i]\n%s\n' % (n, subtree)
+
+ return s
+
+
+def other_name():
+ i = random.randint(0, sys.maxint)
+ s = 'otherName = IMPLICIT:0,SEQUENCE:otherNameSequence%i\n' % i
+ s += '[otherNameSequence%i]\n' % i
+ s += 'type_id = OID:1.2.3.4.5\n'
+ s += 'value = FORMAT:HEX,OCTETSTRING:DEADBEEF\n'
+ return s
+
+
+def rfc822_name(name):
+ return 'rfc822Name = IMPLICIT:1,IA5STRING:' + name
+
+
+def dns_name(name):
+ return 'dNSName = IMPLICIT:2,IA5STRING:' + name
+
+
+def x400_address():
+ i = random.randint(0, sys.maxint)
+ s = 'x400Address = IMPLICIT:3,SEQUENCE:x400AddressSequence%i\n' % i
+ s += '[x400AddressSequence%i]\n' % i
+ s += 'builtinstandardattributes = SEQUENCE:BuiltInStandardAttributes%i\n' % i
+ s += '[BuiltInStandardAttributes%i]\n' % i
+ s += 'countryname = EXPLICIT:1A,PRINTABLESTRING:US\n'
+ return s
+
+
+def directory_name(name):
+ return str(name).replace(
+ 'asn1 = SEQUENCE', 'directoryName = IMPLICIT:4,SEQUENCE')
+
+
+def edi_party_name():
+ i = random.randint(0, sys.maxint)
+ s = 'ediPartyName = IMPLICIT:5,SEQUENCE:ediPartyNameSequence%i\n' % i
+ s += '[ediPartyNameSequence%i]\n' % i
+ s += 'partyName = IMPLICIT:1,UTF8:foo\n'
+ return s
+
+
+def uniform_resource_identifier(name):
+ return 'uniformResourceIdentifier = IMPLICIT:6,IA5STRING:' + name
+
+
+def ip_address(addr, enforce_length=True):
+ if enforce_length:
+ assert len(addr) in (4,16)
+ addr_str = ""
+ for addr_byte in addr:
+ addr_str += '%02X'%(addr_byte)
+ return 'iPAddress = IMPLICIT:7,FORMAT:HEX,OCTETSTRING:' + addr_str
+
+
+def ip_address_range(addr, netmask, enforce_length=True):
+ if enforce_length:
+ assert len(addr) == len(netmask)
+ assert len(addr) in (4,16)
+ addr_str = ""
+ netmask_str = ""
+ for addr_byte, mask_byte in map(None, addr, netmask):
+ assert (addr_byte & ~mask_byte) == 0
+ addr_str += '%02X'%(addr_byte)
+ netmask_str += '%02X'%(mask_byte)
+ return ('iPAddress = IMPLICIT:7,FORMAT:HEX,OCTETSTRING:' + addr_str +
+ netmask_str)
+
+
+def registered_id(oid):
+ return 'registeredID = IMPLICIT:8,OID:' + oid
+
+
+def with_min_max(val, minimum=None, maximum=None):
+ s = val
+ s += '\n'
+ assert '\n[' not in s
+ if minimum is not None:
+ s += 'minimum = IMPLICIT:0,INTEGER:%i\n' % minimum
+ if maximum is not None:
+ s += 'maximum = IMPLICIT:1,INTEGER:%i\n' % maximum
+ return s
+
+
+def main():
+ dnsname_constraints = NameConstraintsGenerator()
+ dnsname_constraints.add_permitted(dns_name("permitted.example.com"))
+ dnsname_constraints.add_permitted(dns_name("permitted.example2.com"))
+ dnsname_constraints.add_permitted(dns_name("permitted.example3.com."))
+ dnsname_constraints.add_permitted(dns_name("alsopermitted.example.com"))
+ dnsname_constraints.add_excluded(dns_name("excluded.permitted.example.com"))
+ dnsname_constraints.add_permitted(
+ dns_name("stillnotpermitted.excluded.permitted.example.com"))
+ dnsname_constraints.add_excluded(dns_name("extraneousexclusion.example.com"))
+ generate(dnsname_constraints, "dnsname.pem")
+
+ dnsname_constraints2 = NameConstraintsGenerator()
+ dnsname_constraints2.add_permitted(dns_name("com"))
+ dnsname_constraints2.add_excluded(dns_name("foo.bar.com"))
+ generate(dnsname_constraints2, "dnsname2.pem")
+
+ dnsname_constraints3 = NameConstraintsGenerator()
+ dnsname_constraints3.add_permitted(dns_name(".bar.com"))
+ generate(dnsname_constraints3, "dnsname-permitted_with_leading_dot.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_excluded(dns_name("excluded.permitted.example.com"))
+ generate(c, "dnsname-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(dns_name("permitted.example.com"))
+ c.add_excluded(dns_name(""))
+ generate(c, "dnsname-excludeall.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(dns_name("permitted.example.com"))
+ c.add_excluded(dns_name("."))
+ generate(c, "dnsname-exclude_dot.pem")
+
+ ipaddress_constraints = NameConstraintsGenerator()
+ ipaddress_constraints.add_permitted(
+ ip_address_range((192,168,0,0),(255,255,0,0)))
+ ipaddress_constraints.add_excluded(
+ ip_address_range((192,168,5,0),(255,255,255,0)))
+ ipaddress_constraints.add_permitted(
+ ip_address_range((192,168,5,32),(255,255,255,224)))
+ ipaddress_constraints.add_permitted(
+ ip_address_range((192,167,5,32),(255,255,255,224)))
+ ipaddress_constraints.add_excluded(
+ ip_address_range((192,166,5,32),(255,255,255,224)))
+ ipaddress_constraints.add_permitted(ip_address_range(
+ (1,2,3,4,5,6,7,8,9,10,11,12,0,0,0,0),
+ (255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0)))
+ ipaddress_constraints.add_excluded(ip_address_range(
+ (1,2,3,4,5,6,7,8,9,10,11,12,5,0,0,0),
+ (255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0)))
+ ipaddress_constraints.add_permitted(ip_address_range(
+ (1,2,3,4,5,6,7,8,9,10,11,12,5,32,0,0),
+ (255,255,255,255,255,255,255,255,255,255,255,255,255,224,0,0)))
+ ipaddress_constraints.add_permitted(ip_address_range(
+ (1,2,3,4,5,6,7,8,9,10,11,11,5,32,0,0),
+ (255,255,255,255,255,255,255,255,255,255,255,255,255,224,0,0)))
+ ipaddress_constraints.add_excluded(ip_address_range(
+ (1,2,3,4,5,6,7,8,9,10,11,10,5,32,0,0),
+ (255,255,255,255,255,255,255,255,255,255,255,255,255,224,0,0)))
+ generate(ipaddress_constraints, "ipaddress.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((192,168,1,3),(255,255,255,255)))
+ generate(c, "ipaddress-permit_singlehost.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((0,0,0,0),(0,0,0,0)))
+ generate(c, "ipaddress-permit_all.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((0x80,0,0,0),(0x80,0,0,0)))
+ generate(c, "ipaddress-permit_prefix1.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((192,168,1,2),(255,255,255,254)))
+ generate(c, "ipaddress-permit_prefix31.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((192,168,1,0),(255,255,255,253)))
+ generate(c, "ipaddress-invalid_mask_not_contiguous_1.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((192,168,0,0),(255,253,0,0)))
+ generate(c, "ipaddress-invalid_mask_not_contiguous_2.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((0,0,0,0),(0x40,0,0,0)))
+ generate(c, "ipaddress-invalid_mask_not_contiguous_3.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((192,0,0,0),(0xFF,0,0xFF,0)))
+ generate(c, "ipaddress-invalid_mask_not_contiguous_4.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_excluded(ip_address_range((192,168,5,0),(255,255,255,0)))
+ generate(c, "ipaddress-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((192,168,0,0),(255,255,0,0)))
+ c.add_permitted(ip_address_range((1,2,3,4,5,6,7,8,9,10,11,12,0,0,0,0),
+ (255,255,255,255,255,255,255,255,
+ 255,255,255,255,0,0,0,0)))
+ c.add_excluded(ip_address_range((0,0,0,0),(0,0,0,0)))
+ c.add_excluded(ip_address_range((0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)))
+ generate(c, "ipaddress-excludeall.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(ip_address_range((192,168,0,0),(255,255,255,0)))
+ c.add_permitted(ip_address_range((192,168,5,0,0),(255,255,255,0,0),
+ enforce_length=False))
+ generate(c, "ipaddress-invalid_addr.pem")
+
+ n_us = generate_names.NameGenerator()
+ n_us.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'US')
+ generate(n_us, "name-us.pem")
+ n_us_az = copy.deepcopy(n_us)
+ n_us_az.add_rdn().add_attr('stateOrProvinceName', 'UTF8', 'Arizona')
+ generate(n_us_az, "name-us-arizona.pem")
+ n_us_ca = copy.deepcopy(n_us)
+ n_us_ca.add_rdn().add_attr('stateOrProvinceName', 'UTF8', 'California')
+ generate(n_us_ca, "name-us-california.pem")
+ n_us_ca_mountain_view = copy.deepcopy(n_us_ca)
+ n_us_ca_mountain_view.add_rdn().add_attr(
+ 'localityName', 'UTF8', 'Mountain View')
+ generate(n_us_ca_mountain_view, "name-us-california-mountain_view.pem")
+
+ n_jp = generate_names.NameGenerator()
+ n_jp.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'JP')
+ generate(n_jp, "name-jp.pem")
+ n_jp_tokyo = copy.deepcopy(n_jp)
+ n_jp_tokyo.add_rdn().add_attr(
+ 'stateOrProvinceName', 'UTF8', '\xe6\x9d\xb1\xe4\xba\xac', 'FORMAT:UTF8')
+ generate(n_jp_tokyo, "name-jp-tokyo.pem")
+
+ n_us_az_foodotcom = copy.deepcopy(n_us_az)
+ n_us_az_foodotcom.add_rdn().add_attr('commonName', 'UTF8', 'foo.com')
+ generate(n_us_az_foodotcom, "name-us-arizona-foo.com.pem")
+
+ n_us_az_permittedexamplecom = copy.deepcopy(n_us_az)
+ n_us_az_permittedexamplecom.add_rdn().add_attr('commonName', 'UTF8',
+ 'permitted.example.com')
+ generate(n_us_az_permittedexamplecom,
+ "name-us-arizona-permitted.example.com.pem")
+
+ n_us_ca_permittedexamplecom = copy.deepcopy(n_us_ca)
+ n_us_ca_permittedexamplecom.add_rdn().add_attr('commonName', 'UTF8',
+ 'permitted.example.com')
+ generate(n_us_ca_permittedexamplecom,
+ "name-us-california-permitted.example.com.pem")
+
+ n_us_az_ip1111 = copy.deepcopy(n_us_az)
+ n_us_az_ip1111.add_rdn().add_attr('commonName', 'UTF8', '1.1.1.1')
+ generate(n_us_az_ip1111, "name-us-arizona-1.1.1.1.pem")
+
+ n_us_az_192_168_1_1 = copy.deepcopy(n_us_az)
+ n_us_az_192_168_1_1.add_rdn().add_attr('commonName', 'UTF8', '192.168.1.1')
+ generate(n_us_az_192_168_1_1, "name-us-arizona-192.168.1.1.pem")
+
+ n_us_az_ipv6 = copy.deepcopy(n_us_az)
+ n_us_az_ipv6.add_rdn().add_attr('commonName', 'UTF8',
+ '102:304:506:708:90a:b0c::1')
+ generate(n_us_az_ipv6, "name-us-arizona-ipv6.pem")
+
+ n_us_ca_192_168_1_1 = copy.deepcopy(n_us_ca)
+ n_us_ca_192_168_1_1.add_rdn().add_attr('commonName', 'UTF8', '192.168.1.1')
+ generate(n_us_ca_192_168_1_1, "name-us-california-192.168.1.1.pem")
+
+ n_us_az_email = copy.deepcopy(n_us_az)
+ n_us_az_email.add_rdn().add_attr('emailAddress', 'IA5STRING',
+ 'bar@example.com')
+ generate(n_us_az_email, "name-us-arizona-email.pem")
+
+ n_ca = generate_names.NameGenerator()
+ n_ca.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'CA')
+ generate(n_ca, "name-ca.pem")
+
+ n_de = generate_names.NameGenerator()
+ n_de.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'DE')
+ generate(n_de, "name-de.pem")
+
+ n_empty = generate_names.NameGenerator()
+ generate(n_empty, "name-empty.pem")
+
+
+ directoryname_constraints = NameConstraintsGenerator()
+ directoryname_constraints.add_permitted(directory_name(n_us))
+ directoryname_constraints.add_excluded(directory_name(n_us_ca))
+ directoryname_constraints.add_permitted(directory_name(n_us_ca_mountain_view))
+ directoryname_constraints.add_excluded(directory_name(n_de))
+ directoryname_constraints.add_permitted(directory_name(n_jp_tokyo))
+ generate(directoryname_constraints, "directoryname.pem")
+
+ c = NameConstraintsGenerator()
+ c.union_from(directoryname_constraints)
+ c.union_from(dnsname_constraints)
+ generate(c, "directoryname_and_dnsname.pem")
+
+ c = NameConstraintsGenerator()
+ c.union_from(directoryname_constraints)
+ c.union_from(dnsname_constraints)
+ c.union_from(ipaddress_constraints)
+ generate(c, "directoryname_and_dnsname_and_ipaddress.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_excluded(directory_name(n_us_ca))
+ generate(c, "directoryname-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(directory_name(n_us))
+ c.add_excluded(directory_name(n_empty))
+ generate(c, "directoryname-excludeall.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(dns_name("permitted.example.com"))
+ san.add_name(ip_address((192,168,1,2)))
+ san.add_name(directory_name(n_us_az))
+ generate(san, "san-permitted.pem")
+
+ san2 = copy.deepcopy(san)
+ san2.add_name(
+ dns_name("foo.stillnotpermitted.excluded.permitted.example.com"))
+ generate(san2, "san-excluded-dnsname.pem")
+
+ san2 = copy.deepcopy(san)
+ san2.add_name(ip_address((192,168,5,5)))
+ generate(san2, "san-excluded-ipaddress.pem")
+
+ san2 = copy.deepcopy(san)
+ san2.add_name(directory_name(n_us_ca_mountain_view))
+ generate(san2, "san-excluded-directoryname.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(other_name())
+ generate(san, "san-othername.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(rfc822_name("foo@example.com"))
+ generate(san, "san-rfc822name.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(x400_address())
+ generate(san, "san-x400address.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(edi_party_name())
+ generate(san, "san-edipartyname.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(uniform_resource_identifier('http://example.com'))
+ generate(san, "san-uri.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(registered_id("1.2.3.4"))
+ generate(san, "san-registeredid.pem")
+
+ san = SubjectAltNameGenerator()
+ generate(san, "san-invalid-empty.pem")
+
+ san = SubjectAltNameGenerator()
+ san.add_name(ip_address((192,168,0,5,0), enforce_length=False))
+ generate(san, "san-invalid-ipaddress.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(other_name())
+ generate(c, "othername-permitted.pem")
+ c = NameConstraintsGenerator()
+ c.add_excluded(other_name())
+ generate(c, "othername-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(rfc822_name("foo@example.com"))
+ generate(c, "rfc822name-permitted.pem")
+ c = NameConstraintsGenerator()
+ c.add_excluded(rfc822_name("foo@example.com"))
+ generate(c, "rfc822name-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(x400_address())
+ generate(c, "x400address-permitted.pem")
+ c = NameConstraintsGenerator()
+ c.add_excluded(x400_address())
+ generate(c, "x400address-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(edi_party_name())
+ generate(c, "edipartyname-permitted.pem")
+ c = NameConstraintsGenerator()
+ c.add_excluded(edi_party_name())
+ generate(c, "edipartyname-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(uniform_resource_identifier("http://example.com"))
+ generate(c, "uri-permitted.pem")
+ c = NameConstraintsGenerator()
+ c.add_excluded(uniform_resource_identifier("http://example.com"))
+ generate(c, "uri-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(registered_id("1.2.3.4"))
+ generate(c, "registeredid-permitted.pem")
+ c = NameConstraintsGenerator()
+ c.add_excluded(registered_id("1.2.3.4"))
+ generate(c, "registeredid-excluded.pem")
+
+ c = NameConstraintsGenerator()
+ generate(c, "invalid-no_subtrees.pem")
+
+ c = NameConstraintsGenerator(force_permitted_sequence=True)
+ generate(c, "invalid-empty_permitted_subtree.pem")
+
+ c = NameConstraintsGenerator(force_excluded_sequence=True)
+ generate(c, "invalid-empty_excluded_subtree.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(with_min_max(dns_name("permitted.example.com"), minimum=0))
+ generate(c, "dnsname-with_min_0.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(with_min_max(dns_name("permitted.example.com"), minimum=1))
+ generate(c, "dnsname-with_min_1.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(with_min_max(
+ dns_name("permitted.example.com"), minimum=0, maximum=2))
+ generate(c, "dnsname-with_min_0_and_max.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(with_min_max(
+ dns_name("permitted.example.com"), minimum=1, maximum=2))
+ generate(c, "dnsname-with_min_1_and_max.pem")
+
+ c = NameConstraintsGenerator()
+ c.add_permitted(with_min_max(dns_name("permitted.example.com"), maximum=2))
+ generate(c, "dnsname-with_max.pem")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/chromium/net/data/name_constraints_unittest/invalid-empty_excluded_subtree.pem b/chromium/net/data/name_constraints_unittest/invalid-empty_excluded_subtree.pem
new file mode 100644
index 00000000000..ab4c77c1704
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/invalid-empty_excluded_subtree.pem
@@ -0,0 +1,5 @@
+ 0:d=0 hl=2 l= 2 cons: SEQUENCE
+ 2:d=1 hl=2 l= 0 cons: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MAKhAA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/invalid-empty_permitted_subtree.pem b/chromium/net/data/name_constraints_unittest/invalid-empty_permitted_subtree.pem
new file mode 100644
index 00000000000..35eb42585ac
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/invalid-empty_permitted_subtree.pem
@@ -0,0 +1,5 @@
+ 0:d=0 hl=2 l= 2 cons: SEQUENCE
+ 2:d=1 hl=2 l= 0 cons: cont [ 0 ]
+-----BEGIN NAME CONSTRAINTS-----
+MAKgAA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/invalid-no_subtrees.pem b/chromium/net/data/name_constraints_unittest/invalid-no_subtrees.pem
new file mode 100644
index 00000000000..20e405699f0
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/invalid-no_subtrees.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 0 cons: SEQUENCE
+-----BEGIN NAME CONSTRAINTS-----
+MAA=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-excludeall.pem b/chromium/net/data/name_constraints_unittest/ipaddress-excludeall.pem
new file mode 100644
index 00000000000..c06188c27d5
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-excludeall.pem
@@ -0,0 +1,15 @@
+ 0:d=0 hl=2 l= 100 cons: SEQUENCE
+ 2:d=1 hl=2 l= 48 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 16:d=2 hl=2 l= 34 cons: SEQUENCE
+ 18:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 52:d=1 hl=2 l= 48 cons: cont [ 1 ]
+ 54:d=2 hl=2 l= 10 cons: SEQUENCE
+ 56:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 66:d=2 hl=2 l= 34 cons: SEQUENCE
+ 68:d=3 hl=2 l= 32 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MGSgMDAKhwjAqAAA//8AADAihyABAgMEBQYHCAkKCwwAAAAA////////////////AAAAAKEwMAqH
+CAAAAAAAAAAAMCKHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-excluded.pem b/chromium/net/data/name_constraints_unittest/ipaddress-excluded.pem
new file mode 100644
index 00000000000..962924c4b23
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-excluded.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6hDDAKhwjAqAUA////AA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-invalid_addr.pem b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_addr.pem
new file mode 100644
index 00000000000..66adb2aa64a
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_addr.pem
@@ -0,0 +1,9 @@
+ 0:d=0 hl=2 l= 28 cons: SEQUENCE
+ 2:d=1 hl=2 l= 26 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 16:d=2 hl=2 l= 12 cons: SEQUENCE
+ 18:d=3 hl=2 l= 10 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MBygGjAKhwjAqAAA////ADAMhwrAqAUAAP///wAA
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_1.pem b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_1.pem
new file mode 100644
index 00000000000..1ac3279da1b
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_1.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwjAqAEA/////Q==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_2.pem b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_2.pem
new file mode 100644
index 00000000000..9c25df76f4f
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_2.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwjAqAAA//0AAA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_3.pem b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_3.pem
new file mode 100644
index 00000000000..4c24ab607b5
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_3.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwgAAAAAQAAAAA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_4.pem b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_4.pem
new file mode 100644
index 00000000000..991af99e42e
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-invalid_mask_not_contiguous_4.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwjAAAAA/wD/AA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-permit_all.pem b/chromium/net/data/name_constraints_unittest/ipaddress-permit_all.pem
new file mode 100644
index 00000000000..0c2cae5a922
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-permit_all.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwgAAAAAAAAAAA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix1.pem b/chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix1.pem
new file mode 100644
index 00000000000..05cf9ce8b7b
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix1.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwiAAAAAgAAAAA==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix31.pem b/chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix31.pem
new file mode 100644
index 00000000000..d1f371430dc
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-permit_prefix31.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwjAqAEC/////g==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress-permit_singlehost.pem b/chromium/net/data/name_constraints_unittest/ipaddress-permit_singlehost.pem
new file mode 100644
index 00000000000..d4b2195f794
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress-permit_singlehost.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKhwjAqAED/////w==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/ipaddress.pem b/chromium/net/data/name_constraints_unittest/ipaddress.pem
new file mode 100644
index 00000000000..5515af94dfc
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/ipaddress.pem
@@ -0,0 +1,30 @@
+ 0:d=0 hl=3 l= 245 cons: SEQUENCE
+ 3:d=1 hl=3 l= 144 cons: cont [ 0 ]
+ 6:d=2 hl=2 l= 10 cons: SEQUENCE
+ 8:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 18:d=2 hl=2 l= 10 cons: SEQUENCE
+ 20:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 30:d=2 hl=2 l= 10 cons: SEQUENCE
+ 32:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 42:d=2 hl=2 l= 34 cons: SEQUENCE
+ 44:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 78:d=2 hl=2 l= 34 cons: SEQUENCE
+ 80:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 114:d=2 hl=2 l= 34 cons: SEQUENCE
+ 116:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 150:d=1 hl=2 l= 96 cons: cont [ 1 ]
+ 152:d=2 hl=2 l= 10 cons: SEQUENCE
+ 154:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 164:d=2 hl=2 l= 10 cons: SEQUENCE
+ 166:d=3 hl=2 l= 8 prim: cont [ 7 ]
+ 176:d=2 hl=2 l= 34 cons: SEQUENCE
+ 178:d=3 hl=2 l= 32 prim: cont [ 7 ]
+ 212:d=2 hl=2 l= 34 cons: SEQUENCE
+ 214:d=3 hl=2 l= 32 prim: cont [ 7 ]
+-----BEGIN NAME CONSTRAINTS-----
+MIH1oIGQMAqHCMCoAAD//wAAMAqHCMCoBSD////gMAqHCMCnBSD////gMCKHIAECAwQFBgcICQoL
+DAAAAAD///////////////8AAAAAMCKHIAECAwQFBgcICQoLDAUgAAD/////////////////4AAA
+MCKHIAECAwQFBgcICQoLCwUgAAD/////////////////4AAAoWAwCocIwKgFAP///wAwCocIwKYF
+IP///+AwIocgAQIDBAUGBwgJCgsMBQAAAP////////////////8AAAAwIocgAQIDBAUGBwgJCgsK
+BSAAAP/////////////////gAAA=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/name-ca.pem b/chromium/net/data/name_constraints_unittest/name-ca.pem
new file mode 100644
index 00000000000..eeef80b93ae
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-ca.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 13 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :CA
+-----BEGIN NAME-----
+MA0xCzAJBgNVBAYTAkNB
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-de.pem b/chromium/net/data/name_constraints_unittest/name-de.pem
new file mode 100644
index 00000000000..2c26155824f
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-de.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 13 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :DE
+-----BEGIN NAME-----
+MA0xCzAJBgNVBAYTAkRF
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-empty.pem b/chromium/net/data/name_constraints_unittest/name-empty.pem
new file mode 100644
index 00000000000..c1fa55c37df
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-empty.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 0 cons: SEQUENCE
+-----BEGIN NAME-----
+MAA=
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-jp-tokyo.pem b/chromium/net/data/name_constraints_unittest/name-jp-tokyo.pem
new file mode 100644
index 00000000000..5e734eaead2
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-jp-tokyo.pem
@@ -0,0 +1,12 @@
+ 0:d=0 hl=2 l= 30 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :JP
+ 15:d=1 hl=2 l= 15 cons: SET
+ 17:d=2 hl=2 l= 13 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 6 prim: UTF8STRING :東京
+-----BEGIN NAME-----
+MB4xCzAJBgNVBAYTAkpQMQ8wDQYDVQQIDAbmnbHkuqw=
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-jp.pem b/chromium/net/data/name_constraints_unittest/name-jp.pem
new file mode 100644
index 00000000000..3746455b866
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-jp.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 13 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :JP
+-----BEGIN NAME-----
+MA0xCzAJBgNVBAYTAkpQ
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-arizona-1.1.1.1.pem b/chromium/net/data/name_constraints_unittest/name-us-arizona-1.1.1.1.pem
new file mode 100644
index 00000000000..7ccd6dc88a8
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-arizona-1.1.1.1.pem
@@ -0,0 +1,16 @@
+ 0:d=0 hl=2 l= 49 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 16 cons: SET
+ 17:d=2 hl=2 l= 14 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 7 prim: UTF8STRING :Arizona
+ 33:d=1 hl=2 l= 16 cons: SET
+ 35:d=2 hl=2 l= 14 cons: SEQUENCE
+ 37:d=3 hl=2 l= 3 prim: OBJECT :commonName
+ 42:d=3 hl=2 l= 7 prim: UTF8STRING :1.1.1.1
+-----BEGIN NAME-----
+MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMRAwDgYDVQQDDAcxLjEuMS4x
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-arizona-192.168.1.1.pem b/chromium/net/data/name_constraints_unittest/name-us-arizona-192.168.1.1.pem
new file mode 100644
index 00000000000..70d5bc68c51
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-arizona-192.168.1.1.pem
@@ -0,0 +1,16 @@
+ 0:d=0 hl=2 l= 53 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 16 cons: SET
+ 17:d=2 hl=2 l= 14 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 7 prim: UTF8STRING :Arizona
+ 33:d=1 hl=2 l= 20 cons: SET
+ 35:d=2 hl=2 l= 18 cons: SEQUENCE
+ 37:d=3 hl=2 l= 3 prim: OBJECT :commonName
+ 42:d=3 hl=2 l= 11 prim: UTF8STRING :192.168.1.1
+-----BEGIN NAME-----
+MDUxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMRQwEgYDVQQDDAsxOTIuMTY4LjEuMQ==
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-arizona-email.pem b/chromium/net/data/name_constraints_unittest/name-us-arizona-email.pem
new file mode 100644
index 00000000000..499e8f7ffe8
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-arizona-email.pem
@@ -0,0 +1,17 @@
+ 0:d=0 hl=2 l= 63 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 16 cons: SET
+ 17:d=2 hl=2 l= 14 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 7 prim: UTF8STRING :Arizona
+ 33:d=1 hl=2 l= 30 cons: SET
+ 35:d=2 hl=2 l= 28 cons: SEQUENCE
+ 37:d=3 hl=2 l= 9 prim: OBJECT :emailAddress
+ 48:d=3 hl=2 l= 15 prim: IA5STRING :bar@example.com
+-----BEGIN NAME-----
+MD8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMR4wHAYJKoZIhvcNAQkBFg9iYXJAZXhh
+bXBsZS5jb20=
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-arizona-foo.com.pem b/chromium/net/data/name_constraints_unittest/name-us-arizona-foo.com.pem
new file mode 100644
index 00000000000..a73ab28269c
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-arizona-foo.com.pem
@@ -0,0 +1,16 @@
+ 0:d=0 hl=2 l= 49 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 16 cons: SET
+ 17:d=2 hl=2 l= 14 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 7 prim: UTF8STRING :Arizona
+ 33:d=1 hl=2 l= 16 cons: SET
+ 35:d=2 hl=2 l= 14 cons: SEQUENCE
+ 37:d=3 hl=2 l= 3 prim: OBJECT :commonName
+ 42:d=3 hl=2 l= 7 prim: UTF8STRING :foo.com
+-----BEGIN NAME-----
+MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMRAwDgYDVQQDDAdmb28uY29t
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-arizona-ipv6.pem b/chromium/net/data/name_constraints_unittest/name-us-arizona-ipv6.pem
new file mode 100644
index 00000000000..73adee9bcab
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-arizona-ipv6.pem
@@ -0,0 +1,17 @@
+ 0:d=0 hl=2 l= 68 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 16 cons: SET
+ 17:d=2 hl=2 l= 14 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 7 prim: UTF8STRING :Arizona
+ 33:d=1 hl=2 l= 35 cons: SET
+ 35:d=2 hl=2 l= 33 cons: SEQUENCE
+ 37:d=3 hl=2 l= 3 prim: OBJECT :commonName
+ 42:d=3 hl=2 l= 26 prim: UTF8STRING :102:304:506:708:90a:b0c::1
+-----BEGIN NAME-----
+MEQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMSMwIQYDVQQDDBoxMDI6MzA0OjUwNjo3
+MDg6OTBhOmIwYzo6MQ==
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-arizona-permitted.example.com.pem b/chromium/net/data/name_constraints_unittest/name-us-arizona-permitted.example.com.pem
new file mode 100644
index 00000000000..f0b71f3f29f
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-arizona-permitted.example.com.pem
@@ -0,0 +1,17 @@
+ 0:d=0 hl=2 l= 63 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 16 cons: SET
+ 17:d=2 hl=2 l= 14 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 7 prim: UTF8STRING :Arizona
+ 33:d=1 hl=2 l= 30 cons: SET
+ 35:d=2 hl=2 l= 28 cons: SEQUENCE
+ 37:d=3 hl=2 l= 3 prim: OBJECT :commonName
+ 42:d=3 hl=2 l= 21 prim: UTF8STRING :permitted.example.com
+-----BEGIN NAME-----
+MD8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMR4wHAYDVQQDDBVwZXJtaXR0ZWQuZXhh
+bXBsZS5jb20=
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-arizona.pem b/chromium/net/data/name_constraints_unittest/name-us-arizona.pem
new file mode 100644
index 00000000000..44e1494acdc
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-arizona.pem
@@ -0,0 +1,12 @@
+ 0:d=0 hl=2 l= 31 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 16 cons: SET
+ 17:d=2 hl=2 l= 14 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 7 prim: UTF8STRING :Arizona
+-----BEGIN NAME-----
+MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25h
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-california-192.168.1.1.pem b/chromium/net/data/name_constraints_unittest/name-us-california-192.168.1.1.pem
new file mode 100644
index 00000000000..54af1cc6d8a
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-california-192.168.1.1.pem
@@ -0,0 +1,17 @@
+ 0:d=0 hl=2 l= 56 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 19 cons: SET
+ 17:d=2 hl=2 l= 17 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 10 prim: UTF8STRING :California
+ 36:d=1 hl=2 l= 20 cons: SET
+ 38:d=2 hl=2 l= 18 cons: SEQUENCE
+ 40:d=3 hl=2 l= 3 prim: OBJECT :commonName
+ 45:d=3 hl=2 l= 11 prim: UTF8STRING :192.168.1.1
+-----BEGIN NAME-----
+MDgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQDDAsxOTIuMTY4LjEu
+MQ==
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-california-mountain_view.pem b/chromium/net/data/name_constraints_unittest/name-us-california-mountain_view.pem
new file mode 100644
index 00000000000..a1d1c91bbdf
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-california-mountain_view.pem
@@ -0,0 +1,17 @@
+ 0:d=0 hl=2 l= 58 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 19 cons: SET
+ 17:d=2 hl=2 l= 17 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 10 prim: UTF8STRING :California
+ 36:d=1 hl=2 l= 22 cons: SET
+ 38:d=2 hl=2 l= 20 cons: SEQUENCE
+ 40:d=3 hl=2 l= 3 prim: OBJECT :localityName
+ 45:d=3 hl=2 l= 13 prim: UTF8STRING :Mountain View
+-----BEGIN NAME-----
+MDoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-california-permitted.example.com.pem b/chromium/net/data/name_constraints_unittest/name-us-california-permitted.example.com.pem
new file mode 100644
index 00000000000..48c28a02830
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-california-permitted.example.com.pem
@@ -0,0 +1,17 @@
+ 0:d=0 hl=2 l= 66 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 19 cons: SET
+ 17:d=2 hl=2 l= 17 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 10 prim: UTF8STRING :California
+ 36:d=1 hl=2 l= 30 cons: SET
+ 38:d=2 hl=2 l= 28 cons: SEQUENCE
+ 40:d=3 hl=2 l= 3 prim: OBJECT :commonName
+ 45:d=3 hl=2 l= 21 prim: UTF8STRING :permitted.example.com
+-----BEGIN NAME-----
+MEIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMR4wHAYDVQQDDBVwZXJtaXR0ZWQu
+ZXhhbXBsZS5jb20=
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us-california.pem b/chromium/net/data/name_constraints_unittest/name-us-california.pem
new file mode 100644
index 00000000000..2ff17e6e069
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us-california.pem
@@ -0,0 +1,12 @@
+ 0:d=0 hl=2 l= 34 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+ 15:d=1 hl=2 l= 19 cons: SET
+ 17:d=2 hl=2 l= 17 cons: SEQUENCE
+ 19:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
+ 24:d=3 hl=2 l= 10 prim: UTF8STRING :California
+-----BEGIN NAME-----
+MCIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/name-us.pem b/chromium/net/data/name_constraints_unittest/name-us.pem
new file mode 100644
index 00000000000..9be8fbcdeb2
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/name-us.pem
@@ -0,0 +1,8 @@
+ 0:d=0 hl=2 l= 13 cons: SEQUENCE
+ 2:d=1 hl=2 l= 11 cons: SET
+ 4:d=2 hl=2 l= 9 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: OBJECT :countryName
+ 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US
+-----BEGIN NAME-----
+MA0xCzAJBgNVBAYTAlVT
+-----END NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/othername-excluded.pem b/chromium/net/data/name_constraints_unittest/othername-excluded.pem
new file mode 100644
index 00000000000..77761f45d28
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/othername-excluded.pem
@@ -0,0 +1,9 @@
+ 0:d=0 hl=2 l= 18 cons: SEQUENCE
+ 2:d=1 hl=2 l= 16 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 14 cons: SEQUENCE
+ 6:d=3 hl=2 l= 12 cons: cont [ 0 ]
+ 8:d=4 hl=2 l= 4 prim: OBJECT :1.2.3.4.5
+ 14:d=4 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:DEADBEEF
+-----BEGIN NAME CONSTRAINTS-----
+MBKhEDAOoAwGBCoDBAUEBN6tvu8=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/othername-permitted.pem b/chromium/net/data/name_constraints_unittest/othername-permitted.pem
new file mode 100644
index 00000000000..e89c6caf373
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/othername-permitted.pem
@@ -0,0 +1,9 @@
+ 0:d=0 hl=2 l= 18 cons: SEQUENCE
+ 2:d=1 hl=2 l= 16 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 14 cons: SEQUENCE
+ 6:d=3 hl=2 l= 12 cons: cont [ 0 ]
+ 8:d=4 hl=2 l= 4 prim: OBJECT :1.2.3.4.5
+ 14:d=4 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:DEADBEEF
+-----BEGIN NAME CONSTRAINTS-----
+MBKgEDAOoAwGBCoDBAUEBN6tvu8=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/registeredid-excluded.pem b/chromium/net/data/name_constraints_unittest/registeredid-excluded.pem
new file mode 100644
index 00000000000..680a723bb35
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/registeredid-excluded.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 9 cons: SEQUENCE
+ 2:d=1 hl=2 l= 7 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 5 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: cont [ 8 ]
+-----BEGIN NAME CONSTRAINTS-----
+MAmhBzAFiAMqAwQ=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/registeredid-permitted.pem b/chromium/net/data/name_constraints_unittest/registeredid-permitted.pem
new file mode 100644
index 00000000000..e1bb2de8c23
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/registeredid-permitted.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 9 cons: SEQUENCE
+ 2:d=1 hl=2 l= 7 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 5 cons: SEQUENCE
+ 6:d=3 hl=2 l= 3 prim: cont [ 8 ]
+-----BEGIN NAME CONSTRAINTS-----
+MAmgBzAFiAMqAwQ=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/rfc822name-excluded.pem b/chromium/net/data/name_constraints_unittest/rfc822name-excluded.pem
new file mode 100644
index 00000000000..a6e706b84b8
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/rfc822name-excluded.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 21 cons: SEQUENCE
+ 2:d=1 hl=2 l= 19 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 17 cons: SEQUENCE
+ 6:d=3 hl=2 l= 15 prim: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MBWhEzARgQ9mb29AZXhhbXBsZS5jb20=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/rfc822name-permitted.pem b/chromium/net/data/name_constraints_unittest/rfc822name-permitted.pem
new file mode 100644
index 00000000000..328ababa5a6
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/rfc822name-permitted.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 21 cons: SEQUENCE
+ 2:d=1 hl=2 l= 19 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 17 cons: SEQUENCE
+ 6:d=3 hl=2 l= 15 prim: cont [ 1 ]
+-----BEGIN NAME CONSTRAINTS-----
+MBWgEzARgQ9mb29AZXhhbXBsZS5jb20=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/san-edipartyname.pem b/chromium/net/data/name_constraints_unittest/san-edipartyname.pem
new file mode 100644
index 00000000000..bf263e58fed
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-edipartyname.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 9 prim: OCTET STRING [HEX DUMP]:3007A5058103666F6F
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BAkwB6UFgQNmb28=
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-excluded-directoryname.pem b/chromium/net/data/name_constraints_unittest/san-excluded-directoryname.pem
new file mode 100644
index 00000000000..3f10f60b8f4
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-excluded-directoryname.pem
@@ -0,0 +1,6 @@
+ 0:d=0 hl=2 l= 124 prim: OCTET STRING [HEX DUMP]:307A82157065726D69747465642E6578616D706C652E636F6D8704C0A80102A41F310B30090603550406130255533110300E06035504080C074172697A6F6E61A43A310B30090603550406130255533113301106035504080C0A43616C69666F726E69613116301406035504070C0D4D6F756E7461696E2056696577
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BHwweoIVcGVybWl0dGVkLmV4YW1wbGUuY29thwTAqAECpB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQI
+DAdBcml6b25hpDoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1N
+b3VudGFpbiBWaWV3
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-excluded-dnsname.pem b/chromium/net/data/name_constraints_unittest/san-excluded-dnsname.pem
new file mode 100644
index 00000000000..834e28a49a3
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-excluded-dnsname.pem
@@ -0,0 +1,6 @@
+ 0:d=0 hl=2 l= 118 prim: OCTET STRING [HEX DUMP]:307482157065726D69747465642E6578616D706C652E636F6D8704C0A80102A41F310B30090603550406130255533110300E06035504080C074172697A6F6E618234666F6F2E7374696C6C6E6F747065726D69747465642E6578636C756465642E7065726D69747465642E6578616D706C652E636F6D
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BHYwdIIVcGVybWl0dGVkLmV4YW1wbGUuY29thwTAqAECpB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQI
+DAdBcml6b25hgjRmb28uc3RpbGxub3RwZXJtaXR0ZWQuZXhjbHVkZWQucGVybWl0dGVkLmV4YW1w
+bGUuY29t
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-excluded-ipaddress.pem b/chromium/net/data/name_constraints_unittest/san-excluded-ipaddress.pem
new file mode 100644
index 00000000000..b4b0f18ee31
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-excluded-ipaddress.pem
@@ -0,0 +1,5 @@
+ 0:d=0 hl=2 l= 70 prim: OCTET STRING [HEX DUMP]:304482157065726D69747465642E6578616D706C652E636F6D8704C0A80102A41F310B30090603550406130255533110300E06035504080C074172697A6F6E618704C0A80505
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BEYwRIIVcGVybWl0dGVkLmV4YW1wbGUuY29thwTAqAECpB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQI
+DAdBcml6b25hhwTAqAUF
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-invalid-empty.pem b/chromium/net/data/name_constraints_unittest/san-invalid-empty.pem
new file mode 100644
index 00000000000..684007ca287
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-invalid-empty.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 2 prim: OCTET STRING [HEX DUMP]:3000
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BAIwAA==
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-invalid-ipaddress.pem b/chromium/net/data/name_constraints_unittest/san-invalid-ipaddress.pem
new file mode 100644
index 00000000000..2a45350c8bc
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-invalid-ipaddress.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 9 prim: OCTET STRING [HEX DUMP]:30078705C0A8000500
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BAkwB4cFwKgABQA=
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-othername.pem b/chromium/net/data/name_constraints_unittest/san-othername.pem
new file mode 100644
index 00000000000..21edf4337df
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-othername.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:300EA00C06042A0304050404DEADBEEF
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BBAwDqAMBgQqAwQFBATerb7v
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-permitted.pem b/chromium/net/data/name_constraints_unittest/san-permitted.pem
new file mode 100644
index 00000000000..fbb26f74857
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-permitted.pem
@@ -0,0 +1,5 @@
+ 0:d=0 hl=2 l= 64 prim: OCTET STRING [HEX DUMP]:303E82157065726D69747465642E6578616D706C652E636F6D8704C0A80102A41F310B30090603550406130255533110300E06035504080C074172697A6F6E61
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BEAwPoIVcGVybWl0dGVkLmV4YW1wbGUuY29thwTAqAECpB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQI
+DAdBcml6b25h
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-registeredid.pem b/chromium/net/data/name_constraints_unittest/san-registeredid.pem
new file mode 100644
index 00000000000..11870ff9eaa
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-registeredid.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 7 prim: OCTET STRING [HEX DUMP]:300588032A0304
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BAcwBYgDKgME
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-rfc822name.pem b/chromium/net/data/name_constraints_unittest/san-rfc822name.pem
new file mode 100644
index 00000000000..5d5f5142e32
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-rfc822name.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 19 prim: OCTET STRING [HEX DUMP]:3011810F666F6F406578616D706C652E636F6D
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BBMwEYEPZm9vQGV4YW1wbGUuY29t
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-uri.pem b/chromium/net/data/name_constraints_unittest/san-uri.pem
new file mode 100644
index 00000000000..5bb31198bd3
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-uri.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 22 prim: OCTET STRING [HEX DUMP]:30148612687474703A2F2F6578616D706C652E636F6D
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BBYwFIYSaHR0cDovL2V4YW1wbGUuY29t
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/san-x400address.pem b/chromium/net/data/name_constraints_unittest/san-x400address.pem
new file mode 100644
index 00000000000..8984b4ae340
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/san-x400address.pem
@@ -0,0 +1,4 @@
+ 0:d=0 hl=2 l= 12 prim: OCTET STRING [HEX DUMP]:300AA3083006610413025553
+-----BEGIN SUBJECT ALTERNATIVE NAME-----
+BAwwCqMIMAZhBBMCVVM=
+-----END SUBJECT ALTERNATIVE NAME-----
diff --git a/chromium/net/data/name_constraints_unittest/uri-excluded.pem b/chromium/net/data/name_constraints_unittest/uri-excluded.pem
new file mode 100644
index 00000000000..1f76b3f2c29
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/uri-excluded.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 24 cons: SEQUENCE
+ 2:d=1 hl=2 l= 22 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 20 cons: SEQUENCE
+ 6:d=3 hl=2 l= 18 prim: cont [ 6 ]
+-----BEGIN NAME CONSTRAINTS-----
+MBihFjAUhhJodHRwOi8vZXhhbXBsZS5jb20=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/uri-permitted.pem b/chromium/net/data/name_constraints_unittest/uri-permitted.pem
new file mode 100644
index 00000000000..8c70ecc3757
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/uri-permitted.pem
@@ -0,0 +1,7 @@
+ 0:d=0 hl=2 l= 24 cons: SEQUENCE
+ 2:d=1 hl=2 l= 22 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 20 cons: SEQUENCE
+ 6:d=3 hl=2 l= 18 prim: cont [ 6 ]
+-----BEGIN NAME CONSTRAINTS-----
+MBigFjAUhhJodHRwOi8vZXhhbXBsZS5jb20=
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/x400address-excluded.pem b/chromium/net/data/name_constraints_unittest/x400address-excluded.pem
new file mode 100644
index 00000000000..4570d489f85
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/x400address-excluded.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 1 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 cons: cont [ 3 ]
+ 8:d=4 hl=2 l= 6 cons: SEQUENCE
+ 10:d=5 hl=2 l= 4 cons: appl [ 1 ]
+ 12:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+-----BEGIN NAME CONSTRAINTS-----
+MA6hDDAKowgwBmEEEwJVUw==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/name_constraints_unittest/x400address-permitted.pem b/chromium/net/data/name_constraints_unittest/x400address-permitted.pem
new file mode 100644
index 00000000000..640bfd9fdbe
--- /dev/null
+++ b/chromium/net/data/name_constraints_unittest/x400address-permitted.pem
@@ -0,0 +1,10 @@
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: cont [ 0 ]
+ 4:d=2 hl=2 l= 10 cons: SEQUENCE
+ 6:d=3 hl=2 l= 8 cons: cont [ 3 ]
+ 8:d=4 hl=2 l= 6 cons: SEQUENCE
+ 10:d=5 hl=2 l= 4 cons: appl [ 1 ]
+ 12:d=6 hl=2 l= 2 prim: PRINTABLESTRING :US
+-----BEGIN NAME CONSTRAINTS-----
+MA6gDDAKowgwBmEEEwJVUw==
+-----END NAME CONSTRAINTS-----
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_false.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_false.pem
new file mode 100644
index 00000000000..9acb44bc95e
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_false.pem
@@ -0,0 +1,7 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 3 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: BOOLEAN :0
+-----BEGIN BASIC CONSTRAINTS-----
+MAMBAQA=
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_no_path.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_no_path.pem
new file mode 100644
index 00000000000..7d25c801ec2
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_no_path.pem
@@ -0,0 +1,7 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 3 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: BOOLEAN :255
+-----BEGIN BASIC CONSTRAINTS-----
+MAMBAf8=
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_path_9.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_path_9.pem
new file mode 100644
index 00000000000..7bb05d22d39
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_ca_path_9.pem
@@ -0,0 +1,8 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 6 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: BOOLEAN :255
+ 5:d=1 hl=2 l= 1 prim: INTEGER :09
+-----BEGIN BASIC CONSTRAINTS-----
+MAYBAf8CAQk=
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_negative_path.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_negative_path.pem
new file mode 100644
index 00000000000..cc2ef3bd0e4
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_negative_path.pem
@@ -0,0 +1,8 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 6 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: BOOLEAN :255
+ 5:d=1 hl=2 l= 1 prim: INTEGER :-01
+-----BEGIN BASIC CONSTRAINTS-----
+MAYBAf8CAf8=
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_not_ca.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_not_ca.pem
new file mode 100644
index 00000000000..15ad41622e8
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_not_ca.pem
@@ -0,0 +1,6 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 0 cons: SEQUENCE
+-----BEGIN BASIC CONSTRAINTS-----
+MAA=
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_path_too_large.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_path_too_large.pem
new file mode 100644
index 00000000000..dd986d1a078
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_path_too_large.pem
@@ -0,0 +1,8 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 29 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: BOOLEAN :255
+ 5:d=1 hl=2 l= 24 prim: INTEGER :0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+-----BEGIN BASIC CONSTRAINTS-----
+MB0BAf8CGA///////////////////////////////w==
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_255.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_255.pem
new file mode 100644
index 00000000000..b97e27415da
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_255.pem
@@ -0,0 +1,8 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 7 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: BOOLEAN :255
+ 5:d=1 hl=2 l= 2 prim: INTEGER :FF
+-----BEGIN BASIC CONSTRAINTS-----
+MAcBAf8CAgD/
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_256.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_256.pem
new file mode 100644
index 00000000000..23c21012d90
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_256.pem
@@ -0,0 +1,8 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 7 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: BOOLEAN :255
+ 5:d=1 hl=2 l= 2 prim: INTEGER :0100
+-----BEGIN BASIC CONSTRAINTS-----
+MAcBAf8CAgEA
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_not_ca.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_not_ca.pem
new file mode 100644
index 00000000000..f462f1c540d
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_pathlen_not_ca.pem
@@ -0,0 +1,7 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 3 cons: SEQUENCE
+ 2:d=1 hl=2 l= 1 prim: INTEGER :01
+-----BEGIN BASIC CONSTRAINTS-----
+MAMCAQE=
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/basic_constraints_unconsumed_data.pem b/chromium/net/data/parse_certificate_unittest/basic_constraints_unconsumed_data.pem
new file mode 100644
index 00000000000..b31bb5875dd
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/basic_constraints_unconsumed_data.pem
@@ -0,0 +1,7 @@
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 2 cons: SEQUENCE
+ 2:d=1 hl=2 l= 0 prim: NULL
+-----BEGIN BASIC CONSTRAINTS-----
+MAIFAA==
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extension_critical.pem b/chromium/net/data/parse_certificate_unittest/extension_critical.pem
new file mode 100644
index 00000000000..fb105bcee58
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extension_critical.pem
@@ -0,0 +1,12 @@
+This is a basic constraints extension, which is marked as critical.
+
+
+$ openssl asn1parse -i < [EXTENSION]
+ 0:d=0 hl=2 l= 12 cons: SEQUENCE
+ 2:d=1 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints
+ 7:d=1 hl=2 l= 1 prim: BOOLEAN :255
+ 10:d=1 hl=2 l= 2 prim: OCTET STRING [HEX DUMP]:3000
+
+-----BEGIN EXTENSION-----
+MAwGA1UdEwEB/wQCMAA=
+-----END EXTENSION-----
diff --git a/chromium/net/data/parse_certificate_unittest/extension_critical_0.pem b/chromium/net/data/parse_certificate_unittest/extension_critical_0.pem
new file mode 100644
index 00000000000..a057ac54682
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extension_critical_0.pem
@@ -0,0 +1,15 @@
+This is a basic constraints extension, where the critical field (BOOLEAN) is 0.
+
+This is not valid because the critical field has a default of FALSE, so under
+DER-encoding it should be omitted.
+
+
+$ openssl asn1parse -i < [EXTENSION]
+ 0:d=0 hl=2 l= 12 cons: SEQUENCE
+ 2:d=1 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints
+ 7:d=1 hl=2 l= 1 prim: BOOLEAN :0
+ 10:d=1 hl=2 l= 2 prim: OCTET STRING [HEX DUMP]:3000
+
+-----BEGIN EXTENSION-----
+MAwGA1UdEwEBAAQCMAA=
+-----END EXTENSION-----
diff --git a/chromium/net/data/parse_certificate_unittest/extension_critical_3.pem b/chromium/net/data/parse_certificate_unittest/extension_critical_3.pem
new file mode 100644
index 00000000000..435c8432f6a
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extension_critical_3.pem
@@ -0,0 +1,15 @@
+This is a basic constraints extension, where the critical field (BOOLEAN) is 3.
+
+This is not valid because BOOLEANs in DER-encoding should use an octet of
+either all 0 bits or all 1 bits.
+
+
+$ openssl asn1parse -i < [EXTENSION]
+ 0:d=0 hl=2 l= 12 cons: SEQUENCE
+ 2:d=1 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints
+ 7:d=1 hl=2 l= 1 prim: BOOLEAN :3
+ 10:d=1 hl=2 l= 2 prim: OCTET STRING [HEX DUMP]:3000
+
+-----BEGIN EXTENSION-----
+MAwGA1UdEwEBAwQCMAA=
+-----END EXTENSION-----
diff --git a/chromium/net/data/parse_certificate_unittest/extension_not_critical.pem b/chromium/net/data/parse_certificate_unittest/extension_not_critical.pem
new file mode 100644
index 00000000000..0c845353a4f
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extension_not_critical.pem
@@ -0,0 +1,12 @@
+This is a modified basic constraints extension, where the critical field was
+removed (in other words, FALSE).
+
+
+$ openssl asn1parse -i < [EXTENSION]
+ 0:d=0 hl=2 l= 9 cons: SEQUENCE
+ 2:d=1 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints
+ 7:d=1 hl=2 l= 2 prim: OCTET STRING [HEX DUMP]:3000
+
+-----BEGIN EXTENSION-----
+MAkGA1UdEwQCMAA=
+-----END EXTENSION-----
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_basic_constraints.pem b/chromium/net/data/parse_certificate_unittest/extensions_basic_constraints.pem
new file mode 100644
index 00000000000..211cef081d8
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_basic_constraints.pem
@@ -0,0 +1,16 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 14 cons: SEQUENCE
+ 2:d=1 hl=2 l= 12 cons: SEQUENCE
+ 4:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints
+ 9:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 12:d=2 hl=2 l= 2 prim: OCTET STRING [HEX DUMP]:3000
+-----BEGIN EXTENSIONS-----
+MA4wDAYDVR0TAQH/BAIwAA==
+-----END EXTENSIONS-----
+
+$ openssl asn1parse -i < [BASIC CONSTRAINTS]
+ 0:d=0 hl=2 l= 0 cons: SEQUENCE
+-----BEGIN BASIC CONSTRAINTS-----
+MAA=
+-----END BASIC CONSTRAINTS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_data_after_sequence.pem b/chromium/net/data/parse_certificate_unittest/extensions_data_after_sequence.pem
new file mode 100644
index 00000000000..5bf26acb5c7
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_data_after_sequence.pem
@@ -0,0 +1,11 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 18 cons: SEQUENCE
+ 2:d=1 hl=2 l= 14 cons: SEQUENCE
+ 4:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage
+ 9:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 12:d=2 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:030203B8
+ 18:d=1 hl=2 l= 0 prim: NULL
+-----BEGIN EXTENSIONS-----
+MBIwDgYDVR0PAQH/BAQDAgO4BQA=
+-----END EXTENSIONS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_duplicate_key_usage.pem b/chromium/net/data/parse_certificate_unittest/extensions_duplicate_key_usage.pem
new file mode 100644
index 00000000000..c2633848a7a
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_duplicate_key_usage.pem
@@ -0,0 +1,14 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 32 cons: SEQUENCE
+ 2:d=1 hl=2 l= 14 cons: SEQUENCE
+ 4:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage
+ 9:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 12:d=2 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:030203B8
+ 18:d=1 hl=2 l= 14 cons: SEQUENCE
+ 20:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage
+ 25:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 28:d=2 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:030203B8
+-----BEGIN EXTENSIONS-----
+MCAwDgYDVR0PAQH/BAQDAgO4MA4GA1UdDwEB/wQEAwIDuA==
+-----END EXTENSIONS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_empty_sequence.pem b/chromium/net/data/parse_certificate_unittest/extensions_empty_sequence.pem
new file mode 100644
index 00000000000..d3f1a73dd0b
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_empty_sequence.pem
@@ -0,0 +1,6 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 0 cons: SEQUENCE
+-----BEGIN EXTENSIONS-----
+MAA=
+-----END EXTENSIONS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_extended_key_usage.pem b/chromium/net/data/parse_certificate_unittest/extensions_extended_key_usage.pem
new file mode 100644
index 00000000000..9cda6e21e23
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_extended_key_usage.pem
@@ -0,0 +1,20 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 54 cons: SEQUENCE
+ 2:d=1 hl=2 l= 52 cons: SEQUENCE
+ 4:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Extended Key Usage
+ 9:d=2 hl=2 l= 45 prim: OCTET STRING [HEX DUMP]:302B06082B0601050507030106082B06010505070302060A2B0601040182370A030306096086480186F8420401
+-----BEGIN EXTENSIONS-----
+MDYwNAYDVR0lBC0wKwYIKwYBBQUHAwEGCCsGAQUFBwMCBgorBgEEAYI3CgMDBglghkgBhvhCBAE
+=
+-----END EXTENSIONS-----
+
+$ openssl asn1parse -i < [EXTENDED KEY USAGE]
+ 0:d=0 hl=2 l= 43 cons: SEQUENCE
+ 2:d=1 hl=2 l= 8 prim: OBJECT :TLS Web Server Authentication
+ 12:d=1 hl=2 l= 8 prim: OBJECT :TLS Web Client Authentication
+ 22:d=1 hl=2 l= 10 prim: OBJECT :Microsoft Server Gated Crypto
+ 34:d=1 hl=2 l= 9 prim: OBJECT :Netscape Server Gated Crypto
+-----BEGIN EXTENDED KEY USAGE-----
+MCsGCCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQB
+-----END EXTENDED KEY USAGE-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_key_usage.pem b/chromium/net/data/parse_certificate_unittest/extensions_key_usage.pem
new file mode 100644
index 00000000000..1b56edd0a33
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_key_usage.pem
@@ -0,0 +1,16 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 16 cons: SEQUENCE
+ 2:d=1 hl=2 l= 14 cons: SEQUENCE
+ 4:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage
+ 9:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 12:d=2 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:030205A0
+-----BEGIN EXTENSIONS-----
+MBAwDgYDVR0PAQH/BAQDAgWg
+-----END EXTENSIONS-----
+
+$ openssl asn1parse -i < [KEY USAGE]
+ 0:d=0 hl=2 l= 2 prim: BIT STRING
+-----BEGIN KEY USAGE-----
+AwIFoA==
+-----END KEY USAGE-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_not_sequence.pem b/chromium/net/data/parse_certificate_unittest/extensions_not_sequence.pem
new file mode 100644
index 00000000000..f8cb11b7f32
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_not_sequence.pem
@@ -0,0 +1,6 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 0 prim: NULL
+-----BEGIN EXTENSIONS-----
+BQA=
+-----END EXTENSIONS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_policies.pem b/chromium/net/data/parse_certificate_unittest/extensions_policies.pem
new file mode 100644
index 00000000000..79a1c90aa00
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_policies.pem
@@ -0,0 +1,25 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 104 cons: SEQUENCE
+ 2:d=1 hl=2 l= 102 cons: SEQUENCE
+ 4:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Certificate Policies
+ 9:d=2 hl=2 l= 95 prim: OCTET STRING [HEX DUMP]:305D304D060A2A83088C9C1E01020201303F303D06082B06010505070201163168747470733A2F2F7265706F312E7365636F6D74727573742E6E65742F73706370702F6370732F696E6465782E68746D6C300C060A2A83088C9B1B64870501
+-----BEGIN EXTENSIONS-----
+MGgwZgYDVR0gBF8wXTBNBgoqgwiMnB4BAgIBMD8wPQYIKwYBBQUHAgEWMWh0dHBzOi8vcmVwbzE
+uc2Vjb210cnVzdC5uZXQvc3BjcHAvY3BzL2luZGV4Lmh0bWwwDAYKKoMIjJsbZIcFAQ==
+-----END EXTENSIONS-----
+
+$ openssl asn1parse -i < [POLICIES]
+ 0:d=0 hl=2 l= 93 cons: SEQUENCE
+ 2:d=1 hl=2 l= 77 cons: SEQUENCE
+ 4:d=2 hl=2 l= 10 prim: OBJECT :1.2.392.200222.1.2.2.1
+ 16:d=2 hl=2 l= 63 cons: SEQUENCE
+ 18:d=3 hl=2 l= 61 cons: SEQUENCE
+ 20:d=4 hl=2 l= 8 prim: OBJECT :Policy Qualifier CPS
+ 30:d=4 hl=2 l= 49 prim: IA5STRING :https://repo1.secomtrust.net/spcpp/cps/index.html
+ 81:d=1 hl=2 l= 12 cons: SEQUENCE
+ 83:d=2 hl=2 l= 10 prim: OBJECT :1.2.392.200091.100.901.1
+-----BEGIN POLICIES-----
+MF0wTQYKKoMIjJweAQICATA/MD0GCCsGAQUFBwIBFjFodHRwczovL3JlcG8xLnNlY29tdHJ1c3Q
+ubmV0L3NwY3BwL2Nwcy9pbmRleC5odG1sMAwGCiqDCIybG2SHBQE=
+-----END POLICIES-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_real.pem b/chromium/net/data/parse_certificate_unittest/extensions_real.pem
new file mode 100644
index 00000000000..5ece71c420a
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_real.pem
@@ -0,0 +1,35 @@
+A real world extensions sequence (taken from Google's GAI2).
+
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=3 l= 228 cons: SEQUENCE
+ 3:d=1 hl=2 l= 31 cons: SEQUENCE
+ 5:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Authority Key Identifier
+ 10:d=2 hl=2 l= 24 prim: OCTET STRING [HEX DUMP]:30168014C07A98688D89FBAB05640C117DAA7D65B8CACC4E
+ 36:d=1 hl=2 l= 29 cons: SEQUENCE
+ 38:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Subject Key Identifier
+ 43:d=2 hl=2 l= 22 prim: OCTET STRING [HEX DUMP]:04144ADD06161BBCF668B576F581B6BB621ABA5A812F
+ 67:d=1 hl=2 l= 14 cons: SEQUENCE
+ 69:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage
+ 74:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 77:d=2 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:03020106
+ 83:d=1 hl=2 l= 46 cons: SEQUENCE
+ 85:d=2 hl=2 l= 8 prim: OBJECT :Authority Information Access
+ 95:d=2 hl=2 l= 34 prim: OCTET STRING [HEX DUMP]:3020301E06082B060105050730018612687474703A2F2F672E73796D63642E636F6D
+ 131:d=1 hl=2 l= 18 cons: SEQUENCE
+ 133:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints
+ 138:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 141:d=2 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:30060101FF020100
+ 151:d=1 hl=2 l= 53 cons: SEQUENCE
+ 153:d=2 hl=2 l= 3 prim: OBJECT :X509v3 CRL Distribution Points
+ 158:d=2 hl=2 l= 46 prim: OCTET STRING [HEX DUMP]:302C302AA028A0268624687474703A2F2F672E73796D63622E636F6D2F63726C732F6774676C6F62616C2E63726C
+ 206:d=1 hl=2 l= 23 cons: SEQUENCE
+ 208:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Certificate Policies
+ 213:d=2 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:300E300C060A2B06010401D679020501
+-----BEGIN EXTENSIONS-----
+MIHkMB8GA1UdIwQYMBaAFMB6mGiNifurBWQMEX2qfWW4ysxOMB0GA1UdDgQWBBRK3QYWG7z2aLV
+29YG2u2IaulqBLzAOBgNVHQ8BAf8EBAMCAQYwLgYIKwYBBQUHAQEEIjAgMB4GCCsGAQUFBzABhh
+JodHRwOi8vZy5zeW1jZC5jb20wEgYDVR0TAQH/BAgwBgEB/wIBADA1BgNVHR8ELjAsMCqgKKAmh
+iRodHRwOi8vZy5zeW1jYi5jb20vY3Jscy9ndGdsb2JhbC5jcmwwFwYDVR0gBBAwDjAMBgorBgEE
+AdZ5AgUB
+-----END EXTENSIONS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_subject_alt_name.pem b/chromium/net/data/parse_certificate_unittest/extensions_subject_alt_name.pem
new file mode 100644
index 00000000000..3ce5fdad035
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_subject_alt_name.pem
@@ -0,0 +1,16 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 32 cons: SEQUENCE
+ 2:d=1 hl=2 l= 30 cons: SEQUENCE
+ 4:d=2 hl=2 l= 3 prim: OBJECT :X509v3 Subject Alternative Name
+ 9:d=2 hl=2 l= 23 prim: OCTET STRING [HEX DUMP]:30158213656D657267656E6379737570706F72742E7573
+-----BEGIN EXTENSIONS-----
+MCAwHgYDVR0RBBcwFYITZW1lcmdlbmN5c3VwcG9ydC51cw==
+-----END EXTENSIONS-----
+
+$ openssl asn1parse -i < [SUBJECT ALT NAME]
+ 0:d=0 hl=2 l= 21 cons: SEQUENCE
+ 2:d=1 hl=2 l= 19 prim: cont [ 2 ]
+-----BEGIN SUBJECT ALT NAME-----
+MBWCE2VtZXJnZW5jeXN1cHBvcnQudXM=
+-----END SUBJECT ALT NAME-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_unknown_critical.pem b/chromium/net/data/parse_certificate_unittest/extensions_unknown_critical.pem
new file mode 100644
index 00000000000..3913615c74b
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_unknown_critical.pem
@@ -0,0 +1,10 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 25 cons: SEQUENCE
+ 2:d=1 hl=2 l= 23 cons: SEQUENCE
+ 4:d=2 hl=2 l= 12 prim: OBJECT :1.2.840.113554.4.1.72585.0
+ 18:d=2 hl=2 l= 1 prim: BOOLEAN :255
+ 21:d=2 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:030203B8
+-----BEGIN EXTENSIONS-----
+MBkwFwYMKoZIhvcSBAGEtwkAAQH/BAQDAgO4
+-----END EXTENSIONS-----
+
diff --git a/chromium/net/data/parse_certificate_unittest/extensions_unknown_non_critical.pem b/chromium/net/data/parse_certificate_unittest/extensions_unknown_non_critical.pem
new file mode 100644
index 00000000000..532cb2ab22a
--- /dev/null
+++ b/chromium/net/data/parse_certificate_unittest/extensions_unknown_non_critical.pem
@@ -0,0 +1,9 @@
+$ openssl asn1parse -i < [EXTENSIONS]
+ 0:d=0 hl=2 l= 22 cons: SEQUENCE
+ 2:d=1 hl=2 l= 20 cons: SEQUENCE
+ 4:d=2 hl=2 l= 12 prim: OBJECT :1.2.840.113554.4.1.72585.0
+ 18:d=2 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:030203B8
+-----BEGIN EXTENSIONS-----
+MBYwFAYMKoZIhvcSBAGEtwkABAQDAgO4
+-----END EXTENSIONS-----
+
diff --git a/chromium/net/data/ssl/certificates/README b/chromium/net/data/ssl/certificates/README
index 6eed2be42e8..493283e16cf 100644
--- a/chromium/net/data/ssl/certificates/README
+++ b/chromium/net/data/ssl/certificates/README
@@ -136,6 +136,10 @@ unit tests.
These certificates are the common certificates used by the Python test
server for simulating HTTPS connections.
+- wildcard_.pem
+ A certificate and private key valid for *.example.org, used in various
+ net unit tests.
+
- name_constraint_bad.pem
- name_constraint_good.pem
Two certificates used to test the built-in ability to restrict a root to
@@ -158,6 +162,10 @@ unit tests.
- sha1_2016.pem
Used to test the handling of SHA1 certificates expiring in 2016.
+- sha1_dec_2015.pem
+- sha1_jan_2016.pem
+ Used to test enforcement of the Baseline Requirements' policies on SHA-1.
+
- 10_year_validity.pem
- 11_year_validity.pem
- 39_months_after_2015_04.pem
diff --git a/chromium/net/data/ssl/certificates/large_key.pem b/chromium/net/data/ssl/certificates/large_key.pem
index 8ccb287b6b9..fe8a1d687f9 100644
--- a/chromium/net/data/ssl/certificates/large_key.pem
+++ b/chromium/net/data/ssl/certificates/large_key.pem
@@ -1,112 +1,194 @@
Certificate:
Data:
Version: 1 (0x0)
- Serial Number:
- fa:ba:a5:10:ef:85:bb:70
- Signature Algorithm: sha256WithRSAEncryption
+ Serial Number: 10746871423479549511 (0x95248e9ecb4b8e47)
+ Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
Validity
- Not Before: Apr 23 21:32:21 2015 GMT
- Not After : Apr 20 21:32:21 2025 GMT
+ Not Before: Dec 2 20:57:39 2015 GMT
+ Not After : Nov 29 20:57:39 2025 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
- RSA Public Key: (4104 bit)
- Modulus (4104 bit):
- 00:c9:98:35:7d:a5:d4:41:1b:83:60:84:76:14:c2:
- 0d:a6:7f:e7:52:15:a5:7c:96:96:56:b8:98:f9:bc:
- 94:56:23:14:f2:74:05:e6:ba:d9:3a:58:dd:b5:03:
- 9c:d1:f5:47:76:c2:45:78:f9:b8:e1:44:40:45:08:
- 2d:d1:ff:c3:bf:d7:b2:4a:94:6a:61:37:dd:cb:66:
- 22:28:8d:cc:5f:35:dd:9a:1a:d5:0e:cc:36:76:ae:
- 65:a2:96:d3:cd:de:8d:b4:c9:28:a8:a8:2d:45:89:
- 98:aa:7d:9e:12:7b:e1:a5:ba:d9:56:8a:4a:1f:1c:
- 7d:e2:cf:f5:f0:54:38:6d:47:4c:1d:1c:22:3c:74:
- 72:4b:fd:c2:97:66:b1:9c:8e:c3:d6:88:5e:6a:ed:
- c9:fe:b7:d9:ef:03:25:5d:da:4a:ab:5e:fa:f4:a8:
- 87:30:90:00:85:a6:5b:40:77:b6:34:64:63:58:05:
- cd:1e:58:d6:fd:b2:13:51:ba:a4:9f:7f:e3:db:88:
- 88:58:1f:df:5f:67:cc:49:0a:bb:e0:ce:d9:3f:ce:
- 26:20:1e:35:f3:f0:8a:bd:8b:8b:4f:16:80:53:4e:
- 44:3b:1a:9e:60:6b:ff:cf:f7:9f:40:bf:d2:86:e4:
- 79:39:3a:d7:5a:bd:d0:63:cf:f6:54:e1:9e:09:e7:
- 63:8a:17:33:bf:f2:5f:ec:ee:45:18:52:ee:e7:23:
- a2:a8:af:d2:85:4b:bb:f9:12:ba:35:22:d2:5e:9c:
- 42:2d:66:e1:01:02:d4:0f:ff:86:1c:91:8f:55:9c:
- 9f:24:4e:17:c8:23:c1:a7:4e:39:ed:4b:dc:b8:c4:
- 3f:7d:c9:0f:ff:01:40:4d:dd:9a:55:29:84:f8:52:
- 72:da:38:32:9a:ef:2b:2e:67:5b:d2:2d:70:46:91:
- 42:79:22:a2:08:c0:fd:24:95:9e:04:a6:5c:9e:c0:
- ed:25:2a:57:62:17:b7:c0:12:d4:8b:59:f3:db:8b:
- cd:95:4f:d9:32:f2:f0:e1:14:9b:db:73:e7:b4:97:
- a6:90:f7:0d:cb:59:93:94:12:2a:c1:28:7d:3c:bd:
- b5:7e:bb:13:c0:4c:ef:ce:20:3d:3b:4f:84:25:77:
- dc:1f:0f:08:dd:76:9c:ad:7d:00:2f:23:42:6a:37:
- e9:d0:6b:8e:9a:6f:3b:46:09:74:23:43:a9:58:46:
- 62:33:69:2a:0c:df:cd:6c:75:88:f1:01:3d:67:e0:
- a8:e3:bd:23:03:66:f3:11:f2:07:a8:bf:4b:c9:81:
- ce:a9:ed:8d:48:a6:10:15:fb:79:27:ae:2e:8f:35:
- c5:39:12:eb:f2:b7:28:d3:b3:e7:4c:71:d8:e1:d1:
- f7:39:94:87
+ Public-Key: (8200 bit)
+ Modulus:
+ 00:df:c1:08:64:7a:31:df:14:95:3f:cd:6d:83:9c:
+ 3f:9d:f6:31:ce:29:40:76:5b:4f:9c:f2:5f:a5:bf:
+ d4:82:eb:67:1d:1a:18:c5:43:53:b6:9c:19:de:87:
+ da:53:fe:11:e8:cd:49:b6:5c:98:68:dc:ae:b2:3e:
+ 86:03:8a:a5:eb:a5:95:1a:01:b6:b7:67:84:5a:07:
+ cd:90:06:69:52:db:10:b8:73:f6:0f:e2:43:28:4b:
+ 5f:42:75:c9:78:65:bb:2d:4b:b9:e9:97:09:be:1f:
+ 49:5e:57:86:c7:3f:fb:eb:18:90:57:7e:86:c0:e1:
+ 77:ec:67:6e:27:eb:f7:80:7a:e6:b1:dd:78:c9:f2:
+ ef:1b:10:3e:e2:6f:89:8b:56:8d:69:d7:f0:1b:1e:
+ 35:d6:41:c6:1a:80:1f:15:be:0e:ae:c9:87:df:e8:
+ 80:a2:85:20:de:32:3a:f8:cc:12:72:eb:41:1e:2b:
+ 2a:29:3f:f7:e1:eb:29:99:ad:b4:8d:79:0a:99:8e:
+ 0f:4a:1f:44:e9:74:b7:17:cb:97:21:7a:7d:d5:6c:
+ a5:fd:d1:53:b5:21:8c:0a:53:4d:0a:e9:4d:40:52:
+ 0b:35:5f:40:09:09:1f:6d:b6:04:9c:75:f2:ee:32:
+ 89:d8:ff:a3:5b:37:93:69:f0:25:4c:ec:2a:a7:1e:
+ e2:29:33:ef:07:f4:61:8c:91:a9:bb:f9:89:ba:b2:
+ dd:98:08:91:bf:77:f6:bb:3b:f7:8a:f7:1c:d7:6b:
+ 17:d3:fa:62:12:2e:bb:d3:bf:78:a3:eb:1e:cb:00:
+ 70:6e:87:3f:9e:eb:fd:2d:32:77:f2:31:af:5c:dc:
+ 15:a7:2c:d9:ae:e7:fb:f8:01:4a:c9:45:f3:87:dc:
+ c7:cc:14:fe:7f:7d:46:94:08:ac:25:6a:18:02:49:
+ b5:aa:bd:4f:c5:1a:04:b8:ac:a1:6a:54:01:19:05:
+ f4:55:e0:08:98:67:f5:ec:61:09:ec:fc:81:9b:88:
+ 77:53:7a:d1:48:4c:8f:e2:b7:0d:06:04:bc:05:6e:
+ 0f:0a:a1:56:07:b1:13:41:90:49:fd:12:70:f6:01:
+ 57:ad:d6:2d:a2:a1:04:cf:d1:29:38:f5:68:76:58:
+ 9b:5d:1e:0f:2c:77:f6:f0:cf:d8:df:c5:d2:23:8b:
+ 34:a9:ae:94:67:74:4b:21:99:7c:bb:de:be:f9:5c:
+ b6:eb:14:2d:bb:38:56:fb:0c:7c:70:42:42:1b:1b:
+ 3c:98:6d:61:1f:16:32:ce:73:2a:23:9e:eb:e6:d1:
+ 89:0d:30:07:d2:94:09:8c:6d:38:49:e6:07:fd:bd:
+ 23:48:47:6c:ca:c0:da:50:e8:5f:06:08:72:e1:ca:
+ fd:91:fc:29:fc:26:40:ff:1d:78:16:23:1f:c2:64:
+ 41:04:b6:3c:40:b7:08:27:a6:7d:26:4a:fd:57:af:
+ ee:ba:e3:93:45:07:64:5c:5f:c0:a7:e8:a2:5b:a7:
+ 3d:da:d3:97:1f:7c:da:77:00:0d:30:3e:e3:ae:fd:
+ 4c:c7:18:e6:62:e0:9d:74:0f:90:00:aa:c2:32:de:
+ dc:d1:8f:d7:c3:c2:08:bf:d1:bd:7e:21:09:79:32:
+ 8f:1a:12:43:97:91:41:33:bd:d4:2e:3b:a9:6d:06:
+ 23:d1:da:7e:5f:45:27:d5:17:9c:0e:df:2c:d1:66:
+ cb:ed:ec:e3:c3:6b:ab:0d:ba:71:04:a4:92:a4:71:
+ 55:69:20:35:72:fd:ad:54:a8:cf:44:c3:9d:a1:5a:
+ 94:4d:05:62:5e:98:d6:25:c5:d6:cf:f5:ef:94:c0:
+ 2c:53:87:0b:9f:13:0f:63:c5:97:d5:5b:8a:46:7c:
+ 0e:28:de:66:96:74:df:2a:b2:b0:27:6d:4c:4f:54:
+ 72:d9:2d:ae:58:4f:d3:63:63:93:c2:34:57:66:3b:
+ 38:90:36:a9:a9:95:e6:7d:e8:84:87:68:73:9b:44:
+ 68:d9:69:1f:1c:1b:9d:58:44:77:72:e8:28:c1:1a:
+ 11:bd:5c:40:b7:d0:58:b9:58:91:9f:5b:30:94:33:
+ fa:f6:be:2a:59:8b:43:cc:e3:04:45:1b:43:7e:d7:
+ b5:f4:d3:dc:5d:65:ae:6b:d1:92:d2:f7:b6:8f:df:
+ c6:5c:00:c3:0b:37:28:33:33:dd:05:cb:3c:62:0d:
+ 0b:54:42:ea:9f:6c:e9:f2:ef:c7:ab:7c:5c:cf:18:
+ 55:35:1c:f7:72:8f:c3:d5:1b:c0:09:6f:44:e8:06:
+ 62:44:c4:0b:10:e2:c3:b1:9c:de:73:37:5d:51:bc:
+ b6:3f:38:1b:75:d9:26:df:4f:1a:eb:63:9c:e1:49:
+ 11:e4:cb:ec:e3:3a:b1:e2:00:8b:92:bb:73:fb:05:
+ 78:81:e7:ac:21:1b:23:c1:8f:8b:9c:52:bb:09:da:
+ 72:23:bf:81:e6:74:18:63:1f:84:9b:5d:06:92:72:
+ aa:84:50:f4:8f:2a:94:05:8f:42:5f:de:45:05:b2:
+ be:26:3d:dc:c4:ef:83:cb:aa:b4:67:2f:5c:e2:f9:
+ b3:9c:1f:f9:92:8f:40:4f:99:df:9a:5e:fd:c5:db:
+ 92:dc:a8:41:13:64:f4:bb:0a:65:87:dc:cf:39:30:
+ be:9e:3a:86:62:d6:2e:6f:17:8a:d9:77:3a:e2:8d:
+ 8f:08:eb:1e:fd:af:67:22:1d:ff:ff:b8:22:2b:93:
+ 51:1d:12:c7:6b:85:4d:b7:18:96:64:e2:25:06:ec:
+ 45:67:63:2b:b1:23
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
- 2d:3b:5f:58:30:58:97:65:d0:36:a6:03:0c:6b:bc:a6:5b:e7:
- 8f:a3:a7:05:5d:db:9b:3f:0e:22:89:3e:e1:00:91:3c:17:ab:
- 10:10:80:f5:d1:f9:cb:d7:38:9e:bc:36:a0:31:d2:e3:2f:98:
- 62:d8:a2:cd:73:7c:56:29:b0:c0:41:01:71:50:70:7a:b2:9d:
- b6:ad:13:71:d8:19:7d:4f:7a:be:4b:36:2e:d7:f7:81:53:a7:
- e0:7f:04:77:09:84:a3:56:22:48:7e:6d:ca:20:12:ed:a7:da:
- 29:cf:46:46:81:8f:97:4b:17:63:25:f2:18:48:c1:82:21:c7:
- be:4f:54:29:88:29:78:d0:be:98:9c:d9:4f:76:e7:6b:a2:10:
- 4a:ce:45:02:c7:5e:5a:ac:5f:0e:4b:a3:51:a9:ec:7a:3f:a0:
- 51:49:75:bc:af:f4:89:88:35:69:65:15:a5:33:c5:2f:1e:c5:
- 30:98:6b:04:14:b9:29:b5:31:76:23:88:32:72:29:e4:16:de:
- bb:95:d6:bb:48:e5:38:37:57:6e:8a:2f:c0:64:2c:01:4d:e6:
- 69:9e:ae:4a:39:87:96:5d:50:e6:25:08:46:77:ea:da:4d:b2:
- bd:5e:44:ca:e2:46:b1:7a:4a:3d:83:16:a9:a6:e5:c4:ef:fc:
- af:77:58:6e:3b:cd:b3:b3:0e:d2:59:d2:be:16:ac:64:fa:f7:
- b1:06:02:7d:c9:8a:06:65:73:da:d8:a8:02:41:d5:68:41:7a:
- 0f:a7:5c:90:b3:6f:01:66:65:96:4c:50:bd:c7:38:67:61:21:
- 52:dc:a9:f0:f7:0b:16:95:2d:5d:b8:0b:da:9a:fe:f8:4c:e9:
- fa:6a:32:a7:d4:67:7b:21:45:7a:4e:7c:a6:fa:cb:65:3d:8f:
- 38:90:5a:29:7d:7f:21:32:6d:c6:61:70:f9:a8:4e:3f:9b:3c:
- f0:4b:40:d6:7d:e5:d6:31:08:ff:29:21:f9:e7:81:36:1a:86:
- d5:96:06:1d:1e:b1:fc:4c:e3:6d:ce:3a:2c:16:b8:03:76:f3:
- 70:77:15:ea:b5:32:c3:f5:9f:a6:61:e1:29:bb:88:2c:a0:cf:
- 05:f5:3d:97:ae:b5:b9:01:e8:2f:5e:54:17:2e:09:5b:ea:d0:
- 4a:95:65:d9:cf:83:3a:bc:1d:7d:28:4b:7b:8d:5c:ef:8a:06:
- f9:64:b5:ec:3f:73:fc:6c:58:cc:57:da:d3:5d:5e:b5:58:43:
- 53:27:f0:49:01:e4:45:8d:eb:68:f3:40:fc:ec:63:62:ce:c3:
- d9:97:d3:a3:51:8c:c5:09:a9:81:6e:23:e0:6a:1f:02:b0:f8:
- b0:40:0c:2f:ea:ee:c2:1f:1b
+ ba:7f:75:5f:5f:e6:a9:7a:b2:53:a8:d4:02:60:21:29:ce:a5:
+ e3:95:8a:eb:22:d0:54:f3:76:1b:22:a4:bd:2b:fe:a0:0e:f4:
+ 46:8a:c4:b4:ee:58:ca:c0:dc:7a:1c:26:30:99:85:ed:e5:ae:
+ 3a:23:81:76:5b:b4:e8:50:33:6f:19:52:a6:03:82:c7:13:ce:
+ 4f:97:af:d7:42:6e:28:0f:f2:cf:e6:eb:f9:e9:65:40:2e:92:
+ 44:87:ac:f7:a3:65:84:a6:46:1e:c6:3c:23:9a:98:13:d8:f3:
+ ce:a0:20:06:d3:6a:ec:db:3f:d7:92:5c:01:a7:e1:c1:d9:ba:
+ 6f:1b:41:0f:ff:6d:80:dd:df:69:1b:45:36:f1:e4:1d:72:96:
+ 57:3d:8a:80:e3:ae:b4:91:8e:88:40:48:e6:33:0d:e7:ad:3f:
+ aa:d3:c1:96:f2:44:73:bb:51:56:ce:75:b5:e9:2d:f0:a7:9f:
+ 68:da:bb:17:9e:b4:c1:a2:81:15:be:28:43:f7:2c:20:35:94:
+ 17:33:99:52:33:8b:7b:72:12:27:df:88:29:11:93:2e:55:8a:
+ eb:63:56:14:e9:cb:58:e3:a6:52:e4:21:04:48:fc:09:a0:30:
+ 8a:8c:cf:df:b2:6c:5c:d3:96:0a:59:26:70:b5:fa:d0:1a:cf:
+ 06:e9:30:f8:a2:45:52:63:43:c9:8d:ee:13:35:c4:6d:fc:f9:
+ 16:4f:f7:5c:56:16:1a:1f:17:6c:f6:2e:20:d6:ec:57:0f:fa:
+ 34:1c:a7:b5:18:fa:7d:16:54:71:3e:cd:97:70:f8:b9:7d:ea:
+ 67:83:50:74:4d:a7:c5:90:a8:51:50:50:61:c9:31:06:63:7a:
+ 8d:3c:b9:eb:f5:31:3c:fa:be:4a:1e:2d:02:26:cb:7d:fb:54:
+ 21:16:7a:06:72:34:fd:1a:9c:36:9f:d0:4a:bf:df:86:74:0f:
+ fc:df:bf:32:6a:41:ae:24:67:a1:4a:f7:c8:cd:a1:6a:9b:c5:
+ 69:db:72:94:b9:85:13:ab:20:25:77:b2:2f:a4:40:ec:e9:0f:
+ 68:b2:a8:f7:78:50:f5:5b:30:6b:67:4a:f0:ca:57:18:0d:54:
+ 9a:bd:e4:33:24:9c:51:4a:6f:99:92:3e:05:0b:a8:d1:9f:a8:
+ d4:54:28:b0:8b:be:0a:ff:64:76:aa:76:7c:f0:23:3f:c1:8d:
+ 91:4f:04:37:2c:30:90:1e:6d:60:41:88:9d:b5:7b:0a:1b:98:
+ e5:15:58:47:d8:fd:11:d0:0f:5d:ec:6c:65:fd:3c:b1:4a:a4:
+ 7a:79:bd:e9:4d:4d:39:7b:9b:30:76:11:1c:c5:df:51:5b:7e:
+ 7b:44:1e:25:44:35:f3:71:19:3b:d4:7a:5e:db:3a:3c:85:54:
+ 0f:b1:d9:1d:ab:69:88:04:a1:2e:37:77:8d:97:aa:24:17:af:
+ 54:71:9f:ff:1d:74:e9:f3:7d:c8:79:e9:08:59:5f:dc:0e:d8:
+ b7:5b:fa:ee:4c:07:cf:51:fb:e7:5b:7c:d0:d5:85:f9:08:9c:
+ 81:6a:83:f7:15:cd:fc:4d:a5:a7:39:6b:b2:cc:f2:e9:90:b7:
+ ea:e5:5e:3a:a0:a9:1d:e5:8d:2f:80:9b:30:8a:f0:ff:d5:c2:
+ a6:0e:83:7b:80:ec:f4:7b:88:f4:ad:69:01:81:35:94:14:0c:
+ 8e:50:93:a5:39:17:5b:06:e0:70:3c:f9:6e:5e:09:89:84:23:
+ 74:12:42:82:22:78:bc:aa:64:d3:51:f4:c6:96:8a:33:19:56:
+ bb:21:6f:bd:dd:c9:0b:69:0e:2c:17:5e:67:12:64:08:21:fd:
+ 2e:5b:49:14:6e:9f:47:86:a4:99:4b:06:a5:50:20:30:a4:c7:
+ fb:32:d5:b6:5b:74:82:4c:7a:d0:e2:2b:99:7a:67:69:7a:3e:
+ d0:4e:65:eb:d3:ad:41:83:71:e1:c3:c7:69:36:03:ac:e4:0b:
+ cd:26:d7:00:36:88:26:36:22:fe:d4:d5:4f:79:5a:88:10:55:
+ 98:0d:e6:e3:49:c8:fb:b5:b3:b8:5c:cb:a3:57:80:a8:06:34:
+ 32:57:70:0a:df:78:d4:d1:f9:cc:27:ef:17:2e:38:26:e6:32:
+ ff:7d:a7:f8:44:b3:52:00:4c:a0:af:76:6a:a3:99:c2:a7:73:
+ c8:fd:9c:fa:40:c8:48:0f:83:e8:03:3f:2b:7e:3a:bc:3b:6c:
+ 43:af:2b:ca:a3:29:a7:2a:d2:c2:22:90:98:fb:7e:33:79:c3:
+ 6d:b9:56:96:bd:6d:f5:57:cf:79:03:77:e6:85:17:d2:7b:5a:
+ 67:6d:03:b2:cc:e0:4f:81:56:d7:54:f7:cd:31:c7:bd:cf:d4:
+ 19:9f:99:1b:91:69:28:9b:09:27:77:28:de:4f:cb:2a:38:4d:
+ 29:28:de:4f:a4:d4:e4:09:a2:a4:ca:dd:86:e4:fd:3b:95:1a:
+ 5a:74:9f:3b:af:32:d0:25:7a:67:c3:de:c6:93:0e:8a:6b:1e:
+ 79:89:4c:0c:86:91:cf:b5:bd:b3:3d:6c:c0:26:74:83:49:62:
+ cc:51:83:3a:e7:08:bb:17:67:17:c2:fa:9a:af:86:57:b8:44:
+ a6:3f:af:8f:21:85:bd:88:5b:ff:1b:af:78:3b:aa:90:74:ff:
+ 3a:f3:18:40:69:4f:35:a6:45:80:ff:99:7b:95:a3:51:1b:e0:
+ 26:cc:46:41:dc:4a:ca:54:a2:c1:14:d9:44:36:ba:eb:29
-----BEGIN CERTIFICATE-----
-MIIFPjCCAyUCCQD6uqUQ74W7cDANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJV
+MIIJPjCCBSUCCQCVJI6ey0uORzANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJV
UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQ
-MA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMB4XDTE1MDQyMzIx
-MzIyMVoXDTI1MDQyMDIxMzIyMVowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+MA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMB4XDTE1MTIwMjIw
+NTczOVoXDTI1MTEyOTIwNTczOVowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
-Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCAiMwDQYJKoZIhvcNAQEBBQADggIQADCC
-AgsCggICAMmYNX2l1EEbg2CEdhTCDaZ/51IVpXyWlla4mPm8lFYjFPJ0Bea62TpY
-3bUDnNH1R3bCRXj5uOFEQEUILdH/w7/XskqUamE33ctmIiiNzF813Zoa1Q7MNnau
-ZaKW083ejbTJKKioLUWJmKp9nhJ74aW62VaKSh8cfeLP9fBUOG1HTB0cIjx0ckv9
-wpdmsZyOw9aIXmrtyf632e8DJV3aSqte+vSohzCQAIWmW0B3tjRkY1gFzR5Y1v2y
-E1G6pJ9/49uIiFgf319nzEkKu+DO2T/OJiAeNfPwir2Li08WgFNORDsanmBr/8/3
-n0C/0obkeTk611q90GPP9lThngnnY4oXM7/yX+zuRRhS7ucjoqiv0oVLu/kSujUi
-0l6cQi1m4QEC1A//hhyRj1WcnyROF8gjwadOOe1L3LjEP33JD/8BQE3dmlUphPhS
-cto4MprvKy5nW9ItcEaRQnkiogjA/SSVngSmXJ7A7SUqV2IXt8AS1ItZ89uLzZVP
-2TLy8OEUm9tz57SXppD3DctZk5QSKsEofTy9tX67E8BM784gPTtPhCV33B8PCN12
-nK19AC8jQmo36dBrjppvO0YJdCNDqVhGYjNpKgzfzWx1iPEBPWfgqOO9IwNm8xHy
-B6i/S8mBzqntjUimEBX7eSeuLo81xTkS6/K3KNOz50xx2OHR9zmUhwIDAQABMA0G
-CSqGSIb3DQEBCwUAA4ICAgAtO19YMFiXZdA2pgMMa7ymW+ePo6cFXdubPw4iiT7h
-AJE8F6sQEID10fnL1zievDagMdLjL5hi2KLNc3xWKbDAQQFxUHB6sp22rRNx2Bl9
-T3q+SzYu1/eBU6fgfwR3CYSjViJIfm3KIBLtp9opz0ZGgY+XSxdjJfIYSMGCIce+
-T1QpiCl40L6YnNlPdudrohBKzkUCx15arF8OS6NRqex6P6BRSXW8r/SJiDVpZRWl
-M8UvHsUwmGsEFLkptTF2I4gycinkFt67lda7SOU4N1duii/AZCwBTeZpnq5KOYeW
-XVDmJQhGd+raTbK9XkTK4kaxeko9gxappuXE7/yvd1huO82zsw7SWdK+Fqxk+vex
-BgJ9yYoGZXPa2KgCQdVoQXoPp1yQs28BZmWWTFC9xzhnYSFS3Knw9wsWlS1duAva
-mv74TOn6ajKn1Gd7IUV6Tnym+stlPY84kFopfX8hMm3GYXD5qE4/mzzwS0DWfeXW
-MQj/KSH554E2GobVlgYdHrH8TONtzjosFrgDdvNwdxXqtTLD9Z+mYeEpu4gsoM8F
-9T2XrrW5AegvXlQXLglb6tBKlWXZz4M6vB19KEt7jVzvigb5ZLXsP3P8bFjMV9rT
-XV61WENTJ/BJAeRFjeto80D87GNizsPZl9OjUYzFCamBbiPgah8CsPiwQAwv6u7C
-Hxs=
+Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCBCMwDQYJKoZIhvcNAQEBBQADggQQADCC
+BAsCggQCAN/BCGR6Md8UlT/NbYOcP532Mc4pQHZbT5zyX6W/1ILrZx0aGMVDU7ac
+Gd6H2lP+EejNSbZcmGjcrrI+hgOKpeullRoBtrdnhFoHzZAGaVLbELhz9g/iQyhL
+X0J1yXhluy1LuemXCb4fSV5Xhsc/++sYkFd+hsDhd+xnbifr94B65rHdeMny7xsQ
+PuJviYtWjWnX8BseNdZBxhqAHxW+Dq7Jh9/ogKKFIN4yOvjMEnLrQR4rKik/9+Hr
+KZmttI15CpmOD0ofROl0txfLlyF6fdVspf3RU7UhjApTTQrpTUBSCzVfQAkJH222
+BJx18u4yidj/o1s3k2nwJUzsKqce4ikz7wf0YYyRqbv5ibqy3ZgIkb939rs794r3
+HNdrF9P6YhIuu9O/eKPrHssAcG6HP57r/S0yd/Ixr1zcFacs2a7n+/gBSslF84fc
+x8wU/n99RpQIrCVqGAJJtaq9T8UaBLisoWpUARkF9FXgCJhn9exhCez8gZuId1N6
+0UhMj+K3DQYEvAVuDwqhVgexE0GQSf0ScPYBV63WLaKhBM/RKTj1aHZYm10eDyx3
+9vDP2N/F0iOLNKmulGd0SyGZfLvevvlctusULbs4VvsMfHBCQhsbPJhtYR8WMs5z
+KiOe6+bRiQ0wB9KUCYxtOEnmB/29I0hHbMrA2lDoXwYIcuHK/ZH8KfwmQP8deBYj
+H8JkQQS2PEC3CCemfSZK/Vev7rrjk0UHZFxfwKfoolunPdrTlx982ncADTA+4679
+TMcY5mLgnXQPkACqwjLe3NGP18PCCL/RvX4hCXkyjxoSQ5eRQTO91C47qW0GI9Ha
+fl9FJ9UXnA7fLNFmy+3s48Nrqw26cQSkkqRxVWkgNXL9rVSoz0TDnaFalE0FYl6Y
+1iXF1s/175TALFOHC58TD2PFl9VbikZ8DijeZpZ03yqysCdtTE9UctktrlhP02Nj
+k8I0V2Y7OJA2qamV5n3ohIdoc5tEaNlpHxwbnVhEd3LoKMEaEb1cQLfQWLlYkZ9b
+MJQz+va+KlmLQ8zjBEUbQ37XtfTT3F1lrmvRktL3to/fxlwAwws3KDMz3QXLPGIN
+C1RC6p9s6fLvx6t8XM8YVTUc93KPw9UbwAlvROgGYkTECxDiw7Gc3nM3XVG8tj84
+G3XZJt9PGutjnOFJEeTL7OM6seIAi5K7c/sFeIHnrCEbI8GPi5xSuwnaciO/geZ0
+GGMfhJtdBpJyqoRQ9I8qlAWPQl/eRQWyviY93MTvg8uqtGcvXOL5s5wf+ZKPQE+Z
+35pe/cXbktyoQRNk9LsKZYfczzkwvp46hmLWLm8Xitl3OuKNjwjrHv2vZyId//+4
+IiuTUR0Sx2uFTbcYlmTiJQbsRWdjK7EjAgMBAAEwDQYJKoZIhvcNAQELBQADggQC
+ALp/dV9f5ql6slOo1AJgISnOpeOViusi0FTzdhsipL0r/qAO9EaKxLTuWMrA3Hoc
+JjCZhe3lrjojgXZbtOhQM28ZUqYDgscTzk+Xr9dCbigP8s/m6/npZUAukkSHrPej
+ZYSmRh7GPCOamBPY886gIAbTauzbP9eSXAGn4cHZum8bQQ//bYDd32kbRTbx5B1y
+llc9ioDjrrSRjohASOYzDeetP6rTwZbyRHO7UVbOdbXpLfCnn2jauxeetMGigRW+
+KEP3LCA1lBczmVIzi3tyEiffiCkRky5ViutjVhTpy1jjplLkIQRI/AmgMIqMz9+y
+bFzTlgpZJnC1+tAazwbpMPiiRVJjQ8mN7hM1xG38+RZP91xWFhofF2z2LiDW7FcP
++jQcp7UY+n0WVHE+zZdw+Ll96meDUHRNp8WQqFFQUGHJMQZjeo08uev1MTz6vkoe
+LQImy337VCEWegZyNP0anDaf0Eq/34Z0D/zfvzJqQa4kZ6FK98jNoWqbxWnbcpS5
+hROrICV3si+kQOzpD2iyqPd4UPVbMGtnSvDKVxgNVJq95DMknFFKb5mSPgULqNGf
+qNRUKLCLvgr/ZHaqdnzwIz/BjZFPBDcsMJAebWBBiJ21ewobmOUVWEfY/RHQD13s
+bGX9PLFKpHp5velNTTl7mzB2ERzF31FbfntEHiVENfNxGTvUel7bOjyFVA+x2R2r
+aYgEoS43d42XqiQXr1Rxn/8ddOnzfch56QhZX9wO2Ldb+u5MB89R++dbfNDVhfkI
+nIFqg/cVzfxNpac5a7LM8umQt+rlXjqgqR3ljS+AmzCK8P/VwqYOg3uA7PR7iPSt
+aQGBNZQUDI5Qk6U5F1sG4HA8+W5eCYmEI3QSQoIieLyqZNNR9MaWijMZVrshb73d
+yQtpDiwXXmcSZAgh/S5bSRRun0eGpJlLBqVQIDCkx/sy1bZbdIJMetDiK5l6Z2l6
+PtBOZevTrUGDceHDx2k2A6zkC80m1wA2iCY2Iv7U1U95WogQVZgN5uNJyPu1s7hc
+y6NXgKgGNDJXcArfeNTR+cwn7xcuOCbmMv99p/hEs1IATKCvdmqjmcKnc8j9nPpA
+yEgPg+gDPyt+Orw7bEOvK8qjKacq0sIikJj7fjN5w225Vpa9bfVXz3kDd+aFF9J7
+WmdtA7LM4E+BVtdU980xx73P1BmfmRuRaSibCSd3KN5Pyyo4TSko3k+k1OQJoqTK
+3Ybk/TuVGlp0nzuvMtAlemfD3saTDoprHnmJTAyGkc+1vbM9bMAmdINJYsxRgzrn
+CLsXZxfC+pqvhle4RKY/r48hhb2IW/8br3g7qpB0/zrzGEBpTzWmRYD/mXuVo1Eb
+4CbMRkHcSspUosEU2UQ2uusp
-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/name_constraint_bad.pem b/chromium/net/data/ssl/certificates/name_constraint_bad.pem
index e0ec5067f5a..9ee785dcc7e 100644
--- a/chromium/net/data/ssl/certificates/name_constraint_bad.pem
+++ b/chromium/net/data/ssl/certificates/name_constraint_bad.pem
@@ -1,30 +1,30 @@
-----BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1+PQy2PX0Zcrp
-0Mvd6ZehbpDi9LKyFtCb4plX7XvGW29JwZQAqQ1dtTX0Ons8GAajeFpo/6YFH30Q
-CK4JbNzv3biXnmzOy6DcMysele8d+9Pa+D5X7YuOnoZNEqYMMCPvCEVPIRJCiIcB
-2KUyn7c472Ctt0drO0umXCtWclzRtTiHmew7/8YC74Y47uIFxvBm4hiRUOVXIyeZ
-u9tJJIhmqBSWfhptKuH/GPVqN9KIqHnJuVD1mmgLBJ5oAh2hceCJFboqSAZ6eNPR
-DHeDmIP4ueJgIJIHm9TIwPpaWp0mQMI1ZQDzoOLTIU2lxJGIkBSnXvcTt+oror3X
-hBgat3tdAgMBAAECggEABykz2uhkzWhQEuFvlF0D5YtnUjcU7SMutGO3axliXIzu
-lTVz8I62gvCFngXLIbNEV5x92lHtI5h4oG/nAWHyU9Ii2HyYhY7H1sKAuORnk4N8
-c8p/EZC8hDFC0behJyuhzl9B8vo3ML0UqwLuhU55tFjfMhbbTaH4uSQ5ZF59vpbV
-BLe+j3+0BWINSi65KrE/V9PAlH0IuSir4YYuFcJApZIMdiXGqb1mnnUn4CkMmmeH
-JvRaYvrxD14T/lzMVzBkR0bez5jYe7syspCe+mmyqIS0mTOw8rQER1vL/DHcyJsG
-inG5IazyDaCvgqNAEKzeh0AC3aoel86lURIlt/TrFQKBgQDrSKIvDDXFpYxtpJYt
-Q+gyUqN/QPwGVL39n7kSpBoFWKsP9eSGKjVfD4PJboYjE0pcoci4ohsOHmyHpaqi
-lAzy4oGd5VqEfu4qz65W7xFwZnMnxLv7OZeHzZG7nw2PIT6k57hNd0/IEndFLHZU
-zBm56Ow/Czkb4HA/IR5RQG4SywKBgQDF/qst7PVtWOm6wJ3boJNl7QasWTRKsNxg
-DkEo76dOwq2BSFTO+WYKWFPsOYrlnHbf3Ni869WB/vGwE8IecOH0Ir39plbRb2nc
-WRW13mljwTET9AGb0/nhPkduYPyN7Gjvy1DTTz5e47rk5881siU8dPCSvgygo9DO
-vy+ZlAtddwKBgQCIGa3ndTKtsAO5cNmGOZ/ZbEAzXk3rA54bVgdipxZ+PTpGs0CL
-82KIKJtdK9ff9kqvps5LL0pjMmopVUWNYgLThP7hbUidGCeBED2TABugX0MBoCX1
-Pu1OmzVPyMO5Jcvs7DWKahf2begcVYnlp2LCTeBK350baQrFGc1FxvVlXQKBgHrS
-y7/2oh1OLdgTCxoml6mAC0a5I6493sebsCJD4McED3wGsc2fewRp3M3KuHZNxJSE
-vNMdfVpiG+39o8scfZ7kOnXyTSMo+UOe48/pg/lE7DwTfzf6nKV06/z2H1WvVT2E
-I8SiAO/+V38OqkUGGQFTDbYKPW0dkjfe9BlSdGZrAoGAfbDe3biBtcMw57AKTf78
-i+dku+lnVkAmPOr1I6nnN2qGUdbXjbV2EE88BSo4OF6TF7C6dwicQuv5PxpozCRM
-NkdqZ7UT2h7JX0KybnrIvHefboG/pK/Jjg9cEBhN1P6y6+pyzWKa7Nc1c0pXRqz6
-FzMv6eiJALyDSTm0ChEm6ug=
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDD5m1zsjUwajot
+NE67oL3Ln1Gj5dOIy85u4iS4bA29+3VCpDpFSb8q+atKgK4VM4H41gZ4ilk6T4Nw
+bh0z9PDQBIH8s5Yd0Xkqf3Ji0SDRsqBn+kQ2BXKHjup34lQrCgJ2BPoqle9Aj+Jd
+Z2mjnCB2C5E8it8BYziraCdsXLC8wRBDoWFi6laPMuEd910uTaav4/MZ3y6SBJLm
++Q0URXm5d5msqK7KuAVlgYDdnzS1iRNiGH2fPU/NHw1NMsJyM5b3MEwu72YDzmxS
+9QTpAp5vVPxKbMIhGqkVZpcfEVkB4FMZYueAJtr761dUhzZSSGoB3/D54cghc6ly
+9HySHvFDAgMBAAECggEAfp4WClyZwlQ2i/cuGFm5sr2j7/JhOh64q7ShFU5Jx4ya
+6trpCtWyqN08mGf5nJxxGluDTS/moii4hNe3KljbuSfguGt+0IEO9qfvT+1pcAAr
+a2k34068CuAVrizsR/EtTAjFhPbp7+nP3p0zi1sjJAkv81iy8NunyioEqSZz2Vsw
+ngPFuJeytOgeczoE69yzP1L0BaM46jOKXezXahC31lwtG+U5tLvElU0b/To/7GTg
++u5qnsJ87wHYkOctXvqH+L1JeMkc7RWCo0h4Kbk3ur1kDokjqUV4FGQSaMyIy0PC
+ndk9WZhUV03v+Lsy3gzBM8261HOiTSMRz/+KrYqAOQKBgQD6ET0Hm11FIUFSeM/I
+Dbxb41oN4ODl4YUgGk/9jPX8/ztvrGddh3VGWD4KUVNlWLioBX/t7FH5paGtd6tg
+ZG8X3n48DaJ5h4u95ulAzcVjrkF4aNahy4aMmofdpe4S3+7HwlBcfIocO9WpAtL0
+pzFjlXivLQgUQow67tbG2dYrPQKBgQDIjDWWSqn6kB1zFyI6Hh9HhfFAKCRvCIzQ
+OvqIOCtExP4U4mE0rUY7RWkFrRTDoMmYCwRuCohL1C4p6i/2AwK1mhS8OgPji7YV
+zgYZuw2lSmp1lqzRmiLaOZxLcEKWlHQ1C9Sq606T7YAhgXi3tDfQ53gb1uFDvt1h
+rE3AkU1WfwKBgHZ2EBk4aljDRjSRcqzshNxquVB1xVRhHzV0AYy1aBpvtnJSk6zk
+7JNkXg95My6BdwhxgobtOnAvHIYWeKLzMQV3qwk71EoKAhL1/m1qjSWJeQ5Xa8W9
+qoGU+uPvJPbgCjerP3JwtORnG/Iymki3o1fviPpDNN6UH+YTGr+cli5pAoGBAKnT
+4gU1kR/4LpgpvPhOTdq5mITl+YR1Txl++G2mcy23TBrPYdXD7jd/HeKKoYzQeibh
+HY06KhVcxwMDqD3CaubyZiDHWEe3Jijs4MmlV3bjv6d4Qzz0NBNsuehAVoNBj+7j
+5+IdhdtLQjgddebLHIExosqgev5tgPeXe/hYk49tAoGBALENmfF8ORreFf+aOd4+
+w/CZB2VaN4p0N6I+w2HPRRJO6Rhk0Pe6NtPkxbUS0x/cm+WOpvSbntH1DOjigL8e
+mo+n2Ym+lrtYmEtB/M2C1k29pwaGYMfEIP3URUuYNEpWvTs6AOY7Sp5QN/X/v9ES
+76pTvCiginWRyEeR+6vrDGM8
-----END PRIVATE KEY-----
Certificate:
Data:
@@ -33,37 +33,37 @@ Certificate:
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Test Root CA
Validity
- Not Before: Aug 14 03:05:29 2014 GMT
- Not After : Aug 11 03:05:29 2024 GMT
+ Not Before: Dec 21 20:35:47 2015 GMT
+ Not After : Dec 18 20:35:47 2025 GMT
Subject: CN=Leaf certificate
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
- 00:b5:f8:f4:32:d8:f5:f4:65:ca:e9:d0:cb:dd:e9:
- 97:a1:6e:90:e2:f4:b2:b2:16:d0:9b:e2:99:57:ed:
- 7b:c6:5b:6f:49:c1:94:00:a9:0d:5d:b5:35:f4:3a:
- 7b:3c:18:06:a3:78:5a:68:ff:a6:05:1f:7d:10:08:
- ae:09:6c:dc:ef:dd:b8:97:9e:6c:ce:cb:a0:dc:33:
- 2b:1e:95:ef:1d:fb:d3:da:f8:3e:57:ed:8b:8e:9e:
- 86:4d:12:a6:0c:30:23:ef:08:45:4f:21:12:42:88:
- 87:01:d8:a5:32:9f:b7:38:ef:60:ad:b7:47:6b:3b:
- 4b:a6:5c:2b:56:72:5c:d1:b5:38:87:99:ec:3b:ff:
- c6:02:ef:86:38:ee:e2:05:c6:f0:66:e2:18:91:50:
- e5:57:23:27:99:bb:db:49:24:88:66:a8:14:96:7e:
- 1a:6d:2a:e1:ff:18:f5:6a:37:d2:88:a8:79:c9:b9:
- 50:f5:9a:68:0b:04:9e:68:02:1d:a1:71:e0:89:15:
- ba:2a:48:06:7a:78:d3:d1:0c:77:83:98:83:f8:b9:
- e2:60:20:92:07:9b:d4:c8:c0:fa:5a:5a:9d:26:40:
- c2:35:65:00:f3:a0:e2:d3:21:4d:a5:c4:91:88:90:
- 14:a7:5e:f7:13:b7:ea:2b:a2:bd:d7:84:18:1a:b7:
- 7b:5d
+ 00:c3:e6:6d:73:b2:35:30:6a:3a:2d:34:4e:bb:a0:
+ bd:cb:9f:51:a3:e5:d3:88:cb:ce:6e:e2:24:b8:6c:
+ 0d:bd:fb:75:42:a4:3a:45:49:bf:2a:f9:ab:4a:80:
+ ae:15:33:81:f8:d6:06:78:8a:59:3a:4f:83:70:6e:
+ 1d:33:f4:f0:d0:04:81:fc:b3:96:1d:d1:79:2a:7f:
+ 72:62:d1:20:d1:b2:a0:67:fa:44:36:05:72:87:8e:
+ ea:77:e2:54:2b:0a:02:76:04:fa:2a:95:ef:40:8f:
+ e2:5d:67:69:a3:9c:20:76:0b:91:3c:8a:df:01:63:
+ 38:ab:68:27:6c:5c:b0:bc:c1:10:43:a1:61:62:ea:
+ 56:8f:32:e1:1d:f7:5d:2e:4d:a6:af:e3:f3:19:df:
+ 2e:92:04:92:e6:f9:0d:14:45:79:b9:77:99:ac:a8:
+ ae:ca:b8:05:65:81:80:dd:9f:34:b5:89:13:62:18:
+ 7d:9f:3d:4f:cd:1f:0d:4d:32:c2:72:33:96:f7:30:
+ 4c:2e:ef:66:03:ce:6c:52:f5:04:e9:02:9e:6f:54:
+ fc:4a:6c:c2:21:1a:a9:15:66:97:1f:11:59:01:e0:
+ 53:19:62:e7:80:26:da:fb:eb:57:54:87:36:52:48:
+ 6a:01:df:f0:f9:e1:c8:21:73:a9:72:f4:7c:92:1e:
+ f1:43
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
- 82:04:1D:BD:05:71:83:6F:F6:98:19:4D:4F:11:46:88:4D:9B:BF:A8
+ 64:AD:F5:F3:4B:2D:70:3A:13:B7:0D:D6:8F:9F:82:37:C3:58:73:A8
X509v3 Authority Key Identifier:
keyid:BC:F7:30:D1:3C:C0:F2:79:FA:EF:9F:C9:6C:5C:93:F3:8A:68:AB:83
@@ -72,38 +72,38 @@ Certificate:
X509v3 Subject Alternative Name:
DNS:test.ExAmPlE.CoM, DNS:test.ExAmPlE.OrG
Signature Algorithm: sha256WithRSAEncryption
- a6:90:20:7b:27:40:64:b3:df:ec:56:9e:71:67:02:e7:88:7e:
- c2:f0:ed:24:19:53:27:c9:97:95:18:76:16:52:4c:78:57:63:
- 4b:3d:17:3d:7f:f3:d6:e2:1e:5a:cd:84:ea:be:0c:82:5d:4e:
- 69:b9:d8:66:a3:a0:2f:e5:50:c8:84:bd:50:15:5f:25:fe:30:
- a0:41:b6:e6:b6:cf:fc:87:db:23:4e:3e:f4:0e:75:74:3c:9e:
- f1:d6:af:11:ad:11:80:b0:60:42:06:f5:bf:e4:5f:0c:73:7a:
- 62:49:f2:e5:62:15:f1:8f:bd:ed:34:75:cf:50:11:cc:ee:a3:
- 59:21:22:b7:ec:44:22:f7:98:77:1f:64:50:0f:f3:ab:5a:ff:
- d2:62:cc:1b:46:81:56:2a:76:00:e0:ff:0e:9e:e0:d4:d0:03:
- 2d:1d:23:c9:d3:a4:f0:2f:a5:b3:30:12:82:46:f0:71:7e:91:
- b9:1a:ae:3e:25:74:cf:79:35:d2:82:33:55:ac:54:94:43:7f:
- de:cc:3e:ef:0d:a6:03:2a:c8:f5:8d:3b:ba:d2:97:ed:6d:d5:
- a9:90:5f:8b:df:3e:d3:be:4b:43:7f:28:ce:9e:3e:90:f7:fb:
- db:34:21:69:5c:94:f5:32:f0:ba:30:f5:60:4c:1f:3b:9b:43:
- 94:6c:8d:cc
+ af:4e:e7:07:29:47:e4:18:64:96:83:22:3c:21:4c:dc:41:90:
+ c9:28:5b:a7:ce:e9:ad:da:28:04:90:f6:62:c9:6c:0e:a1:98:
+ 3a:19:ec:28:f5:b7:cf:07:cd:b3:0c:d0:97:a4:3d:e2:fe:0c:
+ d8:68:f4:cf:57:18:3e:58:f9:ed:1b:2f:f5:11:e4:4d:61:93:
+ b3:f3:1c:bc:53:cf:8b:81:2e:1b:a3:28:f6:df:ae:82:74:99:
+ 75:62:51:3d:78:1d:65:3d:eb:0a:7b:60:0e:3a:c7:ff:57:1c:
+ a4:9e:19:66:ef:18:78:b1:d6:1f:27:31:e0:a6:a2:27:42:15:
+ 2f:2a:38:e7:4a:0c:3b:8e:4d:c2:a1:27:45:32:0d:c4:b8:51:
+ 70:41:a6:1a:2f:13:d0:f8:3d:fa:76:0c:57:ad:3e:86:ec:1c:
+ 05:ea:81:d2:33:35:0b:1e:ab:86:2a:94:ee:44:9f:a4:1a:fe:
+ 94:0c:7f:f7:e7:17:1f:cc:1c:b8:cc:5a:55:ce:b1:d8:2e:0b:
+ 3d:8c:19:fc:c2:6b:da:c8:1d:b7:27:fa:bb:90:04:a6:53:bb:
+ 94:7b:cb:a3:ec:80:7e:18:2e:86:aa:41:97:43:c7:25:1f:33:
+ a3:ee:93:00:c5:ec:31:da:0e:40:f2:a2:a9:39:42:a8:e1:65:
+ ed:c7:65:f0
-----BEGIN CERTIFICATE-----
MIIDTTCCAjWgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0
-IFJvb3QgQ0EwHhcNMTQwODE0MDMwNTI5WhcNMjQwODExMDMwNTI5WjAbMRkwFwYD
+IFJvb3QgQ0EwHhcNMTUxMjIxMjAzNTQ3WhcNMjUxMjE4MjAzNTQ3WjAbMRkwFwYD
VQQDExBMZWFmIGNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAtfj0Mtj19GXK6dDL3emXoW6Q4vSyshbQm+KZV+17xltvScGUAKkNXbU1
-9Dp7PBgGo3haaP+mBR99EAiuCWzc7924l55szsug3DMrHpXvHfvT2vg+V+2Ljp6G
-TRKmDDAj7whFTyESQoiHAdilMp+3OO9grbdHaztLplwrVnJc0bU4h5nsO//GAu+G
-OO7iBcbwZuIYkVDlVyMnmbvbSSSIZqgUln4abSrh/xj1ajfSiKh5yblQ9ZpoCwSe
-aAIdoXHgiRW6KkgGenjT0Qx3g5iD+LniYCCSB5vUyMD6WlqdJkDCNWUA86Di0yFN
-pcSRiJAUp173E7fqK6K914QYGrd7XQIDAQABo4GfMIGcMAwGA1UdEwEB/wQCMAAw
-HQYDVR0OBBYEFIIEHb0FcYNv9pgZTU8RRohNm7+oMB8GA1UdIwQYMBaAFLz3MNE8
+CgKCAQEAw+Ztc7I1MGo6LTROu6C9y59Ro+XTiMvObuIkuGwNvft1QqQ6RUm/Kvmr
+SoCuFTOB+NYGeIpZOk+DcG4dM/Tw0ASB/LOWHdF5Kn9yYtEg0bKgZ/pENgVyh47q
+d+JUKwoCdgT6KpXvQI/iXWdpo5wgdguRPIrfAWM4q2gnbFywvMEQQ6FhYupWjzLh
+HfddLk2mr+PzGd8ukgSS5vkNFEV5uXeZrKiuyrgFZYGA3Z80tYkTYhh9nz1PzR8N
+TTLCcjOW9zBMLu9mA85sUvUE6QKeb1T8SmzCIRqpFWaXHxFZAeBTGWLngCba++tX
+VIc2UkhqAd/w+eHIIXOpcvR8kh7xQwIDAQABo4GfMIGcMAwGA1UdEwEB/wQCMAAw
+HQYDVR0OBBYEFGSt9fNLLXA6E7cN1o+fgjfDWHOoMB8GA1UdIwQYMBaAFLz3MNE8
wPJ5+u+fyWxck/OKaKuDMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAt
BgNVHREEJjAkghB0ZXN0LkV4QW1QbEUuQ29NghB0ZXN0LkV4QW1QbEUuT3JHMA0G
-CSqGSIb3DQEBCwUAA4IBAQCmkCB7J0Bks9/sVp5xZwLniH7C8O0kGVMnyZeVGHYW
-Ukx4V2NLPRc9f/PW4h5azYTqvgyCXU5pudhmo6Av5VDIhL1QFV8l/jCgQbbmts/8
-h9sjTj70DnV0PJ7x1q8RrRGAsGBCBvW/5F8Mc3piSfLlYhXxj73tNHXPUBHM7qNZ
-ISK37EQi95h3H2RQD/OrWv/SYswbRoFWKnYA4P8OnuDU0AMtHSPJ06TwL6WzMBKC
-RvBxfpG5Gq4+JXTPeTXSgjNVrFSUQ3/ezD7vDaYDKsj1jTu60pftbdWpkF+L3z7T
-vktDfyjOnj6Q9/vbNCFpXJT1MvC6MPVgTB87m0OUbI3M
+CSqGSIb3DQEBCwUAA4IBAQCvTucHKUfkGGSWgyI8IUzcQZDJKFunzumt2igEkPZi
+yWwOoZg6Gewo9bfPB82zDNCXpD3i/gzYaPTPVxg+WPntGy/1EeRNYZOz8xy8U8+L
+gS4boyj2366CdJl1YlE9eB1lPesKe2AOOsf/Vxyknhlm7xh4sdYfJzHgpqInQhUv
+KjjnSgw7jk3CoSdFMg3EuFFwQaYaLxPQ+D36dgxXrT6G7BwF6oHSMzULHquGKpTu
+RJ+kGv6UDH/35xcfzBy4zFpVzrHYLgs9jBn8wmvayB23J/q7kASmU7uUe8uj7IB+
+GC6GqkGXQ8clHzOj7pMAxewx2g5A8qKpOUKo4WXtx2Xw
-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/name_constraint_good.pem b/chromium/net/data/ssl/certificates/name_constraint_good.pem
index 7dba6578c12..683deebcfe8 100644
--- a/chromium/net/data/ssl/certificates/name_constraint_good.pem
+++ b/chromium/net/data/ssl/certificates/name_constraint_good.pem
@@ -1,30 +1,30 @@
-----BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1+PQy2PX0Zcrp
-0Mvd6ZehbpDi9LKyFtCb4plX7XvGW29JwZQAqQ1dtTX0Ons8GAajeFpo/6YFH30Q
-CK4JbNzv3biXnmzOy6DcMysele8d+9Pa+D5X7YuOnoZNEqYMMCPvCEVPIRJCiIcB
-2KUyn7c472Ctt0drO0umXCtWclzRtTiHmew7/8YC74Y47uIFxvBm4hiRUOVXIyeZ
-u9tJJIhmqBSWfhptKuH/GPVqN9KIqHnJuVD1mmgLBJ5oAh2hceCJFboqSAZ6eNPR
-DHeDmIP4ueJgIJIHm9TIwPpaWp0mQMI1ZQDzoOLTIU2lxJGIkBSnXvcTt+oror3X
-hBgat3tdAgMBAAECggEABykz2uhkzWhQEuFvlF0D5YtnUjcU7SMutGO3axliXIzu
-lTVz8I62gvCFngXLIbNEV5x92lHtI5h4oG/nAWHyU9Ii2HyYhY7H1sKAuORnk4N8
-c8p/EZC8hDFC0behJyuhzl9B8vo3ML0UqwLuhU55tFjfMhbbTaH4uSQ5ZF59vpbV
-BLe+j3+0BWINSi65KrE/V9PAlH0IuSir4YYuFcJApZIMdiXGqb1mnnUn4CkMmmeH
-JvRaYvrxD14T/lzMVzBkR0bez5jYe7syspCe+mmyqIS0mTOw8rQER1vL/DHcyJsG
-inG5IazyDaCvgqNAEKzeh0AC3aoel86lURIlt/TrFQKBgQDrSKIvDDXFpYxtpJYt
-Q+gyUqN/QPwGVL39n7kSpBoFWKsP9eSGKjVfD4PJboYjE0pcoci4ohsOHmyHpaqi
-lAzy4oGd5VqEfu4qz65W7xFwZnMnxLv7OZeHzZG7nw2PIT6k57hNd0/IEndFLHZU
-zBm56Ow/Czkb4HA/IR5RQG4SywKBgQDF/qst7PVtWOm6wJ3boJNl7QasWTRKsNxg
-DkEo76dOwq2BSFTO+WYKWFPsOYrlnHbf3Ni869WB/vGwE8IecOH0Ir39plbRb2nc
-WRW13mljwTET9AGb0/nhPkduYPyN7Gjvy1DTTz5e47rk5881siU8dPCSvgygo9DO
-vy+ZlAtddwKBgQCIGa3ndTKtsAO5cNmGOZ/ZbEAzXk3rA54bVgdipxZ+PTpGs0CL
-82KIKJtdK9ff9kqvps5LL0pjMmopVUWNYgLThP7hbUidGCeBED2TABugX0MBoCX1
-Pu1OmzVPyMO5Jcvs7DWKahf2begcVYnlp2LCTeBK350baQrFGc1FxvVlXQKBgHrS
-y7/2oh1OLdgTCxoml6mAC0a5I6493sebsCJD4McED3wGsc2fewRp3M3KuHZNxJSE
-vNMdfVpiG+39o8scfZ7kOnXyTSMo+UOe48/pg/lE7DwTfzf6nKV06/z2H1WvVT2E
-I8SiAO/+V38OqkUGGQFTDbYKPW0dkjfe9BlSdGZrAoGAfbDe3biBtcMw57AKTf78
-i+dku+lnVkAmPOr1I6nnN2qGUdbXjbV2EE88BSo4OF6TF7C6dwicQuv5PxpozCRM
-NkdqZ7UT2h7JX0KybnrIvHefboG/pK/Jjg9cEBhN1P6y6+pyzWKa7Nc1c0pXRqz6
-FzMv6eiJALyDSTm0ChEm6ug=
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDD5m1zsjUwajot
+NE67oL3Ln1Gj5dOIy85u4iS4bA29+3VCpDpFSb8q+atKgK4VM4H41gZ4ilk6T4Nw
+bh0z9PDQBIH8s5Yd0Xkqf3Ji0SDRsqBn+kQ2BXKHjup34lQrCgJ2BPoqle9Aj+Jd
+Z2mjnCB2C5E8it8BYziraCdsXLC8wRBDoWFi6laPMuEd910uTaav4/MZ3y6SBJLm
++Q0URXm5d5msqK7KuAVlgYDdnzS1iRNiGH2fPU/NHw1NMsJyM5b3MEwu72YDzmxS
+9QTpAp5vVPxKbMIhGqkVZpcfEVkB4FMZYueAJtr761dUhzZSSGoB3/D54cghc6ly
+9HySHvFDAgMBAAECggEAfp4WClyZwlQ2i/cuGFm5sr2j7/JhOh64q7ShFU5Jx4ya
+6trpCtWyqN08mGf5nJxxGluDTS/moii4hNe3KljbuSfguGt+0IEO9qfvT+1pcAAr
+a2k34068CuAVrizsR/EtTAjFhPbp7+nP3p0zi1sjJAkv81iy8NunyioEqSZz2Vsw
+ngPFuJeytOgeczoE69yzP1L0BaM46jOKXezXahC31lwtG+U5tLvElU0b/To/7GTg
++u5qnsJ87wHYkOctXvqH+L1JeMkc7RWCo0h4Kbk3ur1kDokjqUV4FGQSaMyIy0PC
+ndk9WZhUV03v+Lsy3gzBM8261HOiTSMRz/+KrYqAOQKBgQD6ET0Hm11FIUFSeM/I
+Dbxb41oN4ODl4YUgGk/9jPX8/ztvrGddh3VGWD4KUVNlWLioBX/t7FH5paGtd6tg
+ZG8X3n48DaJ5h4u95ulAzcVjrkF4aNahy4aMmofdpe4S3+7HwlBcfIocO9WpAtL0
+pzFjlXivLQgUQow67tbG2dYrPQKBgQDIjDWWSqn6kB1zFyI6Hh9HhfFAKCRvCIzQ
+OvqIOCtExP4U4mE0rUY7RWkFrRTDoMmYCwRuCohL1C4p6i/2AwK1mhS8OgPji7YV
+zgYZuw2lSmp1lqzRmiLaOZxLcEKWlHQ1C9Sq606T7YAhgXi3tDfQ53gb1uFDvt1h
+rE3AkU1WfwKBgHZ2EBk4aljDRjSRcqzshNxquVB1xVRhHzV0AYy1aBpvtnJSk6zk
+7JNkXg95My6BdwhxgobtOnAvHIYWeKLzMQV3qwk71EoKAhL1/m1qjSWJeQ5Xa8W9
+qoGU+uPvJPbgCjerP3JwtORnG/Iymki3o1fviPpDNN6UH+YTGr+cli5pAoGBAKnT
+4gU1kR/4LpgpvPhOTdq5mITl+YR1Txl++G2mcy23TBrPYdXD7jd/HeKKoYzQeibh
+HY06KhVcxwMDqD3CaubyZiDHWEe3Jijs4MmlV3bjv6d4Qzz0NBNsuehAVoNBj+7j
+5+IdhdtLQjgddebLHIExosqgev5tgPeXe/hYk49tAoGBALENmfF8ORreFf+aOd4+
+w/CZB2VaN4p0N6I+w2HPRRJO6Rhk0Pe6NtPkxbUS0x/cm+WOpvSbntH1DOjigL8e
+mo+n2Ym+lrtYmEtB/M2C1k29pwaGYMfEIP3URUuYNEpWvTs6AOY7Sp5QN/X/v9ES
+76pTvCiginWRyEeR+6vrDGM8
-----END PRIVATE KEY-----
Certificate:
Data:
@@ -33,77 +33,78 @@ Certificate:
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Test Root CA
Validity
- Not Before: Aug 14 03:05:29 2014 GMT
- Not After : Aug 11 03:05:29 2024 GMT
+ Not Before: Dec 21 20:35:47 2015 GMT
+ Not After : Dec 18 20:35:47 2025 GMT
Subject: CN=Leaf Certificate
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
- 00:b5:f8:f4:32:d8:f5:f4:65:ca:e9:d0:cb:dd:e9:
- 97:a1:6e:90:e2:f4:b2:b2:16:d0:9b:e2:99:57:ed:
- 7b:c6:5b:6f:49:c1:94:00:a9:0d:5d:b5:35:f4:3a:
- 7b:3c:18:06:a3:78:5a:68:ff:a6:05:1f:7d:10:08:
- ae:09:6c:dc:ef:dd:b8:97:9e:6c:ce:cb:a0:dc:33:
- 2b:1e:95:ef:1d:fb:d3:da:f8:3e:57:ed:8b:8e:9e:
- 86:4d:12:a6:0c:30:23:ef:08:45:4f:21:12:42:88:
- 87:01:d8:a5:32:9f:b7:38:ef:60:ad:b7:47:6b:3b:
- 4b:a6:5c:2b:56:72:5c:d1:b5:38:87:99:ec:3b:ff:
- c6:02:ef:86:38:ee:e2:05:c6:f0:66:e2:18:91:50:
- e5:57:23:27:99:bb:db:49:24:88:66:a8:14:96:7e:
- 1a:6d:2a:e1:ff:18:f5:6a:37:d2:88:a8:79:c9:b9:
- 50:f5:9a:68:0b:04:9e:68:02:1d:a1:71:e0:89:15:
- ba:2a:48:06:7a:78:d3:d1:0c:77:83:98:83:f8:b9:
- e2:60:20:92:07:9b:d4:c8:c0:fa:5a:5a:9d:26:40:
- c2:35:65:00:f3:a0:e2:d3:21:4d:a5:c4:91:88:90:
- 14:a7:5e:f7:13:b7:ea:2b:a2:bd:d7:84:18:1a:b7:
- 7b:5d
+ 00:c3:e6:6d:73:b2:35:30:6a:3a:2d:34:4e:bb:a0:
+ bd:cb:9f:51:a3:e5:d3:88:cb:ce:6e:e2:24:b8:6c:
+ 0d:bd:fb:75:42:a4:3a:45:49:bf:2a:f9:ab:4a:80:
+ ae:15:33:81:f8:d6:06:78:8a:59:3a:4f:83:70:6e:
+ 1d:33:f4:f0:d0:04:81:fc:b3:96:1d:d1:79:2a:7f:
+ 72:62:d1:20:d1:b2:a0:67:fa:44:36:05:72:87:8e:
+ ea:77:e2:54:2b:0a:02:76:04:fa:2a:95:ef:40:8f:
+ e2:5d:67:69:a3:9c:20:76:0b:91:3c:8a:df:01:63:
+ 38:ab:68:27:6c:5c:b0:bc:c1:10:43:a1:61:62:ea:
+ 56:8f:32:e1:1d:f7:5d:2e:4d:a6:af:e3:f3:19:df:
+ 2e:92:04:92:e6:f9:0d:14:45:79:b9:77:99:ac:a8:
+ ae:ca:b8:05:65:81:80:dd:9f:34:b5:89:13:62:18:
+ 7d:9f:3d:4f:cd:1f:0d:4d:32:c2:72:33:96:f7:30:
+ 4c:2e:ef:66:03:ce:6c:52:f5:04:e9:02:9e:6f:54:
+ fc:4a:6c:c2:21:1a:a9:15:66:97:1f:11:59:01:e0:
+ 53:19:62:e7:80:26:da:fb:eb:57:54:87:36:52:48:
+ 6a:01:df:f0:f9:e1:c8:21:73:a9:72:f4:7c:92:1e:
+ f1:43
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
- 82:04:1D:BD:05:71:83:6F:F6:98:19:4D:4F:11:46:88:4D:9B:BF:A8
+ 64:AD:F5:F3:4B:2D:70:3A:13:B7:0D:D6:8F:9F:82:37:C3:58:73:A8
X509v3 Authority Key Identifier:
keyid:BC:F7:30:D1:3C:C0:F2:79:FA:EF:9F:C9:6C:5C:93:F3:8A:68:AB:83
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Alternative Name:
- DNS:test.ExAmPlE.CoM, DNS:example.notarealtld
+ DNS:test.ExAmPlE.CoM, DNS:example.notarealtld, DNS:*.test2.ExAmPlE.CoM, DNS:*.example2.notarealtld
Signature Algorithm: sha256WithRSAEncryption
- 36:cf:f0:0a:f6:e9:6b:30:2b:d2:46:1b:c8:e4:4d:d2:2b:4d:
- 0e:45:c8:e0:93:83:bb:f3:37:c2:81:65:fd:ea:cc:72:18:f6:
- 0b:60:a3:a0:7d:80:ca:28:ac:61:ec:bd:3b:e2:80:22:2f:40:
- 6f:a0:0f:33:3c:73:31:58:3e:16:ad:82:69:fe:02:51:e9:0f:
- 64:4f:e7:c9:f7:b6:63:fb:b3:d9:90:b3:18:a0:01:59:73:44:
- c3:bf:ea:96:a9:9b:71:ef:78:c5:ba:82:30:15:5f:b6:20:3e:
- ed:57:c4:8b:50:5f:44:8f:41:1e:63:9d:5c:a1:b1:87:d1:96:
- da:21:21:ac:91:16:66:3a:c8:ca:84:c1:47:52:9f:55:e3:09:
- 82:38:c7:ca:e3:8b:c0:10:e2:d0:aa:c6:b8:de:b8:39:80:8d:
- 49:37:1a:17:7a:90:8e:66:b7:b5:61:c0:85:13:86:ef:37:03:
- 2e:77:ba:8a:eb:3c:82:be:0a:27:51:5e:33:ec:92:33:5d:f5:
- cf:ed:43:79:41:f5:6e:0f:54:80:a7:a4:a2:bc:84:c5:36:1c:
- 5e:f5:19:b4:89:31:7b:c4:38:54:09:b1:a5:7c:b7:18:95:fc:
- e1:bf:86:42:fc:0b:41:4c:4a:fd:0b:4c:5d:db:c6:11:a7:0d:
- 99:07:e9:22
+ 22:eb:19:0b:53:ae:ac:05:af:4f:70:28:c5:ae:8b:c4:6e:d7:
+ 2a:7a:58:a4:44:7b:46:be:6e:01:6c:b6:d0:15:48:51:10:c7:
+ 27:ae:8a:de:52:82:91:70:36:dd:d7:55:ac:52:b2:c8:33:53:
+ fc:a1:e3:c1:80:6b:e6:46:fb:9c:0d:09:bf:91:c2:ee:25:77:
+ 39:69:7c:d2:f1:95:f0:2d:1e:fd:52:eb:1a:38:60:34:db:f4:
+ 43:a2:18:a9:b7:25:14:53:1a:1f:42:97:ab:25:7c:bb:25:88:
+ 56:fe:ac:d3:6f:5c:fe:90:e4:99:83:91:74:c0:dc:bb:a2:54:
+ 91:16:dd:d9:12:a5:22:6f:7a:1e:18:ab:54:63:18:4d:79:7c:
+ cb:16:78:04:2c:4d:32:13:2c:21:30:c9:22:b3:c7:41:7d:85:
+ 0f:9f:91:13:88:dd:b6:35:2e:de:a4:b7:72:d3:a0:f1:64:1c:
+ 30:b9:65:9e:4f:f3:5b:2b:7d:42:7b:7c:21:54:bf:c2:b0:02:
+ 2f:4e:10:2d:40:11:08:70:36:5c:66:e9:b6:3b:6a:9f:dd:7f:
+ f9:42:04:d0:8c:3c:93:54:5d:9f:d2:34:c4:67:d7:7c:ee:3f:
+ 22:4f:71:86:af:b1:79:6f:00:b4:65:60:58:ed:ef:16:cd:e5:
+ 97:e0:b8:49
-----BEGIN CERTIFICATE-----
-MIIDUDCCAjigAwIBAgIBBDANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0
-IFJvb3QgQ0EwHhcNMTQwODE0MDMwNTI5WhcNMjQwODExMDMwNTI5WjAbMRkwFwYD
+MIIDfTCCAmWgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0
+IFJvb3QgQ0EwHhcNMTUxMjIxMjAzNTQ3WhcNMjUxMjE4MjAzNTQ3WjAbMRkwFwYD
VQQDExBMZWFmIENlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAtfj0Mtj19GXK6dDL3emXoW6Q4vSyshbQm+KZV+17xltvScGUAKkNXbU1
-9Dp7PBgGo3haaP+mBR99EAiuCWzc7924l55szsug3DMrHpXvHfvT2vg+V+2Ljp6G
-TRKmDDAj7whFTyESQoiHAdilMp+3OO9grbdHaztLplwrVnJc0bU4h5nsO//GAu+G
-OO7iBcbwZuIYkVDlVyMnmbvbSSSIZqgUln4abSrh/xj1ajfSiKh5yblQ9ZpoCwSe
-aAIdoXHgiRW6KkgGenjT0Qx3g5iD+LniYCCSB5vUyMD6WlqdJkDCNWUA86Di0yFN
-pcSRiJAUp173E7fqK6K914QYGrd7XQIDAQABo4GiMIGfMAwGA1UdEwEB/wQCMAAw
-HQYDVR0OBBYEFIIEHb0FcYNv9pgZTU8RRohNm7+oMB8GA1UdIwQYMBaAFLz3MNE8
-wPJ5+u+fyWxck/OKaKuDMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAw
-BgNVHREEKTAnghB0ZXN0LkV4QW1QbEUuQ29NghNleGFtcGxlLm5vdGFyZWFsdGxk
-MA0GCSqGSIb3DQEBCwUAA4IBAQA2z/AK9ulrMCvSRhvI5E3SK00ORcjgk4O78zfC
-gWX96sxyGPYLYKOgfYDKKKxh7L074oAiL0BvoA8zPHMxWD4WrYJp/gJR6Q9kT+fJ
-97Zj+7PZkLMYoAFZc0TDv+qWqZtx73jFuoIwFV+2ID7tV8SLUF9Ej0EeY51cobGH
-0ZbaISGskRZmOsjKhMFHUp9V4wmCOMfK44vAEOLQqsa43rg5gI1JNxoXepCOZre1
-YcCFE4bvNwMud7qK6zyCvgonUV4z7JIzXfXP7UN5QfVuD1SAp6SivITFNhxe9Rm0
-iTF7xDhUCbGlfLcYlfzhv4ZC/AtBTEr9C0xd28YRpw2ZB+ki
+CgKCAQEAw+Ztc7I1MGo6LTROu6C9y59Ro+XTiMvObuIkuGwNvft1QqQ6RUm/Kvmr
+SoCuFTOB+NYGeIpZOk+DcG4dM/Tw0ASB/LOWHdF5Kn9yYtEg0bKgZ/pENgVyh47q
+d+JUKwoCdgT6KpXvQI/iXWdpo5wgdguRPIrfAWM4q2gnbFywvMEQQ6FhYupWjzLh
+HfddLk2mr+PzGd8ukgSS5vkNFEV5uXeZrKiuyrgFZYGA3Z80tYkTYhh9nz1PzR8N
+TTLCcjOW9zBMLu9mA85sUvUE6QKeb1T8SmzCIRqpFWaXHxFZAeBTGWLngCba++tX
+VIc2UkhqAd/w+eHIIXOpcvR8kh7xQwIDAQABo4HPMIHMMAwGA1UdEwEB/wQCMAAw
+HQYDVR0OBBYEFGSt9fNLLXA6E7cN1o+fgjfDWHOoMB8GA1UdIwQYMBaAFLz3MNE8
+wPJ5+u+fyWxck/OKaKuDMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBd
+BgNVHREEVjBUghB0ZXN0LkV4QW1QbEUuQ29NghNleGFtcGxlLm5vdGFyZWFsdGxk
+ghMqLnRlc3QyLkV4QW1QbEUuQ29NghYqLmV4YW1wbGUyLm5vdGFyZWFsdGxkMA0G
+CSqGSIb3DQEBCwUAA4IBAQAi6xkLU66sBa9PcCjFrovEbtcqelikRHtGvm4BbLbQ
+FUhREMcnroreUoKRcDbd11WsUrLIM1P8oePBgGvmRvucDQm/kcLuJXc5aXzS8ZXw
+LR79UusaOGA02/RDohiptyUUUxofQperJXy7JYhW/qzTb1z+kOSZg5F0wNy7olSR
+Ft3ZEqUib3oeGKtUYxhNeXzLFngELE0yEywhMMkis8dBfYUPn5ETiN22NS7epLdy
+06DxZBwwuWWeT/NbK31Ce3whVL/CsAIvThAtQBEIcDZcZum2O2qf3X/5QgTQjDyT
+VF2f0jTEZ9d87j8iT3GGr7F5bwC0ZWBY7e8WzeWX4LhJ
-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic_test.example.com.key.sct b/chromium/net/data/ssl/certificates/quic_test.example.com.key.sct
new file mode 100644
index 00000000000..55b0b42b414
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/quic_test.example.com.key.sct
@@ -0,0 +1 @@
+fake sct for test.example.com
diff --git a/chromium/net/data/ssl/certificates/sha1_dec_2015.pem b/chromium/net/data/ssl/certificates/sha1_dec_2015.pem
new file mode 100644
index 00000000000..b5047d27954
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/sha1_dec_2015.pem
@@ -0,0 +1,82 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 8 (0x8)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Test Root CA
+ Validity
+ Not Before: Dec 31 23:59:59 2015 GMT
+ Not After : Dec 30 00:00:00 2016 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:da:6a:85:4f:e5:d7:73:82:af:a2:1e:85:49:d0:
+ a9:ef:65:b9:29:e3:1d:32:d0:33:10:0d:67:a8:7d:
+ 22:d1:99:c1:c9:ab:e5:3e:06:9b:63:62:81:60:26:
+ 9c:70:b4:92:65:95:46:b2:fd:ad:e5:19:b1:30:6d:
+ a5:00:7d:d8:4d:b3:e7:b6:a5:83:da:be:26:79:ee:
+ 58:0a:f8:dd:8a:ae:13:db:f7:9a:8a:2b:eb:9f:15:
+ 53:5d:ce:18:ac:03:f2:ed:30:f4:8c:af:d6:7e:76:
+ 97:aa:97:c4:24:a5:7e:28:dc:dc:22:ea:86:54:4f:
+ 15:bf:03:81:11:ea:f9:ca:17:db:5a:b8:f0:3d:1a:
+ a5:c9:96:1b:d3:ed:99:ba:7a:55:e3:fa:9e:61:54:
+ 61:75:16:79:22:10:e9:e6:5a:b5:6b:b5:9d:32:bb:
+ e8:10:de:66:d7:1a:59:6f:d7:42:bf:80:b5:b2:73:
+ b9:a1:0b:5d:fe:0f:a1:6c:fc:de:99:d2:b3:ae:13:
+ d6:7f:f3:a9:7e:c0:07:f1:e4:a2:27:1b:1f:6d:81:
+ 86:b4:0f:f7:2b:9a:3c:7b:76:dc:5d:3a:b0:9e:b7:
+ 64:5f:53:33:08:3a:51:77:df:d1:91:b5:54:b8:4e:
+ 7a:0c:29:d1:40:cb:47:a4:cc:3b:b4:6e:a2:4d:91:
+ 6b:75
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 16:04:CF:CB:65:43:70:72:46:1E:83:5B:87:5E:10:CB:CB:69:B2:60
+ X509v3 Authority Key Identifier:
+ keyid:6C:29:1B:65:A9:3F:B8:19:9A:0F:FC:77:D6:95:55:2A:F2:4B:74:E6
+
+ 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
+ 58:b4:e7:31:15:4f:c4:70:1e:51:c6:ae:c3:47:3d:e8:17:92:
+ b9:8e:3b:76:c4:38:98:f7:c9:6e:be:0b:6a:2c:9d:fb:29:37:
+ e5:a7:4a:33:56:b5:2b:38:37:3e:65:8c:32:97:26:cf:47:94:
+ 1c:35:d1:8b:83:67:33:60:35:ed:8d:84:51:21:84:fe:15:4b:
+ 31:6d:6c:df:b2:24:ad:25:cd:f2:40:c5:bf:68:d8:62:db:ad:
+ d3:05:4b:71:0a:83:f5:12:d1:49:47:c5:44:a5:a5:08:1d:26:
+ 35:a2:2e:42:f1:06:4d:79:8a:54:95:51:54:a7:d3:aa:33:86:
+ ab:c7:5f:81:03:76:c1:c3:61:9a:9f:d9:a4:0c:6e:9f:31:40:
+ 0a:ee:b7:ae:e4:4a:17:aa:79:9c:17:1b:d4:49:65:52:57:f4:
+ 52:bb:e4:12:0e:b0:1a:65:c4:8d:e4:02:26:ff:43:42:87:53:
+ 7c:4b:10:7d:19:14:a9:c8:b7:9e:9a:e6:54:c1:f9:9e:2e:57:
+ 58:8e:37:3b:66:25:ce:1c:5c:7c:55:e1:0c:3a:dc:ac:46:48:
+ e2:d6:f5:c9:dd:36:c3:4f:75:df:06:af:e4:dc:21:fd:73:14:
+ 6d:51:1c:2d:b3:15:2e:1c:fb:b4:b9:b4:01:1f:82:ae:1d:20:
+ 3d:5f:25:98
+-----BEGIN CERTIFICATE-----
+MIIDczCCAlugAwIBAgIBCDANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0
+IFJvb3QgQ0EwHhcNMTUxMjMxMjM1OTU5WhcNMTYxMjMwMDAwMDAwWjBgMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2mqFT+XXc4Kvoh6FSdCp72W5KeMd
+MtAzEA1nqH0i0ZnByavlPgabY2KBYCaccLSSZZVGsv2t5RmxMG2lAH3YTbPntqWD
+2r4mee5YCvjdiq4T2/eaiivrnxVTXc4YrAPy7TD0jK/WfnaXqpfEJKV+KNzcIuqG
+VE8VvwOBEer5yhfbWrjwPRqlyZYb0+2ZunpV4/qeYVRhdRZ5IhDp5lq1a7WdMrvo
+EN5m1xpZb9dCv4C1snO5oQtd/g+hbPzemdKzrhPWf/OpfsAH8eSiJxsfbYGGtA/3
+K5o8e3bcXTqwnrdkX1MzCDpRd9/RkbVUuE56DCnRQMtHpMw7tG6iTZFrdQIDAQAB
+o4GAMH4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUFgTPy2VDcHJGHoNbh14Qy8tp
+smAwHwYDVR0jBBgwFoAUbCkbZak/uBmaD/x31pVVKvJLdOYwHQYDVR0lBBYwFAYI
+KwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEL
+BQADggEBAFi05zEVT8RwHlHGrsNHPegXkrmOO3bEOJj3yW6+C2osnfspN+WnSjNW
+tSs4Nz5ljDKXJs9HlBw10YuDZzNgNe2NhFEhhP4VSzFtbN+yJK0lzfJAxb9o2GLb
+rdMFS3EKg/US0UlHxUSlpQgdJjWiLkLxBk15ilSVUVSn06ozhqvHX4EDdsHDYZqf
+2aQMbp8xQArut67kSheqeZwXG9RJZVJX9FK75BIOsBplxI3kAib/Q0KHU3xLEH0Z
+FKnIt56a5lTB+Z4uV1iONztmJc4cXHxV4Qw63KxGSOLW9cndNsNPdd8Gr+TcIf1z
+FG1RHC2zFS4c+7S5tAEfgq4dID1fJZg=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/sha1_jan_2016.pem b/chromium/net/data/ssl/certificates/sha1_jan_2016.pem
new file mode 100644
index 00000000000..efb9b016d14
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/sha1_jan_2016.pem
@@ -0,0 +1,82 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 9 (0x9)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Test Root CA
+ Validity
+ Not Before: Jan 1 00:00:00 2016 GMT
+ Not After : Dec 30 00:00:00 2016 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:b6:93:55:29:0f:ea:d2:34:c0:71:6b:df:b4:f6:
+ 9f:12:72:65:e1:0c:ac:1a:7d:ab:3e:76:2e:64:5a:
+ 02:c7:bc:61:bd:1e:ed:f3:eb:30:76:bd:44:48:d0:
+ 15:fc:8b:f3:c5:bc:06:18:c2:8e:7b:99:a1:bc:f1:
+ 24:d4:17:05:39:51:bc:cc:1f:39:c7:0a:67:3b:76:
+ 8b:23:3f:9a:df:a9:21:70:71:17:40:c3:6f:b0:a2:
+ ea:7b:e3:64:94:08:cd:4b:66:a4:00:27:2f:af:8e:
+ ce:99:4c:c6:21:c6:4a:05:5e:08:17:41:3a:d4:31:
+ a0:bc:a0:0a:2e:a1:b2:ff:08:d9:11:a6:40:fc:f0:
+ 0f:3e:9c:31:de:32:4b:23:c2:b8:d4:a3:2c:81:84:
+ e7:64:c7:25:3b:e9:8e:aa:6c:7f:13:8a:66:35:2d:
+ a6:3c:07:95:7f:26:75:16:24:c0:92:6e:cf:f3:c3:
+ 19:f4:66:f9:23:4f:75:de:2f:a5:cd:1a:15:94:23:
+ 8c:68:bc:32:74:1d:21:fa:5f:c9:88:48:9a:08:c7:
+ 1e:9c:31:27:fb:8e:d7:01:72:6e:60:bb:b4:b6:f3:
+ d8:8b:6c:97:6c:ec:a0:42:b6:48:02:f1:f1:b7:15:
+ 0d:84:e5:96:64:9e:f4:59:a1:4f:df:cb:e6:58:51:
+ bf:d7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ A6:36:4C:FB:11:3E:B2:79:D1:1F:94:96:A1:F0:14:03:01:BB:09:CE
+ X509v3 Authority Key Identifier:
+ keyid:6C:29:1B:65:A9:3F:B8:19:9A:0F:FC:77:D6:95:55:2A:F2:4B:74:E6
+
+ 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
+ 6c:76:f5:b4:56:92:77:34:99:32:47:05:9b:23:93:8e:82:29:
+ d9:cd:7f:e8:81:65:19:4a:db:6c:c7:c3:ef:7d:47:43:30:24:
+ 58:8a:9b:63:b6:88:d5:c4:57:09:89:79:ce:ac:4a:e2:bf:e5:
+ 87:1e:5d:e5:99:37:b6:af:96:7b:0c:a4:6c:ff:1c:65:eb:36:
+ cd:5f:74:53:e9:28:ef:72:e1:9f:b6:b5:aa:0f:8f:60:91:f7:
+ 79:62:85:d1:b2:19:84:26:9d:ff:e0:20:4c:71:7d:72:12:10:
+ 7e:83:4e:e1:c5:6a:a7:d2:5c:c2:c4:ac:33:e1:02:c5:74:d3:
+ 79:57:cd:8b:89:a2:17:b2:9a:97:83:ce:8a:b3:ae:50:e4:99:
+ d7:af:96:d2:d8:57:72:d3:22:67:17:52:7d:f0:4d:d3:48:95:
+ 5a:ef:8a:d4:1d:43:bd:3b:65:49:5b:70:da:7f:2e:8a:aa:e0:
+ b5:ed:6d:8f:d0:1d:7a:cc:ee:c7:47:dc:66:de:cf:b0:19:07:
+ 3f:44:d6:ce:db:1d:b1:1a:3e:54:60:16:93:df:85:76:62:9d:
+ 0e:fa:27:1c:bd:6f:fe:20:9b:34:4a:b6:f8:f9:52:c4:bb:22:
+ 92:01:69:8e:5b:da:0f:b9:f6:63:89:3f:f2:58:bc:59:9e:3d:
+ 58:c6:fe:db
+-----BEGIN CERTIFICATE-----
+MIIDczCCAlugAwIBAgIBCTANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0
+IFJvb3QgQ0EwHhcNMTYwMTAxMDAwMDAwWhcNMTYxMjMwMDAwMDAwWjBgMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtpNVKQ/q0jTAcWvftPafEnJl4Qys
+Gn2rPnYuZFoCx7xhvR7t8+swdr1ESNAV/IvzxbwGGMKOe5mhvPEk1BcFOVG8zB85
+xwpnO3aLIz+a36khcHEXQMNvsKLqe+NklAjNS2akACcvr47OmUzGIcZKBV4IF0E6
+1DGgvKAKLqGy/wjZEaZA/PAPPpwx3jJLI8K41KMsgYTnZMclO+mOqmx/E4pmNS2m
+PAeVfyZ1FiTAkm7P88MZ9Gb5I0913i+lzRoVlCOMaLwydB0h+l/JiEiaCMcenDEn
++47XAXJuYLu0tvPYi2yXbOygQrZIAvHxtxUNhOWWZJ70WaFP38vmWFG/1wIDAQAB
+o4GAMH4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUpjZM+xE+snnRH5SWofAUAwG7
+Cc4wHwYDVR0jBBgwFoAUbCkbZak/uBmaD/x31pVVKvJLdOYwHQYDVR0lBBYwFAYI
+KwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEL
+BQADggEBAGx29bRWknc0mTJHBZsjk46CKdnNf+iBZRlK22zHw+99R0MwJFiKm2O2
+iNXEVwmJec6sSuK/5YceXeWZN7avlnsMpGz/HGXrNs1fdFPpKO9y4Z+2taoPj2CR
+93lihdGyGYQmnf/gIExxfXISEH6DTuHFaqfSXMLErDPhAsV003lXzYuJoheympeD
+zoqzrlDkmdevltLYV3LTImcXUn3wTdNIlVrvitQdQ707ZUlbcNp/Loqq4LXtbY/Q
+HXrM7sdH3Gbez7AZBz9E1s7bHbEaPlRgFpPfhXZinQ76Jxy9b/4gmzRKtvj5UsS7
+IpIBaY5b2g+59mOJP/JYvFmePVjG/ts=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/wildcard.pem b/chromium/net/data/ssl/certificates/wildcard.pem
new file mode 100644
index 00000000000..6c047849ec9
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/wildcard.pem
@@ -0,0 +1,110 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDfhiVHagGcPZTL
+4aHOnMXM4dYquwuCgl322Pn1H7KXj+zmaWna8ZzP2i9Zp4++aGoSk0ZMxdgMCSrq
+ayCQS6n0Fm5ouEK2dz2EbEWjLMEX4+PRP7Vkh1tE7yS6oQpEGK1nApCSyDqfhmIU
+C5G9o5GupqC3WrIOwAPvpDiEKLpAExetEf7IZd415Tj6yq2umyWzxbYUwqSI0fUv
+0BY84C+2vaVhPNqv5jCSHBW8ueR+gnIto9vkq6JfOp4yuJ1ufqSdpt67gYskieJw
+sBZmyZ3FQYlKj35lPhOnWbRpPTG0L5IhMCRsJ/qR1h2Hrs+dU4+hyLyZpdqic0wL
+3UQnpKtPAgMBAAECggEACpATSOmog9KhKnVSKSpdao4tib1nENbKS/T68ut5jBIA
+Fu9aUj9isqvT2v/BGjVi9dfB1bTvvbndLlC7rDX3JRK+SvKSLH88B/r523ks8s0R
+If1JvCNtW7eVW8BqdMdZwmlrnZQauRknn1zgmT6WjtNO+vstOOc4CGYRSaWHD6oA
+rpg23vKm8JbYLACnlQBgDr/fhHN0PLWrsLEFTYSfvFz8+B//2Rslj4/mJhEfu+aG
+Nr0N6HqIrgzTZarI0nhst9PTJuOMBjyJIByV6T8hchOgLqWqvtTnXq3U4GLsbTh2
+vvKIndORecZV29y+VqIiJLch+OFg4uDR8yqMQndvyQKBgQD5ZRc9YLmXlXPS1PsV
+5mix54ZiX70jm4ZwSmDlX3XboEyJrxJJ0EefqSDz1HxMObzWdPs+dT8JzUezU7ha
+sBpCDY++rj1UUZbOqCmiU3xdpWVea02xCjAhGO43XErnu5FCmyL4xCTSm48t0w01
+3jH9WanO9I3OjngNHawYyarPQwKBgQDlcaYnubY0Vro+JxCuYHYlggYaj9OaNSJ8
+hH9PZ6FG3O7OusP8fSvHKNbzdGkXO72UrGcYJGoaYbdIPKP4k3iJ43M1+wX6VZb2
+ohylWuHmVn4pMkLC+1zKASLd1AKBgdgX2+mpmfHa5Nnv7+6KgYKNAQKE1IMcq++a
+2aateUd1BQKBgQCKFjYi7u50BvVFlFWeD6CCeL5Is9fm4lMy04wJFK0OORiH157Z
+rfAqcBvlxg44qnNrjwQZ1hNcWwRLP5zA4eb4Ecg4fQNKL46/yA6daXpf45dYCzPO
+ReTWPpaPopN68bkBVyKq+PemgSlq5wPWgrvNGptSEsh9yRahtH84jlj8PwKBgGL8
+nwRweI0oBX2e+PFiKFaSO/PlrRLQbaput0YYnVmnI1gI91jM38AyfFnYFSay3V1w
+66FcxHHRSnNdxhgN92j1udTGEZQorNKGqfkktmTbV96KEodwTl3QE6zENLiOvh29
+AJftFIytQuDjEHSs3xfaIa4QyOfrvZl+4QviUNPJAoGAe8cNgvKPVSEZjt+/tW0K
+LPCOZxDsBgwIWcpxFpzTigdw/4AKedccwp0vMRaj44gzKDCVxgnU3qPBEGHqLOAs
+UcV6KEVQrIupPB8ix8y1qpiRsrDqhEcNRyDcTJEaPgjOfNKw80lstromo6dmrpFe
+cO+alA7DDyg+545GrCsgy/Q=
+-----END PRIVATE KEY-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 12 (0xc)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Test Root CA
+ Validity
+ Not Before: Dec 30 20:30:57 2015 GMT
+ Not After : Dec 27 20:30:57 2025 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:df:86:25:47:6a:01:9c:3d:94:cb:e1:a1:ce:9c:
+ c5:cc:e1:d6:2a:bb:0b:82:82:5d:f6:d8:f9:f5:1f:
+ b2:97:8f:ec:e6:69:69:da:f1:9c:cf:da:2f:59:a7:
+ 8f:be:68:6a:12:93:46:4c:c5:d8:0c:09:2a:ea:6b:
+ 20:90:4b:a9:f4:16:6e:68:b8:42:b6:77:3d:84:6c:
+ 45:a3:2c:c1:17:e3:e3:d1:3f:b5:64:87:5b:44:ef:
+ 24:ba:a1:0a:44:18:ad:67:02:90:92:c8:3a:9f:86:
+ 62:14:0b:91:bd:a3:91:ae:a6:a0:b7:5a:b2:0e:c0:
+ 03:ef:a4:38:84:28:ba:40:13:17:ad:11:fe:c8:65:
+ de:35:e5:38:fa:ca:ad:ae:9b:25:b3:c5:b6:14:c2:
+ a4:88:d1:f5:2f:d0:16:3c:e0:2f:b6:bd:a5:61:3c:
+ da:af:e6:30:92:1c:15:bc:b9:e4:7e:82:72:2d:a3:
+ db:e4:ab:a2:5f:3a:9e:32:b8:9d:6e:7e:a4:9d:a6:
+ de:bb:81:8b:24:89:e2:70:b0:16:66:c9:9d:c5:41:
+ 89:4a:8f:7e:65:3e:13:a7:59:b4:69:3d:31:b4:2f:
+ 92:21:30:24:6c:27:fa:91:d6:1d:87:ae:cf:9d:53:
+ 8f:a1:c8:bc:99:a5:da:a2:73:4c:0b:dd:44:27:a4:
+ ab:4f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 07:AA:23:37:A2:23:9D:E6:7C:C8:28:0E:5B:F7:E0:46:A7:B9:F7:A9
+ X509v3 Authority Key Identifier:
+ keyid:BC:F7:30:D1:3C:C0:F2:79:FA:EF:9F:C9:6C:5C:93:F3:8A:68:AB:83
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Subject Alternative Name:
+ DNS:*.example.org
+ Signature Algorithm: sha256WithRSAEncryption
+ 35:09:35:43:ec:28:b2:fb:91:25:ef:70:8d:77:58:3e:4b:ec:
+ 59:3e:53:d7:1f:2c:bc:9c:d7:77:4d:82:93:b5:07:06:cb:9e:
+ dd:3d:0b:77:22:46:7f:d1:87:80:8b:04:ca:9b:97:13:0c:f1:
+ b7:ed:cf:07:f2:5e:cc:cb:63:57:6e:c8:10:de:1d:25:ce:dd:
+ 0c:64:35:43:92:9e:59:03:57:b5:04:25:74:4a:40:26:e7:df:
+ 99:4e:de:05:13:be:d7:91:b8:72:e0:ea:09:32:58:e3:b7:4f:
+ 55:b6:fb:8d:26:31:54:ac:1b:c7:97:34:7a:73:f2:95:5a:ab:
+ 54:48:80:19:50:a1:f2:ce:89:3f:06:1a:2c:48:c1:11:7e:62:
+ 00:c4:ec:41:7d:5e:6c:9b:81:c8:21:1a:8a:2b:38:dc:8d:36:
+ c7:e0:e2:f5:20:68:6f:f5:af:ab:62:ec:d8:10:6f:99:b7:f4:
+ 9a:94:ec:5a:2b:5e:00:62:96:ac:2c:19:b8:dc:ee:c0:da:f9:
+ 10:50:9f:1f:2a:80:46:68:9f:f5:95:5f:7e:f8:de:ce:3e:b5:
+ f1:0b:09:55:c0:09:9f:fb:65:07:41:85:a7:6e:7d:04:fb:25:
+ 85:dc:c2:d6:4d:0b:00:12:11:be:4c:c1:c2:4a:7d:b4:47:19:
+ 51:76:9e:f7
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAmWgAwIBAgIBDDANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0
+IFJvb3QgQ0EwHhcNMTUxMjMwMjAzMDU3WhcNMjUxMjI3MjAzMDU3WjBgMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA34YlR2oBnD2Uy+GhzpzFzOHWKrsL
+goJd9tj59R+yl4/s5mlp2vGcz9ovWaePvmhqEpNGTMXYDAkq6msgkEup9BZuaLhC
+tnc9hGxFoyzBF+Pj0T+1ZIdbRO8kuqEKRBitZwKQksg6n4ZiFAuRvaORrqagt1qy
+DsAD76Q4hCi6QBMXrRH+yGXeNeU4+sqtrpsls8W2FMKkiNH1L9AWPOAvtr2lYTza
+r+YwkhwVvLnkfoJyLaPb5KuiXzqeMridbn6knabeu4GLJInicLAWZsmdxUGJSo9+
+ZT4Tp1m0aT0xtC+SITAkbCf6kdYdh67PnVOPoci8maXaonNMC91EJ6SrTwIDAQAB
+o4GKMIGHMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFAeqIzeiI53mfMgoDlv34Ean
+ufepMB8GA1UdIwQYMBaAFLz3MNE8wPJ5+u+fyWxck/OKaKuDMB0GA1UdJQQWMBQG
+CCsGAQUFBwMBBggrBgEFBQcDAjAYBgNVHREEETAPgg0qLmV4YW1wbGUub3JnMA0G
+CSqGSIb3DQEBCwUAA4IBAQA1CTVD7Ciy+5El73CNd1g+S+xZPlPXHyy8nNd3TYKT
+tQcGy57dPQt3IkZ/0YeAiwTKm5cTDPG37c8H8l7My2NXbsgQ3h0lzt0MZDVDkp5Z
+A1e1BCV0SkAm59+ZTt4FE77Xkbhy4OoJMljjt09VtvuNJjFUrBvHlzR6c/KVWqtU
+SIAZUKHyzok/BhosSMERfmIAxOxBfV5sm4HIIRqKKzjcjTbH4OL1IGhv9a+rYuzY
+EG+Zt/SalOxaK14AYpasLBm43O7A2vkQUJ8fKoBGaJ/1lV9++N7OPrXxCwlVwAmf
++2UHQYWnbn0E+yWF3MLWTQsAEhG+TMHCSn20RxlRdp73
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/scripts/ca.cnf b/chromium/net/data/ssl/scripts/ca.cnf
index 1b78e01985e..28778a3dd7f 100644
--- a/chromium/net/data/ssl/scripts/ca.cnf
+++ b/chromium/net/data/ssl/scripts/ca.cnf
@@ -59,6 +59,8 @@ DNS.2 = test.ExAmPlE.OrG
[san_name_constraint_good]
DNS.1 = test.ExAmPlE.CoM
DNS.2 = example.notarealtld
+DNS.3 = *.test2.ExAmPlE.CoM
+DNS.4 = *.example2.notarealtld
[ca_cert]
# Extensions to add when signing a request for an intermediate/CA cert
diff --git a/chromium/net/data/ssl/scripts/ee.cnf b/chromium/net/data/ssl/scripts/ee.cnf
index 0151613049f..5bf4e46baa0 100644
--- a/chromium/net/data/ssl/scripts/ee.cnf
+++ b/chromium/net/data/ssl/scripts/ee.cnf
@@ -60,6 +60,9 @@ dirName = more_san_sanity
[req_spdy_pooling]
subjectAltName = @spdy_pooling
+[req_wildcard]
+subjectAltName = @wildcard
+
[more_san_sanity]
CN=127.0.0.3
@@ -72,3 +75,6 @@ DNS.3 = mail.example.com
DNS.1 = xn--wgv71a119e.com
DNS.2 = *.xn--wgv71a119e.com
DNS.3 = blahblahblahblah.com
+
+[wildcard]
+DNS.1 = *.example.org
diff --git a/chromium/net/data/ssl/scripts/generate-test-certs.sh b/chromium/net/data/ssl/scripts/generate-test-certs.sh
index d777718ccca..13586531b8c 100755
--- a/chromium/net/data/ssl/scripts/generate-test-certs.sh
+++ b/chromium/net/data/ssl/scripts/generate-test-certs.sh
@@ -50,6 +50,13 @@ try openssl req \
-out out/ok_cert.req \
-config ee.cnf
+try openssl req \
+ -new \
+ -keyout out/wildcard.key \
+ -out out/wildcard.req \
+ -reqexts req_wildcard \
+ -config ee.cnf
+
SUBJECT_NAME=req_localhost_cn \
try openssl req \
-new \
@@ -81,6 +88,15 @@ CA_COMMON_NAME="Test Root CA" \
CA_COMMON_NAME="Test Root CA" \
try openssl ca \
-batch \
+ -extensions user_cert \
+ -days 3650 \
+ -in out/wildcard.req \
+ -out out/wildcard.pem \
+ -config ca.cnf
+
+CA_COMMON_NAME="Test Root CA" \
+ try openssl ca \
+ -batch \
-extensions name_constraint_bad \
-subj "/CN=Leaf certificate/" \
-days 3650 \
@@ -120,6 +136,8 @@ CA_COMMON_NAME="Test Root CA" \
try /bin/sh -c "cat out/ok_cert.key out/ok_cert.pem \
> ../certificates/ok_cert.pem"
+try /bin/sh -c "cat out/wildcard.key out/wildcard.pem \
+ > ../certificates/wildcard.pem"
try /bin/sh -c "cat out/localhost_cert.key out/localhost_cert.pem \
> ../certificates/localhost_cert.pem"
try /bin/sh -c "cat out/expired_cert.key out/expired_cert.pem \
@@ -164,9 +182,9 @@ SUBJECT_NAME="req_dn" \
-out ../certificates/reject_intranet_hosts.pem
## Leaf certificate with a large key; Apple's certificate verifier rejects with
-## a fatal error if the key is bigger than 4096 bits.
+## a fatal error if the key is bigger than 8192 bits.
try openssl req -x509 -days 3650 \
- -config ../scripts/ee.cnf -newkey rsa:4104 -text \
+ -config ../scripts/ee.cnf -newkey rsa:8200 -text \
-sha256 \
-out ../certificates/large_key.pem
@@ -183,6 +201,32 @@ CA_COMMON_NAME="Test Root CA" \
-out ../certificates/sha1_2016.pem \
-config ca.cnf
+## SHA1 certificate issued the last second before the SHA-1 deprecation date.
+try openssl req -config ../scripts/ee.cnf -sha1 \
+ -newkey rsa:2048 -text -out out/sha1_dec_2015.req
+CA_COMMON_NAME="Test Root CA" \
+ try openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 151231235959Z \
+ -enddate 161230000000Z \
+ -in out/sha1_dec_2015.req \
+ -out ../certificates/sha1_dec_2015.pem \
+ -config ca.cnf
+
+## SHA1 certificate issued on the SHA-1 deprecation date.
+try openssl req -config ../scripts/ee.cnf -sha1 \
+ -newkey rsa:2048 -text -out out/sha1_jan_2016.req
+CA_COMMON_NAME="Test Root CA" \
+ try openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 160101000000Z \
+ -enddate 161230000000Z \
+ -in out/sha1_jan_2016.req \
+ -out ../certificates/sha1_jan_2016.pem \
+ -config ca.cnf
+
## Validity too long unit test support.
try openssl req -config ../scripts/ee.cnf \
-newkey rsa:2048 -text -out ../certificates/10_year_validity.req
diff --git a/chromium/net/data/verify_certificate_chain_unittest/README b/chromium/net/data/verify_certificate_chain_unittest/README
new file mode 100644
index 00000000000..11cc4cbef53
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/README
@@ -0,0 +1,29 @@
+This directory contains test data for verifying certificate chains.
+
+It contains the following types of files:
+
+===============================
+generate-*.py
+===============================
+
+Generates the file for an individual test case. If the python file was
+named generate-XXX.py, then the corresponding output will be named
+XXX.pem.
+
+===============================
+generate-all.sh
+===============================
+
+Runs all of the generate-*.py scripts and does some cleanup.
+
+===============================
+*.pem
+===============================
+
+These files descibe a test case for certificate chain verification.
+
+The input file is a PEM file with blocks for:
+ * The trust store
+ * The certificate chain (target certificate and all intermediaries)
+ * The timestamp to use when verifying
+ * The expected result of verification (success or fail)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem b/chromium/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem
new file mode 100644
index 00000000000..5ed112630f0
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem
@@ -0,0 +1,370 @@
+[Created by: generate-basic-constraints-pathlen-0-self-issued.py]
+
+Certificate chain with 2 intermediaries. The first intermediary has a basic
+constraints path length of 0. The second one is self-issued so does not count
+against the path length.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:cc:d5:1f:2f:97:16:d6:23:ca:d5:a1:c1:97:42:
+ 2b:7e:3e:7f:45:44:70:b9:8d:81:76:be:b4:69:56:
+ 78:a9:14:10:69:ad:60:8e:ed:80:b2:a2:f9:85:d6:
+ fe:4c:81:d0:30:8e:c8:75:48:29:48:b9:ad:9f:a9:
+ 83:b6:4f:c7:ba:40:f9:d5:66:9f:f9:51:48:72:0d:
+ 95:38:65:da:41:8a:91:4a:e1:34:d6:1c:a0:0b:ee:
+ 4d:07:69:0c:74:87:58:79:1b:e5:7b:51:ae:19:36:
+ b2:6a:a6:89:81:30:bd:51:c1:7f:99:86:63:78:48:
+ a6:8e:74:f6:5f:cc:fb:3f:12:ac:2e:e7:a8:75:15:
+ b7:5b:37:dd:ce:54:68:ae:0d:ad:80:13:b5:d7:06:
+ 98:39:a9:67:f9:fb:c1:7f:e0:f6:6b:14:f3:d3:b4:
+ f4:33:2c:41:9e:69:63:de:b3:f9:cd:4e:f8:58:98:
+ dd:6f:9b:9a:b7:82:19:c1:01:c9:2d:fb:d3:5a:48:
+ 5f:e4:e5:c5:6e:5f:b1:3b:31:49:65:f0:0d:46:a5:
+ 33:fb:57:23:fc:ca:17:51:72:fc:5a:f7:7c:44:74:
+ 24:3b:cc:54:2c:e3:d4:8b:e9:9c:13:da:78:58:a1:
+ d8:00:19:30:ee:3d:29:fb:2b:7a:79:b8:69:f2:3b:
+ d3:19
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 6D:49:C7:0A:DE:44:7C:B7:07:ED:87:EF:41:DE:5D:12:91:28:3D:1C
+ X509v3 Authority Key Identifier:
+ keyid:31:9F:A3:DB:EA:90:94:EB:3D:93:39:9F:BA:8A:05:7E:2C:94:23:9B
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 34:51:df:38:e9:c2:df:c6:2c:01:00:7e:a1:4b:5e:d1:43:8a:
+ d7:4e:ff:49:5d:17:e7:bd:e2:3c:cd:43:63:4d:a9:05:97:bf:
+ 76:e2:8d:90:d2:dd:ea:6b:4c:e3:1e:c1:7b:8b:35:5a:24:cc:
+ d8:b2:9a:12:07:d2:66:fa:fd:3c:79:b4:a7:d7:cb:69:af:07:
+ f7:9d:66:34:ee:ed:22:1f:7d:58:9e:e1:49:90:88:95:1e:27:
+ 2a:3d:dc:a9:b9:1d:2b:1f:88:b9:0c:89:a1:bc:dd:25:97:b9:
+ 32:0e:02:86:fa:a3:2c:cd:8e:29:e5:68:12:3b:5b:bf:0e:cc:
+ 25:ad:06:ef:77:26:d7:b4:84:cf:ba:00:55:c4:f0:95:39:88:
+ ff:22:f8:a5:89:8a:d2:31:aa:e7:98:76:02:19:bd:04:bc:5c:
+ 26:be:5e:eb:96:2b:f6:a2:cf:13:3e:a1:82:92:63:c0:13:bc:
+ b6:f9:06:fb:77:c3:0f:cd:39:b1:af:43:b5:9d:fc:64:d4:bd:
+ d0:81:5c:06:fb:8b:0e:c5:59:0b:07:d6:a7:8b:a9:8e:b3:6b:
+ f5:ed:9b:ea:ea:f7:6f:ea:2b:02:df:62:92:ae:98:fb:45:ca:
+ bc:1c:6b:eb:6d:33:e3:0e:32:0f:0d:e3:7f:5c:ef:e3:1b:c2:
+ f6:fc:99:a4
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDM1R8v
+lxbWI8rVocGXQit+Pn9FRHC5jYF2vrRpVnipFBBprWCO7YCyovmF1v5MgdAwjsh1
+SClIua2fqYO2T8e6QPnVZp/5UUhyDZU4ZdpBipFK4TTWHKAL7k0HaQx0h1h5G+V7
+Ua4ZNrJqpomBML1RwX+ZhmN4SKaOdPZfzPs/Eqwu56h1FbdbN93OVGiuDa2AE7XX
+Bpg5qWf5+8F/4PZrFPPTtPQzLEGeaWPes/nNTvhYmN1vm5q3ghnBAckt+9NaSF/k
+5cVuX7E7MUll8A1GpTP7VyP8yhdRcvxa93xEdCQ7zFQs49SL6ZwT2nhYodgAGTDu
+PSn7K3p5uGnyO9MZAgMBAAGjgekwgeYwHQYDVR0OBBYEFG1JxwreRHy3B+2H70He
+XRKRKD0cMB8GA1UdIwQYMBaAFDGfo9vqkJTrPZM5n7qKBX4slCObMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEANFHfOOnC38YsAQB+oUte
+0UOK107/SV0X573iPM1DY02pBZe/duKNkNLd6mtM4x7Be4s1WiTM2LKaEgfSZvr9
+PHm0p9fLaa8H951mNO7tIh99WJ7hSZCIlR4nKj3cqbkdKx+IuQyJobzdJZe5Mg4C
+hvqjLM2OKeVoEjtbvw7MJa0G73cm17SEz7oAVcTwlTmI/yL4pYmK0jGq55h2Ahm9
+BLxcJr5e65Yr9qLPEz6hgpJjwBO8tvkG+3fDD805sa9DtZ38ZNS90IFcBvuLDsVZ
+CwfWp4upjrNr9e2b6ur3b+orAt9ikq6Y+0XKvBxr620z4w4yDw3jf1zv4xvC9vyZ
+pA==
+-----END CERTIFICATE-----
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e6:56:91:e6:27:53:a1:d7:64:56:d8:c8:57:b7:
+ 55:7c:89:a2:b4:9d:ab:72:f0:bc:03:35:16:53:77:
+ 7e:ef:bf:0b:f5:91:d5:de:ae:bb:ae:ae:3a:53:00:
+ ec:80:3b:a0:2b:d3:6a:ae:0c:d0:4c:a1:24:b2:b4:
+ 77:de:ad:81:0f:70:f8:f4:dc:f8:c7:6e:f8:54:29:
+ 84:3a:b8:83:f4:95:22:80:ae:71:b0:dd:4e:ba:82:
+ 87:80:d1:c7:f3:ad:a7:45:c5:db:47:3c:8e:84:31:
+ bc:c6:bd:29:77:70:39:78:f4:3b:5e:ae:8f:d9:44:
+ 6b:1a:1d:cb:f9:7b:84:14:7c:5b:b8:82:3c:ed:47:
+ 16:c6:4e:2b:75:5a:1b:b4:5d:0c:0a:2f:55:b6:48:
+ 87:a1:25:a2:a9:5b:e4:a8:f9:bc:70:24:92:07:7f:
+ 5b:94:83:3b:44:78:65:cb:62:0c:30:fa:cf:f1:f7:
+ 20:9e:76:c8:52:78:8b:f8:30:62:f0:66:28:8a:7f:
+ ba:74:12:f8:05:ef:29:d8:17:cb:8a:95:61:fc:af:
+ 58:d2:e2:86:d7:8c:fb:3b:56:28:8d:e4:d9:27:48:
+ b6:c1:fc:9a:4e:d4:24:b8:68:c3:32:5d:65:30:6e:
+ a3:9e:b9:bf:6e:a7:3b:b4:3d:2e:5d:13:a1:28:4e:
+ a4:0d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 31:9F:A3:DB:EA:90:94:EB:3D:93:39:9F:BA:8A:05:7E:2C:94:23:9B
+ X509v3 Authority Key Identifier:
+ keyid:73:4C:95:45:4C:3B:F6:7E:7B:92:30:C9:AC:30:51:E7:7D:21:D2:BF
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ Signature Algorithm: sha256WithRSAEncryption
+ 0d:7d:a3:df:40:cd:02:79:b5:69:5d:c5:a7:eb:bc:87:95:c3:
+ 17:fc:73:dd:59:a8:c2:d3:67:71:15:09:7a:9b:f8:01:5d:a0:
+ d2:a3:e5:37:1d:f5:f3:2c:fd:8d:8e:e7:6c:ca:01:2a:83:a8:
+ 00:c9:65:26:8e:ab:0b:13:91:9c:00:9a:a3:60:44:8c:82:0f:
+ 04:1e:74:b1:c6:4f:a6:da:37:70:16:35:03:92:f2:04:ab:c8:
+ 21:97:a8:b4:e3:bf:bf:67:9e:ce:c3:24:df:6a:cc:43:d6:ea:
+ 59:89:b7:3e:1c:de:ed:ab:99:ec:26:60:3b:b7:84:4b:e0:1a:
+ b7:be:6d:20:7b:f4:88:a2:bf:95:3f:6e:7a:fa:ea:e1:55:72:
+ 88:ae:67:b3:13:1a:3a:1f:07:16:1d:84:fd:e5:e3:1e:90:ec:
+ dc:d2:ce:73:c0:50:19:69:10:dc:c7:db:91:46:f4:50:52:87:
+ 94:6e:ce:ef:a6:20:57:d2:ad:36:95:1e:94:7f:a3:8f:d9:0d:
+ 99:dd:8f:e3:2a:b2:2b:69:a0:f7:26:4e:cd:f2:f1:cf:05:14:
+ 31:3d:aa:71:01:dd:42:24:19:62:5c:00:1b:98:ac:7d:45:f2:
+ e6:14:dd:2e:10:06:74:39:61:6d:b9:3c:68:c1:e7:3d:b6:3d:
+ e1:75:c9:fd
+-----BEGIN CERTIFICATE-----
+MIIDiDCCAnCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjAXMRUwEwYD
+VQQDDAxJbnRlcm1lZGlhcnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDmVpHmJ1Oh12RW2MhXt1V8iaK0naty8LwDNRZTd37vvwv1kdXerruurjpTAOyA
+O6Ar02quDNBMoSSytHferYEPcPj03PjHbvhUKYQ6uIP0lSKArnGw3U66goeA0cfz
+radFxdtHPI6EMbzGvSl3cDl49Dtero/ZRGsaHcv5e4QUfFu4gjztRxbGTit1Whu0
+XQwKL1W2SIehJaKpW+So+bxwJJIHf1uUgztEeGXLYgww+s/x9yCedshSeIv4MGLw
+ZiiKf7p0EvgF7ynYF8uKlWH8r1jS4obXjPs7ViiN5NknSLbB/JpO1CS4aMMyXWUw
+bqOeub9upzu0PS5dE6EoTqQNAgMBAAGjgd4wgdswHQYDVR0OBBYEFDGfo9vqkJTr
+PZM5n7qKBX4slCObMB8GA1UdIwQYMBaAFHNMlUVMO/Z+e5IwyawwUed9IdK/MD8G
+CCsGAQUFBwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0lu
+dGVybWVkaWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3It
+Y3JsL0ludGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI
+MAYBAf8CAQAwDQYJKoZIhvcNAQELBQADggEBAA19o99AzQJ5tWldxafrvIeVwxf8
+c91ZqMLTZ3EVCXqb+AFdoNKj5Tcd9fMs/Y2O52zKASqDqADJZSaOqwsTkZwAmqNg
+RIyCDwQedLHGT6baN3AWNQOS8gSryCGXqLTjv79nns7DJN9qzEPW6lmJtz4c3u2r
+mewmYDu3hEvgGre+bSB79Iiiv5U/bnr66uFVcoiuZ7MTGjofBxYdhP3l4x6Q7NzS
+znPAUBlpENzH25FG9FBSh5Ruzu+mIFfSrTaVHpR/o4/ZDZndj+MqsitpoPcmTs3y
+8c8FFDE9qnEB3UIkGWJcABuYrH1F8uYU3S4QBnQ5YW25PGjB5z22PeF1yf0=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c9:30:53:c1:b9:0f:27:7a:39:3d:39:c4:a3:7c:
+ 96:bb:0e:e4:d9:fd:10:76:98:36:62:fc:33:7c:02:
+ 47:6c:6f:2e:d2:61:aa:d5:e3:86:67:a2:ef:93:a3:
+ fd:15:83:1c:27:90:f3:81:4a:41:f2:e6:e6:be:26:
+ 9a:b0:77:1d:e5:8a:97:2d:a7:87:6b:80:49:26:0e:
+ da:48:36:ba:eb:71:6a:cb:b4:82:66:42:fd:58:5f:
+ bc:c9:18:30:ee:2f:0c:28:81:e7:36:b9:76:da:55:
+ 8c:7a:cf:a9:1f:04:c6:6e:42:ea:d3:83:c6:8d:04:
+ 26:9e:11:8a:c6:cd:25:c7:4a:58:d1:98:86:b5:37:
+ 9c:3e:68:2e:17:4d:81:85:f3:d4:7d:65:e7:0f:86:
+ 8a:c9:d0:2d:fc:4f:c7:40:2a:ef:48:ab:2e:4c:2e:
+ b6:1c:81:4e:73:73:e9:cc:d4:ef:94:b1:17:2c:70:
+ 64:b0:4c:ad:87:cf:45:13:c2:67:46:d1:c6:b3:61:
+ 8d:77:af:4f:1c:b6:4f:b6:d9:2b:3c:4c:5f:72:23:
+ 77:c7:85:65:1d:85:48:28:06:34:b4:f0:bd:a9:76:
+ 7a:65:60:59:d6:f6:26:f6:85:99:7b:84:16:5e:91:
+ 8d:f9:90:b8:75:d3:4a:77:6a:1f:f8:ed:66:67:22:
+ 64:4b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 73:4C:95:45:4C:3B:F6:7E:7B:92:30:C9:AC:30:51:E7:7D:21:D2:BF
+ X509v3 Authority Key Identifier:
+ keyid:DE:10:87:7A:48:75:9E:50:89:F1:AE:40:E0:BF:BA:5F:D8:63:77:9B
+
+ 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, pathlen:0
+ Signature Algorithm: sha256WithRSAEncryption
+ 3f:40:c5:c8:06:d9:35:27:63:63:e7:9c:08:1d:ee:ef:e3:b6:
+ 11:a7:a2:4f:b0:bf:8b:14:2f:16:6f:47:f5:0b:d8:3d:98:7a:
+ 03:7d:30:0c:85:11:80:a6:ff:fc:99:dd:a0:31:d6:fb:bf:4f:
+ 09:49:64:ca:8a:34:3d:56:c3:72:b0:08:e2:b8:12:95:1e:70:
+ 4f:3f:5b:1e:70:6f:06:f0:78:77:90:3b:d1:54:83:f2:b1:8e:
+ 7e:25:d3:f7:21:66:8b:a9:c4:f7:f6:bb:a9:7a:3b:e0:99:4c:
+ 94:b7:45:3a:fe:61:74:0a:70:de:a0:d6:c1:c4:dd:59:0e:cc:
+ 81:d1:ad:da:99:1d:83:b3:e2:3a:7b:8f:5c:3a:25:52:3e:40:
+ 5a:96:00:71:e6:f3:5d:9c:6a:54:be:0f:24:8e:8b:3a:14:37:
+ 6a:72:0b:41:e6:06:d1:b2:3d:f9:a2:bb:d7:6e:f1:ac:70:08:
+ 62:e7:f2:82:df:fb:85:e4:99:b9:cf:84:9a:34:55:e5:e8:39:
+ a9:e7:e3:79:54:07:c9:6b:1d:33:aa:30:d3:ea:7b:32:07:0f:
+ 23:34:10:fa:58:17:ad:e0:62:c8:ce:d6:0f:db:34:0c:a3:a9:
+ f9:09:05:c6:25:d9:ce:e5:52:0a:5c:8a:f3:c9:44:72:45:71:
+ 6d:5c:fc:d1
+-----BEGIN CERTIFICATE-----
+MIIDcDCCAligAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyTBTwbkP
+J3o5PTnEo3yWuw7k2f0Qdpg2YvwzfAJHbG8u0mGq1eOGZ6Lvk6P9FYMcJ5DzgUpB
+8ubmviaasHcd5YqXLaeHa4BJJg7aSDa663Fqy7SCZkL9WF+8yRgw7i8MKIHnNrl2
+2lWMes+pHwTGbkLq04PGjQQmnhGKxs0lx0pY0ZiGtTecPmguF02BhfPUfWXnD4aK
+ydAt/E/HQCrvSKsuTC62HIFOc3PpzNTvlLEXLHBksEyth89FE8JnRtHGs2GNd69P
+HLZPttkrPExfciN3x4VlHYVIKAY0tPC9qXZ6ZWBZ1vYm9oWZe4QWXpGN+ZC4ddNK
+d2of+O1mZyJkSwIDAQABo4HOMIHLMB0GA1UdDgQWBBRzTJVFTDv2fnuSMMmsMFHn
+fSHSvzAfBgNVHSMEGDAWgBTeEId6SHWeUInxrkDgv7pf2GN3mzA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwDQYJKoZIhvcNAQELBQAD
+ggEBAD9AxcgG2TUnY2PnnAgd7u/jthGnok+wv4sULxZvR/UL2D2YegN9MAyFEYCm
+//yZ3aAx1vu/TwlJZMqKND1Ww3KwCOK4EpUecE8/Wx5wbwbweHeQO9FUg/Kxjn4l
+0/chZoupxPf2u6l6O+CZTJS3RTr+YXQKcN6g1sHE3VkOzIHRrdqZHYOz4jp7j1w6
+JVI+QFqWAHHm812calS+DySOizoUN2pyC0HmBtGyPfmiu9du8axwCGLn8oLf+4Xk
+mbnPhJo0VeXoOann43lUB8lrHTOqMNPqezIHDyM0EPpYF63gYsjO1g/bNAyjqfkJ
+BcYl2c7lUgpcivPJRHJFcW1c/NE=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a8:11:83:b7:cc:88:e9:4c:69:28:ad:6a:95:83:
+ 6a:1c:28:52:d2:02:21:00:93:f0:82:8e:fc:b8:fb:
+ b9:44:e2:43:e9:fe:3f:7e:0c:01:a6:9f:12:fc:09:
+ fc:66:44:03:b4:66:78:3c:36:05:37:00:6e:87:54:
+ ff:61:95:ab:37:88:a0:6e:f7:8f:c2:ea:8d:e5:bf:
+ 4c:21:21:1d:74:22:dd:93:52:b3:66:d7:97:33:b9:
+ cb:ab:8e:38:59:52:e7:f0:5c:09:50:ad:c9:e0:e1:
+ 18:d7:cc:4a:d7:2b:41:cd:91:8c:a2:b0:25:d6:6c:
+ d2:7d:e8:fa:20:3f:c8:aa:15:b9:77:b6:da:ac:86:
+ f8:21:52:2e:f9:e7:b6:d5:65:fd:23:ba:2f:5b:1b:
+ c6:62:76:00:f1:74:4b:e2:d9:9a:d3:67:03:71:d4:
+ 93:af:93:4d:4f:82:da:1c:ba:a5:a9:0f:25:6b:54:
+ dd:63:8c:3e:34:75:32:9e:c8:99:44:fd:f0:47:6d:
+ 98:45:3c:75:b5:ac:0b:eb:d6:30:6a:a1:6c:67:14:
+ ee:62:72:93:fe:bc:4c:e8:10:a2:3c:66:33:1c:49:
+ e8:dc:2f:c9:a4:64:17:88:a0:1c:a4:b0:ff:9c:8f:
+ c4:c6:18:1d:0c:55:62:a9:3b:f6:bc:53:16:62:82:
+ 49:c5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ DE:10:87:7A:48:75:9E:50:89:F1:AE:40:E0:BF:BA:5F:D8:63:77:9B
+ X509v3 Authority Key Identifier:
+ keyid:DE:10:87:7A:48:75:9E:50:89:F1:AE:40:E0:BF:BA:5F:D8:63:77:9B
+
+ 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
+ 27:c0:50:82:2b:1b:71:84:c6:12:ea:45:ed:21:b8:fd:7c:08:
+ 68:ec:de:4a:1b:98:3b:ce:e9:a1:9e:42:9a:e0:f4:e2:09:a6:
+ 5c:98:33:16:5b:65:6b:fc:b9:9b:26:90:e1:86:58:1f:0a:7e:
+ 7e:0d:7d:4e:0e:8b:93:04:b9:84:f0:e8:a3:7f:34:e2:ab:f5:
+ d5:bb:46:b7:df:a0:3a:81:8c:56:48:02:95:8f:06:cb:f2:cd:
+ 2a:39:c6:12:5a:9d:62:e9:a9:49:55:4d:e9:17:c2:97:3d:81:
+ 12:76:d8:68:18:f6:7e:a6:c4:52:a9:85:4c:83:38:94:2b:df:
+ dd:39:bb:cf:e1:9e:4e:e1:a0:eb:63:8a:c0:6e:99:01:65:78:
+ b5:ca:ab:2a:90:86:c5:5e:53:62:57:89:14:c1:41:8f:e6:9a:
+ 60:97:e4:5c:5b:fa:28:9c:9f:e3:55:ed:42:36:b6:d0:8d:f3:
+ 0c:cf:6e:87:38:aa:98:91:a9:1f:48:2a:c7:27:49:04:d6:d6:
+ f8:33:c9:d0:e2:b7:87:00:9a:1f:63:af:5b:ac:70:7e:96:9f:
+ b0:3b:e5:a3:f8:04:b6:f8:2c:38:54:21:06:51:33:32:78:80:
+ 17:59:83:95:66:65:1d:b5:5b:f2:1b:3e:6d:9e:98:c2:09:f3:
+ ec:52:20:5b
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgRg7fMiOlMaSitapWD
+ahwoUtICIQCT8IKO/Lj7uUTiQ+n+P34MAaafEvwJ/GZEA7RmeDw2BTcAbodU/2GV
+qzeIoG73j8LqjeW/TCEhHXQi3ZNSs2bXlzO5y6uOOFlS5/BcCVCtyeDhGNfMStcr
+Qc2RjKKwJdZs0n3o+iA/yKoVuXe22qyG+CFSLvnnttVl/SO6L1sbxmJ2APF0S+LZ
+mtNnA3HUk6+TTU+C2hy6pakPJWtU3WOMPjR1Mp7ImUT98EdtmEU8dbWsC+vWMGqh
+bGcU7mJyk/68TOgQojxmMxxJ6NwvyaRkF4igHKSw/5yPxMYYHQxVYqk79rxTFmKC
+ScUCAwEAAaOByzCByDAdBgNVHQ4EFgQU3hCHekh1nlCJ8a5A4L+6X9hjd5swHwYD
+VR0jBBgwFoAU3hCHekh1nlCJ8a5A4L+6X9hjd5swNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAnwFCCKxtx
+hMYS6kXtIbj9fAho7N5KG5g7zumhnkKa4PTiCaZcmDMWW2Vr/LmbJpDhhlgfCn5+
+DX1ODouTBLmE8OijfzTiq/XVu0a336A6gYxWSAKVjwbL8s0qOcYSWp1i6alJVU3p
+F8KXPYESdthoGPZ+psRSqYVMgziUK9/dObvP4Z5O4aDrY4rAbpkBZXi1yqsqkIbF
+XlNiV4kUwUGP5ppgl+RcW/oonJ/jVe1CNrbQjfMMz26HOKqYkakfSCrHJ0kE1tb4
+M8nQ4reHAJofY69brHB+lp+wO+Wj+AS2+Cw4VCEGUTMyeIAXWYOVZmUdtVvyGz5t
+npjCCfPsUiBb
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/common.py b/chromium/net/data/verify_certificate_chain_unittest/common.py
new file mode 100755
index 00000000000..c7e98d1981b
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/common.py
@@ -0,0 +1,417 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Set of helpers to generate signed X.509v3 certificates.
+
+This works by shelling out calls to the 'openssl req' and 'openssl ca'
+commands, and passing the appropriate command line flags and configuration file
+(.cnf).
+"""
+
+import base64
+import os
+import shutil
+import subprocess
+import sys
+
+import openssl_conf
+
+# Enum for the "type" of certificate that is to be created. This is used to
+# select sane defaults for the .cnf file and command line flags, but they can
+# all be overridden.
+TYPE_CA = 2
+TYPE_END_ENTITY = 3
+
+# January 1st, 2015 midnight UTC
+JANUARY_1_2015_UTC = '150101120000Z'
+
+# January 1st, 2016 midnight UTC
+JANUARY_1_2016_UTC = '160101120000Z'
+
+# March 2nd, 2015 midnight UTC
+DEFAULT_TIME = '150302120000Z'
+
+# Counter used to generate unique (but readable) path names.
+g_cur_path_id = 0
+
+# Output paths used:
+# - g_out_dir: where any temporary files (keys, cert req, signing db etc) are
+# saved to.
+# - g_out_pem: the path to the final output (which is a .pem file)
+#
+# See init() for how these are assigned, based on the name of the calling
+# script.
+g_out_dir = None
+g_out_pem = None
+
+
+def GetUniquePathId(name):
+ """Returns a base filename that contains 'name', but is unique to the output
+ directory"""
+ global g_cur_path_id
+
+ path_id = g_cur_path_id
+ g_cur_path_id += 1
+
+ # Use a short and clean name for the first use of this name.
+ if path_id == 0:
+ return name
+
+ # Otherwise append the count to make it unique.
+ return '%s_%d' % (name, path_id)
+
+
+class Certificate(object):
+ """Helper for building an X.509 certificate."""
+
+ def __init__(self, name, cert_type, issuer):
+ # The name will be used for the subject's CN, and also as a component of
+ # the temporary filenames to help with debugging.
+ self.name = name
+ self.path_id = GetUniquePathId(name)
+
+ # The issuer is also a Certificate object. Passing |None| means it is a
+ # self-signed certificate.
+ self.issuer = issuer
+ if issuer is None:
+ self.issuer = self
+
+ # The config contains all the OpenSSL options that will be passed via a
+ # .cnf file. Set up defaults.
+ self.config = openssl_conf.Config()
+ self.init_config()
+
+ # Some settings need to be passed as flags rather than in the .cnf file.
+ # Technically these can be set though a .cnf, however doing so makes it
+ # sticky to the issuing certificate, rather than selecting it per
+ # subordinate certificate.
+ self.validity_flags = []
+ self.md_flags = []
+
+ # By default OpenSSL will use the current time for the start time. Instead
+ # default to using a fixed timestamp for more predictabl results each time
+ # the certificates are re-generated.
+ self.set_validity_range(JANUARY_1_2015_UTC, JANUARY_1_2016_UTC)
+
+ # Use SHA-256 when THIS certificate is signed (setting it in the
+ # configuration would instead set the hash to use when signing other
+ # certificates with this one).
+ self.set_signature_hash('sha256')
+
+ # Set appropriate key usages and basic constraints. For flexibility in
+ # testing (since want to generate some flawed certificates) these are set
+ # on a per-certificate basis rather than automatically when signing.
+ if cert_type == TYPE_END_ENTITY:
+ self.get_extensions().set_property('keyUsage',
+ 'critical,digitalSignature,keyEncipherment')
+ self.get_extensions().set_property('extendedKeyUsage',
+ 'serverAuth,clientAuth')
+ else:
+ self.get_extensions().set_property('keyUsage',
+ 'critical,keyCertSign,cRLSign')
+ self.get_extensions().set_property('basicConstraints', 'critical,CA:true')
+
+ # Tracks whether the PEM file for this certificate has been written (since
+ # generation is done lazily).
+ self.finalized = False
+
+ # Initialize any files that will be needed if this certificate is used to
+ # sign other certificates. Starts off serial numbers at 1, and will
+ # increment them for each signed certificate.
+ write_string_to_file('01\n', self.get_serial_path())
+ write_string_to_file('', self.get_database_path())
+
+
+ def generate_rsa_key(self, size_bits):
+ """Generates an RSA private key for the certificate."""
+ subprocess.check_call(
+ ['openssl', 'genrsa', '-out', self.get_key_path(), str(size_bits)])
+
+
+ def generate_ec_key(self, named_curve):
+ """Generates an EC private key for the certificate. |named_curve| can be
+ something like secp384r1"""
+ subprocess.check_call(
+ ['openssl', 'ecparam', '-out', self.get_key_path(),
+ '-name', named_curve, '-genkey'])
+
+
+ def set_validity_range(self, start_date, end_date):
+ """Sets the Validity notBefore and notAfter properties for the
+ certificate"""
+ self.validity_flags = ['-startdate', start_date, '-enddate', end_date]
+
+
+ def set_signature_hash(self, md):
+ """Sets the hash function that will be used when signing this certificate.
+ Can be sha1, sha256, sha512, md5, etc."""
+ self.md_flags = ['-md', md]
+
+
+ def get_extensions(self):
+ return self.config.get_section('req_ext')
+
+
+ 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."""
+ return os.path.join(g_out_dir, '%s%s' % (self.path_id, suffix))
+
+
+ def get_key_path(self):
+ return self.get_path('.key')
+
+
+ def get_cert_path(self):
+ return self.get_path('.pem')
+
+
+ def get_serial_path(self):
+ return self.get_path('.serial')
+
+
+ def get_csr_path(self):
+ return self.get_path('.csr')
+
+
+ def get_database_path(self):
+ return self.get_path('.db')
+
+
+ def get_config_path(self):
+ return self.get_path('.cnf')
+
+
+ def get_cert_pem(self):
+ # Finish generating a .pem file for the certificate.
+ self.finalize()
+
+ # Read the certificate data.
+ with open(self.get_cert_path(), 'r') as f:
+ return f.read()
+
+
+ def finalize(self):
+ """Finishes the certificate creation process. This generates any needed
+ key, creates and signs the CSR. On completion the resulting PEM file can be
+ found at self.get_cert_path()"""
+
+ if self.finalized:
+ return # Already finalized, no work needed.
+
+ self.finalized = True
+
+ # Ensure that the issuer has been "finalized", since its outputs need to be
+ # accessible. Note that self.issuer could be the same as self.
+ self.issuer.finalize()
+
+ # Ensure the certificate has a key. Callers have the option to generate a
+ # different type of key, but if that was not done default to a new 2048-bit
+ # RSA key.
+ if not os.path.isfile(self.get_key_path()):
+ self.generate_rsa_key(2048)
+
+ # Serialize the config to a file.
+ self.config.write_to_file(self.get_config_path())
+
+ # Create a CSR.
+ subprocess.check_call(
+ ['openssl', 'req', '-new',
+ '-key', self.get_key_path(),
+ '-out', self.get_csr_path(),
+ '-config', self.get_config_path()])
+
+ cmd = ['openssl', 'ca', '-batch', '-in',
+ self.get_csr_path(), '-out', self.get_cert_path(), '-config',
+ self.issuer.get_config_path()]
+
+ if self.issuer == self:
+ cmd.append('-selfsign')
+
+ # Add in any extra flags.
+ cmd.extend(self.validity_flags)
+ cmd.extend(self.md_flags)
+
+ # Run the 'openssl ca' command.
+ subprocess.check_call(cmd)
+
+
+ def init_config(self):
+ """Initializes default properties in the certificate .cnf file that are
+ generic enough to work for all certificates (but can be overridden later).
+ """
+
+ # --------------------------------------
+ # 'req' section
+ # --------------------------------------
+
+ section = self.config.get_section('req')
+
+ section.set_property('encrypt_key', 'no')
+ section.set_property('utf8', 'yes')
+ section.set_property('string_mask', 'utf8only')
+ section.set_property('prompt', 'no')
+ section.set_property('distinguished_name', 'req_dn')
+ section.set_property('req_extensions', 'req_ext')
+
+ # --------------------------------------
+ # 'req_dn' section
+ # --------------------------------------
+
+ # This section describes the certificate subject's distinguished name.
+
+ section = self.config.get_section('req_dn')
+ section.set_property('commonName', '"%s"' % (self.name))
+
+ # --------------------------------------
+ # 'req_ext' section
+ # --------------------------------------
+
+ # This section describes the certificate's extensions.
+
+ section = self.config.get_section('req_ext')
+ section.set_property('subjectKeyIdentifier', 'hash')
+
+ # --------------------------------------
+ # SECTIONS FOR CAs
+ # --------------------------------------
+
+ # The following sections are used by the 'openssl ca' and relate to the
+ # signing operation. They are not needed for end-entity certificate
+ # configurations, but only if this certifiate will be used to sign other
+ # certificates.
+
+ # --------------------------------------
+ # 'ca' section
+ # --------------------------------------
+
+ section = self.config.get_section('ca')
+ section.set_property('default_ca', 'root_ca')
+
+ section = self.config.get_section('root_ca')
+ section.set_property('certificate', self.get_cert_path())
+ section.set_property('private_key', self.get_key_path())
+ section.set_property('new_certs_dir', g_out_dir)
+ section.set_property('serial', self.get_serial_path())
+ section.set_property('database', self.get_database_path())
+ section.set_property('unique_subject', 'no')
+
+ # These will get overridden via command line flags.
+ section.set_property('default_days', '365')
+ section.set_property('default_md', 'sha256')
+
+ section.set_property('policy', 'policy_anything')
+ section.set_property('email_in_dn', 'no')
+ section.set_property('preserve', 'yes')
+ section.set_property('name_opt', 'multiline,-esc_msb,utf8')
+ section.set_property('cert_opt', 'ca_default')
+ section.set_property('copy_extensions', 'copy')
+ section.set_property('x509_extensions', 'signing_ca_ext')
+ section.set_property('default_crl_days', '30')
+ section.set_property('crl_extensions', 'crl_ext')
+
+ section = self.config.get_section('policy_anything')
+ section.set_property('domainComponent', 'optional')
+ section.set_property('countryName', 'optional')
+ section.set_property('stateOrProvinceName', 'optional')
+ section.set_property('localityName', 'optional')
+ section.set_property('organizationName', 'optional')
+ section.set_property('organizationalUnitName', 'optional')
+ section.set_property('commonName', 'optional')
+ section.set_property('emailAddress', 'optional')
+
+ section = self.config.get_section('signing_ca_ext')
+ section.set_property('subjectKeyIdentifier', 'hash')
+ section.set_property('authorityKeyIdentifier', 'keyid:always')
+ section.set_property('authorityInfoAccess', '@issuer_info')
+ section.set_property('crlDistributionPoints', '@crl_info')
+
+ section = self.config.get_section('issuer_info')
+ section.set_property('caIssuers;URI.0',
+ 'http://url-for-aia/%s.cer' % (self.name))
+
+ section = self.config.get_section('crl_info')
+ section.set_property('URI.0', 'http://url-for-crl/%s.crl' % (self.name))
+
+ section = self.config.get_section('crl_ext')
+ section.set_property('authorityKeyIdentifier', 'keyid:always')
+ section.set_property('authorityInfoAccess', '@issuer_info')
+
+
+def data_to_pem(block_header, block_data):
+ return '-----BEGIN %s-----\n%s\n-----END %s-----\n' % (block_header,
+ base64.b64encode(block_data), block_header)
+
+
+def write_test_file(description, chain, trusted_certs, utc_time, verify_result):
+ """Writes a test file that contains all the inputs necessary to run a
+ verification on a certificate chain"""
+
+ # Prepend the script name that generated the file to the description.
+ test_data = '[Created by: %s]\n\n%s\n' % (sys.argv[0], description)
+
+ # Write the certificate chain to the output file.
+ for cert in chain:
+ test_data += '\n' + cert.get_cert_pem()
+
+ # Write the trust store.
+ for cert in trusted_certs:
+ cert_data = cert.get_cert_pem()
+ # Use a different block type in the .pem file.
+ cert_data = cert_data.replace('CERTIFICATE', 'TRUSTED_CERTIFICATE')
+ test_data += '\n' + cert_data
+
+ test_data += '\n' + data_to_pem('TIME', utc_time)
+
+ verify_result_string = 'SUCCESS' if verify_result else 'FAIL'
+ test_data += '\n' + data_to_pem('VERIFY_RESULT', verify_result_string)
+
+ write_string_to_file(test_data, g_out_pem)
+
+
+def write_string_to_file(data, path):
+ with open(path, 'w') as f:
+ f.write(data)
+
+
+def init(invoking_script_path):
+ """Creates an output directory to contain all the temporary files that may be
+ created, as well as determining the path for the final output. These paths
+ are all based off of the name of the calling script.
+ """
+
+ global g_out_dir
+ global g_out_pem
+
+ # Base the output name off of the invoking script's name.
+ out_name = os.path.splitext(os.path.basename(invoking_script_path))[0]
+
+ # Strip the leading 'generate-'
+ if out_name.startswith('generate-'):
+ out_name = out_name[9:]
+
+ # Use an output directory with the same name as the invoking script.
+ g_out_dir = os.path.join('out', out_name)
+
+ # Ensure the output directory exists and is empty.
+ sys.stdout.write('Creating output directory: %s\n' % (g_out_dir))
+ shutil.rmtree(g_out_dir, True)
+ os.makedirs(g_out_dir)
+
+ g_out_pem = os.path.join('%s.pem' % (out_name))
+
+
+def create_self_signed_root_certificate(name):
+ return Certificate(name, TYPE_CA, None)
+
+
+def create_intermediary_certificate(name, issuer):
+ return Certificate(name, TYPE_CA, issuer)
+
+
+def create_end_entity_certificate(name, issuer):
+ return Certificate(name, TYPE_END_ENTITY, issuer)
+
+init(sys.argv[0])
diff --git a/chromium/net/data/verify_certificate_chain_unittest/expired-intermediary.pem b/chromium/net/data/verify_certificate_chain_unittest/expired-intermediary.pem
new file mode 100644
index 00000000000..f0bad527d3e
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/expired-intermediary.pem
@@ -0,0 +1,280 @@
+[Created by: generate-expired-intermediary.py]
+
+Certificate chain with 1 intermediary, where the intermediary is expired
+(violates validity.notAfter). Verification is expected to fail.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b4:33:49:77:46:22:00:7b:a3:98:45:15:f7:e4:
+ 40:bc:c7:d1:86:bf:05:3b:c7:57:d7:12:e4:b0:aa:
+ 58:38:e7:bb:2f:1a:54:91:a8:78:39:d1:bd:67:5c:
+ c6:d5:08:44:d0:98:7e:7f:69:03:2a:5d:cd:f9:51:
+ 13:44:50:62:c4:ca:44:3e:1d:ea:bc:fd:eb:21:57:
+ e2:cd:85:3d:fe:70:e1:e8:92:c4:5f:68:67:4e:53:
+ 96:6b:02:59:39:31:c9:8b:fe:71:17:b3:b7:14:77:
+ 1b:89:b4:f8:ec:c5:b1:53:dd:42:ca:40:cd:14:c0:
+ 8a:b7:f6:32:72:16:d0:37:72:de:62:9f:49:e5:c3:
+ 2e:22:bc:a0:04:a7:d5:11:56:54:9f:7f:0e:92:f3:
+ 7a:88:bb:74:2e:19:3f:02:9e:69:fa:b4:bd:57:38:
+ 3d:19:99:48:f4:c1:07:57:91:52:db:63:dc:8b:0c:
+ ca:74:85:1a:cd:f1:8c:3f:b9:9f:61:44:31:f8:86:
+ ef:c1:ff:31:e7:fb:cd:7a:59:30:b2:8b:9c:5e:71:
+ 41:04:11:96:e4:8a:a7:8e:0e:58:76:ac:0f:1c:eb:
+ 1e:dc:0f:01:4f:ad:4e:29:ba:9b:40:7f:f5:c8:51:
+ 0c:8b:a9:19:01:51:c3:23:71:25:19:be:0c:10:ea:
+ 46:75
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 77:E8:2F:D7:FB:5C:C4:E2:A0:B9:44:4F:B4:A7:15:35:41:B6:C8:C3
+ X509v3 Authority Key Identifier:
+ keyid:8C:5E:B2:DE:2B:9F:31:B1:26:55:4D:45:E8:E7:23:87:58:5B:83:D1
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 96:9d:3f:9e:85:d1:f5:b1:b8:42:a6:13:92:77:ea:af:0a:3e:
+ f1:2e:73:e5:db:55:e5:08:d9:54:35:67:ed:0c:7a:ec:b4:a6:
+ 3b:6e:7b:db:44:82:36:84:65:6e:f0:95:bc:a2:10:f3:73:39:
+ 41:ae:3d:2b:dc:de:3f:9b:8a:bc:67:83:75:83:dd:67:b1:96:
+ fc:79:0f:ca:89:73:7f:48:83:55:f5:e5:dd:b3:fd:8d:8c:1c:
+ c1:7f:41:fd:db:ac:59:33:58:0e:01:cb:8d:d9:c0:7d:bd:e0:
+ a1:1e:ce:cb:eb:a1:c8:97:05:4d:4d:28:26:f6:eb:1a:7d:20:
+ 3a:d5:a9:9c:12:2d:b4:56:42:ab:fa:4d:f4:50:68:62:e5:94:
+ 2c:9c:e7:83:25:db:d7:8b:40:2d:d7:ba:b8:f4:fe:f4:88:76:
+ 5d:b9:a0:6d:ee:ba:82:a1:33:42:3a:e4:10:77:30:9b:60:c2:
+ c7:8b:cd:9e:29:00:0c:2d:01:a1:eb:1b:ce:41:6a:c7:91:79:
+ ff:64:f4:fe:2e:20:34:c6:6e:8a:4b:82:be:09:6b:17:94:aa:
+ cb:75:82:3a:b4:03:16:8a:52:4e:3a:92:a3:85:fd:db:a2:e8:
+ e7:a3:8c:bf:85:7e:6b:2d:7a:53:1d:db:49:1e:30:d0:8d:99:
+ 06:f8:95:3a
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0M0l3
+RiIAe6OYRRX35EC8x9GGvwU7x1fXEuSwqlg457svGlSRqHg50b1nXMbVCETQmH5/
+aQMqXc35URNEUGLEykQ+Heq8/eshV+LNhT3+cOHoksRfaGdOU5ZrAlk5McmL/nEX
+s7cUdxuJtPjsxbFT3ULKQM0UwIq39jJyFtA3ct5in0nlwy4ivKAEp9URVlSffw6S
+83qIu3QuGT8Cnmn6tL1XOD0ZmUj0wQdXkVLbY9yLDMp0hRrN8Yw/uZ9hRDH4hu/B
+/zHn+816WTCyi5xecUEEEZbkiqeODlh2rA8c6x7cDwFPrU4puptAf/XIUQyLqRkB
+UcMjcSUZvgwQ6kZ1AgMBAAGjgekwgeYwHQYDVR0OBBYEFHfoL9f7XMTioLlET7Sn
+FTVBtsjDMB8GA1UdIwQYMBaAFIxest4rnzGxJlVNRejnI4dYW4PRMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAlp0/noXR9bG4QqYTknfq
+rwo+8S5z5dtV5QjZVDVn7Qx67LSmO25720SCNoRlbvCVvKIQ83M5Qa49K9zeP5uK
+vGeDdYPdZ7GW/HkPyolzf0iDVfXl3bP9jYwcwX9B/dusWTNYDgHLjdnAfb3goR7O
+y+uhyJcFTU0oJvbrGn0gOtWpnBIttFZCq/pN9FBoYuWULJzngyXb14tALde6uPT+
+9Ih2Xbmgbe66gqEzQjrkEHcwm2DCx4vNnikADC0BoesbzkFqx5F5/2T0/i4gNMZu
+ikuCvglrF5Sqy3WCOrQDFopSTjqSo4X926Lo56OMv4V+ay16Ux3bSR4w0I2ZBviV
+Og==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ab:a7:65:bb:25:26:49:f5:55:58:4e:25:97:97:
+ 19:be:89:c0:d7:29:77:db:32:59:71:e5:92:4c:6e:
+ c3:9c:29:73:65:a7:60:ba:a6:59:06:25:28:df:90:
+ ec:d7:fb:b9:fd:67:f4:0a:e2:2f:9c:e6:0d:77:77:
+ 12:60:e7:57:71:08:ba:87:50:30:a0:5f:d6:02:0c:
+ 9a:64:6c:fb:cf:f7:6b:12:ce:09:98:27:d9:15:46:
+ 00:14:58:63:08:e1:58:7f:98:5d:86:09:6b:59:78:
+ 69:c1:74:5b:6e:a4:fc:b0:d7:64:30:e6:50:7a:3a:
+ 98:fd:48:ed:b9:d3:b2:04:5a:f6:67:c8:50:f2:bb:
+ 2a:49:4c:82:2c:9c:1a:ab:5c:e8:0d:7b:ae:2b:5f:
+ 4f:77:90:4a:c9:63:cd:0f:07:1d:63:23:7f:e6:6b:
+ 16:f8:70:f1:43:ac:4c:e0:72:05:36:0e:3f:62:ed:
+ 71:61:8f:e1:7c:8b:16:7d:9c:99:e1:18:d4:8e:52:
+ 14:07:3b:49:7e:5d:06:ac:6b:34:63:6c:86:c5:8a:
+ fb:f0:e5:a3:aa:40:4f:35:da:4b:31:c6:a0:7e:49:
+ c1:47:22:19:5b:2d:c3:07:ac:25:fe:e8:97:4c:e1:
+ 59:59:2c:6b:bd:96:ee:b5:67:ca:03:1d:a7:e1:8e:
+ 19:a3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 8C:5E:B2:DE:2B:9F:31:B1:26:55:4D:45:E8:E7:23:87:58:5B:83:D1
+ X509v3 Authority Key Identifier:
+ keyid:15:EB:EA:C0:58:73:9E:53:97:FB:86:13:F2:7A:4E:1C:E1:91:7C:C5
+
+ 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
+ 0e:32:41:5f:b0:5f:c7:3e:3e:d7:54:43:2c:7d:d5:49:a0:2f:
+ 90:d6:70:2e:f4:d6:a7:13:15:83:3b:44:a0:c2:d8:d8:01:0b:
+ b0:37:ec:14:39:e5:85:99:de:80:f6:da:11:b4:31:5a:66:86:
+ f0:e8:ac:ad:d6:ac:4a:eb:49:4f:af:59:cc:c5:ca:e7:09:8c:
+ 98:e1:b7:86:c1:46:c3:85:34:7a:89:72:0b:0a:f5:e7:41:ac:
+ 6d:9c:78:ff:d6:ba:fc:86:f3:39:b9:77:44:f4:2f:f4:c0:5e:
+ b2:93:01:9e:85:8d:a8:58:dc:cd:77:37:40:28:0c:d7:42:19:
+ f5:bc:a0:e9:ea:f6:a1:42:6a:1f:d3:d6:01:b0:8e:ef:49:97:
+ 7a:d5:8b:37:28:96:95:00:dd:4c:6c:05:5a:59:fd:14:bd:69:
+ ae:03:c3:8b:47:ea:8e:48:92:4c:c9:bc:9c:b7:07:bd:e4:5e:
+ 6c:d3:e1:51:57:45:b2:79:bf:7e:22:c1:d5:65:a8:50:db:51:
+ 13:28:8e:02:2c:d2:19:09:69:16:6d:60:40:23:44:5b:38:4a:
+ a4:a1:61:27:ec:36:95:81:2e:5c:ac:f1:13:39:f5:d0:d5:3a:
+ 94:82:8f:c8:41:da:e8:a4:0e:19:a8:6d:19:6c:fb:29:39:74:
+ af:48:01:e2
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq6dluyUm
+SfVVWE4ll5cZvonA1yl32zJZceWSTG7DnClzZadguqZZBiUo35Ds1/u5/Wf0CuIv
+nOYNd3cSYOdXcQi6h1AwoF/WAgyaZGz7z/drEs4JmCfZFUYAFFhjCOFYf5hdhglr
+WXhpwXRbbqT8sNdkMOZQejqY/UjtudOyBFr2Z8hQ8rsqSUyCLJwaq1zoDXuuK19P
+d5BKyWPNDwcdYyN/5msW+HDxQ6xM4HIFNg4/Yu1xYY/hfIsWfZyZ4RjUjlIUBztJ
+fl0GrGs0Y2yGxYr78OWjqkBPNdpLMcagfknBRyIZWy3DB6wl/uiXTOFZWSxrvZbu
+tWfKAx2n4Y4ZowIDAQABo4HLMIHIMB0GA1UdDgQWBBSMXrLeK58xsSZVTUXo5yOH
+WFuD0TAfBgNVHSMEGDAWgBQV6+rAWHOeU5f7hhPyek4c4ZF8xTA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AA4yQV+wX8c+PtdUQyx91UmgL5DWcC701qcTFYM7RKDC2NgBC7A37BQ55YWZ3oD2
+2hG0MVpmhvDorK3WrErrSU+vWczFyucJjJjht4bBRsOFNHqJcgsK9edBrG2ceP/W
+uvyG8zm5d0T0L/TAXrKTAZ6FjahY3M13N0AoDNdCGfW8oOnq9qFCah/T1gGwju9J
+l3rVizcolpUA3UxsBVpZ/RS9aa4Dw4tH6o5IkkzJvJy3B73kXmzT4VFXRbJ5v34i
+wdVlqFDbURMojgIs0hkJaRZtYEAjRFs4SqShYSfsNpWBLlys8RM59dDVOpSCj8hB
+2uikDhmobRls+yk5dK9IAeI=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ca:63:ce:f6:f5:87:1c:17:7d:20:6c:eb:25:52:
+ 83:6a:00:1b:c4:76:25:c4:5e:e0:0e:eb:dc:c2:86:
+ 9f:84:9a:b2:da:cd:05:7f:5b:ad:e0:11:3a:f9:c5:
+ a9:97:96:77:9c:4a:3c:3d:e8:c2:fe:f0:e5:f4:1f:
+ c2:bd:cb:33:89:fa:a0:61:c2:85:c1:ea:8b:ec:97:
+ f4:5d:dc:cf:bd:45:c8:5d:a9:0d:8e:7a:b0:53:67:
+ 8b:37:bd:67:20:f0:e3:fd:20:5d:7e:e8:df:90:ba:
+ 0a:59:b3:08:fb:42:45:ae:83:89:b8:50:93:09:66:
+ ac:a3:7a:fe:b3:ee:ad:0c:fd:c3:a0:ab:3b:1a:49:
+ 4f:bb:2e:8a:0a:61:ae:99:40:15:79:9a:63:a9:f3:
+ e0:50:98:eb:11:7d:06:56:85:43:50:8d:9c:1f:a5:
+ c3:6e:17:6b:f3:07:3a:8a:ce:c2:4f:71:84:eb:c3:
+ ca:91:1c:71:96:57:14:93:15:f7:93:b6:39:4e:9e:
+ 99:8e:2b:e0:47:ad:86:ff:d4:7f:a4:b1:5b:3f:08:
+ 03:84:95:8f:2a:ff:0c:33:22:28:3e:e8:12:53:5d:
+ 10:3b:86:24:61:1b:85:a8:97:ad:b1:2f:d2:a0:5a:
+ 5f:51:49:7c:ab:4f:4b:4a:43:da:2f:4a:46:6a:c9:
+ 12:d5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 15:EB:EA:C0:58:73:9E:53:97:FB:86:13:F2:7A:4E:1C:E1:91:7C:C5
+ X509v3 Authority Key Identifier:
+ keyid:15:EB:EA:C0:58:73:9E:53:97:FB:86:13:F2:7A:4E:1C:E1:91:7C:C5
+
+ 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
+ 35:78:42:b8:84:7a:f4:0a:9d:ab:2f:a2:95:a7:6a:f5:14:ee:
+ b7:5a:f4:36:43:22:ef:f7:39:c4:85:ff:eb:e4:24:47:c2:04:
+ ac:af:25:a5:04:68:64:a3:41:23:fe:a6:99:d2:2a:95:51:60:
+ 2a:97:31:31:01:a0:83:2c:d8:fe:81:5f:dc:2d:3f:5a:5c:6f:
+ 2f:df:43:57:61:35:a2:e3:d9:56:f0:26:7d:74:15:3f:24:07:
+ 1a:cd:49:d9:d0:2f:94:5b:d8:ae:da:f4:93:fa:7a:34:25:20:
+ a1:d0:ef:d2:1e:c3:eb:b5:63:49:c6:4c:a1:2f:11:d6:5b:88:
+ a8:89:b0:e6:22:92:3f:d2:a9:26:ad:32:85:e4:98:14:3c:9e:
+ 4d:9e:49:62:f9:88:25:bd:e0:0d:72:d0:dc:cc:55:b7:bc:38:
+ 58:70:6b:cb:e0:ce:6b:1a:f8:3a:b6:33:0f:21:0d:d1:80:e1:
+ 5f:2a:ca:b0:29:e0:e0:17:af:4a:39:bb:cc:29:97:30:08:64:
+ 26:d9:ba:0b:1f:17:a3:41:e3:0f:a2:d1:cd:21:a1:4e:40:ee:
+ 3d:c3:20:4a:6d:c4:35:3c:10:f1:f8:76:f8:04:da:7f:17:22:
+ 6a:de:fe:59:24:04:06:e8:57:f1:6b:f8:4d:63:17:c3:0e:dc:
+ 3b:26:f3:e2
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMpjzvb1hxwXfSBs6yVS
+g2oAG8R2JcRe4A7r3MKGn4SastrNBX9breAROvnFqZeWd5xKPD3owv7w5fQfwr3L
+M4n6oGHChcHqi+yX9F3cz71FyF2pDY56sFNnize9ZyDw4/0gXX7o35C6ClmzCPtC
+Ra6DibhQkwlmrKN6/rPurQz9w6CrOxpJT7suigphrplAFXmaY6nz4FCY6xF9BlaF
+Q1CNnB+lw24Xa/MHOorOwk9xhOvDypEccZZXFJMV95O2OU6emY4r4Eethv/Uf6Sx
+Wz8IA4SVjyr/DDMiKD7oElNdEDuGJGEbhaiXrbEv0qBaX1FJfKtPS0pD2i9KRmrJ
+EtUCAwEAAaOByzCByDAdBgNVHQ4EFgQUFevqwFhznlOX+4YT8npOHOGRfMUwHwYD
+VR0jBBgwFoAUFevqwFhznlOX+4YT8npOHOGRfMUwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA1eEK4hHr0
+Cp2rL6KVp2r1FO63WvQ2QyLv9znEhf/r5CRHwgSsryWlBGhko0Ej/qaZ0iqVUWAq
+lzExAaCDLNj+gV/cLT9aXG8v30NXYTWi49lW8CZ9dBU/JAcazUnZ0C+UW9iu2vST
++no0JSCh0O/SHsPrtWNJxkyhLxHWW4ioibDmIpI/0qkmrTKF5JgUPJ5Nnkli+Ygl
+veANctDczFW3vDhYcGvL4M5rGvg6tjMPIQ3RgOFfKsqwKeDgF69KObvMKZcwCGQm
+2boLHxejQeMPotHNIaFOQO49wyBKbcQ1PBDx+Hb4BNp/FyJq3v5ZJAQG6Ffxa/hN
+YxfDDtw7JvPi
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTYwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem b/chromium/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem
new file mode 100644
index 00000000000..e531d9431df
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem
@@ -0,0 +1,280 @@
+[Created by: generate-expired-target-notBefore.py]
+
+Certificate chain with 1 intermediary, where the target is expired (violates
+validity.notBefore). Verification is expected to fail.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e0:ba:cf:dc:e5:4a:42:65:18:58:f0:f8:21:32:
+ 87:ad:b6:d8:ff:96:c7:54:50:9c:6c:ff:f8:ef:1a:
+ 3a:46:57:8b:9f:8d:f3:ea:a3:f8:37:eb:57:73:bb:
+ cb:0e:bf:2f:b1:2e:7e:0f:10:d8:93:be:20:41:f0:
+ 6d:5c:ce:52:20:10:13:37:c5:fb:88:1a:72:e2:f4:
+ 0a:d2:14:43:21:ae:5f:7e:0f:3e:95:53:38:56:f3:
+ ab:b3:67:e0:b7:d9:f0:07:98:b0:50:7c:9c:05:9f:
+ a7:ef:ec:85:cd:e5:ab:22:a3:f1:55:b9:96:5b:c0:
+ 50:7d:8f:1b:37:a8:cf:40:5d:1f:be:6d:48:bc:22:
+ e4:65:ea:15:79:1c:9f:e2:7d:58:25:01:15:ac:7b:
+ 50:6f:53:4e:ed:14:d9:02:55:8d:84:35:34:bc:46:
+ 11:b3:27:5e:27:47:79:8d:f2:df:d1:43:df:73:19:
+ e8:06:11:ee:55:87:4b:11:d8:6d:53:12:47:8d:87:
+ f7:6b:e3:d9:a1:aa:8d:8f:81:ad:dd:6f:52:ce:39:
+ 97:28:83:63:39:3c:e4:f0:b1:93:4c:82:44:b6:2a:
+ 7e:fe:c5:7b:9a:f3:01:35:9c:e0:de:d5:0d:ee:b1:
+ e9:04:f6:bf:74:94:83:56:bb:3d:57:01:56:f9:24:
+ 2f:e5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ C3:8F:E4:91:5B:59:E5:5A:12:DF:C4:31:8B:24:14:1F:CE:B1:8B:33
+ X509v3 Authority Key Identifier:
+ keyid:22:8D:DE:5E:4F:B1:54:9D:71:73:E9:6B:39:85:BB:08:D8:87:CA:D0
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 59:d5:11:a5:3a:be:47:f7:57:74:59:36:de:85:9f:e1:c4:17:
+ e9:03:98:69:f7:c8:f0:b2:49:f6:ff:96:0e:06:4d:e0:1e:4b:
+ b6:09:67:17:28:a6:3f:56:f5:8b:fe:03:0e:b1:76:a9:6d:7d:
+ 07:22:03:ae:df:92:a9:0a:94:96:d9:86:8d:55:34:05:c6:3e:
+ bb:59:c3:a1:84:da:f8:76:4e:cd:42:09:be:d0:72:18:8f:07:
+ f3:8a:04:27:81:05:0a:1a:13:a7:ce:ee:c1:a5:43:b5:a1:64:
+ c5:78:84:4c:fd:02:d7:3b:33:b3:ff:13:32:c3:1f:15:55:92:
+ 74:93:21:4c:c9:fd:a9:33:a1:a6:00:5a:ec:42:31:d2:98:58:
+ 8e:f3:12:32:3b:3f:96:58:19:a3:6b:fc:40:68:45:80:60:85:
+ 30:b3:50:d2:52:74:9c:7f:01:b9:8a:22:8f:60:18:c5:4f:04:
+ 0c:10:7e:ff:da:d6:8f:93:f2:80:a0:b3:3e:61:82:8a:c2:a6:
+ a7:6e:e1:85:76:ef:d3:64:ac:41:37:df:9f:1b:51:ac:8b:c6:
+ 42:e9:54:57:16:fc:ab:cc:79:b3:5e:6e:84:36:3a:67:fa:bd:
+ 8d:c8:b6:1e:a5:c2:af:41:7b:8a:5a:72:5d:bb:87:c8:8d:1e:
+ 51:06:44:ab
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDgus/c
+5UpCZRhY8PghMoetttj/lsdUUJxs//jvGjpGV4ufjfPqo/g361dzu8sOvy+xLn4P
+ENiTviBB8G1czlIgEBM3xfuIGnLi9ArSFEMhrl9+Dz6VUzhW86uzZ+C32fAHmLBQ
+fJwFn6fv7IXN5asio/FVuZZbwFB9jxs3qM9AXR++bUi8IuRl6hV5HJ/ifVglARWs
+e1BvU07tFNkCVY2ENTS8RhGzJ14nR3mN8t/RQ99zGegGEe5Vh0sR2G1TEkeNh/dr
+49mhqo2Pga3db1LOOZcog2M5POTwsZNMgkS2Kn7+xXua8wE1nODe1Q3usekE9r90
+lINWuz1XAVb5JC/lAgMBAAGjgekwgeYwHQYDVR0OBBYEFMOP5JFbWeVaEt/EMYsk
+FB/OsYszMB8GA1UdIwQYMBaAFCKN3l5PsVSdcXPpazmFuwjYh8rQMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAWdURpTq+R/dXdFk23oWf
+4cQX6QOYaffI8LJJ9v+WDgZN4B5LtglnFyimP1b1i/4DDrF2qW19ByIDrt+SqQqU
+ltmGjVU0BcY+u1nDoYTa+HZOzUIJvtByGI8H84oEJ4EFChoTp87uwaVDtaFkxXiE
+TP0C1zszs/8TMsMfFVWSdJMhTMn9qTOhpgBa7EIx0phYjvMSMjs/llgZo2v8QGhF
+gGCFMLNQ0lJ0nH8BuYoij2AYxU8EDBB+/9rWj5PygKCzPmGCisKmp27hhXbv02Ss
+QTffnxtRrIvGQulUVxb8q8x5s15uhDY6Z/q9jci2HqXCr0F7ilpyXbuHyI0eUQZE
+qw==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a0:cf:ed:e6:2e:fe:fc:9c:7d:c5:b5:f9:ad:0c:
+ 07:3b:61:9a:29:79:7d:0b:c2:a0:2b:64:10:ce:17:
+ 64:a9:25:35:b4:17:0e:06:73:83:b2:4e:bb:d2:9d:
+ 38:05:06:0d:61:24:87:ee:f8:eb:0a:87:f4:8c:2d:
+ cf:ec:c2:13:43:f6:a0:ad:bf:e3:94:56:a6:7e:30:
+ 93:3d:65:64:62:88:a5:78:6a:dd:ca:54:3d:36:17:
+ 2b:79:bb:f0:fd:fe:ba:94:99:c7:ce:61:4e:aa:c9:
+ f3:87:98:05:8a:b8:fe:e9:96:52:e3:c7:3e:e9:60:
+ e0:7c:94:75:a2:11:d7:11:d3:70:f1:8e:25:c1:20:
+ af:93:f5:8a:be:76:75:2f:d0:3f:82:8f:99:c7:44:
+ 79:c3:f2:31:d7:24:30:cd:14:ba:b6:c4:a2:16:86:
+ 9c:b7:bf:00:1c:f7:eb:a1:e2:fa:14:f3:08:00:06:
+ f5:b0:a7:79:05:84:ad:a1:4c:e7:f7:e6:14:68:2f:
+ 67:67:aa:06:c7:31:f2:1f:d3:b7:c2:e8:e7:bc:0f:
+ 1a:69:55:a0:75:8d:45:fa:1e:52:f4:ea:87:5c:0c:
+ ef:d6:e4:b4:bb:59:7c:34:eb:67:16:5e:06:56:05:
+ e3:0a:6f:f6:c8:88:e3:1f:a6:cf:ab:6a:93:cd:b8:
+ e8:ab
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 22:8D:DE:5E:4F:B1:54:9D:71:73:E9:6B:39:85:BB:08:D8:87:CA:D0
+ X509v3 Authority Key Identifier:
+ keyid:85:85:73:C1:C8:A5:7B:1C:6D:25:84:2A:CE:2B:A3:E4:21:E4:AE:D0
+
+ 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
+ 32:34:d5:49:6d:d1:25:e9:5b:f5:a8:29:b0:9a:ae:56:da:c0:
+ 56:b5:e1:76:a8:71:a6:af:c7:3d:a9:cd:d2:7e:56:b4:12:ad:
+ ae:61:94:02:bf:f2:0c:c3:64:1c:a2:70:41:3c:7c:30:3f:db:
+ c7:97:69:52:fc:39:63:a3:ed:27:f8:d1:e1:90:09:b5:8a:75:
+ dc:6b:db:4c:f6:b6:e3:57:84:f8:4d:f2:dd:d6:eb:63:ca:5f:
+ 39:d1:c2:52:1a:44:dd:02:b9:7c:4a:46:69:25:52:e9:85:48:
+ a2:22:b4:a6:cc:a3:bb:00:e6:ea:67:e6:ed:40:15:5a:51:d7:
+ a1:a8:e3:58:91:ec:80:65:63:db:f0:85:62:b4:0c:29:b9:c2:
+ 0a:f7:96:10:ed:c9:92:b4:71:53:d1:71:12:9c:04:f7:c9:44:
+ 57:1f:fc:40:57:a9:e1:df:b8:39:17:d0:79:d9:ae:4c:4b:cb:
+ 24:6e:25:01:8b:ad:37:cc:6f:b6:c2:58:ee:54:3f:78:71:45:
+ 69:21:c2:15:7c:86:03:1d:64:22:53:d9:65:68:d2:10:d0:38:
+ be:bc:f2:49:11:a2:39:04:e5:36:79:bf:20:fe:10:03:1a:b5:
+ 6c:12:c7:8a:06:dd:9d:bb:4d:f8:5b:b6:2d:3e:18:9b:26:b2:
+ 6c:59:c3:15
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoM/t5i7+
+/Jx9xbX5rQwHO2GaKXl9C8KgK2QQzhdkqSU1tBcOBnODsk670p04BQYNYSSH7vjr
+Cof0jC3P7MITQ/agrb/jlFamfjCTPWVkYoileGrdylQ9Nhcrebvw/f66lJnHzmFO
+qsnzh5gFirj+6ZZS48c+6WDgfJR1ohHXEdNw8Y4lwSCvk/WKvnZ1L9A/go+Zx0R5
+w/Ix1yQwzRS6tsSiFoact78AHPfroeL6FPMIAAb1sKd5BYStoUzn9+YUaC9nZ6oG
+xzHyH9O3wujnvA8aaVWgdY1F+h5S9OqHXAzv1uS0u1l8NOtnFl4GVgXjCm/2yIjj
+H6bPq2qTzbjoqwIDAQABo4HLMIHIMB0GA1UdDgQWBBQijd5eT7FUnXFz6Ws5hbsI
+2IfK0DAfBgNVHSMEGDAWgBSFhXPByKV7HG0lhCrOK6PkIeSu0DA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+ADI01Ult0SXpW/WoKbCarlbawFa14Xaocaavxz2pzdJ+VrQSra5hlAK/8gzDZByi
+cEE8fDA/28eXaVL8OWOj7Sf40eGQCbWKddxr20z2tuNXhPhN8t3W62PKXznRwlIa
+RN0CuXxKRmklUumFSKIitKbMo7sA5upn5u1AFVpR16Go41iR7IBlY9vwhWK0DCm5
+wgr3lhDtyZK0cVPRcRKcBPfJRFcf/EBXqeHfuDkX0HnZrkxLyyRuJQGLrTfMb7bC
+WO5UP3hxRWkhwhV8hgMdZCJT2WVo0hDQOL688kkRojkE5TZ5vyD+EAMatWwSx4oG
+3Z27Tfhbti0+GJsmsmxZwxU=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c1:48:07:e3:d2:dc:88:8f:f9:f5:ff:26:b3:cb:
+ 73:09:cf:36:b9:28:23:c0:8c:90:51:61:a7:a1:f6:
+ 73:c6:e2:41:b5:d3:ce:8f:38:99:84:3f:96:be:21:
+ df:15:74:e4:dc:1d:df:45:68:a1:bd:d8:75:ca:bc:
+ 42:64:74:de:25:3b:a5:0a:0b:fb:d7:6a:63:e3:19:
+ 48:a9:5b:33:07:e2:bc:02:d5:86:06:5d:3c:fc:75:
+ 96:ea:eb:6d:41:ea:96:52:28:63:2c:a7:f2:13:e9:
+ a9:7f:e3:15:c1:94:31:59:c2:48:e8:b1:9c:ee:10:
+ 57:64:ef:6d:35:66:c2:46:d0:af:5f:b8:60:d8:48:
+ 47:ed:75:5d:ae:86:d4:85:ed:95:5d:0e:e7:ec:be:
+ 85:14:22:03:3e:ed:62:b1:c3:05:b9:b8:2e:77:6a:
+ 86:42:13:68:2c:33:86:f4:89:34:67:db:90:77:51:
+ 0a:a1:23:b4:46:06:22:16:e5:fb:c1:85:ef:2d:60:
+ 60:76:5a:1f:d7:c7:93:83:5c:b7:3b:76:d9:ba:01:
+ 90:29:d3:ea:84:de:26:10:79:7f:05:2f:ab:80:6e:
+ 18:80:bb:eb:26:d1:8c:5d:bd:79:4b:24:05:62:0f:
+ 38:7c:87:fe:1d:6e:5c:16:a2:34:b4:7a:d3:bb:54:
+ 24:d5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 85:85:73:C1:C8:A5:7B:1C:6D:25:84:2A:CE:2B:A3:E4:21:E4:AE:D0
+ X509v3 Authority Key Identifier:
+ keyid:85:85:73:C1:C8:A5:7B:1C:6D:25:84:2A:CE:2B:A3:E4:21:E4:AE:D0
+
+ 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
+ 37:89:65:ac:ae:76:77:0d:71:a3:1c:e3:bf:80:fe:87:f8:49:
+ d3:8b:7f:cf:2a:51:18:b1:f5:a3:6a:d0:e5:e1:7e:f9:83:ca:
+ 11:2b:fc:e5:9e:cc:df:ee:a2:f9:ea:d2:19:32:fa:58:88:cd:
+ 59:5c:d6:42:7f:75:2f:17:93:7d:90:8c:7a:60:3a:24:15:15:
+ 62:82:97:c1:49:81:81:12:25:4a:b9:83:d7:39:dc:2b:da:39:
+ a9:58:6a:82:5c:7d:49:00:c2:cd:c2:dc:84:4a:23:df:9c:81:
+ a2:42:fc:4b:66:87:0b:63:12:d3:b8:59:9b:a6:5a:b0:5f:ff:
+ 51:37:92:03:0c:bb:61:6c:1a:ed:2e:05:e6:d0:a7:2f:d8:7c:
+ 5c:31:f2:84:f2:9b:05:bd:b5:35:35:a4:28:55:fa:23:32:33:
+ 4f:6b:91:55:9e:0f:1e:c7:1e:9a:12:c3:97:8d:3c:f9:c8:51:
+ 27:5b:19:a2:7a:c6:2a:0d:d4:b3:6e:b8:f0:8f:d3:c4:e4:26:
+ 3a:64:93:70:65:5f:2d:f7:73:31:e7:95:e6:23:1f:f4:17:b9:
+ d4:ed:20:e2:4f:45:32:a3:e9:7d:6a:2e:02:76:40:8a:ac:64:
+ c0:b2:99:11:63:de:64:f4:1f:6d:65:4c:84:1e:59:4f:e1:07:
+ 99:23:0e:d4
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFIB+PS3IiP+fX/JrPL
+cwnPNrkoI8CMkFFhp6H2c8biQbXTzo84mYQ/lr4h3xV05Nwd30Voob3Ydcq8QmR0
+3iU7pQoL+9dqY+MZSKlbMwfivALVhgZdPPx1lurrbUHqllIoYyyn8hPpqX/jFcGU
+MVnCSOixnO4QV2TvbTVmwkbQr1+4YNhIR+11Xa6G1IXtlV0O5+y+hRQiAz7tYrHD
+Bbm4LndqhkITaCwzhvSJNGfbkHdRCqEjtEYGIhbl+8GF7y1gYHZaH9fHk4Nctzt2
+2boBkCnT6oTeJhB5fwUvq4BuGIC76ybRjF29eUskBWIPOHyH/h1uXBaiNLR607tU
+JNUCAwEAAaOByzCByDAdBgNVHQ4EFgQUhYVzwcilexxtJYQqziuj5CHkrtAwHwYD
+VR0jBBgwFoAUhYVzwcilexxtJYQqziuj5CHkrtAwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA3iWWsrnZ3
+DXGjHOO/gP6H+EnTi3/PKlEYsfWjatDl4X75g8oRK/zlnszf7qL56tIZMvpYiM1Z
+XNZCf3UvF5N9kIx6YDokFRVigpfBSYGBEiVKuYPXOdwr2jmpWGqCXH1JAMLNwtyE
+SiPfnIGiQvxLZocLYxLTuFmbplqwX/9RN5IDDLthbBrtLgXm0Kcv2HxcMfKE8psF
+vbU1NaQoVfojMjNPa5FVng8exx6aEsOXjTz5yFEnWxmiesYqDdSzbrjwj9PE5CY6
+ZJNwZV8t93Mx55XmIx/0F7nU7SDiT0Uyo+l9ai4CdkCKrGTAspkRY95k9B9tZUyE
+HllP4QeZIw7U
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTQwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/expired-target.pem b/chromium/net/data/verify_certificate_chain_unittest/expired-target.pem
new file mode 100644
index 00000000000..40b08c62bfb
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/expired-target.pem
@@ -0,0 +1,280 @@
+[Created by: generate-expired-target.py]
+
+Certificate chain with 1 intermediary, where the target is expired (violates
+validity.notAfter). Verification is expected to fail.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e4:45:ec:2b:33:db:da:8a:1f:b0:9c:73:6b:4b:
+ c2:a7:60:29:4f:61:1c:a6:5d:2a:17:76:d1:87:76:
+ ec:d7:2c:a6:80:72:62:c1:0c:7b:01:d4:6e:7a:c5:
+ fe:cc:89:1b:e6:4b:ef:76:0b:b8:46:b0:39:c0:50:
+ 54:44:97:d8:ea:4a:95:ae:3e:2c:38:1a:69:51:06:
+ cb:4d:85:44:e0:57:49:30:78:cc:fd:40:81:52:1a:
+ 43:c7:4a:02:db:b0:90:3a:b9:5f:7a:bd:a1:b1:7d:
+ a5:f7:ed:95:c5:e6:da:0e:d5:1a:fa:12:ce:2e:4f:
+ 6b:7c:a4:6b:de:89:47:0d:b9:34:62:c2:3a:06:db:
+ 72:2e:56:29:ca:80:d0:80:27:9e:3f:bf:73:b1:14:
+ 3c:88:f5:31:d3:d9:27:54:46:c3:b2:e3:59:f4:54:
+ 37:b8:73:b5:04:6b:6d:d2:e2:93:e6:57:2e:f8:3a:
+ 36:24:7c:fa:33:da:1a:5b:5d:da:f5:91:87:67:4a:
+ ca:2e:79:47:df:8c:33:8b:36:76:39:79:63:a9:7d:
+ 26:ef:95:22:e2:16:de:0a:1a:4a:4b:74:e3:d8:c5:
+ b9:ee:60:8d:ad:f7:cf:d4:d6:4e:b0:27:18:84:d1:
+ e3:ef:23:b8:00:6d:71:e8:a0:8e:bb:84:72:d9:75:
+ 76:6d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 40:D1:E0:A6:C2:37:1A:32:25:B8:D9:6D:5E:67:E7:CA:E0:76:30:16
+ X509v3 Authority Key Identifier:
+ keyid:DA:CD:B0:93:32:B4:DB:D9:38:FF:99:C6:AF:A7:44:80:D0:C0:4A:A1
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 08:63:be:8b:50:78:97:05:7a:ee:a4:f1:fe:6f:bd:68:84:c4:
+ ce:e6:c9:fd:30:d8:27:a6:3c:37:74:21:4a:69:23:81:5f:da:
+ 02:56:45:f4:1e:a0:22:4c:43:8c:f0:65:c2:cb:db:68:05:5b:
+ 94:4b:93:3a:08:77:da:a0:67:3f:b2:d3:95:09:ad:ed:1e:e2:
+ 91:a4:8e:63:7d:37:d8:90:20:83:60:ab:0f:b7:ec:73:69:69:
+ b3:8e:54:6f:54:5b:95:de:2d:c9:49:73:5e:87:43:7e:37:07:
+ 02:a7:b7:df:e5:5e:9b:77:fb:9a:1f:15:29:29:f4:7e:00:e4:
+ 6f:5c:d2:66:46:5f:54:c4:6b:b2:50:2f:f4:78:8a:5e:cb:da:
+ 32:56:1c:ae:a7:92:d0:8e:71:95:6c:b1:ba:6c:b3:eb:3c:29:
+ 57:4e:e1:cd:8a:ef:41:ea:bd:7f:ce:17:cf:f5:9c:ec:d6:21:
+ cf:e2:e8:2d:b6:b9:dd:d9:2a:fe:d0:91:54:0e:15:a0:d3:ae:
+ ea:92:f9:98:c5:a2:da:a6:0d:89:8f:c9:fe:2e:25:9b:f4:f1:
+ 7f:ae:1a:5b:0f:94:c0:49:fb:15:0a:bb:1f:2b:fe:ca:d1:8e:
+ 10:94:16:c6:a0:a0:af:b9:5d:6a:31:c2:87:94:ee:ca:1e:93:
+ b3:ac:d6:dd
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkRewr
+M9vaih+wnHNrS8KnYClPYRymXSoXdtGHduzXLKaAcmLBDHsB1G56xf7MiRvmS+92
+C7hGsDnAUFREl9jqSpWuPiw4GmlRBstNhUTgV0kweMz9QIFSGkPHSgLbsJA6uV96
+vaGxfaX37ZXF5toO1Rr6Es4uT2t8pGveiUcNuTRiwjoG23IuVinKgNCAJ54/v3Ox
+FDyI9THT2SdURsOy41n0VDe4c7UEa23S4pPmVy74OjYkfPoz2hpbXdr1kYdnSsou
+eUffjDOLNnY5eWOpfSbvlSLiFt4KGkpLdOPYxbnuYI2t98/U1k6wJxiE0ePvI7gA
+bXHooI67hHLZdXZtAgMBAAGjgekwgeYwHQYDVR0OBBYEFEDR4KbCNxoyJbjZbV5n
+58rgdjAWMB8GA1UdIwQYMBaAFNrNsJMytNvZOP+Zxq+nRIDQwEqhMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEACGO+i1B4lwV67qTx/m+9
+aITEzubJ/TDYJ6Y8N3QhSmkjgV/aAlZF9B6gIkxDjPBlwsvbaAVblEuTOgh32qBn
+P7LTlQmt7R7ikaSOY3032JAgg2CrD7fsc2lps45Ub1Rbld4tyUlzXodDfjcHAqe3
+3+Vem3f7mh8VKSn0fgDkb1zSZkZfVMRrslAv9HiKXsvaMlYcrqeS0I5xlWyxumyz
+6zwpV07hzYrvQeq9f84Xz/Wc7NYhz+LoLba53dkq/tCRVA4VoNOu6pL5mMWi2qYN
+iY/J/i4lm/Txf64aWw+UwEn7FQq7Hyv+ytGOEJQWxqCgr7ldajHCh5Tuyh6Ts6zW
+3Q==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b9:80:44:8f:9b:41:d5:be:e0:1a:a7:a4:4d:4e:
+ a0:52:ae:81:e7:c4:bd:f9:79:80:36:6e:8e:2a:56:
+ a9:84:26:da:d5:ad:e2:2a:5a:0e:68:2d:e9:ab:24:
+ 52:89:8e:7e:99:3d:b6:b7:ca:27:b7:80:45:38:4a:
+ eb:66:54:e1:28:a3:0e:df:a1:b7:63:4c:e1:44:e1:
+ af:6f:60:b3:35:af:9e:4d:51:cc:51:4c:70:8f:6b:
+ f2:73:c4:39:cb:a6:0b:9f:14:27:1a:90:f6:75:d3:
+ 3c:a0:b7:ba:3d:7c:27:eb:b3:b1:37:58:2a:e1:d8:
+ 62:09:dc:07:33:41:40:34:2c:93:98:e5:26:bc:d6:
+ 98:ed:75:b2:f1:98:4a:71:b4:21:61:96:12:98:7f:
+ 24:6e:d8:37:f2:2b:54:1e:4a:b0:8a:d9:2c:ab:b7:
+ 88:f5:a7:fb:fe:a7:04:b7:35:82:66:3f:ea:fb:eb:
+ 15:26:ae:52:ae:34:ec:da:fe:08:fa:ef:fd:40:f6:
+ 8d:b4:c5:68:a7:e3:60:2c:dc:b8:e0:3e:54:a9:60:
+ 11:7d:1e:54:37:98:b1:c2:fe:d0:fd:fa:b5:e6:f9:
+ bd:a6:50:b9:b6:1b:ec:3f:dc:ed:c2:d7:01:37:9e:
+ 69:24:90:05:d5:f2:26:fa:76:f3:76:34:e5:b7:88:
+ 92:95
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ DA:CD:B0:93:32:B4:DB:D9:38:FF:99:C6:AF:A7:44:80:D0:C0:4A:A1
+ X509v3 Authority Key Identifier:
+ keyid:CB:65:23:DB:47:DE:B5:40:EC:44:D8:90:A7:D6:C0:78:81:FA:E2:CE
+
+ 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
+ 9d:a0:3a:08:79:82:a7:ac:d8:e9:bc:8a:e1:32:88:09:c8:de:
+ 54:ed:6f:43:fd:ab:68:b2:32:37:8e:74:de:37:da:f9:31:2d:
+ ee:d6:f7:0b:d2:25:f9:16:1e:93:f1:f3:e1:fd:fd:0f:ac:75:
+ 7b:a4:60:09:4c:0f:ea:45:5b:46:cf:e5:5a:c9:36:37:17:ee:
+ cf:44:82:51:c9:ba:eb:55:13:2d:f5:6f:83:9e:01:0c:04:ff:
+ 58:ad:50:54:7c:ee:a5:a4:e6:3c:93:46:c8:a7:bd:6f:18:7f:
+ d0:5c:1c:8a:a4:f3:1d:e3:d7:a3:1d:7e:a4:ca:cd:1b:92:ff:
+ 26:13:cc:b8:89:b2:b8:24:0c:30:df:43:70:20:5d:72:3f:b0:
+ 0e:8b:08:3e:e5:52:c9:d8:65:db:c6:31:95:a1:c4:56:b4:1f:
+ eb:af:e8:9c:8b:78:c2:75:c4:f1:98:e1:20:d6:5a:32:9f:94:
+ 75:c0:a5:86:da:79:a7:d3:25:20:56:13:dd:04:27:bd:e7:27:
+ 21:9d:8d:1d:dd:87:bc:6e:07:fd:9f:64:c5:7e:ac:2a:a4:a8:
+ e5:29:d1:5b:e2:24:6c:db:ca:3a:b6:13:34:00:81:15:08:1d:
+ fb:eb:ac:1a:ab:53:3e:31:db:30:40:4e:17:f3:98:53:00:d8:
+ d1:b8:5c:58
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuYBEj5tB
+1b7gGqekTU6gUq6B58S9+XmANm6OKlaphCba1a3iKloOaC3pqyRSiY5+mT22t8on
+t4BFOErrZlThKKMO36G3Y0zhROGvb2CzNa+eTVHMUUxwj2vyc8Q5y6YLnxQnGpD2
+ddM8oLe6PXwn67OxN1gq4dhiCdwHM0FANCyTmOUmvNaY7XWy8ZhKcbQhYZYSmH8k
+btg38itUHkqwitksq7eI9af7/qcEtzWCZj/q++sVJq5SrjTs2v4I+u/9QPaNtMVo
+p+NgLNy44D5UqWARfR5UN5ixwv7Q/fq15vm9plC5thvsP9ztwtcBN55pJJAF1fIm
++nbzdjTlt4iSlQIDAQABo4HLMIHIMB0GA1UdDgQWBBTazbCTMrTb2Tj/mcavp0SA
+0MBKoTAfBgNVHSMEGDAWgBTLZSPbR961QOxE2JCn1sB4gfrizjA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AJ2gOgh5gqes2Om8iuEyiAnI3lTtb0P9q2iyMjeOdN432vkxLe7W9wvSJfkWHpPx
+8+H9/Q+sdXukYAlMD+pFW0bP5VrJNjcX7s9EglHJuutVEy31b4OeAQwE/1itUFR8
+7qWk5jyTRsinvW8Yf9BcHIqk8x3j16MdfqTKzRuS/yYTzLiJsrgkDDDfQ3AgXXI/
+sA6LCD7lUsnYZdvGMZWhxFa0H+uv6JyLeMJ1xPGY4SDWWjKflHXApYbaeafTJSBW
+E90EJ73nJyGdjR3dh7xuB/2fZMV+rCqkqOUp0VviJGzbyjq2EzQAgRUIHfvrrBqr
+Uz4x2zBAThfzmFMA2NG4XFg=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c6:2e:8f:2a:f4:b2:4f:96:3c:a7:4e:f6:92:54:
+ be:34:77:64:65:fe:dd:dc:fd:11:29:a7:6c:56:04:
+ 9d:70:2f:3c:3f:55:e5:54:79:f0:bb:5f:79:97:f0:
+ 7b:0a:22:fb:66:d5:e8:6d:30:81:93:99:a5:8f:a5:
+ e2:33:b8:bd:05:9e:b1:c7:0a:63:75:12:e6:ac:75:
+ a3:1c:58:a0:c5:7b:40:45:60:f9:6a:8e:45:2a:59:
+ 7e:5f:8a:b8:a3:c9:bc:9d:dd:aa:d9:1d:85:30:67:
+ 67:db:d3:04:aa:cf:e9:42:fe:5d:df:46:ac:06:59:
+ 51:16:a0:e0:6c:f4:c0:ca:f6:c4:85:24:91:60:84:
+ b1:d0:92:7f:ab:ef:ce:5c:35:07:bc:03:72:32:c8:
+ 40:67:23:13:08:db:08:f3:cc:a0:75:e4:08:f7:e9:
+ ba:b3:e1:17:57:b1:16:93:ac:07:fa:04:1c:a7:6c:
+ d6:12:4f:c5:75:da:d4:6d:99:21:d1:9e:84:15:7a:
+ 34:ff:89:4e:c2:5b:43:89:86:63:90:db:37:93:15:
+ 57:27:0e:7a:c9:bb:21:a8:06:69:5d:41:b5:19:24:
+ bf:08:ea:67:0c:26:22:a3:86:7e:e0:04:d0:82:48:
+ b4:f5:48:01:56:20:6e:73:6d:c5:e1:62:1b:8e:f2:
+ bd:e7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ CB:65:23:DB:47:DE:B5:40:EC:44:D8:90:A7:D6:C0:78:81:FA:E2:CE
+ X509v3 Authority Key Identifier:
+ keyid:CB:65:23:DB:47:DE:B5:40:EC:44:D8:90:A7:D6:C0:78:81:FA:E2:CE
+
+ 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
+ 74:69:8a:c4:51:dd:1d:be:5d:53:de:9d:de:c7:91:3a:0d:47:
+ 2f:36:0d:d8:a7:c9:89:7e:68:8f:86:ed:af:e6:83:9c:9e:4e:
+ 99:df:ae:bb:e7:d0:c2:e4:b9:e7:e5:71:f5:4f:c4:55:a5:1d:
+ a6:93:2c:f8:5f:ab:45:b4:37:74:bc:14:d6:32:b0:f5:c4:82:
+ b0:5e:47:14:52:37:64:14:4e:25:f5:bf:db:41:27:78:56:29:
+ 6a:35:87:62:ef:f8:35:fa:51:d7:36:96:b3:6a:6e:bd:3f:ad:
+ a5:0f:c8:25:7e:11:26:96:1b:a2:32:ac:21:ad:a8:ff:31:32:
+ 3d:f3:aa:07:df:f7:72:28:12:a7:b9:40:38:b6:6f:69:89:4e:
+ 33:52:fc:40:61:85:de:b1:29:92:b5:47:b3:f6:a4:37:1c:8c:
+ b9:1b:02:52:72:a1:4d:46:aa:84:32:8e:d8:c9:e5:87:87:3d:
+ 66:8f:a1:af:ef:71:3e:a0:a3:8d:cb:75:4b:57:d6:c8:03:e2:
+ 40:e3:85:cd:a7:cb:af:cc:49:9c:4c:a2:2a:8c:75:6a:70:88:
+ 3e:6a:24:a1:35:85:e7:6d:0d:7a:b1:35:45:e3:8e:a8:a6:c9:
+ 0c:d3:78:41:44:5c:0b:d1:ff:b0:b2:91:ed:a0:83:c7:04:b3:
+ a9:a7:c1:6e
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMYujyr0sk+WPKdO9pJU
+vjR3ZGX+3dz9ESmnbFYEnXAvPD9V5VR58LtfeZfwewoi+2bV6G0wgZOZpY+l4jO4
+vQWesccKY3US5qx1oxxYoMV7QEVg+WqORSpZfl+KuKPJvJ3dqtkdhTBnZ9vTBKrP
+6UL+Xd9GrAZZURag4Gz0wMr2xIUkkWCEsdCSf6vvzlw1B7wDcjLIQGcjEwjbCPPM
+oHXkCPfpurPhF1exFpOsB/oEHKds1hJPxXXa1G2ZIdGehBV6NP+JTsJbQ4mGY5Db
+N5MVVycOesm7IagGaV1BtRkkvwjqZwwmIqOGfuAE0IJItPVIAVYgbnNtxeFiG47y
+vecCAwEAAaOByzCByDAdBgNVHQ4EFgQUy2Uj20fetUDsRNiQp9bAeIH64s4wHwYD
+VR0jBBgwFoAUy2Uj20fetUDsRNiQp9bAeIH64s4wNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB0aYrEUd0d
+vl1T3p3ex5E6DUcvNg3Yp8mJfmiPhu2v5oOcnk6Z366759DC5Lnn5XH1T8RVpR2m
+kyz4X6tFtDd0vBTWMrD1xIKwXkcUUjdkFE4l9b/bQSd4VilqNYdi7/g1+lHXNpaz
+am69P62lD8glfhEmlhuiMqwhraj/MTI986oH3/dyKBKnuUA4tm9piU4zUvxAYYXe
+sSmStUez9qQ3HIy5GwJScqFNRqqEMo7YyeWHhz1mj6Gv73E+oKONy3VLV9bIA+JA
+44XNp8uvzEmcTKIqjHVqcIg+aiShNYXnbQ16sTVF446opskM03hBRFwL0f+wspHt
+oIPHBLOpp8Fu
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTYwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-all.sh b/chromium/net/data/verify_certificate_chain_unittest/generate-all.sh
new file mode 100755
index 00000000000..63374a020cb
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-all.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# Copyright 2015 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.
+
+set -e
+set -x
+
+for script in generate-*.py ; do
+ python "$script"
+done
+
+# Cleanup temporary files.
+rm -rf *.pyc
+rm -rf out/
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py b/chromium/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py
new file mode 100755
index 00000000000..03c6eb50d71
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 2 intermediaries. The first intermediary has a basic
+constraints path length of 0. The second one is self-issued so does not count
+against the path length."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary with pathlen 0
+intermediary1 = common.create_intermediary_certificate('Intermediary', root)
+intermediary1.get_extensions().set_property('basicConstraints',
+ 'critical,CA:true,pathlen:0')
+
+# Another intermediary (with the same pathlen restriction).
+# Note that this is self-issued but NOT self-signed.
+intermediary2 = common.create_intermediary_certificate('Intermediary',
+ intermediary1)
+intermediary2.get_extensions().set_property('basicConstraints',
+ 'critical,CA:true,pathlen:0')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary2)
+
+chain = [target, intermediary2, intermediary1]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = True
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-expired-intermediary.py b/chromium/net/data/verify_certificate_chain_unittest/generate-expired-intermediary.py
new file mode 100755
index 00000000000..7a97fe36526
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-expired-intermediary.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary, where the intermediary is expired
+(violates validity.notAfter). Verification is expected to fail."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.set_validity_range(common.JANUARY_1_2015_UTC,
+ common.JANUARY_1_2016_UTC)
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+
+# March 2nd, 2016 midnight UTC
+time = '160302120000Z'
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py b/chromium/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py
new file mode 100755
index 00000000000..3ff7d63cb08
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary, where the target is expired (violates
+validity.notBefore). Verification is expected to fail."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+target.set_validity_range(common.JANUARY_1_2015_UTC, common.JANUARY_1_2016_UTC)
+
+chain = [target, intermediary]
+trusted = [root]
+
+# March 2nd, 2014 midnight UTC
+time = '140302120000Z'
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-expired-target.py b/chromium/net/data/verify_certificate_chain_unittest/generate-expired-target.py
new file mode 100755
index 00000000000..b3b3c531d14
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-expired-target.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary, where the target is expired (violates
+validity.notAfter). Verification is expected to fail."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+target.set_validity_range(common.JANUARY_1_2015_UTC, common.JANUARY_1_2016_UTC)
+
+chain = [target, intermediary]
+trusted = [root]
+
+# March 2nd, 2016 midnight UTC
+time = '160302120000Z'
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-ca-false.py b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-ca-false.py
new file mode 100755
index 00000000000..4375f0e36b4
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-ca-false.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The intermediary
+has a basic constraints extension that indicates it is NOT a CA. Verification
+is expected to fail."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary with incorrect basic constraints.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.get_extensions().set_property('basicConstraints',
+ 'critical,CA:false')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-not-critical.py b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-not-critical.py
new file mode 100755
index 00000000000..284354fd6eb
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-basic-constraints-not-critical.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The intermediary
+has a basic constraints extension but does not mark it as critical.
+Verification is expected to succeed, since although not critical, the
+basicConstraints indicates CA=true as expected."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary with non-critical basic constarints.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.get_extensions().set_property('basicConstraints', 'CA:true')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = True
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-basic-constraints.py b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-basic-constraints.py
new file mode 100755
index 00000000000..1faced54a1c
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-basic-constraints.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The intermediary
+lacks the basic constraints extension, and hence is expected to fail validation
+(RFC 5280 requires v3 signing certificates have a BasicConstaints)."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary that lacks basic constraints.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.get_extensions().remove_property('basicConstraints')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-signing-key-usage.py b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-signing-key-usage.py
new file mode 100755
index 00000000000..4c3d8e8898e
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-lacks-signing-key-usage.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The intermediary
+contains a keyUsage extension, HOWEVER it does not contain the keyCertSign bit.
+Hence validation is expected to fail."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary that is missing keyCertSign.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.get_extensions().set_property('keyUsage',
+ 'critical,digitalSignature,keyEncipherment')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-signed-with-md5.py b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-signed-with-md5.py
new file mode 100755
index 00000000000..8a59e6516d8
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-signed-with-md5.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The intermediary
+however is signed using the MD5 hash. Verification is expected to fail because
+MD5 is too weak."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.set_signature_hash('md5')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-critical-extension.py b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-critical-extension.py
new file mode 100755
index 00000000000..39c059736d3
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-critical-extension.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The intermediary
+has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as critical.
+Verifying this certificate chain is expected to fail because there is an
+unrecognized critical extension."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary that has an unknown critical extension.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.get_extensions().add_property('1.2.3.4',
+ 'critical,DER:01:02:03:04')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-non-critical-extension.py b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-non-critical-extension.py
new file mode 100755
index 00000000000..874a6585a08
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-intermediary-unknown-non-critical-extension.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The intermediary
+has an unknown X.509v3 extension that is marked as non-critical. Verification
+is expected to succeed because although unrecognized, the extension is not
+critical."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Intermediary that has an unknown non-critical extension.
+intermediary.get_extensions().add_property('1.2.3.4', 'DER:01:02:03:04')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = True
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-and-intermediary.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-and-intermediary.py
new file mode 100755
index 00000000000..94525cc25e7
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-and-intermediary.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. Verification is
+expected to succeed."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = True
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py
new file mode 100755
index 00000000000..fa3cafb4022
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary, a trusted root, and a target
+certificate that is not a CA, and yet has the keyCertSign bit set. Verification
+is expected to fail, since keyCertSign should only be asserted when CA is
+true."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate (end entity but has keyCertSign bit set).
+target = common.create_end_entity_certificate('Target', intermediary)
+target.get_extensions().set_property('keyUsage',
+ 'critical,digitalSignature,keyEncipherment,keyCertSign')
+
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py
new file mode 100755
index 00000000000..5d297393262
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary, a trusted root, and a target
+certificate that is not a CA, and yet has a pathlen set. Verification is
+expected to fail, since pathlen should only be set for CAs."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate (end entity, but has pathlen set).
+target = common.create_end_entity_certificate('Target', intermediary)
+target.get_extensions().set_property('basicConstraints',
+ 'critical,CA:false,pathlen:1')
+
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py
new file mode 100755
index 00000000000..83573ad9649
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary, a trusted root, and a target
+certificate that is also a CA. Verification is expected to succeed, as the test
+code accepts any target certificate."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate (is also a CA)
+target = common.create_intermediary_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = True
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py
new file mode 100755
index 00000000000..75144a0d8ea
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The target
+certificate is signed using a weak RSA key (512-bit modulus), and so
+verification is expected to fail."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary with a very weak key size (512-bit RSA).
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.generate_rsa_key(512)
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py
new file mode 100755
index 00000000000..562ebb1fc27
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with a trusted root using RSA, and intermediary using EC,
+and a target certificate using RSA. Verification is expected to succeed."""
+
+import common
+
+# Self-signed root certificate (part of trust store), using RSA.
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary using an EC key for the P-384 curve.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+intermediary.generate_ec_key('secp384r1')
+
+# Target certificate contains an RSA key (but is signed using ECDSA).
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = True
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py
new file mode 100755
index 00000000000..743ad25b283
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with an intermediary that uses MD5 to sign the target
+certificate. This is expected to fail because MD5 is too weak."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+target.set_signature_hash('md5')
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py
new file mode 100755
index 00000000000..725429920c8
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary and a trusted root. The target
+certificate has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as
+critical. Verifying this certificate chain is expected to fail because there is
+an unrecognized critical extension."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate (has unknown critical extension).
+target = common.create_end_entity_certificate('Target', intermediary)
+target.get_extensions().add_property('1.2.3.4',
+ 'critical,DER:01:02:03:04')
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py b/chromium/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py
new file mode 100755
index 00000000000..162f7160bc7
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain where the target has an incorrect signature. Everything
+else should check out, however the digital signature contained in the target
+certificate is wrong."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate to include in the certificate chain.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Actual intermediate that was used to sign the target certificate. It has the
+# same subject as expected, but a different RSA key from the certificate
+# included in the actual chain.
+wrong_intermediary = common.create_intermediary_certificate('Intermediary',
+ root)
+
+# Target certificate, signed using |wrong_intermediary| NOT |intermediary|.
+target = common.create_end_entity_certificate('Target', wrong_intermediary)
+
+chain = [target, intermediary]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-unknown-root.py b/chromium/net/data/verify_certificate_chain_unittest/generate-unknown-root.py
new file mode 100755
index 00000000000..4f0b5f5098d
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-unknown-root.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 1 intermediary, but the root is not in trust store.
+Verification is expected to fail because the final intermediary (Intermediary)
+does not chain to a known root."""
+
+import common
+
+# Self-signed root certificate, which is NOT added to the trust store.
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary certificate.
+intermediary = common.create_intermediary_certificate('Intermediary', root)
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary)
+
+chain = [target, intermediary]
+trusted = [] # Note that this lacks |root|
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py b/chromium/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py
new file mode 100755
index 00000000000..0298956edb3
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Certificate chain with 2 intermediaries. The first intermediary has a basic
+constraints path length of 0, so it is a violation for it to have a subordinate
+intermediary."""
+
+import common
+
+# Self-signed root certificate (part of trust store).
+root = common.create_self_signed_root_certificate('Root')
+
+# Intermediary with pathlen 0
+intermediary1 = common.create_intermediary_certificate('Intermediary1', root)
+intermediary1.get_extensions().set_property('basicConstraints',
+ 'critical,CA:true,pathlen:0')
+
+# Another intermediary (with the same pathlen restriction)
+intermediary2 = common.create_intermediary_certificate('Intermediary2',
+ intermediary1)
+intermediary2.get_extensions().set_property('basicConstraints',
+ 'critical,CA:true,pathlen:0')
+
+# Target certificate.
+target = common.create_end_entity_certificate('Target', intermediary2)
+
+chain = [target, intermediary2, intermediary1]
+trusted = [root]
+time = common.DEFAULT_TIME
+verify_result = False
+
+common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-ca-false.pem b/chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-ca-false.pem
new file mode 100644
index 00000000000..04bbffe7844
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-ca-false.pem
@@ -0,0 +1,281 @@
+[Created by: generate-intermediary-basic-constraints-ca-false.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+has a basic constraints extension that indicates it is NOT a CA. Verification
+is expected to fail.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d7:2c:b6:2c:cc:74:93:54:76:43:6a:c8:78:5d:
+ c4:cc:30:ab:d1:16:46:84:b6:d8:28:13:74:4f:7f:
+ 6c:e1:ef:0c:12:07:c8:f5:2b:bd:98:3e:5f:ec:3c:
+ 6b:96:6b:7d:42:d1:a0:1c:e3:9a:c5:04:10:9f:f6:
+ d8:d2:e9:0b:98:3b:40:f1:3d:9f:39:fd:70:7b:d3:
+ f6:af:83:14:48:89:1c:87:aa:f1:21:fc:ab:f4:1e:
+ b3:66:3b:1e:ae:f9:9b:5d:9b:6d:6c:19:14:e2:38:
+ 09:36:99:be:b6:c0:27:50:91:33:c5:8d:11:4b:83:
+ 95:db:21:d6:3b:a8:7c:d9:a7:6b:04:cc:d4:81:28:
+ 8e:bb:57:76:2a:d9:d9:fa:31:07:62:dc:34:af:2d:
+ ec:7d:2f:8c:73:b9:57:44:cc:86:3b:49:d5:45:df:
+ bd:11:97:4e:b5:d2:07:17:71:39:0c:54:5b:c7:76:
+ db:69:64:e6:0d:3d:a2:c8:bc:45:35:06:f4:6f:fb:
+ ff:e5:23:53:9d:36:92:b5:15:2e:c7:62:62:22:69:
+ 66:62:2c:51:ee:1c:b7:2e:10:82:14:e2:ff:3f:f9:
+ 4e:a5:ad:70:fe:c8:26:d3:99:fb:ee:ea:67:f9:8a:
+ 06:b8:a1:60:99:4f:ef:95:0e:96:3a:c2:35:11:e9:
+ 4e:7d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 34:A4:95:47:59:7D:2A:43:E3:DD:5F:55:F7:D0:F4:C0:25:E5:AD:8E
+ X509v3 Authority Key Identifier:
+ keyid:9F:6B:93:D1:46:61:07:80:55:0A:40:C8:FE:A8:D8:DD:8E:B1:EF:DD
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 75:a4:8c:02:02:da:03:71:90:d9:46:cc:6a:21:36:ef:86:21:
+ 68:60:4a:a9:ce:af:f6:49:cf:f4:6b:b0:96:42:60:d5:02:91:
+ 62:93:01:8b:cb:0b:eb:a5:b0:b8:49:6c:8e:54:84:c2:53:d4:
+ 46:09:d6:db:29:96:a0:45:e5:09:5b:c1:b7:ba:be:8a:43:62:
+ f9:8b:e4:47:d5:a9:d9:03:0e:83:86:78:19:81:c8:3b:20:86:
+ 1d:72:98:cd:06:73:fa:b1:e4:df:fd:08:9c:52:bb:f6:48:61:
+ bc:6f:3f:1e:1c:ef:f5:4e:94:5b:ee:e7:96:44:ff:1a:8d:6c:
+ a6:9c:d1:77:17:1f:c7:e1:53:d5:5e:a5:d8:55:c8:36:48:f6:
+ 8c:25:c3:1b:27:09:58:8e:30:6a:ad:ad:5e:0a:2e:5f:6f:5a:
+ cb:1a:fb:fe:c9:03:1f:bf:37:9c:b5:c3:93:b7:4c:a2:d5:e2:
+ ac:af:94:91:85:22:8c:c7:8b:b0:39:4a:67:f0:82:dc:db:fe:
+ 39:3c:1d:50:4c:70:44:7e:aa:73:e4:fd:51:48:12:ea:9c:18:
+ b1:27:6b:96:e7:aa:cf:f6:58:bf:05:d0:a4:51:71:27:b6:2c:
+ 3d:a7:50:4d:93:1a:8d:04:84:7e:d3:9f:0d:b5:a5:6b:d3:db:
+ d4:3a:03:fb
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDXLLYs
+zHSTVHZDash4XcTMMKvRFkaEttgoE3RPf2zh7wwSB8j1K72YPl/sPGuWa31C0aAc
+45rFBBCf9tjS6QuYO0DxPZ85/XB70/avgxRIiRyHqvEh/Kv0HrNmOx6u+Ztdm21s
+GRTiOAk2mb62wCdQkTPFjRFLg5XbIdY7qHzZp2sEzNSBKI67V3Yq2dn6MQdi3DSv
+Lex9L4xzuVdEzIY7SdVF370Rl0610gcXcTkMVFvHdttpZOYNPaLIvEU1BvRv+//l
+I1OdNpK1FS7HYmIiaWZiLFHuHLcuEIIU4v8/+U6lrXD+yCbTmfvu6mf5iga4oWCZ
+T++VDpY6wjUR6U59AgMBAAGjgekwgeYwHQYDVR0OBBYEFDSklUdZfSpD491fVffQ
+9MAl5a2OMB8GA1UdIwQYMBaAFJ9rk9FGYQeAVQpAyP6o2N2Ose/dMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAdaSMAgLaA3GQ2UbMaiE2
+74YhaGBKqc6v9knP9GuwlkJg1QKRYpMBi8sL66WwuElsjlSEwlPURgnW2ymWoEXl
+CVvBt7q+ikNi+YvkR9Wp2QMOg4Z4GYHIOyCGHXKYzQZz+rHk3/0InFK79khhvG8/
+Hhzv9U6UW+7nlkT/Go1sppzRdxcfx+FT1V6l2FXINkj2jCXDGycJWI4waq2tXgou
+X29ayxr7/skDH783nLXDk7dMotXirK+UkYUijMeLsDlKZ/CC3Nv+OTwdUExwRH6q
+c+T9UUgS6pwYsSdrlueqz/ZYvwXQpFFxJ7YsPadQTZMajQSEftOfDbWla9Pb1DoD
++w==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b6:2b:92:72:9f:d2:59:95:3f:16:fd:eb:d3:37:
+ 3e:4d:fa:bf:05:3a:e3:8b:b5:32:90:42:9c:d7:69:
+ c5:30:e6:0f:d3:6d:fb:93:c0:0e:30:f2:9f:42:8d:
+ 83:17:62:e0:ac:41:c4:2b:29:4f:e6:c7:64:27:a8:
+ ca:c0:46:16:50:ba:e1:de:3a:ed:4b:1e:49:84:cf:
+ 16:2c:5d:84:0c:8e:0d:42:c0:d2:01:e3:94:2a:79:
+ d7:da:d7:a6:51:75:fe:a3:e5:1a:95:f5:38:a3:5b:
+ f8:5c:8a:a9:90:f1:f9:83:4a:13:25:61:bc:33:fb:
+ 19:69:71:c1:c1:a6:45:4a:bd:7f:3f:a6:92:43:fe:
+ db:88:a2:15:a9:41:cf:9d:62:9b:b4:fc:71:8f:4f:
+ be:5d:4a:48:8a:7a:de:57:11:82:44:49:a6:5c:25:
+ a0:8c:0b:f0:ec:74:51:76:ae:f4:5c:14:c6:d0:90:
+ b9:93:64:93:f8:04:82:99:28:98:fa:c8:a2:e8:98:
+ 20:2d:7d:cd:d9:99:ef:74:eb:7a:63:06:4c:7a:86:
+ 1e:e8:4b:8f:d0:8d:ab:d9:3a:8e:bc:ec:f2:2a:0d:
+ e1:5f:89:54:0f:ef:b8:28:ff:d5:f6:ef:a7:14:94:
+ 52:72:48:50:29:85:5b:d9:fd:1e:14:59:c8:69:df:
+ 89:47
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9F:6B:93:D1:46:61:07:80:55:0A:40:C8:FE:A8:D8:DD:8E:B1:EF:DD
+ X509v3 Authority Key Identifier:
+ keyid:D8:01:99:4C:28:49:4B:7F:FB:30:0A:92:A8:90:6F:8B:9C:45:05:7F
+
+ 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:FALSE
+ Signature Algorithm: sha256WithRSAEncryption
+ 7f:36:da:7c:f5:4a:3b:37:53:82:b4:98:99:0b:d7:c0:73:b9:
+ 05:89:75:fa:97:e4:cc:9d:73:61:18:ad:f2:bd:57:3f:6b:d0:
+ 45:a2:45:2a:27:68:13:f1:a3:80:15:85:13:52:4b:c6:8f:12:
+ 78:ba:21:51:fb:9d:1c:88:5d:5c:f5:0b:e5:66:ef:b4:72:67:
+ 16:cb:3d:79:83:56:9b:90:50:91:fe:f2:0c:f9:36:88:dd:14:
+ ef:b7:d2:1e:a3:54:d3:67:9f:3e:bc:7b:8c:45:be:12:c0:a9:
+ 21:cf:b7:ea:e9:9e:ec:e8:79:02:a0:48:3e:a8:b9:fc:62:9d:
+ a3:ab:74:b6:22:97:ab:78:7f:60:8e:67:96:02:ff:13:6d:66:
+ b9:df:a4:55:c7:e4:82:a9:f7:0d:30:d4:e9:6b:a9:25:68:f8:
+ 3c:2f:73:38:cf:07:af:b5:ef:82:5a:5f:34:0c:d9:0a:56:ad:
+ 30:c4:8a:2a:90:5c:92:e6:01:f5:49:4e:58:a0:13:0c:81:46:
+ ef:01:bc:8f:48:15:49:da:5d:20:28:a7:2a:b9:2b:85:9c:f8:
+ c4:5e:76:6f:ff:67:c0:2a:ee:96:91:2e:8d:b3:be:6b:66:51:
+ 0e:d5:7f:c9:21:c0:af:79:cc:07:0a:cc:dc:85:00:85:cf:74:
+ 9e:6f:2f:31
+-----BEGIN CERTIFICATE-----
+MIIDajCCAlKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtiuScp/S
+WZU/Fv3r0zc+Tfq/BTrji7UykEKc12nFMOYP0237k8AOMPKfQo2DF2LgrEHEKylP
+5sdkJ6jKwEYWULrh3jrtSx5JhM8WLF2EDI4NQsDSAeOUKnnX2temUXX+o+UalfU4
+o1v4XIqpkPH5g0oTJWG8M/sZaXHBwaZFSr1/P6aSQ/7biKIVqUHPnWKbtPxxj0++
+XUpIinreVxGCREmmXCWgjAvw7HRRdq70XBTG0JC5k2ST+ASCmSiY+sii6JggLX3N
+2ZnvdOt6YwZMeoYe6EuP0I2r2TqOvOzyKg3hX4lUD++4KP/V9u+nFJRSckhQKYVb
+2f0eFFnIad+JRwIDAQABo4HIMIHFMB0GA1UdDgQWBBSfa5PRRmEHgFUKQMj+qNjd
+jrHv3TAfBgNVHSMEGDAWgBTYAZlMKElLf/swCpKokG+LnEUFfzA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAH82
+2nz1Sjs3U4K0mJkL18BzuQWJdfqX5Mydc2EYrfK9Vz9r0EWiRSonaBPxo4AVhRNS
+S8aPEni6IVH7nRyIXVz1C+Vm77RyZxbLPXmDVpuQUJH+8gz5NojdFO+30h6jVNNn
+nz68e4xFvhLAqSHPt+rpnuzoeQKgSD6oufxinaOrdLYil6t4f2COZ5YC/xNtZrnf
+pFXH5IKp9w0w1OlrqSVo+DwvczjPB6+174JaXzQM2QpWrTDEiiqQXJLmAfVJTlig
+EwyBRu8BvI9IFUnaXSAopyq5K4Wc+MRedm//Z8Aq7paRLo2zvmtmUQ7Vf8khwK95
+zAcKzNyFAIXPdJ5vLzE=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a6:91:a5:68:ad:ba:89:8f:b6:5c:19:a1:3d:10:
+ ad:55:97:10:17:06:9a:7d:59:e7:7c:56:3d:1d:5f:
+ 17:c7:a2:e5:e7:80:52:a8:cd:ef:ca:82:4a:77:e4:
+ ac:77:7c:35:f1:1b:b3:7a:9a:58:78:9e:1c:00:c9:
+ 67:9d:4d:d0:f4:92:f1:0a:82:8a:f0:d4:57:04:04:
+ cc:12:e4:86:95:93:12:a7:9b:ee:6f:d2:85:5d:63:
+ 3c:5c:94:91:db:d0:3c:f1:a8:ca:05:19:22:98:e0:
+ ef:29:22:35:40:3c:7c:c4:74:5c:df:24:2b:e4:b8:
+ bc:23:ba:db:aa:6b:ef:ba:bb:aa:c2:ab:ce:9f:07:
+ 2e:36:da:21:67:4d:80:71:ba:4a:7b:62:16:08:51:
+ 29:35:dd:c8:1d:8c:60:d8:8c:05:a2:ec:f0:5e:af:
+ f4:f2:e8:95:03:c1:79:77:3e:ff:f4:31:ed:ab:cc:
+ 1b:dd:7e:f6:2c:71:3a:1c:e3:ab:ab:a4:ab:79:12:
+ 59:a5:f6:84:00:83:ff:8c:e5:3b:a0:4f:37:2a:b1:
+ c4:a5:19:69:46:2c:87:bc:a5:0e:ee:31:13:2e:0e:
+ ed:d2:e2:19:be:d0:14:b3:68:b5:34:c6:3f:6e:95:
+ da:eb:2c:55:30:92:3d:f8:93:df:4e:ec:85:a7:b3:
+ 06:71
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ D8:01:99:4C:28:49:4B:7F:FB:30:0A:92:A8:90:6F:8B:9C:45:05:7F
+ X509v3 Authority Key Identifier:
+ keyid:D8:01:99:4C:28:49:4B:7F:FB:30:0A:92:A8:90:6F:8B:9C:45:05:7F
+
+ 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
+ 38:6a:c5:72:2a:2b:2b:2c:d4:6f:07:a5:14:46:10:e5:3b:68:
+ 80:3c:d9:60:ef:12:ed:e6:1a:c0:76:4a:3d:9c:e1:86:71:b5:
+ 15:de:eb:47:51:d6:85:3e:14:ef:18:e6:b0:3c:ac:6b:0b:48:
+ 42:0f:76:3d:59:89:84:63:61:fe:6a:a0:47:0a:75:1a:64:92:
+ e3:09:14:12:d9:af:36:ec:f4:c5:79:37:22:cd:88:b8:f8:3c:
+ 55:0a:28:2e:21:26:45:cf:95:41:e4:6c:5a:ad:23:0a:cc:fd:
+ 83:71:76:7d:63:e2:9f:6c:f2:07:ee:6e:e3:fd:dd:87:f0:23:
+ 9c:04:5e:19:b2:67:38:00:91:ea:05:4c:3c:db:cd:19:d3:f6:
+ 7c:fd:fa:1d:86:fc:49:fe:45:ac:99:28:b1:a6:e7:fb:90:a2:
+ 98:59:a7:12:bc:26:ce:6d:b5:0f:62:19:40:a4:67:45:06:ec:
+ 18:1e:c5:83:e4:a1:fb:e6:58:3c:6c:a3:12:29:46:22:0d:8a:
+ 07:75:72:ab:6a:a9:c3:1c:0c:d3:a3:0b:fd:50:af:37:89:0b:
+ f6:70:57:1c:fb:d6:e7:0f:e6:52:5e:f6:1f:02:1c:73:bb:2b:
+ eb:21:1e:f0:aa:fe:b1:50:c0:12:fc:76:8c:d0:94:0a:ab:3b:
+ a8:0a:6c:28
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaRpWituomPtlwZoT0Q
+rVWXEBcGmn1Z53xWPR1fF8ei5eeAUqjN78qCSnfkrHd8NfEbs3qaWHieHADJZ51N
+0PSS8QqCivDUVwQEzBLkhpWTEqeb7m/ShV1jPFyUkdvQPPGoygUZIpjg7ykiNUA8
+fMR0XN8kK+S4vCO626pr77q7qsKrzp8HLjbaIWdNgHG6SntiFghRKTXdyB2MYNiM
+BaLs8F6v9PLolQPBeXc+//Qx7avMG91+9ixxOhzjq6ukq3kSWaX2hACD/4zlO6BP
+NyqxxKUZaUYsh7ylDu4xEy4O7dLiGb7QFLNotTTGP26V2ussVTCSPfiT307shaez
+BnECAwEAAaOByzCByDAdBgNVHQ4EFgQU2AGZTChJS3/7MAqSqJBvi5xFBX8wHwYD
+VR0jBBgwFoAU2AGZTChJS3/7MAqSqJBvi5xFBX8wNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA4asVyKisr
+LNRvB6UURhDlO2iAPNlg7xLt5hrAdko9nOGGcbUV3utHUdaFPhTvGOawPKxrC0hC
+D3Y9WYmEY2H+aqBHCnUaZJLjCRQS2a827PTFeTcizYi4+DxVCiguISZFz5VB5Gxa
+rSMKzP2DcXZ9Y+KfbPIH7m7j/d2H8COcBF4Zsmc4AJHqBUw8280Z0/Z8/fodhvxJ
+/kWsmSixpuf7kKKYWacSvCbObbUPYhlApGdFBuwYHsWD5KH75lg8bKMSKUYiDYoH
+dXKraqnDHAzTowv9UK83iQv2cFcc+9bnD+ZSXvYfAhxzuyvrIR7wqv6xUMAS/HaM
+0JQKqzuoCmwo
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-not-critical.pem b/chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-not-critical.pem
new file mode 100644
index 00000000000..3ff36828983
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/intermediary-basic-constraints-not-critical.pem
@@ -0,0 +1,282 @@
+[Created by: generate-intermediary-basic-constraints-not-critical.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+has a basic constraints extension but does not mark it as critical.
+Verification is expected to succeed, since although not critical, the
+basicConstraints indicates CA=true as expected.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d2:25:d5:a0:7a:94:e6:21:0b:8b:e5:68:21:06:
+ c4:a7:fe:fd:de:97:31:a6:80:a2:3d:be:f0:03:c2:
+ de:d5:a1:a6:3f:6e:19:3b:fe:f4:66:8f:8f:c8:d3:
+ e4:7f:73:fc:e7:1c:2f:b4:9f:5e:bf:25:71:2d:d0:
+ 65:60:76:0d:a6:be:af:1a:1f:3c:00:bf:cd:8e:de:
+ 04:6f:6c:8d:25:c5:7a:64:71:31:d7:4a:e9:bd:5f:
+ fa:e6:b8:e8:55:a2:c7:2b:b4:7d:4e:e3:bc:23:c9:
+ 0f:79:29:86:dd:4d:b3:dd:12:c5:1a:d3:fc:4a:31:
+ 54:47:7b:62:20:f5:bb:7c:47:6d:7f:67:d5:69:4b:
+ f8:99:4f:dd:13:56:a4:9d:0a:fc:d0:da:b5:bd:e0:
+ 0c:c8:50:d6:e1:73:d8:59:37:95:99:70:31:3d:46:
+ 44:d5:68:7b:45:4b:9e:4a:fd:25:33:05:7c:24:05:
+ 0f:6c:00:4b:3e:0c:cf:56:e8:88:ef:67:bc:bd:66:
+ b4:7c:bc:db:c6:4e:8b:44:0b:65:8f:c6:a9:57:d7:
+ b0:8e:88:19:fc:d6:b7:02:b9:50:a0:e2:06:61:1d:
+ d1:03:7a:ce:75:09:d2:64:d5:c6:61:3b:f1:28:5b:
+ 4b:de:08:2f:b9:96:55:d9:4c:8c:48:d0:c6:2b:ee:
+ 59:33
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ F9:45:14:0B:10:A3:AC:77:3B:19:DE:FB:66:FE:CF:E3:9A:F4:57:1A
+ X509v3 Authority Key Identifier:
+ keyid:73:DC:40:FE:F8:8F:F4:BD:DE:B0:63:30:AF:05:0B:6C:4E:99:54:7F
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 41:3c:ca:d6:88:67:86:f8:dc:35:ab:37:d0:40:96:7b:4e:70:
+ 2a:6b:cc:15:31:fd:06:87:ac:81:6d:89:ce:66:b2:26:73:bc:
+ 71:3e:af:be:b2:ba:d5:bc:a5:b7:64:0c:7d:31:9b:0c:e1:0c:
+ 73:14:0c:e0:fe:95:d3:ca:1d:d1:51:8a:fb:b1:e1:8d:68:58:
+ 30:51:a6:2f:86:57:61:a6:20:7c:1f:0c:7f:14:c7:fe:fa:88:
+ 14:7b:d9:41:5c:20:da:16:3c:ce:77:b8:ee:7c:33:d8:cf:2e:
+ 6e:e3:43:01:00:0a:c0:1c:a0:eb:6b:36:a0:d6:bd:6e:91:a9:
+ e1:8d:8d:b2:4e:12:d3:fa:56:84:be:eb:65:d8:9d:e2:c7:d4:
+ 36:a2:7e:b8:b2:d4:5c:2f:c2:47:1e:ca:7a:fd:b4:30:3a:59:
+ 19:8d:ca:7e:44:65:86:97:2d:f4:65:3b:f0:12:4b:d0:74:48:
+ f9:dd:d3:d3:89:97:83:c6:4c:bb:da:e7:ce:e7:5e:93:f3:51:
+ 4c:22:95:31:59:a9:3d:82:ec:8d:4c:8e:44:42:5f:13:d0:56:
+ c2:35:e1:07:11:6d:23:92:3c:de:b1:3e:1c:4e:0e:e3:c6:06:
+ 09:e1:dc:b8:4c:89:82:35:3c:51:60:1f:06:65:11:39:8b:b4:
+ 20:04:f0:90
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSJdWg
+epTmIQuL5WghBsSn/v3elzGmgKI9vvADwt7VoaY/bhk7/vRmj4/I0+R/c/znHC+0
+n16/JXEt0GVgdg2mvq8aHzwAv82O3gRvbI0lxXpkcTHXSum9X/rmuOhVoscrtH1O
+47wjyQ95KYbdTbPdEsUa0/xKMVRHe2Ig9bt8R21/Z9VpS/iZT90TVqSdCvzQ2rW9
+4AzIUNbhc9hZN5WZcDE9RkTVaHtFS55K/SUzBXwkBQ9sAEs+DM9W6IjvZ7y9ZrR8
+vNvGTotEC2WPxqlX17COiBn81rcCuVCg4gZhHdEDes51CdJk1cZhO/EoW0veCC+5
+llXZTIxI0MYr7lkzAgMBAAGjgekwgeYwHQYDVR0OBBYEFPlFFAsQo6x3Oxne+2b+
+z+Oa9FcaMB8GA1UdIwQYMBaAFHPcQP74j/S93rBjMK8FC2xOmVR/MD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAQTzK1ohnhvjcNas30ECW
+e05wKmvMFTH9BoesgW2JzmayJnO8cT6vvrK61bylt2QMfTGbDOEMcxQM4P6V08od
+0VGK+7HhjWhYMFGmL4ZXYaYgfB8MfxTH/vqIFHvZQVwg2hY8zne47nwz2M8ubuND
+AQAKwByg62s2oNa9bpGp4Y2Nsk4S0/pWhL7rZdid4sfUNqJ+uLLUXC/CRx7Kev20
+MDpZGY3KfkRlhpct9GU78BJL0HRI+d3T04mXg8ZMu9rnzudek/NRTCKVMVmpPYLs
+jUyOREJfE9BWwjXhBxFtI5I83rE+HE4O48YGCeHcuEyJgjU8UWAfBmUROYu0IATw
+kA==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:4a:96:98:34:e1:a8:92:88:9a:0c:d0:b7:e3:
+ a0:dc:71:4b:32:cd:59:a1:b9:9c:d5:e5:30:1b:ad:
+ 7e:41:7f:e7:39:81:25:d1:e7:66:c2:5f:79:80:ea:
+ ff:6b:ef:b9:95:9e:8b:a0:0c:6a:b6:c8:4b:50:2c:
+ 7d:f1:ad:46:ed:9a:7c:7d:6a:65:70:de:c2:45:7e:
+ 1b:28:af:dc:eb:3d:bb:4c:98:a9:8c:b3:a3:35:a1:
+ 2b:cd:bb:8e:2a:2b:74:6d:0c:91:72:36:c2:2f:0e:
+ 46:2a:77:34:ab:98:f8:28:c9:02:42:78:2f:b2:e0:
+ 9a:0d:ae:03:94:c0:31:79:1e:72:ce:8b:7c:21:c8:
+ d5:1c:9b:94:04:29:ce:1c:5f:22:e3:f0:20:62:2b:
+ 7d:7d:c2:fa:29:5c:8b:2a:dd:0f:08:31:49:58:7d:
+ 85:76:21:b4:46:0e:d8:26:dc:26:f9:0a:9b:58:a2:
+ b8:29:b4:df:c0:4e:10:56:28:96:02:54:7c:e9:a3:
+ 3f:84:12:6a:89:ed:f0:0d:a0:03:54:0c:b2:33:6d:
+ 1b:a7:84:f2:a0:b0:57:5e:4b:c1:2f:6d:e9:22:52:
+ 50:b1:3b:a7:7d:ee:a7:dc:6e:6a:bd:b6:a6:ea:66:
+ f8:1f:30:60:18:d8:5b:a6:dd:9d:9b:d3:4e:2b:0a:
+ c4:0b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 73:DC:40:FE:F8:8F:F4:BD:DE:B0:63:30:AF:05:0B:6C:4E:99:54:7F
+ X509v3 Authority Key Identifier:
+ keyid:6C:05:B0:A0:A8:03:A4:A1:90:D1:A5:74:D2:13:D9:2E:57:83:36:73
+
+ 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:
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 81:08:b8:48:94:05:02:aa:61:ea:32:48:55:02:31:f6:e0:5d:
+ 05:6f:32:9b:6a:a0:3b:6f:0e:1d:2a:01:1a:14:20:a2:1e:23:
+ b4:70:61:86:55:b5:4c:5b:61:3f:dd:1e:38:a4:98:3f:bd:61:
+ e4:1e:56:54:ed:0e:51:65:6c:73:af:99:86:fc:a7:50:48:87:
+ 95:6f:5a:93:0d:c9:7a:ff:fb:39:d1:f4:40:2c:fe:1f:28:aa:
+ 85:cf:12:bd:7b:df:2b:12:56:4a:91:4e:e4:80:00:52:4c:bb:
+ b2:e6:05:27:47:e2:3f:bb:a4:d7:cc:92:c2:27:02:10:50:10:
+ 0c:f8:ee:4c:93:90:89:8d:db:8a:f9:05:f1:ec:d7:cf:67:20:
+ a4:da:90:e0:38:34:fd:79:9b:6b:04:a8:bd:6f:e8:82:4a:d9:
+ 37:49:b3:10:50:e6:c5:56:d9:ac:9b:e8:97:52:41:a1:66:be:
+ cb:64:1d:12:0d:86:8b:34:42:26:9a:ad:c3:8a:14:ff:35:0d:
+ 82:8f:96:e0:af:b7:e7:20:30:3e:b3:fe:57:4a:80:5e:53:8b:
+ ec:15:ca:a8:db:b7:c6:87:b7:ab:81:8b:42:23:4a:74:9c:9e:
+ 59:b8:3c:8d:0e:d2:f3:9d:79:45:9a:0e:fd:8c:6b:9e:b5:c8:
+ e7:03:64:79
+-----BEGIN CERTIFICATE-----
+MIIDajCCAlKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1UqWmDTh
+qJKImgzQt+Og3HFLMs1Zobmc1eUwG61+QX/nOYEl0edmwl95gOr/a++5lZ6LoAxq
+tshLUCx98a1G7Zp8fWplcN7CRX4bKK/c6z27TJipjLOjNaErzbuOKit0bQyRcjbC
+Lw5GKnc0q5j4KMkCQngvsuCaDa4DlMAxeR5yzot8IcjVHJuUBCnOHF8i4/AgYit9
+fcL6KVyLKt0PCDFJWH2FdiG0Rg7YJtwm+QqbWKK4KbTfwE4QViiWAlR86aM/hBJq
+ie3wDaADVAyyM20bp4TyoLBXXkvBL23pIlJQsTunfe6n3G5qvbam6mb4HzBgGNhb
+pt2dm9NOKwrECwIDAQABo4HIMIHFMB0GA1UdDgQWBBRz3ED++I/0vd6wYzCvBQts
+TplUfzAfBgNVHSMEGDAWgBRsBbCgqAOkoZDRpXTSE9kuV4M2czA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIEI
+uEiUBQKqYeoySFUCMfbgXQVvMptqoDtvDh0qARoUIKIeI7RwYYZVtUxbYT/dHjik
+mD+9YeQeVlTtDlFlbHOvmYb8p1BIh5VvWpMNyXr/+znR9EAs/h8oqoXPEr173ysS
+VkqRTuSAAFJMu7LmBSdH4j+7pNfMksInAhBQEAz47kyTkImN24r5BfHs189nIKTa
+kOA4NP15m2sEqL1v6IJK2TdJsxBQ5sVW2ayb6JdSQaFmvstkHRINhos0QiaarcOK
+FP81DYKPluCvt+cgMD6z/ldKgF5Ti+wVyqjbt8aHt6uBi0IjSnScnlm4PI0O0vOd
+eUWaDv2Ma561yOcDZHk=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b6:f1:d2:f8:c9:10:d5:cf:0c:55:ce:8c:38:a2:
+ 8f:f5:f1:cf:20:85:56:92:df:42:8c:5c:1a:db:8e:
+ 1d:2e:b4:b3:95:72:e4:67:76:7c:c5:61:62:2b:cf:
+ 97:f7:84:29:80:ff:df:e8:e7:da:f6:05:11:1d:40:
+ 1e:73:76:ff:e4:eb:fa:45:59:20:d9:35:cb:c7:4f:
+ 2b:49:2a:61:7c:45:a1:fe:da:8c:89:05:38:84:ab:
+ cb:0b:c9:36:3b:e5:3e:31:5e:0b:a6:27:63:b1:c2:
+ 34:88:3a:e5:e3:43:93:0b:46:69:03:dd:31:16:65:
+ 18:6e:64:4c:84:e4:a1:37:6b:15:ef:f3:8f:57:e8:
+ 57:f6:a8:86:62:9b:92:d0:67:d3:ed:0f:89:d3:4e:
+ 09:aa:e8:74:ab:ce:4b:51:63:52:55:f1:24:9d:42:
+ 70:cb:14:0f:e3:b4:7f:ba:6a:3c:87:27:eb:3b:82:
+ 64:99:6a:f9:be:20:5a:9e:b9:8a:8b:ab:94:ed:f3:
+ 33:eb:ea:42:5c:7e:20:df:f4:9d:82:8f:ac:8e:52:
+ 99:06:db:d0:9f:01:38:e7:b9:0c:d2:b4:ca:7f:74:
+ 03:e2:f7:0b:0e:a9:40:14:6c:7f:1b:15:00:77:0a:
+ 98:76:ee:bd:62:24:f6:a7:8b:d4:7e:4b:8d:c9:eb:
+ 04:a7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 6C:05:B0:A0:A8:03:A4:A1:90:D1:A5:74:D2:13:D9:2E:57:83:36:73
+ X509v3 Authority Key Identifier:
+ keyid:6C:05:B0:A0:A8:03:A4:A1:90:D1:A5:74:D2:13:D9:2E:57:83:36:73
+
+ 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
+ 52:82:fe:3f:2b:71:41:fd:4c:9b:db:c5:b1:60:72:a7:cf:f4:
+ 29:91:36:0f:ce:92:72:95:3e:34:ab:84:0c:af:23:e8:e1:28:
+ 35:29:c9:c8:78:9a:12:d7:f1:22:1c:21:e1:b0:b4:df:af:36:
+ c4:ca:71:2a:6e:6f:4a:d5:65:58:31:7a:c2:d1:30:66:e0:0a:
+ 61:54:e0:61:97:7b:41:72:58:d9:02:da:22:8b:21:e6:d5:31:
+ 4c:d2:3c:11:d8:0d:12:f0:dc:eb:e0:1d:16:3a:74:de:9c:b4:
+ b2:bb:69:ed:e1:53:14:9e:1c:06:3f:ff:e7:2f:8a:d1:f6:37:
+ 89:76:b2:61:60:5f:48:ce:a3:8f:e0:b5:6f:92:18:21:e4:a8:
+ 1f:12:70:86:54:2a:da:78:3d:5d:3c:13:b8:b4:7f:a5:81:f0:
+ 55:cf:ea:56:b4:0a:8a:ca:2b:ca:be:08:9e:a6:4c:12:99:5f:
+ 23:93:08:58:70:8f:c8:fb:88:11:fe:d6:16:c7:a3:3b:1f:6b:
+ 78:b0:05:29:9f:7d:4c:01:ba:ed:8a:5f:a8:38:e9:a4:c2:44:
+ ce:e8:37:1d:d8:1f:16:e4:ef:84:bb:1f:4b:3a:b0:9a:00:57:
+ aa:ba:52:1c:f4:da:f7:69:5d:ef:8d:35:ef:5c:03:fa:8d:87:
+ fc:92:60:28
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALbx0vjJENXPDFXOjDii
+j/XxzyCFVpLfQoxcGtuOHS60s5Vy5Gd2fMVhYivPl/eEKYD/3+jn2vYFER1AHnN2
+/+Tr+kVZINk1y8dPK0kqYXxFof7ajIkFOISrywvJNjvlPjFeC6YnY7HCNIg65eND
+kwtGaQPdMRZlGG5kTITkoTdrFe/zj1foV/aohmKbktBn0+0PidNOCarodKvOS1Fj
+UlXxJJ1CcMsUD+O0f7pqPIcn6zuCZJlq+b4gWp65iourlO3zM+vqQlx+IN/0nYKP
+rI5SmQbb0J8BOOe5DNK0yn90A+L3Cw6pQBRsfxsVAHcKmHbuvWIk9qeL1H5Ljcnr
+BKcCAwEAAaOByzCByDAdBgNVHQ4EFgQUbAWwoKgDpKGQ0aV00hPZLleDNnMwHwYD
+VR0jBBgwFoAUbAWwoKgDpKGQ0aV00hPZLleDNnMwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBSgv4/K3FB
+/Uyb28WxYHKnz/QpkTYPzpJylT40q4QMryPo4Sg1KcnIeJoS1/EiHCHhsLTfrzbE
+ynEqbm9K1WVYMXrC0TBm4AphVOBhl3tBcljZAtoiiyHm1TFM0jwR2A0S8Nzr4B0W
+OnTenLSyu2nt4VMUnhwGP//nL4rR9jeJdrJhYF9IzqOP4LVvkhgh5KgfEnCGVCra
+eD1dPBO4tH+lgfBVz+pWtAqKyivKvgiepkwSmV8jkwhYcI/I+4gR/tYWx6M7H2t4
+sAUpn31MAbrtil+oOOmkwkTO6Dcd2B8W5O+Eux9LOrCaAFequlIc9Nr3aV3vjTXv
+XAP6jYf8kmAo
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-basic-constraints.pem b/chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-basic-constraints.pem
new file mode 100644
index 00000000000..016f94e14fd
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-basic-constraints.pem
@@ -0,0 +1,278 @@
+[Created by: generate-intermediary-lacks-basic-constraints.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+lacks the basic constraints extension, and hence is expected to fail validation
+(RFC 5280 requires v3 signing certificates have a BasicConstaints).
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:f3:d6:19:96:48:0c:01:e2:21:3d:98:21:52:df:
+ 5a:79:95:01:e5:c2:ab:77:e4:7b:10:17:64:75:a4:
+ ca:b6:69:cc:a9:4a:1d:b6:7f:a0:16:89:32:21:c2:
+ 2a:c2:58:28:d2:f3:ef:a5:2d:81:92:47:17:d5:61:
+ 65:ab:43:22:ce:59:5b:20:31:be:6e:84:23:19:d5:
+ 7e:a8:70:50:6c:de:06:b8:58:09:97:fd:02:98:31:
+ 2d:3b:ab:1b:4a:82:6c:28:ab:c5:a3:6b:ea:40:2b:
+ 48:02:73:e4:ce:ea:f6:3b:6a:80:1f:5b:59:30:86:
+ 1b:5e:64:61:b5:94:d2:f0:c8:bb:88:b1:90:05:1a:
+ e8:e6:97:dc:7d:e8:53:c8:9f:88:09:69:82:1f:1e:
+ e2:d1:70:f3:85:06:63:18:0a:d2:f1:71:a3:25:a3:
+ 42:76:3a:5e:02:78:e6:7a:c6:a4:82:dd:79:35:5a:
+ da:8e:37:92:82:bf:01:13:1b:6e:52:97:97:32:f1:
+ b2:4e:95:bc:55:89:61:61:73:b4:64:30:b1:89:87:
+ 51:17:29:f3:67:de:5b:99:ee:47:71:07:8c:d5:17:
+ 55:e0:70:bc:b6:06:6e:eb:7a:c6:69:69:97:e1:3d:
+ 1d:be:93:da:a0:fa:cb:2f:f0:ed:5c:da:18:0e:67:
+ 89:8d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ FD:C8:4E:91:CD:73:65:1D:13:F9:EC:F0:91:13:F1:D0:01:AD:1E:7C
+ X509v3 Authority Key Identifier:
+ keyid:60:E7:1E:8E:53:95:1F:8F:00:D1:F7:9F:36:01:26:15:86:53:0E:F2
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 88:1d:e7:e6:1e:4b:93:a9:79:59:0e:10:43:1e:f7:79:a4:c7:
+ 68:55:81:b6:b4:6d:b0:5b:b6:46:13:8b:4e:1c:d4:79:17:b1:
+ 71:46:b6:69:21:92:fa:bf:bd:76:cc:6c:b1:04:58:28:41:79:
+ 34:4f:09:e7:17:5c:d0:ac:fc:c5:2e:1e:5c:31:ca:ed:55:ea:
+ df:4a:43:9a:72:37:0a:8a:69:dd:4e:e9:a3:ef:dd:48:45:41:
+ 7b:55:e3:d1:98:69:a5:ec:0b:43:32:24:da:33:cd:fd:35:74:
+ 17:81:b1:61:37:b1:12:5d:51:86:e6:a2:08:e5:c7:99:aa:f7:
+ 23:c4:5f:83:c0:59:9c:36:f9:a0:4c:03:f7:40:42:fb:90:39:
+ 5a:45:e5:e2:94:a3:58:c2:a1:d8:c9:aa:3e:83:98:b0:32:a1:
+ 85:9a:b1:34:c7:67:a4:03:67:6e:5b:d7:83:b8:92:0f:af:81:
+ b5:00:50:c4:0f:f6:bb:cd:7d:0f:a8:cd:28:bb:48:b8:32:82:
+ ef:d1:cf:96:74:e4:25:74:ce:5e:4c:75:d2:80:55:a3:6b:a6:
+ 76:eb:aa:3e:2b:55:d3:c9:bd:2b:32:d3:1d:01:00:cb:8d:c4:
+ c0:b9:29:0b:10:e5:ab:34:2f:30:63:29:df:a8:4f:b3:28:dd:
+ 0b:8c:ea:14
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDz1hmW
+SAwB4iE9mCFS31p5lQHlwqt35HsQF2R1pMq2acypSh22f6AWiTIhwirCWCjS8++l
+LYGSRxfVYWWrQyLOWVsgMb5uhCMZ1X6ocFBs3ga4WAmX/QKYMS07qxtKgmwoq8Wj
+a+pAK0gCc+TO6vY7aoAfW1kwhhteZGG1lNLwyLuIsZAFGujml9x96FPIn4gJaYIf
+HuLRcPOFBmMYCtLxcaMlo0J2Ol4CeOZ6xqSC3Xk1WtqON5KCvwETG25Sl5cy8bJO
+lbxViWFhc7RkMLGJh1EXKfNn3luZ7kdxB4zVF1XgcLy2Bm7resZpaZfhPR2+k9qg
++ssv8O1c2hgOZ4mNAgMBAAGjgekwgeYwHQYDVR0OBBYEFP3ITpHNc2UdE/ns8JET
+8dABrR58MB8GA1UdIwQYMBaAFGDnHo5TlR+PANH3nzYBJhWGUw7yMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAiB3n5h5Lk6l5WQ4QQx73
+eaTHaFWBtrRtsFu2RhOLThzUeRexcUa2aSGS+r+9dsxssQRYKEF5NE8J5xdc0Kz8
+xS4eXDHK7VXq30pDmnI3Copp3U7po+/dSEVBe1Xj0ZhppewLQzIk2jPN/TV0F4Gx
+YTexEl1RhuaiCOXHmar3I8Rfg8BZnDb5oEwD90BC+5A5WkXl4pSjWMKh2MmqPoOY
+sDKhhZqxNMdnpANnblvXg7iSD6+BtQBQxA/2u819D6jNKLtIuDKC79HPlnTkJXTO
+Xkx10oBVo2umduuqPitV08m9KzLTHQEAy43EwLkpCxDlqzQvMGMp36hPsyjdC4zq
+FA==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a0:8f:6c:dd:c5:0d:76:a9:8a:da:5d:9f:94:cf:
+ 9a:18:cd:32:ee:e1:c3:88:29:0d:40:7d:8b:37:9c:
+ 18:b9:ed:11:81:5b:cc:8c:7c:4a:f3:e2:b9:eb:f7:
+ 3c:74:5a:5c:78:37:e3:7e:a8:b9:34:d7:da:d2:dc:
+ 52:de:c6:bb:ca:cd:39:c3:ea:8e:84:1b:e5:ad:4b:
+ 67:1b:70:bd:70:0e:5e:20:95:37:bf:ae:d1:f4:b0:
+ 97:c0:8a:d3:e5:2a:04:d8:eb:1d:c8:f0:95:1b:25:
+ d4:49:ae:d4:5f:d9:bc:ea:19:2d:38:d3:d2:c4:8b:
+ 77:37:45:ae:f9:70:b2:43:93:85:06:58:e0:3e:38:
+ 11:32:d2:bc:a5:d4:df:09:2d:e9:c4:16:a7:f9:5b:
+ 25:8d:57:f7:bf:01:4e:c8:25:b4:f8:5d:33:1d:7a:
+ 04:4b:9d:fe:71:d4:65:78:4b:8d:52:ef:04:80:d4:
+ 45:18:1d:d8:53:8e:2a:e8:23:3f:14:a4:b4:f1:00:
+ ff:30:be:06:c5:61:ac:13:e8:cb:4c:ef:77:f7:6b:
+ 1d:da:5a:d4:7f:f8:5a:87:cb:4b:45:05:8c:06:73:
+ 7b:65:d5:71:c9:35:c7:6e:07:ce:0b:e2:54:e1:43:
+ f0:da:a9:51:b8:ad:fe:da:de:29:8c:5f:2d:40:06:
+ 7f:39
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 60:E7:1E:8E:53:95:1F:8F:00:D1:F7:9F:36:01:26:15:86:53:0E:F2
+ X509v3 Authority Key Identifier:
+ keyid:73:D9:03:F6:54:EA:FC:42:DA:77:EC:19:89:AD:6D:D2:A3:3E:E9:FD
+
+ 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
+ Signature Algorithm: sha256WithRSAEncryption
+ 43:31:7d:91:39:1d:8a:88:6c:d2:2d:36:b1:92:53:1d:18:24:
+ e9:42:27:c3:d3:f1:77:69:6f:67:7b:39:46:32:fb:36:a1:8d:
+ 07:ee:16:6b:ac:09:e3:78:38:7a:a7:4b:fe:3f:81:eb:f2:85:
+ aa:d6:3e:5a:68:57:e3:98:0d:ae:ee:45:84:d1:ed:6d:9c:78:
+ fe:63:50:94:55:5e:b5:41:ef:c9:16:ed:4f:38:03:cb:73:3c:
+ 79:c1:c4:0c:c1:95:43:11:49:c0:bc:7e:9a:6a:05:d2:43:c4:
+ 66:72:66:57:69:46:ed:a7:10:af:bf:e9:bb:48:72:4b:00:a2:
+ 46:78:38:68:dd:6b:a9:ac:62:70:4b:0b:f3:29:fa:a7:a2:42:
+ 4b:d7:88:1f:97:1f:71:60:20:82:89:d6:3a:60:d5:4b:08:28:
+ 6a:6a:97:2e:c9:93:d8:a7:32:b7:e1:68:be:07:7a:3c:76:3b:
+ 2c:1b:10:17:4c:c9:ea:ee:48:c9:ad:ac:2e:61:dd:16:eb:62:
+ 1e:33:1d:6c:8a:b4:56:0f:3d:04:35:f3:8f:d0:12:f9:66:8d:
+ 39:95:e9:44:41:32:7e:f3:17:2e:58:c9:0c:23:b1:e3:db:f7:
+ ed:da:bd:94:0e:00:27:34:3d:3d:c6:48:d8:e4:a3:66:57:d9:
+ 5e:13:3e:59
+-----BEGIN CERTIFICATE-----
+MIIDXDCCAkSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoI9s3cUN
+dqmK2l2flM+aGM0y7uHDiCkNQH2LN5wYue0RgVvMjHxK8+K56/c8dFpceDfjfqi5
+NNfa0txS3sa7ys05w+qOhBvlrUtnG3C9cA5eIJU3v67R9LCXwIrT5SoE2OsdyPCV
+GyXUSa7UX9m86hktONPSxIt3N0Wu+XCyQ5OFBljgPjgRMtK8pdTfCS3pxBan+Vsl
+jVf3vwFOyCW0+F0zHXoES53+cdRleEuNUu8EgNRFGB3YU44q6CM/FKS08QD/ML4G
+xWGsE+jLTO9392sd2lrUf/hah8tLRQWMBnN7ZdVxyTXHbgfOC+JU4UPw2qlRuK3+
+2t4pjF8tQAZ/OQIDAQABo4G6MIG3MB0GA1UdDgQWBBRg5x6OU5UfjwDR9582ASYV
+hlMO8jAfBgNVHSMEGDAWgBRz2QP2VOr8Qtp37BmJrW3Soz7p/TA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBDMX2ROR2KiGzSLTaxklMd
+GCTpQifD0/F3aW9nezlGMvs2oY0H7hZrrAnjeDh6p0v+P4Hr8oWq1j5aaFfjmA2u
+7kWE0e1tnHj+Y1CUVV61Qe/JFu1POAPLczx5wcQMwZVDEUnAvH6aagXSQ8RmcmZX
+aUbtpxCvv+m7SHJLAKJGeDho3WuprGJwSwvzKfqnokJL14gflx9xYCCCidY6YNVL
+CChqapcuyZPYpzK34Wi+B3o8djssGxAXTMnq7kjJrawuYd0W62IeMx1sirRWDz0E
+NfOP0BL5Zo05lelEQTJ+8xcuWMkMI7Hj2/ft2r2UDgAnND09xkjY5KNmV9leEz5Z
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ea:c6:b8:66:62:c2:1a:2a:7d:83:ca:b2:7b:11:
+ e4:92:4a:b8:3a:39:35:73:aa:89:55:7d:f4:ec:40:
+ 4b:2c:c7:56:58:ac:9d:25:ef:c3:26:86:98:c4:74:
+ a4:3a:94:36:d8:78:7c:1a:f4:f7:5c:a0:56:69:fc:
+ 23:c0:a4:06:5f:5b:ce:ea:cb:32:9b:c3:21:89:fd:
+ 9f:4e:38:a2:b9:f4:de:af:44:1e:53:02:09:41:44:
+ 92:bc:a5:4f:70:86:23:85:48:2a:51:01:70:ab:b0:
+ c4:bd:97:3c:2f:d0:2c:3e:9c:be:40:2e:ee:be:f8:
+ ed:63:a2:1b:fd:e2:0f:d1:b2:3b:b3:ce:da:84:59:
+ 56:bb:77:17:93:ef:c0:b7:b4:11:db:b9:6e:b0:4a:
+ 28:55:fb:56:4e:ed:22:b6:e3:4d:5b:ad:6a:af:ff:
+ df:33:f9:18:a6:91:0a:b8:89:d3:28:55:18:c7:71:
+ 19:32:bc:88:a8:ee:5b:c8:34:84:e5:f5:fe:6e:5e:
+ c0:3b:73:9b:a4:bc:4c:6a:8a:5a:31:c0:34:f3:c3:
+ 89:e0:57:97:64:01:dd:c2:9f:75:8e:e3:fd:b3:58:
+ b5:0b:e3:4d:8f:94:e8:9b:0c:c2:12:af:13:31:30:
+ d1:a6:1c:2c:f1:0a:7a:a4:17:e2:2f:6f:73:cb:22:
+ 15:67
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 73:D9:03:F6:54:EA:FC:42:DA:77:EC:19:89:AD:6D:D2:A3:3E:E9:FD
+ X509v3 Authority Key Identifier:
+ keyid:73:D9:03:F6:54:EA:FC:42:DA:77:EC:19:89:AD:6D:D2:A3:3E:E9:FD
+
+ 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
+ e0:b7:24:3a:ee:4c:8d:42:9f:b9:52:2b:7d:21:c5:7b:dd:2b:
+ bc:6a:5d:86:57:ee:d5:1f:27:e6:e1:08:e3:72:a3:10:2b:97:
+ 1b:98:b9:39:18:6e:7f:b8:b0:1c:f1:f5:d9:7e:1d:05:3f:5b:
+ f4:cd:1e:66:7f:77:ed:ab:d0:51:b6:ad:6c:a6:66:ab:fc:31:
+ a1:ac:ee:66:ae:3b:af:4e:3c:c6:29:07:dc:1a:ac:b5:10:3f:
+ 3f:ad:27:1b:bc:32:19:ab:b3:75:62:47:23:d1:b8:60:78:ac:
+ 96:0c:4f:b8:31:7b:40:7e:f3:f7:ba:a9:ae:9b:65:ef:c5:e3:
+ fc:c8:28:c6:c0:74:48:00:33:48:a4:e6:3c:0c:5b:a0:1e:c2:
+ 57:c5:0c:24:34:c3:36:c0:8a:f3:a6:c3:16:24:32:c3:dc:81:
+ 76:54:3e:00:68:c8:6a:b6:ee:9f:ab:44:64:64:37:54:ff:1b:
+ b9:a5:c2:bf:ff:a5:68:b3:5a:ef:d7:bc:64:39:24:2e:ad:c7:
+ a3:9c:ef:60:cb:ab:de:45:f1:40:65:95:01:0c:52:ea:a8:d6:
+ 8b:77:e0:2e:1f:2b:4f:a3:bc:b8:80:6b:8d:92:42:66:17:10:
+ 4b:d4:b0:2d:8d:4c:77:50:74:83:0e:9a:4c:0d:3b:6b:3d:c6:
+ 0a:2e:f6:5c
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOrGuGZiwhoqfYPKsnsR
+5JJKuDo5NXOqiVV99OxASyzHVlisnSXvwyaGmMR0pDqUNth4fBr091ygVmn8I8Ck
+Bl9bzurLMpvDIYn9n044orn03q9EHlMCCUFEkrylT3CGI4VIKlEBcKuwxL2XPC/Q
+LD6cvkAu7r747WOiG/3iD9GyO7PO2oRZVrt3F5PvwLe0Edu5brBKKFX7Vk7tIrbj
+TVutaq//3zP5GKaRCriJ0yhVGMdxGTK8iKjuW8g0hOX1/m5ewDtzm6S8TGqKWjHA
+NPPDieBXl2QB3cKfdY7j/bNYtQvjTY+U6JsMwhKvEzEw0aYcLPEKeqQX4i9vc8si
+FWcCAwEAAaOByzCByDAdBgNVHQ4EFgQUc9kD9lTq/ELad+wZia1t0qM+6f0wHwYD
+VR0jBBgwFoAUc9kD9lTq/ELad+wZia1t0qM+6f0wNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDgtyQ67kyN
+Qp+5Uit9IcV73Su8al2GV+7VHyfm4QjjcqMQK5cbmLk5GG5/uLAc8fXZfh0FP1v0
+zR5mf3ftq9BRtq1spmar/DGhrO5mrjuvTjzGKQfcGqy1ED8/rScbvDIZq7N1Ykcj
+0bhgeKyWDE+4MXtAfvP3uqmum2XvxeP8yCjGwHRIADNIpOY8DFugHsJXxQwkNMM2
+wIrzpsMWJDLD3IF2VD4AaMhqtu6fq0RkZDdU/xu5pcK//6Vos1rv17xkOSQurcej
+nO9gy6veRfFAZZUBDFLqqNaLd+AuHytPo7y4gGuNkkJmFxBL1LAtjUx3UHSDDppM
+DTtrPcYKLvZc
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-signing-key-usage.pem b/chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-signing-key-usage.pem
new file mode 100644
index 00000000000..63275452fce
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/intermediary-lacks-signing-key-usage.pem
@@ -0,0 +1,281 @@
+[Created by: generate-intermediary-lacks-signing-key-usage.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+contains a keyUsage extension, HOWEVER it does not contain the keyCertSign bit.
+Hence validation is expected to fail.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b6:80:03:5a:ee:21:94:59:e3:bf:eb:26:bb:b5:
+ 2e:39:80:35:38:e7:7e:1d:e6:17:d2:fb:50:be:d2:
+ 03:33:14:ee:1f:a2:f8:78:bb:d0:60:e2:0c:ff:59:
+ 80:52:fb:5a:3d:38:2d:26:9e:d6:af:df:f2:ff:49:
+ f7:ec:8a:02:2b:51:02:d3:53:f9:6e:2b:ed:68:5e:
+ 90:54:03:7b:f7:0c:08:93:59:9f:41:2c:27:05:6c:
+ dd:dc:f8:a8:ea:78:c0:6d:a1:c8:11:cd:e8:40:cc:
+ 6c:65:db:16:50:20:07:68:00:c0:7f:c5:89:fe:e8:
+ 6a:0c:36:6a:ad:5a:ab:40:8e:4c:0e:e9:51:a0:6b:
+ 28:b8:df:c0:7c:3c:6c:a7:b8:8b:9e:07:1f:e5:29:
+ 01:5b:81:76:ca:53:80:b8:a4:8f:1a:35:66:b7:96:
+ 24:ac:fb:44:a1:4c:71:c6:28:6d:91:75:59:1a:bf:
+ e4:8e:15:71:43:3f:24:3f:b4:db:a0:2c:5e:af:46:
+ 16:65:7e:25:0c:90:5e:16:7b:e3:a6:47:0f:03:fe:
+ 31:cc:06:dc:ba:0e:0b:fa:6b:e5:4a:53:11:c4:00:
+ 54:d5:76:09:97:12:38:31:12:9d:27:49:e8:4d:01:
+ 18:0c:54:b3:c7:a8:c3:fc:60:3f:92:0b:ef:9f:72:
+ 8e:59
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 76:E3:64:67:6F:B9:A6:B7:6E:DC:62:12:09:FE:30:0A:19:F4:BF:B3
+ X509v3 Authority Key Identifier:
+ keyid:5A:C6:0B:DA:37:A3:BB:21:85:17:C5:EF:0C:FA:BF:A9:79:B1:FE:29
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 92:d5:77:f8:65:61:e9:66:0d:f7:00:9b:46:28:26:52:37:9f:
+ 3c:15:33:01:95:61:b9:0c:a1:c3:e7:f5:09:6a:4c:ba:0f:3b:
+ 80:3a:65:c3:22:e7:9d:e7:4d:c3:ca:3a:bc:88:98:6c:a3:8e:
+ 56:4e:64:98:b7:85:a7:aa:d3:e8:9a:b3:e4:2f:7d:18:bf:74:
+ c7:29:d9:51:a7:39:4a:4b:e1:94:14:0b:f9:af:e9:89:26:98:
+ cb:b2:b7:64:d4:ab:42:f5:68:cb:40:78:72:91:02:13:fe:05:
+ 41:68:42:c2:e0:d5:ea:bd:56:52:6f:76:b3:20:f4:e6:39:2a:
+ 83:ea:7a:c9:d2:37:4a:45:c4:ad:ac:6a:24:38:6e:fd:d6:ed:
+ 4c:42:cf:87:2c:7d:21:e5:18:ee:3a:c0:1e:83:ac:25:70:9a:
+ f5:fd:e7:4e:ab:67:0e:5d:00:9f:44:e4:e5:d6:d9:02:43:05:
+ 91:c3:66:a6:1f:8a:ce:ae:c8:2b:4d:c6:0e:9e:5f:d7:ff:e7:
+ b6:39:a7:f1:19:b0:3a:59:33:6a:72:a6:03:6b:42:e7:f8:07:
+ a3:0d:2d:f7:31:c3:f4:e5:cf:8b:24:42:0c:29:40:5a:7d:df:
+ 65:81:8c:0f:cb:86:e6:2b:39:26:58:0b:18:b8:4c:87:6c:10:
+ 03:0b:7c:c4
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2gANa
+7iGUWeO/6ya7tS45gDU4534d5hfS+1C+0gMzFO4fovh4u9Bg4gz/WYBS+1o9OC0m
+ntav3/L/SffsigIrUQLTU/luK+1oXpBUA3v3DAiTWZ9BLCcFbN3c+KjqeMBtocgR
+zehAzGxl2xZQIAdoAMB/xYn+6GoMNmqtWqtAjkwO6VGgayi438B8PGynuIueBx/l
+KQFbgXbKU4C4pI8aNWa3liSs+0ShTHHGKG2RdVkav+SOFXFDPyQ/tNugLF6vRhZl
+fiUMkF4We+OmRw8D/jHMBty6Dgv6a+VKUxHEAFTVdgmXEjgxEp0nSehNARgMVLPH
+qMP8YD+SC++fco5ZAgMBAAGjgekwgeYwHQYDVR0OBBYEFHbjZGdvuaa3btxiEgn+
+MAoZ9L+zMB8GA1UdIwQYMBaAFFrGC9o3o7shhRfF7wz6v6l5sf4pMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAktV3+GVh6WYN9wCbRigm
+UjefPBUzAZVhuQyhw+f1CWpMug87gDplwyLnnedNw8o6vIiYbKOOVk5kmLeFp6rT
+6Jqz5C99GL90xynZUac5SkvhlBQL+a/piSaYy7K3ZNSrQvVoy0B4cpECE/4FQWhC
+wuDV6r1WUm92syD05jkqg+p6ydI3SkXEraxqJDhu/dbtTELPhyx9IeUY7jrAHoOs
+JXCa9f3nTqtnDl0An0Tk5dbZAkMFkcNmph+Kzq7IK03GDp5f1//ntjmn8RmwOlkz
+anKmA2tC5/gHow0t9zHD9OXPiyRCDClAWn3fZYGMD8uG5is5JlgLGLhMh2wQAwt8
+xA==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9b:71:4d:95:69:ff:1c:81:da:58:66:90:29:ae:
+ 15:48:a6:43:09:a2:05:75:ca:16:d1:a5:69:e0:77:
+ c8:c1:f4:e5:e2:4d:97:c6:09:e4:e0:98:64:c2:b7:
+ 7f:11:5a:ee:7a:3e:c5:d8:24:b0:b8:a2:98:ac:05:
+ bd:71:07:71:6a:11:67:17:55:5c:2d:d3:fe:4b:d0:
+ e1:f3:d5:08:de:7e:c2:56:ff:e6:95:6f:11:7f:5a:
+ 34:e7:0c:1c:e3:82:f6:f4:e1:ed:4e:ce:60:2f:f7:
+ 5d:b8:b1:54:f0:c8:aa:28:5d:56:90:24:7b:cf:a7:
+ 01:de:d9:63:16:a3:7b:5e:34:c9:8c:35:50:57:fc:
+ be:6c:48:70:83:7a:52:d9:19:f8:e8:a2:91:f3:23:
+ 34:f3:14:b6:3d:59:e6:86:05:9b:26:ec:14:fa:78:
+ d3:91:a4:af:f7:c5:01:15:c0:3c:84:b8:5f:09:62:
+ ab:c3:b3:51:df:14:20:47:ee:0b:5f:85:06:42:4d:
+ b3:5a:e0:08:14:32:d8:0a:8b:7a:41:f5:0e:34:cc:
+ 4a:a3:79:be:6d:b5:cd:d1:b8:e0:71:2a:81:e1:22:
+ bc:6c:fe:89:59:97:ee:71:ad:d7:e1:d4:ea:01:85:
+ 0a:ae:83:a1:09:65:3c:2e:68:29:e1:3f:b0:c2:c7:
+ 90:85
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 5A:C6:0B:DA:37:A3:BB:21:85:17:C5:EF:0C:FA:BF:A9:79:B1:FE:29
+ X509v3 Authority Key Identifier:
+ keyid:D3:3B:10:26:28:99:EC:09:2A:08:9C:53:7D:24:9F:B1:F1:04:0B:B5
+
+ 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 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 53:21:fb:72:d3:86:6c:af:f6:75:07:5c:bc:0c:7a:97:8f:05:
+ b8:86:af:ee:af:ca:9b:c0:89:2f:28:cd:79:a7:a3:70:04:37:
+ 8b:ca:4d:84:3a:72:d5:9a:2e:f9:85:64:59:5b:7f:7e:b4:bf:
+ 09:74:af:fe:f1:d1:8c:47:3a:1b:87:9d:73:ce:a1:de:8f:33:
+ f7:ad:b4:7d:83:d5:e2:60:ff:f4:b2:79:ee:6b:fb:db:ae:c5:
+ f5:1c:e9:20:9a:b9:71:31:c9:55:02:a1:e1:9b:a6:b7:dd:c0:
+ cc:e1:66:02:91:fe:a1:59:67:bf:3b:45:32:20:08:a0:08:66:
+ eb:47:2d:db:24:6f:ab:3c:53:9b:96:81:5f:61:4a:fa:bb:70:
+ 2a:31:a1:2b:ff:cc:ae:1c:c9:be:e5:a6:f1:6a:6e:b1:3f:4b:
+ 30:59:e3:a7:9f:f2:6e:6d:9d:ed:5f:b9:cf:b2:07:66:84:63:
+ 53:f4:64:c7:d1:b2:62:63:c6:ec:a2:09:89:c5:bc:75:96:bc:
+ d2:a5:86:f7:9c:28:1c:47:45:30:e6:90:87:c6:e3:2b:be:d3:
+ 8e:b7:89:30:f3:f3:83:14:f6:56:be:0c:e7:34:6e:6f:b4:f3:
+ 0c:17:87:dd:a8:e2:8b:ec:34:24:dc:0c:16:dc:e4:c4:21:da:
+ dc:ba:9d:a6
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm3FNlWn/
+HIHaWGaQKa4VSKZDCaIFdcoW0aVp4HfIwfTl4k2Xxgnk4Jhkwrd/EVruej7F2CSw
+uKKYrAW9cQdxahFnF1VcLdP+S9Dh89UI3n7CVv/mlW8Rf1o05wwc44L29OHtTs5g
+L/dduLFU8MiqKF1WkCR7z6cB3tljFqN7XjTJjDVQV/y+bEhwg3pS2Rn46KKR8yM0
+8xS2PVnmhgWbJuwU+njTkaSv98UBFcA8hLhfCWKrw7NR3xQgR+4LX4UGQk2zWuAI
+FDLYCot6QfUONMxKo3m+bbXN0bjgcSqB4SK8bP6JWZfuca3X4dTqAYUKroOhCWU8
+Lmgp4T+wwseQhQIDAQABo4HLMIHIMB0GA1UdDgQWBBRaxgvaN6O7IYUXxe8M+r+p
+ebH+KTAfBgNVHSMEGDAWgBTTOxAmKJnsCSoInFN9JJ+x8QQLtTA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgWgMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AFMh+3LThmyv9nUHXLwMepePBbiGr+6vypvAiS8ozXmno3AEN4vKTYQ6ctWaLvmF
+ZFlbf360vwl0r/7x0YxHOhuHnXPOod6PM/ettH2D1eJg//Syee5r+9uuxfUc6SCa
+uXExyVUCoeGbprfdwMzhZgKR/qFZZ787RTIgCKAIZutHLdskb6s8U5uWgV9hSvq7
+cCoxoSv/zK4cyb7lpvFqbrE/SzBZ46ef8m5tne1fuc+yB2aEY1P0ZMfRsmJjxuyi
+CYnFvHWWvNKlhvecKBxHRTDmkIfG4yu+0463iTDz84MU9la+DOc0bm+08wwXh92o
+4ovsNCTcDBbc5MQh2ty6naY=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:99:27:87:07:8d:52:53:4f:bc:b6:55:16:e3:64:
+ 12:13:89:32:c4:f9:6f:a2:9c:93:06:fc:4c:a9:4d:
+ 09:1a:04:8a:24:58:74:7a:53:ad:d6:c6:29:0e:19:
+ f2:cc:1e:02:72:2d:7f:52:4c:3a:88:dd:35:fc:c5:
+ e6:d4:41:1a:b0:76:a7:b9:c1:db:d9:7a:a0:56:d8:
+ e7:4c:a6:ed:45:ca:99:eb:4c:dd:44:5b:52:79:00:
+ 1b:f0:ca:fc:19:c9:39:d7:1c:24:e5:90:f8:77:f7:
+ 4a:cd:0c:ec:dc:c5:15:6d:43:de:43:b4:f9:03:b9:
+ fa:b9:8f:4f:b4:e2:9f:dd:e8:d5:af:9f:ab:79:ce:
+ 32:2f:be:04:85:e8:2f:5e:91:26:b5:08:a1:ef:11:
+ f5:20:28:8d:09:9f:4e:b9:5a:ef:cf:45:b3:aa:6e:
+ 14:1b:fe:1e:c3:4b:39:ad:76:9a:58:b5:be:c4:ae:
+ ce:0e:03:ef:8e:5d:a7:03:00:e7:ed:88:0e:97:8e:
+ 2d:bd:82:6e:d8:39:7f:c0:7e:4e:c8:1e:eb:60:cb:
+ f7:97:dd:fb:79:ee:a8:00:4a:40:b7:1c:2f:1a:59:
+ 5a:51:36:a9:aa:0b:97:a0:d0:d5:87:5e:b9:36:73:
+ 5c:31:fc:b6:8c:ef:f1:2a:f5:ea:6d:2b:05:d2:8c:
+ 60:87
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ D3:3B:10:26:28:99:EC:09:2A:08:9C:53:7D:24:9F:B1:F1:04:0B:B5
+ X509v3 Authority Key Identifier:
+ keyid:D3:3B:10:26:28:99:EC:09:2A:08:9C:53:7D:24:9F:B1:F1:04:0B:B5
+
+ 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
+ 2e:84:d8:57:d4:09:e8:0e:8f:b5:9c:8f:48:ef:62:40:49:3e:
+ 9a:2e:b9:85:1c:77:f6:94:f3:73:0e:06:58:d4:63:5d:20:90:
+ e4:4b:c8:39:64:ca:ec:04:8c:bb:dd:b2:58:81:3e:89:05:1d:
+ 42:19:f9:d4:92:24:de:03:6c:69:36:74:95:65:b3:a4:06:83:
+ 2b:9f:93:72:57:dc:53:09:be:d2:fb:23:39:df:85:73:9a:c2:
+ c4:2d:7e:aa:36:01:dd:4e:a6:4f:fe:61:99:21:9c:89:a4:e7:
+ f8:8e:03:92:f6:cc:24:08:db:c8:59:41:6e:ea:c2:c3:4a:54:
+ d6:93:e5:3d:17:ff:24:a4:f7:55:2b:3c:d2:40:a7:2a:67:df:
+ 67:66:f5:37:ef:aa:20:d2:5a:da:d1:19:08:43:be:ae:11:f3:
+ 43:80:8a:ce:15:af:04:c5:b5:10:21:7c:f6:5e:7a:68:8e:59:
+ 40:ca:4b:be:c7:59:1b:48:a4:a1:ee:ef:57:b4:5b:d9:93:3b:
+ a2:36:3b:b6:f2:54:1e:c8:97:7e:5c:62:99:6c:f6:b0:bf:df:
+ af:5a:52:64:99:39:93:20:dc:4f:5e:a6:fe:8d:19:e2:21:1f:
+ 95:9d:7c:e8:8e:05:eb:74:ed:60:8e:ee:76:17:a8:40:56:36:
+ ac:bf:61:b9
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJknhweNUlNPvLZVFuNk
+EhOJMsT5b6Kckwb8TKlNCRoEiiRYdHpTrdbGKQ4Z8sweAnItf1JMOojdNfzF5tRB
+GrB2p7nB29l6oFbY50ym7UXKmetM3URbUnkAG/DK/BnJOdccJOWQ+Hf3Ss0M7NzF
+FW1D3kO0+QO5+rmPT7Tin93o1a+fq3nOMi++BIXoL16RJrUIoe8R9SAojQmfTrla
+789Fs6puFBv+HsNLOa12mli1vsSuzg4D745dpwMA5+2IDpeOLb2Cbtg5f8B+Tsge
+62DL95fd+3nuqABKQLccLxpZWlE2qaoLl6DQ1YdeuTZzXDH8tozv8Sr16m0rBdKM
+YIcCAwEAAaOByzCByDAdBgNVHQ4EFgQU0zsQJiiZ7AkqCJxTfSSfsfEEC7UwHwYD
+VR0jBBgwFoAU0zsQJiiZ7AkqCJxTfSSfsfEEC7UwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAuhNhX1Ano
+Do+1nI9I72JAST6aLrmFHHf2lPNzDgZY1GNdIJDkS8g5ZMrsBIy73bJYgT6JBR1C
+GfnUkiTeA2xpNnSVZbOkBoMrn5NyV9xTCb7S+yM534VzmsLELX6qNgHdTqZP/mGZ
+IZyJpOf4jgOS9swkCNvIWUFu6sLDSlTWk+U9F/8kpPdVKzzSQKcqZ99nZvU376og
+0lra0RkIQ76uEfNDgIrOFa8ExbUQIXz2XnpojllAyku+x1kbSKSh7u9XtFvZkzui
+Nju28lQeyJd+XGKZbPawv9+vWlJkmTmTINxPXqb+jRniIR+VnXzojgXrdO1gju52
+F6hAVjasv2G5
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/intermediary-signed-with-md5.pem b/chromium/net/data/verify_certificate_chain_unittest/intermediary-signed-with-md5.pem
new file mode 100644
index 00000000000..d15448165e2
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/intermediary-signed-with-md5.pem
@@ -0,0 +1,281 @@
+[Created by: generate-intermediary-signed-with-md5.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+however is signed using the MD5 hash. Verification is expected to fail because
+MD5 is too weak.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e9:b3:cb:c4:9b:c5:59:0a:ca:5e:ca:b3:7b:e1:
+ bb:ec:3d:4b:10:7b:d4:ee:71:92:1c:c0:24:af:0b:
+ c4:5e:55:3b:af:aa:e3:43:a3:d3:ae:1c:db:7b:fe:
+ 2a:35:d0:d8:49:77:09:f5:5d:65:9b:84:42:93:da:
+ 64:a4:12:f7:f5:6d:91:2f:7c:96:aa:7b:50:09:67:
+ 1d:f6:76:a2:4f:64:6c:d7:78:c6:78:f4:5c:83:3a:
+ 01:64:3c:15:37:4e:2a:b9:48:2a:ce:42:36:35:59:
+ b0:b0:f6:4c:db:21:59:14:87:91:09:d8:18:76:b8:
+ fb:0c:b4:e4:ab:5a:24:27:e5:47:9c:c7:eb:d0:74:
+ 17:5b:13:9a:f7:96:b7:1d:de:84:8c:6a:fd:c7:92:
+ 53:09:72:31:66:aa:54:07:3d:1c:2c:86:e9:68:d8:
+ 12:f6:22:ec:37:b5:58:6c:26:fe:79:c5:d0:f7:42:
+ 79:f9:ad:7a:3a:f4:0a:52:3e:5a:5b:45:d9:a8:d1:
+ 18:35:db:9d:56:81:11:49:f9:77:0d:ff:a7:1e:39:
+ 63:14:3b:64:3d:d0:2f:1b:47:c6:ad:6a:a8:d8:c9:
+ 09:cd:58:0b:5d:de:ad:aa:56:38:bd:42:0f:f9:c6:
+ 9d:c0:da:b0:06:03:a5:3f:43:5f:e1:83:74:cc:a7:
+ ab:9f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ E8:2D:DF:58:DB:57:BD:6D:98:31:15:C9:58:49:E0:02:47:79:10:9D
+ X509v3 Authority Key Identifier:
+ keyid:0E:AF:B4:0B:04:28:C3:55:B4:F8:2D:EB:A1:62:49:26:60:A2:A7:D8
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ a2:d6:e1:fe:94:8d:78:bc:5b:9e:53:1a:b9:6b:76:32:2e:66:
+ 0b:b3:ce:8f:96:9a:33:37:b6:e2:fb:99:56:2e:3b:cb:3d:d3:
+ 96:c7:b8:05:9a:00:e4:f4:72:f6:97:b2:b3:72:08:3d:17:59:
+ af:98:b3:16:a2:cb:e7:b8:bf:c1:5b:49:92:28:9c:47:bd:29:
+ 9e:56:f8:52:67:eb:de:23:69:52:79:32:1f:ba:b5:58:d3:b6:
+ 19:58:ac:62:04:a5:29:9a:7b:df:90:ad:c1:b1:42:c4:6c:a6:
+ 16:db:af:5e:ee:85:83:9e:c9:02:ba:c6:3c:63:55:93:58:36:
+ b4:86:b8:fa:e4:09:6f:98:6f:23:2a:2c:98:04:e4:2c:fd:69:
+ 61:b2:36:88:8f:a2:70:ec:2a:47:6d:e0:cb:f8:5c:07:25:71:
+ f4:f6:af:50:a7:d7:49:d8:c8:08:4a:09:12:8c:21:bc:d7:54:
+ f2:04:fc:f0:33:2f:aa:b1:a7:d3:0a:d0:96:0f:69:7c:a4:a8:
+ cd:a5:a6:d3:d2:6a:b1:f2:b1:0a:81:18:68:18:23:c1:6f:9c:
+ 40:9f:d2:2d:6d:e2:52:36:05:4e:99:ae:b2:e1:b3:da:40:99:
+ 1f:c6:9f:ae:9b:43:1d:e3:db:58:7c:96:b5:b8:cc:b6:b7:e9:
+ 1b:57:a0:61
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDps8vE
+m8VZCspeyrN74bvsPUsQe9TucZIcwCSvC8ReVTuvquNDo9OuHNt7/io10NhJdwn1
+XWWbhEKT2mSkEvf1bZEvfJaqe1AJZx32dqJPZGzXeMZ49FyDOgFkPBU3Tiq5SCrO
+QjY1WbCw9kzbIVkUh5EJ2Bh2uPsMtOSrWiQn5Uecx+vQdBdbE5r3lrcd3oSMav3H
+klMJcjFmqlQHPRwshulo2BL2Iuw3tVhsJv55xdD3Qnn5rXo69ApSPlpbRdmo0Rg1
+251WgRFJ+XcN/6ceOWMUO2Q90C8bR8ataqjYyQnNWAtd3q2qVji9Qg/5xp3A2rAG
+A6U/Q1/hg3TMp6ufAgMBAAGjgekwgeYwHQYDVR0OBBYEFOgt31jbV71tmDEVyVhJ
+4AJHeRCdMB8GA1UdIwQYMBaAFA6vtAsEKMNVtPgt66FiSSZgoqfYMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAotbh/pSNeLxbnlMauWt2
+Mi5mC7POj5aaMze24vuZVi47yz3Tlse4BZoA5PRy9peys3IIPRdZr5izFqLL57i/
+wVtJkiicR70pnlb4Umfr3iNpUnkyH7q1WNO2GVisYgSlKZp735CtwbFCxGymFtuv
+Xu6Fg57JArrGPGNVk1g2tIa4+uQJb5hvIyosmATkLP1pYbI2iI+icOwqR23gy/hc
+ByVx9PavUKfXSdjICEoJEowhvNdU8gT88DMvqrGn0wrQlg9pfKSozaWm09JqsfKx
+CoEYaBgjwW+cQJ/SLW3iUjYFTpmusuGz2kCZH8afrptDHePbWHyWtbjMtrfpG1eg
+YQ==
+-----END CERTIFICATE-----
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e9:c2:e1:d4:1c:a8:bf:ff:07:7f:17:bf:a4:f7:
+ f5:bc:e3:1f:76:32:e2:a3:e4:5c:a2:5d:83:a4:ad:
+ c7:19:12:8a:20:dc:5c:d3:db:22:97:e5:59:09:d8:
+ 7f:95:bc:79:61:c2:66:d1:69:02:fc:98:02:12:8e:
+ f4:4e:63:4d:1f:d0:df:f9:25:f0:86:f0:17:ba:3d:
+ 1c:5c:7d:7c:0a:f5:fc:f5:f3:a1:1f:44:45:30:e5:
+ f2:02:b8:e2:04:69:50:f7:b8:10:1d:35:92:56:3b:
+ 06:42:fc:a7:e5:45:40:b0:0c:2f:2c:61:dd:0e:55:
+ cb:23:7d:8b:48:b6:ac:68:b3:e3:3b:fc:07:a4:89:
+ 17:3e:e3:fc:74:12:e6:2f:15:b8:78:dc:a2:6b:6b:
+ 98:e2:36:f6:69:26:71:21:20:d1:60:4d:44:ea:32:
+ fd:54:64:4a:f1:6a:94:f3:51:43:e8:f9:5f:68:9e:
+ 03:a8:a8:6c:a2:0e:55:e5:d8:87:ad:62:db:61:5b:
+ a8:4b:1a:dc:f3:14:9f:97:24:5c:32:98:e4:9b:8b:
+ 1e:32:d4:12:d0:5b:a1:c1:f6:2e:85:42:c4:dc:60:
+ 8f:b1:b2:8b:7a:63:3e:ad:95:62:60:2a:0e:88:dc:
+ 5c:10:c6:90:ab:6b:75:d2:42:f4:b2:a9:81:5a:d8:
+ 0e:41
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 0E:AF:B4:0B:04:28:C3:55:B4:F8:2D:EB:A1:62:49:26:60:A2:A7:D8
+ X509v3 Authority Key Identifier:
+ keyid:DE:7E:F6:82:CA:37:00:C9:C3:30:07:35:D1:BA:48:C5:9B:B6:2D:A7
+
+ 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: md5WithRSAEncryption
+ 03:a2:90:68:d8:0d:83:e4:1c:83:20:2e:0b:ff:60:1c:01:a9:
+ ec:66:71:cd:3b:61:2c:10:95:ab:42:4e:fc:05:bb:40:d3:8c:
+ 00:34:72:b3:8f:74:de:21:67:0a:e8:b4:93:3d:c3:a2:a0:a0:
+ f0:4b:d9:7d:c6:2b:4f:dd:31:12:ad:72:3c:54:58:5c:21:3f:
+ 75:39:46:80:da:f3:20:1d:93:a3:ef:bb:00:91:bd:8d:22:16:
+ d9:5e:c7:a1:45:39:1a:76:d9:7d:e6:86:6c:65:0e:29:50:4b:
+ 5f:40:ec:79:9c:9a:d0:d9:fa:6a:6a:90:62:db:fa:9e:28:1a:
+ 40:e4:b3:45:90:41:26:09:d4:7c:f7:5c:58:ce:c5:67:6a:d1:
+ 41:86:73:df:6e:cb:79:70:75:5f:d2:54:53:07:e0:53:d1:45:
+ d9:4b:e7:f6:2b:60:fb:56:b4:17:79:be:2a:7e:98:0d:ad:ea:
+ d1:79:5d:87:80:65:84:15:61:d8:dd:a8:3c:5f:f0:90:a6:0b:
+ d8:c5:ca:d8:8d:fb:2f:1b:f8:a2:4d:ea:33:71:c2:30:a5:3b:
+ 56:a4:73:79:51:b7:7a:e7:6c:f7:23:52:48:61:1c:82:54:97:
+ 0d:54:e5:80:07:bb:84:d7:ee:90:ee:4d:85:df:f7:34:fb:d3:
+ d8:bf:19:7f
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6cLh1Byo
+v/8Hfxe/pPf1vOMfdjLio+Rcol2DpK3HGRKKINxc09sil+VZCdh/lbx5YcJm0WkC
+/JgCEo70TmNNH9Df+SXwhvAXuj0cXH18CvX89fOhH0RFMOXyArjiBGlQ97gQHTWS
+VjsGQvyn5UVAsAwvLGHdDlXLI32LSLasaLPjO/wHpIkXPuP8dBLmLxW4eNyia2uY
+4jb2aSZxISDRYE1E6jL9VGRK8WqU81FD6PlfaJ4DqKhsog5V5diHrWLbYVuoSxrc
+8xSflyRcMpjkm4seMtQS0FuhwfYuhULE3GCPsbKLemM+rZViYCoOiNxcEMaQq2t1
+0kL0sqmBWtgOQQIDAQABo4HLMIHIMB0GA1UdDgQWBBQOr7QLBCjDVbT4LeuhYkkm
+YKKn2DAfBgNVHSMEGDAWgBTefvaCyjcAycMwBzXRukjFm7YtpzA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEB
+AAOikGjYDYPkHIMgLgv/YBwBqexmcc07YSwQlatCTvwFu0DTjAA0crOPdN4hZwro
+tJM9w6KgoPBL2X3GK0/dMRKtcjxUWFwhP3U5RoDa8yAdk6PvuwCRvY0iFtlex6FF
+ORp22X3mhmxlDilQS19A7HmcmtDZ+mpqkGLb+p4oGkDks0WQQSYJ1Hz3XFjOxWdq
+0UGGc99uy3lwdV/SVFMH4FPRRdlL5/YrYPtWtBd5vip+mA2t6tF5XYeAZYQVYdjd
+qDxf8JCmC9jFytiN+y8b+KJN6jNxwjClO1akc3lRt3rnbPcjUkhhHIJUlw1U5YAH
+u4TX7pDuTYXf9zT709i/GX8=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c6:d0:57:18:e0:d7:81:35:67:b0:a4:a1:5b:fd:
+ 8f:32:51:4f:d9:76:67:02:84:59:10:4d:4a:b9:ed:
+ 1d:ef:fe:5e:d4:69:c1:24:e3:1f:91:08:d8:15:de:
+ 68:ca:dc:c7:fc:ea:6f:27:a5:60:45:af:0f:f1:44:
+ b8:d7:c7:96:70:d9:e1:dd:84:aa:ea:65:52:62:67:
+ e1:06:cd:d9:18:ad:eb:a3:0a:60:4b:cd:76:71:44:
+ 26:3c:22:c7:44:74:77:31:50:a5:b3:c4:ef:ac:14:
+ 1e:ea:ff:74:a0:7b:e4:7a:ca:87:dd:45:0b:bc:75:
+ 4b:92:44:0f:e8:f3:d2:6d:3e:47:4b:cf:77:a2:e9:
+ ff:f9:e2:79:9f:88:d7:ff:e5:cc:93:91:91:24:e1:
+ 9f:ef:a4:13:15:cc:03:3e:06:ba:9d:4c:de:52:b9:
+ de:c6:57:af:76:d8:9e:4b:37:11:1d:52:57:fe:af:
+ 8e:11:1d:fd:a8:55:3b:84:c9:10:ac:dc:51:62:e8:
+ c8:54:5b:3d:60:0b:8e:ad:66:2a:26:92:81:c6:a1:
+ be:31:51:d3:28:b1:9e:86:67:ca:c4:f2:88:47:1c:
+ 03:c9:f8:ee:f8:87:4c:b4:9e:24:9d:c0:48:d8:ec:
+ a7:8b:52:7a:d0:65:cf:06:2a:63:7f:1c:c9:15:44:
+ 48:01
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ DE:7E:F6:82:CA:37:00:C9:C3:30:07:35:D1:BA:48:C5:9B:B6:2D:A7
+ X509v3 Authority Key Identifier:
+ keyid:DE:7E:F6:82:CA:37:00:C9:C3:30:07:35:D1:BA:48:C5:9B:B6:2D:A7
+
+ 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
+ 8c:97:4a:f9:c2:c2:57:2a:4b:a1:69:03:9e:c1:17:fb:4c:f2:
+ 8e:36:0f:e2:c4:f6:4d:42:9c:ac:7f:67:7b:fd:7e:fd:14:3b:
+ fb:df:08:3d:0e:23:fa:d1:47:d5:68:14:b2:1f:5c:40:db:fe:
+ 8d:e6:fc:17:3a:c6:2f:5e:96:1a:3c:32:fa:63:c5:e5:cf:fc:
+ db:6b:59:71:b8:f7:d2:70:78:cc:7f:8c:54:5f:c6:69:ba:98:
+ 77:92:32:b3:a1:18:84:ed:3c:93:3f:12:93:64:e6:7f:92:8a:
+ 4f:db:42:1d:c0:7c:0d:4a:d6:ef:ca:05:a3:5b:26:47:79:7e:
+ 91:b0:e6:35:92:91:e2:2f:4d:18:17:44:b5:a7:de:8a:92:86:
+ 4c:0c:de:0e:23:53:c0:30:1f:7a:c5:70:59:94:19:02:8a:f1:
+ 23:f9:88:fb:09:af:b8:90:d6:c6:d5:46:92:74:44:8b:8e:66:
+ b1:79:cb:82:3d:80:cc:cf:d9:03:5a:a3:71:a6:f5:f0:75:9f:
+ 79:38:f0:fe:66:e5:d1:a1:9d:0a:48:e1:45:a1:42:fb:d3:16:
+ 53:91:b9:c9:0d:27:8a:34:e0:59:8d:4f:e0:e7:7d:7d:0c:e6:
+ ec:a1:ea:66:23:77:55:fc:f1:d0:13:32:1d:9e:0c:fd:3b:38:
+ 1d:dc:2c:2b
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbQVxjg14E1Z7CkoVv9
+jzJRT9l2ZwKEWRBNSrntHe/+XtRpwSTjH5EI2BXeaMrcx/zqbyelYEWvD/FEuNfH
+lnDZ4d2EquplUmJn4QbN2Rit66MKYEvNdnFEJjwix0R0dzFQpbPE76wUHur/dKB7
+5HrKh91FC7x1S5JED+jz0m0+R0vPd6Lp//nieZ+I1//lzJORkSThn++kExXMAz4G
+up1M3lK53sZXr3bYnks3ER1SV/6vjhEd/ahVO4TJEKzcUWLoyFRbPWALjq1mKiaS
+gcahvjFR0yixnoZnysTyiEccA8n47viHTLSeJJ3ASNjsp4tSetBlzwYqY38cyRVE
+SAECAwEAAaOByzCByDAdBgNVHQ4EFgQU3n72gso3AMnDMAc10bpIxZu2LacwHwYD
+VR0jBBgwFoAU3n72gso3AMnDMAc10bpIxZu2LacwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCMl0r5wsJX
+KkuhaQOewRf7TPKONg/ixPZNQpysf2d7/X79FDv73wg9DiP60UfVaBSyH1xA2/6N
+5vwXOsYvXpYaPDL6Y8Xlz/zba1lxuPfScHjMf4xUX8Zpuph3kjKzoRiE7TyTPxKT
+ZOZ/kopP20IdwHwNStbvygWjWyZHeX6RsOY1kpHiL00YF0S1p96KkoZMDN4OI1PA
+MB96xXBZlBkCivEj+Yj7Ca+4kNbG1UaSdESLjmaxecuCPYDMz9kDWqNxpvXwdZ95
+OPD+ZuXRoZ0KSOFFoUL70xZTkbnJDSeKNOBZjU/g5319DObsoepmI3dV/PHQEzId
+ngz9Ozgd3Cwr
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-critical-extension.pem b/chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-critical-extension.pem
new file mode 100644
index 00000000000..7e7045c1158
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-critical-extension.pem
@@ -0,0 +1,284 @@
+[Created by: generate-intermediary-unknown-critical-extension.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as critical.
+Verifying this certificate chain is expected to fail because there is an
+unrecognized critical extension.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:cf:51:a6:c4:9e:d4:eb:c4:eb:d6:57:2b:80:e5:
+ da:cd:db:3a:cf:b0:43:c5:18:9c:4e:b7:c4:9c:18:
+ 73:e6:85:e6:00:00:76:25:9f:5d:8f:28:19:f2:05:
+ 02:a9:5c:75:65:12:38:d7:7a:eb:e3:46:42:07:3d:
+ 3b:c4:5d:32:7b:26:fb:1e:69:cb:36:ca:c2:da:2f:
+ b4:ec:e3:bf:5e:9a:d3:8a:6d:3e:f2:53:dc:da:40:
+ 3c:fe:fd:02:36:32:f5:b2:17:bf:05:97:f0:3e:8b:
+ b7:15:a2:10:be:27:79:62:30:82:3e:57:60:60:13:
+ 8e:fc:33:8e:72:cd:d9:d9:50:e9:62:04:8c:e4:db:
+ f8:cf:1b:da:a2:f7:ee:4c:b8:7f:b2:bf:92:c9:2c:
+ 44:a7:b5:ad:b9:75:06:c0:24:5a:0b:44:ca:4f:af:
+ f6:2f:c2:00:12:bb:7b:0c:c4:54:47:f1:73:53:64:
+ 72:40:9d:51:40:b3:21:73:ce:82:c5:f3:b7:14:ef:
+ 31:50:5b:d5:0b:b7:92:0e:08:5c:ea:ed:73:86:e3:
+ b1:6d:63:7f:56:7d:74:3e:3b:90:8c:2f:a2:6e:65:
+ b9:4e:38:a3:54:fb:7b:de:69:6f:c0:57:ea:51:c0:
+ 09:83:b4:a8:4d:ec:74:a6:ea:31:97:0c:9a:66:b7:
+ 58:0f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 89:EB:AF:F5:F3:C7:53:ED:03:95:5A:DB:94:4A:E0:BF:C3:D2:CE:FA
+ X509v3 Authority Key Identifier:
+ keyid:21:32:55:0D:16:9C:AD:C4:16:5D:BE:40:67:0D:B6:40:4E:E2:75:60
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 17:7b:87:2f:11:ac:6d:68:03:d3:07:31:20:18:b7:d4:9d:98:
+ e4:aa:10:6d:f2:41:2f:3e:cf:1f:50:f9:f9:3f:6e:61:c2:b7:
+ dd:e0:f6:5a:d6:66:bb:2d:31:98:6a:12:0a:17:e8:a1:4e:cd:
+ fd:c4:ed:3e:01:a3:1c:ef:18:9e:fb:f8:46:c6:1b:ad:a4:ce:
+ ba:84:79:a6:84:f0:2c:84:d4:6c:3f:f9:ff:f8:66:f1:9b:82:
+ 8c:83:c8:79:5b:bd:f0:dd:e0:e5:76:55:92:97:d2:46:64:ea:
+ 3e:99:bc:9d:b8:8f:15:41:f8:3f:1b:c0:df:cd:d5:01:88:74:
+ 37:8e:58:f8:ad:7d:75:70:59:98:cc:c4:bd:fc:b9:bd:f5:69:
+ fe:09:08:be:ea:e8:f3:ee:53:d8:05:4f:d5:d1:85:dc:7e:58:
+ 64:cf:d4:41:c1:d0:ec:c4:2a:ca:ae:39:8e:57:63:e3:03:ff:
+ 4f:d4:42:92:ec:ac:e8:f6:83:e5:51:0e:32:2c:6f:2d:15:72:
+ 21:37:f0:18:77:3b:97:f5:71:84:1f:07:e0:76:b6:a0:f4:34:
+ 16:b9:53:e2:4f:48:45:b6:7d:b3:0f:30:06:e6:89:89:a4:3f:
+ e8:4c:2a:9c:1f:9c:91:c9:66:4e:28:39:3d:5b:21:19:03:dc:
+ 02:56:69:e9
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPUabE
+ntTrxOvWVyuA5drN2zrPsEPFGJxOt8ScGHPmheYAAHYln12PKBnyBQKpXHVlEjjX
+euvjRkIHPTvEXTJ7Jvseacs2ysLaL7Ts479emtOKbT7yU9zaQDz+/QI2MvWyF78F
+l/A+i7cVohC+J3liMII+V2BgE478M45yzdnZUOliBIzk2/jPG9qi9+5MuH+yv5LJ
+LESnta25dQbAJFoLRMpPr/YvwgASu3sMxFRH8XNTZHJAnVFAsyFzzoLF87cU7zFQ
+W9ULt5IOCFzq7XOG47FtY39WfXQ+O5CML6JuZblOOKNU+3veaW/AV+pRwAmDtKhN
+7HSm6jGXDJpmt1gPAgMBAAGjgekwgeYwHQYDVR0OBBYEFInrr/Xzx1PtA5Va25RK
+4L/D0s76MB8GA1UdIwQYMBaAFCEyVQ0WnK3EFl2+QGcNtkBO4nVgMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAF3uHLxGsbWgD0wcxIBi3
+1J2Y5KoQbfJBLz7PH1D5+T9uYcK33eD2WtZmuy0xmGoSChfooU7N/cTtPgGjHO8Y
+nvv4RsYbraTOuoR5poTwLITUbD/5//hm8ZuCjIPIeVu98N3g5XZVkpfSRmTqPpm8
+nbiPFUH4PxvA383VAYh0N45Y+K19dXBZmMzEvfy5vfVp/gkIvuro8+5T2AVP1dGF
+3H5YZM/UQcHQ7MQqyq45jldj4wP/T9RCkuys6PaD5VEOMixvLRVyITfwGHc7l/Vx
+hB8H4Ha2oPQ0FrlT4k9IRbZ9sw8wBuaJiaQ/6EwqnB+ckclmTig5PVshGQPcAlZp
+6Q==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c7:80:3b:a7:4e:4e:fa:0a:39:4f:5b:5c:af:ba:
+ 84:27:6a:8d:34:95:5e:91:93:c8:d0:1f:64:84:5f:
+ 25:d9:3b:5d:f9:31:5f:4f:6f:04:be:50:35:09:5e:
+ 78:f3:9a:15:b5:27:fa:24:70:04:26:29:08:95:a5:
+ dd:b1:ee:4f:ee:d8:a0:59:51:ab:75:70:c2:7b:42:
+ 06:e2:4d:d7:91:ec:e5:e7:f8:34:1e:01:63:45:11:
+ 6a:fe:45:3e:e7:16:59:86:e7:4b:91:67:ec:1f:c1:
+ 13:a4:62:cb:f6:0d:9b:2b:e5:1e:df:c4:35:f3:94:
+ 60:9b:99:e1:54:ce:ff:7d:92:f1:9d:d4:f6:0e:99:
+ 8c:dc:7b:b1:95:54:04:6f:40:1c:23:42:50:ab:96:
+ f5:9e:93:27:f1:5c:e5:97:9c:c1:e4:ae:a8:cb:f9:
+ 42:7e:14:02:e1:32:4b:4d:03:2d:2a:a6:7e:a1:77:
+ c3:4e:4e:46:18:1a:95:d7:0d:48:8d:a1:d3:bb:b7:
+ 55:07:01:d9:c0:27:fd:f7:ec:61:3a:57:84:b6:91:
+ 78:dc:a9:19:a6:d4:83:c5:57:67:bd:b7:a0:6a:ec:
+ 7b:83:1e:d9:bf:2f:b7:bf:d6:ce:18:5a:54:cf:8b:
+ 1a:fc:5a:03:63:bc:d2:3a:01:db:91:e0:ce:96:19:
+ 55:19
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 21:32:55:0D:16:9C:AD:C4:16:5D:BE:40:67:0D:B6:40:4E:E2:75:60
+ X509v3 Authority Key Identifier:
+ keyid:BA:1F:26:2C:E0:77:F2:16:78:6D:83:49:A1:30:9E:B4:AB:10:6A:22
+
+ 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
+ 1.2.3.4: critical
+ ....
+ Signature Algorithm: sha256WithRSAEncryption
+ 02:57:1a:5a:82:9a:29:1e:39:b4:aa:c4:e3:04:2b:6f:1c:0a:
+ 79:df:d3:f8:c9:9f:94:b6:c1:7e:e5:47:8d:35:72:e2:09:ce:
+ 6f:61:f1:7e:93:f3:37:11:0d:c0:28:05:bc:8d:dc:f8:2a:22:
+ 0e:dc:79:b9:71:99:38:f5:c2:81:ac:0b:47:c2:39:96:2e:2b:
+ 35:0a:fe:80:fe:50:da:74:03:1c:4b:36:be:4b:23:70:4f:a1:
+ 1f:c8:3b:9a:6b:92:3d:61:9b:67:9a:8b:ea:0b:b0:8c:aa:6a:
+ 02:fd:27:6f:a8:be:8f:d0:78:f2:84:76:da:e2:c5:10:3c:9f:
+ 61:c4:3f:50:8e:40:ac:d8:aa:87:b6:7c:da:42:c5:05:c0:82:
+ bc:9f:35:ae:22:34:32:11:71:ab:fd:27:af:ef:42:ec:cd:b7:
+ d1:66:14:5f:f1:e5:10:c2:1f:ac:e4:96:1f:a9:9c:5a:ad:97:
+ 4d:90:40:df:cb:77:15:ba:d5:f4:76:94:9f:d6:c2:4f:53:60:
+ 3b:c3:a3:9c:02:4d:03:28:32:58:3d:0f:62:36:a9:7b:70:d9:
+ f8:2b:05:cd:ca:c7:17:68:76:6b:cd:ad:7f:f1:65:a6:d1:be:
+ b7:4c:83:bb:0d:5d:98:6e:02:d3:b6:ea:82:b6:44:0d:a1:b2:
+ 37:4b:a0:a3
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAmWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx4A7p05O
++go5T1tcr7qEJ2qNNJVekZPI0B9khF8l2Ttd+TFfT28EvlA1CV5485oVtSf6JHAE
+JikIlaXdse5P7tigWVGrdXDCe0IG4k3Xkezl5/g0HgFjRRFq/kU+5xZZhudLkWfs
+H8ETpGLL9g2bK+Ue38Q185Rgm5nhVM7/fZLxndT2DpmM3HuxlVQEb0AcI0JQq5b1
+npMn8Vzll5zB5K6oy/lCfhQC4TJLTQMtKqZ+oXfDTk5GGBqV1w1IjaHTu7dVBwHZ
+wCf99+xhOleEtpF43KkZptSDxVdnvbegaux7gx7Zvy+3v9bOGFpUz4sa/FoDY7zS
+OgHbkeDOlhlVGQIDAQABo4HbMIHYMB0GA1UdDgQWBBQhMlUNFpytxBZdvkBnDbZA
+TuJ1YDAfBgNVHSMEGDAWgBS6HyYs4HfyFnhtg0mhMJ60qxBqIjA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDgYDKgMEAQH/BAQBAgMEMA0G
+CSqGSIb3DQEBCwUAA4IBAQACVxpagpopHjm0qsTjBCtvHAp539P4yZ+UtsF+5UeN
+NXLiCc5vYfF+k/M3EQ3AKAW8jdz4KiIO3Hm5cZk49cKBrAtHwjmWLis1Cv6A/lDa
+dAMcSza+SyNwT6EfyDuaa5I9YZtnmovqC7CMqmoC/SdvqL6P0HjyhHba4sUQPJ9h
+xD9QjkCs2KqHtnzaQsUFwIK8nzWuIjQyEXGr/Sev70LszbfRZhRf8eUQwh+s5JYf
+qZxarZdNkEDfy3cVutX0dpSf1sJPU2A7w6OcAk0DKDJYPQ9iNql7cNn4KwXNyscX
+aHZrza1/8WWm0b63TIO7DV2YbgLTtuqCtkQNobI3S6Cj
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9f:42:45:62:cb:c5:f3:07:65:8a:9b:4c:d4:91:
+ 4a:66:e6:89:24:24:6f:91:3e:4a:50:63:42:47:e3:
+ 67:10:71:ac:f3:81:82:3b:9f:56:7c:6a:36:a6:87:
+ be:d5:e6:03:4b:bb:d3:c8:90:6a:6b:1d:4c:16:a1:
+ c3:98:58:f7:39:de:90:27:df:40:c5:03:10:b2:b4:
+ 1b:cb:28:5d:80:a4:83:60:f2:c0:ac:f5:1f:81:4d:
+ 31:84:6f:04:96:7b:26:bf:b6:55:78:33:06:23:65:
+ 1c:bc:65:ac:a3:31:27:49:38:ce:92:73:87:a7:b4:
+ 53:4b:85:71:29:7a:f5:09:fc:03:9a:90:56:14:b1:
+ b7:89:03:c4:61:b6:49:fc:3d:30:62:84:a2:46:66:
+ 22:37:32:fd:a3:62:bb:99:62:53:ca:fc:1f:e9:29:
+ c6:d4:8c:09:6f:02:d5:de:7c:de:12:d8:00:dd:df:
+ 04:94:d4:36:b5:f6:d9:fe:a7:ff:46:e7:07:da:3e:
+ d0:e3:ea:90:4c:7c:b7:ff:bc:85:99:d5:1f:46:f5:
+ ac:57:e9:09:03:61:8c:0b:9d:a8:82:9c:17:43:27:
+ de:80:d2:59:e3:ca:ed:23:41:1a:32:48:83:ca:bd:
+ 8e:cb:bf:9c:f0:03:7d:e0:41:ce:72:05:27:59:3c:
+ 10:5b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ BA:1F:26:2C:E0:77:F2:16:78:6D:83:49:A1:30:9E:B4:AB:10:6A:22
+ X509v3 Authority Key Identifier:
+ keyid:BA:1F:26:2C:E0:77:F2:16:78:6D:83:49:A1:30:9E:B4:AB:10:6A:22
+
+ 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
+ 70:b4:15:ff:b7:d9:b7:51:10:ce:fa:e5:61:0e:f6:c7:b6:d7:
+ be:59:ed:07:d5:77:95:e1:ef:3f:80:9e:99:d2:2c:1b:9a:a7:
+ 35:1c:ec:84:9e:ce:27:52:3a:2c:00:06:4d:60:62:aa:4b:a7:
+ 61:32:e3:64:f1:96:c7:d2:3f:fe:78:bc:f4:da:76:f9:44:d2:
+ 9b:1a:94:1f:44:9a:49:c9:c0:1c:de:a9:63:d0:23:4a:c3:fb:
+ 60:45:76:dd:12:ef:c1:95:4f:8e:bd:48:56:b8:f9:74:e2:5c:
+ ae:90:5a:19:9e:90:13:0b:97:ff:cd:a9:45:54:68:aa:fa:f6:
+ ea:3f:2e:fa:2a:40:48:42:cd:10:cc:c8:e6:a4:34:9d:8f:1c:
+ 74:55:58:b2:99:cf:35:40:23:bf:90:5f:4c:60:30:5f:a0:b4:
+ d6:0f:4f:42:03:71:82:f7:d3:f5:72:bb:a8:cf:24:ab:10:7e:
+ c5:e1:84:a9:7e:25:b1:8a:80:db:ae:0e:49:f1:03:fb:11:1a:
+ 63:58:42:7f:73:9b:f3:f8:d6:ae:81:0b:59:ca:98:ec:3d:9c:
+ 85:6b:7d:70:e8:c2:04:47:f0:b6:7e:4a:96:70:c9:a8:11:b7:
+ 23:54:55:d3:57:c3:7e:47:66:35:91:26:56:fd:37:14:35:a4:
+ 6b:29:38:ee
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ9CRWLLxfMHZYqbTNSR
+SmbmiSQkb5E+SlBjQkfjZxBxrPOBgjufVnxqNqaHvtXmA0u708iQamsdTBahw5hY
+9znekCffQMUDELK0G8soXYCkg2DywKz1H4FNMYRvBJZ7Jr+2VXgzBiNlHLxlrKMx
+J0k4zpJzh6e0U0uFcSl69Qn8A5qQVhSxt4kDxGG2Sfw9MGKEokZmIjcy/aNiu5li
+U8r8H+kpxtSMCW8C1d583hLYAN3fBJTUNrX22f6n/0bnB9o+0OPqkEx8t/+8hZnV
+H0b1rFfpCQNhjAudqIKcF0Mn3oDSWePK7SNBGjJIg8q9jsu/nPADfeBBznIFJ1k8
+EFsCAwEAAaOByzCByDAdBgNVHQ4EFgQUuh8mLOB38hZ4bYNJoTCetKsQaiIwHwYD
+VR0jBBgwFoAUuh8mLOB38hZ4bYNJoTCetKsQaiIwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBwtBX/t9m3
+URDO+uVhDvbHtte+We0H1XeV4e8/gJ6Z0iwbmqc1HOyEns4nUjosAAZNYGKqS6dh
+MuNk8ZbH0j/+eLz02nb5RNKbGpQfRJpJycAc3qlj0CNKw/tgRXbdEu/BlU+OvUhW
+uPl04lyukFoZnpATC5f/zalFVGiq+vbqPy76KkBIQs0QzMjmpDSdjxx0VViymc81
+QCO/kF9MYDBfoLTWD09CA3GC99P1cruozySrEH7F4YSpfiWxioDbrg5J8QP7ERpj
+WEJ/c5vz+NaugQtZypjsPZyFa31w6MIER/C2fkqWcMmoEbcjVFXTV8N+R2Y1kSZW
+/TcUNaRrKTju
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-non-critical-extension.pem b/chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-non-critical-extension.pem
new file mode 100644
index 00000000000..dffed19e120
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/intermediary-unknown-non-critical-extension.pem
@@ -0,0 +1,284 @@
+[Created by: generate-intermediary-unknown-non-critical-extension.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+has an unknown X.509v3 extension that is marked as non-critical. Verification
+is expected to succeed because although unrecognized, the extension is not
+critical.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e2:f4:a3:48:79:59:87:08:4d:c1:84:b4:97:67:
+ 5d:f6:24:2b:74:f1:f0:1a:13:e0:a5:28:30:1f:c6:
+ 04:fc:ce:9b:73:4a:95:1f:56:a0:9d:26:07:97:8f:
+ 7c:06:c7:a2:fb:5f:85:41:d3:bd:50:83:61:72:5e:
+ a0:f9:e1:39:c6:ae:77:05:8c:f7:8e:6f:ae:5d:14:
+ 69:97:12:4a:c7:40:de:e7:ab:7a:83:9b:b3:e8:15:
+ 90:ab:52:3a:ee:c4:36:9b:58:eb:51:c3:1d:c5:c8:
+ eb:f7:65:e9:15:56:93:e4:55:37:97:29:f1:88:da:
+ fc:1c:53:5f:24:07:f9:3e:14:86:b3:50:c6:94:06:
+ 8e:b1:b1:ab:32:d4:f3:98:ee:f8:42:ed:65:43:36:
+ bb:4f:59:a0:4d:77:a5:9e:a9:c2:40:40:df:cc:3c:
+ d7:dc:56:bd:d4:2c:fe:b5:20:d6:a8:74:cd:99:4f:
+ bf:eb:71:0b:20:95:f2:c3:21:92:42:d7:e6:ff:5b:
+ 87:0b:c2:89:5c:e7:d6:30:77:cd:8d:c7:92:0d:74:
+ 6f:88:d6:81:49:e8:f6:25:de:6d:51:3e:db:cd:e4:
+ 91:99:98:5a:ff:7a:61:46:da:7a:ec:9b:22:a5:5f:
+ 16:6e:cd:7a:ec:3b:b0:aa:1b:af:65:a6:3a:85:fc:
+ a6:e9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 82:EC:E0:87:C2:A2:2A:EF:4B:E0:B5:F8:75:6A:18:32:51:B4:0D:54
+ X509v3 Authority Key Identifier:
+ keyid:60:BD:98:38:CE:C3:01:40:CA:86:14:C7:F4:E4:D5:72:BA:ED:80:31
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 89:1e:64:8c:61:b5:87:aa:76:6d:f6:ef:87:b6:ca:3b:0f:47:
+ a9:bb:9a:91:7f:7a:d8:65:e9:c7:b1:1a:ea:13:fb:9c:79:5e:
+ df:33:f5:d9:bc:f1:f8:89:bc:59:31:27:c2:2d:3e:47:e9:13:
+ 27:65:c8:cb:ba:e1:da:51:60:7a:93:aa:28:92:d5:81:89:09:
+ b7:22:e7:4b:4f:82:0e:fb:2f:62:19:b4:ea:f5:47:34:fd:60:
+ 7e:4c:e6:be:08:8e:f8:fd:89:62:ff:97:89:27:69:37:7f:e3:
+ 76:ea:72:30:ca:de:73:bb:c7:65:1c:6d:5e:ab:f8:ba:da:57:
+ 7d:28:1f:6a:64:76:aa:89:6b:ac:57:a3:e9:e2:c1:ca:f8:4b:
+ 7c:0b:21:57:cc:71:c8:9b:7f:25:8f:09:61:6e:5c:a8:9b:0b:
+ 79:98:7a:1e:82:95:22:fd:9e:9c:cd:20:73:0d:0e:d9:21:cb:
+ 67:3d:e9:1e:24:ae:4f:84:1f:de:3e:27:ee:54:41:66:71:9c:
+ b6:6b:08:7a:16:e7:c1:c7:7a:71:24:ed:c0:2a:d9:fd:2b:ff:
+ e6:41:c9:63:93:90:52:35:21:4a:72:be:f9:9c:27:49:0d:b7:
+ 01:af:cb:5f:53:ee:ef:58:69:16:ba:e6:5b:12:45:e0:d4:3d:
+ ea:58:fe:a5
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDi9KNI
+eVmHCE3BhLSXZ132JCt08fAaE+ClKDAfxgT8zptzSpUfVqCdJgeXj3wGx6L7X4VB
+071Qg2FyXqD54TnGrncFjPeOb65dFGmXEkrHQN7nq3qDm7PoFZCrUjruxDabWOtR
+wx3FyOv3ZekVVpPkVTeXKfGI2vwcU18kB/k+FIazUMaUBo6xsasy1POY7vhC7WVD
+NrtPWaBNd6WeqcJAQN/MPNfcVr3ULP61INaodM2ZT7/rcQsglfLDIZJC1+b/W4cL
+wolc59Ywd82Nx5INdG+I1oFJ6PYl3m1RPtvN5JGZmFr/emFG2nrsmyKlXxZuzXrs
+O7CqG69lpjqF/KbpAgMBAAGjgekwgeYwHQYDVR0OBBYEFILs4IfCoirvS+C1+HVq
+GDJRtA1UMB8GA1UdIwQYMBaAFGC9mDjOwwFAyoYUx/Tk1XK67YAxMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAiR5kjGG1h6p2bfbvh7bK
+Ow9HqbuakX962GXpx7Ea6hP7nHle3zP12bzx+Im8WTEnwi0+R+kTJ2XIy7rh2lFg
+epOqKJLVgYkJtyLnS0+CDvsvYhm06vVHNP1gfkzmvgiO+P2JYv+XiSdpN3/jdupy
+MMrec7vHZRxtXqv4utpXfSgfamR2qolrrFej6eLByvhLfAshV8xxyJt/JY8JYW5c
+qJsLeZh6HoKVIv2enM0gcw0O2SHLZz3pHiSuT4Qf3j4n7lRBZnGctmsIehbnwcd6
+cSTtwCrZ/Sv/5kHJY5OQUjUhSnK++ZwnSQ23Aa/LX1Pu71hpFrrmWxJF4NQ96lj+
+pQ==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:de:7c:cd:1c:92:c3:9a:ff:be:f3:03:37:c7:6a:
+ 3a:d4:ac:56:50:3a:b1:17:0d:73:09:ef:d9:16:4b:
+ 38:de:a4:82:46:61:a8:ed:f8:b9:a0:21:7e:3c:26:
+ f6:a8:c5:d3:34:99:9c:58:c6:e1:de:f6:1c:eb:49:
+ a3:34:65:71:29:95:3a:2e:b4:5f:33:dd:2a:0b:5f:
+ 7a:e0:47:3f:bc:00:15:a1:24:26:9f:c6:c7:d7:eb:
+ e3:f3:37:19:d5:30:48:f2:7d:c5:77:11:cc:cc:17:
+ 7e:91:c4:20:f8:a6:c3:28:00:ec:23:53:40:7b:0e:
+ dc:14:6e:57:a5:ca:52:9f:2b:3b:34:ea:e4:ae:5c:
+ ed:b4:8d:25:9a:08:00:26:d0:e4:34:d2:94:36:8c:
+ e1:df:ef:31:f8:18:5b:ed:80:57:44:77:94:a2:fa:
+ ae:5c:e0:ea:e1:30:e3:24:03:da:7c:5b:66:90:c7:
+ 01:f1:f8:8d:ca:bc:d7:e3:25:35:28:3c:f6:f4:83:
+ 13:2a:73:d0:f7:c2:69:11:b1:ed:43:6d:71:28:7e:
+ 43:8d:f5:f0:78:e2:5a:31:39:38:ae:92:05:29:e0:
+ 1f:04:6f:9d:a0:a1:b4:29:80:af:87:1c:0c:e5:7d:
+ 6d:11:59:63:43:af:7f:a4:32:fa:0a:d1:7e:88:86:
+ cd:61
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 60:BD:98:38:CE:C3:01:40:CA:86:14:C7:F4:E4:D5:72:BA:ED:80:31
+ X509v3 Authority Key Identifier:
+ keyid:B2:41:26:7A:EF:3A:C9:BF:FE:6A:E7:7F:04:60:B0:34:62:08:E3:93
+
+ 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
+ 1.2.3.4:
+ ....
+ Signature Algorithm: sha256WithRSAEncryption
+ 68:5c:74:6c:fd:93:14:86:9f:d9:3a:4b:67:1d:6e:2b:78:2f:
+ 89:b4:b0:76:ac:3f:aa:ea:4a:ea:42:04:40:96:09:1a:b7:b7:
+ 01:93:fb:55:0d:44:30:0e:16:b3:e8:bb:b2:77:17:79:93:37:
+ 17:b5:62:c9:5b:15:76:90:2d:74:3d:1f:7e:59:61:59:e2:61:
+ 81:18:46:6b:94:42:be:be:d3:1e:37:16:68:49:db:9e:f0:f1:
+ 24:bb:e0:00:e0:57:e0:27:3f:59:e9:a8:92:31:80:2a:7a:cc:
+ b1:47:5b:8d:3b:55:f5:5a:f0:9a:56:90:1a:8e:d2:ab:51:e2:
+ 15:ca:9f:cb:a9:ec:10:f1:5d:58:72:84:75:63:bd:a7:7c:bf:
+ 5b:80:65:d6:97:77:e2:8a:89:8a:ea:5b:1f:da:55:5e:7b:33:
+ 37:e2:60:09:02:13:89:a3:ca:0f:bf:17:8e:47:fb:c1:8d:a8:
+ fb:9f:20:64:a6:a4:a0:86:da:fa:7f:6a:e1:50:10:41:9b:21:
+ e6:8e:9f:29:9c:cc:0b:83:a3:65:47:2a:15:8b:47:6a:48:89:
+ e4:2c:97:d7:81:51:bb:bb:e0:db:22:e2:be:bf:53:63:26:77:
+ 08:c3:b6:04:c7:9b:9c:03:91:00:63:bd:70:cb:e2:6c:c8:a7:
+ 2c:5b:f6:28
+-----BEGIN CERTIFICATE-----
+MIIDejCCAmKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3nzNHJLD
+mv++8wM3x2o61KxWUDqxFw1zCe/ZFks43qSCRmGo7fi5oCF+PCb2qMXTNJmcWMbh
+3vYc60mjNGVxKZU6LrRfM90qC1964Ec/vAAVoSQmn8bH1+vj8zcZ1TBI8n3FdxHM
+zBd+kcQg+KbDKADsI1NAew7cFG5XpcpSnys7NOrkrlzttI0lmggAJtDkNNKUNozh
+3+8x+Bhb7YBXRHeUovquXODq4TDjJAPafFtmkMcB8fiNyrzX4yU1KDz29IMTKnPQ
+98JpEbHtQ21xKH5DjfXweOJaMTk4rpIFKeAfBG+doKG0KYCvhxwM5X1tEVljQ69/
+pDL6CtF+iIbNYQIDAQABo4HYMIHVMB0GA1UdDgQWBBRgvZg4zsMBQMqGFMf05NVy
+uu2AMTAfBgNVHSMEGDAWgBSyQSZ67zrJv/5q538EYLA0YgjjkzA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wCwYDKgMEBAQBAgMEMA0GCSqG
+SIb3DQEBCwUAA4IBAQBoXHRs/ZMUhp/ZOktnHW4reC+JtLB2rD+q6krqQgRAlgka
+t7cBk/tVDUQwDhaz6Luydxd5kzcXtWLJWxV2kC10PR9+WWFZ4mGBGEZrlEK+vtMe
+NxZoSdue8PEku+AA4FfgJz9Z6aiSMYAqesyxR1uNO1X1WvCaVpAajtKrUeIVyp/L
+qewQ8V1YcoR1Y72nfL9bgGXWl3fiiomK6lsf2lVeezM34mAJAhOJo8oPvxeOR/vB
+jaj7nyBkpqSghtr6f2rhUBBBmyHmjp8pnMwLg6NlRyoVi0dqSInkLJfXgVG7u+Db
+IuK+v1NjJncIw7YEx5ucA5EAY71wy+JsyKcsW/Yo
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a8:e9:07:4a:9e:20:9a:c5:14:9a:16:49:17:bf:
+ 0b:c1:7d:b6:91:54:cd:60:e6:df:bf:81:e1:bb:24:
+ 47:df:ea:c8:27:93:bb:49:b7:b7:e6:48:ff:11:43:
+ c1:8d:cb:54:f8:0d:49:05:e7:4b:a9:0d:cb:79:b8:
+ 49:26:6b:1c:ad:7d:2c:e5:a3:0a:1b:ad:99:9c:d4:
+ c2:d6:2c:de:ae:74:42:b7:06:ca:e0:57:06:e6:46:
+ 5a:80:70:6f:f7:0c:76:c5:8f:de:cc:35:85:bf:f5:
+ 79:29:63:79:22:fd:c0:48:1e:a0:4f:86:6b:2f:07:
+ 72:55:1f:96:dc:81:c7:19:8d:bf:7f:56:21:fc:05:
+ 6e:1a:3d:6d:f2:a7:37:6f:8d:c9:f5:5e:79:3a:89:
+ 6b:b5:6b:d4:14:eb:c4:de:3d:68:8c:e6:f8:96:e3:
+ b3:cb:73:09:6a:d1:8d:46:9e:c6:9f:1d:01:30:69:
+ ea:a4:2a:3c:90:fe:40:92:9d:61:81:88:96:67:cb:
+ ae:4c:f5:3d:31:37:8b:31:0a:a0:cf:87:80:f7:50:
+ eb:93:32:bf:64:13:3e:0a:d8:98:80:4b:b7:b1:a9:
+ 87:fe:b8:d3:d2:3b:a2:7d:20:cb:ff:6b:4e:67:88:
+ 52:03:4c:a2:2a:81:0d:63:4e:d0:f8:2e:f6:38:c9:
+ 9b:03
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ B2:41:26:7A:EF:3A:C9:BF:FE:6A:E7:7F:04:60:B0:34:62:08:E3:93
+ X509v3 Authority Key Identifier:
+ keyid:B2:41:26:7A:EF:3A:C9:BF:FE:6A:E7:7F:04:60:B0:34:62:08:E3:93
+
+ 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
+ 91:be:af:fa:3e:50:a9:b4:7e:d5:c6:a9:91:2f:d3:63:11:bc:
+ 07:35:35:31:76:8e:69:e4:39:7d:82:65:be:6b:b0:9e:42:ce:
+ 0c:02:5a:0d:73:93:ce:89:c1:c7:27:cb:19:26:a0:77:85:53:
+ b5:1e:a8:60:9f:0c:b9:b4:fa:34:9f:4f:3a:0e:d6:ab:d3:a6:
+ 47:32:d8:ec:c9:80:90:2e:7c:fa:5f:16:96:f6:ba:fd:13:10:
+ 73:ec:3e:b0:3c:f5:7a:e1:8f:e3:32:59:d2:f1:3c:36:8c:92:
+ 21:a1:29:21:39:1c:08:b1:f6:85:35:ab:36:97:56:fc:4c:85:
+ 11:bc:69:72:05:f6:21:b8:85:bb:1e:cf:69:1a:3c:98:dd:93:
+ 58:53:e0:f1:ce:d0:2a:68:d9:b3:b9:26:71:d9:61:01:a8:cd:
+ bb:53:48:06:a5:c4:3f:d6:3b:aa:01:4d:01:fc:f2:79:96:a9:
+ 13:d3:ba:25:2c:2a:3d:e5:bd:e1:f7:ae:f9:3a:ea:59:77:8c:
+ 27:3c:f5:a4:01:f8:08:97:1b:28:1a:81:cb:ce:36:6b:2f:1e:
+ 41:05:f6:d6:d9:4d:84:87:16:61:e4:34:4c:06:7e:a8:2b:2b:
+ b5:a1:93:de:ca:52:f7:74:d9:ce:f7:f7:2b:0f:5d:f8:b6:9f:
+ 93:34:b2:00
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKjpB0qeIJrFFJoWSRe/
+C8F9tpFUzWDm37+B4bskR9/qyCeTu0m3t+ZI/xFDwY3LVPgNSQXnS6kNy3m4SSZr
+HK19LOWjChutmZzUwtYs3q50QrcGyuBXBuZGWoBwb/cMdsWP3sw1hb/1eSljeSL9
+wEgeoE+Gay8HclUfltyBxxmNv39WIfwFbho9bfKnN2+NyfVeeTqJa7Vr1BTrxN49
+aIzm+Jbjs8tzCWrRjUaexp8dATBp6qQqPJD+QJKdYYGIlmfLrkz1PTE3izEKoM+H
+gPdQ65Myv2QTPgrYmIBLt7Gph/6409I7on0gy/9rTmeIUgNMoiqBDWNO0Pgu9jjJ
+mwMCAwEAAaOByzCByDAdBgNVHQ4EFgQUskEmeu86yb/+aud/BGCwNGII45MwHwYD
+VR0jBBgwFoAUskEmeu86yb/+aud/BGCwNGII45MwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCRvq/6PlCp
+tH7VxqmRL9NjEbwHNTUxdo5p5Dl9gmW+a7CeQs4MAloNc5POicHHJ8sZJqB3hVO1
+Hqhgnwy5tPo0n086Dtar06ZHMtjsyYCQLnz6XxaW9rr9ExBz7D6wPPV64Y/jMlnS
+8Tw2jJIhoSkhORwIsfaFNas2l1b8TIURvGlyBfYhuIW7Hs9pGjyY3ZNYU+DxztAq
+aNmzuSZx2WEBqM27U0gGpcQ/1juqAU0B/PJ5lqkT07olLCo95b3h9675OupZd4wn
+PPWkAfgIlxsoGoHLzjZrLx5BBfbW2U2EhxZh5DRMBn6oKyu1oZPeylL3dNnO9/cr
+D134tp+TNLIA
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem b/chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem
new file mode 100644
index 00000000000..f4c1086a8de
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem
@@ -0,0 +1,284 @@
+This is certificate chain where the issuer of the second certificate is not
+byte-for-byte equal to the subject of the trust anchor.
+
+The names are equal when applying the comparison rules given in RFC 5280. The
+difference in byte values is due to encoding some components as UTF8String
+which were encoded in the other version as PrintableString.
+
+The verification should succeed.
+
+This certificate chain was obtained from the certificate transparency database.
+
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 16695415 (0xfec077)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=KR, O=Government of Korea, OU=GPKI, CN=CA134040001
+ Validity
+ Not Before: May 2 04:58:54 2012 GMT
+ Not After : Jul 23 02:59:59 2014 GMT
+ Subject: C=KR, O=Government of Korea, OU=Group of Server, OU=\xEA\xB5\x90\xEC\x9C\xA1\xEA\xB3\xBC\xED\x95\x99\xEA\xB8\xB0\xEC\x88\xA0\xEB\xB6\x80, CN=*.daejin.or.kr
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (1024 bit)
+ Modulus:
+ 00:f1:3d:ac:1e:99:11:4f:45:7b:82:31:1f:e7:87:
+ cc:8d:8c:4a:04:e4:1f:64:ec:cb:31:96:3d:1d:1c:
+ 6d:06:cb:49:03:31:77:aa:df:c7:95:93:6c:6e:dc:
+ 80:b9:c9:fe:4a:74:ee:5e:15:46:8d:9c:f0:ea:6d:
+ 6b:b6:46:f3:2e:64:50:3f:5e:22:df:99:0a:15:7c:
+ 2f:23:aa:88:f3:36:da:58:03:29:ae:d3:13:2d:af:
+ 9f:03:58:a9:9e:07:26:d7:10:8a:74:55:6c:50:af:
+ ee:fa:17:d6:16:bb:5e:80:d5:89:45:58:7e:18:df:
+ 92:88:52:66:31:4d:7b:70:59
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ CA Issuers - URI:ldap://ldap.epki.go.kr:389/cn=GPKIRootCA,ou=GPKI,o=Government of Korea,c=KR
+
+ X509v3 Authority Key Identifier:
+ keyid:FA:72:04:03:99:FD:EA:DB:7C:50:DD:BE:E5:72:A4:D2:77:25:15:C8
+ DirName:/C=KR/O=Government of Korea/OU=GPKI/CN=GPKIRootCA
+ serial:47:FE:F6:00:02:07:86:D8:01:92:35:FF:9E:4A:20:02
+
+ X509v3 Subject Key Identifier:
+ B3:11:A0:4B:54:32:7E:40:C3:70:F9:D4:CB:A3:C4:23:E1:B6:35:8F
+ X509v3 Key Usage:
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:ldap://ldap.epki.go.kr:389/ou=dp1p20710,ou=CRL,ou=GPKI,o=Government of Korea,c=kr?certificateRevocationList
+
+ Netscape Cert Type:
+ SSL Client, SSL Server
+ Signature Algorithm: sha1WithRSAEncryption
+ 4a:9f:a9:b7:98:72:b2:0e:89:67:9a:2c:ab:ad:c9:bb:b0:00:
+ a7:f4:49:2d:7a:53:63:a1:5b:00:d1:5c:f1:90:40:61:07:e8:
+ 20:ea:b3:0e:3e:13:16:3a:8c:b5:4e:68:ed:17:26:e6:88:ac:
+ 99:30:69:c2:c0:67:30:21:35:2e:30:91:cb:15:c3:f3:00:16:
+ 5e:4a:47:e9:52:ba:e4:ac:6e:dc:c2:f1:95:f5:95:92:9d:75:
+ 48:c5:f1:72:88:ca:4c:34:ec:0f:7b:ac:c4:45:1a:6d:ab:bb:
+ 9b:01:30:d5:63:30:9a:4d:8d:3d:99:07:68:56:1a:95:59:f9:
+ 63:16:fe:a4:3e:12:eb:65:46:1d:7a:23:f1:06:7e:8c:b2:23:
+ b8:fd:16:eb:10:15:bc:4a:d1:fe:86:d8:f4:61:6a:e8:82:62:
+ aa:5b:73:bc:6c:d9:bf:2a:80:be:a9:f8:5c:4c:4e:8a:44:f3:
+ 8d:7f:79:f1:a8:17:a5:bd:40:1f:80:7f:33:3f:3b:4c:78:9d:
+ f1:40:ac:3f:2e:7b:d1:07:5e:74:7c:94:8f:ec:51:f7:76:fb:
+ a3:e6:9f:21:32:86:73:74:56:6a:a9:e9:a8:38:b8:2a:01:d4:
+ cb:80:31:83:51:72:17:f8:4f:b1:89:79:0f:17:47:51:e9:b6:
+ 02:62:84:5c
+
+-----BEGIN CERTIFICATE-----
+MIIEnDCCA4SgAwIBAgIEAP7AdzANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJLUjEcMBoGA1U
+ECgwTR292ZXJubWVudCBvZiBLb3JlYTENMAsGA1UECwwER1BLSTEUMBIGA1UEAwwLQ0ExMzQwND
+AwMDEwHhcNMTIwNTAyMDQ1ODU0WhcNMTQwNzIzMDI1OTU5WjB+MQswCQYDVQQGEwJLUjEcMBoGA
+1UECgwTR292ZXJubWVudCBvZiBLb3JlYTEYMBYGA1UECwwPR3JvdXAgb2YgU2VydmVyMR4wHAYD
+VQQLDBXqtZDsnKHqs7ztlZnquLDsiKDrtoAxFzAVBgNVBAMMDiouZGFlamluLm9yLmtyMIGfMA0
+GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDxPawemRFPRXuCMR/nh8yNjEoE5B9k7Msxlj0dHG0Gy0
+kDMXeq38eVk2xu3IC5yf5KdO5eFUaNnPDqbWu2RvMuZFA/XiLfmQoVfC8jqojzNtpYAymu0xMtr
+58DWKmeBybXEIp0VWxQr+76F9YWu16A1YlFWH4Y35KIUmYxTXtwWQIDAQABo4IB0jCCAc4wZwYI
+KwYBBQUHAQEEWzBZMFcGCCsGAQUFBzAChktsZGFwOi8vbGRhcC5lcGtpLmdvLmtyOjM4OS9jbj1
+HUEtJUm9vdENBLG91PUdQS0ksbz1Hb3Zlcm5tZW50IG9mIEtvcmVhLGM9S1IwgYYGA1UdIwR/MH
+2AFPpyBAOZ/erbfFDdvuVypNJ3JRXIoVOkUTBPMQswCQYDVQQGEwJLUjEcMBoGA1UECgwTR292Z
+XJubWVudCBvZiBLb3JlYTENMAsGA1UECwwER1BLSTETMBEGA1UEAwwKR1BLSVJvb3RDQYIQR/72
+AAIHhtgBkjX/nkogAjAdBgNVHQ4EFgQUsxGgS1QyfkDDcPnUy6PEI+G2NY8wCwYDVR0PBAQDAgW
+gMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB8BgNVHR8EdTBzMHGgb6BthmtsZGFwOi
+8vbGRhcC5lcGtpLmdvLmtyOjM4OS9vdT1kcDFwMjA3MTAsb3U9Q1JMLG91PUdQS0ksbz1Hb3Zlc
+m5tZW50IG9mIEtvcmVhLGM9a3I/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDARBglghkgBhvhC
+AQEEBAMCBsAwDQYJKoZIhvcNAQEFBQADggEBAEqfqbeYcrIOiWeaLKutybuwAKf0SS16U2OhWwD
+RXPGQQGEH6CDqsw4+ExY6jLVOaO0XJuaIrJkwacLAZzAhNS4wkcsVw/MAFl5KR+lSuuSsbtzC8Z
+X1lZKddUjF8XKIykw07A97rMRFGm2ru5sBMNVjMJpNjT2ZB2hWGpVZ+WMW/qQ+EutlRh16I/EGf
+oyyI7j9FusQFbxK0f6G2PRhauiCYqpbc7xs2b8qgL6p+FxMTopE841/efGoF6W9QB+AfzM/O0x4
+nfFArD8ue9EHXnR8lI/sUfd2+6PmnyEyhnN0Vmqp6ag4uCoB1MuAMYNRchf4T7GJeQ8XR1HptgJ
+ihFw=
+-----END CERTIFICATE-----
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 47:fe:f6:00:02:07:86:d8:01:92:35:ff:9e:4a:20:02
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=KR, O=Government of Korea, OU=GPKI, CN=GPKIRootCA
+ Validity
+ Not Before: Jun 9 14:09:21 2008 GMT
+ Not After : Jun 9 14:09:21 2018 GMT
+ Subject: C=KR, O=Government of Korea, OU=GPKI, CN=CA134040001
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2047 bit)
+ Modulus:
+ 66:f0:e5:31:3d:4f:c0:d8:44:91:e0:79:5a:fb:f2:
+ 0a:b4:17:7f:5d:1a:87:68:d6:34:3a:b7:03:ce:88:
+ 10:73:95:44:1d:ec:36:80:01:82:40:87:b9:ee:f4:
+ 8c:86:bf:10:8f:4f:46:97:68:a2:e3:d8:75:1f:83:
+ 24:f9:05:4b:d4:0b:8b:39:60:92:b3:c2:35:08:49:
+ aa:be:ef:b9:74:1d:fc:95:76:38:58:4a:86:ca:e5:
+ 22:b2:99:68:1d:45:53:49:dd:26:6c:de:cd:95:19:
+ 67:10:5f:b0:1c:fa:2c:08:d1:66:7e:04:54:f3:ea:
+ 41:8f:83:47:b7:d2:ae:08:7c:87:ac:86:3c:c8:4c:
+ b5:5f:1a:00:34:e9:32:42:e6:9d:f4:a3:60:92:ac:
+ 63:83:53:62:17:81:b1:74:3b:92:bd:9d:dc:22:b9:
+ 6b:b4:a7:dc:dc:de:e1:3b:c2:d3:90:f2:72:da:53:
+ 58:f2:4d:c8:53:b1:f0:08:72:8b:47:55:83:be:e6:
+ 34:dc:78:b8:f5:d0:86:58:a9:e2:7e:29:57:88:9b:
+ 2e:55:70:f8:ef:44:f7:fe:e5:50:31:b7:d7:21:ff:
+ c2:04:a5:e2:e9:30:71:08:c7:1d:72:36:75:a7:6f:
+ 3f:63:3a:de:d8:dd:1d:77:d9:54:70:47:63:72:20:
+ 2b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:16:67:32:F4:68:5E:68:31:47:DB:ED:EC:CE:61:2E:9A:24:46:C4:7D
+
+ X509v3 Subject Key Identifier:
+ FA:72:04:03:99:FD:EA:DB:7C:50:DD:BE:E5:72:A4:D2:77:25:15:C8
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Certificate Policies:
+ Policy: 1.2.410.100001.5.3.1.3
+ Policy: 1.2.410.100001.5.3.1.1
+ Policy: 1.2.410.100001.5.3.1.7
+ Policy: 1.2.410.100001.5.3.1.9
+ Policy: 1.2.410.100001.5.3.1.5
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:ldap://cen.dir.go.kr:389/cn=GPKIRootCA,ou=GPKI,o=Government of Korea,c=KR?authorityRevocationlist;binary
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 21:6a:06:b3:c6:d3:18:fa:9f:a2:d4:5f:ce:c8:92:74:93:06:
+ 54:f0:fa:ca:21:22:54:64:ca:41:c4:c6:99:a5:f0:b3:51:64:
+ a7:68:ef:47:6b:a4:8f:9e:a9:bc:80:4e:f5:64:95:7e:29:48:
+ fa:96:5e:98:2f:75:44:c5:a1:94:d9:83:e9:35:4c:db:a3:89:
+ 85:b9:33:f9:40:1a:3e:77:5f:2c:11:90:08:b0:a3:c0:1b:66:
+ 57:c3:5c:14:07:1e:75:8d:db:8c:05:61:98:a3:8d:c9:15:2f:
+ 97:3e:5a:f1:ad:85:0b:3e:86:e9:ae:e7:6b:a9:3b:7e:11:f7:
+ c6:fb:e8:5e:cb:5f:15:06:4f:e6:3e:e6:f2:a2:f1:65:31:9e:
+ f8:7a:c5:7d:e8:87:a7:26:f1:b1:30:d8:6c:4b:e5:3e:44:81:
+ 35:42:82:c3:b1:c2:6b:95:e9:e6:8d:cb:5b:a3:03:59:f2:9a:
+ bd:d4:c2:70:e9:5f:0e:1b:4c:3d:10:b5:50:32:df:7c:ba:27:
+ 73:53:67:f3:17:85:b4:5f:11:e2:22:56:41:b6:9e:a2:98:e6:
+ 71:43:ec:6d:0a:22:5d:d3:f4:bf:8e:91:28:1c:15:3d:64:42:
+ 6b:05:1a:25:44:c7:6f:7f:93:a1:da:a4:cb:7a:8c:19:53:5e:
+ d1:b4:2f:13
+-----BEGIN CERTIFICATE-----
+MIIEXjCCA0agAwIBAgIQR/72AAIHhtgBkjX/nkogAjANBgkqhkiG9w0BAQUFADBPMQswCQYDVQQ
+GEwJLUjEcMBoGA1UECgwTR292ZXJubWVudCBvZiBLb3JlYTENMAsGA1UECwwER1BLSTETMBEGA1
+UEAwwKR1BLSVJvb3RDQTAeFw0wODA2MDkxNDA5MjFaFw0xODA2MDkxNDA5MjFaMFAxCzAJBgNVB
+AYTAktSMRwwGgYDVQQKDBNHb3Zlcm5tZW50IG9mIEtvcmVhMQ0wCwYDVQQLDARHUEtJMRQwEgYD
+VQQDDAtDQTEzNDA0MDAwMTCCASEwDQYJKoZIhvcNAQEBBQADggEOADCCAQkCggEAZvDlMT1PwNh
+EkeB5WvvyCrQXf10ah2jWNDq3A86IEHOVRB3sNoABgkCHue70jIa/EI9PRpdoouPYdR+DJPkFS9
+QLizlgkrPCNQhJqr7vuXQd/JV2OFhKhsrlIrKZaB1FU0ndJmzezZUZZxBfsBz6LAjRZn4EVPPqQ
+Y+DR7fSrgh8h6yGPMhMtV8aADTpMkLmnfSjYJKsY4NTYheBsXQ7kr2d3CK5a7Sn3Nze4TvC05Dy
+ctpTWPJNyFOx8Ahyi0dVg77mNNx4uPXQhlip4n4pV4ibLlVw+O9E9/7lUDG31yH/wgSl4ukwcQj
+HHXI2dadvP2M63tjdHXfZVHBHY3IgKwIDAQABo4IBNDCCATAwHwYDVR0jBBgwFoAUFmcy9GheaD
+FH2+3szmEumiRGxH0wHQYDVR0OBBYEFPpyBAOZ/erbfFDdvuVypNJ3JRXIMA4GA1UdDwEB/wQEA
+wIBBjBPBgNVHSAESDBGMAwGCiqDGoaNIQUDAQMwDAYKKoMaho0hBQMBATAMBgoqgxqGjSEFAwEH
+MAwGCiqDGoaNIQUDAQkwDAYKKoMaho0hBQMBBTASBgNVHRMBAf8ECDAGAQH/AgEAMHkGA1UdHwR
+yMHAwbqBsoGqGaGxkYXA6Ly9jZW4uZGlyLmdvLmtyOjM4OS9jbj1HUEtJUm9vdENBLG91PUdQS0
+ksbz1Hb3Zlcm5tZW50IG9mIEtvcmVhLGM9S1I/YXV0aG9yaXR5UmV2b2NhdGlvbmxpc3Q7YmluY
+XJ5MA0GCSqGSIb3DQEBBQUAA4IBAQAhagazxtMY+p+i1F/OyJJ0kwZU8PrKISJUZMpBxMaZpfCz
+UWSnaO9Ha6SPnqm8gE71ZJV+KUj6ll6YL3VExaGU2YPpNUzbo4mFuTP5QBo+d18sEZAIsKPAG2Z
+Xw1wUBx51jduMBWGYo43JFS+XPlrxrYULPobprudrqTt+EffG++hey18VBk/mPubyovFlMZ74es
+V96IenJvGxMNhsS+U+RIE1QoLDscJrlenmjctbowNZ8pq91MJw6V8OG0w9ELVQMt98uidzU2fzF
+4W0XxHiIlZBtp6imOZxQ+xtCiJd0/S/jpEoHBU9ZEJrBRolRMdvf5Oh2qTLeowZU17RtC8T
+-----END CERTIFICATE-----
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 45:f8:e0:e4:01:c5:3e:71:e6:bd:71:6d:97:9c:41:23
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=KR, O=Government of Korea, OU=GPKI, CN=GPKIRootCA
+ Validity
+ Not Before: Mar 15 06:00:04 2007 GMT
+ Not After : Mar 15 06:00:04 2017 GMT
+ Subject: C=KR, O=Government of Korea, OU=GPKI, CN=GPKIRootCA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2047 bit)
+ Modulus:
+ 5a:2b:41:15:9b:db:76:26:01:f0:54:72:0b:87:13:
+ 1f:a0:d0:3f:96:aa:0d:b3:34:81:de:48:5a:9f:f3:
+ 70:5a:c2:f1:3a:9e:04:f0:4e:94:79:97:e1:f4:b5:
+ 14:4c:d7:6f:c4:8b:18:b7:dc:12:2b:1d:0a:9b:ee:
+ 20:0c:5b:8f:ff:f9:af:82:9e:98:46:d0:3d:5d:28:
+ f3:97:16:c1:5c:e5:56:bf:44:a4:00:a1:7a:cb:9b:
+ 7a:5b:dc:d4:ed:fb:f2:a0:02:67:00:1e:44:e5:8a:
+ 01:dc:a5:a3:4e:fe:d6:0c:67:ca:49:b9:f0:d0:a0:
+ f9:4d:1f:03:d3:86:ef:0d:85:75:4d:f3:ed:fb:cd:
+ 6a:66:04:57:f4:57:9b:ac:66:8a:4f:c2:a8:4f:71:
+ 89:09:dd:4c:00:df:96:bb:d5:90:0a:b4:b6:6a:6d:
+ c6:bf:d3:99:29:ff:62:f0:10:da:45:ac:09:72:0b:
+ 82:10:e8:15:a8:8b:5f:e2:a2:5a:79:1e:c2:67:fd:
+ e9:44:57:0b:03:d0:21:15:51:b0:00:f3:8f:6d:e2:
+ 23:f0:49:21:d9:6d:cf:62:3d:ec:eb:fd:28:92:01:
+ 3f:7a:a3:72:7c:eb:f3:ae:e7:f8:0a:ec:6e:ad:7a:
+ 9b:55:c9:30:4b:9c:b6:61:46:6b:58:1a:fe:9f:48:
+ 1d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:16:67:32:F4:68:5E:68:31:47:DB:ED:EC:CE:61:2E:9A:24:46:C4:7D
+
+ X509v3 Subject Key Identifier:
+ 16:67:32:F4:68:5E:68:31:47:DB:ED:EC:CE:61:2E:9A:24:46:C4:7D
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment, Key Agreement, Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha1WithRSAEncryption
+ 35:63:52:c6:60:18:1c:b7:c2:c1:5a:58:02:ec:07:d5:a1:90:
+ 93:fc:80:47:d0:52:78:ab:85:f8:76:d3:b8:b0:18:32:a0:b6:
+ 90:68:13:66:3d:6f:af:8e:dc:f6:a3:c4:ce:39:5f:af:ed:0a:
+ 66:e0:7c:11:c8:0c:cb:9e:1f:38:29:8a:8b:de:c8:63:2e:c7:
+ b4:d2:ce:36:91:94:e0:4f:84:92:b6:aa:22:a8:fd:31:a7:33:
+ 48:c9:5b:f6:13:d8:16:16:eb:1f:3f:a5:4e:06:93:3a:d9:06:
+ 65:30:96:fa:8d:06:db:a1:1a:f4:2b:fa:0f:68:f0:c1:2b:7c:
+ 9d:05:d7:09:42:3b:d2:2f:91:90:fc:0e:6b:38:5b:b2:75:a9:
+ 57:9c:57:64:f5:98:20:a4:ff:d4:30:04:e4:ce:1f:90:c9:2f:
+ c1:df:5a:56:b8:cb:aa:aa:b4:bf:eb:b8:f7:22:4a:4d:c1:35:
+ f4:65:bd:78:bc:6f:78:1b:56:3a:81:e8:0d:f5:c2:a5:17:30:
+ d3:8d:57:77:cb:a5:c1:4c:b1:30:dd:34:b8:ab:92:0a:22:02:
+ 36:8b:f6:6c:f7:61:b9:08:ee:30:ad:1a:a8:44:f1:2e:32:ec:
+ 83:a2:48:48:3a:67:5f:e9:6f:1b:17:33:08:2a:c1:c9:c3:67:
+ 9a:0e:85:67
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDijCCAnKgAwIBAgIQRfjg5AHFPnHmvXFtl5xBIzANBgkqhkiG9w0BAQUFADBPMQswCQYDVQQ
+GEwJLUjEcMBoGA1UEChMTR292ZXJubWVudCBvZiBLb3JlYTENMAsGA1UECxMER1BLSTETMBEGA1
+UEAxMKR1BLSVJvb3RDQTAeFw0wNzAzMTUwNjAwMDRaFw0xNzAzMTUwNjAwMDRaME8xCzAJBgNVB
+AYTAktSMRwwGgYDVQQKExNHb3Zlcm5tZW50IG9mIEtvcmVhMQ0wCwYDVQQLEwRHUEtJMRMwEQYD
+VQQDEwpHUEtJUm9vdENBMIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBaK0EVm9t2JgH
+wVHILhxMfoNA/lqoNszSB3khan/NwWsLxOp4E8E6UeZfh9LUUTNdvxIsYt9wSKx0Km+4gDFuP//
+mvgp6YRtA9XSjzlxbBXOVWv0SkAKF6y5t6W9zU7fvyoAJnAB5E5YoB3KWjTv7WDGfKSbnw0KD5T
+R8D04bvDYV1TfPt+81qZgRX9FebrGaKT8KoT3GJCd1MAN+Wu9WQCrS2am3Gv9OZKf9i8BDaRawJ
+cguCEOgVqItf4qJaeR7CZ/3pRFcLA9AhFVGwAPOPbeIj8Ekh2W3PYj3s6/0okgE/eqNyfOvzruf
+4CuxurXqbVckwS5y2YUZrWBr+n0gdAgMBAAGjYzBhMB8GA1UdIwQYMBaAFBZnMvRoXmgxR9vt7M
+5hLpokRsR9MB0GA1UdDgQWBBQWZzL0aF5oMUfb7ezOYS6aJEbEfTAOBgNVHQ8BAf8EBAMCAa4wD
+wYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEANWNSxmAYHLfCwVpYAuwH1aGQk/yA
+R9BSeKuF+HbTuLAYMqC2kGgTZj1vr47c9qPEzjlfr+0KZuB8EcgMy54fOCmKi97IYy7HtNLONpG
+U4E+EkraqIqj9MaczSMlb9hPYFhbrHz+lTgaTOtkGZTCW+o0G26Ea9Cv6D2jwwSt8nQXXCUI70i
++RkPwOazhbsnWpV5xXZPWYIKT/1DAE5M4fkMkvwd9aVrjLqqq0v+u49yJKTcE19GW9eLxveBtWO
+oHoDfXCpRcw041Xd8ulwUyxMN00uKuSCiICNov2bPdhuQjuMK0aqETxLjLsg6JISDpnX+lvGxcz
+CCrBycNnmg6FZw==
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTIwNTAyMDQ1ODU0Wg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
+
+
diff --git a/chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem b/chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem
new file mode 100644
index 00000000000..631061037a9
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem
@@ -0,0 +1,464 @@
+This is certificate chain where the issuer of the second certificate is not
+byte-for-byte equal to the subject of the third certificate.
+
+The names are equal when applying the comparison rules given in RFC 5280. The
+difference in byte values is due to encoding some components as UTF8String
+which were encoded in the other version as PrintableString.
+
+The verification should succeed.
+
+This certificate chain was obtained from the certificate transparency database.
+
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 966709257826132928 (0xd6a70f2b9cee3c0)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=Trend Micro Inc, CN=Trend Micro CA
+ Validity
+ Not Before: May 20 15:18:33 2013 GMT
+ Not After : May 21 15:18:33 2015 GMT
+ Subject: businessCategory=Business Entity/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=California/serialNumber=C1919248, C=US, ST=California, L=Cupertino, O=Trend Micro, Inc., CN=community.trendmicro.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:84:0a:28:77:d4:40:6b:62:00:de:5f:a7:da:
+ de:c0:83:bb:81:56:f1:a5:1f:7b:ea:23:e2:f0:53:
+ 96:b4:e4:c9:dd:68:06:5b:f4:d6:c8:de:d5:a8:21:
+ e5:c3:b5:fc:a7:04:7c:ef:1f:ac:1b:06:6d:f3:e5:
+ 36:2f:a8:ea:7c:2b:c9:cf:43:a7:f6:5f:15:be:7b:
+ cb:d8:35:14:39:6a:47:f2:9b:e8:c7:07:48:97:a3:
+ 02:67:8c:bf:97:f8:51:ec:8f:fd:3a:74:05:01:f9:
+ 7c:1b:85:25:e4:f2:66:8d:11:de:d5:f0:12:97:3f:
+ a1:8f:23:36:b3:71:bd:ac:1e:e7:8f:fb:89:11:36:
+ a7:bd:32:7f:44:9a:e9:8d:54:f2:85:06:d2:4f:d1:
+ 3f:4a:a0:e2:0f:35:16:5f:ac:7b:2e:7e:da:d5:77:
+ 72:64:88:ea:2e:1f:c1:f2:eb:81:17:b5:89:2f:22:
+ e7:fc:c1:2b:22:6f:b8:ac:29:e6:61:95:3f:3b:4d:
+ b4:03:5a:f5:44:cb:00:e3:1a:16:36:53:eb:33:7a:
+ 88:73:51:22:3a:03:c9:a6:01:bc:1e:07:a5:0f:d4:
+ a3:57:5f:ce:3d:19:59:e6:97:60:e5:5b:8d:0e:66:
+ 6d:e2:5e:6f:39:48:d4:69:77:5b:c2:08:bc:c9:55:
+ 82:09
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ CA Issuers - URI:http://ocsp.trendmicro.com/tmca.crt
+ OCSP - URI:http://ocsp.trendmicro.com/tmca
+
+ X509v3 Subject Key Identifier:
+ 58:E3:2D:66:53:0F:E5:F0:00:2C:A6:5E:CF:AD:D1:64:2D:1E:77:21
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Authority Key Identifier:
+ keyid:AD:31:C7:FA:02:CE:67:F7:65:1C:FB:BA:5F:C0:BB:C5:50:4C:67:C8
+
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.34697.2.2
+ Policy: 2.16.756.1.89.1.2.1.1
+ Policy: 1.3.6.1.4.1.34697.1.1
+ CPS: http://ssl.trendmicro.com/resources/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.trendmicro.com/crl/trendmicroca.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Subject Alternative Name:
+ DNS:community.trendmicro.com
+ Signature Algorithm: sha1WithRSAEncryption
+ a7:ec:1b:48:20:53:62:a8:6b:e5:b0:ae:7c:c5:5b:37:ec:59:
+ de:39:b7:ef:e0:64:26:85:94:2f:22:91:d3:91:c6:07:93:8e:
+ 23:ea:41:84:5b:90:c5:d2:32:1c:8b:d4:83:8c:0c:c9:7a:b2:
+ de:a8:b6:e9:de:06:50:5c:ef:f7:73:d1:5f:66:31:53:e0:80:
+ 14:c8:1c:dc:81:e4:fe:05:f1:88:b5:ff:24:58:48:c5:4c:f5:
+ 4f:1a:a6:dd:1a:43:b1:91:74:75:99:7a:c9:22:04:12:9d:6c:
+ ef:b2:05:60:f5:ec:15:84:81:aa:ee:0b:d9:ba:75:74:4f:f6:
+ fb:d0:a9:99:d8:d4:11:d6:a6:c6:79:64:cd:de:19:6e:92:89:
+ f4:85:d0:b3:dc:94:00:93:27:29:b5:dd:30:71:67:e7:c3:e2:
+ cb:9a:d1:d7:da:56:7b:f7:33:4b:2b:6c:52:ca:1b:7b:51:9c:
+ 6b:7a:d2:2f:38:a0:d2:e5:7c:cf:f4:34:f8:1c:d7:4b:80:bd:
+ 8a:c0:e9:7d:dd:85:86:5d:12:05:60:19:0d:ff:72:15:30:ba:
+ cf:c0:2e:a4:1a:a1:7f:73:85:9f:4a:4e:2c:a6:98:47:20:e5:
+ fc:29:09:ed:21:97:28:49:5d:a3:cc:03:f0:ca:e3:c6:e3:56:
+ 9b:22:fd:36
+
+-----BEGIN CERTIFICATE-----
+MIIFVjCCBD6gAwIBAgIIDWpw8rnO48AwDQYJKoZIhvcNAQEFBQAwQDELMAkGA1UEBhMCVVMxGDA
+WBgNVBAoMD1RyZW5kIE1pY3JvIEluYzEXMBUGA1UEAwwOVHJlbmQgTWljcm8gQ0EwHhcNMTMwNT
+IwMTUxODMzWhcNMTUwNTIxMTUxODMzWjCB1DEYMBYGA1UEDwwPQnVzaW5lc3MgRW50aXR5MRMwE
+QYLKwYBBAGCNzwCAQMMAlVTMRswGQYLKwYBBAGCNzwCAQIMCkNhbGlmb3JuaWExETAPBgNVBAUT
+CEMxOTE5MjQ4MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3V
+wZXJ0aW5vMRowGAYDVQQKDBFUcmVuZCBNaWNybywgSW5jLjEhMB8GA1UEAwwYY29tbXVuaXR5Ln
+RyZW5kbWljcm8uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv4QKKHfUQGtiA
+N5fp9rewIO7gVbxpR976iPi8FOWtOTJ3WgGW/TWyN7VqCHlw7X8pwR87x+sGwZt8+U2L6jqfCvJ
+z0On9l8VvnvL2DUUOWpH8pvoxwdIl6MCZ4y/l/hR7I/9OnQFAfl8G4Ul5PJmjRHe1fASlz+hjyM
+2s3G9rB7nj/uJETanvTJ/RJrpjVTyhQbST9E/SqDiDzUWX6x7Ln7a1XdyZIjqLh/B8uuBF7WJLy
+Ln/MErIm+4rCnmYZU/O020A1r1RMsA4xoWNlPrM3qIc1EiOgPJpgG8HgelD9SjV1/OPRlZ5pdg5
+VuNDmZt4l5vOUjUaXdbwgi8yVWCCQIDAQABo4IBvTCCAbkwbAYIKwYBBQUHAQEEYDBeMC8GCCsG
+AQUFBzAChiNodHRwOi8vb2NzcC50cmVuZG1pY3JvLmNvbS90bWNhLmNydDArBggrBgEFBQcwAYY
+faHR0cDovL29jc3AudHJlbmRtaWNyby5jb20vdG1jYTAdBgNVHQ4EFgQUWOMtZlMP5fAALKZez6
+3RZC0edyEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBStMcf6As5n92Uc+7pfwLvFUExnyDBmB
+gNVHSAEXzBdMAwGCisGAQQBgo8JAgIwCwYJYIV0AVkBAgEBMEAGCisGAQQBgo8JAQEwMjAwBggr
+BgEFBQcCARYkaHR0cDovL3NzbC50cmVuZG1pY3JvLmNvbS9yZXNvdXJjZXMvMD8GA1UdHwQ4MDY
+wNKAyoDCGLmh0dHA6Ly9jcmwudHJlbmRtaWNyby5jb20vY3JsL3RyZW5kbWljcm9jYS5jcmwwDg
+YDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAjBgNVHREEHDAag
+hhjb21tdW5pdHkudHJlbmRtaWNyby5jb20wDQYJKoZIhvcNAQEFBQADggEBAKfsG0ggU2Koa+Ww
+rnzFWzfsWd45t+/gZCaFlC8ikdORxgeTjiPqQYRbkMXSMhyL1IOMDMl6st6otuneBlBc7/dz0V9
+mMVPggBTIHNyB5P4F8Yi1/yRYSMVM9U8apt0aQ7GRdHWZeskiBBKdbO+yBWD17BWEgaruC9m6dX
+RP9vvQqZnY1BHWpsZ5ZM3eGW6SifSF0LPclACTJym13TBxZ+fD4sua0dfaVnv3M0srbFLKG3tRn
+Gt60i84oNLlfM/0NPgc10uAvYrA6X3dhYZdEgVgGQ3/chUwus/ALqQaoX9zhZ9KTiymmEcg5fwp
+Ce0hlyhJXaPMA/DK48bjVpsi/TY=
+-----END CERTIFICATE-----
+
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 6555005306879019608 (0x5af80e98c1530a58)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=AffirmTrust, CN=AffirmTrust Networking
+ Validity
+ Not Before: Oct 22 19:14:42 2011 GMT
+ Not After : Dec 31 14:08:24 2030 GMT
+ Subject: C=US, O=Trend Micro Inc, CN=Trend Micro CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c2:b7:3e:ea:50:16:fa:d4:31:c5:60:36:d1:8f:
+ af:67:8a:49:3f:e2:c6:d0:e7:73:67:3d:2a:ce:04:
+ 91:17:dc:4e:7d:30:03:e8:10:ef:db:89:8c:e8:30:
+ 5e:00:dd:47:41:2f:36:6c:46:9e:12:60:96:74:5b:
+ 26:f2:bd:a1:31:b3:d1:47:10:27:e9:71:7a:21:38:
+ 23:e4:1b:bb:b5:44:2e:04:b5:48:0c:8f:0d:e5:36:
+ fb:b7:80:3b:f2:8b:9b:ad:71:d2:88:e2:e3:b0:22:
+ 48:43:f2:86:e3:2a:ec:d2:95:4e:08:69:48:ec:4d:
+ a7:88:44:e2:90:1e:db:64:0c:cc:3b:77:c1:e1:39:
+ 1c:b7:42:74:d2:20:29:59:de:18:16:0c:96:59:1c:
+ ec:84:db:18:46:85:dc:86:fc:a7:cd:97:0f:ee:5e:
+ d2:7d:03:9f:d8:50:f1:e9:e1:d0:df:ad:05:76:3d:
+ 4a:fe:75:38:2c:dc:12:21:f6:be:dd:46:78:25:6b:
+ 80:6a:6e:f3:5a:1f:c6:30:dd:f1:49:f0:3a:98:d7:
+ 5f:09:1f:91:92:43:74:50:c0:7a:73:d9:fd:f8:9f:
+ 4c:b6:3d:34:8c:2d:09:4c:50:2d:a2:44:13:9d:f1:
+ d8:56:25:ee:51:19:b2:9f:bd:e1:d7:0d:f0:60:a9:
+ d0:41
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ AD:31:C7:FA:02:CE:67:F7:65:1C:FB:BA:5F:C0:BB:C5:50:4C:67:C8
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Authority Key Identifier:
+ keyid:07:1F:D2:E7:9C:DA:C2:6E:A2:40:B4:B0:7A:50:10:50:74:C4:C8:BD
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.affirmtrust.com/resources/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.affirmtrust.com/crl/AffirmTrustNetworking.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Signature Algorithm: sha1WithRSAEncryption
+ b3:f0:b1:7c:b3:8b:9e:a1:a6:68:bf:4f:df:85:53:c9:96:6f:
+ 1f:97:22:1a:ff:3c:4a:c5:1e:cf:2b:6e:8b:5c:96:d5:ed:9e:
+ 02:2f:fe:d7:b6:9d:33:56:dc:c0:78:58:6e:0f:5d:58:4a:41:
+ ba:04:eb:c1:0e:fa:33:b7:8a:c7:94:bb:8e:8f:f4:7e:20:8d:
+ 74:b0:11:b8:47:76:75:89:45:1e:5d:52:c8:e5:ee:0b:d1:12:
+ fc:bd:bd:4f:34:18:21:51:61:7b:fb:75:b8:19:ef:c2:7c:78:
+ e7:a3:55:79:23:6f:77:93:ce:68:b6:98:e0:ab:43:20:26:ca:
+ f5:ea:87:bd:be:38:ce:91:74:99:68:6d:7e:35:7b:21:c1:aa:
+ 85:6c:31:48:ef:43:91:08:fd:07:98:a0:03:3c:01:a6:fb:eb:
+ 25:ea:15:62:b3:52:3d:7d:6a:3d:72:89:ec:89:84:53:1e:cd:
+ 9a:73:47:ff:6c:0b:b9:97:20:df:dc:e4:84:b5:c6:98:9a:f3:
+ 2e:cf:02:38:05:9e:f1:4e:63:db:c7:4a:45:37:e7:64:a5:2f:
+ 15:d9:53:b5:6c:84:eb:90:a0:64:5b:a2:ea:95:5c:83:63:c6:
+ a5:ed:0e:1e:6b:2f:21:48:52:5b:44:13:73:c8:f8:fe:a1:aa:
+ d9:eb:d1:df
+
+-----BEGIN CERTIFICATE-----
+MIIEATCCAumgAwIBAgIIWvgOmMFTClgwDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDA
+SBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDT
+ExMTAyMjE5MTQ0MloXDTMwMTIzMTE0MDgyNFowQDELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1RyZ
+W5kIE1pY3JvIEluYzEXMBUGA1UEAwwOVHJlbmQgTWljcm8gQ0EwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDCtz7qUBb61DHFYDbRj69nikk/4sbQ53NnPSrOBJEX3E59MAPoEO/biYz
+oMF4A3UdBLzZsRp4SYJZ0WybyvaExs9FHECfpcXohOCPkG7u1RC4EtUgMjw3lNvu3gDvyi5utcd
+KI4uOwIkhD8objKuzSlU4IaUjsTaeIROKQHttkDMw7d8HhORy3QnTSIClZ3hgWDJZZHOyE2xhGh
+dyG/KfNlw/uXtJ9A5/YUPHp4dDfrQV2PUr+dTgs3BIh9r7dRngla4BqbvNaH8Yw3fFJ8DqY118J
+H5GSQ3RQwHpz2f34n0y2PTSMLQlMUC2iRBOd8dhWJe5RGbKfveHXDfBgqdBBAgMBAAGjgfowgfc
+wHQYDVR0OBBYEFK0xx/oCzmf3ZRz7ul/Au8VQTGfIMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBB
+gwFoAUBx/S55zawm6iQLSwelAQUHTEyL0wSQYDVR0gBEIwQDA+BgRVHSAAMDYwNAYIKwYBBQUHA
+gEWKGh0dHA6Ly93d3cuYWZmaXJtdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwSQYDVR0fBEIwQDA+
+oDygOoY4aHR0cDovL2NybC5hZmZpcm10cnVzdC5jb20vY3JsL0FmZmlybVRydXN0TmV0d29ya2l
+uZy5jcmwwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCz8LF8s4ueoaZov0/fhV
+PJlm8flyIa/zxKxR7PK26LXJbV7Z4CL/7Xtp0zVtzAeFhuD11YSkG6BOvBDvozt4rHlLuOj/R+I
+I10sBG4R3Z1iUUeXVLI5e4L0RL8vb1PNBghUWF7+3W4Ge/CfHjno1V5I293k85otpjgq0MgJsr1
+6oe9vjjOkXSZaG1+NXshwaqFbDFI70ORCP0HmKADPAGm++sl6hVis1I9fWo9consiYRTHs2ac0f
+/bAu5lyDf3OSEtcaYmvMuzwI4BZ7xTmPbx0pFN+dkpS8V2VO1bITrkKBkW6LqlVyDY8al7Q4eay
+8hSFJbRBNzyPj+oarZ69Hf
+-----END CERTIFICATE-----
+
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 84:3c:74:b1:aa:34:86:b1:c4:c7:a0:df:55:b5:e9
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2
+ Validity
+ Not Before: Dec 1 12:00:00 2009 GMT
+ Not After : Nov 1 12:00:00 2019 GMT
+ Subject: C=US, O=AffirmTrust, CN=AffirmTrust Networking
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b4:84:cc:33:17:2e:6b:94:6c:6b:61:52:a0:eb:
+ a3:cf:79:94:4c:e5:94:80:99:cb:55:64:44:65:8f:
+ 67:64:e2:06:e3:5c:37:49:f6:2f:9b:84:84:1e:2d:
+ f2:60:9d:30:4e:cc:84:85:e2:2c:cf:1e:9e:fe:36:
+ ab:33:77:35:44:d8:35:96:1a:3d:36:e8:7a:0e:d8:
+ d5:47:a1:6a:69:8b:d9:fc:bb:3a:ae:79:5a:d5:f4:
+ d6:71:bb:9a:90:23:6b:9a:b7:88:74:87:0c:1e:5f:
+ b9:9e:2d:fa:ab:53:2b:dc:bb:76:3e:93:4c:08:08:
+ 8c:1e:a2:23:1c:d4:6a:ad:22:ba:99:01:2e:6d:65:
+ cb:be:24:66:55:24:4b:40:44:b1:1b:d7:e1:c2:85:
+ c0:de:10:3f:3d:ed:b8:fc:f1:f1:23:53:dc:bf:65:
+ 97:6f:d9:f9:40:71:8d:7d:bd:95:d4:ce:be:a0:5e:
+ 27:23:de:fd:a6:d0:26:0e:00:29:eb:3c:46:f0:3d:
+ 60:bf:3f:50:d2:dc:26:41:51:9e:14:37:42:04:a3:
+ 70:57:a8:1b:87:ed:2d:fa:7b:ee:8c:0a:e3:a9:66:
+ 89:19:cb:41:f9:dd:44:36:61:cf:e2:77:46:c8:7d:
+ f6:f4:92:81:36:fd:db:34:f1:72:7e:f3:0c:16:bd:
+ b4:15
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ 07:1F:D2:E7:9C:DA:C2:6E:A2:40:B4:B0:7A:50:10:50:74:C4:C8:BD
+ X509v3 Authority Key Identifier:
+ keyid:5B:25:7B:96:A4:65:51:7E:B8:39:F3:C0:78:66:5E:E8:3A:E7:F0:EE
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.swisssign.net/5B257B96A465517EB839F3C078665EE83AE7F0EE
+
+ Full Name:
+ URI:ldap://directory.swisssign.net/CN=5B257B96A465517EB839F3C078665EE83AE7F0EE%2CO=SwissSign%2CC=CH?certificateRevocationList?base?objectClass=cRLDistributionPoint
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.affirmtrust.com/resources/cps
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 72:7a:80:2b:d3:9b:96:58:44:bb:91:8c:ed:b8:af:cc:0f:4d:
+ 8b:a9:52:c0:99:85:ce:e7:a4:9f:67:45:00:df:91:4a:ff:67:
+ 00:ff:88:de:06:6b:26:ce:ff:65:aa:8e:c2:e1:b5:d7:c4:3e:
+ 4e:a2:2e:2c:85:32:52:be:f1:0c:2e:e6:e3:10:b3:a4:99:3c:
+ 4d:8d:64:89:a6:c6:d3:61:b8:91:61:2a:e1:1a:f4:94:34:8b:
+ dd:39:cd:db:a3:cf:93:c2:27:58:13:2c:8d:98:64:d1:6f:6c:
+ 7d:4c:40:19:5c:9a:7e:21:9f:bb:68:de:bb:46:52:a4:52:ad:
+ c1:83:50:06:0f:06:50:56:53:13:ec:06:c2:81:ed:bf:e9:72:
+ 5b:e6:04:83:5b:2c:48:90:1a:8c:08:c3:93:9d:18:b7:28:5d:
+ 0d:68:eb:32:c8:4b:81:2a:4b:dd:76:56:ce:2f:f7:85:38:29:
+ 27:ac:68:9b:89:2f:8b:92:7e:8e:7f:e1:72:9e:5f:f1:15:73:
+ c2:70:a0:60:a1:3d:77:d5:5d:6e:78:20:48:66:4a:e8:bb:89:
+ 6f:0d:aa:49:e5:ce:31:e3:63:c1:ec:42:97:16:bc:c0:55:dc:
+ 6c:dd:c7:de:59:5a:52:a8:92:e7:13:75:67:7a:8e:ef:65:60:
+ 4c:44:73:1e:d5:c4:12:da:52:c6:e2:ae:84:af:67:ff:e7:9c:
+ 66:b8:bc:ca:b4:b2:f6:b8:07:14:fb:b4:c3:a6:a2:9b:52:f8:
+ b1:48:70:64:a4:65:ca:e5:17:fa:7a:56:ea:57:3f:72:02:da:
+ ca:64:3a:4f:dd:a0:b0:5d:50:14:35:14:70:4f:55:d8:c9:9f:
+ f5:b2:63:65:81:42:dc:ad:f1:e5:60:bd:56:f2:2c:e9:eb:49:
+ 1a:7d:de:f3:14:ff:cf:c7:bd:94:90:99:0a:3a:17:a7:5c:aa:
+ 06:21:4b:9b:cc:25:77:99:37:91:d3:7a:7b:15:e1:da:1f:84:
+ ae:35:23:ef:f0:f5:aa:95:09:84:38:e6:97:da:b1:c9:3d:a3:
+ d4:3b:42:0d:14:71:4f:b2:d7:b7:3e:13:5c:85:36:73:88:2d:
+ d0:a3:1f:4c:3c:11:bd:3b:10:95:da:2b:c4:b0:19:a3:cd:20:
+ 66:e6:62:c9:4d:ff:96:bd:93:76:dd:2f:86:4a:70:3d:f9:46:
+ 32:27:3e:d8:c4:25:e8:55:22:37:76:75:2c:cc:d1:12:06:39:
+ 02:5a:bb:ec:40:67:41:1f:8d:39:7d:f5:ed:64:1c:bc:89:96:
+ 29:d8:d4:13:b1:d1:42:88:8d:7b:79:ea:17:4d:5d:3e:ad:fd:
+ 8f:02:fa:d3:f1:4d:3d:23
+
+-----BEGIN CERTIFICATE-----
+MIIFxzCCA6+gAwIBAgIQAIQ8dLGqNIaxxMeg31W16TANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQ
+GEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQS
+AtIEcyMB4XDTA5MTIwMTEyMDAwMFoXDTE5MTEwMTEyMDAwMFowRDELMAkGA1UEBhMCVVMxFDASB
+gNVBAoTC0FmZmlybVRydXN0MR8wHQYDVQQDExZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9
+nZOIG41w3SfYvm4SEHi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rn
+la1fTWcbuakCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQ
+ESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q
+0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr2
+0FQIDAQABo4IBsjCCAa4wDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUBx/S55zawm6iQLSwel
+AQUHTEyL0wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn8O4wDgYDVR0PAQH/BAQDAgEGM
+IH/BgNVHR8EgfcwgfQwR6BFoEOGQWh0dHA6Ly9jcmwuc3dpc3NzaWduLm5ldC81QjI1N0I5NkE0
+NjU1MTdFQjgzOUYzQzA3ODY2NUVFODNBRTdGMEVFMIGooIGloIGihoGfbGRhcDovL2RpcmVjdG9
+yeS5zd2lzc3NpZ24ubmV0L0NOPTVCMjU3Qjk2QTQ2NTUxN0VCODM5RjNDMDc4NjY1RUU4M0FFN0
+YwRUUlMkNPPVN3aXNzU2lnbiUyQ0M9Q0g/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdD9iYXNlP
+29iamVjdENsYXNzPWNSTERpc3RyaWJ1dGlvblBvaW50MEkGA1UdIARCMEAwPgYEVR0gADA2MDQG
+CCsGAQUFBwIBFihodHRwOi8vd3d3LmFmZmlybXRydXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSq
+GSIb3DQEBBQUAA4ICAQByeoAr05uWWES7kYztuK/MD02LqVLAmYXO56SfZ0UA35FK/2cA/4jeBm
+smzv9lqo7C4bXXxD5Ooi4shTJSvvEMLubjELOkmTxNjWSJpsbTYbiRYSrhGvSUNIvdOc3bo8+Tw
+idYEyyNmGTRb2x9TEAZXJp+IZ+7aN67RlKkUq3Bg1AGDwZQVlMT7AbCge2/6XJb5gSDWyxIkBqM
+CMOTnRi3KF0NaOsyyEuBKkvddlbOL/eFOCknrGibiS+Lkn6Of+Fynl/xFXPCcKBgoT131V1ueCB
+IZkrou4lvDapJ5c4x42PB7EKXFrzAVdxs3cfeWVpSqJLnE3Vneo7vZWBMRHMe1cQS2lLG4q6Er2
+f/55xmuLzKtLL2uAcU+7TDpqKbUvixSHBkpGXK5Rf6elbqVz9yAtrKZDpP3aCwXVAUNRRwT1XYy
+Z/1smNlgULcrfHlYL1W8izp60kafd7zFP/Px72UkJkKOhenXKoGIUubzCV3mTeR03p7FeHaH4Su
+NSPv8PWqlQmEOOaX2rHJPaPUO0INFHFPste3PhNchTZziC3Qox9MPBG9OxCV2ivEsBmjzSBm5mL
+JTf+WvZN23S+GSnA9+UYyJz7YxCXoVSI3dnUszNESBjkCWrvsQGdBH405ffXtZBy8iZYp2NQTsd
+FCiI17eeoXTV0+rf2PAvrT8U09Iw==
+-----END CERTIFICATE-----
+
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 13492815561806991280 (0xbb401c43f55e4fb0)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2
+ Validity
+ Not Before: Oct 25 08:30:35 2006 GMT
+ Not After : Oct 25 08:30:35 2036 GMT
+ Subject: C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:af:e4:ee:7e:8b:24:0e:12:6e:a9:50:2d:16:44:
+ 3b:92:92:5c:ca:b8:5d:84:92:42:13:2a:bc:65:57:
+ 82:40:3e:57:24:cd:50:8b:25:2a:b7:6f:fc:ef:a2:
+ d0:c0:1f:02:24:4a:13:96:8f:23:13:e6:28:58:00:
+ a3:47:c7:06:a7:84:23:2b:bb:bd:96:2b:7f:55:cc:
+ 8b:c1:57:1f:0e:62:65:0f:dd:3d:56:8a:73:da:ae:
+ 7e:6d:ba:81:1c:7e:42:8c:20:35:d9:43:4d:84:fa:
+ 84:db:52:2c:f3:0e:27:77:0b:6b:bf:11:2f:72:78:
+ 9f:2e:d8:3e:e6:18:37:5a:2a:72:f9:da:62:90:92:
+ 95:ca:1f:9c:e9:b3:3c:2b:cb:f3:01:13:bf:5a:cf:
+ c1:b5:0a:60:bd:dd:b5:99:64:53:b8:a0:96:b3:6f:
+ e2:26:77:91:8c:e0:62:10:02:9f:34:0f:a4:d5:92:
+ 33:51:de:be:8d:ba:84:7a:60:3c:6a:db:9f:2b:ec:
+ de:de:01:3f:6e:4d:e5:50:86:cb:b4:af:ed:44:40:
+ c5:ca:5a:8c:da:d2:2b:7c:a8:ee:be:a6:e5:0a:aa:
+ 0e:a5:df:05:52:b7:55:c7:22:5d:32:6a:97:97:63:
+ 13:db:c9:db:79:36:7b:85:3a:4a:c5:52:89:f9:24:
+ e7:9d:77:a9:82:ff:55:1c:a5:71:69:2b:d1:02:24:
+ f2:b3:26:d4:6b:da:04:55:e5:c1:0a:c7:6d:30:37:
+ 90:2a:e4:9e:14:33:5e:16:17:55:c5:5b:b5:cb:34:
+ 89:92:f1:9d:26:8f:a1:07:d4:c6:b2:78:50:db:0c:
+ 0c:0b:7c:0b:8c:41:d7:b9:e9:dd:8c:88:f7:a3:4d:
+ b2:32:cc:d8:17:da:cd:b7:ce:66:9d:d4:fd:5e:ff:
+ bd:97:3e:29:75:e7:7e:a7:62:58:af:25:34:a5:41:
+ c7:3d:bc:0d:50:ca:03:03:0f:08:5a:1f:95:73:78:
+ 62:bf:af:72:14:69:0e:a5:e5:03:0e:78:8e:26:28:
+ 42:f0:07:0b:62:20:10:67:39:46:fa:a9:03:cc:04:
+ 38:7a:66:ef:20:83:b5:8c:4a:56:8e:91:00:fc:8e:
+ 5c:82:de:88:a0:c3:e2:68:6e:7d:8d:ef:3c:dd:65:
+ f4:5d:ac:51:ef:24:80:ae:aa:56:97:6f:f9:ad:7d:
+ da:61:3f:98:77:3c:a5:91:b6:1c:8c:26:da:65:a2:
+ 09:6d:c1:e2:54:e3:b9:ca:4c:4c:80:8f:77:7b:60:
+ 9a:1e:df:b6:f2:48:1e:0e:ba:4e:54:6d:98:e0:e1:
+ a2:1a:a2:77:50:cf:c4:63:92:ec:47:19:9d:eb:e6:
+ 6b:ce:c1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ 5B:25:7B:96:A4:65:51:7E:B8:39:F3:C0:78:66:5E:E8:3A:E7:F0:EE
+ X509v3 Authority Key Identifier:
+ keyid:5B:25:7B:96:A4:65:51:7E:B8:39:F3:C0:78:66:5E:E8:3A:E7:F0:EE
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.756.1.89.1.2.1.1
+ CPS: http://repository.swisssign.com/
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 27:ba:e3:94:7c:f1:ae:c0:de:17:e6:e5:d8:d5:f5:54:b0:83:
+ f4:bb:cd:5e:05:7b:4f:9f:75:66:af:3c:e8:56:7e:fc:72:78:
+ 38:03:d9:2b:62:1b:00:b9:f8:e9:60:cd:cc:ce:51:8a:c7:50:
+ 31:6e:e1:4a:7e:18:2f:69:59:b6:3d:64:81:2b:e3:83:84:e6:
+ 22:87:8e:7d:e0:ee:02:99:61:b8:1e:f4:b8:2b:88:12:16:84:
+ c2:31:93:38:96:31:a6:b9:3b:53:3f:c3:24:93:56:5b:69:92:
+ ec:c5:c1:bb:38:00:e3:ec:17:a9:b8:dc:c7:7c:01:83:9f:32:
+ 47:ba:52:22:34:1d:32:7a:09:56:a7:7c:25:36:a9:3d:4b:da:
+ c0:82:6f:0a:bb:12:c8:87:4b:27:11:f9:1e:2d:c7:93:3f:9e:
+ db:5f:26:6b:52:d9:2e:8a:f1:14:c6:44:8d:15:a9:b7:bf:bd:
+ de:a6:1a:ee:ae:2d:fb:48:77:17:fe:bb:ec:af:18:f5:2a:51:
+ f0:39:84:97:95:6c:6e:1b:c3:2b:c4:74:60:79:25:b0:0a:27:
+ df:df:5e:d2:39:cf:45:7d:42:4b:df:b3:2c:1e:c5:c6:5d:ca:
+ 55:3a:a0:9c:69:9a:8f:da:ef:b2:b0:3c:9f:87:6c:12:2b:65:
+ 70:15:52:31:1a:24:cf:6f:31:23:50:1f:8c:4f:8f:23:c3:74:
+ 41:63:1c:55:a8:14:dd:3e:e0:51:50:cf:f1:1b:30:56:0e:92:
+ b0:82:85:d8:83:cb:22:64:bc:2d:b8:25:d5:54:a2:b8:06:ea:
+ ad:92:a4:24:a0:c1:86:b5:4a:13:6a:47:cf:2e:0b:56:95:54:
+ cb:ce:9a:db:6a:b4:a6:b2:db:41:08:86:27:77:f7:6a:a0:42:
+ 6c:0b:38:ce:d7:75:50:32:92:c2:df:2b:30:22:48:d0:d5:41:
+ 38:25:5d:a4:e9:5d:9f:c6:94:75:d0:45:fd:30:97:43:8f:90:
+ ab:0a:c7:86:73:60:4a:69:2d:de:a5:78:d7:06:da:6a:9e:4b:
+ 3e:77:3a:20:13:22:01:d0:bf:68:9e:63:60:6b:35:4d:0b:6d:
+ ba:a1:3d:c0:93:e0:7f:23:b3:55:ad:72:25:4e:46:f9:d2:16:
+ ef:b0:64:c1:01:9e:e9:ca:a0:6a:98:0e:cf:d8:60:f2:2f:49:
+ b8:e4:42:e1:38:35:16:f4:c8:6e:4f:f7:81:56:e8:ba:a3:be:
+ 23:af:ae:fd:6f:03:e0:02:3b:30:76:fa:1b:6d:41:cf:01:b1:
+ e9:b8:c9:66:f4:db:26:f3:3a:a4:74:f2:49:24:5b:c9:b0:d0:
+ 57:c1:fa:3e:7a:e1:97:c9
+
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRU
+wEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHh
+cNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU
+3dpc3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG
+9w0BAQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1
+QiyUqt2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bb
+qBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/W
+s/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbL
+tK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9
+VHKVxaSvRAiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3
+wLjEHXuendjIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc
+3hiv69yFGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59
+je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kg
+eDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDw
+YDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwF
+oAUWyV7lqRlUX64OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEF
+BQcCARYgaHR0cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggI
+BACe645R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUD
+Fu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFw
+bs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS
+2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V
+9QkvfsywexcZdylU6oJxpmo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4F
+FQz/EbMFYOkrCChdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIh
+id392qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG
+2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPI
+vSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0F
+fB+j564ZfJ
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTMwNTIwMTUxODMzWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
+
+
diff --git a/chromium/net/data/verify_certificate_chain_unittest/openssl_conf.py b/chromium/net/data/verify_certificate_chain_unittest/openssl_conf.py
new file mode 100755
index 00000000000..fe1838d6638
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/openssl_conf.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""This file contains helpers for representing, manipulating, and writing
+OpenSSL configuration files [1]
+
+Configuration files are simply a collection of name=value "properties", which
+are grouped into "sections".
+
+[1] https://www.openssl.org/docs/manmaster/apps/config.html
+"""
+
+class Property(object):
+ """Represents a key/value pair in OpenSSL .cnf files.
+
+ Names and values are not quoted in any way, so callers need to pass the text
+ exactly as it should be written to the file (leading and trailing whitespace
+ doesn't matter).
+
+ For instance:
+ baseConstraints = critical, CA:false
+
+ Could be represented by a Property where:
+ name = 'baseConstraints'
+ value = 'critical, CA:false'
+ """
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+
+ def write_to(self, out):
+ """Outputs this property to .cnf file."""
+ out.write('%s = %s\n' % (self.name, self.value))
+
+
+class Section(object):
+ """Represents a section in OpenSSL. For instance:
+ [CA_root]
+ preserve = true
+
+ Could be represented by a Section where:
+ name = 'CA_root'
+ properties = [Property('preserve', 'true')]
+ """
+ def __init__(self, name):
+ self.name = name
+ self.properties = []
+
+
+ def ensure_property_name_not_duplicated(self, name):
+ """Raises an exception of there is more than 1 property named |name|."""
+ count = 0
+ for prop in self.properties:
+ if prop.name == name:
+ count += 1
+ if count > 1:
+ raise Exception('Duplicate property: %s' % (name))
+
+
+ def set_property(self, name, value):
+ """Replaces, adds, or removes a Property from the Section:
+
+ - If |value| is None, then this is equivalent to calling
+ remove_property(name)
+ - If there is an existing property matching |name| then its value is
+ replaced with |value|
+ - If there are no properties matching |name| then a new one is added at
+ the end of the section
+
+ It is expected that there is AT MOST 1 property with the given name. If
+ that is not the case then this function will raise an error."""
+
+ if value is None:
+ self.remove_property(name)
+ return
+
+ self.ensure_property_name_not_duplicated(name)
+
+ for prop in self.properties:
+ if prop.name == name:
+ prop.value = value
+ return
+
+ self.add_property(name, value)
+
+
+ def add_property(self, name, value):
+ """Adds a property (allows duplicates)"""
+ self.properties.append(Property(name, value))
+
+
+ def remove_property(self, name):
+ """Removes the property with the indicated name, if it exists.
+
+ It is expected that there is AT MOST 1 property with the given name. If
+ that is not the case then this function will raise an error."""
+ self.ensure_property_name_not_duplicated(name)
+
+ for i in range(len(self.properties)):
+ if self.properties[i].name == name:
+ self.properties.pop(i)
+ return
+
+
+ def write_to(self, out):
+ """Outputs the section in the format used by .cnf files"""
+ out.write('[%s]\n' % (self.name))
+ for prop in self.properties:
+ prop.write_to(out)
+ out.write('\n')
+
+
+class Config(object):
+ """Represents a .cnf (configuration) file in OpenSSL"""
+ def __init__(self):
+ self.sections = []
+
+
+ def get_section(self, name):
+ """Gets or creates a section with the given name."""
+ for section in self.sections:
+ if section.name == name:
+ return section
+ new_section = Section(name)
+ self.sections.append(new_section)
+ return new_section
+
+
+ def write_to_file(self, path):
+ """Outputs the Config to a .cnf files."""
+ with open(path, 'w') as out:
+ for section in self.sections:
+ section.write_to(out)
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-and-intermediary.pem b/chromium/net/data/verify_certificate_chain_unittest/target-and-intermediary.pem
new file mode 100644
index 00000000000..51446abd1fc
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-and-intermediary.pem
@@ -0,0 +1,280 @@
+[Created by: generate-target-and-intermediary.py]
+
+Certificate chain with 1 intermediary and a trusted root. Verification is
+expected to succeed.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:dc:50:a0:d0:af:3b:b6:d5:af:48:be:31:08:db:
+ 91:81:c5:c8:d7:22:88:d4:74:1e:12:de:7a:79:79:
+ 10:71:de:b5:8a:4e:d1:1d:46:6b:46:62:e8:de:f8:
+ 01:f5:9d:6b:35:f6:a6:b7:f2:7f:4c:5f:f9:ad:10:
+ f6:7e:9c:87:dc:27:e5:3f:19:1c:f0:c5:69:06:51:
+ 96:bf:d0:c5:ef:b8:e3:2c:47:6a:8f:44:68:70:ed:
+ 18:b9:f1:85:7b:2e:42:bc:44:5d:e3:d3:df:95:93:
+ 8c:1d:ad:bc:9e:45:ad:6e:4f:78:68:6e:8f:ee:16:
+ a9:6e:9d:50:6b:9c:72:a0:d7:fe:ff:68:4b:1c:df:
+ 18:fd:26:fb:65:be:c9:63:30:30:15:7d:f9:83:95:
+ c4:5e:2e:e5:d1:f0:ce:9c:5e:4a:6c:ec:6f:26:f6:
+ 79:38:bc:15:e2:50:68:f0:46:c2:7f:7d:0a:c2:79:
+ 08:b7:ea:41:18:d5:65:29:3e:6d:bb:80:8e:a2:0d:
+ c3:c4:8a:e2:dd:3c:19:01:e9:ea:0c:bb:db:6c:c7:
+ ed:6d:c5:7e:78:5f:5d:e2:87:d9:fa:90:3a:1d:c3:
+ b6:d8:7f:78:77:7b:e8:2c:bb:ed:04:18:72:a7:0f:
+ b2:ef:96:65:b4:39:a0:e9:59:b3:64:f4:db:9d:53:
+ 42:9f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 86:F0:37:63:2C:67:7D:F8:D4:71:4D:9B:A3:47:47:BA:F5:F0:0E:90
+ X509v3 Authority Key Identifier:
+ keyid:42:1A:C3:C4:D6:79:39:E2:20:E5:63:13:EB:41:7B:8C:0E:28:72:8E
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 4e:86:be:e0:4b:d5:15:99:49:09:6c:9a:6d:9a:82:e2:41:3e:
+ 99:a5:e3:23:dd:43:d7:22:8d:c6:4f:4c:51:47:cb:32:44:b8:
+ 3a:f0:b6:88:0c:fd:08:d1:ea:0d:b0:72:fe:a0:48:6b:5d:a2:
+ 9e:f2:2d:12:6a:bf:68:ce:2e:d0:35:5f:da:32:c9:74:4b:29:
+ 53:81:69:a1:a1:1a:de:c8:5e:c1:73:21:b6:02:81:d8:57:ef:
+ 68:c3:24:f7:05:fa:ae:ed:d7:8a:62:e3:09:bf:fc:d0:41:93:
+ e8:12:a5:fc:c3:46:d8:2b:f6:e3:cc:36:a7:39:cd:32:9e:9d:
+ e1:79:68:ff:15:b9:10:5f:86:ad:4d:a0:dc:60:2f:1f:36:6f:
+ d3:7a:60:81:c5:38:71:d0:fa:28:ae:ba:80:0e:cf:9c:ef:4d:
+ 1f:d4:0c:27:0f:55:a8:49:65:c1:d6:af:6d:b1:1d:fb:90:38:
+ ad:8b:5e:ba:82:68:60:2a:e4:7a:b8:07:aa:91:37:84:d6:18:
+ 38:ba:37:a6:d9:bb:3b:45:da:59:8c:c5:90:11:1d:85:fe:af:
+ fa:62:87:84:5d:5a:90:91:c3:6c:53:e1:d3:74:e7:51:19:b6:
+ b5:e7:12:1a:73:35:34:16:dd:e4:31:62:58:de:3a:fb:40:80:
+ 21:4f:f5:13
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDcUKDQ
+rzu21a9IvjEI25GBxcjXIojUdB4S3np5eRBx3rWKTtEdRmtGYuje+AH1nWs19qa3
+8n9MX/mtEPZ+nIfcJ+U/GRzwxWkGUZa/0MXvuOMsR2qPRGhw7Ri58YV7LkK8RF3j
+09+Vk4wdrbyeRa1uT3hobo/uFqlunVBrnHKg1/7/aEsc3xj9JvtlvsljMDAVffmD
+lcReLuXR8M6cXkps7G8m9nk4vBXiUGjwRsJ/fQrCeQi36kEY1WUpPm27gI6iDcPE
+iuLdPBkB6eoMu9tsx+1txX54X13ih9n6kDodw7bYf3h3e+gsu+0EGHKnD7LvlmW0
+OaDpWbNk9NudU0KfAgMBAAGjgekwgeYwHQYDVR0OBBYEFIbwN2MsZ3341HFNm6NH
+R7r18A6QMB8GA1UdIwQYMBaAFEIaw8TWeTniIOVjE+tBe4wOKHKOMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAToa+4EvVFZlJCWyabZqC
+4kE+maXjI91D1yKNxk9MUUfLMkS4OvC2iAz9CNHqDbBy/qBIa12invItEmq/aM4u
+0DVf2jLJdEspU4FpoaEa3shewXMhtgKB2FfvaMMk9wX6ru3XimLjCb/80EGT6BKl
+/MNG2Cv248w2pznNMp6d4Xlo/xW5EF+GrU2g3GAvHzZv03pggcU4cdD6KK66gA7P
+nO9NH9QMJw9VqEllwdavbbEd+5A4rYteuoJoYCrkergHqpE3hNYYOLo3ptm7O0Xa
+WYzFkBEdhf6v+mKHhF1akJHDbFPh03TnURm2tecSGnM1NBbd5DFiWN46+0CAIU/1
+Ew==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a4:16:0d:45:92:8b:7b:8e:42:07:a1:f4:01:dc:
+ 31:0e:68:b4:3f:f3:b7:0d:8f:08:f4:f0:bb:2b:45:
+ 37:98:b4:3b:6f:61:7c:23:2e:6e:cf:33:a3:d1:09:
+ 16:74:3f:ac:4f:59:f1:92:42:35:e6:8a:e9:98:5e:
+ 39:a2:0d:45:26:8f:7d:bb:ad:bf:f8:66:a3:b0:eb:
+ 7f:eb:79:60:9a:70:03:5d:9f:46:a8:47:64:7d:a9:
+ eb:a7:7d:77:60:3a:f5:5f:e8:bc:54:f3:d7:25:5e:
+ 5b:62:3a:4a:df:f3:21:df:e4:bc:89:69:26:fa:d7:
+ 24:16:f1:06:d0:57:a1:a0:aa:f2:bd:9f:0c:59:50:
+ 57:c2:5d:25:24:05:eb:91:58:bb:1a:82:df:eb:03:
+ ec:55:ed:d4:46:b5:fe:2e:fa:08:14:d7:76:71:99:
+ 2b:34:10:2d:20:21:ed:78:91:f9:05:04:14:42:a0:
+ ed:95:46:a3:a2:e6:55:1e:87:0b:1b:57:8e:e4:7c:
+ c5:c5:39:83:b1:c6:91:e1:54:8a:6f:6a:9b:a5:80:
+ 93:ec:00:81:6f:20:70:6c:31:95:42:76:a3:82:17:
+ d8:d2:ff:3a:09:53:be:76:ea:e1:a9:fb:a9:a5:5f:
+ 2b:5f:f9:5a:78:97:2e:f9:9d:31:42:2a:f9:1c:26:
+ 16:7d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 42:1A:C3:C4:D6:79:39:E2:20:E5:63:13:EB:41:7B:8C:0E:28:72:8E
+ X509v3 Authority Key Identifier:
+ keyid:FE:3F:EE:E8:53:09:31:CA:D4:66:C1:C7:FE:E0:74:C3:D7:81:44:5F
+
+ 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
+ af:11:72:82:33:e5:f9:b1:10:fc:c2:4a:9e:c8:8e:b4:16:51:
+ 62:8d:b5:e3:e3:c7:30:32:52:52:55:aa:6b:c4:c2:67:de:71:
+ 37:2d:85:68:80:c8:b7:9b:4b:05:6f:97:e1:82:03:f4:b7:07:
+ b8:c2:a8:02:7a:60:34:c8:07:9b:7e:c3:02:bd:11:26:51:b4:
+ 4d:e2:6c:e4:38:bc:4c:e7:35:91:24:f1:40:6e:69:7f:ac:b4:
+ ee:12:8a:1c:41:f6:96:13:93:67:c4:11:18:67:80:e6:41:ef:
+ 2b:3e:47:1a:57:b1:66:ac:87:93:ed:6c:fe:a2:c4:5a:47:75:
+ d0:1b:01:b6:74:b6:f8:7b:aa:e3:91:c3:45:56:2b:a4:d2:67:
+ 94:18:71:e7:ea:41:14:bb:12:4e:56:d8:5a:95:89:bc:e6:89:
+ be:9a:03:8c:b8:2b:18:56:7c:41:db:2d:e3:86:b5:de:aa:cb:
+ 11:da:91:8f:f2:75:1d:d2:b6:0b:bd:d6:b5:65:a5:96:1a:44:
+ fd:66:80:89:bf:a5:a9:c4:fb:3f:2b:cc:f5:e7:a6:e6:bd:5f:
+ e3:df:51:76:e3:e8:1c:e5:53:e9:6e:cf:e8:54:5f:f3:7f:ca:
+ 3a:b2:b2:07:7d:6c:29:a9:01:17:cf:f9:e8:0a:13:88:13:d3:
+ ad:ac:be:ad
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApBYNRZKL
+e45CB6H0AdwxDmi0P/O3DY8I9PC7K0U3mLQ7b2F8Iy5uzzOj0QkWdD+sT1nxkkI1
+5orpmF45og1FJo99u62/+GajsOt/63lgmnADXZ9GqEdkfanrp313YDr1X+i8VPPX
+JV5bYjpK3/Mh3+S8iWkm+tckFvEG0FehoKryvZ8MWVBXwl0lJAXrkVi7GoLf6wPs
+Ve3URrX+LvoIFNd2cZkrNBAtICHteJH5BQQUQqDtlUajouZVHocLG1eO5HzFxTmD
+scaR4VSKb2qbpYCT7ACBbyBwbDGVQnajghfY0v86CVO+durhqfuppV8rX/laeJcu
++Z0xQir5HCYWfQIDAQABo4HLMIHIMB0GA1UdDgQWBBRCGsPE1nk54iDlYxPrQXuM
+DihyjjAfBgNVHSMEGDAWgBT+P+7oUwkxytRmwcf+4HTD14FEXzA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AK8RcoIz5fmxEPzCSp7IjrQWUWKNtePjxzAyUlJVqmvEwmfecTcthWiAyLebSwVv
+l+GCA/S3B7jCqAJ6YDTIB5t+wwK9ESZRtE3ibOQ4vEznNZEk8UBuaX+stO4SihxB
+9pYTk2fEERhngOZB7ys+RxpXsWash5PtbP6ixFpHddAbAbZ0tvh7quORw0VWK6TS
+Z5QYcefqQRS7Ek5W2FqVibzmib6aA4y4KxhWfEHbLeOGtd6qyxHakY/ydR3Stgu9
+1rVlpZYaRP1mgIm/panE+z8rzPXnpua9X+PfUXbj6BzlU+luz+hUX/N/yjqysgd9
+bCmpARfP+egKE4gT062svq0=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ea:28:d6:83:e1:ad:7f:df:9a:70:91:b6:2a:45:
+ 28:bb:1a:00:d2:1f:0c:6e:14:10:27:c0:65:c9:90:
+ 40:45:83:6c:af:9a:66:ed:cb:59:2f:f7:82:67:74:
+ aa:1d:73:ec:f3:98:cb:38:9c:f6:6b:4f:bc:6b:5d:
+ f7:15:89:ed:02:f8:ed:17:69:df:a2:8d:ee:f5:d1:
+ 84:92:42:b8:9f:fe:77:fd:d5:06:7b:6f:59:8a:2a:
+ c7:32:f5:ff:ad:f9:8a:59:e7:93:11:79:fe:f6:2a:
+ cb:99:db:a9:d7:05:a8:be:af:db:2e:b1:8a:56:8e:
+ f7:ec:b4:b0:a3:a4:96:39:79:69:3c:3b:ce:fe:42:
+ 15:a8:56:bb:88:94:42:a5:0b:04:b4:e9:fa:c9:1a:
+ 14:7d:c0:82:d5:d8:3a:de:ec:6f:a6:be:5c:43:6d:
+ 85:f8:84:57:cd:06:b0:e1:63:a5:ab:05:14:2f:2d:
+ fb:04:99:fb:7e:ce:06:cf:3b:29:27:7a:70:1a:6b:
+ fb:6a:f3:a6:23:31:dd:93:80:67:b9:09:03:92:e2:
+ a9:c4:71:85:1b:a5:f9:1c:ff:86:b0:72:e3:23:58:
+ 15:6c:4e:55:7f:89:91:35:0a:b3:41:ba:3c:17:76:
+ da:e6:39:6e:58:92:67:9d:06:c5:c8:84:e0:61:49:
+ ea:b3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ FE:3F:EE:E8:53:09:31:CA:D4:66:C1:C7:FE:E0:74:C3:D7:81:44:5F
+ X509v3 Authority Key Identifier:
+ keyid:FE:3F:EE:E8:53:09:31:CA:D4:66:C1:C7:FE:E0:74:C3:D7:81:44:5F
+
+ 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
+ 9f:ae:51:c1:f5:31:bf:30:6c:e1:b5:38:07:b5:c2:56:38:6b:
+ 3c:f3:49:50:93:5f:75:9e:94:15:5c:15:0a:91:87:6a:c1:fa:
+ 36:d6:4a:72:6f:cd:8c:9d:77:e7:61:96:14:88:4f:b2:71:d7:
+ 81:8f:06:9f:c7:14:49:0c:de:7c:73:ba:00:c8:44:58:ac:0a:
+ 4b:27:bb:3d:cb:fd:4d:14:dd:f7:61:b7:a0:f4:00:8a:ff:54:
+ 6b:c0:6a:6d:21:43:b8:9b:cb:f9:ad:9d:fe:2a:09:3d:a1:dd:
+ de:17:7d:6f:74:44:79:0c:12:4e:d0:68:4f:b2:35:60:ef:95:
+ da:a5:25:f8:e4:4c:ea:83:38:c1:26:83:db:13:78:58:1c:50:
+ e3:20:93:b0:c8:5e:a0:76:5f:c2:fe:cc:16:3d:f6:2f:33:08:
+ fe:61:af:57:cd:c6:ae:8a:d2:7b:98:e8:eb:98:9b:89:ff:47:
+ 24:d6:bf:a3:29:f6:e3:7e:e2:08:0b:a6:06:11:36:07:ea:61:
+ 5f:58:16:d3:c1:29:b4:c8:39:7c:32:98:17:82:e7:8c:0f:2e:
+ 34:bc:a3:78:62:15:29:95:4e:ca:c4:40:8b:29:2e:5c:8c:9b:
+ 14:ee:90:68:08:91:ef:64:fe:8f:61:89:cd:6b:44:dd:24:cf:
+ 7c:3d:a3:86
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOoo1oPhrX/fmnCRtipF
+KLsaANIfDG4UECfAZcmQQEWDbK+aZu3LWS/3gmd0qh1z7POYyzic9mtPvGtd9xWJ
+7QL47Rdp36KN7vXRhJJCuJ/+d/3VBntvWYoqxzL1/635ilnnkxF5/vYqy5nbqdcF
+qL6v2y6xilaO9+y0sKOkljl5aTw7zv5CFahWu4iUQqULBLTp+skaFH3AgtXYOt7s
+b6a+XENthfiEV80GsOFjpasFFC8t+wSZ+37OBs87KSd6cBpr+2rzpiMx3ZOAZ7kJ
+A5LiqcRxhRul+Rz/hrBy4yNYFWxOVX+JkTUKs0G6PBd22uY5bliSZ50GxciE4GFJ
+6rMCAwEAAaOByzCByDAdBgNVHQ4EFgQU/j/u6FMJMcrUZsHH/uB0w9eBRF8wHwYD
+VR0jBBgwFoAU/j/u6FMJMcrUZsHH/uB0w9eBRF8wNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCfrlHB9TG/
+MGzhtTgHtcJWOGs880lQk191npQVXBUKkYdqwfo21kpyb82MnXfnYZYUiE+ycdeB
+jwafxxRJDN58c7oAyERYrApLJ7s9y/1NFN33Ybeg9ACK/1RrwGptIUO4m8v5rZ3+
+Kgk9od3eF31vdER5DBJO0GhPsjVg75XapSX45EzqgzjBJoPbE3hYHFDjIJOwyF6g
+dl/C/swWPfYvMwj+Ya9XzcauitJ7mOjrmJuJ/0ck1r+jKfbjfuIIC6YGETYH6mFf
+WBbTwSm0yDl8MpgXgueMDy40vKN4YhUplU7KxECLKS5cjJsU7pBoCJHvZP6PYYnN
+a0TdJM98PaOG
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem b/chromium/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem
new file mode 100644
index 00000000000..f008c4e8727
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem
@@ -0,0 +1,282 @@
+[Created by: ./generate-target-has-keycertsign-but-not-ca.py]
+
+Certificate chain with 1 intermediary, a trusted root, and a target
+certificate that is not a CA, and yet has the keyCertSign bit set. Verification
+is expected to fail, since keyCertSign should only be asserted when CA is
+true.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a6:ec:9f:55:56:11:c4:7a:fc:00:75:b9:b4:bb:
+ 08:8f:8f:88:ad:df:22:e4:5d:b4:f1:7d:af:a4:62:
+ df:64:86:46:34:cb:a4:32:21:b0:53:7c:94:5e:8a:
+ e6:6d:56:8b:28:93:23:79:ef:0b:7f:96:5a:19:09:
+ 3a:b7:30:77:e3:db:54:a5:c0:f7:df:3c:bd:f5:26:
+ 9f:ab:73:f9:c5:02:e8:67:cf:4d:d5:0e:31:4d:ab:
+ b7:d5:55:1a:f2:dc:1a:87:45:61:3c:ea:56:19:a3:
+ a7:f7:34:82:30:6f:48:54:fd:ce:05:cc:fe:95:2b:
+ a3:d8:b5:8f:20:26:60:e9:22:07:2e:e3:54:22:fe:
+ e2:2e:fc:33:2b:9d:6d:ed:1f:56:6d:7b:4a:69:15:
+ c0:f3:d5:0a:f8:c2:9b:82:b0:91:36:7c:5a:06:6b:
+ eb:02:85:58:5c:15:14:c4:c9:72:8c:21:29:29:e7:
+ 23:ca:56:07:7e:28:fa:f0:99:69:ad:10:bc:6c:43:
+ 31:1c:d1:bc:79:51:dd:92:54:f9:f3:0c:f8:ee:a4:
+ 8a:96:1d:17:ef:70:64:71:f4:30:54:b5:77:53:26:
+ 11:80:ce:dc:cb:38:98:98:69:20:e1:ae:f7:1b:61:
+ 53:32:59:27:8d:e9:84:b8:6f:c1:9f:03:95:ac:9a:
+ 8c:35
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 64:67:70:1F:EA:D4:3D:30:5E:54:D3:BF:DF:83:3D:14:94:C3:DD:58
+ X509v3 Authority Key Identifier:
+ keyid:F3:98:98:C6:42:9E:AB:03:53:76:3F:43:FB:C9:9D:E4:0B:FF:BF:B5
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment, Certificate Sign
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 65:55:d3:04:1b:96:89:b8:44:32:01:15:ee:43:85:c0:c9:ee:
+ f9:19:6c:ef:f4:5a:92:22:b2:62:b1:18:38:c5:42:06:e5:c7:
+ be:83:9c:96:6b:72:d7:2a:0c:68:40:d6:30:91:4b:4e:e1:d4:
+ 13:05:c5:5a:91:c1:11:ce:57:2e:31:87:2a:f3:70:e4:77:3a:
+ 60:82:fa:58:56:18:1f:bf:4a:dd:89:48:c6:ab:4c:01:06:d5:
+ ec:8d:aa:55:eb:07:0f:bd:bd:2b:67:f6:3f:43:15:c7:a4:77:
+ 88:fa:f8:9f:3b:fa:0b:a2:fe:55:7c:f1:0b:49:da:b7:08:24:
+ 34:68:db:a8:76:37:60:02:be:32:54:29:b4:b7:69:c4:05:66:
+ 60:a4:86:9f:a1:13:d7:c3:f6:ed:a0:97:37:17:35:97:05:c9:
+ ce:f9:af:e0:42:c3:e5:32:15:d7:1e:6c:3b:41:93:df:ba:b0:
+ aa:60:e8:66:46:55:b3:00:65:e2:1c:70:85:c7:81:21:3f:8e:
+ 41:69:19:a0:ac:8b:54:bc:d0:4b:78:db:f8:11:d7:93:eb:a4:
+ 48:04:1b:76:96:e2:ae:d5:2b:dd:ea:e4:a5:02:ca:02:86:11:
+ 82:cc:3c:70:10:3a:35:81:0e:52:ad:71:11:be:d9:f2:9c:3f:
+ 85:53:b8:df
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCm7J9V
+VhHEevwAdbm0uwiPj4it3yLkXbTxfa+kYt9khkY0y6QyIbBTfJReiuZtVosokyN5
+7wt/lloZCTq3MHfj21SlwPffPL31Jp+rc/nFAuhnz03VDjFNq7fVVRry3BqHRWE8
+6lYZo6f3NIIwb0hU/c4FzP6VK6PYtY8gJmDpIgcu41Qi/uIu/DMrnW3tH1Zte0pp
+FcDz1Qr4wpuCsJE2fFoGa+sChVhcFRTEyXKMISkp5yPKVgd+KPrwmWmtELxsQzEc
+0bx5Ud2SVPnzDPjupIqWHRfvcGRx9DBUtXdTJhGAztzLOJiYaSDhrvcbYVMyWSeN
+6YS4b8GfA5Wsmow1AgMBAAGjgekwgeYwHQYDVR0OBBYEFGRncB/q1D0wXlTTv9+D
+PRSUw91YMB8GA1UdIwQYMBaAFPOYmMZCnqsDU3Y/Q/vJneQL/7+1MD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAZVXTBBuWibhEMgEV7kOF
+wMnu+Rls7/RakiKyYrEYOMVCBuXHvoOclmty1yoMaEDWMJFLTuHUEwXFWpHBEc5X
+LjGHKvNw5Hc6YIL6WFYYH79K3YlIxqtMAQbV7I2qVesHD729K2f2P0MVx6R3iPr4
+nzv6C6L+VXzxC0natwgkNGjbqHY3YAK+MlQptLdpxAVmYKSGn6ET18P27aCXNxc1
+lwXJzvmv4ELD5TIV1x5sO0GT37qwqmDoZkZVswBl4hxwhceBIT+OQWkZoKyLVLzQ
+S3jb+BHXk+ukSAQbdpbirtUr3erkpQLKAoYRgsw8cBA6NYEOUq1xEb7Z8pw/hVO4
+3w==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a8:d0:63:48:13:03:82:fe:27:31:f5:c0:25:67:
+ 0e:46:56:3b:d0:db:01:06:88:ae:64:12:2a:b3:8f:
+ 79:c1:20:87:75:e7:11:2d:97:09:b4:55:e6:c4:14:
+ 7e:61:4e:98:6c:1d:dc:ec:2c:ef:16:40:99:d1:29:
+ dd:0d:74:77:c7:f9:2f:5f:bd:55:63:35:3c:a2:36:
+ e1:42:12:49:a1:83:0b:7b:53:f1:9d:53:02:97:3e:
+ cf:27:50:2e:41:63:3a:6f:c2:b0:2a:b6:f9:bd:bb:
+ d8:0a:42:0d:99:e5:5a:ea:c8:26:bc:54:6f:b6:36:
+ d2:28:d4:d6:53:b5:f6:0e:8d:dd:e0:46:98:32:61:
+ 42:20:ee:44:f0:a1:06:e4:9e:8c:c3:b6:cd:1b:7e:
+ ef:3c:68:d6:80:5e:49:b4:66:3f:2a:5c:e1:c3:fd:
+ 43:ce:b7:c7:ec:fa:1f:1d:94:e4:21:4e:51:5f:5d:
+ 5a:fd:3f:84:a5:15:2a:64:2c:d5:70:4f:24:dd:96:
+ 67:43:c6:1d:62:53:ed:2f:ef:64:8c:a9:b2:c3:c7:
+ f3:a2:55:08:ed:dc:2a:5f:51:50:05:59:e8:e2:0e:
+ cf:8d:06:5b:7b:19:56:b9:3b:dc:75:ce:b0:4e:74:
+ 62:d7:31:a4:7b:1f:44:ca:3f:79:8d:5c:b7:41:a6:
+ c0:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ F3:98:98:C6:42:9E:AB:03:53:76:3F:43:FB:C9:9D:E4:0B:FF:BF:B5
+ X509v3 Authority Key Identifier:
+ keyid:97:E9:16:F3:C4:AD:14:F3:56:CD:F3:E6:E5:60:D4:8F:EF:F7:BA:06
+
+ 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
+ 05:1f:e8:41:f2:76:1f:cd:2a:92:f9:cc:61:a9:6f:14:40:12:
+ 69:19:1c:44:1d:3e:2e:c5:d0:a8:25:e3:bc:62:a3:6c:0f:e8:
+ b9:dc:b0:92:cd:7a:ae:1d:4e:de:cc:90:3f:97:98:d4:d4:b0:
+ a2:73:f7:b4:83:94:fb:ac:83:d3:39:af:13:64:61:bd:80:8d:
+ dc:de:af:50:1a:15:12:c2:99:04:d4:c6:b8:31:12:2c:15:0a:
+ 7c:13:ad:c8:be:37:fb:fa:43:ae:70:fd:64:70:a8:fb:77:fd:
+ 09:7e:7e:e1:ff:27:e6:91:d8:c4:62:54:ad:cd:04:51:b0:da:
+ 09:df:99:ac:91:0b:f8:31:e3:2e:18:64:f4:76:55:dd:d9:b3:
+ 90:3a:07:91:e5:89:f7:83:48:15:5d:b3:bb:76:e6:d6:4a:1f:
+ 3b:a4:3e:89:36:de:a8:80:09:2c:1f:23:a7:8a:cb:c3:e7:46:
+ f3:f3:1e:0f:8b:88:bb:a9:87:9e:a7:64:2e:64:be:48:c1:91:
+ d2:ef:c1:82:b9:1a:f4:08:d9:b1:a0:1f:ff:16:af:c4:b2:bc:
+ 01:0f:e4:a0:f0:eb:81:aa:37:32:70:61:16:52:01:f6:39:10:
+ a3:b0:8c:ec:2c:3f:ac:1b:cd:12:91:44:2f:6a:2e:4f:d4:8d:
+ 92:a5:55:1b
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqNBjSBMD
+gv4nMfXAJWcORlY70NsBBoiuZBIqs495wSCHdecRLZcJtFXmxBR+YU6YbB3c7Czv
+FkCZ0SndDXR3x/kvX71VYzU8ojbhQhJJoYMLe1PxnVMClz7PJ1AuQWM6b8KwKrb5
+vbvYCkINmeVa6sgmvFRvtjbSKNTWU7X2Do3d4EaYMmFCIO5E8KEG5J6Mw7bNG37v
+PGjWgF5JtGY/Klzhw/1DzrfH7PofHZTkIU5RX11a/T+EpRUqZCzVcE8k3ZZnQ8Yd
+YlPtL+9kjKmyw8fzolUI7dwqX1FQBVno4g7PjQZbexlWuTvcdc6wTnRi1zGkex9E
+yj95jVy3QabAvwIDAQABo4HLMIHIMB0GA1UdDgQWBBTzmJjGQp6rA1N2P0P7yZ3k
+C/+/tTAfBgNVHSMEGDAWgBSX6RbzxK0U81bN8+blYNSP7/e6BjA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AAUf6EHydh/NKpL5zGGpbxRAEmkZHEQdPi7F0Kgl47xio2wP6LncsJLNeq4dTt7M
+kD+XmNTUsKJz97SDlPusg9M5rxNkYb2Ajdzer1AaFRLCmQTUxrgxEiwVCnwTrci+
+N/v6Q65w/WRwqPt3/Ql+fuH/J+aR2MRiVK3NBFGw2gnfmayRC/gx4y4YZPR2Vd3Z
+s5A6B5HlifeDSBVds7t25tZKHzukPok23qiACSwfI6eKy8PnRvPzHg+LiLuph56n
+ZC5kvkjBkdLvwYK5GvQI2bGgH/8Wr8SyvAEP5KDw64GqNzJwYRZSAfY5EKOwjOws
+P6wbzRKRRC9qLk/UjZKlVRs=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ba:52:6a:89:3e:75:9b:d6:ed:f4:d1:1c:fb:aa:
+ 99:8f:5e:89:59:2a:75:5a:54:77:9c:b5:91:d5:2a:
+ f8:8a:a3:74:d2:75:39:24:cc:c5:f7:42:83:11:a7:
+ 6c:cd:c2:2b:e1:18:84:b6:26:d8:12:fd:e2:a8:6a:
+ 4d:4d:8f:a1:25:07:08:d2:73:a0:17:c7:54:11:a5:
+ fb:0e:36:cd:e2:24:a8:dc:85:a1:22:a2:7c:c3:20:
+ 02:60:ec:40:ba:1e:5b:03:51:68:d7:f2:28:f6:3d:
+ 3f:b3:30:34:0e:33:6c:44:c4:31:a9:ee:cf:42:96:
+ c2:eb:06:52:92:86:80:b9:0b:99:41:4b:64:aa:b7:
+ 55:2b:21:25:92:46:1d:e2:31:3d:0b:54:ad:a9:c7:
+ 2a:29:be:5c:bb:ba:99:59:69:70:71:75:bb:9a:a1:
+ 7c:fa:36:79:bd:b4:f3:6c:4b:6c:c9:ea:32:03:dd:
+ 64:9e:94:82:33:d1:d9:f8:48:04:ae:79:35:5c:a4:
+ 43:54:c1:ec:3c:97:bf:3a:40:f6:e6:9d:7b:bf:a1:
+ 67:b0:59:de:78:ff:33:94:f2:2b:15:d0:0a:89:0c:
+ 2c:ee:9f:dc:f8:48:f0:68:0c:19:59:86:86:41:1c:
+ 19:02:89:4f:0c:ea:43:b2:a8:b9:c9:c1:1d:76:c0:
+ 3d:19
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 97:E9:16:F3:C4:AD:14:F3:56:CD:F3:E6:E5:60:D4:8F:EF:F7:BA:06
+ X509v3 Authority Key Identifier:
+ keyid:97:E9:16:F3:C4:AD:14:F3:56:CD:F3:E6:E5:60:D4:8F:EF:F7:BA:06
+
+ 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
+ a5:32:dc:be:9a:58:7d:66:69:99:07:13:d9:ec:20:99:72:37:
+ c1:8b:4d:e1:8e:79:0b:7f:ed:1c:89:a1:9b:18:66:bd:1b:fe:
+ ec:74:f6:aa:7b:57:71:06:07:ea:02:41:6e:83:b4:68:39:15:
+ c8:c5:16:d7:4e:10:75:f5:05:b4:f2:c6:e4:bd:b4:64:21:16:
+ c8:14:dd:06:88:f7:81:89:76:44:c8:70:99:70:f2:67:e6:4c:
+ 72:3e:75:24:d7:2f:83:b2:4e:6b:f8:4d:f0:e7:16:25:02:16:
+ c3:fa:8a:9c:c2:75:60:6b:ed:40:1d:b2:14:97:6a:26:a1:72:
+ b9:53:f1:95:fb:6e:d9:11:b3:d4:67:ff:ba:0a:06:c3:5b:fb:
+ 84:e7:b1:48:07:fb:db:d7:6f:c9:7e:6f:e6:b4:3b:8c:e0:3c:
+ 73:fe:80:8e:cd:35:3c:4f:51:f8:ac:fc:b4:d0:0a:5e:b9:d7:
+ 95:f2:e6:fb:a8:de:25:ab:20:da:d5:e6:e2:d3:5b:6b:9b:db:
+ 2c:77:0e:59:01:7a:29:07:1f:53:72:2b:f3:06:86:1b:04:a0:
+ 01:82:aa:59:4f:a5:e6:8b:2a:01:24:8b:77:5b:bb:8d:36:94:
+ 4a:02:ab:61:5c:0a:ba:87:ee:53:53:a7:5d:e3:6a:bc:73:9f:
+ fe:e9:fc:9f
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpSaok+dZvW7fTRHPuq
+mY9eiVkqdVpUd5y1kdUq+IqjdNJ1OSTMxfdCgxGnbM3CK+EYhLYm2BL94qhqTU2P
+oSUHCNJzoBfHVBGl+w42zeIkqNyFoSKifMMgAmDsQLoeWwNRaNfyKPY9P7MwNA4z
+bETEManuz0KWwusGUpKGgLkLmUFLZKq3VSshJZJGHeIxPQtUranHKim+XLu6mVlp
+cHF1u5qhfPo2eb2082xLbMnqMgPdZJ6UgjPR2fhIBK55NVykQ1TB7DyXvzpA9uad
+e7+hZ7BZ3nj/M5TyKxXQCokMLO6f3PhI8GgMGVmGhkEcGQKJTwzqQ7KoucnBHXbA
+PRkCAwEAAaOByzCByDAdBgNVHQ4EFgQUl+kW88StFPNWzfPm5WDUj+/3ugYwHwYD
+VR0jBBgwFoAUl+kW88StFPNWzfPm5WDUj+/3ugYwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQClMty+mlh9
+ZmmZBxPZ7CCZcjfBi03hjnkLf+0ciaGbGGa9G/7sdPaqe1dxBgfqAkFug7RoORXI
+xRbXThB19QW08sbkvbRkIRbIFN0GiPeBiXZEyHCZcPJn5kxyPnUk1y+Dsk5r+E3w
+5xYlAhbD+oqcwnVga+1AHbIUl2omoXK5U/GV+27ZEbPUZ/+6CgbDW/uE57FIB/vb
+12/Jfm/mtDuM4Dxz/oCOzTU8T1H4rPy00ApeudeV8ub7qN4lqyDa1ebi01trm9ss
+dw5ZAXopBx9TcivzBoYbBKABgqpZT6XmiyoBJIt3W7uNNpRKAqthXAq6h+5TU6dd
+42q8c5/+6fyf
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem b/chromium/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem
new file mode 100644
index 00000000000..34c777c0e4d
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem
@@ -0,0 +1,283 @@
+[Created by: ./generate-target-has-pathlen-but-not-ca.py]
+
+Certificate chain with 1 intermediary, a trusted root, and a target
+certificate that is not a CA, and yet has a pathlen set. Verification is
+expected to fail, since pathlen should only be set for CAs.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e4:03:84:57:5e:99:af:4e:fe:20:15:48:81:f8:
+ 76:01:11:a3:33:b0:2e:ff:3d:ec:69:be:76:8d:9b:
+ c6:9b:5d:cb:b1:a6:eb:84:60:8e:99:fd:31:c1:66:
+ 9f:bb:3d:bb:16:e0:c8:d8:f5:cd:23:10:8a:c5:96:
+ e7:df:ed:96:d9:76:eb:82:23:e2:8c:7d:00:a9:71:
+ ff:71:df:2e:14:b4:ab:3e:29:e8:11:c2:44:75:f9:
+ 9f:e9:cd:cf:2f:0c:db:7b:47:b2:80:c1:90:45:a8:
+ 01:6d:26:88:ff:3b:d8:54:7b:cd:ff:dc:aa:bd:38:
+ 49:b0:02:d8:80:e2:79:07:33:5a:74:cd:ce:8e:df:
+ 75:33:41:e7:5e:fb:25:c0:45:fb:48:32:78:47:1a:
+ 70:03:d6:56:66:32:6e:2d:35:6b:76:8c:a6:33:4c:
+ 1d:60:91:10:5f:70:f3:13:ec:b4:03:4f:cf:99:f9:
+ 8e:e8:99:85:23:0b:cc:3d:17:5b:ec:df:aa:eb:8a:
+ a7:52:67:10:dd:66:c5:b2:95:9f:72:2b:4e:fa:19:
+ 31:99:62:d7:60:fd:9d:9e:e0:ca:29:13:ec:e3:c6:
+ af:47:e0:84:73:ab:3b:2d:58:f5:d8:d1:0c:ee:f6:
+ 23:b1:5c:55:1e:33:40:87:84:f9:d8:8a:ac:ac:46:
+ ed:93
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 3F:B5:B3:28:77:02:A4:B0:9D:4B:DE:37:42:2E:E6:59:0A:D8:38:84
+ X509v3 Authority Key Identifier:
+ keyid:77:62:DF:59:FD:79:52:7B:9A:CF:99:3C:7C:BD:87:CE:41:27:57:F6
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment, Certificate Sign
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Basic Constraints: critical
+ CA:FALSE, pathlen:1
+ Signature Algorithm: sha256WithRSAEncryption
+ 0f:6a:84:9e:41:23:9d:77:90:68:4b:93:39:8e:74:cc:f5:3f:
+ 0a:1c:8f:d9:45:bc:5d:42:d1:23:11:e6:a6:2f:52:58:23:5f:
+ ba:ef:a2:3a:c7:3e:bd:24:a3:47:d3:5a:f7:00:37:0d:a4:c8:
+ cd:ee:92:73:67:4c:d0:3f:63:08:c4:90:a8:42:5f:0e:cb:1e:
+ 96:ae:c7:16:5f:4d:69:e4:3c:8c:a9:47:7e:ad:aa:52:dd:b3:
+ 77:d8:f6:bf:f3:e3:c5:46:ec:c3:21:af:52:62:76:e5:99:0a:
+ ba:a2:1c:54:62:8f:3f:0b:b8:c1:9e:e3:6e:50:4e:36:17:d0:
+ ee:e1:a2:2e:29:c0:1e:a3:94:a3:69:1f:4d:13:50:4c:44:5c:
+ 0f:c3:80:94:3f:6f:60:02:98:da:4f:3a:40:e4:ee:01:af:f1:
+ b3:7b:4a:2e:3a:57:3b:8e:9c:8a:0c:3e:4c:49:e2:22:09:ef:
+ dc:ea:fc:e2:04:20:5c:8e:a5:82:a9:0e:83:b3:ef:cc:09:ff:
+ a9:bc:fa:47:0f:61:3f:7f:d6:df:ec:57:b2:da:16:70:42:8e:
+ 68:28:f5:4d:cb:fb:85:16:e4:78:3b:5e:8a:96:f0:73:d6:f7:
+ b0:ce:4d:18:6a:b9:1b:99:33:01:15:ce:90:c2:13:8e:14:e6:
+ 0e:32:84:28
+-----BEGIN CERTIFICATE-----
+MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkA4RX
+XpmvTv4gFUiB+HYBEaMzsC7/PexpvnaNm8abXcuxpuuEYI6Z/THBZp+7PbsW4MjY
+9c0jEIrFluff7ZbZduuCI+KMfQCpcf9x3y4UtKs+KegRwkR1+Z/pzc8vDNt7R7KA
+wZBFqAFtJoj/O9hUe83/3Kq9OEmwAtiA4nkHM1p0zc6O33UzQede+yXARftIMnhH
+GnAD1lZmMm4tNWt2jKYzTB1gkRBfcPMT7LQDT8+Z+Y7omYUjC8w9F1vs36rriqdS
+ZxDdZsWylZ9yK076GTGZYtdg/Z2e4MopE+zjxq9H4IRzqzstWPXY0Qzu9iOxXFUe
+M0CHhPnYiqysRu2TAgMBAAGjgfowgfcwHQYDVR0OBBYEFD+1syh3AqSwnUveN0Iu
+5lkK2DiEMB8GA1UdIwQYMBaAFHdi31n9eVJ7ms+ZPHy9h85BJ1f2MD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAgEBMA0GCSqGSIb3DQEBCwUAA4IB
+AQAPaoSeQSOdd5BoS5M5jnTM9T8KHI/ZRbxdQtEjEeamL1JYI1+676I6xz69JKNH
+01r3ADcNpMjN7pJzZ0zQP2MIxJCoQl8Oyx6WrscWX01p5DyMqUd+rapS3bN32Pa/
+8+PFRuzDIa9SYnblmQq6ohxUYo8/C7jBnuNuUE42F9Du4aIuKcAeo5SjaR9NE1BM
+RFwPw4CUP29gApjaTzpA5O4Br/Gze0ouOlc7jpyKDD5MSeIiCe/c6vziBCBcjqWC
+qQ6Ds+/MCf+pvPpHD2E/f9bf7Fey2hZwQo5oKPVNy/uFFuR4O16KlvBz1vewzk0Y
+arkbmTMBFc6QwhOOFOYOMoQo
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:cd:be:5e:d6:3b:af:1c:51:0b:b8:31:41:16:86:
+ a1:04:5b:d4:c3:d1:e8:16:12:b0:7a:f8:d4:b6:61:
+ 9b:5a:51:bb:7d:a5:e6:cf:70:48:1d:4e:21:74:de:
+ f8:de:c7:8d:b2:e1:b5:a0:b9:4a:7c:76:b1:24:e6:
+ 6d:7b:17:79:28:99:85:44:d5:9c:c7:b3:7c:64:fd:
+ 3a:97:76:94:88:aa:dc:eb:c3:6e:ab:43:42:d2:89:
+ b3:cb:56:dc:89:f6:4c:65:e0:be:1e:72:01:c7:c6:
+ 50:e6:5b:df:a2:de:4f:43:9d:3d:e8:c8:25:2e:50:
+ 1b:61:0e:2c:45:22:f0:93:7b:d6:05:9f:a4:23:fb:
+ 78:b1:15:49:fe:eb:73:29:b0:eb:9f:e8:6e:3b:92:
+ 86:c0:d0:20:e7:4c:b7:69:7f:d3:0f:54:39:05:3a:
+ 46:9b:47:4d:fa:7e:8c:ce:45:a5:1f:2c:6f:f7:33:
+ 36:10:bc:67:d9:b6:15:86:71:5f:7a:7a:af:4e:71:
+ 59:1d:46:d1:76:96:d8:4b:fc:a0:b9:11:e4:5f:5d:
+ fe:f4:bf:c8:48:54:66:60:be:4b:8b:70:4a:33:e0:
+ ea:02:7a:cd:a1:37:3d:67:ad:93:f3:d0:a5:9e:f2:
+ a4:ff:18:3e:77:97:d2:2c:58:12:a5:d6:55:03:6d:
+ a1:cb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 77:62:DF:59:FD:79:52:7B:9A:CF:99:3C:7C:BD:87:CE:41:27:57:F6
+ X509v3 Authority Key Identifier:
+ keyid:AA:16:BC:F9:7E:AD:F4:71:D6:D4:94:D9:61:4B:01:38:B2:95:8B:84
+
+ 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
+ 4f:dc:80:b5:cb:13:5d:2d:af:b6:6d:7b:51:4e:81:36:16:d1:
+ 36:bb:5d:37:be:6e:4d:40:87:57:5e:db:a9:75:ae:46:e4:74:
+ c4:dc:e5:fd:bc:04:2f:ca:7f:b4:67:db:65:f7:d6:37:94:74:
+ a4:f9:8a:e2:da:d5:64:9e:00:4d:85:39:07:6f:e0:96:d7:2b:
+ ef:73:d3:a4:77:6b:e1:ee:d4:f7:54:ba:30:23:a3:95:2c:c8:
+ 38:21:0c:14:fb:f4:44:27:9a:f3:81:2f:89:59:3e:12:52:52:
+ bf:4e:7c:93:7c:db:b7:df:9b:fb:b6:3c:70:fc:67:07:a6:42:
+ 99:6d:95:c0:64:f8:99:50:aa:2f:b6:19:d8:63:80:0f:22:c3:
+ b4:d6:b0:09:9b:62:a0:37:0e:21:e5:ef:c2:61:ed:7e:2f:f5:
+ 7d:09:19:f4:6f:8a:c8:7a:0e:0a:44:41:9b:22:01:d4:7c:c9:
+ a8:da:d5:91:d9:a6:1f:1f:b8:4a:6a:bd:bc:7e:36:33:7a:e0:
+ 9c:58:c1:75:71:9f:14:04:ce:c9:1f:e6:dc:40:95:ee:ed:b3:
+ 6c:77:5c:31:9a:90:bd:99:80:ab:8f:ef:8d:a6:e0:64:ba:16:
+ 03:a2:21:5d:75:bd:d9:50:7f:d2:02:44:58:9e:b5:c2:1d:37:
+ 50:8f:27:21
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzb5e1juv
+HFELuDFBFoahBFvUw9HoFhKwevjUtmGbWlG7faXmz3BIHU4hdN743seNsuG1oLlK
+fHaxJOZtexd5KJmFRNWcx7N8ZP06l3aUiKrc68Nuq0NC0omzy1bcifZMZeC+HnIB
+x8ZQ5lvfot5PQ5096MglLlAbYQ4sRSLwk3vWBZ+kI/t4sRVJ/utzKbDrn+huO5KG
+wNAg50y3aX/TD1Q5BTpGm0dN+n6MzkWlHyxv9zM2ELxn2bYVhnFfenqvTnFZHUbR
+dpbYS/yguRHkX13+9L/ISFRmYL5Li3BKM+DqAnrNoTc9Z62T89ClnvKk/xg+d5fS
+LFgSpdZVA22hywIDAQABo4HLMIHIMB0GA1UdDgQWBBR3Yt9Z/XlSe5rPmTx8vYfO
+QSdX9jAfBgNVHSMEGDAWgBSqFrz5fq30cdbUlNlhSwE4spWLhDA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AE/cgLXLE10tr7Zte1FOgTYW0Ta7XTe+bk1Ah1de26l1rkbkdMTc5f28BC/Kf7Rn
+22X31jeUdKT5iuLa1WSeAE2FOQdv4JbXK+9z06R3a+Hu1PdUujAjo5UsyDghDBT7
+9EQnmvOBL4lZPhJSUr9OfJN827ffm/u2PHD8ZwemQpltlcBk+JlQqi+2GdhjgA8i
+w7TWsAmbYqA3DiHl78Jh7X4v9X0JGfRvish6DgpEQZsiAdR8yaja1ZHZph8fuEpq
+vbx+NjN64JxYwXVxnxQEzskf5txAle7ts2x3XDGakL2ZgKuP742m4GS6FgOiIV11
+vdlQf9ICRFietcIdN1CPJyE=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:eb:e2:5f:c7:d4:38:fe:e8:6d:64:82:8e:c6:d8:
+ d7:a5:a4:ca:65:5f:55:b6:c5:5c:9c:f6:cc:af:d6:
+ 4b:ec:a1:5c:c3:55:08:19:1c:0e:99:4a:4d:b2:14:
+ 22:36:a0:db:eb:c3:1c:6f:d6:05:69:a5:5b:61:59:
+ 7a:fb:88:da:28:1d:95:c6:fe:31:51:06:ac:f7:41:
+ a6:10:08:25:7f:41:f1:01:39:48:27:c1:34:73:2f:
+ c2:05:b1:97:42:80:de:d4:3a:44:db:a0:34:8c:b8:
+ 5c:de:ab:42:c8:1e:f1:08:7e:10:3a:ee:16:8e:61:
+ ee:ab:aa:f5:7a:2b:ab:af:a2:69:da:f4:b5:95:32:
+ 17:bc:cf:ba:ad:a7:7b:fc:ea:9b:43:bc:ae:07:c3:
+ 92:15:ce:4a:fb:ee:33:e6:89:7d:09:88:f9:a5:af:
+ 0b:4d:c1:7f:28:30:d8:93:75:92:b5:27:2c:01:bd:
+ 52:05:5d:42:a5:dc:f3:1f:1e:b2:3c:a1:17:19:9b:
+ 30:ec:18:85:41:e3:72:d2:93:ef:a0:4d:0b:d4:8a:
+ fa:89:0d:b6:46:fe:bc:f0:82:de:99:4c:1e:57:1c:
+ 8d:71:b3:9c:41:ea:03:8f:a1:d6:f2:a4:9d:1c:b8:
+ 50:c8:c0:19:6a:18:4d:c0:7f:7d:f8:b3:af:c6:62:
+ 09:9b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ AA:16:BC:F9:7E:AD:F4:71:D6:D4:94:D9:61:4B:01:38:B2:95:8B:84
+ X509v3 Authority Key Identifier:
+ keyid:AA:16:BC:F9:7E:AD:F4:71:D6:D4:94:D9:61:4B:01:38:B2:95:8B:84
+
+ 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
+ 07:d5:33:48:84:04:40:42:f1:f2:ff:d9:07:5e:5f:bf:d9:72:
+ 07:6f:a9:6a:f1:5f:f3:59:69:99:41:cd:9d:37:65:cb:2e:c8:
+ 06:f3:0a:0c:da:46:28:6d:d6:06:08:20:5b:ca:ed:c9:14:6e:
+ 11:5a:9f:df:33:06:67:44:e7:63:ba:b2:42:53:2e:31:0b:ce:
+ ef:c1:74:60:76:96:0b:3f:da:9b:f2:a1:d1:89:99:34:f0:f9:
+ ae:8c:39:fd:3d:a6:be:7f:f5:82:f0:25:62:b0:b7:b4:bc:1b:
+ 51:c3:60:05:af:bc:22:b9:62:49:c0:27:12:72:c2:ac:d9:1e:
+ 17:ff:e7:57:f6:b2:f8:37:dd:76:1a:dc:e0:89:4f:b3:8a:74:
+ 0b:76:5f:48:fc:6c:af:6d:42:85:25:b4:44:ca:27:ed:2e:fb:
+ d8:df:1a:a1:82:bd:6c:25:35:62:cb:50:db:27:9e:b2:65:cc:
+ 58:fa:fd:1e:6a:2a:77:cd:3f:b4:6b:e6:71:ec:85:f5:7b:73:
+ a9:73:05:78:1f:26:21:dc:8b:a4:f5:e1:06:a6:97:13:9f:5f:
+ 84:03:12:59:37:81:17:21:2d:39:db:b7:b0:f4:17:73:90:7c:
+ a1:2f:53:c0:4a:af:53:54:2c:5b:9c:8a:e3:66:80:40:30:96:
+ e3:d8:b2:23
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOviX8fUOP7obWSCjsbY
+16WkymVfVbbFXJz2zK/WS+yhXMNVCBkcDplKTbIUIjag2+vDHG/WBWmlW2FZevuI
+2igdlcb+MVEGrPdBphAIJX9B8QE5SCfBNHMvwgWxl0KA3tQ6RNugNIy4XN6rQsge
+8Qh+EDruFo5h7quq9Xorq6+iadr0tZUyF7zPuq2ne/zqm0O8rgfDkhXOSvvuM+aJ
+fQmI+aWvC03Bfygw2JN1krUnLAG9UgVdQqXc8x8esjyhFxmbMOwYhUHjctKT76BN
+C9SK+okNtkb+vPCC3plMHlccjXGznEHqA4+h1vKknRy4UMjAGWoYTcB/ffizr8Zi
+CZsCAwEAAaOByzCByDAdBgNVHQ4EFgQUqha8+X6t9HHW1JTZYUsBOLKVi4QwHwYD
+VR0jBBgwFoAUqha8+X6t9HHW1JTZYUsBOLKVi4QwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAH1TNIhARA
+QvHy/9kHXl+/2XIHb6lq8V/zWWmZQc2dN2XLLsgG8woM2kYobdYGCCBbyu3JFG4R
+Wp/fMwZnROdjurJCUy4xC87vwXRgdpYLP9qb8qHRiZk08PmujDn9Paa+f/WC8CVi
+sLe0vBtRw2AFr7wiuWJJwCcScsKs2R4X/+dX9rL4N912GtzgiU+zinQLdl9I/Gyv
+bUKFJbREyiftLvvY3xqhgr1sJTViy1DbJ56yZcxY+v0eaip3zT+0a+Zx7IX1e3Op
+cwV4HyYh3Iuk9eEGppcTn1+EAxJZN4EXIS0527ew9BdzkHyhL1PASq9TVCxbnIrj
+ZoBAMJbj2LIj
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem b/chromium/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem
new file mode 100644
index 00000000000..249d42a467d
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem
@@ -0,0 +1,280 @@
+[Created by: ./generate-target-not-end-entity.py]
+
+Certificate chain with 1 intermediary, a trusted root, and a target
+certificate that is also a CA. Verification is expected to succeed, as the test
+code accepts any target certificate.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ee:c2:63:d9:42:ea:55:e7:60:10:b7:7a:07:f3:
+ 2c:85:b7:38:91:0c:ec:29:d5:fd:ca:14:ad:58:8b:
+ 12:c2:fd:b6:2e:fb:50:dc:04:e9:c3:20:d1:db:23:
+ da:0e:5e:93:94:cf:82:54:fd:e7:5d:9a:ee:01:37:
+ 84:67:e9:f4:93:7b:ef:be:b1:e1:a3:5a:5a:eb:31:
+ b1:29:8e:05:1a:90:d5:15:aa:5e:de:29:1b:1f:80:
+ eb:17:fa:89:4b:d4:5b:77:0f:d1:e0:7b:f2:8d:a6:
+ b4:aa:22:44:42:3e:bb:af:b7:5e:06:ae:0b:c0:20:
+ 6e:ea:90:ef:4c:cb:34:5a:6b:37:29:a7:07:0c:66:
+ 65:16:36:29:f0:d7:c8:e7:cc:88:2f:cc:bd:63:33:
+ 2d:f5:91:8d:9b:69:f6:f3:05:d3:ca:87:96:ed:79:
+ e4:0f:85:a4:41:62:aa:f2:f9:89:fe:a7:92:e5:7c:
+ 0a:6e:74:70:b0:be:b2:67:12:2c:c4:44:77:54:f0:
+ d6:07:26:aa:ad:8f:9c:f2:12:c2:c1:23:2d:54:8c:
+ 09:df:94:59:7c:8b:e0:62:f1:2d:7b:cc:26:f3:11:
+ 7b:97:04:3b:2a:02:c5:8f:2f:28:c5:c4:52:dc:4c:
+ 5b:6f:0b:8c:e4:89:0a:85:d0:a3:d4:02:74:35:48:
+ c7:c5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 75:E4:93:1E:26:35:79:D3:34:F7:E2:FD:A3:1C:38:1C:68:8B:F6:CD
+ X509v3 Authority Key Identifier:
+ keyid:58:01:24:B6:3B:E6:E7:85:87:83:6F:54:23:6A:C2:D4:E0:9D:6C:37
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 86:0e:74:e2:4f:1c:93:23:8a:9c:37:4a:42:ff:ab:4b:7b:5c:
+ 38:c3:67:11:1d:60:03:b3:1e:57:15:8f:1f:b2:94:45:f0:44:
+ 31:f1:7e:30:0e:f9:cc:48:7b:a3:27:2b:bf:9a:bd:e9:a1:69:
+ e2:1f:e7:91:ef:98:e9:58:5e:f8:7c:a0:8d:e5:81:85:af:8c:
+ a6:04:c5:57:3e:cb:5f:33:dc:ca:b6:72:5b:e7:82:9b:68:91:
+ 73:aa:f2:47:b9:6b:e2:7d:12:b4:85:87:2a:a9:49:a0:cd:79:
+ 41:8d:60:33:43:e8:aa:55:4b:60:8a:41:26:ca:e1:75:35:bd:
+ 45:00:a7:1a:2e:16:15:14:1f:be:9d:aa:25:54:e2:0d:f2:da:
+ 96:27:72:2c:75:4b:d7:06:5f:9d:47:37:25:08:7f:1f:ad:df:
+ e7:6f:1d:f6:95:63:e8:08:02:c9:51:dc:ae:4a:31:eb:c5:61:
+ 24:79:4c:d1:88:79:1f:04:ae:35:79:24:bc:29:4d:0c:c0:05:
+ 99:91:db:f3:83:af:95:4f:f3:13:35:b4:a9:40:04:81:cb:f5:
+ 39:e1:55:96:cf:42:86:68:26:f8:cc:82:6a:b9:10:77:41:55:
+ 03:16:9d:0e:57:37:33:a0:53:ca:7e:0b:1c:85:9e:c2:81:8d:
+ c8:3e:b8:62
+-----BEGIN CERTIFICATE-----
+MIIDfzCCAmegAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDuwmPZ
+QupV52AQt3oH8yyFtziRDOwp1f3KFK1YixLC/bYu+1DcBOnDINHbI9oOXpOUz4JU
+/eddmu4BN4Rn6fSTe+++seGjWlrrMbEpjgUakNUVql7eKRsfgOsX+olL1Ft3D9Hg
+e/KNprSqIkRCPruvt14GrgvAIG7qkO9MyzRaazcppwcMZmUWNinw18jnzIgvzL1j
+My31kY2bafbzBdPKh5bteeQPhaRBYqry+Yn+p5LlfApudHCwvrJnEizERHdU8NYH
+Jqqtj5zyEsLBIy1UjAnflFl8i+Bi8S17zCbzEXuXBDsqAsWPLyjFxFLcTFtvC4zk
+iQqF0KPUAnQ1SMfFAgMBAAGjgdswgdgwHQYDVR0OBBYEFHXkkx4mNXnTNPfi/aMc
+OBxoi/bNMB8GA1UdIwQYMBaAFFgBJLY75ueFh4NvVCNqwtTgnWw3MD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAIYOdOJPHJMjipw3SkL/q0t7XDjDZxEdYAOzHlcV
+jx+ylEXwRDHxfjAO+cxIe6MnK7+avemhaeIf55HvmOlYXvh8oI3lgYWvjKYExVc+
+y18z3Mq2clvngptokXOq8ke5a+J9ErSFhyqpSaDNeUGNYDND6KpVS2CKQSbK4XU1
+vUUApxouFhUUH76dqiVU4g3y2pYncix1S9cGX51HNyUIfx+t3+dvHfaVY+gIAslR
+3K5KMevFYSR5TNGIeR8ErjV5JLwpTQzABZmR2/ODr5VP8xM1tKlABIHL9TnhVZbP
+QoZoJvjMgmq5EHdBVQMWnQ5XNzOgU8p+CxyFnsKBjcg+uGI=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c7:c3:50:5c:f2:60:57:55:0d:be:39:c4:be:74:
+ 76:26:ce:b2:4c:be:ac:dc:17:ac:a0:a4:c3:5f:ae:
+ 64:59:da:20:77:7c:88:28:0e:75:7e:ef:70:80:9c:
+ 0c:8e:94:1c:48:ea:4f:b3:34:1e:e4:cf:af:f8:29:
+ 13:06:6f:19:0f:e7:9a:df:59:8c:44:d3:0e:26:70:
+ 5f:c7:a5:3a:36:4d:4b:50:9c:bd:14:fb:21:4a:f8:
+ d6:2b:49:94:2b:df:4c:8c:89:32:d7:53:f8:59:14:
+ e9:23:76:f3:fb:b4:27:2d:c9:28:17:cc:fe:06:2c:
+ bd:b5:97:30:83:40:9e:c7:ff:9e:0a:99:a7:f0:e8:
+ 0c:c7:73:ca:3f:48:3a:75:97:bd:de:9a:84:6d:5b:
+ 13:dc:0c:64:1e:66:4f:72:10:28:cd:34:bb:15:f1:
+ ca:65:3f:03:db:aa:fa:4d:4c:26:64:8a:3f:6f:67:
+ 51:fa:15:2d:71:7c:fd:0b:12:9e:12:c2:77:9c:f2:
+ a8:86:78:f2:6f:9f:79:c9:50:51:28:41:13:79:79:
+ 7c:a1:93:dd:71:f7:08:92:99:f7:9c:37:ff:2b:82:
+ b6:4e:a9:93:47:83:dc:36:83:40:13:22:96:eb:5e:
+ 2f:ad:a1:d6:70:38:c5:2b:3a:0b:ce:4c:fc:81:c1:
+ 49:f5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 58:01:24:B6:3B:E6:E7:85:87:83:6F:54:23:6A:C2:D4:E0:9D:6C:37
+ X509v3 Authority Key Identifier:
+ keyid:92:00:23:C7:C3:33:14:62:3D:59:C9:52:A4:CC:A0:5C:16:DD:35:2D
+
+ 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
+ 3d:c9:5f:4a:71:a9:28:ca:c0:27:47:f1:23:b0:87:2c:5f:4c:
+ 20:de:1e:60:8b:6d:c3:42:2c:bf:ed:82:26:00:b6:f8:4f:7e:
+ ac:37:ec:43:ea:7a:a5:58:fc:34:cd:af:54:2d:3e:30:e8:44:
+ 8d:37:8d:5b:5c:b8:52:bd:f1:d5:ab:c7:61:d9:83:b5:f5:51:
+ 41:ed:f0:1c:02:c7:ae:4f:57:60:49:c8:6d:3e:44:53:13:ce:
+ 97:47:78:b5:04:23:fd:0a:49:e5:99:67:90:07:e7:a5:66:61:
+ 2b:93:5f:b5:dd:d0:fe:92:e8:36:3e:4f:cb:a7:f0:64:d2:88:
+ 11:e5:78:42:89:a7:3f:b6:fe:93:3a:d8:52:d0:8c:9d:ea:89:
+ 21:56:67:04:21:c5:c2:83:42:13:43:ee:5c:1c:2f:00:97:45:
+ 56:4a:18:21:ad:2d:b3:b6:38:ed:5e:df:fe:13:43:53:90:2a:
+ 05:ab:47:6a:dd:9e:9e:51:a2:f2:98:08:03:4c:3f:17:5f:55:
+ e7:b0:f3:ae:62:be:a3:0f:5f:d2:3c:b9:c3:48:55:a9:f6:0d:
+ 4b:fd:15:54:f5:0b:57:30:c7:f5:fb:61:ff:0a:82:35:58:21:
+ f0:05:90:a2:d6:52:d4:6b:53:a8:ea:98:68:53:59:0c:11:db:
+ b2:af:fd:3e
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx8NQXPJg
+V1UNvjnEvnR2Js6yTL6s3BesoKTDX65kWdogd3yIKA51fu9wgJwMjpQcSOpPszQe
+5M+v+CkTBm8ZD+ea31mMRNMOJnBfx6U6Nk1LUJy9FPshSvjWK0mUK99MjIky11P4
+WRTpI3bz+7QnLckoF8z+Biy9tZcwg0Cex/+eCpmn8OgMx3PKP0g6dZe93pqEbVsT
+3AxkHmZPchAozTS7FfHKZT8D26r6TUwmZIo/b2dR+hUtcXz9CxKeEsJ3nPKohnjy
+b595yVBRKEETeXl8oZPdcfcIkpn3nDf/K4K2TqmTR4PcNoNAEyKW614vraHWcDjF
+KzoLzkz8gcFJ9QIDAQABo4HLMIHIMB0GA1UdDgQWBBRYASS2O+bnhYeDb1QjasLU
+4J1sNzAfBgNVHSMEGDAWgBSSACPHwzMUYj1ZyVKkzKBcFt01LTA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AD3JX0pxqSjKwCdH8SOwhyxfTCDeHmCLbcNCLL/tgiYAtvhPfqw37EPqeqVY/DTN
+r1QtPjDoRI03jVtcuFK98dWrx2HZg7X1UUHt8BwCx65PV2BJyG0+RFMTzpdHeLUE
+I/0KSeWZZ5AH56VmYSuTX7Xd0P6S6DY+T8un8GTSiBHleEKJpz+2/pM62FLQjJ3q
+iSFWZwQhxcKDQhND7lwcLwCXRVZKGCGtLbO2OO1e3/4TQ1OQKgWrR2rdnp5RovKY
+CANMPxdfVeew865ivqMPX9I8ucNIVan2DUv9FVT1C1cwx/X7Yf8KgjVYIfAFkKLW
+UtRrU6jqmGhTWQwR27Kv/T4=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9d:bb:c1:61:ff:52:46:21:fd:d7:06:43:c7:e0:
+ 5d:5c:c8:02:0a:44:68:63:45:92:58:8d:2f:d6:b3:
+ 86:f1:01:ee:fd:34:97:4b:d6:64:fc:4f:8f:88:50:
+ 56:1a:e6:20:00:9f:8c:8d:e0:c0:30:41:28:99:10:
+ 14:b6:28:6c:b9:37:ef:5c:c4:ee:eb:37:ff:06:07:
+ f3:5c:17:8b:aa:d6:5c:8e:19:01:8d:66:3b:8f:c9:
+ e2:83:0a:0f:8c:7b:21:da:cb:4d:ea:81:11:17:92:
+ 83:f5:35:19:d5:b5:92:49:3d:08:a5:c3:95:37:76:
+ ad:38:9c:fd:11:ff:d4:7f:09:60:10:ea:07:93:5c:
+ 2f:4c:95:53:a1:cb:3b:b1:a8:9a:9d:b9:a4:87:af:
+ 78:78:6e:dc:76:bb:00:74:cd:54:75:6a:17:45:b8:
+ 55:d8:87:87:88:7a:d4:98:30:05:92:df:65:07:aa:
+ d7:08:b7:18:b8:35:79:bb:5e:13:e2:c3:07:65:42:
+ d4:52:e3:91:41:9d:38:cb:1e:9e:5d:3b:51:7d:95:
+ f4:3b:6f:31:77:57:4b:e8:74:59:82:47:60:f9:91:
+ 83:19:20:54:03:a0:cb:76:5e:50:32:ec:32:57:f6:
+ d0:1d:f7:46:7d:c1:ff:a7:b8:1d:80:66:f0:d9:c9:
+ 59:d9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 92:00:23:C7:C3:33:14:62:3D:59:C9:52:A4:CC:A0:5C:16:DD:35:2D
+ X509v3 Authority Key Identifier:
+ keyid:92:00:23:C7:C3:33:14:62:3D:59:C9:52:A4:CC:A0:5C:16:DD:35:2D
+
+ 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
+ 7a:76:9e:1b:08:ba:ae:df:d7:32:30:27:f7:6d:e0:00:f2:4f:
+ f0:cf:dd:b5:3e:65:71:d9:97:18:5c:fc:5f:a4:61:88:41:73:
+ e6:45:d2:09:3a:a5:6d:09:ab:29:13:dc:0a:43:fd:8a:1f:be:
+ 7f:a5:a2:07:cc:9c:63:d5:30:51:93:eb:fc:27:17:08:d4:15:
+ 80:84:1c:5e:1b:bd:00:a0:21:0d:08:8a:44:64:40:73:6c:b5:
+ 50:2b:82:5f:c8:d8:fd:26:f6:91:38:df:d2:58:20:a0:ae:f2:
+ 14:54:e5:d2:ff:ef:87:57:7d:bd:5e:68:b8:1b:62:e0:ae:f4:
+ 08:cd:53:35:1e:a4:cf:3c:21:22:55:1e:e4:51:87:f9:74:38:
+ 10:29:86:64:87:8b:55:9b:96:5a:81:e4:93:2d:c0:fb:06:7f:
+ dd:17:b1:d3:24:75:73:97:df:31:d6:01:a4:be:70:e2:af:ee:
+ c3:bc:fc:a1:cd:93:2d:4d:b6:b5:95:02:28:38:68:27:59:38:
+ 95:d9:64:20:1e:e5:46:f1:bb:f3:5a:2c:b3:f8:d8:cc:fd:34:
+ 09:fb:0b:02:b7:e5:de:0f:ea:2a:2b:0d:81:55:4d:84:d6:f6:
+ ba:a4:47:fe:f1:f9:7d:3f:f9:a1:46:bf:fd:dd:89:8b:b4:22:
+ 1d:86:9f:c5
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ27wWH/UkYh/dcGQ8fg
+XVzIAgpEaGNFkliNL9azhvEB7v00l0vWZPxPj4hQVhrmIACfjI3gwDBBKJkQFLYo
+bLk371zE7us3/wYH81wXi6rWXI4ZAY1mO4/J4oMKD4x7IdrLTeqBEReSg/U1GdW1
+kkk9CKXDlTd2rTic/RH/1H8JYBDqB5NcL0yVU6HLO7Gomp25pIeveHhu3Ha7AHTN
+VHVqF0W4VdiHh4h61JgwBZLfZQeq1wi3GLg1ebteE+LDB2VC1FLjkUGdOMsenl07
+UX2V9DtvMXdXS+h0WYJHYPmRgxkgVAOgy3ZeUDLsMlf20B33Rn3B/6e4HYBm8NnJ
+WdkCAwEAAaOByzCByDAdBgNVHQ4EFgQUkgAjx8MzFGI9WclSpMygXBbdNS0wHwYD
+VR0jBBgwFoAUkgAjx8MzFGI9WclSpMygXBbdNS0wNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB6dp4bCLqu
+39cyMCf3beAA8k/wz921PmVx2ZcYXPxfpGGIQXPmRdIJOqVtCaspE9wKQ/2KH75/
+paIHzJxj1TBRk+v8JxcI1BWAhBxeG70AoCENCIpEZEBzbLVQK4JfyNj9JvaRON/S
+WCCgrvIUVOXS/++HV329Xmi4G2LgrvQIzVM1HqTPPCEiVR7kUYf5dDgQKYZkh4tV
+m5ZageSTLcD7Bn/dF7HTJHVzl98x1gGkvnDir+7DvPyhzZMtTba1lQIoOGgnWTiV
+2WQgHuVG8bvzWiyz+NjM/TQJ+wsCt+XeD+oqKw2BVU2E1va6pEf+8fl9P/mhRr/9
+3YmLtCIdhp/F
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem b/chromium/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem
new file mode 100644
index 00000000000..8c8bd2428ef
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem
@@ -0,0 +1,248 @@
+[Created by: generate-target-signed-by-512bit-rsa.py]
+
+Certificate chain with 1 intermediary and a trusted root. The target
+certificate is signed using a weak RSA key (512-bit modulus), and so
+verification is expected to fail.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a0:09:f8:e1:95:28:53:9e:e3:c1:a5:c0:76:05:
+ 74:88:fb:fb:d0:c9:c2:3e:61:e3:a1:e3:b0:c8:81:
+ a3:d1:bf:0c:f4:d8:06:3d:8f:58:45:e1:f0:00:8e:
+ b1:8c:ab:bc:83:ae:d1:39:3d:6c:52:ef:76:f1:6f:
+ 93:b0:b2:26:b7:b4:ab:fd:25:44:94:85:4a:c1:ad:
+ 2a:6c:59:11:3c:33:63:39:e9:f1:c6:96:05:7a:a4:
+ 8b:3c:74:10:cb:ae:19:eb:cd:df:eb:b0:68:91:cd:
+ 5c:56:8d:41:d4:b4:4f:db:45:50:4d:01:01:10:09:
+ be:84:a3:3a:98:55:a2:a6:ea:6b:fc:c7:4f:ae:cd:
+ 31:60:80:2b:86:27:cf:64:f8:4f:35:32:83:02:57:
+ ab:85:9e:ae:e0:39:06:03:d8:8e:c5:6f:01:5f:f6:
+ 08:1f:ae:c9:a1:32:65:35:c5:9b:d7:2c:e1:6f:93:
+ 41:f7:40:ff:b1:36:08:5e:35:9e:42:2b:a4:d8:0a:
+ c2:ce:e4:94:cf:51:7c:76:18:d0:0a:4e:e8:37:b3:
+ 44:f4:0b:31:fa:49:96:94:c8:c0:ef:3a:10:ca:4d:
+ eb:ed:24:a7:d4:ec:bf:d5:5d:80:ed:d7:3a:b1:7c:
+ 3f:0f:b7:cb:48:59:73:fb:af:43:5e:3e:6b:e7:a5:
+ ed:01
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 01:E0:D2:38:1C:28:DC:51:7E:F9:E6:25:7A:C5:47:ED:81:6C:FC:5F
+ X509v3 Authority Key Identifier:
+ keyid:B8:D0:79:3D:EA:8A:56:E5:90:68:D6:6C:E9:91:14:0C:AE:5A:48:10
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ be:ba:eb:82:1f:02:6b:d0:9e:c9:55:09:b1:e9:e1:82:8c:50:
+ 39:7e:f5:ff:0f:4f:ef:d8:7d:52:10:07:5e:c1:c4:0e:d5:94:
+ 67:d2:0e:2e:22:e6:5a:91:b5:f7:05:e3:a4:be:bc:6c:fb:38:
+ 2c:df:47:55:61:bc:4c:39:14:68
+-----BEGIN CERTIFICATE-----
+MIICyzCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgCfjh
+lShTnuPBpcB2BXSI+/vQycI+YeOh47DIgaPRvwz02AY9j1hF4fAAjrGMq7yDrtE5
+PWxS73bxb5Owsia3tKv9JUSUhUrBrSpsWRE8M2M56fHGlgV6pIs8dBDLrhnrzd/r
+sGiRzVxWjUHUtE/bRVBNAQEQCb6EozqYVaKm6mv8x0+uzTFggCuGJ89k+E81MoMC
+V6uFnq7gOQYD2I7FbwFf9ggfrsmhMmU1xZvXLOFvk0H3QP+xNgheNZ5CK6TYCsLO
+5JTPUXx2GNAKTug3s0T0CzH6SZaUyMDvOhDKTevtJKfU7L/VXYDt1zqxfD8Pt8tI
+WXP7r0NePmvnpe0BAgMBAAGjgekwgeYwHQYDVR0OBBYEFAHg0jgcKNxRfvnmJXrF
+R+2BbPxfMB8GA1UdIwQYMBaAFLjQeT3qilblkGjWbOmRFAyuWkgQMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAANBAL6664IfAmvQnslVCbHp4YKM
+UDl+9f8PT+/YfVIQB17BxA7VlGfSDi4i5lqRtfcF46S+vGz7OCzfR1VhvEw5FGg=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (512 bit)
+ Modulus:
+ 00:da:fa:51:64:db:d4:40:cf:aa:60:3f:0b:9a:0e:
+ 26:21:59:0e:f1:8b:e2:75:11:de:2d:1c:e5:dc:9b:
+ e2:16:ce:cf:50:a1:aa:c9:e0:19:9f:5c:e5:44:69:
+ 0d:f9:0c:d7:c5:1e:cf:11:65:77:cd:37:5f:d8:fe:
+ 6f:e0:99:b3:f7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ B8:D0:79:3D:EA:8A:56:E5:90:68:D6:6C:E9:91:14:0C:AE:5A:48:10
+ X509v3 Authority Key Identifier:
+ keyid:68:06:12:0B:9D:1F:3A:7C:E5:87:20:3C:ED:A3:49:5D:3E:74:28:69
+
+ 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
+ 8c:35:af:f3:d9:62:41:91:93:ed:8b:f6:42:3e:94:80:cf:31:
+ ed:0f:a5:52:2e:51:3f:f3:3f:56:38:c5:f0:25:c5:f1:13:8c:
+ 6a:80:28:58:79:e1:eb:39:25:5a:af:31:07:24:da:8c:ae:17:
+ c7:56:fd:c1:d4:3a:2c:7e:7e:a4:ff:eb:66:74:96:66:e8:26:
+ 52:1d:c5:d6:0a:64:ea:cd:b7:df:b8:49:b1:c4:44:c6:d0:e3:
+ 94:0f:b2:b2:cb:75:5a:bf:48:c6:ad:82:46:74:a7:53:bd:55:
+ 00:67:6e:ba:2c:b8:15:43:30:64:d8:10:3a:67:b0:31:df:f6:
+ 9e:7e:7c:0b:63:d6:6d:b0:5d:9a:61:96:51:03:71:d3:fb:da:
+ 30:b8:d1:a6:8a:4a:a2:36:58:84:34:c0:30:5a:d8:51:30:d0:
+ 89:8c:1e:c3:45:32:85:17:ba:01:4d:60:04:91:23:ee:df:71:
+ 0d:82:90:67:2f:04:4e:e2:64:a9:48:55:03:e7:0b:a1:b4:e3:
+ e7:e9:54:3b:bc:83:f0:b3:bb:3f:1a:fd:03:95:28:0e:d2:3b:
+ 8b:62:fe:bb:b7:9a:1d:15:d3:96:47:be:c9:4e:21:77:63:60:
+ 3b:27:b3:3d:7e:8b:fd:3b:55:17:cf:8b:99:81:6d:92:66:5b:
+ 35:62:4a:96
+-----BEGIN CERTIFICATE-----
+MIICpTCCAY2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANr6UWTb1EDPqmA/C5oO
+JiFZDvGL4nUR3i0c5dyb4hbOz1ChqsngGZ9c5URpDfkM18UezxFld803X9j+b+CZ
+s/cCAwEAAaOByzCByDAdBgNVHQ4EFgQUuNB5PeqKVuWQaNZs6ZEUDK5aSBAwHwYD
+VR0jBBgwFoAUaAYSC50fOnzlhyA87aNJXT50KGkwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCMNa/z2WJB
+kZPti/ZCPpSAzzHtD6VSLlE/8z9WOMXwJcXxE4xqgChYeeHrOSVarzEHJNqMrhfH
+Vv3B1Dosfn6k/+tmdJZm6CZSHcXWCmTqzbffuEmxxETG0OOUD7Kyy3Vav0jGrYJG
+dKdTvVUAZ266LLgVQzBk2BA6Z7Ax3/aefnwLY9ZtsF2aYZZRA3HT+9owuNGmikqi
+NliENMAwWthRMNCJjB7DRTKFF7oBTWAEkSPu33ENgpBnLwRO4mSpSFUD5wuhtOPn
+6VQ7vIPws7s/Gv0DlSgO0juLYv67t5odFdOWR77JTiF3Y2A7J7M9fov9O1UXz4uZ
+gW2SZls1YkqW
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:cc:43:57:ce:f5:69:b5:17:2d:24:1e:10:48:61:
+ 1e:6e:27:06:10:ae:6d:cd:70:97:4c:39:7b:0d:68:
+ 76:49:5b:2a:56:cf:24:d3:35:e4:f9:44:b0:60:c2:
+ db:ee:58:f0:2c:3f:25:53:95:bf:fc:3b:cf:1a:5c:
+ de:94:67:30:7f:6b:7b:c1:9c:d9:55:91:8b:34:57:
+ a7:4f:d0:d7:38:8c:e6:57:ae:f6:61:66:bb:fb:4e:
+ d3:b0:d0:c0:74:83:e3:43:7a:15:ab:29:fa:3f:65:
+ b5:58:3b:0b:76:cf:b9:85:d9:2a:5b:bf:81:4d:d7:
+ bb:72:cf:30:91:1a:0a:4f:6c:64:48:13:fe:cc:14:
+ 21:f0:74:b8:90:73:f7:d5:fe:5b:dd:b2:7a:71:1a:
+ e3:c3:22:5a:37:38:db:d0:39:62:b3:87:0e:7d:a8:
+ 93:68:82:01:29:36:eb:30:20:66:d9:2a:f8:e9:7d:
+ 53:ac:93:c1:68:c1:21:66:26:9e:4d:34:8a:14:c2:
+ 38:c0:6e:57:9a:c8:93:c1:7d:7d:d8:22:6e:bb:5e:
+ ff:dd:e0:af:e4:af:32:6d:f2:e7:57:d4:53:8d:ea:
+ f9:ca:72:d3:3a:4e:19:e3:b8:b7:4f:fb:d8:5b:41:
+ da:0e:17:59:e2:88:cd:c2:b7:6b:d4:64:50:f0:1e:
+ 36:9d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 68:06:12:0B:9D:1F:3A:7C:E5:87:20:3C:ED:A3:49:5D:3E:74:28:69
+ X509v3 Authority Key Identifier:
+ keyid:68:06:12:0B:9D:1F:3A:7C:E5:87:20:3C:ED:A3:49:5D:3E:74:28:69
+
+ 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
+ 2a:56:07:28:0a:b2:16:a5:3e:e3:cc:7e:10:47:8d:88:04:be:
+ 92:d6:ef:fa:c2:e3:5f:5f:57:3a:75:5a:8e:8e:62:e0:94:26:
+ 32:d2:ab:d3:d7:88:7e:d0:14:b1:1b:1a:5d:15:87:15:45:ae:
+ 47:50:0b:50:dd:52:55:03:0b:cb:91:13:b0:96:20:24:c5:aa:
+ 13:f5:4f:60:20:b6:46:6a:a6:cf:9d:4e:88:09:77:ad:4d:6f:
+ ea:d6:18:81:ac:7c:ad:59:9c:bb:f5:c5:62:e5:e4:b3:61:b2:
+ fb:f4:22:4e:38:a4:42:3a:e1:00:54:78:dd:24:90:20:47:d2:
+ 74:2b:89:44:64:04:02:3b:f9:8b:fa:35:aa:90:c1:73:82:95:
+ 94:fa:5f:85:e9:af:e1:3e:33:2b:1b:91:31:1d:94:ee:1c:0c:
+ e5:22:de:48:d4:2d:f7:3a:16:7e:f2:40:dc:ce:ec:3e:41:0d:
+ 12:3e:9c:ff:15:2b:9b:b3:80:87:02:50:76:ae:e1:05:dd:89:
+ 72:fc:49:e5:81:1f:91:cc:c8:27:b7:2c:b2:ef:71:a0:97:76:
+ 49:da:71:75:24:5e:45:2d:5b:2b:79:d2:b0:a3:b8:85:13:d5:
+ 68:d7:53:f0:d1:b8:87:d1:84:7c:9e:e1:18:23:f4:cc:2a:8d:
+ f3:93:51:5e
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMxDV871abUXLSQeEEhh
+Hm4nBhCubc1wl0w5ew1odklbKlbPJNM15PlEsGDC2+5Y8Cw/JVOVv/w7zxpc3pRn
+MH9re8Gc2VWRizRXp0/Q1ziM5leu9mFmu/tO07DQwHSD40N6Fasp+j9ltVg7C3bP
+uYXZKlu/gU3Xu3LPMJEaCk9sZEgT/swUIfB0uJBz99X+W92yenEa48MiWjc429A5
+YrOHDn2ok2iCASk26zAgZtkq+Ol9U6yTwWjBIWYmnk00ihTCOMBuV5rIk8F9fdgi
+brte/93gr+SvMm3y51fUU43q+cpy0zpOGeO4t0/72FtB2g4XWeKIzcK3a9RkUPAe
+Np0CAwEAAaOByzCByDAdBgNVHQ4EFgQUaAYSC50fOnzlhyA87aNJXT50KGkwHwYD
+VR0jBBgwFoAUaAYSC50fOnzlhyA87aNJXT50KGkwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAqVgcoCrIW
+pT7jzH4QR42IBL6S1u/6wuNfX1c6dVqOjmLglCYy0qvT14h+0BSxGxpdFYcVRa5H
+UAtQ3VJVAwvLkROwliAkxaoT9U9gILZGaqbPnU6ICXetTW/q1hiBrHytWZy79cVi
+5eSzYbL79CJOOKRCOuEAVHjdJJAgR9J0K4lEZAQCO/mL+jWqkMFzgpWU+l+F6a/h
+PjMrG5ExHZTuHAzlIt5I1C33OhZ+8kDczuw+QQ0SPpz/FSubs4CHAlB2ruEF3Yly
+/EnlgR+RzMgntyyy73Ggl3ZJ2nF1JF5FLVsredKwo7iFE9Vo11Pw0biH0YR8nuEY
+I/TMKo3zk1Fe
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem b/chromium/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem
new file mode 100644
index 00000000000..6109796debb
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem
@@ -0,0 +1,252 @@
+[Created by: generate-target-signed-using-ecdsa.py]
+
+Certificate chain with a trusted root using RSA, and intermediary using EC,
+and a target certificate using RSA. Verification is expected to succeed.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:f5:15:82:5b:5b:ef:98:fd:63:b3:5b:08:9c:21:
+ 8b:be:10:f1:3a:ab:17:e8:f2:9c:37:24:80:41:6a:
+ 87:71:1d:9a:ea:c3:a6:f7:25:e3:09:03:3f:92:2e:
+ e1:bc:9e:fd:70:65:e9:29:21:4f:46:01:12:20:e2:
+ 08:d9:bd:86:40:5d:3d:b9:6a:c5:ad:3f:dc:82:00:
+ 75:7b:da:26:a1:c9:49:f2:b5:30:6c:40:07:94:c6:
+ f4:41:1f:88:3a:d7:89:ab:86:79:50:cc:85:8e:f6:
+ a4:fc:7b:03:70:74:1e:6e:09:98:ff:b4:8a:ea:c0:
+ c1:e3:07:ff:8d:f8:e8:bc:f5:fd:6e:aa:db:fc:26:
+ 2e:44:bd:52:e3:66:f5:58:6d:ea:0c:30:19:ed:8f:
+ db:cd:1f:40:20:2f:36:35:d7:63:b5:d7:2c:e8:4b:
+ d3:e2:90:82:2f:27:4d:22:8a:94:e3:fb:c7:40:77:
+ e2:e0:56:c7:70:b6:ae:9b:e9:7c:fa:b5:d0:40:34:
+ dd:0b:59:96:0d:ba:84:47:87:62:c1:3e:1f:21:5b:
+ 3b:15:56:3a:8b:e8:4e:6c:02:c8:da:dc:b3:2b:a3:
+ b9:7e:c6:dc:06:94:9b:0c:ea:fc:7e:02:d3:3f:d2:
+ 87:30:da:c4:41:1a:5f:1f:89:c9:6f:39:96:e5:fd:
+ 3a:c9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 0A:36:4B:AA:5E:42:C2:6B:CE:3C:58:0C:33:53:9B:ED:09:42:89:B9
+ X509v3 Authority Key Identifier:
+ keyid:A4:A1:01:1C:8F:94:62:C3:11:19:36:76:04:DC:A9:AF:6F:B6:11:9C
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:64:02:30:3b:0e:cc:c2:70:77:25:fe:01:46:fb:e7:fe:ee:
+ 68:07:50:f1:14:b8:9a:6f:53:bb:1f:4f:7f:ba:62:d2:76:06:
+ 4b:d4:93:8a:1b:f6:3c:96:91:8c:57:90:a2:99:5d:0b:02:30:
+ 3e:98:92:c5:01:13:f9:d4:21:bc:44:14:a6:9b:b9:8e:f0:86:
+ ec:67:c8:12:07:74:41:8c:f0:f3:e8:b7:cc:e3:23:a0:a1:05:
+ 2f:66:73:be:62:9b:1c:ce:70:fe:eb:09
+-----BEGIN CERTIFICATE-----
+MIIC6zCCAnKgAwIBAgIBATAKBggqhkjOPQQDAjAXMRUwEwYDVQQDDAxJbnRlcm1l
+ZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYDVQQD
+DAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD1FYJbW++Y
+/WOzWwicIYu+EPE6qxfo8pw3JIBBaodxHZrqw6b3JeMJAz+SLuG8nv1wZekpIU9G
+ARIg4gjZvYZAXT25asWtP9yCAHV72iahyUnytTBsQAeUxvRBH4g614mrhnlQzIWO
+9qT8ewNwdB5uCZj/tIrqwMHjB/+N+Oi89f1uqtv8Ji5EvVLjZvVYbeoMMBntj9vN
+H0AgLzY112O11yzoS9PikIIvJ00iipTj+8dAd+LgVsdwtq6b6Xz6tdBANN0LWZYN
+uoRHh2LBPh8hWzsVVjqL6E5sAsja3LMro7l+xtwGlJsM6vx+AtM/0ocw2sRBGl8f
+iclvOZbl/TrJAgMBAAGjgekwgeYwHQYDVR0OBBYEFAo2S6peQsJrzjxYDDNTm+0J
+Qom5MB8GA1UdIwQYMBaAFKShARyPlGLDERk2dgTcqa9vthGcMD8GCCsGAQUFBwEB
+BDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVkaWFy
+eS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0ludGVy
+bWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
+BggrBgEFBQcDAjAKBggqhkjOPQQDAgNnADBkAjA7DszCcHcl/gFG++f+7mgHUPEU
+uJpvU7sfT3+6YtJ2BkvUk4ob9jyWkYxXkKKZXQsCMD6YksUBE/nUIbxEFKabuY7w
+huxnyBIHdEGM8PPot8zjI6ChBS9mc75imxzOcP7rCQ==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:ca:bc:6c:d5:4b:51:ef:d3:7d:8a:46:12:ab:5f:
+ d4:f3:3c:7d:eb:40:8b:de:0f:79:6d:6f:a4:40:0f:
+ 96:51:8a:00:20:48:7a:d3:d4:30:2e:5b:1d:9f:e1:
+ 00:3e:54:cb:93:62:21:7c:09:57:2e:43:38:08:77:
+ 5c:1c:8b:aa:17:c1:22:c0:db:01:bf:c0:80:0a:24:
+ 68:0d:2d:ce:51:e4:a3:2a:c9:42:0b:7c:57:82:31:
+ 94:2f:b7:a8:42:9c:4e
+ ASN1 OID: secp384r1
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ A4:A1:01:1C:8F:94:62:C3:11:19:36:76:04:DC:A9:AF:6F:B6:11:9C
+ X509v3 Authority Key Identifier:
+ keyid:E9:AC:73:09:B6:86:CD:95:42:29:5D:E5:EC:C7:99:29:12:91:8C:53
+
+ 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
+ 22:50:e8:71:34:bf:8b:44:c5:4e:82:31:fd:50:48:f4:fa:3a:
+ 01:4a:f9:71:a6:a9:a2:d0:1e:bc:d3:1d:dc:ac:8f:4e:db:58:
+ 8a:6b:a2:64:29:6e:f5:1b:0b:87:2e:f5:bd:dd:92:7a:5f:4e:
+ a6:aa:1d:b4:7c:f2:eb:5a:2b:17:83:99:29:1f:2b:12:45:9b:
+ 1a:cd:d3:b1:71:a3:d9:7d:cf:78:f4:64:ce:03:a5:0b:c7:98:
+ e8:73:58:e2:26:47:5c:c0:ed:ac:c0:11:b8:39:11:19:39:fc:
+ 01:b6:4c:a2:f5:4a:ae:a3:9e:3c:82:73:3e:b5:2c:28:63:ec:
+ 14:a2:9f:a7:d7:4b:3e:f3:56:50:f6:9e:87:9b:d1:38:fa:78:
+ 2e:7f:29:fe:4a:a8:d6:43:c4:05:d6:d6:67:7f:52:90:36:53:
+ ff:a6:78:1f:7f:f7:ad:66:65:7d:4b:57:3c:d6:b3:19:9d:08:
+ af:d2:5b:1a:76:42:ff:b2:6b:2c:0d:d1:1d:05:c0:d8:28:02:
+ 9b:cb:f6:1d:7a:35:93:b9:c9:76:2d:d3:ef:f4:07:bf:d6:8b:
+ 33:2a:83:69:8a:68:63:0a:b9:45:f6:e4:12:38:37:87:d6:53:
+ 46:33:ae:f8:72:d3:e5:e9:93:bb:ba:db:8d:73:01:b1:79:0f:
+ d8:1c:a0:d0
+-----BEGIN CERTIFICATE-----
+MIICvzCCAaegAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEyrxs1UtR79N9ikYSq1/U
+8zx960CL3g95bW+kQA+WUYoAIEh609QwLlsdn+EAPlTLk2IhfAlXLkM4CHdcHIuq
+F8EiwNsBv8CACiRoDS3OUeSjKslCC3xXgjGUL7eoQpxOo4HLMIHIMB0GA1UdDgQW
+BBSkoQEcj5RiwxEZNnYE3Kmvb7YRnDAfBgNVHSMEGDAWgBTprHMJtobNlUIpXeXs
+x5kpEpGMUzA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwt
+Zm9yLWFpYS9Sb290LmNlcjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZv
+ci1jcmwvUm9vdC5jcmwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBACJQ6HE0v4tExU6CMf1QSPT6OgFK+XGmqaLQHrzT
+Hdysj07bWIpromQpbvUbC4cu9b3dknpfTqaqHbR88utaKxeDmSkfKxJFmxrN07Fx
+o9l9z3j0ZM4DpQvHmOhzWOImR1zA7azAEbg5ERk5/AG2TKL1Sq6jnjyCcz61LChj
+7BSin6fXSz7zVlD2noeb0Tj6eC5/Kf5KqNZDxAXW1md/UpA2U/+meB9/961mZX1L
+VzzWsxmdCK/SWxp2Qv+yaywN0R0FwNgoApvL9h16NZO5yXYt0+/0B7/WizMqg2mK
+aGMKuUX25BI4N4fWU0Yzrvhy0+Xpk7u6241zAbF5D9gcoNA=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b8:3c:af:88:6d:5e:96:7e:58:90:09:5d:40:54:
+ 11:4f:55:ff:bb:e7:94:1b:ba:d7:df:b9:47:c3:ff:
+ 84:71:22:da:a8:89:e6:98:71:4b:ae:d8:c1:19:df:
+ 4f:69:bf:c2:3d:da:0a:a8:65:08:a8:c3:2c:aa:34:
+ c7:a2:b9:00:45:6f:2e:69:6e:90:ee:9b:a2:f6:20:
+ 0d:75:17:c2:33:e0:59:2c:7d:d6:3d:23:34:0e:e6:
+ e0:49:74:3b:21:04:9f:6b:25:92:1a:2e:0f:e5:4a:
+ 0a:96:85:0d:69:dc:ab:31:23:19:b7:d0:54:e6:18:
+ c6:a1:ef:c6:e1:8b:da:a4:c2:78:7a:61:19:d7:83:
+ 5f:81:34:37:3e:1a:e2:b4:56:64:eb:db:af:7c:83:
+ c7:67:58:f1:69:c4:02:3a:05:1c:d9:56:5c:32:32:
+ bd:a7:e9:5f:82:b3:bb:1e:a6:e8:9c:86:86:ee:de:
+ 9b:19:d7:19:4f:89:cf:98:76:81:6d:dc:10:7d:d3:
+ 92:b8:7b:0d:c8:2f:2d:fc:ee:d7:68:fb:d5:87:7e:
+ 64:9a:32:73:57:58:5b:31:fc:da:d3:2c:2c:22:1d:
+ d6:db:71:a6:58:0b:84:0d:28:de:82:ad:d1:4e:2c:
+ 4b:b4:df:1d:78:34:59:52:a3:16:bd:0b:77:26:4d:
+ 4b:6f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ E9:AC:73:09:B6:86:CD:95:42:29:5D:E5:EC:C7:99:29:12:91:8C:53
+ X509v3 Authority Key Identifier:
+ keyid:E9:AC:73:09:B6:86:CD:95:42:29:5D:E5:EC:C7:99:29:12:91:8C:53
+
+ 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
+ 76:62:2d:4c:94:4e:63:cb:7f:35:52:08:e2:8a:f3:d1:03:55:
+ 31:f4:e8:e0:79:68:23:f0:19:d5:7f:b2:dd:27:0a:a2:bb:6c:
+ f3:85:ae:48:83:3c:37:7e:62:69:e9:af:e0:4d:60:f0:8b:bf:
+ 1b:2c:da:90:10:fc:8c:83:b1:55:46:a6:fe:d1:d1:21:6f:91:
+ e1:cc:d6:c6:8c:1e:b1:03:e5:d7:5b:5f:3c:a7:2d:16:a1:71:
+ 54:e1:8a:4b:62:61:18:42:b1:f4:ec:6e:33:5a:3b:52:2a:8e:
+ 1a:60:75:73:89:78:72:86:9f:42:82:e5:d7:0e:5c:ce:36:a7:
+ 2d:8e:78:0a:e9:95:2d:72:d2:42:6f:b6:7c:7e:28:29:2d:85:
+ 3c:46:ab:6f:04:a8:f4:a2:ec:c4:24:7e:7a:a9:96:ec:b3:49:
+ 8b:ec:2a:00:88:c0:a6:50:01:a5:f0:df:ef:1c:6c:f8:bf:8e:
+ 64:ab:ff:43:bf:05:ce:82:b6:d4:cc:30:47:d8:74:7f:4e:4c:
+ dc:cc:a6:92:e3:96:37:97:b1:03:27:93:38:62:4d:b7:ae:fe:
+ a2:2b:61:05:32:27:28:27:c3:1f:e9:50:91:0a:4a:4b:ca:a3:
+ b0:8e:d4:56:30:ad:e8:76:49:e4:0e:36:83:15:22:8a:bc:59:
+ 27:1c:62:f3
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALg8r4htXpZ+WJAJXUBU
+EU9V/7vnlBu619+5R8P/hHEi2qiJ5phxS67YwRnfT2m/wj3aCqhlCKjDLKo0x6K5
+AEVvLmlukO6bovYgDXUXwjPgWSx91j0jNA7m4El0OyEEn2slkhouD+VKCpaFDWnc
+qzEjGbfQVOYYxqHvxuGL2qTCeHphGdeDX4E0Nz4a4rRWZOvbr3yDx2dY8WnEAjoF
+HNlWXDIyvafpX4Kzux6m6JyGhu7emxnXGU+Jz5h2gW3cEH3Tkrh7DcgvLfzu12j7
+1Yd+ZJoyc1dYWzH82tMsLCId1ttxplgLhA0o3oKt0U4sS7TfHXg0WVKjFr0LdyZN
+S28CAwEAAaOByzCByDAdBgNVHQ4EFgQU6axzCbaGzZVCKV3l7MeZKRKRjFMwHwYD
+VR0jBBgwFoAU6axzCbaGzZVCKV3l7MeZKRKRjFMwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB2Yi1MlE5j
+y381UgjiivPRA1Ux9OjgeWgj8BnVf7LdJwqiu2zzha5Igzw3fmJp6a/gTWDwi78b
+LNqQEPyMg7FVRqb+0dEhb5HhzNbGjB6xA+XXW188py0WoXFU4YpLYmEYQrH07G4z
+WjtSKo4aYHVziXhyhp9CguXXDlzONqctjngK6ZUtctJCb7Z8figpLYU8RqtvBKj0
+ouzEJH56qZbss0mL7CoAiMCmUAGl8N/vHGz4v45kq/9DvwXOgrbUzDBH2HR/Tkzc
+zKaS45Y3l7EDJ5M4Yk23rv6iK2EFMicoJ8Mf6VCRCkpLyqOwjtRWMK3odknkDjaD
+FSKKvFknHGLz
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+U1VDQ0VTUw==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem b/chromium/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem
new file mode 100644
index 00000000000..dd82071d7b0
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem
@@ -0,0 +1,280 @@
+[Created by: generate-target-signed-with-md5.py]
+
+Certificate chain with an intermediary that uses MD5 to sign the target
+certificate. This is expected to fail because MD5 is too weak.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c5:55:ac:42:f6:5f:21:93:e6:93:07:6a:dc:a0:
+ 4c:66:21:42:8c:2e:f4:d0:61:30:ac:bf:9a:3b:b3:
+ 59:21:e4:29:9f:33:5d:5e:6f:a1:de:4d:c2:b3:22:
+ f3:16:0a:81:f0:51:90:f8:45:e0:5e:9b:7d:3a:e4:
+ 60:d2:a8:a1:b1:2f:13:8c:41:dc:c3:58:1d:66:6c:
+ 67:13:5e:21:51:f7:49:21:5d:29:dd:91:fd:a7:36:
+ 10:bb:d1:30:71:16:ee:4b:7f:1b:ba:02:c3:79:0c:
+ 4d:e7:98:59:b1:0f:c8:61:a3:f9:5c:fa:03:08:29:
+ 41:af:60:50:b8:80:3b:f6:fe:75:0f:bb:d4:92:d9:
+ f5:3a:25:41:12:f1:cd:ad:2c:08:c9:f9:a3:17:78:
+ 86:2a:18:13:b1:20:15:83:de:04:ac:2a:c6:42:5c:
+ d1:f9:e6:12:1c:1b:51:7a:2c:cd:40:94:c8:76:17:
+ d7:20:4a:f8:e4:c8:3c:57:7c:c8:c6:6d:bd:2a:5e:
+ a9:03:7e:14:9d:a5:4e:1f:b1:aa:94:2f:64:34:6e:
+ d1:cb:5f:41:84:f7:86:95:04:90:ce:77:27:f6:7d:
+ 8e:5b:9c:52:7a:5e:dd:e2:f6:e6:fd:10:8d:e2:7d:
+ 34:f0:54:1b:c2:54:45:fe:01:97:90:f7:33:03:db:
+ 0c:bd
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ DF:16:6B:0E:36:1E:E4:F1:15:A2:3A:9E:07:4A:F9:6D:81:82:7A:D5
+ X509v3 Authority Key Identifier:
+ keyid:E2:CD:39:61:AF:F5:B9:CE:D9:7C:36:97:5D:28:36:61:63:0B:CA:49
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: md5WithRSAEncryption
+ 35:9f:32:4a:5f:2e:b6:3f:d4:03:97:8f:0d:70:8b:5a:8d:62:
+ 30:77:44:37:e0:85:5f:e8:fc:8a:f6:e2:cb:df:05:f3:08:2d:
+ 05:dc:bb:16:1f:69:06:2e:4b:2b:1b:6f:a1:b3:77:02:1e:7d:
+ 49:da:a0:d9:6a:ac:bd:5e:4d:65:10:51:ee:e6:2a:33:e5:b9:
+ b5:5b:83:67:3d:c1:9d:c5:a6:c4:6e:7b:3b:ad:88:02:dc:ef:
+ 98:c4:cf:1d:cc:ab:45:23:53:27:ee:7f:87:f4:e6:13:5a:3a:
+ 3d:30:1e:66:b7:6e:67:e7:ae:1b:c6:4e:26:14:0f:cf:71:8a:
+ 0c:ee:60:14:25:45:a1:4b:2f:46:73:41:11:59:9f:e7:9f:12:
+ 01:7e:dc:e4:68:96:31:a5:c0:cc:03:fc:e3:b0:c5:c2:65:57:
+ ef:48:a4:85:eb:6e:d9:95:2f:d8:b1:48:46:b1:d5:30:84:d6:
+ c0:aa:32:41:a2:8a:be:35:b4:97:e5:1d:f7:36:f4:47:36:68:
+ f9:6b:10:39:1f:13:e8:b3:f5:7c:57:71:df:a8:e8:40:28:ed:
+ 65:3a:ba:7a:98:fa:4d:14:e9:5e:f5:a3:92:03:aa:d5:0b:72:
+ 29:7e:30:80:03:40:b9:eb:72:e2:ac:43:3a:2c:f6:c9:a3:13:
+ c7:c9:05:b9
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQQFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFVaxC
+9l8hk+aTB2rcoExmIUKMLvTQYTCsv5o7s1kh5CmfM11eb6HeTcKzIvMWCoHwUZD4
+ReBem3065GDSqKGxLxOMQdzDWB1mbGcTXiFR90khXSndkf2nNhC70TBxFu5Lfxu6
+AsN5DE3nmFmxD8hho/lc+gMIKUGvYFC4gDv2/nUPu9SS2fU6JUES8c2tLAjJ+aMX
+eIYqGBOxIBWD3gSsKsZCXNH55hIcG1F6LM1AlMh2F9cgSvjkyDxXfMjGbb0qXqkD
+fhSdpU4fsaqUL2Q0btHLX0GE94aVBJDOdyf2fY5bnFJ6Xt3i9ub9EI3ifTTwVBvC
+VEX+AZeQ9zMD2wy9AgMBAAGjgekwgeYwHQYDVR0OBBYEFN8Waw42HuTxFaI6ngdK
++W2BgnrVMB8GA1UdIwQYMBaAFOLNOWGv9bnO2Xw2l10oNmFjC8pJMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQQFAAOCAQEANZ8ySl8utj/UA5ePDXCL
+Wo1iMHdEN+CFX+j8ivbiy98F8wgtBdy7Fh9pBi5LKxtvobN3Ah59Sdqg2WqsvV5N
+ZRBR7uYqM+W5tVuDZz3BncWmxG57O62IAtzvmMTPHcyrRSNTJ+5/h/TmE1o6PTAe
+ZrduZ+euG8ZOJhQPz3GKDO5gFCVFoUsvRnNBEVmf558SAX7c5GiWMaXAzAP847DF
+wmVX70ikhetu2ZUv2LFIRrHVMITWwKoyQaKKvjW0l+Ud9zb0RzZo+WsQOR8T6LP1
+fFdx36joQCjtZTq6epj6TRTpXvWjkgOq1QtyKX4wgANAuety4qxDOiz2yaMTx8kF
+uQ==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b0:67:b9:ee:01:e6:50:d2:01:11:81:3a:70:41:
+ c3:36:af:95:28:11:ed:90:02:37:9a:f9:fe:23:38:
+ d6:72:c5:38:da:62:a4:84:dc:50:12:0e:03:e2:34:
+ 4d:d8:88:b7:aa:09:31:14:71:b5:e5:f9:80:06:c5:
+ 72:8a:1a:dd:72:a8:c9:76:79:3b:14:34:0a:bc:7a:
+ d4:a6:75:58:c0:f1:77:d7:23:bb:5b:a1:54:d2:cf:
+ ec:0f:b7:ab:53:01:7d:1d:54:40:68:12:fb:75:68:
+ 56:d5:0d:5c:00:de:81:5f:a5:14:fd:5d:77:b8:1f:
+ 3e:ee:84:99:a5:b5:0d:13:9a:fe:cf:b8:b0:e1:4c:
+ db:87:64:e1:36:a0:04:02:5d:fd:58:9e:e5:70:85:
+ 63:65:50:93:b8:3e:6c:85:10:67:bc:3d:e2:77:38:
+ b2:75:b5:e3:57:55:b2:44:68:3c:ab:65:2b:cb:8b:
+ 11:29:d5:7c:b8:24:88:25:d1:80:0b:04:3f:0e:e9:
+ 1d:79:db:39:7d:ab:81:67:fb:cf:ae:a3:da:ea:f1:
+ 12:ac:cd:87:96:5c:ed:fd:db:bc:e2:3a:4e:33:05:
+ af:1a:d3:03:85:ec:74:23:04:12:7e:62:a1:56:4c:
+ 45:9c:95:80:55:b6:2f:13:82:27:24:c4:a0:68:33:
+ e6:71
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ E2:CD:39:61:AF:F5:B9:CE:D9:7C:36:97:5D:28:36:61:63:0B:CA:49
+ X509v3 Authority Key Identifier:
+ keyid:BD:2A:00:54:BB:89:72:89:4F:27:75:12:AA:89:38:AB:A0:06:F7:D1
+
+ 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
+ 3d:9a:bd:e5:a7:4d:e4:0e:ea:6a:34:da:9e:48:c7:8a:e4:34:
+ 6c:19:fe:d0:2f:2f:7b:01:14:46:3a:45:d7:a7:46:6e:83:bb:
+ 54:cc:4e:af:cf:ef:fc:6d:90:e4:54:38:94:2d:cb:55:85:bd:
+ 1d:9f:9e:cd:ac:68:b3:7f:ed:bb:1f:30:30:14:15:ba:17:e4:
+ 62:db:6b:70:5a:1f:c2:e7:43:c6:30:d0:0f:be:78:06:4e:09:
+ 0b:00:96:63:d2:14:84:93:88:5d:e6:bf:93:1c:e9:18:9d:df:
+ 7d:db:34:39:e5:94:f8:c9:84:b6:ff:a0:e7:5c:51:5e:ba:40:
+ 82:5a:7e:64:ca:bf:e3:0e:c8:76:0b:5c:be:29:b1:62:79:18:
+ b2:d6:c3:ee:d0:05:61:96:be:a8:dc:c5:65:72:cc:f7:f8:6e:
+ 27:85:c3:9b:68:6d:3d:a5:e5:34:20:ff:19:12:62:7c:5d:b8:
+ 95:8f:a8:a8:a8:90:41:e0:83:f1:e3:3f:67:26:bc:b1:6c:76:
+ b1:5e:25:60:49:7d:78:bf:bb:11:22:43:ac:d3:5f:c0:c9:73:
+ 76:d5:9c:97:b0:ec:17:36:0d:4b:83:3e:77:d0:84:62:76:98:
+ af:6d:42:ac:cb:40:bb:04:1d:9e:0a:a3:97:11:f2:b0:3f:6b:
+ b6:fd:ff:da
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsGe57gHm
+UNIBEYE6cEHDNq+VKBHtkAI3mvn+IzjWcsU42mKkhNxQEg4D4jRN2Ii3qgkxFHG1
+5fmABsVyihrdcqjJdnk7FDQKvHrUpnVYwPF31yO7W6FU0s/sD7erUwF9HVRAaBL7
+dWhW1Q1cAN6BX6UU/V13uB8+7oSZpbUNE5r+z7iw4Uzbh2ThNqAEAl39WJ7lcIVj
+ZVCTuD5shRBnvD3idziydbXjV1WyRGg8q2Ury4sRKdV8uCSIJdGACwQ/Dukdeds5
+fauBZ/vPrqPa6vESrM2Hllzt/du84jpOMwWvGtMDhex0IwQSfmKhVkxFnJWAVbYv
+E4InJMSgaDPmcQIDAQABo4HLMIHIMB0GA1UdDgQWBBTizTlhr/W5ztl8NpddKDZh
+YwvKSTAfBgNVHSMEGDAWgBS9KgBUu4lyiU8ndRKqiTiroAb30TA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AD2aveWnTeQO6mo02p5Ix4rkNGwZ/tAvL3sBFEY6RdenRm6Du1TMTq/P7/xtkORU
+OJQty1WFvR2fns2saLN/7bsfMDAUFboX5GLba3BaH8LnQ8Yw0A++eAZOCQsAlmPS
+FISTiF3mv5Mc6Rid333bNDnllPjJhLb/oOdcUV66QIJafmTKv+MOyHYLXL4psWJ5
+GLLWw+7QBWGWvqjcxWVyzPf4bieFw5tobT2l5TQg/xkSYnxduJWPqKiokEHgg/Hj
+P2cmvLFsdrFeJWBJfXi/uxEiQ6zTX8DJc3bVnJew7Bc2DUuDPnfQhGJ2mK9tQqzL
+QLsEHZ4Ko5cR8rA/a7b9/9o=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a0:9b:ff:8c:74:7b:c9:1e:3c:34:5b:7c:c0:35:
+ a4:88:6a:26:ed:0b:52:e9:58:e6:b5:bd:fd:f6:ae:
+ 0f:08:09:24:ef:62:fb:1c:61:7f:8a:ca:5f:d4:b5:
+ 2b:45:c2:21:1f:1a:a1:ef:f9:d8:0d:be:31:88:bd:
+ d7:35:8e:0d:de:e8:be:60:63:f6:3c:6a:cd:e7:1d:
+ 78:36:86:91:a1:e9:5c:2d:c6:9a:95:b9:e7:c3:66:
+ 6f:b5:0c:4b:aa:9a:51:ea:b3:a3:9e:57:d6:17:c9:
+ ae:4c:3f:32:ef:28:5a:99:6a:dc:50:54:f5:cc:80:
+ 51:76:6c:50:4d:52:01:45:92:af:a2:ca:a7:c1:9e:
+ 76:24:29:9c:d1:73:95:0a:a1:16:73:0f:56:9d:e8:
+ fe:c2:bb:e4:64:99:a3:d4:46:7d:7a:f7:25:d3:49:
+ c0:da:38:18:78:9c:2a:40:60:c2:b8:98:8a:84:ed:
+ d2:84:e0:39:a6:31:64:36:2a:59:ca:ba:dc:c2:6d:
+ a2:ac:1a:93:58:27:76:95:ea:5d:12:8d:7a:a5:b6:
+ 50:3b:1c:25:3f:75:ee:eb:db:12:78:67:47:0d:86:
+ 49:77:ce:f5:d0:37:03:55:eb:98:93:bf:f1:10:5b:
+ 87:aa:a1:ef:76:30:e1:e4:77:54:b1:52:e8:c9:81:
+ 4d:5b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ BD:2A:00:54:BB:89:72:89:4F:27:75:12:AA:89:38:AB:A0:06:F7:D1
+ X509v3 Authority Key Identifier:
+ keyid:BD:2A:00:54:BB:89:72:89:4F:27:75:12:AA:89:38:AB:A0:06:F7:D1
+
+ 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
+ 43:7c:24:ea:dc:11:3a:08:d7:6e:dd:8c:b9:21:1a:d7:88:d8:
+ f1:4c:90:a0:b7:67:a7:3c:d2:8d:a4:68:50:34:db:a4:f1:69:
+ d4:e0:8b:4c:b3:39:62:11:b5:4a:df:3a:60:87:eb:f6:79:2c:
+ ef:4d:67:91:93:5f:b3:d1:63:1b:2e:12:74:4e:e2:60:d8:c1:
+ 1f:e8:b2:5d:d4:56:2d:85:27:64:36:b0:e4:17:5e:d1:9c:ce:
+ 56:e2:f4:68:d3:80:6f:44:d6:e4:7b:5b:c6:5e:3e:ea:69:9d:
+ 97:4b:0d:83:3b:a7:52:f5:78:96:9f:af:15:e2:bf:59:a7:5f:
+ 5b:d4:21:d1:49:b2:f4:b5:26:b1:b1:cf:74:d0:ba:26:b1:2e:
+ 0e:ef:74:29:ed:f5:35:18:2f:cc:8b:80:39:41:8f:ea:ab:81:
+ 6a:89:71:b8:22:e6:bc:e5:33:34:f7:dd:6c:37:0a:e1:21:a7:
+ 7f:2d:29:f6:aa:02:d8:47:3f:a6:3d:0e:85:20:59:f8:5f:49:
+ 06:f7:3a:9a:b8:d9:3a:08:ce:9a:60:aa:dd:72:07:1e:bb:8f:
+ 86:fd:6a:3e:dc:4a:3f:5e:c2:b7:e6:0e:89:75:08:89:e3:bf:
+ 2b:6c:cc:02:63:e0:1c:04:21:79:64:c0:7c:89:73:2b:e9:85:
+ 49:80:5e:f4
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKCb/4x0e8kePDRbfMA1
+pIhqJu0LUulY5rW9/fauDwgJJO9i+xxhf4rKX9S1K0XCIR8aoe/52A2+MYi91zWO
+Dd7ovmBj9jxqzecdeDaGkaHpXC3GmpW558Nmb7UMS6qaUeqzo55X1hfJrkw/Mu8o
+Wplq3FBU9cyAUXZsUE1SAUWSr6LKp8GediQpnNFzlQqhFnMPVp3o/sK75GSZo9RG
+fXr3JdNJwNo4GHicKkBgwriYioTt0oTgOaYxZDYqWcq63MJtoqwak1gndpXqXRKN
+eqW2UDscJT917uvbEnhnRw2GSXfO9dA3A1XrmJO/8RBbh6qh73Yw4eR3VLFS6MmB
+TVsCAwEAAaOByzCByDAdBgNVHQ4EFgQUvSoAVLuJcolPJ3USqok4q6AG99EwHwYD
+VR0jBBgwFoAUvSoAVLuJcolPJ3USqok4q6AG99EwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBDfCTq3BE6
+CNdu3Yy5IRrXiNjxTJCgt2enPNKNpGhQNNuk8WnU4ItMszliEbVK3zpgh+v2eSzv
+TWeRk1+z0WMbLhJ0TuJg2MEf6LJd1FYthSdkNrDkF17RnM5W4vRo04BvRNbke1vG
+Xj7qaZ2XSw2DO6dS9XiWn68V4r9Zp19b1CHRSbL0tSaxsc900LomsS4O73Qp7fU1
+GC/Mi4A5QY/qq4FqiXG4Iua85TM0991sNwrhIad/LSn2qgLYRz+mPQ6FIFn4X0kG
+9zqauNk6CM6aYKrdcgceu4+G/Wo+3Eo/XsK35g6JdQiJ478rbMwCY+AcBCF5ZMB8
+iXMr6YVJgF70
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem b/chromium/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem
new file mode 100644
index 00000000000..f02ac62135d
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem
@@ -0,0 +1,284 @@
+[Created by: ./generate-target-unknown-critical-extension.py]
+
+Certificate chain with 1 intermediary and a trusted root. The intermediary
+has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as critical.
+Verifying this certificate chain is expected to fail because there is an
+unrecognized critical extension.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c9:42:1d:0f:19:4b:d8:78:b9:3f:4d:43:a8:a9:
+ 92:67:ed:f3:55:a4:f5:9e:f4:d0:21:3c:25:cc:28:
+ 1d:db:22:5c:c0:eb:e8:78:fe:6c:71:72:ed:0c:cd:
+ 76:80:44:dc:72:d1:92:29:7d:e8:7f:e0:42:60:d6:
+ cb:b1:53:06:0d:6c:8b:f4:d3:ce:42:af:34:bc:57:
+ 63:34:dd:b2:00:26:3f:a9:7f:c8:ce:f6:1a:66:75:
+ db:7c:b6:57:ef:ee:3d:e7:d7:b8:38:3a:83:5d:7a:
+ 63:1f:91:c4:f1:15:da:9b:e9:f7:ef:d5:d6:26:16:
+ 96:c1:94:55:3f:3e:67:13:26:bf:3d:0c:93:ab:1b:
+ a2:58:10:38:60:11:18:15:c5:3c:db:71:62:ef:27:
+ 1f:a9:62:61:1f:f6:55:51:d9:7c:2d:b6:e3:2d:c3:
+ 86:2b:cd:5c:30:d3:a0:0d:a4:e4:34:fb:bb:59:09:
+ d5:7b:8f:b2:49:10:0d:d7:2d:0e:34:72:25:7b:b4:
+ 0e:e9:fd:cb:ce:50:ee:d2:71:40:14:3d:06:ad:71:
+ 52:43:cc:e9:77:4e:c4:8c:af:8c:a2:41:40:4a:82:
+ 82:83:a2:58:e3:5e:40:fa:74:f0:fb:bd:46:aa:55:
+ 9d:6d:5b:db:af:6a:1f:7c:46:cf:1a:1f:d3:17:c3:
+ 02:2f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 07:DB:E2:A1:15:3D:67:0C:54:ED:D5:22:AD:DE:59:73:9E:0F:F5:24
+ X509v3 Authority Key Identifier:
+ keyid:07:D2:5E:3F:28:F7:AD:46:16:25:D0:4D:DD:6D:77:7B:26:81:89:85
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ 1.2.3.4: critical
+ ....
+ Signature Algorithm: sha256WithRSAEncryption
+ 66:78:33:4b:09:c3:20:05:e2:d2:a3:7f:90:2f:96:15:b8:d0:
+ ca:7e:97:c6:12:53:4b:18:92:03:77:b6:2c:8b:57:8e:84:7d:
+ 14:ee:df:cc:99:0d:f9:2e:21:dd:ca:4d:00:77:87:88:4d:13:
+ 28:36:4a:88:82:52:d2:b8:1d:75:67:1f:b5:0a:ea:bd:6a:b8:
+ 98:79:ea:cf:6e:2c:5f:21:94:e4:a9:29:d5:37:87:58:6a:d7:
+ 5b:0b:f5:35:59:c9:68:dd:f9:e7:c6:67:1a:ef:26:17:cf:89:
+ e7:18:8c:be:41:c4:07:d3:b7:1a:20:44:4f:20:12:8c:2e:5a:
+ 39:7c:8b:f3:12:f7:bd:b6:f1:7b:8c:48:7f:c5:29:7f:7a:9e:
+ 1e:28:13:08:36:56:ca:8d:17:f2:37:ce:59:0a:e7:ca:19:90:
+ c7:c8:b4:45:ab:3b:f7:0e:10:db:81:4b:2d:74:05:46:ab:5c:
+ 7e:c2:88:83:87:09:4d:5a:a3:40:56:f5:d5:da:fd:a2:2d:99:
+ 8c:d1:bf:0b:d0:8c:ce:79:12:0c:37:fc:b2:08:68:b2:fe:5e:
+ cc:3e:99:85:40:74:27:88:7f:f6:43:0f:60:dd:b7:6e:31:e3:
+ d4:39:87:8e:b1:cf:2d:b7:2f:bb:f9:ec:f8:86:96:1e:fc:68:
+ 0d:45:21:2c
+-----BEGIN CERTIFICATE-----
+MIIDnTCCAoWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJQh0P
+GUvYeLk/TUOoqZJn7fNVpPWe9NAhPCXMKB3bIlzA6+h4/mxxcu0MzXaARNxy0ZIp
+feh/4EJg1suxUwYNbIv0085CrzS8V2M03bIAJj+pf8jO9hpmddt8tlfv7j3n17g4
+OoNdemMfkcTxFdqb6ffv1dYmFpbBlFU/PmcTJr89DJOrG6JYEDhgERgVxTzbcWLv
+Jx+pYmEf9lVR2XwttuMtw4YrzVww06ANpOQ0+7tZCdV7j7JJEA3XLQ40ciV7tA7p
+/cvOUO7ScUAUPQatcVJDzOl3TsSMr4yiQUBKgoKDoljjXkD6dPD7vUaqVZ1tW9uv
+ah98Rs8aH9MXwwIvAgMBAAGjgfkwgfYwHQYDVR0OBBYEFAfb4qEVPWcMVO3VIq3e
+WXOeD/UkMB8GA1UdIwQYMBaAFAfSXj8o961GFiXQTd1td3smgYmFMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjAOBgMqAwQBAf8EBAECAwQwDQYJKoZIhvcNAQELBQADggEB
+AGZ4M0sJwyAF4tKjf5AvlhW40Mp+l8YSU0sYkgN3tiyLV46EfRTu38yZDfkuId3K
+TQB3h4hNEyg2SoiCUtK4HXVnH7UK6r1quJh56s9uLF8hlOSpKdU3h1hq11sL9TVZ
+yWjd+efGZxrvJhfPiecYjL5BxAfTtxogRE8gEowuWjl8i/MS97228XuMSH/FKX96
+nh4oEwg2VsqNF/I3zlkK58oZkMfItEWrO/cOENuBSy10BUarXH7CiIOHCU1ao0BW
+9dXa/aItmYzRvwvQjM55Egw3/LIIaLL+Xsw+mYVAdCeIf/ZDD2Ddt24x49Q5h46x
+zy23L7v57PiGlh78aA1FISw=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e1:3b:e0:9e:b3:37:a6:d2:5d:5a:cf:1d:6c:d4:
+ e7:9d:92:0e:29:b6:da:7e:48:32:ea:dd:a8:6e:a5:
+ 4f:d4:07:23:be:f5:b2:e2:e9:57:1b:a1:bc:67:5a:
+ 27:15:9d:f7:51:07:23:d9:0a:0f:21:36:4b:b1:c3:
+ 48:71:f5:f8:67:6f:a4:9c:54:8b:e8:d2:79:da:6e:
+ 70:06:b8:ae:b5:6f:82:ab:89:5a:68:19:56:c7:8a:
+ 93:25:f9:4b:7e:8b:de:2f:1a:92:c4:be:c4:9f:ea:
+ 34:fe:95:f5:74:ab:fc:47:8b:34:7d:28:d3:7a:7b:
+ 29:70:3e:aa:b9:d9:be:53:fe:79:3a:ea:79:c7:d7:
+ 1d:b1:c3:47:e6:7d:8e:ed:40:2a:47:d9:71:5f:c2:
+ 6c:cb:52:be:1b:83:01:de:06:97:d4:98:ea:37:67:
+ f6:fb:67:69:c7:b1:fe:07:ad:be:0a:f8:c8:a8:5d:
+ 98:0b:f6:02:7b:cb:19:f6:23:58:79:f9:d3:8c:a5:
+ 09:73:c9:2b:ae:76:33:3f:2d:a9:49:93:39:89:92:
+ bc:5e:27:1c:ae:a6:29:43:97:a1:04:d0:6c:b6:b6:
+ b8:c3:62:5e:43:7c:ca:27:50:e2:91:da:bb:cc:c6:
+ e5:7b:5a:31:62:77:a6:4d:6a:ee:84:ea:7a:87:de:
+ a9:bd
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 07:D2:5E:3F:28:F7:AD:46:16:25:D0:4D:DD:6D:77:7B:26:81:89:85
+ X509v3 Authority Key Identifier:
+ keyid:C8:0F:45:73:03:B2:2C:B8:35:14:0F:C4:D7:4B:E4:E2:9D:B2:AB:CE
+
+ 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
+ 2a:af:ec:1b:fc:c9:ad:bf:ad:97:8d:ed:f4:44:87:7f:72:86:
+ c0:4d:85:dd:eb:6c:d3:c7:17:df:11:0a:f5:e5:2b:c2:53:41:
+ 58:73:66:da:29:8a:43:af:5e:24:b2:16:26:b6:89:7e:4a:6f:
+ 46:13:05:c4:3f:13:6c:ed:b8:37:a7:a9:f6:c9:c8:b9:b3:a1:
+ 7c:eb:99:57:fb:8d:12:c5:47:ff:1e:02:b2:47:dc:e9:6f:41:
+ 17:0a:3b:ff:ba:14:76:cc:14:35:ec:71:b0:1a:d4:eb:b0:6c:
+ a3:96:eb:7d:50:59:d7:01:a0:ee:67:b8:c8:b6:ed:78:02:b1:
+ 0b:72:9c:ea:c3:3b:14:3d:89:fc:89:c2:af:6c:18:ae:b0:13:
+ 31:04:a2:89:4f:a6:99:58:00:c6:00:e1:39:79:d4:31:0b:0f:
+ d5:92:86:a2:e7:ec:c6:b8:f2:62:21:bb:0d:d5:91:b8:f2:5f:
+ db:dc:b1:b2:b2:28:fd:d5:14:54:a6:cf:8d:bd:33:ca:22:27:
+ 72:d8:27:85:03:21:7f:8e:4f:2d:e6:bf:22:08:86:03:a8:f3:
+ 9f:42:2f:81:8f:1e:44:39:e3:23:b2:9d:3d:64:7e:e2:b3:93:
+ 8d:46:a0:b7:08:4e:d5:e6:14:af:1d:5d:b6:74:7c:91:36:37:
+ 0c:c0:ab:14
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4TvgnrM3
+ptJdWs8dbNTnnZIOKbbafkgy6t2obqVP1AcjvvWy4ulXG6G8Z1onFZ33UQcj2QoP
+ITZLscNIcfX4Z2+knFSL6NJ52m5wBriutW+Cq4laaBlWx4qTJflLfoveLxqSxL7E
+n+o0/pX1dKv8R4s0fSjTenspcD6qudm+U/55Oup5x9cdscNH5n2O7UAqR9lxX8Js
+y1K+G4MB3gaX1JjqN2f2+2dpx7H+B62+CvjIqF2YC/YCe8sZ9iNYefnTjKUJc8kr
+rnYzPy2pSZM5iZK8XiccrqYpQ5ehBNBstra4w2JeQ3zKJ1Dikdq7zMble1oxYnem
+TWruhOp6h96pvQIDAQABo4HLMIHIMB0GA1UdDgQWBBQH0l4/KPetRhYl0E3dbXd7
+JoGJhTAfBgNVHSMEGDAWgBTID0VzA7IsuDUUD8TXS+TinbKrzjA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+ACqv7Bv8ya2/rZeN7fREh39yhsBNhd3rbNPHF98RCvXlK8JTQVhzZtopikOvXiSy
+Fia2iX5Kb0YTBcQ/E2ztuDenqfbJyLmzoXzrmVf7jRLFR/8eArJH3OlvQRcKO/+6
+FHbMFDXscbAa1OuwbKOW631QWdcBoO5nuMi27XgCsQtynOrDOxQ9ifyJwq9sGK6w
+EzEEoolPpplYAMYA4Tl51DELD9WShqLn7Ma48mIhuw3VkbjyX9vcsbKyKP3VFFSm
+z429M8oiJ3LYJ4UDIX+OTy3mvyIIhgOo859CL4GPHkQ54yOynT1kfuKzk41GoLcI
+TtXmFK8dXbZ0fJE2NwzAqxQ=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:dc:6a:1a:05:36:f1:a3:7c:28:e9:97:2f:7b:85:
+ d5:c1:91:33:0a:72:2d:bb:45:ae:c6:29:54:22:05:
+ c2:e9:f4:be:f2:39:ec:e0:64:66:1d:e3:c9:42:3e:
+ 6c:c8:3b:65:0a:e4:2c:74:e4:c9:17:c8:8b:27:6e:
+ c0:4c:9a:b4:85:ae:ff:3f:e3:1e:d0:21:1c:8b:84:
+ e0:3b:f6:59:00:a7:ab:59:f3:58:67:d7:af:97:74:
+ a9:b1:1f:78:80:ad:e3:09:31:81:c2:11:55:10:d0:
+ 93:ca:eb:de:a7:72:76:09:33:6a:89:f9:51:b1:de:
+ ca:4a:48:e8:9f:1c:5f:df:bc:7d:a7:f5:27:6b:77:
+ a3:53:e5:c3:e4:3d:9e:82:72:9e:d2:1b:76:52:8c:
+ f0:53:b6:98:5f:6c:54:1b:da:9a:72:14:ee:c3:51:
+ b4:c7:6b:f0:75:b2:2c:6e:b4:b7:29:54:92:ab:69:
+ 57:af:3c:6d:96:e8:05:c8:a4:d0:7a:c2:42:7d:8b:
+ 7f:3c:8f:9d:1d:c1:35:af:41:7b:f5:0e:60:88:72:
+ 90:22:ac:37:2f:7b:b4:47:01:62:b8:fe:73:4b:d2:
+ 7b:56:8d:b2:37:d3:18:2f:dc:fb:d1:fb:e9:14:19:
+ b1:d8:76:eb:34:d2:c0:40:a8:22:68:33:44:a7:84:
+ 90:e1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ C8:0F:45:73:03:B2:2C:B8:35:14:0F:C4:D7:4B:E4:E2:9D:B2:AB:CE
+ X509v3 Authority Key Identifier:
+ keyid:C8:0F:45:73:03:B2:2C:B8:35:14:0F:C4:D7:4B:E4:E2:9D:B2:AB:CE
+
+ 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
+ 54:39:78:5b:30:97:aa:99:fb:e5:0a:39:27:2a:ea:ad:9f:37:
+ 3e:aa:5a:b8:c4:51:66:83:6e:36:5c:c3:1b:da:de:cd:a7:6e:
+ bd:55:47:7c:3e:53:12:6a:51:02:13:c2:98:03:32:b6:5b:d9:
+ 5e:26:b2:9a:d1:21:ca:39:cd:20:be:ad:d8:3a:23:a2:de:d7:
+ 18:b2:99:bb:d4:1a:82:43:7c:6e:20:3c:01:f1:22:5f:72:ac:
+ 43:9a:87:07:37:5d:a8:34:26:19:89:aa:f3:18:e3:ee:c6:67:
+ 43:49:64:e4:b3:d8:2c:11:8c:f7:8b:48:7f:fd:e1:6b:e9:a5:
+ 87:55:bf:f1:9d:54:fe:b5:7f:c4:5c:8b:08:cf:4f:47:21:58:
+ 06:5e:ab:40:be:b7:28:0c:27:55:82:6b:e8:17:5e:dd:f8:79:
+ 61:f2:7e:18:59:7a:24:7e:e3:08:3c:d9:d1:81:73:36:51:99:
+ a1:ea:bf:18:ff:94:40:d7:ff:5f:1a:8a:b1:ae:78:c1:91:7b:
+ 55:1a:d8:b1:91:02:b6:5e:94:32:84:5f:77:f8:89:89:00:5c:
+ 74:be:77:1b:95:3e:60:2d:6a:67:a3:e9:42:03:51:af:1f:10:
+ d8:21:6f:36:29:33:72:90:f4:7e:05:17:bb:a5:aa:fb:d6:56:
+ fc:40:2e:0e
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxqGgU28aN8KOmXL3uF
+1cGRMwpyLbtFrsYpVCIFwun0vvI57OBkZh3jyUI+bMg7ZQrkLHTkyRfIiyduwEya
+tIWu/z/jHtAhHIuE4Dv2WQCnq1nzWGfXr5d0qbEfeICt4wkxgcIRVRDQk8rr3qdy
+dgkzaon5UbHeykpI6J8cX9+8faf1J2t3o1Plw+Q9noJyntIbdlKM8FO2mF9sVBva
+mnIU7sNRtMdr8HWyLG60tylUkqtpV688bZboBcik0HrCQn2LfzyPnR3BNa9Be/UO
+YIhykCKsNy97tEcBYrj+c0vSe1aNsjfTGC/c+9H76RQZsdh26zTSwECoImgzRKeE
+kOECAwEAAaOByzCByDAdBgNVHQ4EFgQUyA9FcwOyLLg1FA/E10vk4p2yq84wHwYD
+VR0jBBgwFoAUyA9FcwOyLLg1FA/E10vk4p2yq84wNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBUOXhbMJeq
+mfvlCjknKuqtnzc+qlq4xFFmg242XMMb2t7Np269VUd8PlMSalECE8KYAzK2W9le
+JrKa0SHKOc0gvq3YOiOi3tcYspm71BqCQ3xuIDwB8SJfcqxDmocHN12oNCYZiarz
+GOPuxmdDSWTks9gsEYz3i0h//eFr6aWHVb/xnVT+tX/EXIsIz09HIVgGXqtAvrco
+DCdVgmvoF17d+Hlh8n4YWXokfuMIPNnRgXM2UZmh6r8Y/5RA1/9fGoqxrnjBkXtV
+GtixkQK2XpQyhF93+ImJAFx0vncblT5gLWpno+lCA1GvHxDYIW82KTNykPR+BRe7
+par71lb8QC4O
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem b/chromium/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem
new file mode 100644
index 00000000000..9d162b0dc55
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem
@@ -0,0 +1,281 @@
+[Created by: generate-target-wrong-signature.py]
+
+Certificate chain where the target has an incorrect signature. Everything
+else should check out, however the digital signature contained in the target
+certificate is wrong.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:cd:40:90:3b:6e:2e:d4:5d:a8:08:3e:d4:69:a0:
+ ec:3b:62:99:ec:81:30:1b:6e:d0:92:8b:bd:df:17:
+ 3a:fb:ce:bd:2a:32:5b:bb:5e:da:53:6c:b9:3d:4b:
+ a8:0b:12:41:61:d3:f9:3f:23:b9:71:3f:33:8a:bf:
+ 57:48:bd:99:e1:5d:c7:99:72:fd:ac:f4:4f:e1:cd:
+ ca:b8:0c:81:57:64:c5:56:1f:d9:ed:f8:df:c6:60:
+ 70:82:ee:b5:23:4a:a4:b5:d6:b4:e3:84:74:c9:ca:
+ da:d7:a7:11:51:c4:56:36:6c:b4:53:0e:35:e5:63:
+ fa:fd:75:df:72:01:31:17:e9:4d:35:8c:ae:a9:c1:
+ 3b:ae:ac:06:75:e0:77:2b:36:97:e5:bb:99:34:b6:
+ dc:f4:11:f6:2f:33:4e:db:4b:73:18:78:51:e6:12:
+ d1:be:94:2a:02:33:d9:bc:8a:36:dc:12:f0:2f:ae:
+ 57:4b:66:f0:ba:e6:1b:65:01:de:95:06:63:22:9b:
+ d0:58:42:55:99:34:06:ec:5a:00:f2:77:ed:71:23:
+ 24:7d:66:9a:e0:8c:d3:64:91:0a:a6:5b:36:43:36:
+ e3:07:33:a0:c3:fa:46:9c:3e:81:b2:2c:a6:51:92:
+ a7:7a:01:cb:95:1a:ea:cf:3c:fa:93:2d:81:5b:29:
+ 98:d5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 7F:F7:32:82:5E:B7:BD:FB:F8:64:38:93:2A:B1:6E:10:D6:4A:B4:28
+ X509v3 Authority Key Identifier:
+ keyid:E1:EB:47:46:C2:78:53:C4:B6:58:28:94:20:81:58:06:93:17:36:7F
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 80:dc:43:74:98:bf:da:2c:ea:5f:60:45:7f:d9:90:46:b1:f1:
+ ba:ea:9f:e3:39:40:4e:43:51:30:f1:a6:1a:c7:52:48:ed:de:
+ 2a:d8:6d:0d:b6:b2:69:a7:d7:e6:e9:4d:c3:73:c6:e5:3f:56:
+ 06:04:79:d2:a5:56:b7:a6:a5:a8:a2:2c:4f:0e:fa:fe:4f:39:
+ 11:5a:83:76:af:5e:0f:5d:df:0e:c6:c2:ea:79:19:04:92:a1:
+ c7:57:b2:16:83:c3:44:d1:47:89:e1:14:eb:1c:2c:f0:a9:63:
+ ed:31:fc:43:d0:93:c5:4c:7f:d3:68:6e:9b:81:2c:4f:70:71:
+ 90:af:98:ce:f6:73:97:5b:dc:13:d3:d9:01:8e:5f:34:a8:00:
+ 1d:71:89:a7:6e:12:f3:df:9d:4b:18:1f:0f:84:59:2b:7f:d0:
+ 05:5d:5f:e7:97:b7:26:ab:c1:12:87:19:28:6a:43:dc:c0:76:
+ 38:8a:fc:16:93:92:d3:2e:69:1f:9b:f3:1d:75:0d:32:89:f6:
+ ca:a4:8c:f2:c6:0a:17:e4:29:c3:bc:a6:33:df:c2:cd:42:97:
+ 28:65:1f:99:c9:6b:41:0e:4b:59:de:32:f2:1e:f7:62:88:66:
+ c6:d1:e7:9a:25:78:86:7d:e3:f3:4e:f7:18:11:ce:bc:37:56:
+ 78:f4:04:b1
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNQJA7
+bi7UXagIPtRpoOw7YpnsgTAbbtCSi73fFzr7zr0qMlu7XtpTbLk9S6gLEkFh0/k/
+I7lxPzOKv1dIvZnhXceZcv2s9E/hzcq4DIFXZMVWH9nt+N/GYHCC7rUjSqS11rTj
+hHTJytrXpxFRxFY2bLRTDjXlY/r9dd9yATEX6U01jK6pwTuurAZ14HcrNpflu5k0
+ttz0EfYvM07bS3MYeFHmEtG+lCoCM9m8ijbcEvAvrldLZvC65htlAd6VBmMim9BY
+QlWZNAbsWgDyd+1xIyR9ZprgjNNkkQqmWzZDNuMHM6DD+kacPoGyLKZRkqd6AcuV
+GurPPPqTLYFbKZjVAgMBAAGjgekwgeYwHQYDVR0OBBYEFH/3MoJet737+GQ4kyqx
+bhDWSrQoMB8GA1UdIwQYMBaAFOHrR0bCeFPEtlgolCCBWAaTFzZ/MD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAgNxDdJi/2izqX2BFf9mQ
+RrHxuuqf4zlATkNRMPGmGsdSSO3eKthtDbayaafX5ulNw3PG5T9WBgR50qVWt6al
+qKIsTw76/k85EVqDdq9eD13fDsbC6nkZBJKhx1eyFoPDRNFHieEU6xws8Klj7TH8
+Q9CTxUx/02hum4EsT3BxkK+YzvZzl1vcE9PZAY5fNKgAHXGJp24S89+dSxgfD4RZ
+K3/QBV1f55e3JqvBEocZKGpD3MB2OIr8FpOS0y5pH5vzHXUNMon2yqSM8sYKF+Qp
+w7ymM9/CzUKXKGUfmclrQQ5LWd4y8h73YohmxtHnmiV4hn3j8073GBHOvDdWePQE
+sQ==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c8:7f:42:62:ee:29:ef:bb:58:84:48:c3:aa:61:
+ ca:32:b1:ec:f0:e6:34:0b:f4:7e:d2:21:46:bb:bb:
+ b5:fb:43:ef:e8:66:88:2e:a3:86:4f:2e:95:51:f8:
+ 82:dd:c4:7a:9f:3b:6e:81:4d:32:eb:a6:c7:05:4a:
+ 1d:f1:bd:31:9a:2d:45:0b:2e:a9:9b:d4:13:a4:55:
+ 40:1c:12:db:4b:76:2b:31:cc:8b:fb:f7:a4:52:e1:
+ de:f7:0f:b8:17:47:a4:0a:1e:53:b9:7c:a6:cc:ac:
+ ed:40:72:d1:9c:93:85:05:2e:77:1e:60:ab:7d:fc:
+ 46:0f:f1:47:65:09:53:62:c6:90:db:5d:4e:ee:cd:
+ e9:ea:f0:18:f0:ba:a3:91:e2:bf:7b:24:e9:eb:13:
+ 48:4e:05:63:f4:40:b8:f1:84:7b:d6:91:e9:90:50:
+ c2:7a:f7:44:2e:70:ad:73:c1:5a:3c:32:5e:3c:9b:
+ 15:5f:9a:b2:48:03:50:a6:72:2f:10:94:81:e5:27:
+ bf:28:01:6a:a2:ef:3f:6c:10:b0:a2:02:72:27:d8:
+ 1c:0c:d4:4d:06:55:48:19:ab:6d:67:56:cd:2d:55:
+ 63:e5:50:63:02:7d:cc:c6:28:ef:29:ed:db:50:f2:
+ 31:23:dd:52:f3:27:7e:fd:e1:5f:6f:f5:0f:69:58:
+ 2b:01
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ C4:E1:12:23:5E:5D:61:E9:F8:C1:9E:0E:57:94:54:97:B2:4E:0B:65
+ X509v3 Authority Key Identifier:
+ keyid:81:56:F3:D5:96:CB:97:DE:87:18:26:E0:E7:E9:59:9E:58:FC:8B:76
+
+ 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
+ 4a:7b:2a:d9:aa:69:78:28:dc:2d:46:22:f2:ec:d3:09:b7:b7:
+ 91:2b:6d:a0:07:b9:8a:9e:5c:11:73:ba:1d:61:ed:07:b2:a3:
+ 7e:3c:48:f3:95:59:ed:98:e9:40:9c:88:47:47:23:9e:37:ce:
+ f3:49:b5:53:51:be:4a:8b:77:ac:ef:76:2a:3b:11:d1:92:61:
+ cc:f4:04:85:09:c2:83:db:21:cc:20:a6:49:3d:54:da:e8:ba:
+ e2:0f:f6:15:fd:cb:83:8a:82:17:b2:c3:43:dd:a4:0a:42:61:
+ 59:75:5c:c6:5b:7e:5f:97:e6:ea:7e:bc:19:17:5b:df:9e:72:
+ a4:31:fd:64:6d:34:5b:05:39:5d:f3:2d:35:44:0a:cc:da:cb:
+ af:86:06:14:0f:ae:47:9e:ff:f1:55:dc:32:4b:9b:43:df:60:
+ d9:ee:0a:09:95:08:43:c3:c3:18:30:c6:56:f1:d0:b9:17:c9:
+ 19:5f:a5:c3:a2:76:c0:ad:b2:73:24:0e:34:03:f0:83:17:a5:
+ ac:b1:4f:9e:38:3d:7d:82:f6:90:ca:43:f5:37:c4:1a:19:2e:
+ a5:a9:40:64:0a:fb:d1:eb:42:c2:42:f1:08:26:6b:d6:c3:59:
+ bc:14:99:95:b3:62:80:92:93:49:4f:95:fe:71:e8:7c:3d:ee:
+ 21:99:7a:aa
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyH9CYu4p
+77tYhEjDqmHKMrHs8OY0C/R+0iFGu7u1+0Pv6GaILqOGTy6VUfiC3cR6nztugU0y
+66bHBUod8b0xmi1FCy6pm9QTpFVAHBLbS3YrMcyL+/ekUuHe9w+4F0ekCh5TuXym
+zKztQHLRnJOFBS53HmCrffxGD/FHZQlTYsaQ211O7s3p6vAY8LqjkeK/eyTp6xNI
+TgVj9EC48YR71pHpkFDCevdELnCtc8FaPDJePJsVX5qySANQpnIvEJSB5Se/KAFq
+ou8/bBCwogJyJ9gcDNRNBlVIGattZ1bNLVVj5VBjAn3MxijvKe3bUPIxI91S8yd+
+/eFfb/UPaVgrAQIDAQABo4HLMIHIMB0GA1UdDgQWBBTE4RIjXl1h6fjBng5XlFSX
+sk4LZTAfBgNVHSMEGDAWgBSBVvPVlsuX3ocYJuDn6VmeWPyLdjA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AEp7KtmqaXgo3C1GIvLs0wm3t5ErbaAHuYqeXBFzuh1h7Qeyo348SPOVWe2Y6UCc
+iEdHI543zvNJtVNRvkqLd6zvdio7EdGSYcz0BIUJwoPbIcwgpkk9VNrouuIP9hX9
+y4OKgheyw0PdpApCYVl1XMZbfl+X5up+vBkXW9+ecqQx/WRtNFsFOV3zLTVECsza
+y6+GBhQPrkee//FV3DJLm0PfYNnuCgmVCEPDwxgwxlbx0LkXyRlfpcOidsCtsnMk
+DjQD8IMXpayxT544PX2C9pDKQ/U3xBoZLqWpQGQK+9HrQsJC8Qgma9bDWbwUmZWz
+YoCSk0lPlf5x6Hw97iGZeqo=
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ce:b8:01:ca:69:e8:5c:e1:16:2a:54:88:85:15:
+ 66:e9:09:2e:04:cf:e8:7f:98:b0:63:1a:39:b9:25:
+ 0d:dd:d8:81:f6:e3:d3:3b:98:39:70:09:eb:ed:63:
+ 35:91:6a:bf:c4:4e:38:fa:04:a7:1c:bd:32:92:3b:
+ 5b:2b:29:f3:94:bc:b2:e6:69:7c:32:57:40:36:1b:
+ 6a:1f:9d:12:10:96:db:75:2b:77:bb:50:95:0e:03:
+ 65:d7:28:85:12:c8:54:89:38:be:2c:83:81:59:31:
+ c7:36:d8:d8:89:28:f3:87:7d:ab:b8:24:c0:d9:43:
+ a8:c8:0d:18:fa:98:4c:32:90:73:4c:86:ec:b1:c1:
+ 52:1f:af:03:73:84:7c:80:ee:72:56:4e:49:91:0e:
+ 1d:16:bc:ad:39:5a:dd:52:96:cb:87:09:e0:15:6a:
+ a4:ac:24:5c:c0:93:13:4b:09:1e:b7:bd:a6:0b:0a:
+ 94:96:5d:b5:7f:3a:ea:25:cd:c3:c5:7a:49:6a:89:
+ 42:db:e6:b5:71:fc:46:45:19:d2:33:d8:e4:95:a4:
+ 53:12:fd:09:f1:94:d8:24:28:d3:cc:ec:21:bd:cb:
+ 46:1b:24:d9:5a:70:86:1d:cb:7f:6c:be:24:7c:e4:
+ 37:72:3e:4f:c5:3e:01:68:d8:3b:ae:4a:ab:b2:90:
+ 3c:cd
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 81:56:F3:D5:96:CB:97:DE:87:18:26:E0:E7:E9:59:9E:58:FC:8B:76
+ X509v3 Authority Key Identifier:
+ keyid:81:56:F3:D5:96:CB:97:DE:87:18:26:E0:E7:E9:59:9E:58:FC:8B:76
+
+ 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
+ 49:ab:00:40:12:3b:b6:18:a4:f7:c0:e3:94:db:49:b3:45:02:
+ 45:ac:38:50:2c:4f:b9:a3:31:4f:99:e5:1a:3d:a7:76:23:1f:
+ 47:83:c4:ea:11:1e:98:f4:a5:d2:d3:76:d1:e7:47:23:09:5f:
+ e6:de:ef:d3:9e:aa:fa:42:4f:2e:14:2e:78:ee:0f:3f:ac:53:
+ 1c:d5:7f:b2:ec:4e:34:bd:c6:10:f4:be:fa:31:e4:a3:67:7e:
+ 3e:31:e7:55:ad:17:8c:b3:72:e0:19:5e:77:59:06:bb:56:8e:
+ 81:ec:c8:b5:c1:95:d6:6c:53:9c:86:a0:19:72:1d:47:ea:be:
+ ad:bc:4d:cd:26:f8:87:75:ff:08:1d:9a:d5:f8:7c:ae:3f:57:
+ 97:3a:54:aa:90:5a:b5:93:97:3f:47:be:34:2d:14:bf:7d:fd:
+ be:67:88:22:7e:b7:b5:3a:a0:3a:b0:d2:0f:9d:28:1e:fb:1a:
+ c0:11:ed:ba:a6:4e:c5:6f:2a:4b:90:84:26:1d:2b:f0:14:40:
+ 7a:55:22:c7:7d:39:ee:42:30:7f:b5:4a:0b:d5:1b:12:42:36:
+ 62:86:b2:02:68:24:8a:c3:a6:7e:18:b1:15:5d:d4:f0:62:2c:
+ cf:09:0d:7d:8f:80:a5:13:8d:9a:53:87:70:f0:94:b1:62:71:
+ e3:b9:b0:d1
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM64Acpp6FzhFipUiIUV
+ZukJLgTP6H+YsGMaObklDd3Ygfbj0zuYOXAJ6+1jNZFqv8ROOPoEpxy9MpI7Wysp
+85S8suZpfDJXQDYbah+dEhCW23Urd7tQlQ4DZdcohRLIVIk4viyDgVkxxzbY2Iko
+84d9q7gkwNlDqMgNGPqYTDKQc0yG7LHBUh+vA3OEfIDuclZOSZEOHRa8rTla3VKW
+y4cJ4BVqpKwkXMCTE0sJHre9pgsKlJZdtX866iXNw8V6SWqJQtvmtXH8RkUZ0jPY
+5JWkUxL9CfGU2CQo08zsIb3LRhsk2Vpwhh3Lf2y+JHzkN3I+T8U+AWjYO65Kq7KQ
+PM0CAwEAAaOByzCByDAdBgNVHQ4EFgQUgVbz1ZbLl96HGCbg5+lZnlj8i3YwHwYD
+VR0jBBgwFoAUgVbz1ZbLl96HGCbg5+lZnlj8i3YwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBJqwBAEju2
+GKT3wOOU20mzRQJFrDhQLE+5ozFPmeUaPad2Ix9Hg8TqER6Y9KXS03bR50cjCV/m
+3u/Tnqr6Qk8uFC547g8/rFMc1X+y7E40vcYQ9L76MeSjZ34+MedVrReMs3LgGV53
+WQa7Vo6B7Mi1wZXWbFOchqAZch1H6r6tvE3NJviHdf8IHZrV+HyuP1eXOlSqkFq1
+k5c/R740LRS/ff2+Z4gifre1OqA6sNIPnSge+xrAEe26pk7FbypLkIQmHSvwFEB6
+VSLHfTnuQjB/tUoL1RsSQjZihrICaCSKw6Z+GLEVXdTwYizPCQ19j4ClE42aU4dw
+8JSxYnHjubDR
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/unknown-root.pem b/chromium/net/data/verify_certificate_chain_unittest/unknown-root.pem
new file mode 100644
index 00000000000..a3ee2f7d83f
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/unknown-root.pem
@@ -0,0 +1,192 @@
+[Created by: generate-unknown-root.py]
+
+Certificate chain with 1 intermediary, but the root is not in trust store.
+Verification is expected to fail because the final intermediary (Intermediary)
+does not chain to a known root.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:f3:f6:f4:c5:f5:4f:a3:17:ee:19:45:0e:97:90:
+ 31:60:2a:a5:31:0d:e4:c7:f4:fa:4d:e4:99:f5:3c:
+ db:ad:6b:2d:f2:8d:07:4f:dc:c1:e3:3f:53:b6:48:
+ 31:8e:8e:a6:b3:d6:a4:3c:fb:21:00:01:a6:35:79:
+ 50:a6:d0:43:10:8d:13:1b:6f:a9:4b:a3:9b:77:11:
+ af:0f:7c:f9:f0:e6:03:c5:b5:b4:49:7a:9d:8f:a1:
+ 42:89:a5:41:5d:c7:e1:7d:4a:e5:af:8f:66:ad:93:
+ b0:f6:60:52:f4:0c:2d:d1:60:ca:a4:4c:fa:0d:55:
+ 0d:46:60:69:10:a7:8e:06:bd:ad:28:65:63:a5:63:
+ 36:d8:eb:8e:e1:cc:fd:53:76:80:d3:1d:e2:b8:46:
+ f9:24:e7:3a:86:30:f9:14:34:a2:42:81:b7:2b:a4:
+ 41:14:7a:9c:77:83:51:cb:b9:08:31:29:a2:b0:25:
+ 92:1e:7f:43:90:1c:6a:43:ca:64:04:37:c8:26:b7:
+ 7b:ae:cb:8b:2e:e7:6f:09:c4:3e:87:0d:b1:ef:70:
+ 58:cd:b5:d7:c7:6b:dd:7b:3c:46:0c:4d:5f:21:1d:
+ 78:b9:cf:46:5e:f8:35:48:7d:14:0b:3e:a4:2a:1c:
+ 4e:78:6d:27:76:61:e5:c5:74:16:fb:f1:77:9c:f3:
+ 51:7f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ F8:48:56:E7:65:49:C4:48:98:8E:F0:F5:EA:01:C4:01:C8:4D:56:D9
+ X509v3 Authority Key Identifier:
+ keyid:41:D3:BE:10:2F:EE:43:B6:25:B0:04:4E:39:CF:78:F9:0E:ED:E1:9D
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 48:65:f4:55:86:82:85:93:a0:4d:b0:ce:b8:b2:21:f5:bf:56:
+ 66:ef:e3:f5:24:52:da:a5:15:21:f7:b4:a1:7c:2f:69:de:1e:
+ 6a:90:8d:98:e9:38:29:b8:51:44:7b:43:68:92:95:e4:50:7c:
+ 32:94:72:6c:96:4a:77:07:ce:0c:55:df:19:50:29:e5:ee:ff:
+ c4:54:c9:75:2d:c2:fd:f1:41:5c:c4:28:3c:15:df:1a:12:73:
+ aa:a6:af:2a:3e:f5:a6:17:68:5b:80:d8:6d:fa:6d:37:26:a1:
+ 01:0e:0a:c1:a8:ed:ef:2b:65:1c:43:4d:dd:aa:7b:e1:6d:a6:
+ a6:23:66:11:58:73:f0:e2:98:d2:ba:db:94:ed:c9:fc:41:6f:
+ 4b:99:7c:be:2e:e9:57:e2:c6:26:24:db:2a:02:4e:3c:7e:8b:
+ d8:96:27:43:7b:b4:1e:25:2f:19:c0:e4:05:b9:5e:0e:57:29:
+ 9e:81:9c:1e:d8:48:4b:d0:c8:ff:1a:a7:7f:71:4a:9f:51:0d:
+ 8a:11:6e:74:86:8e:89:d8:fd:a4:69:bb:67:78:2d:2d:44:75:
+ 9b:63:31:ef:b1:3e:38:11:ce:01:ae:b0:fa:a4:3f:b0:df:be:
+ 13:9a:5e:11:f6:bb:eb:8e:3a:7d:09:be:76:9b:e5:d4:91:f3:
+ dc:e5:23:df
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl
+cm1lZGlhcnkwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD
+VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDz9vTF
+9U+jF+4ZRQ6XkDFgKqUxDeTH9PpN5Jn1PNutay3yjQdP3MHjP1O2SDGOjqaz1qQ8
++yEAAaY1eVCm0EMQjRMbb6lLo5t3Ea8PfPnw5gPFtbRJep2PoUKJpUFdx+F9SuWv
+j2atk7D2YFL0DC3RYMqkTPoNVQ1GYGkQp44Gva0oZWOlYzbY647hzP1TdoDTHeK4
+Rvkk5zqGMPkUNKJCgbcrpEEUepx3g1HLuQgxKaKwJZIef0OQHGpDymQEN8gmt3uu
+y4su528JxD6HDbHvcFjNtdfHa917PEYMTV8hHXi5z0Ze+DVIfRQLPqQqHE54bSd2
+YeXFdBb78Xec81F/AgMBAAGjgekwgeYwHQYDVR0OBBYEFPhIVudlScRImI7w9eoB
+xAHITVbZMB8GA1UdIwQYMBaAFEHTvhAv7kO2JbAETjnPePkO7eGdMD8GCCsGAQUF
+BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk
+aWFyeS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu
+dGVybWVkaWFyeS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEASGX0VYaChZOgTbDOuLIh
+9b9WZu/j9SRS2qUVIfe0oXwvad4eapCNmOk4KbhRRHtDaJKV5FB8MpRybJZKdwfO
+DFXfGVAp5e7/xFTJdS3C/fFBXMQoPBXfGhJzqqavKj71phdoW4DYbfptNyahAQ4K
+wajt7ytlHENN3ap74W2mpiNmEVhz8OKY0rrblO3J/EFvS5l8vi7pV+LGJiTbKgJO
+PH6L2JYnQ3u0HiUvGcDkBbleDlcpnoGcHthIS9DI/xqnf3FKn1ENihFudIaOidj9
+pGm7Z3gtLUR1m2Mx77E+OBHOAa6w+qQ/sN++E5peEfa76446fQm+dpvl1JHz3OUj
+3w==
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:cd:6f:e8:b3:ea:d4:9e:d9:23:03:8a:4a:f3:6c:
+ 84:cd:0c:28:7c:c2:07:60:89:c5:9a:9f:74:b8:d0:
+ ac:e4:30:f1:4b:1c:c5:7f:9d:d2:0f:4e:e0:e5:45:
+ 4a:cc:93:70:a0:df:3c:4c:fc:0c:a5:d5:c9:86:fd:
+ ba:4e:67:c0:af:c3:04:98:cb:bb:f6:25:a6:af:7f:
+ 7b:a3:29:b9:86:60:87:80:67:90:ab:e7:64:86:ec:
+ e6:30:f6:dd:5b:3a:69:4f:b1:58:f8:4b:15:ae:13:
+ c8:84:24:bf:9a:a0:6c:8a:b3:36:31:84:2f:a4:3e:
+ 4a:f2:9f:07:91:a4:8b:dc:fa:5b:65:3c:4e:93:19:
+ 02:a5:3a:78:5d:f2:51:bd:d7:96:16:6e:c5:8b:17:
+ d0:21:77:2f:96:4a:44:c8:17:2d:73:d5:da:24:40:
+ d1:a4:b7:f2:c4:b2:e2:16:6a:19:9b:72:cb:58:62:
+ eb:30:2f:2f:c5:35:1c:74:2f:ba:e6:93:7e:dc:78:
+ bc:ad:e3:89:c9:72:9a:f5:01:95:61:02:9f:82:40:
+ f9:c1:c8:6e:36:b7:14:4a:13:36:bb:d0:1b:25:bd:
+ d6:5e:11:e7:d9:ea:a7:db:6d:d3:92:98:b1:2a:c1:
+ cf:00:52:c1:78:c9:0a:30:41:30:09:c8:90:0a:04:
+ 8f:0d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 41:D3:BE:10:2F:EE:43:B6:25:B0:04:4E:39:CF:78:F9:0E:ED:E1:9D
+ X509v3 Authority Key Identifier:
+ keyid:A7:80:43:01:58:B0:DD:7A:AD:7C:38:10:73:02:DE:2C:E6:E4:9E:A9
+
+ 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
+ 90:b6:a5:85:fe:d4:51:b9:f7:92:ae:60:80:ab:54:09:3d:63:
+ 43:fd:ce:e0:ea:e3:f2:c0:db:f5:1b:a7:db:f1:b3:21:d0:e4:
+ 7f:63:c1:75:13:ca:3d:6b:70:76:55:23:cc:c8:74:80:b8:82:
+ c0:cd:63:41:77:4c:27:8a:32:34:f7:9d:8d:0e:9f:15:ee:22:
+ 4f:ed:d7:32:f2:c9:95:bd:35:87:d8:c5:58:19:ba:06:58:a4:
+ 96:bc:2d:4e:1b:ed:2f:23:ac:b1:2f:b7:e0:88:a9:fc:68:c0:
+ 8d:8a:41:e6:d3:ba:b9:88:77:54:37:5a:e5:a9:b3:f2:85:7b:
+ b4:7d:69:83:37:81:12:54:21:4c:d1:69:98:a2:fd:ef:a3:65:
+ e9:32:f6:63:1e:54:ce:a9:75:74:53:61:b4:f0:78:72:c4:f0:
+ 04:f0:f3:a8:70:93:f6:35:89:0f:6f:49:7a:0e:57:e0:af:33:
+ 35:89:b6:cd:ef:81:aa:8c:10:11:e9:57:a1:66:4c:30:9c:11:
+ 6a:c6:85:4b:d1:94:88:6e:aa:5f:8e:fb:d2:31:3d:ee:19:19:
+ 01:3c:4a:05:72:9c:aa:ae:ef:af:b0:f1:9f:e0:ae:d6:8e:09:
+ d1:05:ee:6b:77:08:11:52:8c:91:a0:2f:9b:ac:88:98:14:14:
+ a4:08:b5:7d
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50
+ZXJtZWRpYXJ5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzW/os+rU
+ntkjA4pK82yEzQwofMIHYInFmp90uNCs5DDxSxzFf53SD07g5UVKzJNwoN88TPwM
+pdXJhv26TmfAr8MEmMu79iWmr397oym5hmCHgGeQq+dkhuzmMPbdWzppT7FY+EsV
+rhPIhCS/mqBsirM2MYQvpD5K8p8HkaSL3PpbZTxOkxkCpTp4XfJRvdeWFm7FixfQ
+IXcvlkpEyBctc9XaJEDRpLfyxLLiFmoZm3LLWGLrMC8vxTUcdC+65pN+3Hi8reOJ
+yXKa9QGVYQKfgkD5wchuNrcUShM2u9AbJb3WXhHn2eqn223TkpixKsHPAFLBeMkK
+MEEwCciQCgSPDQIDAQABo4HLMIHIMB0GA1UdDgQWBBRB074QL+5DtiWwBE45z3j5
+Du3hnTAfBgNVHSMEGDAWgBSngEMBWLDdeq18OBBzAt4s5uSeqTA3BggrBgEFBQcB
+AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs
+BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
+AJC2pYX+1FG595KuYICrVAk9Y0P9zuDq4/LA2/Ubp9vxsyHQ5H9jwXUTyj1rcHZV
+I8zIdIC4gsDNY0F3TCeKMjT3nY0OnxXuIk/t1zLyyZW9NYfYxVgZugZYpJa8LU4b
+7S8jrLEvt+CIqfxowI2KQebTurmId1Q3WuWps/KFe7R9aYM3gRJUIUzRaZii/e+j
+Zeky9mMeVM6pdXRTYbTweHLE8ATw86hwk/Y1iQ9vSXoOV+CvMzWJts3vgaqMEBHp
+V6FmTDCcEWrGhUvRlIhuql+O+9IxPe4ZGQE8SgVynKqu76+w8Z/grtaOCdEF7mt3
+CBFSjJGgL5usiJgUFKQItX0=
+-----END CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem b/chromium/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem
new file mode 100644
index 00000000000..a0cd187e5ce
--- /dev/null
+++ b/chromium/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem
@@ -0,0 +1,370 @@
+[Created by: generate-violates-basic-constraints-pathlen-0.py]
+
+Certificate chain with 2 intermediaries. The first intermediary has a basic
+constraints path length of 0, so it is a violation for it to have a subordinate
+intermediary.
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary2
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Target
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b2:f1:24:bb:4b:3d:6d:80:7f:67:ad:2e:0e:e8:
+ 07:e4:4b:6c:28:0d:2e:d9:9d:9d:e5:31:0a:7f:37:
+ 3f:9c:c1:c3:03:8e:b8:72:5a:1c:52:d4:4e:84:7a:
+ 9c:4d:f6:2a:a8:4b:f2:5c:5b:6c:f4:23:73:b3:4e:
+ 0a:b9:66:16:ae:e4:c4:8b:d7:1b:b5:d0:5e:5f:03:
+ 21:ce:63:b8:3a:da:e0:3c:f8:0a:7e:4b:99:f9:c6:
+ 0d:01:a2:ab:18:d8:a7:a0:84:8c:3f:09:fd:10:41:
+ 7c:6f:b0:51:34:4f:5d:39:b5:3f:6d:a0:68:87:6d:
+ 09:47:db:0d:2a:62:99:83:02:0c:b9:d7:93:0b:bf:
+ 17:5f:06:58:22:27:62:fc:1c:d9:02:b9:1e:e9:f0:
+ fb:e1:a4:cc:fd:e3:9e:a8:a5:2d:f9:af:8b:b8:1e:
+ 68:dc:f1:52:a2:55:94:20:da:82:14:b7:c0:a0:c5:
+ 53:ff:00:0f:76:f9:fd:bf:53:71:99:60:2f:00:c9:
+ 9e:d0:07:eb:3c:d0:47:5c:7b:65:cb:62:db:9b:74:
+ ed:b8:51:a0:ed:ed:af:e9:6f:44:0e:8c:a4:42:ee:
+ fc:92:bb:19:1a:b3:42:74:27:39:47:b8:d4:06:ed:
+ bd:99:72:0c:83:15:10:ff:4a:66:66:0f:d6:14:ef:
+ dd:17
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 33:73:C0:44:EE:71:53:CD:C0:EA:D9:FC:FF:BE:B7:DD:16:66:19:84
+ X509v3 Authority Key Identifier:
+ keyid:FD:31:C0:C5:57:AB:1E:A5:78:24:73:72:58:9F:75:7D:78:17:42:AC
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary2.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary2.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 61:39:30:49:95:f7:63:44:f3:a5:97:35:48:84:ea:94:cd:94:
+ 37:ce:09:7a:b1:58:21:3e:f8:9c:a4:a9:65:bf:1d:a1:cb:eb:
+ 09:95:f7:f6:ad:a4:65:95:a1:51:c4:18:06:43:d2:93:eb:16:
+ 41:65:33:8a:42:cc:90:9d:e9:66:1f:d6:98:31:f1:48:f4:a8:
+ a3:89:50:29:bc:f2:2d:af:8b:f7:af:9e:62:02:21:06:75:3d:
+ 4a:8d:98:a0:df:4d:5d:db:9a:af:2a:0f:32:50:aa:61:c3:19:
+ 87:99:54:60:3a:16:c5:46:ea:ed:54:ab:91:34:5f:8e:60:33:
+ 10:e4:e1:4d:05:8d:36:5b:47:1c:c3:f2:58:7f:22:07:c7:95:
+ 02:24:8e:03:f4:1f:06:25:d7:49:76:f8:f1:02:25:7c:9a:cf:
+ 0f:4d:8f:08:e7:bf:fd:13:31:43:e5:56:20:eb:0a:43:ca:41:
+ 0d:7c:4f:68:f6:d1:d1:67:ca:24:4f:e3:8e:8e:12:39:2f:7b:
+ e8:9a:5c:c9:b5:19:01:1a:46:7e:54:21:ad:7e:c5:cd:e2:40:
+ c3:13:aa:b5:e5:16:b3:18:dc:c8:61:d7:73:b7:3b:23:00:04:
+ ce:dc:5a:22:1a:0b:da:8a:99:10:96:33:32:ae:4e:83:f4:d0:
+ 93:e7:75:56
+-----BEGIN CERTIFICATE-----
+MIIDkDCCAnigAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1JbnRl
+cm1lZGlhcnkyMB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowETEPMA0G
+A1UEAwwGVGFyZ2V0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsvEk
+u0s9bYB/Z60uDugH5EtsKA0u2Z2d5TEKfzc/nMHDA464clocUtROhHqcTfYqqEvy
+XFts9CNzs04KuWYWruTEi9cbtdBeXwMhzmO4OtrgPPgKfkuZ+cYNAaKrGNinoISM
+Pwn9EEF8b7BRNE9dObU/baBoh20JR9sNKmKZgwIMudeTC78XXwZYIidi/BzZArke
+6fD74aTM/eOeqKUt+a+LuB5o3PFSolWUINqCFLfAoMVT/wAPdvn9v1NxmWAvAMme
+0AfrPNBHXHtly2Lbm3TtuFGg7e2v6W9EDoykQu78krsZGrNCdCc5R7jUBu29mXIM
+gxUQ/0pmZg/WFO/dFwIDAQABo4HrMIHoMB0GA1UdDgQWBBQzc8BE7nFTzcDq2fz/
+vrfdFmYZhDAfBgNVHSMEGDAWgBT9McDFV6sepXgkc3JYn3V9eBdCrDBABggrBgEF
+BQcBAQQ0MDIwMAYIKwYBBQUHMAKGJGh0dHA6Ly91cmwtZm9yLWFpYS9JbnRlcm1l
+ZGlhcnkyLmNlcjA1BgNVHR8ELjAsMCqgKKAmhiRodHRwOi8vdXJsLWZvci1jcmwv
+SW50ZXJtZWRpYXJ5Mi5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsG
+AQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAYTkwSZX3Y0TzpZc1
+SITqlM2UN84JerFYIT74nKSpZb8docvrCZX39q2kZZWhUcQYBkPSk+sWQWUzikLM
+kJ3pZh/WmDHxSPSoo4lQKbzyLa+L96+eYgIhBnU9So2YoN9NXduaryoPMlCqYcMZ
+h5lUYDoWxUbq7VSrkTRfjmAzEOThTQWNNltHHMPyWH8iB8eVAiSOA/QfBiXXSXb4
+8QIlfJrPD02PCOe//RMxQ+VWIOsKQ8pBDXxPaPbR0WfKJE/jjo4SOS976JpcybUZ
+ARpGflQhrX7FzeJAwxOqteUWsxjcyGHXc7c7IwAEztxaIhoL2oqZEJYzMq5Og/TQ
+k+d1Vg==
+-----END CERTIFICATE-----
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Intermediary1
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2016 GMT
+ Subject: CN=Intermediary2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b9:4e:dc:bd:a8:9e:1d:81:d7:bb:c3:4d:8a:5d:
+ 34:3f:b2:71:12:c0:0d:76:05:d6:b3:6a:b6:3d:b5:
+ 97:a8:8d:a0:ba:d9:2f:3c:da:b0:8f:5f:18:f0:83:
+ fb:59:ef:91:8d:5a:57:57:63:36:a1:ff:54:9a:f5:
+ 10:ab:4a:6b:16:fc:c6:f2:4e:9f:97:ec:22:6f:97:
+ dd:0e:63:ef:ce:71:4f:f6:8e:04:68:22:c9:6d:b4:
+ d2:fe:7b:46:aa:e9:05:a0:c0:b0:25:42:cd:ba:e8:
+ 8d:bb:cb:3e:5f:e4:54:b7:dd:48:c6:08:52:30:54:
+ e2:f4:c1:ae:ee:71:71:a7:33:ce:c1:b1:55:e4:77:
+ 15:72:c5:ea:5f:ed:b3:a6:ef:a7:cc:f6:eb:6c:42:
+ 1d:45:c3:75:15:d5:bd:09:44:52:b9:f5:5d:1f:10:
+ e1:fc:31:9e:37:90:ca:7c:8d:16:c4:f7:76:39:b7:
+ 57:ea:5b:75:3d:6c:50:60:26:ed:8b:2a:e4:a2:b8:
+ a2:34:ba:51:89:ce:3c:e3:68:c3:3c:4a:58:cb:be:
+ 79:34:54:2d:61:38:7b:7a:89:3f:4c:5f:3f:c9:c6:
+ fc:d0:81:de:0c:21:2e:5a:2a:74:cd:fe:d7:c9:de:
+ b3:3a:60:d6:16:e7:91:13:87:a4:f4:f8:67:4b:17:
+ e6:13
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ FD:31:C0:C5:57:AB:1E:A5:78:24:73:72:58:9F:75:7D:78:17:42:AC
+ X509v3 Authority Key Identifier:
+ keyid:09:87:C1:14:11:81:04:D8:AF:CF:66:4A:4F:8D:1C:A5:BB:04:CF:DA
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Intermediary1.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Intermediary1.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ Signature Algorithm: sha256WithRSAEncryption
+ 51:f3:32:1a:03:bd:bd:a1:40:7d:4a:55:ef:6e:5e:58:57:8c:
+ 50:75:7c:e6:d0:44:ff:7e:0c:f7:9d:c2:67:99:83:e2:da:19:
+ e6:0b:54:8a:61:7d:16:86:99:2d:b7:32:2d:c6:a0:7a:1a:e2:
+ c2:46:8c:a1:b7:f8:bb:d4:22:b1:ae:d0:2f:a9:98:32:4e:14:
+ 20:6c:22:cf:df:c8:08:ce:f4:4c:8b:5c:03:33:0a:d1:32:2b:
+ 5a:0d:d2:99:18:79:a1:e8:ed:8d:31:85:9e:dd:30:52:30:1f:
+ ff:af:1f:09:08:98:a0:75:11:02:e6:6c:2b:7e:67:df:89:91:
+ 1e:57:b4:a2:ba:1e:7b:86:68:f3:62:7a:69:c1:4e:b3:76:58:
+ 74:e5:84:3d:0f:6d:1b:22:97:e9:7f:0b:c7:2f:00:c5:4d:1a:
+ fd:47:ff:9f:c0:84:0b:ee:dc:cd:c2:43:7f:0f:7a:a6:28:6e:
+ c3:2c:7a:a1:cf:4f:16:3f:f5:fc:40:c7:65:91:a5:bc:5c:82:
+ 9c:a0:fb:0a:1d:69:89:85:e5:9e:10:41:7e:4d:83:02:4f:64:
+ 54:04:86:97:d7:5e:6c:e1:ef:65:b0:a4:69:b8:e3:d4:0e:cd:
+ 20:04:1a:05:56:e9:e1:c3:e9:2f:9a:7b:43:59:73:ff:0b:82:
+ 38:e8:b3:b5
+-----BEGIN CERTIFICATE-----
+MIIDjDCCAnSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1JbnRl
+cm1lZGlhcnkxMB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowGDEWMBQG
+A1UEAwwNSW50ZXJtZWRpYXJ5MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALlO3L2onh2B17vDTYpdND+ycRLADXYF1rNqtj21l6iNoLrZLzzasI9fGPCD
++1nvkY1aV1djNqH/VJr1EKtKaxb8xvJOn5fsIm+X3Q5j785xT/aOBGgiyW200v57
+RqrpBaDAsCVCzbrojbvLPl/kVLfdSMYIUjBU4vTBru5xcaczzsGxVeR3FXLF6l/t
+s6bvp8z262xCHUXDdRXVvQlEUrn1XR8Q4fwxnjeQynyNFsT3djm3V+pbdT1sUGAm
+7Ysq5KK4ojS6UYnOPONowzxKWMu+eTRULWE4e3qJP0xfP8nG/NCB3gwhLloqdM3+
+18neszpg1hbnkROHpPT4Z0sX5hMCAwEAAaOB4DCB3TAdBgNVHQ4EFgQU/THAxVer
+HqV4JHNyWJ91fXgXQqwwHwYDVR0jBBgwFoAUCYfBFBGBBNivz2ZKT40cpbsEz9ow
+QAYIKwYBBQUHAQEENDAyMDAGCCsGAQUFBzAChiRodHRwOi8vdXJsLWZvci1haWEv
+SW50ZXJtZWRpYXJ5MS5jZXIwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL3VybC1m
+b3ItY3JsL0ludGVybWVkaWFyeTEuY3JsMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
+Af8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBCwUAA4IBAQBR8zIaA729oUB9SlXvbl5Y
+V4xQdXzm0ET/fgz3ncJnmYPi2hnmC1SKYX0WhpkttzItxqB6GuLCRoyht/i71CKx
+rtAvqZgyThQgbCLP38gIzvRMi1wDMwrRMitaDdKZGHmh6O2NMYWe3TBSMB//rx8J
+CJigdREC5mwrfmffiZEeV7Siuh57hmjzYnppwU6zdlh05YQ9D20bIpfpfwvHLwDF
+TRr9R/+fwIQL7tzNwkN/D3qmKG7DLHqhz08WP/X8QMdlkaW8XIKcoPsKHWmJheWe
+EEF+TYMCT2RUBIaX115s4e9lsKRpuOPUDs0gBBoFVunhw+kvmntDWXP/C4I46LO1
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Intermediary1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ab:e9:a0:28:67:38:13:72:12:a0:3b:f2:f9:13:
+ c2:2b:c1:a2:07:e6:45:35:cf:ff:1a:46:b0:d2:58:
+ 12:63:fc:3d:b3:85:50:68:9c:57:21:ff:31:ff:24:
+ 48:db:13:de:b1:f4:f8:39:7a:f3:34:dd:51:58:1a:
+ 12:73:9d:85:e0:d0:f8:be:fd:9d:e2:34:ce:36:e0:
+ a0:48:53:36:23:bf:52:d2:ac:da:d1:ef:6c:da:9f:
+ 11:3b:6c:e1:67:6a:f1:df:97:2c:1a:12:c7:c3:72:
+ 0f:98:21:6a:40:2b:f0:28:b8:c2:ef:7f:cb:ee:7a:
+ e9:8f:17:fe:0a:a1:ff:d5:15:4c:63:5b:53:55:15:
+ 01:b9:5d:91:77:b0:23:03:0e:45:00:84:52:33:2b:
+ 11:51:99:e8:0d:5b:45:ef:d2:e2:c9:0e:a2:ae:43:
+ c2:92:5c:b0:36:76:06:21:91:d0:42:e8:0f:6f:80:
+ 61:98:12:a6:c0:c3:b7:64:7e:77:0c:76:12:1f:50:
+ 73:f8:bb:28:1a:5d:7b:68:36:01:fa:09:e7:9a:90:
+ b6:c5:3d:e9:16:a0:7b:c2:76:19:f0:e9:bc:15:0d:
+ 55:df:ea:67:2a:b2:e0:69:f8:c1:49:c4:a6:51:e9:
+ 43:d2:df:2a:de:e3:a0:66:3f:0c:18:b8:f8:8d:bb:
+ 43:15
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 09:87:C1:14:11:81:04:D8:AF:CF:66:4A:4F:8D:1C:A5:BB:04:CF:DA
+ X509v3 Authority Key Identifier:
+ keyid:A4:9D:E4:F8:B0:AF:D5:A4:2F:B9:3F:42:B8:C3:D5:60:9D:64:C2:8C
+
+ 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, pathlen:0
+ Signature Algorithm: sha256WithRSAEncryption
+ 7d:97:b6:93:81:ef:63:d9:d6:31:8d:ba:e0:61:36:7c:06:cd:
+ b5:2f:3f:4a:04:84:c2:c4:51:07:49:55:53:4f:22:b6:2f:15:
+ d9:62:8a:65:97:15:84:a1:e2:2e:4e:66:59:02:b2:8f:b6:d6:
+ 84:d6:ed:d4:df:45:a3:75:93:58:88:76:8d:6c:01:81:cc:c5:
+ 91:99:cc:9c:65:f9:c9:f0:86:ed:3a:fe:d0:a0:2e:6c:04:d2:
+ 49:f8:d4:31:9f:ce:db:93:bb:5a:73:4d:5d:24:83:4b:55:fe:
+ 49:79:67:64:83:18:56:d9:ad:90:96:0b:ab:49:de:08:80:7a:
+ 93:54:b1:38:19:c2:0b:6f:e1:b1:50:52:19:67:15:a9:aa:5a:
+ c5:ed:73:30:63:1a:64:24:d4:8b:95:c9:c4:54:78:62:ce:42:
+ f7:98:f1:94:2e:4d:93:7e:df:6f:cd:6f:41:c4:ef:c8:ed:f7:
+ 73:92:af:ee:19:b5:e5:47:82:f7:47:41:35:29:8c:88:3b:62:
+ 18:c0:f6:80:56:3f:f8:9e:b4:6e:33:2c:ce:41:da:56:83:c7:
+ c7:30:c6:0f:f5:49:f5:79:d6:7b:c5:33:4c:0f:2a:e9:13:27:
+ 0b:e3:b8:63:74:14:c0:2e:19:24:00:a4:f8:17:d7:cd:b5:1b:
+ c1:38:25:9a
+-----BEGIN CERTIFICATE-----
+MIIDcTCCAlmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowGDEWMBQGA1UEAwwNSW50
+ZXJtZWRpYXJ5MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKvpoChn
+OBNyEqA78vkTwivBogfmRTXP/xpGsNJYEmP8PbOFUGicVyH/Mf8kSNsT3rH0+Dl6
+8zTdUVgaEnOdheDQ+L79neI0zjbgoEhTNiO/UtKs2tHvbNqfETts4Wdq8d+XLBoS
+x8NyD5ghakAr8Ci4wu9/y+566Y8X/gqh/9UVTGNbU1UVAbldkXewIwMORQCEUjMr
+EVGZ6A1bRe/S4skOoq5DwpJcsDZ2BiGR0ELoD2+AYZgSpsDDt2R+dwx2Eh9Qc/i7
+KBpde2g2AfoJ55qQtsU96Rage8J2GfDpvBUNVd/qZyqy4Gn4wUnEplHpQ9LfKt7j
+oGY/DBi4+I27QxUCAwEAAaOBzjCByzAdBgNVHQ4EFgQUCYfBFBGBBNivz2ZKT40c
+pbsEz9owHwYDVR0jBBgwFoAUpJ3k+LCv1aQvuT9CuMPVYJ1kwowwNwYIKwYBBQUH
+AQEEKzApMCcGCCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIw
+LAYDVR0fBCUwIzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4G
+A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBCwUA
+A4IBAQB9l7aTge9j2dYxjbrgYTZ8Bs21Lz9KBITCxFEHSVVTTyK2LxXZYopllxWE
+oeIuTmZZArKPttaE1u3U30WjdZNYiHaNbAGBzMWRmcycZfnJ8IbtOv7QoC5sBNJJ
++NQxn87bk7tac01dJINLVf5JeWdkgxhW2a2QlgurSd4IgHqTVLE4GcILb+GxUFIZ
+ZxWpqlrF7XMwYxpkJNSLlcnEVHhizkL3mPGULk2Tft9vzW9BxO/I7fdzkq/uGbXl
+R4L3R0E1KYyIO2IYwPaAVj/4nrRuMyzOQdpWg8fHMMYP9Un1edZ7xTNMDyrpEycL
+47hjdBTALhkkAKT4F9fNtRvBOCWa
+-----END CERTIFICATE-----
+
+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 2016 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9e:1f:9a:ec:aa:50:56:02:47:76:c8:ff:b9:91:
+ c0:58:8d:08:b9:87:d9:ac:9e:7c:6e:2e:b7:60:68:
+ d6:ab:1c:3d:f3:e2:a8:e6:05:58:ff:52:27:7c:f9:
+ 7e:96:2d:19:71:35:84:eb:8d:3c:db:27:f7:5f:2f:
+ d1:56:af:73:a8:26:84:f5:bb:7f:7a:7c:40:81:66:
+ e9:e5:c1:53:eb:ac:d5:65:47:3d:a1:0a:67:c6:c8:
+ 3b:cb:2f:a9:1e:9c:d5:30:6b:7b:50:cb:ad:46:6b:
+ 33:44:91:14:94:20:ad:e2:79:1b:62:bb:1d:7e:a7:
+ 2a:45:03:4b:d4:64:1b:15:82:c6:dc:cb:48:84:c5:
+ 77:22:2a:20:6d:d8:bd:25:8d:55:11:95:46:73:97:
+ fa:53:66:2e:ec:1a:73:66:09:f7:ef:e4:f8:df:ea:
+ ce:90:c8:f8:38:67:bb:3c:c2:48:e7:69:01:98:6b:
+ c1:3e:8f:17:05:0f:c0:d0:eb:49:f1:c7:ab:c6:07:
+ 49:85:a7:57:ac:11:42:e5:de:bf:a1:65:4b:e6:ba:
+ e8:44:64:2d:84:d8:a4:4a:ba:62:56:76:49:bf:67:
+ 19:91:e1:29:e9:fb:aa:de:ef:df:58:01:08:65:14:
+ 8e:71:b5:3b:43:fb:6c:65:9a:d6:6e:42:65:24:2d:
+ f4:99
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ A4:9D:E4:F8:B0:AF:D5:A4:2F:B9:3F:42:B8:C3:D5:60:9D:64:C2:8C
+ X509v3 Authority Key Identifier:
+ keyid:A4:9D:E4:F8:B0:AF:D5:A4:2F:B9:3F:42:B8:C3:D5:60:9D:64:C2:8C
+
+ 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
+ 39:75:b8:af:a2:4e:d6:2f:15:08:4e:6d:06:1f:e7:65:29:96:
+ c2:77:96:ed:1b:b2:48:e3:f9:cf:fd:8c:40:d1:67:37:1a:7c:
+ e8:40:f0:ca:ee:72:9e:ef:6d:eb:e7:e9:5c:c4:61:e5:65:0e:
+ 25:62:8e:ca:b1:5d:08:d2:21:6d:cb:0f:d6:f3:41:4a:66:56:
+ 5b:06:3a:a7:6e:df:ad:6c:4d:18:01:95:b4:c9:7e:f4:80:e7:
+ 75:17:e0:41:25:7e:03:1b:5b:bd:a0:2d:1c:f8:f5:18:e6:0b:
+ 4c:69:7e:aa:54:78:f3:b4:84:b8:eb:8c:37:e9:60:dd:df:b8:
+ f8:43:57:37:99:db:b1:ed:99:2e:1f:f2:af:94:33:97:86:83:
+ 58:6d:e6:37:56:36:f8:68:e6:32:70:3f:5b:9b:13:75:a5:fc:
+ c0:5a:e5:61:61:37:d2:b6:d8:d5:5c:55:21:d5:8e:3a:ed:bf:
+ 83:81:76:e7:71:2b:3f:5b:0f:77:43:20:3a:d2:f6:ef:53:c8:
+ 29:19:2c:0a:4d:a6:2e:fb:9b:3b:10:73:e1:dc:ac:0e:8d:e4:
+ bd:36:da:e9:1e:0a:e6:57:b4:1d:ea:d8:cd:a0:dd:e3:88:8d:
+ a5:b4:43:7f:fd:b1:3c:29:e5:6a:b4:c9:4e:e6:77:83:ae:c6:
+ f7:04:47:a2
+-----BEGIN TRUSTED_CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ4fmuyqUFYCR3bI/7mR
+wFiNCLmH2ayefG4ut2Bo1qscPfPiqOYFWP9SJ3z5fpYtGXE1hOuNPNsn918v0Vav
+c6gmhPW7f3p8QIFm6eXBU+us1WVHPaEKZ8bIO8svqR6c1TBre1DLrUZrM0SRFJQg
+reJ5G2K7HX6nKkUDS9RkGxWCxtzLSITFdyIqIG3YvSWNVRGVRnOX+lNmLuwac2YJ
+9+/k+N/qzpDI+DhnuzzCSOdpAZhrwT6PFwUPwNDrSfHHq8YHSYWnV6wRQuXev6Fl
+S+a66ERkLYTYpEq6YlZ2Sb9nGZHhKen7qt7v31gBCGUUjnG1O0P7bGWa1m5CZSQt
+9JkCAwEAAaOByzCByDAdBgNVHQ4EFgQUpJ3k+LCv1aQvuT9CuMPVYJ1kwowwHwYD
+VR0jBBgwFoAUpJ3k+LCv1aQvuT9CuMPVYJ1kwowwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA5dbivok7W
+LxUITm0GH+dlKZbCd5btG7JI4/nP/YxA0Wc3GnzoQPDK7nKe723r5+lcxGHlZQ4l
+Yo7KsV0I0iFtyw/W80FKZlZbBjqnbt+tbE0YAZW0yX70gOd1F+BBJX4DG1u9oC0c
++PUY5gtMaX6qVHjztIS464w36WDd37j4Q1c3mdux7ZkuH/KvlDOXhoNYbeY3Vjb4
+aOYycD9bmxN1pfzAWuVhYTfSttjVXFUh1Y467b+DgXbncSs/Ww93QyA60vbvU8gp
+GSwKTaYu+5s7EHPh3KwOjeS9NtrpHgrmV7Qd6tjNoN3jiI2ltEN//bE8KeVqtMlO
+5neDrsb3BEei
+-----END TRUSTED_CERTIFICATE-----
+
+-----BEGIN TIME-----
+MTUwMzAyMTIwMDAwWg==
+-----END TIME-----
+
+-----BEGIN VERIFY_RESULT-----
+RkFJTA==
+-----END VERIFY_RESULT-----
diff --git a/chromium/net/data/verify_name_match_unittest/scripts/generate-names.py b/chromium/net/data/verify_name_match_unittest/scripts/generate_names.py
index c49a4321a13..e30533016d1 100755
--- a/chromium/net/data/verify_name_match_unittest/scripts/generate-names.py
+++ b/chromium/net/data/verify_name_match_unittest/scripts/generate_names.py
@@ -44,20 +44,24 @@ class NameGenerator:
def __init__(self):
self.rdns = []
+ def token(self):
+ return "NAME"
+
def add_rdn(self):
rdn = RDN()
self.rdns.append(rdn)
return rdn
def __str__(self):
- s = 'asn1 = SEQUENCE:rdnSequence\n\n[rdnSequence]\n'
+ s = 'asn1 = SEQUENCE:rdnSequence%i\n\n[rdnSequence%i]\n' % (
+ id(self), id(self))
for n, rdn in enumerate(self.rdns):
- s += 'rdn%i = SET:rdnSet%i\n' % (n, n)
+ s += 'rdn%i = SET:rdnSet%i_%i\n' % (n, id(self), n)
s += '\n'
for n, rdn in enumerate(self.rdns):
- s += '[rdnSet%i]\n%s\n' % (n, rdn)
+ s += '[rdnSet%i_%i]\n%s\n' % (id(self), n, rdn)
return s
diff --git a/chromium/net/der/input.cc b/chromium/net/der/input.cc
index 75d1c9c1847..871f9f4ec7d 100644
--- a/chromium/net/der/input.cc
+++ b/chromium/net/der/input.cc
@@ -4,6 +4,8 @@
#include <string.h>
+#include <algorithm>
+
#include "base/logging.h"
#include "net/der/input.h"
@@ -17,6 +19,11 @@ Input::Input() : data_(nullptr), len_(0) {
Input::Input(const uint8_t* data, size_t len) : data_(data), len_(len) {
}
+Input::Input(const base::StringPiece& in)
+ : data_(reinterpret_cast<const uint8_t*>(in.data())), len_(in.length()) {}
+
+Input::Input(const std::string* s) : Input(base::StringPiece(*s)) {}
+
bool Input::Equals(const Input& other) const {
if (len_ != other.len_)
return false;
@@ -27,6 +34,16 @@ std::string Input::AsString() const {
return std::string(reinterpret_cast<const char*>(data_), len_);
}
+base::StringPiece Input::AsStringPiece() const {
+ return base::StringPiece(reinterpret_cast<const char*>(data_), len_);
+}
+
+bool operator<(const Input& lhs, const Input& rhs) {
+ return std::lexicographical_compare(
+ lhs.UnsafeData(), lhs.UnsafeData() + lhs.Length(), rhs.UnsafeData(),
+ rhs.UnsafeData() + rhs.Length());
+}
+
ByteReader::ByteReader(const Input& in)
: data_(in.UnsafeData()), len_(in.Length()) {
}
diff --git a/chromium/net/der/input.h b/chromium/net/der/input.h
index c0195ff15f8..9c3f5ca87a4 100644
--- a/chromium/net/der/input.h
+++ b/chromium/net/der/input.h
@@ -5,10 +5,13 @@
#ifndef NET_DER_INPUT_H_
#define NET_DER_INPUT_H_
+#include <stddef.h>
#include <stdint.h>
+
#include <string>
#include "base/compiler_specific.h"
+#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
namespace net {
@@ -47,7 +50,15 @@ class NET_EXPORT_PRIVATE Input {
: data_(data), len_(N) {}
// Creates an Input from the given |data| and |len|.
- Input(const uint8_t* data, size_t len);
+ explicit Input(const uint8_t* data, size_t len);
+
+ // Creates an Input from a base::StringPiece.
+ explicit Input(const base::StringPiece& sp);
+
+ // Creates an Input from a std::string. The lifetimes are a bit subtle when
+ // using this function: The constructed Input is only valid so long as |s| is
+ // still alive and not mutated.
+ Input(const std::string* s);
// Returns the length in bytes of an Input's data.
size_t Length() const { return len_; }
@@ -64,11 +75,25 @@ class NET_EXPORT_PRIVATE Input {
// Returns a copy of the data represented by this object as a std::string.
std::string AsString() const;
+ // Returns a StringPiece pointing to the same data as the Input. The resulting
+ // StringPiece must not outlive the data that was used to construct this
+ // Input.
+ base::StringPiece AsStringPiece() const;
+
private:
+ // This constructor is deleted to prevent constructing an Input from a
+ // std::string r-value. Since the Input points to memory owned by another
+ // object, such an Input would point to invalid memory. Without this deleted
+ // constructor, a std::string could be passed in to the base::StringPiece
+ // constructor because of StringPiece's implicit constructor.
+ Input(std::string) = delete;
const uint8_t* data_;
size_t len_;
};
+// Returns true if |lhs|'s data is lexicographically less than |rhs|'s data.
+NET_EXPORT_PRIVATE bool operator<(const Input& lhs, const Input& rhs);
+
// This class provides ways to read data from an Input in a bounds-checked way.
// The ByteReader is designed to read through the input sequentially. Once a
// byte has been read with a ByteReader, the caller can't go back and re-read
diff --git a/chromium/net/der/input_unittest.cc b/chromium/net/der/input_unittest.cc
index 63fe715c33e..e7193b08b52 100644
--- a/chromium/net/der/input_unittest.cc
+++ b/chromium/net/der/input_unittest.cc
@@ -11,6 +11,7 @@ namespace der {
namespace test {
const uint8_t kInput[] = {'t', 'e', 's', 't'};
+const uint8_t kInput2[] = {'t', 'e', 'a', 'l'};
TEST(InputTest, Equals) {
Input test(kInput);
@@ -27,6 +28,19 @@ TEST(InputTest, Equals) {
EXPECT_FALSE(test_truncated.Equals(test));
}
+TEST(InputTest, LessThan) {
+ Input test(kInput);
+ EXPECT_FALSE(test < test);
+
+ Input test2(kInput2);
+ EXPECT_FALSE(test < test2);
+ EXPECT_TRUE(test2 < test);
+
+ Input test_truncated(kInput, arraysize(kInput) - 1);
+ EXPECT_FALSE(test < test_truncated);
+ EXPECT_TRUE(test_truncated < test);
+}
+
TEST(InputTest, AsString) {
Input input(kInput);
std::string expected_string(reinterpret_cast<const char*>(kInput),
diff --git a/chromium/net/der/parse_values.cc b/chromium/net/der/parse_values.cc
index 7920d9fc89d..a2df4b8af65 100644
--- a/chromium/net/der/parse_values.cc
+++ b/chromium/net/der/parse_values.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
+
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "net/der/parse_values.h"
@@ -191,10 +193,48 @@ bool ParseUint64(const Input& in, uint64_t* out) {
return true;
}
+bool ParseUint8(const Input& in, uint8_t* out) {
+ // TODO(eroman): Implement this more directly.
+ uint64_t value;
+ if (!ParseUint64(in, &value))
+ return false;
+
+ if (value > 0xFF)
+ return false;
+
+ *out = static_cast<uint8_t>(value);
+ return true;
+}
+
BitString::BitString(const Input& bytes, uint8_t unused_bits)
: bytes_(bytes), unused_bits_(unused_bits) {
DCHECK_LT(unused_bits, 8);
DCHECK(unused_bits == 0 || bytes.Length() != 0);
+ // The unused bits must be zero.
+ DCHECK(bytes.Length() == 0 ||
+ (bytes.UnsafeData()[bytes.Length() - 1] & ((1u << unused_bits) - 1)) ==
+ 0);
+}
+
+bool BitString::AssertsBit(size_t bit_index) const {
+ // Index of the byte that contains the bit.
+ size_t byte_index = bit_index / 8;
+
+ // If the bit is outside of the bitstring, by definition it is not
+ // asserted.
+ if (byte_index >= bytes_.Length())
+ return false;
+
+ // Within a byte, bits are ordered from most significant to least significant.
+ // Convert |bit_index| to an index within the |byte_index| byte, measured from
+ // its least significant bit.
+ uint8_t bit_index_in_byte = 7 - (bit_index - byte_index * 8);
+
+ // BIT STRING parsing already guarantees that unused bits in a byte are zero
+ // (otherwise it wouldn't be valid DER). Therefore it isn't necessary to check
+ // |unused_bits_|
+ uint8_t byte = bytes_.UnsafeData()[byte_index];
+ return 0 != (byte & (1 << bit_index_in_byte));
}
bool ParseBitString(const Input& in, BitString* out) {
@@ -239,17 +279,9 @@ bool ParseBitString(const Input& in, BitString* out) {
}
bool operator<(const GeneralizedTime& lhs, const GeneralizedTime& rhs) {
- if (lhs.year != rhs.year)
- return lhs.year < rhs.year;
- if (lhs.month != rhs.month)
- return lhs.month < rhs.month;
- if (lhs.day != rhs.day)
- return lhs.day < rhs.day;
- if (lhs.hours != rhs.hours)
- return lhs.hours < rhs.hours;
- if (lhs.minutes != rhs.minutes)
- return lhs.minutes < rhs.minutes;
- return lhs.seconds < rhs.seconds;
+ return std::tie(lhs.year, lhs.month, lhs.day, lhs.hours, lhs.minutes,
+ lhs.seconds) < std::tie(rhs.year, rhs.month, rhs.day,
+ rhs.hours, rhs.minutes, rhs.seconds);
}
// A UTC Time in DER encoding should be YYMMDDHHMMSSZ, but some CAs encode
diff --git a/chromium/net/der/parse_values.h b/chromium/net/der/parse_values.h
index 27a6f5fb7fc..4f503566dfd 100644
--- a/chromium/net/der/parse_values.h
+++ b/chromium/net/der/parse_values.h
@@ -5,6 +5,8 @@
#ifndef NET_DER_PARSE_VALUES_H_
#define NET_DER_PARSE_VALUES_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/der/input.h"
@@ -41,6 +43,9 @@ NET_EXPORT bool IsValidInteger(const Input& in,
// integer.
NET_EXPORT bool ParseUint64(const Input& in, uint64_t* out) WARN_UNUSED_RESULT;
+// Same as ParseUint64() but for a uint8_t.
+NET_EXPORT bool ParseUint8(const Input& in, uint8_t* out) WARN_UNUSED_RESULT;
+
// The BitString class is a helper for representing a valid parsed BIT STRING.
//
// * The bits are ordered within each octet of bytes() from most to least
@@ -59,6 +64,14 @@ class NET_EXPORT BitString {
const Input& bytes() const { return bytes_; }
uint8_t unused_bits() const { return unused_bits_; }
+ // Returns true if the bit string contains 1 at the specified position.
+ // Otherwise returns false.
+ //
+ // A return value of false can mean either:
+ // * The bit value at |bit_index| is 0.
+ // * There is no bit at |bit_index| (index is beyond the end).
+ bool AssertsBit(size_t bit_index) const WARN_UNUSED_RESULT;
+
private:
Input bytes_;
uint8_t unused_bits_;
@@ -100,7 +113,7 @@ NET_EXPORT bool ParseUTCTimeRelaxed(const Input& in,
// Reads a DER-encoded ASN.1 GeneralizedTime value from |in| and puts the
// resulting value in |out|, returning true if the GeneralizedTime could
-// be parsed sucessfully. This function is even more restrictive than the
+// be parsed successfully. This function is even more restrictive than the
// DER rules - it follows the rules from RFC5280, which does not allow for
// fractional seconds.
NET_EXPORT bool ParseGeneralizedTime(const Input& in,
diff --git a/chromium/net/der/parse_values_unittest.cc b/chromium/net/der/parse_values_unittest.cc
index b76c4c99c8d..b29634f15ac 100644
--- a/chromium/net/der/parse_values_unittest.cc
+++ b/chromium/net/der/parse_values_unittest.cc
@@ -214,6 +214,42 @@ TEST(ParseValuesTest, ParseUint64) {
}
}
+struct Uint8TestData {
+ bool should_pass;
+ const uint8_t input[9];
+ size_t length;
+ uint8_t expected_value;
+};
+
+const Uint8TestData kUint8TestData[] = {
+ {true, {0x00}, 1, 0},
+ // This number fails because it is not a minimal representation.
+ {false, {0x00, 0x00}, 2},
+ {true, {0x01}, 1, 1},
+ {false, {0x01, 0xFF}, 2},
+ {false, {0x03, 0x83}, 2},
+ {true, {0x7F}, 1, 0x7F},
+ {true, {0x00, 0xFF}, 2, 0xFF},
+ // This number fails because it is negative.
+ {false, {0xFF}, 1},
+ {false, {0x80}, 1},
+ {false, {0x00, 0x01}, 2},
+ {false, {0}, 0},
+};
+
+TEST(ParseValuesTest, ParseUint8) {
+ for (size_t i = 0; i < arraysize(kUint8TestData); i++) {
+ const Uint8TestData& test_case = kUint8TestData[i];
+ SCOPED_TRACE(i);
+
+ uint8_t result;
+ EXPECT_EQ(test_case.should_pass,
+ ParseUint8(Input(test_case.input, test_case.length), &result));
+ if (test_case.should_pass)
+ EXPECT_EQ(test_case.expected_value, result);
+ }
+}
+
struct IsValidIntegerTestData {
bool should_pass;
const uint8_t input[2];
@@ -269,6 +305,10 @@ TEST(ParseValuesTest, ParseBitStringEmptyNoUnusedBits) {
EXPECT_EQ(0u, bit_string.unused_bits());
EXPECT_EQ(0u, bit_string.bytes().Length());
+
+ EXPECT_FALSE(bit_string.AssertsBit(0));
+ EXPECT_FALSE(bit_string.AssertsBit(1));
+ EXPECT_FALSE(bit_string.AssertsBit(3));
}
// Tests parsing an empty BIT STRING that incorrectly claims one unused bit.
@@ -298,6 +338,16 @@ TEST(ParseValuesTest, ParseBitStringSevenOneBits) {
EXPECT_EQ(1u, bit_string.unused_bits());
EXPECT_EQ(1u, bit_string.bytes().Length());
EXPECT_EQ(0xFE, bit_string.bytes().UnsafeData()[0]);
+
+ EXPECT_TRUE(bit_string.AssertsBit(0));
+ EXPECT_TRUE(bit_string.AssertsBit(1));
+ EXPECT_TRUE(bit_string.AssertsBit(2));
+ EXPECT_TRUE(bit_string.AssertsBit(3));
+ EXPECT_TRUE(bit_string.AssertsBit(4));
+ EXPECT_TRUE(bit_string.AssertsBit(5));
+ EXPECT_TRUE(bit_string.AssertsBit(6));
+ EXPECT_FALSE(bit_string.AssertsBit(7));
+ EXPECT_FALSE(bit_string.AssertsBit(8));
}
// Tests parsing a BIT STRING of 7 bits each of which are 1. The unused bit
diff --git a/chromium/net/der/parser.h b/chromium/net/der/parser.h
index 37f1f856c4c..2192371d6c6 100644
--- a/chromium/net/der/parser.h
+++ b/chromium/net/der/parser.h
@@ -5,7 +5,10 @@
#ifndef NET_DER_PARSER_H_
#define NET_DER_PARSER_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/der/input.h"
@@ -146,7 +149,7 @@ class NET_EXPORT Parser {
// Expects the current tag to be kInteger, and calls ParseUint64 on the
// current value. Note that DER-encoded integers are arbitrary precision,
// so this method will fail for valid input that represents an integer
- // outside the range of an int64.
+ // outside the range of an int64_t.
//
// Note that on failure the Parser is left in an undefined state (the
// input may or may not have been advanced).
diff --git a/chromium/net/der/tag.cc b/chromium/net/der/tag.cc
index a8240243943..99acf8cdfd8 100644
--- a/chromium/net/der/tag.cc
+++ b/chromium/net/der/tag.cc
@@ -20,10 +20,18 @@ Tag ContextSpecificPrimitive(uint8_t base) {
return (base & kTagNumberMask) | kTagPrimitive | kTagContextSpecific;
}
+bool IsContextSpecific(Tag tag) {
+ return (tag & kTagClassMask) == kTagContextSpecific;
+}
+
bool IsConstructed(Tag tag) {
return (tag & kTagConstructionMask) == kTagConstructed;
}
+uint8_t GetTagNumber(Tag tag) {
+ return tag & kTagNumberMask;
+}
+
} // namespace der
} // namespace net
diff --git a/chromium/net/der/tag.h b/chromium/net/der/tag.h
index 4f8752b6173..cb18ac6a7c1 100644
--- a/chromium/net/der/tag.h
+++ b/chromium/net/der/tag.h
@@ -28,6 +28,7 @@ const Tag kBitString = 0x03;
const Tag kOctetString = 0x04;
const Tag kNull = 0x05;
const Tag kOid = 0x06;
+const Tag kEnumerated = 0x0A;
const Tag kUtf8String = 0x0C;
const Tag kPrintableString = 0x13;
const Tag kIA5String = 0x16;
@@ -65,8 +66,13 @@ const uint8_t kTagClassMask = 0xC0;
NET_EXPORT Tag ContextSpecificConstructed(uint8_t class_number);
NET_EXPORT Tag ContextSpecificPrimitive(uint8_t base);
+
+NET_EXPORT bool IsContextSpecific(Tag tag);
+
NET_EXPORT bool IsConstructed(Tag tag);
+NET_EXPORT uint8_t GetTagNumber(Tag tag);
+
} // namespace der
} // namespace net
diff --git a/chromium/net/disk_cache/backend_unittest.cc b/chromium/net/disk_cache/backend_unittest.cc
index d1d72a4084d..fb7396ca52a 100644
--- a/chromium/net/disk_cache/backend_unittest.cc
+++ b/chromium/net/disk_cache/backend_unittest.cc
@@ -4,7 +4,6 @@
#include <stdint.h>
-#include "base/basictypes.h"
#include "base/files/file_util.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
@@ -65,7 +64,7 @@ scoped_ptr<disk_cache::BackendImpl> CreateExistingEntryCache(
return scoped_ptr<disk_cache::BackendImpl>();
entry->Close();
- return cache.Pass();
+ return cache;
}
} // namespace
@@ -89,6 +88,10 @@ class DiskCacheBackendTest : public DiskCacheTestWithCache {
std::set<std::string>* keys_to_match,
size_t* count);
+ // Computes the expected size of entry metadata, i.e. the total size without
+ // the actual data stored. This depends only on the entry's |key| size.
+ int GetEntryMetadataSize(std::string key);
+
// Actual tests:
void BackendBasics();
void BackendKeying();
@@ -110,6 +113,7 @@ class DiskCacheBackendTest : public DiskCacheTestWithCache {
void BackendFixEnumerators();
void BackendDoomRecent();
void BackendDoomBetween();
+ void BackendCalculateSizeOfAllEntries();
void BackendTransaction(const std::string& name, int num_entries, bool load);
void BackendRecoverInsert();
void BackendRecoverRemove();
@@ -281,6 +285,18 @@ bool DiskCacheBackendTest::EnumerateAndMatchKeys(
return true;
}
+int DiskCacheBackendTest::GetEntryMetadataSize(std::string key) {
+ // For blockfile and memory backends, it is just the key size.
+ if (!simple_cache_mode_)
+ return key.size();
+
+ // For the simple cache, we must add the file header and EOF, and that for
+ // every stream.
+ return disk_cache::kSimpleEntryStreamCount *
+ (sizeof(disk_cache::SimpleFileHeader) +
+ sizeof(disk_cache::SimpleFileEOF) + key.size());
+}
+
void DiskCacheBackendTest::BackendBasics() {
InitCache();
disk_cache::Entry *entry1 = NULL, *entry2 = NULL;
@@ -504,7 +520,7 @@ TEST_F(DiskCacheBackendTest, ExternalFiles) {
// Tests that we deal with file-level pending operations at destruction time.
void DiskCacheBackendTest::BackendShutdownWithPendingFileIO(bool fast) {
ASSERT_TRUE(CleanupCacheDir());
- uint32 flags = disk_cache::kNoBuffering;
+ uint32_t flags = disk_cache::kNoBuffering;
if (!fast)
flags |= disk_cache::kNoRandom;
@@ -606,7 +622,7 @@ void DiskCacheBackendTest::BackendShutdownWithPendingIO(bool fast) {
ASSERT_TRUE(cache_thread.StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
- uint32 flags = disk_cache::kNoBuffering;
+ uint32_t flags = disk_cache::kNoBuffering;
if (!fast)
flags |= disk_cache::kNoRandom;
@@ -1674,13 +1690,90 @@ TEST_F(DiskCacheBackendTest, DoomEntriesBetweenSparse) {
EXPECT_EQ(3, cache_->GetEntryCount());
}
+void DiskCacheBackendTest::BackendCalculateSizeOfAllEntries() {
+ InitCache();
+
+ // The cache is initially empty.
+ EXPECT_EQ(0, CalculateSizeOfAllEntries());
+
+ // Generate random entries and populate them with data of respective
+ // sizes 0, 1, ..., count - 1 bytes.
+ std::set<std::string> key_pool;
+ CreateSetOfRandomEntries(&key_pool);
+
+ int count = 0;
+ for (std::string key : key_pool) {
+ std::string data(count, ' ');
+ scoped_refptr<net::StringIOBuffer> buffer = new net::StringIOBuffer(data);
+
+ // Alternate between writing to first two streams to test that we do not
+ // take only one stream into account.
+ disk_cache::Entry* entry;
+ ASSERT_EQ(net::OK, OpenEntry(key, &entry));
+ ASSERT_EQ(count, WriteData(entry, count % 2, 0, buffer.get(), count, true));
+ entry->Close();
+
+ ++count;
+ }
+
+ // The resulting size should be (0 + 1 + ... + count - 1) plus keys.
+ int result = CalculateSizeOfAllEntries();
+ int total_metadata_size = 0;
+ for (std::string key : key_pool)
+ total_metadata_size += GetEntryMetadataSize(key);
+ EXPECT_EQ((count - 1) * count / 2 + total_metadata_size, result);
+
+ // Add another entry and test if the size is updated. Then remove it and test
+ // if the size is back to original value.
+ {
+ const int last_entry_size = 47;
+ std::string data(last_entry_size, ' ');
+ scoped_refptr<net::StringIOBuffer> buffer = new net::StringIOBuffer(data);
+
+ disk_cache::Entry* entry;
+ std::string key = GenerateKey(true);
+ ASSERT_EQ(net::OK, CreateEntry(key, &entry));
+ ASSERT_EQ(last_entry_size,
+ WriteData(entry, 0, 0, buffer.get(), last_entry_size, true));
+ entry->Close();
+
+ int new_result = CalculateSizeOfAllEntries();
+ EXPECT_EQ(result + last_entry_size + GetEntryMetadataSize(key), new_result);
+
+ DoomEntry(key);
+ new_result = CalculateSizeOfAllEntries();
+ EXPECT_EQ(result, new_result);
+ }
+
+ // After dooming the entries, the size should be back to zero.
+ ASSERT_EQ(net::OK, DoomAllEntries());
+ EXPECT_EQ(0, CalculateSizeOfAllEntries());
+}
+
+TEST_F(DiskCacheBackendTest, CalculateSizeOfAllEntries) {
+ BackendCalculateSizeOfAllEntries();
+}
+
+TEST_F(DiskCacheBackendTest, MemoryOnlyCalculateSizeOfAllEntries) {
+ SetMemoryOnlyMode();
+ BackendCalculateSizeOfAllEntries();
+}
+
+TEST_F(DiskCacheBackendTest, SimpleCacheCalculateSizeOfAllEntries) {
+ // Use net::APP_CACHE to make size estimations deterministic via
+ // non-optimistic writes.
+ SetCacheType(net::APP_CACHE);
+ SetSimpleCacheMode();
+ BackendCalculateSizeOfAllEntries();
+}
+
void DiskCacheBackendTest::BackendTransaction(const std::string& name,
int num_entries, bool load) {
success_ = false;
ASSERT_TRUE(CopyTestCache(name));
DisableFirstCleanup();
- uint32 mask;
+ uint32_t mask;
if (load) {
mask = 0xf;
SetMaxSize(0x100000);
@@ -2981,7 +3074,7 @@ TEST_F(DiskCacheTest, MultipleInstances) {
// Test the six regions of the curve that determines the max cache size.
TEST_F(DiskCacheTest, AutomaticMaxSize) {
using disk_cache::kDefaultCacheSize;
- int64 large_size = kDefaultCacheSize;
+ int64_t large_size = kDefaultCacheSize;
// Region 1: expected = available * 0.8
EXPECT_EQ((kDefaultCacheSize - 1) * 8 / 10,
@@ -3014,7 +3107,7 @@ TEST_F(DiskCacheTest, AutomaticMaxSize) {
disk_cache::PreferredCacheSize(large_size * 250 - 1));
// Region 5: expected = available * 0.1
- int64 largest_size = kDefaultCacheSize * 4;
+ int64_t largest_size = kDefaultCacheSize * 4;
EXPECT_EQ(kDefaultCacheSize * 25 / 10,
disk_cache::PreferredCacheSize(large_size * 250));
EXPECT_EQ(largest_size - 1,
diff --git a/chromium/net/disk_cache/blockfile/addr.h b/chromium/net/disk_cache/blockfile/addr.h
index a5e4367757b..cf6071ed9de 100644
--- a/chromium/net/disk_cache/blockfile/addr.h
+++ b/chromium/net/disk_cache/blockfile/addr.h
@@ -8,6 +8,9 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_ADDR_H_
#define NET_DISK_CACHE_BLOCKFILE_ADDR_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/disk_format_base.h"
@@ -25,9 +28,9 @@ enum FileType {
};
const int kMaxBlockSize = 4096 * 4;
-const int16 kMaxBlockFile = 255;
+const int16_t kMaxBlockFile = 255;
const int kMaxNumBlocks = 4;
-const int16 kFirstAdditionalBlockFile = 4;
+const int16_t kFirstAdditionalBlockFile = 4;
const size_t kFirstAdditionalBlockFileV3 = 7;
// Defines a storage address for a cache record
@@ -165,20 +168,18 @@ class NET_EXPORT_PRIVATE Addr {
bool SanityCheckForRankings() const;
private:
- uint32 reserved_bits() const {
- return value_ & kReservedBitsMask;
- }
-
- static const uint32 kInitializedMask = 0x80000000;
- static const uint32 kFileTypeMask = 0x70000000;
- static const uint32 kFileTypeOffset = 28;
- static const uint32 kReservedBitsMask = 0x0c000000;
- static const uint32 kNumBlocksMask = 0x03000000;
- static const uint32 kNumBlocksOffset = 24;
- static const uint32 kFileSelectorMask = 0x00ff0000;
- static const uint32 kFileSelectorOffset = 16;
- static const uint32 kStartBlockMask = 0x0000FFFF;
- static const uint32 kFileNameMask = 0x0FFFFFFF;
+ uint32_t reserved_bits() const { return value_ & kReservedBitsMask; }
+
+ static const uint32_t kInitializedMask = 0x80000000;
+ static const uint32_t kFileTypeMask = 0x70000000;
+ static const uint32_t kFileTypeOffset = 28;
+ static const uint32_t kReservedBitsMask = 0x0c000000;
+ static const uint32_t kNumBlocksMask = 0x03000000;
+ static const uint32_t kNumBlocksOffset = 24;
+ static const uint32_t kFileSelectorMask = 0x00ff0000;
+ static const uint32_t kFileSelectorOffset = 16;
+ static const uint32_t kStartBlockMask = 0x0000FFFF;
+ static const uint32_t kFileNameMask = 0x0FFFFFFF;
CacheAddr value_;
};
diff --git a/chromium/net/disk_cache/blockfile/addr_unittest.cc b/chromium/net/disk_cache/blockfile/addr_unittest.cc
index eaed65976b2..b62e31f7925 100644
--- a/chromium/net/disk_cache/blockfile/addr_unittest.cc
+++ b/chromium/net/disk_cache/blockfile/addr_unittest.cc
@@ -13,7 +13,7 @@ TEST_F(DiskCacheTest, CacheAddr_Size) {
EXPECT_FALSE(addr1.is_initialized());
// The object should not be more expensive than the actual address.
- EXPECT_EQ(sizeof(uint32), sizeof(addr1));
+ EXPECT_EQ(sizeof(uint32_t), sizeof(addr1));
}
TEST_F(DiskCacheTest, CacheAddr_ValidValues) {
diff --git a/chromium/net/disk_cache/blockfile/backend_impl.cc b/chromium/net/disk_cache/blockfile/backend_impl.cc
index 82a58b36b6d..980ddc73a53 100644
--- a/chromium/net/disk_cache/blockfile/backend_impl.cc
+++ b/chromium/net/disk_cache/blockfile/backend_impl.cc
@@ -4,6 +4,9 @@
#include "net/disk_cache/blockfile/backend_impl.h"
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file.h"
@@ -53,7 +56,7 @@ const int kBaseTableLen = 64 * 1024;
// Avoid trimming the cache for the first 5 minutes (10 timer ticks).
const int kTrimDelay = 10;
-int DesiredIndexTableLen(int32 storage_size) {
+int DesiredIndexTableLen(int32_t storage_size) {
if (storage_size <= k64kEntriesStore)
return kBaseTableLen;
if (storage_size <= k64kEntriesStore * 2)
@@ -63,7 +66,7 @@ int DesiredIndexTableLen(int32 storage_size) {
if (storage_size <= k64kEntriesStore * 8)
return kBaseTableLen * 8;
- // The biggest storage_size for int32 requires a 4 MB table.
+ // The biggest storage_size for int32_t requires a 4 MB table.
return kBaseTableLen * 16;
}
@@ -139,7 +142,7 @@ BackendImpl::BackendImpl(
BackendImpl::BackendImpl(
const base::FilePath& path,
- uint32 mask,
+ uint32_t mask,
const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread,
net::NetLog* net_log)
: background_queue_(this, cache_thread),
@@ -161,8 +164,7 @@ BackendImpl::BackendImpl(
user_load_(false),
net_log_(net_log),
done_(true, false),
- ptr_factory_(this) {
-}
+ ptr_factory_(this) {}
BackendImpl::~BackendImpl() {
if (user_flags_ & kNoRandom) {
@@ -401,7 +403,7 @@ int BackendImpl::SyncDoomEntriesBetween(const base::Time initial_time,
if (next)
next->Release();
next = NULL;
- SyncEndEnumeration(iterator.Pass());
+ SyncEndEnumeration(std::move(iterator));
}
node->Release();
@@ -410,6 +412,14 @@ int BackendImpl::SyncDoomEntriesBetween(const base::Time initial_time,
return net::OK;
}
+int BackendImpl::SyncCalculateSizeOfAllEntries() {
+ DCHECK_NE(net::APP_CACHE, cache_type_);
+ if (disabled_)
+ return net::ERR_FAILED;
+
+ return data_->header.num_bytes;
+}
+
// We use OpenNextEntryImpl to retrieve elements from the cache, until we get
// entries that are too old.
int BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) {
@@ -426,13 +436,14 @@ int BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) {
if (initial_time > entry->GetLastUsed()) {
entry->Release();
- SyncEndEnumeration(iterator.Pass());
+ SyncEndEnumeration(std::move(iterator));
return net::OK;
}
entry->DoomImpl();
entry->Release();
- SyncEndEnumeration(iterator.Pass()); // The doom invalidated the iterator.
+ SyncEndEnumeration(
+ std::move(iterator)); // The doom invalidated the iterator.
}
}
@@ -450,7 +461,7 @@ void BackendImpl::SyncOnExternalCacheHit(const std::string& key) {
if (disabled_)
return;
- uint32 hash = base::Hash(key);
+ uint32_t hash = base::Hash(key);
bool error;
EntryImpl* cache_entry = MatchEntry(key, hash, false, Addr(), &error);
if (cache_entry) {
@@ -466,7 +477,7 @@ EntryImpl* BackendImpl::OpenEntryImpl(const std::string& key) {
return NULL;
TimeTicks start = TimeTicks::Now();
- uint32 hash = base::Hash(key);
+ uint32_t hash = base::Hash(key);
Trace("Open hash 0x%x", hash);
bool error;
@@ -481,9 +492,9 @@ EntryImpl* BackendImpl::OpenEntryImpl(const std::string& key) {
}
int current_size = data_->header.num_bytes / (1024 * 1024);
- int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120;
- int64 no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
- int64 use_hours = total_hours - no_use_hours;
+ int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120;
+ int64_t no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
+ int64_t use_hours = total_hours - no_use_hours;
if (!cache_entry) {
CACHE_UMA(AGE_MS, "OpenTime.Miss", 0, start);
@@ -517,7 +528,7 @@ EntryImpl* BackendImpl::CreateEntryImpl(const std::string& key) {
return NULL;
TimeTicks start = TimeTicks::Now();
- uint32 hash = base::Hash(key);
+ uint32_t hash = base::Hash(key);
Trace("Create hash 0x%x", hash);
scoped_refptr<EntryImpl> parent;
@@ -689,8 +700,11 @@ bool BackendImpl::SetMaxSize(int max_bytes) {
return true;
// Avoid a DCHECK later on.
- if (max_bytes >= kint32max - kint32max / 10)
- max_bytes = kint32max - kint32max / 10 - 1;
+ if (max_bytes >= std::numeric_limits<int32_t>::max() -
+ std::numeric_limits<int32_t>::max() / 10) {
+ max_bytes = std::numeric_limits<int32_t>::max() -
+ std::numeric_limits<int32_t>::max() / 10 - 1;
+ }
user_flags_ |= kMaxSize;
max_size_ = max_bytes;
@@ -784,7 +798,7 @@ void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) {
return;
}
- uint32 hash = cache_entry->GetHash();
+ uint32_t hash = cache_entry->GetHash();
cache_entry->Release();
// Anything on the table means that this entry is there.
@@ -796,7 +810,7 @@ void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) {
}
void BackendImpl::InternalDoomEntry(EntryImpl* entry) {
- uint32 hash = entry->GetHash();
+ uint32_t hash = entry->GetHash();
std::string key = entry->GetKey();
Addr entry_addr = entry->entry()->address();
bool error;
@@ -843,7 +857,7 @@ CacheAddr BackendImpl::GetNextAddr(Addr address) {
void BackendImpl::NotLinked(EntryImpl* entry) {
Addr entry_addr = entry->entry()->address();
- uint32 i = entry->GetHash() & mask_;
+ uint32_t i = entry->GetHash() & mask_;
Addr address(data_->table[i]);
if (!address.is_initialized())
return;
@@ -898,7 +912,7 @@ EntryImpl* BackendImpl::GetOpenEntry(CacheRankingsBlock* rankings) const {
return NULL;
}
-int32 BackendImpl::GetCurrentEntryId() const {
+int32_t BackendImpl::GetCurrentEntryId() const {
return data_->header.this_id;
}
@@ -906,7 +920,7 @@ int BackendImpl::MaxFileSize() const {
return cache_type() == net::PNACL_CACHE ? max_size_ : max_size_ / 8;
}
-void BackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) {
+void BackendImpl::ModifyStorageSize(int32_t old_size, int32_t new_size) {
if (disabled_ || old_size == new_size)
return;
if (old_size > new_size)
@@ -920,7 +934,7 @@ void BackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) {
stats_.ModifyStorageStats(old_size, new_size);
}
-void BackendImpl::TooMuchStorageRequested(int32 size) {
+void BackendImpl::TooMuchStorageRequested(int32_t size) {
stats_.ModifyStorageStats(0, size);
}
@@ -969,7 +983,7 @@ bool BackendImpl::ShouldReportAgain() {
return uma_report_ == 2;
uma_report_++;
- int64 last_report = stats_.GetCounter(Stats::LAST_REPORT);
+ int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT);
Time last_time = Time::FromInternalValue(last_report);
if (!last_report || (Time::Now() - last_time).InDays() >= 7) {
stats_.SetCounter(Stats::LAST_REPORT, Time::Now().ToInternalValue());
@@ -987,7 +1001,7 @@ void BackendImpl::FirstEviction() {
Time create_time = Time::FromInternalValue(data_->header.create_time);
CACHE_UMA(AGE, "FillupAge", 0, create_time);
- int64 use_time = stats_.GetCounter(Stats::TIMER);
+ int64_t use_time = stats_.GetCounter(Stats::TIMER);
CACHE_UMA(HOURS, "FillupTime", 0, static_cast<int>(use_time / 120));
CACHE_UMA(PERCENTAGE, "FirstHitRatio", 0, stats_.GetHitRatio());
@@ -1051,14 +1065,14 @@ void BackendImpl::OnEvent(Stats::Counters an_event) {
stats_.OnEvent(an_event);
}
-void BackendImpl::OnRead(int32 bytes) {
+void BackendImpl::OnRead(int32_t bytes) {
DCHECK_GE(bytes, 0);
byte_count_ += bytes;
if (byte_count_ < 0)
- byte_count_ = kint32max;
+ byte_count_ = std::numeric_limits<int32_t>::max();
}
-void BackendImpl::OnWrite(int32 bytes) {
+void BackendImpl::OnWrite(int32_t bytes) {
// We use the same implementation as OnRead... just log the number of bytes.
OnRead(bytes);
}
@@ -1068,13 +1082,13 @@ void BackendImpl::OnStatsTimer() {
return;
stats_.OnEvent(Stats::TIMER);
- int64 time = stats_.GetCounter(Stats::TIMER);
- int64 current = stats_.GetCounter(Stats::OPEN_ENTRIES);
+ int64_t time = stats_.GetCounter(Stats::TIMER);
+ int64_t current = stats_.GetCounter(Stats::OPEN_ENTRIES);
// OPEN_ENTRIES is a sampled average of the number of open entries, avoiding
// the bias towards 0.
if (num_refs_ && (current != num_refs_)) {
- int64 diff = (num_refs_ - current) / 50;
+ int64_t diff = (num_refs_ - current) / 50;
if (!diff)
diff = num_refs_ > current ? 1 : -1;
current = current + diff;
@@ -1129,7 +1143,7 @@ void BackendImpl::SetNewEviction() {
new_eviction_ = true;
}
-void BackendImpl::SetFlags(uint32 flags) {
+void BackendImpl::SetFlags(uint32_t flags) {
user_flags_ |= flags;
}
@@ -1197,12 +1211,12 @@ net::CacheType BackendImpl::GetCacheType() const {
return cache_type_;
}
-int32 BackendImpl::GetEntryCount() const {
+int32_t BackendImpl::GetEntryCount() const {
if (!index_.get() || disabled_)
return 0;
// num_entries includes entries already evicted.
- int32 not_deleted = data_->header.num_entries -
- data_->header.lru.sizes[Rankings::DELETED];
+ int32_t not_deleted =
+ data_->header.num_entries - data_->header.lru.sizes[Rankings::DELETED];
if (not_deleted < 0) {
NOTREACHED();
@@ -1254,6 +1268,12 @@ int BackendImpl::DoomEntriesSince(const base::Time initial_time,
return net::ERR_IO_PENDING;
}
+int BackendImpl::CalculateSizeOfAllEntries(const CompletionCallback& callback) {
+ DCHECK(!callback.is_null());
+ background_queue_.CalculateSizeOfAllEntries(callback);
+ return net::ERR_IO_PENDING;
+}
+
class BackendImpl::IteratorImpl : public Backend::Iterator {
public:
explicit IteratorImpl(base::WeakPtr<InFlightBackendIO> background_queue)
@@ -1263,7 +1283,7 @@ class BackendImpl::IteratorImpl : public Backend::Iterator {
~IteratorImpl() override {
if (background_queue_)
- background_queue_->EndEnumeration(iterator_.Pass());
+ background_queue_->EndEnumeration(std::move(iterator_));
}
int OpenNextEntry(Entry** next_entry,
@@ -1353,7 +1373,8 @@ bool BackendImpl::InitBackingStore(bool* file_created) {
bool ret = true;
*file_created = base_file.created();
- scoped_refptr<disk_cache::File> file(new disk_cache::File(base_file.Pass()));
+ scoped_refptr<disk_cache::File> file(
+ new disk_cache::File(std::move(base_file)));
if (*file_created)
ret = CreateBackingStore(file.get());
@@ -1388,7 +1409,7 @@ void BackendImpl::AdjustMaxCacheSize(int table_len) {
DCHECK(!table_len || data_->header.magic);
// The user is not setting the size, let's figure it out.
- int64 available = base::SysInfo::AmountOfFreeDiskSpace(path_);
+ int64_t available = base::SysInfo::AmountOfFreeDiskSpace(path_);
if (available < 0) {
max_size_ = kDefaultCacheSize;
return;
@@ -1467,10 +1488,10 @@ void BackendImpl::StoreStats() {
}
void BackendImpl::RestartCache(bool failure) {
- int64 errors = stats_.GetCounter(Stats::FATAL_ERROR);
- int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE);
- int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT);
- int64 last_report = stats_.GetCounter(Stats::LAST_REPORT);
+ int64_t errors = stats_.GetCounter(Stats::FATAL_ERROR);
+ int64_t full_dooms = stats_.GetCounter(Stats::DOOM_CACHE);
+ int64_t partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT);
+ int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT);
PrepareForRestart();
if (failure) {
@@ -1589,8 +1610,10 @@ int BackendImpl::NewEntry(Addr address, EntryImpl** entry) {
return 0;
}
-EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash,
- bool find_parent, Addr entry_addr,
+EntryImpl* BackendImpl::MatchEntry(const std::string& key,
+ uint32_t hash,
+ bool find_parent,
+ Addr entry_addr,
bool* match_error) {
Addr address(data_->table[hash & mask_]);
scoped_refptr<EntryImpl> cache_entry, parent_entry;
@@ -1794,12 +1817,12 @@ void BackendImpl::DestroyInvalidEntry(EntryImpl* entry) {
stats_.OnEvent(Stats::INVALID_ENTRY);
}
-void BackendImpl::AddStorageSize(int32 bytes) {
+void BackendImpl::AddStorageSize(int32_t bytes) {
data_->header.num_bytes += bytes;
DCHECK_GE(data_->header.num_bytes, 0);
}
-void BackendImpl::SubstractStorageSize(int32 bytes) {
+void BackendImpl::SubstractStorageSize(int32_t bytes) {
data_->header.num_bytes -= bytes;
DCHECK_GE(data_->header.num_bytes, 0);
}
@@ -1879,7 +1902,7 @@ void BackendImpl::ReportStats() {
if (age)
CACHE_UMA(HOURS, "FilesAge", 0, age);
- int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120;
+ int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120;
if (!data_->header.create_time || !data_->header.lru.filled) {
int cause = data_->header.create_time ? 0 : 1;
if (!data_->header.lru.filled)
@@ -1899,7 +1922,7 @@ void BackendImpl::ReportStats() {
if (base::RandInt(0, 99) < hit_ratio_as_percentage)
CACHE_UMA(HOURS, "HitRatioByTotalTime", 0, static_cast<int>(total_hours));
- int64 use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
+ int64_t use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
stats_.SetCounter(Stats::LAST_REPORT_TIMER, stats_.GetCounter(Stats::TIMER));
// We may see users with no use_hours at this point if this is the first time
@@ -1918,7 +1941,7 @@ void BackendImpl::ReportStats() {
CACHE_UMA(HOURS, "HitRatioByUseTime", 0, static_cast<int>(use_hours));
CACHE_UMA(PERCENTAGE, "HitRatio", 0, hit_ratio_as_percentage);
- int64 trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours;
+ int64_t trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours;
CACHE_UMA(COUNTS, "TrimRate", 0, static_cast<int>(trim_rate));
int avg_size = data_->header.num_bytes / GetEntryCount();
@@ -2002,7 +2025,7 @@ bool BackendImpl::CheckIndex() {
#if !defined(NET_BUILD_STRESS_CACHE)
if (data_->header.num_bytes < 0 ||
- (max_size_ < kint32max - kDefaultCacheSize &&
+ (max_size_ < std::numeric_limits<int32_t>::max() - kDefaultCacheSize &&
data_->header.num_bytes > max_size_ + kDefaultCacheSize)) {
LOG(ERROR) << "Invalid cache (current) size";
return false;
@@ -2024,7 +2047,7 @@ bool BackendImpl::CheckIndex() {
int BackendImpl::CheckAllEntries() {
int num_dirty = 0;
int num_entries = 0;
- DCHECK(mask_ < kuint32max);
+ DCHECK(mask_ < std::numeric_limits<uint32_t>::max());
for (unsigned int i = 0; i <= mask_; i++) {
Addr address(data_->table[i]);
if (!address.is_initialized())
@@ -2080,7 +2103,7 @@ bool BackendImpl::CheckEntry(EntryImpl* cache_entry) {
}
int BackendImpl::MaxBuffersSize() {
- static int64 total_memory = base::SysInfo::AmountOfPhysicalMemory();
+ static int64_t total_memory = base::SysInfo::AmountOfPhysicalMemory();
static bool done = false;
if (!done) {
diff --git a/chromium/net/disk_cache/blockfile/backend_impl.h b/chromium/net/disk_cache/blockfile/backend_impl.h
index 3feafc19989..89edef2eb58 100644
--- a/chromium/net/disk_cache/blockfile/backend_impl.h
+++ b/chromium/net/disk_cache/blockfile/backend_impl.h
@@ -7,8 +7,11 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_H_
#define NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_H_
+#include <stdint.h>
+
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/timer/timer.h"
#include "net/disk_cache/blockfile/block_files.h"
@@ -54,7 +57,7 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
net::NetLog* net_log);
// mask can be used to limit the usable size of the hash table, for testing.
BackendImpl(const base::FilePath& path,
- uint32 mask,
+ uint32_t mask,
const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread,
net::NetLog* net_log);
~BackendImpl() override;
@@ -73,6 +76,7 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
int SyncDoomAllEntries();
int SyncDoomEntriesBetween(base::Time initial_time,
base::Time end_time);
+ int SyncCalculateSizeOfAllEntries();
int SyncDoomEntriesSince(base::Time initial_time);
int SyncOpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry);
void SyncEndEnumeration(scoped_ptr<Rankings::Iterator> iterator);
@@ -148,16 +152,16 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
EntryImpl* GetOpenEntry(CacheRankingsBlock* rankings) const;
// Returns the id being used on this run of the cache.
- int32 GetCurrentEntryId() const;
+ int32_t GetCurrentEntryId() const;
// Returns the maximum size for a file to reside on the cache.
int MaxFileSize() const;
// A user data block is being created, extended or truncated.
- void ModifyStorageSize(int32 old_size, int32 new_size);
+ void ModifyStorageSize(int32_t old_size, int32_t new_size);
// Logs requests that are denied due to being too big.
- void TooMuchStorageRequested(int32 size);
+ void TooMuchStorageRequested(int32_t size);
// Returns true if a temporary buffer is allowed to be extended.
bool IsAllocAllowed(int current_size, int new_size);
@@ -227,7 +231,7 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
void SetNewEviction();
// Sets an explicit set of BackendFlags.
- void SetFlags(uint32 flags);
+ void SetFlags(uint32_t flags);
// Clears the counter of references to test handling of corruptions.
void ClearRefCountForTest();
@@ -260,7 +264,7 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
// Backend implementation.
net::CacheType GetCacheType() const override;
- int32 GetEntryCount() const override;
+ int32_t GetEntryCount() const override;
int OpenEntry(const std::string& key,
Entry** entry,
const CompletionCallback& callback) override;
@@ -275,6 +279,7 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
const CompletionCallback& callback) override;
int DoomEntriesSince(base::Time initial_time,
const CompletionCallback& callback) override;
+ int CalculateSizeOfAllEntries(const CompletionCallback& callback) override;
// NOTE: The blockfile Backend::Iterator::OpenNextEntry method does not modify
// the last_used field of the entry, and therefore it does not impact the
// eviction ranking of the entry. However, an enumeration will go through all
@@ -314,8 +319,11 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
// if it doesn't match the entry on the index, we know that it was replaced
// with a new entry; in this case |*match_error| will be set to true and the
// return value will be NULL.
- EntryImpl* MatchEntry(const std::string& key, uint32 hash, bool find_parent,
- Addr entry_addr, bool* match_error);
+ EntryImpl* MatchEntry(const std::string& key,
+ uint32_t hash,
+ bool find_parent,
+ Addr entry_addr,
+ bool* match_error);
// Opens the next or previous entry on a single list. If successful,
// |from_entry| will be updated to point to the new entry, otherwise it will
@@ -333,8 +341,8 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
void DestroyInvalidEntry(EntryImpl* entry);
// Handles the used storage count.
- void AddStorageSize(int32 bytes);
- void SubstractStorageSize(int32 bytes);
+ void AddStorageSize(int32_t bytes);
+ void SubstractStorageSize(int32_t bytes);
// Update the number of referenced cache entries.
void IncreaseNumRefs();
@@ -369,8 +377,8 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
Index* data_; // Pointer to the index data.
BlockFiles block_files_; // Set of files used to store all data.
Rankings rankings_; // Rankings to be able to trim the cache.
- uint32 mask_; // Binary mask to map a hash to the hash table.
- int32 max_size_; // Maximum data size for this instance.
+ uint32_t mask_; // Binary mask to map a hash to the hash table.
+ int32_t max_size_; // Maximum data size for this instance.
Eviction eviction_; // Handler of the eviction algorithm.
EntriesMap open_entries_; // Map of open entries.
int num_refs_; // Number of referenced cache entries.
@@ -382,7 +390,7 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend {
int up_ticks_; // The number of timer ticks received (OnStatsTimer).
net::CacheType cache_type_;
int uma_report_; // Controls transmission of UMA data.
- uint32 user_flags_; // Flags set by the user.
+ uint32_t user_flags_; // Flags set by the user.
bool init_; // controls the initialization of the system.
bool restarted_;
bool unit_test_;
diff --git a/chromium/net/disk_cache/blockfile/backend_impl_v3.cc b/chromium/net/disk_cache/blockfile/backend_impl_v3.cc
index fd572c3e226..ae90bd96aef 100644
--- a/chromium/net/disk_cache/blockfile/backend_impl_v3.cc
+++ b/chromium/net/disk_cache/blockfile/backend_impl_v3.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/blockfile/backend_impl_v3.h"
+#include <limits>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
@@ -100,8 +102,11 @@ bool BackendImplV3::SetMaxSize(int max_bytes) {
return true;
// Avoid a DCHECK later on.
- if (max_bytes >= kint32max - kint32max / 10)
- max_bytes = kint32max - kint32max / 10 - 1;
+ if (max_bytes >= std::numeric_limits<int32_t>::max() -
+ std::numeric_limits<int32_t>::max() / 10) {
+ max_bytes = std::numeric_limits<int32_t>::max() -
+ std::numeric_limits<int32_t>::max() / 10 - 1;
+ }
user_flags_ |= MAX_SIZE;
max_size_ = max_bytes;
@@ -126,7 +131,7 @@ void BackendImplV3::UpdateRank(EntryImplV3* entry, bool modified) {
}
void BackendImplV3::InternalDoomEntry(EntryImplV3* entry) {
- uint32 hash = entry->GetHash();
+ uint32_t hash = entry->GetHash();
std::string key = entry->GetKey();
Addr entry_addr = entry->entry()->address();
bool error;
@@ -184,7 +189,7 @@ int BackendImplV3::MaxFileSize() const {
return max_size_ / 8;
}
-void BackendImplV3::ModifyStorageSize(int32 old_size, int32 new_size) {
+void BackendImplV3::ModifyStorageSize(int32_t old_size, int32_t new_size) {
if (disabled_ || old_size == new_size)
return;
if (old_size > new_size)
@@ -196,7 +201,7 @@ void BackendImplV3::ModifyStorageSize(int32 old_size, int32 new_size) {
stats_.ModifyStorageStats(old_size, new_size);
}
-void BackendImplV3::TooMuchStorageRequested(int32 size) {
+void BackendImplV3::TooMuchStorageRequested(int32_t size) {
stats_.ModifyStorageStats(0, size);
}
@@ -247,7 +252,7 @@ bool BackendImplV3::ShouldReportAgain() {
return uma_report_ == 2;
uma_report_++;
- int64 last_report = stats_.GetCounter(Stats::LAST_REPORT);
+ int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT);
Time last_time = Time::FromInternalValue(last_report);
if (!last_report || (Time::Now() - last_time).InDays() >= 7) {
stats_.SetCounter(Stats::LAST_REPORT, Time::Now().ToInternalValue());
@@ -267,7 +272,7 @@ void BackendImplV3::FirstEviction() {
Time create_time = Time::FromInternalValue(header->create_time);
CACHE_UMA(AGE, "FillupAge", create_time);
- int64 use_time = stats_.GetCounter(Stats::TIMER);
+ int64_t use_time = stats_.GetCounter(Stats::TIMER);
CACHE_UMA(HOURS, "FillupTime", static_cast<int>(use_time / 120));
CACHE_UMA(PERCENTAGE, "FirstHitRatio", stats_.GetHitRatio());
@@ -302,27 +307,27 @@ void BackendImplV3::OnEvent(Stats::Counters an_event) {
stats_.OnEvent(an_event);
}
-void BackendImplV3::OnRead(int32 bytes) {
+void BackendImplV3::OnRead(int32_t bytes) {
DCHECK_GE(bytes, 0);
byte_count_ += bytes;
if (byte_count_ < 0)
- byte_count_ = kint32max;
+ byte_count_ = std::numeric_limits<int32_t>::max();
}
-void BackendImplV3::OnWrite(int32 bytes) {
+void BackendImplV3::OnWrite(int32_t bytes) {
// We use the same implementation as OnRead... just log the number of bytes.
OnRead(bytes);
}
void BackendImplV3::OnTimerTick() {
stats_.OnEvent(Stats::TIMER);
- int64 time = stats_.GetCounter(Stats::TIMER);
- int64 current = stats_.GetCounter(Stats::OPEN_ENTRIES);
+ int64_t time = stats_.GetCounter(Stats::TIMER);
+ int64_t current = stats_.GetCounter(Stats::OPEN_ENTRIES);
// OPEN_ENTRIES is a sampled average of the number of open entries, avoiding
// the bias towards 0.
if (num_refs_ && (current != num_refs_)) {
- int64 diff = (num_refs_ - current) / 50;
+ int64_t diff = (num_refs_ - current) / 50;
if (!diff)
diff = num_refs_ > current ? 1 : -1;
current = current + diff;
@@ -368,7 +373,7 @@ void BackendImplV3::SetNewEviction() {
lru_eviction_ = false;
}
-void BackendImplV3::SetFlags(uint32 flags) {
+void BackendImplV3::SetFlags(uint32_t flags) {
user_flags_ |= flags;
}
@@ -417,7 +422,7 @@ net::CacheType BackendImplV3::GetCacheType() const {
return cache_type_;
}
-int32 BackendImplV3::GetEntryCount() const {
+int32_t BackendImplV3::GetEntryCount() const {
if (disabled_)
return 0;
DCHECK(init_);
@@ -430,7 +435,7 @@ int BackendImplV3::OpenEntry(const std::string& key, Entry** entry,
return NULL;
TimeTicks start = TimeTicks::Now();
- uint32 hash = base::Hash(key);
+ uint32_t hash = base::Hash(key);
Trace("Open hash 0x%x", hash);
bool error;
@@ -442,9 +447,9 @@ int BackendImplV3::OpenEntry(const std::string& key, Entry** entry,
}
int current_size = data_->header.num_bytes / (1024 * 1024);
- int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120;
- int64 no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
- int64 use_hours = total_hours - no_use_hours;
+ int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120;
+ int64_t no_use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
+ int64_t use_hours = total_hours - no_use_hours;
if (!cache_entry) {
CACHE_UMA(AGE_MS, "OpenTime.Miss", 0, start);
@@ -717,7 +722,7 @@ void BackendImplV3::OnExternalCacheHit(const std::string& key) {
if (disabled_)
return;
- uint32 hash = base::Hash(key);
+ uint32_t hash = base::Hash(key);
bool error;
EntryImpl* cache_entry = MatchEntry(key, hash, false, Addr(), &error);
if (cache_entry) {
@@ -740,7 +745,7 @@ void BackendImplV3::AdjustMaxCacheSize(int table_len) {
DCHECK(!table_len || data_->header.magic);
// The user is not setting the size, let's figure it out.
- int64 available = base::SysInfo::AmountOfFreeDiskSpace(path_);
+ int64_t available = base::SysInfo::AmountOfFreeDiskSpace(path_);
if (available < 0) {
max_size_ = kDefaultCacheSize;
return;
@@ -822,10 +827,10 @@ void BackendImplV3::StoreStats() {
}
void BackendImplV3::RestartCache(bool failure) {
- int64 errors = stats_.GetCounter(Stats::FATAL_ERROR);
- int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE);
- int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT);
- int64 last_report = stats_.GetCounter(Stats::LAST_REPORT);
+ int64_t errors = stats_.GetCounter(Stats::FATAL_ERROR);
+ int64_t full_dooms = stats_.GetCounter(Stats::DOOM_CACHE);
+ int64_t partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT);
+ int64_t last_report = stats_.GetCounter(Stats::LAST_REPORT);
PrepareForRestart();
if (failure) {
@@ -965,12 +970,12 @@ int BackendImplV3::NewEntry(Addr address, EntryImplV3** entry) {
return 0;
}
-void BackendImplV3::AddStorageSize(int32 bytes) {
+void BackendImplV3::AddStorageSize(int32_t bytes) {
data_->header.num_bytes += bytes;
DCHECK_GE(data_->header.num_bytes, 0);
}
-void BackendImplV3::SubstractStorageSize(int32 bytes) {
+void BackendImplV3::SubstractStorageSize(int32_t bytes) {
data_->header.num_bytes -= bytes;
DCHECK_GE(data_->header.num_bytes, 0);
}
@@ -1262,7 +1267,7 @@ void BackendImplV3::ReportStats() {
stats_.SetCounter(Stats::DOOM_CACHE, 0);
stats_.SetCounter(Stats::DOOM_RECENT, 0);
- int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120;
+ int64_t total_hours = stats_.GetCounter(Stats::TIMER) / 120;
if (!(header->flags & CACHE_EVICTED)) {
CACHE_UMA(HOURS, "TotalTimeNotFull", static_cast<int>(total_hours));
return;
@@ -1273,7 +1278,7 @@ void BackendImplV3::ReportStats() {
CACHE_UMA(HOURS, "TotalTime", static_cast<int>(total_hours));
- int64 use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
+ int64_t use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120;
stats_.SetCounter(Stats::LAST_REPORT_TIMER, stats_.GetCounter(Stats::TIMER));
// We may see users with no use_hours at this point if this is the first time
@@ -1286,7 +1291,7 @@ void BackendImplV3::ReportStats() {
CACHE_UMA(HOURS, "UseTime", static_cast<int>(use_hours));
- int64 trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours;
+ int64_t trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours;
CACHE_UMA(COUNTS, "TrimRate", static_cast<int>(trim_rate));
int avg_size = header->num_bytes / GetEntryCount();
@@ -1368,7 +1373,7 @@ bool BackendImplV3::CheckIndex() {
#if !defined(NET_BUILD_STRESS_CACHE)
if (data_->header.num_bytes < 0 ||
- (max_size_ < kint32max - kDefaultCacheSize &&
+ (max_size_ < std::numeric_limits<int32_t>::max() - kDefaultCacheSize &&
data_->header.num_bytes > max_size_ + kDefaultCacheSize)) {
LOG(ERROR) << "Invalid cache (current) size";
return false;
@@ -1391,7 +1396,7 @@ bool BackendImplV3::CheckIndex() {
int BackendImplV3::CheckAllEntries() {
int num_dirty = 0;
int num_entries = 0;
- DCHECK(mask_ < kuint32max);
+ DCHECK(mask_ < std::numeric_limits<uint32_t>::max());
for (unsigned int i = 0; i <= mask_; i++) {
Addr address(data_->table[i]);
if (!address.is_initialized())
@@ -1447,7 +1452,7 @@ bool BackendImplV3::CheckEntry(EntryImpl* cache_entry) {
}
int BackendImplV3::MaxBuffersSize() {
- static int64 total_memory = base::SysInfo::AmountOfPhysicalMemory();
+ static int64_t total_memory = base::SysInfo::AmountOfPhysicalMemory();
static bool done = false;
if (!done) {
@@ -1474,7 +1479,7 @@ net::CacheType BackendImplV3::GetCacheType() const {
return cache_type_;
}
-int32 BackendImplV3::GetEntryCount() const {
+int32_t BackendImplV3::GetEntryCount() const {
return 0;
}
@@ -1508,6 +1513,10 @@ int BackendImplV3::DoomEntriesSince(base::Time initial_time,
return net::ERR_FAILED;
}
+int BackendImplV3::CalculateSizeOfAllEntries(
+ const CompletionCallback& callback) {
+ return net::ERR_FAILED;
+}
class BackendImplV3::NotImplementedIterator : public Backend::Iterator {
public:
diff --git a/chromium/net/disk_cache/blockfile/backend_impl_v3.h b/chromium/net/disk_cache/blockfile/backend_impl_v3.h
index 4ec5b3fc5b3..df51c2137af 100644
--- a/chromium/net/disk_cache/blockfile/backend_impl_v3.h
+++ b/chromium/net/disk_cache/blockfile/backend_impl_v3.h
@@ -7,8 +7,11 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_V3_H_
#define NET_DISK_CACHE_BLOCKFILE_BACKEND_IMPL_V3_H_
+#include <stdint.h>
+
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/timer/timer.h"
#include "net/disk_cache/blockfile/block_bitmaps_v3.h"
@@ -86,16 +89,16 @@ class NET_EXPORT_PRIVATE BackendImplV3 : public Backend {
EntryImplV3* GetOpenEntry(Addr address) const;
// Returns the id being used on this run of the cache.
- int32 GetCurrentEntryId() const;
+ int32_t GetCurrentEntryId() const;
// Returns the maximum size for a file to reside on the cache.
int MaxFileSize() const;
// A user data block is being created, extended or truncated.
- void ModifyStorageSize(int32 old_size, int32 new_size);
+ void ModifyStorageSize(int32_t old_size, int32_t new_size);
// Logs requests that are denied due to being too big.
- void TooMuchStorageRequested(int32 size);
+ void TooMuchStorageRequested(int32_t size);
// Returns true if a temporary buffer is allowed to be extended.
bool IsAllocAllowed(int current_size, int new_size);
@@ -154,7 +157,7 @@ class NET_EXPORT_PRIVATE BackendImplV3 : public Backend {
void SetNewEviction();
// Sets an explicit set of BackendFlags.
- void SetFlags(uint32 flags);
+ void SetFlags(uint32_t flags);
// Sends a dummy operation through the operation queue, for unit tests.
int FlushQueueForTest(const CompletionCallback& callback);
@@ -173,7 +176,7 @@ class NET_EXPORT_PRIVATE BackendImplV3 : public Backend {
// Backend implementation.
net::CacheType GetCacheType() const override;
- int32 GetEntryCount() const override;
+ int32_t GetEntryCount() const override;
int OpenEntry(const std::string& key,
Entry** entry,
const CompletionCallback& callback) override;
@@ -188,6 +191,7 @@ class NET_EXPORT_PRIVATE BackendImplV3 : public Backend {
const CompletionCallback& callback) override;
int DoomEntriesSince(base::Time initial_time,
const CompletionCallback& callback) override;
+ int CalculateSizeOfAllEntries(const CompletionCallback& callback) override;
scoped_ptr<Iterator> CreateIterator() override;
void GetStats(StatsItems* stats) override;
void OnExternalCacheHit(const std::string& key) override;
@@ -215,8 +219,8 @@ class NET_EXPORT_PRIVATE BackendImplV3 : public Backend {
int NewEntry(Addr address, EntryImplV3** entry);
// Handles the used storage count.
- void AddStorageSize(int32 bytes);
- void SubstractStorageSize(int32 bytes);
+ void AddStorageSize(int32_t bytes);
+ void SubstractStorageSize(int32_t bytes);
// Update the number of referenced cache entries.
void IncreaseNumRefs();
@@ -248,7 +252,7 @@ class NET_EXPORT_PRIVATE BackendImplV3 : public Backend {
IndexTable index_;
base::FilePath path_; // Path to the folder used as backing storage.
BlockBitmaps block_files_;
- int32 max_size_; // Maximum data size for this instance.
+ int32_t max_size_; // Maximum data size for this instance.
EvictionV3 eviction_; // Handler of the eviction algorithm.
EntriesMap open_entries_;
int num_refs_; // Number of referenced cache entries.
@@ -259,7 +263,7 @@ class NET_EXPORT_PRIVATE BackendImplV3 : public Backend {
int up_ticks_; // The number of timer ticks received (OnTimerTick).
net::CacheType cache_type_;
int uma_report_; // Controls transmission of UMA data.
- uint32 user_flags_; // Flags set by the user.
+ uint32_t user_flags_; // Flags set by the user.
bool init_; // controls the initialization of the system.
bool restarted_;
bool read_only_; // Prevents updates of the rankings data (used by tools).
diff --git a/chromium/net/disk_cache/blockfile/backend_worker_v3.cc b/chromium/net/disk_cache/blockfile/backend_worker_v3.cc
index 9d2e6a61f3c..897ee3c3d39 100644
--- a/chromium/net/disk_cache/blockfile/backend_worker_v3.cc
+++ b/chromium/net/disk_cache/blockfile/backend_worker_v3.cc
@@ -4,6 +4,10 @@
#include "net/disk_cache/blockfile/backend_worker_v3.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
@@ -38,7 +42,7 @@ const int kDefaultCacheSize = 80 * 1024 * 1024;
// Avoid trimming the cache for the first 5 minutes (10 timer ticks).
const int kTrimDelay = 10;
-int DesiredIndexTableLen(int32 storage_size) {
+int DesiredIndexTableLen(int32_t storage_size) {
if (storage_size <= k64kEntriesStore)
return kBaseTableLen;
if (storage_size <= k64kEntriesStore * 2)
@@ -48,7 +52,7 @@ int DesiredIndexTableLen(int32 storage_size) {
if (storage_size <= k64kEntriesStore * 8)
return kBaseTableLen * 8;
- // The biggest storage_size for int32 requires a 4 MB table.
+ // The biggest storage_size for int32_t requires a 4 MB table.
return kBaseTableLen * 16;
}
@@ -397,7 +401,7 @@ bool BackendImpl::CheckIndex() {
#if !defined(NET_BUILD_STRESS_CACHE)
if (data_->header.num_bytes < 0 ||
- (max_size_ < kint32max - kDefaultCacheSize &&
+ (max_size_ < std::numeric_limits<int32_t>::max() - kDefaultCacheSize &&
data_->header.num_bytes > max_size_ + kDefaultCacheSize)) {
LOG(ERROR) << "Invalid cache (current) size";
return false;
diff --git a/chromium/net/disk_cache/blockfile/backend_worker_v3.h b/chromium/net/disk_cache/blockfile/backend_worker_v3.h
index 6874228477c..fc8b317345e 100644
--- a/chromium/net/disk_cache/blockfile/backend_worker_v3.h
+++ b/chromium/net/disk_cache/blockfile/backend_worker_v3.h
@@ -9,6 +9,7 @@
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/disk_cache/blockfile/addr.h"
#include "net/disk_cache/blockfile/backend_impl_v3.h"
diff --git a/chromium/net/disk_cache/blockfile/bitmap.cc b/chromium/net/disk_cache/blockfile/bitmap.cc
index cfbf8460d84..7e241bcabd6 100644
--- a/chromium/net/disk_cache/blockfile/bitmap.cc
+++ b/chromium/net/disk_cache/blockfile/bitmap.cc
@@ -11,7 +11,7 @@
namespace {
// Returns the number of trailing zeros.
-int FindLSBSetNonZero(uint32 word) {
+int FindLSBSetNonZero(uint32_t word) {
// Get the LSB, put it on the exponent of a 32 bit float and remove the
// mantisa and the bias. This code requires IEEE 32 bit float compliance.
float f = static_cast<float>(word & -static_cast<int>(word));
@@ -19,7 +19,7 @@ int FindLSBSetNonZero(uint32 word) {
// We use a union to go around strict-aliasing complains.
union {
float ieee_float;
- uint32 as_uint;
+ uint32_t as_uint;
} x;
x.ieee_float = f;
@@ -28,7 +28,7 @@ int FindLSBSetNonZero(uint32 word) {
// Returns the index of the first bit set to |value| from |word|. This code
// assumes that we'll be able to find that bit.
-int FindLSBNonEmpty(uint32 word, bool value) {
+int FindLSBNonEmpty(uint32_t word, bool value) {
// If we are looking for 0, negate |word| and look for 1.
if (!value)
word = ~word;
@@ -44,21 +44,20 @@ Bitmap::Bitmap(int num_bits, bool clear_bits)
: num_bits_(num_bits),
array_size_(RequiredArraySize(num_bits)),
alloc_(true) {
- map_ = new uint32[array_size_];
+ map_ = new uint32_t[array_size_];
// Initialize all of the bits.
if (clear_bits)
Clear();
}
-Bitmap::Bitmap(uint32* map, int num_bits, int num_words)
+Bitmap::Bitmap(uint32_t* map, int num_bits, int num_words)
: map_(map),
num_bits_(num_bits),
// If size is larger than necessary, trim because array_size_ is used
// as a bound by various methods.
array_size_(std::min(RequiredArraySize(num_bits), num_words)),
- alloc_(false) {
-}
+ alloc_(false) {}
Bitmap::~Bitmap() {
if (alloc_)
@@ -72,7 +71,7 @@ void Bitmap::Resize(int num_bits, bool clear_bits) {
array_size_ = RequiredArraySize(num_bits);
if (array_size_ != old_array_size) {
- uint32* new_map = new uint32[array_size_];
+ uint32_t* new_map = new uint32_t[array_size_];
// Always clear the unused bits in the last word.
new_map[array_size_ - 1] = 0;
memcpy(new_map, map_,
@@ -116,19 +115,19 @@ void Bitmap::Toggle(int index) {
map_[j] ^= (1 << i);
}
-void Bitmap::SetMapElement(int array_index, uint32 value) {
+void Bitmap::SetMapElement(int array_index, uint32_t value) {
DCHECK_LT(array_index, array_size_);
DCHECK_GE(array_index, 0);
map_[array_index] = value;
}
-uint32 Bitmap::GetMapElement(int array_index) const {
+uint32_t Bitmap::GetMapElement(int array_index) const {
DCHECK_LT(array_index, array_size_);
DCHECK_GE(array_index, 0);
return map_[array_index];
}
-void Bitmap::SetMap(const uint32* map, int size) {
+void Bitmap::SetMap(const uint32_t* map, int size) {
memcpy(map_, map, std::min(size, array_size_) * sizeof(*map_));
}
@@ -176,7 +175,7 @@ bool Bitmap::TestRange(int begin, int end, bool value) const {
int last_offset = (end - 1) & (kIntBits - 1);
// If we are looking for zeros, negate the data from the map.
- uint32 this_word = map_[word];
+ uint32_t this_word = map_[word];
if (!value)
this_word = ~this_word;
@@ -200,7 +199,7 @@ bool Bitmap::TestRange(int begin, int end, bool value) const {
// Test the portion of the last word that lies within the range. (This logic
// also handles the case where the entire range lies within a single word.)
- const uint32 mask = ((2 << (last_offset - offset)) - 1) << offset;
+ const uint32_t mask = ((2 << (last_offset - offset)) - 1) << offset;
this_word = map_[last_word];
if (!value)
@@ -222,7 +221,7 @@ bool Bitmap::FindNextBit(int* index, int limit, bool value) const {
// From now on limit != 0, since if it was we would have returned false.
int word_index = bit_index >> kLogIntBits;
- uint32 one_word = map_[word_index];
+ uint32_t one_word = map_[word_index];
// Simple optimization where we can immediately return true if the first
// bit is set. This helps for cases where many bits are set, and doesn't
@@ -233,14 +232,14 @@ bool Bitmap::FindNextBit(int* index, int limit, bool value) const {
const int first_bit_offset = bit_index & (kIntBits - 1);
// First word is special - we need to mask off leading bits.
- uint32 mask = 0xFFFFFFFF << first_bit_offset;
+ uint32_t mask = 0xFFFFFFFF << first_bit_offset;
if (value) {
one_word &= mask;
} else {
one_word |= ~mask;
}
- uint32 empty_value = value ? 0 : 0xFFFFFFFF;
+ uint32_t empty_value = value ? 0 : 0xFFFFFFFF;
// Loop through all but the last word. Note that 'limit' is one
// past the last bit we want to check, and we don't want to read
@@ -299,7 +298,7 @@ void Bitmap::SetWordBits(int start, int len, bool value) {
int word = start / kIntBits;
int offset = start % kIntBits;
- uint32 to_add = 0xffffffff << len;
+ uint32_t to_add = 0xffffffff << len;
to_add = (~to_add) << offset;
if (value) {
map_[word] |= to_add;
diff --git a/chromium/net/disk_cache/blockfile/bitmap.h b/chromium/net/disk_cache/blockfile/bitmap.h
index dc05157f7a4..59a987a2fae 100644
--- a/chromium/net/disk_cache/blockfile/bitmap.h
+++ b/chromium/net/disk_cache/blockfile/bitmap.h
@@ -5,7 +5,10 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_BITMAP_H_
#define NET_DISK_CACHE_BLOCKFILE_BITMAP_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+#include <string.h>
+
+#include "base/macros.h"
#include "net/base/net_export.h"
namespace disk_cache {
@@ -15,14 +18,14 @@ class NET_EXPORT_PRIVATE Bitmap {
public:
Bitmap() : map_(NULL), num_bits_(0), array_size_(0), alloc_(false) {}
- // This constructor will allocate on a uint32 boundary. If |clear_bits| is
+ // This constructor will allocate on a uint32_t boundary. If |clear_bits| is
// false, the bitmap bits will not be initialized.
Bitmap(int num_bits, bool clear_bits);
// Constructs a Bitmap with the actual storage provided by the caller. |map|
// has to be valid until this object destruction. |num_bits| is the number of
// bits in the bitmap, and |num_words| is the size of |map| in 32-bit words.
- Bitmap(uint32* map, int num_bits, int num_words);
+ Bitmap(uint32_t* map, int num_bits, int num_words);
~Bitmap();
@@ -54,18 +57,18 @@ class NET_EXPORT_PRIVATE Bitmap {
// Directly sets an element of the internal map. Requires |array_index| <
// ArraySize();
- void SetMapElement(int array_index, uint32 value);
+ void SetMapElement(int array_index, uint32_t value);
// Gets an entry of the internal map. Requires array_index <
// ArraySize()
- uint32 GetMapElement(int array_index) const;
+ uint32_t GetMapElement(int array_index) const;
// Directly sets the whole internal map. |size| is the number of 32-bit words
// to set from |map|. If |size| > array_size(), it ignores the end of |map|.
- void SetMap(const uint32* map, int size);
+ void SetMap(const uint32_t* map, int size);
// Gets a pointer to the internal map.
- const uint32* GetMap() const { return map_; }
+ const uint32_t* GetMap() const { return map_; }
// Sets a range of bits to |value|.
void SetRange(int begin, int end, bool value);
@@ -116,14 +119,14 @@ class NET_EXPORT_PRIVATE Bitmap {
}
private:
- static const int kIntBits = sizeof(uint32) * 8;
+ static const int kIntBits = sizeof(uint32_t) * 8;
static const int kLogIntBits = 5; // 2^5 == 32 bits per word.
// Sets |len| bits from |start| to |value|. All the bits to be set should be
// stored in the same word, and len < kIntBits.
void SetWordBits(int start, int len, bool value);
- uint32* map_; // The bitmap.
+ uint32_t* map_; // The bitmap.
int num_bits_; // The upper bound of the bitmap.
int array_size_; // The physical size (in uint32s) of the bitmap.
bool alloc_; // Whether or not we allocated the memory.
diff --git a/chromium/net/disk_cache/blockfile/bitmap_unittest.cc b/chromium/net/disk_cache/blockfile/bitmap_unittest.cc
index a0748bf81a5..29d8739246e 100644
--- a/chromium/net/disk_cache/blockfile/bitmap_unittest.cc
+++ b/chromium/net/disk_cache/blockfile/bitmap_unittest.cc
@@ -24,7 +24,7 @@ TEST(BitmapTest, DefaultConstructor) {
TEST(BitmapTest, Basics) {
disk_cache::Bitmap bitmap(80, true);
- const uint32 kValue = 0x74f10060;
+ const uint32_t kValue = 0x74f10060;
// Test proper allocation size.
EXPECT_EQ(80, bitmap.Size());
@@ -94,7 +94,7 @@ TEST(BitmapTest, Map) {
local_map[i] = static_cast<char>(i);
disk_cache::Bitmap bitmap(kMapSize * 8, false);
- bitmap.SetMap(reinterpret_cast<uint32*>(local_map), kMapSize / 4);
+ bitmap.SetMap(reinterpret_cast<uint32_t*>(local_map), kMapSize / 4);
for (int i = 0; i < kMapSize; i++) {
if (i % 2)
EXPECT_TRUE(bitmap.Get(i * 8));
@@ -105,7 +105,7 @@ TEST(BitmapTest, Map) {
EXPECT_EQ(0, memcmp(local_map, bitmap.GetMap(), kMapSize));
// Now let's create a bitmap that shares local_map as storage.
- disk_cache::Bitmap bitmap2(reinterpret_cast<uint32*>(local_map),
+ disk_cache::Bitmap bitmap2(reinterpret_cast<uint32_t*>(local_map),
kMapSize * 8, kMapSize / 4);
EXPECT_EQ(0, memcmp(local_map, bitmap2.GetMap(), kMapSize));
diff --git a/chromium/net/disk_cache/blockfile/block_bitmaps_v3.cc b/chromium/net/disk_cache/blockfile/block_bitmaps_v3.cc
index 21a52c9afc4..70208aef74f 100644
--- a/chromium/net/disk_cache/blockfile/block_bitmaps_v3.cc
+++ b/chromium/net/disk_cache/blockfile/block_bitmaps_v3.cc
@@ -71,7 +71,7 @@ void BlockBitmaps::Clear() {
void BlockBitmaps::ReportStats() {
int used_blocks[kFirstAdditionalBlockFile];
int load[kFirstAdditionalBlockFile];
- for (int16 i = 0; i < kFirstAdditionalBlockFile; i++) {
+ for (int16_t i = 0; i < kFirstAdditionalBlockFile; i++) {
GetFileStats(i, &used_blocks[i], &load[i]);
}
UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_0", used_blocks[0]);
diff --git a/chromium/net/disk_cache/blockfile/block_bitmaps_v3.h b/chromium/net/disk_cache/blockfile/block_bitmaps_v3.h
index 40eefb14a74..b2ca46141e7 100644
--- a/chromium/net/disk_cache/blockfile/block_bitmaps_v3.h
+++ b/chromium/net/disk_cache/blockfile/block_bitmaps_v3.h
@@ -8,6 +8,7 @@
#define NET_DISK_CACHE_BLOCKFILE_BLOCK_BITMAPS_V3_H_
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/addr.h"
#include "net/disk_cache/blockfile/block_files.h"
diff --git a/chromium/net/disk_cache/blockfile/block_bitmaps_v3_unittest.cc b/chromium/net/disk_cache/blockfile/block_bitmaps_v3_unittest.cc
index bf22d8824f6..64ca115cded 100644
--- a/chromium/net/disk_cache/blockfile/block_bitmaps_v3_unittest.cc
+++ b/chromium/net/disk_cache/blockfile/block_bitmaps_v3_unittest.cc
@@ -19,7 +19,7 @@ TEST(DiskCacheBlockBitmaps, V3AllocationMap) {
memset(&headers[i], 0, sizeof(headers[i]));
headers[i].magic = disk_cache::kBlockMagic;
headers[i].version = disk_cache::kBlockCurrentVersion;
- headers[i].this_file = static_cast<int16>(i);
+ headers[i].this_file = static_cast<int16_t>(i);
headers[i].empty[3] = 200;
headers[i].max_entries = 800;
bitmaps.push_back(disk_cache::BlockHeader(&headers[i]));
@@ -51,7 +51,7 @@ TEST(DiskCacheBlockBitmaps, V3AllocationMap) {
// The first part of the allocation map should be completely filled. We used
// 10 bits per each of four entries, so 250 bits total. All entries should go
// to the third file.
- uint8* buffer = reinterpret_cast<uint8*>(&headers[2].allocation_map);
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(&headers[2].allocation_map);
for (int i = 0; i < 29; i++) {
SCOPED_TRACE(i);
EXPECT_EQ(0xff, buffer[i]);
diff --git a/chromium/net/disk_cache/blockfile/block_files.cc b/chromium/net/disk_cache/blockfile/block_files.cc
index c829afc1c18..f7cc38178f4 100644
--- a/chromium/net/disk_cache/blockfile/block_files.cc
+++ b/chromium/net/disk_cache/blockfile/block_files.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/blockfile/block_files.h"
+#include <limits>
+
#include "base/atomicops.h"
#include "base/files/file_path.h"
#include "base/metrics/histogram_macros.h"
@@ -28,7 +30,7 @@ const char s_types[16] = {4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
// Returns the type of block (number of consecutive blocks that can be stored)
// for a given nibble of the bitmap.
-inline int GetMapBlockType(uint32 value) {
+inline int GetMapBlockType(uint32_t value) {
value &= 0xf;
return s_types[value];
}
@@ -75,7 +77,7 @@ bool BlockHeader::CreateMapBlock(int size, int* index) {
for (int i = 0; i < header_->max_entries / 32; i++, current++) {
if (current == header_->max_entries / 32)
current = 0;
- uint32 map_block = header_->allocation_map[current];
+ uint32_t map_block = header_->allocation_map[current];
for (int j = 0; j < 8; j++, map_block >>= 4) {
if (GetMapBlockType(map_block) != target)
@@ -85,7 +87,7 @@ bool BlockHeader::CreateMapBlock(int size, int* index) {
int index_offset = j * 4 + 4 - target;
*index = current * 32 + index_offset;
STRESS_DCHECK(*index / 4 == (*index + size - 1) / 4);
- uint32 to_add = ((1 << size) - 1) << index_offset;
+ uint32_t to_add = ((1 << size) - 1) << index_offset;
header_->num_entries++;
// Note that there is no race in the normal sense here, but if we enforce
@@ -120,22 +122,22 @@ void BlockHeader::DeleteMapBlock(int index, int size) {
}
TimeTicks start = TimeTicks::Now();
int byte_index = index / 8;
- uint8* byte_map = reinterpret_cast<uint8*>(header_->allocation_map);
- uint8 map_block = byte_map[byte_index];
+ uint8_t* byte_map = reinterpret_cast<uint8_t*>(header_->allocation_map);
+ uint8_t map_block = byte_map[byte_index];
if (index % 8 >= 4)
map_block >>= 4;
// See what type of block will be available after we delete this one.
int bits_at_end = 4 - size - index % 4;
- uint8 end_mask = (0xf << (4 - bits_at_end)) & 0xf;
+ uint8_t end_mask = (0xf << (4 - bits_at_end)) & 0xf;
bool update_counters = (map_block & end_mask) == 0;
- uint8 new_value = map_block & ~(((1 << size) - 1) << (index % 4));
+ uint8_t new_value = map_block & ~(((1 << size) - 1) << (index % 4));
int new_type = GetMapBlockType(new_value);
disk_cache::FileLock lock(header_);
STRESS_DCHECK((((1 << size) - 1) << (index % 8)) < 0x100);
- uint8 to_clear = ((1 << size) - 1) << (index % 8);
+ uint8_t to_clear = ((1 << size) - 1) << (index % 8);
STRESS_DCHECK((byte_map[byte_index] & to_clear) == to_clear);
byte_map[byte_index] &= ~to_clear;
@@ -157,14 +159,14 @@ bool BlockHeader::UsedMapBlock(int index, int size) {
return false;
int byte_index = index / 8;
- uint8* byte_map = reinterpret_cast<uint8*>(header_->allocation_map);
- uint8 map_block = byte_map[byte_index];
+ uint8_t* byte_map = reinterpret_cast<uint8_t*>(header_->allocation_map);
+ uint8_t map_block = byte_map[byte_index];
if (index % 8 >= 4)
map_block >>= 4;
STRESS_DCHECK((((1 << size) - 1) << (index % 8)) < 0x100);
- uint8 to_clear = ((1 << size) - 1) << (index % 8);
+ uint8_t to_clear = ((1 << size) - 1) << (index % 8);
return ((byte_map[byte_index] & to_clear) == to_clear);
}
@@ -175,7 +177,7 @@ void BlockHeader::FixAllocationCounters() {
}
for (int i = 0; i < header_->max_entries / 32; i++) {
- uint32 map_block = header_->allocation_map[i];
+ uint32_t map_block = header_->allocation_map[i];
for (int j = 0; j < 8; j++, map_block >>= 4) {
int type = GetMapBlockType(map_block);
@@ -279,7 +281,7 @@ bool BlockFiles::Init(bool create_files) {
thread_checker_.reset(new base::ThreadChecker);
block_files_.resize(kFirstAdditionalBlockFile);
- for (int16 i = 0; i < kFirstAdditionalBlockFile; i++) {
+ for (int16_t i = 0; i < kFirstAdditionalBlockFile; i++) {
if (create_files)
if (!CreateBlockFile(i, static_cast<FileType>(i + 1), true))
return false;
@@ -457,8 +459,8 @@ bool BlockFiles::CreateBlockFile(int index, FileType file_type, bool force) {
header.magic = kBlockMagic;
header.version = kBlockVersion2;
header.entry_size = Addr::BlockSizeForFileType(file_type);
- header.this_file = static_cast<int16>(index);
- DCHECK(index <= kint16max && index >= 0);
+ header.this_file = static_cast<int16_t>(index);
+ DCHECK(index <= std::numeric_limits<int16_t>::max() && index >= 0);
return file->Write(&header, sizeof(header), 0);
}
@@ -574,7 +576,7 @@ MappedFile* BlockFiles::FileForNewBlock(FileType block_type, int block_count) {
MappedFile* BlockFiles::NextFile(MappedFile* file) {
ScopedFlush flush(file);
BlockFileHeader* header = reinterpret_cast<BlockFileHeader*>(file->buffer());
- int16 new_file = header->next_file;
+ int16_t new_file = header->next_file;
if (!new_file) {
// RANKINGS is not reported as a type for small entries, but we may be
// extending the rankings block file.
@@ -595,8 +597,8 @@ MappedFile* BlockFiles::NextFile(MappedFile* file) {
return GetFile(address);
}
-int16 BlockFiles::CreateNextBlockFile(FileType block_type) {
- for (int16 i = kFirstAdditionalBlockFile; i <= kMaxBlockFile; i++) {
+int16_t BlockFiles::CreateNextBlockFile(FileType block_type) {
+ for (int16_t i = kFirstAdditionalBlockFile; i <= kMaxBlockFile; i++) {
if (CreateBlockFile(i, block_type, false))
return i;
}
diff --git a/chromium/net/disk_cache/blockfile/block_files.h b/chromium/net/disk_cache/blockfile/block_files.h
index 7c2794a0303..1de3bedb830 100644
--- a/chromium/net/disk_cache/blockfile/block_files.h
+++ b/chromium/net/disk_cache/blockfile/block_files.h
@@ -7,10 +7,13 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_BLOCK_FILES_H_
#define NET_DISK_CACHE_BLOCKFILE_BLOCK_FILES_H_
+#include <stdint.h>
+
#include <vector>
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/addr.h"
@@ -136,7 +139,7 @@ class NET_EXPORT_PRIVATE BlockFiles {
MappedFile* NextFile(MappedFile* file);
// Creates an empty block file and returns its index.
- int16 CreateNextBlockFile(FileType block_type);
+ int16_t CreateNextBlockFile(FileType block_type);
// Removes a chained block file that is now empty.
bool RemoveEmptyFile(FileType block_type);
diff --git a/chromium/net/disk_cache/blockfile/block_files_unittest.cc b/chromium/net/disk_cache/blockfile/block_files_unittest.cc
index 343485ab211..ca1e019dfa1 100644
--- a/chromium/net/disk_cache/blockfile/block_files_unittest.cc
+++ b/chromium/net/disk_cache/blockfile/block_files_unittest.cc
@@ -329,7 +329,7 @@ TEST_F(DiskCacheTest, AllocationMap) {
// 10 bits per each four entries, so 250 bits total.
BlockFileHeader* header =
reinterpret_cast<BlockFileHeader*>(files.GetFile(address[0])->buffer());
- uint8* buffer = reinterpret_cast<uint8*>(&header->allocation_map);
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(&header->allocation_map);
for (int i =0; i < 29; i++) {
SCOPED_TRACE(i);
EXPECT_EQ(0xff, buffer[i]);
diff --git a/chromium/net/disk_cache/blockfile/disk_cache_perftest.cc b/chromium/net/disk_cache/blockfile/disk_cache_perftest.cc
index 9aaa7f407b1..80806532660 100644
--- a/chromium/net/disk_cache/blockfile/disk_cache_perftest.cc
+++ b/chromium/net/disk_cache/blockfile/disk_cache_perftest.cc
@@ -4,7 +4,6 @@
#include <string>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/hash.h"
diff --git a/chromium/net/disk_cache/blockfile/disk_format.h b/chromium/net/disk_cache/blockfile/disk_format.h
index b2e666abb2b..a621ec17c56 100644
--- a/chromium/net/disk_cache/blockfile/disk_format.h
+++ b/chromium/net/disk_cache/blockfile/disk_format.h
@@ -45,44 +45,47 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_DISK_FORMAT_H_
#define NET_DISK_CACHE_BLOCKFILE_DISK_FORMAT_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/disk_format_base.h"
namespace disk_cache {
const int kIndexTablesize = 0x10000;
-const uint32 kIndexMagic = 0xC103CAC3;
-const uint32 kCurrentVersion = 0x20000; // Version 2.0.
+const uint32_t kIndexMagic = 0xC103CAC3;
+const uint32_t kCurrentVersion = 0x20000; // Version 2.0.
struct LruData {
- int32 pad1[2];
- int32 filled; // Flag to tell when we filled the cache.
- int32 sizes[5];
+ int32_t pad1[2];
+ int32_t filled; // Flag to tell when we filled the cache.
+ int32_t sizes[5];
CacheAddr heads[5];
CacheAddr tails[5];
CacheAddr transaction; // In-flight operation target.
- int32 operation; // Actual in-flight operation.
- int32 operation_list; // In-flight operation list.
- int32 pad2[7];
+ int32_t operation; // Actual in-flight operation.
+ int32_t operation_list; // In-flight operation list.
+ int32_t pad2[7];
};
// Header for the master index file.
struct NET_EXPORT_PRIVATE IndexHeader {
IndexHeader();
- uint32 magic;
- uint32 version;
- int32 num_entries; // Number of entries currently stored.
- int32 num_bytes; // Total size of the stored data.
- int32 last_file; // Last external file created.
- int32 this_id; // Id for all entries being changed (dirty flag).
+ uint32_t magic;
+ uint32_t version;
+ int32_t num_entries; // Number of entries currently stored.
+ int32_t num_bytes; // Total size of the stored data.
+ int32_t last_file; // Last external file created.
+ int32_t this_id; // Id for all entries being changed (dirty flag).
CacheAddr stats; // Storage for usage data.
- int32 table_len; // Actual size of the table (0 == kIndexTablesize).
- int32 crash; // Signals a previous crash.
- int32 experiment; // Id of an ongoing test.
- uint64 create_time; // Creation time for this set of files.
- int32 pad[52];
+ int32_t table_len; // Actual size of the table (0 == kIndexTablesize).
+ int32_t crash; // Signals a previous crash.
+ int32_t experiment; // Id of an ongoing test.
+ uint64_t create_time; // Creation time for this set of files.
+ int32_t pad[52];
LruData lru; // Eviction control data.
};
@@ -99,20 +102,20 @@ struct Index {
// After that point, the whole key will be stored as a data block or external
// file.
struct EntryStore {
- uint32 hash; // Full hash of the key.
+ uint32_t hash; // Full hash of the key.
CacheAddr next; // Next entry with the same hash or bucket.
CacheAddr rankings_node; // Rankings node for this entry.
- int32 reuse_count; // How often is this entry used.
- int32 refetch_count; // How often is this fetched from the net.
- int32 state; // Current state.
- uint64 creation_time;
- int32 key_len;
+ int32_t reuse_count; // How often is this entry used.
+ int32_t refetch_count; // How often is this fetched from the net.
+ int32_t state; // Current state.
+ uint64_t creation_time;
+ int32_t key_len;
CacheAddr long_key; // Optional address of a long key.
- int32 data_size[4]; // We can store up to 4 data streams for each
+ int32_t data_size[4]; // We can store up to 4 data streams for each
CacheAddr data_addr[4]; // entry.
- uint32 flags; // Any combination of EntryFlags.
- int32 pad[4];
- uint32 self_hash; // The hash of EntryStore up to this point.
+ uint32_t flags; // Any combination of EntryFlags.
+ int32_t pad[4];
+ uint32_t self_hash; // The hash of EntryStore up to this point.
char key[256 - 24 * 4]; // null terminated
};
@@ -136,13 +139,13 @@ enum EntryFlags {
#pragma pack(push, 4)
// Rankings information for a given entry.
struct RankingsNode {
- uint64 last_used; // LRU info.
- uint64 last_modified; // LRU info.
+ uint64_t last_used; // LRU info.
+ uint64_t last_modified; // LRU info.
CacheAddr next; // LRU list.
CacheAddr prev; // LRU list.
CacheAddr contents; // Address of the EntryStore.
- int32 dirty; // The entry is being modifyied.
- uint32 self_hash; // RankingsNode's hash.
+ int32_t dirty; // The entry is being modifyied.
+ uint32_t self_hash; // RankingsNode's hash.
};
#pragma pack(pop)
diff --git a/chromium/net/disk_cache/blockfile/disk_format_base.h b/chromium/net/disk_cache/blockfile/disk_format_base.h
index 1c49a48e737..bd7a12b4c4e 100644
--- a/chromium/net/disk_cache/blockfile/disk_format_base.h
+++ b/chromium/net/disk_cache/blockfile/disk_format_base.h
@@ -20,23 +20,24 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_DISK_FORMAT_BASE_H_
#define NET_DISK_CACHE_BLOCKFILE_DISK_FORMAT_BASE_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "net/base/net_export.h"
namespace disk_cache {
-typedef uint32 CacheAddr;
+typedef uint32_t CacheAddr;
-const uint32 kBlockVersion2 = 0x20000; // Version 2.0.
-const uint32 kBlockCurrentVersion = 0x30000; // Version 3.0.
+const uint32_t kBlockVersion2 = 0x20000; // Version 2.0.
+const uint32_t kBlockCurrentVersion = 0x30000; // Version 3.0.
-const uint32 kBlockMagic = 0xC104CAC3;
+const uint32_t kBlockMagic = 0xC104CAC3;
const int kBlockHeaderSize = 8192; // Two pages: almost 64k entries
const int kMaxBlocks = (kBlockHeaderSize - 80) * 8;
const int kNumExtraBlocks = 1024; // How fast files grow.
// Bitmap to track used blocks on a block-file.
-typedef uint32 AllocBitmap[kMaxBlocks / 32];
+typedef uint32_t AllocBitmap[kMaxBlocks / 32];
// A block-file is the file used to store information in blocks (could be
// EntryStore blocks, RankingsNode blocks or user-data blocks).
@@ -47,17 +48,17 @@ typedef uint32 AllocBitmap[kMaxBlocks / 32];
// from the beginning every time).
// This Structure is the header of a block-file:
struct BlockFileHeader {
- uint32 magic;
- uint32 version;
- int16 this_file; // Index of this file.
- int16 next_file; // Next file when this one is full.
- int32 entry_size; // Size of the blocks of this file.
- int32 num_entries; // Number of stored entries.
- int32 max_entries; // Current maximum number of entries.
- int32 empty[4]; // Counters of empty entries for each type.
- int32 hints[4]; // Last used position for each entry type.
- volatile int32 updating; // Keep track of updates to the header.
- int32 user[5];
+ uint32_t magic;
+ uint32_t version;
+ int16_t this_file; // Index of this file.
+ int16_t next_file; // Next file when this one is full.
+ int32_t entry_size; // Size of the blocks of this file.
+ int32_t num_entries; // Number of stored entries.
+ int32_t max_entries; // Current maximum number of entries.
+ int32_t empty[4]; // Counters of empty entries for each type.
+ int32_t hints[4]; // Last used position for each entry type.
+ volatile int32_t updating; // Keep track of updates to the header.
+ int32_t user[5];
AllocBitmap allocation_map;
};
@@ -103,23 +104,23 @@ static_assert(sizeof(BlockFileHeader) == kBlockHeaderSize, "bad header");
// to be only partialy filled. In that case, last_block and last_block_len will
// keep track of that block.
struct SparseHeader {
- int64 signature; // The parent and children signature.
- uint32 magic; // Structure identifier (equal to kIndexMagic).
- int32 parent_key_len; // Key length for the parent entry.
- int32 last_block; // Index of the last written block.
- int32 last_block_len; // Lenght of the last written block.
- int32 dummy[10];
+ int64_t signature; // The parent and children signature.
+ uint32_t magic; // Structure identifier (equal to kIndexMagic).
+ int32_t parent_key_len; // Key length for the parent entry.
+ int32_t last_block; // Index of the last written block.
+ int32_t last_block_len; // Lenght of the last written block.
+ int32_t dummy[10];
};
// The SparseHeader will be followed by a bitmap, as described by this
// structure.
struct SparseData {
SparseHeader header;
- uint32 bitmap[32]; // Bitmap representation of known children (if this
- // is a parent entry), or used blocks (for child
- // entries. The size is fixed for child entries but
- // not for parents; it can be as small as 4 bytes
- // and as large as 8 KB.
+ uint32_t bitmap[32]; // Bitmap representation of known children (if this
+ // is a parent entry), or used blocks (for child
+ // entries. The size is fixed for child entries but
+ // not for parents; it can be as small as 4 bytes
+ // and as large as 8 KB.
};
// The number of blocks stored by a child entry.
diff --git a/chromium/net/disk_cache/blockfile/disk_format_v3.h b/chromium/net/disk_cache/blockfile/disk_format_v3.h
index f16648b5bf1..da873ed4917 100644
--- a/chromium/net/disk_cache/blockfile/disk_format_v3.h
+++ b/chromium/net/disk_cache/blockfile/disk_format_v3.h
@@ -45,14 +45,16 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_DISK_FORMAT_V3_H_
#define NET_DISK_CACHE_BLOCKFILE_DISK_FORMAT_V3_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+#include <string.h>
+
#include "net/disk_cache/blockfile/disk_format_base.h"
namespace disk_cache {
const int kBaseTableLen = 0x400;
-const uint32 kIndexMagicV3 = 0xC103CAC3;
-const uint32 kVersion3 = 0x30000; // Version 3.0.
+const uint32_t kIndexMagicV3 = 0xC103CAC3;
+const uint32_t kVersion3 = 0x30000; // Version 3.0.
// Flags for a given cache.
enum CacheFlags {
@@ -63,30 +65,30 @@ enum CacheFlags {
// Header for the master index file.
struct IndexHeaderV3 {
- uint32 magic;
- uint32 version;
- int32 num_entries; // Number of entries currently stored.
- int32 num_bytes; // Total size of the stored data.
- int32 last_file; // Last external file created.
- int32 reserved1;
+ uint32_t magic;
+ uint32_t version;
+ int32_t num_entries; // Number of entries currently stored.
+ int32_t num_bytes; // Total size of the stored data.
+ int32_t last_file; // Last external file created.
+ int32_t reserved1;
CacheAddr stats; // Storage for usage data.
- int32 table_len; // Actual size of the table.
- int32 crash; // Signals a previous crash.
- int32 experiment; // Id of an ongoing test.
- int32 max_bytes; // Total maximum size of the stored data.
- uint32 flags;
- int32 used_cells;
- int32 max_bucket;
- uint64 create_time; // Creation time for this set of files.
- uint64 base_time; // Current base for timestamps.
- uint64 old_time; // Previous time used for timestamps.
- int32 max_block_file;
- int32 num_no_use_entries;
- int32 num_low_use_entries;
- int32 num_high_use_entries;
- int32 reserved;
- int32 num_evicted_entries;
- int32 pad[6];
+ int32_t table_len; // Actual size of the table.
+ int32_t crash; // Signals a previous crash.
+ int32_t experiment; // Id of an ongoing test.
+ int32_t max_bytes; // Total maximum size of the stored data.
+ uint32_t flags;
+ int32_t used_cells;
+ int32_t max_bucket;
+ uint64_t create_time; // Creation time for this set of files.
+ uint64_t base_time; // Current base for timestamps.
+ uint64_t old_time; // Previous time used for timestamps.
+ int32_t max_block_file;
+ int32_t num_no_use_entries;
+ int32_t num_low_use_entries;
+ int32_t num_high_use_entries;
+ int32_t reserved;
+ int32_t num_evicted_entries;
+ int32_t pad[6];
};
const int kBaseBitmapBytes = 3968;
@@ -95,7 +97,7 @@ const int kBaseBitmapBytes = 3968;
// given time. The required file size can be computed from header.table_len.
struct IndexBitmap {
IndexHeaderV3 header;
- uint32 bitmap[kBaseBitmapBytes / 4]; // First page of the bitmap.
+ uint32_t bitmap[kBaseBitmapBytes / 4]; // First page of the bitmap.
};
static_assert(sizeof(IndexBitmap) == 4096, "bad IndexHeader");
@@ -180,16 +182,16 @@ struct IndexCell {
// If that same Addr is stored on a large table, the location field would be
// 0x61234
- uint64 first_part;
- uint8 last_part;
+ uint64_t first_part;
+ uint8_t last_part;
};
static_assert(sizeof(IndexCell) == 9, "bad IndexCell");
const int kCellsPerBucket = 4;
struct IndexBucket {
IndexCell cells[kCellsPerBucket];
- int32 next;
- uint32 hash; // The high order byte is reserved (should be zero).
+ int32_t next;
+ uint32_t hash; // The high order byte is reserved (should be zero).
};
static_assert(sizeof(IndexBucket) == 44, "bad IndexBucket");
const int kBytesPerCell = 44 / kCellsPerBucket;
@@ -209,35 +211,35 @@ enum EntryFlags {
};
struct EntryRecord {
- uint32 hash;
- uint32 pad1;
- uint8 reuse_count;
- uint8 refetch_count;
- int8 state; // Current EntryState.
- uint8 flags; // Any combination of EntryFlags.
- int32 key_len;
- int32 data_size[4]; // We can store up to 4 data streams for each
+ uint32_t hash;
+ uint32_t pad1;
+ uint8_t reuse_count;
+ uint8_t refetch_count;
+ int8_t state; // Current EntryState.
+ uint8_t flags; // Any combination of EntryFlags.
+ int32_t key_len;
+ int32_t data_size[4]; // We can store up to 4 data streams for each
CacheAddr data_addr[4]; // entry.
- uint32 data_hash[4];
- uint64 creation_time;
- uint64 last_modified_time;
- uint64 last_access_time;
- int32 pad[3];
- uint32 self_hash;
+ uint32_t data_hash[4];
+ uint64_t creation_time;
+ uint64_t last_modified_time;
+ uint64_t last_access_time;
+ int32_t pad[3];
+ uint32_t self_hash;
};
static_assert(sizeof(EntryRecord) == 104, "bad EntryRecord");
struct ShortEntryRecord {
- uint32 hash;
- uint32 pad1;
- uint8 reuse_count;
- uint8 refetch_count;
- int8 state; // Current EntryState.
- uint8 flags;
- int32 key_len;
- uint64 last_access_time;
- uint32 long_hash[5];
- uint32 self_hash;
+ uint32_t hash;
+ uint32_t pad1;
+ uint8_t reuse_count;
+ uint8_t refetch_count;
+ int8_t state; // Current EntryState.
+ uint8_t flags;
+ int32_t key_len;
+ uint64_t last_access_time;
+ uint32_t long_hash[5];
+ uint32_t self_hash;
};
static_assert(sizeof(ShortEntryRecord) == 48, "bad ShortEntryRecord");
diff --git a/chromium/net/disk_cache/blockfile/entry_impl.cc b/chromium/net/disk_cache/blockfile/entry_impl.cc
index c26026e2d78..60204641b9f 100644
--- a/chromium/net/disk_cache/blockfile/entry_impl.cc
+++ b/chromium/net/disk_cache/blockfile/entry_impl.cc
@@ -4,7 +4,10 @@
#include "net/disk_cache/blockfile/entry_impl.h"
+#include <limits>
+
#include "base/hash.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "net/base/io_buffer.h"
@@ -350,7 +353,9 @@ int EntryImpl::WriteDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
return result;
}
-int EntryImpl::ReadSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImpl::ReadSparseDataImpl(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
DCHECK(node_.Data()->dirty || read_only_);
int result = InitSparseData();
@@ -364,7 +369,9 @@ int EntryImpl::ReadSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
return result;
}
-int EntryImpl::WriteSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImpl::WriteSparseDataImpl(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
DCHECK(node_.Data()->dirty || read_only_);
int result = InitSparseData();
@@ -378,7 +385,7 @@ int EntryImpl::WriteSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
return result;
}
-int EntryImpl::GetAvailableRangeImpl(int64 offset, int len, int64* start) {
+int EntryImpl::GetAvailableRangeImpl(int64_t offset, int len, int64_t* start) {
int result = InitSparseData();
if (net::OK != result)
return result;
@@ -398,12 +405,13 @@ int EntryImpl::ReadyForSparseIOImpl(const CompletionCallback& callback) {
return sparse_->ReadyToUse(callback);
}
-uint32 EntryImpl::GetHash() {
+uint32_t EntryImpl::GetHash() {
return entry_.Data()->hash;
}
-bool EntryImpl::CreateEntry(Addr node_address, const std::string& key,
- uint32 hash) {
+bool EntryImpl::CreateEntry(Addr node_address,
+ const std::string& key,
+ uint32_t hash) {
Trace("Create entry In");
EntryStore* entry_store = entry_.Data();
RankingsNode* node = node_.Data();
@@ -417,7 +425,7 @@ bool EntryImpl::CreateEntry(Addr node_address, const std::string& key,
entry_store->hash = hash;
entry_store->creation_time = Time::Now().ToInternalValue();
- entry_store->key_len = static_cast<int32>(key.size());
+ entry_store->key_len = static_cast<int32_t>(key.size());
if (entry_store->key_len > kMaxInternalKeyLength) {
Addr address(0);
if (!CreateBlock(entry_store->key_len + 1, &address))
@@ -442,14 +450,14 @@ bool EntryImpl::CreateEntry(Addr node_address, const std::string& key,
memcpy(entry_store->key, key.data(), key.size());
entry_store->key[key.size()] = '\0';
}
- backend_->ModifyStorageSize(0, static_cast<int32>(key.size()));
- CACHE_UMA(COUNTS, "KeySize", 0, static_cast<int32>(key.size()));
+ backend_->ModifyStorageSize(0, static_cast<int32_t>(key.size()));
+ CACHE_UMA(COUNTS, "KeySize", 0, static_cast<int32_t>(key.size()));
node->dirty = backend_->GetCurrentEntryId();
Log("Create Entry ");
return true;
}
-bool EntryImpl::IsSameEntry(const std::string& key, uint32 hash) {
+bool EntryImpl::IsSameEntry(const std::string& key, uint32_t hash) {
if (entry_.Data()->hash != hash ||
static_cast<size_t>(entry_.Data()->key_len) != key.size())
return false;
@@ -546,7 +554,7 @@ bool EntryImpl::Update() {
return true;
}
-void EntryImpl::SetDirtyFlag(int32 current_id) {
+void EntryImpl::SetDirtyFlag(int32_t current_id) {
DCHECK(node_.HasData());
if (node_.Data()->dirty && current_id != node_.Data()->dirty)
dirty_ = true;
@@ -555,7 +563,7 @@ void EntryImpl::SetDirtyFlag(int32 current_id) {
dirty_ = true;
}
-void EntryImpl::SetPointerForInvalidEntry(int32 new_id) {
+void EntryImpl::SetPointerForInvalidEntry(int32_t new_id) {
node_.Data()->dirty = new_id;
node_.Store();
}
@@ -800,7 +808,7 @@ Time EntryImpl::GetLastModified() const {
return Time::FromInternalValue(node->Data()->last_modified);
}
-int32 EntryImpl::GetDataSize(int index) const {
+int32_t EntryImpl::GetDataSize(int index) const {
if (index < 0 || index >= kNumStreams)
return 0;
@@ -851,7 +859,9 @@ int EntryImpl::WriteData(int index, int offset, IOBuffer* buf, int buf_len,
return net::ERR_IO_PENDING;
}
-int EntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImpl::ReadSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
if (callback.is_null())
return ReadSparseDataImpl(offset, buf, buf_len, callback);
@@ -863,7 +873,9 @@ int EntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
return net::ERR_IO_PENDING;
}
-int EntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImpl::WriteSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
if (callback.is_null())
return WriteSparseDataImpl(offset, buf, buf_len, callback);
@@ -875,7 +887,9 @@ int EntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
return net::ERR_IO_PENDING;
}
-int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start,
+int EntryImpl::GetAvailableRange(int64_t offset,
+ int len,
+ int64_t* start,
const CompletionCallback& callback) {
if (!background_queue_.get())
return net::ERR_UNEXPECTED;
@@ -1077,7 +1091,7 @@ int EntryImpl::InternalWriteData(int index, int offset,
offset + buf_len > max_file_size) {
int size = offset + buf_len;
if (size <= max_file_size)
- size = kint32max;
+ size = std::numeric_limits<int32_t>::max();
backend_->TooMuchStorageRequested(size);
return net::ERR_FAILED;
}
@@ -1499,12 +1513,12 @@ int EntryImpl::InitSparseData() {
return result;
}
-void EntryImpl::SetEntryFlags(uint32 flags) {
+void EntryImpl::SetEntryFlags(uint32_t flags) {
entry_.Data()->flags |= flags;
entry_.set_modified();
}
-uint32 EntryImpl::GetEntryFlags() {
+uint32_t EntryImpl::GetEntryFlags() {
return entry_.Data()->flags;
}
diff --git a/chromium/net/disk_cache/blockfile/entry_impl.h b/chromium/net/disk_cache/blockfile/entry_impl.h
index aafb59b66a2..336ccc9c871 100644
--- a/chromium/net/disk_cache/blockfile/entry_impl.h
+++ b/chromium/net/disk_cache/blockfile/entry_impl.h
@@ -5,6 +5,9 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_ENTRY_IMPL_H_
#define NET_DISK_CACHE_BLOCKFILE_ENTRY_IMPL_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/disk_cache/blockfile/disk_format.h"
#include "net/disk_cache/blockfile/storage_block-inl.h"
@@ -46,11 +49,15 @@ class NET_EXPORT_PRIVATE EntryImpl
const CompletionCallback& callback);
int WriteDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
const CompletionCallback& callback, bool truncate);
- int ReadSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
+ int ReadSparseDataImpl(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback);
- int WriteSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
+ int WriteSparseDataImpl(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback);
- int GetAvailableRangeImpl(int64 offset, int len, int64* start);
+ int GetAvailableRangeImpl(int64_t offset, int len, int64_t* start);
void CancelSparseIOImpl();
int ReadyForSparseIOImpl(const CompletionCallback& callback);
@@ -62,14 +69,14 @@ class NET_EXPORT_PRIVATE EntryImpl
return &node_;
}
- uint32 GetHash();
+ uint32_t GetHash();
// Performs the initialization of a EntryImpl that will be added to the
// cache.
- bool CreateEntry(Addr node_address, const std::string& key, uint32 hash);
+ bool CreateEntry(Addr node_address, const std::string& key, uint32_t hash);
// Returns true if this entry matches the lookup arguments.
- bool IsSameEntry(const std::string& key, uint32 hash);
+ bool IsSameEntry(const std::string& key, uint32_t hash);
// Permamently destroys this entry.
void InternalDoom();
@@ -104,10 +111,10 @@ class NET_EXPORT_PRIVATE EntryImpl
// Marks this entry as dirty (in memory) if needed. This is intended only for
// entries that are being read from disk, to be called during loading.
- void SetDirtyFlag(int32 current_id);
+ void SetDirtyFlag(int32_t current_id);
// Fixes this entry so it can be treated as valid (to delete it).
- void SetPointerForInvalidEntry(int32 new_id);
+ void SetPointerForInvalidEntry(int32_t new_id);
// Returns true if this entry is so meesed up that not everything is going to
// be removed.
@@ -152,7 +159,7 @@ class NET_EXPORT_PRIVATE EntryImpl
std::string GetKey() const override;
base::Time GetLastUsed() const override;
base::Time GetLastModified() const override;
- int32 GetDataSize(int index) const override;
+ int32_t GetDataSize(int index) const override;
int ReadData(int index,
int offset,
IOBuffer* buf,
@@ -164,17 +171,17 @@ class NET_EXPORT_PRIVATE EntryImpl
int buf_len,
const CompletionCallback& callback,
bool truncate) override;
- int ReadSparseData(int64 offset,
+ int ReadSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int WriteSparseData(int64 offset,
+ int WriteSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int GetAvailableRange(int64 offset,
+ int GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) override;
bool CouldBeSparse() const override;
void CancelSparseIO() override;
@@ -248,10 +255,10 @@ class NET_EXPORT_PRIVATE EntryImpl
int InitSparseData();
// Adds the provided |flags| to the current EntryFlags for this entry.
- void SetEntryFlags(uint32 flags);
+ void SetEntryFlags(uint32_t flags);
// Returns the current EntryFlags for this entry.
- uint32 GetEntryFlags();
+ uint32_t GetEntryFlags();
// Gets the data stored at the given index. If the information is in memory,
// a buffer will be allocated and the data will be copied to it (the caller
diff --git a/chromium/net/disk_cache/blockfile/entry_impl_v3.cc b/chromium/net/disk_cache/blockfile/entry_impl_v3.cc
index 73719364829..883a6f24ade 100644
--- a/chromium/net/disk_cache/blockfile/entry_impl_v3.cc
+++ b/chromium/net/disk_cache/blockfile/entry_impl_v3.cc
@@ -4,7 +4,10 @@
#include "net/disk_cache/blockfile/entry_impl_v3.h"
+#include <limits>
+
#include "base/hash.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "net/base/io_buffer.h"
@@ -257,8 +260,9 @@ EntryImplV3::EntryImplV3(BackendImplV3* backend, Addr address, bool read_only)
#if defined(V3_NOT_JUST_YET_READY)
-bool EntryImplV3::CreateEntry(Addr node_address, const std::string& key,
- uint32 hash) {
+bool EntryImplV3::CreateEntry(Addr node_address,
+ const std::string& key,
+ uint32_t hash) {
Trace("Create entry In");
EntryStore* entry_store = entry_.Data();
RankingsNode* node = node_.Data();
@@ -272,7 +276,7 @@ bool EntryImplV3::CreateEntry(Addr node_address, const std::string& key,
entry_store->hash = hash;
entry_store->creation_time = Time::Now().ToInternalValue();
- entry_store->key_len = static_cast<int32>(key.size());
+ entry_store->key_len = static_cast<int32_t>(key.size());
if (entry_store->key_len > kMaxInternalKeyLength) {
Addr address(0);
if (!CreateBlock(entry_store->key_len + 1, &address))
@@ -297,18 +301,18 @@ bool EntryImplV3::CreateEntry(Addr node_address, const std::string& key,
memcpy(entry_store->key, key.data(), key.size());
entry_store->key[key.size()] = '\0';
}
- backend_->ModifyStorageSize(0, static_cast<int32>(key.size()));
- CACHE_UMA(COUNTS, "KeySize", 0, static_cast<int32>(key.size()));
+ backend_->ModifyStorageSize(0, static_cast<int32_t>(key.size()));
+ CACHE_UMA(COUNTS, "KeySize", 0, static_cast<int32_t>(key.size()));
node->dirty = backend_->GetCurrentEntryId();
Log("Create Entry ");
return true;
}
-uint32 EntryImplV3::GetHash() {
+uint32_t EntryImplV3::GetHash() {
return entry_.Data()->hash;
}
-bool EntryImplV3::IsSameEntry(const std::string& key, uint32 hash) {
+bool EntryImplV3::IsSameEntry(const std::string& key, uint32_t hash) {
if (entry_.Data()->hash != hash ||
static_cast<size_t>(entry_.Data()->key_len) != key.size())
return false;
@@ -513,7 +517,7 @@ Time EntryImplV3::GetLastModified() const {
return Time::FromInternalValue(node->Data()->last_modified);
}
-int32 EntryImplV3::GetDataSize(int index) const {
+int32_t EntryImplV3::GetDataSize(int index) const {
if (index < 0 || index >= kNumStreams)
return 0;
@@ -602,7 +606,9 @@ int EntryImpl::WriteDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
return result;
}
-int EntryImplV3::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImplV3::ReadSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
if (callback.is_null())
return ReadSparseDataImpl(offset, buf, buf_len, callback);
@@ -614,7 +620,9 @@ int EntryImplV3::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
return net::ERR_IO_PENDING;
}
-int EntryImpl::ReadSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImpl::ReadSparseDataImpl(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
DCHECK(node_.Data()->dirty || read_only_);
int result = InitSparseData();
@@ -628,7 +636,9 @@ int EntryImpl::ReadSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
return result;
}
-int EntryImplV3::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImplV3::WriteSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
if (callback.is_null())
return WriteSparseDataImpl(offset, buf, buf_len, callback);
@@ -640,7 +650,9 @@ int EntryImplV3::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
return net::ERR_IO_PENDING;
}
-int EntryImpl::WriteSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImpl::WriteSparseDataImpl(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
DCHECK(node_.Data()->dirty || read_only_);
int result = InitSparseData();
@@ -654,7 +666,9 @@ int EntryImpl::WriteSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
return result;
}
-int EntryImplV3::GetAvailableRange(int64 offset, int len, int64* start,
+int EntryImplV3::GetAvailableRange(int64_t offset,
+ int len,
+ int64_t* start,
const CompletionCallback& callback) {
if (!background_queue_)
return net::ERR_UNEXPECTED;
@@ -663,7 +677,7 @@ int EntryImplV3::GetAvailableRange(int64 offset, int len, int64* start,
return net::ERR_IO_PENDING;
}
-int EntryImpl::GetAvailableRangeImpl(int64 offset, int len, int64* start) {
+int EntryImpl::GetAvailableRangeImpl(int64_t offset, int len, int64_t* start) {
int result = InitSparseData();
if (net::OK != result)
return result;
@@ -875,7 +889,7 @@ int EntryImpl::InternalWriteData(int index, int offset,
offset + buf_len > max_file_size) {
int size = offset + buf_len;
if (size <= max_file_size)
- size = kint32max;
+ size = std::numeric_limits<int32_t>::max();
backend_->TooMuchStorageRequested(size);
return net::ERR_FAILED;
}
@@ -1320,12 +1334,12 @@ int EntryImpl::InitSparseData() {
return result;
}
-void EntryImpl::SetEntryFlags(uint32 flags) {
+void EntryImpl::SetEntryFlags(uint32_t flags) {
entry_.Data()->flags |= flags;
entry_.set_modified();
}
-uint32 EntryImpl::GetEntryFlags() {
+uint32_t EntryImpl::GetEntryFlags() {
return entry_.Data()->flags;
}
@@ -1415,7 +1429,7 @@ Time EntryImplV3::GetLastModified() const {
return Time();
}
-int32 EntryImplV3::GetDataSize(int index) const {
+int32_t EntryImplV3::GetDataSize(int index) const {
return 0;
}
@@ -1429,17 +1443,23 @@ int EntryImplV3::WriteData(int index, int offset, IOBuffer* buf, int buf_len,
return net::ERR_FAILED;
}
-int EntryImplV3::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImplV3::ReadSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
return net::ERR_FAILED;
}
-int EntryImplV3::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int EntryImplV3::WriteSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
return net::ERR_FAILED;
}
-int EntryImplV3::GetAvailableRange(int64 offset, int len, int64* start,
+int EntryImplV3::GetAvailableRange(int64_t offset,
+ int len,
+ int64_t* start,
const CompletionCallback& callback) {
return net::ERR_FAILED;
}
diff --git a/chromium/net/disk_cache/blockfile/entry_impl_v3.h b/chromium/net/disk_cache/blockfile/entry_impl_v3.h
index e36834b6755..a9a5df5170d 100644
--- a/chromium/net/disk_cache/blockfile/entry_impl_v3.h
+++ b/chromium/net/disk_cache/blockfile/entry_impl_v3.h
@@ -5,8 +5,11 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_ENTRY_IMPL_V3_H_
#define NET_DISK_CACHE_BLOCKFILE_ENTRY_IMPL_V3_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/disk_cache/blockfile/disk_format_v3.h"
#include "net/disk_cache/blockfile/storage_block.h"
@@ -40,11 +43,11 @@ class NET_EXPORT_PRIVATE EntryImplV3
// Performs the initialization of a EntryImplV3 that will be added to the
// cache.
- bool CreateEntry(Addr node_address, const std::string& key, uint32 hash);
+ bool CreateEntry(Addr node_address, const std::string& key, uint32_t hash);
- uint32 GetHash();
+ uint32_t GetHash();
- uint32 GetHash() const;
+ uint32_t GetHash() const;
Addr GetAddress() const;
int GetReuseCounter() const;
void SetReuseCounter(int count);
@@ -52,7 +55,7 @@ class NET_EXPORT_PRIVATE EntryImplV3
void SetRefetchCounter(int count);
// Returns true if this entry matches the lookup arguments.
- bool IsSameEntry(const std::string& key, uint32 hash);
+ bool IsSameEntry(const std::string& key, uint32_t hash);
// Permamently destroys this entry.
void InternalDoom();
@@ -82,7 +85,7 @@ class NET_EXPORT_PRIVATE EntryImplV3
std::string GetKey() const override;
base::Time GetLastUsed() const override;
base::Time GetLastModified() const override;
- int32 GetDataSize(int index) const override;
+ int32_t GetDataSize(int index) const override;
int ReadData(int index,
int offset,
IOBuffer* buf,
@@ -94,17 +97,17 @@ class NET_EXPORT_PRIVATE EntryImplV3
int buf_len,
const CompletionCallback& callback,
bool truncate) override;
- int ReadSparseData(int64 offset,
+ int ReadSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int WriteSparseData(int64 offset,
+ int WriteSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int GetAvailableRange(int64 offset,
+ int GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) override;
bool CouldBeSparse() const override;
void CancelSparseIO() override;
@@ -176,10 +179,10 @@ class NET_EXPORT_PRIVATE EntryImplV3
int InitSparseData();
// Adds the provided |flags| to the current EntryFlags for this entry.
- void SetEntryFlags(uint32 flags);
+ void SetEntryFlags(uint32_t flags);
// Returns the current EntryFlags for this entry.
- uint32 GetEntryFlags();
+ uint32_t GetEntryFlags();
// Gets the data stored at the given index. If the information is in memory,
// a buffer will be allocated and the data will be copied to it (the caller
diff --git a/chromium/net/disk_cache/blockfile/eviction.cc b/chromium/net/disk_cache/blockfile/eviction.cc
index 46eb2d7f70e..6e0dcd5a833 100644
--- a/chromium/net/disk_cache/blockfile/eviction.cc
+++ b/chromium/net/disk_cache/blockfile/eviction.cc
@@ -28,6 +28,10 @@
#include "net/disk_cache/blockfile/eviction.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
@@ -408,7 +412,7 @@ void Eviction::OnOpenEntryV2(EntryImpl* entry) {
EntryStore* info = entry->entry()->Data();
DCHECK_EQ(ENTRY_NORMAL, info->state);
- if (info->reuse_count < kint32max) {
+ if (info->reuse_count < std::numeric_limits<int32_t>::max()) {
info->reuse_count++;
entry->entry()->set_modified();
@@ -434,7 +438,7 @@ void Eviction::OnCreateEntryV2(EntryImpl* entry) {
break;
};
case ENTRY_EVICTED: {
- if (info->refetch_count < kint32max)
+ if (info->refetch_count < std::numeric_limits<int32_t>::max())
info->refetch_count++;
if (info->refetch_count > kHighUse && info->reuse_count < kHighUse) {
diff --git a/chromium/net/disk_cache/blockfile/eviction.h b/chromium/net/disk_cache/blockfile/eviction.h
index e49883bac2e..baea659e247 100644
--- a/chromium/net/disk_cache/blockfile/eviction.h
+++ b/chromium/net/disk_cache/blockfile/eviction.h
@@ -5,7 +5,7 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_EVICTION_H_
#define NET_DISK_CACHE_BLOCKFILE_EVICTION_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/disk_cache/blockfile/rankings.h"
diff --git a/chromium/net/disk_cache/blockfile/eviction_v3.cc b/chromium/net/disk_cache/blockfile/eviction_v3.cc
index 9d404a9172a..c658a8e0e52 100644
--- a/chromium/net/disk_cache/blockfile/eviction_v3.cc
+++ b/chromium/net/disk_cache/blockfile/eviction_v3.cc
@@ -28,6 +28,10 @@
#include "net/disk_cache/blockfile/eviction_v3.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
@@ -174,7 +178,7 @@ void EvictionV3::OnOpenEntry(EntryImplV3* entry) {
EntryStore* info = entry->entry()->Data();
DCHECK_EQ(ENTRY_NORMAL, info->state);
- if (info->reuse_count < kint32max) {
+ if (info->reuse_count < std::numeric_limits<int32_t>::max()) {
info->reuse_count++;
entry->entry()->set_modified();
@@ -200,7 +204,7 @@ void EvictionV3::OnCreateEntry(EntryImplV3* entry) {
break;
};
case ENTRY_EVICTED: {
- if (info->refetch_count < kint32max)
+ if (info->refetch_count < std::numeric_limits<int32_t>::max())
info->refetch_count++;
if (info->refetch_count > kHighUse && info->reuse_count < kHighUse) {
diff --git a/chromium/net/disk_cache/blockfile/eviction_v3.h b/chromium/net/disk_cache/blockfile/eviction_v3.h
index 01fe6136115..a9b48f41839 100644
--- a/chromium/net/disk_cache/blockfile/eviction_v3.h
+++ b/chromium/net/disk_cache/blockfile/eviction_v3.h
@@ -5,7 +5,7 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_EVICTION_V3_H_
#define NET_DISK_CACHE_BLOCKFILE_EVICTION_V3_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/disk_cache/blockfile/disk_format_v3.h"
#include "net/disk_cache/blockfile/index_table_v3.h"
diff --git a/chromium/net/disk_cache/blockfile/experiments.h b/chromium/net/disk_cache/blockfile/experiments.h
index 53b6582b0d7..a2ca9600625 100644
--- a/chromium/net/disk_cache/blockfile/experiments.h
+++ b/chromium/net/disk_cache/blockfile/experiments.h
@@ -5,7 +5,6 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_EXPERIMENTS_H_
#define NET_DISK_CACHE_BLOCKFILE_EXPERIMENTS_H_
-
namespace disk_cache {
// This lists the experiment groups that we care about. Only add new groups at
diff --git a/chromium/net/disk_cache/blockfile/file.h b/chromium/net/disk_cache/blockfile/file.h
index 9425d598501..0e34fabf3d6 100644
--- a/chromium/net/disk_cache/blockfile/file.h
+++ b/chromium/net/disk_cache/blockfile/file.h
@@ -7,7 +7,10 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_FILE_H_
#define NET_DISK_CACHE_BLOCKFILE_FILE_H_
+#include <stddef.h>
+
#include "base/files/file.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/disk_cache/blockfile/file_block.h b/chromium/net/disk_cache/blockfile/file_block.h
index fdcfcd05f51..4250dd1b492 100644
--- a/chromium/net/disk_cache/blockfile/file_block.h
+++ b/chromium/net/disk_cache/blockfile/file_block.h
@@ -7,6 +7,8 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_FILE_BLOCK_H_
#define NET_DISK_CACHE_BLOCKFILE_FILE_BLOCK_H_
+#include <stddef.h>
+
namespace disk_cache {
// This interface exposes common functionality for a single block of data
diff --git a/chromium/net/disk_cache/blockfile/file_ios.cc b/chromium/net/disk_cache/blockfile/file_ios.cc
index 3ffb5a58567..b2a6d6ef400 100644
--- a/chromium/net/disk_cache/blockfile/file_ios.cc
+++ b/chromium/net/disk_cache/blockfile/file_ios.cc
@@ -4,9 +4,16 @@
#include "net/disk_cache/blockfile/file.h"
+#include <limits.h>
+#include <stdint.h>
+
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/threading/worker_pool.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/blockfile/in_flight_io.h"
@@ -167,10 +174,7 @@ void DeleteFileInFlightIO() {
namespace disk_cache {
File::File(base::File file)
- : init_(true),
- mixed_(true),
- base_file_(file.Pass()) {
-}
+ : init_(true), mixed_(true), base_file_(std::move(file)) {}
bool File::Init(const base::FilePath& name) {
if (base_file_.IsValid())
@@ -188,8 +192,8 @@ bool File::IsValid() const {
bool File::Read(void* buffer, size_t buffer_len, size_t offset) {
DCHECK(base_file_.IsValid());
- if (buffer_len > static_cast<size_t>(kint32max) ||
- offset > static_cast<size_t>(kint32max)) {
+ if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) ||
+ offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
return false;
}
@@ -199,8 +203,8 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset) {
bool File::Write(const void* buffer, size_t buffer_len, size_t offset) {
DCHECK(base_file_.IsValid());
- if (buffer_len > static_cast<size_t>(kint32max) ||
- offset > static_cast<size_t>(kint32max)) {
+ if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) ||
+ offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
return false;
}
@@ -244,7 +248,7 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset,
bool File::SetLength(size_t length) {
DCHECK(base_file_.IsValid());
- if (length > kuint32max)
+ if (length > std::numeric_limits<uint32_t>::max())
return false;
return base_file_.SetLength(length);
@@ -252,10 +256,10 @@ bool File::SetLength(size_t length) {
size_t File::GetLength() {
DCHECK(base_file_.IsValid());
- int64 len = base_file_.GetLength();
+ int64_t len = base_file_.GetLength();
- if (len > static_cast<int64>(kuint32max))
- return kuint32max;
+ if (len > static_cast<int64_t>(std::numeric_limits<uint32_t>::max()))
+ return std::numeric_limits<uint32_t>::max();
return static_cast<size_t>(len);
}
diff --git a/chromium/net/disk_cache/blockfile/file_lock.h b/chromium/net/disk_cache/blockfile/file_lock.h
index 3486aba18d1..607abfcd188 100644
--- a/chromium/net/disk_cache/blockfile/file_lock.h
+++ b/chromium/net/disk_cache/blockfile/file_lock.h
@@ -7,6 +7,8 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_FILE_LOCK_H_
#define NET_DISK_CACHE_BLOCKFILE_FILE_LOCK_H_
+#include <stdint.h>
+
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/disk_format_base.h"
@@ -37,7 +39,7 @@ class NET_EXPORT_PRIVATE FileLock {
virtual void Unlock();
private:
bool acquired_;
- volatile int32* updating_;
+ volatile int32_t* updating_;
};
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/blockfile/file_posix.cc b/chromium/net/disk_cache/blockfile/file_posix.cc
index 828673f9b30..5a3ad455478 100644
--- a/chromium/net/disk_cache/blockfile/file_posix.cc
+++ b/chromium/net/disk_cache/blockfile/file_posix.cc
@@ -4,6 +4,10 @@
#include "net/disk_cache/blockfile/file.h"
+#include <stdint.h>
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/location.h"
@@ -35,10 +39,7 @@ base::LazyInstance<FileWorkerPool>::Leaky s_worker_pool =
namespace disk_cache {
File::File(base::File file)
- : init_(true),
- mixed_(true),
- base_file_(file.Pass()) {
-}
+ : init_(true), mixed_(true), base_file_(std::move(file)) {}
bool File::Init(const base::FilePath& name) {
if (base_file_.IsValid())
@@ -56,8 +57,8 @@ bool File::IsValid() const {
bool File::Read(void* buffer, size_t buffer_len, size_t offset) {
DCHECK(base_file_.IsValid());
- if (buffer_len > static_cast<size_t>(kint32max) ||
- offset > static_cast<size_t>(kint32max)) {
+ if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) ||
+ offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
return false;
}
@@ -67,8 +68,8 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset) {
bool File::Write(const void* buffer, size_t buffer_len, size_t offset) {
DCHECK(base_file_.IsValid());
- if (buffer_len > static_cast<size_t>(kint32max) ||
- offset > static_cast<size_t>(kint32max)) {
+ if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) ||
+ offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
return false;
}
@@ -86,8 +87,8 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset,
return Read(buffer, buffer_len, offset);
}
- if (buffer_len > static_cast<size_t>(kint32max) ||
- offset > static_cast<size_t>(kint32max)) {
+ if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) ||
+ offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
return false;
}
@@ -109,8 +110,8 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset,
return Write(buffer, buffer_len, offset);
}
- if (buffer_len > static_cast<size_t>(kint32max) ||
- offset > static_cast<size_t>(kint32max)) {
+ if (buffer_len > static_cast<size_t>(std::numeric_limits<int32_t>::max()) ||
+ offset > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
return false;
}
@@ -125,7 +126,7 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset,
bool File::SetLength(size_t length) {
DCHECK(base_file_.IsValid());
- if (length > kuint32max)
+ if (length > std::numeric_limits<uint32_t>::max())
return false;
return base_file_.SetLength(length);
@@ -133,10 +134,10 @@ bool File::SetLength(size_t length) {
size_t File::GetLength() {
DCHECK(base_file_.IsValid());
- int64 len = base_file_.GetLength();
+ int64_t len = base_file_.GetLength();
- if (len > static_cast<int64>(kuint32max))
- return kuint32max;
+ if (len > static_cast<int64_t>(std::numeric_limits<uint32_t>::max()))
+ return std::numeric_limits<uint32_t>::max();
return static_cast<size_t>(len);
}
diff --git a/chromium/net/disk_cache/blockfile/file_win.cc b/chromium/net/disk_cache/blockfile/file_win.cc
index 81f8cf86fa8..ef7be4308d1 100644
--- a/chromium/net/disk_cache/blockfile/file_win.cc
+++ b/chromium/net/disk_cache/blockfile/file_win.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/blockfile/file.h"
+#include <limits.h>
+
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
diff --git a/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc b/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc
index 28d7114ba61..307f7d2a8d0 100644
--- a/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc
+++ b/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/blockfile/in_flight_backend_io.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
@@ -115,6 +117,10 @@ void BackendIO::DoomEntriesSince(const base::Time initial_time) {
initial_time_ = initial_time;
}
+void BackendIO::CalculateSizeOfAllEntries() {
+ operation_ = OP_SIZE_ALL;
+}
+
void BackendIO::OpenNextEntry(Rankings::Iterator* iterator,
Entry** next_entry) {
operation_ = OP_OPEN_NEXT;
@@ -124,7 +130,7 @@ void BackendIO::OpenNextEntry(Rankings::Iterator* iterator,
void BackendIO::EndEnumeration(scoped_ptr<Rankings::Iterator> iterator) {
operation_ = OP_END_ENUMERATION;
- scoped_iterator_ = iterator.Pass();
+ scoped_iterator_ = std::move(iterator);
}
void BackendIO::OnExternalCacheHit(const std::string& key) {
@@ -172,8 +178,10 @@ void BackendIO::WriteData(EntryImpl* entry, int index, int offset,
truncate_ = truncate;
}
-void BackendIO::ReadSparseData(EntryImpl* entry, int64 offset,
- net::IOBuffer* buf, int buf_len) {
+void BackendIO::ReadSparseData(EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len) {
operation_ = OP_READ_SPARSE;
entry_ = entry;
offset64_ = offset;
@@ -181,8 +189,10 @@ void BackendIO::ReadSparseData(EntryImpl* entry, int64 offset,
buf_len_ = buf_len;
}
-void BackendIO::WriteSparseData(EntryImpl* entry, int64 offset,
- net::IOBuffer* buf, int buf_len) {
+void BackendIO::WriteSparseData(EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len) {
operation_ = OP_WRITE_SPARSE;
entry_ = entry;
offset64_ = offset;
@@ -190,8 +200,10 @@ void BackendIO::WriteSparseData(EntryImpl* entry, int64 offset,
buf_len_ = buf_len;
}
-void BackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, int len,
- int64* start) {
+void BackendIO::GetAvailableRange(EntryImpl* entry,
+ int64_t offset,
+ int len,
+ int64_t* start) {
operation_ = OP_GET_RANGE;
entry_ = entry;
offset64_ = offset;
@@ -244,11 +256,14 @@ void BackendIO::ExecuteBackendOperation() {
case OP_DOOM_SINCE:
result_ = backend_->SyncDoomEntriesSince(initial_time_);
break;
+ case OP_SIZE_ALL:
+ result_ = backend_->SyncCalculateSizeOfAllEntries();
+ break;
case OP_OPEN_NEXT:
result_ = backend_->SyncOpenNextEntry(iterator_, entry_ptr_);
break;
case OP_END_ENUMERATION:
- backend_->SyncEndEnumeration(scoped_iterator_.Pass());
+ backend_->SyncEndEnumeration(std::move(scoped_iterator_));
result_ = net::OK;
break;
case OP_ON_EXTERNAL_CACHE_HIT:
@@ -375,6 +390,13 @@ void InFlightBackendIO::DoomEntriesBetween(const base::Time initial_time,
PostOperation(operation.get());
}
+void InFlightBackendIO::CalculateSizeOfAllEntries(
+ const net::CompletionCallback& callback) {
+ scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ operation->CalculateSizeOfAllEntries();
+ PostOperation(operation.get());
+}
+
void InFlightBackendIO::DoomEntriesSince(
const base::Time initial_time, const net::CompletionCallback& callback) {
scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
@@ -394,7 +416,7 @@ void InFlightBackendIO::EndEnumeration(
scoped_ptr<Rankings::Iterator> iterator) {
scoped_refptr<BackendIO> operation(
new BackendIO(this, backend_, net::CompletionCallback()));
- operation->EndEnumeration(iterator.Pass());
+ operation->EndEnumeration(std::move(iterator));
PostOperation(operation.get());
}
@@ -450,7 +472,10 @@ void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset,
}
void InFlightBackendIO::ReadSparseData(
- EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len,
+ EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
const net::CompletionCallback& callback) {
scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
operation->ReadSparseData(entry, offset, buf, buf_len);
@@ -458,7 +483,10 @@ void InFlightBackendIO::ReadSparseData(
}
void InFlightBackendIO::WriteSparseData(
- EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len,
+ EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
const net::CompletionCallback& callback) {
scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
operation->WriteSparseData(entry, offset, buf, buf_len);
@@ -466,7 +494,10 @@ void InFlightBackendIO::WriteSparseData(
}
void InFlightBackendIO::GetAvailableRange(
- EntryImpl* entry, int64 offset, int len, int64* start,
+ EntryImpl* entry,
+ int64_t offset,
+ int len,
+ int64_t* start,
const net::CompletionCallback& callback) {
scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
operation->GetAvailableRange(entry, offset, len, start);
diff --git a/chromium/net/disk_cache/blockfile/in_flight_backend_io.h b/chromium/net/disk_cache/blockfile/in_flight_backend_io.h
index e2fa4e7b3a5..5ac0bf44235 100644
--- a/chromium/net/disk_cache/blockfile/in_flight_backend_io.h
+++ b/chromium/net/disk_cache/blockfile/in_flight_backend_io.h
@@ -5,9 +5,12 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
#define NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
+#include <stdint.h>
+
#include <list>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
@@ -56,6 +59,7 @@ class BackendIO : public BackgroundIO {
void DoomEntriesBetween(const base::Time initial_time,
const base::Time end_time);
void DoomEntriesSince(const base::Time initial_time);
+ void CalculateSizeOfAllEntries();
void OpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry);
void EndEnumeration(scoped_ptr<Rankings::Iterator> iterator);
void OnExternalCacheHit(const std::string& key);
@@ -67,11 +71,18 @@ class BackendIO : public BackgroundIO {
int buf_len);
void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
int buf_len, bool truncate);
- void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
+ void ReadSparseData(EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
int buf_len);
- void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
+ void WriteSparseData(EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
int buf_len);
- void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start);
+ void GetAvailableRange(EntryImpl* entry,
+ int64_t offset,
+ int len,
+ int64_t* start);
void CancelSparseIO(EntryImpl* entry);
void ReadyForSparseIO(EntryImpl* entry);
@@ -90,6 +101,7 @@ class BackendIO : public BackgroundIO {
OP_DOOM_ALL,
OP_DOOM_BETWEEN,
OP_DOOM_SINCE,
+ OP_SIZE_ALL,
OP_OPEN_NEXT,
OP_END_ENUMERATION,
OP_ON_EXTERNAL_CACHE_HIT,
@@ -135,8 +147,8 @@ class BackendIO : public BackgroundIO {
scoped_refptr<net::IOBuffer> buf_;
int buf_len_;
bool truncate_;
- int64 offset64_;
- int64* start_;
+ int64_t offset64_;
+ int64_t* start_;
base::TimeTicks start_time_;
base::Closure task_;
@@ -165,6 +177,7 @@ class InFlightBackendIO : public InFlightIO {
const net::CompletionCallback& callback);
void DoomEntriesSince(const base::Time initial_time,
const net::CompletionCallback& callback);
+ void CalculateSizeOfAllEntries(const net::CompletionCallback& callback);
void OpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry,
const net::CompletionCallback& callback);
void EndEnumeration(scoped_ptr<Rankings::Iterator> iterator);
@@ -179,11 +192,20 @@ class InFlightBackendIO : public InFlightIO {
void WriteData(
EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
int buf_len, bool truncate, const net::CompletionCallback& callback);
- void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
- int buf_len, const net::CompletionCallback& callback);
- void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
- int buf_len, const net::CompletionCallback& callback);
- void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start,
+ void ReadSparseData(EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback);
+ void WriteSparseData(EntryImpl* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback);
+ void GetAvailableRange(EntryImpl* entry,
+ int64_t offset,
+ int len,
+ int64_t* start,
const net::CompletionCallback& callback);
void CancelSparseIO(EntryImpl* entry);
void ReadyForSparseIO(EntryImpl* entry,
diff --git a/chromium/net/disk_cache/blockfile/in_flight_io.h b/chromium/net/disk_cache/blockfile/in_flight_io.h
index 288a7c5d6d3..2834b947baa 100644
--- a/chromium/net/disk_cache/blockfile/in_flight_io.h
+++ b/chromium/net/disk_cache/blockfile/in_flight_io.h
@@ -7,6 +7,7 @@
#include <set>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
diff --git a/chromium/net/disk_cache/blockfile/index_table_v3.cc b/chromium/net/disk_cache/blockfile/index_table_v3.cc
index 039cba7f052..9c24e8053fe 100644
--- a/chromium/net/disk_cache/blockfile/index_table_v3.cc
+++ b/chromium/net/disk_cache/blockfile/index_table_v3.cc
@@ -5,9 +5,11 @@
#include "net/disk_cache/blockfile/index_table_v3.h"
#include <algorithm>
+#include <limits>
#include <set>
#include <utility>
+#include "base/bit_cast.h"
#include "base/bits.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -24,16 +26,16 @@ namespace {
// The following constants describe the bitfields of an IndexCell so they are
// implicitly synchronized with the descrption of IndexCell on file_format_v3.h.
-const uint64 kCellLocationMask = (1 << 22) - 1;
-const uint64 kCellIdMask = (1 << 18) - 1;
-const uint64 kCellTimestampMask = (1 << 20) - 1;
-const uint64 kCellReuseMask = (1 << 4) - 1;
-const uint8 kCellStateMask = (1 << 3) - 1;
-const uint8 kCellGroupMask = (1 << 3) - 1;
-const uint8 kCellSumMask = (1 << 2) - 1;
+const uint64_t kCellLocationMask = (1 << 22) - 1;
+const uint64_t kCellIdMask = (1 << 18) - 1;
+const uint64_t kCellTimestampMask = (1 << 20) - 1;
+const uint64_t kCellReuseMask = (1 << 4) - 1;
+const uint8_t kCellStateMask = (1 << 3) - 1;
+const uint8_t kCellGroupMask = (1 << 3) - 1;
+const uint8_t kCellSumMask = (1 << 2) - 1;
-const uint64 kCellSmallTableLocationMask = (1 << 16) - 1;
-const uint64 kCellSmallTableIdMask = (1 << 24) - 1;
+const uint64_t kCellSmallTableLocationMask = (1 << 16) - 1;
+const uint64_t kCellSmallTableIdMask = (1 << 24) - 1;
const int kCellIdOffset = 22;
const int kCellTimestampOffset = 40;
@@ -60,19 +62,19 @@ const int kEvictedEntriesFile = disk_cache::BLOCK_EVICTED - 1;
const int kMaxLocation = 1 << 22;
const int kMinFileNumber = 1 << 16;
-uint32 GetCellLocation(const IndexCell& cell) {
+uint32_t GetCellLocation(const IndexCell& cell) {
return cell.first_part & kCellLocationMask;
}
-uint32 GetCellSmallTableLocation(const IndexCell& cell) {
+uint32_t GetCellSmallTableLocation(const IndexCell& cell) {
return cell.first_part & kCellSmallTableLocationMask;
}
-uint32 GetCellId(const IndexCell& cell) {
+uint32_t GetCellId(const IndexCell& cell) {
return (cell.first_part >> kCellIdOffset) & kCellIdMask;
}
-uint32 GetCellSmallTableId(const IndexCell& cell) {
+uint32_t GetCellSmallTableId(const IndexCell& cell) {
return (cell.first_part >> kCellSmallTableIdOffset) &
kCellSmallTableIdMask;
}
@@ -97,42 +99,42 @@ int GetCellSum(const IndexCell& cell) {
return (cell.last_part >> kCellSumOffset) & kCellSumMask;
}
-void SetCellLocation(IndexCell* cell, uint32 address) {
- DCHECK_LE(address, static_cast<uint32>(kCellLocationMask));
+void SetCellLocation(IndexCell* cell, uint32_t address) {
+ DCHECK_LE(address, static_cast<uint32_t>(kCellLocationMask));
cell->first_part &= ~kCellLocationMask;
cell->first_part |= address;
}
-void SetCellSmallTableLocation(IndexCell* cell, uint32 address) {
- DCHECK_LE(address, static_cast<uint32>(kCellSmallTableLocationMask));
+void SetCellSmallTableLocation(IndexCell* cell, uint32_t address) {
+ DCHECK_LE(address, static_cast<uint32_t>(kCellSmallTableLocationMask));
cell->first_part &= ~kCellSmallTableLocationMask;
cell->first_part |= address;
}
-void SetCellId(IndexCell* cell, uint32 hash) {
- DCHECK_LE(hash, static_cast<uint32>(kCellIdMask));
+void SetCellId(IndexCell* cell, uint32_t hash) {
+ DCHECK_LE(hash, static_cast<uint32_t>(kCellIdMask));
cell->first_part &= ~(kCellIdMask << kCellIdOffset);
- cell->first_part |= static_cast<int64>(hash) << kCellIdOffset;
+ cell->first_part |= static_cast<int64_t>(hash) << kCellIdOffset;
}
-void SetCellSmallTableId(IndexCell* cell, uint32 hash) {
- DCHECK_LE(hash, static_cast<uint32>(kCellSmallTableIdMask));
+void SetCellSmallTableId(IndexCell* cell, uint32_t hash) {
+ DCHECK_LE(hash, static_cast<uint32_t>(kCellSmallTableIdMask));
cell->first_part &= ~(kCellSmallTableIdMask << kCellSmallTableIdOffset);
- cell->first_part |= static_cast<int64>(hash) << kCellSmallTableIdOffset;
+ cell->first_part |= static_cast<int64_t>(hash) << kCellSmallTableIdOffset;
}
void SetCellTimestamp(IndexCell* cell, int timestamp) {
DCHECK_LT(timestamp, 1 << 20);
DCHECK_GE(timestamp, 0);
cell->first_part &= ~(kCellTimestampMask << kCellTimestampOffset);
- cell->first_part |= static_cast<int64>(timestamp) << kCellTimestampOffset;
+ cell->first_part |= static_cast<int64_t>(timestamp) << kCellTimestampOffset;
}
void SetCellReuse(IndexCell* cell, int count) {
DCHECK_LT(count, 16);
DCHECK_GE(count, 0);
cell->first_part &= ~(kCellReuseMask << kCellReuseOffset);
- cell->first_part |= static_cast<int64>(count) << kCellReuseOffset;
+ cell->first_part |= static_cast<int64_t>(count) << kCellReuseOffset;
}
void SetCellState(IndexCell* cell, disk_cache::EntryState state) {
@@ -155,9 +157,9 @@ void SetCellSum(IndexCell* cell, int sum) {
// This is a very particular way to calculate the sum, so it will not match if
// compared a gainst a pure 2 bit, modulo 2 sum.
int CalculateCellSum(const IndexCell& cell) {
- uint32* words = bit_cast<uint32*>(&cell);
- uint8* bytes = bit_cast<uint8*>(&cell);
- uint32 result = words[0] + words[1];
+ uint32_t* words = bit_cast<uint32_t*>(&cell);
+ uint8_t* bytes = bit_cast<uint8_t*>(&cell);
+ uint32_t result = words[0] + words[1];
result += result >> 16;
result += (result >> 8) + (bytes[8] & 0x3f);
result += result >> 4;
@@ -252,7 +254,8 @@ void UpdateIterator(const disk_cache::EntryCell& cell,
void InitIterator(IndexIterator* iterator) {
iterator->cells.clear();
- iterator->timestamp = iterator->forward ? kint32max : 0;
+ iterator->timestamp =
+ iterator->forward ? std::numeric_limits<int32_t>::max() : 0;
}
} // namespace
@@ -271,7 +274,7 @@ bool EntryCell::IsValid() const {
// in the case of small tables. See also the comment by the definition of
// kEntriesFile.
Addr EntryCell::GetAddress() const {
- uint32 location = GetLocation();
+ uint32_t location = GetLocation();
int file_number = FileNumberFromLocation(location);
if (small_table_) {
DCHECK_EQ(0, file_number);
@@ -317,8 +320,8 @@ void EntryCell::SetTimestamp(int timestamp) {
}
// Static.
-EntryCell EntryCell::GetEntryCellForTest(int32 cell_num,
- uint32 hash,
+EntryCell EntryCell::GetEntryCellForTest(int32_t cell_num,
+ uint32_t hash,
Addr address,
IndexCell* cell,
bool small_table) {
@@ -339,13 +342,11 @@ EntryCell::EntryCell() : cell_num_(0), hash_(0), small_table_(false) {
cell_.Clear();
}
-EntryCell::EntryCell(int32 cell_num,
- uint32 hash,
+EntryCell::EntryCell(int32_t cell_num,
+ uint32_t hash,
Addr address,
bool small_table)
- : cell_num_(cell_num),
- hash_(hash),
- small_table_(small_table) {
+ : cell_num_(cell_num), hash_(hash), small_table_(small_table) {
DCHECK(IsValidAddress(address) || !address.value());
cell_.Clear();
@@ -357,34 +358,33 @@ EntryCell::EntryCell(int32 cell_num,
SetCellSmallTableLocation(&cell_, address.start_block());
SetCellSmallTableId(&cell_, hash >> kSmallTableHashShift);
} else {
- uint32 location = address.FileNumber() << 16 | address.start_block();
+ uint32_t location = address.FileNumber() << 16 | address.start_block();
SetCellLocation(&cell_, location);
SetCellId(&cell_, hash >> kHashShift);
}
}
-EntryCell::EntryCell(int32 cell_num,
- uint32 hash,
+EntryCell::EntryCell(int32_t cell_num,
+ uint32_t hash,
const IndexCell& cell,
bool small_table)
: cell_num_(cell_num),
hash_(hash),
cell_(cell),
- small_table_(small_table) {
-}
+ small_table_(small_table) {}
void EntryCell::FixSum() {
SetCellSum(&cell_, CalculateCellSum(cell_));
}
-uint32 EntryCell::GetLocation() const {
+uint32_t EntryCell::GetLocation() const {
if (small_table_)
return GetCellSmallTableLocation(cell_);
return GetCellLocation(cell_);
}
-uint32 EntryCell::RecomputeHash() {
+uint32_t EntryCell::RecomputeHash() {
if (small_table_) {
hash_ &= (1 << kSmallTableHashShift) - 1;
hash_ |= GetCellSmallTableId(cell_) << kSmallTableHashShift;
@@ -512,13 +512,13 @@ void IndexTable::Init(IndexTableInitData* params) {
int old_main_table_bit_words = ((mask_ >> 1) + 1) * kCellsPerBucket / 32;
DCHECK_GT(num_words, old_main_table_bit_words);
memset(params->index_bitmap->bitmap + old_main_table_bit_words, 0,
- (num_words - old_main_table_bit_words) * sizeof(int32));
+ (num_words - old_main_table_bit_words) * sizeof(int32_t));
DCHECK(growing);
int old_num_words = (backup_header_.get()->table_len + 31) / 32;
DCHECK_GT(old_num_words, old_main_table_bit_words);
memset(backup_bitmap_storage_.get() + old_main_table_bit_words, 0,
- (old_num_words - old_main_table_bit_words) * sizeof(int32));
+ (old_num_words - old_main_table_bit_words) * sizeof(int32_t));
}
bitmap_.reset(new Bitmap(params->index_bitmap->bitmap, header_->table_len,
num_words));
@@ -526,11 +526,11 @@ void IndexTable::Init(IndexTableInitData* params) {
if (growing) {
int old_num_words = (backup_header_.get()->table_len + 31) / 32;
DCHECK_GE(num_words, old_num_words);
- scoped_ptr<uint32[]> storage(new uint32[num_words]);
+ scoped_ptr<uint32_t[]> storage(new uint32_t[num_words]);
memcpy(storage.get(), backup_bitmap_storage_.get(),
- old_num_words * sizeof(int32));
+ old_num_words * sizeof(int32_t));
memset(storage.get() + old_num_words, 0,
- (num_words - old_num_words) * sizeof(int32));
+ (num_words - old_num_words) * sizeof(int32_t));
backup_bitmap_storage_.swap(storage);
backup_header_->table_len = header_->table_len;
@@ -574,7 +574,7 @@ void IndexTable::Shutdown() {
//
// One consequence of this pattern is that we never start looking at buckets in
// the extra table, unless we are following a link from the main table.
-EntrySet IndexTable::LookupEntries(uint32 hash) {
+EntrySet IndexTable::LookupEntries(uint32_t hash) {
EntrySet entries;
int bucket_num = static_cast<int>(hash & mask_);
IndexBucket* bucket = &main_table_[bucket_num];
@@ -611,7 +611,7 @@ EntrySet IndexTable::LookupEntries(uint32 hash) {
return entries;
}
-EntryCell IndexTable::CreateEntryCell(uint32 hash, Addr address) {
+EntryCell IndexTable::CreateEntryCell(uint32_t hash, Addr address) {
DCHECK(IsValidAddress(address));
DCHECK(address.FileNumber() || address.start_block());
@@ -665,7 +665,7 @@ EntryCell IndexTable::CreateEntryCell(uint32 hash, Addr address) {
return entry_cell;
}
-EntryCell IndexTable::FindEntryCell(uint32 hash, Addr address) {
+EntryCell IndexTable::FindEntryCell(uint32_t hash, Addr address) {
return FindEntryCellImpl(hash, address, false);
}
@@ -679,7 +679,7 @@ base::Time IndexTable::TimeFromTimestamp(int timestamp) {
TimeDelta::FromMinutes(timestamp);
}
-void IndexTable::SetSate(uint32 hash, Addr address, EntryState state) {
+void IndexTable::SetSate(uint32_t hash, Addr address, EntryState state) {
EntryCell cell = FindEntryCellImpl(hash, address, state == ENTRY_FREE);
if (!cell.IsValid()) {
NOTREACHED();
@@ -727,7 +727,7 @@ void IndexTable::SetSate(uint32 hash, Addr address, EntryState state) {
Save(&cell);
}
-void IndexTable::UpdateTime(uint32 hash, Addr address, base::Time current) {
+void IndexTable::UpdateTime(uint32_t hash, Addr address, base::Time current) {
EntryCell cell = FindEntryCell(hash, address);
if (!cell.IsValid())
return;
@@ -792,7 +792,8 @@ void IndexTable::OnBackupTimer() {
// -----------------------------------------------------------------------
-EntryCell IndexTable::FindEntryCellImpl(uint32 hash, Addr address,
+EntryCell IndexTable::FindEntryCellImpl(uint32_t hash,
+ Addr address,
bool allow_deleted) {
int bucket_num = static_cast<int>(hash & mask_);
IndexBucket* bucket = &main_table_[bucket_num];
@@ -847,7 +848,7 @@ void IndexTable::CheckState(const EntryCell& cell) {
void IndexTable::Write(const EntryCell& cell) {
IndexBucket* bucket = NULL;
int bucket_num = cell.cell_num() / kCellsPerBucket;
- if (bucket_num < static_cast<int32>(mask_ + 1)) {
+ if (bucket_num < static_cast<int32_t>(mask_ + 1)) {
bucket = &main_table_[bucket_num];
} else {
DCHECK_LE(bucket_num, header()->max_bucket);
@@ -888,7 +889,7 @@ void IndexTable::WalkTables(int limit_time,
header_->num_high_use_entries = 0;
header_->num_evicted_entries = 0;
- for (int i = 0; i < static_cast<int32>(mask_ + 1); i++) {
+ for (int i = 0; i < static_cast<int32_t>(mask_ + 1); i++) {
int bucket_num = i;
IndexBucket* bucket = &main_table_[i];
do {
@@ -957,7 +958,7 @@ void IndexTable::MoveCells(IndexBucket* old_extra_table) {
// (h >> 14). If the table is say 8 times the original size (growing from 4x),
// the bit that we are interested in would be the 3rd bit of the stored value,
// in other words 'multiplier' >> 1.
- uint32 new_bit = (1 << extra_bits_) >> 1;
+ uint32_t new_bit = (1 << extra_bits_) >> 1;
scoped_ptr<IndexBucket[]> old_main_table;
IndexBucket* source_table = main_table_;
@@ -1016,7 +1017,7 @@ void IndexTable::MoveCells(IndexBucket* old_extra_table) {
void IndexTable::MoveSingleCell(IndexCell* current_cell, int cell_num,
int main_table_index, bool growing) {
- uint32 hash = GetFullHash(*current_cell, main_table_index);
+ uint32_t hash = GetFullHash(*current_cell, main_table_index);
EntryCell old_cell(cell_num, hash, *current_cell, small_table_);
// This method may be called when moving entries from a small table to a
@@ -1070,7 +1071,7 @@ void IndexTable::HandleMisplacedCell(IndexCell* current_cell, int cell_num,
NOTREACHED(); // No unit tests yet.
// The cell may be misplaced, or a duplicate cell exists with this data.
- uint32 hash = GetFullHash(*current_cell, main_table_index);
+ uint32_t hash = GetFullHash(*current_cell, main_table_index);
MoveSingleCell(current_cell, cell_num, main_table_index, false);
// Now look for a duplicate cell.
@@ -1108,21 +1109,21 @@ void IndexTable::CheckBucketList(int bucket_num) {
} while (bucket_num);
}
-uint32 IndexTable::GetLocation(const IndexCell& cell) {
+uint32_t IndexTable::GetLocation(const IndexCell& cell) {
if (small_table_)
return GetCellSmallTableLocation(cell);
return GetCellLocation(cell);
}
-uint32 IndexTable::GetHashValue(const IndexCell& cell) {
+uint32_t IndexTable::GetHashValue(const IndexCell& cell) {
if (small_table_)
return GetCellSmallTableId(cell);
return GetCellId(cell);
}
-uint32 IndexTable::GetFullHash(const IndexCell& cell, uint32 lower_part) {
+uint32_t IndexTable::GetFullHash(const IndexCell& cell, uint32_t lower_part) {
// It is OK for the high order bits of lower_part to overlap with the stored
// part of the hash.
if (small_table_)
@@ -1132,16 +1133,16 @@ uint32 IndexTable::GetFullHash(const IndexCell& cell, uint32 lower_part) {
}
// All the bits stored in the cell should match the provided hash.
-bool IndexTable::IsHashMatch(const IndexCell& cell, uint32 hash) {
+bool IndexTable::IsHashMatch(const IndexCell& cell, uint32_t hash) {
hash = small_table_ ? hash >> kSmallTableHashShift : hash >> kHashShift;
return GetHashValue(cell) == hash;
}
-bool IndexTable::MisplacedHash(const IndexCell& cell, uint32 hash) {
+bool IndexTable::MisplacedHash(const IndexCell& cell, uint32_t hash) {
if (!extra_bits_)
return false;
- uint32 mask = (1 << extra_bits_) - 1;
+ uint32_t mask = (1 << extra_bits_) - 1;
hash = small_table_ ? hash >> kSmallTableHashShift : hash >> kHashShift;
return (GetHashValue(cell) & mask) != (hash & mask);
}
diff --git a/chromium/net/disk_cache/blockfile/index_table_v3.h b/chromium/net/disk_cache/blockfile/index_table_v3.h
index 598aeecf8a7..78122c85fbd 100644
--- a/chromium/net/disk_cache/blockfile/index_table_v3.h
+++ b/chromium/net/disk_cache/blockfile/index_table_v3.h
@@ -18,9 +18,12 @@
// re-initialized with the new structures. Note that the IndexTable instance is
// still functional while the backend performs file IO.
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
@@ -54,8 +57,8 @@ class NET_EXPORT_PRIVATE EntryCell {
bool IsValid() const;
- int32 cell_num() const { return cell_num_; }
- uint32 hash() const { return hash_; }
+ int32_t cell_num() const { return cell_num_; }
+ uint32_t hash() const { return hash_; }
Addr GetAddress() const;
EntryState GetState() const;
@@ -68,8 +71,8 @@ class NET_EXPORT_PRIVATE EntryCell {
void SetReuse(int count);
void SetTimestamp(int timestamp);
- static EntryCell GetEntryCellForTest(int32 cell_num,
- uint32 hash,
+ static EntryCell GetEntryCellForTest(int32_t cell_num,
+ uint32_t hash,
Addr address,
IndexCell* cell,
bool small_table);
@@ -80,9 +83,9 @@ class NET_EXPORT_PRIVATE EntryCell {
friend class CacheDumperHelper;
EntryCell();
- EntryCell(int32 cell_num, uint32 hash, Addr address, bool small_table);
- EntryCell(int32 cell_num,
- uint32 hash,
+ EntryCell(int32_t cell_num, uint32_t hash, Addr address, bool small_table);
+ EntryCell(int32_t cell_num,
+ uint32_t hash,
const IndexCell& cell,
bool small_table);
@@ -90,16 +93,16 @@ class NET_EXPORT_PRIVATE EntryCell {
void FixSum();
// Returns the raw value stored on the index table.
- uint32 GetLocation() const;
+ uint32_t GetLocation() const;
// Recalculates hash_ assuming that only the low order bits are valid and the
// rest come from cell_.
- uint32 RecomputeHash();
+ uint32_t RecomputeHash();
void Serialize(IndexCell* destination) const;
- int32 cell_num_;
- uint32 hash_;
+ int32_t cell_num_;
+ uint32_t hash_;
IndexCell cell_;
bool small_table_;
};
@@ -116,7 +119,10 @@ struct NET_EXPORT_PRIVATE EntrySet {
// A given entity referenced by the index table is uniquely identified by the
// combination of hash and address.
-struct CellInfo { uint32 hash; Addr address; };
+struct CellInfo {
+ uint32_t hash;
+ Addr address;
+};
typedef std::vector<CellInfo> CellList;
// An index iterator is used to get a group of cells that share the same
@@ -160,7 +166,7 @@ struct NET_EXPORT_PRIVATE IndexTableInitData {
IndexBucket* main_table;
IndexBucket* extra_table;
scoped_ptr<IndexHeaderV3> backup_header;
- scoped_ptr<uint32[]> backup_bitmap;
+ scoped_ptr<uint32_t[]> backup_bitmap;
};
// See the description at the top of this file.
@@ -182,16 +188,16 @@ class NET_EXPORT_PRIVATE IndexTable {
// Locates a resouce on the index. Returns a list of all resources that match
// the provided hash.
- EntrySet LookupEntries(uint32 hash);
+ EntrySet LookupEntries(uint32_t hash);
// Creates a new cell to store a new resource.
- EntryCell CreateEntryCell(uint32 hash, Addr address);
+ EntryCell CreateEntryCell(uint32_t hash, Addr address);
// Locates a particular cell. This method allows a caller to perform slow
// operations with some entries while the index evolves, by returning the
// current state of a cell. If the desired cell cannot be located, the return
// object will be invalid.
- EntryCell FindEntryCell(uint32 hash, Addr address);
+ EntryCell FindEntryCell(uint32_t hash, Addr address);
// Returns an IndexTable timestamp for a given absolute time. The actual
// resolution of the timestamp should be considered an implementation detail,
@@ -203,8 +209,8 @@ class NET_EXPORT_PRIVATE IndexTable {
base::Time TimeFromTimestamp(int timestamp);
// Updates a particular cell.
- void SetSate(uint32 hash, Addr address, EntryState state);
- void UpdateTime(uint32 hash, Addr address, base::Time current);
+ void SetSate(uint32_t hash, Addr address, EntryState state);
+ void UpdateTime(uint32_t hash, Addr address, base::Time current);
// Saves the contents of |cell| to the table.
void Save(EntryCell* cell);
@@ -232,7 +238,7 @@ class NET_EXPORT_PRIVATE IndexTable {
const IndexHeaderV3* header() const { return header_; }
private:
- EntryCell FindEntryCellImpl(uint32 hash, Addr address, bool allow_deleted);
+ EntryCell FindEntryCellImpl(uint32_t hash, Addr address, bool allow_deleted);
void CheckState(const EntryCell& cell);
void Write(const EntryCell& cell);
int NewExtraBucket();
@@ -252,21 +258,21 @@ class NET_EXPORT_PRIVATE IndexTable {
int main_table_index);
void CheckBucketList(int bucket_id);
- uint32 GetLocation(const IndexCell& cell);
- uint32 GetHashValue(const IndexCell& cell);
- uint32 GetFullHash(const IndexCell& cell, uint32 lower_part);
- bool IsHashMatch(const IndexCell& cell, uint32 hash);
- bool MisplacedHash(const IndexCell& cell, uint32 hash);
+ uint32_t GetLocation(const IndexCell& cell);
+ uint32_t GetHashValue(const IndexCell& cell);
+ uint32_t GetFullHash(const IndexCell& cell, uint32_t lower_part);
+ bool IsHashMatch(const IndexCell& cell, uint32_t hash);
+ bool MisplacedHash(const IndexCell& cell, uint32_t hash);
IndexTableBackend* backend_;
IndexHeaderV3* header_;
scoped_ptr<Bitmap> bitmap_;
scoped_ptr<Bitmap> backup_bitmap_;
- scoped_ptr<uint32[]> backup_bitmap_storage_;
+ scoped_ptr<uint32_t[]> backup_bitmap_storage_;
scoped_ptr<IndexHeaderV3> backup_header_;
IndexBucket* main_table_;
IndexBucket* extra_table_;
- uint32 mask_; // Binary mask to map a hash to the hash table.
+ uint32_t mask_; // Binary mask to map a hash to the hash table.
int extra_bits_; // How many bits are in mask_ above the default value.
bool modified_;
bool small_table_;
diff --git a/chromium/net/disk_cache/blockfile/index_table_v3_unittest.cc b/chromium/net/disk_cache/blockfile/index_table_v3_unittest.cc
index 237b983ca61..e2fca1063e4 100644
--- a/chromium/net/disk_cache/blockfile/index_table_v3_unittest.cc
+++ b/chromium/net/disk_cache/blockfile/index_table_v3_unittest.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "net/disk_cache/blockfile/index_table_v3.h"
+
#include <stdint.h>
+#include <utility>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "net/disk_cache/blockfile/addr.h"
#include "net/disk_cache/blockfile/disk_format_v3.h"
-#include "net/disk_cache/blockfile/index_table_v3.h"
#include "testing/gtest/include/gtest/gtest.h"
using disk_cache::EntryCell;
@@ -61,7 +63,7 @@ class TestCacheTables {
base::Time start_time() const { return start_time_; }
private:
- scoped_ptr<uint64[]> main_bitmap_;
+ scoped_ptr<uint64_t[]> main_bitmap_;
scoped_ptr<disk_cache::IndexBucket[]> main_table_;
scoped_ptr<disk_cache::IndexBucket[]> extra_table_;
base::Time start_time_;
@@ -82,7 +84,7 @@ TestCacheTables::TestCacheTables(int num_entries) {
// depend on that.
num_bitmap_bytes_ = (num_entries + num_entries / 2) / 8;
size_t required_size = sizeof(disk_cache::IndexHeaderV3) + num_bitmap_bytes_;
- main_bitmap_.reset(new uint64[required_size / sizeof(uint64)]);
+ main_bitmap_.reset(new uint64_t[required_size / sizeof(uint64_t)]);
memset(main_bitmap_.get(), 0, required_size);
disk_cache::IndexHeaderV3* header =
@@ -113,7 +115,8 @@ void TestCacheTables::GetInitData(IndexTableInitData* result) {
memcpy(result->backup_header.get(), result->index_bitmap,
sizeof(result->index_bitmap->header));
- result->backup_bitmap.reset(new uint32[num_bitmap_bytes_ / sizeof(uint32)]);
+ result->backup_bitmap.reset(
+ new uint32_t[num_bitmap_bytes_ / sizeof(uint32_t)]);
memcpy(result->backup_bitmap.get(), result->index_bitmap->bitmap,
num_bitmap_bytes_);
}
@@ -148,7 +151,7 @@ void TestCacheTables::CopyFrom(const TestCacheTables& other) {
} // namespace
TEST(DiskCacheIndexTable, EntryCell) {
- uint32 hash = 0x55aa6699;
+ uint32_t hash = 0x55aa6699;
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, 0x4531);
bool small_table = true;
int cell_num = 88;
@@ -277,7 +280,7 @@ TEST(DiskCacheIndexTable, Basics) {
disk_cache::CellList entries;
for (int i = 0; i < 250; i++) {
SCOPED_TRACE(i);
- uint32 hash = i * i * 1111 + i * 11;
+ uint32_t hash = i * i * 1111 + i * 11;
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, i * 13 + 1);
EntryCell entry = index.CreateEntryCell(hash, addr);
EXPECT_TRUE(entry.IsValid());
@@ -289,7 +292,7 @@ TEST(DiskCacheIndexTable, Basics) {
// Read them back.
for (size_t i = 0; i < entries.size(); i++) {
SCOPED_TRACE(i);
- uint32 hash = entries[i].hash;
+ uint32_t hash = entries[i].hash;
disk_cache::Addr addr = entries[i].address;
disk_cache::EntrySet found_entries = index.LookupEntries(hash);
@@ -311,7 +314,7 @@ TEST(DiskCacheIndexTable, Basics) {
// See what we have now.
for (size_t i = 0; i < entries.size(); i++) {
SCOPED_TRACE(i);
- uint32 hash = entries[i].hash;
+ uint32_t hash = entries[i].hash;
disk_cache::Addr addr = entries[i].address;
disk_cache::EntrySet found_entries = index.LookupEntries(hash);
@@ -336,7 +339,7 @@ TEST(DiskCacheIndexTable, SameHash) {
index.Init(&init_data);
disk_cache::CellList entries;
- uint32 hash = 0x55aa55bb;
+ uint32_t hash = 0x55aa55bb;
for (int i = 0; i < 6; i++) {
SCOPED_TRACE(i);
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, i * 13 + 1);
@@ -476,7 +479,7 @@ TEST(DiskCacheIndexTable, Iterations) {
disk_cache::CellList entries;
for (int i = 0; i < 44; i++) {
SCOPED_TRACE(i);
- uint32 hash = i; // The entries will be ordered on the table.
+ uint32_t hash = i; // The entries will be ordered on the table.
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, i * 13 + 1);
if (i < 10 || i == 40)
addr = disk_cache::Addr(disk_cache::BLOCK_EVICTED, 1, 6, i * 13 + 1);
@@ -583,7 +586,7 @@ TEST(DiskCacheIndexTable, Doubling) {
// Go from 1024 to 256k cells.
for (int resizes = 0; resizes <= 8; resizes++) {
- scoped_ptr<TestCacheTables> old_cache(cache.Pass());
+ scoped_ptr<TestCacheTables> old_cache(std::move(cache));
cache.reset(new TestCacheTables(size));
cache.get()->CopyFrom(*old_cache.get());
@@ -594,7 +597,7 @@ TEST(DiskCacheIndexTable, Doubling) {
// Write some entries.
for (int i = 0; i < 250; i++, entry_id++) {
SCOPED_TRACE(entry_id);
- uint32 hash = entry_id * i * 321 + entry_id * 13;
+ uint32_t hash = entry_id * i * 321 + entry_id * 13;
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, entry_id * 17 + 1);
EntryCell entry = index.CreateEntryCell(hash, addr);
EXPECT_TRUE(entry.IsValid());
@@ -628,7 +631,7 @@ TEST(DiskCacheIndexTable, BucketChains) {
// Write some entries.
for (int i = 0; i < 8; i++) {
SCOPED_TRACE(i);
- uint32 hash = i * 256;
+ uint32_t hash = i * 256;
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, i * 7 + 1);
EntryCell entry = index.CreateEntryCell(hash, addr);
EXPECT_TRUE(entry.IsValid());
@@ -638,7 +641,7 @@ TEST(DiskCacheIndexTable, BucketChains) {
}
// Double the size.
- scoped_ptr<TestCacheTables> old_cache(cache.Pass());
+ scoped_ptr<TestCacheTables> old_cache(std::move(cache));
cache.reset(new TestCacheTables(size * 2));
cache.get()->CopyFrom(*old_cache.get());
@@ -648,7 +651,7 @@ TEST(DiskCacheIndexTable, BucketChains) {
// Write more entries, starting with the upper half of the table.
for (int i = 9; i < 11; i++) {
SCOPED_TRACE(i);
- uint32 hash = i * 256;
+ uint32_t hash = i * 256;
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, i * 7 + 1);
EntryCell entry = index.CreateEntryCell(hash, addr);
EXPECT_TRUE(entry.IsValid());
@@ -679,7 +682,7 @@ TEST(DiskCacheIndexTable, GrowIndex) {
// Write some entries.
for (int i = 0; i < 512; i++) {
SCOPED_TRACE(i);
- uint32 hash = 0;
+ uint32_t hash = 0;
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, i + 1);
EntryCell entry = index.CreateEntryCell(hash, addr);
EXPECT_TRUE(entry.IsValid());
@@ -697,7 +700,7 @@ TEST(DiskCacheIndexTable, SaveIndex) {
IndexTable index(&backend);
index.Init(&init_data);
- uint32 hash = 0;
+ uint32_t hash = 0;
disk_cache::Addr addr(disk_cache::BLOCK_ENTRIES, 1, 5, 6);
EntryCell entry = index.CreateEntryCell(hash, addr);
EXPECT_TRUE(entry.IsValid());
diff --git a/chromium/net/disk_cache/blockfile/mapped_file.h b/chromium/net/disk_cache/blockfile/mapped_file.h
index 7634cb70f46..7ae0941442b 100644
--- a/chromium/net/disk_cache/blockfile/mapped_file.h
+++ b/chromium/net/disk_cache/blockfile/mapped_file.h
@@ -7,6 +7,9 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_MAPPED_FILE_H_
#define NET_DISK_CACHE_BLOCKFILE_MAPPED_FILE_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/file.h"
#include "net/disk_cache/blockfile/file_block.h"
diff --git a/chromium/net/disk_cache/blockfile/mapped_file_unittest.cc b/chromium/net/disk_cache/blockfile/mapped_file_unittest.cc
index 9b31d6d5457..bd8e913b7ba 100644
--- a/chromium/net/disk_cache/blockfile/mapped_file_unittest.cc
+++ b/chromium/net/disk_cache/blockfile/mapped_file_unittest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/strings/string_util.h"
#include "net/disk_cache/blockfile/file_block.h"
diff --git a/chromium/net/disk_cache/blockfile/rankings.cc b/chromium/net/disk_cache/blockfile/rankings.cc
index 6ea790955c7..387950f3567 100644
--- a/chromium/net/disk_cache/blockfile/rankings.cc
+++ b/chromium/net/disk_cache/blockfile/rankings.cc
@@ -4,6 +4,11 @@
#include "net/disk_cache/blockfile/rankings.h"
+#include <stdint.h>
+
+#include <limits>
+
+#include "base/macros.h"
#include "net/disk_cache/blockfile/backend_impl.h"
#include "net/disk_cache/blockfile/disk_format.h"
#include "net/disk_cache/blockfile/entry_impl.h"
@@ -907,8 +912,8 @@ void Rankings::IncrementCounter(List list) {
if (!count_lists_)
return;
- DCHECK(control_data_->sizes[list] < kint32max);
- if (control_data_->sizes[list] < kint32max)
+ DCHECK(control_data_->sizes[list] < std::numeric_limits<int32_t>::max());
+ if (control_data_->sizes[list] < std::numeric_limits<int32_t>::max())
control_data_->sizes[list]++;
}
diff --git a/chromium/net/disk_cache/blockfile/rankings.h b/chromium/net/disk_cache/blockfile/rankings.h
index b523932498d..637f6a564d6 100644
--- a/chromium/net/disk_cache/blockfile/rankings.h
+++ b/chromium/net/disk_cache/blockfile/rankings.h
@@ -9,6 +9,7 @@
#include <list>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/disk_cache/blockfile/addr.h"
#include "net/disk_cache/blockfile/mapped_file.h"
diff --git a/chromium/net/disk_cache/blockfile/sparse_control.cc b/chromium/net/disk_cache/blockfile/sparse_control.cc
index 08d79a836bf..1de0d60cd11 100644
--- a/chromium/net/disk_cache/blockfile/sparse_control.cc
+++ b/chromium/net/disk_cache/blockfile/sparse_control.cc
@@ -10,6 +10,7 @@
#include "base/format_macros.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -46,8 +47,9 @@ const int kBlockSize = 1024;
// If the entry is called entry_name, child entries will be named something
// like Range_entry_name:XXX:YYY where XXX is the entry signature and YYY is the
// number of the particular child.
-std::string GenerateChildName(const std::string& base_name, int64 signature,
- int64 child_id) {
+std::string GenerateChildName(const std::string& base_name,
+ int64_t signature,
+ int64_t child_id) {
return base::StringPrintf("Range_%s:%" PRIx64 ":%" PRIx64, base_name.c_str(),
signature, child_id);
}
@@ -76,7 +78,7 @@ class ChildrenDeleter
base::WeakPtr<disk_cache::BackendImpl> backend_;
std::string name_;
disk_cache::Bitmap children_map_;
- int64 signature_;
+ int64_t signature_;
scoped_ptr<char[]> buffer_;
DISALLOW_COPY_AND_ASSIGN(ChildrenDeleter);
};
@@ -245,8 +247,11 @@ bool SparseControl::CouldBeSparse() const {
return (entry_->GetDataSize(kSparseIndex) != 0);
}
-int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
- int buf_len, const CompletionCallback& callback) {
+int SparseControl::StartIO(SparseOperation op,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
DCHECK(init_);
// We don't support simultaneous IO for sparse data.
if (operation_ != kNoOperation)
@@ -256,7 +261,7 @@ int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
return net::ERR_INVALID_ARGUMENT;
// We only support up to 64 GB.
- if (static_cast<uint64>(offset) + static_cast<unsigned int>(buf_len) >=
+ if (static_cast<uint64_t>(offset) + static_cast<unsigned int>(buf_len) >=
UINT64_C(0x1000000000)) {
return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
}
@@ -297,7 +302,7 @@ int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
return net::ERR_IO_PENDING;
}
-int SparseControl::GetAvailableRange(int64 offset, int len, int64* start) {
+int SparseControl::GetAvailableRange(int64_t offset, int len, int64_t* start) {
DCHECK(init_);
// We don't support simultaneous IO for sparse data.
if (operation_ != kNoOperation)
@@ -441,7 +446,7 @@ int SparseControl::OpenSparseEntry(int data_len) {
// Grow the bitmap to the current size and copy the bits.
children_map_.Resize(map_len * 8, false);
- children_map_.SetMap(reinterpret_cast<uint32*>(buf->data()), map_len);
+ children_map_.SetMap(reinterpret_cast<uint32_t*>(buf->data()), map_len);
return net::OK;
}
diff --git a/chromium/net/disk_cache/blockfile/sparse_control.h b/chromium/net/disk_cache/blockfile/sparse_control.h
index d3450a3eaec..3edab38d8a0 100644
--- a/chromium/net/disk_cache/blockfile/sparse_control.h
+++ b/chromium/net/disk_cache/blockfile/sparse_control.h
@@ -5,11 +5,13 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_SPARSE_CONTROL_H_
#define NET_DISK_CACHE_BLOCKFILE_SPARSE_CONTROL_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/completion_callback.h"
#include "net/disk_cache/blockfile/bitmap.h"
#include "net/disk_cache/blockfile/disk_format.h"
@@ -59,11 +61,14 @@ class SparseControl {
// to use for asynchronous operations. See the description of the Read /
// WriteSparseData for details about the arguments. The return value is the
// number of bytes read or written, or a net error code.
- int StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
- int buf_len, const CompletionCallback& callback);
+ int StartIO(SparseOperation op,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback);
// Implements Entry::GetAvailableRange().
- int GetAvailableRange(int64 offset, int len, int64* start);
+ int GetAvailableRange(int64_t offset, int len, int64_t* start);
// Cancels the current sparse operation (if any).
void CancelIO();
@@ -162,7 +167,7 @@ class SparseControl {
CompletionCallback user_callback_;
std::vector<CompletionCallback> abort_callbacks_;
- int64 offset_; // Current sparse offset.
+ int64_t offset_; // Current sparse offset.
scoped_refptr<net::DrainableIOBuffer> user_buf_;
int buf_len_; // Bytes to read or write.
int child_offset_; // Offset to use for the current child.
diff --git a/chromium/net/disk_cache/blockfile/sparse_control_v3.cc b/chromium/net/disk_cache/blockfile/sparse_control_v3.cc
index bee23dcce25..82a322122a0 100644
--- a/chromium/net/disk_cache/blockfile/sparse_control_v3.cc
+++ b/chromium/net/disk_cache/blockfile/sparse_control_v3.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/format_macros.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -42,8 +43,9 @@ const int kBlockSize = 1024;
// If the entry is called entry_name, child entries will be named something
// like Range_entry_name:XXX:YYY where XXX is the entry signature and YYY is the
// number of the particular child.
-std::string GenerateChildName(const std::string& base_name, int64 signature,
- int64 child_id) {
+std::string GenerateChildName(const std::string& base_name,
+ int64_t signature,
+ int64_t child_id) {
return base::StringPrintf("Range_%s:%" PRIx64 ":%" PRIx64, base_name.c_str(),
signature, child_id);
}
@@ -72,7 +74,7 @@ class ChildrenDeleter
base::WeakPtr<disk_cache::BackendImpl> backend_;
std::string name_;
disk_cache::Bitmap children_map_;
- int64 signature_;
+ int64_t signature_;
scoped_ptr<char[]> buffer_;
DISALLOW_COPY_AND_ASSIGN(ChildrenDeleter);
};
@@ -222,8 +224,11 @@ bool SparseControl::CouldBeSparse() const {
return (entry_->GetDataSize(kSparseIndex) != 0);
}
-int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
- int buf_len, const CompletionCallback& callback) {
+int SparseControl::StartIO(SparseOperation op,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
DCHECK(init_);
// We don't support simultaneous IO for sparse data.
if (operation_ != kNoOperation)
@@ -272,7 +277,7 @@ int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
return net::ERR_IO_PENDING;
}
-int SparseControl::GetAvailableRange(int64 offset, int len, int64* start) {
+int SparseControl::GetAvailableRange(int64_t offset, int len, int64_t* start) {
DCHECK(init_);
// We don't support simultaneous IO for sparse data.
if (operation_ != kNoOperation)
@@ -439,7 +444,7 @@ int SparseControl::OpenSparseEntry(int data_len) {
// Grow the bitmap to the current size and copy the bits.
children_map_.Resize(map_len * 8, false);
- children_map_.SetMap(reinterpret_cast<uint32*>(buf->data()), map_len);
+ children_map_.SetMap(reinterpret_cast<uint32_t*>(buf->data()), map_len);
return net::OK;
}
diff --git a/chromium/net/disk_cache/blockfile/sparse_control_v3.h b/chromium/net/disk_cache/blockfile/sparse_control_v3.h
index 495ae191612..a6c7d19c1cf 100644
--- a/chromium/net/disk_cache/blockfile/sparse_control_v3.h
+++ b/chromium/net/disk_cache/blockfile/sparse_control_v3.h
@@ -5,11 +5,13 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_SPARSE_CONTROL_V3_H_
#define NET_DISK_CACHE_BLOCKFILE_SPARSE_CONTROL_V3_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/completion_callback.h"
#include "net/disk_cache/blockfile/bitmap.h"
#include "net/disk_cache/disk_format.h"
@@ -54,11 +56,14 @@ class SparseControl {
// to use for asynchronous operations. See the description of the Read /
// WriteSparseData for details about the arguments. The return value is the
// number of bytes read or written, or a net error code.
- int StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
- int buf_len, const CompletionCallback& callback);
+ int StartIO(SparseOperation op,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback);
// Implements Entry::GetAvailableRange().
- int GetAvailableRange(int64 offset, int len, int64* start);
+ int GetAvailableRange(int64_t offset, int len, int64_t* start);
// Cancels the current sparse operation (if any).
void CancelIO();
@@ -160,7 +165,7 @@ class SparseControl {
CompletionCallback user_callback_;
std::vector<CompletionCallback> abort_callbacks_;
- int64 offset_; // Current sparse offset.
+ int64_t offset_; // Current sparse offset.
scoped_refptr<net::DrainableIOBuffer> user_buf_;
int buf_len_; // Bytes to read or write.
int child_offset_; // Offset to use for the current child.
diff --git a/chromium/net/disk_cache/blockfile/stats.cc b/chromium/net/disk_cache/blockfile/stats.cc
index bb319f55b15..a371d287b6a 100644
--- a/chromium/net/disk_cache/blockfile/stats.cc
+++ b/chromium/net/disk_cache/blockfile/stats.cc
@@ -16,18 +16,18 @@
namespace {
-const int32 kDiskSignature = 0xF01427E0;
+const int32_t kDiskSignature = 0xF01427E0;
struct OnDiskStats {
- int32 signature;
+ int32_t signature;
int size;
int data_sizes[disk_cache::Stats::kDataSizesLength];
- int64 counters[disk_cache::Stats::MAX_COUNTER];
+ int64_t counters[disk_cache::Stats::MAX_COUNTER];
};
static_assert(sizeof(OnDiskStats) < 512, "needs more than 2 blocks");
// Returns the "floor" (as opposed to "ceiling") of log base 2 of number.
-int LogBase2(int32 number) {
+int LogBase2(int32_t number) {
unsigned int value = static_cast<unsigned int>(number);
const unsigned int mask[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
const unsigned int s[] = {1, 2, 4, 8, 16};
@@ -169,7 +169,7 @@ int Stats::StorageSize() {
return 256 * 2;
}
-void Stats::ModifyStorageStats(int32 old_size, int32 new_size) {
+void Stats::ModifyStorageStats(int32_t old_size, int32_t new_size) {
// We keep a counter of the data block size on an array where each entry is
// the adjusted log base 2 of the size. The first entry counts blocks of 256
// bytes, the second blocks up to 512 bytes, etc. With 20 entries, the last
@@ -189,12 +189,12 @@ void Stats::OnEvent(Counters an_event) {
counters_[an_event]++;
}
-void Stats::SetCounter(Counters counter, int64 value) {
+void Stats::SetCounter(Counters counter, int64_t value) {
DCHECK(counter >= MIN_COUNTER && counter < MAX_COUNTER);
counters_[counter] = value;
}
-int64 Stats::GetCounter(Counters counter) const {
+int64_t Stats::GetCounter(Counters counter) const {
DCHECK(counter >= MIN_COUNTER && counter < MAX_COUNTER);
return counters_[counter];
}
@@ -295,7 +295,7 @@ int Stats::GetBucketRange(size_t i) const {
// 25 [16M, 32M)
// 26 [32M, 64M)
// 27 [64M, ...)
-int Stats::GetStatsBucket(int32 size) {
+int Stats::GetStatsBucket(int32_t size) {
if (size < 1024)
return 0;
@@ -318,7 +318,7 @@ int Stats::GetStatsBucket(int32 size) {
}
int Stats::GetRatio(Counters hit, Counters miss) const {
- int64 ratio = GetCounter(hit) * 100;
+ int64_t ratio = GetCounter(hit) * 100;
if (!ratio)
return 0;
diff --git a/chromium/net/disk_cache/blockfile/stats.h b/chromium/net/disk_cache/blockfile/stats.h
index 32dcc2f22b5..34b54c6ef53 100644
--- a/chromium/net/disk_cache/blockfile/stats.h
+++ b/chromium/net/disk_cache/blockfile/stats.h
@@ -5,9 +5,12 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_STATS_H_
#define NET_DISK_CACHE_BLOCKFILE_STATS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_split.h"
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/addr.h"
@@ -64,12 +67,12 @@ class NET_EXPORT_PRIVATE Stats {
int StorageSize();
// Tracks changes to the stoage space used by an entry.
- void ModifyStorageStats(int32 old_size, int32 new_size);
+ void ModifyStorageStats(int32_t old_size, int32_t new_size);
// Tracks general events.
void OnEvent(Counters an_event);
- void SetCounter(Counters counter, int64 value);
- int64 GetCounter(Counters counter) const;
+ void SetCounter(Counters counter, int64_t value);
+ int64_t GetCounter(Counters counter) const;
void GetItems(StatsItems* items);
int GetHitRatio() const;
@@ -86,12 +89,12 @@ class NET_EXPORT_PRIVATE Stats {
private:
// Supports generation of SizeStats histogram data.
int GetBucketRange(size_t i) const;
- int GetStatsBucket(int32 size);
+ int GetStatsBucket(int32_t size);
int GetRatio(Counters hit, Counters miss) const;
Addr storage_addr_;
int data_sizes_[kDataSizesLength];
- int64 counters_[MAX_COUNTER];
+ int64_t counters_[MAX_COUNTER];
DISALLOW_COPY_AND_ASSIGN(Stats);
};
diff --git a/chromium/net/disk_cache/blockfile/storage_block-inl.h b/chromium/net/disk_cache/blockfile/storage_block-inl.h
index f919c128c40..3d880bb9938 100644
--- a/chromium/net/disk_cache/blockfile/storage_block-inl.h
+++ b/chromium/net/disk_cache/blockfile/storage_block-inl.h
@@ -7,6 +7,9 @@
#include "net/disk_cache/blockfile/storage_block.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/hash.h"
#include "base/logging.h"
#include "net/disk_cache/blockfile/trace.h"
@@ -103,7 +106,7 @@ template<typename T> bool StorageBlock<T>::HasData() const {
}
template<typename T> bool StorageBlock<T>::VerifyHash() const {
- uint32 hash = CalculateHash();
+ uint32_t hash = CalculateHash();
return (!data_->self_hash || data_->self_hash == hash);
}
@@ -196,7 +199,8 @@ template<typename T> void StorageBlock<T>::DeleteData() {
}
}
-template<typename T> uint32 StorageBlock<T>::CalculateHash() const {
+template <typename T>
+uint32_t StorageBlock<T>::CalculateHash() const {
return base::Hash(reinterpret_cast<char*>(data_), offsetof(T, self_hash));
}
diff --git a/chromium/net/disk_cache/blockfile/storage_block.h b/chromium/net/disk_cache/blockfile/storage_block.h
index 6db4a3101de..62e5349deb2 100644
--- a/chromium/net/disk_cache/blockfile/storage_block.h
+++ b/chromium/net/disk_cache/blockfile/storage_block.h
@@ -7,6 +7,10 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_H_
#define NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/disk_cache/blockfile/addr.h"
#include "net/disk_cache/blockfile/mapped_file.h"
@@ -80,7 +84,7 @@ class StorageBlock : public FileBlock {
private:
void AllocateData();
void DeleteData();
- uint32 CalculateHash() const;
+ uint32_t CalculateHash() const;
T* data_;
MappedFile* file_;
diff --git a/chromium/net/disk_cache/blockfile/trace.h b/chromium/net/disk_cache/blockfile/trace.h
index 6805e6c60c2..1c30dacb0fd 100644
--- a/chromium/net/disk_cache/blockfile/trace.h
+++ b/chromium/net/disk_cache/blockfile/trace.h
@@ -9,7 +9,7 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_TRACE_H_
#define NET_DISK_CACHE_BLOCKFILE_TRACE_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/disk_cache/cache_creator.cc b/chromium/net/disk_cache/cache_creator.cc
index 25bde280f4b..54338c1fb08 100644
--- a/chromium/net/disk_cache/cache_creator.cc
+++ b/chromium/net/disk_cache/cache_creator.cc
@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
@@ -26,7 +29,7 @@ class CacheCreator {
int max_bytes,
net::CacheType type,
net::BackendType backend_type,
- uint32 flags,
+ uint32_t flags,
const scoped_refptr<base::SingleThreadTaskRunner>& thread,
net::NetLog* net_log,
scoped_ptr<disk_cache::Backend>* backend,
@@ -48,7 +51,7 @@ class CacheCreator {
int max_bytes_;
net::CacheType type_;
net::BackendType backend_type_;
- uint32 flags_;
+ uint32_t flags_;
scoped_refptr<base::SingleThreadTaskRunner> thread_;
scoped_ptr<disk_cache::Backend>* backend_;
net::CompletionCallback callback_;
@@ -64,7 +67,7 @@ CacheCreator::CacheCreator(
int max_bytes,
net::CacheType type,
net::BackendType backend_type,
- uint32 flags,
+ uint32_t flags,
const scoped_refptr<base::SingleThreadTaskRunner>& thread,
net::NetLog* net_log,
scoped_ptr<disk_cache::Backend>* backend,
@@ -79,8 +82,7 @@ CacheCreator::CacheCreator(
thread_(thread),
backend_(backend),
callback_(callback),
- net_log_(net_log) {
-}
+ net_log_(net_log) {}
CacheCreator::~CacheCreator() {
}
@@ -122,7 +124,7 @@ int CacheCreator::Run() {
void CacheCreator::DoCallback(int result) {
DCHECK_NE(net::ERR_IO_PENDING, result);
if (result == net::OK) {
- *backend_ = created_cache_.Pass();
+ *backend_ = std::move(created_cache_);
} else {
LOG(ERROR) << "Unable to create cache";
created_cache_.reset();
diff --git a/chromium/net/disk_cache/cache_util.cc b/chromium/net/disk_cache/cache_util.cc
index 167113860d6..51ec95b492c 100644
--- a/chromium/net/disk_cache/cache_util.cc
+++ b/chromium/net/disk_cache/cache_util.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/cache_util.h"
+#include <limits>
+
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/location.h"
@@ -49,7 +51,7 @@ base::FilePath GetTempCacheName(const base::FilePath& path,
return base::FilePath();
}
-int64 PreferredCacheSizeInternal(int64 available) {
+int64_t PreferredCacheSizeInternal(int64_t available) {
using disk_cache::kDefaultCacheSize;
// Return 80% of the available space if there is not enough space to use
// kDefaultCacheSize.
@@ -62,12 +64,12 @@ int64 PreferredCacheSizeInternal(int64 available) {
// Return 10% of the available space if the target size
// (2.5 * kDefaultCacheSize) is more than 10%.
- if (available < static_cast<int64>(kDefaultCacheSize) * 25)
+ if (available < static_cast<int64_t>(kDefaultCacheSize) * 25)
return available / 10;
// Return the target size (2.5 * kDefaultCacheSize) if it uses 10% to 1%
// of the available space.
- if (available < static_cast<int64>(kDefaultCacheSize) * 250)
+ if (available < static_cast<int64_t>(kDefaultCacheSize) * 250)
return kDefaultCacheSize * 5 / 2;
// Return 1% of the available space.
@@ -141,16 +143,16 @@ bool DelayedCacheCleanup(const base::FilePath& full_path) {
// Returns the preferred maximum number of bytes for the cache given the
// number of available bytes.
-int PreferredCacheSize(int64 available) {
+int PreferredCacheSize(int64_t available) {
if (available < 0)
return kDefaultCacheSize;
// Limit cache size to somewhat less than kint32max to avoid potential
// integer overflows in cache backend implementations.
- DCHECK_LT(kDefaultCacheSize * 4, kint32max);
- return static_cast<int32>(std::min(
- PreferredCacheSizeInternal(available),
- static_cast<int64>(kDefaultCacheSize * 4)));
+ DCHECK_LT(kDefaultCacheSize * 4, std::numeric_limits<int32_t>::max());
+ return static_cast<int32_t>(
+ std::min(PreferredCacheSizeInternal(available),
+ static_cast<int64_t>(kDefaultCacheSize * 4)));
}
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/cache_util.h b/chromium/net/disk_cache/cache_util.h
index c4baa2d6110..25940124277 100644
--- a/chromium/net/disk_cache/cache_util.h
+++ b/chromium/net/disk_cache/cache_util.h
@@ -5,7 +5,8 @@
#ifndef NET_DISK_CACHE_CACHE_UTIL_H_
#define NET_DISK_CACHE_CACHE_UTIL_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "net/base/net_export.h"
#include "net/disk_cache/disk_cache.h"
@@ -37,7 +38,7 @@ NET_EXPORT_PRIVATE bool DeleteCacheFile(const base::FilePath& name);
bool DelayedCacheCleanup(const base::FilePath& full_path);
// Returns the preferred max cache size given the available disk space.
-NET_EXPORT_PRIVATE int PreferredCacheSize(int64 available);
+NET_EXPORT_PRIVATE int PreferredCacheSize(int64_t available);
// The default cache size should not ideally be exposed, but the blockfile
// backend uses it for reasons that include testing.
diff --git a/chromium/net/disk_cache/disk_cache.h b/chromium/net/disk_cache/disk_cache.h
index 84c1ee99516..5f99c325058 100644
--- a/chromium/net/disk_cache/disk_cache.h
+++ b/chromium/net/disk_cache/disk_cache.h
@@ -8,10 +8,11 @@
#ifndef NET_DISK_CACHE_DISK_CACHE_H_
#define NET_DISK_CACHE_DISK_CACHE_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_split.h"
@@ -98,7 +99,7 @@ class NET_EXPORT Backend {
virtual net::CacheType GetCacheType() const = 0;
// Returns the number of entries in the cache.
- virtual int32 GetEntryCount() const = 0;
+ virtual int32_t GetEntryCount() const = 0;
// Opens an existing entry. Upon success, |entry| holds a pointer to an Entry
// object representing the specified disk cache entry. When the entry pointer
@@ -145,6 +146,12 @@ class NET_EXPORT Backend {
virtual int DoomEntriesSince(base::Time initial_time,
const CompletionCallback& callback) = 0;
+ // Calculate the total size of the cache. The return value is the size in
+ // bytes or a net error code. If this method returns ERR_IO_PENDING,
+ // the |callback| will be invoked when the operation completes.
+ virtual int CalculateSizeOfAllEntries(
+ const CompletionCallback& callback) = 0;
+
// Returns an iterator which will enumerate all entries of the cache in an
// undefined order.
virtual scoped_ptr<Iterator> CreateIterator() = 0;
@@ -181,7 +188,7 @@ class NET_EXPORT Entry {
virtual base::Time GetLastModified() const = 0;
// Returns the size of the cache data with the given index.
- virtual int32 GetDataSize(int index) const = 0;
+ virtual int32_t GetDataSize(int index) const = 0;
// Copies cached data into the given buffer of length |buf_len|. Returns the
// number of bytes read or a network error code. If this function returns
@@ -254,7 +261,9 @@ class NET_EXPORT Entry {
// Behaves like ReadData() except that this method is used to access sparse
// entries.
- virtual int ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
+ virtual int ReadSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) = 0;
// Behaves like WriteData() except that this method is used to access sparse
@@ -263,7 +272,9 @@ class NET_EXPORT Entry {
// start again, or to reduce the total size of the stream data (which implies
// that the content has changed), the whole entry should be doomed and
// re-created.
- virtual int WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
+ virtual int WriteSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) = 0;
// Returns information about the currently stored portion of a sparse entry.
@@ -275,7 +286,9 @@ class NET_EXPORT Entry {
// net error code whenever the request cannot be completed successfully. If
// this method returns ERR_IO_PENDING, the |callback| will be invoked when the
// operation completes, and |start| must remain valid until that point.
- virtual int GetAvailableRange(int64 offset, int len, int64* start,
+ virtual int GetAvailableRange(int64_t offset,
+ int len,
+ int64_t* start,
const CompletionCallback& callback) = 0;
// Returns true if this entry could be a sparse entry or false otherwise. This
diff --git a/chromium/net/disk_cache/disk_cache_test_base.cc b/chromium/net/disk_cache/disk_cache_test_base.cc
index 2e9bd7f1abf..d3a21257325 100644
--- a/chromium/net/disk_cache/disk_cache_test_base.cc
+++ b/chromium/net/disk_cache/disk_cache_test_base.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/disk_cache_test_base.h"
+#include <utility>
+
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
@@ -54,8 +56,7 @@ void DiskCacheTest::TearDown() {
DiskCacheTestWithCache::TestIterator::TestIterator(
scoped_ptr<disk_cache::Backend::Iterator> iterator)
- : iterator_(iterator.Pass()) {
-}
+ : iterator_(std::move(iterator)) {}
DiskCacheTestWithCache::TestIterator::~TestIterator() {}
@@ -167,6 +168,12 @@ int DiskCacheTestWithCache::DoomEntriesSince(const base::Time initial_time) {
return cb.GetResult(rv);
}
+int DiskCacheTestWithCache::CalculateSizeOfAllEntries() {
+ net::TestCompletionCallback cb;
+ int rv = cache_->CalculateSizeOfAllEntries(cb.callback());
+ return cb.GetResult(rv);
+}
+
scoped_ptr<DiskCacheTestWithCache::TestIterator>
DiskCacheTestWithCache::CreateIterator() {
return scoped_ptr<TestIterator>(new TestIterator(cache_->CreateIterator()));
@@ -208,7 +215,8 @@ int DiskCacheTestWithCache::WriteData(disk_cache::Entry* entry, int index,
}
int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry* entry,
- int64 offset, net::IOBuffer* buf,
+ int64_t offset,
+ net::IOBuffer* buf,
int len) {
net::TestCompletionCallback cb;
int rv = entry->ReadSparseData(offset, buf, len, cb.callback());
@@ -216,8 +224,9 @@ int DiskCacheTestWithCache::ReadSparseData(disk_cache::Entry* entry,
}
int DiskCacheTestWithCache::WriteSparseData(disk_cache::Entry* entry,
- int64 offset,
- net::IOBuffer* buf, int len) {
+ int64_t offset,
+ net::IOBuffer* buf,
+ int len) {
net::TestCompletionCallback cb;
int rv = entry->WriteSparseData(offset, buf, len, cb.callback());
return cb.GetResult(rv);
@@ -293,7 +302,8 @@ void DiskCacheTestWithCache::InitDiskCache() {
CreateBackend(disk_cache::kNoRandom, &cache_thread_);
}
-void DiskCacheTestWithCache::CreateBackend(uint32 flags, base::Thread* thread) {
+void DiskCacheTestWithCache::CreateBackend(uint32_t flags,
+ base::Thread* thread) {
scoped_refptr<base::SingleThreadTaskRunner> runner;
if (use_current_thread_)
runner = base::ThreadTaskRunnerHandle::Get();
@@ -308,7 +318,7 @@ void DiskCacheTestWithCache::CreateBackend(uint32 flags, base::Thread* thread) {
int rv = simple_backend->Init(cb.callback());
ASSERT_EQ(net::OK, cb.GetResult(rv));
simple_cache_impl_ = simple_backend.get();
- cache_ = simple_backend.Pass();
+ cache_ = std::move(simple_backend);
if (simple_cache_wait_for_index_) {
net::TestCompletionCallback wait_for_index_cb;
rv = simple_cache_impl_->index()->ExecuteWhenReady(
diff --git a/chromium/net/disk_cache/disk_cache_test_base.h b/chromium/net/disk_cache/disk_cache_test_base.h
index ef136f4429f..713bba0e6a2 100644
--- a/chromium/net/disk_cache/disk_cache_test_base.h
+++ b/chromium/net/disk_cache/disk_cache_test_base.h
@@ -5,9 +5,11 @@
#ifndef NET_DISK_CACHE_DISK_CACHE_TEST_BASE_H_
#define NET_DISK_CACHE_DISK_CACHE_TEST_BASE_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread.h"
#include "net/base/cache_type.h"
@@ -72,7 +74,7 @@ class DiskCacheTestWithCache : public DiskCacheTest {
DiskCacheTestWithCache();
~DiskCacheTestWithCache() override;
- void CreateBackend(uint32 flags, base::Thread* thread);
+ void CreateBackend(uint32_t flags, base::Thread* thread);
void InitCache();
void SimulateCrash();
@@ -86,9 +88,7 @@ class DiskCacheTestWithCache : public DiskCacheTest {
simple_cache_mode_ = true;
}
- void SetMask(uint32 mask) {
- mask_ = mask;
- }
+ void SetMask(uint32_t mask) { mask_ = mask; }
void SetMaxSize(int size);
@@ -128,6 +128,7 @@ class DiskCacheTestWithCache : public DiskCacheTest {
int DoomAllEntries();
int DoomEntriesBetween(const base::Time initial_time,
const base::Time end_time);
+ int CalculateSizeOfAllEntries();
int DoomEntriesSince(const base::Time initial_time);
scoped_ptr<TestIterator> CreateIterator();
void FlushQueueForTest();
@@ -136,10 +137,14 @@ class DiskCacheTestWithCache : public DiskCacheTest {
net::IOBuffer* buf, int len);
int WriteData(disk_cache::Entry* entry, int index, int offset,
net::IOBuffer* buf, int len, bool truncate);
- int ReadSparseData(disk_cache::Entry* entry, int64 offset, net::IOBuffer* buf,
+ int ReadSparseData(disk_cache::Entry* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
int len);
- int WriteSparseData(disk_cache::Entry* entry, int64 offset,
- net::IOBuffer* buf, int len);
+ int WriteSparseData(disk_cache::Entry* entry,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int len);
// Asks the cache to trim an entry. If |empty| is true, the whole cache is
// deleted.
@@ -163,7 +168,7 @@ class DiskCacheTestWithCache : public DiskCacheTest {
disk_cache::SimpleBackendImpl* simple_cache_impl_;
disk_cache::MemBackendImpl* mem_cache_;
- uint32 mask_;
+ uint32_t mask_;
int size_;
net::CacheType type_;
bool memory_only_;
diff --git a/chromium/net/disk_cache/disk_cache_test_util.cc b/chromium/net/disk_cache/disk_cache_test_util.cc
index 69738d34dbb..0a2a27ecc8b 100644
--- a/chromium/net/disk_cache/disk_cache_test_util.cc
+++ b/chromium/net/disk_cache/disk_cache_test_util.cc
@@ -58,8 +58,9 @@ bool DeleteCache(const base::FilePath& path) {
return true;
}
-bool CheckCacheIntegrity(const base::FilePath& path, bool new_eviction,
- uint32 mask) {
+bool CheckCacheIntegrity(const base::FilePath& path,
+ bool new_eviction,
+ uint32_t mask) {
scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
path, mask, base::ThreadTaskRunnerHandle::Get(), NULL));
if (!cache.get())
@@ -105,7 +106,7 @@ void MessageLoopHelper::TimerExpired() {
CHECK_LE(callbacks_called_, num_callbacks_);
if (callbacks_called_ == num_callbacks_) {
completed_ = true;
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
} else {
// Not finished yet. See if we have to abort.
if (last_ == callbacks_called_)
@@ -113,7 +114,7 @@ void MessageLoopHelper::TimerExpired() {
else
last_ = callbacks_called_;
if (40 == num_iterations_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
}
diff --git a/chromium/net/disk_cache/disk_cache_test_util.h b/chromium/net/disk_cache/disk_cache_test_util.h
index 7191874348b..1dc348b55ae 100644
--- a/chromium/net/disk_cache/disk_cache_test_util.h
+++ b/chromium/net/disk_cache/disk_cache_test_util.h
@@ -5,9 +5,13 @@
#ifndef NET_DISK_CACHE_DISK_CACHE_TEST_UTIL_H_
#define NET_DISK_CACHE_DISK_CACHE_TEST_UTIL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
@@ -25,8 +29,9 @@ void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls);
std::string GenerateKey(bool same_length);
// Returns true if the cache is not corrupt.
-bool CheckCacheIntegrity(const base::FilePath& path, bool new_eviction,
- uint32 mask);
+bool CheckCacheIntegrity(const base::FilePath& path,
+ bool new_eviction,
+ uint32_t mask);
// -----------------------------------------------------------------------
diff --git a/chromium/net/disk_cache/entry_unittest.cc b/chromium/net/disk_cache/entry_unittest.cc
index 639cf87d320..ea5804930e4 100644
--- a/chromium/net/disk_cache/entry_unittest.cc
+++ b/chromium/net/disk_cache/entry_unittest.cc
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/platform_thread.h"
@@ -1638,8 +1640,11 @@ TEST_F(DiskCacheEntryTest, MemoryOnlyEnumerationWithSparseEntries) {
}
// Writes |buf_1| to offset and reads it back as |buf_2|.
-void VerifySparseIO(disk_cache::Entry* entry, int64 offset,
- net::IOBuffer* buf_1, int size, net::IOBuffer* buf_2) {
+void VerifySparseIO(disk_cache::Entry* entry,
+ int64_t offset,
+ net::IOBuffer* buf_1,
+ int size,
+ net::IOBuffer* buf_2) {
net::TestCompletionCallback cb;
memset(buf_2->data(), 0, size);
@@ -1657,7 +1662,9 @@ void VerifySparseIO(disk_cache::Entry* entry, int64 offset,
// Reads |size| bytes from |entry| at |offset| and verifies that they are the
// same as the content of the provided |buffer|.
-void VerifyContentSparseIO(disk_cache::Entry* entry, int64 offset, char* buffer,
+void VerifyContentSparseIO(disk_cache::Entry* entry,
+ int64_t offset,
+ char* buffer,
int size) {
net::TestCompletionCallback cb;
@@ -1754,7 +1761,7 @@ void DiskCacheEntryTest::GetAvailableRange() {
EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F4400, buf.get(), kSize));
// We stop at the first empty block.
- int64 start;
+ int64_t start;
net::TestCompletionCallback cb;
int rv = entry->GetAvailableRange(
0x20F0000, kSize * 2, &start, cb.callback());
@@ -1833,7 +1840,7 @@ TEST_F(DiskCacheEntryTest, SparseWriteDropped) {
int offset = 1024 - 500;
int rv = 0;
net::TestCompletionCallback cb;
- int64 start;
+ int64_t start;
for (int i = 0; i < 5; i++) {
// Check result of last GetAvailableRange.
EXPECT_EQ(0, rv);
@@ -1887,8 +1894,8 @@ TEST_F(DiskCacheEntryTest, SparseSquentialWriteNotDropped) {
// Any starting offset is fine as long as it is 1024-bytes aligned.
int rv = 0;
net::TestCompletionCallback cb;
- int64 start;
- int64 offset = 1024 * 11;
+ int64_t start;
+ int64_t offset = 1024 * 11;
for (; offset < 20000; offset += kSize) {
rv = entry->WriteSparseData(offset, buf_1.get(), kSize, cb.callback());
EXPECT_EQ(kSize, cb.GetResult(rv));
@@ -2025,7 +2032,7 @@ TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedGetAvailableRange) {
entry->WriteSparseData(
50000, buf.get(), 8192, net::CompletionCallback()));
- int64 start;
+ int64_t start;
net::TestCompletionCallback cb;
// Test that we stop at a discontinuous child at the second block.
int rv = entry->GetAvailableRange(0, 10000, &start, cb.callback());
@@ -2117,7 +2124,7 @@ void DiskCacheEntryTest::DoomSparseEntry() {
scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
CacheTestFillBuffer(buf->data(), kSize, false);
- int64 offset = 1024;
+ int64_t offset = 1024;
// Write to a bunch of ranges.
for (int i = 0; i < 12; i++) {
EXPECT_EQ(kSize, WriteSparseData(entry1, offset, buf.get(), kSize));
@@ -2179,8 +2186,7 @@ TEST_F(DiskCacheEntryTest, MemoryOnlyDoomSparseEntry) {
class SparseTestCompletionCallback: public net::TestCompletionCallback {
public:
explicit SparseTestCompletionCallback(scoped_ptr<disk_cache::Backend> cache)
- : cache_(cache.Pass()) {
- }
+ : cache_(std::move(cache)) {}
private:
void SetResult(int result) override {
@@ -2205,7 +2211,7 @@ TEST_F(DiskCacheEntryTest, DoomSparseEntry2) {
scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize));
CacheTestFillBuffer(buf->data(), kSize, false);
- int64 offset = 1024;
+ int64_t offset = 1024;
// Write to a bunch of ranges.
for (int i = 0; i < 12; i++) {
EXPECT_EQ(kSize,
@@ -2217,7 +2223,7 @@ TEST_F(DiskCacheEntryTest, DoomSparseEntry2) {
entry->Close();
disk_cache::Backend* cache = cache_.get();
- SparseTestCompletionCallback cb(cache_.Pass());
+ SparseTestCompletionCallback cb(std::move(cache_));
int rv = cache->DoomEntry(key, cb.callback());
EXPECT_EQ(net::ERR_IO_PENDING, rv);
EXPECT_EQ(net::OK, cb.WaitForResult());
@@ -2263,7 +2269,7 @@ void DiskCacheEntryTest::PartialSparseEntry() {
EXPECT_EQ(0, ReadSparseData(entry, 99, buf2.get(), kSize));
int rv;
- int64 start;
+ int64_t start;
net::TestCompletionCallback cb;
if (memory_only_ || simple_cache_mode_) {
rv = entry->GetAvailableRange(0, 600, &start, cb.callback());
@@ -2395,7 +2401,7 @@ TEST_F(DiskCacheEntryTest, CancelSparseIO) {
1024 * 1024 - 4096, buf.get(), kSize, cb1.callback());
EXPECT_EQ(net::ERR_IO_PENDING, rv);
- int64 offset = 0;
+ int64_t offset = 0;
rv = entry->GetAvailableRange(offset, kSize, &offset, cb5.callback());
rv = cb5.GetResult(rv);
if (!cb1.have_result()) {
@@ -2637,7 +2643,7 @@ bool DiskCacheEntryTest::SimpleCacheMakeBadChecksumEntry(const std::string& key,
if (!entry_file0.IsValid())
return false;
- int64 file_offset =
+ int64_t file_offset =
sizeof(disk_cache::SimpleFileHeader) + key.size() + kDataSize - 2;
EXPECT_EQ(1, entry_file0.Write(file_offset, "X", 1));
*data_size = kDataSize;
@@ -2690,7 +2696,7 @@ TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) {
entry->Doom(); // Should not crash.
}
-bool TruncatePath(const base::FilePath& file_path, int64 length) {
+bool TruncatePath(const base::FilePath& file_path, int64_t length) {
base::File file(file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN);
if (!file.IsValid())
return false;
@@ -2721,7 +2727,7 @@ TEST_F(DiskCacheEntryTest, SimpleCacheNoEOF) {
int kTruncationBytes = -static_cast<int>(sizeof(disk_cache::SimpleFileEOF));
const base::FilePath entry_path = cache_path_.AppendASCII(
disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
- const int64 invalid_size =
+ const int64_t invalid_size =
disk_cache::simple_util::GetFileSizeFromKeyAndDataSize(key,
kTruncationBytes);
EXPECT_TRUE(TruncatePath(entry_path, invalid_size));
@@ -4145,5 +4151,16 @@ TEST_F(DiskCacheEntryTest, SimpleCacheTruncateLargeSparseFile) {
ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
EXPECT_EQ(0, callback.GetResult(ret));
+ // Close and reopen the entry and make sure the first entry is still absent
+ // and the second entry is still present.
+ entry->Close();
+ ASSERT_EQ(net::OK, OpenEntry(key, &entry));
+
+ ret = entry->ReadSparseData(0, buffer.get(), kSize, callback.callback());
+ EXPECT_EQ(0, callback.GetResult(ret));
+
+ ret = entry->ReadSparseData(kSize, buffer.get(), kSize, callback.callback());
+ EXPECT_EQ(kSize, callback.GetResult(ret));
+
entry->Close();
}
diff --git a/chromium/net/disk_cache/memory/mem_backend_impl.cc b/chromium/net/disk_cache/memory/mem_backend_impl.cc
index 8350963c6e3..5b37ca92bfc 100644
--- a/chromium/net/disk_cache/memory/mem_backend_impl.cc
+++ b/chromium/net/disk_cache/memory/mem_backend_impl.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/memory/mem_backend_impl.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/sys_info.h"
#include "net/base/net_errors.h"
@@ -47,7 +49,7 @@ scoped_ptr<Backend> MemBackendImpl::CreateBackend(int max_bytes,
scoped_ptr<MemBackendImpl> cache(new MemBackendImpl(net_log));
cache->SetMaxSize(max_bytes);
if (cache->Init())
- return cache.Pass();
+ return std::move(cache);
LOG(ERROR) << "Unable to create cache";
return nullptr;
@@ -57,7 +59,7 @@ bool MemBackendImpl::Init() {
if (max_size_)
return true;
- int64 total_memory = base::SysInfo::AmountOfPhysicalMemory();
+ int64_t total_memory = base::SysInfo::AmountOfPhysicalMemory();
if (total_memory <= 0) {
max_size_ = kDefaultInMemoryCacheSize;
@@ -70,7 +72,7 @@ bool MemBackendImpl::Init() {
if (total_memory > kDefaultInMemoryCacheSize * 5)
max_size_ = kDefaultInMemoryCacheSize * 5;
else
- max_size_ = static_cast<int32>(total_memory);
+ max_size_ = static_cast<int32_t>(total_memory);
return true;
}
@@ -107,7 +109,7 @@ void MemBackendImpl::UpdateRank(MemEntryImpl* node) {
rankings_.UpdateRank(node);
}
-void MemBackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) {
+void MemBackendImpl::ModifyStorageSize(int32_t old_size, int32_t new_size) {
if (old_size >= new_size)
SubstractStorageSize(old_size - new_size);
else
@@ -130,8 +132,8 @@ net::CacheType MemBackendImpl::GetCacheType() const {
return net::MEMORY_CACHE;
}
-int32 MemBackendImpl::GetEntryCount() const {
- return static_cast<int32>(entries_.size());
+int32_t MemBackendImpl::GetEntryCount() const {
+ return static_cast<int32_t>(entries_.size());
}
int MemBackendImpl::OpenEntry(const std::string& key, Entry** entry,
@@ -182,6 +184,11 @@ int MemBackendImpl::DoomEntriesSince(const base::Time initial_time,
return net::ERR_FAILED;
}
+int MemBackendImpl::CalculateSizeOfAllEntries(
+ const CompletionCallback& callback) {
+ return current_size_;
+}
+
class MemBackendImpl::MemIterator : public Backend::Iterator {
public:
explicit MemIterator(base::WeakPtr<MemBackendImpl> backend)
@@ -330,7 +337,7 @@ void MemBackendImpl::TrimCache(bool empty) {
return;
}
-void MemBackendImpl::AddStorageSize(int32 bytes) {
+void MemBackendImpl::AddStorageSize(int32_t bytes) {
current_size_ += bytes;
DCHECK_GE(current_size_, 0);
@@ -338,7 +345,7 @@ void MemBackendImpl::AddStorageSize(int32 bytes) {
TrimCache(false);
}
-void MemBackendImpl::SubstractStorageSize(int32 bytes) {
+void MemBackendImpl::SubstractStorageSize(int32_t bytes) {
current_size_ -= bytes;
DCHECK_GE(current_size_, 0);
}
diff --git a/chromium/net/disk_cache/memory/mem_backend_impl.h b/chromium/net/disk_cache/memory/mem_backend_impl.h
index 6be8e946797..e2a9f1afda6 100644
--- a/chromium/net/disk_cache/memory/mem_backend_impl.h
+++ b/chromium/net/disk_cache/memory/mem_backend_impl.h
@@ -7,8 +7,11 @@
#ifndef NET_DISK_CACHE_MEMORY_MEM_BACKEND_IMPL_H_
#define NET_DISK_CACHE_MEMORY_MEM_BACKEND_IMPL_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_split.h"
#include "net/disk_cache/disk_cache.h"
@@ -49,7 +52,7 @@ class NET_EXPORT_PRIVATE MemBackendImpl : public Backend {
void UpdateRank(MemEntryImpl* node);
// A user data block is being created, extended or truncated.
- void ModifyStorageSize(int32 old_size, int32 new_size);
+ void ModifyStorageSize(int32_t old_size, int32_t new_size);
// Returns the maximum size for a file to reside on the cache.
int MaxFileSize() const;
@@ -65,7 +68,7 @@ class NET_EXPORT_PRIVATE MemBackendImpl : public Backend {
// Backend interface.
net::CacheType GetCacheType() const override;
- int32 GetEntryCount() const override;
+ int32_t GetEntryCount() const override;
int OpenEntry(const std::string& key,
Entry** entry,
const CompletionCallback& callback) override;
@@ -80,6 +83,7 @@ class NET_EXPORT_PRIVATE MemBackendImpl : public Backend {
const CompletionCallback& callback) override;
int DoomEntriesSince(base::Time initial_time,
const CompletionCallback& callback) override;
+ int CalculateSizeOfAllEntries(const CompletionCallback& callback) override;
scoped_ptr<Iterator> CreateIterator() override;
void GetStats(base::StringPairs* stats) override {}
void OnExternalCacheHit(const std::string& key) override;
@@ -105,13 +109,13 @@ class NET_EXPORT_PRIVATE MemBackendImpl : public Backend {
void TrimCache(bool empty);
// Handles the used storage count.
- void AddStorageSize(int32 bytes);
- void SubstractStorageSize(int32 bytes);
+ void AddStorageSize(int32_t bytes);
+ void SubstractStorageSize(int32_t bytes);
EntryMap entries_;
MemRankings rankings_; // Rankings to be able to trim the cache.
- int32 max_size_; // Maximum data size for this instance.
- int32 current_size_;
+ int32_t max_size_; // Maximum data size for this instance.
+ int32_t current_size_;
net::NetLog* net_log_;
diff --git a/chromium/net/disk_cache/memory/mem_entry_impl.cc b/chromium/net/disk_cache/memory/mem_entry_impl.cc
index daa3980144c..692551866a6 100644
--- a/chromium/net/disk_cache/memory/mem_entry_impl.cc
+++ b/chromium/net/disk_cache/memory/mem_entry_impl.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/memory/mem_entry_impl.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
@@ -26,12 +28,12 @@ const int kMaxSparseEntryBits = 12;
const int kMaxSparseEntrySize = 1 << kMaxSparseEntryBits;
// Convert global offset to child index.
-inline int ToChildIndex(int64 offset) {
+inline int ToChildIndex(int64_t offset) {
return static_cast<int>(offset >> kMaxSparseEntryBits);
}
// Convert global offset to offset in child entry.
-inline int ToChildOffset(int64 offset) {
+inline int ToChildOffset(int64_t offset) {
return static_cast<int>(offset & (kMaxSparseEntrySize - 1));
}
@@ -52,7 +54,7 @@ scoped_ptr<base::Value> NetLogChildEntryCreationCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("key", GenerateChildName(parent->GetKey(), child_id));
dict->SetBoolean("created", true);
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
@@ -88,7 +90,7 @@ bool MemEntryImpl::CreateEntry(const std::string& key, net::NetLog* net_log) {
CreateNetLogEntryCreationCallback(this, true));
Open();
- backend_->ModifyStorageSize(0, static_cast<int32>(key.size()));
+ backend_->ModifyStorageSize(0, static_cast<int32_t>(key.size()));
return true;
}
@@ -177,7 +179,7 @@ Time MemEntryImpl::GetLastModified() const {
return last_modified_;
}
-int32 MemEntryImpl::GetDataSize(int index) const {
+int32_t MemEntryImpl::GetDataSize(int index) const {
if (index < 0 || index >= NUM_STREAMS)
return 0;
return data_size_[index];
@@ -219,7 +221,9 @@ int MemEntryImpl::WriteData(int index, int offset, IOBuffer* buf, int buf_len,
return result;
}
-int MemEntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int MemEntryImpl::ReadSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
if (net_log_.IsCapturing()) {
net_log_.BeginEvent(
@@ -232,7 +236,9 @@ int MemEntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
return result;
}
-int MemEntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
+int MemEntryImpl::WriteSparseData(int64_t offset,
+ IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
if (net_log_.IsCapturing()) {
net_log_.BeginEvent(
@@ -245,7 +251,9 @@ int MemEntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
return result;
}
-int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start,
+int MemEntryImpl::GetAvailableRange(int64_t offset,
+ int len,
+ int64_t* start,
const CompletionCallback& callback) {
if (net_log_.IsCapturing()) {
net_log_.BeginEvent(
@@ -275,7 +283,7 @@ int MemEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) {
MemEntryImpl::~MemEntryImpl() {
for (int i = 0; i < NUM_STREAMS; i++)
backend_->ModifyStorageSize(data_size_[i], 0);
- backend_->ModifyStorageSize(static_cast<int32>(key_.size()), 0);
+ backend_->ModifyStorageSize(static_cast<int32_t>(key_.size()), 0);
net_log_.EndEvent(net::NetLog::TYPE_DISK_CACHE_MEM_ENTRY_IMPL);
}
@@ -344,7 +352,8 @@ int MemEntryImpl::InternalWriteData(int index, int offset, IOBuffer* buf,
return buf_len;
}
-int MemEntryImpl::InternalReadSparseData(int64 offset, IOBuffer* buf,
+int MemEntryImpl::InternalReadSparseData(int64_t offset,
+ IOBuffer* buf,
int buf_len) {
DCHECK(type() == kParentEntry);
@@ -401,7 +410,8 @@ int MemEntryImpl::InternalReadSparseData(int64 offset, IOBuffer* buf,
return io_buf->BytesConsumed();
}
-int MemEntryImpl::InternalWriteSparseData(int64 offset, IOBuffer* buf,
+int MemEntryImpl::InternalWriteSparseData(int64_t offset,
+ IOBuffer* buf,
int buf_len) {
DCHECK(type() == kParentEntry);
@@ -467,7 +477,7 @@ int MemEntryImpl::InternalWriteSparseData(int64 offset, IOBuffer* buf,
return io_buf->BytesConsumed();
}
-int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start) {
+int MemEntryImpl::GetAvailableRange(int64_t offset, int len, int64_t* start) {
DCHECK(type() == kParentEntry);
DCHECK(start);
@@ -577,7 +587,7 @@ bool MemEntryImpl::InitChildEntry(MemEntryImpl* parent, int child_id,
return true;
}
-MemEntryImpl* MemEntryImpl::OpenChild(int64 offset, bool create) {
+MemEntryImpl* MemEntryImpl::OpenChild(int64_t offset, bool create) {
DCHECK(type() == kParentEntry);
int index = ToChildIndex(offset);
EntryMap::iterator i = children_->find(index);
@@ -592,7 +602,7 @@ MemEntryImpl* MemEntryImpl::OpenChild(int64 offset, bool create) {
return NULL;
}
-int MemEntryImpl::FindNextChild(int64 offset, int len, MemEntryImpl** child) {
+int MemEntryImpl::FindNextChild(int64_t offset, int len, MemEntryImpl** child) {
DCHECK(child);
*child = NULL;
int scanned_len = 0;
diff --git a/chromium/net/disk_cache/memory/mem_entry_impl.h b/chromium/net/disk_cache/memory/mem_entry_impl.h
index c550b977176..52a1696f63c 100644
--- a/chromium/net/disk_cache/memory/mem_entry_impl.h
+++ b/chromium/net/disk_cache/memory/mem_entry_impl.h
@@ -5,7 +5,10 @@
#ifndef NET_DISK_CACHE_MEMORY_MEM_ENTRY_IMPL_H_
#define NET_DISK_CACHE_MEMORY_MEM_ENTRY_IMPL_H_
+#include <stdint.h>
+
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/disk_cache/disk_cache.h"
#include "net/log/net_log.h"
@@ -91,7 +94,7 @@ class MemEntryImpl : public Entry {
std::string GetKey() const override;
base::Time GetLastUsed() const override;
base::Time GetLastModified() const override;
- int32 GetDataSize(int index) const override;
+ int32_t GetDataSize(int index) const override;
int ReadData(int index,
int offset,
IOBuffer* buf,
@@ -103,17 +106,17 @@ class MemEntryImpl : public Entry {
int buf_len,
const CompletionCallback& callback,
bool truncate) override;
- int ReadSparseData(int64 offset,
+ int ReadSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int WriteSparseData(int64 offset,
+ int WriteSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int GetAvailableRange(int64 offset,
+ int GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) override;
bool CouldBeSparse() const override;
void CancelSparseIO() override {}
@@ -133,11 +136,11 @@ class MemEntryImpl : public Entry {
int InternalReadData(int index, int offset, IOBuffer* buf, int buf_len);
int InternalWriteData(int index, int offset, IOBuffer* buf, int buf_len,
bool truncate);
- int InternalReadSparseData(int64 offset, IOBuffer* buf, int buf_len);
- int InternalWriteSparseData(int64 offset, IOBuffer* buf, int buf_len);
+ int InternalReadSparseData(int64_t offset, IOBuffer* buf, int buf_len);
+ int InternalWriteSparseData(int64_t offset, IOBuffer* buf, int buf_len);
// Old Entry interface.
- int GetAvailableRange(int64 offset, int len, int64* start);
+ int GetAvailableRange(int64_t offset, int len, int64_t* start);
// Grows and cleans up the data buffer.
void PrepareTarget(int index, int offset, int buf_len);
@@ -158,19 +161,19 @@ class MemEntryImpl : public Entry {
// child entry or this entry itself if |offset| points to the first range.
// If such entry does not exist and |create| is true, a new child entry is
// created.
- MemEntryImpl* OpenChild(int64 offset, bool create);
+ MemEntryImpl* OpenChild(int64_t offset, bool create);
// Finds the first child located within the range [|offset|, |offset + len|).
// Returns the number of bytes ahead of |offset| to reach the first available
// bytes in the entry. The first child found is output to |child|.
- int FindNextChild(int64 offset, int len, MemEntryImpl** child);
+ int FindNextChild(int64_t offset, int len, MemEntryImpl** child);
// Removes child indexed by |child_id| from the children map.
void DetachChild(int child_id);
std::string key_;
std::vector<char> data_[NUM_STREAMS]; // User data.
- int32 data_size_[NUM_STREAMS];
+ int32_t data_size_[NUM_STREAMS];
int ref_count_;
int child_id_; // The ID of a child entry.
diff --git a/chromium/net/disk_cache/memory/mem_rankings.h b/chromium/net/disk_cache/memory/mem_rankings.h
index b75bfc14fb9..d660cabd83f 100644
--- a/chromium/net/disk_cache/memory/mem_rankings.h
+++ b/chromium/net/disk_cache/memory/mem_rankings.h
@@ -7,7 +7,7 @@
#ifndef NET_DISK_CACHE_MEMORY_MEM_RANKINGS_H_
#define NET_DISK_CACHE_MEMORY_MEM_RANKINGS_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
namespace disk_cache {
diff --git a/chromium/net/disk_cache/net_log_parameters.cc b/chromium/net/disk_cache/net_log_parameters.cc
index 8234ced0155..842ce25e638 100644
--- a/chromium/net/disk_cache/net_log_parameters.cc
+++ b/chromium/net/disk_cache/net_log_parameters.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/net_log_parameters.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
@@ -20,7 +22,7 @@ scoped_ptr<base::Value> NetLogEntryCreationCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("key", entry->GetKey());
dict->SetBoolean("created", created);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogReadWriteDataCallback(
@@ -35,7 +37,7 @@ scoped_ptr<base::Value> NetLogReadWriteDataCallback(
dict->SetInteger("buf_len", buf_len);
if (truncate)
dict->SetBoolean("truncate", truncate);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogReadWriteCompleteCallback(
@@ -48,19 +50,19 @@ scoped_ptr<base::Value> NetLogReadWriteCompleteCallback(
} else {
dict->SetInteger("bytes_copied", bytes_copied);
}
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSparseOperationCallback(
- int64 offset,
- int buff_len,
+ int64_t offset,
+ int buf_len,
net::NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
// Values can only be created with at most 32-bit integers. Using a string
// instead circumvents that restriction.
dict->SetString("offset", base::Int64ToString(offset));
- dict->SetInteger("buff_len", buff_len);
- return dict.Pass();
+ dict->SetInteger("buf_len", buf_len);
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSparseReadWriteCallback(
@@ -70,11 +72,11 @@ scoped_ptr<base::Value> NetLogSparseReadWriteCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
source.AddToEventParameters(dict.get());
dict->SetInteger("child_len", child_len);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogGetAvailableRangeResultCallback(
- int64 start,
+ int64_t start,
int result,
net::NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -84,7 +86,7 @@ scoped_ptr<base::Value> NetLogGetAvailableRangeResultCallback(
} else {
dict->SetInteger("net_error", result);
}
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
@@ -113,9 +115,9 @@ net::NetLog::ParametersCallback CreateNetLogReadWriteCompleteCallback(
}
net::NetLog::ParametersCallback CreateNetLogSparseOperationCallback(
- int64 offset,
- int buff_len) {
- return base::Bind(&NetLogSparseOperationCallback, offset, buff_len);
+ int64_t offset,
+ int buf_len) {
+ return base::Bind(&NetLogSparseOperationCallback, offset, buf_len);
}
net::NetLog::ParametersCallback CreateNetLogSparseReadWriteCallback(
@@ -125,7 +127,7 @@ net::NetLog::ParametersCallback CreateNetLogSparseReadWriteCallback(
}
net::NetLog::ParametersCallback CreateNetLogGetAvailableRangeResultCallback(
- int64 start,
+ int64_t start,
int result) {
return base::Bind(&NetLogGetAvailableRangeResultCallback, start, result);
}
diff --git a/chromium/net/disk_cache/net_log_parameters.h b/chromium/net/disk_cache/net_log_parameters.h
index 6e144201c8e..2bbed1232d5 100644
--- a/chromium/net/disk_cache/net_log_parameters.h
+++ b/chromium/net/disk_cache/net_log_parameters.h
@@ -5,6 +5,8 @@
#ifndef NET_DISK_CACHE_NET_LOG_PARAMETERS_H_
#define NET_DISK_CACHE_NET_LOG_PARAMETERS_H_
+#include <stdint.h>
+
#include <string>
#include "net/log/net_log.h"
@@ -42,8 +44,8 @@ net::NetLog::ParametersCallback CreateNetLogReadWriteCompleteCallback(
// Creates a NetLog callback that returns parameters for when a sparse
// operation is started.
net::NetLog::ParametersCallback CreateNetLogSparseOperationCallback(
- int64 offset,
- int buff_len);
+ int64_t offset,
+ int buf_len);
// Creates a NetLog callback that returns parameters for when a read or write
// for a sparse entry's child is started.
@@ -54,7 +56,7 @@ net::NetLog::ParametersCallback CreateNetLogSparseReadWriteCallback(
// Creates a NetLog callback that returns parameters for when a call to
// GetAvailableRange returns.
net::NetLog::ParametersCallback CreateNetLogGetAvailableRangeResultCallback(
- int64 start,
+ int64_t start,
int result);
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/simple/simple_backend_impl.cc b/chromium/net/disk_cache/simple/simple_backend_impl.cc
index 5d1730f883f..9f410ed4677 100644
--- a/chromium/net/disk_cache/simple/simple_backend_impl.cc
+++ b/chromium/net/disk_cache/simple/simple_backend_impl.cc
@@ -17,6 +17,7 @@
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
@@ -209,20 +210,18 @@ class SimpleBackendImpl::ActiveEntryProxy
}
static scoped_ptr<SimpleEntryImpl::ActiveEntryProxy> Create(
- int64 entry_hash,
+ int64_t entry_hash,
SimpleBackendImpl* backend) {
scoped_ptr<SimpleEntryImpl::ActiveEntryProxy>
proxy(new ActiveEntryProxy(entry_hash, backend));
- return proxy.Pass();
+ return proxy;
}
private:
- ActiveEntryProxy(uint64 entry_hash,
- SimpleBackendImpl* backend)
- : entry_hash_(entry_hash),
- backend_(backend->AsWeakPtr()) {}
+ ActiveEntryProxy(uint64_t entry_hash, SimpleBackendImpl* backend)
+ : entry_hash_(entry_hash), backend_(backend->AsWeakPtr()) {}
- uint64 entry_hash_;
+ uint64_t entry_hash_;
base::WeakPtr<SimpleBackendImpl> backend_;
};
@@ -282,15 +281,15 @@ int SimpleBackendImpl::GetMaxFileSize() const {
return static_cast<int>(index_->max_size() / kMaxFileRatio);
}
-void SimpleBackendImpl::OnDoomStart(uint64 entry_hash) {
+void SimpleBackendImpl::OnDoomStart(uint64_t entry_hash) {
DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash));
entries_pending_doom_.insert(
std::make_pair(entry_hash, std::vector<Closure>()));
}
-void SimpleBackendImpl::OnDoomComplete(uint64 entry_hash) {
+void SimpleBackendImpl::OnDoomComplete(uint64_t entry_hash) {
DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash));
- base::hash_map<uint64, std::vector<Closure> >::iterator it =
+ base::hash_map<uint64_t, std::vector<Closure>>::iterator it =
entries_pending_doom_.find(entry_hash);
std::vector<Closure> to_run_closures;
to_run_closures.swap(it->second);
@@ -300,13 +299,13 @@ void SimpleBackendImpl::OnDoomComplete(uint64 entry_hash) {
std::mem_fun_ref(&Closure::Run));
}
-void SimpleBackendImpl::DoomEntries(std::vector<uint64>* entry_hashes,
+void SimpleBackendImpl::DoomEntries(std::vector<uint64_t>* entry_hashes,
const net::CompletionCallback& callback) {
- scoped_ptr<std::vector<uint64> >
- mass_doom_entry_hashes(new std::vector<uint64>());
+ scoped_ptr<std::vector<uint64_t>> mass_doom_entry_hashes(
+ new std::vector<uint64_t>());
mass_doom_entry_hashes->swap(*entry_hashes);
- std::vector<uint64> to_doom_individually_hashes;
+ std::vector<uint64_t> to_doom_individually_hashes;
// For each of the entry hashes, there are two cases:
// 1. The entry is either open or pending doom, and so it should be doomed
@@ -314,7 +313,7 @@ void SimpleBackendImpl::DoomEntries(std::vector<uint64>* entry_hashes,
// 2. The entry is not in use at all, so we can call
// SimpleSynchronousEntry::DoomEntrySet and delete the files en masse.
for (int i = mass_doom_entry_hashes->size() - 1; i >= 0; --i) {
- const uint64 entry_hash = (*mass_doom_entry_hashes)[i];
+ const uint64_t entry_hash = (*mass_doom_entry_hashes)[i];
DCHECK(active_entries_.count(entry_hash) == 0 ||
entries_pending_doom_.count(entry_hash) == 0);
if (!active_entries_.count(entry_hash) &&
@@ -331,16 +330,18 @@ void SimpleBackendImpl::DoomEntries(std::vector<uint64>* entry_hashes,
net::CompletionCallback barrier_callback =
MakeBarrierCompletionCallback(to_doom_individually_hashes.size() + 1,
callback);
- for (std::vector<uint64>::const_iterator
+ for (std::vector<uint64_t>::const_iterator
it = to_doom_individually_hashes.begin(),
- end = to_doom_individually_hashes.end(); it != end; ++it) {
+ end = to_doom_individually_hashes.end();
+ it != end; ++it) {
const int doom_result = DoomEntryFromHash(*it, barrier_callback);
DCHECK_EQ(net::ERR_IO_PENDING, doom_result);
index_->Remove(*it);
}
- for (std::vector<uint64>::const_iterator it = mass_doom_entry_hashes->begin(),
- end = mass_doom_entry_hashes->end();
+ for (std::vector<uint64_t>::const_iterator
+ it = mass_doom_entry_hashes->begin(),
+ end = mass_doom_entry_hashes->end();
it != end; ++it) {
index_->Remove(*it);
OnDoomStart(*it);
@@ -348,7 +349,7 @@ void SimpleBackendImpl::DoomEntries(std::vector<uint64>* entry_hashes,
// Taking this pointer here avoids undefined behaviour from calling
// base::Passed before mass_doom_entry_hashes.get().
- std::vector<uint64>* mass_doom_entry_hashes_ptr =
+ std::vector<uint64_t>* mass_doom_entry_hashes_ptr =
mass_doom_entry_hashes.get();
PostTaskAndReplyWithResult(worker_pool_.get(),
FROM_HERE,
@@ -365,7 +366,7 @@ net::CacheType SimpleBackendImpl::GetCacheType() const {
return net::DISK_CACHE;
}
-int32 SimpleBackendImpl::GetEntryCount() const {
+int32_t SimpleBackendImpl::GetEntryCount() const {
// TODO(pasko): Use directory file count when index is not ready.
return index_->GetEntryCount();
}
@@ -373,11 +374,11 @@ int32 SimpleBackendImpl::GetEntryCount() const {
int SimpleBackendImpl::OpenEntry(const std::string& key,
Entry** entry,
const CompletionCallback& callback) {
- const uint64 entry_hash = simple_util::GetEntryHashKey(key);
+ const uint64_t entry_hash = simple_util::GetEntryHashKey(key);
// TODO(gavinp): Factor out this (not quite completely) repetitive code
// block from OpenEntry/CreateEntry/DoomEntry.
- base::hash_map<uint64, std::vector<Closure> >::iterator it =
+ base::hash_map<uint64_t, std::vector<Closure>>::iterator it =
entries_pending_doom_.find(entry_hash);
if (it != entries_pending_doom_.end()) {
Callback<int(const net::CompletionCallback&)> operation =
@@ -403,9 +404,9 @@ int SimpleBackendImpl::CreateEntry(const std::string& key,
Entry** entry,
const CompletionCallback& callback) {
DCHECK_LT(0u, key.size());
- const uint64 entry_hash = simple_util::GetEntryHashKey(key);
+ const uint64_t entry_hash = simple_util::GetEntryHashKey(key);
- base::hash_map<uint64, std::vector<Closure> >::iterator it =
+ base::hash_map<uint64_t, std::vector<Closure>>::iterator it =
entries_pending_doom_.find(entry_hash);
if (it != entries_pending_doom_.end()) {
Callback<int(const net::CompletionCallback&)> operation =
@@ -422,9 +423,9 @@ int SimpleBackendImpl::CreateEntry(const std::string& key,
int SimpleBackendImpl::DoomEntry(const std::string& key,
const net::CompletionCallback& callback) {
- const uint64 entry_hash = simple_util::GetEntryHashKey(key);
+ const uint64_t entry_hash = simple_util::GetEntryHashKey(key);
- base::hash_map<uint64, std::vector<Closure> >::iterator it =
+ base::hash_map<uint64_t, std::vector<Closure>>::iterator it =
entries_pending_doom_.find(entry_hash);
if (it != entries_pending_doom_.end()) {
Callback<int(const net::CompletionCallback&)> operation =
@@ -442,19 +443,6 @@ int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) {
return DoomEntriesBetween(Time(), Time(), callback);
}
-void SimpleBackendImpl::IndexReadyForDoom(Time initial_time,
- Time end_time,
- const CompletionCallback& callback,
- int result) {
- if (result != net::OK) {
- callback.Run(result);
- return;
- }
- scoped_ptr<std::vector<uint64> > removed_key_hashes(
- index_->GetEntriesBetween(initial_time, end_time).release());
- DoomEntries(removed_key_hashes.get(), callback);
-}
-
int SimpleBackendImpl::DoomEntriesBetween(
const Time initial_time,
const Time end_time,
@@ -470,6 +458,12 @@ int SimpleBackendImpl::DoomEntriesSince(
return DoomEntriesBetween(initial_time, Time(), callback);
}
+int SimpleBackendImpl::CalculateSizeOfAllEntries(
+ const CompletionCallback& callback) {
+ return index_->ExecuteWhenReady(base::Bind(
+ &SimpleBackendImpl::IndexReadyForSizeCalculation, AsWeakPtr(), callback));
+}
+
class SimpleBackendImpl::SimpleIterator final : public Iterator {
public:
explicit SimpleIterator(base::WeakPtr<SimpleBackendImpl> backend)
@@ -498,10 +492,10 @@ class SimpleBackendImpl::SimpleIterator final : public Iterator {
return;
}
if (!hashes_to_enumerate_)
- hashes_to_enumerate_ = backend_->index()->GetAllHashes().Pass();
+ hashes_to_enumerate_ = backend_->index()->GetAllHashes();
while (!hashes_to_enumerate_->empty()) {
- uint64 entry_hash = hashes_to_enumerate_->back();
+ uint64_t entry_hash = hashes_to_enumerate_->back();
hashes_to_enumerate_->pop_back();
if (backend_->index()->Has(entry_hash)) {
*next_entry = NULL;
@@ -536,7 +530,7 @@ class SimpleBackendImpl::SimpleIterator final : public Iterator {
private:
base::WeakPtr<SimpleBackendImpl> backend_;
- scoped_ptr<std::vector<uint64> > hashes_to_enumerate_;
+ scoped_ptr<std::vector<uint64_t>> hashes_to_enumerate_;
base::WeakPtrFactory<SimpleIterator> weak_factory_;
};
@@ -564,9 +558,30 @@ void SimpleBackendImpl::InitializeIndex(const CompletionCallback& callback,
callback.Run(result.net_error);
}
+void SimpleBackendImpl::IndexReadyForDoom(Time initial_time,
+ Time end_time,
+ const CompletionCallback& callback,
+ int result) {
+ if (result != net::OK) {
+ callback.Run(result);
+ return;
+ }
+ scoped_ptr<std::vector<uint64_t>> removed_key_hashes(
+ index_->GetEntriesBetween(initial_time, end_time).release());
+ DoomEntries(removed_key_hashes.get(), callback);
+}
+
+void SimpleBackendImpl::IndexReadyForSizeCalculation(
+ const CompletionCallback& callback,
+ int result) {
+ if (result == net::OK)
+ result = static_cast<int>(index_->GetCacheSize());
+ callback.Run(result);
+}
+
SimpleBackendImpl::DiskStatResult SimpleBackendImpl::InitCacheStructureOnDisk(
const base::FilePath& path,
- uint64 suggested_max_size) {
+ uint64_t suggested_max_size) {
DiskStatResult result;
result.max_size = suggested_max_size;
result.net_error = net::OK;
@@ -579,7 +594,7 @@ SimpleBackendImpl::DiskStatResult SimpleBackendImpl::InitCacheStructureOnDisk(
disk_cache::simple_util::GetMTime(path, &result.cache_dir_mtime);
DCHECK(mtime_result);
if (!result.max_size) {
- int64 available = base::SysInfo::AmountOfFreeDiskSpace(path);
+ int64_t available = base::SysInfo::AmountOfFreeDiskSpace(path);
result.max_size = disk_cache::PreferredCacheSize(available);
}
DCHECK(result.max_size);
@@ -588,7 +603,7 @@ SimpleBackendImpl::DiskStatResult SimpleBackendImpl::InitCacheStructureOnDisk(
}
scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry(
- const uint64 entry_hash,
+ const uint64_t entry_hash,
const std::string& key) {
DCHECK_EQ(entry_hash, simple_util::GetEntryHashKey(key));
std::pair<EntryMap::iterator, bool> insert_result =
@@ -613,10 +628,10 @@ scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry(
return make_scoped_refptr(it->second);
}
-int SimpleBackendImpl::OpenEntryFromHash(uint64 entry_hash,
+int SimpleBackendImpl::OpenEntryFromHash(uint64_t entry_hash,
Entry** entry,
const CompletionCallback& callback) {
- base::hash_map<uint64, std::vector<Closure> >::iterator it =
+ base::hash_map<uint64_t, std::vector<Closure>>::iterator it =
entries_pending_doom_.find(entry_hash);
if (it != entries_pending_doom_.end()) {
Callback<int(const net::CompletionCallback&)> operation =
@@ -640,12 +655,12 @@ int SimpleBackendImpl::OpenEntryFromHash(uint64 entry_hash,
return simple_entry->OpenEntry(entry, backend_callback);
}
-int SimpleBackendImpl::DoomEntryFromHash(uint64 entry_hash,
+int SimpleBackendImpl::DoomEntryFromHash(uint64_t entry_hash,
const CompletionCallback& callback) {
Entry** entry = new Entry*();
scoped_ptr<Entry*> scoped_entry(entry);
- base::hash_map<uint64, std::vector<Closure> >::iterator pending_it =
+ base::hash_map<uint64_t, std::vector<Closure>>::iterator pending_it =
entries_pending_doom_.find(entry_hash);
if (pending_it != entries_pending_doom_.end()) {
Callback<int(const net::CompletionCallback&)> operation =
@@ -662,14 +677,14 @@ int SimpleBackendImpl::DoomEntryFromHash(uint64 entry_hash,
// There's no pending dooms, nor any open entry. We can make a trivial
// call to DoomEntries() to delete this entry.
- std::vector<uint64> entry_hash_vector;
+ std::vector<uint64_t> entry_hash_vector;
entry_hash_vector.push_back(entry_hash);
DoomEntries(&entry_hash_vector, callback);
return net::ERR_IO_PENDING;
}
void SimpleBackendImpl::OnEntryOpenedFromHash(
- uint64 hash,
+ uint64_t hash,
Entry** entry,
const scoped_refptr<SimpleEntryImpl>& simple_entry,
const CompletionCallback& callback,
@@ -722,13 +737,11 @@ void SimpleBackendImpl::OnEntryOpenedFromKey(
}
void SimpleBackendImpl::DoomEntriesComplete(
- scoped_ptr<std::vector<uint64> > entry_hashes,
+ scoped_ptr<std::vector<uint64_t>> entry_hashes,
const net::CompletionCallback& callback,
int result) {
- std::for_each(
- entry_hashes->begin(), entry_hashes->end(),
- std::bind1st(std::mem_fun(&SimpleBackendImpl::OnDoomComplete),
- this));
+ for (const uint64_t& entry_hash : *entry_hashes)
+ OnDoomComplete(entry_hash);
callback.Run(result);
}
diff --git a/chromium/net/disk_cache/simple/simple_backend_impl.h b/chromium/net/disk_cache/simple/simple_backend_impl.h
index 7993fdcd853..6db40163761 100644
--- a/chromium/net/disk_cache/simple/simple_backend_impl.h
+++ b/chromium/net/disk_cache/simple/simple_backend_impl.h
@@ -5,6 +5,8 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
+#include <stdint.h>
+
#include <string>
#include <utility>
#include <vector>
@@ -77,20 +79,20 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
// The entry for |entry_hash| is being doomed; the backend will not attempt
// run new operations for this |entry_hash| until the Doom is completed.
- void OnDoomStart(uint64 entry_hash);
+ void OnDoomStart(uint64_t entry_hash);
// The entry for |entry_hash| has been successfully doomed, we can now allow
// operations on this entry, and we can run any operations enqueued while the
// doom completed.
- void OnDoomComplete(uint64 entry_hash);
+ void OnDoomComplete(uint64_t entry_hash);
// SimpleIndexDelegate:
- void DoomEntries(std::vector<uint64>* entry_hashes,
+ void DoomEntries(std::vector<uint64_t>* entry_hashes,
const CompletionCallback& callback) override;
// Backend:
net::CacheType GetCacheType() const override;
- int32 GetEntryCount() const override;
+ int32_t GetEntryCount() const override;
int OpenEntry(const std::string& key,
Entry** entry,
const CompletionCallback& callback) override;
@@ -105,6 +107,7 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
const CompletionCallback& callback) override;
int DoomEntriesSince(base::Time initial_time,
const CompletionCallback& callback) override;
+ int CalculateSizeOfAllEntries(const CompletionCallback& callback) override;
scoped_ptr<Iterator> CreateIterator() override;
void GetStats(base::StringPairs* stats) override;
void OnExternalCacheHit(const std::string& key) override;
@@ -113,9 +116,9 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
class SimpleIterator;
friend class SimpleIterator;
- typedef base::hash_map<uint64, SimpleEntryImpl*> EntryMap;
+ typedef base::hash_map<uint64_t, SimpleEntryImpl*> EntryMap;
- typedef base::Callback<void(base::Time mtime, uint64 max_size, int result)>
+ typedef base::Callback<void(base::Time mtime, uint64_t max_size, int result)>
InitializeIndexCallback;
class ActiveEntryProxy;
@@ -124,7 +127,7 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
// Return value of InitCacheStructureOnDisk().
struct DiskStatResult {
base::Time cache_dir_mtime;
- uint64 max_size;
+ uint64_t max_size;
bool detected_magic_number_mismatch;
int net_error;
};
@@ -139,35 +142,40 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
const CompletionCallback& callback,
int result);
+ // Calculates the size of the entire cache. Invoked when the index is ready.
+ void IndexReadyForSizeCalculation(const CompletionCallback& callback,
+ int result);
+
// Try to create the directory if it doesn't exist. This must run on the IO
// thread.
static DiskStatResult InitCacheStructureOnDisk(const base::FilePath& path,
- uint64 suggested_max_size);
+ uint64_t suggested_max_size);
// Searches |active_entries_| for the entry corresponding to |key|. If found,
// returns the found entry. Otherwise, creates a new entry and returns that.
scoped_refptr<SimpleEntryImpl> CreateOrFindActiveEntry(
- uint64 entry_hash,
+ uint64_t entry_hash,
const std::string& key);
// Given a hash, will try to open the corresponding Entry. If we have an Entry
// corresponding to |hash| in the map of active entries, opens it. Otherwise,
// a new empty Entry will be created, opened and filled with information from
// the disk.
- int OpenEntryFromHash(uint64 entry_hash,
+ int OpenEntryFromHash(uint64_t entry_hash,
Entry** entry,
const CompletionCallback& callback);
// Doom the entry corresponding to |entry_hash|, if it's active or currently
// pending doom. This function does not block if there is an active entry,
// which is very important to prevent races in DoomEntries() above.
- int DoomEntryFromHash(uint64 entry_hash, const CompletionCallback & callback);
+ int DoomEntryFromHash(uint64_t entry_hash,
+ const CompletionCallback& callback);
// Called when we tried to open an entry with hash alone. When a blank entry
// has been created and filled in with information from the disk - based on a
// hash alone - this checks that a duplicate active entry was not created
// using a key in the meantime.
- void OnEntryOpenedFromHash(uint64 hash,
+ void OnEntryOpenedFromHash(uint64_t hash,
Entry** entry,
const scoped_refptr<SimpleEntryImpl>& simple_entry,
const CompletionCallback& callback,
@@ -183,7 +191,7 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
// A callback thunk used by DoomEntries to clear the |entries_pending_doom_|
// after a mass doom.
- void DoomEntriesComplete(scoped_ptr<std::vector<uint64> > entry_hashes,
+ void DoomEntriesComplete(scoped_ptr<std::vector<uint64_t>> entry_hashes,
const CompletionCallback& callback,
int result);
@@ -202,7 +210,7 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
// these entries cannot have Doom/Create/Open operations run until the doom
// is complete. The base::Closure map target is used to store deferred
// operations to be run at the completion of the Doom.
- base::hash_map<uint64, std::vector<base::Closure> > entries_pending_doom_;
+ base::hash_map<uint64_t, std::vector<base::Closure>> entries_pending_doom_;
net::NetLog* const net_log_;
};
diff --git a/chromium/net/disk_cache/simple/simple_backend_version.h b/chromium/net/disk_cache/simple/simple_backend_version.h
index fe350a2e886..d6ddf9b61ca 100644
--- a/chromium/net/disk_cache/simple/simple_backend_version.h
+++ b/chromium/net/disk_cache/simple/simple_backend_version.h
@@ -5,6 +5,8 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_VERSION_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_VERSION_H_
+#include <stdint.h>
+
namespace disk_cache {
// Short rules helping to think about data upgrades within Simple Cache:
@@ -16,11 +18,11 @@ namespace disk_cache {
// |kSimpleVersion - 1| then the whole cache directory will be cleared.
// * Dropping cache data on disk or some of its parts can be a valid way to
// Upgrade.
-const uint32 kSimpleVersion = 6;
+const uint32_t kSimpleVersion = 6;
// The version of the entry file(s) as written to disk. Must be updated iff the
// entry format changes with the overall backend version update.
-const uint32 kSimpleEntryVersionOnDisk = 5;
+const uint32_t kSimpleEntryVersionOnDisk = 5;
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/simple/simple_entry_format.h b/chromium/net/disk_cache/simple/simple_entry_format.h
index 767efb2ec9c..aec7162f2c2 100644
--- a/chromium/net/disk_cache/simple/simple_entry_format.h
+++ b/chromium/net/disk_cache/simple/simple_entry_format.h
@@ -7,7 +7,6 @@
#include <stdint.h>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
namespace base {
@@ -16,9 +15,9 @@ class Time;
namespace disk_cache {
-const uint64 kSimpleInitialMagicNumber = UINT64_C(0xfcfb6d1ba7725c30);
-const uint64 kSimpleFinalMagicNumber = UINT64_C(0xf4fa6f45970d41d8);
-const uint64 kSimpleSparseRangeMagicNumber = UINT64_C(0xeb97bf016553676b);
+const uint64_t kSimpleInitialMagicNumber = UINT64_C(0xfcfb6d1ba7725c30);
+const uint64_t kSimpleFinalMagicNumber = UINT64_C(0xf4fa6f45970d41d8);
+const uint64_t kSimpleSparseRangeMagicNumber = UINT64_C(0xeb97bf016553676b);
// A file containing stream 0 and stream 1 in the Simple cache consists of:
// - a SimpleFileHeader.
@@ -39,10 +38,10 @@ static const int kSimpleEntryStreamCount = 3;
struct NET_EXPORT_PRIVATE SimpleFileHeader {
SimpleFileHeader();
- uint64 initial_magic_number;
- uint32 version;
- uint32 key_length;
- uint32 key_hash;
+ uint64_t initial_magic_number;
+ uint32_t version;
+ uint32_t key_length;
+ uint32_t key_hash;
};
struct NET_EXPORT_PRIVATE SimpleFileEOF {
@@ -52,20 +51,20 @@ struct NET_EXPORT_PRIVATE SimpleFileEOF {
SimpleFileEOF();
- uint64 final_magic_number;
- uint32 flags;
- uint32 data_crc32;
+ uint64_t final_magic_number;
+ uint32_t flags;
+ uint32_t data_crc32;
// |stream_size| is only used in the EOF record for stream 0.
- uint32 stream_size;
+ uint32_t stream_size;
};
struct SimpleFileSparseRangeHeader {
SimpleFileSparseRangeHeader();
- uint64 sparse_range_magic_number;
- int64 offset;
- int64 length;
- uint32 data_crc32;
+ uint64_t sparse_range_magic_number;
+ int64_t offset;
+ int64_t length;
+ uint32_t data_crc32;
};
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/simple/simple_entry_format_history.h b/chromium/net/disk_cache/simple/simple_entry_format_history.h
index 89d378b620b..3bcb8b44917 100644
--- a/chromium/net/disk_cache/simple/simple_entry_format_history.h
+++ b/chromium/net/disk_cache/simple/simple_entry_format_history.h
@@ -7,15 +7,14 @@
#include <stdint.h>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
namespace disk_cache {
namespace simplecache_v5 {
-const uint64 kSimpleInitialMagicNumber = UINT64_C(0xfcfb6d1ba7725c30);
-const uint64 kSimpleFinalMagicNumber = UINT64_C(0xf4fa6f45970d41d8);
+const uint64_t kSimpleInitialMagicNumber = UINT64_C(0xfcfb6d1ba7725c30);
+const uint64_t kSimpleFinalMagicNumber = UINT64_C(0xf4fa6f45970d41d8);
// A file containing stream 0 and stream 1 in the Simple cache consists of:
// - a SimpleFileHeader.
@@ -36,10 +35,10 @@ static const int kSimpleEntryStreamCount = 3;
struct NET_EXPORT_PRIVATE SimpleFileHeader {
SimpleFileHeader();
- uint64 initial_magic_number;
- uint32 version;
- uint32 key_length;
- uint32 key_hash;
+ uint64_t initial_magic_number;
+ uint32_t version;
+ uint32_t key_length;
+ uint32_t key_hash;
};
struct NET_EXPORT_PRIVATE SimpleFileEOF {
@@ -49,11 +48,11 @@ struct NET_EXPORT_PRIVATE SimpleFileEOF {
SimpleFileEOF();
- uint64 final_magic_number;
- uint32 flags;
- uint32 data_crc32;
+ uint64_t final_magic_number;
+ uint32_t flags;
+ uint32_t data_crc32;
// |stream_size| is only used in the EOF record for stream 0.
- uint32 stream_size;
+ uint32_t stream_size;
};
} // namespace simplecache_v5
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.cc b/chromium/net/disk_cache/simple/simple_entry_impl.cc
index 39107927606..2c25d0ff8d0 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.cc
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.cc
@@ -6,6 +6,8 @@
#include <algorithm>
#include <cstring>
+#include <limits>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -34,7 +36,7 @@ namespace {
// An entry can store sparse data taking up to 1 / kMaxSparseDataSizeDivisor of
// the cache.
-const int64 kMaxSparseDataSizeDivisor = 10;
+const int64_t kMaxSparseDataSizeDivisor = 10;
// Used in histograms, please only add entries at the end.
enum ReadResult {
@@ -164,7 +166,7 @@ SimpleEntryImpl::ActiveEntryProxy::~ActiveEntryProxy() {}
SimpleEntryImpl::SimpleEntryImpl(net::CacheType cache_type,
const FilePath& path,
- const uint64 entry_hash,
+ const uint64_t entry_hash,
OperationsMode operations_mode,
SimpleBackendImpl* backend,
net::NetLog* net_log)
@@ -181,8 +183,8 @@ SimpleEntryImpl::SimpleEntryImpl(net::CacheType cache_type,
doomed_(false),
state_(STATE_UNINITIALIZED),
synchronous_entry_(NULL),
- net_log_(net::BoundNetLog::Make(
- net_log, net::NetLog::SOURCE_DISK_CACHE_ENTRY)),
+ net_log_(net::BoundNetLog::Make(net_log,
+ net::NetLog::SOURCE_DISK_CACHE_ENTRY)),
stream_0_data_(new net::GrowableIOBuffer()) {
static_assert(arraysize(data_size_) == arraysize(crc32s_end_offset_),
"arrays should be the same size");
@@ -333,7 +335,7 @@ Time SimpleEntryImpl::GetLastModified() const {
return last_modified_;
}
-int32 SimpleEntryImpl::GetDataSize(int stream_index) const {
+int32_t SimpleEntryImpl::GetDataSize(int stream_index) const {
DCHECK(io_thread_checker_.CalledOnValidThread());
DCHECK_LE(0, data_size_[stream_index]);
return data_size_[stream_index];
@@ -471,33 +473,43 @@ int SimpleEntryImpl::WriteData(int stream_index,
return ret_value;
}
-int SimpleEntryImpl::ReadSparseData(int64 offset,
+int SimpleEntryImpl::ReadSparseData(int64_t offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
+ if (net_log_.IsCapturing()) {
+ net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_SPARSE_CALL,
+ CreateNetLogSparseOperationCallback(offset, buf_len));
+ }
+
ScopedOperationRunner operation_runner(this);
pending_operations_.push(SimpleEntryOperation::ReadSparseOperation(
this, offset, buf_len, buf, callback));
return net::ERR_IO_PENDING;
}
-int SimpleEntryImpl::WriteSparseData(int64 offset,
+int SimpleEntryImpl::WriteSparseData(int64_t offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
+ if (net_log_.IsCapturing()) {
+ net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_SPARSE_CALL,
+ CreateNetLogSparseOperationCallback(offset, buf_len));
+ }
+
ScopedOperationRunner operation_runner(this);
pending_operations_.push(SimpleEntryOperation::WriteSparseOperation(
this, offset, buf_len, buf, callback));
return net::ERR_IO_PENDING;
}
-int SimpleEntryImpl::GetAvailableRange(int64 offset,
+int SimpleEntryImpl::GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
@@ -765,7 +777,7 @@ void SimpleEntryImpl::CloseInternal() {
for (int i = 0; i < kSimpleEntryStreamCount; ++i) {
if (have_written_[i]) {
if (GetDataSize(i) == crc32s_end_offset_[i]) {
- int32 crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i];
+ int32_t crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i];
crc32s_to_write->push_back(CRCRecord(i, true, crc));
} else {
crc32s_to_write->push_back(CRCRecord(i, false, 0));
@@ -858,7 +870,7 @@ void SimpleEntryImpl::ReadDataInternal(int stream_index,
if (!doomed_ && backend_.get())
backend_->index()->UseIfExists(entry_hash_);
- scoped_ptr<uint32> read_crc32(new uint32());
+ scoped_ptr<uint32_t> read_crc32(new uint32_t());
scoped_ptr<int> result(new int());
scoped_ptr<SimpleEntryStat> entry_stat(
new SimpleEntryStat(last_used_, last_modified_, data_size_,
@@ -927,7 +939,7 @@ void SimpleEntryImpl::WriteDataInternal(int stream_index,
// Ignore zero-length writes that do not change the file size.
if (buf_len == 0) {
- int32 data_size = data_size_[stream_index];
+ int32_t data_size = data_size_[stream_index];
if (truncate ? (offset == data_size) : (offset <= data_size)) {
RecordWriteResult(cache_type_, WRITE_RESULT_FAST_EMPTY_RETURN);
if (!callback.is_null()) {
@@ -983,13 +995,19 @@ void SimpleEntryImpl::WriteDataInternal(int stream_index,
}
void SimpleEntryImpl::ReadSparseDataInternal(
- int64 sparse_offset,
+ int64_t sparse_offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
ScopedOperationRunner operation_runner(this);
+ if (net_log_.IsCapturing()) {
+ net_log_.AddEvent(
+ net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_SPARSE_BEGIN,
+ CreateNetLogSparseOperationCallback(sparse_offset, buf_len));
+ }
+
DCHECK_EQ(STATE_READY, state_);
state_ = STATE_IO_PENDING;
@@ -1011,19 +1029,25 @@ void SimpleEntryImpl::ReadSparseDataInternal(
}
void SimpleEntryImpl::WriteSparseDataInternal(
- int64 sparse_offset,
+ int64_t sparse_offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
ScopedOperationRunner operation_runner(this);
+ if (net_log_.IsCapturing()) {
+ net_log_.AddEvent(
+ net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_SPARSE_BEGIN,
+ CreateNetLogSparseOperationCallback(sparse_offset, buf_len));
+ }
+
DCHECK_EQ(STATE_READY, state_);
state_ = STATE_IO_PENDING;
- uint64 max_sparse_data_size = kint64max;
+ uint64_t max_sparse_data_size = std::numeric_limits<int64_t>::max();
if (backend_.get()) {
- uint64 max_cache_size = backend_->index()->max_size();
+ uint64_t max_cache_size = backend_->index()->max_size();
max_sparse_data_size = max_cache_size / kMaxSparseDataSizeDivisor;
}
@@ -1051,9 +1075,9 @@ void SimpleEntryImpl::WriteSparseDataInternal(
}
void SimpleEntryImpl::GetAvailableRangeInternal(
- int64 sparse_offset,
+ int64_t sparse_offset,
int len,
- int64* out_start,
+ int64_t* out_start,
const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
ScopedOperationRunner operation_runner(this);
@@ -1166,7 +1190,7 @@ void SimpleEntryImpl::ReadOperationComplete(
int stream_index,
int offset,
const CompletionCallback& completion_callback,
- scoped_ptr<uint32> read_crc32,
+ scoped_ptr<uint32_t> read_crc32,
scoped_ptr<SimpleEntryStat> entry_stat,
scoped_ptr<int> result) {
DCHECK(io_thread_checker_.CalledOnValidThread());
@@ -1181,8 +1205,8 @@ void SimpleEntryImpl::ReadOperationComplete(
}
if (*result > 0 && crc32s_end_offset_[stream_index] == offset) {
- uint32 current_crc = offset == 0 ? crc32(0, Z_NULL, 0)
- : crc32s_[stream_index];
+ uint32_t current_crc =
+ offset == 0 ? crc32(0, Z_NULL, 0) : crc32s_[stream_index];
crc32s_[stream_index] = crc32_combine(current_crc, *read_crc32, *result);
crc32s_end_offset_[stream_index] += *result;
if (!have_written_[stream_index] &&
@@ -1230,7 +1254,7 @@ void SimpleEntryImpl::ReadOperationComplete(
CreateNetLogReadWriteCompleteCallback(*result));
}
- EntryOperationComplete(completion_callback, *entry_stat, result.Pass());
+ EntryOperationComplete(completion_callback, *entry_stat, std::move(result));
}
void SimpleEntryImpl::WriteOperationComplete(
@@ -1251,7 +1275,7 @@ void SimpleEntryImpl::WriteOperationComplete(
crc32s_end_offset_[stream_index] = 0;
}
- EntryOperationComplete(completion_callback, *entry_stat, result.Pass());
+ EntryOperationComplete(completion_callback, *entry_stat, std::move(result));
}
void SimpleEntryImpl::ReadSparseOperationComplete(
@@ -1262,9 +1286,14 @@ void SimpleEntryImpl::ReadSparseOperationComplete(
DCHECK(synchronous_entry_);
DCHECK(result);
+ if (net_log_.IsCapturing()) {
+ net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_SPARSE_END,
+ CreateNetLogReadWriteCompleteCallback(*result));
+ }
+
SimpleEntryStat entry_stat(*last_used, last_modified_, data_size_,
sparse_data_size_);
- EntryOperationComplete(completion_callback, entry_stat, result.Pass());
+ EntryOperationComplete(completion_callback, entry_stat, std::move(result));
}
void SimpleEntryImpl::WriteSparseOperationComplete(
@@ -1275,7 +1304,12 @@ void SimpleEntryImpl::WriteSparseOperationComplete(
DCHECK(synchronous_entry_);
DCHECK(result);
- EntryOperationComplete(completion_callback, *entry_stat, result.Pass());
+ if (net_log_.IsCapturing()) {
+ net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END,
+ CreateNetLogReadWriteCompleteCallback(*result));
+ }
+
+ EntryOperationComplete(completion_callback, *entry_stat, std::move(result));
}
void SimpleEntryImpl::GetAvailableRangeOperationComplete(
@@ -1287,7 +1321,7 @@ void SimpleEntryImpl::GetAvailableRangeOperationComplete(
SimpleEntryStat entry_stat(last_used_, last_modified_, data_size_,
sparse_data_size_);
- EntryOperationComplete(completion_callback, entry_stat, result.Pass());
+ EntryOperationComplete(completion_callback, entry_stat, std::move(result));
}
void SimpleEntryImpl::DoomOperationComplete(
@@ -1335,7 +1369,7 @@ void SimpleEntryImpl::ChecksumOperationComplete(
SimpleEntryStat entry_stat(last_used_, last_modified_, data_size_,
sparse_data_size_);
- EntryOperationComplete(completion_callback, entry_stat, result.Pass());
+ EntryOperationComplete(completion_callback, entry_stat, std::move(result));
}
void SimpleEntryImpl::CloseOperationComplete() {
@@ -1365,8 +1399,8 @@ void SimpleEntryImpl::UpdateDataFromEntryStat(
backend_->index()->UpdateEntrySize(entry_hash_, GetDiskUsage());
}
-int64 SimpleEntryImpl::GetDiskUsage() const {
- int64 file_size = 0;
+int64_t SimpleEntryImpl::GetDiskUsage() const {
+ int64_t file_size = 0;
for (int i = 0; i < kSimpleEntryStreamCount; ++i) {
file_size +=
simple_util::GetFileSizeFromKeyAndDataSize(key_, data_size_[i]);
@@ -1510,7 +1544,7 @@ void SimpleEntryImpl::AdvanceCrc(net::IOBuffer* buffer,
// the crc of the data. When we write to an entry and close without having
// done a sequential write, we don't check the CRC on read.
if (offset == 0 || crc32s_end_offset_[stream_index] == offset) {
- uint32 initial_crc =
+ uint32_t initial_crc =
(offset != 0) ? crc32s_[stream_index] : crc32(0, Z_NULL, 0);
if (length > 0) {
crc32s_[stream_index] = crc32(
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.h b/chromium/net/disk_cache/simple/simple_entry_impl.h
index ba544e3616e..df9d240fc11 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.h
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.h
@@ -5,6 +5,8 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
+#include <stdint.h>
+
#include <queue>
#include <string>
@@ -57,7 +59,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
SimpleEntryImpl(net::CacheType cache_type,
const base::FilePath& path,
- uint64 entry_hash,
+ uint64_t entry_hash,
OperationsMode operations_mode,
SimpleBackendImpl* backend,
net::NetLog* net_log);
@@ -76,7 +78,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
int DoomEntry(const CompletionCallback& callback);
const std::string& key() const { return key_; }
- uint64 entry_hash() const { return entry_hash_; }
+ uint64_t entry_hash() const { return entry_hash_; }
void SetKey(const std::string& key);
// From Entry:
@@ -85,7 +87,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
std::string GetKey() const override;
base::Time GetLastUsed() const override;
base::Time GetLastModified() const override;
- int32 GetDataSize(int index) const override;
+ int32_t GetDataSize(int index) const override;
int ReadData(int stream_index,
int offset,
net::IOBuffer* buf,
@@ -97,17 +99,17 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
int buf_len,
const CompletionCallback& callback,
bool truncate) override;
- int ReadSparseData(int64 offset,
+ int ReadSparseData(int64_t offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int WriteSparseData(int64 offset,
+ int WriteSparseData(int64_t offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int GetAvailableRange(int64 offset,
+ int GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) override;
bool CouldBeSparse() const override;
void CancelSparseIO() override;
@@ -193,19 +195,19 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
const CompletionCallback& callback,
bool truncate);
- void ReadSparseDataInternal(int64 sparse_offset,
+ void ReadSparseDataInternal(int64_t sparse_offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback);
- void WriteSparseDataInternal(int64 sparse_offset,
+ void WriteSparseDataInternal(int64_t sparse_offset,
net::IOBuffer* buf,
int buf_len,
const CompletionCallback& callback);
- void GetAvailableRangeInternal(int64 sparse_offset,
+ void GetAvailableRangeInternal(int64_t sparse_offset,
int len,
- int64* out_start,
+ int64_t* out_start,
const CompletionCallback& callback);
void DoomEntryInternal(const CompletionCallback& callback);
@@ -236,7 +238,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
void ReadOperationComplete(int stream_index,
int offset,
const CompletionCallback& completion_callback,
- scoped_ptr<uint32> read_crc32,
+ scoped_ptr<uint32_t> read_crc32,
scoped_ptr<SimpleEntryStat> entry_stat,
scoped_ptr<int> result);
@@ -266,7 +268,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
int result);
// Called after validating the checksums on an entry. Passes through the
- // original result if successful, propogates the error if the checksum does
+ // original result if successful, propagates the error if the checksum does
// not validate.
void ChecksumOperationComplete(
int stream_index,
@@ -279,7 +281,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
// index to make them available on next IO operations.
void UpdateDataFromEntryStat(const SimpleEntryStat& entry_stat);
- int64 GetDiskUsage() const;
+ int64_t GetDiskUsage() const;
// Used to report histograms.
void RecordReadIsParallelizable(const SimpleEntryOperation& operation) const;
@@ -312,7 +314,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
const net::CacheType cache_type_;
const scoped_refptr<base::TaskRunner> worker_pool_;
const base::FilePath path_;
- const uint64 entry_hash_;
+ const uint64_t entry_hash_;
const bool use_optimistic_operations_;
std::string key_;
@@ -321,8 +323,8 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
// TODO(clamy): Unify last_used_ with data in the index.
base::Time last_used_;
base::Time last_modified_;
- int32 data_size_[kSimpleEntryStreamCount];
- int32 sparse_data_size_;
+ int32_t data_size_[kSimpleEntryStreamCount];
+ int32_t sparse_data_size_;
// Number of times this object has been returned from Backend::OpenEntry() and
// Backend::CreateEntry() without subsequent Entry::Close() calls. Used to
@@ -341,8 +343,8 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
// a single entry reader that reads serially through the entire file.
// Extending this to multiple readers is possible, but isn't currently worth
// it; see http://crbug.com/488076#c3 for details.
- int32 crc32s_end_offset_[kSimpleEntryStreamCount];
- uint32 crc32s_[kSimpleEntryStreamCount];
+ int32_t crc32s_end_offset_[kSimpleEntryStreamCount];
+ uint32_t crc32s_[kSimpleEntryStreamCount];
// If |have_written_[index]| is true, we have written to the file that
// contains stream |index|.
diff --git a/chromium/net/disk_cache/simple/simple_entry_operation.cc b/chromium/net/disk_cache/simple/simple_entry_operation.cc
index 7dfe0d2111f..ce8b09c8fa2 100644
--- a/chromium/net/disk_cache/simple/simple_entry_operation.cc
+++ b/chromium/net/disk_cache/simple/simple_entry_operation.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/simple/simple_entry_operation.h"
+#include <limits.h>
+
#include "base/logging.h"
#include "net/base/io_buffer.h"
#include "net/disk_cache/disk_cache.h"
@@ -168,7 +170,7 @@ SimpleEntryOperation SimpleEntryOperation::WriteOperation(
// static
SimpleEntryOperation SimpleEntryOperation::ReadSparseOperation(
SimpleEntryImpl* entry,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
net::IOBuffer* buf,
const CompletionCallback& callback) {
@@ -191,7 +193,7 @@ SimpleEntryOperation SimpleEntryOperation::ReadSparseOperation(
// static
SimpleEntryOperation SimpleEntryOperation::WriteSparseOperation(
SimpleEntryImpl* entry,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
net::IOBuffer* buf,
const CompletionCallback& callback) {
@@ -214,9 +216,9 @@ SimpleEntryOperation SimpleEntryOperation::WriteSparseOperation(
// static
SimpleEntryOperation SimpleEntryOperation::GetAvailableRangeOperation(
SimpleEntryImpl* entry,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
- int64* out_start,
+ int64_t* out_start,
const CompletionCallback& callback) {
return SimpleEntryOperation(entry,
NULL,
@@ -241,9 +243,9 @@ SimpleEntryOperation SimpleEntryOperation::DoomOperation(
net::IOBuffer* const buf = NULL;
Entry** const out_entry = NULL;
const int offset = 0;
- const int64 sparse_offset = 0;
+ const int64_t sparse_offset = 0;
const int length = 0;
- int64* const out_start = NULL;
+ int64_t* const out_start = NULL;
const bool have_index = false;
const int index = 0;
const bool truncate = false;
@@ -287,8 +289,8 @@ bool SimpleEntryOperation::ConflictsWith(
// and offsets to see whether they overlap.
if (IsSparseType(type_)) {
- int64 end = sparse_offset_ + length_;
- int64 other_op_end = other_op.sparse_offset() + other_op.length();
+ int64_t end = sparse_offset_ + length_;
+ int64_t other_op_end = other_op.sparse_offset() + other_op.length();
return sparse_offset_ < other_op_end && other_op.sparse_offset() < end;
}
@@ -312,9 +314,9 @@ SimpleEntryOperation::SimpleEntryOperation(SimpleEntryImpl* entry,
const CompletionCallback& callback,
Entry** out_entry,
int offset,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
- int64* out_start,
+ int64_t* out_start,
EntryOperationType type,
bool have_index,
int index,
@@ -334,7 +336,6 @@ SimpleEntryOperation::SimpleEntryOperation(SimpleEntryImpl* entry,
index_(index),
truncate_(truncate),
optimistic_(optimistic),
- alone_in_queue_(alone_in_queue) {
-}
+ alone_in_queue_(alone_in_queue) {}
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/simple/simple_entry_operation.h b/chromium/net/disk_cache/simple/simple_entry_operation.h
index b2f5502a00b..a9b3a0fb1f5 100644
--- a/chromium/net/disk_cache/simple/simple_entry_operation.h
+++ b/chromium/net/disk_cache/simple/simple_entry_operation.h
@@ -5,6 +5,8 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_OPERATION_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_OPERATION_H_
+#include <stdint.h>
+
#include "base/memory/ref_counted.h"
#include "net/base/completion_callback.h"
#include "net/log/net_log.h"
@@ -68,21 +70,21 @@ class SimpleEntryOperation {
const CompletionCallback& callback);
static SimpleEntryOperation ReadSparseOperation(
SimpleEntryImpl* entry,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
net::IOBuffer* buf,
const CompletionCallback& callback);
static SimpleEntryOperation WriteSparseOperation(
SimpleEntryImpl* entry,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
net::IOBuffer* buf,
const CompletionCallback& callback);
static SimpleEntryOperation GetAvailableRangeOperation(
SimpleEntryImpl* entry,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
- int64* out_start,
+ int64_t* out_start,
const CompletionCallback& callback);
static SimpleEntryOperation DoomOperation(
SimpleEntryImpl* entry,
@@ -101,9 +103,9 @@ class SimpleEntryOperation {
bool have_index() const { return have_index_; }
int index() const { return index_; }
int offset() const { return offset_; }
- int64 sparse_offset() const { return sparse_offset_; }
+ int64_t sparse_offset() const { return sparse_offset_; }
int length() const { return length_; }
- int64* out_start() { return out_start_; }
+ int64_t* out_start() { return out_start_; }
net::IOBuffer* buf() { return buf_.get(); }
bool truncate() const { return truncate_; }
bool optimistic() const { return optimistic_; }
@@ -115,9 +117,9 @@ class SimpleEntryOperation {
const CompletionCallback& callback,
Entry** out_entry,
int offset,
- int64 sparse_offset,
+ int64_t sparse_offset,
int length,
- int64* out_start,
+ int64_t* out_start,
EntryOperationType type,
bool have_index,
int index,
@@ -135,11 +137,11 @@ class SimpleEntryOperation {
// Used in write and read operations.
const int offset_;
- const int64 sparse_offset_;
+ const int64_t sparse_offset_;
const int length_;
// Used in get available range operations.
- int64* const out_start_;
+ int64_t* const out_start_;
const EntryOperationType type_;
// Used in open and create operations.
diff --git a/chromium/net/disk_cache/simple/simple_index.cc b/chromium/net/disk_cache/simple/simple_index.cc
index fd01abd8994..7df258a1d43 100644
--- a/chromium/net/disk_cache/simple/simple_index.cc
+++ b/chromium/net/disk_cache/simple/simple_index.cc
@@ -45,9 +45,9 @@ const int kWriteToDiskOnBackgroundDelayMSecs = 100;
// Divides the cache space into this amount of parts to evict when only one part
// is left.
-const uint32 kEvictionMarginDivisor = 20;
+const uint32_t kEvictionMarginDivisor = 20;
-const uint32 kBytesInKb = 1024;
+const uint32_t kBytesInKb = 1024;
// Utility class used for timestamp comparisons in entry metadata while sorting.
class CompareHashesForTimestamp {
@@ -56,7 +56,8 @@ class CompareHashesForTimestamp {
public:
explicit CompareHashesForTimestamp(const EntrySet& set);
- bool operator()(uint64 hash1, uint64 hash2);
+ bool operator()(uint64_t hash1, uint64_t hash2);
+
private:
const EntrySet& entry_set_;
};
@@ -65,7 +66,7 @@ CompareHashesForTimestamp::CompareHashesForTimestamp(const EntrySet& set)
: entry_set_(set) {
}
-bool CompareHashesForTimestamp::operator()(uint64 hash1, uint64 hash2) {
+bool CompareHashesForTimestamp::operator()(uint64_t hash1, uint64_t hash2) {
EntrySet::const_iterator it1 = entry_set_.find(hash1);
DCHECK(it1 != entry_set_.end());
EntrySet::const_iterator it2 = entry_set_.find(hash2);
@@ -82,9 +83,9 @@ EntryMetadata::EntryMetadata()
entry_size_(0) {
}
-EntryMetadata::EntryMetadata(base::Time last_used_time, uint64 entry_size)
+EntryMetadata::EntryMetadata(base::Time last_used_time, uint64_t entry_size)
: last_used_time_seconds_since_epoch_(0),
- entry_size_(base::checked_cast<int32>(entry_size)) {
+ entry_size_(base::checked_cast<int32_t>(entry_size)) {
SetLastUsedTime(last_used_time);
}
@@ -104,37 +105,38 @@ void EntryMetadata::SetLastUsedTime(const base::Time& last_used_time) {
return;
}
- last_used_time_seconds_since_epoch_ = base::checked_cast<uint32>(
+ last_used_time_seconds_since_epoch_ = base::checked_cast<uint32_t>(
(last_used_time - base::Time::UnixEpoch()).InSeconds());
// Avoid accidental nullity.
if (last_used_time_seconds_since_epoch_ == 0)
last_used_time_seconds_since_epoch_ = 1;
}
-uint64 EntryMetadata::GetEntrySize() const {
+uint64_t EntryMetadata::GetEntrySize() const {
return entry_size_;
}
-void EntryMetadata::SetEntrySize(uint64 entry_size) {
- entry_size_ = base::checked_cast<int32>(entry_size);
+void EntryMetadata::SetEntrySize(uint64_t entry_size) {
+ entry_size_ = base::checked_cast<int32_t>(entry_size);
}
void EntryMetadata::Serialize(base::Pickle* pickle) const {
DCHECK(pickle);
- int64 internal_last_used_time = GetLastUsedTime().ToInternalValue();
+ int64_t internal_last_used_time = GetLastUsedTime().ToInternalValue();
pickle->WriteInt64(internal_last_used_time);
pickle->WriteUInt64(entry_size_);
}
bool EntryMetadata::Deserialize(base::PickleIterator* it) {
DCHECK(it);
- int64 tmp_last_used_time;
- uint64 tmp_entry_size;
+ int64_t tmp_last_used_time;
+ uint64_t tmp_entry_size;
if (!it->ReadInt64(&tmp_last_used_time) || !it->ReadUInt64(&tmp_entry_size) ||
- tmp_entry_size > static_cast<uint64>(std::numeric_limits<int32>::max()))
+ tmp_entry_size >
+ static_cast<uint64_t>(std::numeric_limits<int32_t>::max()))
return false;
SetLastUsedTime(base::Time::FromInternalValue(tmp_last_used_time));
- entry_size_ = static_cast<int32>(tmp_entry_size);
+ entry_size_ = static_cast<int32_t>(tmp_entry_size);
return true;
}
@@ -151,13 +153,12 @@ SimpleIndex::SimpleIndex(
low_watermark_(0),
eviction_in_progress_(false),
initialized_(false),
- index_file_(index_file.Pass()),
+ index_file_(std::move(index_file)),
io_thread_(io_thread),
// Creating the callback once so it is reused every time
// write_to_disk_timer_.Start() is called.
write_to_disk_cb_(base::Bind(&SimpleIndex::WriteToDisk, AsWeakPtr())),
- app_on_background_(false) {
-}
+ app_on_background_(false) {}
SimpleIndex::~SimpleIndex() {
DCHECK(io_thread_checker_.CalledOnValidThread());
@@ -188,7 +189,7 @@ void SimpleIndex::Initialize(base::Time cache_mtime) {
index_file_->LoadIndexEntries(cache_mtime, reply, load_result);
}
-void SimpleIndex::SetMaxSize(uint64 max_bytes) {
+void SimpleIndex::SetMaxSize(uint64_t max_bytes) {
// Zero size means use the default.
if (max_bytes) {
max_size_ = max_bytes;
@@ -227,19 +228,24 @@ scoped_ptr<SimpleIndex::HashList> SimpleIndex::GetEntriesBetween(
if (initial_time <= entry_time && entry_time < extended_end_time)
ret_hashes->push_back(it->first);
}
- return ret_hashes.Pass();
+ return ret_hashes;
}
scoped_ptr<SimpleIndex::HashList> SimpleIndex::GetAllHashes() {
return GetEntriesBetween(base::Time(), base::Time());
}
-int32 SimpleIndex::GetEntryCount() const {
+int32_t SimpleIndex::GetEntryCount() const {
// TODO(pasko): return a meaningful initial estimate before initialized.
return entries_set_.size();
}
-void SimpleIndex::Insert(uint64 entry_hash) {
+uint64_t SimpleIndex::GetCacheSize() const {
+ DCHECK(initialized_);
+ return cache_size_;
+}
+
+void SimpleIndex::Insert(uint64_t entry_hash) {
DCHECK(io_thread_checker_.CalledOnValidThread());
// Upon insert we don't know yet the size of the entry.
// It will be updated later when the SimpleEntryImpl finishes opening or
@@ -251,7 +257,7 @@ void SimpleIndex::Insert(uint64 entry_hash) {
PostponeWritingToDisk();
}
-void SimpleIndex::Remove(uint64 entry_hash) {
+void SimpleIndex::Remove(uint64_t entry_hash) {
DCHECK(io_thread_checker_.CalledOnValidThread());
EntrySet::iterator it = entries_set_.find(entry_hash);
if (it != entries_set_.end()) {
@@ -264,13 +270,13 @@ void SimpleIndex::Remove(uint64 entry_hash) {
PostponeWritingToDisk();
}
-bool SimpleIndex::Has(uint64 hash) const {
+bool SimpleIndex::Has(uint64_t hash) const {
DCHECK(io_thread_checker_.CalledOnValidThread());
// If not initialized, always return true, forcing it to go to the disk.
return !initialized_ || entries_set_.count(hash) > 0;
}
-bool SimpleIndex::UseIfExists(uint64 entry_hash) {
+bool SimpleIndex::UseIfExists(uint64_t entry_hash) {
DCHECK(io_thread_checker_.CalledOnValidThread());
// Always update the last used time, even if it is during initialization.
// It will be merged later.
@@ -296,7 +302,7 @@ void SimpleIndex::StartEvictionIfNeeded() {
SIMPLE_CACHE_UMA(
MEMORY_KB, "Eviction.MaxCacheSizeOnStart2", cache_type_,
static_cast<base::HistogramBase::Sample>(max_size_ / kBytesInKb));
- std::vector<uint64> entry_hashes;
+ std::vector<uint64_t> entry_hashes;
entry_hashes.reserve(entries_set_.size());
for (EntrySet::const_iterator it = entries_set_.begin(),
end = entries_set_.end(); it != end; ++it) {
@@ -306,8 +312,8 @@ void SimpleIndex::StartEvictionIfNeeded() {
CompareHashesForTimestamp(entries_set_));
// Remove as many entries from the index to get below |low_watermark_|.
- std::vector<uint64>::iterator it = entry_hashes.begin();
- uint64 evicted_so_far_size = 0;
+ std::vector<uint64_t>::iterator it = entry_hashes.begin();
+ uint64_t evicted_so_far_size = 0;
while (evicted_so_far_size < cache_size_ - low_watermark_) {
DCHECK(it != entry_hashes.end());
EntrySet::iterator found_meta = entries_set_.find(*it);
@@ -332,7 +338,7 @@ void SimpleIndex::StartEvictionIfNeeded() {
AsWeakPtr()));
}
-bool SimpleIndex::UpdateEntrySize(uint64 entry_hash, int64 entry_size) {
+bool SimpleIndex::UpdateEntrySize(uint64_t entry_hash, int64_t entry_size) {
DCHECK(io_thread_checker_.CalledOnValidThread());
EntrySet::iterator it = entries_set_.find(entry_hash);
if (it == entries_set_.end())
@@ -360,7 +366,7 @@ void SimpleIndex::EvictionDone(int result) {
// static
void SimpleIndex::InsertInEntrySet(
- uint64 entry_hash,
+ uint64_t entry_hash,
const disk_cache::EntryMetadata& entry_metadata,
EntrySet* entry_set) {
DCHECK(entry_set);
@@ -378,7 +384,7 @@ void SimpleIndex::PostponeWritingToDisk() {
}
void SimpleIndex::UpdateEntryIteratorSize(EntrySet::iterator* it,
- int64 entry_size) {
+ int64_t entry_size) {
// Update the total cache size with the new entry size.
DCHECK(io_thread_checker_.CalledOnValidThread());
DCHECK_GE(cache_size_, (*it)->second.GetEntrySize());
@@ -394,7 +400,7 @@ void SimpleIndex::MergeInitializingSet(
EntrySet* index_file_entries = &load_result->entries;
- for (base::hash_set<uint64>::const_iterator it = removed_entries_.begin();
+ for (base::hash_set<uint64_t>::const_iterator it = removed_entries_.begin();
it != removed_entries_.end(); ++it) {
index_file_entries->erase(*it);
}
@@ -402,7 +408,7 @@ void SimpleIndex::MergeInitializingSet(
for (EntrySet::const_iterator it = entries_set_.begin();
it != entries_set_.end(); ++it) {
- const uint64 entry_hash = it->first;
+ const uint64_t entry_hash = it->first;
std::pair<EntrySet::iterator, bool> insert_result =
index_file_entries->insert(EntrySet::value_type(entry_hash,
EntryMetadata()));
@@ -410,7 +416,7 @@ void SimpleIndex::MergeInitializingSet(
possibly_inserted_entry->second = it->second;
}
- uint64 merged_cache_size = 0;
+ uint64_t merged_cache_size = 0;
for (EntrySet::iterator it = index_file_entries->begin();
it != index_file_entries->end(); ++it) {
merged_cache_size += it->second.GetEntrySize();
diff --git a/chromium/net/disk_cache/simple/simple_index.h b/chromium/net/disk_cache/simple/simple_index.h
index 11adab9d72f..0946e5b5cf7 100644
--- a/chromium/net/disk_cache/simple/simple_index.h
+++ b/chromium/net/disk_cache/simple/simple_index.h
@@ -5,10 +5,11 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
+#include <stdint.h>
+
#include <list>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
@@ -42,13 +43,13 @@ struct SimpleIndexLoadResult;
class NET_EXPORT_PRIVATE EntryMetadata {
public:
EntryMetadata();
- EntryMetadata(base::Time last_used_time, uint64 entry_size);
+ EntryMetadata(base::Time last_used_time, uint64_t entry_size);
base::Time GetLastUsedTime() const;
void SetLastUsedTime(const base::Time& last_used_time);
- uint64 GetEntrySize() const;
- void SetEntrySize(uint64 entry_size);
+ uint64_t GetEntrySize() const;
+ void SetEntrySize(uint64_t entry_size);
// Serialize the data into the provided pickle.
void Serialize(base::Pickle* pickle) const;
@@ -68,8 +69,8 @@ class NET_EXPORT_PRIVATE EntryMetadata {
// size of each entry matters. Even when the values used to set these members
// are originally calculated as >32-bit types, the actual necessary size for
// each shouldn't exceed 32 bits, so we use 32-bit types here.
- uint32 last_used_time_seconds_since_epoch_;
- int32 entry_size_; // Storage size in bytes.
+ uint32_t last_used_time_seconds_since_epoch_;
+ int32_t entry_size_; // Storage size in bytes.
};
static_assert(sizeof(EntryMetadata) == 8, "incorrect metadata size");
@@ -77,7 +78,7 @@ static_assert(sizeof(EntryMetadata) == 8, "incorrect metadata size");
class NET_EXPORT_PRIVATE SimpleIndex
: public base::SupportsWeakPtr<SimpleIndex> {
public:
- typedef std::vector<uint64> HashList;
+ typedef std::vector<uint64_t> HashList;
SimpleIndex(const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
SimpleIndexDelegate* delegate,
@@ -88,29 +89,29 @@ class NET_EXPORT_PRIVATE SimpleIndex
void Initialize(base::Time cache_mtime);
- void SetMaxSize(uint64 max_bytes);
- uint64 max_size() const { return max_size_; }
+ void SetMaxSize(uint64_t max_bytes);
+ uint64_t max_size() const { return max_size_; }
- void Insert(uint64 entry_hash);
- void Remove(uint64 entry_hash);
+ void Insert(uint64_t entry_hash);
+ void Remove(uint64_t entry_hash);
// Check whether the index has the entry given the hash of its key.
- bool Has(uint64 entry_hash) const;
+ bool Has(uint64_t entry_hash) const;
// Update the last used time of the entry with the given key and return true
// iff the entry exist in the index.
- bool UseIfExists(uint64 entry_hash);
+ bool UseIfExists(uint64_t entry_hash);
void WriteToDisk();
// Update the size (in bytes) of an entry, in the metadata stored in the
// index. This should be the total disk-file size including all streams of the
// entry.
- bool UpdateEntrySize(uint64 entry_hash, int64 entry_size);
+ bool UpdateEntrySize(uint64_t entry_hash, int64_t entry_size);
- typedef base::hash_map<uint64, EntryMetadata> EntrySet;
+ typedef base::hash_map<uint64_t, EntryMetadata> EntrySet;
- static void InsertInEntrySet(uint64 entry_hash,
+ static void InsertInEntrySet(uint64_t entry_hash,
const EntryMetadata& entry_metadata,
EntrySet* entry_set);
@@ -128,7 +129,11 @@ class NET_EXPORT_PRIVATE SimpleIndex
scoped_ptr<HashList> GetAllHashes();
// Returns number of indexed entries.
- int32 GetEntryCount() const;
+ int32_t GetEntryCount() const;
+
+ // Returns the size of the entire cache in bytes. Can only be called after the
+ // index has been initialized.
+ uint64_t GetCacheSize() const;
// Returns whether the index has been initialized yet.
bool initialized() const { return initialized_; }
@@ -145,7 +150,7 @@ class NET_EXPORT_PRIVATE SimpleIndex
void PostponeWritingToDisk();
- void UpdateEntryIteratorSize(EntrySet::iterator* it, int64 entry_size);
+ void UpdateEntryIteratorSize(EntrySet::iterator* it, int64_t entry_size);
// Must run on IO Thread.
void MergeInitializingSet(scoped_ptr<SimpleIndexLoadResult> load_result);
@@ -162,16 +167,16 @@ class NET_EXPORT_PRIVATE SimpleIndex
EntrySet entries_set_;
const net::CacheType cache_type_;
- uint64 cache_size_; // Total cache storage size in bytes.
- uint64 max_size_;
- uint64 high_watermark_;
- uint64 low_watermark_;
+ uint64_t cache_size_; // Total cache storage size in bytes.
+ uint64_t max_size_;
+ uint64_t high_watermark_;
+ uint64_t low_watermark_;
bool eviction_in_progress_;
base::TimeTicks eviction_start_time_;
// This stores all the entry_hash of entries that are removed during
// initialization.
- base::hash_set<uint64> removed_entries_;
+ base::hash_set<uint64_t> removed_entries_;
bool initialized_;
scoped_ptr<SimpleIndexFile> index_file_;
diff --git a/chromium/net/disk_cache/simple/simple_index_delegate.h b/chromium/net/disk_cache/simple/simple_index_delegate.h
index e942484164e..c21e5c54dd6 100644
--- a/chromium/net/disk_cache/simple/simple_index_delegate.h
+++ b/chromium/net/disk_cache/simple/simple_index_delegate.h
@@ -5,6 +5,8 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_DELEGATE_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_DELEGATE_H_
+#include <stdint.h>
+
#include <vector>
#include "net/base/completion_callback.h"
@@ -19,7 +21,7 @@ class NET_EXPORT_PRIVATE SimpleIndexDelegate {
// Dooms all entries in |entries|, calling |callback| with the result
// asynchronously. |entries| is mutated in an undefined way by this call,
// for efficiency.
- virtual void DoomEntries(std::vector<uint64>* entry_hashes,
+ virtual void DoomEntries(std::vector<uint64_t>* entry_hashes,
const net::CompletionCallback& callback) = 0;
};
diff --git a/chromium/net/disk_cache/simple/simple_index_file.cc b/chromium/net/disk_cache/simple/simple_index_file.cc
index 11d37a95048..7e80c02fa22 100644
--- a/chromium/net/disk_cache/simple/simple_index_file.cc
+++ b/chromium/net/disk_cache/simple/simple_index_file.cc
@@ -4,6 +4,7 @@
#include "net/disk_cache/simple/simple_index_file.h"
+#include <utility>
#include <vector>
#include "base/files/file.h"
@@ -32,9 +33,9 @@ namespace {
const int kEntryFilesHashLength = 16;
const int kEntryFilesSuffixLength = 2;
-const uint64 kMaxEntiresInIndex = 100000000;
+const uint64_t kMaxEntiresInIndex = 100000000;
-uint32 CalculatePickleCRC(const base::Pickle& pickle) {
+uint32_t CalculatePickleCRC(const base::Pickle& pickle) {
return crc32(crc32(0, Z_NULL, 0),
reinterpret_cast<const Bytef*>(pickle.payload()),
pickle.payload_size());
@@ -72,7 +73,7 @@ void UmaRecordIndexInitMethod(IndexInitMethod method,
bool WritePickleFile(base::Pickle* pickle, const base::FilePath& file_name) {
File file(
file_name,
- File::FLAG_CREATE | File::FLAG_WRITE | File::FLAG_SHARE_DELETE);
+ File::FLAG_CREATE_ALWAYS | File::FLAG_WRITE | File::FLAG_SHARE_DELETE);
if (!file.IsValid())
return false;
@@ -98,7 +99,7 @@ void ProcessEntryFile(SimpleIndex::EntrySet* entries,
return;
const base::StringPiece hash_string(
file_name.begin(), file_name.begin() + kEntryFilesHashLength);
- uint64 hash_key = 0;
+ uint64_t hash_key = 0;
if (!simple_util::GetEntryHashKeyFromHexString(hash_string, &hash_key)) {
LOG(WARNING) << "Invalid entry hash key filename while restoring index from"
<< " disk: " << file_name;
@@ -119,7 +120,7 @@ void ProcessEntryFile(SimpleIndex::EntrySet* entries,
if (last_used_time.is_null())
last_used_time = file_info.last_modified;
- int64 file_size = file_info.size;
+ int64_t file_size = file_info.size;
SimpleIndex::EntrySet::iterator it = entries->find(hash_key);
if (it == entries->end()) {
SimpleIndex::InsertInEntrySet(
@@ -160,8 +161,8 @@ SimpleIndexFile::IndexMetadata::IndexMetadata()
number_of_entries_(0),
cache_size_(0) {}
-SimpleIndexFile::IndexMetadata::IndexMetadata(
- uint64 number_of_entries, uint64 cache_size)
+SimpleIndexFile::IndexMetadata::IndexMetadata(uint64_t number_of_entries,
+ uint64_t cache_size)
: magic_number_(kSimpleIndexMagicNumber),
version_(kSimpleVersion),
number_of_entries_(number_of_entries),
@@ -277,7 +278,7 @@ void SimpleIndexFile::LoadIndexEntries(base::Time cache_last_modified,
}
void SimpleIndexFile::WriteToDisk(const SimpleIndex::EntrySet& entry_set,
- uint64 cache_size,
+ uint64_t cache_size,
const base::TimeTicks& start,
bool app_on_background,
const base::Closure& callback) {
@@ -354,7 +355,7 @@ void SimpleIndexFile::SyncLoadFromDisk(const base::FilePath& index_filename,
return;
base::MemoryMappedFile index_file_map;
- if (!index_file_map.Initialize(file.Pass())) {
+ if (!index_file_map.Initialize(std::move(file))) {
simple_util::SimpleCacheDeleteFile(index_filename);
return;
}
@@ -382,7 +383,7 @@ scoped_ptr<base::Pickle> SimpleIndexFile::Serialize(
pickle->WriteUInt64(it->first);
it->second.Serialize(pickle.get());
}
- return pickle.Pass();
+ return pickle;
}
// static
@@ -403,8 +404,8 @@ void SimpleIndexFile::Deserialize(const char* data, int data_len,
base::PickleIterator pickle_it(pickle);
SimpleIndexFile::PickleHeader* header_p =
pickle.headerT<SimpleIndexFile::PickleHeader>();
- const uint32 crc_read = header_p->crc;
- const uint32 crc_calculated = CalculatePickleCRC(pickle);
+ const uint32_t crc_read = header_p->crc;
+ const uint32_t crc_calculated = CalculatePickleCRC(pickle);
if (crc_read != crc_calculated) {
LOG(WARNING) << "Invalid CRC in Simple Index file.";
@@ -427,7 +428,7 @@ void SimpleIndexFile::Deserialize(const char* data, int data_len,
entries->resize(index_metadata.GetNumberOfEntries() + kExtraSizeForMerge);
#endif
while (entries->size() < index_metadata.GetNumberOfEntries()) {
- uint64 hash_key;
+ uint64_t hash_key;
EntryMetadata entry_metadata;
if (!pickle_it.ReadUInt64(&hash_key) ||
!entry_metadata.Deserialize(&pickle_it)) {
@@ -438,7 +439,7 @@ void SimpleIndexFile::Deserialize(const char* data, int data_len,
SimpleIndex::InsertInEntrySet(hash_key, entry_metadata, entries);
}
- int64 cache_last_modified;
+ int64_t cache_last_modified;
if (!pickle_it.ReadInt64(&cache_last_modified)) {
entries->clear();
return;
diff --git a/chromium/net/disk_cache/simple/simple_index_file.h b/chromium/net/disk_cache/simple/simple_index_file.h
index b0ca1f553f0..eb13301168b 100644
--- a/chromium/net/disk_cache/simple/simple_index_file.h
+++ b/chromium/net/disk_cache/simple/simple_index_file.h
@@ -6,14 +6,15 @@
#define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_
#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
#include "net/base/cache_type.h"
@@ -27,7 +28,7 @@ class TaskRunner;
namespace disk_cache {
-const uint64 kSimpleIndexMagicNumber = UINT64_C(0x656e74657220796f);
+const uint64_t kSimpleIndexMagicNumber = UINT64_C(0x656e74657220796f);
struct NET_EXPORT_PRIVATE SimpleIndexLoadResult {
SimpleIndexLoadResult();
@@ -55,23 +56,23 @@ class NET_EXPORT_PRIVATE SimpleIndexFile {
class NET_EXPORT_PRIVATE IndexMetadata {
public:
IndexMetadata();
- IndexMetadata(uint64 number_of_entries, uint64 cache_size);
+ IndexMetadata(uint64_t number_of_entries, uint64_t cache_size);
void Serialize(base::Pickle* pickle) const;
bool Deserialize(base::PickleIterator* it);
bool CheckIndexMetadata();
- uint64 GetNumberOfEntries() { return number_of_entries_; }
+ uint64_t GetNumberOfEntries() { return number_of_entries_; }
private:
FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics);
FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize);
- uint64 magic_number_;
- uint32 version_;
- uint64 number_of_entries_;
- uint64 cache_size_; // Total cache storage size in bytes.
+ uint64_t magic_number_;
+ uint32_t version_;
+ uint64_t number_of_entries_;
+ uint64_t cache_size_; // Total cache storage size in bytes.
};
SimpleIndexFile(
@@ -88,7 +89,7 @@ class NET_EXPORT_PRIVATE SimpleIndexFile {
// Write the specified set of entries to disk.
virtual void WriteToDisk(const SimpleIndex::EntrySet& entry_set,
- uint64 cache_size,
+ uint64_t cache_size,
const base::TimeTicks& start,
bool app_on_background,
const base::Closure& callback);
@@ -169,7 +170,7 @@ class NET_EXPORT_PRIVATE SimpleIndexFile {
const base::FilePath& index_file_path);
struct PickleHeader : public base::Pickle::Header {
- uint32 crc;
+ uint32_t crc;
};
const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_;
diff --git a/chromium/net/disk_cache/simple/simple_index_file_unittest.cc b/chromium/net/disk_cache/simple/simple_index_file_unittest.cc
index ae4945a045b..3f1bca572dd 100644
--- a/chromium/net/disk_cache/simple/simple_index_file_unittest.cc
+++ b/chromium/net/disk_cache/simple/simple_index_file_unittest.cc
@@ -87,6 +87,10 @@ class WrappedSimpleIndexFile : public SimpleIndexFile {
return index_file_;
}
+ const base::FilePath& GetTempIndexFilePath() const {
+ return temp_index_file_;
+ }
+
bool CreateIndexFileDirectory() const {
return base::CreateDirectory(index_file_.DirName());
}
@@ -104,14 +108,14 @@ class SimpleIndexFileTest : public testing::Test {
TEST_F(SimpleIndexFileTest, Serialize) {
SimpleIndex::EntrySet entries;
- static const uint64 kHashes[] = { 11, 22, 33 };
+ static const uint64_t kHashes[] = {11, 22, 33};
static const size_t kNumHashes = arraysize(kHashes);
EntryMetadata metadata_entries[kNumHashes];
- SimpleIndexFile::IndexMetadata index_metadata(static_cast<uint64>(kNumHashes),
- 456);
+ SimpleIndexFile::IndexMetadata index_metadata(
+ static_cast<uint64_t>(kNumHashes), 456);
for (size_t i = 0; i < kNumHashes; ++i) {
- uint64 hash = kHashes[i];
+ uint64_t hash = kHashes[i];
metadata_entries[i] = EntryMetadata(Time(), hash);
SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries);
}
@@ -177,16 +181,16 @@ TEST_F(SimpleIndexFileTest, WriteThenLoadIndex) {
ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
SimpleIndex::EntrySet entries;
- static const uint64 kHashes[] = { 11, 22, 33 };
+ static const uint64_t kHashes[] = {11, 22, 33};
static const size_t kNumHashes = arraysize(kHashes);
EntryMetadata metadata_entries[kNumHashes];
for (size_t i = 0; i < kNumHashes; ++i) {
- uint64 hash = kHashes[i];
+ uint64_t hash = kHashes[i];
metadata_entries[i] = EntryMetadata(Time(), hash);
SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries);
}
- const uint64 kCacheSize = 456U;
+ const uint64_t kCacheSize = 456U;
net::TestClosure closure;
{
WrappedSimpleIndexFile simple_index_file(cache_dir.path());
@@ -288,8 +292,8 @@ TEST_F(SimpleIndexFileTest, SimpleCacheUpgrade) {
// thread after that.
MessageLoopHelper helper;
CallbackTest cb_shutdown(&helper, false);
- cache_thread.task_runner()->PostTask(
- FROM_HERE,
+ cache_thread.task_runner()->PostTaskAndReply(
+ FROM_HERE, base::Bind(&base::DoNothing),
base::Bind(&CallbackTest::Run, base::Unretained(&cb_shutdown), net::OK));
helper.WaitUntilCacheIoFinished(1);
@@ -310,6 +314,35 @@ TEST_F(SimpleIndexFileTest, SimpleCacheUpgrade) {
EXPECT_TRUE(deserialize_result.did_load);
}
+TEST_F(SimpleIndexFileTest, OverwritesStaleTempFile) {
+ base::ScopedTempDir cache_dir;
+ ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
+ const base::FilePath cache_path = cache_dir.path();
+ WrappedSimpleIndexFile simple_index_file(cache_path);
+ ASSERT_TRUE(simple_index_file.CreateIndexFileDirectory());
+
+ // Create an temporary index file.
+ const base::FilePath& temp_index_path =
+ simple_index_file.GetTempIndexFilePath();
+ const std::string kDummyData = "nothing to be seen here";
+ EXPECT_EQ(
+ static_cast<int>(kDummyData.size()),
+ base::WriteFile(temp_index_path, kDummyData.data(), kDummyData.size()));
+ ASSERT_TRUE(base::PathExists(simple_index_file.GetTempIndexFilePath()));
+
+ // Write the index file.
+ SimpleIndex::EntrySet entries;
+ SimpleIndex::InsertInEntrySet(11, EntryMetadata(Time(), 11), &entries);
+ net::TestClosure closure;
+ simple_index_file.WriteToDisk(entries, 120U, base::TimeTicks(), false,
+ closure.closure());
+ closure.WaitForResult();
+
+ // Check that the temporary file was deleted and the index file was created.
+ EXPECT_FALSE(base::PathExists(simple_index_file.GetTempIndexFilePath()));
+ EXPECT_TRUE(base::PathExists(simple_index_file.GetIndexFilePath()));
+}
+
#endif // defined(OS_POSIX)
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/simple/simple_index_unittest.cc b/chromium/net/disk_cache/simple/simple_index_unittest.cc
index 3741070d4df..649d48f538c 100644
--- a/chromium/net/disk_cache/simple/simple_index_unittest.cc
+++ b/chromium/net/disk_cache/simple/simple_index_unittest.cc
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "net/disk_cache/simple/simple_index.h"
+
#include <algorithm>
#include <functional>
+#include <utility>
#include "base/files/scoped_temp_dir.h"
#include "base/hash.h"
@@ -16,7 +19,6 @@
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "net/base/cache_type.h"
-#include "net/disk_cache/simple/simple_index.h"
#include "net/disk_cache/simple/simple_index_delegate.h"
#include "net/disk_cache/simple/simple_index_file.h"
#include "net/disk_cache/simple/simple_test_util.h"
@@ -28,7 +30,7 @@ namespace {
const base::Time kTestLastUsedTime =
base::Time::UnixEpoch() + base::TimeDelta::FromDays(20);
-const uint64 kTestEntrySize = 789;
+const uint64_t kTestEntrySize = 789;
} // namespace
@@ -66,7 +68,7 @@ class MockSimpleIndexFile : public SimpleIndexFile,
}
void WriteToDisk(const SimpleIndex::EntrySet& entry_set,
- uint64 cache_size,
+ uint64_t cache_size,
const base::TimeTicks& start,
bool app_on_background,
const base::Closure& callback) override {
@@ -97,7 +99,7 @@ class SimpleIndexTest : public testing::Test, public SimpleIndexDelegate {
: hashes_(base::Bind(&HashesInitializer)),
doom_entries_calls_(0) {}
- static uint64 HashesInitializer(size_t hash_index) {
+ static uint64_t HashesInitializer(size_t hash_index) {
return disk_cache::simple_util::GetEntryHashKey(
base::StringPrintf("key%d", static_cast<int>(hash_index)));
}
@@ -106,7 +108,7 @@ class SimpleIndexTest : public testing::Test, public SimpleIndexDelegate {
scoped_ptr<MockSimpleIndexFile> index_file(new MockSimpleIndexFile());
index_file_ = index_file->AsWeakPtr();
index_.reset(
- new SimpleIndex(NULL, this, net::DISK_CACHE, index_file.Pass()));
+ new SimpleIndex(NULL, this, net::DISK_CACHE, std::move(index_file)));
index_->Initialize(base::Time());
}
@@ -120,17 +122,16 @@ class SimpleIndexTest : public testing::Test, public SimpleIndexDelegate {
}
// From SimpleIndexDelegate:
- void DoomEntries(std::vector<uint64>* entry_hashes,
+ void DoomEntries(std::vector<uint64_t>* entry_hashes,
const net::CompletionCallback& callback) override {
- std::for_each(entry_hashes->begin(), entry_hashes->end(),
- std::bind1st(std::mem_fun(&SimpleIndex::Remove),
- index_.get()));
+ for (const uint64_t& entry_hash : *entry_hashes)
+ index_->Remove(entry_hash);
last_doom_entry_hashes_ = *entry_hashes;
++doom_entries_calls_;
}
// Redirect to allow single "friend" declaration in base class.
- bool GetEntryForTesting(uint64 key, EntryMetadata* metadata) {
+ bool GetEntryForTesting(uint64_t key, EntryMetadata* metadata) {
SimpleIndex::EntrySet::iterator it = index_->entries_set_.find(key);
if (index_->entries_set_.end() == it)
return false;
@@ -138,7 +139,7 @@ class SimpleIndexTest : public testing::Test, public SimpleIndexDelegate {
return true;
}
- void InsertIntoIndexFileReturn(uint64 hash_key,
+ void InsertIntoIndexFileReturn(uint64_t hash_key,
base::Time last_used_time,
int entry_size) {
index_file_->load_result()->entries.insert(std::make_pair(
@@ -154,17 +155,16 @@ class SimpleIndexTest : public testing::Test, public SimpleIndexDelegate {
SimpleIndex* index() { return index_.get(); }
const MockSimpleIndexFile* index_file() const { return index_file_.get(); }
- const std::vector<uint64>& last_doom_entry_hashes() const {
+ const std::vector<uint64_t>& last_doom_entry_hashes() const {
return last_doom_entry_hashes_;
}
int doom_entries_calls() const { return doom_entries_calls_; }
-
- const simple_util::ImmutableArray<uint64, 16> hashes_;
+ const simple_util::ImmutableArray<uint64_t, 16> hashes_;
scoped_ptr<SimpleIndex> index_;
base::WeakPtr<MockSimpleIndexFile> index_file_;
- std::vector<uint64> last_doom_entry_hashes_;
+ std::vector<uint64_t> last_doom_entry_hashes_;
int doom_entries_calls_;
};
@@ -209,19 +209,19 @@ TEST_F(SimpleIndexTest, IndexSizeCorrectOnMerge) {
{
scoped_ptr<SimpleIndexLoadResult> result(new SimpleIndexLoadResult());
result->did_load = true;
- index()->MergeInitializingSet(result.Pass());
+ index()->MergeInitializingSet(std::move(result));
}
EXPECT_EQ(9U, index()->cache_size_);
{
scoped_ptr<SimpleIndexLoadResult> result(new SimpleIndexLoadResult());
result->did_load = true;
- const uint64 new_hash_key = hashes_.at<11>();
+ const uint64_t new_hash_key = hashes_.at<11>();
result->entries.insert(
std::make_pair(new_hash_key, EntryMetadata(base::Time::Now(), 11)));
- const uint64 redundant_hash_key = hashes_.at<4>();
+ const uint64_t redundant_hash_key = hashes_.at<4>();
result->entries.insert(std::make_pair(redundant_hash_key,
EntryMetadata(base::Time::Now(), 4)));
- index()->MergeInitializingSet(result.Pass());
+ index()->MergeInitializingSet(std::move(result));
}
EXPECT_EQ(2U + 3U + 4U + 11U, index()->cache_size_);
}
@@ -255,7 +255,7 @@ TEST_F(SimpleIndexTest, Has) {
EXPECT_EQ(1, index_file_->load_index_entries_calls());
// Confirm "Has()" always returns true before the callback is called.
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
EXPECT_TRUE(index()->Has(kHash1));
index()->Insert(kHash1);
EXPECT_TRUE(index()->Has(kHash1));
@@ -279,7 +279,7 @@ TEST_F(SimpleIndexTest, UseIfExists) {
// Confirm "UseIfExists()" always returns true before the callback is called
// and updates mod time if the entry was really there.
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
EntryMetadata metadata1, metadata2;
EXPECT_TRUE(index()->UseIfExists(kHash1));
EXPECT_FALSE(GetEntryForTesting(kHash1, &metadata1));
@@ -318,7 +318,7 @@ TEST_F(SimpleIndexTest, UpdateEntrySize) {
index()->SetMaxSize(1000);
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
InsertIntoIndexFileReturn(kHash1, now - base::TimeDelta::FromDays(2), 475);
ReturnIndexFile();
@@ -396,7 +396,7 @@ TEST_F(SimpleIndexTest, BasicInit) {
// Remove something that's going to come in from the loaded index.
TEST_F(SimpleIndexTest, RemoveBeforeInit) {
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
index()->Remove(kHash1);
InsertIntoIndexFileReturn(kHash1,
@@ -410,7 +410,7 @@ TEST_F(SimpleIndexTest, RemoveBeforeInit) {
// Insert something that's going to come in from the loaded index; correct
// result?
TEST_F(SimpleIndexTest, InsertBeforeInit) {
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
index()->Insert(kHash1);
InsertIntoIndexFileReturn(kHash1,
@@ -428,7 +428,7 @@ TEST_F(SimpleIndexTest, InsertBeforeInit) {
// Insert and Remove something that's going to come in from the loaded index.
TEST_F(SimpleIndexTest, InsertRemoveBeforeInit) {
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
index()->Insert(kHash1);
index()->Remove(kHash1);
@@ -442,7 +442,7 @@ TEST_F(SimpleIndexTest, InsertRemoveBeforeInit) {
// Insert and Remove something that's going to come in from the loaded index.
TEST_F(SimpleIndexTest, RemoveInsertBeforeInit) {
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
index()->Remove(kHash1);
index()->Insert(kHash1);
@@ -556,7 +556,7 @@ TEST_F(SimpleIndexTest, DiskWriteQueued) {
EXPECT_FALSE(index()->write_to_disk_timer_.IsRunning());
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
index()->Insert(kHash1);
EXPECT_TRUE(index()->write_to_disk_timer_.IsRunning());
index()->write_to_disk_timer_.Stop();
@@ -581,7 +581,7 @@ TEST_F(SimpleIndexTest, DiskWriteExecuted) {
EXPECT_FALSE(index()->write_to_disk_timer_.IsRunning());
- const uint64 kHash1 = hashes_.at<1>();
+ const uint64_t kHash1 = hashes_.at<1>();
index()->Insert(kHash1);
index()->UpdateEntrySize(kHash1, 20);
EXPECT_TRUE(index()->write_to_disk_timer_.IsRunning());
@@ -594,7 +594,7 @@ TEST_F(SimpleIndexTest, DiskWriteExecuted) {
SimpleIndex::EntrySet entry_set;
index_file_->GetAndResetDiskWriteEntrySet(&entry_set);
- uint64 hash_key = kHash1;
+ uint64_t hash_key = kHash1;
base::Time now(base::Time::Now());
ASSERT_EQ(1u, entry_set.size());
EXPECT_EQ(hash_key, entry_set.begin()->first);
diff --git a/chromium/net/disk_cache/simple/simple_net_log_parameters.cc b/chromium/net/disk_cache/simple/simple_net_log_parameters.cc
index 8fe57f50d3a..46c678c2001 100644
--- a/chromium/net/disk_cache/simple/simple_net_log_parameters.cc
+++ b/chromium/net/disk_cache/simple/simple_net_log_parameters.cc
@@ -4,6 +4,8 @@
#include "net/disk_cache/simple/simple_net_log_parameters.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/format_macros.h"
@@ -21,7 +23,7 @@ scoped_ptr<base::Value> NetLogSimpleEntryConstructionCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("entry_hash",
base::StringPrintf("%#016" PRIx64, entry->entry_hash()));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSimpleEntryCreationCallback(
@@ -32,7 +34,7 @@ scoped_ptr<base::Value> NetLogSimpleEntryCreationCallback(
dict->SetInteger("net_error", net_error);
if (net_error == net::OK)
dict->SetString("key", entry->key());
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
diff --git a/chromium/net/disk_cache/simple/simple_synchronous_entry.cc b/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
index f6f0c71717d..3fdb3cca345 100644
--- a/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
+++ b/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -9,7 +9,6 @@
#include <functional>
#include <limits>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/hash.h"
@@ -125,8 +124,8 @@ using simple_util::GetFileIndexFromStreamIndex;
SimpleEntryStat::SimpleEntryStat(base::Time last_used,
base::Time last_modified,
- const int32 data_size[],
- const int32 sparse_data_size)
+ const int32_t data_size[],
+ const int32_t sparse_data_size)
: last_used_(last_used),
last_modified_(last_modified),
sparse_data_size_(sparse_data_size) {
@@ -156,9 +155,9 @@ int SimpleEntryStat::GetLastEOFOffsetInFile(const std::string& key,
return GetOffsetInFile(key, eof_data_offset, stream_index);
}
-int64 SimpleEntryStat::GetFileSize(const std::string& key,
- int file_index) const {
- const int32 total_data_size =
+int64_t SimpleEntryStat::GetFileSize(const std::string& key,
+ int file_index) const {
+ const int32_t total_data_size =
file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF)
: data_size_[2];
return GetFileSizeFromKeyAndDataSize(key, total_data_size);
@@ -182,10 +181,8 @@ SimpleSynchronousEntry::CRCRecord::CRCRecord() : index(-1),
SimpleSynchronousEntry::CRCRecord::CRCRecord(int index_p,
bool has_crc32_p,
- uint32 data_crc32_p)
- : index(index_p),
- has_crc32(has_crc32_p),
- data_crc32(data_crc32_p) {}
+ uint32_t data_crc32_p)
+ : index(index_p), has_crc32(has_crc32_p), data_crc32(data_crc32_p) {}
SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p,
int offset_p,
@@ -206,18 +203,17 @@ SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p,
doomed(doomed_p) {}
SimpleSynchronousEntry::EntryOperationData::EntryOperationData(
- int64 sparse_offset_p,
+ int64_t sparse_offset_p,
int buf_len_p)
- : sparse_offset(sparse_offset_p),
- buf_len(buf_len_p) {}
+ : sparse_offset(sparse_offset_p), buf_len(buf_len_p) {}
// static
void SimpleSynchronousEntry::OpenEntry(
net::CacheType cache_type,
const FilePath& path,
- const uint64 entry_hash,
+ const uint64_t entry_hash,
bool had_index,
- SimpleEntryCreationResults *out_results) {
+ SimpleEntryCreationResults* out_results) {
base::ElapsedTimer open_time;
SimpleSynchronousEntry* sync_entry =
new SimpleSynchronousEntry(cache_type, path, "", entry_hash);
@@ -242,9 +238,9 @@ void SimpleSynchronousEntry::CreateEntry(
net::CacheType cache_type,
const FilePath& path,
const std::string& key,
- const uint64 entry_hash,
+ const uint64_t entry_hash,
bool had_index,
- SimpleEntryCreationResults *out_results) {
+ SimpleEntryCreationResults* out_results) {
DCHECK_EQ(entry_hash, GetEntryHashKey(key));
SimpleSynchronousEntry* sync_entry =
new SimpleSynchronousEntry(cache_type, path, key, entry_hash);
@@ -261,31 +257,32 @@ void SimpleSynchronousEntry::CreateEntry(
}
// static
-int SimpleSynchronousEntry::DoomEntry(
- const FilePath& path,
- uint64 entry_hash) {
+int SimpleSynchronousEntry::DoomEntry(const FilePath& path,
+ uint64_t entry_hash) {
const bool deleted_well = DeleteFilesForEntryHash(path, entry_hash);
return deleted_well ? net::OK : net::ERR_FAILED;
}
// static
int SimpleSynchronousEntry::DoomEntrySet(
- const std::vector<uint64>* key_hashes,
+ const std::vector<uint64_t>* key_hashes,
const FilePath& path) {
const size_t did_delete_count = std::count_if(
- key_hashes->begin(), key_hashes->end(), std::bind1st(
- std::ptr_fun(SimpleSynchronousEntry::DeleteFilesForEntryHash), path));
+ key_hashes->begin(), key_hashes->end(),
+ [&path](const uint64_t& key_hash) {
+ return SimpleSynchronousEntry::DeleteFilesForEntryHash(path, key_hash);
+ });
return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED;
}
void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op,
net::IOBuffer* out_buf,
- uint32* out_crc32,
+ uint32_t* out_crc32,
SimpleEntryStat* entry_stat,
int* out_result) const {
DCHECK(initialized_);
DCHECK_NE(0, in_entry_op.index);
- const int64 file_offset =
+ const int64_t file_offset =
entry_stat->GetOffsetInFile(key_, in_entry_op.offset, in_entry_op.index);
int file_index = GetFileIndexFromStreamIndex(in_entry_op.index);
// Zero-length reads and reads to the empty streams of omitted files should
@@ -321,7 +318,7 @@ void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op,
int buf_len = in_entry_op.buf_len;
bool truncate = in_entry_op.truncate;
bool doomed = in_entry_op.doomed;
- const int64 file_offset = out_entry_stat->GetOffsetInFile(
+ const int64_t file_offset = out_entry_stat->GetOffsetInFile(
key_, in_entry_op.offset, in_entry_op.index);
bool extending_by_write = offset + buf_len > out_entry_stat->data_size(index);
@@ -354,7 +351,7 @@ void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op,
if (extending_by_write) {
// The EOF record and the eventual stream afterward need to be zeroed out.
- const int64 file_eof_offset =
+ const int64_t file_eof_offset =
out_entry_stat->GetEOFOffsetInFile(key_, index);
if (!files_[file_index].SetLength(file_eof_offset)) {
RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE);
@@ -399,7 +396,7 @@ void SimpleSynchronousEntry::ReadSparseData(
base::Time* out_last_used,
int* out_result) {
DCHECK(initialized_);
- int64 offset = in_entry_op.sparse_offset;
+ int64_t offset = in_entry_op.sparse_offset;
int buf_len = in_entry_op.buf_len;
char* buf = out_buf->data();
@@ -415,9 +412,10 @@ void SimpleSynchronousEntry::ReadSparseData(
DCHECK_EQ(it->first, found_range->offset);
if (found_range->offset + found_range->length > offset) {
DCHECK_GE(found_range->length, 0);
- DCHECK_LE(found_range->length, kint32max);
+ DCHECK_LE(found_range->length, std::numeric_limits<int32_t>::max());
DCHECK_GE(offset - found_range->offset, 0);
- DCHECK_LE(offset - found_range->offset, kint32max);
+ DCHECK_LE(offset - found_range->offset,
+ std::numeric_limits<int32_t>::max());
int net_offset = static_cast<int>(offset - found_range->offset);
int range_len_after_offset =
static_cast<int>(found_range->length - net_offset);
@@ -456,11 +454,11 @@ void SimpleSynchronousEntry::ReadSparseData(
void SimpleSynchronousEntry::WriteSparseData(
const EntryOperationData& in_entry_op,
net::IOBuffer* in_buf,
- uint64 max_sparse_data_size,
+ uint64_t max_sparse_data_size,
SimpleEntryStat* out_entry_stat,
int* out_result) {
DCHECK(initialized_);
- int64 offset = in_entry_op.sparse_offset;
+ int64_t offset = in_entry_op.sparse_offset;
int buf_len = in_entry_op.buf_len;
const char* buf = in_buf->data();
@@ -472,13 +470,14 @@ void SimpleSynchronousEntry::WriteSparseData(
return;
}
- uint64 sparse_data_size = out_entry_stat->sparse_data_size();
+ uint64_t sparse_data_size = out_entry_stat->sparse_data_size();
// This is a pessimistic estimate; it assumes the entire buffer is going to
// be appended as a new range, not written over existing ranges.
if (sparse_data_size + buf_len > max_sparse_data_size) {
DVLOG(1) << "Truncating sparse data file (" << sparse_data_size << " + "
<< buf_len << " > " << max_sparse_data_size << ")";
TruncateSparseFile();
+ out_entry_stat->set_sparse_data_size(0);
}
SparseRangeIterator it = sparse_ranges_.lower_bound(offset);
@@ -488,9 +487,10 @@ void SimpleSynchronousEntry::WriteSparseData(
SparseRange* found_range = &it->second;
if (found_range->offset + found_range->length > offset) {
DCHECK_GE(found_range->length, 0);
- DCHECK_LE(found_range->length, kint32max);
+ DCHECK_LE(found_range->length, std::numeric_limits<int32_t>::max());
DCHECK_GE(offset - found_range->offset, 0);
- DCHECK_LE(offset - found_range->offset, kint32max);
+ DCHECK_LE(offset - found_range->offset,
+ std::numeric_limits<int32_t>::max());
int net_offset = static_cast<int>(offset - found_range->offset);
int range_len_after_offset =
static_cast<int>(found_range->length - net_offset);
@@ -552,23 +552,23 @@ void SimpleSynchronousEntry::WriteSparseData(
base::Time modification_time = Time::Now();
out_entry_stat->set_last_used(modification_time);
out_entry_stat->set_last_modified(modification_time);
- int32 old_sparse_data_size = out_entry_stat->sparse_data_size();
+ int32_t old_sparse_data_size = out_entry_stat->sparse_data_size();
out_entry_stat->set_sparse_data_size(old_sparse_data_size + appended_so_far);
*out_result = written_so_far;
}
void SimpleSynchronousEntry::GetAvailableRange(
const EntryOperationData& in_entry_op,
- int64* out_start,
+ int64_t* out_start,
int* out_result) {
DCHECK(initialized_);
- int64 offset = in_entry_op.sparse_offset;
+ int64_t offset = in_entry_op.sparse_offset;
int len = in_entry_op.buf_len;
SparseRangeIterator it = sparse_ranges_.lower_bound(offset);
- int64 start = offset;
- int64 avail_so_far = 0;
+ int64_t start = offset;
+ int64_t avail_so_far = 0;
if (it != sparse_ranges_.end() && it->second.offset < offset + len)
start = it->second.offset;
@@ -590,17 +590,17 @@ void SimpleSynchronousEntry::GetAvailableRange(
++it;
}
- int64 len_from_start = len - (start - offset);
+ int64_t len_from_start = len - (start - offset);
*out_start = start;
*out_result = static_cast<int>(std::min(avail_so_far, len_from_start));
}
void SimpleSynchronousEntry::CheckEOFRecord(int index,
const SimpleEntryStat& entry_stat,
- uint32 expected_crc32,
+ uint32_t expected_crc32,
int* out_result) const {
DCHECK(initialized_);
- uint32 crc32;
+ uint32_t crc32;
bool has_crc32;
int stream_size;
*out_result =
@@ -674,11 +674,11 @@ void SimpleSynchronousEntry::Close(
continue;
files_[i].Close();
- const int64 file_size = entry_stat.GetFileSize(key_, i);
+ const int64_t file_size = entry_stat.GetFileSize(key_, i);
SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
"LastClusterSize", cache_type_,
file_size % 4096, 0, 4097, 50);
- const int64 cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0;
+ const int64_t cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0;
SIMPLE_CACHE_UMA(PERCENTAGE,
"LastClusterLossPercent", cache_type_,
static_cast<base::HistogramBase::Sample>(
@@ -701,7 +701,7 @@ void SimpleSynchronousEntry::Close(
SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type,
const FilePath& path,
const std::string& key,
- const uint64 entry_hash)
+ const uint64_t entry_hash)
: cache_type_(cache_type),
path_(path),
entry_hash_(entry_hash),
@@ -902,7 +902,7 @@ int SimpleSynchronousEntry::InitializeForOpen(
bool had_index,
SimpleEntryStat* out_entry_stat,
scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
- uint32* out_stream_0_crc32) {
+ uint32_t* out_stream_0_crc32) {
DCHECK(!initialized_);
if (!OpenFiles(had_index, out_entry_stat)) {
DLOG(WARNING) << "Could not open platform files for entry.";
@@ -971,7 +971,7 @@ int SimpleSynchronousEntry::InitializeForOpen(
}
}
- int32 sparse_data_size = 0;
+ int32_t sparse_data_size = 0;
if (!OpenSparseFileIfExists(&sparse_data_size)) {
RecordSyncOpenResult(
cache_type_, OPEN_ENTRY_SPARSE_OPEN_FAILED, had_index);
@@ -1053,14 +1053,14 @@ int SimpleSynchronousEntry::ReadAndValidateStream0(
int total_data_size,
SimpleEntryStat* out_entry_stat,
scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
- uint32* out_stream_0_crc32) const {
+ uint32_t* out_stream_0_crc32) const {
// Temporarily assign all the data size to stream 1 in order to read the
// EOF record for stream 0, which contains the size of stream 0.
out_entry_stat->set_data_size(0, 0);
out_entry_stat->set_data_size(1, total_data_size - sizeof(SimpleFileEOF));
bool has_crc32;
- uint32 read_crc32;
+ uint32_t read_crc32;
int stream_0_size;
int ret_value_crc32 = GetEOFRecordData(
0, *out_entry_stat, &has_crc32, &read_crc32, &stream_0_size);
@@ -1086,7 +1086,7 @@ int SimpleSynchronousEntry::ReadAndValidateStream0(
return net::ERR_FAILED;
// Check the CRC32.
- uint32 expected_crc32 =
+ uint32_t expected_crc32 =
stream_0_size == 0
? crc32(0, Z_NULL, 0)
: crc32(crc32(0, Z_NULL, 0),
@@ -1105,7 +1105,7 @@ int SimpleSynchronousEntry::ReadAndValidateStream0(
int SimpleSynchronousEntry::GetEOFRecordData(int index,
const SimpleEntryStat& entry_stat,
bool* out_has_crc32,
- uint32* out_crc32,
+ uint32_t* out_crc32,
int* out_data_size) const {
SimpleFileEOF eof_record;
int file_offset = entry_stat.GetEOFOffsetInFile(key_, index);
@@ -1137,10 +1137,9 @@ void SimpleSynchronousEntry::Doom() const {
}
// static
-bool SimpleSynchronousEntry::DeleteFileForEntryHash(
- const FilePath& path,
- const uint64 entry_hash,
- const int file_index) {
+bool SimpleSynchronousEntry::DeleteFileForEntryHash(const FilePath& path,
+ const uint64_t entry_hash,
+ const int file_index) {
FilePath to_delete = path.AppendASCII(
GetFilenameFromEntryHashAndFileIndex(entry_hash, file_index));
return simple_util::SimpleCacheDeleteFile(to_delete);
@@ -1149,7 +1148,7 @@ bool SimpleSynchronousEntry::DeleteFileForEntryHash(
// static
bool SimpleSynchronousEntry::DeleteFilesForEntryHash(
const FilePath& path,
- const uint64 entry_hash) {
+ const uint64_t entry_hash) {
bool result = true;
for (int i = 0; i < kSimpleEntryFileCount; ++i) {
if (!DeleteFileForEntryHash(path, entry_hash, i) && !CanOmitEmptyFile(i))
@@ -1183,7 +1182,7 @@ FilePath SimpleSynchronousEntry::GetFilenameFromFileIndex(int file_index) {
}
bool SimpleSynchronousEntry::OpenSparseFileIfExists(
- int32* out_sparse_data_size) {
+ int32_t* out_sparse_data_size) {
DCHECK(!sparse_file_open());
FilePath filename = path_.AppendASCII(
@@ -1219,13 +1218,14 @@ void SimpleSynchronousEntry::CloseSparseFile() {
bool SimpleSynchronousEntry::TruncateSparseFile() {
DCHECK(sparse_file_open());
- int64 header_and_key_length = sizeof(SimpleFileHeader) + key_.size();
+ int64_t header_and_key_length = sizeof(SimpleFileHeader) + key_.size();
if (!sparse_file_.SetLength(header_and_key_length)) {
DLOG(WARNING) << "Could not truncate sparse file";
return false;
}
sparse_ranges_.clear();
+ sparse_tail_offset_ = header_and_key_length;
return true;
}
@@ -1259,10 +1259,10 @@ bool SimpleSynchronousEntry::InitializeSparseFile() {
return true;
}
-bool SimpleSynchronousEntry::ScanSparseFile(int32* out_sparse_data_size) {
+bool SimpleSynchronousEntry::ScanSparseFile(int32_t* out_sparse_data_size) {
DCHECK(sparse_file_open());
- int64 sparse_data_size = 0;
+ int64_t sparse_data_size = 0;
SimpleFileHeader header;
int header_read_result =
@@ -1284,7 +1284,7 @@ bool SimpleSynchronousEntry::ScanSparseFile(int32* out_sparse_data_size) {
sparse_ranges_.clear();
- int64 range_header_offset = sizeof(header) + key_.size();
+ int64_t range_header_offset = sizeof(header) + key_.size();
while (1) {
SimpleFileSparseRangeHeader range_header;
int range_header_read_result =
@@ -1317,7 +1317,7 @@ bool SimpleSynchronousEntry::ScanSparseFile(int32* out_sparse_data_size) {
sparse_data_size += range.length;
}
- *out_sparse_data_size = static_cast<int32>(sparse_data_size);
+ *out_sparse_data_size = static_cast<int32_t>(sparse_data_size);
sparse_tail_offset_ = range_header_offset;
return true;
@@ -1338,9 +1338,8 @@ bool SimpleSynchronousEntry::ReadSparseRange(const SparseRange* range,
// If we read the whole range and we have a crc32, check it.
if (offset == 0 && len == range->length && range->data_crc32 != 0) {
- uint32 actual_crc32 = crc32(crc32(0L, Z_NULL, 0),
- reinterpret_cast<const Bytef*>(buf),
- len);
+ uint32_t actual_crc32 =
+ crc32(crc32(0L, Z_NULL, 0), reinterpret_cast<const Bytef*>(buf), len);
if (actual_crc32 != range->data_crc32) {
DLOG(WARNING) << "Sparse range crc32 mismatch.";
return false;
@@ -1359,7 +1358,7 @@ bool SimpleSynchronousEntry::WriteSparseRange(SparseRange* range,
DCHECK_LE(offset, range->length);
DCHECK_LE(offset + len, range->length);
- uint32 new_crc32 = 0;
+ uint32_t new_crc32 = 0;
if (offset == 0 && len == range->length) {
new_crc32 = crc32(crc32(0L, Z_NULL, 0),
reinterpret_cast<const Bytef*>(buf),
@@ -1393,16 +1392,15 @@ bool SimpleSynchronousEntry::WriteSparseRange(SparseRange* range,
return true;
}
-bool SimpleSynchronousEntry::AppendSparseRange(int64 offset,
+bool SimpleSynchronousEntry::AppendSparseRange(int64_t offset,
int len,
const char* buf) {
DCHECK_GE(offset, 0);
DCHECK_GT(len, 0);
DCHECK(buf);
- uint32 data_crc32 = crc32(crc32(0L, Z_NULL, 0),
- reinterpret_cast<const Bytef*>(buf),
- len);
+ uint32_t data_crc32 =
+ crc32(crc32(0L, Z_NULL, 0), reinterpret_cast<const Bytef*>(buf), len);
SimpleFileSparseRangeHeader header;
header.sparse_range_magic_number = kSimpleSparseRangeMagicNumber;
@@ -1424,7 +1422,7 @@ bool SimpleSynchronousEntry::AppendSparseRange(int64 offset,
DLOG(WARNING) << "Could not append sparse range data.";
return false;
}
- int64 data_file_offset = sparse_tail_offset_;
+ int64_t data_file_offset = sparse_tail_offset_;
sparse_tail_offset_ += bytes_written;
SparseRange range;
diff --git a/chromium/net/disk_cache/simple/simple_synchronous_entry.h b/chromium/net/disk_cache/simple/simple_synchronous_entry.h
index 7f98b21ceaa..6386a451235 100644
--- a/chromium/net/disk_cache/simple/simple_synchronous_entry.h
+++ b/chromium/net/disk_cache/simple/simple_synchronous_entry.h
@@ -5,6 +5,8 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
+#include <stdint.h>
+
#include <algorithm>
#include <map>
#include <string>
@@ -36,15 +38,15 @@ class NET_EXPORT_PRIVATE SimpleEntryStat {
public:
SimpleEntryStat(base::Time last_used,
base::Time last_modified,
- const int32 data_size[],
- const int32 sparse_data_size);
+ const int32_t data_size[],
+ const int32_t sparse_data_size);
int GetOffsetInFile(const std::string& key,
int offset,
int stream_index) const;
int GetEOFOffsetInFile(const std::string& key, int stream_index) const;
int GetLastEOFOffsetInFile(const std::string& key, int file_index) const;
- int64 GetFileSize(const std::string& key, int file_index) const;
+ int64_t GetFileSize(const std::string& key, int file_index) const;
base::Time last_used() const { return last_used_; }
base::Time last_modified() const { return last_modified_; }
@@ -53,21 +55,21 @@ class NET_EXPORT_PRIVATE SimpleEntryStat {
last_modified_ = last_modified;
}
- int32 data_size(int stream_index) const { return data_size_[stream_index]; }
+ int32_t data_size(int stream_index) const { return data_size_[stream_index]; }
void set_data_size(int stream_index, int data_size) {
data_size_[stream_index] = data_size;
}
- int32 sparse_data_size() const { return sparse_data_size_; }
- void set_sparse_data_size(int32 sparse_data_size) {
+ int32_t sparse_data_size() const { return sparse_data_size_; }
+ void set_sparse_data_size(int32_t sparse_data_size) {
sparse_data_size_ = sparse_data_size;
}
private:
base::Time last_used_;
base::Time last_modified_;
- int32 data_size_[kSimpleEntryStreamCount];
- int32 sparse_data_size_;
+ int32_t data_size_[kSimpleEntryStreamCount];
+ int32_t sparse_data_size_;
};
struct SimpleEntryCreationResults {
@@ -77,7 +79,7 @@ struct SimpleEntryCreationResults {
SimpleSynchronousEntry* sync_entry;
scoped_refptr<net::GrowableIOBuffer> stream_0_data;
SimpleEntryStat entry_stat;
- uint32 stream_0_crc32;
+ uint32_t stream_0_crc32;
int result;
};
@@ -88,11 +90,11 @@ class SimpleSynchronousEntry {
public:
struct CRCRecord {
CRCRecord();
- CRCRecord(int index_p, bool has_crc32_p, uint32 data_crc32_p);
+ CRCRecord(int index_p, bool has_crc32_p, uint32_t data_crc32_p);
int index;
bool has_crc32;
- uint32 data_crc32;
+ uint32_t data_crc32;
};
struct EntryOperationData {
@@ -102,11 +104,11 @@ class SimpleSynchronousEntry {
int buf_len_p,
bool truncate_p,
bool doomed_p);
- EntryOperationData(int64 sparse_offset_p, int buf_len_p);
+ EntryOperationData(int64_t sparse_offset_p, int buf_len_p);
int index;
int offset;
- int64 sparse_offset;
+ int64_t sparse_offset;
int buf_len;
bool truncate;
bool doomed;
@@ -114,33 +116,32 @@ class SimpleSynchronousEntry {
static void OpenEntry(net::CacheType cache_type,
const base::FilePath& path,
- uint64 entry_hash,
+ uint64_t entry_hash,
bool had_index,
SimpleEntryCreationResults* out_results);
static void CreateEntry(net::CacheType cache_type,
const base::FilePath& path,
const std::string& key,
- uint64 entry_hash,
+ uint64_t entry_hash,
bool had_index,
SimpleEntryCreationResults* out_results);
// Deletes an entry from the file system without affecting the state of the
// corresponding instance, if any (allowing operations to continue to be
// executed through that instance). Returns a net error code.
- static int DoomEntry(const base::FilePath& path,
- uint64 entry_hash);
+ static int DoomEntry(const base::FilePath& path, uint64_t entry_hash);
// Like |DoomEntry()| above. Deletes all entries corresponding to the
// |key_hashes|. Succeeds only when all entries are deleted. Returns a net
// error code.
- static int DoomEntrySet(const std::vector<uint64>* key_hashes,
+ static int DoomEntrySet(const std::vector<uint64_t>* key_hashes,
const base::FilePath& path);
// N.B. ReadData(), WriteData(), CheckEOFRecord() and Close() may block on IO.
void ReadData(const EntryOperationData& in_entry_op,
net::IOBuffer* out_buf,
- uint32* out_crc32,
+ uint32_t* out_crc32,
SimpleEntryStat* entry_stat,
int* out_result) const;
void WriteData(const EntryOperationData& in_entry_op,
@@ -149,7 +150,7 @@ class SimpleSynchronousEntry {
int* out_result);
void CheckEOFRecord(int index,
const SimpleEntryStat& entry_stat,
- uint32 expected_crc32,
+ uint32_t expected_crc32,
int* out_result) const;
void ReadSparseData(const EntryOperationData& in_entry_op,
@@ -158,11 +159,11 @@ class SimpleSynchronousEntry {
int* out_result);
void WriteSparseData(const EntryOperationData& in_entry_op,
net::IOBuffer* in_buf,
- uint64 max_sparse_data_size,
+ uint64_t max_sparse_data_size,
SimpleEntryStat* out_entry_stat,
int* out_result);
void GetAvailableRange(const EntryOperationData& in_entry_op,
- int64* out_start,
+ int64_t* out_start,
int* out_result);
// Close all streams, and add write EOF records to streams indicated by the
@@ -189,21 +190,20 @@ class SimpleSynchronousEntry {
};
struct SparseRange {
- int64 offset;
- int64 length;
- uint32 data_crc32;
- int64 file_offset;
+ int64_t offset;
+ int64_t length;
+ uint32_t data_crc32;
+ int64_t file_offset;
bool operator<(const SparseRange& other) const {
return offset < other.offset;
}
};
- SimpleSynchronousEntry(
- net::CacheType cache_type,
- const base::FilePath& path,
- const std::string& key,
- uint64 entry_hash);
+ SimpleSynchronousEntry(net::CacheType cache_type,
+ const base::FilePath& path,
+ const std::string& key,
+ uint64_t entry_hash);
// Like Entry, the SimpleSynchronousEntry self releases when Close() is
// called.
@@ -233,7 +233,7 @@ class SimpleSynchronousEntry {
int InitializeForOpen(bool had_index,
SimpleEntryStat* out_entry_stat,
scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
- uint32* out_stream_0_crc32);
+ uint32_t* out_stream_0_crc32);
// Writes the header and key to a newly-created stream file. |index| is the
// index of the stream. Returns true on success; returns false and sets
@@ -252,17 +252,17 @@ class SimpleSynchronousEntry {
int total_data_size,
SimpleEntryStat* out_entry_stat,
scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
- uint32* out_stream_0_crc32) const;
+ uint32_t* out_stream_0_crc32) const;
int GetEOFRecordData(int index,
const SimpleEntryStat& entry_stat,
bool* out_has_crc32,
- uint32* out_crc32,
+ uint32_t* out_crc32,
int* out_data_size) const;
void Doom() const;
// Opens the sparse data file and scans it if it exists.
- bool OpenSparseFileIfExists(int32* out_sparse_data_size);
+ bool OpenSparseFileIfExists(int32_t* out_sparse_data_size);
// Creates and initializes the sparse data file.
bool CreateSparseFile();
@@ -279,7 +279,7 @@ class SimpleSynchronousEntry {
// Scans the existing ranges in the sparse file. Populates |sparse_ranges_|
// and sets |*out_sparse_data_size| to the total size of all the ranges (not
// including headers).
- bool ScanSparseFile(int32* out_sparse_data_size);
+ bool ScanSparseFile(int32_t* out_sparse_data_size);
// Reads from a single sparse range. If asked to read the entire range, also
// verifies the CRC32.
@@ -292,13 +292,13 @@ class SimpleSynchronousEntry {
int offset, int len, const char* buf);
// Appends a new sparse range to the sparse data file.
- bool AppendSparseRange(int64 offset, int len, const char* buf);
+ bool AppendSparseRange(int64_t offset, int len, const char* buf);
static bool DeleteFileForEntryHash(const base::FilePath& path,
- uint64 entry_hash,
+ uint64_t entry_hash,
int file_index);
static bool DeleteFilesForEntryHash(const base::FilePath& path,
- uint64 entry_hash);
+ uint64_t entry_hash);
void RecordSyncCreateResult(CreateEntryResult result, bool had_index);
@@ -310,7 +310,7 @@ class SimpleSynchronousEntry {
const net::CacheType cache_type_;
const base::FilePath path_;
- const uint64 entry_hash_;
+ const uint64_t entry_hash_;
std::string key_;
bool have_open_files_;
@@ -322,13 +322,13 @@ class SimpleSynchronousEntry {
// was created to store it.
bool empty_file_omitted_[kSimpleEntryFileCount];
- typedef std::map<int64, SparseRange> SparseRangeOffsetMap;
+ typedef std::map<int64_t, SparseRange> SparseRangeOffsetMap;
typedef SparseRangeOffsetMap::iterator SparseRangeIterator;
SparseRangeOffsetMap sparse_ranges_;
base::File sparse_file_;
// Offset of the end of the sparse file (where the next sparse range will be
// written).
- int64 sparse_tail_offset_;
+ int64_t sparse_tail_offset_;
// True if the entry was created, or false if it was opened. Used to log
// SimpleCache.*.EntryCreatedWithStream2Omitted only for created entries.
diff --git a/chromium/net/disk_cache/simple/simple_test_util.h b/chromium/net/disk_cache/simple/simple_test_util.h
index ec9b64434c0..95ab0550e35 100644
--- a/chromium/net/disk_cache/simple/simple_test_util.h
+++ b/chromium/net/disk_cache/simple/simple_test_util.h
@@ -5,9 +5,10 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_TEST_UTIL_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_TEST_UTIL_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/callback.h"
namespace base {
diff --git a/chromium/net/disk_cache/simple/simple_util.cc b/chromium/net/disk_cache/simple/simple_util.cc
index d0e1ce5f995..a81c28ff4f6 100644
--- a/chromium/net/disk_cache/simple/simple_util.cc
+++ b/chromium/net/disk_cache/simple/simple_util.cc
@@ -19,8 +19,8 @@
namespace {
-// Size of the uint64 hash_key number in Hex format in a string.
-const size_t kEntryHashKeyAsHexStringSize = 2 * sizeof(uint64);
+// Size of the uint64_t hash_key number in Hex format in a string.
+const size_t kEntryHashKeyAsHexStringSize = 2 * sizeof(uint64_t);
#if defined(OS_POSIX)
// TODO(clamy, gavinp): this should go in base
@@ -51,7 +51,7 @@ namespace disk_cache {
namespace simple_util {
-std::string ConvertEntryHashKeyToHexString(uint64 hash_key) {
+std::string ConvertEntryHashKeyToHexString(uint64_t hash_key) {
const std::string hash_key_str = base::StringPrintf("%016" PRIx64, hash_key);
DCHECK_EQ(kEntryHashKeyAsHexStringSize, hash_key_str.size());
return hash_key_str;
@@ -65,29 +65,29 @@ std::string GetEntryHashKeyAsHexString(const std::string& key) {
}
bool GetEntryHashKeyFromHexString(const base::StringPiece& hash_key,
- uint64* hash_key_out) {
+ uint64_t* hash_key_out) {
if (hash_key.size() != kEntryHashKeyAsHexStringSize) {
return false;
}
return base::HexStringToUInt64(hash_key, hash_key_out);
}
-uint64 GetEntryHashKey(const std::string& key) {
+uint64_t GetEntryHashKey(const std::string& key) {
union {
unsigned char sha_hash[base::kSHA1Length];
- uint64 key_hash;
+ uint64_t key_hash;
} u;
base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(key.data()),
key.size(), u.sha_hash);
return u.key_hash;
}
-std::string GetFilenameFromEntryHashAndFileIndex(uint64 entry_hash,
+std::string GetFilenameFromEntryHashAndFileIndex(uint64_t entry_hash,
int file_index) {
return base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, file_index);
}
-std::string GetSparseFilenameFromEntryHash(uint64 entry_hash) {
+std::string GetSparseFilenameFromEntryHash(uint64_t entry_hash) {
return base::StringPrintf("%016" PRIx64 "_s", entry_hash);
}
@@ -97,13 +97,15 @@ std::string GetFilenameFromKeyAndFileIndex(const std::string& key,
base::StringPrintf("_%1d", file_index);
}
-int32 GetDataSizeFromKeyAndFileSize(const std::string& key, int64 file_size) {
- int64 data_size = file_size - key.size() - sizeof(SimpleFileHeader) -
- sizeof(SimpleFileEOF);
- return base::checked_cast<int32>(data_size);
+int32_t GetDataSizeFromKeyAndFileSize(const std::string& key,
+ int64_t file_size) {
+ int64_t data_size =
+ file_size - key.size() - sizeof(SimpleFileHeader) - sizeof(SimpleFileEOF);
+ return base::checked_cast<int32_t>(data_size);
}
-int64 GetFileSizeFromKeyAndDataSize(const std::string& key, int32 data_size) {
+int64_t GetFileSizeFromKeyAndDataSize(const std::string& key,
+ int32_t data_size) {
return data_size + key.size() + sizeof(SimpleFileHeader) +
sizeof(SimpleFileEOF);
}
@@ -123,7 +125,7 @@ bool GetMTime(const base::FilePath& path, base::Time* out_mtime) {
time_t sec;
long nsec;
if (GetNanoSecsFromStat(file_stat, &sec, &nsec)) {
- int64 usec = (nsec / base::Time::kNanosecondsPerMicrosecond);
+ int64_t usec = (nsec / base::Time::kNanosecondsPerMicrosecond);
*out_mtime = base::Time::FromTimeT(sec)
+ base::TimeDelta::FromMicroseconds(usec);
return true;
diff --git a/chromium/net/disk_cache/simple/simple_util.h b/chromium/net/disk_cache/simple/simple_util.h
index 24bfa0b4c3d..faf36b6a90c 100644
--- a/chromium/net/disk_cache/simple/simple_util.h
+++ b/chromium/net/disk_cache/simple/simple_util.h
@@ -5,9 +5,10 @@
#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_UTIL_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_UTIL_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -20,22 +21,23 @@ namespace disk_cache {
namespace simple_util {
-NET_EXPORT_PRIVATE std::string ConvertEntryHashKeyToHexString(uint64 hash_key);
+NET_EXPORT_PRIVATE std::string ConvertEntryHashKeyToHexString(
+ uint64_t hash_key);
// |key| is the regular cache key, such as an URL.
-// Returns the Hex ascii representation of the uint64 hash_key.
+// Returns the Hex ascii representation of the uint64_t hash_key.
NET_EXPORT_PRIVATE std::string GetEntryHashKeyAsHexString(
const std::string& key);
// |key| is the regular HTTP Cache key, which is a URL.
-// Returns the hash of the key as uint64.
-NET_EXPORT_PRIVATE uint64 GetEntryHashKey(const std::string& key);
+// Returns the hash of the key as uint64_t.
+NET_EXPORT_PRIVATE uint64_t GetEntryHashKey(const std::string& key);
-// Parses the |hash_key| string into a uint64 buffer.
+// Parses the |hash_key| string into a uint64_t buffer.
// |hash_key| string must be of the form: FFFFFFFFFFFFFFFF .
NET_EXPORT_PRIVATE bool GetEntryHashKeyFromHexString(
const base::StringPiece& hash_key,
- uint64* hash_key_out);
+ uint64_t* hash_key_out);
// Given a |key| for a (potential) entry in the simple backend and the |index|
// of a stream on that entry, returns the filename in which that stream would be
@@ -45,21 +47,21 @@ NET_EXPORT_PRIVATE std::string GetFilenameFromKeyAndFileIndex(
int file_index);
// Same as |GetFilenameFromKeyAndIndex| above, but using a hex string.
-std::string GetFilenameFromEntryHashAndFileIndex(uint64 entry_hash,
+std::string GetFilenameFromEntryHashAndFileIndex(uint64_t entry_hash,
int file_index);
// Given a |key| for an entry, returns the name of the sparse data file.
-std::string GetSparseFilenameFromEntryHash(uint64 entry_hash);
+std::string GetSparseFilenameFromEntryHash(uint64_t entry_hash);
// Given the size of a file holding a stream in the simple backend and the key
// to an entry, returns the number of bytes in the stream.
-NET_EXPORT_PRIVATE int32 GetDataSizeFromKeyAndFileSize(const std::string& key,
- int64 file_size);
+NET_EXPORT_PRIVATE int32_t GetDataSizeFromKeyAndFileSize(const std::string& key,
+ int64_t file_size);
// Given the size of a stream in the simple backend and the key to an entry,
// returns the number of bytes in the file.
-NET_EXPORT_PRIVATE int64 GetFileSizeFromKeyAndDataSize(const std::string& key,
- int32 data_size);
+NET_EXPORT_PRIVATE int64_t GetFileSizeFromKeyAndDataSize(const std::string& key,
+ int32_t data_size);
// Given the stream index, returns the number of the file the stream is stored
// in.
diff --git a/chromium/net/disk_cache/simple/simple_util_unittest.cc b/chromium/net/disk_cache/simple/simple_util_unittest.cc
index fbda55ca8a7..2956f27f17d 100644
--- a/chromium/net/disk_cache/simple/simple_util_unittest.cc
+++ b/chromium/net/disk_cache/simple/simple_util_unittest.cc
@@ -47,7 +47,7 @@ TEST_F(SimpleUtilTest, GetEntryHashKey) {
}
TEST_F(SimpleUtilTest, GetEntryHashKeyFromHexString) {
- uint64 hash_key = 0;
+ uint64_t hash_key = 0;
EXPECT_TRUE(GetEntryHashKeyFromHexString("0000000005f5e0ff", &hash_key));
EXPECT_EQ(UINT64_C(99999999), hash_key);
diff --git a/chromium/net/disk_cache/simple/simple_version_upgrade.cc b/chromium/net/disk_cache/simple/simple_version_upgrade.cc
index c20a1ba71bf..91d1b9c5f35 100644
--- a/chromium/net/disk_cache/simple/simple_version_upgrade.cc
+++ b/chromium/net/disk_cache/simple/simple_version_upgrade.cc
@@ -20,7 +20,7 @@ namespace {
// It is not possible to upgrade cache structures on disk that are of version
// below this, the entire cache should be dropped for them.
-const uint32 kMinVersionAbleToUpgrade = 5;
+const uint32_t kMinVersionAbleToUpgrade = 5;
const char kFakeIndexFileName[] = "index";
const char kIndexFileName[] = "the-real-index";
@@ -155,7 +155,7 @@ bool UpgradeSimpleCacheOnDisk(const base::FilePath& path) {
}
fake_index_file.Close();
- uint32 version_from = file_header.version;
+ uint32_t version_from = file_header.version;
if (version_from < kMinVersionAbleToUpgrade ||
version_from > kSimpleVersion) {
LOG(ERROR) << "Inconsistent cache version.";
diff --git a/chromium/net/disk_cache/simple/simple_version_upgrade.h b/chromium/net/disk_cache/simple/simple_version_upgrade.h
index 352379b997b..f8fa119f0e4 100644
--- a/chromium/net/disk_cache/simple/simple_version_upgrade.h
+++ b/chromium/net/disk_cache/simple/simple_version_upgrade.h
@@ -9,7 +9,8 @@
// Backend on disk. Assumes no backend operations are running simultaneously.
// Hence must be run at cache initialization step.
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "net/base/net_export.h"
namespace base {
@@ -33,13 +34,13 @@ struct NET_EXPORT_PRIVATE FakeIndexData {
FakeIndexData();
// Must be equal to simplecache_v4::kSimpleInitialMagicNumber.
- uint64 initial_magic_number;
+ uint64_t initial_magic_number;
// Must be equal kSimpleVersion when the cache backend is instantiated.
- uint32 version;
+ uint32_t version;
- uint32 unused_must_be_zero1;
- uint32 unused_must_be_zero2;
+ uint32_t unused_must_be_zero1;
+ uint32_t unused_must_be_zero2;
};
// Exposed for testing.
diff --git a/chromium/net/disk_cache/simple/simple_version_upgrade_unittest.cc b/chromium/net/disk_cache/simple/simple_version_upgrade_unittest.cc
index 0a8d8c9a79d..4aef6f1b4d4 100644
--- a/chromium/net/disk_cache/simple/simple_version_upgrade_unittest.cc
+++ b/chromium/net/disk_cache/simple/simple_version_upgrade_unittest.cc
@@ -6,7 +6,6 @@
#include <stdint.h>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
@@ -24,7 +23,7 @@
namespace {
// Same as |disk_cache::kSimpleInitialMagicNumber|.
-const uint64 kSimpleInitialMagicNumber = UINT64_C(0xfcfb6d1ba7725c30);
+const uint64_t kSimpleInitialMagicNumber = UINT64_C(0xfcfb6d1ba7725c30);
// The "fake index" file that cache backends use to distinguish whether the
// cache belongs to one backend or another.
@@ -102,14 +101,14 @@ TEST(SimpleVersionUpgradeTest, UpgradeV5V6IndexMustDisappear) {
base::WriteFile(index_file, file_contents.data(), file_contents.size()));
// Create a few entry-like files.
- const uint64 kEntries = 5;
- for (uint64 entry_hash = 0; entry_hash < kEntries; ++entry_hash) {
+ const uint64_t kEntries = 5;
+ for (uint64_t entry_hash = 0; entry_hash < kEntries; ++entry_hash) {
for (int index = 0; index < 3; ++index) {
std::string file_name =
base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, index);
std::string entry_contents =
file_contents +
- base::StringPrintf(" %" PRIx64, static_cast<uint64>(entry_hash));
+ base::StringPrintf(" %" PRIx64, static_cast<uint64_t>(entry_hash));
ASSERT_EQ(static_cast<int>(entry_contents.size()),
base::WriteFile(cache_path.AppendASCII(file_name),
entry_contents.data(), entry_contents.size()));
@@ -121,13 +120,13 @@ TEST(SimpleVersionUpgradeTest, UpgradeV5V6IndexMustDisappear) {
// Check that the old index disappeared but the files remain unchanged.
EXPECT_FALSE(base::PathExists(index_file));
- for (uint64 entry_hash = 0; entry_hash < kEntries; ++entry_hash) {
+ for (uint64_t entry_hash = 0; entry_hash < kEntries; ++entry_hash) {
for (int index = 0; index < 3; ++index) {
std::string file_name =
base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, index);
std::string expected_contents =
file_contents +
- base::StringPrintf(" %" PRIx64, static_cast<uint64>(entry_hash));
+ base::StringPrintf(" %" PRIx64, static_cast<uint64_t>(entry_hash));
std::string real_contents;
EXPECT_TRUE(base::ReadFileToString(cache_path.AppendASCII(file_name),
&real_contents));
diff --git a/chromium/net/dns/address_sorter.h b/chromium/net/dns/address_sorter.h
index 6ac943086ef..31115a617a6 100644
--- a/chromium/net/dns/address_sorter.h
+++ b/chromium/net/dns/address_sorter.h
@@ -5,8 +5,8 @@
#ifndef NET_DNS_ADDRESS_SORTER_H_
#define NET_DNS_ADDRESS_SORTER_H_
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/dns/address_sorter_posix.cc b/chromium/net/dns/address_sorter_posix.cc
index 9bbe835ebc8..f0a04225c35 100644
--- a/chromium/net/dns/address_sorter_posix.cc
+++ b/chromium/net/dns/address_sorter_posix.cc
@@ -5,6 +5,7 @@
#include "net/dns/address_sorter_posix.h"
#include <netinet/in.h>
+#include <utility>
#if defined(OS_MACOSX) || defined(OS_BSD)
#include <sys/socket.h> // Must be included before ifaddrs.h.
@@ -16,9 +17,10 @@
#endif
#include <algorithm>
+#include <vector>
#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "net/base/net_errors.h"
#include "net/socket/client_socket_factory.h"
#include "net/udp/datagram_client_socket.h"
@@ -186,8 +188,8 @@ struct DestinationInfo {
// Returns true iff |dst_a| should precede |dst_b| in the address list.
// RFC 3484, section 6.
-bool CompareDestinations(const DestinationInfo* dst_a,
- const DestinationInfo* dst_b) {
+bool CompareDestinations(const scoped_ptr<DestinationInfo>& dst_a,
+ const scoped_ptr<DestinationInfo>& dst_b) {
// Rule 1: Avoid unusable destinations.
// Unusable destinations are already filtered out.
DCHECK(dst_a->src);
@@ -257,7 +259,7 @@ AddressSorterPosix::~AddressSorterPosix() {
void AddressSorterPosix::Sort(const AddressList& list,
const CallbackType& callback) const {
DCHECK(CalledOnValidThread());
- ScopedVector<DestinationInfo> sort_list;
+ std::vector<scoped_ptr<DestinationInfo>> sort_list;
for (size_t i = 0; i < list.size(); ++i) {
scoped_ptr<DestinationInfo> info(new DestinationInfo());
@@ -304,7 +306,7 @@ void AddressSorterPosix::Sort(const AddressList& list,
CommonPrefixLength(info->address, src.address()),
info->src->prefix_length);
}
- sort_list.push_back(info.Pass());
+ sort_list.push_back(std::move(info));
}
std::stable_sort(sort_list.begin(), sort_list.end(), CompareDestinations);
diff --git a/chromium/net/dns/address_sorter_posix.h b/chromium/net/dns/address_sorter_posix.h
index d23f0497b9f..06d2dd8dd5f 100644
--- a/chromium/net/dns/address_sorter_posix.h
+++ b/chromium/net/dns/address_sorter_posix.h
@@ -8,6 +8,7 @@
#include <map>
#include <vector>
+#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "net/base/address_list.h"
#include "net/base/ip_address_number.h"
diff --git a/chromium/net/dns/address_sorter_posix_unittest.cc b/chromium/net/dns/address_sorter_posix_unittest.cc
index 88a135fef9d..13778ebefee 100644
--- a/chromium/net/dns/address_sorter_posix_unittest.cc
+++ b/chromium/net/dns/address_sorter_posix_unittest.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/base/test_completion_callback.h"
@@ -43,8 +44,8 @@ class TestUDPClientSocket : public DatagramClientSocket {
NOTIMPLEMENTED();
return OK;
}
- int SetReceiveBufferSize(int32) override { return OK; }
- int SetSendBufferSize(int32) override { return OK; }
+ int SetReceiveBufferSize(int32_t) override { return OK; }
+ int SetSendBufferSize(int32_t) override { return OK; }
void Close() override {}
int GetPeerAddress(IPEndPoint* address) const override {
@@ -57,6 +58,17 @@ class TestUDPClientSocket : public DatagramClientSocket {
*address = local_endpoint_;
return OK;
}
+ int BindToNetwork(NetworkChangeNotifier::NetworkHandle network) override {
+ NOTIMPLEMENTED();
+ return ERR_NOT_IMPLEMENTED;
+ }
+ int BindToDefaultNetwork() override {
+ NOTIMPLEMENTED();
+ return ERR_NOT_IMPLEMENTED;
+ }
+ NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override {
+ return NetworkChangeNotifier::kInvalidNetworkHandle;
+ }
int Connect(const IPEndPoint& remote) override {
if (connected_)
diff --git a/chromium/net/dns/address_sorter_win.cc b/chromium/net/dns/address_sorter_win.cc
index 8d97a41111b..816b42d0b44 100644
--- a/chromium/net/dns/address_sorter_win.cc
+++ b/chromium/net/dns/address_sorter_win.cc
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/threading/worker_pool.h"
#include "base/win/windows_version.h"
#include "net/base/address_list.h"
@@ -109,8 +110,11 @@ class AddressSorterWin : public AddressSorter {
list.reserve(output_buffer_->iAddressCount);
for (int i = 0; i < output_buffer_->iAddressCount; ++i) {
IPEndPoint ipe;
- ipe.FromSockAddr(output_buffer_->Address[i].lpSockaddr,
- output_buffer_->Address[i].iSockaddrLength);
+ bool result =
+ ipe.FromSockAddr(output_buffer_->Address[i].lpSockaddr,
+ output_buffer_->Address[i].iSockaddrLength);
+ DCHECK(result) << "Unable to roundtrip between IPEndPoint and "
+ << "SOCKET_ADDRESS!";
// Unmap V4MAPPED IPv6 addresses so that Happy Eyeballs works.
if (IsIPv4Mapped(ipe.address())) {
ipe = IPEndPoint(ConvertIPv4MappedToIPv4(ipe.address()),
diff --git a/chromium/net/dns/dns_client.cc b/chromium/net/dns/dns_client.cc
index 062894ad703..a9531523ae3 100644
--- a/chromium/net/dns/dns_client.cc
+++ b/chromium/net/dns/dns_client.cc
@@ -4,6 +4,8 @@
#include "net/dns/dns_client.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/rand_util.h"
#include "net/dns/address_sorter.h"
@@ -32,10 +34,8 @@ class DnsClientImpl : public DnsClient {
scoped_ptr<DnsSocketPool> socket_pool(
config.randomize_ports ? DnsSocketPool::CreateDefault(factory)
: DnsSocketPool::CreateNull(factory));
- session_ = new DnsSession(config,
- socket_pool.Pass(),
- base::Bind(&base::RandInt),
- net_log_);
+ session_ = new DnsSession(config, std::move(socket_pool),
+ base::Bind(&base::RandInt), net_log_);
factory_ = DnsTransactionFactory::CreateFactory(session_.get());
}
}
diff --git a/chromium/net/dns/dns_config_service.cc b/chromium/net/dns/dns_config_service.cc
index 447f7083c1f..fbb429ade1e 100644
--- a/chromium/net/dns/dns_config_service.cc
+++ b/chromium/net/dns/dns_config_service.cc
@@ -138,7 +138,7 @@ void DnsConfig::CopyIgnoreHosts(const DnsConfig& d) {
use_local_ipv6 = d.use_local_ipv6;
}
-base::Value* DnsConfig::ToValue() const {
+scoped_ptr<base::Value> DnsConfig::ToValue() const {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
base::ListValue* list = new base::ListValue();
@@ -161,7 +161,7 @@ base::Value* DnsConfig::ToValue() const {
dict->SetBoolean("use_local_ipv6", use_local_ipv6);
dict->SetInteger("num_hosts", hosts.size());
- return dict.release();
+ return std::move(dict);
}
DnsConfigService::DnsConfigService()
diff --git a/chromium/net/dns/dns_config_service.h b/chromium/net/dns/dns_config_service.h
index 10d93ac13cf..fbbdb415e88 100644
--- a/chromium/net/dns/dns_config_service.h
+++ b/chromium/net/dns/dns_config_service.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/threading/non_thread_safe.h"
@@ -73,10 +74,9 @@ struct NET_EXPORT_PRIVATE DnsConfig {
void CopyIgnoreHosts(const DnsConfig& src);
- // Returns a Value representation of |this|. Caller takes ownership of the
- // returned Value. For performance reasons, the Value only contains the
- // number of hosts rather than the full list.
- base::Value* ToValue() const;
+ // Returns a Value representation of |this|. For performance reasons, the
+ // Value only contains the number of hosts rather than the full list.
+ scoped_ptr<base::Value> ToValue() const;
bool IsValid() const {
return !nameservers.empty();
diff --git a/chromium/net/dns/dns_config_service_posix.cc b/chromium/net/dns/dns_config_service_posix.cc
index 4300dfc420a..31a40616b05 100644
--- a/chromium/net/dns/dns_config_service_posix.cc
+++ b/chromium/net/dns/dns_config_service_posix.cc
@@ -6,13 +6,13 @@
#include <string>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
#include "base/lazy_instance.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
@@ -266,13 +266,17 @@ class DnsConfigServicePosix::Watcher {
class DnsConfigServicePosix::ConfigReader : public SerialWorker {
public:
explicit ConfigReader(DnsConfigServicePosix* service)
- : service_(service), success_(false) {}
+ : service_(service), success_(false) {
+ const DnsConfig* test_config = service->dns_config_for_testing_;
+ if (test_config)
+ dns_config_for_testing_.reset(new DnsConfig(*test_config));
+ }
void DoWork() override {
base::TimeTicks start_time = base::TimeTicks::Now();
ConfigParsePosixResult result = ReadDnsConfig(&dns_config_);
- if (service_->dns_config_for_testing_) {
- dns_config_ = *service_->dns_config_for_testing_;
+ if (dns_config_for_testing_) {
+ dns_config_ = *dns_config_for_testing_;
result = CONFIG_PARSE_POSIX_OK;
}
switch (result) {
@@ -306,7 +310,12 @@ class DnsConfigServicePosix::ConfigReader : public SerialWorker {
private:
~ConfigReader() override {}
- DnsConfigServicePosix* service_;
+ // Raw pointer to owning DnsConfigService. This must never be accessed inside
+ // DoWork(), since service may be destroyed while SerialWorker is running
+ // on worker thread.
+ DnsConfigServicePosix* const service_;
+ // Dns config value to always return for testing.
+ scoped_ptr<const DnsConfig> dns_config_for_testing_;
// Written in DoWork, read in OnWorkFinished, no locking necessary.
DnsConfig dns_config_;
bool success_;
@@ -318,15 +327,16 @@ class DnsConfigServicePosix::ConfigReader : public SerialWorker {
class DnsConfigServicePosix::HostsReader : public SerialWorker {
public:
explicit HostsReader(DnsConfigServicePosix* service)
- : service_(service), success_(false) {}
+ : service_(service),
+ file_path_hosts_(service->file_path_hosts_),
+ success_(false) {}
private:
~HostsReader() override {}
void DoWork() override {
base::TimeTicks start_time = base::TimeTicks::Now();
- success_ =
- ParseHostsFile(base::FilePath(service_->file_path_hosts_), &hosts_);
+ success_ = ParseHostsFile(file_path_hosts_, &hosts_);
UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_);
UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration",
base::TimeTicks::Now() - start_time);
@@ -340,7 +350,12 @@ class DnsConfigServicePosix::HostsReader : public SerialWorker {
}
}
- DnsConfigServicePosix* service_;
+ // Raw pointer to owning DnsConfigService. This must never be accessed inside
+ // DoWork(), since service may be destroyed while SerialWorker is running
+ // on worker thread.
+ DnsConfigServicePosix* const service_;
+ // Hosts file path to parse.
+ const base::FilePath file_path_hosts_;
// Written in DoWork, read in OnWorkFinished, no locking necessary.
DnsHosts hosts_;
bool success_;
@@ -349,8 +364,8 @@ class DnsConfigServicePosix::HostsReader : public SerialWorker {
};
DnsConfigServicePosix::DnsConfigServicePosix()
- : file_path_hosts_(kFilePathHosts),
- dns_config_for_testing_(nullptr),
+ : file_path_hosts_(kFilePathHosts), // Must set before |hosts_reader_|
+ dns_config_for_testing_(nullptr), // Must set before |config_reader_|
config_reader_(new ConfigReader(this)),
hosts_reader_(new HostsReader(this))
#if defined(OS_ANDROID)
@@ -408,6 +423,23 @@ void DnsConfigServicePosix::SetDnsConfigForTesting(
const DnsConfig* dns_config) {
DCHECK(CalledOnValidThread());
dns_config_for_testing_ = dns_config;
+ // Reset ConfigReader to bind new DnsConfig for testing.
+ config_reader_->Cancel();
+ config_reader_ = make_scoped_refptr(new ConfigReader(this));
+}
+
+void DnsConfigServicePosix::SetHostsFilePathForTesting(
+ const base::FilePath::CharType* file_path) {
+ DCHECK(CalledOnValidThread());
+ file_path_hosts_ = file_path;
+ // Reset HostsReader to bind new hosts file path.
+ hosts_reader_->Cancel();
+ hosts_reader_ = make_scoped_refptr(new HostsReader(this));
+ // If watching, reset to bind new hosts file path and resume watching.
+ if (watcher_) {
+ watcher_.reset(new Watcher(this));
+ watcher_->Watch();
+ }
}
#if !defined(OS_ANDROID)
diff --git a/chromium/net/dns/dns_config_service_posix.h b/chromium/net/dns/dns_config_service_posix.h
index 0db525dfd6f..18cb5a0c327 100644
--- a/chromium/net/dns/dns_config_service_posix.h
+++ b/chromium/net/dns/dns_config_service_posix.h
@@ -13,6 +13,7 @@
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
#include "net/dns/dns_config_service.h"
@@ -48,6 +49,7 @@ class NET_EXPORT_PRIVATE DnsConfigServicePosix : public DnsConfigService {
#endif
void SetDnsConfigForTesting(const DnsConfig* dns_config);
+ void SetHostsFilePathForTesting(const base::FilePath::CharType* file_path);
protected:
// DnsConfigService:
@@ -55,7 +57,6 @@ class NET_EXPORT_PRIVATE DnsConfigServicePosix : public DnsConfigService {
bool StartWatching() override;
private:
- friend class DnsConfigServicePosixTest;
class Watcher;
class ConfigReader;
class HostsReader;
diff --git a/chromium/net/dns/dns_config_service_posix_unittest.cc b/chromium/net/dns/dns_config_service_posix_unittest.cc
index 4a9937014e2..04384d47a23 100644
--- a/chromium/net/dns/dns_config_service_posix_unittest.cc
+++ b/chromium/net/dns/dns_config_service_posix_unittest.cc
@@ -18,6 +18,13 @@
#include "base/android/path_utils.h"
#endif // defined(OS_ANDROID)
+// Required for inet_pton()
+#if defined(OS_WIN)
+#include <winsock2.h>
+#else
+#include <arpa/inet.h>
+#endif
+
namespace net {
#if !defined(OS_ANDROID)
@@ -41,6 +48,10 @@ const char* const kNameserversIPv6[] = {
};
#endif
+void DummyConfigCallback(const DnsConfig& config) {
+ // Do nothing
+}
+
// Fills in |res| with sane configuration.
void InitializeResState(res_state res) {
memset(res, 0, sizeof(*res));
@@ -164,6 +175,16 @@ TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) {
internal::ConvertResStateToDnsConfig(res, &config));
}
+TEST(DnsConfigServicePosixTest, DestroyWhileJobsWorking) {
+ // Regression test to verify crash does not occur if DnsConfigServicePosix
+ // instance is destroyed while SerialWorker jobs have posted to worker pool.
+ scoped_ptr<internal::DnsConfigServicePosix> service(
+ new internal::DnsConfigServicePosix());
+ service->ReadConfig(base::Bind(&DummyConfigCallback));
+ service.reset();
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1000));
+}
+
} // namespace
#else // OS_ANDROID
@@ -181,7 +202,7 @@ class DnsConfigServicePosixTest : public testing::Test {
void OnConfigChanged(const DnsConfig& config) {
EXPECT_TRUE(config.IsValid());
seen_config_ = true;
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
void WriteMockHostsFile(const char* hosts_string) {
@@ -198,6 +219,10 @@ class DnsConfigServicePosixTest : public testing::Test {
service_->SetDnsConfigForTesting(&test_config_);
}
+ void MockHostsFilePath(const char* file_path) {
+ service_->SetHostsFilePathForTesting(file_path);
+ }
+
void SetUp() override {
// TODO(pauljensen): Get rid of GetExternalStorageDirectory() when
// crbug.com/475568 is fixed. For now creating a temp file in the
@@ -226,7 +251,7 @@ class DnsConfigServicePosixTest : public testing::Test {
void StartWatching() {
creation_time_ = base::Time::Now();
service_.reset(new DnsConfigServicePosix());
- service_->file_path_hosts_ = temp_file_.value().c_str();
+ MockHostsFilePath(temp_file_.value().c_str());
MockDNSConfig("8.8.8.8");
seen_config_ = false;
service_->WatchConfig(base::Bind(
diff --git a/chromium/net/dns/dns_config_service_unittest.cc b/chromium/net/dns/dns_config_service_unittest.cc
index ed6d86d7a99..40796adfb16 100644
--- a/chromium/net/dns/dns_config_service_unittest.cc
+++ b/chromium/net/dns/dns_config_service_unittest.cc
@@ -4,7 +4,6 @@
#include "net/dns/dns_config_service.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/cancelable_callback.h"
#include "base/location.h"
@@ -115,7 +114,7 @@ class DnsConfigServiceTest : public testing::Test {
void OnConfigChanged(const DnsConfig& config) {
last_config_ = config;
if (quit_on_config_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
protected:
@@ -147,7 +146,7 @@ class DnsConfigServiceTest : public testing::Test {
};
void WaitForConfig(base::TimeDelta timeout) {
- base::CancelableClosure closure(base::MessageLoop::QuitClosure());
+ base::CancelableClosure closure(base::MessageLoop::QuitWhenIdleClosure());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, closure.callback(), timeout);
quit_on_config_ = true;
diff --git a/chromium/net/dns/dns_config_service_win.cc b/chromium/net/dns/dns_config_service_win.cc
index 443ee27ff7f..8c3192d90ba 100644
--- a/chromium/net/dns/dns_config_service_win.cc
+++ b/chromium/net/dns/dns_config_service_win.cc
@@ -13,6 +13,7 @@
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
@@ -333,7 +334,7 @@ class RegistryWatcher : public base::NonThreadSafe {
bool IsStatelessDiscoveryAddress(const IPAddressNumber& address) {
if (address.size() != kIPv6AddressSize)
return false;
- const uint8 kPrefix[] = {
+ const uint8_t kPrefix[] = {
0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
diff --git a/chromium/net/dns/dns_config_service_win.h b/chromium/net/dns/dns_config_service_win.h
index 5b6f22bb7de..96d47130ee4 100644
--- a/chromium/net/dns/dns_config_service_win.h
+++ b/chromium/net/dns/dns_config_service_win.h
@@ -13,6 +13,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
diff --git a/chromium/net/dns/dns_config_service_win_unittest.cc b/chromium/net/dns/dns_config_service_win_unittest.cc
index dc521ecefb2..3a452bc9d79 100644
--- a/chromium/net/dns/dns_config_service_win_unittest.cc
+++ b/chromium/net/dns/dns_config_service_win_unittest.cc
@@ -4,7 +4,6 @@
#include "net/dns/dns_config_service_win.h"
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/win/windows_version.h"
#include "net/dns/dns_protocol.h"
@@ -52,7 +51,7 @@ struct AdapterInfo {
IF_OPER_STATUS oper_status;
const WCHAR* dns_suffix;
std::string dns_server_addresses[4]; // Empty string indicates end.
- uint16 ports[4];
+ uint16_t ports[4];
};
scoped_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> CreateAdapterAddresses(
@@ -117,7 +116,7 @@ TEST(DnsConfigServiceWinTest, ConvertAdapterAddresses) {
AdapterInfo input_adapters[4]; // |if_type| == 0 indicates end.
std::string expected_nameservers[4]; // Empty string indicates end.
std::string expected_suffix;
- uint16 expected_ports[4];
+ uint16_t expected_ports[4];
} cases[] = {
{ // Ignore loopback and inactive adapters.
{
@@ -176,7 +175,7 @@ TEST(DnsConfigServiceWinTest, ConvertAdapterAddresses) {
for (size_t j = 0; !t.expected_nameservers[j].empty(); ++j) {
IPAddressNumber ip;
ASSERT_TRUE(ParseIPLiteralToNumber(t.expected_nameservers[j], &ip));
- uint16 port = t.expected_ports[j];
+ uint16_t port = t.expected_ports[j];
if (!port)
port = dns_protocol::kDefaultPort;
expected_nameservers.push_back(IPEndPoint(ip, port));
diff --git a/chromium/net/dns/dns_hosts.cc b/chromium/net/dns/dns_hosts.cc
index 9e641b6a2cf..a4f293f6d7e 100644
--- a/chromium/net/dns/dns_hosts.cc
+++ b/chromium/net/dns/dns_hosts.cc
@@ -6,6 +6,7 @@
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
@@ -190,7 +191,7 @@ bool ParseHostsFile(const base::FilePath& path, DnsHosts* dns_hosts) {
if (!base::PathExists(path))
return true;
- int64 size;
+ int64_t size;
if (!base::GetFileSize(path, &size))
return false;
@@ -198,7 +199,7 @@ bool ParseHostsFile(const base::FilePath& path, DnsHosts* dns_hosts) {
static_cast<base::HistogramBase::Sample>(size));
// Reject HOSTS files larger than |kMaxHostsSize| bytes.
- const int64 kMaxHostsSize = 1 << 25; // 32MB
+ const int64_t kMaxHostsSize = 1 << 25; // 32MB
if (size > kMaxHostsSize)
return false;
diff --git a/chromium/net/dns/dns_hosts.h b/chromium/net/dns/dns_hosts.h
index c35857e1f57..d8ece2cd48e 100644
--- a/chromium/net/dns/dns_hosts.h
+++ b/chromium/net/dns/dns_hosts.h
@@ -5,12 +5,13 @@
#ifndef NET_DNS_DNS_HOSTS_H_
#define NET_DNS_DNS_HOSTS_H_
+#include <stddef.h>
+
#include <map>
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
#include "net/base/address_family.h"
diff --git a/chromium/net/dns/dns_protocol.h b/chromium/net/dns/dns_protocol.h
index f3f9292009a..21bfc6cbc82 100644
--- a/chromium/net/dns/dns_protocol.h
+++ b/chromium/net/dns/dns_protocol.h
@@ -5,15 +5,16 @@
#ifndef NET_DNS_DNS_PROTOCOL_H_
#define NET_DNS_DNS_PROTOCOL_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "net/base/net_export.h"
namespace net {
namespace dns_protocol {
-static const uint16 kDefaultPort = 53;
-static const uint16 kDefaultPortMulticast = 5353;
+static const uint16_t kDefaultPort = 53;
+static const uint16_t kDefaultPortMulticast = 5353;
// DNS packet consists of a header followed by questions and/or answers.
// For the meaning of specific fields, please see RFC 1035 and 2535
@@ -73,28 +74,27 @@ static const uint16 kDefaultPortMulticast = 5353;
#pragma pack(push)
#pragma pack(1)
-// On-the-wire header. All uint16 are in network order.
-// Used internally in DnsQuery and DnsResponse.
-struct NET_EXPORT_PRIVATE Header {
- uint16 id;
- uint16 flags;
- uint16 qdcount;
- uint16 ancount;
- uint16 nscount;
- uint16 arcount;
+// On-the-wire header. All uint16_t are in network order.
+struct NET_EXPORT Header {
+ uint16_t id;
+ uint16_t flags;
+ uint16_t qdcount;
+ uint16_t ancount;
+ uint16_t nscount;
+ uint16_t arcount;
};
#pragma pack(pop)
-static const uint8 kLabelMask = 0xc0;
-static const uint8 kLabelPointer = 0xc0;
-static const uint8 kLabelDirect = 0x0;
-static const uint16 kOffsetMask = 0x3fff;
+static const uint8_t kLabelMask = 0xc0;
+static const uint8_t kLabelPointer = 0xc0;
+static const uint8_t kLabelDirect = 0x0;
+static const uint16_t kOffsetMask = 0x3fff;
// In MDns the most significant bit of the rrclass is designated as the
// "cache-flush bit", as described in http://www.rfc-editor.org/rfc/rfc6762.txt
// section 10.2.
-static const uint16 kMDnsClassMask = 0x7FFF;
+static const uint16_t kMDnsClassMask = 0x7FFF;
static const int kMaxNameLength = 255;
@@ -107,34 +107,33 @@ static const int kMaxUDPSize = 512;
static const int kMaxMulticastSize = 9000;
// DNS class types.
-static const uint16 kClassIN = 1;
+static const uint16_t kClassIN = 1;
// DNS resource record types. See
// http://www.iana.org/assignments/dns-parameters
-static const uint16 kTypeA = 1;
-static const uint16 kTypeCNAME = 5;
-static const uint16 kTypePTR = 12;
-static const uint16 kTypeTXT = 16;
-static const uint16 kTypeAAAA = 28;
-static const uint16 kTypeSRV = 33;
-static const uint16 kTypeNSEC = 47;
-
+static const uint16_t kTypeA = 1;
+static const uint16_t kTypeCNAME = 5;
+static const uint16_t kTypePTR = 12;
+static const uint16_t kTypeTXT = 16;
+static const uint16_t kTypeAAAA = 28;
+static const uint16_t kTypeSRV = 33;
+static const uint16_t kTypeNSEC = 47;
// DNS rcode values.
-static const uint8 kRcodeMask = 0xf;
-static const uint8 kRcodeNOERROR = 0;
-static const uint8 kRcodeFORMERR = 1;
-static const uint8 kRcodeSERVFAIL = 2;
-static const uint8 kRcodeNXDOMAIN = 3;
-static const uint8 kRcodeNOTIMP = 4;
-static const uint8 kRcodeREFUSED = 5;
+static const uint8_t kRcodeMask = 0xf;
+static const uint8_t kRcodeNOERROR = 0;
+static const uint8_t kRcodeFORMERR = 1;
+static const uint8_t kRcodeSERVFAIL = 2;
+static const uint8_t kRcodeNXDOMAIN = 3;
+static const uint8_t kRcodeNOTIMP = 4;
+static const uint8_t kRcodeREFUSED = 5;
// DNS flags.
-static const uint16 kFlagResponse = 0x8000;
-static const uint16 kFlagRA = 0x80;
-static const uint16 kFlagRD = 0x100;
-static const uint16 kFlagTC = 0x200;
-static const uint16 kFlagAA = 0x400;
+static const uint16_t kFlagResponse = 0x8000;
+static const uint16_t kFlagRA = 0x80;
+static const uint16_t kFlagRD = 0x100;
+static const uint16_t kFlagTC = 0x200;
+static const uint16_t kFlagAA = 0x400;
} // namespace dns_protocol
diff --git a/chromium/net/dns/dns_query.cc b/chromium/net/dns/dns_query.cc
index f418162df54..76e2b56efb2 100644
--- a/chromium/net/dns/dns_query.cc
+++ b/chromium/net/dns/dns_query.cc
@@ -4,13 +4,11 @@
#include "net/dns/dns_query.h"
-#include <limits>
-
#include "base/big_endian.h"
#include "base/sys_byteorder.h"
-#include "net/base/dns_util.h"
#include "net/base/io_buffer.h"
#include "net/dns/dns_protocol.h"
+#include "net/dns/dns_util.h"
namespace net {
@@ -18,23 +16,19 @@ namespace net {
// For details, see RFC 1035 section 4.1.1. This header template sets RD
// bit, which directs the name server to pursue query recursively, and sets
// the QDCOUNT to 1, meaning the question section has a single entry.
-DnsQuery::DnsQuery(uint16 id, const base::StringPiece& qname, uint16 qtype)
+DnsQuery::DnsQuery(uint16_t id, const base::StringPiece& qname, uint16_t qtype)
: qname_size_(qname.size()) {
DCHECK(!DNSDomainToString(qname).empty());
- // QNAME + QTYPE + QCLASS
- size_t question_size = qname_size_ + sizeof(uint16) + sizeof(uint16);
io_buffer_ = new IOBufferWithSize(sizeof(dns_protocol::Header) +
- question_size);
- dns_protocol::Header* header =
- reinterpret_cast<dns_protocol::Header*>(io_buffer_->data());
- memset(header, 0, sizeof(dns_protocol::Header));
- header->id = base::HostToNet16(id);
- header->flags = base::HostToNet16(dns_protocol::kFlagRD);
- header->qdcount = base::HostToNet16(1);
+ question_size());
+ *header() = {};
+ header()->id = base::HostToNet16(id);
+ header()->flags = base::HostToNet16(dns_protocol::kFlagRD);
+ header()->qdcount = base::HostToNet16(1);
// Write question section after the header.
- base::BigEndianWriter writer(reinterpret_cast<char*>(header + 1),
- question_size);
+ base::BigEndianWriter writer(
+ io_buffer_->data() + sizeof(dns_protocol::Header), question_size());
writer.WriteBytes(qname.data(), qname.size());
writer.WriteU16(qtype);
writer.WriteU16(dns_protocol::kClassIN);
@@ -43,11 +37,11 @@ DnsQuery::DnsQuery(uint16 id, const base::StringPiece& qname, uint16 qtype)
DnsQuery::~DnsQuery() {
}
-scoped_ptr<DnsQuery> DnsQuery::CloneWithNewId(uint16 id) const {
+scoped_ptr<DnsQuery> DnsQuery::CloneWithNewId(uint16_t id) const {
return make_scoped_ptr(new DnsQuery(*this, id));
}
-uint16 DnsQuery::id() const {
+uint16_t DnsQuery::id() const {
const dns_protocol::Header* header =
reinterpret_cast<const dns_protocol::Header*>(io_buffer_->data());
return base::NetToHost16(header->id);
@@ -58,32 +52,32 @@ base::StringPiece DnsQuery::qname() const {
qname_size_);
}
-uint16 DnsQuery::qtype() const {
- uint16 type;
- base::ReadBigEndian<uint16>(
+uint16_t DnsQuery::qtype() const {
+ uint16_t type;
+ base::ReadBigEndian<uint16_t>(
io_buffer_->data() + sizeof(dns_protocol::Header) + qname_size_, &type);
return type;
}
base::StringPiece DnsQuery::question() const {
return base::StringPiece(io_buffer_->data() + sizeof(dns_protocol::Header),
- qname_size_ + sizeof(uint16) + sizeof(uint16));
+ question_size());
+}
+
+void DnsQuery::set_flags(uint16_t flags) {
+ header()->flags = flags;
}
-DnsQuery::DnsQuery(const DnsQuery& orig, uint16 id) {
+DnsQuery::DnsQuery(const DnsQuery& orig, uint16_t id) {
qname_size_ = orig.qname_size_;
io_buffer_ = new IOBufferWithSize(orig.io_buffer()->size());
memcpy(io_buffer_.get()->data(), orig.io_buffer()->data(),
io_buffer_.get()->size());
- dns_protocol::Header* header =
- reinterpret_cast<dns_protocol::Header*>(io_buffer_->data());
- header->id = base::HostToNet16(id);
+ header()->id = base::HostToNet16(id);
}
-void DnsQuery::set_flags(uint16 flags) {
- dns_protocol::Header* header =
- reinterpret_cast<dns_protocol::Header*>(io_buffer_->data());
- header->flags = flags;
+dns_protocol::Header* DnsQuery::header() {
+ return reinterpret_cast<dns_protocol::Header*>(io_buffer_->data());
}
} // namespace net
diff --git a/chromium/net/dns/dns_query.h b/chromium/net/dns/dns_query.h
index c3104c355f2..77d5200a798 100644
--- a/chromium/net/dns/dns_query.h
+++ b/chromium/net/dns/dns_query.h
@@ -5,7 +5,10 @@
#ifndef NET_DNS_DNS_QUERY_H_
#define NET_DNS_DNS_QUERY_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
@@ -13,6 +16,10 @@
namespace net {
+namespace dns_protocol {
+struct Header;
+}
+
class IOBufferWithSize;
// Represents on-the-wire DNS query message as an object.
@@ -21,16 +28,16 @@ class NET_EXPORT_PRIVATE DnsQuery {
public:
// Constructs a query message from |qname| which *MUST* be in a valid
// DNS name format, and |qtype|. The qclass is set to IN.
- DnsQuery(uint16 id, const base::StringPiece& qname, uint16 qtype);
+ DnsQuery(uint16_t id, const base::StringPiece& qname, uint16_t qtype);
~DnsQuery();
// Clones |this| verbatim, with ID field of the header set to |id|.
- scoped_ptr<DnsQuery> CloneWithNewId(uint16 id) const;
+ scoped_ptr<DnsQuery> CloneWithNewId(uint16_t id) const;
// DnsQuery field accessors.
- uint16 id() const;
+ uint16_t id() const;
base::StringPiece qname() const;
- uint16 qtype() const;
+ uint16_t qtype() const;
// Returns the Question section of the query. Used when matching the
// response.
@@ -39,10 +46,19 @@ class NET_EXPORT_PRIVATE DnsQuery {
// IOBuffer accessor to be used for writing out the query.
IOBufferWithSize* io_buffer() const { return io_buffer_.get(); }
- void set_flags(uint16 flags);
+ void set_flags(uint16_t flags);
private:
- DnsQuery(const DnsQuery& orig, uint16 id);
+ DnsQuery(const DnsQuery& orig, uint16_t id);
+
+ // Convenience for header access.
+ dns_protocol::Header* header();
+
+ // Returns the size of the question section.
+ size_t question_size() const {
+ // QNAME + QTYPE + QCLASS
+ return qname_size_ + sizeof(uint16_t) + sizeof(uint16_t);
+ }
// Size of the DNS name (*NOT* hostname) we are trying to resolve; used
// to calculate offsets.
diff --git a/chromium/net/dns/dns_query_unittest.cc b/chromium/net/dns/dns_query_unittest.cc
index bd8bf3ab260..2a4648e244f 100644
--- a/chromium/net/dns/dns_query_unittest.cc
+++ b/chromium/net/dns/dns_query_unittest.cc
@@ -15,24 +15,19 @@ namespace {
TEST(DnsQueryTest, Constructor) {
// This includes \0 at the end.
const char qname_data[] = "\x03""www""\x07""example""\x03""com";
- const uint8 query_data[] = {
- // Header
- 0xbe, 0xef,
- 0x01, 0x00, // Flags -- set RD (recursion desired) bit.
- 0x00, 0x01, // Set QDCOUNT (question count) to 1, all the
- // rest are 0 for a query.
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
-
- // Question
- 0x03, 'w', 'w', 'w', // QNAME: www.example.com in DNS format.
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
-
- 0x00, 0x01, // QTYPE: A query.
- 0x00, 0x01, // QCLASS: IN class.
+ const uint8_t query_data[] = {
+ // Header
+ 0xbe, 0xef, 0x01, 0x00, // Flags -- set RD (recursion desired) bit.
+ 0x00, 0x01, // Set QDCOUNT (question count) to 1, all the
+ // rest are 0 for a query.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ // Question
+ 0x03, 'w', 'w', 'w', // QNAME: www.example.com in DNS format.
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00,
+
+ 0x00, 0x01, // QTYPE: A query.
+ 0x00, 0x01, // QCLASS: IN class.
};
base::StringPiece qname(qname_data, sizeof(qname_data));
diff --git a/chromium/net/base/dns_reloader.cc b/chromium/net/dns/dns_reloader.cc
index 18041d9fc61..74534e6b1ba 100644
--- a/chromium/net/base/dns_reloader.cc
+++ b/chromium/net/dns/dns_reloader.cc
@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/base/dns_reloader.h"
+#include "net/dns/dns_reloader.h"
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \
!defined(OS_ANDROID)
#include <resolv.h>
-#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_local_storage.h"
diff --git a/chromium/net/base/dns_reloader.h b/chromium/net/dns/dns_reloader.h
index 889d404794a..4317d9eaf63 100644
--- a/chromium/net/base/dns_reloader.h
+++ b/chromium/net/dns/dns_reloader.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_BASE_DNS_RELOADER_H_
-#define NET_BASE_DNS_RELOADER_H_
+#ifndef NET_DNS_DNS_RELOADER_H_
+#define NET_DNS_DNS_RELOADER_H_
#include "build/build_config.h"
@@ -20,4 +20,4 @@ void DnsReloaderMaybeReload();
} // namespace net
#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
-#endif // NET_BASE_DNS_RELOADER_H_
+#endif // NET_DNS_DNS_RELOADER_H_
diff --git a/chromium/net/dns/dns_response.cc b/chromium/net/dns/dns_response.cc
index 730206ca608..c11b8a9c8af 100644
--- a/chromium/net/dns/dns_response.cc
+++ b/chromium/net/dns/dns_response.cc
@@ -4,15 +4,17 @@
#include "net/dns/dns_response.h"
+#include <limits>
+
#include "base/big_endian.h"
#include "base/strings/string_util.h"
#include "base/sys_byteorder.h"
#include "net/base/address_list.h"
-#include "net/base/dns_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/dns_query.h"
+#include "net/dns/dns_util.h"
namespace net {
@@ -61,19 +63,19 @@ unsigned DnsRecordParser::ReadName(const void* const vpos,
// either a direct length or a pointer to the remainder of the name.
switch (*p & dns_protocol::kLabelMask) {
case dns_protocol::kLabelPointer: {
- if (p + sizeof(uint16) > end)
+ if (p + sizeof(uint16_t) > end)
return 0;
if (consumed == 0) {
- consumed = p - pos + sizeof(uint16);
+ consumed = p - pos + sizeof(uint16_t);
if (!out)
return consumed; // If name is not stored, that's all we need.
}
- seen += sizeof(uint16);
+ seen += sizeof(uint16_t);
// If seen the whole packet, then we must be in a loop.
if (seen > length_)
return 0;
- uint16 offset;
- base::ReadBigEndian<uint16>(p, &offset);
+ uint16_t offset;
+ base::ReadBigEndian<uint16_t>(p, &offset);
offset &= dns_protocol::kOffsetMask;
p = packet_ + offset;
if (p >= end)
@@ -81,7 +83,7 @@ unsigned DnsRecordParser::ReadName(const void* const vpos,
break;
}
case dns_protocol::kLabelDirect: {
- uint8 label_len = *p;
+ uint8_t label_len = *p;
++p;
// Note: root domain (".") is NOT included.
if (label_len == 0) {
@@ -115,7 +117,7 @@ bool DnsRecordParser::ReadRecord(DnsResourceRecord* out) {
return false;
base::BigEndianReader reader(cur_ + consumed,
packet_ + length_ - (cur_ + consumed));
- uint16 rdlen;
+ uint16_t rdlen;
if (reader.ReadU16(&out->type) &&
reader.ReadU16(&out->klass) &&
reader.ReadU32(&out->ttl) &&
@@ -132,7 +134,7 @@ bool DnsRecordParser::SkipQuestion() {
if (!consumed)
return false;
- const char* next = cur_ + consumed + 2 * sizeof(uint16); // QTYPE + QCLASS
+ const char* next = cur_ + consumed + 2 * sizeof(uint16_t); // QTYPE + QCLASS
if (next > packet_ + length_)
return false;
@@ -216,12 +218,12 @@ bool DnsResponse::IsValid() const {
return parser_.IsValid();
}
-uint16 DnsResponse::flags() const {
+uint16_t DnsResponse::flags() const {
DCHECK(parser_.IsValid());
return base::NetToHost16(header()->flags) & ~(dns_protocol::kRcodeMask);
}
-uint8 DnsResponse::rcode() const {
+uint8_t DnsResponse::rcode() const {
DCHECK(parser_.IsValid());
return base::NetToHost16(header()->flags) & dns_protocol::kRcodeMask;
}
@@ -240,18 +242,19 @@ base::StringPiece DnsResponse::qname() const {
DCHECK(parser_.IsValid());
// The response is HEADER QNAME QTYPE QCLASS ANSWER.
// |parser_| is positioned at the beginning of ANSWER, so the end of QNAME is
- // two uint16s before it.
+ // two uint16_ts before it.
const size_t hdr_size = sizeof(dns_protocol::Header);
- const size_t qname_size = parser_.GetOffset() - 2 * sizeof(uint16) - hdr_size;
+ const size_t qname_size =
+ parser_.GetOffset() - 2 * sizeof(uint16_t) - hdr_size;
return base::StringPiece(io_buffer_->data() + hdr_size, qname_size);
}
-uint16 DnsResponse::qtype() const {
+uint16_t DnsResponse::qtype() const {
DCHECK(parser_.IsValid());
// QTYPE starts where QNAME ends.
- const size_t type_offset = parser_.GetOffset() - 2 * sizeof(uint16);
- uint16 type;
- base::ReadBigEndian<uint16>(io_buffer_->data() + type_offset, &type);
+ const size_t type_offset = parser_.GetOffset() - 2 * sizeof(uint16_t);
+ uint16_t type;
+ base::ReadBigEndian<uint16_t>(io_buffer_->data() + type_offset, &type);
return type;
}
@@ -282,14 +285,14 @@ DnsResponse::Result DnsResponse::ParseToAddressList(
// Expected owner of record. No trailing dot.
std::string expected_name = GetDottedName();
- uint16 expected_type = qtype();
+ uint16_t expected_type = qtype();
DCHECK(expected_type == dns_protocol::kTypeA ||
expected_type == dns_protocol::kTypeAAAA);
size_t expected_size = (expected_type == dns_protocol::kTypeAAAA)
? kIPv6AddressSize : kIPv4AddressSize;
- uint32 ttl_sec = kuint32max;
+ uint32_t ttl_sec = std::numeric_limits<uint32_t>::max();
IPAddressList ip_addresses;
DnsRecordParser parser = Parser();
DnsResourceRecord record;
diff --git a/chromium/net/dns/dns_response.h b/chromium/net/dns/dns_response.h
index 6e67b5dea97..4d5e6b7307c 100644
--- a/chromium/net/dns/dns_response.h
+++ b/chromium/net/dns/dns_response.h
@@ -5,9 +5,12 @@
#ifndef NET_DNS_DNS_RESPONSE_H_
#define NET_DNS_DNS_RESPONSE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
@@ -29,9 +32,9 @@ struct NET_EXPORT_PRIVATE DnsResourceRecord {
~DnsResourceRecord();
std::string name; // in dotted form
- uint16 type;
- uint16 klass;
- uint32 ttl;
+ uint16_t type;
+ uint16_t klass;
+ uint32_t ttl;
base::StringPiece rdata; // points to the original response buffer
};
@@ -127,15 +130,15 @@ class NET_EXPORT_PRIVATE DnsResponse {
// All of the methods below are valid only if the response is valid.
// Accessors for the header.
- uint16 flags() const; // excluding rcode
- uint8 rcode() const;
+ uint16_t flags() const; // excluding rcode
+ uint8_t rcode() const;
unsigned answer_count() const;
unsigned additional_answer_count() const;
// Accessors to the question. The qname is unparsed.
base::StringPiece qname() const;
- uint16 qtype() const;
+ uint16_t qtype() const;
// Returns qname in dotted format.
std::string GetDottedName() const;
diff --git a/chromium/net/dns/dns_response_unittest.cc b/chromium/net/dns/dns_response_unittest.cc
index 9cb98cead5f..e701c9a9eca 100644
--- a/chromium/net/dns/dns_response_unittest.cc
+++ b/chromium/net/dns/dns_response_unittest.cc
@@ -29,17 +29,15 @@ TEST(DnsRecordParserTest, Constructor) {
}
TEST(DnsRecordParserTest, ReadName) {
- const uint8 data[] = {
+ const uint8_t data[] = {
// all labels "foo.example.com"
- 0x03, 'f', 'o', 'o',
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
+ 0x03, 'f', 'o', 'o', 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0x03, 'c',
+ 'o', 'm',
// byte 0x10
0x00,
// byte 0x11
// part label, part pointer, "bar.example.com"
- 0x03, 'b', 'a', 'r',
- 0xc0, 0x04,
+ 0x03, 'b', 'a', 'r', 0xc0, 0x04,
// byte 0x17
// all pointer to "bar.example.com", 2 jumps
0xc0, 0x11,
@@ -75,15 +73,13 @@ TEST(DnsRecordParserTest, ReadName) {
}
TEST(DnsRecordParserTest, ReadNameFail) {
- const uint8 data[] = {
+ const uint8_t data[] = {
// label length beyond packet
- 0x30, 'x', 'x',
- 0x00,
+ 0x30, 'x', 'x', 0x00,
// pointer offset beyond packet
0xc0, 0x20,
// pointer loop
- 0xc0, 0x08,
- 0xc0, 0x06,
+ 0xc0, 0x08, 0xc0, 0x06,
// incorrect label type (currently supports only direct and pointer)
0x80, 0x00,
// truncated name (missing root label)
@@ -103,12 +99,10 @@ TEST(DnsRecordParserTest, ReadNameFail) {
}
TEST(DnsRecordParserTest, ReadRecord) {
- const uint8 data[] = {
+ const uint8_t data[] = {
// Type CNAME record.
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x05, // TYPE is CNAME.
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00, 0x00,
+ 0x05, // TYPE is CNAME.
0x00, 0x01, // CLASS is IN.
0x00, 0x01, 0x24, 0x74, // TTL is 0x00012474.
0x00, 0x06, // RDLENGTH is 6 bytes.
@@ -116,8 +110,7 @@ TEST(DnsRecordParserTest, ReadRecord) {
0xc0, 0x00,
// Type A record.
0x03, 'b', 'a', 'r', // compressed owner name
- 0xc0, 0x00,
- 0x00, 0x01, // TYPE is A.
+ 0xc0, 0x00, 0x00, 0x01, // TYPE is A.
0x00, 0x01, // CLASS is IN.
0x00, 0x20, 0x13, 0x55, // TTL is 0x00201355.
0x00, 0x04, // RDLENGTH is 4 bytes.
@@ -161,47 +154,40 @@ TEST(DnsResponseTest, InitParse) {
// Compilers want to copy when binding temporary to const &, so must use heap.
scoped_ptr<DnsQuery> query(new DnsQuery(0xcafe, qname, dns_protocol::kTypeA));
- const uint8 response_data[] = {
- // Header
- 0xca, 0xfe, // ID
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x01, // 1 question
- 0x00, 0x02, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Question
- // This part is echoed back from the respective query.
- 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w',
- 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm',
- 0x03, 'o', 'r', 'g',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
-
- // Answer 1
- 0xc0, 0x0c, // NAME is a pointer to name in Question section.
- 0x00, 0x05, // TYPE is CNAME.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x12, // RDLENGTH is 18 bytes.
- // ghs.l.google.com in DNS format.
- 0x03, 'g', 'h', 's',
- 0x01, 'l',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
-
- // Answer 2
- 0xc0, 0x35, // NAME is a pointer to name in Answer 1.
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is 53 seconds.
- 0x00, 0x35,
- 0x00, 0x04, // RDLENGTH is 4 bytes.
- 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121
- 0x5f, 0x79,
+ const uint8_t response_data[] = {
+ // Header
+ 0xca, 0xfe, // ID
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x01, // 1 question
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Question
+ // This part is echoed back from the respective query.
+ 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h',
+ 'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
+ 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+
+ // Answer 1
+ 0xc0, 0x0c, // NAME is a pointer to name in Question section.
+ 0x00, 0x05, // TYPE is CNAME.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x12, // RDLENGTH is 18 bytes.
+ // ghs.l.google.com in DNS format.
+ 0x03, 'g', 'h', 's', 0x01, 'l', 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 0x03,
+ 'c', 'o', 'm', 0x00,
+
+ // Answer 2
+ 0xc0, 0x35, // NAME is a pointer to name in Answer 1.
+ 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 53 seconds.
+ 0x00, 0x35, 0x00, 0x04, // RDLENGTH is 4 bytes.
+ 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121
+ 0x5f, 0x79,
};
DnsResponse resp;
@@ -274,27 +260,24 @@ TEST(DnsResponseTest, InitParseWithoutQuery) {
}
TEST(DnsResponseTest, InitParseWithoutQueryNoQuestions) {
- const uint8 response_data[] = {
- // Header
- 0xca, 0xfe, // ID
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No question
- 0x00, 0x01, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w',
- 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm',
- 0x03, 'o', 'r', 'g',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is 53 seconds.
- 0x00, 0x35,
- 0x00, 0x04, // RDLENGTH is 4 bytes.
- 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121
- 0x5f, 0x79,
+ const uint8_t response_data[] = {
+ // Header
+ 0xca, 0xfe, // ID
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No question
+ 0x00, 0x01, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h',
+ 'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
+ 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 53 seconds.
+ 0x00, 0x35, 0x00, 0x04, // RDLENGTH is 4 bytes.
+ 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121
+ 0x5f, 0x79,
};
DnsResponse resp;
@@ -321,38 +304,35 @@ TEST(DnsResponseTest, InitParseWithoutQueryNoQuestions) {
}
TEST(DnsResponseTest, InitParseWithoutQueryTwoQuestions) {
- const uint8 response_data[] = {
- // Header
- 0xca, 0xfe, // ID
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x02, // 2 questions
- 0x00, 0x01, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Question 1
- 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w',
- 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm',
- 0x03, 'o', 'r', 'g',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
-
- // Question 2
- 0x0b, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', '2',
- 0xc0, 0x18, // pointer to "chromium.org"
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
-
- // Answer 1
- 0xc0, 0x0c, // NAME is a pointer to name in Question section.
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is 53 seconds.
- 0x00, 0x35,
- 0x00, 0x04, // RDLENGTH is 4 bytes.
- 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121
- 0x5f, 0x79,
+ const uint8_t response_data[] = {
+ // Header
+ 0xca, 0xfe, // ID
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x02, // 2 questions
+ 0x00, 0x01, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Question 1
+ 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h',
+ 'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
+ 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+
+ // Question 2
+ 0x0b, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', '2', 0xc0,
+ 0x18, // pointer to "chromium.org"
+ 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+
+ // Answer 1
+ 0xc0, 0x0c, // NAME is a pointer to name in Question section.
+ 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 53 seconds.
+ 0x00, 0x35, 0x00, 0x04, // RDLENGTH is 4 bytes.
+ 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121
+ 0x5f, 0x79,
};
DnsResponse resp;
@@ -379,11 +359,11 @@ TEST(DnsResponseTest, InitParseWithoutQueryTwoQuestions) {
}
TEST(DnsResponseTest, InitParseWithoutQueryPacketTooShort) {
- const uint8 response_data[] = {
- // Header
- 0xca, 0xfe, // ID
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No question
+ const uint8_t response_data[] = {
+ // Header
+ 0xca, 0xfe, // ID
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No question
};
DnsResponse resp;
@@ -404,7 +384,7 @@ void VerifyAddressList(const std::vector<const char*>& ip_addresses,
TEST(DnsResponseTest, ParseToAddressList) {
const struct TestCase {
size_t query_size;
- const uint8* response_data;
+ const uint8_t* response_data;
size_t response_size;
const char* const* expected_addresses;
size_t num_expected_addresses;
@@ -457,92 +437,92 @@ TEST(DnsResponseTest, ParseToAddressList) {
}
}
-const uint8 kResponseTruncatedRecord[] = {
- // Header: 1 question, 1 answer RR
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- // Question: name = 'a', type = A (0x1)
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
- // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x04, 0x0A, 0x0A, 0x0A, // Truncated RDATA.
+const uint8_t kResponseTruncatedRecord[] = {
+ // Header: 1 question, 1 answer RR
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ // Question: name = 'a', type = A (0x1)
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
+ // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04,
+ 0x0A, 0x0A, 0x0A, // Truncated RDATA.
};
-const uint8 kResponseTruncatedCNAME[] = {
- // Header: 1 question, 1 answer RR
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- // Question: name = 'a', type = A (0x1)
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
- // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'foo' (truncated)
- 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x03, 0x03, 'f', 'o', // Truncated name.
+const uint8_t kResponseTruncatedCNAME[] = {
+ // Header: 1 question, 1 answer RR
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ // Question: name = 'a', type = A (0x1)
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
+ // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'foo' (truncated)
+ 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x03,
+ 0x03, 'f', 'o', // Truncated name.
};
-const uint8 kResponseNameMismatch[] = {
- // Header: 1 question, 1 answer RR
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- // Question: name = 'a', type = A (0x1)
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
- // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
- 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
+const uint8_t kResponseNameMismatch[] = {
+ // Header: 1 question, 1 answer RR
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ // Question: name = 'a', type = A (0x1)
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
+ // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
+ 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04,
+ 0x0A, 0x0A, 0x0A, 0x0A,
};
-const uint8 kResponseNameMismatchInChain[] = {
- // Header: 1 question, 3 answer RR
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- // Question: name = 'a', type = A (0x1)
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
- // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b'
- 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x03, 0x01, 'b', 0x00,
- // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
- 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
- // Answer: name = 'c', type = A, TTL = 0xFF, RDATA = 10.10.10.11
- 0x01, 'c', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0B,
+const uint8_t kResponseNameMismatchInChain[] = {
+ // Header: 1 question, 3 answer RR
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ // Question: name = 'a', type = A (0x1)
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
+ // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b'
+ 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x03,
+ 0x01, 'b', 0x00,
+ // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
+ 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04,
+ 0x0A, 0x0A, 0x0A, 0x0A,
+ // Answer: name = 'c', type = A, TTL = 0xFF, RDATA = 10.10.10.11
+ 0x01, 'c', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04,
+ 0x0A, 0x0A, 0x0A, 0x0B,
};
-const uint8 kResponseSizeMismatch[] = {
- // Header: 1 answer RR
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- // Question: name = 'a', type = AAAA (0x1c)
- 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01,
- // Answer: name = 'a', type = AAAA, TTL = 0xFF, RDATA = 10.10.10.10
- 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
+const uint8_t kResponseSizeMismatch[] = {
+ // Header: 1 answer RR
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ // Question: name = 'a', type = AAAA (0x1c)
+ 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01,
+ // Answer: name = 'a', type = AAAA, TTL = 0xFF, RDATA = 10.10.10.10
+ 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04,
+ 0x0A, 0x0A, 0x0A, 0x0A,
};
-const uint8 kResponseCNAMEAfterAddress[] = {
- // Header: 2 answer RR
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- // Question: name = 'a', type = A (0x1)
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
- // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10.
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
- // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b'
- 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x03, 0x01, 'b', 0x00,
+const uint8_t kResponseCNAMEAfterAddress[] = {
+ // Header: 2 answer RR
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ // Question: name = 'a', type = A (0x1)
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
+ // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10.
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04,
+ 0x0A, 0x0A, 0x0A, 0x0A,
+ // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b'
+ 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x03,
+ 0x01, 'b', 0x00,
};
-const uint8 kResponseNoAddresses[] = {
- // Header: 1 question, 1 answer RR, 1 authority RR
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
- // Question: name = 'a', type = A (0x1)
- 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
- // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b'
- 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x03, 0x01, 'b', 0x00,
- // Authority section
- // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
- 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
+const uint8_t kResponseNoAddresses[] = {
+ // Header: 1 question, 1 answer RR, 1 authority RR
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ // Question: name = 'a', type = A (0x1)
+ 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
+ // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'b'
+ 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x03,
+ 0x01, 'b', 0x00,
+ // Authority section
+ // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
+ 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04,
+ 0x0A, 0x0A, 0x0A, 0x0A,
};
TEST(DnsResponseTest, ParseToAddressListFail) {
const struct TestCase {
- const uint8* data;
+ const uint8_t* data;
size_t size;
DnsResponse::Result expected_result;
} cases[] = {
diff --git a/chromium/net/dns/dns_session.cc b/chromium/net/dns/dns_session.cc
index 4d8f61e99c1..5148e0b878b 100644
--- a/chromium/net/dns/dns_session.cc
+++ b/chromium/net/dns/dns_session.cc
@@ -4,9 +4,13 @@
#include "net/dns/dns_session.h"
-#include "base/basictypes.h"
+#include <stdint.h>
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sample_vector.h"
#include "base/rand_util.h"
@@ -74,10 +78,12 @@ DnsSession::RttBuckets::RttBuckets() : base::BucketRanges(kRTTBucketCount + 1) {
DnsSession::SocketLease::SocketLease(scoped_refptr<DnsSession> session,
unsigned server_index,
scoped_ptr<DatagramClientSocket> socket)
- : session_(session), server_index_(server_index), socket_(socket.Pass()) {}
+ : session_(session),
+ server_index_(server_index),
+ socket_(std::move(socket)) {}
DnsSession::SocketLease::~SocketLease() {
- session_->FreeSocket(server_index_, socket_.Pass());
+ session_->FreeSocket(server_index_, std::move(socket_));
}
DnsSession::DnsSession(const DnsConfig& config,
@@ -85,16 +91,18 @@ DnsSession::DnsSession(const DnsConfig& config,
const RandIntCallback& rand_int_callback,
NetLog* net_log)
: config_(config),
- socket_pool_(socket_pool.Pass()),
- rand_callback_(base::Bind(rand_int_callback, 0, kuint16max)),
+ socket_pool_(std::move(socket_pool)),
+ rand_callback_(base::Bind(rand_int_callback,
+ 0,
+ std::numeric_limits<uint16_t>::max())),
net_log_(net_log),
server_index_(0) {
socket_pool_->Initialize(&config_.nameservers, net_log);
UMA_HISTOGRAM_CUSTOM_COUNTS(
"AsyncDNS.ServerCount", config_.nameservers.size(), 0, 10, 11);
for (size_t i = 0; i < config_.nameservers.size(); ++i) {
- server_stats_.push_back(new ServerStats(config_.timeout,
- rtt_buckets_.Pointer()));
+ server_stats_.push_back(make_scoped_ptr(
+ new ServerStats(config_.timeout, rtt_buckets_.Pointer())));
}
}
@@ -102,8 +110,8 @@ DnsSession::~DnsSession() {
RecordServerStats();
}
-uint16 DnsSession::NextQueryId() const {
- return static_cast<uint16>(rand_callback_.Run());
+uint16_t DnsSession::NextQueryId() const {
+ return static_cast<uint16_t>(rand_callback_.Run());
}
unsigned DnsSession::NextFirstServerIndex() {
@@ -233,7 +241,7 @@ scoped_ptr<DnsSession::SocketLease> DnsSession::AllocateSocket(
socket->NetLog().BeginEvent(NetLog::TYPE_SOCKET_IN_USE,
source.ToEventParametersCallback());
- SocketLease* lease = new SocketLease(this, server_index, socket.Pass());
+ SocketLease* lease = new SocketLease(this, server_index, std::move(socket));
return scoped_ptr<SocketLease>(lease);
}
@@ -249,7 +257,7 @@ void DnsSession::FreeSocket(unsigned server_index,
socket->NetLog().EndEvent(NetLog::TYPE_SOCKET_IN_USE);
- socket_pool_->FreeSocket(server_index, socket.Pass());
+ socket_pool_->FreeSocket(server_index, std::move(socket));
}
base::TimeDelta DnsSession::NextTimeoutFromJacobson(unsigned server_index,
diff --git a/chromium/net/dns/dns_session.h b/chromium/net/dns/dns_session.h
index e878a57572c..106493e94b8 100644
--- a/chromium/net/dns/dns_session.h
+++ b/chromium/net/dns/dns_session.h
@@ -5,12 +5,14 @@
#ifndef NET_DNS_DNS_SESSION_H_
#define NET_DNS_DNS_SESSION_H_
+#include <stdint.h>
+
#include <vector>
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/metrics/bucket_ranges.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
@@ -66,7 +68,7 @@ class NET_EXPORT_PRIVATE DnsSession
NetLog* net_log() const { return net_log_; }
// Return the next random query ID.
- uint16 NextQueryId() const;
+ uint16_t NextQueryId() const;
// Return the index of the first configured server to use on first attempt.
unsigned NextFirstServerIndex();
@@ -131,7 +133,7 @@ class NET_EXPORT_PRIVATE DnsSession
struct ServerStats;
// Track runtime statistics of each DNS server.
- ScopedVector<ServerStats> server_stats_;
+ std::vector<scoped_ptr<ServerStats>> server_stats_;
// Buckets shared for all |ServerStats::rtt_histogram|.
struct RttBuckets : public base::BucketRanges {
diff --git a/chromium/net/dns/dns_session_unittest.cc b/chromium/net/dns/dns_session_unittest.cc
index 46815e00a3b..b2a09f187f9 100644
--- a/chromium/net/dns/dns_session_unittest.cc
+++ b/chromium/net/dns/dns_session_unittest.cc
@@ -5,6 +5,7 @@
#include "net/dns/dns_session.h"
#include <list>
+#include <utility>
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
@@ -190,8 +191,7 @@ TestClientSocketFactory::CreateDatagramClientSocket(
data_providers_.push_back(data_provider);
scoped_ptr<MockUDPClientSocket> socket(
new MockUDPClientSocket(data_provider, net_log));
- data_provider->set_socket(socket.get());
- return socket.Pass();
+ return std::move(socket);
}
TestClientSocketFactory::~TestClientSocketFactory() {
diff --git a/chromium/net/dns/dns_socket_pool.cc b/chromium/net/dns/dns_socket_pool.cc
index 2c3c8c27357..e365d57a190 100644
--- a/chromium/net/dns/dns_socket_pool.cc
+++ b/chromium/net/dns/dns_socket_pool.cc
@@ -5,6 +5,7 @@
#include "net/dns/dns_socket_pool.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "net/base/address_list.h"
@@ -86,7 +87,7 @@ scoped_ptr<DatagramClientSocket> DnsSocketPool::CreateConnectedSocket(
LOG(WARNING) << "Failed to create socket.";
}
- return socket.Pass();
+ return socket;
}
class NullDnsSocketPool : public DnsSocketPool {
diff --git a/chromium/net/dns/dns_socket_pool.h b/chromium/net/dns/dns_socket_pool.h
index 68d9a9c3b26..195393866d8 100644
--- a/chromium/net/dns/dns_socket_pool.h
+++ b/chromium/net/dns/dns_socket_pool.h
@@ -7,6 +7,7 @@
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/log/net_log.h"
diff --git a/chromium/net/dns/dns_test_util.cc b/chromium/net/dns/dns_test_util.cc
index 39857d79eef..de91048c9fe 100644
--- a/chromium/net/dns/dns_test_util.cc
+++ b/chromium/net/dns/dns_test_util.cc
@@ -13,13 +13,13 @@
#include "base/single_thread_task_runner.h"
#include "base/sys_byteorder.h"
#include "base/thread_task_runner_handle.h"
-#include "net/base/dns_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/dns/address_sorter.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_transaction.h"
+#include "net/dns/dns_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -41,7 +41,7 @@ class MockTransaction : public DnsTransaction,
public:
MockTransaction(const MockDnsClientRuleList& rules,
const std::string& hostname,
- uint16 qtype,
+ uint16_t qtype,
const DnsTransactionFactory::CallbackType& callback)
: result_(MockDnsClientRule::FAIL),
hostname_(hostname),
@@ -64,7 +64,7 @@ class MockTransaction : public DnsTransaction,
const std::string& GetHostname() const override { return hostname_; }
- uint16 GetType() const override { return qtype_; }
+ uint16_t GetType() const override { return qtype_; }
void Start() override {
EXPECT_FALSE(started_);
@@ -102,10 +102,10 @@ class MockTransaction : public DnsTransaction,
header->flags |= dns_protocol::kFlagResponse;
if (MockDnsClientRule::OK == result_) {
- const uint16 kPointerToQueryName =
- static_cast<uint16>(0xc000 | sizeof(*header));
+ const uint16_t kPointerToQueryName =
+ static_cast<uint16_t>(0xc000 | sizeof(*header));
- const uint32 kTTL = 86400; // One day.
+ const uint32_t kTTL = 86400; // One day.
// Size of RDATA which is a IPv4 or IPv6 address.
size_t rdata_size = qtype_ == dns_protocol::kTypeA ? kIPv4AddressSize
@@ -122,7 +122,7 @@ class MockTransaction : public DnsTransaction,
writer.WriteU16(qtype_);
writer.WriteU16(dns_protocol::kClassIN);
writer.WriteU32(kTTL);
- writer.WriteU16(rdata_size);
+ writer.WriteU16(static_cast<uint16_t>(rdata_size));
if (qtype_ == dns_protocol::kTypeA) {
char kIPv4Loopback[] = { 0x7f, 0, 0, 1 };
writer.WriteBytes(kIPv4Loopback, sizeof(kIPv4Loopback));
@@ -150,7 +150,7 @@ class MockTransaction : public DnsTransaction,
MockDnsClientRule::Result result_;
const std::string hostname_;
- const uint16 qtype_;
+ const uint16_t qtype_;
DnsTransactionFactory::CallbackType callback_;
bool started_;
bool delayed_;
@@ -168,7 +168,7 @@ class MockTransactionFactory : public DnsTransactionFactory {
scoped_ptr<DnsTransaction> CreateTransaction(
const std::string& hostname,
- uint16 qtype,
+ uint16_t qtype,
const DnsTransactionFactory::CallbackType& callback,
const BoundNetLog&) override {
MockTransaction* transaction =
diff --git a/chromium/net/dns/dns_test_util.h b/chromium/net/dns/dns_test_util.h
index e168afc4f02..fc325005610 100644
--- a/chromium/net/dns/dns_test_util.h
+++ b/chromium/net/dns/dns_test_util.h
@@ -5,10 +5,12 @@
#ifndef NET_DNS_DNS_TEST_UTIL_H_
#define NET_DNS_DNS_TEST_UTIL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/dns/dns_client.h"
#include "net/dns/dns_config_service.h"
@@ -19,7 +21,7 @@ namespace net {
//-----------------------------------------------------------------------------
// Query/response set for www.google.com, ID is fixed to 0.
static const char kT0HostName[] = "www.google.com";
-static const uint16 kT0Qtype = dns_protocol::kTypeA;
+static const uint16_t kT0Qtype = dns_protocol::kTypeA;
static const char kT0DnsName[] = {
0x03, 'w', 'w', 'w',
0x06, 'g', 'o', 'o', 'g', 'l', 'e',
@@ -27,27 +29,20 @@ static const char kT0DnsName[] = {
0x00
};
static const size_t kT0QuerySize = 32;
-static const uint8 kT0ResponseDatagram[] = {
- // response contains one CNAME for www.l.google.com and the following
- // IP addresses: 74.125.226.{179,180,176,177,178}
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
- 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
- 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01,
- 0x4d, 0x13, 0x00, 0x08, 0x03, 0x77, 0x77, 0x77,
- 0x01, 0x6c, 0xc0, 0x10, 0xc0, 0x2c, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04,
- 0x4a, 0x7d, 0xe2, 0xb3, 0xc0, 0x2c, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04,
- 0x4a, 0x7d, 0xe2, 0xb4, 0xc0, 0x2c, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04,
- 0x4a, 0x7d, 0xe2, 0xb0, 0xc0, 0x2c, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04,
- 0x4a, 0x7d, 0xe2, 0xb1, 0xc0, 0x2c, 0x00, 0x01,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04,
- 0x4a, 0x7d, 0xe2, 0xb2
-};
+static const uint8_t kT0ResponseDatagram[] = {
+ // response contains one CNAME for www.l.google.com and the following
+ // IP addresses: 74.125.226.{179,180,176,177,178}
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
+ 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05,
+ 0x00, 0x01, 0x00, 0x01, 0x4d, 0x13, 0x00, 0x08, 0x03, 0x77, 0x77, 0x77,
+ 0x01, 0x6c, 0xc0, 0x10, 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb3, 0xc0, 0x2c, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb4,
+ 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04,
+ 0x4a, 0x7d, 0xe2, 0xb0, 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb1, 0xc0, 0x2c, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb2};
static const char* const kT0IpAddresses[] = {
"74.125.226.179", "74.125.226.180", "74.125.226.176",
"74.125.226.177", "74.125.226.178"
@@ -60,7 +55,7 @@ static const unsigned kT0RecordCount = arraysize(kT0IpAddresses) + 1;
//-----------------------------------------------------------------------------
// Query/response set for codereview.chromium.org, ID is fixed to 1.
static const char kT1HostName[] = "codereview.chromium.org";
-static const uint16 kT1Qtype = dns_protocol::kTypeA;
+static const uint16_t kT1Qtype = dns_protocol::kTypeA;
static const char kT1DnsName[] = {
0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w',
0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm',
@@ -68,21 +63,17 @@ static const char kT1DnsName[] = {
0x00
};
static const size_t kT1QuerySize = 41;
-static const uint8 kT1ResponseDatagram[] = {
- // response contains one CNAME for ghs.l.google.com and the following
- // IP address: 64.233.169.121
- 0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, 0x64,
- 0x65, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x08,
- 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d,
- 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00,
- 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00,
- 0x01, 0x41, 0x75, 0x00, 0x12, 0x03, 0x67, 0x68,
- 0x73, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67,
- 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0,
- 0x35, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
- 0x0b, 0x00, 0x04, 0x40, 0xe9, 0xa9, 0x79
-};
+static const uint8_t kT1ResponseDatagram[] = {
+ // response contains one CNAME for ghs.l.google.com and the following
+ // IP address: 64.233.169.121
+ 0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x76, 0x69, 0x65,
+ 0x77, 0x08, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x03,
+ 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00,
+ 0x05, 0x00, 0x01, 0x00, 0x01, 0x41, 0x75, 0x00, 0x12, 0x03, 0x67,
+ 0x68, 0x73, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x35, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x0b, 0x00, 0x04, 0x40, 0xe9, 0xa9, 0x79};
static const char* const kT1IpAddresses[] = {
"64.233.169.121"
};
@@ -94,7 +85,7 @@ static const unsigned kT1RecordCount = arraysize(kT1IpAddresses) + 1;
//-----------------------------------------------------------------------------
// Query/response set for www.ccs.neu.edu, ID is fixed to 2.
static const char kT2HostName[] = "www.ccs.neu.edu";
-static const uint16 kT2Qtype = dns_protocol::kTypeA;
+static const uint16_t kT2Qtype = dns_protocol::kTypeA;
static const char kT2DnsName[] = {
0x03, 'w', 'w', 'w',
0x03, 'c', 'c', 's',
@@ -103,19 +94,15 @@ static const char kT2DnsName[] = {
0x00
};
static const size_t kT2QuerySize = 33;
-static const uint8 kT2ResponseDatagram[] = {
- // response contains one CNAME for vulcan.ccs.neu.edu and the following
- // IP address: 129.10.116.81
- 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
- 0x03, 0x63, 0x63, 0x73, 0x03, 0x6e, 0x65, 0x75,
- 0x03, 0x65, 0x64, 0x75, 0x00, 0x00, 0x01, 0x00,
- 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00,
- 0x00, 0x01, 0x2c, 0x00, 0x09, 0x06, 0x76, 0x75,
- 0x6c, 0x63, 0x61, 0x6e, 0xc0, 0x10, 0xc0, 0x2d,
- 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2c,
- 0x00, 0x04, 0x81, 0x0a, 0x74, 0x51
-};
+static const uint8_t kT2ResponseDatagram[] = {
+ // response contains one CNAME for vulcan.ccs.neu.edu and the following
+ // IP address: 129.10.116.81
+ 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x77, 0x77, 0x77, 0x03, 0x63, 0x63, 0x73, 0x03, 0x6e, 0x65, 0x75,
+ 0x03, 0x65, 0x64, 0x75, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00,
+ 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x09, 0x06, 0x76, 0x75,
+ 0x6c, 0x63, 0x61, 0x6e, 0xc0, 0x10, 0xc0, 0x2d, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x81, 0x0a, 0x74, 0x51};
static const char* const kT2IpAddresses[] = {
"129.10.116.81"
};
@@ -127,7 +114,7 @@ static const unsigned kT2RecordCount = arraysize(kT2IpAddresses) + 1;
//-----------------------------------------------------------------------------
// Query/response set for www.google.az, ID is fixed to 3.
static const char kT3HostName[] = "www.google.az";
-static const uint16 kT3Qtype = dns_protocol::kTypeA;
+static const uint16_t kT3Qtype = dns_protocol::kTypeA;
static const char kT3DnsName[] = {
0x03, 'w', 'w', 'w',
0x06, 'g', 'o', 'o', 'g', 'l', 'e',
@@ -135,37 +122,28 @@ static const char kT3DnsName[] = {
0x00
};
static const size_t kT3QuerySize = 31;
-static const uint8 kT3ResponseDatagram[] = {
- // response contains www.google.com as CNAME for www.google.az and
- // www.l.google.com as CNAME for www.google.com and the following
- // IP addresses: 74.125.226.{178,179,180,176,177}
- // The TTLs on the records are: 0x00015099, 0x00025099, 0x00000415,
- // 0x00003015, 0x00002015, 0x00000015, 0x00001015.
- // The last record is an imaginary TXT record for t.google.com.
- 0x00, 0x03, 0x81, 0x80, 0x00, 0x01, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
- 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x02,
- 0x61, 0x7a, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
- 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x50,
- 0x99, 0x00, 0x10, 0x03, 0x77, 0x77, 0x77, 0x06,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
- 0x6f, 0x6d, 0x00, 0xc0, 0x2b, 0x00, 0x05, 0x00,
- 0x01, 0x00, 0x02, 0x50, 0x99, 0x00, 0x08, 0x03,
- 0x77, 0x77, 0x77, 0x01, 0x6c, 0xc0, 0x2f, 0xc0,
- 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x04,
- 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb2, 0xc0,
- 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x30,
- 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb3, 0xc0,
- 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x20,
- 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb4, 0xc0,
- 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb0, 0xc0,
- 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10,
- 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb1, 0x01,
- 0x74, 0xc0, 0x2f, 0x00, 0x10, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x04, 0xde, 0xad, 0xfe,
- 0xed
-};
+static const uint8_t kT3ResponseDatagram[] = {
+ // response contains www.google.com as CNAME for www.google.az and
+ // www.l.google.com as CNAME for www.google.com and the following
+ // IP addresses: 74.125.226.{178,179,180,176,177}
+ // The TTLs on the records are: 0x00015099, 0x00025099, 0x00000415,
+ // 0x00003015, 0x00002015, 0x00000015, 0x00001015.
+ // The last record is an imaginary TXT record for t.google.com.
+ 0x00, 0x03, 0x81, 0x80, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x02,
+ 0x61, 0x7a, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00,
+ 0x01, 0x00, 0x01, 0x50, 0x99, 0x00, 0x10, 0x03, 0x77, 0x77, 0x77, 0x06,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0,
+ 0x2b, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x50, 0x99, 0x00, 0x08, 0x03,
+ 0x77, 0x77, 0x77, 0x01, 0x6c, 0xc0, 0x2f, 0xc0, 0x47, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x04, 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb2, 0xc0,
+ 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x30, 0x15, 0x00, 0x04, 0x4a,
+ 0x7d, 0xe2, 0xb3, 0xc0, 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x20,
+ 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb4, 0xc0, 0x47, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb0, 0xc0,
+ 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10, 0x15, 0x00, 0x04, 0x4a,
+ 0x7d, 0xe2, 0xb1, 0x01, 0x74, 0xc0, 0x2f, 0x00, 0x10, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x04, 0xde, 0xad, 0xfe, 0xed};
static const char* const kT3IpAddresses[] = {
"74.125.226.178", "74.125.226.179", "74.125.226.180",
"74.125.226.176", "74.125.226.177"
@@ -190,15 +168,17 @@ struct MockDnsClientRule {
// If |delay| is true, matching transactions will be delayed until triggered
// by the consumer.
MockDnsClientRule(const std::string& prefix_arg,
- uint16 qtype_arg,
+ uint16_t qtype_arg,
Result result_arg,
bool delay)
- : result(result_arg), prefix(prefix_arg), qtype(qtype_arg),
+ : result(result_arg),
+ prefix(prefix_arg),
+ qtype(qtype_arg),
delay(delay) {}
Result result;
std::string prefix;
- uint16 qtype;
+ uint16_t qtype;
bool delay;
};
diff --git a/chromium/net/dns/dns_transaction.cc b/chromium/net/dns/dns_transaction.cc
index 020d5b4d01e..8eebb8c69f2 100644
--- a/chromium/net/dns/dns_transaction.cc
+++ b/chromium/net/dns/dns_transaction.cc
@@ -6,14 +6,15 @@
#include <deque>
#include <string>
+#include <utility>
#include <vector>
#include "base/big_endian.h"
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram.h"
#include "base/profiler/scoped_tracker.h"
@@ -26,7 +27,6 @@
#include "base/timer/timer.h"
#include "base/values.h"
#include "net/base/completion_callback.h"
-#include "net/base/dns_util.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
@@ -34,6 +34,7 @@
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_session.h"
+#include "net/dns/dns_util.h"
#include "net/log/net_log.h"
#include "net/socket/stream_socket.h"
#include "net/udp/datagram_client_socket.h"
@@ -62,12 +63,12 @@ bool IsIPLiteral(const std::string& hostname) {
scoped_ptr<base::Value> NetLogStartCallback(
const std::string* hostname,
- uint16 qtype,
+ uint16_t qtype,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("hostname", *hostname);
dict->SetInteger("query_type", qtype);
- return dict.Pass();
+ return std::move(dict);
};
// ----------------------------------------------------------------------------
@@ -109,7 +110,7 @@ class DnsAttempt {
dict->SetInteger("rcode", GetResponse()->rcode());
dict->SetInteger("answer_count", GetResponse()->answer_count());
GetSocketNetLog().source().AddToEventParameters(dict.get());
- return dict.Pass();
+ return std::move(dict);
}
void set_result(int result) {
@@ -142,8 +143,8 @@ class DnsUDPAttempt : public DnsAttempt {
: DnsAttempt(server_index),
next_state_(STATE_NONE),
received_malformed_response_(false),
- socket_lease_(socket_lease.Pass()),
- query_(query.Pass()) {}
+ socket_lease_(std::move(socket_lease)),
+ query_(std::move(query)) {}
// DnsAttempt:
int Start(const CompletionCallback& callback) override {
@@ -303,9 +304,9 @@ class DnsTCPAttempt : public DnsAttempt {
scoped_ptr<DnsQuery> query)
: DnsAttempt(server_index),
next_state_(STATE_NONE),
- socket_(socket.Pass()),
- query_(query.Pass()),
- length_buffer_(new IOBufferWithSize(sizeof(uint16))),
+ socket_(std::move(socket)),
+ query_(std::move(query)),
+ length_buffer_(new IOBufferWithSize(sizeof(uint16_t))),
response_length_(0) {}
// DnsAttempt:
@@ -402,10 +403,10 @@ class DnsTCPAttempt : public DnsAttempt {
if (rv < 0)
return rv;
- uint16 query_size = static_cast<uint16>(query_->io_buffer()->size());
+ uint16_t query_size = static_cast<uint16_t>(query_->io_buffer()->size());
if (static_cast<int>(query_size) != query_->io_buffer()->size())
return ERR_FAILED;
- base::WriteBigEndian<uint16>(length_buffer_->data(), query_size);
+ base::WriteBigEndian<uint16_t>(length_buffer_->data(), query_size);
buffer_ =
new DrainableIOBuffer(length_buffer_.get(), length_buffer_->size());
next_state_ = STATE_SEND_LENGTH;
@@ -470,7 +471,7 @@ class DnsTCPAttempt : public DnsAttempt {
return OK;
}
- base::ReadBigEndian<uint16>(length_buffer_->data(), &response_length_);
+ base::ReadBigEndian<uint16_t>(length_buffer_->data(), &response_length_);
// Check if advertised response is too short. (Optimization only.)
if (response_length_ < query_->io_buffer()->size())
return ERR_DNS_MALFORMED_RESPONSE;
@@ -535,7 +536,7 @@ class DnsTCPAttempt : public DnsAttempt {
scoped_refptr<IOBufferWithSize> length_buffer_;
scoped_refptr<DrainableIOBuffer> buffer_;
- uint16 response_length_;
+ uint16_t response_length_;
scoped_ptr<DnsResponse> response_;
CompletionCallback callback_;
@@ -557,18 +558,18 @@ class DnsTransactionImpl : public DnsTransaction,
public:
DnsTransactionImpl(DnsSession* session,
const std::string& hostname,
- uint16 qtype,
+ uint16_t qtype,
const DnsTransactionFactory::CallbackType& callback,
const BoundNetLog& net_log)
- : session_(session),
- hostname_(hostname),
- qtype_(qtype),
- callback_(callback),
- net_log_(net_log),
- qnames_initial_size_(0),
- attempts_count_(0),
- had_tcp_attempt_(false),
- first_server_index_(0) {
+ : session_(session),
+ hostname_(hostname),
+ qtype_(qtype),
+ callback_(callback),
+ net_log_(net_log),
+ qnames_initial_size_(0),
+ attempts_count_(0),
+ had_tcp_attempt_(false),
+ first_server_index_(0) {
DCHECK(session_.get());
DCHECK(!hostname_.empty());
DCHECK(!callback_.is_null());
@@ -587,7 +588,7 @@ class DnsTransactionImpl : public DnsTransaction,
return hostname_;
}
- uint16 GetType() const override {
+ uint16_t GetType() const override {
DCHECK(CalledOnValidThread());
return qtype_;
}
@@ -703,7 +704,7 @@ class DnsTransactionImpl : public DnsTransaction,
AttemptResult MakeAttempt() {
unsigned attempt_number = attempts_.size();
- uint16 id = session_->NextQueryId();
+ uint16_t id = session_->NextQueryId();
scoped_ptr<DnsQuery> query;
if (attempts_.empty()) {
query.reset(new DnsQuery(id, qnames_.front(), qtype_));
@@ -724,9 +725,9 @@ class DnsTransactionImpl : public DnsTransaction,
bool got_socket = !!lease.get();
DnsUDPAttempt* attempt =
- new DnsUDPAttempt(server_index, lease.Pass(), query.Pass());
+ new DnsUDPAttempt(server_index, std::move(lease), std::move(query));
- attempts_.push_back(attempt);
+ attempts_.push_back(make_scoped_ptr(attempt));
++attempts_count_;
if (!got_socket)
@@ -758,7 +759,7 @@ class DnsTransactionImpl : public DnsTransaction,
session_->CreateTCPSocket(server_index, net_log_.source()));
// TODO(szym): Reuse the same id to help the server?
- uint16 id = session_->NextQueryId();
+ uint16_t id = session_->NextQueryId();
scoped_ptr<DnsQuery> query =
previous_attempt->GetQuery()->CloneWithNewId(id);
@@ -768,10 +769,10 @@ class DnsTransactionImpl : public DnsTransaction,
unsigned attempt_number = attempts_.size();
- DnsTCPAttempt* attempt = new DnsTCPAttempt(server_index, socket.Pass(),
- query.Pass());
+ DnsTCPAttempt* attempt =
+ new DnsTCPAttempt(server_index, std::move(socket), std::move(query));
- attempts_.push_back(attempt);
+ attempts_.push_back(make_scoped_ptr(attempt));
++attempts_count_;
had_tcp_attempt_ = true;
@@ -807,7 +808,7 @@ class DnsTransactionImpl : public DnsTransaction,
base::TimeTicks start,
int rv) {
DCHECK_LT(attempt_number, attempts_.size());
- const DnsAttempt* attempt = attempts_[attempt_number];
+ const DnsAttempt* attempt = attempts_[attempt_number].get();
if (attempt->GetResponse()) {
session_->RecordRTT(attempt->server_index(),
base::TimeTicks::Now() - start);
@@ -819,7 +820,7 @@ class DnsTransactionImpl : public DnsTransaction,
if (callback_.is_null())
return;
DCHECK_LT(attempt_number, attempts_.size());
- const DnsAttempt* attempt = attempts_[attempt_number];
+ const DnsAttempt* attempt = attempts_[attempt_number].get();
AttemptResult result = ProcessAttemptResult(AttemptResult(rv, attempt));
if (result.rv != ERR_IO_PENDING)
DoCallback(result);
@@ -909,7 +910,7 @@ class DnsTransactionImpl : public DnsTransaction,
default:
// Server failure.
DCHECK(result.attempt);
- if (result.attempt != attempts_.back()) {
+ if (result.attempt != attempts_.back().get()) {
// This attempt already timed out. Ignore it.
session_->RecordServerFailure(result.attempt->server_index());
return AttemptResult(ERR_IO_PENDING, NULL);
@@ -935,14 +936,14 @@ class DnsTransactionImpl : public DnsTransaction,
return;
DCHECK(!attempts_.empty());
AttemptResult result = ProcessAttemptResult(
- AttemptResult(ERR_DNS_TIMED_OUT, attempts_.back()));
+ AttemptResult(ERR_DNS_TIMED_OUT, attempts_.back().get()));
if (result.rv != ERR_IO_PENDING)
DoCallback(result);
}
scoped_refptr<DnsSession> session_;
std::string hostname_;
- uint16 qtype_;
+ uint16_t qtype_;
// Cleared in DoCallback.
DnsTransactionFactory::CallbackType callback_;
@@ -953,7 +954,7 @@ class DnsTransactionImpl : public DnsTransaction,
size_t qnames_initial_size_;
// List of attempts for the current name.
- ScopedVector<DnsAttempt> attempts_;
+ std::vector<scoped_ptr<DnsAttempt>> attempts_;
// Count of attempts, not reset when |attempts_| vector is cleared.
int attempts_count_;
bool had_tcp_attempt_;
@@ -978,7 +979,7 @@ class DnsTransactionFactoryImpl : public DnsTransactionFactory {
scoped_ptr<DnsTransaction> CreateTransaction(
const std::string& hostname,
- uint16 qtype,
+ uint16_t qtype,
const CallbackType& callback,
const BoundNetLog& net_log) override {
return scoped_ptr<DnsTransaction>(new DnsTransactionImpl(
diff --git a/chromium/net/dns/dns_transaction.h b/chromium/net/dns/dns_transaction.h
index faf4f64e79d..e338cb92956 100644
--- a/chromium/net/dns/dns_transaction.h
+++ b/chromium/net/dns/dns_transaction.h
@@ -5,9 +5,10 @@
#ifndef NET_DNS_DNS_TRANSACTION_H_
#define NET_DNS_DNS_TRANSACTION_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -32,7 +33,7 @@ class NET_EXPORT_PRIVATE DnsTransaction {
virtual const std::string& GetHostname() const = 0;
// Returns the |qtype|.
- virtual uint16 GetType() const = 0;
+ virtual uint16_t GetType() const = 0;
// Starts the transaction. Always completes asynchronously.
virtual void Start() = 0;
@@ -62,7 +63,7 @@ class NET_EXPORT_PRIVATE DnsTransactionFactory {
// The |net_log| is used as the parent log.
virtual scoped_ptr<DnsTransaction> CreateTransaction(
const std::string& hostname,
- uint16 qtype,
+ uint16_t qtype,
const CallbackType& callback,
const BoundNetLog& net_log) WARN_UNUSED_RESULT = 0;
diff --git a/chromium/net/dns/dns_transaction_unittest.cc b/chromium/net/dns/dns_transaction_unittest.cc
index f5a897390a5..7b906ba2a0f 100644
--- a/chromium/net/dns/dns_transaction_unittest.cc
+++ b/chromium/net/dns/dns_transaction_unittest.cc
@@ -4,18 +4,22 @@
#include "net/dns/dns_transaction.h"
+#include <stdint.h>
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/rand_util.h"
#include "base/sys_byteorder.h"
#include "base/test/test_timeouts.h"
-#include "net/base/dns_util.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
#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/socket/socket_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -34,20 +38,20 @@ std::string DomainFromDot(const base::StringPiece& dotted) {
class DnsSocketData {
public:
// The ctor takes parameters for the DnsQuery.
- DnsSocketData(uint16 id,
+ DnsSocketData(uint16_t id,
const char* dotted_name,
- uint16 qtype,
+ uint16_t qtype,
IoMode mode,
bool use_tcp)
: query_(new DnsQuery(id, DomainFromDot(dotted_name), qtype)),
use_tcp_(use_tcp) {
if (use_tcp_) {
- scoped_ptr<uint16> length(new uint16);
+ scoped_ptr<uint16_t> length(new uint16_t);
*length = base::HostToNet16(query_->io_buffer()->size());
writes_.push_back(MockWrite(mode,
reinterpret_cast<const char*>(length.get()),
- sizeof(uint16), num_reads_and_writes()));
- lengths_.push_back(length.Pass());
+ sizeof(uint16_t), num_reads_and_writes()));
+ lengths_.push_back(std::move(length));
}
writes_.push_back(MockWrite(mode, query_->io_buffer()->data(),
query_->io_buffer()->size(),
@@ -58,31 +62,32 @@ class DnsSocketData {
// All responses must be added before GetProvider.
// Adds pre-built DnsResponse. |tcp_length| will be used in TCP mode only.
- void AddResponseWithLength(scoped_ptr<DnsResponse> response, IoMode mode,
- uint16 tcp_length) {
+ void AddResponseWithLength(scoped_ptr<DnsResponse> response,
+ IoMode mode,
+ uint16_t tcp_length) {
CHECK(!provider_.get());
if (use_tcp_) {
- scoped_ptr<uint16> length(new uint16);
+ scoped_ptr<uint16_t> length(new uint16_t);
*length = base::HostToNet16(tcp_length);
reads_.push_back(MockRead(mode,
reinterpret_cast<const char*>(length.get()),
- sizeof(uint16), num_reads_and_writes()));
- lengths_.push_back(length.Pass());
+ sizeof(uint16_t), num_reads_and_writes()));
+ lengths_.push_back(std::move(length));
}
reads_.push_back(MockRead(mode, response->io_buffer()->data(),
response->io_buffer()->size(),
num_reads_and_writes()));
- responses_.push_back(response.Pass());
+ responses_.push_back(std::move(response));
}
// Adds pre-built DnsResponse.
void AddResponse(scoped_ptr<DnsResponse> response, IoMode mode) {
- uint16 tcp_length = response->io_buffer()->size();
- AddResponseWithLength(response.Pass(), mode, tcp_length);
+ uint16_t tcp_length = response->io_buffer()->size();
+ AddResponseWithLength(std::move(response), mode, tcp_length);
}
// Adds pre-built response from |data| buffer.
- void AddResponseData(const uint8* data, size_t length, IoMode mode) {
+ void AddResponseData(const uint8_t* data, size_t length, IoMode mode) {
CHECK(!provider_.get());
AddResponse(make_scoped_ptr(
new DnsResponse(reinterpret_cast<const char*>(data), length, 0)), mode);
@@ -97,7 +102,7 @@ class DnsSocketData {
dns_protocol::Header* header =
reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data());
header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode);
- AddResponse(response.Pass(), mode);
+ AddResponse(std::move(response), mode);
}
// Add error response.
@@ -113,7 +118,7 @@ class DnsSocketData {
// Terminate the reads with ERR_IO_PENDING to prevent overrun and default to
// timeout.
reads_.push_back(
- MockRead(ASYNC, ERR_IO_PENDING, writes_.size() + reads_.size()));
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, writes_.size() + reads_.size()));
provider_.reset(new SequencedSocketData(&reads_[0], reads_.size(),
&writes_[0], writes_.size()));
if (use_tcp_) {
@@ -122,17 +127,15 @@ class DnsSocketData {
return provider_.get();
}
- uint16 query_id() const {
- return query_->id();
- }
+ uint16_t query_id() const { return query_->id(); }
private:
size_t num_reads_and_writes() const { return reads_.size() + writes_.size(); }
scoped_ptr<DnsQuery> query_;
bool use_tcp_;
- ScopedVector<uint16> lengths_;
- ScopedVector<DnsResponse> responses_;
+ std::vector<scoped_ptr<uint16_t>> lengths_;
+ std::vector<scoped_ptr<DnsResponse>> responses_;
std::vector<MockWrite> writes_;
std::vector<MockRead> reads_;
scoped_ptr<SequencedSocketData> provider_;
@@ -194,8 +197,7 @@ class TestSocketFactory : public MockClientSocketFactory {
SocketDataProvider* data_provider = mock_data().GetNext();
scoped_ptr<TestUDPClientSocket> socket(
new TestUDPClientSocket(this, data_provider, net_log));
- data_provider->set_socket(socket.get());
- return socket.Pass();
+ return std::move(socket);
}
void OnConnect(const IPEndPoint& endpoint) {
@@ -221,22 +223,21 @@ class TransactionHelper {
public:
// If |expected_answer_count| < 0 then it is the expected net error.
TransactionHelper(const char* hostname,
- uint16 qtype,
+ uint16_t qtype,
int expected_answer_count)
: hostname_(hostname),
qtype_(qtype),
expected_answer_count_(expected_answer_count),
cancel_in_callback_(false),
quit_in_callback_(false),
- completed_(false) {
- }
+ completed_(false) {}
// Mark that the transaction shall be destroyed immediately upon callback.
void set_cancel_in_callback() {
cancel_in_callback_ = true;
}
- // Mark to call MessageLoop::Quit() upon callback.
+ // Mark to call MessageLoop::QuitWhenIdle() upon callback.
void set_quit_in_callback() {
quit_in_callback_ = true;
}
@@ -274,7 +275,7 @@ class TransactionHelper {
// Tell MessageLoop to quit now, in case any ASSERT_* fails.
if (quit_in_callback_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
if (expected_answer_count_ >= 0) {
ASSERT_EQ(OK, rv);
@@ -315,7 +316,7 @@ class TransactionHelper {
private:
std::string hostname_;
- uint16 qtype_;
+ uint16_t qtype_;
scoped_ptr<DnsTransaction> transaction_;
int expected_answer_count_;
bool cancel_in_callback_;
@@ -359,16 +360,16 @@ class DnsTransactionTest : public testing::Test {
CHECK(socket_factory_.get());
transaction_ids_.push_back(data->query_id());
socket_factory_->AddSocketDataProvider(data->GetProvider());
- socket_data_.push_back(data.Pass());
+ socket_data_.push_back(std::move(data));
}
// Add expected query for |dotted_name| and |qtype| with |id| and response
// taken verbatim from |data| of |data_length| bytes. The transaction id in
// |data| should equal |id|, unless testing mismatched response.
- void AddQueryAndResponse(uint16 id,
+ void AddQueryAndResponse(uint16_t id,
const char* dotted_name,
- uint16 qtype,
- const uint8* response_data,
+ uint16_t qtype,
+ const uint8_t* response_data,
size_t response_length,
IoMode mode,
bool use_tcp) {
@@ -376,55 +377,59 @@ class DnsTransactionTest : public testing::Test {
scoped_ptr<DnsSocketData> data(
new DnsSocketData(id, dotted_name, qtype, mode, use_tcp));
data->AddResponseData(response_data, response_length, mode);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
}
- void AddAsyncQueryAndResponse(uint16 id,
+ void AddAsyncQueryAndResponse(uint16_t id,
const char* dotted_name,
- uint16 qtype,
- const uint8* data,
+ uint16_t qtype,
+ const uint8_t* data,
size_t data_length) {
AddQueryAndResponse(id, dotted_name, qtype, data, data_length, ASYNC,
false);
}
- void AddSyncQueryAndResponse(uint16 id,
+ void AddSyncQueryAndResponse(uint16_t id,
const char* dotted_name,
- uint16 qtype,
- const uint8* data,
+ uint16_t qtype,
+ const uint8_t* data,
size_t data_length) {
AddQueryAndResponse(id, dotted_name, qtype, data, data_length, SYNCHRONOUS,
false);
}
// Add expected query of |dotted_name| and |qtype| and no response.
- void AddQueryAndTimeout(const char* dotted_name, uint16 qtype) {
- uint16 id = base::RandInt(0, kuint16max);
+ void AddQueryAndTimeout(const char* dotted_name, uint16_t qtype) {
+ uint16_t id = base::RandInt(0, std::numeric_limits<uint16_t>::max());
scoped_ptr<DnsSocketData> data(
new DnsSocketData(id, dotted_name, qtype, ASYNC, false));
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
}
// Add expected query of |dotted_name| and |qtype| and matching response with
// no answer and RCODE set to |rcode|. The id will be generated randomly.
void AddQueryAndRcode(const char* dotted_name,
- uint16 qtype,
+ uint16_t qtype,
int rcode,
IoMode mode,
bool use_tcp) {
CHECK_NE(dns_protocol::kRcodeNOERROR, rcode);
- uint16 id = base::RandInt(0, kuint16max);
+ uint16_t id = base::RandInt(0, std::numeric_limits<uint16_t>::max());
scoped_ptr<DnsSocketData> data(
new DnsSocketData(id, dotted_name, qtype, mode, use_tcp));
data->AddRcode(rcode, mode);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
}
- void AddAsyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) {
+ void AddAsyncQueryAndRcode(const char* dotted_name,
+ uint16_t qtype,
+ int rcode) {
AddQueryAndRcode(dotted_name, qtype, rcode, ASYNC, false);
}
- void AddSyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) {
+ void AddSyncQueryAndRcode(const char* dotted_name,
+ uint16_t qtype,
+ int rcode) {
AddQueryAndRcode(dotted_name, qtype, rcode, SYNCHRONOUS, false);
}
@@ -467,7 +472,7 @@ class DnsTransactionTest : public testing::Test {
DnsConfig config_;
- ScopedVector<DnsSocketData> socket_data_;
+ std::vector<scoped_ptr<DnsSocketData>> socket_data_;
std::deque<int> transaction_ids_;
scoped_ptr<TestSocketFactory> socket_factory_;
@@ -514,11 +519,6 @@ TEST_F(DnsTransactionTest, CancelLookup) {
helper1.StartTransaction(transaction_factory_.get());
helper0.Cancel();
- // Since the transaction has been cancelled, the assocaited socket has been
- // destroyed, so make sure the data provide does not attempt to callback
- // to the socket.
- // TODO(rch): Make the SocketDataProvider and MockSocket do this by default.
- socket_data_[0]->GetProvider()->set_socket(nullptr);
base::MessageLoop::current()->RunUntilIdle();
@@ -562,7 +562,7 @@ TEST_F(DnsTransactionTest, MismatchedResponseSync) {
arraysize(kT1ResponseDatagram), SYNCHRONOUS);
data->AddResponseData(kT0ResponseDatagram,
arraysize(kT0ResponseDatagram), SYNCHRONOUS);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -581,7 +581,7 @@ TEST_F(DnsTransactionTest, MismatchedResponseAsync) {
arraysize(kT1ResponseDatagram), ASYNC);
data->AddResponseData(kT0ResponseDatagram,
arraysize(kT0ResponseDatagram), ASYNC);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
AddQueryAndTimeout(kT0HostName, kT0Qtype);
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
@@ -785,19 +785,15 @@ TEST_F(DnsTransactionTest, DontAppendToMultiLabelName) {
EXPECT_TRUE(helper2.Run(transaction_factory_.get()));
}
-const uint8 kResponseNoData[] = {
- 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
- // Question
- 0x01, 'x', 0x01, 'y', 0x01, 'z', 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01,
- // Authority section, SOA record, TTL 0x3E6
- 0x01, 'z', 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE6,
- // Minimal RDATA, 18 bytes
- 0x00, 0x12,
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
+const uint8_t kResponseNoData[] = {
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ // Question
+ 0x01, 'x', 0x01, 'y', 0x01, 'z', 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01,
+ // Authority section, SOA record, TTL 0x3E6
+ 0x01, 'z', 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE6,
+ // Minimal RDATA, 18 bytes
+ 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
TEST_F(DnsTransactionTest, SuffixSearchStop) {
@@ -916,9 +912,8 @@ TEST_F(DnsTransactionTest, TCPMalformed) {
make_scoped_ptr(
new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram),
arraysize(kT0ResponseDatagram), 0)),
- ASYNC,
- static_cast<uint16>(kT0QuerySize - 1));
- AddSocketData(data.Pass());
+ ASYNC, static_cast<uint16_t>(kT0QuerySize - 1));
+ AddSocketData(std::move(data));
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_MALFORMED_RESPONSE);
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
@@ -946,11 +941,10 @@ TEST_F(DnsTransactionTest, TCPReadReturnsZeroAsync) {
make_scoped_ptr(
new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram),
arraysize(kT0ResponseDatagram) - 1, 0)),
- ASYNC,
- static_cast<uint16>(arraysize(kT0ResponseDatagram)));
+ ASYNC, static_cast<uint16_t>(arraysize(kT0ResponseDatagram)));
// Then return a 0-length read.
data->AddReadError(0, ASYNC);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
@@ -966,11 +960,10 @@ TEST_F(DnsTransactionTest, TCPReadReturnsZeroSynchronous) {
make_scoped_ptr(
new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram),
arraysize(kT0ResponseDatagram) - 1, 0)),
- SYNCHRONOUS,
- static_cast<uint16>(arraysize(kT0ResponseDatagram)));
+ SYNCHRONOUS, static_cast<uint16_t>(arraysize(kT0ResponseDatagram)));
// Then return a 0-length read.
data->AddReadError(0, SYNCHRONOUS);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
@@ -982,7 +975,7 @@ TEST_F(DnsTransactionTest, TCPConnectionClosedAsync) {
scoped_ptr<DnsSocketData> data(
new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true));
data->AddReadError(ERR_CONNECTION_CLOSED, ASYNC);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
@@ -994,7 +987,7 @@ TEST_F(DnsTransactionTest, TCPConnectionClosedSynchronous) {
scoped_ptr<DnsSocketData> data(
new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true));
data->AddReadError(ERR_CONNECTION_CLOSED, SYNCHRONOUS);
- AddSocketData(data.Pass());
+ AddSocketData(std::move(data));
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
diff --git a/chromium/net/base/dns_util.cc b/chromium/net/dns/dns_util.cc
index 9afaf4faec9..d2897ff2ae0 100644
--- a/chromium/net/base/dns_util.cc
+++ b/chromium/net/dns/dns_util.cc
@@ -2,10 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/base/dns_util.h"
+#include "net/dns/dns_util.h"
+
+#include <errno.h>
+#include <limits.h>
#include <cstring>
+#include "build/build_config.h"
+
+#if defined(OS_POSIX)
+#include <netinet/in.h>
+#if !defined(OS_NACL)
+#include <net/if.h>
+#if !defined(OS_ANDROID)
+#include <ifaddrs.h>
+#endif // !defined(OS_ANDROID)
+#endif // !defined(OS_NACL)
+#endif // defined(OS_POSIX)
+
+#if defined(OS_ANDROID)
+#include "net/android/network_library.h"
+#endif
+
namespace net {
// Based on DJB's public domain code.
@@ -82,13 +101,55 @@ std::string DNSDomainToString(const base::StringPiece& domain) {
return ret;
}
-std::string TrimEndingDot(const base::StringPiece& host) {
- base::StringPiece host_trimmed = host;
- size_t len = host_trimmed.length();
- if (len > 1 && host_trimmed[len - 1] == '.') {
- host_trimmed.remove_suffix(1);
+bool HaveOnlyLoopbackAddresses() {
+#if defined(OS_ANDROID)
+ return android::HaveOnlyLoopbackAddresses();
+#elif defined(OS_NACL)
+ NOTIMPLEMENTED();
+ return false;
+#elif defined(OS_POSIX)
+ struct ifaddrs* interface_addr = NULL;
+ int rv = getifaddrs(&interface_addr);
+ if (rv != 0) {
+ DVLOG(1) << "getifaddrs() failed with errno = " << errno;
+ return false;
+ }
+
+ bool result = true;
+ for (struct ifaddrs* interface = interface_addr;
+ interface != NULL;
+ interface = interface->ifa_next) {
+ if (!(IFF_UP & interface->ifa_flags))
+ continue;
+ if (IFF_LOOPBACK & interface->ifa_flags)
+ continue;
+ const struct sockaddr* addr = interface->ifa_addr;
+ if (!addr)
+ continue;
+ if (addr->sa_family == AF_INET6) {
+ // Safe cast since this is AF_INET6.
+ const struct sockaddr_in6* addr_in6 =
+ reinterpret_cast<const struct sockaddr_in6*>(addr);
+ const struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
+ if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr))
+ continue;
+ }
+ if (addr->sa_family != AF_INET6 && addr->sa_family != AF_INET)
+ continue;
+
+ result = false;
+ break;
}
- return host_trimmed.as_string();
+ freeifaddrs(interface_addr);
+ return result;
+#elif defined(OS_WIN)
+ // TODO(wtc): implement with the GetAdaptersAddresses function.
+ NOTIMPLEMENTED();
+ return false;
+#else
+ NOTIMPLEMENTED();
+ return false;
+#endif // defined(various platforms)
}
} // namespace net
diff --git a/chromium/net/base/dns_util.h b/chromium/net/dns/dns_util.h
index 141f282f391..74f17cc839d 100644
--- a/chromium/net/base/dns_util.h
+++ b/chromium/net/dns/dns_util.h
@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_BASE_DNS_UTIL_H_
-#define NET_BASE_DNS_UTIL_H_
+#ifndef NET_DNS_DNS_UTIL_H_
+#define NET_DNS_DNS_UTIL_H_
#include <string>
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -26,9 +25,11 @@ NET_EXPORT_PRIVATE bool DNSDomainFromDot(const base::StringPiece& dotted,
NET_EXPORT_PRIVATE std::string DNSDomainToString(
const base::StringPiece& domain);
-// Returns the hostname by trimming the ending dot, if one exists.
-NET_EXPORT std::string TrimEndingDot(const base::StringPiece& host);
+// Returns true if it can determine that only loopback addresses are configured.
+// i.e. if only 127.0.0.1 and ::1 are routable.
+// Also returns false if it cannot determine this.
+NET_EXPORT_PRIVATE bool HaveOnlyLoopbackAddresses();
} // namespace net
-#endif // NET_BASE_DNS_UTIL_H_
+#endif // NET_DNS_DNS_UTIL_H_
diff --git a/chromium/net/base/dns_util_unittest.cc b/chromium/net/dns/dns_util_unittest.cc
index 55e40c119fb..1d534716b6a 100644
--- a/chromium/net/base/dns_util_unittest.cc
+++ b/chromium/net/dns/dns_util_unittest.cc
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/base/dns_util.h"
+#include "net/dns/dns_util.h"
+
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
diff --git a/chromium/net/dns/host_cache.h b/chromium/net/dns/host_cache.h
index e8628fb04ec..70b18930a2a 100644
--- a/chromium/net/dns/host_cache.h
+++ b/chromium/net/dns/host_cache.h
@@ -5,10 +5,14 @@
#ifndef NET_DNS_HOST_CACHE_H_
#define NET_DNS_HOST_CACHE_H_
+#include <stddef.h>
+
#include <functional>
#include <string>
+#include <tuple>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
@@ -46,14 +50,13 @@ class NET_EXPORT HostCache : NON_EXPORTED_BASE(public base::NonThreadSafe) {
host_resolver_flags(host_resolver_flags) {}
bool operator<(const Key& other) const {
+ // The order of comparisons of |Key| fields is arbitrary, thus
// |address_family| and |host_resolver_flags| are compared before
// |hostname| under assumption that integer comparisons are faster than
// string comparisons.
- if (address_family != other.address_family)
- return address_family < other.address_family;
- if (host_resolver_flags != other.host_resolver_flags)
- return host_resolver_flags < other.host_resolver_flags;
- return hostname < other.hostname;
+ return std::tie(address_family, host_resolver_flags, hostname) <
+ std::tie(other.address_family, other.host_resolver_flags,
+ other.hostname);
}
std::string hostname;
diff --git a/chromium/net/dns/host_resolver.cc b/chromium/net/dns/host_resolver.cc
index deacb2d9a62..a4750674937 100644
--- a/chromium/net/dns/host_resolver.cc
+++ b/chromium/net/dns/host_resolver.cc
@@ -8,6 +8,7 @@
#include "base/metrics/field_trial.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "base/values.h"
#include "net/dns/dns_client.h"
#include "net/dns/dns_config_service.h"
#include "net/dns/host_cache.h"
@@ -106,8 +107,8 @@ HostCache* HostResolver::GetHostCache() {
return NULL;
}
-base::Value* HostResolver::GetDnsConfigAsValue() const {
- return NULL;
+scoped_ptr<base::Value> HostResolver::GetDnsConfigAsValue() const {
+ return nullptr;
}
// static
diff --git a/chromium/net/dns/host_resolver.h b/chromium/net/dns/host_resolver.h
index 76ee8e2f54c..93bc62ec549 100644
--- a/chromium/net/dns/host_resolver.h
+++ b/chromium/net/dns/host_resolver.h
@@ -5,9 +5,12 @@
#ifndef NET_DNS_HOST_RESOLVER_H_
#define NET_DNS_HOST_RESOLVER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_family.h"
#include "net/base/completion_callback.h"
@@ -67,7 +70,7 @@ class NET_EXPORT HostResolver {
host_port_pair_ = host_port_pair;
}
- uint16 port() const { return host_port_pair_.port(); }
+ uint16_t port() const { return host_port_pair_.port(); }
const std::string& hostname() const { return host_port_pair_.host(); }
AddressFamily address_family() const { return address_family_; }
@@ -173,10 +176,9 @@ class NET_EXPORT HostResolver {
// Used primarily to clear the cache and for getting debug information.
virtual HostCache* GetHostCache();
- // Returns the current DNS configuration |this| is using, as a Value, or NULL
- // if it's configured to always use the system host resolver. Caller takes
- // ownership of the returned Value.
- virtual base::Value* GetDnsConfigAsValue() const;
+ // Returns the current DNS configuration |this| is using, as a Value, or
+ // nullptr if it's configured to always use the system host resolver.
+ virtual scoped_ptr<base::Value> GetDnsConfigAsValue() const;
// Creates a HostResolver implementation that queries the underlying system.
// (Except if a unit-test has changed the global HostResolverProc using
diff --git a/chromium/net/dns/host_resolver_impl.cc b/chromium/net/dns/host_resolver_impl.cc
index 97345a029e4..16970cd5682 100644
--- a/chromium/net/dns/host_resolver_impl.cc
+++ b/chromium/net/dns/host_resolver_impl.cc
@@ -4,6 +4,8 @@
#include "net/dns/host_resolver_impl.h"
+#include <utility>
+
#if defined(OS_WIN)
#include <Winsock2.h>
#elif defined(OS_POSIX)
@@ -14,13 +16,14 @@
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
@@ -35,8 +38,6 @@
#include "base/values.h"
#include "net/base/address_family.h"
#include "net/base/address_list.h"
-#include "net/base/dns_reloader.h"
-#include "net/base/dns_util.h"
#include "net/base/host_port_pair.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
@@ -45,8 +46,10 @@
#include "net/dns/dns_client.h"
#include "net/dns/dns_config_service.h"
#include "net/dns/dns_protocol.h"
+#include "net/dns/dns_reloader.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_transaction.h"
+#include "net/dns/dns_util.h"
#include "net/dns/host_resolver_proc.h"
#include "net/log/net_log.h"
#include "net/socket/client_socket_factory.h"
@@ -216,7 +219,7 @@ bool IsGloballyReachable(const IPAddressNumber& dest,
bool is_link_local = (address[0] == 0xFE) && ((address[1] & 0xC0) == 0x80);
if (is_link_local)
return false;
- const uint8 kTeredoPrefix[] = { 0x20, 0x01, 0, 0 };
+ const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0};
bool is_teredo = std::equal(kTeredoPrefix,
kTeredoPrefix + arraysize(kTeredoPrefix),
address.begin());
@@ -287,7 +290,7 @@ bool ConfigureAsyncDnsNoFallbackFieldTrial() {
//-----------------------------------------------------------------------------
-AddressList EnsurePortOnAddressList(const AddressList& list, uint16 port) {
+AddressList EnsurePortOnAddressList(const AddressList& list, uint16_t port) {
if (list.empty() || list.front().port() == port)
return list;
return AddressList::CopyWithPort(list, port);
@@ -314,7 +317,7 @@ bool IsAllIPv4Loopback(const AddressList& addresses) {
// Creates NetLog parameters when the resolve failed.
scoped_ptr<base::Value> NetLogProcTaskFailedCallback(
- uint32 attempt_number,
+ uint32_t attempt_number,
int net_error,
int os_error,
NetLogCaptureMode /* capture_mode */) {
@@ -343,7 +346,7 @@ scoped_ptr<base::Value> NetLogProcTaskFailedCallback(
#endif
}
- return dict.Pass();
+ return std::move(dict);
}
// Creates NetLog parameters when the DnsTask failed.
@@ -355,7 +358,7 @@ scoped_ptr<base::Value> NetLogDnsTaskFailedCallback(
dict->SetInteger("net_error", net_error);
if (dns_error)
dict->SetInteger("dns_error", dns_error);
- return dict.Pass();
+ return std::move(dict);
};
// Creates NetLog parameters containing the information in a RequestInfo object,
@@ -370,7 +373,7 @@ scoped_ptr<base::Value> NetLogRequestInfoCallback(
static_cast<int>(info->address_family()));
dict->SetBoolean("allow_cached_response", info->allow_cached_response());
dict->SetBoolean("is_speculative", info->is_speculative());
- return dict.Pass();
+ return std::move(dict);
}
// Creates NetLog parameters for the creation of a HostResolverImpl::Job.
@@ -381,7 +384,7 @@ scoped_ptr<base::Value> NetLogJobCreationCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
source.AddToEventParameters(dict.get());
dict->SetString("host", *host);
- return dict.Pass();
+ return std::move(dict);
}
// Creates NetLog parameters for HOST_RESOLVER_IMPL_JOB_ATTACH/DETACH events.
@@ -392,14 +395,14 @@ scoped_ptr<base::Value> NetLogJobAttachCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
source.AddToEventParameters(dict.get());
dict->SetString("priority", RequestPriorityToString(priority));
- return dict.Pass();
+ return std::move(dict);
}
// Creates NetLog parameters for the DNS_CONFIG_CHANGED event.
scoped_ptr<base::Value> NetLogDnsConfigCallback(
const DnsConfig* config,
NetLogCaptureMode /* capture_mode */) {
- return make_scoped_ptr(config->ToValue());
+ return config->ToValue();
}
scoped_ptr<base::Value> NetLogIPv6AvailableCallback(
@@ -409,7 +412,7 @@ scoped_ptr<base::Value> NetLogIPv6AvailableCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetBoolean("ipv6_available", ipv6_available);
dict->SetBoolean("cached", cached);
- return dict.Pass();
+ return std::move(dict);
}
// The logging routines are defined here because some requests are resolved
@@ -675,9 +678,8 @@ class HostResolverImpl::ProcTask
return;
}
- net_log_.AddEvent(
- NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED,
- NetLog::IntegerCallback("attempt_number", attempt_number_));
+ net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED,
+ NetLog::IntCallback("attempt_number", attempt_number_));
// If we don't get the results within a given time, RetryIfNotComplete
// will start a new attempt on a different worker thread if none of our
@@ -696,7 +698,7 @@ class HostResolverImpl::ProcTask
// may no longer exist. Multiple DoLookups() could be running in parallel, so
// any state inside of |this| must not mutate .
void DoLookup(const base::TimeTicks& start_time,
- const uint32 attempt_number) {
+ const uint32_t attempt_number) {
AddressList results;
int os_error = 0;
// Running on the worker thread
@@ -742,7 +744,7 @@ class HostResolverImpl::ProcTask
// Callback for when DoLookup() completes (runs on task runner thread).
void OnLookupComplete(const AddressList& results,
const base::TimeTicks& start_time,
- const uint32 attempt_number,
+ const uint32_t attempt_number,
int error,
const int os_error) {
DCHECK(task_runner_->BelongsToCurrentThread());
@@ -777,8 +779,7 @@ class HostResolverImpl::ProcTask
error,
os_error);
} else {
- net_log_callback = NetLog::IntegerCallback("attempt_number",
- attempt_number);
+ net_log_callback = NetLog::IntCallback("attempt_number", attempt_number);
}
net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_FINISHED,
net_log_callback);
@@ -876,7 +877,7 @@ class HostResolverImpl::ProcTask
}
void RecordAttemptHistograms(const base::TimeTicks& start_time,
- const uint32 attempt_number,
+ const uint32_t attempt_number,
const int error,
const int os_error) const {
DCHECK(task_runner_->BelongsToCurrentThread());
@@ -944,11 +945,11 @@ class HostResolverImpl::ProcTask
// Keeps track of the number of attempts we have made so far to resolve the
// host. Whenever we start an attempt to resolve the host, we increase this
// number.
- uint32 attempt_number_;
+ uint32_t attempt_number_;
// The index of the attempt which finished first (or 0 if the job is still in
// progress).
- uint32 completed_attempt_number_;
+ uint32_t completed_attempt_number_;
// The result (a net error code) from the first attempt to complete.
int completed_attempt_error_;
@@ -1288,9 +1289,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
// else CompleteRequests logged EndEvent.
// Log any remaining Requests as cancelled.
- for (RequestsList::const_iterator it = requests_.begin();
- it != requests_.end(); ++it) {
- Request* req = *it;
+ for (const scoped_ptr<Request>& req : requests_) {
if (req->was_canceled())
continue;
DCHECK_EQ(this, req->job());
@@ -1340,7 +1339,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
proc_task_->set_had_non_speculative_request();
}
- requests_.push_back(req.Pass());
+ requests_.push_back(std::move(req));
UpdatePriority();
}
@@ -1373,6 +1372,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
// Called from AbortAllInProgressJobs. Completes all requests and destroys
// the job. This currently assumes the abort is due to a network change.
+ // TODO This should not delete |this|.
void Abort() {
DCHECK(is_running());
CompleteRequestsWithError(ERR_NETWORK_CHANGED);
@@ -1732,10 +1732,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
resolver_->CacheResult(key_, entry, ttl);
// Complete all of the requests that were attached to the job.
- for (RequestsList::const_iterator it = requests_.begin();
- it != requests_.end(); ++it) {
- Request* req = *it;
-
+ for (const scoped_ptr<Request>& req : requests_) {
if (req->was_canceled())
continue;
@@ -1809,7 +1806,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
scoped_ptr<DnsTask> dns_task_;
// All Requests waiting for the result of this Job. Some can be canceled.
- RequestsList requests_;
+ std::vector<scoped_ptr<Request>> requests_;
// A handle used in |HostResolverImpl::dispatcher_|.
PrioritizedDispatcher::Handle handle_;
@@ -1960,7 +1957,7 @@ int HostResolverImpl::Resolve(const RequestInfo& info,
if (out_req)
*out_req = reinterpret_cast<RequestHandle>(req.get());
- job->AddRequest(req.Pass());
+ job->AddRequest(std::move(req));
// Completion happens during Job::CompleteRequests().
return ERR_IO_PENDING;
}
@@ -2041,16 +2038,16 @@ HostCache* HostResolverImpl::GetHostCache() {
return cache_.get();
}
-base::Value* HostResolverImpl::GetDnsConfigAsValue() const {
+scoped_ptr<base::Value> HostResolverImpl::GetDnsConfigAsValue() const {
// Check if async DNS is disabled.
if (!dns_client_.get())
- return NULL;
+ return nullptr;
// Check if async DNS is enabled, but we currently have no configuration
// for it.
const DnsConfig* dns_config = dns_client_->GetConfig();
if (dns_config == NULL)
- return new base::DictionaryValue();
+ return make_scoped_ptr(new base::DictionaryValue());
return dns_config->ToValue();
}
@@ -2252,11 +2249,11 @@ bool HostResolverImpl::IsIPv6Reachable(const BoundNetLog& net_log) {
void HostResolverImpl::AbortAllInProgressJobs() {
// In Abort, a Request callback could spawn new Jobs with matching keys, so
// first collect and remove all running jobs from |jobs_|.
- ScopedVector<Job> jobs_to_abort;
+ std::vector<scoped_ptr<Job>> jobs_to_abort;
for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) {
Job* job = it->second;
if (job->is_running()) {
- jobs_to_abort.push_back(job);
+ jobs_to_abort.push_back(make_scoped_ptr(job));
jobs_.erase(it++);
} else {
DCHECK(job->is_queued());
@@ -2278,7 +2275,7 @@ void HostResolverImpl::AbortAllInProgressJobs() {
// Then Abort them.
for (size_t i = 0; self.get() && i < jobs_to_abort.size(); ++i) {
jobs_to_abort[i]->Abort();
- jobs_to_abort[i] = NULL;
+ ignore_result(jobs_to_abort[i].release());
}
if (self)
@@ -2423,7 +2420,7 @@ void HostResolverImpl::OnDnsTaskResolve(int net_error) {
void HostResolverImpl::SetDnsClient(scoped_ptr<DnsClient> dns_client) {
// DnsClient and config must be updated before aborting DnsTasks, since doing
// so may start new jobs.
- dns_client_ = dns_client.Pass();
+ dns_client_ = std::move(dns_client);
if (dns_client_ && !dns_client_->GetConfig() &&
num_dns_failures_ < kMaximumDnsFailures) {
DnsConfig dns_config;
diff --git a/chromium/net/dns/host_resolver_impl.h b/chromium/net/dns/host_resolver_impl.h
index dd3cb3df443..7c454991736 100644
--- a/chromium/net/dns/host_resolver_impl.h
+++ b/chromium/net/dns/host_resolver_impl.h
@@ -5,11 +5,13 @@
#ifndef NET_DNS_HOST_RESOLVER_IMPL_H_
#define NET_DNS_HOST_RESOLVER_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
@@ -93,7 +95,7 @@ class NET_EXPORT HostResolverImpl
base::TimeDelta unresponsive_delay;
// Factor to grow |unresponsive_delay| when we re-re-try.
- uint32 retry_factor;
+ uint32_t retry_factor;
};
// Creates a HostResolver as specified by |options|.
@@ -136,7 +138,7 @@ class NET_EXPORT HostResolverImpl
void CancelRequest(RequestHandle req) override;
void SetDnsClientEnabled(bool enabled) override;
HostCache* GetHostCache() override;
- base::Value* GetDnsConfigAsValue() const override;
+ scoped_ptr<base::Value> GetDnsConfigAsValue() const override;
void set_proc_params_for_test(const ProcTaskParams& proc_params) {
proc_params_ = proc_params;
@@ -151,7 +153,6 @@ class NET_EXPORT HostResolverImpl
class Request;
typedef HostCache::Key Key;
typedef std::map<Key, Job*> JobMap;
- typedef ScopedVector<Request> RequestsList;
// Number of consecutive failures of DnsTask (with successful fallback to
// ProcTask) before the DnsClient is disabled until the next DNS change.
diff --git a/chromium/net/dns/host_resolver_impl_unittest.cc b/chromium/net/dns/host_resolver_impl_unittest.cc
index 2ab20b71378..569d1ab8ad8 100644
--- a/chromium/net/dns/host_resolver_impl_unittest.cc
+++ b/chromium/net/dns/host_resolver_impl_unittest.cc
@@ -6,12 +6,15 @@
#include <algorithm>
#include <string>
+#include <tuple>
+#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -61,8 +64,8 @@ class MockHostResolverProc : public HostResolverProc {
ResolveKey(const std::string& hostname, AddressFamily address_family)
: hostname(hostname), address_family(address_family) {}
bool operator<(const ResolveKey& other) const {
- return address_family < other.address_family ||
- (address_family == other.address_family && hostname < other.hostname);
+ return std::tie(address_family, hostname) <
+ std::tie(other.address_family, other.hostname);
}
std::string hostname;
AddressFamily address_family;
@@ -184,8 +187,9 @@ class MockHostResolverProc : public HostResolverProc {
DISALLOW_COPY_AND_ASSIGN(MockHostResolverProc);
};
-bool AddressListContains(const AddressList& list, const std::string& address,
- uint16 port) {
+bool AddressListContains(const AddressList& list,
+ const std::string& address,
+ uint16_t port) {
IPAddressNumber ip;
bool rv = ParseIPLiteralToNumber(address, &ip);
DCHECK(rv);
@@ -253,7 +257,7 @@ class Request {
bool completed() const { return result_ != ERR_IO_PENDING; }
bool pending() const { return handle_ != NULL; }
- bool HasAddress(const std::string& address, uint16 port) const {
+ bool HasAddress(const std::string& address, uint16_t port) const {
return AddressListContains(list_, address, port);
}
@@ -262,7 +266,7 @@ class Request {
return list_.size();
}
- bool HasOneAddress(const std::string& address, uint16 port) const {
+ bool HasOneAddress(const std::string& address, uint16_t port) const {
return HasAddress(address, port) && (NumberOfAddresses() == 1u);
}
@@ -270,7 +274,7 @@ class Request {
int WaitForResult() {
if (completed())
return result_;
- base::CancelableClosure closure(base::MessageLoop::QuitClosure());
+ base::CancelableClosure closure(base::MessageLoop::QuitWhenIdleClosure());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, closure.callback(), TestTimeouts::action_max_timeout());
quit_on_complete_ = true;
@@ -298,7 +302,7 @@ class Request {
if (handler_)
handler_->Handle(this);
if (quit_on_complete_) {
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
quit_on_complete_ = false;
}
}
@@ -480,7 +484,7 @@ class HostResolverImplTest : public testing::Test {
Request* CreateRequest(const std::string& hostname) {
return test->CreateRequest(hostname);
}
- ScopedVector<Request>& requests() { return test->requests_; }
+ std::vector<scoped_ptr<Request>>& requests() { return test->requests_; }
void DeleteResolver() { test->resolver_.reset(); }
@@ -509,10 +513,9 @@ class HostResolverImplTest : public testing::Test {
// not start until released by |proc_->SignalXXX|.
Request* CreateRequest(const HostResolver::RequestInfo& info,
RequestPriority priority) {
- Request* req = new Request(
- info, priority, requests_.size(), resolver_.get(), handler_.get());
- requests_.push_back(req);
- return req;
+ requests_.push_back(make_scoped_ptr(new Request(
+ info, priority, requests_.size(), resolver_.get(), handler_.get())));
+ return requests_.back().get();
}
Request* CreateRequest(const std::string& hostname,
@@ -564,7 +567,7 @@ class HostResolverImplTest : public testing::Test {
scoped_refptr<MockHostResolverProc> proc_;
scoped_ptr<HostResolverImpl> resolver_;
- ScopedVector<Request> requests_;
+ std::vector<scoped_ptr<Request>> requests_;
scoped_ptr<Handler> handler_;
};
@@ -847,7 +850,7 @@ TEST_F(HostResolverImplTest, DeleteWithinCallback) {
// Quit after returning from OnCompleted (to give it a chance at
// incorrectly running the cancelled tasks).
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
};
set_handler(new MyHandler());
@@ -873,7 +876,7 @@ TEST_F(HostResolverImplTest, DeleteWithinAbortedCallback) {
// Quit after returning from OnCompleted (to give it a chance at
// incorrectly running the cancelled tasks).
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
};
set_handler(new MyHandler());
@@ -951,7 +954,7 @@ TEST_F(HostResolverImplTest, BypassCache) {
CreateRequest(info, DEFAULT_PRIORITY)->Resolve());
} else if (71 == req->info().port()) {
// Test is done.
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
} else {
FAIL() << "Unexpected request";
}
@@ -1473,7 +1476,7 @@ class HostResolverImplDnsTest : public HostResolverImplTest {
// Adds a rule to |dns_rules_|. Must be followed by |CreateResolver| to apply.
void AddDnsRule(const std::string& prefix,
- uint16 qtype,
+ uint16_t qtype,
MockDnsClientRule::Result result,
bool delay) {
dns_rules_.push_back(MockDnsClientRule(prefix, qtype, result, delay));
diff --git a/chromium/net/dns/host_resolver_mojo.cc b/chromium/net/dns/host_resolver_mojo.cc
index 161f586f61a..1daf6338fd4 100644
--- a/chromium/net/dns/host_resolver_mojo.cc
+++ b/chromium/net/dns/host_resolver_mojo.cc
@@ -4,11 +4,13 @@
#include "net/dns/host_resolver_mojo.h"
+#include <utility>
+
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/dns/mojo_host_type_converters.h"
#include "net/log/net_log.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
namespace net {
namespace {
@@ -78,7 +80,7 @@ int HostResolverMojo::Resolve(const RequestInfo& info,
*request_handle = new Job(key, addresses, callback, mojo::GetProxy(&handle),
host_cache_weak_factory_.GetWeakPtr());
impl_->ResolveDns(interfaces::HostResolverRequestInfo::From(info),
- handle.Pass());
+ std::move(handle));
return ERR_IO_PENDING;
}
@@ -125,7 +127,7 @@ HostResolverMojo::Job::Job(
: key_(key),
addresses_(addresses),
callback_(callback),
- binding_(this, request.Pass()),
+ binding_(this, std::move(request)),
host_cache_(host_cache) {
binding_.set_connection_error_handler(base::Bind(
&HostResolverMojo::Job::OnConnectionError, base::Unretained(this)));
diff --git a/chromium/net/dns/host_resolver_mojo.h b/chromium/net/dns/host_resolver_mojo.h
index 23fb0ff0c8b..905d6c944d2 100644
--- a/chromium/net/dns/host_resolver_mojo.h
+++ b/chromium/net/dns/host_resolver_mojo.h
@@ -5,6 +5,7 @@
#ifndef NET_DNS_HOST_RESOLVER_MOJO_H_
#define NET_DNS_HOST_RESOLVER_MOJO_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "net/dns/host_cache.h"
diff --git a/chromium/net/dns/host_resolver_mojo_unittest.cc b/chromium/net/dns/host_resolver_mojo_unittest.cc
index 209bda88a81..c5f3ba9433f 100644
--- a/chromium/net/dns/host_resolver_mojo_unittest.cc
+++ b/chromium/net/dns/host_resolver_mojo_unittest.cc
@@ -5,8 +5,9 @@
#include "net/dns/host_resolver_mojo.h"
#include <string>
+#include <utility>
-#include "base/memory/scoped_vector.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
@@ -14,7 +15,6 @@
#include "net/dns/mojo_host_type_converters.h"
#include "net/test/event_waiter.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
namespace net {
namespace {
@@ -37,7 +37,7 @@ class MockMojoHostResolverRequest {
MockMojoHostResolverRequest::MockMojoHostResolverRequest(
interfaces::HostResolverRequestClientPtr client,
const base::Closure& error_callback)
- : client_(client.Pass()), error_callback_(error_callback) {
+ : client_(std::move(client)), error_callback_(error_callback) {
client_.set_connection_error_handler(base::Bind(
&MockMojoHostResolverRequest::OnConnectionError, base::Unretained(this)));
}
@@ -56,26 +56,26 @@ struct HostResolverAction {
static scoped_ptr<HostResolverAction> ReturnError(Error error) {
scoped_ptr<HostResolverAction> result(new HostResolverAction);
result->error = error;
- return result.Pass();
+ return result;
}
static scoped_ptr<HostResolverAction> ReturnResult(
const AddressList& address_list) {
scoped_ptr<HostResolverAction> result(new HostResolverAction);
result->addresses = interfaces::AddressList::From(address_list);
- return result.Pass();
+ return result;
}
static scoped_ptr<HostResolverAction> DropRequest() {
scoped_ptr<HostResolverAction> result(new HostResolverAction);
result->action = DROP;
- return result.Pass();
+ return result;
}
static scoped_ptr<HostResolverAction> RetainRequest() {
scoped_ptr<HostResolverAction> result(new HostResolverAction);
result->action = RETAIN;
- return result.Pass();
+ return result;
}
Action action = COMPLETE;
@@ -99,11 +99,11 @@ class MockMojoHostResolver : public HostResolverMojo::Impl {
interfaces::HostResolverRequestClientPtr client) override;
private:
- ScopedVector<HostResolverAction> actions_;
+ std::vector<scoped_ptr<HostResolverAction>> actions_;
size_t results_returned_ = 0;
mojo::Array<interfaces::HostResolverRequestInfoPtr> requests_received_;
const base::Closure request_connection_error_callback_;
- ScopedVector<MockMojoHostResolverRequest> requests_;
+ std::vector<scoped_ptr<MockMojoHostResolverRequest>> requests_;
};
MockMojoHostResolver::MockMojoHostResolver(
@@ -116,22 +116,22 @@ MockMojoHostResolver::~MockMojoHostResolver() {
}
void MockMojoHostResolver::AddAction(scoped_ptr<HostResolverAction> action) {
- actions_.push_back(action.Pass());
+ actions_.push_back(std::move(action));
}
void MockMojoHostResolver::ResolveDns(
interfaces::HostResolverRequestInfoPtr request_info,
interfaces::HostResolverRequestClientPtr client) {
- requests_received_.push_back(request_info.Pass());
+ requests_received_.push_back(std::move(request_info));
ASSERT_LE(results_returned_, actions_.size());
switch (actions_[results_returned_]->action) {
case HostResolverAction::COMPLETE:
client->ReportResult(actions_[results_returned_]->error,
- actions_[results_returned_]->addresses.Pass());
+ std::move(actions_[results_returned_]->addresses));
break;
case HostResolverAction::RETAIN:
- requests_.push_back(new MockMojoHostResolverRequest(
- client.Pass(), request_connection_error_callback_));
+ requests_.push_back(make_scoped_ptr(new MockMojoHostResolverRequest(
+ std::move(client), request_connection_error_callback_)));
break;
case HostResolverAction::DROP:
client.reset();
diff --git a/chromium/net/dns/host_resolver_proc.cc b/chromium/net/dns/host_resolver_proc.cc
index 98b98125c1b..4bed222a215 100644
--- a/chromium/net/dns/host_resolver_proc.cc
+++ b/chromium/net/dns/host_resolver_proc.cc
@@ -9,10 +9,10 @@
#include "base/logging.h"
#include "base/sys_byteorder.h"
#include "net/base/address_list.h"
-#include "net/base/dns_reloader.h"
-#include "net/base/dns_util.h"
#include "net/base/net_errors.h"
#include "net/base/sys_addrinfo.h"
+#include "net/dns/dns_reloader.h"
+#include "net/dns/dns_util.h"
#if defined(OS_OPENBSD)
#define AI_ADDRCONFIG 0
diff --git a/chromium/net/dns/host_resolver_proc.h b/chromium/net/dns/host_resolver_proc.h
index cb61e195df3..182298b7f5a 100644
--- a/chromium/net/dns/host_resolver_proc.h
+++ b/chromium/net/dns/host_resolver_proc.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/address_family.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/dns/mapped_host_resolver.cc b/chromium/net/dns/mapped_host_resolver.cc
index fedc05f0072..97461148873 100644
--- a/chromium/net/dns/mapped_host_resolver.cc
+++ b/chromium/net/dns/mapped_host_resolver.cc
@@ -4,7 +4,10 @@
#include "net/dns/mapped_host_resolver.h"
+#include <utility>
+
#include "base/strings/string_util.h"
+#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
@@ -12,8 +15,7 @@
namespace net {
MappedHostResolver::MappedHostResolver(scoped_ptr<HostResolver> impl)
- : impl_(impl.Pass()) {
-}
+ : impl_(std::move(impl)) {}
MappedHostResolver::~MappedHostResolver() {
}
@@ -55,7 +57,7 @@ HostCache* MappedHostResolver::GetHostCache() {
return impl_->GetHostCache();
}
-base::Value* MappedHostResolver::GetDnsConfigAsValue() const {
+scoped_ptr<base::Value> MappedHostResolver::GetDnsConfigAsValue() const {
return impl_->GetDnsConfigAsValue();
}
diff --git a/chromium/net/dns/mapped_host_resolver.h b/chromium/net/dns/mapped_host_resolver.h
index ecdc2e8adbf..b5b946002ec 100644
--- a/chromium/net/dns/mapped_host_resolver.h
+++ b/chromium/net/dns/mapped_host_resolver.h
@@ -57,7 +57,7 @@ class NET_EXPORT MappedHostResolver : public HostResolver {
void CancelRequest(RequestHandle req) override;
void SetDnsClientEnabled(bool enabled) override;
HostCache* GetHostCache() override;
- base::Value* GetDnsConfigAsValue() const override;
+ scoped_ptr<base::Value> GetDnsConfigAsValue() const override;
private:
// Modify the request |info| according to |rules_|. Returns either OK or
diff --git a/chromium/net/dns/mapped_host_resolver_unittest.cc b/chromium/net/dns/mapped_host_resolver_unittest.cc
index 5218e2afb40..002a9888b56 100644
--- a/chromium/net/dns/mapped_host_resolver_unittest.cc
+++ b/chromium/net/dns/mapped_host_resolver_unittest.cc
@@ -4,6 +4,8 @@
#include "net/dns/mapped_host_resolver.h"
+#include <utility>
+
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
@@ -32,7 +34,7 @@ TEST(MappedHostResolverTest, Inclusion) {
// Create a remapped resolver that uses |resolver_impl|.
scoped_ptr<MappedHostResolver> resolver(
- new MappedHostResolver(resolver_impl.Pass()));
+ new MappedHostResolver(std::move(resolver_impl)));
int rv;
AddressList address_list;
@@ -106,7 +108,7 @@ TEST(MappedHostResolverTest, Exclusion) {
// Create a remapped resolver that uses |resolver_impl|.
scoped_ptr<MappedHostResolver> resolver(
- new MappedHostResolver(resolver_impl.Pass()));
+ new MappedHostResolver(std::move(resolver_impl)));
int rv;
AddressList address_list;
@@ -153,7 +155,7 @@ TEST(MappedHostResolverTest, SetRulesFromString) {
// Create a remapped resolver that uses |resolver_impl|.
scoped_ptr<MappedHostResolver> resolver(
- new MappedHostResolver(resolver_impl.Pass()));
+ new MappedHostResolver(std::move(resolver_impl)));
int rv;
AddressList address_list;
@@ -210,7 +212,7 @@ TEST(MappedHostResolverTest, MapToError) {
resolver_impl->rules()->AddRule("*", "192.168.1.5");
scoped_ptr<MappedHostResolver> resolver(
- new MappedHostResolver(resolver_impl.Pass()));
+ new MappedHostResolver(std::move(resolver_impl)));
int rv;
AddressList address_list;
diff --git a/chromium/net/dns/mdns_cache.cc b/chromium/net/dns/mdns_cache.cc
index 010a34f45d4..2c57828ba72 100644
--- a/chromium/net/dns/mdns_cache.cc
+++ b/chromium/net/dns/mdns_cache.cc
@@ -5,9 +5,9 @@
#include "net/dns/mdns_cache.h"
#include <algorithm>
+#include <tuple>
#include <utility>
-#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/record_parsed.h"
@@ -44,16 +44,9 @@ MDnsCache::Key& MDnsCache::Key::operator=(
MDnsCache::Key::~Key() {
}
-bool MDnsCache::Key::operator<(const MDnsCache::Key& key) const {
- if (name_ != key.name_)
- return name_ < key.name_;
-
- if (type_ != key.type_)
- return type_ < key.type_;
-
- if (optional_ != key.optional_)
- return optional_ < key.optional_;
- return false; // keys are equal
+bool MDnsCache::Key::operator<(const MDnsCache::Key& other) const {
+ return std::tie(name_, type_, optional_) <
+ std::tie(other.name_, other.type_, other.optional_);
}
bool MDnsCache::Key::operator==(const MDnsCache::Key& key) const {
@@ -72,20 +65,14 @@ MDnsCache::MDnsCache() {
}
MDnsCache::~MDnsCache() {
- Clear();
-}
-
-void MDnsCache::Clear() {
- next_expiration_ = base::Time();
- STLDeleteValues(&mdns_cache_);
}
const RecordParsed* MDnsCache::LookupKey(const Key& key) {
RecordMap::iterator found = mdns_cache_.find(key);
if (found != mdns_cache_.end()) {
- return found->second;
+ return found->second.get();
}
- return NULL;
+ return nullptr;
}
MDnsCache::UpdateType MDnsCache::UpdateDnsRecord(
@@ -101,20 +88,18 @@ MDnsCache::UpdateType MDnsCache::UpdateDnsRecord(
new_expiration = std::min(new_expiration, next_expiration_);
std::pair<RecordMap::iterator, bool> insert_result =
- mdns_cache_.insert(std::make_pair(cache_key, (const RecordParsed*)NULL));
+ mdns_cache_.insert(std::make_pair(cache_key, nullptr));
UpdateType type = NoChange;
if (insert_result.second) {
type = RecordAdded;
} else {
- const RecordParsed* other_record = insert_result.first->second;
-
- if (record->ttl() != 0 && !record->IsEqual(other_record, true)) {
+ if (record->ttl() != 0 &&
+ !record->IsEqual(insert_result.first->second.get(), true)) {
type = RecordChanged;
}
- delete other_record;
}
- insert_result.first->second = record.release();
+ insert_result.first->second = std::move(record);
next_expiration_ = new_expiration;
return type;
}
@@ -131,10 +116,9 @@ void MDnsCache::CleanupRecords(
for (RecordMap::iterator i = mdns_cache_.begin();
i != mdns_cache_.end(); ) {
- base::Time expiration = GetEffectiveExpiration(i->second);
+ base::Time expiration = GetEffectiveExpiration(i->second.get());
if (now >= expiration) {
- record_removed_callback.Run(i->second);
- delete i->second;
+ record_removed_callback.Run(i->second.get());
mdns_cache_.erase(i++);
} else {
if (next_expiration == base::Time() || expiration < next_expiration) {
@@ -161,7 +145,7 @@ void MDnsCache::FindDnsRecords(unsigned type,
break;
}
- const RecordParsed* record = i->second;
+ const RecordParsed* record = i->second.get();
// Records are deleted only upon request.
if (now >= GetEffectiveExpiration(record)) continue;
@@ -175,17 +159,17 @@ scoped_ptr<const RecordParsed> MDnsCache::RemoveRecord(
Key key = Key::CreateFor(record);
RecordMap::iterator found = mdns_cache_.find(key);
- if (found != mdns_cache_.end() && found->second == record) {
+ if (found != mdns_cache_.end() && found->second.get() == record) {
+ scoped_ptr<const RecordParsed> result = std::move(found->second);
mdns_cache_.erase(key);
- return scoped_ptr<const RecordParsed>(record);
+ return result;
}
return scoped_ptr<const RecordParsed>();
}
// static
-std::string MDnsCache::GetOptionalFieldForRecord(
- const RecordParsed* record) {
+std::string MDnsCache::GetOptionalFieldForRecord(const RecordParsed* record) {
switch (record->type()) {
case PtrRecordRdata::kType: {
const PtrRecordRdata* rdata = record->rdata<PtrRecordRdata>();
diff --git a/chromium/net/dns/mdns_cache.h b/chromium/net/dns/mdns_cache.h
index 6a38fc8f0e2..38f121a9ef3 100644
--- a/chromium/net/dns/mdns_cache.h
+++ b/chromium/net/dns/mdns_cache.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
@@ -92,10 +93,8 @@ class NET_EXPORT_PRIVATE MDnsCache {
// passed in if it was removed, scoped null otherwise.
scoped_ptr<const RecordParsed> RemoveRecord(const RecordParsed* record);
- void Clear();
-
private:
- typedef std::map<Key, const RecordParsed*> RecordMap;
+ typedef std::map<Key, scoped_ptr<const RecordParsed>> RecordMap;
// Get the effective expiration of a cache entry, based on its creation time
// and TTL. Does adjustments so entries with a TTL of zero will have a
@@ -105,8 +104,7 @@ class NET_EXPORT_PRIVATE MDnsCache {
// Get optional part of the DNS key for shared records. For example, in PTR
// records this is the pointed domain, since multiple PTR records may exist
// for the same name.
- static std::string GetOptionalFieldForRecord(
- const RecordParsed* record);
+ static std::string GetOptionalFieldForRecord(const RecordParsed* record);
RecordMap mdns_cache_;
diff --git a/chromium/net/dns/mdns_cache_unittest.cc b/chromium/net/dns/mdns_cache_unittest.cc
index c12ad6b6ec3..0659e4f97c8 100644
--- a/chromium/net/dns/mdns_cache_unittest.cc
+++ b/chromium/net/dns/mdns_cache_unittest.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "net/dns/mdns_cache.h"
+
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_test_util.h"
-#include "net/dns/mdns_cache.h"
#include "net/dns/record_parsed.h"
#include "net/dns/record_rdata.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -18,111 +20,83 @@ using ::testing::StrictMock;
namespace net {
-static const uint8 kTestResponsesDifferentAnswers[] = {
- // Answer 1
- // ghs.l.google.com in DNS format.
- 3, 'g', 'h', 's',
- 1, 'l',
- 6, 'g', 'o', 'o', 'g', 'l', 'e',
- 3, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
- 0, 4, // RDLENGTH is 4 bytes.
- 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
-
- // Answer 2
- // Pointer to answer 1
- 0xc0, 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
- 0, 4, // RDLENGTH is 4 bytes.
- 74, 125, 95, 122, // RDATA is the IP: 74.125.95.122
+static const uint8_t kTestResponsesDifferentAnswers[] = {
+ // Answer 1
+ // ghs.l.google.com in DNS format.
+ 3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
+
+ // Answer 2
+ // Pointer to answer 1
+ 0xc0, 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 122, // RDATA is the IP: 74.125.95.122
};
-static const uint8 kTestResponsesSameAnswers[] = {
- // Answer 1
- // ghs.l.google.com in DNS format.
- 3, 'g', 'h', 's',
- 1, 'l',
- 6, 'g', 'o', 'o', 'g', 'l', 'e',
- 3, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
- 0, 4, // RDLENGTH is 4 bytes.
- 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
-
- // Answer 2
- // Pointer to answer 1
- 0xc0, 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 112, // TTL (4 bytes) is 112 seconds.
- 0, 4, // RDLENGTH is 4 bytes.
- 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
+static const uint8_t kTestResponsesSameAnswers[] = {
+ // Answer 1
+ // ghs.l.google.com in DNS format.
+ 3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
+
+ // Answer 2
+ // Pointer to answer 1
+ 0xc0, 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 112, // TTL (4 bytes) is 112 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
};
-static const uint8 kTestResponseTwoRecords[] = {
- // Answer 1
- // ghs.l.google.com in DNS format. (A)
- 3, 'g', 'h', 's',
- 1, 'l',
- 6, 'g', 'o', 'o', 'g', 'l', 'e',
- 3, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
- 0, 4, // RDLENGTH is 4 bytes.
- 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
-
- // Answer 2
- // ghs.l.google.com in DNS format. (AAAA)
- 3, 'g', 'h', 's',
- 1, 'l',
- 6, 'g', 'o', 'o', 'g', 'l', 'e',
- 3, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x1c, // TYPE is AAA.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
- 0, 16, // RDLENGTH is 16 bytes.
- 0x4a, 0x7d, 0x4a, 0x7d,
- 0x5f, 0x79, 0x5f, 0x79,
- 0x5f, 0x79, 0x5f, 0x79,
- 0x5f, 0x79, 0x5f, 0x79,
+static const uint8_t kTestResponseTwoRecords[] = {
+ // Answer 1
+ // ghs.l.google.com in DNS format. (A)
+ 3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
+
+ // Answer 2
+ // ghs.l.google.com in DNS format. (AAAA)
+ 3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x1c, // TYPE is AAA.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 16, // RDLENGTH is 16 bytes.
+ 0x4a, 0x7d, 0x4a, 0x7d, 0x5f, 0x79, 0x5f, 0x79, 0x5f, 0x79, 0x5f, 0x79,
+ 0x5f, 0x79, 0x5f, 0x79,
};
-static const uint8 kTestResponsesGoodbyePacket[] = {
- // Answer 1
- // ghs.l.google.com in DNS format. (Goodbye packet)
- 3, 'g', 'h', 's',
- 1, 'l',
- 6, 'g', 'o', 'o', 'g', 'l', 'e',
- 3, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 0, // TTL (4 bytes) is zero.
- 0, 4, // RDLENGTH is 4 bytes.
- 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
-
- // Answer 2
- // ghs.l.google.com in DNS format.
- 3, 'g', 'h', 's',
- 1, 'l',
- 6, 'g', 'o', 'o', 'g', 'l', 'e',
- 3, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
- 0, 4, // RDLENGTH is 4 bytes.
- 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
+static const uint8_t kTestResponsesGoodbyePacket[] = {
+ // Answer 1
+ // ghs.l.google.com in DNS format. (Goodbye packet)
+ 3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 0, // TTL (4 bytes) is zero.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
+
+ // Answer 2
+ // ghs.l.google.com in DNS format.
+ 3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
};
class RecordRemovalMock {
@@ -155,9 +129,9 @@ TEST_F(MDnsCacheTest, InsertLookupSingle) {
record1 = RecordParsed::CreateFrom(&parser, default_time_);
record2 = RecordParsed::CreateFrom(&parser, default_time_);
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record2.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results,
default_time_);
@@ -192,8 +166,8 @@ TEST_F(MDnsCacheTest, Expiration) {
base::TimeDelta ttl2 = base::TimeDelta::FromSeconds(record2->ttl());
record_to_be_deleted = record2.get();
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass()));
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record2.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results,
default_time_);
@@ -237,9 +211,9 @@ TEST_F(MDnsCacheTest, RecordChange) {
record1 = RecordParsed::CreateFrom(&parser, default_time_);
record2 = RecordParsed::CreateFrom(&parser, default_time_);
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
EXPECT_EQ(MDnsCache::RecordChanged,
- cache_.UpdateDnsRecord(record2.Pass()));
+ cache_.UpdateDnsRecord(std::move(record2)));
}
// Test that a new record replacing an otherwise identical one already in the
@@ -257,8 +231,8 @@ TEST_F(MDnsCacheTest, RecordNoChange) {
record2 = RecordParsed::CreateFrom(&parser, default_time_ +
base::TimeDelta::FromSeconds(1));
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass()));
- EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(record2.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
+ EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(std::move(record2)));
}
// Test that the next expiration time of the cache is updated properly on record
@@ -278,9 +252,9 @@ TEST_F(MDnsCacheTest, RecordPreemptExpirationTime) {
base::TimeDelta ttl2 = base::TimeDelta::FromSeconds(record2->ttl());
EXPECT_EQ(base::Time(), cache_.next_expiration());
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record2.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
EXPECT_EQ(default_time_ + ttl2, cache_.next_expiration());
- EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(record1.Pass()));
+ EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(std::move(record1)));
EXPECT_EQ(default_time_ + ttl1, cache_.next_expiration());
}
@@ -307,13 +281,14 @@ TEST_F(MDnsCacheTest, GoodbyePacket) {
base::TimeDelta ttl = base::TimeDelta::FromSeconds(record_hello->ttl());
EXPECT_EQ(base::Time(), cache_.next_expiration());
- EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(record_goodbye.Pass()));
+ EXPECT_EQ(MDnsCache::NoChange,
+ cache_.UpdateDnsRecord(std::move(record_goodbye)));
EXPECT_EQ(base::Time(), cache_.next_expiration());
EXPECT_EQ(MDnsCache::RecordAdded,
- cache_.UpdateDnsRecord(record_hello.Pass()));
+ cache_.UpdateDnsRecord(std::move(record_hello)));
EXPECT_EQ(default_time_ + ttl, cache_.next_expiration());
EXPECT_EQ(MDnsCache::NoChange,
- cache_.UpdateDnsRecord(record_goodbye2.Pass()));
+ cache_.UpdateDnsRecord(std::move(record_goodbye2)));
EXPECT_EQ(default_time_ + base::TimeDelta::FromSeconds(1),
cache_.next_expiration());
}
@@ -329,8 +304,8 @@ TEST_F(MDnsCacheTest, AnyRRType) {
record1 = RecordParsed::CreateFrom(&parser, default_time_);
record2 = RecordParsed::CreateFrom(&parser, default_time_);
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass()));
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record2.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
cache_.FindDnsRecords(0, "ghs.l.google.com", &results, default_time_);
@@ -354,7 +329,7 @@ TEST_F(MDnsCacheTest, RemoveRecord) {
std::vector<const RecordParsed*> results;
record1 = RecordParsed::CreateFrom(&parser, default_time_);
- EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass()));
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
cache_.FindDnsRecords(dns_protocol::kTypeCNAME, "codereview.chromium.org",
&results, default_time_);
diff --git a/chromium/net/dns/mdns_client.cc b/chromium/net/dns/mdns_client.cc
index f7bb48e3941..8b4e037912f 100644
--- a/chromium/net/dns/mdns_client.cc
+++ b/chromium/net/dns/mdns_client.cc
@@ -5,6 +5,7 @@
#include "net/dns/mdns_client.h"
#include "net/base/net_errors.h"
+#include "net/base/net_util.h"
#include "net/base/network_interfaces.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/mdns_client_impl.h"
@@ -26,7 +27,7 @@ IPEndPoint GetMDnsIPEndPoint(const char* address) {
}
int Bind(const IPEndPoint& multicast_addr,
- uint32 interface_index,
+ uint32_t interface_index,
DatagramServerSocket* socket) {
IPAddressNumber address_any(multicast_addr.address().size());
IPEndPoint bind_endpoint(address_any, multicast_addr.port());
@@ -86,7 +87,7 @@ InterfaceIndexFamilyList GetMDnsInterfacesToBind() {
scoped_ptr<DatagramServerSocket> CreateAndBindMDnsSocket(
AddressFamily address_family,
- uint32 interface_index) {
+ uint32_t interface_index) {
scoped_ptr<DatagramServerSocket> socket(
new UDPServerSocket(NULL, NetLog::Source()));
@@ -97,7 +98,7 @@ scoped_ptr<DatagramServerSocket> CreateAndBindMDnsSocket(
VLOG(1) << "Bind failed, endpoint=" << multicast_addr.ToStringWithoutPort()
<< ", error=" << rv;
}
- return socket.Pass();
+ return socket;
}
} // namespace net
diff --git a/chromium/net/dns/mdns_client.h b/chromium/net/dns/mdns_client.h
index 1c75b046513..279aa6d8d17 100644
--- a/chromium/net/dns/mdns_client.h
+++ b/chromium/net/dns/mdns_client.h
@@ -5,18 +5,18 @@
#ifndef NET_DNS_MDNS_CLIENT_H_
#define NET_DNS_MDNS_CLIENT_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
#include "net/dns/record_parsed.h"
-template <typename T>
-class ScopedVector;
-
namespace net {
class DatagramServerSocket;
@@ -78,7 +78,7 @@ class NET_EXPORT MDnsTransaction {
virtual const std::string& GetName() const = 0;
// Get the type for this transaction (SRV, TXT, A, AAA, etc)
- virtual uint16 GetType() const = 0;
+ virtual uint16_t GetType() const = 0;
};
// A listener listens for updates regarding a specific record or set of records.
@@ -124,14 +124,15 @@ class NET_EXPORT MDnsListener {
virtual const std::string& GetName() const = 0;
// Get the type for this query (SRV, TXT, A, AAA, etc)
- virtual uint16 GetType() const = 0;
+ virtual uint16_t GetType() const = 0;
};
// Creates bound datagram sockets ready to use by MDnsClient.
class NET_EXPORT MDnsSocketFactory {
public:
virtual ~MDnsSocketFactory() {}
- virtual void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) = 0;
+ virtual void CreateSockets(
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets) = 0;
static scoped_ptr<MDnsSocketFactory> CreateDefault();
};
@@ -147,7 +148,7 @@ class NET_EXPORT MDnsClient {
// Create listener object for RRType |rrtype| and name |name|.
virtual scoped_ptr<MDnsListener> CreateListener(
- uint16 rrtype,
+ uint16_t rrtype,
const std::string& name,
MDnsListener::Delegate* delegate) = 0;
@@ -155,7 +156,7 @@ class NET_EXPORT MDnsClient {
// network, or both for records of type |rrtype| and name |name|. |flags| is
// defined by MDnsTransactionFlags.
virtual scoped_ptr<MDnsTransaction> CreateTransaction(
- uint16 rrtype,
+ uint16_t rrtype,
const std::string& name,
int flags,
const MDnsTransaction::ResultCallback& callback) = 0;
@@ -173,7 +174,8 @@ class NET_EXPORT MDnsClient {
NET_EXPORT IPEndPoint GetMDnsIPEndPoint(AddressFamily address_family);
-typedef std::vector<std::pair<uint32, AddressFamily> > InterfaceIndexFamilyList;
+typedef std::vector<std::pair<uint32_t, AddressFamily>>
+ InterfaceIndexFamilyList;
// Returns pairs of interface and address family to bind. Current
// implementation returns unique list of all available interfaces.
NET_EXPORT InterfaceIndexFamilyList GetMDnsInterfacesToBind();
@@ -183,7 +185,7 @@ NET_EXPORT InterfaceIndexFamilyList GetMDnsInterfacesToBind();
// Returns NULL if failed.
NET_EXPORT scoped_ptr<DatagramServerSocket> CreateAndBindMDnsSocket(
AddressFamily address_family,
- uint32 interface_index);
+ uint32_t interface_index);
} // namespace net
diff --git a/chromium/net/dns/mdns_client_impl.cc b/chromium/net/dns/mdns_client_impl.cc
index 053d4fe3861..cb717fc44b4 100644
--- a/chromium/net/dns/mdns_client_impl.cc
+++ b/chromium/net/dns/mdns_client_impl.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <queue>
+#include <utility>
#include "base/bind.h"
#include "base/location.h"
@@ -16,10 +17,10 @@
#include "base/time/default_clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
-#include "net/base/dns_util.h"
#include "net/base/net_errors.h"
#include "net/base/rand_callback.h"
#include "net/dns/dns_protocol.h"
+#include "net/dns/dns_util.h"
#include "net/dns/record_rdata.h"
#include "net/log/net_log.h"
#include "net/udp/datagram_socket.h"
@@ -44,7 +45,7 @@ const double kListenerRefreshRatio2 = 0.95;
} // namespace
void MDnsSocketFactoryImpl::CreateSockets(
- ScopedVector<DatagramServerSocket>* sockets) {
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets) {
InterfaceIndexFamilyList interfaces(GetMDnsInterfacesToBind());
for (size_t i = 0; i < interfaces.size(); ++i) {
DCHECK(interfaces[i].second == ADDRESS_FAMILY_IPV4 ||
@@ -52,18 +53,17 @@ void MDnsSocketFactoryImpl::CreateSockets(
scoped_ptr<DatagramServerSocket> socket(
CreateAndBindMDnsSocket(interfaces[i].second, interfaces[i].first));
if (socket)
- sockets->push_back(socket.Pass());
+ sockets->push_back(std::move(socket));
}
}
MDnsConnection::SocketHandler::SocketHandler(
scoped_ptr<DatagramServerSocket> socket,
MDnsConnection* connection)
- : socket_(socket.Pass()),
+ : socket_(std::move(socket)),
connection_(connection),
response_(dns_protocol::kMaxMulticastSize),
- send_in_progress_(false) {
-}
+ send_in_progress_(false) {}
MDnsConnection::SocketHandler::~SocketHandler() {
}
@@ -142,14 +142,13 @@ MDnsConnection::~MDnsConnection() {
}
bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) {
- ScopedVector<DatagramServerSocket> sockets;
+ std::vector<scoped_ptr<DatagramServerSocket>> sockets;
socket_factory->CreateSockets(&sockets);
- for (size_t i = 0; i < sockets.size(); ++i) {
- socket_handlers_.push_back(
- new MDnsConnection::SocketHandler(make_scoped_ptr(sockets[i]), this));
+ for (scoped_ptr<DatagramServerSocket>& socket : sockets) {
+ socket_handlers_.push_back(make_scoped_ptr(
+ new MDnsConnection::SocketHandler(std::move(socket), this)));
}
- sockets.weak_clear();
// All unbound sockets need to be bound before processing untrusted input.
// This is done for security reasons, so that an attacker can't get an unbound
@@ -169,14 +168,18 @@ bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) {
void MDnsConnection::Send(const scoped_refptr<IOBuffer>& buffer,
unsigned size) {
- for (size_t i = 0; i < socket_handlers_.size(); ++i)
- socket_handlers_[i]->Send(buffer, size);
+ for (scoped_ptr<SocketHandler>& handler : socket_handlers_)
+ handler->Send(buffer, size);
}
void MDnsConnection::PostOnError(SocketHandler* loop, int rv) {
- VLOG(1) << "Socket error. id="
- << std::find(socket_handlers_.begin(), socket_handlers_.end(), loop) -
- socket_handlers_.begin() << ", error=" << rv;
+ int id = 0;
+ for (const auto& it : socket_handlers_) {
+ if (it.get() == loop)
+ break;
+ id++;
+ }
+ VLOG(1) << "Socket error. id=" << id << ", error=" << rv;
// Post to allow deletion of this object by delegate.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -212,7 +215,7 @@ bool MDnsClientImpl::Core::Init(MDnsSocketFactory* socket_factory) {
return connection_->Init(socket_factory);
}
-bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, const std::string& name) {
+bool MDnsClientImpl::Core::SendQuery(uint16_t rrtype, const std::string& name) {
std::string name_dns;
if (!DNSDomainFromDot(name, &name_dns))
return false;
@@ -268,7 +271,7 @@ void MDnsClientImpl::Core::HandlePacket(DnsResponse* response,
}
MDnsCache::Key update_key = MDnsCache::Key::CreateFor(record.get());
- MDnsCache::UpdateType update = cache_.UpdateDnsRecord(record.Pass());
+ MDnsCache::UpdateType update = cache_.UpdateDnsRecord(std::move(record));
// Cleanup time may have changed.
ScheduleCleanup(cache_.next_expiration());
@@ -418,7 +421,8 @@ void MDnsClientImpl::Core::OnRecordRemoved(
}
void MDnsClientImpl::Core::QueryCache(
- uint16 rrtype, const std::string& name,
+ uint16_t rrtype,
+ const std::string& name,
std::vector<const RecordParsed*>* records) const {
cache_.FindDnsRecords(rrtype, name, records, clock_->Now());
}
@@ -430,8 +434,7 @@ MDnsClientImpl::MDnsClientImpl()
MDnsClientImpl::MDnsClientImpl(scoped_ptr<base::Clock> clock,
scoped_ptr<base::Timer> timer)
- : clock_(clock.Pass()), cleanup_timer_(timer.Pass()) {
-}
+ : clock_(std::move(clock)), cleanup_timer_(std::move(timer)) {}
MDnsClientImpl::~MDnsClientImpl() {
}
@@ -455,7 +458,7 @@ bool MDnsClientImpl::IsListening() const {
}
scoped_ptr<MDnsListener> MDnsClientImpl::CreateListener(
- uint16 rrtype,
+ uint16_t rrtype,
const std::string& name,
MDnsListener::Delegate* delegate) {
return scoped_ptr<MDnsListener>(
@@ -463,7 +466,7 @@ scoped_ptr<MDnsListener> MDnsClientImpl::CreateListener(
}
scoped_ptr<MDnsTransaction> MDnsClientImpl::CreateTransaction(
- uint16 rrtype,
+ uint16_t rrtype,
const std::string& name,
int flags,
const MDnsTransaction::ResultCallback& callback) {
@@ -471,7 +474,7 @@ scoped_ptr<MDnsTransaction> MDnsClientImpl::CreateTransaction(
new MDnsTransactionImpl(rrtype, name, flags, callback, this));
}
-MDnsListenerImpl::MDnsListenerImpl(uint16 rrtype,
+MDnsListenerImpl::MDnsListenerImpl(uint16_t rrtype,
const std::string& name,
base::Clock* clock,
MDnsListener::Delegate* delegate,
@@ -482,8 +485,7 @@ MDnsListenerImpl::MDnsListenerImpl(uint16 rrtype,
client_(client),
delegate_(delegate),
started_(false),
- active_refresh_(false) {
-}
+ active_refresh_(false) {}
MDnsListenerImpl::~MDnsListenerImpl() {
if (started_) {
@@ -519,7 +521,7 @@ const std::string& MDnsListenerImpl::GetName() const {
return name_;
}
-uint16 MDnsListenerImpl::GetType() const {
+uint16_t MDnsListenerImpl::GetType() const {
return rrtype_;
}
@@ -602,13 +604,17 @@ void MDnsListenerImpl::DoRefresh() {
}
MDnsTransactionImpl::MDnsTransactionImpl(
- uint16 rrtype,
+ uint16_t rrtype,
const std::string& name,
int flags,
const MDnsTransaction::ResultCallback& callback,
MDnsClientImpl* client)
- : rrtype_(rrtype), name_(name), callback_(callback), client_(client),
- started_(false), flags_(flags) {
+ : rrtype_(rrtype),
+ name_(name),
+ callback_(callback),
+ client_(client),
+ started_(false),
+ flags_(flags) {
DCHECK((flags_ & MDnsTransaction::FLAG_MASK) == flags_);
DCHECK(flags_ & MDnsTransaction::QUERY_CACHE ||
flags_ & MDnsTransaction::QUERY_NETWORK);
@@ -643,7 +649,7 @@ const std::string& MDnsTransactionImpl::GetName() const {
return name_;
}
-uint16 MDnsTransactionImpl::GetType() const {
+uint16_t MDnsTransactionImpl::GetType() const {
return rrtype_;
}
diff --git a/chromium/net/dns/mdns_client_impl.h b/chromium/net/dns/mdns_client_impl.h
index eb7e5e3bb98..16a216e8b3a 100644
--- a/chromium/net/dns/mdns_client_impl.h
+++ b/chromium/net/dns/mdns_client_impl.h
@@ -5,6 +5,8 @@
#ifndef NET_DNS_MDNS_CLIENT_IMPL_H_
#define NET_DNS_MDNS_CLIENT_IMPL_H_
+#include <stdint.h>
+
#include <map>
#include <queue>
#include <string>
@@ -13,7 +15,8 @@
#include "base/cancelable_callback.h"
#include "base/gtest_prod_util.h"
-#include "base/memory/scoped_vector.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
@@ -35,7 +38,8 @@ class MDnsSocketFactoryImpl : public MDnsSocketFactory {
MDnsSocketFactoryImpl() {}
~MDnsSocketFactoryImpl() override{};
- void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) override;
+ void CreateSockets(
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets) override;
private:
DISALLOW_COPY_AND_ASSIGN(MDnsSocketFactoryImpl);
@@ -97,7 +101,7 @@ class NET_EXPORT_PRIVATE MDnsConnection {
void OnError(int rv);
// Only socket handlers which successfully bound and started are kept.
- ScopedVector<SocketHandler> socket_handlers_;
+ std::vector<scoped_ptr<SocketHandler>> socket_handlers_;
Delegate* delegate_;
@@ -123,14 +127,15 @@ class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
bool Init(MDnsSocketFactory* socket_factory);
// Send a query with a specific rrtype and name. Returns true on success.
- bool SendQuery(uint16 rrtype, const std::string& name);
+ bool SendQuery(uint16_t rrtype, const std::string& name);
// Add/remove a listener to the list of listeners.
void AddListener(MDnsListenerImpl* listener);
void RemoveListener(MDnsListenerImpl* listener);
// Query the cache for records of a specific type and name.
- void QueryCache(uint16 rrtype, const std::string& name,
+ void QueryCache(uint16_t rrtype,
+ const std::string& name,
std::vector<const RecordParsed*>* records) const;
// Parse the response and alert relevant listeners.
@@ -141,7 +146,7 @@ class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
private:
FRIEND_TEST_ALL_PREFIXES(MDnsTest, CacheCleanupWithShortTTL);
- typedef std::pair<std::string, uint16> ListenerKey;
+ typedef std::pair<std::string, uint16_t> ListenerKey;
typedef std::map<ListenerKey, base::ObserverList<MDnsListenerImpl>*>
ListenerMap;
@@ -182,12 +187,12 @@ class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
// MDnsClient implementation:
scoped_ptr<MDnsListener> CreateListener(
- uint16 rrtype,
+ uint16_t rrtype,
const std::string& name,
MDnsListener::Delegate* delegate) override;
scoped_ptr<MDnsTransaction> CreateTransaction(
- uint16 rrtype,
+ uint16_t rrtype,
const std::string& name,
int flags,
const MDnsTransaction::ResultCallback& callback) override;
@@ -215,7 +220,7 @@ class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
class MDnsListenerImpl : public MDnsListener,
public base::SupportsWeakPtr<MDnsListenerImpl> {
public:
- MDnsListenerImpl(uint16 rrtype,
+ MDnsListenerImpl(uint16_t rrtype,
const std::string& name,
base::Clock* clock,
MDnsListener::Delegate* delegate,
@@ -231,7 +236,7 @@ class MDnsListenerImpl : public MDnsListener,
const std::string& GetName() const override;
- uint16 GetType() const override;
+ uint16_t GetType() const override;
MDnsListener::Delegate* delegate() { return delegate_; }
@@ -246,14 +251,14 @@ class MDnsListenerImpl : public MDnsListener,
void ScheduleNextRefresh();
void DoRefresh();
- uint16 rrtype_;
+ uint16_t rrtype_;
std::string name_;
base::Clock* clock_;
MDnsClientImpl* client_;
MDnsListener::Delegate* delegate_;
base::Time last_update_;
- uint32 ttl_;
+ uint32_t ttl_;
bool started_;
bool active_refresh_;
@@ -265,7 +270,7 @@ class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>,
public MDnsTransaction,
public MDnsListener::Delegate {
public:
- MDnsTransactionImpl(uint16 rrtype,
+ MDnsTransactionImpl(uint16_t rrtype,
const std::string& name,
int flags,
const MDnsTransaction::ResultCallback& callback,
@@ -276,7 +281,7 @@ class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>,
bool Start() override;
const std::string& GetName() const override;
- uint16 GetType() const override;
+ uint16_t GetType() const override;
// MDnsListener::Delegate implementation:
void OnRecordUpdate(MDnsListener::UpdateType update,
@@ -309,7 +314,7 @@ class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>,
// or if it fails to send a query.
bool QueryAndListen();
- uint16 rrtype_;
+ uint16_t rrtype_;
std::string name_;
MDnsTransaction::ResultCallback callback_;
diff --git a/chromium/net/dns/mdns_client_unittest.cc b/chromium/net/dns/mdns_client_unittest.cc
index bd84aca3d83..ae1a8d915db 100644
--- a/chromium/net/dns/mdns_client_unittest.cc
+++ b/chromium/net/dns/mdns_client_unittest.cc
@@ -3,9 +3,12 @@
// found in the LICENSE file.
#include <queue>
+#include <vector>
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -34,201 +37,104 @@ namespace net {
namespace {
-const uint8 kSamplePacket1[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x02, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is 1 second;
- 0x00, 0x01,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'h', 'e', 'l', 'l', 'o',
- 0xc0, 0x0c,
-
- // Answer 2
- 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r',
- 0xc0, 0x14, // Pointer to "._tcp.local"
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
- 0x24, 0x75,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'h', 'e', 'l', 'l', 'o',
- 0xc0, 0x32
-};
+const uint8_t kSamplePacket1[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
-const uint8 kCorruptedPacketBadQuestion[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x01, // One question
- 0x00, 0x02, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Question is corrupted and cannot be read.
- 0x99, 'h', 'e', 'l', 'l', 'o',
- 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x99, // RDLENGTH is impossible
- 0x05, 'h', 'e', 'l', 'l', 'o',
- 0xc0, 0x0c,
-
- // Answer 2
- 0x08, '_', 'p', 'r', // Useless trailing data.
-};
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 1 second;
+ 0x00, 0x01, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
-const uint8 kCorruptedPacketUnsalvagable[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x02, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x99, // RDLENGTH is impossible
- 0x05, 'h', 'e', 'l', 'l', 'o',
- 0xc0, 0x0c,
-
- // Answer 2
- 0x08, '_', 'p', 'r', // Useless trailing data.
-};
+ // Answer 2
+ 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', 0xc0,
+ 0x14, // Pointer to "._tcp.local"
+ 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
+ 0x24, 0x75, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32};
+
+const uint8_t kCorruptedPacketBadQuestion[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x01, // One question
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Question is corrupted and cannot be read.
+ 0x99, 'h', 'e', 'l', 'l', 'o', 0x00, 0x00, 0x00, 0x00, 0x00,
-const uint8 kCorruptedPacketDoubleRecord[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x02, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x06, 'p', 'r', 'i', 'v', 'e', 't',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x04, // RDLENGTH is 4
- 0x05, 0x03,
- 0xc0, 0x0c,
-
- // Answer 2 -- Same key
- 0x06, 'p', 'r', 'i', 'v', 'e', 't',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x04, // RDLENGTH is 4
- 0x02, 0x03,
- 0x04, 0x05,
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x99, // RDLENGTH is impossible
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
+
+ // Answer 2
+ 0x08, '_', 'p', 'r', // Useless trailing data.
};
-const uint8 kCorruptedPacketSalvagable[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x02, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x99, 'h', 'e', 'l', 'l', 'o', // Bad RDATA format.
- 0xc0, 0x0c,
-
- // Answer 2
- 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r',
- 0xc0, 0x14, // Pointer to "._tcp.local"
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
- 0x24, 0x75,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'h', 'e', 'l', 'l', 'o',
- 0xc0, 0x32
+const uint8_t kCorruptedPacketUnsalvagable[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x99, // RDLENGTH is impossible
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
+
+ // Answer 2
+ 0x08, '_', 'p', 'r', // Useless trailing data.
};
-const uint8 kSamplePacket2[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x02, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'z', 'z', 'z', 'z', 'z',
- 0xc0, 0x0c,
-
- // Answer 2
- 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r',
- 0xc0, 0x14, // Pointer to "._tcp.local"
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'z', 'z', 'z', 'z', 'z',
- 0xc0, 0x32
+const uint8_t kCorruptedPacketDoubleRecord[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x06, 'p', 'r', 'i', 'v', 'e', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
+ 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x04, // RDLENGTH is 4
+ 0x05, 0x03, 0xc0, 0x0c,
+
+ // Answer 2 -- Same key
+ 0x06, 'p', 'r', 'i', 'v', 'e', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
+ 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x04, // RDLENGTH is 4
+ 0x02, 0x03, 0x04, 0x05,
};
-const uint8 kSamplePacket3[] = {
+const uint8_t kCorruptedPacketSalvagable[] = {
// Header
0x00, 0x00, // ID is zeroed out
0x81, 0x80, // Standard query response, RA, no error
@@ -238,159 +144,186 @@ const uint8 kSamplePacket3[] = {
0x00, 0x00, // 0 additional RRs
// Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', //
- 0x04, '_', 't', 'c', 'p', //
- 0x05, 'l', 'o', 'c', 'a', 'l', //
- 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is 1 second;
- 0x00, 0x01, //
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'h', 'e', 'l', 'l', 'o', //
- 0xc0, 0x0c, //
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x99, 'h', 'e', 'l', 'l', 'o', // Bad RDATA format.
+ 0xc0, 0x0c,
+
+ // Answer 2
+ 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', 0xc0,
+ 0x14, // Pointer to "._tcp.local"
+ 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
+ 0x24, 0x75, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32};
+
+const uint8_t kSamplePacket2[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'z', 'z', 'z', 'z', 'z', 0xc0, 0x0c,
// Answer 2
- 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', //
- 0xc0, 0x14, // Pointer to "._tcp.local"
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is 3 seconds.
- 0x00, 0x03, //
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'h', 'e', 'l', 'l', 'o', //
+ 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', 0xc0,
+ 0x14, // Pointer to "._tcp.local"
+ 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'z', 'z', 'z', 'z', 'z', 0xc0, 0x32};
+
+const uint8_t kSamplePacket3[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', //
+ 0x04, '_', 't', 'c', 'p', //
+ 0x05, 'l', 'o', 'c', 'a', 'l', //
+ 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 1 second;
+ 0x00, 0x01, //
+ 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', //
+ 0xc0, 0x0c, //
+
+ // Answer 2
+ 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', //
+ 0xc0, 0x14, // Pointer to "._tcp.local"
+ 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 3 seconds.
+ 0x00, 0x03, //
+ 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', //
0xc0, 0x32};
-const uint8 kQueryPacketPrivet[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x00, 0x00, // No flags.
- 0x00, 0x01, // One question.
- 0x00, 0x00, // 0 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Question
- // This part is echoed back from the respective query.
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
+const uint8_t kQueryPacketPrivet[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x00, 0x00, // No flags.
+ 0x00, 0x01, // One question.
+ 0x00, 0x00, // 0 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Question
+ // This part is echoed back from the respective query.
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
};
-const uint8 kQueryPacketPrivetA[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x00, 0x00, // No flags.
- 0x00, 0x01, // One question.
- 0x00, 0x00, // 0 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Question
- // This part is echoed back from the respective query.
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
+const uint8_t kQueryPacketPrivetA[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x00, 0x00, // No flags.
+ 0x00, 0x01, // One question.
+ 0x00, 0x00, // 0 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Question
+ // This part is echoed back from the respective query.
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
};
-const uint8 kSamplePacketAdditionalOnly[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x00, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x01, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'h', 'e', 'l', 'l', 'o',
- 0xc0, 0x0c,
+const uint8_t kSamplePacketAdditionalOnly[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x00, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x01, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
};
-const uint8 kSamplePacketNsec[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x01, // 1 RR (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x2f, // TYPE is NSEC.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x06, // RDLENGTH is 6 bytes.
- 0xc0, 0x0c,
- 0x00, 0x02, 0x00, 0x08 // Only A record present
+const uint8_t kSamplePacketNsec[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x01, // 1 RR (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x2f, // TYPE is NSEC.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x06, // RDLENGTH is 6 bytes.
+ 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x08 // Only A record present
};
-const uint8 kSamplePacketAPrivet[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x01, // 1 RR (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x01, // TYPE is A.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is 5 seconds
- 0x00, 0x05,
- 0x00, 0x04, // RDLENGTH is 4 bytes.
- 0xc0, 0x0c,
- 0x00, 0x02,
+const uint8_t kSamplePacketAPrivet[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x01, // 1 RR (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 5 seconds
+ 0x00, 0x05, 0x00, 0x04, // RDLENGTH is 4 bytes.
+ 0xc0, 0x0c, 0x00, 0x02,
};
-const uint8 kSamplePacketGoodbye[] = {
- // Header
- 0x00, 0x00, // ID is zeroed out
- 0x81, 0x80, // Standard query response, RA, no error
- 0x00, 0x00, // No questions (for simplicity)
- 0x00, 0x01, // 2 RRs (answers)
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
-
- // Answer 1
- 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
- 0x04, '_', 't', 'c', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- 0x00, 0x0c, // TYPE is PTR.
- 0x00, 0x01, // CLASS is IN.
- 0x00, 0x00, // TTL (4 bytes) is zero;
- 0x00, 0x00,
- 0x00, 0x08, // RDLENGTH is 8 bytes.
- 0x05, 'z', 'z', 'z', 'z', 'z',
- 0xc0, 0x0c,
+const uint8_t kSamplePacketGoodbye[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x01, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is zero;
+ 0x00, 0x00, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'z', 'z', 'z', 'z', 'z', 0xc0, 0x0c,
};
-std::string MakeString(const uint8* data, unsigned size) {
+std::string MakeString(const uint8_t* data, unsigned size) {
return std::string(reinterpret_cast<const char*>(data), size);
}
@@ -478,8 +411,8 @@ class MDnsTest : public ::testing::Test {
const RecordParsed* record));
protected:
- void ExpectPacket(const uint8* packet, unsigned size);
- void SimulatePacketReceive(const uint8* packet, unsigned size);
+ void ExpectPacket(const uint8_t* packet, unsigned size);
+ void SimulatePacketReceive(const uint8_t* packet, unsigned size);
scoped_ptr<MDnsClientImpl> test_client_;
IPEndPoint mdns_ipv4_endpoint_;
@@ -506,11 +439,11 @@ void MDnsTest::SetUp() {
test_client_->StartListening(&socket_factory_);
}
-void MDnsTest::SimulatePacketReceive(const uint8* packet, unsigned size) {
+void MDnsTest::SimulatePacketReceive(const uint8_t* packet, unsigned size) {
socket_factory_.SimulateReceive(packet, size);
}
-void MDnsTest::ExpectPacket(const uint8* packet, unsigned size) {
+void MDnsTest::ExpectPacket(const uint8_t* packet, unsigned size) {
EXPECT_CALL(socket_factory_, OnSendTo(MakeString(packet, size)))
.Times(2);
}
@@ -535,7 +468,7 @@ void MDnsTest::RunFor(base::TimeDelta time_period) {
}
void MDnsTest::Stop() {
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
TEST_F(MDnsTest, PassiveListeners) {
@@ -1157,17 +1090,18 @@ TEST_F(MDnsTest, RefreshQuery) {
// This is a simplifying assumption based on the way the code works now.
class SimpleMockSocketFactory : public MDnsSocketFactory {
public:
- void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) override {
+ void CreateSockets(
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets) override {
sockets->clear();
sockets->swap(sockets_);
}
- void PushSocket(DatagramServerSocket* socket) {
- sockets_.push_back(socket);
+ void PushSocket(scoped_ptr<DatagramServerSocket> socket) {
+ sockets_.push_back(std::move(socket));
}
private:
- ScopedVector<DatagramServerSocket> sockets_;
+ std::vector<scoped_ptr<DatagramServerSocket>> sockets_;
};
class MockMDnsConnectionDelegate : public MDnsConnection::Delegate {
@@ -1191,8 +1125,8 @@ class MDnsConnectionTest : public ::testing::Test {
void SetUp() override {
socket_ipv4_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV4);
socket_ipv6_ = new MockMDnsDatagramServerSocket(ADDRESS_FAMILY_IPV6);
- factory_.PushSocket(socket_ipv6_);
- factory_.PushSocket(socket_ipv4_);
+ factory_.PushSocket(make_scoped_ptr(socket_ipv6_));
+ factory_.PushSocket(make_scoped_ptr(socket_ipv4_));
sample_packet_ = MakeString(kSamplePacket1, sizeof(kSamplePacket1));
sample_buffer_ = new StringIOBuffer(sample_packet_);
}
diff --git a/chromium/net/dns/mock_host_resolver.h b/chromium/net/dns/mock_host_resolver.h
index 6920ae7842a..71f557ea080 100644
--- a/chromium/net/dns/mock_host_resolver.h
+++ b/chromium/net/dns/mock_host_resolver.h
@@ -5,9 +5,12 @@
#ifndef NET_DNS_MOCK_HOST_RESOLVER_H_
#define NET_DNS_MOCK_HOST_RESOLVER_H_
+#include <stddef.h>
+
#include <list>
#include <map>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
diff --git a/chromium/net/dns/mock_mdns_socket_factory.cc b/chromium/net/dns/mock_mdns_socket_factory.cc
index 88c0dcfa223..ae46d2f428d 100644
--- a/chromium/net/dns/mock_mdns_socket_factory.cc
+++ b/chromium/net/dns/mock_mdns_socket_factory.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "net/dns/mock_mdns_socket_factory.h"
+
#include <algorithm>
+#include <utility>
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/net_errors.h"
-#include "net/dns/mock_mdns_socket_factory.h"
using testing::_;
using testing::Invoke;
@@ -65,14 +67,14 @@ MockMDnsSocketFactory::~MockMDnsSocketFactory() {
}
void MockMDnsSocketFactory::CreateSockets(
- ScopedVector<DatagramServerSocket>* sockets) {
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets) {
CreateSocket(ADDRESS_FAMILY_IPV4, sockets);
CreateSocket(ADDRESS_FAMILY_IPV6, sockets);
}
void MockMDnsSocketFactory::CreateSocket(
AddressFamily address_family,
- ScopedVector<DatagramServerSocket>* sockets) {
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets) {
scoped_ptr<testing::NiceMock<MockMDnsDatagramServerSocket> > new_socket(
new testing::NiceMock<MockMDnsDatagramServerSocket>(address_family));
@@ -86,10 +88,10 @@ void MockMDnsSocketFactory::CreateSocket(
this,
&MockMDnsSocketFactory::RecvFromInternal));
- sockets->push_back(new_socket.Pass());
+ sockets->push_back(std::move(new_socket));
}
-void MockMDnsSocketFactory::SimulateReceive(const uint8* packet, int size) {
+void MockMDnsSocketFactory::SimulateReceive(const uint8_t* packet, int size) {
DCHECK(recv_buffer_size_ >= size);
DCHECK(recv_buffer_.get());
DCHECK(!recv_callback_.is_null());
diff --git a/chromium/net/dns/mock_mdns_socket_factory.h b/chromium/net/dns/mock_mdns_socket_factory.h
index 34f482072c5..a5b14222ce5 100644
--- a/chromium/net/dns/mock_mdns_socket_factory.h
+++ b/chromium/net/dns/mock_mdns_socket_factory.h
@@ -5,8 +5,12 @@
#ifndef NET_DNS_MOCK_MDNS_SOCKET_FACTORY_H_
#define NET_DNS_MOCK_MDNS_SOCKET_FACTORY_H_
+#include <stdint.h>
+
#include <string>
+#include <vector>
+#include "base/memory/scoped_ptr.h"
#include "net/dns/mdns_client_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -35,8 +39,8 @@ class MockMDnsDatagramServerSocket : public DatagramServerSocket {
const std::string address,
const CompletionCallback& callback));
- MOCK_METHOD1(SetReceiveBufferSize, int(int32 size));
- MOCK_METHOD1(SetSendBufferSize, int(int32 size));
+ MOCK_METHOD1(SetReceiveBufferSize, int(int32_t size));
+ MOCK_METHOD1(SetSendBufferSize, int(int32_t size));
MOCK_METHOD0(Close, void());
@@ -50,7 +54,7 @@ class MockMDnsDatagramServerSocket : public DatagramServerSocket {
MOCK_CONST_METHOD1(JoinGroup, int(const IPAddressNumber& group_address));
MOCK_CONST_METHOD1(LeaveGroup, int(const IPAddressNumber& address));
- MOCK_METHOD1(SetMulticastInterface, int(uint32 interface_index));
+ MOCK_METHOD1(SetMulticastInterface, int(uint32_t interface_index));
MOCK_METHOD1(SetMulticastTimeToLive, int(int ttl));
MOCK_METHOD1(SetMulticastLoopbackMode, int(bool loopback));
@@ -76,9 +80,10 @@ class MockMDnsSocketFactory : public MDnsSocketFactory {
MockMDnsSocketFactory();
~MockMDnsSocketFactory() override;
- void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) override;
+ void CreateSockets(
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets) override;
- void SimulateReceive(const uint8* packet, int size);
+ void SimulateReceive(const uint8_t* packet, int size);
MOCK_METHOD1(OnSendTo, void(const std::string&));
@@ -93,7 +98,7 @@ class MockMDnsSocketFactory : public MDnsSocketFactory {
const CompletionCallback& callback);
void CreateSocket(AddressFamily address_family,
- ScopedVector<DatagramServerSocket>* sockets);
+ std::vector<scoped_ptr<DatagramServerSocket>>* sockets);
scoped_refptr<IOBuffer> recv_buffer_;
int recv_buffer_size_;
diff --git a/chromium/net/dns/mojo_host_resolver_impl.cc b/chromium/net/dns/mojo_host_resolver_impl.cc
index c39079c94e9..bf49c99ff1b 100644
--- a/chromium/net/dns/mojo_host_resolver_impl.cc
+++ b/chromium/net/dns/mojo_host_resolver_impl.cc
@@ -4,7 +4,8 @@
#include "net/dns/mojo_host_resolver_impl.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/stl_util.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
@@ -60,7 +61,7 @@ void MojoHostResolverImpl::Resolve(
DCHECK(thread_checker_.CalledOnValidThread());
Job* job = new Job(this, resolver_,
request_info->To<net::HostResolver::RequestInfo>(),
- net_log_, client.Pass());
+ net_log_, std::move(client));
pending_jobs_.insert(job);
job->Start();
}
@@ -82,7 +83,7 @@ MojoHostResolverImpl::Job::Job(
resolver_(resolver),
request_info_(request_info),
net_log_(net_log),
- client_(client.Pass()),
+ client_(std::move(client)),
handle_(nullptr) {
client_.set_connection_error_handler(base::Bind(
&MojoHostResolverImpl::Job::OnConnectionError, base::Unretained(this)));
diff --git a/chromium/net/dns/mojo_host_resolver_impl_unittest.cc b/chromium/net/dns/mojo_host_resolver_impl_unittest.cc
index 4f7a05b47ee..3bf32758ba3 100644
--- a/chromium/net/dns/mojo_host_resolver_impl_unittest.cc
+++ b/chromium/net/dns/mojo_host_resolver_impl_unittest.cc
@@ -5,10 +5,13 @@
#include "net/dns/mojo_host_resolver_impl.h"
#include <string>
+#include <utility>
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/time/time.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
@@ -16,8 +19,6 @@
#include "net/dns/mojo_host_type_converters.h"
#include "net/log/net_log.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
namespace net {
@@ -27,7 +28,7 @@ class TestRequestClient : public interfaces::HostResolverRequestClient {
public:
explicit TestRequestClient(
mojo::InterfaceRequest<interfaces::HostResolverRequestClient> req)
- : done_(false), binding_(this, req.Pass()) {
+ : done_(false), binding_(this, std::move(req)) {
binding_.set_connection_error_handler(base::Bind(
&TestRequestClient::OnConnectionError, base::Unretained(this)));
}
@@ -75,7 +76,7 @@ void TestRequestClient::ReportResult(int32_t error,
}
ASSERT_FALSE(done_);
error_ = error;
- results_ = results.Pass();
+ results_ = std::move(results);
done_ = true;
}
@@ -144,7 +145,7 @@ class MojoHostResolverImplTest : public testing::Test {
request->port = port;
request->address_family = interfaces::ADDRESS_FAMILY_IPV4;
request->is_my_ip_address = is_my_ip_address;
- return request.Pass();
+ return request;
}
// Wait until the mock resolver has received |num| resolve requests.
@@ -166,7 +167,7 @@ TEST_F(MojoHostResolverImplTest, Resolve) {
interfaces::HostResolverRequestInfoPtr request =
CreateRequest("example.com", 80, false);
- resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
+ resolver_service_->Resolve(std::move(request), std::move(client_ptr));
client.WaitForResult();
EXPECT_EQ(net::OK, client.error_);
@@ -183,7 +184,7 @@ TEST_F(MojoHostResolverImplTest, ResolveSynchronous) {
interfaces::HostResolverRequestInfoPtr request =
CreateRequest("example.com", 80, false);
- resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
+ resolver_service_->Resolve(std::move(request), std::move(client_ptr));
client.WaitForResult();
EXPECT_EQ(net::OK, client.error_);
@@ -202,10 +203,10 @@ TEST_F(MojoHostResolverImplTest, ResolveMultiple) {
interfaces::HostResolverRequestInfoPtr request1 =
CreateRequest("example.com", 80, false);
- resolver_service_->Resolve(request1.Pass(), client1_ptr.Pass());
+ resolver_service_->Resolve(std::move(request1), std::move(client1_ptr));
interfaces::HostResolverRequestInfoPtr request2 =
CreateRequest("chromium.org", 80, false);
- resolver_service_->Resolve(request2.Pass(), client2_ptr.Pass());
+ resolver_service_->Resolve(std::move(request2), std::move(client2_ptr));
WaitForRequests(2);
mock_host_resolver_.ResolveAllPending();
@@ -232,10 +233,10 @@ TEST_F(MojoHostResolverImplTest, ResolveDuplicate) {
interfaces::HostResolverRequestInfoPtr request1 =
CreateRequest("example.com", 80, false);
- resolver_service_->Resolve(request1.Pass(), client1_ptr.Pass());
+ resolver_service_->Resolve(std::move(request1), std::move(client1_ptr));
interfaces::HostResolverRequestInfoPtr request2 =
CreateRequest("example.com", 80, false);
- resolver_service_->Resolve(request2.Pass(), client2_ptr.Pass());
+ resolver_service_->Resolve(std::move(request2), std::move(client2_ptr));
WaitForRequests(2);
mock_host_resolver_.ResolveAllPending();
@@ -258,7 +259,7 @@ TEST_F(MojoHostResolverImplTest, ResolveFailure) {
interfaces::HostResolverRequestInfoPtr request =
CreateRequest("failure.fail", 80, false);
- resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
+ resolver_service_->Resolve(std::move(request), std::move(client_ptr));
client.WaitForResult();
EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, client.error_);
@@ -274,7 +275,7 @@ TEST_F(MojoHostResolverImplTest, DestroyClient) {
interfaces::HostResolverRequestInfoPtr request =
CreateRequest("example.com", 80, false);
- resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
+ resolver_service_->Resolve(std::move(request), std::move(client_ptr));
WaitForRequests(1);
client.reset();
diff --git a/chromium/net/dns/mojo_host_type_converters.cc b/chromium/net/dns/mojo_host_type_converters.cc
index c64679ef46c..07dfe4df23f 100644
--- a/chromium/net/dns/mojo_host_type_converters.cc
+++ b/chromium/net/dns/mojo_host_type_converters.cc
@@ -4,9 +4,11 @@
#include "net/dns/mojo_host_type_converters.h"
+#include <utility>
+
+#include "mojo/public/cpp/bindings/type_converter.h"
#include "net/base/address_list.h"
#include "net/base/net_util.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/type_converter.h"
namespace net {
namespace {
@@ -64,7 +66,7 @@ TypeConverter<net::interfaces::HostResolverRequestInfoPtr,
result->port = obj.port();
result->address_family = net::AddressFamilyToMojo(obj.address_family());
result->is_my_ip_address = obj.is_my_ip_address();
- return result.Pass();
+ return result;
}
// static
@@ -76,9 +78,9 @@ TypeConverter<net::interfaces::AddressListPtr, net::AddressList>::Convert(
net::interfaces::IPEndPointPtr ep(net::interfaces::IPEndPoint::New());
ep->port = endpoint.port();
ep->address = mojo::Array<uint8_t>::From(endpoint.address());
- result->addresses.push_back(ep.Pass());
+ result->addresses.push_back(std::move(ep));
}
- return result.Pass();
+ return result;
}
// static
diff --git a/chromium/net/dns/notify_watcher_mac.h b/chromium/net/dns/notify_watcher_mac.h
index ded752cea71..5a8734398d7 100644
--- a/chromium/net/dns/notify_watcher_mac.h
+++ b/chromium/net/dns/notify_watcher_mac.h
@@ -6,6 +6,7 @@
#define NET_DNS_NOTIFY_WATCHER_MAC_H_
#include "base/callback.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
namespace net {
diff --git a/chromium/net/dns/record_parsed.cc b/chromium/net/dns/record_parsed.cc
index 4ae6ed29210..c5a72ef59dc 100644
--- a/chromium/net/dns/record_parsed.cc
+++ b/chromium/net/dns/record_parsed.cc
@@ -4,18 +4,26 @@
#include "net/dns/record_parsed.h"
+#include <utility>
+
#include "base/logging.h"
#include "net/dns/dns_response.h"
#include "net/dns/record_rdata.h"
namespace net {
-RecordParsed::RecordParsed(const std::string& name, uint16 type, uint16 klass,
- uint32 ttl, scoped_ptr<const RecordRdata> rdata,
+RecordParsed::RecordParsed(const std::string& name,
+ uint16_t type,
+ uint16_t klass,
+ uint32_t ttl,
+ scoped_ptr<const RecordRdata> rdata,
base::Time time_created)
- : name_(name), type_(type), klass_(klass), ttl_(ttl), rdata_(rdata.Pass()),
- time_created_(time_created) {
-}
+ : name_(name),
+ type_(type),
+ klass_(klass),
+ ttl_(ttl),
+ rdata_(std::move(rdata)),
+ time_created_(time_created) {}
RecordParsed::~RecordParsed() {
}
@@ -60,18 +68,15 @@ scoped_ptr<const RecordParsed> RecordParsed::CreateFrom(
if (!rdata.get())
return scoped_ptr<const RecordParsed>();
- return scoped_ptr<const RecordParsed>(new RecordParsed(record.name,
- record.type,
- record.klass,
- record.ttl,
- rdata.Pass(),
- time_created));
+ return scoped_ptr<const RecordParsed>(
+ new RecordParsed(record.name, record.type, record.klass, record.ttl,
+ std::move(rdata), time_created));
}
bool RecordParsed::IsEqual(const RecordParsed* other, bool is_mdns) const {
DCHECK(other);
- uint16 klass = klass_;
- uint16 other_klass = other->klass_;
+ uint16_t klass = klass_;
+ uint16_t other_klass = other->klass_;
if (is_mdns) {
klass &= dns_protocol::kMDnsClassMask;
diff --git a/chromium/net/dns/record_parsed.h b/chromium/net/dns/record_parsed.h
index 016c4910bfb..654574cc26e 100644
--- a/chromium/net/dns/record_parsed.h
+++ b/chromium/net/dns/record_parsed.h
@@ -5,6 +5,8 @@
#ifndef NET_DNS_RECORD_PARSED_H_
#define NET_DNS_RECORD_PARSED_H_
+#include <stdint.h>
+
#include <string>
#include "base/memory/scoped_ptr.h"
@@ -27,9 +29,9 @@ class NET_EXPORT_PRIVATE RecordParsed {
base::Time time_created);
const std::string& name() const { return name_; }
- uint16 type() const { return type_; }
- uint16 klass() const { return klass_; }
- uint32 ttl() const { return ttl_; }
+ uint16_t type() const { return type_; }
+ uint16_t klass() const { return klass_; }
+ uint32_t ttl() const { return ttl_; }
base::Time time_created() const { return time_created_; }
@@ -45,14 +47,17 @@ class NET_EXPORT_PRIVATE RecordParsed {
bool IsEqual(const RecordParsed* other, bool is_mdns) const;
private:
- RecordParsed(const std::string& name, uint16 type, uint16 klass,
- uint32 ttl, scoped_ptr<const RecordRdata> rdata,
+ RecordParsed(const std::string& name,
+ uint16_t type,
+ uint16_t klass,
+ uint32_t ttl,
+ scoped_ptr<const RecordRdata> rdata,
base::Time time_created);
std::string name_; // in dotted form
- const uint16 type_;
- const uint16 klass_;
- const uint32 ttl_;
+ const uint16_t type_;
+ const uint16_t klass_;
+ const uint32_t ttl_;
const scoped_ptr<const RecordRdata> rdata_;
diff --git a/chromium/net/dns/record_parsed_unittest.cc b/chromium/net/dns/record_parsed_unittest.cc
index 2864dcbe761..cfaac31c03b 100644
--- a/chromium/net/dns/record_parsed_unittest.cc
+++ b/chromium/net/dns/record_parsed_unittest.cc
@@ -12,23 +12,16 @@
namespace net {
-static const uint8 kT1ResponseWithCacheFlushBit[] = {
- 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w',
- 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm',
- 0x03, 'o', 'r', 'g',
- 0x00,
- 0x00, 0x05, // TYPE is CNAME.
- 0x80, 0x01, // CLASS is IN with cache flush bit set.
- 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
- 0x24, 0x74,
- 0x00, 0x12, // RDLENGTH is 18 bytes.
- // ghs.l.google.com in DNS format.
- 0x03, 'g', 'h', 's',
- 0x01, 'l',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00
-};
+static const uint8_t kT1ResponseWithCacheFlushBit[] = {
+ 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x08, 'c', 'h', 'r',
+ 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00, 0x00,
+ 0x05, // TYPE is CNAME.
+ 0x80, 0x01, // CLASS is IN with cache flush bit set.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
+ 0x24, 0x74, 0x00, 0x12, // RDLENGTH is 18 bytes.
+ // ghs.l.google.com in DNS format.
+ 0x03, 'g', 'h', 's', 0x01, 'l', 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 0x03,
+ 'c', 'o', 'm', 0x00};
TEST(RecordParsedTest, ParseSingleRecord) {
DnsRecordParser parser(kT1ResponseDatagram, sizeof(kT1ResponseDatagram),
diff --git a/chromium/net/dns/record_rdata.cc b/chromium/net/dns/record_rdata.cc
index 4503b68d425..22134737b05 100644
--- a/chromium/net/dns/record_rdata.cc
+++ b/chromium/net/dns/record_rdata.cc
@@ -39,10 +39,10 @@ scoped_ptr<SrvRecordRdata> SrvRecordRdata::Create(
&rdata->target_))
return scoped_ptr<SrvRecordRdata>();
- return rdata.Pass();
+ return rdata;
}
-uint16 SrvRecordRdata::Type() const {
+uint16_t SrvRecordRdata::Type() const {
return SrvRecordRdata::kType;
}
@@ -75,10 +75,10 @@ scoped_ptr<ARecordRdata> ARecordRdata::Create(
rdata->address_[i] = data[i];
}
- return rdata.Pass();
+ return rdata;
}
-uint16 ARecordRdata::Type() const {
+uint16_t ARecordRdata::Type() const {
return ARecordRdata::kType;
}
@@ -108,10 +108,10 @@ scoped_ptr<AAAARecordRdata> AAAARecordRdata::Create(
rdata->address_[i] = data[i];
}
- return rdata.Pass();
+ return rdata;
}
-uint16 AAAARecordRdata::Type() const {
+uint16_t AAAARecordRdata::Type() const {
return AAAARecordRdata::kType;
}
@@ -136,10 +136,10 @@ scoped_ptr<CnameRecordRdata> CnameRecordRdata::Create(
if (!parser.ReadName(data.begin(), &rdata->cname_))
return scoped_ptr<CnameRecordRdata>();
- return rdata.Pass();
+ return rdata;
}
-uint16 CnameRecordRdata::Type() const {
+uint16_t CnameRecordRdata::Type() const {
return CnameRecordRdata::kType;
}
@@ -165,10 +165,10 @@ scoped_ptr<PtrRecordRdata> PtrRecordRdata::Create(
if (!parser.ReadName(data.begin(), &rdata->ptrdomain_))
return scoped_ptr<PtrRecordRdata>();
- return rdata.Pass();
+ return rdata;
}
-uint16 PtrRecordRdata::Type() const {
+uint16_t PtrRecordRdata::Type() const {
return PtrRecordRdata::kType;
}
@@ -191,7 +191,7 @@ scoped_ptr<TxtRecordRdata> TxtRecordRdata::Create(
scoped_ptr<TxtRecordRdata> rdata(new TxtRecordRdata);
for (size_t i = 0; i < data.size(); ) {
- uint8 length = data[i];
+ uint8_t length = data[i];
if (i + length >= data.size())
return scoped_ptr<TxtRecordRdata>();
@@ -202,10 +202,10 @@ scoped_ptr<TxtRecordRdata> TxtRecordRdata::Create(
i += length + 1;
}
- return rdata.Pass();
+ return rdata;
}
-uint16 TxtRecordRdata::Type() const {
+uint16_t TxtRecordRdata::Type() const {
return TxtRecordRdata::kType;
}
@@ -237,8 +237,8 @@ scoped_ptr<NsecRecordRdata> NsecRecordRdata::Create(
return scoped_ptr<NsecRecordRdata>();
struct BitmapHeader {
- uint8 block_number; // The block number should be zero.
- uint8 length; // Bitmap length in bytes. Between 1 and 32.
+ uint8_t block_number; // The block number should be zero.
+ uint8_t length; // Bitmap length in bytes. Between 1 and 32.
};
const BitmapHeader* header = reinterpret_cast<const BitmapHeader*>(
@@ -260,10 +260,10 @@ scoped_ptr<NsecRecordRdata> NsecRecordRdata::Create(
bitmap_data.begin(),
bitmap_data.end());
- return rdata.Pass();
+ return rdata;
}
-uint16 NsecRecordRdata::Type() const {
+uint16_t NsecRecordRdata::Type() const {
return NsecRecordRdata::kType;
}
diff --git a/chromium/net/dns/record_rdata.h b/chromium/net/dns/record_rdata.h
index a94d628f7fe..8184edd62f4 100644
--- a/chromium/net/dns/record_rdata.h
+++ b/chromium/net/dns/record_rdata.h
@@ -5,11 +5,13 @@
#ifndef NET_DNS_RECORD_RDATA_H_
#define NET_DNS_RECORD_RDATA_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/ip_address_number.h"
@@ -27,7 +29,7 @@ class NET_EXPORT_PRIVATE RecordRdata {
virtual ~RecordRdata() {}
virtual bool IsEqual(const RecordRdata* other) const = 0;
- virtual uint16 Type() const = 0;
+ virtual uint16_t Type() const = 0;
protected:
RecordRdata();
@@ -42,27 +44,27 @@ class NET_EXPORT_PRIVATE RecordRdata {
// target: domain name (on-the-wire representation)
class NET_EXPORT_PRIVATE SrvRecordRdata : public RecordRdata {
public:
- static const uint16 kType = dns_protocol::kTypeSRV;
+ static const uint16_t kType = dns_protocol::kTypeSRV;
~SrvRecordRdata() override;
static scoped_ptr<SrvRecordRdata> Create(const base::StringPiece& data,
const DnsRecordParser& parser);
bool IsEqual(const RecordRdata* other) const override;
- uint16 Type() const override;
+ uint16_t Type() const override;
- uint16 priority() const { return priority_; }
- uint16 weight() const { return weight_; }
- uint16 port() const { return port_; }
+ uint16_t priority() const { return priority_; }
+ uint16_t weight() const { return weight_; }
+ uint16_t port() const { return port_; }
const std::string& target() const { return target_; }
private:
SrvRecordRdata();
- uint16 priority_;
- uint16 weight_;
- uint16 port_;
+ uint16_t priority_;
+ uint16_t weight_;
+ uint16_t port_;
std::string target_;
@@ -73,13 +75,13 @@ class NET_EXPORT_PRIVATE SrvRecordRdata : public RecordRdata {
// 4 bytes for IP address.
class NET_EXPORT_PRIVATE ARecordRdata : public RecordRdata {
public:
- static const uint16 kType = dns_protocol::kTypeA;
+ static const uint16_t kType = dns_protocol::kTypeA;
~ARecordRdata() override;
static scoped_ptr<ARecordRdata> Create(const base::StringPiece& data,
const DnsRecordParser& parser);
bool IsEqual(const RecordRdata* other) const override;
- uint16 Type() const override;
+ uint16_t Type() const override;
const IPAddressNumber& address() const { return address_; }
@@ -95,13 +97,13 @@ class NET_EXPORT_PRIVATE ARecordRdata : public RecordRdata {
// 16 bytes for IP address.
class NET_EXPORT_PRIVATE AAAARecordRdata : public RecordRdata {
public:
- static const uint16 kType = dns_protocol::kTypeAAAA;
+ static const uint16_t kType = dns_protocol::kTypeAAAA;
~AAAARecordRdata() override;
static scoped_ptr<AAAARecordRdata> Create(const base::StringPiece& data,
const DnsRecordParser& parser);
bool IsEqual(const RecordRdata* other) const override;
- uint16 Type() const override;
+ uint16_t Type() const override;
const IPAddressNumber& address() const { return address_; }
@@ -117,13 +119,13 @@ class NET_EXPORT_PRIVATE AAAARecordRdata : public RecordRdata {
// cname: On the wire representation of domain name.
class NET_EXPORT_PRIVATE CnameRecordRdata : public RecordRdata {
public:
- static const uint16 kType = dns_protocol::kTypeCNAME;
+ static const uint16_t kType = dns_protocol::kTypeCNAME;
~CnameRecordRdata() override;
static scoped_ptr<CnameRecordRdata> Create(const base::StringPiece& data,
const DnsRecordParser& parser);
bool IsEqual(const RecordRdata* other) const override;
- uint16 Type() const override;
+ uint16_t Type() const override;
std::string cname() const { return cname_; }
@@ -139,13 +141,13 @@ class NET_EXPORT_PRIVATE CnameRecordRdata : public RecordRdata {
// domain: On the wire representation of domain name.
class NET_EXPORT_PRIVATE PtrRecordRdata : public RecordRdata {
public:
- static const uint16 kType = dns_protocol::kTypePTR;
+ static const uint16_t kType = dns_protocol::kTypePTR;
~PtrRecordRdata() override;
static scoped_ptr<PtrRecordRdata> Create(const base::StringPiece& data,
const DnsRecordParser& parser);
bool IsEqual(const RecordRdata* other) const override;
- uint16 Type() const override;
+ uint16_t Type() const override;
std::string ptrdomain() const { return ptrdomain_; }
@@ -162,13 +164,13 @@ class NET_EXPORT_PRIVATE PtrRecordRdata : public RecordRdata {
// a <character-string> is a length octet followed by as many characters.
class NET_EXPORT_PRIVATE TxtRecordRdata : public RecordRdata {
public:
- static const uint16 kType = dns_protocol::kTypeTXT;
+ static const uint16_t kType = dns_protocol::kTypeTXT;
~TxtRecordRdata() override;
static scoped_ptr<TxtRecordRdata> Create(const base::StringPiece& data,
const DnsRecordParser& parser);
bool IsEqual(const RecordRdata* other) const override;
- uint16 Type() const override;
+ uint16_t Type() const override;
const std::vector<std::string>& texts() const { return texts_; }
@@ -186,13 +188,13 @@ class NET_EXPORT_PRIVATE TxtRecordRdata : public RecordRdata {
// http://www.rfc-editor.org/rfc/rfc6762.txt Section 6.1.
class NET_EXPORT_PRIVATE NsecRecordRdata : public RecordRdata {
public:
- static const uint16 kType = dns_protocol::kTypeNSEC;
+ static const uint16_t kType = dns_protocol::kTypeNSEC;
~NsecRecordRdata() override;
static scoped_ptr<NsecRecordRdata> Create(const base::StringPiece& data,
const DnsRecordParser& parser);
bool IsEqual(const RecordRdata* other) const override;
- uint16 Type() const override;
+ uint16_t Type() const override;
// Length of the bitmap in bits.
unsigned bitmap_length() const { return bitmap_.size() * 8; }
@@ -205,7 +207,7 @@ class NET_EXPORT_PRIVATE NsecRecordRdata : public RecordRdata {
private:
NsecRecordRdata();
- std::vector<uint8> bitmap_;
+ std::vector<uint8_t> bitmap_;
DISALLOW_COPY_AND_ASSIGN(NsecRecordRdata);
};
diff --git a/chromium/net/dns/record_rdata_unittest.cc b/chromium/net/dns/record_rdata_unittest.cc
index d5306d807a4..d83f497cb42 100644
--- a/chromium/net/dns/record_rdata_unittest.cc
+++ b/chromium/net/dns/record_rdata_unittest.cc
@@ -11,7 +11,7 @@
namespace net {
-base::StringPiece MakeStringPiece(const uint8* data, unsigned size) {
+base::StringPiece MakeStringPiece(const uint8_t* data, unsigned size) {
const char* data_cc = reinterpret_cast<const char*>(data);
return base::StringPiece(data_cc, size);
}
@@ -23,20 +23,15 @@ TEST(RecordRdataTest, ParseSrvRecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
- const uint8 record[] = {
- 0x00, 0x01,
- 0x00, 0x02,
- 0x00, 0x50,
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x01, 0x01,
- 0x01, 0x02,
- 0x01, 0x03,
- 0x04, 'w', 'w', 'w', '2',
- 0xc0, 0x0a, // Pointer to "google.com"
- };
+ const uint8_t
+ record[] =
+ {
+ 0x00, 0x01, 0x00, 0x02, 0x00, 0x50, 0x03, 'w', 'w',
+ 'w', 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 0x03,
+ 'c', 'o', 'm', 0x00, 0x01, 0x01, 0x01, 0x02, 0x01,
+ 0x03, 0x04, 'w', 'w', 'w', '2', 0xc0, 0x0a, // Pointer to
+ // "google.com"
+ };
DnsRecordParser parser(record, sizeof(record), 0);
const unsigned first_record_len = 22;
@@ -71,8 +66,8 @@ TEST(RecordRdataTest, ParseARecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
- const uint8 record[] = {
- 0x7F, 0x00, 0x00, 0x01 // 127.0.0.1
+ const uint8_t record[] = {
+ 0x7F, 0x00, 0x00, 0x01 // 127.0.0.1
};
DnsRecordParser parser(record, sizeof(record), 0);
@@ -92,11 +87,9 @@ TEST(RecordRdataTest, ParseAAAARecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
- const uint8 record[] = {
- 0x12, 0x34, 0x56, 0x78,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x09 // 1234:5678::9A
+ const uint8_t record[] = {
+ 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 // 1234:5678::9A
};
DnsRecordParser parser(record, sizeof(record), 0);
@@ -117,12 +110,8 @@ TEST(RecordRdataTest, ParseCnameRecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
- const uint8 record[] = {
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00
- };
+ const uint8_t record[] = {0x03, 'w', 'w', 'w', 0x06, 'g', 'o', 'o',
+ 'g', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00};
DnsRecordParser parser(record, sizeof(record), 0);
base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));
@@ -141,12 +130,8 @@ TEST(RecordRdataTest, ParsePtrRecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
- const uint8 record[] = {
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00
- };
+ const uint8_t record[] = {0x03, 'w', 'w', 'w', 0x06, 'g', 'o', 'o',
+ 'g', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00};
DnsRecordParser parser(record, sizeof(record), 0);
base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));
@@ -165,11 +150,8 @@ TEST(RecordRdataTest, ParseTxtRecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
- const uint8 record[] = {
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm'
- };
+ const uint8_t record[] = {0x03, 'w', 'w', 'w', 0x06, 'g', 'o', 'o',
+ 'g', 'l', 'e', 0x03, 'c', 'o', 'm'};
DnsRecordParser parser(record, sizeof(record), 0);
base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));
@@ -193,13 +175,9 @@ TEST(RecordRdataTest, ParseNsecRecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
- const uint8 record[] = {
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x02, 0x40, 0x01
- };
+ const uint8_t record[] = {0x03, 'w', 'w', 'w', 0x06, 'g', 'o',
+ 'o', 'g', 'l', 'e', 0x03, 'c', 'o',
+ 'm', 0x00, 0x00, 0x02, 0x40, 0x01};
DnsRecordParser parser(record, sizeof(record), 0);
base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));
diff --git a/chromium/net/dns/serial_worker.h b/chromium/net/dns/serial_worker.h
index f63178a593e..c48a61b1e26 100644
--- a/chromium/net/dns/serial_worker.h
+++ b/chromium/net/dns/serial_worker.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/dns/single_request_host_resolver.h b/chromium/net/dns/single_request_host_resolver.h
index 3c8ef020edc..f2843093fc8 100644
--- a/chromium/net/dns/single_request_host_resolver.h
+++ b/chromium/net/dns/single_request_host_resolver.h
@@ -5,8 +5,7 @@
#ifndef NET_DNS_SINGLE_REQUEST_HOST_RESOLVER_H_
#define NET_DNS_SINGLE_REQUEST_HOST_RESOLVER_H_
-#include "base/basictypes.h"
-
+#include "base/macros.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
diff --git a/chromium/net/dns/single_request_host_resolver_unittest.cc b/chromium/net/dns/single_request_host_resolver_unittest.cc
index 8bd285f1534..c5bb9f1ae6b 100644
--- a/chromium/net/dns/single_request_host_resolver_unittest.cc
+++ b/chromium/net/dns/single_request_host_resolver_unittest.cc
@@ -4,6 +4,7 @@
#include "net/dns/single_request_host_resolver.h"
+#include "base/macros.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
diff --git a/chromium/net/docs/bug-triage-labels.md b/chromium/net/docs/bug-triage-labels.md
index d6f3e2ba940..5f2b0d496c1 100644
--- a/chromium/net/docs/bug-triage-labels.md
+++ b/chromium/net/docs/bug-triage-labels.md
@@ -70,14 +70,20 @@ they fall largely outside the purview of the network stack team:
**Cr-Blink-Storage-AppCache**
-**Cr-Blink-WebSockets**
+**Cr-Blink-Network-WebSockets**
+: Issues with the WebSockets. Attach this label to any issue about the
+ WebSocket feature regardless of where the cause of the issue is (net/ or
+ Blink).
-**Cr-Blink-XHR**
-: Generic issues with sync/async XHR requests - missing request or response
+**Cr-Blink-Network-FetchAPI**
+: Generic issues with the Fetch API - missing request or response
headers, multiple headers, etc. These will often run into issues in certain
corner cases (Cross origin / CORS, proxy, whatever). Attach all labels that
seem appropriate.
+**Cr-Blink-Network-XHR**
+: Generic issues with sync/async XHR requests.
+
**Cr-Services-Sync**
: Sharing data/tabs/history/passwords/etc between machines not working.
diff --git a/chromium/net/docs/bug-triage-suggested-workflow.md b/chromium/net/docs/bug-triage-suggested-workflow.md
index c3b55e4b882..43a8e41c88c 100644
--- a/chromium/net/docs/bug-triage-suggested-workflow.md
+++ b/chromium/net/docs/bug-triage-suggested-workflow.md
@@ -159,10 +159,16 @@
sublabel applies, or only the Cr-Internals-Network-HTTP sublabel applies, and
there's no clear owner), try to figure out the exact cause.
-## Monitoring UMA histograms and gasper alerts
+## Monitoring UMA histograms and Chirp/Gasper alerts
-For each Gasper alert that fires, determine if it's a real alert and file a bug
-if so.
+Sign up to chrome-network-debugging@google.com mailing list to receive automated
+e-mails about UMA alerts. Chirp is the new alert system, sending automated
+e-mails with sender address finch-chirp@google.com. Gasper is the old alert
+system, sending automated e-mails with sender address gasper-alerts@google.com.
+While Chirp is of higher priority, Gasper is not deprecated yet, so both alerts
+should be monitored for the time being.
+
+For each alert that fires, determine if it's a real alert and file a bug if so.
* Don't file if the alert is coincident with a major volume change. The volume
at a particular date can be determined by hovering the mouse over the
@@ -178,9 +184,8 @@ if so.
* SimpleCache on Windows
* DiskCache on Android.
-For each Gasper alert, respond to chrome-network-debugging@google.com with a
-summary of the action you've taken and why, including issue link if an issue
-was filed.
+For each alert, respond to chrome-network-debugging@google.com with a summary of
+the action you've taken and why, including issue link if an issue was filed.
## Investigating crashers
diff --git a/chromium/net/docs/bug-triage.md b/chromium/net/docs/bug-triage.md
index 58d4c749183..38a7f63c3fc 100644
--- a/chromium/net/docs/bug-triage.md
+++ b/chromium/net/docs/bug-triage.md
@@ -11,7 +11,7 @@ label seems suitable.
* Identify new network issues.
* Request data about recent Cr-Internals-Network issue.
* Investigate each recent Cr-Internals-Network issue.
-* Monitor UMA histograms and gasper alerts.
+* Monitor UMA histograms and Chirp/Gasper alerts.
### Best effort:
* Investigate unowned and owned-but-forgotten net/ crashers
@@ -67,11 +67,11 @@ uniform, predictable two day commitment for all triagers.
Available. Future triagers should ignore bugs with this status, unless
investigating stale bugs.
-* Monitor UMA histograms and gasper alerts.
+* Monitor UMA histograms and Chirp/Gasper alerts.
- * For each Gasper alert that fires, the triager should determine if the
- alert is real (not due to noise), and file a bug with the appropriate
- label if so. Note that if no label more specific than
+ * For each Chirp and Gasper alert that fires, the triager should determine
+ if the alert is real (not due to noise), and file a bug with the
+ appropriate label if so. Note that if no label more specific than
Cr-Internals-Network is appropriate, the responsibility remains with the
triager to continue investigating the bug, as above.
@@ -96,3 +96,6 @@ suggested workflows.
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. \ No newline at end of file
diff --git a/chromium/net/docs/crash-course-in-net-internals.md b/chromium/net/docs/crash-course-in-net-internals.md
new file mode 100644
index 00000000000..5dcfb244ced
--- /dev/null
+++ b/chromium/net/docs/crash-course-in-net-internals.md
@@ -0,0 +1,183 @@
+# A Crash Course in Debugging with about: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
+document is aimed more at how to get started using some of its features to
+investigate bug reports, rather than as a feature overview.
+
+It would probably be useful to read [life-of-a-url-request.md](
+life-of-a-url-request.md) before this document.
+
+# 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.
+
+The top level network stack object is the URLRequestContext. The Events View
+has information for all Chrome URLRequestContexts that are hooked up to the
+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 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. Most
+debugging is done with the Events view (which will be all this document
+covers), but it's good to be aware of this distinction.
+
+# Events vs Sources
+
+The Event View shows events logged by the NetLog. The NetLog model is that
+long-lived network stack objects, called sources, emit events over their
+lifetime. Some events have a beginning and end point (during which other
+subevents may occur), and some only occur at a single point in time. Generally
+only one event can be occuring for a source at a time. If there can be multiple
+events doing completely independent thing, the code often uses new sources to
+represent the parallelism.
+
+"Sources" correspond to certain net objects, however, multiple layers of net/
+will often log to a single source. Here are the main source types and what they
+include (Excluding HTTP2 [SPDY]/QUIC):
+
+* URL_REQUEST: This corresponds to the URLRequest object. It includes events
+from all the URLRequestJobs, HttpCache::Transactions, NetworkTransactions,
+HttpStreamFactoryImpl::Requests, HttpStream implementations, and
+HttpStreamParsers used to service a response. If the URL_REQUEST follows HTTP
+redirects, it will include each redirect. This is a lot of stuff, but generally
+only object is doing work at a time. This event source includes the full URL
+and generally includes the request / response headers (Except when the cache
+handles the response).
+
+* HTTP_STREAM_JOB: This corresponds to HttpStreamFactoryImpl::Job (Note that
+one Request can have multiple Jobs). It also includes its proxy and DNS
+lookups. HTTP_STREAM_JOB log events are separate from URL_REQUEST because
+two stream jobs may be created and races against each other, in some cases -
+one for one for QUIC, and one for HTTP. One of the final events of this source
+indicates how an HttpStream was created (Reusing an existing SOCKET /
+HTTP2_SESSION / QUIC_SESSION, or creating a new one).
+
+* CONNECT_JOB: This corresponds to the ConnectJob subclasses that each socket
+pool uses. A successful CONNECT_JOB return a SOCKET. The events here vary a
+lot by job type. Their main event is generally either to create a socket, or
+request a socket from another socket pool (Which creates another CONNECT_JOB)
+and then do some extra work on top of that - like establish an SSL connection on
+top of a TCP connection.
+
+* SOCKET: These correspond to TCPSockets, but may also have other classes
+layered on top of them (Like an SSLClientSocket). This is a bit different from
+the other classes, where the name corresponds to the topmost class, instead of
+the bottommost one. This is largely an artifact of the fact the socket is
+created first, and then SSL (Or a proxy connection) is layered on top of it.
+SOCKETs may be reused between multiple requests, and a request may end up
+getting a socket created for another request.
+
+* HOST_RESOLVER_IMPL_JOB: These correspond to HostResolverImpl::Job. The
+include information about how long the lookup was queued, each DNS request that
+was attempted (With the platform or built-in resolver) and all the other sources
+that are waiting on the job.
+
+When one source depends on another, the code generally logs an event with
+"source_dependency" value to both sources, which lets you jump between the two
+related events.
+
+# Debugging
+
+When you receive a report from the user, the first thing you'll generally want
+to do find the URL_REQUEST[s] that are misbehaving. If the user gives an ERR_*
+code or the exact URL of the resource that won't load, you can just search for
+it. If it's an upload, you can search for "post", or if it's a redirect issue,
+you can search for "redirect". However, you often won't have much information
+about the actual problem. There are two filters in net-internals that can help
+in a lot of cases:
+
+* "type:URL_REQUEST is:error" will restrict the list to URL_REQUEST object with
+an error of some sort (red background). Cache errors are often non-fatal, so
+you should generally ignore those, and look for a more interesting one.
+
+* "type:URL_REQUEST sort:duration" will show the lonest-lived requests (as of
+when about:net-internals was opened) first. 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.
+
+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
+to response or request headers. You can use "source_dependency" links to drill
+down into other related sources, or up from layers below URL_REQUEST.
+
+You can use the name of an event to search for the code responsible for that
+event, and try to deduce what went wrong before/after a particular event. Note
+that the event names used in net-internals are not the entire string names, so
+you should not do an entire string match.
+
+Some things to look for while debugging:
+
+* CANCELLED events almost always come from outside the network stack.
+
+* Changing networks and entering / exiting suspend mode can have all sorts of
+fun and exciting effects on underway network activity. Network changes log a
+top level NETWORK_CHANGED event with no source - the event itself is treated as
+its own source. Suspend events are currently not logged.
+
+* URL_REQUEST_DELEGATE / DELEGATE_INFO events mean a URL_REQUEST is blocked on a
+URLRequest::Delegate or the NetworkDelegate, which are implemented outside the
+network stack. A request will sometimes be CANCELED here for reasons known only
+to the delegate. Or the delegate may cause a hang. In general, to debug issues
+related to delegates, one needs to figure out which method of which object is
+causing the problem. The object may be the a NetworkDelegate, a
+ResourceThrottle, a ResourceHandler, the ResourceLoader itself, or the
+ResourceDispatcherHost.
+
+* Sockets are often reused between requests. If a request is on a stale
+(reused) socket, what was the previous request that used the socket, how long
+ago was it made?
+
+* SSL negotation is a process fraught with peril, particularly with broken
+proxies. These will generally stall or fail in the SSL_CONNECT phase at the
+SOCKET layer.
+
+* Range requests have magic to handle them at the cache layer, and are often
+issued by the media and PDF code.
+
+* Late binding: HTTP_STREAM_JOBs are not associated with any CONNECT_JOB until
+a CONNECT_JOB actually connects. This is so the highest priority pending job
+gets the first available socket (Which may be a new socket, or an old one that's
+freed up). For this reason, it can be a little tricky to relate hung
+HTTP_STREAM_JOBs to CONNECT_JOBs.
+
+* Each CONNECT_JOB belongs to a "group", which has a limit of 6 connections. If
+all CONNECT_JOBs beling to a group (The CONNECT_JOB's description field) are
+stalled waiting on an available socket, the group probably has 6 sockets that
+that are hung - either hung trying to connect, or used by stalled requests and
+thus outside the socket pool's control.
+
+* There's a limit on number of DNS resolutions that can be started at once. If
+everything is stalled while resolving DNS addresses, you've probably hit this
+limit, and the DNS lookups are also misbehaving in some fashion.
+
+# Miscellany
+
+These are just miscellaneous things you may notice when looking through the
+logs.
+
+* URLRequests that look to start twice for no obvious reason. These are
+typically main frame requests, and the first request is AppCache. Can just
+ignore it and move on with your life.
+
+* Some HTTP requests are not handled by URLRequestHttpJobs. These include
+things like HSTS redirects (URLRequestRedirectJob), AppCache, ServiceWorker,
+etc. These generally don't log as much information, so it can be tricky to
+figure out what's going on with these.
+
+* Non-HTTP requests also appear in the log, and also generally don't log much
+(blob URLs, chrome URLs, etc).
+
+* Preconnects create a "HTTP_STREAM_JOB" event that may create multiple
+CONNECT_JOBs (or none) and is then destroyed. These can be identified by the
+"SOCKET_POOL_CONNECTING_N_SOCKETS" events.
diff --git a/chromium/net/extras/sqlite/sqlite_channel_id_store.cc b/chromium/net/extras/sqlite/sqlite_channel_id_store.cc
index c6aa09a09e9..5b8b351b433 100644
--- a/chromium/net/extras/sqlite/sqlite_channel_id_store.cc
+++ b/chromium/net/extras/sqlite/sqlite_channel_id_store.cc
@@ -5,15 +5,16 @@
#include "net/extras/sqlite/sqlite_channel_id_store.h"
#include <set>
+#include <utility>
+#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
@@ -82,7 +83,7 @@ class SQLiteChannelIDStore::Backend
}
void LoadInBackground(
- ScopedVector<DefaultChannelIDStore::ChannelID>* channel_ids);
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>* channel_ids);
// Database upgrade statements.
bool EnsureDatabaseVersion();
@@ -148,9 +149,10 @@ void SQLiteChannelIDStore::Backend::Load(
const LoadedCallback& loaded_callback) {
// This function should be called only once per instance.
DCHECK(!db_.get());
- scoped_ptr<ScopedVector<DefaultChannelIDStore::ChannelID> > channel_ids(
- new ScopedVector<DefaultChannelIDStore::ChannelID>());
- ScopedVector<DefaultChannelIDStore::ChannelID>* channel_ids_ptr =
+ scoped_ptr<std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>>
+ channel_ids(
+ new std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>());
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>* channel_ids_ptr =
channel_ids.get();
background_task_runner_->PostTaskAndReply(
@@ -160,7 +162,7 @@ void SQLiteChannelIDStore::Backend::Load(
}
void SQLiteChannelIDStore::Backend::LoadInBackground(
- ScopedVector<DefaultChannelIDStore::ChannelID>* channel_ids) {
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>* channel_ids) {
DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
// This method should be called only once per instance.
@@ -174,7 +176,7 @@ void SQLiteChannelIDStore::Backend::LoadInBackground(
if (!base::PathExists(dir) && !base::CreateDirectory(dir))
return;
- int64 db_size = 0;
+ int64_t db_size = 0;
if (base::GetFileSize(path_, &db_size))
UMA_HISTOGRAM_COUNTS("DomainBoundCerts.DBSizeInKB", db_size / 1024);
@@ -217,7 +219,7 @@ void SQLiteChannelIDStore::Backend::LoadInBackground(
}
while (smt.Step()) {
- std::vector<uint8> private_key_from_db, public_key_from_db;
+ std::vector<uint8_t> private_key_from_db, public_key_from_db;
smt.ColumnBlobAsVector(1, &private_key_from_db);
smt.ColumnBlobAsVector(2, &public_key_from_db);
scoped_ptr<crypto::ECPrivateKey> key(
@@ -229,8 +231,8 @@ void SQLiteChannelIDStore::Backend::LoadInBackground(
scoped_ptr<DefaultChannelIDStore::ChannelID> channel_id(
new DefaultChannelIDStore::ChannelID(
smt.ColumnString(0), // host
- base::Time::FromInternalValue(smt.ColumnInt64(3)), key.Pass()));
- channel_ids->push_back(channel_id.release());
+ base::Time::FromInternalValue(smt.ColumnInt64(3)), std::move(key)));
+ channel_ids->push_back(std::move(channel_id));
}
UMA_HISTOGRAM_COUNTS_10000(
@@ -492,7 +494,7 @@ void SQLiteChannelIDStore::Backend::Commit() {
case PendingOperation::CHANNEL_ID_ADD: {
add_statement.Reset(true);
add_statement.BindString(0, po->channel_id().server_identifier());
- std::vector<uint8> private_key, public_key;
+ std::vector<uint8_t> private_key, public_key;
if (!po->channel_id().key()->ExportEncryptedPrivateKey(
ChannelIDService::kEPKIPassword, 1, &private_key))
continue;
diff --git a/chromium/net/extras/sqlite/sqlite_channel_id_store_unittest.cc b/chromium/net/extras/sqlite/sqlite_channel_id_store_unittest.cc
index c06a42fa0f8..2b5e80a3aa2 100644
--- a/chromium/net/extras/sqlite/sqlite_channel_id_store_unittest.cc
+++ b/chromium/net/extras/sqlite/sqlite_channel_id_store_unittest.cc
@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <vector>
+
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
-#include "base/stl_util.h"
#include "base/thread_task_runner_handle.h"
#include "crypto/ec_private_key.h"
#include "net/base/test_data_directory.h"
@@ -28,7 +29,8 @@ const base::FilePath::CharType kTestChannelIDFilename[] =
class SQLiteChannelIDStoreTest : public testing::Test {
public:
- void Load(ScopedVector<DefaultChannelIDStore::ChannelID>* channel_ids) {
+ void Load(
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>* channel_ids) {
base::RunLoop run_loop;
store_->Load(base::Bind(&SQLiteChannelIDStoreTest::OnLoaded,
base::Unretained(this),
@@ -40,7 +42,8 @@ class SQLiteChannelIDStoreTest : public testing::Test {
void OnLoaded(
base::RunLoop* run_loop,
- scoped_ptr<ScopedVector<DefaultChannelIDStore::ChannelID> > channel_ids) {
+ scoped_ptr<std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>>
+ channel_ids) {
channel_ids_.swap(*channel_ids);
run_loop->Quit();
}
@@ -55,12 +58,12 @@ class SQLiteChannelIDStoreTest : public testing::Test {
GetTestCertsDirectory().AppendASCII("unittest.originbound.der");
ASSERT_TRUE(base::ReadFileToString(key_path, key_data));
ASSERT_TRUE(base::ReadFileToString(cert_path, cert_data));
- std::vector<uint8> private_key(key_data->size());
- memcpy(vector_as_array(&private_key), key_data->data(), key_data->size());
+ std::vector<uint8_t> private_key(key_data->size());
+ memcpy(private_key.data(), key_data->data(), key_data->size());
base::StringPiece spki;
ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(*cert_data, &spki));
- std::vector<uint8> public_key(spki.size());
- memcpy(vector_as_array(&public_key), spki.data(), spki.size());
+ std::vector<uint8_t> public_key(spki.size());
+ memcpy(public_key.data(), spki.data(), spki.size());
key->reset(crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
ChannelIDService::kEPKIPassword, private_key, public_key));
}
@@ -102,7 +105,7 @@ class SQLiteChannelIDStoreTest : public testing::Test {
store_ = new SQLiteChannelIDStore(
temp_dir_.path().Append(kTestChannelIDFilename),
base::ThreadTaskRunnerHandle::Get());
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids;
Load(&channel_ids);
ASSERT_EQ(0u, channel_ids.size());
// Make sure the store gets written at least once.
@@ -114,7 +117,7 @@ class SQLiteChannelIDStoreTest : public testing::Test {
base::ScopedTempDir temp_dir_;
scoped_refptr<SQLiteChannelIDStore> store_;
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids_;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids_;
scoped_ptr<crypto::ECPrivateKey> google_key_;
};
@@ -125,7 +128,7 @@ TEST_F(SQLiteChannelIDStoreTest, TestPersistence) {
"foo.com", base::Time::FromInternalValue(3),
make_scoped_ptr(foo_key->Copy())));
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids;
// Replace the store effectively destroying the current one and forcing it
// to write its data to disk. Then we can see if after loading it again it
// is still there.
@@ -142,11 +145,11 @@ TEST_F(SQLiteChannelIDStoreTest, TestPersistence) {
DefaultChannelIDStore::ChannelID* goog_channel_id;
DefaultChannelIDStore::ChannelID* foo_channel_id;
if (channel_ids[0]->server_identifier() == "google.com") {
- goog_channel_id = channel_ids[0];
- foo_channel_id = channel_ids[1];
+ goog_channel_id = channel_ids[0].get();
+ foo_channel_id = channel_ids[1].get();
} else {
- goog_channel_id = channel_ids[1];
- foo_channel_id = channel_ids[0];
+ goog_channel_id = channel_ids[1].get();
+ foo_channel_id = channel_ids[0].get();
}
ASSERT_EQ("google.com", goog_channel_id->server_identifier());
EXPECT_TRUE(KeysEqual(google_key_.get(), goog_channel_id->key()));
@@ -181,7 +184,7 @@ TEST_F(SQLiteChannelIDStoreTest, TestDeleteAll) {
"foo.com", base::Time::FromInternalValue(3),
make_scoped_ptr(crypto::ECPrivateKey::Create())));
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids;
// Replace the store effectively destroying the current one and forcing it
// to write its data to disk. Then we can see if after loading it again it
// is still there.
@@ -263,7 +266,7 @@ TEST_F(SQLiteChannelIDStoreTest, TestUpgradeV1) {
for (int i = 0; i < 2; ++i) {
SCOPED_TRACE(i);
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids;
store_ = new SQLiteChannelIDStore(v1_db_path,
base::ThreadTaskRunnerHandle::Get());
@@ -335,7 +338,7 @@ TEST_F(SQLiteChannelIDStoreTest, TestUpgradeV2) {
for (int i = 0; i < 2; ++i) {
SCOPED_TRACE(i);
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids;
store_ = new SQLiteChannelIDStore(v2_db_path,
base::ThreadTaskRunnerHandle::Get());
@@ -413,7 +416,7 @@ TEST_F(SQLiteChannelIDStoreTest, TestUpgradeV3) {
for (int i = 0; i < 2; ++i) {
SCOPED_TRACE(i);
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids;
store_ = new SQLiteChannelIDStore(v3_db_path,
base::ThreadTaskRunnerHandle::Get());
@@ -507,7 +510,7 @@ TEST_F(SQLiteChannelIDStoreTest, TestUpgradeV4) {
for (int i = 0; i < 2; ++i) {
SCOPED_TRACE(i);
- ScopedVector<DefaultChannelIDStore::ChannelID> channel_ids;
+ std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>> channel_ids;
store_ = new SQLiteChannelIDStore(v4_db_path,
base::ThreadTaskRunnerHandle::Get());
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
index 8a063d004f4..6f46d4fbef4 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -7,13 +7,13 @@
#include <map>
#include <set>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
@@ -42,7 +42,15 @@ namespace {
// 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.
+#if defined(OS_IOS)
+// TODO(ellyjones): This should be 200ms, but currently CookieStoreIOS is
+// waiting for -FinishedLoadingCookies to be called after all eTLD cookies are
+// loaded before making any network requests. Changing to 0ms for now.
+// crbug.com/462593
+const int kLoadDelayMilliseconds = 0;
+#else
const int kLoadDelayMilliseconds = 0;
+#endif
} // namespace
@@ -590,7 +598,7 @@ bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
return false;
}
- int64 db_size = 0;
+ int64_t db_size = 0;
if (base::GetFileSize(path_, &db_size))
UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024);
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.h b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.h
index c55ef6deec0..b8c1caad5eb 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.h
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.h
@@ -11,6 +11,7 @@
#include <vector>
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/cookies/cookie_monster.h"
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc
index b149ac08959..4be580b811e 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc
@@ -99,7 +99,6 @@ class SQLitePersistentCookieStorePerfTest : public testing::Test {
void TearDown() override {
store_ = NULL;
- pool_owner_->pool()->Shutdown();
}
protected:
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 fd140eabf12..2166be022a1 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -196,7 +196,6 @@ class SQLitePersistentCookieStoreTest : public testing::Test {
void TearDown() override {
DestroyStore();
- pool_owner_->pool()->Shutdown();
}
protected:
@@ -420,7 +419,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestFlush) {
base::FilePath path = temp_dir_.path().Append(kCookieFilename);
base::File::Info info;
ASSERT_TRUE(base::GetFileInfo(path, &info));
- int64 base_size = info.size;
+ int64_t base_size = info.size;
// Write some large cookies, so the DB will have to expand by several KB.
for (char c = 'a'; c < 'z'; ++c) {
diff --git a/chromium/net/filter/brotli_filter.cc b/chromium/net/filter/brotli_filter.cc
new file mode 100644
index 00000000000..7ce402ecb68
--- /dev/null
+++ b/chromium/net/filter/brotli_filter.cc
@@ -0,0 +1,190 @@
+// Copyright 2015 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/filter/brotli_filter.h"
+
+#include "base/bit_cast.h"
+#include "base/macros.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/numerics/safe_math.h"
+#include "third_party/brotli/dec/decode.h"
+
+namespace net {
+
+// BrotliFilter applies Brotli content decoding to a data stream.
+// Brotli format specification: http://www.ietf.org/id/draft-alakuijala-brotli
+//
+// BrotliFilter is a subclass of Filter. See the latter's header file filter.h
+// for sample usage.
+class BrotliFilter : public Filter {
+ public:
+ BrotliFilter(FilterType type)
+ : Filter(type),
+ decoding_status_(DecodingStatus::DECODING_IN_PROGRESS),
+ used_memory_(0),
+ used_memory_maximum_(0),
+ consumed_bytes_(0),
+ produced_bytes_(0) {
+ brotli_state_ = BrotliCreateState(BrotliFilter::AllocateMemory,
+ BrotliFilter::FreeMemory, this);
+ CHECK(brotli_state_);
+ }
+
+ ~BrotliFilter() override {
+ BrotliDestroyState(brotli_state_);
+ brotli_state_ = nullptr;
+ DCHECK(used_memory_ == 0);
+
+ UMA_HISTOGRAM_ENUMERATION(
+ "BrotliFilter.Status", static_cast<int>(decoding_status_),
+ static_cast<int>(DecodingStatus::DECODING_STATUS_COUNT));
+ if (decoding_status_ == DecodingStatus::DECODING_DONE) {
+ // CompressionPercent is undefined when there is no output produced.
+ if (produced_bytes_ != 0) {
+ UMA_HISTOGRAM_PERCENTAGE(
+ "BrotliFilter.CompressionPercent",
+ static_cast<int>((consumed_bytes_ * 100) / produced_bytes_));
+ }
+ }
+
+ // All code here is for gathering stats, and can be removed when
+ // BrotliFilter is considered stable.
+ static const int kBuckets = 48;
+ static const int64_t kMaxKb = 1 << (kBuckets / 3); // 64MiB in KiB
+ UMA_HISTOGRAM_CUSTOM_COUNTS("BrotliFilter.UsedMemoryKB",
+ used_memory_maximum_ / 1024, 1, kMaxKb,
+ kBuckets);
+ }
+
+ // Decodes the pre-filter data and writes the output into the |dest_buffer|
+ // passed in.
+ // The function returns FilterStatus. See filter.h for its description.
+ //
+ // Upon entry, |*dest_len| is the total size (in number of chars) of the
+ // destination buffer. Upon exit, |*dest_len| is the actual number of chars
+ // written into the destination buffer.
+ //
+ // This function will fail if there is no pre-filter data in the
+ // |stream_buffer_|. On the other hand, |*dest_len| can be 0 upon successful
+ // return. For example, decompressor may process some pre-filter data
+ // but not produce output yet.
+ FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override {
+ if (!dest_buffer || !dest_len)
+ return Filter::FILTER_ERROR;
+
+ if (decoding_status_ == DecodingStatus::DECODING_DONE) {
+ *dest_len = 0;
+ return Filter::FILTER_DONE;
+ }
+
+ if (decoding_status_ != DecodingStatus::DECODING_IN_PROGRESS)
+ return Filter::FILTER_ERROR;
+
+ size_t output_buffer_size = base::checked_cast<size_t>(*dest_len);
+ size_t input_buffer_size = base::checked_cast<size_t>(stream_data_len_);
+
+ size_t available_in = input_buffer_size;
+ const uint8_t* next_in = bit_cast<uint8_t*>(next_stream_data_);
+ size_t available_out = output_buffer_size;
+ uint8_t* next_out = bit_cast<uint8_t*>(dest_buffer);
+ size_t total_out = 0;
+ BrotliResult result =
+ BrotliDecompressStream(&available_in, &next_in, &available_out,
+ &next_out, &total_out, brotli_state_);
+
+ CHECK(available_in <= input_buffer_size);
+ CHECK(available_out <= output_buffer_size);
+ consumed_bytes_ += input_buffer_size - available_in;
+ produced_bytes_ += output_buffer_size - available_out;
+
+ base::CheckedNumeric<size_t> safe_bytes_written(output_buffer_size);
+ safe_bytes_written -= available_out;
+ int bytes_written =
+ base::checked_cast<int>(safe_bytes_written.ValueOrDie());
+
+ switch (result) {
+ case BROTLI_RESULT_NEEDS_MORE_OUTPUT:
+ // Fall through.
+ case BROTLI_RESULT_SUCCESS:
+ *dest_len = bytes_written;
+ stream_data_len_ = base::checked_cast<int>(available_in);
+ next_stream_data_ = bit_cast<char*>(next_in);
+ if (result == BROTLI_RESULT_SUCCESS) {
+ decoding_status_ = DecodingStatus::DECODING_DONE;
+ return Filter::FILTER_DONE;
+ }
+ return Filter::FILTER_OK;
+
+ case BROTLI_RESULT_NEEDS_MORE_INPUT:
+ *dest_len = bytes_written;
+ stream_data_len_ = 0;
+ next_stream_data_ = nullptr;
+ return Filter::FILTER_NEED_MORE_DATA;
+
+ default:
+ decoding_status_ = DecodingStatus::DECODING_ERROR;
+ return Filter::FILTER_ERROR;
+ }
+ }
+
+ private:
+ static void* AllocateMemory(void* opaque, size_t size) {
+ BrotliFilter* filter = reinterpret_cast<BrotliFilter*>(opaque);
+ return filter->AllocateMemoryInternal(size);
+ }
+
+ static void FreeMemory(void* opaque, void* address) {
+ BrotliFilter* filter = reinterpret_cast<BrotliFilter*>(opaque);
+ filter->FreeMemoryInternal(address);
+ }
+
+ void* AllocateMemoryInternal(size_t size) {
+ size_t* array = reinterpret_cast<size_t*>(malloc(size + sizeof(size_t)));
+ if (!array)
+ return nullptr;
+ used_memory_ += size;
+ if (used_memory_maximum_ < used_memory_)
+ used_memory_maximum_ = used_memory_;
+ array[0] = size;
+ return &array[1];
+ }
+
+ void FreeMemoryInternal(void* address) {
+ if (!address)
+ return;
+ size_t* array = reinterpret_cast<size_t*>(address);
+ used_memory_ -= array[-1];
+ free(&array[-1]);
+ }
+
+ // Reported in UMA and must be kept in sync with the histograms.xml file.
+ enum class DecodingStatus : int {
+ DECODING_IN_PROGRESS = 0,
+ DECODING_DONE,
+ DECODING_ERROR,
+
+ DECODING_STATUS_COUNT
+ // DECODING_STATUS_COUNT must always be the last element in this enum.
+ };
+
+ // Tracks the status of decoding.
+ // This variable is updated only by ReadFilteredData.
+ DecodingStatus decoding_status_;
+
+ BrotliState* brotli_state_;
+
+ size_t used_memory_;
+ size_t used_memory_maximum_;
+ size_t consumed_bytes_;
+ size_t produced_bytes_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrotliFilter);
+};
+
+Filter* CreateBrotliFilter(Filter::FilterType type_id) {
+ return new BrotliFilter(type_id);
+}
+
+} // namespace net
diff --git a/chromium/net/filter/brotli_filter.h b/chromium/net/filter/brotli_filter.h
new file mode 100644
index 00000000000..5570ae4320e
--- /dev/null
+++ b/chromium/net/filter/brotli_filter.h
@@ -0,0 +1,17 @@
+// Copyright 2015 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_FILTER_BROTLI_FILTER_H_
+#define NET_FILTER_BROTLI_FILTER_H_
+
+#include "net/filter/filter.h"
+
+namespace net {
+
+// Creates instance of filter or returns nullptr if brotli is not supported.
+Filter* CreateBrotliFilter(Filter::FilterType type_id);
+
+} // namespace net
+
+#endif // NET_FILTER_BROTLI_FILTER_H__
diff --git a/chromium/net/filter/brotli_filter_disabled.cc b/chromium/net/filter/brotli_filter_disabled.cc
new file mode 100644
index 00000000000..1081ff46481
--- /dev/null
+++ b/chromium/net/filter/brotli_filter_disabled.cc
@@ -0,0 +1,13 @@
+// Copyright 2015 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/filter/brotli_filter.h"
+
+namespace net {
+
+Filter* CreateBrotliFilter(Filter::FilterType type_id) {
+ return nullptr;
+}
+
+} // namespace net
diff --git a/chromium/net/filter/brotli_filter_unittest.cc b/chromium/net/filter/brotli_filter_unittest.cc
new file mode 100644
index 00000000000..38cfc82d954
--- /dev/null
+++ b/chromium/net/filter/brotli_filter_unittest.cc
@@ -0,0 +1,269 @@
+// Copyright 2015 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 "base/files/file_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
+#include "net/base/io_buffer.h"
+#include "net/filter/brotli_filter.h"
+#include "net/filter/mock_filter_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace {
+const int kDefaultBufferSize = 4096;
+const int kSmallBufferSize = 128;
+} // namespace
+
+namespace net {
+
+// These tests use the path service, which uses autoreleased objects on the
+// Mac, so this needs to be a PlatformTest.
+class BrotliUnitTest : public PlatformTest {
+ protected:
+ void SetUp() override {
+ PlatformTest::SetUp();
+
+ // Get the path of data directory.
+ base::FilePath data_dir;
+ PathService::Get(base::DIR_SOURCE_ROOT, &data_dir);
+ data_dir = data_dir.AppendASCII("net");
+ data_dir = data_dir.AppendASCII("data");
+ data_dir = data_dir.AppendASCII("filter_unittests");
+
+ // Read data from the original file into buffer.
+ base::FilePath file_path;
+ file_path = data_dir.AppendASCII("google.txt");
+ ASSERT_TRUE(base::ReadFileToString(file_path, &source_buffer_));
+
+ // Read data from the encoded file into buffer.
+ base::FilePath encoded_file_path;
+ encoded_file_path = data_dir.AppendASCII("google.br");
+ ASSERT_TRUE(base::ReadFileToString(encoded_file_path, &encoded_buffer_));
+ ASSERT_GE(kDefaultBufferSize, static_cast<int>(encoded_buffer_.size()));
+ }
+
+ // Use filter to decode compressed data, and compare the decoded result with
+ // the orginal data.
+ // Parameters: |source| and |source_len| are original data and its size.
+ // |encoded_source| and |encoded_source_len| are compressed data and its size.
+ // |output_buffer_size| specifies the size of buffer to read out data from
+ // filter.
+ void DecodeAndCompareWithFilter(Filter* filter,
+ const char* source,
+ int source_len,
+ const char* encoded_source,
+ int encoded_source_len,
+ int output_buffer_size) {
+ // Make sure we have enough space to hold the decoding output.
+ ASSERT_GE(kDefaultBufferSize, source_len);
+ ASSERT_GE(kDefaultBufferSize, output_buffer_size);
+
+ char decode_buffer[kDefaultBufferSize];
+ char* decode_next = decode_buffer;
+ int decode_avail_size = kDefaultBufferSize;
+
+ const char* encode_next = encoded_source;
+ int encode_avail_size = encoded_source_len;
+
+ int code = Filter::FILTER_OK;
+ while (code != Filter::FILTER_DONE) {
+ int encode_data_len =
+ std::min(encode_avail_size, filter->stream_buffer_size());
+ memcpy(filter->stream_buffer()->data(), encode_next, encode_data_len);
+ filter->FlushStreamBuffer(encode_data_len);
+ encode_next += encode_data_len;
+ encode_avail_size -= encode_data_len;
+
+ while (true) {
+ int decode_data_len = std::min(decode_avail_size, output_buffer_size);
+
+ code = filter->ReadData(decode_next, &decode_data_len);
+ decode_next += decode_data_len;
+ decode_avail_size -= decode_data_len;
+
+ ASSERT_NE(Filter::FILTER_ERROR, code);
+
+ if (code == Filter::FILTER_NEED_MORE_DATA ||
+ code == Filter::FILTER_DONE) {
+ break;
+ }
+ }
+ }
+
+ // Compare the decoding result with source data
+ int decode_total_data_len = kDefaultBufferSize - decode_avail_size;
+ EXPECT_EQ(source_len, decode_total_data_len);
+ EXPECT_EQ(memcmp(source, decode_buffer, source_len), 0);
+ }
+
+ // Unsafe function to use filter to decode compressed data.
+ // Parameters: |source| and |source_len| are compressed data and its size.
+ // |dest| is the buffer for decoding results. Upon entry, |*dest_len| is the
+ // size of the output buffer. Upon exit, |*dest_len| is the number of chars
+ // written into the buffer.
+ int DecodeAllWithFilter(Filter* filter,
+ const char* source,
+ int source_len,
+ char* dest,
+ int* dest_len) {
+ memcpy(filter->stream_buffer()->data(), source, source_len);
+ filter->FlushStreamBuffer(source_len);
+ return filter->ReadData(dest, dest_len);
+ }
+
+ void InitFilter() {
+ std::vector<Filter::FilterType> filter_types;
+ filter_types.push_back(Filter::FILTER_TYPE_BROTLI);
+ filter_.reset(Filter::Factory(filter_types, filter_context_));
+ ASSERT_TRUE(filter_.get());
+ ASSERT_LE(kDefaultBufferSize, filter_->stream_buffer_size());
+ }
+
+ void InitFilterWithBufferSize(int buffer_size) {
+ std::vector<Filter::FilterType> filter_types;
+ filter_types.push_back(Filter::FILTER_TYPE_BROTLI);
+ filter_.reset(
+ Filter::FactoryForTests(filter_types, filter_context_, buffer_size));
+ ASSERT_TRUE(filter_.get());
+ }
+
+ const char* source_buffer() const { return source_buffer_.data(); }
+ int source_len() const { return static_cast<int>(source_buffer_.size()); }
+
+ const char* encoded_buffer() const { return encoded_buffer_.data(); }
+ int encoded_len() const { return static_cast<int>(encoded_buffer_.size()); }
+
+ scoped_ptr<Filter> filter_;
+
+ private:
+ MockFilterContext filter_context_;
+ std::string source_buffer_;
+ std::string encoded_buffer_;
+};
+
+// Basic scenario: decoding brotli data with big enough buffer.
+TEST_F(BrotliUnitTest, DecodeBrotli) {
+ InitFilter();
+ memcpy(filter_->stream_buffer()->data(), encoded_buffer(), encoded_len());
+ filter_->FlushStreamBuffer(encoded_len());
+
+ ASSERT_GE(kDefaultBufferSize, source_len());
+ char decode_buffer[kDefaultBufferSize];
+ int decode_size = kDefaultBufferSize;
+ filter_->ReadData(decode_buffer, &decode_size);
+
+ // Compare the decoding result with source data
+ EXPECT_EQ(source_len(), decode_size);
+ EXPECT_EQ(memcmp(source_buffer(), decode_buffer, source_len()), 0);
+}
+
+// Tests we can call filter repeatedly to get all the data decoded.
+// To do that, we create a filter with a small buffer that can not hold all
+// the input data.
+TEST_F(BrotliUnitTest, DecodeWithSmallBuffer) {
+ InitFilterWithBufferSize(kSmallBufferSize);
+ EXPECT_EQ(kSmallBufferSize, filter_->stream_buffer_size());
+ DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
+ encoded_buffer(), encoded_len(),
+ kDefaultBufferSize);
+}
+
+// Tests we can still decode with just 1 byte buffer in the filter.
+// The purpose of this test: sometimes the filter will consume input without
+// generating output. Verify filter can handle it correctly.
+TEST_F(BrotliUnitTest, DecodeWithOneByteBuffer) {
+ InitFilterWithBufferSize(1);
+ EXPECT_EQ(1, filter_->stream_buffer_size());
+ DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
+ encoded_buffer(), encoded_len(),
+ kDefaultBufferSize);
+}
+
+// Tests we can decode when caller has small buffer to read out from filter.
+TEST_F(BrotliUnitTest, DecodeWithSmallOutputBuffer) {
+ InitFilter();
+ DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
+ encoded_buffer(), encoded_len(), kSmallBufferSize);
+}
+
+// Tests we can decode when caller has small buffer and input is also broken
+// into small parts. This may uncover some corner cases that doesn't happen with
+// one-byte buffers.
+TEST_F(BrotliUnitTest, DecodeWithSmallInputAndOutputBuffer) {
+ InitFilterWithBufferSize(kSmallBufferSize);
+ DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
+ encoded_buffer(), encoded_len(), kSmallBufferSize);
+}
+
+// Tests we can still decode with just 1 byte buffer in the filter and just 1
+// byte buffer in the caller.
+TEST_F(BrotliUnitTest, DecodeWithOneByteInputAndOutputBuffer) {
+ InitFilterWithBufferSize(1);
+ EXPECT_EQ(1, filter_->stream_buffer_size());
+ DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
+ encoded_buffer(), encoded_len(), 1);
+}
+
+// Decoding deflate stream with corrupted data.
+TEST_F(BrotliUnitTest, DecodeCorruptedData) {
+ char corrupt_data[kDefaultBufferSize];
+ int corrupt_data_len = encoded_len();
+ memcpy(corrupt_data, encoded_buffer(), encoded_len());
+
+ int pos = corrupt_data_len / 2;
+ corrupt_data[pos] = !corrupt_data[pos];
+
+ // Decode the corrupted data with filter
+ InitFilter();
+ char corrupt_decode_buffer[kDefaultBufferSize];
+ int corrupt_decode_size = kDefaultBufferSize;
+
+ int code = DecodeAllWithFilter(filter_.get(), corrupt_data, corrupt_data_len,
+ corrupt_decode_buffer, &corrupt_decode_size);
+
+ // Expect failures
+ EXPECT_EQ(Filter::FILTER_ERROR, code);
+}
+
+// Decoding deflate stream with missing data.
+TEST_F(BrotliUnitTest, DecodeMissingData) {
+ char corrupt_data[kDefaultBufferSize];
+ int corrupt_data_len = encoded_len();
+ memcpy(corrupt_data, encoded_buffer(), encoded_len());
+
+ int pos = corrupt_data_len / 2;
+ int len = corrupt_data_len - pos - 1;
+ memmove(&corrupt_data[pos], &corrupt_data[pos + 1], len);
+ --corrupt_data_len;
+
+ // Decode the corrupted data with filter
+ InitFilter();
+ char corrupt_decode_buffer[kDefaultBufferSize];
+ int corrupt_decode_size = kDefaultBufferSize;
+
+ int code = DecodeAllWithFilter(filter_.get(), corrupt_data, corrupt_data_len,
+ corrupt_decode_buffer, &corrupt_decode_size);
+
+ // Expect failures
+ EXPECT_EQ(Filter::FILTER_ERROR, code);
+}
+
+// Decoding brotli stream with empty output data.
+TEST_F(BrotliUnitTest, DecodeEmptyData) {
+ char data[1] = {6}; // WBITS = 16, ISLAST = 1, ISLASTEMPTY = 1
+ int data_len = 1;
+
+ InitFilter();
+ char decode_buffer[kDefaultBufferSize];
+ int decode_size = kDefaultBufferSize;
+ int code = DecodeAllWithFilter(filter_.get(), data, data_len, decode_buffer,
+ &decode_size);
+
+ // Expect success / empty output.
+ EXPECT_EQ(Filter::FILTER_DONE, code);
+ EXPECT_EQ(0, decode_size);
+}
+
+} // namespace net
diff --git a/chromium/net/filter/filter.cc b/chromium/net/filter/filter.cc
index f9c3712cf4a..466aa109fd7 100644
--- a/chromium/net/filter/filter.cc
+++ b/chromium/net/filter/filter.cc
@@ -28,6 +28,7 @@
#include "base/values.h"
#include "net/base/io_buffer.h"
#include "net/base/sdch_net_log_params.h"
+#include "net/filter/brotli_filter.h"
#include "net/filter/gzip_filter.h"
#include "net/filter/sdch_filter.h"
#include "net/url_request/url_request_context.h"
@@ -38,6 +39,7 @@ namespace net {
namespace {
// Filter types (using canonical lower case only):
+const char kBrotli[] = "br";
const char kDeflate[] = "deflate";
const char kGZip[] = "gzip";
const char kXGZip[] = "x-gzip";
@@ -62,6 +64,8 @@ void LogSdchProblem(const FilterContext& filter_context,
std::string FilterTypeAsString(Filter::FilterType type_id) {
switch (type_id) {
+ case Filter::FILTER_TYPE_BROTLI:
+ return "FILTER_TYPE_BROTLI";
case Filter::FILTER_TYPE_DEFLATE:
return "FILTER_TYPE_DEFLATE";
case Filter::FILTER_TYPE_GZIP:
@@ -184,7 +188,9 @@ bool Filter::FlushStreamBuffer(int stream_data_len) {
Filter::FilterType Filter::ConvertEncodingToType(
const std::string& filter_type) {
FilterType type_id;
- if (base::LowerCaseEqualsASCII(filter_type, kDeflate)) {
+ if (base::LowerCaseEqualsASCII(filter_type, kBrotli)) {
+ type_id = FILTER_TYPE_BROTLI;
+ } else if (base::LowerCaseEqualsASCII(filter_type, kDeflate)) {
type_id = FILTER_TYPE_DEFLATE;
} else if (base::LowerCaseEqualsASCII(filter_type, kGZip) ||
base::LowerCaseEqualsASCII(filter_type, kXGZip)) {
@@ -350,6 +356,16 @@ Filter::FilterStatus Filter::CopyOut(char* dest_buffer, int* dest_len) {
}
// static
+Filter* Filter::InitBrotliFilter(FilterType type_id, int buffer_size) {
+ scoped_ptr<Filter> brotli_filter(CreateBrotliFilter(type_id));
+ if (!brotli_filter.get())
+ return nullptr;
+
+ brotli_filter->InitBuffer(buffer_size);
+ return brotli_filter.release();
+}
+
+// static
Filter* Filter::InitGZipFilter(FilterType type_id, int buffer_size) {
scoped_ptr<GZipFilter> gz_filter(new GZipFilter(type_id));
gz_filter->InitBuffer(buffer_size);
@@ -372,6 +388,9 @@ Filter* Filter::PrependNewFilter(FilterType type_id,
Filter* filter_list) {
scoped_ptr<Filter> first_filter; // Soon to be start of chain.
switch (type_id) {
+ case FILTER_TYPE_BROTLI:
+ first_filter.reset(InitBrotliFilter(type_id, buffer_size));
+ break;
case FILTER_TYPE_GZIP_HELPING_SDCH:
case FILTER_TYPE_DEFLATE:
case FILTER_TYPE_GZIP:
diff --git a/chromium/net/filter/filter.h b/chromium/net/filter/filter.h
index 1904a8cdbb9..e9df3dbc9db 100644
--- a/chromium/net/filter/filter.h
+++ b/chromium/net/filter/filter.h
@@ -46,11 +46,13 @@
#ifndef NET_FILTER_FILTER_H__
#define NET_FILTER_FILTER_H__
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
@@ -113,7 +115,7 @@ class NET_EXPORT_PRIVATE FilterContext {
// How many bytes were read from the net or cache so far (and potentially
// pushed into a filter for processing)?
- virtual int64 GetByteReadCount() const = 0;
+ virtual int64_t GetByteReadCount() const = 0;
// What response code was received with the associated network transaction?
// For example: 200 is ok. 4xx are error codes. etc.
@@ -151,6 +153,7 @@ class NET_EXPORT_PRIVATE Filter {
// Specifies type of filters that can be created.
enum FilterType {
+ FILTER_TYPE_BROTLI,
FILTER_TYPE_DEFLATE,
FILTER_TYPE_GZIP,
FILTER_TYPE_GZIP_HELPING_SDCH, // Gzip possible, but pass through allowed.
@@ -231,6 +234,7 @@ class NET_EXPORT_PRIVATE Filter {
std::string OrderedFilterList() const;
protected:
+ friend class BrotliUnitTest;
friend class GZipUnitTest;
friend class SdchFilterChainingTest;
FRIEND_TEST_ALL_PREFIXES(FilterTest, ThreeFilterChain);
@@ -283,6 +287,7 @@ class NET_EXPORT_PRIVATE Filter {
// Helper methods for PrependNewFilter. If initialization is successful,
// they return a fully initialized Filter. Otherwise, return NULL.
+ static Filter* InitBrotliFilter(FilterType type_id, int buffer_size);
static Filter* InitGZipFilter(FilterType type_id, int buffer_size);
static Filter* InitSdchFilter(FilterType type_id,
const FilterContext& filter_context,
diff --git a/chromium/net/filter/filter_unittest.cc b/chromium/net/filter/filter_unittest.cc
index d0441fabb2c..d10fadc637b 100644
--- a/chromium/net/filter/filter_unittest.cc
+++ b/chromium/net/filter/filter_unittest.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/base/io_buffer.h"
#include "net/filter/filter.h"
+
+#include <utility>
+
+#include "base/macros.h"
+#include "net/base/io_buffer.h"
#include "net/filter/mock_filter_context.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -54,7 +58,7 @@ TEST(FilterTest, SdchEncoding) {
MockFilterContext filter_context;
// Empty handle indicates to filter that SDCH is active.
filter_context.SetSdchResponse(
- SdchManager::CreateEmptyDictionarySetForTesting().Pass());
+ SdchManager::CreateEmptyDictionarySetForTesting());
std::vector<Filter::FilterType> encoding_types;
@@ -92,7 +96,7 @@ TEST(FilterTest, MissingSdchEncoding) {
const std::string kTextHtmlMime("text/html");
MockFilterContext filter_context;
filter_context.SetSdchResponse(
- SdchManager::CreateEmptyDictionarySetForTesting().Pass());
+ SdchManager::CreateEmptyDictionarySetForTesting());
std::vector<Filter::FilterType> encoding_types;
@@ -153,8 +157,8 @@ TEST(FilterTest, ThreeFilterChain) {
filter2->InitBuffer(32 * 1024);
filter3->InitBuffer(32 * 1024);
- filter2->next_filter_ = filter3.Pass();
- filter1->next_filter_ = filter2.Pass();
+ filter2->next_filter_ = std::move(filter3);
+ filter1->next_filter_ = std::move(filter2);
// Initialize the input array with a varying byte sequence.
const size_t input_array_size = 64 * 1024;
diff --git a/chromium/net/filter/gzip_filter.cc b/chromium/net/filter/gzip_filter.cc
index 6d15ee98f1a..209e3c45d62 100644
--- a/chromium/net/filter/gzip_filter.cc
+++ b/chromium/net/filter/gzip_filter.cc
@@ -4,6 +4,7 @@
#include "net/filter/gzip_filter.h"
+#include "base/bit_cast.h"
#include "base/logging.h"
#include "net/filter/gzip_header.h"
#include "third_party/zlib/zlib.h"
diff --git a/chromium/net/filter/gzip_filter.h b/chromium/net/filter/gzip_filter.h
index 2306c9b05fc..67330d73473 100644
--- a/chromium/net/filter/gzip_filter.h
+++ b/chromium/net/filter/gzip_filter.h
@@ -15,7 +15,7 @@
#ifndef NET_FILTER_GZIP_FILTER_H_
#define NET_FILTER_GZIP_FILTER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/filter/filter.h"
diff --git a/chromium/net/filter/gzip_filter_unittest.cc b/chromium/net/filter/gzip_filter_unittest.cc
index 2f11e28a9fb..e25cc1c83f7 100644
--- a/chromium/net/filter/gzip_filter_unittest.cc
+++ b/chromium/net/filter/gzip_filter_unittest.cc
@@ -5,6 +5,7 @@
#include <fstream>
#include <ostream>
+#include "base/bit_cast.h"
#include "base/files/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
diff --git a/chromium/net/filter/gzip_header.cc b/chromium/net/filter/gzip_header.cc
index f4aca6b1518..36a1c866a90 100644
--- a/chromium/net/filter/gzip_header.cc
+++ b/chromium/net/filter/gzip_header.cc
@@ -11,7 +11,7 @@
namespace net {
-const uint8 GZipHeader::magic[] = { 0x1f, 0x8b };
+const uint8_t GZipHeader::magic[] = {0x1f, 0x8b};
GZipHeader::GZipHeader() {
Reset();
@@ -29,8 +29,8 @@ void GZipHeader::Reset() {
GZipHeader::Status GZipHeader::ReadMore(const char* inbuf, int inbuf_len,
const char** header_end) {
DCHECK_GE(inbuf_len, 0);
- const uint8* pos = reinterpret_cast<const uint8*>(inbuf);
- const uint8* const end = pos + inbuf_len;
+ const uint8_t* pos = reinterpret_cast<const uint8_t*>(inbuf);
+ const uint8_t* const end = pos + inbuf_len;
while ( pos < end ) {
switch ( state_ ) {
@@ -105,9 +105,8 @@ GZipHeader::Status GZipHeader::ReadMore(const char* inbuf, int inbuf_len,
case IN_FEXTRA: {
// Grab the rest of the bytes in the extra field, or as many
// of them as are actually present so far.
- const uint16 num_extra_bytes = static_cast<uint16>(std::min(
- static_cast<ptrdiff_t>(extra_length_),
- (end - pos)));
+ const uint16_t num_extra_bytes = static_cast<uint16_t>(
+ std::min(static_cast<ptrdiff_t>(extra_length_), (end - pos)));
pos += num_extra_bytes;
extra_length_ -= num_extra_bytes;
if ( extra_length_ == 0 ) {
@@ -123,7 +122,7 @@ GZipHeader::Status GZipHeader::ReadMore(const char* inbuf, int inbuf_len,
break;
}
// See if we can find the end of the \0-terminated FNAME field.
- pos = reinterpret_cast<const uint8*>(memchr(pos, '\0', (end - pos)));
+ pos = reinterpret_cast<const uint8_t*>(memchr(pos, '\0', (end - pos)));
if ( pos != NULL ) {
pos++; // advance past the '\0'
flags_ &= ~FLAG_FNAME; // we're done with the FNAME stuff
@@ -139,7 +138,7 @@ GZipHeader::Status GZipHeader::ReadMore(const char* inbuf, int inbuf_len,
break;
}
// See if we can find the end of the \0-terminated FCOMMENT field.
- pos = reinterpret_cast<const uint8*>(memchr(pos, '\0', (end - pos)));
+ pos = reinterpret_cast<const uint8_t*>(memchr(pos, '\0', (end - pos)));
if ( pos != NULL ) {
pos++; // advance past the '\0'
flags_ &= ~FLAG_FCOMMENT; // we're done with the FCOMMENT stuff
diff --git a/chromium/net/filter/gzip_header.h b/chromium/net/filter/gzip_header.h
index 986afc44a7b..91d695522ed 100644
--- a/chromium/net/filter/gzip_header.h
+++ b/chromium/net/filter/gzip_header.h
@@ -15,7 +15,9 @@
#ifndef NET_FILTER_GZIP_HEADER_H_
#define NET_FILTER_GZIP_HEADER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
namespace net {
@@ -80,11 +82,11 @@ class GZipHeader {
IN_DONE,
};
- static const uint8 magic[]; // gzip magic header
+ static const uint8_t magic[]; // gzip magic header
int state_; // our current State in the parsing FSM: an int so we can ++
- uint8 flags_; // the flags byte of the header ("FLG" in the RFC)
- uint16 extra_length_; // how much of the "extra field" we have yet to read
+ uint8_t flags_; // the flags byte of the header ("FLG" in the RFC)
+ uint16_t extra_length_; // how much of the "extra field" we have yet to read
DISALLOW_COPY_AND_ASSIGN(GZipHeader);
};
diff --git a/chromium/net/filter/mock_filter_context.cc b/chromium/net/filter/mock_filter_context.cc
index ebcaa186521..2165aa05136 100644
--- a/chromium/net/filter/mock_filter_context.cc
+++ b/chromium/net/filter/mock_filter_context.cc
@@ -48,7 +48,9 @@ MockFilterContext::SdchDictionariesAdvertised() const {
return dictionaries_handle_.get();
}
-int64 MockFilterContext::GetByteReadCount() const { return 0; }
+int64_t MockFilterContext::GetByteReadCount() const {
+ return 0;
+}
int MockFilterContext::GetResponseCode() const { return response_code_; }
diff --git a/chromium/net/filter/mock_filter_context.h b/chromium/net/filter/mock_filter_context.h
index 33d41a6e53e..50858c4df48 100644
--- a/chromium/net/filter/mock_filter_context.h
+++ b/chromium/net/filter/mock_filter_context.h
@@ -5,8 +5,11 @@
#ifndef NET_FILTER_MOCK_FILTER_CONTEXT_H_
#define NET_FILTER_MOCK_FILTER_CONTEXT_H_
+#include <stdint.h>
#include <string>
+#include <utility>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/sdch_manager.h"
#include "net/filter/filter.h"
@@ -28,7 +31,7 @@ class MockFilterContext : public FilterContext {
void SetCached(bool is_cached) { is_cached_content_ = is_cached; }
void SetResponseCode(int response_code) { response_code_ = response_code; }
void SetSdchResponse(scoped_ptr<SdchManager::DictionarySet> handle) {
- dictionaries_handle_ = handle.Pass();
+ dictionaries_handle_ = std::move(handle);
}
URLRequestContext* GetModifiableURLRequestContext() const {
return context_.get();
@@ -55,7 +58,7 @@ class MockFilterContext : public FilterContext {
SdchManager::DictionarySet* SdchDictionariesAdvertised() const override;
// How many bytes were fed to filter(s) so far?
- int64 GetByteReadCount() const override;
+ int64_t GetByteReadCount() const override;
int GetResponseCode() const override;
diff --git a/chromium/net/filter/sdch_filter.cc b/chromium/net/filter/sdch_filter.cc
index 31df38887e6..67b4b10e287 100644
--- a/chromium/net/filter/sdch_filter.cc
+++ b/chromium/net/filter/sdch_filter.cc
@@ -6,8 +6,8 @@
#include <ctype.h>
#include <limits.h>
-
#include <algorithm>
+#include <utility>
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
@@ -16,7 +16,6 @@
#include "net/base/sdch_net_log_params.h"
#include "net/base/sdch_problem_codes.h"
#include "net/url_request/url_request_context.h"
-
#include "sdch/open-vcdiff/src/google/vcdecoder.h"
namespace net {
@@ -97,7 +96,7 @@ scoped_ptr<base::Value> NetLogSdchResponseCorruptionDetectionCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("cause", ResponseCorruptionDetectionCauseToString(cause));
dict->SetBoolean("cached", cached);
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
diff --git a/chromium/net/filter/sdch_filter.h b/chromium/net/filter/sdch_filter.h
index 43125e8e3cc..83e29c525e0 100644
--- a/chromium/net/filter/sdch_filter.h
+++ b/chromium/net/filter/sdch_filter.h
@@ -14,8 +14,11 @@
#ifndef NET_FILTER_SDCH_FILTER_H_
#define NET_FILTER_SDCH_FILTER_H_
+#include <stddef.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/base/sdch_dictionary.h"
diff --git a/chromium/net/filter/sdch_filter_unittest.cc b/chromium/net/filter/sdch_filter_unittest.cc
index 35276cb764a..701aba00660 100644
--- a/chromium/net/filter/sdch_filter_unittest.cc
+++ b/chromium/net/filter/sdch_filter_unittest.cc
@@ -8,7 +8,9 @@
#include <string>
#include <vector>
+#include "base/bit_cast.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/test/histogram_tester.h"
#include "base/test/simple_test_clock.h"
@@ -81,8 +83,7 @@ class SdchFilterTest : public testing::Test {
// Sets both the GURL and the SDCH response for a filter context.
void SetupFilterContextWithGURL(GURL url) {
filter_context_->SetURL(url);
- filter_context_->SetSdchResponse(
- sdch_manager_->GetDictionarySet(url).Pass());
+ filter_context_->SetSdchResponse(sdch_manager_->GetDictionarySet(url));
}
std::string NewSdchCompressedData(const std::string& dictionary) {
@@ -1213,8 +1214,7 @@ TEST_F(SdchFilterTest, UnexpectedDictionary) {
SdchProblemCode problem_code;
scoped_ptr<SdchManager::DictionarySet> hash_set(
- sdch_manager_->GetDictionarySetByHash(
- url, server_hash, &problem_code).Pass());
+ sdch_manager_->GetDictionarySetByHash(url, server_hash, &problem_code));
ASSERT_TRUE(hash_set);
ASSERT_EQ(SDCH_OK, problem_code);
diff --git a/chromium/net/ftp/ftp_auth_cache.h b/chromium/net/ftp/ftp_auth_cache.h
index 526b3588782..e7f3057e153 100644
--- a/chromium/net/ftp/ftp_auth_cache.h
+++ b/chromium/net/ftp/ftp_auth_cache.h
@@ -5,6 +5,8 @@
#ifndef NET_FTP_FTP_AUTH_CACHE_H_
#define NET_FTP_FTP_AUTH_CACHE_H_
+#include <stddef.h>
+
#include <list>
#include "net/base/auth.h"
diff --git a/chromium/net/ftp/ftp_ctrl_response_buffer.cc b/chromium/net/ftp/ftp_ctrl_response_buffer.cc
index b3f2d2399a1..064068e965e 100644
--- a/chromium/net/ftp/ftp_ctrl_response_buffer.cc
+++ b/chromium/net/ftp/ftp_ctrl_response_buffer.cc
@@ -4,6 +4,8 @@
#include "net/ftp/ftp_ctrl_response_buffer.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
@@ -87,8 +89,8 @@ scoped_ptr<base::Value> NetLogFtpCtrlResponseCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("status_code", response->status_code);
- dict->Set("lines", lines.Pass());
- return dict.Pass();
+ dict->Set("lines", std::move(lines));
+ return std::move(dict);
}
} // namespace
diff --git a/chromium/net/ftp/ftp_ctrl_response_buffer.h b/chromium/net/ftp/ftp_ctrl_response_buffer.h
index 92aaf533c1f..ae90fea5fcb 100644
--- a/chromium/net/ftp/ftp_ctrl_response_buffer.h
+++ b/chromium/net/ftp/ftp_ctrl_response_buffer.h
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-
#ifndef NET_FTP_FTP_CTRL_RESPONSE_BUFFER_H_
#define NET_FTP_FTP_CTRL_RESPONSE_BUFFER_H_
@@ -10,7 +9,7 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/log/net_log.h"
diff --git a/chromium/net/ftp/ftp_directory_listing_parser.h b/chromium/net/ftp/ftp_directory_listing_parser.h
index d2dd677bb09..bcf9a7c01fd 100644
--- a/chromium/net/ftp/ftp_directory_listing_parser.h
+++ b/chromium/net/ftp/ftp_directory_listing_parser.h
@@ -5,10 +5,11 @@
#ifndef NET_FTP_FTP_DIRECTORY_LISTING_PARSER_H_
#define NET_FTP_FTP_DIRECTORY_LISTING_PARSER_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
@@ -28,7 +29,7 @@ struct FtpDirectoryListingEntry {
Type type;
base::string16 name; // Name (UTF-16-encoded).
std::string raw_name; // Name in original character encoding.
- int64 size; // File size, in bytes. -1 if not applicable.
+ int64_t size; // File size, in bytes. -1 if not applicable.
// Last modified time, in local time zone.
base::Time last_modified;
diff --git a/chromium/net/ftp/ftp_directory_listing_parser_ls.cc b/chromium/net/ftp/ftp_directory_listing_parser_ls.cc
index 96d0dc84607..9d1b7116758 100644
--- a/chromium/net/ftp/ftp_directory_listing_parser_ls.cc
+++ b/chromium/net/ftp/ftp_directory_listing_parser_ls.cc
@@ -142,11 +142,12 @@ bool ParseFtpDirectoryListingLs(
if (columns.size() == 2 && !received_total_line) {
received_total_line = true;
- int64 total_number;
+ // Some FTP servers incorrectly return a negative integer for "n". Since
+ // this value is ignored anyway, just check any valid integer was
+ // provided.
+ int64_t total_number;
if (!base::StringToInt64(columns[1], &total_number))
return false;
- if (total_number < 0)
- return false;
continue;
}
diff --git a/chromium/net/ftp/ftp_directory_listing_parser_unittest.cc b/chromium/net/ftp/ftp_directory_listing_parser_unittest.cc
index b21c8da392a..5c98c23f630 100644
--- a/chromium/net/ftp/ftp_directory_listing_parser_unittest.cc
+++ b/chromium/net/ftp/ftp_directory_listing_parser_unittest.cc
@@ -81,7 +81,7 @@ TEST_P(FtpDirectoryListingParserTest, Parse) {
for (size_t i = 0; i < lines.size() / 9; i++) {
std::string type(lines[9 * i]);
std::string name(lines[9 * i + 1]);
- int64 size;
+ int64_t size;
base::StringToInt64(lines[9 * i + 2], &size);
SCOPED_TRACE(base::StringPrintf("Filename: %s", name.c_str()));
@@ -156,6 +156,7 @@ const FtpTestParam kTestParams[] = {
{"dir-listing-ls-30", OK},
{"dir-listing-ls-31", OK},
{"dir-listing-ls-32", OK}, // busybox
+ {"dir-listing-ls-33", OK},
{"dir-listing-netware-1", OK},
{"dir-listing-netware-2", OK},
diff --git a/chromium/net/ftp/ftp_directory_listing_parser_unittest.h b/chromium/net/ftp/ftp_directory_listing_parser_unittest.h
index 22c2cf90740..3cbe17ad2d6 100644
--- a/chromium/net/ftp/ftp_directory_listing_parser_unittest.h
+++ b/chromium/net/ftp/ftp_directory_listing_parser_unittest.h
@@ -5,6 +5,8 @@
#ifndef NET_FTP_FTP_DIRECTORY_LISTING_PARSER_UNITTEST_H_
#define NET_FTP_FTP_DIRECTORY_LISTING_PARSER_UNITTEST_H_
+#include <stdint.h>
+
#include <vector>
#include "base/strings/utf_string_conversions.h"
@@ -19,7 +21,7 @@ class FtpDirectoryListingParserTest : public testing::Test {
const char* input;
FtpDirectoryListingEntry::Type type;
const char* filename;
- int64 size;
+ int64_t size;
int year;
int month;
int day_of_month;
diff --git a/chromium/net/ftp/ftp_directory_listing_parser_vms.cc b/chromium/net/ftp/ftp_directory_listing_parser_vms.cc
index eb92a1903d3..e05f2c73a93 100644
--- a/chromium/net/ftp/ftp_directory_listing_parser_vms.cc
+++ b/chromium/net/ftp/ftp_directory_listing_parser_vms.cc
@@ -55,7 +55,7 @@ bool ParseVmsFilename(const base::string16& raw_filename,
return true;
}
-bool ParseVmsFilesize(const base::string16& input, int64* size) {
+bool ParseVmsFilesize(const base::string16& input, int64_t* size) {
if (base::ContainsOnlyChars(input, base::ASCIIToUTF16("*"))) {
// Response consisting of asterisks means unknown size.
*size = -1;
@@ -80,7 +80,7 @@ bool ParseVmsFilesize(const base::string16& input, int64* size) {
if (parts.size() != 2)
return false;
- int64 blocks_used, blocks_allocated;
+ int64_t blocks_used, blocks_allocated;
if (!base::StringToInt64(parts[0], &blocks_used))
return false;
if (!base::StringToInt64(parts[1], &blocks_allocated))
@@ -262,6 +262,9 @@ bool ParseFtpDirectoryListingVms(
space, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
}
+ if (columns.empty())
+ return false;
+
FtpDirectoryListingEntry entry;
if (!ParseVmsFilename(columns[0], &entry.name, &entry.type))
return false;
diff --git a/chromium/net/ftp/ftp_directory_listing_parser_vms_unittest.cc b/chromium/net/ftp/ftp_directory_listing_parser_vms_unittest.cc
index 08ee9e19128..f566481b548 100644
--- a/chromium/net/ftp/ftp_directory_listing_parser_vms_unittest.cc
+++ b/chromium/net/ftp/ftp_directory_listing_parser_vms_unittest.cc
@@ -165,6 +165,31 @@ TEST_F(FtpDirectoryListingParserVmsTest, BadDataAfterFooter) {
}
}
+TEST_F(FtpDirectoryListingParserVmsTest, EmptyColumnZero) {
+ std::vector<base::string16> lines;
+
+ // The parser requires a directory header before accepting regular input.
+ lines.push_back(ASCIIToUTF16("garbage"));
+
+ base::char16 data[] = {0x0};
+ lines.push_back(base::string16(data, 1));
+
+ std::vector<FtpDirectoryListingEntry> entries;
+ EXPECT_FALSE(ParseFtpDirectoryListingVms(lines, &entries));
+}
+
+TEST_F(FtpDirectoryListingParserVmsTest, EmptyColumnWhitespace) {
+ std::vector<base::string16> lines;
+
+ // The parser requires a directory header before accepting regular input.
+ lines.push_back(ASCIIToUTF16("garbage"));
+
+ lines.push_back(ASCIIToUTF16(" "));
+
+ std::vector<FtpDirectoryListingEntry> entries;
+ EXPECT_FALSE(ParseFtpDirectoryListingVms(lines, &entries));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/ftp/ftp_network_layer.cc b/chromium/net/ftp/ftp_network_layer.cc
index e8053dee3ae..c8658d0a5b0 100644
--- a/chromium/net/ftp/ftp_network_layer.cc
+++ b/chromium/net/ftp/ftp_network_layer.cc
@@ -18,12 +18,12 @@ FtpNetworkLayer::FtpNetworkLayer(HostResolver* host_resolver)
FtpNetworkLayer::~FtpNetworkLayer() {
}
-FtpTransaction* FtpNetworkLayer::CreateTransaction() {
+scoped_ptr<FtpTransaction> FtpNetworkLayer::CreateTransaction() {
if (suspended_)
- return NULL;
+ return scoped_ptr<FtpTransaction>();
- return new FtpNetworkTransaction(session_->host_resolver(),
- ClientSocketFactory::GetDefaultFactory());
+ return make_scoped_ptr(new FtpNetworkTransaction(
+ session_->host_resolver(), ClientSocketFactory::GetDefaultFactory()));
}
void FtpNetworkLayer::Suspend(bool suspend) {
diff --git a/chromium/net/ftp/ftp_network_layer.h b/chromium/net/ftp/ftp_network_layer.h
index e22ec49e865..877f8c01ee7 100644
--- a/chromium/net/ftp/ftp_network_layer.h
+++ b/chromium/net/ftp/ftp_network_layer.h
@@ -5,8 +5,8 @@
#ifndef NET_FTP_FTP_NETWORK_LAYER_H_
#define NET_FTP_FTP_NETWORK_LAYER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/ftp/ftp_transaction_factory.h"
@@ -22,7 +22,7 @@ class NET_EXPORT FtpNetworkLayer : public FtpTransactionFactory {
~FtpNetworkLayer() override;
// FtpTransactionFactory methods:
- FtpTransaction* CreateTransaction() override;
+ scoped_ptr<FtpTransaction> CreateTransaction() override;
void Suspend(bool suspend) override;
private:
diff --git a/chromium/net/ftp/ftp_network_transaction.cc b/chromium/net/ftp/ftp_network_transaction.cc
index 806f01459e7..9c2c136f633 100644
--- a/chromium/net/ftp/ftp_network_transaction.cc
+++ b/chromium/net/ftp/ftp_network_transaction.cc
@@ -17,8 +17,8 @@
#include "net/base/connection_type_histograms.h"
#include "net/base/escape.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "net/base/port_util.h"
+#include "net/base/url_util.h"
#include "net/ftp/ftp_request_info.h"
#include "net/ftp/ftp_util.h"
#include "net/log/net_log.h"
@@ -319,7 +319,7 @@ LoadState FtpNetworkTransaction::GetLoadState() const {
return LOAD_STATE_IDLE;
}
-uint64 FtpNetworkTransaction::GetUploadProgress() const {
+uint64_t FtpNetworkTransaction::GetUploadProgress() const {
return 0;
}
@@ -961,7 +961,7 @@ int FtpNetworkTransaction::ProcessResponseEPSV(
!IsPortAllowedForScheme(port, url::kFtpScheme)) {
return Stop(ERR_UNSAFE_PORT);
}
- data_connection_port_ = static_cast<uint16>(port);
+ data_connection_port_ = static_cast<uint16_t>(port);
next_state_ = STATE_DATA_CONNECT;
break;
}
@@ -999,7 +999,7 @@ int FtpNetworkTransaction::ProcessResponsePASV(
!IsPortAllowedForScheme(port, url::kFtpScheme)) {
return Stop(ERR_UNSAFE_PORT);
}
- data_connection_port_ = static_cast<uint16>(port);
+ data_connection_port_ = static_cast<uint16_t>(port);
next_state_ = STATE_DATA_CONNECT;
break;
}
@@ -1068,7 +1068,7 @@ int FtpNetworkTransaction::ProcessResponseSIZE(
case ERROR_CLASS_OK:
if (response.lines.size() != 1)
return Stop(ERR_INVALID_RESPONSE);
- int64 size;
+ int64_t size;
if (!base::StringToInt64(response.lines[0], &size))
return Stop(ERR_INVALID_RESPONSE);
if (size < 0)
diff --git a/chromium/net/ftp/ftp_network_transaction.h b/chromium/net/ftp/ftp_network_transaction.h
index 390a6c124b3..ec0c1f8de2b 100644
--- a/chromium/net/ftp/ftp_network_transaction.h
+++ b/chromium/net/ftp/ftp_network_transaction.h
@@ -5,10 +5,11 @@
#ifndef NET_FTP_FTP_NETWORK_TRANSACTION_H_
#define NET_FTP_FTP_NETWORK_TRANSACTION_H_
+#include <stdint.h>
+
#include <string>
#include <utility>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
@@ -46,7 +47,7 @@ class NET_EXPORT_PRIVATE FtpNetworkTransaction : public FtpTransaction {
const CompletionCallback& callback) override;
const FtpResponseInfo* GetResponseInfo() const override;
LoadState GetLoadState() const override;
- uint64 GetUploadProgress() const override;
+ uint64_t GetUploadProgress() const override;
private:
FRIEND_TEST_ALL_PREFIXES(FtpNetworkTransactionTest,
@@ -244,7 +245,7 @@ class NET_EXPORT_PRIVATE FtpNetworkTransaction : public FtpTransaction {
// with any trailing slash removed.
std::string current_remote_directory_;
- uint16 data_connection_port_;
+ uint16_t data_connection_port_;
ClientSocketFactory* socket_factory_;
diff --git a/chromium/net/ftp/ftp_network_transaction_unittest.cc b/chromium/net/ftp/ftp_network_transaction_unittest.cc
index 0d364a1160e..ec1dc200c21 100644
--- a/chromium/net/ftp/ftp_network_transaction_unittest.cc
+++ b/chromium/net/ftp/ftp_network_transaction_unittest.cc
@@ -7,6 +7,7 @@
#include "build/build_config.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -1386,7 +1387,7 @@ TEST_P(FtpNetworkTransactionTest, Escaping) {
// Test for http://crbug.com/23794.
TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilSize) {
- // Try to overflow int64 in the response.
+ // Try to overflow int64_t in the response.
FtpSocketDataProviderEvilSize ctrl_socket(
"213 99999999999999999999999999999999\r\n",
FtpSocketDataProvider::PRE_QUIT);
diff --git a/chromium/net/ftp/ftp_response_info.h b/chromium/net/ftp/ftp_response_info.h
index 8bae8c19931..70d365367d8 100644
--- a/chromium/net/ftp/ftp_response_info.h
+++ b/chromium/net/ftp/ftp_response_info.h
@@ -5,6 +5,8 @@
#ifndef NET_FTP_FTP_RESPONSE_INFO_H_
#define NET_FTP_FTP_RESPONSE_INFO_H_
+#include <stdint.h>
+
#include "base/time/time.h"
#include "net/base/host_port_pair.h"
@@ -29,7 +31,7 @@ class FtpResponseInfo {
// Expected content size, in bytes, as reported by SIZE command. Only valid
// for file downloads. -1 means unknown size.
- int64 expected_content_size;
+ int64_t expected_content_size;
// True if the response data is of a directory listing.
bool is_directory_listing;
diff --git a/chromium/net/ftp/ftp_transaction.h b/chromium/net/ftp/ftp_transaction.h
index f0e1b41f26d..07401896fb6 100644
--- a/chromium/net/ftp/ftp_transaction.h
+++ b/chromium/net/ftp/ftp_transaction.h
@@ -5,6 +5,8 @@
#ifndef NET_FTP_FTP_TRANSACTION_H_
#define NET_FTP_FTP_TRANSACTION_H_
+#include <stdint.h>
+
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/load_states.h"
@@ -72,7 +74,7 @@ class NET_EXPORT_PRIVATE FtpTransaction {
// Returns the upload progress in bytes. If there is no upload data,
// zero will be returned.
- virtual uint64 GetUploadProgress() const = 0;
+ virtual uint64_t GetUploadProgress() const = 0;
};
} // namespace net
diff --git a/chromium/net/ftp/ftp_transaction_factory.h b/chromium/net/ftp/ftp_transaction_factory.h
index db32fbeeac5..6b7cdb93212 100644
--- a/chromium/net/ftp/ftp_transaction_factory.h
+++ b/chromium/net/ftp/ftp_transaction_factory.h
@@ -5,6 +5,7 @@
#ifndef NET_FTP_FTP_TRANSACTION_FACTORY_H_
#define NET_FTP_FTP_TRANSACTION_FACTORY_H_
+#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
namespace net {
@@ -17,7 +18,7 @@ class NET_EXPORT FtpTransactionFactory {
virtual ~FtpTransactionFactory() {}
// Creates a FtpTransaction object.
- virtual FtpTransaction* CreateTransaction() = 0;
+ virtual scoped_ptr<FtpTransaction> CreateTransaction() = 0;
// Suspends the creation of new transactions. If |suspend| is false, creation
// of new transactions is resumed.
diff --git a/chromium/net/ftp/ftp_util.cc b/chromium/net/ftp/ftp_util.cc
index 2f1df696c28..a2bee15cf5d 100644
--- a/chromium/net/ftp/ftp_util.cc
+++ b/chromium/net/ftp/ftp_util.cc
@@ -10,6 +10,7 @@
#include "base/i18n/case_conversion.h"
#include "base/i18n/char_iterator.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
diff --git a/chromium/net/ftp/ftp_util_unittest.cc b/chromium/net/ftp/ftp_util_unittest.cc
index 121780bb65b..a6f2ff019ef 100644
--- a/chromium/net/ftp/ftp_util_unittest.cc
+++ b/chromium/net/ftp/ftp_util_unittest.cc
@@ -4,7 +4,6 @@
#include "net/ftp/ftp_util.h"
-#include "base/basictypes.h"
#include "base/format_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
diff --git a/chromium/net/http/bidirectional_stream.cc b/chromium/net/http/bidirectional_stream.cc
new file mode 100644
index 00000000000..cacb08478a0
--- /dev/null
+++ b/chromium/net/http/bidirectional_stream.cc
@@ -0,0 +1,224 @@
+// Copyright 2015 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/bidirectional_stream.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/http/bidirectional_stream_request_info.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_stream.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "net/ssl/ssl_config.h"
+#include "url/gurl.h"
+
+namespace net {
+
+BidirectionalStream::Delegate::Delegate() {}
+
+BidirectionalStream::Delegate::~Delegate() {}
+
+BidirectionalStream::BidirectionalStream(
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info,
+ HttpNetworkSession* session,
+ Delegate* delegate)
+ : BidirectionalStream(std::move(request_info),
+ session,
+ delegate,
+ make_scoped_ptr(new base::Timer(false, false))) {}
+
+BidirectionalStream::BidirectionalStream(
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info,
+ HttpNetworkSession* session,
+ Delegate* delegate,
+ scoped_ptr<base::Timer> timer)
+ : request_info_(std::move(request_info)),
+ net_log_(BoundNetLog::Make(session->net_log(),
+ NetLog::SOURCE_BIDIRECTIONAL_STREAM)),
+ delegate_(delegate),
+ timer_(std::move(timer)) {
+ DCHECK(delegate_);
+ DCHECK(request_info_);
+
+ SSLConfig server_ssl_config;
+ session->ssl_config_service()->GetSSLConfig(&server_ssl_config);
+ session->GetAlpnProtos(&server_ssl_config.alpn_protos);
+ session->GetNpnProtos(&server_ssl_config.npn_protos);
+
+ if (!request_info_->url.SchemeIs(url::kHttpsScheme)) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&BidirectionalStream::Delegate::OnFailed,
+ base::Unretained(delegate_), ERR_DISALLOWED_URL_SCHEME));
+ 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;
+ stream_request_.reset(
+ session->http_stream_factory()->RequestBidirectionalStreamJob(
+ http_request_info, request_info_->priority, server_ssl_config,
+ server_ssl_config, this, net_log_));
+ // Check that this call cannot fail to set a non-NULL |stream_request_|.
+ DCHECK(stream_request_);
+ // Check that HttpStreamFactory does not invoke OnBidirectionalStreamJobReady
+ // synchronously.
+ DCHECK(!stream_job_);
+}
+
+BidirectionalStream::~BidirectionalStream() {
+ Cancel();
+}
+
+int BidirectionalStream::ReadData(IOBuffer* buf, int buf_len) {
+ DCHECK(stream_job_);
+
+ return stream_job_->ReadData(buf, buf_len);
+}
+
+void BidirectionalStream::SendData(IOBuffer* data,
+ int length,
+ bool end_stream) {
+ DCHECK(stream_job_);
+
+ stream_job_->SendData(data, length, end_stream);
+}
+
+void BidirectionalStream::Cancel() {
+ stream_request_.reset();
+ if (stream_job_) {
+ stream_job_->Cancel();
+ stream_job_.reset();
+ }
+}
+
+NextProto BidirectionalStream::GetProtocol() const {
+ if (!stream_job_)
+ return kProtoUnknown;
+
+ return stream_job_->GetProtocol();
+}
+
+int64_t BidirectionalStream::GetTotalReceivedBytes() const {
+ if (!stream_job_)
+ return 0;
+
+ return stream_job_->GetTotalReceivedBytes();
+}
+
+int64_t BidirectionalStream::GetTotalSentBytes() const {
+ if (!stream_job_)
+ return 0;
+
+ return stream_job_->GetTotalSentBytes();
+}
+
+void BidirectionalStream::OnHeadersSent() {
+ delegate_->OnHeadersSent();
+}
+
+void BidirectionalStream::OnHeadersReceived(
+ const SpdyHeaderBlock& response_headers) {
+ delegate_->OnHeadersReceived(response_headers);
+}
+
+void BidirectionalStream::OnDataRead(int bytes_read) {
+ delegate_->OnDataRead(bytes_read);
+}
+
+void BidirectionalStream::OnDataSent() {
+ delegate_->OnDataSent();
+}
+
+void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) {
+ delegate_->OnTrailersReceived(trailers);
+}
+
+void BidirectionalStream::OnFailed(int status) {
+ delegate_->OnFailed(status);
+}
+
+void BidirectionalStream::OnStreamReady(const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ HttpStream* stream) {
+ NOTREACHED();
+}
+
+void BidirectionalStream::OnBidirectionalStreamJobReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream) {
+ DCHECK(!stream_job_);
+
+ stream_request_.reset();
+ stream_job_.reset(stream);
+ stream_job_->Start(request_info_.get(), net_log_, this, std::move(timer_));
+}
+
+void BidirectionalStream::OnWebSocketHandshakeStreamReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ WebSocketHandshakeStreamBase* stream) {
+ NOTREACHED();
+}
+
+void BidirectionalStream::OnStreamFailed(int result,
+ const SSLConfig& used_ssl_config,
+ SSLFailureState ssl_failure_state) {
+ DCHECK_LT(result, 0);
+ DCHECK_NE(result, ERR_IO_PENDING);
+ DCHECK(stream_request_);
+
+ delegate_->OnFailed(result);
+}
+
+void BidirectionalStream::OnCertificateError(int result,
+ const SSLConfig& used_ssl_config,
+ const SSLInfo& ssl_info) {
+ DCHECK_LT(result, 0);
+ DCHECK_NE(result, ERR_IO_PENDING);
+ DCHECK(stream_request_);
+
+ delegate_->OnFailed(result);
+}
+
+void BidirectionalStream::OnNeedsProxyAuth(
+ const HttpResponseInfo& proxy_response,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ HttpAuthController* auth_controller) {
+ DCHECK(stream_request_);
+
+ delegate_->OnFailed(ERR_PROXY_AUTH_REQUESTED);
+}
+
+void BidirectionalStream::OnNeedsClientAuth(const SSLConfig& used_ssl_config,
+ SSLCertRequestInfo* cert_info) {
+ DCHECK(stream_request_);
+
+ delegate_->OnFailed(ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
+}
+
+void BidirectionalStream::OnHttpsProxyTunnelResponse(
+ const HttpResponseInfo& response_info,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ HttpStream* stream) {
+ DCHECK(stream_request_);
+
+ delegate_->OnFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
+}
+
+void BidirectionalStream::OnQuicBroken() {}
+
+} // namespace net
diff --git a/chromium/net/http/bidirectional_stream.h b/chromium/net/http/bidirectional_stream.h
new file mode 100644
index 00000000000..5de3135e99d
--- /dev/null
+++ b/chromium/net/http/bidirectional_stream.h
@@ -0,0 +1,212 @@
+// Copyright 2015 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_BIDIRECTIONAL_STREAM_H_
+#define NET_HTTP_BIDIRECTIONAL_STREAM_H_
+
+#include <stdint.h>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/http/bidirectional_stream_job.h"
+#include "net/http/http_stream_factory.h"
+#include "net/log/net_log.h"
+#include "net/net_features.h"
+
+#if !BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+#error Only include this if ENABLE_BIDIRECTIONAL_STREAM is defined
+#endif
+
+class GURL;
+
+namespace net {
+
+class HttpAuthController;
+class HttpNetworkSession;
+class HttpStream;
+class HttpStreamRequest;
+class IOBuffer;
+class ProxyInfo;
+class SpdyHeaderBlock;
+struct BidirectionalStreamRequestInfo;
+struct SSLConfig;
+
+// A class to do HTTP/2 bidirectional streaming. Note that at most one each of
+// ReadData or SendData should be in flight until the operation completes.
+// The BidirectionalStream must be torn down before the HttpNetworkSession.
+class NET_EXPORT BidirectionalStream
+ : public NON_EXPORTED_BASE(BidirectionalStreamJob::Delegate),
+ public NON_EXPORTED_BASE(HttpStreamRequest::Delegate) {
+ public:
+ // Delegate interface to get notified of success of failure. Callbacks will be
+ // invoked asynchronously.
+ class NET_EXPORT Delegate {
+ public:
+ Delegate();
+
+ // Called when headers have been sent. This is called at most once for
+ // the lifetime of a stream.
+ // The delegate may call BidirectionalStream::ReadData to start reading,
+ // or call BidirectionalStream::SendData to send data.
+ // The delegate should not call BidirectionalStream::Cancel
+ // during this callback.
+ virtual void OnHeadersSent() = 0;
+
+ // Called when headers are received. This is called at most once for the
+ // lifetime of a stream.
+ // The delegate may call BidirectionalStream::ReadData to start reading,
+ // call BidirectionalStream::SendData to send data,
+ // or call BidirectionalStream::Cancel to cancel the stream.
+ virtual void OnHeadersReceived(const SpdyHeaderBlock& response_headers) = 0;
+
+ // Called when a pending read is completed asynchronously.
+ // |bytes_read| specifies how much data is read.
+ // The delegate may call BidirectionalStream::ReadData to continue
+ // reading, call BidirectionalStream::SendData to send data,
+ // or call BidirectionalStream::Cancel to cancel the stream.
+ virtual void OnDataRead(int bytes_read) = 0;
+
+ // Called when the entire buffer passed through SendData is sent.
+ // The delegate may call BidirectionalStream::ReadData to continue
+ // reading, call BidirectionalStream::SendData to send data,
+ // The delegate should not call BidirectionalStream::Cancel
+ // during this callback.
+ virtual void OnDataSent() = 0;
+
+ // Called when trailers are received. This is called as soon as trailers
+ // are received, which can happen before a read completes.
+ // The delegate is able to continue reading if there is no pending read and
+ // EOF has not been received, or to send data if there is no pending send.
+ virtual void OnTrailersReceived(const SpdyHeaderBlock& trailers) = 0;
+
+ // Called when the stream is closed or an error occurred.
+ // No other delegate functions will be called after this.
+ virtual void OnFailed(int error) = 0;
+
+ protected:
+ virtual ~Delegate();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Delegate);
+ };
+
+ // Constructs a BidirectionalStream. |request_info| contains information about
+ // the request, and must be non-NULL. |session| is the http network session
+ // with which this request will be made. |delegate| must be non-NULL.
+ // |session| and |delegate| must outlive |this|.
+ BidirectionalStream(scoped_ptr<BidirectionalStreamRequestInfo> request_info,
+ HttpNetworkSession* session,
+ Delegate* delegate);
+
+ // Constructor that accepts a Timer, which can be used in tests to control
+ // the buffering of received data.
+ BidirectionalStream(scoped_ptr<BidirectionalStreamRequestInfo> request_info,
+ HttpNetworkSession* session,
+ Delegate* delegate,
+ scoped_ptr<base::Timer> timer);
+
+ // Cancels |stream_request_| or |stream_job_| if applicable.
+ // |this| should not be destroyed during Delegate::OnHeadersSent or
+ // Delegate::OnDataSent.
+ ~BidirectionalStream() override;
+
+ // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes read,
+ // or ERR_IO_PENDING if the read is to be completed asynchronously, or an
+ // error code if any error occurred. If returns 0, there is no more data to
+ // read. This should not be called before Delegate::OnHeadersReceived is
+ // invoked, and should not be called again unless it returns with number
+ // greater than 0 or until Delegate::OnDataRead is invoked.
+ int ReadData(IOBuffer* buf, int buf_len);
+
+ // Sends data. This should not be called before Delegate::OnHeadersSent is
+ // invoked, and should not be called again until Delegate::OnDataSent is
+ // invoked. If |end_stream| is true, the DATA frame will have an END_STREAM
+ // flag.
+ void SendData(IOBuffer* data, int length, bool end_stream);
+
+ // If |stream_request_| is non-NULL, cancel it. If |stream_job_| is
+ // established, cancel it. No delegate method will be called after Cancel().
+ // Any pending operations may or may not succeed.
+ void Cancel();
+
+ // Returns the protocol used by this stream. If stream has not been
+ // established, return kProtoUnknown.
+ NextProto GetProtocol() const;
+
+ // Total number of bytes received over the network of SPDY data, headers, and
+ // push_promise frames associated with this stream, including the size of
+ // frame headers, after SSL decryption and not including proxy overhead.
+ // If stream has not been established, return 0.
+ int64_t GetTotalReceivedBytes() const;
+
+ // Total number of bytes sent over the network of SPDY frames associated with
+ // this stream, including the size of frame headers, before SSL encryption and
+ // not including proxy overhead. Note that some SPDY frames such as pings are
+ // not associated with any stream, and are not included in this value.
+ int64_t GetTotalSentBytes() const;
+
+ // TODO(xunjieli): Implement a method to do flow control and a method to ping
+ // remote end point.
+
+ private:
+ // BidirectionalStreamJob::Delegate implementation:
+ void OnHeadersSent() override;
+ void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override;
+ void OnDataRead(int bytes_read) override;
+ void OnDataSent() override;
+ void OnTrailersReceived(const SpdyHeaderBlock& trailers) override;
+ void OnFailed(int error) override;
+
+ // HttpStreamRequest::Delegate implementation:
+ void OnStreamReady(const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ HttpStream* stream) override;
+ void OnBidirectionalStreamJobReady(const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream) override;
+ void OnWebSocketHandshakeStreamReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ WebSocketHandshakeStreamBase* stream) override;
+ void OnStreamFailed(int status,
+ const SSLConfig& used_ssl_config,
+ SSLFailureState ssl_failure_state) override;
+ void OnCertificateError(int status,
+ const SSLConfig& used_ssl_config,
+ const SSLInfo& ssl_info) override;
+ void OnNeedsProxyAuth(const HttpResponseInfo& response_info,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ HttpAuthController* auth_controller) override;
+ void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
+ SSLCertRequestInfo* cert_info) override;
+ void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ HttpStream* stream) override;
+ void OnQuicBroken() override;
+
+ // BidirectionalStreamRequestInfo used when requesting the stream.
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info_;
+ const BoundNetLog net_log_;
+
+ Delegate* const delegate_;
+
+ // Timer used to buffer data received in short time-spans and send a single
+ // read completion notification.
+ scoped_ptr<base::Timer> timer_;
+ // HttpStreamRequest used to request a BidirectionalStreamJob. This is NULL if
+ // the request has been canceled or completed.
+ scoped_ptr<HttpStreamRequest> stream_request_;
+ // The underlying BidirectioanlStreamJob used for this stream. It is non-NULL,
+ // if the |stream_request_| successfully finishes.
+ scoped_ptr<BidirectionalStreamJob> stream_job_;
+
+ DISALLOW_COPY_AND_ASSIGN(BidirectionalStream);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_BIDIRECTIONAL_STREAM_H_
diff --git a/chromium/net/http/bidirectional_stream_job.cc b/chromium/net/http/bidirectional_stream_job.cc
new file mode 100644
index 00000000000..3c307536f94
--- /dev/null
+++ b/chromium/net/http/bidirectional_stream_job.cc
@@ -0,0 +1,17 @@
+// Copyright 2015 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/bidirectional_stream_job.h"
+
+namespace net {
+
+BidirectionalStreamJob::Delegate::Delegate() {}
+
+BidirectionalStreamJob::Delegate::~Delegate() {}
+
+BidirectionalStreamJob::BidirectionalStreamJob() {}
+
+BidirectionalStreamJob::~BidirectionalStreamJob() {}
+
+} // namespace net
diff --git a/chromium/net/http/bidirectional_stream_job.h b/chromium/net/http/bidirectional_stream_job.h
new file mode 100644
index 00000000000..001944de5e5
--- /dev/null
+++ b/chromium/net/http/bidirectional_stream_job.h
@@ -0,0 +1,140 @@
+// Copyright 2015 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_BIDIRECTIONAL_STREAM_JOB_H_
+#define NET_HTTP_BIDIRECTIONAL_STREAM_JOB_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
+#include "net/net_features.h"
+#include "net/socket/next_proto.h"
+
+#if !BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+#error Only include this if ENABLE_BIDIRECTIONAL_STREAM is defined
+#endif
+
+namespace base {
+class Timer;
+} // namespace base
+
+namespace net {
+
+class BoundNetLog;
+class IOBuffer;
+class SpdyHeaderBlock;
+struct BidirectionalStreamRequestInfo;
+
+// Exposes an interface to do HTTP/2 bidirectional streaming.
+// Note that only one ReadData or SendData should be in flight until the
+// operation completes synchronously or asynchronously.
+// BidirectionalStreamJob once created by HttpStreamFactoryImpl should be owned
+// by BidirectionalStream.
+class NET_EXPORT_PRIVATE BidirectionalStreamJob {
+ public:
+ // Delegate to handle BidirectionalStreamJob events.
+ class NET_EXPORT_PRIVATE Delegate {
+ public:
+ Delegate();
+
+ // Called when the request headers have been sent.
+ // The delegate may call BidirectionalStreamJob::ReadData to start reading,
+ // call BidirectionalStreamJob::SendData to send data,
+ // or call BidirectionalStreamJob::Cancel to cancel the stream.
+ // The delegate should not call BidirectionalStreamJob::Cancel
+ // during this callback.
+ virtual void OnHeadersSent() = 0;
+
+ // Called when response headers are received.
+ // This is called at most once for the lifetime of a stream.
+ // The delegate may call BidirectionalStreamJob::ReadData to start
+ // reading, call BidirectionalStreamJob::SendData to send data,
+ // or call BidirectionalStreamJob::Cancel to cancel the stream.
+ virtual void OnHeadersReceived(const SpdyHeaderBlock& response_headers) = 0;
+
+ // Called when read is completed asynchronously. |bytes_read| specifies how
+ // much data is available.
+ // The delegate may call BidirectionalStreamJob::ReadData to continue
+ // reading, call BidirectionalStreamJob::SendData to send data,
+ // or call BidirectionalStreamJob::Cancel to cancel the stream.
+ virtual void OnDataRead(int bytes_read) = 0;
+
+ // Called when the entire buffer passed through SendData is sent.
+ // The delegate may call BidirectionalStreamJob::ReadData to continue
+ // reading, or call BidirectionalStreamJob::SendData to send data.
+ // The delegate should not call BidirectionalStreamJob::Cancel
+ // during this callback.
+ virtual void OnDataSent() = 0;
+
+ // Called when trailers are received. This is called as soon as trailers
+ // are received, which can happen before a read completes.
+ // The delegate is able to continue reading if there is no pending read and
+ // EOF has not been received, or to send data if there is no pending send.
+ virtual void OnTrailersReceived(const SpdyHeaderBlock& trailers) = 0;
+
+ // Called when an error occurred.
+ // No other delegate functions will be called after this.
+ virtual void OnFailed(int status) = 0;
+
+ protected:
+ virtual ~Delegate();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Delegate);
+ };
+
+ BidirectionalStreamJob();
+
+ // |this| should not be destroyed during Delegate::OnHeadersSent or
+ // Delegate::OnDataSent.
+ virtual ~BidirectionalStreamJob();
+
+ // Starts the BidirectionalStreamJob and sends request headers.
+ virtual void Start(const BidirectionalStreamRequestInfo* request_info,
+ const BoundNetLog& net_log,
+ BidirectionalStreamJob::Delegate* delegate,
+ scoped_ptr<base::Timer> timer) = 0;
+
+ // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes read,
+ // ERR_IO_PENDING if the read is to be completed asynchronously, or an error
+ // code if any error occurred. If returns 0, there is no more data to read.
+ // This should not be called before Delegate::OnHeadersReceived is invoked,
+ // and should not be called again unless it returns with number greater than
+ // 0 or until Delegate::OnDataRead is invoked.
+ virtual int ReadData(IOBuffer* buf, int buf_len) = 0;
+
+ // Sends data. This should not be called be called before
+ // Delegate::OnHeadersSent is invoked, and should not be called again until
+ // Delegate::OnDataSent is invoked. If |end_stream| is true, the DATA frame
+ // will have an END_STREAM flag.
+ virtual void SendData(IOBuffer* data, int length, bool end_stream) = 0;
+
+ // Cancels the stream. No Delegate method will be called. Any pending
+ // operations may or may not succeed.
+ virtual void Cancel() = 0;
+
+ // Returns the protocol used by this stream. If stream has not been
+ // established, return kProtoUnknown.
+ virtual NextProto GetProtocol() const = 0;
+
+ // Total number of bytes received over the network of SPDY data, headers, and
+ // push_promise frames associated with this stream, including the size of
+ // frame headers, after SSL decryption and not including proxy overhead.
+ virtual int64_t GetTotalReceivedBytes() const = 0;
+
+ // Total number of bytes sent over the network of SPDY frames associated with
+ // this stream, including the size of frame headers, before SSL encryption and
+ // not including proxy overhead. Note that some SPDY frames such as pings are
+ // not associated with any stream, and are not included in this value.
+ virtual int64_t GetTotalSentBytes() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BidirectionalStreamJob);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_BIDIRECTIONAL_STREAM_JOB_H_
diff --git a/chromium/net/http/bidirectional_stream_request_info.cc b/chromium/net/http/bidirectional_stream_request_info.cc
new file mode 100644
index 00000000000..309606e7873
--- /dev/null
+++ b/chromium/net/http/bidirectional_stream_request_info.cc
@@ -0,0 +1,14 @@
+// Copyright 2015 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/bidirectional_stream_request_info.h"
+
+namespace net {
+
+BidirectionalStreamRequestInfo::BidirectionalStreamRequestInfo()
+ : priority(LOW), end_stream_on_headers(false) {}
+
+BidirectionalStreamRequestInfo::~BidirectionalStreamRequestInfo() {}
+
+} // namespace net
diff --git a/chromium/net/http/bidirectional_stream_request_info.h b/chromium/net/http/bidirectional_stream_request_info.h
new file mode 100644
index 00000000000..34ea66e179d
--- /dev/null
+++ b/chromium/net/http/bidirectional_stream_request_info.h
@@ -0,0 +1,40 @@
+// Copyright 2015 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_BIDIRECTIONAL_STREAM_REQUEST_INFO_H_
+#define NET_HTTP_BIDIRECTIONAL_STREAM_REQUEST_INFO_H_
+
+#include <string>
+
+#include "net/base/net_export.h"
+#include "net/base/request_priority.h"
+#include "net/http/http_request_headers.h"
+#include "url/gurl.h"
+
+namespace net {
+
+// Struct containing information needed to request a BidirectionalStream.
+struct NET_EXPORT BidirectionalStreamRequestInfo {
+ BidirectionalStreamRequestInfo();
+ ~BidirectionalStreamRequestInfo();
+
+ // The requested URL.
+ GURL url;
+
+ // The method to use (GET, POST, etc.).
+ std::string method;
+
+ // Request priority.
+ RequestPriority priority;
+
+ // Any extra request headers (including User-Agent).
+ HttpRequestHeaders extra_headers;
+
+ // Whether END_STREAM should be set on the request HEADER frame.
+ bool end_stream_on_headers;
+};
+
+} // namespace net
+
+#endif // NET_HTTP_BIDIRECTIONAL_STREAM_REQUEST_INFO_H_
diff --git a/chromium/net/http/bidirectional_stream_unittest.cc b/chromium/net/http/bidirectional_stream_unittest.cc
new file mode 100644
index 00000000000..aeee7a869e0
--- /dev/null
+++ b/chromium/net/http/bidirectional_stream_unittest.cc
@@ -0,0 +1,1196 @@
+// Copyright 2015 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/bidirectional_stream.h"
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/time/time.h"
+#include "base/timer/mock_timer.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_data_directory.h"
+#include "net/http/bidirectional_stream_request_info.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_response_headers.h"
+#include "net/log/net_log.h"
+#include "net/socket/socket_test_util.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_test_util_common.h"
+#include "net/test/cert_test_util.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+const char kBodyData[] = "Body data";
+const size_t kBodyDataSize = arraysize(kBodyData);
+// Size of the buffer to be allocated for each read.
+const size_t kReadBufferSize = 4096;
+
+// Delegate that reads data but does not send any data.
+class TestDelegateBase : public BidirectionalStream::Delegate {
+ public:
+ TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
+ : TestDelegateBase(read_buf,
+ read_buf_len,
+ make_scoped_ptr(new base::Timer(false, false))) {}
+
+ TestDelegateBase(IOBuffer* read_buf,
+ int read_buf_len,
+ scoped_ptr<base::Timer> timer)
+ : read_buf_(read_buf),
+ read_buf_len_(read_buf_len),
+ timer_(std::move(timer)),
+ loop_(nullptr),
+ error_(OK),
+ on_data_read_count_(0),
+ on_data_sent_count_(0),
+ do_not_start_read_(false),
+ run_until_completion_(false),
+ not_expect_callback_(false) {}
+
+ ~TestDelegateBase() override {}
+
+ void OnHeadersSent() override { CHECK(!not_expect_callback_); }
+
+ void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
+ CHECK(!not_expect_callback_);
+
+ response_headers_ = response_headers;
+ if (!do_not_start_read_)
+ StartOrContinueReading();
+ }
+
+ void OnDataRead(int bytes_read) override {
+ CHECK(!not_expect_callback_);
+
+ ++on_data_read_count_;
+ CHECK_GE(bytes_read, OK);
+ data_received_.append(read_buf_->data(), bytes_read);
+ if (!do_not_start_read_)
+ StartOrContinueReading();
+ }
+
+ void OnDataSent() override {
+ CHECK(!not_expect_callback_);
+
+ ++on_data_sent_count_;
+ }
+
+ void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
+ CHECK(!not_expect_callback_);
+
+ trailers_ = trailers;
+ if (run_until_completion_)
+ loop_->Quit();
+ }
+
+ void OnFailed(int error) override {
+ CHECK(!not_expect_callback_);
+ CHECK_EQ(OK, error_);
+ CHECK_NE(OK, error);
+
+ error_ = error;
+ if (run_until_completion_)
+ loop_->Quit();
+ }
+
+ void Start(scoped_ptr<BidirectionalStreamRequestInfo> request_info,
+ HttpNetworkSession* session) {
+ stream_.reset(new BidirectionalStream(std::move(request_info), session,
+ this, std::move(timer_)));
+ if (run_until_completion_)
+ loop_->Run();
+ }
+
+ void SendData(IOBuffer* data, int length, bool end_of_stream) {
+ not_expect_callback_ = true;
+ stream_->SendData(data, length, end_of_stream);
+ not_expect_callback_ = false;
+ }
+
+ // Starts or continues reading data from |stream_| until no more bytes
+ // can be read synchronously.
+ void StartOrContinueReading() {
+ int rv = ReadData();
+ while (rv > 0) {
+ rv = ReadData();
+ }
+ if (run_until_completion_ && rv == 0)
+ loop_->Quit();
+ }
+
+ // Calls ReadData on the |stream_| and updates internal states.
+ int ReadData() {
+ not_expect_callback_ = true;
+ int rv = stream_->ReadData(read_buf_.get(), read_buf_len_);
+ not_expect_callback_ = false;
+ if (rv > 0)
+ data_received_.append(read_buf_->data(), rv);
+ return rv;
+ }
+
+ // Cancels |stream_|.
+ void CancelStream() { stream_->Cancel(); }
+
+ // Deletes |stream_|.
+ void DeleteStream() { stream_.reset(); }
+
+ NextProto GetProtocol() const { return stream_->GetProtocol(); }
+
+ int64_t GetTotalReceivedBytes() const {
+ return stream_->GetTotalReceivedBytes();
+ }
+
+ int64_t GetTotalSentBytes() const { return stream_->GetTotalSentBytes(); }
+
+ // Const getters for internal states.
+ const std::string& data_received() const { return data_received_; }
+ int error() const { return error_; }
+ const SpdyHeaderBlock& response_headers() const { return response_headers_; }
+ const SpdyHeaderBlock& trailers() const { return trailers_; }
+ int on_data_read_count() const { return on_data_read_count_; }
+ int on_data_sent_count() const { return on_data_sent_count_; }
+
+ // Sets whether the delegate should automatically start reading.
+ void set_do_not_start_read(bool do_not_start_read) {
+ do_not_start_read_ = do_not_start_read;
+ }
+ // Sets whether the delegate should wait until the completion of the stream.
+ void SetRunUntilCompletion(bool run_until_completion) {
+ run_until_completion_ = run_until_completion;
+ loop_.reset(new base::RunLoop);
+ }
+
+ protected:
+ // Quits |loop_|.
+ void QuitLoop() { loop_->Quit(); }
+
+ private:
+ scoped_ptr<BidirectionalStream> stream_;
+ scoped_refptr<IOBuffer> read_buf_;
+ int read_buf_len_;
+ scoped_ptr<base::Timer> timer_;
+ std::string data_received_;
+ scoped_ptr<base::RunLoop> loop_;
+ SpdyHeaderBlock response_headers_;
+ SpdyHeaderBlock trailers_;
+ int error_;
+ int on_data_read_count_;
+ int on_data_sent_count_;
+ bool do_not_start_read_;
+ bool run_until_completion_;
+ // This is to ensure that delegate callback is not invoked synchronously when
+ // calling into |stream_|.
+ bool not_expect_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestDelegateBase);
+};
+
+// A delegate that deletes the stream in a particular callback.
+class CancelOrDeleteStreamDelegate : public TestDelegateBase {
+ public:
+ // Specifies in which callback the stream can be deleted.
+ enum Phase {
+ ON_HEADERS_RECEIVED,
+ ON_DATA_READ,
+ ON_TRAILERS_RECEIVED,
+ ON_FAILED,
+ };
+
+ CancelOrDeleteStreamDelegate(IOBuffer* buf,
+ int buf_len,
+ Phase phase,
+ bool do_cancel)
+ : TestDelegateBase(buf, buf_len), phase_(phase), do_cancel_(do_cancel) {}
+ ~CancelOrDeleteStreamDelegate() override {}
+
+ void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
+ TestDelegateBase::OnHeadersReceived(response_headers);
+ if (phase_ == ON_HEADERS_RECEIVED) {
+ CancelOrDelete();
+ QuitLoop();
+ }
+ }
+
+ void OnDataSent() override { NOTREACHED(); }
+
+ void OnDataRead(int bytes_read) override {
+ if (phase_ == ON_HEADERS_RECEIVED) {
+ NOTREACHED();
+ return;
+ }
+ TestDelegateBase::OnDataRead(bytes_read);
+ if (phase_ == ON_DATA_READ) {
+ CancelOrDelete();
+ QuitLoop();
+ }
+ }
+
+ void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
+ if (phase_ == ON_HEADERS_RECEIVED || phase_ == ON_DATA_READ) {
+ NOTREACHED();
+ return;
+ }
+ TestDelegateBase::OnTrailersReceived(trailers);
+ if (phase_ == ON_TRAILERS_RECEIVED) {
+ CancelOrDelete();
+ QuitLoop();
+ }
+ }
+
+ void OnFailed(int error) override {
+ if (phase_ != ON_FAILED) {
+ NOTREACHED();
+ return;
+ }
+ TestDelegateBase::OnFailed(error);
+ CancelOrDelete();
+ QuitLoop();
+ }
+
+ private:
+ void CancelOrDelete() {
+ if (do_cancel_) {
+ CancelStream();
+ } else {
+ DeleteStream();
+ }
+ }
+
+ // Indicates in which callback the delegate should cancel or delete the
+ // stream.
+ Phase phase_;
+ // Indicates whether to cancel or delete the stream.
+ bool do_cancel_;
+
+ DISALLOW_COPY_AND_ASSIGN(CancelOrDeleteStreamDelegate);
+};
+
+// A Timer that does not start a delayed task unless the timer is fired.
+class MockTimer : public base::MockTimer {
+ public:
+ MockTimer() : base::MockTimer(false, false) {}
+ ~MockTimer() override {}
+
+ void Start(const tracked_objects::Location& posted_from,
+ base::TimeDelta delay,
+ const base::Closure& user_task) override {
+ // Sets a maximum delay, so the timer does not fire unless it is told to.
+ base::TimeDelta infinite_delay = base::TimeDelta::Max();
+ base::MockTimer::Start(posted_from, infinite_delay, user_task);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockTimer);
+};
+
+} // namespace
+
+class BidirectionalStreamTest : public testing::TestWithParam<bool> {
+ public:
+ BidirectionalStreamTest()
+ : spdy_util_(kProtoHTTP2, false),
+ session_deps_(kProtoHTTP2),
+ ssl_data_(SSLSocketDataProvider(ASYNC, OK)) {
+ ssl_data_.SetNextProto(kProtoHTTP2);
+ ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
+ }
+
+ protected:
+ void TearDown() override {
+ if (sequenced_data_) {
+ EXPECT_TRUE(sequenced_data_->AllReadDataConsumed());
+ EXPECT_TRUE(sequenced_data_->AllWriteDataConsumed());
+ }
+ }
+
+ // Initializes the session using SequencedSocketData.
+ void InitSession(MockRead* reads,
+ size_t reads_count,
+ MockWrite* writes,
+ size_t writes_count,
+ const SpdySessionKey& key) {
+ ASSERT_TRUE(ssl_data_.cert.get());
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data_);
+ sequenced_data_.reset(
+ new SequencedSocketData(reads, reads_count, writes, writes_count));
+ session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get());
+ http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+ session_ = CreateSecureSpdySession(http_session_.get(), key, BoundNetLog());
+ }
+
+ SpdyTestUtil spdy_util_;
+ SpdySessionDependencies session_deps_;
+ scoped_ptr<SequencedSocketData> sequenced_data_;
+ scoped_ptr<HttpNetworkSession> http_session_;
+
+ private:
+ SSLSocketDataProvider ssl_data_;
+ base::WeakPtr<SpdySession> session_;
+};
+
+TEST_F(BidirectionalStreamTest, CreateInsecureStream) {
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("http://www.example.org/");
+
+ TestDelegateBase delegate(nullptr, 0);
+ HttpNetworkSession::Params params =
+ SpdySessionDependencies::CreateSessionParams(&session_deps_);
+ scoped_ptr<HttpNetworkSession> session(new HttpNetworkSession(params));
+ delegate.SetRunUntilCompletion(true);
+ delegate.Start(std::move(request_info), session.get());
+
+ EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, delegate.error());
+}
+
+// Simulates user calling ReadData after END_STREAM has been received in
+// BidirectionalStreamSpdyJob.
+TEST_F(BidirectionalStreamTest, TestReadDataAfterClose) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+ // Empty DATA frame with an END_STREAM flag.
+ scoped_ptr<SpdyFrame> end_stream(
+ spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
+ MockWrite writes[] = {
+ CreateMockWrite(*req.get(), 0),
+ };
+
+ const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
+
+ scoped_ptr<SpdyFrame> body_frame(spdy_util_.ConstructSpdyBodyFrame(1, false));
+ // Last body frame has END_STREAM flag set.
+ scoped_ptr<SpdyFrame> last_body_frame(
+ spdy_util_.ConstructSpdyBodyFrame(1, true));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1),
+ MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
+ CreateMockRead(*body_frame, 3),
+ MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
+ CreateMockRead(*body_frame, 5),
+ CreateMockRead(*last_body_frame, 6),
+ MockRead(SYNCHRONOUS, 0, 7),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->end_stream_on_headers = true;
+ request_info->priority = LOWEST;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ // Create a MockTimer. Retain a raw pointer since the underlying
+ // BidirectionalStreamJob owns it.
+ MockTimer* timer = new MockTimer();
+ scoped_ptr<TestDelegateBase> delegate(new TestDelegateBase(
+ read_buffer.get(), kReadBufferSize, make_scoped_ptr(timer)));
+ delegate->set_do_not_start_read(true);
+
+ delegate->Start(std::move(request_info), http_session_.get());
+
+ // Write request, and deliver response headers.
+ sequenced_data_->RunUntilPaused();
+ EXPECT_FALSE(timer->IsRunning());
+ // ReadData returns asynchronously because no data is buffered.
+ int rv = delegate->ReadData();
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ // Deliver a DATA frame.
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+ timer->Fire();
+ // Asynchronous completion callback is invoke.
+ EXPECT_EQ(1, delegate->on_data_read_count());
+ EXPECT_EQ(kUploadDataSize * 1,
+ static_cast<int>(delegate->data_received().size()));
+
+ // Deliver the rest. Note that user has not called a second ReadData.
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+ // ReadData now. Read should complete synchronously.
+ rv = delegate->ReadData();
+ EXPECT_EQ(kUploadDataSize * 2, rv);
+ rv = delegate->ReadData();
+ EXPECT_EQ(OK, rv); // EOF.
+
+ const SpdyHeaderBlock response_headers = delegate->response_headers();
+ EXPECT_EQ("200", response_headers.find(":status")->second);
+ EXPECT_EQ("header-value", response_headers.find("header-name")->second);
+ EXPECT_EQ(1, delegate->on_data_read_count());
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ delegate->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ delegate->GetTotalReceivedBytes());
+}
+
+TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) {
+ BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
+
+ scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+ "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
+ scoped_ptr<SpdyFrame> data_frame1(
+ framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
+ scoped_ptr<SpdyFrame> data_frame2(
+ framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
+ scoped_ptr<SpdyFrame> data_frame3(
+ framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_FIN));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*data_frame1, 3),
+ CreateMockWrite(*data_frame2, 6), CreateMockWrite(*data_frame3, 9),
+ };
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
+ scoped_ptr<SpdyFrame> response_body_frame1(
+ spdy_util_.ConstructSpdyBodyFrame(1, false));
+ scoped_ptr<SpdyFrame> response_body_frame2(
+ spdy_util_.ConstructSpdyBodyFrame(1, true));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1),
+ MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
+ CreateMockRead(*response_body_frame1, 4),
+ MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
+ CreateMockRead(*response_body_frame2, 7),
+ MockRead(ASYNC, ERR_IO_PENDING, 8), // Force a pause.
+ MockRead(ASYNC, 0, 10),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "POST";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
+ base::SizeTToString(kBodyDataSize * 3));
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ MockTimer* timer = new MockTimer();
+ scoped_ptr<TestDelegateBase> delegate(new TestDelegateBase(
+ read_buffer.get(), kReadBufferSize, make_scoped_ptr(timer)));
+ delegate->set_do_not_start_read(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Send the request and receive response headers.
+ sequenced_data_->RunUntilPaused();
+ EXPECT_FALSE(timer->IsRunning());
+
+ // Send a DATA frame.
+ scoped_refptr<StringIOBuffer> buf(
+ new StringIOBuffer(std::string(kBodyData, kBodyDataSize)));
+
+ // Send a DATA frame.
+ delegate->SendData(buf.get(), buf->size(), false);
+ // ReadData and it should return asynchronously because no data is buffered.
+ int rv = delegate->ReadData();
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ // Deliver a DATA frame, and fire the timer.
+ sequenced_data_->Resume();
+ sequenced_data_->RunUntilPaused();
+ timer->Fire();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, delegate->on_data_sent_count());
+ EXPECT_EQ(1, delegate->on_data_read_count());
+
+ // Send a DATA frame.
+ delegate->SendData(buf.get(), buf->size(), false);
+ // ReadData and it should return asynchronously because no data is buffered.
+ rv = delegate->ReadData();
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ // Deliver a DATA frame, and fire the timer.
+ sequenced_data_->Resume();
+ sequenced_data_->RunUntilPaused();
+ timer->Fire();
+ base::RunLoop().RunUntilIdle();
+ // Last DATA frame is read. Server half closes.
+ EXPECT_EQ(2, delegate->on_data_read_count());
+ EXPECT_EQ(2, delegate->on_data_sent_count());
+
+ // Send the last body frame. Client half closes.
+ delegate->SendData(buf.get(), buf->size(), true);
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3, delegate->on_data_sent_count());
+
+ // OnClose is invoked since both sides are closed.
+ rv = delegate->ReadData();
+ EXPECT_EQ(OK, rv);
+
+ EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
+ EXPECT_EQ(2, delegate->on_data_read_count());
+ EXPECT_EQ(3, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ delegate->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ delegate->GetTotalReceivedBytes());
+}
+
+// Tests that BidirectionalStreamSpdyJob::OnClose will complete any remaining
+// read even if the read queue is empty.
+TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+ // Empty DATA frame with an END_STREAM flag.
+ scoped_ptr<SpdyFrame> end_stream(
+ spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
+
+ MockWrite writes[] = {CreateMockWrite(*req.get(), 0)};
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
+
+ scoped_ptr<SpdyFrame> response_body_frame(
+ spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1),
+ MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
+ CreateMockRead(*response_body_frame, 3), MockRead(SYNCHRONOUS, 0, 4),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->end_stream_on_headers = true;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ MockTimer* timer = new MockTimer();
+ scoped_ptr<TestDelegateBase> delegate(new TestDelegateBase(
+ read_buffer.get(), kReadBufferSize, make_scoped_ptr(timer)));
+ delegate->set_do_not_start_read(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Write request, and deliver response headers.
+ sequenced_data_->RunUntilPaused();
+ EXPECT_FALSE(timer->IsRunning());
+
+ // ReadData should return asynchronously because no data is buffered.
+ int rv = delegate->ReadData();
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ // Deliver END_STREAM.
+ // OnClose should trigger completion of the remaining read.
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
+ EXPECT_EQ(1, delegate->on_data_read_count());
+ EXPECT_EQ(0u, delegate->data_received().size());
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ delegate->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ delegate->GetTotalReceivedBytes());
+}
+
+TEST_F(BidirectionalStreamTest, TestBuffering) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+ // Empty DATA frame with an END_STREAM flag.
+ scoped_ptr<SpdyFrame> end_stream(
+ spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
+
+ MockWrite writes[] = {CreateMockWrite(*req.get(), 0)};
+
+ const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
+
+ scoped_ptr<SpdyFrame> body_frame(spdy_util_.ConstructSpdyBodyFrame(1, false));
+ // Last body frame has END_STREAM flag set.
+ scoped_ptr<SpdyFrame> last_body_frame(
+ spdy_util_.ConstructSpdyBodyFrame(1, true));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1),
+ CreateMockRead(*body_frame, 2),
+ CreateMockRead(*body_frame, 3),
+ MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
+ CreateMockRead(*last_body_frame, 5),
+ MockRead(SYNCHRONOUS, 0, 6),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->end_stream_on_headers = true;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ MockTimer* timer = new MockTimer();
+ scoped_ptr<TestDelegateBase> delegate(new TestDelegateBase(
+ read_buffer.get(), kReadBufferSize, make_scoped_ptr(timer)));
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Deliver two DATA frames together.
+ sequenced_data_->RunUntilPaused();
+ EXPECT_TRUE(timer->IsRunning());
+ timer->Fire();
+ base::RunLoop().RunUntilIdle();
+ // This should trigger |more_read_data_pending_| to execute the task at a
+ // later time, and Delegate::OnReadComplete should not have been called.
+ EXPECT_TRUE(timer->IsRunning());
+ EXPECT_EQ(0, delegate->on_data_read_count());
+
+ // Fire the timer now, the two DATA frame should be combined into one
+ // single Delegate::OnReadComplete callback.
+ timer->Fire();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, delegate->on_data_read_count());
+ EXPECT_EQ(kUploadDataSize * 2,
+ static_cast<int>(delegate->data_received().size()));
+
+ // Deliver last DATA frame and EOF. There will be an additional
+ // Delegate::OnReadComplete callback.
+ sequenced_data_->Resume();
+ EXPECT_EQ(2, delegate->on_data_read_count());
+ EXPECT_EQ(kUploadDataSize * 3,
+ static_cast<int>(delegate->data_received().size()));
+
+ const SpdyHeaderBlock response_headers = delegate->response_headers();
+ EXPECT_EQ("200", response_headers.find(":status")->second);
+ EXPECT_EQ("header-value", response_headers.find("header-name")->second);
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ delegate->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ delegate->GetTotalReceivedBytes());
+}
+
+TEST_F(BidirectionalStreamTest, TestBufferingWithTrailers) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+ // Empty DATA frame with an END_STREAM flag.
+ scoped_ptr<SpdyFrame> end_stream(
+ spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
+
+ MockWrite writes[] = {
+ CreateMockWrite(*req.get(), 0),
+ };
+
+ const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
+
+ scoped_ptr<SpdyFrame> body_frame(spdy_util_.ConstructSpdyBodyFrame(1, false));
+
+ const char* const kTrailers[] = {"foo", "bar"};
+ scoped_ptr<SpdyFrame> trailers(
+ spdy_util_.ConstructSpdyHeaderFrame(1, kTrailers, 1, true));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), CreateMockRead(*body_frame, 2),
+ CreateMockRead(*body_frame, 3), CreateMockRead(*body_frame, 4),
+ MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
+ CreateMockRead(*trailers, 6), MockRead(SYNCHRONOUS, 0, 7),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ MockTimer* timer = new MockTimer();
+ scoped_ptr<TestDelegateBase> delegate(new TestDelegateBase(
+ read_buffer.get(), kReadBufferSize, make_scoped_ptr(timer)));
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->end_stream_on_headers = true;
+
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Deliver all three DATA frames together.
+ sequenced_data_->RunUntilPaused();
+ EXPECT_TRUE(timer->IsRunning());
+ timer->Fire();
+ base::RunLoop().RunUntilIdle();
+ // This should trigger |more_read_data_pending_| to execute the task at a
+ // later time, and Delegate::OnReadComplete should not have been called.
+ EXPECT_TRUE(timer->IsRunning());
+ EXPECT_EQ(0, delegate->on_data_read_count());
+
+ // Deliver trailers. Remaining read should be completed, since OnClose is
+ // called right after OnTrailersReceived. The three DATA frames should be
+ // delivered in a single OnReadCompleted callback.
+ sequenced_data_->Resume();
+ EXPECT_EQ(1, delegate->on_data_read_count());
+ EXPECT_EQ(kUploadDataSize * 3,
+ static_cast<int>(delegate->data_received().size()));
+ const SpdyHeaderBlock response_headers = delegate->response_headers();
+ EXPECT_EQ("200", response_headers.find(":status")->second);
+ EXPECT_EQ("header-value", response_headers.find("header-name")->second);
+ EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ delegate->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ delegate->GetTotalReceivedBytes());
+}
+
+TEST_F(BidirectionalStreamTest, CancelStreamAfterSendData) {
+ BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
+
+ scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+ "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
+ scoped_ptr<SpdyFrame> data_frame(
+ framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*data_frame, 3),
+ CreateMockWrite(*rst, 5),
+ };
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
+ scoped_ptr<SpdyFrame> response_body_frame(
+ spdy_util_.ConstructSpdyBodyFrame(1, false));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1),
+ MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
+ MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
+ MockRead(ASYNC, 0, 6),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "POST";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
+ base::SizeTToString(kBodyDataSize * 3));
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ scoped_ptr<TestDelegateBase> delegate(
+ new TestDelegateBase(read_buffer.get(), kReadBufferSize));
+ delegate->set_do_not_start_read(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Send the request and receive response headers.
+ sequenced_data_->RunUntilPaused();
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+
+ // Send a DATA frame.
+ scoped_refptr<StringIOBuffer> buf(
+ new StringIOBuffer(std::string(kBodyData, kBodyDataSize)));
+ delegate->SendData(buf.get(), buf->size(), false);
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+ // Cancel the stream.
+ delegate->CancelStream();
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
+ EXPECT_EQ(0, delegate->on_data_read_count());
+ // EXPECT_EQ(1, delegate->on_data_send_count());
+ // OnDataSent may or may not have been invoked.
+ // Calling after stream is canceled gives kProtoUnknown.
+ EXPECT_EQ(kProtoUnknown, delegate->GetProtocol());
+ EXPECT_EQ(0, delegate->GetTotalSentBytes());
+ EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
+}
+
+TEST_F(BidirectionalStreamTest, CancelStreamDuringReadData) {
+ BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
+
+ scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+ "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
+ scoped_ptr<SpdyFrame> data_frame(
+ framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
+ };
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
+ scoped_ptr<SpdyFrame> response_body_frame(
+ spdy_util_.ConstructSpdyBodyFrame(1, false));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1),
+ MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
+ CreateMockRead(*response_body_frame, 3), MockRead(ASYNC, 0, 5),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "POST";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
+ base::SizeTToString(kBodyDataSize * 3));
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ scoped_ptr<TestDelegateBase> delegate(
+ new TestDelegateBase(read_buffer.get(), kReadBufferSize));
+ delegate->set_do_not_start_read(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Send the request and receive response headers.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
+ // Cancel the stream after ReadData returns ERR_IO_PENDING.
+ int rv = delegate->ReadData();
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ delegate->CancelStream();
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(0, delegate->on_data_read_count());
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ // Calling after stream is canceled gives kProtoUnknown.
+ EXPECT_EQ(kProtoUnknown, delegate->GetProtocol());
+ EXPECT_EQ(0, delegate->GetTotalSentBytes());
+ EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
+}
+
+// Receiving a header with uppercase ASCII will result in a protocol error,
+// which should be propagated via Delegate::OnFailed.
+TEST_F(BidirectionalStreamTest, PropagateProtocolError) {
+ scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+ "https://www.example.org", 1, kBodyDataSize * 3, LOW, nullptr, 0));
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
+
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
+ };
+
+ const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), MockRead(ASYNC, 0, 3),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "POST";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
+ base::SizeTToString(kBodyDataSize * 3));
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ scoped_ptr<TestDelegateBase> delegate(
+ new TestDelegateBase(read_buffer.get(), kReadBufferSize));
+ delegate->SetRunUntilCompletion(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, delegate->error());
+ EXPECT_EQ(delegate->response_headers().end(),
+ delegate->response_headers().find(":status"));
+ EXPECT_EQ(0, delegate->on_data_read_count());
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ // BidirectionalStreamSpdyStreamJob does not count the bytes sent for |rst|
+ // because it is sent after SpdyStream::Delegate::OnClose is called.
+ EXPECT_EQ(CountWriteBytes(writes, 1), delegate->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ delegate->GetTotalReceivedBytes());
+}
+
+INSTANTIATE_TEST_CASE_P(CancelOrDeleteTests,
+ BidirectionalStreamTest,
+ ::testing::Values(true, false));
+
+TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnHeadersReceived) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
+ };
+
+ const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), MockRead(ASYNC, 0, 3),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->end_stream_on_headers = true;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ scoped_ptr<CancelOrDeleteStreamDelegate> delegate(
+ new CancelOrDeleteStreamDelegate(
+ read_buffer.get(), kReadBufferSize,
+ CancelOrDeleteStreamDelegate::Phase::ON_HEADERS_RECEIVED,
+ GetParam()));
+ delegate->SetRunUntilCompletion(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Makes sure delegate does not get called.
+ base::RunLoop().RunUntilIdle();
+ const SpdyHeaderBlock response_headers = delegate->response_headers();
+ EXPECT_EQ("200", response_headers.find(":status")->second);
+ EXPECT_EQ("header-value", response_headers.find("header-name")->second);
+ EXPECT_EQ(0u, delegate->data_received().size());
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(0, delegate->on_data_read_count());
+
+ // If stream is destroyed, do not call into stream.
+ if (!GetParam())
+ return;
+ EXPECT_EQ(0, delegate->GetTotalSentBytes());
+ EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
+ EXPECT_EQ(kProtoUnknown, delegate->GetProtocol());
+}
+
+TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnDataRead) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3),
+ };
+
+ const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
+
+ scoped_ptr<SpdyFrame> response_body_frame(
+ spdy_util_.ConstructSpdyBodyFrame(1, false));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), CreateMockRead(*response_body_frame, 2),
+ MockRead(ASYNC, 0, 4),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->end_stream_on_headers = true;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ scoped_ptr<CancelOrDeleteStreamDelegate> delegate(
+ new CancelOrDeleteStreamDelegate(
+ read_buffer.get(), kReadBufferSize,
+ CancelOrDeleteStreamDelegate::Phase::ON_DATA_READ, GetParam()));
+ delegate->SetRunUntilCompletion(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Makes sure delegate does not get called.
+ base::RunLoop().RunUntilIdle();
+ const SpdyHeaderBlock response_headers = delegate->response_headers();
+ EXPECT_EQ("200", response_headers.find(":status")->second);
+ EXPECT_EQ("header-value", response_headers.find("header-name")->second);
+ EXPECT_EQ(kUploadDataSize * 1,
+ static_cast<int>(delegate->data_received().size()));
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+
+ // If stream is destroyed, do not call into stream.
+ if (!GetParam())
+ return;
+ EXPECT_EQ(0, delegate->GetTotalSentBytes());
+ EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
+ EXPECT_EQ(kProtoUnknown, delegate->GetProtocol());
+}
+
+TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnTrailersReceived) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
+ };
+
+ const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
+
+ scoped_ptr<SpdyFrame> response_body_frame(
+ spdy_util_.ConstructSpdyBodyFrame(1, false));
+
+ const char* const kTrailers[] = {"foo", "bar"};
+ scoped_ptr<SpdyFrame> trailers(
+ spdy_util_.ConstructSpdyHeaderFrame(1, kTrailers, 1, true));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), CreateMockRead(*response_body_frame, 2),
+ CreateMockRead(*trailers, 3), MockRead(ASYNC, 0, 5),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->end_stream_on_headers = true;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ scoped_ptr<CancelOrDeleteStreamDelegate> delegate(
+ new CancelOrDeleteStreamDelegate(
+ read_buffer.get(), kReadBufferSize,
+ CancelOrDeleteStreamDelegate::Phase::ON_TRAILERS_RECEIVED,
+ GetParam()));
+ delegate->SetRunUntilCompletion(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Makes sure delegate does not get called.
+ base::RunLoop().RunUntilIdle();
+ const SpdyHeaderBlock response_headers = delegate->response_headers();
+ EXPECT_EQ("200", response_headers.find(":status")->second);
+ EXPECT_EQ("header-value", response_headers.find("header-name")->second);
+ EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ // OnDataRead may or may not have been fired before the stream is
+ // canceled/deleted.
+
+ // If stream is destroyed, do not call into stream.
+ if (!GetParam())
+ return;
+ EXPECT_EQ(0, delegate->GetTotalSentBytes());
+ EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
+ EXPECT_EQ(kProtoUnknown, delegate->GetProtocol());
+}
+
+TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnFailed) {
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
+
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
+ };
+
+ const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
+
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), MockRead(ASYNC, 0, 3),
+ };
+
+ HostPortPair host_port_pair("www.example.org", 443);
+ SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
+
+ scoped_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = GURL("https://www.example.org/");
+ request_info->priority = LOWEST;
+ request_info->end_stream_on_headers = true;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ scoped_ptr<CancelOrDeleteStreamDelegate> delegate(
+ new CancelOrDeleteStreamDelegate(
+ read_buffer.get(), kReadBufferSize,
+ CancelOrDeleteStreamDelegate::Phase::ON_FAILED, GetParam()));
+ delegate->SetRunUntilCompletion(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+ // Makes sure delegate does not get called.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(delegate->response_headers().end(),
+ delegate->response_headers().find(":status"));
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(0, delegate->on_data_read_count());
+ EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, delegate->error());
+
+ // If stream is destroyed, do not call into stream.
+ if (!GetParam())
+ return;
+ EXPECT_EQ(0, delegate->GetTotalSentBytes());
+ EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
+ EXPECT_EQ(kProtoUnknown, delegate->GetProtocol());
+}
+
+} // namespace net
diff --git a/chromium/net/http/des.cc b/chromium/net/http/des.cc
index 874372f3873..4fce9ccd00d 100644
--- a/chromium/net/http/des.cc
+++ b/chromium/net/http/des.cc
@@ -56,7 +56,7 @@
* ***** END LICENSE BLOCK ***** */
// Set odd parity bit (in least significant bit position).
-static uint8 DESSetKeyParity(uint8 x) {
+static uint8_t DESSetKeyParity(uint8_t x) {
if ((((x >> 7) ^ (x >> 6) ^ (x >> 5) ^
(x >> 4) ^ (x >> 3) ^ (x >> 2) ^
(x >> 1)) & 0x01) == 0) {
@@ -69,7 +69,7 @@ static uint8 DESSetKeyParity(uint8 x) {
namespace net {
-void DESMakeKey(const uint8* raw, uint8* key) {
+void DESMakeKey(const uint8_t* raw, uint8_t* key) {
key[0] = DESSetKeyParity(raw[0]);
key[1] = DESSetKeyParity((raw[0] << 7) | (raw[1] >> 1));
key[2] = DESSetKeyParity((raw[1] << 6) | (raw[2] >> 2));
@@ -82,7 +82,7 @@ void DESMakeKey(const uint8* raw, uint8* key) {
#if defined(USE_OPENSSL)
-void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
+void DESEncrypt(const uint8_t* key, const uint8_t* src, uint8_t* hash) {
crypto::EnsureOpenSSLInit();
DES_key_schedule ks;
@@ -95,7 +95,7 @@ void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
#elif defined(OS_IOS)
-void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
+void DESEncrypt(const uint8_t* key, const uint8_t* src, uint8_t* hash) {
CCCryptorStatus status;
size_t data_out_moved = 0;
status = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode,
diff --git a/chromium/net/http/des.h b/chromium/net/http/des.h
index a1803ba3a39..8540d62803b 100644
--- a/chromium/net/http/des.h
+++ b/chromium/net/http/des.h
@@ -5,7 +5,8 @@
#ifndef NET_HTTP_DES_H_
#define NET_HTTP_DES_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "net/base/net_export.h"
namespace net {
@@ -16,13 +17,14 @@ namespace net {
// TODO(wtc): Turn this into a C++ API and move it to the base module.
// Build a 64-bit DES key from a 56-bit raw key.
-NET_EXPORT_PRIVATE void DESMakeKey(const uint8* raw, uint8* key);
+NET_EXPORT_PRIVATE void DESMakeKey(const uint8_t* raw, uint8_t* key);
// Run the DES encryption algorithm in ECB mode on one block (8 bytes) of
// data. |key| is a DES key (8 bytes), |src| is the input plaintext (8
// bytes), and |hash| is an 8-byte buffer receiving the output ciphertext.
-NET_EXPORT_PRIVATE void DESEncrypt(const uint8* key, const uint8* src,
- uint8* hash);
+NET_EXPORT_PRIVATE void DESEncrypt(const uint8_t* key,
+ const uint8_t* src,
+ uint8_t* hash);
} // namespace net
diff --git a/chromium/net/http/des_unittest.cc b/chromium/net/http/des_unittest.cc
index a615a084495..63172bb7e9b 100644
--- a/chromium/net/http/des_unittest.cc
+++ b/chromium/net/http/des_unittest.cc
@@ -12,17 +12,16 @@ namespace net {
// This test vector comes from the NSS FIPS power-up self-test.
TEST(DESTest, KnownAnswerTest1) {
// DES known key (56-bits).
- static const uint8 des_known_key[] = "ANSI DES";
+ static const uint8_t des_known_key[] = "ANSI DES";
// DES known plaintext (64-bits).
- static const uint8 des_ecb_known_plaintext[] = "Netscape";
+ static const uint8_t des_ecb_known_plaintext[] = "Netscape";
// DES known ciphertext (64-bits).
- static const uint8 des_ecb_known_ciphertext[] = {
- 0x26, 0x14, 0xe9, 0xc3, 0x28, 0x80, 0x50, 0xb0
- };
+ static const uint8_t des_ecb_known_ciphertext[] = {0x26, 0x14, 0xe9, 0xc3,
+ 0x28, 0x80, 0x50, 0xb0};
- uint8 ciphertext[8];
+ uint8_t ciphertext[8];
memset(ciphertext, 0xaf, sizeof(ciphertext));
DESEncrypt(des_known_key, des_ecb_known_plaintext, ciphertext);
@@ -33,14 +32,11 @@ TEST(DESTest, KnownAnswerTest1) {
// Operation Validation System (MOVS): Requirements and Procedures, Appendix
// A, page 124.
TEST(DESTest, KnownAnswerTest2) {
- static const uint8 key[] = {
- 0x10, 0x31, 0x6e, 0x02, 0x8c, 0x8f, 0x3b, 0x4a
- };
- static const uint8 plaintext[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static const uint8 known_ciphertext[] = {
- 0x82, 0xdc, 0xba, 0xfb, 0xde, 0xab, 0x66, 0x02
- };
- uint8 ciphertext[8];
+ static const uint8_t key[] = {0x10, 0x31, 0x6e, 0x02, 0x8c, 0x8f, 0x3b, 0x4a};
+ static const uint8_t plaintext[] = {0, 0, 0, 0, 0, 0, 0, 0};
+ static const uint8_t known_ciphertext[] = {0x82, 0xdc, 0xba, 0xfb,
+ 0xde, 0xab, 0x66, 0x02};
+ uint8_t ciphertext[8];
memset(ciphertext, 0xaf, sizeof(ciphertext));
DESEncrypt(key, plaintext, ciphertext);
diff --git a/chromium/net/http/disk_based_cert_cache.h b/chromium/net/http/disk_based_cert_cache.h
index 347d2f0bb1d..7c9edec01c5 100644
--- a/chromium/net/http/disk_based_cert_cache.h
+++ b/chromium/net/http/disk_based_cert_cache.h
@@ -5,11 +5,14 @@
#ifndef NET_HTTP_DISK_BASED_CERT_CACHE_H
#define NET_HTTP_DISK_BASED_CERT_CACHE_H
+#include <stddef.h>
+
#include <string>
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/containers/mru_cache.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
diff --git a/chromium/net/http/disk_cache_based_quic_server_info.cc b/chromium/net/http/disk_cache_based_quic_server_info.cc
index d019f9b3501..2ba6cf8e0dc 100644
--- a/chromium/net/http/disk_cache_based_quic_server_info.cc
+++ b/chromium/net/http/disk_cache_based_quic_server_info.cc
@@ -326,7 +326,7 @@ int DiskCacheBasedQuicServerInfo::DoOpen() {
}
int DiskCacheBasedQuicServerInfo::DoRead() {
- const int32 size = entry_->GetDataSize(0 /* index */);
+ const int32_t size = entry_->GetDataSize(0 /* index */);
if (!size) {
state_ = WAIT_FOR_DATA_READY_DONE;
return OK;
diff --git a/chromium/net/http/disk_cache_based_quic_server_info.h b/chromium/net/http/disk_cache_based_quic_server_info.h
index 3076f3aa496..9403d6f4687 100644
--- a/chromium/net/http/disk_cache_based_quic_server_info.h
+++ b/chromium/net/http/disk_cache_based_quic_server_info.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
diff --git a/chromium/net/http/disk_cache_based_quic_server_info_unittest.cc b/chromium/net/http/disk_cache_based_quic_server_info_unittest.cc
index d51bab78036..6f6425ea175 100644
--- a/chromium/net/http/disk_cache_based_quic_server_info_unittest.cc
+++ b/chromium/net/http/disk_cache_based_quic_server_info_unittest.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "net/base/net_errors.h"
#include "net/http/mock_http_cache.h"
@@ -39,7 +40,7 @@ const MockTransaction kHostInfoTransaction1 = {
};
const MockTransaction kHostInfoTransaction2 = {
- "quicserverinfo:http://www.google.com:80",
+ "quicserverinfo:https://www.google.com:80",
"",
base::Time(),
"",
@@ -85,8 +86,8 @@ TEST(DiskCacheBasedQuicServerInfo, DeleteInCallback) {
// Use the blocking mock backend factory to force asynchronous completion
// of quic_server_info->WaitForDataReady(), so that the callback will run.
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(factory);
- QuicServerId server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED);
+ MockHttpCache cache(make_scoped_ptr(factory));
+ QuicServerId server_id("www.verisign.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
quic_server_info->Start();
@@ -104,7 +105,7 @@ TEST(DiskCacheBasedQuicServerInfo, Update) {
AddMockTransaction(&kHostInfoTransaction1);
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
quic_server_info->Start();
@@ -171,7 +172,7 @@ TEST(DiskCacheBasedQuicServerInfo, UpdateDifferentPorts) {
TestCompletionCallback callback;
// Persist data for port 443.
- QuicServerId server_id1("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id1("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info1(
new DiskCacheBasedQuicServerInfo(server_id1, cache.http_cache()));
quic_server_info1->Start();
@@ -195,7 +196,7 @@ TEST(DiskCacheBasedQuicServerInfo, UpdateDifferentPorts) {
base::MessageLoop::current()->RunUntilIdle();
// Persist data for port 80.
- QuicServerId server_id2("www.google.com", 80, false, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id2("www.google.com", 80, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info2(
new DiskCacheBasedQuicServerInfo(server_id2, cache.http_cache()));
quic_server_info2->Start();
@@ -258,7 +259,7 @@ TEST(DiskCacheBasedQuicServerInfo, IsReadyToPersist) {
AddMockTransaction(&kHostInfoTransaction1);
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -314,7 +315,7 @@ TEST(DiskCacheBasedQuicServerInfo, MultiplePersist) {
AddMockTransaction(&kHostInfoTransaction1);
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -390,9 +391,9 @@ TEST(DiskCacheBasedQuicServerInfo, MultiplePersist) {
TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReady) {
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(factory);
+ MockHttpCache cache(make_scoped_ptr(factory));
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -412,7 +413,7 @@ TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyButDataIsReady) {
AddMockTransaction(&kHostInfoTransaction1);
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -431,7 +432,7 @@ TEST(DiskCacheBasedQuicServerInfo, CancelWaitForDataReadyAfterDeleteCache) {
AddMockTransaction(&kHostInfoTransaction1);
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
quic_server_info.reset(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -451,7 +452,7 @@ TEST(DiskCacheBasedQuicServerInfo, StartAndPersist) {
MockHttpCache cache;
AddMockTransaction(&kHostInfoTransaction1);
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -508,11 +509,11 @@ TEST(DiskCacheBasedQuicServerInfo, StartAndPersist) {
// persists the data when Start() finishes.
TEST(DiskCacheBasedQuicServerInfo, PersistWhenNotReadyToPersist) {
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(factory);
+ MockHttpCache cache(make_scoped_ptr(factory));
AddMockTransaction(&kHostInfoTransaction1);
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -567,7 +568,7 @@ TEST(DiskCacheBasedQuicServerInfo, MultiplePersistsWithoutWaiting) {
AddMockTransaction(&kHostInfoTransaction1);
TestCompletionCallback callback;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
scoped_ptr<QuicServerInfo> quic_server_info(
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache()));
EXPECT_FALSE(quic_server_info->IsDataReady());
@@ -639,8 +640,8 @@ TEST(DiskCacheBasedQuicServerInfo, DeleteServerInfoInCallback) {
// Use the blocking mock backend factory to force asynchronous completion
// of quic_server_info->WaitForDataReady(), so that the callback will run.
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(factory);
- QuicServerId server_id("www.verisign.com", 443, true, PRIVACY_MODE_DISABLED);
+ MockHttpCache cache(make_scoped_ptr(factory));
+ QuicServerId server_id("www.verisign.com", 443, PRIVACY_MODE_DISABLED);
QuicServerInfo* quic_server_info =
new DiskCacheBasedQuicServerInfo(server_id, cache.http_cache());
// |cb| takes owndership and deletes |quic_server_info| when it is called.
diff --git a/chromium/net/http/failing_http_transaction_factory.cc b/chromium/net/http/failing_http_transaction_factory.cc
index adb96914ad0..be824076278 100644
--- a/chromium/net/http/failing_http_transaction_factory.cc
+++ b/chromium/net/http/failing_http_transaction_factory.cc
@@ -13,6 +13,7 @@
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/load_timing_info.h"
+#include "net/base/net_error_details.h"
#include "net/base/upload_progress.h"
#include "net/http/http_response_info.h"
#include "net/socket/connection_attempts.h"
@@ -23,6 +24,7 @@ class AuthCredentials;
class BoundNetLog;
class HttpRequestHeaders;
class IOBuffer;
+class SSLPrivateKey;
class X509Certificate;
namespace {
@@ -41,6 +43,7 @@ class FailingHttpTransaction : public HttpTransaction {
const BoundNetLog& net_log) override;
int RestartIgnoringLastError(const CompletionCallback& callback) override;
int RestartWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
const CompletionCallback& callback) override;
int RestartWithAuth(const AuthCredentials& credentials,
const CompletionCallback& callback) override;
@@ -59,6 +62,7 @@ class FailingHttpTransaction : public HttpTransaction {
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) const override;
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -95,7 +99,8 @@ int FailingHttpTransaction::RestartIgnoringLastError(
int FailingHttpTransaction::RestartWithCertificate(
X509Certificate* client_cert,
- const CompletionCallback& callback) {
+ SSLPrivateKey* client_private_key,
+ const CompletionCallback& callback) {
return ERR_FAILED;
}
@@ -122,7 +127,7 @@ bool FailingHttpTransaction::GetFullRequestHeaders(
return false;
}
-int64 FailingHttpTransaction::GetTotalReceivedBytes() const {
+int64_t FailingHttpTransaction::GetTotalReceivedBytes() const {
return 0;
}
@@ -159,6 +164,11 @@ bool FailingHttpTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
return false;
}
+void FailingHttpTransaction::PopulateNetErrorDetails(
+ NetErrorDetails* /*details*/) const {
+ return;
+}
+
void FailingHttpTransaction::SetPriority(RequestPriority priority) {}
void FailingHttpTransaction::SetWebSocketHandshakeStreamCreateHelper(
@@ -211,4 +221,3 @@ HttpNetworkSession* FailingHttpTransactionFactory::GetSession() {
}
} // namespace net
-
diff --git a/chromium/net/http/http_auth.cc b/chromium/net/http/http_auth.cc
index 7752d743a22..15768a05fd4 100644
--- a/chromium/net/http/http_auth.cc
+++ b/chromium/net/http/http_auth.cc
@@ -6,13 +6,13 @@
#include <algorithm>
-#include "base/basictypes.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_auth_scheme.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
@@ -131,13 +131,8 @@ std::string HttpAuth::GetAuthTargetString(Target target) {
// static
const char* HttpAuth::SchemeToString(Scheme scheme) {
static const char* const kSchemeNames[] = {
- "basic",
- "digest",
- "ntlm",
- "negotiate",
- "spdyproxy",
- "mock",
- };
+ kBasicAuthScheme, kDigestAuthScheme, kNtlmAuthScheme,
+ kNegotiateAuthScheme, kSpdyProxyAuthScheme, kMockAuthScheme};
static_assert(arraysize(kSchemeNames) == AUTH_SCHEME_MAX,
"http auth scheme names incorrect size");
if (scheme < AUTH_SCHEME_BASIC || scheme >= AUTH_SCHEME_MAX) {
diff --git a/chromium/net/http/http_auth_cache.h b/chromium/net/http/http_auth_cache.h
index f05f8184d02..53b998f7ffb 100644
--- a/chromium/net/http/http_auth_cache.h
+++ b/chromium/net/http/http_auth_cache.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_HTTP_AUTH_CACHE_H_
#define NET_HTTP_HTTP_AUTH_CACHE_H_
+#include <stddef.h>
+
#include <list>
#include <string>
diff --git a/chromium/net/http/http_auth_controller.cc b/chromium/net/http/http_auth_controller.cc
index 4d9d6be1f0d..294bde0b72f 100644
--- a/chromium/net/http/http_auth_controller.cc
+++ b/chromium/net/http/http_auth_controller.cc
@@ -11,7 +11,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "net/base/auth.h"
-#include "net/base/net_util.h"
+#include "net/base/url_util.h"
#include "net/dns/host_resolver.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
diff --git a/chromium/net/http/http_auth_controller.h b/chromium/net/http/http_auth_controller.h
index 2df9d57274d..b7d6e94d394 100644
--- a/chromium/net/http/http_auth_controller.h
+++ b/chromium/net/http/http_auth_controller.h
@@ -8,7 +8,6 @@
#include <set>
#include <string>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
diff --git a/chromium/net/http/http_auth_filter.h b/chromium/net/http/http_auth_filter.h
index 260da47c16d..345149dd460 100644
--- a/chromium/net/http/http_auth_filter.h
+++ b/chromium/net/http/http_auth_filter.h
@@ -8,6 +8,7 @@
#include <list>
#include <string>
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/http/http_auth.h"
#include "net/proxy/proxy_bypass_rules.h"
diff --git a/chromium/net/http/http_auth_filter_unittest.cc b/chromium/net/http/http_auth_filter_unittest.cc
index 25723c136a3..a23d73b8b17 100644
--- a/chromium/net/http/http_auth_filter_unittest.cc
+++ b/chromium/net/http/http_auth_filter_unittest.cc
@@ -4,7 +4,6 @@
#include <ostream>
-
#include "base/memory/scoped_ptr.h"
#include "net/http/http_auth_filter.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/http/http_auth_gssapi_posix.cc b/chromium/net/http/http_auth_gssapi_posix.cc
index 0b87b33a137..1c3352c92dc 100644
--- a/chromium/net/http/http_auth_gssapi_posix.cc
+++ b/chromium/net/http/http_auth_gssapi_posix.cc
@@ -11,6 +11,7 @@
#include "base/files/file_path.h"
#include "base/format_macros.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
@@ -430,8 +431,7 @@ base::NativeLibrary GSSAPISharedLibrary::LoadSharedLibrary() {
} else {
static const char* const kDefaultLibraryNames[] = {
#if defined(OS_MACOSX)
- // This library is provided by Kerberos.framework.
- "libgssapi_krb5.dylib"
+ "/System/Library/Frameworks/Kerberos.framework/Kerberos"
#elif defined(OS_OPENBSD)
"libgssapi.so" // Heimdal - OpenBSD
#else
@@ -452,12 +452,16 @@ base::NativeLibrary GSSAPISharedLibrary::LoadSharedLibrary() {
// TODO(asanka): Move library loading to a separate thread.
// http://crbug.com/66702
base::ThreadRestrictions::ScopedAllowIO allow_io_temporarily;
- base::NativeLibrary lib = base::LoadNativeLibrary(file_path, NULL);
+ base::NativeLibraryLoadError load_error;
+ base::NativeLibrary lib = base::LoadNativeLibrary(file_path, &load_error);
if (lib) {
// Only return this library if we can bind the functions we need.
if (BindMethods(lib))
return lib;
base::UnloadNativeLibrary(lib);
+ } else {
+ // If this is the only library available, log the reason for failure.
+ LOG_IF(WARNING, num_lib_names == 1) << load_error.ToString();
}
}
LOG(WARNING) << "Unable to find a compatible GSSAPI library";
diff --git a/chromium/net/http/http_auth_gssapi_posix.h b/chromium/net/http/http_auth_gssapi_posix.h
index 73502c9b435..cf4dcd50f35 100644
--- a/chromium/net/http/http_auth_gssapi_posix.h
+++ b/chromium/net/http/http_auth_gssapi_posix.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/native_library.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/http/http_auth_gssapi_posix_unittest.cc b/chromium/net/http/http_auth_gssapi_posix_unittest.cc
index 79a248f893d..6334fbef9ff 100644
--- a/chromium/net/http/http_auth_gssapi_posix_unittest.cc
+++ b/chromium/net/http/http_auth_gssapi_posix_unittest.cc
@@ -4,7 +4,6 @@
#include "net/http/http_auth_gssapi_posix.h"
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/native_library.h"
diff --git a/chromium/net/http/http_auth_handler_basic.cc b/chromium/net/http/http_auth_handler_basic.cc
index 27b892bb016..45367857297 100644
--- a/chromium/net/http/http_auth_handler_basic.cc
+++ b/chromium/net/http/http_auth_handler_basic.cc
@@ -13,6 +13,7 @@
#include "net/base/net_string_util.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_challenge_tokenizer.h"
+#include "net/http/http_auth_scheme.h"
namespace net {
@@ -62,7 +63,7 @@ bool HttpAuthHandlerBasic::Init(HttpAuthChallengeTokenizer* challenge) {
bool HttpAuthHandlerBasic::ParseChallenge(
HttpAuthChallengeTokenizer* challenge) {
// Verify the challenge's auth-scheme.
- if (!base::LowerCaseEqualsASCII(challenge->scheme(), "basic"))
+ if (!base::LowerCaseEqualsASCII(challenge->scheme(), kBasicAuthScheme))
return false;
std::string realm;
diff --git a/chromium/net/http/http_auth_handler_basic_unittest.cc b/chromium/net/http/http_auth_handler_basic_unittest.cc
index 60e588291ca..e6a9818aac3 100644
--- a/chromium/net/http/http_auth_handler_basic_unittest.cc
+++ b/chromium/net/http/http_auth_handler_basic_unittest.cc
@@ -4,7 +4,6 @@
#include <string>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chromium/net/http/http_auth_handler_digest.cc b/chromium/net/http/http_auth_handler_digest.cc
index a5f96b1e25f..14c9ecded01 100644
--- a/chromium/net/http/http_auth_handler_digest.cc
+++ b/chromium/net/http/http_auth_handler_digest.cc
@@ -17,6 +17,7 @@
#include "net/base/net_util.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_challenge_tokenizer.h"
+#include "net/http/http_auth_scheme.h"
#include "net/http/http_request_info.h"
#include "net/http/http_util.h"
#include "url/gurl.h"
@@ -113,7 +114,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerDigest::HandleAnotherChallenge(
// to differentiate between stale and rejected responses.
// Note that the state of the current handler is not mutated - this way if
// there is a rejection the realm hasn't changed.
- if (!base::LowerCaseEqualsASCII(challenge->scheme(), "digest"))
+ if (!base::LowerCaseEqualsASCII(challenge->scheme(), kDigestAuthScheme))
return HttpAuth::AUTHORIZATION_RESULT_INVALID;
HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
@@ -199,7 +200,7 @@ bool HttpAuthHandlerDigest::ParseChallenge(
realm_ = original_realm_ = nonce_ = domain_ = opaque_ = std::string();
// FAIL -- Couldn't match auth-scheme.
- if (!base::LowerCaseEqualsASCII(challenge->scheme(), "digest"))
+ if (!base::LowerCaseEqualsASCII(challenge->scheme(), kDigestAuthScheme))
return false;
HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
diff --git a/chromium/net/http/http_auth_handler_digest.h b/chromium/net/http/http_auth_handler_digest.h
index dbe02b4f2da..27cdfcd0ab0 100644
--- a/chromium/net/http/http_auth_handler_digest.h
+++ b/chromium/net/http/http_auth_handler_digest.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/http/http_auth_handler.h"
diff --git a/chromium/net/http/http_auth_handler_digest_unittest.cc b/chromium/net/http/http_auth_handler_digest_unittest.cc
index 8b5179e1926..89f30109a39 100644
--- a/chromium/net/http/http_auth_handler_digest_unittest.cc
+++ b/chromium/net/http/http_auth_handler_digest_unittest.cc
@@ -4,7 +4,6 @@
#include <string>
-#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
diff --git a/chromium/net/http/http_auth_handler_factory.cc b/chromium/net/http/http_auth_handler_factory.cc
index 5a89964a80c..c03792f1e93 100644
--- a/chromium/net/http/http_auth_handler_factory.cc
+++ b/chromium/net/http/http_auth_handler_factory.cc
@@ -12,6 +12,8 @@
#include "net/http/http_auth_handler_basic.h"
#include "net/http/http_auth_handler_digest.h"
#include "net/http/http_auth_handler_ntlm.h"
+#include "net/http/http_auth_preferences.h"
+#include "net/http/http_auth_scheme.h"
#if defined(USE_KERBEROS)
#include "net/http/http_auth_handler_negotiate.h"
@@ -42,79 +44,81 @@ int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString(
digest_nonce_count, net_log, handler);
}
-// static
-scoped_ptr<HttpAuthHandlerRegistryFactory>
-HttpAuthHandlerFactory::CreateDefault(HostResolver* host_resolver) {
- DCHECK(host_resolver);
- scoped_ptr<HttpAuthHandlerRegistryFactory> registry_factory =
- make_scoped_ptr(new HttpAuthHandlerRegistryFactory());
- registry_factory->RegisterSchemeFactory(
- "basic", new HttpAuthHandlerBasic::Factory());
- registry_factory->RegisterSchemeFactory(
- "digest", new HttpAuthHandlerDigest::Factory());
-
-// On Android Chrome needs an account type configured to enable Kerberos,
-// so the default factory should not include Kerberos.
+namespace {
+
+const char* const kDefaultAuthSchemes[] = {kBasicAuthScheme, kDigestAuthScheme,
#if defined(USE_KERBEROS) && !defined(OS_ANDROID)
- HttpAuthHandlerNegotiate::Factory* negotiate_factory =
- new HttpAuthHandlerNegotiate::Factory();
-#if defined(OS_POSIX)
- negotiate_factory->set_library(new GSSAPISharedLibrary(std::string()));
-#elif defined(OS_WIN)
- negotiate_factory->set_library(new SSPILibraryDefault());
+ kNegotiateAuthScheme,
#endif
- negotiate_factory->set_host_resolver(host_resolver);
- registry_factory->RegisterSchemeFactory("negotiate", negotiate_factory);
-#endif // defined(USE_KERBEROS) && !defined(OS_ANDROID)
-
- HttpAuthHandlerNTLM::Factory* ntlm_factory =
- new HttpAuthHandlerNTLM::Factory();
+ kNtlmAuthScheme};
+
+// Create a registry factory. Note that |prefs| may be a temporary, and
+// should only be used to create the factories. It should not be passed
+// to the registry factory or its children as the preferences they should
+// use.
+scoped_ptr<HttpAuthHandlerRegistryFactory> CreateAuthHandlerRegistryFactory(
+ const HttpAuthPreferences& prefs,
+ HostResolver* host_resolver) {
+ scoped_ptr<HttpAuthHandlerRegistryFactory> registry_factory(
+ new HttpAuthHandlerRegistryFactory());
+ if (prefs.IsSupportedScheme(kBasicAuthScheme))
+ registry_factory->RegisterSchemeFactory(
+ kBasicAuthScheme, new HttpAuthHandlerBasic::Factory());
+ if (prefs.IsSupportedScheme(kDigestAuthScheme))
+ registry_factory->RegisterSchemeFactory(
+ kDigestAuthScheme, new HttpAuthHandlerDigest::Factory());
+ if (prefs.IsSupportedScheme(kNtlmAuthScheme)) {
+ HttpAuthHandlerNTLM::Factory* ntlm_factory =
+ new HttpAuthHandlerNTLM::Factory();
#if defined(OS_WIN)
- ntlm_factory->set_sspi_library(new SSPILibraryDefault());
-#endif
- registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory);
+ ntlm_factory->set_sspi_library(new SSPILibraryDefault());
+#endif // defined(OS_WIN)
+ registry_factory->RegisterSchemeFactory(kNtlmAuthScheme, ntlm_factory);
+ }
+#if defined(USE_KERBEROS)
+ if (prefs.IsSupportedScheme(kNegotiateAuthScheme)) {
+ DCHECK(host_resolver);
+ HttpAuthHandlerNegotiate::Factory* negotiate_factory =
+ new HttpAuthHandlerNegotiate::Factory();
+#if defined(OS_WIN)
+ negotiate_factory->set_library(make_scoped_ptr(new SSPILibraryDefault()));
+#elif defined(OS_POSIX) && !defined(OS_ANDROID)
+ negotiate_factory->set_library(
+ make_scoped_ptr(new GSSAPISharedLibrary(prefs.GssapiLibraryName())));
+#endif // defined(OS_POSIX) && !defined(OS_ANDROID)
+ negotiate_factory->set_host_resolver(host_resolver);
+ registry_factory->RegisterSchemeFactory(kNegotiateAuthScheme,
+ negotiate_factory);
+ }
+#endif // defined(USE_KERBEROS)
return registry_factory;
}
-namespace {
-
-bool IsSupportedScheme(const std::vector<std::string>& supported_schemes,
- const std::string& scheme) {
- std::vector<std::string>::const_iterator it = std::find(
- supported_schemes.begin(), supported_schemes.end(), scheme);
- return it != supported_schemes.end();
-}
-
} // namespace
HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory() {
}
HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() {
- STLDeleteContainerPairSecondPointers(factory_map_.begin(),
- factory_map_.end());
}
-void HttpAuthHandlerRegistryFactory::SetURLSecurityManager(
+void HttpAuthHandlerRegistryFactory::SetHttpAuthPreferences(
const std::string& scheme,
- URLSecurityManager* security_manager) {
+ const HttpAuthPreferences* prefs) {
HttpAuthHandlerFactory* factory = GetSchemeFactory(scheme);
if (factory)
- factory->set_url_security_manager(security_manager);
+ factory->set_http_auth_preferences(prefs);
}
void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory(
const std::string& scheme,
HttpAuthHandlerFactory* factory) {
+ factory->set_http_auth_preferences(http_auth_preferences());
std::string lower_scheme = base::ToLowerASCII(scheme);
- FactoryMap::iterator it = factory_map_.find(lower_scheme);
- if (it != factory_map_.end()) {
- delete it->second;
- }
if (factory)
- factory_map_[lower_scheme] = factory;
+ factory_map_[lower_scheme] = make_scoped_ptr(factory);
else
- factory_map_.erase(it);
+ factory_map_.erase(lower_scheme);
}
HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory(
@@ -124,56 +128,33 @@ HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory(
if (it == factory_map_.end()) {
return NULL; // |scheme| is not registered.
}
- return it->second;
+ return it->second.get();
}
// static
-HttpAuthHandlerRegistryFactory* HttpAuthHandlerRegistryFactory::Create(
- const std::vector<std::string>& supported_schemes,
- URLSecurityManager* security_manager,
- HostResolver* host_resolver,
- const std::string& gssapi_library_name,
- const std::string& auth_android_negotiate_account_type,
- bool negotiate_disable_cname_lookup,
- bool negotiate_enable_port) {
- HttpAuthHandlerRegistryFactory* registry_factory =
- new HttpAuthHandlerRegistryFactory();
- if (IsSupportedScheme(supported_schemes, "basic"))
- registry_factory->RegisterSchemeFactory(
- "basic", new HttpAuthHandlerBasic::Factory());
- if (IsSupportedScheme(supported_schemes, "digest"))
- registry_factory->RegisterSchemeFactory(
- "digest", new HttpAuthHandlerDigest::Factory());
- if (IsSupportedScheme(supported_schemes, "ntlm")) {
- HttpAuthHandlerNTLM::Factory* ntlm_factory =
- new HttpAuthHandlerNTLM::Factory();
- ntlm_factory->set_url_security_manager(security_manager);
-#if defined(OS_WIN)
- ntlm_factory->set_sspi_library(new SSPILibraryDefault());
-#endif
- registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory);
- }
-#if defined(USE_KERBEROS)
- if (IsSupportedScheme(supported_schemes, "negotiate")) {
- HttpAuthHandlerNegotiate::Factory* negotiate_factory =
- new HttpAuthHandlerNegotiate::Factory();
-#if defined(OS_ANDROID)
- negotiate_factory->set_library(&auth_android_negotiate_account_type);
-#elif defined(OS_POSIX)
- negotiate_factory->set_library(
- new GSSAPISharedLibrary(gssapi_library_name));
-#elif defined(OS_WIN)
- negotiate_factory->set_library(new SSPILibraryDefault());
+scoped_ptr<HttpAuthHandlerRegistryFactory>
+HttpAuthHandlerFactory::CreateDefault(HostResolver* host_resolver) {
+ std::vector<std::string> auth_types(std::begin(kDefaultAuthSchemes),
+ std::end(kDefaultAuthSchemes));
+ HttpAuthPreferences prefs(auth_types
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ std::string()
#endif
- negotiate_factory->set_url_security_manager(security_manager);
- DCHECK(host_resolver || negotiate_disable_cname_lookup);
- negotiate_factory->set_host_resolver(host_resolver);
- negotiate_factory->set_disable_cname_lookup(negotiate_disable_cname_lookup);
- negotiate_factory->set_use_port(negotiate_enable_port);
- registry_factory->RegisterSchemeFactory("negotiate", negotiate_factory);
- }
-#endif // defined(USE_KERBEROS)
+ );
+ return CreateAuthHandlerRegistryFactory(prefs, host_resolver);
+}
+// static
+scoped_ptr<HttpAuthHandlerRegistryFactory>
+HttpAuthHandlerRegistryFactory::Create(const HttpAuthPreferences* prefs,
+ HostResolver* host_resolver) {
+ scoped_ptr<HttpAuthHandlerRegistryFactory> registry_factory(
+ CreateAuthHandlerRegistryFactory(*prefs, host_resolver));
+ registry_factory->set_http_auth_preferences(prefs);
+ for (auto& factory_entry : registry_factory->factory_map_) {
+ factory_entry.second->set_http_auth_preferences(prefs);
+ }
return registry_factory;
}
diff --git a/chromium/net/http/http_auth_handler_factory.h b/chromium/net/http/http_auth_handler_factory.h
index 1261bedd567..a98f9d7f4b1 100644
--- a/chromium/net/http/http_auth_handler_factory.h
+++ b/chromium/net/http/http_auth_handler_factory.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/http/http_auth.h"
@@ -19,6 +20,7 @@ class GURL;
namespace net {
class BoundNetLog;
+class HttpAuthPreferences;
class HostResolver;
class HttpAuthChallengeTokenizer;
class HttpAuthHandler;
@@ -34,18 +36,21 @@ class NET_EXPORT HttpAuthHandlerFactory {
CREATE_PREEMPTIVE, // Create a handler preemptively.
};
- HttpAuthHandlerFactory() : url_security_manager_(NULL) {}
+ HttpAuthHandlerFactory() : http_auth_preferences_(NULL) {}
virtual ~HttpAuthHandlerFactory() {}
- // Sets an URL security manager. HttpAuthHandlerFactory doesn't own the URL
- // security manager, and the URL security manager should outlive this object.
- void set_url_security_manager(URLSecurityManager* url_security_manager) {
- url_security_manager_ = url_security_manager;
+ // Sets the source of the HTTP authentication preferences.
+ // HttpAuthHandlerFactory doesn't own the preferences, and the
+ // HttpAuthPreferences object should outlive the factory and any handlers it
+ // creates.
+ void set_http_auth_preferences(
+ const HttpAuthPreferences* http_auth_preferences) {
+ http_auth_preferences_ = http_auth_preferences;
}
// Retrieves the associated URL security manager.
- URLSecurityManager* url_security_manager() {
- return url_security_manager_;
+ const HttpAuthPreferences* http_auth_preferences() {
+ return http_auth_preferences_;
}
// Creates an HttpAuthHandler object based on the authentication
@@ -119,8 +124,8 @@ class NET_EXPORT HttpAuthHandlerFactory {
HostResolver* resolver);
private:
- // The URL security manager
- URLSecurityManager* url_security_manager_;
+ // The preferences for HTTP authentication.
+ const HttpAuthPreferences* http_auth_preferences_;
DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerFactory);
};
@@ -133,9 +138,9 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory
HttpAuthHandlerRegistryFactory();
~HttpAuthHandlerRegistryFactory() override;
- // Sets an URL security manager into the factory associated with |scheme|.
- void SetURLSecurityManager(const std::string& scheme,
- URLSecurityManager* url_security_manager);
+ // Sets the preferences into the factory associated with |scheme|.
+ void SetHttpAuthPreferences(const std::string& scheme,
+ const HttpAuthPreferences* prefs);
// Registers a |factory| that will be used for a particular HTTP
// authentication scheme such as Basic, Digest, or Negotiate.
@@ -157,37 +162,17 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory
// Creates an HttpAuthHandlerRegistryFactory.
//
- // |supported_schemes| is a list of authentication schemes. Valid values
- // include "basic", "digest", "ntlm", and "negotiate", where case matters.
- //
- // |security_manager| is used by the NTLM and Negotiate authenticators
- // to determine which servers Integrated Authentication can be used with. If
- // NULL, Integrated Authentication will not be used with any server.
+ // |prefs| is a pointer to the (single) authentication preferences object.
+ // That object tracks preference, and hence policy, updates relevant to HTTP
+ // authentication, and provides the current values of the preferences.
//
// |host_resolver| is used by the Negotiate authentication handler to perform
// CNAME lookups to generate a Kerberos SPN for the server. If the "negotiate"
// scheme is used and |negotiate_disable_cname_lookup| is false,
// |host_resolver| must not be NULL.
- //
- // |gssapi_library_name| specifies the name of the GSSAPI library that will
- // be loaded on Posix platforms other than Android. |gssapi_library_name| is
- // ignored on Android and Windows.
- //
- // |auth_android_negotiate_account_type| is an Android account type, used to
- // find the appropriate authenticator service on Android. It is ignored on
- // non-Android platforms.
- //
- // |negotiate_disable_cname_lookup| and |negotiate_enable_port| both control
- // how Negotiate does SPN generation, by default these should be false.
- static HttpAuthHandlerRegistryFactory* Create(
- const std::vector<std::string>& supported_schemes,
- URLSecurityManager* security_manager,
- HostResolver* host_resolver,
- const std::string& gssapi_library_name,
- const std::string& auth_android_negotiate_account_type,
- bool negotiate_disable_cname_lookup,
- bool negotiate_enable_port);
-
+ static scoped_ptr<HttpAuthHandlerRegistryFactory> Create(
+ const HttpAuthPreferences* prefs,
+ HostResolver* host_resolver);
// Creates an auth handler by dispatching out to the registered factories
// based on the first token in |challenge|.
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
@@ -199,7 +184,7 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory
scoped_ptr<HttpAuthHandler>* handler) override;
private:
- typedef std::map<std::string, HttpAuthHandlerFactory*> FactoryMap;
+ using FactoryMap = std::map<std::string, scoped_ptr<HttpAuthHandlerFactory>>;
FactoryMap factory_map_;
DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerRegistryFactory);
diff --git a/chromium/net/http/http_auth_handler_factory_unittest.cc b/chromium/net/http/http_auth_handler_factory_unittest.cc
index be0c3b0b54b..b73e47b8961 100644
--- a/chromium/net/http/http_auth_handler_factory_unittest.cc
+++ b/chromium/net/http/http_auth_handler_factory_unittest.cc
@@ -7,7 +7,8 @@
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
-#include "net/http/mock_allow_url_security_manager.h"
+#include "net/http/http_auth_scheme.h"
+#include "net/http/mock_allow_http_auth_preferences.h"
#include "net/http/url_security_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -98,11 +99,11 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) {
TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
scoped_ptr<HostResolver> host_resolver(new MockHostResolver());
- MockAllowURLSecurityManager url_security_manager;
+ MockAllowHttpAuthPreferences http_auth_preferences;
scoped_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory(
HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
- http_auth_handler_factory->SetURLSecurityManager(
- "negotiate", &url_security_manager);
+ http_auth_handler_factory->SetHttpAuthPreferences(kNegotiateAuthScheme,
+ &http_auth_preferences);
GURL server_origin("http://www.example.com");
GURL proxy_origin("http://cache.example.com:3128");
{
diff --git a/chromium/net/http/http_auth_handler_mock.cc b/chromium/net/http/http_auth_handler_mock.cc
index f800c192ac4..04a09e4d6b1 100644
--- a/chromium/net/http/http_auth_handler_mock.cc
+++ b/chromium/net/http/http_auth_handler_mock.cc
@@ -161,7 +161,7 @@ HttpAuthHandlerMock::Factory::~Factory() {
void HttpAuthHandlerMock::Factory::AddMockHandler(
HttpAuthHandler* handler, HttpAuth::Target target) {
- handlers_[target].push_back(handler);
+ handlers_[target].push_back(make_scoped_ptr(handler));
}
int HttpAuthHandlerMock::Factory::CreateAuthHandler(
@@ -174,8 +174,8 @@ int HttpAuthHandlerMock::Factory::CreateAuthHandler(
scoped_ptr<HttpAuthHandler>* handler) {
if (handlers_[target].empty())
return ERR_UNEXPECTED;
- scoped_ptr<HttpAuthHandler> tmp_handler(handlers_[target][0]);
- std::vector<HttpAuthHandler*>& handlers = handlers_[target].get();
+ scoped_ptr<HttpAuthHandler> tmp_handler = std::move(handlers_[target][0]);
+ std::vector<scoped_ptr<HttpAuthHandler>>& handlers = handlers_[target];
handlers.erase(handlers.begin());
if (do_init_from_challenge_ &&
!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
diff --git a/chromium/net/http/http_auth_handler_mock.h b/chromium/net/http/http_auth_handler_mock.h
index 32b416d2fba..2677526803b 100644
--- a/chromium/net/http/http_auth_handler_mock.h
+++ b/chromium/net/http/http_auth_handler_mock.h
@@ -6,8 +6,9 @@
#define NET_HTTP_HTTP_AUTH_HANDLER_MOCK_H_
#include <string>
+#include <vector>
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
@@ -51,7 +52,8 @@ class HttpAuthHandlerMock : public HttpAuthHandler {
scoped_ptr<HttpAuthHandler>* handler) override;
private:
- ScopedVector<HttpAuthHandler> handlers_[HttpAuth::AUTH_NUM_TARGETS];
+ std::vector<scoped_ptr<HttpAuthHandler>>
+ handlers_[HttpAuth::AUTH_NUM_TARGETS];
bool do_init_from_challenge_;
};
diff --git a/chromium/net/http/http_auth_handler_negotiate.cc b/chromium/net/http/http_auth_handler_negotiate.cc
index 3262767ef1c..864a703e12e 100644
--- a/chromium/net/http/http_auth_handler_negotiate.cc
+++ b/chromium/net/http/http_auth_handler_negotiate.cc
@@ -13,14 +13,12 @@
#include "net/dns/host_resolver.h"
#include "net/dns/single_request_host_resolver.h"
#include "net/http/http_auth_filter.h"
-#include "net/http/url_security_manager.h"
+#include "net/http/http_auth_preferences.h"
namespace net {
HttpAuthHandlerNegotiate::Factory::Factory()
- : disable_cname_lookup_(false),
- use_port_(false),
- resolver_(NULL),
+ : resolver_(NULL),
#if defined(OS_WIN)
max_token_length_(0),
#endif
@@ -58,16 +56,16 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
// method and only constructing when valid.
scoped_ptr<HttpAuthHandler> tmp_handler(
new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_,
- url_security_manager(), resolver_,
- disable_cname_lookup_, use_port_));
+ http_auth_preferences(), resolver_));
#elif defined(OS_ANDROID)
- if (is_unsupported_ || auth_library_->empty() || reason == CREATE_PREEMPTIVE)
+ if (is_unsupported_ || !http_auth_preferences() ||
+ http_auth_preferences()->AuthAndroidNegotiateAccountType().empty() ||
+ reason == CREATE_PREEMPTIVE)
return ERR_UNSUPPORTED_AUTH_SCHEME;
// TODO(cbentzel): Move towards model of parsing in the factory
// method and only constructing when valid.
- scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate(
- auth_library_.get(), url_security_manager(), resolver_,
- disable_cname_lookup_, use_port_));
+ scoped_ptr<HttpAuthHandler> tmp_handler(
+ new HttpAuthHandlerNegotiate(http_auth_preferences(), resolver_));
#elif defined(OS_POSIX)
if (is_unsupported_)
return ERR_UNSUPPORTED_AUTH_SCHEME;
@@ -77,10 +75,8 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
}
// TODO(ahendrickson): Move towards model of parsing in the factory
// method and only constructing when valid.
- scoped_ptr<HttpAuthHandler> tmp_handler(
- new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(),
- resolver_, disable_cname_lookup_,
- use_port_));
+ scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate(
+ auth_library_.get(), http_auth_preferences(), resolver_));
#endif
if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
return ERR_INVALID_RESPONSE;
@@ -89,36 +85,34 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
}
HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate(
+#if !defined(OS_ANDROID)
AuthLibrary* auth_library,
+#endif
#if defined(OS_WIN)
ULONG max_token_length,
#endif
- URLSecurityManager* url_security_manager,
- HostResolver* resolver,
- bool disable_cname_lookup,
- bool use_port)
+ const HttpAuthPreferences* prefs,
+ HostResolver* resolver)
#if defined(OS_ANDROID)
- : auth_system_(*auth_library),
+ : auth_system_(prefs),
#elif defined(OS_WIN)
: auth_system_(auth_library, "Negotiate", NEGOSSP_NAME, max_token_length),
#elif defined(OS_POSIX)
: auth_system_(auth_library, "Negotiate", CHROME_GSS_SPNEGO_MECH_OID_DESC),
#endif
- disable_cname_lookup_(disable_cname_lookup),
- use_port_(use_port),
resolver_(resolver),
already_called_(false),
has_credentials_(false),
auth_token_(NULL),
next_state_(STATE_NONE),
- url_security_manager_(url_security_manager) {
+ http_auth_preferences_(prefs) {
}
HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() {
}
-std::string HttpAuthHandlerNegotiate::CreateSPN(
- const AddressList& address_list, const GURL& origin) {
+std::string HttpAuthHandlerNegotiate::CreateSPN(const AddressList& address_list,
+ const GURL& origin) {
// Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI,
// and in the form HTTP@<host>:<port> through GSSAPI
// http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx
@@ -157,7 +151,9 @@ std::string HttpAuthHandlerNegotiate::CreateSPN(
#elif defined(OS_POSIX)
static const char kSpnSeparator = '@';
#endif
- if (port != 80 && port != 443 && use_port_) {
+ if (port != 80 && port != 443 &&
+ (http_auth_preferences_ &&
+ http_auth_preferences_->NegotiateEnablePort())) {
return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(),
port);
} else {
@@ -178,9 +174,9 @@ bool HttpAuthHandlerNegotiate::NeedsIdentity() {
bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() {
if (target_ == HttpAuth::AUTH_PROXY)
return true;
- if (!url_security_manager_)
+ if (!http_auth_preferences_)
return false;
- return url_security_manager_->CanUseDefaultCredentials(origin_);
+ return http_auth_preferences_->CanUseDefaultCredentials(origin_);
}
bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() {
@@ -284,7 +280,9 @@ int HttpAuthHandlerNegotiate::DoLoop(int result) {
int HttpAuthHandlerNegotiate::DoResolveCanonicalName() {
next_state_ = STATE_RESOLVE_CANONICAL_NAME_COMPLETE;
- if (disable_cname_lookup_ || !resolver_)
+ if ((http_auth_preferences_ &&
+ http_auth_preferences_->NegotiateDisableCnameLookup()) ||
+ !resolver_)
return OK;
// TODO(cbentzel): Add reverse DNS lookup for numeric addresses.
@@ -336,9 +334,9 @@ bool HttpAuthHandlerNegotiate::CanDelegate() const {
// TODO(cbentzel): Should delegation be allowed on proxies?
if (target_ == HttpAuth::AUTH_PROXY)
return false;
- if (!url_security_manager_)
+ if (!http_auth_preferences_)
return false;
- return url_security_manager_->CanDelegate(origin_);
+ return http_auth_preferences_->CanDelegate(origin_);
}
} // namespace net
diff --git a/chromium/net/http/http_auth_handler_negotiate.h b/chromium/net/http/http_auth_handler_negotiate.h
index 92b1b521605..1d744318946 100644
--- a/chromium/net/http/http_auth_handler_negotiate.h
+++ b/chromium/net/http/http_auth_handler_negotiate.h
@@ -6,6 +6,7 @@
#define NET_HTTP_HTTP_AUTH_HANDLER_NEGOTIATE_H_
#include <string>
+#include <utility>
#include "build/build_config.h"
#include "net/base/address_list.h"
@@ -23,9 +24,9 @@
namespace net {
+class HttpAuthPreferences;
class HostResolver;
class SingleRequestHostResolver;
-class URLSecurityManager;
// Handler for WWW-Authenticate: Negotiate protocol.
//
@@ -36,9 +37,6 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
public:
#if defined(OS_ANDROID)
typedef net::android::HttpAuthNegotiateAndroid AuthSystem;
- // For Android this isn't a library, but for the Android Account type, which
- // indirectly identifies the Kerberos/SPNEGO authentication app.
- typedef const std::string AuthLibrary;
#elif defined(OS_WIN)
typedef SSPILibrary AuthLibrary;
typedef HttpAuthSSPI AuthSystem;
@@ -52,30 +50,17 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
Factory();
~Factory() override;
- // |disable_cname_lookup()| and |set_disable_cname_lookup()| get/set whether
- // the auth handlers generated by this factory should skip looking up the
- // canonical DNS name of the the host that they are authenticating to when
- // generating the SPN. The default value is false.
- bool disable_cname_lookup() const { return disable_cname_lookup_; }
- void set_disable_cname_lookup(bool disable_cname_lookup) {
- disable_cname_lookup_ = disable_cname_lookup;
- }
-
- // |use_port()| and |set_use_port()| get/set whether the auth handlers
- // generated by this factory should include the port number of the server
- // they are authenticating to when constructing a Kerberos SPN. The default
- // value is false.
- bool use_port() const { return use_port_; }
- void set_use_port(bool use_port) { use_port_ = use_port; }
-
void set_host_resolver(HostResolver* host_resolver);
+#if !defined(OS_ANDROID)
// Sets the system library to use, thereby assuming ownership of
// |auth_library|.
- void set_library(AuthLibrary* auth_provider) {
- auth_library_.reset(auth_provider);
+ void set_library(scoped_ptr<AuthLibrary> auth_provider) {
+ auth_library_ = std::move(auth_provider);
}
+#endif
+ // HttpAuthHandlerFactory overrides
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const GURL& origin,
@@ -85,24 +70,25 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
scoped_ptr<HttpAuthHandler>* handler) override;
private:
- bool disable_cname_lookup_;
- bool use_port_;
HostResolver* resolver_;
#if defined(OS_WIN)
ULONG max_token_length_;
#endif
bool is_unsupported_;
+#if !defined(OS_ANDROID)
scoped_ptr<AuthLibrary> auth_library_;
+#endif
};
- HttpAuthHandlerNegotiate(AuthLibrary* auth_library,
+ HttpAuthHandlerNegotiate(
+#if !defined(OS_ANDROID)
+ AuthLibrary* auth_library,
+#endif
#if defined(OS_WIN)
- ULONG max_token_length,
+ ULONG max_token_length,
#endif
- URLSecurityManager* url_security_manager,
- HostResolver* host_resolver,
- bool disable_cname_lookup,
- bool use_port);
+ const HttpAuthPreferences* prefs,
+ HostResolver* host_resolver);
~HttpAuthHandlerNegotiate() override;
@@ -145,8 +131,6 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
bool CanDelegate() const;
AuthSystem auth_system_;
- bool disable_cname_lookup_;
- bool use_port_;
HostResolver* const resolver_;
// Members which are needed for DNS lookup + SPN.
@@ -165,7 +149,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
State next_state_;
- const URLSecurityManager* url_security_manager_;
+ const HttpAuthPreferences* http_auth_preferences_;
};
} // namespace net
diff --git a/chromium/net/http/http_auth_handler_negotiate_unittest.cc b/chromium/net/http/http_auth_handler_negotiate_unittest.cc
index 49ebdad62ad..fd467162ace 100644
--- a/chromium/net/http/http_auth_handler_negotiate_unittest.cc
+++ b/chromium/net/http/http_auth_handler_negotiate_unittest.cc
@@ -12,7 +12,7 @@
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_request_info.h"
-#include "net/http/mock_allow_url_security_manager.h"
+#include "net/http/mock_allow_http_auth_preferences.h"
#if defined(OS_ANDROID)
#include "net/android/dummy_spnego_authenticator.h"
#elif defined(OS_WIN)
@@ -41,17 +41,16 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest {
resolver_->rules()->AddIPLiteralRule("alias", "10.0.0.2",
"canonical.example.com");
- url_security_manager_.reset(new MockAllowURLSecurityManager());
+ http_auth_preferences_.reset(new MockAllowHttpAuthPreferences());
factory_.reset(new HttpAuthHandlerNegotiate::Factory());
- factory_->set_url_security_manager(url_security_manager_.get());
+ factory_->set_http_auth_preferences(http_auth_preferences_.get());
#if defined(OS_ANDROID)
- std::string* authenticator =
- new std::string("org.chromium.test.DummySpnegoAuthenticator");
- factory_->set_library(authenticator);
+ http_auth_preferences_->set_auth_android_negotiate_account_type(
+ "org.chromium.test.DummySpnegoAuthenticator");
MockAuthLibrary::EnsureTestAccountExists();
#endif
#if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_ANDROID))
- factory_->set_library(auth_library_);
+ factory_->set_library(make_scoped_ptr(auth_library_));
#endif
factory_->set_host_resolver(resolver_.get());
}
@@ -194,8 +193,9 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest {
bool synchronous_resolve_mode,
const std::string& url_string,
scoped_ptr<HttpAuthHandlerNegotiate>* handler) {
- factory_->set_disable_cname_lookup(disable_cname_lookup);
- factory_->set_use_port(use_port);
+ http_auth_preferences_->set_negotiate_disable_cname_lookup(
+ disable_cname_lookup);
+ http_auth_preferences_->set_negotiate_enable_port(use_port);
resolver_->set_synchronous_mode(synchronous_resolve_mode);
GURL gurl(url_string);
@@ -224,10 +224,12 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest {
#if defined(OS_WIN)
scoped_ptr<SecPkgInfoW> security_package_;
#endif
- // |auth_library_| is passed to |factory_|, which assumes ownership of it.
+ // |auth_library_| is passed to |factory_|, which assumes ownership of it, but
+ // can't be a scoped pointer to it since the tests need access when they set
+ // up the mocks after passing ownership.
MockAuthLibrary* auth_library_;
scoped_ptr<MockHostResolver> resolver_;
- scoped_ptr<URLSecurityManager> url_security_manager_;
+ scoped_ptr<MockAllowHttpAuthPreferences> http_auth_preferences_;
scoped_ptr<HttpAuthHandlerNegotiate::Factory> factory_;
};
@@ -360,13 +362,13 @@ TEST_F(HttpAuthHandlerNegotiateTest, NoKerberosCredentials) {
#if defined(DLOPEN_KERBEROS)
TEST_F(HttpAuthHandlerNegotiateTest, MissingGSSAPI) {
scoped_ptr<HostResolver> host_resolver(new MockHostResolver());
- MockAllowURLSecurityManager url_security_manager;
+ MockAllowHttpAuthPreferences http_auth_preferences;
scoped_ptr<HttpAuthHandlerNegotiate::Factory> negotiate_factory(
new HttpAuthHandlerNegotiate::Factory());
- negotiate_factory->set_host_resolver(host_resolver.get());
- negotiate_factory->set_url_security_manager(&url_security_manager);
+ negotiate_factory->set_host_resolver(host_resolver);
+ negotiate_factory->set_http_auth_preferences(&http_auth_preferences);
negotiate_factory->set_library(
- new GSSAPISharedLibrary("/this/library/does/not/exist"));
+ make_scoped_ptr(new GSSAPISharedLibrary("/this/library/does/not/exist")));
GURL gurl("http://www.example.com");
scoped_ptr<HttpAuthHandler> generic_handler;
diff --git a/chromium/net/http/http_auth_handler_ntlm.cc b/chromium/net/http/http_auth_handler_ntlm.cc
index 0bf7260efad..2411f9fcd1e 100644
--- a/chromium/net/http/http_auth_handler_ntlm.cc
+++ b/chromium/net/http/http_auth_handler_ntlm.cc
@@ -13,6 +13,7 @@
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/http/http_auth_challenge_tokenizer.h"
+#include "net/http/http_auth_scheme.h"
namespace net {
@@ -46,7 +47,7 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl(
// GenerateType1Msg, and GenerateType3Msg, and perhaps further.
const void* in_buf;
void* out_buf;
- uint32 in_buf_len, out_buf_len;
+ uint32_t in_buf_len, out_buf_len;
std::string decoded_auth_data;
// The username may be in the form "DOMAIN\user". Parse it into the two
@@ -112,7 +113,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerNTLM::ParseChallenge(
auth_data_.clear();
// Verify the challenge's auth-scheme.
- if (!base::LowerCaseEqualsASCII(tok->scheme(), "ntlm"))
+ if (!base::LowerCaseEqualsASCII(tok->scheme(), kNtlmAuthScheme))
return HttpAuth::AUTHORIZATION_RESULT_INVALID;
std::string base64_param = tok->base64_param();
diff --git a/chromium/net/http/http_auth_handler_ntlm.h b/chromium/net/http/http_auth_handler_ntlm.h
index b24b7e071dd..d71b498daa3 100644
--- a/chromium/net/http/http_auth_handler_ntlm.h
+++ b/chromium/net/http/http_auth_handler_ntlm.h
@@ -5,6 +5,9 @@
#ifndef NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_
#define NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "build/build_config.h"
// This contains the portable and the SSPI implementations for NTLM.
@@ -24,14 +27,13 @@
#include <string>
-#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
namespace net {
-class URLSecurityManager;
+class HttpAuthPreferences;
// Code for handling HTTP NTLM authentication.
class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
@@ -67,7 +69,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
#if defined(NTLM_PORTABLE)
// A function that generates n random bytes in the output buffer.
- typedef void (*GenerateRandomProc)(uint8* output, size_t n);
+ typedef void (*GenerateRandomProc)(uint8_t* output, size_t n);
// A function that returns the local host name. Returns an empty string if
// the local host name is not available.
@@ -98,8 +100,9 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
HttpAuthHandlerNTLM();
#endif
#if defined(NTLM_SSPI)
- HttpAuthHandlerNTLM(SSPILibrary* sspi_library, ULONG max_token_length,
- URLSecurityManager* url_security_manager);
+ HttpAuthHandlerNTLM(SSPILibrary* sspi_library,
+ ULONG max_token_length,
+ const HttpAuthPreferences* http_auth_preferences);
#endif
bool NeedsIdentity() override;
@@ -138,9 +141,9 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
// Given an input token received from the server, generate the next output
// token to be sent to the server.
int GetNextToken(const void* in_token,
- uint32 in_token_len,
+ uint32_t in_token_len,
void** out_token,
- uint32* out_token_len);
+ uint32_t* out_token_len);
// Create an NTLM SPN to identify the |origin| server.
static std::string CreateSPN(const GURL& origin);
@@ -162,7 +165,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
std::string auth_data_;
#if defined(NTLM_SSPI)
- URLSecurityManager* url_security_manager_;
+ const HttpAuthPreferences* http_auth_preferences_;
#endif
};
diff --git a/chromium/net/http/http_auth_handler_ntlm_portable.cc b/chromium/net/http/http_auth_handler_ntlm_portable.cc
index 54d4492a4bf..0522c3179fa 100644
--- a/chromium/net/http/http_auth_handler_ntlm_portable.cc
+++ b/chromium/net/http/http_auth_handler_ntlm_portable.cc
@@ -177,12 +177,12 @@ static bool SendLM() {
#define SWAP16(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
#define SWAP32(x) ((SWAP16((x) & 0xffff) << 16) | (SWAP16((x) >> 16)))
-static void* WriteBytes(void* buf, const void* data, uint32 data_len) {
+static void* WriteBytes(void* buf, const void* data, uint32_t data_len) {
memcpy(buf, data, data_len);
return static_cast<char*>(buf) + data_len;
}
-static void* WriteDWORD(void* buf, uint32 dword) {
+static void* WriteDWORD(void* buf, uint32_t dword) {
#ifdef IS_BIG_ENDIAN
// NTLM uses little endian on the wire.
dword = SWAP32(dword);
@@ -190,7 +190,7 @@ static void* WriteDWORD(void* buf, uint32 dword) {
return WriteBytes(buf, &dword, sizeof(dword));
}
-static void* WriteSecBuf(void* buf, uint16 length, uint32 offset) {
+static void* WriteSecBuf(void* buf, uint16_t length, uint32_t offset) {
#ifdef IS_BIG_ENDIAN
length = SWAP16(length);
offset = SWAP32(offset);
@@ -213,14 +213,15 @@ static void* WriteSecBuf(void* buf, uint16 length, uint32 offset) {
* to pass the same buffer as both input and output, which is a handy way to
* convert the unicode buffer to little-endian on big-endian platforms.
*/
-static void* WriteUnicodeLE(
- void* buf, const base::char16* str, uint32 str_len) {
+static void* WriteUnicodeLE(void* buf,
+ const base::char16* str,
+ uint32_t str_len) {
// Convert input string from BE to LE.
- uint8* cursor = static_cast<uint8*>(buf);
- const uint8* input = reinterpret_cast<const uint8*>(str);
- for (uint32 i = 0; i < str_len; ++i, input += 2, cursor += 2) {
+ uint8_t* cursor = static_cast<uint8_t*>(buf);
+ const uint8_t* input = reinterpret_cast<const uint8_t*>(str);
+ for (uint32_t i = 0; i < str_len; ++i, input += 2, cursor += 2) {
// Allow for the case where |buf == str|.
- uint8 temp = input[0];
+ uint8_t temp = input[0];
cursor[0] = input[1];
cursor[1] = temp;
}
@@ -228,18 +229,18 @@ static void* WriteUnicodeLE(
}
#endif
-static uint16 ReadUint16(const uint8*& buf) {
- uint16 x = (static_cast<uint16>(buf[0])) |
- (static_cast<uint16>(buf[1]) << 8);
+static uint16_t ReadUint16(const uint8_t*& buf) {
+ uint16_t x =
+ (static_cast<uint16_t>(buf[0])) | (static_cast<uint16_t>(buf[1]) << 8);
buf += sizeof(x);
return x;
}
-static uint32 ReadUint32(const uint8*& buf) {
- uint32 x = (static_cast<uint32>(buf[0])) |
- (static_cast<uint32>(buf[1]) << 8) |
- (static_cast<uint32>(buf[2]) << 16) |
- (static_cast<uint32>(buf[3]) << 24);
+static uint32_t ReadUint32(const uint8_t*& buf) {
+ uint32_t x = (static_cast<uint32_t>(buf[0])) |
+ (static_cast<uint32_t>(buf[1]) << 8) |
+ (static_cast<uint32_t>(buf[2]) << 16) |
+ (static_cast<uint32_t>(buf[3]) << 24);
buf += sizeof(x);
return x;
}
@@ -255,8 +256,8 @@ static uint32 ReadUint32(const uint8*& buf) {
//
// Note: This function is not being used because our SendLM() function always
// returns false.
-static void LM_Hash(const base::string16& password, uint8* hash) {
- static const uint8 LM_MAGIC[] = "KGS!@#$%";
+static void LM_Hash(const base::string16& password, uint8_t* hash) {
+ static const uint8_t LM_MAGIC[] = "KGS!@#$%";
// Convert password to OEM character set. We'll just use the native
// filesystem charset.
@@ -264,9 +265,9 @@ static void LM_Hash(const base::string16& password, uint8* hash) {
passbuf = base::ToUpperASCII(passbuf);
passbuf.resize(14, '\0');
- uint8 k1[8], k2[8];
- DESMakeKey(reinterpret_cast<const uint8*>(passbuf.data()) , k1);
- DESMakeKey(reinterpret_cast<const uint8*>(passbuf.data()) + 7, k2);
+ uint8_t k1[8], k2[8];
+ DESMakeKey(reinterpret_cast<const uint8_t*>(passbuf.data()), k1);
+ DESMakeKey(reinterpret_cast<const uint8_t*>(passbuf.data()) + 7, k2);
ZapString(&passbuf);
// Use password keys to hash LM magic string twice.
@@ -280,19 +281,19 @@ static void LM_Hash(const base::string16& password, uint8* hash) {
// null-terminated unicode password.
// param hash
// 16-byte result buffer
-static void NTLM_Hash(const base::string16& password, uint8* hash) {
+static void NTLM_Hash(const base::string16& password, uint8_t* hash) {
#ifdef IS_BIG_ENDIAN
- uint32 len = password.length();
- uint8* passbuf;
+ uint32_t len = password.length();
+ uint8_t* passbuf;
- passbuf = static_cast<uint8*>(malloc(len * 2));
+ passbuf = static_cast<uint8_t*>(malloc(len * 2));
WriteUnicodeLE(passbuf, password.data(), len);
weak_crypto::MD4Sum(passbuf, len * 2, hash);
ZapBuf(passbuf, len * 2);
free(passbuf);
#else
- weak_crypto::MD4Sum(reinterpret_cast<const uint8*>(password.data()),
+ weak_crypto::MD4Sum(reinterpret_cast<const uint8_t*>(password.data()),
password.length() * 2, hash);
#endif
}
@@ -308,10 +309,10 @@ static void NTLM_Hash(const base::string16& password, uint8* hash) {
// 8-byte challenge from Type-2 message
// param response
// 24-byte buffer to contain the LM response upon return
-static void LM_Response(const uint8* hash,
- const uint8* challenge,
- uint8* response) {
- uint8 keybytes[21], k1[8], k2[8], k3[8];
+static void LM_Response(const uint8_t* hash,
+ const uint8_t* challenge,
+ uint8_t* response) {
+ uint8_t keybytes[21], k1[8], k2[8], k3[8];
memcpy(keybytes, hash, 16);
ZapBuf(keybytes + 16, 5);
@@ -328,7 +329,7 @@ static void LM_Response(const uint8* hash,
//-----------------------------------------------------------------------------
// Returns OK or a network error code.
-static int GenerateType1Msg(void** out_buf, uint32* out_len) {
+static int GenerateType1Msg(void** out_buf, uint32_t* out_len) {
//
// Verify that buf_len is sufficient.
//
@@ -369,16 +370,16 @@ static int GenerateType1Msg(void** out_buf, uint32* out_len) {
}
struct Type2Msg {
- uint32 flags; // NTLM_Xxx bitwise combination
- uint8 challenge[8]; // 8 byte challenge
+ uint32_t flags; // NTLM_Xxx bitwise combination
+ uint8_t challenge[8]; // 8 byte challenge
const void* target; // target string (type depends on flags)
- uint32 target_len; // target length in bytes
+ uint32_t target_len; // target length in bytes
};
// Returns OK or a network error code.
// TODO(wtc): This function returns ERR_UNEXPECTED when the input message is
// invalid. We should return a better error code.
-static int ParseType2Msg(const void* in_buf, uint32 in_len, Type2Msg* msg) {
+static int ParseType2Msg(const void* in_buf, uint32_t in_len, Type2Msg* msg) {
// Make sure in_buf is long enough to contain a meaningful type2 msg.
//
// 0 NTLMSSP Signature
@@ -391,7 +392,7 @@ static int ParseType2Msg(const void* in_buf, uint32 in_len, Type2Msg* msg) {
if (in_len < NTLM_TYPE2_HEADER_LEN)
return ERR_UNEXPECTED;
- const uint8* cursor = (const uint8*) in_buf;
+ const uint8_t* cursor = (const uint8_t*)in_buf;
// verify NTLMSSP signature
if (memcmp(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0)
@@ -404,16 +405,16 @@ static int ParseType2Msg(const void* in_buf, uint32 in_len, Type2Msg* msg) {
cursor += sizeof(NTLM_TYPE2_MARKER);
// read target name security buffer
- uint32 target_len = ReadUint16(cursor);
+ uint32_t target_len = ReadUint16(cursor);
ReadUint16(cursor); // discard next 16-bit value
- uint32 offset = ReadUint32(cursor); // get offset from in_buf
+ uint32_t offset = ReadUint32(cursor); // get offset from in_buf
msg->target_len = 0;
msg->target = NULL;
// Check the offset / length combo is in range of the input buffer, including
// integer overflow checking.
if (offset + target_len > offset && offset + target_len <= in_len) {
msg->target_len = target_len;
- msg->target = ((const uint8*) in_buf) + offset;
+ msg->target = ((const uint8_t*)in_buf) + offset;
}
// read flags
@@ -424,8 +425,8 @@ static int ParseType2Msg(const void* in_buf, uint32 in_len, Type2Msg* msg) {
cursor += sizeof(msg->challenge);
NTLM_LOG(("NTLM type 2 message:\n"));
- LogBuf("target", (const uint8*) msg->target, msg->target_len);
- LogBuf("flags", (const uint8*) &msg->flags, 4);
+ LogBuf("target", (const uint8_t*)msg->target, msg->target_len);
+ LogBuf("flags", (const uint8_t*)&msg->flags, 4);
LogFlags(msg->flags);
LogBuf("challenge", msg->challenge, sizeof(msg->challenge));
@@ -435,7 +436,7 @@ static int ParseType2Msg(const void* in_buf, uint32 in_len, Type2Msg* msg) {
return OK;
}
-static void GenerateRandom(uint8* output, size_t n) {
+static void GenerateRandom(uint8_t* output, size_t n) {
for (size_t i = 0; i < n; ++i)
output[i] = base::RandInt(0, 255);
}
@@ -447,9 +448,9 @@ static int GenerateType3Msg(const base::string16& domain,
const std::string& hostname,
const void* rand_8_bytes,
const void* in_buf,
- uint32 in_len,
+ uint32_t in_len,
void** out_buf,
- uint32* out_len) {
+ uint32_t* out_len) {
// in_buf contains Type-2 msg (the challenge) from server.
int rv;
@@ -473,7 +474,7 @@ static int GenerateType3Msg(const base::string16& domain,
const void* domain_ptr;
const void* user_ptr;
const void* host_ptr;
- uint32 domain_len, user_len, host_len;
+ uint32_t domain_len, user_len, host_len;
//
// Get domain name.
@@ -545,13 +546,13 @@ static int GenerateType3Msg(const base::string16& domain,
//
// Next, we compute the LM and NTLM responses.
//
- uint8 lm_resp[LM_RESP_LEN];
- uint8 ntlm_resp[NTLM_RESP_LEN];
- uint8 ntlm_hash[NTLM_HASH_LEN];
+ uint8_t lm_resp[LM_RESP_LEN];
+ uint8_t ntlm_resp[NTLM_RESP_LEN];
+ uint8_t ntlm_hash[NTLM_HASH_LEN];
if (msg.flags & NTLM_NegotiateNTLM2Key) {
// compute NTLM2 session response
base::MD5Digest session_hash;
- uint8 temp[16];
+ uint8_t temp[16];
memcpy(lm_resp, rand_8_bytes, 8);
memset(lm_resp + 8, 0, LM_RESP_LEN - 8);
@@ -567,7 +568,7 @@ static int GenerateType3Msg(const base::string16& domain,
LM_Response(ntlm_hash, msg.challenge, ntlm_resp);
if (SendLM()) {
- uint8 lm_hash[LM_HASH_LEN];
+ uint8_t lm_hash[LM_HASH_LEN];
LM_Hash(password, lm_hash);
LM_Response(lm_hash, msg.challenge, lm_resp);
} else {
@@ -582,7 +583,7 @@ static int GenerateType3Msg(const base::string16& domain,
// Finally, we assemble the Type-3 msg :-)
//
void* cursor = *out_buf;
- uint32 offset;
+ uint32_t offset;
// 0 : signature
cursor = WriteBytes(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE));
@@ -593,27 +594,27 @@ static int GenerateType3Msg(const base::string16& domain,
// 12 : LM response sec buf
offset = NTLM_TYPE3_HEADER_LEN + domain_len + user_len + host_len;
cursor = WriteSecBuf(cursor, LM_RESP_LEN, offset);
- memcpy(static_cast<uint8*>(*out_buf) + offset, lm_resp, LM_RESP_LEN);
+ memcpy(static_cast<uint8_t*>(*out_buf) + offset, lm_resp, LM_RESP_LEN);
// 20 : NTLM response sec buf
offset += LM_RESP_LEN;
cursor = WriteSecBuf(cursor, NTLM_RESP_LEN, offset);
- memcpy(static_cast<uint8*>(*out_buf) + offset, ntlm_resp, NTLM_RESP_LEN);
+ memcpy(static_cast<uint8_t*>(*out_buf) + offset, ntlm_resp, NTLM_RESP_LEN);
// 28 : domain name sec buf
offset = NTLM_TYPE3_HEADER_LEN;
cursor = WriteSecBuf(cursor, domain_len, offset);
- memcpy(static_cast<uint8*>(*out_buf) + offset, domain_ptr, domain_len);
+ memcpy(static_cast<uint8_t*>(*out_buf) + offset, domain_ptr, domain_len);
// 36 : user name sec buf
offset += domain_len;
cursor = WriteSecBuf(cursor, user_len, offset);
- memcpy(static_cast<uint8*>(*out_buf) + offset, user_ptr, user_len);
+ memcpy(static_cast<uint8_t*>(*out_buf) + offset, user_ptr, user_len);
// 44 : workstation (host) name sec buf
offset += user_len;
cursor = WriteSecBuf(cursor, host_len, offset);
- memcpy(static_cast<uint8*>(*out_buf) + offset, host_ptr, host_len);
+ memcpy(static_cast<uint8_t*>(*out_buf) + offset, host_ptr, host_len);
// 52 : session key sec buf (not used)
cursor = WriteSecBuf(cursor, 0, 0);
@@ -683,9 +684,9 @@ HttpAuthHandlerNTLM::Factory::~Factory() {
}
int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
- uint32 in_token_len,
+ uint32_t in_token_len,
void** out_token,
- uint32* out_token_len) {
+ uint32_t* out_token_len) {
int rv = 0;
// If in_token is non-null, then assume it contains a type 2 message...
@@ -694,7 +695,7 @@ int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
std::string hostname = get_host_name_proc_();
if (hostname.empty())
return ERR_UNEXPECTED;
- uint8 rand_buf[8];
+ uint8_t rand_buf[8];
generate_random_proc_(rand_buf, 8);
rv = GenerateType3Msg(domain_,
credentials_.username(), credentials_.password(),
diff --git a/chromium/net/http/http_auth_handler_ntlm_win.cc b/chromium/net/http/http_auth_handler_ntlm_win.cc
index f471ea97206..7aca5f07bd9 100644
--- a/chromium/net/http/http_auth_handler_ntlm_win.cc
+++ b/chromium/net/http/http_auth_handler_ntlm_win.cc
@@ -12,19 +12,19 @@
#include "base/strings/string_util.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
+#include "net/http/http_auth_preferences.h"
#include "net/http/http_auth_sspi_win.h"
-#include "net/http/url_security_manager.h"
#pragma comment(lib, "secur32.lib")
namespace net {
HttpAuthHandlerNTLM::HttpAuthHandlerNTLM(
- SSPILibrary* sspi_library, ULONG max_token_length,
- URLSecurityManager* url_security_manager)
+ SSPILibrary* sspi_library,
+ ULONG max_token_length,
+ const HttpAuthPreferences* http_auth_preferences)
: auth_sspi_(sspi_library, "NTLM", NTLMSP_NAME, max_token_length),
- url_security_manager_(url_security_manager) {
-}
+ http_auth_preferences_(http_auth_preferences) {}
HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
}
@@ -37,9 +37,9 @@ bool HttpAuthHandlerNTLM::NeedsIdentity() {
bool HttpAuthHandlerNTLM::AllowsDefaultCredentials() {
if (target_ == HttpAuth::AUTH_PROXY)
return true;
- if (!url_security_manager_)
+ if (!http_auth_preferences_)
return false;
- return url_security_manager_->CanUseDefaultCredentials(origin_);
+ return http_auth_preferences_->CanUseDefaultCredentials(origin_);
}
HttpAuthHandlerNTLM::Factory::Factory()
@@ -70,9 +70,8 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
}
// TODO(cbentzel): Move towards model of parsing in the factory
// method and only constructing when valid.
- scoped_ptr<HttpAuthHandler> tmp_handler(
- new HttpAuthHandlerNTLM(sspi_library_.get(), max_token_length_,
- url_security_manager()));
+ scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNTLM(
+ sspi_library_.get(), max_token_length_, http_auth_preferences()));
if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
return ERR_INVALID_RESPONSE;
handler->swap(tmp_handler);
diff --git a/chromium/net/http/http_auth_preferences.cc b/chromium/net/http/http_auth_preferences.cc
new file mode 100644
index 00000000000..bdb12b31d0e
--- /dev/null
+++ b/chromium/net/http/http_auth_preferences.cc
@@ -0,0 +1,82 @@
+// Copyright 2015 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 "base/strings/string_split.h"
+#include "net/http/http_auth_filter.h"
+#include "net/http/http_auth_preferences.h"
+#include "net/http/url_security_manager.h"
+
+namespace net {
+
+HttpAuthPreferences::HttpAuthPreferences(
+ const std::vector<std::string>& auth_schemes
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ const std::string& gssapi_library_name
+#endif
+ )
+ : auth_schemes_(auth_schemes.begin(), auth_schemes.end()),
+ negotiate_disable_cname_lookup_(false),
+ negotiate_enable_port_(false),
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ gssapi_library_name_(gssapi_library_name),
+#endif
+ security_manager_(URLSecurityManager::Create()) {
+}
+
+HttpAuthPreferences::~HttpAuthPreferences() {}
+
+bool HttpAuthPreferences::IsSupportedScheme(const std::string& scheme) const {
+ return auth_schemes_.count(scheme) == 1;
+}
+
+bool HttpAuthPreferences::NegotiateDisableCnameLookup() const {
+ return negotiate_disable_cname_lookup_;
+}
+
+bool HttpAuthPreferences::NegotiateEnablePort() const {
+ return negotiate_enable_port_;
+}
+
+#if defined(OS_ANDROID)
+std::string HttpAuthPreferences::AuthAndroidNegotiateAccountType() const {
+ return auth_android_negotiate_account_type_;
+}
+#endif
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+std::string HttpAuthPreferences::GssapiLibraryName() const {
+ return gssapi_library_name_;
+}
+#endif
+
+bool HttpAuthPreferences::CanUseDefaultCredentials(
+ const GURL& auth_origin) const {
+ return security_manager_->CanUseDefaultCredentials(auth_origin);
+}
+
+bool HttpAuthPreferences::CanDelegate(const GURL& auth_origin) const {
+ return security_manager_->CanDelegate(auth_origin);
+}
+
+void HttpAuthPreferences::set_server_whitelist(
+ const std::string& server_whitelist) {
+ if (server_whitelist.empty()) {
+ security_manager_->SetDefaultWhitelist(scoped_ptr<HttpAuthFilter>());
+ } else {
+ security_manager_->SetDefaultWhitelist(scoped_ptr<HttpAuthFilter>(
+ new net::HttpAuthFilterWhitelist(server_whitelist)));
+ }
+}
+
+void HttpAuthPreferences::set_delegate_whitelist(
+ const std::string& delegate_whitelist) {
+ if (delegate_whitelist.empty()) {
+ security_manager_->SetDelegateWhitelist(scoped_ptr<HttpAuthFilter>());
+ } else {
+ security_manager_->SetDelegateWhitelist(scoped_ptr<HttpAuthFilter>(
+ new net::HttpAuthFilterWhitelist(delegate_whitelist)));
+ }
+}
+
+} // namespace net
diff --git a/chromium/net/http/http_auth_preferences.h b/chromium/net/http/http_auth_preferences.h
new file mode 100644
index 00000000000..eabd13833f4
--- /dev/null
+++ b/chromium/net/http/http_auth_preferences.h
@@ -0,0 +1,84 @@
+// Copyright 2015 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_AUTH_PREFERENCES_H_
+#define NET_HTTP_HTTP_AUTH_PREFERENCES_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "net/base/net_export.h"
+#include "url/gurl.h"
+
+namespace net {
+
+class URLSecurityManager;
+
+// Manage the preferences needed for authentication, and provide a cache of
+// them accessible from the IO thread.
+class NET_EXPORT HttpAuthPreferences {
+ public:
+ HttpAuthPreferences(const std::vector<std::string>& auth_schemes
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ const std::string& gssapi_library_name
+#endif
+ );
+ virtual ~HttpAuthPreferences();
+
+ virtual bool IsSupportedScheme(const std::string& scheme) const;
+ virtual bool NegotiateDisableCnameLookup() const;
+ virtual bool NegotiateEnablePort() const;
+#if defined(OS_ANDROID)
+ virtual std::string AuthAndroidNegotiateAccountType() const;
+#endif
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ virtual std::string GssapiLibraryName() const;
+#endif
+ virtual bool CanUseDefaultCredentials(const GURL& auth_origin) const;
+ virtual bool CanDelegate(const GURL& auth_origin) const;
+
+ void set_negotiate_disable_cname_lookup(bool negotiate_disable_cname_lookup) {
+ negotiate_disable_cname_lookup_ = negotiate_disable_cname_lookup;
+ }
+
+ void set_negotiate_enable_port(bool negotiate_enable_port) {
+ negotiate_enable_port_ = negotiate_enable_port;
+ }
+
+ void set_server_whitelist(const std::string& server_whitelist);
+
+ void set_delegate_whitelist(const std::string& delegate_whitelist);
+
+#if defined(OS_ANDROID)
+ void set_auth_android_negotiate_account_type(
+ const std::string& account_type) {
+ auth_android_negotiate_account_type_ = account_type;
+ }
+#endif
+
+ private:
+ // TODO(aberent) allow changes to auth scheme set after startup.
+ // See https://crbug/549273.
+ const std::set<std::string> auth_schemes_;
+ bool negotiate_disable_cname_lookup_;
+ bool negotiate_enable_port_;
+
+#if defined(OS_ANDROID)
+ std::string auth_android_negotiate_account_type_;
+#endif
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ // GSSAPI library name cannot change after startup, since changing it
+ // requires unloading the existing GSSAPI library, which could cause all
+ // sorts of problems for, for example, active Negotiate transactions.
+ const std::string gssapi_library_name_;
+#endif
+ scoped_ptr<URLSecurityManager> security_manager_;
+ DISALLOW_COPY_AND_ASSIGN(HttpAuthPreferences);
+};
+
+} // namespace net
+#endif // NET_HTTP_HTTP_AUTH_PREFERENCES_H_
diff --git a/chromium/net/http/http_auth_preferences_unittest.cc b/chromium/net/http/http_auth_preferences_unittest.cc
new file mode 100644
index 00000000000..479b0d52b6d
--- /dev/null
+++ b/chromium/net/http/http_auth_preferences_unittest.cc
@@ -0,0 +1,114 @@
+// 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/http/http_auth_preferences.h"
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/testing_pref_service.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+TEST(HttpAuthPreferencesTest, AuthSchemes) {
+ const char* const expected_schemes[] = {"scheme1", "scheme2"};
+ std::vector<std::string> expected_schemes_vector(
+ expected_schemes, expected_schemes + arraysize(expected_schemes));
+ HttpAuthPreferences http_auth_preferences(expected_schemes_vector
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ ""
+#endif
+ );
+ EXPECT_TRUE(http_auth_preferences.IsSupportedScheme("scheme1"));
+ EXPECT_TRUE(http_auth_preferences.IsSupportedScheme("scheme2"));
+ EXPECT_FALSE(http_auth_preferences.IsSupportedScheme("scheme3"));
+}
+
+TEST(HttpAuthPreferencesTest, DisableCnameLookup) {
+ std::vector<std::string> auth_schemes;
+ HttpAuthPreferences http_auth_preferences(auth_schemes
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ ""
+#endif
+ );
+ EXPECT_FALSE(http_auth_preferences.NegotiateDisableCnameLookup());
+ http_auth_preferences.set_negotiate_disable_cname_lookup(true);
+ EXPECT_TRUE(http_auth_preferences.NegotiateDisableCnameLookup());
+}
+
+TEST(HttpAuthPreferencesTest, NegotiateEnablePort) {
+ std::vector<std::string> auth_schemes;
+ HttpAuthPreferences http_auth_preferences(auth_schemes
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ ""
+#endif
+ );
+ EXPECT_FALSE(http_auth_preferences.NegotiateEnablePort());
+ http_auth_preferences.set_negotiate_enable_port(true);
+ EXPECT_TRUE(http_auth_preferences.NegotiateEnablePort());
+}
+
+#if defined(OS_ANDROID)
+TEST(HttpAuthPreferencesTest, AuthAndroidhNegotiateAccountType) {
+ std::vector<std::string> auth_schemes;
+ HttpAuthPreferences http_auth_preferences(auth_schemes
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ ""
+#endif
+ );
+ EXPECT_EQ(std::string(),
+ http_auth_preferences.AuthAndroidNegotiateAccountType());
+ http_auth_preferences.set_auth_android_negotiate_account_type("foo");
+ EXPECT_EQ(std::string("foo"),
+ http_auth_preferences.AuthAndroidNegotiateAccountType());
+}
+#endif
+
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+TEST(HttpAuthPreferencesTest, GssApiLibraryName) {
+ std::vector<std::string> AuthSchemes;
+ HttpAuthPreferences http_auth_preferences(AuthSchemes, "bar");
+ EXPECT_EQ(std::string("bar"), http_auth_preferences.GssapiLibraryName());
+}
+#endif
+
+TEST(HttpAuthPreferencesTest, AuthServerWhitelist) {
+ std::vector<std::string> auth_schemes;
+ HttpAuthPreferences http_auth_preferences(auth_schemes
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ ""
+#endif
+ );
+ // Check initial value
+ EXPECT_FALSE(http_auth_preferences.CanUseDefaultCredentials(GURL("abc")));
+ http_auth_preferences.set_server_whitelist("*");
+ EXPECT_TRUE(http_auth_preferences.CanUseDefaultCredentials(GURL("abc")));
+}
+
+TEST(HttpAuthPreferencesTest, AuthDelegateWhitelist) {
+ std::vector<std::string> auth_schemes;
+ HttpAuthPreferences http_auth_preferences(auth_schemes
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ ""
+#endif
+ );
+ // Check initial value
+ EXPECT_FALSE(http_auth_preferences.CanDelegate(GURL("abc")));
+ http_auth_preferences.set_delegate_whitelist("*");
+ EXPECT_TRUE(http_auth_preferences.CanDelegate(GURL("abc")));
+}
+
+} // namespace net
diff --git a/chromium/net/http/http_auth_scheme.cc b/chromium/net/http/http_auth_scheme.cc
new file mode 100644
index 00000000000..75debb310c9
--- /dev/null
+++ b/chromium/net/http/http_auth_scheme.cc
@@ -0,0 +1,15 @@
+// Copyright 2015 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/net_export.h"
+#include "net/http/http_auth_scheme.h"
+
+namespace net {
+const char kBasicAuthScheme[] = "basic";
+const char kDigestAuthScheme[] = "digest";
+const char kNtlmAuthScheme[] = "ntlm";
+const char kNegotiateAuthScheme[] = "negotiate";
+const char kSpdyProxyAuthScheme[] = "spdyproxy";
+const char kMockAuthScheme[] = "mock";
+} // namespace net
diff --git a/chromium/net/http/http_auth_scheme.h b/chromium/net/http/http_auth_scheme.h
new file mode 100644
index 00000000000..98e17857a99
--- /dev/null
+++ b/chromium/net/http/http_auth_scheme.h
@@ -0,0 +1,17 @@
+// Copyright 2015 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_AUTH_SCHEME_H_
+#define NET_HTTP_HTTP_AUTH_SCHEME_H_
+
+namespace net {
+NET_EXPORT extern const char kBasicAuthScheme[];
+NET_EXPORT extern const char kDigestAuthScheme[];
+NET_EXPORT extern const char kNtlmAuthScheme[];
+NET_EXPORT extern const char kNegotiateAuthScheme[];
+NET_EXPORT extern const char kSpdyProxyAuthScheme[];
+NET_EXPORT extern const char kMockAuthScheme[];
+} // namespace net
+
+#endif // NET_HTTP_HTTP_AUTH_SCHEME_H_
diff --git a/chromium/net/http/http_auth_sspi_win_unittest.cc b/chromium/net/http/http_auth_sspi_win_unittest.cc
index feebaf0cee1..0bb90ff70f3 100644
--- a/chromium/net/http/http_auth_sspi_win_unittest.cc
+++ b/chromium/net/http/http_auth_sspi_win_unittest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_sspi_win.h"
@@ -48,7 +47,7 @@ TEST(HttpAuthSSPITest, DetermineMaxTokenLength_Normal) {
ULONG max_token_length = kMaxTokenLength;
int rv = DetermineMaxTokenLength(&mock_library, L"NTLM", &max_token_length);
EXPECT_EQ(OK, rv);
- EXPECT_EQ(1337, max_token_length);
+ EXPECT_EQ(1337u, max_token_length);
}
TEST(HttpAuthSSPITest, DetermineMaxTokenLength_InvalidPackage) {
@@ -60,7 +59,7 @@ TEST(HttpAuthSSPITest, DetermineMaxTokenLength_InvalidPackage) {
EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME, rv);
// |DetermineMaxTokenLength()| interface states that |max_token_length| should
// not change on failure.
- EXPECT_EQ(100, max_token_length);
+ EXPECT_EQ(100u, max_token_length);
}
TEST(HttpAuthSSPITest, ParseChallenge_FirstRound) {
diff --git a/chromium/net/http/http_auth_unittest.cc b/chromium/net/http/http_auth_unittest.cc
index a81a409f064..c550803857b 100644
--- a/chromium/net/http/http_auth_unittest.cc
+++ b/chromium/net/http/http_auth_unittest.cc
@@ -16,9 +16,10 @@
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_handler_mock.h"
+#include "net/http/http_auth_scheme.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
-#include "net/http/mock_allow_url_security_manager.h"
+#include "net/http/mock_allow_http_auth_preferences.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -121,12 +122,12 @@ TEST(HttpAuthTest, ChooseBestChallenge) {
}};
GURL origin("http://www.example.com");
std::set<HttpAuth::Scheme> disabled_schemes;
- MockAllowURLSecurityManager url_security_manager;
+ MockAllowHttpAuthPreferences http_auth_preferences;
scoped_ptr<HostResolver> host_resolver(new MockHostResolver());
scoped_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory(
HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
- http_auth_handler_factory->SetURLSecurityManager(
- "negotiate", &url_security_manager);
+ http_auth_handler_factory->SetHttpAuthPreferences(kNegotiateAuthScheme,
+ &http_auth_preferences);
for (size_t i = 0; i < arraysize(tests); ++i) {
// Make a HttpResponseHeaders object.
diff --git a/chromium/net/http/http_basic_state.cc b/chromium/net/http/http_basic_state.cc
index 060f2fe27fb..b6e04df0373 100644
--- a/chromium/net/http/http_basic_state.cc
+++ b/chromium/net/http/http_basic_state.cc
@@ -4,7 +4,8 @@
#include "net/http/http_basic_state.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/logging.h"
#include "net/base/io_buffer.h"
#include "net/http/http_request_info.h"
@@ -36,7 +37,7 @@ int HttpBasicState::Initialize(const HttpRequestInfo* request_info,
}
scoped_ptr<ClientSocketHandle> HttpBasicState::ReleaseConnection() {
- return connection_.Pass();
+ return std::move(connection_);
}
scoped_refptr<GrowableIOBuffer> HttpBasicState::read_buf() const {
diff --git a/chromium/net/http/http_basic_state.h b/chromium/net/http/http_basic_state.h
index 259c5022252..41298e4f7aa 100644
--- a/chromium/net/http/http_basic_state.h
+++ b/chromium/net/http/http_basic_state.h
@@ -10,7 +10,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
diff --git a/chromium/net/http/http_basic_stream.cc b/chromium/net/http/http_basic_stream.cc
index 436127f31b8..260ad55f2f5 100644
--- a/chromium/net/http/http_basic_stream.cc
+++ b/chromium/net/http/http_basic_stream.cc
@@ -117,6 +117,10 @@ void HttpBasicStream::Drain(HttpNetworkSession* session) {
// |drainer| will delete itself.
}
+void HttpBasicStream::PopulateNetErrorDetails(NetErrorDetails* /*details*/) {
+ return;
+}
+
void HttpBasicStream::SetPriority(RequestPriority priority) {
// TODO(akalin): Plumb this through to |connection_|.
}
diff --git a/chromium/net/http/http_basic_stream.h b/chromium/net/http/http_basic_stream.h
index c9428d6fb1f..0ca196250b5 100644
--- a/chromium/net/http/http_basic_stream.h
+++ b/chromium/net/http/http_basic_stream.h
@@ -13,7 +13,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/http/http_basic_state.h"
#include "net/http/http_stream.h"
@@ -78,6 +78,8 @@ class HttpBasicStream : public HttpStream {
void Drain(HttpNetworkSession* session) override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) override;
+
void SetPriority(RequestPriority priority) override;
private:
diff --git a/chromium/net/http/http_byte_range.cc b/chromium/net/http/http_byte_range.cc
index b43cb2e8008..ad12fa9847c 100644
--- a/chromium/net/http/http_byte_range.cc
+++ b/chromium/net/http/http_byte_range.cc
@@ -11,7 +11,7 @@
namespace {
-const int64 kPositionNotSpecified = -1;
+const int64_t kPositionNotSpecified = -1;
} // namespace
@@ -25,8 +25,8 @@ HttpByteRange::HttpByteRange()
}
// static
-HttpByteRange HttpByteRange::Bounded(int64 first_byte_position,
- int64 last_byte_position) {
+HttpByteRange HttpByteRange::Bounded(int64_t first_byte_position,
+ int64_t last_byte_position) {
HttpByteRange range;
range.set_first_byte_position(first_byte_position);
range.set_last_byte_position(last_byte_position);
@@ -34,14 +34,14 @@ HttpByteRange HttpByteRange::Bounded(int64 first_byte_position,
}
// static
-HttpByteRange HttpByteRange::RightUnbounded(int64 first_byte_position) {
+HttpByteRange HttpByteRange::RightUnbounded(int64_t first_byte_position) {
HttpByteRange range;
range.set_first_byte_position(first_byte_position);
return range;
}
// static
-HttpByteRange HttpByteRange::Suffix(int64 suffix_length) {
+HttpByteRange HttpByteRange::Suffix(int64_t suffix_length) {
HttpByteRange range;
range.set_suffix_length(suffix_length);
return range;
@@ -82,7 +82,7 @@ std::string HttpByteRange::GetHeaderValue() const {
first_byte_position(), last_byte_position());
}
-bool HttpByteRange::ComputeBounds(int64 size) {
+bool HttpByteRange::ComputeBounds(int64_t size) {
if (size < 0)
return false;
if (has_computed_bounds_)
diff --git a/chromium/net/http/http_byte_range.h b/chromium/net/http/http_byte_range.h
index 63c02f1ba5c..f83187407b7 100644
--- a/chromium/net/http/http_byte_range.h
+++ b/chromium/net/http/http_byte_range.h
@@ -5,9 +5,10 @@
#ifndef NET_HTTP_HTTP_BYTE_RANGE_H_
#define NET_HTTP_HTTP_BYTE_RANGE_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
namespace net {
@@ -20,21 +21,21 @@ class NET_EXPORT HttpByteRange {
HttpByteRange();
// Convenience constructors.
- static HttpByteRange Bounded(int64 first_byte_position,
- int64 last_byte_position);
- static HttpByteRange RightUnbounded(int64 first_byte_position);
- static HttpByteRange Suffix(int64 suffix_length);
+ static HttpByteRange Bounded(int64_t first_byte_position,
+ int64_t last_byte_position);
+ static HttpByteRange RightUnbounded(int64_t first_byte_position);
+ static HttpByteRange Suffix(int64_t suffix_length);
// Since this class is POD, we use constructor, assignment operator
// and destructor provided by compiler.
- int64 first_byte_position() const { return first_byte_position_; }
- void set_first_byte_position(int64 value) { first_byte_position_ = value; }
+ int64_t first_byte_position() const { return first_byte_position_; }
+ void set_first_byte_position(int64_t value) { first_byte_position_ = value; }
- int64 last_byte_position() const { return last_byte_position_; }
- void set_last_byte_position(int64 value) { last_byte_position_ = value; }
+ int64_t last_byte_position() const { return last_byte_position_; }
+ void set_last_byte_position(int64_t value) { last_byte_position_ = value; }
- int64 suffix_length() const { return suffix_length_; }
- void set_suffix_length(int64 value) { suffix_length_ = value; }
+ int64_t suffix_length() const { return suffix_length_; }
+ void set_suffix_length(int64_t value) { suffix_length_ = value; }
// Returns true if this is a suffix byte range.
bool IsSuffixByteRange() const;
@@ -57,12 +58,12 @@ class NET_EXPORT HttpByteRange {
// no side effect.
// Returns false if this method is called more than once and there will be
// no side effect.
- bool ComputeBounds(int64 size);
+ bool ComputeBounds(int64_t size);
private:
- int64 first_byte_position_;
- int64 last_byte_position_;
- int64 suffix_length_;
+ int64_t first_byte_position_;
+ int64_t last_byte_position_;
+ int64_t suffix_length_;
bool has_computed_bounds_;
};
diff --git a/chromium/net/http/http_byte_range_unittest.cc b/chromium/net/http/http_byte_range_unittest.cc
index 0a77da3ed39..412c7f80109 100644
--- a/chromium/net/http/http_byte_range_unittest.cc
+++ b/chromium/net/http/http_byte_range_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/macros.h"
#include "net/http/http_byte_range.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -11,9 +12,9 @@ namespace {
TEST(HttpByteRangeTest, ValidRanges) {
const struct {
- int64 first_byte_position;
- int64 last_byte_position;
- int64 suffix_length;
+ int64_t first_byte_position;
+ int64_t last_byte_position;
+ int64_t suffix_length;
bool valid;
} tests[] = {
{ -1, -1, 0, false },
@@ -38,13 +39,13 @@ TEST(HttpByteRangeTest, ValidRanges) {
TEST(HttpByteRangeTest, SetInstanceSize) {
const struct {
- int64 first_byte_position;
- int64 last_byte_position;
- int64 suffix_length;
- int64 instance_size;
+ int64_t first_byte_position;
+ int64_t last_byte_position;
+ int64_t suffix_length;
+ int64_t instance_size;
bool expected_return_value;
- int64 expected_lower_bound;
- int64 expected_upper_bound;
+ int64_t expected_lower_bound;
+ int64_t expected_upper_bound;
} tests[] = {
{ -10, 0, -1, 0, false, -1, -1 },
{ 10, 0, -1, 0, false, -1, -1 },
diff --git a/chromium/net/http/http_cache.cc b/chromium/net/http/http_cache.cc
index 796aeea5014..ae678fd2f8b 100644
--- a/chromium/net/http/http_cache.cc
+++ b/chromium/net/http/http_cache.cc
@@ -5,6 +5,7 @@
#include "net/http/http_cache.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -13,6 +14,7 @@
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
@@ -74,9 +76,11 @@ HttpCache::DefaultBackend::DefaultBackend(
HttpCache::DefaultBackend::~DefaultBackend() {}
// static
-HttpCache::BackendFactory* HttpCache::DefaultBackend::InMemory(int max_bytes) {
- return new DefaultBackend(MEMORY_CACHE, CACHE_BACKEND_DEFAULT,
- base::FilePath(), max_bytes, NULL);
+scoped_ptr<HttpCache::BackendFactory> HttpCache::DefaultBackend::InMemory(
+ int max_bytes) {
+ return make_scoped_ptr(new DefaultBackend(MEMORY_CACHE, CACHE_BACKEND_DEFAULT,
+ base::FilePath(), max_bytes,
+ nullptr));
}
int HttpCache::DefaultBackend::CreateBackend(
@@ -294,49 +298,38 @@ class HttpCache::QuicServerInfoFactoryAdaptor : public QuicServerInfoFactory {
};
//-----------------------------------------------------------------------------
-HttpCache::HttpCache(const HttpNetworkSession::Params& params,
- BackendFactory* backend_factory)
- : net_log_(params.net_log),
- backend_factory_(backend_factory),
- building_backend_(false),
- bypass_lock_for_test_(false),
- fail_conditionalization_for_test_(false),
- mode_(NORMAL),
- network_layer_(new HttpNetworkLayer(new HttpNetworkSession(params))),
- clock_(new base::DefaultClock()),
- weak_factory_(this) {
- SetupQuicServerInfoFactory(network_layer_->GetSession());
-}
-
-
-// This call doesn't change the shared |session|'s QuicServerInfoFactory because
-// |session| is shared.
HttpCache::HttpCache(HttpNetworkSession* session,
- BackendFactory* backend_factory)
- : net_log_(session->net_log()),
- backend_factory_(backend_factory),
- building_backend_(false),
- bypass_lock_for_test_(false),
- fail_conditionalization_for_test_(false),
- mode_(NORMAL),
- network_layer_(new HttpNetworkLayer(session)),
- clock_(new base::DefaultClock()),
- weak_factory_(this) {
-}
-
-HttpCache::HttpCache(HttpTransactionFactory* network_layer,
- NetLog* net_log,
- BackendFactory* backend_factory)
- : net_log_(net_log),
- backend_factory_(backend_factory),
+ scoped_ptr<BackendFactory> backend_factory,
+ bool set_up_quic_server_info)
+ : HttpCache(make_scoped_ptr(new HttpNetworkLayer(session)),
+ std::move(backend_factory),
+ set_up_quic_server_info) {}
+
+HttpCache::HttpCache(scoped_ptr<HttpTransactionFactory> network_layer,
+ scoped_ptr<BackendFactory> backend_factory,
+ bool set_up_quic_server_info)
+ : net_log_(nullptr),
+ backend_factory_(std::move(backend_factory)),
building_backend_(false),
bypass_lock_for_test_(false),
fail_conditionalization_for_test_(false),
mode_(NORMAL),
- network_layer_(network_layer),
+ network_layer_(std::move(network_layer)),
clock_(new base::DefaultClock()),
weak_factory_(this) {
- SetupQuicServerInfoFactory(network_layer_->GetSession());
+ HttpNetworkSession* session = network_layer_->GetSession();
+ // Session may be NULL in unittests.
+ // TODO(mmenke): Seems like tests could be changed to provide a session,
+ // rather than having logic only used in unit tests here.
+ if (session) {
+ net_log_ = session->net_log();
+ if (set_up_quic_server_info &&
+ !session->quic_stream_factory()->has_quic_server_info_factory()) {
+ // QuicStreamFactory takes ownership of QuicServerInfoFactoryAdaptor.
+ session->quic_stream_factory()->set_quic_server_info_factory(
+ new QuicServerInfoFactoryAdaptor(this));
+ }
+ }
}
HttpCache::~HttpCache() {
@@ -488,9 +481,10 @@ HttpNetworkSession* HttpCache::GetSession() {
scoped_ptr<HttpTransactionFactory>
HttpCache::SetHttpNetworkTransactionFactoryForTesting(
scoped_ptr<HttpTransactionFactory> new_network_layer) {
- scoped_ptr<HttpTransactionFactory> old_network_layer(network_layer_.Pass());
- network_layer_ = new_network_layer.Pass();
- return old_network_layer.Pass();
+ scoped_ptr<HttpTransactionFactory> old_network_layer(
+ std::move(network_layer_));
+ network_layer_ = std::move(new_network_layer);
+ return old_network_layer;
}
//-----------------------------------------------------------------------------
@@ -996,16 +990,6 @@ bool HttpCache::RemovePendingTransactionFromPendingOp(PendingOp* pending_op,
return false;
}
-void HttpCache::SetupQuicServerInfoFactory(HttpNetworkSession* session) {
- if (session &&
- !session->quic_stream_factory()->has_quic_server_info_factory()) {
- DCHECK(!quic_server_info_factory_);
- quic_server_info_factory_.reset(new QuicServerInfoFactoryAdaptor(this));
- session->quic_stream_factory()->set_quic_server_info_factory(
- quic_server_info_factory_.get());
- }
-}
-
void HttpCache::ProcessPendingQueue(ActiveEntry* entry) {
// Multiple readers may finish with an entry at once, so we want to batch up
// calls to OnProcessPendingQueue. This flag also tells us that we should
@@ -1159,7 +1143,7 @@ void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) {
// and the last call clears building_backend_.
backend_factory_.reset(); // Reclaim memory.
if (result == OK) {
- disk_cache_ = pending_op->backend.Pass();
+ disk_cache_ = std::move(pending_op->backend);
if (UseCertCache())
cert_cache_.reset(new DiskBasedCertCache(disk_cache_.get()));
}
diff --git a/chromium/net/http/http_cache.h b/chromium/net/http/http_cache.h
index 026d476e92f..618709adc8e 100644
--- a/chromium/net/http/http_cache.h
+++ b/chromium/net/http/http_cache.h
@@ -18,9 +18,9 @@
#include <set>
#include <string>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
@@ -106,7 +106,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory,
~DefaultBackend() override;
// Returns a factory for an in-memory cache.
- static BackendFactory* InMemory(int max_bytes);
+ static scoped_ptr<BackendFactory> InMemory(int max_bytes);
// BackendFactory implementation.
int CreateBackend(NetLog* net_log,
@@ -126,23 +126,24 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory,
static const int kPrefetchReuseMins = 5;
// The disk cache is initialized lazily (by CreateTransaction) in this case.
- // The HttpCache takes ownership of the |backend_factory|.
- HttpCache(const HttpNetworkSession::Params& params,
- BackendFactory* backend_factory);
-
- // The disk cache is initialized lazily (by CreateTransaction) in this case.
// Provide an existing HttpNetworkSession, the cache can construct a
// network layer with a shared HttpNetworkSession in order for multiple
// network layers to share information (e.g. authentication data). The
// HttpCache takes ownership of the |backend_factory|.
- HttpCache(HttpNetworkSession* session, BackendFactory* backend_factory);
-
- // Initialize the cache from its component parts. The lifetime of the
- // |network_layer| and |backend_factory| are managed by the HttpCache and
- // will be destroyed using |delete| when the HttpCache is destroyed.
- HttpCache(HttpTransactionFactory* network_layer,
- NetLog* net_log,
- BackendFactory* backend_factory);
+ //
+ // The HttpCache must be destroyed before the HttpNetworkSession.
+ //
+ // If |set_up_quic_server_info| is true, configures the cache to track
+ // information about servers supporting QUIC.
+ HttpCache(HttpNetworkSession* session,
+ scoped_ptr<BackendFactory> backend_factory,
+ bool set_up_quic_server_info);
+
+ // Initialize the cache from its component parts. |network_layer| and
+ // |backend_factory| will be destroyed when the HttpCache is.
+ HttpCache(scoped_ptr<HttpTransactionFactory> network_layer,
+ scoped_ptr<BackendFactory> backend_factory,
+ bool set_up_quic_server_info);
~HttpCache() override;
@@ -377,10 +378,6 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory,
// Removes the transaction |trans|, from the pending list of |pending_op|.
bool RemovePendingTransactionFromPendingOp(PendingOp* pending_op,
Transaction* trans);
-
- // Instantiates and sets QUIC server info factory.
- void SetupQuicServerInfoFactory(HttpNetworkSession* session);
-
// Resumes processing the pending list of |entry|.
void ProcessPendingQueue(ActiveEntry* entry);
@@ -418,8 +415,6 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory,
Mode mode_;
- scoped_ptr<QuicServerInfoFactoryAdaptor> quic_server_info_factory_;
-
scoped_ptr<HttpTransactionFactory> network_layer_;
scoped_ptr<disk_cache::Backend> disk_cache_;
diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc
index 9dd8458e2e2..3b9f28dc30c 100644
--- a/chromium/net/http/http_cache_transaction.cc
+++ b/chromium/net/http/http_cache_transaction.cc
@@ -18,9 +18,9 @@
#include "base/compiler_specific.h"
#include "base/format_macros.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h" // For HexEncode.
#include "base/strings/string_piece.h"
@@ -32,7 +32,6 @@
#include "net/base/auth.h"
#include "net/base/load_flags.h"
#include "net/base/load_timing_info.h"
-#include "net/base/net_errors.h"
#include "net/base/upload_data_stream.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/x509_certificate.h"
@@ -406,6 +405,7 @@ int HttpCache::Transaction::RestartIgnoringLastError(
int HttpCache::Transaction::RestartWithCertificate(
X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
const CompletionCallback& callback) {
DCHECK(!callback.is_null());
@@ -415,7 +415,8 @@ int HttpCache::Transaction::RestartWithCertificate(
if (!cache_.get())
return ERR_UNEXPECTED;
- int rv = RestartNetworkRequestWithCertificate(client_cert);
+ int rv =
+ RestartNetworkRequestWithCertificate(client_cert, client_private_key);
if (rv == ERR_IO_PENDING)
callback_ = callback;
@@ -611,6 +612,13 @@ bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
return false;
}
+void HttpCache::Transaction::PopulateNetErrorDetails(
+ NetErrorDetails* details) const {
+ if (network_trans_)
+ return network_trans_->PopulateNetErrorDetails(details);
+ return;
+}
+
void HttpCache::Transaction::SetPriority(RequestPriority priority) {
priority_ = priority;
if (network_trans_)
@@ -1300,11 +1308,6 @@ int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() {
// transaction then metadata will be written to cache twice. If prefetching
// becomes more common, consider combining the writes.
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "422516 HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch"));
-
next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE;
return WriteResponseInfoToEntry(false);
}
@@ -1604,11 +1607,6 @@ int HttpCache::Transaction::DoUpdateCachedResponse() {
}
int HttpCache::Transaction::DoCacheWriteUpdatedResponse() {
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "422516 HttpCache::Transaction::DoCacheWriteUpdatedResponse"));
-
next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE;
return WriteResponseInfoToEntry(false);
}
@@ -1686,11 +1684,6 @@ int HttpCache::Transaction::DoOverwriteCachedResponse() {
}
int HttpCache::Transaction::DoCacheWriteResponse() {
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "422516 HttpCache::Transaction::DoCacheWriteResponse"));
-
next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE;
return WriteResponseInfoToEntry(truncated_);
}
@@ -1890,7 +1883,7 @@ int HttpCache::Transaction::DoCacheWriteDataComplete(int result) {
result = write_len_;
} else if (!done_reading_ && entry_ && (!partial_ || truncated_)) {
int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
- int64 body_size = response_.headers->GetContentLength();
+ int64_t body_size = response_.headers->GetContentLength();
if (body_size >= 0 && body_size <= current_size)
done_reading_ = true;
}
@@ -2296,13 +2289,15 @@ int HttpCache::Transaction::RestartNetworkRequest() {
}
int HttpCache::Transaction::RestartNetworkRequestWithCertificate(
- X509Certificate* client_cert) {
+ X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key) {
DCHECK(mode_ & WRITE || mode_ == NONE);
DCHECK(network_trans_.get());
DCHECK_EQ(STATE_NONE, next_state_);
next_state_ = STATE_SEND_REQUEST_COMPLETE;
- int rv = network_trans_->RestartWithCertificate(client_cert, io_callback_);
+ int rv = network_trans_->RestartWithCertificate(
+ client_cert, client_private_key, io_callback_);
if (rv != ERR_IO_PENDING)
return DoLoop(rv);
return rv;
@@ -2358,8 +2353,8 @@ ValidationType HttpCache::Transaction::RequiresValidation() {
cache_->clock_->Now());
if (validation_required_by_headers == VALIDATION_ASYNCHRONOUS) {
- // Asynchronous revalidation is only supported for GET and HEAD methods.
- if (request_->method != "GET" && request_->method != "HEAD")
+ // Asynchronous revalidation is only supported for GET methods.
+ if (request_->method != "GET")
return VALIDATION_SYNCHRONOUS;
}
@@ -2907,8 +2902,9 @@ void HttpCache::Transaction::RecordHistograms() {
}
TimeDelta before_send_time = send_request_since_ - first_cache_access_since_;
- int64 before_send_percent = (total_time.ToInternalValue() == 0) ?
- 0 : before_send_time * 100 / total_time;
+ int64_t before_send_percent = (total_time.ToInternalValue() == 0)
+ ? 0
+ : before_send_time * 100 / total_time;
DCHECK_GE(before_send_percent, 0);
DCHECK_LE(before_send_percent, 100);
base::HistogramBase::Sample before_send_sample =
diff --git a/chromium/net/http/http_cache_transaction.h b/chromium/net/http/http_cache_transaction.h
index 482bb644977..175e3f948be 100644
--- a/chromium/net/http/http_cache_transaction.h
+++ b/chromium/net/http/http_cache_transaction.h
@@ -13,7 +13,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -22,6 +22,7 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/load_states.h"
+#include "net/base/net_error_details.h"
#include "net/base/request_priority.h"
#include "net/base/upload_progress.h"
#include "net/http/http_cache.h"
@@ -39,6 +40,7 @@ namespace net {
class PartialData;
struct HttpRequestInfo;
struct LoadTimingInfo;
+class SSLPrivateKey;
// This is the transaction that is returned by the HttpCache transaction
// factory.
@@ -134,6 +136,7 @@ class HttpCache::Transaction : public HttpTransaction {
const BoundNetLog& net_log) override;
int RestartIgnoringLastError(const CompletionCallback& callback) override;
int RestartWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
const CompletionCallback& callback) override;
int RestartWithAuth(const AuthCredentials& credentials,
const CompletionCallback& callback) override;
@@ -152,6 +155,7 @@ class HttpCache::Transaction : public HttpTransaction {
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) const override;
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -333,7 +337,8 @@ class HttpCache::Transaction : public HttpTransaction {
// Called to restart a network transaction with a client certificate.
// Returns network error code.
- int RestartNetworkRequestWithCertificate(X509Certificate* client_cert);
+ int RestartNetworkRequestWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key);
// Called to restart a network transaction with authentication credentials.
// Returns network error code.
diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc
index 6eeef8f1157..44039e41a3d 100644
--- a/chromium/net/http/http_cache_unittest.cc
+++ b/chromium/net/http/http_cache_unittest.cc
@@ -5,12 +5,14 @@
#include "net/http/http_cache.h"
#include <stdint.h>
-
#include <algorithm>
+#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/memory/scoped_vector.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
@@ -490,10 +492,10 @@ void Verify206Response(const std::string& response, int start, int end) {
ASSERT_EQ(206, headers->response_code());
- int64 range_start, range_end, object_size;
+ int64_t range_start, range_end, object_size;
ASSERT_TRUE(
headers->GetContentRange(&range_start, &range_end, &object_size));
- int64 content_length = headers->GetContentLength();
+ int64_t content_length = headers->GetContentLength();
int length = end - start + 1;
ASSERT_EQ(length, content_length);
@@ -702,10 +704,11 @@ TEST(HttpCache, SimpleGETNoDiskCache) {
TEST(HttpCache, SimpleGETNoDiskCache2) {
// This will initialize a cache object with NULL backend.
- MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
+ scoped_ptr<MockBlockingBackendFactory> factory(
+ new MockBlockingBackendFactory());
factory->set_fail(true);
factory->FinishCreation(); // We'll complete synchronously.
- MockHttpCache cache(factory);
+ MockHttpCache cache(std::move(factory));
// Read from the network, and don't use the cache.
RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
@@ -1413,12 +1416,12 @@ TEST(HttpCache, SimpleGET_DoomWithPending) {
MockHttpRequest writer_request(kSimpleGET_Transaction);
writer_request.load_flags = LOAD_BYPASS_CACHE;
- ScopedVector<Context> context_list;
+ std::vector<scoped_ptr<Context>> context_list;
const int kNumTransactions = 4;
for (int i = 0; i < kNumTransactions; ++i) {
- context_list.push_back(new Context());
- Context* c = context_list[i];
+ context_list.push_back(make_scoped_ptr(new Context()));
+ Context* c = context_list[i].get();
c->result = cache.CreateTransaction(&c->trans);
ASSERT_EQ(OK, c->result);
@@ -1437,13 +1440,12 @@ TEST(HttpCache, SimpleGET_DoomWithPending) {
EXPECT_EQ(2, cache.network_layer()->transaction_count());
// Cancel the first queued transaction.
- delete context_list[1];
- context_list.get()[1] = NULL;
+ context_list[1].reset();
for (int i = 0; i < kNumTransactions; ++i) {
if (i == 1)
continue;
- Context* c = context_list[i];
+ Context* c = context_list[i].get();
ASSERT_EQ(ERR_IO_PENDING, c->result);
c->result = c->callback.WaitForResult();
ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
@@ -1744,8 +1746,8 @@ TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
// Tests that we can delete the HttpCache and deal with queued transactions
// ("waiting for the backend" as opposed to Active or Doomed entries).
TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
- scoped_ptr<MockHttpCache> cache(new MockHttpCache(
- new MockBackendNoCbFactory()));
+ scoped_ptr<MockHttpCache> cache(
+ new MockHttpCache(make_scoped_ptr(new MockBackendNoCbFactory())));
MockHttpRequest request(kSimpleGET_Transaction);
@@ -1782,7 +1784,7 @@ TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
// Tests that we queue requests when initializing the backend.
TEST(HttpCache, SimpleGET_WaitForBackend) {
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(factory);
+ MockHttpCache cache(make_scoped_ptr(factory));
MockHttpRequest request0(kSimpleGET_Transaction);
MockHttpRequest request1(kTypicalGET_Transaction);
@@ -1828,7 +1830,7 @@ TEST(HttpCache, SimpleGET_WaitForBackend) {
// to be initialized.
TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache cache(factory);
+ MockHttpCache cache(make_scoped_ptr(factory));
MockHttpRequest request0(kSimpleGET_Transaction);
MockHttpRequest request1(kTypicalGET_Transaction);
@@ -1882,7 +1884,7 @@ TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
// Tests that we can delete the cache while creating the backend.
TEST(HttpCache, DeleteCacheWaitingForBackend) {
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
+ scoped_ptr<MockHttpCache> cache(new MockHttpCache(make_scoped_ptr(factory)));
MockHttpRequest request(kSimpleGET_Transaction);
@@ -1914,7 +1916,7 @@ TEST(HttpCache, DeleteCacheWaitingForBackend) {
// one of the callbacks.
TEST(HttpCache, DeleteCacheWaitingForBackend2) {
MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
- MockHttpCache* cache = new MockHttpCache(factory);
+ MockHttpCache* cache = new MockHttpCache(make_scoped_ptr(factory));
DeleteCacheCompletionCallback cb(cache);
disk_cache::Backend* backend;
@@ -2923,11 +2925,12 @@ TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
MockTransaction transaction(kSimplePOST_Transaction);
- const int64 kUploadId = 1; // Just a dummy value.
+ const int64_t kUploadId = 1; // Just a dummy value.
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers),
kUploadId);
MockHttpRequest request(transaction);
request.upload_data_stream = &upload_data_stream;
@@ -2955,11 +2958,12 @@ TEST(HttpCache, SimplePOST_WithRanges) {
MockTransaction transaction(kSimplePOST_Transaction);
transaction.request_headers = "Range: bytes = 0-4\r\n";
- const int64 kUploadId = 1; // Just a dummy value.
+ const int64_t kUploadId = 1; // Just a dummy value.
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers),
kUploadId);
MockHttpRequest request(transaction);
@@ -2977,9 +2981,10 @@ TEST(HttpCache, SimplePOST_WithRanges) {
TEST(HttpCache, SimplePOST_SeparateCache) {
MockHttpCache cache;
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
MockTransaction transaction(kSimplePOST_Transaction);
MockHttpRequest req1(transaction);
@@ -3016,9 +3021,10 @@ TEST(HttpCache, SimplePOST_Invalidate_205) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
transaction.method = "POST";
transaction.status = "HTTP/1.1 205 No Content";
@@ -3055,9 +3061,10 @@ TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
transaction.method = "POST";
transaction.status = "HTTP/1.1 205 No Content";
@@ -3081,14 +3088,16 @@ TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
// Tests that processing a POST before creating the backend doesn't crash.
TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
// This will initialize a cache object with NULL backend.
- MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
+ scoped_ptr<MockBlockingBackendFactory> factory(
+ new MockBlockingBackendFactory());
factory->set_fail(true);
factory->FinishCreation();
- MockHttpCache cache(factory);
+ MockHttpCache cache(std::move(factory));
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
MockTransaction transaction(kSimplePOST_Transaction);
AddMockTransaction(&transaction);
@@ -3115,9 +3124,10 @@ TEST(HttpCache, SimplePOST_DontInvalidate_100) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
transaction.method = "POST";
transaction.status = "HTTP/1.1 100 Continue";
@@ -3426,9 +3436,10 @@ TEST(HttpCache, SimplePUT_Miss) {
MockTransaction transaction(kSimplePOST_Transaction);
transaction.method = "PUT";
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
MockHttpRequest request(transaction);
request.upload_data_stream = &upload_data_stream;
@@ -3455,9 +3466,10 @@ TEST(HttpCache, SimplePUT_Invalidate) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
transaction.method = "PUT";
MockHttpRequest req2(transaction);
@@ -3491,9 +3503,10 @@ TEST(HttpCache, SimplePUT_Invalidate_305) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
transaction.method = "PUT";
transaction.status = "HTTP/1.1 305 Use Proxy";
@@ -3529,9 +3542,10 @@ TEST(HttpCache, SimplePUT_DontInvalidate_404) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
transaction.method = "PUT";
transaction.status = "HTTP/1.1 404 Not Found";
@@ -3559,9 +3573,10 @@ TEST(HttpCache, SimpleDELETE_Miss) {
MockTransaction transaction(kSimplePOST_Transaction);
transaction.method = "DELETE";
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
MockHttpRequest request(transaction);
request.upload_data_stream = &upload_data_stream;
@@ -3588,9 +3603,10 @@ TEST(HttpCache, SimpleDELETE_Invalidate) {
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello", 5));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
transaction.method = "DELETE";
MockHttpRequest req2(transaction);
@@ -5417,10 +5433,11 @@ TEST(HttpCache, RangeGET_LargeValues) {
// Tests that we don't crash with a range request if the disk cache was not
// initialized properly.
TEST(HttpCache, RangeGET_NoDiskCache) {
- MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
+ scoped_ptr<MockBlockingBackendFactory> factory(
+ new MockBlockingBackendFactory());
factory->set_fail(true);
factory->FinishCreation(); // We'll complete synchronously.
- MockHttpCache cache(factory);
+ MockHttpCache cache(std::move(factory));
AddMockTransaction(&kRangeGET_TransactionOK);
diff --git a/chromium/net/http/http_chunked_decoder.h b/chromium/net/http/http_chunked_decoder.h
index 23076f9b368..87412deb102 100644
--- a/chromium/net/http/http_chunked_decoder.h
+++ b/chromium/net/http/http_chunked_decoder.h
@@ -45,6 +45,8 @@
#ifndef NET_HTTP_HTTP_CHUNKED_DECODER_H_
#define NET_HTTP_HTTP_CHUNKED_DECODER_H_
+#include <stddef.h>
+
#include <string>
#include "net/base/net_export.h"
diff --git a/chromium/net/http/http_chunked_decoder_unittest.cc b/chromium/net/http/http_chunked_decoder_unittest.cc
index 06dd353ca68..2f2ab2501e0 100644
--- a/chromium/net/http/http_chunked_decoder_unittest.cc
+++ b/chromium/net/http/http_chunked_decoder_unittest.cc
@@ -4,7 +4,6 @@
#include "net/http/http_chunked_decoder.h"
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/http/http_content_disposition.cc b/chromium/net/http/http_content_disposition.cc
index 28ea8bd5547..bef2d44a146 100644
--- a/chromium/net/http/http_content_disposition.cc
+++ b/chromium/net/http/http_content_disposition.cc
@@ -10,6 +10,7 @@
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "net/base/escape.h"
#include "net/base/net_string_util.h"
#include "net/base/net_util.h"
#include "net/http/http_util.h"
diff --git a/chromium/net/http/http_content_disposition.h b/chromium/net/http/http_content_disposition.h
index c96ba618603..0f1b5ac066d 100644
--- a/chromium/net/http/http_content_disposition.h
+++ b/chromium/net/http/http_content_disposition.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
namespace net {
diff --git a/chromium/net/http/http_log_util.cc b/chromium/net/http/http_log_util.cc
index 87c2fd99f19..8146f0d6b17 100644
--- a/chromium/net/http/http_log_util.cc
+++ b/chromium/net/http/http_log_util.cc
@@ -4,9 +4,11 @@
#include "net/http/http_log_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "net/http/http_auth_challenge_tokenizer.h"
+#include "net/http/http_auth_scheme.h"
#include "net/http/http_util.h"
namespace net {
@@ -26,7 +28,7 @@ bool ShouldRedactChallenge(HttpAuthChallengeTokenizer* challenge) {
// Ignore Basic and Digest authentication challenges, as they contain
// public information.
- if (scheme == "basic" || scheme == "digest")
+ if (scheme == kBasicAuthScheme || scheme == kDigestAuthScheme)
return false;
return true;
@@ -42,7 +44,7 @@ std::string ElideHeaderValueForNetLog(NetLogCaptureMode capture_mode,
if (redact_begin == redact_end &&
!capture_mode.include_cookies_and_credentials()) {
- // Note: this logic should be kept in sync with stripCookiesAndLoginInfo in
+ // Note: this logic should be kept in sync with stripCookieOrLoginInfo in
// chrome/browser/resources/net_internals/log_view_painter.js.
if (base::EqualsCaseInsensitiveASCII(header, "set-cookie") ||
@@ -73,4 +75,16 @@ std::string ElideHeaderValueForNetLog(NetLogCaptureMode capture_mode,
std::string(redact_end, value.end());
}
+std::string ElideGoAwayDebugDataForNetLog(NetLogCaptureMode capture_mode,
+ base::StringPiece debug_data) {
+ // Note: this logic should be kept in sync with stripGoAwayDebugData in
+ // chrome/browser/resources/net_internals/log_view_painter.js.
+ if (capture_mode.include_cookies_and_credentials()) {
+ return debug_data.as_string();
+ }
+
+ return std::string("[") + base::SizeTToString(debug_data.size()) +
+ std::string(" bytes were stripped]");
+}
+
} // namespace net
diff --git a/chromium/net/http/http_log_util.h b/chromium/net/http/http_log_util.h
index 77589433256..5fda79ccf13 100644
--- a/chromium/net/http/http_log_util.h
+++ b/chromium/net/http/http_log_util.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/log/net_log.h"
@@ -19,6 +20,12 @@ NET_EXPORT_PRIVATE std::string ElideHeaderValueForNetLog(
const std::string& header,
const std::string& value);
+// Given an HTTP/2 GOAWAY frame |debug_data|, returns the elided version
+// according to |capture_mode|.
+NET_EXPORT_PRIVATE std::string ElideGoAwayDebugDataForNetLog(
+ NetLogCaptureMode capture_mode,
+ base::StringPiece debug_data);
+
} // namespace net
#endif // NET_HTTP_HTTP_LOG_UTIL_
diff --git a/chromium/net/http/http_log_util_unittest.cc b/chromium/net/http/http_log_util_unittest.cc
index bd9c79f0680..6b8d48e378f 100644
--- a/chromium/net/http/http_log_util_unittest.cc
+++ b/chromium/net/http/http_log_util_unittest.cc
@@ -68,4 +68,14 @@ TEST(HttpLogUtilTest, ElideHeaderValueForNetLog) {
"WWW-Authenticate", "NTLM 1234 "));
}
+TEST(HttpLogUtilTest, ElideGoAwayDebugDataForNetLog) {
+ // Only elide for appropriate log level.
+ EXPECT_EQ(
+ "[6 bytes were stripped]",
+ ElideGoAwayDebugDataForNetLog(NetLogCaptureMode::Default(), "foobar"));
+ EXPECT_EQ("foobar",
+ ElideGoAwayDebugDataForNetLog(
+ NetLogCaptureMode::IncludeCookiesAndCredentials(), "foobar"));
+}
+
} // namspace net
diff --git a/chromium/net/http/http_network_layer.cc b/chromium/net/http/http_network_layer.cc
index 8e6b35cb25e..169a1cc1be5 100644
--- a/chromium/net/http/http_network_layer.cc
+++ b/chromium/net/http/http_network_layer.cc
@@ -22,11 +22,11 @@ namespace net {
HttpNetworkLayer::HttpNetworkLayer(HttpNetworkSession* session)
: session_(session),
suspended_(false) {
- DCHECK(session_.get());
+ DCHECK(session_);
#if defined(OS_WIN)
- base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
- if (power_monitor)
- power_monitor->AddObserver(this);
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->AddObserver(this);
#endif
}
@@ -51,13 +51,13 @@ HttpCache* HttpNetworkLayer::GetCache() {
return NULL;
}
-HttpNetworkSession* HttpNetworkLayer::GetSession() { return session_.get(); }
+HttpNetworkSession* HttpNetworkLayer::GetSession() {
+ return session_;
+}
void HttpNetworkLayer::OnSuspend() {
suspended_ = true;
-
- if (session_.get())
- session_->CloseIdleConnections();
+ session_->CloseIdleConnections();
}
void HttpNetworkLayer::OnResume() {
diff --git a/chromium/net/http/http_network_layer.h b/chromium/net/http/http_network_layer.h
index 5ade926c3bd..3026f2e1eea 100644
--- a/chromium/net/http/http_network_layer.h
+++ b/chromium/net/http/http_network_layer.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/power_monitor/power_observer.h"
@@ -26,7 +26,8 @@ class NET_EXPORT HttpNetworkLayer
NON_EXPORTED_BASE(public base::NonThreadSafe) {
public:
// Construct a HttpNetworkLayer with an existing HttpNetworkSession which
- // contains a valid ProxyService.
+ // contains a valid ProxyService. The HttpNetworkLayer must be destroyed
+ // before |session|.
explicit HttpNetworkLayer(HttpNetworkSession* session);
~HttpNetworkLayer() override;
@@ -41,7 +42,7 @@ class NET_EXPORT HttpNetworkLayer
void OnResume() override;
private:
- const scoped_refptr<HttpNetworkSession> session_;
+ HttpNetworkSession* const session_;
bool suspended_;
DISALLOW_COPY_AND_ASSIGN(HttpNetworkLayer);
diff --git a/chromium/net/http/http_network_layer_unittest.cc b/chromium/net/http/http_network_layer_unittest.cc
index 153423e45ff..8589cbf2acc 100644
--- a/chromium/net/http/http_network_layer_unittest.cc
+++ b/chromium/net/http/http_network_layer_unittest.cc
@@ -4,7 +4,8 @@
#include "net/http/http_network_layer.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/strings/stringprintf.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
@@ -35,7 +36,7 @@ class HttpNetworkLayerTest : public PlatformTest {
void ConfigureTestDependencies(scoped_ptr<ProxyService> proxy_service) {
cert_verifier_.reset(new MockCertVerifier);
transport_security_state_.reset(new TransportSecurityState);
- proxy_service_ = proxy_service.Pass();
+ proxy_service_ = std::move(proxy_service);
HttpNetworkSession::Params session_params;
session_params.client_socket_factory = &mock_socket_factory_;
session_params.host_resolver = &host_resolver_;
@@ -45,7 +46,7 @@ class HttpNetworkLayerTest : public PlatformTest {
session_params.ssl_config_service = ssl_config_service_.get();
session_params.http_server_properties =
http_server_properties_.GetWeakPtr();
- network_session_ = new HttpNetworkSession(session_params);
+ network_session_.reset(new HttpNetworkSession(session_params));
factory_.reset(new HttpNetworkLayer(network_session_.get()));
}
@@ -259,7 +260,7 @@ class HttpNetworkLayerTest : public PlatformTest {
scoped_ptr<TransportSecurityState> transport_security_state_;
scoped_ptr<ProxyService> proxy_service_;
const scoped_refptr<SSLConfigService> ssl_config_service_;
- scoped_refptr<HttpNetworkSession> network_session_;
+ scoped_ptr<HttpNetworkSession> network_session_;
scoped_ptr<HttpNetworkLayer> factory_;
HttpServerPropertiesImpl http_server_properties_;
};
diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc
index 6f364c55630..935453e5235 100644
--- a/chromium/net/http/http_network_session.cc
+++ b/chromium/net/http/http_network_session.cc
@@ -6,11 +6,13 @@
#include <utility>
+#include "base/atomic_sequence_num.h"
#include "base/compiler_specific.h"
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "net/http/http_auth_handler_factory.h"
@@ -34,9 +36,12 @@ namespace net {
namespace {
+base::StaticAtomicSequenceNumber g_next_shard_id;
+
ClientSocketPoolManager* CreateSocketPoolManager(
HttpNetworkSession::SocketPoolType pool_type,
- const HttpNetworkSession::Params& params) {
+ const HttpNetworkSession::Params& params,
+ const std::string& ssl_session_cache_shard) {
// TODO(yutak): Differentiate WebSocket pool manager and allow more
// simultaneous connections for WebSockets.
return new ClientSocketPoolManagerImpl(
@@ -45,31 +50,31 @@ ClientSocketPoolManager* CreateSocketPoolManager(
: ClientSocketFactory::GetDefaultFactory(),
params.host_resolver, params.cert_verifier, params.channel_id_service,
params.transport_security_state, params.cert_transparency_verifier,
- params.cert_policy_enforcer, params.ssl_session_cache_shard,
+ params.ct_policy_enforcer, ssl_session_cache_shard,
params.ssl_config_service, pool_type);
}
} // unnamed namespace
// The maximum receive window sizes for HTTP/2 sessions and streams.
-const int32 kSpdySessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
-const int32 kSpdyStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
+const int32_t kSpdySessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
+const int32_t kSpdyStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
// QUIC's socket receive buffer size.
// We should adaptively set this buffer size, but for now, we'll use a size
// that seems large enough to receive data at line rate for most connections,
// and does not consume "too much" memory.
-const int32 kQuicSocketReceiveBufferSize = 1024 * 1024; // 1MB
+const int32_t kQuicSocketReceiveBufferSize = 1024 * 1024; // 1MB
// Number of recent connections to consider for certain thresholds
// that trigger disabling QUIC. E.g. disable QUIC if PUBLIC_RESET was
// received post handshake for at least 2 of 20 recent connections.
-const int32 kQuicMaxRecentDisabledReasons = 20;
+const int32_t kQuicMaxRecentDisabledReasons = 20;
HttpNetworkSession::Params::Params()
: client_socket_factory(NULL),
host_resolver(NULL),
cert_verifier(NULL),
- cert_policy_enforcer(NULL),
+ ct_policy_enforcer(NULL),
channel_id_service(NULL),
transport_security_state(NULL),
cert_transparency_verifier(NULL),
@@ -93,8 +98,9 @@ HttpNetworkSession::Params::Params()
time_func(&base::TimeTicks::Now),
use_alternative_services(false),
alternative_service_probability_threshold(1),
+ enable_npn(true),
+ enable_brotli(false),
enable_quic(false),
- enable_insecure_quic(false),
enable_quic_for_proxies(false),
enable_quic_port_selection(true),
quic_always_require_handshake_confirmation(false),
@@ -108,14 +114,20 @@ HttpNetworkSession::Params::Params()
quic_packet_loss_threshold(1.0f),
quic_socket_receive_buffer_size(kQuicSocketReceiveBufferSize),
quic_delay_tcp_race(false),
+ quic_max_server_configs_stored_in_properties(0u),
quic_clock(NULL),
quic_random(NULL),
quic_max_packet_length(kDefaultMaxPacketSize),
enable_user_alternate_protocol_ports(false),
- quic_crypto_client_stream_factory(NULL),
+ quic_crypto_client_stream_factory(
+ QuicCryptoClientStreamFactory::GetDefaultFactory()),
quic_max_recent_disabled_reasons(kQuicMaxRecentDisabledReasons),
quic_threshold_public_resets_post_handshake(0),
quic_threshold_timeouts_streams_open(0),
+ quic_close_sessions_on_ip_change(false),
+ quic_idle_connection_timeout_seconds(kIdleConnectionTimeoutSeconds),
+ quic_disable_preconnect_if_0rtt(false),
+ quic_migrate_sessions_on_network_change(false),
proxy_delegate(NULL) {
quic_supported_versions.push_back(QUIC_VERSION_25);
}
@@ -131,10 +143,6 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
http_auth_handler_factory_(params.http_auth_handler_factory),
proxy_service_(params.proxy_service),
ssl_config_service_(params.ssl_config_service),
- normal_socket_pool_manager_(
- CreateSocketPoolManager(NORMAL_SOCKET_POOL, params)),
- websocket_socket_pool_manager_(
- CreateSocketPoolManager(WEBSOCKET_SOCKET_POOL, params)),
quic_stream_factory_(
params.host_resolver,
params.client_socket_factory
@@ -142,9 +150,10 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
: ClientSocketFactory::GetDefaultFactory(),
params.http_server_properties,
params.cert_verifier,
- params.cert_policy_enforcer,
+ params.ct_policy_enforcer,
params.channel_id_service,
params.transport_security_state,
+ params.cert_transparency_verifier,
params.socket_performance_watcher_factory,
params.quic_crypto_client_stream_factory,
params.quic_random ? params.quic_random : QuicRandom::GetInstance(),
@@ -167,6 +176,10 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
params.quic_threshold_timeouts_streams_open,
params.quic_socket_receive_buffer_size,
params.quic_delay_tcp_race,
+ params.quic_max_server_configs_stored_in_properties,
+ params.quic_close_sessions_on_ip_change,
+ params.quic_idle_connection_timeout_seconds,
+ params.quic_migrate_sessions_on_network_change,
params.quic_connection_options),
spdy_session_pool_(params.host_resolver,
params.ssl_config_service,
@@ -187,6 +200,13 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
DCHECK(ssl_config_service_.get());
CHECK(http_server_properties_);
+ const std::string ssl_session_cache_shard =
+ "http_network_session/" + base::IntToString(g_next_shard_id.GetNext());
+ normal_socket_pool_manager_.reset(CreateSocketPoolManager(
+ NORMAL_SOCKET_POOL, params, ssl_session_cache_shard));
+ websocket_socket_pool_manager_.reset(CreateSocketPoolManager(
+ WEBSOCKET_SOCKET_POOL, params, ssl_session_cache_shard));
+
for (int i = ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION;
i <= ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION; ++i) {
enabled_protocols_[i - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION] = false;
@@ -219,6 +239,8 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
http_server_properties_->SetAlternativeServiceProbabilityThreshold(
params.alternative_service_probability_threshold);
+ http_server_properties_->SetMaxServerConfigsStoredInProperties(
+ params.quic_max_server_configs_stored_in_properties);
}
HttpNetworkSession::~HttpNetworkSession() {
@@ -289,21 +311,37 @@ scoped_ptr<base::Value> HttpNetworkSession::QuicInfoToValue() const {
it != params_.quic_connection_options.end(); ++it) {
connection_options->AppendString("'" + QuicUtils::TagToString(*it) + "'");
}
- dict->Set("connection_options", connection_options.Pass());
+ dict->Set("connection_options", std::move(connection_options));
dict->SetString("origin_to_force_quic_on",
params_.origin_to_force_quic_on.ToString());
dict->SetDouble("alternative_service_probability_threshold",
params_.alternative_service_probability_threshold);
+ dict->SetDouble("load_server_info_timeout_srtt_multiplier",
+ params_.quic_load_server_info_timeout_srtt_multiplier);
+ dict->SetBoolean("enable_connection_racing",
+ params_.quic_enable_connection_racing);
+ dict->SetBoolean("disable_disk_cache", params_.quic_disable_disk_cache);
+ dict->SetBoolean("prefer_aes", params_.quic_prefer_aes);
+ dict->SetInteger("max_number_of_lossy_connections",
+ params_.quic_max_number_of_lossy_connections);
+ dict->SetDouble("packet_loss_threshold", params_.quic_packet_loss_threshold);
+ dict->SetBoolean("delay_tcp_race", params_.quic_delay_tcp_race);
+ dict->SetInteger("max_server_configs_stored_in_properties",
+ params_.quic_max_server_configs_stored_in_properties);
+ dict->SetInteger("idle_connection_timeout_seconds",
+ params_.quic_idle_connection_timeout_seconds);
+ dict->SetBoolean("disable_preconnect_if_0rtt",
+ params_.quic_disable_preconnect_if_0rtt);
dict->SetString("disabled_reason",
quic_stream_factory_.QuicDisabledReasonString());
- return dict.Pass();
+ return std::move(dict);
}
void HttpNetworkSession::CloseAllConnections() {
normal_socket_pool_manager_->FlushSocketPoolsWithError(ERR_ABORTED);
websocket_socket_pool_manager_->FlushSocketPoolsWithError(ERR_ABORTED);
spdy_session_pool_.CloseCurrentSessions(ERR_ABORTED);
- quic_stream_factory_.CloseAllSessions(ERR_ABORTED);
+ quic_stream_factory_.CloseAllSessions(ERR_ABORTED, QUIC_INTERNAL_ERROR);
}
void HttpNetworkSession::CloseIdleConnections() {
@@ -318,11 +356,19 @@ bool HttpNetworkSession::IsProtocolEnabled(AlternateProtocol protocol) const {
protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION];
}
-void HttpNetworkSession::GetNextProtos(NextProtoVector* next_protos) const {
+void HttpNetworkSession::GetAlpnProtos(NextProtoVector* alpn_protos) const {
if (HttpStreamFactory::spdy_enabled()) {
- *next_protos = next_protos_;
+ *alpn_protos = next_protos_;
+ } else {
+ alpn_protos->clear();
+ }
+}
+
+void HttpNetworkSession::GetNpnProtos(NextProtoVector* npn_protos) const {
+ if (HttpStreamFactory::spdy_enabled() && params_.enable_npn) {
+ *npn_protos = next_protos_;
} else {
- next_protos->clear();
+ npn_protos->clear();
}
}
diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h
index c0503c9f73c..9f984896382 100644
--- a/chromium/net/http/http_network_session.h
+++ b/chromium/net/http/http_network_session.h
@@ -5,11 +5,14 @@
#ifndef NET_HTTP_HTTP_NETWORK_SESSION_H_
#define NET_HTTP_HTTP_NETWORK_SESSION_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <set>
#include <string>
+#include <unordered_set>
#include <vector>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
@@ -29,7 +32,7 @@ class Value;
namespace net {
-class CertPolicyEnforcer;
+class CTPolicyEnforcer;
class CertVerifier;
class ChannelIDService;
class ClientSocketFactory;
@@ -57,8 +60,7 @@ class TransportSecurityState;
// This class holds session objects used by HttpNetworkTransaction objects.
class NET_EXPORT HttpNetworkSession
- : public base::RefCounted<HttpNetworkSession>,
- NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ : NON_EXPORTED_BASE(public base::NonThreadSafe) {
public:
struct NET_EXPORT Params {
Params();
@@ -67,12 +69,11 @@ class NET_EXPORT HttpNetworkSession
ClientSocketFactory* client_socket_factory;
HostResolver* host_resolver;
CertVerifier* cert_verifier;
- CertPolicyEnforcer* cert_policy_enforcer;
+ CTPolicyEnforcer* ct_policy_enforcer;
ChannelIDService* channel_id_service;
TransportSecurityState* transport_security_state;
CTVerifier* cert_transparency_verifier;
ProxyService* proxy_service;
- std::string ssl_session_cache_shard;
SSLConfigService* ssl_config_service;
HttpAuthHandlerFactory* http_auth_handler_factory;
NetworkDelegate* network_delegate;
@@ -81,11 +82,13 @@ class NET_EXPORT HttpNetworkSession
HostMappingRules* host_mapping_rules;
SocketPerformanceWatcherFactory* socket_performance_watcher_factory;
bool ignore_certificate_errors;
- uint16 testing_fixed_http_port;
- uint16 testing_fixed_https_port;
+ uint16_t testing_fixed_http_port;
+ uint16_t testing_fixed_https_port;
bool enable_tcp_fast_open_for_ssl;
+ // Compress SPDY headers.
bool enable_spdy_compression;
+ // Use SPDY ping frames to test for connection health after idle.
bool enable_spdy_ping_based_connection_checking;
NextProto spdy_default_protocol;
// The protocols supported by NPN (next protocol negotiation) during the
@@ -97,40 +100,94 @@ class NET_EXPORT HttpNetworkSession
size_t spdy_session_max_recv_window_size;
size_t spdy_stream_max_recv_window_size;
size_t spdy_initial_max_concurrent_streams;
+ // Source of time for SPDY connections.
SpdySessionPool::TimeFunc time_func;
+ // This SPDY proxy is allowed to push resources from origins that are
+ // different from those of their associated streams.
std::string trusted_spdy_proxy;
// URLs to exclude from forced SPDY.
std::set<HostPortPair> forced_spdy_exclusions;
+ // Process Alt-Svc headers.
bool use_alternative_services;
+ // Only honor alternative service entries which have a higher probability
+ // than this value.
double alternative_service_probability_threshold;
+ // Enables NPN support. Note that ALPN is always enabled.
+ bool enable_npn;
+
+ // Enables Brotli Content-Encoding support.
+ bool enable_brotli;
+
+ // Enables QUIC support.
bool enable_quic;
- bool enable_insecure_quic;
+ // Enables QUIC for proxies.
bool enable_quic_for_proxies;
+ // Instruct QUIC to use consistent ephemeral ports when talking to
+ // the same server.
bool enable_quic_port_selection;
+ // Disables QUIC's 0-RTT behavior.
bool quic_always_require_handshake_confirmation;
+ // Disables QUIC connection pooling.
bool quic_disable_connection_pooling;
+ // If not zero, the task to load QUIC server configs from the disk cache
+ // will timeout after this value multiplied by the smoothed RTT for the
+ // server.
float quic_load_server_info_timeout_srtt_multiplier;
+ // Causes QUIC to race reading the server config from disk with
+ // sending an inchoate CHLO.
bool quic_enable_connection_racing;
+ // Use non-blocking IO for UDP sockets.
bool quic_enable_non_blocking_io;
+ // Disables using the disk cache to store QUIC server configs.
bool quic_disable_disk_cache;
+ // Prefer AES-GCM to ChaCha20 even if no hardware support is present.
bool quic_prefer_aes;
+ // Specifies the maximum number of connections with high packet loss in
+ // a row after which QUIC will be disabled.
int quic_max_number_of_lossy_connections;
+ // Specifies packet loss rate in fraction after which a connection is
+ // closed and is considered as a lossy connection.
float quic_packet_loss_threshold;
+ // Size in bytes of the QUIC DUP socket receive buffer.
int quic_socket_receive_buffer_size;
+ // Delay starting a TCP connection when QUIC believes it can speak
+ // 0-RTT to a server.
bool quic_delay_tcp_race;
+ // Maximum number of server configs that are to be stored in
+ // HttpServerProperties, instead of the disk cache.
+ size_t quic_max_server_configs_stored_in_properties;
+ // If not empty, QUIC will be used for all connections to this origin.
HostPortPair origin_to_force_quic_on;
- QuicClock* quic_clock; // Will be owned by QuicStreamFactory.
+ // Source of time for QUIC connections. Will be owned by QuicStreamFactory.
+ QuicClock* quic_clock;
+ // Source of entropy for QUIC connections.
QuicRandom* quic_random;
+ // Limit on the size of QUIC packets.
size_t quic_max_packet_length;
+ // User agent description to send in the QUIC handshake.
std::string quic_user_agent_id;
bool enable_user_alternate_protocol_ports;
+ // Optional factory to use for creating QuicCryptoClientStreams.
QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory;
+ // Versions of QUIC which may be used.
QuicVersionVector quic_supported_versions;
int quic_max_recent_disabled_reasons;
int quic_threshold_public_resets_post_handshake;
int quic_threshold_timeouts_streams_open;
+ // Set of QUIC tags to send in the handshake's connection options.
QuicTagVector quic_connection_options;
+ // If true, all QUIC sessions are closed when any local IP address changes.
+ bool quic_close_sessions_on_ip_change;
+ // Specifes QUIC idle connection state lifetime.
+ int quic_idle_connection_timeout_seconds;
+ // If true, disable preconnections if QUIC can do 0RTT.
+ bool quic_disable_preconnect_if_0rtt;
+ // List of hosts for which QUIC is explicitly whitelisted.
+ std::unordered_set<std::string> quic_host_whitelist;
+ // If true, active QUIC sessions may be migrated onto new IPs when network
+ // changes.
+ bool quic_migrate_sessions_on_network_change;
ProxyDelegate* proxy_delegate;
};
@@ -141,6 +198,7 @@ class NET_EXPORT HttpNetworkSession
};
explicit HttpNetworkSession(const Params& params);
+ ~HttpNetworkSession();
HttpAuthCache* http_auth_cache() { return &http_auth_cache_; }
SSLClientAuthCache* ssl_client_auth_cache() {
@@ -205,19 +263,19 @@ class NET_EXPORT HttpNetworkSession
bool IsProtocolEnabled(AlternateProtocol protocol) const;
- // Populates |*next_protos| with protocols.
- void GetNextProtos(NextProtoVector* next_protos) const;
+ // Populates |*alpn_protos| with protocols to be used with ALPN.
+ void GetAlpnProtos(NextProtoVector* alpn_protos) const;
+
+ // Populates |*npn_protos| with protocols to be used with NPN.
+ void GetNpnProtos(NextProtoVector* npn_protos) const;
// Convenience function for searching through |params_| for
// |forced_spdy_exclusions|.
bool HasSpdyExclusion(HostPortPair host_port_pair) const;
private:
- friend class base::RefCounted<HttpNetworkSession>;
friend class HttpNetworkSessionPeer;
- ~HttpNetworkSession();
-
ClientSocketPoolManager* GetSocketPoolManager(SocketPoolType pool_type);
NetLog* const net_log_;
diff --git a/chromium/net/http/http_network_session_peer.cc b/chromium/net/http/http_network_session_peer.cc
index a32e48b9ebb..a5fb8a594a5 100644
--- a/chromium/net/http/http_network_session_peer.cc
+++ b/chromium/net/http/http_network_session_peer.cc
@@ -14,8 +14,7 @@
namespace net {
-HttpNetworkSessionPeer::HttpNetworkSessionPeer(
- const scoped_refptr<HttpNetworkSession>& session)
+HttpNetworkSessionPeer::HttpNetworkSessionPeer(HttpNetworkSession* session)
: session_(session) {}
HttpNetworkSessionPeer::~HttpNetworkSessionPeer() {}
diff --git a/chromium/net/http/http_network_session_peer.h b/chromium/net/http/http_network_session_peer.h
index 755e539cebb..18d7a23a876 100644
--- a/chromium/net/http/http_network_session_peer.h
+++ b/chromium/net/http/http_network_session_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_HTTP_HTTP_NETWORK_SESSION_PEER_H_
#define NET_HTTP_HTTP_NETWORK_SESSION_PEER_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -18,8 +19,8 @@ class ProxyService;
class NET_EXPORT_PRIVATE HttpNetworkSessionPeer {
public:
- explicit HttpNetworkSessionPeer(
- const scoped_refptr<HttpNetworkSession>& session);
+ // |session| should outlive the HttpNetworkSessionPeer.
+ explicit HttpNetworkSessionPeer(HttpNetworkSession* session);
~HttpNetworkSessionPeer();
void SetClientSocketPoolManager(
@@ -32,7 +33,7 @@ class NET_EXPORT_PRIVATE HttpNetworkSessionPeer {
scoped_ptr<HttpStreamFactory> http_stream_factory_for_websocket);
private:
- const scoped_refptr<HttpNetworkSession> session_;
+ HttpNetworkSession* const session_;
DISALLOW_COPY_AND_ASSIGN(HttpNetworkSessionPeer);
};
diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc
index c12f95dfa67..201e3915a24 100644
--- a/chromium/net/http/http_network_transaction.cc
+++ b/chromium/net/http/http_network_transaction.cc
@@ -5,6 +5,7 @@
#include "net/http/http_network_transaction.h"
#include <set>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -60,6 +61,7 @@
#include "net/spdy/spdy_session_pool.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_connection_status_flags.h"
+#include "net/ssl/ssl_private_key.h"
#include "url/gurl.h"
#include "url/url_canon.h"
@@ -108,8 +110,8 @@ scoped_ptr<base::Value> NetLogSSLVersionFallbackCallback(
const GURL* url,
int net_error,
SSLFailureState ssl_failure_state,
- uint16 version_before,
- uint16 version_after,
+ uint16_t version_before,
+ uint16_t version_after,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host_and_port", GetHostAndPort(*url));
@@ -117,7 +119,7 @@ scoped_ptr<base::Value> NetLogSSLVersionFallbackCallback(
dict->SetInteger("ssl_failure_state", ssl_failure_state);
dict->SetInteger("version_before", version_before);
dict->SetInteger("version_after", version_after);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSSLCipherFallbackCallback(
@@ -127,7 +129,7 @@ scoped_ptr<base::Value> NetLogSSLCipherFallbackCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host_and_port", GetHostAndPort(*url));
dict->SetInteger("net_error", net_error);
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
@@ -152,9 +154,11 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority,
total_sent_bytes_(0),
next_state_(STATE_NONE),
establishing_tunnel_(false),
- websocket_handshake_stream_base_create_helper_(NULL) {
+ websocket_handshake_stream_base_create_helper_(NULL),
+ net_error_details_() {
session->ssl_config_service()->GetSSLConfig(&server_ssl_config_);
- session->GetNextProtos(&server_ssl_config_.next_protos);
+ session->GetAlpnProtos(&server_ssl_config_.alpn_protos);
+ session->GetNpnProtos(&server_ssl_config_.npn_protos);
proxy_ssl_config_ = server_ssl_config_;
}
@@ -219,7 +223,9 @@ int HttpNetworkTransaction::RestartIgnoringLastError(
}
int HttpNetworkTransaction::RestartWithCertificate(
- X509Certificate* client_cert, const CompletionCallback& callback) {
+ X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
+ const CompletionCallback& callback) {
// In HandleCertificateRequest(), we always tear down existing stream
// requests to force a new connection. So we shouldn't have one here.
DCHECK(!stream_request_.get());
@@ -230,8 +236,10 @@ int HttpNetworkTransaction::RestartWithCertificate(
&proxy_ssl_config_ : &server_ssl_config_;
ssl_config->send_client_cert = true;
ssl_config->client_cert = client_cert;
+ ssl_config->client_private_key = client_private_key;
session_->ssl_client_auth_cache()->Add(
- response_.cert_request_info->host_and_port, client_cert);
+ response_.cert_request_info->host_and_port, client_cert,
+ client_private_key);
// Reset the other member variables.
// Note: this is necessary only with SSL renegotiation.
ResetStateForRestart();
@@ -459,6 +467,13 @@ bool HttpNetworkTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
return true;
}
+void HttpNetworkTransaction::PopulateNetErrorDetails(
+ NetErrorDetails* details) const {
+ *details = net_error_details_;
+ if (stream_)
+ stream_->PopulateNetErrorDetails(details);
+}
+
void HttpNetworkTransaction::SetPriority(RequestPriority priority) {
priority_ = priority;
if (stream_request_)
@@ -510,6 +525,13 @@ void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config,
OnIOComplete(OK);
}
+void HttpNetworkTransaction::OnBidirectionalStreamJobReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream_job) {
+ NOTREACHED();
+}
+
void HttpNetworkTransaction::OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
@@ -604,6 +626,10 @@ void HttpNetworkTransaction::OnHttpsProxyTunnelResponse(
OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
}
+void HttpNetworkTransaction::OnQuicBroken() {
+ net_error_details_.quic_broken = true;
+}
+
void HttpNetworkTransaction::GetConnectionAttempts(
ConnectionAttempts* out) const {
*out = connection_attempts_;
@@ -839,7 +865,7 @@ int HttpNetworkTransaction::DoInitStreamComplete(int result) {
total_received_bytes_ += stream_->GetTotalReceivedBytes();
total_sent_bytes_ += stream_->GetTotalSentBytes();
}
- stream_.reset();
+ CacheNetErrorDetailsAndResetStream();
}
return result;
@@ -1078,7 +1104,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers));
- if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
+ if (response_.headers->GetHttpVersion() < HttpVersion(1, 0)) {
// HTTP/0.9 doesn't support the PUT method, so lack of response headers
// indicates a buggy server. See:
// https://bugzilla.mozilla.org/show_bug.cgi?id=193921
@@ -1214,7 +1240,7 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) {
total_received_bytes_ += stream_->GetTotalReceivedBytes();
total_sent_bytes_ += stream_->GetTotalSentBytes();
stream_->Close(true);
- stream_.reset();
+ CacheNetErrorDetailsAndResetStream();
}
// The server is asking for a client certificate during the initial
@@ -1225,8 +1251,10 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) {
// to provide one for this server before, use the past decision
// automatically.
scoped_refptr<X509Certificate> client_cert;
+ scoped_refptr<SSLPrivateKey> client_private_key;
bool found_cached_cert = session_->ssl_client_auth_cache()->Lookup(
- response_.cert_request_info->host_and_port, &client_cert);
+ response_.cert_request_info->host_and_port, &client_cert,
+ &client_private_key);
if (!found_cached_cert)
return error;
@@ -1250,6 +1278,7 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) {
&proxy_ssl_config_ : &server_ssl_config_;
ssl_config->send_client_cert = true;
ssl_config->client_cert = client_cert;
+ ssl_config->client_private_key = client_private_key;
next_state_ = STATE_CREATE_STREAM;
// Reset the other member variables.
// Note: this is necessary only with SSL renegotiation.
@@ -1290,19 +1319,19 @@ int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
// reflect servers require a deprecated cipher rather than merely prefer
// it. This, however, has no security benefit until the ciphers are actually
// removed.
- if (!server_ssl_config_.enable_deprecated_cipher_suites &&
+ if (!server_ssl_config_.deprecated_cipher_suites_enabled &&
(error == ERR_SSL_VERSION_OR_CIPHER_MISMATCH ||
error == ERR_CONNECTION_CLOSED || error == ERR_CONNECTION_RESET)) {
net_log_.AddEvent(
NetLog::TYPE_SSL_CIPHER_FALLBACK,
base::Bind(&NetLogSSLCipherFallbackCallback, &request_->url, error));
- server_ssl_config_.enable_deprecated_cipher_suites = true;
+ server_ssl_config_.deprecated_cipher_suites_enabled = true;
ResetConnectionAndRequestForResend();
return OK;
}
bool should_fallback = false;
- uint16 version_max = server_ssl_config_.version_max;
+ uint16_t version_max = server_ssl_config_.version_max;
switch (error) {
case ERR_CONNECTION_CLOSED:
@@ -1440,7 +1469,7 @@ void HttpNetworkTransaction::ResetStateForRestart() {
total_received_bytes_ += stream_->GetTotalReceivedBytes();
total_sent_bytes_ += stream_->GetTotalSentBytes();
}
- stream_.reset();
+ CacheNetErrorDetailsAndResetStream();
}
void HttpNetworkTransaction::ResetStateForAuthRestart() {
@@ -1455,6 +1484,14 @@ void HttpNetworkTransaction::ResetStateForAuthRestart() {
response_ = HttpResponseInfo();
establishing_tunnel_ = false;
remote_endpoint_ = IPEndPoint();
+ net_error_details_.quic_broken = false;
+ net_error_details_.quic_connection_error = QUIC_NO_ERROR;
+}
+
+void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() {
+ if (stream_)
+ stream_->PopulateNetErrorDetails(&net_error_details_);
+ stream_.reset();
}
void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) {
@@ -1513,7 +1550,7 @@ void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) {
}
UMA_HISTOGRAM_BOOLEAN("Net.ConnectionUsedSSLDeprecatedCipherFallback2",
- server_ssl_config_.enable_deprecated_cipher_suites);
+ server_ssl_config_.deprecated_cipher_suites_enabled);
if (server_ssl_config_.version_fallback) {
// Record the error code which triggered the fallback and the state the
@@ -1544,7 +1581,7 @@ bool HttpNetworkTransaction::ShouldResendRequest() const {
void HttpNetworkTransaction::ResetConnectionAndRequestForResend() {
if (stream_.get()) {
stream_->Close(true);
- stream_.reset();
+ CacheNetErrorDetailsAndResetStream();
}
// We need to clear request_headers_ because it contains the real request
diff --git a/chromium/net/http/http_network_transaction.h b/chromium/net/http/http_network_transaction.h
index a5e5b080323..f8584b842d8 100644
--- a/chromium/net/http/http_network_transaction.h
+++ b/chromium/net/http/http_network_transaction.h
@@ -9,11 +9,12 @@
#include <string>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
+#include "net/base/net_error_details.h"
#include "net/base/request_priority.h"
#include "net/http/http_auth.h"
#include "net/http/http_request_headers.h"
@@ -29,6 +30,7 @@
namespace net {
+class BidirectionalStreamJob;
class ClientSocketHandle;
class HttpAuthController;
class HttpNetworkSession;
@@ -37,6 +39,7 @@ class HttpStreamRequest;
class IOBuffer;
class ProxyInfo;
class SpdySession;
+class SSLPrivateKey;
struct HttpRequestInfo;
class NET_EXPORT_PRIVATE HttpNetworkTransaction
@@ -54,6 +57,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
const BoundNetLog& net_log) override;
int RestartIgnoringLastError(const CompletionCallback& callback) override;
int RestartWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
const CompletionCallback& callback) override;
int RestartWithAuth(const AuthCredentials& credentials,
const CompletionCallback& callback) override;
@@ -73,6 +77,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) const override;
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -86,6 +91,10 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
void OnStreamReady(const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStream* stream) override;
+ void OnBidirectionalStreamJobReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream_job) override;
void OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
@@ -107,6 +116,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
const ProxyInfo& used_proxy_info,
HttpStream* stream) override;
+ void OnQuicBroken() override;
void GetConnectionAttempts(ConnectionAttempts* out) const override;
private:
@@ -114,6 +124,8 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
ResetStateForRestart);
+ FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, EnableNPN);
+ FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, DisableNPN);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
WindowUpdateReceived);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
@@ -242,6 +254,10 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// to be maintained for multi-round auth.
void ResetStateForAuthRestart();
+ // Caches network error details from the stream if available
+ // and resets the stream.
+ void CacheNetErrorDetailsAndResetStream();
+
// Records metrics relating to SSL fallbacks.
void RecordSSLFallbackMetrics(int result);
@@ -353,7 +369,8 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
ConnectionAttempts connection_attempts_;
IPEndPoint remote_endpoint_;
-
+ // Network error details for this transaction.
+ NetErrorDetails net_error_details_;
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 da28d9cd74d..4aa59a68f8e 100644
--- a/chromium/net/http/http_network_transaction_ssl_unittest.cc
+++ b/chromium/net/http/http_network_transaction_ssl_unittest.cc
@@ -3,10 +3,10 @@
// found in the LICENSE file.
#include <string>
+#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/net_util.h"
#include "net/base/request_priority.h"
#include "net/dns/mock_host_resolver.h"
@@ -79,7 +79,7 @@ class HttpNetworkTransactionSSLTest : public testing::Test {
HttpRequestInfo* request_info = new HttpRequestInfo;
request_info->url = GURL(url);
request_info->method = "GET";
- request_info_vector_.push_back(request_info);
+ request_info_vector_.push_back(make_scoped_ptr(request_info));
return request_info;
}
@@ -96,7 +96,7 @@ class HttpNetworkTransactionSSLTest : public testing::Test {
HttpServerPropertiesImpl http_server_properties_;
TransportSecurityState transport_security_state_;
HttpNetworkSession::Params session_params_;
- ScopedVector<HttpRequestInfo> request_info_vector_;
+ std::vector<scoped_ptr<HttpRequestInfo>> request_info_vector_;
};
// Tests that HttpNetworkTransaction attempts to fallback from
@@ -127,16 +127,14 @@ TEST_F(HttpNetworkTransactionSSLTest, SSLFallback) {
StaticSocketDataProvider data3(NULL, 0, NULL, 0);
mock_socket_factory_.AddSocketDataProvider(&data3);
- scoped_refptr<HttpNetworkSession> session(
- new HttpNetworkSession(session_params_));
- scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ HttpNetworkSession session(session_params_);
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, &session);
TestCompletionCallback callback;
// This will consume |ssl_data1|, |ssl_data2| and |ssl_data3|.
- int rv = callback.GetResult(
- trans->Start(GetRequestInfo("https://www.paypal.com/"),
- callback.callback(), BoundNetLog()));
+ int rv =
+ callback.GetResult(trans.Start(GetRequestInfo("https://www.paypal.com/"),
+ callback.callback(), BoundNetLog()));
EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
SocketDataProviderArray<SocketDataProvider>& mock_data =
@@ -144,7 +142,7 @@ TEST_F(HttpNetworkTransactionSSLTest, SSLFallback) {
// Confirms that |ssl_data1|, |ssl_data2| and |ssl_data3| are consumed.
EXPECT_EQ(3u, mock_data.next_index());
- SSLConfig& ssl_config = GetServerSSLConfig(trans.get());
+ SSLConfig& ssl_config = GetServerSSLConfig(&trans);
// |version_max| fallbacks to TLS 1.0.
EXPECT_EQ(SSL_PROTOCOL_VERSION_TLS1, ssl_config.version_max);
EXPECT_TRUE(ssl_config.version_fallback);
diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc
index 4744f6197b6..ed7470b3a61 100644
--- a/chromium/net/http/http_network_transaction_unittest.cc
+++ b/chromium/net/http/http_network_transaction_unittest.cc
@@ -7,20 +7,20 @@
#include <math.h> // ceil
#include <stdarg.h>
#include <stdint.h>
-
+#include <limits>
#include <string>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
-#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_file_util.h"
@@ -44,6 +44,7 @@
#include "net/http/http_auth_handler_digest.h"
#include "net/http/http_auth_handler_mock.h"
#include "net/http/http_auth_handler_ntlm.h"
+#include "net/http/http_auth_scheme.h"
#include "net/http/http_basic_state.h"
#include "net/http/http_basic_stream.h"
#include "net/http/http_network_session.h"
@@ -78,8 +79,10 @@
#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"
#include "net/websockets/websocket_handshake_stream_base.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "url/gurl.h"
@@ -92,6 +95,19 @@ namespace net {
namespace {
+enum TestCase {
+ // Test using the SPDY/3.1 protocol.
+ kTestCaseSPDY31,
+
+ // Test using the HTTP/2 protocol, without specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2NoPriorityDependencies,
+
+ // Test using the HTTP/2 protocol, specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2PriorityDependencies
+};
+
const base::string16 kBar(ASCIIToUTF16("bar"));
const base::string16 kBar2(ASCIIToUTF16("bar2"));
const base::string16 kBar3(ASCIIToUTF16("bar3"));
@@ -232,7 +248,8 @@ void AddWebSocketHeaders(HttpRequestHeaders* headers) {
headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
}
-HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
+scoped_ptr<HttpNetworkSession> CreateSession(
+ SpdySessionDependencies* session_deps) {
return SpdySessionDependencies::SpdyCreateSession(session_deps);
}
@@ -240,7 +257,7 @@ HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
class HttpNetworkTransactionTest
: public PlatformTest,
- public ::testing::WithParamInterface<NextProto> {
+ public ::testing::WithParamInterface<TestCase> {
public:
virtual ~HttpNetworkTransactionTest() {
// Important to restore the per-pool limit first, since the pool limit must
@@ -249,16 +266,19 @@ class HttpNetworkTransactionTest
HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
ClientSocketPoolManager::set_max_sockets_per_group(
HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
}
protected:
HttpNetworkTransactionTest()
- : spdy_util_(GetParam()),
- session_deps_(GetParam()),
+ : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
+ session_deps_(GetProtocol()),
old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
HttpNetworkSession::NORMAL_SOCKET_POOL)),
old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
HttpNetworkSession::NORMAL_SOCKET_POOL)) {
+ SpdySession::SetPriorityDependencyDefaultForTesting(
+ GetDependenciesFromPriority());
}
struct SimpleGetHelperResult {
@@ -287,9 +307,17 @@ class HttpNetworkTransactionTest
base::MessageLoop::current()->RunUntilIdle();
}
+ NextProto GetProtocol() const {
+ return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
+ }
+
+ bool GetDependenciesFromPriority() const {
+ return GetParam() == kTestCaseHTTP2PriorityDependencies;
+ }
+
const char* GetAlternateProtocolFromParam() {
- return
- AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
+ return AlternateProtocolToString(
+ AlternateProtocolFromNextProto(GetProtocol()));
}
std::string GetAlternativeServiceHttpHeader() {
@@ -328,7 +356,7 @@ class HttpNetworkTransactionTest
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -445,10 +473,11 @@ class HttpNetworkTransactionTest
int old_max_pool_sockets_;
};
-INSTANTIATE_TEST_CASE_P(NextProto,
+INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
HttpNetworkTransactionTest,
- testing::Values(kProtoSPDY31,
- kProtoHTTP2));
+ testing::Values(kTestCaseSPDY31,
+ kTestCaseHTTP2NoPriorityDependencies,
+ kTestCaseHTTP2PriorityDependencies));
namespace {
@@ -518,10 +547,9 @@ void FillLargeHeadersString(std::string* str, int size) {
#if defined(NTLM_PORTABLE)
// Alternative functions that eliminate randomness and dependency on the local
// host name so that the generated NTLM messages are reproducible.
-void MockGenerateRandom1(uint8* output, size_t n) {
- static const uint8 bytes[] = {
- 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
- };
+void MockGenerateRandom1(uint8_t* output, size_t n) {
+ static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
+ 0x6b, 0x9c, 0x73, 0x54};
static size_t current_byte = 0;
for (size_t i = 0; i < n; ++i) {
output[i] = bytes[current_byte++];
@@ -529,11 +557,10 @@ void MockGenerateRandom1(uint8* output, size_t n) {
}
}
-void MockGenerateRandom2(uint8* output, size_t n) {
- static const uint8 bytes[] = {
- 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
- 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
- };
+void MockGenerateRandom2(uint8_t* output, size_t n) {
+ static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
+ 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
+ 0x31, 0x5b, 0xd3, 0x1f};
static size_t current_byte = 0;
for (size_t i = 0; i < n; ++i) {
output[i] = bytes[current_byte++];
@@ -640,7 +667,7 @@ bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
EXPECT_FALSE(auth_challenge->is_proxy);
EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
EXPECT_EQ("MyRealm1", auth_challenge->realm);
- EXPECT_EQ("basic", auth_challenge->scheme);
+ EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
return true;
}
@@ -650,7 +677,7 @@ bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
EXPECT_TRUE(auth_challenge->is_proxy);
EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
EXPECT_EQ("MyRealm1", auth_challenge->realm);
- EXPECT_EQ("basic", auth_challenge->scheme);
+ EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
return true;
}
@@ -660,7 +687,7 @@ bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
EXPECT_FALSE(auth_challenge->is_proxy);
EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
EXPECT_EQ("digestive", auth_challenge->realm);
- EXPECT_EQ("digest", auth_challenge->scheme);
+ EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
return true;
}
@@ -671,7 +698,7 @@ bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
EXPECT_FALSE(auth_challenge->is_proxy);
EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
EXPECT_EQ(std::string(), auth_challenge->realm);
- EXPECT_EQ("ntlm", auth_challenge->scheme);
+ EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
return true;
}
#endif // defined(NTLM_PORTABLE)
@@ -679,7 +706,7 @@ bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
} // namespace
TEST_P(HttpNetworkTransactionTest, Basic) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
}
@@ -1000,7 +1027,7 @@ TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
request.url = GURL("http://redirect.com/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1045,7 +1072,7 @@ TEST_P(HttpNetworkTransactionTest, Head) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
BeforeProxyHeadersSentHandler proxy_headers_handler;
@@ -1059,12 +1086,11 @@ TEST_P(HttpNetworkTransactionTest, Head) {
"Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads1[] = {
- MockRead("HTTP/1.1 404 Not Found\r\n"),
- MockRead("Server: Blah\r\n"),
- MockRead("Content-Length: 1234\r\n\r\n"),
+ MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
+ MockRead("Content-Length: 1234\r\n\r\n"),
- // No response body because the test stops reading here.
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ // No response body because the test stops reading here.
+ MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
};
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
@@ -1105,7 +1131,7 @@ TEST_P(HttpNetworkTransactionTest, Head) {
}
TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
@@ -1153,9 +1179,10 @@ TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
}
TEST_P(HttpNetworkTransactionTest, Ignores100) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -1163,7 +1190,7 @@ TEST_P(HttpNetworkTransactionTest, Ignores100) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1205,7 +1232,7 @@ TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
request.url = GURL("http://www.foo.com/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1244,7 +1271,7 @@ TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
request.url = GURL("http://www.foo.com/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1275,7 +1302,7 @@ TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
request.url = GURL("http://www.foo.com/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1304,7 +1331,7 @@ void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Written data for successfully sending both requests.
MockWrite data1_writes[] = {
@@ -1347,7 +1374,7 @@ void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
"hello", "world"
};
- uint32 first_socket_log_id = NetLog::Source::kInvalidId;
+ uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
for (int i = 0; i < 2; ++i) {
TestCompletionCallback callback;
@@ -1394,13 +1421,13 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
SSLSocketDataProvider ssl1(ASYNC, OK);
SSLSocketDataProvider ssl2(ASYNC, OK);
if (use_spdy) {
- ssl1.SetNextProto(GetParam());
- ssl2.SetNextProto(GetParam());
+ ssl1.SetNextProto(GetProtocol());
+ ssl2.SetNextProto(GetProtocol());
}
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
@@ -1465,7 +1492,8 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
// Preconnect a socket.
SSLConfig ssl_config;
session->ssl_config_service()->GetSSLConfig(&ssl_config);
- session->GetNextProtos(&ssl_config.next_protos);
+ session->GetAlpnProtos(&ssl_config.alpn_protos);
+ session->GetNpnProtos(&ssl_config.npn_protos);
session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
ssl_config);
// Wait for the preconnect to complete.
@@ -1495,7 +1523,11 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
ASSERT_TRUE(response != NULL);
EXPECT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ if (response->was_fetched_via_spdy) {
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ } else {
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ }
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
@@ -1590,7 +1622,7 @@ TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1644,7 +1676,7 @@ TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1693,7 +1725,7 @@ TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1724,7 +1756,7 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1765,7 +1797,7 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -1807,52 +1839,78 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ const char* request_data =
+ "GET / HTTP/1.1\r\n"
+ "Host: www.foo.com\r\n"
+ "Connection: keep-alive\r\n\r\n";
+ MockWrite data_writes[] = {
+ MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
+ MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
+ MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
+ MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
+ MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
+ };
// Note that because all these reads happen in the same
// StaticSocketDataProvider, it shows that the same socket is being reused for
// all transactions.
- MockRead data1_reads[] = {
- MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
- MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
- MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
- MockRead("HTTP/1.1 302 Found\r\n"
- "Content-Length: 0\r\n\r\n"),
- MockRead("HTTP/1.1 302 Found\r\n"
- "Content-Length: 5\r\n\r\n"
- "hello"),
- MockRead("HTTP/1.1 301 Moved Permanently\r\n"
- "Content-Length: 0\r\n\r\n"),
- MockRead("HTTP/1.1 301 Moved Permanently\r\n"
- "Content-Length: 5\r\n\r\n"
- "hello"),
- MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
- MockRead("hello"),
- };
- StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
- session_deps_.socket_factory->AddSocketDataProvider(&data1);
-
- MockRead data2_reads[] = {
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ MockRead data_reads[] = {
+ MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
+ MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
+ MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
+ MockRead(ASYNC, 7,
+ "HTTP/1.1 302 Found\r\n"
+ "Content-Length: 0\r\n\r\n"),
+ MockRead(ASYNC, 9,
+ "HTTP/1.1 302 Found\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "hello"),
+ MockRead(ASYNC, 11,
+ "HTTP/1.1 301 Moved Permanently\r\n"
+ "Content-Length: 0\r\n\r\n"),
+ MockRead(ASYNC, 13,
+ "HTTP/1.1 301 Moved Permanently\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "hello"),
+
+ // In the next two rounds, IsConnectedAndIdle returns false, due to
+ // the set_busy_before_sync_reads(true) call, while the
+ // HttpNetworkTransaction is being shut down, but the socket is still
+ // reuseable. See http://crbug.com/544255.
+ MockRead(ASYNC, 15,
+ "HTTP/1.1 200 Hunky-Dory\r\n"
+ "Content-Length: 5\r\n\r\n"),
+ MockRead(SYNCHRONOUS, 16, "hello"),
+
+ MockRead(ASYNC, 18,
+ "HTTP/1.1 200 Hunky-Dory\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "he"),
+ MockRead(SYNCHRONOUS, 19, "llo"),
+
+ // The body of the final request is actually read.
+ MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
+ MockRead(ASYNC, 22, "hello"),
};
- StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
- session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ data.set_busy_before_sync_reads(true);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
- const int kNumUnreadBodies = arraysize(data1_reads) - 2;
+ const int kNumUnreadBodies = arraysize(data_writes) - 1;
std::string response_lines[kNumUnreadBodies];
- uint32 first_socket_log_id = NetLog::Source::kInvalidId;
- for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
+ uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
+ for (size_t i = 0; i < kNumUnreadBodies; ++i) {
TestCompletionCallback callback;
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ EXPECT_EQ(OK, callback.GetResult(rv));
LoadTimingInfo load_timing_info;
EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
@@ -1865,22 +1923,27 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
}
const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers.get() != NULL);
+ ASSERT_TRUE(response->headers);
response_lines[i] = response->headers->GetStatusLine();
- // We intentionally don't read the response bodies.
+ // Delete the transaction without reading the response bodies. Then spin
+ // the message loop, so the response bodies are drained.
+ trans.reset();
+ base::RunLoop().RunUntilIdle();
}
const char* const kStatusLines[] = {
- "HTTP/1.1 204 No Content",
- "HTTP/1.1 205 Reset Content",
- "HTTP/1.1 304 Not Modified",
- "HTTP/1.1 302 Found",
- "HTTP/1.1 302 Found",
- "HTTP/1.1 301 Moved Permanently",
- "HTTP/1.1 301 Moved Permanently",
+ "HTTP/1.1 204 No Content",
+ "HTTP/1.1 205 Reset Content",
+ "HTTP/1.1 304 Not Modified",
+ "HTTP/1.1 302 Found",
+ "HTTP/1.1 302 Found",
+ "HTTP/1.1 301 Moved Permanently",
+ "HTTP/1.1 301 Moved Permanently",
+ "HTTP/1.1 200 Hunky-Dory",
+ "HTTP/1.1 200 Hunky-Dory",
};
static_assert(kNumUnreadBodies == arraysize(kStatusLines),
@@ -1893,12 +1956,10 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ EXPECT_EQ(OK, callback.GetResult(rv));
const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- ASSERT_TRUE(response->headers.get() != NULL);
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
@@ -1916,7 +1977,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuth) {
TestNetLog log;
session_deps_.net_log = &log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -2027,7 +2088,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
MockHostResolver* resolver = new MockHostResolver();
session_deps_.net_log = &log;
session_deps_.host_resolver.reset(resolver);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -2137,7 +2198,7 @@ TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
request.url = GURL("http://www.example.org/");
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -2181,106 +2242,96 @@ TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
// Test the request-challenge-retry sequence for basic auth, over a keep-alive
// connection.
TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.load_flags = 0;
-
- TestNetLog log;
- session_deps_.net_log = &log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
- MockWrite data_writes1[] = {
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
-
- // After calling trans->RestartWithAuth(), this is the request we should
- // be issuing -- the final header line contains the credentials.
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n"
- "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
- };
-
- MockRead data_reads1[] = {
- MockRead("HTTP/1.1 401 Unauthorized\r\n"),
- MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
- MockRead("Content-Length: 14\r\n\r\n"),
- MockRead("Unauthorized\r\n"),
+ // On the second pass, the body read of the auth challenge is synchronous, so
+ // IsConnectedAndIdle returns false. The socket should still be drained and
+ // reused. See http://crbug.com/544255.
+ for (int i = 0; i < 2; ++i) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
- // Lastly, the server responds with the actual content.
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
- MockRead("Content-Length: 5\r\n\r\n"),
- MockRead("Hello"),
- };
+ TestNetLog log;
+ session_deps_.net_log = &log;
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- // If there is a regression where we disconnect a Keep-Alive
- // connection during an auth roundtrip, we'll end up reading this.
- MockRead data_reads2[] = {
- MockRead(SYNCHRONOUS, ERR_FAILED),
- };
+ MockWrite data_writes[] = {
+ MockWrite(ASYNC, 0,
+ "GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
- StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
- data_writes1, arraysize(data_writes1));
- StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
- NULL, 0);
- session_deps_.socket_factory->AddSocketDataProvider(&data1);
- session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite(ASYNC, 6,
+ "GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n"
+ "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ };
- TestCompletionCallback callback1;
+ MockRead data_reads[] = {
+ MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
+ MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
+ MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
+ MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
+
+ // Lastly, the server responds with the actual content.
+ MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
+ MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
+ MockRead(ASYNC, 10, "Hello"),
+ };
- scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
- int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ data.set_busy_before_sync_reads(true);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
- rv = callback1.WaitForResult();
- EXPECT_EQ(OK, rv);
+ TestCompletionCallback callback1;
- LoadTimingInfo load_timing_info1;
- EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
- TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
+ ASSERT_EQ(OK, callback1.GetResult(rv));
- const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
+ LoadTimingInfo load_timing_info1;
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
+ TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
- TestCompletionCallback callback2;
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
- rv = trans->RestartWithAuth(
- AuthCredentials(kFoo, kBar), callback2.callback());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ TestCompletionCallback callback2;
- rv = callback2.WaitForResult();
- EXPECT_EQ(OK, rv);
+ rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
+ callback2.callback());
+ ASSERT_EQ(OK, callback2.GetResult(rv));
- LoadTimingInfo load_timing_info2;
- EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
- TestLoadTimingReused(load_timing_info2);
- // The load timing after restart should have the same socket ID, and times
- // those of the first load timing.
- EXPECT_LE(load_timing_info1.receive_headers_end,
- load_timing_info2.send_start);
- EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
+ LoadTimingInfo load_timing_info2;
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
+ TestLoadTimingReused(load_timing_info2);
+ // The load timing after restart should have the same socket ID, and times
+ // those of the first load timing.
+ EXPECT_LE(load_timing_info1.receive_headers_end,
+ load_timing_info2.send_start);
+ EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
- response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- EXPECT_TRUE(response->auth_challenge.get() == NULL);
- EXPECT_EQ(5, response->headers->GetContentLength());
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_FALSE(response->auth_challenge);
+ EXPECT_EQ(5, response->headers->GetContentLength());
- std::string response_data;
- rv = ReadTransaction(trans.get(), &response_data);
- EXPECT_EQ(OK, rv);
+ std::string response_data;
+ EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
- int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
- EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
- int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
- EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
+ int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
+ EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
+ }
}
// Test the request-challenge-retry sequence for basic auth, over a keep-alive
@@ -2291,7 +2342,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockWrite data_writes1[] = {
MockWrite(
@@ -2369,7 +2420,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockWrite data_writes1[] = {
MockWrite(
@@ -2455,7 +2506,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockWrite data_writes1[] = {
MockWrite(
@@ -2550,36 +2601,39 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
-
- // After calling trans->RestartWithAuth(), this is the request we should
- // be issuing -- the final header line contains the credentials.
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
-
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
- // The proxy responds to the connect with a 407, using a persistent
+ // The proxy responds to the connect with a 407, using a non-persistent
// connection.
MockRead data_reads1[] = {
// No credentials.
MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
+ };
+ // Since the first connection couldn't be reused, need to establish another
+ // once given credentials.
+ MockWrite data_writes2[] = {
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads2[] = {
MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
MockRead("HTTP/1.1 200 OK\r\n"),
@@ -2591,6 +2645,9 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
data_writes1, arraysize(data_writes1));
session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
SSLSocketDataProvider ssl(ASYNC, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -2668,48 +2725,52 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
+ // The proxy responds to the connect with a 407, using a non-persistent
+ // connection.
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
+ MockRead("Proxy-Connection: close\r\n\r\n"),
+ };
+
+ MockWrite data_writes2[] = {
// After calling trans->RestartWithAuth(), this is the request we should
// be issuing -- the final header line contains the credentials.
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
- // The proxy responds to the connect with a 407, using a persistent
- // connection.
- MockRead data_reads1[] = {
- // No credentials.
- MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
- MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Proxy-Connection: close\r\n\r\n"),
-
- MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
- MockRead("Content-Length: 5\r\n\r\n"),
- MockRead(SYNCHRONOUS, "hello"),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 5\r\n\r\n"),
+ MockRead(SYNCHRONOUS, "hello"),
};
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
data_writes1, arraysize(data_writes1));
session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
SSLSocketDataProvider ssl(ASYNC, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -2777,75 +2838,313 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
// Test the request-challenge-retry sequence for basic auth, over a keep-alive
// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
+ // On the second pass, the body read of the auth challenge is synchronous, so
+ // IsConnectedAndIdle returns false. The socket should still be drained and
+ // reused. See http://crbug.com/544255.
+ for (int i = 0; i < 2; ++i) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.example.org/");
+ // Ensure that proxy authentication is attempted even
+ // when the no authentication data flag is set.
+ request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
+
+ // Configure against proxy server "myproxy:70".
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
+ BoundTestNetLog log;
+ session_deps_.net_log = log.bound().net_log();
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ // Since we have proxy, should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite(ASYNC, 0,
+ "CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite(ASYNC, 3,
+ "CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, using a persistent
+ // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead(ASYNC, 1,
+ "HTTP/1.0 407 Proxy Authentication Required\r\n"
+ "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Content-Length: 10\r\n\r\n"),
+ MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
+
+ // Wrong credentials (wrong password).
+ MockRead(ASYNC, 4,
+ "HTTP/1.0 407 Proxy Authentication Required\r\n"
+ "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Content-Length: 10\r\n\r\n"),
+ // No response body because the test stops reading here.
+ MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
+ };
+
+ SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
+ arraysize(data_writes1));
+ data1.set_busy_before_sync_reads(true);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+
+ TestCompletionCallback callback1;
+
+ int rv = trans->Start(&request, callback1.callback(), log.bound());
+ EXPECT_EQ(OK, callback1.GetResult(rv));
+
+ TestNetLogEntry::List entries;
+ log.GetEntries(&entries);
+ size_t pos = ExpectLogContainsSomewhere(
+ entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+ NetLog::PHASE_NONE);
+ ExpectLogContainsSomewhere(
+ entries, pos,
+ NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+ NetLog::PHASE_NONE);
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_EQ(10, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
+
+ TestCompletionCallback callback2;
+
+ // Wrong password (should be "bar").
+ rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
+ callback2.callback());
+ EXPECT_EQ(OK, callback2.GetResult(rv));
+
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_EQ(10, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
+
+ // Flush the idle socket before the NetLog and HttpNetworkTransaction go
+ // out of scope.
+ session->CloseAllConnections();
+ }
+}
+
+// Test the request-challenge-retry sequence for basic auth, over a keep-alive
+// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
+TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
+ // On the second pass, the body read of the auth challenge is synchronous, so
+ // IsConnectedAndIdle returns false. The socket should still be drained and
+ // reused. See http://crbug.com/544255.
+ for (int i = 0; i < 2; ++i) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.example.org/");
+ // Ensure that proxy authentication is attempted even
+ // when the no authentication data flag is set.
+ request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
+
+ // Configure against proxy server "myproxy:70".
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
+ BoundTestNetLog log;
+ session_deps_.net_log = log.bound().net_log();
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ // Since we have proxy, should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite(ASYNC, 0,
+ "CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite(ASYNC, 3,
+ "CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, using a persistent
+ // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead(ASYNC, 1,
+ "HTTP/1.1 407 Proxy Authentication Required\r\n"
+ "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
+ "Content-Length: 10\r\n\r\n"),
+ MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
+
+ // Wrong credentials (wrong password).
+ MockRead(ASYNC, 4,
+ "HTTP/1.1 407 Proxy Authentication Required\r\n"
+ "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
+ "Content-Length: 10\r\n\r\n"),
+ // No response body because the test stops reading here.
+ MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
+ };
+
+ SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
+ arraysize(data_writes1));
+ data1.set_busy_before_sync_reads(true);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+
+ TestCompletionCallback callback1;
+
+ int rv = trans->Start(&request, callback1.callback(), log.bound());
+ EXPECT_EQ(OK, callback1.GetResult(rv));
+
+ TestNetLogEntry::List entries;
+ log.GetEntries(&entries);
+ size_t pos = ExpectLogContainsSomewhere(
+ entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+ NetLog::PHASE_NONE);
+ ExpectLogContainsSomewhere(
+ entries, pos,
+ NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+ NetLog::PHASE_NONE);
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_EQ(10, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
+
+ TestCompletionCallback callback2;
+
+ // Wrong password (should be "bar").
+ rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
+ callback2.callback());
+ EXPECT_EQ(OK, callback2.GetResult(rv));
+
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_EQ(10, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
+
+ // Flush the idle socket before the NetLog and HttpNetworkTransaction go
+ // out of scope.
+ session->CloseAllConnections();
+ }
+}
+
+// Test the request-challenge-retry sequence for basic auth, over a keep-alive
+// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
+// the case the server sends extra data on the original socket, so it can't be
+// reused.
+TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("https://www.example.org/");
- // Ensure that proxy authentication is attempted even
// when the no authentication data flag is set.
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
- scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite(ASYNC, 0,
+ "CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, using a persistent, but sends
+ // extra data, so the socket cannot be reused.
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead(ASYNC, 1,
+ "HTTP/1.1 407 Proxy Authentication Required\r\n"
+ "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
+ "Content-Length: 10\r\n\r\n"),
+ MockRead(SYNCHRONOUS, 2, "0123456789"),
+ MockRead(SYNCHRONOUS, 3, "I'm broken!"),
+ };
+ MockWrite data_writes2[] = {
// After calling trans->RestartWithAuth(), this is the request we should
// be issuing -- the final header line contains the credentials.
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ MockWrite(ASYNC, 0,
+ "CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+
+ MockWrite(ASYNC, 2,
+ "GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
- // The proxy responds to the connect with a 407, using a persistent
- // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
- MockRead data_reads1[] = {
- // No credentials.
- MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
- MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Proxy-Connection: keep-alive\r\n"),
- MockRead("Content-Length: 10\r\n\r\n"),
- MockRead("0123456789"),
+ MockRead data_reads2[] = {
+ MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
- // Wrong credentials (wrong password).
- MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
- MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Proxy-Connection: keep-alive\r\n"),
- MockRead("Content-Length: 10\r\n\r\n"),
+ MockRead(ASYNC, 3,
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=iso-8859-1\r\n"
+ "Content-Length: 5\r\n\r\n"),
// No response body because the test stops reading here.
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
};
- StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
- data_writes1, arraysize(data_writes1));
+ SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
+ arraysize(data_writes1));
+ data1.set_busy_before_sync_reads(true);
session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
+ arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
TestCompletionCallback callback1;
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
int rv = trans->Start(&request, callback1.callback(), log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback1.GetResult(rv));
- rv = callback1.WaitForResult();
- EXPECT_EQ(OK, rv);
TestNetLogEntry::List entries;
log.GetEntries(&entries);
size_t pos = ExpectLogContainsSomewhere(
entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
NetLog::PHASE_NONE);
ExpectLogContainsSomewhere(
- entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+ entries, pos,
+ NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
NetLog::PHASE_NONE);
const HttpResponseInfo* response = trans->GetResponseInfo();
@@ -2853,37 +3152,39 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
ASSERT_TRUE(response->headers);
EXPECT_TRUE(response->headers->IsKeepAlive());
EXPECT_EQ(407, response->headers->response_code());
- EXPECT_EQ(10, response->headers->GetContentLength());
- EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
+ LoadTimingInfo load_timing_info;
+ // CONNECT requests and responses are handled at the connect job level, so
+ // the transaction does not yet have a connection.
+ EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
+
TestCompletionCallback callback2;
- // Wrong password (should be "bar").
rv =
- trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- rv = callback2.WaitForResult();
- EXPECT_EQ(OK, rv);
+ trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
+ EXPECT_EQ(OK, callback2.GetResult(rv));
- response = trans->GetResponseInfo();
- ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers);
EXPECT_TRUE(response->headers->IsKeepAlive());
- EXPECT_EQ(407, response->headers->response_code());
- EXPECT_EQ(10, response->headers->GetContentLength());
- EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
- EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_EQ(5, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ // The password prompt info should not be set.
+ EXPECT_FALSE(response->auth_challenge);
- // Flush the idle socket before the NetLog and HttpNetworkTransaction go
- // out of scope.
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
+ TestLoadTimingNotReusedWithPac(load_timing_info,
+ CONNECT_TIMING_HAS_SSL_TIMES);
+
+ trans.reset();
session->CloseAllConnections();
}
-// Test the request-challenge-retry sequence for basic auth, over a keep-alive
-// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
-TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
+// Test the case a proxy closes a socket while the challenge body is being
+// drained.
+TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("https://www.example.org/");
@@ -2893,98 +3194,83 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
- BoundTestNetLog log;
- session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
-
- // After calling trans->RestartWithAuth(), this is the request we should
- // be issuing -- the final header line contains the credentials.
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
// The proxy responds to the connect with a 407, using a persistent
// connection.
MockRead data_reads1[] = {
- // No credentials.
- MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
- MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Content-Length: 10\r\n\r\n"),
- MockRead("0123456789"),
+ // No credentials.
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
+ MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
+ // Server hands up in the middle of the body.
+ MockRead(ASYNC, ERR_CONNECTION_CLOSED),
+ };
- // Wrong credentials (wrong password).
- MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
- MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Content-Length: 10\r\n\r\n"),
- // No response body because the test stops reading here.
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ MockWrite data_writes2[] = {
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
+
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 5\r\n\r\n"),
+ MockRead(SYNCHRONOUS, "hello"),
};
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
data_writes1, arraysize(data_writes1));
session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
- TestCompletionCallback callback1;
-
- int rv = trans->Start(&request, callback1.callback(), log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ TestCompletionCallback callback;
- rv = callback1.WaitForResult();
- EXPECT_EQ(OK, rv);
- TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- size_t pos = ExpectLogContainsSomewhere(
- entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
- NetLog::PHASE_NONE);
- ExpectLogContainsSomewhere(
- entries, pos,
- NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
- NetLog::PHASE_NONE);
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(OK, callback.GetResult(rv));
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response);
ASSERT_TRUE(response->headers);
EXPECT_TRUE(response->headers->IsKeepAlive());
EXPECT_EQ(407, response->headers->response_code());
- EXPECT_EQ(10, response->headers->GetContentLength());
- EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
- TestCompletionCallback callback2;
-
- // Wrong password (should be "bar").
- rv = trans->RestartWithAuth(
- AuthCredentials(kFoo, kBaz), callback2.callback());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- rv = callback2.WaitForResult();
- EXPECT_EQ(OK, rv);
+ rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
+ EXPECT_EQ(OK, callback.GetResult(rv));
response = trans->GetResponseInfo();
ASSERT_TRUE(response);
ASSERT_TRUE(response->headers);
EXPECT_TRUE(response->headers->IsKeepAlive());
- EXPECT_EQ(407, response->headers->response_code());
- EXPECT_EQ(10, response->headers->GetContentLength());
- EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
- EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
-
- // Flush the idle socket before the NetLog and HttpNetworkTransaction go
- // out of scope.
- session->CloseAllConnections();
+ EXPECT_EQ(200, response->headers->response_code());
+ std::string body;
+ EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
+ EXPECT_EQ("hello", body);
}
// Test that we don't read the response body when we fail to establish a tunnel,
@@ -2998,17 +3284,16 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
// The proxy responds to the connect with a 407.
@@ -3016,7 +3301,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
MockRead("Content-Length: 10\r\n\r\n"),
- MockRead("0123456789"), // Should not be reached.
+ MockRead("0123456789"),
MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
};
@@ -3058,17 +3343,16 @@ TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
// The proxy responds to the connect with a 407.
@@ -3078,7 +3362,7 @@ TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
MockRead("Set-Cookie: foo=bar\r\n"),
MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
MockRead("Content-Length: 10\r\n\r\n"),
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
};
StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
@@ -3119,7 +3403,7 @@ TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
request.load_flags = 0;
// We are using a DIRECT connection (i.e. no proxy) for this session.
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -3167,19 +3451,17 @@ TEST_P(HttpNetworkTransactionTest,
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads1[] = {
@@ -3218,6 +3500,446 @@ TEST_P(HttpNetworkTransactionTest,
NetLog::PHASE_NONE);
}
+// Test a proxy auth scheme that allows default credentials and a proxy server
+// that uses non-persistent connections.
+TEST_P(HttpNetworkTransactionTest,
+ AuthAllowsDefaultCredentialsTunnelConnectionClose) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.example.org/");
+
+ // Configure against proxy server "myproxy:70".
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
+
+ scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
+ new HttpAuthHandlerMock::Factory());
+ auth_handler_factory->set_do_init_from_challenge(true);
+ scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
+ mock_handler->set_allows_default_credentials(true);
+ auth_handler_factory->AddMockHandler(mock_handler.release(),
+ HttpAuth::AUTH_PROXY);
+ session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
+
+ // Add NetLog just so can verify load timing information gets a NetLog ID.
+ NetLog net_log;
+ session_deps_.net_log = &net_log;
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
+
+ // Since we have proxy, should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, using a non-persistent
+ // connection.
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Proxy-Authenticate: Mock\r\n"),
+ MockRead("Proxy-Connection: close\r\n\r\n"),
+ };
+
+ // Since the first connection couldn't be reused, need to establish another
+ // once given credentials.
+ MockWrite data_writes2[] = {
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: auth_token\r\n\r\n"),
+
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
+
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 5\r\n\r\n"),
+ MockRead(SYNCHRONOUS, "hello"),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_FALSE(response->headers->IsKeepAlive());
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(trans->IsReadyToRestartForAuth());
+ EXPECT_FALSE(response->auth_challenge.get());
+
+ LoadTimingInfo load_timing_info;
+ // CONNECT requests and responses are handled at the connect job level, so
+ // the transaction does not yet have a connection.
+ EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
+
+ rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_EQ(5, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ // The password prompt info should not be set.
+ EXPECT_FALSE(response->auth_challenge);
+
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
+ TestLoadTimingNotReusedWithPac(load_timing_info,
+ CONNECT_TIMING_HAS_SSL_TIMES);
+
+ trans.reset();
+ session->CloseAllConnections();
+}
+
+// Test a proxy auth scheme that allows default credentials and a proxy server
+// that hangs up when credentials are initially sent.
+TEST_P(HttpNetworkTransactionTest,
+ AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.example.org/");
+
+ // Configure against proxy server "myproxy:70".
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
+
+ scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
+ new HttpAuthHandlerMock::Factory());
+ auth_handler_factory->set_do_init_from_challenge(true);
+ scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
+ mock_handler->set_allows_default_credentials(true);
+ auth_handler_factory->AddMockHandler(mock_handler.release(),
+ HttpAuth::AUTH_PROXY);
+ session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
+
+ // Add NetLog just so can verify load timing information gets a NetLog ID.
+ NetLog net_log;
+ session_deps_.net_log = &net_log;
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
+
+ // Should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: auth_token\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, using a non-persistent
+ // connection.
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
+ MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
+ };
+
+ // Since the first connection was closed, need to establish another once given
+ // credentials.
+ MockWrite data_writes2[] = {
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: auth_token\r\n\r\n"),
+
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
+
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 5\r\n\r\n"),
+ MockRead(SYNCHRONOUS, "hello"),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(trans->IsReadyToRestartForAuth());
+ EXPECT_FALSE(response->auth_challenge);
+
+ LoadTimingInfo load_timing_info;
+ // CONNECT requests and responses are handled at the connect job level, so
+ // the transaction does not yet have a connection.
+ EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
+
+ rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_EQ(5, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ // The password prompt info should not be set.
+ EXPECT_TRUE(response->auth_challenge.get() == NULL);
+
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
+ TestLoadTimingNotReusedWithPac(load_timing_info,
+ CONNECT_TIMING_HAS_SSL_TIMES);
+
+ trans.reset();
+ session->CloseAllConnections();
+}
+
+// Test a proxy auth scheme that allows default credentials and a proxy server
+// that hangs up when credentials are initially sent, and hangs up again when
+// they are retried.
+TEST_P(HttpNetworkTransactionTest,
+ AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.example.org/");
+
+ // Configure against proxy server "myproxy:70".
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
+
+ scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
+ new HttpAuthHandlerMock::Factory());
+ auth_handler_factory->set_do_init_from_challenge(true);
+ scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
+ mock_handler->set_allows_default_credentials(true);
+ auth_handler_factory->AddMockHandler(mock_handler.release(),
+ HttpAuth::AUTH_PROXY);
+ session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
+
+ // Add NetLog just so can verify load timing information gets a NetLog ID.
+ NetLog net_log;
+ session_deps_.net_log = &net_log;
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
+
+ // Should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: auth_token\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, and then hangs up after the
+ // second request is sent.
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Content-Length: 0\r\n"),
+ MockRead("Proxy-Connection: keep-alive\r\n"),
+ MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
+ MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
+ };
+
+ // HttpNetworkTransaction sees a reused connection that was closed with
+ // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
+ // request.
+ MockWrite data_writes2[] = {
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
+
+ // The proxy, having had more than enough of us, just hangs up.
+ MockRead data_reads2[] = {
+ // No credentials.
+ MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(trans->IsReadyToRestartForAuth());
+ EXPECT_FALSE(response->auth_challenge);
+
+ LoadTimingInfo load_timing_info;
+ EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
+
+ rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
+ EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
+
+ trans.reset();
+ session->CloseAllConnections();
+}
+
+// Test a proxy auth scheme that allows default credentials and a proxy server
+// that hangs up when credentials are initially sent, and sends a challenge
+// again they are retried.
+TEST_P(HttpNetworkTransactionTest,
+ AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.example.org/");
+
+ // Configure against proxy server "myproxy:70".
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
+
+ scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
+ new HttpAuthHandlerMock::Factory());
+ auth_handler_factory->set_do_init_from_challenge(true);
+ scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
+ mock_handler->set_allows_default_credentials(true);
+ auth_handler_factory->AddMockHandler(mock_handler.release(),
+ HttpAuth::AUTH_PROXY);
+ // Add another handler for the second challenge. It supports default
+ // credentials, but they shouldn't be used, since they were already tried.
+ mock_handler.reset(new HttpAuthHandlerMock());
+ mock_handler->set_allows_default_credentials(true);
+ auth_handler_factory->AddMockHandler(mock_handler.release(),
+ HttpAuth::AUTH_PROXY);
+ session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
+
+ // Add NetLog just so can verify load timing information gets a NetLog ID.
+ NetLog net_log;
+ session_deps_.net_log = &net_log;
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
+
+ // Should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, using a non-persistent
+ // connection.
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Proxy-Authenticate: Mock\r\n"),
+ MockRead("Proxy-Connection: close\r\n\r\n"),
+ };
+
+ // Since the first connection was closed, need to establish another once given
+ // credentials.
+ MockWrite data_writes2[] = {
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: auth_token\r\n\r\n"),
+ };
+
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Proxy-Authenticate: Mock\r\n"),
+ MockRead("Proxy-Connection: close\r\n\r\n"),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(trans->IsReadyToRestartForAuth());
+ EXPECT_FALSE(response->auth_challenge);
+
+ LoadTimingInfo load_timing_info;
+ EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
+
+ rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_FALSE(trans->IsReadyToRestartForAuth());
+ EXPECT_TRUE(response->auth_challenge);
+
+ trans.reset();
+ session->CloseAllConnections();
+}
+
// Test the load timing for HTTPS requests with an HTTP proxy.
TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
HttpRequestInfo request1;
@@ -3232,24 +3954,21 @@ TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET /1 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET /1 HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET /2 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET /2 HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
// The proxy responds to the connect with a 407, using a persistent
@@ -3333,24 +4052,21 @@ TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET /1 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET /1 HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET /2 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET /2 HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
// The proxy responds to the connect with a 407, using a persistent
@@ -3430,7 +4146,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should use full url
MockWrite data_writes1[] = {
@@ -3492,7 +4208,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// fetch http://www.example.org/ via SPDY
scoped_ptr<SpdyFrame> req(
@@ -3510,7 +4226,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
TestCompletionCallback callback1;
@@ -3532,7 +4248,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
@@ -3552,7 +4268,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Fetch http://www.example.org/ through the SPDY proxy.
scoped_ptr<SpdyFrame> req(
@@ -3570,7 +4286,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
TestCompletionCallback callback1;
@@ -3590,7 +4306,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
SpdySessionKey key(
HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> spdy_session =
- CreateSecureSpdySession(session, key, log.bound());
+ CreateSecureSpdySession(session.get(), key, log.bound());
// Unstall the resolution begun by the transaction.
session_deps_.host_resolver->set_ondemand_mode(true);
@@ -3603,7 +4319,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
@@ -3621,12 +4337,13 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// The first request will be a bare GET, the second request will be a
// GET with a Proxy-Authorization header.
scoped_ptr<SpdyFrame> req_get(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
+ spdy_util_.UpdateWithStreamDestruction(1);
const char* const kExtraAuthorizationHeaders[] = {
"proxy-authorization", "Basic Zm9vOmJhcg=="
};
@@ -3670,7 +4387,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
session_deps_.socket_factory->AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
TestCompletionCallback callback1;
@@ -3721,7 +4438,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -3767,7 +4484,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
SSLSocketDataProvider ssl2(ASYNC, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
@@ -3796,6 +4513,8 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
+ SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
+
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("https://www.example.org/");
@@ -3805,7 +4524,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -3816,16 +4535,16 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
// fetch https://www.example.org/ via SPDY
const char kMyUrl[] = "https://www.example.org/";
scoped_ptr<SpdyFrame> get(
- spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
+ spdy_util_wrapped.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
scoped_ptr<SpdyFrame> wrapped_get(
spdy_util_.ConstructWrappedSpdyFrame(get, 1));
scoped_ptr<SpdyFrame> conn_resp(
spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> get_resp(
- spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> wrapped_get_resp(
spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
- scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ scoped_ptr<SpdyFrame> body(spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
scoped_ptr<SpdyFrame> wrapped_body(
spdy_util_.ConstructWrappedSpdyFrame(body, 1));
scoped_ptr<SpdyFrame> window_update_get_resp(
@@ -3853,10 +4572,10 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
SSLSocketDataProvider ssl2(ASYNC, OK);
- ssl2.SetNextProto(GetParam());
+ ssl2.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
TestCompletionCallback callback1;
@@ -3867,7 +4586,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
// Allow the SpdyProxyClientSocket's write callback to complete.
base::MessageLoop::current()->RunUntilIdle();
// Now allow the read of the response to complete.
- spdy_data.CompleteRead();
+ spdy_data.Resume();
rv = callback1.WaitForResult();
EXPECT_EQ(OK, rv);
@@ -3878,7 +4597,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
@@ -3896,7 +4615,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -3922,10 +4641,10 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
SSLSocketDataProvider ssl2(ASYNC, OK);
- ssl2.SetNextProto(GetParam());
+ ssl2.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
TestCompletionCallback callback1;
@@ -3947,7 +4666,7 @@ TEST_P(HttpNetworkTransactionTest,
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps_));
HttpRequestInfo request1;
@@ -3986,7 +4705,7 @@ TEST_P(HttpNetworkTransactionTest,
SpdyHeaderBlock connect2_block;
spdy_util_.MaybeAddVersionHeader(&connect2_block);
connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
- if (GetParam() == kProtoHTTP2) {
+ if (GetProtocol() == kProtoHTTP2) {
connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
} else {
connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
@@ -4034,7 +4753,7 @@ TEST_P(HttpNetworkTransactionTest,
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
SSLSocketDataProvider ssl2(ASYNC, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
@@ -4089,7 +4808,7 @@ TEST_P(HttpNetworkTransactionTest,
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps_));
HttpRequestInfo request1;
@@ -4158,7 +4877,7 @@ TEST_P(HttpNetworkTransactionTest,
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
SSLSocketDataProvider ssl2(ASYNC, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
@@ -4212,7 +4931,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps_));
HttpRequestInfo request1;
@@ -4234,6 +4953,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body1(
spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
// http://mail.example.org/
scoped_ptr<SpdyHeaderBlock> headers2(
@@ -4263,7 +4983,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
TestCompletionCallback callback;
@@ -4281,7 +5001,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
std::string response_data;
scoped_refptr<IOBuffer> buf(new IOBuffer(256));
@@ -4318,7 +5038,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should use full url
MockWrite data_writes1[] = {
@@ -4415,21 +5135,19 @@ void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
// Configure against proxy server "myproxy:70".
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads[] = {
- status,
- MockRead("Content-Length: 10\r\n\r\n"),
- // No response body because the test stops reading here.
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ status, MockRead("Content-Length: 10\r\n\r\n"),
+ // No response body because the test stops reading here.
+ MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
};
StaticSocketDataProvider data(data_reads, arraysize(data_reads),
@@ -4633,7 +5351,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -4769,7 +5487,7 @@ TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
MockGetHostName);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockWrite data_writes1[] = {
MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
@@ -4898,7 +5616,7 @@ TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
MockGetHostName);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockWrite data_writes1[] = {
MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
@@ -5098,7 +5816,7 @@ TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -5137,26 +5855,25 @@ TEST_P(HttpNetworkTransactionTest,
// Configure against proxy server "myproxy:70".
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
// The proxy responds to the connect with a 404, using a persistent
// connection. Usually a proxy would return 501 (not implemented),
// or 200 (tunnel established).
MockRead data_reads1[] = {
- MockRead("HTTP/1.1 404 Not Found\r\n"),
- MockRead("Content-Length: 10\r\n\r\n"),
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ MockRead("HTTP/1.1 404 Not Found\r\n"),
+ MockRead("Content-Length: 10\r\n\r\n"),
+ MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
};
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
@@ -5191,7 +5908,7 @@ TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -5270,7 +5987,7 @@ TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -5336,7 +6053,7 @@ TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -5404,10 +6121,7 @@ TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
"rt=prt.2642,ol.2649,xjs.2951");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
- scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockRead data_reads[] = {
MockRead("HTTP/1.1 204 No Content\r\n"
@@ -5420,6 +6134,11 @@ TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
+ // Transaction must be created after the MockReads, so it's destroyed before
+ // them.
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
TestCompletionCallback callback;
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
@@ -5451,9 +6170,10 @@ TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
}
TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request[2];
// Transaction 1: a GET request that succeeds. The socket is recycled
@@ -5470,7 +6190,7 @@ TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
request[1].upload_data_stream = &upload_data_stream;
request[1].load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// The first socket is used for transaction 1 and the first attempt of
// transaction 2.
@@ -5548,7 +6268,7 @@ TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
request.url = GURL("http://foo:b@r@www.example.org/");
request.load_flags = LOAD_NORMAL;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -5631,7 +6351,7 @@ TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
request.load_flags = LOAD_NORMAL;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -5742,7 +6462,7 @@ TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
request.url = GURL("http://foo:bar@www.example.org/");
request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -5816,7 +6536,7 @@ TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
// Test that previously tried username/passwords for a realm get re-used.
TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Transaction 1: authenticate (foo, bar) on MyRealm1
{
@@ -5962,7 +6682,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
EXPECT_EQ("www.example.org:80",
response->auth_challenge->challenger.ToString());
EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
- EXPECT_EQ("basic", response->auth_challenge->scheme);
+ EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
TestCompletionCallback callback2;
@@ -6216,7 +6936,7 @@ TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
digest_factory->set_nonce_generator(nonce_generator);
session_deps_.http_auth_handler_factory.reset(digest_factory);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Transaction 1: authenticate (foo, bar) on MyRealm1
{
@@ -6348,7 +7068,7 @@ TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
// Test the ResetStateForRestart() private method.
TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
// Create a transaction (the dependencies aren't important).
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpNetworkTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6395,7 +7115,7 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
request.url = GURL("https://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6455,10 +7175,9 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
request.load_flags = 0;
MockWrite proxy_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead proxy_reads[] = {
@@ -6467,14 +7186,12 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
};
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads[] = {
@@ -6503,7 +7220,7 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
for (int i = 0; i < 2; i++) {
session_deps_.socket_factory->ResetNextMockIndexes();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6540,14 +7257,12 @@ TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
request.load_flags = 0;
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads[] = {
@@ -6569,7 +7284,7 @@ TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6606,10 +7321,9 @@ TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
request.load_flags = 0;
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads[] = {
@@ -6628,7 +7342,7 @@ TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6702,14 +7416,14 @@ TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
arraysize(data_writes));
SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
- proxy_ssl.SetNextProto(GetParam());
+ proxy_ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSocketDataProvider(&data);
session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6739,10 +7453,9 @@ TEST_P(HttpNetworkTransactionTest,
request.load_flags = 0;
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads[] = {
@@ -6761,7 +7474,7 @@ TEST_P(HttpNetworkTransactionTest,
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6811,14 +7524,14 @@ TEST_P(HttpNetworkTransactionTest,
SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
arraysize(data_writes));
SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
- proxy_ssl.SetNextProto(GetParam());
+ proxy_ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSocketDataProvider(&data);
session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -6845,13 +7558,14 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+ spdy_util_.UpdateWithStreamDestruction(1);
// After calling trans->RestartWithAuth(), this is the request we should
// be issuing -- the final header line contains the credentials.
@@ -6907,7 +7621,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
// Negotiate SPDY to the proxy
SSLSocketDataProvider proxy(ASYNC, OK);
- proxy.SetNextProto(GetParam());
+ proxy.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
// Vanilla SSL to the server
SSLSocketDataProvider server(ASYNC, OK);
@@ -6990,7 +7704,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
// Enable cross-origin push.
session_deps_.trusted_spdy_proxy = "myproxy:70";
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<SpdyFrame> stream1_syn(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
@@ -7021,7 +7735,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
CreateMockRead(*stream2_syn, 2, ASYNC),
CreateMockRead(*stream1_body, 3, ASYNC),
CreateMockRead(*stream2_body, 4, ASYNC),
- MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
};
SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
@@ -7029,7 +7743,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
// Negotiate SPDY to the proxy
SSLSocketDataProvider proxy(ASYNC, OK);
- proxy.SetNextProto(GetParam());
+ proxy.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
scoped_ptr<HttpTransaction> trans(
@@ -7103,7 +7817,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
// Enable cross-origin push.
session_deps_.trusted_spdy_proxy = "myproxy:70";
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<SpdyFrame> stream1_syn(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
@@ -7132,7 +7846,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
CreateMockRead(*stream1_reply, 1, ASYNC),
CreateMockRead(*stream2_syn, 2, ASYNC),
CreateMockRead(*stream1_body, 4, ASYNC),
- MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
};
SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
@@ -7140,7 +7854,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
// Negotiate SPDY to the proxy
SSLSocketDataProvider proxy(ASYNC, OK);
- proxy.SetNextProto(GetParam());
+ proxy.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
scoped_ptr<HttpTransaction> trans(
@@ -7180,10 +7894,9 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
// Attempt to fetch the URL from a server with a bad cert
MockWrite bad_cert_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead bad_cert_reads[] = {
@@ -7193,14 +7906,12 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
// Attempt to fetch the URL with a good cert
MockWrite good_data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
MockRead good_cert_reads[] = {
@@ -7231,7 +7942,7 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7260,7 +7971,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
"Chromium Ultra Awesome X Edition");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7301,16 +8012,15 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
"Chromium Ultra Awesome X Edition");
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
};
MockRead data_reads[] = {
// Return an error, so the transaction stops here (this test isn't
@@ -7341,7 +8051,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
"http://the.previous.site.com/");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7379,7 +8089,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
request.method = "POST";
request.url = GURL("http://www.example.org/");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7417,7 +8127,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
request.method = "PUT";
request.url = GURL("http://www.example.org/");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7455,7 +8165,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
request.method = "HEAD";
request.url = GURL("http://www.example.org/");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7492,7 +8202,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
request.url = GURL("http://www.example.org/");
request.load_flags = LOAD_BYPASS_CACHE;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7533,7 +8243,7 @@ TEST_P(HttpNetworkTransactionTest,
request.url = GURL("http://www.example.org/");
request.load_flags = LOAD_VALIDATE_CACHE;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7572,7 +8282,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
request.url = GURL("http://www.example.org/");
request.extra_headers.SetHeader("FooHeader", "Bar");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7613,7 +8323,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
request.extra_headers.SetHeader("hEllo", "Kitty");
request.extra_headers.SetHeader("FoO", "bar");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7659,7 +8369,7 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7718,7 +8428,7 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7782,7 +8492,7 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7841,7 +8551,7 @@ TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7913,7 +8623,7 @@ TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
TestNetLog net_log;
session_deps_.net_log = &net_log;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7990,10 +8700,10 @@ struct GroupNameTest {
bool ssl;
};
-scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
+scoped_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
NextProto next_proto,
SpdySessionDependencies* session_deps_) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
@@ -8007,16 +8717,15 @@ scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
return session;
}
-int GroupNameTransactionHelper(
- const std::string& url,
- const scoped_refptr<HttpNetworkSession>& session) {
+int GroupNameTransactionHelper(const std::string& url,
+ HttpNetworkSession* session) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL(url);
request.load_flags = 0;
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
TestCompletionCallback callback;
@@ -8067,10 +8776,10 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
for (size_t i = 0; i < arraysize(tests); ++i) {
session_deps_.proxy_service =
ProxyService::CreateFixed(tests[i].proxy_server);
- scoped_refptr<HttpNetworkSession> session(
- SetupSessionForGroupNameTests(GetParam(), &session_deps_));
+ scoped_ptr<HttpNetworkSession> session(
+ SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
CaptureGroupNameTransportSocketPool* transport_conn_pool =
new CaptureGroupNameTransportSocketPool(NULL, NULL);
CaptureGroupNameSSLSocketPool* ssl_conn_pool =
@@ -8079,10 +8788,10 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
EXPECT_EQ(ERR_IO_PENDING,
- GroupNameTransactionHelper(tests[i].url, session));
+ GroupNameTransactionHelper(tests[i].url, session.get()));
if (tests[i].ssl)
EXPECT_EQ(tests[i].expected_group_name,
ssl_conn_pool->last_group_name_received());
@@ -8129,10 +8838,10 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
for (size_t i = 0; i < arraysize(tests); ++i) {
session_deps_.proxy_service =
ProxyService::CreateFixed(tests[i].proxy_server);
- scoped_refptr<HttpNetworkSession> session(
- SetupSessionForGroupNameTests(GetParam(), &session_deps_));
+ scoped_ptr<HttpNetworkSession> session(
+ SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
HostPortPair proxy_host("http_proxy", 80);
CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
@@ -8144,10 +8853,10 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
EXPECT_EQ(ERR_IO_PENDING,
- GroupNameTransactionHelper(tests[i].url, session));
+ GroupNameTransactionHelper(tests[i].url, session.get()));
if (tests[i].ssl)
EXPECT_EQ(tests[i].expected_group_name,
ssl_conn_pool->last_group_name_received());
@@ -8199,10 +8908,10 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
for (size_t i = 0; i < arraysize(tests); ++i) {
session_deps_.proxy_service =
ProxyService::CreateFixed(tests[i].proxy_server);
- scoped_refptr<HttpNetworkSession> session(
- SetupSessionForGroupNameTests(GetParam(), &session_deps_));
+ scoped_ptr<HttpNetworkSession> session(
+ SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
HostPortPair proxy_host("socks_proxy", 1080);
CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
@@ -8214,13 +8923,13 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
EXPECT_EQ(ERR_IO_PENDING,
- GroupNameTransactionHelper(tests[i].url, session));
+ GroupNameTransactionHelper(tests[i].url, session.get()));
if (tests[i].ssl)
EXPECT_EQ(tests[i].expected_group_name,
ssl_conn_pool->last_group_name_received());
@@ -8242,7 +8951,7 @@ TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
// connecting to both proxies (myproxy:70 and foobar:80).
session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8268,7 +8977,7 @@ void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
// Select a host resolver that does caching.
session_deps_.host_resolver.reset(new MockCachingHostResolver);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8337,7 +9046,7 @@ TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
StaticSocketDataProvider data(NULL, 0,
write_failure, arraysize(write_failure));
session_deps_.socket_factory->AddSocketDataProvider(&data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback;
@@ -8369,7 +9078,7 @@ TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback;
@@ -8447,7 +9156,7 @@ TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
data_writes2, arraysize(data_writes2));
session_deps_.socket_factory->AddSocketDataProvider(&data2);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback1;
@@ -8503,7 +9212,7 @@ TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
session_deps_.socket_factory->ResetNextMockIndexes();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8520,7 +9229,7 @@ TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8553,15 +9262,15 @@ TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
- const uint64 kFakeSize = 100000; // file is actually blank
+ const uint64_t kFakeSize = 100000; // file is actually blank
UploadFileElementReader::ScopedOverridingContentLengthForTests
overriding_content_length(kFakeSize);
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, kuint64max, base::Time()));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -8569,7 +9278,7 @@ TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8611,11 +9320,11 @@ TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
temp_file_content.length()));
ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file, 0, kuint64max, base::Time()));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -8624,7 +9333,7 @@ TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
request.load_flags = 0;
// If we try to upload an unreadable file, the transaction should fail.
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8655,8 +9364,8 @@ TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
callback_ = callback;
return ERR_IO_PENDING;
}
- uint64 GetContentLength() const override { return 0; }
- uint64 BytesRemaining() const override { return 0; }
+ uint64_t GetContentLength() const override { return 0; }
+ uint64_t BytesRemaining() const override { return 0; }
int Read(IOBuffer* buf,
int buf_length,
const CompletionCallback& callback) override {
@@ -8668,9 +9377,9 @@ TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
};
FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(fake_reader);
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(fake_reader));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -8678,7 +9387,7 @@ TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8785,7 +9494,7 @@ TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
TestCompletionCallback callback1;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8803,7 +9512,7 @@ TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
EXPECT_FALSE(challenge->is_proxy);
EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
EXPECT_EQ("first_realm", challenge->realm);
- EXPECT_EQ("basic", challenge->scheme);
+ EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
// Issue the second request with an incorrect password. There should be a
// password prompt for second_realm waiting to be filled in after the
@@ -8821,7 +9530,7 @@ TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
EXPECT_FALSE(challenge->is_proxy);
EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
EXPECT_EQ("second_realm", challenge->realm);
- EXPECT_EQ("basic", challenge->scheme);
+ EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
// Issue the third request with another incorrect password. There should be
// a password prompt for first_realm waiting to be filled in. If the password
@@ -8840,7 +9549,7 @@ TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
EXPECT_FALSE(challenge->is_proxy);
EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
EXPECT_EQ("first_realm", challenge->realm);
- EXPECT_EQ("basic", challenge->scheme);
+ EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
// Issue the fourth request with the correct password and username.
TestCompletionCallback callback4;
@@ -8880,7 +9589,7 @@ TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8910,12 +9619,69 @@ TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
alternative_service_vector =
http_server_properties.GetAlternativeServices(http_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
- EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
+ EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
alternative_service_vector[0].protocol);
EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
EXPECT_EQ(443, alternative_service_vector[0].port);
}
+TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
+ session_deps_.next_protos = SpdyNextProtos();
+ session_deps_.use_alternative_services = true;
+
+ // Set an alternative service for origin.
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpServerProperties& http_server_properties =
+ *session->http_server_properties();
+ HostPortPair http_host_port_pair("www.example.org", 80);
+ AlternativeService alternative_service(QUIC, "", 80);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ http_server_properties.SetAlternativeService(
+ http_host_port_pair, alternative_service, 1.0, expiration);
+ AlternativeServiceVector alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ EXPECT_EQ(1u, alternative_service_vector.size());
+
+ // Send a clear header.
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: clear\r\n"),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ TestCompletionCallback callback;
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(OK, callback.GetResult(rv));
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response != nullptr);
+ ASSERT_TRUE(response->headers.get() != nullptr);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_FALSE(response->was_npn_negotiated);
+
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+ EXPECT_EQ("hello world", response_data);
+
+ alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ EXPECT_TRUE(alternative_service_vector.empty());
+}
+
// Alternative Service headers must be ignored when |use_alternative_services|
// is false.
TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
@@ -8944,7 +9710,7 @@ TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9001,7 +9767,7 @@ TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9031,7 +9797,7 @@ TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
alternative_service_vector =
http_server_properties.GetAlternativeServices(http_host_port_pair);
ASSERT_EQ(2u, alternative_service_vector.size());
- EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
+ EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
alternative_service_vector[0].protocol);
EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
EXPECT_EQ(443, alternative_service_vector[0].port);
@@ -9068,7 +9834,7 @@ TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9099,7 +9865,7 @@ TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
http_server_properties.GetAlternativeServices(http_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
EXPECT_EQ(443, alternative_service_vector[0].port);
- EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
+ EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
alternative_service_vector[0].protocol);
}
@@ -9125,7 +9891,7 @@ TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HostPortPair http_host_port_pair("www.example.org", 80);
HttpServerProperties& http_server_properties =
@@ -9192,7 +9958,7 @@ TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9222,7 +9988,7 @@ TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
alternative_service_vector =
http_server_properties.GetAlternativeServices(http_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
- EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
+ EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
alternative_service_vector[0].protocol);
EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
EXPECT_EQ(443, alternative_service_vector[0].port);
@@ -9251,12 +10017,13 @@ TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
nullptr, 0);
session_deps_.socket_factory->AddSocketDataProvider(&second_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
+ AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
+ 80);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
@@ -9272,6 +10039,141 @@ TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
}
+TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
+ HostPortPair origin("origin.example.org", 443);
+ HostPortPair alternative("alternative.example.org", 443);
+ std::string origin_url = "https://origin.example.org:443";
+ std::string alternative_url = "https://alternative.example.org:443";
+
+ // Negotiate HTTP/1.1 with alternative.example.org.
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ ssl.SetNextProto(kProtoHTTP11);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ // HTTP/1.1 data for request.
+ MockWrite http_writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: alternative.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=iso-8859-1\r\n"
+ "Content-Length: 40\r\n\r\n"
+ "first HTTP/1.1 response from alternative"),
+ };
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
+ http_writes, arraysize(http_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&http_data);
+
+ StaticSocketDataProvider data_refused;
+ data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
+ session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
+
+ // Set up a QUIC alternative service for origin.
+ session_deps_.use_alternative_services = true;
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ base::WeakPtr<HttpServerProperties> http_server_properties =
+ session->http_server_properties();
+ AlternativeService alternative_service(QUIC, alternative);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ http_server_properties->SetAlternativeService(origin, alternative_service,
+ 1.0, expiration);
+ // Mark the QUIC alternative service as broken.
+ http_server_properties->MarkAlternativeServiceBroken(alternative_service);
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL(origin_url);
+ request.load_flags = 0;
+ TestCompletionCallback callback;
+ NetErrorDetails details;
+ EXPECT_FALSE(details.quic_broken);
+
+ trans->Start(&request, callback.callback(), BoundNetLog());
+ trans->PopulateNetErrorDetails(&details);
+ EXPECT_TRUE(details.quic_broken);
+}
+
+TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
+ HostPortPair origin("origin.example.org", 443);
+ HostPortPair alternative1("alternative1.example.org", 443);
+ HostPortPair alternative2("alternative2.example.org", 443);
+ std::string origin_url = "https://origin.example.org:443";
+ std::string alternative_url1 = "https://alternative1.example.org:443";
+ std::string alternative_url2 = "https://alternative2.example.org:443";
+
+ // Negotiate HTTP/1.1 with alternative1.example.org.
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ ssl.SetNextProto(kProtoHTTP11);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ // HTTP/1.1 data for request.
+ MockWrite http_writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: alternative1.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=iso-8859-1\r\n"
+ "Content-Length: 40\r\n\r\n"
+ "first HTTP/1.1 response from alternative1"),
+ };
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
+ http_writes, arraysize(http_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&http_data);
+
+ StaticSocketDataProvider data_refused;
+ data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
+ session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
+
+ session_deps_.use_alternative_services = true;
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ base::WeakPtr<HttpServerProperties> http_server_properties =
+ session->http_server_properties();
+
+ // Set up two QUIC alternative services for origin.
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+
+ AlternativeService alternative_service1(QUIC, alternative1);
+ AlternativeServiceInfo alternative_service_info1(alternative_service1, 1.0,
+ expiration);
+ alternative_service_info_vector.push_back(alternative_service_info1);
+ AlternativeService alternative_service2(QUIC, alternative2);
+ AlternativeServiceInfo alternative_service_info2(alternative_service2, 1.0,
+ expiration);
+ alternative_service_info_vector.push_back(alternative_service_info2);
+
+ http_server_properties->SetAlternativeServices(
+ origin, alternative_service_info_vector);
+
+ // Mark one of the QUIC alternative service as broken.
+ http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
+
+ const AlternativeServiceVector alternative_service_vector =
+ http_server_properties->GetAlternativeServices(origin);
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL(origin_url);
+ request.load_flags = 0;
+ TestCompletionCallback callback;
+ NetErrorDetails details;
+ EXPECT_FALSE(details.quic_broken);
+
+ trans->Start(&request, callback.callback(), BoundNetLog());
+ trans->PopulateNetErrorDetails(&details);
+ EXPECT_FALSE(details.quic_broken);
+}
+
TEST_P(HttpNetworkTransactionTest,
MarkBrokenAlternateProtocolAndFallback) {
session_deps_.use_alternative_services = true;
@@ -9295,7 +10197,7 @@ TEST_P(HttpNetworkTransactionTest,
data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&second_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
@@ -9303,7 +10205,7 @@ TEST_P(HttpNetworkTransactionTest,
// Port must be < 1024, or the header will be ignored (since initial port was
// port 80 (another restricted port).
const AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "www.example.org",
+ AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
666); // Port is ignored by MockConnect anyway.
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
@@ -9361,13 +10263,13 @@ TEST_P(HttpNetworkTransactionTest,
data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&second_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
const int kUnrestrictedAlternatePort = 1024;
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "www.example.org",
+ AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
kUnrestrictedAlternatePort);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
@@ -9413,13 +10315,13 @@ TEST_P(HttpNetworkTransactionTest,
data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&second_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
const int kUnrestrictedAlternatePort = 1024;
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "www.example.org",
+ AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
kUnrestrictedAlternatePort);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
@@ -9464,13 +10366,13 @@ TEST_P(HttpNetworkTransactionTest,
data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&second_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
const int kRestrictedAlternatePort = 80;
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "www.example.org",
+ AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
kRestrictedAlternatePort);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
@@ -9516,13 +10418,13 @@ TEST_P(HttpNetworkTransactionTest,
data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&second_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
const int kRestrictedAlternatePort = 80;
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "www.example.org",
+ AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
kRestrictedAlternatePort);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
@@ -9567,13 +10469,13 @@ TEST_P(HttpNetworkTransactionTest,
data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&second_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
const int kUnrestrictedAlternatePort = 1025;
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "www.example.org",
+ AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
kUnrestrictedAlternatePort);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
@@ -9613,13 +10515,13 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
const int kUnsafePort = 7;
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), "www.example.org",
+ AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
kUnsafePort);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
@@ -9669,7 +10571,7 @@ TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
ASSERT_TRUE(ssl.cert.get());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -9698,7 +10600,7 @@ TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9724,7 +10626,7 @@ TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
@@ -9759,16 +10661,18 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
- StaticSocketDataProvider hanging_socket(
- NULL, 0, NULL, 0);
- hanging_socket.set_connect_data(never_finishing_connect);
+ StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
+ hanging_socket1.set_connect_data(never_finishing_connect);
// Socket 2 and 3 are the hanging Alternate-Protocol and
// non-Alternate-Protocol jobs from the 2nd transaction.
- session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
- session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
+ session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
+
+ StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
+ hanging_socket2.set_connect_data(never_finishing_connect);
+ session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
ASSERT_TRUE(ssl.cert.get());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -9798,9 +10702,11 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
// Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
- session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
+ StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
+ hanging_socket3.set_connect_data(never_finishing_connect);
+ session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback1;
HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
@@ -9833,7 +10739,7 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
response = trans2.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
@@ -9842,7 +10748,7 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
response = trans3.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
@@ -9875,7 +10781,7 @@ TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
@@ -9887,11 +10793,13 @@ TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
&hanging_alternate_protocol_socket);
// 2nd request is just a copy of the first one, over HTTP again.
- session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
+ StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
+ NULL, 0);
+ session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -10015,7 +10923,7 @@ TEST_P(HttpNetworkTransactionTest,
session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
ASSERT_TRUE(ssl.cert.get());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -10025,7 +10933,7 @@ TEST_P(HttpNetworkTransactionTest,
MockWrite spdy_writes[] = {
MockWrite(ASYNC, 0,
"CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
+ "Host: www.example.org:443\r\n"
"Proxy-Connection: keep-alive\r\n\r\n"),
CreateMockWrite(*req, 2),
};
@@ -10035,10 +10943,8 @@ TEST_P(HttpNetworkTransactionTest,
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockRead spdy_reads[] = {
- MockRead(ASYNC, 1, kCONNECTResponse),
- CreateMockRead(*resp.get(), 3),
- CreateMockRead(*data.get(), 4),
- MockRead(ASYNC, ERR_IO_PENDING, 5),
+ MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
+ CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
};
SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
@@ -10055,7 +10961,7 @@ TEST_P(HttpNetworkTransactionTest,
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -10083,7 +10989,7 @@ TEST_P(HttpNetworkTransactionTest,
response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
@@ -10127,7 +11033,7 @@ TEST_P(HttpNetworkTransactionTest,
session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
ASSERT_TRUE(ssl.cert.get());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -10148,7 +11054,7 @@ TEST_P(HttpNetworkTransactionTest,
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -10171,7 +11077,7 @@ TEST_P(HttpNetworkTransactionTest,
SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> spdy_session =
- CreateSecureSpdySession(session, key, BoundNetLog());
+ CreateSecureSpdySession(session.get(), key, BoundNetLog());
trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -10182,7 +11088,7 @@ TEST_P(HttpNetworkTransactionTest,
response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
@@ -10249,11 +11155,11 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
"Authorization: auth_token\r\n\r\n");
const MockWrite kConnect(
"CONNECT www.example.com:443 HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
+ "Host: www.example.com:443\r\n"
"Proxy-Connection: keep-alive\r\n\r\n");
const MockWrite kConnectProxyAuth(
"CONNECT www.example.com:443 HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
+ "Host: www.example.com:443\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authorization: auth_token\r\n\r\n");
@@ -10540,8 +11446,7 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
request.url = GURL(test_config.server_url);
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
@@ -10556,8 +11461,7 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
// kProxyChallenge uses Proxy-Connection: close which means that the
// socket is closed and a new one will be created for the next request.
- if (read_write_round.read.data == kProxyChallenge.data &&
- read_write_round.write.data != kConnect.data) {
+ if (read_write_round.read.data == kProxyChallenge.data) {
mock_reads.push_back(std::vector<MockRead>());
mock_writes.push_back(std::vector<MockWrite>());
}
@@ -10575,15 +11479,19 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
&ssl_socket_data_provider);
}
- ScopedVector<StaticSocketDataProvider> data_providers;
+ std::vector<scoped_ptr<StaticSocketDataProvider>> data_providers;
for (size_t i = 0; i < mock_reads.size(); ++i) {
- data_providers.push_back(new StaticSocketDataProvider(
- vector_as_array(&mock_reads[i]), mock_reads[i].size(),
- vector_as_array(&mock_writes[i]), mock_writes[i].size()));
+ data_providers.push_back(make_scoped_ptr(new StaticSocketDataProvider(
+ mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
+ mock_writes[i].size())));
session_deps_.socket_factory->AddSocketDataProvider(
- data_providers.back());
+ data_providers.back().get());
}
+ // Transaction must be created after DataProviders, so it's destroyed before
+ // they are as well.
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+
for (int round = 0; round < test_config.num_auth_rounds; ++round) {
const TestRound& read_write_round = test_config.rounds[round];
// Start or restart the transaction.
@@ -10640,12 +11548,12 @@ TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
request.url = origin;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Use a TCP Socket Pool with only one connection per group. This is used
// to validate that the TCP socket is not released to the pool between
// each round of multi-round authentication.
- HttpNetworkSessionPeer session_peer(session);
+ HttpNetworkSessionPeer session_peer(session.get());
TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
50, // Max sockets for pool
1, // Max sockets per group
@@ -10655,7 +11563,7 @@ TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_pool);
- session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -10840,7 +11748,7 @@ TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -10875,7 +11783,7 @@ TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
request.load_flags = 0;
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
scoped_ptr<SpdyFrame> req(
@@ -10892,7 +11800,7 @@ TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
TestCompletionCallback callback;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -10996,14 +11904,14 @@ TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
// First connection attempt without Proxy-Authorization.
MockWrite(ASYNC, 0,
"CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
+ "Host: www.example.org:443\r\n"
"Proxy-Connection: keep-alive\r\n"
"\r\n"),
// Second connection attempt with Proxy-Authorization.
MockWrite(ASYNC, 2,
"CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
+ "Host: www.example.org:443\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authorization: auth_token\r\n"
"\r\n"),
@@ -11011,30 +11919,27 @@ TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
// SPDY request
CreateMockWrite(*req, 4),
};
- const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
- "Proxy-Authenticate: Mock\r\n"
- "Proxy-Connection: close\r\n"
- "\r\n");
- const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
MockRead data_reads_2[] = {
// First connection attempt fails
- MockRead(ASYNC, kRejectConnectResponse,
- arraysize(kRejectConnectResponse) - 1, 1),
+ MockRead(ASYNC, 1,
+ "HTTP/1.1 407 Unauthorized\r\n"
+ "Proxy-Authenticate: Mock\r\n"
+ "Content-Length: 0\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "\r\n"),
// Second connection attempt passes
- MockRead(ASYNC, kAcceptConnectResponse,
- arraysize(kAcceptConnectResponse) - 1, 3),
+ MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
// SPDY response
- CreateMockRead(*resp.get(), 5),
- CreateMockRead(*data.get(), 6),
+ CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
MockRead(ASYNC, 0, 0, 7),
};
SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
data_writes_2, arraysize(data_writes_2));
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
ASSERT_TRUE(ssl.cert.get());
@@ -11049,7 +11954,7 @@ TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
session_deps_.socket_factory->AddSocketDataProvider(
&hanging_non_alternate_protocol_socket);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// First round should work and provide the Alternate-Protocol state.
TestCompletionCallback callback_1;
@@ -11109,7 +12014,7 @@ TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
request.load_flags = 0;
session_deps_.host_resolver->set_synchronous_mode(true);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -11147,7 +12052,7 @@ TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
{
HttpRequestInfo request;
@@ -11183,7 +12088,7 @@ TEST_P(HttpNetworkTransactionTest, ProxyGet) {
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpRequestInfo request;
request.method = "GET";
@@ -11247,7 +12152,7 @@ TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpRequestInfo request;
request.method = "GET";
@@ -11255,15 +12160,13 @@ TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads1[] = {
@@ -11318,13 +12221,88 @@ TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
CONNECT_TIMING_HAS_SSL_TIMES);
}
+// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
+// literal host.
+TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
+ BoundTestNetLog log;
+ session_deps_.net_log = log.bound().net_log();
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://[::1]:443/");
+
+ // Since we have proxy, should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
+ "Host: [::1]:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: [::1]\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads1[] = {
+ MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
+
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 100\r\n\r\n"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ TestCompletionCallback callback1;
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ int rv = trans->Start(&request, callback1.callback(), log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback1.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ TestNetLogEntry::List entries;
+ log.GetEntries(&entries);
+ size_t pos = ExpectLogContainsSomewhere(
+ entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+ NetLog::PHASE_NONE);
+ ExpectLogContainsSomewhere(
+ entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+ NetLog::PHASE_NONE);
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_EQ(100, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ EXPECT_TRUE(response->was_fetched_via_proxy);
+ EXPECT_TRUE(
+ response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
+
+ LoadTimingInfo load_timing_info;
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
+ TestLoadTimingNotReusedWithPac(load_timing_info,
+ CONNECT_TIMING_HAS_SSL_TIMES);
+}
+
// Test a basic HTTPS GET request through a proxy, but the server hangs up
// while establishing the tunnel.
TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpRequestInfo request;
request.method = "GET";
@@ -11332,15 +12310,13 @@ TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
// Since we have proxy, should try to establish tunnel.
MockWrite data_writes1[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads1[] = {
@@ -11393,17 +12369,17 @@ TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Set up an initial SpdySession in the pool to reuse.
HostPortPair host_port_pair("www.example.org", 443);
SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> spdy_session =
- CreateInsecureSpdySession(session, key, BoundNetLog());
+ CreateInsecureSpdySession(session.get(), key, BoundNetLog());
HttpRequestInfo request;
request.method = "GET";
@@ -11439,7 +12415,7 @@ void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
session_deps_.socket_factory->AddSocketDataProvider(&data);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -11526,7 +12502,7 @@ TEST_P(HttpNetworkTransactionTest,
StaticSocketDataProvider data4(NULL, 0, NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data4);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -11544,14 +12520,15 @@ TEST_P(HttpNetworkTransactionTest,
// of SSLClientCertCache, NULL is just as meaningful as a real
// certificate, so this is the same as supply a
// legitimate-but-unacceptable certificate.
- rv = trans->RestartWithCertificate(NULL, callback.callback());
+ rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
// Ensure the certificate was added to the client auth cache before
// allowing the connection to continue restarting.
scoped_refptr<X509Certificate> client_cert;
+ scoped_refptr<SSLPrivateKey> client_private_key;
ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("www.example.com", 443), &client_cert));
+ HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
ASSERT_EQ(NULL, client_cert.get());
// Restart the handshake. This will consume ssl_data2, which fails, and
@@ -11563,7 +12540,7 @@ TEST_P(HttpNetworkTransactionTest,
// Ensure that the client certificate is removed from the cache on a
// handshake failure.
ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("www.example.com", 443), &client_cert));
+ HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
}
// Ensure that a client certificate is removed from the SSL client auth
@@ -11643,7 +12620,7 @@ TEST_P(HttpNetworkTransactionTest,
StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data5);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -11661,14 +12638,15 @@ TEST_P(HttpNetworkTransactionTest,
// of SSLClientCertCache, NULL is just as meaningful as a real
// certificate, so this is the same as supply a
// legitimate-but-unacceptable certificate.
- rv = trans->RestartWithCertificate(NULL, callback.callback());
+ rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
// Ensure the certificate was added to the client auth cache before
// allowing the connection to continue restarting.
scoped_refptr<X509Certificate> client_cert;
+ scoped_refptr<SSLPrivateKey> client_private_key;
ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("www.example.com", 443), &client_cert));
+ HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
ASSERT_EQ(NULL, client_cert.get());
// Restart the handshake. This will consume ssl_data2, which fails, and
@@ -11680,7 +12658,7 @@ TEST_P(HttpNetworkTransactionTest,
// Ensure that the client certificate is removed from the cache on a
// handshake failure.
ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("www.example.com", 443), &client_cert));
+ HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
}
// Ensure that a client certificate is removed from the SSL client auth
@@ -11735,7 +12713,7 @@ TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
for (size_t i = 0; i < arraysize(requests); ++i) {
session_deps_.socket_factory->ResetNextMockIndexes();
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpNetworkTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -11753,19 +12731,21 @@ TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
// of SSLClientCertCache, NULL is just as meaningful as a real
// certificate, so this is the same as supply a
// legitimate-but-unacceptable certificate.
- rv = trans->RestartWithCertificate(NULL, callback.callback());
+ rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
// Ensure the certificate was added to the client auth cache before
// allowing the connection to continue restarting.
scoped_refptr<X509Certificate> client_cert;
+ scoped_refptr<SSLPrivateKey> client_private_key;
ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("proxy", 70), &client_cert));
+ HostPortPair("proxy", 70), &client_cert, &client_private_key));
ASSERT_EQ(NULL, client_cert.get());
// Ensure the certificate was NOT cached for the endpoint. This only
// applies to HTTPS requests, but is fine to check for HTTP requests.
ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("www.example.com", 443), &client_cert));
+ HostPortPair("www.example.com", 443), &client_cert,
+ &client_private_key));
// Restart the handshake. This will consume ssl_data2, which fails, and
// then consume ssl_data3, which should also fail. The result code is
@@ -11776,9 +12756,10 @@ TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
// Now that the new handshake has failed, ensure that the client
// certificate was removed from the client auth cache.
ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("proxy", 70), &client_cert));
+ HostPortPair("proxy", 70), &client_cert, &client_private_key));
ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
- HostPortPair("www.example.com", 443), &client_cert));
+ HostPortPair("www.example.com", 443), &client_cert,
+ &client_private_key));
}
}
@@ -11788,16 +12769,17 @@ TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
// Set up a special HttpNetworkSession with a MockCachingHostResolver.
session_deps_.host_resolver.reset(new MockCachingHostResolver());
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
pool_peer.DisableDomainAuthenticationVerification();
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
scoped_ptr<SpdyFrame> host1_req(
spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> host2_req(
spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
MockWrite spdy_writes[] = {
@@ -11841,7 +12823,7 @@ TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
const HttpResponseInfo* response = trans1.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
@@ -11874,7 +12856,7 @@ TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
response = trans2.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
@@ -11887,16 +12869,17 @@ TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
// Set up a special HttpNetworkSession with a MockCachingHostResolver.
session_deps_.host_resolver.reset(new MockCachingHostResolver());
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
pool_peer.DisableDomainAuthenticationVerification();
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
scoped_ptr<SpdyFrame> host1_req(
spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> host2_req(
spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
MockWrite spdy_writes[] = {
@@ -11940,7 +12923,7 @@ TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
const HttpResponseInfo* response = trans1.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
@@ -11959,7 +12942,7 @@ TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
response = trans2.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
@@ -12017,16 +13000,17 @@ TEST_P(HttpNetworkTransactionTest,
HttpNetworkSession::Params params =
SpdySessionDependencies::CreateSessionParams(&session_deps_);
params.host_resolver = &host_resolver;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
pool_peer.DisableDomainAuthenticationVerification();
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
scoped_ptr<SpdyFrame> host1_req(
spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> host2_req(
spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
MockWrite spdy_writes[] = {
@@ -12070,7 +13054,7 @@ TEST_P(HttpNetworkTransactionTest,
const HttpResponseInfo* response = trans1.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
@@ -12102,7 +13086,7 @@ TEST_P(HttpNetworkTransactionTest,
response = trans2.GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
@@ -12123,11 +13107,8 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
- MockRead reads1[] = {
- CreateMockRead(*resp1, 1),
- CreateMockRead(*body1, 2),
- MockRead(ASYNC, ERR_IO_PENDING, 3)
- };
+ MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
SequencedSocketData data1(reads1, arraysize(reads1), writes1,
arraysize(writes1));
@@ -12152,12 +13133,12 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
arraysize(writes2));
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
session_deps_.socket_factory->AddSocketDataProvider(&data1);
session_deps_.socket_factory->AddSocketDataProvider(&data2);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Start the first transaction to set up the SpdySession
HttpRequestInfo request1;
@@ -12205,7 +13186,7 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
EXPECT_TRUE(
cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
SSLSocketDataProvider ssl(ASYNC, OK);
- ssl.SetNextProto(GetParam());
+ ssl.SetNextProto(GetProtocol());
ssl.cert = cert;
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -12229,6 +13210,7 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
if (pooling) {
req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
+ spdy_util_.UpdateWithStreamDestruction(1);
req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
writes.push_back(CreateMockWrite(*req0, 0));
@@ -12258,8 +13240,8 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
reads.push_back(MockRead(ASYNC, OK, 3));
}
- SequencedSocketData data(vector_as_array(&reads), reads.size(),
- vector_as_array(&writes), writes.size());
+ SequencedSocketData data(reads.data(), reads.size(), writes.data(),
+ writes.size());
session_deps_.socket_factory->AddSocketDataProvider(&data);
// Connection to the origin fails.
@@ -12269,11 +13251,11 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
session_deps_.use_alternative_services = true;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), alternative);
+ AlternateProtocolFromNextProto(GetProtocol()), alternative);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
1.0, expiration);
@@ -12306,9 +13288,8 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
base::MessageLoop::current()->RunUntilIdle();
- if (data.IsReadPaused()) {
- data.CompleteRead();
- }
+ if (data.IsPaused())
+ data.Resume();
rv = callback1.WaitForResult();
if (valid) {
EXPECT_EQ(OK, rv);
@@ -12322,10 +13303,11 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
}
};
-INSTANTIATE_TEST_CASE_P(NextProto,
+INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
AltSvcCertificateVerificationTest,
- testing::Values(kProtoSPDY31,
- kProtoHTTP2));
+ testing::Values(kTestCaseSPDY31,
+ kTestCaseHTTP2NoPriorityDependencies,
+ kTestCaseHTTP2PriorityDependencies));
// The alternative service host must exhibit a certificate that is valid for the
// origin host. Test that this is enforced when pooling to an existing
@@ -12373,11 +13355,11 @@ TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
// Set up alternative service for origin.
session_deps_.use_alternative_services = true;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), alternative);
+ AlternateProtocolFromNextProto(GetProtocol()), alternative);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
1.0, expiration);
@@ -12446,11 +13428,11 @@ TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
// Set up alternative service for origin.
session_deps_.use_alternative_services = true;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), alternative);
+ AlternateProtocolFromNextProto(GetProtocol()), alternative);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
1.0, expiration);
@@ -12555,11 +13537,11 @@ TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
// Set up alternative service for origin.
session_deps_.use_alternative_services = true;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
- AlternateProtocolFromNextProto(GetParam()), alternative);
+ AlternateProtocolFromNextProto(GetProtocol()), alternative);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
1.0, expiration);
@@ -12628,12 +13610,15 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
const std::string https_url = "https://www.example.org:8080/";
const std::string http_url = "http://www.example.org:8080/";
+ // Separate SPDY util instance for naked and wrapped requests.
+ SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
+
// SPDY GET for HTTPS URL (through CONNECT tunnel)
const HostPortPair host_port_pair("www.example.org", 8080);
scoped_ptr<SpdyFrame> connect(
spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
scoped_ptr<SpdyFrame> req1(
- spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
+ spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
scoped_ptr<SpdyFrame> wrapped_req1(
spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
@@ -12648,9 +13633,8 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
MockWrite writes1[] = {
- CreateMockWrite(*connect, 0),
- CreateMockWrite(*wrapped_req1, 2),
- CreateMockWrite(*req2, 5),
+ CreateMockWrite(*connect, 0), CreateMockWrite(*wrapped_req1, 2),
+ CreateMockWrite(*req2, 6),
};
scoped_ptr<SpdyFrame> conn_resp(
@@ -12658,22 +13642,24 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
scoped_ptr<SpdyFrame> wrapped_resp1(
- spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
+ spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
scoped_ptr<SpdyFrame> wrapped_body1(
- spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
+ spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
MockRead reads1[] = {
- CreateMockRead(*conn_resp, 1),
- CreateMockRead(*wrapped_resp1, 3),
- CreateMockRead(*wrapped_body1, 4),
- CreateMockRead(*resp2, 6),
- CreateMockRead(*body2, 7),
- MockRead(ASYNC, ERR_IO_PENDING, 8)
+ CreateMockRead(*conn_resp, 1),
+ MockRead(ASYNC, ERR_IO_PENDING, 3),
+ CreateMockRead(*wrapped_resp1, 4),
+ CreateMockRead(*wrapped_body1, 5),
+ MockRead(ASYNC, ERR_IO_PENDING, 7),
+ CreateMockRead(*resp2, 8),
+ CreateMockRead(*body2, 9),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
};
- DeterministicSocketData data1(reads1, arraysize(reads1),
- writes1, arraysize(writes1));
+ SequencedSocketData data1(reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
MockConnect connect_data1(ASYNC, OK);
data1.set_connect_data(connect_data1);
@@ -12682,15 +13668,14 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
TestNetLog log;
session_deps_.net_log = &log;
SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
- ssl1.SetNextProto(GetParam());
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
+ ssl1.SetNextProto(GetProtocol());
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
- ssl2.SetNextProto(GetParam());
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
+ ssl2.SetNextProto(GetProtocol());
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
- scoped_refptr<HttpNetworkSession> session(
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
// Start the first transaction to set up the SpdySession
HttpRequestInfo request1;
@@ -12699,12 +13684,13 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
request1.load_flags = 0;
HttpNetworkTransaction trans1(LOWEST, session.get());
TestCompletionCallback callback1;
- EXPECT_EQ(ERR_IO_PENDING,
- trans1.Start(&request1, callback1.callback(), BoundNetLog()));
- base::MessageLoop::current()->RunUntilIdle();
- data1.RunFor(4);
+ int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
- EXPECT_EQ(OK, callback1.WaitForResult());
+ // This pause is a hack to avoid running into https://crbug.com/497228.
+ data1.RunUntilPaused();
+ base::RunLoop().RunUntilIdle();
+ data1.Resume();
+ EXPECT_EQ(OK, callback1.GetResult(rv));
EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
LoadTimingInfo load_timing_info1;
@@ -12712,19 +13698,21 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
TestLoadTimingNotReusedWithPac(load_timing_info1,
CONNECT_TIMING_HAS_SSL_TIMES);
- // Now, start the HTTP request
+ // Now, start the HTTP request.
HttpRequestInfo request2;
request2.method = "GET";
request2.url = GURL(http_url);
request2.load_flags = 0;
HttpNetworkTransaction trans2(MEDIUM, session.get());
TestCompletionCallback callback2;
- EXPECT_EQ(ERR_IO_PENDING,
- trans2.Start(&request2, callback2.callback(), BoundNetLog()));
- base::MessageLoop::current()->RunUntilIdle();
- data1.RunFor(3);
+ rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
+
+ // This pause is a hack to avoid running into https://crbug.com/497228.
+ data1.RunUntilPaused();
+ base::RunLoop().RunUntilIdle();
+ data1.Resume();
+ EXPECT_EQ(OK, callback2.GetResult(rv));
- EXPECT_EQ(OK, callback2.WaitForResult());
EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
LoadTimingInfo load_timing_info2;
@@ -12745,6 +13733,9 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
const std::string url2 = "https://news.example.org/";
const std::string ip_addr = "1.2.3.4";
+ // Second SpdyTestUtil instance for the second socket.
+ SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
+
// SPDY GET for HTTP URL (through SPDY proxy)
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
@@ -12758,41 +13749,36 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockRead reads1[] = {
- CreateMockRead(*resp1, 1),
- CreateMockRead(*body1, 2),
- MockRead(ASYNC, OK, 3) // EOF
+ MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
+ CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4), // EOF
};
- scoped_ptr<DeterministicSocketData> data1(
- new DeterministicSocketData(reads1, arraysize(reads1),
- writes1, arraysize(writes1)));
+ SequencedSocketData data1(reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
IPAddressNumber ip;
ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
IPEndPoint peer_addr = IPEndPoint(ip, 443);
MockConnect connect_data1(ASYNC, OK, peer_addr);
- data1->set_connect_data(connect_data1);
+ data1.set_connect_data(connect_data1);
// SPDY GET for HTTPS URL (direct)
scoped_ptr<SpdyFrame> req2(
- spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
+ spdy_util_secure.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
MockWrite writes2[] = {
CreateMockWrite(*req2, 0),
};
- scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
- MockRead reads2[] = {
- CreateMockRead(*resp2, 1),
- CreateMockRead(*body2, 2),
- MockRead(ASYNC, OK, 3) // EOF
- };
+ scoped_ptr<SpdyFrame> resp2(
+ spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> body2(spdy_util_secure.ConstructSpdyBodyFrame(1, true));
+ MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
+ MockRead(ASYNC, OK, 3)};
- scoped_ptr<DeterministicSocketData> data2(
- new DeterministicSocketData(reads2, arraysize(reads2),
- writes2, arraysize(writes2)));
+ SequencedSocketData data2(reads2, arraysize(reads2), writes2,
+ arraysize(writes2));
MockConnect connect_data2(ASYNC, OK);
- data2->set_connect_data(connect_data2);
+ data2.set_connect_data(connect_data2);
// Set up a proxy config that sends HTTP requests to a proxy, and
// all others direct.
@@ -12803,29 +13789,26 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
NULL));
SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
- ssl1.SetNextProto(GetParam());
+ ssl1.SetNextProto(GetProtocol());
// Load a valid cert. Note, that this does not need to
// be valid for proxy because the MockSSLClientSocket does
// not actually verify it. But SpdySession will use this
// to see if it is valid for the new origin
ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
ASSERT_TRUE(ssl1.cert.get());
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(
- data1.get());
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
- ssl2.SetNextProto(GetParam());
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(
- data2.get());
+ ssl2.SetNextProto(GetProtocol());
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
session_deps_.host_resolver.reset(new MockCachingHostResolver());
session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
- scoped_refptr<HttpNetworkSession> session(
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
// Start the first transaction to set up the SpdySession
HttpRequestInfo request1;
@@ -12836,9 +13819,11 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
TestCompletionCallback callback1;
ASSERT_EQ(ERR_IO_PENDING,
trans1.Start(&request1, callback1.callback(), BoundNetLog()));
- data1->RunFor(3);
+ // This pause is a hack to avoid running into https://crbug.com/497228.
+ data1.RunUntilPaused();
+ base::RunLoop().RunUntilIdle();
+ data1.Resume();
- ASSERT_TRUE(callback1.have_result());
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
@@ -12852,7 +13837,6 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
EXPECT_EQ(ERR_IO_PENDING,
trans2.Start(&request2, callback2.callback(), BoundNetLog()));
base::MessageLoop::current()->RunUntilIdle();
- data2->RunFor(3);
ASSERT_TRUE(callback2.have_result());
EXPECT_EQ(OK, callback2.WaitForResult());
@@ -12890,16 +13874,16 @@ TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
arraysize(writes2));
SSLSocketDataProvider ssl1(ASYNC, OK);
- ssl1.SetNextProto(GetParam());
+ ssl1.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
session_deps_.socket_factory->AddSocketDataProvider(&data1);
SSLSocketDataProvider ssl2(ASYNC, OK);
- ssl2.SetNextProto(GetParam());
+ ssl2.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
session_deps_.socket_factory->AddSocketDataProvider(&data2);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps_));
// Start the first transaction to set up the SpdySession and verify that
@@ -12938,12 +13922,12 @@ TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
// Use two different hosts with different IPs so they don't get pooled.
session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
SSLSocketDataProvider ssl1(ASYNC, OK);
- ssl1.SetNextProto(GetParam());
+ ssl1.SetNextProto(GetProtocol());
SSLSocketDataProvider ssl2(ASYNC, OK);
- ssl2.SetNextProto(GetParam());
+ ssl2.SetNextProto(GetProtocol());
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
@@ -12957,29 +13941,30 @@ TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
scoped_ptr<SpdyFrame> host1_resp_body(
spdy_util_.ConstructSpdyBodyFrame(1, true));
MockRead spdy1_reads[] = {
- CreateMockRead(*host1_resp, 1),
- CreateMockRead(*host1_resp_body, 2),
- MockRead(ASYNC, ERR_IO_PENDING, 3),
+ CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
};
+ // Use a separate test instance for the separate SpdySession that will be
+ // created.
+ SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
scoped_ptr<SequencedSocketData> spdy1_data(
new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
arraysize(spdy1_writes)));
session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
- scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
+ scoped_ptr<SpdyFrame> host2_req(spdy_util_2.ConstructSpdyGet(
"https://www.b.com", false, 1, DEFAULT_PRIORITY));
MockWrite spdy2_writes[] = {
CreateMockWrite(*host2_req, 0),
};
scoped_ptr<SpdyFrame> host2_resp(
- spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> host2_resp_body(
- spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_2.ConstructSpdyBodyFrame(1, true));
MockRead spdy2_reads[] = {
- CreateMockRead(*host2_resp, 1),
- CreateMockRead(*host2_resp_body, 2),
- MockRead(ASYNC, ERR_IO_PENDING, 3),
+ CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
};
scoped_ptr<SequencedSocketData> spdy2_data(
@@ -13024,7 +14009,7 @@ TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
@@ -13053,7 +14038,7 @@ TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
@@ -13098,7 +14083,7 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -13135,7 +14120,7 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -13172,7 +14157,7 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -13206,7 +14191,7 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -13240,7 +14225,7 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -13277,7 +14262,7 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -13315,7 +14300,7 @@ TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
request.load_flags = 0;
request.extra_headers.SetHeader("X-Foo", "bar");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -13430,6 +14415,8 @@ class FakeStream : public HttpStream,
void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
+ void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
+
void SetPriority(RequestPriority priority) override { priority_ = priority; }
UploadProgress GetUploadProgress() const override { return UploadProgress(); }
@@ -13534,6 +14521,17 @@ class FakeStreamFactory : public HttpStreamFactory {
return fake_request;
}
+ HttpStreamRequest* RequestBidirectionalStreamJob(
+ const HttpRequestInfo& info,
+ RequestPriority priority,
+ const SSLConfig& server_ssl_config,
+ const SSLConfig& proxy_ssl_config,
+ HttpStreamRequest::Delegate* delegate,
+ const BoundNetLog& net_log) override {
+ NOTREACHED();
+ return nullptr;
+ }
+
HttpStreamRequest* RequestWebSocketHandshakeStream(
const HttpRequestInfo& info,
RequestPriority priority,
@@ -13648,6 +14646,8 @@ class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
+ void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
+
void SetPriority(RequestPriority priority) override { NOTREACHED(); }
UploadProgress GetUploadProgress() const override {
@@ -13681,7 +14681,7 @@ class FakeWebSocketStreamCreateHelper :
WebSocketHandshakeStreamBase* CreateBasicStream(
scoped_ptr<ClientSocketHandle> connection,
bool using_proxy) override {
- return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
+ return new FakeWebSocketBasicHandshakeStream(std::move(connection),
using_proxy);
}
@@ -13705,8 +14705,8 @@ class FakeWebSocketStreamCreateHelper :
// Make sure that HttpNetworkTransaction passes on its priority to its
// stream request on start.
TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session);
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpNetworkSessionPeer peer(session.get());
FakeStreamFactory* fake_factory = new FakeStreamFactory();
peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
@@ -13728,8 +14728,8 @@ TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
// Make sure that HttpNetworkTransaction passes on its priority
// updates to its stream request.
TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session);
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpNetworkSessionPeer peer(session.get());
FakeStreamFactory* fake_factory = new FakeStreamFactory();
peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
@@ -13753,8 +14753,8 @@ TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
// Make sure that HttpNetworkTransaction passes on its priority
// updates to its stream.
TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session);
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpNetworkSessionPeer peer(session.get());
FakeStreamFactory* fake_factory = new FakeStreamFactory();
peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
@@ -13783,8 +14783,8 @@ TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
std::string test_cases[] = {"ws://www.example.org/",
"wss://www.example.org/"};
for (size_t i = 0; i < arraysize(test_cases); ++i) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session);
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpNetworkSessionPeer peer(session.get());
FakeStreamFactory* fake_factory = new FakeStreamFactory();
FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
peer.SetHttpStreamFactoryForWebSocket(
@@ -13865,7 +14865,7 @@ TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
http_writes, arraysize(http_writes));
session_deps_.socket_factory->AddSocketDataProvider(&http_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Start the SSL request.
TestCompletionCallback ssl_callback;
@@ -13947,7 +14947,7 @@ TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
http_writes, arraysize(http_writes));
session_deps_.socket_factory->AddSocketDataProvider(&http_data);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Preconnect an SSL socket. A preconnect is needed because connect jobs are
// cancelled when a normal transaction is cancelled.
@@ -13978,9 +14978,10 @@ TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
}
TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -13988,7 +14989,7 @@ TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14033,7 +15034,7 @@ TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
// response from a server that rejected a POST with a CONNECTION_RESET.
TEST_P(HttpNetworkTransactionTest,
PostReadsErrorResponseAfterResetOnReusedSocket) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
"Host: www.foo.com\r\n"
@@ -14085,9 +15086,10 @@ TEST_P(HttpNetworkTransactionTest,
// Delete the transaction to release the socket back into the socket pool.
trans1.reset();
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request2;
request2.method = "POST";
@@ -14117,9 +15119,10 @@ TEST_P(HttpNetworkTransactionTest,
TEST_P(HttpNetworkTransactionTest,
PostReadsErrorResponseAfterResetPartialBodySent) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -14127,7 +15130,7 @@ TEST_P(HttpNetworkTransactionTest,
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14172,8 +15175,6 @@ TEST_P(HttpNetworkTransactionTest,
// This tests the more common case than the previous test, where headers and
// body are not merged into a single request.
TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
ChunkedUploadDataStream upload_data_stream(0);
HttpRequestInfo request;
@@ -14182,7 +15183,7 @@ TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14231,9 +15232,10 @@ TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
}
TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -14241,7 +15243,7 @@ TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -14284,9 +15286,10 @@ TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
}
TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -14294,7 +15297,7 @@ TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14326,9 +15329,10 @@ TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
TEST_P(HttpNetworkTransactionTest,
PostIgnoresNonErrorResponseAfterResetAnd100) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -14336,7 +15340,7 @@ TEST_P(HttpNetworkTransactionTest,
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14369,9 +15373,10 @@ TEST_P(HttpNetworkTransactionTest,
}
TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -14379,7 +15384,7 @@ TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14409,9 +15414,10 @@ TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
}
TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -14419,7 +15425,7 @@ TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14460,31 +15466,28 @@ TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
session_deps_.proxy_service =
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since a proxy is configured, try to establish a tunnel.
MockWrite data_writes[] = {
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
// After calling trans->RestartWithAuth(), this is the request we should
// be issuing -- the final header line contains the credentials.
- MockWrite(
- "CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
+ "Host: www.example.org:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
- 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\r\n"),
+ 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\r\n"),
};
// The proxy responds to the connect with a 407, using a persistent
@@ -14493,7 +15496,8 @@ TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
// No credentials.
MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Proxy-Connection: close\r\n\r\n"),
+ MockRead("Content-Length: 0\r\n"),
+ MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
@@ -14566,7 +15570,7 @@ TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
session_deps_.proxy_service =
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
MockWrite data_writes[] = {
// Try to establish a tunnel for the WebSocket connection, with
@@ -14633,16 +15637,17 @@ TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
}
TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
request.url = GURL("http://www.foo.com/");
request.upload_data_stream = &upload_data_stream;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
MockWrite data_writes[] = {
@@ -14677,16 +15682,17 @@ TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
}
TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
request.url = GURL("http://www.foo.com/");
request.upload_data_stream = &upload_data_stream;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
MockWrite data_writes[] = {
@@ -14722,8 +15728,6 @@ TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
}
TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("foo", 3));
ChunkedUploadDataStream upload_data_stream(0);
HttpRequestInfo request;
@@ -14731,7 +15735,7 @@ TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
request.url = GURL("http://www.foo.com/");
request.upload_data_stream = &upload_data_stream;
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
// Send headers successfully, but get an error while sending the body.
@@ -14773,4 +15777,29 @@ TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
trans->GetTotalReceivedBytes());
}
+TEST_P(HttpNetworkTransactionTest, EnableNPN) {
+ session_deps_.next_protos = NextProtosDefaults();
+ session_deps_.enable_npn = true;
+
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+
+ EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
+ testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
+ EXPECT_THAT(trans.server_ssl_config_.npn_protos,
+ testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
+}
+
+TEST_P(HttpNetworkTransactionTest, DisableNPN) {
+ session_deps_.next_protos = NextProtosDefaults();
+ session_deps_.enable_npn = false;
+
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+
+ EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
+ testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
+ EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
+}
+
} // namespace net
diff --git a/chromium/net/http/http_proxy_client_socket.cc b/chromium/net/http/http_proxy_client_socket.cc
index f5feb585bf2..562bff36b90 100644
--- a/chromium/net/http/http_proxy_client_socket.cc
+++ b/chromium/net/http/http_proxy_client_socket.cc
@@ -32,8 +32,7 @@ HttpProxyClientSocket::HttpProxyClientSocket(
const std::string& user_agent,
const HostPortPair& endpoint,
const HostPortPair& proxy_server,
- HttpAuthCache* http_auth_cache,
- HttpAuthHandlerFactory* http_auth_handler_factory,
+ HttpAuthController* http_auth_controller,
bool tunnel,
bool using_spdy,
NextProto protocol_negotiated,
@@ -44,13 +43,7 @@ HttpProxyClientSocket::HttpProxyClientSocket(
next_state_(STATE_NONE),
transport_(transport_socket),
endpoint_(endpoint),
- auth_(tunnel ?
- new HttpAuthController(HttpAuth::AUTH_PROXY,
- GURL((is_https_proxy ? "https://" : "http://")
- + proxy_server.ToString()),
- http_auth_cache,
- http_auth_handler_factory)
- : NULL),
+ auth_(http_auth_controller),
tunnel_(tunnel),
using_spdy_(using_spdy),
protocol_negotiated_(protocol_negotiated),
@@ -219,6 +212,10 @@ void HttpProxyClientSocket::GetConnectionAttempts(
out->clear();
}
+int64_t HttpProxyClientSocket::GetTotalReceivedBytes() const {
+ return transport_->socket()->GetTotalReceivedBytes();
+}
+
int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(user_callback_.is_null());
@@ -247,11 +244,11 @@ int HttpProxyClientSocket::Write(IOBuffer* buf, int buf_len,
return transport_->socket()->Write(buf, buf_len, callback);
}
-int HttpProxyClientSocket::SetReceiveBufferSize(int32 size) {
+int HttpProxyClientSocket::SetReceiveBufferSize(int32_t size) {
return transport_->socket()->SetReceiveBufferSize(size);
}
-int HttpProxyClientSocket::SetSendBufferSize(int32 size) {
+int HttpProxyClientSocket::SetSendBufferSize(int32_t size) {
return transport_->socket()->SetSendBufferSize(size);
}
@@ -267,36 +264,36 @@ int HttpProxyClientSocket::PrepareForAuthRestart() {
if (!response_.headers.get())
return ERR_CONNECTION_RESET;
- bool keep_alive = false;
- if (response_.headers->IsKeepAlive() &&
- http_stream_parser_->CanFindEndOfResponse()) {
- if (!http_stream_parser_->IsResponseBodyComplete()) {
- next_state_ = STATE_DRAIN_BODY;
- drain_buf_ = new IOBuffer(kDrainBodyBufferSize);
- return OK;
- }
- keep_alive = true;
+ // If the connection can't be reused, just return ERR_CONNECTION_CLOSED.
+ // The request should be retried at a higher layer.
+ if (!response_.headers->IsKeepAlive() ||
+ !http_stream_parser_->CanFindEndOfResponse() ||
+ !transport_->socket()->IsConnected()) {
+ transport_->socket()->Disconnect();
+ return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH;
+ }
+
+ // If the auth request had a body, need to drain it before reusing the socket.
+ if (!http_stream_parser_->IsResponseBodyComplete()) {
+ next_state_ = STATE_DRAIN_BODY;
+ drain_buf_ = new IOBuffer(kDrainBodyBufferSize);
+ return OK;
}
- // We don't need to drain the response body, so we act as if we had drained
- // the response body.
- return DidDrainBodyForAuthRestart(keep_alive);
+ return DidDrainBodyForAuthRestart();
}
-int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) {
- if (keep_alive && transport_->socket()->IsConnectedAndIdle()) {
- next_state_ = STATE_GENERATE_AUTH_TOKEN;
- transport_->set_reuse_type(ClientSocketHandle::REUSED_IDLE);
- } else {
- // This assumes that the underlying transport socket is a TCP socket,
- // since only TCP sockets are restartable.
- next_state_ = STATE_TCP_RESTART;
- transport_->socket()->Disconnect();
- }
+int HttpProxyClientSocket::DidDrainBodyForAuthRestart() {
+ // Can't reuse the socket if there's still unread data on it.
+ if (!transport_->socket()->IsConnectedAndIdle())
+ return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH;
+
+ next_state_ = STATE_GENERATE_AUTH_TOKEN;
+ transport_->set_reuse_type(ClientSocketHandle::REUSED_IDLE);
// Reset the other member variables.
- drain_buf_ = NULL;
- parser_buf_ = NULL;
+ drain_buf_ = nullptr;
+ parser_buf_ = nullptr;
http_stream_parser_.reset();
request_line_.clear();
request_headers_.Clear();
@@ -373,13 +370,6 @@ int HttpProxyClientSocket::DoLoop(int last_io_result) {
case STATE_DRAIN_BODY_COMPLETE:
rv = DoDrainBodyComplete(rv);
break;
- case STATE_TCP_RESTART:
- DCHECK_EQ(OK, rv);
- rv = DoTCPRestart();
- break;
- case STATE_TCP_RESTART_COMPLETE:
- rv = DoTCPRestartComplete(rv);
- break;
case STATE_DONE:
break;
default:
@@ -458,7 +448,7 @@ int HttpProxyClientSocket::DoReadHeadersComplete(int result) {
return result;
// Require the "HTTP/1.x" status line for SSL CONNECT.
- if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0))
+ if (response_.headers->GetHttpVersion() < HttpVersion(1, 0))
return ERR_TUNNEL_CONNECTION_FAILED;
net_log_.AddEvent(
@@ -538,33 +528,17 @@ int HttpProxyClientSocket::DoDrainBody() {
int HttpProxyClientSocket::DoDrainBodyComplete(int result) {
if (result < 0)
- return result;
-
- if (http_stream_parser_->IsResponseBodyComplete())
- return DidDrainBodyForAuthRestart(true);
+ return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH;
- // Keep draining.
- next_state_ = STATE_DRAIN_BODY;
- return OK;
-}
+ if (!http_stream_parser_->IsResponseBodyComplete()) {
+ // Keep draining.
+ next_state_ = STATE_DRAIN_BODY;
+ return OK;
+ }
-int HttpProxyClientSocket::DoTCPRestart() {
- next_state_ = STATE_TCP_RESTART_COMPLETE;
- return transport_->socket()->Connect(
- base::Bind(&HttpProxyClientSocket::OnIOComplete, base::Unretained(this)));
+ return DidDrainBodyForAuthRestart();
}
-int HttpProxyClientSocket::DoTCPRestartComplete(int result) {
- // TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "462784 HttpProxyClientSocket::DoTCPRestartComplete"));
-
- if (result != OK)
- return result;
-
- next_state_ = STATE_GENERATE_AUTH_TOKEN;
- return result;
-}
+//----------------------------------------------------------------
} // namespace net
diff --git a/chromium/net/http/http_proxy_client_socket.h b/chromium/net/http/http_proxy_client_socket.h
index 439278aa398..a8a5d275ede 100644
--- a/chromium/net/http/http_proxy_client_socket.h
+++ b/chromium/net/http/http_proxy_client_socket.h
@@ -5,9 +5,11 @@
#ifndef NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_H_
#define NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/completion_callback.h"
#include "net/base/host_port_pair.h"
@@ -25,7 +27,6 @@ namespace net {
class AddressList;
class ClientSocketHandle;
class GrowableIOBuffer;
-class HttpAuthCache;
class HttpStream;
class HttpStreamParser;
class IOBuffer;
@@ -40,8 +41,7 @@ class HttpProxyClientSocket : public ProxyClientSocket {
const std::string& user_agent,
const HostPortPair& endpoint,
const HostPortPair& proxy_server,
- HttpAuthCache* http_auth_cache,
- HttpAuthHandlerFactory* http_auth_handler_factory,
+ HttpAuthController* http_auth_controller,
bool tunnel,
bool using_spdy,
NextProto protocol_negotiated,
@@ -75,6 +75,7 @@ class HttpProxyClientSocket : public ProxyClientSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -83,8 +84,8 @@ class HttpProxyClientSocket : public ProxyClientSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
@@ -99,8 +100,6 @@ class HttpProxyClientSocket : public ProxyClientSocket {
STATE_READ_HEADERS_COMPLETE,
STATE_DRAIN_BODY,
STATE_DRAIN_BODY_COMPLETE,
- STATE_TCP_RESTART,
- STATE_TCP_RESTART_COMPLETE,
STATE_DONE,
};
@@ -110,7 +109,7 @@ class HttpProxyClientSocket : public ProxyClientSocket {
static const int kDrainBodyBufferSize = 1024;
int PrepareForAuthRestart();
- int DidDrainBodyForAuthRestart(bool keep_alive);
+ int DidDrainBodyForAuthRestart();
void LogBlockedTunnelResponse() const;
@@ -126,8 +125,6 @@ class HttpProxyClientSocket : public ProxyClientSocket {
int DoReadHeadersComplete(int result);
int DoDrainBody();
int DoDrainBodyComplete(int result);
- int DoTCPRestart();
- int DoTCPRestartComplete(int result);
CompletionCallback io_callback_;
State next_state_;
diff --git a/chromium/net/http/http_proxy_client_socket_pool.cc b/chromium/net/http/http_proxy_client_socket_pool.cc
index 1a60c6ae5ad..f0f8795a08a 100644
--- a/chromium/net/http/http_proxy_client_socket_pool.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool.cc
@@ -5,6 +5,7 @@
#include "net/http/http_proxy_client_socket_pool.h"
#include <algorithm>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/time/time.h"
@@ -13,7 +14,7 @@
#include "net/base/net_errors.h"
#include "net/base/proxy_delegate.h"
#include "net/http/http_network_session.h"
-#include "net/http/http_proxy_client_socket.h"
+#include "net/http/http_proxy_client_socket_wrapper.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool_base.h"
@@ -86,305 +87,66 @@ HttpProxyConnectJob::HttpProxyConnectJob(
SSLClientSocketPool* ssl_pool,
Delegate* delegate,
NetLog* net_log)
- : ConnectJob(group_name, timeout_duration, priority, delegate,
+ : ConnectJob(group_name,
+ base::TimeDelta() /* The socket takes care of timeouts */,
+ priority,
+ delegate,
BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
- params_(params),
- transport_pool_(transport_pool),
- ssl_pool_(ssl_pool),
- using_spdy_(false),
- protocol_negotiated_(kProtoUnknown),
- weak_ptr_factory_(this) {
- callback_= base::Bind(&HttpProxyConnectJob::OnIOComplete,
- weak_ptr_factory_.GetWeakPtr());
-}
+ client_socket_(new HttpProxyClientSocketWrapper(
+ group_name,
+ priority,
+ timeout_duration,
+ base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds),
+ transport_pool,
+ ssl_pool,
+ params->transport_params(),
+ params->ssl_params(),
+ params->user_agent(),
+ params->endpoint(),
+ params->http_auth_cache(),
+ params->http_auth_handler_factory(),
+ params->spdy_session_pool(),
+ params->tunnel(),
+ params->proxy_delegate(),
+ this->net_log())) {}
HttpProxyConnectJob::~HttpProxyConnectJob() {}
LoadState HttpProxyConnectJob::GetLoadState() const {
- switch (next_state_) {
- case STATE_TCP_CONNECT:
- case STATE_TCP_CONNECT_COMPLETE:
- case STATE_SSL_CONNECT:
- case STATE_SSL_CONNECT_COMPLETE:
- return transport_socket_handle_->GetLoadState();
- case STATE_HTTP_PROXY_CONNECT:
- case STATE_HTTP_PROXY_CONNECT_COMPLETE:
- case STATE_SPDY_PROXY_CREATE_STREAM:
- case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
- return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
- default:
- NOTREACHED();
- return LOAD_STATE_IDLE;
- }
+ return client_socket_->GetConnectLoadState();
}
void HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
- if (error_response_info_.cert_request_info.get()) {
- handle->set_ssl_error_response_info(error_response_info_);
+ if (error_response_info_) {
+ handle->set_ssl_error_response_info(*error_response_info_);
handle->set_is_ssl_error(true);
}
}
-void HttpProxyConnectJob::OnIOComplete(int result) {
- int rv = DoLoop(result);
- if (rv != ERR_IO_PENDING) {
- NotifyProxyDelegateOfCompletion(rv);
- NotifyDelegateOfCompletion(rv); // Deletes |this|
- }
-}
-
-int HttpProxyConnectJob::DoLoop(int result) {
- DCHECK_NE(next_state_, STATE_NONE);
-
- int rv = result;
- do {
- State state = next_state_;
- next_state_ = STATE_NONE;
- switch (state) {
- case STATE_TCP_CONNECT:
- DCHECK_EQ(OK, rv);
- rv = DoTransportConnect();
- break;
- case STATE_TCP_CONNECT_COMPLETE:
- rv = DoTransportConnectComplete(rv);
- break;
- case STATE_SSL_CONNECT:
- DCHECK_EQ(OK, rv);
- rv = DoSSLConnect();
- break;
- case STATE_SSL_CONNECT_COMPLETE:
- rv = DoSSLConnectComplete(rv);
- break;
- case STATE_HTTP_PROXY_CONNECT:
- DCHECK_EQ(OK, rv);
- rv = DoHttpProxyConnect();
- break;
- case STATE_HTTP_PROXY_CONNECT_COMPLETE:
- rv = DoHttpProxyConnectComplete(rv);
- break;
- case STATE_SPDY_PROXY_CREATE_STREAM:
- DCHECK_EQ(OK, rv);
- rv = DoSpdyProxyCreateStream();
- break;
- case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
- rv = DoSpdyProxyCreateStreamComplete(rv);
- break;
- default:
- NOTREACHED() << "bad state";
- rv = ERR_FAILED;
- break;
- }
- } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
-
- return rv;
-}
-
-int HttpProxyConnectJob::DoTransportConnect() {
- next_state_ = STATE_TCP_CONNECT_COMPLETE;
- transport_socket_handle_.reset(new ClientSocketHandle());
- return transport_socket_handle_->Init(group_name(),
- params_->transport_params(),
- priority(),
- callback_,
- transport_pool_,
- net_log());
-}
-
-int HttpProxyConnectJob::DoTransportConnectComplete(int result) {
- if (result != OK)
- return ERR_PROXY_CONNECTION_FAILED;
-
- // Reset the timer to just the length of time allowed for HttpProxy handshake
- // so that a fast TCP connection plus a slow HttpProxy failure doesn't take
- // longer to timeout than it should.
- ResetTimer(base::TimeDelta::FromSeconds(
- kHttpProxyConnectJobTimeoutInSeconds));
-
- next_state_ = STATE_HTTP_PROXY_CONNECT;
- return result;
+int HttpProxyConnectJob::ConnectInternal() {
+ int result = client_socket_->Connect(base::Bind(
+ &HttpProxyConnectJob::OnConnectComplete, base::Unretained(this)));
+ return HandleConnectResult(result);
}
-int HttpProxyConnectJob::DoSSLConnect() {
- if (params_->tunnel()) {
- SpdySessionKey key(params_->destination().host_port_pair(),
- ProxyServer::Direct(),
- PRIVACY_MODE_DISABLED);
- if (params_->spdy_session_pool()->FindAvailableSession(key, net_log())) {
- using_spdy_ = true;
- next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
- return OK;
- }
- }
- next_state_ = STATE_SSL_CONNECT_COMPLETE;
- transport_socket_handle_.reset(new ClientSocketHandle());
- return transport_socket_handle_->Init(
- group_name(), params_->ssl_params(), priority(), callback_,
- ssl_pool_, net_log());
+void HttpProxyConnectJob::OnConnectComplete(int result) {
+ DCHECK_NE(ERR_IO_PENDING, result);
+ result = HandleConnectResult(result);
+ NotifyDelegateOfCompletion(result);
+ // |this| will have been deleted at this point.
}
-int HttpProxyConnectJob::DoSSLConnectComplete(int result) {
- if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
- error_response_info_ = transport_socket_handle_->ssl_error_response_info();
- DCHECK(error_response_info_.cert_request_info.get());
- error_response_info_.cert_request_info->is_proxy = true;
- return result;
- }
- if (IsCertificateError(result)) {
- if (params_->ssl_params()->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS) {
- result = OK;
- } else {
- // TODO(rch): allow the user to deal with proxy cert errors in the
- // same way as server cert errors.
- transport_socket_handle_->socket()->Disconnect();
- return ERR_PROXY_CERTIFICATE_INVALID;
- }
- }
- // A SPDY session to the proxy completed prior to resolving the proxy
- // hostname. Surface this error, and allow the delegate to retry.
- // See crbug.com/334413.
- if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) {
- DCHECK(!transport_socket_handle_->socket());
- return ERR_SPDY_SESSION_ALREADY_EXISTS;
- }
- if (result < 0) {
- if (transport_socket_handle_->socket())
- transport_socket_handle_->socket()->Disconnect();
- return ERR_PROXY_CONNECTION_FAILED;
- }
+int HttpProxyConnectJob::HandleConnectResult(int result) {
+ if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
+ error_response_info_ = client_socket_->GetAdditionalErrorState();
- SSLClientSocket* ssl =
- static_cast<SSLClientSocket*>(transport_socket_handle_->socket());
- protocol_negotiated_ = ssl->GetNegotiatedProtocol();
- using_spdy_ = NextProtoIsSPDY(protocol_negotiated_);
-
- // Reset the timer to just the length of time allowed for HttpProxy handshake
- // so that a fast SSL connection plus a slow HttpProxy failure doesn't take
- // longer to timeout than it should.
- ResetTimer(base::TimeDelta::FromSeconds(
- kHttpProxyConnectJobTimeoutInSeconds));
- // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy
- // (one that we speak SPDY over SSL to, but to which we send HTTPS
- // request directly instead of through CONNECT tunnels, then we
- // need to add a predicate to this if statement so we fall through
- // to the else case. (HttpProxyClientSocket currently acts as
- // a "trusted" SPDY proxy).
- if (using_spdy_ && params_->tunnel()) {
- next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
- } else {
- next_state_ = STATE_HTTP_PROXY_CONNECT;
- }
- return result;
-}
-
-int HttpProxyConnectJob::DoHttpProxyConnect() {
- next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
- const HostResolver::RequestInfo& tcp_destination = params_->destination();
- const HostPortPair& proxy_server = tcp_destination.host_port_pair();
-
- // Add a HttpProxy connection on top of the tcp socket.
- transport_socket_.reset(
- new HttpProxyClientSocket(transport_socket_handle_.release(),
- params_->user_agent(),
- params_->endpoint(),
- proxy_server,
- params_->http_auth_cache(),
- params_->http_auth_handler_factory(),
- params_->tunnel(),
- using_spdy_,
- protocol_negotiated_,
- params_->proxy_delegate(),
- params_->ssl_params().get() != NULL));
- return transport_socket_->Connect(callback_);
-}
-
-int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
if (result == OK || result == ERR_PROXY_AUTH_REQUESTED ||
result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
- SetSocket(transport_socket_.Pass());
+ SetSocket(std::move(client_socket_));
}
-
- if (result == ERR_HTTP_1_1_REQUIRED)
- return ERR_PROXY_HTTP_1_1_REQUIRED;
-
return result;
}
-int HttpProxyConnectJob::DoSpdyProxyCreateStream() {
- DCHECK(using_spdy_);
- DCHECK(params_->tunnel());
- SpdySessionKey key(params_->destination().host_port_pair(),
- ProxyServer::Direct(),
- PRIVACY_MODE_DISABLED);
- SpdySessionPool* spdy_pool = params_->spdy_session_pool();
- base::WeakPtr<SpdySession> spdy_session =
- spdy_pool->FindAvailableSession(key, net_log());
- // It's possible that a session to the proxy has recently been created
- if (spdy_session) {
- if (transport_socket_handle_.get()) {
- if (transport_socket_handle_->socket())
- transport_socket_handle_->socket()->Disconnect();
- transport_socket_handle_->Reset();
- }
- } else {
- // Create a session direct to the proxy itself
- spdy_session =
- spdy_pool->CreateAvailableSessionFromSocket(
- key, transport_socket_handle_.Pass(),
- net_log(), OK, /*using_ssl_*/ true);
- DCHECK(spdy_session);
- }
-
- next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
- return spdy_stream_request_.StartRequest(
- SPDY_BIDIRECTIONAL_STREAM, spdy_session,
- GURL("https://" + params_->endpoint().ToString()), priority(),
- spdy_session->net_log(), callback_);
-}
-
-int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
- if (result < 0)
- return result;
-
- next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
- base::WeakPtr<SpdyStream> stream = spdy_stream_request_.ReleaseStream();
- DCHECK(stream.get());
- // |transport_socket_| will set itself as |stream|'s delegate.
- transport_socket_.reset(
- new SpdyProxyClientSocket(stream,
- params_->user_agent(),
- params_->endpoint(),
- params_->destination().host_port_pair(),
- net_log(),
- params_->http_auth_cache(),
- params_->http_auth_handler_factory()));
- return transport_socket_->Connect(callback_);
-}
-
-void HttpProxyConnectJob::NotifyProxyDelegateOfCompletion(int result) {
- if (!params_->proxy_delegate())
- return;
-
- const HostPortPair& proxy_server = params_->destination().host_port_pair();
- params_->proxy_delegate()->OnTunnelConnectCompleted(params_->endpoint(),
- proxy_server,
- result);
-}
-
-int HttpProxyConnectJob::ConnectInternal() {
- if (params_->transport_params().get()) {
- next_state_ = STATE_TCP_CONNECT;
- } else {
- next_state_ = STATE_SSL_CONNECT;
- }
-
- int rv = DoLoop(OK);
- if (rv != ERR_IO_PENDING) {
- NotifyProxyDelegateOfCompletion(rv);
- }
-
- return rv;
-}
-
HttpProxyClientSocketPool::
HttpProxyConnectJobFactory::HttpProxyConnectJobFactory(
TransportClientSocketPool* transport_pool,
@@ -486,7 +248,7 @@ void HttpProxyClientSocketPool::CancelRequest(
void HttpProxyClientSocketPool::ReleaseSocket(const std::string& group_name,
scoped_ptr<StreamSocket> socket,
int id) {
- base_.ReleaseSocket(group_name, socket.Pass(), id);
+ base_.ReleaseSocket(group_name, std::move(socket), id);
}
void HttpProxyClientSocketPool::FlushWithError(int error) {
@@ -530,7 +292,7 @@ scoped_ptr<base::DictionaryValue> HttpProxyClientSocketPool::GetInfoAsValue(
}
dict->Set("nested_pools", list);
}
- return dict.Pass();
+ return dict;
}
base::TimeDelta HttpProxyClientSocketPool::ConnectionTimeout() const {
diff --git a/chromium/net/http/http_proxy_client_socket_pool.h b/chromium/net/http/http_proxy_client_socket_pool.h
index 1440fc7eb67..44f9ab6703d 100644
--- a/chromium/net/http/http_proxy_client_socket_pool.h
+++ b/chromium/net/http/http_proxy_client_socket_pool.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -26,6 +26,7 @@ namespace net {
class HttpAuthCache;
class HttpAuthHandlerFactory;
+class HttpProxyClientSocketWrapper;
class ProxyDelegate;
class SSLClientSocketPool;
class SSLSocketParams;
@@ -113,39 +114,6 @@ class HttpProxyConnectJob : public ConnectJob {
void GetAdditionalErrorState(ClientSocketHandle* handle) override;
private:
- enum State {
- STATE_TCP_CONNECT,
- STATE_TCP_CONNECT_COMPLETE,
- STATE_SSL_CONNECT,
- STATE_SSL_CONNECT_COMPLETE,
- STATE_HTTP_PROXY_CONNECT,
- STATE_HTTP_PROXY_CONNECT_COMPLETE,
- STATE_SPDY_PROXY_CREATE_STREAM,
- STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE,
- STATE_SPDY_PROXY_CONNECT_COMPLETE,
- STATE_NONE,
- };
-
- void OnIOComplete(int result);
-
- // Runs the state transition loop.
- int DoLoop(int result);
-
- // Connecting to HTTP Proxy
- int DoTransportConnect();
- int DoTransportConnectComplete(int result);
- // Connecting to HTTPS Proxy
- int DoSSLConnect();
- int DoSSLConnectComplete(int result);
-
- int DoHttpProxyConnect();
- int DoHttpProxyConnectComplete(int result);
-
- int DoSpdyProxyCreateStream();
- int DoSpdyProxyCreateStreamComplete(int result);
-
- void NotifyProxyDelegateOfCompletion(int result);
-
// Begins the tcp connection and the optional Http proxy tunnel. If the
// request is not immediately servicable (likely), the request will return
// ERR_IO_PENDING. An OK return from this function or the callback means
@@ -155,23 +123,13 @@ class HttpProxyConnectJob : public ConnectJob {
// a standard net error code will be returned.
int ConnectInternal() override;
- scoped_refptr<HttpProxySocketParams> params_;
- TransportClientSocketPool* const transport_pool_;
- SSLClientSocketPool* const ssl_pool_;
-
- State next_state_;
- CompletionCallback callback_;
- scoped_ptr<ClientSocketHandle> transport_socket_handle_;
- scoped_ptr<ProxyClientSocket> transport_socket_;
- bool using_spdy_;
- // Protocol negotiated with the server.
- NextProto protocol_negotiated_;
+ void OnConnectComplete(int result);
- HttpResponseInfo error_response_info_;
+ int HandleConnectResult(int result);
- SpdyStreamRequest spdy_stream_request_;
+ scoped_ptr<HttpProxyClientSocketWrapper> client_socket_;
- base::WeakPtrFactory<HttpProxyConnectJob> weak_ptr_factory_;
+ scoped_ptr<HttpResponseInfo> error_response_info_;
DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob);
};
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 6b44dbbee49..97d7270fa67 100644
--- a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -41,16 +41,19 @@ enum HttpProxyType {
struct HttpProxyClientSocketPoolTestParams {
HttpProxyClientSocketPoolTestParams()
: proxy_type(HTTP),
- protocol(kProtoSPDY31) {}
+ protocol(kProtoSPDY31),
+ priority_to_dependency(false) {}
- HttpProxyClientSocketPoolTestParams(
- HttpProxyType proxy_type,
- NextProto protocol)
+ HttpProxyClientSocketPoolTestParams(HttpProxyType proxy_type,
+ NextProto protocol,
+ bool priority_to_dependency)
: proxy_type(proxy_type),
- protocol(protocol) {}
+ protocol(protocol),
+ priority_to_dependency(priority_to_dependency) {}
HttpProxyType proxy_type;
NextProto protocol;
+ bool priority_to_dependency;
};
typedef ::testing::TestWithParam<HttpProxyType> TestWithHttpParam;
@@ -149,6 +152,7 @@ class TestProxyDelegate : public ProxyDelegate {
std::string on_tunnel_headers_received_status_line_;
};
+} // namespace
class HttpProxyClientSocketPoolTest
: public ::testing::TestWithParam<HttpProxyClientSocketPoolTestParams> {
@@ -164,7 +168,7 @@ class HttpProxyClientSocketPoolTest
NULL /* channel_id_store */,
NULL /* transport_security_state */,
NULL /* cert_transparency_verifier */,
- NULL /* cert_policy_enforcer */,
+ NULL /* ct_policy_enforcer */,
std::string() /* ssl_session_cache_shard */,
session_deps_.socket_factory.get(),
&transport_socket_pool_,
@@ -173,14 +177,18 @@ class HttpProxyClientSocketPoolTest
session_deps_.ssl_config_service.get(),
BoundNetLog().net_log()),
session_(CreateNetworkSession()),
- spdy_util_(GetParam().protocol),
+ spdy_util_(GetParam().protocol, GetParam().priority_to_dependency),
pool_(kMaxSockets,
kMaxSocketsPerGroup,
&transport_socket_pool_,
&ssl_socket_pool_,
- NULL) {}
+ NULL) {
+ SpdySession::SetPriorityDependencyDefaultForTesting(
+ GetParam().priority_to_dependency);
+ }
virtual ~HttpProxyClientSocketPoolTest() {
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
}
void AddAuthToCache() {
@@ -287,7 +295,7 @@ class HttpProxyClientSocketPoolTest
ssl_data_->SetNextProto(GetParam().protocol);
}
- HttpNetworkSession* CreateNetworkSession() {
+ scoped_ptr<HttpNetworkSession> CreateNetworkSession() {
return SpdySessionDependencies::SpdyCreateSession(&session_deps_);
}
@@ -303,7 +311,7 @@ class HttpProxyClientSocketPoolTest
scoped_ptr<CertVerifier> cert_verifier_;
SSLClientSocketPool ssl_socket_pool_;
- const scoped_refptr<HttpNetworkSession> session_;
+ const scoped_ptr<HttpNetworkSession> session_;
protected:
SpdyTestUtil spdy_util_;
@@ -323,12 +331,16 @@ class HttpProxyClientSocketPoolTest
INSTANTIATE_TEST_CASE_P(
HttpProxyClientSocketPoolTests,
HttpProxyClientSocketPoolTest,
- ::testing::Values(HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY31),
- HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY31),
- HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY31),
- HttpProxyClientSocketPoolTestParams(HTTP, kProtoHTTP2),
- HttpProxyClientSocketPoolTestParams(HTTPS, kProtoHTTP2),
- HttpProxyClientSocketPoolTestParams(SPDY, kProtoHTTP2)));
+ ::testing::Values(
+ HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY31, false),
+ HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY31, false),
+ HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY31, false),
+ HttpProxyClientSocketPoolTestParams(HTTP, kProtoHTTP2, false),
+ HttpProxyClientSocketPoolTestParams(HTTP, kProtoHTTP2, true),
+ HttpProxyClientSocketPoolTestParams(HTTPS, kProtoHTTP2, false),
+ HttpProxyClientSocketPoolTestParams(HTTPS, kProtoHTTP2, true),
+ HttpProxyClientSocketPoolTestParams(SPDY, kProtoHTTP2, false),
+ HttpProxyClientSocketPoolTestParams(SPDY, kProtoHTTP2, true)));
TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) {
Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0);
@@ -339,9 +351,7 @@ TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) {
EXPECT_EQ(OK, rv);
EXPECT_TRUE(handle_.is_initialized());
ASSERT_TRUE(handle_.socket());
- HttpProxyClientSocket* tunnel_socket =
- static_cast<HttpProxyClientSocket*>(handle_.socket());
- EXPECT_TRUE(tunnel_socket->IsConnected());
+ EXPECT_TRUE(handle_.socket()->IsConnected());
EXPECT_FALSE(proxy_delegate->on_before_tunnel_request_called());
EXPECT_FALSE(proxy_delegate->on_tunnel_headers_received_called());
EXPECT_TRUE(proxy_delegate->on_tunnel_request_completed_called());
@@ -359,9 +369,10 @@ TEST_P(HttpProxyClientSocketPoolTest, SetSocketRequestPriorityOnInit) {
TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) {
MockWrite writes[] = {
- MockWrite(ASYNC, 0, "CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite(ASYNC, 0,
+ "CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead reads[] = {
// No credentials.
@@ -425,10 +436,11 @@ TEST_P(HttpProxyClientSocketPoolTest, HaveAuth) {
(kHttpsProxyHost + std::string(":443"));
std::string request =
"CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
+ "Host: www.google.com:443\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
- "Foo: " + proxy_host_port + "\r\n\r\n";
+ "Foo: " +
+ proxy_host_port + "\r\n\r\n";
MockWrite writes[] = {
MockWrite(SYNCHRONOUS, 0, request.c_str()),
};
@@ -446,9 +458,7 @@ TEST_P(HttpProxyClientSocketPoolTest, HaveAuth) {
EXPECT_EQ(OK, rv);
EXPECT_TRUE(handle_.is_initialized());
ASSERT_TRUE(handle_.socket());
- HttpProxyClientSocket* tunnel_socket =
- static_cast<HttpProxyClientSocket*>(handle_.socket());
- EXPECT_TRUE(tunnel_socket->IsConnected());
+ EXPECT_TRUE(handle_.socket()->IsConnected());
proxy_delegate->VerifyOnTunnelHeadersReceived(
"www.google.com:443",
proxy_host_port.c_str(),
@@ -465,10 +475,11 @@ TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
(kHttpsProxyHost + std::string(":443"));
std::string request =
"CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
+ "Host: www.google.com:443\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
- "Foo: " + proxy_host_port + "\r\n\r\n";
+ "Foo: " +
+ proxy_host_port + "\r\n\r\n";
MockWrite writes[] = {
MockWrite(ASYNC, 0, request.c_str()),
};
@@ -613,11 +624,11 @@ TEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) {
TEST_P(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) {
MockWrite writes[] = {
- MockWrite(ASYNC, 0,
- "CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ MockWrite(ASYNC, 0,
+ "CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead(ASYNC, 1, "HTTP/1.1 200 Conn"),
@@ -663,10 +674,10 @@ TEST_P(HttpProxyClientSocketPoolTest, Tunnel1xxResponse) {
}
MockWrite writes[] = {
- MockWrite(ASYNC, 0,
- "CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite(ASYNC, 0,
+ "CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead reads[] = {
MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
@@ -687,11 +698,11 @@ TEST_P(HttpProxyClientSocketPoolTest, Tunnel1xxResponse) {
TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupError) {
MockWrite writes[] = {
- MockWrite(ASYNC, 0,
- "CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ MockWrite(ASYNC, 0,
+ "CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead(ASYNC, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"),
@@ -737,11 +748,11 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) {
"Set-Cookie: foo=bar\r\n"
"\r\n";
MockWrite writes[] = {
- MockWrite(ASYNC, 0,
- "CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ MockWrite(ASYNC, 0,
+ "CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead(ASYNC, 1, responseText.c_str()),
@@ -816,6 +827,4 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) {
// It would be nice to also test the timeouts in HttpProxyClientSocketPool.
-} // namespace
-
} // namespace net
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.cc b/chromium/net/http/http_proxy_client_socket_wrapper.cc
new file mode 100644
index 00000000000..1a56a5c488f
--- /dev/null
+++ b/chromium/net/http/http_proxy_client_socket_wrapper.cc
@@ -0,0 +1,636 @@
+// Copyright 2015 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/http_proxy_client_socket_wrapper.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
+#include "base/memory/weak_ptr.h"
+#include "base/profiler/scoped_tracker.h"
+#include "base/values.h"
+#include "net/base/net_util.h"
+#include "net/base/proxy_delegate.h"
+#include "net/http/http_proxy_client_socket.h"
+#include "net/http/http_response_info.h"
+#include "net/socket/client_socket_handle.h"
+#include "net/spdy/spdy_proxy_client_socket.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_stream.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "url/gurl.h"
+
+namespace net {
+
+HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper(
+ const std::string& group_name,
+ RequestPriority priority,
+ base::TimeDelta connect_timeout_duration,
+ base::TimeDelta proxy_negotiation_timeout_duration,
+ TransportClientSocketPool* transport_pool,
+ SSLClientSocketPool* ssl_pool,
+ const scoped_refptr<TransportSocketParams>& transport_params,
+ const scoped_refptr<SSLSocketParams>& ssl_params,
+ const std::string& user_agent,
+ const HostPortPair& endpoint,
+ HttpAuthCache* http_auth_cache,
+ HttpAuthHandlerFactory* http_auth_handler_factory,
+ SpdySessionPool* spdy_session_pool,
+ bool tunnel,
+ ProxyDelegate* proxy_delegate,
+ const BoundNetLog& net_log)
+ : next_state_(STATE_NONE),
+ group_name_(group_name),
+ priority_(priority),
+ connect_timeout_duration_(connect_timeout_duration),
+ proxy_negotiation_timeout_duration_(proxy_negotiation_timeout_duration),
+ transport_pool_(transport_pool),
+ ssl_pool_(ssl_pool),
+ transport_params_(transport_params),
+ ssl_params_(ssl_params),
+ user_agent_(user_agent),
+ endpoint_(endpoint),
+ http_auth_cache_(http_auth_cache),
+ http_auth_handler_factory_(http_auth_handler_factory),
+ spdy_session_pool_(spdy_session_pool),
+ tunnel_(tunnel),
+ proxy_delegate_(proxy_delegate),
+ using_spdy_(false),
+ http_auth_controller_(
+ tunnel ? new HttpAuthController(
+ HttpAuth::AUTH_PROXY,
+ GURL((ssl_params_.get() ? "https://" : "http://") +
+ GetDestination().host_port_pair().ToString()),
+ http_auth_cache,
+ http_auth_handler_factory)
+ : nullptr),
+ net_log_(BoundNetLog::Make(net_log.net_log(),
+ NetLog::SOURCE_PROXY_CLIENT_SOCKET_WRAPPER)) {
+ net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
+ net_log.source().ToEventParametersCallback());
+ DCHECK(transport_params || ssl_params);
+ DCHECK(!transport_params || !ssl_params);
+}
+
+HttpProxyClientSocketWrapper::~HttpProxyClientSocketWrapper() {
+ // Make sure no sockets are returned to the lower level socket pools.
+ Disconnect();
+
+ net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
+}
+
+LoadState HttpProxyClientSocketWrapper::GetConnectLoadState() const {
+ switch (next_state_) {
+ case STATE_BEGIN_CONNECT:
+ case STATE_TCP_CONNECT:
+ case STATE_TCP_CONNECT_COMPLETE:
+ case STATE_SSL_CONNECT:
+ case STATE_SSL_CONNECT_COMPLETE:
+ return transport_socket_handle_->GetLoadState();
+ case STATE_HTTP_PROXY_CONNECT:
+ case STATE_HTTP_PROXY_CONNECT_COMPLETE:
+ case STATE_SPDY_PROXY_CREATE_STREAM:
+ case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
+ case STATE_SPDY_PROXY_CONNECT_COMPLETE:
+ case STATE_RESTART_WITH_AUTH:
+ case STATE_RESTART_WITH_AUTH_COMPLETE:
+ return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
+ case STATE_NONE:
+ // May be possible for this method to be called after an error, shouldn't
+ // be called after a successful connect.
+ break;
+ }
+ return LOAD_STATE_IDLE;
+}
+
+scoped_ptr<HttpResponseInfo>
+HttpProxyClientSocketWrapper::GetAdditionalErrorState() {
+ return std::move(error_response_info_);
+}
+
+const HttpResponseInfo* HttpProxyClientSocketWrapper::GetConnectResponseInfo()
+ const {
+ if (transport_socket_)
+ return transport_socket_->GetConnectResponseInfo();
+ return nullptr;
+}
+
+HttpStream* HttpProxyClientSocketWrapper::CreateConnectResponseStream() {
+ if (transport_socket_)
+ return transport_socket_->CreateConnectResponseStream();
+ return nullptr;
+}
+
+int HttpProxyClientSocketWrapper::RestartWithAuth(
+ const CompletionCallback& callback) {
+ DCHECK(!callback.is_null());
+ DCHECK(connect_callback_.is_null());
+ DCHECK(transport_socket_);
+ DCHECK_EQ(STATE_NONE, next_state_);
+
+ connect_callback_ = callback;
+ next_state_ = STATE_RESTART_WITH_AUTH;
+ return DoLoop(OK);
+}
+
+const scoped_refptr<HttpAuthController>&
+HttpProxyClientSocketWrapper::GetAuthController() const {
+ return http_auth_controller_;
+}
+
+bool HttpProxyClientSocketWrapper::IsUsingSpdy() const {
+ if (transport_socket_)
+ return transport_socket_->IsUsingSpdy();
+ return false;
+}
+
+NextProto HttpProxyClientSocketWrapper::GetProtocolNegotiated() const {
+ if (transport_socket_)
+ return transport_socket_->GetProtocolNegotiated();
+ return kProtoUnknown;
+}
+
+int HttpProxyClientSocketWrapper::Connect(const CompletionCallback& callback) {
+ DCHECK(!callback.is_null());
+ DCHECK(connect_callback_.is_null());
+
+ // If connecting or previously connected and not disconnected, return OK, to
+ // match TCPClientSocket's behavior.
+ if (next_state_ != STATE_NONE || transport_socket_)
+ return OK;
+
+ next_state_ = STATE_BEGIN_CONNECT;
+ int rv = DoLoop(OK);
+ if (rv == ERR_IO_PENDING) {
+ connect_callback_ = callback;
+ } else {
+ connect_timer_.Stop();
+ NotifyProxyDelegateOfCompletion(rv);
+ }
+
+ return rv;
+}
+
+void HttpProxyClientSocketWrapper::Disconnect() {
+ connect_callback_.Reset();
+ connect_timer_.Stop();
+ next_state_ = STATE_NONE;
+ spdy_stream_request_.CancelRequest();
+ if (transport_socket_handle_) {
+ if (transport_socket_handle_->socket())
+ transport_socket_handle_->socket()->Disconnect();
+ transport_socket_handle_->Reset();
+ transport_socket_handle_.reset();
+ }
+
+ if (transport_socket_)
+ transport_socket_->Disconnect();
+}
+
+bool HttpProxyClientSocketWrapper::IsConnected() const {
+ if (transport_socket_)
+ return transport_socket_->IsConnected();
+ // Don't return true if still connecting. Shouldn't really matter, either
+ // way.
+ return false;
+}
+
+bool HttpProxyClientSocketWrapper::IsConnectedAndIdle() const {
+ if (transport_socket_)
+ return transport_socket_->IsConnectedAndIdle();
+ return false;
+}
+
+const BoundNetLog& HttpProxyClientSocketWrapper::NetLog() const {
+ return net_log_;
+}
+
+void HttpProxyClientSocketWrapper::SetSubresourceSpeculation() {
+ // This flag isn't passed to reconnected sockets, as only the first connection
+ // can be a preconnect.
+ if (transport_socket_)
+ transport_socket_->SetSubresourceSpeculation();
+}
+
+void HttpProxyClientSocketWrapper::SetOmniboxSpeculation() {
+ // This flag isn't passed to reconnected sockets, as only the first connection
+ // can be a preconnect.
+ if (transport_socket_)
+ transport_socket_->SetOmniboxSpeculation();
+}
+
+bool HttpProxyClientSocketWrapper::WasEverUsed() const {
+ // TODO(mmenke): This is a little weird. Figure out if something else should
+ // be done.
+ if (transport_socket_)
+ return transport_socket_->WasEverUsed();
+ return false;
+}
+
+bool HttpProxyClientSocketWrapper::UsingTCPFastOpen() const {
+ if (transport_socket_)
+ return transport_socket_->UsingTCPFastOpen();
+ return false;
+}
+
+bool HttpProxyClientSocketWrapper::WasNpnNegotiated() const {
+ if (transport_socket_)
+ return transport_socket_->WasNpnNegotiated();
+ return false;
+}
+
+NextProto HttpProxyClientSocketWrapper::GetNegotiatedProtocol() const {
+ if (transport_socket_)
+ return transport_socket_->GetNegotiatedProtocol();
+ return kProtoUnknown;
+}
+
+bool HttpProxyClientSocketWrapper::GetSSLInfo(SSLInfo* ssl_info) {
+ if (transport_socket_)
+ return transport_socket_->GetSSLInfo(ssl_info);
+ return false;
+}
+
+void HttpProxyClientSocketWrapper::GetConnectionAttempts(
+ ConnectionAttempts* out) const {
+ // TODO(mmenke): Not clear how reconnecting for auth fits into things.
+ if (transport_socket_) {
+ transport_socket_->GetConnectionAttempts(out);
+ } else {
+ out->clear();
+ }
+}
+
+void HttpProxyClientSocketWrapper::ClearConnectionAttempts() {
+ if (transport_socket_)
+ transport_socket_->ClearConnectionAttempts();
+}
+
+void HttpProxyClientSocketWrapper::AddConnectionAttempts(
+ const ConnectionAttempts& attempts) {
+ if (transport_socket_)
+ transport_socket_->AddConnectionAttempts(attempts);
+}
+
+int64_t HttpProxyClientSocketWrapper::GetTotalReceivedBytes() const {
+ return transport_socket_->GetTotalReceivedBytes();
+}
+
+int HttpProxyClientSocketWrapper::Read(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ if (transport_socket_)
+ return transport_socket_->Read(buf, buf_len, callback);
+ return ERR_SOCKET_NOT_CONNECTED;
+}
+
+int HttpProxyClientSocketWrapper::Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ if (transport_socket_)
+ return transport_socket_->Write(buf, buf_len, callback);
+ return ERR_SOCKET_NOT_CONNECTED;
+}
+
+int HttpProxyClientSocketWrapper::SetReceiveBufferSize(int32_t size) {
+ // TODO(mmenke): Should this persist across reconnects? Seems a little
+ // weird, and not done for normal reconnects.
+ if (transport_socket_)
+ return transport_socket_->SetReceiveBufferSize(size);
+ return ERR_SOCKET_NOT_CONNECTED;
+}
+
+int HttpProxyClientSocketWrapper::SetSendBufferSize(int32_t size) {
+ if (transport_socket_)
+ return transport_socket_->SetSendBufferSize(size);
+ return ERR_SOCKET_NOT_CONNECTED;
+}
+
+int HttpProxyClientSocketWrapper::GetPeerAddress(IPEndPoint* address) const {
+ if (transport_socket_)
+ return transport_socket_->GetPeerAddress(address);
+ return ERR_SOCKET_NOT_CONNECTED;
+}
+
+int HttpProxyClientSocketWrapper::GetLocalAddress(IPEndPoint* address) const {
+ if (transport_socket_)
+ return transport_socket_->GetLocalAddress(address);
+ return ERR_SOCKET_NOT_CONNECTED;
+}
+
+void HttpProxyClientSocketWrapper::OnIOComplete(int result) {
+ int rv = DoLoop(result);
+ if (rv != ERR_IO_PENDING) {
+ connect_timer_.Stop();
+ NotifyProxyDelegateOfCompletion(rv);
+ // May delete |this|.
+ base::ResetAndReturn(&connect_callback_).Run(rv);
+ }
+}
+
+int HttpProxyClientSocketWrapper::DoLoop(int result) {
+ DCHECK_NE(next_state_, STATE_NONE);
+
+ int rv = result;
+ do {
+ State state = next_state_;
+ next_state_ = STATE_NONE;
+ switch (state) {
+ case STATE_BEGIN_CONNECT:
+ DCHECK_EQ(OK, rv);
+ rv = DoBeginConnect();
+ break;
+ case STATE_TCP_CONNECT:
+ DCHECK_EQ(OK, rv);
+ rv = DoTransportConnect();
+ break;
+ case STATE_TCP_CONNECT_COMPLETE:
+ rv = DoTransportConnectComplete(rv);
+ break;
+ case STATE_SSL_CONNECT:
+ DCHECK_EQ(OK, rv);
+ rv = DoSSLConnect();
+ break;
+ case STATE_SSL_CONNECT_COMPLETE:
+ rv = DoSSLConnectComplete(rv);
+ break;
+ case STATE_HTTP_PROXY_CONNECT:
+ DCHECK_EQ(OK, rv);
+ rv = DoHttpProxyConnect();
+ break;
+ case STATE_HTTP_PROXY_CONNECT_COMPLETE:
+ rv = DoHttpProxyConnectComplete(rv);
+ break;
+ case STATE_SPDY_PROXY_CREATE_STREAM:
+ DCHECK_EQ(OK, rv);
+ rv = DoSpdyProxyCreateStream();
+ break;
+ case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
+ rv = DoSpdyProxyCreateStreamComplete(rv);
+ break;
+ case STATE_RESTART_WITH_AUTH:
+ DCHECK_EQ(OK, rv);
+ rv = DoRestartWithAuth();
+ break;
+ case STATE_RESTART_WITH_AUTH_COMPLETE:
+ rv = DoRestartWithAuthComplete(rv);
+ break;
+ default:
+ NOTREACHED() << "bad state";
+ rv = ERR_FAILED;
+ break;
+ }
+ } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
+
+ return rv;
+}
+
+int HttpProxyClientSocketWrapper::DoBeginConnect() {
+ SetConnectTimer(connect_timeout_duration_);
+ if (transport_params_) {
+ next_state_ = STATE_TCP_CONNECT;
+ } else {
+ next_state_ = STATE_SSL_CONNECT;
+ }
+
+ return OK;
+}
+
+int HttpProxyClientSocketWrapper::DoTransportConnect() {
+ next_state_ = STATE_TCP_CONNECT_COMPLETE;
+ transport_socket_handle_.reset(new ClientSocketHandle());
+ return transport_socket_handle_->Init(
+ group_name_, transport_params_, priority_,
+ base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete,
+ base::Unretained(this)),
+ transport_pool_, net_log_);
+}
+
+int HttpProxyClientSocketWrapper::DoTransportConnectComplete(int result) {
+ if (result != OK)
+ return ERR_PROXY_CONNECTION_FAILED;
+
+ // Reset the timer to just the length of time allowed for HttpProxy handshake
+ // so that a fast TCP connection plus a slow HttpProxy failure doesn't take
+ // longer to timeout than it should.
+ SetConnectTimer(proxy_negotiation_timeout_duration_);
+
+ next_state_ = STATE_HTTP_PROXY_CONNECT;
+ return result;
+}
+
+int HttpProxyClientSocketWrapper::DoSSLConnect() {
+ if (tunnel_) {
+ SpdySessionKey key(GetDestination().host_port_pair(), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ if (spdy_session_pool_->FindAvailableSession(key, net_log_)) {
+ using_spdy_ = true;
+ next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
+ return OK;
+ }
+ }
+ next_state_ = STATE_SSL_CONNECT_COMPLETE;
+ transport_socket_handle_.reset(new ClientSocketHandle());
+ return transport_socket_handle_->Init(
+ group_name_, ssl_params_, priority_,
+ base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete,
+ base::Unretained(this)),
+ ssl_pool_, net_log_);
+}
+
+int HttpProxyClientSocketWrapper::DoSSLConnectComplete(int result) {
+ if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
+ DCHECK(
+ transport_socket_handle_->ssl_error_response_info().cert_request_info);
+ error_response_info_.reset(new HttpResponseInfo(
+ transport_socket_handle_->ssl_error_response_info()));
+ error_response_info_->cert_request_info->is_proxy = true;
+ return result;
+ }
+
+ if (IsCertificateError(result)) {
+ if (ssl_params_->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS) {
+ result = OK;
+ } else {
+ // TODO(rch): allow the user to deal with proxy cert errors in the
+ // same way as server cert errors.
+ transport_socket_handle_->socket()->Disconnect();
+ return ERR_PROXY_CERTIFICATE_INVALID;
+ }
+ }
+ // A SPDY session to the proxy completed prior to resolving the proxy
+ // hostname. Surface this error, and allow the delegate to retry.
+ // See crbug.com/334413.
+ if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) {
+ DCHECK(!transport_socket_handle_->socket());
+ return ERR_SPDY_SESSION_ALREADY_EXISTS;
+ }
+ if (result < 0) {
+ if (transport_socket_handle_->socket())
+ transport_socket_handle_->socket()->Disconnect();
+ return ERR_PROXY_CONNECTION_FAILED;
+ }
+
+ SSLClientSocket* ssl =
+ static_cast<SSLClientSocket*>(transport_socket_handle_->socket());
+ protocol_negotiated_ = ssl->GetNegotiatedProtocol();
+ using_spdy_ = NextProtoIsSPDY(protocol_negotiated_);
+
+ // Reset the timer to just the length of time allowed for HttpProxy handshake
+ // so that a fast SSL connection plus a slow HttpProxy failure doesn't take
+ // longer to timeout than it should.
+ SetConnectTimer(proxy_negotiation_timeout_duration_);
+
+ // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy
+ // (one that we speak SPDY over SSL to, but to which we send HTTPS
+ // request directly instead of through CONNECT tunnels, then we
+ // need to add a predicate to this if statement so we fall through
+ // to the else case. (HttpProxyClientSocket currently acts as
+ // a "trusted" SPDY proxy).
+ if (using_spdy_ && tunnel_) {
+ next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
+ } else {
+ next_state_ = STATE_HTTP_PROXY_CONNECT;
+ }
+ return result;
+}
+
+int HttpProxyClientSocketWrapper::DoHttpProxyConnect() {
+ next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
+
+ // Add a HttpProxy connection on top of the tcp socket.
+ transport_socket_.reset(new HttpProxyClientSocket(
+ transport_socket_handle_.release(), user_agent_, endpoint_,
+ GetDestination().host_port_pair(), http_auth_controller_.get(), tunnel_,
+ using_spdy_, protocol_negotiated_, proxy_delegate_,
+ ssl_params_.get() != nullptr));
+ return transport_socket_->Connect(base::Bind(
+ &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
+}
+
+int HttpProxyClientSocketWrapper::DoHttpProxyConnectComplete(int result) {
+ if (result == ERR_HTTP_1_1_REQUIRED)
+ return ERR_PROXY_HTTP_1_1_REQUIRED;
+
+ return result;
+}
+
+int HttpProxyClientSocketWrapper::DoSpdyProxyCreateStream() {
+ DCHECK(using_spdy_);
+ DCHECK(tunnel_);
+ SpdySessionKey key(GetDestination().host_port_pair(), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ base::WeakPtr<SpdySession> spdy_session =
+ spdy_session_pool_->FindAvailableSession(key, net_log_);
+ // It's possible that a session to the proxy has recently been created
+ if (spdy_session) {
+ if (transport_socket_handle_.get()) {
+ if (transport_socket_handle_->socket())
+ transport_socket_handle_->socket()->Disconnect();
+ transport_socket_handle_->Reset();
+ }
+ } else {
+ // Create a session direct to the proxy itself
+ spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket(
+ key, std::move(transport_socket_handle_), net_log_, OK,
+ /*using_ssl_*/ true);
+ DCHECK(spdy_session);
+ }
+
+ next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
+ return spdy_stream_request_.StartRequest(
+ SPDY_BIDIRECTIONAL_STREAM, spdy_session,
+ GURL("https://" + endpoint_.ToString()), priority_,
+ spdy_session->net_log(),
+ base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete,
+ base::Unretained(this)));
+}
+
+int HttpProxyClientSocketWrapper::DoSpdyProxyCreateStreamComplete(int result) {
+ if (result < 0)
+ return result;
+
+ next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
+ base::WeakPtr<SpdyStream> stream = spdy_stream_request_.ReleaseStream();
+ DCHECK(stream.get());
+ // |transport_socket_| will set itself as |stream|'s delegate.
+ transport_socket_.reset(new SpdyProxyClientSocket(
+ stream, user_agent_, endpoint_, GetDestination().host_port_pair(),
+ net_log_, http_auth_controller_.get()));
+ return transport_socket_->Connect(base::Bind(
+ &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
+}
+
+int HttpProxyClientSocketWrapper::DoRestartWithAuth() {
+ DCHECK(transport_socket_);
+
+ next_state_ = STATE_RESTART_WITH_AUTH_COMPLETE;
+ return transport_socket_->RestartWithAuth(base::Bind(
+ &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
+}
+
+int HttpProxyClientSocketWrapper::DoRestartWithAuthComplete(int result) {
+ DCHECK_NE(ERR_IO_PENDING, result);
+ // If the connection could not be reused to attempt to send proxy auth
+ // credentials, try reconnecting. If auth credentials were sent, pass the
+ // error on to caller, even if the credentials may have passed a close message
+ // from the server in flight.
+ if (result == ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH) {
+ // If can't reuse the connection, attempt to create a new one.
+ transport_socket_.reset();
+ // Reconnect with HIGHEST priority to get in front of other requests that
+ // don't yet have the information |http_auth_controller_| does.
+ // TODO(mmenke): This may still result in waiting in line, if there are
+ // other HIGHEST priority requests. Consider a workaround for
+ // that. Starting the new request before releasing the old
+ // socket and using LOAD_IGNORE_LIMITS would do the trick,
+ // without exceding the the socket pool limits (Since the old
+ // socket would free up the extra socket slot when destroyed).
+ priority_ = HIGHEST;
+ next_state_ = STATE_BEGIN_CONNECT;
+ return OK;
+ }
+
+ return result;
+}
+
+void HttpProxyClientSocketWrapper::NotifyProxyDelegateOfCompletion(int result) {
+ if (!proxy_delegate_)
+ return;
+
+ const HostPortPair& proxy_server = GetDestination().host_port_pair();
+ proxy_delegate_->OnTunnelConnectCompleted(endpoint_, proxy_server, result);
+}
+
+void HttpProxyClientSocketWrapper::SetConnectTimer(base::TimeDelta delay) {
+ connect_timer_.Stop();
+ connect_timer_.Start(FROM_HERE, delay, this,
+ &HttpProxyClientSocketWrapper::ConnectTimeout);
+}
+
+void HttpProxyClientSocketWrapper::ConnectTimeout() {
+ // Timer shouldn't be running if next_state_ is STATE_NONE.
+ DCHECK_NE(STATE_NONE, next_state_);
+ DCHECK(!connect_callback_.is_null());
+
+ NotifyProxyDelegateOfCompletion(ERR_CONNECTION_TIMED_OUT);
+
+ CompletionCallback callback = connect_callback_;
+ Disconnect();
+ callback.Run(ERR_CONNECTION_TIMED_OUT);
+}
+
+const HostResolver::RequestInfo&
+HttpProxyClientSocketWrapper::GetDestination() {
+ if (transport_params_) {
+ return transport_params_->destination();
+ } else {
+ return ssl_params_->GetDirectConnectionParams()->destination();
+ }
+}
+
+} // namespace net
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.h b/chromium/net/http/http_proxy_client_socket_wrapper.h
new file mode 100644
index 00000000000..70e3882be68
--- /dev/null
+++ b/chromium/net/http/http_proxy_client_socket_wrapper.h
@@ -0,0 +1,214 @@
+// Copyright 2015 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_PROXY_CLIENT_SOCKET_WRAPPER_H_
+#define NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_WRAPPER_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "net/base/completion_callback.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/load_timing_info.h"
+#include "net/http/http_auth_controller.h"
+#include "net/http/proxy_client_socket.h"
+#include "net/log/net_log.h"
+#include "net/socket/next_proto.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/socket/ssl_client_socket_pool.h"
+#include "net/socket/transport_client_socket_pool.h"
+#include "net/spdy/spdy_session.h"
+
+namespace net {
+
+class ClientSocketHandle;
+class IOBuffer;
+class HttpAuthCache;
+class HttpResponseInfo;
+class HttpStream;
+class IOBuffer;
+class ProxyDelegate;
+class SpdySessionPool;
+class SSLClientSocketPool;
+class TransportClientSocketPool;
+
+// Class that establishes connections by calling into the lower layer socket
+// pools, creates a HttpProxyClientSocket / SpdyProxyClientSocket, and then
+// wraps the resulting socket.
+//
+// This class is needed to handle auth state across multiple connection. On
+// auth challenge, this class retains auth state in its AuthController, and can
+// either send the auth response to the old connection, or establish a new
+// connection and send the response there.
+//
+// TODO(mmenke): Ideally, we'd have a central location store auth state across
+// multiple connections to the same server instead.
+class HttpProxyClientSocketWrapper : public ProxyClientSocket {
+ public:
+ HttpProxyClientSocketWrapper(
+ const std::string& group_name,
+ RequestPriority priority,
+ base::TimeDelta connect_timeout_duration,
+ base::TimeDelta proxy_negotiation_timeout_duration,
+ TransportClientSocketPool* transport_pool,
+ SSLClientSocketPool* ssl_pool,
+ const scoped_refptr<TransportSocketParams>& transport_params,
+ const scoped_refptr<SSLSocketParams>& ssl_params,
+ const std::string& user_agent,
+ const HostPortPair& endpoint,
+ HttpAuthCache* http_auth_cache,
+ HttpAuthHandlerFactory* http_auth_handler_factory,
+ SpdySessionPool* spdy_session_pool,
+ bool tunnel,
+ ProxyDelegate* proxy_delegate,
+ const BoundNetLog& net_log);
+
+ // On destruction Disconnect() is called.
+ ~HttpProxyClientSocketWrapper() override;
+
+ // Returns load state while establishing a connection. Returns
+ // LOAD_STATE_IDLE at other times.
+ LoadState GetConnectLoadState() const;
+
+ scoped_ptr<HttpResponseInfo> GetAdditionalErrorState();
+
+ // ProxyClientSocket implementation.
+ const HttpResponseInfo* GetConnectResponseInfo() const override;
+ HttpStream* CreateConnectResponseStream() override;
+ int RestartWithAuth(const CompletionCallback& callback) override;
+ const scoped_refptr<HttpAuthController>& GetAuthController() const override;
+ bool IsUsingSpdy() const override;
+ NextProto GetProtocolNegotiated() const override;
+
+ // StreamSocket implementation.
+ int Connect(const CompletionCallback& callback) override;
+ void Disconnect() override;
+ bool IsConnected() const override;
+ bool IsConnectedAndIdle() const override;
+ const BoundNetLog& NetLog() const override;
+ void SetSubresourceSpeculation() override;
+ void SetOmniboxSpeculation() override;
+ bool WasEverUsed() const override;
+ bool UsingTCPFastOpen() const override;
+ bool WasNpnNegotiated() const override;
+ NextProto GetNegotiatedProtocol() const override;
+ bool GetSSLInfo(SSLInfo* ssl_info) override;
+ void GetConnectionAttempts(ConnectionAttempts* out) const override;
+ void ClearConnectionAttempts() override;
+ void AddConnectionAttempts(const ConnectionAttempts& attempts) override;
+ int64_t GetTotalReceivedBytes() const override;
+
+ // Socket implementation.
+ int Read(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) override;
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
+ int GetPeerAddress(IPEndPoint* address) const override;
+ int GetLocalAddress(IPEndPoint* address) const override;
+
+ private:
+ enum State {
+ STATE_BEGIN_CONNECT,
+ STATE_TCP_CONNECT,
+ STATE_TCP_CONNECT_COMPLETE,
+ STATE_SSL_CONNECT,
+ STATE_SSL_CONNECT_COMPLETE,
+ STATE_HTTP_PROXY_CONNECT,
+ STATE_HTTP_PROXY_CONNECT_COMPLETE,
+ STATE_SPDY_PROXY_CREATE_STREAM,
+ STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE,
+ STATE_SPDY_PROXY_CONNECT_COMPLETE,
+ STATE_RESTART_WITH_AUTH,
+ STATE_RESTART_WITH_AUTH_COMPLETE,
+ STATE_NONE,
+ };
+
+ void OnIOComplete(int result);
+
+ // Runs the state transition loop.
+ int DoLoop(int result);
+
+ // Determine if need to go through TCP or SSL path.
+ int DoBeginConnect();
+ // Connecting to HTTP Proxy
+ int DoTransportConnect();
+ int DoTransportConnectComplete(int result);
+ // Connecting to HTTPS Proxy
+ int DoSSLConnect();
+ int DoSSLConnectComplete(int result);
+
+ int DoHttpProxyConnect();
+ int DoHttpProxyConnectComplete(int result);
+
+ int DoSpdyProxyCreateStream();
+ int DoSpdyProxyCreateStreamComplete(int result);
+
+ int DoRestartWithAuth();
+ int DoRestartWithAuthComplete(int result);
+
+ void NotifyProxyDelegateOfCompletion(int result);
+
+ void SetConnectTimer(base::TimeDelta duration);
+ void ConnectTimeout();
+
+ const HostResolver::RequestInfo& GetDestination();
+
+ State next_state_;
+
+ const std::string group_name_;
+ RequestPriority priority_;
+ const base::TimeDelta connect_timeout_duration_;
+ const base::TimeDelta proxy_negotiation_timeout_duration_;
+
+ TransportClientSocketPool* const transport_pool_;
+ SSLClientSocketPool* const ssl_pool_;
+ const scoped_refptr<TransportSocketParams> transport_params_;
+ const scoped_refptr<SSLSocketParams> ssl_params_;
+
+ const std::string user_agent_;
+ const HostPortPair endpoint_;
+ HttpAuthCache* const http_auth_cache_;
+ HttpAuthHandlerFactory* const http_auth_handler_factory_;
+ SpdySessionPool* const spdy_session_pool_;
+
+ const bool tunnel_;
+ ProxyDelegate* const proxy_delegate_;
+
+ bool using_spdy_;
+ NextProto protocol_negotiated_;
+
+ scoped_ptr<HttpResponseInfo> error_response_info_;
+
+ scoped_ptr<ClientSocketHandle> transport_socket_handle_;
+ scoped_ptr<ProxyClientSocket> transport_socket_;
+
+ // Called when a connection is established. Also used when restarting with
+ // AUTH, which will invoke this when ready to restart, after reconnecting
+ // if necessary.
+ CompletionCallback connect_callback_;
+
+ SpdyStreamRequest spdy_stream_request_;
+
+ scoped_refptr<HttpAuthController> http_auth_controller_;
+
+ BoundNetLog net_log_;
+
+ base::OneShotTimer connect_timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocketWrapper);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_WRAPPER_H_
diff --git a/chromium/net/http/http_request_headers.cc b/chromium/net/http/http_request_headers.cc
index c2eee59af95..d3f1401c777 100644
--- a/chromium/net/http/http_request_headers.cc
+++ b/chromium/net/http/http_request_headers.cc
@@ -4,6 +4,8 @@
#include "net/http/http_request_headers.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -154,15 +156,9 @@ void HttpRequestHeaders::AddHeaderFromString(
void HttpRequestHeaders::AddHeadersFromString(
const base::StringPiece& headers) {
- // TODO(willchan): Consider adding more StringPiece support in string_util.h
- // to eliminate copies.
- std::vector<std::string> header_line_vector;
- base::SplitStringUsingSubstr(headers.as_string(), "\r\n",
- &header_line_vector);
- for (std::vector<std::string>::const_iterator it = header_line_vector.begin();
- it != header_line_vector.end(); ++it) {
- if (!it->empty())
- AddHeaderFromString(*it);
+ for (const base::StringPiece& header : base::SplitStringPieceUsingSubstr(
+ headers, "\r\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+ AddHeaderFromString(header);
}
}
@@ -203,7 +199,7 @@ scoped_ptr<base::Value> HttpRequestHeaders::NetLogCallback(
it->key.c_str(), log_value.c_str())));
}
dict->Set("headers", headers);
- return dict.Pass();
+ return std::move(dict);
}
// static
diff --git a/chromium/net/http/http_request_headers.h b/chromium/net/http/http_request_headers.h
index e6f25eda21e..76bf25e4af4 100644
--- a/chromium/net/http/http_request_headers.h
+++ b/chromium/net/http/http_request_headers.h
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/log/net_log.h"
diff --git a/chromium/net/http/http_request_info.h b/chromium/net/http/http_request_info.h
index a587a421b58..0c4c09defbc 100644
--- a/chromium/net/http/http_request_info.h
+++ b/chromium/net/http/http_request_info.h
@@ -7,7 +7,6 @@
#include <string>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
#include "net/base/privacy_mode.h"
#include "net/http/http_request_headers.h"
diff --git a/chromium/net/http/http_response_body_drainer.h b/chromium/net/http/http_response_body_drainer.h
index 33368225be6..2ff4a767f95 100644
--- a/chromium/net/http/http_response_body_drainer.h
+++ b/chromium/net/http/http_response_body_drainer.h
@@ -5,7 +5,7 @@
#ifndef NET_HTTP_HTTP_RESPONSE_BODY_DRAINER_H_
#define NET_HTTP_HTTP_RESPONSE_BODY_DRAINER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
diff --git a/chromium/net/http/http_response_body_drainer_unittest.cc b/chromium/net/http/http_response_body_drainer_unittest.cc
index e44e6ee1e8a..4568cbacce6 100644
--- a/chromium/net/http/http_response_body_drainer_unittest.cc
+++ b/chromium/net/http/http_response_body_drainer_unittest.cc
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
@@ -56,7 +57,7 @@ class CloseResultWaiter {
result_ = result;
have_result_ = true;
if (waiting_for_result_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
private:
@@ -127,6 +128,8 @@ class MockHttpStream : public HttpStream {
void Drain(HttpNetworkSession*) override {}
+ void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
+
void SetPriority(RequestPriority priority) override {}
// Methods to tweak/observer mock behavior:
@@ -232,7 +235,7 @@ class HttpResponseBodyDrainerTest : public testing::Test {
scoped_refptr<SSLConfigService> ssl_config_service_;
scoped_ptr<HttpServerPropertiesImpl> http_server_properties_;
scoped_ptr<TransportSecurityState> transport_security_state_;
- const scoped_refptr<HttpNetworkSession> session_;
+ const scoped_ptr<HttpNetworkSession> session_;
CloseResultWaiter result_waiter_;
MockHttpStream* const mock_stream_; // Owned by |drainer_|.
HttpResponseBodyDrainer* const drainer_; // Deletes itself.
diff --git a/chromium/net/http/http_response_headers.cc b/chromium/net/http/http_response_headers.cc
index c535e0ab64e..ba51cfdbc57 100644
--- a/chromium/net/http/http_response_headers.cc
+++ b/chromium/net/http/http_response_headers.cc
@@ -10,6 +10,7 @@
#include "net/http/http_response_headers.h"
#include <algorithm>
+#include <utility>
#include "base/format_macros.h"
#include "base/logging.h"
@@ -361,10 +362,9 @@ void HttpResponseHeaders::ReplaceStatusLine(const std::string& new_status) {
MergeWithHeaders(new_raw_headers, empty_to_remove);
}
-void HttpResponseHeaders::UpdateWithNewRange(
- const HttpByteRange& byte_range,
- int64 resource_size,
- bool replace_status_line) {
+void HttpResponseHeaders::UpdateWithNewRange(const HttpByteRange& byte_range,
+ int64_t resource_size,
+ bool replace_status_line) {
DCHECK(byte_range.IsValid());
DCHECK(byte_range.HasFirstBytePosition());
DCHECK(byte_range.HasLastBytePosition());
@@ -375,9 +375,9 @@ void HttpResponseHeaders::UpdateWithNewRange(
RemoveHeader(kLengthHeader);
RemoveHeader(kRangeHeader);
- int64 start = byte_range.first_byte_position();
- int64 end = byte_range.last_byte_position();
- int64 range_len = end - start + 1;
+ int64_t start = byte_range.first_byte_position();
+ int64_t end = byte_range.last_byte_position();
+ int64_t range_len = end - start + 1;
if (replace_status_line)
ReplaceStatusLine("HTTP/1.1 206 Partial Content");
@@ -530,12 +530,22 @@ std::string HttpResponseHeaders::GetStatusLine() const {
std::string HttpResponseHeaders::GetStatusText() const {
// GetStatusLine() is already normalized, so it has the format:
- // <http_version> SP <response_code> SP <status_text>
+ // '<http_version> SP <response_code>' or
+ // '<http_version> SP <response_code> SP <status_text>'.
std::string status_text = GetStatusLine();
std::string::const_iterator begin = status_text.begin();
std::string::const_iterator end = status_text.end();
- for (int i = 0; i < 2; ++i)
- begin = std::find(begin, end, ' ') + 1;
+ // Seek to beginning of <response_code>.
+ begin = std::find(begin, end, ' ');
+ CHECK(begin != end);
+ ++begin;
+ CHECK(begin != end);
+ // See if there is another space.
+ begin = std::find(begin, end, ' ');
+ if (begin == end)
+ return std::string();
+ ++begin;
+ CHECK(begin != end);
return std::string(begin, end);
}
@@ -649,8 +659,8 @@ HttpVersion HttpResponseHeaders::ParseVersion(
return HttpVersion();
}
- uint16 major = *p - '0';
- uint16 minor = *dot - '0';
+ uint16_t major = *p - '0';
+ uint16_t minor = *dot - '0';
return HttpVersion(major, minor);
}
@@ -662,13 +672,16 @@ void HttpResponseHeaders::ParseStatusLine(
std::string::const_iterator line_end,
bool has_headers) {
// Extract the version number
- parsed_http_version_ = ParseVersion(line_begin, line_end);
+ HttpVersion parsed_http_version = ParseVersion(line_begin, line_end);
- // Clamp the version number to one of: {0.9, 1.0, 1.1}
- if (parsed_http_version_ == HttpVersion(0, 9) && !has_headers) {
+ // Clamp the version number to one of: {0.9, 1.0, 1.1, 2.0}
+ if (parsed_http_version == HttpVersion(0, 9) && !has_headers) {
http_version_ = HttpVersion(0, 9);
raw_headers_ = "HTTP/0.9";
- } else if (parsed_http_version_ >= HttpVersion(1, 1)) {
+ } else if (parsed_http_version == HttpVersion(2, 0)) {
+ http_version_ = HttpVersion(2, 0);
+ raw_headers_ = "HTTP/2.0";
+ } else if (parsed_http_version >= HttpVersion(1, 1)) {
http_version_ = HttpVersion(1, 1);
raw_headers_ = "HTTP/1.1";
} else {
@@ -676,7 +689,7 @@ void HttpResponseHeaders::ParseStatusLine(
http_version_ = HttpVersion(1, 0);
raw_headers_ = "HTTP/1.0";
}
- if (parsed_http_version_ != http_version_) {
+ if (parsed_http_version != http_version_) {
DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "."
<< http_version_.minor_value();
}
@@ -692,40 +705,36 @@ void HttpResponseHeaders::ParseStatusLine(
}
// Skip whitespace.
- while (*p == ' ')
+ while (p < line_end && *p == ' ')
++p;
std::string::const_iterator code = p;
- while (*p >= '0' && *p <= '9')
+ while (p < line_end && *p >= '0' && *p <= '9')
++p;
if (p == code) {
DVLOG(1) << "missing response status number; assuming 200";
- raw_headers_.append(" 200 OK");
+ raw_headers_.append(" 200");
response_code_ = 200;
return;
}
raw_headers_.push_back(' ');
raw_headers_.append(code, p);
- raw_headers_.push_back(' ');
base::StringToInt(StringPiece(code, p), &response_code_);
// Skip whitespace.
- while (*p == ' ')
+ while (p < line_end && *p == ' ')
++p;
// Trim trailing whitespace.
while (line_end > p && line_end[-1] == ' ')
--line_end;
- if (p == line_end) {
- DVLOG(1) << "missing response status text; assuming OK";
- // Not super critical what we put here. Just use "OK"
- // even if it isn't descriptive of response_code_.
- raw_headers_.append("OK");
- } else {
- raw_headers_.append(p, line_end);
- }
+ if (p == line_end)
+ return;
+
+ raw_headers_.push_back(' ');
+ raw_headers_.append(p, line_end);
}
size_t HttpResponseHeaders::FindHeader(size_t from,
@@ -754,7 +763,7 @@ bool HttpResponseHeaders::GetCacheControlDirective(const StringPiece& directive,
base::StartsWith(value, directive,
base::CompareCase::INSENSITIVE_ASCII) &&
value[directive_size] == '=') {
- int64 seconds;
+ int64_t seconds;
base::StringToInt64(
StringPiece(value.begin() + directive_size + 1, value.end()),
&seconds);
@@ -1146,7 +1155,7 @@ bool HttpResponseHeaders::GetAgeValue(TimeDelta* result) const {
if (!EnumerateHeader(NULL, "Age", &value))
return false;
- int64 seconds;
+ int64_t seconds;
base::StringToInt64(value, &seconds);
*result = TimeDelta::FromSeconds(seconds);
return true;
@@ -1241,11 +1250,11 @@ bool HttpResponseHeaders::HasStrongValidators() const {
// From RFC 2616:
// Content-Length = "Content-Length" ":" 1*DIGIT
-int64 HttpResponseHeaders::GetContentLength() const {
+int64_t HttpResponseHeaders::GetContentLength() const {
return GetInt64HeaderValue("content-length");
}
-int64 HttpResponseHeaders::GetInt64HeaderValue(
+int64_t HttpResponseHeaders::GetInt64HeaderValue(
const std::string& header) const {
void* iter = NULL;
std::string content_length_val;
@@ -1258,7 +1267,7 @@ int64 HttpResponseHeaders::GetInt64HeaderValue(
if (content_length_val[0] == '+')
return -1;
- int64 result;
+ int64_t result;
bool ok = base::StringToInt64(content_length_val, &result);
if (!ok || result < 0)
return -1;
@@ -1272,9 +1281,9 @@ int64 HttpResponseHeaders::GetInt64HeaderValue(
// byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*"
// instance-length = 1*DIGIT
// bytes-unit = "bytes"
-bool HttpResponseHeaders::GetContentRange(int64* first_byte_position,
- int64* last_byte_position,
- int64* instance_length) const {
+bool HttpResponseHeaders::GetContentRange(int64_t* first_byte_position,
+ int64_t* last_byte_position,
+ int64_t* instance_length) const {
void* iter = NULL;
std::string content_range_spec;
*first_byte_position = *last_byte_position = *instance_length = -1;
@@ -1399,7 +1408,7 @@ scoped_ptr<base::Value> HttpResponseHeaders::NetLogCallback(
escaped_value.c_str())));
}
dict->Set("headers", headers);
- return dict.Pass();
+ return std::move(dict);
}
// static
diff --git a/chromium/net/http/http_response_headers.h b/chromium/net/http/http_response_headers.h
index 3d8e656cfbf..91c223ebe81 100644
--- a/chromium/net/http/http_response_headers.h
+++ b/chromium/net/http/http_response_headers.h
@@ -5,11 +5,14 @@
#ifndef NET_HTTP_HTTP_RESPONSE_HEADERS_H_
#define NET_HTTP_HTTP_RESPONSE_HEADERS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -104,12 +107,12 @@ class NET_EXPORT HttpResponseHeaders
// |byte_range| must have a valid, bounded range (i.e. coming from a valid
// response or should be usable for a response).
void UpdateWithNewRange(const HttpByteRange& byte_range,
- int64 resource_size,
+ int64_t resource_size,
bool replace_status_line);
// Creates a normalized header string. The output will be formatted exactly
// like so:
- // HTTP/<version> <status_code> <status_text>\n
+ // HTTP/<version> <status_code>[ <status_text>]\n
// [<header-name>: <header-values>\n]*
// meaning, each line is \n-terminated, and there is no extra whitespace
// beyond the single space separators shown (of course, values can contain
@@ -143,9 +146,7 @@ class NET_EXPORT HttpResponseHeaders
//
bool GetNormalizedHeader(const std::string& name, std::string* value) const;
- // Returns the normalized status line. For HTTP/0.9 responses (i.e.,
- // responses that lack a status line), this is the manufactured string
- // "HTTP/0.9 200 OK".
+ // Returns the normalized status line.
std::string GetStatusLine() const;
// Get the HTTP version of the normalized status line.
@@ -153,11 +154,6 @@ class NET_EXPORT HttpResponseHeaders
return http_version_;
}
- // Get the HTTP version determined while parsing; or (0,0) if parsing failed
- HttpVersion GetParsedHttpVersion() const {
- return parsed_http_version_;
- }
-
// Get the HTTP status text of the normalized status line.
std::string GetStatusText() const;
@@ -264,11 +260,11 @@ class NET_EXPORT HttpResponseHeaders
// Extracts the value of the Content-Length header or returns -1 if there is
// no such header in the response.
- int64 GetContentLength() const;
+ int64_t GetContentLength() const;
// Extracts the value of the specified header or returns -1 if there is no
// such header in the response.
- int64 GetInt64HeaderValue(const std::string& header) const;
+ int64_t GetInt64HeaderValue(const std::string& header) const;
// Extracts the values in a Content-Range header and returns true if they are
// valid for a 206 response; otherwise returns false.
@@ -277,9 +273,9 @@ class NET_EXPORT HttpResponseHeaders
// |*last_byte_position| = inclusive position of the last byte of the range
// |*instance_length| = size in bytes of the object requested
// If any of the above values is unknown, its value will be -1.
- bool GetContentRange(int64* first_byte_position,
- int64* last_byte_position,
- int64* instance_length) const;
+ bool GetContentRange(int64_t* first_byte_position,
+ int64_t* last_byte_position,
+ int64_t* instance_length) const;
// Returns true if the response is chunk-encoded.
bool IsChunkEncoded() const;
@@ -406,9 +402,6 @@ class NET_EXPORT HttpResponseHeaders
// The normalized http version (consistent with what GetStatusLine() returns).
HttpVersion http_version_;
- // The parsed http version number (not normalized).
- HttpVersion parsed_http_version_;
-
DISALLOW_COPY_AND_ASSIGN(HttpResponseHeaders);
};
diff --git a/chromium/net/http/http_response_headers_unittest.cc b/chromium/net/http/http_response_headers_unittest.cc
index 35a63608c05..1bc99bbd7b8 100644
--- a/chromium/net/http/http_response_headers_unittest.cc
+++ b/chromium/net/http/http_response_headers_unittest.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <algorithm>
#include <iostream>
#include <limits>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
#include "base/time/time.h"
@@ -22,9 +23,9 @@ namespace {
struct TestData {
const char* raw_headers;
const char* expected_headers;
- int expected_response_code;
- HttpVersion expected_parsed_version;
HttpVersion expected_version;
+ int expected_response_code;
+ const char* expected_status_text;
};
class HttpResponseHeadersTest : public testing::Test {
@@ -110,15 +111,13 @@ TEST_P(CommonHttpResponseHeadersTest, TestCommon) {
EXPECT_EQ(expected_headers, headers);
- EXPECT_EQ(test.expected_response_code, parsed->response_code());
-
- EXPECT_TRUE(test.expected_parsed_version == parsed->GetParsedHttpVersion());
EXPECT_TRUE(test.expected_version == parsed->GetHttpVersion());
+ EXPECT_EQ(test.expected_response_code, parsed->response_code());
+ EXPECT_EQ(test.expected_status_text, parsed->GetStatusText());
}
TestData response_headers_tests[] = {
- {// Normalise whitespace.
-
+ {// Normalize whitespace.
"HTTP/1.1 202 Accepted \n"
"Content-TYPE : text/html; charset=utf-8 \n"
"Set-Cookie: a \n"
@@ -128,11 +127,8 @@ TestData response_headers_tests[] = {
"Content-TYPE: text/html; charset=utf-8\n"
"Set-Cookie: a, b\n",
- 202,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
+ HttpVersion(1, 1), 202, "Accepted"},
{// Normalize leading whitespace.
-
"HTTP/1.1 202 Accepted \n"
// Starts with space -- will be skipped as invalid.
" Content-TYPE : text/html; charset=utf-8 \n"
@@ -142,11 +138,14 @@ TestData response_headers_tests[] = {
"HTTP/1.1 202 Accepted\n"
"Set-Cookie: a, b\n",
- 202,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
- {// Normalize blank headers.
+ HttpVersion(1, 1), 202, "Accepted"},
+ {// Keep whitespace within status text.
+ "HTTP/1.0 404 Not found \n",
+
+ "HTTP/1.0 404 Not found\n",
+ HttpVersion(1, 0), 404, "Not found"},
+ {// Normalize blank headers.
"HTTP/1.1 200 OK\n"
"Header1 : \n"
"Header2: \n"
@@ -160,73 +159,58 @@ TestData response_headers_tests[] = {
"Header3: \n"
"Header5: \n",
- 200,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
+ HttpVersion(1, 1), 200, "OK"},
{// Don't believe the http/0.9 version if there are headers!
-
"hTtP/0.9 201\n"
"Content-TYPE: text/html; charset=utf-8\n",
- "HTTP/1.0 201 OK\n"
+ "HTTP/1.0 201\n"
"Content-TYPE: text/html; charset=utf-8\n",
- 201,
- HttpVersion(0, 9),
- HttpVersion(1, 0)},
+ HttpVersion(1, 0), 201, ""},
{// Accept the HTTP/0.9 version number if there are no headers.
// This is how HTTP/0.9 responses get constructed from
// HttpNetworkTransaction.
-
"hTtP/0.9 200 OK\n",
"HTTP/0.9 200 OK\n",
- 200,
- HttpVersion(0, 9),
- HttpVersion(0, 9)},
- {// Add missing OK.
-
+ HttpVersion(0, 9), 200, "OK"},
+ {// Do not add missing status text.
"HTTP/1.1 201\n"
"Content-TYPE: text/html; charset=utf-8\n",
- "HTTP/1.1 201 OK\n"
+ "HTTP/1.1 201\n"
"Content-TYPE: text/html; charset=utf-8\n",
- 201,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
+ HttpVersion(1, 1), 201, ""},
{// Normalize bad status line.
-
"SCREWED_UP_STATUS_LINE\n"
"Content-TYPE: text/html; charset=utf-8\n",
"HTTP/1.0 200 OK\n"
"Content-TYPE: text/html; charset=utf-8\n",
- 200,
- HttpVersion(0, 0), // Parse error.
- HttpVersion(1, 0)},
- {// Normalize invalid status code.
+ HttpVersion(1, 0), 200, "OK"},
+ {// Normalize bad status line.
+ "Foo bar.",
+
+ "HTTP/1.0 200\n",
+ HttpVersion(1, 0), 200, ""},
+ {// Normalize invalid status code.
"HTTP/1.1 -1 Unknown\n",
- "HTTP/1.1 200 OK\n",
+ "HTTP/1.1 200\n",
- 200,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
+ HttpVersion(1, 1), 200, ""},
{// Normalize empty header.
-
"",
"HTTP/1.0 200 OK\n",
- 200,
- HttpVersion(0, 0), // Parse Error.
- HttpVersion(1, 0)},
+ HttpVersion(1, 0), 200, "OK"},
{// Normalize headers that start with a colon.
-
"HTTP/1.1 202 Accepted \n"
"foo: bar\n"
": a \n"
@@ -237,11 +221,8 @@ TestData response_headers_tests[] = {
"foo: bar\n"
"baz: blat\n",
- 202,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
+ HttpVersion(1, 1), 202, "Accepted"},
{// Normalize headers that end with a colon.
-
"HTTP/1.1 202 Accepted \n"
"foo: \n"
"bar:\n"
@@ -254,20 +235,14 @@ TestData response_headers_tests[] = {
"baz: blat\n"
"zip: \n",
- 202,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
+ HttpVersion(1, 1), 202, "Accepted"},
{// Normalize whitespace headers.
-
"\n \n",
"HTTP/1.0 200 OK\n",
- 200,
- HttpVersion(0, 0), // Parse error.
- HttpVersion(1, 0)},
+ HttpVersion(1, 0), 200, "OK"},
{// Consolidate Set-Cookie headers.
-
"HTTP/1.1 200 OK\n"
"Set-Cookie: x=1\n"
"Set-Cookie: y=2\n",
@@ -275,28 +250,22 @@ TestData response_headers_tests[] = {
"HTTP/1.1 200 OK\n"
"Set-Cookie: x=1, y=2\n",
- 200,
- HttpVersion(1, 1),
- HttpVersion(1, 1)},
+ HttpVersion(1, 1), 200, "OK"},
+ {// Consolidate cache-control headers.
+ "HTTP/1.1 200 OK\n"
+ "Cache-control: private\n"
+ "cache-Control: no-store\n",
+
+ "HTTP/1.1 200 OK\n"
+ "Cache-control: private, no-store\n",
+
+ HttpVersion(1, 1), 200, "OK"},
};
INSTANTIATE_TEST_CASE_P(HttpResponseHeaders,
CommonHttpResponseHeadersTest,
testing::ValuesIn(response_headers_tests));
-TEST(HttpResponseHeadersTest, GetNormalizedHeader) {
- std::string headers =
- "HTTP/1.1 200 OK\n"
- "Cache-control: private\n"
- "cache-Control: no-store\n";
- HeadersToRaw(&headers);
- scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers));
-
- std::string value;
- EXPECT_TRUE(parsed->GetNormalizedHeader("cache-control", &value));
- EXPECT_EQ("private, no-store", value);
-}
-
struct PersistData {
HttpResponseHeaders::PersistOptions options;
const char* raw_headers;
@@ -1214,7 +1183,7 @@ INSTANTIATE_TEST_CASE_P(HttpResponseHeaders,
struct ContentLengthTestData {
const char* headers;
- int64 expected_len;
+ int64_t expected_len;
};
class GetContentLengthTest
@@ -1233,74 +1202,56 @@ TEST_P(GetContentLengthTest, GetContentLength) {
}
const ContentLengthTestData content_length_tests[] = {
- { "HTTP/1.1 200 OK\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 10\n",
- 10
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: \n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: abc\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: -10\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: +10\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 23xb5\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 0xA\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 010\n",
- 10
- },
- // Content-Length too big, will overflow an int64.
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 40000000000000000000\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 10\n",
- 10
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 10 \n",
- 10
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: \t10\n",
- 10
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: \v10\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: \f10\n",
- -1
- },
- { "HTTP/1.1 200 OK\n"
- "cOnTeNt-LENgth: 33\n",
- 33
- },
- { "HTTP/1.1 200 OK\n"
- "Content-Length: 34\r\n",
- -1
- },
+ {"HTTP/1.1 200 OK\n", -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 10\n",
+ 10},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: \n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: abc\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: -10\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: +10\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 23xb5\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 0xA\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 010\n",
+ 10},
+ // Content-Length too big, will overflow an int64_t.
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 40000000000000000000\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 10\n",
+ 10},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 10 \n",
+ 10},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: \t10\n",
+ 10},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: \v10\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: \f10\n",
+ -1},
+ {"HTTP/1.1 200 OK\n"
+ "cOnTeNt-LENgth: 33\n",
+ 33},
+ {"HTTP/1.1 200 OK\n"
+ "Content-Length: 34\r\n",
+ -1},
};
INSTANTIATE_TEST_CASE_P(HttpResponseHeaders,
@@ -1310,9 +1261,9 @@ INSTANTIATE_TEST_CASE_P(HttpResponseHeaders,
struct ContentRangeTestData {
const char* headers;
bool expected_return_value;
- int64 expected_first_byte_position;
- int64 expected_last_byte_position;
- int64 expected_instance_size;
+ int64_t expected_first_byte_position;
+ int64_t expected_last_byte_position;
+ int64_t expected_instance_size;
};
class ContentRangeTest
@@ -1327,9 +1278,9 @@ TEST_P(ContentRangeTest, GetContentRange) {
HeadersToRaw(&headers);
scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers));
- int64 first_byte_position;
- int64 last_byte_position;
- int64 instance_size;
+ int64_t first_byte_position;
+ int64_t last_byte_position;
+ int64_t instance_size;
bool return_value = parsed->GetContentRange(&first_byte_position,
&last_byte_position,
&instance_size);
@@ -1340,238 +1291,105 @@ TEST_P(ContentRangeTest, GetContentRange) {
}
const ContentRangeTestData content_range_tests[] = {
- { "HTTP/1.1 206 Partial Content",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range:",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: megabytes 0-10/50",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: 0-10/50",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: Bytes 0-50/51",
- true,
- 0,
- 50,
- 51
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-50/51",
- true,
- 0,
- 50,
- 51
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes\t0-50/51",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-50/51",
- true,
- 0,
- 50,
- 51
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0 - 50 \t / \t51",
- true,
- 0,
- 50,
- 51
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0\t-\t50\t/\t51\t",
- true,
- 0,
- 50,
- 51
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: \tbytes\t\t\t 0\t-\t50\t/\t51\t",
- true,
- 0,
- 50,
- 51
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: \t bytes \t 0 - 50 / 5 1",
- false,
- 0,
- 50,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: \t bytes \t 0 - 5 0 / 51",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 50-0/51",
- false,
- 50,
- 0,
- -1
- },
- { "HTTP/1.1 416 Requested range not satisfiable\n"
- "Content-Range: bytes * /*",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 416 Requested range not satisfiable\n"
- "Content-Range: bytes * / * ",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-50/*",
- false,
- 0,
- 50,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-50 / * ",
- false,
- 0,
- 50,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-10000000000/10000000001",
- true,
- 0,
- 10000000000ll,
- 10000000001ll
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-10000000000/10000000000",
- false,
- 0,
- 10000000000ll,
- 10000000000ll
- },
- // 64 bit wraparound.
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0 - 9223372036854775807 / 100",
- false,
- 0,
- kint64max,
- 100
- },
- // 64 bit wraparound.
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0 - 100 / -9223372036854775808",
- false,
- 0,
- 100,
- kint64min
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes */50",
- false,
- -1,
- -1,
- 50
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-50/10",
- false,
- 0,
- 50,
- 10
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 40-50/45",
- false,
- 40,
- 50,
- 45
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-50/-10",
- false,
- 0,
- 50,
- -10
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-0/1",
- true,
- 0,
- 0,
- 1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-40000000000000000000/40000000000000000001",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 1-/100",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes -/100",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes -1/100",
- false,
- -1,
- -1,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0-1233/*",
- false,
- 0,
- 1233,
- -1
- },
- { "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes -123 - -1/100",
- false,
- -1,
- -1,
- -1
- },
+ {"HTTP/1.1 206 Partial Content", false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range:",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: megabytes 0-10/50",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: 0-10/50",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: Bytes 0-50/51",
+ true, 0, 50, 51},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-50/51",
+ true, 0, 50, 51},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes\t0-50/51",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-50/51",
+ true, 0, 50, 51},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0 - 50 \t / \t51",
+ true, 0, 50, 51},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0\t-\t50\t/\t51\t",
+ true, 0, 50, 51},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: \tbytes\t\t\t 0\t-\t50\t/\t51\t",
+ true, 0, 50, 51},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: \t bytes \t 0 - 50 / 5 1",
+ false, 0, 50, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: \t bytes \t 0 - 5 0 / 51",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 50-0/51",
+ false, 50, 0, -1},
+ {"HTTP/1.1 416 Requested range not satisfiable\n"
+ "Content-Range: bytes * /*",
+ false, -1, -1, -1},
+ {"HTTP/1.1 416 Requested range not satisfiable\n"
+ "Content-Range: bytes * / * ",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-50/*",
+ false, 0, 50, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-50 / * ",
+ false, 0, 50, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-10000000000/10000000001",
+ true, 0, 10000000000ll, 10000000001ll},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-10000000000/10000000000",
+ false, 0, 10000000000ll, 10000000000ll},
+ // 64 bit wraparound.
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0 - 9223372036854775807 / 100",
+ false, 0, std::numeric_limits<int64_t>::max(), 100},
+ // 64 bit wraparound.
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0 - 100 / -9223372036854775808",
+ false, 0, 100, std::numeric_limits<int64_t>::min()},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes */50",
+ false, -1, -1, 50},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-50/10",
+ false, 0, 50, 10},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 40-50/45",
+ false, 40, 50, 45},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-50/-10",
+ false, 0, 50, -10},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-0/1",
+ true, 0, 0, 1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-40000000000000000000/40000000000000000001",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 1-/100",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes -/100",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes -1/100",
+ false, -1, -1, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-1233/*",
+ false, 0, 1233, -1},
+ {"HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes -123 - -1/100",
+ false, -1, -1, -1},
};
INSTANTIATE_TEST_CASE_P(HttpResponseHeaders,
@@ -1816,37 +1634,6 @@ INSTANTIATE_TEST_CASE_P(HttpResponseHeaders,
HasStrongValidatorsTest,
testing::ValuesIn(strong_validators_tests));
-TEST(HttpResponseHeadersTest, GetStatusText) {
- std::string headers("HTTP/1.1 404 Not Found");
- HeadersToRaw(&headers);
- scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers));
- EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText());
-}
-
-TEST(HttpResponseHeadersTest, GetStatusTextMissing) {
- std::string headers("HTTP/1.1 404");
- HeadersToRaw(&headers);
- scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers));
- // Since the status line gets normalized, we have OK.
- EXPECT_EQ(std::string("OK"), parsed->GetStatusText());
-}
-
-TEST(HttpResponseHeadersTest, GetStatusTextMultiSpace) {
- std::string headers("HTTP/1.0 404 Not Found");
- HeadersToRaw(&headers);
- scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers));
- EXPECT_EQ(std::string("Not Found"), parsed->GetStatusText());
-}
-
-TEST(HttpResponseHeadersTest, GetStatusBadStatusLine) {
- std::string headers("Foo bar.");
- HeadersToRaw(&headers);
- scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers));
- // The bad status line would have gotten rewritten as
- // HTTP/1.0 200 OK.
- EXPECT_EQ(std::string("OK"), parsed->GetStatusText());
-}
-
struct AddHeaderTestData {
const char* orig_headers;
const char* new_header;
@@ -2150,7 +1937,7 @@ TEST_P(UpdateWithNewRangeTest, UpdateWithNewRange) {
std::replace(orig_headers.begin(), orig_headers.end(), '\n', '\0');
scoped_refptr<HttpResponseHeaders> parsed(
new HttpResponseHeaders(orig_headers + '\0'));
- int64 content_size = parsed->GetContentLength();
+ int64_t content_size = parsed->GetContentLength();
std::string resulting_headers;
// Update headers without replacing status line.
@@ -2260,7 +2047,7 @@ TEST_F(HttpResponseHeadersCacheControlTest, MaxAgeCaseInsensitive) {
struct MaxAgeTestData {
const char* max_age_string;
- const int64 expected_seconds;
+ const int64_t expected_seconds;
};
class MaxAgeEdgeCasesTest
@@ -2279,22 +2066,22 @@ TEST_P(MaxAgeEdgeCasesTest, MaxAgeEdgeCases) {
}
const MaxAgeTestData max_age_tests[] = {
- {" 1 ", 1}, // Spaces are ignored.
- {"-1", -1}, // Negative numbers are passed through.
- {"--1", 0}, // Leading junk gives 0.
- {"2s", 2}, // Trailing junk is ignored.
- {"3 days", 3},
- {"'4'", 0}, // Single quotes don't work.
- {"\"5\"", 0}, // Double quotes don't work.
- {"0x6", 0}, // Hex not parsed as hex.
- {"7F", 7}, // Hex without 0x still not parsed as hex.
- {"010", 10}, // Octal not parsed as octal.
- {"9223372036854", 9223372036854},
- // {"9223372036855", -9223372036854}, // Undefined behaviour.
- // {"9223372036854775806", -2}, // Undefined behaviour.
- {"9223372036854775807", 9223372036854775807},
- {"20000000000000000000",
- std::numeric_limits<int64>::max()}, // Overflow int64.
+ {" 1 ", 1}, // Spaces are ignored.
+ {"-1", -1}, // Negative numbers are passed through.
+ {"--1", 0}, // Leading junk gives 0.
+ {"2s", 2}, // Trailing junk is ignored.
+ {"3 days", 3},
+ {"'4'", 0}, // Single quotes don't work.
+ {"\"5\"", 0}, // Double quotes don't work.
+ {"0x6", 0}, // Hex not parsed as hex.
+ {"7F", 7}, // Hex without 0x still not parsed as hex.
+ {"010", 10}, // Octal not parsed as octal.
+ {"9223372036854", 9223372036854},
+ // {"9223372036855", -9223372036854}, // Undefined behaviour.
+ // {"9223372036854775806", -2}, // Undefined behaviour.
+ {"9223372036854775807", 9223372036854775807},
+ {"20000000000000000000",
+ std::numeric_limits<int64_t>::max()}, // Overflow int64_t.
};
INSTANTIATE_TEST_CASE_P(HttpResponseHeadersCacheControl,
diff --git a/chromium/net/http/http_response_info.cc b/chromium/net/http/http_response_info.cc
index fa9d63cccb4..fe6e57e56e1 100644
--- a/chromium/net/http/http_response_info.cc
+++ b/chromium/net/http/http_response_info.cc
@@ -179,7 +179,7 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
}
// Read request-time
- int64 time_val;
+ int64_t time_val;
if (!iter.ReadInt64(&time_val))
return false;
request_time = Time::FromInternalValue(time_val);
@@ -229,7 +229,7 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
for (int i = 0; i < num_scts; ++i) {
scoped_refptr<ct::SignedCertificateTimestamp> sct(
ct::SignedCertificateTimestamp::CreateFromPickle(&iter));
- uint16 status;
+ uint16_t status;
if (!sct.get() || !iter.ReadUInt16(&status))
return false;
ssl_info.signed_certificate_timestamps.push_back(
@@ -248,7 +248,7 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
std::string socket_address_host;
if (iter.ReadString(&socket_address_host)) {
// If the host was written, we always expect the port to follow.
- uint16 socket_address_port;
+ uint16_t socket_address_port;
if (!iter.ReadUInt16(&socket_address_port))
return false;
socket_address = HostPortPair(socket_address_host, socket_address_port);
@@ -365,7 +365,7 @@ void HttpResponseInfo::Persist(base::Pickle* pickle,
ssl_info.signed_certificate_timestamps.begin(); it !=
ssl_info.signed_certificate_timestamps.end(); ++it) {
it->sct->Persist(pickle);
- pickle->WriteUInt16(static_cast<uint16>(it->status));
+ pickle->WriteUInt16(static_cast<uint16_t>(it->status));
}
}
}
@@ -389,9 +389,6 @@ void HttpResponseInfo::Persist(base::Pickle* pickle,
HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto(
NextProto next_proto) {
switch (next_proto) {
- case kProtoDeprecatedSPDY2:
- return CONNECTION_INFO_DEPRECATED_SPDY2;
- case kProtoSPDY3:
case kProtoSPDY31:
return CONNECTION_INFO_SPDY3;
case kProtoHTTP2:
@@ -417,7 +414,8 @@ std::string HttpResponseInfo::ConnectionInfoToString(
case CONNECTION_INFO_HTTP1:
return "http/1";
case CONNECTION_INFO_DEPRECATED_SPDY2:
- return "spdy/2";
+ NOTREACHED();
+ return "";
case CONNECTION_INFO_SPDY3:
return "spdy/3";
// Since ConnectionInfo is persisted to disk, deprecated values have to be
diff --git a/chromium/net/http/http_response_info.h b/chromium/net/http/http_response_info.h
index dd1b3da351e..2dce1a1de07 100644
--- a/chromium/net/http/http_response_info.h
+++ b/chromium/net/http/http_response_info.h
@@ -29,11 +29,9 @@ class NET_EXPORT HttpResponseInfo {
public:
// Describes the kind of connection used to fetch this response.
//
- // NOTE: This is persisted to the cache, so make sure not to reorder
- // these values.
- //
- // TODO(akalin): Better yet, just use a string instead of an enum,
- // like |npn_negotiated_protocol|.
+ // NOTE: Please keep in sync with Net.HttpResponseInfo.ConnectionInfo
+ // histogram. Because of that, and also because these values are persisted to
+ // the cache, please make sure not to delete or reorder values.
enum ConnectionInfo {
CONNECTION_INFO_UNKNOWN = 0,
CONNECTION_INFO_HTTP1 = 1,
diff --git a/chromium/net/http/http_security_headers.cc b/chromium/net/http/http_security_headers.cc
index b99b206c3f3..ecb8e57d2b3 100644
--- a/chromium/net/http/http_security_headers.cc
+++ b/chromium/net/http/http_security_headers.cc
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <limits>
+
#include "base/base64.h"
-#include "base/basictypes.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
@@ -18,36 +19,36 @@ namespace {
enum MaxAgeParsing { REQUIRE_MAX_AGE, DO_NOT_REQUIRE_MAX_AGE };
-static_assert(kMaxHSTSAgeSecs <= kuint32max, "kMaxHSTSAgeSecs too large");
+static_assert(kMaxHSTSAgeSecs <= UINT32_MAX, "kMaxHSTSAgeSecs too large");
// MaxAgeToInt converts a string representation of a "whole number" of
-// seconds into a uint32. The string may contain an arbitrarily large number,
+// seconds into a uint32_t. The string may contain an arbitrarily large number,
// which will be clipped to kMaxHSTSAgeSecs and which is guaranteed to fit
// within a 32-bit unsigned integer. False is returned on any parse error.
bool MaxAgeToInt(std::string::const_iterator begin,
std::string::const_iterator end,
- uint32* result) {
+ uint32_t* result) {
const base::StringPiece s(begin, end);
if (s.empty())
return false;
- int64 i = 0;
-
- // Return false on any StringToInt64 parse errors *except* for
- // int64 overflow. StringToInt64 is used, rather than StringToUint64,
- // in order to properly handle and reject negative numbers
- // (StringToUint64 does not return false on negative numbers).
- // For values too large to be stored in an int64, StringToInt64 will
- // return false with i set to kint64max, so this case is detected
- // by the immediately following if-statement and allowed to fall
- // through so that i gets clipped to kMaxHSTSAgeSecs.
- if (!base::StringToInt64(s, &i) && i != kint64max)
+ int64_t i = 0;
+
+ // Return false on any StringToInt64 parse errors *except* for int64_t
+ // overflow. StringToInt64 is used, rather than StringToUint64, in order to
+ // properly handle and reject negative numbers (StringToUint64 does not return
+ // false on negative numbers). For values too large to be stored in an
+ // int64_t, StringToInt64 will return false with i set to
+ // std::numeric_limits<int64_t>::max(), so this case is detected by the
+ // immediately following if-statement and allowed to fall through so that i
+ // gets clipped to kMaxHSTSAgeSecs.
+ if (!base::StringToInt64(s, &i) && i != std::numeric_limits<int64_t>::max())
return false;
if (i < 0)
return false;
if (i > kMaxHSTSAgeSecs)
i = kMaxHSTSAgeSecs;
- *result = (uint32)i;
+ *result = (uint32_t)i;
return true;
}
@@ -128,7 +129,7 @@ bool ParseHPKPHeaderImpl(const std::string& value,
GURL* report_uri) {
bool parsed_max_age = false;
bool include_subdomains_candidate = false;
- uint32 max_age_candidate = 0;
+ uint32_t max_age_candidate = 0;
GURL parsed_report_uri;
HashValueVector pins;
bool require_max_age = max_age_status == REQUIRE_MAX_AGE;
@@ -224,7 +225,7 @@ bool ParseHPKPHeaderImpl(const std::string& value,
bool ParseHSTSHeader(const std::string& value,
base::TimeDelta* max_age,
bool* include_subdomains) {
- uint32 max_age_candidate = 0;
+ uint32_t max_age_candidate = 0;
bool include_subdomains_candidate = false;
// We must see max-age exactly once.
diff --git a/chromium/net/http/http_security_headers.h b/chromium/net/http/http_security_headers.h
index f54df691fae..af904307870 100644
--- a/chromium/net/http/http_security_headers.h
+++ b/chromium/net/http/http_security_headers.h
@@ -5,9 +5,10 @@
#ifndef NET_HTTP_HTTP_SECURITY_HEADERS_H_
#define NET_HTTP_HTTP_SECURITY_HEADERS_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/hash_value.h"
@@ -17,7 +18,7 @@ class GURL;
namespace net {
-const int64 kMaxHSTSAgeSecs = 86400 * 365; // 1 year
+const int64_t kMaxHSTSAgeSecs = 86400 * 365; // 1 year
// Parses |value| as a Strict-Transport-Security header value. If successful,
// returns true and sets |*max_age| and |*include_subdomains|.
diff --git a/chromium/net/http/http_security_headers_unittest.cc b/chromium/net/http/http_security_headers_unittest.cc
index 4a510f2f11d..9c0997217b3 100644
--- a/chromium/net/http/http_security_headers_unittest.cc
+++ b/chromium/net/http/http_security_headers_unittest.cc
@@ -21,13 +21,13 @@ namespace net {
namespace {
-HashValue GetTestHashValue(uint8 label, HashValueTag tag) {
+HashValue GetTestHashValue(uint8_t label, HashValueTag tag) {
HashValue hash_value(tag);
memset(hash_value.data(), label, hash_value.size());
return hash_value;
}
-std::string GetTestPinImpl(uint8 label, HashValueTag tag, bool quoted) {
+std::string GetTestPinImpl(uint8_t label, HashValueTag tag, bool quoted) {
HashValue hash_value = GetTestHashValue(label, tag);
std::string base64;
base::Base64Encode(base::StringPiece(
@@ -50,11 +50,11 @@ std::string GetTestPinImpl(uint8 label, HashValueTag tag, bool quoted) {
return ret;
}
-std::string GetTestPin(uint8 label, HashValueTag tag) {
+std::string GetTestPin(uint8_t label, HashValueTag tag) {
return GetTestPinImpl(label, tag, true);
}
-std::string GetTestPinUnquoted(uint8 label, HashValueTag tag) {
+std::string GetTestPinUnquoted(uint8_t label, HashValueTag tag) {
return GetTestPinImpl(label, tag, false);
}
@@ -389,7 +389,7 @@ TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
"max-age=39408299 ;incLudesUbdOmains", &max_age,
&include_subdomains));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(39408299))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(39408299))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
@@ -397,7 +397,7 @@ TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
"max-age=394082038 ; incLudesUbdOmains", &max_age,
&include_subdomains));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
@@ -405,7 +405,7 @@ TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
"max-age=394082038 ; incLudesUbdOmains;", &max_age,
&include_subdomains));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
@@ -413,7 +413,7 @@ TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
";; max-age=394082038 ; incLudesUbdOmains; ;", &max_age,
&include_subdomains));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
@@ -421,7 +421,7 @@ TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
";; max-age=394082038 ;", &max_age,
&include_subdomains));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
@@ -429,7 +429,7 @@ TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
";; ; ; max-age=394082038;;; includeSubdomains ;; ;", &max_age,
&include_subdomains));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
@@ -437,7 +437,7 @@ TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
"incLudesUbdOmains ; max-age=394082038 ;;", &max_age,
&include_subdomains));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
@@ -530,7 +530,7 @@ static void TestValidPKPHeaders(HashValueTag tag) {
"max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ", chain_hashes,
&max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(39408299))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(39408299))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
@@ -539,7 +539,7 @@ static void TestValidPKPHeaders(HashValueTag tag) {
good_pin + ";" + backup_pin + "; ",
chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(
- std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
+ std::min(kMaxHSTSAgeSecs, static_cast<int64_t>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
diff --git a/chromium/net/http/http_server_properties.cc b/chromium/net/http/http_server_properties.cc
index 1e3ccd234f0..fc6281e43b5 100644
--- a/chromium/net/http/http_server_properties.cc
+++ b/chromium/net/http/http_server_properties.cc
@@ -20,8 +20,6 @@ namespace {
// The order of these strings much match the order of the enum definition
// for AlternateProtocol.
const char* const kAlternateProtocolStrings[] = {
- "npn-spdy/2",
- "npn-spdy/3",
"npn-spdy/3.1",
"npn-h2",
"quic"};
@@ -50,8 +48,6 @@ bool IsAlternateProtocolValid(AlternateProtocol protocol) {
const char* AlternateProtocolToString(AlternateProtocol protocol) {
switch (protocol) {
- case DEPRECATED_NPN_SPDY_2:
- case NPN_SPDY_3:
case NPN_SPDY_3_1:
case NPN_HTTP_2:
case QUIC:
@@ -77,10 +73,6 @@ AlternateProtocol AlternateProtocolFromString(const std::string& str) {
AlternateProtocol AlternateProtocolFromNextProto(NextProto next_proto) {
switch (next_proto) {
- case kProtoDeprecatedSPDY2:
- return DEPRECATED_NPN_SPDY_2;
- case kProtoSPDY3:
- return NPN_SPDY_3;
case kProtoSPDY31:
return NPN_SPDY_3_1;
case kProtoHTTP2:
@@ -103,14 +95,21 @@ std::string AlternativeService::ToString() const {
}
std::string AlternativeServiceInfo::ToString() const {
- return base::StringPrintf("%s, p=%f", alternative_service.ToString().c_str(),
- probability);
+ base::Time::Exploded exploded;
+ expiration.LocalExplode(&exploded);
+ return base::StringPrintf("%s, p=%f, expires %04d-%02d-%02d %02d:%02d:%02d",
+ alternative_service.ToString().c_str(), probability,
+ exploded.year, exploded.month,
+ exploded.day_of_month, exploded.hour,
+ exploded.minute, exploded.second);
}
// static
void HttpServerProperties::ForceHTTP11(SSLConfig* ssl_config) {
- ssl_config->next_protos.clear();
- ssl_config->next_protos.push_back(kProtoHTTP11);
+ ssl_config->alpn_protos.clear();
+ ssl_config->alpn_protos.push_back(kProtoHTTP11);
+ ssl_config->npn_protos.clear();
+ ssl_config->npn_protos.push_back(kProtoHTTP11);
}
} // namespace net
diff --git a/chromium/net/http/http_server_properties.h b/chromium/net/http/http_server_properties.h
index 2e50f5ede71..b8ea59b2c4f 100644
--- a/chromium/net/http/http_server_properties.h
+++ b/chromium/net/http/http_server_properties.h
@@ -5,18 +5,22 @@
#ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_H_
#define NET_HTTP_HTTP_SERVER_PROPERTIES_H_
+#include <stdint.h>
+
#include <map>
#include <string>
+#include <tuple>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/mru_cache.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "net/base/host_port_pair.h"
+#include "net/base/ip_address_number.h"
#include "net/base/net_export.h"
-#include "net/base/net_util.h"
#include "net/quic/quic_bandwidth.h"
+#include "net/quic/quic_server_id.h"
#include "net/socket/next_proto.h"
#include "net/spdy/spdy_framer.h" // TODO(willchan): Reconsider this.
#include "net/spdy/spdy_protocol.h"
@@ -62,12 +66,10 @@ NET_EXPORT void HistogramBrokenAlternateProtocolLocation(
BrokenAlternateProtocolLocation location);
enum AlternateProtocol {
- DEPRECATED_NPN_SPDY_2 = 0,
- ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION = DEPRECATED_NPN_SPDY_2,
- NPN_SPDY_MINIMUM_VERSION = DEPRECATED_NPN_SPDY_2,
- NPN_SPDY_3,
NPN_SPDY_3_1,
- NPN_HTTP_2, // HTTP/2
+ ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION = NPN_SPDY_3_1,
+ NPN_SPDY_MINIMUM_VERSION = NPN_SPDY_3_1,
+ NPN_HTTP_2,
NPN_SPDY_MAXIMUM_VERSION = NPN_HTTP_2,
QUIC,
ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION = QUIC,
@@ -99,7 +101,7 @@ struct NET_EXPORT AlternativeService {
AlternativeService(AlternateProtocol protocol,
const std::string& host,
- uint16 port)
+ uint16_t port)
: protocol(protocol), host(host), port(port) {}
AlternativeService(AlternateProtocol protocol,
@@ -124,18 +126,15 @@ struct NET_EXPORT AlternativeService {
}
bool operator<(const AlternativeService& other) const {
- if (protocol != other.protocol)
- return protocol < other.protocol;
- if (host != other.host)
- return host < other.host;
- return port < other.port;
+ return std::tie(protocol, host, port) <
+ std::tie(other.protocol, other.host, other.port);
}
std::string ToString() const;
AlternateProtocol protocol;
std::string host;
- uint16 port;
+ uint16_t port;
};
struct NET_EXPORT AlternativeServiceInfo {
@@ -150,7 +149,7 @@ struct NET_EXPORT AlternativeServiceInfo {
AlternativeServiceInfo(AlternateProtocol protocol,
const std::string& host,
- uint16 port,
+ uint16_t port,
double probability,
base::Time expiration)
: alternative_service(protocol, host, port),
@@ -213,15 +212,23 @@ typedef base::MRUCache<HostPortPair, AlternativeServiceInfoVector>
AlternativeServiceMap;
typedef base::MRUCache<HostPortPair, SettingsMap> SpdySettingsMap;
typedef base::MRUCache<HostPortPair, ServerNetworkStats> ServerNetworkStatsMap;
+typedef base::MRUCache<QuicServerId, std::string> QuicServerInfoMap;
+
+// Persist 5 QUIC Servers. This is mainly used by cronet.
+const int kMaxQuicServersToPersist = 5;
extern const char kAlternateProtocolHeader[];
extern const char kAlternativeServiceHeader[];
// The interface for setting/retrieving the HTTP server properties.
// Currently, this class manages servers':
-// * SPDY support (based on NPN results)
-// * alternative service support
-// * Spdy Settings (like CWND ID field)
+// * SPDY support (based on NPN results).
+// * alternative service support.
+// * SPDY Settings (like CWND ID field).
+// * QUIC data (like ServerNetworkStats and QuicServerInfo).
+//
+// Embedders must ensure that HttpServerProperites is completely initialized
+// before the first request is issued.
class NET_EXPORT HttpServerProperties {
public:
HttpServerProperties() {}
@@ -335,7 +342,7 @@ class NET_EXPORT HttpServerProperties {
virtual bool SetSpdySetting(const HostPortPair& host_port_pair,
SpdySettingsIds id,
SpdySettingsFlags flags,
- uint32 value) = 0;
+ uint32_t value) = 0;
// Clears all SPDY settings for a host.
virtual void ClearSpdySettings(const HostPortPair& host_port_pair) = 0;
@@ -360,6 +367,25 @@ class NET_EXPORT HttpServerProperties {
virtual const ServerNetworkStatsMap& server_network_stats_map() const = 0;
+ // Save QuicServerInfo (in std::string form) for the given |server_id|.
+ // Returns true if the value has changed otherwise it returns false.
+ virtual bool SetQuicServerInfo(const QuicServerId& server_id,
+ const std::string& server_info) = 0;
+
+ // Get QuicServerInfo (in std::string form) for the given |server_id|.
+ virtual const std::string* GetQuicServerInfo(
+ const QuicServerId& server_id) = 0;
+
+ // Returns all persistent QuicServerInfo objects.
+ virtual const QuicServerInfoMap& quic_server_info_map() const = 0;
+
+ // Returns the number of server configs (QuicServerInfo objects) persisted.
+ virtual size_t max_server_configs_stored_in_properties() const = 0;
+
+ // Sets the number of server configs (QuicServerInfo objects) to be persisted.
+ virtual void SetMaxServerConfigsStoredInProperties(
+ size_t max_server_configs_stored_in_properties) = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(HttpServerProperties);
};
diff --git a/chromium/net/http/http_server_properties_impl.cc b/chromium/net/http/http_server_properties_impl.cc
index 6278f3627bf..662aab64b8d 100644
--- a/chromium/net/http/http_server_properties_impl.cc
+++ b/chromium/net/http/http_server_properties_impl.cc
@@ -5,11 +5,13 @@
#include "net/http/http_server_properties_impl.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
@@ -21,7 +23,7 @@ namespace net {
namespace {
-const uint64 kBrokenAlternativeProtocolDelaySecs = 300;
+const uint64_t kBrokenAlternativeProtocolDelaySecs = 300;
} // namespace
@@ -31,6 +33,8 @@ HttpServerPropertiesImpl::HttpServerPropertiesImpl()
spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT),
server_network_stats_map_(ServerNetworkStatsMap::NO_AUTO_EVICT),
alternative_service_probability_threshold_(1.0),
+ quic_server_info_map_(QuicServerInfoMap::NO_AUTO_EVICT),
+ max_server_configs_stored_in_properties_(kMaxQuicServersToPersist),
weak_ptr_factory_(this) {
canonical_suffixes_.push_back(".c.youtube.com");
canonical_suffixes_.push_back(".googlevideo.com");
@@ -46,62 +50,63 @@ void HttpServerPropertiesImpl::InitializeSpdyServers(
DCHECK(CalledOnValidThread());
if (!spdy_servers)
return;
+
// Add the entries from persisted data.
+ SpdyServerHostPortMap spdy_servers_map(SpdyServerHostPortMap::NO_AUTO_EVICT);
for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin();
it != spdy_servers->rend(); ++it) {
- spdy_servers_map_.Put(*it, support_spdy);
+ spdy_servers_map.Put(*it, support_spdy);
+ }
+
+ // |spdy_servers_map| will have the memory cache.
+ spdy_servers_map_.Swap(spdy_servers_map);
+
+ // Add the entries from the memory cache.
+ for (SpdyServerHostPortMap::reverse_iterator it = spdy_servers_map.rbegin();
+ it != spdy_servers_map.rend(); ++it) {
+ // Add the entry if it is not in the cache, otherwise move it to the front
+ // of recency list.
+ if (spdy_servers_map_.Get(it->first) == spdy_servers_map_.end())
+ spdy_servers_map_.Put(it->first, it->second);
}
}
void HttpServerPropertiesImpl::InitializeAlternativeServiceServers(
AlternativeServiceMap* alternative_service_map) {
- for (AlternativeServiceMap::iterator map_it =
- alternative_service_map_.begin();
- map_it != alternative_service_map_.end();) {
- for (AlternativeServiceInfoVector::iterator it = map_it->second.begin();
- it != map_it->second.end();) {
- // Keep all the broken ones since those do not get persisted.
- AlternativeService alternative_service(it->alternative_service);
- if (alternative_service.host.empty()) {
- alternative_service.host = map_it->first.host();
- }
- if (IsAlternativeServiceBroken(alternative_service)) {
- ++it;
- continue;
- }
- it = map_it->second.erase(it);
- }
- if (map_it->second.empty()) {
- RemoveCanonicalHost(map_it->first);
- map_it = alternative_service_map_.Erase(map_it);
- continue;
- }
- ++map_it;
+ int32_t size_diff =
+ alternative_service_map->size() - alternative_service_map_.size();
+ if (size_diff > 0) {
+ UMA_HISTOGRAM_COUNTS("Net.AlternativeServiceServers.MorePrefsEntries",
+ size_diff);
+ } else {
+ UMA_HISTOGRAM_COUNTS(
+ "Net.AlternativeServiceServers.MoreOrEqualCacheEntries", -size_diff);
}
+ AlternativeServiceMap new_alternative_service_map(
+ AlternativeServiceMap::NO_AUTO_EVICT);
// Add the entries from persisted data.
for (AlternativeServiceMap::reverse_iterator input_it =
alternative_service_map->rbegin();
input_it != alternative_service_map->rend(); ++input_it) {
DCHECK(!input_it->second.empty());
- AlternativeServiceMap::iterator output_it =
- alternative_service_map_.Peek(input_it->first);
- if (output_it == alternative_service_map_.end()) {
- // There is no value in alternative_service_map_ for input_it->first:
- // inserting in AlternativeServiceVectorInfo.
+ new_alternative_service_map.Put(input_it->first, input_it->second);
+ }
+
+ alternative_service_map_.Swap(new_alternative_service_map);
+
+ // Add the entries from the memory cache.
+ for (AlternativeServiceMap::reverse_iterator input_it =
+ new_alternative_service_map.rbegin();
+ input_it != new_alternative_service_map.rend(); ++input_it) {
+ if (alternative_service_map_.Get(input_it->first) ==
+ alternative_service_map_.end()) {
alternative_service_map_.Put(input_it->first, input_it->second);
- continue;
- }
- // There are some broken alternative services in alternative_service_map_
- // for input_it->first: appending AlternativeServiceInfo one by one.
- for (const AlternativeServiceInfo& alternative_service_info :
- input_it->second) {
- output_it->second.push_back(alternative_service_info);
}
}
// Attempt to find canonical servers.
- uint16 canonical_ports[] = { 80, 443 };
+ uint16_t canonical_ports[] = {80, 443};
for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
std::string canonical_suffix = canonical_suffixes_[i];
for (size_t j = 0; j < arraysize(canonical_ports); ++j) {
@@ -130,9 +135,20 @@ void HttpServerPropertiesImpl::InitializeAlternativeServiceServers(
void HttpServerPropertiesImpl::InitializeSpdySettingsServers(
SpdySettingsMap* spdy_settings_map) {
+ // Add the entries from persisted data.
+ SpdySettingsMap new_spdy_settings_map(SpdySettingsMap::NO_AUTO_EVICT);
for (SpdySettingsMap::reverse_iterator it = spdy_settings_map->rbegin();
it != spdy_settings_map->rend(); ++it) {
- spdy_settings_map_.Put(it->first, it->second);
+ new_spdy_settings_map.Put(it->first, it->second);
+ }
+
+ spdy_settings_map_.Swap(new_spdy_settings_map);
+
+ // Add the entries from the memory cache.
+ for (SpdySettingsMap::reverse_iterator it = new_spdy_settings_map.rbegin();
+ it != new_spdy_settings_map.rend(); ++it) {
+ if (spdy_settings_map_.Get(it->first) == spdy_settings_map_.end())
+ spdy_settings_map_.Put(it->first, it->second);
}
}
@@ -144,10 +160,45 @@ void HttpServerPropertiesImpl::InitializeSupportsQuic(
void HttpServerPropertiesImpl::InitializeServerNetworkStats(
ServerNetworkStatsMap* server_network_stats_map) {
+ // Add the entries from persisted data.
+ ServerNetworkStatsMap new_server_network_stats_map(
+ ServerNetworkStatsMap::NO_AUTO_EVICT);
for (ServerNetworkStatsMap::reverse_iterator it =
server_network_stats_map->rbegin();
it != server_network_stats_map->rend(); ++it) {
- server_network_stats_map_.Put(it->first, it->second);
+ new_server_network_stats_map.Put(it->first, it->second);
+ }
+
+ server_network_stats_map_.Swap(new_server_network_stats_map);
+
+ // Add the entries from the memory cache.
+ for (ServerNetworkStatsMap::reverse_iterator it =
+ new_server_network_stats_map.rbegin();
+ it != new_server_network_stats_map.rend(); ++it) {
+ if (server_network_stats_map_.Get(it->first) ==
+ server_network_stats_map_.end()) {
+ server_network_stats_map_.Put(it->first, it->second);
+ }
+ }
+}
+
+void HttpServerPropertiesImpl::InitializeQuicServerInfoMap(
+ QuicServerInfoMap* quic_server_info_map) {
+ // Add the entries from persisted data.
+ QuicServerInfoMap temp_map(QuicServerInfoMap::NO_AUTO_EVICT);
+ for (QuicServerInfoMap::reverse_iterator it = quic_server_info_map->rbegin();
+ it != quic_server_info_map->rend(); ++it) {
+ temp_map.Put(it->first, it->second);
+ }
+
+ quic_server_info_map_.Swap(temp_map);
+
+ // Add the entries from the memory cache.
+ for (QuicServerInfoMap::reverse_iterator it = temp_map.rbegin();
+ it != temp_map.rend(); ++it) {
+ if (quic_server_info_map_.Get(it->first) == quic_server_info_map_.end()) {
+ quic_server_info_map_.Put(it->first, it->second);
+ }
}
}
@@ -181,6 +232,7 @@ void HttpServerPropertiesImpl::Clear() {
spdy_settings_map_.Clear();
last_quic_address_.clear();
server_network_stats_map_.Clear();
+ quic_server_info_map_.Clear();
}
bool HttpServerPropertiesImpl::SupportsRequestPriority(
@@ -284,7 +336,8 @@ AlternativeServiceVector HttpServerPropertiesImpl::GetAlternativeServices(
it = map_it->second.erase(it);
continue;
}
- if (it->probability < alternative_service_probability_threshold_) {
+ if (it->probability == 0 ||
+ it->probability < alternative_service_probability_threshold_) {
++it;
continue;
}
@@ -509,10 +562,10 @@ HttpServerPropertiesImpl::GetAlternativeServiceInfoAsValue()
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host_port_pair", host_port_pair.ToString());
dict->Set("alternative_service",
- scoped_ptr<base::Value>(alternative_service_list.Pass()));
- dict_list->Append(dict.Pass());
+ scoped_ptr<base::Value>(std::move(alternative_service_list)));
+ dict_list->Append(std::move(dict));
}
- return dict_list.Pass();
+ return std::move(dict_list);
}
const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings(
@@ -529,7 +582,7 @@ bool HttpServerPropertiesImpl::SetSpdySetting(
const HostPortPair& host_port_pair,
SpdySettingsIds id,
SpdySettingsFlags flags,
- uint32 value) {
+ uint32_t value) {
if (!(flags & SETTINGS_FLAG_PLEASE_PERSIST))
return false;
@@ -601,6 +654,51 @@ HttpServerPropertiesImpl::server_network_stats_map() const {
return server_network_stats_map_;
}
+bool HttpServerPropertiesImpl::SetQuicServerInfo(
+ const QuicServerId& server_id,
+ const std::string& server_info) {
+ QuicServerInfoMap::iterator it = quic_server_info_map_.Peek(server_id);
+ bool changed =
+ (it == quic_server_info_map_.end() || it->second != server_info);
+ quic_server_info_map_.Put(server_id, server_info);
+ return changed;
+}
+
+const std::string* HttpServerPropertiesImpl::GetQuicServerInfo(
+ const QuicServerId& server_id) {
+ QuicServerInfoMap::iterator it = quic_server_info_map_.Get(server_id);
+ if (it == quic_server_info_map_.end())
+ return nullptr;
+ return &it->second;
+}
+
+const QuicServerInfoMap& HttpServerPropertiesImpl::quic_server_info_map()
+ const {
+ return quic_server_info_map_;
+}
+
+size_t HttpServerPropertiesImpl::max_server_configs_stored_in_properties()
+ const {
+ return max_server_configs_stored_in_properties_;
+}
+
+void HttpServerPropertiesImpl::SetMaxServerConfigsStoredInProperties(
+ size_t max_server_configs_stored_in_properties) {
+ max_server_configs_stored_in_properties_ =
+ max_server_configs_stored_in_properties;
+
+ // MRUCache doesn't allow the size of the cache to be changed. Thus create a
+ // new map with the new size and add current elements and swap the new map.
+ quic_server_info_map_.ShrinkToSize(max_server_configs_stored_in_properties_);
+ QuicServerInfoMap temp_map(max_server_configs_stored_in_properties_);
+ for (QuicServerInfoMap::reverse_iterator it = quic_server_info_map_.rbegin();
+ it != quic_server_info_map_.rend(); ++it) {
+ temp_map.Put(it->first, it->second);
+ }
+
+ quic_server_info_map_.Swap(temp_map);
+}
+
void HttpServerPropertiesImpl::SetAlternativeServiceProbabilityThreshold(
double threshold) {
alternative_service_probability_threshold_ = threshold;
diff --git a/chromium/net/http/http_server_properties_impl.h b/chromium/net/http/http_server_properties_impl.h
index d6ee31a684f..b8678bed747 100644
--- a/chromium/net/http/http_server_properties_impl.h
+++ b/chromium/net/http/http_server_properties_impl.h
@@ -5,14 +5,17 @@
#ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_
#define NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <map>
#include <set>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
@@ -60,6 +63,8 @@ class NET_EXPORT HttpServerPropertiesImpl
void InitializeServerNetworkStats(
ServerNetworkStatsMap* server_network_stats_map);
+ void InitializeQuicServerInfoMap(QuicServerInfoMap* quic_server_info_map);
+
// Get the list of servers (host/port) that support SPDY. The max_size is the
// number of MRU servers that support SPDY that are to be returned.
void GetSpdyServerList(base::ListValue* spdy_server_list,
@@ -114,7 +119,7 @@ class NET_EXPORT HttpServerPropertiesImpl
bool SetSpdySetting(const HostPortPair& host_port_pair,
SpdySettingsIds id,
SpdySettingsFlags flags,
- uint32 value) override;
+ uint32_t value) override;
void ClearSpdySettings(const HostPortPair& host_port_pair) override;
void ClearAllSpdySettings() override;
const SpdySettingsMap& spdy_settings_map() const override;
@@ -125,6 +130,13 @@ class NET_EXPORT HttpServerPropertiesImpl
const ServerNetworkStats* GetServerNetworkStats(
const HostPortPair& host_port_pair) override;
const ServerNetworkStatsMap& server_network_stats_map() const override;
+ bool SetQuicServerInfo(const QuicServerId& server_id,
+ const std::string& server_info) override;
+ const std::string* GetQuicServerInfo(const QuicServerId& server_id) override;
+ const QuicServerInfoMap& quic_server_info_map() const override;
+ size_t max_server_configs_stored_in_properties() const override;
+ void SetMaxServerConfigsStoredInProperties(
+ size_t max_server_configs_stored_in_properties) override;
private:
friend class HttpServerPropertiesImplPeer;
@@ -177,6 +189,9 @@ class NET_EXPORT HttpServerPropertiesImpl
double alternative_service_probability_threshold_;
+ QuicServerInfoMap quic_server_info_map_;
+ size_t max_server_configs_stored_in_properties_;
+
base::WeakPtrFactory<HttpServerPropertiesImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl);
diff --git a/chromium/net/http/http_server_properties_impl_unittest.cc b/chromium/net/http/http_server_properties_impl_unittest.cc
index e354b77c53d..a4e81310ee0 100644
--- a/chromium/net/http/http_server_properties_impl_unittest.cc
+++ b/chromium/net/http/http_server_properties_impl_unittest.cc
@@ -7,7 +7,6 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -22,8 +21,6 @@ class ListValue;
namespace net {
-const int kMaxSupportsSpdyServerHosts = 500;
-
class HttpServerPropertiesImplPeer {
public:
static void AddBrokenAlternativeServiceWithExpirationTime(
@@ -47,6 +44,15 @@ void PrintTo(const AlternativeService& alternative_service, std::ostream* os) {
namespace {
+const int kMaxSupportsSpdyServerHosts = 500;
+const SpdySettingsIds kSpdySettingsId = SETTINGS_UPLOAD_BANDWIDTH;
+const SpdySettingsFlags kSpdySettingsFlags = SETTINGS_FLAG_PERSISTED;
+
+struct SpdySettingsDataToVerify {
+ HostPortPair spdy_server;
+ uint32_t value;
+};
+
class HttpServerPropertiesImplTest : public testing::Test {
protected:
bool HasAlternativeService(const HostPortPair& origin) {
@@ -64,6 +70,35 @@ class HttpServerPropertiesImplTest : public testing::Test {
alternative_probability, expiration);
}
+ void InitializeSpdySettingsUploadBandwidth(SpdySettingsMap* spdy_settings_map,
+ const HostPortPair& spdy_server,
+ uint32_t value) {
+ SettingsMap settings_map;
+ settings_map[kSpdySettingsId] =
+ SettingsFlagsAndValue(kSpdySettingsFlags, value);
+ spdy_settings_map->Put(spdy_server, settings_map);
+ }
+
+ void VerifySpdySettingsUploadBandwidth(
+ const SpdySettingsDataToVerify* data_to_verify) {
+ const SpdySettingsMap& spdy_settings_map = impl_.spdy_settings_map();
+ int count = 0;
+ for (SpdySettingsMap::const_iterator map_it = spdy_settings_map.begin();
+ map_it != spdy_settings_map.end(); ++map_it, ++count) {
+ const SpdySettingsDataToVerify& data = data_to_verify[count];
+ EXPECT_TRUE(data.spdy_server.Equals(map_it->first));
+ const SettingsMap& settings_map_memory = map_it->second;
+
+ EXPECT_EQ(1U, settings_map_memory.size());
+ SettingsMap::const_iterator it =
+ settings_map_memory.find(kSpdySettingsId);
+ EXPECT_TRUE(it != settings_map_memory.end());
+ SettingsFlagsAndValue flags_and_value_memory = it->second;
+ EXPECT_EQ(kSpdySettingsFlags, flags_and_value_memory.first);
+ EXPECT_EQ(data.value, flags_and_value_memory.second);
+ }
+ }
+
HttpServerPropertiesImpl impl_;
};
@@ -73,9 +108,15 @@ TEST_F(SpdyServerPropertiesTest, Initialize) {
HostPortPair spdy_server_google("www.google.com", 443);
std::string spdy_server_g = spdy_server_google.ToString();
+ HostPortPair spdy_server_photos("photos.google.com", 443);
+ std::string spdy_server_p = spdy_server_photos.ToString();
+
HostPortPair spdy_server_docs("docs.google.com", 443);
std::string spdy_server_d = spdy_server_docs.ToString();
+ HostPortPair spdy_server_mail("mail.google.com", 443);
+ std::string spdy_server_m = spdy_server_mail.ToString();
+
// Check by initializing NULL spdy servers.
impl_.InitializeSpdyServers(NULL, true);
EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_google));
@@ -85,31 +126,80 @@ TEST_F(SpdyServerPropertiesTest, Initialize) {
impl_.InitializeSpdyServers(&spdy_servers, true);
EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_google));
- // Check by initializing with www.google.com:443 spdy server.
+ // Check by initializing www.google.com:443 and photos.google.com:443 as spdy
+ // servers.
std::vector<std::string> spdy_servers1;
- spdy_servers1.push_back(spdy_server_g);
+ spdy_servers1.push_back(spdy_server_g); // Will be 0th index.
+ spdy_servers1.push_back(spdy_server_p); // Will be 1st index.
impl_.InitializeSpdyServers(&spdy_servers1, true);
+ EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_photos));
EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google));
- // Check by initializing with www.google.com:443 and docs.google.com:443 spdy
- // servers.
- std::vector<std::string> spdy_servers2;
- spdy_servers2.push_back(spdy_server_g);
- spdy_servers2.push_back(spdy_server_d);
- impl_.InitializeSpdyServers(&spdy_servers2, true);
-
// Verify spdy_server_g and spdy_server_d are in the list in the same order.
base::ListValue spdy_server_list;
impl_.GetSpdyServerList(&spdy_server_list, kMaxSupportsSpdyServerHosts);
EXPECT_EQ(2U, spdy_server_list.GetSize());
std::string string_value_g;
+ ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); // 0th index.
+ ASSERT_EQ(spdy_server_g, string_value_g);
+ std::string string_value_p;
+ ASSERT_TRUE(spdy_server_list.GetString(1, &string_value_p)); // 1st index.
+ ASSERT_EQ(spdy_server_p, string_value_p);
+
+ // Check by initializing mail.google.com:443 and docs.google.com:443 as spdy
+ // servers.
+ std::vector<std::string> spdy_servers2;
+ spdy_servers2.push_back(spdy_server_m); // Will be 2nd index.
+ spdy_servers2.push_back(spdy_server_d); // Will be 3rd index.
+ impl_.InitializeSpdyServers(&spdy_servers2, true);
+
+ // Verify all the servers are in the list in the same order.
+ spdy_server_list.Clear();
+ impl_.GetSpdyServerList(&spdy_server_list, kMaxSupportsSpdyServerHosts);
+ EXPECT_EQ(4U, spdy_server_list.GetSize());
+
ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g));
ASSERT_EQ(spdy_server_g, string_value_g);
+ ASSERT_TRUE(spdy_server_list.GetString(1, &string_value_p));
+ ASSERT_EQ(spdy_server_p, string_value_p);
+ std::string string_value_m;
+ ASSERT_TRUE(spdy_server_list.GetString(2, &string_value_m));
+ ASSERT_EQ(spdy_server_m, string_value_m);
std::string string_value_d;
- ASSERT_TRUE(spdy_server_list.GetString(1, &string_value_d));
+ ASSERT_TRUE(spdy_server_list.GetString(3, &string_value_d));
ASSERT_EQ(spdy_server_d, string_value_d);
+
+ EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_docs));
+ EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_mail));
+ EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_photos));
EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google));
+
+ // Verify new data that is being initialized overwrites what is already in the
+ // memory and also verify the recency list order.
+ //
+ // Change supports SPDY value for photos and mails servers and order of
+ // initalization shouldn't matter.
+ std::vector<std::string> spdy_servers3;
+ spdy_servers3.push_back(spdy_server_m);
+ spdy_servers3.push_back(spdy_server_p);
+ impl_.InitializeSpdyServers(&spdy_servers3, false);
+
+ // Verify the entries are in the same order.
+ ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g));
+ ASSERT_EQ(spdy_server_g, string_value_g);
+ ASSERT_TRUE(spdy_server_list.GetString(1, &string_value_p));
+ ASSERT_EQ(spdy_server_p, string_value_p);
+ ASSERT_TRUE(spdy_server_list.GetString(2, &string_value_m));
+ ASSERT_EQ(spdy_server_m, string_value_m);
+ ASSERT_TRUE(spdy_server_list.GetString(3, &string_value_d));
+ ASSERT_EQ(spdy_server_d, string_value_d);
+
+ // Verify photos and mail servers don't support SPDY and other servers support
+ // SPDY.
EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_docs));
+ EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_mail));
+ EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_photos));
+ EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google));
}
TEST_F(SpdyServerPropertiesTest, SupportsRequestPriorityTest) {
@@ -358,74 +448,92 @@ TEST_F(AlternateProtocolServerPropertiesTest, ProbabilityExcluded) {
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
+TEST_F(AlternateProtocolServerPropertiesTest, ZeroProbabilityAlwaysExcluded) {
+ impl_.SetAlternativeServiceProbabilityThreshold(0.0);
+
+ HostPortPair test_host_port_pair("foo", 80);
+ const AlternativeService alternative_service(NPN_HTTP_2, "foo", 443);
+ SetAlternativeService(test_host_port_pair, alternative_service, 0);
+ EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
+}
+
TEST_F(AlternateProtocolServerPropertiesTest, Initialize) {
- // |test_host_port_pair1| has one alternative service, which is non-broken,
- // and thus will be removed by InitializeAlternativeServiceServers().
+ // |test_host_port_pair1| has an alternative service, which will not be
+ // affected by InitializeAlternativeServiceServers(), because
+ // |alternative_service_map| does not have an entry for
+ // |test_host_port_pair1|.
HostPortPair test_host_port_pair1("foo1", 80);
const AlternativeService alternative_service1(NPN_HTTP_2, "bar1", 443);
const base::Time now = base::Time::Now();
base::Time expiration1 = now + base::TimeDelta::FromDays(1);
+ // 1st entry in the memory.
impl_.SetAlternativeService(test_host_port_pair1, alternative_service1, 1.0,
expiration1);
- // |test_host_port_pair2| has two alternative services. The broken one will
- // remain, the non-broken one will be removed by
- // InitializeAlternativeServiceServers().
+ // |test_host_port_pair2| has an alternative service, which will be
+ // overwritten by InitializeAlternativeServiceServers(), because
+ // |alternative_service_map| has an entry for
+ // |test_host_port_pair2|.
AlternativeServiceInfoVector alternative_service_info_vector;
const AlternativeService alternative_service2(NPN_SPDY_3_1, "bar2", 443);
base::Time expiration2 = now + base::TimeDelta::FromDays(2);
alternative_service_info_vector.push_back(
AlternativeServiceInfo(alternative_service2, 1.0, expiration2));
- const AlternativeService alternative_service3(NPN_SPDY_3_1, "bar3", 1234);
- base::Time expiration3 = now + base::TimeDelta::FromDays(3);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service3, 0.8, expiration3));
HostPortPair test_host_port_pair2("foo2", 80);
+ // 0th entry in the memory.
impl_.SetAlternativeServices(test_host_port_pair2,
alternative_service_info_vector);
- impl_.MarkAlternativeServiceBroken(alternative_service2);
// Prepare |alternative_service_map| to be loaded by
// InitializeAlternativeServiceServers().
AlternativeServiceMap alternative_service_map(
AlternativeServiceMap::NO_AUTO_EVICT);
- const AlternativeService alternative_service4(NPN_HTTP_2, "bar4", 123);
- base::Time expiration4 = now + base::TimeDelta::FromDays(4);
- const AlternativeServiceInfo alternative_service_info1(alternative_service4,
- 0.7, expiration4);
+ const AlternativeService alternative_service3(NPN_HTTP_2, "bar3", 123);
+ base::Time expiration3 = now + base::TimeDelta::FromDays(3);
+ const AlternativeServiceInfo alternative_service_info1(alternative_service3,
+ 0.7, expiration3);
+ // Simulate updating data for 0th entry with data from Preferences.
alternative_service_map.Put(
test_host_port_pair2,
AlternativeServiceInfoVector(/*size=*/1, alternative_service_info1));
HostPortPair test_host_port_pair3("foo3", 80);
- const AlternativeService alternative_service5(NPN_HTTP_2, "bar5", 1234);
- base::Time expiration5 = now + base::TimeDelta::FromDays(5);
- const AlternativeServiceInfo alternative_service_info2(alternative_service5,
- 0.2, expiration5);
+ const AlternativeService alternative_service4(NPN_HTTP_2, "bar4", 1234);
+ base::Time expiration4 = now + base::TimeDelta::FromDays(4);
+ const AlternativeServiceInfo alternative_service_info2(alternative_service4,
+ 0.2, expiration4);
+ // Add an old entry from Preferences, this will be added to end of recency
+ // list.
alternative_service_map.Put(
test_host_port_pair3,
AlternativeServiceInfoVector(/*size=*/1, alternative_service_info2));
+ // MRU list will be test_host_port_pair2, test_host_port_pair1,
+ // test_host_port_pair3.
impl_.InitializeAlternativeServiceServers(&alternative_service_map);
// Verify alternative_service_map.
const AlternativeServiceMap& map = impl_.alternative_service_map();
- ASSERT_EQ(2u, map.size());
+ ASSERT_EQ(3u, map.size());
AlternativeServiceMap::const_iterator map_it = map.begin();
- EXPECT_TRUE(map_it->first.Equals(test_host_port_pair3));
+
+ EXPECT_TRUE(map_it->first.Equals(test_host_port_pair2));
ASSERT_EQ(1u, map_it->second.size());
- EXPECT_EQ(alternative_service5, map_it->second[0].alternative_service);
- EXPECT_EQ(0.2, map_it->second[0].probability);
- EXPECT_EQ(expiration5, map_it->second[0].expiration);
+ EXPECT_EQ(alternative_service3, map_it->second[0].alternative_service);
+ EXPECT_EQ(0.7, map_it->second[0].probability);
+ EXPECT_EQ(expiration3, map_it->second[0].expiration);
++map_it;
- EXPECT_TRUE(map_it->first.Equals(test_host_port_pair2));
- ASSERT_EQ(2u, map_it->second.size());
- EXPECT_EQ(alternative_service2, map_it->second[0].alternative_service);
+ EXPECT_TRUE(map_it->first.Equals(test_host_port_pair1));
+ ASSERT_EQ(1u, map_it->second.size());
+ EXPECT_EQ(alternative_service1, map_it->second[0].alternative_service);
EXPECT_EQ(1.0, map_it->second[0].probability);
- EXPECT_EQ(expiration2, map_it->second[0].expiration);
- EXPECT_EQ(alternative_service4, map_it->second[1].alternative_service);
- EXPECT_EQ(0.7, map_it->second[1].probability);
- EXPECT_EQ(expiration4, map_it->second[1].expiration);
+ EXPECT_EQ(expiration1, map_it->second[0].expiration);
+ ++map_it;
+ EXPECT_TRUE(map_it->first.Equals(test_host_port_pair3));
+ ASSERT_EQ(1u, map_it->second.size());
+ EXPECT_EQ(alternative_service4, map_it->second[0].alternative_service);
+ EXPECT_EQ(0.2, map_it->second[0].probability);
+ EXPECT_EQ(expiration4, map_it->second[0].expiration);
}
// Regression test for https://crbug.com/504032:
@@ -928,29 +1036,67 @@ typedef HttpServerPropertiesImplTest SpdySettingsServerPropertiesTest;
TEST_F(SpdySettingsServerPropertiesTest, Initialize) {
HostPortPair spdy_server_google("www.google.com", 443);
+ HostPortPair spdy_server_photos("photos.google.com", 443);
+ HostPortPair spdy_server_docs("docs.google.com", 443);
+ HostPortPair spdy_server_mail("mail.google.com", 443);
// Check by initializing empty spdy settings.
SpdySettingsMap spdy_settings_map(SpdySettingsMap::NO_AUTO_EVICT);
impl_.InitializeSpdySettingsServers(&spdy_settings_map);
EXPECT_TRUE(impl_.GetSpdySettings(spdy_server_google).empty());
- // Check by initializing with www.google.com:443 spdy server settings.
- SettingsMap settings_map;
- const SpdySettingsIds id = SETTINGS_UPLOAD_BANDWIDTH;
- const SpdySettingsFlags flags = SETTINGS_FLAG_PERSISTED;
- const uint32 value = 31337;
- SettingsFlagsAndValue flags_and_value(flags, value);
- settings_map[id] = flags_and_value;
- spdy_settings_map.Put(spdy_server_google, settings_map);
- impl_.InitializeSpdySettingsServers(&spdy_settings_map);
-
- const SettingsMap& settings_map2 = impl_.GetSpdySettings(spdy_server_google);
- ASSERT_EQ(1U, settings_map2.size());
- SettingsMap::const_iterator it = settings_map2.find(id);
- EXPECT_TRUE(it != settings_map2.end());
- SettingsFlagsAndValue flags_and_value2 = it->second;
- EXPECT_EQ(flags, flags_and_value2.first);
- EXPECT_EQ(value, flags_and_value2.second);
+ // Check by initializing spdy server settings for www.google.com:443 and
+ // photos.google.com:443.
+ const SpdySettingsDataToVerify data_to_verify1[] = {
+ {spdy_server_google, 10000}, {spdy_server_photos, 20000},
+ };
+ // Insert them in reverse order to make spdy_server_google as MRU.
+ SpdySettingsMap spdy_settings_map1(SpdySettingsMap::NO_AUTO_EVICT);
+ InitializeSpdySettingsUploadBandwidth(&spdy_settings_map1,
+ data_to_verify1[1].spdy_server,
+ data_to_verify1[1].value);
+ InitializeSpdySettingsUploadBandwidth(&spdy_settings_map1,
+ data_to_verify1[0].spdy_server,
+ data_to_verify1[0].value);
+ impl_.InitializeSpdySettingsServers(&spdy_settings_map1);
+ VerifySpdySettingsUploadBandwidth(data_to_verify1);
+
+ // Check by initializing mail.google.com:443 and docs.google.com:443 as spdy
+ // servers.
+ const SpdySettingsDataToVerify data_to_verify2[] = {
+ {spdy_server_google, 10000},
+ {spdy_server_photos, 20000},
+ {spdy_server_mail, 30000},
+ {spdy_server_docs, 40000},
+ };
+ SpdySettingsMap spdy_settings_map2(SpdySettingsMap::NO_AUTO_EVICT);
+ InitializeSpdySettingsUploadBandwidth(&spdy_settings_map2,
+ data_to_verify2[3].spdy_server,
+ data_to_verify2[3].value);
+ InitializeSpdySettingsUploadBandwidth(&spdy_settings_map2,
+ data_to_verify2[2].spdy_server,
+ data_to_verify2[2].value);
+ impl_.InitializeSpdySettingsServers(&spdy_settings_map2);
+ VerifySpdySettingsUploadBandwidth(data_to_verify2);
+
+ // Verify new data that is being initialized overwrites what is already in the
+ // memory and also verify the recency list order by updating 3rd and 1st
+ // element's data.
+ const SpdySettingsDataToVerify data_to_verify3[] = {
+ {spdy_server_google, 10000},
+ {spdy_server_photos, 60000}, // Change the value of photos.
+ {spdy_server_mail, 30000},
+ {spdy_server_docs, 50000}, // Change the value of docs.
+ };
+ SpdySettingsMap spdy_settings_map3(SpdySettingsMap::NO_AUTO_EVICT);
+ InitializeSpdySettingsUploadBandwidth(&spdy_settings_map3,
+ data_to_verify3[3].spdy_server,
+ data_to_verify3[3].value);
+ InitializeSpdySettingsUploadBandwidth(&spdy_settings_map3,
+ data_to_verify3[1].spdy_server,
+ data_to_verify3[1].value);
+ impl_.InitializeSpdySettingsServers(&spdy_settings_map3);
+ VerifySpdySettingsUploadBandwidth(data_to_verify3);
}
TEST_F(SpdySettingsServerPropertiesTest, SetSpdySetting) {
@@ -962,7 +1108,7 @@ TEST_F(SpdySettingsServerPropertiesTest, SetSpdySetting) {
HostPortPair spdy_server_google("www.google.com", 443);
const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH;
const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value1 = 31337;
+ const uint32_t value1 = 31337;
EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_google, id1, flags1, value1));
// Check the values.
const SettingsMap& settings_map1_ret =
@@ -978,7 +1124,7 @@ TEST_F(SpdySettingsServerPropertiesTest, SetSpdySetting) {
HostPortPair spdy_server_mail("mail.google.com", 443);
const SpdySettingsIds id2 = SETTINGS_DOWNLOAD_BANDWIDTH;
const SpdySettingsFlags flags2 = SETTINGS_FLAG_NONE;
- const uint32 value2 = 62667;
+ const uint32_t value2 = 62667;
EXPECT_FALSE(impl_.SetSpdySetting(spdy_server_mail, id2, flags2, value2));
const SettingsMap& settings_map2_ret =
impl_.GetSpdySettings(spdy_server_mail);
@@ -988,7 +1134,7 @@ TEST_F(SpdySettingsServerPropertiesTest, SetSpdySetting) {
HostPortPair spdy_server_docs("docs.google.com", 443);
const SpdySettingsIds id3 = SETTINGS_ROUND_TRIP_TIME;
const SpdySettingsFlags flags3 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value3 = 93997;
+ const uint32_t value3 = 93997;
SettingsFlagsAndValue flags_and_value3(flags3, value3);
EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_docs, id3, flags3, value3));
// Check the values.
@@ -1029,7 +1175,7 @@ TEST_F(SpdySettingsServerPropertiesTest, Clear) {
HostPortPair spdy_server_google("www.google.com", 443);
const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH;
const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value1 = 31337;
+ const uint32_t value1 = 31337;
EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_google, id1, flags1, value1));
// Check the values.
const SettingsMap& settings_map1_ret =
@@ -1045,7 +1191,7 @@ TEST_F(SpdySettingsServerPropertiesTest, Clear) {
HostPortPair spdy_server_docs("docs.google.com", 443);
const SpdySettingsIds id3 = SETTINGS_ROUND_TRIP_TIME;
const SpdySettingsFlags flags3 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value3 = 93997;
+ const uint32_t value3 = 93997;
EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_docs, id3, flags3, value3));
// Check the values.
const SettingsMap& settings_map3_ret =
@@ -1067,14 +1213,14 @@ TEST_F(SpdySettingsServerPropertiesTest, MRUOfGetSpdySettings) {
HostPortPair spdy_server_google("www.google.com", 443);
const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH;
const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value1 = 31337;
+ const uint32_t value1 = 31337;
EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_google, id1, flags1, value1));
// Add docs.google.com:443 as persisting
HostPortPair spdy_server_docs("docs.google.com", 443);
const SpdySettingsIds id2 = SETTINGS_ROUND_TRIP_TIME;
const SpdySettingsFlags flags2 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value2 = 93997;
+ const uint32_t value2 = 93997;
EXPECT_TRUE(impl_.SetSpdySetting(spdy_server_docs, id2, flags2, value2));
// Verify the first element is docs.google.com:443.
@@ -1155,22 +1301,67 @@ TEST_F(ServerNetworkStatsServerPropertiesTest, Initialize) {
HostPortPair google_server("www.google.com", 443);
// Check by initializing empty ServerNetworkStats.
- ServerNetworkStatsMap server_network_stats_map(
+ ServerNetworkStatsMap init_server_network_stats_map(
ServerNetworkStatsMap::NO_AUTO_EVICT);
- impl_.InitializeServerNetworkStats(&server_network_stats_map);
+ impl_.InitializeServerNetworkStats(&init_server_network_stats_map);
const ServerNetworkStats* stats = impl_.GetServerNetworkStats(google_server);
EXPECT_EQ(NULL, stats);
// Check by initializing with www.google.com:443.
- ServerNetworkStats stats1;
- stats1.srtt = base::TimeDelta::FromMicroseconds(10);
- stats1.bandwidth_estimate = QuicBandwidth::FromBitsPerSecond(100);
- server_network_stats_map.Put(google_server, stats1);
+ ServerNetworkStats stats_google;
+ stats_google.srtt = base::TimeDelta::FromMicroseconds(10);
+ stats_google.bandwidth_estimate = QuicBandwidth::FromBitsPerSecond(100);
+ init_server_network_stats_map.Put(google_server, stats_google);
+ impl_.InitializeServerNetworkStats(&init_server_network_stats_map);
+
+ // Verify data for www.google.com:443.
+ ASSERT_EQ(1u, impl_.server_network_stats_map().size());
+ EXPECT_EQ(stats_google, *(impl_.GetServerNetworkStats(google_server)));
+
+ // Test recency order and overwriting of data.
+ //
+ // |docs_server| has a ServerNetworkStats, which will be overwritten by
+ // InitializeServerNetworkStats(), because |server_network_stats_map| has an
+ // entry for |docs_server|.
+ HostPortPair docs_server("docs.google.com", 443);
+ ServerNetworkStats stats_docs;
+ stats_docs.srtt = base::TimeDelta::FromMicroseconds(20);
+ stats_docs.bandwidth_estimate = QuicBandwidth::FromBitsPerSecond(200);
+ // Recency order will be |docs_server| and |google_server|.
+ impl_.SetServerNetworkStats(docs_server, stats_docs);
+
+ // Prepare |server_network_stats_map| to be loaded by
+ // InitializeServerNetworkStats().
+ ServerNetworkStatsMap server_network_stats_map(
+ ServerNetworkStatsMap::NO_AUTO_EVICT);
+
+ // Change the values for |docs_server|.
+ ServerNetworkStats new_stats_docs;
+ new_stats_docs.srtt = base::TimeDelta::FromMicroseconds(25);
+ new_stats_docs.bandwidth_estimate = QuicBandwidth::FromBitsPerSecond(250);
+ server_network_stats_map.Put(docs_server, new_stats_docs);
+ // Add data for mail.google.com:443.
+ HostPortPair mail_server("mail.google.com", 443);
+ ServerNetworkStats stats_mail;
+ stats_mail.srtt = base::TimeDelta::FromMicroseconds(30);
+ stats_mail.bandwidth_estimate = QuicBandwidth::FromBitsPerSecond(300);
+ server_network_stats_map.Put(mail_server, stats_mail);
+
+ // Recency order will be |docs_server|, |google_server| and |mail_server|.
impl_.InitializeServerNetworkStats(&server_network_stats_map);
- const ServerNetworkStats* stats2 = impl_.GetServerNetworkStats(google_server);
- EXPECT_EQ(10, stats2->srtt.ToInternalValue());
- EXPECT_EQ(100, stats2->bandwidth_estimate.ToBitsPerSecond());
+ const ServerNetworkStatsMap& map = impl_.server_network_stats_map();
+ ASSERT_EQ(3u, map.size());
+ ServerNetworkStatsMap::const_iterator map_it = map.begin();
+
+ EXPECT_TRUE(map_it->first.Equals(docs_server));
+ EXPECT_EQ(new_stats_docs, map_it->second);
+ ++map_it;
+ EXPECT_TRUE(map_it->first.Equals(google_server));
+ EXPECT_EQ(stats_google, map_it->second);
+ ++map_it;
+ EXPECT_TRUE(map_it->first.Equals(mail_server));
+ EXPECT_EQ(stats_mail, map_it->second);
}
TEST_F(ServerNetworkStatsServerPropertiesTest, SetServerNetworkStats) {
@@ -1192,6 +1383,111 @@ TEST_F(ServerNetworkStatsServerPropertiesTest, SetServerNetworkStats) {
EXPECT_EQ(NULL, stats3);
}
+typedef HttpServerPropertiesImplTest QuicServerInfoServerPropertiesTest;
+
+TEST_F(QuicServerInfoServerPropertiesTest, Initialize) {
+ HostPortPair google_server("www.google.com", 443);
+ QuicServerId google_quic_server_id(google_server, PRIVACY_MODE_ENABLED);
+
+ EXPECT_EQ(QuicServerInfoMap::NO_AUTO_EVICT,
+ impl_.quic_server_info_map().max_size());
+ impl_.SetMaxServerConfigsStoredInProperties(10);
+ EXPECT_EQ(10u, impl_.quic_server_info_map().max_size());
+
+ // Check empty map.
+ QuicServerInfoMap init_quic_server_info_map(QuicServerInfoMap::NO_AUTO_EVICT);
+ impl_.InitializeQuicServerInfoMap(&init_quic_server_info_map);
+ EXPECT_EQ(0u, impl_.quic_server_info_map().size());
+
+ // Check by initializing with www.google.com:443.
+ std::string google_server_info("google_quic_server_info");
+ init_quic_server_info_map.Put(google_quic_server_id, google_server_info);
+ impl_.InitializeQuicServerInfoMap(&init_quic_server_info_map);
+
+ // Verify data for www.google.com:443.
+ EXPECT_EQ(1u, impl_.quic_server_info_map().size());
+ EXPECT_EQ(google_server_info,
+ *impl_.GetQuicServerInfo(google_quic_server_id));
+
+ // Test recency order and overwriting of data.
+ //
+ // |docs_server| has a QuicServerInfo, which will be overwritten by
+ // InitializeQuicServerInfoMap(), because |quic_server_info_map| has an
+ // entry for |docs_server|.
+ HostPortPair docs_server("docs.google.com", 443);
+ QuicServerId docs_quic_server_id(docs_server, PRIVACY_MODE_ENABLED);
+ std::string docs_server_info("docs_quic_server_info");
+ impl_.SetQuicServerInfo(docs_quic_server_id, docs_server_info);
+
+ // Recency order will be |docs_server| and |google_server|.
+ const QuicServerInfoMap& map = impl_.quic_server_info_map();
+ ASSERT_EQ(2u, map.size());
+ QuicServerInfoMap::const_iterator map_it = map.begin();
+ EXPECT_EQ(map_it->first, docs_quic_server_id);
+ EXPECT_EQ(docs_server_info, map_it->second);
+ ++map_it;
+ EXPECT_EQ(map_it->first, google_quic_server_id);
+ EXPECT_EQ(google_server_info, map_it->second);
+
+ // Prepare |quic_server_info_map| to be loaded by
+ // InitializeQuicServerInfoMap().
+ QuicServerInfoMap quic_server_info_map(QuicServerInfoMap::NO_AUTO_EVICT);
+ // Change the values for |docs_server|.
+ std::string new_docs_server_info("new_docs_quic_server_info");
+ quic_server_info_map.Put(docs_quic_server_id, new_docs_server_info);
+ // Add data for mail.google.com:443.
+ HostPortPair mail_server("mail.google.com", 443);
+ QuicServerId mail_quic_server_id(mail_server, PRIVACY_MODE_ENABLED);
+ std::string mail_server_info("mail_quic_server_info");
+ quic_server_info_map.Put(mail_quic_server_id, mail_server_info);
+ impl_.InitializeQuicServerInfoMap(&quic_server_info_map);
+
+ // Recency order will be |docs_server|, |google_server| and |mail_server|.
+ const QuicServerInfoMap& memory_map = impl_.quic_server_info_map();
+ ASSERT_EQ(3u, memory_map.size());
+ QuicServerInfoMap::const_iterator memory_map_it = memory_map.begin();
+ EXPECT_EQ(memory_map_it->first, docs_quic_server_id);
+ EXPECT_EQ(new_docs_server_info, memory_map_it->second);
+ ++memory_map_it;
+ EXPECT_EQ(memory_map_it->first, google_quic_server_id);
+ EXPECT_EQ(google_server_info, memory_map_it->second);
+ ++memory_map_it;
+ EXPECT_EQ(memory_map_it->first, mail_quic_server_id);
+ EXPECT_EQ(mail_server_info, memory_map_it->second);
+
+ // Shrink the size of |quic_server_info_map| and verify the MRU order is
+ // maintained.
+ impl_.SetMaxServerConfigsStoredInProperties(2);
+ EXPECT_EQ(2u, impl_.quic_server_info_map().max_size());
+
+ const QuicServerInfoMap& memory_map1 = impl_.quic_server_info_map();
+ ASSERT_EQ(2u, memory_map1.size());
+ QuicServerInfoMap::const_iterator memory_map1_it = memory_map1.begin();
+ EXPECT_EQ(memory_map1_it->first, docs_quic_server_id);
+ EXPECT_EQ(new_docs_server_info, memory_map1_it->second);
+ ++memory_map1_it;
+ EXPECT_EQ(memory_map1_it->first, google_quic_server_id);
+ EXPECT_EQ(google_server_info, memory_map1_it->second);
+ // |QuicServerInfo| for |mail_quic_server_id| shouldn't be there.
+ EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(mail_quic_server_id));
+}
+
+TEST_F(QuicServerInfoServerPropertiesTest, SetQuicServerInfo) {
+ HostPortPair foo_server("foo", 80);
+ QuicServerId quic_server_id(foo_server, PRIVACY_MODE_ENABLED);
+ EXPECT_EQ(0u, impl_.quic_server_info_map().size());
+
+ std::string quic_server_info1("quic_server_info1");
+ impl_.SetQuicServerInfo(quic_server_id, quic_server_info1);
+
+ EXPECT_EQ(1u, impl_.quic_server_info_map().size());
+ EXPECT_EQ(quic_server_info1, *(impl_.GetQuicServerInfo(quic_server_id)));
+
+ impl_.Clear();
+ EXPECT_EQ(0u, impl_.quic_server_info_map().size());
+ EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(quic_server_id));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/http/http_server_properties_manager.cc b/chromium/net/http/http_server_properties_manager.cc
index 2577f953cd8..f7493ff0652 100644
--- a/chromium/net/http/http_server_properties_manager.cc
+++ b/chromium/net/http/http_server_properties_manager.cc
@@ -23,21 +23,19 @@ namespace {
// Time to wait before starting an update the http_server_properties_impl_ cache
// from preferences. Scheduling another update during this period will reset the
// timer.
-const int64 kUpdateCacheDelayMs = 1000;
+const int64_t kUpdateCacheDelayMs = 1000;
// Time to wait before starting an update the preferences from the
// http_server_properties_impl_ cache. Scheduling another update during this
// period will reset the timer.
-const int64 kUpdatePrefsDelayMs = 60000;
+const int64_t kUpdatePrefsDelayMs = 60000;
// "version" 0 indicates, http_server_properties doesn't have "version"
// property.
const int kMissingVersion = 0;
// The version number of persisted http_server_properties.
-const int kVersionNumber = 3;
-
-typedef std::vector<std::string> StringVector;
+const int kVersionNumber = 4;
// Persist 200 MRU AlternateProtocolHostPortPairs.
const int kMaxAlternateProtocolHostsToPersist = 200;
@@ -56,9 +54,10 @@ const char kServersKey[] = "servers";
const char kSupportsSpdyKey[] = "supports_spdy";
const char kSettingsKey[] = "settings";
const char kSupportsQuicKey[] = "supports_quic";
+const char kQuicServers[] = "quic_servers";
+const char kServerInfoKey[] = "server_info";
const char kUsedQuicKey[] = "used_quic";
const char kAddressKey[] = "address";
-const char kAlternateProtocolKey[] = "alternate_protocol";
const char kAlternativeServiceKey[] = "alternative_service";
const char kProtocolKey[] = "protocol_str";
const char kHostKey[] = "host";
@@ -309,7 +308,7 @@ bool HttpServerPropertiesManager::SetSpdySetting(
const HostPortPair& host_port_pair,
SpdySettingsIds id,
SpdySettingsFlags flags,
- uint32 value) {
+ uint32_t value) {
DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
bool persist = http_server_properties_impl_->SetSpdySetting(
host_port_pair, id, flags, value);
@@ -384,6 +383,43 @@ HttpServerPropertiesManager::server_network_stats_map() const {
return http_server_properties_impl_->server_network_stats_map();
}
+bool HttpServerPropertiesManager::SetQuicServerInfo(
+ const QuicServerId& server_id,
+ const std::string& server_info) {
+ DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
+ bool changed =
+ http_server_properties_impl_->SetQuicServerInfo(server_id, server_info);
+ if (changed)
+ ScheduleUpdatePrefsOnNetworkThread(SET_QUIC_SERVER_INFO);
+ return changed;
+}
+
+const std::string* HttpServerPropertiesManager::GetQuicServerInfo(
+ const QuicServerId& server_id) {
+ DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
+ return http_server_properties_impl_->GetQuicServerInfo(server_id);
+}
+
+const QuicServerInfoMap& HttpServerPropertiesManager::quic_server_info_map()
+ const {
+ DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
+ return http_server_properties_impl_->quic_server_info_map();
+}
+
+size_t HttpServerPropertiesManager::max_server_configs_stored_in_properties()
+ const {
+ DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
+ return http_server_properties_impl_
+ ->max_server_configs_stored_in_properties();
+}
+
+void HttpServerPropertiesManager::SetMaxServerConfigsStoredInProperties(
+ size_t max_server_configs_stored_in_properties) {
+ DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
+ return http_server_properties_impl_->SetMaxServerConfigsStoredInProperties(
+ max_server_configs_stored_in_properties);
+}
+
//
// Update the HttpServerPropertiesImpl's cache with data from preferences.
//
@@ -423,43 +459,119 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread() {
return;
}
- // The properties for a given server is in
- // http_server_properties_dict["servers"][server].
- const base::DictionaryValue* servers_dict = NULL;
- if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
- kServersKey, &servers_dict)) {
- DVLOG(1) << "Malformed http_server_properties for servers.";
- return;
+ const base::DictionaryValue* servers_dict = nullptr;
+ const base::ListValue* servers_list = nullptr;
+ if (version < 4) {
+ // The properties for a given server is in
+ // http_server_properties_dict["servers"][server].
+ // Before Version 4, server data was stored in the following format in
+ // alphabetical order.
+ //
+ // "http_server_properties": {
+ // "servers": {
+ // "0-edge-chat.facebook.com:443" : {...},
+ // "0.client-channel.google.com:443" : {...},
+ // "yt3.ggpht.com:443" : {...},
+ // ...
+ // }, ...
+ // },
+ if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
+ kServersKey, &servers_dict)) {
+ DVLOG(1) << "Malformed http_server_properties for servers.";
+ return;
+ }
+ } else {
+ // From Version 4 onwards, data was stored in the following format.
+ // |servers| are saved in MRU order.
+ //
+ // "http_server_properties": {
+ // "servers": [
+ // {"yt3.ggpht.com:443" : {...}},
+ // {"0.client-channel.google.com:443" : {...}},
+ // {"0-edge-chat.facebook.com:443" : {...}},
+ // ...
+ // ], ...
+ // },
+ if (!http_server_properties_dict.GetListWithoutPathExpansion(
+ kServersKey, &servers_list)) {
+ DVLOG(1) << "Malformed http_server_properties for servers list.";
+ return;
+ }
}
IPAddressNumber* addr = new IPAddressNumber;
ReadSupportsQuic(http_server_properties_dict, addr);
// String is host/port pair of spdy server.
- scoped_ptr<StringVector> spdy_servers(new StringVector);
+ scoped_ptr<ServerList> spdy_servers(new ServerList);
scoped_ptr<SpdySettingsMap> spdy_settings_map(
new SpdySettingsMap(kMaxSpdySettingsHostsToPersist));
scoped_ptr<AlternativeServiceMap> alternative_service_map(
new AlternativeServiceMap(kMaxAlternateProtocolHostsToPersist));
scoped_ptr<ServerNetworkStatsMap> server_network_stats_map(
new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist));
+ scoped_ptr<QuicServerInfoMap> quic_server_info_map(
+ new QuicServerInfoMap(QuicServerInfoMap::NO_AUTO_EVICT));
+
+ if (version < 4) {
+ if (!AddServersData(*servers_dict, spdy_servers.get(),
+ spdy_settings_map.get(), alternative_service_map.get(),
+ server_network_stats_map.get())) {
+ detected_corrupted_prefs = true;
+ }
+ } else {
+ for (base::ListValue::const_iterator it = servers_list->begin();
+ it != servers_list->end(); ++it) {
+ if (!(*it)->GetAsDictionary(&servers_dict)) {
+ DVLOG(1) << "Malformed http_server_properties for servers dictionary.";
+ detected_corrupted_prefs = true;
+ continue;
+ }
+ if (!AddServersData(
+ *servers_dict, spdy_servers.get(), spdy_settings_map.get(),
+ alternative_service_map.get(), server_network_stats_map.get())) {
+ detected_corrupted_prefs = true;
+ }
+ }
+ }
+
+ if (!AddToQuicServerInfoMap(http_server_properties_dict,
+ quic_server_info_map.get())) {
+ detected_corrupted_prefs = true;
+ }
+
+ network_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread,
+ base::Unretained(this), base::Owned(spdy_servers.release()),
+ base::Owned(spdy_settings_map.release()),
+ base::Owned(alternative_service_map.release()), base::Owned(addr),
+ base::Owned(server_network_stats_map.release()),
+ base::Owned(quic_server_info_map.release()),
+ detected_corrupted_prefs));
+}
- for (base::DictionaryValue::Iterator it(*servers_dict); !it.IsAtEnd();
+bool HttpServerPropertiesManager::AddServersData(
+ const base::DictionaryValue& servers_dict,
+ ServerList* spdy_servers,
+ SpdySettingsMap* spdy_settings_map,
+ AlternativeServiceMap* alternative_service_map,
+ ServerNetworkStatsMap* network_stats_map) {
+ for (base::DictionaryValue::Iterator it(servers_dict); !it.IsAtEnd();
it.Advance()) {
// Get server's host/pair.
const std::string& server_str = it.key();
HostPortPair server = HostPortPair::FromString(server_str);
if (server.host().empty()) {
DVLOG(1) << "Malformed http_server_properties for server: " << server_str;
- detected_corrupted_prefs = true;
- continue;
+ return false;
}
- const base::DictionaryValue* server_pref_dict = NULL;
+ const base::DictionaryValue* server_pref_dict = nullptr;
if (!it.value().GetAsDictionary(&server_pref_dict)) {
DVLOG(1) << "Malformed http_server_properties server: " << server_str;
- detected_corrupted_prefs = true;
- continue;
+ return false;
}
// Get if server supports Spdy.
@@ -469,24 +581,14 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread() {
spdy_servers->push_back(server_str);
}
- AddToSpdySettingsMap(server, *server_pref_dict, spdy_settings_map.get());
+ AddToSpdySettingsMap(server, *server_pref_dict, spdy_settings_map);
if (!AddToAlternativeServiceMap(server, *server_pref_dict,
- alternative_service_map.get()) ||
- !AddToNetworkStatsMap(server, *server_pref_dict,
- server_network_stats_map.get())) {
- detected_corrupted_prefs = true;
+ alternative_service_map) ||
+ !AddToNetworkStatsMap(server, *server_pref_dict, network_stats_map)) {
+ return false;
}
}
-
- network_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread,
- base::Unretained(this), base::Owned(spdy_servers.release()),
- base::Owned(spdy_settings_map.release()),
- base::Owned(alternative_service_map.release()), base::Owned(addr),
- base::Owned(server_network_stats_map.release()),
- detected_corrupted_prefs));
+ return true;
}
void HttpServerPropertiesManager::AddToSpdySettingsMap(
@@ -495,7 +597,7 @@ void HttpServerPropertiesManager::AddToSpdySettingsMap(
SpdySettingsMap* spdy_settings_map) {
// Get SpdySettings.
DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end());
- const base::DictionaryValue* spdy_settings_dict = NULL;
+ const base::DictionaryValue* spdy_settings_dict = nullptr;
if (!server_pref_dict.GetDictionaryWithoutPathExpansion(
kSettingsKey, &spdy_settings_dict)) {
return;
@@ -562,7 +664,7 @@ bool HttpServerPropertiesManager::ParseAlternativeServiceDict(
return false;
}
alternative_service_info->alternative_service.port =
- static_cast<uint32>(port);
+ static_cast<uint32_t>(port);
// Probability is optional, defaults to 1.0.
alternative_service_info->probability = 1.0;
@@ -585,7 +687,7 @@ bool HttpServerPropertiesManager::ParseAlternativeServiceDict(
std::string expiration_string;
if (alternative_service_dict.GetStringWithoutPathExpansion(
kExpirationKey, &expiration_string)) {
- int64 expiration_int64 = 0;
+ int64_t expiration_int64 = 0;
if (!base::StringToInt64(expiration_string, &expiration_int64)) {
DVLOG(1) << "Malformed alternative service expiration for server: "
<< server_str;
@@ -596,16 +698,6 @@ bool HttpServerPropertiesManager::ParseAlternativeServiceDict(
return true;
}
- // Early release 46 Dev and Canary versions stored expiration as double.
- // TODO(bnc) Remove the following code parsing double around 2015-10-01.
- double expiration_double;
- if (alternative_service_dict.GetDoubleWithoutPathExpansion(
- kExpirationKey, &expiration_double)) {
- alternative_service_info->expiration =
- base::Time::FromDoubleT(expiration_double);
- return true;
- }
-
DVLOG(1) << "Malformed alternative service expiration for server: "
<< server_str;
return false;
@@ -617,40 +709,28 @@ bool HttpServerPropertiesManager::AddToAlternativeServiceMap(
AlternativeServiceMap* alternative_service_map) {
DCHECK(alternative_service_map->Peek(server) ==
alternative_service_map->end());
- // Get alternative_services...
const base::ListValue* alternative_service_list;
- const base::DictionaryValue* alternative_service_dict;
+ if (!server_pref_dict.GetListWithoutPathExpansion(
+ kAlternativeServiceKey, &alternative_service_list)) {
+ return true;
+ }
+
AlternativeServiceInfoVector alternative_service_info_vector;
- if (server_pref_dict.GetListWithoutPathExpansion(kAlternativeServiceKey,
- &alternative_service_list)) {
- for (const base::Value* alternative_service_list_item :
- *alternative_service_list) {
- if (!alternative_service_list_item->GetAsDictionary(
- &alternative_service_dict))
- return false;
- AlternativeServiceInfo alternative_service_info;
- if (!ParseAlternativeServiceDict(*alternative_service_dict,
- server.ToString(),
- &alternative_service_info)) {
- return false;
- }
- alternative_service_info_vector.push_back(alternative_service_info);
- }
- } else {
- // ...or alternate_protocol.
- // TODO(bnc): Remove this in M46, we do not need preference migration for
- // long.
- if (!server_pref_dict.GetDictionaryWithoutPathExpansion(
- kAlternateProtocolKey, &alternative_service_dict)) {
- return true;
- }
+ for (const base::Value* alternative_service_list_item :
+ *alternative_service_list) {
+ const base::DictionaryValue* alternative_service_dict;
+ if (!alternative_service_list_item->GetAsDictionary(
+ &alternative_service_dict))
+ return false;
AlternativeServiceInfo alternative_service_info;
if (!ParseAlternativeServiceDict(*alternative_service_dict,
server.ToString(),
&alternative_service_info)) {
return false;
}
- alternative_service_info_vector.push_back(alternative_service_info);
+ if (base::Time::Now() < alternative_service_info.expiration) {
+ alternative_service_info_vector.push_back(alternative_service_info);
+ }
}
if (alternative_service_info_vector.empty()) {
@@ -664,7 +744,7 @@ bool HttpServerPropertiesManager::AddToAlternativeServiceMap(
bool HttpServerPropertiesManager::ReadSupportsQuic(
const base::DictionaryValue& http_server_properties_dict,
IPAddressNumber* last_quic_address) {
- const base::DictionaryValue* supports_quic_dict = NULL;
+ const base::DictionaryValue* supports_quic_dict = nullptr;
if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
kSupportsQuicKey, &supports_quic_dict)) {
return true;
@@ -693,7 +773,7 @@ bool HttpServerPropertiesManager::AddToNetworkStatsMap(
const base::DictionaryValue& server_pref_dict,
ServerNetworkStatsMap* network_stats_map) {
DCHECK(network_stats_map->Peek(server) == network_stats_map->end());
- const base::DictionaryValue* server_network_stats_dict = NULL;
+ const base::DictionaryValue* server_network_stats_dict = nullptr;
if (!server_pref_dict.GetDictionaryWithoutPathExpansion(
kNetworkStatsKey, &server_network_stats_dict)) {
return true;
@@ -713,12 +793,57 @@ bool HttpServerPropertiesManager::AddToNetworkStatsMap(
return true;
}
+bool HttpServerPropertiesManager::AddToQuicServerInfoMap(
+ const base::DictionaryValue& http_server_properties_dict,
+ QuicServerInfoMap* quic_server_info_map) {
+ const base::DictionaryValue* quic_servers_dict = nullptr;
+ if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
+ kQuicServers, &quic_servers_dict)) {
+ DVLOG(1) << "Malformed http_server_properties for quic_servers.";
+ return true;
+ }
+
+ bool detected_corrupted_prefs = false;
+ for (base::DictionaryValue::Iterator it(*quic_servers_dict); !it.IsAtEnd();
+ it.Advance()) {
+ // Get quic_server_id.
+ const std::string& quic_server_id_str = it.key();
+ QuicServerId quic_server_id = QuicServerId::FromString(quic_server_id_str);
+ if (quic_server_id.host().empty()) {
+ DVLOG(1) << "Malformed http_server_properties for quic server: "
+ << quic_server_id_str;
+ detected_corrupted_prefs = true;
+ continue;
+ }
+
+ const base::DictionaryValue* quic_server_pref_dict = nullptr;
+ if (!it.value().GetAsDictionary(&quic_server_pref_dict)) {
+ DVLOG(1) << "Malformed http_server_properties quic server dict: "
+ << quic_server_id_str;
+ detected_corrupted_prefs = true;
+ continue;
+ }
+
+ std::string quic_server_info;
+ if (!quic_server_pref_dict->GetStringWithoutPathExpansion(
+ kServerInfoKey, &quic_server_info)) {
+ DVLOG(1) << "Malformed http_server_properties quic server info: "
+ << quic_server_id_str;
+ detected_corrupted_prefs = true;
+ continue;
+ }
+ quic_server_info_map->Put(quic_server_id, quic_server_info);
+ }
+ return !detected_corrupted_prefs;
+}
+
void HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread(
- StringVector* spdy_servers,
+ ServerList* spdy_servers,
SpdySettingsMap* spdy_settings_map,
AlternativeServiceMap* alternative_service_map,
IPAddressNumber* last_quic_address,
ServerNetworkStatsMap* server_network_stats_map,
+ QuicServerInfoMap* quic_server_info_map,
bool detected_corrupted_prefs) {
// Preferences have the master data because admins might have pushed new
// preferences. Update the cached data with new data from preferences.
@@ -744,6 +869,9 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread(
http_server_properties_impl_->InitializeServerNetworkStats(
server_network_stats_map);
+ http_server_properties_impl_->InitializeQuicServerInfoMap(
+ quic_server_info_map);
+
// Update the prefs with what we have read (delete all corrupted prefs).
if (detected_corrupted_prefs)
ScheduleUpdatePrefsOnNetworkThread(DETECTED_CORRUPTED_PREFS);
@@ -784,6 +912,7 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
const base::Closure& completion) {
DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
+ // It is in MRU order.
base::ListValue* spdy_server_list = new base::ListValue;
http_server_properties_impl_->GetSpdyServerList(
spdy_server_list, kMaxSupportsSpdyServerHostsToPersist);
@@ -793,8 +922,9 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
const SpdySettingsMap& main_map =
http_server_properties_impl_->spdy_settings_map();
int count = 0;
- for (SpdySettingsMap::const_iterator it = main_map.begin();
- it != main_map.end() && count < kMaxSpdySettingsHostsToPersist;
+ // Maintain MRU order.
+ for (SpdySettingsMap::const_reverse_iterator it = main_map.rbegin();
+ it != main_map.rend() && count < kMaxSpdySettingsHostsToPersist;
++it, ++count) {
spdy_settings_map->Put(it->first, it->second);
}
@@ -803,20 +933,26 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
new AlternativeServiceMap(kMaxAlternateProtocolHostsToPersist);
const AlternativeServiceMap& map =
http_server_properties_impl_->alternative_service_map();
+ UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers.Memory",
+ map.size());
count = 0;
typedef std::map<std::string, bool> CanonicalHostPersistedMap;
CanonicalHostPersistedMap persisted_map;
- for (AlternativeServiceMap::const_iterator it = map.begin();
- it != map.end() && count < kMaxAlternateProtocolHostsToPersist; ++it) {
+ // Maintain MRU order.
+ for (AlternativeServiceMap::const_reverse_iterator it = map.rbegin();
+ it != map.rend() && count < kMaxAlternateProtocolHostsToPersist; ++it) {
const HostPortPair& server = it->first;
AlternativeServiceInfoVector notbroken_alternative_service_info_vector;
for (const AlternativeServiceInfo& alternative_service_info : it->second) {
- if (!IsAlternateProtocolValid(
- alternative_service_info.alternative_service.protocol)) {
+ // Do not persist expired entries.
+ if (alternative_service_info.expiration < base::Time::Now()) {
continue;
}
AlternativeService alternative_service(
alternative_service_info.alternative_service);
+ if (!IsAlternateProtocolValid(alternative_service.protocol)) {
+ continue;
+ }
if (alternative_service.host.empty()) {
alternative_service.host = server.host();
}
@@ -829,8 +965,6 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
if (notbroken_alternative_service_info_vector.empty()) {
continue;
}
- alternative_service_map->Put(server,
- notbroken_alternative_service_info_vector);
std::string canonical_suffix =
http_server_properties_impl_->GetCanonicalSuffix(server.host());
if (!canonical_suffix.empty()) {
@@ -838,19 +972,36 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
continue;
persisted_map[canonical_suffix] = true;
}
+ alternative_service_map->Put(server,
+ notbroken_alternative_service_info_vector);
++count;
}
ServerNetworkStatsMap* server_network_stats_map =
new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist);
- const ServerNetworkStatsMap& main_server_network_stats_map =
+ const ServerNetworkStatsMap& network_stats_map =
http_server_properties_impl_->server_network_stats_map();
- for (ServerNetworkStatsMap::const_iterator it =
- main_server_network_stats_map.begin();
- it != main_server_network_stats_map.end(); ++it) {
+ count = 0;
+ for (ServerNetworkStatsMap::const_reverse_iterator
+ it = network_stats_map.rbegin();
+ it != network_stats_map.rend() &&
+ count < kMaxServerNetworkStatsHostsToPersist;
+ ++it, ++count) {
server_network_stats_map->Put(it->first, it->second);
}
+ QuicServerInfoMap* quic_server_info_map = nullptr;
+ const QuicServerInfoMap& main_quic_server_info_map =
+ http_server_properties_impl_->quic_server_info_map();
+ if (main_quic_server_info_map.size() > 0) {
+ quic_server_info_map =
+ new QuicServerInfoMap(max_server_configs_stored_in_properties());
+ for (const std::pair<const QuicServerId, std::string>& entry :
+ main_quic_server_info_map) {
+ quic_server_info_map->Put(entry.first, entry.second);
+ }
+ }
+
IPAddressNumber* last_quic_addr = new IPAddressNumber;
http_server_properties_impl_->GetSupportsQuic(last_quic_addr);
// Update the preferences on the pref thread.
@@ -860,7 +1011,8 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
&HttpServerPropertiesManager::UpdatePrefsOnPrefThread, pref_weak_ptr_,
base::Owned(spdy_server_list), base::Owned(spdy_settings_map),
base::Owned(alternative_service_map), base::Owned(last_quic_addr),
- base::Owned(server_network_stats_map), completion));
+ base::Owned(server_network_stats_map),
+ base::Owned(quic_server_info_map), completion));
}
// A local or temporary data structure to hold |supports_spdy|, SpdySettings,
@@ -869,10 +1021,10 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
struct ServerPref {
ServerPref()
: supports_spdy(false),
- settings_map(NULL),
- alternative_service_info_vector(NULL),
- supports_quic(NULL),
- server_network_stats(NULL) {}
+ settings_map(nullptr),
+ alternative_service_info_vector(nullptr),
+ supports_quic(nullptr),
+ server_network_stats(nullptr) {}
ServerPref(
bool supports_spdy,
const SettingsMap* settings_map,
@@ -891,61 +1043,89 @@ struct ServerPref {
const ServerNetworkStats* server_network_stats;
};
+// All maps and lists are in MRU order.
void HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
base::ListValue* spdy_server_list,
SpdySettingsMap* spdy_settings_map,
AlternativeServiceMap* alternative_service_map,
IPAddressNumber* last_quic_address,
ServerNetworkStatsMap* server_network_stats_map,
+ QuicServerInfoMap* quic_server_info_map,
const base::Closure& completion) {
- typedef std::map<HostPortPair, ServerPref> ServerPrefMap;
- ServerPrefMap server_pref_map;
+ typedef base::MRUCache<HostPortPair, ServerPref> ServerPrefMap;
+ ServerPrefMap server_pref_map(ServerPrefMap::NO_AUTO_EVICT);
DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
- // Add servers that support spdy to server_pref_map.
- std::string s;
- for (base::ListValue::const_iterator list_it = spdy_server_list->begin();
- list_it != spdy_server_list->end();
- ++list_it) {
- if ((*list_it)->GetAsString(&s)) {
+ // Add servers that support spdy to server_pref_map in the MRU order.
+ for (size_t index = spdy_server_list->GetSize(); index > 0; --index) {
+ std::string s;
+ if (spdy_server_list->GetString(index - 1, &s)) {
HostPortPair server = HostPortPair::FromString(s);
- server_pref_map[server].supports_spdy = true;
+ ServerPrefMap::iterator it = server_pref_map.Get(server);
+ if (it == server_pref_map.end()) {
+ ServerPref server_pref;
+ server_pref.supports_spdy = true;
+ server_pref_map.Put(server, server_pref);
+ } else {
+ it->second.supports_spdy = true;
+ }
}
}
- // Add servers that have SpdySettings to server_pref_map.
- for (SpdySettingsMap::iterator map_it = spdy_settings_map->begin();
- map_it != spdy_settings_map->end(); ++map_it) {
+ // Add servers that have SpdySettings to server_pref_map in the MRU order.
+ for (SpdySettingsMap::reverse_iterator map_it = spdy_settings_map->rbegin();
+ map_it != spdy_settings_map->rend(); ++map_it) {
const HostPortPair& server = map_it->first;
- server_pref_map[server].settings_map = &map_it->second;
+ ServerPrefMap::iterator it = server_pref_map.Get(server);
+ if (it == server_pref_map.end()) {
+ ServerPref server_pref;
+ server_pref.settings_map = &map_it->second;
+ server_pref_map.Put(server, server_pref);
+ } else {
+ it->second.settings_map = &map_it->second;
+ }
}
- // Add alternative services to server_pref_map.
- for (AlternativeServiceMap::const_iterator map_it =
- alternative_service_map->begin();
- map_it != alternative_service_map->end(); ++map_it) {
- server_pref_map[map_it->first].alternative_service_info_vector =
- &map_it->second;
+ // Add alternative services to server_pref_map in the MRU order.
+ for (AlternativeServiceMap::const_reverse_iterator map_it =
+ alternative_service_map->rbegin();
+ map_it != alternative_service_map->rend(); ++map_it) {
+ const HostPortPair& server = map_it->first;
+ ServerPrefMap::iterator it = server_pref_map.Get(server);
+ if (it == server_pref_map.end()) {
+ ServerPref server_pref;
+ server_pref.alternative_service_info_vector = &map_it->second;
+ server_pref_map.Put(server, server_pref);
+ } else {
+ it->second.alternative_service_info_vector = &map_it->second;
+ }
}
- // Add ServerNetworkStats servers to server_pref_map.
- for (ServerNetworkStatsMap::const_iterator map_it =
- server_network_stats_map->begin();
- map_it != server_network_stats_map->end(); ++map_it) {
+ // Add ServerNetworkStats servers to server_pref_map in the MRU order.
+ for (ServerNetworkStatsMap::const_reverse_iterator map_it =
+ server_network_stats_map->rbegin();
+ map_it != server_network_stats_map->rend(); ++map_it) {
const HostPortPair& server = map_it->first;
- server_pref_map[server].server_network_stats = &map_it->second;
+ ServerPrefMap::iterator it = server_pref_map.Get(server);
+ if (it == server_pref_map.end()) {
+ ServerPref server_pref;
+ server_pref.server_network_stats = &map_it->second;
+ server_pref_map.Put(server, server_pref);
+ } else {
+ it->second.server_network_stats = &map_it->second;
+ }
}
- // Persist properties to the |path_|.
+ // Persist properties to the |path_| in the MRU order.
base::DictionaryValue http_server_properties_dict;
- base::DictionaryValue* servers_dict = new base::DictionaryValue;
- for (ServerPrefMap::const_iterator map_it = server_pref_map.begin();
- map_it != server_pref_map.end();
- ++map_it) {
+ base::ListValue* servers_list = new base::ListValue;
+ for (ServerPrefMap::const_reverse_iterator map_it = server_pref_map.rbegin();
+ map_it != server_pref_map.rend(); ++map_it) {
const HostPortPair& server = map_it->first;
const ServerPref& server_pref = map_it->second;
+ base::DictionaryValue* servers_dict = new base::DictionaryValue;
base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
// Save supports_spdy.
@@ -958,14 +1138,19 @@ void HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
server_pref_dict);
servers_dict->SetWithoutPathExpansion(server.ToString(), server_pref_dict);
+ bool value = servers_list->AppendIfNotPresent(servers_dict);
+ DCHECK(value); // Should never happen.
}
http_server_properties_dict.SetWithoutPathExpansion(kServersKey,
- servers_dict);
+ servers_list);
SetVersion(&http_server_properties_dict, kVersionNumber);
SaveSupportsQuicToPrefs(last_quic_address, &http_server_properties_dict);
+ SaveQuicServerInfoMapToServerPrefs(quic_server_info_map,
+ &http_server_properties_dict);
+
setting_prefs_ = true;
pref_service_->Set(path_, http_server_properties_dict);
setting_prefs_ = false;
@@ -988,7 +1173,7 @@ void HttpServerPropertiesManager::SaveSpdySettingsToServerPrefs(
for (SettingsMap::const_iterator it = settings_map->begin();
it != settings_map->end(); ++it) {
SpdySettingsIds id = it->first;
- uint32 value = it->second.second;
+ uint32_t value = it->second.second;
std::string key = base::StringPrintf("%u", id);
spdy_settings_dict->SetInteger(key, value);
}
@@ -1017,7 +1202,7 @@ void HttpServerPropertiesManager::SaveAlternativeServiceToServerPrefs(
kProtocolKey, AlternateProtocolToString(alternative_service.protocol));
alternative_service_dict->SetDouble(kProbabilityKey,
alternative_service_info.probability);
- // JSON cannot store int64, so expiration is converted to a string.
+ // JSON cannot store int64_t, so expiration is converted to a string.
alternative_service_dict->SetString(
kExpirationKey,
base::Int64ToString(
@@ -1051,7 +1236,7 @@ void HttpServerPropertiesManager::SaveNetworkStatsToServerPrefs(
return;
base::DictionaryValue* server_network_stats_dict = new base::DictionaryValue;
- // Becasue JSON doesn't support int64, persist int64 as a string.
+ // Becasue JSON doesn't support int64_t, persist int64_t as a string.
server_network_stats_dict->SetInteger(
kSrttKey, static_cast<int>(server_network_stats->srtt.ToInternalValue()));
// TODO(rtenneti): When QUIC starts using bandwidth_estimate, then persist
@@ -1060,6 +1245,26 @@ void HttpServerPropertiesManager::SaveNetworkStatsToServerPrefs(
server_network_stats_dict);
}
+void HttpServerPropertiesManager::SaveQuicServerInfoMapToServerPrefs(
+ QuicServerInfoMap* quic_server_info_map,
+ base::DictionaryValue* http_server_properties_dict) {
+ if (!quic_server_info_map)
+ return;
+
+ base::DictionaryValue* quic_servers_dict = new base::DictionaryValue;
+ for (const std::pair<QuicServerId, std::string>& entry :
+ *quic_server_info_map) {
+ const QuicServerId& server_id = entry.first;
+ base::DictionaryValue* quic_server_pref_dict = new base::DictionaryValue;
+ quic_server_pref_dict->SetStringWithoutPathExpansion(kServerInfoKey,
+ entry.second);
+ quic_servers_dict->SetWithoutPathExpansion(server_id.ToString(),
+ quic_server_pref_dict);
+ }
+ http_server_properties_dict->SetWithoutPathExpansion(kQuicServers,
+ quic_servers_dict);
+}
+
void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() {
DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
if (!setting_prefs_)
diff --git a/chromium/net/http/http_server_properties_manager.h b/chromium/net/http/http_server_properties_manager.h
index 1e09ff7a75d..b08ae16d20a 100644
--- a/chromium/net/http/http_server_properties_manager.h
+++ b/chromium/net/http/http_server_properties_manager.h
@@ -5,12 +5,14 @@
#ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_MANAGER_H_
#define NET_HTTP_HTTP_SERVER_PROPERTIES_MANAGER_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/prefs/pref_change_registrar.h"
@@ -116,7 +118,7 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
bool SetSpdySetting(const HostPortPair& host_port_pair,
SpdySettingsIds id,
SpdySettingsFlags flags,
- uint32 value) override;
+ uint32_t value) override;
void ClearSpdySettings(const HostPortPair& host_port_pair) override;
void ClearAllSpdySettings() override;
const SpdySettingsMap& spdy_settings_map() const override;
@@ -128,6 +130,13 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
const ServerNetworkStats* GetServerNetworkStats(
const HostPortPair& host_port_pair) override;
const ServerNetworkStatsMap& server_network_stats_map() const override;
+ bool SetQuicServerInfo(const QuicServerId& server_id,
+ const std::string& server_info) override;
+ const std::string* GetQuicServerInfo(const QuicServerId& server_id) override;
+ const QuicServerInfoMap& quic_server_info_map() const override;
+ size_t max_server_configs_stored_in_properties() const override;
+ void SetMaxServerConfigsStoredInProperties(
+ size_t max_server_configs_stored_in_properties) override;
protected:
// The location where ScheduleUpdatePrefsOnNetworkThread was called.
@@ -145,7 +154,8 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
SET_SUPPORTS_QUIC = 10,
SET_SERVER_NETWORK_STATS = 11,
DETECTED_CORRUPTED_PREFS = 12,
- NUM_LOCATIONS = 13,
+ SET_QUIC_SERVER_INFO = 13,
+ NUM_LOCATIONS = 14,
};
// --------------------
@@ -174,6 +184,7 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
AlternativeServiceMap* alternative_service_map,
IPAddressNumber* last_quic_address,
ServerNetworkStatsMap* server_network_stats_map,
+ QuicServerInfoMap* quic_server_info_map,
bool detected_corrupted_prefs);
// These are used to delay updating the preferences when cached data in
@@ -204,17 +215,23 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
AlternativeServiceMap* alternative_service_map,
IPAddressNumber* last_quic_address,
ServerNetworkStatsMap* server_network_stats_map,
+ QuicServerInfoMap* quic_server_info_map,
const base::Closure& completion);
private:
+ typedef std::vector<std::string> ServerList;
+
FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest,
AddToAlternativeServiceMap);
FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest,
- AlternativeServiceExpirationDouble);
+ DoNotLoadExpiredAlternativeService);
void OnHttpServerPropertiesChanged();
- bool ReadSupportsQuic(const base::DictionaryValue& server_dict,
- IPAddressNumber* last_quic_address);
+ bool AddServersData(const base::DictionaryValue& server_dict,
+ ServerList* spdy_servers,
+ SpdySettingsMap* spdy_settings_map,
+ AlternativeServiceMap* alternative_service_map,
+ ServerNetworkStatsMap* network_stats_map);
void AddToSpdySettingsMap(const HostPortPair& server,
const base::DictionaryValue& server_dict,
SpdySettingsMap* spdy_settings_map);
@@ -226,21 +243,27 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
const HostPortPair& server,
const base::DictionaryValue& server_dict,
AlternativeServiceMap* alternative_service_map);
+ bool ReadSupportsQuic(const base::DictionaryValue& server_dict,
+ IPAddressNumber* last_quic_address);
bool AddToNetworkStatsMap(const HostPortPair& server,
const base::DictionaryValue& server_dict,
ServerNetworkStatsMap* network_stats_map);
+ bool AddToQuicServerInfoMap(const base::DictionaryValue& server_dict,
+ QuicServerInfoMap* quic_server_info_map);
void SaveSpdySettingsToServerPrefs(const SettingsMap* spdy_settings_map,
base::DictionaryValue* server_pref_dict);
void SaveAlternativeServiceToServerPrefs(
const AlternativeServiceInfoVector* alternative_service_info_vector,
base::DictionaryValue* server_pref_dict);
+ void SaveSupportsQuicToPrefs(
+ const IPAddressNumber* last_quic_address,
+ base::DictionaryValue* http_server_properties_dict);
void SaveNetworkStatsToServerPrefs(
const ServerNetworkStats* server_network_stats,
base::DictionaryValue* server_pref_dict);
-
- void SaveSupportsQuicToPrefs(
- const IPAddressNumber* last_quic_address,
+ void SaveQuicServerInfoMapToServerPrefs(
+ QuicServerInfoMap* quic_server_info_map,
base::DictionaryValue* http_server_properties_dict);
// -----------
diff --git a/chromium/net/http/http_server_properties_manager_unittest.cc b/chromium/net/http/http_server_properties_manager_unittest.cc
index 2164bb52485..49d19db177e 100644
--- a/chromium/net/http/http_server_properties_manager_unittest.cc
+++ b/chromium/net/http/http_server_properties_manager_unittest.cc
@@ -4,9 +4,9 @@
#include "net/http/http_server_properties_manager.h"
-#include "base/basictypes.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/testing_pref_service.h"
@@ -83,19 +83,22 @@ class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager {
MOCK_METHOD0(UpdateCacheFromPrefsOnPrefThread, void());
MOCK_METHOD1(UpdatePrefsFromCacheOnNetworkThread, void(const base::Closure&));
MOCK_METHOD1(ScheduleUpdatePrefsOnNetworkThread, void(Location location));
- MOCK_METHOD6(UpdateCacheFromPrefsOnNetworkThread,
+ MOCK_METHOD7(UpdateCacheFromPrefsOnNetworkThread,
void(std::vector<std::string>* spdy_servers,
SpdySettingsMap* spdy_settings_map,
AlternativeServiceMap* alternative_service_map,
IPAddressNumber* last_quic_address,
ServerNetworkStatsMap* server_network_stats_map,
+ QuicServerInfoMap* quic_server_info_map,
bool detected_corrupted_prefs));
- MOCK_METHOD5(UpdatePrefsOnPref,
+ MOCK_METHOD7(UpdatePrefsOnPrefThread,
void(base::ListValue* spdy_server_list,
SpdySettingsMap* spdy_settings_map,
AlternativeServiceMap* alternative_service_map,
IPAddressNumber* last_quic_address,
- ServerNetworkStatsMap* server_network_stats_map));
+ ServerNetworkStatsMap* server_network_stats_map,
+ QuicServerInfoMap* quic_server_info_map,
+ const base::Closure& completion));
private:
DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager);
@@ -103,7 +106,11 @@ class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager {
} // namespace
-class HttpServerPropertiesManagerTest : public testing::Test {
+// TODO(rtenneti): After we stop supporting version 3 and everyone has migrated
+// to version 4, delete the following code.
+static const int kHttpServerPropertiesVersions[] = {3, 4};
+
+class HttpServerPropertiesManagerTest : public testing::TestWithParam<int> {
protected:
HttpServerPropertiesManagerTest() {}
@@ -180,7 +187,11 @@ class HttpServerPropertiesManagerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
};
-TEST_F(HttpServerPropertiesManagerTest,
+INSTANTIATE_TEST_CASE_P(Tests,
+ HttpServerPropertiesManagerTest,
+ ::testing::ValuesIn(kHttpServerPropertiesVersions));
+
+TEST_P(HttpServerPropertiesManagerTest,
SingleUpdateForTwoSpdyServerPrefChanges) {
ExpectCacheUpdate();
@@ -201,11 +212,11 @@ TEST_F(HttpServerPropertiesManagerTest,
base::DictionaryValue* alternative_service_dict1 = new base::DictionaryValue;
alternative_service_dict1->SetInteger("port", 1234);
alternative_service_dict1->SetString("protocol_str", "quic");
- base::ListValue* alternative_service_list = new base::ListValue;
- alternative_service_list->Append(alternative_service_dict0);
- alternative_service_list->Append(alternative_service_dict1);
+ base::ListValue* alternative_service_list0 = new base::ListValue;
+ alternative_service_list0->Append(alternative_service_dict0);
+ alternative_service_list0->Append(alternative_service_dict1);
server_pref_dict->SetWithoutPathExpansion("alternative_service",
- alternative_service_list);
+ alternative_service_list0);
// Set up ServerNetworkStats for www.google.com:80.
base::DictionaryValue* stats = new base::DictionaryValue;
@@ -215,6 +226,13 @@ TEST_F(HttpServerPropertiesManagerTest,
// Set the server preference for www.google.com:80.
base::DictionaryValue* servers_dict = new base::DictionaryValue;
servers_dict->SetWithoutPathExpansion("www.google.com:80", server_pref_dict);
+ base::ListValue* servers_list = nullptr;
+ if (GetParam() == 4) {
+ servers_list = new base::ListValue;
+ // |servers_list| takes ownership of |servers_dict|.
+ servers_list->AppendIfNotPresent(servers_dict);
+ servers_dict = new base::DictionaryValue;
+ }
// Set the preference for mail.google.com server.
base::DictionaryValue* server_pref_dict1 = new base::DictionaryValue;
@@ -222,32 +240,73 @@ TEST_F(HttpServerPropertiesManagerTest,
// Set supports_spdy for mail.google.com:80
server_pref_dict1->SetBoolean("supports_spdy", true);
- // Set up alternate_protocol for mail.google.com:80 to test migration to
- // alternative_service.
- base::DictionaryValue* alternate_protocol_dict = new base::DictionaryValue;
- alternate_protocol_dict->SetString("protocol_str", "npn-spdy/3.1");
- alternate_protocol_dict->SetInteger("port", 444);
- server_pref_dict1->SetWithoutPathExpansion("alternate_protocol",
- alternate_protocol_dict);
+ // Set up alternative_services for mail.google.com:80.
+ base::DictionaryValue* alternative_service_dict2 = new base::DictionaryValue;
+ alternative_service_dict2->SetString("protocol_str", "npn-spdy/3.1");
+ alternative_service_dict2->SetInteger("port", 444);
+ base::ListValue* alternative_service_list1 = new base::ListValue;
+ alternative_service_list1->Append(alternative_service_dict2);
+ server_pref_dict1->SetWithoutPathExpansion("alternative_service",
+ alternative_service_list1);
- // Set up ServerNetworkStats for mail.google.com:80.
+ // Set up ServerNetworkStats for mail.google.com:80 and it is the MRU server.
base::DictionaryValue* stats1 = new base::DictionaryValue;
stats1->SetInteger("srtt", 20);
server_pref_dict1->SetWithoutPathExpansion("network_stats", stats1);
// Set the server preference for mail.google.com:80.
servers_dict->SetWithoutPathExpansion("mail.google.com:80",
server_pref_dict1);
-
base::DictionaryValue* http_server_properties_dict =
new base::DictionaryValue;
- HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
- http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
+ if (GetParam() == 4) {
+ // |servers_list| takes ownership of |servers_dict|.
+ servers_list->AppendIfNotPresent(servers_dict);
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_list);
+ } else {
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict,
+ GetParam());
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_dict);
+ }
base::DictionaryValue* supports_quic = new base::DictionaryValue;
supports_quic->SetBoolean("used_quic", true);
supports_quic->SetString("address", "127.0.0.1");
http_server_properties_dict->SetWithoutPathExpansion("supports_quic",
supports_quic);
+ // Set quic_server_info for www.google.com:80, mail.google.com:80 and
+ // play.google.com:80 and verify the MRU.
+ http_server_props_manager_->SetMaxServerConfigsStoredInProperties(3);
+ base::DictionaryValue* quic_servers_dict = new base::DictionaryValue;
+ base::DictionaryValue* quic_server_pref_dict1 = new base::DictionaryValue;
+ std::string quic_server_info1("quic_server_info1");
+ quic_server_pref_dict1->SetStringWithoutPathExpansion("server_info",
+ quic_server_info1);
+ base::DictionaryValue* quic_server_pref_dict2 = new base::DictionaryValue;
+ std::string quic_server_info2("quic_server_info2");
+ quic_server_pref_dict2->SetStringWithoutPathExpansion("server_info",
+ quic_server_info2);
+ base::DictionaryValue* quic_server_pref_dict3 = new base::DictionaryValue;
+ std::string quic_server_info3("quic_server_info3");
+ quic_server_pref_dict3->SetStringWithoutPathExpansion("server_info",
+ quic_server_info3);
+ // Set the quic_server_info1 for www.google.com server.
+ QuicServerId google_quic_server_id("www.google.com", 80);
+ quic_servers_dict->SetWithoutPathExpansion(google_quic_server_id.ToString(),
+ quic_server_pref_dict1);
+ // Set the quic_server_info2 for mail.google.com server.
+ QuicServerId mail_quic_server_id("mail.google.com", 80);
+ quic_servers_dict->SetWithoutPathExpansion(mail_quic_server_id.ToString(),
+ quic_server_pref_dict2);
+ // Set the quic_server_info3 for play.google.com server.
+ QuicServerId play_quic_server_id("play.google.com", 80);
+ quic_servers_dict->SetWithoutPathExpansion(play_quic_server_id.ToString(),
+ quic_server_pref_dict3);
+ http_server_properties_dict->SetWithoutPathExpansion("quic_servers",
+ quic_servers_dict);
+
// Set the same value for kHttpServerProperties multiple times.
pref_service_.SetManagedPref(kTestHttpServerProperties,
http_server_properties_dict);
@@ -267,24 +326,46 @@ TEST_F(HttpServerPropertiesManagerTest,
HostPortPair::FromString("foo.google.com:1337")));
// Verify alternative service.
- const AlternativeServiceMap& map =
- http_server_props_manager_->alternative_service_map();
- ASSERT_EQ(2u, map.size());
- AlternativeServiceMap::const_iterator map_it = map.begin();
- EXPECT_EQ("www.google.com", map_it->first.host());
- ASSERT_EQ(2u, map_it->second.size());
- EXPECT_EQ(NPN_HTTP_2, map_it->second[0].alternative_service.protocol);
- EXPECT_TRUE(map_it->second[0].alternative_service.host.empty());
- EXPECT_EQ(443, map_it->second[0].alternative_service.port);
- EXPECT_EQ(QUIC, map_it->second[1].alternative_service.protocol);
- EXPECT_TRUE(map_it->second[1].alternative_service.host.empty());
- EXPECT_EQ(1234, map_it->second[1].alternative_service.port);
- ++map_it;
- EXPECT_EQ("mail.google.com", map_it->first.host());
- ASSERT_EQ(1u, map_it->second.size());
- EXPECT_EQ(NPN_SPDY_3_1, map_it->second[0].alternative_service.protocol);
- EXPECT_TRUE(map_it->second[0].alternative_service.host.empty());
- EXPECT_EQ(444, map_it->second[0].alternative_service.port);
+ if (GetParam() == 4) {
+ const AlternativeServiceMap& map =
+ http_server_props_manager_->alternative_service_map();
+ ASSERT_EQ(2u, map.size());
+
+ AlternativeServiceMap::const_iterator map_it = map.begin();
+ EXPECT_EQ("mail.google.com", map_it->first.host());
+ ASSERT_EQ(1u, map_it->second.size());
+ EXPECT_EQ(NPN_SPDY_3_1, map_it->second[0].alternative_service.protocol);
+ EXPECT_TRUE(map_it->second[0].alternative_service.host.empty());
+ EXPECT_EQ(444, map_it->second[0].alternative_service.port);
+ ++map_it;
+ EXPECT_EQ("www.google.com", map_it->first.host());
+ ASSERT_EQ(2u, map_it->second.size());
+ EXPECT_EQ(NPN_HTTP_2, map_it->second[0].alternative_service.protocol);
+ EXPECT_TRUE(map_it->second[0].alternative_service.host.empty());
+ EXPECT_EQ(443, map_it->second[0].alternative_service.port);
+ EXPECT_EQ(QUIC, map_it->second[1].alternative_service.protocol);
+ EXPECT_TRUE(map_it->second[1].alternative_service.host.empty());
+ EXPECT_EQ(1234, map_it->second[1].alternative_service.port);
+ } else {
+ const AlternativeServiceMap& map =
+ http_server_props_manager_->alternative_service_map();
+ ASSERT_EQ(2u, map.size());
+ AlternativeServiceMap::const_iterator map_it = map.begin();
+ EXPECT_EQ("www.google.com", map_it->first.host());
+ ASSERT_EQ(2u, map_it->second.size());
+ EXPECT_EQ(NPN_HTTP_2, map_it->second[0].alternative_service.protocol);
+ EXPECT_TRUE(map_it->second[0].alternative_service.host.empty());
+ EXPECT_EQ(443, map_it->second[0].alternative_service.port);
+ EXPECT_EQ(QUIC, map_it->second[1].alternative_service.protocol);
+ EXPECT_TRUE(map_it->second[1].alternative_service.host.empty());
+ EXPECT_EQ(1234, map_it->second[1].alternative_service.port);
+ ++map_it;
+ EXPECT_EQ("mail.google.com", map_it->first.host());
+ ASSERT_EQ(1u, map_it->second.size());
+ EXPECT_EQ(NPN_SPDY_3_1, map_it->second[0].alternative_service.protocol);
+ EXPECT_TRUE(map_it->second[0].alternative_service.host.empty());
+ EXPECT_EQ(444, map_it->second[0].alternative_service.port);
+ }
// Verify SupportsQuic.
IPAddressNumber last_address;
@@ -298,9 +379,26 @@ TEST_F(HttpServerPropertiesManagerTest,
const ServerNetworkStats* stats3 =
http_server_props_manager_->GetServerNetworkStats(mail_server);
EXPECT_EQ(20, stats3->srtt.ToInternalValue());
+
+ // Verify QuicServerInfo.
+ EXPECT_EQ(quic_server_info1, *http_server_props_manager_->GetQuicServerInfo(
+ google_quic_server_id));
+ EXPECT_EQ(quic_server_info2, *http_server_props_manager_->GetQuicServerInfo(
+ mail_quic_server_id));
+ EXPECT_EQ(quic_server_info3, *http_server_props_manager_->GetQuicServerInfo(
+ play_quic_server_id));
+
+ // Verify the MRU order.
+ http_server_props_manager_->SetMaxServerConfigsStoredInProperties(2);
+ EXPECT_EQ(nullptr, http_server_props_manager_->GetQuicServerInfo(
+ google_quic_server_id));
+ EXPECT_EQ(quic_server_info2, *http_server_props_manager_->GetQuicServerInfo(
+ mail_quic_server_id));
+ EXPECT_EQ(quic_server_info3, *http_server_props_manager_->GetQuicServerInfo(
+ play_quic_server_id));
}
-TEST_F(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
+TEST_P(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
ExpectCacheUpdate();
// The prefs are automaticalls updated in the case corruption is detected.
ExpectPrefsUpdate();
@@ -329,11 +427,32 @@ TEST_F(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
base::DictionaryValue* servers_dict = new base::DictionaryValue;
servers_dict->SetWithoutPathExpansion("www.google.com:65536",
server_pref_dict);
-
base::DictionaryValue* http_server_properties_dict =
new base::DictionaryValue;
- HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
- http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
+ if (GetParam() == 4) {
+ base::ListValue* servers_list = new base::ListValue;
+ // |servers_list| takes ownership of |servers_dict|.
+ servers_list->AppendIfNotPresent(servers_dict);
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_list);
+ } else {
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict,
+ GetParam());
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_dict);
+ }
+
+ // Set quic_server_info for www.google.com:65536.
+ base::DictionaryValue* quic_servers_dict = new base::DictionaryValue;
+ base::DictionaryValue* quic_server_pref_dict1 = new base::DictionaryValue;
+ quic_server_pref_dict1->SetStringWithoutPathExpansion("server_info",
+ "quic_server_info1");
+ quic_servers_dict->SetWithoutPathExpansion("http://mail.google.com:65536",
+ quic_server_pref_dict1);
+
+ http_server_properties_dict->SetWithoutPathExpansion("quic_servers",
+ quic_servers_dict);
// Set up the pref.
pref_service_.SetManagedPref(kTestHttpServerProperties,
@@ -350,10 +469,11 @@ TEST_F(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
const ServerNetworkStats* stats1 =
http_server_props_manager_->GetServerNetworkStats(
HostPortPair::FromString("www.google.com:65536"));
- EXPECT_EQ(NULL, stats1);
+ EXPECT_EQ(nullptr, stats1);
+ EXPECT_EQ(0u, http_server_props_manager_->quic_server_info_map().size());
}
-TEST_F(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
+TEST_P(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
ExpectCacheUpdate();
// The prefs are automaticalls updated in the case corruption is detected.
ExpectPrefsUpdate();
@@ -376,11 +496,21 @@ TEST_F(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
// Set the server preference for www.google.com:80.
base::DictionaryValue* servers_dict = new base::DictionaryValue;
servers_dict->SetWithoutPathExpansion("www.google.com:80", server_pref_dict);
-
base::DictionaryValue* http_server_properties_dict =
new base::DictionaryValue;
- HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
- http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
+ if (GetParam() == 4) {
+ base::ListValue* servers_list = new base::ListValue;
+ // |servers_list| takes ownership of |servers_dict|.
+ servers_list->AppendIfNotPresent(servers_dict);
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_list);
+ } else {
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict,
+ GetParam());
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_dict);
+ }
// Set up the pref.
pref_service_.SetManagedPref(kTestHttpServerProperties,
@@ -394,7 +524,7 @@ TEST_F(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
HasAlternativeService(HostPortPair::FromString("www.google.com:80")));
}
-TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
+TEST_P(HttpServerPropertiesManagerTest, SupportsSpdy) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThread();
@@ -417,7 +547,7 @@ TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
}
-TEST_F(HttpServerPropertiesManagerTest, SetSpdySetting) {
+TEST_P(HttpServerPropertiesManagerTest, SetSpdySetting) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThread();
@@ -425,7 +555,7 @@ TEST_F(HttpServerPropertiesManagerTest, SetSpdySetting) {
HostPortPair spdy_server_mail("mail.google.com", 443);
const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH;
const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value1 = 31337;
+ const uint32_t value1 = 31337;
http_server_props_manager_->SetSpdySetting(
spdy_server_mail, id1, flags1, value1);
@@ -444,7 +574,7 @@ TEST_F(HttpServerPropertiesManagerTest, SetSpdySetting) {
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
}
-TEST_F(HttpServerPropertiesManagerTest, ClearSpdySetting) {
+TEST_P(HttpServerPropertiesManagerTest, ClearSpdySetting) {
ExpectPrefsUpdateRepeatedly();
ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
@@ -452,7 +582,7 @@ TEST_F(HttpServerPropertiesManagerTest, ClearSpdySetting) {
HostPortPair spdy_server_mail("mail.google.com", 443);
const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH;
const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value1 = 31337;
+ const uint32_t value1 = 31337;
http_server_props_manager_->SetSpdySetting(
spdy_server_mail, id1, flags1, value1);
@@ -483,7 +613,7 @@ TEST_F(HttpServerPropertiesManagerTest, ClearSpdySetting) {
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
}
-TEST_F(HttpServerPropertiesManagerTest, ClearAllSpdySetting) {
+TEST_P(HttpServerPropertiesManagerTest, ClearAllSpdySetting) {
ExpectPrefsUpdateRepeatedly();
ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
@@ -491,7 +621,7 @@ TEST_F(HttpServerPropertiesManagerTest, ClearAllSpdySetting) {
HostPortPair spdy_server_mail("mail.google.com", 443);
const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH;
const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value1 = 31337;
+ const uint32_t value1 = 31337;
http_server_props_manager_->SetSpdySetting(
spdy_server_mail, id1, flags1, value1);
@@ -521,7 +651,7 @@ TEST_F(HttpServerPropertiesManagerTest, ClearAllSpdySetting) {
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
}
-TEST_F(HttpServerPropertiesManagerTest, GetAlternativeServices) {
+TEST_P(HttpServerPropertiesManagerTest, GetAlternativeServices) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThread();
@@ -545,7 +675,7 @@ TEST_F(HttpServerPropertiesManagerTest, GetAlternativeServices) {
EXPECT_EQ(alternative_service, alternative_service_vector[0]);
}
-TEST_F(HttpServerPropertiesManagerTest, SetAlternativeServices) {
+TEST_P(HttpServerPropertiesManagerTest, SetAlternativeServices) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThread();
@@ -576,7 +706,7 @@ TEST_F(HttpServerPropertiesManagerTest, SetAlternativeServices) {
EXPECT_EQ(alternative_service2, alternative_service_vector[1]);
}
-TEST_F(HttpServerPropertiesManagerTest, SetAlternativeServicesEmpty) {
+TEST_P(HttpServerPropertiesManagerTest, SetAlternativeServicesEmpty) {
HostPortPair spdy_server_mail("mail.google.com", 80);
EXPECT_FALSE(HasAlternativeService(spdy_server_mail));
const AlternativeService alternative_service(NPN_HTTP_2, "mail.google.com",
@@ -592,7 +722,7 @@ TEST_F(HttpServerPropertiesManagerTest, SetAlternativeServicesEmpty) {
EXPECT_FALSE(HasAlternativeService(spdy_server_mail));
}
-TEST_F(HttpServerPropertiesManagerTest, ClearAlternativeServices) {
+TEST_P(HttpServerPropertiesManagerTest, ClearAlternativeServices) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThread();
@@ -613,7 +743,7 @@ TEST_F(HttpServerPropertiesManagerTest, ClearAlternativeServices) {
EXPECT_FALSE(HasAlternativeService(spdy_server_mail));
}
-TEST_F(HttpServerPropertiesManagerTest, ConfirmAlternativeService) {
+TEST_P(HttpServerPropertiesManagerTest, ConfirmAlternativeService) {
ExpectPrefsUpdate();
HostPortPair spdy_server_mail("mail.google.com", 80);
@@ -659,7 +789,7 @@ TEST_F(HttpServerPropertiesManagerTest, ConfirmAlternativeService) {
alternative_service));
}
-TEST_F(HttpServerPropertiesManagerTest, SupportsQuic) {
+TEST_P(HttpServerPropertiesManagerTest, SupportsQuic) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThread();
@@ -680,14 +810,14 @@ TEST_F(HttpServerPropertiesManagerTest, SupportsQuic) {
EXPECT_EQ(actual_address, address);
}
-TEST_F(HttpServerPropertiesManagerTest, ServerNetworkStats) {
+TEST_P(HttpServerPropertiesManagerTest, ServerNetworkStats) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThread();
HostPortPair mail_server("mail.google.com", 80);
const ServerNetworkStats* stats =
http_server_props_manager_->GetServerNetworkStats(mail_server);
- EXPECT_EQ(NULL, stats);
+ EXPECT_EQ(nullptr, stats);
ServerNetworkStats stats1;
stats1.srtt = base::TimeDelta::FromMicroseconds(10);
http_server_props_manager_->SetServerNetworkStats(mail_server, stats1);
@@ -703,7 +833,29 @@ TEST_F(HttpServerPropertiesManagerTest, ServerNetworkStats) {
EXPECT_EQ(10, stats2->srtt.ToInternalValue());
}
-TEST_F(HttpServerPropertiesManagerTest, Clear) {
+TEST_P(HttpServerPropertiesManagerTest, QuicServerInfo) {
+ ExpectPrefsUpdate();
+ ExpectScheduleUpdatePrefsOnNetworkThread();
+
+ QuicServerId mail_quic_server_id("mail.google.com", 80);
+ EXPECT_EQ(nullptr,
+ http_server_props_manager_->GetQuicServerInfo(mail_quic_server_id));
+ std::string quic_server_info1("quic_server_info1");
+ http_server_props_manager_->SetQuicServerInfo(mail_quic_server_id,
+ quic_server_info1);
+ // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
+ http_server_props_manager_->SetQuicServerInfo(mail_quic_server_id,
+ quic_server_info1);
+
+ // Run the task.
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+
+ EXPECT_EQ(quic_server_info1, *http_server_props_manager_->GetQuicServerInfo(
+ mail_quic_server_id));
+}
+
+TEST_P(HttpServerPropertiesManagerTest, Clear) {
ExpectPrefsUpdate();
ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
@@ -719,11 +871,16 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
stats.srtt = base::TimeDelta::FromMicroseconds(10);
http_server_props_manager_->SetServerNetworkStats(spdy_server_mail, stats);
+ QuicServerId mail_quic_server_id("mail.google.com", 80);
+ std::string quic_server_info1("quic_server_info1");
+ http_server_props_manager_->SetQuicServerInfo(mail_quic_server_id,
+ quic_server_info1);
+
const SpdySettingsIds id1 = SETTINGS_UPLOAD_BANDWIDTH;
const SpdySettingsFlags flags1 = SETTINGS_FLAG_PLEASE_PERSIST;
- const uint32 value1 = 31337;
- http_server_props_manager_->SetSpdySetting(
- spdy_server_mail, id1, flags1, value1);
+ const uint32_t value1 = 31337;
+ http_server_props_manager_->SetSpdySetting(spdy_server_mail, id1, flags1,
+ value1);
// Run the task.
base::RunLoop().RunUntilIdle();
@@ -737,6 +894,8 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
const ServerNetworkStats* stats1 =
http_server_props_manager_->GetServerNetworkStats(spdy_server_mail);
EXPECT_EQ(10, stats1->srtt.ToInternalValue());
+ EXPECT_EQ(quic_server_info1, *http_server_props_manager_->GetQuicServerInfo(
+ mail_quic_server_id));
// Check SPDY settings values.
const SettingsMap& settings_map1_ret =
@@ -753,7 +912,7 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
ExpectPrefsUpdate();
// Clear http server data, time out if we do not get a completion callback.
- http_server_props_manager_->Clear(base::MessageLoop::QuitClosure());
+ http_server_props_manager_->Clear(base::MessageLoop::QuitWhenIdleClosure());
base::RunLoop().Run();
EXPECT_FALSE(
@@ -762,7 +921,9 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
EXPECT_FALSE(http_server_props_manager_->GetSupportsQuic(&address));
const ServerNetworkStats* stats2 =
http_server_props_manager_->GetServerNetworkStats(spdy_server_mail);
- EXPECT_EQ(NULL, stats2);
+ EXPECT_EQ(nullptr, stats2);
+ EXPECT_EQ(nullptr,
+ http_server_props_manager_->GetQuicServerInfo(mail_quic_server_id));
const SettingsMap& settings_map2_ret =
http_server_props_manager_->GetSpdySettings(spdy_server_mail);
@@ -773,10 +934,13 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
// https://crbug.com/444956: Add 200 alternative_service servers followed by
// supports_quic and verify we have read supports_quic from prefs.
-TEST_F(HttpServerPropertiesManagerTest, BadSupportsQuic) {
+TEST_P(HttpServerPropertiesManagerTest, BadSupportsQuic) {
ExpectCacheUpdate();
base::DictionaryValue* servers_dict = new base::DictionaryValue;
+ base::ListValue* servers_list = nullptr;
+ if (GetParam() == 4)
+ servers_list = new base::ListValue;
for (int i = 0; i < 200; ++i) {
// Set up alternative_service for www.google.com:i.
@@ -788,8 +952,16 @@ TEST_F(HttpServerPropertiesManagerTest, BadSupportsQuic) {
base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
server_pref_dict->SetWithoutPathExpansion("alternative_service",
alternative_service_list);
- servers_dict->SetWithoutPathExpansion(StringPrintf("www.google.com:%d", i),
- server_pref_dict);
+ if (GetParam() == 4) {
+ servers_dict->SetWithoutPathExpansion(
+ StringPrintf("www.google.com:%d", i), server_pref_dict);
+ // |servers_list| takes ownership of |servers_dict|.
+ servers_list->AppendIfNotPresent(servers_dict);
+ servers_dict = new base::DictionaryValue;
+ } else {
+ servers_dict->SetWithoutPathExpansion(
+ StringPrintf("www.google.com:%d", i), server_pref_dict);
+ }
}
// Set the preference for mail.google.com server.
@@ -798,11 +970,20 @@ TEST_F(HttpServerPropertiesManagerTest, BadSupportsQuic) {
// Set the server preference for mail.google.com:80.
servers_dict->SetWithoutPathExpansion("mail.google.com:80",
server_pref_dict1);
-
base::DictionaryValue* http_server_properties_dict =
new base::DictionaryValue;
- HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
- http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
+ if (GetParam() == 4) {
+ // |servers_list| takes ownership of |servers_dict|.
+ servers_list->AppendIfNotPresent(servers_dict);
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_list);
+ } else {
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict,
+ GetParam());
+ http_server_properties_dict->SetWithoutPathExpansion("servers",
+ servers_dict);
+ }
// Set up SupportsQuic for 127.0.0.1
base::DictionaryValue* supports_quic = new base::DictionaryValue;
@@ -835,7 +1016,7 @@ TEST_F(HttpServerPropertiesManagerTest, BadSupportsQuic) {
EXPECT_EQ("127.0.0.1", IPAddressToString(address));
}
-TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
+TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
const HostPortPair server_www("www.google.com", 80);
@@ -868,6 +1049,12 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
stats.srtt = base::TimeDelta::FromInternalValue(42);
http_server_props_manager_->SetServerNetworkStats(server_mail, stats);
+ // Set quic_server_info string.
+ QuicServerId mail_quic_server_id("mail.google.com", 80);
+ std::string quic_server_info1("quic_server_info1");
+ http_server_props_manager_->SetQuicServerInfo(mail_quic_server_id,
+ quic_server_info1);
+
// Set SupportsQuic.
IPAddressNumber actual_address;
CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address));
@@ -881,16 +1068,21 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
// Verify preferences.
const char expected_json[] =
- "{\"servers\":{\"mail.google.com:80\":{\"alternative_service\":[{"
- "\"expiration\":\"9223372036854775807\",\"host\":\"foo.google.com\","
- "\"port\":444,\"probability\":0.2,\"protocol_str\":\"npn-spdy/3.1\"}],"
- "\"network_stats\":{\"srtt\":42}},\"www.google.com:80\":{"
+ "{\"quic_servers\":{\"https://"
+ "mail.google.com:80\":{\"server_info\":\"quic_server_info1\"}},"
+ "\"servers\":["
+ "{\"www.google.com:80\":{"
"\"alternative_service\":[{\"expiration\":\"13756212000000000\","
"\"port\":443,\"probability\":1.0,\"protocol_str\":\"npn-h2\"},"
"{\"expiration\":\"13758804000000000\",\"host\":\"www.google.com\","
"\"port\":1234,\"probability\":0.7,\"protocol_str\":\"npn-h2\"}]}},"
+ "{\"mail.google.com:80\":{\"alternative_service\":[{"
+ "\"expiration\":\"9223372036854775807\",\"host\":\"foo.google.com\","
+ "\"port\":444,\"probability\":0.2,\"protocol_str\":\"npn-spdy/3.1\"}],"
+ "\"network_stats\":{\"srtt\":42}}}"
+ "],"
"\"supports_quic\":{\"address\":\"127.0.0.1\",\"used_quic\":true},"
- "\"version\":3}";
+ "\"version\":4}";
const base::Value* http_server_properties =
pref_service_.GetUserPref(kTestHttpServerProperties);
@@ -901,7 +1093,7 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
EXPECT_EQ(expected_json, preferences_json);
}
-TEST_F(HttpServerPropertiesManagerTest, AddToAlternativeServiceMap) {
+TEST_P(HttpServerPropertiesManagerTest, AddToAlternativeServiceMap) {
scoped_ptr<base::Value> server_value = base::JSONReader::Read(
"{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"npn-h2\"},"
"{\"port\":123,\"protocol_str\":\"quic\",\"probability\":0.7,"
@@ -940,7 +1132,7 @@ TEST_F(HttpServerPropertiesManagerTest, AddToAlternativeServiceMap) {
EXPECT_EQ("", alternative_service_info_vector[1].alternative_service.host);
EXPECT_EQ(123, alternative_service_info_vector[1].alternative_service.port);
EXPECT_DOUBLE_EQ(0.7, alternative_service_info_vector[1].probability);
- // numeric_limits<int64>::max() represents base::Time::Max().
+ // numeric_limits<int64_t>::max() represents base::Time::Max().
EXPECT_EQ(base::Time::Max(), alternative_service_info_vector[1].expiration);
EXPECT_EQ(NPN_HTTP_2,
@@ -955,22 +1147,105 @@ TEST_F(HttpServerPropertiesManagerTest, AddToAlternativeServiceMap) {
EXPECT_EQ(expected_expiration, alternative_service_info_vector[2].expiration);
}
-// Early release 46 Dev and Canary builds serialized alternative service
-// expiration as double. Test that they are properly parsed.
-// TODO(bnc) Remove this test around 2015-10-01,
-// and remove corresponding FRIEND macro from header file.
-TEST_F(HttpServerPropertiesManagerTest, AlternativeServiceExpirationDouble) {
- scoped_ptr<base::Value> server_value = base::JSONReader::Read(
- "{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"npn-h2\","
- "\"expiration\":1234567890.0}]}");
- ASSERT_TRUE(server_value);
- base::DictionaryValue* server_dict;
- ASSERT_TRUE(server_value->GetAsDictionary(&server_dict));
+// Do not persist expired or broken alternative service entries to disk.
+TEST_P(HttpServerPropertiesManagerTest,
+ DoNotPersistExpiredOrBrokenAlternativeService) {
+ ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
+
+ AlternativeServiceInfoVector alternative_service_info_vector;
+
+ const AlternativeService broken_alternative_service(
+ NPN_HTTP_2, "broken.example.com", 443);
+ const base::Time time_one_day_later =
+ base::Time::Now() + base::TimeDelta::FromDays(1);
+ alternative_service_info_vector.push_back(AlternativeServiceInfo(
+ broken_alternative_service, 1.0, time_one_day_later));
+ http_server_props_manager_->MarkAlternativeServiceBroken(
+ broken_alternative_service);
+
+ const AlternativeService expired_alternative_service(
+ NPN_HTTP_2, "expired.example.com", 443);
+ const base::Time time_one_day_ago =
+ base::Time::Now() - base::TimeDelta::FromDays(1);
+ alternative_service_info_vector.push_back(AlternativeServiceInfo(
+ expired_alternative_service, 1.0, time_one_day_ago));
+
+ const AlternativeService valid_alternative_service(NPN_HTTP_2,
+ "valid.example.com", 443);
+ alternative_service_info_vector.push_back(AlternativeServiceInfo(
+ valid_alternative_service, 1.0, time_one_day_later));
+
+ const HostPortPair host_port_pair("www.example.com", 443);
+ http_server_props_manager_->SetAlternativeServices(
+ host_port_pair, alternative_service_info_vector);
+
+ // Update cache.
+ ExpectPrefsUpdate();
+ ExpectCacheUpdate();
+ http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
+ base::RunLoop().RunUntilIdle();
+
+ const base::Value* pref_value =
+ pref_service_.GetUserPref(kTestHttpServerProperties);
+ ASSERT_NE(nullptr, pref_value);
+
+ const base::DictionaryValue* pref_dict;
+ ASSERT_TRUE(pref_value->GetAsDictionary(&pref_dict));
+
+ const base::ListValue* servers_list = nullptr;
+ ASSERT_TRUE(pref_dict->GetListWithoutPathExpansion("servers", &servers_list));
+ base::ListValue::const_iterator it = servers_list->begin();
+ const base::DictionaryValue* server_pref_dict;
+ ASSERT_TRUE((*it)->GetAsDictionary(&server_pref_dict));
+
+ const base::DictionaryValue* example_pref_dict;
+ ASSERT_TRUE(server_pref_dict->GetDictionaryWithoutPathExpansion(
+ "www.example.com:443", &example_pref_dict));
+
+ const base::ListValue* altsvc_list;
+ ASSERT_TRUE(example_pref_dict->GetList("alternative_service", &altsvc_list));
+
+ ASSERT_EQ(1u, altsvc_list->GetSize());
+
+ const base::DictionaryValue* altsvc_entry;
+ ASSERT_TRUE(altsvc_list->GetDictionary(0, &altsvc_entry));
+
+ std::string hostname;
+ ASSERT_TRUE(altsvc_entry->GetString("host", &hostname));
+ EXPECT_EQ("valid.example.com", hostname);
+}
+
+// Test that expired alternative service entries on disk are ignored.
+TEST_P(HttpServerPropertiesManagerTest, DoNotLoadExpiredAlternativeService) {
+ scoped_ptr<base::ListValue> alternative_service_list(new base::ListValue);
+ base::DictionaryValue* expired_dict = new base::DictionaryValue;
+ expired_dict->SetString("protocol_str", "npn-h2");
+ expired_dict->SetString("host", "expired.example.com");
+ expired_dict->SetInteger("port", 443);
+ expired_dict->SetDouble("probability", 1.0);
+ base::Time time_one_day_ago =
+ base::Time::Now() - base::TimeDelta::FromDays(1);
+ expired_dict->SetString(
+ "expiration", base::Int64ToString(time_one_day_ago.ToInternalValue()));
+ alternative_service_list->Append(expired_dict);
+
+ base::DictionaryValue* valid_dict = new base::DictionaryValue;
+ valid_dict->SetString("protocol_str", "npn-h2");
+ valid_dict->SetString("host", "valid.example.com");
+ valid_dict->SetInteger("port", 443);
+ valid_dict->SetDouble("probability", 1.0);
+ valid_dict->SetString(
+ "expiration", base::Int64ToString(one_day_from_now_.ToInternalValue()));
+ alternative_service_list->Append(valid_dict);
+
+ base::DictionaryValue server_pref_dict;
+ server_pref_dict.SetWithoutPathExpansion("alternative_service",
+ alternative_service_list.release());
const HostPortPair host_port_pair("example.com", 443);
AlternativeServiceMap alternative_service_map(/*max_size=*/5);
- EXPECT_TRUE(http_server_props_manager_->AddToAlternativeServiceMap(
- host_port_pair, *server_dict, &alternative_service_map));
+ ASSERT_TRUE(http_server_props_manager_->AddToAlternativeServiceMap(
+ host_port_pair, server_pref_dict, &alternative_service_map));
AlternativeServiceMap::iterator it =
alternative_service_map.Get(host_port_pair);
@@ -980,17 +1255,14 @@ TEST_F(HttpServerPropertiesManagerTest, AlternativeServiceExpirationDouble) {
EXPECT_EQ(NPN_HTTP_2,
alternative_service_info_vector[0].alternative_service.protocol);
- EXPECT_EQ("", alternative_service_info_vector[0].alternative_service.host);
+ EXPECT_EQ("valid.example.com",
+ alternative_service_info_vector[0].alternative_service.host);
EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service.port);
- // Probability defaults to 1.0.
EXPECT_DOUBLE_EQ(1.0, alternative_service_info_vector[0].probability);
- base::Time expected_expiration;
- ASSERT_TRUE(
- base::Time::FromUTCString("2009-02-13 23:31:30", &expected_expiration));
- EXPECT_EQ(expected_expiration, alternative_service_info_vector[0].expiration);
+ EXPECT_EQ(one_day_from_now_, alternative_service_info_vector[0].expiration);
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
+TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
// Post an update task to the UI thread.
http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
// Shutdown comes before the task is executed.
@@ -1000,7 +1272,7 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
base::RunLoop().RunUntilIdle();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) {
+TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) {
// Post an update task.
http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
// Shutdown comes before the task is executed.
@@ -1012,7 +1284,7 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) {
base::RunLoop().RunUntilIdle();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) {
+TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) {
http_server_props_manager_->UpdateCacheFromPrefsOnUIConcrete();
// Shutdown comes before the task is executed.
http_server_props_manager_->ShutdownOnPrefThread();
@@ -1026,7 +1298,7 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) {
//
// Tests for shutdown when updating prefs.
//
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) {
+TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) {
// Post an update task to the IO thread.
http_server_props_manager_->ScheduleUpdatePrefsOnNetworkThread();
// Shutdown comes before the task is executed.
@@ -1036,7 +1308,7 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) {
base::RunLoop().RunUntilIdle();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) {
+TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) {
ExpectPrefsUpdate();
// Post an update task.
http_server_props_manager_->ScheduleUpdatePrefsOnNetworkThread();
@@ -1049,7 +1321,7 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) {
base::RunLoop().RunUntilIdle();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) {
+TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) {
// This posts a task to the UI thread.
http_server_props_manager_->UpdatePrefsFromCacheOnNetworkThreadConcrete(
base::Closure());
diff --git a/chromium/net/http/http_status_line_validator.h b/chromium/net/http/http_status_line_validator.h
index 1bfa69f878d..1a12cd03e48 100644
--- a/chromium/net/http/http_status_line_validator.h
+++ b/chromium/net/http/http_status_line_validator.h
@@ -5,9 +5,11 @@
#ifndef NET_HTTP_HTTP_STATUS_LINE_VALIDATOR_H_
#define NET_HTTP_HTTP_STATUS_LINE_VALIDATOR_H_
+#include <stddef.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/http/http_stream.h b/chromium/net/http/http_stream.h
index 1febd11ae95..b7e7888ac20 100644
--- a/chromium/net/http/http_stream.h
+++ b/chromium/net/http/http_stream.h
@@ -13,9 +13,10 @@
#include <stdint.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
+#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
#include "net/base/upload_progress.h"
@@ -156,6 +157,11 @@ class NET_EXPORT_PRIVATE HttpStream {
// draining is complete.
virtual void Drain(HttpNetworkSession* session) = 0;
+ // Get the network error details this stream is encountering.
+ // Fills in |details| if it is available; leaves |details| unchanged if it
+ // is unavailable.
+ virtual void PopulateNetErrorDetails(NetErrorDetails* details) = 0;
+
// Called when the priority of the parent transaction changes.
virtual void SetPriority(RequestPriority priority) = 0;
diff --git a/chromium/net/http/http_stream_factory.cc b/chromium/net/http/http_stream_factory.cc
index 1b6e66fccef..d6d76b453c8 100644
--- a/chromium/net/http/http_stream_factory.cc
+++ b/chromium/net/http/http_stream_factory.cc
@@ -13,6 +13,7 @@
#include "net/base/host_port_pair.h"
#include "net/base/port_util.h"
#include "net/http/http_network_session.h"
+#include "net/quic/quic_protocol.h"
#include "net/spdy/spdy_alt_svc_wire_format.h"
#include "url/gurl.h"
@@ -54,6 +55,24 @@ void HttpStreamFactory::ProcessAlternativeService(
!IsPortValid(alternative_service_entry.port)) {
continue;
}
+ // Check if QUIC version is supported.
+ if (protocol == QUIC && !alternative_service_entry.version.empty()) {
+ bool match_found = false;
+ for (QuicVersion supported : session.params().quic_supported_versions) {
+ for (uint16_t advertised : alternative_service_entry.version) {
+ if (supported == advertised) {
+ match_found = true;
+ break;
+ }
+ }
+ if (match_found) {
+ break;
+ }
+ }
+ if (!match_found) {
+ continue;
+ }
+ }
AlternativeService alternative_service(protocol,
alternative_service_entry.host,
alternative_service_entry.port);
@@ -61,7 +80,7 @@ void HttpStreamFactory::ProcessAlternativeService(
base::Time::Now() +
base::TimeDelta::FromSeconds(alternative_service_entry.max_age);
AlternativeServiceInfo alternative_service_info(
- alternative_service, alternative_service_entry.p, expiration);
+ alternative_service, alternative_service_entry.probability, expiration);
alternative_service_info_vector.push_back(alternative_service_info);
}
@@ -133,8 +152,8 @@ void HttpStreamFactory::ProcessAlternateProtocol(
http_server_properties->SetAlternativeService(
RewriteHost(http_host_port_pair),
- AlternativeService(protocol, "", static_cast<uint16>(port)), probability,
- base::Time::Now() + base::TimeDelta::FromDays(1));
+ AlternativeService(protocol, "", static_cast<uint16_t>(port)),
+ probability, base::Time::Now() + base::TimeDelta::FromDays(30));
}
GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
diff --git a/chromium/net/http/http_stream_factory.h b/chromium/net/http/http_stream_factory.h
index 231271dffe7..359f7f0dbda 100644
--- a/chromium/net/http/http_stream_factory.h
+++ b/chromium/net/http/http_stream_factory.h
@@ -8,7 +8,7 @@
#include <list>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "net/base/completion_callback.h"
@@ -33,6 +33,7 @@ namespace net {
class AuthCredentials;
class BoundNetLog;
+class BidirectionalStreamJob;
class HostMappingRules;
class HostPortPair;
class HttpAuthController;
@@ -84,6 +85,11 @@ class NET_EXPORT_PRIVATE HttpStreamRequest {
const ProxyInfo& used_proxy_info,
WebSocketHandshakeStreamBase* stream) = 0;
+ virtual void OnBidirectionalStreamJobReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* 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
@@ -148,6 +154,10 @@ class NET_EXPORT_PRIVATE HttpStreamRequest {
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
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() {}
@@ -222,6 +232,17 @@ class NET_EXPORT HttpStreamFactory {
WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log) = 0;
+ // Request a BidirectionalStreamJob.
+ // Will call delegate->OnBidirectionalStreamJobReady on successful
+ // completion.
+ virtual HttpStreamRequest* RequestBidirectionalStreamJob(
+ const HttpRequestInfo& info,
+ RequestPriority priority,
+ const SSLConfig& server_ssl_config,
+ const SSLConfig& proxy_ssl_config,
+ HttpStreamRequest::Delegate* delegate,
+ const BoundNetLog& net_log) = 0;
+
// Requests that enough connections for |num_streams| be opened.
virtual void PreconnectStreams(int num_streams,
const HttpRequestInfo& info,
diff --git a/chromium/net/http/http_stream_factory_impl.cc b/chromium/net/http/http_stream_factory_impl.cc
index 2a8664e51a6..c9272a8310f 100644
--- a/chromium/net/http/http_stream_factory_impl.cc
+++ b/chromium/net/http/http_stream_factory_impl.cc
@@ -8,15 +8,23 @@
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/strings/string_util.h"
#include "net/base/net_util.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_stream_factory_impl_job.h"
#include "net/http/http_stream_factory_impl_request.h"
+#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
+#include "net/net_features.h"
+#include "net/quic/quic_server_id.h"
#include "net/spdy/spdy_http_stream.h"
#include "url/gurl.h"
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+#include "net/spdy/bidirectional_stream_spdy_job.h"
+#endif
+
namespace net {
HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session,
@@ -75,6 +83,36 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestWebSocketHandshakeStream(
net_log);
}
+HttpStreamRequest* HttpStreamFactoryImpl::RequestBidirectionalStreamJob(
+ const HttpRequestInfo& request_info,
+ RequestPriority priority,
+ const SSLConfig& server_ssl_config,
+ const SSLConfig& proxy_ssl_config,
+ HttpStreamRequest::Delegate* delegate,
+ const BoundNetLog& net_log) {
+ DCHECK(!for_websockets_);
+ DCHECK(request_info.url.SchemeIs(url::kHttpsScheme));
+
+// TODO(xunjieli): Create QUIC's version of BidirectionalStreamJob.
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ HostPortPair server = HostPortPair::FromURL(request_info.url);
+ GURL origin_url = ApplyHostMappingRules(request_info.url, &server);
+ Request* request =
+ new Request(request_info.url, this, delegate, nullptr, net_log,
+ Request::BIDIRECTIONAL_STREAM_SPDY_JOB);
+ Job* job = new Job(this, session_, request_info, priority, server_ssl_config,
+ proxy_ssl_config, server, origin_url, net_log.net_log());
+ request->AttachJob(job);
+
+ job->Start(request);
+ return request;
+
+#else
+ DCHECK(false);
+ return nullptr;
+#endif
+}
+
HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal(
const HttpRequestInfo& request_info,
RequestPriority priority,
@@ -84,27 +122,33 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal(
WebSocketHandshakeStreamBase::CreateHelper*
websocket_handshake_stream_create_helper,
const BoundNetLog& net_log) {
- Request* request = new Request(request_info.url,
- this,
- delegate,
+ Request* request = new Request(request_info.url, this, delegate,
websocket_handshake_stream_create_helper,
- net_log);
+ net_log, Request::HTTP_STREAM);
+ HostPortPair server = HostPortPair::FromURL(request_info.url);
+ GURL origin_url = ApplyHostMappingRules(request_info.url, &server);
+
Job* job = new Job(this, session_, request_info, priority, server_ssl_config,
- proxy_ssl_config, net_log.net_log());
+ proxy_ssl_config, server, origin_url, net_log.net_log());
request->AttachJob(job);
- const AlternativeServiceVector alternative_service_vector =
- GetAlternativeServicesFor(request_info.url);
- if (!alternative_service_vector.empty()) {
- // TODO(bnc): Pass on multiple alternative services to Job.
- const AlternativeService& alternative_service =
- alternative_service_vector[0];
+ const AlternativeService alternative_service =
+ GetAlternativeServiceFor(request_info, delegate);
+
+ if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) {
// Never share connection with other jobs for FTP requests.
+ DVLOG(1) << "Selected alternative service (host: "
+ << alternative_service.host_port_pair().host()
+ << " port: " << alternative_service.host_port_pair().port() << ")";
+
DCHECK(!request_info.url.SchemeIs("ftp"));
+ HostPortPair server = alternative_service.host_port_pair();
+ GURL origin_url = ApplyHostMappingRules(request_info.url, &server);
Job* alternative_job =
new Job(this, session_, request_info, priority, server_ssl_config,
- proxy_ssl_config, alternative_service, net_log.net_log());
+ proxy_ssl_config, server, origin_url, alternative_service,
+ net_log.net_log());
request->AttachJob(alternative_job);
job->WaitFor(alternative_job);
@@ -127,21 +171,28 @@ void HttpStreamFactoryImpl::PreconnectStreams(
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config) {
DCHECK(!for_websockets_);
- AlternativeService alternative_service;
- AlternativeServiceVector alternative_service_vector =
- GetAlternativeServicesFor(request_info.url);
- if (!alternative_service_vector.empty()) {
- // TODO(bnc): Pass on multiple alternative services to Job.
- alternative_service = alternative_service_vector[0];
+ AlternativeService alternative_service =
+ GetAlternativeServiceFor(request_info, nullptr);
+ HostPortPair server;
+ if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) {
+ server = alternative_service.host_port_pair();
+ if (session_->params().quic_disable_preconnect_if_0rtt &&
+ alternative_service.protocol == QUIC &&
+ session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId(
+ alternative_service.host_port_pair(), request_info.privacy_mode))) {
+ return;
+ }
+ } else {
+ server = HostPortPair::FromURL(request_info.url);
}
-
+ GURL origin_url = ApplyHostMappingRules(request_info.url, &server);
// Due to how the socket pools handle priorities and idle sockets, only IDLE
// priority currently makes sense for preconnects. The priority for
// preconnects is currently ignored (see RequestSocketsForPool()), but could
// be used at some point for proxy resolution or something.
- Job* job =
- new Job(this, session_, request_info, IDLE, server_ssl_config,
- proxy_ssl_config, alternative_service, session_->net_log());
+ Job* job = new Job(this, session_, request_info, IDLE, server_ssl_config,
+ proxy_ssl_config, server, origin_url, alternative_service,
+ session_->net_log());
preconnect_job_set_.insert(job);
job->Preconnect(num_streams);
}
@@ -150,10 +201,13 @@ const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const {
return session_->params().host_mapping_rules;
}
-AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
- const GURL& original_url) {
+AlternativeService HttpStreamFactoryImpl::GetAlternativeServiceFor(
+ const HttpRequestInfo& request_info,
+ HttpStreamRequest::Delegate* delegate) {
+ GURL original_url = request_info.url;
+
if (original_url.SchemeIs("ftp"))
- return AlternativeServiceVector();
+ return AlternativeService();
HostPortPair origin = HostPortPair::FromURL(original_url);
HttpServerProperties& http_server_properties =
@@ -161,15 +215,22 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
const AlternativeServiceVector alternative_service_vector =
http_server_properties.GetAlternativeServices(origin);
if (alternative_service_vector.empty())
- return AlternativeServiceVector();
+ return AlternativeService();
+
+ bool quic_advertised = false;
+ bool quic_all_broken = true;
const bool enable_different_host =
session_->params().use_alternative_services;
- AlternativeServiceVector enabled_alternative_service_vector;
+ // First Alt-Svc that is not marked as broken.
+ AlternativeService first_alternative_service;
+
for (const AlternativeService& alternative_service :
alternative_service_vector) {
DCHECK(IsAlternateProtocolValid(alternative_service.protocol));
+ if (!quic_advertised && alternative_service.protocol == QUIC)
+ quic_advertised = true;
if (http_server_properties.IsAlternativeServiceBroken(
alternative_service)) {
HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN);
@@ -200,25 +261,46 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
if (session_->HasSpdyExclusion(origin))
continue;
- enabled_alternative_service_vector.push_back(alternative_service);
+ // Cache this entry if we don't have a non-broken Alt-Svc yet.
+ if (first_alternative_service.protocol ==
+ UNINITIALIZED_ALTERNATE_PROTOCOL)
+ first_alternative_service = alternative_service;
continue;
}
DCHECK_EQ(QUIC, alternative_service.protocol);
+ quic_all_broken = false;
if (!session_->params().enable_quic)
continue;
if (session_->quic_stream_factory()->IsQuicDisabled(origin.port()))
continue;
- if (!session_->params().enable_insecure_quic &&
- !original_url.SchemeIs("https")) {
+ if (!original_url.SchemeIs("https"))
continue;
- }
- enabled_alternative_service_vector.push_back(alternative_service);
+ // Check whether there's an existing session to use for this QUIC Alt-Svc.
+ HostPortPair destination = alternative_service.host_port_pair();
+ std::string origin_host =
+ ApplyHostMappingRules(request_info.url, &destination).host();
+ QuicServerId server_id(destination, request_info.privacy_mode);
+ if (session_->quic_stream_factory()->CanUseExistingSession(
+ server_id, request_info.privacy_mode, origin_host))
+ return alternative_service;
+
+ if (!IsQuicWhitelistedForHost(destination.host()))
+ continue;
+
+ // Cache this entry if we don't have a non-broken Alt-Svc yet.
+ if (first_alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL)
+ first_alternative_service = alternative_service;
}
- return enabled_alternative_service_vector;
+
+ // Ask delegate to mark QUIC as broken for the origin.
+ if (quic_advertised && quic_all_broken && delegate != nullptr)
+ delegate->OnQuicBroken();
+
+ return first_alternative_service;
}
void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) {
@@ -260,12 +342,18 @@ void HttpStreamFactoryImpl::OnNewSpdySessionReady(
// TODO(ricea): Restore this code path when WebSocket over SPDY
// implementation is ready.
NOTREACHED();
+ } else if (request->for_bidirectional()) {
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ request->OnBidirectionalStreamJobReady(
+ nullptr, used_ssl_config, used_proxy_info,
+ new BidirectionalStreamSpdyJob(spdy_session));
+#else
+ DCHECK(false);
+#endif
} else {
bool use_relative_url = direct || request->url().SchemeIs("https");
request->OnStreamReady(
- NULL,
- used_ssl_config,
- used_proxy_info,
+ nullptr, used_ssl_config, used_proxy_info,
new SpdyHttpStream(spdy_session, use_relative_url));
}
}
@@ -283,4 +371,16 @@ void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) {
OnPreconnectsCompleteInternal();
}
+bool HttpStreamFactoryImpl::IsQuicWhitelistedForHost(const std::string& host) {
+ if (session_->params().transport_security_state->IsGooglePinnedHost(host))
+ return true;
+
+ std::string lower_host = base::ToLowerASCII(host);
+ if (ContainsKey(session_->params().quic_host_whitelist, lower_host))
+ return true;
+
+ return base::EndsWith(lower_host, ".snapchat.com",
+ base::CompareCase::SENSITIVE);
+}
+
} // namespace net
diff --git a/chromium/net/http/http_stream_factory_impl.h b/chromium/net/http/http_stream_factory_impl.h
index 1ac451dd99e..799398f539e 100644
--- a/chromium/net/http/http_stream_factory_impl.h
+++ b/chromium/net/http/http_stream_factory_impl.h
@@ -5,11 +5,14 @@
#ifndef NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_
#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_
+#include <stddef.h>
+
#include <map>
#include <set>
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/host_port_pair.h"
#include "net/http/http_stream_factory.h"
@@ -48,6 +51,14 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log) override;
+ HttpStreamRequest* RequestBidirectionalStreamJob(
+ const HttpRequestInfo& info,
+ RequestPriority priority,
+ const SSLConfig& server_ssl_config,
+ const SSLConfig& proxy_ssl_config,
+ HttpStreamRequest::Delegate* delegate,
+ const BoundNetLog& net_log) override;
+
void PreconnectStreams(int num_streams,
const HttpRequestInfo& info,
const SSLConfig& server_ssl_config,
@@ -74,7 +85,9 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log);
- AlternativeServiceVector GetAlternativeServicesFor(const GURL& original_url);
+ AlternativeService GetAlternativeServiceFor(
+ const HttpRequestInfo& request_info,
+ HttpStreamRequest::Delegate* delegate);
// Detaches |job| from |request|.
void OrphanJob(Job* job, const Request* request);
@@ -105,6 +118,10 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
// Called when the Preconnect completes. Used for testing.
virtual void OnPreconnectsCompleteInternal() {}
+ // Returns true if QUIC is whitelisted for |host|, which should be
+ // the result of calling ApplyHostMappingRules().
+ bool IsQuicWhitelistedForHost(const std::string& host);
+
HttpNetworkSession* const session_;
// All Requests are handed out to clients. By the time HttpStreamFactoryImpl
diff --git a/chromium/net/http/http_stream_factory_impl_job.cc b/chromium/net/http/http_stream_factory_impl_job.cc
index a9bd728d5dd..791a390dac5 100644
--- a/chromium/net/http/http_stream_factory_impl_job.cc
+++ b/chromium/net/http/http_stream_factory_impl_job.cc
@@ -6,12 +6,14 @@
#include <algorithm>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/profiler/scoped_tracker.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -42,11 +44,18 @@
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_client_socket_pool.h"
#include "net/spdy/spdy_http_stream.h"
+#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/ssl/ssl_cert_request_info.h"
+#include "net/ssl/ssl_connection_status_flags.h"
#include "net/ssl/ssl_failure_state.h"
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+#include "net/http/bidirectional_stream_job.h"
+#include "net/spdy/bidirectional_stream_spdy_job.h"
+#endif
+
namespace net {
// Returns parameters associated with the start of a HTTP stream job.
@@ -64,7 +73,7 @@ scoped_ptr<base::Value> NetLogHttpStreamJobCallback(
dict->SetString("url", url->GetOrigin().spec());
dict->SetString("alternative_service", alternative_service->ToString());
dict->SetString("priority", RequestPriorityToString(priority));
- return dict.Pass();
+ return std::move(dict);
}
// Returns parameters associated with the Proto (with NPN negotiation) of a HTTP
@@ -78,7 +87,7 @@ scoped_ptr<base::Value> NetLogHttpStreamProtoCallback(
dict->SetString("next_proto_status",
SSLClientSocket::NextProtoStatusToString(status));
dict->SetString("proto", *proto);
- return dict.Pass();
+ return std::move(dict);
}
HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
@@ -87,6 +96,8 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
+ HostPortPair server,
+ GURL origin_url,
NetLog* net_log)
: Job(stream_factory,
session,
@@ -94,9 +105,10 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
priority,
server_ssl_config,
proxy_ssl_config,
+ server,
+ origin_url,
AlternativeService(),
- net_log) {
-}
+ net_log) {}
HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
HttpNetworkSession* session,
@@ -104,6 +116,8 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
+ HostPortPair server,
+ GURL origin_url,
AlternativeService alternative_service,
NetLog* net_log)
: request_(NULL),
@@ -118,6 +132,8 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
stream_factory_(stream_factory),
next_state_(STATE_NONE),
pac_request_(NULL),
+ server_(server),
+ origin_url_(origin_url),
alternative_service_(alternative_service),
blocking_job_(NULL),
waiting_job_(NULL),
@@ -134,6 +150,7 @@ HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
spdy_session_direct_(false),
job_status_(STATUS_RUNNING),
other_job_status_(STATUS_RUNNING),
+ for_bidirectional_(false),
ptr_factory_(this) {
DCHECK(stream_factory);
DCHECK(session);
@@ -165,6 +182,8 @@ HttpStreamFactoryImpl::Job::~Job() {
void HttpStreamFactoryImpl::Job::Start(Request* request) {
DCHECK(request);
request_ = request;
+ // Saves |for_bidirectional_|, since request is nulled when job is orphaned.
+ for_bidirectional_ = request_->for_bidirectional();
StartInternal();
}
@@ -355,8 +374,33 @@ void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() {
// |this| may be deleted after this call.
}
+void HttpStreamFactoryImpl::Job::OnBidirectionalStreamJobReadyCallback() {
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ DCHECK(bidirectional_stream_job_);
+
+ MaybeCopyConnectionAttemptsFromSocketOrHandle();
+
+ if (IsOrphaned()) {
+ stream_factory_->OnOrphanedJobComplete(this);
+ } else {
+ request_->Complete(was_npn_negotiated(), protocol_negotiated(),
+ using_spdy());
+ request_->OnBidirectionalStreamJobReady(
+ this, server_ssl_config_, proxy_info_,
+ bidirectional_stream_job_.release());
+ }
+// |this| may be deleted after this call.
+#else
+ DCHECK(false);
+#endif
+}
+
void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() {
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ DCHECK(stream_.get() || bidirectional_stream_job_.get());
+#else
DCHECK(stream_.get());
+#endif
DCHECK(!IsPreconnecting());
DCHECK(using_spdy());
// Note: an event loop iteration has passed, so |new_spdy_session_| may be
@@ -376,8 +420,22 @@ void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() {
}
stream_factory_->OnOrphanedJobComplete(this);
} else {
- request_->OnNewSpdySessionReady(
- this, stream_.Pass(), spdy_session, spdy_session_direct_);
+ if (for_bidirectional_) {
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ DCHECK(bidirectional_stream_job_);
+ request_->OnNewSpdySessionReady(this, /*spdy_http_stream=*/nullptr,
+ std::move(bidirectional_stream_job_),
+ spdy_session, spdy_session_direct_);
+#else
+ DCHECK(false);
+#endif
+
+ } else {
+ DCHECK(stream_);
+ request_->OnNewSpdySessionReady(this, std::move(stream_),
+ /** bidirectional_stream_job=*/nullptr,
+ spdy_session, spdy_session_direct_);
+ }
}
// |this| may be deleted after this call.
}
@@ -564,6 +622,20 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback,
ptr_factory_.GetWeakPtr()));
+ } else if (for_bidirectional_) {
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ if (!bidirectional_stream_job_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&Job::OnStreamFailedCallback,
+ ptr_factory_.GetWeakPtr(), ERR_FAILED));
+ } else {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&Job::OnBidirectionalStreamJobReadyCallback,
+ ptr_factory_.GetWeakPtr()));
+ }
+#else
+ DCHECK(false);
+#endif
} else {
DCHECK(stream_.get());
base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -657,13 +729,6 @@ int HttpStreamFactoryImpl::Job::StartInternal() {
}
int HttpStreamFactoryImpl::Job::DoStart() {
- if (IsSpdyAlternative() || IsQuicAlternative()) {
- server_ = alternative_service_.host_port_pair();
- } else {
- server_ = HostPortPair::FromURL(request_info_.url);
- }
- origin_url_ =
- stream_factory_->ApplyHostMappingRules(request_info_.url, &server_);
valid_spdy_session_pool_.reset(new ValidSpdySessionPool(
session_->spdy_session_pool(), origin_url_, IsSpdyAlternative()));
@@ -772,7 +837,7 @@ int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) {
bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const {
return session_->params().enable_quic &&
session_->params().origin_to_force_quic_on.Equals(server_) &&
- proxy_info_.is_direct();
+ proxy_info_.is_direct() && origin_url_.SchemeIs("https");
}
int HttpStreamFactoryImpl::Job::DoWaitForJob() {
@@ -831,31 +896,29 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
}
HostPortPair destination;
std::string origin_host;
- bool secure_quic;
SSLConfig* ssl_config;
if (proxy_info_.is_quic()) {
// A proxy's certificate is expected to be valid for the proxy hostname.
destination = proxy_info_.proxy_server().host_port_pair();
origin_host = destination.host();
- secure_quic = true;
ssl_config = &proxy_ssl_config_;
// If QUIC is disabled on the destination port, return error.
if (session_->quic_stream_factory()->IsQuicDisabled(destination.port()))
return ERR_QUIC_PROTOCOL_ERROR;
} else {
+ DCHECK(using_ssl_);
// The certificate of a QUIC alternative server is expected to be valid
// for the origin of the request (in addition to being valid for the
// server itself).
destination = server_;
origin_host = origin_url_.host();
- secure_quic = using_ssl_;
ssl_config = &server_ssl_config_;
}
- int rv = quic_request_.Request(
- destination, secure_quic, request_info_.privacy_mode,
- ssl_config->GetCertVerifyFlags(), origin_host, request_info_.method,
- net_log_, io_callback_);
+ int rv =
+ quic_request_.Request(destination, request_info_.privacy_mode,
+ ssl_config->GetCertVerifyFlags(), origin_host,
+ request_info_.method, net_log_, io_callback_);
if (rv == OK) {
using_existing_quic_session_ = true;
} else {
@@ -946,7 +1009,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
if (stream_factory_->for_websockets_) {
// TODO(ricea): Re-enable NPN when WebSockets over SPDY is supported.
SSLConfig websocket_server_ssl_config = server_ssl_config_;
- websocket_server_ssl_config.next_protos.clear();
+ websocket_server_ssl_config.alpn_protos.clear();
+ websocket_server_ssl_config.npn_protos.clear();
return InitSocketHandleForWebSocketRequest(
GetSocketGroup(), server_, request_info_.extra_headers,
request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy,
@@ -1142,12 +1206,23 @@ int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) {
return ERR_IO_PENDING;
}
-int HttpStreamFactoryImpl::Job::SetSpdyHttpStream(
- base::WeakPtr<SpdySession> session, bool direct) {
+int HttpStreamFactoryImpl::Job::SetSpdyHttpStreamOrBidirectionalStreamJob(
+ base::WeakPtr<SpdySession> session,
+ bool direct) {
// TODO(ricea): Restore the code for WebSockets over SPDY once it's
// implemented.
if (stream_factory_->for_websockets_)
return ERR_NOT_IMPLEMENTED;
+ if (for_bidirectional_) {
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ // TODO(xunjieli): Create QUIC's version of BidirectionalStreamJob.
+ bidirectional_stream_job_.reset(new BidirectionalStreamSpdyJob(session));
+ return OK;
+#else
+ DCHECK(false);
+ return ERR_FAILED;
+#endif
+ }
// TODO(willchan): Delete this code, because eventually, the
// HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it
@@ -1185,7 +1260,7 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
DCHECK(request_->websocket_handshake_stream_create_helper());
websocket_stream_.reset(
request_->websocket_handshake_stream_create_helper()
- ->CreateBasicStream(connection_.Pass(), using_proxy));
+ ->CreateBasicStream(std::move(connection_), using_proxy));
} else {
stream_.reset(new HttpBasicStream(connection_.release(), using_proxy));
}
@@ -1201,7 +1276,8 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
connection_->socket()->Disconnect();
connection_->Reset();
- int set_result = SetSpdyHttpStream(existing_spdy_session_, direct);
+ int set_result = SetSpdyHttpStreamOrBidirectionalStreamJob(
+ existing_spdy_session_, direct);
existing_spdy_session_.reset();
return set_result;
}
@@ -1214,12 +1290,12 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
return result;
}
if (spdy_session) {
- return SetSpdyHttpStream(spdy_session, direct);
+ return SetSpdyHttpStreamOrBidirectionalStreamJob(spdy_session, direct);
}
result = valid_spdy_session_pool_->CreateAvailableSessionFromSocket(
- spdy_session_key, connection_.Pass(), net_log_, spdy_certificate_error_,
- using_ssl_, &spdy_session);
+ spdy_session_key, std::move(connection_), net_log_,
+ spdy_certificate_error_, using_ssl_, &spdy_session);
if (result != OK) {
return result;
}
@@ -1230,6 +1306,17 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY;
}
+ SSLInfo ssl_info;
+ bool was_npn_negotiated;
+ NextProto protocol_negotiated;
+ if (spdy_session->GetProtocolVersion() >= HTTP2 &&
+ spdy_session->GetSSLInfo(&ssl_info, &was_npn_negotiated,
+ &protocol_negotiated)) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
+ "Net.Http2SSLCipherSuite",
+ SSLConnectionStatusToCipherSuite(ssl_info.connection_status));
+ }
+
new_spdy_session_ = spdy_session;
spdy_session_direct_ = direct;
const HostPortPair& host_port_pair = spdy_session_key.host_port_pair();
@@ -1238,12 +1325,13 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
if (http_server_properties)
http_server_properties->SetSupportsSpdy(host_port_pair, true);
- // Create a SpdyHttpStream attached to the session;
- // OnNewSpdySessionReadyCallback is not called until an event loop
+ // Create a SpdyHttpStream or a BidirectionalStreamJob attached to the
+ // session; OnNewSpdySessionReadyCallback is not called until an event loop
// iteration later, so if the SpdySession is closed between then, allow
// reuse state from the underlying socket, sampled by SpdyHttpStream,
// bubble up to the request.
- return SetSpdyHttpStream(new_spdy_session_, spdy_session_direct_);
+ return SetSpdyHttpStreamOrBidirectionalStreamJob(new_spdy_session_,
+ spdy_session_direct_);
}
int HttpStreamFactoryImpl::Job::DoCreateStreamComplete(int result) {
@@ -1560,7 +1648,7 @@ int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::
bool is_secure,
base::WeakPtr<SpdySession>* spdy_session) {
*spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket(
- key, connection.Pass(), net_log, certificate_error_code, is_secure);
+ key, std::move(connection), net_log, certificate_error_code, is_secure);
return CheckAlternativeServiceValidityForOrigin(*spdy_session);
}
diff --git a/chromium/net/http/http_stream_factory_impl_job.h b/chromium/net/http/http_stream_factory_impl_job.h
index 81b812a6083..5e935cc14d3 100644
--- a/chromium/net/http/http_stream_factory_impl_job.h
+++ b/chromium/net/http/http_stream_factory_impl_job.h
@@ -5,6 +5,7 @@
#ifndef NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_H_
#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -16,6 +17,7 @@
#include "net/http/http_request_info.h"
#include "net/http/http_stream_factory_impl.h"
#include "net/log/net_log.h"
+#include "net/net_features.h"
#include "net/proxy/proxy_service.h"
#include "net/quic/quic_stream_factory.h"
#include "net/socket/client_socket_handle.h"
@@ -26,6 +28,7 @@
namespace net {
+class BidirectionalStreamJob;
class ClientSocketHandle;
class HttpAuthController;
class HttpNetworkSession;
@@ -44,6 +47,8 @@ class HttpStreamFactoryImpl::Job {
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
+ HostPortPair server,
+ GURL origin_url,
NetLog* net_log);
// Constructor for alternative Job.
Job(HttpStreamFactoryImpl* stream_factory,
@@ -52,6 +57,8 @@ class HttpStreamFactoryImpl::Job {
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
+ HostPortPair server,
+ GURL origin_url,
AlternativeService alternative_service,
NetLog* net_log);
~Job();
@@ -86,6 +93,7 @@ class HttpStreamFactoryImpl::Job {
NextProto protocol_negotiated() const;
bool using_spdy() const;
const BoundNetLog& net_log() const { return net_log_; }
+ bool for_bidirectional() const { return for_bidirectional_; }
const SSLConfig& server_ssl_config() const;
const SSLConfig& proxy_ssl_config() const;
@@ -194,6 +202,7 @@ class HttpStreamFactoryImpl::Job {
};
void OnStreamReadyCallback();
+ void OnBidirectionalStreamJobReadyCallback();
void OnWebSocketHandshakeStreamReadyCallback();
// This callback function is called when a new SPDY session is created.
void OnNewSpdySessionReadyCallback();
@@ -228,9 +237,12 @@ class HttpStreamFactoryImpl::Job {
int DoRestartTunnelAuth();
int DoRestartTunnelAuthComplete(int result);
- // Creates a SpdyHttpStream from the given values and sets to |stream_|. Does
+ // Creates a SpdyHttpStream or a BidirectionalStreamJob from the given values
+ // and sets to |stream_| or |bidirectional_stream_job_| respectively. Does
// nothing if |stream_factory_| is for WebSockets.
- int SetSpdyHttpStream(base::WeakPtr<SpdySession> session, bool direct);
+ int SetSpdyHttpStreamOrBidirectionalStreamJob(
+ base::WeakPtr<SpdySession> session,
+ bool direct);
// Returns to STATE_INIT_CONNECTION and resets some state.
void ReturnToStateInitConnection(bool close_connection);
@@ -368,6 +380,9 @@ class HttpStreamFactoryImpl::Job {
scoped_ptr<HttpStream> stream_;
scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ scoped_ptr<BidirectionalStreamJob> bidirectional_stream_job_;
+#endif
// True if we negotiated NPN.
bool was_npn_negotiated_;
@@ -393,6 +408,9 @@ class HttpStreamFactoryImpl::Job {
JobStatus job_status_;
JobStatus other_job_status_;
+ // True if BidirectionalStreamJob is requested.
+ bool for_bidirectional_;
+
base::WeakPtrFactory<Job> ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Job);
diff --git a/chromium/net/http/http_stream_factory_impl_request.cc b/chromium/net/http/http_stream_factory_impl_request.cc
index 9e2f9dc3d94..59b7b44c4ac 100644
--- a/chromium/net/http/http_stream_factory_impl_request.cc
+++ b/chromium/net/http/http_stream_factory_impl_request.cc
@@ -11,6 +11,10 @@
#include "net/spdy/spdy_http_stream.h"
#include "net/spdy/spdy_session.h"
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+#include "net/http/bidirectional_stream_job.h"
+#endif
+
namespace net {
HttpStreamFactoryImpl::Request::Request(
@@ -19,7 +23,8 @@ HttpStreamFactoryImpl::Request::Request(
HttpStreamRequest::Delegate* delegate,
WebSocketHandshakeStreamBase::CreateHelper*
websocket_handshake_stream_create_helper,
- const BoundNetLog& net_log)
+ const BoundNetLog& net_log,
+ StreamType stream_type)
: url_(url),
factory_(factory),
websocket_handshake_stream_create_helper_(
@@ -29,7 +34,8 @@ HttpStreamFactoryImpl::Request::Request(
completed_(false),
was_npn_negotiated_(false),
protocol_negotiated_(kProtoUnknown),
- using_spdy_(false) {
+ using_spdy_(false),
+ for_bidirectional_(stream_type == BIDIRECTIONAL_STREAM_SPDY_JOB) {
DCHECK(factory_);
DCHECK(delegate_);
@@ -77,6 +83,7 @@ void HttpStreamFactoryImpl::Request::OnStreamReady(
const ProxyInfo& used_proxy_info,
HttpStream* stream) {
DCHECK(!factory_->for_websockets_);
+ DCHECK(!for_bidirectional_);
DCHECK(stream);
DCHECK(completed_);
@@ -84,12 +91,28 @@ void HttpStreamFactoryImpl::Request::OnStreamReady(
delegate_->OnStreamReady(used_ssl_config, used_proxy_info, stream);
}
+void HttpStreamFactoryImpl::Request::OnBidirectionalStreamJobReady(
+ Job* job,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream_job) {
+ DCHECK(!factory_->for_websockets_);
+ DCHECK(for_bidirectional_);
+ DCHECK(stream_job);
+ DCHECK(completed_);
+
+ OnJobSucceeded(job);
+ delegate_->OnBidirectionalStreamJobReady(used_ssl_config, used_proxy_info,
+ stream_job);
+}
+
void HttpStreamFactoryImpl::Request::OnWebSocketHandshakeStreamReady(
Job* job,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
WebSocketHandshakeStreamBase* stream) {
DCHECK(factory_->for_websockets_);
+ DCHECK(!for_bidirectional_);
DCHECK(stream);
DCHECK(completed_);
@@ -252,13 +275,18 @@ bool HttpStreamFactoryImpl::Request::HasSpdySessionKey() const {
void HttpStreamFactoryImpl::Request::OnNewSpdySessionReady(
Job* job,
scoped_ptr<HttpStream> stream,
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ scoped_ptr<BidirectionalStreamJob> bidirectional_stream_job,
+#else
+ void* bidirectional_stream_job,
+#endif
const base::WeakPtr<SpdySession>& spdy_session,
bool direct) {
DCHECK(job);
DCHECK(job->using_spdy());
// Note: |spdy_session| may be NULL. In that case, |delegate_| should still
- // receive |stream| so the error propogates up correctly, however there is no
+ // receive |stream| so the error propagates up correctly, however there is no
// point in broadcasting |spdy_session| to other requests.
// The first case is the usual case.
@@ -286,7 +314,19 @@ void HttpStreamFactoryImpl::Request::OnNewSpdySessionReady(
// TODO(ricea): Re-instate this code when WebSockets over SPDY is
// implemented.
NOTREACHED();
+ } else if (for_bidirectional_) {
+ DCHECK(bidirectional_stream_job);
+ DCHECK(!stream);
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ delegate_->OnBidirectionalStreamJobReady(
+ job->server_ssl_config(), job->proxy_info(),
+ bidirectional_stream_job.release());
+#else
+ NOTREACHED();
+#endif
} else {
+ DCHECK(!bidirectional_stream_job);
+ DCHECK(stream);
delegate_->OnStreamReady(job->server_ssl_config(), job->proxy_info(),
stream.release());
}
diff --git a/chromium/net/http/http_stream_factory_impl_request.h b/chromium/net/http/http_stream_factory_impl_request.h
index e65dac88e45..a92303c97b9 100644
--- a/chromium/net/http/http_stream_factory_impl_request.h
+++ b/chromium/net/http/http_stream_factory_impl_request.h
@@ -6,9 +6,12 @@
#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
#include <set>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/http/http_stream_factory_impl.h"
#include "net/log/net_log.h"
+#include "net/net_features.h"
#include "net/socket/connection_attempts.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/spdy_session_key.h"
@@ -17,18 +20,27 @@
namespace net {
+class BidirectionalStreamJob;
class ClientSocketHandle;
class HttpStream;
class SpdySession;
class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
public:
+ // Indicates which type of stream is requested.
+ enum StreamType {
+ BIDIRECTIONAL_STREAM_SPDY_JOB,
+ HTTP_STREAM,
+ };
+
Request(const GURL& url,
HttpStreamFactoryImpl* factory,
HttpStreamRequest::Delegate* delegate,
WebSocketHandshakeStreamBase::CreateHelper*
websocket_handshake_stream_create_helper,
- const BoundNetLog& net_log);
+ const BoundNetLog& net_log,
+ StreamType stream_type);
+
~Request() override;
// The GURL from the HttpRequestInfo the started the Request.
@@ -57,10 +69,18 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
void RemoveRequestFromSpdySessionRequestMap();
// Called by an attached Job if it sets up a SpdySession.
- void OnNewSpdySessionReady(Job* job,
- scoped_ptr<HttpStream> stream,
- const base::WeakPtr<SpdySession>& spdy_session,
- bool direct);
+ // |stream| is null when |for_bidirectional| is true.
+ // |bidirectional_stream_spdy_job| is null when |for_bidirectional| is false.
+ void OnNewSpdySessionReady(
+ Job* job,
+ scoped_ptr<HttpStream> stream,
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ scoped_ptr<BidirectionalStreamJob> bidirectional_stream_spdy_job,
+#else
+ void* unused,
+#endif
+ const base::WeakPtr<SpdySession>& spdy_session,
+ bool direct);
// Called by an attached Job to record connection attempts made by the socket
// layer for this stream request.
@@ -78,6 +98,11 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStream* stream);
+ void OnBidirectionalStreamJobReady(Job* job,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream);
+
void OnWebSocketHandshakeStreamReady(Job* job,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
@@ -114,6 +139,7 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
NextProto protocol_negotiated() const override;
bool using_spdy() const override;
const ConnectionAttempts& connection_attempts() const override;
+ bool for_bidirectional() const { return for_bidirectional_; }
private:
// Used to bind |job| to the request and orphan all other jobs in |jobs_|.
@@ -147,6 +173,7 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
bool using_spdy_;
ConnectionAttempts connection_attempts_;
+ const bool for_bidirectional_;
DISALLOW_COPY_AND_ASSIGN(Request);
};
diff --git a/chromium/net/http/http_stream_factory_impl_request_unittest.cc b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
index 7a5483155bf..9e9c5d1f013 100644
--- a/chromium/net/http/http_stream_factory_impl_request_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
@@ -35,6 +35,11 @@ class DoNothingRequestDelegate : public HttpStreamRequest::Delegate {
void OnStreamReady(const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStream* stream) override {}
+ void OnBidirectionalStreamJobReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream_job) override {}
+
void OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
@@ -55,6 +60,7 @@ class DoNothingRequestDelegate : public HttpStreamRequest::Delegate {
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStream* stream) override {}
+ void OnQuicBroken() override {}
};
} // namespace
@@ -64,23 +70,24 @@ TEST_P(HttpStreamFactoryImplRequestTest, SetPriority) {
SpdySessionDependencies session_deps(GetParam(),
ProxyService::CreateDirect());
- scoped_refptr<HttpNetworkSession>
- session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
+ scoped_ptr<HttpNetworkSession> session =
+ SpdySessionDependencies::SpdyCreateSession(&session_deps);
HttpStreamFactoryImpl* factory =
static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory());
DoNothingRequestDelegate request_delegate;
HttpStreamFactoryImpl::Request request(
- GURL(), factory, &request_delegate, NULL, BoundNetLog());
-
- HttpStreamFactoryImpl::Job* job =
- new HttpStreamFactoryImpl::Job(factory,
- session.get(),
- HttpRequestInfo(),
- DEFAULT_PRIORITY,
- SSLConfig(),
- SSLConfig(),
- NULL);
+ GURL(), factory, &request_delegate, NULL, BoundNetLog(),
+ HttpStreamFactoryImpl::Request::HTTP_STREAM);
+
+ HttpRequestInfo request_info;
+
+ HostPortPair server = HostPortPair::FromURL(request_info.url);
+ GURL original_url = factory->ApplyHostMappingRules(request_info.url, &server);
+
+ HttpStreamFactoryImpl::Job* job = new HttpStreamFactoryImpl::Job(
+ factory, session.get(), request_info, DEFAULT_PRIORITY, SSLConfig(),
+ SSLConfig(), server, original_url, NULL);
request.AttachJob(job);
EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
diff --git a/chromium/net/http/http_stream_factory_impl_unittest.cc b/chromium/net/http/http_stream_factory_impl_unittest.cc
index b3dfe7f0cf5..32c20e32c7a 100644
--- a/chromium/net/http/http_stream_factory_impl_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_unittest.cc
@@ -5,12 +5,12 @@
#include "net/http/http_stream_factory_impl.h"
#include <stdint.h>
-
#include <string>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/port_util.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/mock_cert_verifier.h"
@@ -25,8 +25,11 @@
#include "net/http/http_stream.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
+#include "net/net_features.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_service.h"
+#include "net/quic/quic_server_id.h"
+#include "net/quic/test_tools/quic_stream_factory_peer.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/mock_client_socket_pool_manager.h"
#include "net/socket/next_proto.h"
@@ -42,8 +45,14 @@
#include "net/websockets/websocket_handshake_stream_base.h"
#include "testing/gtest/include/gtest/gtest.h"
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+#include "net/http/bidirectional_stream_job.h"
+#endif
+
namespace net {
+class BidirectionalStreamJob;
+
namespace {
class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
@@ -95,6 +104,7 @@ class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
void Drain(HttpNetworkSession* session) override {}
+ void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
void SetPriority(RequestPriority priority) override {}
UploadProgress GetUploadProgress() const override { return UploadProgress(); }
HttpStream* RenewStreamForAuth() override { return nullptr; }
@@ -110,13 +120,11 @@ class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
// HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
public:
- MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session,
- bool for_websockets)
- : HttpStreamFactoryImpl(session, for_websockets),
+ MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session)
+ : HttpStreamFactoryImpl(session, false),
preconnect_done_(false),
waiting_for_preconnect_(false) {}
-
void WaitForPreconnects() {
while (!preconnect_done_) {
waiting_for_preconnect_ = true;
@@ -130,7 +138,7 @@ class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
void OnPreconnectsCompleteInternal() override {
preconnect_done_ = true;
if (waiting_for_preconnect_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
bool preconnect_done_;
@@ -140,8 +148,7 @@ class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
class StreamRequestWaiter : public HttpStreamRequest::Delegate {
public:
StreamRequestWaiter()
- : waiting_for_stream_(false),
- stream_done_(false) {}
+ : waiting_for_stream_(false), stream_done_(false), error_status_(OK) {}
// HttpStreamRequest::Delegate
@@ -150,7 +157,7 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate {
HttpStream* stream) override {
stream_done_ = true;
if (waiting_for_stream_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
stream_.reset(stream);
used_ssl_config_ = used_ssl_config;
used_proxy_info_ = used_proxy_info;
@@ -162,15 +169,36 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate {
WebSocketHandshakeStreamBase* stream) override {
stream_done_ = true;
if (waiting_for_stream_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
websocket_stream_.reset(stream);
used_ssl_config_ = used_ssl_config;
used_proxy_info_ = used_proxy_info;
}
+ void OnBidirectionalStreamJobReady(const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ BidirectionalStreamJob* stream) override {
+ stream_done_ = true;
+ if (waiting_for_stream_)
+ base::MessageLoop::current()->QuitWhenIdle();
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ bidirectional_stream_job_.reset(stream);
+#else
+ DCHECK(!stream);
+#endif
+ used_ssl_config_ = used_ssl_config;
+ used_proxy_info_ = used_proxy_info;
+ }
+
void OnStreamFailed(int status,
const SSLConfig& used_ssl_config,
- SSLFailureState ssl_failure_state) override {}
+ SSLFailureState ssl_failure_state) override {
+ stream_done_ = true;
+ if (waiting_for_stream_)
+ base::MessageLoop::current()->QuitWhenIdle();
+ used_ssl_config_ = used_ssl_config;
+ error_status_ = status;
+ }
void OnCertificateError(int status,
const SSLConfig& used_ssl_config,
@@ -189,6 +217,8 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate {
const ProxyInfo& used_proxy_info,
HttpStream* stream) override {}
+ void OnQuicBroken() override {}
+
void WaitForStream() {
while (!stream_done_) {
waiting_for_stream_ = true;
@@ -213,15 +243,26 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate {
return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
}
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ BidirectionalStreamJob* bidirectional_stream_job() {
+ return bidirectional_stream_job_.get();
+ }
+#endif
+
bool stream_done() const { return stream_done_; }
+ int error_status() const { return error_status_; }
private:
bool waiting_for_stream_;
bool stream_done_;
scoped_ptr<HttpStream> stream_;
scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+ scoped_ptr<BidirectionalStreamJob> bidirectional_stream_job_;
+#endif
SSLConfig used_ssl_config_;
ProxyInfo used_proxy_info_;
+ int error_status_;
DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
};
@@ -246,7 +287,7 @@ class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
explicit WebSocketBasicHandshakeStream(
scoped_ptr<ClientSocketHandle> connection)
: MockWebSocketHandshakeStream(kStreamTypeBasic),
- connection_(connection.Pass()) {}
+ connection_(std::move(connection)) {}
~WebSocketBasicHandshakeStream() override {
connection_->socket()->Disconnect();
@@ -266,7 +307,7 @@ class WebSocketStreamCreateHelper
WebSocketHandshakeStreamBase* CreateBasicStream(
scoped_ptr<ClientSocketHandle> connection,
bool using_proxy) override {
- return new WebSocketBasicHandshakeStream(connection.Pass());
+ return new WebSocketBasicHandshakeStream(std::move(connection));
}
WebSocketHandshakeStreamBase* CreateSpdyStream(
@@ -293,7 +334,7 @@ void PreconnectHelperForURL(int num_streams,
HttpNetworkSession* session) {
HttpNetworkSessionPeer peer(session);
MockHttpStreamFactoryImplForPreconnect* mock_factory =
- new MockHttpStreamFactoryImplForPreconnect(session, false);
+ new MockHttpStreamFactoryImplForPreconnect(session);
peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory));
SSLConfig ssl_config;
session->ssl_config_service()->GetSSLConfig(&ssl_config);
@@ -407,7 +448,7 @@ CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
nullptr, // channel_id_store
nullptr, // transport_security_state
nullptr, // cert_transparency_verifier
- nullptr, // cert_policy_enforcer
+ nullptr, // ct_policy_enforcer
std::string(), // ssl_session_cache_shard
nullptr, // deterministic_socket_factory
nullptr, // transport_socket_pool
@@ -431,9 +472,9 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
for (size_t i = 0; i < arraysize(kTests); ++i) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateDirect());
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
CapturePreconnectsTransportSocketPool* transport_conn_pool =
new CapturePreconnectsTransportSocketPool(
session_deps.host_resolver.get(),
@@ -446,7 +487,7 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
PreconnectHelper(kTests[i], session.get());
if (kTests[i].ssl)
EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
@@ -459,9 +500,9 @@ TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
for (size_t i = 0; i < arraysize(kTests); ++i) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateFixed("http_proxy"));
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
HostPortPair proxy_host("http_proxy", 80);
CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
new CapturePreconnectsHttpProxySocketPool(
@@ -475,7 +516,7 @@ TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
PreconnectHelper(kTests[i], session.get());
if (kTests[i].ssl)
EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
@@ -488,9 +529,9 @@ TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
for (size_t i = 0; i < arraysize(kTests); ++i) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
HostPortPair proxy_host("socks_proxy", 1080);
CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
new CapturePreconnectsSOCKSSocketPool(
@@ -504,7 +545,7 @@ TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
PreconnectHelper(kTests[i], session.get());
if (kTests[i].ssl)
EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
@@ -517,9 +558,9 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
for (size_t i = 0; i < arraysize(kTests); ++i) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateDirect());
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
// Put a SpdySession in the pool.
HostPortPair host_port_pair("www.google.com", 443);
@@ -539,7 +580,7 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
PreconnectHelper(kTests[i], session.get());
// We shouldn't be preconnecting if we have an existing session, which is
// the case for https://www.google.com.
@@ -558,9 +599,9 @@ TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateDirect());
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
- HttpNetworkSessionPeer peer(session);
+ HttpNetworkSessionPeer peer(session.get());
CapturePreconnectsTransportSocketPool* transport_conn_pool =
new CapturePreconnectsTransportSocketPool(
session_deps.host_resolver.get(),
@@ -568,7 +609,7 @@ TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
@@ -589,7 +630,7 @@ TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
socket_data2.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream. It should succeed using the second proxy in the
@@ -639,6 +680,7 @@ TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
HttpNetworkSession::Params params;
params.enable_quic = true;
+ params.quic_disable_preconnect_if_0rtt = false;
params.enable_quic_for_proxies = true;
scoped_refptr<SSLConfigServiceDefaults> ssl_config_service(
new SSLConfigServiceDefaults);
@@ -653,8 +695,7 @@ TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
params.ssl_config_service = ssl_config_service.get();
params.http_server_properties = http_server_properties.GetWeakPtr();
- scoped_refptr<HttpNetworkSession> session;
- session = new HttpNetworkSession(params);
+ scoped_ptr<HttpNetworkSession> session(new HttpNetworkSession(params));
session->quic_stream_factory()->set_require_confirmation(false);
StaticSocketDataProvider socket_data1;
@@ -701,6 +742,7 @@ TEST_P(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad) {
HttpNetworkSession::Params params;
params.enable_quic = true;
params.enable_quic_for_proxies = true;
+ params.quic_disable_preconnect_if_0rtt = false;
scoped_refptr<SSLConfigServiceDefaults> ssl_config_service(
new SSLConfigServiceDefaults);
HttpServerPropertiesImpl http_server_properties;
@@ -715,8 +757,7 @@ TEST_P(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad) {
params.http_server_properties = http_server_properties.GetWeakPtr();
params.quic_max_number_of_lossy_connections = 2;
- scoped_refptr<HttpNetworkSession> session;
- session = new HttpNetworkSession(params);
+ scoped_ptr<HttpNetworkSession> session(new HttpNetworkSession(params));
session->quic_stream_factory()->set_require_confirmation(false);
session->quic_stream_factory()->number_of_lossy_connections_[99] =
@@ -750,6 +791,105 @@ TEST_P(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad) {
EXPECT_TRUE(iter != retry_info.end());
}
+TEST_P(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) {
+ for (int num_streams = 1; num_streams < 3; ++num_streams) {
+ GURL url = GURL("https://www.google.com");
+
+ // Set up QUIC as alternative_service.
+ HttpServerPropertiesImpl http_server_properties;
+ const AlternativeService alternative_service(QUIC, url.host().c_str(),
+ url.IntPort());
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service, 1.0, expiration));
+ HostPortPair host_port_pair(alternative_service.host_port_pair());
+ http_server_properties.SetAlternativeServices(
+ host_port_pair, alternative_service_info_vector);
+
+ SpdySessionDependencies session_deps(
+ GetParam(), ProxyService::CreateFixed("http_proxy"));
+
+ // Setup params to disable preconnect, but QUIC doesn't 0RTT.
+ HttpNetworkSession::Params params =
+ SpdySessionDependencies::CreateSessionParams(&session_deps);
+ params.enable_quic = true;
+ params.quic_disable_preconnect_if_0rtt = true;
+ params.http_server_properties = http_server_properties.GetWeakPtr();
+
+ scoped_ptr<HttpNetworkSession> session(new HttpNetworkSession(params));
+ HttpNetworkSessionPeer peer(session.get());
+ HostPortPair proxy_host("http_proxy", 80);
+ CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
+ new CapturePreconnectsHttpProxySocketPool(
+ session_deps.host_resolver.get(), session_deps.cert_verifier.get());
+ CapturePreconnectsSSLSocketPool* ssl_conn_pool =
+ new CapturePreconnectsSSLSocketPool(session_deps.host_resolver.get(),
+ session_deps.cert_verifier.get());
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
+ mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
+ mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
+ PreconnectHelperForURL(num_streams, url, session.get());
+ EXPECT_EQ(num_streams, ssl_conn_pool->last_num_streams());
+ }
+}
+
+TEST_P(HttpStreamFactoryTest, QuicDisablePreConnectIfZeroRtt) {
+ for (int num_streams = 1; num_streams < 3; ++num_streams) {
+ GURL url = GURL("https://www.google.com");
+
+ // Set up QUIC as alternative_service.
+ HttpServerPropertiesImpl http_server_properties;
+ const AlternativeService alternative_service(QUIC, "www.google.com", 443);
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service, 1.0, expiration));
+ HostPortPair host_port_pair(alternative_service.host_port_pair());
+ http_server_properties.SetAlternativeServices(
+ host_port_pair, alternative_service_info_vector);
+
+ SpdySessionDependencies session_deps(GetParam());
+
+ // Setup params to disable preconnect, but QUIC does 0RTT.
+ HttpNetworkSession::Params params =
+ SpdySessionDependencies::CreateSessionParams(&session_deps);
+ params.enable_quic = true;
+ params.quic_disable_preconnect_if_0rtt = true;
+ params.http_server_properties = http_server_properties.GetWeakPtr();
+
+ scoped_ptr<HttpNetworkSession> session(new HttpNetworkSession(params));
+
+ // Setup 0RTT for QUIC.
+ QuicStreamFactory* factory = session->quic_stream_factory();
+ factory->set_require_confirmation(false);
+ test::QuicStreamFactoryPeer::CacheDummyServerConfig(
+ factory, QuicServerId(host_port_pair, PRIVACY_MODE_DISABLED));
+
+ HttpNetworkSessionPeer peer(session.get());
+ CapturePreconnectsTransportSocketPool* transport_conn_pool =
+ new CapturePreconnectsTransportSocketPool(
+ session_deps.host_resolver.get(), session_deps.cert_verifier.get());
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
+ mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
+ peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = url;
+ request.load_flags = 0;
+
+ SSLConfig ssl_config;
+ session->ssl_config_service()->GetSSLConfig(&ssl_config);
+ session->http_stream_factory()->PreconnectStreams(num_streams, request,
+ ssl_config, ssl_config);
+ EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
+ }
+}
+
namespace {
TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
@@ -763,7 +903,7 @@ TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
SSLSocketDataProvider ssl(ASYNC, OK);
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Set an existing SpdySession in the pool.
@@ -829,7 +969,7 @@ TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
SSLSocketDataProvider ssl(ASYNC, OK);
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL);
@@ -879,7 +1019,7 @@ TEST_P(HttpStreamFactoryTest, GetLoadState) {
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
HttpRequestInfo request_info;
@@ -906,7 +1046,7 @@ TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream. It should succeed using the second proxy in the
@@ -956,7 +1096,7 @@ TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
@@ -1001,7 +1141,7 @@ TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream. It should succeed using the second proxy in the
@@ -1054,7 +1194,7 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
@@ -1102,7 +1242,7 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
@@ -1147,7 +1287,7 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
@@ -1208,7 +1348,7 @@ TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
HostPortPair host_port_pair("www.google.com", 443);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
@@ -1245,6 +1385,106 @@ TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
EXPECT_TRUE(waiter.used_proxy_info().is_direct());
}
+#if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
+TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJob) {
+ SpdySessionDependencies session_deps(GetParam(),
+ ProxyService::CreateDirect());
+
+ MockRead mock_read(ASYNC, OK);
+ SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
+ socket_data.set_connect_data(MockConnect(ASYNC, OK));
+ session_deps.socket_factory->AddSocketDataProvider(&socket_data);
+
+ SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+ ssl_socket_data.SetNextProto(GetParam());
+ session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
+
+ HostPortPair host_port_pair("www.google.com", 443);
+ scoped_ptr<HttpNetworkSession> session(
+ SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+ // Now request a stream.
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("https://www.google.com");
+ request_info.load_flags = 0;
+
+ SSLConfig ssl_config;
+ StreamRequestWaiter waiter;
+ scoped_ptr<HttpStreamRequest> request(
+ session->http_stream_factory()->RequestBidirectionalStreamJob(
+ request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
+ BoundNetLog()));
+ waiter.WaitForStream();
+ EXPECT_TRUE(waiter.stream_done());
+ EXPECT_FALSE(waiter.websocket_stream());
+ ASSERT_FALSE(waiter.stream());
+ ASSERT_TRUE(waiter.bidirectional_stream_job());
+ EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL)));
+ EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL)));
+ EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool(
+ HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
+ EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
+ HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
+ EXPECT_TRUE(waiter.used_proxy_info().is_direct());
+ ASSERT_EQ(0u,
+ static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory())
+ ->num_orphaned_jobs());
+}
+
+TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJobFailure) {
+ SpdySessionDependencies session_deps(GetParam(),
+ ProxyService::CreateDirect());
+
+ MockRead mock_read(ASYNC, OK);
+ SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
+ socket_data.set_connect_data(MockConnect(ASYNC, OK));
+ session_deps.socket_factory->AddSocketDataProvider(&socket_data);
+
+ SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+
+ // If HTTP/1 is used, BidirectionalStreamJob should not be obtained.
+ ssl_socket_data.SetNextProto(kProtoHTTP11);
+ session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
+
+ HostPortPair host_port_pair("www.google.com", 443);
+ scoped_ptr<HttpNetworkSession> session(
+ SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+ // Now request a stream.
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("https://www.google.com");
+ request_info.load_flags = 0;
+
+ SSLConfig ssl_config;
+ StreamRequestWaiter waiter;
+ scoped_ptr<HttpStreamRequest> request(
+ session->http_stream_factory()->RequestBidirectionalStreamJob(
+ request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
+ BoundNetLog()));
+ waiter.WaitForStream();
+ EXPECT_TRUE(waiter.stream_done());
+ ASSERT_EQ(ERR_FAILED, waiter.error_status());
+ EXPECT_FALSE(waiter.websocket_stream());
+ ASSERT_FALSE(waiter.stream());
+ ASSERT_FALSE(waiter.bidirectional_stream_job());
+ EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL)));
+ EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL)));
+ EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool(
+ HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
+ EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
+ HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
+ ASSERT_EQ(0u,
+ static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory())
+ ->num_orphaned_jobs());
+}
+#endif
+
// TODO(ricea): This test can be removed once the new WebSocket stack supports
// SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
// use plain SSL.
@@ -1261,8 +1501,8 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
HostPortPair host_port_pair("www.google.com", 80);
- scoped_refptr<HttpNetworkSession>
- session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
+ scoped_ptr<HttpNetworkSession> session(
+ SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
HttpRequestInfo request_info;
@@ -1313,8 +1553,8 @@ TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
HostPortPair host_port_pair("www.google.com", 80);
- scoped_refptr<HttpNetworkSession>
- session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
+ scoped_ptr<HttpNetworkSession> session(
+ SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
HttpRequestInfo request_info;
@@ -1395,7 +1635,7 @@ TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
ssl_socket_data.SetNextProto(GetParam());
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
// Now request a stream.
diff --git a/chromium/net/http/http_stream_parser.cc b/chromium/net/http/http_stream_parser.cc
index 4e4b6b6523f..e115743ea59 100644
--- a/chromium/net/http/http_stream_parser.cc
+++ b/chromium/net/http/http_stream_parser.cc
@@ -4,6 +4,8 @@
#include "net/http/http_stream_parser.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
@@ -44,7 +46,7 @@ void RecordHeaderParserEvent(HttpHeaderParserEvent header_event) {
NUM_HEADER_EVENTS);
}
-const uint64 kMaxMergedHeaderAndBodySize = 1400;
+const uint64_t kMaxMergedHeaderAndBodySize = 1400;
const size_t kRequestBodyBufferSize = 1 << 14; // 16KB
std::string GetResponseHeaderLines(const HttpResponseHeaders& headers) {
@@ -79,7 +81,7 @@ bool HeadersContainMultipleCopiesOfField(const HttpResponseHeaders& headers,
}
scoped_ptr<base::Value> NetLogSendRequestBodyCallback(
- uint64 length,
+ uint64_t length,
bool is_chunked,
bool did_merge,
NetLogCaptureMode /* capture_mode */) {
@@ -87,7 +89,7 @@ scoped_ptr<base::Value> NetLogSendRequestBodyCallback(
dict->SetInteger("length", static_cast<int>(length));
dict->SetBoolean("is_chunked", is_chunked);
dict->SetBoolean("did_merge", did_merge);
- return dict.Pass();
+ return std::move(dict);
}
// Returns true if |error_code| is an error for which we give the server a
@@ -287,7 +289,7 @@ int HttpStreamParser::SendRequest(const std::string& request_line,
memcpy(request_headers_->data(), request.data(), request_headers_length_);
request_headers_->DidConsume(request_headers_length_);
- uint64 todo = request_->upload_data_stream->size();
+ uint64_t todo = request_->upload_data_stream->size();
while (todo) {
int consumed = request_->upload_data_stream->Read(
request_headers_.get(), static_cast<int>(todo), CompletionCallback());
@@ -735,7 +737,7 @@ int HttpStreamParser::DoReadBodyComplete(int result) {
if (chunked_decoder_.get()) {
save_amount = chunked_decoder_->bytes_after_eof();
} else if (response_body_length_ >= 0) {
- int64 extra_data_read = response_body_read_ - response_body_length_;
+ int64_t extra_data_read = response_body_read_ - response_body_length_;
if (extra_data_read > 0) {
save_amount = static_cast<int>(extra_data_read);
if (result > 0)
@@ -1130,7 +1132,7 @@ bool HttpStreamParser::ShouldMergeRequestHeadersAndBody(
// IsInMemory() ensures that the request body is not chunked.
request_body->IsInMemory() &&
request_body->size() > 0) {
- uint64 merged_size = request_headers.size() + request_body->size();
+ uint64_t merged_size = request_headers.size() + request_body->size();
if (merged_size <= kMaxMergedHeaderAndBodySize)
return true;
}
diff --git a/chromium/net/http/http_stream_parser.h b/chromium/net/http/http_stream_parser.h
index f8700c472f5..d51cb9188bb 100644
--- a/chromium/net/http/http_stream_parser.h
+++ b/chromium/net/http/http_stream_parser.h
@@ -5,11 +5,12 @@
#ifndef NET_HTTP_HTTP_STREAM_PARSER_H_
#define NET_HTTP_HTTP_STREAM_PARSER_H_
+#include <stddef.h>
#include <stdint.h>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -226,10 +227,10 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// Indicates the content length. If this value is less than zero
// (and chunked_decoder_ is null), then we must read until the server
// closes the connection.
- int64 response_body_length_;
+ int64_t response_body_length_;
// Keep track of the number of response body bytes read so far.
- int64 response_body_read_;
+ int64_t response_body_read_;
// Helper if the data is chunked.
scoped_ptr<HttpChunkedDecoder> chunked_decoder_;
diff --git a/chromium/net/http/http_stream_parser_unittest.cc b/chromium/net/http/http_stream_parser_unittest.cc
index 012960606c1..79364264138 100644
--- a/chromium/net/http/http_stream_parser_unittest.cc
+++ b/chromium/net/http/http_stream_parser_unittest.cc
@@ -5,15 +5,16 @@
#include "net/http/http_stream_parser.h"
#include <stdint.h>
-
#include <algorithm>
#include <string>
+#include <utility>
#include <vector>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
@@ -51,14 +52,13 @@ scoped_ptr<ClientSocketHandle> CreateConnectedSocketHandle(
scoped_ptr<MockTCPClientSocket> socket(
new MockTCPClientSocket(net::AddressList(), nullptr, data));
- data->set_socket(socket.get());
TestCompletionCallback callback;
EXPECT_EQ(OK, socket->Connect(callback.callback()));
scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
- socket_handle->SetSocket(socket.Pass());
- return socket_handle.Pass();
+ socket_handle->SetSocket(std::move(socket));
+ return socket_handle;
}
// The empty payload is how the last chunk is encoded.
@@ -126,9 +126,9 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_NoBody) {
}
TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_EmptyBody) {
- ScopedVector<UploadElementReader> element_readers;
- scoped_ptr<UploadDataStream> body(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ scoped_ptr<UploadDataStream> body(make_scoped_ptr(
+ new ElementsUploadDataStream(std::move(element_readers), 0)));
ASSERT_EQ(OK, body->Init(CompletionCallback()));
// Shouldn't be merged if upload data is empty.
ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -146,22 +146,21 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_ChunkedBody) {
}
TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_FileBody) {
- {
- ScopedVector<UploadElementReader> element_readers;
+ // Create an empty temporary file.
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ base::FilePath temp_file_path;
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file_path));
- // Create an empty temporary file.
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath temp_file_path;
- ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(),
- &temp_file_path));
+ {
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
- element_readers.push_back(
+ element_readers.push_back(make_scoped_ptr(
new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- temp_file_path, 0, 0, base::Time()));
+ temp_file_path, 0, 0, base::Time())));
scoped_ptr<UploadDataStream> body(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING, body->Init(callback.callback()));
ASSERT_EQ(OK, callback.WaitForResult());
@@ -169,18 +168,19 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_FileBody) {
ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
"some header", body.get()));
}
+
// UploadFileElementReaders may post clean-up tasks on destruction.
base::RunLoop().RunUntilIdle();
}
TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_SmallBodyInMemory) {
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
const std::string payload = "123";
- element_readers.push_back(new UploadBytesElementReader(
- payload.data(), payload.size()));
+ element_readers.push_back(make_scoped_ptr(
+ new UploadBytesElementReader(payload.data(), payload.size())));
scoped_ptr<UploadDataStream> body(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
ASSERT_EQ(OK, body->Init(CompletionCallback()));
// Yes, should be merged if the in-memory body is small here.
ASSERT_TRUE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -188,13 +188,13 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_SmallBodyInMemory) {
}
TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) {
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
const std::string payload(10000, 'a'); // 'a' x 10000.
- element_readers.push_back(new UploadBytesElementReader(
- payload.data(), payload.size()));
+ element_readers.push_back(make_scoped_ptr(
+ new UploadBytesElementReader(payload.data(), payload.size())));
scoped_ptr<UploadDataStream> body(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
ASSERT_EQ(OK, body->Init(CompletionCallback()));
// Shouldn't be merged if the in-memory body is large here.
ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -333,9 +333,10 @@ TEST(HttpStreamParser, SentBytesPost) {
scoped_ptr<ClientSocketHandle> socket_handle =
CreateConnectedSocketHandle(&data);
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadBytesElementReader("hello world!", 12));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(
+ make_scoped_ptr(new UploadBytesElementReader("hello world!", 12)));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
HttpRequestInfo request;
@@ -1034,12 +1035,12 @@ TEST(HttpStreamParser, ReceivedBytesNormal) {
get_runner.AddRead(response);
get_runner.SetupParserAndSendRequest();
get_runner.ReadHeaders();
- int64 headers_size = headers.size();
+ int64_t headers_size = headers.size();
EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
int body_size = body.size();
int read_lengths[] = {body_size, 0};
get_runner.ReadBody(body_size, read_lengths);
- int64 response_size = response.size();
+ int64_t response_size = response.size();
EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
}
@@ -1058,14 +1059,14 @@ TEST(HttpStreamParser, ReceivedBytesExcludesNextResponse) {
get_runner.SetupParserAndSendRequest();
get_runner.ReadHeaders();
EXPECT_EQ(39, get_runner.parser()->received_bytes());
- int64 headers_size = headers.size();
+ int64_t headers_size = headers.size();
EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
int body_size = body.size();
int read_lengths[] = {body_size, 0};
get_runner.ReadBody(body_size, read_lengths);
- int64 response_size = response.size();
+ int64_t response_size = response.size();
EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
- int64 next_response_size = next_response.size();
+ int64_t next_response_size = next_response.size();
EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
}
@@ -1079,7 +1080,7 @@ TEST(HttpStreamParser, ReceivedBytesExcludesNextResponse) {
TEST(HttpStreamParser, ReceivedBytesMultiReadExcludesNextResponse) {
std::string headers = "HTTP/1.1 200 OK\r\n"
"Content-Length: 36\r\n\r\n";
- int64 user_buf_len = 32;
+ int64_t user_buf_len = 32;
std::string body_start = std::string(user_buf_len, '#');
int body_start_size = body_start.size();
EXPECT_EQ(user_buf_len, body_start_size);
@@ -1093,14 +1094,14 @@ TEST(HttpStreamParser, ReceivedBytesMultiReadExcludesNextResponse) {
get_runner.AddRead(response_end);
get_runner.SetupParserAndSendRequest();
get_runner.ReadHeaders();
- int64 headers_size = headers.size();
+ int64_t headers_size = headers.size();
EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
int body_end_size = body_end.size();
int read_lengths[] = {body_start_size, body_end_size, 0};
get_runner.ReadBody(body_start_size, read_lengths);
- int64 response_size = response_start.size() + body_end_size;
+ int64_t response_size = response_start.size() + body_end_size;
EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
- int64 next_response_size = next_response.size();
+ int64_t next_response_size = next_response.size();
EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
}
@@ -1120,14 +1121,14 @@ TEST(HttpStreamParser, ReceivedBytesFromReadBufExcludesNextResponse) {
get_runner.AddInitialData(data);
get_runner.SetupParserAndSendRequest();
get_runner.ReadHeaders();
- int64 headers_size = headers.size();
+ int64_t headers_size = headers.size();
EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
int body_size = body.size();
int read_lengths[] = {body_size, 0};
get_runner.ReadBody(body_size, read_lengths);
- int64 response_size = response.size();
+ int64_t response_size = response.size();
EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
- int64 next_response_size = next_response.size();
+ int64_t next_response_size = next_response.size();
EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
}
@@ -1136,7 +1137,7 @@ TEST(HttpStreamParser, ReceivedBytesFromReadBufExcludesNextResponse) {
TEST(HttpStreamParser, ReceivedBytesUseReadBuf) {
std::string buffer = "HTTP/1.1 200 OK\r\n";
std::string remaining_headers = "Content-Length: 7\r\n\r\n";
- int64 headers_size = buffer.size() + remaining_headers.size();
+ int64_t headers_size = buffer.size() + remaining_headers.size();
std::string body = "content";
std::string response = remaining_headers + body;
@@ -1171,9 +1172,9 @@ TEST(HttpStreamParser, ReceivedBytesChunkedTransferExcludesNextResponse) {
get_runner.ReadHeaders();
int read_lengths[] = {4, 3, 6, 2, 6, 0};
get_runner.ReadBody(7, read_lengths);
- int64 response_size = response.size();
+ int64_t response_size = response.size();
EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
- int64 next_response_size = next_response.size();
+ int64_t next_response_size = next_response.size();
EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
}
@@ -1199,11 +1200,11 @@ TEST(HttpStreamParser, ReceivedBytesMultipleReads) {
get_runner.AddRead(blocks[i]);
get_runner.SetupParserAndSendRequest();
get_runner.ReadHeaders();
- int64 headers_size = headers.size();
+ int64_t headers_size = headers.size();
EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
int read_lengths[] = {1, 4, 4, 4, 4, 4, 4, 4, 4, 0};
get_runner.ReadBody(receive_length + 1, read_lengths);
- int64 response_size = response.size();
+ int64_t response_size = response.size();
EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
}
@@ -1212,7 +1213,7 @@ TEST(HttpStreamParser, ReceivedBytesIncludesContinueHeader) {
std::string status100 = "HTTP/1.1 100 OK\r\n\r\n";
std::string headers = "HTTP/1.1 200 OK\r\n"
"Content-Length: 7\r\n\r\n";
- int64 headers_size = status100.size() + headers.size();
+ int64_t headers_size = status100.size() + headers.size();
std::string body = "content";
std::string response = headers + body;
@@ -1222,12 +1223,12 @@ TEST(HttpStreamParser, ReceivedBytesIncludesContinueHeader) {
get_runner.SetupParserAndSendRequest();
get_runner.ReadHeaders();
EXPECT_EQ(100, get_runner.response_info()->headers->response_code());
- int64 status100_size = status100.size();
+ int64_t status100_size = status100.size();
EXPECT_EQ(status100_size, get_runner.parser()->received_bytes());
get_runner.ReadHeaders();
EXPECT_EQ(200, get_runner.response_info()->headers->response_code());
EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
- int64 response_size = headers_size + body.size();
+ int64_t response_size = headers_size + body.size();
int body_size = body.size();
int read_lengths[] = {body_size, 0};
get_runner.ReadBody(body_size, read_lengths);
diff --git a/chromium/net/http/http_transaction.h b/chromium/net/http/http_transaction.h
index 9ccf3f11cf1..8ee37235e40 100644
--- a/chromium/net/http/http_transaction.h
+++ b/chromium/net/http/http_transaction.h
@@ -9,6 +9,7 @@
#include "net/base/completion_callback.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/base/upload_progress.h"
@@ -26,6 +27,7 @@ class IOBuffer;
struct LoadTimingInfo;
class ProxyInfo;
class QuicServerInfo;
+class SSLPrivateKey;
class X509Certificate;
// Represents a single HTTP transaction (i.e., a single request/response pair).
@@ -80,6 +82,7 @@ class NET_EXPORT_PRIVATE HttpTransaction {
// Restarts the HTTP transaction with a client certificate.
virtual int RestartWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
const CompletionCallback& callback) = 0;
// Restarts the HTTP transaction with authentication credentials.
@@ -166,6 +169,9 @@ class NET_EXPORT_PRIVATE HttpTransaction {
// unavailable.
virtual bool GetRemoteEndpoint(IPEndPoint* endpoint) const = 0;
+ // Populates network error details for this transaction.
+ virtual void PopulateNetErrorDetails(NetErrorDetails* details) const = 0;
+
// Called when the priority of the parent job changes.
virtual void SetPriority(RequestPriority priority) = 0;
diff --git a/chromium/net/http/http_transaction_test_util.cc b/chromium/net/http/http_transaction_test_util.cc
index 628c8fa884f..4a97ae618e9 100644
--- a/chromium/net/http/http_transaction_test_util.cc
+++ b/chromium/net/http/http_transaction_test_util.cc
@@ -5,6 +5,7 @@
#include "net/http/http_transaction_test_util.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/location.h"
@@ -207,7 +208,7 @@ void TestTransactionConsumer::DidFinish(int result) {
state_ = DONE;
error_ = result;
if (--quit_counter_ == 0)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
void TestTransactionConsumer::Read() {
@@ -244,6 +245,7 @@ MockNetworkTransaction::MockNetworkTransaction(RequestPriority priority,
received_bytes_(0),
sent_bytes_(0),
socket_log_id_(NetLog::Source::kInvalidId),
+ done_reading_called_(false),
weak_factory_(this) {}
MockNetworkTransaction::~MockNetworkTransaction() {}
@@ -265,6 +267,7 @@ int MockNetworkTransaction::RestartIgnoringLastError(
int MockNetworkTransaction::RestartWithCertificate(
X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
const CompletionCallback& callback) {
return ERR_FAILED;
}
@@ -284,6 +287,11 @@ int MockNetworkTransaction::RestartWithAuth(
return StartInternal(&auth_request_info, callback, BoundNetLog());
}
+void MockNetworkTransaction::PopulateNetErrorDetails(
+ NetErrorDetails* /*details*/) const {
+ NOTIMPLEMENTED();
+}
+
bool MockNetworkTransaction::IsReadyToRestartForAuth() {
if (!request_)
return false;
@@ -300,6 +308,7 @@ bool MockNetworkTransaction::IsReadyToRestartForAuth() {
int MockNetworkTransaction::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
+ CHECK(!done_reading_called_);
int data_len = static_cast<int>(data_.size());
int num = std::min(buf_len, data_len - data_cursor_);
if (test_mode_ & TEST_MODE_SLOW_READ)
@@ -334,6 +343,8 @@ int64_t MockNetworkTransaction::GetTotalSentBytes() const {
}
void MockNetworkTransaction::DoneReading() {
+ CHECK(!done_reading_called_);
+ done_reading_called_ = true;
if (transaction_factory_.get())
transaction_factory_->TransactionDoneReading();
}
@@ -505,6 +516,7 @@ MockNetworkLayer::MockNetworkLayer()
MockNetworkLayer::~MockNetworkLayer() {}
void MockNetworkLayer::TransactionDoneReading() {
+ CHECK(!done_reading_called_);
done_reading_called_ = true;
}
@@ -519,7 +531,7 @@ int MockNetworkLayer::CreateTransaction(RequestPriority priority,
scoped_ptr<MockNetworkTransaction> mock_transaction(
new MockNetworkTransaction(priority, this));
last_transaction_ = mock_transaction->AsWeakPtr();
- *trans = mock_transaction.Pass();
+ *trans = std::move(mock_transaction);
return OK;
}
diff --git a/chromium/net/http/http_transaction_test_util.h b/chromium/net/http/http_transaction_test_util.h
index 61aaeee9b2e..54e7c522c74 100644
--- a/chromium/net/http/http_transaction_test_util.h
+++ b/chromium/net/http/http_transaction_test_util.h
@@ -17,6 +17,7 @@
#include "base/strings/string16.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
+#include "net/base/net_error_details.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/base/test_completion_callback.h"
@@ -32,6 +33,7 @@ namespace net {
class HttpRequestHeaders;
class IOBuffer;
+class SSLPrivateKey;
class X509Certificate;
struct HttpRequestInfo;
@@ -182,6 +184,7 @@ class MockNetworkTransaction
int RestartIgnoringLastError(const CompletionCallback& callback) override;
int RestartWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key,
const CompletionCallback& callback) override;
int RestartWithAuth(const AuthCredentials& credentials,
@@ -192,6 +195,7 @@ class MockNetworkTransaction
int Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) const override;
void StopCaching() override;
@@ -266,6 +270,8 @@ class MockNetworkTransaction
// be initialized.
unsigned int socket_log_id_;
+ bool done_reading_called_;
+
base::WeakPtrFactory<MockNetworkTransaction> weak_factory_;
};
diff --git a/chromium/net/http/http_util.cc b/chromium/net/http/http_util.cc
index f1e5143e701..08382d9a18a 100644
--- a/chromium/net/http/http_util.cc
+++ b/chromium/net/http/http_util.cc
@@ -9,7 +9,6 @@
#include <algorithm>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -18,7 +17,6 @@
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
-
namespace net {
// Helpers --------------------------------------------------------------------
@@ -210,7 +208,7 @@ bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier,
HttpByteRange range;
// Try to obtain first-byte-pos.
if (!first_byte_pos.empty()) {
- int64 first_byte_position = -1;
+ int64_t first_byte_position = -1;
if (!base::StringToInt64(first_byte_pos, &first_byte_position))
return false;
range.set_first_byte_position(first_byte_position);
@@ -225,7 +223,7 @@ bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier,
// We have last-byte-pos or suffix-byte-range-spec in this case.
if (!last_byte_pos.empty()) {
- int64 last_byte_position;
+ int64_t last_byte_position;
if (!base::StringToInt64(last_byte_pos, &last_byte_position))
return false;
if (range.HasFirstBytePosition())
@@ -346,6 +344,24 @@ bool HttpUtil::IsValidHeaderValue(const std::string& value) {
}
// static
+bool HttpUtil::IsValidHeaderValueRFC7230(const base::StringPiece& value) {
+ // This empty string is a valid header-value.
+ if (value.empty())
+ return true;
+
+ // Check leading/trailing whitespaces.
+ if (IsLWS(value[0]) || IsLWS(value[value.size() - 1]))
+ return false;
+
+ // Check each octet is |field-vchar|, |SP| or |HTAB|.
+ for (unsigned char c : value) {
+ if (c == 0x7F || (c < 0x20 && c != '\t'))
+ return false;
+ }
+ return true;
+}
+
+// static
std::string HttpUtil::StripHeaders(const std::string& headers,
const char* const headers_to_remove[],
size_t headers_to_remove_len) {
diff --git a/chromium/net/http/http_util.h b/chromium/net/http/http_util.h
index 1bb3c93f8ab..13209b8f421 100644
--- a/chromium/net/http/http_util.h
+++ b/chromium/net/http/http_util.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_HTTP_UTIL_H_
#define NET_HTTP_HTTP_UTIL_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
@@ -80,6 +82,11 @@ class NET_EXPORT HttpUtil {
// a fully RFC-2616-compliant header value validation.
static bool IsValidHeaderValue(const std::string& value);
+ // Returns true if |value| is a valid HTTP header value according to
+ // RFC 7230 and doesn't contain CR or LF.
+ // i.e. returns true if |value| matches |*field-content| in RFC 7230.
+ static bool IsValidHeaderValueRFC7230(const base::StringPiece& value);
+
// Strips all header lines from |headers| whose name matches
// |headers_to_remove|. |headers_to_remove| is a list of null-terminated
// lower-case header names, with array length |headers_to_remove_len|.
diff --git a/chromium/net/http/http_util_unittest.cc b/chromium/net/http/http_util_unittest.cc
index a5c984db66b..e83f6b99163 100644
--- a/chromium/net/http/http_util_unittest.cc
+++ b/chromium/net/http/http_util_unittest.cc
@@ -4,7 +4,6 @@
#include <algorithm>
-#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "net/http/http_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -766,9 +765,9 @@ TEST(HttpUtilTest, ParseRanges) {
bool expected_return_value;
size_t expected_ranges_size;
const struct {
- int64 expected_first_byte_position;
- int64 expected_last_byte_position;
- int64 expected_suffix_length;
+ int64_t expected_first_byte_position;
+ int64_t expected_last_byte_position;
+ int64_t expected_suffix_length;
} expected_ranges[10];
} tests[] = {
{ "Range: bytes=0-10",
@@ -1178,4 +1177,27 @@ TEST(HttpUtilTest, NameValuePairsIteratorMissingEndQuote) {
&parser, false, true, std::string(), std::string()));
}
+TEST(HttpUtilTest, IsValidHeaderValueRFC7230) {
+ EXPECT_TRUE(HttpUtil::IsValidHeaderValueRFC7230(""));
+
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230(" "));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230(" q"));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("q "));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("\t"));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("\tq"));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("q\t"));
+
+ EXPECT_TRUE(HttpUtil::IsValidHeaderValueRFC7230("q q"));
+ EXPECT_TRUE(HttpUtil::IsValidHeaderValueRFC7230("q\tq"));
+
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230(std::string("\0", 1)));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230(std::string("q\0q", 3)));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("q\rq"));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("q\nq"));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("q\x01q"));
+ EXPECT_FALSE(HttpUtil::IsValidHeaderValueRFC7230("q\x7fq"));
+
+ EXPECT_TRUE(HttpUtil::IsValidHeaderValueRFC7230("q\x80q"));
+}
+
} // namespace net
diff --git a/chromium/net/http/http_version.h b/chromium/net/http/http_version.h
index 127e7115bf9..13864a65c60 100644
--- a/chromium/net/http/http_version.h
+++ b/chromium/net/http/http_version.h
@@ -5,7 +5,7 @@
#ifndef NET_HTTP_HTTP_VERSION_H_
#define NET_HTTP_HTTP_VERSION_H_
-#include "base/basictypes.h"
+#include <stdint.h>
namespace net {
@@ -16,17 +16,13 @@ class HttpVersion {
HttpVersion() : value_(0) { }
// Build from unsigned major/minor pair.
- HttpVersion(uint16 major, uint16 minor) : value_(major << 16 | minor) { }
+ HttpVersion(uint16_t major, uint16_t minor) : value_(major << 16 | minor) {}
// Major version number.
- uint16 major_value() const {
- return value_ >> 16;
- }
+ uint16_t major_value() const { return value_ >> 16; }
// Minor version number.
- uint16 minor_value() const {
- return value_ & 0xffff;
- }
+ uint16_t minor_value() const { return value_ & 0xffff; }
// Overloaded operators:
@@ -50,7 +46,7 @@ class HttpVersion {
}
private:
- uint32 value_; // Packed as <major>:<minor>
+ uint32_t value_; // Packed as <major>:<minor>
};
} // namespace net
diff --git a/chromium/net/http/md4.cc b/chromium/net/http/md4.cc
index da1e8d3b202..7de9cb0b64e 100644
--- a/chromium/net/http/md4.cc
+++ b/chromium/net/http/md4.cc
@@ -49,8 +49,8 @@
#include <string.h>
-typedef uint32 Uint32;
-typedef uint8 Uint8;
+typedef uint32_t Uint32;
+typedef uint8_t Uint8;
/* the "conditional" function */
#define F(x,y,z) (((x) & (y)) | (~(x) & (z)))
diff --git a/chromium/net/http/md4.h b/chromium/net/http/md4.h
index b416e261de0..0b74df5430d 100644
--- a/chromium/net/http/md4.h
+++ b/chromium/net/http/md4.h
@@ -44,7 +44,7 @@
#ifndef NET_HTTP_MD4_H_
#define NET_HTTP_MD4_H_
-#include "base/basictypes.h"
+#include <stdint.h>
namespace net {
namespace weak_crypto {
@@ -66,7 +66,7 @@ namespace weak_crypto {
* interface would make more sense if that were a requirement. Currently, this
* is good enough for the applications we care about.
*/
-void MD4Sum(const uint8 *input, uint32 inputLen, uint8 *result);
+void MD4Sum(const uint8_t* input, uint32_t inputLen, uint8_t* result);
} // namespace net::weak_crypto
} // namespace net
diff --git a/chromium/net/http/mock_allow_http_auth_preferences.cc b/chromium/net/http/mock_allow_http_auth_preferences.cc
new file mode 100644
index 00000000000..8951139aa31
--- /dev/null
+++ b/chromium/net/http/mock_allow_http_auth_preferences.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2011 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/mock_allow_http_auth_preferences.h"
+
+namespace net {
+
+MockAllowHttpAuthPreferences::MockAllowHttpAuthPreferences()
+ : HttpAuthPreferences(std::vector<std::string>()
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ ,
+ std::string()
+#endif
+ ) {
+}
+
+MockAllowHttpAuthPreferences::~MockAllowHttpAuthPreferences() {}
+
+bool MockAllowHttpAuthPreferences::CanUseDefaultCredentials(
+ const GURL& auth_origin) const {
+ return true;
+}
+
+bool MockAllowHttpAuthPreferences::CanDelegate(const GURL& auth_origin) const {
+ return true;
+}
+
+} // namespace net
diff --git a/chromium/net/http/mock_allow_http_auth_preferences.h b/chromium/net/http/mock_allow_http_auth_preferences.h
new file mode 100644
index 00000000000..3b51d7a0d63
--- /dev/null
+++ b/chromium/net/http/mock_allow_http_auth_preferences.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2011 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_MOCK_ALLOW_HTTP_AUTH_PREFERENCES_H_
+#define NET_HTTP_MOCK_ALLOW_HTTP_AUTH_PREFERENCES_H_
+
+#include "base/macros.h"
+#include "net/http/http_auth_preferences.h"
+
+namespace net {
+
+// An HttpAuthPreferences class which allows all origins to use default
+// credentials and delegate. This should only be used in unit testing.
+class MockAllowHttpAuthPreferences : public HttpAuthPreferences {
+ public:
+ MockAllowHttpAuthPreferences();
+ ~MockAllowHttpAuthPreferences() override;
+
+ bool CanUseDefaultCredentials(const GURL& auth_origin) const override;
+ bool CanDelegate(const GURL& auth_origin) const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockAllowHttpAuthPreferences);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_MOCK_ALLOW_HTTP_AUTH_PREFERENCES_H_
diff --git a/chromium/net/http/mock_allow_url_security_manager.cc b/chromium/net/http/mock_allow_url_security_manager.cc
deleted file mode 100644
index e8b2c4ffe2b..00000000000
--- a/chromium/net/http/mock_allow_url_security_manager.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2011 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/mock_allow_url_security_manager.h"
-
-namespace net {
-
-MockAllowURLSecurityManager::MockAllowURLSecurityManager() {}
-
-MockAllowURLSecurityManager::~MockAllowURLSecurityManager() {}
-
-bool MockAllowURLSecurityManager::CanUseDefaultCredentials(
- const GURL& auth_origin) const {
- return true;
-}
-
-bool MockAllowURLSecurityManager::CanDelegate(const GURL& auth_origin) const {
- return true;
-}
-
-} // namespace net
diff --git a/chromium/net/http/mock_allow_url_security_manager.h b/chromium/net/http/mock_allow_url_security_manager.h
deleted file mode 100644
index 2a0b2055222..00000000000
--- a/chromium/net/http/mock_allow_url_security_manager.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011 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_MOCK_ALLOW_URL_SECURITY_MANAGER_H_
-#define NET_HTTP_MOCK_ALLOW_URL_SECURITY_MANAGER_H_
-
-#include "net/http/url_security_manager.h"
-
-namespace net {
-
-// An URLSecurityManager which is very permissive and which should only be used
-// in unit testing.
-class MockAllowURLSecurityManager : public URLSecurityManager {
- public:
- MockAllowURLSecurityManager();
- ~MockAllowURLSecurityManager() override;
-
- bool CanUseDefaultCredentials(const GURL& auth_origin) const override;
- bool CanDelegate(const GURL& auth_origin) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockAllowURLSecurityManager);
-};
-
-} // namespace net
-
-#endif // NET_HTTP_MOCK_ALLOW_URL_SECURITY_MANAGER_H_
diff --git a/chromium/net/http/mock_http_cache.cc b/chromium/net/http/mock_http_cache.cc
index d939a3d8f96..533177a9f89 100644
--- a/chromium/net/http/mock_http_cache.cc
+++ b/chromium/net/http/mock_http_cache.cc
@@ -4,6 +4,9 @@
#include "net/http/mock_http_cache.h"
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
@@ -86,9 +89,9 @@ base::Time MockDiskEntry::GetLastModified() const {
return base::Time::FromInternalValue(0);
}
-int32 MockDiskEntry::GetDataSize(int index) const {
+int32_t MockDiskEntry::GetDataSize(int index) const {
DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
- return static_cast<int32>(data_[index].size());
+ return static_cast<int32_t>(data_[index].size());
}
int MockDiskEntry::ReadData(int index,
@@ -146,7 +149,7 @@ int MockDiskEntry::WriteData(int index,
return ERR_IO_PENDING;
}
-int MockDiskEntry::ReadSparseData(int64 offset,
+int MockDiskEntry::ReadSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
@@ -161,7 +164,7 @@ int MockDiskEntry::ReadSparseData(int64 offset,
if (fail_requests_)
return ERR_CACHE_READ_FAILURE;
- DCHECK(offset < kint32max);
+ DCHECK(offset < std::numeric_limits<int32_t>::max());
int real_offset = static_cast<int>(offset);
if (!buf_len)
return 0;
@@ -179,7 +182,7 @@ int MockDiskEntry::ReadSparseData(int64 offset,
return ERR_IO_PENDING;
}
-int MockDiskEntry::WriteSparseData(int64 offset,
+int MockDiskEntry::WriteSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
@@ -201,7 +204,7 @@ int MockDiskEntry::WriteSparseData(int64 offset,
if (fail_requests_)
return ERR_CACHE_READ_FAILURE;
- DCHECK(offset < kint32max);
+ DCHECK(offset < std::numeric_limits<int32_t>::max());
int real_offset = static_cast<int>(offset);
if (static_cast<int>(data_[1].size()) < real_offset + buf_len)
@@ -215,9 +218,9 @@ int MockDiskEntry::WriteSparseData(int64 offset,
return ERR_IO_PENDING;
}
-int MockDiskEntry::GetAvailableRange(int64 offset,
+int MockDiskEntry::GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) {
DCHECK(!callback.is_null());
if (!sparse_ || busy_ || cancel_)
@@ -229,7 +232,7 @@ int MockDiskEntry::GetAvailableRange(int64 offset,
return ERR_CACHE_READ_FAILURE;
*start = offset;
- DCHECK(offset < kint32max);
+ DCHECK(offset < std::numeric_limits<int32_t>::max());
int real_offset = static_cast<int>(offset);
if (static_cast<int>(data_[1].size()) < real_offset)
return 0;
@@ -368,8 +371,8 @@ CacheType MockDiskCache::GetCacheType() const {
return DISK_CACHE;
}
-int32 MockDiskCache::GetEntryCount() const {
- return static_cast<int32>(entries_.size());
+int32_t MockDiskCache::GetEntryCount() const {
+ return static_cast<int32_t>(entries_.size());
}
int MockDiskCache::OpenEntry(const std::string& key,
@@ -477,6 +480,11 @@ int MockDiskCache::DoomEntriesSince(const base::Time initial_time,
return ERR_NOT_IMPLEMENTED;
}
+int MockDiskCache::CalculateSizeOfAllEntries(
+ const CompletionCallback& callback) {
+ return ERR_NOT_IMPLEMENTED;
+}
+
class MockDiskCache::NotImplementedIterator : public Iterator {
public:
int OpenNextEntry(disk_cache::Entry** next_entry,
@@ -520,12 +528,13 @@ int MockBackendFactory::CreateBackend(NetLog* net_log,
//-----------------------------------------------------------------------------
MockHttpCache::MockHttpCache()
- : http_cache_(new MockNetworkLayer(), NULL, new MockBackendFactory()) {
-}
+ : MockHttpCache(make_scoped_ptr(new MockBackendFactory())) {}
-MockHttpCache::MockHttpCache(HttpCache::BackendFactory* disk_cache_factory)
- : http_cache_(new MockNetworkLayer(), NULL, disk_cache_factory) {
-}
+MockHttpCache::MockHttpCache(
+ scoped_ptr<HttpCache::BackendFactory> disk_cache_factory)
+ : http_cache_(make_scoped_ptr(new MockNetworkLayer()),
+ std::move(disk_cache_factory),
+ true) {}
disk_cache::Backend* MockHttpCache::backend() {
TestCompletionCallback cb;
diff --git a/chromium/net/http/mock_http_cache.h b/chromium/net/http/mock_http_cache.h
index 632bb3e63c1..86b8e51d758 100644
--- a/chromium/net/http/mock_http_cache.h
+++ b/chromium/net/http/mock_http_cache.h
@@ -10,6 +10,8 @@
#ifndef NET_HTTP_MOCK_HTTP_CACHE_H_
#define NET_HTTP_MOCK_HTTP_CACHE_H_
+#include <stdint.h>
+
#include "base/containers/hash_tables.h"
#include "base/strings/string_split.h"
#include "net/disk_cache/disk_cache.h"
@@ -33,7 +35,7 @@ class MockDiskEntry : public disk_cache::Entry,
std::string GetKey() const override;
base::Time GetLastUsed() const override;
base::Time GetLastModified() const override;
- int32 GetDataSize(int index) const override;
+ int32_t GetDataSize(int index) const override;
int ReadData(int index,
int offset,
IOBuffer* buf,
@@ -45,17 +47,17 @@ class MockDiskEntry : public disk_cache::Entry,
int buf_len,
const CompletionCallback& callback,
bool truncate) override;
- int ReadSparseData(int64 offset,
+ int ReadSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int WriteSparseData(int64 offset,
+ int WriteSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int GetAvailableRange(int64 offset,
+ int GetAvailableRange(int64_t offset,
int len,
- int64* start,
+ int64_t* start,
const CompletionCallback& callback) override;
bool CouldBeSparse() const override;
void CancelSparseIO() override;
@@ -112,7 +114,7 @@ class MockDiskCache : public disk_cache::Backend {
~MockDiskCache() override;
CacheType GetCacheType() const override;
- int32 GetEntryCount() const override;
+ int32_t GetEntryCount() const override;
int OpenEntry(const std::string& key,
disk_cache::Entry** entry,
const CompletionCallback& callback) override;
@@ -127,6 +129,7 @@ class MockDiskCache : public disk_cache::Backend {
const CompletionCallback& callback) override;
int DoomEntriesSince(base::Time initial_time,
const CompletionCallback& callback) override;
+ int CalculateSizeOfAllEntries(const CompletionCallback& callback) override;
scoped_ptr<Iterator> CreateIterator() override;
void GetStats(base::StringPairs* stats) override;
void OnExternalCacheHit(const std::string& key) override;
@@ -176,7 +179,8 @@ class MockBackendFactory : public HttpCache::BackendFactory {
class MockHttpCache {
public:
MockHttpCache();
- explicit MockHttpCache(HttpCache::BackendFactory* disk_cache_factory);
+ explicit MockHttpCache(
+ scoped_ptr<HttpCache::BackendFactory> disk_cache_factory);
HttpCache* http_cache() { return &http_cache_; }
diff --git a/chromium/net/http/mock_sspi_library_win.cc b/chromium/net/http/mock_sspi_library_win.cc
index 77218538655..1d3379cd278 100644
--- a/chromium/net/http/mock_sspi_library_win.cc
+++ b/chromium/net/http/mock_sspi_library_win.cc
@@ -47,7 +47,7 @@ SECURITY_STATUS MockSSPILibrary::InitializeSecurityContext(
// Fill in the outbound buffer with garbage data.
PSecBuffer out_buffer = pOutput->pBuffers;
out_buffer->cbBuffer = 2;
- uint8* buf = reinterpret_cast<uint8 *>(out_buffer->pvBuffer);
+ uint8_t* buf = reinterpret_cast<uint8_t*>(out_buffer->pvBuffer);
buf[0] = 0xAB;
buf[1] = 0xBA;
diff --git a/chromium/net/http/partial_data.cc b/chromium/net/http/partial_data.cc
index 8e1eb0ab846..915aaa4bb92 100644
--- a/chromium/net/http/partial_data.cc
+++ b/chromium/net/http/partial_data.cc
@@ -4,6 +4,8 @@
#include "net/http/partial_data.h"
+#include <limits>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/format_macros.h"
@@ -72,8 +74,9 @@ void PartialData::SetHeaders(const HttpRequestHeaders& headers) {
void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const {
DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange());
- int64 end = byte_range_.IsSuffixByteRange() ?
- byte_range_.suffix_length() : byte_range_.last_byte_position();
+ int64_t end = byte_range_.IsSuffixByteRange()
+ ? byte_range_.suffix_length()
+ : byte_range_.last_byte_position();
headers->CopyFrom(extra_headers_);
if (truncated_ || !byte_range_.IsValid())
@@ -102,7 +105,7 @@ int PartialData::ShouldValidateCache(disk_cache::Entry* entry,
if (sparse_entry_) {
DCHECK(callback_.is_null());
- int64* start = new int64;
+ int64_t* start = new int64_t;
// This callback now owns "start". We make sure to keep it
// in a local variable since we want to use it later.
CompletionCallback cb =
@@ -193,7 +196,7 @@ bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
// Now we avoid resume if there is no content length, but that was not
// always the case so double check here.
- int64 total_length = headers->GetContentLength();
+ int64_t total_length = headers->GetContentLength();
if (total_length <= 0)
return false;
@@ -220,7 +223,7 @@ bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
if (!headers->HasStrongValidators())
return false;
- int64 length_value = headers->GetContentLength();
+ int64_t length_value = headers->GetContentLength();
if (length_value <= 0)
return false; // We must have stored the resource length.
@@ -270,7 +273,7 @@ bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) {
byte_range_.HasLastBytePosition();
}
- int64 start, end, total_length;
+ int64_t start, end, total_length;
if (!headers->GetContentRange(&start, &end, &total_length))
return false;
if (total_length <= 0)
@@ -280,7 +283,7 @@ bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) {
// A server should return a valid content length with a 206 (per the standard)
// but relax the requirement because some servers don't do that.
- int64 content_length = headers->GetContentLength();
+ int64_t content_length = headers->GetContentLength();
if (content_length > 0 && content_length != end - start + 1)
return false;
@@ -374,7 +377,7 @@ int PartialData::CacheRead(disk_cache::Entry* entry,
rv = entry->ReadSparseData(current_range_start_, data, read_len,
callback);
} else {
- if (current_range_start_ > kint32max)
+ if (current_range_start_ > std::numeric_limits<int32_t>::max())
return ERR_INVALID_ARGUMENT;
rv = entry->ReadData(kDataStream, static_cast<int>(current_range_start_),
@@ -392,7 +395,7 @@ int PartialData::CacheWrite(disk_cache::Entry* entry,
return entry->WriteSparseData(
current_range_start_, data, data_len, callback);
} else {
- if (current_range_start_ > kint32max)
+ if (current_range_start_ > std::numeric_limits<int32_t>::max())
return ERR_INVALID_ARGUMENT;
return entry->WriteData(kDataStream, static_cast<int>(current_range_start_),
@@ -415,16 +418,16 @@ void PartialData::OnNetworkReadCompleted(int result) {
}
int PartialData::GetNextRangeLen() {
- int64 range_len =
- byte_range_.HasLastBytePosition() ?
- byte_range_.last_byte_position() - current_range_start_ + 1 :
- kint32max;
- if (range_len > kint32max)
- range_len = kint32max;
- return static_cast<int32>(range_len);
+ int64_t range_len =
+ byte_range_.HasLastBytePosition()
+ ? byte_range_.last_byte_position() - current_range_start_ + 1
+ : std::numeric_limits<int32_t>::max();
+ if (range_len > std::numeric_limits<int32_t>::max())
+ range_len = std::numeric_limits<int32_t>::max();
+ return static_cast<int32_t>(range_len);
}
-void PartialData::GetAvailableRangeCompleted(int64* start, int result) {
+void PartialData::GetAvailableRangeCompleted(int64_t* start, int result) {
DCHECK(!callback_.is_null());
DCHECK_NE(ERR_IO_PENDING, result);
diff --git a/chromium/net/http/partial_data.h b/chromium/net/http/partial_data.h
index 649d4623e01..29ccbb3c4a9 100644
--- a/chromium/net/http/partial_data.h
+++ b/chromium/net/http/partial_data.h
@@ -5,7 +5,9 @@
#ifndef NET_HTTP_PARTIAL_DATA_H_
#define NET_HTTP_PARTIAL_DATA_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/completion_callback.h"
#include "net/http/http_byte_range.h"
@@ -124,12 +126,12 @@ class PartialData {
int GetNextRangeLen();
// Completion routine for our callback.
- void GetAvailableRangeCompleted(int64* start, int result);
+ void GetAvailableRangeCompleted(int64_t* start, int result);
- int64 current_range_start_;
- int64 current_range_end_;
- int64 cached_start_;
- int64 resource_size_;
+ int64_t current_range_start_;
+ int64_t current_range_end_;
+ int64_t cached_start_;
+ int64_t resource_size_;
int cached_min_len_;
HttpByteRange byte_range_; // The range requested by the user.
// The clean set of extra headers (no ranges).
diff --git a/chromium/net/http/proxy_client_socket.cc b/chromium/net/http/proxy_client_socket.cc
index 3094b436a20..b0dd40be47d 100644
--- a/chromium/net/http/proxy_client_socket.cc
+++ b/chromium/net/http/proxy_client_socket.cc
@@ -45,9 +45,7 @@ void ProxyClientSocket::BuildTunnelRequest(
std::string host_and_port = endpoint.ToString();
*request_line =
base::StringPrintf("CONNECT %s HTTP/1.1\r\n", host_and_port.c_str());
- request_headers->SetHeader(HttpRequestHeaders::kHost, endpoint.port() == 443
- ? endpoint.host()
- : host_and_port);
+ request_headers->SetHeader(HttpRequestHeaders::kHost, host_and_port);
request_headers->SetHeader(HttpRequestHeaders::kProxyConnection,
"keep-alive");
if (!user_agent.empty())
diff --git a/chromium/net/http/proxy_client_socket.h b/chromium/net/http/proxy_client_socket.h
index 2d6688f72fd..b240689b726 100644
--- a/chromium/net/http/proxy_client_socket.h
+++ b/chromium/net/http/proxy_client_socket.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.cc b/chromium/net/http/proxy_connect_redirect_http_stream.cc
index d0f69fe7cec..2b26b08888f 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.cc
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.cc
@@ -106,6 +106,11 @@ void ProxyConnectRedirectHttpStream::Drain(HttpNetworkSession* session) {
NOTREACHED();
}
+void ProxyConnectRedirectHttpStream::PopulateNetErrorDetails(
+ NetErrorDetails* /*details*/) {
+ return;
+}
+
void ProxyConnectRedirectHttpStream::SetPriority(RequestPriority priority) {
// Nothing to do.
}
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.h b/chromium/net/http/proxy_connect_redirect_http_stream.h
index 1b0b6d6b163..af3940c2173 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.h
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.h
@@ -58,6 +58,7 @@ class ProxyConnectRedirectHttpStream : public HttpStream {
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
bool GetRemoteEndpoint(IPEndPoint* endpoint) override;
void Drain(HttpNetworkSession* session) override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) override;
// This function may be called.
void SetPriority(RequestPriority priority) override;
diff --git a/chromium/net/http/transport_security_persister.cc b/chromium/net/http/transport_security_persister.cc
index 78898c327e5..a07e632ab5d 100644
--- a/chromium/net/http/transport_security_persister.cc
+++ b/chromium/net/http/transport_security_persister.cc
@@ -4,6 +4,8 @@
#include "net/http/transport_security_persister.h"
+#include <utility>
+
#include "base/base64.h"
#include "base/bind.h"
#include "base/files/file_path.h"
@@ -162,7 +164,7 @@ bool TransportSecurityPersister::SerializeData(std::string* output) {
continue;
}
- toplevel.Set(key, serialized.Pass());
+ toplevel.Set(key, std::move(serialized));
}
TransportSecurityState::PKPStateIterator pkp_iterator(
@@ -181,7 +183,7 @@ bool TransportSecurityPersister::SerializeData(std::string* output) {
new base::DictionaryValue);
serialized = serialized_scoped.get();
PopulateEntryWithDefaults(serialized);
- toplevel.Set(key, serialized_scoped.Pass());
+ toplevel.Set(key, std::move(serialized_scoped));
}
serialized->SetBoolean(kPkpIncludeSubdomains, pkp_state.include_subdomains);
diff --git a/chromium/net/http/transport_security_persister.h b/chromium/net/http/transport_security_persister.h
index 27ecc23c19a..d4e1e36a2c0 100644
--- a/chromium/net/http/transport_security_persister.h
+++ b/chromium/net/http/transport_security_persister.h
@@ -37,6 +37,7 @@
#include "base/files/file_path.h"
#include "base/files/important_file_writer.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc
index 89d467151ba..8eb29434f86 100644
--- a/chromium/net/http/transport_security_state.cc
+++ b/chromium/net/http/transport_security_state.cc
@@ -4,18 +4,8 @@
#include "net/http/transport_security_state.h"
-#if defined(USE_OPENSSL)
-#include <openssl/ecdsa.h>
-#include <openssl/ssl.h>
-#else // !defined(USE_OPENSSL)
-#include <cryptohi.h>
-#include <hasht.h>
-#include <keyhi.h>
-#include <nspr.h>
-#include <pk11pub.h>
-#endif
-
#include <algorithm>
+#include <utility>
#include "base/base64.h"
#include "base/build_time.h"
@@ -29,27 +19,26 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
#include "base/values.h"
#include "crypto/sha2.h"
-#include "net/base/dns_util.h"
#include "net/base/host_port_pair.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
+#include "net/dns/dns_util.h"
#include "net/http/http_security_headers.h"
#include "net/ssl/ssl_info.h"
#include "url/gurl.h"
-#if defined(USE_OPENSSL)
-#include "crypto/openssl_util.h"
-#endif
-
namespace net {
namespace {
#include "net/http/transport_security_state_static.h"
+const size_t kMaxHPKPReportCacheEntries = 50;
+const int kTimeToRememberHPKPReportsMins = 60;
+const size_t kReportCacheKeyLength = 16;
+
std::string TimeToISO8601(const base::Time& t) {
base::Time::Exploded exploded;
t.UTCExplode(&exploded);
@@ -70,26 +59,37 @@ scoped_ptr<base::ListValue> GetPEMEncodedChainAsList(
for (const std::string& cert : pem_encoded_chain)
result->Append(make_scoped_ptr(new base::StringValue(cert)));
- return result.Pass();
+ return result;
+}
+
+bool HashReportForCache(const base::DictionaryValue& report,
+ const GURL& report_uri,
+ std::string* cache_key) {
+ char hashed[crypto::kSHA256Length];
+ std::string to_hash;
+ if (!base::JSONWriter::Write(report, &to_hash))
+ return false;
+ to_hash += "," + report_uri.spec();
+ crypto::SHA256HashString(to_hash, hashed, sizeof(hashed));
+ static_assert(kReportCacheKeyLength <= sizeof(hashed),
+ "HPKP report cache key size is larger than hash size.");
+ *cache_key = std::string(hashed, kReportCacheKeyLength);
+ return true;
}
bool GetHPKPReport(const HostPortPair& host_port_pair,
const TransportSecurityState::PKPState& pkp_state,
const X509Certificate* served_certificate_chain,
const X509Certificate* validated_certificate_chain,
- std::string* serialized_report) {
- // TODO(estark): keep track of reports already sent and rate-limit,
- // break loops
+ std::string* serialized_report,
+ std::string* cache_key) {
if (pkp_state.report_uri.is_empty())
return false;
base::DictionaryValue report;
base::Time now = base::Time::Now();
- report.SetString("date-time", TimeToISO8601(now));
report.SetString("hostname", host_port_pair.host());
report.SetInteger("port", host_port_pair.port());
- report.SetString("effective-expiration-date",
- TimeToISO8601(pkp_state.expiry));
report.SetBoolean("include-subdomains", pkp_state.include_subdomains);
report.SetString("noted-hostname", pkp_state.domain);
@@ -97,9 +97,10 @@ bool GetHPKPReport(const HostPortPair& host_port_pair,
GetPEMEncodedChainAsList(served_certificate_chain);
scoped_ptr<base::ListValue> validated_certificate_chain_list =
GetPEMEncodedChainAsList(validated_certificate_chain);
- report.Set("served-certificate-chain", served_certificate_chain_list.Pass());
+ report.Set("served-certificate-chain",
+ std::move(served_certificate_chain_list));
report.Set("validated-certificate-chain",
- validated_certificate_chain_list.Pass());
+ std::move(validated_certificate_chain_list));
scoped_ptr<base::ListValue> known_pin_list(new base::ListValue());
for (const auto& hash_value : pkp_state.spki_hashes) {
@@ -125,8 +126,20 @@ bool GetHPKPReport(const HostPortPair& host_port_pair,
scoped_ptr<base::Value>(new base::StringValue(known_pin)));
}
- report.Set("known-pins", known_pin_list.Pass());
+ report.Set("known-pins", std::move(known_pin_list));
+
+ // For the sent reports cache, do not include the effective expiration
+ // date. The expiration date will likely change every time the user
+ // visits the site, so it would prevent reports from being effectively
+ // deduplicated.
+ if (!HashReportForCache(report, pkp_state.report_uri, cache_key)) {
+ LOG(ERROR) << "Failed to compute cache key for HPKP violation report.";
+ return false;
+ }
+ report.SetString("date-time", TimeToISO8601(now));
+ report.SetString("effective-expiration-date",
+ TimeToISO8601(pkp_state.expiry));
if (!base::JSONWriter::Write(report, serialized_report)) {
LOG(ERROR) << "Failed to serialize HPKP violation report.";
return false;
@@ -145,42 +158,6 @@ bool IsReportUriValidForHost(const GURL& report_uri, const std::string& host) {
!report_uri.SchemeIsCryptographic());
}
-bool CheckPinsAndMaybeSendReport(
- const HostPortPair& host_port_pair,
- const TransportSecurityState::PKPState& pkp_state,
- const HashValueVector& hashes,
- const X509Certificate* served_certificate_chain,
- const X509Certificate* validated_certificate_chain,
- const TransportSecurityState::PublicKeyPinReportStatus report_status,
- TransportSecurityState::ReportSender* report_sender,
- std::string* failure_log) {
- if (pkp_state.CheckPublicKeyPins(hashes, failure_log))
- return true;
-
- if (!report_sender ||
- report_status != TransportSecurityState::ENABLE_PIN_REPORTS ||
- pkp_state.report_uri.is_empty()) {
- return false;
- }
-
- DCHECK(pkp_state.report_uri.is_valid());
- // Report URIs should not be used if they are the same host as the pin
- // and are HTTPS, to avoid going into a report-sending loop.
- if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host()))
- return false;
-
- std::string serialized_report;
-
- if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain,
- validated_certificate_chain, &serialized_report)) {
- return false;
- }
-
- report_sender->Send(pkp_state.report_uri, serialized_report);
-
- return false;
-}
-
std::string HashesToBase64String(const HashValueVector& hashes) {
std::string str;
for (size_t i = 0; i != hashes.size(); ++i) {
@@ -210,10 +187,9 @@ bool HashesIntersect(const HashValueVector& a,
return false;
}
-bool AddHash(const char* sha1_hash,
- HashValueVector* out) {
- HashValue hash(HASH_VALUE_SHA1);
- memcpy(hash.data(), sha1_hash, hash.size());
+bool AddHash(const char* sha256_hash, HashValueVector* out) {
+ HashValue hash(HASH_VALUE_SHA256);
+ memcpy(hash.data(), sha256_hash, hash.size());
out->push_back(hash);
return true;
}
@@ -248,7 +224,7 @@ std::string CanonicalizeHost(const std::string& host) {
// BitReader is a class that allows a bytestring to be read bit-by-bit.
class BitReader {
public:
- BitReader(const uint8* bytes, size_t num_bits)
+ BitReader(const uint8_t* bytes, size_t num_bits)
: bytes_(bytes),
num_bits_(num_bits),
num_bytes_((num_bits + 7) / 8),
@@ -274,16 +250,16 @@ class BitReader {
// Read sets the |num_bits| least-significant bits of |*out| to the value of
// the next |num_bits| bits from the input. It returns false if there are
// insufficient bits in the input or true otherwise.
- bool Read(unsigned num_bits, uint32* out) {
+ bool Read(unsigned num_bits, uint32_t* out) {
DCHECK_LE(num_bits, 32u);
- uint32 ret = 0;
+ uint32_t ret = 0;
for (unsigned i = 0; i < num_bits; ++i) {
bool bit;
if (!Next(&bit)) {
return false;
}
- ret |= static_cast<uint32>(bit) << (num_bits - 1 - i);
+ ret |= static_cast<uint32_t>(bit) << (num_bits - 1 - i);
}
*out = ret;
@@ -325,13 +301,13 @@ class BitReader {
}
private:
- const uint8* const bytes_;
+ const uint8_t* const bytes_;
const size_t num_bits_;
const size_t num_bytes_;
// current_byte_index_ contains the current byte offset in |bytes_|.
size_t current_byte_index_;
// current_byte_ contains the current byte of the input.
- uint8 current_byte_;
+ uint8_t current_byte_;
// num_bits_used_ contains the number of bits of |current_byte_| that have
// been read.
unsigned num_bits_used_;
@@ -346,11 +322,11 @@ class BitReader {
// The tree is decoded by walking rather than a table-driven approach.
class HuffmanDecoder {
public:
- HuffmanDecoder(const uint8* tree, size_t tree_bytes)
+ HuffmanDecoder(const uint8_t* tree, size_t tree_bytes)
: tree_(tree), tree_bytes_(tree_bytes) {}
bool Decode(BitReader* reader, char* out) {
- const uint8* current = &tree_[tree_bytes_ - 2];
+ const uint8_t* current = &tree_[tree_bytes_ - 2];
for (;;) {
bool bit;
@@ -358,7 +334,7 @@ class HuffmanDecoder {
return false;
}
- uint8 b = current[bit];
+ uint8_t b = current[bit];
if (b & 0x80) {
*out = static_cast<char>(b & 0x7f);
return true;
@@ -375,15 +351,15 @@ class HuffmanDecoder {
}
private:
- const uint8* const tree_;
+ const uint8_t* const tree_;
const size_t tree_bytes_;
};
// PreloadResult is the result of resolving a specific name in the preloaded
// data.
struct PreloadResult {
- uint32 pinset_id;
- uint32 domain_id;
+ uint32_t pinset_id;
+ uint32_t domain_id;
// hostname_offset contains the number of bytes from the start of the given
// hostname where the name of the matching entry starts.
size_t hostname_offset;
@@ -391,6 +367,8 @@ struct PreloadResult {
bool pkp_include_subdomains;
bool force_https;
bool has_pins;
+ bool expect_ct;
+ uint32_t expect_ct_report_uri_id;
};
// DecodeHSTSPreloadRaw resolves |hostname| in the preloaded data. It returns
@@ -518,6 +496,14 @@ bool DecodeHSTSPreloadRaw(const std::string& search_hostname,
}
}
+ if (!reader.Next(&tmp.expect_ct))
+ return false;
+
+ if (tmp.expect_ct) {
+ if (!reader.Read(4, &tmp.expect_ct_report_uri_id))
+ return false;
+ }
+
tmp.hostname_offset = hostname_offset;
if (hostname_offset == 0 || hostname[hostname_offset - 1] == '.') {
@@ -543,8 +529,8 @@ bool DecodeHSTSPreloadRaw(const std::string& search_hostname,
if (is_first_offset) {
// The first offset is backwards from the current position.
- uint32 jump_delta_bits;
- uint32 jump_delta;
+ uint32_t jump_delta_bits;
+ uint32_t jump_delta;
if (!reader.Read(5, &jump_delta_bits) ||
!reader.Read(jump_delta_bits, &jump_delta)) {
return false;
@@ -558,18 +544,18 @@ bool DecodeHSTSPreloadRaw(const std::string& search_hostname,
is_first_offset = false;
} else {
// Subsequent offsets are forward from the target of the first offset.
- uint32 is_long_jump;
+ uint32_t is_long_jump;
if (!reader.Read(1, &is_long_jump)) {
return false;
}
- uint32 jump_delta;
+ uint32_t jump_delta;
if (!is_long_jump) {
if (!reader.Read(7, &jump_delta)) {
return false;
}
} else {
- uint32 jump_delta_bits;
+ uint32_t jump_delta_bits;
if (!reader.Read(4, &jump_delta_bits) ||
!reader.Read(jump_delta_bits + 8, &jump_delta)) {
return false;
@@ -606,11 +592,16 @@ bool DecodeHSTSPreload(const std::string& hostname, PreloadResult* out) {
} // namespace
TransportSecurityState::TransportSecurityState()
- : delegate_(nullptr), report_sender_(nullptr), enable_static_pins_(true) {
+ : delegate_(nullptr),
+ report_sender_(nullptr),
+ enable_static_pins_(true),
+ enable_static_expect_ct_(true),
+ sent_reports_cache_(kMaxHPKPReportCacheEntries) {
// Static pinning is only enabled for official builds to make sure that
// others don't end up with pins that cannot be easily updated.
#if !defined(OFFICIAL_BUILD) || defined(OS_ANDROID) || defined(OS_IOS)
enable_static_pins_ = false;
+ enable_static_expect_ct_ = false;
#endif
DCHECK(CalledOnValidThread());
}
@@ -782,6 +773,53 @@ void TransportSecurityState::EnablePKPHost(const std::string& host,
DirtyNotify();
}
+bool TransportSecurityState::CheckPinsAndMaybeSendReport(
+ const HostPortPair& host_port_pair,
+ const TransportSecurityState::PKPState& pkp_state,
+ const HashValueVector& hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const TransportSecurityState::PublicKeyPinReportStatus report_status,
+ std::string* failure_log) {
+ if (pkp_state.CheckPublicKeyPins(hashes, failure_log))
+ return true;
+
+ if (!report_sender_ ||
+ report_status != TransportSecurityState::ENABLE_PIN_REPORTS ||
+ pkp_state.report_uri.is_empty()) {
+ return false;
+ }
+
+ DCHECK(pkp_state.report_uri.is_valid());
+ // Report URIs should not be used if they are the same host as the pin
+ // and are HTTPS, to avoid going into a report-sending loop.
+ if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host()))
+ return false;
+
+ std::string serialized_report;
+ std::string report_cache_key;
+ if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain,
+ validated_certificate_chain, &serialized_report,
+ &report_cache_key)) {
+ return false;
+ }
+
+ // Limit the rate at which duplicate reports are sent to the same
+ // report URI. The same report will not be sent within
+ // |kTimeToRememberHPKPReportsMins|, which reduces load on servers and
+ // also prevents accidental loops (a.com triggers a report to b.com
+ // which triggers a report to a.com). See section 2.1.4 of RFC 7469.
+ if (sent_reports_cache_.Get(report_cache_key, base::TimeTicks::Now()))
+ return false;
+ sent_reports_cache_.Put(
+ report_cache_key, true, base::TimeTicks::Now(),
+ base::TimeTicks::Now() +
+ base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins));
+
+ report_sender_->Send(pkp_state.report_uri, serialized_report);
+ return false;
+}
+
bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
DCHECK(CalledOnValidThread());
@@ -951,18 +989,11 @@ bool TransportSecurityState::ProcessHPKPReportOnlyHeader(
CheckPinsAndMaybeSendReport(
host_port_pair, pkp_state, ssl_info.public_key_hashes,
ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS,
- report_sender_, &unused_failure_log);
+ &unused_failure_log);
return true;
}
// static
-bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) {
- PreloadResult result;
- return DecodeHSTSPreload(host, &result) && result.has_pins &&
- kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts;
-}
-
-// static
void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
PreloadResult result;
if (!DecodeHSTSPreload(host, &result) ||
@@ -1011,7 +1042,7 @@ bool TransportSecurityState::CheckPublicKeyPinsImpl(
return CheckPinsAndMaybeSendReport(
host_port_pair, pkp_state, hashes, served_certificate_chain,
- validated_certificate_chain, report_status, report_sender_, failure_log);
+ validated_certificate_chain, report_status, failure_log);
}
bool TransportSecurityState::GetStaticDomainState(const std::string& host,
@@ -1051,17 +1082,17 @@ bool TransportSecurityState::GetStaticDomainState(const std::string& host,
pkp_state->report_uri = GURL(pinset->report_uri);
if (pinset->accepted_pins) {
- const char* const* sha1_hash = pinset->accepted_pins;
- while (*sha1_hash) {
- AddHash(*sha1_hash, &pkp_state->spki_hashes);
- sha1_hash++;
+ const char* const* sha256_hash = pinset->accepted_pins;
+ while (*sha256_hash) {
+ AddHash(*sha256_hash, &pkp_state->spki_hashes);
+ sha256_hash++;
}
}
if (pinset->rejected_pins) {
- const char* const* sha1_hash = pinset->rejected_pins;
- while (*sha1_hash) {
- AddHash(*sha1_hash, &pkp_state->bad_spki_hashes);
- sha1_hash++;
+ const char* const* sha256_hash = pinset->rejected_pins;
+ while (*sha256_hash) {
+ AddHash(*sha256_hash, &pkp_state->bad_spki_hashes);
+ sha256_hash++;
}
}
}
@@ -1069,6 +1100,46 @@ bool TransportSecurityState::GetStaticDomainState(const std::string& host,
return true;
}
+bool TransportSecurityState::IsGooglePinnedHost(const std::string& host) const {
+ DCHECK(CalledOnValidThread());
+
+ if (!IsBuildTimely())
+ return false;
+
+ PreloadResult result;
+ if (!DecodeHSTSPreload(host, &result))
+ return false;
+
+ if (!result.has_pins)
+ return false;
+
+ if (result.pinset_id >= arraysize(kPinsets))
+ return false;
+
+ return kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts;
+}
+
+bool TransportSecurityState::GetStaticExpectCTState(
+ const std::string& host,
+ ExpectCTState* expect_ct_state) const {
+ DCHECK(CalledOnValidThread());
+
+ if (!IsBuildTimely())
+ return false;
+
+ PreloadResult result;
+ if (!DecodeHSTSPreload(host, &result))
+ return false;
+
+ if (!enable_static_expect_ct_ || !result.expect_ct)
+ return false;
+
+ expect_ct_state->domain = host.substr(result.hostname_offset);
+ expect_ct_state->report_uri =
+ GURL(kExpectCTReportURIs[result.expect_ct_report_uri_id]);
+ return true;
+}
+
bool TransportSecurityState::GetDynamicSTSState(const std::string& host,
STSState* result) {
DCHECK(CalledOnValidThread());
@@ -1197,6 +1268,10 @@ TransportSecurityState::PKPState::PKPState() : include_subdomains(false) {
TransportSecurityState::PKPState::~PKPState() {
}
+TransportSecurityState::ExpectCTState::ExpectCTState() {}
+
+TransportSecurityState::ExpectCTState::~ExpectCTState() {}
+
bool TransportSecurityState::PKPState::CheckPublicKeyPins(
const HashValueVector& hashes,
std::string* failure_log) const {
diff --git a/chromium/net/http/transport_security_state.h b/chromium/net/http/transport_security_state.h
index d7befb7cfef..a4c52e7ecfe 100644
--- a/chromium/net/http/transport_security_state.h
+++ b/chromium/net/http/transport_security_state.h
@@ -13,8 +13,10 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
+#include "net/base/expiring_cache.h"
#include "net/base/net_export.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
@@ -180,6 +182,20 @@ class NET_EXPORT TransportSecurityState
std::map<std::string, PKPState>::const_iterator end_;
};
+ // An ExpectCTState describes a site that expects valid Certificate
+ // Transparency information to be supplied on every connection to it.
+ class NET_EXPORT ExpectCTState {
+ public:
+ ExpectCTState();
+ ~ExpectCTState();
+
+ // The domain which matched during a search for this DomainState entry.
+ std::string domain;
+ // The URI to which reports should be sent if valid CT info is not
+ // provided.
+ GURL report_uri;
+ };
+
// An interface for asynchronously sending HPKP violation reports.
class NET_EXPORT ReportSender {
public:
@@ -266,6 +282,17 @@ class NET_EXPORT TransportSecurityState
STSState* sts_result,
PKPState* pkp_result) const;
+ // Returns true iff there is static (built-in) state for |host| that
+ // references the Google pins.
+ // TODO(rch): Remove this temporary gross layering violation once QUIC 32 is
+ // deployed.
+ bool IsGooglePinnedHost(const std::string& host) const;
+
+ // Returns true and updates |*expect_ct_result| iff there is a static
+ // (built-in) state for |host| with expect_ct=true.
+ bool GetStaticExpectCTState(const std::string& host,
+ ExpectCTState* expect_ct_result) const;
+
// Returns true and updates |*result| iff |host| has HSTS (respectively, HPKP)
// state. If multiple HSTS (respectively, HPKP) entries match |host|, the
// most specific match determines the HSTS (respectively, HPKP) return value.
@@ -291,8 +318,10 @@ class NET_EXPORT TransportSecurityState
const base::Time& expiry,
bool include_subdomains);
- // Adds explicitly-specified data as if it was processed from an
- // HPKP header (used for net-internals and unit tests).
+ // Adds explicitly-specified data as if it was processed from an HPKP header.
+ // Note: This method will persist the HPKP if a Delegate is present. Make sure
+ // that the delegate is nullptr if the persistence is not desired.
+ // See |SetDelegate| method for more details.
void AddHPKP(const std::string& host,
const base::Time& expiry,
bool include_subdomains,
@@ -307,14 +336,6 @@ class NET_EXPORT TransportSecurityState
const HostPortPair& host_port_pair,
const SSLInfo& ssl_info);
- // Returns true iff we have any static public key pins for the |host| and
- // iff its set of required pins is the set we expect for Google
- // properties.
- //
- // If |host| matches both an exact entry and is a subdomain of another
- // entry, the exact match determines the return value.
- static bool IsGooglePinnedProperty(const std::string& host);
-
// The maximum number of seconds for which we'll cache an HSTS request.
static const long int kMaxHSTSAgeSecs;
@@ -376,6 +397,22 @@ class NET_EXPORT TransportSecurityState
void EnableSTSHost(const std::string& host, const STSState& state);
void EnablePKPHost(const std::string& host, const PKPState& state);
+ // Returns true if a request to |host_port_pair| with the given
+ // SubjectPublicKeyInfo |hashes| satisfies the pins in |pkp_state|,
+ // and false otherwise. If a violation is found and reporting is
+ // configured (i.e. there is a report URI in |pkp_state| and
+ // |report_status| says to), this method sends an HPKP violation
+ // report containing |served_certificate_chain| and
+ // |validated_certificate_chain|.
+ bool CheckPinsAndMaybeSendReport(
+ const HostPortPair& host_port_pair,
+ const TransportSecurityState::PKPState& pkp_state,
+ const HashValueVector& hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const TransportSecurityState::PublicKeyPinReportStatus report_status,
+ std::string* failure_log);
+
// The sets of hosts that have enabled TransportSecurity. |domain| will always
// be empty for a STSState or PKPState in these maps; the domain
// comes from the map keys instead. In addition, |upgrade_mode| in the
@@ -391,6 +428,14 @@ class NET_EXPORT TransportSecurityState
// True if static pins should be used.
bool enable_static_pins_;
+ // True if static expect-CT state should be used.
+ bool enable_static_expect_ct_;
+
+ // Keeps track of reports that have been sent recently for
+ // rate-limiting.
+ ExpiringCache<std::string, bool, base::TimeTicks, std::less<base::TimeTicks>>
+ sent_reports_cache_;
+
DISALLOW_COPY_AND_ASSIGN(TransportSecurityState);
};
diff --git a/chromium/net/http/transport_security_state_static.certs b/chromium/net/http/transport_security_state_static.certs
index 65f8fe0492b..75df69f5087 100644
--- a/chromium/net/http/transport_security_state_static.certs
+++ b/chromium/net/http/transport_security_state_static.certs
@@ -7,26 +7,11 @@
# details.
# Each entry consists of a line containing the name of the pin followed either
-# by a hash in the format "sha1/" + base64(hash), or a PEM encoded certificate.
+# by a hash in the format "sha256/" + base64(hash), a PEM encoded certificate,
+# or a PEM encoded public key.
TestSPKI
-sha1/AAAAAAAAAAAAAAAAAAAAAAAAAAA=
-
-VeriSignClass3
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
-MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
-BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
-BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
-I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
-CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
-2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
-2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
------END CERTIFICATE-----
+sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
VeriSignClass3_G3
-----BEGIN CERTIFICATE-----
@@ -55,10 +40,41 @@ TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
GoogleBackup2048
-sha1/vq7OyjSnqOco9nyMCDGdy77eijM=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuYB7COWpsVCLYy0iOzd
+WOvYPdisLAa8u0G3OOSy/mYb1Owk+ldOZdjpwNHex9KpRIGwQ5sSCLRutA2cC2zE
+XbrqpymxPTbDDrpn0+XVqckCKmOHURkF8zBRlg51VLuRIiASSwBudRXZXoZwt5rr
+Zco9moIQOlR0HxuM01muFYP5zXkryYWq67SsJxQVeRi6omLjR9X+TXNw1+CCeXdG
+Yd+CmLVLE/2ngCaVkgepDmKGM0aTRL3zqRKQo+9t/x4OzBkZTcCg0JPvT56IzJIf
+b9h1TpRizUsdRJPcMOGrOA/orUZMGRvwGkwwf4SZT3NMHIAj8BjaoY7frV3gdItk
+bQIDAQAB
+-----END PUBLIC KEY-----
GoogleG2
-sha1/Q9rWMO5T+KmAym79hfRqo3mQ4Oo=
+-----BEGIN CERTIFICATE-----
+MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG
+EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
+bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
+VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
+h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
+ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
+EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
+DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7
+qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD
+VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov
+L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig
+JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ
+MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+
+3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI
+hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI
+Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X
+Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm
+X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40
+fsg12A==
+-----END CERTIFICATE-----
GeoTrustGlobal
-----BEGIN CERTIFICATE-----
@@ -205,11 +221,37 @@ CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Tor1
-sha1/juNxSTv9UANmpC9kF5GKpmWNx3Y=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlOpp8zfF+jEbI6R7nxnm
+phFPqBCCHMpahBMjQOjHD/860wrH1ZoIeevW9ZJ6MIuBV0jwwtAQokNsx8FVAmMH
+Tjg6b4blbum1meahODgafcGjHrRGzEvuN6r577SgHcOQXkAIVsbZ6Bjk+8kh1t/v
+cEaLa9DmzBQpMTYWCDY4kN0tFMSNS8CJekgA6vDVFHFRp4NiJ1eFmd38furKsZUZ
+rqvY4jzyaIls/UQB8q/6bHbEeF5lTUaWPZob1XBv0Ib7nVX2gGzan+qYQim8Wdjc
+LrGhnUBwil5lh9qQ/8VIMVbjtcAjeZpVWuTZA3stbOiaDCqJBGTe9glFOH1xz9hS
+7QIDAQAB
+-----END PUBLIC KEY-----
+
Tor2
-sha1/lia43lPolzSPVIq34Dw57uYcLD8=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1b2qGT7y4sjNG18lZKuC
+tLwDfE57KseaNY6VM61DySaobdDt9VOiFS+3QaPcrT60qOH9aQ1DGhNv3jcAJvtT
+i5nKSgVDu7Emb70j2xrRaJ+lnITYs2Je9JYUQmb6IQAplYTz60s0Ng1MrROqNswl
+UhhXTCZLB1Bo+uN8OM7LoZ+Sr+sP0YhMsNAyxf3ZJVvzhWHQYGHvNBqIrXpq6YLc
+zHSdd5QirZ3lSdhv2uGYxDBLslfk47xObxSvqblLD2ISlMRPL85FnetHL/dRMUEo
+2c9MJ49nxItUbeizxxIeCbfWdbucd4il5bBlN9t3duFqwCu80ZOuHMvxavpP05D5
+RwIDAQAB
+-----END PUBLIC KEY-----
+
Tor3
-sha1/rzEyQIKOh77j87n5bjWUNguXF8Y=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtNfM24/03NeOb3R1sRN5
+7zwYThdBJPSOXehVN3JvShTZ86kg+f0HYwbZZ0Xx0jujghabKgHkhiLMChl+Fg97
+Pi0t4mQm/3sdltfUypprdcE6CbCzKkWNTaD9+iMA4m8peSq0Pd5hCKvRidb1+OCL
+rJKOqx24r9VwsIa69zdiE5DpFBqvi1YczoaknF09jNR/hjqMyEwENR7t/AKZ1VpK
+6L6loJt2mCl3FWjM+Wt50ktrSyAI4aPfSAILAmSRhb5TY1xWRBuHDOzdf+DvegXu
+/aHn0j5UscN2XqQiNJcUrdJYsekfpHDtYKP/pesHCp2lCSbYdAaS8mnqDJwV8xC4
+1wIDAQAB
+-----END PUBLIC KEY-----
VeriSignClass1
-----BEGIN CERTIFICATE-----
@@ -432,7 +474,15 @@ lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
-----END CERTIFICATE-----
Twitter1
-sha1/Vv7zwhR9TtOIN/29MFI4cgHld40=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApNG3ovIHXvy3YJ64Eq2O
+6J0gV0i1nbnWrPdNFHoR1y6rAKJzhCTq0XY69W+1GjHw5scQ/zhVxsYJku2BB+9i
+jvzk5Yl5j0EYqWyCmNGqTXwX7b4A9+pLFs95RjooxwVkhRA57tcEuWEXX1dJlca+
+qOmrs+jisCmu9Kvs4cichyuAoYwc3/pgevGErrXg7lMmJKASa5WGPV8/prS2KQmH
+wZMIAAWXUTmVRQRFshAET1rzBbcDfjf4lX5UVPzSYzUDbL4yNyHPIOWrewVfP7Mg
+WB6VB5x8aEgyePZF0dbNZN/mFJuXZU+NNzogP2z0dfmWoh1I2H5389yPBEU+9o4M
+nQIDAQAB
+-----END PUBLIC KEY-----
GeoTrustGlobal2
-----BEGIN CERTIFICATE-----
@@ -1366,10 +1416,109 @@ Ea8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc=
-----END CERTIFICATE-----
FacebookBackup
-sha1/1ww8E0AYsR2oX5lndk2hwp2Uosk=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtHIqUt4FvcdEZQZqucdY
+UEWSMuSIZnRgs0vvyLqb0KmIz8n8WLwifrMzTnrk9ol8EMcuoe4kkntJ3kn4pRIm
+2Sdw33nibWBzXJu3zuorFGFZ9fsZLfh1zHIrNAKbjQmjHnD+XJLfPyoRI/3eOcl4
+ArQwdqg5ymAmffy8Zapgrf3tSa6OsOxZF7+dLVfr+zzh2tawfH+kzzS3e0eXyO1x
+aSSpcSsFjuB1/cBJDeS/0a1/eLK8KeCWZcb7ev7ge0WnRvkfo+0KxdzSFxTrfjg0
+uy8blcsjtFoq5lG5Ba1982Qzkmot+08ZZQi/QxZ+QARS16YL3KQgJRCb7y+UXmGa
+PQIDAQAB
+-----END PUBLIC KEY-----
SpiderOak2
-sha1/D0fS/hquA6QprluciyO1hlFUAxg=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ACdmloAbzQugdO44I7l
+N5QHEeZIPpYE8W6T0u2bdcQLNKKbl6SzF7p1KcxGnUGYYSKoMTX+6FqQFxngUZlO
+KZL5NuDeHrtx5tACMFqJeMQcfyPufaerV7M7Qr6aMeNCaORVzt5VXHrl+quhSy7I
+kcxo7RSEnpX7v6+MEaRPlTF5ravRd88b/FH9DBwSGjGky3cap4DC0IxSN+QbEjLj
+BcoOPQa79q1UkgmD/5BkhxfMBGczT7VudfArKKyZNEeYmP6itrGy2BdIBSkw+XPL
+Hs5+68eGpG74cdV3HjvhDPTD/OP+hgGHRQOmcOd0Y1vayW9i3+B7qiUvCngzfiIt
+ZQIDAQAB
+-----END PUBLIC KEY-----
SpiderOak3
-sha1/l5JoIXv4lztZ+C6TJWgxZCHQzS4=
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3uV1DNSAfxGyfqhF2XkD
+F/ADpxyl11guzjBlsVyaAXByxV72rPR2a09XlLiobFrp/9jF9om9lEtujBsaVDjg
+ga8EqVxGV++RxJalAnk3KsKrGQAS6IiOMvkZ2jm0F7+77+oSW8+FQB4NjdMH2lfg
+ysqpS9SqP8zQoypnUZalR89ZGf6pjCbKM1ZQWGjBC03B5JRdEoPjULzzBB/e2igM
+Vchpq1U6WS8/WGgtiDNXS43Bx0Nka41KLIk4Pv8VSy7Jfxu6i33+SuA7cDP1oTK9
+aFE/tQpQ/YVB8aQ9+2vGoBDv9bFF+bxMmQyFtST3SUvKLhgeRqLraEd8OPfEizYl
+PwIDAQAB
+-----END PUBLIC KEY-----
+
+YahooBackup1
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1vZXDjNejqvtVvyYcP0
+7ubiG0RW1sar002td1qI7Zo9Lz8kZtrAUJrBXGh6bbpovsIwWkUjirUQk2b3M7Ob
+bgQWVGGeQlrVUUjTMth4Cg5p2Xj8b5Z5Nt7H4G9yS1boxQyh23yxpS6vB4E8LNhY
+xUBdL20j24UeRjMC+KcgKLdz0cnXpu/icfLNs9NRuYGFQZzdM7hlCKJKFLZfpNOw
+xW38ArbbJfvCZ7KhenRphlnCTCxUglp3hgGMc9pBb2xKhIh1bABn12/DB/ZuOP4d
+hYeg5UhYKhS7Z5q3Yg+mBLgQQrdat82yTU677iY38IXNzud9kvxRYb5mZrc5va6N
+SQIDAQAB
+-----END PUBLIC KEY-----
+
+YahooBackup2
+-----BEGIN PUBLIC KEY-----
+MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEY26fFxATbUDuPe7tEeZx7uGLIycMrm20
+/opCiPXC5oAcyOu0pLmiGWBKD8CRK+Po/pYsyIsHotll0aZ6V3BbQg==
+-----END PUBLIC KEY-----
+
+LetsEncryptAuthorityX1
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa
+MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
+ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB
+BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg
+PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG
+dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1
+gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4
+4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud
+EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy
+BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j
+b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv
+ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ
+MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH
+AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw
+MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM
+LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3
+pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd
+v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd
+ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW
+ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk
+6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj
+f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk=
+-----END CERTIFICATE-----
+
+LetsEncryptAuthorityX2
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIRAMODTJjAvWslLKN5tm+lKw4wDQYJKoZIhvcNAQELBQAw
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjM1MDFaFw0yMDEwMTkyMjM1MDFa
+MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
+ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMjCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAOEkdEJ7t5Ex2XP/OKrYzkRctzkK3ESuDb1FuZc3Z6+9UE9f
+0xBUa/dB2o5j5m1bwOhAqYxB/NEDif9iYQlg1gcFeJqQvRpkPk/cz3cviWvLZ69B
+TcWNAMBr/o2E3LXylTGo6PaQoENKk3Rcsz5DaUuJIkd0UT6ZZMPNJAH5hC8odxci
+p93DbAhMZi83dMVvk46wRjcWYdFQmMiwD09YU3ys9totlmFQrUPcCqZPnrVSuZyO
+707fRrMx3CD8acKjIHU+7DgbNk5mZtLf9Wakky97pg6UPmA9Skscb7q0TRw8kVhu
+L03E2nDb7QE5dsBJ5+k1tRQGkMHlkuIQ/Wu5tIUCAwEAAaOCAZIwggGOMBIGA1Ud
+EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy
+BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j
+b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv
+ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ
+MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH
+AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw
+MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM
+LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUxbGrTkyxzWQwk37B
+hJkFq+YD4iUwDQYJKoZIhvcNAQELBQADggEBAAcSAhaE7rvHxyUnhgkEpMR56o2I
+IH+mlw5kknjhAuvaBIAM59MZkFbFg5CrNWt8K+G3UoxJgFwv7HvJJxqwgPpNgXC/
+uT3prkvwt+2lvzKJKbqdH+lo40P8EuSyyJOz2hjrRzNMHbJHYDS9OhF5WC5LOQQa
+ydgLZ/JHxXgJypEZqcmVgQ+yYBs0XPwXjE7OE8vbx5REwu7gToMIqAoWRoWW2MxS
+g28RGPVnHzHk2XV1nZGy9T+NYQ91vWWJr1pzNEFZ0cnA2xGwTeJ+zZ3URCfw3Z1U
++YAL3YUmrvdoRBlASOTmNJmXSo9qvMYPa3DEomAPoFQFZqsSN6kuqDEIqMA=
+-----END CERTIFICATE-----
diff --git a/chromium/net/http/transport_security_state_static.h b/chromium/net/http/transport_security_state_static.h
index 6fbfee87a75..22c734393ef 100644
--- a/chromium/net/http/transport_security_state_static.h
+++ b/chromium/net/http/transport_security_state_static.h
@@ -8,6 +8,8 @@
#ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_STATIC_H_
#define NET_HTTP_TRANSPORT_SECURITY_STATE_STATIC_H_
+#include <stdint.h>
+
enum SecondLevelDomainName {
DOMAIN_NOT_PINNED,
DOMAIN_GOOGLE_COM,
@@ -275,265 +277,286 @@ enum SecondLevelDomainName {
DOMAIN_DROPBOXUSERCONTENT_COM,
DOMAIN_WITHYOUTUBE_COM,
DOMAIN_WITHGOOGLE_COM,
+ DOMAIN_G4W_CO,
+ DOMAIN_BADSSL_COM,
+ DOMAIN_YAHOO_COM,
+ DOMAIN_GOOGLEVIDEO_COM,
+ DOMAIN_GOOGLEWEBLIGHT_COM,
+ DOMAIN_GOOGLEADSSERVING_CN,
// Boundary value for UMA_HISTOGRAM_ENUMERATION.
DOMAIN_NUM_EVENTS,
};
// These are SubjectPublicKeyInfo hashes for public key pinning. The
-// hashes are SHA1 digests.
+// hashes are SHA256 digests.
static const char kSPKIHash_TestSPKI[] =
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-
-static const char kSPKIHash_VeriSignClass3[] =
- "\xe2\x7f\x7b\xd8\x77\xd5\xdf\x9e\x0a\x3f"
- "\x9e\xb4\xcb\x0e\x2e\xa9\xef\xdb\x69\x77";
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
static const char kSPKIHash_VeriSignClass3_G3[] =
- "\x22\xf1\x9e\x2e\xc6\xea\xcc\xfc\x5d\x23"
- "\x46\xf4\xc2\xe8\xf6\xc5\x54\xdd\x5e\x07";
+ "\x49\x5a\x96\xba\x6b\xad\x78\x24\x07\xbd\x52\x1a\x00\xba\xce\x65"
+ "\x7b\xb3\x55\x55\x5e\x4b\xb7\xf8\x14\x6c\x71\xbb\xa5\x7e\x7a\xce";
static const char kSPKIHash_GoogleBackup2048[] =
- "\xbe\xae\xce\xca\x34\xa7\xa8\xe7\x28\xf6"
- "\x7c\x8c\x08\x31\x9d\xcb\xbe\xde\x8a\x33";
+ "\x20\xf3\x1b\x0c\x08\xcb\x55\x21\xa7\xb4\x63\xb7\x58\xfe\x77\x5f"
+ "\xfc\xe2\x94\x25\x67\x75\xec\xf9\x60\x9d\xbe\xbc\x9b\xe1\x26\xc0";
static const char kSPKIHash_GoogleG2[] =
- "\x43\xda\xd6\x30\xee\x53\xf8\xa9\x80\xca"
- "\x6e\xfd\x85\xf4\x6a\xa3\x79\x90\xe0\xea";
+ "\xec\x72\x29\x69\xcb\x64\x20\x0a\xb6\x63\x8f\x68\xac\x53\x8e\x40"
+ "\xab\xab\x5b\x19\xa6\x48\x56\x61\x04\x2a\x10\x61\xc4\x61\x27\x76";
static const char kSPKIHash_GeoTrustGlobal[] =
- "\xc0\x7a\x98\x68\x8d\x89\xfb\xab\x05\x64"
- "\x0c\x11\x7d\xaa\x7d\x65\xb8\xca\xcc\x4e";
+ "\x87\xaf\x34\xd6\x6f\xb3\xf2\xfd\xf3\x6e\x09\x11\x1e\x9a\xba\x2f"
+ "\x6f\x44\xb2\x07\xf3\x86\x3f\x3d\x0b\x54\xb2\x50\x23\x90\x9a\xa5";
static const char kSPKIHash_GeoTrustPrimary[] =
- "\xb0\x19\x89\xe7\xef\xfb\x4a\xaf\xcb\x14"
- "\x8f\x58\x46\x39\x76\x22\x41\x50\xe1\xba";
+ "\x49\x05\x46\x66\x23\xab\x41\x78\xbe\x92\xac\x5c\xbd\x65\x84\xf7"
+ "\xa1\xe1\x7f\x27\x65\x2d\x5a\x85\xaf\x89\x50\x4e\xa2\x39\xaa\xaa";
static const char kSPKIHash_RapidSSL[] =
- "\xa3\x93\x99\xc4\x04\xc3\xb2\x09\xb0\x81"
- "\xc2\x1f\x21\x62\x27\x78\xc2\x74\x8e\x4c";
+ "\x95\x3d\x3d\x80\xf5\x1e\x41\xf6\xd8\xae\x5c\x51\xb6\x9b\x07\xae"
+ "\x30\xdb\x96\x3f\x51\xa7\x3f\xae\xed\xa8\xdf\x0a\xb8\x38\xa8\x33";
static const char kSPKIHash_DigiCertEVRoot[] =
- "\x83\x31\x7e\x62\x85\x42\x53\xd6\xd7\x78"
- "\x31\x90\xec\x91\x90\x56\xe9\x91\xb9\xe3";
+ "\x5a\x88\x96\x47\x22\x0e\x54\xd6\xbd\x8a\x16\x81\x72\x24\x52\x0b"
+ "\xb5\xc7\x8e\x58\x98\x4b\xd5\x70\x50\x63\x88\xb9\xde\x0f\x07\x5f";
static const char kSPKIHash_DigiCertAssuredIDRoot[] =
- "\x68\x33\x0e\x61\x35\x85\x21\x59\x29\x83"
- "\xa3\xc8\xd2\xd2\xe1\x40\x6e\x7a\xb3\xc1";
+ "\x23\xf2\xed\xff\x3e\xde\x90\x25\x9a\x9e\x30\xf4\x0a\xf8\xf9\x12"
+ "\xa5\xe5\xb3\x69\x4e\x69\x38\x44\x03\x41\xf6\x06\x0e\x01\x4f\xfa";
static const char kSPKIHash_DigiCertGlobalRoot[] =
- "\xd5\x2e\x13\xc1\xab\xe3\x49\xda\xe8\xb4"
- "\x95\x94\xef\x7c\x38\x43\x60\x64\x66\xbd";
+ "\xaf\xf9\x88\x90\x6d\xde\x12\x95\x5d\x9b\xeb\xbf\x92\x8f\xdc\xc3"
+ "\x1c\xce\x32\x8d\x5b\x93\x84\xf2\x1c\x89\x41\xca\x26\xe2\x03\x91";
static const char kSPKIHash_Tor1[] =
- "\x8e\xe3\x71\x49\x3b\xfd\x50\x03\x66\xa4"
- "\x2f\x64\x17\x91\x8a\xa6\x65\x8d\xc7\x76";
+ "\x6d\x8c\xfd\x25\x30\xe4\xf3\xd5\xf7\xaa\xed\xdf\x82\xcc\x06\xfa"
+ "\x50\x50\xb2\x8e\x6f\x23\x43\x75\x7f\x44\x71\xe2\x0a\x38\x9c\xba";
static const char kSPKIHash_Tor2[] =
- "\x96\x26\xb8\xde\x53\xe8\x97\x34\x8f\x54"
- "\x8a\xb7\xe0\x3c\x39\xee\xe6\x1c\x2c\x3f";
+ "\xc5\x70\xb1\x85\x37\x67\xee\xec\x57\x9d\xe2\x52\x6d\x00\xaa\xa0"
+ "\x0b\xee\x5b\x76\x6d\x42\x5d\xa9\x0d\x54\xdf\xda\xc7\xb0\x4b\xcc";
static const char kSPKIHash_Tor3[] =
- "\xaf\x31\x32\x40\x82\x8e\x87\xbe\xe3\xf3"
- "\xb9\xf9\x6e\x35\x94\x36\x0b\x97\x17\xc6";
+ "\x0a\x57\x82\xd6\xac\x14\x47\xc2\x4f\x80\x7d\x67\x5e\xf4\x9e\xd9"
+ "\x51\xf1\x0d\xee\x7f\x29\xf3\x6c\xf7\xa1\x2e\xb1\xb7\xd2\x39\xfa";
static const char kSPKIHash_VeriSignClass1[] =
- "\x23\x43\xd1\x48\xa2\x55\x89\x9b\x94\x7d"
- "\x46\x1a\x79\x7e\xc0\x4c\xfe\xd1\x70\xb7";
+ "\x2d\xc9\x47\x0b\xe6\x3e\xf4\xac\xf1\xbd\x82\x86\x09\x40\x2b\xb7"
+ "\xb8\x7b\xd9\x96\x38\xa6\x43\x93\x4e\x88\x68\x2d\x1b\xe8\xc3\x08";
static const char kSPKIHash_VeriSignClass3_G4[] =
- "\xed\x66\x31\x35\xd3\x1b\xd4\xec\xa6\x14"
- "\xc4\x29\xe3\x19\x06\x9f\x94\xc1\x26\x50";
+ "\x51\x92\x43\x8e\xc3\x69\xd7\xee\x0c\xe7\x1f\x5c\x6d\xb7\x5f\x94"
+ "\x1e\xfb\xf7\x2e\x58\x44\x17\x15\xe9\x9e\xab\x04\xc2\xc8\xac\xee";
static const char kSPKIHash_VeriSignClass4_G3[] =
- "\x3c\x03\x43\x68\x68\x95\x1c\xf3\x69\x2a"
- "\xb8\xb4\x26\xda\xba\x8f\xe9\x22\xe5\xbd";
+ "\x56\x7b\x82\x11\xfd\x20\xd3\xd2\x83\xee\x0c\xd7\xce\x06\x72\xcb"
+ "\x9d\x99\xbc\x5b\x48\x7a\x58\xc9\xd5\x4e\xc6\x7f\x77\xd4\xa8\xf5";
static const char kSPKIHash_VeriSignClass1_G3[] =
- "\x55\x19\xb2\x78\xac\xb2\x81\xd7\xed\xa7"
- "\xab\xc1\x83\x99\xc3\xbb\x69\x04\x24\xb5";
+ "\x22\x07\x6e\x5a\xef\x44\xbb\x9a\x41\x6a\x28\xb7\xd1\xc4\x43\x22"
+ "\xd7\x05\x9f\x60\xfe\xff\xa5\xca\xf6\xc5\xbe\x84\x47\x89\x13\x03";
static const char kSPKIHash_VeriSignClass2_G3[] =
- "\x5a\xbe\xc5\x75\xdc\xae\xf3\xb0\x8e\x27"
- "\x19\x43\xfc\x7f\x25\x0c\x3d\xf6\x61\xe3";
+ "\x70\x06\xa3\x83\x11\xe5\x8f\xb1\x93\x48\x42\x33\x21\x82\x10\xc6"
+ "\x61\x25\xa0\xe4\xa8\x26\xae\xd5\x39\xac\x56\x1d\xfb\xfb\xd9\x03";
static const char kSPKIHash_VeriSignClass3_G2[] =
- "\x1a\x21\xb4\x95\x2b\x62\x93\xce\x18\xb3"
- "\x65\xec\x9c\x0e\x93\x4c\xb3\x81\xe6\xd4";
+ "\x02\x3c\x81\xcc\xe8\xe7\xc6\x4f\xa9\x42\xd3\xc1\x50\x48\x70\x7d"
+ "\x35\xd9\xbb\x5b\x87\xf4\xf5\x44\xc5\xbf\x1b\xc5\x64\x3a\xf2\xfa";
static const char kSPKIHash_VeriSignClass2_G2[] =
- "\x12\x37\xba\x45\x17\xee\xad\x29\x26\xfd"
- "\xc1\xcd\xfe\xbe\xed\xf2\xde\xd9\x14\x5c";
+ "\xda\x80\x0b\x80\xb2\xa8\x7d\x39\x9e\x66\xfa\x19\xd7\x2f\xdf\x49"
+ "\x98\x3b\x47\xd8\xcf\x32\x2c\x7c\x79\x50\x3a\x0c\x7e\x28\xfe\xaf";
static const char kSPKIHash_VeriSignClass3_G5[] =
- "\xb1\x81\x08\x1a\x19\xa4\xc0\x94\x1f\xfa"
- "\xe8\x95\x28\xc1\x24\xc9\x9b\x34\xac\xc7";
+ "\x25\xb4\x1b\x50\x6e\x49\x30\x95\x28\x23\xa6\xeb\x9f\x1d\x31\xde"
+ "\xf6\x45\xea\x38\xa5\xc6\xc6\xa9\x6d\x71\x95\x7e\x38\x4d\xf0\x58";
static const char kSPKIHash_VeriSignUniversal[] =
- "\xbb\xc2\x3e\x29\x0b\xb3\x28\x77\x1d\xad"
- "\x3e\xa2\x4d\xbd\xf4\x23\xbd\x06\xb0\x3d";
+ "\x96\x7b\x0c\xd9\x3f\xce\xf7\xf2\x7c\xe2\xc2\x45\x76\x7a\xe9\xb0"
+ "\x5a\x77\x6b\x06\x49\xf9\x96\x5b\x62\x90\x96\x84\x69\x68\x68\x72";
static const char kSPKIHash_Twitter1[] =
- "\x56\xfe\xf3\xc2\x14\x7d\x4e\xd3\x88\x37"
- "\xfd\xbd\x30\x52\x38\x72\x01\xe5\x77\x8d";
+ "\xbd\x4f\x4c\xe3\xc2\xf3\x0f\xf0\x85\xdf\x8c\x04\xe4\xf3\xdf\xe2"
+ "\x70\x70\x47\x2a\x2c\xcb\x4e\x97\xdb\x52\x74\x6a\x9f\x32\x4b\x9b";
static const char kSPKIHash_GeoTrustGlobal2[] =
- "\x71\x38\x36\xf2\x02\x31\x53\x47\x2b\x6e"
- "\xba\x65\x46\xa9\x10\x15\x58\x20\x05\x09";
+ "\x17\x75\x5a\x5c\x29\x5f\x3d\x2d\x72\xe6\xf0\x31\xa1\xf0\x7f\x40"
+ "\x0c\x58\x8b\x9e\x58\x2b\x22\xf1\x7e\xae\x31\xa1\x59\x0d\x11\x85";
static const char kSPKIHash_GeoTrustUniversal[] =
- "\x87\xe8\x5b\x63\x53\xc6\x23\xa3\x12\x8c"
- "\xb0\xff\xbb\xf5\x51\xfe\x59\x80\x0e\x22";
+ "\x96\x99\x22\x5c\x5d\xe5\x2e\x56\xcd\xd3\x2d\xf2\xe9\x6d\x1c\xfe"
+ "\xa5\xaa\x3c\xa0\xbb\x52\xcd\x89\x33\xc2\x3b\x5c\x27\x44\x38\x20";
static const char kSPKIHash_GeoTrustUniversal2[] =
- "\x5e\x4f\x53\x86\x85\xdd\x4f\x9e\xca\x5f"
- "\xdc\x0d\x45\x6f\x7d\x51\xb1\xdc\x9b\x7b";
+ "\x7c\xaa\x03\x46\x51\x24\x59\x0c\x60\x1e\x56\x7e\x52\x14\x8e\x95"
+ "\x2c\x0c\xff\xe8\x90\x00\x53\x0f\xe0\xd9\x5b\x6d\x50\xea\xae\x41";
static const char kSPKIHash_GeoTrustPrimary_G2[] =
- "\xbd\xbe\xa7\x1b\xab\x71\x57\xf9\xe4\x75"
- "\xd9\x54\xd2\xb7\x27\x80\x1a\x82\x26\x82";
+ "\xbc\xfb\x44\xaa\xb9\xad\x02\x10\x15\x70\x6b\x41\x21\xea\x76\x1c"
+ "\x81\xc9\xe8\x89\x67\x59\x0f\x6f\x94\xae\x74\x4d\xc8\x8b\x78\xfb";
static const char kSPKIHash_GeoTrustPrimary_G3[] =
- "\x9c\xa9\x8d\x00\xaf\x74\x0d\xdd\x81\x80"
- "\xd2\x13\x45\xa5\x8b\x8f\x2e\x94\x38\xd6";
+ "\xab\x98\x49\x52\x76\xad\xf1\xec\xaf\xf2\x8f\x35\xc5\x30\x48\x78"
+ "\x1e\x5c\x17\x18\xda\xb9\xc8\xe6\x7a\x50\x4f\x4f\x6a\x51\x32\x8f";
static const char kSPKIHash_Entrust_2048[] =
- "\x55\xe4\x81\xd1\x11\x80\xbe\xd8\x89\xb9"
- "\x08\xa3\x31\xf9\xa1\x24\x09\x16\xb9\x70";
+ "\x1e\xa3\xc5\xe4\x3e\xd6\x6c\x2d\xa2\x98\x3a\x42\xa4\xa7\x9b\x1e"
+ "\x90\x67\x86\xce\x9f\x1b\x58\x62\x14\x19\xa0\x04\x63\xa8\x7d\x38";
static const char kSPKIHash_Entrust_EV[] =
- "\xba\x42\xb0\x81\x88\x53\x88\x1d\x86\x63"
- "\xbd\x4c\xc0\x5e\x08\xfe\xea\x6e\xbb\x77";
+ "\x6d\xbf\xae\x00\xd3\x7b\x9c\xd7\x3f\x8f\xb4\x7d\xe6\x59\x17\xaf"
+ "\x00\xe0\xdd\xdf\x42\xdb\xce\xac\x20\xc1\x7c\x02\x75\xee\x20\x95";
static const char kSPKIHash_Entrust_G2[] =
- "\xab\x30\xd3\xaf\x4b\xd8\xf1\x6b\x58\x69"
- "\xee\x45\x69\x29\xda\x84\xb8\x73\x94\x88";
+ "\x76\xee\x85\x90\x37\x4c\x71\x54\x37\xbb\xca\x6b\xba\x60\x28\xea"
+ "\xdd\xe2\xdc\x6d\xbb\xb8\xc3\xf6\x10\xe8\x51\xf1\x1d\x1a\xb7\xf5";
static const char kSPKIHash_Entrust_SSL[] =
- "\xf0\x17\x62\x13\x55\x3d\xb3\xff\x0a\x00"
- "\x6b\xfb\x50\x84\x97\xf3\xed\x62\xd0\x1a";
+ "\x9e\xcc\x51\x36\x8e\x86\xe3\x46\x0f\x66\xc2\x95\xe4\x94\x2d\xd5"
+ "\x30\x80\xf2\x7b\x1e\x41\x0a\xff\x2d\x1a\xa9\xd4\xe6\xbc\x7e\x7c";
static const char kSPKIHash_AAACertificateServices[] =
- "\xc4\x30\x28\xc5\xd3\xe3\x08\x0c\x10\x44"
- "\x8b\x2c\x77\xba\x24\x53\x97\x60\xbb\xf9";
+ "\xbd\x15\x3e\xd7\xb0\x43\x4f\x68\x86\xb1\x7b\xce\x8b\xbe\x84\xed"
+ "\x34\x0c\x71\x32\xd7\x02\xa8\xf4\xfa\x31\x8f\x75\x6e\xcb\xd6\xf3";
static const char kSPKIHash_AddTrustClass1CARoot[] =
- "\x8b\xdb\xd7\xcc\xa0\x68\x53\x42\x16\xf4"
- "\xc1\x2b\x25\x44\xfc\x02\x9c\xa5\x8b\x47";
+ "\x05\x2b\x68\x71\x07\xec\x84\xe8\x73\x03\x82\x45\x2e\xc2\xa2\x74"
+ "\x51\x74\x5d\x74\x85\xa5\x7d\x6f\x46\x4e\x0d\xa7\xa1\xb6\xaf\x2a";
static const char kSPKIHash_AddTrustExternalCARoot[] =
- "\x4f\x9c\x7d\x21\x79\x9c\xad\x0e\xd8\xb9"
- "\x0c\x57\x9f\x1a\x02\x99\xe7\x90\xf3\x87";
+ "\x94\x2a\x69\x16\xa6\xe4\xae\x52\x77\x11\xc5\x45\x02\x47\xa2\xa7"
+ "\x4f\xb8\xe1\x56\xa8\x25\x4c\xa6\x6e\x73\x9a\x11\x49\x3b\xb4\x45";
static const char kSPKIHash_AddTrustPublicCARoot[] =
- "\xa8\x57\x65\xd6\xe8\x32\xc8\xc5\x19\x63"
- "\x73\x5a\x9a\x17\x74\x3a\x81\xdf\xee\x2e";
+ "\x38\x61\xd7\xb6\x96\x1f\xcd\xb2\x12\x04\x56\xff\x6f\xc2\xeb\x77"
+ "\x04\xb1\xa7\x41\xb4\xbd\x93\x3a\x83\x76\xf5\xe1\x91\x5c\xa6\x98";
static const char kSPKIHash_AddTrustQualifiedCARoot[] =
- "\xbc\xe4\xb7\x23\x12\x55\x98\xe5\x63\x41"
- "\x19\x1c\x50\xe4\xb6\x47\xc2\x76\x05\xd7";
+ "\xc7\x3a\xfc\x2e\xba\x77\x0d\x0c\xbc\x1e\xe4\x1f\x25\x2b\x52\xe8"
+ "\xa9\x3d\x12\xb7\x2d\xcc\xec\x03\x1d\x8d\x83\x9c\xbf\x81\x8a\x79";
static const char kSPKIHash_COMODOCertificationAuthority[] =
- "\x11\xe4\x91\xd1\xc9\xe4\xc0\xeb\x9a\xce"
- "\xcf\x73\x54\x5d\xe1\xf1\xa8\x30\x3e\xc3";
+ "\x00\x6d\x7b\xe7\x55\x5d\xd8\x20\x26\x44\x2c\x4f\x1a\x27\xa8\x0e"
+ "\x89\xa1\x98\x9c\xb8\x7b\x34\x44\x8e\xd2\x19\x4c\x18\x19\x6d\x5e";
static const char kSPKIHash_SecureCertificateServices[] =
- "\x3c\xb4\x1a\x84\x2e\xf5\x5c\xf2\x1a\x3d"
- "\xa5\x4a\xc8\xd1\xbe\x39\x08\x76\x37\xbc";
+ "\x46\x91\xcb\xfd\xe8\x4a\x6b\x60\x52\xdd\xbe\x15\x2b\xb0\xc2\x16"
+ "\xae\x25\xa8\x6e\x57\x47\x81\x3d\xbc\x0f\x14\x7f\x33\x85\x70\xbe";
static const char kSPKIHash_TrustedCertificateServices[] =
- "\xfe\x72\xc8\xeb\xbf\x0c\x2f\xbb\x0e\x26"
- "\x13\x93\x93\x3c\x2c\xa9\x8d\xdc\x24\x94";
+ "\xe2\xd8\x91\xef\xb7\x38\x66\x91\x05\xd5\x30\xde\x5e\xd7\x2e\x2b"
+ "\x2a\xc3\xf4\xa6\x70\x78\xb5\x34\x9b\x3f\xda\xca\x49\x6f\x5e\xb8";
static const char kSPKIHash_UTNDATACorpSGC[] =
- "\x53\x32\xd1\xb3\xcf\x7f\xfa\xe0\xf1\xa0"
- "\x5d\x85\x4e\x92\xd2\x9e\x45\x1d\xb4\x4f";
+ "\x40\x02\xfc\xd3\x11\xd0\x73\x31\x56\x7e\x71\xbc\xd9\x71\xe4\x60"
+ "\x48\xc8\xdc\xe8\xd1\x65\x97\x11\x75\x3b\x3d\xaa\x2a\x26\x9a\xfa";
static const char kSPKIHash_UTNUSERFirstClientAuthenticationandEmail[] =
- "\x89\x82\x67\x7d\xc4\x9d\x26\x70\x00\x4b"
- "\xb4\x50\x48\x7c\xde\x3d\xae\x04\x6e\x7d";
+ "\x2d\xa8\xf9\xea\x34\x54\xd2\x11\x46\x46\x4a\x3f\x9d\x02\x8d\xc4"
+ "\xc7\xfb\xb5\x7b\x1c\x52\xc7\x3c\x2b\x05\x72\xa2\xf5\x99\xa2\xd3";
static const char kSPKIHash_UTNUSERFirstHardware[] =
- "\xa1\x72\x5f\x26\x1b\x28\x98\x43\x95\x5d"
- "\x07\x37\xd5\x85\x96\x9d\x4b\xd2\xc3\x45";
+ "\x4d\x40\xe7\xaf\x43\x04\xa0\x9d\xe8\x7f\xbf\x98\x96\x20\x4c\x05"
+ "\x51\x41\xe3\xf8\x09\xb2\xfe\x73\x3b\xb2\x31\x0f\xdf\x98\xa1\x62";
static const char kSPKIHash_UTNUSERFirstObject[] =
- "\xda\xed\x64\x74\x14\x9c\x14\x3c\xab\xdd"
- "\x99\xa9\xbd\x5b\x28\x4d\x8b\x3c\xc9\xd8";
+ "\x0f\xe1\x4c\x26\x4b\x17\xbb\x6f\x0d\x65\x3e\x7a\x70\xeb\x36\x3d"
+ "\xbf\x54\xbe\x15\x80\x39\xed\xda\xe5\xc2\x57\x11\xdf\x48\xc1\x03";
static const char kSPKIHash_GTECyberTrustGlobalRoot[] =
- "\x59\x79\x12\xde\x61\x75\xd6\x6f\xc4\x23"
- "\xb7\x77\x13\x74\xc7\x96\xde\x6f\x88\x72";
+ "\x10\x69\xfa\x47\xa0\xaa\x4f\x8c\xf7\x11\x1b\x1c\xae\xa3\x65\xee"
+ "\xae\xd1\x0b\xff\xf3\x26\x60\xde\xf6\xe0\x61\x4b\xfa\xe7\x08\x75";
static const char kSPKIHash_BaltimoreCyberTrustRoot[] =
- "\x30\xa4\xe6\x4f\xde\x76\x8a\xfc\xed\x5a"
- "\x90\x84\x28\x30\x46\x79\x2c\x29\x15\x70";
+ "\x63\xd9\xaf\x9b\x47\xb1\x06\x4d\x49\xa1\x0e\x7b\x7f\xd5\x66\xdb"
+ "\xc8\xca\xa3\x99\x45\x9b\xfc\x28\x29\xc5\x71\xad\x8c\x6e\xf3\x4a";
static const char kSPKIHash_GlobalSignRootCA[] =
- "\x87\xdb\xd4\x5f\xb0\x92\x8d\x4e\x1d\xf8"
- "\x15\x67\xe7\xf2\xab\xaf\xd6\x2b\x67\x75";
+ "\x2b\xce\xe8\x58\x15\x8c\xf5\x46\x5f\xc9\xd7\x6f\x0d\xfa\x31\x2f"
+ "\xef\x25\xa4\xdc\xa8\x50\x1d\xa9\xb4\x6b\x67\xd1\xfb\xfa\x1b\x64";
static const char kSPKIHash_GlobalSignRootCA_R2[] =
- "\xa5\x06\x8a\x78\xcf\x84\xbd\x74\x32\xdd"
- "\x58\xf9\x65\xeb\x3a\x55\xe7\xc7\x80\xdc";
+ "\x8a\x27\xb5\x55\x7b\x4b\xec\x7c\xc0\x30\x5f\xbf\x3d\x53\xd1\xf7"
+ "\x1c\xd3\xf3\x49\x10\xc5\xd6\x5e\x27\xec\xdd\xb8\x20\x77\xba\x3d";
static const char kSPKIHash_GlobalSignRootCA_R3[] =
- "\xf7\x93\x19\xef\xdf\xc1\xf5\x20\xfb\xac"
- "\x85\x55\x2c\xf2\xd2\x8f\x5a\xb9\xca\x0b";
+ "\x70\x6b\xb1\x01\x7c\x85\x5c\x59\x16\x9b\xad\x5c\x17\x81\xcf\x59"
+ "\x7f\x12\xd2\xca\xd2\xf6\x3d\x1a\x4a\xa3\x74\x93\x80\x0f\xfb\x80";
static const char kSPKIHash_EntrustRootEC1[] =
- "\x07\x23\x2d\x45\x65\x87\xb9\xd7\xb1\xd9"
- "\x7d\xd1\xc5\xfb\x65\xc5\x89\xbf\x92\x96";
+ "\xfe\xa2\xb7\xd6\x45\xfb\xa7\x3d\x75\x3c\x1e\xc9\xa7\x87\x0c\x40"
+ "\xe1\xf7\xb0\xc5\x61\xe9\x27\xb9\x85\xbf\x71\x18\x66\xe3\x6f\x22";
static const char kSPKIHash_TheGoDaddyGroupClass2[] =
- "\xee\xe5\x9f\x1e\x2a\xa5\x44\xc3\xcb\x25"
- "\x43\xa6\x9a\x5b\xd4\x6a\x25\xbc\xbb\x8e";
+ "\x56\x32\xd9\x7b\xfa\x77\x5b\xf3\xc9\x9d\xde\xa5\x2f\xc2\x55\x34"
+ "\x10\x86\x40\x16\x72\x9c\x52\xdd\x65\x24\xc8\xa9\xc3\xb4\x48\x9f";
static const char kSPKIHash_GoDaddyRoot_G2[] =
- "\x21\x0f\x2c\x89\xf7\xc4\xcd\x5d\x1b\x82"
- "\x5e\x38\xd6\xc6\x59\x3b\xa6\x93\x75\xae";
+ "\x2a\x8f\x2d\x8a\xf0\xeb\x12\x38\x98\xf7\x4c\x86\x6a\xc3\xfa\x66"
+ "\x90\x54\xe2\x3c\x17\xbc\x7a\x95\xbd\x02\x34\x19\x2d\xc6\x35\xd0";
static const char kSPKIHash_GoDaddySecure[] =
- "\xba\x2e\xb5\xa8\x3e\x13\x23\xd9\x53\x4b"
- "\x5e\x65\xbc\xe7\xa3\x13\x5d\xd0\xa9\x96";
+ "\x32\xb6\x4b\x66\x72\x7a\x20\x63\xe4\x06\x6f\x3b\x95\x8c\xb0\xaa"
+ "\xee\x57\x6a\x5e\xce\xfd\x95\x33\x99\xbb\x88\x74\x73\x1d\x95\x87";
static const char kSPKIHash_ThawtePremiumServer[] =
- "\x5f\xf3\x24\x6c\x8f\x91\x24\xaf\x9b\x5f"
- "\x3e\xb0\x34\x6a\xf4\x2d\x5c\xa8\x5d\xcc";
+ "\xf5\x3c\x22\x05\x98\x17\xdd\x96\xf4\x00\x65\x16\x39\xd2\xf8\x57"
+ "\xe2\x10\x70\xa5\x9a\xbe\xd9\x07\x94\x00\xd9\xf6\x95\x50\x69\x00";
static const char kSPKIHash_ThawtePrimaryRootCA_G2[] =
- "\x6a\x25\x23\x9d\x62\x75\xcd\x52\x21\x69"
- "\x5c\x31\xe9\x89\xc4\xd5\x38\xb8\xc4\xea";
+ "\x67\xdc\x4f\x32\xfa\x10\xe7\xd0\x1a\x79\xa0\x73\xaa\x0c\x9e\x02"
+ "\x12\xec\x2f\xfc\x3d\x77\x9e\x0a\xa7\xf9\xc0\xf0\xe1\xc2\xc8\x93";
static const char kSPKIHash_ThawtePrimaryRootCA_G3[] =
- "\xab\x76\x88\xf4\xe5\xe1\x38\xc9\xe9\x50"
- "\x17\xcd\xcd\xb3\x18\x17\xb3\x3e\x8c\xf5";
+ "\x19\x06\xc6\x12\x4d\xbb\x43\x85\x78\xd0\x0e\x06\x6d\x50\x54\xc6"
+ "\xc3\x7f\x0f\xa6\x02\x8c\x05\x54\x5e\x09\x94\xed\xda\xec\x86\x29";
static const char kSPKIHash_ThawtePrimaryRootCA[] =
- "\x6c\xca\xbd\x7d\xb4\x7e\x94\xa5\x75\x99"
- "\x01\xb6\xa7\xdf\xd4\x5d\x1c\x09\x1c\xcc";
+ "\x1d\x75\xd0\x83\x1b\x9e\x08\x85\x39\x4d\x32\xc7\xa1\xbf\xdb\x3d"
+ "\xbc\x1c\x28\xe2\xb0\xe8\x39\x1f\xb1\x35\x98\x1d\xbc\x5b\xa9\x36";
static const char kSPKIHash_SymantecClass3EVG3[] =
- "\x47\x49\xdf\x16\x57\xf4\x6c\x8b\xd2\x8c"
- "\x79\x1b\x99\xfb\x9f\x28\x81\x2a\x60\xe0";
+ "\x80\xcc\x56\x3a\xb5\xf8\x3c\xc4\x1e\xb0\xaf\x6a\x14\xd6\xd8\x07"
+ "\x18\xc1\x7e\x35\x2f\x96\x49\xff\xbc\xdd\x67\xf8\xbf\x65\x13\x91";
static const char kSPKIHash_DigiCertECCSecureServerCA[] =
- "\xc3\x02\xb1\x73\x62\x0b\x47\x78\x5d\x21"
- "\xe2\x4d\xb3\xac\x46\xb1\xfc\xb8\xc5\xa9";
+ "\x3d\x95\xcd\xde\x54\x40\xcb\xef\x2d\x04\xa9\x36\x3b\x1e\x85\xee"
+ "\x32\x25\x9f\x3a\xf6\x63\x39\xb0\xa9\xcd\xc9\x9f\x27\xd7\xa0\x2c";
static const char kSPKIHash_FacebookBackup[] =
- "\xd7\x0c\x3c\x13\x40\x18\xb1\x1d\xa8\x5f"
- "\x99\x67\x76\x4d\xa1\xc2\x9d\x94\xa2\xc9";
+ "\xab\x83\xce\xd8\x6d\x9c\x6e\x46\x61\x67\xcd\xbe\x26\x09\x91\x53"
+ "\x21\x8c\xa0\x07\xa8\xcc\x0f\x81\x49\x75\x57\x41\x60\x7c\x5d\x64";
static const char kSPKIHash_SpiderOak2[] =
- "\x0f\x47\xd2\xfe\x1a\xae\x03\xa4\x29\xae"
- "\x5b\x9c\x8b\x23\xb5\x86\x51\x54\x03\x18";
+ "\xed\x8d\xd4\x9f\x16\xdf\x7c\xbf\x1a\x14\xf5\xec\x38\x90\x69\x19"
+ "\xab\x20\xa4\x39\xa7\x82\x92\x21\x03\x11\x8a\x75\x04\x64\x95\x04";
static const char kSPKIHash_SpiderOak3[] =
- "\x97\x92\x68\x21\x7b\xf8\x97\x3b\x59\xf8"
- "\x2e\x93\x25\x68\x31\x64\x21\xd0\xcd\x2e";
+ "\x2e\x41\x11\xe7\x8b\xce\x76\x5c\xa0\xa5\x3b\x1b\x62\xf9\x69\x32"
+ "\xad\x42\x13\xf9\x43\x00\x6d\x40\x3f\xdc\x66\x76\xdc\x2f\x57\x60";
+
+static const char kSPKIHash_YahooBackup1[] =
+ "\xd9\xf4\x40\x51\x7c\xb1\x97\x80\x35\xfd\x71\xeb\x28\xd0\x66\x73"
+ "\xc6\xd3\x93\x30\x3b\xcb\x81\x41\xfc\x62\xc9\xb8\xd0\x33\x0a\xa6";
+
+static const char kSPKIHash_YahooBackup2[] =
+ "\x76\x89\x67\x6e\xdc\xc4\x06\x71\x0b\xc7\xff\x65\x38\x44\x36\xd9"
+ "\xee\x8e\x64\xef\xd0\x35\xbe\x95\x49\x25\xf6\x5c\x70\x37\x13\xb0";
+
+static const char kSPKIHash_LetsEncryptAuthorityX1[] =
+ "\x60\xb8\x75\x75\x44\x7d\xcb\xa2\xa3\x6b\x7d\x11\xac\x09\xfb\x24"
+ "\xa9\xdb\x40\x6f\xee\x12\xd2\xcc\x90\x18\x05\x17\x61\x6e\x8a\x18";
+
+static const char kSPKIHash_LetsEncryptAuthorityX2[] =
+ "\xb1\x11\xdd\x8a\x1c\x20\x91\xa8\x9b\xd4\xfd\x60\xc5\x7f\x07\x16"
+ "\xcc\xe5\x0f\xee\xff\x81\x37\xcd\xbe\xe0\x32\x6e\x02\xcf\x36\x2b";
+static const char* const kExpectCTReportURIs[] = {
+ "https://report.badssl.com/expect-ct",
+};
// The following is static data describing the hosts that are hardcoded with
// certificate pins or HSTS information.
@@ -562,11 +585,12 @@ static const char* const kTorAcceptableCerts[] = {
kSPKIHash_Tor1,
kSPKIHash_Tor2,
kSPKIHash_Tor3,
+ kSPKIHash_LetsEncryptAuthorityX1,
+ kSPKIHash_LetsEncryptAuthorityX2,
NULL,
};
static const char* const kTwitterComAcceptableCerts[] = {
kSPKIHash_VeriSignClass1,
- kSPKIHash_VeriSignClass3,
kSPKIHash_VeriSignClass3_G4,
kSPKIHash_VeriSignClass4_G3,
kSPKIHash_VeriSignClass3_G3,
@@ -591,7 +615,6 @@ static const char* const kTwitterComAcceptableCerts[] = {
};
static const char* const kTwitterCDNAcceptableCerts[] = {
kSPKIHash_VeriSignClass1,
- kSPKIHash_VeriSignClass3,
kSPKIHash_VeriSignClass3_G4,
kSPKIHash_VeriSignClass4_G3,
kSPKIHash_VeriSignClass3_G3,
@@ -671,6 +694,24 @@ static const char* const kSpideroakAcceptableCerts[] = {
kSPKIHash_SpiderOak3,
NULL,
};
+static const char* const kYahooAcceptableCerts[] = {
+ kSPKIHash_VeriSignClass2_G2,
+ kSPKIHash_VeriSignClass2_G3,
+ kSPKIHash_VeriSignClass3_G3,
+ kSPKIHash_VeriSignClass3_G4,
+ kSPKIHash_VeriSignClass3_G5,
+ kSPKIHash_VeriSignUniversal,
+ kSPKIHash_GeoTrustGlobal,
+ kSPKIHash_GeoTrustPrimary,
+ kSPKIHash_GeoTrustPrimary_G2,
+ kSPKIHash_GeoTrustPrimary_G3,
+ kSPKIHash_GeoTrustUniversal,
+ kSPKIHash_DigiCertGlobalRoot,
+ kSPKIHash_DigiCertEVRoot,
+ kSPKIHash_YahooBackup1,
+ kSPKIHash_YahooBackup2,
+ NULL,
+};
struct Pinset {
const char *const *const accepted_pins;
@@ -687,2797 +728,4136 @@ static const struct Pinset kPinsets[] = {
{kDropboxAcceptableCerts, kNoRejectedPublicKeys, kDropboxReportURI},
{kFacebookAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
{kSpideroakAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
+ {kYahooAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
};
// kHSTSHuffmanTree describes a Huffman tree. The nodes of the tree are pairs
// of uint8s. The last node in the array is the root of the tree. Each pair is
-// two uint8 values, the first is "left" and the second is "right". If a uint8
-// value has the MSB set then it represents a literal leaf value. Otherwise
-// it's a pointer to the n'th element of the array.
-static const uint8 kHSTSHuffmanTree[] = {
- 0xf5, 0xe4, 0x00, 0xf2, 0x01, 0x80, 0xb2, 0xf1, 0xb9, 0xb6, 0xb8, 0x04,
- 0xb4, 0x05, 0x03, 0x06, 0xb1, 0xb0, 0xb5, 0xb7, 0x09, 0xb3, 0x08, 0x0a,
- 0x0b, 0xea, 0x07, 0x0c, 0xe6, 0x0d, 0x0e, 0xed, 0xe9, 0x0f, 0xae, 0xf7,
- 0x11, 0xe7, 0x12, 0xef, 0x10, 0x13, 0x02, 0x14, 0xeb, 0xe2, 0xe3, 0x16,
- 0xe1, 0x17, 0x18, 0xff, 0xfa, 0xf8, 0xf6, 0x1a, 0x1b, 0xe8, 0xf3, 0x1c,
- 0xe5, 0x1d, 0xec, 0xee, 0xad, 0xf9, 0x20, 0xf0, 0xf4, 0x21, 0x1f, 0x22,
- 0x1e, 0x23, 0x19, 0x24, 0x15, 0x25,
+// two uint8_t values, the first is "left" and the second is "right". If a
+// uint8_t value has the MSB set then it represents a literal leaf value.
+// Otherwise it's a pointer to the n'th element of the array.
+static const uint8_t kHSTSHuffmanTree[] = {
+ 0xf5, 0xe4, 0x00, 0xf2, 0x01, 0x80, 0xf9, 0xe6, 0x03, 0xe7, 0xe9, 0x04,
+ 0xb7, 0xb6, 0x06, 0xb1, 0xb0, 0xb3, 0x07, 0x08, 0x09, 0xea, 0xf8, 0x0a,
+ 0x0b, 0xf7, 0xed, 0x0c, 0x0d, 0xef, 0x05, 0x0e, 0x02, 0x0f, 0xeb, 0xe2,
+ 0xe3, 0x11, 0xe1, 0x12, 0x13, 0xff, 0xec, 0xf3, 0xe5, 0x15, 0xb9, 0xb5,
+ 0xb8, 0x17, 0xb2, 0x18, 0xb4, 0xf1, 0x19, 0x1a, 0xfa, 0x1b, 0x1c, 0xf6,
+ 0xad, 0xae, 0x1d, 0x1e, 0x1f, 0xee, 0xe8, 0xf0, 0xf4, 0x21, 0x20, 0x22,
+ 0x16, 0x23, 0x14, 0x24, 0x10, 0x25,
};
-static const uint8 kPreloadedHSTSData[] = {
- 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x22, 0x5b, 0xbf, 0x01, 0xd7, 0xa4,
- 0x2a, 0xe7, 0x5d, 0xbf, 0x8e, 0xbf, 0xfe, 0x8e, 0xc4, 0x85, 0xd4, 0xde,
- 0x51, 0x9e, 0x3a, 0xe7, 0xd1, 0xd5, 0x23, 0xfa, 0x08, 0xba, 0x27, 0x5f,
- 0xec, 0x64, 0x63, 0xdd, 0x43, 0xaf, 0xff, 0x68, 0x0b, 0xe8, 0xe6, 0xfe,
- 0x17, 0xe9, 0xd7, 0x66, 0x8e, 0xbc, 0xee, 0xd3, 0x44, 0x5b, 0x52, 0x44,
- 0x2e, 0x24, 0xb4, 0x56, 0xee, 0x68, 0xea, 0xe1, 0xe2, 0xe8, 0xbe, 0xff,
- 0xfc, 0x07, 0xee, 0x0f, 0x39, 0x9b, 0xcb, 0xc8, 0xb3, 0xaf, 0x63, 0x60,
- 0xeb, 0xf8, 0x23, 0x0d, 0x58, 0x0e, 0xbf, 0xe6, 0x45, 0x34, 0x83, 0xbc,
- 0x8e, 0xbc, 0x14, 0x9c, 0xea, 0x43, 0xd4, 0x73, 0x8b, 0xff, 0x9b, 0xc8,
- 0x52, 0x07, 0xca, 0xb2, 0xac, 0xac, 0x1d, 0x7f, 0x93, 0xa2, 0x07, 0x51,
- 0xa7, 0x54, 0x22, 0x17, 0x14, 0xef, 0xff, 0x20, 0x8c, 0x6f, 0xf7, 0x39,
- 0xac, 0x64, 0xeb, 0xb3, 0x72, 0xad, 0x05, 0x5b, 0xfe, 0x1a, 0x5f, 0xc5,
- 0xaf, 0xf7, 0xb3, 0x9f, 0xad, 0x34, 0x53, 0x06, 0xa6, 0xfe, 0x97, 0x53,
- 0x66, 0x4c, 0x75, 0x41, 0xf9, 0xba, 0x25, 0xfd, 0xd4, 0x6c, 0x2d, 0x0e,
- 0xbf, 0xd1, 0xfc, 0xef, 0x28, 0x57, 0x3a, 0xc3, 0x07, 0xc2, 0x25, 0x76,
- 0x61, 0x58, 0x5d, 0x5f, 0x55, 0xc2, 0xf1, 0x09, 0x89, 0xcb, 0xb2, 0x1f,
- 0x6a, 0x11, 0x35, 0x51, 0x06, 0xbb, 0x08, 0x01, 0x85, 0x2e, 0x88, 0x76,
- 0xe3, 0x0b, 0xfb, 0x08, 0x1b, 0xff, 0xff, 0x9d, 0x6c, 0x27, 0x38, 0x0e,
- 0x72, 0x07, 0x14, 0x4e, 0xf7, 0x3e, 0x9d, 0x7f, 0xf9, 0x56, 0x51, 0x95,
- 0x79, 0xc2, 0xaa, 0xf9, 0xf3, 0xbb, 0x67, 0x5f, 0xb8, 0xd7, 0x76, 0x9a,
- 0x2a, 0x2b, 0xf4, 0x77, 0x39, 0x87, 0x5f, 0xff, 0xbf, 0x94, 0xea, 0xb4,
- 0x2b, 0x73, 0xb7, 0x9f, 0x3e, 0x77, 0x6c, 0xeb, 0xff, 0xf3, 0xc8, 0x63,
- 0x59, 0xbb, 0x45, 0xf3, 0x76, 0x9d, 0x66, 0x24, 0x9b, 0xc6, 0x31, 0x34,
- 0xcf, 0xa4, 0xbb, 0x1a, 0xef, 0xfc, 0x1c, 0x5b, 0x1b, 0x78, 0x29, 0xe3,
- 0xaf, 0x63, 0x38, 0x75, 0xfe, 0xcc, 0x9c, 0x31, 0x81, 0x3a, 0xf7, 0x60,
- 0x27, 0x5f, 0xe8, 0x84, 0x11, 0x02, 0xb9, 0xd7, 0x38, 0x0e, 0xbe, 0xea,
- 0x75, 0x85, 0x42, 0x2b, 0x94, 0x1b, 0x98, 0xc7, 0xa3, 0x6c, 0x99, 0x5f,
- 0xb8, 0xd7, 0x76, 0x9a, 0x2b, 0xdb, 0xf2, 0x6d, 0x34, 0x13, 0x9d, 0x74,
- 0x48, 0xeb, 0xa3, 0xf3, 0xac, 0xc6, 0x22, 0x27, 0x86, 0x6e, 0x57, 0xf8,
- 0xad, 0xff, 0xcc, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89, 0x1a, 0xff,
- 0xf3, 0x0b, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x13, 0xc5, 0xff, 0xe6,
- 0x16, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x27, 0xfb, 0xff, 0xcc, 0x2d,
- 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x50, 0xd7, 0xff, 0x2d, 0xe4, 0xc6,
- 0x71, 0xae, 0xed, 0x34, 0x51, 0x17, 0xfe, 0x93, 0x00, 0xd7, 0xc8, 0xd4,
- 0x48, 0xea, 0x61, 0x12, 0x30, 0xa1, 0x7f, 0xe9, 0x93, 0xbb, 0xe7, 0x83,
- 0x8b, 0x3a, 0xff, 0xc2, 0xec, 0x78, 0x40, 0xf2, 0xd1, 0xd7, 0xee, 0x35,
- 0xdd, 0xa6, 0x8a, 0x46, 0xff, 0xa2, 0x51, 0xc9, 0xe3, 0x93, 0x9d, 0x79,
- 0xe4, 0xc6, 0x1f, 0x60, 0x99, 0xdf, 0xd2, 0xce, 0xf5, 0xe4, 0x75, 0xff,
- 0xfd, 0x81, 0xec, 0x7d, 0x63, 0xc2, 0xff, 0xeb, 0x51, 0xf9, 0x56, 0x62,
- 0x13, 0xa4, 0x69, 0xfa, 0xe1, 0x53, 0xe3, 0x2d, 0xb2, 0xcb, 0xf7, 0x1a,
- 0xee, 0xd3, 0x44, 0xa1, 0x7f, 0xf8, 0x5f, 0xda, 0xfa, 0x20, 0x90, 0xe2,
- 0xce, 0xbe, 0x61, 0xe4, 0xc6, 0x1f, 0xe2, 0xcc, 0xea, 0x76, 0x7d, 0x2c,
- 0xa7, 0x67, 0x83, 0x0e, 0x96, 0xc7, 0xd6, 0x8a, 0x6a, 0xf0, 0xee, 0xe4,
- 0x3c, 0x96, 0x87, 0xd5, 0x1f, 0xd5, 0xd5, 0x2a, 0xfa, 0x87, 0x40, 0x23,
- 0xc7, 0xda, 0x86, 0xad, 0xff, 0xe6, 0x16, 0xf2, 0x63, 0x38, 0xd7, 0x76,
- 0x9a, 0x27, 0x3b, 0xff, 0xcc, 0x2d, 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34,
- 0x51, 0x37, 0xf2, 0x6a, 0x69, 0x27, 0xe7, 0x5f, 0xe8, 0x9f, 0xee, 0xdb,
- 0x8f, 0xe7, 0x5e, 0xe4, 0x98, 0xe9, 0xf3, 0x7d, 0x2e, 0xae, 0x26, 0x97,
- 0xa5, 0x70, 0x42, 0xf6, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x0e, 0x5f, 0xc0,
- 0x6f, 0x12, 0x04, 0xeb, 0x31, 0x87, 0xbd, 0xd3, 0x3b, 0xfe, 0x8e, 0x63,
- 0x7b, 0x1b, 0xc8, 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x17, 0xdf, 0xb2, 0x69,
- 0x3e, 0x8e, 0xae, 0x1e, 0xa7, 0xd2, 0xdb, 0xfd, 0xac, 0x0f, 0x73, 0xf7,
- 0x3a, 0xe1, 0x9c, 0xeb, 0xfe, 0xf0, 0xc2, 0xfe, 0x87, 0xb0, 0x75, 0x41,
- 0xe7, 0xa0, 0xb5, 0xda, 0xdc, 0xeb, 0xef, 0x4a, 0x14, 0x2a, 0x96, 0x6e,
- 0x5c, 0x5e, 0xfc, 0xf3, 0xfb, 0x3a, 0x75, 0x98, 0x9d, 0x3d, 0x1c, 0x84,
- 0x64, 0xc4, 0x9d, 0x84, 0x08, 0xac, 0xed, 0x90, 0x5f, 0xff, 0xff, 0x0b,
- 0xb1, 0x80, 0x54, 0xa2, 0x89, 0xee, 0xe2, 0x4b, 0x5f, 0x31, 0x48, 0x91,
- 0xd7, 0xfe, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x13, 0x25, 0x98, 0x6a,
- 0x33, 0x17, 0x08, 0x2b, 0xba, 0xb3, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x16,
- 0xf5, 0x98, 0x09, 0xe4, 0xe0, 0xb5, 0xff, 0xe6, 0x16, 0xf2, 0x63, 0x38,
- 0xd7, 0x76, 0x9a, 0x29, 0x3b, 0x95, 0x95, 0x6c, 0xeb, 0xfb, 0x3c, 0x31,
- 0x0b, 0x3a, 0xfe, 0xdf, 0xff, 0xbc, 0x7f, 0xce, 0xbb, 0xac, 0x2a, 0x0f,
- 0xf3, 0xa4, 0x0e, 0x55, 0x50, 0xb9, 0xc7, 0x28, 0xfe, 0x72, 0x33, 0x8d,
- 0x3c, 0x6c, 0x28, 0xfb, 0x0d, 0x3b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34,
- 0x43, 0xb7, 0xee, 0x35, 0xdd, 0xa6, 0x89, 0x62, 0xfb, 0x3f, 0x5a, 0x1d,
- 0x7e, 0x61, 0x6f, 0x26, 0x30, 0xf5, 0x36, 0xcc, 0xef, 0xf3, 0x19, 0xc6,
- 0xbb, 0xb4, 0xd1, 0x18, 0x5f, 0x31, 0x2c, 0xd1, 0xd7, 0xff, 0xfd, 0x2d,
- 0x30, 0xde, 0xbc, 0xcd, 0xee, 0x71, 0x58, 0xec, 0xcb, 0xd1, 0xd7, 0xec,
- 0xf7, 0xf0, 0xd3, 0xaf, 0xff, 0x47, 0x93, 0xf8, 0x90, 0x7b, 0x02, 0xd3,
- 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x11, 0xed, 0xf6, 0x9f, 0x7d, 0x87, 0x5d,
- 0x26, 0x30, 0xf5, 0xfc, 0x67, 0x7f, 0xff, 0x3b, 0x02, 0x0c, 0xee, 0x0f,
- 0xf8, 0x3e, 0xee, 0x1d, 0x66, 0x37, 0x4e, 0xf2, 0x67, 0x0e, 0x13, 0xbc,
- 0x27, 0xc4, 0xba, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x61, 0xdf, 0xe9, 0x0c,
- 0x66, 0xb0, 0x4e, 0xb3, 0x18, 0x7c, 0x5b, 0x99, 0xdf, 0xe6, 0x33, 0x8d,
- 0x77, 0x69, 0xa2, 0xe7, 0xbf, 0xff, 0xff, 0xfa, 0x15, 0xa4, 0xa7, 0x6f,
- 0x7e, 0x7c, 0xee, 0xdb, 0x13, 0x81, 0x45, 0x5d, 0x0a, 0x8d, 0xe7, 0x9d,
- 0xab, 0xf9, 0xf3, 0xbb, 0x67, 0x54, 0x2e, 0x6e, 0xcf, 0x09, 0x39, 0x21,
- 0xb4, 0xfd, 0x23, 0xde, 0x5c, 0x2e, 0x7c, 0x53, 0xb4, 0x7f, 0x7f, 0x98,
- 0xce, 0x35, 0xdd, 0xa6, 0x88, 0x7a, 0xf9, 0xae, 0xed, 0x34, 0x44, 0xd7,
- 0xf6, 0x6d, 0x01, 0x78, 0x13, 0xaf, 0xf7, 0x80, 0xfb, 0xf6, 0x36, 0x1d,
- 0x5c, 0x44, 0x88, 0x96, 0xf8, 0xbe, 0xfe, 0x4f, 0xf5, 0xf3, 0x02, 0x75,
- 0xff, 0xfa, 0x39, 0xff, 0x63, 0x64, 0xd1, 0x0b, 0xd6, 0x04, 0xeb, 0xfe,
- 0xef, 0x63, 0x64, 0xb3, 0x90, 0x75, 0xbd, 0xd4, 0x48, 0x3a, 0xbd, 0xff,
- 0x27, 0x93, 0xd9, 0xfc, 0x70, 0xea, 0xc3, 0xdf, 0x72, 0x8b, 0xff, 0xfb,
- 0xdd, 0x8e, 0x7f, 0xac, 0x0f, 0x80, 0xed, 0xce, 0x1d, 0x77, 0x96, 0x75,
- 0xff, 0xec, 0xef, 0xd9, 0xf5, 0x09, 0xbf, 0xa1, 0x67, 0x5f, 0xfa, 0x78,
- 0x97, 0xdc, 0xe6, 0xb1, 0x93, 0xab, 0x11, 0xfd, 0xba, 0xdf, 0x45, 0x80,
- 0x99, 0x7d, 0xe0, 0x3f, 0xd3, 0x44, 0x2f, 0x7e, 0xee, 0x4e, 0x01, 0x3a,
- 0xf9, 0xf9, 0x1b, 0x0e, 0xa0, 0x9e, 0x4f, 0xe4, 0xf6, 0x63, 0x15, 0xa2,
- 0x70, 0xbf, 0xb1, 0x8f, 0x6a, 0x31, 0xe0, 0x1e, 0xec, 0x79, 0xbf, 0xf7,
- 0x01, 0x3e, 0x76, 0x61, 0x80, 0x9d, 0x77, 0x5c, 0xeb, 0x00, 0xea, 0xc3,
- 0x4b, 0xa1, 0x5b, 0xdf, 0xe9, 0x88, 0x44, 0x27, 0x99, 0x2f, 0xff, 0xb1,
- 0x25, 0xa6, 0x33, 0x79, 0x3c, 0xff, 0x5a, 0x75, 0x42, 0x22, 0x7a, 0x6d,
- 0x7e, 0x56, 0x34, 0x93, 0xaa, 0x0e, 0xbf, 0x95, 0x9f, 0xbd, 0xee, 0x4e,
- 0x75, 0xba, 0x75, 0x2b, 0x27, 0x8a, 0x03, 0x5b, 0xe0, 0xe0, 0xcc, 0x75,
- 0xc9, 0xe3, 0xad, 0xe4, 0x36, 0xdd, 0x21, 0xbf, 0xdb, 0xfb, 0x79, 0x00,
- 0x54, 0x3a, 0xff, 0xd1, 0x30, 0xe6, 0xc7, 0x5a, 0xd0, 0xea, 0x73, 0xf4,
- 0x01, 0xb5, 0xff, 0xff, 0xdd, 0x00, 0x53, 0x39, 0x30, 0xe6, 0xce, 0xe0,
- 0x63, 0x5a, 0x85, 0x0e, 0xbf, 0xfc, 0x93, 0x4b, 0x37, 0x97, 0xc5, 0xbb,
- 0x89, 0xd7, 0x3e, 0xd1, 0xd6, 0x54, 0x62, 0x72, 0x2a, 0x42, 0x69, 0xa4,
- 0x3d, 0x73, 0x74, 0xbb, 0xb6, 0xd4, 0x3a, 0xfd, 0xd7, 0xf3, 0xc8, 0xeb,
- 0xf9, 0x38, 0x39, 0x9c, 0x3a, 0xff, 0x4b, 0x51, 0xa5, 0x6a, 0xac, 0xab,
- 0x27, 0x5f, 0xfc, 0xbf, 0x9a, 0x1c, 0xde, 0x42, 0xf3, 0x9d, 0x7b, 0x49,
- 0xf9, 0xd5, 0x87, 0xc4, 0x88, 0xd7, 0x99, 0x65, 0x92, 0xaf, 0xce, 0x3e,
- 0xee, 0x14, 0xc1, 0x7f, 0x7e, 0x7f, 0x4d, 0x9e, 0x3a, 0x82, 0x89, 0xbf,
- 0xcf, 0xc4, 0xd6, 0xfd, 0xd1, 0x55, 0xfb, 0x7b, 0x47, 0x5c, 0xee, 0x75,
- 0xba, 0x87, 0x8e, 0xe6, 0x77, 0xff, 0x7e, 0x93, 0x7c, 0xec, 0x27, 0x00,
- 0xae, 0x75, 0xfc, 0x20, 0xf2, 0x4f, 0x07, 0x5f, 0xf9, 0x14, 0x81, 0x8d,
- 0x42, 0x2c, 0xeb, 0xfb, 0x36, 0x02, 0x59, 0xa3, 0xaf, 0xb0, 0x39, 0x39,
- 0xd7, 0xca, 0xff, 0x21, 0x58, 0x3a, 0xee, 0x41, 0xd5, 0x8a, 0xdb, 0x5a,
- 0x4d, 0xb9, 0x52, 0x46, 0x80, 0xae, 0xef, 0x31, 0x32, 0xd2, 0xba, 0x58,
- 0x27, 0x7e, 0x2e, 0xd8, 0x43, 0xb4, 0x57, 0x7e, 0x66, 0x30, 0x28, 0x75,
- 0xe0, 0x7b, 0x47, 0x5f, 0xff, 0xff, 0xf6, 0xbe, 0x77, 0x27, 0x86, 0x77,
- 0x96, 0xbe, 0x01, 0xbc, 0xe4, 0x7c, 0x99, 0x4d, 0xfe, 0x7c, 0xee, 0xd9,
- 0xd5, 0x88, 0xec, 0x69, 0x37, 0x87, 0x2e, 0x07, 0xe7, 0x5d, 0xb6, 0xac,
- 0x9d, 0x7b, 0xe4, 0x9a, 0x75, 0x41, 0xe9, 0xa8, 0x2e, 0xb1, 0xeb, 0xff,
- 0xfb, 0x9f, 0x07, 0x36, 0x67, 0x25, 0xf2, 0x02, 0xf3, 0x68, 0xeb, 0xff,
- 0xff, 0x87, 0x78, 0x50, 0x70, 0x3d, 0x49, 0xbe, 0x6b, 0x37, 0x97, 0x31,
- 0x93, 0xab, 0x11, 0xac, 0x2c, 0x17, 0xde, 0x04, 0x4e, 0x75, 0xfe, 0x96,
- 0x77, 0x17, 0x0d, 0x3a, 0x90, 0xf4, 0xfc, 0x45, 0x7f, 0xff, 0x6f, 0x2d,
- 0x2f, 0x07, 0xe6, 0xd2, 0x76, 0x74, 0xce, 0x1d, 0x65, 0x73, 0xab, 0x0f,
- 0xcd, 0xac, 0x17, 0xff, 0xfe, 0x67, 0xe0, 0xe3, 0x7a, 0x83, 0x80, 0xdf,
- 0xdf, 0x1d, 0x9c, 0x50, 0xeb, 0xfc, 0xa0, 0x41, 0x1d, 0x18, 0x3a, 0xff,
- 0x6f, 0x2d, 0x28, 0x08, 0xdc, 0xeb, 0xfc, 0xec, 0x82, 0x68, 0xf3, 0x9d,
- 0x50, 0x98, 0x66, 0x38, 0xa1, 0x90, 0x9b, 0x5f, 0xfa, 0x34, 0x39, 0xb3,
- 0xe4, 0x97, 0x23, 0xaf, 0xbf, 0xf2, 0x4e, 0x75, 0xfe, 0xf7, 0x50, 0x7f,
- 0xfa, 0xb3, 0xaf, 0xf4, 0xf0, 0xb1, 0x8d, 0xff, 0x3a, 0xd1, 0x23, 0xe9,
- 0x73, 0x5b, 0xff, 0x9f, 0x92, 0xf9, 0xe1, 0x89, 0x67, 0x8e, 0xa8, 0x57,
- 0x4d, 0x8e, 0x89, 0x09, 0x4e, 0x46, 0x5b, 0xd3, 0xa7, 0x41, 0x18, 0x46,
- 0x00, 0x9a, 0xff, 0xfb, 0x88, 0x05, 0x4c, 0x7c, 0xd0, 0x3f, 0x5e, 0x78,
- 0xeb, 0x81, 0x23, 0xaf, 0xd1, 0xfe, 0xa7, 0xf1, 0xd7, 0x9f, 0xda, 0x3a,
- 0xe0, 0x4e, 0x75, 0xe1, 0xf4, 0xd2, 0x36, 0x5c, 0x1b, 0xbf, 0x80, 0xdf,
- 0x81, 0xdd, 0x93, 0xaa, 0x0f, 0x95, 0x0c, 0xef, 0xf7, 0x20, 0x31, 0xd8,
- 0x91, 0xd7, 0xff, 0xd1, 0xef, 0x82, 0x0d, 0xaf, 0x99, 0xed, 0xbc, 0xf1,
- 0xd4, 0x88, 0x89, 0x01, 0x8d, 0xff, 0xdd, 0x85, 0x3e, 0x78, 0x5f, 0xd1,
- 0xe3, 0xaf, 0xf7, 0xcd, 0xe4, 0x9d, 0x02, 0xce, 0xaf, 0xcf, 0xec, 0x51,
- 0x6f, 0xfe, 0xcd, 0x98, 0x1f, 0x9e, 0x51, 0x19, 0xd1, 0xd7, 0xfe, 0xe4,
- 0xdf, 0x35, 0x09, 0x3b, 0xf8, 0xea, 0x84, 0x56, 0x04, 0x88, 0x09, 0x37,
- 0x3f, 0xe7, 0x5f, 0xff, 0x7c, 0x18, 0xd4, 0x4e, 0x38, 0x1e, 0xa4, 0xc7,
- 0x5f, 0xff, 0xfd, 0xae, 0x0c, 0x4d, 0xf3, 0xef, 0x92, 0x59, 0xbf, 0xb3,
- 0x60, 0xe6, 0x8e, 0xae, 0x23, 0x1c, 0x54, 0x2b, 0xc8, 0xff, 0x04, 0x37,
- 0x68, 0xeb, 0xa6, 0x91, 0xd5, 0x06, 0x87, 0x81, 0x57, 0xff, 0x0f, 0xb5,
- 0xb1, 0x3d, 0x18, 0x33, 0x1d, 0x7e, 0xe2, 0x6a, 0x37, 0x3a, 0xb0, 0xfa,
- 0xdd, 0x12, 0xff, 0x4e, 0xa8, 0x9a, 0x49, 0xed, 0x1d, 0x7e, 0x1f, 0x77,
- 0x36, 0x8e, 0xbf, 0x4d, 0xa7, 0xe2, 0x87, 0x5e, 0x76, 0x79, 0x07, 0xa5,
- 0x85, 0x35, 0x24, 0x6e, 0xa1, 0x07, 0x21, 0x17, 0x7f, 0xdd, 0x4e, 0x4d,
- 0xd7, 0xce, 0x1d, 0x7f, 0xff, 0xff, 0x7f, 0xa1, 0xc7, 0xdf, 0xe0, 0x7a,
- 0x0f, 0x83, 0x9b, 0xcb, 0x01, 0x38, 0xe3, 0xee, 0x75, 0x35, 0x18, 0xc8,
- 0x71, 0x79, 0xdd, 0xa6, 0x8a, 0x62, 0xb0, 0xf2, 0x5a, 0x45, 0x7f, 0xec,
- 0x1d, 0xe5, 0xaf, 0x47, 0x26, 0x3a, 0xf6, 0x27, 0xe7, 0x5b, 0x0e, 0xbd,
- 0xb8, 0xe7, 0xe6, 0xab, 0x60, 0xdd, 0x22, 0x27, 0x9d, 0xa6, 0xff, 0x73,
- 0xaf, 0xf1, 0x61, 0x98, 0xeb, 0xfd, 0xf3, 0x79, 0x0c, 0x66, 0x8e, 0xa4,
- 0x3e, 0xa7, 0x36, 0xbf, 0xff, 0x7e, 0x9a, 0xf9, 0xd7, 0xd7, 0xa2, 0x6d,
- 0x77, 0x0e, 0xbf, 0x93, 0xae, 0x93, 0xc1, 0xd7, 0xa5, 0x1b, 0x9d, 0x7f,
- 0x96, 0x1e, 0xc4, 0xf8, 0xc9, 0xd5, 0x87, 0xf7, 0xb9, 0x5b, 0x8e, 0x5f,
- 0xff, 0xe1, 0xc6, 0xfb, 0xd1, 0xed, 0x4c, 0x38, 0xcf, 0xc8, 0x56, 0x0e,
- 0xbf, 0xf3, 0x61, 0x7d, 0xcd, 0x62, 0x09, 0xd5, 0x08, 0xa2, 0xeb, 0x3d,
- 0xfb, 0x91, 0xb2, 0x38, 0x75, 0xfc, 0xe3, 0xf0, 0x30, 0x27, 0x56, 0x1f,
- 0xb2, 0x11, 0x00, 0xa2, 0xa1, 0x95, 0xe1, 0x3a, 0xb4, 0x85, 0x83, 0x0c,
- 0x05, 0x21, 0x52, 0xd8, 0xd2, 0x77, 0x8c, 0xb9, 0x12, 0x66, 0x8d, 0xa3,
- 0x91, 0xa1, 0xae, 0x17, 0xfd, 0x84, 0x5f, 0xe4, 0x03, 0x0d, 0x3f, 0x46,
- 0x8d, 0x7f, 0xdc, 0x76, 0x7e, 0x38, 0x5e, 0x73, 0xaf, 0xe7, 0x66, 0x61,
- 0x40, 0x9d, 0x7f, 0xff, 0x83, 0x93, 0xb8, 0xfb, 0x50, 0xdf, 0x8b, 0x5a,
- 0x0b, 0x4e, 0xbf, 0x83, 0xa7, 0x8d, 0xe4, 0x75, 0x42, 0x23, 0x9d, 0x86,
- 0xff, 0xa2, 0x6e, 0xa4, 0x2d, 0xc2, 0x75, 0x28, 0x9a, 0x77, 0x0e, 0xc6,
- 0x17, 0x60, 0x21, 0xbe, 0xc1, 0x51, 0x5c, 0xeb, 0xff, 0xff, 0xf7, 0x53,
- 0xdd, 0xce, 0x46, 0xcf, 0x8b, 0x06, 0xd7, 0xcc, 0xde, 0x58, 0x01, 0xff,
- 0x47, 0x5b, 0xc8, 0x8b, 0x1d, 0x12, 0x5f, 0xfa, 0x1b, 0xf0, 0x5f, 0x4b,
- 0x81, 0x3a, 0xff, 0xfd, 0x99, 0xd4, 0x6f, 0x73, 0xe6, 0x81, 0xd8, 0x57,
- 0x3a, 0xff, 0xfb, 0xdd, 0xcf, 0xfe, 0x2e, 0x33, 0xc1, 0xc1, 0x3a, 0xfe,
- 0x70, 0xf3, 0x80, 0x9c, 0xeb, 0xf4, 0x60, 0xfb, 0x6c, 0xea, 0x69, 0xeb,
- 0x2c, 0xba, 0xfb, 0xc9, 0xcc, 0x3a, 0xdb, 0xfc, 0x3c, 0x2c, 0x22, 0xb6,
- 0xb1, 0x31, 0x27, 0x87, 0x45, 0x2d, 0x3d, 0x41, 0x3d, 0xf4, 0x6d, 0x57,
- 0xff, 0xff, 0xe1, 0xcd, 0xe4, 0x9a, 0x1c, 0xd9, 0xdc, 0x9b, 0xb0, 0x33,
- 0x7c, 0x76, 0xa6, 0xc3, 0xa9, 0x11, 0x7a, 0x03, 0x6b, 0xff, 0xc8, 0x1f,
- 0x8b, 0x4f, 0x90, 0x17, 0x9b, 0x47, 0x5d, 0x29, 0x1d, 0x6e, 0x41, 0xf1,
- 0xce, 0x9b, 0x7e, 0x94, 0x6f, 0x2d, 0x1d, 0x7f, 0xff, 0xff, 0xec, 0x15,
- 0x3e, 0x27, 0x40, 0xc4, 0xc9, 0xe8, 0x58, 0xba, 0x9d, 0x46, 0x33, 0xbb,
- 0xff, 0x01, 0x2a, 0xff, 0xff, 0xe6, 0xa3, 0x21, 0x07, 0x3e, 0x02, 0x27,
- 0xd3, 0x7a, 0x0e, 0xee, 0xec, 0x9d, 0x70, 0x27, 0xdd, 0x34, 0x04, 0x28,
- 0xd4, 0x27, 0xea, 0x17, 0x3a, 0x7b, 0x2a, 0xe5, 0xe1, 0x0a, 0x31, 0xb4,
- 0x5f, 0xe7, 0x96, 0x2d, 0xc7, 0xf3, 0xaf, 0xb3, 0xb1, 0x31, 0xd7, 0x96,
- 0xdf, 0x9d, 0x3d, 0x27, 0x31, 0xbf, 0xff, 0xfd, 0xc6, 0x8e, 0x6c, 0xf9,
- 0xa4, 0xc1, 0xff, 0xe0, 0xe6, 0xc1, 0xcd, 0x6c, 0x3a, 0xff, 0x9b, 0x8e,
- 0xbf, 0x9b, 0x70, 0xb3, 0xab, 0x11, 0x75, 0xc7, 0xeb, 0xff, 0xf2, 0x0f,
- 0xbb, 0x9b, 0x5e, 0x9b, 0x15, 0xdc, 0x7f, 0x3a, 0xfd, 0x0c, 0xfc, 0xd4,
- 0xc7, 0x5f, 0xf8, 0x67, 0x1c, 0xd9, 0xa0, 0x46, 0xe7, 0x5f, 0xf8, 0x3d,
- 0x8d, 0xfe, 0x2a, 0xfd, 0x9f, 0xa1, 0xd5, 0x08, 0x8a, 0x9d, 0x02, 0x91,
- 0x35, 0x4d, 0x11, 0x79, 0x68, 0x10, 0xb5, 0xbf, 0xf0, 0xc9, 0xbd, 0x4e,
- 0x88, 0x27, 0x3a, 0xf7, 0xb1, 0x52, 0x75, 0x41, 0xee, 0xe1, 0xf5, 0xed,
- 0xbc, 0xe9, 0xd7, 0x60, 0x4e, 0xa9, 0xd5, 0x9a, 0xca, 0x52, 0x1e, 0xa1,
- 0x3f, 0xe2, 0x0d, 0x83, 0xd7, 0xe4, 0xf6, 0xb3, 0xf3, 0xaf, 0xdd, 0xcd,
- 0x89, 0xb0, 0xeb, 0xc9, 0x9f, 0x9d, 0x7f, 0x06, 0x07, 0xaf, 0x23, 0xaf,
- 0x40, 0x60, 0xeb, 0xf6, 0x7b, 0x4f, 0x37, 0xc3, 0xc5, 0x59, 0x5d, 0xfc,
- 0xcf, 0xc5, 0x6d, 0x5a, 0xaa, 0x95, 0xb3, 0xaa, 0x48, 0x86, 0x44, 0x1b,
- 0xff, 0xf7, 0x01, 0xce, 0x40, 0xe2, 0x89, 0xde, 0xe7, 0xd3, 0xaf, 0x80,
- 0xfb, 0xf8, 0xea, 0x92, 0x7a, 0x21, 0x27, 0x50, 0xaa, 0x68, 0x73, 0x70,
- 0x8b, 0xaa, 0xd4, 0x75, 0xfd, 0xa6, 0xb5, 0xc5, 0x43, 0xa9, 0x56, 0x36,
- 0xfe, 0x0a, 0xbf, 0xc3, 0xf3, 0x66, 0xf2, 0xd4, 0xc7, 0x5d, 0x3e, 0xe7,
- 0x5f, 0xba, 0xea, 0xf1, 0xf9, 0xd4, 0x13, 0xfb, 0x73, 0x9d, 0xa1, 0x8b,
- 0xfd, 0xc9, 0x87, 0x3a, 0xfe, 0x3a, 0xa1, 0x30, 0x4c, 0x85, 0x0a, 0x18,
- 0xdf, 0x93, 0x81, 0xc1, 0x3a, 0xfd, 0xfe, 0x7b, 0xec, 0xe7, 0x5f, 0xe6,
- 0x7d, 0x9d, 0xf9, 0xbe, 0x8e, 0xa8, 0x3e, 0x27, 0x2b, 0xa9, 0x23, 0x6b,
- 0xa6, 0x63, 0x08, 0x7b, 0xfe, 0xf7, 0x72, 0x4e, 0x39, 0xb9, 0xd7, 0xff,
- 0xfc, 0x2f, 0xfe, 0xa7, 0xc4, 0x1f, 0x0e, 0x6c, 0xf9, 0xa6, 0x44, 0xea,
- 0x14, 0x50, 0x78, 0xde, 0xff, 0xc9, 0x93, 0x7c, 0xd4, 0x75, 0xd5, 0xce,
- 0xbf, 0xed, 0xf2, 0x37, 0x98, 0x61, 0x67, 0x5f, 0xdb, 0xeb, 0xb8, 0xfc,
- 0x3a, 0xff, 0xff, 0xc8, 0xbe, 0x26, 0x6e, 0x20, 0xf4, 0x77, 0xe6, 0xc4,
- 0xf4, 0xd0, 0x75, 0x3a, 0x27, 0x3c, 0x5b, 0x41, 0x4c, 0xe7, 0xa8, 0x5e,
- 0x86, 0xad, 0xff, 0x67, 0x27, 0x84, 0xe6, 0x09, 0xd6, 0x59, 0xdf, 0x0d,
- 0xb5, 0xe1, 0xc0, 0x9d, 0x50, 0x6f, 0x37, 0x22, 0xbf, 0xb7, 0xd6, 0x60,
- 0xa8, 0x75, 0xf2, 0xfe, 0xc7, 0xe7, 0x5f, 0xfe, 0x9c, 0x3c, 0x76, 0x8e,
- 0x6c, 0xe2, 0x68, 0xea, 0xc4, 0x4e, 0x21, 0x68, 0x09, 0x2f, 0xf3, 0xfb,
- 0xaf, 0x37, 0xd5, 0x9d, 0x78, 0x1b, 0xfe, 0x75, 0x42, 0xb4, 0x1c, 0x8d,
- 0x6d, 0x21, 0x51, 0xc8, 0x5e, 0xb9, 0x70, 0x9a, 0xdf, 0xde, 0x7e, 0xfc,
- 0x0c, 0x1d, 0x7f, 0xfb, 0xda, 0xfb, 0xaf, 0x9e, 0x18, 0x96, 0x78, 0xeb,
- 0xfd, 0xe4, 0x9f, 0x3a, 0x0f, 0x1d, 0x69, 0x8e, 0xbf, 0xb0, 0x19, 0xd6,
- 0xce, 0x75, 0xd9, 0xbc, 0x1b, 0xed, 0x08, 0xdf, 0xdd, 0x79, 0x2f, 0x88,
- 0x75, 0xff, 0xca, 0x28, 0xfe, 0xd7, 0x86, 0x37, 0x91, 0xd7, 0xf7, 0x86,
- 0x25, 0x9e, 0x3a, 0xa0, 0xfc, 0x64, 0x8d, 0x72, 0x68, 0xeb, 0xdc, 0xcd,
- 0xce, 0xa0, 0x9b, 0x1f, 0xc5, 0x6f, 0xff, 0x3a, 0x9e, 0x52, 0x06, 0x59,
- 0xd4, 0x59, 0xd7, 0xe4, 0xd6, 0xa1, 0x67, 0x52, 0x22, 0x44, 0x48, 0xb6,
- 0x24, 0xd4, 0x2a, 0xc8, 0xc2, 0xe5, 0x13, 0x51, 0xc7, 0xf2, 0xc1, 0x84,
- 0xe8, 0x21, 0xc7, 0x7e, 0x0a, 0x0b, 0x84, 0xeb, 0xff, 0xf4, 0xbb, 0x93,
- 0x76, 0x05, 0x41, 0xcf, 0x74, 0x07, 0x52, 0x1f, 0xd7, 0x09, 0x6f, 0xff,
- 0xf2, 0x66, 0xf2, 0xd7, 0xbb, 0x0b, 0x84, 0x0f, 0xc8, 0x56, 0x0e, 0xbf,
- 0xce, 0x3f, 0x1b, 0xaf, 0xc2, 0x75, 0xff, 0x81, 0xaf, 0x8b, 0xfb, 0xd7,
- 0xec, 0x1d, 0x7e, 0xcf, 0x03, 0x37, 0x3a, 0xf2, 0x99, 0xb9, 0xd7, 0x44,
- 0xdf, 0x0f, 0x13, 0xc4, 0xf4, 0x28, 0xb6, 0x04, 0x21, 0xaf, 0xff, 0xff,
- 0xc0, 0x1f, 0x8c, 0xbe, 0xf2, 0xe3, 0xff, 0xf3, 0x40, 0x8d, 0xfb, 0x88,
- 0x38, 0xa1, 0xd7, 0xff, 0xe0, 0x73, 0x99, 0xed, 0x75, 0x33, 0xe7, 0x7f,
- 0x83, 0xab, 0x11, 0xc1, 0xd8, 0x44, 0xdf, 0xb0, 0x5b, 0xf5, 0x67, 0x5f,
- 0xfd, 0xdc, 0x81, 0x98, 0x73, 0xda, 0x73, 0xad, 0x2f, 0x1f, 0x4e, 0xd1,
- 0x45, 0xff, 0xf8, 0x38, 0xbf, 0x9b, 0x5e, 0x8d, 0x4d, 0x27, 0xe4, 0xe7,
- 0x5f, 0xff, 0xde, 0x49, 0xf0, 0x3f, 0x16, 0xf2, 0xe2, 0x4e, 0xeb, 0x3a,
- 0xff, 0x4e, 0xeb, 0x18, 0xe4, 0xc7, 0x5f, 0xf6, 0xf8, 0xa7, 0xeb, 0xcf,
- 0x9c, 0xc4, 0x48, 0x22, 0xed, 0xff, 0x60, 0xcf, 0xf3, 0xf7, 0x79, 0x8e,
- 0xbf, 0xee, 0x4f, 0x13, 0xce, 0x0e, 0x4e, 0x75, 0xff, 0xbe, 0x4d, 0xd0,
- 0x28, 0x98, 0x2a, 0x1d, 0x7f, 0x87, 0xe6, 0x81, 0xb6, 0x0e, 0x1d, 0x58,
- 0x7f, 0x40, 0x42, 0xa8, 0x46, 0xc6, 0xa1, 0x6f, 0x7f, 0xfa, 0x7f, 0x9a,
- 0xe8, 0x3e, 0x7b, 0x5a, 0x8e, 0x1d, 0x7f, 0xfd, 0xd8, 0x9f, 0xe0, 0xe6,
- 0xc7, 0xef, 0x63, 0x73, 0xaf, 0xff, 0xfb, 0x7d, 0x26, 0x33, 0xf3, 0xb9,
- 0xed, 0x64, 0xff, 0x31, 0x02, 0x75, 0x05, 0x17, 0xd8, 0xa7, 0x7f, 0x4f,
- 0xe9, 0x86, 0x16, 0x75, 0xff, 0xfd, 0x93, 0xe2, 0x04, 0x41, 0xdf, 0x90,
- 0x17, 0x9b, 0x47, 0x56, 0x27, 0x74, 0x91, 0x87, 0x39, 0x16, 0x8b, 0xaa,
- 0x75, 0xf8, 0x80, 0xb3, 0x29, 0x0e, 0xb6, 0xc6, 0x0f, 0xbc, 0x24, 0x10,
- 0xaf, 0x90, 0xec, 0x5a, 0xa6, 0xa3, 0x13, 0xf4, 0x7c, 0x37, 0xfb, 0xc3,
- 0x9e, 0xee, 0x4e, 0x75, 0xff, 0x9f, 0x9d, 0xcf, 0x40, 0xa7, 0xe7, 0x5f,
- 0xff, 0x0e, 0x4f, 0xf3, 0xf0, 0x7b, 0x31, 0x7f, 0xb2, 0x75, 0xf4, 0xbc,
- 0x93, 0x9d, 0x7f, 0xd8, 0xce, 0xf2, 0xd7, 0xcf, 0x21, 0xd7, 0xfe, 0x94,
- 0x67, 0xfd, 0xcc, 0x16, 0x9d, 0x7f, 0xfb, 0xa8, 0x21, 0xf9, 0xf5, 0xa3,
- 0x9d, 0xc3, 0xab, 0x11, 0x0f, 0x31, 0xe5, 0xff, 0x75, 0x17, 0x18, 0x3e,
- 0xd1, 0xd7, 0xff, 0xf8, 0x1e, 0xe0, 0x26, 0xf9, 0xe9, 0xba, 0x0f, 0xfc,
- 0x99, 0xb4, 0x75, 0xf4, 0x36, 0x17, 0xf1, 0x18, 0x6d, 0x23, 0x13, 0x6a,
- 0x85, 0x56, 0x2d, 0x32, 0xe1, 0xe3, 0xaa, 0x09, 0x16, 0xd4, 0x70, 0xd7,
- 0xff, 0xf7, 0x31, 0xd7, 0xf1, 0x47, 0xdf, 0xb9, 0xde, 0xc7, 0x8e, 0xbf,
- 0xd0, 0xbc, 0xce, 0x4d, 0x23, 0xaf, 0x93, 0xc9, 0x07, 0x5f, 0xff, 0xfe,
- 0x14, 0x53, 0xaf, 0x37, 0xc1, 0x06, 0xd7, 0xcc, 0xde, 0x58, 0x01, 0xff,
- 0x47, 0x5f, 0xba, 0x90, 0x33, 0x9d, 0x77, 0xa1, 0x68, 0xa6, 0xd9, 0x08,
- 0x0a, 0x92, 0x3e, 0x92, 0x18, 0xb5, 0x0c, 0xd1, 0xac, 0x9f, 0xa9, 0x49,
- 0x6c, 0x5c, 0x5f, 0xea, 0xeb, 0xc6, 0x59, 0x7e, 0x81, 0xf2, 0x6c, 0x3a,
- 0xfb, 0xda, 0x7f, 0xce, 0xbf, 0xfb, 0xa9, 0xf1, 0x38, 0x09, 0xdf, 0x8d,
- 0x3a, 0xf9, 0x3a, 0xf3, 0x9d, 0x7d, 0xb2, 0x3d, 0x07, 0x5f, 0xb5, 0x9e,
- 0x4d, 0x1d, 0x7e, 0x02, 0xa4, 0x5f, 0xc7, 0x5f, 0xdd, 0x79, 0xfe, 0x4b,
- 0xc7, 0x5f, 0x9f, 0x83, 0xba, 0x1d, 0x50, 0x88, 0x04, 0x2a, 0xf1, 0x85,
- 0x05, 0x3a, 0x6c, 0x27, 0x50, 0x89, 0xa8, 0xc8, 0x43, 0x31, 0x17, 0xa1,
- 0x4d, 0x7f, 0xbb, 0x08, 0x2f, 0xc5, 0x0e, 0xbf, 0xa1, 0x05, 0xf8, 0xa1,
- 0xd7, 0xfb, 0xf7, 0xff, 0x9c, 0x4e, 0x7c, 0x3d, 0xce, 0x98, 0xdb, 0xf3,
- 0xaf, 0xe8, 0xe4, 0xf1, 0xc9, 0xce, 0xbc, 0x07, 0xd1, 0xd5, 0x23, 0xc9,
- 0xfa, 0x5d, 0x7f, 0xff, 0x27, 0x3e, 0x62, 0x60, 0xa9, 0xd4, 0xc5, 0xe3,
- 0x4e, 0xbf, 0xff, 0xe4, 0x9f, 0x90, 0xbd, 0x02, 0x3e, 0x47, 0x20, 0x3d,
- 0x85, 0x9d, 0x58, 0x8c, 0x0e, 0x2c, 0xdf, 0xbf, 0xd2, 0x6e, 0xc9, 0xd7,
- 0xfe, 0xe6, 0x6f, 0xdd, 0xe1, 0x73, 0xc1, 0xd7, 0xff, 0xff, 0xb9, 0xc4,
- 0x9f, 0xe7, 0x73, 0xc3, 0x13, 0x77, 0x27, 0x8d, 0xfc, 0x06, 0x9d, 0x7f,
- 0xff, 0xf4, 0x29, 0xd8, 0xf8, 0x38, 0x05, 0x3e, 0x6f, 0x2d, 0x20, 0xfd,
- 0x89, 0xce, 0xbf, 0x6f, 0xa4, 0xc1, 0x3a, 0xb1, 0x13, 0xe0, 0x79, 0xa4,
- 0x4c, 0xf7, 0xb1, 0x8d, 0xdf, 0xfd, 0x2d, 0x22, 0x9d, 0x84, 0x9e, 0x14,
- 0x3a, 0xff, 0x84, 0x13, 0x0e, 0x75, 0xfc, 0x75, 0xfe, 0xec, 0x32, 0x1e,
- 0xba, 0xce, 0xbf, 0xe5, 0xe6, 0xbe, 0x4c, 0x30, 0xb3, 0xa8, 0x27, 0xda,
- 0xb3, 0x3b, 0xff, 0xfe, 0x7e, 0x77, 0x3c, 0x98, 0x33, 0xea, 0x30, 0x43,
- 0xd8, 0x3a, 0xfb, 0xdf, 0x27, 0xe1, 0xd5, 0xba, 0x21, 0xdd, 0x8a, 0xff,
- 0xff, 0xdb, 0xe4, 0xe0, 0xda, 0xf9, 0xbc, 0xbd, 0x0c, 0xfc, 0xce, 0x7f,
- 0xfc, 0x1d, 0x7f, 0xf9, 0x97, 0x19, 0xd6, 0x04, 0x0a, 0x0a, 0x1d, 0x7f,
- 0x4d, 0xbc, 0x81, 0x1e, 0x3a, 0xff, 0xba, 0xeb, 0x1c, 0xeb, 0xf8, 0xeb,
- 0xec, 0xe7, 0xec, 0x9d, 0x50, 0x88, 0x8d, 0x17, 0xf8, 0xda, 0xfe, 0xcf,
- 0x73, 0x99, 0x23, 0xaf, 0xe1, 0xce, 0x8e, 0x34, 0xeb, 0xe1, 0xcd, 0x7c,
- 0x98, 0xf5, 0xbc, 0x59, 0x7f, 0xd8, 0xbe, 0xc2, 0x70, 0x0a, 0xe7, 0x50,
- 0x57, 0x7a, 0xb0, 0x89, 0x42, 0xa6, 0xc6, 0xfb, 0xb9, 0x4a, 0x22, 0xf2,
- 0x14, 0x9d, 0x85, 0x4b, 0x91, 0xe9, 0xe7, 0xd0, 0xd0, 0xd9, 0x08, 0x5f,
- 0xa7, 0x77, 0xfe, 0xc6, 0x47, 0x01, 0x8a, 0x4b, 0xf3, 0xaf, 0xfc, 0x39,
- 0xf3, 0x99, 0xd1, 0xc9, 0x8e, 0xbf, 0xff, 0xdd, 0x7f, 0xf5, 0xf0, 0x73,
- 0x60, 0xe6, 0xb1, 0x70, 0xd3, 0xa8, 0x51, 0x41, 0xa3, 0xea, 0x55, 0x99,
- 0x1f, 0x70, 0xb5, 0x93, 0xd9, 0xdb, 0xc3, 0x49, 0xe1, 0xbf, 0x7f, 0x67,
- 0x7e, 0x8e, 0xff, 0x9d, 0x7f, 0x77, 0x07, 0xdf, 0x80, 0xeb, 0xf0, 0xc2,
- 0xdc, 0x27, 0x5f, 0xec, 0x9b, 0xb9, 0xe8, 0x09, 0xd7, 0xf0, 0xf9, 0xd6,
- 0x9e, 0x3a, 0xd2, 0x3a, 0xa0, 0xdd, 0xf8, 0xae, 0xf0, 0xb6, 0x0e, 0xbf,
- 0xff, 0xfe, 0xee, 0x7b, 0x4f, 0x37, 0xc1, 0xcd, 0xe5, 0x80, 0x9c, 0x70,
- 0x3d, 0x49, 0x8e, 0xb8, 0x0a, 0x1d, 0x48, 0x8b, 0x1e, 0x0d, 0x7a, 0x10,
- 0x17, 0xf6, 0x4e, 0x39, 0xbe, 0x8e, 0xbf, 0xf8, 0x7f, 0xdb, 0xce, 0xa4,
- 0x2d, 0xc2, 0x75, 0xff, 0xff, 0xfa, 0x5a, 0xd0, 0x23, 0xc8, 0x1c, 0x19,
- 0xbe, 0x0e, 0x72, 0x07, 0xdd, 0xcd, 0xa3, 0xaf, 0xfe, 0xde, 0x5a, 0xc5,
- 0xef, 0x1d, 0xec, 0x1d, 0x5b, 0xa3, 0x2b, 0x90, 0x85, 0xb6, 0x8e, 0xac,
- 0x4d, 0x20, 0x11, 0x87, 0xfd, 0x29, 0xbf, 0xb3, 0x79, 0x47, 0xf0, 0x75,
- 0xf8, 0x73, 0xaf, 0xe3, 0xad, 0x1b, 0x9e, 0x92, 0xcb, 0x6f, 0xbe, 0x36,
- 0x76, 0x4e, 0xbf, 0x4f, 0xf0, 0x11, 0x31, 0xd7, 0xff, 0xfc, 0x31, 0xfe,
- 0xf2, 0xd0, 0x23, 0xc3, 0x81, 0x4c, 0xe4, 0xc7, 0x53, 0xa2, 0x47, 0xc5,
- 0x75, 0x0b, 0x9e, 0x81, 0x30, 0x42, 0xd9, 0x89, 0x7a, 0xda, 0xf0, 0xd1,
- 0x13, 0x4d, 0x46, 0xea, 0x08, 0x45, 0x6c, 0x28, 0xfb, 0x0b, 0x7b, 0xf4,
- 0x93, 0x99, 0xb9, 0xd7, 0xb5, 0xdc, 0x3a, 0xfd, 0x9a, 0x9f, 0x19, 0x3a,
- 0xb7, 0x3e, 0xa9, 0x89, 0xfa, 0x37, 0x7f, 0xfd, 0x3e, 0x34, 0x3d, 0x4c,
- 0x53, 0xe2, 0x80, 0x83, 0xaf, 0xfb, 0xe7, 0xdf, 0x26, 0xc8, 0x16, 0x9d,
- 0x48, 0x89, 0x0e, 0xa9, 0xdf, 0xfe, 0x8d, 0xe5, 0xaf, 0x3c, 0xfb, 0x43,
- 0x9b, 0x9d, 0x7f, 0xdd, 0x9d, 0x30, 0x77, 0x96, 0x8e, 0xbf, 0xed, 0xfb,
- 0x8d, 0x1c, 0x02, 0xb9, 0xd6, 0x94, 0x1f, 0xa6, 0x1c, 0xdf, 0xc9, 0xbf,
- 0xfc, 0x70, 0x9d, 0x7e, 0xc4, 0xce, 0x7e, 0x75, 0x74, 0xf5, 0x04, 0xba,
- 0xfb, 0x6b, 0xd9, 0xd3, 0xae, 0x45, 0x9d, 0x7f, 0xff, 0xed, 0xe4, 0xfb,
- 0xfc, 0x10, 0x6d, 0x7c, 0xcd, 0xe5, 0x80, 0x1f, 0xf4, 0x75, 0x2d, 0x11,
- 0x7b, 0x42, 0xb7, 0xb6, 0xd1, 0x52, 0x75, 0x7c, 0x4c, 0x62, 0x72, 0x1c,
- 0x85, 0x7e, 0xd9, 0x35, 0xff, 0xff, 0xfa, 0x37, 0xd0, 0x23, 0x7f, 0x9d,
- 0xc0, 0xfc, 0x1c, 0x02, 0x9f, 0x35, 0xff, 0xe9, 0xe3, 0xaf, 0xd0, 0x3b,
- 0xbc, 0xe7, 0x5f, 0xff, 0xff, 0xfb, 0x1b, 0x1d, 0x85, 0xfb, 0x35, 0xa8,
- 0xe7, 0x20, 0x72, 0x7c, 0x06, 0x81, 0x30, 0xc2, 0xce, 0xbc, 0x0e, 0x28,
- 0x75, 0x2d, 0x16, 0x9b, 0x70, 0x97, 0xbf, 0x3f, 0xff, 0x5e, 0x73, 0xab,
- 0x0f, 0x55, 0x0a, 0xef, 0x27, 0xf0, 0x75, 0xfc, 0x11, 0xce, 0xbf, 0x8e,
- 0xbf, 0x7b, 0x79, 0x27, 0x0e, 0xac, 0x3d, 0x3d, 0x15, 0xd4, 0xe8, 0x8f,
- 0xfd, 0xba, 0xff, 0x4e, 0x08, 0xf2, 0xd3, 0xc7, 0x5f, 0xfa, 0x14, 0xda,
- 0x06, 0x0c, 0xdf, 0x56, 0x75, 0x61, 0xfb, 0xee, 0x67, 0x7f, 0xec, 0xcf,
- 0xf5, 0xf3, 0x9a, 0x0e, 0x8e, 0xbf, 0xdc, 0xc6, 0xf5, 0x39, 0x31, 0xd7,
- 0x67, 0x82, 0x7e, 0x98, 0x83, 0x7d, 0x3a, 0x0f, 0x8e, 0xbf, 0x67, 0x7a,
- 0xf2, 0x3a, 0xfe, 0xf2, 0x72, 0x7c, 0x69, 0xd5, 0x0b, 0xf7, 0xb9, 0x0c,
- 0x15, 0x08, 0xb7, 0x86, 0x12, 0x47, 0x25, 0xc4, 0x85, 0xc2, 0x37, 0xb1,
- 0x98, 0x3c, 0x2b, 0xc6, 0x13, 0x9a, 0x84, 0xb0, 0x0b, 0x36, 0xc8, 0x76,
- 0x89, 0xaf, 0x3b, 0x70, 0xeb, 0xff, 0x4d, 0xf3, 0xc3, 0x8c, 0xe2, 0x68,
- 0xea, 0x55, 0x1e, 0xd4, 0x0d, 0x51, 0xd7, 0xf6, 0x2e, 0x3a, 0xfd, 0x3a,
- 0xef, 0x93, 0x1d, 0x5f, 0x0f, 0x10, 0x25, 0x77, 0xff, 0xdb, 0xc8, 0x63,
- 0xe2, 0xc6, 0x14, 0xf2, 0x4e, 0x75, 0x42, 0x31, 0x31, 0x39, 0x09, 0x2f,
- 0xdc, 0xf8, 0x3b, 0x19, 0x3a, 0xfb, 0xaf, 0xfc, 0x1d, 0x7b, 0xb9, 0xc3,
- 0xaa, 0x0f, 0xa1, 0xcb, 0x36, 0x88, 0x6f, 0xe9, 0xe6, 0x92, 0xab, 0x93,
- 0x9d, 0x7e, 0x5a, 0x07, 0x02, 0x75, 0xa6, 0x3a, 0xe8, 0x59, 0xd6, 0xf1,
- 0xd5, 0xc3, 0x4a, 0xe2, 0xb4, 0x13, 0xd6, 0xe9, 0xb5, 0xee, 0x44, 0xc7,
- 0x5e, 0xd3, 0xee, 0x75, 0x39, 0xb8, 0xf0, 0xe5, 0xd3, 0x39, 0xd7, 0xf3,
- 0xb3, 0x1e, 0xc9, 0xce, 0xbf, 0x93, 0x9b, 0xc8, 0x60, 0xeb, 0xfc, 0x1e,
- 0xc6, 0xf2, 0xcf, 0x1d, 0x5d, 0x3d, 0xff, 0x16, 0x52, 0xb2, 0x9f, 0x7c,
- 0x1a, 0xe3, 0xe2, 0x2d, 0x2c, 0x80, 0x45, 0x81, 0x08, 0xcb, 0xfc, 0xce,
- 0x48, 0x40, 0xfa, 0x3a, 0xfd, 0xbb, 0x2e, 0x3f, 0x9d, 0x70, 0xa8, 0x75,
- 0xb4, 0x86, 0xfc, 0x05, 0x37, 0xff, 0xf4, 0x2c, 0x71, 0xbb, 0xf8, 0x5f,
- 0xab, 0x8c, 0xf1, 0xd7, 0xff, 0xe8, 0xe4, 0x37, 0x17, 0x0d, 0x92, 0x68,
- 0x0b, 0x3a, 0xa1, 0x34, 0x29, 0x9c, 0x7a, 0x4d, 0xb6, 0xb1, 0x7f, 0x73,
- 0x21, 0x48, 0x13, 0xaf, 0x0b, 0xac, 0xeb, 0xbf, 0x83, 0xaa, 0x47, 0xb6,
- 0x85, 0x62, 0x35, 0x4a, 0xcb, 0xf0, 0x0c, 0x2b, 0x6e, 0xca, 0xa8, 0xfb,
- 0x95, 0xa2, 0xcc, 0x4b, 0x87, 0x9e, 0x3a, 0x09, 0x42, 0x08, 0x33, 0x95,
- 0x79, 0x4b, 0x6e, 0x52, 0x52, 0xbb, 0x67, 0x77, 0x77, 0x97, 0xac, 0x92,
- 0x8b, 0x26, 0x94, 0xe9, 0xc9, 0xc1, 0x55, 0xcb, 0x2c, 0xed, 0x38, 0x09,
- 0xe5, 0x09, 0x7f, 0x0c, 0x61, 0xa4, 0xa4, 0xea, 0x75, 0x5f, 0xd4, 0x8d,
- 0x80, 0x46, 0x93, 0xb2, 0x1d, 0x2c, 0xc2, 0x57, 0x6e, 0x50, 0xff, 0xd8,
- 0xeb, 0x76, 0xa1, 0x39, 0x7f, 0xff, 0x01, 0xac, 0x6f, 0xee, 0x46, 0x6e,
- 0xaa, 0x0b, 0xba, 0x87, 0x53, 0x0a, 0xaa, 0x92, 0x52, 0x45, 0xfe, 0x57,
- 0x74, 0xf6, 0x90, 0x4e, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x53, 0xb7, 0x66,
- 0xe7, 0x5f, 0xfe, 0x00, 0x05, 0x06, 0x3a, 0x8b, 0xcd, 0x1d, 0x66, 0x21,
- 0x18, 0x58, 0x67, 0xb9, 0x9a, 0xc5, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x15,
- 0x1d, 0xff, 0x9e, 0x4c, 0x67, 0x1a, 0xee, 0xd3, 0x44, 0xd1, 0x7c, 0x31,
- 0x9b, 0x9d, 0x58, 0x89, 0xd5, 0x99, 0xf9, 0x2a, 0xff, 0x7d, 0x7d, 0x8c,
- 0x79, 0x27, 0x3a, 0x98, 0x3e, 0x78, 0x2f, 0xbf, 0x71, 0xae, 0xed, 0x34,
- 0x55, 0xf7, 0xf6, 0x6c, 0x81, 0xe8, 0x0e, 0xb3, 0x18, 0x7c, 0x1c, 0x33,
- 0xbf, 0x71, 0xae, 0xed, 0x34, 0x56, 0xd7, 0xfd, 0x26, 0x33, 0x8d, 0x77,
- 0x69, 0xa2, 0x41, 0xb3, 0x18, 0x7f, 0x0e, 0x67, 0x7f, 0xf3, 0x0f, 0x26,
- 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x43, 0xbf, 0xf6, 0x98, 0xcf, 0x20, 0x70,
- 0x66, 0x3a, 0xf3, 0xbb, 0x4f, 0x18, 0x1d, 0x41, 0xf2, 0xb4, 0xfa, 0xee,
- 0xab, 0x9d, 0x7f, 0xe9, 0x76, 0x3d, 0xa5, 0x63, 0x4a, 0xd8, 0x9d, 0x7f,
- 0xf9, 0x57, 0x2a, 0xe5, 0x63, 0xb0, 0xb1, 0x7e, 0xa7, 0x0e, 0xb6, 0xe7,
- 0x5c, 0x82, 0x75, 0xfd, 0x01, 0x8f, 0x38, 0x4e, 0xa0, 0x9e, 0x84, 0xc2,
- 0x3e, 0x14, 0xbf, 0xf9, 0x06, 0x78, 0x53, 0xef, 0xff, 0xc6, 0xe7, 0x5f,
- 0xb3, 0x07, 0xfd, 0x1d, 0x7e, 0x70, 0xfd, 0x81, 0x3a, 0xff, 0xdc, 0xf7,
- 0xd1, 0x76, 0xe0, 0xb4, 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x62, 0x5e, 0x00,
- 0xc8, 0xeb, 0xfc, 0xd8, 0xce, 0x7f, 0xff, 0x8e, 0xa9, 0xd1, 0xc3, 0x84,
- 0xfc, 0x3e, 0xf1, 0x68, 0x06, 0xef, 0xd9, 0xc8, 0x15, 0x0e, 0xbf, 0x7d,
- 0xdb, 0xce, 0x41, 0xd7, 0xb5, 0x02, 0x75, 0xbb, 0x07, 0x8a, 0x85, 0x77,
- 0xff, 0x46, 0x6b, 0x04, 0x29, 0xfc, 0x09, 0xd7, 0x86, 0x27, 0x3a, 0x84,
- 0xf6, 0xc0, 0x81, 0x7d, 0x1c, 0x85, 0x9d, 0x52, 0x3c, 0x1d, 0x10, 0xde,
- 0x5b, 0xf8, 0xeb, 0x93, 0xf3, 0xab, 0x86, 0xc7, 0x6c, 0x6e, 0xfc, 0x9b,
- 0x00, 0xfa, 0x3a, 0xff, 0x83, 0xdc, 0x5e, 0x3f, 0x27, 0x3a, 0xfd, 0xef,
- 0x3c, 0xb4, 0x75, 0xff, 0x81, 0x9b, 0x87, 0x67, 0x71, 0xe6, 0x3a, 0xb7,
- 0x3e, 0x8d, 0x84, 0xf6, 0x91, 0xd7, 0xd9, 0x8c, 0xe8, 0xea, 0x83, 0x63,
- 0xe1, 0x0b, 0x80, 0x27, 0x54, 0x26, 0x57, 0x90, 0xa0, 0xe2, 0xb6, 0x88,
- 0x2f, 0xfa, 0x35, 0xf7, 0x39, 0x99, 0x31, 0xd7, 0xf7, 0x25, 0xfe, 0x64,
- 0xc7, 0x5f, 0x3c, 0x26, 0xd9, 0xd5, 0x87, 0xa1, 0xc2, 0xeb, 0xe9, 0x7d,
- 0xec, 0x1d, 0x7b, 0x91, 0x23, 0xa9, 0xcd, 0xf6, 0xc2, 0x3b, 0xfa, 0x17,
- 0x89, 0xc9, 0x8e, 0xbe, 0xfb, 0x1b, 0x5a, 0x3a, 0xfd, 0x81, 0xec, 0x74,
- 0xeb, 0xee, 0x23, 0x2a, 0xe7, 0x50, 0x9e, 0x5e, 0x89, 0xa8, 0x28, 0x92,
- 0xd3, 0x8d, 0x42, 0x6c, 0x48, 0xbf, 0xd2, 0x27, 0x85, 0xf5, 0xfc, 0x82,
- 0xeb, 0x8e, 0x9d, 0x7f, 0xfa, 0x17, 0x12, 0x08, 0xc7, 0x5f, 0x38, 0x75,
- 0x1d, 0x52, 0x3d, 0x0d, 0xb4, 0x6b, 0xde, 0xcf, 0xce, 0xbf, 0x96, 0x9a,
- 0xd2, 0x04, 0xeb, 0xcf, 0xc5, 0x0e, 0xa0, 0x1e, 0x43, 0x25, 0x97, 0xf9,
- 0xa3, 0x9b, 0x07, 0x34, 0x75, 0xff, 0x6f, 0x27, 0xc1, 0xcf, 0x68, 0xeb,
- 0xff, 0x66, 0xf2, 0xec, 0x69, 0x4e, 0xc1, 0xd5, 0x24, 0xf3, 0xb7, 0x7a,
- 0x98, 0x97, 0x8c, 0x9d, 0x23, 0x13, 0x2d, 0xa3, 0x7b, 0x6d, 0x9d, 0x74,
- 0xb4, 0x75, 0x9e, 0x46, 0xa7, 0x71, 0x3b, 0xef, 0x20, 0xb2, 0x55, 0x80,
- 0x75, 0xa3, 0x0d, 0x8f, 0x48, 0x6f, 0xf9, 0xc7, 0xda, 0xdf, 0x4e, 0xae,
- 0x75, 0x3a, 0x2e, 0x3f, 0x58, 0x01, 0x2d, 0xfd, 0xd4, 0xd7, 0x39, 0x87,
- 0x5f, 0xfa, 0x19, 0xfb, 0x3e, 0xb1, 0x70, 0xae, 0x75, 0xce, 0xc9, 0xd6,
- 0xc6, 0xa2, 0x1b, 0xc5, 0x9b, 0x11, 0x2f, 0xfe, 0xeb, 0xa7, 0xa5, 0x8a,
- 0x0e, 0x7e, 0x75, 0xf8, 0x66, 0x8e, 0xc1, 0xd7, 0xec, 0xee, 0xee, 0xae,
- 0x75, 0xf7, 0xfa, 0x81, 0x3a, 0xff, 0x73, 0xae, 0x9a, 0x4d, 0x87, 0x54,
- 0x1e, 0xa6, 0x10, 0xd2, 0x26, 0x0e, 0xe8, 0x62, 0x4d, 0xa7, 0xeb, 0xf9,
- 0x98, 0xe7, 0x1e, 0x63, 0xaf, 0xf8, 0x30, 0xdf, 0xbf, 0xff, 0x1b, 0x9d,
- 0x7f, 0xcf, 0xcc, 0x5a, 0x6d, 0xc2, 0xce, 0xa6, 0x9f, 0xb0, 0x0f, 0x6f,
- 0xbd, 0x1b, 0xc8, 0xeb, 0xf9, 0x3f, 0xdb, 0x14, 0xfc, 0xea, 0x9c, 0xf4,
- 0xb8, 0x45, 0x50, 0x99, 0xde, 0x42, 0x91, 0xdd, 0x2f, 0xed, 0x9c, 0x78,
- 0x4d, 0xb3, 0xad, 0x87, 0x52, 0xcd, 0xf8, 0x98, 0x5f, 0xfb, 0xb8, 0x10,
- 0xa6, 0xf9, 0xbf, 0x8e, 0xbf, 0xbe, 0x07, 0xeb, 0xf3, 0x87, 0x54, 0xe7,
- 0xe0, 0x13, 0xfb, 0xe7, 0x84, 0xdb, 0x3a, 0xff, 0xa1, 0x03, 0xe1, 0x7d,
- 0xf4, 0x75, 0x41, 0xfe, 0x04, 0x8c, 0x48, 0xa9, 0x58, 0x6c, 0x19, 0x15,
- 0xb1, 0x95, 0x6a, 0x91, 0x10, 0xa9, 0x91, 0x80, 0x52, 0x72, 0x30, 0x75,
- 0x12, 0x9a, 0xd7, 0xbc, 0x30, 0x91, 0x4e, 0x62, 0x4e, 0x46, 0xa6, 0xb4,
- 0x1e, 0xc7, 0xd6, 0xf2, 0x83, 0xbf, 0x8d, 0x28, 0x61, 0x6d, 0xa8, 0xcf,
- 0xbd, 0x1b, 0xb0, 0x1c, 0xbe, 0xc6, 0x19, 0x7f, 0xf7, 0x52, 0x3d, 0xd7,
- 0x53, 0x07, 0xf3, 0xaf, 0xec, 0xf4, 0x22, 0xf4, 0x75, 0xfe, 0x0c, 0x4b,
- 0x39, 0x9a, 0x3a, 0xf6, 0xbe, 0xe8, 0xeb, 0xff, 0xec, 0xde, 0x5e, 0x04,
- 0xec, 0x75, 0xd6, 0x9a, 0x3a, 0xff, 0x80, 0xf8, 0x14, 0xdc, 0x5c, 0xeb,
- 0xde, 0x18, 0x3a, 0xee, 0xb1, 0x89, 0xaf, 0xcc, 0x86, 0xb2, 0xb7, 0x31,
- 0x11, 0xed, 0x29, 0x7d, 0x36, 0xa6, 0x15, 0xa7, 0x44, 0xad, 0xcb, 0xfb,
- 0x38, 0xd7, 0x76, 0x9a, 0x2c, 0xdb, 0xff, 0x47, 0x3f, 0xf6, 0xbb, 0x88,
- 0x13, 0xaf, 0x90, 0x5e, 0x73, 0xab, 0xa7, 0xbd, 0xa3, 0xeb, 0xe6, 0x3b,
- 0x1d, 0x3a, 0x98, 0x3c, 0x4d, 0xa2, 0x2a, 0x61, 0x30, 0x07, 0x86, 0xd5,
- 0xfe, 0x5b, 0x10, 0x8b, 0xfb, 0xc3, 0xae, 0xc0, 0x9d, 0x7f, 0xe7, 0x93,
- 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x40, 0x5f, 0xe4, 0x5c, 0x2b, 0xf7, 0x27,
- 0x3a, 0xcc, 0x62, 0x25, 0x16, 0x2b, 0xd4, 0xab, 0xf9, 0xfd, 0xa9, 0x27,
- 0xe7, 0x5f, 0xd2, 0x63, 0x26, 0x89, 0x1d, 0x4c, 0x1e, 0xdc, 0x16, 0xdc,
- 0x0e, 0x9d, 0x7f, 0x6a, 0x16, 0x31, 0x31, 0xd6, 0xe9, 0xd7, 0xbe, 0x8c,
- 0xc7, 0x5d, 0x9e, 0xc3, 0x5d, 0xf8, 0x85, 0x7e, 0x88, 0x61, 0x5a, 0xbb,
- 0xe6, 0x8e, 0xbc, 0x00, 0xe1, 0xd7, 0xfb, 0x39, 0xe1, 0x85, 0xe8, 0xeb,
- 0x6d, 0x9d, 0x48, 0x7b, 0xfd, 0x1b, 0xfc, 0xc6, 0xf9, 0xae, 0xed, 0x34,
- 0x5b, 0xf7, 0xb6, 0xdf, 0xc7, 0x5f, 0xdf, 0x7c, 0xed, 0x7e, 0x1d, 0x5c,
- 0x3f, 0x95, 0x96, 0xfe, 0x3d, 0x7d, 0x82, 0x93, 0x1d, 0x7e, 0xf4, 0xb5,
- 0xf7, 0x47, 0x5e, 0xd7, 0x42, 0x75, 0xfb, 0xef, 0x86, 0x3f, 0x3a, 0x96,
- 0x78, 0xbb, 0x07, 0x2f, 0xfe, 0xf6, 0x93, 0x50, 0x39, 0xee, 0xa1, 0xd7,
- 0x87, 0x3a, 0x75, 0x2c, 0xf6, 0xf6, 0x20, 0xdf, 0x83, 0x0a, 0xe0, 0x59,
- 0xd7, 0xfc, 0xfa, 0x8c, 0x10, 0xf6, 0x0e, 0xbf, 0xfb, 0x17, 0xcc, 0xdf,
- 0xa2, 0xea, 0xf3, 0x9d, 0x76, 0xb5, 0xc3, 0xfc, 0x13, 0x5a, 0x84, 0xdd,
- 0xb1, 0xfd, 0x09, 0x1e, 0x14, 0xd7, 0xce, 0x83, 0xe3, 0xaf, 0x72, 0x3c,
- 0x75, 0xfd, 0x33, 0x87, 0xa8, 0xb3, 0xaf, 0xef, 0x26, 0x06, 0x16, 0x75,
- 0x78, 0xf6, 0x19, 0x2d, 0xbb, 0x42, 0x75, 0xfd, 0xbe, 0xa1, 0xb8, 0xb3,
- 0xab, 0x88, 0xd8, 0x77, 0x3d, 0x11, 0x80, 0x56, 0xfb, 0xaa, 0x05, 0x67,
- 0x5d, 0x92, 0x3a, 0xb0, 0xdc, 0x09, 0x1d, 0x2b, 0x6b, 0xbb, 0x91, 0x09,
- 0xc9, 0x11, 0x85, 0xdf, 0x21, 0x50, 0x86, 0x1c, 0x20, 0xec, 0x7c, 0xbf,
- 0x9f, 0x8c, 0x3d, 0xfc, 0xe9, 0x7f, 0x3e, 0xec, 0x2d, 0xfc, 0x75, 0x30,
- 0x8e, 0x01, 0x85, 0x95, 0xfc, 0x16, 0x35, 0xed, 0x6e, 0x75, 0xca, 0xca,
- 0xb6, 0x75, 0xe5, 0xbe, 0xe7, 0x5d, 0xb1, 0x0e, 0xbe, 0xe7, 0x33, 0xe9,
- 0xd7, 0xed, 0x4f, 0x8c, 0xb0, 0xac, 0x1f, 0xb4, 0x10, 0x4c, 0x38, 0xe2,
- 0xf5, 0x09, 0x83, 0x24, 0x29, 0xaf, 0xff, 0xff, 0x23, 0x5f, 0x8f, 0xd9,
- 0x67, 0xb0, 0x3a, 0x75, 0xe7, 0x27, 0x8d, 0xce, 0xbf, 0x71, 0xae, 0xed,
- 0x34, 0x52, 0x97, 0xff, 0xcf, 0xe1, 0xc9, 0xf9, 0x1d, 0x4e, 0xe7, 0x0e,
- 0xbc, 0xf2, 0x62, 0x11, 0xed, 0x8e, 0xdf, 0x99, 0xdf, 0xf4, 0x98, 0xce,
- 0x35, 0xdd, 0xa6, 0x89, 0x3a, 0xcc, 0x2d, 0x10, 0xce, 0x83, 0x51, 0x08,
- 0xd0, 0x09, 0xe7, 0x05, 0x25, 0x1b, 0xd0, 0x6f, 0x8b, 0x93, 0x21, 0xdc,
- 0xd8, 0xd1, 0xd2, 0x10, 0x4a, 0xf0, 0xa0, 0x98, 0x9f, 0x90, 0xb6, 0x5d,
- 0x67, 0xa7, 0xd8, 0xcb, 0x1c, 0xa7, 0xf8, 0x64, 0x8c, 0x24, 0x75, 0x3d,
- 0xbd, 0xe8, 0xcb, 0xb6, 0x47, 0x47, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x87,
- 0xef, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x25, 0x3b, 0x31, 0x87,
- 0xfa, 0xb3, 0x3b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x44, 0xf7, 0xf4,
- 0xc9, 0xed, 0x01, 0x67, 0x5f, 0xfe, 0x55, 0x94, 0x65, 0x5e, 0x70, 0xaa,
- 0xbe, 0x7c, 0xee, 0xd9, 0xd7, 0xee, 0x35, 0xdd, 0xa6, 0x88, 0xc6, 0xff,
- 0xfd, 0xfc, 0xa7, 0x55, 0xa1, 0x5b, 0x9d, 0xbc, 0xf9, 0xf3, 0xbb, 0x67,
- 0x5f, 0x26, 0xf2, 0x56, 0xce, 0xb3, 0x10, 0x9a, 0xac, 0x8b, 0xb1, 0x8b,
- 0xa6, 0x7e, 0x6b, 0xbf, 0xfc, 0xc2, 0xde, 0x4c, 0x67, 0x1a, 0xee, 0xd3,
- 0x44, 0xf3, 0x7f, 0x31, 0xfc, 0x0c, 0xb4, 0x75, 0x42, 0xa9, 0x19, 0xca,
- 0x25, 0x1c, 0xa7, 0x54, 0x3c, 0xaf, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x88,
- 0x2f, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x25, 0x4b, 0x31, 0x87,
- 0xfa, 0xb3, 0x3b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x45, 0x17, 0xf9,
- 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x8c, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x13,
- 0x2d, 0xfa, 0x59, 0xe7, 0x69, 0xd7, 0xe6, 0x16, 0xf2, 0x63, 0x0f, 0x67,
- 0x73, 0x3b, 0xf7, 0x1a, 0xee, 0xd3, 0x45, 0x49, 0x61, 0x3a, 0xdf, 0x4e,
- 0xb3, 0x18, 0x7a, 0x8a, 0xe6, 0x60, 0x0f, 0xbf, 0xcc, 0x67, 0x1a, 0xee,
- 0xd3, 0x45, 0x75, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0x16, 0xff,
- 0xe5, 0xbc, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89, 0xea, 0xff, 0x99, 0x61,
- 0xe1, 0x36, 0xd3, 0x68, 0xeb, 0xff, 0xf4, 0xc3, 0x0b, 0x63, 0x34, 0x8c,
- 0x85, 0xdd, 0x43, 0xae, 0xd7, 0x8e, 0xbf, 0x0b, 0xac, 0x60, 0xeb, 0xf8,
- 0x1a, 0xeb, 0xc9, 0x85, 0x6c, 0xdd, 0x7d, 0x16, 0xbf, 0x67, 0xb4, 0x8b,
- 0x3a, 0xff, 0xf4, 0x6f, 0xec, 0x99, 0x39, 0xed, 0x01, 0x5c, 0xeb, 0xcf,
- 0xbb, 0x02, 0x7e, 0x9e, 0x26, 0xb7, 0xb1, 0x38, 0x4e, 0x42, 0x43, 0x50,
- 0xc0, 0xa6, 0x15, 0x29, 0x42, 0x82, 0x47, 0x85, 0x7e, 0x4e, 0x8b, 0xcc,
- 0x75, 0xfa, 0x58, 0x1f, 0x98, 0x75, 0x2a, 0x0f, 0x3a, 0x09, 0xaf, 0xd9,
- 0xe4, 0x06, 0x8e, 0xb9, 0x58, 0x56, 0xa7, 0x52, 0xb5, 0x3c, 0x75, 0x58,
- 0x9a, 0xfc, 0xab, 0x95, 0x8d, 0x73, 0xc7, 0x5f, 0xef, 0xa3, 0x9c, 0xe4,
- 0x34, 0xea, 0x56, 0x0f, 0x99, 0x54, 0x67, 0x7d, 0xc5, 0xfb, 0x73, 0xaf,
- 0xe5, 0x61, 0x59, 0x54, 0x44, 0x96, 0x75, 0xe6, 0xe7, 0x4a, 0xbc, 0xb8,
- 0xd1, 0xd7, 0xbf, 0xe4, 0x1d, 0x7f, 0x67, 0xe9, 0x32, 0x32, 0x75, 0xff,
- 0x9f, 0x5f, 0x35, 0xac, 0x94, 0xa0, 0xeb, 0xff, 0xf0, 0xba, 0x89, 0xc8,
- 0x94, 0xb3, 0x5f, 0xff, 0x07, 0x50, 0x51, 0x84, 0xa1, 0x77, 0x4f, 0xef,
- 0xff, 0xee, 0x26, 0xd3, 0xad, 0x88, 0xe7, 0x13, 0x69, 0xa0, 0x9c, 0xeb,
- 0xe4, 0xef, 0xd5, 0x9d, 0x7f, 0xf9, 0x14, 0xf9, 0x82, 0xfb, 0xe9, 0x45,
- 0x1c, 0xea, 0x69, 0xf8, 0x09, 0x1d, 0xff, 0xe7, 0xd0, 0xe7, 0xec, 0x75,
- 0x1a, 0xfc, 0x3a, 0xfe, 0x0e, 0x29, 0xec, 0x69, 0xd7, 0xdd, 0x85, 0xb4,
- 0xea, 0x73, 0xce, 0xf1, 0x6d, 0xf8, 0x29, 0x32, 0x32, 0x75, 0xff, 0xdf,
- 0x22, 0x06, 0x17, 0xf3, 0xe7, 0x76, 0xce, 0xa8, 0x3f, 0x31, 0x28, 0xbf,
- 0xf7, 0x72, 0x6e, 0xa7, 0x63, 0x90, 0x75, 0xcf, 0xb9, 0xd7, 0xf9, 0xf4,
- 0xfd, 0x00, 0xce, 0x75, 0x09, 0xe4, 0x00, 0x5a, 0xa7, 0x5c, 0x0e, 0x90,
- 0xda, 0x43, 0x7b, 0x86, 0x2b, 0x86, 0x97, 0x48, 0x46, 0x12, 0xfe, 0x84,
- 0xa7, 0xd2, 0x0d, 0xa8, 0x42, 0xde, 0x17, 0xf1, 0xd7, 0x85, 0x34, 0x75,
- 0x99, 0x54, 0x1b, 0x48, 0x1a, 0xbe, 0xe6, 0xc7, 0x59, 0xd7, 0xe5, 0x8b,
- 0xfb, 0x47, 0x5e, 0x8c, 0xe1, 0xd7, 0xff, 0x9a, 0xfc, 0x7f, 0x26, 0xa0,
- 0x63, 0xf3, 0xad, 0x2e, 0x9f, 0x0f, 0xd1, 0xaa, 0xdd, 0x16, 0x3c, 0x84,
- 0x3d, 0x62, 0x65, 0x08, 0x56, 0x08, 0x6a, 0x5e, 0xd6, 0xd6, 0xd1, 0xd7,
- 0xfd, 0xd7, 0xf4, 0x4d, 0xa4, 0x59, 0xd7, 0xfa, 0x24, 0x39, 0xbf, 0xb0,
- 0xeb, 0xdd, 0x02, 0xce, 0xac, 0x45, 0x3a, 0x11, 0x70, 0xe0, 0x06, 0x37,
- 0xf7, 0xb5, 0x34, 0x0c, 0xe7, 0x5f, 0x85, 0x44, 0xcd, 0x1d, 0x7e, 0x65,
- 0xfc, 0xed, 0x3a, 0xff, 0xec, 0x65, 0xff, 0xc6, 0xf5, 0xff, 0xd1, 0xd7,
- 0xfe, 0xd3, 0xef, 0x02, 0xe1, 0xc5, 0x0e, 0xa4, 0x46, 0x7f, 0x49, 0x84,
- 0x9f, 0xc8, 0xb7, 0x47, 0x4e, 0xb0, 0x4e, 0xa5, 0x9a, 0x51, 0x15, 0xbe,
- 0x10, 0xfc, 0x50, 0xeb, 0xfb, 0x34, 0xcb, 0x8c, 0xe7, 0x56, 0x1f, 0x8b,
- 0x90, 0x09, 0x25, 0xf8, 0x0a, 0x68, 0x30, 0x75, 0xe5, 0xa6, 0x8e, 0xbf,
- 0xa3, 0x79, 0x69, 0x04, 0xea, 0x85, 0x4d, 0x39, 0x0f, 0xd4, 0x86, 0x8f,
- 0x4b, 0x1c, 0xa0, 0x46, 0xef, 0xff, 0x28, 0xf9, 0xbf, 0xbd, 0x19, 0xb1,
- 0x1a, 0x75, 0xfe, 0x1c, 0xd7, 0x9d, 0xc4, 0xea, 0x50, 0xfe, 0xb6, 0x25,
- 0xdf, 0xff, 0xf9, 0x39, 0xc8, 0xfb, 0xe4, 0x10, 0x4b, 0x34, 0x10, 0x3f,
- 0x24, 0x75, 0xff, 0xfc, 0x38, 0xa6, 0x0f, 0xcd, 0x7b, 0xb8, 0xbf, 0xb1,
- 0xf9, 0xd5, 0x08, 0xca, 0xc6, 0xcb, 0xfc, 0x07, 0xd2, 0x4c, 0x8c, 0x9d,
- 0x48, 0x9a, 0x1f, 0x61, 0xde, 0x24, 0x37, 0xbb, 0x02, 0x75, 0xed, 0xfc,
- 0xb3, 0xa9, 0xa6, 0xdd, 0xc6, 0xaf, 0xd3, 0x87, 0x88, 0xc9, 0xd7, 0xfb,
- 0xeb, 0xec, 0x49, 0x91, 0x93, 0xaf, 0xfe, 0x41, 0xc0, 0x72, 0x75, 0xc6,
- 0x78, 0xea, 0x83, 0xf9, 0x09, 0xbd, 0xfc, 0x17, 0xe7, 0xfb, 0x78, 0x75,
- 0xee, 0xfd, 0xd8, 0x75, 0xff, 0x42, 0xc7, 0x1b, 0xc4, 0xfc, 0xea, 0x91,
- 0xeb, 0xe8, 0x82, 0xff, 0xa2, 0x58, 0x9a, 0xd0, 0x20, 0xeb, 0xff, 0x7a,
- 0x17, 0xbb, 0x53, 0x7c, 0xe1, 0xd7, 0xee, 0xe7, 0x13, 0x47, 0x5e, 0x14,
- 0x96, 0xe7, 0xcb, 0xe3, 0xfb, 0xff, 0x3e, 0x7f, 0x02, 0xe1, 0xc5, 0x0e,
- 0xa9, 0xd3, 0x0a, 0x94, 0x26, 0xff, 0x33, 0xbf, 0xcf, 0xbe, 0xbd, 0xec,
- 0x57, 0x3a, 0xff, 0xf2, 0x73, 0xaf, 0x8d, 0x0e, 0x73, 0xf4, 0x3a, 0xfe,
- 0x53, 0xd1, 0x82, 0xd3, 0xaf, 0xff, 0x46, 0x6f, 0xee, 0xc7, 0x86, 0x3f,
- 0xd1, 0xd7, 0x47, 0xe7, 0x5d, 0xd5, 0x9d, 0x4d, 0x35, 0x9a, 0x16, 0xa4,
- 0x46, 0x17, 0x8b, 0x00, 0xeb, 0x7a, 0x74, 0xe1, 0xd7, 0xf0, 0x35, 0xed,
- 0x67, 0x8e, 0xbf, 0x80, 0xa9, 0x49, 0x91, 0x93, 0xae, 0xce, 0x9d, 0x79,
- 0x96, 0x59, 0x2a, 0xff, 0xf7, 0x93, 0xda, 0xea, 0x6d, 0xfd, 0xe4, 0x48,
- 0xa6, 0x0b, 0xfa, 0x51, 0x30, 0xd4, 0x1c, 0x72, 0xdf, 0x19, 0x00, 0xd2,
- 0xff, 0xff, 0x93, 0xd2, 0x81, 0xcf, 0x75, 0x33, 0xd0, 0xb4, 0xe4, 0x8e,
- 0xa9, 0x2f, 0x30, 0x85, 0xaf, 0x08, 0x1b, 0x0a, 0x24, 0x21, 0x9a, 0x10,
- 0xfc, 0x8c, 0xb1, 0x67, 0x1d, 0x36, 0x18, 0xc2, 0xbd, 0x19, 0xe6, 0xc4,
- 0xab, 0xfe, 0xde, 0x5a, 0xd6, 0x05, 0xfc, 0x75, 0xb0, 0xeb, 0xee, 0x0b,
- 0xec, 0x3a, 0xa0, 0xfa, 0x94, 0x39, 0x40, 0xfb, 0x39, 0xd7, 0xa3, 0xba,
- 0x3a, 0xb7, 0x35, 0x48, 0x1f, 0x7f, 0xff, 0x3f, 0x93, 0xae, 0xbf, 0x99,
- 0xa8, 0xce, 0x60, 0x9d, 0x7f, 0xf9, 0x1b, 0xa8, 0xdb, 0xcf, 0x4a, 0x59,
- 0xa3, 0xab, 0x88, 0xc4, 0x12, 0x1d, 0x8b, 0x17, 0xdc, 0xee, 0x09, 0xd4,
- 0x87, 0xa2, 0xe6, 0x37, 0xde, 0x8d, 0xd9, 0x3a, 0xba, 0x78, 0x6c, 0x90,
- 0x5c, 0xcf, 0x4e, 0xbf, 0xfd, 0x02, 0xdf, 0xbc, 0x7f, 0xd3, 0xdd, 0x83,
- 0xaf, 0xf2, 0x33, 0xac, 0xc1, 0x9c, 0xeb, 0xe8, 0xd4, 0x6c, 0x3a, 0xff,
- 0xe8, 0x17, 0xf4, 0xa1, 0x47, 0x67, 0xc7, 0x57, 0x4f, 0x94, 0x04, 0x57,
- 0xbe, 0x3b, 0x4e, 0xa6, 0xa6, 0x6f, 0xf8, 0xbe, 0x92, 0xbd, 0x09, 0x7d,
- 0xa2, 0x2b, 0xe5, 0xfd, 0x81, 0x3a, 0xf9, 0x03, 0x8b, 0x3a, 0xf9, 0xdc,
- 0x7f, 0x3a, 0xcc, 0xc1, 0xe0, 0x28, 0x41, 0x70, 0x16, 0x75, 0xfe, 0x65,
- 0xe6, 0xc9, 0x42, 0xb9, 0xd4, 0x87, 0xeb, 0xd2, 0x9d, 0x0b, 0x5f, 0xe8,
- 0x7e, 0x75, 0x97, 0x09, 0x57, 0x32, 0xc9, 0x54, 0x13, 0xca, 0x64, 0xca,
- 0xf7, 0x91, 0x5c, 0xa6, 0x0d, 0x1d, 0xfd, 0xbb, 0x53, 0x5d, 0x43, 0xaf,
- 0x81, 0x20, 0x78, 0xea, 0x44, 0xfc, 0x26, 0x86, 0xbe, 0xa1, 0x37, 0xe2,
- 0xfd, 0xb2, 0xdb, 0x99, 0xd1, 0xd6, 0xc3, 0xad, 0xbe, 0x1a, 0x6f, 0x0b,
- 0xdf, 0x6f, 0x25, 0x46, 0xe7, 0x5f, 0xfd, 0xad, 0x04, 0x60, 0x3d, 0x8f,
- 0x68, 0xea, 0x84, 0x49, 0x61, 0x38, 0x0a, 0x2f, 0xfd, 0xe4, 0xe3, 0xff,
- 0xb5, 0xec, 0xe9, 0xd7, 0xfc, 0x8c, 0x8e, 0x79, 0x01, 0xf9, 0xd7, 0xf9,
- 0xf9, 0xed, 0x0a, 0x28, 0x75, 0xff, 0xed, 0x62, 0x98, 0x0e, 0x38, 0x63,
- 0xb0, 0x75, 0x49, 0x32, 0x14, 0x2e, 0x57, 0x41, 0x73, 0x8d, 0x19, 0x5e,
- 0xc4, 0xe1, 0xd7, 0xfa, 0x48, 0xbe, 0xee, 0xea, 0xe7, 0x5f, 0x3f, 0x22,
- 0x47, 0x5f, 0xf3, 0xef, 0xf3, 0x7d, 0x60, 0xa8, 0x75, 0x4e, 0x8a, 0xcd,
- 0xc6, 0x96, 0x6d, 0xe2, 0x0b, 0xee, 0xab, 0xa2, 0xce, 0xbc, 0x31, 0xf9,
- 0xd7, 0xa1, 0x79, 0xf0, 0xdf, 0xe8, 0x92, 0xff, 0xd1, 0xbf, 0x61, 0x6d,
- 0xea, 0x4c, 0x75, 0x62, 0x3c, 0x11, 0xfb, 0x86, 0x77, 0xe6, 0xbc, 0xf8,
- 0xc9, 0xd7, 0xe8, 0xe0, 0x70, 0x4e, 0xa1, 0x3c, 0xdf, 0x14, 0x5f, 0xfd,
- 0x1f, 0xc7, 0x56, 0x2e, 0xa7, 0x50, 0xeb, 0x2a, 0x8e, 0xbf, 0xc1, 0xec,
- 0x0b, 0x2f, 0xb9, 0xd7, 0xff, 0x20, 0x7b, 0x0d, 0x8f, 0xdc, 0x7f, 0x3a,
- 0xff, 0xff, 0x96, 0xe3, 0xbc, 0x98, 0x67, 0x13, 0x66, 0x0e, 0x05, 0xe4,
- 0x78, 0xbd, 0x6f, 0xca, 0x79, 0xdc, 0x4e, 0xbc, 0x20, 0x9c, 0xea, 0x73,
- 0xc2, 0xf1, 0x35, 0x22, 0x35, 0xc6, 0x16, 0xd5, 0x09, 0xf5, 0xf0, 0x85,
- 0x68, 0x6e, 0x29, 0xa3, 0x30, 0x46, 0x35, 0x72, 0xb0, 0xad, 0x9d, 0x79,
- 0x23, 0x87, 0x52, 0xa8, 0xdd, 0x74, 0x82, 0xff, 0xee, 0x22, 0xe1, 0x5c,
- 0x71, 0x7b, 0xc1, 0xd5, 0x23, 0xea, 0x98, 0x96, 0xf9, 0x05, 0xc2, 0x75,
- 0xe9, 0xd6, 0x87, 0x50, 0x4d, 0xd8, 0x8f, 0xdf, 0xa5, 0x9b, 0x22, 0x47,
- 0x5e, 0xce, 0x41, 0xd5, 0xba, 0x30, 0x11, 0x7b, 0x84, 0x1d, 0x28, 0xbf,
- 0xfe, 0xcf, 0x6b, 0x26, 0xec, 0x6c, 0xce, 0xf6, 0x0e, 0xbf, 0xff, 0xff,
- 0x26, 0x6f, 0xa4, 0xc6, 0x7e, 0x66, 0xf2, 0xd2, 0x7b, 0x49, 0xb8, 0x42,
- 0x09, 0xce, 0xbf, 0xff, 0x20, 0x87, 0xe7, 0xdf, 0x26, 0x9d, 0x04, 0x12,
- 0x3a, 0x85, 0x32, 0xef, 0x28, 0x6c, 0x84, 0x45, 0xe0, 0x72, 0x47, 0x5f,
- 0xcf, 0xef, 0xfe, 0x8c, 0x8e, 0xaf, 0x87, 0x97, 0x38, 0xe5, 0xfe, 0x89,
- 0x23, 0x0c, 0xb2, 0xc9, 0x57, 0x94, 0xc0, 0x9d, 0x7f, 0x75, 0xf8, 0xd8,
- 0xf1, 0xd7, 0x38, 0x4e, 0xbf, 0xb8, 0xfa, 0xeb, 0xc8, 0xeb, 0x6e, 0x75,
- 0xc8, 0xc9, 0xd7, 0x7d, 0xfc, 0xea, 0x98, 0xd7, 0xfe, 0x2d, 0x7a, 0x4e,
- 0x13, 0xae, 0x65, 0x93, 0xaa, 0x48, 0xd7, 0xc1, 0x56, 0x96, 0x22, 0x06,
- 0x88, 0xd9, 0x1b, 0xbd, 0xef, 0xbf, 0x94, 0xc1, 0xeb, 0x5f, 0xf2, 0x07,
- 0x16, 0x93, 0x23, 0x27, 0x5f, 0xfe, 0x70, 0xe6, 0x0a, 0x9a, 0xd6, 0x0f,
- 0xe7, 0x5f, 0x74, 0x0e, 0xa4, 0x22, 0x01, 0x67, 0x17, 0xff, 0xf4, 0x9f,
- 0x5a, 0x8c, 0x9c, 0x12, 0x0f, 0x05, 0xd9, 0x3a, 0xef, 0x40, 0x51, 0x2a,
- 0x87, 0x57, 0xed, 0x3c, 0xfa, 0xe9, 0xd5, 0x25, 0x62, 0x01, 0x1c, 0xde,
- 0x35, 0x94, 0x8d, 0x1b, 0xc5, 0xb7, 0xed, 0x9f, 0x7a, 0x9e, 0x3a, 0xff,
- 0xb3, 0xdd, 0x8e, 0x7b, 0x1a, 0x75, 0xe8, 0xe4, 0xc7, 0x54, 0x2f, 0x17,
- 0x64, 0x6d, 0x69, 0x08, 0x2e, 0x92, 0xbc, 0xb4, 0x6f, 0xd6, 0x04, 0xaf,
- 0x6c, 0xde, 0xf6, 0x9e, 0x63, 0xaf, 0xfe, 0x40, 0xbf, 0x93, 0x59, 0x2c,
- 0xe9, 0xd7, 0x3e, 0xd1, 0xd6, 0xce, 0x9e, 0xcf, 0x90, 0x6b, 0x74, 0x4e,
- 0x0b, 0xad, 0xf6, 0x6f, 0x3e, 0xc3, 0xaf, 0xf8, 0x43, 0x82, 0x09, 0x66,
- 0x8e, 0xbf, 0xdf, 0x7c, 0x39, 0x3a, 0x70, 0xeb, 0xef, 0x26, 0x90, 0xea,
- 0xe2, 0x2b, 0xdc, 0x94, 0x4d, 0x80, 0x69, 0x7f, 0xdd, 0x40, 0xa2, 0xa6,
- 0x05, 0x0e, 0xbf, 0xcf, 0x2c, 0x0f, 0x35, 0xa3, 0xaf, 0xa3, 0x3e, 0x84,
- 0xeb, 0xfc, 0xa2, 0x79, 0xfa, 0xca, 0xb9, 0xd7, 0xfd, 0xcc, 0x9b, 0xb9,
- 0xa7, 0x13, 0xaf, 0xfb, 0xb9, 0x2c, 0x02, 0xa5, 0xc4, 0xeb, 0xff, 0xfc,
- 0x83, 0x9b, 0xf9, 0x47, 0xf7, 0x63, 0xb9, 0xb1, 0xe4, 0x75, 0x05, 0x35,
- 0xd6, 0x99, 0x21, 0x17, 0x0d, 0xfc, 0x6f, 0xb0, 0xea, 0xff, 0x82, 0x9c,
- 0x8d, 0x9f, 0xea, 0x47, 0x5d, 0x0b, 0x3a, 0xde, 0x83, 0xd0, 0xe9, 0xdd,
- 0xff, 0xa3, 0x4f, 0xd4, 0x0b, 0x52, 0x73, 0xaa, 0x15, 0x51, 0xe4, 0x72,
- 0xcf, 0x0a, 0x90, 0x13, 0xde, 0x81, 0xf1, 0xd7, 0xf9, 0x3a, 0x9c, 0x94,
- 0xd0, 0x75, 0xff, 0xf9, 0x00, 0xdf, 0xbb, 0xfe, 0xfa, 0x7e, 0x26, 0xff,
- 0x9d, 0x7c, 0xfc, 0x89, 0x1d, 0x7f, 0xff, 0x20, 0xba, 0x0f, 0xfc, 0x8e,
- 0xba, 0x7a, 0x3a, 0x75, 0x09, 0xfb, 0x78, 0x82, 0xfc, 0x9e, 0xd0, 0x27,
- 0x3a, 0xff, 0xfa, 0x05, 0x3f, 0xf6, 0xed, 0x4e, 0x7d, 0x80, 0x9d, 0x41,
- 0x4d, 0xa9, 0x21, 0xa0, 0xb2, 0x1f, 0x14, 0x5f, 0xb8, 0x06, 0xf6, 0x0e,
- 0xbf, 0xb9, 0x34, 0x93, 0xda, 0x3a, 0xc3, 0x07, 0xab, 0x84, 0xf7, 0xfa,
- 0x67, 0x99, 0xf7, 0x96, 0x8e, 0xbf, 0x9e, 0x74, 0x99, 0x19, 0x3a, 0xb0,
- 0xf8, 0xdc, 0xd6, 0xfe, 0x9f, 0x06, 0x7c, 0x64, 0xeb, 0xfe, 0x89, 0xfe,
- 0xcb, 0xa0, 0x79, 0xce, 0xac, 0x3e, 0xae, 0x17, 0x5f, 0xa3, 0x9c, 0xce,
- 0x9d, 0x7f, 0x0b, 0xa9, 0x0b, 0x83, 0xaa, 0x47, 0xa2, 0x02, 0x6b, 0xe8,
- 0x9d, 0x45, 0x0e, 0xbf, 0xff, 0x23, 0x61, 0x7a, 0x7e, 0x62, 0xc0, 0xd7,
- 0x91, 0xd7, 0x26, 0xc3, 0xad, 0xd3, 0xaa, 0x47, 0xf4, 0xae, 0xa6, 0x01,
- 0x7b, 0xc1, 0x85, 0x9d, 0x7f, 0xb3, 0xfc, 0x9a, 0x37, 0xd1, 0xd5, 0x07,
- 0x9f, 0x83, 0x77, 0xf7, 0x5e, 0x51, 0xa9, 0x1d, 0x7f, 0xd9, 0xd4, 0xdf,
- 0x5d, 0x06, 0x8e, 0xbb, 0x05, 0xa7, 0xcb, 0xf9, 0x65, 0xfc, 0x2f, 0xf8,
- 0x70, 0x4e, 0xbf, 0x26, 0xde, 0x71, 0x43, 0xae, 0x52, 0x47, 0x5f, 0xba,
- 0x9b, 0x11, 0xa7, 0x5d, 0x9d, 0x91, 0xbf, 0x68, 0xbd, 0x2d, 0x12, 0xbb,
- 0x6d, 0x37, 0x99, 0x65, 0x92, 0xaf, 0xfd, 0xc1, 0x03, 0xfd, 0xc9, 0xa1,
- 0x67, 0x30, 0x5f, 0xdf, 0xba, 0x93, 0x23, 0x27, 0x54, 0x1f, 0xbe, 0x27,
- 0xdf, 0xe8, 0x0e, 0x4a, 0x05, 0xa7, 0x54, 0x2f, 0xc8, 0x48, 0x6b, 0x23,
- 0x9c, 0x57, 0x84, 0xbc, 0xd0, 0x88, 0xe4, 0x22, 0x96, 0xe5, 0xd2, 0x27,
- 0x84, 0xf0, 0xc2, 0x07, 0x50, 0x85, 0xf1, 0x68, 0x21, 0x80, 0xcc, 0x2f,
- 0x3e, 0x90, 0x5f, 0x73, 0x99, 0xd3, 0xaf, 0xee, 0xa6, 0xd6, 0xd0, 0x14,
- 0x3a, 0xa0, 0xf5, 0x5a, 0x43, 0x65, 0x49, 0xd6, 0x43, 0xaf, 0xfb, 0xd1,
- 0xcd, 0x76, 0x07, 0xc7, 0x59, 0x52, 0x75, 0xff, 0x7a, 0x39, 0xae, 0xc0,
- 0xf8, 0xeb, 0xb5, 0x07, 0x5e, 0x58, 0x60, 0xeb, 0xfc, 0x3e, 0x79, 0xb5,
- 0x1e, 0x3a, 0x90, 0xf3, 0x5c, 0x6e, 0xf9, 0x1f, 0x1a, 0x75, 0xff, 0xb3,
- 0x60, 0xe6, 0xa6, 0x18, 0x09, 0xd7, 0xcd, 0x0c, 0x4e, 0x75, 0xdf, 0xc1,
- 0xd7, 0xb4, 0x9c, 0x3a, 0xb0, 0xf4, 0xff, 0x22, 0xf0, 0xb5, 0xfe, 0x96,
- 0x0a, 0x07, 0x04, 0xeb, 0xde, 0xd3, 0x10, 0x9e, 0xde, 0x0a, 0x4c, 0x6f,
- 0xd6, 0x2f, 0xc8, 0x04, 0x7f, 0x50, 0x91, 0xf1, 0x7d, 0xda, 0x83, 0xaf,
- 0x2c, 0x30, 0x75, 0xfe, 0x1f, 0x3c, 0xda, 0x8f, 0x1d, 0x48, 0x79, 0xae,
- 0x37, 0x7c, 0x8f, 0x8d, 0x3a, 0xff, 0xd9, 0xb0, 0x73, 0x53, 0x0c, 0x04,
- 0xeb, 0xe6, 0x86, 0x27, 0x3a, 0xfe, 0x9b, 0xf4, 0x57, 0x79, 0x8e, 0xbb,
- 0xf8, 0x3a, 0xf6, 0x93, 0x87, 0x56, 0x22, 0x15, 0xa4, 0x5f, 0x99, 0x78,
- 0x5a, 0xff, 0x4b, 0x05, 0x03, 0x82, 0x75, 0xfc, 0x2e, 0x1c, 0x51, 0x88,
- 0x5c, 0x8e, 0x08, 0xa6, 0x07, 0xb6, 0x50, 0x94, 0xd0, 0x89, 0xeb, 0x17,
- 0xe4, 0x02, 0x3f, 0xa8, 0x61, 0xf8, 0xf6, 0xff, 0xee, 0x46, 0xfa, 0x18,
- 0x5e, 0x6f, 0xe3, 0xaf, 0xff, 0xce, 0x1c, 0xc1, 0x53, 0xe8, 0xc0, 0xce,
- 0x9c, 0x3a, 0xf3, 0xf2, 0x73, 0xc8, 0x25, 0x7d, 0x2c, 0xde, 0x47, 0x90,
- 0x4a, 0xf6, 0x90, 0x27, 0x90, 0x4a, 0xe6, 0x59, 0x3c, 0x82, 0x54, 0xd4,
- 0x52, 0xcc, 0x53, 0xe2, 0xf6, 0x4a, 0x2e, 0x7f, 0x16, 0x41, 0x23, 0x06,
- 0xfe, 0xfe, 0xce, 0xe6, 0x0a, 0x87, 0x5e, 0x71, 0xff, 0xe2, 0xfa, 0x5c,
- 0x4e, 0x57, 0xf2, 0x18, 0x2b, 0x44, 0x18, 0xce, 0x3c, 0x69, 0x7d, 0xb7,
- 0x8f, 0xd3, 0xad, 0x8a, 0xe8, 0xa1, 0xfd, 0xfa, 0xd2, 0x3a, 0xff, 0x4d,
- 0x20, 0x4f, 0xe4, 0x9c, 0xab, 0x41, 0xd7, 0xf9, 0x24, 0x07, 0xd7, 0x50,
- 0xeb, 0xfb, 0x36, 0x3a, 0xf3, 0xa7, 0x5a, 0x45, 0x5e, 0x7e, 0x4e, 0x55,
- 0x15, 0x50, 0x6d, 0x9a, 0x20, 0xb1, 0xcb, 0xd1, 0xfb, 0x4a, 0x60, 0xd6,
- 0xd2, 0xd1, 0x7a, 0x30, 0x90, 0xa8, 0x4c, 0x57, 0x21, 0xdd, 0x7f, 0xfd,
- 0xf4, 0x65, 0xae, 0x87, 0x39, 0xfa, 0xd3, 0x47, 0x5f, 0x01, 0xf9, 0x23,
- 0xac, 0xb3, 0xae, 0xc9, 0x04, 0xd8, 0xcc, 0x43, 0x7e, 0x67, 0x26, 0x45,
- 0x9d, 0x7f, 0x36, 0x26, 0x94, 0x7e, 0x55, 0x90, 0xeb, 0xfe, 0x9c, 0x12,
- 0x0f, 0x40, 0xe2, 0x75, 0xfc, 0x90, 0xb9, 0xf1, 0x93, 0xaf, 0xd9, 0x3a,
- 0xf1, 0x67, 0x5e, 0xd2, 0x70, 0xea, 0x13, 0xc2, 0xf1, 0x3d, 0xfc, 0x2f,
- 0xff, 0xe0, 0xd1, 0xd7, 0xf2, 0x29, 0xf6, 0x16, 0xc0, 0x53, 0x06, 0xc0,
- 0xfe, 0x1c, 0xe9, 0xbf, 0xc4, 0x35, 0x89, 0xe6, 0x21, 0x40, 0xc6, 0x69,
- 0x7c, 0x39, 0x38, 0x0e, 0xbf, 0xec, 0xf7, 0xc1, 0xcf, 0xfe, 0xee, 0x75,
- 0x49, 0x73, 0x2c, 0x25, 0x98, 0x21, 0xc3, 0x6e, 0xc6, 0x49, 0xf9, 0x38,
- 0xc2, 0x0f, 0x51, 0xfc, 0xf8, 0xd3, 0x6c, 0x86, 0xff, 0xfd, 0x3f, 0x39,
- 0x81, 0x75, 0xf5, 0xfc, 0x31, 0x31, 0xd7, 0xff, 0xff, 0x81, 0xc0, 0x4c,
- 0x2f, 0xfe, 0xb5, 0x8a, 0x60, 0x38, 0xe1, 0x8e, 0xc1, 0xd7, 0xdb, 0x5d,
- 0x07, 0xd3, 0xaf, 0x32, 0xcb, 0x25, 0x5d, 0x28, 0x29, 0x82, 0xfe, 0xa1,
- 0x33, 0x89, 0xd5, 0x77, 0x78, 0xe2, 0x35, 0xfc, 0xa4, 0x73, 0x99, 0xd3,
- 0xaf, 0xe9, 0xe6, 0x92, 0xab, 0x93, 0x9d, 0x7d, 0xd7, 0xdd, 0x93, 0xaf,
- 0xd3, 0xf1, 0x21, 0x67, 0x5f, 0xff, 0x47, 0xdf, 0x0c, 0x7e, 0xfe, 0xff,
- 0xe8, 0xc8, 0xea, 0x56, 0x51, 0xa4, 0x86, 0xae, 0x47, 0xe2, 0x7b, 0xff,
- 0x3f, 0xb4, 0xce, 0x77, 0xf7, 0xf1, 0xd7, 0xff, 0xfe, 0xcf, 0x43, 0x47,
- 0x30, 0x62, 0x5e, 0xeb, 0xac, 0x73, 0x61, 0xd4, 0x14, 0x53, 0xb2, 0x7f,
- 0x7b, 0xe8, 0x66, 0x3a, 0xf4, 0x90, 0x4e, 0xbe, 0x9f, 0xee, 0xd3, 0x27,
- 0x5f, 0xf4, 0x75, 0xd3, 0xd3, 0x23, 0x27, 0x5f, 0xfe, 0x52, 0x35, 0xc8,
- 0xe8, 0xe7, 0xa1, 0x67, 0x5f, 0xf6, 0x87, 0x36, 0x24, 0xc8, 0xc9, 0xd7,
- 0xff, 0xf0, 0x1e, 0x76, 0x82, 0x7f, 0x67, 0x47, 0x3d, 0xd4, 0x3a, 0xfd,
- 0x13, 0x08, 0x34, 0x75, 0x62, 0x60, 0x88, 0x91, 0xd3, 0xaf, 0x2d, 0xdc,
- 0x82, 0x75, 0xfc, 0xe3, 0xfe, 0x79, 0x43, 0xaa, 0x15, 0x1f, 0xce, 0x49,
- 0x21, 0xf7, 0x1a, 0x12, 0x9f, 0x46, 0x79, 0xb0, 0xf3, 0x6c, 0x52, 0xfb,
- 0xa0, 0x5c, 0x1d, 0x73, 0xe8, 0xeb, 0x80, 0xa9, 0x3a, 0x9c, 0xf4, 0x04,
- 0x84, 0x02, 0xb7, 0x3b, 0x0a, 0x87, 0xca, 0x86, 0x56, 0xdb, 0x15, 0x50,
- 0x93, 0x56, 0x85, 0x6a, 0xd4, 0x8d, 0x57, 0x1d, 0xc4, 0xe1, 0x4c, 0xf2,
- 0x81, 0xe5, 0x0d, 0xb0, 0xca, 0xa4, 0xca, 0x43, 0xe2, 0x91, 0x97, 0x36,
- 0x3b, 0x0d, 0xe3, 0x5a, 0x49, 0x48, 0x93, 0x4a, 0x31, 0xe4, 0x7d, 0x0b,
- 0x94, 0xcd, 0xd9, 0xfe, 0xe7, 0x8c, 0x87, 0xf8, 0x69, 0x0c, 0xad, 0xed,
- 0x4f, 0xeb, 0xfa, 0x9c, 0x18, 0x08, 0xf6, 0x59, 0x3f, 0xdb, 0x87, 0xff,
- 0xd9, 0x64, 0xdb, 0x50, 0xcc, 0xbf, 0x2f, 0x11, 0xff, 0x3a, 0xf9, 0xae,
- 0xed, 0x34, 0x51, 0x57, 0xff, 0xe7, 0xfe, 0x1b, 0xd4, 0xd7, 0x53, 0xdd,
- 0xc1, 0x3a, 0xb8, 0x88, 0x01, 0x2d, 0xbf, 0x30, 0xb7, 0x93, 0x10, 0x8c,
- 0x8c, 0x85, 0x35, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x2e, 0x8b, 0xff,
- 0x98, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x5d, 0xfb, 0x8d, 0x77,
- 0x69, 0xa2, 0xf2, 0xb9, 0xf6, 0x1d, 0x66, 0x30, 0xf2, 0xb6, 0xcc, 0xea,
- 0x1f, 0x50, 0x3a, 0x72, 0x89, 0x1f, 0xe4, 0x26, 0x1b, 0x09, 0x59, 0x8e,
- 0x16, 0x7f, 0xd9, 0x52, 0x23, 0x79, 0x61, 0x7a, 0x96, 0x3b, 0xe4, 0x50,
- 0x1f, 0xec, 0x84, 0xdd, 0xff, 0xe6, 0x16, 0xf2, 0x63, 0x38, 0xd7, 0x76,
- 0x9a, 0x25, 0x9b, 0x81, 0xd3, 0xaf, 0xf2, 0x07, 0xb8, 0x82, 0xa1, 0xd7,
- 0xdd, 0x7f, 0x00, 0xeb, 0xee, 0xc2, 0xba, 0xce, 0xbc, 0x06, 0xb9, 0xd5,
- 0x24, 0x48, 0xa1, 0x8a, 0xb9, 0x0f, 0xd2, 0x4b, 0xf8, 0x3e, 0x03, 0xcb,
- 0x47, 0x5e, 0xf3, 0xac, 0xeb, 0xff, 0x76, 0x3a, 0x8a, 0x7b, 0x4f, 0xf9,
- 0xd7, 0xf0, 0xfb, 0x90, 0xed, 0x3a, 0xf9, 0xae, 0xed, 0x34, 0x46, 0x77,
- 0xf2, 0x42, 0xe7, 0xc6, 0x4e, 0xb8, 0x64, 0x75, 0x96, 0x75, 0xf9, 0x39,
- 0xd7, 0x63, 0x87, 0xa4, 0xb2, 0xdf, 0xa2, 0xb7, 0xf3, 0xc9, 0x38, 0xfc,
- 0x3a, 0xff, 0xed, 0x20, 0x35, 0x82, 0x09, 0x66, 0x8e, 0xbd, 0xa8, 0xdc,
- 0xea, 0x92, 0x78, 0x18, 0x7f, 0xc2, 0xb5, 0xbf, 0x8a, 0x76, 0x8a, 0xfc,
- 0x85, 0x7f, 0xdc, 0x76, 0x7a, 0x91, 0xc8, 0x3a, 0xff, 0xa5, 0xac, 0x8f,
- 0x91, 0xa5, 0x9d, 0x7d, 0xbf, 0x63, 0x47, 0x5f, 0x6a, 0x3d, 0xa3, 0xab,
- 0x0f, 0x0f, 0x44, 0x57, 0xff, 0x79, 0x38, 0xff, 0xfc, 0xde, 0x50, 0xb3,
- 0xaf, 0xc3, 0x12, 0xd3, 0x9d, 0x48, 0x7d, 0x9b, 0x11, 0xef, 0xff, 0xff,
- 0xb3, 0xde, 0x45, 0xf1, 0x33, 0x71, 0x07, 0xa3, 0xbf, 0x36, 0x27, 0xa6,
- 0x83, 0xaf, 0xf3, 0xcb, 0x5a, 0x71, 0x91, 0xd7, 0xe5, 0x3d, 0xe8, 0x59,
- 0xd7, 0xff, 0xbd, 0x0d, 0x4f, 0x22, 0xe6, 0xd2, 0x09, 0xd6, 0x91, 0xd4,
- 0x87, 0xb1, 0xf5, 0x22, 0xfd, 0xfc, 0x7a, 0x02, 0x75, 0x22, 0x32, 0x9e,
- 0x10, 0x00, 0x23, 0xbf, 0xfe, 0x07, 0xb5, 0xbc, 0xa0, 0x7f, 0xd7, 0xc0,
- 0x09, 0xd7, 0xa3, 0xd0, 0x75, 0x04, 0xfb, 0x76, 0x29, 0xde, 0xee, 0x09,
- 0xd4, 0x86, 0xf8, 0x04, 0x97, 0x76, 0x63, 0xaf, 0xf6, 0xfa, 0x1c, 0xe0,
- 0x60, 0xea, 0x43, 0xc9, 0x71, 0x7b, 0xef, 0x74, 0x1b, 0x67, 0x5f, 0xec,
- 0x8e, 0x3c, 0x93, 0xa7, 0x5f, 0xe4, 0x67, 0x51, 0xd7, 0x57, 0x3a, 0xb8,
- 0x7c, 0xbe, 0x30, 0xa4, 0x45, 0x62, 0xe1, 0x15, 0x7f, 0xf9, 0x3a, 0x05,
- 0x70, 0xf4, 0x1a, 0xde, 0x4e, 0x75, 0x61, 0xfa, 0xb9, 0x3d, 0xef, 0xb8,
- 0xaa, 0x3a, 0xff, 0xf0, 0x3f, 0x5a, 0x0e, 0x7e, 0x38, 0xf3, 0x1d, 0x7f,
- 0xd0, 0x9d, 0x48, 0x19, 0x80, 0x75, 0xff, 0x80, 0x1e, 0x60, 0x3b, 0x0b,
- 0xc3, 0xab, 0x11, 0xbb, 0xc2, 0x1e, 0xa4, 0xe8, 0xda, 0xff, 0xfb, 0x79,
- 0x27, 0x03, 0xd0, 0x73, 0x1b, 0xdc, 0x3a, 0xe4, 0x64, 0xeb, 0xb6, 0xb0,
- 0xea, 0xd1, 0xae, 0xf0, 0xb5, 0xfd, 0xa8, 0xf6, 0xba, 0x87, 0x5f, 0x87,
- 0x17, 0xcc, 0x3a, 0xfb, 0x9b, 0x30, 0x27, 0x56, 0x1f, 0xa2, 0xcb, 0x00,
- 0x4b, 0x7d, 0xfa, 0x6f, 0x23, 0xaf, 0xf4, 0x0f, 0x92, 0x71, 0x83, 0xaf,
- 0xff, 0x27, 0x12, 0x78, 0x1c, 0xef, 0x01, 0xb0, 0xea, 0xfd, 0x13, 0xa2,
- 0x47, 0xe3, 0x0b, 0x30, 0xad, 0xb3, 0x00, 0x22, 0x14, 0xf3, 0xa0, 0x84,
- 0xb7, 0x23, 0xdb, 0x51, 0x8f, 0x73, 0x74, 0x7c, 0x9a, 0x11, 0xbc, 0x23,
- 0x5c, 0x20, 0x3b, 0x0f, 0xb7, 0x86, 0xf7, 0xed, 0x23, 0x1a, 0x0e, 0xa1,
- 0xfb, 0xe3, 0xcd, 0x8f, 0xdb, 0x70, 0x95, 0xfb, 0x0c, 0xbb, 0xff, 0xcc,
- 0x2d, 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x4d, 0x37, 0xff, 0x98, 0x5b,
- 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x9c, 0x6f, 0xff, 0x30, 0xb7, 0x93,
- 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x40, 0xdf, 0xb8, 0xd7, 0x76, 0x9a, 0x2e,
- 0x0b, 0xf8, 0x73, 0xcd, 0x4d, 0x1d, 0x74, 0x21, 0xd7, 0xf8, 0x65, 0x08,
- 0x1c, 0x59, 0xd5, 0x88, 0xa2, 0x59, 0x9f, 0x4a, 0xc0, 0x29, 0x7e, 0x93,
- 0x0a, 0x2a, 0x14, 0x3a, 0x98, 0x3e, 0xb8, 0x3c, 0xb9, 0xff, 0x3a, 0xfd,
- 0x34, 0xa0, 0x64, 0x75, 0x1d, 0x58, 0x6c, 0x44, 0x9e, 0xfa, 0x3f, 0xc6,
- 0x4e, 0xb9, 0x18, 0xe2, 0x22, 0x05, 0x1f, 0xe8, 0xfd, 0xff, 0x49, 0x8c,
- 0xe3, 0x5d, 0xda, 0x68, 0x92, 0x6c, 0xc7, 0x51, 0x04, 0xe7, 0xb7, 0x33,
- 0xf9, 0xd7, 0xf9, 0xfc, 0x39, 0x3b, 0x89, 0xd7, 0xf6, 0x0b, 0xef, 0x2d,
- 0x1d, 0x7f, 0x42, 0xf9, 0x81, 0xf1, 0xd7, 0x3b, 0x01, 0x45, 0x02, 0x83,
- 0x1c, 0x30, 0xd1, 0x65, 0x4e, 0xd9, 0x00, 0x4a, 0x98, 0xae, 0xd8, 0xd6,
- 0x26, 0x57, 0xfd, 0x5f, 0x51, 0xb2, 0x7a, 0x32, 0xcd, 0x90, 0xc9, 0xbf,
- 0xf2, 0x8e, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x5a, 0x97, 0xfe, 0x79, 0x31,
- 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0xad, 0xc8, 0xc9, 0xd4, 0x75, 0x98, 0x51,
- 0x16, 0xab, 0x4b, 0xf2, 0x56, 0xd0, 0xb5, 0xfd, 0x9c, 0x6b, 0xbb, 0x4d,
- 0x11, 0x4d, 0xff, 0xcb, 0x63, 0xc2, 0xff, 0xeb, 0xd8, 0xd3, 0xa9, 0x83,
- 0xfd, 0x73, 0x8b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x46, 0x97, 0x03,
- 0xa7, 0x5f, 0xf8, 0x38, 0xb4, 0xe6, 0x6a, 0x68, 0x3a, 0xff, 0xff, 0x9c,
- 0x1a, 0xee, 0x07, 0xef, 0xdd, 0x27, 0xdf, 0x26, 0xa6, 0xfa, 0x75, 0xe4,
- 0x76, 0x4e, 0xa4, 0x46, 0x3a, 0xb9, 0xea, 0xdb, 0xef, 0x9a, 0xee, 0xd3,
- 0x45, 0x3f, 0x77, 0xa0, 0xea, 0xe1, 0xe1, 0x78, 0xb6, 0xff, 0xde, 0x9a,
- 0x3d, 0xd7, 0x9b, 0xe6, 0x1d, 0x7f, 0xf9, 0x16, 0x20, 0xea, 0x73, 0x35,
- 0x34, 0x1d, 0x7f, 0xf0, 0x3d, 0xc0, 0x4d, 0xa6, 0xbc, 0xda, 0x3a, 0xff,
- 0xec, 0x98, 0x03, 0x3e, 0x9a, 0xf3, 0x68, 0xeb, 0x30, 0xad, 0xaa, 0x89,
- 0x88, 0x6e, 0xe3, 0xa2, 0x11, 0x3a, 0x08, 0xa4, 0x79, 0x1e, 0xff, 0xf3,
- 0x0b, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x13, 0x55, 0xfe, 0x63, 0x38,
- 0xd7, 0x76, 0x9a, 0x2b, 0xbb, 0xe6, 0xbb, 0xb4, 0xd1, 0x5f, 0x5e, 0x65,
- 0x96, 0x4a, 0xb0, 0x94, 0xc1, 0x7f, 0x5c, 0x3e, 0xb5, 0xa6, 0x5e, 0x94,
- 0x6e, 0x75, 0xe9, 0xb3, 0xa7, 0x5f, 0xfb, 0x3a, 0xcb, 0xfb, 0x51, 0x93,
- 0x9d, 0x6f, 0x1d, 0x7f, 0xc9, 0xcc, 0x9d, 0x25, 0x81, 0x3a, 0xb8, 0x78,
- 0xee, 0x21, 0x7e, 0xdf, 0x6b, 0xa0, 0xfa, 0x75, 0xb8, 0x75, 0x1d, 0x6e,
- 0xa1, 0x75, 0xc1, 0x0b, 0x31, 0x89, 0xb6, 0xcc, 0x44, 0xe3, 0x82, 0x39,
- 0xa8, 0x42, 0x80, 0x87, 0x6d, 0x22, 0xff, 0xf3, 0x0b, 0x79, 0x31, 0x9c,
- 0x6b, 0xbb, 0x4d, 0x13, 0xdd, 0xfb, 0xb1, 0xb4, 0xfb, 0x9d, 0x7e, 0xe3,
- 0x5d, 0xda, 0x68, 0xb8, 0x6c, 0xc4, 0x1e, 0xee, 0x15, 0x5f, 0xfc, 0xc3,
- 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x93, 0xea, 0x19, 0x05, 0xb3, 0xc3,
- 0x16, 0x44, 0x4a, 0x4a, 0xc8, 0x6b, 0x94, 0xca, 0xfc, 0x94, 0x2f, 0xd7,
- 0x2d, 0x42, 0xd3, 0x61, 0x3d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x22,
- 0xab, 0xf7, 0x1a, 0xee, 0xd3, 0x45, 0x33, 0x7f, 0x27, 0x71, 0xf7, 0xfc,
- 0xeb, 0x31, 0x87, 0xc1, 0xb6, 0x67, 0x7f, 0xf9, 0x85, 0xbc, 0x98, 0xce,
- 0x35, 0xdd, 0xa6, 0x89, 0x9e, 0xff, 0xf3, 0x0b, 0x79, 0x31, 0x9c, 0x6b,
- 0xbb, 0x4d, 0x14, 0x6d, 0x4e, 0x9b, 0xc0, 0x61, 0x3e, 0xa1, 0x5f, 0x95,
- 0xef, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x23, 0xab, 0xff, 0xb9,
- 0x3b, 0x1a, 0x1c, 0xf6, 0xa1, 0x67, 0x53, 0x08, 0x8f, 0x84, 0xab, 0x81,
- 0xd3, 0xaf, 0x9a, 0xd0, 0x34, 0xeb, 0xf6, 0x08, 0x72, 0x73, 0xaf, 0xf4,
- 0x43, 0x73, 0x9c, 0xc3, 0xa9, 0x0f, 0x58, 0x49, 0xaf, 0xd9, 0xc6, 0x81,
- 0x43, 0xaf, 0xfc, 0x38, 0xa3, 0xcd, 0xae, 0xc0, 0x4e, 0xbd, 0x33, 0xf8,
- 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x4d, 0x5f, 0xb3, 0x76, 0x5f, 0xa7, 0x5f,
- 0xfd, 0xac, 0x10, 0xc7, 0xc5, 0x5f, 0xb3, 0xf4, 0x3a, 0x82, 0x99, 0x22,
- 0x14, 0x4c, 0x7d, 0xc1, 0xc1, 0x2d, 0xd1, 0x45, 0xff, 0xff, 0x60, 0xfb,
- 0x48, 0xdc, 0x1d, 0x37, 0xa9, 0xd6, 0xfd, 0x9c, 0xeb, 0xfe, 0xd3, 0xef,
- 0x93, 0x47, 0x74, 0x75, 0xdd, 0x41, 0x45, 0x07, 0x99, 0xef, 0xfe, 0x97,
- 0x50, 0x67, 0xd0, 0x23, 0x93, 0x1d, 0x7f, 0xda, 0xd3, 0x53, 0x9c, 0x49,
- 0xce, 0xbf, 0xf6, 0x32, 0xff, 0xbf, 0xbd, 0x9d, 0x3a, 0xff, 0xc2, 0x0f,
- 0x77, 0x26, 0x94, 0x6e, 0x75, 0xa6, 0x3a, 0xfd, 0x9d, 0x71, 0x09, 0xd5,
- 0x39, 0xb6, 0xfc, 0x46, 0xe8, 0x50, 0xeb, 0xf9, 0xff, 0xd2, 0xac, 0xab,
- 0x2a, 0xc7, 0x5f, 0xc9, 0x0b, 0x9f, 0x19, 0x3a, 0xff, 0xfb, 0x3d, 0xdc,
- 0x97, 0x1c, 0x7d, 0xd7, 0x91, 0xd7, 0x47, 0xe7, 0x5f, 0xe7, 0xde, 0x1a,
- 0x8d, 0x63, 0x88, 0x90, 0x12, 0xdf, 0xa9, 0xb5, 0x89, 0xea, 0xa3, 0xaf,
- 0x48, 0xc4, 0x5b, 0x50, 0xcd, 0xbf, 0x7b, 0xac, 0xbc, 0xe7, 0x59, 0x85,
- 0x6d, 0x77, 0xf6, 0x05, 0x82, 0xf1, 0x91, 0xa2, 0x36, 0x1e, 0xfb, 0x96,
- 0xf1, 0x14, 0x4e, 0x7d, 0x28, 0x4f, 0xea, 0x6d, 0xfb, 0x8d, 0x77, 0x69,
- 0xa2, 0xaa, 0xbf, 0xf3, 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x9b, 0x6c,
- 0xc6, 0x1f, 0xea, 0xcc, 0xef, 0xf3, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x5f,
- 0xdf, 0xb8, 0xd7, 0x76, 0x9a, 0x2c, 0x6b, 0xb6, 0xa4, 0x75, 0x98, 0xc3,
- 0xcc, 0x98, 0xce, 0xfd, 0xa6, 0xf6, 0x14, 0x3a, 0xff, 0x08, 0x25, 0x9a,
- 0x7f, 0x1d, 0x77, 0x3c, 0x75, 0xff, 0x67, 0xbd, 0x9c, 0x0e, 0x09, 0xd7,
- 0x94, 0x96, 0x1d, 0x66, 0x31, 0x13, 0x2e, 0x62, 0x22, 0xda, 0x36, 0xb2,
- 0x30, 0x98, 0x17, 0x21, 0x83, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xb5, 0x6f,
- 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x28, 0x2b, 0xf4, 0x33, 0xb7,
- 0x9c, 0x3a, 0xcc, 0x62, 0x29, 0xd6, 0x67, 0xf5, 0x2a, 0xff, 0x40, 0xff,
- 0x0a, 0xee, 0xb3, 0xae, 0xe4, 0x1d, 0x52, 0x3c, 0x9d, 0xa3, 0x4b, 0xe6,
- 0xbb, 0xb4, 0xd1, 0x71, 0x5f, 0xc0, 0x7d, 0xc3, 0x9c, 0x3a, 0xb8, 0x7b,
- 0x5a, 0x2d, 0xbd, 0xc8, 0x59, 0xd7, 0xcf, 0xb4, 0x93, 0x9d, 0x7e, 0xe8,
- 0x14, 0xc1, 0x3a, 0xf6, 0xd2, 0x34, 0xea, 0x09, 0xe2, 0xed, 0x13, 0xdf,
- 0xe5, 0xbc, 0xb4, 0x81, 0xc3, 0xaf, 0xf4, 0x2d, 0xf6, 0x47, 0x36, 0x8e,
- 0xbf, 0xb3, 0x8f, 0xe0, 0x41, 0xd7, 0xff, 0xce, 0x30, 0x9b, 0x5a, 0x4d,
- 0x67, 0x73, 0x6c, 0xea, 0x09, 0xfe, 0x6c, 0x2b, 0xbf, 0xf9, 0x04, 0x12,
- 0xcd, 0x69, 0x03, 0x87, 0x54, 0xc7, 0xcb, 0xe2, 0x4b, 0x31, 0x0a, 0xad,
- 0x71, 0xff, 0x84, 0x5d, 0x1b, 0x76, 0x9f, 0xc9, 0x7c, 0x63, 0xf6, 0x31,
- 0x7b, 0xf2, 0xa9, 0x5a, 0x7e, 0xa4, 0x1d, 0x7f, 0xe4, 0xdd, 0x56, 0xd7,
- 0x3e, 0x7c, 0xee, 0xd9, 0xd7, 0xdd, 0x8f, 0x34, 0xea, 0x56, 0xa7, 0xda,
- 0x14, 0xcb, 0xff, 0xca, 0xb2, 0x8c, 0xab, 0xce, 0x15, 0x57, 0xcf, 0x9d,
- 0xdb, 0x3a, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x74, 0xdf, 0xa0, 0x5c, 0x30,
- 0x75, 0xe8, 0xf6, 0xd1, 0xd7, 0xd8, 0x1c, 0x09, 0xd7, 0xfc, 0xfb, 0x23,
- 0xda, 0x03, 0x55, 0x27, 0x59, 0x85, 0x59, 0x3f, 0xd8, 0x85, 0x04, 0x8a,
- 0x31, 0x89, 0x0c, 0xfa, 0x48, 0xe3, 0xc2, 0x41, 0x7f, 0xfd, 0x83, 0xe4,
- 0x5f, 0x61, 0x05, 0xf8, 0xa1, 0xd7, 0xf4, 0xf1, 0xe7, 0x50, 0x07, 0x51,
- 0xd7, 0xff, 0x47, 0x3f, 0xf9, 0xae, 0xc2, 0xdc, 0x4e, 0xbf, 0xd1, 0xcf,
- 0xbd, 0xee, 0x7e, 0x75, 0x48, 0xfe, 0xba, 0x8b, 0x7f, 0x49, 0xe4, 0xe2,
- 0xd3, 0xaf, 0xff, 0x67, 0xa1, 0x9f, 0xb3, 0xeb, 0x17, 0x0a, 0xe7, 0x59,
- 0x85, 0x65, 0x32, 0x0c, 0x84, 0x24, 0xc4, 0x42, 0x57, 0x5c, 0x4e, 0x71,
- 0x71, 0xa7, 0x5f, 0x63, 0x2a, 0xca, 0xce, 0xbf, 0xe4, 0xe0, 0xc6, 0xeb,
- 0x7f, 0x1d, 0x7f, 0xff, 0xc0, 0xe4, 0xb5, 0xd7, 0x4e, 0x73, 0x80, 0xdd,
- 0x38, 0xfa, 0x3a, 0xff, 0xc2, 0xec, 0xfb, 0x3a, 0xf3, 0x39, 0xd7, 0xff,
- 0xf7, 0x44, 0x0e, 0xaf, 0x92, 0xee, 0x29, 0x81, 0x98, 0x07, 0x5c, 0xdc,
- 0x3a, 0xa0, 0xfc, 0xd4, 0x5e, 0xbc, 0xa6, 0xa4, 0x75, 0xff, 0xa5, 0x9c,
- 0xe3, 0xca, 0x7c, 0x64, 0xeb, 0xff, 0xb0, 0x31, 0x28, 0xe4, 0x7d, 0x71,
- 0x3a, 0xff, 0xdb, 0x32, 0x4b, 0x0a, 0x6c, 0x80, 0x9d, 0x4b, 0x44, 0x1b,
- 0xa1, 0x5c, 0xec, 0x4e, 0xa8, 0xea, 0x66, 0x7e, 0x42, 0xc3, 0x44, 0x5e,
- 0x1d, 0xfb, 0x0c, 0x2a, 0xea, 0xae, 0x41, 0x94, 0xe3, 0x7f, 0xef, 0x23,
- 0x50, 0x2e, 0x2a, 0x41, 0xd7, 0xfd, 0x1b, 0xf5, 0xf5, 0xe8, 0x64, 0xea,
- 0x83, 0xf5, 0xe1, 0xe5, 0xc0, 0xe9, 0xd7, 0xe1, 0xce, 0xbf, 0x8e, 0xbf,
- 0xa4, 0xf9, 0xb2, 0x02, 0x75, 0x2a, 0x0f, 0x49, 0x57, 0x92, 0xdf, 0x20,
- 0x25, 0x07, 0x5f, 0x9e, 0x69, 0x27, 0x8e, 0xbf, 0xf4, 0x07, 0x91, 0x24,
- 0xdf, 0xd8, 0x75, 0x49, 0x10, 0x9f, 0x90, 0x78, 0x9e, 0xff, 0xff, 0xa0,
- 0x3d, 0xcd, 0xfc, 0x2f, 0xdf, 0xdf, 0x5a, 0x7e, 0x34, 0xeb, 0xfd, 0x99,
- 0x8a, 0x28, 0xf2, 0x3a, 0x94, 0x44, 0xc7, 0x99, 0xaf, 0xdb, 0x13, 0x98,
- 0x13, 0xaf, 0xff, 0xb5, 0xd4, 0xd7, 0xbb, 0x81, 0x4d, 0x60, 0x9d, 0x7b,
- 0xb0, 0x38, 0x7e, 0xa0, 0x28, 0xbf, 0xd0, 0xbc, 0x45, 0xc2, 0xb9, 0xd7,
- 0xfa, 0x4b, 0xd2, 0x0e, 0xf2, 0x3a, 0x9a, 0x7c, 0xd3, 0x19, 0xde, 0x77,
- 0x69, 0xa2, 0x4c, 0xbd, 0xb4, 0x9a, 0x3a, 0x9a, 0x78, 0xbb, 0x44, 0xf7,
- 0xe6, 0xaa, 0xca, 0xa5, 0x65, 0x50, 0x75, 0xfe, 0xcd, 0xfd, 0xe7, 0x96,
- 0x8e, 0xa8, 0x3e, 0xde, 0x1d, 0x5f, 0xe1, 0x7f, 0x69, 0xa0, 0x13, 0xaf,
- 0xff, 0xee, 0x67, 0xe9, 0xfb, 0x38, 0x9b, 0x07, 0x3d, 0xd4, 0x3a, 0xb1,
- 0x11, 0xa8, 0x63, 0x52, 0x54, 0xc1, 0x90, 0x97, 0xe3, 0x42, 0xe1, 0x25,
- 0xd8, 0x57, 0x5f, 0xc1, 0xfd, 0x51, 0xaf, 0xf6, 0xce, 0xbd, 0xa4, 0x09,
- 0xd7, 0xf0, 0xc6, 0xeb, 0x7f, 0x1d, 0x7f, 0xd0, 0xdf, 0x03, 0xbc, 0x86,
- 0x4e, 0xbf, 0xcd, 0x4e, 0x6a, 0x68, 0x73, 0xaf, 0xfe, 0x06, 0xba, 0xf2,
- 0xeb, 0xca, 0x04, 0xea, 0xdc, 0xfd, 0x38, 0x65, 0x77, 0x52, 0x64, 0xc5,
- 0xf8, 0x36, 0xb2, 0xcf, 0x42, 0xb6, 0xfb, 0xc8, 0xb7, 0x3a, 0xff, 0x27,
- 0x75, 0x1e, 0x80, 0x9d, 0x58, 0x7a, 0x3e, 0x20, 0xbf, 0xe8, 0xef, 0x92,
- 0x75, 0xc3, 0x4e, 0xbf, 0xff, 0x3b, 0x79, 0x1d, 0x1c, 0xf6, 0x30, 0xcb,
- 0x2c, 0x95, 0x52, 0x45, 0x86, 0x88, 0x7c, 0x71, 0x7f, 0x35, 0xa0, 0x68,
- 0xc1, 0xd7, 0xff, 0xb3, 0x79, 0x0c, 0x4b, 0x91, 0xe7, 0xf1, 0xd7, 0xfe,
- 0x7f, 0x47, 0x35, 0xd8, 0x1f, 0x1d, 0x7e, 0xc9, 0x23, 0xec, 0x3a, 0x84,
- 0xf8, 0xf4, 0x79, 0x52, 0x46, 0x60, 0x21, 0x57, 0x7f, 0xf8, 0x62, 0x5c,
- 0xe0, 0x37, 0x4e, 0x3e, 0x8e, 0xbf, 0xfe, 0xd6, 0x28, 0x39, 0xed, 0x64,
- 0x85, 0xd9, 0x3a, 0xed, 0x89, 0xd4, 0x4b, 0xf9, 0x26, 0xfb, 0x6a, 0x3b,
- 0xa3, 0xaa, 0x0f, 0x53, 0x0c, 0x2f, 0xef, 0x08, 0x27, 0xdd, 0x5c, 0xeb,
- 0xff, 0xd1, 0x38, 0xe6, 0x4f, 0xe5, 0x20, 0x64, 0x75, 0xff, 0x9c, 0x67,
- 0xeb, 0xad, 0x34, 0x87, 0x53, 0xa2, 0xdc, 0x4c, 0x99, 0x49, 0xbc, 0xcb,
- 0x2c, 0x95, 0x7d, 0x3a, 0xd3, 0x45, 0x30, 0x5f, 0xdd, 0x01, 0x3a, 0xdc,
- 0x73, 0xc7, 0x13, 0x2b, 0xff, 0xff, 0x80, 0xe2, 0xde, 0x66, 0xc8, 0x1f,
- 0x2e, 0x30, 0x43, 0x9b, 0xf8, 0xeb, 0xfd, 0x28, 0xe4, 0xf1, 0xc9, 0xce,
- 0xbf, 0xb5, 0xa4, 0xc1, 0xfc, 0xeb, 0xdc, 0xc5, 0x73, 0xaf, 0xfd, 0x0c,
- 0xfd, 0x9f, 0x58, 0xb8, 0x57, 0x3a, 0xb8, 0x88, 0xe5, 0x96, 0x78, 0x7a,
- 0xa1, 0x1e, 0x59, 0x0c, 0x2b, 0xf2, 0x7a, 0x7c, 0x64, 0xeb, 0xfe, 0x86,
- 0xf4, 0x41, 0xe8, 0xd1, 0xd7, 0xff, 0x26, 0xd4, 0x36, 0x17, 0x81, 0x75,
- 0x9d, 0x7f, 0xfe, 0xf7, 0x72, 0x5f, 0x1b, 0xd4, 0xf6, 0xed, 0x4e, 0x1d,
- 0x5c, 0x47, 0xda, 0xca, 0x3a, 0x6e, 0x28, 0x97, 0xfc, 0xb8, 0xe6, 0xcc,
- 0xe4, 0x4c, 0x75, 0xff, 0xb8, 0xd5, 0xc6, 0xfa, 0xcd, 0x98, 0x75, 0xfe,
- 0x1f, 0xf6, 0xf0, 0x38, 0xb3, 0xaf, 0xe1, 0xf9, 0xb7, 0x9c, 0x83, 0xaa,
- 0x11, 0x4b, 0x88, 0x0e, 0x6b, 0x7f, 0xd8, 0xff, 0xfc, 0xc0, 0xbc, 0x8e,
- 0xbf, 0xfc, 0xf3, 0xf5, 0x20, 0x72, 0x64, 0xe2, 0x1d, 0x58, 0x9e, 0x47,
- 0xe7, 0x9a, 0x86, 0xff, 0x8b, 0x59, 0x39, 0xbf, 0x0e, 0x75, 0xfc, 0x75,
- 0xff, 0xa5, 0x03, 0x3f, 0xde, 0x08, 0x24, 0x75, 0x2b, 0x9f, 0x2c, 0xc4,
- 0xb7, 0xde, 0x9f, 0x02, 0x75, 0xff, 0x22, 0x9f, 0x79, 0xfa, 0xd3, 0x47,
- 0x54, 0xc7, 0xbd, 0xb6, 0x45, 0x79, 0x96, 0x59, 0x3a, 0xff, 0xfd, 0x8b,
- 0xf0, 0xc7, 0xf8, 0x1d, 0x62, 0xe1, 0xa5, 0x30, 0x5f, 0xdf, 0xec, 0x6f,
- 0x52, 0x05, 0xa7, 0x5f, 0xee, 0x47, 0x91, 0xa8, 0x13, 0xaf, 0xd2, 0x9b,
- 0x31, 0xa7, 0x5b, 0x87, 0x52, 0xb0, 0x7d, 0x10, 0x63, 0xf4, 0x9e, 0xb1,
- 0x3f, 0x94, 0x84, 0x27, 0x51, 0x45, 0x8f, 0x50, 0x98, 0xbd, 0xe9, 0x74,
- 0xeb, 0x21, 0xd7, 0xf7, 0x63, 0xe3, 0x52, 0x73, 0xaf, 0xee, 0x3f, 0x06,
- 0x24, 0x75, 0xff, 0xf4, 0x29, 0xae, 0xba, 0x7a, 0x16, 0x2e, 0xa1, 0xd7,
- 0xfe, 0xcd, 0x9d, 0x4f, 0x9a, 0xd2, 0x2c, 0xeb, 0x9f, 0xd2, 0x44, 0x7f,
- 0x53, 0xaf, 0xfc, 0x92, 0x4e, 0x6f, 0x03, 0x1a, 0x3a, 0x95, 0xa2, 0x6c,
- 0x41, 0x0f, 0xe1, 0x78, 0xc2, 0xeb, 0xc5, 0xd7, 0x49, 0x85, 0x6d, 0xb4,
- 0xbe, 0x55, 0x34, 0x44, 0x2c, 0x25, 0x0c, 0x9c, 0x95, 0xf2, 0xa2, 0xd3,
- 0x63, 0x4e, 0xde, 0x35, 0x04, 0x30, 0x9a, 0x1f, 0x1c, 0x8c, 0x4f, 0xb0,
- 0xd7, 0x78, 0x4a, 0xfe, 0x4c, 0x31, 0xb1, 0x6a, 0x57, 0x4f, 0xa5, 0x57,
- 0xed, 0xa9, 0x7d, 0x8d, 0xfa, 0xff, 0xf7, 0x31, 0x90, 0xf7, 0x26, 0x1c,
- 0xe4, 0x8e, 0xbd, 0xcc, 0x57, 0x3a, 0xff, 0xd0, 0xcf, 0xd9, 0xf5, 0x8b,
- 0x85, 0x73, 0xab, 0x88, 0xac, 0x5a, 0x57, 0x87, 0xaf, 0xff, 0x9d, 0x71,
- 0xc6, 0xf0, 0x0a, 0x70, 0x0f, 0xa3, 0xab, 0x11, 0x00, 0x03, 0x0b, 0xfd,
- 0xc6, 0x81, 0xc2, 0xb8, 0x3a, 0xff, 0xe8, 0xe7, 0xdf, 0x27, 0xbb, 0x81,
- 0x43, 0xaf, 0xfd, 0xd1, 0x89, 0xfe, 0xf7, 0xae, 0xae, 0x75, 0x42, 0x2e,
- 0x67, 0x32, 0xc4, 0x4b, 0xcf, 0xc9, 0xce, 0xb9, 0x96, 0x4e, 0xbc, 0xed,
- 0x61, 0xa6, 0xd1, 0x91, 0xcb, 0xfa, 0x38, 0xf2, 0x4e, 0x9d, 0x7e, 0xc5,
- 0xf5, 0xc2, 0x75, 0x98, 0x86, 0xfb, 0xdb, 0x23, 0xe8, 0x50, 0xa9, 0xb2,
- 0xc2, 0xf9, 0x0a, 0x07, 0xad, 0x37, 0xc6, 0x54, 0xbe, 0xa1, 0xb7, 0xb1,
- 0x8d, 0x93, 0x4d, 0xa2, 0xba, 0x93, 0xaf, 0xf3, 0x0c, 0xf1, 0x06, 0xf1,
- 0x94, 0xf0, 0xa1, 0x70, 0x8b, 0xec, 0x65, 0x7f, 0xc3, 0x5b, 0x52, 0xcd,
- 0xbd, 0x29, 0xf4, 0x15, 0xfb, 0xa5, 0xfd, 0xa8, 0x9a, 0x49, 0x31, 0xd7,
- 0xff, 0xa2, 0x7c, 0xf4, 0x0a, 0x7f, 0x9b, 0xf8, 0xeb, 0x31, 0xa3, 0xf7,
- 0xfa, 0x5d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x8d, 0x6f, 0x29, 0xbe, 0x8e,
- 0xb3, 0x18, 0x7a, 0x3e, 0x33, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x54, 0xb7,
- 0x3b, 0x4d, 0x10, 0xd5, 0x98, 0xc3, 0xd5, 0x73, 0x3b, 0xf7, 0x1a, 0xee,
- 0xd3, 0x44, 0x7d, 0x7f, 0xfc, 0x2f, 0xe9, 0x42, 0x9f, 0x23, 0xda, 0x8f,
- 0xce, 0xbc, 0xf2, 0x63, 0x11, 0x09, 0xf4, 0xce, 0xff, 0xcf, 0x3c, 0x75,
- 0x38, 0x90, 0xb3, 0xaf, 0xf4, 0x73, 0x07, 0xd9, 0xd3, 0xaf, 0x2f, 0x18,
- 0xdb, 0x3e, 0xcf, 0xa7, 0x94, 0xc2, 0x36, 0xe2, 0x14, 0x57, 0xff, 0xfd,
- 0x20, 0x71, 0x47, 0xd6, 0x06, 0x37, 0xd7, 0xdf, 0x28, 0x8a, 0x1d, 0x7f,
- 0x03, 0x7d, 0xe5, 0x9e, 0x3a, 0xff, 0xf2, 0xac, 0xa3, 0x2a, 0xf3, 0x85,
- 0x55, 0xf3, 0xe7, 0x76, 0xce, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x58, 0xf7,
- 0x3e, 0x8e, 0xbf, 0xa7, 0xfb, 0xce, 0x67, 0x0e, 0xa9, 0x1e, 0x2b, 0x8a,
- 0xdf, 0xf0, 0xba, 0x9d, 0x48, 0x19, 0xce, 0xbf, 0xff, 0x7f, 0x29, 0xd5,
- 0x68, 0x56, 0xe7, 0x6f, 0x3e, 0x7c, 0xee, 0xd9, 0xd7, 0xe4, 0xf7, 0x93,
- 0xc7, 0x5f, 0x73, 0x99, 0xb6, 0x75, 0x61, 0xe5, 0x39, 0x35, 0xfb, 0x39,
- 0x99, 0x31, 0xd6, 0x62, 0x15, 0x64, 0x4e, 0xd9, 0x22, 0xfc, 0x62, 0x47,
- 0x89, 0x88, 0x7a, 0x6f, 0xa8, 0x5a, 0xfd, 0x20, 0xbc, 0xab, 0x2d, 0x43,
- 0xaf, 0xe5, 0x40, 0xe7, 0x5f, 0xc7, 0x5f, 0xe7, 0xff, 0x4f, 0xef, 0x39,
- 0xd7, 0x2d, 0xa7, 0x50, 0x9e, 0x47, 0x8c, 0xaf, 0xfd, 0x8c, 0xf3, 0x05,
- 0xf7, 0x96, 0x8e, 0xbf, 0x66, 0xba, 0x8c, 0x9d, 0x7d, 0xfa, 0xd3, 0x87,
- 0x5f, 0xff, 0xf4, 0x70, 0x70, 0x39, 0xde, 0xa3, 0x7a, 0x9e, 0xd3, 0xee,
- 0x75, 0x22, 0x21, 0xba, 0x45, 0x7f, 0x47, 0x3f, 0xdb, 0x07, 0x8e, 0xbf,
- 0xe8, 0x1f, 0x2a, 0x9f, 0xc0, 0x83, 0xaf, 0xff, 0x47, 0x61, 0x6d, 0xea,
- 0x7b, 0x31, 0x67, 0x5f, 0x7f, 0xfa, 0x7d, 0x3a, 0xf3, 0xbb, 0x4d, 0x16,
- 0x85, 0xff, 0x9d, 0x9d, 0xa6, 0xbf, 0x27, 0xc6, 0x4e, 0xbf, 0xbf, 0x81,
- 0x8f, 0x68, 0xea, 0x6a, 0x25, 0xb8, 0x4f, 0xfa, 0x1d, 0xff, 0xff, 0xf2,
- 0x73, 0xae, 0x29, 0x1e, 0x4e, 0xc6, 0xbb, 0x9a, 0xe6, 0x37, 0x3c, 0x75,
- 0x49, 0x50, 0xb0, 0x4c, 0x5a, 0x74, 0x88, 0xfc, 0x85, 0xdf, 0x4c, 0x6e,
- 0xc5, 0x9d, 0x7f, 0xf3, 0xef, 0xb3, 0xaa, 0xe9, 0xe1, 0x85, 0x9d, 0x5c,
- 0x3d, 0xd7, 0x15, 0xbf, 0xff, 0x27, 0xb4, 0xfb, 0xeb, 0x59, 0xd4, 0xd0,
- 0x27, 0x3a, 0xff, 0xf8, 0x13, 0xf1, 0x3d, 0x38, 0x39, 0x2d, 0x2b, 0xa1,
- 0xd5, 0xd4, 0x55, 0x8a, 0xb5, 0xff, 0xf0, 0x39, 0xc8, 0x1c, 0x51, 0x3b,
- 0xdc, 0xfa, 0x75, 0x95, 0x27, 0x57, 0x0f, 0x90, 0x0a, 0x17, 0xf9, 0x60,
- 0x1f, 0x68, 0x1c, 0x3a, 0xb8, 0x7a, 0xbb, 0x64, 0x57, 0xf6, 0xc9, 0xbb,
- 0x9f, 0xb9, 0xd7, 0xe1, 0x6b, 0xe9, 0x0e, 0xbf, 0xff, 0xb8, 0x31, 0x1b,
- 0xfc, 0xd7, 0x86, 0x03, 0xd8, 0xf1, 0xd7, 0x27, 0x4e, 0xbe, 0x90, 0xbf,
- 0xd3, 0xaf, 0xf0, 0x5f, 0xfe, 0x71, 0xff, 0x3a, 0xfd, 0x9c, 0x6a, 0xbb,
- 0x27, 0x52, 0x1e, 0xf8, 0x9a, 0x54, 0x26, 0x6d, 0x84, 0xaa, 0xeb, 0x6e,
- 0x2a, 0x08, 0x40, 0xde, 0x75, 0x74, 0x3a, 0xff, 0xdf, 0x7c, 0xa2, 0x29,
- 0x18, 0x30, 0x75, 0xfb, 0xef, 0x86, 0x3f, 0x3a, 0xb7, 0x44, 0x2f, 0x07,
- 0x76, 0x1f, 0xdf, 0xa3, 0xd9, 0xd8, 0x3a, 0xff, 0xff, 0xf7, 0x50, 0x38,
- 0x93, 0xf6, 0x23, 0xe6, 0x6f, 0x2d, 0x27, 0x9c, 0x70, 0xeb, 0xff, 0x66,
- 0xf2, 0xd4, 0xdc, 0x7f, 0x68, 0xeb, 0xff, 0xec, 0xf6, 0xb2, 0x6e, 0xc6,
- 0xcc, 0xef, 0x60, 0xeb, 0xfe, 0x18, 0x89, 0xb3, 0x62, 0x70, 0xea, 0x9d,
- 0x36, 0x36, 0x92, 0xfe, 0xec, 0x28, 0x1e, 0x50, 0xbf, 0x7c, 0x9a, 0x49,
- 0x31, 0xd5, 0x0a, 0x83, 0x72, 0x39, 0x64, 0x4c, 0xbf, 0xfb, 0xa9, 0xf3,
- 0x07, 0x13, 0x8f, 0xb0, 0xeb, 0xff, 0xfd, 0xd8, 0x1c, 0xff, 0x58, 0x1e,
- 0xc4, 0xeb, 0x00, 0x84, 0xea, 0x51, 0x14, 0x9e, 0x44, 0xbf, 0xff, 0xa2,
- 0x6c, 0x0f, 0x63, 0x67, 0x73, 0xc3, 0x10, 0xb3, 0xaf, 0xed, 0xf5, 0xf6,
- 0x70, 0x09, 0xd7, 0xfd, 0x0d, 0xea, 0x4c, 0xef, 0x39, 0xd4, 0xb4, 0x61,
- 0xba, 0xd7, 0xe6, 0x37, 0xfa, 0x51, 0xc9, 0xe3, 0x93, 0x9d, 0x7f, 0xc8,
- 0x01, 0x97, 0x23, 0x02, 0x75, 0xff, 0xff, 0x77, 0x24, 0xde, 0xa7, 0x63,
- 0x39, 0x2f, 0x0c, 0x2f, 0x47, 0x56, 0x91, 0x35, 0xe3, 0x6a, 0x84, 0x78,
- 0xe4, 0x33, 0xaf, 0xf7, 0x1b, 0x36, 0x27, 0x40, 0x75, 0xfe, 0x5c, 0x34,
- 0x5f, 0x7f, 0x1d, 0x7f, 0x72, 0x3d, 0x3e, 0x32, 0x75, 0xff, 0xff, 0xf2,
- 0x03, 0x9d, 0xc9, 0xa6, 0x7e, 0x4d, 0xee, 0x83, 0xfd, 0x62, 0x6c, 0x0c,
- 0x1d, 0x7e, 0xf7, 0x5c, 0x54, 0x3a, 0xff, 0x84, 0x13, 0x87, 0xb8, 0x30,
- 0x75, 0xb0, 0x28, 0xe0, 0xc8, 0x41, 0x34, 0x9e, 0xff, 0xf7, 0x3f, 0x6f,
- 0xe3, 0x9e, 0xd3, 0xb8, 0x9d, 0x50, 0x9f, 0xae, 0x19, 0xa1, 0x90, 0xc6,
- 0x1c, 0x03, 0x9b, 0xfd, 0x9d, 0x99, 0x3a, 0x8b, 0x3a, 0xff, 0x4b, 0x39,
- 0xa1, 0x89, 0xce, 0xbd, 0xb7, 0x93, 0x9d, 0x7b, 0x3a, 0xe7, 0x5f, 0xa6,
- 0x08, 0x00, 0x27, 0x50, 0x4f, 0x09, 0xc6, 0xaf, 0xf6, 0x33, 0x8d, 0x6e,
- 0x32, 0x75, 0xff, 0x6e, 0xbc, 0xc1, 0xf6, 0xde, 0x1d, 0x79, 0x49, 0x00,
- 0xeb, 0xf7, 0x63, 0x93, 0xac, 0xeb, 0xfc, 0x07, 0x1e, 0xe3, 0xcc, 0x75,
- 0xb7, 0x98, 0xf6, 0x59, 0x28, 0xa4, 0x45, 0x0b, 0xbb, 0x56, 0x26, 0x5e,
- 0xe6, 0x63, 0x0d, 0xba, 0xc5, 0x49, 0x1b, 0x99, 0x21, 0x93, 0xb0, 0xea,
- 0x35, 0x0b, 0xbd, 0x07, 0x5c, 0xfe, 0x3a, 0xb8, 0x6a, 0xba, 0x2b, 0x7f,
- 0xdc, 0xce, 0xe4, 0xff, 0x13, 0x47, 0x56, 0x1e, 0xd8, 0x08, 0x6f, 0xe4,
- 0x10, 0x4b, 0x34, 0x75, 0xff, 0xb3, 0xd1, 0xbf, 0xef, 0xde, 0xa1, 0xd6,
- 0x59, 0xd7, 0xf2, 0x08, 0x25, 0x9a, 0xf8, 0x79, 0xdb, 0x0f, 0xa9, 0x44,
- 0x60, 0x79, 0xe6, 0xcc, 0x2b, 0x6d, 0xa0, 0xb2, 0xa8, 0x8a, 0x1d, 0xe7,
- 0x21, 0x91, 0xf0, 0x61, 0x5b, 0x92, 0x8e, 0x14, 0x85, 0xd3, 0x61, 0x98,
- 0x90, 0xdb, 0x98, 0x95, 0x71, 0xb3, 0x76, 0x57, 0x13, 0xc3, 0x67, 0xf8,
- 0x73, 0x8c, 0x64, 0x3a, 0x94, 0x37, 0xe9, 0x52, 0xbb, 0x70, 0xd5, 0xfb,
- 0x0e, 0x1b, 0xfb, 0x69, 0x02, 0x31, 0x31, 0xd7, 0xa1, 0xc4, 0xeb, 0xec,
- 0xeb, 0xf8, 0xeb, 0x2a, 0x30, 0xfa, 0x3a, 0x5e, 0x23, 0x37, 0xff, 0xff,
- 0xba, 0xe3, 0xed, 0x42, 0x4b, 0x36, 0x87, 0xd1, 0xd8, 0x50, 0x11, 0xb4,
- 0x75, 0xf6, 0x6b, 0xf4, 0x3a, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x6b, 0x5f,
- 0xe5, 0xa2, 0xde, 0x6c, 0xe9, 0xd7, 0xf6, 0x6d, 0x69, 0xc5, 0xa7, 0x5e,
- 0xe4, 0x2c, 0xeb, 0xfb, 0xb9, 0xa8, 0x9f, 0x68, 0xeb, 0xfe, 0x93, 0x19,
- 0xc6, 0xbb, 0xb4, 0xd1, 0x41, 0xd6, 0x1f, 0xab, 0x98, 0x5f, 0x64, 0xd1,
- 0xe3, 0xaf, 0xfa, 0x25, 0x1c, 0x9e, 0x39, 0x39, 0xd7, 0xff, 0xef, 0x69,
- 0x27, 0x7d, 0x38, 0xbf, 0xbb, 0x13, 0x1d, 0x66, 0x15, 0x4a, 0xb0, 0xe0,
- 0xde, 0x4f, 0x58, 0x42, 0x86, 0x73, 0x19, 0x70, 0xb9, 0x70, 0x90, 0xe9,
- 0x00, 0x90, 0xfd, 0x39, 0xbf, 0xfc, 0xc2, 0xde, 0x4c, 0x67, 0x1a, 0xee,
- 0xd3, 0x45, 0x17, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0xaa, 0xa1,
- 0xbf, 0xf2, 0x93, 0xe3, 0x5f, 0x52, 0x38, 0x65, 0xca, 0xf0, 0xed, 0x69,
- 0x47, 0xfc, 0xe5, 0x0e, 0xa1, 0x53, 0xe5, 0x7b, 0xf7, 0x1a, 0xee, 0xd3,
- 0x44, 0x43, 0x7b, 0xb8, 0x13, 0xaf, 0xb3, 0x62, 0x70, 0xeb, 0x31, 0x87,
- 0xe1, 0xb9, 0x9a, 0xb8, 0xdd, 0xb6, 0xce, 0xbe, 0x8e, 0xc2, 0xce, 0xbe,
- 0x6b, 0xbb, 0x4d, 0x11, 0xb5, 0x34, 0xf3, 0x78, 0x41, 0x66, 0x02, 0x88,
- 0x2c, 0x60, 0xbf, 0xcc, 0x67, 0x1a, 0xee, 0xd3, 0x45, 0x37, 0x7e, 0xe3,
- 0x5d, 0xda, 0x68, 0xa8, 0x2f, 0x66, 0xec, 0x9d, 0x66, 0x30, 0xf4, 0x3a,
- 0x67, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8a, 0x9a, 0xfd, 0xc6, 0xbb,
- 0xb4, 0xd1, 0x58, 0x5f, 0x91, 0x90, 0x83, 0x87, 0x5c, 0xbd, 0x1d, 0x7f,
- 0x26, 0xdb, 0xc2, 0x6d, 0x9d, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x88,
- 0xfe, 0xa0, 0xfb, 0xe4, 0x61, 0x7b, 0x22, 0x73, 0xaf, 0xf6, 0x6f, 0x27,
- 0x92, 0x09, 0xd7, 0x3f, 0x8e, 0xb3, 0x18, 0x9b, 0x13, 0x4c, 0xd6, 0x50,
- 0xf0, 0x85, 0x12, 0x1f, 0x0d, 0xed, 0x98, 0xdf, 0xfe, 0x61, 0x6f, 0x26,
- 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x6f, 0xbf, 0xf9, 0x6f, 0x26, 0x33, 0x8d,
- 0x77, 0x69, 0xa2, 0x7e, 0xbf, 0x9f, 0xb9, 0xe8, 0x09, 0xd7, 0x0b, 0x4e,
- 0xbe, 0xd4, 0xcb, 0xd1, 0xd7, 0xf9, 0xbd, 0x4f, 0x66, 0x2c, 0xeb, 0xb6,
- 0x34, 0xf1, 0x81, 0x54, 0x22, 0x39, 0x05, 0x74, 0x47, 0xe3, 0x1b, 0xfc,
- 0xab, 0x95, 0x81, 0xc9, 0xe3, 0x73, 0xaf, 0xca, 0xca, 0xa3, 0x6f, 0x37,
- 0x3a, 0xfe, 0x56, 0x1e, 0x7e, 0xa2, 0xb9, 0xd7, 0xe5, 0x6d, 0x45, 0x31,
- 0x5c, 0xeb, 0xb6, 0x34, 0xf1, 0x80, 0xdb, 0xa7, 0x52, 0xb2, 0x98, 0x6a,
- 0xb0, 0x7c, 0xa8, 0x34, 0x55, 0xc6, 0xbe, 0x31, 0x01, 0x2d, 0xf2, 0xb7,
- 0xc7, 0xc3, 0xaf, 0x95, 0x53, 0xaf, 0x47, 0x5f, 0xff, 0xca, 0xd8, 0xbf,
- 0xa0, 0x5a, 0x8b, 0x08, 0x1f, 0x92, 0x3a, 0xff, 0x9f, 0xa9, 0xb1, 0x86,
- 0x59, 0x64, 0xab, 0xfd, 0xd7, 0xf7, 0x9d, 0xd9, 0x3a, 0x95, 0x48, 0xf4,
- 0x55, 0xe4, 0xea, 0xd5, 0x75, 0x57, 0x1f, 0x5f, 0xff, 0xe5, 0x65, 0x51,
- 0xae, 0x42, 0x7b, 0xb8, 0x14, 0xd6, 0x0f, 0xe7, 0x5f, 0xca, 0xf1, 0xc7,
- 0x79, 0x1d, 0x7e, 0xea, 0x3f, 0xea, 0xb8, 0xea, 0x56, 0x11, 0x86, 0xab,
- 0x34, 0x78, 0xba, 0xce, 0x75, 0xf9, 0x54, 0xad, 0x3f, 0x52, 0x0e, 0xbf,
- 0xfe, 0x88, 0x88, 0x88, 0x88, 0x88, 0xdf, 0x47, 0x5e, 0x4d, 0xf0, 0xeb,
- 0xf7, 0x12, 0x77, 0x59, 0x57, 0x32, 0xc9, 0x55, 0x86, 0xfd, 0x92, 0x7b,
- 0x00, 0xa6, 0x0d, 0x0d, 0x42, 0x39, 0x7f, 0x49, 0xd3, 0xdd, 0xf9, 0xdc,
- 0x63, 0x68, 0xeb, 0xff, 0xc8, 0x38, 0xb8, 0xd6, 0xb2, 0x5b, 0x78, 0x75,
- 0xff, 0xee, 0xc4, 0x9f, 0x02, 0x9b, 0x35, 0xfb, 0x4e, 0xbf, 0xdc, 0x00,
- 0x83, 0xc0, 0xf1, 0xd7, 0xbb, 0x02, 0x75, 0xa1, 0x0f, 0x37, 0xc6, 0x75,
- 0x08, 0xbe, 0xec, 0x26, 0x2f, 0x0a, 0x41, 0xd7, 0xe8, 0xfa, 0xbe, 0xa1,
- 0xd5, 0xc3, 0xc1, 0x11, 0x9b, 0xfa, 0x5a, 0xf6, 0x0a, 0x87, 0x5e, 0x65,
- 0xd9, 0x3a, 0xff, 0xf7, 0xb8, 0xf3, 0x87, 0xb1, 0xaf, 0x03, 0xa7, 0x5d,
- 0x8b, 0xe9, 0xf4, 0x68, 0x76, 0xfc, 0xed, 0xea, 0x70, 0xeb, 0xff, 0xff,
- 0xc2, 0xea, 0x27, 0x22, 0x5f, 0x3a, 0x8b, 0x0c, 0x7c, 0xdb, 0x07, 0x53,
- 0x87, 0x5f, 0x3c, 0x93, 0x73, 0xaf, 0xfd, 0xd4, 0xf6, 0x73, 0x80, 0x9f,
- 0x61, 0xd7, 0xfc, 0x9e, 0xce, 0x70, 0x13, 0xec, 0x3a, 0xf6, 0x80, 0x3f,
- 0x0f, 0xf3, 0xa8, 0x34, 0x14, 0xe8, 0xb8, 0x5b, 0xd2, 0x61, 0x7d, 0xd4,
- 0x27, 0x6d, 0x07, 0x5f, 0xff, 0x46, 0xf2, 0x71, 0xff, 0xe7, 0xe9, 0xc4,
- 0x50, 0xea, 0xdb, 0x3e, 0x2d, 0xa0, 0xfb, 0xe9, 0xd6, 0x92, 0x3a, 0xfa,
- 0x3f, 0xfa, 0xb3, 0xaf, 0x84, 0x0f, 0x23, 0xa9, 0xa7, 0x89, 0xa2, 0x4b,
- 0xfd, 0xd8, 0x5b, 0x1f, 0xff, 0x07, 0x54, 0x22, 0xf7, 0x19, 0x90, 0x8a,
- 0xfe, 0x99, 0x3b, 0xec, 0x69, 0xd5, 0xc3, 0xda, 0x72, 0xdb, 0xfe, 0xdc,
- 0x3f, 0x61, 0x5f, 0xa0, 0xd1, 0xd7, 0xff, 0xe0, 0xf6, 0x38, 0x9f, 0xc7,
- 0xd8, 0x98, 0x61, 0x67, 0x5f, 0xe5, 0x20, 0x7d, 0xa7, 0xe9, 0xd4, 0x88,
- 0x88, 0x75, 0x6a, 0x84, 0x74, 0x0c, 0x31, 0xef, 0xf7, 0x62, 0x7e, 0x46,
- 0x04, 0xeb, 0xff, 0xe1, 0xcd, 0x8d, 0x7e, 0x4e, 0xfe, 0x7d, 0xff, 0x3a,
- 0xa1, 0x10, 0x8e, 0x65, 0x7f, 0x85, 0xe7, 0xde, 0x51, 0xb4, 0x75, 0xfe,
- 0xd7, 0x5f, 0xef, 0x62, 0x47, 0x54, 0xe7, 0xd5, 0xb9, 0xb5, 0xec, 0xc9,
- 0x8e, 0xbf, 0xe8, 0x90, 0xbf, 0xa4, 0x9b, 0x0e, 0xbd, 0xf6, 0x3f, 0x3a,
- 0xba, 0x7a, 0xda, 0x38, 0xb2, 0xb9, 0xd7, 0xbd, 0x2c, 0x3a, 0xed, 0x61,
- 0xd7, 0xff, 0x6a, 0x38, 0xdf, 0x0e, 0x4e, 0xe2, 0x75, 0x62, 0x29, 0xd0,
- 0x89, 0xc4, 0xff, 0x1b, 0xf0, 0xad, 0xfc, 0x09, 0x81, 0xe8, 0xe9, 0xd7,
- 0xff, 0x06, 0x3c, 0xfa, 0xce, 0xf5, 0x16, 0x75, 0xfe, 0x9c, 0x30, 0xfc,
- 0xfc, 0x07, 0x5e, 0xf2, 0x4c, 0x75, 0x42, 0x24, 0xb1, 0x0b, 0x46, 0x97,
- 0xe8, 0x57, 0x46, 0x5a, 0x75, 0x43, 0x2b, 0xa2, 0x73, 0x09, 0x13, 0x86,
- 0x30, 0x7c, 0x68, 0xdc, 0x85, 0x25, 0x1b, 0xcd, 0x0b, 0x1e, 0x46, 0x7e,
- 0xb8, 0xc2, 0x7b, 0x0a, 0xa7, 0x84, 0x5f, 0xe4, 0x83, 0x18, 0xc6, 0x92,
- 0x3d, 0x0c, 0x0f, 0xa5, 0xd7, 0xff, 0xfc, 0xab, 0xd5, 0x51, 0x8a, 0xd7,
- 0x8a, 0xa5, 0x5b, 0x62, 0xba, 0xae, 0x07, 0xcf, 0x9d, 0xdb, 0x3a, 0xf4,
- 0xdf, 0x56, 0x75, 0xff, 0x67, 0xb5, 0x9e, 0xee, 0x7e, 0x75, 0x39, 0xeb,
- 0x88, 0xfd, 0xce, 0x27, 0x57, 0x0d, 0xa2, 0xc8, 0x2f, 0xa3, 0xd8, 0xb3,
- 0xaf, 0xde, 0x81, 0x4f, 0xce, 0xbf, 0xb1, 0x97, 0xfd, 0x78, 0x75, 0x7c,
- 0x3f, 0x3c, 0x20, 0x12, 0x6b, 0xf7, 0x27, 0x8f, 0x68, 0xeb, 0xe7, 0xe3,
- 0xc8, 0xeb, 0x73, 0x0f, 0x20, 0x4a, 0x2f, 0x32, 0xcb, 0x27, 0x5f, 0x4e,
- 0x29, 0x05, 0x30, 0x5f, 0xdf, 0xf2, 0xbf, 0x5c, 0x64, 0x18, 0x9c, 0xeb,
- 0xb7, 0x91, 0xd7, 0xf9, 0x48, 0xf6, 0xba, 0xe0, 0x3a, 0xfc, 0x93, 0xe6,
- 0xfe, 0x3a, 0xe4, 0x69, 0xd5, 0x08, 0x87, 0x50, 0x5d, 0x66, 0x7e, 0x28,
- 0xbf, 0x28, 0xfa, 0xd9, 0x23, 0xab, 0x73, 0xe7, 0xf1, 0xed, 0x2a, 0xca,
- 0xfa, 0xa2, 0x31, 0xe0, 0xc2, 0x51, 0x1d, 0xfa, 0x8a, 0xe6, 0x00, 0x8c,
- 0xa6, 0xff, 0xed, 0x8c, 0xe6, 0x85, 0x23, 0x99, 0x39, 0xd7, 0xff, 0xff,
- 0xfe, 0x57, 0xf9, 0xdc, 0xde, 0x5d, 0x5f, 0xc6, 0xf4, 0x1e, 0xf6, 0x0f,
- 0x73, 0xd0, 0x1f, 0x9f, 0x3b, 0xb6, 0x75, 0xff, 0x07, 0x00, 0xa9, 0x4e,
- 0xba, 0xce, 0xbf, 0x42, 0xc7, 0x26, 0x3b, 0x0d, 0xdd, 0xed, 0x98, 0x13,
- 0xaf, 0xf2, 0x9d, 0x48, 0x10, 0x41, 0xd5, 0xd3, 0xce, 0x71, 0xda, 0x0a,
- 0x29, 0x35, 0x08, 0x3b, 0xfa, 0x25, 0xd8, 0xd8, 0x87, 0x5f, 0x9f, 0x80,
- 0x7d, 0x1d, 0x74, 0xbc, 0x75, 0xf4, 0xd1, 0xe7, 0x3a, 0xf8, 0x1f, 0xe0,
- 0xb4, 0xdb, 0x80, 0x5a, 0xd2, 0x3a, 0xa7, 0x3c, 0x8e, 0x9c, 0x5f, 0xfd,
- 0x1d, 0xfa, 0x1f, 0x26, 0x4d, 0x0b, 0x3a, 0xfa, 0x3c, 0x05, 0x9d, 0x46,
- 0x88, 0x3a, 0xfe, 0x79, 0xff, 0x71, 0x09, 0x2b, 0x06, 0xdb, 0x4d, 0x3d,
- 0x2d, 0xb1, 0x7a, 0x5a, 0x27, 0xbc, 0xe7, 0x7f, 0xfe, 0x5e, 0x9e, 0x5d,
- 0x4c, 0xf6, 0xb9, 0x81, 0xc3, 0xaf, 0xfa, 0x3c, 0x39, 0xb0, 0x73, 0x47,
- 0x54, 0x22, 0xb7, 0x08, 0xf4, 0xa7, 0x7f, 0x3f, 0x61, 0x5c, 0x12, 0x3a,
- 0xa4, 0xab, 0x89, 0xa5, 0xbc, 0x85, 0x2a, 0xc8, 0xfd, 0x1c, 0x86, 0xc2,
- 0xeb, 0xfa, 0x43, 0x9b, 0xfb, 0x0e, 0xbf, 0xff, 0x7d, 0xff, 0xf8, 0xdf,
- 0x27, 0x0b, 0xbb, 0x5c, 0x27, 0x54, 0x22, 0x17, 0x85, 0x97, 0xf9, 0xc7,
- 0xd2, 0xce, 0x61, 0xd7, 0xf0, 0xa7, 0xfa, 0xea, 0x1d, 0x77, 0x02, 0x75,
- 0xcc, 0xb2, 0x75, 0x48, 0xd7, 0x32, 0x2d, 0x7a, 0x13, 0x61, 0x4c, 0x1a,
- 0x2a, 0x74, 0x54, 0xe9, 0xf2, 0xef, 0xf4, 0x75, 0xfc, 0x9d, 0x45, 0x14,
- 0x83, 0xae, 0xd7, 0xd0, 0x9e, 0x27, 0x85, 0xe9, 0x11, 0x2d, 0xf5, 0x9a,
- 0xf3, 0x2c, 0xb2, 0x55, 0x14, 0xc1, 0x7f, 0x7c, 0x8c, 0xa4, 0xc5, 0x53,
- 0x4d, 0xe2, 0x0d, 0x5f, 0xb3, 0x91, 0xb3, 0x0e, 0xa8, 0x64, 0x0d, 0x4e,
- 0x8b, 0x91, 0xc4, 0xa4, 0xb0, 0xae, 0x43, 0xad, 0x64, 0x5d, 0x8d, 0xbc,
- 0x5f, 0xf4, 0x41, 0x7d, 0xc9, 0x03, 0x0e, 0xbf, 0xc3, 0xbf, 0xbe, 0xf5,
- 0xff, 0x3a, 0xf0, 0xa6, 0x8e, 0xbe, 0x0b, 0x8f, 0xe7, 0x5f, 0xfd, 0x03,
- 0xf8, 0xc6, 0xf3, 0x40, 0xfe, 0x75, 0x62, 0x2d, 0x50, 0xdb, 0xf1, 0xad,
- 0x10, 0xd9, 0x0e, 0xbf, 0xe7, 0x51, 0xbd, 0x40, 0xbc, 0x8e, 0xbe, 0x9e,
- 0x77, 0xdc, 0xeb, 0xbf, 0xd2, 0x1f, 0x58, 0x87, 0xfd, 0x38, 0xbf, 0x46,
- 0x73, 0xa8, 0x75, 0xff, 0xe6, 0x7f, 0xee, 0x64, 0xe9, 0x9b, 0x23, 0x73,
- 0xaf, 0xff, 0x7f, 0x0b, 0xe7, 0x22, 0x7f, 0x3b, 0xa8, 0x75, 0xfe, 0x96,
- 0x77, 0x17, 0x0d, 0x3a, 0xf6, 0x2d, 0x5c, 0xeb, 0xfd, 0x9a, 0x1c, 0xf7,
- 0x50, 0xea, 0x09, 0xe7, 0x08, 0xf5, 0x62, 0x73, 0x33, 0x1e, 0x74, 0x97,
- 0xf4, 0xdf, 0x25, 0xec, 0x7f, 0xbf, 0xbd, 0x93, 0x0c, 0x2c, 0xf1, 0x01,
- 0x5f, 0x9c, 0x43, 0xd8, 0x34, 0x40, 0x4c, 0x1b, 0x9b, 0xff, 0x93, 0x7d,
- 0x07, 0x06, 0x04, 0x10, 0x75, 0xff, 0xc0, 0x6a, 0x9c, 0xcd, 0xf5, 0xfb,
- 0xf8, 0xeb, 0xf4, 0x49, 0xf7, 0x64, 0xea, 0xc4, 0x58, 0x22, 0x0f, 0x11,
- 0xed, 0x39, 0xd7, 0xef, 0x99, 0x32, 0x2c, 0xeb, 0xff, 0xc0, 0x8f, 0x9b,
- 0x5e, 0x4d, 0x77, 0x77, 0x64, 0xea, 0x9c, 0xfe, 0x74, 0x53, 0x7f, 0xec,
- 0x0f, 0x5d, 0x88, 0xec, 0x6e, 0x75, 0x2a, 0x11, 0xd7, 0xc8, 0x45, 0x2c,
- 0x8e, 0xff, 0xc8, 0x2a, 0x70, 0x51, 0xa0, 0x13, 0xaf, 0xff, 0xcf, 0xbe,
- 0xfa, 0x81, 0xf7, 0xd9, 0xba, 0x9e, 0xd1, 0xd5, 0x08, 0xce, 0xc3, 0x90,
- 0x1e, 0x5f, 0x2e, 0x31, 0x67, 0x5f, 0xfb, 0x17, 0x0d, 0x4f, 0x70, 0x0b,
- 0x3a, 0xf2, 0x6f, 0xa3, 0xad, 0x12, 0x3d, 0x9f, 0xcf, 0x6f, 0xf7, 0x26,
- 0xd2, 0x0f, 0x90, 0xeb, 0xfd, 0xd4, 0xdf, 0xfe, 0x38, 0x4e, 0xbe, 0xdf,
- 0xfe, 0x41, 0x57, 0x32, 0xc9, 0x55, 0x06, 0xed, 0x92, 0x3b, 0x85, 0x0a,
- 0x60, 0xd0, 0xde, 0x7e, 0x4b, 0xe2, 0x2d, 0x65, 0x09, 0x0a, 0x56, 0xd9,
- 0x0e, 0xb1, 0x0d, 0x6c, 0x94, 0x80, 0x90, 0x94, 0xe4, 0x3c, 0xfb, 0x1f,
- 0x3b, 0x97, 0x0b, 0xcf, 0x8a, 0x01, 0x0e, 0x7b, 0xd3, 0xba, 0xce, 0xbd,
- 0xe4, 0x64, 0xf1, 0x84, 0x5f, 0x78, 0x0f, 0xf4, 0xd1, 0x03, 0xee, 0x6a,
- 0x69, 0xd1, 0x0c, 0x04, 0x5b, 0xca, 0xe9, 0xf9, 0xd7, 0x40, 0x0e, 0xbf,
- 0x00, 0x7f, 0xfb, 0x23, 0xaf, 0xff, 0x87, 0x35, 0xf3, 0xef, 0x63, 0xf5,
- 0xbc, 0xbe, 0x61, 0xbf, 0xd0, 0xad, 0x01, 0x19, 0x3b, 0x17, 0xaf, 0xfd,
- 0xd0, 0x4f, 0x1f, 0x23, 0xd0, 0x13, 0xaf, 0x3f, 0x27, 0x3a, 0xe6, 0x59,
- 0x3a, 0xff, 0x71, 0x33, 0x67, 0xd9, 0x30, 0xd3, 0x68, 0xc8, 0xe5, 0xff,
- 0x91, 0x4f, 0x9a, 0x07, 0xeb, 0x89, 0x1d, 0x7f, 0xb5, 0x9e, 0x75, 0xe0,
- 0x9d, 0x41, 0x4c, 0xd7, 0x8e, 0x9d, 0x4f, 0xf2, 0x15, 0xff, 0xc3, 0x8a,
- 0x75, 0xe5, 0xf5, 0xf7, 0x83, 0xaa, 0x11, 0x07, 0x87, 0xd7, 0xff, 0x2d,
- 0x6f, 0x2c, 0xe3, 0x5d, 0xda, 0x68, 0x86, 0x2f, 0xff, 0xff, 0x3e, 0xb0,
- 0x71, 0xbd, 0x8d, 0xe5, 0xb7, 0x9d, 0x6a, 0x60, 0xba, 0x87, 0x56, 0x23,
- 0x18, 0x09, 0xf4, 0x8a, 0xb9, 0xbb, 0x1e, 0xe8, 0xc3, 0x9e, 0xff, 0x2f,
- 0xaf, 0x38, 0xc4, 0x8a, 0xbb, 0x40, 0x3a, 0xfe, 0x97, 0x5d, 0xc6, 0x0e,
- 0xb4, 0x34, 0xf0, 0x37, 0x16, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x41, 0x57,
- 0xbb, 0x0b, 0x3a, 0xff, 0xd1, 0x3b, 0xfb, 0x99, 0x2d, 0xbc, 0x3a, 0xb1,
- 0x11, 0xc8, 0x66, 0x23, 0x77, 0xee, 0xc2, 0xc1, 0xb9, 0xd7, 0xde, 0xd4,
- 0x7e, 0x55, 0xe7, 0xe4, 0xe5, 0x5f, 0x00, 0x5d, 0x42, 0xaf, 0xf2, 0x4f,
- 0x9e, 0xd4, 0x7e, 0x55, 0x15, 0x7f, 0x63, 0x63, 0xb0, 0xb2, 0xae, 0x65,
- 0x92, 0xaf, 0xe1, 0x81, 0x9d, 0x38, 0x55, 0x62, 0x61, 0x4d, 0x22, 0x58,
- 0xe7, 0x48, 0x7f, 0x33, 0x10, 0xa6, 0x4a, 0xfe, 0x8c, 0x5c, 0x9c, 0x29,
- 0x83, 0xf4, 0xa9, 0x27, 0xf5, 0x31, 0x6f, 0x63, 0xa6, 0xa8, 0x56, 0xb5,
- 0xd7, 0x27, 0x95, 0x61, 0x7f, 0x60, 0xe9, 0x07, 0x0e, 0xbd, 0xd0, 0x2c,
- 0xea, 0xe9, 0xe2, 0xed, 0x14, 0xdf, 0xe7, 0x1c, 0xd7, 0x23, 0x47, 0x5f,
- 0xc1, 0xc1, 0x7f, 0x68, 0xeb, 0x44, 0x8f, 0x6f, 0x46, 0x17, 0xee, 0x6f,
- 0x2c, 0xf1, 0xd7, 0xff, 0xfd, 0xd4, 0xe6, 0x05, 0xd7, 0x83, 0xe1, 0x86,
- 0x73, 0xda, 0x3a, 0xd0, 0x75, 0xfb, 0xb1, 0xb0, 0x30, 0xd3, 0xf2, 0xfd,
- 0x8e, 0xb8, 0x8d, 0xbf, 0x42, 0x6a, 0xff, 0x6f, 0x2d, 0xb8, 0x6e, 0x2c,
- 0xeb, 0xff, 0xff, 0x73, 0x91, 0xbc, 0xb7, 0xd2, 0x71, 0xbd, 0xcf, 0xbc,
- 0x48, 0x09, 0xd5, 0x08, 0xa5, 0xc3, 0x6b, 0xff, 0xf3, 0x54, 0x7d, 0x67,
- 0x24, 0x9d, 0x71, 0xde, 0x47, 0x5f, 0xf9, 0xb1, 0xed, 0x67, 0x93, 0x76,
- 0x4e, 0xb3, 0xe2, 0x25, 0x14, 0x55, 0xa8, 0x4e, 0xab, 0xb0, 0xcd, 0x18,
- 0x5a, 0xde, 0xf3, 0xfe, 0x75, 0xff, 0xf9, 0xde, 0x4f, 0xdf, 0x99, 0x38,
- 0x3c, 0x07, 0xfa, 0x68, 0xbe, 0xef, 0x7f, 0x01, 0x3a, 0xff, 0xda, 0x41,
- 0xde, 0x5c, 0x04, 0x68, 0xea, 0x99, 0x17, 0xfc, 0x65, 0xf0, 0xe5, 0xfe,
- 0x89, 0xfb, 0x93, 0x42, 0xb9, 0xd6, 0x69, 0xd7, 0xff, 0xfb, 0xf4, 0xe2,
- 0x9d, 0x85, 0xcd, 0x24, 0x1e, 0xc7, 0x20, 0xeb, 0x7b, 0x0f, 0xc7, 0x42,
- 0x17, 0xde, 0x1c, 0x91, 0xd5, 0x07, 0x8e, 0x84, 0xf7, 0xfe, 0x14, 0x97,
- 0xbb, 0x9c, 0x4d, 0x1d, 0x7f, 0x44, 0x87, 0x32, 0x73, 0xaf, 0xf3, 0x86,
- 0x3f, 0x86, 0x74, 0x75, 0x74, 0xf7, 0x9c, 0xae, 0xfe, 0xdb, 0x56, 0xbf,
- 0x3e, 0x77, 0x6c, 0xf1, 0x00, 0xdf, 0xef, 0x7f, 0xf4, 0x65, 0xdc, 0x3c,
- 0x40, 0x37, 0x9f, 0x92, 0x3c, 0x40, 0x35, 0x87, 0xd4, 0x04, 0x2b, 0x9e,
- 0x47, 0x88, 0x06, 0xf9, 0xc7, 0x79, 0x1e, 0x20, 0x1b, 0xfc, 0x8d, 0xee,
- 0x7f, 0xfc, 0x1e, 0x20, 0x1b, 0xc8, 0x21, 0x3c, 0x40, 0x34, 0x14, 0x5b,
- 0xac, 0x8b, 0xa5, 0xdb, 0x10, 0x2c, 0xa1, 0xe2, 0x01, 0xbd, 0xc8, 0xf1,
- 0xe2, 0x01, 0xa3, 0xc4, 0x03, 0x7b, 0x6d, 0x3f, 0x3c, 0x40, 0x37, 0x42,
- 0xcf, 0x10, 0x0d, 0x04, 0xf9, 0x70, 0x5d, 0x0b, 0x2f, 0x91, 0x61, 0x83,
- 0xc4, 0x03, 0x7b, 0xce, 0xd3, 0xc4, 0x03, 0x7f, 0xe1, 0x79, 0x31, 0xd4,
- 0x6b, 0xf0, 0xf1, 0x00, 0xdf, 0xfc, 0xfe, 0x04, 0xe8, 0x3e, 0xeb, 0xc8,
- 0xf1, 0x00, 0xdc, 0xe1, 0x3c, 0x40, 0x37, 0xf8, 0x5d, 0x9d, 0x6a, 0x3f,
- 0x3c, 0x40, 0x37, 0xe4, 0x51, 0xc7, 0xf3, 0xc4, 0x03, 0x72, 0x68, 0xf1,
- 0x00, 0xd7, 0x0f, 0x5b, 0xc6, 0x97, 0xff, 0xba, 0x9e, 0xf6, 0x6b, 0xe7,
- 0x12, 0x16, 0x78, 0x80, 0x6f, 0xde, 0x18, 0xde, 0x46, 0x88, 0x06, 0xef,
- 0xe0, 0xf1, 0x00, 0xb0, 0x6d, 0x2f, 0xc9, 0x0b, 0x70, 0x9e, 0x20, 0x1b,
- 0xe0, 0x38, 0xb4, 0xf1, 0x00, 0xde, 0x8e, 0x34, 0xf1, 0x00, 0xdf, 0xfb,
- 0x37, 0xd0, 0x63, 0x07, 0xfd, 0x1e, 0x20, 0x1b, 0xf0, 0x1e, 0x52, 0x83,
- 0xc4, 0x03, 0x7e, 0x76, 0xf6, 0x37, 0x3c, 0x40, 0x35, 0x88, 0xb2, 0xea,
- 0x58, 0x0c, 0xee, 0xe7, 0xe7, 0x88, 0x06, 0xa4, 0xac, 0x94, 0x24, 0x59,
- 0x09, 0x66, 0x91, 0x24, 0x22, 0xfa, 0x69, 0xf9, 0x96, 0x8b, 0x7d, 0x0d,
- 0xa0, 0x17, 0xdf, 0xb3, 0xda, 0x7d, 0xcf, 0x10, 0x0d, 0xfe, 0x0c, 0x36,
- 0x6e, 0x47, 0x8f, 0x10, 0x08, 0x4d, 0xa5, 0xee, 0x43, 0x27, 0x88, 0x06,
- 0x9a, 0x7f, 0x3c, 0x50, 0xbf, 0xc0, 0x79, 0x4a, 0x3e, 0xac, 0xf1, 0x00,
- 0xdf, 0x20, 0xcb, 0x47, 0x88, 0x06, 0xfe, 0x79, 0xa5, 0x9b, 0xc8, 0xf1,
- 0x00, 0xd6, 0x23, 0x2f, 0xa4, 0x5f, 0xa0, 0x80, 0xb6, 0xff, 0xbb, 0x1a,
- 0x63, 0x40, 0xe7, 0xe7, 0x88, 0x06, 0xc8, 0x78, 0x80, 0x6e, 0x79, 0xc2,
- 0x7c, 0x9d, 0x48, 0xbb, 0x9f, 0x9e, 0x20, 0x1b, 0xf3, 0xfb, 0x49, 0xb9,
- 0xe2, 0x01, 0xbf, 0x90, 0x41, 0x2c, 0xd1, 0xe2, 0x01, 0xa8, 0x44, 0x80,
- 0x92, 0x78, 0xd2, 0xa1, 0x94, 0xb0, 0x18, 0x5a, 0xe4, 0x36, 0x10, 0xfe,
- 0x61, 0xee, 0x42, 0x37, 0xa5, 0xae, 0x5b, 0xf9, 0x40, 0xa5, 0x6a, 0x5b,
- 0xaf, 0xa5, 0x09, 0xed, 0xc2, 0x87, 0xec, 0x2f, 0xaf, 0x79, 0x19, 0x3c,
- 0x61, 0x37, 0x9d, 0xda, 0x68, 0x80, 0x58, 0x4c, 0x57, 0x78, 0x76, 0x5f,
- 0x28, 0xad, 0x02, 0xb3, 0xae, 0xd9, 0x39, 0xd7, 0xed, 0x83, 0x01, 0xe9,
- 0xd5, 0x07, 0x82, 0x83, 0x37, 0xff, 0x48, 0x71, 0xbd, 0x4f, 0xff, 0x04,
- 0xc7, 0x5d, 0xfc, 0x15, 0x65, 0x0a, 0xbd, 0xd8, 0x9c, 0xeb, 0x99, 0x64,
- 0xaa, 0x43, 0xdb, 0x57, 0x16, 0x98, 0x45, 0x91, 0xcb, 0xcb, 0x4d, 0x14,
- 0xc1, 0xe0, 0x5e, 0x40, 0x78, 0xeb, 0xff, 0xde, 0xd6, 0x28, 0x9c, 0xfb,
- 0xff, 0xf1, 0xb9, 0xd5, 0x3b, 0x3a, 0x62, 0x44, 0x01, 0x84, 0xd3, 0x69,
- 0x71, 0xc8, 0x9d, 0xc6, 0xa7, 0x20, 0xfe, 0x1c, 0x3e, 0x2d, 0xfa, 0x37,
- 0x7f, 0xf8, 0x7d, 0xb7, 0x93, 0x49, 0xf9, 0x38, 0x60, 0xeb, 0xfb, 0xdf,
- 0x76, 0x6c, 0x8d, 0x1d, 0x7f, 0xb3, 0x7f, 0x79, 0xe5, 0xa3, 0xaf, 0x0e,
- 0xf2, 0x3c, 0x60, 0x15, 0x88, 0xdc, 0x44, 0xde, 0x19, 0xb9, 0x9d, 0xfa,
- 0x69, 0x47, 0x27, 0x3a, 0xfa, 0x14, 0x85, 0x9d, 0x5c, 0x3c, 0xa5, 0x94,
- 0xdf, 0xfa, 0x5a, 0xf8, 0x38, 0xb8, 0xe2, 0x87, 0x5f, 0xd2, 0x8e, 0x7f,
- 0xf5, 0x67, 0x5f, 0xfd, 0xb0, 0x73, 0x5e, 0xc1, 0x96, 0x68, 0xeb, 0xe5,
- 0xc0, 0x3c, 0x75, 0x61, 0xf2, 0x3a, 0x1d, 0xdd, 0x7c, 0x45, 0xa0, 0xc2,
- 0x52, 0xff, 0xa1, 0xb0, 0xb4, 0x5f, 0xe8, 0x75, 0x70, 0xfa, 0x36, 0x8c,
- 0x6f, 0xef, 0xac, 0xf1, 0x33, 0xa5, 0x5f, 0xfd, 0xf8, 0xa6, 0x6f, 0xe9,
- 0xa4, 0xfc, 0x3a, 0xfa, 0x6e, 0xbc, 0xc7, 0x5f, 0x35, 0xf9, 0x39, 0xd7,
- 0xec, 0x9a, 0x51, 0xb9, 0xd7, 0xba, 0x93, 0x1d, 0x78, 0x62, 0x45, 0x5f,
- 0xf8, 0x7f, 0x4d, 0xad, 0xa0, 0x4a, 0x15, 0xce, 0xac, 0x3e, 0x17, 0x1a,
- 0xad, 0xd3, 0x4f, 0xe2, 0x2f, 0x48, 0xc4, 0x8b, 0xc5, 0x1b, 0x4f, 0xb5,
- 0x0a, 0xdf, 0x30, 0x89, 0x23, 0x5c, 0xe9, 0x2b, 0xc6, 0xfd, 0x7f, 0x6f,
- 0xae, 0x72, 0x3c, 0x75, 0xfd, 0x2d, 0x29, 0xc7, 0x69, 0xd7, 0x87, 0xda,
- 0x3a, 0xfd, 0xa0, 0x08, 0x1a, 0x75, 0x41, 0xf8, 0x21, 0x70, 0x06, 0xef,
- 0xfe, 0xeb, 0x31, 0xcd, 0x63, 0x2f, 0xc5, 0x0e, 0xbf, 0x60, 0x43, 0x8b,
- 0x3a, 0xff, 0xf7, 0xb7, 0x6a, 0x77, 0x6e, 0x3d, 0xdf, 0xba, 0x3a, 0xe5,
- 0x4e, 0x8e, 0xbe, 0x14, 0xde, 0x47, 0x5f, 0xf2, 0x6f, 0xdc, 0x0f, 0x1d,
- 0xa7, 0x54, 0x1e, 0xcf, 0x08, 0x6f, 0xfb, 0xb1, 0xc8, 0x6a, 0x0b, 0x4e,
- 0xbe, 0xf2, 0x8f, 0xae, 0x1e, 0xbe, 0xd1, 0x0d, 0x49, 0x3c, 0x3e, 0x23,
- 0x2c, 0x98, 0x0a, 0x0c, 0xc3, 0x2a, 0xfd, 0xb4, 0x05, 0xe0, 0x4e, 0xbf,
- 0xf7, 0x73, 0x69, 0xc5, 0x4c, 0xdf, 0xc7, 0x5f, 0xf6, 0x37, 0xa8, 0x1e,
- 0x81, 0x43, 0xaf, 0x7b, 0x1a, 0x75, 0x2c, 0xf5, 0x34, 0x73, 0x7a, 0x4b,
- 0xfc, 0xea, 0x51, 0x1a, 0x9f, 0xc2, 0x57, 0xc4, 0x57, 0xfc, 0xa3, 0xfc,
- 0x85, 0x8a, 0x28, 0x75, 0xff, 0x9f, 0x4b, 0x84, 0xe7, 0x11, 0x93, 0xad,
- 0xa5, 0x0f, 0xdf, 0xa7, 0x57, 0xfd, 0x9e, 0xf2, 0x29, 0xec, 0x69, 0xd7,
- 0xf8, 0x31, 0xbe, 0xb3, 0x7f, 0x1d, 0x7f, 0xd1, 0xe4, 0x6a, 0x06, 0x3c,
- 0x75, 0xb4, 0x14, 0x51, 0x61, 0xc7, 0x0d, 0x2b, 0x74, 0xc0, 0x3d, 0x0c,
- 0xbb, 0xfe, 0xf2, 0x4f, 0x1b, 0xff, 0xc8, 0x3a, 0xf6, 0xbd, 0x87, 0x5d,
- 0x9a, 0xf8, 0x7a, 0xbf, 0x4e, 0xaf, 0xfe, 0xcf, 0x26, 0xf2, 0x18, 0x55,
- 0x2a, 0xfd, 0xb3, 0xaf, 0xd9, 0xef, 0xdf, 0xc7, 0x54, 0x8f, 0xdf, 0x6d,
- 0x42, 0xff, 0xfd, 0x1d, 0x7c, 0x18, 0xe2, 0x81, 0x03, 0xf2, 0x47, 0x54,
- 0x93, 0x20, 0xf4, 0x2a, 0x36, 0x89, 0x6a, 0x17, 0x35, 0x71, 0x45, 0x21,
- 0xfc, 0xf1, 0xd7, 0x02, 0x39, 0xfb, 0xee, 0xa3, 0xc8, 0xeb, 0xfd, 0x83,
- 0x2c, 0xd7, 0xd5, 0x9d, 0x7e, 0x5e, 0xbf, 0x77, 0x3a, 0xbc, 0x7b, 0x5f,
- 0x4c, 0xef, 0xfb, 0x98, 0x3f, 0x3b, 0x9b, 0xb2, 0x75, 0xff, 0x48, 0x41,
- 0xff, 0xc6, 0xaf, 0xf3, 0xaa, 0x74, 0xc5, 0xa4, 0xf5, 0x84, 0x9b, 0x9d,
- 0xdf, 0xf0, 0xc6, 0x6f, 0xec, 0xe4, 0x1d, 0x50, 0x7e, 0xae, 0x7f, 0x7e,
- 0x7d, 0x81, 0x0c, 0x1d, 0x76, 0xb4, 0x75, 0xe6, 0x59, 0x64, 0xeb, 0xbf,
- 0x72, 0x98, 0x2f, 0xeb, 0x87, 0xb7, 0xa3, 0x5b, 0xff, 0x66, 0x85, 0xd4,
- 0x98, 0x52, 0x63, 0xaf, 0xef, 0xe2, 0x5d, 0xfb, 0xa3, 0xaf, 0x3f, 0xf8,
- 0x55, 0x49, 0x32, 0xe5, 0xc2, 0x0f, 0xa4, 0x5f, 0x9f, 0x6d, 0x98, 0x5f,
- 0x40, 0x50, 0x27, 0x5f, 0x83, 0xc4, 0x04, 0xe7, 0x5f, 0xe6, 0x70, 0x73,
- 0x62, 0x70, 0xeb, 0xf8, 0x73, 0x7f, 0xfe, 0xc8, 0xea, 0x99, 0x11, 0x62,
- 0x51, 0xe3, 0x3b, 0x9d, 0x67, 0x5f, 0xec, 0xd9, 0x8c, 0x32, 0xcb, 0x25,
- 0x5f, 0xa6, 0x8c, 0xee, 0x8e, 0xa1, 0x3d, 0xff, 0xa7, 0x17, 0xf9, 0x53,
- 0x00, 0x6f, 0x53, 0x87, 0x5e, 0x5b, 0xf8, 0xea, 0x99, 0x1d, 0x1d, 0x74,
- 0x01, 0x1e, 0xc3, 0x6b, 0xf8, 0x76, 0x3a, 0xd1, 0x67, 0x5f, 0xb2, 0x69,
- 0x44, 0x8e, 0xbf, 0xa7, 0x0c, 0x60, 0x84, 0xea, 0x85, 0x5a, 0xf2, 0x54,
- 0x48, 0x55, 0xbc, 0x63, 0x1a, 0x40, 0xf1, 0x6f, 0xd2, 0x7b, 0xcf, 0xfa,
- 0x1d, 0x7f, 0xc1, 0x10, 0x6b, 0x27, 0xc9, 0xce, 0xbd, 0x1c, 0x13, 0xaf,
- 0xf6, 0x04, 0x5f, 0x48, 0x13, 0xad, 0xd3, 0xaf, 0x01, 0xe7, 0x13, 0xc0,
- 0xd1, 0x85, 0x93, 0x88, 0x8d, 0xf2, 0xd5, 0x2d, 0x30, 0x97, 0x1b, 0x54,
- 0xc3, 0x1a, 0xff, 0xf6, 0x05, 0xd7, 0x9b, 0xcb, 0x3f, 0xc0, 0x9d, 0x77,
- 0x5c, 0xeb, 0xa6, 0xd1, 0xd7, 0xec, 0xd8, 0x82, 0x1c, 0x35, 0x9f, 0x45,
- 0x6f, 0xdd, 0xcd, 0xfd, 0x07, 0x5f, 0xb6, 0x9e, 0x7f, 0xb2, 0x3a, 0xbe,
- 0x26, 0x10, 0xc3, 0xae, 0x1f, 0x80, 0x9e, 0xf8, 0x39, 0xd7, 0x3a, 0xff,
- 0xe8, 0xc1, 0x97, 0x70, 0x46, 0x19, 0x3a, 0xb8, 0x8a, 0x01, 0x40, 0xf1,
- 0x05, 0xfe, 0xe6, 0xbb, 0x82, 0x9a, 0x3a, 0x90, 0xf8, 0x1c, 0xbe, 0xff,
- 0xb0, 0x38, 0x30, 0x20, 0x83, 0xae, 0x86, 0x4e, 0xa9, 0xdd, 0x99, 0xf4,
- 0xa5, 0xe8, 0x86, 0x5c, 0xae, 0x3e, 0x29, 0x08, 0x06, 0xca, 0xac, 0xdc,
- 0xe5, 0x21, 0xb7, 0x31, 0x8f, 0x29, 0xf0, 0xcb, 0x8e, 0x03, 0xb3, 0x80,
- 0x0e, 0xa9, 0xfc, 0x27, 0x86, 0x7b, 0x17, 0x51, 0xf2, 0xfa, 0x70, 0x94,
- 0x11, 0xbc, 0xec, 0x94, 0x83, 0xf4, 0x83, 0x68, 0xd2, 0xff, 0xb3, 0x83,
- 0x1e, 0x96, 0x74, 0xeb, 0xf8, 0x7f, 0xc0, 0xbc, 0x8e, 0xbf, 0xff, 0x03,
- 0xda, 0x6f, 0x50, 0x63, 0x7d, 0x22, 0xe0, 0xeb, 0xfc, 0xd1, 0xc9, 0x49,
- 0xf4, 0x75, 0xfc, 0xec, 0xe7, 0xff, 0x7c, 0x75, 0xf9, 0xe5, 0xf0, 0x28,
- 0x75, 0xe9, 0x47, 0xe7, 0x5f, 0xbe, 0xcd, 0x28, 0x57, 0x2a, 0xa1, 0x38,
- 0x8c, 0x36, 0x50, 0xb1, 0x15, 0x38, 0x63, 0xd3, 0x0f, 0x14, 0x7d, 0x1c,
- 0xb3, 0x4e, 0xbf, 0xf9, 0x41, 0x03, 0xfd, 0xcd, 0x24, 0x09, 0xd7, 0xb6,
- 0xd0, 0x27, 0x57, 0x0f, 0x85, 0x68, 0x77, 0xff, 0x6f, 0xe0, 0x2f, 0xb0,
- 0x82, 0xe1, 0x3a, 0xf9, 0x4e, 0x3b, 0x27, 0x5b, 0xe9, 0xa2, 0x05, 0xb7,
- 0x8d, 0x40, 0xa5, 0x78, 0xde, 0x32, 0x3f, 0x58, 0x88, 0x14, 0x5f, 0xbf,
- 0xf2, 0x6d, 0xf5, 0x3e, 0xb1, 0xff, 0xf0, 0x55, 0xff, 0x0f, 0xb4, 0x0d,
- 0xfc, 0x8c, 0x9d, 0x7f, 0x80, 0xfa, 0xcc, 0x15, 0x0e, 0xa8, 0x3e, 0xbe,
- 0x9d, 0x5f, 0xfe, 0x45, 0x3e, 0x0b, 0xa9, 0xf3, 0x5f, 0xff, 0x07, 0x5f,
- 0xe7, 0xee, 0xfa, 0x81, 0xf1, 0xd5, 0xa4, 0x41, 0x79, 0x42, 0xff, 0x9b,
- 0xd4, 0x9a, 0x50, 0x32, 0x3a, 0xfa, 0x5d, 0xc9, 0xce, 0xbf, 0xe8, 0xdd,
- 0x6f, 0xec, 0xdf, 0xc7, 0x56, 0xe7, 0xb6, 0x24, 0x57, 0xfd, 0x0d, 0xf0,
- 0x3b, 0xc8, 0x64, 0xeb, 0xb8, 0xe7, 0x5f, 0xff, 0xd1, 0xcf, 0xf3, 0x62,
- 0x6b, 0x58, 0x2d, 0x71, 0xfc, 0xea, 0xe1, 0xf8, 0x74, 0x56, 0xff, 0xcf,
- 0xbe, 0xb3, 0xc8, 0xb7, 0x91, 0xd6, 0xf1, 0xd5, 0xf9, 0xe6, 0xfd, 0x3d,
- 0xbf, 0xff, 0xf8, 0x1a, 0xeb, 0xcb, 0x52, 0x4f, 0x7d, 0xe4, 0x76, 0x3d,
- 0xa7, 0xdc, 0xeb, 0xf4, 0x60, 0xfb, 0x6c, 0xeb, 0xf9, 0x37, 0xff, 0x8e,
- 0x13, 0xac, 0xb3, 0xa9, 0x67, 0xcd, 0xd2, 0x81, 0x2e, 0xbd, 0x20, 0x04,
- 0xeb, 0x9f, 0x7f, 0x87, 0x94, 0xe5, 0xd5, 0xc4, 0xd4, 0xf5, 0x19, 0x25,
- 0xff, 0xfd, 0x83, 0x3e, 0xb5, 0x1f, 0xe7, 0x53, 0x8e, 0xcf, 0x8e, 0xa0,
- 0xae, 0x48, 0x6f, 0x0a, 0x39, 0x88, 0xf9, 0x09, 0x35, 0x91, 0x76, 0x15,
- 0x3f, 0xb7, 0xfa, 0x37, 0x86, 0x4a, 0xaa, 0x17, 0x76, 0x92, 0x75, 0x02,
- 0xff, 0xff, 0xb9, 0x3e, 0x24, 0xce, 0xf2, 0xd4, 0x2c, 0x3d, 0x81, 0x69,
- 0xd7, 0xc1, 0xe8, 0x27, 0x3a, 0xff, 0x05, 0xe5, 0x93, 0x80, 0x4e, 0xb4,
- 0xf0, 0x7a, 0xb8, 0x47, 0x72, 0xa7, 0x0e, 0xac, 0x3c, 0x07, 0x27, 0xbf,
- 0xbd, 0xb6, 0x0e, 0xe3, 0x4e, 0xbf, 0xdc, 0x8f, 0x27, 0xf1, 0x23, 0xaf,
- 0x4e, 0x32, 0x3a, 0x95, 0x0c, 0x91, 0x68, 0x71, 0x42, 0x25, 0xc3, 0x13,
- 0xb3, 0xbf, 0x6e, 0x58, 0x30, 0xfa, 0xd1, 0x07, 0x8c, 0x00, 0x65, 0x7f,
- 0xe5, 0x47, 0xd8, 0x5b, 0x7a, 0xfb, 0xfe, 0x75, 0xfe, 0x94, 0xd8, 0x2f,
- 0xdc, 0x3a, 0xff, 0x6c, 0x79, 0x83, 0x03, 0x39, 0xd7, 0xd0, 0x05, 0x4a,
- 0x1d, 0x7b, 0xde, 0x83, 0xaf, 0xf2, 0x72, 0x27, 0x7e, 0x34, 0xeb, 0x7b,
- 0x87, 0xe2, 0xe4, 0x9e, 0x1b, 0xbf, 0xfd, 0xc6, 0x8e, 0x6c, 0x1c, 0x8e,
- 0x46, 0x8e, 0xbf, 0xcf, 0x37, 0x71, 0x79, 0xa3, 0xab, 0x0f, 0xeb, 0x62,
- 0x45, 0xfc, 0x8a, 0x7b, 0x31, 0x67, 0x5f, 0xb0, 0x29, 0xcd, 0x1d, 0x7b,
- 0xde, 0xdc, 0xeb, 0xff, 0xb7, 0x6a, 0x77, 0xe6, 0xd6, 0x75, 0x16, 0x75,
- 0x7e, 0x7c, 0xde, 0x1d, 0xb8, 0x1c, 0x3a, 0xb4, 0x6e, 0x76, 0xc8, 0xed,
- 0x13, 0xa3, 0xa5, 0x98, 0x62, 0xd4, 0x2a, 0xbb, 0xc8, 0x53, 0x24, 0x2b,
- 0xba, 0x47, 0xe8, 0xc5, 0x6f, 0xfc, 0x29, 0xf7, 0x7c, 0xd9, 0xbc, 0x7d,
- 0x3a, 0xff, 0xf2, 0x67, 0x03, 0x0c, 0xe7, 0x63, 0x7d, 0x1d, 0x7d, 0xf6,
- 0x39, 0xf9, 0xd7, 0x3f, 0x0e, 0xbf, 0xbc, 0x93, 0xae, 0x1a, 0x75, 0x04,
- 0xf0, 0xba, 0x2b, 0x76, 0x6d, 0x1d, 0x7d, 0xff, 0xd1, 0x91, 0xd7, 0x7e,
- 0xe2, 0x6f, 0x3c, 0x31, 0x50, 0x88, 0xa0, 0x2f, 0x5d, 0xbc, 0xc7, 0x5f,
- 0xbe, 0xfb, 0xf5, 0xe1, 0xd4, 0xb3, 0xc2, 0xfc, 0x62, 0xf3, 0x63, 0x47,
- 0x5f, 0xf4, 0x9f, 0x9e, 0x18, 0x5e, 0x8e, 0xbf, 0xd0, 0x18, 0xe0, 0x23,
- 0xf3, 0xae, 0x5e, 0xa6, 0x3e, 0x95, 0x9b, 0xdf, 0xfa, 0x1c, 0x73, 0xde,
- 0x46, 0x7c, 0x75, 0x42, 0x62, 0x58, 0x46, 0x90, 0x84, 0x01, 0x7d, 0x2a,
- 0x97, 0xaf, 0xa1, 0x1a, 0x52, 0xbb, 0x31, 0x65, 0xa8, 0x93, 0x24, 0xea,
- 0x1e, 0x1e, 0x8d, 0xda, 0xfe, 0x80, 0x6e, 0x9b, 0xed, 0x1d, 0x7e, 0xc6,
- 0x73, 0x7f, 0x1d, 0x6e, 0x7c, 0x3d, 0x94, 0x31, 0xbf, 0xfd, 0xac, 0x10,
- 0x37, 0xb8, 0xb9, 0x9d, 0xa7, 0x5f, 0xe1, 0x53, 0xb0, 0xb5, 0x89, 0xd7,
- 0xf2, 0xba, 0x46, 0xd0, 0x3c, 0x75, 0xfa, 0x26, 0xcc, 0x69, 0xd5, 0x88,
- 0x8a, 0x43, 0x2e, 0x99, 0x5f, 0xfb, 0xb9, 0x32, 0x4c, 0x0d, 0xa0, 0x68,
- 0xeb, 0xc9, 0xc5, 0x0e, 0xa4, 0x3d, 0xf1, 0x43, 0xbf, 0x46, 0xd7, 0x62,
- 0x63, 0xaa, 0x47, 0x95, 0xa2, 0x0b, 0xff, 0x81, 0x32, 0x76, 0x37, 0x94,
- 0x4d, 0x07, 0x5f, 0x82, 0xe3, 0x1d, 0x3a, 0xfe, 0x94, 0x6f, 0xec, 0xe9,
- 0xd7, 0xff, 0xbd, 0xa4, 0xfe, 0x25, 0xac, 0xcd, 0xfc, 0x75, 0x4c, 0x7e,
- 0xfa, 0x2d, 0xb2, 0x75, 0x17, 0xec, 0xc2, 0x72, 0xff, 0xfd, 0xc0, 0x73,
- 0x90, 0x38, 0xa2, 0x77, 0xb9, 0xf4, 0xeb, 0xf8, 0x5d, 0x03, 0x02, 0x75,
- 0xf4, 0xf1, 0xb5, 0x07, 0x5e, 0xd8, 0x0e, 0x9d, 0x7f, 0xf2, 0x2d, 0x35,
- 0xd8, 0x4e, 0x01, 0x5c, 0xea, 0x84, 0x43, 0xa1, 0x23, 0x8f, 0x5f, 0xc3,
- 0xa4, 0xd9, 0x01, 0x3a, 0xf0, 0xa2, 0x87, 0x5f, 0xde, 0x4e, 0x27, 0x80,
- 0x75, 0xa1, 0x67, 0x8f, 0xf4, 0x6e, 0xfe, 0x07, 0xde, 0xe6, 0xfa, 0x3a,
- 0xff, 0xff, 0xfd, 0xc8, 0xf0, 0xbb, 0x53, 0x53, 0x27, 0x1b, 0x1a, 0xf4,
- 0x6f, 0x1f, 0x73, 0x47, 0x5f, 0xee, 0xe6, 0xf1, 0xc4, 0x59, 0xd7, 0xff,
- 0xff, 0xfe, 0xd6, 0xb3, 0xdd, 0x75, 0xeb, 0x9c, 0x4d, 0xfc, 0xee, 0xa6,
- 0x64, 0xc0, 0xf4, 0x33, 0xbc, 0x1d, 0x50, 0x9a, 0x88, 0x61, 0x06, 0xe6,
- 0x57, 0xdf, 0xbe, 0xfa, 0x3a, 0xe6, 0x59, 0x3a, 0xb4, 0x6e, 0xd9, 0x23,
- 0xbf, 0x27, 0x5f, 0x3a, 0x53, 0x06, 0x8a, 0xff, 0x81, 0xe8, 0x16, 0xab,
- 0x7f, 0xac, 0xeb, 0xdd, 0x8f, 0xce, 0xa4, 0x3d, 0xa7, 0x3e, 0xbf, 0xdd,
- 0x8f, 0x01, 0x60, 0xf1, 0xd5, 0x0b, 0xfd, 0x92, 0x29, 0x0c, 0x34, 0xf7,
- 0x86, 0xba, 0xb9, 0x14, 0xd1, 0x82, 0x70, 0xb9, 0x6a, 0xdd, 0x85, 0x83,
- 0x96, 0xfe, 0xe8, 0xa9, 0x29, 0x18, 0xe0, 0x75, 0x09, 0x1f, 0x42, 0x43,
- 0x68, 0x82, 0xfd, 0x34, 0x4d, 0xd8, 0x3a, 0xef, 0xb0, 0x75, 0xe6, 0x59,
- 0x64, 0xab, 0xe9, 0x7b, 0x1a, 0x53, 0x05, 0xfd, 0xfb, 0x02, 0x9f, 0xe8,
- 0xf7, 0x7f, 0x57, 0x0f, 0x94, 0x4c, 0x6a, 0x11, 0xc9, 0xc2, 0x87, 0x84,
- 0xdd, 0xde, 0xd1, 0xd7, 0xfd, 0xf3, 0xdd, 0x8f, 0x6b, 0xa8, 0x75, 0xb4,
- 0x75, 0xfe, 0xf6, 0xf2, 0xec, 0x0c, 0xe7, 0x5f, 0xfb, 0x37, 0x92, 0x60,
- 0x8e, 0x04, 0xeb, 0xf4, 0xeb, 0x06, 0xfe, 0x3a, 0xa1, 0x1f, 0x3b, 0x8b,
- 0x70, 0xe8, 0x44, 0x34, 0x69, 0xe3, 0xbb, 0xfe, 0x18, 0x67, 0x48, 0x3b,
- 0xc8, 0xeb, 0xa1, 0xa7, 0x50, 0x9e, 0x6e, 0xc3, 0x8b, 0xe9, 0xfe, 0xc2,
- 0xb9, 0xd7, 0xfb, 0x41, 0x18, 0x67, 0x04, 0xea, 0xe1, 0xec, 0x78, 0x9e,
- 0xa1, 0x34, 0x04, 0x85, 0x1b, 0xbd, 0xdf, 0xc3, 0xbe, 0xa6, 0xcf, 0x1d,
- 0x7f, 0x27, 0x85, 0xff, 0xd1, 0xd7, 0xff, 0xbd, 0x36, 0x73, 0x1d, 0x71,
- 0xd4, 0x09, 0xd7, 0xf0, 0x17, 0x9d, 0xdd, 0xce, 0xa5, 0x11, 0x42, 0x25,
- 0x9a, 0x48, 0xbf, 0xfc, 0x81, 0x17, 0xdc, 0x73, 0xd8, 0x9f, 0x9d, 0x7f,
- 0x47, 0xbb, 0x2d, 0x00, 0xeb, 0xf7, 0x5f, 0x99, 0xc3, 0xae, 0x03, 0x9d,
- 0x4d, 0x37, 0x62, 0x4d, 0x7f, 0x72, 0x12, 0x4f, 0xa3, 0xad, 0x13, 0x9e,
- 0x58, 0x90, 0x5f, 0xa7, 0x57, 0x4c, 0xdc, 0xeb, 0xf2, 0x6a, 0x27, 0x59,
- 0xec, 0xfd, 0xbf, 0x43, 0xf3, 0xf0, 0x1e, 0xcf, 0xdb, 0x9e, 0x47, 0xb3,
- 0xf6, 0xf8, 0x12, 0xcd, 0x1e, 0xcf, 0xda, 0x09, 0xe8, 0x09, 0x15, 0xfa,
- 0x33, 0x58, 0x27, 0xb3, 0xf6, 0x8f, 0x67, 0xed, 0xcf, 0xe3, 0xd9, 0xfa,
- 0xb2, 0xde, 0xd2, 0x13, 0xf9, 0x02, 0x45, 0xf6, 0x6d, 0xa7, 0xe7, 0xb3,
- 0xf6, 0x8f, 0x67, 0xed, 0xdf, 0xc1, 0xec, 0xfd, 0xbf, 0xec, 0xfd, 0xf9,
- 0x9b, 0x30, 0x27, 0xb3, 0xf6, 0xfe, 0xce, 0xa6, 0x81, 0x39, 0xec, 0xfd,
- 0xaf, 0xd1, 0x46, 0x24, 0x7a, 0x46, 0xbe, 0xe4, 0xf1, 0xe3, 0xd9, 0xfb,
- 0x47, 0xb3, 0xf7, 0x0d, 0x7d, 0xcc, 0xb2, 0x7b, 0x3f, 0x6a, 0x4a, 0xc3,
- 0x82, 0x69, 0x90, 0x84, 0xde, 0x13, 0x5c, 0x27, 0x59, 0x8e, 0xa1, 0x75,
- 0xe5, 0xf6, 0x49, 0xaf, 0x4a, 0x14, 0x2d, 0x9f, 0xa6, 0x11, 0x21, 0x7f,
- 0xb5, 0x92, 0x94, 0x7b, 0x73, 0xab, 0x0f, 0xc3, 0x47, 0xb7, 0xfe, 0xc6,
- 0x87, 0x38, 0xcb, 0xf6, 0x63, 0xae, 0x94, 0xe5, 0x5f, 0x4c, 0xef, 0xc3,
- 0xaa, 0x74, 0x4c, 0x6e, 0x42, 0x27, 0xfb, 0x42, 0xf5, 0xc5, 0xd1, 0x27,
- 0x9c, 0xd1, 0xbf, 0xcb, 0xd0, 0xe7, 0xb3, 0xf3, 0xaf, 0xf9, 0xb1, 0xf8,
- 0x40, 0xfc, 0x91, 0xd7, 0xfe, 0x77, 0x9f, 0x16, 0xe3, 0xbc, 0x8e, 0xbf,
- 0x32, 0x2e, 0xa6, 0xb0, 0xfd, 0xa6, 0x39, 0xa8, 0x47, 0x43, 0xc2, 0xa2,
- 0xfc, 0x3e, 0xee, 0x4e, 0x75, 0xc1, 0x64, 0xea, 0x83, 0x7d, 0x84, 0xf7,
- 0xff, 0xe9, 0x72, 0x36, 0x3c, 0xd0, 0x1e, 0xc2, 0xde, 0x63, 0xaf, 0xf6,
- 0xd3, 0xe9, 0x35, 0x36, 0x1d, 0x5b, 0xa2, 0x33, 0x8a, 0xf5, 0x0c, 0xc1,
- 0x99, 0x4a, 0x6c, 0xc3, 0x34, 0x86, 0x7a, 0xb9, 0x87, 0x11, 0xfb, 0x0b,
- 0x37, 0x9d, 0x39, 0x18, 0xc5, 0x74, 0xc8, 0x08, 0x55, 0xdf, 0xff, 0xf2,
- 0x75, 0xfb, 0x12, 0x63, 0x3f, 0x89, 0x68, 0x3d, 0x8e, 0x1d, 0x7f, 0xe5,
- 0x23, 0x71, 0x8e, 0xf4, 0x0d, 0x3a, 0xff, 0xf0, 0x79, 0x18, 0x39, 0x24,
- 0xee, 0x6c, 0x3a, 0xfe, 0x17, 0x53, 0xaf, 0x23, 0xaf, 0x32, 0xcb, 0x25,
- 0x5e, 0xfb, 0x1f, 0x94, 0xc1, 0x7f, 0x7f, 0xcf, 0x2f, 0xbc, 0xcd, 0x8f,
- 0xc3, 0xaf, 0xff, 0xdd, 0xc9, 0x7d, 0x11, 0xc9, 0xe6, 0x94, 0x72, 0x73,
- 0xa8, 0x51, 0x27, 0xe3, 0xbb, 0xfe, 0xf3, 0x8e, 0x6b, 0x91, 0xa3, 0xaf,
- 0xa5, 0x1f, 0xee, 0x75, 0xfd, 0xfc, 0x0e, 0x6f, 0xe3, 0xae, 0x7f, 0xfe,
- 0x1e, 0x87, 0xd2, 0x3a, 0x74, 0x5c, 0x0c, 0x21, 0xaf, 0x6c, 0x8e, 0x1d,
- 0x52, 0x56, 0x2c, 0x16, 0x6c, 0x3f, 0x5a, 0x47, 0xe9, 0x63, 0x0c, 0x1f,
- 0x43, 0x6b, 0x61, 0x35, 0xc9, 0x39, 0xd7, 0xf8, 0x5a, 0x14, 0xd9, 0x01,
- 0x3a, 0x82, 0x79, 0x20, 0x16, 0xb7, 0xe7, 0x5f, 0xf6, 0x42, 0xbf, 0xce,
- 0xbe, 0x70, 0xeb, 0xfd, 0xfe, 0xda, 0x2c, 0x21, 0xc3, 0xaf, 0xfb, 0xdd,
- 0xcd, 0x7c, 0xf2, 0x4e, 0x75, 0x41, 0xf8, 0xa1, 0xb5, 0xff, 0x0a, 0x01,
- 0x53, 0xad, 0xb8, 0xf1, 0xd5, 0x24, 0xc6, 0xe6, 0x11, 0xec, 0x2b, 0x04,
- 0x82, 0xf3, 0x2c, 0xb2, 0x58, 0x84, 0x17, 0xcd, 0x77, 0x69, 0x62, 0x10,
- 0x30, 0x6b, 0x6f, 0x9f, 0x98, 0xc9, 0xd5, 0xc3, 0xe0, 0xd8, 0x7f, 0x79,
- 0x96, 0x59, 0x2c, 0x41, 0xea, 0x2c, 0x41, 0xe6, 0x0d, 0x6d, 0xe6, 0x59,
- 0x64, 0xeb, 0xda, 0x85, 0x0a, 0x60, 0xbf, 0xb2, 0xf1, 0x18, 0xad, 0x51,
- 0xf2, 0x45, 0xff, 0xdd, 0x89, 0x27, 0xb3, 0xad, 0x85, 0x9d, 0x50, 0x7e,
- 0xfb, 0x0d, 0x6f, 0xff, 0x67, 0x53, 0x9d, 0x7c, 0xd2, 0x3c, 0xe7, 0x5f,
- 0x47, 0xa1, 0x67, 0x52, 0xcf, 0x9f, 0xc8, 0xf7, 0xf3, 0x2e, 0x10, 0x3f,
- 0xd3, 0xaf, 0x85, 0x21, 0x43, 0xaf, 0x7d, 0x8f, 0xce, 0xa9, 0xcd, 0xf2,
- 0xc8, 0x2f, 0xcd, 0x8e, 0xc2, 0xca, 0xbf, 0x0b, 0x88, 0xe1, 0x57, 0x63,
- 0x4a, 0xb9, 0x96, 0x4a, 0xac, 0x3f, 0x6d, 0x13, 0x78, 0x8d, 0x91, 0x5b,
- 0xfc, 0x3f, 0x63, 0xfe, 0xe6, 0xd1, 0x4c, 0x1b, 0xcb, 0xff, 0xd3, 0x87,
- 0x8e, 0xd1, 0xcd, 0x9c, 0x4d, 0x1d, 0x50, 0x9f, 0xb6, 0x11, 0x23, 0x6b,
- 0xc3, 0x50, 0x09, 0x17, 0xff, 0x47, 0xfa, 0xcc, 0x0b, 0x8b, 0xa8, 0x75,
- 0xff, 0xf4, 0xb4, 0xcc, 0x73, 0xb0, 0x9d, 0x81, 0x43, 0xaf, 0xff, 0xb4,
- 0x39, 0xbf, 0xef, 0xa7, 0xe2, 0x6f, 0xf9, 0xd5, 0xba, 0x27, 0x99, 0x4d,
- 0xae, 0xa6, 0x0a, 0xf0, 0xe0, 0xbf, 0xb5, 0xf4, 0x20, 0x19, 0x1d, 0x7f,
- 0x23, 0x43, 0x8f, 0xf9, 0xd7, 0xff, 0xfe, 0x89, 0xd8, 0xd7, 0xb5, 0xbf,
- 0xc0, 0xe0, 0x61, 0xf9, 0x83, 0xf9, 0xd7, 0xe5, 0xe9, 0x97, 0xdc, 0xeb,
- 0x68, 0x28, 0x99, 0xfa, 0xe1, 0x7f, 0x64, 0xd2, 0x4e, 0x68, 0xea, 0x86,
- 0x4a, 0xa8, 0x61, 0x8f, 0x91, 0x9e, 0xa4, 0xa0, 0xce, 0x4a, 0x80, 0x78,
- 0xd4, 0x55, 0x25, 0x02, 0x5f, 0xa8, 0x62, 0xf8, 0xae, 0xf3, 0x2c, 0xb2,
- 0x55, 0xf7, 0xee, 0x21, 0x29, 0x82, 0xfe, 0xfb, 0xa8, 0xf2, 0x3a, 0xfb,
- 0x9c, 0x45, 0x9d, 0x7b, 0x51, 0xe3, 0xaf, 0x0f, 0xb4, 0x86, 0xf2, 0x62,
- 0x1b, 0xdf, 0x14, 0xdb, 0x3a, 0xf7, 0x9c, 0x27, 0x57, 0x0d, 0xee, 0x88,
- 0xaf, 0xe6, 0xc7, 0xe9, 0xc5, 0x0e, 0xbf, 0xbe, 0xe7, 0x33, 0x26, 0x3a,
- 0xfc, 0xfd, 0xf8, 0x18, 0x3a, 0xa4, 0x9d, 0x08, 0x4c, 0x71, 0x71, 0x1b,
- 0xc4, 0x87, 0x45, 0xde, 0x2e, 0xbf, 0x3f, 0x39, 0x9b, 0x9d, 0x7f, 0xfb,
- 0xdd, 0x47, 0xff, 0x38, 0x18, 0x19, 0x1d, 0x7f, 0xfb, 0x7f, 0x9b, 0xff,
- 0x02, 0xd7, 0x9c, 0x5c, 0xea, 0x84, 0x5e, 0x61, 0x38, 0xa4, 0x5f, 0xa3,
- 0x5f, 0x46, 0x47, 0x5f, 0xff, 0xfc, 0xe9, 0xe4, 0xeb, 0x53, 0xe4, 0x93,
- 0xae, 0x3e, 0x96, 0x73, 0x0e, 0xbd, 0xdc, 0xda, 0x3a, 0xfd, 0xed, 0x7d,
- 0xd7, 0xce, 0xa2, 0x35, 0xdb, 0xef, 0xe6, 0x75, 0xd7, 0x6c, 0x1d, 0x7f,
- 0xff, 0xf2, 0x29, 0xbc, 0xbd, 0x83, 0xed, 0x7c, 0xd6, 0xb3, 0x98, 0x2f,
- 0x23, 0xaf, 0xfe, 0x60, 0x23, 0x00, 0x6e, 0x28, 0x9c, 0x3a, 0xec, 0x64,
- 0xeb, 0x64, 0x1e, 0xd6, 0x91, 0x2f, 0xf0, 0x7b, 0x13, 0x3b, 0xee, 0x75,
- 0xee, 0xff, 0xb0, 0xea, 0xe1, 0xe9, 0x6d, 0x19, 0xd4, 0x91, 0x3a, 0xef,
- 0x17, 0xff, 0x67, 0x3f, 0x5a, 0x6b, 0xee, 0xa3, 0x0e, 0xbc, 0xea, 0xfa,
- 0x3a, 0xa4, 0x7c, 0x6e, 0x8b, 0x78, 0x38, 0xb3, 0xaf, 0xbf, 0xf6, 0x7e,
- 0x75, 0x21, 0xbe, 0xe0, 0xdd, 0xff, 0x37, 0xa3, 0x1b, 0xa4, 0x74, 0xea,
- 0x85, 0xd1, 0x69, 0x46, 0x3c, 0x12, 0xdc, 0x85, 0xaa, 0x22, 0x70, 0xb5,
- 0xe3, 0x6a, 0x18, 0x42, 0x81, 0x7f, 0xe9, 0x05, 0xff, 0x9d, 0x02, 0x0f,
- 0x6a, 0x7c, 0x64, 0xeb, 0xf6, 0xb1, 0x48, 0xd1, 0xd7, 0xf2, 0xbe, 0x90,
- 0x77, 0x91, 0xd7, 0xfe, 0x7e, 0x6d, 0xa7, 0x71, 0xf7, 0xfc, 0xeb, 0xff,
- 0xf2, 0x7a, 0x17, 0x9b, 0xfa, 0x17, 0xf7, 0x8f, 0xf9, 0xd7, 0xc8, 0x2e,
- 0x13, 0xaf, 0xfb, 0x51, 0xcf, 0x43, 0x01, 0x43, 0xaa, 0x48, 0xae, 0x0a,
- 0xbe, 0x87, 0xef, 0xff, 0x69, 0x39, 0x12, 0xec, 0x4c, 0x20, 0x50, 0xeb,
- 0x9b, 0xb6, 0x75, 0xfc, 0xa7, 0xa3, 0xb1, 0xa3, 0xaf, 0xee, 0xa6, 0xfa,
- 0x7d, 0xce, 0xa9, 0x1f, 0xa2, 0x0c, 0xfe, 0x5b, 0x7f, 0xe1, 0x79, 0xba,
- 0xfc, 0xe2, 0x04, 0xeb, 0xc1, 0x41, 0x3a, 0xfe, 0x8f, 0x2a, 0x1e, 0x37,
- 0x3a, 0xbe, 0x1e, 0x52, 0x0d, 0x54, 0x95, 0x86, 0xe1, 0x3b, 0x4c, 0x12,
- 0x1d, 0xf3, 0x18, 0x72, 0x17, 0xcb, 0x2f, 0x66, 0x10, 0xf7, 0xe4, 0x5a,
- 0xac, 0xab, 0xd5, 0xb3, 0xaf, 0xbe, 0xc3, 0x3a, 0x3a, 0xef, 0xfc, 0x75,
- 0xf7, 0x39, 0x9a, 0x3a, 0xec, 0x98, 0xeb, 0x4b, 0xe1, 0xf9, 0x4e, 0x48,
- 0xe2, 0xff, 0x48, 0x6f, 0xc9, 0xe7, 0x1c, 0x3a, 0xfd, 0xc0, 0xe6, 0x09,
- 0xd7, 0xff, 0x2b, 0xa6, 0x76, 0x36, 0x6b, 0xb1, 0xb9, 0xd7, 0xf6, 0xfc,
- 0x06, 0xfe, 0x91, 0xd4, 0xe8, 0x9d, 0xd1, 0x28, 0x12, 0x2f, 0xfb, 0x07,
- 0x99, 0xac, 0x4e, 0x9d, 0x7f, 0xfd, 0x2f, 0x0e, 0x3f, 0x87, 0x3d, 0xec,
- 0x64, 0xeb, 0xd3, 0xe6, 0xc3, 0xaf, 0xff, 0x7b, 0x59, 0x37, 0x63, 0x66,
- 0x77, 0xb0, 0x75, 0xfd, 0xd0, 0xa6, 0xc8, 0x09, 0xd5, 0x87, 0xf2, 0xe9,
- 0x77, 0xd9, 0xe4, 0xd1, 0xd7, 0xf2, 0xb1, 0x30, 0xab, 0x73, 0x80, 0xea,
- 0xd1, 0xec, 0xf8, 0x82, 0xa4, 0xaa, 0x90, 0x30, 0xc1, 0x69, 0x7e, 0xe6,
- 0xbc, 0x4d, 0x18, 0x4b, 0xf9, 0xe6, 0xf3, 0x39, 0xd3, 0xaf, 0xf6, 0x91,
- 0x4e, 0xb8, 0xa1, 0xd7, 0xc9, 0xac, 0x0b, 0x9e, 0x6f, 0x87, 0x2f, 0xfc,
- 0xea, 0xff, 0x83, 0x48, 0x3b, 0xc8, 0xeb, 0xff, 0xfb, 0xd9, 0xd4, 0x8f,
- 0x27, 0xf1, 0x26, 0x19, 0x65, 0x92, 0xaf, 0xf7, 0x40, 0xeb, 0x0b, 0xac,
- 0xea, 0x14, 0x48, 0x79, 0x7a, 0xf8, 0x39, 0x8a, 0x15, 0x7c, 0xff, 0xbf,
- 0x8e, 0xbf, 0xee, 0x3b, 0x7e, 0x76, 0x3e, 0x89, 0xd7, 0x81, 0x1c, 0x3a,
- 0xef, 0x68, 0x27, 0xad, 0x31, 0xdd, 0xe9, 0x08, 0x0d, 0x10, 0xcd, 0xee,
- 0xc4, 0xe7, 0x5e, 0x65, 0x96, 0x4a, 0xbd, 0x82, 0xd2, 0x98, 0x2f, 0xef,
- 0xfd, 0x93, 0xe0, 0x5e, 0x43, 0x13, 0x9d, 0x5f, 0x9f, 0x38, 0x95, 0x5f,
- 0x38, 0xab, 0x55, 0x51, 0xd7, 0x2b, 0x55, 0x6a, 0x75, 0xfb, 0x3d, 0xe0,
- 0x4e, 0x75, 0xa4, 0xad, 0x4f, 0x28, 0x48, 0xaf, 0x3a, 0xbc, 0x1d, 0x7e,
- 0xc0, 0xf5, 0xd5, 0xce, 0xbf, 0x0e, 0x06, 0x16, 0x75, 0x42, 0xae, 0x19,
- 0xc8, 0x82, 0x43, 0x8e, 0xfb, 0x97, 0xcc, 0x51, 0xc8, 0x51, 0x74, 0x89,
- 0xdd, 0x00, 0x5b, 0xb0, 0x75, 0x92, 0x9b, 0xfd, 0x0b, 0xc4, 0xe4, 0xd2,
- 0x3a, 0xf7, 0x92, 0x0e, 0xbb, 0x04, 0xea, 0x43, 0x5c, 0x01, 0xab, 0xff,
- 0xf7, 0x5f, 0x9a, 0xc4, 0x17, 0xf6, 0x99, 0x81, 0x3a, 0xfc, 0x14, 0xe4,
- 0x78, 0xeb, 0xb7, 0xfc, 0xeb, 0xf9, 0x71, 0xaf, 0xd1, 0xa7, 0x5e, 0xd4,
- 0x29, 0xf9, 0xe2, 0xe8, 0x62, 0xff, 0x03, 0x39, 0xff, 0xe8, 0x27, 0x5f,
- 0xfb, 0x16, 0x81, 0xe6, 0x05, 0xd6, 0x75, 0xf6, 0x2f, 0xe8, 0x4e, 0xae,
- 0x9e, 0xf8, 0x9e, 0x5f, 0xfe, 0x40, 0xf7, 0xee, 0xb3, 0x8d, 0x77, 0x69,
- 0xa2, 0x0c, 0xbe, 0x07, 0x71, 0xa7, 0x54, 0x8f, 0xe3, 0x6d, 0x5e, 0xf7,
- 0x40, 0xae, 0x75, 0xff, 0xee, 0x3e, 0xcc, 0x16, 0xf5, 0x3f, 0xfb, 0xe3,
- 0xaa, 0x11, 0x22, 0xa9, 0x25, 0x00, 0xfd, 0x6e, 0xa8, 0x93, 0xa6, 0xba,
- 0x84, 0x97, 0xa3, 0x2a, 0xbf, 0xdf, 0xa7, 0x7b, 0x9f, 0xb9, 0xd7, 0xff,
- 0xfc, 0xbc, 0xf7, 0x9f, 0x83, 0x1b, 0xcb, 0xef, 0x3f, 0x5a, 0x68, 0xeb,
- 0xfe, 0x5a, 0x33, 0x82, 0x1e, 0xc1, 0xd7, 0x74, 0x07, 0x5f, 0xff, 0xa4,
- 0x82, 0x1e, 0xe6, 0xff, 0x5c, 0x7c, 0x21, 0x3a, 0xf2, 0x32, 0xae, 0x75,
- 0xfe, 0xcd, 0x9a, 0xf7, 0xa1, 0x67, 0x57, 0x0f, 0x4f, 0xa3, 0xf5, 0x09,
- 0xc0, 0x63, 0x4a, 0x1b, 0xcc, 0x2d, 0xa8, 0x54, 0x5f, 0xed, 0xbc, 0xd6,
- 0xde, 0x72, 0x0e, 0xbf, 0xfe, 0x18, 0x6f, 0xce, 0x62, 0x01, 0x53, 0x9b,
- 0x58, 0x75, 0x49, 0x77, 0x64, 0x24, 0x18, 0xa4, 0x92, 0xa3, 0xff, 0x4b,
- 0xd4, 0x76, 0x7e, 0x4e, 0xda, 0x37, 0xbf, 0xda, 0xd6, 0x0f, 0xfb, 0x78,
- 0x75, 0xf0, 0xa6, 0xd4, 0x1d, 0x69, 0x8e, 0xbf, 0xb5, 0x83, 0xfe, 0xde,
- 0x1d, 0x6d, 0x9f, 0x11, 0x2f, 0x86, 0xbf, 0x91, 0x68, 0x46, 0xff, 0x81,
- 0xef, 0xc0, 0xb8, 0xcf, 0x1d, 0x7f, 0xf8, 0x67, 0xf9, 0x32, 0x0e, 0x07,
- 0x05, 0x43, 0xaf, 0xe4, 0xdf, 0x6b, 0xb1, 0xe3, 0xaf, 0x7d, 0xc8, 0x3a,
- 0xa1, 0x12, 0xea, 0xe9, 0x6e, 0x61, 0x7f, 0xff, 0xe7, 0x0e, 0x0b, 0xfb,
- 0x59, 0xcf, 0xff, 0x8c, 0xdf, 0xda, 0x43, 0xaf, 0x47, 0x26, 0x3a, 0xbe,
- 0x36, 0xbb, 0x31, 0x2d, 0x32, 0x78, 0x41, 0x06, 0x15, 0x39, 0x2b, 0xa9,
- 0xb0, 0xbd, 0xdc, 0xdd, 0x25, 0xd9, 0xf6, 0x15, 0xef, 0x3c, 0x73, 0xfc,
- 0x63, 0x42, 0x8e, 0x08, 0x68, 0x32, 0x63, 0xb6, 0xd7, 0x7b, 0x79, 0xf6,
- 0x1d, 0x7f, 0x7c, 0x6f, 0x63, 0x7d, 0xa3, 0xaf, 0x7c, 0xfd, 0x93, 0xab,
- 0x73, 0xd3, 0xf1, 0x9d, 0xfd, 0x8c, 0xe6, 0x0a, 0x87, 0x5f, 0x2d, 0xf3,
- 0x47, 0x52, 0x1e, 0x63, 0x96, 0x5f, 0xff, 0x36, 0x35, 0xa8, 0x5e, 0x79,
- 0x35, 0xd7, 0x3a, 0xff, 0x08, 0xc4, 0x97, 0x08, 0x75, 0xfe, 0xf2, 0x6c,
- 0x4f, 0x4a, 0x0a, 0xb2, 0xce, 0xbf, 0xb0, 0x54, 0xe4, 0x30, 0x87, 0x87,
- 0xf4, 0xce, 0xb1, 0x30, 0x54, 0x4d, 0xd3, 0x95, 0xf7, 0x01, 0xbc, 0x8e,
- 0xbf, 0xc3, 0x21, 0xc5, 0xc3, 0x4e, 0xbc, 0xb0, 0xe1, 0xd5, 0x07, 0xdd,
- 0x84, 0x6e, 0x61, 0x7b, 0x6c, 0x1e, 0x3a, 0xff, 0xf7, 0xa1, 0x68, 0x1c,
- 0x15, 0x3b, 0x0b, 0x3a, 0x9a, 0x7c, 0xfe, 0x1f, 0xbf, 0xfe, 0x4f, 0x76,
- 0x35, 0x1d, 0x84, 0x9e, 0x14, 0x3a, 0xfd, 0xef, 0x69, 0xff, 0x3a, 0xfd,
- 0x0b, 0xf6, 0x34, 0xeb, 0x92, 0x73, 0xaa, 0x11, 0x64, 0x89, 0xdd, 0x28,
- 0xf1, 0x35, 0xf9, 0x94, 0x0e, 0xd2, 0x1d, 0x7f, 0xdd, 0x89, 0x20, 0xe2,
- 0xe0, 0xeb, 0xfe, 0xcf, 0x77, 0x16, 0x2f, 0xe3, 0xaf, 0xed, 0x89, 0xcd,
- 0xe1, 0x5c, 0xeb, 0x08, 0x4f, 0xa3, 0x0d, 0xaf, 0xcb, 0x86, 0xce, 0x13,
- 0xaf, 0xa5, 0x0b, 0x73, 0xaf, 0xdc, 0xfd, 0x69, 0xa3, 0xae, 0xf6, 0xb0,
- 0xfc, 0x1c, 0xa3, 0xe9, 0x05, 0x42, 0x34, 0x41, 0x09, 0x6b, 0x68, 0xeb,
- 0xfa, 0x27, 0xc1, 0x45, 0x0e, 0xae, 0x1b, 0xcd, 0x08, 0x5f, 0xfd, 0x02,
- 0xfd, 0x8f, 0xd8, 0xe6, 0xb4, 0x55, 0x4e, 0xa8, 0xd8, 0x31, 0xb7, 0x63,
- 0x1a, 0xc8, 0x6f, 0xf3, 0x87, 0x5a, 0x8e, 0x48, 0xeb, 0x81, 0x39, 0xd7,
- 0xfb, 0x79, 0x6f, 0xa4, 0xf4, 0x1d, 0x79, 0x37, 0xd1, 0xd5, 0x87, 0xa0,
- 0x86, 0x94, 0x88, 0x87, 0xeb, 0x3d, 0xd8, 0xd3, 0xaf, 0x73, 0x34, 0x77,
- 0x8b, 0x5b, 0xff, 0xe0, 0xfc, 0x74, 0xcd, 0x44, 0xf8, 0x28, 0xa1, 0xd7,
- 0xfb, 0x8b, 0x8d, 0xfc, 0xed, 0x3a, 0xb1, 0x10, 0x48, 0x9f, 0x7c, 0x8b,
- 0x89, 0x8e, 0xbe, 0xc9, 0xc1, 0x23, 0xaa, 0x63, 0xc3, 0x64, 0x86, 0xf8,
- 0x01, 0x0c, 0x1d, 0x50, 0x78, 0xae, 0x49, 0x76, 0x32, 0x75, 0x15, 0x7f,
- 0x6b, 0xec, 0x72, 0x16, 0x55, 0x15, 0x45, 0x51, 0x54, 0x55, 0x48, 0xf8,
- 0x10, 0x2b, 0xf2, 0xe0, 0x05, 0x6d, 0x85, 0x6d, 0x05, 0x5d, 0xdc, 0x2a,
- 0xfe, 0x77, 0xf4, 0xd0, 0xb2, 0xbe, 0x16, 0xb6, 0x54, 0x95, 0x45, 0x51,
- 0x55, 0x22, 0xd1, 0x02, 0xa8, 0xaa, 0x2a, 0x8a, 0xa2, 0xa8, 0xaa, 0x2a,
- 0xa7, 0x37, 0x81, 0x0a, 0x40, 0xaf, 0xc2, 0xb4, 0x15, 0xb0, 0x2a, 0x8a,
- 0xa2, 0xaa, 0x45, 0xa6, 0x82, 0xa8, 0xaa, 0x2a, 0x8a, 0xa2, 0xaa, 0x46,
- 0xa3, 0xf0, 0xaf, 0x05, 0x6d, 0x05, 0x51, 0x54, 0x55, 0x15, 0x45, 0x54,
- 0xe6, 0xa1, 0x40, 0xae, 0x05, 0x74, 0x2a, 0xca, 0x15, 0x45, 0x51, 0x54,
- 0x55, 0x15, 0x41, 0x35, 0x1b, 0x85, 0x7e, 0x14, 0x00, 0xaa, 0x2a, 0x8a,
- 0xa2, 0xaf, 0xdd, 0x8f, 0xf5, 0x85, 0x51, 0x55, 0x23, 0xcf, 0x68, 0x57,
- 0x42, 0x9c, 0x2b, 0xf2, 0x7b, 0x34, 0xaa, 0x2a, 0x8a, 0xa2, 0xa8, 0xaa,
- 0x91, 0xa8, 0xdc, 0x29, 0x02, 0xb6, 0x05, 0x51, 0x54, 0x55, 0x15, 0x45,
- 0x54, 0x8d, 0x40, 0x42, 0xba, 0x14, 0x21, 0x56, 0xe9, 0x54, 0x55, 0x15,
- 0x69, 0x15, 0x45, 0x6e, 0x58, 0x51, 0x54, 0x55, 0x15, 0x45, 0x54, 0xe7,
- 0xcd, 0x20, 0xa5, 0x06, 0x9a, 0x35, 0x30, 0x57, 0xe1, 0x5e, 0x0a, 0xb6,
- 0x15, 0x45, 0x51, 0x56, 0x91, 0x54, 0x56, 0xe5, 0x85, 0x15, 0x45, 0x54,
- 0x1e, 0x94, 0x82, 0x90, 0x6b, 0x83, 0x4b, 0x0a, 0xa2, 0xa8, 0xaa, 0x2a,
- 0x8a, 0xa2, 0xaa, 0x0d, 0x96, 0xe1, 0x5c, 0x0a, 0x58, 0x50, 0x85, 0x51,
- 0x54, 0x55, 0x15, 0x5c, 0x2f, 0xb4, 0x15, 0xe0, 0xaa, 0x2a, 0x8a, 0xa2,
- 0xa9, 0x65, 0xf0, 0x85, 0x78, 0x2a, 0xcb, 0x2a, 0x8a, 0xa2, 0xab, 0xf2,
- 0xd0, 0x01, 0x54, 0x55, 0x15, 0x45, 0x51, 0x55, 0x06, 0xa2, 0x60, 0xae,
- 0x85, 0x00, 0x2a, 0xa1, 0x7e, 0xa6, 0x77, 0x19, 0x1e, 0x84, 0xa3, 0x16,
- 0xda, 0xd9, 0xba, 0x42, 0x33, 0xab, 0x9e, 0xcc, 0x73, 0xc8, 0x46, 0x2d,
- 0x27, 0xa7, 0x0e, 0xcb, 0xf9, 0xd0, 0xbb, 0x69, 0x9f, 0xcc, 0x20, 0x79,
- 0xd8, 0xca, 0xca, 0x5e, 0xd9, 0x67, 0xd2, 0x4d, 0xa4, 0x9b, 0xf4, 0x86,
- 0x33, 0x45, 0x30, 0x9a, 0xb5, 0xe4, 0x85, 0x95, 0x7c, 0x8d, 0x7e, 0x1d,
- 0x79, 0x03, 0x87, 0x59, 0x8d, 0xd1, 0x1b, 0xc3, 0x9e, 0x8d, 0x78, 0x82,
- 0xd1, 0xb1, 0x94, 0x8f, 0xf6, 0x94, 0x05, 0x7f, 0xba, 0x8c, 0x87, 0x91,
- 0x39, 0xd7, 0x93, 0x62, 0xa4, 0xea, 0xdd, 0x11, 0xd3, 0x1c, 0xf8, 0xd2,
- 0xfd, 0x99, 0x33, 0xfd, 0x3a, 0xef, 0xe0, 0xeb, 0xfb, 0x8e, 0x3f, 0x63,
- 0xf3, 0xae, 0x7e, 0x1d, 0x64, 0x39, 0xa5, 0xad, 0x9a, 0x75, 0x96, 0x75,
- 0xdb, 0x6c, 0x22, 0x25, 0xf8, 0x2d, 0xd4, 0x37, 0x1e, 0xfa, 0x21, 0x7f,
- 0xdd, 0x85, 0xe4, 0xd0, 0x33, 0x9d, 0x7f, 0xf7, 0xc7, 0x68, 0x7b, 0x1f,
- 0xe0, 0xfe, 0x75, 0xdf, 0xc1, 0xd5, 0x87, 0xb9, 0xfa, 0x35, 0x62, 0x62,
- 0x1f, 0xad, 0x02, 0x12, 0x97, 0xff, 0x08, 0xc4, 0xe3, 0x89, 0xb2, 0x36,
- 0xce, 0xbd, 0x1b, 0xe8, 0xea, 0x73, 0xe1, 0xd2, 0x2d, 0xe7, 0xe4, 0x1d,
- 0x7e, 0x4d, 0xb7, 0x1f, 0xce, 0xa9, 0x1e, 0x1a, 0xc6, 0xaf, 0xfb, 0xeb,
- 0x87, 0x58, 0xb8, 0x57, 0x3a, 0xf6, 0x6e, 0xc9, 0xd7, 0xb7, 0xff, 0x38,
- 0x7b, 0x22, 0x79, 0x7d, 0xb3, 0x39, 0x23, 0xaf, 0x05, 0xc4, 0xea, 0x43,
- 0x7a, 0xe4, 0x77, 0xff, 0xd1, 0xf1, 0xf9, 0xc7, 0xfe, 0x18, 0x65, 0x96,
- 0x4e, 0xa8, 0x4d, 0x81, 0xde, 0xf4, 0xe2, 0x01, 0xfa, 0x54, 0x37, 0x17,
- 0xb0, 0xe7, 0x3b, 0x7c, 0xa3, 0x25, 0x0c, 0x27, 0x72, 0x12, 0x6d, 0x86,
- 0xa6, 0xe7, 0x69, 0x29, 0x81, 0x5d, 0x16, 0x68, 0x5c, 0xf0, 0xdd, 0x70,
- 0xac, 0xec, 0x2a, 0x5e, 0x95, 0xeb, 0xf9, 0x90, 0xc7, 0x9f, 0xa8, 0x4b,
- 0xfa, 0x3c, 0x4b, 0xe4, 0x16, 0xc1, 0xd7, 0xf3, 0x2f, 0xce, 0x3e, 0xe7,
- 0x5f, 0xff, 0xb5, 0xce, 0x24, 0xda, 0xe4, 0x79, 0x1a, 0x81, 0x3a, 0x96,
- 0x8a, 0x21, 0x1f, 0x64, 0xba, 0xf9, 0x7e, 0x8d, 0x1d, 0x7f, 0xbd, 0x00,
- 0x6f, 0x53, 0x87, 0x5f, 0xd8, 0xde, 0xc6, 0xf2, 0x3a, 0xfe, 0x5e, 0x91,
- 0x4f, 0x32, 0x75, 0xfa, 0x37, 0xec, 0x48, 0xea, 0x14, 0x5a, 0xf8, 0xcb,
- 0xe9, 0x6e, 0xd1, 0x7d, 0xdb, 0xf8, 0xeb, 0xf7, 0x9c, 0x41, 0x87, 0x5f,
- 0xed, 0x62, 0xd3, 0xdd, 0x73, 0xad, 0x18, 0x7d, 0xa2, 0x2f, 0xe2, 0x5b,
- 0xe9, 0x7c, 0x5a, 0x1d, 0x7b, 0x6b, 0x90, 0x75, 0xfe, 0xe2, 0x4c, 0x39,
- 0xb1, 0xce, 0xbb, 0x7d, 0x7c, 0x3f, 0x48, 0x23, 0xe0, 0xf5, 0xff, 0x0c,
- 0x3c, 0xfd, 0x8e, 0x7e, 0x75, 0xcf, 0xb0, 0xeb, 0xfa, 0x42, 0x92, 0xee,
- 0x1d, 0x7e, 0x9d, 0x39, 0x12, 0x3a, 0xa6, 0x3e, 0x9e, 0x0b, 0x89, 0x5d,
- 0xf6, 0x05, 0x14, 0x3a, 0xff, 0xf3, 0xa7, 0xa3, 0xda, 0xeb, 0xa7, 0x40,
- 0x75, 0xf0, 0x88, 0x24, 0x75, 0xff, 0xbb, 0x1c, 0xfc, 0x71, 0x97, 0xfc,
- 0xeb, 0xd9, 0x93, 0x1d, 0x6c, 0xe9, 0xed, 0x7e, 0x7f, 0x7f, 0x03, 0x80,
- 0x5b, 0x89, 0xd7, 0xcb, 0x8c, 0x9c, 0xeb, 0xf6, 0x6c, 0x18, 0xdc, 0xea,
- 0x43, 0xc9, 0xd1, 0x0d, 0xf4, 0x0f, 0x9a, 0x75, 0xa0, 0x2a, 0xa4, 0x32,
- 0x14, 0x3c, 0x2f, 0xe9, 0x0b, 0xa3, 0x8b, 0xd6, 0x8a, 0x3c, 0xeb, 0xb6,
- 0x43, 0x7f, 0x6b, 0x16, 0x9d, 0x83, 0xaf, 0x6f, 0x2d, 0x1d, 0x5b, 0x9e,
- 0x47, 0x0a, 0xef, 0x6b, 0xf6, 0x4e, 0xa8, 0x3c, 0x1c, 0x23, 0xbe, 0x03,
- 0xf2, 0x47, 0x5f, 0x40, 0x15, 0x3a, 0x2a, 0xfd, 0x26, 0x19, 0x65, 0x93,
- 0xa8, 0x4f, 0x44, 0x04, 0xb7, 0xcf, 0xe5, 0xf8, 0xea, 0x0a, 0x2d, 0x31,
- 0xcb, 0xf2, 0x1a, 0x85, 0xf3, 0xec, 0x30, 0x48, 0x6b, 0x2e, 0x15, 0xcf,
- 0x0a, 0x6f, 0xe5, 0x66, 0x8c, 0x62, 0x60, 0x86, 0xa5, 0xe5, 0x65, 0x57,
- 0xaa, 0x0e, 0xbd, 0x21, 0x73, 0xad, 0xba, 0xb2, 0x78, 0xb0, 0x57, 0x7f,
- 0x47, 0x27, 0x8e, 0x4e, 0x75, 0xf8, 0x1f, 0xe0, 0xb4, 0xeb, 0xdc, 0x89,
- 0x8e, 0xbe, 0x41, 0x79, 0x8e, 0xbf, 0xde, 0xcf, 0xb1, 0x32, 0x68, 0xea,
- 0x92, 0x31, 0x78, 0x5c, 0xb2, 0x7e, 0x8e, 0x6c, 0x20, 0xbf, 0xe8, 0x4e,
- 0xc2, 0xe7, 0xc6, 0x4e, 0xbf, 0xa3, 0xa9, 0x3b, 0x89, 0xd7, 0xfd, 0x38,
- 0xe4, 0xbb, 0x9f, 0xe8, 0xeb, 0xff, 0x60, 0xef, 0x2d, 0x70, 0x11, 0xf9,
- 0xd7, 0xec, 0xf6, 0xb1, 0x43, 0xa9, 0x0f, 0x99, 0x67, 0xf7, 0x83, 0x1b,
- 0x0e, 0xbf, 0xfe, 0xc1, 0x18, 0x64, 0x23, 0x1b, 0xc9, 0x04, 0xeb, 0xff,
- 0xcf, 0xf2, 0x69, 0x47, 0x27, 0xf8, 0xce, 0x74, 0xea, 0x0a, 0x2e, 0x7a,
- 0x3a, 0x29, 0x97, 0xfc, 0xbe, 0xe7, 0xb0, 0x1c, 0x9c, 0xeb, 0xfe, 0x8f,
- 0x67, 0x1a, 0xee, 0xd3, 0x45, 0xf1, 0x7e, 0xce, 0x46, 0xf2, 0x3a, 0xf7,
- 0x61, 0x6d, 0x3e, 0xaf, 0x21, 0xdf, 0xff, 0x85, 0xbf, 0x3b, 0x09, 0xc4,
- 0x5a, 0x6d, 0xc2, 0xce, 0xbc, 0xfc, 0x9c, 0xd1, 0x7f, 0xd4, 0x22, 0xcf,
- 0x0c, 0xda, 0xaf, 0x7f, 0xff, 0xba, 0xfa, 0x48, 0xd7, 0xcf, 0x77, 0x17,
- 0x8d, 0x7e, 0x1d, 0x74, 0x6d, 0x1d, 0x7d, 0xad, 0x3a, 0xce, 0xae, 0xa2,
- 0x67, 0xf6, 0x0f, 0x0c, 0x5f, 0xff, 0xd2, 0x70, 0xb7, 0xa8, 0x39, 0xb1,
- 0xe5, 0xa4, 0x09, 0xd7, 0xfd, 0x0b, 0xf8, 0x1c, 0xcf, 0xf4, 0x75, 0xff,
- 0x26, 0x08, 0x54, 0x4c, 0xe1, 0xd4, 0x87, 0xe1, 0xb4, 0x75, 0x7f, 0x3f,
- 0x37, 0x96, 0x78, 0xeb, 0xff, 0x7b, 0x49, 0xcf, 0x08, 0x1e, 0x47, 0x5f,
- 0xfe, 0x5c, 0x6d, 0xe0, 0x07, 0x33, 0x64, 0x6e, 0x75, 0xff, 0xa3, 0x39,
- 0x9c, 0xfd, 0x69, 0xa3, 0xaf, 0x3e, 0xfb, 0x47, 0x5f, 0xcf, 0xed, 0x46,
- 0x4e, 0x75, 0x42, 0x67, 0xd8, 0x5a, 0x87, 0xa2, 0x99, 0xb0, 0xf5, 0x91,
- 0xfb, 0xfe, 0x04, 0x2f, 0x58, 0xb8, 0x57, 0x3a, 0xff, 0xed, 0x60, 0xfb,
- 0x5f, 0x76, 0x46, 0x6e, 0x75, 0xff, 0x33, 0xf6, 0x7d, 0x62, 0xe1, 0x5c,
- 0xeb, 0xc9, 0xd4, 0x3a, 0xfa, 0x5c, 0x0c, 0x8e, 0xbe, 0x5f, 0x92, 0x73,
- 0xab, 0x0f, 0x11, 0x08, 0xaf, 0xfe, 0xd9, 0xe5, 0x20, 0x65, 0x9d, 0x45,
- 0x9d, 0x74, 0xfe, 0x3a, 0xff, 0x6c, 0xeb, 0xca, 0x30, 0x4e, 0xa8, 0x3c,
- 0x9c, 0x17, 0xbf, 0xb1, 0x9f, 0xbd, 0x7f, 0x1d, 0x7f, 0xfe, 0xf7, 0xd9,
- 0x46, 0xc4, 0x1f, 0xf8, 0x90, 0xbc, 0x2a, 0xfb, 0xbf, 0x77, 0xf1, 0xd7,
- 0xec, 0x5e, 0x26, 0xc3, 0xaf, 0x4f, 0x32, 0xb9, 0xd5, 0x3a, 0x3c, 0xf0,
- 0xbd, 0xaa, 0xe8, 0x4a, 0x02, 0x7b, 0xbd, 0x87, 0x5f, 0xb8, 0x93, 0xba,
- 0xcd, 0x30, 0x9d, 0xf7, 0x81, 0x0e, 0x69, 0x84, 0xee, 0xfe, 0x0d, 0x40,
- 0x9d, 0xfe, 0x17, 0x53, 0xd1, 0xcf, 0xcd, 0x40, 0x9d, 0xfe, 0xd6, 0x75,
- 0x34, 0x09, 0xcd, 0x30, 0x9d, 0xd8, 0x13, 0x4c, 0x27, 0x73, 0x2c, 0x9e,
- 0x61, 0x3a, 0xc4, 0xd2, 0xf7, 0x34, 0x42, 0xd5, 0x91, 0xe9, 0x03, 0x62,
- 0x03, 0x24, 0x56, 0xf1, 0x66, 0x13, 0x30, 0x7c, 0xf6, 0x4d, 0xd3, 0xf7,
- 0x66, 0x3c, 0x7a, 0x85, 0xcc, 0xf4, 0x3f, 0xea, 0xf3, 0x90, 0x0c, 0x23,
- 0xb5, 0x18, 0x9f, 0xa5, 0x20, 0x5e, 0x1f, 0xd6, 0x75, 0xff, 0x40, 0x3c,
- 0x29, 0xb3, 0xea, 0xce, 0xbc, 0x39, 0xac, 0x3d, 0x7e, 0x0e, 0x5e, 0x0f,
- 0xf3, 0x1d, 0x50, 0xcc, 0xe4, 0x9e, 0x13, 0xe1, 0x86, 0xd6, 0x17, 0xb6,
- 0x35, 0x64, 0x86, 0x3c, 0xc6, 0x3c, 0x86, 0x57, 0x63, 0x62, 0x15, 0x7d,
- 0x1d, 0x7a, 0x74, 0x5b, 0x64, 0x33, 0x3e, 0x98, 0xdf, 0x83, 0x9c, 0x45,
- 0x0e, 0xbf, 0xbb, 0x1f, 0x47, 0x7f, 0xce, 0xbf, 0x7b, 0x26, 0x45, 0x9d,
- 0x7e, 0x8d, 0xff, 0xfe, 0x0e, 0xa8, 0x3d, 0x01, 0x27, 0xbf, 0x46, 0xc8,
- 0x1f, 0x1d, 0x7e, 0x4d, 0x9e, 0x49, 0xce, 0xbf, 0x3c, 0xbd, 0x8d, 0x3a,
- 0xfc, 0x39, 0xf7, 0x26, 0x3a, 0xff, 0xf6, 0x7f, 0xae, 0xa7, 0xcd, 0xe5,
- 0x19, 0x39, 0xd7, 0xfd, 0xd7, 0x5f, 0x52, 0x37, 0x91, 0xd7, 0xf7, 0xd1,
- 0x96, 0xdb, 0xce, 0x75, 0x49, 0x16, 0xe8, 0x9b, 0xf9, 0xc5, 0x4e, 0x9d,
- 0x28, 0x48, 0x1a, 0x4f, 0xc2, 0x91, 0x26, 0xf4, 0x37, 0xef, 0xfd, 0x8f,
- 0xd9, 0x90, 0x7b, 0x9b, 0x9d, 0x7f, 0x7f, 0x34, 0xa3, 0xda, 0x3a, 0xff,
- 0xff, 0xfd, 0x9d, 0xc1, 0xff, 0x07, 0xdd, 0xce, 0xc6, 0x4c, 0x9c, 0x9b,
- 0xa9, 0xbf, 0x8e, 0xbe, 0x18, 0xc6, 0x4e, 0xbe, 0x8d, 0xf4, 0xe7, 0x54,
- 0x36, 0x4b, 0xb3, 0xa6, 0x04, 0xe3, 0x29, 0xa1, 0xe9, 0x0f, 0x25, 0x72,
- 0x77, 0x94, 0x4a, 0x2b, 0xbe, 0x3d, 0x01, 0x7e, 0xc8, 0x41, 0x7d, 0x20,
- 0xbf, 0xfe, 0x41, 0xc5, 0xc7, 0xd1, 0x04, 0x87, 0x16, 0x75, 0xff, 0x05,
- 0x30, 0x41, 0x2c, 0xd1, 0xd7, 0xfd, 0xd4, 0x97, 0x5e, 0x48, 0xb3, 0xaf,
- 0xfd, 0xa4, 0x1d, 0xe5, 0xe4, 0xd2, 0x1d, 0x58, 0x7e, 0x9e, 0x37, 0xbf,
- 0x69, 0x70, 0x18, 0x3a, 0xa4, 0x99, 0xf6, 0x26, 0xae, 0x15, 0x5e, 0x21,
- 0xbe, 0x18, 0xe4, 0x8e, 0xbf, 0xee, 0xc4, 0x90, 0x44, 0x1b, 0x9d, 0x7f,
- 0xd1, 0x9e, 0xfb, 0xff, 0xf1, 0xb9, 0xd6, 0xe4, 0x22, 0x4f, 0x08, 0x16,
- 0x6f, 0x7f, 0xff, 0xfb, 0xae, 0x9e, 0x90, 0x07, 0xda, 0xeb, 0xcb, 0xe8,
- 0xc3, 0x79, 0x12, 0x3a, 0xff, 0xda, 0xfb, 0xe4, 0x10, 0x4b, 0x34, 0x75,
- 0x2b, 0xa2, 0xdb, 0xae, 0xf7, 0xff, 0xf6, 0x6f, 0x9a, 0x71, 0xea, 0x47,
- 0xba, 0x07, 0x59, 0xd5, 0x09, 0xb4, 0x3c, 0x3a, 0x84, 0x9a, 0xfe, 0x10,
- 0x2d, 0x3b, 0x07, 0x5f, 0xff, 0x9c, 0x7c, 0xef, 0xd1, 0x8f, 0x69, 0x9c,
- 0xe9, 0xd7, 0xfe, 0x9d, 0xc7, 0x5e, 0xea, 0x46, 0x8e, 0xbf, 0xe8, 0xff,
- 0x41, 0x03, 0xf2, 0x47, 0x5e, 0xe6, 0xb4, 0x78, 0x80, 0xef, 0x9a, 0xee,
- 0xd3, 0x44, 0x06, 0xc1, 0xa9, 0xbf, 0xb9, 0x1d, 0x8f, 0x99, 0x24, 0x50,
- 0x71, 0x8a, 0x9d, 0x32, 0x3f, 0xb0, 0xdd, 0xaf, 0xd3, 0x9f, 0xf4, 0x6e,
- 0xb7, 0xb6, 0x47, 0x4e, 0xac, 0x54, 0x24, 0x91, 0xe5, 0x7d, 0x2b, 0xbd,
- 0xd7, 0x57, 0x3a, 0xfa, 0x3f, 0xdb, 0xc3, 0xab, 0xf3, 0xc2, 0xf0, 0xf5,
- 0xf0, 0xfb, 0xf0, 0x1d, 0x7e, 0x5a, 0xb2, 0xac, 0xab, 0x2a, 0xc1, 0xd7,
- 0xff, 0xf4, 0xb3, 0x49, 0xce, 0x22, 0xfe, 0xfb, 0xb8, 0xcf, 0x8e, 0xac,
- 0x45, 0xda, 0x11, 0x39, 0xe5, 0xff, 0xe6, 0x70, 0x7d, 0x83, 0x2c, 0xd7,
- 0xd5, 0x9d, 0x7f, 0xfa, 0x59, 0xbc, 0xbe, 0xc7, 0xec, 0x32, 0xcb, 0x25,
- 0x5f, 0x96, 0xce, 0x26, 0xc3, 0xaf, 0x4b, 0x06, 0x63, 0xfb, 0xfa, 0xa5,
- 0x50, 0x8f, 0xa7, 0x86, 0x2d, 0x42, 0xa2, 0xbe, 0xc3, 0x78, 0x63, 0x27,
- 0xbf, 0xe4, 0x19, 0x69, 0x5a, 0xab, 0x0a, 0xca, 0xb0, 0x75, 0xf4, 0xda,
- 0xc9, 0x8e, 0xbf, 0x7f, 0x1e, 0xc5, 0x73, 0xaf, 0xf4, 0x67, 0x1a, 0xee,
- 0xd3, 0x44, 0x13, 0x7f, 0xd1, 0xec, 0xe3, 0x5d, 0xda, 0x68, 0xbe, 0x6f,
- 0x0e, 0x68, 0x28, 0x80, 0x69, 0xed, 0x0a, 0x37, 0x76, 0x42, 0xaa, 0xff,
- 0xe8, 0xea, 0x29, 0x9c, 0x9d, 0x60, 0xdc, 0xea, 0xc4, 0xdb, 0xd2, 0x30,
- 0x0e, 0x94, 0xdf, 0xe0, 0x77, 0x6f, 0xa8, 0xde, 0x9d, 0x7f, 0xe9, 0xdf,
- 0x7d, 0xbc, 0xf0, 0xbe, 0xc3, 0xaf, 0xff, 0xb3, 0xd0, 0x3e, 0xd6, 0x62,
- 0x8a, 0x3c, 0x8e, 0xbf, 0xf6, 0x06, 0x25, 0x1d, 0xcf, 0xdc, 0xeb, 0xf9,
- 0xe4, 0x09, 0x38, 0x4e, 0xbc, 0xcb, 0x2c, 0x95, 0x7e, 0xee, 0x35, 0xf8,
- 0x53, 0x05, 0xfd, 0xff, 0xfe, 0x9b, 0x91, 0xb3, 0xe2, 0x8f, 0xf3, 0xec,
- 0xda, 0xf9, 0x9b, 0xf8, 0xea, 0xf2, 0x29, 0x7e, 0x9b, 0x5f, 0xfe, 0x4e,
- 0x27, 0x81, 0x9e, 0x75, 0xe0, 0x9d, 0x53, 0xaa, 0x28, 0x6a, 0x1a, 0xd3,
- 0xbf, 0x3c, 0x18, 0x78, 0x78, 0x96, 0xff, 0xcb, 0x8d, 0xf4, 0x39, 0x3f,
- 0xd9, 0x1d, 0x7f, 0xff, 0x93, 0xae, 0x3b, 0xcb, 0xec, 0xa0, 0x64, 0xeb,
- 0xc0, 0x9d, 0x7f, 0xfb, 0x33, 0xa1, 0xec, 0x6b, 0x3a, 0x9f, 0x9d, 0x7f,
- 0x94, 0xf9, 0x34, 0xa3, 0x9a, 0x3a, 0xa7, 0x4c, 0x82, 0x48, 0x21, 0x60,
- 0x44, 0x8b, 0xf9, 0x5f, 0x25, 0xd8, 0xe1, 0xd7, 0xfb, 0xd0, 0x9d, 0x52,
- 0x37, 0x3a, 0xff, 0xf6, 0xe3, 0xf1, 0xbd, 0x4f, 0xff, 0x8e, 0x48, 0xea,
- 0x84, 0x58, 0x21, 0x7f, 0xd3, 0x3b, 0xe5, 0x7d, 0x4b, 0x61, 0xd7, 0xff,
- 0xa2, 0x7f, 0xbd, 0x8d, 0xfd, 0x93, 0x88, 0x4e, 0xa7, 0x3f, 0x41, 0x27,
- 0xbf, 0xd1, 0x83, 0xe5, 0x43, 0x2d, 0x3a, 0xff, 0x77, 0x36, 0x7c, 0xd4,
- 0x9a, 0x75, 0x81, 0xa3, 0xed, 0xf1, 0xb5, 0xfe, 0x71, 0xf9, 0xf7, 0x9d,
- 0x73, 0xaf, 0xd9, 0xc7, 0xdd, 0x93, 0xaf, 0xff, 0xf4, 0xf8, 0xc8, 0xe0,
- 0x78, 0x80, 0x9c, 0x3d, 0x81, 0x9c, 0xea, 0x9d, 0x11, 0x5a, 0x28, 0xbc,
- 0xcb, 0x2c, 0x95, 0x7f, 0xbe, 0xff, 0x03, 0x9b, 0xf8, 0xa6, 0x0b, 0xfb,
- 0xff, 0xf9, 0x53, 0xf1, 0xbd, 0x40, 0x87, 0x19, 0xf9, 0xed, 0x64, 0xe7,
- 0x57, 0x51, 0x54, 0x04, 0x5a, 0x44, 0xc4, 0x1e, 0x1d, 0xb5, 0x3b, 0x28,
- 0x2e, 0x51, 0xde, 0x04, 0xd5, 0x25, 0x2f, 0x72, 0x37, 0xf5, 0xc3, 0xbb,
- 0xb0, 0xa4, 0x18, 0x46, 0xe8, 0xa3, 0xd1, 0xe7, 0xdf, 0xfb, 0x10, 0x67,
- 0x71, 0xf6, 0x2c, 0xeb, 0xff, 0x75, 0x19, 0x0f, 0x73, 0xdb, 0x78, 0x75,
- 0xec, 0x1f, 0xce, 0xbe, 0xcf, 0x4d, 0x23, 0xaf, 0xfe, 0xda, 0x18, 0xda,
- 0xd3, 0x8f, 0xdf, 0xf4, 0x75, 0x74, 0xfb, 0x5c, 0x8a, 0xff, 0xd9, 0xe8,
- 0xe6, 0xbb, 0x03, 0xe3, 0xc4, 0x11, 0x7f, 0xa3, 0x38, 0xd7, 0x76, 0x9a,
- 0x20, 0x86, 0x0f, 0x26, 0xfe, 0x7e, 0xf3, 0x88, 0xc9, 0xd7, 0xf2, 0xb8,
- 0x59, 0x71, 0x91, 0xd4, 0x27, 0xba, 0x02, 0xdb, 0xff, 0xf4, 0x06, 0x69,
- 0x20, 0xfa, 0x3f, 0x98, 0x52, 0x63, 0xa9, 0x45, 0x42, 0xbd, 0x84, 0x47,
- 0xed, 0x43, 0x0a, 0xcd, 0x84, 0x37, 0xf7, 0x73, 0xde, 0x45, 0x9d, 0x7f,
- 0x7b, 0xee, 0x75, 0xf7, 0x3a, 0xb7, 0x3d, 0xb1, 0x2c, 0xbf, 0xfd, 0xad,
- 0x0b, 0xf9, 0xd7, 0xf6, 0x27, 0xc3, 0xaa, 0x0f, 0xb0, 0x04, 0x57, 0xf6,
- 0x37, 0xee, 0xce, 0xe1, 0xd7, 0x42, 0x87, 0x5e, 0x0a, 0x09, 0xd7, 0x84,
- 0x13, 0x9d, 0x7e, 0xeb, 0xcb, 0x04, 0xeb, 0xf9, 0x3c, 0x39, 0xd4, 0x3a,
- 0xec, 0xef, 0xc3, 0xcf, 0x82, 0x5b, 0x9d, 0x9f, 0x88, 0xc9, 0xc1, 0x6e,
- 0x8d, 0x79, 0xae, 0xa4, 0x9b, 0x26, 0x10, 0x8c, 0x3e, 0x6f, 0xff, 0xef,
- 0x77, 0x35, 0xac, 0xc0, 0x72, 0x7c, 0x00, 0xf8, 0xeb, 0xfe, 0xec, 0x73,
- 0xc3, 0x19, 0xb9, 0xd7, 0xff, 0xfc, 0x93, 0xc4, 0xb5, 0xce, 0x26, 0xf3,
- 0x49, 0xf8, 0xbc, 0xdc, 0xeb, 0xdd, 0xc1, 0x0a, 0x28, 0x3a, 0x6f, 0x48,
- 0x99, 0x6f, 0xa1, 0xf5, 0x7f, 0xe6, 0xf6, 0x33, 0x92, 0xd0, 0x16, 0x75,
- 0xc9, 0xa3, 0xaf, 0xfb, 0x27, 0x7f, 0x7f, 0xf4, 0x64, 0x75, 0xfd, 0xf5,
- 0x7a, 0x65, 0xf7, 0x3a, 0xa1, 0x1c, 0xf8, 0x50, 0xa1, 0xf7, 0x05, 0x7c,
- 0x77, 0x7b, 0x99, 0xd3, 0xaf, 0x69, 0x16, 0x75, 0xa3, 0x86, 0xdb, 0xc3,
- 0x77, 0xc9, 0x32, 0x32, 0x75, 0xff, 0xcb, 0x7d, 0xfe, 0xf9, 0x39, 0x00,
- 0x54, 0x9d, 0x7f, 0xfe, 0x04, 0xe3, 0x19, 0xd6, 0x23, 0xd9, 0xd0, 0x70,
- 0xeb, 0xef, 0x6b, 0xee, 0x82, 0x8c, 0x1c, 0x22, 0xfa, 0x95, 0x7e, 0xd2,
- 0xf3, 0xda, 0x3a, 0xfc, 0xf2, 0x14, 0x83, 0xaf, 0xe8, 0x71, 0xf6, 0x09,
- 0xd5, 0x24, 0xe9, 0xb2, 0x1c, 0xe8, 0x96, 0xb2, 0x71, 0x24, 0xbf, 0x9b,
- 0xd4, 0xdb, 0x45, 0x0e, 0xbf, 0xfc, 0x9f, 0xc6, 0x97, 0x09, 0xce, 0x23,
- 0x27, 0x5f, 0x2b, 0xf7, 0x27, 0x3a, 0xff, 0x40, 0x73, 0xc9, 0xd0, 0x1d,
- 0x65, 0xc1, 0xeb, 0x04, 0x96, 0xff, 0xff, 0xcb, 0x71, 0xfe, 0x49, 0xa0,
- 0x2f, 0xa9, 0x1e, 0xe8, 0x1d, 0x67, 0x5f, 0xff, 0x08, 0x3d, 0x24, 0xff,
- 0xae, 0x9e, 0x75, 0x9d, 0x77, 0xc5, 0x73, 0xaf, 0xff, 0xce, 0x9e, 0x40,
- 0xe0, 0x73, 0xc8, 0xb4, 0xe1, 0xd7, 0xb8, 0xfa, 0xc4, 0x5d, 0x71, 0x3b,
- 0xa3, 0x77, 0x27, 0x9d, 0x36, 0x50, 0x46, 0x4b, 0x74, 0xa0, 0xeb, 0xff,
- 0xd3, 0x87, 0xb1, 0xdc, 0xdf, 0xfc, 0xf6, 0x8e, 0xa7, 0x3e, 0x10, 0x0a,
- 0xd0, 0x55, 0x88, 0xe1, 0x82, 0x42, 0x7d, 0xe3, 0x8c, 0x18, 0x4a, 0xdf,
- 0xdc, 0x89, 0xd0, 0x7c, 0x75, 0xe0, 0xfd, 0x59, 0xd7, 0xe1, 0x80, 0xe4,
- 0xc7, 0x5f, 0x68, 0x1c, 0x50, 0xeb, 0xf4, 0x77, 0xd1, 0x23, 0xaf, 0x82,
- 0x0f, 0x6a, 0x0f, 0xbf, 0x72, 0x6f, 0xc8, 0xef, 0xdf, 0xe2, 0xe3, 0xa7,
- 0x5e, 0x54, 0xf7, 0x0e, 0xa0, 0xa6, 0x8f, 0x85, 0x89, 0x08, 0xd1, 0x48,
- 0x01, 0x3d, 0xee, 0x7d, 0xd1, 0xd7, 0x42, 0xb4, 0x3a, 0xff, 0xce, 0x2d,
- 0xce, 0x35, 0xdd, 0xa6, 0x88, 0x46, 0xe9, 0x4e, 0x75, 0x42, 0x26, 0x3f,
- 0x1e, 0x00, 0xde, 0xc4, 0x8b, 0xff, 0xff, 0xdd, 0xc0, 0x71, 0x4e, 0xa6,
- 0xf1, 0xe0, 0x74, 0x73, 0x7f, 0x01, 0xf4, 0x75, 0xff, 0xd9, 0xbf, 0xdf,
- 0x20, 0x82, 0x59, 0xa3, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x33,
- 0x8b, 0x86, 0x06, 0x78, 0xe0, 0x70, 0x73, 0xda, 0x46, 0xe0, 0xfd, 0x9f,
- 0x39, 0x1a, 0x17, 0x53, 0x58, 0x9f, 0xfe, 0x0f, 0xc5, 0xc3, 0x03, 0x3c,
- 0x70, 0xea, 0x84, 0xd3, 0xf1, 0x16, 0xff, 0xef, 0x38, 0xcf, 0xbc, 0x86,
- 0x33, 0x47, 0x5f, 0xfb, 0xee, 0x75, 0xd6, 0xc3, 0x2c, 0xb2, 0x75, 0xff,
- 0xfb, 0x1b, 0xd8, 0x10, 0x8a, 0x4f, 0x82, 0x8a, 0x1d, 0x73, 0xbc, 0xe8,
- 0x96, 0x92, 0x25, 0xff, 0xfd, 0x30, 0xc7, 0xfa, 0x6f, 0x53, 0x93, 0x0c,
- 0x7f, 0xa3, 0xaf, 0xfe, 0xf7, 0x53, 0x67, 0x5e, 0x5c, 0x85, 0x0e, 0xbf,
- 0x81, 0xe4, 0x00, 0xa8, 0x75, 0xfd, 0x8c, 0xe0, 0x83, 0xf3, 0xaf, 0xd2,
- 0xcf, 0x47, 0xe7, 0x5d, 0x0b, 0x9c, 0xf5, 0x37, 0x2d, 0xbf, 0xff, 0xfb,
- 0xf5, 0xbc, 0xba, 0xe9, 0xe4, 0x0e, 0x07, 0x3c, 0x8b, 0x4e, 0x1d, 0x5a,
- 0x44, 0xf0, 0x0b, 0xef, 0xd3, 0xae, 0x03, 0x07, 0x54, 0x97, 0x3f, 0x43,
- 0x1e, 0x46, 0xe4, 0x53, 0x43, 0x67, 0x85, 0xdd, 0x5d, 0xd2, 0x37, 0xa3,
- 0x1f, 0xfa, 0x47, 0x7f, 0xa3, 0x5a, 0x89, 0xf1, 0x93, 0xaf, 0xf7, 0x71,
- 0x79, 0xd0, 0x09, 0xd4, 0x13, 0xe4, 0xf1, 0x9d, 0x62, 0x63, 0x8f, 0x0f,
- 0xab, 0xcc, 0xb2, 0xc9, 0x57, 0xfd, 0x9f, 0xbf, 0x33, 0x66, 0x04, 0xa6,
- 0x0b, 0xfb, 0x99, 0x64, 0xab, 0xcc, 0xb2, 0xc9, 0x57, 0xf3, 0xce, 0x1e,
- 0xc6, 0x8a, 0x60, 0xbf, 0xa1, 0x45, 0xeb, 0x29, 0x3b, 0x66, 0xf7, 0xe6,
- 0xa0, 0x7e, 0xac, 0xa6, 0x0d, 0x9d, 0xe6, 0x59, 0x64, 0xab, 0xda, 0x8e,
- 0x14, 0xc1, 0x7f, 0x7c, 0xe3, 0xbf, 0x8e, 0xb7, 0xe8, 0x8a, 0x5f, 0x2c,
- 0xb2, 0x57, 0x7f, 0x04, 0x62, 0x4e, 0xd3, 0xaf, 0xda, 0x04, 0xfb, 0x62,
- 0x75, 0xf8, 0x29, 0xb2, 0x02, 0x75, 0xf6, 0x0e, 0x2b, 0x9d, 0x5c, 0x3c,
- 0xa5, 0x94, 0x52, 0x22, 0x5f, 0xeb, 0xad, 0xff, 0xdd, 0x79, 0x0b, 0xa9,
- 0x30, 0xa4, 0xc7, 0x5f, 0xfd, 0x9c, 0x9e, 0x37, 0xd2, 0x0e, 0x7e, 0x75,
- 0xfd, 0xdc, 0xd9, 0x9e, 0xd1, 0xd4, 0xd4, 0x5b, 0x7e, 0x89, 0xe4, 0x4a,
- 0xe2, 0x79, 0xbd, 0x86, 0x10, 0xc3, 0x6a, 0xe9, 0xfc, 0x75, 0x42, 0xa5,
- 0x5c, 0x94, 0x08, 0x27, 0x57, 0xb7, 0x56, 0xaa, 0xc1, 0xd7, 0xff, 0xb1,
- 0x5d, 0xc7, 0xfc, 0x6c, 0x76, 0x16, 0x75, 0xf6, 0xba, 0x93, 0x15, 0x7f,
- 0xcf, 0xbf, 0xb2, 0x60, 0x71, 0x43, 0xac, 0xd4, 0x3d, 0xd0, 0x11, 0x5f,
- 0xe1, 0xcd, 0xe5, 0xa4, 0x50, 0xeb, 0xe7, 0x7e, 0x28, 0x75, 0x7c, 0x3d,
- 0x49, 0xcc, 0xef, 0xfb, 0x31, 0xbf, 0xc6, 0x6f, 0x23, 0xaf, 0xa1, 0xd7,
- 0xb0, 0xab, 0xff, 0xba, 0x8f, 0xff, 0xf1, 0xfc, 0x77, 0x47, 0x5f, 0xdd,
- 0xc5, 0xad, 0xe4, 0x75, 0xe6, 0x59, 0x64, 0xab, 0xfc, 0x3e, 0xea, 0x40,
- 0xce, 0x53, 0x05, 0xfd, 0xe8, 0xff, 0x24, 0x88, 0xcc, 0x4b, 0xaf, 0x26,
- 0x09, 0xf6, 0x1a, 0x36, 0xc6, 0xa6, 0xa2, 0xb8, 0xc9, 0xaf, 0xf4, 0x7d,
- 0xe7, 0x13, 0xda, 0x3a, 0xa1, 0x5a, 0xdc, 0x8a, 0x37, 0x85, 0x3a, 0x3d,
- 0xcc, 0x4b, 0xd8, 0xe2, 0x44, 0xbe, 0xfd, 0xfe, 0x27, 0x54, 0x3a, 0xff,
- 0xfb, 0x1b, 0x02, 0xfe, 0xd0, 0x40, 0xfc, 0x91, 0xd5, 0xb9, 0xfa, 0xac,
- 0xa2, 0xf3, 0x63, 0x47, 0x5f, 0xfd, 0xf6, 0x59, 0xd7, 0xea, 0x73, 0x90,
- 0x75, 0x61, 0xef, 0xfe, 0x37, 0x7e, 0x8f, 0x6b, 0x66, 0x1d, 0x7e, 0x07,
- 0x14, 0xea, 0x1d, 0x50, 0x8f, 0x41, 0x84, 0x17, 0x88, 0xb6, 0xca, 0x2f,
- 0xff, 0x93, 0x66, 0x08, 0x45, 0xd9, 0xc1, 0x75, 0x0e, 0xbf, 0xff, 0xe0,
- 0xf5, 0x19, 0xcd, 0xa4, 0x5b, 0xfb, 0x40, 0x96, 0x6f, 0xe3, 0xab, 0x11,
- 0x70, 0xe9, 0xd7, 0xfd, 0x33, 0x7a, 0x8b, 0x8e, 0x28, 0x75, 0xfa, 0x7f,
- 0x80, 0x89, 0x8e, 0xb4, 0x8e, 0xbd, 0xf4, 0x66, 0x3a, 0xa4, 0x6b, 0xbf,
- 0x10, 0xac, 0x45, 0xab, 0x9d, 0x69, 0x66, 0xa1, 0xd9, 0xbc, 0x4f, 0x28,
- 0xf6, 0x52, 0x91, 0x43, 0x2a, 0x97, 0x29, 0x48, 0xca, 0x42, 0xd9, 0xa7,
- 0x69, 0x29, 0x5a, 0x69, 0x50, 0x9c, 0x94, 0x90, 0xb9, 0x44, 0xbd, 0x96,
- 0xbc, 0xf1, 0xcf, 0xff, 0x0e, 0x51, 0x9e, 0x58, 0xd4, 0xe1, 0x87, 0xa5,
- 0xc8, 0x82, 0x3d, 0x96, 0x61, 0xf7, 0xf6, 0x1a, 0xd7, 0xb6, 0x40, 0x9d,
- 0x7f, 0xfd, 0x82, 0xc7, 0x94, 0x4d, 0xf5, 0xdc, 0xfd, 0xce, 0xa9, 0x1f,
- 0x68, 0x47, 0x2f, 0xf3, 0x8b, 0x73, 0xdd, 0x43, 0xab, 0x73, 0xd2, 0x59,
- 0x15, 0x95, 0xa1, 0xd7, 0xfe, 0x71, 0xff, 0xe0, 0x40, 0xfc, 0x91, 0xd7,
- 0xc8, 0x33, 0xc1, 0xd4, 0xae, 0x7c, 0x1c, 0x40, 0xa5, 0x5e, 0x89, 0xbc,
- 0x76, 0xbd, 0x03, 0x39, 0xd7, 0xc9, 0xd4, 0x59, 0xd6, 0xea, 0x1b, 0xb9,
- 0x86, 0xef, 0xe8, 0x6c, 0x6b, 0xc8, 0x75, 0xff, 0x47, 0xba, 0xff, 0xbe,
- 0xfa, 0x3a, 0x82, 0x7c, 0x82, 0x57, 0x7f, 0xee, 0x7f, 0xf3, 0xa8, 0xd0,
- 0x73, 0xf3, 0xaf, 0x4c, 0x0e, 0x1d, 0x7f, 0xe7, 0x4e, 0x66, 0xec, 0x32,
- 0xcb, 0x27, 0x54, 0x22, 0x89, 0xd0, 0xf4, 0x3b, 0x7f, 0xfc, 0x31, 0x2f,
- 0x9f, 0x7c, 0x82, 0x09, 0x66, 0x8e, 0xac, 0x4f, 0x35, 0xb0, 0x8b, 0xec,
- 0x30, 0xff, 0x2e, 0xbf, 0xd0, 0x32, 0x1c, 0xcf, 0xce, 0xbf, 0xb3, 0x9a,
- 0x18, 0x9c, 0xeb, 0xf9, 0xfd, 0xd7, 0x1f, 0xce, 0xbf, 0xf3, 0xfb, 0x26,
- 0x78, 0x18, 0x98, 0xeb, 0x27, 0x0f, 0xa3, 0xa5, 0x97, 0x35, 0xa6, 0x8c,
- 0x12, 0xa4, 0x8d, 0xe6, 0xc2, 0x53, 0xf2, 0x7b, 0xb0, 0x4e, 0xbf, 0xfd,
- 0xe8, 0x16, 0xe7, 0xba, 0x9c, 0xfd, 0xa7, 0x50, 0x4f, 0x77, 0x05, 0x2f,
- 0xf4, 0x2f, 0x5a, 0x71, 0x9c, 0xeb, 0xed, 0x60, 0xf8, 0xeb, 0xdb, 0x51,
- 0xc3, 0xa9, 0xcd, 0xf0, 0x08, 0x2f, 0x79, 0xd5, 0xce, 0xbf, 0xde, 0xea,
- 0x31, 0xfb, 0xa1, 0xd4, 0x14, 0xc0, 0xba, 0x42, 0x2e, 0x1e, 0x20, 0x00,
- 0xf5, 0xf7, 0x51, 0xe4, 0x75, 0xe0, 0xbc, 0x8e, 0xb8, 0x1f, 0xc1, 0xbb,
- 0xc2, 0x0b, 0xfe, 0x6e, 0x7a, 0x36, 0x20, 0xfe, 0x75, 0xff, 0xfc, 0x08,
- 0xf6, 0xb0, 0x7e, 0x72, 0x10, 0x22, 0xf2, 0x3a, 0xfc, 0xde, 0xee, 0xea,
- 0xe7, 0x5f, 0xfc, 0x81, 0x10, 0x7b, 0x50, 0x31, 0xa3, 0xa9, 0x11, 0xfc,
- 0x27, 0x20, 0x59, 0xd8, 0x57, 0x7f, 0xf7, 0xef, 0xcc, 0xd9, 0x81, 0xe0,
- 0xb2, 0x75, 0xff, 0xfc, 0x39, 0xa0, 0x7c, 0xce, 0xb8, 0xe4, 0xd2, 0x8d,
- 0xce, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x40, 0xd7, 0xf3, 0xcf, 0xfb, 0x88,
- 0x49, 0x58, 0x3e, 0xf6, 0x68, 0x18, 0x7d, 0xdb, 0x66, 0x77, 0xba, 0xf2,
- 0xf8, 0x8f, 0xe1, 0x86, 0x4d, 0x2d, 0x37, 0xef, 0x46, 0x89, 0x7f, 0xc3,
- 0xff, 0x92, 0x75, 0xc3, 0x4e, 0xbf, 0x05, 0x5b, 0x70, 0xab, 0x67, 0x54,
- 0x2a, 0x4f, 0xc8, 0xee, 0xd0, 0xa9, 0xce, 0x6f, 0xf6, 0x6f, 0xe0, 0xe6,
- 0x28, 0x75, 0xfd, 0x9e, 0x81, 0x4f, 0xce, 0xbc, 0xfc, 0x9c, 0xd1, 0x82,
- 0xdf, 0xf9, 0xf9, 0x83, 0xfe, 0xbd, 0xad, 0xce, 0xbf, 0xff, 0xff, 0xb3,
- 0xdd, 0x71, 0x53, 0xe6, 0xb8, 0xef, 0xed, 0x98, 0x1f, 0x98, 0xb7, 0x1d,
- 0xe4, 0x78, 0x82, 0xef, 0xfc, 0xee, 0xa3, 0x5c, 0x3f, 0x14, 0x64, 0xf1,
- 0x05, 0xdf, 0xfd, 0xd4, 0xea, 0x40, 0xfb, 0xe2, 0x8c, 0x9e, 0x20, 0xbb,
- 0xfd, 0x08, 0x3e, 0xf8, 0xa3, 0x27, 0x88, 0x2e, 0xfe, 0x5e, 0x07, 0xe2,
- 0x8c, 0x9e, 0x20, 0xbb, 0xff, 0xfe, 0x71, 0x14, 0x5f, 0xcd, 0x37, 0xa9,
- 0xc4, 0x52, 0x7c, 0x64, 0xf1, 0x05, 0xdd, 0xbf, 0xc0, 0xa7, 0x2e, 0xd4,
- 0xfe, 0x29, 0xba, 0x10, 0x9f, 0x54, 0x2a, 0xc8, 0xe9, 0xf8, 0xca, 0x31,
- 0xbf, 0xc9, 0x0a, 0x6b, 0xda, 0xdc, 0xeb, 0xe7, 0xe7, 0xee, 0x75, 0xff,
- 0xdd, 0x4e, 0xa4, 0x0f, 0xbe, 0x28, 0xc9, 0xe2, 0x0b, 0xbf, 0xe9, 0xb4,
- 0xd4, 0x9f, 0xe2, 0x8c, 0x9e, 0x20, 0xbb, 0xf7, 0xb5, 0x0b, 0xf8, 0xd4,
- 0x4f, 0xfd, 0x53, 0xbf, 0xfd, 0xf1, 0xbd, 0x46, 0xc7, 0xb5, 0xf1, 0x46,
- 0x4f, 0x10, 0x5d, 0xff, 0xff, 0xc2, 0x28, 0xbf, 0x80, 0xcf, 0x9a, 0x6f,
- 0x53, 0x88, 0xa4, 0xf8, 0xc9, 0xe2, 0x0b, 0xac, 0x4c, 0x93, 0x74, 0x47,
- 0x5d, 0xbf, 0xee, 0xa7, 0x11, 0x49, 0xf1, 0x93, 0xc4, 0x17, 0x7f, 0xfc,
- 0xef, 0xbc, 0xb5, 0xd4, 0x08, 0x63, 0x90, 0x55, 0xff, 0xb2, 0x52, 0x06,
- 0xb8, 0x33, 0xed, 0x9e, 0x20, 0xba, 0x6a, 0x39, 0x38, 0x8f, 0xa4, 0xeb,
- 0xff, 0x35, 0x39, 0xe7, 0xff, 0x5f, 0x19, 0x3c, 0x41, 0x77, 0xf7, 0x53,
- 0xbd, 0x4f, 0xcd, 0x00, 0x5d, 0xfb, 0x3f, 0xf8, 0xa3, 0x27, 0x88, 0x2e,
- 0xec, 0xf3, 0x4f, 0xcf, 0xa7, 0x55, 0xba, 0x3b, 0xf5, 0x0c, 0x2b, 0xf9,
- 0x78, 0x1f, 0x8a, 0x32, 0x78, 0x82, 0xef, 0xfc, 0xde, 0xa7, 0x11, 0x49,
- 0xf1, 0x93, 0xc4, 0x17, 0x76, 0x7c, 0x74, 0x45, 0xe8, 0xfa, 0xff, 0x01,
- 0x16, 0xe3, 0xbc, 0x8f, 0x10, 0x5d, 0xff, 0xb1, 0x36, 0x60, 0xe0, 0x5e,
- 0x47, 0x88, 0x2d, 0x66, 0xfe, 0x82, 0xbb, 0xfb, 0xc3, 0x7f, 0xcd, 0x06,
- 0x3e, 0x4d, 0x46, 0x29, 0xe8, 0xc7, 0xc1, 0x0b, 0x46, 0x5b, 0xae, 0xfe,
- 0x0d, 0x10, 0x5b, 0x08, 0x8c, 0xb9, 0xda, 0x75, 0xb4, 0xd6, 0x4e, 0x2f,
- 0xf4, 0x97, 0xaf, 0x1b, 0x5d, 0x2d, 0xa3, 0xaf, 0x44, 0xb6, 0x8e, 0xa8,
- 0x36, 0xe2, 0x33, 0x53, 0xb2, 0xaf, 0x42, 0x67, 0xfd, 0x27, 0xc0, 0x5e,
- 0xef, 0xfe, 0xc9, 0x0e, 0x7b, 0xa9, 0x9b, 0xf8, 0xeb, 0xf4, 0x7b, 0x5d,
- 0x43, 0xaf, 0xfd, 0xa9, 0xa4, 0x00, 0xcd, 0x20, 0x04, 0xea, 0x91, 0xf4,
- 0x78, 0x9a, 0xff, 0xe8, 0xde, 0x5f, 0x57, 0xaf, 0x46, 0xec, 0x9d, 0x7e,
- 0x96, 0xd6, 0xd0, 0x27, 0x3a, 0xdd, 0x43, 0xf8, 0x74, 0x9b, 0xf7, 0x23,
- 0x79, 0x68, 0xea, 0x91, 0xe7, 0x70, 0x9a, 0xff, 0xef, 0xc1, 0xad, 0xbc,
- 0xe7, 0xeb, 0x4d, 0x1d, 0x7f, 0xbf, 0x07, 0x86, 0x3d, 0xa3, 0xab, 0xf3,
- 0xfc, 0xd2, 0x4d, 0x42, 0x75, 0x39, 0x0e, 0x87, 0x84, 0xf5, 0xfc, 0xf2,
- 0x8d, 0x8f, 0xd3, 0xaf, 0xb7, 0xd4, 0x6e, 0x75, 0xe5, 0xc4, 0x8e, 0xbf,
- 0x60, 0x7a, 0x06, 0x4e, 0xaf, 0x87, 0xcc, 0xe4, 0x62, 0x37, 0x78, 0x2f,
- 0xe3, 0xab, 0x87, 0x94, 0xe5, 0xf7, 0x93, 0x6f, 0x0e, 0xbc, 0xfc, 0xfc,
- 0xeb, 0x6f, 0x06, 0xe7, 0xc3, 0xb7, 0xcc, 0xe7, 0x5c, 0xeb, 0xe5, 0x38,
- 0x8c, 0x9d, 0x7e, 0x9d, 0xfb, 0x0a, 0xe7, 0x52, 0xb0, 0x79, 0xb8, 0x47,
- 0x50, 0x9f, 0x92, 0x43, 0x75, 0xd6, 0xbf, 0x27, 0x16, 0xeb, 0xff, 0xc2,
- 0x31, 0x3a, 0xfa, 0x9c, 0xe3, 0xc8, 0xeb, 0xfd, 0x3c, 0xf0, 0x3b, 0xe7,
- 0x8e, 0xac, 0x3f, 0xc4, 0x48, 0xbf, 0xfb, 0x82, 0x0d, 0xfc, 0x39, 0x3b,
- 0x89, 0xd7, 0x9f, 0x93, 0x9d, 0x77, 0xf0, 0x75, 0xf2, 0x42, 0xf0, 0xea,
- 0x3a, 0xfe, 0x75, 0x3d, 0x1c, 0xfc, 0xea, 0x09, 0xb8, 0x10, 0xab, 0xff,
- 0xfd, 0x08, 0x11, 0x80, 0x37, 0xd8, 0xd0, 0xc3, 0x7e, 0xac, 0xeb, 0xbf,
- 0x83, 0xae, 0x85, 0x0e, 0xbf, 0xec, 0xf6, 0xa1, 0x7f, 0x72, 0x63, 0xaf,
- 0xf6, 0xb3, 0xa9, 0xa0, 0x4e, 0x75, 0xcc, 0xb2, 0x55, 0xff, 0x0e, 0x6c,
- 0x79, 0x69, 0x02, 0x75, 0x35, 0x3f, 0x24, 0x1c, 0xe0, 0xb2, 0xd5, 0xfa,
- 0x41, 0xfb, 0x02, 0xa4, 0x58, 0x45, 0xb4, 0x74, 0xc9, 0x9f, 0xd1, 0x8b,
- 0xcc, 0xb2, 0xc9, 0x56, 0x59, 0x4c, 0x17, 0xf7, 0xd3, 0x3b, 0xf0, 0xa6,
- 0x11, 0xbd, 0xf6, 0x17, 0xd5, 0x3a, 0xb5, 0xb7, 0x96, 0x27, 0x7f, 0x7a,
- 0x33, 0xb9, 0x39, 0xd7, 0x62, 0xce, 0xad, 0xcf, 0x07, 0x45, 0x95, 0x0d,
- 0xf3, 0x8c, 0xa1, 0x7d, 0x92, 0x8c, 0x14, 0x48, 0xde, 0x30, 0xe4, 0x8e,
- 0x57, 0x90, 0x85, 0xec, 0xb7, 0x97, 0xa5, 0x7f, 0x7e, 0x96, 0x32, 0x94,
- 0xf5, 0x28, 0xab, 0xd0, 0xc9, 0x04, 0xb7, 0xbd, 0x8d, 0xb7, 0xf6, 0x7f,
- 0xfa, 0x72, 0x47, 0x5c, 0xdc, 0x3a, 0x82, 0x78, 0x6e, 0x5d, 0x76, 0x32,
- 0x75, 0xd1, 0xe3, 0xaa, 0x73, 0x56, 0xd1, 0x6b, 0x2c, 0xea, 0xc3, 0x65,
- 0xe2, 0x2b, 0xfd, 0x24, 0x1c, 0x58, 0x3a, 0x75, 0xff, 0xb3, 0xda, 0xea,
- 0x2d, 0xf3, 0x87, 0x54, 0x1f, 0x68, 0x98, 0xdf, 0x7c, 0xf4, 0x6c, 0x3a,
- 0xfb, 0x17, 0x9e, 0x3a, 0xf7, 0x9d, 0x43, 0xaf, 0xff, 0xfe, 0x6b, 0xcc,
- 0x09, 0x01, 0xbf, 0x3a, 0x9e, 0xf4, 0x6f, 0x13, 0xc6, 0x8e, 0xbf, 0xff,
- 0xe5, 0x71, 0x77, 0xd9, 0x12, 0xec, 0x72, 0x78, 0xf6, 0x9e, 0x47, 0x5e,
- 0x4d, 0xe6, 0x3a, 0xfd, 0x99, 0x38, 0x34, 0x75, 0xf7, 0x05, 0x3f, 0x3a,
- 0xf9, 0x1a, 0xfc, 0x3a, 0xe8, 0xfc, 0xeb, 0xe0, 0x4e, 0x06, 0x3a, 0x6d,
- 0xbe, 0x90, 0x52, 0x22, 0x53, 0xaa, 0xf7, 0xfd, 0xd7, 0xd7, 0x52, 0x77,
- 0x13, 0xaf, 0x9e, 0x7f, 0xb2, 0x3a, 0x95, 0x4a, 0xf0, 0x21, 0xfa, 0x50,
- 0x8d, 0xc2, 0x0d, 0xc9, 0x50, 0x83, 0x83, 0x8e, 0xed, 0xfb, 0x4e, 0x87,
- 0x7d, 0x0b, 0xbf, 0xa4, 0x5b, 0x46, 0xf7, 0xf0, 0x80, 0x2b, 0x79, 0x1d,
- 0x79, 0x27, 0x01, 0xd7, 0xe8, 0xfd, 0x37, 0xc3, 0xae, 0x5e, 0xc3, 0xac,
- 0x18, 0x37, 0xe2, 0x4f, 0x7f, 0xfa, 0x43, 0x1f, 0x16, 0x30, 0xa7, 0x92,
- 0x73, 0xaf, 0xce, 0xbc, 0xea, 0xce, 0xad, 0xcf, 0xc7, 0xc9, 0x77, 0xbd,
- 0xc8, 0x3a, 0xff, 0x6b, 0xdb, 0x30, 0x70, 0x27, 0x54, 0x27, 0x1d, 0x22,
- 0xcc, 0x5b, 0x48, 0x4b, 0x2c, 0x8d, 0xc6, 0xef, 0x3f, 0xcf, 0xa7, 0x5f,
- 0x2d, 0x70, 0xb3, 0xaf, 0xff, 0x86, 0x5f, 0x30, 0x29, 0xad, 0xfc, 0x07,
- 0xd1, 0xd7, 0xfb, 0xe8, 0xbf, 0xa5, 0x0a, 0x1d, 0x7d, 0x99, 0xbc, 0x8e,
- 0xbd, 0xa4, 0x98, 0xeb, 0x28, 0x26, 0xf7, 0x44, 0x37, 0xff, 0x3c, 0xe3,
- 0x1b, 0xa0, 0x46, 0x27, 0x3a, 0xb8, 0x7d, 0x42, 0x4f, 0x7e, 0xf9, 0xd8,
- 0xe4, 0x8e, 0xaf, 0x89, 0xdb, 0x40, 0xfe, 0x10, 0xb5, 0x45, 0xe1, 0xb6,
- 0xc9, 0x0d, 0xe5, 0xea, 0x0e, 0xbf, 0xa7, 0x9a, 0x4a, 0xae, 0x4e, 0x75,
- 0xf2, 0xf1, 0xfa, 0x75, 0xd2, 0x9c, 0xeb, 0xdd, 0x0a, 0x1d, 0x7e, 0xee,
- 0x24, 0xb4, 0x75, 0xff, 0xf7, 0x63, 0xeb, 0x1e, 0x17, 0xff, 0x5a, 0x8f,
- 0xca, 0xbf, 0x71, 0xae, 0xed, 0x3c, 0x40, 0x97, 0xb5, 0x1b, 0x9d, 0x6f,
- 0xf0, 0xf3, 0xf7, 0x33, 0xbd, 0xe4, 0x9c, 0xeb, 0xd3, 0xb8, 0x9d, 0x52,
- 0x4c, 0xa0, 0x24, 0xdc, 0x85, 0x12, 0xca, 0x7c, 0x39, 0x7f, 0x0b, 0x5d,
- 0x4e, 0xa1, 0xd7, 0x6d, 0x48, 0xeb, 0xef, 0x4e, 0xe2, 0x75, 0xe1, 0x75,
- 0x0e, 0xbc, 0xa2, 0x78, 0xeb, 0xda, 0x7f, 0x1d, 0x4a, 0x1b, 0x7d, 0xc7,
- 0x2e, 0xf9, 0xd3, 0xaf, 0xe5, 0xf9, 0x02, 0x08, 0x3a, 0xf2, 0xfc, 0xd3,
- 0xad, 0xe8, 0x3c, 0x8c, 0x2c, 0xa9, 0xd3, 0x35, 0xc1, 0x96, 0x90, 0xf5,
- 0x4b, 0xf2, 0x31, 0x60, 0xbb, 0x80, 0x3a, 0xff, 0x0b, 0xb3, 0xad, 0x47,
- 0xe7, 0x5e, 0xdb, 0x75, 0x0e, 0xbf, 0xe8, 0x5c, 0xb2, 0x7c, 0x02, 0xa4,
- 0xeb, 0xe7, 0xf2, 0xa6, 0x73, 0xab, 0x11, 0x02, 0x83, 0xee, 0x79, 0x79,
- 0x96, 0x59, 0x3d, 0x5f, 0x57, 0x9c, 0x42, 0x5a, 0xbe, 0xac, 0x1a, 0xcb,
- 0xf6, 0x48, 0x10, 0xa1, 0xd5, 0x09, 0xc1, 0x84, 0x5b, 0x90, 0xb4, 0xfd,
- 0x67, 0xc7, 0x37, 0xff, 0xec, 0x14, 0x51, 0x8d, 0x7b, 0xa0, 0x79, 0x4a,
- 0x0e, 0xa9, 0xd1, 0x4a, 0xa2, 0x85, 0xf6, 0x05, 0xe4, 0x75, 0xf9, 0xc4,
- 0x51, 0x67, 0x5f, 0xf7, 0x53, 0x98, 0x8b, 0x85, 0x73, 0xaf, 0xc8, 0xb7,
- 0x1c, 0x3a, 0xbe, 0x2f, 0x60, 0xab, 0x23, 0x70, 0x6b, 0x22, 0x00, 0x8b,
- 0xe4, 0x68, 0x6a, 0x28, 0x24, 0x6c, 0x2f, 0x2a, 0x03, 0xf2, 0x51, 0x20,
- 0x01, 0x26, 0xd9, 0xcd, 0xf9, 0x3d, 0x1e, 0xd1, 0x57, 0xcd, 0x8f, 0x68,
- 0xab, 0x99, 0x64, 0xaa, 0x91, 0xef, 0xe1, 0x33, 0x24, 0x37, 0x63, 0x25,
- 0x30, 0x6b, 0xef, 0xff, 0xbd, 0x0d, 0xcc, 0x1f, 0x75, 0x20, 0x67, 0x3a,
- 0x8e, 0xac, 0x3d, 0x6d, 0x26, 0x57, 0xe8, 0x9e, 0x65, 0xf6, 0xff, 0xff,
- 0x46, 0xc4, 0x1f, 0xfe, 0x7b, 0x58, 0xde, 0xb8, 0xfb, 0x47, 0x5f, 0xa5,
- 0xd0, 0x47, 0x0e, 0xbf, 0xf9, 0xd7, 0xc8, 0xd8, 0x9b, 0x04, 0x1a, 0x3a,
- 0xb7, 0x3e, 0xde, 0x93, 0xdf, 0xb0, 0x0b, 0x8d, 0x1d, 0x47, 0x5d, 0x93,
- 0x70, 0xd8, 0x68, 0x9a, 0xff, 0x90, 0x0a, 0x9e, 0xc7, 0xd1, 0x9c, 0xeb,
- 0xfe, 0x89, 0xe3, 0x7f, 0x0e, 0x4e, 0x75, 0x62, 0x29, 0x1a, 0x5a, 0x87,
- 0xd7, 0xe7, 0x58, 0xc6, 0xe7, 0x54, 0xc9, 0xa5, 0xf2, 0x1e, 0xfd, 0x2e,
- 0xbe, 0xce, 0xe4, 0xe7, 0x5e, 0x93, 0xf0, 0xeb, 0xf4, 0xb3, 0xd8, 0x12,
- 0xaf, 0xa0, 0x46, 0x0e, 0xa9, 0x8f, 0x7f, 0xc3, 0x7f, 0x49, 0xaf, 0xbf,
- 0xd2, 0xf8, 0x75, 0x28, 0x8d, 0x54, 0x84, 0x07, 0x8c, 0xaf, 0xf8, 0x73,
- 0xb9, 0xf3, 0xb9, 0x39, 0xd7, 0xf0, 0x15, 0x29, 0xce, 0x61, 0xd7, 0xde,
- 0x53, 0x3a, 0x75, 0xb4, 0x75, 0xc9, 0xf9, 0xd7, 0x75, 0x0e, 0xb8, 0x1a,
- 0xf8, 0x6a, 0xe6, 0x16, 0xa7, 0x3e, 0xbf, 0xce, 0xee, 0xfe, 0x0e, 0xbb,
- 0xf8, 0x3a, 0xfc, 0x09, 0x60, 0xb0, 0x86, 0xb3, 0xf1, 0x6a, 0x84, 0xc6,
- 0x7f, 0x84, 0x68, 0xa7, 0x5f, 0xff, 0x60, 0xbe, 0xfa, 0x51, 0x47, 0xf8,
- 0xd5, 0xfe, 0x75, 0xff, 0xde, 0xee, 0x2f, 0xec, 0x7f, 0x9b, 0xf8, 0xeb,
- 0xfd, 0xbb, 0x53, 0x9f, 0x60, 0x27, 0x5f, 0x7e, 0xb7, 0x97, 0xc4, 0x68,
- 0x69, 0x53, 0xc8, 0xf7, 0xf7, 0xeb, 0xfb, 0xaf, 0xb3, 0x9d, 0x76, 0x6e,
- 0x75, 0x6e, 0x79, 0x5b, 0x66, 0x97, 0xdf, 0xf1, 0x38, 0x75, 0x42, 0x37,
- 0x1e, 0x12, 0x8c, 0x93, 0x5f, 0x68, 0x1b, 0xf8, 0xeb, 0xb1, 0x93, 0xaf,
- 0xfa, 0x37, 0xcf, 0xe3, 0x66, 0x4e, 0x75, 0x70, 0xf4, 0x7f, 0x16, 0xbf,
- 0xf4, 0xd1, 0x3e, 0xb9, 0x8d, 0x89, 0xce, 0xbf, 0xb1, 0x78, 0x14, 0x64,
- 0xeb, 0x97, 0x07, 0x52, 0xcf, 0x05, 0xcb, 0x2f, 0xe1, 0xc9, 0xba, 0x9e,
- 0x3a, 0xfb, 0x33, 0xba, 0x3a, 0xb1, 0x1d, 0xcf, 0x08, 0x1f, 0x10, 0xed,
- 0x16, 0x5e, 0x65, 0x96, 0x4a, 0xbf, 0x62, 0x82, 0x0d, 0x14, 0xc1, 0x7f,
- 0x7e, 0xc6, 0x19, 0x65, 0x93, 0xaa, 0x0f, 0x8b, 0xc6, 0xf7, 0xfd, 0xae,
- 0x40, 0x3c, 0x29, 0xb0, 0xeb, 0xff, 0x0e, 0x69, 0xbd, 0x46, 0xc0, 0x9d,
- 0x7f, 0xff, 0x94, 0x65, 0xf8, 0xa3, 0x1a, 0xc9, 0x08, 0x1f, 0x58, 0x27,
- 0x54, 0x23, 0x5b, 0x0e, 0x50, 0xee, 0xf9, 0x97, 0x19, 0x1d, 0x7f, 0xde,
- 0x8d, 0xff, 0x7e, 0xf5, 0x0e, 0xb7, 0x4e, 0xac, 0x3c, 0x96, 0x9c, 0xde,
- 0x65, 0x96, 0x4a, 0xbf, 0x91, 0xd4, 0xea, 0x78, 0xa6, 0x0b, 0xfb, 0xef,
- 0x69, 0xf8, 0x75, 0xee, 0xc0, 0x4e, 0xa4, 0x37, 0x8e, 0x43, 0x7e, 0xcf,
- 0xf3, 0x26, 0x3a, 0xda, 0xf8, 0x8f, 0xee, 0x20, 0x75, 0xe0, 0x47, 0xee,
- 0x04, 0x82, 0x9d, 0x66, 0x46, 0xd1, 0x7e, 0x54, 0xf6, 0x27, 0x01, 0xd5,
- 0xd5, 0x47, 0x43, 0x1e, 0xc8, 0x0d, 0x6f, 0x46, 0xc8, 0x3a, 0x90, 0xf4,
- 0xc4, 0xde, 0xf0, 0xc6, 0xc3, 0xae, 0x54, 0xa1, 0xd7, 0x27, 0x4e, 0xb3,
- 0xce, 0x6b, 0xb8, 0x33, 0x7d, 0xed, 0x01, 0x5c, 0xeb, 0xfd, 0x03, 0x21,
- 0x48, 0xdc, 0xea, 0x86, 0x6e, 0x5c, 0x89, 0x72, 0x50, 0xda, 0x91, 0x86,
- 0x34, 0xd5, 0x0e, 0x79, 0x1a, 0x4f, 0x63, 0xe1, 0x73, 0x4f, 0xdd, 0x06,
- 0x31, 0x1d, 0x43, 0x13, 0xd2, 0xe1, 0x36, 0x10, 0x6d, 0xa5, 0x7d, 0x27,
- 0xda, 0x25, 0xb9, 0x58, 0x43, 0xaf, 0xfd, 0x13, 0x7b, 0x6b, 0x51, 0x30,
- 0x38, 0x75, 0xff, 0xd8, 0x9d, 0x80, 0xf4, 0x11, 0xbe, 0x8e, 0xbc, 0x15,
- 0x3f, 0x3a, 0xfc, 0xbe, 0x71, 0xfc, 0x75, 0x7c, 0x3c, 0x58, 0x1e, 0xbf,
- 0xfc, 0xd9, 0x9d, 0xbd, 0x89, 0x78, 0x71, 0x67, 0x5f, 0xff, 0x22, 0xf7,
- 0x96, 0xbe, 0x60, 0x8e, 0x27, 0xe7, 0x5e, 0x4e, 0x80, 0xea, 0x56, 0x53,
- 0xbc, 0x90, 0xd7, 0x10, 0xfb, 0x08, 0x87, 0x23, 0xf2, 0x4e, 0xc5, 0x0b,
- 0x30, 0xac, 0x46, 0xc5, 0xf8, 0xa8, 0x85, 0xca, 0xb7, 0x1a, 0x42, 0xa9,
- 0xb1, 0x5a, 0x46, 0x32, 0xab, 0xe3, 0x16, 0x56, 0xa7, 0x4a, 0xb0, 0x7c,
- 0x53, 0x00, 0x27, 0x9d, 0x08, 0x95, 0x22, 0x4c, 0x34, 0x90, 0xcc, 0xb6,
- 0x8e, 0x8a, 0x4b, 0x0e, 0x6d, 0x26, 0x23, 0x79, 0xf5, 0xf4, 0xa4, 0x67,
- 0x4d, 0x4e, 0x08, 0xe5, 0x34, 0xa5, 0x73, 0xf1, 0x1d, 0xad, 0x9e, 0x9e,
- 0xb9, 0xce, 0xfe, 0x92, 0x60, 0xa9, 0x86, 0xb0, 0xd6, 0x69, 0xfa, 0xb6,
- 0xaf, 0xbe, 0xb4, 0x17, 0xa0, 0x9d, 0x1b, 0xd9, 0x29, 0x4d, 0x99, 0x41,
- 0xfb, 0x73, 0xe3, 0xdf, 0x69, 0xf8, 0xdb, 0x52, 0xb6, 0x29, 0x88, 0xd9,
- 0x8e, 0xa5, 0x9b, 0x1a, 0x65, 0xf9, 0x8f, 0xd7, 0x9e, 0x3a, 0xff, 0x31,
- 0x9c, 0x6b, 0xbb, 0x4d, 0x17, 0x1d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a,
- 0x2e, 0xbb, 0xff, 0x98, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x8d,
- 0x44, 0x6d, 0x6e, 0x32, 0x85, 0xd8, 0x4a, 0x54, 0x84, 0x7b, 0x4a, 0x12,
- 0x3a, 0x15, 0x77, 0x17, 0xcd, 0x9a, 0x47, 0xf3, 0xbd, 0x14, 0xf8, 0xff,
- 0x68, 0xfe, 0xff, 0xf3, 0x0b, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12,
- 0xd5, 0xff, 0x2a, 0xee, 0xa2, 0xbb, 0xc6, 0xfb, 0x47, 0x5f, 0xb8, 0xd7,
- 0x76, 0x9a, 0x23, 0x7b, 0xff, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89,
- 0x7e, 0xfe, 0x8f, 0x7d, 0xeb, 0xf8, 0xeb, 0xfd, 0x9f, 0x78, 0xa7, 0x41,
- 0xa3, 0xac, 0xc2, 0xb5, 0x4c, 0x97, 0x11, 0x16, 0x67, 0xd4, 0xa1, 0x2e,
- 0xbf, 0xcc, 0x67, 0x1a, 0xee, 0xd3, 0x45, 0x57, 0x72, 0x6d, 0x1d, 0x7c,
- 0x8b, 0x7d, 0x87, 0x52, 0x86, 0xeb, 0xc3, 0x17, 0x87, 0x69, 0x93, 0xaf,
- 0xe7, 0xec, 0xc3, 0x01, 0x3a, 0xff, 0xef, 0x76, 0x34, 0x2e, 0x05, 0x4a,
- 0x70, 0xeb, 0xd1, 0x2c, 0x3a, 0x82, 0x88, 0xcd, 0xcb, 0x26, 0x46, 0xbf,
- 0xe5, 0x30, 0x73, 0x7f, 0x3a, 0xce, 0xb8, 0x28, 0x75, 0xfd, 0x9c, 0x6b,
- 0xbb, 0x4d, 0x12, 0x05, 0x7c, 0x3c, 0xd6, 0x05, 0x6f, 0xda, 0x71, 0x7d,
- 0xce, 0xb8, 0x10, 0x75, 0x48, 0xf8, 0x37, 0x25, 0xe1, 0x35, 0xfe, 0x94,
- 0x72, 0x78, 0xe4, 0xe7, 0x5f, 0xee, 0x4e, 0xb8, 0x19, 0x68, 0xea, 0x83,
- 0xe7, 0xc3, 0x4b, 0xec, 0x9d, 0xc2, 0x75, 0xff, 0xec, 0x9b, 0xae, 0xbf,
- 0x76, 0x3c, 0x05, 0x9d, 0x53, 0xab, 0x06, 0x09, 0x16, 0x42, 0xad, 0x43,
- 0x27, 0x87, 0x28, 0xc2, 0x5f, 0xc4, 0x1f, 0x48, 0x6f, 0xfe, 0x1c, 0x9d,
- 0x8d, 0xb8, 0x11, 0xcf, 0x1d, 0x4c, 0x23, 0x23, 0x90, 0x83, 0xbf, 0xcc,
- 0x67, 0x1a, 0xee, 0xd3, 0x45, 0x91, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6,
- 0x8b, 0x5e, 0xff, 0xf6, 0x7d, 0x89, 0xd8, 0xc9, 0xbc, 0x18, 0x13, 0xaf,
- 0xf3, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x72, 0x5f, 0xb8, 0xd7, 0x76, 0x9a,
- 0x2e, 0xcb, 0xff, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8a, 0x3a, 0xcc,
- 0x61, 0xfe, 0xac, 0xce, 0xf8, 0x62, 0x4b, 0x3a, 0xd2, 0x3a, 0xfd, 0xc6,
- 0xbb, 0xb4, 0xd1, 0x4a, 0xdf, 0xf3, 0x7a, 0x93, 0x76, 0x27, 0xc3, 0xaf,
- 0xff, 0x76, 0x27, 0x8e, 0xa6, 0xc7, 0x0f, 0x50, 0xe6, 0x0d, 0xcd, 0xd2,
- 0x63, 0x11, 0x8f, 0x33, 0x65, 0x6e, 0x98, 0x3b, 0xc3, 0x5e, 0xff, 0xce,
- 0x9e, 0x90, 0x02, 0xe3, 0xf9, 0xd6, 0x60, 0x29, 0xc6, 0xae, 0x32, 0x7e,
- 0x94, 0xd4, 0xec, 0x9b, 0xb9, 0x46, 0xf9, 0xba, 0xb2, 0x4e, 0x23, 0xac,
- 0xa7, 0xf3, 0xf1, 0x3f, 0xd2, 0x67, 0xa1, 0x79, 0xb2, 0x3b, 0x5b, 0xfe,
- 0x93, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x1c, 0x5f, 0xf2, 0x31, 0x9c, 0x6b,
- 0xbb, 0x4d, 0x15, 0xad, 0x98, 0x74, 0x44, 0xf9, 0x16, 0xff, 0xf3, 0x0b,
- 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0xdd, 0xe0, 0x73, 0xf3, 0xae,
- 0xcd, 0xce, 0xbf, 0xc1, 0xc5, 0xae, 0x13, 0x47, 0x5e, 0xd8, 0x09, 0x1d,
- 0x4d, 0x44, 0x16, 0xe3, 0xa8, 0x2d, 0xb0, 0xc6, 0xf7, 0x43, 0x23, 0xaf,
- 0xfb, 0x37, 0x1c, 0xff, 0xf7, 0x91, 0xd7, 0x2d, 0xa7, 0x54, 0x1e, 0x7c,
- 0x8e, 0x6f, 0x86, 0x37, 0x91, 0xd7, 0xff, 0xe7, 0xdf, 0xf0, 0xf5, 0xe5,
- 0x9a, 0x10, 0x3f, 0xd3, 0xa9, 0xa7, 0xf1, 0xd2, 0x1b, 0xf9, 0x38, 0x29,
- 0xed, 0x1d, 0x7e, 0xe3, 0x8e, 0x41, 0xd4, 0x68, 0x86, 0xfa, 0x79, 0xee,
- 0x57, 0x74, 0x09, 0xd7, 0xf2, 0x08, 0x71, 0x02, 0x75, 0x41, 0xbe, 0x90,
- 0xa5, 0xf6, 0x4d, 0x2c, 0x3a, 0xff, 0xcf, 0x26, 0x33, 0x8d, 0x77, 0x69,
- 0xa2, 0x60, 0xbf, 0x7f, 0xa7, 0x1f, 0xce, 0xbf, 0xc0, 0xdf, 0x89, 0x0b,
- 0xc3, 0xaf, 0xfa, 0x27, 0xf0, 0xc0, 0x3d, 0xa3, 0xad, 0xee, 0x9f, 0x56,
- 0xd9, 0x95, 0xf6, 0xed, 0x45, 0x0e, 0xac, 0x3c, 0xef, 0x15, 0xdf, 0xed,
- 0x27, 0x51, 0x78, 0xa1, 0xd7, 0xff, 0x9e, 0x7e, 0xa4, 0x0e, 0x4c, 0x9c,
- 0x43, 0xab, 0xc7, 0xf2, 0xc9, 0x95, 0xcd, 0xc3, 0xae, 0x07, 0xe5, 0x52,
- 0x1a, 0xce, 0x0a, 0xdf, 0xec, 0x08, 0xe7, 0xbb, 0x87, 0x5f, 0xd3, 0xfd,
- 0xdb, 0x71, 0xfc, 0xeb, 0xfb, 0x3d, 0xe8, 0xe6, 0x8e, 0xbf, 0x9c, 0x7f,
- 0x9f, 0xff, 0x1d, 0x50, 0x88, 0xe1, 0x33, 0xdb, 0x2c, 0xb3, 0x10, 0xbb,
- 0x13, 0x39, 0xf8, 0x5a, 0xf2, 0x13, 0x2d, 0x71, 0xdd, 0xcb, 0x84, 0x0b,
- 0x21, 0x74, 0xa1, 0x87, 0x06, 0xa1, 0x35, 0xe4, 0xfd, 0x84, 0x1f, 0x61,
- 0x7d, 0x79, 0x60, 0xe1, 0x57, 0xfe, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d,
- 0x13, 0x1d, 0xf4, 0x72, 0x36, 0x8e, 0xb3, 0x08, 0x88, 0x95, 0x8e, 0x75,
- 0x2a, 0xfa, 0x27, 0x8e, 0x1d, 0x7e, 0xc8, 0x99, 0x16, 0x75, 0x21, 0xe3,
- 0xf0, 0x86, 0xff, 0x76, 0x39, 0x3f, 0xd0, 0x7e, 0x75, 0xcf, 0xa3, 0xaf,
- 0xbe, 0x7b, 0x3a, 0x75, 0xa3, 0xa6, 0xe3, 0x42, 0xb7, 0xa0, 0x67, 0x3a,
- 0xff, 0xff, 0xfa, 0x5a, 0xee, 0x01, 0x9d, 0x77, 0x1b, 0x9a, 0xf9, 0x9b,
- 0xcb, 0x48, 0x28, 0x75, 0xe7, 0x76, 0x9a, 0x2b, 0x1b, 0xe7, 0xfb, 0x0a,
- 0x1d, 0x4d, 0x3c, 0xae, 0x13, 0xdf, 0xfb, 0x6f, 0x3c, 0x38, 0x08, 0x1f,
- 0x1d, 0x4a, 0x26, 0xd4, 0xd2, 0x6d, 0xc6, 0xf9, 0x0c, 0x9f, 0x11, 0x5f,
- 0xfc, 0x3e, 0x50, 0x10, 0x38, 0xd8, 0xe1, 0xd7, 0xfb, 0x93, 0xfb, 0x4f,
- 0xbb, 0x4e, 0xa8, 0x3f, 0x77, 0x42, 0xbf, 0xa3, 0x6b, 0xd9, 0xbc, 0xc7,
- 0x5f, 0xc0, 0xdb, 0x6f, 0x51, 0x52, 0x75, 0xfd, 0x9a, 0xde, 0x51, 0xd3,
- 0xae, 0x8d, 0x87, 0x58, 0x3d, 0x3c, 0x41, 0x2d, 0xbf, 0xe8, 0xde, 0x53,
- 0x49, 0xf9, 0x39, 0xd5, 0x08, 0xda, 0xc7, 0x84, 0x27, 0xbd, 0x12, 0xf1,
- 0xd7, 0xfe, 0xc0, 0xf1, 0x01, 0x3f, 0xfa, 0x91, 0xd7, 0xcb, 0x7d, 0xfc,
- 0x75, 0xff, 0xd3, 0xc7, 0xbe, 0x7d, 0x6f, 0xdd, 0xaf, 0xba, 0x3a, 0xff,
- 0xb9, 0x1a, 0x7e, 0x0c, 0x48, 0xea, 0xe2, 0x21, 0xf6, 0x28, 0xde, 0x93,
- 0xce, 0x75, 0xef, 0x93, 0xac, 0xeb, 0x83, 0xe3, 0xa9, 0x54, 0x98, 0xfe,
- 0x42, 0xa7, 0x72, 0x54, 0x1c, 0x11, 0xfb, 0xff, 0x0b, 0x87, 0xb1, 0xb3,
- 0xae, 0x27, 0x5f, 0xff, 0xf8, 0x13, 0xe3, 0x7e, 0x08, 0x36, 0xbe, 0x66,
- 0xf2, 0xc0, 0x0f, 0xfa, 0x3a, 0xff, 0x9f, 0x71, 0xc0, 0xf5, 0xd9, 0x3a,
- 0x82, 0x8e, 0xa1, 0x3d, 0xd3, 0xad, 0xfd, 0x3c, 0xd2, 0x55, 0x72, 0x73,
- 0xaf, 0x84, 0x73, 0xc7, 0x52, 0xb2, 0x7a, 0x90, 0x6b, 0x7f, 0x4f, 0xf7,
- 0x6d, 0xc7, 0xf3, 0xaf, 0xfe, 0x9b, 0xae, 0xbf, 0x76, 0x3c, 0x05, 0x9d,
- 0x7f, 0xc9, 0x24, 0xe8, 0x16, 0xb4, 0x3a, 0xa1, 0x15, 0xf8, 0x67, 0xe4,
- 0x5b, 0xdd, 0x46, 0x21, 0x90, 0xaf, 0x22, 0x1c, 0x8f, 0x65, 0xb0, 0xc9,
- 0xe1, 0x07, 0x63, 0x0b, 0x72, 0xd1, 0x1b, 0xd4, 0x6b, 0xfe, 0x8c, 0xf3,
- 0x6e, 0x10, 0x7f, 0x61, 0xab, 0x74, 0x84, 0xeb, 0xfb, 0x9c, 0x80, 0xe2,
- 0xce, 0xbb, 0xef, 0xe7, 0x5e, 0xea, 0x2c, 0xeb, 0x4c, 0x75, 0x39, 0xac,
- 0x00, 0xdd, 0xf9, 0xc6, 0x70, 0x68, 0xeb, 0xfe, 0x80, 0xf7, 0x03, 0xc7,
- 0x69, 0xd4, 0x88, 0xef, 0xfc, 0xb0, 0x51, 0x74, 0x41, 0xe2, 0x7b, 0xda,
- 0xfb, 0xa3, 0xaf, 0xb7, 0x9e, 0x14, 0x3a, 0x82, 0x78, 0x40, 0x1e, 0xbb,
- 0xd0, 0x75, 0xf9, 0x78, 0x31, 0x23, 0xaf, 0x81, 0xec, 0xd1, 0xd7, 0xd1,
- 0xc7, 0x13, 0xaf, 0xf3, 0xf2, 0x5f, 0xa6, 0xfa, 0x3a, 0xfb, 0x5a, 0x8f,
- 0xce, 0xa8, 0x45, 0xda, 0x12, 0xf4, 0x84, 0x03, 0xec, 0x9a, 0x5f, 0x4b,
- 0xf0, 0x48, 0xeb, 0xee, 0x7d, 0x8f, 0xce, 0xa8, 0x3c, 0x74, 0x23, 0xbf,
- 0xc9, 0x3b, 0xaf, 0xff, 0xe0, 0xeb, 0xfe, 0x46, 0xf7, 0x26, 0x18, 0x09,
- 0xd7, 0xd2, 0xf6, 0x7d, 0x3a, 0xf3, 0x63, 0xf3, 0xaf, 0x72, 0x16, 0x75,
- 0x39, 0xed, 0x00, 0x8d, 0x91, 0xcb, 0xf4, 0x4f, 0xf7, 0x26, 0x3a, 0xf4,
- 0x0c, 0x8e, 0xa9, 0x93, 0x58, 0xe1, 0x07, 0x4d, 0x06, 0x12, 0x3a, 0x2f,
- 0xf1, 0x55, 0xff, 0xa3, 0x35, 0xf2, 0x10, 0x3f, 0x64, 0x75, 0xfc, 0x8c,
- 0xea, 0x7c, 0x64, 0xea, 0x13, 0xef, 0xf2, 0x05, 0xfa, 0x03, 0xec, 0x69,
- 0xd7, 0xdd, 0x81, 0x69, 0xd5, 0x23, 0xe7, 0xd1, 0x0f, 0x89, 0xaf, 0x9c,
- 0x5e, 0x63, 0xaf, 0xc9, 0xe1, 0xc9, 0x1d, 0x7d, 0x0c, 0xc4, 0xc7, 0x5d,
- 0xf5, 0x67, 0x5f, 0xf0, 0x3e, 0x78, 0x5f, 0xfc, 0x13, 0xaa, 0x74, 0x5c,
- 0x28, 0x40, 0x84, 0xbd, 0x22, 0x11, 0x8b, 0xfd, 0x0c, 0x84, 0x0f, 0xc9,
- 0x1d, 0x7f, 0x27, 0x37, 0xd4, 0x48, 0xeb, 0x6c, 0x3a, 0xb8, 0x7e, 0x5d,
- 0x33, 0xda, 0x2d, 0xbc, 0x28, 0xa1, 0xd7, 0xd8, 0x14, 0xd8, 0x75, 0xd0,
- 0xbc, 0x37, 0xae, 0x37, 0x6d, 0x1d, 0x48, 0x6e, 0x9c, 0xaa, 0xef, 0xe0,
- 0xab, 0x99, 0x64, 0xaa, 0x43, 0x5c, 0xc8, 0xb5, 0xfe, 0x79, 0x0e, 0x7b,
- 0xa8, 0x53, 0x06, 0x86, 0xf3, 0xef, 0xa3, 0xaf, 0xbe, 0xf5, 0xfc, 0x75,
- 0x04, 0xdf, 0xf8, 0x72, 0xf4, 0x0c, 0xc7, 0x5c, 0x30, 0x75, 0xa6, 0x3a,
- 0xa6, 0x3c, 0x0e, 0x0d, 0xb8, 0xa5, 0xff, 0xca, 0x20, 0xb7, 0x50, 0xb7,
- 0xdf, 0xc7, 0x5e, 0xff, 0x36, 0x8e, 0xa5, 0x0f, 0x8f, 0x88, 0x97, 0xcb,
- 0xd0, 0x16, 0x75, 0x94, 0x3a, 0xdb, 0x67, 0x5d, 0xc5, 0x0e, 0xa8, 0x3d,
- 0xd4, 0x22, 0x00, 0x8f, 0xd1, 0x3b, 0xff, 0xee, 0xe4, 0xb5, 0x1e, 0x96,
- 0x2b, 0xb8, 0xfe, 0x75, 0xff, 0xa4, 0x9e, 0xee, 0x6f, 0xe0, 0x41, 0xd7,
- 0x66, 0x8e, 0xa8, 0x3d, 0x39, 0x1f, 0x56, 0x91, 0x8b, 0xe8, 0x52, 0x5f,
- 0x92, 0x17, 0x0b, 0x3a, 0xd8, 0x75, 0x21, 0xee, 0x68, 0xa3, 0x6c, 0x96,
- 0xa1, 0x58, 0x0e, 0x30, 0xa4, 0x24, 0xbb, 0x08, 0x07, 0x8d, 0x76, 0xf6,
- 0xa2, 0x63, 0xa8, 0xeb, 0x2c, 0xea, 0xf1, 0x75, 0xb0, 0x2a, 0xfd, 0xfa,
- 0x71, 0x14, 0x3a, 0xe7, 0x50, 0xea, 0x99, 0x12, 0xdd, 0x36, 0xfc, 0x88,
- 0x4a, 0x2e, 0xf4, 0x1d, 0x7e, 0x8e, 0xe6, 0xc7, 0x3a, 0x9c, 0xde, 0x7e,
- 0x2b, 0x7f, 0x27, 0xb3, 0xae, 0xa1, 0xd7, 0xf7, 0x40, 0xf3, 0xf5, 0x0e,
- 0xbc, 0xcb, 0x2c, 0x95, 0x7f, 0xc1, 0x89, 0xfe, 0xe7, 0x5f, 0x72, 0x98,
- 0x2f, 0xee, 0xc9, 0xce, 0xa0, 0xa2, 0xb5, 0xa9, 0x88, 0x97, 0x7a, 0x16,
- 0x87, 0x56, 0x1e, 0x4b, 0x4b, 0xef, 0x93, 0x9b, 0x41, 0x3a, 0xfd, 0xd8,
- 0xdd, 0xd5, 0xce, 0xbf, 0xfe, 0x8f, 0x68, 0x39, 0xe4, 0xe8, 0x33, 0x7f,
- 0x1d, 0x5d, 0x3f, 0x9f, 0x15, 0x5b, 0x87, 0x5f, 0xec, 0xc6, 0xfd, 0xd9,
- 0xdc, 0x3a, 0xe0, 0x68, 0xeb, 0xff, 0xf6, 0x06, 0x33, 0x7f, 0xbe, 0x41,
- 0x04, 0xb3, 0x47, 0x5c, 0xbf, 0xce, 0xb9, 0xc4, 0xea, 0xe9, 0xab, 0x71,
- 0x7b, 0xf2, 0xd3, 0xdf, 0xb9, 0xd5, 0x3a, 0x7c, 0x39, 0x09, 0xd5, 0x72,
- 0x29, 0x84, 0x1c, 0xd4, 0x45, 0xbd, 0x08, 0x00, 0x10, 0x5f, 0x77, 0xc9,
- 0x39, 0xd7, 0xf9, 0xa9, 0xa1, 0xcd, 0x8e, 0x75, 0xf4, 0x4e, 0xf2, 0x3a,
- 0xec, 0xf1, 0xd7, 0xec, 0x9c, 0x73, 0x73, 0xab, 0x11, 0x63, 0xb9, 0x17,
- 0x0c, 0xba, 0x42, 0x22, 0xb7, 0xbb, 0x01, 0x3a, 0xee, 0x68, 0xea, 0x39,
- 0x0b, 0x6b, 0xfd, 0x03, 0x27, 0x5e, 0x04, 0xeb, 0xef, 0x2d, 0x7c, 0x3a,
- 0xff, 0xef, 0xe0, 0x5a, 0xfe, 0xff, 0xe8, 0xc8, 0xeb, 0xd2, 0x4e, 0x9d,
- 0x7d, 0xe1, 0xc9, 0x1d, 0x7e, 0xc0, 0x2a, 0x74, 0xe7, 0x5f, 0xfe, 0x4d,
- 0x77, 0x02, 0x39, 0xb0, 0x73, 0x47, 0x54, 0x93, 0x45, 0x50, 0xc3, 0x72,
- 0x29, 0x91, 0xb8, 0x36, 0x24, 0x1e, 0x2a, 0xa5, 0x53, 0x67, 0xe3, 0x11,
- 0x82, 0x4f, 0x08, 0xb9, 0x11, 0x06, 0x1a, 0x19, 0x1f, 0x46, 0xf1, 0x99,
- 0xa4, 0x39, 0xe6, 0x85, 0xe7, 0x21, 0x52, 0xb6, 0xee, 0xcb, 0x81, 0x78,
- 0x77, 0x7e, 0xf4, 0xa9, 0x21, 0x18, 0xc8, 0xb5, 0x28, 0x0b, 0xd1, 0x97,
- 0xb2, 0x93, 0xb6, 0x63, 0xf6, 0x35, 0xdb, 0xfe, 0x63, 0xc9, 0x9b, 0x5a,
- 0x04, 0x1d, 0x7f, 0xff, 0xc0, 0x86, 0x3d, 0xa4, 0xeb, 0xa7, 0xb3, 0x9f,
- 0xad, 0xe4, 0x75, 0x30, 0xa8, 0x76, 0x78, 0xdf, 0x02, 0x77, 0x7e, 0xe3,
- 0x5d, 0xda, 0x68, 0xad, 0xef, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a,
- 0x27, 0x0b, 0x31, 0x87, 0xfa, 0xb3, 0x3b, 0x95, 0x41, 0x3a, 0xdd, 0x3a,
- 0xda, 0x3a, 0x80, 0x68, 0x36, 0xc4, 0x2f, 0x9a, 0xee, 0xd3, 0x45, 0xa3,
- 0x7f, 0xfb, 0x03, 0xd7, 0x52, 0x69, 0x93, 0x40, 0x59, 0xd5, 0xc3, 0xf9,
- 0xe9, 0x6d, 0xf3, 0x5c, 0x7f, 0x3a, 0xff, 0xa6, 0xc5, 0x7d, 0x73, 0x8f,
- 0xe3, 0xaf, 0xe8, 0x71, 0x00, 0x70, 0xeb, 0x91, 0x43, 0xaf, 0xff, 0xd3,
- 0xc7, 0xa0, 0x3c, 0x8e, 0xbe, 0x87, 0x3f, 0x3a, 0xff, 0xd1, 0xbb, 0xab,
- 0xf4, 0x5d, 0x5e, 0x73, 0xaf, 0xfd, 0x1c, 0xff, 0x13, 0x39, 0xe0, 0x1d,
- 0x50, 0x8d, 0x5e, 0xaa, 0x69, 0x12, 0xd9, 0x32, 0x63, 0x5a, 0x87, 0x5d,
- 0xfe, 0xef, 0x40, 0xa2, 0xe3, 0x47, 0x5f, 0xff, 0x93, 0x43, 0x9b, 0x1f,
- 0xc3, 0x9a, 0xeb, 0xcc, 0x75, 0x62, 0x22, 0x26, 0x34, 0xbe, 0xcf, 0xdf,
- 0xa7, 0x5d, 0xdd, 0x1d, 0x66, 0x15, 0x0a, 0xea, 0xd5, 0xb3, 0xac, 0x84,
- 0xeb, 0x48, 0xa6, 0x21, 0x59, 0xe7, 0x63, 0x44, 0xf4, 0x2d, 0xf6, 0xc8,
- 0xfe, 0x90, 0xdf, 0x35, 0xdd, 0xa6, 0x8b, 0x6a, 0xff, 0xfe, 0x87, 0xf4,
- 0x76, 0x34, 0x89, 0x24, 0xe6, 0x04, 0xeb, 0xfb, 0xb0, 0xb8, 0x40, 0x9d,
- 0x5c, 0x45, 0x76, 0x8b, 0x7c, 0xad, 0x7f, 0xee, 0xa0, 0x5e, 0x41, 0xea,
- 0x2c, 0xeb, 0xe8, 0xd9, 0x88, 0x75, 0xff, 0x44, 0xa3, 0x93, 0xc7, 0x27,
- 0x3a, 0xff, 0xa3, 0x9f, 0x35, 0x1d, 0x74, 0x3a, 0xff, 0x75, 0x1e, 0x5e,
- 0x49, 0xce, 0xac, 0x4c, 0xc5, 0xa6, 0x1c, 0x3d, 0x12, 0x16, 0x4e, 0x76,
- 0xce, 0x2f, 0xe5, 0x1f, 0x81, 0x00, 0x9d, 0x7f, 0x0e, 0xda, 0x73, 0x14,
- 0x3a, 0xfc, 0x93, 0xae, 0x1a, 0x75, 0xf9, 0xf7, 0x97, 0xdd, 0x1d, 0x66,
- 0x14, 0x45, 0x68, 0x96, 0xf8, 0xbf, 0x61, 0x3d, 0x30, 0x9a, 0x6f, 0xf1,
- 0x83, 0xdc, 0xbe, 0x9d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xb9, 0x6c, 0xc0,
- 0x4f, 0x27, 0x05, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x17, 0x6d, 0xff, 0x24,
- 0xa4, 0x83, 0xfc, 0x48, 0xeb, 0x31, 0x87, 0xd4, 0xe6, 0x75, 0x0e, 0xc5,
- 0x3a, 0x72, 0x99, 0x4f, 0x31, 0x06, 0x36, 0x85, 0x29, 0x1a, 0x89, 0x5b,
- 0x78, 0xab, 0xc2, 0xdf, 0xb2, 0xf4, 0xc6, 0x5e, 0xf6, 0x9d, 0x7d, 0x09,
- 0x2b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x54, 0xf7, 0x83, 0x3a, 0xce,
- 0xb7, 0x8e, 0xbf, 0xe8, 0x79, 0xfe, 0x6f, 0xa8, 0x09, 0xd4, 0x87, 0x96,
- 0x22, 0x17, 0xcd, 0x77, 0x69, 0xa2, 0xb9, 0xbf, 0xcc, 0x67, 0x1a, 0xee,
- 0xd3, 0x45, 0x9d, 0x79, 0xde, 0x47, 0x5f, 0xc9, 0xac, 0x17, 0x64, 0xea,
- 0xe2, 0x2c, 0x7a, 0x5a, 0x27, 0xfe, 0x1a, 0xbf, 0xfd, 0xe8, 0xd7, 0xc0,
- 0x6b, 0xd1, 0x34, 0xc8, 0x75, 0xfc, 0x8b, 0x9c, 0x1c, 0x91, 0xd7, 0xfa,
- 0x3b, 0xf1, 0x6a, 0xda, 0xa3, 0xc7, 0x56, 0x22, 0xe7, 0xa9, 0xbb, 0x0b,
- 0xaf, 0xdc, 0xcf, 0x22, 0xce, 0xbe, 0x71, 0x80, 0x9d, 0x7f, 0x64, 0xd0,
- 0xb8, 0xfa, 0x75, 0xfb, 0x8d, 0x77, 0x69, 0xa2, 0x42, 0xbf, 0xf6, 0x2f,
- 0x1f, 0x93, 0xfc, 0xdd, 0x67, 0x5f, 0xf2, 0x6f, 0xaf, 0x0c, 0x2f, 0x47,
- 0x5d, 0x26, 0x31, 0x15, 0x9d, 0x33, 0xfd, 0x06, 0xff, 0xee, 0xa2, 0xf3,
- 0x5f, 0x37, 0x96, 0x78, 0xeb, 0xe9, 0x77, 0xee, 0x8e, 0xa8, 0x3e, 0xac,
- 0x46, 0xbe, 0x56, 0xfb, 0x0b, 0x3a, 0xfe, 0xee, 0xb5, 0x9c, 0x9c, 0xeb,
- 0xa1, 0x93, 0xab, 0x0f, 0x11, 0x0b, 0xac, 0xc4, 0xeb, 0x99, 0xe1, 0x68,
- 0xc8, 0x68, 0xa4, 0x3d, 0x78, 0x62, 0xb2, 0x6e, 0x8f, 0xbc, 0x36, 0x86,
- 0x14, 0xfa, 0x20, 0xf3, 0x55, 0xff, 0xcc, 0x75, 0xf4, 0x39, 0xef, 0x47,
- 0xe7, 0x5f, 0xfe, 0x61, 0x6f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x7c,
- 0xa6, 0xaf, 0x2e, 0x2b, 0xce, 0x87, 0x2e, 0x16, 0x7d, 0x44, 0xb9, 0x37,
- 0x3a, 0xff, 0xfa, 0x53, 0xaa, 0xd0, 0xad, 0xce, 0xde, 0x7c, 0xf9, 0xdd,
- 0xb3, 0xaa, 0x47, 0xf5, 0xf8, 0xb5, 0xfb, 0x39, 0x99, 0x31, 0xd6, 0x63,
- 0xa7, 0x93, 0xf4, 0x8e, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x59, 0x5f, 0xf9,
- 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x4d, 0xd6, 0x63, 0x0f, 0xf5, 0x66,
- 0x74, 0xd4, 0x68, 0x24, 0x2a, 0x2f, 0xdc, 0x6b, 0xbb, 0x4d, 0x12, 0xb5,
- 0xf8, 0x60, 0x2f, 0xd3, 0xaf, 0xcc, 0x2d, 0xe4, 0xc6, 0x1e, 0xc2, 0x19,
- 0xdf, 0xfb, 0xd8, 0xc6, 0x71, 0x27, 0x75, 0x9d, 0x7f, 0xf9, 0x58, 0x56,
- 0x55, 0x1a, 0xc7, 0x92, 0x67, 0x30, 0xeb, 0xff, 0x26, 0x80, 0xb1, 0x4d,
- 0x80, 0x73, 0xaf, 0xe8, 0x17, 0x6b, 0xab, 0x9d, 0x52, 0x3e, 0xb5, 0x9f,
- 0x5c, 0x1e, 0x1d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x97, 0x2f, 0xf9, 0x1e,
- 0x5e, 0x18, 0x5e, 0x8e, 0xbf, 0x4b, 0x6d, 0x3a, 0xe7, 0x5e, 0x8d, 0xb8,
- 0x3a, 0xf2, 0x0c, 0x1d, 0x52, 0x3d, 0xf0, 0x94, 0xec, 0x1d, 0xbf, 0xff,
- 0x3f, 0x90, 0x12, 0x14, 0x94, 0x78, 0x41, 0x23, 0xaf, 0xe9, 0x77, 0x07,
- 0x1a, 0x75, 0xe9, 0x77, 0xc7, 0x5d, 0xd8, 0x43, 0xc7, 0xe9, 0x5d, 0xff,
- 0xc2, 0x9f, 0xeb, 0x90, 0x92, 0x7d, 0x1d, 0x58, 0x7d, 0xc8, 0x59, 0x79,
- 0xe4, 0xc2, 0xaf, 0x56, 0x31, 0x10, 0xc0, 0x91, 0x16, 0x0b, 0x74, 0xcd,
- 0xe1, 0x2b, 0xa3, 0x1f, 0x46, 0x0f, 0x66, 0x11, 0x5f, 0x72, 0xe5, 0xab,
- 0x5f, 0xfc, 0xc3, 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x8e, 0xef, 0xfb,
- 0xdd, 0xc9, 0x30, 0xe3, 0xa3, 0xaf, 0xe5, 0x50, 0xc3, 0x70, 0x4e, 0xb8,
- 0x1d, 0x3a, 0xfe, 0x54, 0x0e, 0x75, 0xfc, 0x75, 0xff, 0xfd, 0xe9, 0x20,
- 0x7a, 0x9b, 0x3e, 0x60, 0x78, 0x80, 0x69, 0xd7, 0xfb, 0x19, 0xd4, 0x0f,
- 0xb4, 0x75, 0xfe, 0x71, 0xfd, 0xf8, 0xff, 0x4e, 0xbf, 0xf2, 0x73, 0xe6,
- 0x87, 0x17, 0x0d, 0x3a, 0xff, 0xd0, 0x20, 0xf2, 0x3e, 0xc7, 0x91, 0xd7,
- 0xcd, 0x77, 0x69, 0xa2, 0xa1, 0xbf, 0xec, 0xee, 0x0b, 0xf3, 0x88, 0x75,
- 0x28, 0x8d, 0xd6, 0x9f, 0x70, 0xf7, 0x45, 0xb7, 0x4b, 0x0e, 0xbf, 0xe9,
- 0x79, 0x38, 0xed, 0x41, 0x3a, 0xff, 0xf3, 0xaf, 0x38, 0x38, 0x9b, 0x13,
- 0x8e, 0x75, 0xff, 0xdd, 0x1c, 0x9b, 0xdd, 0xce, 0x26, 0x8e, 0xbf, 0x6e,
- 0x28, 0xb4, 0x3a, 0xa1, 0x16, 0x18, 0x8e, 0x88, 0x77, 0xfa, 0x3c, 0xfd,
- 0xf8, 0x18, 0x3a, 0xff, 0xc0, 0xf8, 0xe3, 0x9b, 0x5f, 0x3a, 0x03, 0xaf,
- 0xf4, 0xa3, 0x93, 0xc7, 0x27, 0x3a, 0xff, 0xed, 0x6b, 0x07, 0xda, 0xc9,
- 0x27, 0x4e, 0xbf, 0xfe, 0x8f, 0xf0, 0x7e, 0x3f, 0xbe, 0x77, 0x3f, 0x73,
- 0xae, 0x19, 0xce, 0xa8, 0x46, 0xf6, 0x1a, 0x22, 0x10, 0xa9, 0x5f, 0xdb,
- 0x1d, 0x7d, 0x65, 0xce, 0xbf, 0xff, 0xc9, 0x1e, 0x7e, 0xb1, 0xae, 0xe0,
- 0xfb, 0xe7, 0xf2, 0xd1, 0xd6, 0xc4, 0x44, 0x90, 0x97, 0xdf, 0x77, 0xd9,
- 0x39, 0xd7, 0xec, 0x9d, 0xc7, 0x61, 0xd7, 0xff, 0xff, 0xfa, 0x25, 0xf3,
- 0xdd, 0x48, 0xd7, 0xcc, 0x03, 0x63, 0x67, 0xcc, 0xe7, 0x33, 0x60, 0x1f,
- 0xa7, 0x5f, 0x74, 0x5f, 0x68, 0xea, 0xc4, 0xc0, 0xc4, 0x8b, 0x45, 0x1e,
- 0x84, 0xb5, 0xff, 0xff, 0x01, 0xd5, 0xd2, 0x7e, 0xba, 0x7a, 0x3a, 0x9e,
- 0xd6, 0x04, 0xeb, 0x30, 0xa8, 0x5f, 0x6a, 0x56, 0xcb, 0x95, 0x42, 0xd0,
- 0x5f, 0x3a, 0xf0, 0x4c, 0xb2, 0x31, 0x06, 0x9f, 0x6e, 0x2b, 0xc8, 0x73,
- 0x2c, 0xb7, 0xa6, 0x63, 0x19, 0x16, 0xa1, 0x97, 0xe8, 0xca, 0x76, 0xd0,
- 0x6f, 0x9a, 0xee, 0xd3, 0x45, 0x51, 0x7f, 0xb9, 0x1b, 0x37, 0x96, 0x78,
- 0xea, 0xe1, 0xf1, 0x00, 0xb6, 0xff, 0xcf, 0x26, 0x33, 0x8d, 0x77, 0x69,
- 0xa2, 0x6b, 0xbc, 0xb7, 0xf1, 0xd6, 0x63, 0x11, 0x0e, 0xb2, 0x27, 0x4a,
- 0xbf, 0x71, 0xae, 0xed, 0x34, 0x55, 0x97, 0xfd, 0x12, 0x8e, 0x4f, 0x1c,
- 0x9c, 0xeb, 0x31, 0x87, 0xd8, 0x26, 0x77, 0xfe, 0x63, 0xb1, 0xbf, 0xa3,
- 0xae, 0xae, 0x75, 0xff, 0xcc, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89,
- 0x12, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x69, 0x5f, 0xf9, 0xe4, 0xc6, 0x71,
- 0xae, 0xed, 0x34, 0x4f, 0xb6, 0x63, 0x0f, 0xf5, 0x66, 0x77, 0xff, 0x98,
- 0x5b, 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0xa1, 0x2f, 0xdd, 0x49, 0xe3,
- 0x87, 0x5f, 0xb8, 0xd7, 0x76, 0x9a, 0x28, 0xfb, 0xfe, 0x89, 0x47, 0x27,
- 0x8e, 0x4e, 0x75, 0xff, 0x86, 0x26, 0x81, 0x89, 0xbb, 0x07, 0x5f, 0xff,
- 0xd8, 0x1e, 0xc7, 0xd6, 0x3c, 0x2f, 0xfe, 0xb5, 0x1f, 0x95, 0x7e, 0x61,
- 0x6f, 0x26, 0x21, 0x32, 0xdc, 0x27, 0x13, 0x3f, 0x1c, 0xed, 0x9e, 0x54,
- 0x36, 0x46, 0xf3, 0xce, 0x16, 0xc8, 0xcb, 0x14, 0x54, 0x9f, 0xa2, 0x6c,
- 0x7e, 0xfb, 0xc2, 0x85, 0x09, 0xe6, 0x42, 0xec, 0x33, 0xbf, 0x28, 0xf4,
- 0x70, 0x97, 0xf9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x88, 0xaf, 0xec, 0xe3,
- 0x5d, 0xda, 0x68, 0x8a, 0xef, 0xf9, 0x5d, 0x8c, 0xe3, 0x5d, 0xda, 0x68,
- 0xae, 0x29, 0x84, 0x40, 0x39, 0xc5, 0xff, 0xef, 0xe0, 0x5a, 0xc3, 0xfb,
- 0xff, 0xa3, 0x23, 0xaf, 0x98, 0x9e, 0x65, 0x73, 0xac, 0x9b, 0x9f, 0xaf,
- 0xe9, 0xb7, 0xd9, 0xd7, 0xf1, 0xd7, 0xfb, 0x13, 0x9f, 0xfe, 0x0d, 0x1d,
- 0x65, 0x40, 0x9e, 0xa6, 0x88, 0x2f, 0xff, 0xef, 0x69, 0x3a, 0xe9, 0x24,
- 0x1f, 0x03, 0xbc, 0xc3, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x14, 0xf5, 0xfe,
- 0x5a, 0x04, 0x0f, 0xc9, 0x1d, 0x72, 0xd0, 0xea, 0x83, 0xc7, 0x69, 0x95,
- 0xff, 0xfe, 0x94, 0x7b, 0x40, 0x5b, 0x53, 0xf8, 0xce, 0xa0, 0x1a, 0x75,
- 0xff, 0xfd, 0xce, 0x03, 0x9c, 0x81, 0xc5, 0x13, 0xbd, 0xcf, 0xa7, 0x5f,
- 0xfc, 0x92, 0xc1, 0xfe, 0x16, 0x9c, 0x91, 0xd7, 0xfa, 0x51, 0xc9, 0xe3,
- 0x93, 0x9d, 0x7d, 0xf0, 0x5e, 0x47, 0x5f, 0x9f, 0x3a, 0x8b, 0x3a, 0xb4,
- 0x78, 0xfb, 0x08, 0xaa, 0x11, 0x3f, 0x8f, 0x77, 0xfd, 0x02, 0xdc, 0xd9,
- 0x9e, 0xd1, 0xd7, 0xe7, 0x9e, 0x38, 0x03, 0xa9, 0x54, 0xac, 0xee, 0x0a,
- 0xf1, 0x61, 0xaf, 0x5b, 0x90, 0xa3, 0x03, 0xae, 0x0c, 0x38, 0x76, 0x10,
- 0xed, 0x9c, 0x5f, 0xfe, 0x79, 0x30, 0x11, 0x76, 0x75, 0xa8, 0xfc, 0xeb,
- 0xff, 0xdf, 0xfe, 0x0d, 0x31, 0xf4, 0x5d, 0x63, 0x07, 0x5f, 0xfc, 0x39,
- 0xfb, 0x8f, 0xec, 0x2d, 0x16, 0x75, 0x71, 0x12, 0x3e, 0x4d, 0xa6, 0x13,
- 0x96, 0x0c, 0x25, 0xd2, 0x1b, 0x97, 0x07, 0x0e, 0xbf, 0xf9, 0x03, 0xc7,
- 0xdd, 0x8e, 0x72, 0x27, 0x3a, 0x98, 0x3d, 0xbe, 0x8a, 0xdc, 0x18, 0x3a,
- 0xff, 0xfd, 0xd8, 0xe6, 0x49, 0x1f, 0xd8, 0x14, 0x03, 0x4a, 0xbf, 0x44,
- 0xbf, 0x04, 0x8e, 0xbe, 0x6b, 0xbb, 0x4d, 0x15, 0x9d, 0x4c, 0x7a, 0xbc,
- 0x28, 0xbe, 0xf2, 0x2f, 0x47, 0x5f, 0xd3, 0xae, 0x06, 0x5a, 0x3a, 0xfd,
- 0x9e, 0xd7, 0xdd, 0x1d, 0x7a, 0x27, 0x43, 0xaf, 0xde, 0xff, 0xe8, 0xc8,
- 0xeb, 0xc0, 0x7d, 0x1d, 0x7f, 0xd9, 0x24, 0x02, 0xba, 0xb7, 0xfa, 0xce,
- 0xbf, 0x64, 0xd3, 0x83, 0xf3, 0xac, 0xc4, 0x2a, 0x21, 0x08, 0xae, 0x42,
- 0x9f, 0x72, 0x3e, 0x10, 0xac, 0xb7, 0xa5, 0x2e, 0x36, 0x25, 0x5a, 0x1b,
- 0xfa, 0x83, 0x7f, 0xee, 0xa7, 0x9f, 0x93, 0xc2, 0x04, 0xeb, 0xf7, 0x90,
- 0x71, 0x67, 0x5f, 0x49, 0xc5, 0x8c, 0x3e, 0x2d, 0xa3, 0xdb, 0xff, 0x3c,
- 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89, 0x16, 0xff, 0xcf, 0xe6, 0x21, 0x38,
- 0x9e, 0x01, 0xd4, 0xc2, 0x21, 0xdd, 0x2a, 0xfe, 0xce, 0x35, 0xdd, 0xa6,
- 0x8b, 0x26, 0xff, 0xf7, 0xb5, 0xf7, 0x4c, 0x64, 0xe8, 0x32, 0xd1, 0xd4,
- 0xc2, 0x21, 0x70, 0xe2, 0xff, 0xff, 0x3a, 0x78, 0x1c, 0x7d, 0x30, 0xde,
- 0xa7, 0x22, 0x5a, 0x3a, 0xfe, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0x62, 0xff,
- 0xfe, 0x54, 0x77, 0xe0, 0xe7, 0x3d, 0xae, 0xcd, 0xf3, 0xe7, 0x76, 0xce,
- 0xbd, 0xc0, 0x74, 0xeb, 0xbc, 0xc4, 0x22, 0x1b, 0x8d, 0x54, 0xc2, 0x3b,
- 0x52, 0x17, 0xd7, 0xb3, 0x58, 0x75, 0xf3, 0x5d, 0xda, 0x68, 0xb6, 0xef,
- 0xb5, 0x3b, 0xf0, 0xea, 0xe1, 0xe7, 0xf8, 0xb6, 0xfe, 0x4e, 0xf9, 0x3f,
- 0x01, 0xd7, 0xfd, 0x12, 0x8e, 0x4f, 0x1c, 0x9c, 0xeb, 0x31, 0x24, 0x78,
- 0xe3, 0x4c, 0xc4, 0x42, 0x5b, 0x7f, 0xfb, 0x07, 0xf6, 0x16, 0xe1, 0xcc,
- 0x15, 0x0e, 0xbc, 0xaa, 0xe8, 0x4e, 0xbd, 0x3f, 0x50, 0xeb, 0xff, 0x2a,
- 0x95, 0x4a, 0xd3, 0xdd, 0xc1, 0x8f, 0xce, 0xbf, 0xa0, 0x64, 0x10, 0x2c,
- 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x78, 0x5f, 0xf9, 0xfd, 0x1b, 0x39, 0xcc,
- 0xdf, 0x47, 0x57, 0x0f, 0xb4, 0x4b, 0x6f, 0xbd, 0xb7, 0x9d, 0x3a, 0xfc,
- 0xb8, 0x19, 0x39, 0xd7, 0xfa, 0x50, 0x3e, 0xd8, 0xed, 0x3a, 0xff, 0x47,
- 0x9f, 0xbf, 0x03, 0x07, 0x5f, 0xfb, 0xea, 0xf7, 0x97, 0xb0, 0x7d, 0xa3,
- 0xae, 0xc5, 0x0e, 0xa8, 0x3d, 0x7c, 0x41, 0xbe, 0x49, 0xf1, 0x67, 0x5f,
- 0xb0, 0x7f, 0xda, 0x83, 0xaf, 0xd1, 0xf4, 0x0f, 0xa3, 0xaf, 0xff, 0x62,
- 0xe1, 0xbf, 0x30, 0x41, 0x2c, 0xd1, 0xd7, 0xff, 0x67, 0x7a, 0xf2, 0x5a,
- 0x47, 0x24, 0x75, 0xd1, 0xf9, 0xd5, 0x23, 0xd8, 0xf2, 0x15, 0x2a, 0x15,
- 0xce, 0xaa, 0x88, 0x15, 0x78, 0xe4, 0xe9, 0x99, 0x09, 0x9d, 0xc8, 0x50,
- 0x92, 0x62, 0x55, 0x99, 0xf6, 0x11, 0x4e, 0x41, 0xf9, 0x08, 0x94, 0xe8,
- 0xa3, 0xd0, 0xa1, 0xbf, 0xdb, 0xb1, 0x9f, 0xbf, 0x34, 0x75, 0xfe, 0xfd,
- 0x89, 0xa5, 0x03, 0xe3, 0xa9, 0x84, 0xd5, 0x62, 0x1d, 0x7c, 0x35, 0xbc,
- 0x99, 0xb9, 0xd7, 0xcd, 0x77, 0x69, 0xa2, 0xf4, 0xbf, 0xf2, 0x7b, 0xa2,
- 0xf2, 0xfd, 0xff, 0x3a, 0xb8, 0x7d, 0x6b, 0x2d, 0xbc, 0xb4, 0xf1, 0xd7,
- 0xfc, 0xfe, 0x94, 0x29, 0xe4, 0x9c, 0xea, 0x59, 0xea, 0x08, 0xdd, 0xfb,
- 0x17, 0xd7, 0x09, 0xd4, 0x14, 0xd0, 0xf2, 0x10, 0xdf, 0x5d, 0xb6, 0x88,
- 0x6f, 0xff, 0xf9, 0x36, 0x60, 0xb0, 0x1c, 0x0f, 0x71, 0x6b, 0x79, 0x60,
- 0x9d, 0x4c, 0x22, 0xb3, 0x11, 0xea, 0x1b, 0x63, 0xf9, 0xe1, 0x7f, 0x28,
- 0x4c, 0x64, 0xea, 0x73, 0x61, 0x2c, 0x92, 0x91, 0x26, 0x8c, 0x1f, 0x90,
- 0xc2, 0x5c, 0x2a, 0x3a, 0x47, 0xfc, 0x69, 0xa3, 0x18, 0xce, 0x90, 0xc1,
- 0x3a, 0x76, 0xcc, 0xa2, 0x5b, 0x81, 0xd3, 0xaf, 0xfe, 0x04, 0x4c, 0x39,
- 0xb1, 0xd6, 0xb4, 0x3a, 0xfb, 0x3a, 0xfe, 0x3a, 0xff, 0x62, 0x73, 0xff,
- 0xc1, 0xa3, 0xac, 0xa8, 0x51, 0x13, 0x02, 0x89, 0xa2, 0x0b, 0xef, 0x46,
- 0xf3, 0x9d, 0x7f, 0xde, 0xd6, 0x6f, 0x2e, 0x81, 0x43, 0xa9, 0x0f, 0x78,
- 0x48, 0xef, 0xa3, 0x64, 0x48, 0xeb, 0xf7, 0x1a, 0xee, 0xd3, 0x44, 0x47,
- 0x7f, 0xfd, 0xd0, 0x6b, 0x58, 0xb1, 0xcd, 0x9f, 0x21, 0x58, 0x3a, 0xff,
- 0xa2, 0x7e, 0x67, 0xbc, 0x9e, 0x3a, 0xf0, 0xc6, 0xe7, 0x54, 0x8f, 0x4c,
- 0x27, 0x17, 0xfd, 0x9c, 0xcd, 0x63, 0x8c, 0xe7, 0x5e, 0xc0, 0xac, 0xeb,
- 0xff, 0xfd, 0xd7, 0x4f, 0x47, 0x47, 0x3d, 0xd4, 0xee, 0x23, 0x27, 0x5f,
- 0xff, 0xfe, 0xf7, 0x91, 0x7c, 0x4c, 0xdc, 0x41, 0xe8, 0xef, 0xcd, 0x89,
- 0xe9, 0xa0, 0xea, 0x84, 0x6c, 0x62, 0xed, 0xfe, 0x75, 0xe7, 0x25, 0x0b,
- 0x3a, 0xe9, 0xd6, 0x55, 0xcc, 0xb2, 0x55, 0xff, 0x98, 0x6f, 0x52, 0x6e,
- 0xc4, 0xec, 0x7e, 0x6b, 0xd9, 0x17, 0xbe, 0xd9, 0x1e, 0x83, 0xaa, 0x47,
- 0xfa, 0x8b, 0x77, 0xf6, 0x3a, 0xf3, 0x7f, 0x1d, 0x7f, 0x9d, 0x8d, 0x27,
- 0x1f, 0xf3, 0xac, 0xae, 0x75, 0xff, 0x46, 0x6f, 0x0f, 0x27, 0x91, 0xd4,
- 0xac, 0x9e, 0x48, 0x44, 0xef, 0xe5, 0x71, 0xce, 0xbf, 0x8e, 0xbf, 0xa1,
- 0x4c, 0x14, 0x50, 0xeb, 0xfb, 0x3d, 0xb5, 0xec, 0xe9, 0xd5, 0x88, 0x89,
- 0x12, 0xed, 0x16, 0x5f, 0xff, 0xcd, 0x63, 0x8e, 0x29, 0xe6, 0x39, 0x1e,
- 0x17, 0xfc, 0xea, 0x56, 0xd7, 0xac, 0x15, 0x50, 0xae, 0x88, 0x4c, 0x48,
- 0x83, 0x08, 0x9a, 0x67, 0xbc, 0x2a, 0x90, 0x8a, 0x63, 0x6e, 0x43, 0xcf,
- 0xa4, 0x2f, 0x0d, 0xdf, 0xc8, 0x44, 0xb3, 0x4f, 0x9e, 0x85, 0x86, 0xc2,
- 0xeb, 0xb6, 0xba, 0x75, 0xfb, 0x8d, 0x77, 0x69, 0xa2, 0x2e, 0xbf, 0x7b,
- 0xff, 0xa3, 0x22, 0xaf, 0xda, 0xf7, 0x63, 0xf3, 0xaf, 0xcf, 0x3c, 0x70,
- 0x07, 0x59, 0x89, 0xd1, 0x8b, 0x83, 0x2e, 0x66, 0x02, 0xad, 0xb2, 0x8a,
- 0x61, 0x51, 0x44, 0xa3, 0xd5, 0xbf, 0xf9, 0x6f, 0x26, 0x33, 0x8d, 0x77,
- 0x69, 0xa2, 0x66, 0xbf, 0x95, 0x65, 0x68, 0xa8, 0xd4, 0x78, 0xeb, 0xdb,
- 0xc6, 0x8e, 0xbc, 0xd4, 0x59, 0xd7, 0xca, 0xaf, 0x38, 0x9d, 0x76, 0xda,
- 0xb2, 0x75, 0xd8, 0x03, 0xaf, 0xff, 0x76, 0x16, 0xfe, 0xcd, 0xff, 0x5f,
- 0xde, 0x9d, 0x7f, 0x7b, 0x27, 0xcf, 0xe6, 0x3a, 0xff, 0x7c, 0xc1, 0x7e,
- 0x7f, 0xb6, 0x75, 0xff, 0xf9, 0x6f, 0xdc, 0xdf, 0xfe, 0xb2, 0xfd, 0x9b,
- 0xa0, 0x3a, 0x82, 0x89, 0x0c, 0x37, 0xbb, 0x58, 0x75, 0xdb, 0x5e, 0x3a,
- 0xca, 0x93, 0xad, 0xfc, 0x1a, 0xd0, 0x0c, 0xdf, 0xff, 0xf9, 0x06, 0x1a,
- 0x30, 0xbf, 0x91, 0xce, 0x26, 0xce, 0x3b, 0xfe, 0x75, 0x2b, 0x2a, 0x8d,
- 0x9a, 0x3c, 0x82, 0xb3, 0x26, 0xf6, 0x17, 0xee, 0x45, 0xfa, 0x17, 0x89,
- 0xef, 0xe6, 0x60, 0x47, 0x3c, 0x75, 0xf3, 0xf5, 0x26, 0x3a, 0xfb, 0xb3,
- 0x40, 0x4e, 0xac, 0x3e, 0xe6, 0x95, 0xb9, 0x0d, 0xfe, 0x6a, 0x60, 0x87,
- 0xb0, 0x75, 0x1d, 0x7e, 0xeb, 0xfa, 0x5f, 0x9d, 0x7f, 0xfb, 0xe7, 0x5d,
- 0x3d, 0xf8, 0x04, 0x5e, 0x47, 0x56, 0x22, 0xb1, 0xa6, 0x08, 0x14, 0xb2,
- 0x8b, 0xff, 0xff, 0xff, 0xff, 0xca, 0xbd, 0x51, 0x8a, 0xbd, 0x54, 0xad,
- 0x15, 0xa3, 0x55, 0x30, 0xab, 0x95, 0x5c, 0x9f, 0x6b, 0x00, 0x15, 0x6b,
- 0x1b, 0x7b, 0xfd, 0xea, 0xaa, 0x21, 0x54, 0xae, 0xab, 0x7b, 0xe7, 0xce,
- 0xed, 0x9d, 0x7f, 0xfe, 0xff, 0x79, 0x74, 0x11, 0xc6, 0x3a, 0x8d, 0x7e,
- 0x1d, 0x7f, 0xf6, 0xec, 0xc7, 0x82, 0x8a, 0xfa, 0x85, 0x9d, 0x7f, 0xff,
- 0xe4, 0x5a, 0x73, 0xa0, 0xd4, 0xa3, 0x67, 0x20, 0x7d, 0xdc, 0x91, 0xd7,
- 0xfe, 0x4f, 0x23, 0x50, 0x3e, 0xc6, 0x9d, 0x58, 0x8f, 0x0f, 0x24, 0x6d,
- 0x36, 0x5f, 0x7b, 0x6f, 0x3a, 0x75, 0xff, 0xfe, 0x71, 0x68, 0xe0, 0x7a,
- 0x0f, 0x9d, 0x89, 0x72, 0x27, 0x3a, 0xb1, 0x10, 0xa0, 0x24, 0xbf, 0xff,
- 0xce, 0xa0, 0xe7, 0xe0, 0xd7, 0xc9, 0x27, 0x61, 0xa2, 0xe7, 0x5f, 0x79,
- 0x3a, 0x87, 0x5f, 0xf3, 0xf2, 0x5f, 0x31, 0xa1, 0xc3, 0xa9, 0x54, 0xb8,
- 0x0d, 0x11, 0x95, 0xe4, 0x69, 0x1d, 0x85, 0xbb, 0x91, 0x0b, 0x08, 0x08,
- 0x2d, 0xc3, 0xaf, 0xef, 0x62, 0xf7, 0xc5, 0x9d, 0x6e, 0xe1, 0xbd, 0x41,
- 0x0b, 0xfc, 0x00, 0xbc, 0xb4, 0x92, 0x3a, 0xff, 0xfc, 0x14, 0x19, 0xf3,
- 0x48, 0xfd, 0x61, 0x96, 0x59, 0x2a, 0xfe, 0xf7, 0x62, 0x7e, 0x80, 0xeb,
- 0xfb, 0x79, 0x6b, 0xf0, 0x4c, 0x75, 0xff, 0x4f, 0x9f, 0x84, 0x0f, 0xc9,
- 0x1d, 0x79, 0xdd, 0xa6, 0x8b, 0x3e, 0xfe, 0xfd, 0xc6, 0x48, 0xb3, 0xaa,
- 0x74, 0x46, 0xb4, 0xeb, 0xf2, 0x7b, 0xff, 0x27, 0x62, 0x49, 0xe8, 0xf6,
- 0x8e, 0xbf, 0xfd, 0xce, 0xbf, 0xcc, 0xd8, 0x39, 0xac, 0x13, 0xaf, 0xfe,
- 0xd7, 0x92, 0x66, 0x5c, 0x31, 0xbe, 0x8e, 0xa4, 0x44, 0x80, 0x12, 0xaf,
- 0x32, 0xcb, 0x25, 0x5f, 0xf9, 0xe5, 0xa1, 0xc6, 0x87, 0x38, 0x53, 0x05,
- 0xfd, 0xfb, 0x68, 0x0b, 0xc0, 0x9d, 0x7f, 0xbd, 0xdc, 0xd9, 0xf2, 0x4b,
- 0x3a, 0xb0, 0xf8, 0x40, 0x55, 0x7f, 0xed, 0xe4, 0x20, 0xff, 0xe3, 0x57,
- 0xf9, 0xd7, 0x42, 0x87, 0x54, 0x1e, 0xd4, 0xe8, 0x97, 0xfb, 0xa8, 0x11,
- 0x77, 0x98, 0xeb, 0xfc, 0x1e, 0x81, 0xff, 0xdb, 0xc3, 0xaa, 0x0f, 0x9d,
- 0x0c, 0x6f, 0xf9, 0x04, 0x3f, 0x42, 0x0f, 0x68, 0xeb, 0xd0, 0x2a, 0x1d,
- 0x52, 0x5d, 0x00, 0x09, 0x2b, 0x4c, 0xb7, 0x58, 0x98, 0xbb, 0x90, 0xbe,
- 0x59, 0x97, 0x61, 0x99, 0xfa, 0x08, 0xc2, 0xb7, 0x4f, 0x7e, 0x84, 0x4e,
- 0xc2, 0x0f, 0xa7, 0x57, 0xfd, 0xc7, 0x67, 0xa9, 0x1c, 0x83, 0xaf, 0xfd,
- 0xc4, 0xd4, 0xbe, 0xf6, 0x06, 0x0e, 0xbe, 0xe2, 0x42, 0xce, 0xbf, 0xff,
- 0x79, 0x40, 0x46, 0x07, 0xb9, 0xad, 0xe5, 0x1d, 0x3a, 0xb8, 0x8b, 0x45,
- 0x9f, 0x09, 0x05, 0xcf, 0x23, 0xaf, 0xff, 0xff, 0xe1, 0x76, 0x7d, 0x9d,
- 0x1c, 0xf0, 0x3f, 0x5b, 0xc9, 0xc3, 0x02, 0xfc, 0x79, 0x1d, 0x7f, 0xb3,
- 0xbd, 0x07, 0x9c, 0x4e, 0xbe, 0x5a, 0x4d, 0xa3, 0xac, 0x81, 0x47, 0x6c,
- 0xc2, 0xbc, 0x84, 0x2a, 0xcc, 0x6f, 0xdc, 0x9b, 0x66, 0x04, 0xeb, 0xff,
- 0x63, 0x3b, 0x5c, 0xcd, 0xa1, 0x03, 0x27, 0x54, 0x27, 0xa7, 0xd8, 0xc7,
- 0x1d, 0x20, 0x4a, 0xaf, 0xff, 0xff, 0xbf, 0xd6, 0x60, 0xa9, 0xf7, 0x83,
- 0x19, 0xd6, 0x34, 0x39, 0x3a, 0xf1, 0x67, 0x5f, 0xbe, 0xc0, 0xfd, 0x59,
- 0xd5, 0x88, 0xa9, 0xf3, 0xfd, 0xfb, 0x63, 0xf6, 0x3e, 0x9d, 0x58, 0x79,
- 0x88, 0x45, 0x7b, 0x51, 0x39, 0xd7, 0xfd, 0x18, 0xde, 0xa6, 0xc7, 0xe1,
- 0xd7, 0x67, 0x4e, 0xa1, 0x3c, 0xdd, 0xb3, 0x8a, 0x92, 0x2b, 0x74, 0x41,
- 0xe6, 0x9b, 0xdd, 0x03, 0x27, 0x5e, 0xfc, 0x0d, 0x3a, 0xf7, 0xb3, 0xe9,
- 0xd7, 0xf4, 0x6f, 0xaf, 0x9c, 0x83, 0xaf, 0x04, 0x0d, 0x3a, 0xf8, 0x23,
- 0x12, 0x3a, 0x90, 0xde, 0x38, 0xe5, 0x05, 0x1c, 0x3b, 0x8e, 0xa0, 0xea,
- 0xc7, 0x7a, 0xd7, 0x76, 0x34, 0xeb, 0xfb, 0x89, 0xb3, 0x07, 0x47, 0x5f,
- 0xdb, 0xfb, 0x3a, 0x05, 0x73, 0xaf, 0xee, 0x67, 0x7a, 0x0f, 0x1d, 0x7e,
- 0xe8, 0xc6, 0x70, 0xcb, 0xfb, 0x39, 0x38, 0x1c, 0x26, 0x88, 0x35, 0x83,
- 0x4b, 0x6e, 0x4e, 0x89, 0xd9, 0x29, 0x54, 0x23, 0xe1, 0x21, 0x9d, 0x7e,
- 0x76, 0xa2, 0xe0, 0xeb, 0xfa, 0x5d, 0x17, 0xdf, 0xc7, 0x5b, 0x1a, 0x7a,
- 0x42, 0x4b, 0x7e, 0x8f, 0x7c, 0x5b, 0x27, 0x5f, 0xe9, 0x22, 0xe3, 0xbf,
- 0x42, 0x75, 0xff, 0xe8, 0xc1, 0xdf, 0xd9, 0xc4, 0x9d, 0xd6, 0x75, 0xf9,
- 0xd9, 0xf6, 0x77, 0x47, 0xf9, 0xe3, 0x4a, 0x56, 0xd5, 0x5e, 0xc0, 0xac,
- 0xa3, 0x25, 0xc7, 0x8e, 0x13, 0x0c, 0x29, 0xaf, 0x6b, 0x24, 0x75, 0xf9,
- 0x37, 0x92, 0x09, 0xd7, 0x93, 0xb8, 0x75, 0xd0, 0xbc, 0x3c, 0x06, 0x93,
- 0x5f, 0x07, 0x5d, 0x83, 0xaf, 0xc3, 0xc6, 0x5e, 0x73, 0xab, 0x0f, 0x25,
- 0xc8, 0x6e, 0x00, 0x9d, 0x50, 0x98, 0x2a, 0x2d, 0xf1, 0xd7, 0x44, 0x17,
- 0xbb, 0x82, 0x75, 0xfe, 0x9a, 0x27, 0x5b, 0xcd, 0x07, 0x5f, 0xff, 0x3a,
- 0x9e, 0x8e, 0x7f, 0xc8, 0xf0, 0xbf, 0xe7, 0x5f, 0xff, 0xc2, 0xea, 0x7c,
- 0xfa, 0x2f, 0xed, 0x26, 0xfd, 0x46, 0x4e, 0xac, 0x47, 0xeb, 0x8d, 0x09,
- 0xa0, 0x14, 0x2e, 0xd6, 0xc3, 0xaf, 0x90, 0x5c, 0x27, 0x5f, 0xf9, 0x79,
- 0xed, 0x7d, 0xd3, 0xcb, 0x0e, 0xbf, 0x6a, 0x39, 0xe8, 0x39, 0x83, 0x7f,
- 0x41, 0x44, 0xae, 0x97, 0xaf, 0xdf, 0x66, 0x77, 0xe1, 0xd7, 0xdd, 0xc4,
- 0xd8, 0x75, 0xfd, 0xa4, 0xe6, 0x03, 0x87, 0x5f, 0xff, 0xe8, 0x9b, 0xe2,
- 0x34, 0x1c, 0xd0, 0x3e, 0x2d, 0x3d, 0xd4, 0x3a, 0xb1, 0x3a, 0xc4, 0x85,
- 0x6a, 0xc8, 0xfa, 0x53, 0xe2, 0x2d, 0xa2, 0xcb, 0x96, 0xa8, 0x34, 0x5f,
- 0x97, 0xda, 0xe6, 0x61, 0xd7, 0xff, 0x4b, 0xc0, 0x94, 0x97, 0xef, 0x42,
- 0xce, 0xbf, 0xde, 0xd4, 0x4f, 0x9a, 0x09, 0xd7, 0x77, 0x0e, 0xbf, 0xfe,
- 0xec, 0x07, 0x1b, 0xf3, 0x07, 0x03, 0xd8, 0x3a, 0xff, 0xe4, 0xc1, 0xcc,
- 0xd7, 0xc9, 0x69, 0x67, 0x5f, 0xf9, 0xe3, 0x79, 0x7c, 0xd6, 0xe1, 0x83,
- 0xa8, 0x29, 0xbf, 0xee, 0x40, 0x88, 0xaa, 0xe6, 0x73, 0x0a, 0xe9, 0x3b,
- 0xc8, 0x77, 0x94, 0x8e, 0x1d, 0x7f, 0x06, 0x3f, 0xe6, 0x6e, 0x75, 0x30,
- 0x79, 0x4b, 0x1c, 0xbf, 0xd0, 0xbc, 0x4e, 0x4d, 0x23, 0xae, 0x49, 0x8e,
- 0xbf, 0xfd, 0xe8, 0xe8, 0xbc, 0xf1, 0xce, 0x3c, 0x8e, 0xbd, 0xe4, 0x9c,
- 0xeb, 0xf7, 0xef, 0xbc, 0x4c, 0x75, 0xe1, 0x86, 0x9d, 0x7f, 0xf0, 0x52,
- 0x6e, 0xc7, 0x37, 0x94, 0x70, 0xeb, 0xff, 0x85, 0xf7, 0xd6, 0xb3, 0x81,
- 0xee, 0x1d, 0x7f, 0xfa, 0x1b, 0xf3, 0x98, 0x80, 0x54, 0xe6, 0xd6, 0x1d,
- 0x48, 0x89, 0x31, 0x43, 0xaf, 0x89, 0xdb, 0x20, 0xb2, 0xd2, 0x1c, 0x70,
- 0x4a, 0x74, 0x35, 0xb5, 0x0d, 0x8b, 0x41, 0xd7, 0xba, 0x9e, 0x3a, 0xdb,
- 0x30, 0xd5, 0x7d, 0x0f, 0xa8, 0x5d, 0x82, 0x0a, 0xf6, 0x47, 0x4c, 0x90,
- 0xb3, 0xe9, 0x1b, 0xc7, 0xd1, 0xfc, 0x25, 0xaf, 0xfb, 0x06, 0x43, 0x8b,
- 0x86, 0x9d, 0x7e, 0xea, 0x6c, 0xc0, 0x9d, 0x7f, 0xe0, 0xc0, 0xe0, 0x82,
- 0x59, 0xa3, 0xaf, 0xce, 0xb4, 0xda, 0xc3, 0xaf, 0x7a, 0x37, 0x3a, 0xb0,
- 0xf1, 0x1c, 0xa2, 0xf4, 0x24, 0xc7, 0x5e, 0x15, 0x67, 0x68, 0xeb, 0xf6,
- 0x4e, 0xb8, 0xd1, 0xd7, 0xff, 0xfe, 0x8e, 0xa2, 0xd8, 0x9a, 0x4f, 0xcf,
- 0xbd, 0x4d, 0xf4, 0xd4, 0x9c, 0xea, 0x0a, 0x7a, 0x4a, 0x1a, 0xa1, 0x44,
- 0xcf, 0xfd, 0x20, 0x11, 0xbd, 0x11, 0xed, 0x13, 0xdf, 0xcf, 0xc8, 0xef,
- 0xd0, 0x9d, 0x7d, 0x09, 0x3c, 0x1d, 0x7c, 0xcb, 0xe6, 0x8e, 0xbf, 0xe9,
- 0x2d, 0xe5, 0xed, 0x42, 0x87, 0x54, 0x1e, 0xd3, 0x90, 0xde, 0xd2, 0x09,
- 0xd7, 0xe1, 0x6f, 0xcd, 0x6e, 0x75, 0x61, 0xe2, 0x38, 0xd5, 0x3a, 0x65,
- 0x9f, 0x97, 0x0b, 0xd0, 0x19, 0x2e, 0x9e, 0x47, 0x5e, 0x4e, 0xa1, 0xd5,
- 0xb9, 0xb1, 0xf0, 0xbd, 0xf7, 0xd0, 0x3e, 0x8e, 0xbf, 0xd2, 0x00, 0xcf,
- 0xa4, 0xdc, 0xeb, 0xef, 0xff, 0xcd, 0xce, 0xbf, 0xb6, 0xbd, 0x8e, 0x2d,
- 0x3a, 0xff, 0x80, 0xf2, 0x0e, 0x67, 0xfa, 0x3a, 0xff, 0x7e, 0x9b, 0xef,
- 0x2c, 0xf1, 0xd5, 0xd3, 0xed, 0xd1, 0xc5, 0xfb, 0x7d, 0x2d, 0x15, 0xce,
- 0xbf, 0xff, 0x66, 0xbe, 0x75, 0xd3, 0xdf, 0x80, 0x45, 0xe4, 0x75, 0x42,
- 0x20, 0x04, 0xae, 0xfe, 0x79, 0xff, 0x71, 0x09, 0xd5, 0x32, 0x7c, 0x7c,
- 0x34, 0xe9, 0x27, 0xa1, 0x37, 0xb2, 0x14, 0x5b, 0x64, 0x37, 0xfd, 0xdf,
- 0xb0, 0xdd, 0xbc, 0xe4, 0x1d, 0x50, 0xaa, 0xab, 0x25, 0x03, 0x3b, 0x45,
- 0xd3, 0x00, 0xeb, 0x2c, 0xea, 0xdc, 0xd3, 0xaa, 0x45, 0xef, 0xfe, 0x8e,
- 0x66, 0xc7, 0x97, 0xf9, 0x81, 0x3a, 0xfe, 0x7d, 0xe4, 0x30, 0x13, 0xaf,
- 0xfa, 0x37, 0x92, 0x0a, 0xdf, 0xc7, 0x53, 0x9f, 0x18, 0x96, 0x5f, 0x9e,
- 0x59, 0x3c, 0x1d, 0x7f, 0xf4, 0x6b, 0x58, 0xbf, 0x0c, 0x2f, 0x47, 0x5f,
- 0xfc, 0x91, 0xa1, 0x79, 0x7c, 0xd6, 0x70, 0xeb, 0xff, 0xfc, 0x9a, 0x9f,
- 0x19, 0xc1, 0x06, 0xd4, 0x31, 0x82, 0xfc, 0x3a, 0xff, 0x6f, 0x2d, 0x4d,
- 0x28, 0x9c, 0xea, 0x0a, 0x68, 0x6d, 0x26, 0x14, 0x2f, 0x21, 0x81, 0x8a,
- 0xff, 0xff, 0xdd, 0x4d, 0xfd, 0x9b, 0xfb, 0x9c, 0x8f, 0x7f, 0xf4, 0x65,
- 0xdc, 0x3a, 0xf8, 0x21, 0x71, 0x3a, 0xff, 0xd2, 0x81, 0xf7, 0x13, 0x66,
- 0x04, 0xeb, 0xff, 0x3f, 0x5a, 0x8f, 0xf3, 0x4f, 0xd3, 0xaf, 0xff, 0xda,
- 0x1f, 0x9d, 0x74, 0xf7, 0xe0, 0x11, 0x79, 0x1d, 0x7f, 0xba, 0x8a, 0x6d,
- 0x83, 0x8a, 0x1d, 0x7f, 0xd0, 0xca, 0xfb, 0x08, 0x33, 0x9d, 0x7f, 0xfc,
- 0x39, 0xac, 0x5c, 0x37, 0x3c, 0x9c, 0xc3, 0xad, 0x8d, 0x45, 0xdf, 0x8e,
- 0x36, 0x1c, 0x5f, 0xd3, 0xe7, 0x11, 0xb0, 0x75, 0xf0, 0x86, 0x16, 0x75,
- 0xfb, 0x66, 0x08, 0x1c, 0xeb, 0xf9, 0xff, 0xc0, 0xbc, 0x8e, 0xa8, 0x3f,
- 0x3c, 0x20, 0x42, 0x7a, 0x44, 0x65, 0xf6, 0x13, 0xf5, 0x0b, 0xb7, 0xf3,
- 0x93, 0x06, 0x14, 0xf9, 0x1b, 0x1b, 0x52, 0x91, 0xc2, 0x62, 0x0e, 0x9f,
- 0x7e, 0x7c, 0x31, 0x88, 0x7a, 0x30, 0x2b, 0xff, 0xb0, 0x7f, 0xcc, 0xe6,
- 0xbd, 0x18, 0x75, 0xff, 0x6f, 0xec, 0xe2, 0x4e, 0xeb, 0x3a, 0xd9, 0xf9,
- 0xfd, 0x0a, 0x0d, 0xe5, 0x4c, 0x90, 0xeb, 0xe8, 0x17, 0x91, 0xd7, 0xec,
- 0x57, 0x71, 0xff, 0xe1, 0xbe, 0xe0, 0xfd, 0xfd, 0xb3, 0xa9, 0x1c, 0xd1,
- 0xd7, 0xff, 0xe8, 0x19, 0x67, 0x51, 0x61, 0xc9, 0xa3, 0x38, 0x75, 0xf3,
- 0x7a, 0x93, 0x1d, 0x7f, 0xfe, 0x1c, 0x51, 0x44, 0x0f, 0x52, 0x6e, 0xa6,
- 0xfe, 0x3a, 0xa0, 0xfe, 0x70, 0x8a, 0xf3, 0x5f, 0x87, 0x5f, 0xb4, 0xd8,
- 0xe2, 0x87, 0x57, 0x4f, 0x0f, 0xf1, 0xbb, 0xfd, 0x92, 0xc4, 0x0f, 0x50,
- 0xeb, 0xef, 0x49, 0x7d, 0x3a, 0xf9, 0x14, 0x46, 0x4e, 0xac, 0x3c, 0x41,
- 0x22, 0xbb, 0xe6, 0x1d, 0x7d, 0xa1, 0x85, 0x9d, 0x50, 0x6d, 0xf7, 0x17,
- 0xbe, 0xce, 0xc9, 0x67, 0x54, 0x2b, 0x33, 0x93, 0x2e, 0x21, 0x28, 0x5d,
- 0xd8, 0x65, 0xbb, 0x18, 0x91, 0xe9, 0xd0, 0x0a, 0xfb, 0x64, 0x37, 0x82,
- 0xb6, 0x9d, 0x6e, 0x9d, 0x76, 0xa4, 0x75, 0x7e, 0x69, 0x80, 0x21, 0x7f,
- 0x4f, 0x34, 0x95, 0x5c, 0x9c, 0xeb, 0xcf, 0x9c, 0x3a, 0xf0, 0xe7, 0x8e,
- 0xae, 0x9b, 0x41, 0x1a, 0xbb, 0xc2, 0x75, 0xe8, 0xdf, 0x47, 0x5f, 0x20,
- 0xcb, 0x0e, 0xbd, 0x3b, 0x89, 0xd4, 0x13, 0xd6, 0x58, 0xe7, 0x87, 0xef,
- 0xd9, 0xee, 0xa7, 0x8e, 0xbf, 0x3e, 0xf9, 0xbf, 0x8e, 0xb2, 0x9d, 0x3c,
- 0xef, 0x13, 0x5c, 0x9c, 0x3a, 0xfe, 0x9f, 0xe4, 0xee, 0xfd, 0x3a, 0x95,
- 0x94, 0xf7, 0xe1, 0xa6, 0x44, 0x18, 0xd6, 0x8f, 0xbd, 0x29, 0x71, 0x5b,
- 0xfe, 0xc0, 0x85, 0x37, 0xcd, 0xfc, 0x75, 0xf3, 0x46, 0x24, 0x75, 0x74,
- 0xf6, 0x5c, 0xe6, 0xff, 0x46, 0x7a, 0x3a, 0xe1, 0x3a, 0xa7, 0x3d, 0x10,
- 0x90, 0xdf, 0xfc, 0x18, 0x0f, 0x23, 0xc8, 0xd4, 0x09, 0xd7, 0xd3, 0x46,
- 0xd4, 0x8e, 0xbf, 0xbc, 0xd0, 0x85, 0x7c, 0x3a, 0xff, 0xa6, 0xd6, 0xc7,
- 0x19, 0xc0, 0x13, 0xaf, 0xb3, 0xd8, 0xb3, 0xae, 0x15, 0x0e, 0xb6, 0x9c,
- 0xdb, 0x00, 0x82, 0xfe, 0xe8, 0x27, 0x9b, 0xa8, 0x75, 0xf0, 0x8e, 0x78,
- 0xea, 0x84, 0xe7, 0x82, 0x47, 0x88, 0x4a, 0x12, 0xa1, 0x74, 0xce, 0x5d,
- 0x26, 0xf1, 0x7d, 0xfd, 0xf2, 0x68, 0xf0, 0xec, 0x3a, 0xff, 0xf0, 0xc6,
- 0xce, 0x47, 0x31, 0x3b, 0x01, 0x3a, 0xf0, 0xba, 0xce, 0xa9, 0x22, 0x4f,
- 0x0c, 0x51, 0x22, 0xcc, 0x2b, 0x2e, 0xe9, 0xf9, 0x5b, 0x3c, 0x56, 0x83,
- 0x8a, 0xd4, 0x6e, 0x25, 0x2d, 0x4f, 0x0e, 0xb9, 0x43, 0x64, 0x33, 0x88,
- 0x39, 0x3b, 0x6a, 0xa4, 0x37, 0x1b, 0x2a, 0xfb, 0x78, 0xf8, 0xd2, 0x31,
- 0x19, 0xa5, 0x83, 0xf2, 0x36, 0xb5, 0xc6, 0x73, 0xd9, 0xf6, 0x87, 0x94,
- 0x99, 0xfc, 0x74, 0x2a, 0x96, 0xe1, 0x95, 0x99, 0xa9, 0xe1, 0xcf, 0x4e,
- 0x2f, 0x02, 0x12, 0x4c, 0xa1, 0x6d, 0xca, 0x01, 0xfb, 0x2a, 0xbb, 0x6a,
- 0x30, 0x4a, 0x61, 0xde, 0x82, 0x76, 0xdd, 0x67, 0x5f, 0xfe, 0x61, 0x6f,
- 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x6c, 0xbf, 0xcc, 0x67, 0x1a, 0xee,
- 0xd3, 0x45, 0x5b, 0x7f, 0xa5, 0x20, 0x78, 0x62, 0x47, 0x5f, 0x67, 0x5f,
- 0xc7, 0x59, 0x51, 0x87, 0xa4, 0x26, 0x57, 0xfb, 0x98, 0xd8, 0xff, 0xea,
- 0xce, 0xbf, 0xe8, 0xec, 0x4f, 0xc8, 0xc0, 0x9d, 0x5c, 0x3e, 0xce, 0x9a,
- 0xdf, 0xa3, 0x8b, 0xe8, 0x4e, 0xbc, 0x1c, 0x13, 0xaf, 0x3b, 0xb4, 0xd1,
- 0x5a, 0x5f, 0x94, 0xdf, 0x40, 0xdc, 0xea, 0x69, 0xe9, 0x21, 0x3d, 0xff,
- 0xe4, 0xf4, 0xa1, 0xbd, 0x4f, 0x69, 0xf7, 0x3a, 0xb8, 0x7d, 0x5b, 0x08,
- 0x6f, 0xff, 0x75, 0x17, 0x0d, 0xc5, 0xe0, 0xfb, 0x6c, 0xeb, 0xff, 0xe6,
- 0xc7, 0x33, 0xf7, 0x5b, 0xca, 0x11, 0xa7, 0x5f, 0xff, 0x4b, 0x58, 0x30,
- 0xb7, 0xcf, 0x7a, 0x16, 0x75, 0xde, 0xf4, 0x22, 0x65, 0xd3, 0x6f, 0xff,
- 0xff, 0x46, 0xc4, 0xf6, 0xb1, 0x46, 0xf5, 0x3d, 0x93, 0x0c, 0x2e, 0x7c,
- 0x64, 0xeb, 0xfd, 0x1e, 0x7e, 0xfc, 0x0c, 0x1d, 0x7d, 0x2f, 0x24, 0xe7,
- 0x5f, 0xbe, 0xf8, 0x63, 0xf3, 0xab, 0x73, 0xcb, 0xd8, 0x45, 0x7f, 0x9e,
- 0x5e, 0x49, 0xfa, 0x87, 0x54, 0x1e, 0xba, 0x12, 0xdf, 0xb3, 0xa9, 0x8b,
- 0x3a, 0xff, 0xe1, 0x74, 0x6f, 0x5c, 0x13, 0xf1, 0x0e, 0xa9, 0xcf, 0x9f,
- 0xa4, 0xb7, 0xfa, 0x51, 0xc9, 0xe3, 0x93, 0x9d, 0x7b, 0x39, 0xf9, 0xd7,
- 0xe9, 0xb0, 0x2b, 0x57, 0x3a, 0xfe, 0x18, 0x67, 0x79, 0x68, 0xea, 0x43,
- 0xf5, 0x98, 0x73, 0x68, 0xae, 0xa1, 0x1b, 0x79, 0x0a, 0x9b, 0xff, 0xff,
- 0xfb, 0x11, 0xb9, 0xe8, 0x1f, 0x6b, 0xe4, 0x20, 0x71, 0x7f, 0x39, 0x09,
- 0x27, 0xd1, 0xd7, 0xf6, 0x79, 0xc7, 0xf0, 0x1d, 0x7f, 0x77, 0xe2, 0x4e,
- 0xe2, 0x75, 0x48, 0xf6, 0xb0, 0xb2, 0xcc, 0x2a, 0x97, 0xb9, 0x62, 0x12,
- 0xd3, 0x91, 0x04, 0x9f, 0x21, 0xac, 0xd2, 0x44, 0x87, 0x1f, 0x0b, 0x56,
- 0xf5, 0xd8, 0x6a, 0xbc, 0x21, 0xc6, 0x1f, 0xda, 0x26, 0xf4, 0x38, 0x6f,
- 0xf3, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x60, 0x5f, 0xb8, 0xd7, 0x76, 0x9a,
- 0x27, 0x5b, 0xff, 0xfd, 0xd8, 0x9c, 0x38, 0xb6, 0x35, 0xac, 0xea, 0x68,
- 0x13, 0x9d, 0x7e, 0x61, 0x6f, 0x26, 0x31, 0x12, 0xd3, 0x19, 0xdf, 0xe9,
- 0x69, 0x85, 0x14, 0x85, 0x9d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xb6, 0x6f,
- 0xff, 0xf3, 0xc9, 0x8d, 0x42, 0x60, 0x53, 0x35, 0x9e, 0x18, 0x3a, 0xff,
- 0xdf, 0xc6, 0x98, 0xea, 0x35, 0xf8, 0x75, 0xff, 0x44, 0xa3, 0x93, 0xc7,
- 0x27, 0x3a, 0xcc, 0x62, 0x60, 0xeb, 0x33, 0x75, 0xc1, 0x3f, 0xbf, 0xff,
- 0x3f, 0xff, 0x83, 0x4c, 0x67, 0x1f, 0x5d, 0x79, 0x1d, 0x7c, 0xd7, 0x76,
- 0x9a, 0x2e, 0x6b, 0x2c, 0xea, 0xe1, 0xbd, 0x64, 0xb6, 0xff, 0x70, 0x73,
- 0x7f, 0xd2, 0x47, 0x5d, 0x32, 0xce, 0xa3, 0xac, 0xc6, 0x1f, 0xb2, 0x11,
- 0x32, 0x67, 0xb6, 0x2f, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xbb, 0xef, 0xf4,
- 0x98, 0xd7, 0x38, 0x8c, 0x9d, 0x66, 0x30, 0xfa, 0x1c, 0xce, 0xf9, 0x85,
- 0x03, 0xf9, 0xd5, 0x0f, 0x95, 0x6f, 0x96, 0xf4, 0xc1, 0xa6, 0xbb, 0xab,
- 0xa4, 0xfb, 0xb7, 0x21, 0xd8, 0xb8, 0x6a, 0xba, 0x17, 0xf1, 0x9e, 0x8a,
- 0x16, 0xa3, 0x0a, 0xf4, 0x2b, 0x7e, 0x93, 0xdf, 0xf9, 0x97, 0x19, 0xf4,
- 0x83, 0xbc, 0x8e, 0xbf, 0xfb, 0x27, 0xc6, 0x7b, 0x9a, 0xc4, 0x13, 0xae,
- 0x46, 0x3a, 0x88, 0x11, 0x3f, 0xbf, 0x6b, 0x4b, 0x79, 0x1d, 0x7f, 0xff,
- 0xff, 0xee, 0xa7, 0x52, 0x07, 0xc2, 0xea, 0x67, 0x81, 0xe4, 0xf6, 0xba,
- 0x9c, 0x89, 0xdf, 0x8d, 0x3a, 0xed, 0x41, 0xd7, 0xff, 0x6e, 0xd0, 0x3e,
- 0xfe, 0xcc, 0x15, 0x0e, 0xbc, 0x2e, 0xc4, 0x26, 0x30, 0xd2, 0x7d, 0x42,
- 0x5f, 0xc2, 0xb7, 0x80, 0xeb, 0x3a, 0xfd, 0x9b, 0x5e, 0x85, 0x0e, 0xb6,
- 0xd1, 0xd5, 0x39, 0xbd, 0xc2, 0xaa, 0xe1, 0xfc, 0x8a, 0xc5, 0xff, 0xb4,
- 0xea, 0x75, 0x20, 0x41, 0x07, 0x5f, 0xfb, 0xaf, 0xe7, 0xee, 0xf2, 0xcf,
- 0x1d, 0x58, 0x7f, 0x48, 0x79, 0x73, 0xfe, 0x75, 0xff, 0xff, 0xe1, 0x76,
- 0x47, 0x3d, 0xec, 0x9e, 0x05, 0xd4, 0xd2, 0xe3, 0x04, 0x27, 0x56, 0x22,
- 0x2b, 0x82, 0xd7, 0xfb, 0xb8, 0x14, 0xd9, 0xcc, 0x3a, 0xf3, 0xbb, 0x4d,
- 0x12, 0xbd, 0xfe, 0x51, 0xc7, 0xff, 0x67, 0x4e, 0xa6, 0x9e, 0xd2, 0x13,
- 0xdf, 0xfe, 0xf7, 0x72, 0x4d, 0xea, 0x06, 0x07, 0xc7, 0x54, 0x91, 0xed,
- 0xc8, 0x46, 0x89, 0x0d, 0xd2, 0x9c, 0xeb, 0xff, 0x0b, 0xb2, 0x1e, 0xc4,
- 0xf8, 0xc9, 0xd7, 0xff, 0xec, 0x4f, 0xf1, 0x69, 0xed, 0x42, 0xdf, 0x7f,
- 0x1d, 0x7f, 0xd0, 0xbf, 0x64, 0xd2, 0x4f, 0x1d, 0x52, 0x44, 0x67, 0x95,
- 0x2f, 0x80, 0xfc, 0x91, 0xd7, 0xfd, 0x0d, 0x18, 0x9f, 0xf7, 0xf1, 0xd7,
- 0xff, 0xf9, 0x3c, 0xeb, 0x71, 0xff, 0xac, 0xb8, 0xce, 0xd4, 0x9c, 0xea,
- 0x0a, 0x2e, 0x90, 0x85, 0xce, 0x2f, 0xf8, 0x1f, 0xad, 0xe5, 0xae, 0x04,
- 0xeb, 0xff, 0xfd, 0x88, 0x3e, 0xc1, 0xf8, 0x2e, 0x18, 0x19, 0xe3, 0x87,
- 0x5b, 0x3c, 0x89, 0x7d, 0x87, 0x57, 0xfd, 0xbf, 0xf9, 0xcc, 0xcf, 0x68,
- 0xea, 0x0a, 0xad, 0x0c, 0x86, 0x5f, 0x61, 0xba, 0x30, 0xc5, 0xfa, 0x55,
- 0x7f, 0xef, 0x3c, 0xb5, 0xd8, 0xe7, 0xd0, 0x9d, 0x7f, 0xf7, 0x93, 0x62,
- 0x7a, 0x69, 0x40, 0xf8, 0xeb, 0xff, 0xcf, 0x92, 0xee, 0x20, 0xe7, 0xfb,
- 0x78, 0x75, 0xe7, 0x93, 0x10, 0xbd, 0x43, 0x28, 0x4d, 0x86, 0x15, 0x59,
- 0x18, 0xc2, 0xcd, 0x35, 0x2b, 0x9f, 0xcb, 0x7f, 0x50, 0x36, 0x91, 0x6f,
- 0xff, 0x67, 0x58, 0x1c, 0x0a, 0x0f, 0xb3, 0xa7, 0x5e, 0xf4, 0x04, 0xab,
- 0xff, 0xdd, 0x74, 0xf4, 0x49, 0x39, 0x38, 0x3f, 0x2a, 0xff, 0x3b, 0x58,
- 0x0f, 0x15, 0x2c, 0x41, 0xf2, 0xe8, 0x6e, 0xcc, 0x05, 0x94, 0xb8, 0xd8,
- 0xd1, 0x97, 0x3e, 0xdb, 0xe8, 0x56, 0xec, 0x85, 0x65, 0xff, 0xe6, 0x16,
- 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x26, 0x1b, 0xff, 0xfb, 0x36, 0x38,
- 0x7b, 0x0c, 0x7b, 0xb8, 0x10, 0x7b, 0x47, 0x5f, 0xfe, 0xe3, 0xfe, 0xc2,
- 0x9e, 0x93, 0x31, 0xa9, 0x1d, 0x76, 0x30, 0x28, 0xab, 0xfa, 0xbb, 0x7f,
- 0xf2, 0xa3, 0x37, 0x90, 0x1f, 0xc3, 0x12, 0x3a, 0xfd, 0x8b, 0xf9, 0xba,
- 0xb9, 0xd7, 0xf4, 0x2f, 0x3f, 0x8d, 0x87, 0x50, 0x4f, 0x6f, 0xa5, 0xb7,
- 0xfb, 0x98, 0xd8, 0xff, 0xea, 0xce, 0xbf, 0x76, 0x02, 0x8a, 0x1d, 0x48,
- 0x7f, 0xdc, 0x22, 0xda, 0x35, 0xbf, 0xd0, 0xf3, 0xf9, 0x47, 0xe1, 0xd7,
- 0xe7, 0xe4, 0x9d, 0x67, 0x50, 0x9e, 0xc8, 0x0c, 0xef, 0xff, 0xc9, 0xce,
- 0xbf, 0xc0, 0xe4, 0xbb, 0x1b, 0x03, 0x07, 0x5f, 0xf3, 0x3f, 0x7b, 0x0d,
- 0xea, 0x4c, 0x75, 0xf0, 0x17, 0x81, 0x3a, 0xd9, 0xb9, 0xee, 0xed, 0x1e,
- 0x57, 0x51, 0xbe, 0x30, 0xb4, 0xbf, 0x97, 0x18, 0x3e, 0xdb, 0x3a, 0xda,
- 0x3a, 0xfd, 0x18, 0x3e, 0xdb, 0x3a, 0xfe, 0xea, 0x7b, 0x4f, 0xbf, 0xc3,
- 0xe6, 0x98, 0xb9, 0x62, 0x17, 0xfa, 0x5e, 0x85, 0xec, 0xfe, 0x47, 0x5f,
- 0xff, 0xe6, 0x76, 0xbd, 0x9d, 0xf8, 0x39, 0x3a, 0x60, 0xef, 0x2d, 0x1d,
- 0x7e, 0x67, 0xd9, 0xd6, 0x9d, 0x61, 0xc4, 0x47, 0x3b, 0x35, 0xff, 0xef,
- 0x0b, 0xff, 0xdc, 0x40, 0x83, 0xda, 0x3a, 0xff, 0xa2, 0x7f, 0xb2, 0xe8,
- 0x1e, 0x73, 0xaa, 0x11, 0x0b, 0xc4, 0x9b, 0xff, 0xb3, 0x79, 0x7c, 0xeb,
- 0xb6, 0x04, 0x27, 0x5f, 0xdb, 0x3e, 0xf8, 0x63, 0xf3, 0xaf, 0xff, 0x47,
- 0xbf, 0x89, 0x66, 0xfe, 0x9c, 0x0c, 0x9d, 0x50, 0x7f, 0xc8, 0x63, 0x7f,
- 0x3f, 0xfc, 0xe2, 0x70, 0xeb, 0xde, 0xf9, 0x87, 0x57, 0xe7, 0x95, 0xf4,
- 0xb6, 0xfe, 0xd2, 0x28, 0xb7, 0xf1, 0xd7, 0xff, 0xfe, 0xe6, 0x6c, 0x81,
- 0xf7, 0xcf, 0xa3, 0x1d, 0x74, 0xf4, 0x7b, 0x47, 0x5f, 0xc3, 0x9a, 0xf8,
- 0xd5, 0x51, 0xd5, 0xba, 0x33, 0x78, 0x5b, 0xb1, 0xba, 0xfb, 0xe6, 0xcd,
- 0xa9, 0xce, 0xac, 0x3d, 0xd5, 0x0c, 0xec, 0xae, 0x75, 0xde, 0xc3, 0xaf,
- 0xff, 0x2a, 0x46, 0x16, 0xe9, 0xd7, 0xf7, 0x60, 0xea, 0x83, 0xdf, 0x00,
- 0xad, 0xfe, 0xea, 0x4c, 0xed, 0xd4, 0x8e, 0xbf, 0xd0, 0x3e, 0x75, 0xa7,
- 0x8e, 0xbf, 0xec, 0x4c, 0x58, 0xe4, 0xee, 0x75, 0xfa, 0x3d, 0xaf, 0xc0,
- 0x75, 0x2b, 0x29, 0xa9, 0xe3, 0x93, 0x48, 0x7a, 0x66, 0x26, 0x1e, 0x35,
- 0xbf, 0xff, 0x74, 0x73, 0xdd, 0x4c, 0xdf, 0xd9, 0xb2, 0x34, 0x75, 0xff,
- 0xce, 0x3d, 0x84, 0x0a, 0x6b, 0x24, 0x75, 0xe8, 0xff, 0xe9, 0xd5, 0x88,
- 0xb3, 0x75, 0x51, 0x40, 0xbd, 0xf4, 0x38, 0x75, 0xe5, 0x4e, 0x95, 0x47,
- 0x53, 0x9e, 0x0e, 0x87, 0x6f, 0xf0, 0xbb, 0x31, 0xec, 0x9c, 0xeb, 0x30,
- 0xaa, 0x65, 0x6e, 0xc4, 0x64, 0x01, 0x84, 0x56, 0x46, 0x00, 0xd8, 0x46,
- 0xee, 0xab, 0x34, 0x31, 0x39, 0x0a, 0xb5, 0x91, 0x76, 0x18, 0x7f, 0xb5,
- 0x0c, 0x69, 0xfa, 0x8d, 0xd7, 0xd1, 0x87, 0x01, 0xbb, 0x6c, 0x86, 0xff,
- 0xfb, 0x89, 0xbc, 0xb4, 0x9e, 0xec, 0x73, 0xd0, 0x75, 0xfb, 0x8d, 0x77,
- 0x69, 0xa2, 0xae, 0xbd, 0xc8, 0x59, 0xd7, 0xfd, 0x26, 0x33, 0x8d, 0x77,
- 0x69, 0xa2, 0x3c, 0xbf, 0xe8, 0x94, 0x72, 0x78, 0xe4, 0xe7, 0x5f, 0xfa,
- 0x3c, 0x80, 0x54, 0xe4, 0xa7, 0x98, 0xeb, 0x30, 0x14, 0xd7, 0xb1, 0x3f,
- 0x86, 0x6e, 0x36, 0x28, 0xba, 0x39, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x58,
- 0x37, 0x94, 0x89, 0xce, 0xbf, 0xff, 0x84, 0x0f, 0x3a, 0xf3, 0x6c, 0x1c,
- 0xce, 0x4b, 0xec, 0x8e, 0xbf, 0x60, 0xe7, 0xb4, 0x75, 0xfe, 0xe3, 0xaf,
- 0xef, 0x1f, 0x73, 0xac, 0xc6, 0x26, 0x14, 0xa1, 0x9b, 0x47, 0x5d, 0x83,
- 0xe9, 0x2d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x2c, 0xab, 0xf7, 0x1a,
- 0xee, 0xd3, 0x45, 0xa7, 0x7f, 0xce, 0x1e, 0xbc, 0xdd, 0x45, 0x9d, 0x66,
- 0x30, 0xfa, 0xd6, 0x67, 0x7e, 0x56, 0x8a, 0xbd, 0x59, 0x56, 0x55, 0xb3,
- 0xaf, 0xf9, 0x55, 0xd4, 0x64, 0x2e, 0xed, 0x3a, 0xfc, 0xad, 0x15, 0x1a,
- 0xc8, 0x3a, 0xff, 0x7d, 0x5e, 0x7b, 0x49, 0xa3, 0xac, 0x87, 0x52, 0xa8,
- 0xf0, 0xf6, 0xcd, 0x2f, 0xff, 0xe4, 0xeb, 0x8f, 0xa5, 0x9c, 0xc8, 0x11,
- 0xcf, 0x1d, 0x7e, 0xd8, 0xe1, 0xc5, 0x9d, 0x7c, 0xb8, 0xdf, 0x47, 0x54,
- 0x91, 0x3f, 0x8a, 0xb3, 0x14, 0x5f, 0xbe, 0x73, 0x80, 0xe9, 0xd7, 0xe4,
- 0x52, 0x05, 0xa7, 0x5b, 0x34, 0x7a, 0x1e, 0x2a, 0xbf, 0xfe, 0x16, 0xf5,
- 0x3a, 0x9c, 0x89, 0x99, 0xce, 0x9d, 0x7f, 0xe5, 0xad, 0xe5, 0xb6, 0x0e,
- 0xa7, 0x0e, 0xbf, 0x3e, 0xbd, 0x01, 0x3a, 0xa0, 0xf9, 0xc0, 0x83, 0x50,
- 0x8d, 0x7e, 0xc2, 0xda, 0xfa, 0x3e, 0xc7, 0x4e, 0xbe, 0x6b, 0xbb, 0x4d,
- 0x16, 0xe5, 0xff, 0xb3, 0x98, 0x3f, 0x3b, 0x9b, 0xb2, 0x75, 0xf8, 0x7f,
- 0x7d, 0xf4, 0x75, 0x41, 0xf4, 0x3a, 0x05, 0x6e, 0x8d, 0x7e, 0x11, 0x6a,
- 0x12, 0xb7, 0xf9, 0xc7, 0xf9, 0x86, 0x16, 0x75, 0xe5, 0x8a, 0x1d, 0x61,
- 0x3a, 0xff, 0xba, 0x07, 0xd6, 0x60, 0xa8, 0x75, 0xfb, 0x4f, 0xbb, 0x84,
- 0xeb, 0x20, 0x4f, 0x7b, 0xc6, 0xf5, 0x08, 0xae, 0xc1, 0xae, 0xb6, 0xdf,
- 0xf4, 0x38, 0xf7, 0x30, 0x5a, 0x75, 0xfe, 0xf7, 0x92, 0x75, 0xc0, 0x9d,
- 0x52, 0x3e, 0x6c, 0x34, 0xbf, 0xe8, 0x10, 0x2e, 0x35, 0xe4, 0x3a, 0xf8,
- 0x31, 0x9c, 0x3a, 0xfd, 0xf3, 0x7d, 0x22, 0x87, 0x59, 0xe7, 0x3c, 0xbd,
- 0xc8, 0x2f, 0xfe, 0x96, 0x75, 0x38, 0x1e, 0xc0, 0xb4, 0xeb, 0xfd, 0xbc,
- 0xa0, 0x7d, 0x9f, 0x9d, 0x7d, 0xaf, 0xd3, 0xc7, 0x53, 0xa3, 0x03, 0x45,
- 0x20, 0x42, 0xfa, 0x67, 0x7f, 0xf7, 0x93, 0xf8, 0x90, 0x7b, 0x02, 0xd3,
- 0xa8, 0xeb, 0xc0, 0x7f, 0x1d, 0x70, 0x20, 0xea, 0x91, 0xb0, 0xf0, 0xdd,
- 0x1d, 0x7d, 0xbb, 0x53, 0x87, 0x5e, 0x85, 0xb1, 0x88, 0x87, 0xdc, 0xe9,
- 0x64, 0x3e, 0x0a, 0xa8, 0x4c, 0x65, 0x21, 0x95, 0x78, 0x7d, 0xb6, 0x75,
- 0xff, 0x49, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0xa1, 0xe9, 0x0f, 0x8d, 0xc7,
- 0xaf, 0xdf, 0xc3, 0x71, 0x67, 0x5f, 0x44, 0xd8, 0x13, 0xab, 0x87, 0x91,
- 0xa2, 0x7b, 0xfe, 0xc8, 0x0f, 0x63, 0x6a, 0x26, 0x3a, 0xff, 0x7e, 0x9d,
- 0xee, 0x7e, 0xe7, 0x52, 0xcf, 0xb7, 0xf3, 0xaa, 0x84, 0x59, 0x3c, 0x23,
- 0xef, 0xfc, 0xe1, 0x80, 0xf5, 0x05, 0x16, 0x75, 0xff, 0xda, 0x81, 0x9b,
- 0x07, 0xf7, 0xf6, 0x1d, 0x7f, 0xb4, 0x06, 0xe7, 0x86, 0x0e, 0xa5, 0xa2,
- 0xbb, 0xa7, 0x7e, 0x42, 0xbf, 0xf8, 0x12, 0xeb, 0xf3, 0x7f, 0x42, 0x4e,
- 0x75, 0xff, 0x44, 0xa3, 0x93, 0xc7, 0x27, 0x3a, 0xfc, 0x9e, 0xd3, 0xa1,
- 0xd7, 0xfd, 0xcf, 0xf8, 0xe3, 0xec, 0xfc, 0xea, 0xfc, 0xf7, 0x80, 0x4b,
- 0x7b, 0xef, 0x24, 0x75, 0xfd, 0xf7, 0xc0, 0x8c, 0x9c, 0xea, 0x91, 0xe6,
- 0xcc, 0x3d, 0x7f, 0xf3, 0x46, 0x3c, 0x39, 0xb3, 0x39, 0x23, 0xaf, 0xf8,
- 0x02, 0xa7, 0xde, 0xf4, 0x1a, 0x3a, 0xff, 0x08, 0xbf, 0xbe, 0xc3, 0x4e,
- 0xbe, 0x1f, 0xe7, 0xfc, 0xea, 0xc3, 0xd6, 0x43, 0x2b, 0xfd, 0xaf, 0x9e,
- 0xf8, 0x1c, 0x13, 0xad, 0xf9, 0xd6, 0x4d, 0xcf, 0x1f, 0x86, 0xd7, 0xe7,
- 0xdf, 0x5e, 0x43, 0xaa, 0x13, 0xae, 0xc2, 0x34, 0x43, 0xec, 0x24, 0x85,
- 0x9f, 0x45, 0x17, 0xe7, 0x02, 0x91, 0xf4, 0xeb, 0xf2, 0xab, 0x39, 0x1a,
- 0x3a, 0xa6, 0x3d, 0x31, 0x29, 0xbf, 0xe7, 0xd4, 0x4d, 0xbc, 0xb3, 0x61,
- 0xd7, 0xff, 0xe0, 0xf6, 0x3e, 0xb1, 0xe1, 0x7f, 0xf5, 0xa8, 0xfc, 0xab,
- 0x83, 0x87, 0x5f, 0xa7, 0x89, 0xdf, 0x47, 0x56, 0x22, 0x59, 0x16, 0x5c,
- 0x56, 0xef, 0xc0, 0x75, 0xfc, 0xff, 0xcc, 0x30, 0x13, 0xaa, 0x0f, 0x13,
- 0xa2, 0xf6, 0x61, 0x58, 0x6c, 0x1b, 0x15, 0xb4, 0x35, 0x5e, 0x78, 0xab,
- 0x39, 0xc4, 0x32, 0x25, 0x08, 0x00, 0xc3, 0xfb, 0x21, 0xfc, 0xa1, 0xb3,
- 0x61, 0xc1, 0xbc, 0x25, 0x10, 0x86, 0x68, 0xd0, 0x79, 0x1a, 0xba, 0xe1,
- 0x15, 0xd8, 0xc6, 0x9e, 0x1a, 0x9f, 0x98, 0x0a, 0x2e, 0xa1, 0x2f, 0xe9,
- 0x43, 0xc0, 0x85, 0x66, 0xc2, 0x2d, 0xb8, 0x68, 0xfd, 0x71, 0xbf, 0x98,
- 0x9e, 0x39, 0x25, 0x9d, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0xce,
- 0xa1, 0xd2, 0x14, 0x49, 0xbc, 0x31, 0x81, 0x65, 0x2c, 0x37, 0x79, 0x50,
- 0x1c, 0x8d, 0x99, 0x6a, 0x7d, 0x85, 0x50, 0xd6, 0x12, 0x9a, 0x8f, 0x17,
- 0x61, 0x7d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x29, 0x6b, 0xf7, 0x1a,
- 0xee, 0xd3, 0x45, 0x85, 0x7f, 0xfe, 0x8c, 0x10, 0xc7, 0x63, 0x7f, 0x60,
- 0xba, 0xce, 0xbf, 0x81, 0xc4, 0x9d, 0xd6, 0x75, 0x98, 0xc4, 0x58, 0xac,
- 0xcf, 0x6d, 0x46, 0xff, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x16, 0x5d, 0xdc,
- 0x50, 0xeb, 0xe6, 0x14, 0x55, 0x95, 0x83, 0xaf, 0x31, 0xf5, 0x67, 0x53,
- 0x4f, 0x34, 0x05, 0xd4, 0x28, 0x86, 0xd3, 0x25, 0xbf, 0x3a, 0xe5, 0x27,
- 0x3a, 0xe7, 0xe4, 0x8d, 0x4e, 0x08, 0xdf, 0xf3, 0xee, 0x39, 0xbf, 0xa1,
- 0x43, 0xaf, 0xf4, 0xfb, 0xea, 0x03, 0xe4, 0x3a, 0xfd, 0x19, 0xb2, 0x34,
- 0x75, 0xa1, 0xcf, 0x6d, 0x93, 0x4a, 0x74, 0x5d, 0x8c, 0x25, 0x2f, 0x9e,
- 0x52, 0x09, 0xd7, 0xf3, 0xf2, 0x3c, 0xfd, 0x3a, 0xf3, 0x2c, 0xb2, 0x55,
- 0xff, 0x44, 0xb7, 0xf7, 0x23, 0x37, 0x29, 0x82, 0xfe, 0xff, 0x80, 0xfb,
- 0xe7, 0x93, 0x76, 0x4e, 0xba, 0x34, 0x75, 0x05, 0x30, 0x3e, 0x90, 0x8a,
- 0x56, 0x92, 0x76, 0x1d, 0x5f, 0xc8, 0xfa, 0xff, 0x40, 0x3a, 0xff, 0xfe,
- 0xea, 0x7b, 0xb9, 0xa1, 0xc5, 0x83, 0x5d, 0x79, 0x1d, 0x7f, 0xa2, 0x5e,
- 0x7e, 0xb8, 0x4e, 0xac, 0x44, 0x57, 0x16, 0x6d, 0x23, 0xad, 0x23, 0xad,
- 0x23, 0xaa, 0x0d, 0x82, 0x82, 0x08, 0x21, 0x7f, 0xfe, 0xf6, 0x91, 0xb8,
- 0x3c, 0x81, 0xc0, 0xe2, 0x87, 0x5b, 0x73, 0xae, 0xd0, 0x0e, 0xac, 0x3f,
- 0x9d, 0x29, 0x78, 0x46, 0xe4, 0x83, 0xaf, 0xe1, 0x85, 0x8c, 0x61, 0xd7,
- 0x4a, 0x0e, 0xa0, 0x9e, 0x94, 0xc2, 0x80, 0x29, 0xbf, 0xff, 0xfe, 0xec,
- 0x7b, 0x49, 0xad, 0x47, 0xba, 0x91, 0xcf, 0xd6, 0xf2, 0x97, 0x94, 0x3a,
- 0xe4, 0xdc, 0xeb, 0xa1, 0x67, 0x5f, 0xff, 0xd2, 0x81, 0x04, 0xa5, 0x1e,
- 0xee, 0x2f, 0xec, 0x7e, 0x75, 0xcd, 0x62, 0x17, 0x82, 0xa7, 0x4b, 0x0c,
- 0x39, 0xb2, 0x32, 0x96, 0xa6, 0x72, 0x16, 0xee, 0xa4, 0x30, 0xa6, 0xd4,
- 0x20, 0x3c, 0x61, 0xb1, 0xfb, 0x6c, 0x5b, 0xe8, 0xad, 0xff, 0xe6, 0x16,
- 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x28, 0xcb, 0xf6, 0xc8, 0xe4, 0x7e,
- 0x75, 0xf8, 0x5f, 0xf8, 0xfa, 0x75, 0xff, 0xdb, 0xb5, 0x39, 0xdc, 0xc1,
- 0x96, 0x8e, 0xb3, 0x10, 0x89, 0x4e, 0x94, 0xf8, 0xa2, 0xa4, 0xc9, 0xf9,
- 0xe4, 0x3c, 0x16, 0x72, 0xf3, 0xd9, 0xfa, 0x87, 0x07, 0xa1, 0xd7, 0x7f,
- 0xf3, 0x0f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x39, 0xbf, 0xfc, 0xc2,
- 0xde, 0x4c, 0x67, 0x1a, 0xee, 0xd3, 0x44, 0xe5, 0x7f, 0x98, 0xce, 0x35,
- 0xdd, 0xa6, 0x8b, 0x32, 0xff, 0xa5, 0xa7, 0x5b, 0x1d, 0xf7, 0xe7, 0x5f,
- 0xf2, 0xae, 0x0e, 0x2e, 0x37, 0x85, 0x9d, 0x7f, 0xdf, 0xf2, 0x3d, 0xd7,
- 0xde, 0x47, 0x5f, 0xec, 0xd7, 0x39, 0x9b, 0xe8, 0xeb, 0xfb, 0x8d, 0xeb,
- 0xa2, 0xa4, 0xeb, 0xb7, 0x59, 0xd6, 0x61, 0x58, 0x47, 0x94, 0x1f, 0x48,
- 0xe8, 0x06, 0x7b, 0x66, 0x17, 0xf9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0xb7,
- 0x6f, 0xe1, 0x76, 0x39, 0x3f, 0x4e, 0xbc, 0x9b, 0xfe, 0x75, 0xfb, 0x8d,
- 0x77, 0x69, 0xa2, 0x90, 0xbf, 0xf6, 0x75, 0x36, 0x77, 0x30, 0x5a, 0x75,
- 0xe7, 0x93, 0x18, 0x7e, 0x1a, 0x33, 0xb3, 0x0d, 0x47, 0x77, 0x0b, 0x97,
- 0x08, 0xdb, 0xff, 0x98, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x95,
- 0x4e, 0xb8, 0x4d, 0x32, 0x8a, 0xd5, 0xdc, 0xff, 0xf8, 0xcb, 0x45, 0x63,
- 0xd1, 0x96, 0xed, 0x1e, 0x5f, 0xe9, 0x20, 0xfb, 0x10, 0x27, 0x5e, 0xd0,
- 0x16, 0x75, 0x98, 0xdc, 0xf3, 0x10, 0xc2, 0xf0, 0xbc, 0x8e, 0xbf, 0xf3,
- 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x9d, 0xae, 0x9d, 0x5c, 0xeb, 0xff,
- 0xf2, 0x04, 0x0b, 0x8d, 0xa7, 0x08, 0xc0, 0xe3, 0x4e, 0xbf, 0xe8, 0x94,
- 0x72, 0x78, 0xe4, 0xe7, 0x59, 0x8c, 0x4c, 0x2d, 0x63, 0x5d, 0x4a, 0x71,
- 0xa1, 0x54, 0xbf, 0xfe, 0x63, 0xee, 0xdb, 0x8f, 0xf9, 0xe8, 0x14, 0xfc,
- 0xeb, 0xff, 0x9d, 0x7d, 0xc6, 0xbf, 0x63, 0xec, 0x8e, 0xbc, 0x81, 0x73,
- 0xaf, 0xfe, 0x1c, 0xeb, 0xcf, 0x9a, 0x17, 0xdc, 0xeb, 0xb6, 0xd8, 0x0a,
- 0x28, 0x3a, 0x89, 0xa1, 0xaa, 0x92, 0xab, 0x75, 0xc6, 0x69, 0xa4, 0xfd,
- 0xb8, 0x7a, 0x5f, 0xff, 0xc1, 0x7f, 0x31, 0x9a, 0x81, 0xdf, 0xfd, 0x6a,
- 0x3f, 0x3a, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x16, 0x5f, 0xf9, 0xe4, 0xc6,
- 0x71, 0xae, 0xed, 0x34, 0x4b, 0xb7, 0xff, 0xf6, 0x07, 0xb1, 0xf5, 0x8f,
- 0x0b, 0xff, 0xad, 0x47, 0xe5, 0x59, 0x8c, 0x46, 0xda, 0xcc, 0xf6, 0xd2,
- 0xaf, 0xff, 0x30, 0xb7, 0x93, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x31, 0x5f,
- 0xb8, 0xd7, 0x76, 0x9a, 0x2a, 0x9b, 0x61, 0xd5, 0x87, 0x84, 0xa1, 0x9d,
- 0xff, 0xff, 0xee, 0x3f, 0x77, 0x96, 0x79, 0x8e, 0xbe, 0xb8, 0x8c, 0xfb,
- 0xa9, 0xc9, 0x1d, 0x4c, 0x22, 0x71, 0xc8, 0xaf, 0xff, 0x30, 0xb7, 0x93,
- 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x3a, 0x5f, 0xe4, 0x7e, 0x44, 0x9f, 0x61,
- 0xd7, 0xe9, 0xa2, 0x68, 0xd1, 0xd7, 0xf3, 0x38, 0x9b, 0x30, 0x4e, 0xa4,
- 0x3d, 0x5d, 0x14, 0x5e, 0x4e, 0xc1, 0xcc, 0x1a, 0x1b, 0xff, 0x81, 0xaf,
- 0x46, 0xec, 0x02, 0x64, 0x59, 0xd4, 0xb3, 0xf2, 0xe9, 0x5d, 0xff, 0x9e,
- 0x4c, 0x67, 0x1a, 0xee, 0xd3, 0x44, 0xef, 0x7e, 0xf0, 0x1d, 0x68, 0x55,
- 0xff, 0x86, 0x3d, 0x9a, 0xcc, 0xde, 0x47, 0x50, 0x53, 0xe8, 0xc8, 0xc6,
- 0x96, 0x44, 0xe9, 0x5e, 0x26, 0xbf, 0xa1, 0x8f, 0xc7, 0x02, 0x75, 0x30,
- 0x7f, 0x82, 0x9f, 0x7f, 0xf9, 0x85, 0xbc, 0x98, 0xce, 0x35, 0xdd, 0xa6,
- 0x8a, 0x16, 0xff, 0xff, 0xf7, 0x40, 0xb5, 0xbc, 0x98, 0x6f, 0x41, 0xe8,
- 0x1c, 0x9d, 0x40, 0x44, 0xc7, 0x5f, 0x81, 0xbf, 0x91, 0xa7, 0x5f, 0xb3,
- 0xfc, 0x71, 0x3a, 0xf4, 0x7e, 0xc4, 0xe7, 0x9a, 0x25, 0x14, 0x88, 0xfd,
- 0x18, 0x64, 0x5f, 0xfe, 0x61, 0x6f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2,
- 0x92, 0xbf, 0xff, 0xd9, 0xa6, 0x3e, 0xe4, 0xdd, 0x75, 0xfb, 0xb1, 0xe0,
- 0x2c, 0xea, 0x85, 0xfd, 0xb9, 0xe3, 0x38, 0x91, 0xcb, 0x63, 0x35, 0xe1,
- 0x1a, 0xe5, 0x5d, 0xfe, 0x45, 0xe8, 0xd5, 0x00, 0x4d, 0xb6, 0xaf, 0x7f,
- 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x88, 0x92, 0xff, 0xf3, 0x0b, 0x79, 0x31,
- 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0xf5, 0xf7, 0x01, 0xed, 0x1d, 0x7e, 0xe7,
- 0xeb, 0x4d, 0x1d, 0x7a, 0x07, 0x73, 0xaf, 0xde, 0xfa, 0xb1, 0x83, 0xac,
- 0x9d, 0x3c, 0x31, 0x1b, 0xbf, 0xfd, 0xdd, 0x90, 0x3f, 0xab, 0xe0, 0x73,
- 0x9b, 0x9d, 0x74, 0x78, 0xeb, 0xff, 0xc0, 0x0a, 0x73, 0xec, 0xdb, 0x40,
- 0x71, 0x98, 0xea, 0x92, 0x36, 0x90, 0x9b, 0xf4, 0xfd, 0x0a, 0xdf, 0xfc,
- 0xf3, 0x6a, 0x36, 0x3f, 0x63, 0x79, 0x8e, 0xbf, 0x64, 0xf9, 0xa5, 0x9d,
- 0x7f, 0xf4, 0xdf, 0x3e, 0x8c, 0x6c, 0x7d, 0x91, 0x31, 0xd4, 0x75, 0xfd,
- 0x34, 0x9f, 0xcf, 0xb0, 0xea, 0x84, 0x42, 0xe2, 0x63, 0x85, 0x5d, 0xc8,
- 0x3a, 0x82, 0xab, 0x65, 0x08, 0xa6, 0x8d, 0x17, 0x87, 0xa2, 0x8f, 0xb2,
- 0x15, 0x9b, 0x45, 0xb7, 0x83, 0x82, 0x75, 0xc1, 0xdc, 0xeb, 0xfe, 0x47,
- 0x10, 0x7a, 0x68, 0x50, 0xeb, 0xff, 0xe4, 0xe7, 0xce, 0xc2, 0x7b, 0x40,
- 0x68, 0x20, 0xeb, 0xe4, 0x9f, 0xf5, 0x73, 0xaf, 0x9a, 0xee, 0xd3, 0x45,
- 0x2f, 0x7c, 0x3e, 0x8e, 0x1d, 0x7f, 0xd9, 0xc5, 0x7c, 0x0e, 0x73, 0x73,
- 0xa9, 0x0f, 0x6f, 0x61, 0x05, 0x28, 0x99, 0x0c, 0xca, 0x1c, 0x26, 0xec,
- 0x22, 0x2f, 0xc3, 0xe9, 0xf1, 0x93, 0xaf, 0xfd, 0x03, 0x1d, 0xf8, 0x01,
- 0x03, 0x4e, 0xbc, 0x07, 0xd1, 0xd7, 0xe8, 0xfd, 0xf7, 0xd1, 0xd7, 0x85,
- 0x3f, 0x3a, 0xf6, 0x7b, 0x47, 0x54, 0x1b, 0x6d, 0x0d, 0xd0, 0x51, 0xaf,
- 0x31, 0xf7, 0xe3, 0x7e, 0x5e, 0xbf, 0x2b, 0xb8, 0x87, 0x68, 0xeb, 0xfe,
- 0xff, 0x5c, 0x8d, 0xe4, 0x8b, 0x3a, 0xf7, 0x9f, 0x61, 0xd7, 0xfc, 0xf3,
- 0xfc, 0x9c, 0x13, 0x42, 0xb9, 0xd5, 0x08, 0x97, 0x73, 0xa0, 0x0e, 0xdf,
- 0xf2, 0x6a, 0x64, 0x1f, 0x47, 0xe7, 0x54, 0x8f, 0x99, 0x65, 0xd7, 0x38,
- 0x9d, 0x7f, 0xd1, 0xff, 0xce, 0xc2, 0xdc, 0x4e, 0xb7, 0x37, 0x3c, 0xdd,
- 0x82, 0x95, 0x09, 0xe1, 0xe4, 0x65, 0x28, 0xdf, 0x7b, 0x90, 0xb3, 0xaf,
- 0xe8, 0x19, 0xbc, 0x8a, 0x1d, 0x7f, 0xd2, 0xce, 0x4d, 0x83, 0x0b, 0x3a,
- 0xfd, 0xfc, 0x37, 0x16, 0x75, 0x21, 0xef, 0x70, 0xde, 0xe9, 0x61, 0xd7,
- 0xa3, 0xfd, 0x1d, 0x50, 0x7a, 0x41, 0x21, 0x64, 0x56, 0xfd, 0xd0, 0x29,
- 0x82, 0x75, 0xff, 0x47, 0x74, 0xfe, 0x8e, 0x6d, 0x1d, 0x7f, 0xe5, 0xb8,
- 0x7e, 0xcd, 0x28, 0x1d, 0xce, 0xa0, 0x9f, 0xda, 0x1d, 0x5f, 0x73, 0xff,
- 0xbb, 0x0e, 0xbc, 0x8c, 0xf8, 0xea, 0xe9, 0xe1, 0xe8, 0x9e, 0x82, 0x99,
- 0x47, 0x61, 0x45, 0xe6, 0x4b, 0xfe, 0xfd, 0x3b, 0x9c, 0x79, 0xb4, 0x75,
- 0xff, 0xfa, 0x24, 0x31, 0x3f, 0xd9, 0xb5, 0xdc, 0xda, 0xe7, 0xe7, 0x5f,
- 0xdf, 0x17, 0x9e, 0x7f, 0x1d, 0x66, 0x9d, 0x76, 0xfa, 0xc3, 0x7c, 0xe5,
- 0xd5, 0xba, 0x3f, 0xd6, 0x72, 0xf0, 0x9a, 0xbf, 0xd8, 0xcc, 0x93, 0x40,
- 0x59, 0xd7, 0x6c, 0xd1, 0xd7, 0xec, 0x9f, 0x3b, 0xa3, 0xaa, 0x0d, 0xf8,
- 0x8c, 0x5e, 0xce, 0x68, 0xea, 0x69, 0xba, 0xd8, 0x3f, 0x7f, 0xdf, 0xc7,
- 0xff, 0x76, 0x40, 0xed, 0x1d, 0x50, 0x98, 0x7e, 0x42, 0xb1, 0x08, 0xef,
- 0xff, 0xfe, 0xec, 0x73, 0x76, 0xa6, 0xff, 0x14, 0x7f, 0x9a, 0xeb, 0xb6,
- 0x04, 0x27, 0x5f, 0x78, 0x51, 0x67, 0x5f, 0xe1, 0x87, 0x1f, 0x60, 0x9d,
- 0x7f, 0xba, 0xf3, 0x27, 0x22, 0x73, 0xae, 0xc5, 0x9d, 0x41, 0x4c, 0x37,
- 0x1d, 0xd6, 0x40, 0xe5, 0xdb, 0x0c, 0xef, 0xdb, 0x48, 0xb8, 0xd1, 0xd7,
- 0xe7, 0xd9, 0x9c, 0xd1, 0xd4, 0x13, 0xd1, 0x59, 0x4d, 0xfb, 0xae, 0x28,
- 0xb3, 0xaf, 0x94, 0x9b, 0x50, 0x75, 0xfe, 0x7f, 0xf5, 0x1d, 0x8d, 0x1d,
- 0x50, 0x89, 0xcc, 0x22, 0x42, 0x51, 0x23, 0xbb, 0xf6, 0x9d, 0x6d, 0x1d,
- 0x72, 0x29, 0xa3, 0x4e, 0x01, 0x7b, 0xdf, 0xbb, 0x4e, 0xbf, 0xff, 0x20,
- 0x73, 0x63, 0xf2, 0x6f, 0xb2, 0x7f, 0x3a, 0xce, 0xa8, 0x3f, 0x4e, 0x0e,
- 0x59, 0x88, 0x66, 0xed, 0xce, 0xeb, 0x21, 0xa0, 0x8b, 0xe4, 0x6b, 0x3b,
- 0xa2, 0xa4, 0x3f, 0xe6, 0x94, 0x05, 0xc3, 0x45, 0x8d, 0xf6, 0x1b, 0xaf,
- 0x1a, 0xbf, 0xf1, 0x9a, 0x8c, 0x68, 0x9a, 0x8d, 0x03, 0xd1, 0x9c, 0x6d,
- 0xb0, 0x7d, 0x85, 0x0d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x29, 0xcb,
- 0xff, 0x27, 0x1f, 0x5d, 0xcc, 0x16, 0x9d, 0x7e, 0x5f, 0x39, 0x9a, 0x3a,
- 0xff, 0xfd, 0xd0, 0x7b, 0x91, 0xed, 0x63, 0x75, 0x1c, 0x69, 0xd7, 0xf9,
- 0x16, 0x18, 0xd0, 0x04, 0xeb, 0xfb, 0x3d, 0xbc, 0xa1, 0x93, 0xaf, 0xfe,
- 0x51, 0x37, 0xd0, 0xe0, 0x7a, 0xec, 0x9d, 0x7f, 0xec, 0xec, 0x73, 0x18,
- 0x65, 0x96, 0x4a, 0xb9, 0x19, 0x3a, 0xe9, 0xd8, 0x0a, 0x76, 0x58, 0x76,
- 0xd2, 0x7e, 0xaa, 0x89, 0x8f, 0x8b, 0xb6, 0xd1, 0x76, 0x90, 0x6f, 0xdc,
- 0x6b, 0xbb, 0x4d, 0x15, 0xe5, 0xff, 0xfd, 0x81, 0xec, 0x7d, 0x63, 0xc2,
- 0xff, 0xeb, 0x51, 0xf9, 0x56, 0x63, 0x11, 0x23, 0xb6, 0x67, 0x7f, 0xf3,
- 0x0f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x47, 0xbc, 0xdc, 0x59, 0xd7,
- 0x93, 0xf8, 0x3a, 0xf3, 0x71, 0x65, 0x30, 0x5d, 0xdf, 0xb8, 0xd7, 0x76,
- 0x9a, 0x24, 0x8b, 0xff, 0xfa, 0x13, 0x89, 0xb5, 0x03, 0x3c, 0x79, 0x3a,
- 0xf3, 0x9d, 0x74, 0x98, 0x84, 0x5c, 0xe1, 0x5f, 0x4c, 0xef, 0xd9, 0xd6,
- 0x31, 0x67, 0x59, 0x88, 0x4d, 0x45, 0xe1, 0xdf, 0xe3, 0xbb, 0xff, 0x98,
- 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x55, 0xfb, 0x8d, 0x77, 0x69,
- 0xa2, 0xf1, 0xbf, 0xe9, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x6d, 0x98,
- 0xc3, 0xf8, 0x73, 0x3b, 0x99, 0xe9, 0xd7, 0xe4, 0xff, 0x58, 0x27, 0x5f,
- 0xff, 0x01, 0xf7, 0xcc, 0x51, 0x47, 0x96, 0x6f, 0xe3, 0xaa, 0x47, 0xef,
- 0xa2, 0x6b, 0xdf, 0x46, 0x73, 0xae, 0xe7, 0x8e, 0xbd, 0x30, 0xce, 0x75,
- 0x84, 0xeb, 0xbe, 0xfd, 0x3a, 0xbf, 0x35, 0x3f, 0x43, 0xee, 0xdb, 0x62,
- 0x13, 0x4e, 0xc8, 0x47, 0x74, 0x89, 0xc7, 0xb4, 0x2d, 0xf5, 0x1a, 0xa1,
- 0xba, 0x3f, 0x9c, 0xfe, 0x55, 0x88, 0x58, 0x63, 0x3c, 0x48, 0xfc, 0x66,
- 0x8c, 0x55, 0x65, 0x9d, 0x8e, 0x8b, 0xc7, 0x60, 0x86, 0x4f, 0xd8, 0xdd,
- 0x6a, 0x25, 0xfe, 0x10, 0x4f, 0x29, 0x1a, 0x53, 0xae, 0xe1, 0x9d, 0x4a,
- 0xcc, 0x46, 0xc3, 0x29, 0x38, 0xdc, 0xdb, 0xd4, 0xdd, 0xde, 0xb2, 0xe3,
- 0x4a, 0x4b, 0xea, 0xbc, 0xa2, 0x39, 0xad, 0x86, 0x3f, 0x2d, 0x09, 0x92,
- 0xf3, 0x6c, 0x87, 0xed, 0x2a, 0x31, 0xed, 0x94, 0x17, 0xf3, 0xe6, 0xaa,
- 0x98, 0xf8, 0xc6, 0xb2, 0xb6, 0xd5, 0x6e, 0x23, 0xeb, 0xd4, 0xa9, 0x05,
- 0xaf, 0xeb, 0xd9, 0x4a, 0xc8, 0x66, 0x72, 0x5f, 0x6e, 0x5c, 0x3f, 0xda,
- 0x41, 0x46, 0xd5, 0x75, 0xd5, 0x40,
+static const uint8_t kPreloadedHSTSData[] = {
+ 0xfe, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x11, 0x2a, 0xef, 0xc0, 0x72, 0xf4,
+ 0x85, 0xac, 0xe5, 0xdf, 0x78, 0xe5, 0xff, 0xf4, 0x76, 0x24, 0x2e, 0xaf,
+ 0xd2, 0x8c, 0xf1, 0xcb, 0x9f, 0x67, 0x2a, 0x47, 0xfa, 0x11, 0x84, 0x4f,
+ 0xbf, 0xd8, 0xd8, 0xc7, 0xba, 0x87, 0x2f, 0xfe, 0x03, 0x3a, 0x39, 0xf7,
+ 0x85, 0xfa, 0x72, 0xff, 0xfd, 0x21, 0x7f, 0x3b, 0x37, 0x01, 0x8e, 0xc4,
+ 0x8e, 0x56, 0xd1, 0x2e, 0xa2, 0x25, 0xd9, 0xb3, 0x97, 0x9d, 0xd6, 0x68,
+ 0x8b, 0x55, 0x23, 0xe2, 0xc2, 0x45, 0x8b, 0x5d, 0xad, 0x9c, 0xad, 0x1e,
+ 0x2e, 0xcb, 0xae, 0xf7, 0x8e, 0x5f, 0xff, 0x3f, 0x70, 0x75, 0xac, 0xfa,
+ 0x5e, 0x46, 0x1c, 0xa9, 0x1f, 0x30, 0x05, 0xee, 0x5c, 0x1c, 0xbf, 0xf0,
+ 0x1d, 0x41, 0xc9, 0xb5, 0x0d, 0x9c, 0xb8, 0x5b, 0x39, 0x58, 0x7d, 0xbd,
+ 0x16, 0x6d, 0x02, 0xff, 0xf4, 0xa3, 0x07, 0xc0, 0x70, 0xee, 0x15, 0x39,
+ 0x7f, 0x04, 0x61, 0x6c, 0x01, 0xcb, 0xfa, 0x3e, 0x0e, 0x9e, 0x47, 0x2f,
+ 0x08, 0x60, 0xe5, 0xc1, 0x09, 0xcb, 0xfe, 0x6c, 0x53, 0x68, 0x3f, 0x48,
+ 0xe5, 0xc9, 0x39, 0xcb, 0xfe, 0xf0, 0x34, 0xfb, 0x7c, 0xe9, 0xca, 0x09,
+ 0xe7, 0xa0, 0xbd, 0x62, 0x30, 0x10, 0x5d, 0xe1, 0x11, 0x7f, 0xf2, 0xf5,
+ 0x0a, 0xc0, 0xfb, 0x85, 0x70, 0xa6, 0xa4, 0xe5, 0xff, 0x76, 0x35, 0x9d,
+ 0x4f, 0x84, 0xe5, 0xfd, 0xd1, 0x03, 0xaa, 0xb3, 0x94, 0x13, 0xe6, 0x43,
+ 0x8b, 0x87, 0x67, 0x2a, 0x11, 0xe7, 0x90, 0xbc, 0x12, 0x1b, 0xfe, 0x5a,
+ 0x9e, 0x49, 0x37, 0x9d, 0x39, 0x7f, 0xe8, 0xef, 0x62, 0x5e, 0x55, 0x34,
+ 0x72, 0xcd, 0x67, 0x2f, 0xb5, 0xbc, 0x6c, 0xe5, 0xf0, 0xc7, 0xca, 0x41,
+ 0xb7, 0xc1, 0x4a, 0x9d, 0x15, 0xa2, 0xed, 0x7f, 0x96, 0x9b, 0xd6, 0xa2,
+ 0x47, 0x2f, 0xff, 0xd9, 0xfe, 0xd3, 0xe6, 0xf1, 0x70, 0x20, 0x79, 0x1c,
+ 0xbf, 0xfa, 0x30, 0x7d, 0xbf, 0x66, 0x37, 0xb3, 0x95, 0x09, 0xeb, 0xa4,
+ 0x3a, 0x3a, 0x46, 0x26, 0x7e, 0x56, 0xbb, 0x3e, 0x29, 0x68, 0x29, 0x6f,
+ 0xf4, 0x69, 0xff, 0x17, 0xbf, 0xde, 0xcd, 0x7e, 0xc4, 0xd9, 0x4e, 0x66,
+ 0xa6, 0xfe, 0x97, 0x53, 0x8e, 0x4c, 0x72, 0xa0, 0xfd, 0x9d, 0x1a, 0xfe,
+ 0xea, 0x2e, 0x18, 0x87, 0x2f, 0xf4, 0x7f, 0x3b, 0xca, 0x1a, 0xce, 0x58,
+ 0x60, 0xf8, 0xc4, 0xb2, 0xdc, 0xda, 0x96, 0x50, 0x07, 0x0b, 0x0c, 0x44,
+ 0x27, 0x27, 0x2e, 0xc8, 0xdc, 0x15, 0x84, 0x42, 0xe1, 0x1f, 0xf1, 0x7a,
+ 0x24, 0xcc, 0x5b, 0xa2, 0xee, 0xc3, 0x6c, 0x63, 0x25, 0xdc, 0xa0, 0x96,
+ 0x91, 0x89, 0xa9, 0x08, 0x3b, 0xff, 0xff, 0x9d, 0x9c, 0xd3, 0x5a, 0x06,
+ 0xb5, 0x03, 0x8a, 0xa7, 0x7b, 0x8a, 0x1c, 0xbf, 0xfd, 0xc2, 0x95, 0x6d,
+ 0xae, 0x70, 0xf0, 0xdc, 0xb9, 0x75, 0xa1, 0xcb, 0xe5, 0xbb, 0xac, 0xd1,
+ 0x51, 0x2f, 0xce, 0x32, 0x46, 0x1c, 0xad, 0x1e, 0xa3, 0x0b, 0xaf, 0xbb,
+ 0x9a, 0xc3, 0x97, 0x92, 0x6e, 0x03, 0x95, 0x07, 0x83, 0xd2, 0x1b, 0xf2,
+ 0xdf, 0xb1, 0xd3, 0x97, 0xff, 0xf0, 0x05, 0xd5, 0xe5, 0xe5, 0x60, 0x65,
+ 0x9d, 0x46, 0x1c, 0xbf, 0xff, 0x7f, 0x29, 0xf8, 0x54, 0x35, 0x73, 0xaf,
+ 0x5c, 0xb9, 0x75, 0xa1, 0xcb, 0xff, 0xf8, 0x02, 0xea, 0xf2, 0xf2, 0xb0,
+ 0x32, 0xce, 0xa3, 0x0e, 0x5f, 0x6b, 0x58, 0xd0, 0xe5, 0x31, 0x10, 0x2e,
+ 0xbb, 0x7f, 0xfe, 0x79, 0x0c, 0x6f, 0x3e, 0x58, 0xbe, 0x7c, 0xb3, 0x96,
+ 0xe7, 0x25, 0x64, 0x79, 0x0b, 0x85, 0xb1, 0xa1, 0x0b, 0x09, 0xfa, 0xbb,
+ 0xb8, 0x76, 0xf1, 0x22, 0xbf, 0xf0, 0x71, 0x9c, 0xda, 0x60, 0xa7, 0x8e,
+ 0x5e, 0xc6, 0xf0, 0xe5, 0xe0, 0x44, 0xe7, 0x2f, 0xec, 0x9c, 0x31, 0x81,
+ 0x39, 0x7c, 0x1e, 0xa4, 0xc7, 0x2b, 0x0f, 0x41, 0xcb, 0x6f, 0x36, 0xfd,
+ 0x39, 0x74, 0x04, 0xe5, 0x41, 0xb3, 0xe8, 0xed, 0xfe, 0x88, 0x41, 0x10,
+ 0x35, 0x9c, 0xb9, 0xc0, 0x72, 0xfe, 0x79, 0xf4, 0xef, 0xe3, 0x97, 0xdd,
+ 0x4e, 0xf3, 0xe1, 0x13, 0x72, 0x08, 0xe2, 0xad, 0xb3, 0x29, 0xf4, 0x81,
+ 0xb3, 0x36, 0x82, 0xd7, 0xed, 0x2d, 0xdd, 0x66, 0x8a, 0xf5, 0x7e, 0x4e,
+ 0x05, 0x82, 0x73, 0x97, 0x44, 0x8e, 0x5d, 0x1f, 0x9c, 0xbf, 0xa7, 0x51,
+ 0xa3, 0x8f, 0xe7, 0x2f, 0xfc, 0xe3, 0xfe, 0x7a, 0x05, 0x3f, 0x39, 0x50,
+ 0x7d, 0xed, 0x0c, 0xad, 0xcf, 0x13, 0x1f, 0xd1, 0xa3, 0x96, 0x7e, 0x2c,
+ 0xa4, 0x21, 0xaf, 0xfe, 0xe6, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x12,
+ 0x32, 0xff, 0xf7, 0x36, 0x3c, 0xb9, 0xe6, 0x96, 0xee, 0xb3, 0x44, 0xf0,
+ 0xbf, 0xfd, 0xcd, 0x8f, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x3f, 0xaf,
+ 0xff, 0x73, 0x63, 0xcb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x50, 0xcb, 0xff,
+ 0x98, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x14, 0x42, 0xff, 0xd2, 0xe6,
+ 0x0d, 0xf2, 0x8d, 0xc4, 0x8e, 0x57, 0x34, 0x4a, 0xc2, 0x95, 0xff, 0xa6,
+ 0x4e, 0xfd, 0x9e, 0x0e, 0x30, 0xe5, 0xf6, 0x7b, 0x3f, 0x39, 0x7e, 0x10,
+ 0x3c, 0xb6, 0x72, 0xf0, 0xbf, 0x31, 0x3c, 0x9f, 0x11, 0x5f, 0xb4, 0xb7,
+ 0x75, 0x9a, 0x29, 0x15, 0xff, 0xdd, 0xe2, 0xfa, 0xdb, 0xf7, 0x71, 0x39,
+ 0xcb, 0xff, 0x9f, 0xed, 0xf5, 0xb8, 0xff, 0x92, 0x8c, 0x39, 0x7f, 0xd1,
+ 0x28, 0xd4, 0xf1, 0xa9, 0xce, 0x5e, 0x79, 0x73, 0xc4, 0xc0, 0x1c, 0xd3,
+ 0xf4, 0x71, 0x4b, 0xbf, 0xff, 0xb8, 0xf3, 0x51, 0x79, 0xe8, 0x1f, 0x6d,
+ 0xc4, 0x18, 0x72, 0xff, 0xf4, 0xb9, 0xe9, 0xff, 0x7f, 0x26, 0xb1, 0x87,
+ 0x2f, 0xfd, 0xff, 0x3d, 0x83, 0x5f, 0xf2, 0x0c, 0xc7, 0x2f, 0xe9, 0x67,
+ 0x7a, 0xf2, 0x39, 0x7f, 0xff, 0x60, 0x7b, 0x0a, 0x73, 0xf0, 0xbf, 0xfb,
+ 0xdc, 0x7e, 0x52, 0xdc, 0xe1, 0x5c, 0x4a, 0xe1, 0x12, 0xc8, 0xcc, 0xfa,
+ 0x9e, 0xeb, 0xdf, 0xa6, 0x79, 0x21, 0xa1, 0x6d, 0xff, 0xf7, 0x63, 0xa8,
+ 0xae, 0xf7, 0x83, 0xfb, 0x4c, 0x39, 0x7c, 0xb7, 0x75, 0x9a, 0x25, 0x05,
+ 0xff, 0xa3, 0xf6, 0x3c, 0xbb, 0x0f, 0xa3, 0x95, 0x24, 0x5f, 0x69, 0x48,
+ 0x4b, 0xaf, 0xff, 0x0b, 0xfb, 0x6a, 0x08, 0x24, 0x38, 0xc3, 0x97, 0xdb,
+ 0x70, 0xe1, 0xcb, 0xff, 0xcf, 0x3a, 0x6b, 0x49, 0xf4, 0xbc, 0xff, 0x1c,
+ 0xbe, 0xe6, 0xf2, 0xe7, 0x88, 0xe5, 0x61, 0x7e, 0xd2, 0x5a, 0x10, 0xd4,
+ 0xed, 0xda, 0xe4, 0xa9, 0x48, 0x21, 0x8c, 0x99, 0x72, 0xe5, 0xd2, 0x10,
+ 0xad, 0x71, 0xd9, 0xea, 0x3a, 0x76, 0x2c, 0x75, 0x53, 0xf5, 0xae, 0x1d,
+ 0x6b, 0x70, 0xef, 0x04, 0xba, 0xde, 0x09, 0x45, 0x57, 0xff, 0xb9, 0xb1,
+ 0xe5, 0xcf, 0x34, 0xb7, 0x75, 0x9a, 0x27, 0x35, 0xff, 0xee, 0x6c, 0x79,
+ 0x73, 0xcd, 0x2d, 0xdd, 0x66, 0x8a, 0x25, 0x7f, 0xc0, 0x7d, 0x49, 0xa8,
+ 0xf1, 0xfd, 0x0e, 0x5f, 0x20, 0xc3, 0x0e, 0x5f, 0xc9, 0xb9, 0xa4, 0x9f,
+ 0x9c, 0xbf, 0xd1, 0x3a, 0x8d, 0x1c, 0x7f, 0x39, 0x74, 0xb9, 0x85, 0x19,
+ 0x18, 0x85, 0xd2, 0x05, 0x0b, 0xef, 0xff, 0x73, 0xd8, 0xe7, 0xf1, 0xfe,
+ 0xb5, 0x0d, 0x9c, 0xad, 0x22, 0x67, 0xf4, 0xba, 0xd2, 0xa3, 0x9d, 0xad,
+ 0x02, 0x3b, 0xbb, 0xf6, 0x96, 0xee, 0xb3, 0x44, 0x38, 0xbf, 0x80, 0xbd,
+ 0x24, 0x09, 0xcb, 0x73, 0xc3, 0xe0, 0xe9, 0xa5, 0xff, 0x46, 0xb1, 0x7d,
+ 0x8f, 0xa4, 0x72, 0xff, 0xe1, 0x75, 0x57, 0xd4, 0xd6, 0xa1, 0xb3, 0x97,
+ 0xcb, 0x77, 0x59, 0xa2, 0x2f, 0x5f, 0x85, 0xff, 0x7d, 0x9c, 0xbf, 0x64,
+ 0xd2, 0x7d, 0x9c, 0xad, 0x1f, 0xef, 0x8b, 0x94, 0x27, 0xbf, 0xb0, 0x3d,
+ 0xcf, 0xdc, 0xe5, 0xf4, 0x03, 0x87, 0xd9, 0xca, 0xd9, 0xea, 0x36, 0x5b,
+ 0x70, 0xce, 0x72, 0xff, 0xbc, 0x30, 0xc5, 0x03, 0xd8, 0x39, 0x50, 0x7a,
+ 0x08, 0x2f, 0x76, 0xfe, 0x39, 0x7d, 0xe9, 0x42, 0xa5, 0x29, 0x86, 0xed,
+ 0xc6, 0x2f, 0xcf, 0xf0, 0x1f, 0xc7, 0x2f, 0xcf, 0x3f, 0xb3, 0xa7, 0x2d,
+ 0xce, 0x75, 0x57, 0xa1, 0x39, 0xc8, 0x61, 0x4d, 0x08, 0x4e, 0xb9, 0x8a,
+ 0xd8, 0x08, 0x1a, 0x14, 0x5f, 0xff, 0xff, 0x0b, 0xf3, 0xc0, 0x70, 0xe8,
+ 0xaa, 0x7b, 0xb8, 0x92, 0xdf, 0x2c, 0x56, 0x24, 0x72, 0xfd, 0x9b, 0x60,
+ 0x60, 0xe5, 0xff, 0x9e, 0x5c, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0x64, 0x5b,
+ 0x9a, 0xd1, 0xf1, 0xa8, 0x42, 0xb0, 0x9e, 0xf7, 0xb1, 0x87, 0x2e, 0xeb,
+ 0x0e, 0x5f, 0xb4, 0xb7, 0x75, 0x9a, 0x2d, 0xe5, 0xb9, 0xc1, 0xf3, 0x84,
+ 0x73, 0x05, 0xef, 0xff, 0x73, 0x63, 0xcb, 0x9e, 0x69, 0x6e, 0xeb, 0x34,
+ 0x52, 0x6b, 0x9a, 0xa6, 0xac, 0xe5, 0xfd, 0x9e, 0x18, 0x86, 0x1c, 0xbf,
+ 0xbe, 0xfd, 0x4d, 0x3f, 0xe7, 0x2e, 0xef, 0x3e, 0x10, 0xff, 0xba, 0x42,
+ 0xe5, 0x75, 0x0b, 0xca, 0xf2, 0x95, 0xcd, 0x91, 0xbf, 0xee, 0x14, 0x9c,
+ 0x4d, 0x54, 0x86, 0xc5, 0xfe, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x10, 0xea,
+ 0xfd, 0xa5, 0xbb, 0xac, 0xd1, 0x2c, 0x2f, 0xb3, 0xf6, 0x21, 0xcb, 0xf7,
+ 0x36, 0x3c, 0xb9, 0xe1, 0xeb, 0x34, 0x34, 0xbf, 0xdc, 0xf3, 0x4b, 0x77,
+ 0x59, 0xa2, 0x30, 0x5f, 0xee, 0x60, 0x96, 0x6d, 0xf6, 0x72, 0xff, 0xfc,
+ 0xff, 0xb4, 0xce, 0x62, 0xfe, 0x96, 0x7b, 0x02, 0x72, 0x85, 0x11, 0xbb,
+ 0x35, 0xbe, 0xe7, 0x2c, 0xd9, 0xcb, 0xff, 0xfe, 0x96, 0xf9, 0xaf, 0xaf,
+ 0x32, 0xfb, 0x9a, 0x6a, 0x7b, 0x33, 0x36, 0x72, 0xfd, 0x9e, 0xfe, 0x16,
+ 0x72, 0xff, 0xf4, 0x79, 0x3f, 0x89, 0x07, 0xb0, 0x2b, 0x39, 0x7e, 0xd2,
+ 0xdd, 0xd6, 0x68, 0x8f, 0x57, 0xdb, 0x7f, 0xb8, 0x9c, 0xba, 0x5c, 0xf0,
+ 0xf6, 0x7c, 0x69, 0x7f, 0xff, 0x3f, 0x31, 0x06, 0x77, 0x07, 0xfc, 0x1f,
+ 0x77, 0x0e, 0x5b, 0x9f, 0xc9, 0xe2, 0xcc, 0xe5, 0xa2, 0x87, 0x85, 0x10,
+ 0x97, 0xdf, 0xb4, 0xb7, 0x75, 0x9a, 0x2c, 0x35, 0xfe, 0x90, 0xc6, 0x6f,
+ 0x04, 0xe5, 0xc9, 0x23, 0x96, 0xe7, 0x87, 0xf5, 0xf1, 0xa7, 0xe6, 0x17,
+ 0xf7, 0x86, 0x3f, 0x93, 0x0e, 0x5f, 0xff, 0xf4, 0x46, 0xf9, 0xf8, 0x28,
+ 0xcf, 0xa5, 0xbf, 0xa5, 0x9a, 0x9c, 0xe5, 0xd1, 0xae, 0x68, 0x9a, 0x12,
+ 0xeb, 0xfd, 0xcf, 0x34, 0xb7, 0x75, 0x9a, 0x2e, 0x75, 0xff, 0xff, 0xff,
+ 0xd1, 0xc2, 0xf2, 0x9d, 0x7d, 0xe5, 0xcb, 0xad, 0x39, 0xce, 0x05, 0x78,
+ 0x5a, 0x38, 0x4f, 0xa7, 0x9d, 0x6c, 0xe5, 0xcb, 0xad, 0x0e, 0x54, 0x2f,
+ 0x4a, 0x4f, 0x09, 0x79, 0x22, 0x64, 0x33, 0x96, 0x44, 0x91, 0xf4, 0xb2,
+ 0x1a, 0x5d, 0x86, 0x97, 0x8b, 0xf8, 0x10, 0x6f, 0xf7, 0x3c, 0xd2, 0xdd,
+ 0xd6, 0x68, 0x87, 0x97, 0xcb, 0x77, 0x59, 0xa2, 0x26, 0x5f, 0xd9, 0xc0,
+ 0x06, 0x60, 0x4e, 0x58, 0x07, 0x2f, 0xf7, 0x80, 0xff, 0x76, 0x38, 0x9c,
+ 0xad, 0x22, 0x94, 0x4b, 0xb6, 0x61, 0xe1, 0x1b, 0xf7, 0xfb, 0xe5, 0x81,
+ 0x39, 0x7f, 0x91, 0xbc, 0x1c, 0xfb, 0xc7, 0x29, 0x0f, 0x7b, 0x45, 0x77,
+ 0xff, 0xe8, 0xd7, 0xfd, 0x8e, 0x33, 0x44, 0x33, 0x78, 0x13, 0x97, 0xfd,
+ 0xde, 0xc7, 0x19, 0x66, 0xa0, 0xe5, 0xbd, 0xd4, 0x49, 0x3a, 0xc5, 0xff,
+ 0x27, 0x93, 0xd9, 0xfc, 0x68, 0xe5, 0xf4, 0xfd, 0x04, 0xe7, 0x2b, 0x11,
+ 0x0a, 0xe5, 0x00, 0x38, 0xbd, 0x81, 0xe9, 0xcb, 0xff, 0xfb, 0xdd, 0x8d,
+ 0x7f, 0xbc, 0x0f, 0x80, 0xeb, 0xcd, 0x1c, 0xbb, 0xcc, 0x39, 0x7f, 0xfb,
+ 0x3a, 0xa4, 0xfb, 0x84, 0xfb, 0xd0, 0xc3, 0x97, 0xfd, 0x12, 0x53, 0x35,
+ 0xbc, 0x6c, 0xe5, 0xfe, 0x94, 0x2a, 0x9d, 0x79, 0xce, 0x54, 0xe7, 0xdc,
+ 0x87, 0x55, 0x89, 0xa7, 0xfc, 0xb9, 0xd1, 0x70, 0x42, 0xea, 0xff, 0x83,
+ 0x9c, 0x74, 0xfc, 0x7a, 0x87, 0x2f, 0xcd, 0x82, 0x35, 0x39, 0xcb, 0x27,
+ 0x23, 0xe6, 0x6c, 0xf2, 0xfa, 0x5d, 0x53, 0x67, 0x2e, 0x75, 0x0d, 0x10,
+ 0xba, 0xde, 0xf8, 0xf2, 0x00, 0x49, 0x7e, 0xee, 0x4e, 0x01, 0x39, 0x7c,
+ 0xfa, 0x8e, 0x27, 0x28, 0x27, 0x97, 0xf9, 0x45, 0xfa, 0x69, 0x63, 0x89,
+ 0xcb, 0x73, 0xc5, 0xd4, 0x4d, 0x42, 0x6b, 0xb1, 0x9c, 0x09, 0x76, 0xe3,
+ 0x6b, 0xf4, 0x2a, 0x40, 0xe5, 0xc5, 0xd1, 0xa1, 0x1d, 0xff, 0xb4, 0x09,
+ 0xf3, 0xb3, 0x0c, 0x04, 0xe5, 0xff, 0xfe, 0x74, 0xf0, 0x34, 0xfb, 0xc1,
+ 0xee, 0x60, 0xcb, 0x67, 0x2e, 0xeb, 0x9c, 0xb0, 0x0e, 0x56, 0x1a, 0x7d,
+ 0x8b, 0x5e, 0xff, 0x7c, 0xe1, 0x1c, 0x9d, 0x40, 0xf4, 0x21, 0x2f, 0xff,
+ 0xb1, 0x25, 0xbe, 0x79, 0xf4, 0x9e, 0x75, 0x16, 0x72, 0xa1, 0x13, 0xbd,
+ 0x49, 0xbf, 0xe6, 0xab, 0x84, 0xd6, 0x79, 0x3a, 0x03, 0x97, 0xdb, 0x49,
+ 0xf8, 0x43, 0x94, 0xd5, 0x1f, 0x5b, 0x52, 0x87, 0x7f, 0xe6, 0xab, 0x84,
+ 0x49, 0xe3, 0x92, 0xf7, 0x87, 0x2e, 0xe1, 0x42, 0x72, 0x9a, 0xa3, 0xe7,
+ 0x6a, 0x52, 0xef, 0xfb, 0x3c, 0xa4, 0xef, 0xa4, 0x98, 0xe5, 0xfd, 0x2e,
+ 0x15, 0x3f, 0x09, 0xc2, 0xcd, 0x44, 0xe5, 0x70, 0x88, 0x83, 0x6a, 0xce,
+ 0xef, 0xe6, 0xa9, 0x4e, 0xf7, 0x27, 0x39, 0x6e, 0x9c, 0xa6, 0xa8, 0xf1,
+ 0x80, 0x6b, 0x7c, 0x1c, 0x19, 0x8e, 0x5c, 0x9e, 0x39, 0x6f, 0x21, 0xb8,
+ 0xe9, 0x15, 0xfe, 0xfb, 0xdf, 0x48, 0x02, 0xa9, 0xcb, 0xff, 0x44, 0xc3,
+ 0x9c, 0x5d, 0x8c, 0x43, 0x94, 0xe7, 0xec, 0x03, 0x7b, 0xff, 0xff, 0xba,
+ 0x00, 0xa6, 0x6a, 0x61, 0xce, 0x3d, 0xc0, 0xc6, 0xf7, 0x0a, 0x9c, 0xbf,
+ 0xfc, 0x93, 0x4b, 0x3e, 0x97, 0x26, 0x3b, 0x89, 0xcb, 0x9f, 0x80, 0xe5,
+ 0xff, 0xfe, 0xde, 0x7b, 0x97, 0x71, 0x70, 0xd8, 0xe0, 0x7a, 0x93, 0x1c,
+ 0xb7, 0x09, 0x89, 0xfc, 0xab, 0x09, 0xc5, 0x90, 0xf5, 0xd1, 0xd3, 0x3c,
+ 0x33, 0x73, 0x45, 0x4e, 0x5f, 0x3c, 0xa3, 0xf3, 0x97, 0xee, 0xbf, 0x9e,
+ 0x47, 0x2f, 0xe4, 0xd0, 0xe6, 0x68, 0xe5, 0xe5, 0xcf, 0xd3, 0x97, 0xf6,
+ 0xe3, 0x6d, 0x41, 0xaa, 0x6a, 0x8e, 0x5f, 0xa3, 0x60, 0xea, 0x1c, 0xae,
+ 0x48, 0x83, 0x90, 0xf6, 0xcf, 0xaf, 0xfe, 0x67, 0x2d, 0x8e, 0x7d, 0x21,
+ 0x79, 0xce, 0x5e, 0xda, 0x7e, 0x72, 0xb0, 0xf9, 0x11, 0x1e, 0xf3, 0x6d,
+ 0xb6, 0x52, 0xfc, 0xe3, 0xee, 0xe1, 0x4e, 0x66, 0x82, 0xff, 0xff, 0xe8,
+ 0x9f, 0x96, 0xc1, 0x1f, 0x7b, 0xb8, 0xcc, 0xf0, 0xc7, 0xff, 0xc1, 0xcb,
+ 0xef, 0x4d, 0x9e, 0x39, 0x41, 0x44, 0xcb, 0xbb, 0x50, 0x53, 0x33, 0xfd,
+ 0x00, 0x61, 0xa3, 0x7e, 0xe8, 0xb5, 0x16, 0x9c, 0x07, 0x2e, 0x77, 0x39,
+ 0x6e, 0xa1, 0xe4, 0x39, 0x9d, 0xff, 0xfd, 0xfe, 0xa3, 0x96, 0xa3, 0xdf,
+ 0x4a, 0x15, 0xd3, 0xb6, 0x72, 0xff, 0xc9, 0x37, 0x2e, 0xc2, 0x68, 0x0d,
+ 0x67, 0x2a, 0x11, 0x4b, 0xfb, 0x0d, 0xfd, 0xa4, 0xe0, 0xd6, 0xf6, 0x72,
+ 0xfe, 0x10, 0x79, 0x27, 0x83, 0x97, 0xfe, 0x45, 0x60, 0x63, 0x70, 0x8c,
+ 0x39, 0x7e, 0xe2, 0x09, 0x66, 0xce, 0x5f, 0x7e, 0x82, 0x03, 0x95, 0x87,
+ 0x98, 0x02, 0xab, 0xec, 0x0e, 0x4e, 0x72, 0xf9, 0xaf, 0x94, 0x35, 0x27,
+ 0x2e, 0xd4, 0x1c, 0xa0, 0xae, 0xcb, 0xe1, 0x12, 0xc9, 0xfe, 0x85, 0x72,
+ 0x47, 0x92, 0xd6, 0xfd, 0x34, 0x32, 0xf4, 0x46, 0xc3, 0x1e, 0x96, 0x8c,
+ 0x22, 0x3c, 0x43, 0xc4, 0x8b, 0x80, 0xb2, 0xfc, 0xdc, 0x60, 0x50, 0xe5,
+ 0xe0, 0x7b, 0x67, 0x2f, 0xff, 0xff, 0xfb, 0x7c, 0xbb, 0x93, 0xc3, 0x7f,
+ 0x4b, 0x7c, 0x80, 0xbd, 0x6a, 0x39, 0x4c, 0xaf, 0xdc, 0xb9, 0x75, 0xa1,
+ 0xcb, 0xfb, 0xee, 0x53, 0x66, 0x2c, 0xe5, 0x62, 0x63, 0xeb, 0x27, 0xf0,
+ 0xe8, 0x21, 0x55, 0x70, 0x3f, 0x39, 0x73, 0x46, 0xa8, 0xe5, 0xee, 0x52,
+ 0x59, 0xca, 0x83, 0xd5, 0x54, 0x61, 0x83, 0xd7, 0xff, 0xf6, 0xb9, 0x0e,
+ 0x71, 0xcd, 0x4b, 0x94, 0x05, 0xe6, 0xd9, 0xcb, 0xff, 0xff, 0x87, 0xe8,
+ 0x54, 0x70, 0x3d, 0x49, 0xb9, 0x6f, 0x3e, 0x96, 0xb1, 0xb3, 0x95, 0x88,
+ 0xd8, 0x16, 0x1b, 0xef, 0x02, 0x27, 0x39, 0x7f, 0x49, 0xf5, 0xb4, 0x09,
+ 0xcb, 0xfb, 0x3b, 0x8c, 0x85, 0x9c, 0xa8, 0x3d, 0x99, 0x16, 0xd2, 0x22,
+ 0x77, 0xcf, 0x97, 0xff, 0xf7, 0xd2, 0xdb, 0x30, 0x79, 0x70, 0x27, 0x67,
+ 0x4c, 0xd1, 0xcb, 0x35, 0x9c, 0xac, 0x3f, 0x55, 0xb0, 0xdf, 0xff, 0xf9,
+ 0xbe, 0x43, 0x8b, 0xea, 0x0e, 0x03, 0xef, 0x72, 0x76, 0xf1, 0x53, 0x97,
+ 0xf9, 0x50, 0x82, 0x3a, 0x30, 0x72, 0xff, 0x7d, 0x2d, 0xaa, 0x08, 0xf8,
+ 0xe5, 0xfe, 0x76, 0xc1, 0x34, 0x79, 0xce, 0x5e, 0xe3, 0xe5, 0x0e, 0x54,
+ 0x26, 0x61, 0x8e, 0x48, 0x66, 0x26, 0xed, 0x9a, 0x5f, 0xff, 0x87, 0x03,
+ 0xd0, 0x37, 0xb4, 0xf7, 0x51, 0xff, 0x39, 0x7f, 0x87, 0x38, 0xf2, 0x93,
+ 0x24, 0x72, 0xb4, 0x88, 0xdd, 0xab, 0x5d, 0xbe, 0x27, 0x2a, 0x0d, 0xe0,
+ 0x08, 0xef, 0xbf, 0xf2, 0x4e, 0x72, 0xff, 0x7b, 0xa8, 0x3f, 0xa8, 0xc3,
+ 0x97, 0xff, 0xf7, 0x53, 0x07, 0x10, 0x39, 0x1f, 0xba, 0xdf, 0x47, 0x2f,
+ 0xf4, 0xf0, 0xc1, 0x8f, 0xbf, 0x39, 0x52, 0x46, 0x0f, 0xc6, 0xae, 0xaf,
+ 0x7e, 0xef, 0x27, 0xcd, 0x9c, 0xa8, 0x3d, 0x9c, 0x30, 0xbf, 0xf9, 0xf5,
+ 0x2e, 0x5e, 0x18, 0x96, 0x78, 0xe5, 0x42, 0xeb, 0xd6, 0x42, 0xf9, 0x21,
+ 0x2f, 0xa8, 0xd4, 0x7b, 0x18, 0x8b, 0x90, 0x0c, 0x67, 0xc0, 0x20, 0xb3,
+ 0x59, 0xcb, 0xff, 0xed, 0x20, 0x38, 0x78, 0xe5, 0xb0, 0x7e, 0xcc, 0xf1,
+ 0xcb, 0xff, 0x42, 0xf7, 0x09, 0xf7, 0xa1, 0x87, 0x2d, 0x23, 0x94, 0x27,
+ 0x9e, 0x03, 0xeb, 0xef, 0xf7, 0x3f, 0x8e, 0x5f, 0xf9, 0xd5, 0xe5, 0xe7,
+ 0x71, 0xe5, 0x39, 0xca, 0x83, 0xe8, 0x12, 0x5b, 0xcf, 0xed, 0x9c, 0xb8,
+ 0x13, 0x9c, 0xa9, 0x1b, 0x4d, 0x0e, 0x5f, 0xb2, 0x5d, 0x79, 0x1c, 0xb8,
+ 0x7d, 0x31, 0xe4, 0x74, 0x86, 0xff, 0x38, 0xa9, 0xde, 0xc0, 0x4e, 0x5f,
+ 0xc0, 0x5f, 0x20, 0xfc, 0xd9, 0xcb, 0xfe, 0x86, 0xfb, 0x83, 0xf4, 0x2a,
+ 0x72, 0xed, 0x48, 0xe5, 0x42, 0x39, 0x7e, 0x2e, 0x43, 0x3d, 0x19, 0xb0,
+ 0xea, 0xff, 0x6a, 0x03, 0x1d, 0x89, 0x1c, 0xbf, 0xfe, 0x8f, 0x72, 0x10,
+ 0x70, 0x72, 0xcf, 0x34, 0xcf, 0x1c, 0xa4, 0x44, 0x50, 0x0c, 0xaf, 0xfe,
+ 0xec, 0x2b, 0xcb, 0xc2, 0xfe, 0x8f, 0x1c, 0xbf, 0xdc, 0xbe, 0x92, 0x74,
+ 0x0c, 0x39, 0x5f, 0x9f, 0xe8, 0xa3, 0x5f, 0xfd, 0x9c, 0x70, 0x3c, 0xbc,
+ 0xaa, 0x37, 0xb3, 0x97, 0xfe, 0xd4, 0xdc, 0xb7, 0x09, 0x3b, 0xf8, 0xe5,
+ 0x42, 0x2b, 0x82, 0x44, 0x04, 0xab, 0x9f, 0xf3, 0x97, 0xff, 0xdc, 0x86,
+ 0x37, 0x13, 0x8e, 0x07, 0xa9, 0x31, 0xcb, 0xff, 0xff, 0xb7, 0xa1, 0x89,
+ 0xb9, 0x29, 0xe4, 0x96, 0x7d, 0xec, 0xe2, 0x39, 0xb3, 0x95, 0xa4, 0x64,
+ 0x0a, 0x8d, 0x79, 0x30, 0x10, 0x43, 0x7e, 0x8e, 0x5e, 0xf7, 0x25, 0x4e,
+ 0x5d, 0x34, 0x8e, 0x54, 0x1e, 0x1f, 0xc1, 0x7a, 0x20, 0xbf, 0xf8, 0x7d,
+ 0xbe, 0x29, 0xe8, 0xc1, 0x98, 0xe5, 0xfb, 0x49, 0xb8, 0xf8, 0xe5, 0x61,
+ 0xf6, 0xba, 0x2d, 0xfe, 0x9f, 0x84, 0x9a, 0x49, 0xed, 0x9c, 0xbf, 0x0f,
+ 0xbb, 0x9c, 0x07, 0x2f, 0xd3, 0x6d, 0xf4, 0xa9, 0xcb, 0xce, 0xde, 0xa0,
+ 0xf5, 0x30, 0xaa, 0xa4, 0x8e, 0x14, 0x20, 0xd4, 0x23, 0xef, 0xfb, 0xa9,
+ 0xa9, 0xba, 0xf9, 0xa3, 0x97, 0xff, 0xff, 0xf7, 0xfb, 0x1c, 0x7f, 0xb9,
+ 0x07, 0xa0, 0xe4, 0x39, 0xf4, 0xb0, 0x13, 0x8e, 0x3f, 0xc7, 0x29, 0x68,
+ 0xc8, 0x43, 0x9b, 0xce, 0xeb, 0x34, 0x53, 0x0a, 0xc3, 0xca, 0x59, 0x15,
+ 0xff, 0xb0, 0x7e, 0x96, 0xfd, 0x1a, 0x98, 0xe5, 0xff, 0x9f, 0xec, 0x4d,
+ 0x23, 0x21, 0x53, 0x97, 0xb1, 0x3f, 0x39, 0x6c, 0x39, 0x7b, 0xe1, 0xcf,
+ 0xcd, 0x67, 0x11, 0xca, 0x44, 0x6f, 0xe9, 0x01, 0xda, 0xaf, 0x60, 0x34,
+ 0x72, 0xe9, 0xe6, 0x39, 0x66, 0xce, 0x5c, 0x81, 0x39, 0x4d, 0x66, 0xa3,
+ 0x62, 0x57, 0x06, 0x63, 0x97, 0xfd, 0xac, 0x0f, 0x61, 0xb6, 0x00, 0xe5,
+ 0xca, 0xce, 0x72, 0xa1, 0x1a, 0x18, 0x82, 0xc2, 0x4e, 0x8c, 0x36, 0x75,
+ 0x73, 0x3f, 0x39, 0x7b, 0x5d, 0x7e, 0x47, 0xc3, 0xfa, 0x4d, 0xfe, 0xe5,
+ 0xf4, 0x86, 0x33, 0x67, 0x2b, 0xe4, 0xee, 0x12, 0x34, 0xd7, 0x36, 0xbf,
+ 0xff, 0x7e, 0x9b, 0xe5, 0xd7, 0xdf, 0xa2, 0x6d, 0xf7, 0x0e, 0x5f, 0xdd,
+ 0x7d, 0xf5, 0xe4, 0x72, 0xfe, 0x4e, 0xba, 0x4f, 0x07, 0x2f, 0x4a, 0x3e,
+ 0x39, 0x7f, 0x98, 0x1e, 0xc4, 0xf8, 0xd9, 0xca, 0x84, 0x55, 0xe1, 0x6f,
+ 0xc5, 0x8e, 0x3b, 0x7e, 0xf9, 0x63, 0x1c, 0x4e, 0x5f, 0xf9, 0xfe, 0xda,
+ 0x9d, 0xec, 0x0a, 0xce, 0x56, 0x1f, 0x50, 0x0a, 0xae, 0xde, 0xce, 0x5b,
+ 0x0e, 0x5f, 0xfa, 0x64, 0x55, 0x3c, 0x39, 0xc1, 0xcb, 0x46, 0x9f, 0x88,
+ 0xbd, 0xff, 0xfe, 0x1c, 0x5f, 0xbd, 0x1e, 0xdc, 0xc3, 0x8d, 0xf2, 0x86,
+ 0xa4, 0xe5, 0xff, 0x97, 0x0c, 0xee, 0x6f, 0x10, 0x4e, 0x54, 0x22, 0x93,
+ 0xad, 0x17, 0xed, 0x47, 0x18, 0xd1, 0xcb, 0xf9, 0xc7, 0x90, 0x60, 0x4e,
+ 0x54, 0x26, 0xf1, 0x91, 0x80, 0x21, 0x10, 0x0a, 0x6f, 0xfa, 0x1b, 0x5a,
+ 0x4f, 0x9f, 0x78, 0xe5, 0x35, 0x6d, 0x82, 0x2c, 0x0a, 0x4f, 0x0a, 0x79,
+ 0x42, 0x24, 0x31, 0xc0, 0xab, 0x0d, 0x35, 0xc6, 0x9b, 0xf4, 0x66, 0x08,
+ 0xd9, 0x34, 0x6f, 0xba, 0x8d, 0x19, 0x91, 0x80, 0x76, 0x3e, 0x6f, 0xcd,
+ 0x86, 0x30, 0x4d, 0xc2, 0x97, 0xd1, 0xe0, 0x71, 0x41, 0xbf, 0xed, 0x3b,
+ 0x7c, 0x9c, 0x2f, 0x39, 0xcb, 0xf9, 0xdb, 0x98, 0x50, 0x27, 0x2f, 0xff,
+ 0xf0, 0x72, 0x77, 0x1f, 0x6e, 0x17, 0xc9, 0x8c, 0x41, 0x59, 0xcb, 0xf8,
+ 0x3b, 0x78, 0xfa, 0x47, 0x2a, 0x11, 0x20, 0xec, 0x57, 0xfa, 0x6e, 0xa4,
+ 0x31, 0xc2, 0x72, 0xff, 0x72, 0xd6, 0x27, 0x60, 0x27, 0x2a, 0x0f, 0x9c,
+ 0x4c, 0xe9, 0x54, 0xe8, 0xb4, 0x78, 0x30, 0xbe, 0x04, 0x22, 0x2f, 0xb0,
+ 0x55, 0x6b, 0x39, 0x7f, 0xff, 0xfe, 0xea, 0x7b, 0xb9, 0xa8, 0xe3, 0xc9,
+ 0x80, 0xe0, 0xe5, 0x9f, 0x4b, 0x00, 0x3f, 0xec, 0xe5, 0xbc, 0x88, 0xb3,
+ 0xd9, 0x2d, 0xff, 0xa1, 0x7c, 0x85, 0xf6, 0xc8, 0x13, 0x97, 0xff, 0xba,
+ 0x8b, 0xee, 0x72, 0xd8, 0x3b, 0x0d, 0x67, 0x2f, 0xfb, 0xd9, 0xd1, 0xcf,
+ 0x75, 0x0e, 0x5b, 0x31, 0x10, 0xdf, 0x27, 0xdf, 0xff, 0x7b, 0xb9, 0xff,
+ 0x26, 0x46, 0x78, 0x38, 0x27, 0x2c, 0xd9, 0xcb, 0xf9, 0xc3, 0xad, 0x02,
+ 0x73, 0x97, 0xe8, 0xc1, 0xf3, 0x43, 0x94, 0xa9, 0xf4, 0xac, 0x49, 0x85,
+ 0xf7, 0xde, 0x4d, 0x61, 0xcb, 0x7d, 0xc8, 0xf4, 0x70, 0xc2, 0xdb, 0xc4,
+ 0xcd, 0x5e, 0x30, 0xba, 0x62, 0xa4, 0xf1, 0x86, 0x27, 0xa3, 0x5d, 0xbf,
+ 0xff, 0xfe, 0xcf, 0xa4, 0x9b, 0x1c, 0xe3, 0xdc, 0x9b, 0xb0, 0x33, 0x72,
+ 0x75, 0xa7, 0x13, 0x97, 0xff, 0xfd, 0x82, 0xaf, 0x2d, 0x47, 0x14, 0xf6,
+ 0xf1, 0x54, 0xd3, 0xfc, 0x72, 0x85, 0x1d, 0xca, 0x42, 0x0e, 0x91, 0x35,
+ 0x20, 0x46, 0x55, 0x7f, 0xf9, 0x03, 0xc9, 0x89, 0xca, 0x02, 0xf3, 0x6c,
+ 0xe5, 0xd2, 0x91, 0xcb, 0x6a, 0x0f, 0x96, 0x74, 0xeb, 0xf4, 0xa3, 0xe9,
+ 0x6c, 0xe5, 0xff, 0xff, 0xff, 0xb0, 0x55, 0xe4, 0x9d, 0x07, 0x39, 0x93,
+ 0xd0, 0xc1, 0x75, 0x7a, 0x9c, 0xf3, 0xbf, 0x7f, 0x01, 0x29, 0x7f, 0xff,
+ 0xf2, 0xd1, 0xb0, 0x83, 0x5c, 0x81, 0x13, 0xed, 0x7d, 0x07, 0x7e, 0x76,
+ 0xce, 0x5c, 0x09, 0xfe, 0x4d, 0x15, 0x0a, 0x77, 0x0a, 0x2b, 0xf9, 0x51,
+ 0xcf, 0x75, 0x0e, 0x54, 0x2f, 0x1a, 0x76, 0x5e, 0x4b, 0xc2, 0x38, 0x63,
+ 0x6d, 0x02, 0x1d, 0x98, 0x72, 0xff, 0x3c, 0xb1, 0x8e, 0x3f, 0x9c, 0xbe,
+ 0xce, 0xc4, 0xc7, 0x2f, 0x31, 0x7c, 0x9a, 0xb3, 0xe5, 0xe8, 0x8b, 0x99,
+ 0x5f, 0xff, 0xfe, 0xd2, 0xc7, 0x38, 0xf2, 0xda, 0x60, 0xff, 0xc8, 0x73,
+ 0x88, 0xe6, 0xf8, 0x9c, 0xbf, 0xd8, 0xec, 0xe4, 0xd2, 0x18, 0x72, 0xff,
+ 0xf4, 0xa3, 0x7d, 0x06, 0xb3, 0xde, 0x46, 0x1c, 0xa5, 0xa2, 0x03, 0xe3,
+ 0x6b, 0xff, 0xf0, 0x23, 0x90, 0xe0, 0x7a, 0x8a, 0x86, 0x15, 0xfc, 0xe5,
+ 0x62, 0x6f, 0x9a, 0x87, 0xf8, 0x92, 0x5f, 0xff, 0x90, 0x7d, 0xdc, 0xe0,
+ 0xf4, 0xd8, 0xd6, 0xe3, 0xf9, 0xcb, 0xe6, 0xf9, 0x6e, 0x63, 0x96, 0xf1,
+ 0xca, 0x83, 0x70, 0xe4, 0xf7, 0xfe, 0x19, 0xc7, 0x38, 0xec, 0x11, 0xf1,
+ 0xcb, 0xff, 0x07, 0xb1, 0xf7, 0x26, 0xa3, 0xc7, 0xf4, 0x39, 0x50, 0x88,
+ 0xc9, 0xd0, 0x69, 0x13, 0x95, 0xd9, 0xa7, 0xa1, 0x26, 0x08, 0x55, 0xdf,
+ 0xfc, 0xde, 0x6c, 0x10, 0xae, 0xe3, 0x53, 0x1c, 0xbe, 0xd4, 0x9c, 0x27,
+ 0x2f, 0xfc, 0x32, 0x5f, 0x53, 0xa2, 0x09, 0xce, 0x5e, 0xf6, 0x70, 0xe7,
+ 0x2a, 0x0f, 0x83, 0x0f, 0xef, 0x34, 0xce, 0x9c, 0xbb, 0x02, 0x72, 0xa7,
+ 0x5c, 0xbc, 0x94, 0xb5, 0x8c, 0x47, 0x74, 0x7d, 0xc2, 0x0b, 0xc4, 0x1c,
+ 0x47, 0xaf, 0xc9, 0xed, 0xe7, 0xe7, 0x2f, 0xdd, 0xce, 0x29, 0xc4, 0xe5,
+ 0xff, 0xff, 0x85, 0xfd, 0xd8, 0x9b, 0x90, 0xe7, 0x53, 0xdb, 0x02, 0xc1,
+ 0x07, 0x2e, 0xcf, 0xce, 0x5f, 0xfc, 0x3f, 0x8e, 0x24, 0xdd, 0x81, 0x54,
+ 0xe5, 0x21, 0xed, 0xb8, 0xbd, 0xfa, 0x07, 0xaf, 0x23, 0x97, 0xa0, 0x30,
+ 0x72, 0x82, 0x78, 0x2c, 0x26, 0xa3, 0x97, 0xa0, 0x30, 0x72, 0xfd, 0x9e,
+ 0xdb, 0xcd, 0xc8, 0xf2, 0x20, 0x89, 0x81, 0x77, 0xcd, 0x5b, 0x50, 0xe1,
+ 0x9a, 0xb3, 0x97, 0xc8, 0xe2, 0x13, 0x96, 0x6f, 0x91, 0xec, 0x04, 0xe2,
+ 0xa4, 0x8d, 0x04, 0x85, 0x2d, 0xff, 0xfb, 0x40, 0xd6, 0xa0, 0x71, 0x54,
+ 0xef, 0x71, 0x43, 0x97, 0xc0, 0x7f, 0xbc, 0x72, 0xa4, 0xac, 0xd0, 0x25,
+ 0x18, 0x56, 0xac, 0x32, 0x26, 0x8d, 0xe7, 0x44, 0xfd, 0x56, 0xa3, 0x97,
+ 0xf6, 0xd6, 0xb7, 0x15, 0x4e, 0x57, 0x0a, 0x37, 0x3e, 0x0b, 0xbf, 0xc3,
+ 0xcb, 0x8f, 0xd2, 0xdc, 0xc7, 0x2e, 0x9f, 0xe3, 0x97, 0xee, 0xbb, 0x5c,
+ 0x7e, 0x72, 0x82, 0x7f, 0xce, 0x75, 0xc0, 0x33, 0x7f, 0xb5, 0x30, 0xe7,
+ 0x5f, 0xc7, 0x2a, 0x13, 0x09, 0xc8, 0x52, 0xa1, 0x8d, 0xf9, 0x34, 0x1c,
+ 0x13, 0x97, 0xef, 0xf3, 0xca, 0x4e, 0x72, 0xff, 0x37, 0xec, 0xef, 0x2f,
+ 0xb6, 0x72, 0xa0, 0xf8, 0xdc, 0xae, 0xa4, 0x8d, 0xce, 0x99, 0x8c, 0x22,
+ 0x6f, 0xee, 0xe2, 0xe5, 0x0c, 0x39, 0x7f, 0xbb, 0x92, 0x71, 0xcf, 0x8e,
+ 0x56, 0x1e, 0xff, 0x8b, 0x6f, 0xff, 0xf8, 0x5f, 0xfd, 0xcf, 0x88, 0x3e,
+ 0x1c, 0xe3, 0xcb, 0x6d, 0x89, 0xcb, 0xfb, 0xb8, 0x3f, 0x42, 0xa7, 0x28,
+ 0x51, 0x73, 0xe2, 0x16, 0xda, 0xaf, 0x62, 0x4c, 0x72, 0xff, 0xc9, 0x93,
+ 0x72, 0xdc, 0x75, 0xda, 0xce, 0x5f, 0xff, 0x4b, 0x60, 0xc1, 0xe4, 0x39,
+ 0xde, 0xb8, 0x4e, 0x5f, 0xf7, 0xd9, 0x1f, 0x4c, 0x30, 0xc3, 0x97, 0xf7,
+ 0xdb, 0xee, 0x3e, 0x8e, 0x5f, 0xff, 0xf9, 0x19, 0xa4, 0xcf, 0x84, 0x1e,
+ 0x8e, 0xf2, 0xe2, 0x9e, 0x9a, 0x0e, 0x53, 0xa2, 0x7b, 0xc5, 0xd5, 0x3a,
+ 0x75, 0x21, 0x1c, 0xf9, 0x0f, 0xaa, 0x1e, 0x86, 0xc5, 0xff, 0xf6, 0x3c,
+ 0xfd, 0x84, 0xf6, 0xe2, 0x7c, 0xd9, 0xcb, 0xfe, 0xcd, 0x4f, 0x09, 0xac,
+ 0x13, 0x96, 0x61, 0xce, 0x46, 0xde, 0xf0, 0xe0, 0x4e, 0x54, 0x1b, 0xef,
+ 0x88, 0xef, 0xef, 0xb7, 0x98, 0x2a, 0x9c, 0xbe, 0x62, 0x91, 0xf9, 0xcb,
+ 0xff, 0xd3, 0x87, 0x4e, 0xb1, 0xce, 0x3a, 0x4d, 0x9c, 0xac, 0x44, 0xf2,
+ 0x17, 0x00, 0x92, 0xfe, 0xf7, 0x5e, 0x65, 0x18, 0x72, 0xfe, 0xf4, 0x7f,
+ 0x2c, 0xd9, 0xca, 0x73, 0xde, 0x13, 0x0b, 0xc0, 0xfb, 0xf3, 0x97, 0xf6,
+ 0xe3, 0xef, 0xf5, 0x07, 0x2e, 0x0a, 0x1c, 0xa8, 0x5c, 0xbe, 0xc8, 0xf6,
+ 0x56, 0xa4, 0x90, 0xc4, 0xd4, 0x2f, 0xde, 0x11, 0x82, 0x41, 0xb1, 0xfe,
+ 0x25, 0xf7, 0xf7, 0x9f, 0xbc, 0x83, 0x07, 0x2f, 0xff, 0x7b, 0x6a, 0x6f,
+ 0x97, 0x86, 0x25, 0x9e, 0x39, 0x7f, 0xbc, 0x93, 0xe7, 0x41, 0xe3, 0x97,
+ 0xde, 0xdc, 0x2a, 0x72, 0xd3, 0x1c, 0xbf, 0xb0, 0x19, 0xd5, 0xce, 0x72,
+ 0xdf, 0x41, 0xe0, 0x6c, 0x4a, 0xa1, 0x11, 0x78, 0xc7, 0x7f, 0x75, 0xe4,
+ 0xcd, 0x21, 0xcb, 0xff, 0x95, 0x55, 0xfd, 0xbf, 0x0c, 0x7d, 0x23, 0x97,
+ 0xf7, 0x86, 0x25, 0x9e, 0x39, 0x50, 0x7e, 0x72, 0x47, 0xb9, 0x36, 0x72,
+ 0xcc, 0x39, 0x7b, 0x59, 0xf1, 0xca, 0x09, 0xe2, 0x74, 0x5b, 0xf1, 0x1b,
+ 0xff, 0xce, 0xaf, 0x95, 0x81, 0x96, 0x75, 0x18, 0x72, 0xfc, 0x9b, 0xdc,
+ 0x30, 0xe5, 0x22, 0x28, 0x44, 0xc3, 0x8a, 0x55, 0x42, 0xb3, 0x2c, 0x2f,
+ 0x55, 0x35, 0x21, 0x7f, 0xf9, 0x08, 0xc2, 0x80, 0x11, 0x83, 0x5f, 0x82,
+ 0x82, 0xe1, 0x39, 0x7b, 0x61, 0xf8, 0xe5, 0xdf, 0xac, 0xe5, 0xff, 0xec,
+ 0x9b, 0xb0, 0x2a, 0x8e, 0x7b, 0xa0, 0x39, 0x4a, 0x9f, 0x17, 0x46, 0x2b,
+ 0x92, 0x28, 0xe5, 0x08, 0x0a, 0x44, 0x79, 0xea, 0x19, 0x37, 0xff, 0xf9,
+ 0x33, 0xe9, 0x6f, 0xdd, 0x86, 0x42, 0x07, 0x94, 0x35, 0x27, 0x2f, 0xf3,
+ 0x8f, 0x25, 0xef, 0xf0, 0x9c, 0xbf, 0xf0, 0x37, 0xc9, 0x8a, 0x75, 0xfb,
+ 0x07, 0x2f, 0xd9, 0xe0, 0x67, 0xc7, 0x2f, 0x2b, 0x9f, 0x1c, 0xba, 0x26,
+ 0xe4, 0x78, 0xde, 0x28, 0xa1, 0x45, 0xc0, 0x21, 0x11, 0x7f, 0xff, 0xfe,
+ 0x00, 0xf2, 0x6d, 0xfe, 0x96, 0x9f, 0xfe, 0x5b, 0x04, 0x7d, 0xdc, 0x41,
+ 0xc5, 0x4e, 0x5f, 0xff, 0xef, 0x03, 0x07, 0x92, 0x67, 0x86, 0x3f, 0xe5,
+ 0x88, 0x13, 0x97, 0xfc, 0xcc, 0x67, 0x26, 0x35, 0xf1, 0x91, 0xca, 0xd2,
+ 0x28, 0xd8, 0xc5, 0x7f, 0xfd, 0xad, 0x67, 0xb7, 0xd4, 0xce, 0x5d, 0xfe,
+ 0x0e, 0x52, 0x1f, 0xa8, 0x08, 0xeb, 0x13, 0xc3, 0xec, 0x74, 0x57, 0xec,
+ 0x15, 0xa8, 0xc3, 0x97, 0xff, 0x77, 0x20, 0x66, 0x1c, 0xf6, 0xdc, 0xe5,
+ 0xa5, 0xe3, 0xea, 0xe0, 0x28, 0xbf, 0xff, 0x07, 0x19, 0xcb, 0x83, 0xd1,
+ 0xb9, 0xa4, 0xfa, 0x9c, 0xe5, 0xff, 0xfd, 0xe4, 0x9f, 0x03, 0xc9, 0x8f,
+ 0x2d, 0x24, 0xee, 0xc3, 0x97, 0xfa, 0x77, 0x60, 0xc6, 0xa6, 0x39, 0x7f,
+ 0xdf, 0x62, 0xbf, 0xb3, 0x39, 0x6b, 0x11, 0x24, 0x8b, 0xd7, 0xfd, 0x83,
+ 0x3f, 0x2f, 0xdd, 0xe6, 0x39, 0x7f, 0xfd, 0x80, 0xd7, 0x29, 0xba, 0x05,
+ 0x53, 0x05, 0x53, 0x97, 0xff, 0xcf, 0xe8, 0xd0, 0x18, 0x9b, 0xe5, 0xb9,
+ 0x6c, 0xe5, 0xff, 0x6a, 0x78, 0x9e, 0x70, 0x6a, 0x73, 0x97, 0xfe, 0xe5,
+ 0x37, 0x40, 0xaa, 0x60, 0xaa, 0x72, 0xff, 0x0f, 0x2d, 0x81, 0xa0, 0x34,
+ 0x72, 0xb0, 0xfe, 0xc0, 0x87, 0x50, 0x8d, 0xad, 0xc2, 0xe6, 0xff, 0xf4,
+ 0xfc, 0xb7, 0xd0, 0x72, 0xf6, 0xf7, 0x1a, 0x39, 0x7f, 0xfd, 0xd8, 0x9f,
+ 0x90, 0xe7, 0x17, 0xef, 0x63, 0xe3, 0x97, 0xff, 0xfd, 0xf6, 0xd3, 0x1b,
+ 0xe5, 0xdc, 0xf6, 0xf2, 0x7e, 0x58, 0x81, 0x39, 0x41, 0x46, 0x06, 0x2a,
+ 0x5f, 0xf0, 0xe6, 0xb1, 0x78, 0x81, 0x39, 0x7f, 0x4f, 0xe9, 0x86, 0x18,
+ 0x72, 0xff, 0xfe, 0xc9, 0xf1, 0x02, 0x20, 0xef, 0x28, 0x0b, 0xcd, 0xb3,
+ 0x97, 0xfd, 0x8d, 0xe7, 0x53, 0x5d, 0x73, 0x95, 0x8a, 0x8b, 0x52, 0x31,
+ 0x1e, 0x91, 0x39, 0xb6, 0xcb, 0xfc, 0xbb, 0x53, 0xb2, 0x6b, 0x02, 0xce,
+ 0xac, 0x3b, 0x97, 0x1f, 0x57, 0xd0, 0x93, 0x42, 0xbd, 0x43, 0xbd, 0x8a,
+ 0x9d, 0x3c, 0x15, 0x4d, 0xc6, 0x59, 0xe9, 0x4a, 0x97, 0xfb, 0xc3, 0x9e,
+ 0xee, 0x4e, 0x72, 0xff, 0xcf, 0xae, 0xe7, 0xa0, 0x53, 0xf3, 0x97, 0xff,
+ 0xc3, 0x93, 0xf2, 0xfc, 0x1e, 0xcc, 0x67, 0xed, 0x9c, 0xbe, 0x97, 0x92,
+ 0x73, 0x97, 0xfd, 0x8d, 0xfd, 0x2d, 0xf2, 0xf2, 0x1c, 0xbf, 0xf4, 0xa3,
+ 0x3f, 0xee, 0x60, 0xac, 0xe5, 0xff, 0xee, 0xa0, 0x87, 0x92, 0x8b, 0x1c,
+ 0xee, 0x1c, 0xbf, 0xe7, 0xf6, 0xe6, 0x90, 0x07, 0xc7, 0x2b, 0x11, 0x85,
+ 0x31, 0xef, 0xe9, 0x77, 0xfd, 0xd4, 0x64, 0x60, 0xfb, 0x67, 0x2f, 0xff,
+ 0xf0, 0x3d, 0xa0, 0x4d, 0xcb, 0xd3, 0x74, 0x1f, 0xf9, 0x33, 0x80, 0xe5,
+ 0xf4, 0x2e, 0x19, 0xc9, 0x1a, 0x6b, 0x31, 0x13, 0x7a, 0x85, 0x60, 0x2b,
+ 0x33, 0xd1, 0xeb, 0xaa, 0x89, 0x1f, 0x04, 0x7a, 0x57, 0xff, 0xf6, 0xb1,
+ 0xd9, 0xc9, 0x57, 0xfb, 0xb9, 0xde, 0xc7, 0x8e, 0x5f, 0x66, 0xa6, 0x91,
+ 0xcb, 0xff, 0xca, 0xa7, 0xd2, 0xdf, 0x20, 0xa7, 0x18, 0x09, 0xcb, 0xfe,
+ 0xc9, 0xa5, 0x9d, 0xce, 0x3b, 0x39, 0x7f, 0xfe, 0x0f, 0x41, 0xbe, 0x5d,
+ 0x4f, 0x77, 0x35, 0x1c, 0x4e, 0x5f, 0xd9, 0xf0, 0xe6, 0x7e, 0x72, 0xb1,
+ 0x10, 0xe2, 0xb5, 0x74, 0x33, 0x13, 0x56, 0x54, 0x8f, 0x4a, 0x03, 0x0c,
+ 0x2b, 0x41, 0xcb, 0xe4, 0xd3, 0xfc, 0x72, 0xe4, 0xf2, 0x1b, 0x2d, 0x88,
+ 0x5f, 0xfc, 0x9c, 0x50, 0x3c, 0xa2, 0x60, 0xbb, 0x67, 0x2f, 0xff, 0xff,
+ 0x0a, 0x2b, 0xd7, 0x9b, 0x90, 0x83, 0x83, 0x96, 0x7d, 0x2c, 0x00, 0xff,
+ 0xb3, 0x97, 0xee, 0xa4, 0x0c, 0xe7, 0x29, 0x88, 0xa8, 0xe3, 0x08, 0x1b,
+ 0xe6, 0x22, 0x36, 0x72, 0xa0, 0xf3, 0x1c, 0xaa, 0xb6, 0x9a, 0xef, 0xa3,
+ 0x3d, 0xa9, 0x27, 0x64, 0x91, 0xc4, 0x5e, 0x98, 0x01, 0x39, 0x50, 0xd9,
+ 0x15, 0xe5, 0x27, 0x4d, 0x25, 0xe6, 0xe9, 0x7f, 0xb1, 0xda, 0x3c, 0xa3,
+ 0x10, 0x14, 0xdf, 0xa0, 0x7c, 0x9c, 0x4e, 0x5f, 0x7b, 0x6f, 0xf9, 0xcb,
+ 0xff, 0xba, 0x9c, 0x93, 0x40, 0x9d, 0xf4, 0xb3, 0x97, 0xc9, 0xd7, 0x9c,
+ 0xe5, 0xf7, 0x18, 0xf4, 0x1c, 0xbf, 0x6f, 0x3c, 0x9b, 0x39, 0x7f, 0xf2,
+ 0x7b, 0xa9, 0x98, 0x11, 0xc6, 0xce, 0x5e, 0xd2, 0x2a, 0x72, 0xff, 0xf8,
+ 0x18, 0x9d, 0xc5, 0xf5, 0x39, 0x36, 0xc5, 0x9c, 0xbd, 0xec, 0x6c, 0xe5,
+ 0xec, 0x04, 0xe2, 0x7d, 0xfe, 0x52, 0xbf, 0x03, 0x87, 0x17, 0xf1, 0xcb,
+ 0xfb, 0xaf, 0x3f, 0x29, 0x78, 0xe5, 0xfc, 0xf3, 0x29, 0xb8, 0xc3, 0x97,
+ 0xe7, 0xd0, 0xfc, 0x87, 0x2a, 0x11, 0x64, 0x85, 0x9d, 0x31, 0xf1, 0x75,
+ 0xee, 0xb8, 0x9c, 0xa0, 0xab, 0x07, 0xc2, 0x85, 0x48, 0xd6, 0x8e, 0x84,
+ 0x53, 0x11, 0xb0, 0x9d, 0xd0, 0x86, 0x11, 0x9e, 0x87, 0x2b, 0x67, 0x77,
+ 0xc3, 0xe8, 0x61, 0xcb, 0xfd, 0xd8, 0x41, 0x7d, 0x2a, 0x72, 0xfe, 0x84,
+ 0x17, 0xd2, 0xa7, 0x2f, 0xe7, 0xff, 0x5a, 0x4d, 0x72, 0x3d, 0xee, 0x99,
+ 0x5f, 0xff, 0xfe, 0xe4, 0xc8, 0xcf, 0x72, 0xc9, 0x27, 0x11, 0xcd, 0xf2,
+ 0x80, 0xbc, 0xdb, 0x39, 0x7f, 0x0a, 0xf9, 0x37, 0xbf, 0xce, 0x54, 0x91,
+ 0x60, 0xef, 0xd4, 0x89, 0xcc, 0x7e, 0xfe, 0x08, 0x7b, 0xde, 0xdf, 0x90,
+ 0xe5, 0xe9, 0xbf, 0xf8, 0xe5, 0xe8, 0x57, 0x92, 0xcd, 0xe7, 0xe3, 0x96,
+ 0xfc, 0xe5, 0xfd, 0x1a, 0x9e, 0x35, 0x39, 0xcb, 0xff, 0x26, 0x37, 0xb0,
+ 0x4c, 0x30, 0xc3, 0x97, 0x80, 0xfb, 0x39, 0x52, 0x44, 0x53, 0x0b, 0xd4,
+ 0x3f, 0xbf, 0xff, 0x93, 0x5c, 0xb1, 0x30, 0x55, 0xea, 0x63, 0x31, 0x67,
+ 0x2f, 0xff, 0xfc, 0xcd, 0xaf, 0xb0, 0xbf, 0xa4, 0x20, 0x0f, 0x24, 0x55,
+ 0xc7, 0xf3, 0x97, 0xff, 0xfa, 0x7d, 0x43, 0x36, 0x08, 0xe5, 0x1a, 0x80,
+ 0xf6, 0x18, 0x72, 0xb1, 0x1a, 0x88, 0xe3, 0x58, 0x9a, 0x7e, 0xa3, 0x2e,
+ 0xbf, 0x7f, 0xb4, 0xf9, 0xb3, 0x97, 0xfe, 0xd6, 0x7d, 0xdf, 0xa1, 0x93,
+ 0xc1, 0xcb, 0xff, 0xff, 0xda, 0xd2, 0x4f, 0xcb, 0xb9, 0xe1, 0x89, 0xbb,
+ 0x93, 0xc7, 0xde, 0x02, 0xce, 0x5f, 0xff, 0xfd, 0x0a, 0xf6, 0x39, 0x0e,
+ 0x01, 0x5e, 0x5f, 0x4b, 0x68, 0x2a, 0x44, 0xe7, 0x2f, 0xdf, 0x6d, 0x30,
+ 0x4e, 0x56, 0x22, 0x80, 0x0f, 0x34, 0x89, 0x9f, 0xf6, 0x31, 0xdb, 0xff,
+ 0xb4, 0x3f, 0x66, 0xc1, 0x30, 0xc3, 0x0e, 0x5f, 0xf2, 0x2b, 0xd8, 0x49,
+ 0xe1, 0x53, 0x96, 0x92, 0x1f, 0xfe, 0xd1, 0x6f, 0xf8, 0x41, 0x30, 0xe7,
+ 0x5f, 0xc7, 0x2f, 0xf7, 0x61, 0xb0, 0xf5, 0xd8, 0x72, 0xff, 0x99, 0x9b,
+ 0xe5, 0x30, 0xc3, 0x0e, 0x5f, 0xff, 0xb7, 0x3b, 0xf2, 0x0f, 0x63, 0x5a,
+ 0xce, 0x31, 0xf1, 0xca, 0x0a, 0x32, 0x98, 0x69, 0xe3, 0xbb, 0xff, 0xfe,
+ 0x7d, 0x77, 0x3c, 0x98, 0x33, 0xee, 0x30, 0x43, 0xd8, 0x39, 0x7d, 0xee,
+ 0x53, 0xe8, 0xe5, 0x7c, 0x88, 0x97, 0x63, 0xbf, 0xff, 0xf7, 0xd9, 0x38,
+ 0x38, 0x39, 0x7d, 0x2f, 0x43, 0x7c, 0xb3, 0x5f, 0xff, 0x07, 0x2f, 0xff,
+ 0x36, 0xe3, 0x3b, 0x00, 0x81, 0x41, 0x43, 0x97, 0xf4, 0xdf, 0x48, 0x11,
+ 0xe3, 0x97, 0xff, 0xf4, 0xa3, 0x5f, 0x4b, 0x7c, 0xbb, 0x08, 0x2f, 0xa5,
+ 0x4e, 0x5f, 0xd9, 0x2f, 0x0e, 0x48, 0xe5, 0xff, 0x75, 0xd8, 0x39, 0xd7,
+ 0xf1, 0xcb, 0xbf, 0x6c, 0xe5, 0xf3, 0x4c, 0xd4, 0x1c, 0xb6, 0x68, 0xde,
+ 0x71, 0x19, 0xa8, 0x4d, 0x57, 0xe3, 0x0e, 0xaf, 0x6c, 0xb3, 0xce, 0x77,
+ 0xff, 0x67, 0xb7, 0xcb, 0x58, 0x9d, 0x80, 0x9c, 0xbf, 0xb3, 0xda, 0xd6,
+ 0x48, 0xe5, 0x1c, 0xbf, 0x67, 0x47, 0x16, 0x72, 0xbf, 0x36, 0x22, 0x17,
+ 0x53, 0x1f, 0xff, 0x97, 0xaf, 0x67, 0xde, 0x39, 0x78, 0x73, 0x7c, 0x8f,
+ 0x01, 0xac, 0x8e, 0xff, 0xb1, 0x9d, 0x84, 0xd0, 0x1a, 0xce, 0x50, 0x59,
+ 0x0b, 0x58, 0x52, 0xa9, 0x5a, 0xe3, 0x80, 0xfa, 0x15, 0x08, 0x4f, 0xa8,
+ 0xc0, 0xbb, 0x0b, 0x97, 0x23, 0xdb, 0xd7, 0xa3, 0x9e, 0x02, 0x5f, 0x18,
+ 0xc1, 0x14, 0x37, 0xbf, 0xe8, 0x60, 0xe0, 0x74, 0x93, 0x9c, 0xbf, 0xff,
+ 0xcd, 0xf4, 0x11, 0xf7, 0x2d, 0x6a, 0x27, 0x17, 0x7d, 0x2a, 0x72, 0xff,
+ 0x0e, 0x03, 0x15, 0x97, 0xe7, 0x29, 0xd1, 0x34, 0xdb, 0x35, 0x49, 0x1e,
+ 0xb9, 0x0d, 0x2b, 0xca, 0xc6, 0x8e, 0x5f, 0xf8, 0x73, 0x96, 0xb3, 0xa3,
+ 0x93, 0x1c, 0xbf, 0xff, 0xdd, 0x7f, 0xf7, 0xc8, 0x73, 0x88, 0xe6, 0xf1,
+ 0x90, 0xb3, 0x95, 0x32, 0x2f, 0xc4, 0x77, 0x67, 0xf5, 0xc2, 0x99, 0xad,
+ 0x11, 0x09, 0xcc, 0xa4, 0xed, 0x7d, 0x1e, 0xe3, 0xc3, 0x9a, 0xfe, 0xce,
+ 0xa8, 0x3f, 0x7e, 0x72, 0xfe, 0xee, 0x0f, 0xbf, 0x01, 0xcb, 0xfe, 0x08,
+ 0x63, 0xfe, 0x59, 0xf7, 0x8e, 0x5c, 0xcd, 0x9c, 0xbc, 0xfb, 0x43, 0x95,
+ 0x06, 0xcb, 0xf1, 0x7a, 0x44, 0x48, 0x0b, 0x7d, 0xfe, 0xde, 0xe1, 0x27,
+ 0x7f, 0x1c, 0xbf, 0x95, 0x1c, 0xdc, 0x68, 0xe5, 0xa5, 0x07, 0xc0, 0x03,
+ 0x3b, 0x48, 0xe5, 0xf4, 0x31, 0xc2, 0x72, 0xa0, 0xd9, 0x08, 0x8d, 0xfe,
+ 0xc9, 0xbb, 0x9e, 0x80, 0x9c, 0xbf, 0x87, 0xce, 0xc4, 0xf1, 0xcb, 0x48,
+ 0xe5, 0x41, 0xbd, 0xf1, 0x65, 0xe1, 0x5c, 0x1c, 0xbf, 0xff, 0xfe, 0xee,
+ 0x7b, 0x6f, 0x37, 0x21, 0xcf, 0xa5, 0x80, 0x9c, 0x70, 0x3d, 0x49, 0x8e,
+ 0x5c, 0x05, 0x4e, 0x52, 0x22, 0xd3, 0x43, 0x7e, 0x84, 0x0d, 0xfe, 0xfd,
+ 0x3d, 0xef, 0x63, 0x67, 0x2f, 0xec, 0x9c, 0x73, 0xed, 0x9c, 0xbf, 0xf8,
+ 0x7f, 0x69, 0x9d, 0x48, 0x63, 0x84, 0xe5, 0xff, 0xff, 0xfa, 0x5b, 0xd8,
+ 0x23, 0xc8, 0x1c, 0x19, 0xb9, 0x0e, 0x6a, 0x07, 0xdd, 0xce, 0x03, 0x97,
+ 0xff, 0x7d, 0x2d, 0xe3, 0x3e, 0x8e, 0xf6, 0x0e, 0x57, 0xc8, 0xcc, 0xd4,
+ 0x21, 0xad, 0xb3, 0x95, 0x89, 0xa5, 0x82, 0x31, 0x15, 0x0a, 0x6d, 0x39,
+ 0xcb, 0xf6, 0xb3, 0xe9, 0x6c, 0xe5, 0xe5, 0xf7, 0x0e, 0x5b, 0x27, 0x3c,
+ 0x5d, 0x14, 0xdf, 0xf7, 0xd1, 0xa9, 0xf9, 0x62, 0x04, 0xe5, 0xd3, 0x21,
+ 0xca, 0xc4, 0x69, 0x0a, 0xb8, 0x0a, 0x38, 0x9e, 0x5f, 0xd9, 0xf4, 0xa3,
+ 0xf8, 0x39, 0x7e, 0x1c, 0xeb, 0xf8, 0xe5, 0x7c, 0x7a, 0x8c, 0x2e, 0xbe,
+ 0x4e, 0x39, 0xa3, 0x95, 0x07, 0x8d, 0xd2, 0x3b, 0xee, 0x4b, 0x9d, 0xb3,
+ 0x97, 0xe9, 0xf9, 0x02, 0x26, 0x39, 0x7f, 0xff, 0xc3, 0x1f, 0xfd, 0x2d,
+ 0x82, 0x3c, 0x38, 0x14, 0xcd, 0x4c, 0x72, 0x9d, 0x12, 0x7e, 0x2c, 0xa8,
+ 0x5f, 0xea, 0x09, 0x86, 0x42, 0xfb, 0xe8, 0x40, 0xa2, 0xcc, 0xc3, 0xfd,
+ 0x70, 0x78, 0x6a, 0x7e, 0x68, 0x26, 0xbb, 0x8d, 0xe7, 0xd1, 0x84, 0x82,
+ 0x1a, 0xfc, 0x48, 0x54, 0x85, 0xd5, 0xfa, 0x49, 0xac, 0xf8, 0xe5, 0xed,
+ 0xf7, 0x0e, 0x5f, 0xb3, 0x73, 0xe3, 0x67, 0x2b, 0xe3, 0xed, 0x98, 0xa3,
+ 0xa3, 0x97, 0xff, 0xfb, 0xdb, 0xee, 0x7d, 0x8f, 0xf7, 0x20, 0xc4, 0xfc,
+ 0x95, 0x54, 0xe5, 0xff, 0x62, 0xa3, 0x9e, 0xea, 0x36, 0x72, 0xa1, 0x14,
+ 0x7a, 0x6a, 0xbf, 0xfe, 0x9f, 0x16, 0x1e, 0xa6, 0x2b, 0xc9, 0x50, 0x41,
+ 0xcb, 0xff, 0xa4, 0x9e, 0xee, 0x6b, 0x59, 0xed, 0x9c, 0xbf, 0xee, 0x4a,
+ 0x79, 0x38, 0xc0, 0xac, 0xe5, 0x22, 0x35, 0x66, 0x54, 0xea, 0x25, 0xff,
+ 0xa5, 0xbf, 0x3c, 0xfc, 0x03, 0x9f, 0x1c, 0xbf, 0xd2, 0xec, 0x48, 0x0e,
+ 0xa1, 0xcb, 0x47, 0xc7, 0xee, 0x28, 0x77, 0xfd, 0xd9, 0xd3, 0x07, 0xe9,
+ 0x6c, 0xe5, 0xff, 0x7d, 0xdc, 0x58, 0xe0, 0x1a, 0xce, 0x5f, 0xff, 0x37,
+ 0x8b, 0xde, 0x7a, 0x6c, 0x54, 0x73, 0xf3, 0x96, 0x94, 0x23, 0x23, 0x0e,
+ 0x90, 0xf2, 0xfe, 0x4f, 0xbf, 0xd3, 0x84, 0xe5, 0xec, 0xd7, 0xe7, 0x2f,
+ 0xdb, 0x4c, 0x1f, 0xce, 0x5b, 0x10, 0xf1, 0x36, 0x3b, 0x7e, 0x4f, 0xff,
+ 0xcd, 0x1c, 0xae, 0xa3, 0x08, 0x5c, 0xf6, 0x4d, 0x7d, 0xc1, 0xec, 0xe9,
+ 0xcb, 0x91, 0x87, 0x2f, 0xff, 0xfd, 0xf4, 0x9f, 0xee, 0x42, 0x0e, 0x0e,
+ 0x59, 0xf4, 0xb0, 0x03, 0xfe, 0xce, 0x53, 0x11, 0x1b, 0xc0, 0x2d, 0x79,
+ 0xa2, 0x70, 0xe7, 0x2b, 0x92, 0x65, 0x53, 0x97, 0xe4, 0x2c, 0x9a, 0x13,
+ 0x5f, 0xff, 0xff, 0x7d, 0xb0, 0x47, 0xdc, 0xbb, 0x81, 0xe4, 0x38, 0x05,
+ 0x79, 0x6f, 0xff, 0xd3, 0xc7, 0x2f, 0xff, 0xff, 0x36, 0x38, 0x16, 0x32,
+ 0x3d, 0xbc, 0xf6, 0xf4, 0x98, 0xb1, 0xc0, 0x9c, 0xa8, 0x47, 0xfe, 0x42,
+ 0x26, 0xfd, 0x03, 0xf3, 0xce, 0x72, 0xff, 0xff, 0xff, 0xd8, 0xb8, 0xec,
+ 0x33, 0xd9, 0xbd, 0xc6, 0xb5, 0x03, 0x93, 0xe0, 0x36, 0x09, 0x86, 0x18,
+ 0x72, 0xf0, 0x34, 0xa9, 0xca, 0x62, 0x2d, 0x9a, 0x42, 0x62, 0xfc, 0xff,
+ 0xa8, 0xf3, 0x9c, 0xac, 0x3d, 0x44, 0x2a, 0xbc, 0x9f, 0xc1, 0xcb, 0xf8,
+ 0x23, 0x9d, 0x7f, 0x1c, 0xbf, 0x7b, 0xe9, 0x26, 0x8e, 0x56, 0x1e, 0xae,
+ 0xcb, 0x2a, 0x74, 0x49, 0x7e, 0xe3, 0x7b, 0x4e, 0xa1, 0xcb, 0xf4, 0x79,
+ 0x89, 0xe3, 0x96, 0x9d, 0xcf, 0x10, 0x03, 0xb7, 0xfe, 0x85, 0x78, 0x01,
+ 0x83, 0x32, 0x8c, 0x39, 0x7f, 0xff, 0xff, 0x95, 0x1c, 0xe4, 0x98, 0x2f,
+ 0xee, 0xc4, 0xdc, 0x87, 0x3a, 0x9e, 0xd8, 0x16, 0x08, 0x39, 0x58, 0x8f,
+ 0xcf, 0x8a, 0x00, 0x89, 0x7f, 0xec, 0xcf, 0xf7, 0xcb, 0x5b, 0x0e, 0xce,
+ 0x5f, 0xed, 0x62, 0xfa, 0x9a, 0x98, 0xe5, 0xbc, 0x13, 0xf6, 0xc4, 0x2b,
+ 0xfd, 0x8b, 0x4f, 0x68, 0x0c, 0x39, 0x58, 0x7b, 0x48, 0x4f, 0x79, 0x07,
+ 0xc7, 0x2f, 0xe9, 0x6d, 0xd8, 0x0d, 0x9c, 0xa9, 0xcf, 0x25, 0xc6, 0xef,
+ 0xd9, 0xde, 0xbc, 0x8e, 0x5f, 0xde, 0x4d, 0x4f, 0x8b, 0x39, 0x50, 0xcc,
+ 0x15, 0x0c, 0x35, 0x32, 0x1e, 0xea, 0xc2, 0x9f, 0xe8, 0x77, 0xa4, 0xa1,
+ 0xfd, 0x46, 0x8c, 0xc2, 0x6e, 0xc6, 0x64, 0xf0, 0xb2, 0x18, 0xd9, 0x77,
+ 0x18, 0x00, 0x1a, 0x5a, 0x11, 0x70, 0x13, 0xde, 0x75, 0xe1, 0xca, 0x39,
+ 0x7f, 0xdc, 0xbc, 0x38, 0xde, 0x26, 0xce, 0x53, 0x54, 0x78, 0xb3, 0x05,
+ 0xd7, 0x0c, 0x88, 0x88, 0x60, 0xa3, 0x97, 0xf6, 0x32, 0x3a, 0xfd, 0x39,
+ 0x77, 0x29, 0x8e, 0x57, 0x23, 0xc6, 0x09, 0x65, 0xff, 0xf7, 0xd2, 0x18,
+ 0xe4, 0xc1, 0x85, 0x7c, 0x93, 0x9c, 0xa8, 0x46, 0x46, 0x28, 0xa1, 0x25,
+ 0xfb, 0x5c, 0x87, 0x8b, 0x67, 0x2f, 0xba, 0xff, 0xc1, 0xcb, 0xdd, 0xcd,
+ 0x1c, 0xa8, 0x3e, 0xb7, 0x2d, 0xe0, 0x22, 0xbf, 0xa7, 0x9a, 0x5c, 0x36,
+ 0xa7, 0x39, 0x7e, 0x62, 0x07, 0x02, 0x72, 0xd3, 0x1c, 0xba, 0x18, 0x72,
+ 0xde, 0x39, 0x5a, 0x34, 0xee, 0x2d, 0x41, 0x3d, 0x9e, 0x9c, 0xde, 0xd4,
+ 0x4c, 0x72, 0xf6, 0xdf, 0xe3, 0x94, 0xe6, 0xeb, 0xc3, 0xb7, 0x4c, 0xe7,
+ 0x2f, 0xe7, 0x6e, 0x3d, 0x93, 0x9c, 0xbf, 0x93, 0x5f, 0x48, 0x60, 0xe5,
+ 0xfe, 0x0f, 0x63, 0xe9, 0x67, 0x8e, 0x57, 0x4f, 0x87, 0xc5, 0xb7, 0xfe,
+ 0x69, 0x03, 0xed, 0x27, 0x1c, 0x09, 0xcb, 0x86, 0x63, 0x94, 0xd5, 0x2a,
+ 0x53, 0x83, 0x7c, 0x84, 0x02, 0x2e, 0x30, 0x80, 0x45, 0xc1, 0x08, 0xf6,
+ 0x84, 0x4a, 0x20, 0xdf, 0xe6, 0xf2, 0x42, 0x07, 0xd9, 0xcb, 0xf7, 0xcd,
+ 0xb8, 0xfe, 0x72, 0xe1, 0x54, 0xe5, 0xb6, 0x87, 0x82, 0x02, 0xab, 0xff,
+ 0xf3, 0x07, 0x17, 0xf7, 0x85, 0xfa, 0xc8, 0xcf, 0x1c, 0xbf, 0xfe, 0xc9,
+ 0xdc, 0x57, 0xcb, 0x70, 0xc7, 0xfb, 0xc7, 0x2a, 0x11, 0x4d, 0xa5, 0x4b,
+ 0xff, 0xec, 0xe2, 0xf2, 0xc1, 0x08, 0xc4, 0x83, 0xb3, 0x97, 0xff, 0xff,
+ 0xc9, 0xd0, 0x31, 0x8f, 0x2e, 0x5c, 0x03, 0x8c, 0x85, 0xf2, 0x52, 0x79,
+ 0xdf, 0xe3, 0x97, 0xff, 0xe8, 0xd4, 0x2f, 0x19, 0x0b, 0x92, 0x6c, 0x0c,
+ 0x39, 0x50, 0xaa, 0x3a, 0x67, 0x4e, 0xc3, 0x34, 0x48, 0xbc, 0x9e, 0xd2,
+ 0x11, 0x17, 0xf6, 0xb2, 0x15, 0x81, 0x39, 0x78, 0x5d, 0x87, 0x2e, 0xfe,
+ 0x0e, 0x5f, 0xfd, 0xd6, 0x67, 0xd2, 0xdb, 0xc7, 0xd2, 0x39, 0x72, 0x93,
+ 0x9c, 0xa4, 0x3d, 0xf1, 0x46, 0xa9, 0x23, 0x75, 0x0b, 0x04, 0x6f, 0xce,
+ 0xd4, 0xd5, 0x42, 0x2c, 0x41, 0xa9, 0x84, 0x9f, 0x09, 0x0a, 0xf6, 0xad,
+ 0xcf, 0x86, 0x94, 0xb1, 0xc2, 0xec, 0xf1, 0x3b, 0x63, 0x3c, 0x7f, 0xb2,
+ 0x84, 0xb8, 0x67, 0xa0, 0x72, 0xb0, 0xd0, 0x56, 0x57, 0x6a, 0xe7, 0xcb,
+ 0xfe, 0x9d, 0x7d, 0x49, 0x75, 0x13, 0x4a, 0x90, 0xd4, 0xf0, 0x53, 0x25,
+ 0xe2, 0xf6, 0xb3, 0x92, 0x79, 0x71, 0x3f, 0xca, 0x3b, 0xe1, 0xdc, 0x86,
+ 0x9b, 0x3d, 0xba, 0x42, 0xaf, 0xa9, 0xae, 0xe0, 0x8e, 0x4b, 0x8c, 0x3b,
+ 0xdb, 0x84, 0xc3, 0x49, 0x50, 0x6a, 0x4b, 0x1c, 0xe0, 0x8d, 0x06, 0xff,
+ 0xfe, 0x02, 0xf9, 0xfd, 0xed, 0x46, 0x7d, 0xc3, 0x05, 0xdd, 0x53, 0x95,
+ 0xcd, 0x57, 0xc2, 0x4a, 0x93, 0xbf, 0x9d, 0x3d, 0xb4, 0x13, 0x97, 0x93,
+ 0x58, 0x72, 0x9a, 0xcf, 0x1b, 0x65, 0x77, 0xed, 0x2d, 0xdd, 0x66, 0x8a,
+ 0x75, 0x76, 0x7c, 0x72, 0xff, 0xf0, 0x00, 0x28, 0x31, 0xd4, 0x66, 0x6c,
+ 0xe5, 0xb9, 0xc2, 0x2d, 0xf0, 0x97, 0xe3, 0x46, 0x0b, 0xdf, 0xfc, 0x9a,
+ 0xe6, 0xd1, 0xe7, 0xf6, 0xdf, 0xf3, 0x97, 0xed, 0x2d, 0xdd, 0x66, 0x8a,
+ 0x8d, 0x7f, 0xe7, 0x97, 0x3c, 0xd2, 0xdd, 0xd6, 0x68, 0x9a, 0x17, 0xff,
+ 0x87, 0x26, 0x93, 0xea, 0x43, 0x9c, 0x5c, 0xe5, 0xf0, 0xc6, 0x7c, 0x72,
+ 0xb1, 0x1d, 0x6c, 0x34, 0xda, 0x67, 0x92, 0xaf, 0xf2, 0x8f, 0xc7, 0x9f,
+ 0x92, 0x73, 0x95, 0xcc, 0xfd, 0x60, 0xf2, 0xfd, 0xa5, 0xbb, 0xac, 0xd1,
+ 0x57, 0xaf, 0xec, 0xe3, 0x03, 0xd0, 0x1c, 0xbf, 0x90, 0x21, 0x8d, 0x41,
+ 0xcb, 0xff, 0xfb, 0xef, 0xc4, 0x0c, 0x50, 0x21, 0x8f, 0xd9, 0x19, 0xe3,
+ 0x96, 0xe7, 0x88, 0xed, 0xd1, 0xa7, 0x4b, 0x94, 0x2c, 0xbf, 0x69, 0x6e,
+ 0xeb, 0x34, 0x56, 0xcb, 0xfe, 0x97, 0x3c, 0xd2, 0xdd, 0xd6, 0x68, 0x90,
+ 0x56, 0xe7, 0x87, 0xf6, 0xe6, 0x97, 0xff, 0x73, 0x79, 0x73, 0xcd, 0x2d,
+ 0xdd, 0x66, 0x89, 0x0d, 0x7f, 0xed, 0xf3, 0xcf, 0x20, 0x70, 0x66, 0x39,
+ 0x79, 0xdd, 0x67, 0x8c, 0x0d, 0x50, 0x7d, 0x0b, 0x40, 0xbb, 0xad, 0x67,
+ 0x2f, 0xfd, 0x2e, 0xc7, 0xb6, 0xd4, 0xed, 0xab, 0x13, 0x97, 0xde, 0xf6,
+ 0x70, 0x1c, 0xbf, 0xfd, 0xc2, 0xdc, 0x2c, 0xd4, 0xf6, 0x18, 0x2f, 0xd4,
+ 0xd1, 0xcb, 0x7c, 0x72, 0xe4, 0x13, 0x97, 0xfb, 0x19, 0x8b, 0x17, 0x6b,
+ 0x39, 0x7f, 0x40, 0x63, 0xce, 0x13, 0x97, 0xbb, 0x9b, 0x39, 0x67, 0x39,
+ 0x41, 0x35, 0x9e, 0x1c, 0xa0, 0xa3, 0x52, 0x61, 0x2d, 0x8a, 0xf8, 0xd1,
+ 0x45, 0x8b, 0xef, 0x6d, 0x38, 0x9c, 0xbf, 0xf9, 0x06, 0x78, 0x55, 0x4f,
+ 0xff, 0x8f, 0x8e, 0x5f, 0x60, 0xff, 0xb3, 0x97, 0xff, 0x0b, 0xb7, 0xd4,
+ 0x79, 0x79, 0x27, 0x39, 0x7d, 0x3e, 0xfe, 0x43, 0x95, 0x88, 0x8a, 0xd1,
+ 0x16, 0xd1, 0x2f, 0xce, 0x15, 0x20, 0x4e, 0x5f, 0xfb, 0x5e, 0x50, 0x5d,
+ 0x78, 0x2b, 0x39, 0x7c, 0xb7, 0x75, 0x9a, 0x2c, 0x45, 0xfb, 0x5a, 0x71,
+ 0xf1, 0xcb, 0xe7, 0x0f, 0x40, 0x72, 0xf2, 0x23, 0x67, 0x2f, 0x00, 0x64,
+ 0x72, 0xff, 0x2e, 0x33, 0x5f, 0xff, 0xe3, 0x95, 0x3a, 0x69, 0x38, 0x4f,
+ 0xa3, 0xe6, 0x17, 0x74, 0x9c, 0x48, 0xbc, 0x38, 0x01, 0xcb, 0xf6, 0x6a,
+ 0x05, 0x53, 0x96, 0x43, 0x96, 0x43, 0x96, 0x92, 0xa6, 0x83, 0xf1, 0x0b,
+ 0xf2, 0x8d, 0x33, 0x50, 0x72, 0xfd, 0xef, 0x40, 0xce, 0x72, 0xf6, 0xe0,
+ 0x4e, 0x54, 0x1f, 0x6e, 0x15, 0x21, 0x45, 0x2a, 0x8c, 0x2e, 0xc2, 0x5a,
+ 0xff, 0xe8, 0xcd, 0xe0, 0x85, 0x3f, 0x81, 0x39, 0x78, 0x62, 0x73, 0x94,
+ 0x27, 0xba, 0x04, 0x1b, 0xe8, 0xd4, 0x30, 0xe5, 0x48, 0xf0, 0xb6, 0x43,
+ 0x79, 0x8f, 0xe3, 0x97, 0xff, 0xde, 0xcf, 0xa4, 0x20, 0xf3, 0xa0, 0xc0,
+ 0x4e, 0x5c, 0x9f, 0x9c, 0xbc, 0xf1, 0xf1, 0xca, 0xd2, 0x27, 0x7c, 0x38,
+ 0xd1, 0x3b, 0x80, 0x5e, 0xff, 0xfc, 0xfa, 0x93, 0x06, 0x35, 0x01, 0xc9,
+ 0xa3, 0xa7, 0x2f, 0xb8, 0x81, 0xf6, 0x72, 0xc8, 0x72, 0xa4, 0x88, 0x84,
+ 0x54, 0x98, 0x92, 0xff, 0x83, 0xdc, 0x66, 0x3e, 0xa7, 0x39, 0x7e, 0xf7,
+ 0x9e, 0x5b, 0x39, 0x7f, 0xe0, 0x67, 0xc1, 0xe3, 0xdc, 0x79, 0x8e, 0x57,
+ 0xc7, 0xd5, 0xc4, 0xa2, 0xd2, 0x39, 0x7d, 0x98, 0xde, 0xce, 0x54, 0x1b,
+ 0x3f, 0x08, 0xdc, 0x01, 0x39, 0x50, 0x99, 0x8e, 0x42, 0x8f, 0x4b, 0x1b,
+ 0x20, 0xbf, 0xdb, 0x53, 0x35, 0x99, 0x31, 0xcb, 0xfe, 0x7f, 0x6c, 0x20,
+ 0x7d, 0x48, 0xe5, 0xf8, 0x7c, 0x20, 0x9c, 0xe5, 0x42, 0x25, 0x44, 0xd0,
+ 0x07, 0x37, 0xf6, 0xa5, 0xfe, 0x64, 0xc7, 0x2f, 0x9e, 0x11, 0xa1, 0xca,
+ 0xc3, 0xd1, 0xd1, 0x7d, 0xf4, 0x94, 0xec, 0x1c, 0xbd, 0xa8, 0x91, 0xca,
+ 0x73, 0x7f, 0xc4, 0x8e, 0xfe, 0x86, 0x62, 0x6a, 0x63, 0x97, 0xca, 0x47,
+ 0x06, 0xce, 0x5f, 0xb0, 0x3d, 0x8e, 0x9c, 0xbe, 0xd2, 0x36, 0xd6, 0x72,
+ 0x84, 0xf3, 0x76, 0x4f, 0x7f, 0xfb, 0x48, 0xc8, 0xfb, 0xb0, 0x11, 0x76,
+ 0xb3, 0x94, 0x14, 0x70, 0x6d, 0xcf, 0xc4, 0x35, 0x09, 0xdf, 0xa3, 0x07,
+ 0x48, 0x9e, 0x30, 0xdb, 0xfb, 0xe5, 0xf6, 0x3e, 0xe0, 0x39, 0x7f, 0x20,
+ 0xbb, 0x23, 0xa7, 0x2f, 0xff, 0x43, 0x22, 0x41, 0x18, 0xeb, 0xe6, 0x8e,
+ 0x51, 0xca, 0x91, 0xe9, 0x34, 0x47, 0xbd, 0xec, 0xfc, 0xe5, 0xfc, 0xc4,
+ 0xde, 0xd0, 0x27, 0x2f, 0x3e, 0x95, 0x39, 0x40, 0x3c, 0xa6, 0xcb, 0x6f,
+ 0xf2, 0xc7, 0x38, 0x8e, 0x6c, 0xe5, 0xfe, 0x6b, 0xe4, 0xa4, 0x0b, 0xaa,
+ 0x72, 0xff, 0x49, 0xf0, 0x73, 0xdb, 0x39, 0x58, 0x7d, 0x5f, 0x1c, 0xdf,
+ 0xfb, 0x3e, 0x97, 0x63, 0x6a, 0xf6, 0x0e, 0x54, 0x2a, 0x5d, 0x91, 0x9f,
+ 0xcf, 0xb3, 0x12, 0x69, 0x9f, 0xa4, 0x63, 0x09, 0xde, 0x02, 0x2b, 0x34,
+ 0x39, 0x74, 0xb6, 0x72, 0xcf, 0x23, 0x55, 0xf0, 0x9d, 0xf7, 0x90, 0x5b,
+ 0x29, 0x60, 0x1c, 0xb4, 0x61, 0xb3, 0xe9, 0x15, 0xff, 0x38, 0xfb, 0x7f,
+ 0x6d, 0xda, 0xce, 0x53, 0xa2, 0xef, 0xf5, 0xa0, 0x12, 0xdf, 0xf9, 0x80,
+ 0x9b, 0xed, 0xc4, 0xc9, 0xc4, 0xe5, 0xfe, 0xec, 0x30, 0x63, 0xe9, 0x1c,
+ 0xbf, 0xba, 0x9b, 0xd6, 0xb0, 0xe5, 0xff, 0x93, 0x3d, 0xbd, 0x66, 0xe3,
+ 0xe3, 0x97, 0xfe, 0x86, 0xd4, 0x9f, 0x78, 0xc8, 0x6b, 0x39, 0x73, 0xb6,
+ 0x72, 0x82, 0x8f, 0x95, 0x99, 0xf4, 0xb7, 0xc7, 0xdc, 0x51, 0x2e, 0xcd,
+ 0x9c, 0xa8, 0x4e, 0x7f, 0x23, 0x3d, 0x51, 0x32, 0xff, 0xee, 0xba, 0x7a,
+ 0x58, 0xa8, 0xe7, 0xe7, 0x2f, 0x77, 0x1b, 0x39, 0x7f, 0x98, 0x9b, 0xea,
+ 0x42, 0x1c, 0xbf, 0x0c, 0xd1, 0xd8, 0x39, 0x7e, 0xfd, 0xf8, 0xe0, 0x4e,
+ 0x5f, 0xb3, 0xbf, 0x3b, 0x59, 0xcb, 0xef, 0xf7, 0x02, 0x72, 0xff, 0x6b,
+ 0xae, 0x9b, 0x4e, 0x27, 0x2e, 0x55, 0x0e, 0x54, 0x1f, 0x6e, 0x11, 0x39,
+ 0xa5, 0xff, 0xdd, 0xc1, 0x17, 0xf7, 0x29, 0x43, 0x0e, 0x52, 0x27, 0xd6,
+ 0xd6, 0x88, 0xc1, 0xd7, 0x31, 0xfc, 0x9c, 0x4a, 0xb7, 0x09, 0x8f, 0x16,
+ 0x5f, 0xcd, 0xc6, 0xb4, 0xf3, 0x1c, 0xbf, 0xe0, 0xc2, 0xd4, 0xff, 0xf8,
+ 0xf8, 0xe5, 0xff, 0x3e, 0xb1, 0x88, 0xd2, 0x18, 0x72, 0x96, 0x7e, 0xc0,
+ 0x3d, 0xbe, 0xcd, 0x66, 0xce, 0x5f, 0x7a, 0x3e, 0x91, 0xcb, 0xf9, 0x3f,
+ 0x68, 0x29, 0xf9, 0xca, 0x9c, 0xf4, 0xf4, 0x47, 0x7c, 0x00, 0xf5, 0x0e,
+ 0x5e, 0xf6, 0x28, 0x72, 0xa1, 0x39, 0xdc, 0x85, 0x2f, 0x48, 0x9d, 0xd3,
+ 0x64, 0x7c, 0x04, 0x57, 0xf0, 0xc4, 0xa3, 0x8c, 0x1c, 0xba, 0x3f, 0x39,
+ 0x7f, 0x71, 0xd3, 0xc2, 0x34, 0x39, 0x72, 0x4e, 0x72, 0xd8, 0x72, 0x91,
+ 0x13, 0x73, 0x16, 0xb0, 0x5d, 0xcc, 0x04, 0x5e, 0xfa, 0x7f, 0x62, 0xce,
+ 0x5f, 0xe7, 0x55, 0x4e, 0xf6, 0x24, 0x72, 0x9c, 0xf6, 0x1a, 0x11, 0xdf,
+ 0xfb, 0xb8, 0x10, 0xa7, 0xd9, 0xf7, 0x8e, 0x5f, 0xdc, 0x82, 0xa3, 0xeb,
+ 0x47, 0x2a, 0x73, 0xf1, 0x0a, 0x05, 0xfe, 0x0e, 0x7b, 0xb0, 0x2b, 0x39,
+ 0x7c, 0xf0, 0x8d, 0x0e, 0x5f, 0xf0, 0x79, 0x66, 0xe3, 0x35, 0xf9, 0xcb,
+ 0xdd, 0x53, 0x67, 0x2b, 0x0f, 0x65, 0xce, 0xef, 0xf2, 0x07, 0xc2, 0xff,
+ 0x6c, 0xe5, 0xfe, 0xf6, 0xd3, 0xec, 0xfb, 0xc7, 0x2e, 0x9e, 0x0e, 0x54,
+ 0x1f, 0xfb, 0x99, 0x80, 0xd6, 0xa1, 0x39, 0xc9, 0xc8, 0xc2, 0x65, 0xd7,
+ 0xb1, 0x84, 0xfd, 0x35, 0x2d, 0xd6, 0x6b, 0x56, 0x35, 0xc3, 0x24, 0xb5,
+ 0x02, 0x58, 0x8c, 0xc2, 0x74, 0xc9, 0x12, 0x06, 0x1a, 0x79, 0x1b, 0xc2,
+ 0xae, 0x2b, 0x8c, 0x27, 0xe8, 0x64, 0x24, 0x2f, 0xe6, 0x86, 0x56, 0xa3,
+ 0x61, 0x64, 0x35, 0xbb, 0x28, 0xf9, 0xe5, 0x4f, 0x7f, 0x1b, 0x00, 0xc7,
+ 0x9f, 0xb9, 0x44, 0x3e, 0x94, 0x2a, 0x08, 0x7c, 0x34, 0x85, 0x02, 0x92,
+ 0x8c, 0x2f, 0xdc, 0x0e, 0xb8, 0xd1, 0xcb, 0xff, 0x24, 0x7b, 0xae, 0xae,
+ 0x0f, 0xe7, 0x2f, 0xff, 0x3e, 0xb9, 0x3f, 0xb9, 0x7b, 0xe5, 0xa0, 0x9c,
+ 0xae, 0xa2, 0x33, 0x89, 0xf5, 0xfd, 0x9e, 0x84, 0x66, 0xce, 0x5f, 0xe0,
+ 0xc4, 0xb3, 0x59, 0xb3, 0x97, 0xff, 0xd9, 0xad, 0x02, 0x5a, 0xc8, 0xfa,
+ 0x48, 0xc3, 0x97, 0xb6, 0xa6, 0xce, 0x5f, 0xff, 0x67, 0xd2, 0xf0, 0x27,
+ 0xe7, 0xd7, 0x62, 0x6c, 0xe5, 0xff, 0xbd, 0x0c, 0xdc, 0x24, 0xef, 0xe3,
+ 0x97, 0xf3, 0xb5, 0xbe, 0x7d, 0xe3, 0x95, 0xf1, 0xf7, 0x74, 0xfa, 0xff,
+ 0x3e, 0x05, 0x3e, 0x17, 0x39, 0x58, 0x7a, 0x80, 0x23, 0xb9, 0xb1, 0x39,
+ 0x7b, 0xc3, 0x07, 0x2e, 0xef, 0x38, 0x56, 0x21, 0x90, 0xb6, 0x98, 0x95,
+ 0x85, 0x9d, 0x32, 0x75, 0x01, 0x1e, 0xdc, 0x62, 0xcd, 0x90, 0xa8, 0x2f,
+ 0x5c, 0xd7, 0x62, 0xa2, 0x73, 0x96, 0xfe, 0xcd, 0x2d, 0xdd, 0x66, 0x8b,
+ 0x35, 0x7f, 0xf6, 0xba, 0xfc, 0xd8, 0x09, 0xba, 0x81, 0x39, 0x7f, 0xe8,
+ 0xd7, 0xfe, 0xdf, 0x71, 0x02, 0x72, 0xfd, 0x93, 0x4a, 0x3e, 0x39, 0x7c,
+ 0x82, 0xf3, 0x9c, 0xae, 0xa2, 0x24, 0x4f, 0xf6, 0x53, 0x6e, 0x9c, 0xba,
+ 0x3a, 0x72, 0xfe, 0x1c, 0xe3, 0xd7, 0x91, 0xcb, 0x73, 0x9c, 0xf5, 0x7a,
+ 0x23, 0xe1, 0x6a, 0xe6, 0x8b, 0xce, 0x08, 0x42, 0x57, 0x34, 0xfc, 0xd0,
+ 0xe5, 0xe3, 0x8d, 0xbe, 0x46, 0x29, 0xa3, 0x97, 0xd0, 0xbc, 0xe9, 0xcb,
+ 0xe4, 0x1d, 0x00, 0xe5, 0xfe, 0x8e, 0x2a, 0x78, 0x63, 0xf3, 0x97, 0xca,
+ 0x0e, 0x6c, 0xe5, 0xcc, 0xe7, 0x08, 0xbd, 0x42, 0x39, 0x88, 0x7a, 0x42,
+ 0xe6, 0xd7, 0x62, 0x1c, 0xbb, 0x02, 0x72, 0xff, 0xcf, 0x2e, 0x79, 0xa5,
+ 0xbb, 0xac, 0xd1, 0x40, 0x2f, 0xf2, 0x32, 0x1a, 0xfb, 0x93, 0x9c, 0xb7,
+ 0x39, 0x22, 0xb7, 0x05, 0x58, 0x2d, 0xd4, 0xcb, 0xa4, 0xc3, 0x97, 0xcf,
+ 0xaf, 0xa4, 0x72, 0xfd, 0x1f, 0x79, 0xf4, 0x72, 0xfd, 0xed, 0xc9, 0x3f,
+ 0x39, 0x52, 0x44, 0x5e, 0x0b, 0xa1, 0x1b, 0x94, 0x5f, 0xb9, 0xe4, 0xd1,
+ 0x23, 0x97, 0xfd, 0x1e, 0xee, 0x33, 0x35, 0x87, 0x2f, 0xa6, 0xcc, 0x59,
+ 0xcb, 0xf7, 0x95, 0x7d, 0xf3, 0xd1, 0xec, 0xa8, 0x6f, 0x52, 0x46, 0x33,
+ 0x70, 0x83, 0xae, 0x69, 0x94, 0xc4, 0x60, 0x17, 0x03, 0xa7, 0x2f, 0xff,
+ 0xdc, 0x63, 0xa8, 0x1e, 0xc4, 0xb6, 0xfd, 0x4d, 0x9c, 0xbf, 0xb7, 0x0c,
+ 0x18, 0x98, 0xe5, 0xba, 0x72, 0xf2, 0x83, 0x31, 0xcb, 0x7b, 0x0d, 0x7f,
+ 0xe2, 0x37, 0x64, 0xe7, 0x2b, 0x0d, 0xf0, 0x93, 0xd2, 0x26, 0x1f, 0xfa,
+ 0xb0, 0xc2, 0x6a, 0xee, 0x5b, 0x39, 0x78, 0x01, 0xc3, 0x97, 0xfb, 0x35,
+ 0xe1, 0x86, 0x6c, 0xe5, 0x9a, 0x1c, 0xa4, 0x3e, 0x1e, 0x8e, 0x7e, 0x65,
+ 0x7c, 0xb7, 0x75, 0x9a, 0x2d, 0xf5, 0xe6, 0x8f, 0xe3, 0x97, 0xf2, 0x9e,
+ 0x75, 0xbe, 0x8e, 0x56, 0x8f, 0xe9, 0x85, 0xdf, 0x8f, 0x5c, 0xab, 0x67,
+ 0x2f, 0xb0, 0x52, 0x63, 0x97, 0xbb, 0x1a, 0x39, 0x7e, 0xea, 0x6b, 0xae,
+ 0x72, 0xff, 0xf7, 0x62, 0x7f, 0x67, 0x47, 0x3d, 0xd4, 0x39, 0x79, 0x98,
+ 0x13, 0x96, 0x61, 0xcb, 0xfe, 0xec, 0x4e, 0x1c, 0x6f, 0x7c, 0xe1, 0x17,
+ 0x38, 0x39, 0x31, 0x3b, 0xa4, 0xa8, 0x39, 0x7e, 0xf4, 0xb6, 0xa6, 0xce,
+ 0x5e, 0xdf, 0x42, 0x72, 0xfc, 0xa7, 0x86, 0x3f, 0x39, 0x4c, 0x3c, 0x6e,
+ 0x23, 0xb7, 0xff, 0x7b, 0x69, 0xb8, 0x1c, 0xf7, 0x50, 0xe5, 0xe1, 0xce,
+ 0x9c, 0xa6, 0x1e, 0xef, 0x14, 0x2b, 0xf0, 0x61, 0xac, 0x0c, 0x39, 0x7f,
+ 0xcf, 0xb8, 0xc1, 0x0f, 0x60, 0xe5, 0xff, 0xd8, 0xcd, 0x67, 0xdd, 0x17,
+ 0x6b, 0x9c, 0xe5, 0xdb, 0xde, 0x8f, 0xf8, 0x4d, 0xaa, 0x13, 0x7b, 0xc8,
+ 0x40, 0xa1, 0x23, 0xc2, 0xa6, 0xf9, 0xd0, 0x7c, 0x72, 0xfd, 0xfe, 0xfd,
+ 0x0c, 0x39, 0x7b, 0x51, 0xe3, 0x97, 0xf4, 0xce, 0x1e, 0xa3, 0x0e, 0x5f,
+ 0xde, 0x4c, 0x0c, 0x30, 0xe5, 0x78, 0xf6, 0x9b, 0x2e, 0xbb, 0x62, 0x72,
+ 0xfe, 0xfb, 0x70, 0xbc, 0x61, 0xca, 0x84, 0xc1, 0xb4, 0x52, 0xee, 0xdb,
+ 0x23, 0x00, 0xb5, 0xfc, 0x93, 0x40, 0x8c, 0x1c, 0xbe, 0xea, 0xa1, 0x61,
+ 0xcb, 0x48, 0xe5, 0xfe, 0xff, 0xf0, 0x6d, 0xaf, 0x3e, 0x39, 0x58, 0x79,
+ 0x6e, 0x23, 0x58, 0x88, 0xf1, 0x6f, 0xbf, 0xde, 0x4d, 0xba, 0xde, 0x73,
+ 0x94, 0xd5, 0xb2, 0x32, 0x22, 0x32, 0x69, 0x1a, 0x85, 0xeb, 0x21, 0x53,
+ 0xf1, 0x82, 0x0c, 0xcd, 0x0d, 0xad, 0x3d, 0xf6, 0x3e, 0xbf, 0xd1, 0x06,
+ 0x32, 0x6d, 0xa4, 0xfa, 0x17, 0x4a, 0x10, 0xdf, 0xcf, 0xf7, 0x36, 0x3f,
+ 0x8e, 0x57, 0x34, 0xc9, 0x86, 0x1e, 0xd7, 0xf0, 0x79, 0xef, 0xdb, 0xf8,
+ 0xe5, 0xcd, 0x53, 0x56, 0x72, 0xf3, 0x1f, 0xe3, 0x97, 0xbf, 0x7e, 0x9c,
+ 0xbb, 0x8a, 0x1c, 0xbe, 0xd6, 0xb1, 0x43, 0x97, 0xfd, 0x12, 0x6d, 0xf5,
+ 0xac, 0x50, 0xe5, 0xfb, 0x73, 0xe3, 0x7c, 0xda, 0x94, 0x68, 0x41, 0x0e,
+ 0x0e, 0xcc, 0x3a, 0xe3, 0x02, 0x47, 0x50, 0x9b, 0xe2, 0x46, 0x05, 0x7f,
+ 0xff, 0xdc, 0x3a, 0x78, 0x0f, 0x3f, 0x3c, 0x97, 0x63, 0x59, 0x82, 0xa9,
+ 0xcb, 0xff, 0xff, 0xc8, 0xb7, 0xd3, 0xf6, 0x59, 0xec, 0x0e, 0xdd, 0x99,
+ 0xa9, 0xe3, 0xe3, 0x97, 0xed, 0x2d, 0xdd, 0x66, 0x8a, 0x51, 0x7f, 0xfc,
+ 0xfe, 0x1c, 0x9f, 0x51, 0xd4, 0xee, 0x68, 0xe5, 0xe7, 0x97, 0x38, 0x47,
+ 0xce, 0x3b, 0xfe, 0x69, 0x7f, 0xd2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x12,
+ 0x72, 0x98, 0x88, 0x97, 0x42, 0xbf, 0xda, 0xe7, 0x9d, 0x89, 0x9c, 0xe5,
+ 0x73, 0x3d, 0x77, 0x22, 0xa8, 0x86, 0x8c, 0x34, 0xf3, 0xc5, 0x52, 0x94,
+ 0x44, 0x1c, 0x47, 0x4a, 0xe4, 0x65, 0x4a, 0xa2, 0x2e, 0x3a, 0xa4, 0x8c,
+ 0x41, 0xae, 0x18, 0x13, 0x14, 0x6a, 0x17, 0x8c, 0xb4, 0x0f, 0x1d, 0x94,
+ 0x44, 0xf0, 0xf4, 0xfe, 0x30, 0x31, 0x8f, 0xe3, 0x74, 0xa1, 0x9f, 0x47,
+ 0x4c, 0x02, 0x8e, 0x32, 0x91, 0xaf, 0xda, 0x5b, 0xba, 0xcd, 0x10, 0xfa,
+ 0xff, 0xcf, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x29, 0xad, 0xcf, 0x11,
+ 0x00, 0xc3, 0x4b, 0xfd, 0xcf, 0x34, 0xb7, 0x75, 0x9a, 0x22, 0x75, 0xf9,
+ 0x3d, 0xb0, 0x30, 0xe5, 0xee, 0xc4, 0xc7, 0x2a, 0x63, 0xc5, 0xe9, 0x45,
+ 0xff, 0xee, 0x14, 0xab, 0x6d, 0x73, 0x87, 0x86, 0xe5, 0xcb, 0xad, 0x0e,
+ 0x5f, 0xb4, 0xb7, 0x75, 0x9a, 0x23, 0x15, 0xff, 0xfc, 0x01, 0x75, 0x79,
+ 0x79, 0x58, 0x19, 0x67, 0x51, 0x87, 0x2f, 0xa1, 0x8b, 0xfc, 0xe5, 0xff,
+ 0xf4, 0xa7, 0xe1, 0x50, 0xd5, 0xce, 0xbd, 0x72, 0xe5, 0xd6, 0x87, 0x2b,
+ 0xa8, 0x88, 0xfc, 0x8e, 0xfe, 0xcf, 0x46, 0x7d, 0xe3, 0x97, 0xfe, 0xf2,
+ 0xb0, 0x32, 0xce, 0xa3, 0x0e, 0x5f, 0xf2, 0xb0, 0x32, 0xce, 0xa3, 0x0e,
+ 0x5f, 0x00, 0x5d, 0x5e, 0x47, 0xed, 0xe3, 0xeb, 0xf6, 0xbf, 0x4e, 0xc1,
+ 0xca, 0x61, 0xf1, 0x80, 0xee, 0xf9, 0x3e, 0x93, 0x56, 0x72, 0xfd, 0xca,
+ 0x61, 0x80, 0x9c, 0xb7, 0x38, 0x56, 0x7d, 0x22, 0x3c, 0x64, 0x61, 0xa7,
+ 0x61, 0xca, 0x24, 0x9b, 0x8c, 0x1b, 0xc4, 0x4d, 0x0a, 0x2f, 0xff, 0x73,
+ 0x63, 0xcb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x4f, 0x2b, 0xe8, 0xe3, 0x1d,
+ 0x39, 0x7d, 0x03, 0x2d, 0x9c, 0xbf, 0x75, 0x07, 0x38, 0x9c, 0xad, 0x1f,
+ 0x67, 0xe4, 0x6a, 0x10, 0xdf, 0x01, 0xf5, 0x23, 0x97, 0xe7, 0x0f, 0x63,
+ 0x67, 0x2d, 0xcc, 0x27, 0x92, 0x24, 0x55, 0xcd, 0x14, 0x6d, 0xbd, 0x54,
+ 0x2f, 0x07, 0xce, 0x55, 0x29, 0x78, 0x9d, 0x84, 0x97, 0xa3, 0x69, 0xbf,
+ 0x69, 0x6e, 0xeb, 0x34, 0x44, 0x0b, 0xff, 0x3c, 0xb9, 0xe6, 0x96, 0xee,
+ 0xb3, 0x44, 0xa8, 0xbf, 0xb4, 0x0e, 0xc0, 0xac, 0xe5, 0xfc, 0xb4, 0xce,
+ 0x0e, 0xc1, 0xca, 0x83, 0xdc, 0xc2, 0xdb, 0x73, 0xc4, 0x7e, 0x30, 0xd0,
+ 0x61, 0x51, 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0x8a, 0x17, 0xa3, 0xfc, 0x39,
+ 0x6e, 0x78, 0x7a, 0x0a, 0x1a, 0x5f, 0xee, 0x79, 0xa5, 0xbb, 0xac, 0xd1,
+ 0x19, 0x2f, 0xda, 0x5b, 0xba, 0xcd, 0x13, 0x2a, 0xfd, 0x2c, 0xf3, 0xac,
+ 0xe5, 0xfb, 0x9b, 0x1e, 0x5c, 0xf0, 0xf6, 0xfe, 0x34, 0xbf, 0x69, 0x6e,
+ 0xeb, 0x34, 0x54, 0x8b, 0x09, 0xcb, 0x28, 0x72, 0xdc, 0xf0, 0xf5, 0x9a,
+ 0xcd, 0x00, 0x21, 0x7f, 0xb9, 0xe6, 0x96, 0xee, 0xb3, 0x45, 0x74, 0xbf,
+ 0xdc, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0xc5, 0x5f, 0xfc, 0xc7, 0x97, 0x3c,
+ 0xd2, 0xdd, 0xd6, 0x68, 0x9e, 0x97, 0x9b, 0x75, 0x9c, 0xbf, 0xbb, 0x09,
+ 0xa4, 0xe1, 0xce, 0x5f, 0xa1, 0x1a, 0x27, 0x01, 0xcb, 0x9b, 0xe7, 0x87,
+ 0xf2, 0xb1, 0xd7, 0x31, 0xbf, 0xff, 0xfc, 0x1c, 0x6f, 0x98, 0xe2, 0xaa,
+ 0xbf, 0xb6, 0x83, 0x34, 0x2f, 0x59, 0xf1, 0xcb, 0xff, 0xfb, 0x33, 0xa8,
+ 0xbe, 0xe7, 0x31, 0xcf, 0x75, 0x1b, 0x39, 0x7f, 0xfe, 0x98, 0x61, 0x9c,
+ 0xf3, 0x68, 0xd8, 0x5d, 0xd5, 0x39, 0x76, 0xfc, 0x72, 0xec, 0xd9, 0xcb,
+ 0xb7, 0xf9, 0xcb, 0xf0, 0xbb, 0x06, 0x0e, 0x5f, 0xc0, 0xdf, 0x5e, 0x5c,
+ 0xda, 0xb3, 0xea, 0x71, 0x76, 0xc5, 0x94, 0x18, 0xbd, 0x3c, 0x35, 0x9c,
+ 0xbb, 0x5e, 0x39, 0x7e, 0xcf, 0x6d, 0x18, 0x72, 0xff, 0xf4, 0x7d, 0xec,
+ 0x99, 0x35, 0xed, 0x81, 0xac, 0xe5, 0xe7, 0xfb, 0x9c, 0x22, 0xb5, 0xc8,
+ 0x04, 0x5f, 0xc4, 0xf5, 0x8a, 0x89, 0x35, 0x0c, 0x2d, 0xc6, 0x29, 0x41,
+ 0x56, 0x6e, 0x2f, 0x9e, 0x94, 0xff, 0x5c, 0xd7, 0x1d, 0xa2, 0x19, 0x69,
+ 0x2d, 0xce, 0xfc, 0xd4, 0xa4, 0x03, 0x87, 0x39, 0x7e, 0x4e, 0x8b, 0xcc,
+ 0x72, 0xfd, 0x2c, 0x0f, 0x2c, 0x39, 0x5c, 0x21, 0xe8, 0x41, 0x3d, 0xcc,
+ 0xfc, 0xe5, 0xfb, 0x3c, 0x80, 0xd9, 0xcb, 0x9a, 0x96, 0xa0, 0x72, 0x9a,
+ 0x93, 0xe1, 0x6a, 0x03, 0x1c, 0x28, 0x9e, 0xfd, 0xc2, 0xcd, 0x4e, 0xf5,
+ 0xe3, 0x97, 0xf9, 0x41, 0xcd, 0x6a, 0x16, 0x72, 0x9a, 0x93, 0xe8, 0xe1,
+ 0x8d, 0x6f, 0xb4, 0xcf, 0x7c, 0x72, 0xfe, 0x6a, 0x5a, 0xae, 0x12, 0x24,
+ 0xc3, 0x97, 0x97, 0x9d, 0x29, 0x79, 0x91, 0xb3, 0x97, 0xbf, 0xd4, 0x1c,
+ 0xbf, 0xb3, 0xf4, 0x99, 0x1b, 0x39, 0x7f, 0xe7, 0xdf, 0x2d, 0xef, 0x25,
+ 0x28, 0x39, 0x6d, 0x9c, 0xbf, 0xff, 0x0b, 0xaa, 0x9a, 0x89, 0x4b, 0x37,
+ 0xff, 0xf0, 0x72, 0xff, 0x3f, 0x81, 0x98, 0x2a, 0x9c, 0xa0, 0xa6, 0x10,
+ 0xa9, 0x7c, 0xc8, 0x1d, 0x11, 0xfd, 0x5a, 0xff, 0xfe, 0xd2, 0x70, 0x3b,
+ 0x39, 0xc6, 0xb4, 0x9c, 0x0b, 0x04, 0xe7, 0x2f, 0x93, 0xaa, 0x30, 0xe5,
+ 0xff, 0xe4, 0x57, 0x96, 0x0b, 0xfd, 0xb5, 0x55, 0x73, 0x94, 0xb3, 0xf1,
+ 0x12, 0x3b, 0xff, 0xcf, 0xb1, 0xcf, 0xf9, 0xf5, 0x16, 0xfa, 0x39, 0x70,
+ 0xb6, 0x72, 0xfe, 0x0e, 0x2b, 0xec, 0x59, 0xcb, 0xee, 0xc3, 0x16, 0x72,
+ 0xa0, 0xf9, 0xdc, 0x5f, 0xc5, 0xd7, 0x83, 0x9d, 0x39, 0x7a, 0x64, 0x6c,
+ 0xe5, 0x83, 0x23, 0x74, 0x83, 0x97, 0xff, 0x72, 0x88, 0x18, 0x67, 0x2e,
+ 0x5d, 0x68, 0x72, 0xa0, 0xfc, 0x44, 0x9a, 0xff, 0xdd, 0xc9, 0xba, 0x9d,
+ 0x8d, 0x41, 0xcb, 0x9f, 0xe3, 0x97, 0xf9, 0xf6, 0xfd, 0x00, 0xce, 0x72,
+ 0x84, 0xf2, 0x80, 0x2f, 0x53, 0xae, 0x6c, 0x48, 0x71, 0x23, 0x25, 0xd2,
+ 0x73, 0x21, 0xab, 0xd2, 0x11, 0x85, 0x97, 0xa1, 0xb0, 0xa1, 0x07, 0x04,
+ 0x22, 0x2f, 0x0b, 0xf8, 0xe5, 0xe1, 0x4d, 0x9c, 0xb3, 0x7c, 0x21, 0xb6,
+ 0x81, 0xbb, 0xa3, 0xa7, 0x2f, 0xb5, 0xc5, 0xd8, 0x72, 0xfc, 0x39, 0xe8,
+ 0x6c, 0xe5, 0xff, 0xe4, 0xe5, 0xdc, 0x99, 0x3e, 0xdf, 0x71, 0x67, 0x2f,
+ 0xcc, 0x17, 0xf6, 0xce, 0x5e, 0x8c, 0xd1, 0xcb, 0xff, 0xcb, 0x7d, 0x3f,
+ 0x93, 0x70, 0x31, 0xf9, 0xcb, 0x4b, 0xa7, 0xc6, 0xa0, 0xdd, 0x7c, 0x8b,
+ 0x3d, 0x42, 0x2a, 0xb1, 0x3b, 0x65, 0x96, 0x20, 0xb6, 0xc9, 0x3c, 0x4e,
+ 0x08, 0xc0, 0x2f, 0x9d, 0x14, 0x61, 0xcb, 0xdb, 0xe0, 0xe0, 0x39, 0x7d,
+ 0xca, 0x5f, 0xb0, 0xe5, 0xed, 0x60, 0x4e, 0x5f, 0xe7, 0xf4, 0x4d, 0xb4,
+ 0x61, 0xca, 0x54, 0xf3, 0xfa, 0x39, 0x7f, 0xa2, 0x43, 0x9f, 0x7b, 0x0e,
+ 0x5f, 0xff, 0x27, 0x5d, 0x70, 0x21, 0x9a, 0x51, 0xa9, 0xce, 0x5f, 0xff,
+ 0x7b, 0x61, 0xd6, 0x22, 0xbd, 0x6d, 0xc6, 0x73, 0x97, 0xc2, 0x1c, 0x54,
+ 0xe5, 0xee, 0x81, 0x87, 0x2a, 0x49, 0xf8, 0x61, 0x17, 0xc4, 0x68, 0xeb,
+ 0xa2, 0x3e, 0x99, 0x6d, 0x43, 0xca, 0x40, 0x22, 0xbf, 0xbd, 0xb9, 0xa0,
+ 0x67, 0x39, 0x7e, 0x15, 0x53, 0x36, 0x72, 0xfc, 0xdb, 0xf9, 0xd6, 0x72,
+ 0xff, 0xec, 0x6d, 0xff, 0xc5, 0xf5, 0xff, 0xd9, 0xcb, 0xff, 0x6d, 0xfe,
+ 0x81, 0x70, 0xe2, 0xa7, 0x29, 0x11, 0xa7, 0xd2, 0x71, 0x28, 0xf2, 0x35,
+ 0xd1, 0xd3, 0x96, 0x09, 0xca, 0x61, 0xa7, 0x11, 0x6b, 0xe1, 0x0f, 0x25,
+ 0x4e, 0x5f, 0xd9, 0xb6, 0xdc, 0x67, 0x39, 0x58, 0x7e, 0x6e, 0x40, 0x24,
+ 0xb7, 0xed, 0x03, 0x6e, 0xb3, 0x97, 0xca, 0xec, 0x30, 0x72, 0xa0, 0xf2,
+ 0xc0, 0x51, 0x6d, 0x9c, 0xb6, 0x1c, 0xb3, 0x10, 0xd0, 0xf0, 0x08, 0xdf,
+ 0xf6, 0x0b, 0xcb, 0x72, 0x6e, 0x73, 0x97, 0xd2, 0xda, 0x09, 0xcb, 0x44,
+ 0x8f, 0x6f, 0xe3, 0xab, 0xfc, 0xfa, 0x94, 0x2d, 0x16, 0x72, 0xa1, 0x5b,
+ 0x76, 0x46, 0x04, 0x90, 0xd5, 0xeb, 0xbb, 0xa1, 0x0c, 0x21, 0x00, 0x51,
+ 0x7f, 0xf9, 0x57, 0xcf, 0xbd, 0xe8, 0xce, 0x28, 0xb3, 0x97, 0xf8, 0x73,
+ 0x7e, 0x77, 0x13, 0x94, 0xa9, 0xfe, 0x71, 0x4c, 0xbf, 0xff, 0xf2, 0x6b,
+ 0x50, 0xa7, 0x90, 0x41, 0x2c, 0xd8, 0x40, 0xfa, 0x91, 0xcb, 0xff, 0xf8,
+ 0x71, 0x5c, 0x1e, 0x5b, 0xf7, 0x71, 0x8a, 0x47, 0xe7, 0x2a, 0x11, 0x95,
+ 0x8d, 0x97, 0xf8, 0x0f, 0xb4, 0x99, 0x1b, 0x39, 0x48, 0x9a, 0x27, 0x61,
+ 0xde, 0x24, 0x37, 0xbb, 0x02, 0x72, 0xf7, 0xde, 0x61, 0xca, 0x59, 0xb9,
+ 0x71, 0xbb, 0xf4, 0xe1, 0xd2, 0x36, 0x72, 0xff, 0x28, 0xfc, 0x52, 0x64,
+ 0x6c, 0xe5, 0xfe, 0x06, 0xa7, 0x64, 0x67, 0x8e, 0x5f, 0xf6, 0xe1, 0x81,
+ 0xec, 0x0a, 0xce, 0x5c, 0x83, 0x87, 0xd8, 0xa9, 0xa5, 0x42, 0x33, 0xc3,
+ 0x0a, 0x3b, 0xd2, 0x06, 0xce, 0x5f, 0xc1, 0x7d, 0x7e, 0xd3, 0x0e, 0x5e,
+ 0xea, 0x9c, 0x4e, 0x5f, 0xf4, 0x30, 0x71, 0x7a, 0x4f, 0xce, 0x5f, 0x82,
+ 0xfb, 0xde, 0x1c, 0xa9, 0x1f, 0xfe, 0xc8, 0x00, 0x71, 0x7f, 0xd1, 0x2c,
+ 0x4d, 0xec, 0x10, 0x72, 0xff, 0xde, 0x86, 0x7c, 0xb4, 0xfb, 0x34, 0x72,
+ 0xfd, 0xdc, 0xd2, 0x6c, 0xe5, 0xe1, 0x49, 0x7c, 0x7c, 0xfe, 0x40, 0xbf,
+ 0xf3, 0xe7, 0xf0, 0x2e, 0x1c, 0x54, 0xe5, 0x4e, 0x98, 0x74, 0xa1, 0x3d,
+ 0xf9, 0x9d, 0xf7, 0xbd, 0x8d, 0x67, 0x2f, 0xfa, 0x32, 0x5d, 0xc4, 0x96,
+ 0xce, 0x5c, 0xff, 0x6c, 0xf7, 0x3c, 0x4b, 0x73, 0x24, 0x72, 0xff, 0x9f,
+ 0x16, 0x1c, 0xd7, 0xe8, 0x72, 0xe4, 0xd0, 0x4f, 0x3f, 0xa2, 0xf7, 0xfd,
+ 0x12, 0xd8, 0xc7, 0xee, 0xc3, 0x97, 0xef, 0x46, 0x0a, 0xce, 0x5f, 0x7d,
+ 0xe8, 0x61, 0xca, 0x54, 0xf2, 0x7e, 0x26, 0xbf, 0xe9, 0x29, 0xe4, 0xea,
+ 0x0f, 0x8e, 0x5f, 0xfe, 0x8c, 0xfb, 0xdd, 0x8f, 0x0c, 0x7f, 0xb3, 0x97,
+ 0x47, 0xe7, 0x2e, 0xeb, 0x0e, 0x52, 0xcd, 0x76, 0xc5, 0xe9, 0x11, 0xec,
+ 0xe4, 0x9e, 0x39, 0x03, 0xc5, 0xff, 0xe1, 0x03, 0xc9, 0x80, 0xf7, 0x60,
+ 0x1c, 0x39, 0xcb, 0xd3, 0xa6, 0x8e, 0x5f, 0xf6, 0xd3, 0xef, 0x4d, 0x28,
+ 0xf8, 0xe5, 0xfb, 0x7e, 0xde, 0x78, 0xe5, 0x6c, 0xf9, 0x00, 0x79, 0x7f,
+ 0x03, 0x87, 0x49, 0x91, 0xb3, 0x97, 0x67, 0x4e, 0x5e, 0x6d, 0xb6, 0xca,
+ 0x5f, 0xfe, 0xf2, 0x7b, 0x7d, 0x46, 0x8a, 0x6a, 0x24, 0x53, 0x99, 0xa0,
+ 0xa5, 0x53, 0x6c, 0x48, 0x40, 0xb9, 0x17, 0x8d, 0x00, 0x6d, 0x7f, 0xff,
+ 0xc9, 0xe9, 0x40, 0xe7, 0xba, 0x99, 0xe8, 0x62, 0x6a, 0x47, 0x2a, 0x4c,
+ 0x91, 0x30, 0xb6, 0xe1, 0x02, 0xe1, 0xf3, 0xf1, 0x3a, 0x0e, 0xcd, 0x0a,
+ 0xfd, 0x46, 0x7a, 0xc8, 0x4a, 0x75, 0xf7, 0xf2, 0xd1, 0x8d, 0xdf, 0x67,
+ 0x7e, 0x8e, 0xef, 0x8a, 0x7d, 0xff, 0x7d, 0x2d, 0xef, 0x02, 0xfe, 0x39,
+ 0x6c, 0x39, 0x7d, 0xa1, 0x7e, 0x27, 0x2a, 0x0f, 0xb5, 0x53, 0xa4, 0x10,
+ 0xbd, 0xfe, 0xf0, 0xe5, 0x9c, 0xe5, 0xe8, 0xee, 0xce, 0x57, 0xc6, 0xb1,
+ 0x04, 0x2f, 0xfd, 0x0b, 0xe5, 0x83, 0x00, 0xe1, 0xf6, 0x72, 0xff, 0xfe,
+ 0x7f, 0x27, 0x5d, 0x9c, 0xb3, 0x71, 0x9a, 0xc1, 0x39, 0x7f, 0xf6, 0xdf,
+ 0xed, 0xef, 0x07, 0xf6, 0x98, 0x72, 0xff, 0xf2, 0x2f, 0x70, 0xd3, 0x3d,
+ 0x29, 0x66, 0xce, 0x56, 0x93, 0x50, 0x61, 0x08, 0xa2, 0x79, 0x67, 0x8a,
+ 0x3d, 0xf6, 0xbb, 0x82, 0x72, 0x90, 0xfb, 0x5d, 0x32, 0xfe, 0x1e, 0x4a,
+ 0x6e, 0x30, 0xe5, 0xf7, 0xa3, 0xe6, 0xce, 0x52, 0xd5, 0x3c, 0xf6, 0x50,
+ 0x37, 0xe4, 0x0d, 0x97, 0xdf, 0xff, 0xbc, 0x05, 0x3c, 0x31, 0xfb, 0xfb,
+ 0xf5, 0x06, 0x47, 0x2e, 0x6f, 0xa7, 0x2f, 0xff, 0x40, 0xad, 0x4d, 0x3f,
+ 0xe9, 0xee, 0xc1, 0xcb, 0xf9, 0x9c, 0xbb, 0x9f, 0xb9, 0xcb, 0xf9, 0xbd,
+ 0xe6, 0x0c, 0xe7, 0x2b, 0x0f, 0x79, 0x0c, 0x2f, 0xa3, 0x71, 0xc4, 0xe5,
+ 0xff, 0xd0, 0x2f, 0xe9, 0x42, 0xae, 0xdf, 0x8e, 0x57, 0x4f, 0x9c, 0x04,
+ 0x77, 0xb9, 0x3a, 0xce, 0x54, 0x27, 0xc0, 0xb5, 0x9f, 0xc6, 0x37, 0x0a,
+ 0x8f, 0x42, 0x1f, 0x80, 0x8a, 0xfe, 0x92, 0x8c, 0x62, 0x35, 0x9c, 0xbe,
+ 0x62, 0x90, 0x27, 0x2f, 0x90, 0x38, 0xc3, 0x97, 0xce, 0xe3, 0xf9, 0xcb,
+ 0x37, 0x07, 0x84, 0xa9, 0x0d, 0xc0, 0x61, 0xcb, 0xfc, 0xdb, 0xcd, 0x92,
+ 0x86, 0xb3, 0x97, 0xee, 0x00, 0x4c, 0x93, 0x1c, 0xa4, 0x45, 0x27, 0x4a,
+ 0x76, 0x2e, 0x03, 0x7b, 0xff, 0x42, 0x33, 0xbf, 0x3b, 0x5f, 0xb6, 0x72,
+ 0xff, 0x43, 0xeb, 0xad, 0xb8, 0x4a, 0x5c, 0xdb, 0x65, 0x28, 0x27, 0x98,
+ 0xd9, 0x9d, 0xef, 0x23, 0x59, 0x4e, 0x66, 0x8e, 0xfe, 0xf9, 0x69, 0xbe,
+ 0xa1, 0xcb, 0xe0, 0x48, 0x1e, 0x39, 0x50, 0xaa, 0xa5, 0x0c, 0xa6, 0x8c,
+ 0x21, 0x87, 0x9b, 0x85, 0x8f, 0x8c, 0x5a, 0x17, 0x5f, 0x08, 0x7a, 0xe7,
+ 0x2f, 0x63, 0xb5, 0x9c, 0xac, 0x37, 0xfa, 0x21, 0xb9, 0xbd, 0x9c, 0xb6,
+ 0x1c, 0xb7, 0xd8, 0x6a, 0x3c, 0x31, 0x7d, 0xf4, 0xb8, 0x4f, 0x8e, 0x5f,
+ 0xfd, 0xbd, 0x84, 0x60, 0x3d, 0x8f, 0x6c, 0xe5, 0x42, 0x25, 0x70, 0x9c,
+ 0x05, 0x57, 0xfb, 0xa8, 0xf2, 0xf2, 0x4e, 0x72, 0xff, 0xde, 0x4d, 0x3f,
+ 0xfc, 0x1e, 0xce, 0x9c, 0xbf, 0xe4, 0x6c, 0x73, 0xc8, 0x0f, 0xce, 0x5f,
+ 0x93, 0x41, 0x89, 0xce, 0x5f, 0xe7, 0xd7, 0xb6, 0x28, 0xa9, 0xcb, 0xff,
+ 0xdb, 0xc5, 0x70, 0x1a, 0x70, 0xc7, 0x60, 0xe5, 0x49, 0x38, 0x0f, 0x8b,
+ 0x90, 0xcd, 0xad, 0x0b, 0xa7, 0x2e, 0x51, 0xb3, 0x3b, 0xff, 0xff, 0x3a,
+ 0x7a, 0x3a, 0x39, 0xee, 0xa2, 0x92, 0x8e, 0x28, 0x3f, 0x9c, 0xbf, 0x2f,
+ 0x19, 0x1b, 0x39, 0x78, 0x02, 0x13, 0x95, 0xd4, 0x57, 0xbb, 0x67, 0xe4,
+ 0xf7, 0xb1, 0x34, 0x72, 0xff, 0x49, 0x19, 0xdf, 0x9d, 0xac, 0xe5, 0xf3,
+ 0xea, 0x24, 0x72, 0xff, 0x9f, 0xee, 0x5f, 0x6f, 0x05, 0x53, 0x95, 0x3a,
+ 0x2c, 0x3e, 0x1b, 0x61, 0xbf, 0x88, 0x6f, 0xba, 0xd6, 0x8c, 0x39, 0x78,
+ 0x63, 0xf3, 0x97, 0xa1, 0x99, 0xc8, 0xf0, 0x76, 0x4b, 0x7f, 0xe8, 0xfb,
+ 0xb0, 0xc5, 0xf5, 0x26, 0x39, 0x50, 0x9e, 0xa6, 0x43, 0x81, 0x21, 0x01,
+ 0xa3, 0x4b, 0xf8, 0x43, 0xbd, 0xa3, 0x0e, 0x5f, 0x96, 0xf3, 0xe3, 0x67,
+ 0x2f, 0xd1, 0xa0, 0xe0, 0x9c, 0xac, 0x3f, 0xc1, 0x2d, 0xf1, 0x4d, 0xfa,
+ 0x1a, 0x27, 0x40, 0x72, 0xff, 0xe8, 0xfe, 0x3a, 0xc1, 0x75, 0x7a, 0x87,
+ 0x2d, 0xc3, 0x1c, 0xbf, 0xbb, 0x02, 0xdb, 0xfc, 0x72, 0xff, 0xc3, 0x34,
+ 0x60, 0xcf, 0x9f, 0x78, 0xe5, 0x04, 0xfb, 0x5c, 0xba, 0xf2, 0xaa, 0x30,
+ 0xe5, 0xff, 0xc8, 0x1e, 0xc2, 0xe3, 0xf7, 0x1f, 0xce, 0x5f, 0x9f, 0x73,
+ 0xa6, 0x8e, 0x5f, 0x69, 0x01, 0x39, 0xe2, 0xf5, 0x5f, 0xfb, 0x13, 0x8e,
+ 0x0e, 0x05, 0xe4, 0x78, 0xbd, 0x57, 0xe7, 0x1f, 0xa5, 0xcc, 0x27, 0xf4,
+ 0xd9, 0x85, 0x05, 0x1c, 0x8c, 0x85, 0x15, 0xf9, 0x5f, 0x3b, 0x89, 0xcb,
+ 0xc2, 0x09, 0xce, 0x53, 0x9e, 0x27, 0x89, 0xe9, 0x11, 0x1a, 0x2d, 0x95,
+ 0x0a, 0xcc, 0xc2, 0x5b, 0xa2, 0x96, 0x22, 0x3c, 0x20, 0xc4, 0x87, 0x63,
+ 0xe0, 0x8e, 0xd6, 0xe6, 0xa5, 0xab, 0x39, 0x79, 0x23, 0x47, 0x2b, 0x86,
+ 0x37, 0x9d, 0x21, 0xbf, 0xfb, 0x48, 0xc8, 0x6b, 0x1c, 0x67, 0xd0, 0x72,
+ 0xa4, 0x7d, 0x93, 0x13, 0x5f, 0x20, 0xb8, 0x4e, 0x5e, 0x9d, 0x88, 0x72,
+ 0x82, 0x6f, 0x44, 0x82, 0xfd, 0x2c, 0xe3, 0x12, 0x39, 0x7b, 0x35, 0x07,
+ 0x2b, 0xe4, 0x62, 0x23, 0x06, 0x88, 0x3a, 0x53, 0x70, 0xcc, 0x72, 0xfe,
+ 0xeb, 0xcd, 0xa8, 0x9c, 0xe5, 0xfc, 0x9f, 0x6f, 0xb8, 0xb3, 0x97, 0xff,
+ 0xd9, 0xed, 0xe4, 0xdd, 0x8e, 0x39, 0xde, 0xc1, 0xcb, 0xff, 0xff, 0xf2,
+ 0x67, 0xdb, 0x4c, 0x6f, 0x96, 0x7d, 0x2d, 0xa7, 0xb6, 0x9f, 0x04, 0x20,
+ 0x9c, 0xe5, 0xff, 0xf9, 0x04, 0x3c, 0x94, 0xf2, 0x6d, 0xd0, 0x41, 0x23,
+ 0x97, 0xcf, 0x3f, 0x50, 0xe5, 0x62, 0x78, 0xc8, 0x2f, 0x31, 0x78, 0x97,
+ 0x79, 0x47, 0x8c, 0x22, 0x5a, 0x2b, 0x5e, 0x06, 0xa4, 0x72, 0xff, 0xcc,
+ 0x70, 0xea, 0x3d, 0xdc, 0x09, 0xcb, 0xf9, 0xfd, 0xfa, 0x83, 0x23, 0x97,
+ 0xfc, 0x17, 0x76, 0xff, 0x7f, 0x6c, 0xe5, 0xfe, 0x92, 0x90, 0x22, 0x06,
+ 0x1c, 0xae, 0x48, 0xf7, 0x81, 0xd9, 0xcf, 0x95, 0x2f, 0x73, 0xab, 0xfd,
+ 0x12, 0x4e, 0x6d, 0xb6, 0xd9, 0x4b, 0xb3, 0xa7, 0x2f, 0x2b, 0x81, 0x39,
+ 0x7f, 0x75, 0xf4, 0xb8, 0xf1, 0xcb, 0x9c, 0x27, 0x2f, 0xed, 0x3e, 0xfa,
+ 0xf2, 0x39, 0x6f, 0x8e, 0x5c, 0x8d, 0x9c, 0xb9, 0x4f, 0xce, 0x54, 0xc6,
+ 0xc3, 0xf1, 0x7b, 0xd2, 0x70, 0x9c, 0xb9, 0xb6, 0xce, 0x54, 0x91, 0xbb,
+ 0x82, 0xcb, 0x2d, 0x44, 0x2d, 0x91, 0xb6, 0x39, 0x7b, 0xca, 0x7e, 0x53,
+ 0x99, 0xeb, 0x5f, 0xec, 0x62, 0x06, 0x70, 0x6c, 0xe5, 0xff, 0xfd, 0xfb,
+ 0x4c, 0xd4, 0x79, 0x16, 0x81, 0x9e, 0x06, 0x0e, 0x5e, 0xcf, 0xbc, 0x72,
+ 0xd8, 0x27, 0xf3, 0xb5, 0xca, 0xea, 0x34, 0xf7, 0x0a, 0xdb, 0xfe, 0x40,
+ 0xe3, 0x12, 0x64, 0x6c, 0xe5, 0xff, 0xe7, 0x0e, 0x60, 0xab, 0xbd, 0xe0,
+ 0xfe, 0x72, 0xfb, 0xa0, 0x75, 0x61, 0x10, 0x4c, 0x39, 0xbc, 0x31, 0xd3,
+ 0x97, 0xff, 0xf4, 0x9f, 0x7b, 0x8c, 0x9c, 0x12, 0x0e, 0x85, 0xdb, 0x39,
+ 0x68, 0x0a, 0x2c, 0x55, 0x3a, 0x41, 0xba, 0xda, 0x72, 0x1e, 0x8d, 0x6e,
+ 0xfe, 0x46, 0x2f, 0x05, 0x67, 0x2f, 0x9e, 0x7d, 0xf4, 0xe5, 0x68, 0xf3,
+ 0xf6, 0x59, 0x5c, 0x97, 0x30, 0xe4, 0x2c, 0x11, 0xdf, 0xa3, 0x60, 0x49,
+ 0x52, 0xbe, 0x79, 0xbf, 0x71, 0x53, 0xa9, 0xe3, 0x97, 0xfd, 0x9e, 0xec,
+ 0x6b, 0xd8, 0xb3, 0x97, 0xef, 0xb0, 0x41, 0x31, 0xcb, 0xd1, 0xa9, 0x8e,
+ 0x54, 0x32, 0x6f, 0xf2, 0x50, 0x1a, 0x46, 0xc7, 0xd4, 0xc7, 0x9c, 0xfb,
+ 0xfd, 0xa4, 0x4a, 0xc0, 0x70, 0xd0, 0xa6, 0xf6, 0xde, 0x63, 0x97, 0xff,
+ 0xb3, 0xec, 0xe3, 0x01, 0x1c, 0xf6, 0x7e, 0x72, 0xe5, 0x3f, 0x39, 0x5a,
+ 0x3e, 0x4f, 0xd2, 0xef, 0xfe, 0x40, 0xbf, 0x93, 0x79, 0x2c, 0xe9, 0xcb,
+ 0x9f, 0x80, 0xe5, 0xb3, 0xa7, 0xb7, 0xe4, 0x2b, 0xff, 0xbf, 0x50, 0x64,
+ 0x39, 0xef, 0x64, 0xe7, 0x2b, 0xe4, 0xdb, 0x35, 0x08, 0x11, 0x7e, 0xf1,
+ 0x3d, 0xe1, 0x5f, 0x01, 0xcb, 0xff, 0xfb, 0xed, 0x8b, 0xef, 0xb9, 0x2c,
+ 0xea, 0x6b, 0xae, 0x72, 0xfb, 0x3e, 0x9f, 0x89, 0xcb, 0xfe, 0x10, 0xe0,
+ 0x82, 0x59, 0xb3, 0x97, 0xe8, 0xfb, 0x60, 0xfc, 0xe5, 0xfe, 0x53, 0xc3,
+ 0x93, 0xa6, 0x8e, 0x5f, 0x79, 0x36, 0x87, 0x2b, 0x13, 0x55, 0x41, 0xfd,
+ 0x2d, 0x39, 0x37, 0xe6, 0xe2, 0x54, 0x03, 0x4b, 0xff, 0xa7, 0x85, 0x3f,
+ 0x04, 0xa4, 0xfd, 0x01, 0xcb, 0xfe, 0xea, 0x05, 0x38, 0x78, 0x14, 0x39,
+ 0x7f, 0x9e, 0x58, 0x1d, 0x6f, 0x67, 0x2f, 0xa3, 0x14, 0x09, 0xcb, 0xff,
+ 0xfa, 0x43, 0x19, 0xbc, 0x1f, 0x77, 0x02, 0x0f, 0x6c, 0xe5, 0xfe, 0x55,
+ 0x3c, 0xfd, 0x6d, 0xac, 0xe5, 0xfd, 0x13, 0xb4, 0xcd, 0x41, 0xcb, 0xfd,
+ 0x93, 0x77, 0x36, 0xe2, 0x72, 0xff, 0xc1, 0xcf, 0xa5, 0xbf, 0x6d, 0xff,
+ 0x39, 0x5a, 0x3f, 0x30, 0x19, 0x5f, 0xe6, 0xc3, 0xdc, 0xe3, 0x9a, 0x39,
+ 0x7f, 0xf2, 0x33, 0x92, 0xfa, 0x9d, 0x5a, 0x6c, 0xe5, 0xfe, 0xc9, 0x60,
+ 0x38, 0x77, 0x13, 0x97, 0xff, 0x44, 0xbb, 0x1f, 0x7a, 0x3a, 0xed, 0x67,
+ 0x2a, 0x11, 0xf3, 0xa3, 0x6e, 0xa3, 0x09, 0xb5, 0xff, 0xfe, 0x41, 0xcf,
+ 0xbc, 0xab, 0xfb, 0xb1, 0xdc, 0xe2, 0xf2, 0x39, 0x41, 0x56, 0x80, 0xb3,
+ 0x3f, 0x88, 0x91, 0x66, 0x63, 0x8d, 0x42, 0x8b, 0xd1, 0x8d, 0xf1, 0x3b,
+ 0xb8, 0x60, 0xe5, 0xff, 0x05, 0x35, 0x1c, 0x7f, 0xdc, 0x8e, 0x5d, 0x0c,
+ 0x39, 0x50, 0x7a, 0x5d, 0x3c, 0xae, 0xa2, 0x23, 0xcc, 0xf7, 0xfd, 0xb7,
+ 0xea, 0x05, 0x69, 0x39, 0xcb, 0xfc, 0xf2, 0xc0, 0xef, 0x70, 0x72, 0xa0,
+ 0xfa, 0xf0, 0xe6, 0xa1, 0x74, 0xcb, 0x25, 0xbd, 0xbc, 0x61, 0x20, 0x84,
+ 0x75, 0xe8, 0x1f, 0x1c, 0xbf, 0xfe, 0x8d, 0x67, 0x14, 0xf7, 0xe0, 0x1d,
+ 0xa0, 0x4e, 0x5f, 0xe4, 0xea, 0x6a, 0x53, 0x41, 0xcb, 0xff, 0xf2, 0x01,
+ 0x6a, 0x7d, 0xfb, 0xed, 0xf4, 0x9f, 0x7e, 0x72, 0xf9, 0xf5, 0x12, 0x39,
+ 0x7f, 0xff, 0x20, 0xba, 0x0f, 0xfa, 0x8e, 0xba, 0x7a, 0x3a, 0x72, 0x84,
+ 0xfe, 0x3c, 0x43, 0x7e, 0x4f, 0x6c, 0x13, 0x9c, 0xbf, 0xfc, 0x29, 0xff,
+ 0xbe, 0x5a, 0x69, 0x48, 0x09, 0xcb, 0xfe, 0xea, 0x81, 0x07, 0xb7, 0xfc,
+ 0x1c, 0xa8, 0x44, 0x43, 0xa6, 0x50, 0x53, 0xc5, 0x48, 0x69, 0x30, 0x87,
+ 0xd0, 0xb1, 0xbf, 0x68, 0x0b, 0xec, 0x1c, 0xbf, 0xb5, 0x34, 0x93, 0xdb,
+ 0x39, 0x61, 0x83, 0xd7, 0xc2, 0x8b, 0xfd, 0x33, 0xcc, 0xff, 0x4b, 0x67,
+ 0x2f, 0xe7, 0x9d, 0x26, 0x46, 0xce, 0x5f, 0xff, 0xe7, 0x6f, 0xd9, 0xde,
+ 0x41, 0xc9, 0xa4, 0xfa, 0x9f, 0xa0, 0x39, 0x58, 0x8c, 0xb7, 0x36, 0x12,
+ 0xfb, 0xf6, 0x0c, 0xf8, 0xd9, 0xcb, 0xf3, 0xb3, 0xa8, 0xd9, 0xca, 0x9c,
+ 0xf4, 0x02, 0x51, 0x7f, 0xd1, 0x3a, 0x92, 0xe8, 0x1e, 0x73, 0x95, 0x87,
+ 0xbf, 0xa2, 0x3b, 0x70, 0xc7, 0x2f, 0xd1, 0xad, 0x67, 0x4e, 0x5f, 0xc2,
+ 0xea, 0xc3, 0x20, 0xe5, 0x70, 0x87, 0xd3, 0x21, 0x60, 0x13, 0xdf, 0x44,
+ 0xea, 0xaa, 0x72, 0xff, 0xfc, 0x8b, 0x86, 0x6d, 0xf5, 0x8c, 0x02, 0xde,
+ 0x47, 0x2e, 0x4e, 0x27, 0x2d, 0xd3, 0x95, 0x23, 0xfd, 0x6b, 0x54, 0x00,
+ 0xc5, 0xe0, 0xc3, 0x0e, 0x5f, 0xec, 0xff, 0x26, 0x8f, 0xb6, 0x72, 0xa0,
+ 0xf4, 0x70, 0x72, 0xfe, 0xeb, 0xca, 0x37, 0x23, 0x97, 0xfd, 0x9d, 0x4f,
+ 0xb7, 0xd0, 0x6c, 0xe5, 0xd8, 0x2b, 0x3e, 0x7f, 0xcb, 0x6f, 0xe1, 0x7f,
+ 0xc3, 0x82, 0x72, 0xfc, 0x8d, 0x33, 0x4a, 0x9c, 0xb9, 0x59, 0x1c, 0xbf,
+ 0x75, 0x38, 0xa2, 0xce, 0x5d, 0x9d, 0x91, 0xe0, 0xac, 0x62, 0x98, 0x89,
+ 0x86, 0x8d, 0x77, 0x9b, 0x6d, 0xb2, 0x97, 0xfe, 0xd0, 0x81, 0xd4, 0xc9,
+ 0xa1, 0x87, 0x39, 0x9a, 0x0b, 0xf7, 0x52, 0x64, 0x6c, 0xe5, 0x96, 0x72,
+ 0xa1, 0x11, 0x78, 0xa3, 0xa2, 0x9b, 0xfd, 0x01, 0xc9, 0x40, 0xac, 0xe5,
+ 0x43, 0x25, 0x62, 0x71, 0xb9, 0x28, 0xe4, 0x7f, 0x0d, 0x70, 0x9e, 0x9a,
+ 0x1e, 0x1a, 0x86, 0xe3, 0x21, 0x15, 0xd3, 0x47, 0x85, 0x10, 0xc2, 0x0f,
+ 0x70, 0x87, 0xf1, 0x68, 0x21, 0x88, 0xdc, 0x34, 0x14, 0x2e, 0xbf, 0x31,
+ 0x34, 0xff, 0x9c, 0xbe, 0xd6, 0xb3, 0xa7, 0x2f, 0xee, 0xa7, 0x07, 0x00,
+ 0x15, 0x39, 0x50, 0x7a, 0xeb, 0x22, 0xb7, 0x0e, 0x72, 0xc8, 0x72, 0xff,
+ 0xbd, 0x1a, 0xdf, 0x60, 0x7c, 0x72, 0xdc, 0x39, 0xcb, 0xfe, 0xf4, 0x6b,
+ 0x7d, 0x81, 0xf1, 0xcb, 0xb7, 0x07, 0x2f, 0x30, 0x30, 0x72, 0xff, 0x0f,
+ 0x9e, 0x6d, 0xc7, 0x8e, 0x52, 0x1e, 0x7b, 0x8e, 0x5f, 0x23, 0xe2, 0xce,
+ 0x5f, 0xfb, 0x38, 0x8e, 0x6e, 0x61, 0x80, 0x9c, 0xbe, 0x58, 0x62, 0x73,
+ 0x97, 0x7f, 0x07, 0x2f, 0x6d, 0x34, 0x72, 0xb0, 0xf5, 0xbf, 0x23, 0xf0,
+ 0xbd, 0xfe, 0x96, 0x0a, 0x07, 0x04, 0xe5, 0xef, 0x6f, 0x9c, 0x27, 0xcf,
+ 0x82, 0xd3, 0x1c, 0x75, 0x97, 0xf2, 0x01, 0x20, 0xdc, 0x25, 0x7c, 0x5f,
+ 0x76, 0xe0, 0xe5, 0xe6, 0x06, 0x0e, 0x5f, 0xe1, 0xf3, 0xcd, 0xb8, 0xf1,
+ 0xca, 0x43, 0xcf, 0x71, 0xcb, 0xe4, 0x7c, 0x59, 0xcb, 0xff, 0x67, 0x11,
+ 0xcd, 0xcc, 0x30, 0x13, 0x97, 0xcb, 0x0c, 0x4e, 0x72, 0xfe, 0x9b, 0xf4,
+ 0x6b, 0x79, 0x8e, 0x5d, 0xfc, 0x1c, 0xbd, 0xb4, 0xd1, 0xca, 0xc4, 0x44,
+ 0xac, 0x8f, 0xf3, 0x3f, 0x0b, 0xdf, 0xe9, 0x60, 0xa0, 0x70, 0x4e, 0x5f,
+ 0xc2, 0xe1, 0xc5, 0x79, 0xc2, 0xe5, 0x48, 0x45, 0xb0, 0x41, 0x72, 0x87,
+ 0xe6, 0x84, 0x57, 0x59, 0x7f, 0x20, 0x12, 0x0d, 0xc3, 0x23, 0xc7, 0xb7,
+ 0xff, 0x6a, 0x3e, 0xd8, 0xc3, 0x33, 0xef, 0x1c, 0xbf, 0xff, 0x38, 0x73,
+ 0x05, 0x55, 0x06, 0x06, 0x74, 0xd1, 0xcb, 0xcf, 0xa9, 0xcf, 0x20, 0x92,
+ 0xfa, 0x59, 0xf4, 0x8f, 0x20, 0x92, 0xf6, 0xd0, 0x27, 0x90, 0x49, 0x73,
+ 0x6d, 0x9e, 0x41, 0x25, 0x2d, 0x15, 0x33, 0x15, 0x78, 0xc1, 0xb2, 0x9b,
+ 0x9f, 0xc5, 0x90, 0x48, 0xe6, 0x6f, 0xef, 0xec, 0xee, 0x60, 0xaa, 0x72,
+ 0xf3, 0x8f, 0xfc, 0x97, 0xdb, 0xe2, 0x73, 0x2b, 0x50, 0xc2, 0x62, 0x28,
+ 0xc6, 0x79, 0xe3, 0x6b, 0xe6, 0x98, 0xfd, 0x39, 0x6c, 0x6b, 0x45, 0x0f,
+ 0xef, 0xd6, 0x91, 0xcb, 0xfa, 0x40, 0x9f, 0xc9, 0x39, 0x4b, 0xe7, 0x0f,
+ 0x70, 0xe5, 0xe0, 0xa3, 0x0e, 0x5f, 0xfb, 0xb1, 0xe4, 0x18, 0x64, 0x6c,
+ 0xe5, 0x2a, 0x7f, 0x2e, 0x43, 0xb1, 0xca, 0x99, 0x1b, 0x1d, 0x85, 0x4d,
+ 0xff, 0x40, 0xc8, 0x63, 0xf7, 0x61, 0xcb, 0xf4, 0xd1, 0xd0, 0x68, 0xe5,
+ 0xa0, 0xe5, 0xfe, 0x49, 0x01, 0xf7, 0xd4, 0x39, 0x7f, 0x67, 0x17, 0x66,
+ 0x74, 0xe5, 0xa4, 0x52, 0xf3, 0xea, 0x72, 0x94, 0x52, 0xa0, 0xdc, 0xac,
+ 0x45, 0x83, 0xb7, 0xa3, 0xf5, 0x94, 0xe6, 0x6b, 0x69, 0x88, 0xc3, 0x18,
+ 0x4a, 0x54, 0x26, 0x39, 0x90, 0xf5, 0xbf, 0x6b, 0xf6, 0x26, 0xce, 0x5f,
+ 0xca, 0x0c, 0xb7, 0xd0, 0x9c, 0xc3, 0x53, 0x7c, 0x07, 0xd4, 0x8e, 0x59,
+ 0x87, 0x2e, 0xc9, 0x04, 0xd9, 0xcc, 0x45, 0x7f, 0xf6, 0x7d, 0xed, 0xa0,
+ 0xc7, 0xee, 0xc3, 0x97, 0xd9, 0x32, 0x30, 0xe5, 0x4e, 0x7c, 0xcd, 0xa2,
+ 0x5f, 0xa2, 0x69, 0x47, 0xe5, 0x2f, 0xff, 0xdd, 0xc4, 0x96, 0xf9, 0x7b,
+ 0xb8, 0x10, 0x7b, 0x67, 0x29, 0x68, 0x81, 0xf1, 0x4d, 0x90, 0xe5, 0xff,
+ 0x4e, 0x09, 0x07, 0xa0, 0x71, 0x39, 0x7f, 0x24, 0x32, 0x7c, 0x6c, 0xe5,
+ 0xfb, 0x27, 0x66, 0x30, 0xe5, 0xed, 0xa6, 0x8e, 0x50, 0x9e, 0x27, 0x8a,
+ 0x2f, 0xe1, 0x7f, 0xff, 0x06, 0xce, 0x5f, 0xc8, 0xaa, 0x90, 0xce, 0x61,
+ 0x4c, 0x33, 0x04, 0x34, 0x75, 0xb7, 0x2f, 0x10, 0xd6, 0x2a, 0x44, 0x48,
+ 0x52, 0x8c, 0x65, 0xf7, 0xf7, 0x7b, 0x93, 0xfb, 0x67, 0x2f, 0x64, 0xe0,
+ 0x39, 0x58, 0x79, 0x82, 0x5f, 0x7f, 0xd9, 0xee, 0x43, 0x9f, 0xa9, 0xf1,
+ 0xca, 0x86, 0x7e, 0xa4, 0xa9, 0x11, 0xe1, 0x2c, 0xc8, 0x74, 0xaa, 0x52,
+ 0x86, 0xfa, 0x29, 0xec, 0x65, 0x9f, 0xa8, 0x0b, 0x8e, 0xe5, 0x6b, 0xfa,
+ 0x10, 0xcd, 0x08, 0x2f, 0xff, 0xd3, 0xeb, 0x58, 0x17, 0x67, 0x5f, 0xc3,
+ 0x13, 0x1c, 0xbf, 0xff, 0xfc, 0x0d, 0x02, 0x61, 0x7f, 0xf7, 0xbc, 0x57,
+ 0x01, 0xa7, 0x0c, 0x76, 0x0e, 0x5f, 0xf7, 0x36, 0x38, 0x7b, 0x02, 0x03,
+ 0x97, 0xd0, 0xd6, 0x18, 0x39, 0x7d, 0xc1, 0xd0, 0x28, 0x72, 0xf3, 0x6d,
+ 0xb6, 0x52, 0xe9, 0x41, 0x4e, 0x66, 0x82, 0xf7, 0x78, 0x66, 0xce, 0x54,
+ 0x27, 0x7f, 0x3a, 0xb6, 0x3c, 0xac, 0xeb, 0xe2, 0x4d, 0x23, 0xf1, 0x28,
+ 0xbf, 0xfe, 0x4f, 0x4d, 0x9a, 0xd3, 0xcd, 0x9a, 0xcf, 0x1c, 0xbf, 0x95,
+ 0x8d, 0x6b, 0x3a, 0x72, 0xfe, 0x9e, 0x69, 0x70, 0xda, 0x9c, 0xe5, 0xff,
+ 0xef, 0xd8, 0xf2, 0xe5, 0x01, 0x9d, 0x91, 0xa3, 0x97, 0xc9, 0x03, 0xe3,
+ 0x97, 0xa7, 0x71, 0x39, 0x5a, 0x44, 0x57, 0x53, 0xbc, 0x41, 0x7f, 0xe5,
+ 0x41, 0xb9, 0x26, 0xa7, 0x07, 0xe7, 0x2e, 0x1c, 0x39, 0x79, 0xfe, 0x6c,
+ 0xe5, 0x2a, 0x7e, 0xc8, 0x87, 0xd1, 0x5b, 0xf4, 0xfa, 0x48, 0x61, 0xcb,
+ 0xff, 0xe8, 0x53, 0xc3, 0x1f, 0xbf, 0xbf, 0x50, 0x64, 0x72, 0x9a, 0xa5,
+ 0x42, 0x19, 0x0c, 0x14, 0x85, 0x33, 0x97, 0xf8, 0xa2, 0xf9, 0x40, 0xf5,
+ 0x0e, 0x5f, 0xf9, 0xfd, 0xb6, 0xf3, 0xbf, 0xbf, 0x8e, 0x5f, 0xff, 0xfb,
+ 0x3d, 0x0b, 0x1c, 0xc1, 0x89, 0x7b, 0xae, 0xc1, 0xce, 0x27, 0x2a, 0x74,
+ 0x66, 0x04, 0x8d, 0xb4, 0x0b, 0xca, 0x06, 0x63, 0x97, 0xa4, 0x82, 0x72,
+ 0xfa, 0x75, 0x38, 0x1b, 0x39, 0x7f, 0xd1, 0xd7, 0x4f, 0x4c, 0x8d, 0x9c,
+ 0xbf, 0xf7, 0xf9, 0xa4, 0xff, 0x3f, 0xd3, 0x0e, 0x5f, 0xfe, 0x56, 0x37,
+ 0xa8, 0xe8, 0xe7, 0xa1, 0x87, 0x2e, 0x02, 0x87, 0x2f, 0xf0, 0xe7, 0x14,
+ 0x99, 0x1b, 0x39, 0x5d, 0x3c, 0xdd, 0x8c, 0x5f, 0xff, 0xc0, 0x79, 0xd6,
+ 0x09, 0xfd, 0x9d, 0x1c, 0xf7, 0x50, 0xe5, 0xfa, 0x26, 0x10, 0x6c, 0xe5,
+ 0x62, 0x67, 0x89, 0x09, 0x6e, 0x91, 0x79, 0x72, 0xe4, 0x13, 0x97, 0xf3,
+ 0x8f, 0xf9, 0xe5, 0x4e, 0x54, 0x2a, 0xcf, 0x9c, 0xca, 0x43, 0xee, 0x36,
+ 0x25, 0x3b, 0x39, 0xf4, 0x6f, 0xbc, 0x50, 0x5a, 0x0a, 0xdf, 0x0f, 0xa1,
+ 0xa1, 0xcb, 0xee, 0x81, 0x90, 0x72, 0xe7, 0xd9, 0xcb, 0x81, 0xc3, 0x9c,
+ 0xa6, 0xa8, 0xfd, 0xdc, 0x8c, 0x48, 0x80, 0x2d, 0x73, 0xf3, 0x6a, 0x9f,
+ 0xa3, 0x47, 0x84, 0x84, 0x0b, 0x57, 0x08, 0x7e, 0x1a, 0x15, 0x1c, 0x2e,
+ 0x58, 0xd4, 0x09, 0x38, 0x58, 0xf6, 0x27, 0x3d, 0x27, 0x95, 0x2f, 0x29,
+ 0x49, 0x81, 0x97, 0xd9, 0x94, 0xb4, 0x45, 0x63, 0x60, 0x5c, 0xaa, 0x7f,
+ 0xa5, 0x14, 0x24, 0xb0, 0xe6, 0xb8, 0x58, 0xcd, 0x29, 0x77, 0x52, 0xba,
+ 0x99, 0x2f, 0xd3, 0xb4, 0xba, 0x67, 0x94, 0x03, 0xfc, 0x73, 0x1c, 0x3b,
+ 0x10, 0xce, 0xbd, 0x6e, 0x93, 0x4f, 0xea, 0xc3, 0x9c, 0x12, 0xa5, 0x78,
+ 0xb3, 0xb6, 0xa0, 0xd2, 0x51, 0xf2, 0x92, 0xfc, 0xf8, 0x21, 0xff, 0x7e,
+ 0x66, 0x23, 0xfe, 0x72, 0xf9, 0x6e, 0xeb, 0x34, 0x51, 0x4b, 0xff, 0xf3,
+ 0xff, 0x0b, 0xea, 0x6f, 0xa9, 0xee, 0xe0, 0x9c, 0xad, 0x22, 0x08, 0x4b,
+ 0xaf, 0x3c, 0xb9, 0xc2, 0x32, 0xf2, 0x15, 0x37, 0xff, 0xe0, 0xa4, 0xc3,
+ 0x1e, 0xdf, 0xbe, 0x5a, 0x0c, 0xe7, 0x2d, 0xcd, 0x88, 0x90, 0xd9, 0xcd,
+ 0xfe, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x17, 0x42, 0xff, 0xee, 0x6f, 0x2e,
+ 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x25, 0xaf, 0xda, 0x5b, 0xba, 0xcd, 0x17,
+ 0x92, 0xe7, 0xe2, 0x72, 0xdc, 0xf0, 0xf3, 0x1a, 0x1a, 0x54, 0x3f, 0xab,
+ 0xac, 0xf0, 0x8b, 0x91, 0x56, 0x42, 0x71, 0x70, 0x99, 0x98, 0xe5, 0x88,
+ 0x3d, 0x9c, 0xb7, 0x1b, 0xe9, 0x10, 0xdc, 0xe0, 0x9f, 0x8a, 0xc0, 0x83,
+ 0xc6, 0x14, 0x17, 0xff, 0xb9, 0xb1, 0xe5, 0xcf, 0x34, 0xb7, 0x75, 0x9a,
+ 0x25, 0x95, 0xb8, 0x63, 0x96, 0xe9, 0xca, 0x6a, 0x8d, 0x38, 0x05, 0xaf,
+ 0xf2, 0x07, 0xb8, 0x82, 0xa9, 0xcb, 0xee, 0xbf, 0x80, 0x72, 0xfb, 0xb0,
+ 0xd6, 0xc3, 0x97, 0xfe, 0xce, 0xa4, 0x87, 0x30, 0x1c, 0x39, 0xcb, 0xc0,
+ 0x5b, 0x9c, 0xa9, 0x23, 0x59, 0x0c, 0x9a, 0xc8, 0x98, 0x4a, 0xa2, 0x0d,
+ 0xfc, 0x1f, 0x01, 0xe5, 0xb3, 0x97, 0xc8, 0xd7, 0x13, 0x9c, 0xbd, 0xe7,
+ 0x61, 0xcb, 0xf0, 0x3c, 0x9d, 0x83, 0x97, 0xfe, 0xec, 0x75, 0x15, 0xf6,
+ 0xdf, 0xf3, 0x97, 0xfc, 0xf2, 0xd8, 0x3d, 0x1e, 0xd9, 0xcb, 0xf8, 0x7d,
+ 0xa8, 0x75, 0x9c, 0xb9, 0xf6, 0x72, 0xff, 0xfc, 0xef, 0x27, 0xef, 0x2c,
+ 0x9c, 0x1e, 0x4e, 0xc1, 0xca, 0x9c, 0xfb, 0x26, 0x16, 0xbc, 0xee, 0xb3,
+ 0x44, 0x66, 0xbf, 0xff, 0xfb, 0x3d, 0xbf, 0x79, 0x3b, 0xf4, 0xb6, 0x20,
+ 0xc5, 0x55, 0x47, 0x91, 0xca, 0x5a, 0x27, 0x34, 0x51, 0x7f, 0x24, 0x32,
+ 0x7c, 0x6c, 0xe5, 0xc3, 0x23, 0x96, 0x61, 0xcb, 0xf2, 0x6b, 0xaf, 0xcf,
+ 0x47, 0xaa, 0xc2, 0xe5, 0x05, 0xaf, 0xe7, 0x92, 0x69, 0xf4, 0x72, 0xff,
+ 0xed, 0xa0, 0x37, 0x82, 0x09, 0x66, 0xce, 0x5e, 0xdc, 0x7c, 0x72, 0xa7,
+ 0x56, 0x95, 0x22, 0x70, 0xa0, 0x61, 0xca, 0x42, 0x63, 0x50, 0xc0, 0x63,
+ 0xc0, 0xa7, 0x6c, 0xb3, 0xc8, 0x77, 0xfd, 0xa7, 0x6f, 0xa9, 0x1a, 0x83,
+ 0x97, 0xfd, 0x2d, 0xe4, 0x72, 0x8d, 0xb0, 0xe5, 0xf7, 0xdd, 0x8d, 0x9c,
+ 0xbd, 0x1e, 0xd9, 0xcb, 0xff, 0x62, 0xbb, 0x8c, 0x10, 0xf6, 0x0e, 0x56,
+ 0xcf, 0x64, 0x03, 0x95, 0x88, 0x9e, 0xdb, 0xe5, 0xff, 0xde, 0x4d, 0x3f,
+ 0xfc, 0xbe, 0x94, 0x30, 0xe5, 0xf8, 0x62, 0x5b, 0x73, 0x94, 0x87, 0xdd,
+ 0xc5, 0x22, 0xdd, 0x39, 0x7f, 0xff, 0xf7, 0x91, 0x9a, 0x4c, 0xf8, 0x41,
+ 0xe8, 0xef, 0x2e, 0x29, 0xe9, 0xa0, 0xe5, 0xb3, 0x11, 0x0f, 0xe1, 0x1b,
+ 0xfc, 0xf2, 0xde, 0xdc, 0x64, 0x72, 0xf2, 0xdc, 0x27, 0x2f, 0xfd, 0xe7,
+ 0x1f, 0xf9, 0x29, 0x9f, 0x36, 0x72, 0xfb, 0xde, 0x86, 0x1c, 0xac, 0x3e,
+ 0x65, 0x51, 0x2f, 0xff, 0x7a, 0x16, 0x9e, 0x46, 0x4d, 0xb4, 0x13, 0x97,
+ 0xf9, 0x99, 0xaf, 0xc4, 0x1f, 0x9c, 0xb4, 0x8e, 0x52, 0x22, 0x3d, 0xd2,
+ 0x54, 0x35, 0xbf, 0x7f, 0x1e, 0x80, 0x9c, 0xa8, 0x4e, 0x29, 0x21, 0x04,
+ 0xf0, 0xb1, 0x01, 0x7d, 0xff, 0xf0, 0x3d, 0xbf, 0xa5, 0x03, 0xfe, 0xf9,
+ 0x00, 0x4e, 0x5e, 0x8f, 0x41, 0xca, 0x09, 0xf7, 0xf1, 0x54, 0xbd, 0xdc,
+ 0x13, 0x94, 0x86, 0xfc, 0x04, 0x97, 0x76, 0x63, 0x97, 0xd9, 0x36, 0x4c,
+ 0x72, 0xfb, 0x34, 0x18, 0x39, 0x77, 0xdb, 0xe4, 0x78, 0x82, 0x47, 0x48,
+ 0x88, 0xc7, 0x5c, 0xbf, 0xef, 0x6f, 0x35, 0xf8, 0x83, 0xf3, 0x97, 0xff,
+ 0xb5, 0x1e, 0xdf, 0x61, 0x3d, 0xb8, 0x9c, 0xe5, 0xf7, 0x9f, 0xb0, 0x72,
+ 0xfb, 0xdd, 0x03, 0x43, 0x97, 0xfb, 0x23, 0x4f, 0x24, 0xe9, 0xcb, 0xfc,
+ 0x8d, 0xee, 0x3a, 0xed, 0x67, 0x2b, 0x47, 0xcf, 0xe3, 0x1a, 0x0a, 0x63,
+ 0x3f, 0x25, 0x21, 0x0b, 0x21, 0x19, 0x7f, 0xf9, 0x3a, 0x06, 0xb0, 0xf4,
+ 0x1b, 0xfa, 0x4e, 0x72, 0xa1, 0x3e, 0x6c, 0x8d, 0x51, 0xd0, 0xef, 0x29,
+ 0x9c, 0x31, 0xcb, 0xff, 0xc0, 0xfd, 0x88, 0x39, 0xf8, 0xe3, 0xcc, 0x72,
+ 0xff, 0x27, 0x52, 0x06, 0x60, 0x1c, 0xbf, 0xc9, 0xac, 0xc1, 0xfb, 0xc7,
+ 0x2a, 0x0f, 0x91, 0xcc, 0xaf, 0xfc, 0x00, 0xeb, 0x01, 0xd8, 0x66, 0x1c,
+ 0xac, 0x4c, 0xbb, 0x44, 0x5d, 0x85, 0x76, 0xc8, 0x2f, 0xff, 0xbe, 0x92,
+ 0x68, 0x3d, 0x06, 0xb1, 0x7d, 0xc3, 0x97, 0x23, 0x67, 0x2e, 0xe0, 0xc3,
+ 0x95, 0xb3, 0x61, 0xe1, 0x7b, 0xfb, 0x71, 0xed, 0xf5, 0x0e, 0x5f, 0x87,
+ 0x19, 0xac, 0x39, 0x7d, 0xae, 0x38, 0x13, 0x95, 0x87, 0xee, 0xc2, 0xd0,
+ 0x13, 0x5e, 0x0e, 0x78, 0xe5, 0xfe, 0xc1, 0xe5, 0xd8, 0xc6, 0xb3, 0x97,
+ 0xfe, 0x4f, 0x6f, 0x03, 0x30, 0xc0, 0x4e, 0x5f, 0x7e, 0x9f, 0x48, 0xe5,
+ 0xfe, 0x81, 0xf2, 0x4e, 0x30, 0x72, 0xff, 0xf2, 0x69, 0x27, 0x81, 0xce,
+ 0xe8, 0x1c, 0x4e, 0x50, 0x53, 0x30, 0x60, 0xe7, 0x4d, 0xbf, 0x3e, 0x12,
+ 0x4f, 0x18, 0xdf, 0xfe, 0x81, 0x5b, 0xf9, 0xd5, 0x52, 0x78, 0x9c, 0xe5,
+ 0xff, 0x90, 0x20, 0xf6, 0xdf, 0xce, 0xa9, 0xcb, 0xfc, 0x98, 0xdf, 0xd2,
+ 0xdf, 0x25, 0x51, 0x16, 0xe9, 0x94, 0xd5, 0xb6, 0x56, 0xf1, 0x0f, 0xc9,
+ 0xd3, 0x64, 0x5c, 0x12, 0x5c, 0x96, 0xcc, 0xac, 0x25, 0x7e, 0x38, 0x48,
+ 0x6c, 0x4d, 0x09, 0x0d, 0x42, 0xa9, 0x84, 0xfd, 0x8e, 0xf1, 0xe1, 0xe7,
+ 0xfc, 0x2b, 0x06, 0x50, 0x3e, 0xe3, 0x62, 0xf2, 0x17, 0x18, 0x40, 0xb4,
+ 0x84, 0xc2, 0x91, 0xaf, 0x70, 0x43, 0x8e, 0xfe, 0x64, 0xa2, 0x36, 0x87,
+ 0x2e, 0x7f, 0xce, 0x54, 0x1e, 0x1b, 0x96, 0x5f, 0x9c, 0x2e, 0xff, 0x1c,
+ 0xbb, 0xdc, 0xfa, 0x78, 0xee, 0x41, 0x7f, 0xff, 0xf0, 0x3e, 0x97, 0x37,
+ 0x1f, 0x63, 0x36, 0x1e, 0xc6, 0x82, 0xee, 0xd9, 0xca, 0xe6, 0xaa, 0xe7,
+ 0x25, 0x0a, 0x89, 0x7d, 0xff, 0xee, 0x6c, 0x79, 0x73, 0xcd, 0x2d, 0xdd,
+ 0x66, 0x89, 0xa5, 0x7f, 0xfb, 0x9b, 0x1e, 0x5c, 0xf3, 0x4b, 0x77, 0x59,
+ 0xa2, 0x71, 0x5f, 0xa5, 0x9e, 0x94, 0x8e, 0x5f, 0xee, 0x31, 0xde, 0x43,
+ 0x12, 0x39, 0x7f, 0xe7, 0x97, 0x3c, 0xd2, 0xdd, 0xd6, 0x68, 0xa0, 0x57,
+ 0xff, 0x92, 0x18, 0xe1, 0xd4, 0x7b, 0xb8, 0x13, 0x97, 0xdb, 0x1f, 0xa4,
+ 0x72, 0xdc, 0xfe, 0x4c, 0x55, 0x0a, 0x18, 0x6d, 0xd4, 0xcf, 0x24, 0x5f,
+ 0xb4, 0xb7, 0x75, 0x9a, 0x2e, 0x05, 0xfc, 0x39, 0xe5, 0xa6, 0xce, 0x5d,
+ 0x08, 0x72, 0xfb, 0xa0, 0x79, 0x1c, 0xbf, 0xc3, 0x28, 0x40, 0xe3, 0x0e,
+ 0x56, 0x23, 0x21, 0x86, 0x9d, 0x2c, 0xf0, 0xa8, 0x08, 0xaf, 0xd2, 0xe6,
+ 0xaf, 0x08, 0xa9, 0xca, 0xe6, 0x7f, 0x70, 0x93, 0x73, 0xfe, 0x72, 0xfd,
+ 0x34, 0xa0, 0x64, 0x72, 0x8e, 0x56, 0x1b, 0x31, 0x28, 0xbe, 0x8f, 0xf1,
+ 0xb3, 0x97, 0x27, 0x3d, 0x22, 0x30, 0x52, 0x94, 0x1f, 0xbf, 0xe9, 0x73,
+ 0xcd, 0x2d, 0xdd, 0x66, 0x89, 0x25, 0x6e, 0x7d, 0x44, 0x23, 0x9e, 0xdc,
+ 0xdf, 0xe7, 0x2f, 0xf3, 0xf8, 0x72, 0x77, 0x13, 0x97, 0x2a, 0xd9, 0xcb,
+ 0xfa, 0x4f, 0xa9, 0xc3, 0x07, 0x2f, 0xec, 0x17, 0xfa, 0x5b, 0x39, 0x7f,
+ 0xfe, 0x00, 0xba, 0xbe, 0x56, 0x06, 0x59, 0xd4, 0x61, 0xcb, 0xfa, 0x19,
+ 0xac, 0x0f, 0x8e, 0x5f, 0xb8, 0x3b, 0x02, 0xa9, 0xcb, 0x9f, 0x98, 0x53,
+ 0x6b, 0x54, 0x67, 0xe3, 0x19, 0x86, 0x74, 0x5c, 0xc2, 0xdd, 0xaa, 0xf8,
+ 0xb6, 0xa7, 0x6f, 0x34, 0xe5, 0x5a, 0xf8, 0xac, 0xe6, 0x65, 0xaf, 0xe3,
+ 0x6f, 0xdc, 0x72, 0xde, 0x8c, 0xcf, 0x8c, 0x72, 0xb7, 0xfe, 0x55, 0xf9,
+ 0xe6, 0x96, 0xee, 0xb3, 0x45, 0xa8, 0xbf, 0xf3, 0xcb, 0x9e, 0x69, 0x6e,
+ 0xeb, 0x34, 0x4a, 0xab, 0x91, 0xb3, 0x94, 0x72, 0xdc, 0xd5, 0x45, 0xdb,
+ 0x13, 0x7c, 0x99, 0xc0, 0x2f, 0x7f, 0x66, 0x96, 0xee, 0xb3, 0x44, 0x52,
+ 0xbf, 0xf3, 0xbb, 0x33, 0x5f, 0x88, 0x3f, 0x39, 0x7f, 0xe8, 0xf6, 0xf3,
+ 0x5f, 0x88, 0x3f, 0x39, 0x7c, 0x9b, 0x87, 0x39, 0x7f, 0x85, 0xff, 0xdf,
+ 0xb1, 0x67, 0x2e, 0x67, 0x3e, 0xa3, 0x48, 0x4f, 0xf6, 0x81, 0xe2, 0x0a,
+ 0xe6, 0x9a, 0xab, 0xc6, 0x17, 0x7f, 0xb9, 0xe6, 0x96, 0xee, 0xb3, 0x44,
+ 0x68, 0xb8, 0x1d, 0x39, 0x7f, 0xe0, 0xe3, 0x13, 0x59, 0xb9, 0xa0, 0xe5,
+ 0xff, 0xff, 0x38, 0x37, 0xdc, 0x0a, 0x8a, 0x6d, 0x14, 0xf2, 0x6e, 0x65,
+ 0x0e, 0x5f, 0xfe, 0x99, 0x13, 0xb3, 0x67, 0xa3, 0xd0, 0x13, 0x97, 0x91,
+ 0xdb, 0x29, 0x48, 0x98, 0x83, 0x59, 0xf4, 0xcd, 0x8c, 0x4a, 0xbe, 0x5b,
+ 0xba, 0xcd, 0x14, 0xfa, 0xef, 0x41, 0xca, 0xd1, 0xe2, 0x78, 0xba, 0xff,
+ 0x27, 0x93, 0xdd, 0x07, 0x8e, 0x5f, 0xf4, 0xd1, 0xee, 0xbc, 0xdc, 0xb0,
+ 0xe5, 0x68, 0xfb, 0xfc, 0x67, 0x78, 0x1d, 0x01, 0xcb, 0xff, 0xc8, 0xc1,
+ 0x07, 0x53, 0x59, 0xb9, 0xa0, 0xe5, 0xff, 0xc0, 0xf6, 0x81, 0x36, 0xd6,
+ 0xf3, 0x6c, 0xe5, 0xff, 0xd9, 0x30, 0x06, 0x7d, 0xad, 0xe6, 0xd9, 0xcb,
+ 0xe0, 0x75, 0x34, 0x72, 0xdc, 0xda, 0xb5, 0x6e, 0xd1, 0x19, 0x3e, 0x42,
+ 0x15, 0x21, 0x23, 0xd2, 0x27, 0x1d, 0x14, 0x9f, 0x24, 0x34, 0x47, 0xbf,
+ 0xfd, 0xcd, 0x8f, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x35, 0x2f, 0xec,
+ 0xd2, 0xdd, 0xd6, 0x68, 0xae, 0xd7, 0xff, 0xb3, 0x81, 0x3c, 0x92, 0xe4,
+ 0x31, 0xed, 0x9c, 0xa3, 0x97, 0x37, 0xcf, 0xa7, 0xb0, 0xda, 0x6d, 0x73,
+ 0x46, 0x1a, 0x42, 0x46, 0xef, 0xd0, 0xe5, 0xed, 0xc3, 0x0e, 0x5c, 0xc1,
+ 0x39, 0x7c, 0xb7, 0x75, 0x9a, 0x2b, 0xe5, 0xe6, 0xdb, 0x6c, 0xa5, 0x84,
+ 0xa7, 0x33, 0x41, 0x5a, 0x3f, 0x06, 0x27, 0x5e, 0x94, 0x7c, 0x72, 0xf4,
+ 0xd9, 0xd3, 0x97, 0xfe, 0xce, 0xb6, 0xfe, 0xdc, 0x64, 0xe7, 0x2d, 0xe3,
+ 0x97, 0xfc, 0x9a, 0xc9, 0xd2, 0x58, 0x13, 0x95, 0xa3, 0xc9, 0x71, 0x1b,
+ 0xf7, 0xdc, 0x1d, 0x02, 0x87, 0x2d, 0xa3, 0x94, 0x72, 0x90, 0xbc, 0xd0,
+ 0x8d, 0xd3, 0xaa, 0x72, 0xba, 0x6e, 0x1c, 0x7e, 0xdc, 0xda, 0x8a, 0xa6,
+ 0x08, 0x17, 0x9c, 0x73, 0x21, 0x0d, 0x31, 0x13, 0x8e, 0x88, 0xee, 0xe1,
+ 0x10, 0x02, 0x16, 0x90, 0x82, 0xbf, 0xfd, 0xcd, 0x8f, 0x2e, 0x79, 0xa5,
+ 0xbb, 0xac, 0xd1, 0x3d, 0xaf, 0xa3, 0x81, 0xfe, 0x39, 0x79, 0x07, 0xf3,
+ 0x95, 0xd3, 0xc1, 0xe2, 0x4b, 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0xb8, 0x56,
+ 0xe7, 0x07, 0xb1, 0x84, 0x97, 0xff, 0x73, 0x79, 0x73, 0xcd, 0x2d, 0xdd,
+ 0x66, 0x89, 0x3d, 0x50, 0xcb, 0xd9, 0x9e, 0x39, 0xe9, 0x15, 0xab, 0x2e,
+ 0xdd, 0x70, 0x9a, 0x9a, 0x31, 0xdd, 0x4a, 0x89, 0xec, 0x2a, 0xb7, 0x0f,
+ 0x3e, 0x25, 0x17, 0xfb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x45, 0x4b, 0xf6,
+ 0x96, 0xee, 0xb3, 0x45, 0x32, 0xbf, 0x93, 0xb8, 0xff, 0x7e, 0x72, 0xdc,
+ 0xf0, 0xf8, 0x9a, 0x1a, 0x5f, 0xfe, 0xe6, 0xc7, 0x97, 0x3c, 0xd2, 0xdd,
+ 0xd6, 0x68, 0x99, 0xd7, 0xff, 0xb9, 0xb1, 0xe5, 0xcf, 0x34, 0xb7, 0x75,
+ 0x9a, 0x28, 0xd5, 0x4e, 0x9c, 0x10, 0x61, 0x46, 0xa9, 0x5f, 0x96, 0xaf,
+ 0xfc, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x11, 0xd2, 0xff, 0xed, 0x4f,
+ 0xcf, 0x63, 0x9e, 0xdc, 0x30, 0xe5, 0xff, 0xfe, 0xd4, 0xb9, 0xe0, 0x83,
+ 0xc0, 0x57, 0xdf, 0x2d, 0x35, 0xb3, 0x95, 0xcd, 0x1f, 0x30, 0x98, 0x88,
+ 0xf7, 0x03, 0xa7, 0x2f, 0x96, 0xb0, 0x2c, 0xe5, 0xfb, 0x04, 0x39, 0x39,
+ 0xcb, 0xfd, 0x10, 0xbc, 0xd6, 0xb0, 0xe5, 0x21, 0xec, 0x09, 0x3d, 0xfb,
+ 0x34, 0xb0, 0x2a, 0x72, 0xff, 0xc3, 0x8a, 0xbc, 0xdb, 0xec, 0x04, 0xe5,
+ 0xe9, 0x9f, 0xc7, 0x2f, 0x96, 0xee, 0xb3, 0x45, 0x34, 0xbf, 0x67, 0xcd,
+ 0xbf, 0x4e, 0x5f, 0xfd, 0xbc, 0x10, 0xc7, 0x26, 0xa3, 0xc7, 0xf4, 0x39,
+ 0x41, 0x4c, 0xa9, 0x0a, 0x66, 0x3f, 0xd0, 0xe8, 0x97, 0x6c, 0xa6, 0xff,
+ 0xff, 0xb0, 0x7d, 0xb4, 0x5e, 0x0e, 0xd7, 0xd4, 0xea, 0xd4, 0x9c, 0xe5,
+ 0xff, 0x6d, 0xfe, 0xc9, 0xa3, 0xbb, 0x39, 0x77, 0x50, 0x51, 0x43, 0xe6,
+ 0x7b, 0xff, 0xa5, 0xd4, 0x19, 0xf6, 0x08, 0xd4, 0xc7, 0x2f, 0x49, 0x92,
+ 0x39, 0x7b, 0xff, 0x21, 0xcb, 0xfd, 0xb5, 0xa6, 0xb4, 0x93, 0x9c, 0xa7,
+ 0x3d, 0x1d, 0x8e, 0xdf, 0xff, 0xf6, 0x4f, 0x38, 0x35, 0x36, 0xe7, 0x89,
+ 0xb7, 0xdc, 0x0a, 0x71, 0x39, 0x7f, 0x80, 0xe2, 0xbe, 0x53, 0xec, 0xe5,
+ 0xfd, 0x03, 0xe6, 0x99, 0xe3, 0x97, 0xf9, 0xff, 0x7f, 0x7b, 0x3a, 0x72,
+ 0xa4, 0x7c, 0x2d, 0x97, 0x5d, 0xd0, 0x1c, 0xac, 0x37, 0x5f, 0x91, 0xdf,
+ 0xee, 0xc2, 0x7e, 0xfe, 0x01, 0xcb, 0xff, 0x08, 0x3d, 0xdc, 0x9a, 0x51,
+ 0xf1, 0xcb, 0x4c, 0x72, 0xfd, 0x9d, 0x71, 0x09, 0xca, 0x9c, 0xdc, 0x7e,
+ 0x25, 0x74, 0x2a, 0x72, 0xfe, 0x7f, 0xf7, 0xc2, 0xb8, 0x57, 0x0a, 0x39,
+ 0x7f, 0x24, 0x32, 0x7c, 0x6c, 0xe5, 0xff, 0xf6, 0x7b, 0xb9, 0x2d, 0x38,
+ 0xfb, 0xaf, 0x23, 0x97, 0x47, 0xe7, 0x2f, 0xf3, 0xfd, 0x0b, 0x45, 0xf3,
+ 0xd2, 0x24, 0xc4, 0xb9, 0x44, 0xea, 0xc4, 0xf8, 0x11, 0xe3, 0xa4, 0x62,
+ 0x2f, 0xb8, 0x6a, 0x5f, 0xbf, 0xec, 0x4b, 0x67, 0x2f, 0x36, 0xf3, 0x9c,
+ 0xbf, 0xe8, 0xfd, 0xfd, 0xfa, 0x83, 0x23, 0x95, 0xd3, 0xd9, 0x11, 0xea,
+ 0x84, 0x51, 0xfa, 0x10, 0x56, 0xe6, 0xd5, 0xb2, 0x18, 0x20, 0x5c, 0x2f,
+ 0x79, 0x1a, 0x52, 0xe1, 0xf1, 0xf1, 0x6a, 0x23, 0x69, 0xbb, 0xa4, 0x3f,
+ 0xb7, 0x0c, 0x34, 0x76, 0x43, 0xe9, 0x42, 0x6a, 0x43, 0xc2, 0xfd, 0xa5,
+ 0xbb, 0xac, 0xd1, 0x55, 0x2f, 0xfc, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd,
+ 0x13, 0x6a, 0xdc, 0xf1, 0x10, 0x0c, 0x34, 0xbf, 0xdc, 0xf3, 0x4b, 0x77,
+ 0x59, 0xa2, 0xbf, 0x5f, 0xb4, 0xb7, 0x75, 0x9a, 0x2c, 0x65, 0xdc, 0x12,
+ 0x39, 0x6e, 0x78, 0x79, 0xd3, 0x1a, 0x5f, 0xb6, 0xbe, 0xc2, 0xa7, 0x2f,
+ 0xf0, 0x82, 0x59, 0xb7, 0xf1, 0xcb, 0xf9, 0xaa, 0x0b, 0x56, 0xd5, 0x8a,
+ 0xa7, 0x2f, 0xf8, 0x41, 0x3c, 0xd2, 0x8d, 0x4e, 0x72, 0xed, 0x78, 0xe5,
+ 0xf3, 0xcb, 0x02, 0x72, 0xfe, 0xf6, 0x68, 0x38, 0x27, 0x2d, 0x81, 0x3c,
+ 0xdf, 0x10, 0xde, 0x56, 0x58, 0x72, 0xfe, 0xcd, 0x7b, 0xb9, 0x39, 0xcb,
+ 0x73, 0xc4, 0xe0, 0x98, 0x65, 0xd3, 0xe7, 0x3c, 0x16, 0x4d, 0x93, 0xa8,
+ 0x3b, 0x64, 0xe6, 0xa8, 0x5b, 0x51, 0xd5, 0xdf, 0xb4, 0xb7, 0x75, 0x9a,
+ 0x2d, 0x55, 0xff, 0x9e, 0x5c, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0x82, 0x5f,
+ 0xa1, 0xb6, 0x99, 0xa3, 0x96, 0xe7, 0x88, 0xaa, 0x61, 0xa2, 0x89, 0x97,
+ 0xfe, 0x76, 0xfd, 0x9d, 0xe6, 0xfa, 0xf1, 0xcb, 0xfd, 0x03, 0xfc, 0x35,
+ 0xbb, 0x0e, 0x5f, 0xfe, 0x9a, 0x38, 0xbe, 0xb7, 0xb4, 0xd6, 0x2a, 0x72,
+ 0xff, 0xa1, 0x26, 0x8e, 0x2f, 0xad, 0x9c, 0xbb, 0x50, 0x72, 0xa4, 0x8d,
+ 0x24, 0x35, 0xea, 0x6f, 0x01, 0xd5, 0xf2, 0xdd, 0xd6, 0x68, 0xb8, 0x97,
+ 0xf0, 0x1f, 0xe0, 0xe6, 0x8e, 0x56, 0x8f, 0x73, 0x65, 0xd7, 0xec, 0x62,
+ 0x70, 0x04, 0xe5, 0xd0, 0xc3, 0x94, 0xd6, 0x78, 0x1a, 0x2a, 0xbe, 0x7e,
+ 0x04, 0x9c, 0xe5, 0xfb, 0xa0, 0x57, 0x04, 0xe5, 0xf8, 0x38, 0xd7, 0x1d,
+ 0x39, 0x7b, 0x81, 0x16, 0x72, 0x82, 0x7e, 0x3a, 0x28, 0xe0, 0x2a, 0xbf,
+ 0xcc, 0x79, 0x6d, 0x03, 0x87, 0x2f, 0xa1, 0x58, 0xd9, 0xcb, 0xf0, 0xf8,
+ 0x5d, 0x53, 0x94, 0x72, 0xdb, 0xc3, 0x64, 0xd0, 0x9e, 0xfe, 0x63, 0xf1,
+ 0x8d, 0x70, 0x1c, 0xbf, 0xf2, 0x07, 0x38, 0xb3, 0x25, 0xf4, 0x8e, 0x54,
+ 0x1f, 0x9e, 0x19, 0x5f, 0xd9, 0xa7, 0xf0, 0x20, 0xe5, 0xff, 0xf3, 0x8c,
+ 0x27, 0x06, 0xd3, 0x79, 0xdc, 0x68, 0x72, 0x82, 0x7f, 0xbc, 0x4b, 0x2f,
+ 0xfe, 0x41, 0x04, 0xb3, 0x7b, 0x40, 0xe1, 0xca, 0x98, 0xf9, 0xbc, 0x49,
+ 0x6e, 0x70, 0xb8, 0x63, 0x90, 0x9b, 0xd3, 0x17, 0x49, 0x5e, 0x12, 0xdf,
+ 0x99, 0x09, 0x96, 0xd5, 0x3d, 0x09, 0xb5, 0x23, 0x03, 0xbf, 0xcd, 0x50,
+ 0xb5, 0x7e, 0x68, 0xd5, 0x84, 0xe5, 0xfb, 0x86, 0xe1, 0x7f, 0xd5, 0x83,
+ 0x97, 0xfe, 0x4f, 0xb8, 0x56, 0xf5, 0xcb, 0x97, 0x5a, 0x1c, 0xbe, 0xec,
+ 0x79, 0x67, 0x29, 0xa8, 0x1f, 0x78, 0x53, 0x6f, 0xff, 0x70, 0xa5, 0x5b,
+ 0x6b, 0x9c, 0x3c, 0x37, 0x2e, 0x5d, 0x68, 0x72, 0xfd, 0xa5, 0xbb, 0xac,
+ 0xd1, 0x74, 0xaf, 0xd0, 0x2e, 0x18, 0x39, 0x7f, 0x4a, 0x3e, 0x7d, 0xc8,
+ 0xe5, 0xe8, 0xf7, 0x01, 0xcb, 0xec, 0x0e, 0x04, 0xe5, 0xff, 0x3f, 0x18,
+ 0xf6, 0xc0, 0xbe, 0x1c, 0xe5, 0xf6, 0xe7, 0x75, 0x0e, 0x5b, 0x9b, 0x52,
+ 0xaa, 0x87, 0x85, 0x22, 0xc4, 0x29, 0x64, 0x51, 0x8c, 0x88, 0x69, 0x31,
+ 0x2f, 0x4b, 0x9c, 0x7c, 0x48, 0x7c, 0x81, 0x7f, 0xfd, 0x83, 0xe4, 0x67,
+ 0x61, 0x05, 0xf4, 0xa9, 0xcb, 0xff, 0x33, 0x60, 0xf4, 0x93, 0x8f, 0x50,
+ 0xe5, 0xfd, 0x99, 0xb5, 0xfa, 0x0e, 0x5f, 0xd3, 0xc7, 0x9d, 0x50, 0x1c,
+ 0xa3, 0x97, 0xff, 0x46, 0xbf, 0xe5, 0xbe, 0xc3, 0x1c, 0x4e, 0x5f, 0xe8,
+ 0xd2, 0x9d, 0xee, 0x7e, 0x72, 0xa4, 0x7f, 0x7d, 0x46, 0xbf, 0xa4, 0xf2,
+ 0x71, 0x59, 0xcb, 0xff, 0xd9, 0xe8, 0x6d, 0x49, 0xf7, 0x8c, 0x86, 0xb3,
+ 0x96, 0xe6, 0xd5, 0x26, 0x47, 0x90, 0x86, 0x98, 0x88, 0x4b, 0x2b, 0x49,
+ 0xd0, 0xb2, 0x35, 0x2b, 0xec, 0x6d, 0xaa, 0x61, 0xcb, 0xf8, 0x63, 0xe6,
+ 0x3f, 0x8e, 0x5f, 0xfe, 0x6d, 0xc3, 0xd8, 0xfb, 0xd1, 0xd7, 0x6b, 0x39,
+ 0x64, 0xd1, 0xfd, 0xf4, 0xb6, 0xff, 0xff, 0x81, 0xa9, 0x6f, 0xae, 0x9a,
+ 0xd6, 0x81, 0xf2, 0x69, 0xf6, 0x72, 0xff, 0xc2, 0xed, 0xfb, 0x3a, 0xf3,
+ 0x39, 0xcb, 0xff, 0xfb, 0xa2, 0x07, 0x6b, 0xc9, 0x77, 0x15, 0xc0, 0xcc,
+ 0x03, 0x97, 0x2f, 0x0e, 0x54, 0x1f, 0xaa, 0xab, 0xf7, 0xf9, 0xfd, 0xb8,
+ 0xea, 0x93, 0x1c, 0xbd, 0x28, 0x61, 0xcb, 0xca, 0xee, 0x47, 0x2f, 0xf6,
+ 0xb4, 0xf2, 0x9f, 0x1b, 0x39, 0x74, 0xc0, 0x39, 0x69, 0x61, 0xe6, 0xb6,
+ 0x6b, 0x7f, 0xf6, 0x06, 0x25, 0x1a, 0x85, 0x1c, 0x4e, 0x5f, 0xfb, 0x8e,
+ 0x49, 0x81, 0x4e, 0x30, 0x13, 0x94, 0xc4, 0x42, 0x3a, 0x15, 0xcf, 0xce,
+ 0x75, 0x58, 0xf3, 0x34, 0x6a, 0x16, 0x7d, 0x22, 0x73, 0x5d, 0x8e, 0x79,
+ 0xad, 0x48, 0x56, 0x57, 0x55, 0xbd, 0x0c, 0xae, 0xeb, 0xfd, 0x2c, 0xf7,
+ 0x61, 0x41, 0x39, 0x7f, 0xef, 0x22, 0xd0, 0x2e, 0x2a, 0xc1, 0xcb, 0xfe,
+ 0x8f, 0xba, 0xfb, 0xf4, 0x36, 0x72, 0xa0, 0xfd, 0xf4, 0x7b, 0x70, 0x3a,
+ 0x72, 0xfc, 0x39, 0xd7, 0xf1, 0xcb, 0xfa, 0x4f, 0x9c, 0x60, 0x27, 0x2b,
+ 0x84, 0x3d, 0x46, 0xa2, 0x4d, 0x7c, 0x80, 0x94, 0x1c, 0xbe, 0x41, 0x8f,
+ 0xce, 0x5f, 0x9e, 0x69, 0x27, 0x8e, 0x5f, 0xfa, 0x03, 0xa8, 0x92, 0x7d,
+ 0xec, 0x39, 0x52, 0x45, 0x42, 0xc8, 0x7f, 0x21, 0xf1, 0x45, 0xff, 0xa3,
+ 0x5b, 0xea, 0x2d, 0x60, 0x9c, 0xe5, 0xff, 0xff, 0x40, 0x7b, 0x9f, 0x78,
+ 0x5f, 0xbf, 0xbe, 0xf6, 0xfa, 0x59, 0xcb, 0xfd, 0x99, 0x8a, 0xaa, 0xf2,
+ 0x39, 0x4a, 0xa2, 0x6b, 0xcc, 0xf7, 0xec, 0xda, 0xfd, 0x07, 0x2f, 0xff,
+ 0x23, 0x7b, 0x5f, 0x53, 0xef, 0x6b, 0x50, 0x72, 0xff, 0xff, 0x9d, 0xb5,
+ 0x33, 0x42, 0xff, 0x49, 0x71, 0xed, 0xe7, 0xde, 0x39, 0x58, 0x8d, 0xcd,
+ 0x13, 0xba, 0x65, 0xfb, 0x8a, 0x6b, 0x02, 0x72, 0xff, 0xfb, 0x7d, 0x4d,
+ 0xfb, 0xb8, 0x14, 0xde, 0x09, 0xcb, 0xdd, 0x81, 0xc3, 0xf7, 0x01, 0x4d,
+ 0xf9, 0xfb, 0x21, 0x59, 0xcb, 0xfd, 0x0c, 0xc4, 0x64, 0x35, 0x9c, 0xbf,
+ 0xd2, 0x66, 0xd0, 0x7e, 0x91, 0xca, 0x59, 0xf4, 0x4c, 0x69, 0x7f, 0xfb,
+ 0x35, 0xa7, 0x96, 0xc7, 0x18, 0xa7, 0xc7, 0x2f, 0x3b, 0xac, 0xd1, 0x26,
+ 0x2f, 0x70, 0x26, 0xce, 0x52, 0xcf, 0x1f, 0x80, 0xa2, 0xfc, 0xbe, 0x15,
+ 0xc3, 0x35, 0x5c, 0x21, 0xcb, 0xff, 0xdf, 0x4b, 0x79, 0xc5, 0xd9, 0x8a,
+ 0xc6, 0xce, 0x5f, 0xec, 0xfb, 0xde, 0x79, 0x6c, 0xe5, 0x42, 0x2f, 0xf0,
+ 0xfb, 0x49, 0xb7, 0xf8, 0x5f, 0xdb, 0x58, 0x04, 0xe5, 0xff, 0xf7, 0xe9,
+ 0xfb, 0x78, 0x9c, 0x47, 0x3d, 0xd4, 0x39, 0x7f, 0x9f, 0xed, 0xbb, 0xcb,
+ 0x67, 0x2d, 0xac, 0x44, 0x2f, 0x54, 0xab, 0x11, 0xbe, 0x90, 0xb7, 0xbf,
+ 0xff, 0xc0, 0x7f, 0xb0, 0x61, 0xb5, 0x3c, 0x31, 0xfe, 0x7d, 0xe3, 0x95,
+ 0x25, 0x7d, 0xe1, 0x31, 0xc8, 0x47, 0xac, 0x8f, 0x50, 0x92, 0x64, 0x39,
+ 0x3b, 0x18, 0x6e, 0xc9, 0xaf, 0xe0, 0xff, 0xc2, 0x6f, 0xf6, 0x87, 0x2f,
+ 0x6d, 0x02, 0x72, 0xfe, 0x18, 0xf9, 0x8f, 0xe3, 0x97, 0xfd, 0x0b, 0xf0,
+ 0x3b, 0xa8, 0x6c, 0xe5, 0xff, 0x26, 0x36, 0xbe, 0xc2, 0x34, 0x39, 0x7f,
+ 0x96, 0x9a, 0xdc, 0xd0, 0xe7, 0x2f, 0xfe, 0x06, 0xfa, 0xf2, 0xeb, 0xca,
+ 0x04, 0xe5, 0x7c, 0x7e, 0xda, 0x33, 0xbb, 0xa9, 0x32, 0x6a, 0xda, 0x1c,
+ 0x61, 0x6f, 0x0e, 0x75, 0xe8, 0x58, 0x5f, 0x79, 0x18, 0xe7, 0x2c, 0xa9,
+ 0xcb, 0xfb, 0xbb, 0x8f, 0x40, 0x4e, 0x56, 0x1b, 0xf4, 0x12, 0xac, 0x3f,
+ 0xff, 0x30, 0x5f, 0xf4, 0x77, 0xc9, 0x3b, 0x21, 0x67, 0x2f, 0xff, 0xce,
+ 0xbd, 0x47, 0x47, 0x3d, 0x9c, 0xdb, 0x6d, 0xb2, 0x95, 0x24, 0x59, 0xec,
+ 0x87, 0xc7, 0x37, 0xf2, 0xd6, 0x05, 0x8c, 0x1c, 0xbf, 0xfb, 0xe9, 0x0c,
+ 0x4b, 0x51, 0xe7, 0xf1, 0xcb, 0xa2, 0x47, 0x2b, 0x0f, 0x68, 0x51, 0x2f,
+ 0xfc, 0xfe, 0x8d, 0x6f, 0xb0, 0x3e, 0x39, 0x7e, 0xc9, 0x23, 0xf1, 0x39,
+ 0x42, 0x7c, 0xbb, 0x3d, 0xa9, 0x22, 0x98, 0x10, 0x85, 0xbc, 0xc7, 0xe9,
+ 0xcb, 0xff, 0xc3, 0x12, 0xd6, 0x81, 0xf2, 0x69, 0xf6, 0x72, 0xff, 0xfb,
+ 0x78, 0xa8, 0xe7, 0xb7, 0x92, 0x17, 0x6c, 0xe5, 0x93, 0xa8, 0x99, 0xf2,
+ 0x55, 0x22, 0x37, 0x78, 0xc2, 0xd6, 0xfb, 0x82, 0x3b, 0xb3, 0x97, 0xfa,
+ 0x7f, 0x0c, 0x03, 0xdb, 0x39, 0x7f, 0x99, 0xec, 0x9a, 0x4e, 0x27, 0x2b,
+ 0x0f, 0x9d, 0x0d, 0x2a, 0x11, 0xab, 0x85, 0x3a, 0x84, 0x65, 0xef, 0xff,
+ 0x83, 0x97, 0xe1, 0x04, 0xff, 0x35, 0x9c, 0xad, 0x9e, 0x5f, 0x87, 0xaf,
+ 0xff, 0x44, 0xe3, 0x99, 0x3f, 0x95, 0x81, 0x91, 0xcb, 0xff, 0x38, 0xcf,
+ 0xd7, 0x62, 0x6d, 0x0e, 0x53, 0xa2, 0xa4, 0x48, 0x9b, 0x4a, 0xbc, 0xdb,
+ 0x6d, 0x94, 0xbe, 0x9d, 0x89, 0xb2, 0x9c, 0xcd, 0x05, 0xd0, 0x13, 0x96,
+ 0xd3, 0x9e, 0x58, 0x9a, 0xdf, 0xa3, 0x05, 0xd8, 0x72, 0xff, 0xcf, 0x2e,
+ 0xa7, 0xdf, 0xe9, 0xc2, 0x72, 0xe0, 0xb6, 0x72, 0xff, 0xfd, 0x9c, 0x60,
+ 0x7c, 0xc8, 0xc1, 0x0e, 0x7d, 0xe3, 0x97, 0x9c, 0x57, 0x39, 0xf6, 0xe8,
+ 0x62, 0xbf, 0x4c, 0x14, 0x49, 0x41, 0x0a, 0xdb, 0xfd, 0x28, 0xd4, 0xf1,
+ 0xa9, 0xce, 0x5f, 0xdb, 0xda, 0x60, 0xfe, 0x72, 0xf6, 0xb1, 0xac, 0xe5,
+ 0xff, 0x36, 0xa4, 0xfb, 0xc6, 0x43, 0x59, 0xcb, 0xff, 0xc8, 0xbc, 0x10,
+ 0xe9, 0xd7, 0x9f, 0x78, 0xe5, 0x42, 0x22, 0x36, 0x7f, 0x5a, 0x47, 0xb3,
+ 0x0b, 0x7d, 0x0a, 0x7a, 0x84, 0xd8, 0x32, 0x32, 0xbb, 0xff, 0xe4, 0x98,
+ 0x63, 0xdb, 0xf7, 0xcb, 0x41, 0x9c, 0xe5, 0xff, 0xff, 0xe4, 0x1f, 0xd4,
+ 0x1c, 0xd6, 0xb1, 0xbc, 0x6b, 0xc1, 0x8f, 0xd8, 0xf2, 0x39, 0x7f, 0xff,
+ 0x7b, 0x60, 0x0f, 0x53, 0x26, 0x74, 0x6b, 0x4f, 0xa4, 0x72, 0xff, 0xfe,
+ 0x1c, 0xfd, 0xc7, 0xfd, 0x6b, 0x1b, 0xcf, 0xdf, 0xe3, 0x94, 0x28, 0xbc,
+ 0xf2, 0xfd, 0xf9, 0x3d, 0x3e, 0x36, 0x72, 0xff, 0xa1, 0x7d, 0x10, 0x7a,
+ 0x36, 0x72, 0xff, 0xe4, 0xe0, 0x85, 0xc3, 0x30, 0x2e, 0xc3, 0x97, 0xff,
+ 0xa2, 0x5b, 0xc8, 0x0a, 0x0b, 0xe9, 0x53, 0x97, 0xff, 0xef, 0x77, 0x25,
+ 0xc9, 0x7d, 0x4f, 0x7c, 0xb4, 0xd1, 0xca, 0x92, 0xa9, 0xf4, 0x8c, 0xdb,
+ 0x44, 0x4c, 0x29, 0xe9, 0xc7, 0xe8, 0xa2, 0x91, 0x7f, 0xff, 0xba, 0x82,
+ 0x1d, 0x62, 0xfb, 0x1d, 0xcd, 0x6a, 0x15, 0x39, 0x7f, 0xe5, 0xac, 0x0d,
+ 0x7b, 0x46, 0xf3, 0x47, 0x2f, 0xff, 0xfc, 0x9e, 0x06, 0x9f, 0x6b, 0xea,
+ 0x4c, 0x2e, 0xdf, 0xb3, 0xac, 0x39, 0x48, 0x8b, 0x07, 0x43, 0xbf, 0xe6,
+ 0x46, 0xb8, 0xe6, 0xa2, 0x63, 0x97, 0xfe, 0xd2, 0xd9, 0x1f, 0x6f, 0x38,
+ 0xe1, 0xcb, 0x9d, 0xac, 0xe5, 0xff, 0xfd, 0x30, 0xc0, 0x73, 0xef, 0x64,
+ 0xa0, 0x67, 0x66, 0x1c, 0xbf, 0xbf, 0x69, 0x81, 0xc6, 0x1c, 0xae, 0xa2,
+ 0x2c, 0x56, 0xef, 0xe1, 0xe4, 0xd3, 0x35, 0x07, 0x2a, 0x13, 0x37, 0x9d,
+ 0x07, 0x21, 0x48, 0xe4, 0x57, 0xf9, 0xff, 0xe5, 0x81, 0x79, 0x1c, 0xb2,
+ 0xa7, 0x2f, 0xfe, 0xc5, 0xf6, 0x3b, 0x9a, 0xd4, 0x2a, 0x72, 0xfd, 0x9a,
+ 0xd4, 0x2a, 0x72, 0xf8, 0x53, 0xfd, 0xc1, 0xff, 0x68, 0x4b, 0xa8, 0x97,
+ 0xfe, 0xce, 0xbf, 0xec, 0x79, 0x3e, 0xce, 0x56, 0x26, 0x6c, 0x90, 0xb3,
+ 0xea, 0x2d, 0xff, 0xe7, 0x9f, 0xa9, 0x03, 0x93, 0x26, 0x90, 0xe5, 0x05,
+ 0x7f, 0xc7, 0x25, 0x78, 0x4c, 0xd7, 0xd8, 0xc4, 0x3f, 0x21, 0xdc, 0x6e,
+ 0x5e, 0x8d, 0xdd, 0xb3, 0x4b, 0xf0, 0xe7, 0x5f, 0xc7, 0x2f, 0xfd, 0x28,
+ 0x19, 0xd4, 0xd0, 0x82, 0x47, 0x2f, 0xe1, 0x70, 0xff, 0xf7, 0xe7, 0x29,
+ 0xad, 0x12, 0xd3, 0x13, 0x6d, 0x02, 0xfb, 0xd3, 0xe0, 0x4e, 0x5f, 0xf2,
+ 0x2a, 0xa6, 0xbf, 0x62, 0x6c, 0xe5, 0x4c, 0x7b, 0xed, 0x08, 0xef, 0x36,
+ 0xdb, 0x67, 0x2f, 0xff, 0xd8, 0xcf, 0x0c, 0x7f, 0x81, 0xde, 0x32, 0x16,
+ 0x53, 0x99, 0xa0, 0xbf, 0xf6, 0x7d, 0xc8, 0x73, 0x8e, 0x93, 0x67, 0x2f,
+ 0xe5, 0xf5, 0x20, 0x56, 0x72, 0xa0, 0xfb, 0xb1, 0x0a, 0xff, 0x6a, 0x3c,
+ 0x8b, 0x40, 0x9c, 0xbf, 0x4a, 0x6c, 0xc5, 0x9c, 0xb6, 0x8e, 0x53, 0x52,
+ 0x7d, 0x70, 0x64, 0xa1, 0x45, 0x62, 0xa6, 0xb4, 0x84, 0x9f, 0x51, 0x46,
+ 0x1a, 0x9b, 0x84, 0x5d, 0xef, 0x4b, 0xa7, 0x2c, 0x87, 0x2f, 0xee, 0xc7,
+ 0x25, 0xa4, 0xe7, 0x2f, 0xff, 0x4d, 0xd7, 0x66, 0x69, 0x55, 0x40, 0x3e,
+ 0x39, 0x7f, 0x69, 0xf4, 0x31, 0x23, 0x97, 0xff, 0xcf, 0xee, 0xe7, 0x1e,
+ 0xa7, 0x2d, 0xed, 0x18, 0x72, 0xff, 0xc9, 0x24, 0xd7, 0xd0, 0x31, 0xb3,
+ 0x95, 0xc2, 0xe9, 0xa4, 0x84, 0x43, 0x0c, 0x34, 0x9a, 0x25, 0x9e, 0x53,
+ 0xba, 0x5c, 0xda, 0xb7, 0x42, 0x23, 0xc3, 0x35, 0xc4, 0x35, 0x67, 0x3e,
+ 0x94, 0x36, 0x83, 0x18, 0x06, 0x4e, 0x4a, 0x2b, 0x08, 0x75, 0xc7, 0x1d,
+ 0xf4, 0x72, 0x68, 0x61, 0x34, 0x65, 0xba, 0x8f, 0x6b, 0xb1, 0x93, 0xbc,
+ 0x26, 0xbf, 0x8c, 0xac, 0x63, 0x96, 0xdd, 0x20, 0x67, 0xd2, 0xe4, 0x1a,
+ 0x2c, 0x29, 0x1b, 0x35, 0xff, 0xed, 0x63, 0x61, 0xee, 0x4c, 0x39, 0xa9,
+ 0x1c, 0xbd, 0xac, 0x6b, 0x39, 0x7f, 0xe8, 0x6d, 0x49, 0xf7, 0x8c, 0x86,
+ 0xb3, 0x95, 0xa4, 0x57, 0x31, 0x2f, 0xc3, 0xf7, 0xff, 0xce, 0xc8, 0xd2,
+ 0xf4, 0x05, 0x74, 0x07, 0xd9, 0xca, 0xc4, 0x40, 0x80, 0xc2, 0xff, 0x69,
+ 0x60, 0x70, 0xb2, 0x0e, 0x5f, 0xfd, 0x1a, 0x53, 0xc9, 0xee, 0xe0, 0x50,
+ 0xe5, 0xfe, 0x1f, 0xbf, 0xcd, 0xbb, 0x59, 0xcb, 0xfe, 0x18, 0x9d, 0x4e,
+ 0xf5, 0xda, 0xce, 0x56, 0x1f, 0xa7, 0x4d, 0xef, 0xff, 0xf9, 0x05, 0x3f,
+ 0xde, 0xb1, 0x7d, 0x8e, 0xe6, 0xb5, 0x0a, 0x9c, 0xa8, 0x4d, 0xca, 0x73,
+ 0x3c, 0x85, 0xc7, 0x88, 0x6f, 0x35, 0x16, 0xa6, 0x47, 0x2f, 0x3e, 0xa7,
+ 0x39, 0x73, 0x6d, 0x9c, 0xbc, 0xeb, 0xe6, 0xb3, 0x6c, 0xd8, 0xed, 0xfd,
+ 0x1a, 0x79, 0x27, 0x4e, 0x5f, 0xb1, 0x9d, 0x70, 0x9c, 0xb7, 0x38, 0x75,
+ 0xc6, 0x32, 0x4d, 0x0a, 0x0e, 0x47, 0x9a, 0xa9, 0x52, 0xe7, 0x07, 0x66,
+ 0x2b, 0xd4, 0x2a, 0x9e, 0xd0, 0x99, 0x0c, 0xac, 0xcd, 0xc7, 0x29, 0xe4,
+ 0x2e, 0x2b, 0xcd, 0x9a, 0xf0, 0x16, 0x54, 0x9f, 0x19, 0xf8, 0x34, 0x89,
+ 0x0f, 0xa3, 0x6b, 0xd1, 0x53, 0x21, 0x1f, 0xd9, 0x48, 0x1f, 0xc3, 0x70,
+ 0x4e, 0x37, 0x3a, 0x89, 0xe9, 0x69, 0x40, 0xb5, 0xdb, 0xf7, 0xf6, 0xe2,
+ 0x69, 0x24, 0xc7, 0x2f, 0xfb, 0xd0, 0x29, 0xfe, 0x7d, 0xe3, 0x97, 0xcd,
+ 0x1c, 0x7f, 0x39, 0x74, 0x4f, 0x87, 0xba, 0xa1, 0xcd, 0x6d, 0x17, 0x4a,
+ 0x42, 0x32, 0xff, 0x91, 0x68, 0x1e, 0x7d, 0x8f, 0xce, 0x57, 0x33, 0xe4,
+ 0xf1, 0x4d, 0xff, 0x9d, 0x7c, 0xc1, 0xfa, 0x4b, 0x24, 0x72, 0xfd, 0xa5,
+ 0xbb, 0xac, 0xd1, 0x1a, 0xaf, 0x2b, 0xf6, 0xce, 0x5b, 0x9c, 0xe8, 0x94,
+ 0xc4, 0x1f, 0x1a, 0x5f, 0xff, 0xee, 0x30, 0x3e, 0xe6, 0xfc, 0x5c, 0x38,
+ 0x17, 0x63, 0x84, 0xe5, 0xfb, 0x4b, 0x77, 0x59, 0xa2, 0xa5, 0x5c, 0xeb,
+ 0x34, 0x43, 0x4b, 0x73, 0xc3, 0xd7, 0x73, 0x4b, 0xf6, 0x96, 0xee, 0xb3,
+ 0x44, 0x7c, 0xbf, 0xf8, 0x1a, 0xfd, 0x7d, 0x49, 0x86, 0x3f, 0x39, 0x7f,
+ 0xfc, 0x2f, 0xe9, 0x42, 0xbc, 0xa3, 0xdb, 0x8f, 0xce, 0x5e, 0x79, 0x73,
+ 0xc4, 0x66, 0xec, 0xd1, 0x44, 0x7b, 0xff, 0x3c, 0xf1, 0xd4, 0xd2, 0x43,
+ 0x0e, 0x5f, 0xe8, 0xd6, 0x0f, 0xb3, 0xa7, 0x2f, 0x33, 0x39, 0xb4, 0x3e,
+ 0xe5, 0x0f, 0x6b, 0x9a, 0x3a, 0x62, 0x16, 0x37, 0xff, 0xfd, 0x20, 0x69,
+ 0x57, 0xde, 0x06, 0x3e, 0xda, 0x9e, 0x55, 0x15, 0x39, 0x79, 0xb5, 0x56,
+ 0x72, 0xfd, 0xf7, 0xd2, 0xcf, 0x1c, 0xad, 0x9e, 0x48, 0x07, 0xef, 0xff,
+ 0x70, 0xa5, 0x5b, 0x6b, 0x9c, 0x3c, 0x37, 0x2e, 0x5d, 0x68, 0x72, 0xfd,
+ 0xa5, 0xbb, 0xac, 0xd1, 0x63, 0xaf, 0xf6, 0x20, 0xcf, 0xec, 0xe9, 0xcb,
+ 0x9f, 0x67, 0x2f, 0xe9, 0xd4, 0xd6, 0xb3, 0x47, 0x2a, 0x47, 0x8c, 0xe2,
+ 0xd7, 0xfc, 0x2e, 0xaf, 0x52, 0x06, 0x73, 0x97, 0xff, 0xf0, 0x05, 0xd5,
+ 0xe5, 0xe5, 0x60, 0x65, 0x9d, 0x46, 0x1c, 0xbf, 0xff, 0x7f, 0x29, 0xf8,
+ 0x54, 0x35, 0x73, 0xaf, 0x5c, 0xb9, 0x75, 0xa1, 0xcb, 0x92, 0x47, 0x2f,
+ 0xf7, 0x87, 0x38, 0xf5, 0xe4, 0x72, 0x82, 0x79, 0x58, 0x2d, 0x7e, 0x4f,
+ 0x79, 0x3c, 0x72, 0xff, 0xfc, 0x01, 0x75, 0x7c, 0xac, 0x0c, 0xb3, 0xa8,
+ 0xc3, 0x97, 0xda, 0xd6, 0x34, 0x39, 0x58, 0x8a, 0x06, 0x13, 0xba, 0xad,
+ 0xfb, 0x35, 0x99, 0x31, 0xcb, 0x73, 0x85, 0xc6, 0x99, 0xe1, 0x6b, 0x22,
+ 0x2c, 0x64, 0x54, 0xd1, 0x1e, 0x26, 0x21, 0x61, 0xc7, 0x57, 0x46, 0x16,
+ 0xdb, 0x86, 0x0a, 0x85, 0xd7, 0xca, 0xa6, 0xa6, 0x39, 0x7b, 0x85, 0x31,
+ 0x53, 0x97, 0xf7, 0x08, 0x39, 0xd7, 0xf1, 0xcb, 0xfc, 0xff, 0xed, 0xfd,
+ 0xe7, 0x39, 0x73, 0x16, 0x72, 0x84, 0xf2, 0xbc, 0x67, 0x7f, 0xec, 0x6f,
+ 0x58, 0x2f, 0xf4, 0xb6, 0x72, 0xfd, 0xd7, 0x64, 0x09, 0xcb, 0xed, 0xf5,
+ 0x1b, 0x39, 0x7e, 0x86, 0xfd, 0x9d, 0x39, 0x7a, 0x14, 0xc3, 0x95, 0xc9,
+ 0x11, 0xb8, 0x4c, 0x24, 0x7b, 0x28, 0xbf, 0xfd, 0x9c, 0x18, 0xbf, 0x7d,
+ 0x2c, 0x1f, 0xdc, 0xe5, 0xf7, 0xec, 0x4d, 0x1c, 0xbd, 0x8e, 0x27, 0x2f,
+ 0x76, 0x26, 0x39, 0x72, 0x79, 0x0d, 0xbb, 0x8d, 0x5f, 0xff, 0xf4, 0x68,
+ 0x70, 0x39, 0xde, 0xa2, 0xfa, 0x9e, 0xdb, 0xfc, 0x72, 0xff, 0xfd, 0x93,
+ 0x67, 0x00, 0xe7, 0x11, 0xcf, 0xd9, 0x12, 0x39, 0x7f, 0xcf, 0xf0, 0xe7,
+ 0xb7, 0x8d, 0x9c, 0xa5, 0xa7, 0x90, 0x89, 0xad, 0x6b, 0x5d, 0x2a, 0x16,
+ 0x50, 0x2c, 0xdf, 0xba, 0x9a, 0x04, 0x8e, 0x5f, 0xd1, 0xaf, 0xda, 0x03,
+ 0xc7, 0x2f, 0xfa, 0x07, 0xdc, 0x33, 0xf8, 0x10, 0x72, 0xff, 0xf4, 0x76,
+ 0x18, 0xbe, 0xa7, 0xb3, 0x18, 0x72, 0xfb, 0xff, 0xd1, 0x43, 0x97, 0xe9,
+ 0x6e, 0x7c, 0x6c, 0xe5, 0xf7, 0x73, 0x53, 0x9c, 0xbc, 0xee, 0xb3, 0x45,
+ 0xa0, 0xbf, 0xf3, 0xb7, 0xc0, 0xb7, 0xd4, 0xf8, 0xd9, 0xcb, 0xfb, 0xf8,
+ 0x18, 0xf6, 0xce, 0x54, 0x23, 0x98, 0x25, 0x4b, 0x23, 0xd1, 0x47, 0xe8,
+ 0x97, 0xff, 0xff, 0xc9, 0xae, 0xb8, 0xa4, 0x79, 0x3b, 0x1b, 0xee, 0x6f,
+ 0x58, 0xbc, 0xf1, 0xcb, 0xff, 0xff, 0xc0, 0xdb, 0xea, 0x5b, 0x40, 0xe6,
+ 0xa7, 0x4d, 0xf5, 0xff, 0xde, 0x09, 0xcb, 0xfa, 0x27, 0x63, 0xb8, 0x9c,
+ 0xbf, 0xff, 0x77, 0x1b, 0xf3, 0x23, 0x3d, 0xdc, 0xc1, 0x59, 0xcb, 0xff,
+ 0xf2, 0x7a, 0x59, 0xad, 0x3c, 0x94, 0x17, 0xf6, 0xce, 0x54, 0x2b, 0xf8,
+ 0x91, 0x40, 0x4c, 0x56, 0x78, 0x89, 0x1a, 0x8c, 0x2f, 0xa9, 0x42, 0xf3,
+ 0xb7, 0x8f, 0x16, 0x71, 0x54, 0xbb, 0x18, 0x72, 0xff, 0xe7, 0xfb, 0x8f,
+ 0x5a, 0xd3, 0xc3, 0x0c, 0x39, 0x5a, 0x3d, 0xf7, 0x16, 0xbf, 0xff, 0x27,
+ 0xb6, 0xff, 0x6f, 0x79, 0xd4, 0xd8, 0x27, 0x39, 0x7f, 0xfc, 0x09, 0xf4,
+ 0x9e, 0x9c, 0x1a, 0x96, 0xda, 0xd0, 0xe5, 0x75, 0x15, 0xa2, 0xaf, 0x7f,
+ 0x6d, 0xd4, 0xcf, 0xbc, 0x72, 0xff, 0x20, 0x71, 0x9c, 0xb0, 0x27, 0x2f,
+ 0xff, 0x81, 0xad, 0x40, 0xe2, 0xa9, 0xde, 0xe2, 0x87, 0x2d, 0xc3, 0x9c,
+ 0xad, 0x1f, 0x30, 0x14, 0x2f, 0xf3, 0x00, 0x3e, 0xd8, 0x34, 0x72, 0xa4,
+ 0x8f, 0x0d, 0x42, 0x69, 0xa1, 0x15, 0xfc, 0x3f, 0x4b, 0xc0, 0x09, 0xcb,
+ 0xf3, 0x5e, 0x0b, 0x10, 0xe5, 0x41, 0xec, 0x39, 0x7d, 0xff, 0xce, 0xdf,
+ 0xb3, 0xbb, 0x9b, 0x32, 0x73, 0x97, 0xe9, 0xbb, 0x9f, 0xb9, 0xca, 0xea,
+ 0x23, 0xc4, 0x83, 0x8a, 0x35, 0xff, 0xfe, 0xcc, 0xf6, 0xe2, 0x6e, 0xc7,
+ 0x11, 0xc0, 0xf6, 0x36, 0x72, 0xfc, 0x2b, 0x7d, 0xa1, 0xcb, 0xff, 0xfb,
+ 0x43, 0x11, 0xf7, 0x2d, 0xf8, 0x60, 0x3d, 0x8f, 0x1c, 0xb9, 0x3a, 0x72,
+ 0xfa, 0x42, 0xea, 0x1c, 0xbf, 0xc1, 0x7f, 0xf5, 0xa7, 0xfc, 0xe5, 0xf6,
+ 0x96, 0xd6, 0xd9, 0xcb, 0xe5, 0x78, 0x47, 0x6c, 0xe5, 0x61, 0xe8, 0x39,
+ 0x3d, 0x22, 0x29, 0x46, 0x10, 0xb5, 0x09, 0xc2, 0xe1, 0x33, 0x5a, 0xe3,
+ 0x8b, 0x02, 0x18, 0xf7, 0x9d, 0xad, 0x0e, 0x5f, 0xf9, 0x4f, 0x2a, 0x8a,
+ 0xc6, 0x0c, 0x1c, 0xbf, 0x29, 0xe1, 0x8f, 0xce, 0x57, 0xc8, 0x86, 0xd0,
+ 0xf7, 0x13, 0xfb, 0xf4, 0x7b, 0x3b, 0x07, 0x2f, 0xfd, 0x9f, 0x4b, 0x69,
+ 0xe7, 0x1c, 0x39, 0x7f, 0xb1, 0x9d, 0xc9, 0x9e, 0x63, 0x97, 0xfe, 0xea,
+ 0x07, 0x12, 0x7e, 0xc4, 0x72, 0x3f, 0x1f, 0x1e, 0xdf, 0xff, 0xfd, 0x08,
+ 0x39, 0xe8, 0x63, 0x60, 0x79, 0xf9, 0x67, 0x53, 0x5d, 0x73, 0x97, 0xfe,
+ 0xcf, 0xa5, 0xb9, 0xb4, 0xfe, 0xd9, 0xcb, 0xf0, 0xc2, 0xe4, 0xc3, 0x97,
+ 0xff, 0x6f, 0x26, 0xec, 0x71, 0xce, 0xf6, 0x0e, 0x50, 0x4f, 0xb7, 0xc4,
+ 0xf7, 0xf9, 0xff, 0xdb, 0x1f, 0xef, 0x1c, 0xac, 0x3d, 0x77, 0x22, 0xbf,
+ 0xd1, 0x13, 0x67, 0x14, 0xd1, 0xcb, 0xe4, 0xd6, 0x09, 0xca, 0x13, 0xd4,
+ 0xd9, 0xa5, 0x4e, 0xab, 0xe5, 0x70, 0x97, 0xd2, 0xb7, 0xee, 0x43, 0x18,
+ 0x2f, 0x9d, 0x2f, 0xdc, 0xa6, 0x92, 0x4c, 0x72, 0xa1, 0x5d, 0xee, 0x4b,
+ 0x2c, 0x46, 0x5b, 0xff, 0xba, 0x9c, 0xb0, 0x71, 0x34, 0xfc, 0x4e, 0x5f,
+ 0xfc, 0x82, 0xe1, 0x1c, 0x0f, 0x63, 0x67, 0x2f, 0x29, 0x1a, 0x39, 0x7f,
+ 0xff, 0xbb, 0x03, 0x9f, 0xef, 0x03, 0xd8, 0x9d, 0x80, 0x10, 0x9c, 0xbf,
+ 0x27, 0xbd, 0x12, 0x39, 0x4a, 0xa6, 0x56, 0xb4, 0x5d, 0x20, 0xf8, 0x77,
+ 0x8b, 0x0d, 0xff, 0xfd, 0x13, 0x60, 0x7b, 0x1c, 0x7b, 0x9e, 0x18, 0x86,
+ 0x1c, 0xbf, 0xbe, 0xda, 0x93, 0x80, 0x4e, 0x5f, 0xf4, 0x2f, 0xa9, 0x33,
+ 0xbc, 0xe7, 0x29, 0x88, 0xc5, 0x75, 0xbf, 0xcc, 0x6f, 0xf4, 0xa3, 0x53,
+ 0xc6, 0xa7, 0x39, 0x7f, 0xe4, 0xe2, 0xe3, 0xff, 0x73, 0xf7, 0x39, 0x7f,
+ 0x0c, 0xef, 0xd4, 0x13, 0x97, 0xfc, 0x80, 0x19, 0x6a, 0x30, 0x27, 0x2f,
+ 0xff, 0xfb, 0xb9, 0x25, 0xf5, 0x3b, 0x19, 0xa9, 0x78, 0x61, 0x9b, 0x39,
+ 0x7c, 0x08, 0xf8, 0x27, 0x28, 0x29, 0x95, 0xba, 0x06, 0xcb, 0x3c, 0x6e,
+ 0xdb, 0x2d, 0xf7, 0x04, 0x6a, 0x73, 0x95, 0x09, 0xe8, 0xe4, 0x6c, 0x0e,
+ 0x97, 0x7f, 0xb4, 0xb9, 0xb1, 0x3a, 0x03, 0x97, 0xfe, 0x4e, 0x23, 0x9b,
+ 0xf2, 0xa8, 0xb3, 0x97, 0xfb, 0xdd, 0x6b, 0x4e, 0xbc, 0xc7, 0x2f, 0xe8,
+ 0x58, 0xbf, 0xde, 0x39, 0x52, 0x45, 0x23, 0x5a, 0x03, 0x0d, 0xef, 0xd1,
+ 0xe9, 0xf1, 0xb3, 0x97, 0xfe, 0xf9, 0x62, 0xf3, 0xbc, 0x93, 0xa7, 0x2b,
+ 0x47, 0xd0, 0x02, 0x9b, 0xce, 0x3f, 0x9c, 0xbf, 0xff, 0xfe, 0x40, 0x6b,
+ 0xb9, 0x34, 0xcf, 0xa9, 0xbd, 0xd0, 0x7f, 0xbc, 0x4e, 0x21, 0x83, 0x97,
+ 0xef, 0x75, 0xc5, 0x53, 0x97, 0xfc, 0x20, 0x9c, 0x3d, 0xc1, 0x83, 0x96,
+ 0xc0, 0xa3, 0x8f, 0x21, 0x06, 0xb2, 0x8b, 0xff, 0xbf, 0x5f, 0xe3, 0x9e,
+ 0xdb, 0xb8, 0x9c, 0xbc, 0xc7, 0xf8, 0xe5, 0x68, 0xf8, 0x7f, 0x44, 0xa8,
+ 0x56, 0xa3, 0x90, 0xd8, 0x48, 0x4d, 0xb9, 0x10, 0xc3, 0xfc, 0x10, 0x9a,
+ 0xbf, 0xd9, 0xd9, 0x93, 0xa8, 0xc3, 0x97, 0xfa, 0x59, 0xad, 0x8c, 0x4e,
+ 0x72, 0xf3, 0x4c, 0x9c, 0xe5, 0xff, 0x40, 0xc2, 0xf4, 0x90, 0xc3, 0x97,
+ 0xb3, 0xae, 0x72, 0xfd, 0x30, 0x40, 0x01, 0x39, 0x41, 0x3c, 0x47, 0x1b,
+ 0xbc, 0xd6, 0x8c, 0x39, 0x7f, 0xfe, 0x77, 0xff, 0x71, 0xff, 0xb1, 0x03,
+ 0x83, 0x31, 0xce, 0x97, 0xf7, 0xf3, 0x78, 0xb5, 0xe3, 0x67, 0x2f, 0x42,
+ 0xf8, 0x9c, 0xac, 0x3c, 0xdf, 0x17, 0xdf, 0xf7, 0xcc, 0xcc, 0x1f, 0x34,
+ 0xc3, 0x97, 0x95, 0x90, 0x0e, 0x5f, 0xbb, 0x1a, 0x9d, 0x87, 0x2f, 0xf0,
+ 0x1c, 0x7b, 0x8f, 0x31, 0xcb, 0x7d, 0x31, 0xed, 0xb6, 0x53, 0x48, 0x8a,
+ 0x47, 0x79, 0xac, 0x4c, 0x81, 0xc8, 0x46, 0x1b, 0xd5, 0x8a, 0xd0, 0xfe,
+ 0x33, 0x43, 0x3e, 0x8f, 0xbb, 0xd0, 0xa0, 0x6e, 0x3d, 0x1b, 0xc3, 0x9f,
+ 0x9c, 0xb4, 0x1c, 0xaf, 0xcd, 0x67, 0x87, 0x2e, 0x7f, 0x1c, 0xad, 0x1b,
+ 0x8e, 0x91, 0x5f, 0x32, 0x35, 0xb3, 0x97, 0xfd, 0xac, 0xee, 0x4f, 0xc9,
+ 0x36, 0x72, 0xb0, 0xff, 0x90, 0x84, 0x04, 0x57, 0xf2, 0x08, 0x25, 0x9b,
+ 0x39, 0x7f, 0xec, 0xf4, 0x7d, 0xfb, 0xf7, 0xa8, 0x72, 0xcc, 0x39, 0x7f,
+ 0x20, 0x82, 0x59, 0xbe, 0x47, 0xa1, 0xc4, 0xfe, 0x95, 0x46, 0x1f, 0x9f,
+ 0x2d, 0xcd, 0xa9, 0x74, 0x1b, 0xed, 0x59, 0x27, 0x0c, 0x49, 0x0f, 0x73,
+ 0x90, 0xca, 0x19, 0x81, 0x94, 0x0b, 0x93, 0x8a, 0x2a, 0xc3, 0xf9, 0x70,
+ 0xce, 0xf8, 0x89, 0x23, 0x1f, 0x9a, 0x31, 0xed, 0x18, 0xb2, 0x3e, 0x6e,
+ 0xce, 0x49, 0xbc, 0x6c, 0x3f, 0xc6, 0x26, 0x32, 0x80, 0x77, 0x2e, 0x17,
+ 0xd2, 0xea, 0xda, 0x46, 0x96, 0xa4, 0x3c, 0x2f, 0xee, 0x04, 0x08, 0xc4,
+ 0xc7, 0x2f, 0x43, 0x89, 0xcb, 0xec, 0xeb, 0xf8, 0xe5, 0xb8, 0x4c, 0x3e,
+ 0xbe, 0x98, 0x08, 0xd5, 0xff, 0xff, 0xee, 0xb8, 0xfb, 0x70, 0x92, 0xce,
+ 0x01, 0xf4, 0x76, 0x15, 0x04, 0x70, 0x1c, 0xbe, 0xcd, 0xfe, 0x87, 0x2f,
+ 0xda, 0x5b, 0xba, 0xcd, 0x16, 0xb2, 0xff, 0x31, 0x18, 0xf3, 0x67, 0x4e,
+ 0x5f, 0xd9, 0xc1, 0xb7, 0x15, 0x9c, 0xbd, 0xa8, 0x61, 0xcb, 0xfb, 0xb9,
+ 0xb8, 0x9f, 0x80, 0xe5, 0xff, 0x4b, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x50,
+ 0x6a, 0xc3, 0xf8, 0x73, 0x1b, 0xec, 0x9a, 0x3c, 0x72, 0xff, 0xa2, 0x51,
+ 0xa9, 0xe3, 0x53, 0x9c, 0xbe, 0x57, 0xd9, 0xd3, 0x97, 0xf9, 0x22, 0x6f,
+ 0xdc, 0x66, 0x39, 0x7f, 0xfd, 0xb4, 0x9d, 0xf6, 0xe2, 0xfe, 0xec, 0x4c,
+ 0x72, 0xff, 0xce, 0x3f, 0xe7, 0xa0, 0x53, 0xf3, 0x95, 0xe4, 0x46, 0x34,
+ 0x4f, 0xb7, 0x3e, 0x19, 0x5c, 0x1c, 0x1c, 0x49, 0xef, 0x08, 0x90, 0xd2,
+ 0x63, 0x3d, 0x17, 0xb2, 0x12, 0x9d, 0x20, 0x12, 0x2d, 0x9d, 0x78, 0x8d,
+ 0x48, 0x60, 0x5f, 0xfe, 0xe6, 0xc7, 0x97, 0x3c, 0xd2, 0xdd, 0xd6, 0x68,
+ 0xa2, 0xd7, 0xfb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x5d, 0x4a, 0x87, 0x61,
+ 0x87, 0x28, 0x5c, 0x61, 0xc2, 0xe1, 0x76, 0x91, 0xef, 0x32, 0x72, 0x4b,
+ 0xb6, 0x86, 0x7b, 0xf9, 0xda, 0x6d, 0xc3, 0x27, 0xcb, 0x57, 0xed, 0x2d,
+ 0xdd, 0x66, 0x88, 0x85, 0x7b, 0xa8, 0x27, 0x2e, 0xc0, 0x9c, 0xb2, 0xce,
+ 0x52, 0xcf, 0x0b, 0xa3, 0x62, 0x2d, 0x7d, 0x9c, 0x53, 0x47, 0x2f, 0x93,
+ 0x59, 0xf1, 0xca, 0xc4, 0x74, 0xfc, 0xec, 0xd6, 0x5c, 0xd0, 0x8e, 0xff,
+ 0x7b, 0x9c, 0xc3, 0x1f, 0xec, 0xe5, 0x73, 0x3f, 0x9c, 0x42, 0xb3, 0x43,
+ 0x97, 0xd1, 0xd8, 0x61, 0xcb, 0xe5, 0xbb, 0xac, 0xd1, 0x1b, 0x29, 0x67,
+ 0x9f, 0xa2, 0x1b, 0x73, 0x0a, 0x21, 0x31, 0x8a, 0xff, 0x73, 0xcd, 0x2d,
+ 0xdd, 0x66, 0x8a, 0x6d, 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0xa8, 0x17, 0xb3,
+ 0xe6, 0xce, 0x5b, 0x9e, 0x1e, 0x97, 0x4d, 0x2f, 0xf7, 0x3c, 0xd2, 0xdd,
+ 0xd6, 0x68, 0xa9, 0x97, 0xed, 0x2d, 0xdd, 0x66, 0x8a, 0xc1, 0x7e, 0x46,
+ 0xc2, 0x0d, 0x1c, 0xbd, 0xfa, 0x92, 0x39, 0x76, 0xc4, 0xe5, 0xcc, 0xd9,
+ 0xcb, 0xf9, 0x1a, 0x3c, 0x23, 0x43, 0x97, 0xfb, 0x9e, 0x69, 0x6e, 0xeb,
+ 0x34, 0x47, 0xeb, 0xc3, 0x01, 0x39, 0x50, 0x88, 0xb9, 0x17, 0xa2, 0x0d,
+ 0xa0, 0xe5, 0xd1, 0x39, 0xca, 0x91, 0xa7, 0xc1, 0x0b, 0xfb, 0xe9, 0x3c,
+ 0x90, 0x4e, 0x5e, 0x81, 0x98, 0xe5, 0x61, 0xe4, 0xaa, 0x5b, 0x73, 0xf8,
+ 0xe5, 0xde, 0xf1, 0xcb, 0x73, 0xc5, 0x48, 0x2b, 0x34, 0xf8, 0xa5, 0x07,
+ 0xd8, 0x2c, 0xf0, 0xa2, 0x15, 0x5f, 0x34, 0xb4, 0x22, 0xe0, 0x16, 0xbf,
+ 0xfd, 0xcd, 0x8f, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x37, 0xaf, 0xfe,
+ 0x63, 0xcb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x4f, 0xcb, 0xdc, 0x2e, 0xf2,
+ 0x39, 0x79, 0x6a, 0x30, 0xe5, 0xfb, 0x51, 0xd0, 0x41, 0xcb, 0xf7, 0x73,
+ 0xd0, 0x13, 0x95, 0xc2, 0x1f, 0x62, 0x0f, 0x39, 0x3d, 0xc2, 0xb3, 0x97,
+ 0xdb, 0x99, 0x9b, 0x39, 0x72, 0xd6, 0x72, 0xff, 0x2f, 0xa9, 0xec, 0xc6,
+ 0x1c, 0xbb, 0x8a, 0xcf, 0x18, 0x12, 0xa1, 0x15, 0x28, 0x2d, 0xf9, 0x26,
+ 0xc5, 0xfc, 0x65, 0x7e, 0x6a, 0xb8, 0x46, 0x99, 0xf1, 0xcb, 0xf9, 0xa9,
+ 0x79, 0xfa, 0x8d, 0x67, 0x2f, 0xcd, 0x5a, 0xaa, 0xe3, 0x59, 0xcb, 0xfb,
+ 0xc8, 0x2d, 0xe0, 0x9c, 0xbb, 0x8a, 0xcf, 0x18, 0x0a, 0xdd, 0x39, 0x4d,
+ 0x4a, 0x60, 0x1c, 0x21, 0xaf, 0x0b, 0x1b, 0x61, 0x97, 0x8b, 0x00, 0x4d,
+ 0x7b, 0x4f, 0x87, 0x2f, 0x9c, 0x38, 0xc3, 0x94, 0xd5, 0x9b, 0xc6, 0xa2,
+ 0x37, 0x7d, 0xc3, 0x4e, 0xcd, 0x9c, 0xbf, 0xff, 0x0b, 0xfa, 0x05, 0x68,
+ 0xc0, 0x81, 0xf5, 0x23, 0x97, 0xe6, 0xfd, 0xe8, 0x61, 0xca, 0x6a, 0xcf,
+ 0xf2, 0x75, 0x3b, 0xfe, 0x7e, 0xa7, 0x1e, 0x6d, 0xb6, 0xd9, 0x4b, 0xfd,
+ 0xd7, 0xf7, 0x9d, 0xdb, 0x39, 0x5c, 0x32, 0x68, 0x0d, 0x46, 0x14, 0xad,
+ 0x40, 0xa3, 0x85, 0x90, 0x2f, 0xff, 0xf3, 0x55, 0xc2, 0x6f, 0x50, 0x9e,
+ 0xee, 0x05, 0x37, 0x83, 0xf9, 0xcb, 0xf9, 0xae, 0x34, 0xef, 0x23, 0x97,
+ 0xee, 0xa3, 0xff, 0xc2, 0xc7, 0x29, 0xa9, 0x46, 0x47, 0x0a, 0x6a, 0xf1,
+ 0x7d, 0xff, 0xcd, 0x5b, 0x56, 0xd4, 0xcc, 0x30, 0x1c, 0xfb, 0xc7, 0x2f,
+ 0x87, 0x13, 0xf3, 0x97, 0xdc, 0x2f, 0xfa, 0xb0, 0x72, 0xb8, 0x43, 0xcc,
+ 0xe1, 0x88, 0x6f, 0xfd, 0x11, 0x11, 0x11, 0x1f, 0x6c, 0xe5, 0xe9, 0xa3,
+ 0xc7, 0x2e, 0x88, 0x83, 0xd8, 0x98, 0xee, 0xf2, 0x7d, 0x87, 0x2f, 0xda,
+ 0x49, 0xdd, 0x85, 0x2e, 0x6d, 0xb2, 0x95, 0x87, 0x82, 0xd9, 0x45, 0x80,
+ 0x53, 0x99, 0xa2, 0xbd, 0xdc, 0x59, 0xca, 0x84, 0x75, 0x7e, 0x59, 0xb7,
+ 0xf5, 0x08, 0xef, 0xc0, 0x69, 0x00, 0xf8, 0xe5, 0xf3, 0x8c, 0x70, 0x1c,
+ 0xac, 0x3c, 0xe7, 0x2b, 0xbf, 0xf8, 0x71, 0x91, 0xbd, 0xe4, 0x9a, 0x61,
+ 0xcb, 0xff, 0x3f, 0x97, 0xd4, 0x11, 0x8f, 0x8e, 0x52, 0x22, 0x07, 0xa8,
+ 0x97, 0xfb, 0x02, 0x9c, 0x77, 0xfa, 0xce, 0x5f, 0xff, 0xfb, 0x38, 0xa7,
+ 0xa5, 0x9f, 0xec, 0x73, 0xfd, 0x44, 0xef, 0xa5, 0x9c, 0xba, 0x24, 0xe8,
+ 0xa5, 0xd9, 0xb5, 0xfd, 0xed, 0xe6, 0x4f, 0x07, 0x2b, 0xa7, 0xb4, 0x25,
+ 0xb7, 0xdb, 0x0f, 0x80, 0x72, 0xff, 0xff, 0xee, 0x31, 0xac, 0x08, 0xbe,
+ 0x95, 0x7f, 0x03, 0xc9, 0xed, 0xf5, 0x0e, 0x5f, 0xed, 0x00, 0x41, 0xe0,
+ 0x78, 0xe5, 0xee, 0xc0, 0x9c, 0xb4, 0x21, 0xe7, 0xf8, 0xd2, 0xa1, 0x32,
+ 0xc5, 0x90, 0xa1, 0x1f, 0x61, 0x85, 0x78, 0x52, 0x0e, 0x5f, 0xa1, 0x46,
+ 0x75, 0x0e, 0x56, 0x8f, 0x08, 0x46, 0xaf, 0xcf, 0x3c, 0x3a, 0xce, 0x5f,
+ 0xca, 0x72, 0x8d, 0xc3, 0x0e, 0x57, 0x4f, 0x5d, 0xc9, 0xef, 0xe9, 0x6f,
+ 0xd8, 0x2a, 0x9c, 0xbf, 0xfa, 0x17, 0x9a, 0xce, 0xa6, 0xba, 0xe7, 0x2f,
+ 0x36, 0xed, 0x9c, 0xbf, 0xfa, 0x35, 0x25, 0xf5, 0x26, 0x17, 0x6c, 0xe5,
+ 0xff, 0xda, 0x79, 0xc3, 0xd8, 0xdf, 0x81, 0xd3, 0x95, 0xb4, 0x45, 0xf9,
+ 0x16, 0xcc, 0xd2, 0x61, 0xdd, 0x42, 0xdc, 0x2a, 0x6f, 0xf2, 0x29, 0x0d,
+ 0x87, 0x18, 0x72, 0xb0, 0xfc, 0x3a, 0x79, 0x7f, 0xd1, 0xd8, 0xfa, 0x52,
+ 0x89, 0xce, 0x5f, 0x2f, 0xa9, 0xa3, 0x95, 0xa3, 0xdc, 0x73, 0xab, 0xff,
+ 0xff, 0xc2, 0xea, 0xa6, 0xa2, 0x5c, 0xba, 0x8c, 0x0c, 0x72, 0x68, 0x0e,
+ 0xa6, 0x8e, 0x5f, 0x3c, 0x93, 0xe3, 0x97, 0xfc, 0x9e, 0xcd, 0x68, 0x13,
+ 0xf1, 0x39, 0x7f, 0xdb, 0xcf, 0x07, 0x33, 0xfd, 0x9c, 0xae, 0x9f, 0xaf,
+ 0x8f, 0x2f, 0xf9, 0x3d, 0x9a, 0xd0, 0x27, 0xe2, 0x72, 0xf6, 0xc0, 0x3c,
+ 0x8f, 0x7b, 0xa4, 0x54, 0x15, 0x48, 0xba, 0x7d, 0xe9, 0x08, 0xbe, 0xee,
+ 0x1e, 0xb7, 0xcc, 0x40, 0xc1, 0xcb, 0xf9, 0x3b, 0xad, 0x24, 0xe7, 0x2a,
+ 0x0f, 0x3f, 0xa4, 0x37, 0x37, 0xe3, 0x97, 0xff, 0x22, 0x76, 0x6c, 0xf4,
+ 0x7a, 0x02, 0x72, 0xd0, 0x72, 0xff, 0xfa, 0x3e, 0x93, 0x8f, 0xfc, 0xbf,
+ 0x4d, 0x22, 0xa7, 0x2a, 0x11, 0x7f, 0x30, 0xc3, 0x44, 0x3e, 0x01, 0x0b,
+ 0xef, 0x6f, 0xa8, 0x72, 0xfa, 0x76, 0x24, 0x8e, 0x5f, 0x47, 0xea, 0x30,
+ 0xe5, 0xf0, 0x81, 0xe4, 0x72, 0x96, 0x78, 0xbb, 0x24, 0xbf, 0xdd, 0x86,
+ 0x73, 0xff, 0xf8, 0x39, 0x50, 0x8c, 0x1c, 0x68, 0x42, 0x2b, 0xfa, 0x64,
+ 0xef, 0xb1, 0x67, 0x2b, 0x13, 0x3e, 0xd4, 0x38, 0xdc, 0xb6, 0xff, 0x05,
+ 0x48, 0x6b, 0xe8, 0x36, 0x72, 0xfd, 0xc0, 0x8c, 0xcf, 0x1c, 0xaf, 0x8f,
+ 0x89, 0x87, 0x17, 0xb7, 0x0d, 0x9c, 0xb9, 0xfa, 0x72, 0xf2, 0xb1, 0xe3,
+ 0x97, 0xff, 0xe0, 0xf6, 0x34, 0x9f, 0xc2, 0x91, 0x30, 0xc3, 0x0e, 0x5f,
+ 0xe5, 0x60, 0x7d, 0xb7, 0xe9, 0xca, 0x44, 0x44, 0xba, 0xb5, 0xf8, 0x71,
+ 0xc6, 0x73, 0x95, 0x09, 0xa1, 0xe1, 0x1a, 0x0e, 0xb8, 0xb0, 0xc2, 0x9b,
+ 0x64, 0x37, 0xfb, 0xb1, 0x3e, 0xa3, 0x02, 0x72, 0xff, 0xf8, 0x73, 0x8a,
+ 0xdf, 0x53, 0xbf, 0x9f, 0xef, 0xce, 0x54, 0x22, 0x19, 0xcc, 0xef, 0xf0,
+ 0xbc, 0xff, 0x4a, 0x38, 0x0e, 0x5f, 0xed, 0xf5, 0xd4, 0xec, 0x48, 0xe5,
+ 0x4e, 0x7d, 0x7f, 0x1b, 0xde, 0xcc, 0x98, 0xe5, 0xff, 0xfa, 0x6e, 0xc3,
+ 0x13, 0x49, 0xc1, 0x0a, 0x4f, 0x8d, 0x9c, 0xbf, 0xf2, 0x6a, 0x36, 0xa0,
+ 0x8c, 0x68, 0xe5, 0xff, 0x44, 0x85, 0xfd, 0x24, 0xe2, 0x72, 0xf2, 0x91,
+ 0xf9, 0xca, 0xe9, 0xeb, 0xec, 0xe6, 0xcd, 0x67, 0x2f, 0x7a, 0x58, 0x72,
+ 0xed, 0xe1, 0xcb, 0xff, 0xb7, 0x1a, 0x5f, 0x87, 0x27, 0x71, 0x39, 0x50,
+ 0x9c, 0xd4, 0xeb, 0x79, 0x09, 0x44, 0x22, 0x71, 0x4f, 0xc7, 0x3c, 0x2d,
+ 0x77, 0x98, 0x72, 0xfd, 0x30, 0x3d, 0x1d, 0x39, 0x50, 0x78, 0x00, 0x17,
+ 0xbf, 0xf4, 0x79, 0xf7, 0x9d, 0xea, 0x30, 0xe5, 0xf8, 0x62, 0x78, 0x9c,
+ 0xe5, 0x04, 0xf9, 0x66, 0x3d, 0xbf, 0x83, 0x0f, 0xaf, 0xc0, 0x72, 0xec,
+ 0xe9, 0xca, 0x9c, 0xf1, 0x38, 0x97, 0x5e, 0xf2, 0x4c, 0x72, 0xa1, 0x15,
+ 0x38, 0xcf, 0xb2, 0x5b, 0xfe, 0xd2, 0x6f, 0xae, 0xc8, 0x6b, 0x39, 0x7e,
+ 0x86, 0xb4, 0x6d, 0x67, 0x2a, 0x1b, 0x30, 0xe9, 0xe1, 0x19, 0x28, 0x50,
+ 0x86, 0x52, 0x6e, 0x42, 0x0d, 0x6f, 0x1f, 0x10, 0xa4, 0xbf, 0x16, 0xb8,
+ 0x4f, 0xcd, 0x0e, 0x0d, 0x47, 0x00, 0xc8, 0xf6, 0x7b, 0x0d, 0xe7, 0x84,
+ 0x67, 0xe4, 0x83, 0x1d, 0xb6, 0xe1, 0x51, 0xe8, 0xcb, 0xf8, 0x97, 0x28,
+ 0x77, 0x72, 0xbe, 0x39, 0x7f, 0xff, 0xcd, 0x47, 0x86, 0x8c, 0x6a, 0x1a,
+ 0xe1, 0xb8, 0x57, 0x16, 0xbe, 0x16, 0x07, 0x2e, 0x5d, 0x68, 0x72, 0xe4,
+ 0x83, 0x97, 0xa6, 0x51, 0x87, 0x2f, 0xfb, 0x3d, 0xbc, 0xf7, 0x73, 0xf3,
+ 0x94, 0xa9, 0xf6, 0xb8, 0xa8, 0x8f, 0xdc, 0xe2, 0x72, 0xb4, 0x78, 0x6c,
+ 0x2e, 0xbe, 0x8f, 0x63, 0x0e, 0x5f, 0xbd, 0x02, 0x9f, 0x9c, 0xbf, 0x68,
+ 0x1c, 0x7f, 0x6c, 0xe5, 0xfd, 0x8d, 0xbf, 0xec, 0xc3, 0x95, 0xc9, 0x14,
+ 0x78, 0x43, 0xd2, 0x71, 0x2d, 0xbf, 0xf4, 0x31, 0x3e, 0xd8, 0x26, 0x02,
+ 0xa7, 0x2f, 0xe4, 0x1f, 0x77, 0x24, 0x72, 0xff, 0x0c, 0x36, 0xd3, 0x35,
+ 0x07, 0x2c, 0xdf, 0x24, 0x51, 0x49, 0x08, 0x25, 0x97, 0xed, 0x4f, 0x1e,
+ 0xd9, 0xcb, 0xe7, 0xd3, 0xc8, 0xe5, 0xb5, 0x87, 0x94, 0x25, 0x37, 0x9b,
+ 0x6d, 0xb3, 0x97, 0xd3, 0x8a, 0x41, 0x4e, 0x66, 0x82, 0xff, 0x9a, 0xfa,
+ 0xe3, 0x20, 0xc4, 0xe7, 0x2f, 0x9f, 0xd0, 0x13, 0x97, 0x7d, 0x23, 0x97,
+ 0xf9, 0x58, 0xf6, 0xfa, 0xe0, 0x39, 0x7e, 0x49, 0xf3, 0xef, 0x1c, 0xb9,
+ 0x16, 0x72, 0xa1, 0x11, 0x6a, 0x8c, 0x30, 0xd3, 0xc5, 0x37, 0xe5, 0x5f,
+ 0x7c, 0x64, 0x72, 0xbe, 0x3e, 0x8f, 0x1e, 0xde, 0xc0, 0x34, 0x39, 0x5c,
+ 0x22, 0xec, 0x87, 0x0a, 0x18, 0x88, 0xd1, 0xc3, 0x0c, 0x5c, 0x86, 0xfa,
+ 0x42, 0x0f, 0xa8, 0xce, 0x66, 0x27, 0x80, 0x8c, 0x51, 0xa1, 0x1d, 0xff,
+ 0xdc, 0x5b, 0xcd, 0x8a, 0x46, 0xb2, 0x73, 0x97, 0xff, 0xff, 0xfe, 0x6b,
+ 0xe5, 0xdc, 0xfa, 0x5d, 0x67, 0x25, 0xf4, 0x1e, 0xf6, 0x0f, 0x73, 0xd0,
+ 0x1e, 0x5c, 0xba, 0xd0, 0xe5, 0xff, 0x07, 0x01, 0xc3, 0xa7, 0x5d, 0x87,
+ 0x2f, 0xd0, 0xc1, 0xc9, 0x8e, 0x61, 0xbd, 0xbd, 0xc7, 0x02, 0x72, 0xfe,
+ 0xea, 0x40, 0x82, 0x0e, 0x5f, 0xe8, 0x6b, 0x57, 0x36, 0xed, 0x67, 0x29,
+ 0x53, 0xe4, 0xe9, 0x5d, 0x75, 0x14, 0xaf, 0x08, 0x2b, 0xee, 0xc2, 0x9d,
+ 0x39, 0x41, 0x4c, 0x97, 0x70, 0xdb, 0xf1, 0x3d, 0xfd, 0x12, 0xec, 0x71,
+ 0x43, 0x97, 0xe6, 0x00, 0x61, 0x87, 0x2c, 0x13, 0x97, 0x3e, 0xce, 0x5b,
+ 0x4c, 0x34, 0xe0, 0x11, 0xa8, 0x3f, 0x57, 0x4e, 0xba, 0x5e, 0x39, 0x7d,
+ 0x34, 0x79, 0xce, 0x5f, 0x03, 0xfc, 0x15, 0x9b, 0x90, 0x0b, 0xda, 0x47,
+ 0x2a, 0x73, 0xc9, 0xe9, 0xc5, 0xff, 0xd1, 0xd5, 0x03, 0xe4, 0xc9, 0xa1,
+ 0x87, 0x2f, 0xfd, 0xe4, 0x6d, 0x7d, 0x4e, 0x28, 0x13, 0x97, 0xfb, 0x52,
+ 0xee, 0x71, 0x86, 0x1c, 0xaf, 0x8f, 0xd9, 0x10, 0x6f, 0xcf, 0x2d, 0xa7,
+ 0x13, 0x97, 0xfd, 0x9a, 0xce, 0x59, 0xa8, 0x09, 0xcb, 0xfb, 0x25, 0xf4,
+ 0xb3, 0xc7, 0x2d, 0xe9, 0x1f, 0x3f, 0x4e, 0x6f, 0xa3, 0xc0, 0x61, 0xca,
+ 0x34, 0x41, 0xcb, 0xf9, 0xe7, 0xfd, 0xc4, 0x24, 0xac, 0x1a, 0xb6, 0xd6,
+ 0x7a, 0x8d, 0x06, 0x29, 0x88, 0xa0, 0xf3, 0xb5, 0xff, 0xf9, 0x9b, 0x79,
+ 0x75, 0x33, 0xdb, 0xd6, 0x07, 0x0e, 0x5f, 0xf4, 0x78, 0x73, 0x88, 0xe6,
+ 0xce, 0x54, 0x22, 0xbf, 0x08, 0xf6, 0xa9, 0x7f, 0x3f, 0x61, 0xac, 0x12,
+ 0x39, 0x52, 0x5c, 0xaa, 0x5c, 0x28, 0xf5, 0x0a, 0x26, 0x11, 0xf6, 0x17,
+ 0x7f, 0x91, 0x0c, 0x24, 0x3d, 0x1b, 0xbf, 0x12, 0xeb, 0xfa, 0x43, 0x9f,
+ 0x7b, 0x0e, 0x5f, 0xff, 0x94, 0xff, 0xf8, 0xfb, 0x27, 0x0b, 0xba, 0xdc,
+ 0x27, 0x2a, 0x11, 0x0d, 0xa2, 0xdb, 0xf8, 0x7d, 0x2c, 0xd6, 0x1c, 0xb9,
+ 0xa3, 0x9c, 0xa7, 0x3c, 0x45, 0x0b, 0x2f, 0xf7, 0x71, 0x6f, 0xd8, 0xe9,
+ 0xcb, 0xff, 0x9d, 0x3d, 0x02, 0xbc, 0xf7, 0x50, 0xe5, 0xfc, 0x29, 0xfe,
+ 0xfa, 0x87, 0x2e, 0xd0, 0x4e, 0x5c, 0xdb, 0x67, 0x2a, 0x46, 0xc1, 0xb1,
+ 0x7b, 0xd0, 0x9c, 0x4a, 0x73, 0x34, 0x57, 0xfc, 0x82, 0x9f, 0xef, 0x3a,
+ 0xe7, 0x2b, 0x13, 0x58, 0xe9, 0x93, 0xa0, 0xed, 0xff, 0xc5, 0xf7, 0xf4,
+ 0x0f, 0xbb, 0x92, 0x39, 0x77, 0xfb, 0x39, 0x7f, 0x27, 0x51, 0x55, 0x60,
+ 0xe5, 0x94, 0x09, 0xe3, 0x78, 0x62, 0xb4, 0x89, 0xbd, 0xb9, 0x52, 0x26,
+ 0x0e, 0xa4, 0x39, 0x2f, 0x36, 0xdb, 0x65, 0x28, 0xa7, 0x33, 0x41, 0x7c,
+ 0x8d, 0xa4, 0xc5, 0x29, 0x67, 0x80, 0x83, 0xb7, 0xec, 0xd4, 0x71, 0xc3,
+ 0x95, 0x0c, 0xc0, 0xe9, 0xd1, 0xb2, 0x50, 0x62, 0x4e, 0x70, 0x6a, 0x32,
+ 0x36, 0x33, 0x76, 0x54, 0x08, 0xc2, 0x27, 0x64, 0x37, 0xda, 0x90, 0x30,
+ 0xe5, 0xfe, 0x1f, 0xbc, 0xa7, 0x5f, 0xf3, 0x97, 0x85, 0x36, 0x72, 0xf8,
+ 0x2e, 0x3f, 0x9c, 0xbf, 0xfa, 0x07, 0xf1, 0x8f, 0xa6, 0x81, 0xfc, 0xe5,
+ 0x62, 0x2e, 0x10, 0xdb, 0xf1, 0xbd, 0x91, 0x5f, 0x4b, 0xf9, 0x09, 0xcb,
+ 0xf4, 0xcd, 0x3f, 0x69, 0x87, 0x2c, 0x87, 0x2f, 0xf9, 0xd5, 0x5f, 0x50,
+ 0x2f, 0x23, 0x97, 0xd3, 0xce, 0xff, 0x1c, 0xbb, 0xfd, 0xa1, 0xf7, 0x08,
+ 0x82, 0x87, 0x37, 0xd9, 0xae, 0xa1, 0xcb, 0xff, 0xcf, 0x21, 0xce, 0x2f,
+ 0x34, 0x67, 0xb6, 0x72, 0xa0, 0xfa, 0xdc, 0x86, 0xff, 0xf3, 0x7f, 0xf7,
+ 0x32, 0x74, 0xce, 0x31, 0xf1, 0xcb, 0xff, 0xdf, 0xc3, 0x35, 0xa8, 0x9f,
+ 0xce, 0xea, 0x9c, 0xbf, 0xd2, 0xce, 0xe3, 0x21, 0x67, 0x2f, 0x63, 0x1a,
+ 0xce, 0x5f, 0xf9, 0xf8, 0xe2, 0x83, 0x1d, 0x49, 0xce, 0x5f, 0xec, 0xd8,
+ 0xe7, 0xba, 0x87, 0x28, 0x28, 0x90, 0xd0, 0xf8, 0xa0, 0x56, 0x2a, 0x51,
+ 0x9a, 0x14, 0xdd, 0x20, 0xfd, 0x3b, 0xc9, 0x9c, 0x61, 0x85, 0x7d, 0x2f,
+ 0xf3, 0xf3, 0x97, 0xf7, 0xb2, 0x61, 0x86, 0x1e, 0x20, 0x25, 0xf0, 0x87,
+ 0xb0, 0x68, 0x80, 0x9c, 0xcd, 0xd5, 0x7c, 0x89, 0xe7, 0x5e, 0xbf, 0xf9,
+ 0x3e, 0xd8, 0x70, 0x60, 0x41, 0x07, 0x2f, 0xda, 0x40, 0x70, 0xf0, 0x72,
+ 0xff, 0x6b, 0x3e, 0xdf, 0xef, 0xe3, 0x97, 0x01, 0x70, 0x7c, 0x2a, 0x96,
+ 0x5f, 0xa2, 0x4f, 0xf3, 0x67, 0x2f, 0xfb, 0x96, 0xb5, 0x9d, 0xfa, 0x5b,
+ 0x39, 0x7f, 0xff, 0xb3, 0x60, 0x7f, 0xb3, 0x05, 0x5d, 0xef, 0x07, 0xdb,
+ 0x39, 0x4b, 0x44, 0xef, 0xc7, 0xb7, 0xe7, 0x6c, 0x2a, 0xf1, 0x39, 0x58,
+ 0x9f, 0x3a, 0x42, 0x8f, 0x45, 0xcf, 0x0c, 0x61, 0x24, 0xb4, 0xe7, 0x2f,
+ 0xdc, 0xb2, 0x64, 0x61, 0xcb, 0xff, 0xc0, 0x8e, 0x5c, 0x1e, 0x4d, 0xf7,
+ 0xe7, 0x6c, 0xe5, 0x4e, 0x7f, 0x7b, 0x2a, 0xbf, 0xf6, 0x07, 0xaf, 0xce,
+ 0x3b, 0x1f, 0x1c, 0xae, 0x11, 0x1e, 0x1a, 0x84, 0x6b, 0x08, 0xef, 0xf8,
+ 0x55, 0xd0, 0xa2, 0xc0, 0x27, 0x2f, 0xde, 0x8c, 0x18, 0x39, 0x48, 0x7b,
+ 0xa2, 0x71, 0x79, 0x41, 0xf1, 0xcb, 0xc8, 0xc7, 0x39, 0x53, 0x9b, 0x85,
+ 0x47, 0x6f, 0xff, 0xcf, 0xf7, 0xdb, 0x81, 0xf2, 0x93, 0x75, 0x3d, 0xb3,
+ 0x95, 0x09, 0xb5, 0xe4, 0x25, 0xd1, 0x60, 0x04, 0x77, 0xcc, 0x8c, 0x61,
+ 0xcb, 0xff, 0x63, 0x21, 0x69, 0xed, 0x01, 0x87, 0x2f, 0x27, 0xdb, 0x39,
+ 0x52, 0x3d, 0xbf, 0xcf, 0xaf, 0xb4, 0xf2, 0x98, 0xe5, 0xfb, 0x7b, 0x8f,
+ 0xda, 0x93, 0x94, 0xa9, 0xe8, 0xb6, 0x47, 0x50, 0x89, 0x87, 0x74, 0xbf,
+ 0xda, 0x9b, 0x68, 0x3e, 0x43, 0x97, 0xfb, 0xa9, 0xf7, 0xfa, 0x70, 0x9c,
+ 0xbe, 0xfb, 0xfd, 0x41, 0x4b, 0x9b, 0x6c, 0xa5, 0x41, 0xbd, 0x6c, 0x92,
+ 0xe1, 0x42, 0x9c, 0xcd, 0x0d, 0xff, 0xff, 0xc3, 0xcf, 0x33, 0x82, 0x26,
+ 0x46, 0x44, 0xdc, 0x87, 0xe9, 0x74, 0x1f, 0x9c, 0xa3, 0x97, 0x9f, 0x52,
+ 0xe4, 0x9a, 0x04, 0xa1, 0x27, 0xf1, 0x3f, 0xef, 0x77, 0xf3, 0x8c, 0x96,
+ 0x09, 0xce, 0x53, 0x56, 0xcd, 0x4e, 0x88, 0x6d, 0x4e, 0x79, 0x22, 0x3c,
+ 0x95, 0xda, 0x91, 0x82, 0x6a, 0x50, 0x57, 0x65, 0x56, 0x3a, 0x00, 0xc6,
+ 0x29, 0xe2, 0x10, 0x46, 0xe6, 0xda, 0xc5, 0xef, 0x23, 0x67, 0x2f, 0x4e,
+ 0xec, 0x39, 0x72, 0x04, 0xe5, 0xef, 0x23, 0x67, 0x8c, 0x21, 0x78, 0x0e,
+ 0xa1, 0xa2, 0x07, 0x7c, 0x6a, 0xab, 0xa7, 0xf7, 0xe4, 0x0a, 0x74, 0x5d,
+ 0x02, 0x13, 0x17, 0x87, 0x5c, 0x39, 0xcb, 0xfd, 0x8b, 0x89, 0xc6, 0x16,
+ 0x72, 0xdf, 0x9c, 0xb3, 0x5f, 0x23, 0xc4, 0x43, 0x2b, 0xa0, 0x07, 0x2f,
+ 0xc0, 0x1f, 0xd4, 0x91, 0xcb, 0xff, 0xe1, 0xcd, 0xf2, 0x53, 0xb1, 0xfb,
+ 0x1e, 0x5c, 0xb0, 0xf0, 0x36, 0x2d, 0x40, 0x46, 0xbf, 0x16, 0xcb, 0xff,
+ 0x74, 0x13, 0xc7, 0x28, 0xf4, 0x04, 0xe5, 0xe7, 0xd4, 0xe7, 0x2e, 0x6d,
+ 0xb3, 0x97, 0xfb, 0x49, 0x9c, 0x54, 0x97, 0x35, 0x9b, 0x66, 0xc7, 0x6f,
+ 0xfc, 0x8a, 0xf2, 0xd8, 0x3f, 0x64, 0x48, 0xe5, 0xfe, 0xde, 0x79, 0xd9,
+ 0x82, 0x72, 0x82, 0x99, 0xd6, 0x9d, 0xfa, 0x9f, 0xe4, 0x3b, 0xff, 0x6f,
+ 0x07, 0x3b, 0x8b, 0xc1, 0x39, 0x7f, 0xd2, 0xdf, 0xbb, 0x8c, 0xc9, 0x1c,
+ 0xbf, 0xf6, 0x2b, 0xd7, 0x92, 0x8f, 0xf4, 0x1c, 0xa9, 0x22, 0xd1, 0x0e,
+ 0xc4, 0xe6, 0xa1, 0x32, 0x0c, 0x87, 0x95, 0xff, 0xcc, 0x63, 0xcb, 0x34,
+ 0xb7, 0x75, 0x9a, 0x21, 0x85, 0xff, 0xff, 0xe7, 0xde, 0x0e, 0x2f, 0xb1,
+ 0xf4, 0x9a, 0x67, 0x56, 0x98, 0x2e, 0xa9, 0xca, 0xc4, 0x63, 0x81, 0x42,
+ 0xa1, 0x73, 0x2d, 0x23, 0x3c, 0xec, 0xa7, 0xf1, 0x87, 0x75, 0xf8, 0x63,
+ 0xff, 0xbf, 0x39, 0x7f, 0x75, 0xe7, 0x18, 0x91, 0x4b, 0xff, 0x7b, 0xae,
+ 0x9e, 0x8d, 0x47, 0xe7, 0x2f, 0xdd, 0x71, 0x52, 0x73, 0x95, 0x24, 0x5f,
+ 0x30, 0xa8, 0x4b, 0x5b, 0x3e, 0xbf, 0xf2, 0x2e, 0x36, 0xfa, 0xd2, 0x36,
+ 0x72, 0xff, 0xfb, 0x7f, 0xa6, 0x95, 0x5f, 0x53, 0xa2, 0x09, 0xce, 0x5d,
+ 0xb0, 0x1c, 0xbf, 0xa5, 0xd7, 0x71, 0x83, 0x96, 0x85, 0x9e, 0x17, 0xc2,
+ 0xf7, 0xff, 0x67, 0xa3, 0xa9, 0x8a, 0xab, 0x12, 0x39, 0x7e, 0xd2, 0xdd,
+ 0xd6, 0x68, 0x82, 0x97, 0xbb, 0x0c, 0x39, 0x7f, 0xe8, 0x9d, 0xfd, 0xac,
+ 0x93, 0x4c, 0x39, 0x41, 0x46, 0xa6, 0x22, 0x21, 0xa0, 0x8e, 0x5f, 0xbb,
+ 0x0c, 0x07, 0xc7, 0x2f, 0xbd, 0xb8, 0xfc, 0xa5, 0xe7, 0xd4, 0xe5, 0x2f,
+ 0x80, 0x2e, 0xa9, 0x4b, 0xfc, 0x93, 0xe7, 0xb7, 0x1f, 0x94, 0xa2, 0x97,
+ 0xf6, 0x2e, 0x3b, 0x0c, 0x29, 0x73, 0x6d, 0x94, 0xbf, 0x86, 0x06, 0x74,
+ 0xd1, 0x4a, 0xc4, 0xc4, 0x96, 0x46, 0xc1, 0xde, 0x91, 0x7e, 0x68, 0x21,
+ 0x6d, 0x96, 0x28, 0x33, 0x72, 0x68, 0xa7, 0x33, 0xf3, 0xa9, 0x2a, 0x11,
+ 0x98, 0xeb, 0xb1, 0xd7, 0x5f, 0xff, 0xa1, 0xbd, 0x8e, 0x7d, 0xe7, 0x19,
+ 0xf3, 0xef, 0x1c, 0xa8, 0x5c, 0xad, 0xc3, 0xd4, 0x3e, 0xec, 0x25, 0x5e,
+ 0x58, 0x68, 0x9c, 0xde, 0x63, 0x84, 0xe5, 0xff, 0xff, 0x0e, 0x7b, 0xd1,
+ 0xf4, 0xb9, 0x76, 0x18, 0x0f, 0xb7, 0xd8, 0x39, 0x7f, 0x60, 0xed, 0x07,
+ 0x0e, 0x5e, 0xe8, 0x18, 0x72, 0x95, 0x46, 0x6b, 0x58, 0xe7, 0x5a, 0xb8,
+ 0x0a, 0xaf, 0xf3, 0x8e, 0x6f, 0x51, 0xb3, 0x97, 0xf0, 0x70, 0x5f, 0xdb,
+ 0x39, 0x52, 0x3d, 0xdd, 0x98, 0xdf, 0xda, 0xe4, 0xf3, 0x67, 0x4e, 0x54,
+ 0x1e, 0x92, 0x11, 0x5f, 0xb5, 0xf4, 0xb3, 0xc7, 0x2f, 0xff, 0x9d, 0x3f,
+ 0xde, 0x2a, 0xec, 0xd4, 0x60, 0x9c, 0xbf, 0x79, 0x33, 0xef, 0x1c, 0xbf,
+ 0xff, 0xee, 0xa6, 0xb0, 0x2e, 0xcc, 0x1f, 0x0c, 0x37, 0x9e, 0xd9, 0xcb,
+ 0x41, 0xcb, 0xe8, 0xe2, 0x18, 0x59, 0xfa, 0x7e, 0xc9, 0x7f, 0xe7, 0x97,
+ 0x5f, 0xdb, 0xc1, 0x91, 0xca, 0xe9, 0xfc, 0x78, 0xee, 0xb4, 0x9d, 0x6f,
+ 0x4a, 0x76, 0x9d, 0xe8, 0xc5, 0x2f, 0x2f, 0x18, 0x72, 0xfe, 0x0b, 0xfb,
+ 0x60, 0x91, 0xcb, 0xa4, 0xd2, 0x0f, 0x29, 0x41, 0xcb, 0xf9, 0xf5, 0x1e,
+ 0x4e, 0x27, 0x2b, 0xe3, 0xde, 0x13, 0x0b, 0xff, 0xff, 0x6b, 0x51, 0xf4,
+ 0xbe, 0xda, 0x69, 0x7d, 0xc5, 0x34, 0x90, 0x13, 0x97, 0xfc, 0xfa, 0xcf,
+ 0xa5, 0x1f, 0xc1, 0xca, 0x84, 0x65, 0x61, 0x10, 0x1b, 0xef, 0xff, 0xcb,
+ 0x55, 0xf7, 0x9a, 0x92, 0x75, 0xc7, 0xe9, 0x1c, 0xbf, 0xf2, 0xe3, 0xdb,
+ 0xcf, 0x27, 0xcd, 0x9c, 0xb3, 0xe2, 0x25, 0x95, 0x56, 0xa8, 0x55, 0x45,
+ 0xd8, 0xed, 0x86, 0x18, 0x97, 0xed, 0x88, 0x38, 0xc8, 0xe5, 0xe9, 0xd4,
+ 0x59, 0xca, 0x83, 0xc9, 0x72, 0xab, 0x9f, 0xf3, 0x95, 0x23, 0x6f, 0xe2,
+ 0x0b, 0xff, 0xf3, 0xbc, 0x9f, 0xbc, 0xb2, 0x70, 0x78, 0x0e, 0xa1, 0xa2,
+ 0xfb, 0x5e, 0xfe, 0x02, 0x72, 0xfe, 0x75, 0xc0, 0xc7, 0xe7, 0x2f, 0xfd,
+ 0xb4, 0x1f, 0xa5, 0xa0, 0x46, 0xce, 0x54, 0xc8, 0xed, 0xd3, 0x2f, 0x47,
+ 0x7c, 0x59, 0x7e, 0xee, 0x4d, 0x0d, 0x67, 0x2f, 0xc1, 0xd6, 0xb1, 0xb3,
+ 0x96, 0x89, 0xcf, 0x50, 0x4a, 0xec, 0xb3, 0x97, 0xff, 0xfb, 0xf4, 0xd2,
+ 0xbd, 0x86, 0x4d, 0x24, 0x1e, 0xc6, 0xa0, 0xe5, 0xbd, 0x87, 0xe7, 0xb1,
+ 0x1b, 0xef, 0x0e, 0x48, 0xe5, 0x41, 0xe4, 0x21, 0x3d, 0xff, 0x85, 0x25,
+ 0xee, 0xe6, 0x93, 0x67, 0x2f, 0xd2, 0x1c, 0xc9, 0xce, 0x5d, 0xa9, 0xce,
+ 0x54, 0x1b, 0xfc, 0x27, 0xbf, 0xce, 0x18, 0xfe, 0x1b, 0xd9, 0xca, 0xe9,
+ 0xe9, 0xb8, 0xfd, 0xfc, 0xd1, 0xa8, 0x72, 0xe5, 0xd6, 0x87, 0x88, 0x05,
+ 0x7f, 0xbd, 0xfa, 0x83, 0x2e, 0xe1, 0xe2, 0x01, 0x5e, 0x7d, 0x48, 0xf1,
+ 0x00, 0xab, 0x0f, 0xac, 0x08, 0x57, 0x3c, 0x8f, 0x10, 0x0a, 0xf9, 0xc7,
+ 0xe9, 0x1e, 0x20, 0x15, 0xfe, 0x45, 0xf7, 0x3f, 0xfe, 0x0f, 0x10, 0x0a,
+ 0xf2, 0x08, 0x4f, 0x10, 0x0a, 0x82, 0x8b, 0xb6, 0x11, 0xf4, 0xbf, 0x8a,
+ 0x0d, 0x95, 0x3c, 0x40, 0x2b, 0xda, 0x8f, 0x1e, 0x20, 0x15, 0x1e, 0x20,
+ 0x15, 0xe6, 0x89, 0xf9, 0xe2, 0x01, 0x5d, 0x0c, 0x3c, 0x40, 0x2a, 0x09,
+ 0xf3, 0xe0, 0xc2, 0x16, 0x5f, 0x23, 0x03, 0x07, 0x88, 0x05, 0x7b, 0xce,
+ 0xb3, 0xc4, 0x02, 0xbf, 0xf0, 0xbc, 0xb9, 0xf5, 0x16, 0xfa, 0x3c, 0x40,
+ 0x2b, 0xff, 0x9f, 0xc0, 0x9d, 0x07, 0xdd, 0x79, 0x1e, 0x20, 0x15, 0xce,
+ 0x13, 0xc4, 0x02, 0xbf, 0xc2, 0xed, 0xef, 0x71, 0xf9, 0xe2, 0x01, 0x5f,
+ 0x91, 0x57, 0x1f, 0xcf, 0x10, 0x0a, 0xe4, 0xd9, 0xe2, 0x01, 0x56, 0x8f,
+ 0x63, 0xc6, 0xb7, 0xff, 0xba, 0x9e, 0xf6, 0x6f, 0x96, 0x92, 0x18, 0x78,
+ 0x80, 0x57, 0xef, 0x0c, 0x7d, 0x23, 0x44, 0x02, 0xbb, 0xf8, 0x3c, 0x40,
+ 0x2e, 0x66, 0xd6, 0xfc, 0x90, 0xc7, 0x09, 0xe2, 0x01, 0x5f, 0x01, 0xc5,
+ 0x67, 0x88, 0x05, 0x7a, 0x34, 0xb3, 0xc4, 0x02, 0xbf, 0xf6, 0x7d, 0xb0,
+ 0xc6, 0x0f, 0xfb, 0x3c, 0x40, 0x2b, 0xf0, 0x1e, 0x52, 0x83, 0xc4, 0x02,
+ 0xbf, 0x3a, 0xfb, 0x1f, 0x1e, 0x20, 0x15, 0x62, 0x2d, 0x7a, 0x98, 0x03,
+ 0x4b, 0xb5, 0xf9, 0xe2, 0x01, 0x54, 0x95, 0x9a, 0x04, 0x8f, 0x21, 0x32,
+ 0xb2, 0x24, 0x84, 0x6f, 0x4d, 0xbf, 0x33, 0xd9, 0x77, 0xa1, 0xbc, 0x02,
+ 0xfb, 0xf6, 0x7b, 0x6f, 0xf1, 0xe2, 0x01, 0x5f, 0xe0, 0xc2, 0xe6, 0xd4,
+ 0x78, 0xf1, 0x00, 0x82, 0x6d, 0x6f, 0x6a, 0x1b, 0x3c, 0x40, 0x2a, 0x59,
+ 0xfd, 0xe9, 0x46, 0xff, 0x01, 0xe5, 0x28, 0x51, 0x87, 0x88, 0x05, 0x7c,
+ 0x83, 0x2d, 0x9e, 0x20, 0x15, 0xfc, 0xf3, 0x4b, 0x3e, 0x91, 0xe2, 0x01,
+ 0x56, 0x23, 0x37, 0xa4, 0x5f, 0xa0, 0x80, 0xba, 0xff, 0xbb, 0x1b, 0xe7,
+ 0xb0, 0x6b, 0xf3, 0xc4, 0x02, 0xb2, 0x1e, 0x20, 0x15, 0xcf, 0x38, 0x4f,
+ 0x9f, 0xa9, 0x57, 0x6b, 0xf3, 0xc4, 0x02, 0xbf, 0x3f, 0xb6, 0x9f, 0x1e,
+ 0x20, 0x15, 0xfc, 0x82, 0x09, 0x66, 0xcf, 0x10, 0x0a, 0xa1, 0x12, 0x62,
+ 0x4b, 0xe3, 0x5a, 0x86, 0x53, 0xf8, 0x61, 0x6b, 0x90, 0xdc, 0x43, 0xf9,
+ 0x87, 0xf5, 0x09, 0x0e, 0x96, 0xb9, 0x77, 0xe5, 0x22, 0x99, 0xb9, 0x70,
+ 0xbe, 0x94, 0x30, 0xd2, 0x14, 0x8a, 0x43, 0x06, 0xf7, 0x91, 0xb3, 0xc6,
+ 0x12, 0xbc, 0xee, 0xb3, 0x44, 0x02, 0xe6, 0x98, 0xa7, 0xd0, 0xea, 0xbe,
+ 0x57, 0x85, 0xc2, 0xc3, 0x97, 0x71, 0x9c, 0xe5, 0xfd, 0x3c, 0x6b, 0xae,
+ 0xd6, 0x72, 0xfd, 0xc4, 0x60, 0x3d, 0x39, 0x50, 0x7e, 0x98, 0x34, 0x86,
+ 0x37, 0xff, 0x48, 0x71, 0x7d, 0x4f, 0xff, 0x04, 0xc7, 0x2f, 0xde, 0xc0,
+ 0xbf, 0x4e, 0x5d, 0xfc, 0x14, 0xb2, 0xa5, 0x2f, 0x76, 0x27, 0x39, 0x73,
+ 0x6d, 0x94, 0xa4, 0x3d, 0xf6, 0xb1, 0x79, 0x84, 0x9b, 0x1d, 0xb6, 0xca,
+ 0x73, 0x3c, 0x0b, 0x33, 0x11, 0xd4, 0x90, 0xc6, 0xbf, 0xbd, 0xbc, 0x6f,
+ 0xa8, 0x72, 0xde, 0x39, 0x64, 0xf1, 0xbf, 0x01, 0x75, 0xff, 0xef, 0x6f,
+ 0x15, 0x4d, 0x29, 0xff, 0xf1, 0xf1, 0xca, 0x9d, 0x9f, 0x9f, 0x22, 0x00,
+ 0xc3, 0x3d, 0x74, 0xbb, 0x44, 0x50, 0xd4, 0x27, 0xdc, 0xb3, 0xf8, 0xcc,
+ 0x7c, 0xd6, 0xa1, 0x35, 0xff, 0x64, 0x90, 0x2e, 0xbd, 0xc8, 0xe5, 0xff,
+ 0x31, 0x05, 0x69, 0xa4, 0xfc, 0xe5, 0x2c, 0xfc, 0x3a, 0x71, 0x79, 0x7d,
+ 0x13, 0x97, 0xff, 0x79, 0xa6, 0x4d, 0x27, 0xd4, 0xe1, 0x83, 0x94, 0xc3,
+ 0xe4, 0x11, 0xcb, 0x87, 0xf3, 0x97, 0x46, 0xce, 0x5e, 0xf2, 0x9c, 0x50,
+ 0xd6, 0xf1, 0x17, 0xbf, 0xd9, 0xf7, 0xbc, 0xf2, 0xd9, 0xcb, 0xd2, 0xe1,
+ 0xe4, 0x72, 0xef, 0xa4, 0x78, 0xc0, 0x15, 0xf1, 0xe3, 0x89, 0x15, 0xff,
+ 0xfa, 0x33, 0xbb, 0x17, 0xf0, 0x3c, 0x1e, 0xa2, 0xa7, 0x2a, 0x13, 0xfd,
+ 0xc8, 0x43, 0x22, 0x76, 0x8d, 0xdd, 0xec, 0x48, 0xaf, 0xff, 0xc2, 0x20,
+ 0xfb, 0x3e, 0xf0, 0x74, 0xff, 0x64, 0xe7, 0x2f, 0xd9, 0xed, 0x46, 0xce,
+ 0x52, 0x1f, 0xf8, 0xac, 0x5f, 0xa6, 0x94, 0x6a, 0x73, 0x97, 0xd0, 0xac,
+ 0x30, 0xe5, 0x48, 0xfb, 0x34, 0x40, 0xc2, 0xab, 0xff, 0x4b, 0x7c, 0x87,
+ 0x19, 0x1a, 0x54, 0xe5, 0xfb, 0x97, 0x2c, 0xeb, 0x9c, 0xbf, 0xa5, 0x1a,
+ 0xfd, 0x46, 0x1c, 0xbf, 0xfb, 0x88, 0xe6, 0xfd, 0x83, 0x2c, 0xd9, 0xcb,
+ 0xe6, 0x40, 0x3c, 0x72, 0xb0, 0xf9, 0x9d, 0x12, 0xfc, 0xfe, 0xf3, 0xe8,
+ 0xe5, 0xef, 0x38, 0x9c, 0xb3, 0xe2, 0x3e, 0x06, 0x12, 0xdb, 0x20, 0xe0,
+ 0x27, 0xae, 0x49, 0xb5, 0xf6, 0x32, 0x3b, 0xfe, 0x86, 0xb0, 0xf6, 0x27,
+ 0x71, 0x39, 0x7f, 0xd0, 0xb8, 0x62, 0x33, 0xf4, 0x39, 0x5a, 0x44, 0xff,
+ 0x4b, 0x38, 0x0e, 0xef, 0xe5, 0x1b, 0xd2, 0x67, 0x4a, 0x5f, 0xb7, 0xd8,
+ 0xc9, 0xce, 0x5f, 0xfd, 0xf8, 0xa6, 0x7d, 0xe9, 0xa4, 0xfa, 0x39, 0x7d,
+ 0x37, 0x5e, 0x63, 0x97, 0xcb, 0x7d, 0x4e, 0x72, 0xfd, 0x93, 0x4a, 0x3e,
+ 0x39, 0x72, 0x4c, 0x72, 0xfe, 0xde, 0x68, 0x3d, 0xc3, 0x95, 0xd3, 0xc4,
+ 0xd8, 0xbd, 0xe1, 0x89, 0x14, 0xbf, 0xf0, 0xfe, 0x9c, 0x1c, 0x00, 0x94,
+ 0x35, 0x9c, 0xac, 0x3e, 0x37, 0x1b, 0xae, 0x49, 0xe3, 0xfc, 0x51, 0xa4,
+ 0x6e, 0x92, 0x09, 0x1f, 0x9b, 0x78, 0x21, 0x0b, 0x50, 0xba, 0x25, 0x85,
+ 0xe9, 0x29, 0x2f, 0xa6, 0x6f, 0x1f, 0xb5, 0xfd, 0xf6, 0xf5, 0xa8, 0xf1,
+ 0xcb, 0xfa, 0x5b, 0x57, 0x4e, 0xb3, 0x97, 0x87, 0xdb, 0x39, 0x78, 0x52,
+ 0x47, 0x2f, 0xdb, 0x00, 0x81, 0x67, 0x2f, 0xef, 0x4d, 0x2c, 0xfa, 0x47,
+ 0x2a, 0x11, 0x7c, 0x85, 0xee, 0x38, 0x01, 0xb5, 0x0a, 0x2f, 0xfe, 0xeb,
+ 0x71, 0xad, 0xe3, 0x6f, 0xa5, 0x4e, 0x5f, 0x04, 0x38, 0xc3, 0x97, 0x7f,
+ 0x05, 0x2e, 0x6d, 0xb2, 0x94, 0x86, 0xc1, 0xb1, 0x7b, 0xf0, 0x40, 0xfa,
+ 0x91, 0x4e, 0x66, 0x86, 0xb1, 0x15, 0xaa, 0xb9, 0xdf, 0xfe, 0xf7, 0xcb,
+ 0x4e, 0xb4, 0x8f, 0x75, 0x4d, 0x9c, 0xbf, 0xd1, 0x24, 0xf4, 0xa3, 0xc7,
+ 0x2e, 0xe1, 0xf6, 0x73, 0x46, 0xca, 0xff, 0xba, 0xfe, 0xda, 0xc7, 0x27,
+ 0x39, 0x72, 0xd0, 0xe5, 0xf0, 0xa7, 0xd2, 0x39, 0x7f, 0xc9, 0xf7, 0x70,
+ 0x3a, 0x75, 0x9c, 0xa8, 0x3d, 0xbd, 0x11, 0x5f, 0xed, 0xe2, 0x79, 0x54,
+ 0xe9, 0xcb, 0xfe, 0xec, 0x6a, 0x16, 0x82, 0xb3, 0x97, 0x95, 0x7d, 0xad,
+ 0x1f, 0x9a, 0x71, 0xf1, 0x0f, 0x01, 0x9d, 0x62, 0x70, 0xfe, 0x8c, 0xd6,
+ 0xa4, 0xad, 0xd3, 0x50, 0xf4, 0x61, 0x18, 0x21, 0x02, 0xdc, 0x76, 0x77,
+ 0xf3, 0x6a, 0xbf, 0x86, 0x0e, 0x5f, 0x01, 0x98, 0x13, 0x95, 0xf1, 0xe8,
+ 0x70, 0x17, 0x5f, 0xfb, 0xb9, 0xc0, 0xe2, 0xae, 0x7d, 0xe3, 0x97, 0xfd,
+ 0x8b, 0xea, 0x07, 0xa0, 0x54, 0xe5, 0xef, 0x62, 0xce, 0x53, 0x0f, 0x5b,
+ 0x67, 0x57, 0xa4, 0xcf, 0xce, 0x52, 0xa8, 0xd8, 0xfe, 0x13, 0x1e, 0x22,
+ 0xbf, 0xe5, 0x5f, 0x94, 0x30, 0x51, 0x53, 0x97, 0xfe, 0x7d, 0xb2, 0x13,
+ 0x5a, 0x46, 0xce, 0x5b, 0x6a, 0x9f, 0xcf, 0x4e, 0xef, 0x9e, 0x4f, 0xa3,
+ 0x97, 0xfd, 0x9e, 0xf2, 0x2b, 0xec, 0x59, 0xcb, 0xfa, 0x3e, 0xde, 0x7d,
+ 0xe3, 0x97, 0x6a, 0x0e, 0x50, 0x4f, 0x17, 0xc5, 0xf7, 0xfb, 0xc8, 0xb4,
+ 0x0c, 0x78, 0xe5, 0xfb, 0x70, 0xbc, 0x61, 0xca, 0x83, 0xd9, 0xd9, 0x95,
+ 0xb6, 0x14, 0xc6, 0xb1, 0xfb, 0x4f, 0x75, 0xf2, 0x73, 0x4c, 0x29, 0xf4,
+ 0x67, 0x77, 0xfd, 0xe4, 0x9e, 0x3e, 0xff, 0x50, 0x72, 0xf6, 0xfd, 0x87,
+ 0x2e, 0xcd, 0xf2, 0x3d, 0x75, 0x0e, 0xef, 0xf7, 0x56, 0x9b, 0x04, 0x90,
+ 0xe5, 0xff, 0xd9, 0xe4, 0xfa, 0x43, 0x1c, 0x33, 0x51, 0x68, 0x72, 0xff,
+ 0xf0, 0x25, 0xd7, 0x4f, 0x20, 0xf8, 0x1d, 0x39, 0x7f, 0x95, 0xf7, 0xcb,
+ 0x4d, 0x6c, 0xe5, 0xfb, 0x3d, 0xfb, 0xf8, 0xe5, 0x42, 0x65, 0x72, 0x33,
+ 0xd2, 0x88, 0x12, 0x5a, 0x1b, 0x5f, 0xff, 0xa3, 0xaf, 0x83, 0x1a, 0x54,
+ 0x20, 0x7d, 0x48, 0xe5, 0x49, 0x3f, 0xbf, 0x46, 0xb7, 0xc0, 0x99, 0x50,
+ 0xbd, 0x73, 0x90, 0xad, 0x48, 0x7f, 0x3c, 0xa4, 0xa0, 0x4a, 0x8a, 0xbe,
+ 0xea, 0x3c, 0x8e, 0x5f, 0xec, 0x19, 0x66, 0xd4, 0x61, 0xcb, 0xf3, 0x37,
+ 0xfb, 0xb9, 0xca, 0xf1, 0xed, 0xa8, 0x67, 0x7f, 0xda, 0xc1, 0xe5, 0xdc,
+ 0xf9, 0xb3, 0x97, 0xfd, 0x21, 0x07, 0xfc, 0x96, 0xcf, 0xce, 0x54, 0xe9,
+ 0x8c, 0xc9, 0xf3, 0x08, 0xfe, 0x3c, 0xbf, 0xf9, 0xfb, 0xb4, 0x92, 0x7a,
+ 0x3d, 0xb3, 0x97, 0xfb, 0x3d, 0xd4, 0x68, 0xf3, 0x9c, 0xbf, 0xe1, 0x8c,
+ 0xfb, 0xd9, 0xa8, 0x39, 0x7f, 0xe8, 0xea, 0x9b, 0x1c, 0xf7, 0x70, 0xe5,
+ 0x42, 0x65, 0x88, 0x7f, 0xd4, 0x37, 0x35, 0xfc, 0xde, 0xfc, 0xfc, 0x42,
+ 0x18, 0x39, 0x76, 0xf6, 0x72, 0xf3, 0x6d, 0xb6, 0x72, 0xef, 0xdc, 0xa7,
+ 0x33, 0x41, 0x5a, 0x3e, 0x0d, 0x9b, 0xdf, 0xfb, 0x36, 0x2e, 0xac, 0xc2,
+ 0x93, 0x1c, 0xbf, 0xbf, 0x89, 0x75, 0x4d, 0x9c, 0xbf, 0x90, 0x7f, 0x5a,
+ 0xd0, 0xe5, 0xe7, 0xff, 0x0a, 0x54, 0x93, 0x63, 0x64, 0x22, 0x7a, 0x45,
+ 0xf9, 0xff, 0x13, 0x06, 0x85, 0xb7, 0xd0, 0x14, 0x09, 0xcb, 0xf0, 0x74,
+ 0x80, 0x9c, 0xe5, 0xfe, 0x6f, 0x07, 0x38, 0xa6, 0x8e, 0x5f, 0xc3, 0x9f,
+ 0x7e, 0xa4, 0x8e, 0x54, 0xc8, 0x8d, 0x12, 0x9f, 0x1a, 0x5f, 0xb3, 0x3d,
+ 0xdc, 0x39, 0x73, 0xb0, 0xe5, 0xff, 0x03, 0x7e, 0x89, 0x81, 0xf6, 0xce,
+ 0x5f, 0xec, 0xe3, 0x9c, 0xdb, 0x6d, 0xb2, 0x97, 0xe9, 0xa3, 0x3b, 0xb3,
+ 0x95, 0xc9, 0x13, 0xc2, 0x78, 0xa1, 0xd5, 0xfe, 0xe1, 0xe0, 0x0b, 0xea,
+ 0x68, 0xe5, 0xe6, 0x3f, 0x8e, 0x54, 0xc9, 0x9d, 0x76, 0x16, 0x80, 0x32,
+ 0xe2, 0x71, 0x77, 0xed, 0x51, 0xcb, 0xf7, 0x17, 0x62, 0x30, 0xe5, 0x41,
+ 0xe3, 0x08, 0xed, 0xfb, 0x26, 0x94, 0x48, 0xe5, 0xfd, 0x38, 0x63, 0x04,
+ 0x27, 0x2a, 0x15, 0xd0, 0xc9, 0x89, 0x21, 0x5d, 0xd3, 0x07, 0x8d, 0x83,
+ 0x70, 0x8c, 0xf1, 0x02, 0x85, 0x17, 0x9f, 0xf4, 0x39, 0x7f, 0xc1, 0x10,
+ 0x6f, 0x27, 0xc9, 0xce, 0x5e, 0x8d, 0x09, 0xcb, 0xfd, 0x81, 0x17, 0xda,
+ 0x04, 0xe5, 0xba, 0x72, 0xf0, 0x1e, 0x71, 0x3c, 0x2d, 0x98, 0xd9, 0x34,
+ 0x89, 0x0f, 0x2e, 0xd3, 0x13, 0x0e, 0x71, 0xce, 0x1e, 0x19, 0x56, 0x13,
+ 0x97, 0xd1, 0x3c, 0x48, 0xe5, 0x39, 0xb2, 0x11, 0x0b, 0xff, 0xd8, 0x17,
+ 0x66, 0x7d, 0x2c, 0xff, 0x02, 0x72, 0xee, 0xb9, 0xcb, 0xa6, 0xd9, 0xcb,
+ 0xf6, 0x71, 0x41, 0x0e, 0x1a, 0xe5, 0x05, 0xaf, 0xee, 0x5e, 0xcd, 0xee,
+ 0x0e, 0x5f, 0xbb, 0x9f, 0x7a, 0x0e, 0x5f, 0xb8, 0x1e, 0x75, 0x24, 0x72,
+ 0xb9, 0x26, 0x75, 0xcd, 0xe2, 0x0f, 0xb0, 0xbc, 0x05, 0x17, 0xc1, 0xce,
+ 0xb9, 0xcb, 0xff, 0x60, 0xcb, 0xb8, 0x23, 0x0d, 0x9c, 0xbf, 0xf6, 0x6b,
+ 0x4f, 0x2e, 0x5c, 0x61, 0xac, 0xe5, 0x42, 0x20, 0x64, 0x79, 0x5a, 0x4c,
+ 0x44, 0x53, 0x7d, 0x0a, 0x2b, 0xfd, 0xad, 0xf7, 0x05, 0x36, 0x72, 0xa1,
+ 0x56, 0x8a, 0x4a, 0x6a, 0x73, 0x5b, 0xfe, 0xc0, 0xe0, 0xc0, 0x82, 0x0e,
+ 0x5d, 0x0d, 0x9c, 0xa8, 0x7c, 0x78, 0x39, 0xe1, 0xaf, 0x29, 0xcf, 0x20,
+ 0xce, 0xdd, 0x64, 0x65, 0xca, 0xc3, 0xcd, 0x73, 0x8d, 0xff, 0x42, 0xed,
+ 0x23, 0x0e, 0x9a, 0x12, 0x5a, 0xac, 0x2c, 0x59, 0x2c, 0x5b, 0xb3, 0xca,
+ 0xae, 0xad, 0xfc, 0x3b, 0x46, 0x94, 0xeb, 0xb9, 0x54, 0xde, 0x9d, 0x4d,
+ 0x04, 0x71, 0xfc, 0x65, 0x9e, 0xa8, 0x6d, 0xc0, 0x6b, 0x7f, 0xd9, 0xa1,
+ 0x8f, 0x4b, 0x3a, 0x72, 0xff, 0xe1, 0x5a, 0xaf, 0xbc, 0x94, 0x0a, 0xce,
+ 0x5f, 0xbf, 0xc0, 0xbc, 0x8e, 0x52, 0x1f, 0x58, 0xa1, 0xdf, 0xf7, 0xb7,
+ 0xd4, 0x86, 0x38, 0x4e, 0x5f, 0xfb, 0xa8, 0x31, 0xf6, 0xd1, 0x90, 0x72,
+ 0xf6, 0xe3, 0x47, 0x2e, 0xf6, 0xd6, 0x7b, 0x3f, 0x1e, 0xd4, 0x23, 0x00,
+ 0x10, 0x91, 0xbf, 0xcb, 0x1c, 0x94, 0x9f, 0x67, 0x2f, 0xe7, 0x6f, 0x3f,
+ 0x53, 0xc7, 0x2f, 0xcf, 0x2e, 0x41, 0x43, 0x97, 0xf6, 0xf0, 0x29, 0xb9,
+ 0xce, 0x5e, 0x94, 0x7e, 0x72, 0xfc, 0xa4, 0xd2, 0x86, 0xb2, 0x95, 0x0a,
+ 0xab, 0x32, 0x14, 0x4a, 0xc3, 0x81, 0x09, 0xf4, 0x65, 0xd3, 0x0d, 0x94,
+ 0xf8, 0xb9, 0x41, 0xdb, 0x2c, 0xe5, 0xff, 0xca, 0x88, 0x1d, 0x4c, 0xda,
+ 0x40, 0x9c, 0xbc, 0xd1, 0x02, 0x72, 0xb4, 0x7c, 0x2c, 0x43, 0xbd, 0x0f,
+ 0xa3, 0x97, 0xf3, 0x3d, 0xd8, 0xe3, 0x07, 0x2f, 0xfe, 0xfb, 0xc0, 0x67,
+ 0x61, 0x05, 0xc2, 0x72, 0xf9, 0x5d, 0x3b, 0x67, 0x2c, 0xa1, 0xa2, 0x05,
+ 0x5b, 0xc6, 0xa0, 0x51, 0x5e, 0x37, 0xad, 0x8f, 0xd6, 0x22, 0x0d, 0x18,
+ 0x6f, 0xe4, 0xe1, 0xd7, 0xd8, 0x6c, 0xe5, 0xfe, 0xea, 0x29, 0xcf, 0xff,
+ 0xe0, 0xa5, 0x68, 0xfa, 0xda, 0x19, 0xdf, 0x0f, 0x07, 0x0f, 0xb3, 0x94,
+ 0x87, 0x9c, 0xa1, 0x25, 0xfd, 0xdc, 0x07, 0x0f, 0x9b, 0x39, 0x7f, 0xc3,
+ 0xed, 0x83, 0xef, 0x23, 0x67, 0x2f, 0xff, 0xd8, 0xdc, 0x30, 0x0e, 0x1f,
+ 0x7c, 0xb4, 0x16, 0xce, 0x5f, 0xe0, 0x3e, 0xf3, 0x05, 0x53, 0x95, 0x08,
+ 0xc4, 0x09, 0xdf, 0x55, 0xef, 0xfa, 0x3d, 0xbe, 0x58, 0xc4, 0x09, 0xcb,
+ 0xff, 0x72, 0x17, 0x57, 0x96, 0xff, 0xfe, 0x0e, 0x5f, 0xfe, 0x9c, 0x1f,
+ 0xee, 0x49, 0xbd, 0xc6, 0xa4, 0x72, 0xc8, 0xaa, 0x24, 0xb4, 0x8b, 0x7f,
+ 0x9f, 0xbf, 0x6e, 0x07, 0xc7, 0x2b, 0x67, 0xb9, 0xe2, 0x9b, 0xff, 0xfe,
+ 0x9c, 0x3d, 0x85, 0xf5, 0x26, 0x77, 0x92, 0xae, 0xa3, 0xb5, 0x9c, 0xbf,
+ 0xdd, 0x49, 0xa5, 0x03, 0x23, 0x97, 0xfe, 0x86, 0xf7, 0xc2, 0x3a, 0xf3,
+ 0xef, 0x1c, 0xa8, 0x47, 0x22, 0xdb, 0x3c, 0x67, 0x7d, 0x2e, 0xe4, 0xe7,
+ 0x2f, 0xfa, 0x3e, 0x63, 0xfb, 0x3e, 0xf1, 0xcb, 0x9e, 0x73, 0x95, 0xf1,
+ 0xfa, 0x09, 0x1b, 0x67, 0x57, 0xe0, 0x77, 0x50, 0xd9, 0xcb, 0x9a, 0x39,
+ 0xcb, 0xa1, 0x7e, 0x3c, 0x15, 0x0a, 0x6e, 0xd3, 0x9c, 0xbf, 0xfb, 0x8a,
+ 0x6f, 0x78, 0x2b, 0x71, 0xfc, 0xe5, 0xfe, 0xea, 0x04, 0x38, 0xdc, 0xc7,
+ 0x2f, 0x46, 0xbf, 0xc3, 0xfa, 0x5a, 0x2d, 0x69, 0x18, 0x7d, 0x84, 0x85,
+ 0xff, 0x9f, 0xed, 0xe7, 0x91, 0x8f, 0x23, 0x96, 0xf1, 0xca, 0xfc, 0xf3,
+ 0xd4, 0x3e, 0xbf, 0xff, 0xd3, 0x0c, 0x33, 0x50, 0xbc, 0xd6, 0x75, 0x35,
+ 0xd7, 0x39, 0x7f, 0xfc, 0xfa, 0xfd, 0xa6, 0x6a, 0x24, 0x9f, 0x7b, 0x0e,
+ 0x5f, 0xff, 0xfc, 0x0d, 0xf5, 0xe5, 0xb9, 0x27, 0x94, 0xd4, 0x76, 0x3d,
+ 0xb7, 0xf8, 0xe5, 0xfa, 0x30, 0x7c, 0xd0, 0xe5, 0xfc, 0x9f, 0x7f, 0xa7,
+ 0x09, 0xcb, 0x30, 0xe5, 0x30, 0xfa, 0x3a, 0x50, 0x25, 0xf7, 0x69, 0xac,
+ 0xe5, 0xe9, 0x00, 0x27, 0x2e, 0x7f, 0xb9, 0x1f, 0x2c, 0xc5, 0xce, 0x35,
+ 0x58, 0xa8, 0xbd, 0x17, 0xf4, 0xa5, 0xb8, 0xd0, 0x6f, 0xff, 0xec, 0x19,
+ 0xf7, 0xb8, 0xff, 0x3a, 0x9a, 0x76, 0xfc, 0x72, 0xfe, 0x0e, 0x0a, 0xba,
+ 0x83, 0x95, 0x26, 0x47, 0x70, 0x61, 0xec, 0xb2, 0xff, 0xa3, 0x28, 0x9a,
+ 0x30, 0x6d, 0x42, 0x8d, 0x8e, 0x3d, 0x87, 0x8f, 0xee, 0xfe, 0x94, 0xa6,
+ 0xda, 0x1b, 0x45, 0xcb, 0xff, 0xfc, 0x38, 0x1e, 0xc3, 0x63, 0x89, 0x3b,
+ 0x40, 0x75, 0x34, 0x72, 0xa1, 0x94, 0x86, 0x94, 0x91, 0x00, 0x43, 0x46,
+ 0xd0, 0x72, 0xff, 0xfa, 0x67, 0x79, 0x6e, 0x18, 0x1e, 0xc0, 0xac, 0xe5,
+ 0x41, 0xef, 0xa0, 0x85, 0xff, 0x64, 0xd2, 0x8f, 0xb3, 0xef, 0x1c, 0xbb,
+ 0x53, 0xe1, 0xed, 0x89, 0x05, 0xf0, 0x7a, 0x09, 0xce, 0x5f, 0xe0, 0xbc,
+ 0xb2, 0x70, 0x09, 0xcb, 0xff, 0x6b, 0x1a, 0xe6, 0xeb, 0xb1, 0x36, 0x72,
+ 0xd3, 0xc2, 0x26, 0x70, 0x93, 0x46, 0x77, 0x70, 0xf8, 0x72, 0xb0, 0xf4,
+ 0x1c, 0xd6, 0xfe, 0xf3, 0x40, 0x77, 0x16, 0x72, 0xff, 0x6a, 0x3c, 0x9f,
+ 0xc4, 0x8e, 0x5f, 0xdf, 0x4e, 0xf2, 0x86, 0xb3, 0x97, 0x0c, 0x8e, 0x54,
+ 0x1e, 0x44, 0xe6, 0x55, 0xc2, 0x33, 0xef, 0xe1, 0xca, 0x44, 0x4a, 0x8d,
+ 0xa1, 0x7b, 0x21, 0x8f, 0xda, 0x58, 0xeb, 0xc3, 0xe8, 0x63, 0x16, 0xd9,
+ 0x07, 0x8c, 0x00, 0xf7, 0x7f, 0xee, 0x11, 0x48, 0x62, 0xfa, 0xff, 0x7e,
+ 0x72, 0xff, 0x4a, 0x6c, 0x17, 0xee, 0x1c, 0xbe, 0xfa, 0x50, 0xc3, 0x97,
+ 0x47, 0x4e, 0x5f, 0xcf, 0x30, 0x60, 0x67, 0x39, 0x53, 0x9f, 0x38, 0x91,
+ 0xf1, 0x16, 0xbe, 0x89, 0x93, 0xa7, 0x2f, 0x70, 0x43, 0x0e, 0x53, 0x9e,
+ 0x0f, 0x01, 0x15, 0xf7, 0x04, 0x0a, 0xce, 0x5f, 0xdd, 0xc5, 0x5e, 0x27,
+ 0x39, 0x7e, 0x64, 0x4d, 0xa8, 0x39, 0x7d, 0x00, 0xe1, 0xd0, 0xe5, 0xf9,
+ 0xf7, 0xe4, 0x98, 0xe5, 0xfe, 0x4d, 0x44, 0xef, 0xa5, 0x9c, 0xb7, 0xb9,
+ 0x26, 0x3f, 0x84, 0x8b, 0x24, 0x42, 0xed, 0x14, 0x6c, 0x9b, 0xc5, 0x17,
+ 0xff, 0xb4, 0xb1, 0xce, 0x23, 0x91, 0xa8, 0xd9, 0xcb, 0xfc, 0xf3, 0x77,
+ 0x19, 0x9b, 0x39, 0x58, 0x7f, 0x9c, 0x52, 0x6f, 0x34, 0x8f, 0x1c, 0xbf,
+ 0x95, 0xe5, 0x1c, 0x53, 0x89, 0xca, 0x9c, 0xf4, 0x84, 0x7a, 0xfc, 0xaf,
+ 0xb3, 0x18, 0x72, 0xb0, 0xf2, 0x90, 0x8a, 0xff, 0xf4, 0xc3, 0x8a, 0xaa,
+ 0xfe, 0xda, 0x0c, 0xc7, 0x2f, 0xd8, 0x14, 0xd6, 0xce, 0x5f, 0x94, 0x92,
+ 0x7f, 0xb3, 0x97, 0xed, 0x2e, 0x32, 0x73, 0x97, 0xbd, 0xef, 0x8e, 0x5f,
+ 0xfd, 0xf2, 0xd3, 0xbc, 0xb8, 0x33, 0xa8, 0xc3, 0x95, 0xf9, 0xf4, 0x78,
+ 0x7a, 0xe0, 0x68, 0xe5, 0x62, 0x32, 0xb7, 0x09, 0x06, 0x84, 0x76, 0x89,
+ 0xd3, 0x51, 0x61, 0x3b, 0x70, 0xf4, 0xa8, 0x5d, 0x31, 0xc8, 0xe4, 0x52,
+ 0x1c, 0xfd, 0x85, 0xfb, 0x90, 0x7a, 0x39, 0xdb, 0xff, 0x0a, 0x29, 0xf6,
+ 0x71, 0xfa, 0x14, 0x39, 0x7f, 0xf9, 0x33, 0x41, 0x86, 0xf3, 0xb1, 0xf6,
+ 0xce, 0x5f, 0x29, 0x1a, 0xfc, 0xe5, 0xff, 0xa3, 0xee, 0xf6, 0x27, 0x80,
+ 0x30, 0xe5, 0xca, 0x48, 0xe5, 0xcf, 0xa3, 0x97, 0xf7, 0x92, 0x76, 0x42,
+ 0xce, 0x50, 0x4f, 0x13, 0xa2, 0xd7, 0xff, 0xbf, 0x9a, 0x49, 0xa9, 0x4d,
+ 0x24, 0xd4, 0x8e, 0x5e, 0xf2, 0x4e, 0x72, 0xbe, 0x3e, 0xbd, 0x27, 0x5f,
+ 0x99, 0x80, 0xd4, 0xe7, 0x2f, 0x40, 0x42, 0x72, 0xec, 0xe0, 0x39, 0x7d,
+ 0xfa, 0x83, 0x23, 0x96, 0x71, 0x37, 0xbe, 0x19, 0xbf, 0x6f, 0x78, 0x3f,
+ 0x9c, 0xaf, 0xcf, 0x34, 0x49, 0x6a, 0x13, 0xa1, 0x48, 0x46, 0xb9, 0x1f,
+ 0x8a, 0x41, 0x0a, 0x6b, 0xbe, 0x98, 0xe5, 0xf9, 0x4f, 0x7e, 0xcc, 0x39,
+ 0x4c, 0x3c, 0x3f, 0xc6, 0x6f, 0x2e, 0x36, 0x72, 0xff, 0xa4, 0xfa, 0xf0,
+ 0xc3, 0x36, 0x72, 0xff, 0x40, 0x63, 0x40, 0x8f, 0xce, 0x5c, 0xcd, 0xcc,
+ 0x7d, 0x6c, 0x38, 0xbf, 0xfe, 0x8c, 0xfb, 0xdd, 0xc4, 0x92, 0x2a, 0xae,
+ 0x1c, 0xbf, 0xff, 0x9d, 0xb0, 0xbb, 0xea, 0x7e, 0xbf, 0xba, 0x9a, 0x91,
+ 0xcb, 0xff, 0x43, 0x8e, 0x7b, 0xc8, 0xdf, 0x8e, 0x54, 0x27, 0x85, 0x84,
+ 0x69, 0x08, 0x7d, 0x17, 0x8a, 0x80, 0x17, 0x2b, 0x86, 0x66, 0x0d, 0xc2,
+ 0x3c, 0xa7, 0x72, 0xb1, 0xb1, 0x68, 0x73, 0x25, 0x74, 0x93, 0xf4, 0x0d,
+ 0xc7, 0xfb, 0xe9, 0x4a, 0xf7, 0xf4, 0x03, 0xe4, 0xfb, 0x80, 0xe5, 0xfb,
+ 0x1b, 0xcf, 0xbc, 0x72, 0xb9, 0x1e, 0xda, 0x19, 0x5f, 0xef, 0xa5, 0x81,
+ 0xee, 0x4e, 0x72, 0xb4, 0x7b, 0x02, 0x47, 0x7b, 0x59, 0xb3, 0x97, 0xe4,
+ 0x1e, 0x39, 0x23, 0x97, 0xb1, 0x27, 0x39, 0x4a, 0x9f, 0x03, 0x07, 0x3a,
+ 0x51, 0x7f, 0x44, 0xf9, 0xec, 0x61, 0xcb, 0xff, 0xb0, 0x40, 0xbe, 0xe3,
+ 0x26, 0x75, 0x9c, 0xa4, 0x45, 0x0e, 0x8c, 0x36, 0x5b, 0x7c, 0xc4, 0x80,
+ 0x9c, 0xbf, 0xc2, 0xaf, 0x61, 0x8c, 0x13, 0x97, 0xf3, 0x5a, 0x47, 0x00,
+ 0x3c, 0x72, 0xfd, 0x13, 0x66, 0x2c, 0xe5, 0x42, 0x2b, 0xb0, 0x85, 0x0c,
+ 0xfa, 0x67, 0x7f, 0xee, 0xe4, 0xc9, 0x30, 0x38, 0x01, 0xb3, 0x97, 0x93,
+ 0x4a, 0x9c, 0xa4, 0x3e, 0x11, 0x44, 0xbf, 0x47, 0x07, 0x62, 0x63, 0x95,
+ 0x23, 0xcb, 0xd9, 0x05, 0xff, 0xc0, 0x99, 0x3b, 0x1f, 0x4a, 0x26, 0x83,
+ 0x97, 0xe0, 0xb8, 0xc7, 0x4e, 0x5f, 0xd2, 0x8f, 0xbd, 0x9d, 0x39, 0x7f,
+ 0xfb, 0xdb, 0x4f, 0xe2, 0x5b, 0xcc, 0xfb, 0xc7, 0x2a, 0x63, 0xf9, 0xd9,
+ 0x75, 0x75, 0x18, 0x4d, 0xc2, 0x7e, 0xff, 0x75, 0xe6, 0xc4, 0xe0, 0x09,
+ 0xca, 0x43, 0xdf, 0xd9, 0x4d, 0xff, 0xfb, 0x40, 0xd6, 0xa0, 0x71, 0x54,
+ 0xef, 0x71, 0x43, 0x97, 0xa6, 0xd4, 0x1c, 0xbf, 0x3a, 0x06, 0x04, 0xe5,
+ 0xd0, 0x03, 0x95, 0x07, 0xb0, 0x23, 0xbb, 0x25, 0xbe, 0x9e, 0x38, 0x20,
+ 0xe5, 0xf7, 0x7f, 0x7f, 0x1c, 0xb7, 0x4e, 0x5b, 0x8b, 0x9b, 0x40, 0x11,
+ 0xdf, 0xfc, 0x8c, 0x4d, 0xf6, 0x13, 0x40, 0x6b, 0x39, 0x50, 0x8c, 0x74,
+ 0x59, 0x72, 0x8b, 0xf8, 0x76, 0x9c, 0x60, 0x27, 0x2f, 0xfb, 0xf4, 0x1f,
+ 0x46, 0xc1, 0xd3, 0x97, 0x85, 0x15, 0x39, 0x7f, 0x79, 0x34, 0x9e, 0x01,
+ 0xcb, 0x47, 0x24, 0x41, 0x30, 0xe5, 0x41, 0xcb, 0xf8, 0x0a, 0x77, 0x3e,
+ 0xd9, 0xcb, 0xff, 0xff, 0xf6, 0xa3, 0xc2, 0xeb, 0x4d, 0xcc, 0x9a, 0x5c,
+ 0x6f, 0xd1, 0xf4, 0x29, 0x9b, 0x39, 0x7f, 0xbb, 0x9f, 0x46, 0x91, 0x87,
+ 0x2f, 0xff, 0xff, 0xfb, 0x79, 0xee, 0xbb, 0x37, 0xad, 0x27, 0xde, 0x77,
+ 0x57, 0x32, 0x60, 0x7a, 0x1b, 0xfa, 0x0e, 0x5f, 0x81, 0x36, 0x34, 0xc3,
+ 0x95, 0xb4, 0x60, 0xfa, 0x12, 0xf7, 0xfd, 0xf6, 0xc5, 0x19, 0xec, 0x6b,
+ 0x39, 0x76, 0x68, 0xe5, 0x41, 0xe9, 0x74, 0xf2, 0xfe, 0xf0, 0xbf, 0xf8,
+ 0x27, 0x2f, 0xc2, 0xff, 0xe0, 0x9c, 0xae, 0x47, 0xa5, 0xe2, 0xca, 0x85,
+ 0x51, 0x01, 0x84, 0x1b, 0xc3, 0xd3, 0xcf, 0x40, 0x73, 0xbf, 0xf7, 0x93,
+ 0x62, 0xfe, 0x99, 0xc2, 0x72, 0xfb, 0xf7, 0xfb, 0x67, 0x2e, 0x6d, 0xb3,
+ 0x95, 0xb3, 0x7a, 0xd9, 0x25, 0xf7, 0x5f, 0x3a, 0x53, 0x99, 0xa2, 0xac,
+ 0x46, 0x82, 0x42, 0x76, 0xfc, 0xa6, 0x31, 0x34, 0x72, 0xff, 0x81, 0xe8,
+ 0x15, 0xb5, 0x7f, 0xb0, 0xe5, 0xee, 0xc7, 0xe7, 0x2f, 0xfc, 0x00, 0xf5,
+ 0x34, 0x9f, 0x4d, 0x07, 0x2b, 0x11, 0x88, 0x85, 0x0e, 0x7e, 0x23, 0xb7,
+ 0xbb, 0xc9, 0xac, 0xe5, 0xfb, 0xb0, 0x39, 0x39, 0xca, 0x83, 0xc9, 0x72,
+ 0x2b, 0xfd, 0xd8, 0xf0, 0x18, 0x0f, 0x1c, 0xa8, 0x66, 0x71, 0x4a, 0x32,
+ 0x20, 0xc3, 0x77, 0xe8, 0x73, 0x35, 0x91, 0x4d, 0x1b, 0x3e, 0x88, 0x59,
+ 0x0a, 0xee, 0xc3, 0xd1, 0xcb, 0x7f, 0x85, 0x87, 0x0e, 0x70, 0x32, 0xae,
+ 0x37, 0x19, 0x27, 0xa1, 0xd5, 0xc6, 0x10, 0x5c, 0x04, 0x17, 0xc9, 0xa5,
+ 0x26, 0x39, 0x7f, 0xe1, 0xfd, 0x8f, 0x21, 0x8f, 0x6c, 0xe5, 0xd9, 0x87,
+ 0x2f, 0x97, 0xd4, 0x50, 0xe5, 0x75, 0x13, 0x4e, 0x49, 0xc3, 0x9f, 0x28,
+ 0x2b, 0x7e, 0x9a, 0x26, 0xec, 0x1c, 0xbf, 0xfc, 0x3e, 0xda, 0x9e, 0x41,
+ 0x04, 0xb3, 0x67, 0x2e, 0x52, 0x0e, 0x5e, 0x6d, 0xb6, 0xca, 0x5f, 0x4b,
+ 0xd8, 0xb2, 0x9c, 0xcd, 0x05, 0xfb, 0x02, 0x9f, 0xec, 0xf7, 0x7f, 0x2b,
+ 0x47, 0xd2, 0x26, 0x95, 0x09, 0x9a, 0x61, 0x4e, 0x92, 0x9e, 0x14, 0x17,
+ 0x7b, 0x67, 0x2f, 0xf7, 0xbb, 0x1e, 0xdf, 0x50, 0xe5, 0xfb, 0x96, 0x4c,
+ 0x93, 0x9c, 0xae, 0x47, 0xbd, 0xb3, 0x3b, 0x6c, 0xe5, 0xfe, 0xf7, 0xd2,
+ 0xec, 0x0c, 0xe5, 0x2f, 0xfd, 0x9f, 0x49, 0x30, 0x47, 0x02, 0x72, 0xfd,
+ 0x3b, 0x01, 0xf7, 0x8e, 0x54, 0x26, 0x8d, 0xf3, 0xae, 0x89, 0x04, 0x47,
+ 0x66, 0xbe, 0x3c, 0xb2, 0x1c, 0xbe, 0x75, 0x1c, 0x27, 0x2e, 0xfa, 0x4e,
+ 0x6c, 0x80, 0x21, 0x7f, 0xc3, 0x0d, 0xed, 0x07, 0xe9, 0x1c, 0xba, 0x16,
+ 0x72, 0x84, 0xf3, 0xf8, 0x9c, 0xdf, 0x4e, 0xa4, 0x35, 0x9c, 0xbf, 0x0c,
+ 0x37, 0x82, 0x72, 0xff, 0xbb, 0xf4, 0x2b, 0x34, 0xa1, 0xac, 0xe5, 0xb6,
+ 0x13, 0xe5, 0xc2, 0x6a, 0xd2, 0x2c, 0xfd, 0x08, 0xca, 0x85, 0x40, 0x79,
+ 0x08, 0x94, 0x7c, 0x78, 0x6b, 0x5f, 0xc3, 0xf6, 0xe6, 0xcf, 0x1c, 0xbf,
+ 0x93, 0xc2, 0xff, 0xec, 0xe5, 0xff, 0xef, 0x4d, 0x9a, 0xc7, 0x64, 0x75,
+ 0x02, 0x72, 0xfe, 0x03, 0x33, 0xbf, 0x39, 0xca, 0x55, 0x14, 0x82, 0x5b,
+ 0xb4, 0x9b, 0xff, 0xc8, 0x11, 0x7f, 0x87, 0x3d, 0x89, 0xf9, 0xcb, 0xe5,
+ 0x84, 0x13, 0x9c, 0xbd, 0x2d, 0x80, 0xe5, 0xd1, 0xec, 0x3c, 0x1e, 0x92,
+ 0x5f, 0xba, 0xfa, 0xcd, 0x1c, 0xb8, 0x0e, 0x72, 0x96, 0x6f, 0x44, 0x9e,
+ 0xfa, 0x5e, 0x00, 0x4e, 0x5f, 0xa1, 0x24, 0xfb, 0x39, 0x5f, 0x1e, 0x4e,
+ 0x88, 0xef, 0xfd, 0xf6, 0xd1, 0x5c, 0xf2, 0x6b, 0x0e, 0x54, 0xe8, 0xcb,
+ 0x16, 0x9f, 0x11, 0xdf, 0xe0, 0x8e, 0x71, 0x4d, 0x39, 0xca, 0x83, 0xe3,
+ 0x01, 0x85, 0xfa, 0x76, 0xb4, 0xcf, 0x8e, 0x5f, 0x93, 0x71, 0x3b, 0x0f,
+ 0x67, 0xea, 0xfd, 0x0f, 0xaf, 0xc0, 0x7b, 0x3f, 0x57, 0x3c, 0x8f, 0x67,
+ 0xea, 0xf8, 0x12, 0xcd, 0x9e, 0xcf, 0xd5, 0x04, 0xf4, 0x84, 0x8e, 0xfd,
+ 0x19, 0xbc, 0x13, 0xd9, 0xfa, 0xa3, 0xd9, 0xfa, 0xb9, 0xfc, 0x7b, 0x3f,
+ 0x4c, 0x2e, 0x2d, 0x21, 0x3f, 0xc0, 0x25, 0x5f, 0x63, 0x44, 0xfc, 0xf6,
+ 0x7e, 0xa8, 0xf6, 0x7e, 0xae, 0xfe, 0x0f, 0x67, 0xea, 0xff, 0xb3, 0xf7,
+ 0xd6, 0x71, 0xc0, 0x9e, 0xcf, 0xd5, 0xfd, 0x9d, 0x4d, 0x82, 0x73, 0xd9,
+ 0xfa, 0xaf, 0xd1, 0x4c, 0x24, 0x9b, 0x47, 0xbe, 0xd4, 0xf1, 0xe3, 0xd9,
+ 0xfa, 0xa3, 0xd9, 0xfa, 0xc3, 0x61, 0x73, 0x6d, 0x9e, 0xcf, 0xd5, 0x49,
+ 0x58, 0xe0, 0x4d, 0x72, 0x10, 0xff, 0x42, 0x77, 0x44, 0xec, 0x31, 0xdc,
+ 0x2f, 0xbc, 0xc0, 0xd9, 0x3d, 0xe9, 0x42, 0xa5, 0xb3, 0xf4, 0xe6, 0x89,
+ 0x0b, 0xfa, 0x31, 0x48, 0x94, 0x8e, 0x5f, 0xed, 0xe4, 0xa5, 0x1e, 0xf8,
+ 0xe5, 0x62, 0x28, 0x04, 0xff, 0x65, 0xb7, 0xfe, 0xc5, 0x87, 0x34, 0xdb,
+ 0xf6, 0x63, 0x97, 0xff, 0x6c, 0x72, 0x68, 0x9f, 0xf7, 0xfb, 0x67, 0x2e,
+ 0x94, 0xe5, 0x2f, 0xa6, 0x77, 0xd1, 0xca, 0x9d, 0x1d, 0xff, 0x17, 0x75,
+ 0x00, 0x51, 0xf8, 0x06, 0x2e, 0x49, 0xce, 0x56, 0x97, 0x73, 0x1e, 0x75,
+ 0x9f, 0xc9, 0xd7, 0xf9, 0x9b, 0x1c, 0xf6, 0x7e, 0x72, 0xfe, 0xf6, 0x76,
+ 0x35, 0xf9, 0xcb, 0xfe, 0x5c, 0x7e, 0x10, 0x3e, 0xa4, 0x72, 0xff, 0xce,
+ 0xf3, 0xe3, 0x1c, 0x7e, 0x91, 0xcb, 0xce, 0xae, 0xf0, 0xfe, 0x26, 0x3a,
+ 0xb3, 0x7c, 0x91, 0xb4, 0x30, 0xa6, 0xa8, 0x4c, 0xf5, 0xe3, 0x0d, 0xbf,
+ 0x0f, 0xbb, 0x93, 0x9c, 0xb8, 0x2d, 0x9c, 0xa8, 0x3c, 0x0c, 0x28, 0xbf,
+ 0xff, 0x4b, 0x51, 0xc5, 0xe6, 0x80, 0xf6, 0x18, 0xf3, 0x1c, 0xbf, 0xdc,
+ 0x0f, 0xb4, 0xdc, 0xd8, 0x72, 0xbe, 0x44, 0x76, 0x96, 0x2f, 0x20, 0xc8,
+ 0xe5, 0x43, 0x3e, 0xaa, 0x52, 0xe2, 0x71, 0x15, 0x21, 0xa6, 0xd6, 0x61,
+ 0xa8, 0x44, 0xf6, 0x39, 0x77, 0x9d, 0xed, 0x18, 0xdd, 0xf6, 0xd0, 0x08,
+ 0x57, 0x70, 0x12, 0x5f, 0xff, 0xf2, 0x75, 0xfb, 0x12, 0xe7, 0x9f, 0xc4,
+ 0xb6, 0x1e, 0xc6, 0x8e, 0x5f, 0xf9, 0x58, 0xf8, 0x63, 0xbd, 0x02, 0xce,
+ 0x5f, 0xfd, 0xa8, 0xc1, 0xc9, 0x27, 0x73, 0x89, 0xcb, 0xff, 0xe1, 0x75,
+ 0x77, 0x9c, 0x63, 0xef, 0x6c, 0x0c, 0x39, 0x41, 0x44, 0xb0, 0xa1, 0xde,
+ 0x1e, 0x38, 0x72, 0xfe, 0x17, 0x57, 0xaf, 0x23, 0x97, 0xe5, 0xe3, 0x23,
+ 0x67, 0x2f, 0x36, 0xdb, 0x65, 0x2f, 0x29, 0x1f, 0x94, 0xe6, 0x68, 0x2f,
+ 0xf9, 0xe4, 0xa6, 0xb3, 0x8b, 0xe8, 0xe5, 0xff, 0xfb, 0xb9, 0x25, 0x04,
+ 0x72, 0x79, 0xa5, 0x1a, 0x9c, 0xe5, 0x0a, 0x24, 0xfc, 0x77, 0x7f, 0xfb,
+ 0xf8, 0x93, 0x8c, 0x91, 0x99, 0xf7, 0x8e, 0x5f, 0xf7, 0x9c, 0x73, 0x7a,
+ 0x8d, 0x9c, 0xbe, 0x94, 0x7f, 0xf1, 0xcb, 0xfb, 0xf8, 0x1c, 0xfb, 0xc7,
+ 0x2e, 0x7f, 0xf9, 0x1e, 0x92, 0x84, 0x97, 0xff, 0x94, 0x19, 0x95, 0x70,
+ 0xf7, 0x17, 0x9a, 0x39, 0x48, 0x9a, 0x83, 0xa5, 0x0c, 0x22, 0x76, 0x63,
+ 0x7b, 0x8c, 0x68, 0xe5, 0x49, 0x72, 0x10, 0x2d, 0x19, 0x0d, 0x64, 0x22,
+ 0x60, 0xeb, 0x96, 0xfe, 0x8e, 0x30, 0xc3, 0xf4, 0x6e, 0x5c, 0x50, 0x2e,
+ 0x49, 0xce, 0x5f, 0xe1, 0x58, 0x53, 0x8c, 0x04, 0xe5, 0x04, 0xf2, 0xc0,
+ 0x2f, 0x6f, 0xce, 0x5f, 0xf6, 0x43, 0x5f, 0x2e, 0xbe, 0x68, 0xe5, 0xe6,
+ 0x24, 0xc7, 0x2f, 0xd9, 0xfe, 0xe2, 0x47, 0x2f, 0xc8, 0xc0, 0x87, 0x0e,
+ 0x5b, 0xf1, 0x3c, 0xf6, 0x85, 0x17, 0xfd, 0xee, 0xe6, 0xf9, 0x79, 0x27,
+ 0x39, 0x50, 0x7c, 0xc8, 0x55, 0x7f, 0xc2, 0x80, 0xe1, 0xf6, 0xd2, 0x3c,
+ 0x72, 0xa4, 0x9b, 0xfc, 0xc2, 0x4c, 0x3c, 0xec, 0x34, 0x84, 0x82, 0xfb,
+ 0x3c, 0xa4, 0xe7, 0x2f, 0x36, 0xdb, 0x65, 0x88, 0x40, 0xbe, 0x5b, 0xba,
+ 0xcb, 0x10, 0x81, 0xcc, 0xd7, 0x5f, 0x3e, 0xb1, 0xb3, 0x95, 0xa3, 0xe3,
+ 0xe2, 0x83, 0x79, 0xb6, 0xdb, 0x2c, 0x41, 0xe5, 0x16, 0x20, 0xf3, 0x99,
+ 0xae, 0xbf, 0xb3, 0xdd, 0x03, 0xc8, 0xe5, 0xe6, 0xdb, 0x6c, 0xe5, 0xed,
+ 0xc2, 0xa5, 0x39, 0x9a, 0x0a, 0xc4, 0x7c, 0xad, 0x48, 0x4a, 0xfc, 0x9b,
+ 0x4d, 0x69, 0xf4, 0xb2, 0x3a, 0xeb, 0xff, 0xbb, 0x12, 0x4f, 0x67, 0x57,
+ 0x0c, 0x39, 0x50, 0x7e, 0x1c, 0x4b, 0x6f, 0xfb, 0x63, 0x0c, 0xde, 0xc0,
+ 0x27, 0x2f, 0xff, 0x67, 0x53, 0x5d, 0x7c, 0xda, 0x3c, 0xe7, 0x2f, 0xa3,
+ 0xd0, 0xc3, 0x95, 0xf2, 0x28, 0x58, 0x71, 0xe4, 0x8b, 0xfe, 0xec, 0x0a,
+ 0xfe, 0xdb, 0xb5, 0x9c, 0xbf, 0x38, 0x40, 0xea, 0x1c, 0xa9, 0x1f, 0x23,
+ 0x67, 0x97, 0xc2, 0x90, 0xa9, 0xcb, 0xca, 0x47, 0xe7, 0x2a, 0x73, 0x7e,
+ 0xc2, 0x1b, 0xf2, 0xe3, 0xb0, 0xc2, 0x97, 0xe1, 0x71, 0x1c, 0x29, 0x76,
+ 0x2c, 0xa5, 0xcd, 0xb6, 0x52, 0xb0, 0xfe, 0xb6, 0x4f, 0xe2, 0x46, 0xc5,
+ 0xaf, 0xf0, 0xa9, 0x1f, 0xf7, 0x38, 0x0a, 0x73, 0x37, 0x97, 0xff, 0xa7,
+ 0x0e, 0x9d, 0x63, 0x9c, 0x74, 0x9b, 0x39, 0x50, 0xa9, 0x93, 0x21, 0x2a,
+ 0x8c, 0x4f, 0x0d, 0x80, 0x24, 0xdf, 0xfd, 0x1f, 0xef, 0x30, 0x2e, 0x2e,
+ 0xa9, 0xcb, 0xff, 0xf7, 0x53, 0x8a, 0x08, 0x77, 0x1a, 0x4c, 0xfb, 0x67,
+ 0x2f, 0xe1, 0x8c, 0xd3, 0xfe, 0x72, 0xff, 0xd1, 0xae, 0xc2, 0x76, 0x05,
+ 0x0e, 0x5d, 0x2d, 0xad, 0x17, 0xbe, 0x56, 0x6c, 0xb2, 0xff, 0x40, 0xe3,
+ 0x13, 0xe9, 0x1c, 0xbf, 0xfe, 0xd8, 0xe7, 0xdf, 0xbe, 0xdf, 0x49, 0xf7,
+ 0xe7, 0x2b, 0xe4, 0x60, 0xf8, 0xf5, 0xb3, 0x2a, 0xea, 0x7e, 0x6f, 0x1e,
+ 0x0d, 0xee, 0x2a, 0x30, 0xe5, 0xfd, 0xb5, 0x02, 0x01, 0x91, 0xcb, 0xf9,
+ 0x16, 0x1c, 0x7f, 0xce, 0x5f, 0xff, 0xbd, 0xbf, 0xb9, 0x07, 0x03, 0x0f,
+ 0xac, 0x1f, 0xce, 0x5f, 0xff, 0xfb, 0x97, 0xa5, 0x9f, 0xb4, 0xce, 0x41,
+ 0xc0, 0xc3, 0xeb, 0x07, 0xf2, 0x21, 0x7f, 0xf6, 0x7b, 0x92, 0xfa, 0x9d,
+ 0xea, 0x7e, 0x68, 0x42, 0xd5, 0x24, 0x65, 0x6d, 0xda, 0xf4, 0x4f, 0xcf,
+ 0x69, 0xa2, 0xfa, 0x32, 0x2b, 0xf3, 0x36, 0xdb, 0xfc, 0x72, 0xdb, 0x09,
+ 0xf4, 0x28, 0x7d, 0x7f, 0x64, 0xd2, 0x4d, 0x6c, 0xe5, 0xfd, 0x1f, 0x29,
+ 0xb8, 0xc3, 0x95, 0x0c, 0xd7, 0x60, 0xc3, 0xa3, 0x23, 0xa1, 0x49, 0x55,
+ 0x3a, 0x96, 0x50, 0xf2, 0x91, 0x7f, 0x29, 0xe1, 0xc8, 0x04, 0xbf, 0x71,
+ 0xed, 0x78, 0xa4, 0x05, 0xd7, 0x9b, 0x6d, 0xb2, 0x97, 0x9c, 0x42, 0x53,
+ 0x99, 0xa0, 0xbe, 0xcd, 0x67, 0x8e, 0x57, 0xe7, 0x9d, 0xb2, 0xdb, 0xee,
+ 0xa3, 0xc8, 0xe5, 0xfe, 0xf6, 0xd3, 0x5a, 0x46, 0x1c, 0xbc, 0xc9, 0xc2,
+ 0x72, 0x84, 0xf4, 0x7c, 0x67, 0x7b, 0x92, 0xad, 0x0e, 0x5e, 0xf3, 0x84,
+ 0xe5, 0x68, 0xdf, 0x6c, 0x8a, 0xfe, 0x5c, 0x7e, 0x9a, 0x54, 0xa5, 0xfc,
+ 0xa6, 0x6b, 0x32, 0x63, 0x97, 0xe7, 0xef, 0x20, 0xc1, 0xca, 0x92, 0x73,
+ 0x61, 0x23, 0xc7, 0x24, 0x5f, 0x12, 0x1d, 0x97, 0xf8, 0xba, 0xfc, 0xfa,
+ 0xd6, 0x7c, 0x72, 0xff, 0xf7, 0xba, 0x8f, 0xfe, 0x68, 0x30, 0x32, 0x39,
+ 0x7f, 0xfb, 0xee, 0x5f, 0x7f, 0x02, 0xb7, 0x9c, 0x5c, 0xe5, 0x42, 0x2f,
+ 0xf0, 0xa0, 0x52, 0x6f, 0xd1, 0xb5, 0x06, 0x47, 0x2f, 0xb9, 0x2d, 0x24,
+ 0x72, 0xff, 0xcb, 0xcd, 0x62, 0x6f, 0xb1, 0xc4, 0xe5, 0xff, 0xff, 0xce,
+ 0x9e, 0x4e, 0xad, 0x39, 0x49, 0x3a, 0xe3, 0xe9, 0x66, 0xb0, 0xe5, 0xee,
+ 0xe7, 0x01, 0xca, 0xea, 0x23, 0xdd, 0xc2, 0xff, 0x86, 0x3e, 0xdc, 0x7a,
+ 0x02, 0x72, 0xf6, 0xd4, 0xdf, 0x23, 0xda, 0xc2, 0x2a, 0x0a, 0x70, 0x5f,
+ 0x12, 0x7a, 0x32, 0x8b, 0xff, 0xff, 0xfe, 0x8d, 0xc7, 0xa7, 0xc6, 0xf5,
+ 0x9d, 0x75, 0x37, 0x8a, 0xb8, 0xff, 0x03, 0x13, 0x76, 0x0e, 0x5f, 0xb7,
+ 0xd7, 0x5c, 0x1c, 0xbf, 0x3c, 0xed, 0xbc, 0x8e, 0x50, 0xa3, 0x95, 0xb8,
+ 0x4a, 0xa8, 0x4f, 0x7f, 0xff, 0xf2, 0x2b, 0xf4, 0xbd, 0x83, 0xed, 0xf2,
+ 0xde, 0xf3, 0x58, 0x2f, 0x23, 0x97, 0xff, 0x73, 0x08, 0xc0, 0x17, 0x8a,
+ 0xa6, 0x8e, 0x5d, 0x8d, 0x9c, 0xb6, 0x41, 0xee, 0xed, 0x1a, 0xfe, 0x9f,
+ 0xaf, 0xed, 0x41, 0xcb, 0xfc, 0x1e, 0xc4, 0xce, 0xff, 0x1c, 0xbd, 0xdf,
+ 0xf8, 0x9c, 0xad, 0x1e, 0xa7, 0x01, 0xa5, 0x49, 0x19, 0xba, 0x26, 0x78,
+ 0x41, 0x5f, 0xfd, 0x9a, 0xfd, 0x89, 0xb5, 0x37, 0x18, 0x72, 0xfc, 0x1d,
+ 0x47, 0xcd, 0x67, 0x2f, 0xff, 0xfd, 0xe8, 0xd7, 0xeb, 0xea, 0x49, 0x34,
+ 0xff, 0xf8, 0x61, 0x9b, 0x39, 0x73, 0x5e, 0xce, 0x52, 0xa8, 0x87, 0x76,
+ 0xda, 0x92, 0x63, 0x78, 0x8a, 0xf0, 0xb3, 0xbc, 0xd4, 0x8f, 0xe7, 0x2e,
+ 0xc6, 0x1c, 0xbf, 0xfb, 0x07, 0xfe, 0x4a, 0x6b, 0xf6, 0x26, 0xce, 0x50,
+ 0x4f, 0x7d, 0x82, 0xd7, 0xdf, 0xfb, 0x3f, 0x39, 0x7e, 0x8d, 0xed, 0x38,
+ 0x9c, 0xa4, 0x3e, 0xfd, 0x11, 0x74, 0x92, 0xf3, 0x4f, 0xa0, 0xe5, 0xff,
+ 0x2f, 0xa3, 0x1f, 0x24, 0x74, 0xe5, 0x43, 0x23, 0x86, 0x51, 0x90, 0x84,
+ 0xb7, 0x23, 0xaa, 0x48, 0xc7, 0x74, 0x6c, 0xf1, 0xcf, 0x0c, 0x69, 0xfb,
+ 0x34, 0x04, 0x3c, 0x1a, 0x17, 0x28, 0x3f, 0x7f, 0xe7, 0x40, 0x83, 0xdb,
+ 0x9f, 0x1b, 0x39, 0x7e, 0xde, 0x2b, 0x1b, 0x39, 0x7f, 0x35, 0xed, 0x07,
+ 0xe9, 0x1c, 0xbf, 0xf3, 0xe9, 0xa2, 0x77, 0x1f, 0xef, 0xce, 0x5f, 0xff,
+ 0x93, 0xd0, 0xcc, 0xfb, 0xd0, 0xc5, 0x34, 0xff, 0x9c, 0xbe, 0x41, 0x70,
+ 0x9c, 0xbf, 0xed, 0xc6, 0xbd, 0x1c, 0xc2, 0x87, 0x2a, 0x48, 0xb1, 0x0a,
+ 0xbe, 0xc8, 0x2f, 0xff, 0xec, 0xef, 0x2c, 0x62, 0x76, 0x39, 0x6f, 0x78,
+ 0x3f, 0x9c, 0xbf, 0xf9, 0x35, 0x12, 0xec, 0x4c, 0x20, 0x54, 0xe5, 0x75,
+ 0x14, 0x7b, 0x5e, 0xb9, 0x6d, 0x0e, 0x5f, 0xca, 0xfa, 0x3b, 0x1b, 0x39,
+ 0x7f, 0x75, 0x3e, 0xdb, 0xfc, 0x72, 0xa4, 0x7e, 0xc8, 0x33, 0xf9, 0x75,
+ 0xff, 0xd8, 0xe3, 0x3b, 0x78, 0x21, 0xec, 0x1c, 0xbc, 0xb8, 0x6b, 0x39,
+ 0x7f, 0xa6, 0xeb, 0xeb, 0x48, 0x13, 0x95, 0x87, 0xa6, 0xe3, 0xf7, 0xc9,
+ 0xd7, 0x61, 0xcb, 0xfe, 0x11, 0xc9, 0xfd, 0xe8, 0x61, 0xca, 0x99, 0x30,
+ 0xf1, 0x84, 0xb7, 0x88, 0x14, 0x21, 0xbf, 0x6b, 0x36, 0x8d, 0x9c, 0xbd,
+ 0x0d, 0x45, 0xce, 0x5f, 0xca, 0x40, 0x16, 0x06, 0x1c, 0xb9, 0x04, 0xe5,
+ 0xf4, 0xa0, 0x56, 0x72, 0x82, 0x6d, 0xb0, 0x56, 0xfe, 0x8f, 0x70, 0x8f,
+ 0x1f, 0x1c, 0xae, 0x47, 0xa4, 0x84, 0x17, 0xd1, 0xfe, 0x09, 0xca, 0x92,
+ 0xeb, 0xee, 0x14, 0x2c, 0xc5, 0x21, 0xe5, 0x34, 0x34, 0xf5, 0x09, 0x96,
+ 0x46, 0x7c, 0xe8, 0x9b, 0x28, 0x01, 0x0b, 0x70, 0xb7, 0x68, 0x47, 0x7c,
+ 0xce, 0x14, 0xd4, 0x5a, 0xb3, 0x97, 0x7b, 0x67, 0x29, 0x0f, 0x2e, 0x63,
+ 0x4b, 0xe5, 0x21, 0xbd, 0x9c, 0xbb, 0xff, 0x1c, 0xbb, 0xfe, 0x9c, 0xbe,
+ 0xd6, 0xb3, 0x67, 0x2e, 0xc9, 0x8e, 0x5a, 0x5c, 0x91, 0x1b, 0x39, 0x23,
+ 0x06, 0x1c, 0x61, 0x42, 0x2b, 0xf2, 0x79, 0xc7, 0x0e, 0x5f, 0xb4, 0x1c,
+ 0xc1, 0x39, 0x7f, 0xf3, 0x5a, 0x67, 0x63, 0x8e, 0xfb, 0x1f, 0x1c, 0xbf,
+ 0xbe, 0xd0, 0x3e, 0xf4, 0x8e, 0x53, 0xa2, 0x83, 0x64, 0xc0, 0x49, 0xbf,
+ 0x37, 0xef, 0x64, 0xe7, 0x2f, 0xfb, 0x07, 0x59, 0xbc, 0x4e, 0x9c, 0xbf,
+ 0xfe, 0x97, 0x87, 0x1f, 0xc3, 0x9e, 0xf6, 0x36, 0x72, 0xec, 0xe2, 0x72,
+ 0xff, 0x97, 0xdc, 0x0b, 0x13, 0x58, 0x72, 0xa7, 0x3d, 0x0c, 0x18, 0xbf,
+ 0xa2, 0x35, 0xd8, 0xe2, 0x72, 0xff, 0xf7, 0xb7, 0x93, 0x76, 0x38, 0xe7,
+ 0x7b, 0x07, 0x2f, 0xee, 0x85, 0x38, 0xc0, 0x4e, 0x56, 0x1f, 0xdb, 0xa6,
+ 0x5f, 0x6d, 0x33, 0xf3, 0x97, 0xd9, 0xe4, 0xd9, 0xcb, 0xf9, 0xa9, 0x98,
+ 0x5a, 0xb9, 0xc0, 0x72, 0xb6, 0x7b, 0x7e, 0x21, 0xbf, 0xf0, 0x1d, 0x9b,
+ 0x41, 0x7d, 0x2a, 0x72, 0xa4, 0xae, 0xe8, 0x30, 0xc5, 0xc2, 0xf5, 0x95,
+ 0x7c, 0x6d, 0xa8, 0x4f, 0x74, 0x88, 0x61, 0x53, 0xb2, 0x0f, 0x3e, 0xb6,
+ 0x45, 0x7f, 0xfe, 0xf2, 0x6e, 0x7c, 0x6f, 0x69, 0x38, 0xbf, 0xde, 0x39,
+ 0x79, 0xbc, 0xe9, 0xcb, 0xfd, 0xb4, 0x57, 0xae, 0x28, 0x72, 0xfd, 0x38,
+ 0x45, 0xd5, 0x39, 0x7c, 0x9b, 0xc0, 0xe2, 0x34, 0x1d, 0x63, 0xc3, 0xaa,
+ 0x19, 0x5f, 0xf9, 0xda, 0xff, 0x06, 0xd0, 0x7e, 0x91, 0xcb, 0xfc, 0x1c,
+ 0x14, 0x6f, 0xa0, 0x39, 0x7f, 0xfd, 0xd4, 0x8f, 0x27, 0xf1, 0x2e, 0x6d,
+ 0xb6, 0xd9, 0x4b, 0xff, 0x92, 0x3d, 0xfc, 0x4b, 0x9b, 0x6d, 0xb6, 0x52,
+ 0xb1, 0x13, 0xfd, 0x55, 0xa9, 0xd1, 0xe9, 0xe8, 0x69, 0x5f, 0xee, 0x81,
+ 0xd8, 0x17, 0x61, 0xca, 0x13, 0xdc, 0xf1, 0x4d, 0xf0, 0x73, 0x15, 0x29,
+ 0x7c, 0xff, 0xbf, 0x8e, 0x5f, 0xf6, 0x9d, 0x7c, 0xbb, 0x0a, 0x09, 0xcb,
+ 0xc0, 0x8d, 0x1c, 0xbb, 0xdb, 0x09, 0xeb, 0xcc, 0x77, 0x7a, 0x42, 0x03,
+ 0x44, 0x32, 0xbd, 0xd8, 0x9c, 0xe5, 0xfb, 0xd1, 0x25, 0x58, 0x72, 0xf3,
+ 0x6d, 0xb6, 0x52, 0xf6, 0x0a, 0xca, 0x73, 0x34, 0x17, 0xfe, 0xc9, 0xf0,
+ 0x2f, 0x21, 0x89, 0xce, 0x54, 0x22, 0xd3, 0xf4, 0x91, 0x2d, 0xbe, 0x71,
+ 0x6a, 0x1c, 0x31, 0xcb, 0x9a, 0x83, 0x50, 0x39, 0x7e, 0xcf, 0x78, 0x13,
+ 0x9c, 0xb4, 0x9a, 0x81, 0xe6, 0x09, 0x1d, 0xe7, 0x6b, 0x83, 0x97, 0xec,
+ 0x0f, 0x5d, 0xac, 0xe5, 0xf8, 0x70, 0x30, 0xc3, 0x95, 0x0a, 0xc9, 0xe7,
+ 0x21, 0x09, 0x16, 0x3c, 0xfc, 0x5f, 0x31, 0x4e, 0xa1, 0xa3, 0xd2, 0xf7,
+ 0x78, 0x01, 0x6f, 0x11, 0xe6, 0xca, 0xaf, 0xe6, 0x62, 0x6a, 0x69, 0x1c,
+ 0xbf, 0xfe, 0x55, 0x47, 0x1e, 0xbc, 0xb7, 0x8c, 0x86, 0xb3, 0x95, 0x08,
+ 0x81, 0x42, 0xeb, 0xde, 0x48, 0x39, 0x76, 0x09, 0xca, 0x43, 0x60, 0x01,
+ 0xbb, 0xf0, 0xc7, 0xd1, 0xb3, 0x97, 0xfe, 0xc4, 0x17, 0xf6, 0xdb, 0x81,
+ 0x39, 0x7b, 0xaf, 0xa8, 0x3e, 0x3d, 0x93, 0xdf, 0x26, 0xa3, 0xc7, 0x2f,
+ 0xb7, 0x91, 0x23, 0x94, 0x13, 0xc2, 0x12, 0x1b, 0xf4, 0x4b, 0xb9, 0xf1,
+ 0xcb, 0xbe, 0xfc, 0xe5, 0xfc, 0xc8, 0xdf, 0xe8, 0xb3, 0x97, 0xb7, 0x0a,
+ 0xfe, 0x78, 0xfb, 0x19, 0xbf, 0xc0, 0xcd, 0x7f, 0xfa, 0x09, 0xcb, 0xce,
+ 0xd5, 0xce, 0x72, 0xff, 0xd8, 0xc4, 0x0e, 0xb0, 0x2e, 0xc3, 0x97, 0xd8,
+ 0xc5, 0x02, 0x72, 0xba, 0x7c, 0x02, 0x7b, 0x7f, 0xf9, 0x03, 0xd5, 0x37,
+ 0x9a, 0x5b, 0xba, 0xcd, 0x10, 0x62, 0xff, 0xdd, 0x03, 0xab, 0x9e, 0xf6,
+ 0x74, 0xe5, 0xff, 0xb7, 0xfb, 0xfd, 0xb5, 0x35, 0xd7, 0x39, 0x7c, 0x0e,
+ 0xe2, 0xce, 0x54, 0x91, 0xf4, 0x15, 0x7f, 0x1f, 0xb4, 0x42, 0xbf, 0xed,
+ 0xee, 0x35, 0x25, 0xa4, 0xe7, 0x2f, 0xe0, 0x2a, 0x39, 0x38, 0x0e, 0x54,
+ 0x1f, 0x4f, 0x4e, 0xaf, 0x74, 0x0d, 0x67, 0x2f, 0xff, 0x69, 0xf8, 0xe0,
+ 0xaf, 0xa9, 0xfa, 0x9e, 0x39, 0x50, 0x99, 0xb4, 0xa1, 0x51, 0xc3, 0x90,
+ 0x80, 0x82, 0xbe, 0x57, 0x07, 0xd3, 0x51, 0x34, 0xdc, 0x20, 0xbd, 0x29,
+ 0x46, 0xfd, 0xe4, 0x5a, 0x04, 0xe5, 0xfe, 0xd0, 0x1d, 0x40, 0x3a, 0x87,
+ 0x2e, 0xe3, 0x87, 0x2b, 0x0f, 0x35, 0xcd, 0x6e, 0xff, 0xf3, 0x97, 0xfc,
+ 0xbe, 0xa6, 0x85, 0x3d, 0xb3, 0x94, 0xc3, 0xd1, 0xfc, 0x66, 0xff, 0x7e,
+ 0x9d, 0xee, 0x7e, 0xe7, 0x2f, 0xff, 0xf9, 0x99, 0xef, 0x3e, 0x86, 0x3e,
+ 0x92, 0x9a, 0xfd, 0x89, 0xb3, 0x97, 0xfc, 0xc4, 0x6f, 0x04, 0x3d, 0x83,
+ 0x97, 0x74, 0x07, 0x2f, 0xff, 0xd2, 0x41, 0x0f, 0x73, 0xe5, 0x1c, 0x7c,
+ 0x21, 0x39, 0x79, 0x1b, 0x6b, 0x39, 0x7f, 0xb3, 0x8e, 0xfd, 0xe8, 0x61,
+ 0xca, 0xd1, 0xea, 0xf4, 0x82, 0xa1, 0x38, 0x4c, 0x69, 0x43, 0x89, 0x85,
+ 0xf7, 0x0a, 0xab, 0xf9, 0x18, 0xbc, 0x15, 0x9c, 0xbf, 0xb3, 0x6d, 0x33,
+ 0x50, 0x72, 0xb4, 0x7b, 0x4d, 0x0b, 0x2a, 0x4c, 0x8e, 0xe0, 0xc2, 0x0f,
+ 0x1d, 0x16, 0x42, 0x92, 0xfc, 0xa6, 0x58, 0x63, 0xa3, 0xb8, 0xfe, 0x47,
+ 0xb8, 0xee, 0x3d, 0x0a, 0x8b, 0xfd, 0xbd, 0xe0, 0xfe, 0xd3, 0x0e, 0x5f,
+ 0x0a, 0x70, 0x41, 0xcb, 0xe5, 0x07, 0x36, 0x72, 0xd3, 0x1c, 0xbf, 0xb7,
+ 0x83, 0xfb, 0x4c, 0x39, 0x5c, 0x91, 0x77, 0x86, 0xae, 0x47, 0xf9, 0x16,
+ 0xc4, 0xaf, 0xbc, 0xee, 0x27, 0x2b, 0x89, 0xf5, 0xb6, 0x97, 0x7f, 0xc0,
+ 0xf7, 0xe0, 0x64, 0x67, 0x8e, 0x5f, 0xfe, 0x19, 0xf9, 0x4c, 0x83, 0x81,
+ 0xc1, 0x54, 0xe5, 0xfc, 0x9f, 0x70, 0x76, 0x3c, 0x72, 0xf2, 0x99, 0x07,
+ 0x2f, 0xfb, 0xb8, 0x1d, 0x3a, 0xfd, 0xf9, 0xca, 0x84, 0x69, 0xb5, 0xa6,
+ 0x39, 0x8e, 0xc7, 0x2f, 0xff, 0xf6, 0x0b, 0xfb, 0x79, 0xaf, 0xff, 0x8c,
+ 0xfb, 0xdb, 0x43, 0x97, 0x63, 0x43, 0x96, 0x70, 0x9f, 0xcf, 0x98, 0x6f,
+ 0x46, 0xa6, 0x39, 0x5c, 0x9d, 0x04, 0x04, 0x4e, 0xde, 0xcf, 0x18, 0x70,
+ 0x61, 0x5f, 0x93, 0x81, 0xab, 0x8d, 0xe7, 0xe5, 0x24, 0x9c, 0xba, 0xec,
+ 0x66, 0x0f, 0x49, 0x3f, 0xfe, 0x3d, 0x81, 0x25, 0x04, 0x61, 0xad, 0xc2,
+ 0xdd, 0xa1, 0x3d, 0xef, 0xa7, 0xe2, 0x72, 0xfc, 0xbe, 0xc7, 0xdc, 0x07,
+ 0x2f, 0xdd, 0x7d, 0x31, 0x0e, 0x5f, 0xca, 0x2f, 0xb1, 0xf7, 0x01, 0xca,
+ 0xe4, 0x88, 0x65, 0x96, 0x00, 0x9e, 0xf7, 0x2f, 0xdb, 0x39, 0x5f, 0x1e,
+ 0x9f, 0x8c, 0xaf, 0xec, 0x6f, 0x30, 0x55, 0x39, 0x7c, 0xc7, 0xcd, 0x9c,
+ 0xa4, 0x3c, 0xe7, 0x2d, 0xbf, 0xfe, 0x5c, 0x6f, 0x70, 0xcc, 0xf2, 0x6f,
+ 0xae, 0x72, 0xff, 0x08, 0xc4, 0x99, 0x08, 0x72, 0xff, 0x79, 0x38, 0xa7,
+ 0xa5, 0x05, 0x2c, 0xc3, 0x97, 0xf6, 0x0a, 0xba, 0x8e, 0x68, 0x78, 0xaa,
+ 0x1a, 0x56, 0x26, 0x12, 0x89, 0xdb, 0x75, 0xbc, 0x0f, 0xa4, 0x72, 0xfa,
+ 0x5a, 0x7e, 0x27, 0x2b, 0x47, 0x84, 0x23, 0xd7, 0xf8, 0x64, 0x38, 0xc8,
+ 0x59, 0xcb, 0xcf, 0xb4, 0x39, 0x6c, 0x39, 0x7b, 0x31, 0x53, 0x96, 0x60,
+ 0x4d, 0x67, 0x00, 0x85, 0x42, 0x30, 0xf0, 0x87, 0xa6, 0x2e, 0x8f, 0x7f,
+ 0xc9, 0xc7, 0x34, 0xb7, 0x75, 0x9a, 0x30, 0xd5, 0xe6, 0x80, 0xf1, 0xcb,
+ 0x93, 0x89, 0xcb, 0xe7, 0xd3, 0xa8, 0x72, 0xff, 0xf7, 0xa1, 0x88, 0x1c,
+ 0x15, 0x7b, 0x0c, 0x39, 0x41, 0x47, 0x42, 0xd1, 0x98, 0x3f, 0xb1, 0x8f,
+ 0x11, 0x5e, 0x55, 0x4e, 0x9c, 0xbf, 0xfe, 0x4f, 0x76, 0x37, 0x1d, 0x84,
+ 0x9e, 0x15, 0x39, 0x7f, 0xbb, 0x13, 0x49, 0x35, 0x23, 0x97, 0xfb, 0xc8,
+ 0xdc, 0xc2, 0xed, 0x9c, 0xbf, 0x7b, 0xdb, 0x7f, 0xce, 0x5f, 0xa1, 0x9e,
+ 0xc5, 0x9c, 0xb9, 0x27, 0x39, 0x50, 0x98, 0xf8, 0x53, 0xfe, 0x34, 0x43,
+ 0x5e, 0x94, 0xf8, 0x9e, 0xfc, 0xda, 0x07, 0x81, 0x0e, 0x5f, 0xf7, 0x62,
+ 0x48, 0x38, 0xc8, 0x39, 0x7f, 0xd9, 0xee, 0xe3, 0x05, 0xfc, 0x72, 0xfe,
+ 0xe2, 0x9a, 0xfa, 0x1a, 0xce, 0x58, 0x42, 0x7d, 0x58, 0x6f, 0x7e, 0x64,
+ 0x2e, 0x70, 0x9c, 0xbe, 0x94, 0x31, 0xce, 0x5f, 0xb5, 0xfb, 0x13, 0x67,
+ 0x2e, 0xf6, 0xf0, 0xfc, 0xdc, 0xa5, 0x42, 0x1a, 0x84, 0x69, 0x82, 0x13,
+ 0x36, 0xd9, 0xcb, 0xfa, 0x27, 0xc1, 0x45, 0x4e, 0x56, 0x8d, 0xf6, 0xc4,
+ 0x6f, 0xfe, 0x81, 0x7e, 0xc7, 0xfc, 0xf5, 0xbd, 0x94, 0xa9, 0xd5, 0x1f,
+ 0x86, 0x37, 0x3c, 0x65, 0x61, 0x0d, 0xf9, 0xe6, 0x4c, 0xd9, 0xcb, 0xed,
+ 0xc6, 0xa4, 0x72, 0xe7, 0x0f, 0x23, 0xc9, 0xd9, 0x3d, 0xc0, 0x9c, 0xe5,
+ 0xfe, 0xfa, 0x5f, 0x6d, 0x3d, 0x07, 0x2f, 0x27, 0xdb, 0x39, 0x58, 0x7a,
+ 0x48, 0x6b, 0x48, 0x88, 0xae, 0xb5, 0x5d, 0x8b, 0x39, 0x7b, 0x59, 0xb3,
+ 0x9e, 0x2d, 0xaf, 0xff, 0x83, 0xc9, 0xd3, 0x37, 0x13, 0xe0, 0xa2, 0xa7,
+ 0x2f, 0xf6, 0x99, 0x1f, 0x79, 0xd6, 0x72, 0xff, 0xfe, 0x1c, 0xf7, 0x72,
+ 0x58, 0xb8, 0x5f, 0x85, 0xd8, 0x72, 0xb1, 0x1b, 0x88, 0xa1, 0xb3, 0x4b,
+ 0xe4, 0x64, 0x4c, 0x72, 0xff, 0xed, 0xa7, 0xc3, 0x93, 0x6a, 0x3d, 0xb3,
+ 0x97, 0xd9, 0x38, 0x24, 0x72, 0xa6, 0x44, 0x57, 0xe4, 0x4d, 0xa2, 0xdf,
+ 0xed, 0xc4, 0x9e, 0x77, 0x61, 0xcb, 0xfb, 0xf9, 0xde, 0x50, 0xd6, 0x72,
+ 0xf0, 0x43, 0x07, 0x2b, 0xe3, 0xce, 0x01, 0x95, 0x42, 0x35, 0xd0, 0xcd,
+ 0xe1, 0x03, 0x76, 0x36, 0x72, 0x8b, 0x88, 0x61, 0x7f, 0x6d, 0x48, 0xd4,
+ 0x30, 0xb8, 0x86, 0x14, 0x5c, 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x17, 0x10,
+ 0xc2, 0x8b, 0x88, 0x61, 0x52, 0x45, 0xca, 0x0c, 0xfe, 0x78, 0x01, 0x96,
+ 0x83, 0x3c, 0x03, 0x37, 0x77, 0x0b, 0x88, 0x61, 0x7f, 0x3b, 0xfa, 0x68,
+ 0x61, 0x71, 0x0c, 0x39, 0x1a, 0x4b, 0x70, 0xe5, 0xc4, 0x30, 0xa2, 0xe2,
+ 0x18, 0x51, 0x71, 0x0c, 0x2a, 0x46, 0xc9, 0x06, 0x68, 0xb8, 0x86, 0x14,
+ 0x5c, 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x17, 0x10, 0xc2, 0x8b, 0x88, 0x61,
+ 0x45, 0xc4, 0x30, 0xa9, 0xd1, 0x2c, 0x11, 0x94, 0x19, 0xfc, 0x67, 0x63,
+ 0x3c, 0x46, 0x68, 0xb8, 0x86, 0x14, 0x5c, 0x43, 0x0a, 0x91, 0xb2, 0xd8,
+ 0xcd, 0x17, 0x10, 0xc2, 0x8b, 0x88, 0x61, 0x45, 0xc4, 0x30, 0xa2, 0xe2,
+ 0x18, 0x54, 0x8f, 0x93, 0xf1, 0x9f, 0x0c, 0xf0, 0x0c, 0xd1, 0x71, 0x0c,
+ 0x28, 0xb8, 0x86, 0x14, 0x5c, 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x4e, 0x7c,
+ 0x8a, 0x8c, 0xe8, 0x67, 0xa3, 0x36, 0x54, 0xb8, 0x86, 0x14, 0x5c, 0x43,
+ 0x0a, 0x2e, 0x21, 0x85, 0x17, 0x10, 0xc2, 0x8b, 0x88, 0x61, 0x41, 0x3e,
+ 0x4f, 0x86, 0x7f, 0x19, 0x00, 0xcd, 0x17, 0x10, 0xc2, 0x8b, 0x88, 0x61,
+ 0x45, 0xc4, 0x30, 0xbf, 0x76, 0x3f, 0xde, 0x17, 0x10, 0xc2, 0x8b, 0x88,
+ 0x61, 0x52, 0x44, 0xd2, 0xc6, 0x7a, 0x32, 0xe3, 0x3f, 0x9b, 0x59, 0x65,
+ 0xc4, 0x30, 0xa2, 0xe2, 0x18, 0x51, 0x71, 0x0c, 0x28, 0xb8, 0x86, 0x14,
+ 0x5c, 0x43, 0x0a, 0x91, 0xf2, 0x7c, 0x32, 0x83, 0x3c, 0x46, 0x68, 0xb8,
+ 0x86, 0x14, 0x5c, 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x17, 0x10, 0xc2, 0xa4,
+ 0x7c, 0x81, 0x19, 0xe8, 0xc8, 0x8c, 0xdb, 0xa5, 0xc4, 0x30, 0xa2, 0xe2,
+ 0x18, 0x51, 0x71, 0x0c, 0x2d, 0x22, 0xe2, 0x18, 0x51, 0x71, 0x0c, 0x3e,
+ 0x2f, 0xe8, 0xb8, 0x86, 0x14, 0x5c, 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x17,
+ 0x10, 0xc2, 0xa7, 0x46, 0xf4, 0x86, 0x55, 0x38, 0x59, 0x4c, 0xc3, 0x3f,
+ 0x8c, 0xf8, 0x66, 0xd8, 0x5c, 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x17, 0x10,
+ 0xc2, 0xd2, 0x2e, 0x21, 0x85, 0x17, 0x10, 0xc3, 0xe2, 0xfe, 0x8b, 0x88,
+ 0x61, 0x45, 0xc4, 0x30, 0xa8, 0x45, 0x64, 0x86, 0x50, 0xe3, 0x45, 0x2c,
+ 0x19, 0xa2, 0xe2, 0x18, 0x51, 0x71, 0x0c, 0x28, 0xb8, 0x86, 0x14, 0x5c,
+ 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x41, 0xfe, 0xfc, 0x33, 0xa1, 0x96, 0x0c,
+ 0x88, 0xcd, 0x17, 0x10, 0xc2, 0x8b, 0x88, 0x61, 0x45, 0xc4, 0x30, 0xad,
+ 0x1e, 0x5e, 0xc6, 0x7c, 0x33, 0x45, 0xc4, 0x30, 0xa2, 0xe2, 0x18, 0x51,
+ 0x71, 0x0c, 0x29, 0x87, 0x96, 0x23, 0x3e, 0x19, 0xb3, 0x0b, 0x88, 0x61,
+ 0x45, 0xc4, 0x30, 0xa2, 0xe2, 0x18, 0x57, 0xe6, 0xc8, 0x03, 0x34, 0x5c,
+ 0x43, 0x0a, 0x2e, 0x21, 0x85, 0x17, 0x10, 0xc2, 0x8b, 0x88, 0x61, 0x50,
+ 0x7c, 0x93, 0x0c, 0xf4, 0x64, 0x03, 0x35, 0x0c, 0xc1, 0x49, 0xe1, 0x01,
+ 0x24, 0xd0, 0xab, 0x64, 0x2d, 0x97, 0x08, 0xcf, 0xa1, 0x0a, 0x90, 0xa4,
+ 0x6b, 0x3e, 0x9a, 0x10, 0x9a, 0x86, 0xc3, 0x12, 0xbb, 0x08, 0x37, 0x85,
+ 0x17, 0xe7, 0x63, 0x0f, 0xdd, 0xb4, 0x7a, 0x19, 0x40, 0x86, 0x2f, 0x18,
+ 0x49, 0xb6, 0xf4, 0xd0, 0xb9, 0x45, 0x1e, 0x08, 0x43, 0x5f, 0xa4, 0x31,
+ 0x9b, 0x2e, 0x21, 0x87, 0x34, 0xe5, 0xaf, 0x24, 0x30, 0xb8, 0x86, 0x17,
+ 0xc8, 0xb7, 0xd1, 0xf1, 0x0c, 0x5e, 0x40, 0xe1, 0xf1, 0x0c, 0x5b, 0x9f,
+ 0xc8, 0xc8, 0xd2, 0x4f, 0x4a, 0x7c, 0x5d, 0x68, 0xe2, 0xcf, 0x88, 0x52,
+ 0x9e, 0x85, 0x7f, 0xba, 0x8d, 0x87, 0x51, 0x39, 0xcb, 0xc9, 0xc7, 0x87,
+ 0x39, 0x5f, 0x22, 0x42, 0x63, 0x8f, 0x1a, 0xdf, 0xb3, 0x26, 0x75, 0x0e,
+ 0x5f, 0xe7, 0x15, 0x26, 0x92, 0x09, 0xcb, 0xbf, 0x83, 0x97, 0xf6, 0x9c,
+ 0x54, 0x8f, 0xce, 0x5c, 0xfa, 0x39, 0x64, 0x38, 0xb2, 0xda, 0xcb, 0x39,
+ 0x66, 0x1c, 0xb7, 0x34, 0x44, 0xe6, 0x85, 0xfa, 0x88, 0xe3, 0xea, 0x08,
+ 0xd3, 0x13, 0x20, 0x69, 0x0c, 0xfb, 0xfe, 0xec, 0x33, 0x26, 0x81, 0x9c,
+ 0xe5, 0xff, 0xdc, 0x9d, 0x61, 0xec, 0x7f, 0x83, 0xf9, 0xcb, 0xbf, 0x83,
+ 0x95, 0x87, 0xbd, 0xfa, 0x3d, 0x62, 0x39, 0x3f, 0x2b, 0x04, 0x25, 0xef,
+ 0xfe, 0x11, 0x89, 0xc7, 0x13, 0x8c, 0x34, 0x39, 0x7a, 0x3e, 0xd9, 0xca,
+ 0x73, 0xe2, 0xda, 0x2d, 0xe7, 0xd4, 0x1c, 0xbf, 0x23, 0x47, 0x1f, 0xce,
+ 0x5f, 0x93, 0xed, 0xbf, 0xc7, 0x2a, 0x47, 0xda, 0xc1, 0xbd, 0x94, 0xdf,
+ 0xf2, 0x8e, 0x1d, 0xe3, 0x21, 0xac, 0xe5, 0xec, 0xf9, 0xb3, 0x97, 0xbe,
+ 0xff, 0x34, 0x7b, 0x42, 0x79, 0x7d, 0xc7, 0x35, 0x23, 0x97, 0x82, 0xe2,
+ 0x72, 0x90, 0xdf, 0xb9, 0x25, 0xff, 0xcf, 0xad, 0x3f, 0xf1, 0xcd, 0xb6,
+ 0xdb, 0x39, 0x7f, 0xe5, 0x73, 0xef, 0x27, 0xb4, 0x06, 0x1c, 0xb4, 0x72,
+ 0x44, 0x5f, 0x92, 0xaa, 0x13, 0xd0, 0x78, 0x44, 0xed, 0xcc, 0x10, 0xaa,
+ 0xbf, 0xf8, 0x0a, 0x4d, 0xca, 0x14, 0x75, 0xc7, 0x4e, 0x57, 0x08, 0xe8,
+ 0xdd, 0x22, 0x1f, 0x53, 0xb8, 0xca, 0x32, 0x90, 0xc6, 0x69, 0x91, 0x91,
+ 0x2a, 0x94, 0xb8, 0xcf, 0xbe, 0x57, 0x49, 0x4d, 0x4d, 0x70, 0x8e, 0x9a,
+ 0x17, 0x3a, 0x38, 0x64, 0x60, 0xfd, 0x8e, 0x3d, 0xeb, 0x04, 0xaf, 0xcc,
+ 0x86, 0x51, 0x66, 0xe1, 0x2f, 0xe9, 0x4b, 0xca, 0x23, 0x5e, 0x66, 0xd6,
+ 0x72, 0xf0, 0xae, 0x0e, 0x57, 0x23, 0x70, 0x83, 0xb7, 0xf3, 0x6f, 0xad,
+ 0x3f, 0xc7, 0x2f, 0xff, 0xdb, 0xd6, 0x92, 0x6d, 0xea, 0x3c, 0x8b, 0x40,
+ 0x9c, 0xa6, 0x22, 0x9c, 0x48, 0x9b, 0x2f, 0xbe, 0x67, 0xa3, 0x67, 0x2f,
+ 0xdf, 0xa4, 0xe8, 0x13, 0x97, 0xda, 0x41, 0x54, 0xe5, 0xfe, 0xf4, 0x01,
+ 0x7d, 0x4d, 0x1c, 0xbf, 0xb1, 0x7d, 0x8f, 0xa4, 0x72, 0xfe, 0x66, 0xd1,
+ 0x5f, 0x36, 0x72, 0xfd, 0x1f, 0x76, 0x24, 0x72, 0xb4, 0x8d, 0xb1, 0x22,
+ 0xf1, 0x9a, 0x85, 0xdc, 0x06, 0x17, 0xfd, 0x9f, 0x0e, 0x7b, 0xd9, 0x39,
+ 0xcb, 0xbe, 0xf1, 0xcb, 0xf6, 0x0c, 0xe9, 0xa3, 0x97, 0xef, 0x38, 0x83,
+ 0x0e, 0x5f, 0xed, 0xe3, 0x13, 0xdd, 0x73, 0x96, 0x8c, 0x44, 0xbe, 0x86,
+ 0x04, 0x9f, 0xc4, 0xd7, 0xb9, 0x31, 0x0e, 0x5c, 0x2c, 0x39, 0x52, 0x36,
+ 0x9b, 0x1e, 0xbd, 0xc1, 0xa8, 0x39, 0x7f, 0xdd, 0x4d, 0x75, 0xf8, 0x46,
+ 0xdb, 0x39, 0x7f, 0xb4, 0x93, 0x0e, 0x71, 0x73, 0x96, 0xdf, 0x24, 0x5a,
+ 0x41, 0x0e, 0x0f, 0xe9, 0x02, 0xf9, 0xc4, 0x18, 0x72, 0xbe, 0x3e, 0x3f,
+ 0xd0, 0xef, 0xf8, 0x61, 0xe7, 0xec, 0x6b, 0xf3, 0x97, 0xf9, 0x34, 0x3e,
+ 0xf6, 0x4e, 0x72, 0xe7, 0xe2, 0x72, 0xfe, 0x90, 0xa4, 0xbb, 0x87, 0x2f,
+ 0xd3, 0xa6, 0xa2, 0x47, 0x29, 0x54, 0x4f, 0xcc, 0x67, 0xa1, 0x81, 0x2c,
+ 0xbf, 0x03, 0xcd, 0x33, 0xc7, 0x2f, 0x05, 0x15, 0x39, 0x50, 0x78, 0xf8,
+ 0x55, 0x7b, 0x5f, 0xa8, 0x72, 0xff, 0xe4, 0xf4, 0x7b, 0x7d, 0x74, 0xe8,
+ 0x0e, 0x54, 0x1f, 0x13, 0x8f, 0xdf, 0x08, 0x82, 0x47, 0x2f, 0xfd, 0xd8,
+ 0xd7, 0xe3, 0x8d, 0xbf, 0xe7, 0x2f, 0x66, 0x4c, 0x72, 0xd9, 0xd3, 0xdc,
+ 0xfd, 0x02, 0xf4, 0x7c, 0xd9, 0xcb, 0xf6, 0x80, 0xc7, 0x13, 0x95, 0xe3,
+ 0xc5, 0x00, 0xf5, 0xf3, 0x23, 0x27, 0x39, 0x7e, 0xce, 0x23, 0x1f, 0x1c,
+ 0xa4, 0x3c, 0xbd, 0x91, 0x5f, 0x40, 0xf9, 0x67, 0x28, 0x2a, 0xe6, 0x32,
+ 0x1b, 0x1a, 0x84, 0x2f, 0x61, 0x04, 0xe4, 0x02, 0xfb, 0xb6, 0xdf, 0x36,
+ 0xb4, 0x21, 0xbf, 0xdf, 0xa9, 0x82, 0x1e, 0xc1, 0xca, 0x84, 0x61, 0x3c,
+ 0x23, 0xaf, 0xed, 0xe3, 0x13, 0xb0, 0x72, 0xf7, 0xd2, 0xd9, 0xca, 0xf8,
+ 0xf2, 0xb4, 0x59, 0x7b, 0x7f, 0xb6, 0x72, 0xff, 0xa4, 0xc7, 0x97, 0xb7,
+ 0x0a, 0x9c, 0xa8, 0x3f, 0xcc, 0x23, 0x71, 0xfb, 0xff, 0x23, 0x63, 0x9a,
+ 0xdf, 0x71, 0x67, 0x2f, 0x80, 0xfa, 0x91, 0xcb, 0xe8, 0x07, 0x0f, 0xb2,
+ 0x97, 0xe9, 0x73, 0x6d, 0xb6, 0xce, 0x50, 0x9e, 0xa8, 0x09, 0xef, 0x9f,
+ 0xcc, 0xf1, 0xca, 0x0a, 0x2e, 0xb1, 0xdf, 0xf2, 0x1b, 0xfd, 0xf8, 0xe7,
+ 0x1d, 0x26, 0xce, 0x5f, 0xe5, 0x04, 0x5d, 0xb7, 0xe9, 0xca, 0x86, 0x59,
+ 0x26, 0x18, 0x7c, 0x44, 0x91, 0x82, 0x69, 0x35, 0x90, 0xd0, 0x78, 0xe2,
+ 0xff, 0x9c, 0x7e, 0x18, 0x76, 0x6c, 0xb0, 0x10, 0xf8, 0xe2, 0x60, 0xd9,
+ 0xad, 0xe6, 0xa9, 0xa8, 0xf0, 0x87, 0x2f, 0x48, 0x5c, 0xe5, 0xbe, 0x6a,
+ 0x8f, 0x22, 0x0b, 0x6f, 0xdc, 0x11, 0x2d, 0x41, 0xcb, 0xde, 0x7f, 0xce,
+ 0x5f, 0xd1, 0xa9, 0xe3, 0x53, 0x9c, 0xbf, 0xf4, 0x0f, 0xba, 0x07, 0x94,
+ 0xa0, 0xe5, 0xf8, 0x1f, 0xe0, 0xac, 0xe5, 0xed, 0x44, 0xc7, 0x2f, 0x90,
+ 0x5e, 0x63, 0x97, 0xfe, 0x18, 0x57, 0xaf, 0xe5, 0x33, 0xf3, 0x97, 0xb7,
+ 0xac, 0x39, 0x7f, 0x66, 0xbf, 0x10, 0x7e, 0x72, 0x90, 0xf2, 0xf6, 0x39,
+ 0x66, 0xb3, 0x97, 0xf6, 0x29, 0x13, 0x26, 0xce, 0x50, 0x9e, 0x17, 0x85,
+ 0x2a, 0x15, 0x14, 0x4e, 0x55, 0x21, 0xd0, 0x97, 0xe8, 0xf5, 0x85, 0x1d,
+ 0x1d, 0x12, 0x1f, 0x42, 0x2f, 0x8b, 0x1d, 0xff, 0x42, 0x76, 0x19, 0x3e,
+ 0x36, 0x72, 0xfd, 0xd4, 0x9d, 0xc4, 0xe5, 0xf8, 0x0a, 0xb8, 0xfe, 0x72,
+ 0xfe, 0xde, 0xa3, 0x02, 0x87, 0x2a, 0x0f, 0xf3, 0xa4, 0xfc, 0x4a, 0x6f,
+ 0xfa, 0x71, 0xc9, 0x77, 0x3f, 0xd9, 0xcb, 0xff, 0x60, 0xfd, 0x2d, 0xe8,
+ 0x11, 0xf9, 0xcb, 0xf6, 0x7b, 0x78, 0xa9, 0xca, 0x43, 0xe8, 0x62, 0x05,
+ 0xff, 0xb5, 0xd6, 0xdc, 0x3c, 0x7d, 0x8b, 0x39, 0x7e, 0xf7, 0x2e, 0xe7,
+ 0x01, 0xca, 0x73, 0xef, 0x14, 0x2b, 0xc1, 0x8e, 0x27, 0x2f, 0xff, 0x08,
+ 0xc3, 0x61, 0x18, 0xfa, 0x48, 0x27, 0x2f, 0xcc, 0xce, 0xbf, 0x01, 0xca,
+ 0xc3, 0xf2, 0x44, 0x8b, 0xff, 0xcf, 0xca, 0x69, 0x46, 0xa7, 0xe4, 0xde,
+ 0x74, 0xe5, 0x42, 0x64, 0x21, 0x20, 0xec, 0x24, 0x04, 0x82, 0xff, 0x99,
+ 0xdc, 0xf6, 0x03, 0x53, 0x9c, 0xbf, 0xfb, 0xdb, 0x41, 0x9a, 0x17, 0xac,
+ 0xf8, 0xe5, 0xf8, 0x2a, 0xaa, 0x0f, 0x8e, 0x59, 0x57, 0x3f, 0x10, 0x22,
+ 0xdf, 0xf4, 0x7b, 0x34, 0xb7, 0x75, 0x9a, 0x2f, 0x85, 0xfb, 0x35, 0x1f,
+ 0x48, 0xe5, 0xee, 0xc3, 0x16, 0x7d, 0x9e, 0x44, 0xbf, 0xff, 0x0a, 0xf9,
+ 0x76, 0x13, 0x48, 0xc4, 0x69, 0x0c, 0x39, 0x79, 0xf5, 0x39, 0xa2, 0xff,
+ 0x54, 0x22, 0xd3, 0x0c, 0xd6, 0xaf, 0x7f, 0xcf, 0xed, 0xa0, 0xfd, 0x26,
+ 0x1c, 0xbf, 0xe8, 0xcd, 0x72, 0x92, 0x7d, 0x23, 0x95, 0xf9, 0xfa, 0x78,
+ 0xe6, 0xff, 0xff, 0x75, 0xf6, 0x91, 0xbe, 0x5e, 0xee, 0x33, 0x16, 0xfa,
+ 0x39, 0x74, 0x70, 0x1c, 0xbe, 0xde, 0xdd, 0x87, 0x2b, 0xa8, 0x9c, 0xfd,
+ 0x87, 0xc3, 0x37, 0xfe, 0x9f, 0x3e, 0xf2, 0x9d, 0xee, 0x35, 0x9c, 0xbe,
+ 0xfa, 0x5e, 0x73, 0x97, 0xff, 0xc1, 0x5f, 0x50, 0x73, 0x8b, 0xcb, 0x68,
+ 0x13, 0x95, 0x87, 0xe6, 0xe4, 0x77, 0xef, 0xf7, 0xec, 0xe9, 0xcb, 0xf9,
+ 0xbf, 0x67, 0x65, 0x87, 0x2a, 0x0f, 0x5d, 0xca, 0x6a, 0x13, 0x4f, 0x94,
+ 0x2e, 0x05, 0xde, 0xff, 0xa1, 0x9c, 0x83, 0x99, 0xfe, 0xce, 0x5f, 0x23,
+ 0x35, 0x39, 0xcb, 0xff, 0x7a, 0x37, 0xb8, 0x49, 0xdf, 0xc7, 0x2f, 0xf9,
+ 0x30, 0x42, 0xaa, 0x66, 0x8e, 0x52, 0x23, 0x4f, 0x47, 0x7e, 0x23, 0xe0,
+ 0x3e, 0xbd, 0xec, 0xf8, 0xe5, 0xfc, 0xfa, 0xfa, 0x59, 0xe3, 0x97, 0xfe,
+ 0xf6, 0xd3, 0x5e, 0x10, 0x3c, 0x8e, 0x5f, 0xff, 0x93, 0x78, 0x1e, 0xe7,
+ 0x93, 0x37, 0x3e, 0x36, 0x72, 0xff, 0xf3, 0x21, 0xa6, 0x00, 0x73, 0x38,
+ 0xc7, 0xc7, 0x2f, 0xfd, 0x19, 0xac, 0xd7, 0xec, 0x4d, 0x9c, 0xbc, 0xff,
+ 0x70, 0x1c, 0xbf, 0x9f, 0xdb, 0x8c, 0x9c, 0xe5, 0x42, 0x73, 0x18, 0x5c,
+ 0xb3, 0xe4, 0x55, 0x14, 0xce, 0x27, 0xcd, 0x90, 0x5f, 0xf0, 0x21, 0x9b,
+ 0xc6, 0x43, 0x59, 0xcb, 0xff, 0x6a, 0x7c, 0x0e, 0x77, 0xb8, 0xd6, 0x72,
+ 0xca, 0x9c, 0xbf, 0xde, 0xda, 0x9c, 0x63, 0x3e, 0x39, 0x6c, 0x83, 0xc9,
+ 0x11, 0x2a, 0xc4, 0x58, 0x6e, 0x11, 0x77, 0xf6, 0xde, 0x43, 0x0c, 0x39,
+ 0x7f, 0xfd, 0x28, 0xd4, 0xfe, 0x45, 0x77, 0xb7, 0x19, 0x1c, 0xbf, 0xa7,
+ 0xde, 0x32, 0x1a, 0xce, 0x54, 0xc8, 0x82, 0x51, 0x46, 0xb4, 0x8d, 0x36,
+ 0xe1, 0x5d, 0x79, 0x3a, 0x87, 0x2e, 0x0c, 0x8e, 0x5e, 0x1c, 0x91, 0xcb,
+ 0x4b, 0x46, 0xcb, 0xc2, 0xf7, 0xcc, 0xf2, 0x4e, 0x72, 0xb0, 0xf2, 0x90,
+ 0x9e, 0xff, 0xee, 0x3e, 0x56, 0x06, 0x59, 0xd4, 0x61, 0xcb, 0xa7, 0xf1,
+ 0xcb, 0xfd, 0xc7, 0xaf, 0x28, 0xc1, 0x39, 0x50, 0x79, 0x78, 0x31, 0x7f,
+ 0xfe, 0x97, 0x63, 0x4f, 0xe0, 0x79, 0x3d, 0xbe, 0xa1, 0xcb, 0xfb, 0x1b,
+ 0x53, 0xaf, 0xe3, 0x97, 0xf4, 0x99, 0xe1, 0x04, 0xc7, 0x2f, 0xff, 0x94,
+ 0x94, 0x71, 0x41, 0xff, 0x49, 0x0c, 0xc2, 0x95, 0xa4, 0x40, 0x78, 0xbe,
+ 0xfb, 0xaa, 0x7d, 0xe3, 0x97, 0xec, 0x66, 0x27, 0x13, 0x97, 0xa7, 0x99,
+ 0xac, 0xe5, 0x42, 0x72, 0xd3, 0xaa, 0xe4, 0x2b, 0xd6, 0x46, 0x84, 0xa0,
+ 0x28, 0xbb, 0xd8, 0x72, 0xfd, 0xa4, 0x9d, 0xd8, 0x69, 0x84, 0xd7, 0xde,
+ 0x04, 0x39, 0xa6, 0x13, 0x5d, 0xfc, 0x1a, 0x81, 0x35, 0xfe, 0x17, 0x57,
+ 0xd1, 0xaf, 0xcd, 0x40, 0x9a, 0xff, 0x6f, 0x3a, 0x9b, 0x04, 0xe6, 0x98,
+ 0x4d, 0x76, 0x04, 0xd3, 0x09, 0xae, 0x6d, 0xb3, 0xcc, 0x26, 0xac, 0x4d,
+ 0x4b, 0xe3, 0x54, 0x2e, 0x61, 0x26, 0xd0, 0x78, 0xa0, 0xb6, 0x47, 0x6f,
+ 0x16, 0x61, 0x33, 0x99, 0xf3, 0xd9, 0x3e, 0x54, 0x02, 0xdc, 0x79, 0xf5,
+ 0x0b, 0xb6, 0xa8, 0x53, 0xd8, 0x4b, 0xb9, 0x00, 0xc2, 0x47, 0x71, 0xdb,
+ 0x7a, 0x52, 0xe5, 0xf3, 0xf1, 0xc6, 0xce, 0x5f, 0xff, 0xba, 0xf2, 0xec,
+ 0x42, 0x7b, 0x68, 0x3f, 0x48, 0xe5, 0xe1, 0xfd, 0x87, 0x2f, 0xfa, 0x01,
+ 0xe1, 0x4e, 0x2a, 0x30, 0xe5, 0xd9, 0xbc, 0x3d, 0x8d, 0x0e, 0xd6, 0x91,
+ 0xf8, 0xe4, 0x83, 0x0a, 0xcb, 0xec, 0x4d, 0x2a, 0x72, 0xf0, 0x7f, 0x98,
+ 0xe5, 0x43, 0x68, 0x97, 0x3c, 0x28, 0x83, 0x1d, 0x8e, 0x20, 0xab, 0x0a,
+ 0xb5, 0xc6, 0x91, 0xf4, 0x28, 0x92, 0x17, 0xf3, 0x47, 0x01, 0xa8, 0xc1,
+ 0xd8, 0x7f, 0xd8, 0xed, 0x45, 0x93, 0x70, 0xeb, 0xf4, 0xf5, 0x7f, 0x18,
+ 0xdd, 0x9a, 0x19, 0xa8, 0x45, 0x7e, 0xef, 0xdb, 0x48, 0x39, 0x7d, 0x9a,
+ 0x45, 0x4e, 0x54, 0x1e, 0x50, 0x4a, 0x2f, 0xee, 0xc2, 0x83, 0xf7, 0xe7,
+ 0x2f, 0x35, 0x79, 0xc0, 0x72, 0xf6, 0x63, 0x67, 0x2e, 0x45, 0x4e, 0x54,
+ 0xe6, 0xcd, 0x07, 0x2f, 0xde, 0xc9, 0x91, 0x87, 0x2f, 0xd1, 0xf7, 0xff,
+ 0xc1, 0xca, 0x83, 0xd2, 0x12, 0x8b, 0xf4, 0x71, 0x81, 0xf1, 0xcb, 0xf2,
+ 0x71, 0xf2, 0x4e, 0x72, 0xff, 0xcc, 0x14, 0x56, 0x3d, 0xb4, 0xd1, 0xcb,
+ 0xe9, 0x7b, 0x16, 0x72, 0xb0, 0xf8, 0x1c, 0xfa, 0xfc, 0x38, 0xa6, 0x4c,
+ 0x72, 0xff, 0xf8, 0x56, 0x8c, 0x08, 0x1f, 0x52, 0xcf, 0xbc, 0x72, 0xff,
+ 0xce, 0x3f, 0xfd, 0xed, 0x46, 0x36, 0x72, 0xff, 0xdb, 0xea, 0x72, 0xfa,
+ 0x51, 0x93, 0x9c, 0xb6, 0x35, 0xa2, 0x0b, 0xf4, 0x0b, 0xfe, 0xeb, 0xb3,
+ 0xa9, 0x1f, 0x48, 0xe5, 0xfc, 0xa0, 0xc9, 0xa3, 0xce, 0x72, 0xa1, 0x36,
+ 0x89, 0x43, 0x49, 0x0b, 0x3f, 0x39, 0xa9, 0xd5, 0x62, 0x04, 0x81, 0x65,
+ 0x1a, 0x84, 0x50, 0x90, 0x7a, 0x39, 0x0b, 0xff, 0x63, 0xf6, 0x64, 0x1e,
+ 0xe7, 0xc7, 0x2f, 0xef, 0xe6, 0x94, 0x7b, 0x67, 0x2f, 0xff, 0xff, 0xbb,
+ 0x83, 0xfe, 0x0f, 0xbb, 0x9d, 0x8c, 0x99, 0x35, 0x37, 0x53, 0xef, 0x1c,
+ 0xbf, 0xcc, 0xd2, 0x2f, 0xb9, 0x31, 0xca, 0xc4, 0x59, 0x3b, 0xf5, 0xf0,
+ 0xc6, 0x36, 0x72, 0xfa, 0x3e, 0xdb, 0x9c, 0xa8, 0x6f, 0x45, 0xa7, 0x84,
+ 0x98, 0x61, 0x6b, 0x95, 0xa3, 0xda, 0x47, 0x18, 0xd6, 0x43, 0x31, 0x86,
+ 0x95, 0xde, 0x59, 0xb8, 0xb2, 0x78, 0xf8, 0x10, 0xe2, 0xe2, 0x42, 0xa1,
+ 0x0d, 0xff, 0xf2, 0x0e, 0x32, 0x14, 0x10, 0x48, 0x71, 0x87, 0x2f, 0xf8,
+ 0x29, 0x82, 0x09, 0x66, 0xce, 0x5f, 0xf6, 0xb5, 0x0b, 0xef, 0xce, 0xd6,
+ 0x72, 0xc0, 0x39, 0x7f, 0x2c, 0x0e, 0x16, 0x41, 0xcb, 0xfe, 0xea, 0x4b,
+ 0xaf, 0x24, 0x61, 0xcb, 0xff, 0x6d, 0x07, 0xe9, 0x79, 0x36, 0x87, 0x2b,
+ 0x0f, 0xdb, 0xc7, 0x17, 0xed, 0xb2, 0x03, 0x07, 0x2a, 0x49, 0xde, 0xe2,
+ 0x6a, 0x1b, 0xcc, 0x7b, 0xa1, 0x16, 0x42, 0x8f, 0xc4, 0x37, 0xc3, 0x1a,
+ 0x91, 0xcb, 0xfe, 0xec, 0x49, 0x04, 0x41, 0xf1, 0xcb, 0xfe, 0x89, 0x27,
+ 0xa5, 0x03, 0xf9, 0xcb, 0xfe, 0x8c, 0xf2, 0x9f, 0xff, 0x1f, 0x1c, 0xb6,
+ 0xa1, 0x19, 0xb8, 0x43, 0xa3, 0x86, 0x1c, 0x5f, 0xc3, 0x0b, 0xd4, 0x48,
+ 0xe5, 0xff, 0xf7, 0x5d, 0x3d, 0x20, 0x0f, 0xb7, 0xd7, 0x91, 0xc5, 0x0d,
+ 0x65, 0xff, 0xb6, 0xa7, 0x90, 0x41, 0x2c, 0xd9, 0xcb, 0x83, 0xb3, 0x94,
+ 0xd6, 0x8b, 0x6e, 0xb0, 0x09, 0xfd, 0xff, 0xfd, 0x9f, 0x66, 0xdc, 0x7a,
+ 0x91, 0xee, 0x81, 0xd8, 0x72, 0xa1, 0x3a, 0xe7, 0x8c, 0x8c, 0x4c, 0xaf,
+ 0xc0, 0x62, 0x76, 0x0e, 0x5f, 0xb3, 0x4b, 0x8c, 0x39, 0x42, 0x79, 0xaa,
+ 0x13, 0xdf, 0xf6, 0x33, 0x34, 0x93, 0xbb, 0x0e, 0x5f, 0xfc, 0xec, 0x18,
+ 0xf9, 0xa2, 0xbe, 0xce, 0x9c, 0xbf, 0xff, 0x38, 0xf9, 0xdf, 0xa3, 0x1e,
+ 0xdb, 0x79, 0xd3, 0x97, 0xff, 0x33, 0x6f, 0x2d, 0x46, 0xe0, 0x67, 0x39,
+ 0x7f, 0xd1, 0xee, 0xe3, 0x33, 0x58, 0x72, 0xfd, 0xee, 0xa4, 0x6c, 0xe5,
+ 0xe9, 0xdc, 0x74, 0x7b, 0xdb, 0x37, 0xbf, 0xe8, 0xff, 0x61, 0x03, 0xea,
+ 0x47, 0x2f, 0x6b, 0x7b, 0x3c, 0x40, 0x6b, 0xe5, 0xbb, 0xac, 0xd1, 0x01,
+ 0xb9, 0x9a, 0xab, 0x64, 0x91, 0x49, 0xa6, 0x4b, 0xfe, 0x8e, 0xad, 0x36,
+ 0xe9, 0x39, 0xcb, 0xed, 0x47, 0x63, 0x91, 0xf0, 0x68, 0xa2, 0xb1, 0x50,
+ 0x9b, 0xc2, 0x89, 0x48, 0xcd, 0xe8, 0x2a, 0xc8, 0x7a, 0x71, 0xfa, 0x3f,
+ 0xa5, 0x33, 0x5e, 0xe3, 0x1d, 0x39, 0x58, 0xae, 0xa1, 0x25, 0xa1, 0xa8,
+ 0x8f, 0x73, 0xfc, 0x72, 0xf7, 0x5d, 0xac, 0xe5, 0xf4, 0x7e, 0xd3, 0x0e,
+ 0x5f, 0x31, 0x8f, 0xe3, 0x94, 0xc3, 0xfc, 0xfc, 0x5f, 0xc3, 0xea, 0x12,
+ 0x5f, 0x0f, 0xbf, 0x01, 0xcb, 0xf3, 0x1a, 0xa6, 0xa9, 0xaa, 0x6a, 0x4e,
+ 0x5f, 0xff, 0xd2, 0xcd, 0xa6, 0xb4, 0x8c, 0x53, 0xdd, 0xc6, 0xfc, 0x72,
+ 0xb1, 0x17, 0xa8, 0x46, 0xe7, 0xb7, 0xff, 0x9b, 0xc1, 0xf6, 0x0c, 0xb3,
+ 0x6a, 0x30, 0xe5, 0xff, 0xe9, 0x67, 0xd2, 0x52, 0x3f, 0xe6, 0xdb, 0x6d,
+ 0x94, 0xbf, 0x31, 0xbc, 0x4e, 0x27, 0x2f, 0x4b, 0x06, 0x63, 0xfd, 0x51,
+ 0x4e, 0xa1, 0x1f, 0x6f, 0x0c, 0x7b, 0xff, 0xf3, 0xea, 0x41, 0xec, 0x6c,
+ 0x71, 0xb7, 0xd2, 0xa7, 0x2a, 0x15, 0x4f, 0xf6, 0x1f, 0x63, 0x19, 0x40,
+ 0x09, 0xaf, 0xf9, 0x06, 0x5b, 0x6a, 0x0d, 0x4b, 0x54, 0xd4, 0x9c, 0xbe,
+ 0x9b, 0x79, 0x31, 0xcb, 0xf7, 0xf1, 0xec, 0x6b, 0x39, 0x7f, 0xa3, 0x34,
+ 0xb7, 0x75, 0x9a, 0x20, 0x95, 0xff, 0x47, 0xb3, 0x4b, 0x77, 0x59, 0xa2,
+ 0xf9, 0x5f, 0x9c, 0x3d, 0x85, 0x4e, 0x5e, 0x1c, 0xd8, 0x51, 0x54, 0xb3,
+ 0xe6, 0x22, 0x50, 0xa6, 0x2b, 0xc6, 0x1a, 0xb7, 0xff, 0x47, 0x51, 0x5c,
+ 0xd4, 0xec, 0x07, 0xc7, 0x2f, 0xf8, 0x3a, 0xc6, 0x64, 0x9c, 0x27, 0x2b,
+ 0x13, 0xe2, 0x48, 0xce, 0x7a, 0x54, 0xe8, 0xf7, 0xe9, 0x67, 0xea, 0x78,
+ 0xe5, 0xfd, 0xd6, 0x9d, 0x45, 0xf4, 0xe5, 0x39, 0xed, 0x00, 0xaa, 0xff,
+ 0xde, 0x86, 0x6e, 0x12, 0x77, 0xf1, 0xcb, 0xff, 0x4e, 0xff, 0x34, 0xcf,
+ 0x0b, 0xf1, 0x39, 0x7f, 0xfd, 0x9e, 0x81, 0xf6, 0xf3, 0x15, 0x55, 0xe4,
+ 0x72, 0xfe, 0x57, 0x3d, 0xec, 0x09, 0xcb, 0xff, 0x60, 0x62, 0x51, 0xdc,
+ 0xfd, 0xce, 0x5f, 0xcf, 0x20, 0x49, 0xc2, 0x72, 0xfe, 0xea, 0x4f, 0xbd,
+ 0xb9, 0xcb, 0xcd, 0xb6, 0xd9, 0x4b, 0xf7, 0x71, 0x6f, 0xa2, 0x9c, 0xcd,
+ 0x05, 0xff, 0xfe, 0x9b, 0x51, 0xc7, 0x92, 0xaf, 0xc9, 0x49, 0xb7, 0xcb,
+ 0x3e, 0xf1, 0xca, 0x84, 0x7b, 0x79, 0x39, 0x43, 0x9b, 0xff, 0xc9, 0xa4,
+ 0xf0, 0x33, 0xce, 0xcc, 0x13, 0x95, 0x3a, 0xa9, 0x75, 0xa1, 0xe9, 0x3d,
+ 0x85, 0xdf, 0x9e, 0x8c, 0x64, 0x7e, 0x30, 0xbf, 0xf3, 0x23, 0xed, 0x8e,
+ 0x4e, 0xa4, 0x8e, 0x5f, 0xff, 0xe4, 0xeb, 0x8f, 0xd2, 0x52, 0x50, 0x32,
+ 0x76, 0x60, 0x4e, 0x5f, 0xfe, 0xcc, 0xe8, 0x7b, 0x1b, 0xce, 0xa7, 0xe7,
+ 0x2f, 0xd3, 0x4a, 0x35, 0xb3, 0x97, 0xfb, 0x04, 0x12, 0xdc, 0xee, 0x72,
+ 0xca, 0xf2, 0x3d, 0xc0, 0x94, 0xd4, 0xe9, 0xb8, 0xc9, 0x04, 0x2c, 0x09,
+ 0x0a, 0x5b, 0xee, 0x49, 0xd0, 0x1c, 0xbf, 0x64, 0xbb, 0x1a, 0x39, 0x4b,
+ 0x3c, 0xb6, 0xb2, 0x4b, 0xfd, 0xe8, 0x4e, 0xab, 0x1f, 0x1c, 0xbf, 0xfb,
+ 0xdb, 0x79, 0x6f, 0x17, 0x0c, 0x43, 0x97, 0xff, 0xbe, 0x1e, 0x4b, 0xea,
+ 0x7f, 0xfc, 0x6a, 0x47, 0x2a, 0x11, 0xd6, 0x84, 0xa0, 0x34, 0x51, 0x0e,
+ 0xfe, 0x4d, 0xe0, 0x54, 0xc3, 0x97, 0xee, 0x04, 0x1c, 0xe2, 0x72, 0xff,
+ 0x6b, 0x02, 0x80, 0x5f, 0x56, 0x7b, 0x0e, 0x5b, 0x7f, 0xb6, 0x39, 0xc7,
+ 0xaf, 0x23, 0x97, 0xb7, 0x2e, 0x27, 0x29, 0x0f, 0x4d, 0xac, 0xd2, 0xff,
+ 0xf4, 0x4e, 0xa7, 0x63, 0xef, 0x64, 0xe2, 0x13, 0x94, 0x89, 0x86, 0xbc,
+ 0x27, 0x04, 0x92, 0xff, 0xf7, 0x5e, 0x58, 0x11, 0x47, 0xec, 0x30, 0xe5,
+ 0xfe, 0x8c, 0x1f, 0x70, 0x8d, 0xac, 0xe5, 0xfe, 0xee, 0x71, 0xe5, 0xb9,
+ 0x2c, 0xe5, 0x6c, 0xfc, 0x3c, 0x71, 0x5e, 0x46, 0xc8, 0x21, 0x6f, 0x7f,
+ 0x0f, 0x25, 0x35, 0xd7, 0x39, 0x7f, 0xe0, 0x3c, 0xb9, 0x42, 0x07, 0x18,
+ 0x72, 0x9c, 0xfb, 0xc4, 0xc2, 0xff, 0xda, 0x4f, 0xe7, 0xec, 0x6c, 0x1b,
+ 0x39, 0x7e, 0xcd, 0x3f, 0xcd, 0x9c, 0xbf, 0xff, 0xd3, 0xe3, 0x63, 0x81,
+ 0xd2, 0x02, 0x70, 0xf6, 0x06, 0x73, 0x95, 0x3a, 0x23, 0x36, 0x53, 0x7f,
+ 0xa6, 0x17, 0x6f, 0xd9, 0xd3, 0x97, 0xbb, 0x8b, 0x39, 0x79, 0xb6, 0xdb,
+ 0x29, 0x7f, 0x7f, 0x03, 0x9f, 0x78, 0xa7, 0x33, 0x41, 0x5c, 0x91, 0x60,
+ 0xd0, 0xd1, 0x43, 0xcb, 0xff, 0xfb, 0x87, 0xe4, 0xbe, 0xa0, 0x43, 0x8d,
+ 0xf2, 0xf6, 0xf2, 0x73, 0x95, 0xd4, 0x4e, 0x00, 0xd6, 0xa1, 0x53, 0x02,
+ 0x43, 0x35, 0xe3, 0x70, 0xbf, 0xe5, 0x23, 0x78, 0xda, 0x83, 0xe3, 0x95,
+ 0x3b, 0x3d, 0x46, 0x52, 0x8c, 0x03, 0x09, 0xbf, 0x88, 0x52, 0x56, 0xae,
+ 0xa3, 0xde, 0x64, 0x6f, 0x3d, 0x8e, 0x84, 0x63, 0x0c, 0xdc, 0x25, 0xfd,
+ 0x2a, 0x01, 0x43, 0xab, 0xff, 0x62, 0x0c, 0xee, 0x3e, 0xc6, 0x1c, 0xbf,
+ 0xfd, 0xa5, 0x54, 0xf2, 0x6c, 0x73, 0x8a, 0x04, 0xe5, 0xff, 0x23, 0x61,
+ 0xee, 0x79, 0xa6, 0x1c, 0xa8, 0x44, 0x47, 0x53, 0x6f, 0x85, 0xfe, 0xf1,
+ 0xcb, 0xd8, 0x3f, 0x9c, 0xbe, 0xcf, 0x4d, 0x23, 0x97, 0xff, 0x70, 0x0c,
+ 0x70, 0x6d, 0xc5, 0x4f, 0xf6, 0x72, 0xba, 0x7d, 0xce, 0x47, 0x7f, 0xec,
+ 0xf4, 0x6b, 0x7d, 0x81, 0xf1, 0xe2, 0x08, 0x5f, 0xd9, 0xa5, 0xbb, 0xac,
+ 0xd1, 0x04, 0x39, 0x9e, 0x55, 0xe8, 0x0a, 0x1c, 0xa8, 0x3e, 0x7d, 0xa6,
+ 0x5e, 0xe3, 0x0c, 0x39, 0x7f, 0x3f, 0x75, 0xa4, 0x6c, 0xe5, 0xfc, 0xd6,
+ 0x16, 0xdc, 0x64, 0x72, 0xb0, 0xff, 0x44, 0x78, 0x05, 0xd7, 0xff, 0xa6,
+ 0x92, 0x0f, 0xa3, 0xf9, 0x85, 0x26, 0x39, 0x70, 0xcc, 0x72, 0xd0, 0x13,
+ 0xe3, 0xc4, 0xca, 0x9d, 0x56, 0x92, 0xa4, 0x5d, 0x84, 0x57, 0xf0, 0xd2,
+ 0x18, 0x4f, 0x71, 0x84, 0x85, 0xfd, 0xdc, 0xf7, 0x91, 0x87, 0x2f, 0xef,
+ 0x29, 0x9d, 0x7f, 0x8e, 0x57, 0xc7, 0xb8, 0x25, 0xb7, 0xf6, 0x7d, 0xed,
+ 0x6a, 0x0e, 0x5f, 0xfd, 0xb1, 0x7f, 0x3b, 0x14, 0x89, 0xf0, 0xe5, 0x04,
+ 0xfc, 0xb6, 0x5d, 0x50, 0x8b, 0x60, 0x42, 0x52, 0xfe, 0xc5, 0xa9, 0xc7,
+ 0xb8, 0x72, 0xff, 0xfe, 0x41, 0x0e, 0xb1, 0x7d, 0x8e, 0xe6, 0xb5, 0x0a,
+ 0x9c, 0xba, 0x15, 0x39, 0x72, 0x09, 0xcb, 0x36, 0x72, 0x82, 0x69, 0xd4,
+ 0x15, 0xbc, 0x20, 0x9c, 0xe5, 0xfb, 0xaf, 0x2c, 0x13, 0x97, 0xf2, 0x78,
+ 0x73, 0xa8, 0x72, 0xec, 0xef, 0x23, 0xd1, 0x82, 0x6b, 0x9d, 0xbe, 0x48,
+ 0xfc, 0xc3, 0xee, 0x91, 0x79, 0xba, 0xa4, 0x9f, 0xbe, 0x13, 0xf4, 0xc0,
+ 0x63, 0x56, 0xbf, 0xb6, 0x81, 0x0e, 0x09, 0xcb, 0xff, 0xfb, 0xdd, 0xcd,
+ 0xef, 0x30, 0x1a, 0x9f, 0x00, 0x3e, 0x39, 0x7f, 0xdd, 0x8d, 0x78, 0x63,
+ 0x3e, 0x39, 0x7f, 0xff, 0xc9, 0x3c, 0x4b, 0x7a, 0xd2, 0x7d, 0x34, 0x9f,
+ 0x4c, 0xcf, 0x8e, 0x5f, 0xe8, 0x79, 0xdf, 0x4e, 0xa1, 0xcb, 0xdd, 0xc1,
+ 0x0a, 0x35, 0x7a, 0x71, 0xe6, 0xaa, 0xc4, 0xe7, 0x10, 0xb3, 0xd1, 0x98,
+ 0x5f, 0xa3, 0x53, 0x6e, 0x73, 0x97, 0xfd, 0xd8, 0xcd, 0x4b, 0x60, 0x61,
+ 0xca, 0x9c, 0xf8, 0xd6, 0x55, 0x72, 0x6c, 0xe5, 0xff, 0x64, 0xef, 0xef,
+ 0xd4, 0x19, 0x1c, 0xbf, 0x9f, 0xdc, 0xa2, 0x4a, 0x9c, 0xbf, 0x94, 0x66,
+ 0xdb, 0x7f, 0x8e, 0x54, 0x26, 0xdb, 0x90, 0x98, 0x54, 0x8f, 0x42, 0xce,
+ 0x77, 0xe3, 0x0b, 0xda, 0xce, 0x9c, 0xbd, 0xb4, 0x61, 0xca, 0xd1, 0xb8,
+ 0xf0, 0xe5, 0xc9, 0x39, 0xca, 0x83, 0x71, 0xc0, 0x43, 0x7f, 0xf7, 0x52,
+ 0x07, 0x93, 0x8c, 0x91, 0x87, 0x2f, 0x92, 0x64, 0x6c, 0xe5, 0xff, 0xcc,
+ 0x7f, 0x94, 0xf2, 0x6a, 0x01, 0xc3, 0x9c, 0xbf, 0xff, 0x02, 0x71, 0x8c,
+ 0xef, 0x38, 0xf6, 0x74, 0x1a, 0x39, 0x7d, 0xed, 0xa9, 0xbe, 0x49, 0x84,
+ 0x05, 0x0f, 0x08, 0xd4, 0x4b, 0xbf, 0x6d, 0x99, 0xed, 0x9c, 0xbf, 0xf9,
+ 0x15, 0xcf, 0x27, 0x73, 0xd1, 0xa3, 0x97, 0xe7, 0x90, 0xa4, 0x1c, 0xbf,
+ 0xa1, 0xc7, 0xd8, 0x27, 0x2a, 0x4a, 0x8f, 0xb2, 0x32, 0xb4, 0x59, 0xd1,
+ 0x43, 0x10, 0xc4, 0x96, 0xfd, 0xd4, 0x68, 0x8a, 0x9c, 0xbe, 0xcf, 0xd3,
+ 0x89, 0xca, 0x59, 0xe7, 0x09, 0x55, 0xff, 0xdf, 0xc6, 0xd9, 0x09, 0xad,
+ 0x23, 0x67, 0x2f, 0x3b, 0xc8, 0xe5, 0x21, 0xf0, 0x7e, 0x8b, 0x7f, 0x0e,
+ 0xf1, 0x90, 0xd6, 0x72, 0xf9, 0xaf, 0xb9, 0x39, 0xcb, 0xfd, 0x01, 0xcf,
+ 0x27, 0x40, 0x72, 0xa0, 0xf6, 0x02, 0x4d, 0x50, 0x8a, 0x86, 0x42, 0x1e,
+ 0xff, 0xde, 0x53, 0xf8, 0x52, 0x3f, 0x8f, 0xce, 0x5f, 0xff, 0xf9, 0x8e,
+ 0x3f, 0xc9, 0x36, 0x06, 0x75, 0x23, 0xdd, 0x03, 0xb0, 0xe5, 0xff, 0xf0,
+ 0x83, 0xd2, 0x4f, 0xfa, 0xe9, 0xe7, 0x61, 0xcb, 0xb9, 0x35, 0x9c, 0xbf,
+ 0xff, 0x3a, 0x79, 0x03, 0x81, 0xcf, 0x23, 0x13, 0x47, 0x2f, 0xff, 0x42,
+ 0xc3, 0x8a, 0x79, 0x35, 0x00, 0xe1, 0xce, 0x5e, 0xd3, 0xef, 0x13, 0x0c,
+ 0xd2, 0x7f, 0x47, 0x05, 0x4a, 0xde, 0x74, 0xf1, 0x41, 0x1b, 0xc5, 0x7c,
+ 0xa8, 0xdd, 0x25, 0x04, 0x5d, 0x28, 0x39, 0x7f, 0xfa, 0x70, 0xf6, 0x3b,
+ 0x9f, 0x7f, 0x9e, 0xd9, 0xca, 0x73, 0xe3, 0x00, 0xb5, 0x05, 0x71, 0x67,
+ 0x21, 0x02, 0x90, 0xca, 0x79, 0x4b, 0xc3, 0x08, 0xfb, 0xfb, 0x51, 0x3a,
+ 0x0f, 0x8e, 0x5e, 0x0a, 0x8c, 0x39, 0x7e, 0x18, 0x0e, 0x4c, 0x72, 0xfb,
+ 0x60, 0xd2, 0xa7, 0x2f, 0xd1, 0xdf, 0x44, 0x8e, 0x5f, 0x04, 0x1e, 0xdc,
+ 0x1f, 0x97, 0xc4, 0xff, 0x92, 0x5f, 0xbf, 0xc6, 0x47, 0x4e, 0x5f, 0xff,
+ 0xfe, 0xc9, 0xf7, 0x0a, 0xbe, 0xfd, 0x2c, 0x55, 0x5c, 0xfb, 0xda, 0x8c,
+ 0xf8, 0xe5, 0xfa, 0x39, 0x68, 0x64, 0x72, 0xb6, 0x8a, 0x50, 0x3e, 0x5e,
+ 0xe1, 0xfb, 0x87, 0x28, 0x2a, 0x85, 0xb0, 0xb5, 0x21, 0x20, 0x29, 0x1e,
+ 0x86, 0x68, 0x08, 0xef, 0x69, 0x4d, 0x9c, 0xbf, 0xee, 0xc7, 0xde, 0x8e,
+ 0xbb, 0x59, 0xca, 0x39, 0x5c, 0x8f, 0x1f, 0x85, 0xcf, 0x2f, 0xde, 0xf7,
+ 0xb1, 0xb3, 0x95, 0x07, 0xa8, 0x85, 0x77, 0xfe, 0x71, 0x5e, 0x69, 0x6e,
+ 0xeb, 0x34, 0x42, 0x2b, 0xa5, 0x39, 0xca, 0x84, 0xce, 0xbf, 0x85, 0xc8,
+ 0x08, 0x38, 0xa4, 0xdf, 0xb2, 0x7d, 0xfe, 0xe7, 0x2f, 0xff, 0xff, 0x77,
+ 0x01, 0xa5, 0x7a, 0x9f, 0x47, 0x81, 0xd1, 0xcf, 0xbc, 0x07, 0xd9, 0xcb,
+ 0xff, 0xb3, 0xe5, 0x3c, 0x82, 0x09, 0x66, 0xce, 0x5f, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xb0, 0x67, 0x17, 0x0c, 0x0c, 0xf1, 0xa0, 0xe0, 0xe7, 0xb6,
+ 0x8b, 0xc1, 0x52, 0x7c, 0xd4, 0x6c, 0x5d, 0x5d, 0xe2, 0x7f, 0xf8, 0x3f,
+ 0x17, 0x0c, 0x0c, 0xf1, 0xa3, 0x95, 0x09, 0xa7, 0xe2, 0x2d, 0xff, 0xde,
+ 0x71, 0x9f, 0xe9, 0x0c, 0x66, 0xce, 0x5f, 0xff, 0xa3, 0xf9, 0xa5, 0x13,
+ 0x8b, 0xab, 0xb1, 0x89, 0x1c, 0xbf, 0xf2, 0x99, 0xd7, 0x67, 0x36, 0xdb,
+ 0x6c, 0xe5, 0xff, 0xfb, 0x17, 0xd8, 0x10, 0x8a, 0x4f, 0x82, 0x8a, 0x9c,
+ 0xb3, 0xce, 0x89, 0x89, 0x22, 0xd4, 0x93, 0x18, 0x78, 0x77, 0xdf, 0xff,
+ 0xd3, 0x0c, 0x7f, 0xb5, 0xf5, 0x35, 0x30, 0xc7, 0xfb, 0x39, 0x7f, 0xff,
+ 0x7b, 0x70, 0xac, 0x93, 0xae, 0x3e, 0x96, 0x6b, 0x0e, 0x5f, 0xf9, 0x37,
+ 0x81, 0xe4, 0xff, 0xb4, 0xc3, 0x97, 0xfe, 0xea, 0x71, 0xeb, 0xcb, 0x50,
+ 0xa9, 0xca, 0xc4, 0x6e, 0xad, 0x6b, 0xc8, 0x57, 0xf0, 0x3c, 0x80, 0x15,
+ 0x4e, 0x5f, 0xd8, 0xde, 0x08, 0x3f, 0x39, 0x7e, 0x96, 0x7a, 0x3f, 0x39,
+ 0x74, 0x32, 0x73, 0xd6, 0xf8, 0xba, 0xff, 0xff, 0xef, 0xd8, 0xf2, 0xeb,
+ 0xa7, 0x90, 0x38, 0x1c, 0xf2, 0x31, 0x34, 0x72, 0xb6, 0x89, 0xf0, 0x17,
+ 0xdf, 0xff, 0x87, 0x37, 0x9d, 0x7e, 0x05, 0xf5, 0x19, 0x0b, 0x39, 0x7e,
+ 0x9d, 0x90, 0x18, 0x39, 0x52, 0x5e, 0x9d, 0x0c, 0x79, 0x3f, 0x11, 0x4d,
+ 0x1a, 0xe6, 0x8a, 0x3b, 0x19, 0xde, 0xcb, 0xfd, 0x19, 0x1f, 0x12, 0x35,
+ 0x15, 0xaf, 0xfd, 0x0a, 0xab, 0x03, 0x9e, 0xea, 0x1c, 0xbf, 0xd1, 0xbd,
+ 0xc4, 0xf8, 0xd9, 0xcb, 0xfd, 0xdc, 0x66, 0x74, 0x02, 0x72, 0x82, 0x7c,
+ 0xde, 0x34, 0xbe, 0xcd, 0x2a, 0x87, 0x2a, 0x19, 0x0b, 0x39, 0x3d, 0x8c,
+ 0x90, 0xab, 0x78, 0x52, 0x00, 0x8a, 0xf3, 0x6d, 0xb6, 0x52, 0xff, 0xb3,
+ 0xf7, 0xd6, 0x71, 0xc0, 0x94, 0xe6, 0x68, 0x2e, 0x6d, 0xb2, 0x97, 0x9b,
+ 0x6d, 0xb2, 0x97, 0xf3, 0xce, 0x1e, 0xc6, 0xca, 0x73, 0x34, 0x14, 0x28,
+ 0xc5, 0x6d, 0x31, 0xa1, 0xcd, 0xf9, 0x68, 0x15, 0x18, 0x53, 0x99, 0xb2,
+ 0xbc, 0xdb, 0x6d, 0x94, 0xbd, 0xb8, 0xd1, 0x4e, 0x66, 0x82, 0xf9, 0xc7,
+ 0xef, 0x1c, 0xb7, 0xe8, 0x8a, 0xbf, 0x2d, 0xb6, 0x5d, 0x7f, 0x04, 0x62,
+ 0x4e, 0xb3, 0x97, 0xed, 0x82, 0x76, 0x82, 0x72, 0xfc, 0x14, 0xe3, 0x01,
+ 0x39, 0x7d, 0x83, 0x8d, 0x67, 0x2b, 0x47, 0x98, 0xc2, 0x9a, 0x44, 0x4c,
+ 0xa8, 0xef, 0x7f, 0xf7, 0x5e, 0x42, 0xea, 0xcc, 0x29, 0x31, 0xcb, 0xfe,
+ 0x9e, 0x3e, 0xda, 0x0e, 0x7e, 0x72, 0xf9, 0xe4, 0x9f, 0x9c, 0xad, 0x1e,
+ 0xe7, 0x4e, 0xaf, 0xfb, 0x17, 0x13, 0x87, 0xb1, 0xb3, 0x95, 0x87, 0xb6,
+ 0xd0, 0x8a, 0xfe, 0xee, 0x71, 0xcf, 0x6c, 0xe5, 0x2d, 0x34, 0xef, 0xe1,
+ 0xf9, 0xe2, 0x3a, 0xd2, 0xa6, 0xde, 0xc3, 0x14, 0x63, 0x71, 0xba, 0x7f,
+ 0x1c, 0xa8, 0x55, 0xf1, 0x92, 0xa9, 0x04, 0xf2, 0xfd, 0x3b, 0x4e, 0xe2,
+ 0xce, 0x5c, 0xd4, 0x1a, 0x93, 0x97, 0xed, 0xcd, 0xb8, 0xf1, 0xca, 0xc3,
+ 0xf6, 0xf8, 0xaf, 0xc4, 0x57, 0xe5, 0xc7, 0x61, 0x87, 0x2e, 0x7f, 0x1c,
+ 0xbf, 0x63, 0x5b, 0x8f, 0xf8, 0x6f, 0x44, 0x9e, 0xff, 0xa0, 0x64, 0x21,
+ 0xec, 0x4e, 0x72, 0xfe, 0x0e, 0x69, 0xa3, 0x02, 0x72, 0xf7, 0x52, 0x62,
+ 0x95, 0xa3, 0xcd, 0xd9, 0x85, 0xff, 0x3f, 0xde, 0xc9, 0x81, 0xa5, 0x4e,
+ 0x59, 0x68, 0x7b, 0xc0, 0x22, 0xbf, 0xc3, 0x9f, 0x4b, 0x68, 0xa9, 0xcb,
+ 0xe7, 0x7d, 0x2a, 0x72, 0xca, 0x9c, 0xbf, 0xfb, 0x17, 0xd8, 0xee, 0x6b,
+ 0x50, 0xa9, 0xcb, 0xc9, 0xfe, 0xe0, 0xf5, 0xb4, 0x25, 0x5c, 0x91, 0xbf,
+ 0x39, 0xa0, 0xbc, 0x5f, 0xf6, 0x62, 0xff, 0x8c, 0xfa, 0x47, 0x2f, 0xa1,
+ 0xd9, 0xc4, 0xa5, 0xff, 0xdd, 0x47, 0xff, 0xf8, 0xfe, 0x3b, 0xb3, 0x97,
+ 0xf7, 0x71, 0x8c, 0x79, 0x1c, 0xbc, 0xdb, 0x6d, 0x94, 0xbf, 0xc3, 0xee,
+ 0xa4, 0x0c, 0xe5, 0x39, 0x9a, 0x0b, 0xd1, 0xfe, 0x49, 0x12, 0x38, 0x9b,
+ 0x5e, 0x4c, 0x29, 0x48, 0x6b, 0xdb, 0x16, 0x9a, 0xbb, 0x23, 0x2d, 0xbf,
+ 0xbf, 0x8f, 0xe3, 0xbb, 0x39, 0x7f, 0xa1, 0x4d, 0x69, 0x3d, 0xb3, 0x95,
+ 0x0b, 0x9c, 0xf2, 0x6c, 0x54, 0xfb, 0xe8, 0x71, 0xa4, 0x60, 0xd3, 0x19,
+ 0x76, 0x39, 0x0f, 0xcb, 0xc4, 0xbe, 0xfd, 0xfe, 0x27, 0x55, 0x39, 0x7f,
+ 0xfd, 0x8b, 0x81, 0x7f, 0x6c, 0x20, 0x7d, 0x48, 0xe5, 0x7c, 0x7e, 0xec,
+ 0x29, 0xbf, 0xa0, 0x56, 0xd5, 0x35, 0x16, 0xac, 0xe5, 0xfa, 0x19, 0xa8,
+ 0xe2, 0x72, 0xff, 0xf6, 0xa1, 0x7e, 0x18, 0x6f, 0x3d, 0xbd, 0x9c, 0xbf,
+ 0xff, 0xf8, 0x5d, 0x91, 0xa5, 0x87, 0xb1, 0xb0, 0x3a, 0x4b, 0x7d, 0x79,
+ 0x1c, 0xbc, 0x0f, 0x6c, 0xe5, 0xe5, 0xc6, 0xce, 0x5f, 0xfc, 0xa4, 0xb3,
+ 0xaf, 0xd4, 0xd6, 0xa0, 0xe5, 0x61, 0xf0, 0x7e, 0x39, 0x7e, 0x8f, 0x6f,
+ 0x8e, 0x1c, 0xbf, 0x03, 0x4a, 0xf5, 0x0e, 0x54, 0x2a, 0x34, 0x09, 0x1a,
+ 0xcf, 0x74, 0x52, 0xe9, 0x5f, 0xb8, 0x0b, 0xef, 0x88, 0x9a, 0x14, 0xdf,
+ 0xe1, 0x76, 0xf0, 0x5d, 0x53, 0x97, 0xff, 0x67, 0xb6, 0xa6, 0xd8, 0x31,
+ 0xa8, 0x39, 0x7b, 0x8e, 0x08, 0x4f, 0xd9, 0x86, 0x57, 0xff, 0x37, 0x1a,
+ 0x17, 0x9e, 0x35, 0x12, 0x39, 0x48, 0x7f, 0x1d, 0x34, 0xbf, 0xff, 0xe0,
+ 0xf5, 0x1b, 0xce, 0x04, 0x63, 0xfb, 0x60, 0x96, 0x7d, 0xe3, 0x95, 0x88,
+ 0x8c, 0x72, 0x1b, 0xfe, 0x99, 0x7d, 0x46, 0x46, 0x95, 0x39, 0x7e, 0x9f,
+ 0x90, 0x22, 0x63, 0x96, 0x91, 0xcb, 0xca, 0x0c, 0xc7, 0x2a, 0x46, 0xbf,
+ 0xf1, 0x1a, 0xc4, 0x5c, 0x39, 0xde, 0xd6, 0xea, 0x1f, 0x2b, 0xe2, 0x79,
+ 0x5c, 0x92, 0x9c, 0x29, 0x0c, 0xb5, 0x3c, 0xa7, 0xcc, 0xab, 0x0e, 0x15,
+ 0xc3, 0x11, 0x25, 0x7a, 0x4d, 0x2d, 0xeb, 0x52, 0xd2, 0xd9, 0x2c, 0x27,
+ 0xb3, 0xa0, 0x6f, 0x29, 0xd7, 0xf8, 0xe6, 0x86, 0x91, 0x3d, 0xb9, 0xd1,
+ 0x6f, 0x4e, 0xc9, 0x82, 0x59, 0xf3, 0x71, 0xfd, 0x29, 0x0d, 0x9b, 0xdc,
+ 0x60, 0x4e, 0x5f, 0xff, 0x60, 0xf3, 0xf2, 0xa9, 0xf6, 0xfb, 0x9f, 0xb9,
+ 0xca, 0x91, 0xf8, 0x04, 0x76, 0xf3, 0xbb, 0x67, 0x2e, 0xfe, 0x0e, 0x5f,
+ 0x97, 0x9e, 0xea, 0x1c, 0xb3, 0x84, 0xf6, 0x90, 0x70, 0x45, 0xef, 0xff,
+ 0xfb, 0x3a, 0xea, 0x6f, 0x15, 0x71, 0xfe, 0x06, 0x26, 0xec, 0x1c, 0xb4,
+ 0x1c, 0xbf, 0xff, 0x46, 0xbb, 0x0c, 0xe0, 0x04, 0x0c, 0x4d, 0xd8, 0x39,
+ 0x7e, 0x4d, 0x4d, 0x1d, 0xd2, 0x33, 0x7f, 0x66, 0x11, 0x0a, 0xf9, 0x3c,
+ 0x86, 0x3e, 0x29, 0x0f, 0xfb, 0x70, 0xb9, 0xcb, 0xff, 0x7b, 0xaf, 0x2f,
+ 0x4c, 0x30, 0xc3, 0x97, 0xfe, 0x71, 0xff, 0x90, 0x40, 0xfa, 0x91, 0xcb,
+ 0xe4, 0x19, 0xe0, 0xe5, 0xef, 0x6a, 0x0e, 0x5f, 0xf0, 0xc3, 0x10, 0x71,
+ 0x90, 0x72, 0xe4, 0x0e, 0x1e, 0x8c, 0xc3, 0x94, 0xd6, 0x8e, 0x0d, 0x20,
+ 0x8b, 0x95, 0xff, 0xc3, 0xed, 0xf5, 0xe5, 0xcb, 0x3e, 0xf1, 0xca, 0x6a,
+ 0x29, 0xd8, 0x40, 0xc6, 0x46, 0x3e, 0x03, 0x2b, 0xfe, 0x76, 0xb9, 0xb7,
+ 0x1d, 0x76, 0xb3, 0x97, 0xa0, 0x67, 0x39, 0x7c, 0x9d, 0x46, 0x1c, 0xb7,
+ 0x50, 0xde, 0xcc, 0x39, 0x7f, 0x42, 0xe3, 0x7e, 0x43, 0x97, 0xfd, 0x1e,
+ 0xeb, 0xfe, 0xff, 0x6c, 0xe5, 0x04, 0xf9, 0x84, 0xb2, 0xff, 0xff, 0x08,
+ 0x1d, 0x7b, 0x03, 0xa4, 0xa0, 0x57, 0x9f, 0x78, 0xe5, 0xff, 0xb5, 0xff,
+ 0x2e, 0xa2, 0xc1, 0xaf, 0xce, 0x5e, 0x98, 0x1a, 0x39, 0x7f, 0xe7, 0x4d,
+ 0x67, 0xdc, 0xdb, 0x6d, 0xb3, 0x95, 0x08, 0xa6, 0x74, 0x4d, 0x8f, 0x5f,
+ 0xff, 0x0c, 0x4b, 0x92, 0x9e, 0x41, 0x04, 0xb3, 0x67, 0x2b, 0x15, 0x19,
+ 0x2e, 0x11, 0xac, 0x21, 0xec, 0x60, 0xbf, 0x97, 0x5e, 0xfd, 0xd8, 0x72,
+ 0xec, 0xfc, 0xe5, 0x41, 0xb4, 0xc1, 0xdb, 0xcf, 0x8c, 0x39, 0x70, 0xc8,
+ 0x4d, 0xd7, 0x00, 0xfd, 0xfe, 0x6f, 0x63, 0x81, 0x17, 0x39, 0x72, 0xd0,
+ 0xe5, 0xf8, 0x62, 0x78, 0xf8, 0xe5, 0xb6, 0xb3, 0x7c, 0x82, 0xd5, 0x08,
+ 0xc4, 0x42, 0xe7, 0x70, 0xbf, 0x6b, 0x63, 0x13, 0x9c, 0xbf, 0xfe, 0x6f,
+ 0x17, 0xbc, 0xf4, 0xd8, 0xa8, 0xe7, 0xe7, 0x2b, 0x0f, 0xe9, 0x0a, 0x2f,
+ 0xfb, 0x1b, 0xcd, 0x2d, 0xdd, 0x66, 0x8c, 0x39, 0x7e, 0xf7, 0x5c, 0x7f,
+ 0x39, 0x53, 0x9f, 0x6b, 0xa2, 0xdf, 0xf9, 0xfd, 0x93, 0x3c, 0x0c, 0x4c,
+ 0x72, 0xff, 0xdd, 0x4c, 0x53, 0x26, 0x6e, 0x3e, 0x39, 0x64, 0xd2, 0x28,
+ 0x3a, 0x45, 0xb3, 0xdb, 0x96, 0xb3, 0x46, 0x08, 0xa9, 0x27, 0x0c, 0xb8,
+ 0xcb, 0x7f, 0x35, 0xbf, 0xcd, 0x4e, 0xc2, 0x39, 0xde, 0x10, 0xe5, 0xd8,
+ 0x27, 0x2f, 0xff, 0x7a, 0x05, 0x79, 0xee, 0xa6, 0xbf, 0x59, 0xcb, 0xf0,
+ 0x53, 0x7d, 0x43, 0x97, 0xf2, 0x0e, 0x7b, 0xa8, 0x72, 0xd1, 0x87, 0xa5,
+ 0xb2, 0x7a, 0x0a, 0x35, 0xf0, 0x54, 0x10, 0x9c, 0xbf, 0xd0, 0xcd, 0xed,
+ 0xc6, 0x73, 0x97, 0xfd, 0xfe, 0xe4, 0x9d, 0x74, 0x9c, 0xe5, 0xf6, 0xf0,
+ 0x7c, 0x72, 0xf7, 0x04, 0x68, 0xe5, 0x21, 0xfd, 0x39, 0xd0, 0x08, 0x6f,
+ 0x79, 0xda, 0xce, 0x5f, 0xef, 0x75, 0x39, 0xfe, 0xe8, 0x72, 0xff, 0x2b,
+ 0xd8, 0x90, 0x1f, 0x47, 0x2c, 0x27, 0x29, 0x0f, 0x10, 0x06, 0x97, 0x29,
+ 0x87, 0x2a, 0x75, 0x5e, 0x41, 0x8c, 0x53, 0xa6, 0x83, 0x0a, 0xdf, 0x16,
+ 0x80, 0x7d, 0xa3, 0xca, 0x84, 0x37, 0xe5, 0x7f, 0x49, 0xb6, 0x72, 0xfb,
+ 0xa8, 0xf2, 0x39, 0x78, 0x2f, 0x23, 0x95, 0x06, 0xf7, 0x08, 0x6c, 0x08,
+ 0x44, 0x3f, 0xed, 0x17, 0xff, 0xb9, 0x0b, 0xfa, 0x34, 0x09, 0x6a, 0x24,
+ 0x72, 0xef, 0x6c, 0xe5, 0xf9, 0xd5, 0x6e, 0x34, 0x72, 0x91, 0x11, 0x6e,
+ 0x96, 0x22, 0xf7, 0xff, 0x22, 0xc7, 0x19, 0x13, 0x06, 0x27, 0x39, 0x7f,
+ 0xcb, 0xcf, 0x47, 0x14, 0x1f, 0xce, 0x5f, 0xff, 0xc0, 0x8f, 0x6f, 0x07,
+ 0x96, 0xa1, 0x02, 0x2f, 0x23, 0x97, 0xe5, 0xf7, 0xe7, 0x6b, 0x39, 0x7f,
+ 0xf2, 0x04, 0x41, 0xed, 0xc0, 0xc6, 0xce, 0x52, 0xd3, 0x46, 0x44, 0x41,
+ 0x3a, 0x02, 0xd7, 0x12, 0xcb, 0xff, 0x3e, 0xb3, 0x8e, 0x07, 0x42, 0xd9,
+ 0xcb, 0xff, 0xf9, 0x00, 0x32, 0xc1, 0xf2, 0x34, 0xcf, 0x0b, 0xc8, 0xe5,
+ 0x7e, 0x89, 0x9f, 0x20, 0x5f, 0xff, 0xc3, 0x9b, 0x07, 0x2c, 0xeb, 0x8e,
+ 0x4d, 0x28, 0xf8, 0xe5, 0xfb, 0x4b, 0x77, 0x59, 0xa2, 0x06, 0x5f, 0xcf,
+ 0x3f, 0xee, 0x21, 0x25, 0x60, 0xf5, 0xec, 0xd8, 0x30, 0xfc, 0x1a, 0x1a,
+ 0x5e, 0xeb, 0xcb, 0x92, 0x60, 0x03, 0x0c, 0xcb, 0xfe, 0xea, 0x60, 0xe2,
+ 0xc3, 0x87, 0x29, 0x89, 0xca, 0xfa, 0x32, 0x4e, 0x27, 0x77, 0xbc, 0x08,
+ 0x39, 0x7d, 0xfe, 0xb7, 0xb3, 0x97, 0xfb, 0xff, 0x24, 0xec, 0x85, 0x9c,
+ 0xaf, 0x8f, 0xd5, 0xc7, 0x04, 0x92, 0xfc, 0x16, 0xad, 0xc2, 0xd5, 0x9c,
+ 0xbf, 0xff, 0x3c, 0xb6, 0x81, 0xe5, 0x99, 0xf7, 0xee, 0x3e, 0x39, 0x50,
+ 0xaf, 0x7b, 0x25, 0x3c, 0xa4, 0x2b, 0x9c, 0xb8, 0x06, 0x57, 0x24, 0x8e,
+ 0x5f, 0xdf, 0x78, 0x39, 0x8a, 0x9c, 0xa0, 0x9e, 0x2e, 0x0b, 0x5f, 0xd9,
+ 0xe8, 0x14, 0xfc, 0xe5, 0xfe, 0xd0, 0xbb, 0x6a, 0x7c, 0xd9, 0xcb, 0xbf,
+ 0xe2, 0x72, 0x82, 0x7a, 0x3d, 0x37, 0xbc, 0xfa, 0x9c, 0xd1, 0x82, 0xaf,
+ 0xfc, 0xfa, 0xc1, 0xff, 0x7e, 0xdf, 0xc7, 0x2f, 0xff, 0xff, 0xec, 0xf7,
+ 0x5c, 0x55, 0xe5, 0xbd, 0x3b, 0xfb, 0x8e, 0x07, 0x96, 0x31, 0xc7, 0xe9,
+ 0x1e, 0x20, 0xb5, 0xff, 0x9d, 0xd5, 0x5b, 0x87, 0x92, 0xad, 0x9e, 0x20,
+ 0xb5, 0xff, 0xdd, 0x4e, 0xa4, 0x0f, 0xb9, 0x2a, 0xd9, 0xe2, 0x0b, 0x5f,
+ 0xe8, 0x41, 0xf7, 0x25, 0x5b, 0x3c, 0x41, 0x6b, 0xf9, 0x98, 0x1e, 0x4a,
+ 0xb6, 0x78, 0x82, 0xd7, 0xff, 0xfc, 0xe2, 0x28, 0xce, 0x5b, 0x5f, 0x53,
+ 0x48, 0xac, 0xf8, 0xd9, 0xe2, 0x0b, 0x5d, 0xf7, 0x20, 0xa7, 0x38, 0xb5,
+ 0x0d, 0x2a, 0x3a, 0x18, 0x9f, 0xd4, 0x2a, 0xcf, 0xea, 0x00, 0xca, 0x37,
+ 0xbf, 0xc9, 0x0a, 0xef, 0xdb, 0xf8, 0xe5, 0xf3, 0xeb, 0xf7, 0x39, 0x7f,
+ 0xf7, 0x53, 0xa9, 0x03, 0xee, 0x4a, 0xb6, 0x78, 0x82, 0xd7, 0xfd, 0x36,
+ 0xd6, 0x93, 0xf2, 0x55, 0xb3, 0xc4, 0x16, 0xbf, 0x7b, 0x70, 0xce, 0x4b,
+ 0x45, 0x0a, 0x8a, 0x97, 0xff, 0xb9, 0x2f, 0xa8, 0xb8, 0xf6, 0xf9, 0x2a,
+ 0xd9, 0xe2, 0x0b, 0x5f, 0xff, 0xfc, 0x22, 0x8c, 0xe4, 0x0c, 0xe5, 0xb5,
+ 0xf5, 0x34, 0x8a, 0xcf, 0x8d, 0x9e, 0x20, 0xb5, 0x62, 0x64, 0xbf, 0x21,
+ 0xba, 0xf5, 0xff, 0x75, 0x34, 0x8a, 0xcf, 0x8d, 0x9e, 0x20, 0xb5, 0xff,
+ 0xf3, 0xbf, 0xd2, 0xdf, 0x50, 0x21, 0x8d, 0x41, 0x4b, 0xff, 0x64, 0xa4,
+ 0x0d, 0xe8, 0x67, 0x68, 0x78, 0x82, 0xd4, 0xb4, 0x73, 0x69, 0x23, 0x69,
+ 0xf7, 0xfe, 0x5a, 0x6b, 0xcf, 0xfe, 0xf9, 0x36, 0x78, 0x82, 0xd7, 0xf7,
+ 0x53, 0xbd, 0x4f, 0xcd, 0x00, 0x5a, 0xfd, 0x9f, 0xf2, 0x55, 0xb3, 0xc4,
+ 0x16, 0xbb, 0x3c, 0xb3, 0xf5, 0xe9, 0xdd, 0x7c, 0x8f, 0x2d, 0xc3, 0x16,
+ 0xfe, 0x66, 0x07, 0x92, 0xad, 0x9e, 0x20, 0xb5, 0xff, 0x97, 0xd4, 0xd2,
+ 0x2b, 0x3e, 0x36, 0x78, 0x82, 0xd7, 0x67, 0x27, 0x44, 0x6e, 0xcf, 0xef,
+ 0xf0, 0x11, 0x8e, 0x3f, 0x48, 0xf1, 0x05, 0xaf, 0xfd, 0x89, 0xc7, 0x07,
+ 0x02, 0xf2, 0x3c, 0x41, 0x66, 0x1e, 0x05, 0x05, 0x78, 0x33, 0x46, 0xff,
+ 0x9a, 0x8c, 0x7d, 0x1b, 0x8c, 0x5b, 0xd1, 0x91, 0x02, 0x16, 0xcd, 0xb7,
+ 0xdd, 0xfc, 0x1a, 0x20, 0xb7, 0x34, 0x46, 0x5c, 0xeb, 0x39, 0x6d, 0xad,
+ 0x93, 0xbf, 0xfd, 0x26, 0x47, 0xc7, 0x17, 0x4b, 0x80, 0xe5, 0xe8, 0x97,
+ 0x01, 0xca, 0x83, 0x72, 0x23, 0x55, 0x3b, 0x2c, 0xec, 0x24, 0x3f, 0x3e,
+ 0xff, 0x4a, 0x01, 0x17, 0xdb, 0xff, 0xb2, 0x43, 0x9e, 0xea, 0x67, 0xde,
+ 0x39, 0x7f, 0xa3, 0xa8, 0xdf, 0xd2, 0xd9, 0xcb, 0xf4, 0x7b, 0x7d, 0x43,
+ 0x97, 0xfe, 0xd6, 0x2b, 0xdc, 0x60, 0x35, 0x39, 0xcb, 0xfe, 0xf8, 0x71,
+ 0x19, 0x83, 0xf9, 0xcb, 0xff, 0x6e, 0x69, 0x00, 0x33, 0x48, 0x01, 0x39,
+ 0x53, 0xa6, 0x31, 0x23, 0x50, 0x93, 0xe2, 0x0f, 0x8e, 0x2f, 0xfe, 0x8f,
+ 0xa4, 0xa3, 0x37, 0xe8, 0xf9, 0xb3, 0x97, 0xe9, 0x70, 0x70, 0x02, 0x73,
+ 0x96, 0xea, 0x1f, 0xcb, 0xa4, 0xdf, 0xb5, 0x1f, 0x4b, 0x67, 0x2a, 0x47,
+ 0x9f, 0xa2, 0x6b, 0xcc, 0x7f, 0x1c, 0xbf, 0xf0, 0x36, 0xd3, 0x35, 0xfb,
+ 0x13, 0x67, 0x2f, 0xfe, 0xe3, 0xc6, 0x36, 0xfd, 0xfa, 0x59, 0xe3, 0x95,
+ 0xfa, 0x22, 0xd4, 0x42, 0xbf, 0xdf, 0x83, 0xc3, 0x1e, 0xd9, 0xca, 0x92,
+ 0x60, 0x1f, 0xc2, 0x9f, 0x64, 0xb5, 0x0a, 0x9b, 0x32, 0x31, 0x37, 0x8c,
+ 0x8a, 0xfe, 0x79, 0x47, 0x17, 0xe9, 0xcb, 0xff, 0xb3, 0xef, 0x6d, 0x06,
+ 0x3f, 0x76, 0x1c, 0xbf, 0xf7, 0x0f, 0x82, 0x38, 0xa4, 0x0f, 0xe7, 0x2a,
+ 0x74, 0x43, 0x01, 0x12, 0xfb, 0xed, 0xc7, 0xc7, 0x2f, 0xfd, 0x2c, 0xfa,
+ 0x5a, 0x8f, 0x3f, 0x8e, 0x5e, 0x64, 0x48, 0xe5, 0xfb, 0x03, 0xd0, 0x36,
+ 0x72, 0xb9, 0x22, 0xa2, 0x62, 0x47, 0x3f, 0x11, 0xcb, 0xc1, 0x7f, 0x1c,
+ 0xbf, 0xf6, 0xe0, 0x62, 0x5e, 0xee, 0x09, 0xca, 0xd2, 0x25, 0x9c, 0xfb,
+ 0x63, 0x97, 0x91, 0xa6, 0x1c, 0xbc, 0xfa, 0xfc, 0xe5, 0xbe, 0x83, 0x75,
+ 0xe1, 0xdb, 0xe6, 0xf3, 0xae, 0x72, 0xf9, 0x5d, 0x23, 0x67, 0x2f, 0xd3,
+ 0xbf, 0x61, 0xac, 0xe5, 0x35, 0x27, 0x9f, 0x84, 0x95, 0x0a, 0xcf, 0x72,
+ 0x16, 0x89, 0x1b, 0x13, 0xb4, 0xfe, 0x4e, 0x2e, 0x37, 0xff, 0x0c, 0x4e,
+ 0xce, 0xa6, 0xb4, 0xf2, 0x39, 0x47, 0x28, 0x4f, 0x3d, 0xa2, 0x25, 0xfe,
+ 0x9e, 0x78, 0x1f, 0xb3, 0xc7, 0x2b, 0x0f, 0x61, 0x08, 0xef, 0xfe, 0xd0,
+ 0x83, 0xef, 0x0e, 0x4e, 0xe2, 0x72, 0xff, 0xfe, 0x0f, 0x41, 0x3a, 0x66,
+ 0xb5, 0x91, 0xf4, 0x91, 0x87, 0x2f, 0x3e, 0xa7, 0x39, 0x77, 0xf0, 0x72,
+ 0xf9, 0x21, 0x98, 0x72, 0x8e, 0x5f, 0xce, 0xaf, 0xa3, 0x5f, 0x9c, 0xa0,
+ 0x9b, 0xa1, 0x0b, 0xbf, 0xff, 0xd0, 0x81, 0x18, 0x02, 0xfd, 0x8b, 0x0c,
+ 0x2d, 0x46, 0x1c, 0xbb, 0xf8, 0x39, 0x74, 0x2a, 0x72, 0xff, 0xb3, 0xdb,
+ 0x86, 0x29, 0x93, 0x1c, 0xbf, 0xdb, 0xce, 0xa6, 0xc1, 0x39, 0xcb, 0x9b,
+ 0x6c, 0xa5, 0xff, 0x0e, 0x71, 0x79, 0x6d, 0x02, 0x72, 0x96, 0x9f, 0xe2,
+ 0x0e, 0xe8, 0x5d, 0x8b, 0x5d, 0x20, 0xfd, 0x83, 0x87, 0x17, 0x11, 0x7d,
+ 0x9d, 0x36, 0x68, 0xa0, 0xcd, 0xe6, 0xdb, 0x6c, 0xa5, 0x98, 0x53, 0x99,
+ 0xa0, 0xbe, 0x99, 0xdf, 0x45, 0x39, 0xa3, 0x89, 0x48, 0x5f, 0xd4, 0xea,
+ 0xf1, 0xd6, 0x88, 0xf2, 0xce, 0xaf, 0xef, 0x46, 0x77, 0x27, 0x39, 0x76,
+ 0x30, 0xe5, 0x7c, 0x78, 0x7b, 0x2d, 0xa8, 0x75, 0x78, 0x92, 0x8f, 0xa0,
+ 0x29, 0x19, 0x2a, 0xb9, 0x58, 0xe2, 0x7e, 0x94, 0x5a, 0x92, 0xca, 0xb5,
+ 0x18, 0x43, 0x21, 0x69, 0xd9, 0xd5, 0x17, 0xa5, 0xea, 0x7e, 0xb2, 0x32,
+ 0xf1, 0xf7, 0x2d, 0xe3, 0xd1, 0x83, 0x82, 0x5f, 0x3f, 0x17, 0xcb, 0xfb,
+ 0x3f, 0xfd, 0x35, 0x23, 0x97, 0x2f, 0x0e, 0x50, 0x4f, 0x15, 0xcb, 0xee,
+ 0xc6, 0xce, 0x5d, 0x1e, 0x39, 0x53, 0x9a, 0xd5, 0x8b, 0xd9, 0x87, 0x2b,
+ 0x0d, 0x9f, 0x88, 0xaf, 0xf4, 0x90, 0x71, 0x80, 0xe9, 0xcb, 0xff, 0x67,
+ 0xb7, 0xd4, 0x63, 0xe6, 0x8e, 0x54, 0x1f, 0x78, 0x99, 0x5f, 0xb3, 0x96,
+ 0x7f, 0xe3, 0x97, 0xdc, 0xbd, 0x1c, 0x4e, 0x5f, 0x63, 0x33, 0xc7, 0x2f,
+ 0x79, 0xd5, 0x39, 0x7c, 0xec, 0x79, 0x8e, 0x5f, 0x85, 0xfd, 0xf6, 0xce,
+ 0x5f, 0xff, 0xf9, 0xe6, 0x04, 0x80, 0xbe, 0x5d, 0x4f, 0x7a, 0x3e, 0x89,
+ 0xe3, 0x67, 0x2f, 0xc2, 0xed, 0x73, 0xcc, 0x72, 0xfa, 0x6d, 0xc7, 0x8e,
+ 0x52, 0xd1, 0x81, 0x33, 0x88, 0x0b, 0x2f, 0xff, 0xf9, 0xac, 0x5d, 0xf8,
+ 0xc4, 0xbb, 0x1a, 0x9e, 0x3d, 0xb7, 0x91, 0xcb, 0xc9, 0xf4, 0xc7, 0x2f,
+ 0x81, 0xc3, 0xb1, 0x0e, 0x5f, 0xb3, 0x27, 0x06, 0xce, 0x5f, 0x68, 0x53,
+ 0xf3, 0x97, 0xc8, 0xb7, 0xd1, 0xcb, 0xa3, 0xf3, 0x97, 0xc0, 0x9c, 0x1c,
+ 0xfa, 0x6e, 0x14, 0x21, 0xa4, 0x44, 0xbf, 0x56, 0xae, 0x6b, 0xfc, 0xe5,
+ 0xf9, 0xe3, 0xec, 0x59, 0xcb, 0xfe, 0xeb, 0xef, 0xa9, 0x3b, 0x89, 0xcb,
+ 0xe7, 0x9d, 0x49, 0x1c, 0xae, 0x19, 0x74, 0x9e, 0x21, 0x03, 0x28, 0x47,
+ 0x84, 0x83, 0x0a, 0xbe, 0x26, 0x42, 0x16, 0xb1, 0xd9, 0x88, 0xb5, 0x0e,
+ 0x87, 0x31, 0xfd, 0xab, 0x87, 0x1e, 0xd9, 0x3f, 0xa1, 0x7e, 0x02, 0x26,
+ 0xc6, 0xd4, 0x27, 0xe0, 0x38, 0xbf, 0x84, 0x01, 0x63, 0xc8, 0xe5, 0xe4,
+ 0x9c, 0x07, 0x2f, 0xd1, 0xfa, 0x7d, 0x87, 0x2e, 0x67, 0x13, 0x96, 0x0c,
+ 0x1e, 0x08, 0x94, 0x5f, 0xfe, 0x90, 0xc7, 0x26, 0x0c, 0x2b, 0xe4, 0x9c,
+ 0xe5, 0xf9, 0xd9, 0x9d, 0x61, 0xca, 0xf8, 0xfc, 0xfc, 0x99, 0x7b, 0xda,
+ 0x83, 0x97, 0xfb, 0x7e, 0xe3, 0x83, 0x81, 0x39, 0x7f, 0x66, 0xf2, 0x49,
+ 0xa3, 0x97, 0xbb, 0x1c, 0x4e, 0x5e, 0xdc, 0xa7, 0x39, 0x58, 0x6f, 0x14,
+ 0x1e, 0xa8, 0x54, 0x41, 0x22, 0xdc, 0x5e, 0x48, 0x4c, 0xb0, 0x8d, 0xc7,
+ 0x04, 0xd3, 0xcd, 0x17, 0x9f, 0x92, 0x87, 0x2f, 0x4c, 0x9d, 0x39, 0x7f,
+ 0x46, 0x9e, 0x64, 0xe9, 0xcb, 0xf6, 0xc3, 0x03, 0x3b, 0x9e, 0x56, 0xc7,
+ 0x6f, 0xf6, 0xb2, 0x78, 0xef, 0x60, 0xe5, 0xe6, 0x43, 0x0e, 0x57, 0xc8,
+ 0x8d, 0xd1, 0xf3, 0x0c, 0xef, 0xff, 0x86, 0x5c, 0xb0, 0x29, 0xbf, 0xbc,
+ 0x07, 0xd9, 0xcb, 0xf7, 0x40, 0x31, 0xc4, 0xe5, 0xfc, 0x2f, 0xe9, 0x42,
+ 0xa7, 0x2a, 0x0f, 0x59, 0x42, 0x9b, 0xec, 0xcf, 0xa4, 0x72, 0xf6, 0xd2,
+ 0x63, 0x96, 0x54, 0x4d, 0xfe, 0xc8, 0xaf, 0xfb, 0x49, 0x1e, 0xce, 0x2e,
+ 0x13, 0x97, 0xff, 0x3c, 0xe3, 0x1f, 0x20, 0x46, 0x27, 0x39, 0x5a, 0x45,
+ 0x27, 0x49, 0xc4, 0xe6, 0xfd, 0xcb, 0xb1, 0xa9, 0x1c, 0xae, 0x4a, 0xcb,
+ 0x62, 0x1e, 0xd8, 0x62, 0xb8, 0x54, 0x3c, 0x60, 0xad, 0x97, 0xde, 0x66,
+ 0xe0, 0xe5, 0xfd, 0x3c, 0xd2, 0xe1, 0xb5, 0x39, 0xcb, 0xe6, 0x63, 0xf4,
+ 0xe5, 0xa7, 0x39, 0x7e, 0xf7, 0x51, 0x9a, 0x39, 0x52, 0x37, 0x5a, 0x12,
+ 0xbd, 0xd0, 0xa1, 0xcb, 0xf7, 0x71, 0x25, 0xb3, 0x97, 0xff, 0xdd, 0x85,
+ 0x39, 0xf8, 0x5f, 0xfd, 0xee, 0x3f, 0x29, 0x7e, 0xcf, 0x38, 0x38, 0x73,
+ 0x97, 0xed, 0x2d, 0xdd, 0x67, 0x88, 0x11, 0x7b, 0x71, 0xf1, 0xcb, 0x7f,
+ 0x87, 0xa3, 0xf1, 0xa5, 0xef, 0x24, 0xe7, 0x2f, 0x4e, 0xe2, 0x72, 0xa4,
+ 0x9a, 0xd0, 0x49, 0xfe, 0x54, 0xd3, 0xeb, 0x0a, 0x7c, 0x3b, 0x7f, 0x0a,
+ 0xdd, 0x5e, 0xa1, 0xcb, 0xb8, 0x24, 0x72, 0xfb, 0xd3, 0xb8, 0x9c, 0xbc,
+ 0x2e, 0xa9, 0xcb, 0xfc, 0xae, 0x4e, 0x0f, 0x71, 0xf1, 0xcb, 0xfe, 0x79,
+ 0x6a, 0x27, 0x7d, 0x2c, 0xe5, 0xe5, 0x53, 0xc7, 0x2f, 0x6d, 0xfc, 0x72,
+ 0x95, 0x37, 0x3f, 0x0e, 0xdd, 0xcb, 0xa7, 0x2f, 0xe6, 0x79, 0x02, 0x08,
+ 0x39, 0x79, 0x9e, 0x59, 0xcb, 0x7a, 0x0f, 0x2b, 0x0b, 0x6f, 0xe8, 0x66,
+ 0x2b, 0x1b, 0x39, 0x53, 0xa7, 0xb7, 0x83, 0x4b, 0x22, 0xd0, 0xe3, 0x0e,
+ 0x3a, 0xe5, 0xf9, 0x18, 0xb1, 0xf8, 0x9a, 0xed, 0x00, 0xe5, 0xfe, 0x17,
+ 0x6f, 0x7b, 0x8f, 0xce, 0x5f, 0xf6, 0xb4, 0x9f, 0x4b, 0xcf, 0xf1, 0xcb,
+ 0xcd, 0x1d, 0x53, 0x97, 0xfd, 0x0c, 0x96, 0x4f, 0x80, 0xe1, 0xce, 0x5f,
+ 0xf4, 0x7e, 0x92, 0xea, 0x0f, 0xe7, 0x2d, 0x39, 0xcb, 0x9f, 0xda, 0x3c,
+ 0xbe, 0x1c, 0xe6, 0xb1, 0x1b, 0x48, 0x3e, 0xf0, 0x89, 0xbc, 0xdc, 0x28,
+ 0x72, 0xf3, 0x6d, 0xb6, 0x7a, 0xbe, 0x97, 0x9c, 0x42, 0x5a, 0xbe, 0xae,
+ 0x66, 0xb6, 0xfa, 0x40, 0x85, 0x4e, 0x5b, 0xf3, 0x95, 0x86, 0xd5, 0xc8,
+ 0xea, 0x15, 0x36, 0x04, 0x5d, 0x0d, 0x35, 0x18, 0xaf, 0x4c, 0xbf, 0x4b,
+ 0xf3, 0x85, 0xfe, 0xf7, 0x72, 0x5d, 0x4e, 0x27, 0x2f, 0x99, 0xa0, 0x4e,
+ 0x72, 0xff, 0xf8, 0x51, 0x5e, 0x7b, 0xf7, 0x40, 0xf2, 0x94, 0x1c, 0xa8,
+ 0x3f, 0x6c, 0x24, 0xa9, 0xd3, 0x36, 0x93, 0x5a, 0xb0, 0xab, 0xbe, 0xc0,
+ 0xbc, 0x8e, 0x5f, 0x9c, 0x45, 0x18, 0x72, 0xf6, 0x71, 0x50, 0xe5, 0xc9,
+ 0xd3, 0x97, 0x82, 0xf2, 0x39, 0x7c, 0xec, 0xc6, 0x1c, 0xbe, 0x46, 0x43,
+ 0x59, 0xcb, 0x93, 0x5c, 0x8f, 0x17, 0x08, 0x68, 0x28, 0xa5, 0xc1, 0x6e,
+ 0xb0, 0xdf, 0x91, 0x8e, 0x38, 0x72, 0xb9, 0x32, 0x97, 0x5a, 0xa1, 0xc8,
+ 0x37, 0x92, 0xd8, 0x48, 0x72, 0x37, 0x65, 0x56, 0x52, 0x50, 0x43, 0xce,
+ 0x10, 0xfe, 0x70, 0x24, 0x3b, 0x25, 0x04, 0x31, 0x1a, 0x17, 0xdf, 0xd9,
+ 0xdc, 0x58, 0x30, 0xe5, 0xf9, 0x3d, 0x1e, 0xd9, 0x4b, 0xe5, 0xc7, 0xb6,
+ 0x52, 0xe6, 0xdb, 0x29, 0x52, 0x3e, 0x2c, 0x27, 0x6c, 0x8a, 0xcd, 0x94,
+ 0xe6, 0x6b, 0xef, 0x38, 0xfe, 0x72, 0xb0, 0xf0, 0x15, 0x24, 0xbe, 0x98,
+ 0x5d, 0xb3, 0x97, 0xa6, 0xea, 0x1c, 0xbf, 0xfe, 0xf4, 0x2f, 0x30, 0x7d,
+ 0xd4, 0x81, 0x9c, 0xe5, 0x1c, 0xac, 0x3d, 0x8d, 0xa6, 0xd4, 0xc9, 0xec,
+ 0x7f, 0x0f, 0xd1, 0x22, 0xd9, 0x1b, 0x6e, 0xb7, 0xff, 0x86, 0x3e, 0xff,
+ 0x06, 0x25, 0xad, 0x41, 0xcb, 0xff, 0x7b, 0x78, 0xbe, 0xb8, 0xfb, 0x67,
+ 0x2f, 0x20, 0xfe, 0x73, 0x91, 0xbe, 0xb4, 0x31, 0x16, 0xbc, 0x61, 0x0f,
+ 0x7f, 0xa7, 0x8e, 0xc7, 0x62, 0x73, 0x97, 0x3e, 0xce, 0x5b, 0xb0, 0x79,
+ 0x4e, 0x69, 0x7e, 0x97, 0x41, 0x1a, 0x39, 0x7f, 0xf3, 0xb3, 0x51, 0xc5,
+ 0x38, 0x88, 0x36, 0x72, 0xbe, 0x3e, 0xfe, 0x94, 0x5f, 0xb0, 0x0c, 0x8d,
+ 0x9c, 0xa3, 0x97, 0x64, 0xda, 0x36, 0x5b, 0x27, 0xbf, 0xe4, 0x07, 0x0f,
+ 0xd8, 0x50, 0x67, 0x39, 0x7f, 0xd1, 0x3c, 0x7d, 0xe1, 0xc9, 0xce, 0x56,
+ 0x22, 0x99, 0x65, 0xa8, 0x7f, 0x7f, 0xf2, 0x9b, 0x4d, 0xcc, 0x81, 0xc1,
+ 0xfc, 0xe5, 0xf3, 0x06, 0x3e, 0x39, 0x41, 0x3e, 0x87, 0x46, 0xa9, 0x93,
+ 0xb2, 0xd4, 0x3e, 0xfb, 0x09, 0x6b, 0xec, 0xee, 0x4e, 0x72, 0xf4, 0x9f,
+ 0x47, 0x2f, 0xef, 0xd8, 0xf2, 0xc0, 0x9c, 0xbe, 0xcf, 0x60, 0x4a, 0x5f,
+ 0x3a, 0xbf, 0xb6, 0x72, 0xa4, 0x78, 0xc2, 0x43, 0x7d, 0x02, 0x30, 0x72,
+ 0xa6, 0x46, 0x86, 0x87, 0x3c, 0xe8, 0xa1, 0x0d, 0xf7, 0xfb, 0x66, 0x8e,
+ 0x52, 0xa9, 0xaa, 0xa4, 0x3c, 0xbc, 0x7f, 0x7f, 0xc3, 0x9d, 0xce, 0x5d,
+ 0xc9, 0xce, 0x5f, 0xff, 0xfd, 0xfc, 0x0a, 0xdf, 0xcf, 0xf7, 0xff, 0x79,
+ 0x19, 0xbe, 0xc2, 0x82, 0x72, 0xfe, 0x07, 0x0e, 0x9a, 0xd6, 0x1c, 0xbe,
+ 0xf2, 0xb9, 0xd3, 0x97, 0xfe, 0x1c, 0xf7, 0x81, 0x3f, 0xb1, 0x67, 0x2f,
+ 0xc1, 0x03, 0xea, 0x47, 0x2d, 0xb3, 0x97, 0x27, 0xe7, 0x2e, 0xea, 0x1c,
+ 0xb8, 0x1b, 0xe4, 0x6b, 0x66, 0x17, 0xa7, 0x3e, 0xef, 0xcf, 0xae, 0xfe,
+ 0x0e, 0x5d, 0xfc, 0x1c, 0xbf, 0x02, 0x58, 0x3c, 0xd0, 0xd7, 0x7e, 0x2f,
+ 0x50, 0x9c, 0x3a, 0xa4, 0x68, 0x7f, 0xfc, 0x25, 0x85, 0x42, 0xff, 0xfb,
+ 0x05, 0xfe, 0xda, 0xaa, 0xbf, 0x25, 0xb3, 0xf3, 0x97, 0xff, 0x7b, 0xb8,
+ 0xc5, 0x23, 0xfc, 0xfb, 0xc7, 0x2f, 0xf7, 0xcb, 0x4d, 0x29, 0x01, 0x39,
+ 0x7d, 0xfb, 0x1e, 0x5c, 0x91, 0xa3, 0xb5, 0x5f, 0x23, 0xdc, 0x0f, 0x1c,
+ 0xbf, 0xbf, 0x62, 0x9b, 0x52, 0x73, 0x97, 0xf6, 0xd0, 0x46, 0x3e, 0x39,
+ 0x76, 0x7c, 0x72, 0xbe, 0x3f, 0x6f, 0x19, 0xb4, 0x2c, 0xbe, 0xff, 0x49,
+ 0xa3, 0x95, 0x09, 0x96, 0x49, 0x29, 0xe1, 0x1a, 0xd9, 0x95, 0xe0, 0x7d,
+ 0xe3, 0x96, 0x73, 0x95, 0xb3, 0x5d, 0xe1, 0xeb, 0xb1, 0xb3, 0x97, 0xfd,
+ 0x1f, 0x67, 0xf1, 0xc7, 0x27, 0x39, 0x7f, 0x0e, 0x7b, 0x6f, 0xf9, 0xca,
+ 0xd2, 0x20, 0x3f, 0x17, 0xd9, 0xe5, 0xff, 0x44, 0xfb, 0xd6, 0x2e, 0x27,
+ 0x39, 0x7f, 0xb0, 0x67, 0xc0, 0xbf, 0x4e, 0x54, 0xc7, 0xd8, 0xd9, 0xd5,
+ 0xfd, 0x8c, 0xc0, 0xa3, 0x67, 0x2e, 0x64, 0x1c, 0xa6, 0x1e, 0x1b, 0x96,
+ 0xdf, 0xc3, 0x93, 0x75, 0x3c, 0x72, 0xfb, 0x33, 0xbb, 0x39, 0x58, 0x8d,
+ 0x67, 0x67, 0xf1, 0x0f, 0x01, 0x6d, 0xe6, 0xdb, 0x6c, 0xa5, 0xfb, 0x15,
+ 0x10, 0x6c, 0xa7, 0x33, 0x41, 0x7d, 0xcd, 0xb6, 0xdb, 0x39, 0x76, 0x7e,
+ 0x72, 0xb0, 0xdf, 0xf8, 0xa2, 0xa1, 0x13, 0x3e, 0x79, 0xbf, 0xfe, 0x49,
+ 0x3e, 0xd8, 0xc7, 0x93, 0xab, 0xd4, 0x39, 0x7c, 0x9a, 0xff, 0x67, 0x2f,
+ 0xfb, 0x7a, 0x80, 0x78, 0x53, 0x89, 0xcb, 0xff, 0x0e, 0x6d, 0x7d, 0x45,
+ 0xc0, 0x9c, 0xbf, 0xff, 0xca, 0xb6, 0xfa, 0x57, 0x9e, 0xf2, 0x42, 0x07,
+ 0xde, 0x09, 0xca, 0x84, 0x6d, 0x61, 0xd2, 0x1e, 0x5f, 0xda, 0x02, 0xfa,
+ 0x9b, 0x39, 0x7c, 0xdb, 0x8c, 0x8e, 0x5f, 0xf7, 0xa3, 0xef, 0xdf, 0xbd,
+ 0x43, 0x96, 0xe9, 0xca, 0xc3, 0xcb, 0x59, 0xd5, 0xf6, 0xd1, 0x90, 0x72,
+ 0xfc, 0x39, 0xe8, 0xd1, 0xcb, 0xcd, 0xb6, 0xd9, 0x4b, 0xf3, 0xab, 0xd4,
+ 0xf1, 0x4e, 0x66, 0x82, 0xa1, 0x10, 0x08, 0x8d, 0x7b, 0x8c, 0x30, 0xe5,
+ 0xef, 0x23, 0x67, 0x2f, 0x6d, 0xf4, 0x72, 0xbe, 0x37, 0x3e, 0x1d, 0xbd,
+ 0xd8, 0x09, 0xca, 0xc4, 0x4a, 0xa2, 0xbb, 0x91, 0x5f, 0xb3, 0xfc, 0xc9,
+ 0x8e, 0x5b, 0x7c, 0x93, 0xcd, 0xf8, 0x87, 0x50, 0xa1, 0xec, 0x2d, 0x84,
+ 0xb6, 0xd2, 0x0a, 0xa9, 0x7c, 0x94, 0x75, 0x5c, 0x32, 0xaf, 0x60, 0x4a,
+ 0xc5, 0xbf, 0x70, 0xfd, 0x89, 0xc0, 0x72, 0xff, 0xe4, 0xf4, 0x6b, 0x07,
+ 0xce, 0xe2, 0x72, 0xa6, 0x5c, 0xbf, 0xec, 0x3f, 0x46, 0x59, 0x18, 0x0c,
+ 0x78, 0x97, 0x5e, 0x8e, 0x30, 0x72, 0xb1, 0x76, 0x19, 0x27, 0x43, 0x85,
+ 0x6e, 0xf0, 0xc7, 0x13, 0x97, 0xff, 0x6a, 0x17, 0xd1, 0x7f, 0x0c, 0x36,
+ 0x72, 0xee, 0x1d, 0x0e, 0x5c, 0x9d, 0x39, 0x53, 0x9b, 0x1d, 0x0d, 0xd4,
+ 0x22, 0x59, 0xdd, 0x2f, 0xbd, 0xb0, 0x35, 0x9c, 0xbf, 0xd0, 0x32, 0x14,
+ 0x8f, 0x8e, 0x54, 0x36, 0x99, 0x12, 0x8c, 0x1c, 0x2f, 0x39, 0x29, 0x1d,
+ 0x58, 0xe4, 0x56, 0x6d, 0xf1, 0xd2, 0x3a, 0xea, 0x3b, 0x9e, 0xca, 0x4c,
+ 0x77, 0x0f, 0xe1, 0x42, 0x31, 0xb9, 0xee, 0x1e, 0xfe, 0x9d, 0xa8, 0xe2,
+ 0x70, 0xd2, 0x16, 0x6a, 0x10, 0xf0, 0x13, 0x5f, 0x92, 0x69, 0x20, 0x9c,
+ 0xb9, 0xa9, 0x43, 0x97, 0xfd, 0x37, 0xb8, 0x37, 0x13, 0x03, 0x47, 0x2f,
+ 0xf0, 0x60, 0x59, 0x01, 0x83, 0x95, 0x07, 0xe0, 0xe7, 0xf7, 0xff, 0x08,
+ 0xbf, 0xde, 0xec, 0x2f, 0x26, 0x39, 0x7f, 0x4f, 0x02, 0x8c, 0xc3, 0x97,
+ 0xff, 0x62, 0x76, 0x03, 0xd0, 0x47, 0xdb, 0x39, 0x78, 0x2a, 0xfe, 0x72,
+ 0xfc, 0xcd, 0x69, 0xfc, 0x72, 0xb9, 0x1e, 0x3c, 0x0f, 0xdf, 0xfd, 0x33,
+ 0xaf, 0xb1, 0x2f, 0x0e, 0x30, 0xe5, 0xfd, 0xac, 0x11, 0x79, 0xce, 0x52,
+ 0xcf, 0xc1, 0x11, 0x2f, 0xfe, 0x86, 0xfe, 0x96, 0xf9, 0x67, 0x70, 0x4e,
+ 0x5f, 0xff, 0x23, 0x3e, 0x96, 0xf9, 0x60, 0x8e, 0x27, 0xe7, 0x2f, 0x27,
+ 0x40, 0x72, 0xb9, 0x2b, 0x35, 0x6a, 0x89, 0xe5, 0x08, 0xbc, 0x20, 0x44,
+ 0x4d, 0x16, 0x76, 0x11, 0x6f, 0x09, 0x31, 0x21, 0xf2, 0x3f, 0x15, 0x1b,
+ 0x73, 0x6a, 0xa5, 0x06, 0x5c, 0x35, 0x30, 0x8f, 0xe1, 0x21, 0xb6, 0xd5,
+ 0xc6, 0x93, 0xc3, 0x42, 0x93, 0x85, 0xe3, 0x6c, 0x6a, 0x31, 0x91, 0xb5,
+ 0x03, 0xbe, 0x15, 0x0a, 0x18, 0xad, 0x1f, 0x27, 0x9e, 0xf5, 0x95, 0x33,
+ 0x30, 0x34, 0xde, 0xec, 0xbc, 0x86, 0x75, 0x67, 0x16, 0xd7, 0x58, 0x24,
+ 0x7d, 0x4c, 0xdf, 0x4a, 0x71, 0xf3, 0x5c, 0x79, 0xb3, 0x56, 0x24, 0x1a,
+ 0xac, 0xb3, 0x99, 0x4b, 0xba, 0xed, 0xa1, 0x4a, 0x7b, 0x49, 0x25, 0xfd,
+ 0x36, 0x0f, 0x87, 0x8c, 0x84, 0x6b, 0xf6, 0xbd, 0xde, 0x6d, 0x17, 0xad,
+ 0x7c, 0xb0, 0x27, 0xac, 0x38, 0xcb, 0x48, 0x6e, 0x5d, 0x03, 0x4a, 0x56,
+ 0x32, 0x95, 0xbc, 0x1f, 0x04, 0xe3, 0xed, 0x73, 0x94, 0x20, 0x87, 0x2d,
+ 0x41, 0xa1, 0x57, 0x99, 0x9e, 0x39, 0x7f, 0x9d, 0x91, 0xe4, 0xda, 0x1c,
+ 0xbf, 0x66, 0x94, 0xf6, 0xce, 0x5b, 0x9f, 0xe7, 0xec, 0x23, 0x9b, 0x31,
+ 0xbf, 0xdc, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0xe3, 0x5f, 0xee, 0x79, 0xa5,
+ 0xbb, 0xac, 0xd1, 0x75, 0xaf, 0xfe, 0xe6, 0xf2, 0xe7, 0x9a, 0x5b, 0xba,
+ 0xcd, 0x12, 0x8a, 0xa2, 0x50, 0xb8, 0x4c, 0xa1, 0x4e, 0x12, 0xa5, 0x61,
+ 0x26, 0xb2, 0x94, 0x95, 0x04, 0xd7, 0x09, 0xc7, 0xd4, 0x21, 0x3b, 0xfc,
+ 0x2d, 0x36, 0x6f, 0xe4, 0x1e, 0x04, 0x1b, 0xff, 0xdc, 0xd8, 0xf2, 0xe7,
+ 0x9a, 0x5b, 0xba, 0xcd, 0x12, 0xd2, 0xff, 0xb8, 0x5b, 0xa8, 0xd6, 0xf1,
+ 0xf7, 0x01, 0xcb, 0xf6, 0x96, 0xee, 0xb3, 0x44, 0x6e, 0xbf, 0xe4, 0xd2,
+ 0x70, 0xeb, 0xec, 0x36, 0x72, 0xff, 0xff, 0xfb, 0x88, 0xe6, 0xf6, 0x18,
+ 0xcd, 0x2d, 0xdd, 0x7c, 0xe4, 0x9e, 0x8f, 0x6c, 0xd1, 0x87, 0xad, 0xd8,
+ 0x46, 0x52, 0x1f, 0x5f, 0xb5, 0x0d, 0xb0, 0x27, 0x2f, 0xfc, 0xf2, 0xe7,
+ 0x9a, 0x5b, 0xba, 0xcd, 0x12, 0xfa, 0xfe, 0x8f, 0x29, 0xd7, 0xf1, 0xcb,
+ 0xf9, 0x4d, 0x2b, 0xd0, 0x6c, 0xe5, 0xe8, 0xd4, 0x1c, 0xac, 0x3c, 0xc4,
+ 0x31, 0xbf, 0xee, 0xe2, 0x6a, 0x5d, 0x46, 0xce, 0x5f, 0x03, 0xa9, 0xa3,
+ 0x97, 0xa6, 0xde, 0x8e, 0x5b, 0x9b, 0x50, 0x55, 0xe7, 0x88, 0xcb, 0x87,
+ 0xf6, 0x89, 0xd8, 0x53, 0xd4, 0xc1, 0x7a, 0xf1, 0x03, 0x43, 0x95, 0x08,
+ 0xaf, 0xff, 0x7d, 0x2f, 0x24, 0xdc, 0xc2, 0x9c, 0x60, 0x27, 0x2f, 0xf7,
+ 0x3c, 0xd2, 0xdd, 0xd6, 0x68, 0xaa, 0xd7, 0x27, 0x01, 0xcb, 0xb3, 0x47,
+ 0x2f, 0x91, 0x8f, 0xc4, 0xe5, 0x2a, 0x7a, 0x4e, 0x33, 0xe1, 0x6b, 0xc3,
+ 0xc0, 0xd9, 0xcb, 0xfb, 0xb1, 0xc4, 0x01, 0xc3, 0x97, 0xf3, 0xf6, 0x61,
+ 0x80, 0x9c, 0xbf, 0xfb, 0xdd, 0x8d, 0x8b, 0x83, 0x87, 0x4d, 0x1c, 0xbd,
+ 0x12, 0xc3, 0x95, 0x24, 0x5f, 0x84, 0xbf, 0xe2, 0xd9, 0x92, 0x2f, 0xf9,
+ 0x5c, 0x1c, 0xfb, 0xce, 0xc3, 0x97, 0xb8, 0x23, 0xc7, 0x2f, 0xf6, 0xa1,
+ 0x8a, 0x40, 0xac, 0xe5, 0xef, 0x9f, 0xe3, 0x97, 0xcf, 0xe7, 0xf8, 0xe5,
+ 0xc1, 0x43, 0x97, 0xf6, 0x69, 0x6e, 0xeb, 0x34, 0x48, 0x0a, 0xe4, 0x79,
+ 0xfc, 0xc5, 0xaf, 0xdb, 0x71, 0x7f, 0x8e, 0x5c, 0x08, 0x39, 0x52, 0x3e,
+ 0x3f, 0x89, 0xb4, 0x4f, 0x7f, 0xa5, 0x1a, 0x9e, 0x35, 0x39, 0xcb, 0xfd,
+ 0xa9, 0xd9, 0x03, 0x2d, 0x9c, 0xa8, 0x3e, 0x9c, 0x35, 0xbd, 0x3b, 0x84,
+ 0xe5, 0xfe, 0x5a, 0x63, 0x60, 0x1f, 0x1c, 0xac, 0x3d, 0x0f, 0x87, 0x6e,
+ 0xe1, 0x3a, 0x72, 0xff, 0xf6, 0x4d, 0xd7, 0x67, 0xbb, 0x1e, 0x03, 0x0e,
+ 0x54, 0xeb, 0x8b, 0x81, 0x2f, 0xc8, 0x6f, 0xaa, 0x7e, 0xd6, 0x73, 0x30,
+ 0xfb, 0x0c, 0xfa, 0x3c, 0xf0, 0xd4, 0x18, 0x4c, 0xf9, 0xc1, 0xa1, 0x12,
+ 0x83, 0x97, 0xe8, 0x11, 0xcf, 0x1c, 0xbe, 0xd6, 0x91, 0x67, 0x2f, 0x87,
+ 0x27, 0xe6, 0xd0, 0xf1, 0xd4, 0x25, 0xbf, 0xdc, 0xfa, 0xec, 0xc8, 0x09,
+ 0xca, 0xe6, 0x9c, 0x1e, 0xa3, 0x11, 0x68, 0x7d, 0x7f, 0xb9, 0xe6, 0x96,
+ 0xee, 0xb3, 0x45, 0x90, 0xbf, 0xdc, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0xd7,
+ 0x5f, 0xfe, 0xc5, 0x22, 0x7e, 0x79, 0x37, 0x83, 0x02, 0x72, 0xff, 0x73,
+ 0xcd, 0x2d, 0xdd, 0x66, 0x8b, 0x91, 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0xbb,
+ 0x17, 0xfe, 0x79, 0x73, 0xcd, 0x2d, 0xdd, 0x66, 0x8a, 0x39, 0x6e, 0x78,
+ 0x88, 0x06, 0x1a, 0x5f, 0x0c, 0x49, 0x87, 0x2f, 0xfd, 0xc3, 0x70, 0x8c,
+ 0x8d, 0x4b, 0x13, 0x89, 0xcb, 0x48, 0xe5, 0xfb, 0x4b, 0x77, 0x59, 0xa2,
+ 0x95, 0x5f, 0xf2, 0xfa, 0x93, 0x76, 0x27, 0xc3, 0x97, 0xff, 0xbb, 0x13,
+ 0xc7, 0x53, 0x8b, 0x87, 0xa8, 0x73, 0x99, 0xba, 0xba, 0x5c, 0xf1, 0x19,
+ 0x73, 0x37, 0x57, 0xc9, 0x86, 0xbc, 0x37, 0x2f, 0xfc, 0xe9, 0xe9, 0x00,
+ 0x2e, 0x3f, 0x9c, 0xb7, 0x30, 0xa7, 0xbf, 0xf1, 0x0b, 0x23, 0x57, 0xe9,
+ 0x4d, 0x4e, 0xce, 0xd1, 0x94, 0xb4, 0xdc, 0x85, 0x0f, 0xca, 0x09, 0x3c,
+ 0xe4, 0xc3, 0xbf, 0xd0, 0x45, 0x07, 0x69, 0xbe, 0x86, 0x0f, 0x19, 0x41,
+ 0x37, 0xfd, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x1c, 0x2f, 0xf9, 0x39,
+ 0xe6, 0x96, 0xee, 0xb3, 0x45, 0x6a, 0xb7, 0x37, 0x44, 0x6f, 0x91, 0xef,
+ 0xff, 0x73, 0x63, 0xcb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x4b, 0x6b, 0xc0,
+ 0xd7, 0xe7, 0x2e, 0xcf, 0x8e, 0x5f, 0xe0, 0xe3, 0x19, 0x09, 0xb3, 0x97,
+ 0xb8, 0x82, 0x47, 0x29, 0x68, 0x86, 0xf8, 0x79, 0x05, 0xf8, 0x99, 0x5e,
+ 0xe8, 0x64, 0x72, 0xff, 0xb3, 0xe1, 0xcf, 0xff, 0x79, 0x1c, 0xb9, 0x8b,
+ 0x39, 0x7f, 0xb1, 0x3e, 0xd8, 0x70, 0x4e, 0x54, 0x22, 0x0e, 0x47, 0x5a,
+ 0x17, 0xbe, 0x18, 0xfa, 0x47, 0x2f, 0xe9, 0xe1, 0x6f, 0xaf, 0xce, 0x5f,
+ 0xff, 0x9f, 0xef, 0xc3, 0xd7, 0x96, 0x6c, 0x40, 0xea, 0x1c, 0xbe, 0xff,
+ 0x35, 0x31, 0xca, 0x5a, 0x33, 0x34, 0x45, 0xd2, 0xff, 0xd5, 0xec, 0xa9,
+ 0xcb, 0xf9, 0x34, 0x29, 0xed, 0x9c, 0xbf, 0x69, 0xc7, 0x20, 0xe5, 0x1a,
+ 0x21, 0xb2, 0x1f, 0x1f, 0x44, 0x9c, 0xb2, 0xe8, 0x13, 0x97, 0xb1, 0x02,
+ 0x72, 0xf0, 0x71, 0x87, 0x2e, 0x41, 0x09, 0xb7, 0x41, 0xba, 0x83, 0xf6,
+ 0x92, 0x65, 0xf6, 0x4d, 0x2c, 0x39, 0x7f, 0xe7, 0x97, 0x3c, 0xd2, 0xdd,
+ 0xd6, 0x68, 0x98, 0x17, 0x9b, 0x4f, 0xce, 0x5f, 0x6d, 0xc7, 0xf3, 0x95,
+ 0x31, 0xe0, 0x7e, 0x3d, 0x7f, 0x81, 0xf6, 0x92, 0x19, 0x87, 0x2f, 0xdd,
+ 0x48, 0x19, 0xce, 0x5f, 0xf4, 0x4f, 0xe1, 0x80, 0x7b, 0x67, 0x2d, 0xee,
+ 0xa2, 0x4f, 0x66, 0x6d, 0x09, 0xef, 0xbe, 0x5a, 0x2a, 0x72, 0xb0, 0xf7,
+ 0x3c, 0x71, 0x7f, 0x27, 0xb1, 0x91, 0xd3, 0x97, 0xff, 0x46, 0x93, 0xf9,
+ 0xfb, 0x1b, 0x06, 0xce, 0x56, 0x8f, 0xcb, 0xc5, 0x97, 0xfe, 0xc6, 0x66,
+ 0xb3, 0xe9, 0x67, 0x8e, 0x5f, 0xc9, 0xd4, 0x66, 0x2a, 0x72, 0xba, 0x7d,
+ 0x7b, 0x3e, 0xbf, 0xfc, 0xf3, 0xf5, 0x20, 0x72, 0x64, 0xd2, 0x1c, 0xac,
+ 0x47, 0xbf, 0xa1, 0x1a, 0xd9, 0x15, 0xcb, 0xc3, 0x97, 0x03, 0xf2, 0x94,
+ 0x86, 0xbb, 0x42, 0xd7, 0xe5, 0x62, 0x58, 0x13, 0x97, 0xfb, 0x02, 0x39,
+ 0xee, 0xe1, 0xcb, 0xb8, 0x65, 0x9e, 0x30, 0xa5, 0xf9, 0x46, 0x8e, 0x3f,
+ 0x9c, 0xbf, 0xb3, 0xae, 0xa0, 0xf8, 0xe5, 0x4e, 0x7b, 0x01, 0x2b, 0xbf,
+ 0xb3, 0xde, 0x8d, 0x6c, 0xe5, 0xfc, 0xe3, 0xfc, 0xff, 0xf8, 0xe5, 0x42,
+ 0x20, 0x04, 0x8d, 0xa1, 0x6d, 0xb9, 0xc3, 0x22, 0xae, 0x73, 0xf0, 0xc2,
+ 0x83, 0x21, 0xf6, 0xb8, 0x50, 0xfd, 0x0b, 0x7d, 0x10, 0xb0, 0x89, 0xe1,
+ 0x18, 0x31, 0x89, 0xee, 0x38, 0xaf, 0x31, 0x80, 0x83, 0x89, 0x43, 0x66,
+ 0x2a, 0x46, 0x03, 0x79, 0x80, 0xd1, 0x4b, 0xff, 0x3c, 0xb9, 0xe6, 0x96,
+ 0xee, 0xb3, 0x44, 0xc6, 0xbe, 0x8d, 0x47, 0x01, 0xcb, 0x73, 0x44, 0x46,
+ 0xb0, 0x77, 0xa9, 0x97, 0xfc, 0x14, 0xe3, 0xcf, 0xef, 0xd4, 0x91, 0xcb,
+ 0xe8, 0x9e, 0x34, 0x72, 0xf7, 0xa2, 0x63, 0x97, 0xec, 0x89, 0x91, 0x87,
+ 0x29, 0x0f, 0x9a, 0x62, 0x2d, 0x0e, 0xdf, 0xc1, 0x64, 0x67, 0xb6, 0x72,
+ 0xff, 0x76, 0x35, 0x3a, 0x80, 0xfc, 0xe5, 0xf0, 0x27, 0x71, 0x39, 0x73,
+ 0xec, 0xe5, 0xf7, 0x2f, 0x67, 0x4e, 0x5a, 0x3a, 0x6e, 0xb6, 0x2d, 0x7a,
+ 0x06, 0x73, 0x97, 0xff, 0xff, 0xd2, 0xdf, 0x70, 0x0d, 0xef, 0xb8, 0xbc,
+ 0xdf, 0x2c, 0xfa, 0x5b, 0x41, 0x43, 0x97, 0x9d, 0xd6, 0x68, 0xac, 0x57,
+ 0xce, 0xa4, 0x2a, 0x72, 0x96, 0x79, 0x7a, 0x28, 0xbf, 0xf3, 0x4c, 0xf0,
+ 0xe0, 0x20, 0x7c, 0x72, 0xff, 0x0e, 0x6f, 0xfc, 0xc0, 0x9c, 0xa5, 0x53,
+ 0x9f, 0x59, 0x37, 0xc3, 0x9a, 0x86, 0x5f, 0x88, 0xb8, 0x9f, 0x5f, 0xfc,
+ 0xa8, 0x3d, 0xb1, 0xce, 0x23, 0x9b, 0x39, 0x7f, 0xf0, 0xf9, 0x50, 0x40,
+ 0xe2, 0xe3, 0x47, 0x2f, 0xf6, 0xa7, 0xf6, 0xdf, 0xe5, 0x9c, 0xa8, 0x3f,
+ 0x97, 0x43, 0xbf, 0xe9, 0x67, 0xb0, 0x61, 0xb6, 0x87, 0x2f, 0xdc, 0x1e,
+ 0xcf, 0xa6, 0x39, 0x7f, 0xff, 0xff, 0x9f, 0xde, 0xce, 0xed, 0xe4, 0x83,
+ 0xe9, 0x66, 0xb3, 0x79, 0xd7, 0x9c, 0x62, 0x47, 0x2a, 0x11, 0x71, 0xb2,
+ 0xdb, 0xf8, 0x0d, 0x17, 0xd4, 0xe1, 0xce, 0x5f, 0xd9, 0xbf, 0xa5, 0x1d,
+ 0x39, 0x74, 0x71, 0x39, 0x5d, 0x3c, 0x61, 0x2e, 0xbf, 0xd3, 0x3e, 0x24,
+ 0x94, 0x61, 0xca, 0x09, 0xea, 0xa1, 0x0d, 0xff, 0x47, 0xd2, 0x9a, 0x4f,
+ 0xa9, 0xce, 0x54, 0x26, 0x5b, 0x90, 0xd0, 0x42, 0x1b, 0xd1, 0x2f, 0x1c,
+ 0xbf, 0xf6, 0x07, 0x48, 0x09, 0xff, 0xdc, 0x8e, 0x5f, 0x31, 0xfe, 0xf1,
+ 0xcb, 0xff, 0xa7, 0x8f, 0x72, 0x51, 0x6a, 0x70, 0x29, 0xb3, 0x97, 0xfd,
+ 0xa8, 0xdb, 0xe8, 0x62, 0x47, 0x2b, 0x48, 0x86, 0xe2, 0x9f, 0x7a, 0x4f,
+ 0x39, 0xcb, 0xdc, 0xa7, 0x61, 0xcb, 0x83, 0xe3, 0x95, 0xc3, 0x26, 0x45,
+ 0x90, 0xa9, 0xf8, 0x95, 0x07, 0x44, 0x82, 0xff, 0xc2, 0xe1, 0xec, 0x71,
+ 0xeb, 0x89, 0xcb, 0xff, 0xff, 0x02, 0x7c, 0x5f, 0x21, 0x07, 0x07, 0x2c,
+ 0xfa, 0x58, 0x01, 0xff, 0x67, 0x2f, 0xff, 0x4f, 0x9f, 0x7b, 0x68, 0x31,
+ 0xfb, 0xb0, 0xe5, 0xfe, 0xf8, 0x70, 0x3d, 0x76, 0xce, 0x56, 0x1f, 0xfb,
+ 0xa5, 0xd0, 0x53, 0x53, 0x13, 0xed, 0xc3, 0xd6, 0xfe, 0x9e, 0x69, 0x70,
+ 0xda, 0x9c, 0xe5, 0xf0, 0x8e, 0x78, 0xe5, 0xf9, 0x1a, 0xf5, 0xa4, 0x39,
+ 0x4d, 0x52, 0x20, 0x60, 0xdf, 0xa4, 0x17, 0xf4, 0xea, 0x34, 0x71, 0xfc,
+ 0xe5, 0xf3, 0x5c, 0x6c, 0x4e, 0x5f, 0xfb, 0xae, 0xcf, 0x76, 0x3c, 0x06,
+ 0x1c, 0xac, 0x3e, 0x39, 0x89, 0x2f, 0xfe, 0xcc, 0x55, 0x90, 0x9a, 0xd2,
+ 0x36, 0x72, 0xff, 0x92, 0x49, 0xd0, 0x31, 0x88, 0x72, 0xec, 0xf1, 0xca,
+ 0x84, 0xd2, 0x72, 0x12, 0xba, 0x22, 0xf2, 0x23, 0x43, 0x8b, 0xc2, 0xfc,
+ 0x07, 0x2f, 0x75, 0x39, 0xc3, 0x30, 0x22, 0x72, 0xf9, 0x16, 0x84, 0xdf,
+ 0x23, 0xfb, 0x55, 0x85, 0x70, 0xbf, 0xf8, 0x83, 0x50, 0xf2, 0xec, 0x69,
+ 0xee, 0x66, 0x23, 0x9b, 0x8d, 0x8f, 0xd1, 0xd3, 0x34, 0x85, 0xb2, 0x91,
+ 0xbe, 0xf0, 0x28, 0x5e, 0xe1, 0x66, 0x8d, 0x51, 0xcb, 0xa4, 0x27, 0x2f,
+ 0xed, 0x6a, 0x03, 0x8c, 0x39, 0x7d, 0x3e, 0xa2, 0x73, 0x97, 0x29, 0xf9,
+ 0xcb, 0xbf, 0xd9, 0xcb, 0xdd, 0x46, 0x1c, 0xb4, 0xc7, 0x29, 0x0f, 0x19,
+ 0xc6, 0x00, 0x39, 0x7e, 0x71, 0x9c, 0x1b, 0x39, 0x7f, 0xd0, 0x1e, 0xe0,
+ 0x74, 0xeb, 0x39, 0x48, 0x99, 0xeb, 0x96, 0xfe, 0x48, 0x2b, 0xfb, 0x2d,
+ 0xf1, 0x45, 0xba, 0x72, 0xf6, 0xd4, 0xd9, 0xcb, 0xef, 0xa7, 0x85, 0x4e,
+ 0x54, 0xe7, 0xa8, 0x11, 0x10, 0x0f, 0x5d, 0xe8, 0x39, 0x7f, 0xbe, 0xd4,
+ 0x24, 0x9f, 0x67, 0x2f, 0xb0, 0x62, 0x47, 0x2b, 0x0f, 0x4d, 0x86, 0x76,
+ 0x68, 0x72, 0xff, 0x67, 0xfb, 0xcf, 0x26, 0x8e, 0x5f, 0x03, 0xd9, 0xb3,
+ 0x97, 0x0b, 0x59, 0xcb, 0xda, 0x71, 0x39, 0x6f, 0x8e, 0x54, 0x1a, 0xd0,
+ 0x0d, 0xdf, 0xb3, 0x52, 0x86, 0x1c, 0xbf, 0xcf, 0xa9, 0x7e, 0x9f, 0x6c,
+ 0xe5, 0xf6, 0xf7, 0x1f, 0x9c, 0xa8, 0x4d, 0xb8, 0x24, 0x38, 0x26, 0x86,
+ 0x6c, 0x22, 0xea, 0x33, 0x90, 0x00, 0x9d, 0xb3, 0x5b, 0xf9, 0x04, 0x73,
+ 0x8b, 0x9c, 0xbd, 0x25, 0x3c, 0x72, 0xfa, 0x5f, 0x82, 0x47, 0x2f, 0xb4,
+ 0xa4, 0x7e, 0x72, 0xa0, 0xf2, 0x10, 0x92, 0xff, 0x24, 0xee, 0xcf, 0xff,
+ 0x83, 0x97, 0x20, 0x4e, 0x5f, 0xf2, 0x2f, 0xb9, 0x30, 0xc0, 0x4e, 0x5f,
+ 0x4b, 0xd8, 0xa1, 0xcb, 0xcb, 0x8f, 0xce, 0x5e, 0xd4, 0x30, 0xe5, 0x39,
+ 0xee, 0x00, 0x8d, 0xb1, 0xdb, 0xe9, 0xd4, 0xc9, 0x8e, 0x5e, 0x8d, 0x4e,
+ 0x72, 0xa0, 0xf0, 0x90, 0x96, 0xf4, 0x0c, 0x8e, 0x5f, 0x78, 0x53, 0x80,
+ 0xe5, 0x05, 0x53, 0x0f, 0xc5, 0x93, 0x33, 0x68, 0x81, 0x86, 0xbd, 0x16,
+ 0x18, 0x4a, 0x6d, 0xc7, 0xc4, 0x00, 0x1b, 0xbf, 0xdd, 0x79, 0x70, 0x70,
+ 0x02, 0x73, 0x97, 0x75, 0xa1, 0xcb, 0xff, 0x46, 0x6f, 0x94, 0x20, 0x54,
+ 0x91, 0xcb, 0xf9, 0x1b, 0xdc, 0xf8, 0xd9, 0xca, 0x13, 0xf0, 0xf2, 0x05,
+ 0xfa, 0x03, 0xec, 0x59, 0xcb, 0xd0, 0x2b, 0x39, 0x7f, 0xff, 0x3b, 0x61,
+ 0x77, 0xd4, 0xfd, 0x7f, 0x75, 0x35, 0x23, 0x95, 0xd3, 0xf7, 0x11, 0xba,
+ 0x92, 0x38, 0x36, 0x43, 0xe8, 0x4f, 0x5f, 0x38, 0xbc, 0xc7, 0x2f, 0xc9,
+ 0xe1, 0xc9, 0x1c, 0xbe, 0x86, 0xe2, 0x63, 0x97, 0x28, 0xc3, 0x97, 0xf7,
+ 0x85, 0xff, 0xc1, 0x39, 0x7e, 0x17, 0xff, 0x04, 0xe5, 0x81, 0xc8, 0xf4,
+ 0xbc, 0x59, 0x53, 0xa3, 0xf9, 0x52, 0x14, 0x26, 0xe9, 0x18, 0xb5, 0x5f,
+ 0xe8, 0x6c, 0x20, 0x7d, 0x48, 0xe5, 0xfc, 0x9a, 0xfb, 0x71, 0x23, 0x96,
+ 0xe2, 0x72, 0xb4, 0x7e, 0xbd, 0x34, 0xe0, 0x2e, 0xbc, 0x28, 0xa9, 0xcb,
+ 0xec, 0x0a, 0x71, 0x39, 0x74, 0x33, 0x0d, 0xfb, 0x8e, 0x5f, 0xf6, 0x36,
+ 0xff, 0x76, 0x14, 0x13, 0x96, 0xd9, 0xca, 0x43, 0xf5, 0xd1, 0x53, 0x9d,
+ 0x5b, 0xe3, 0x97, 0x7f, 0x05, 0x2e, 0x6d, 0xb2, 0x94, 0x86, 0xc1, 0xb1,
+ 0x7b, 0xfa, 0x43, 0x9e, 0xea, 0x14, 0xe6, 0x68, 0x68, 0x28, 0xa1, 0x76,
+ 0x3b, 0xdd, 0x86, 0xce, 0x5e, 0x7f, 0xb6, 0x72, 0xdb, 0x39, 0x7c, 0xa7,
+ 0x5f, 0xc7, 0x2a, 0x73, 0xee, 0x08, 0xef, 0xc3, 0xbe, 0x11, 0xbd, 0x03,
+ 0x31, 0xcb, 0x86, 0x0e, 0x5a, 0x63, 0x95, 0x31, 0xe1, 0xe8, 0x71, 0xc5,
+ 0x6f, 0xfe, 0x55, 0x05, 0x7b, 0x86, 0x3f, 0xde, 0x39, 0x7b, 0xfc, 0xe0,
+ 0x39, 0x4a, 0x9f, 0x2e, 0x91, 0x6f, 0x99, 0xb0, 0x30, 0xe5, 0x95, 0x39,
+ 0x66, 0x87, 0x2e, 0xd2, 0xa7, 0x2a, 0x0f, 0x81, 0x08, 0xc0, 0x24, 0xa0,
+ 0x9d, 0xff, 0xf7, 0x72, 0x5b, 0x8f, 0x4b, 0x1a, 0xdc, 0x7f, 0x39, 0x7f,
+ 0xc9, 0xee, 0xe7, 0xde, 0x04, 0x1c, 0xbe, 0x52, 0x35, 0xf9, 0xca, 0x91,
+ 0xee, 0xf4, 0xe6, 0xec, 0xd9, 0xca, 0x83, 0x71, 0x22, 0x2a, 0xda, 0x60,
+ 0xfe, 0x87, 0x3d, 0xbf, 0x39, 0x7e, 0x48, 0x64, 0x30, 0xe5, 0xb0, 0xe5,
+ 0x21, 0xf8, 0xb9, 0x4e, 0xc4, 0x9a, 0x13, 0x59, 0x53, 0x95, 0x0a, 0xe6,
+ 0x72, 0x10, 0x29, 0x09, 0x4e, 0xc2, 0x0d, 0xe3, 0xb3, 0xe0, 0x3c, 0xbd,
+ 0xb8, 0x98, 0xe5, 0xfd, 0x81, 0xce, 0x29, 0xa3, 0x94, 0x72, 0xcc, 0x39,
+ 0x5e, 0x2f, 0x38, 0x85, 0xdf, 0x05, 0xdf, 0xe3, 0x97, 0xef, 0xd3, 0x48,
+ 0xa9, 0xcb, 0x9d, 0x53, 0x97, 0x67, 0xc7, 0x2a, 0x64, 0xc0, 0x98, 0x3b,
+ 0xd4, 0xa7, 0x22, 0xfc, 0x88, 0x4a, 0x5a, 0x0b, 0xdd, 0x9a, 0x39, 0x77,
+ 0xa0, 0xe5, 0xfa, 0x3b, 0x9c, 0x5c, 0xe5, 0x30, 0xf5, 0x1c, 0x5b, 0xf1,
+ 0x6b, 0xf9, 0x3d, 0x9d, 0x75, 0x4e, 0x5f, 0xdd, 0x03, 0xcf, 0xd4, 0x39,
+ 0x79, 0xb6, 0xdb, 0x29, 0x7f, 0xc1, 0x89, 0xd4, 0xce, 0xbf, 0xc5, 0x39,
+ 0x9a, 0x0b, 0xb2, 0x73, 0x97, 0xa5, 0x0c, 0x39, 0x41, 0x46, 0x72, 0xd3,
+ 0x91, 0x36, 0x61, 0x7b, 0xd0, 0xc4, 0x39, 0x58, 0x7b, 0x0b, 0x3d, 0xbe,
+ 0x4d, 0x70, 0x04, 0xe5, 0xfb, 0xb1, 0xf3, 0xb5, 0x9c, 0xbf, 0xfe, 0x8f,
+ 0x6c, 0x39, 0xe4, 0xe8, 0x33, 0xef, 0x1c, 0xae, 0x9f, 0xdf, 0x8a, 0xed,
+ 0xa3, 0x97, 0xfb, 0x31, 0x6a, 0x71, 0xee, 0x1c, 0xbf, 0xe8, 0x1f, 0x0e,
+ 0x7a, 0x1b, 0x39, 0x7f, 0xb1, 0xbd, 0xa0, 0xfd, 0x23, 0x94, 0x87, 0xd7,
+ 0xa3, 0x7b, 0xde, 0xd0, 0x0e, 0x5b, 0x67, 0x28, 0x4d, 0x70, 0x07, 0x6f,
+ 0xff, 0xd8, 0x18, 0xcf, 0x94, 0xf2, 0x08, 0x25, 0x9b, 0x39, 0x73, 0x3f,
+ 0x39, 0x73, 0x89, 0xca, 0xe9, 0xad, 0x71, 0x8b, 0xf3, 0x13, 0xdf, 0xb9,
+ 0xca, 0x9d, 0x55, 0x66, 0x42, 0x81, 0xac, 0x8a, 0x61, 0x1d, 0x42, 0x81,
+ 0xd3, 0xc4, 0x83, 0xd0, 0x82, 0x01, 0x05, 0xda, 0x54, 0xe5, 0xf7, 0x7c,
+ 0x93, 0x9c, 0xbf, 0xcb, 0x4d, 0x8e, 0x71, 0x73, 0x97, 0xd1, 0x3b, 0xc8,
+ 0xe5, 0xf7, 0xb7, 0xd4, 0x39, 0x7f, 0x0b, 0xfa, 0x7c, 0x6c, 0xe5, 0x1c,
+ 0xa1, 0x37, 0x3e, 0x2e, 0xa8, 0x3f, 0xbc, 0x5b, 0xbf, 0x64, 0xe3, 0x9f,
+ 0x1c, 0xbe, 0xf2, 0x0e, 0xce, 0x5f, 0x97, 0xcb, 0x3e, 0xf1, 0xca, 0xc3,
+ 0xcc, 0x42, 0x1a, 0x84, 0xef, 0xf0, 0x63, 0xe2, 0x3d, 0x19, 0xf6, 0x13,
+ 0xa2, 0x41, 0xb7, 0x4b, 0xca, 0x01, 0x43, 0x97, 0x85, 0x1a, 0xce, 0x5f,
+ 0x05, 0xa3, 0xaa, 0x72, 0xa0, 0xf0, 0xf0, 0x7a, 0xf7, 0x60, 0x27, 0x2e,
+ 0xd6, 0xce, 0x51, 0xc4, 0x2d, 0xef, 0xf4, 0x0c, 0x9d, 0x98, 0x13, 0x97,
+ 0xde, 0x63, 0x34, 0x72, 0xff, 0xef, 0xe0, 0x56, 0xfe, 0xfd, 0x41, 0x91,
+ 0xcb, 0xd2, 0x4e, 0x9c, 0xbe, 0xf0, 0xe4, 0x8e, 0x5f, 0x03, 0x87, 0xdb,
+ 0x9c, 0xbf, 0x4e, 0x17, 0x76, 0xce, 0x56, 0x1e, 0x80, 0x09, 0xef, 0xff,
+ 0x26, 0xfb, 0x81, 0x1c, 0xe2, 0x39, 0xb3, 0x95, 0x24, 0xe4, 0x55, 0x31,
+ 0xf8, 0x8e, 0x64, 0x6d, 0x0e, 0x0b, 0x8f, 0x88, 0x69, 0xaa, 0x6f, 0x42,
+ 0x78, 0x62, 0xb8, 0x8d, 0x4e, 0x78, 0x55, 0x48, 0xc0, 0x31, 0xeb, 0xe4,
+ 0xad, 0xd5, 0x61, 0x26, 0xb3, 0xbf, 0xa3, 0x69, 0x48, 0xcc, 0xe6, 0x85,
+ 0xfe, 0xa1, 0xcc, 0xc8, 0x67, 0x76, 0x70, 0xa5, 0xe3, 0x6f, 0xfe, 0x17,
+ 0x7c, 0x39, 0x78, 0xc6, 0xa7, 0xb9, 0x59, 0xbe, 0x94, 0xa0, 0x06, 0x8e,
+ 0x2c, 0x4d, 0x90, 0x34, 0x33, 0x52, 0x3a, 0xab, 0xfe, 0xe7, 0xe4, 0xce,
+ 0x0d, 0x82, 0x0e, 0x5f, 0xff, 0xf0, 0x23, 0x9f, 0xb6, 0x9d, 0x74, 0xf6,
+ 0x6b, 0xf6, 0x3c, 0x8e, 0x57, 0x35, 0x4f, 0xf3, 0xc7, 0xb4, 0x13, 0xdb,
+ 0xf6, 0x96, 0xee, 0xb3, 0x45, 0x6e, 0xbf, 0xf3, 0xcb, 0x9e, 0x69, 0x6e,
+ 0xeb, 0x34, 0x4e, 0x0b, 0x73, 0xc4, 0x40, 0x30, 0xd2, 0xee, 0x18, 0x27,
+ 0x2d, 0xd3, 0x96, 0xd9, 0xca, 0x01, 0xa2, 0x68, 0x23, 0x7e, 0xc6, 0xf6,
+ 0x8d, 0x9c, 0xbe, 0x5b, 0xba, 0xcd, 0x16, 0x8a, 0xff, 0xf6, 0x07, 0xae,
+ 0xac, 0xd3, 0x26, 0xc0, 0xc3, 0x95, 0xa3, 0xfb, 0xe9, 0x75, 0xf2, 0xdc,
+ 0x7f, 0x39, 0x7f, 0xd3, 0x63, 0x5e, 0xf5, 0xa7, 0xf1, 0xcb, 0xfa, 0x1c,
+ 0x40, 0x1c, 0x39, 0x7f, 0xf0, 0xe7, 0x1d, 0xe7, 0x70, 0x54, 0x09, 0xcb,
+ 0xfd, 0x9a, 0xff, 0x26, 0x53, 0x67, 0x2c, 0xa9, 0xcb, 0xfe, 0xc8, 0x9f,
+ 0x26, 0xd2, 0x6c, 0xe5, 0x21, 0xe5, 0xcc, 0x25, 0x7f, 0xfe, 0x9e, 0x3d,
+ 0x01, 0xd4, 0x75, 0xf6, 0x39, 0xf9, 0xcb, 0xff, 0x47, 0xce, 0xd7, 0xd1,
+ 0x76, 0xb9, 0xce, 0x5f, 0xfa, 0x35, 0xfe, 0x26, 0x6b, 0xc0, 0x39, 0x50,
+ 0x8d, 0x8e, 0xaa, 0xed, 0x16, 0xd8, 0x14, 0xfb, 0xd1, 0x16, 0x68, 0x40,
+ 0xee, 0x1f, 0x57, 0x23, 0x67, 0x2e, 0x49, 0x1c, 0xbf, 0xdd, 0xe8, 0x15,
+ 0x64, 0x6c, 0xe5, 0xff, 0xf9, 0x36, 0x39, 0xc5, 0xfc, 0x39, 0xbe, 0xbc,
+ 0xc7, 0x2f, 0xd1, 0xed, 0xa9, 0xd3, 0x95, 0x08, 0xc9, 0xc1, 0x69, 0x8d,
+ 0x45, 0x56, 0xfb, 0x3f, 0x7e, 0x9c, 0xbb, 0xbb, 0x39, 0x6e, 0x7c, 0x22,
+ 0xea, 0x0b, 0x56, 0x7d, 0x39, 0x1e, 0x42, 0x91, 0x64, 0x53, 0x11, 0x30,
+ 0xf7, 0xb2, 0x86, 0xb6, 0x9b, 0xe8, 0x70, 0x34, 0x3b, 0x50, 0x8a, 0xf6,
+ 0xd9, 0xb3, 0x97, 0xff, 0xfe, 0xec, 0x7e, 0xc7, 0x97, 0x2f, 0x77, 0x19,
+ 0x8b, 0x8e, 0xc3, 0x0e, 0x5f, 0xc9, 0x3f, 0x27, 0x1f, 0xce, 0x5f, 0x2d,
+ 0xdd, 0x66, 0x8b, 0x69, 0x7f, 0xff, 0x43, 0xfa, 0x3b, 0x1b, 0x44, 0x92,
+ 0x6b, 0x02, 0x72, 0xfe, 0xec, 0x32, 0x10, 0x27, 0x29, 0x13, 0x4f, 0x99,
+ 0xbb, 0x46, 0x1b, 0x2e, 0xf2, 0xbd, 0xff, 0xba, 0x81, 0x79, 0x07, 0xa8,
+ 0xc3, 0x97, 0xfd, 0x98, 0xb6, 0x80, 0xea, 0x68, 0xe5, 0xf4, 0x71, 0xc4,
+ 0x39, 0x66, 0xa4, 0xe5, 0xff, 0xd9, 0xe8, 0x60, 0xba, 0xa3, 0x9f, 0x9c,
+ 0xb7, 0xe7, 0x2a, 0x63, 0xeb, 0x11, 0x6f, 0x21, 0xdf, 0xf8, 0x11, 0xff,
+ 0x62, 0x71, 0xcd, 0x9c, 0xbf, 0xe8, 0x94, 0x6a, 0x78, 0xd4, 0xe7, 0x2f,
+ 0xff, 0xf4, 0x20, 0xbf, 0x81, 0xec, 0x0c, 0x30, 0x3d, 0x8f, 0x8e, 0x5f,
+ 0xff, 0x0a, 0x71, 0x4f, 0x76, 0x3d, 0xb8, 0xe3, 0x07, 0x2b, 0x48, 0xb0,
+ 0x02, 0xfd, 0xce, 0x13, 0x97, 0xfd, 0x1a, 0xe5, 0xb8, 0xeb, 0xa1, 0xcb,
+ 0xfd, 0xd4, 0x79, 0x79, 0x27, 0x39, 0x7e, 0x0c, 0x60, 0xa1, 0xca, 0x6a,
+ 0x57, 0x37, 0xb2, 0x36, 0xc5, 0xa5, 0xcc, 0x7d, 0xa3, 0xa6, 0x42, 0x37,
+ 0xa5, 0xe2, 0x7f, 0xb8, 0x75, 0x78, 0x8d, 0xb1, 0x66, 0x87, 0x2a, 0x19,
+ 0xdf, 0xca, 0xbe, 0x82, 0x01, 0x39, 0x7f, 0xd1, 0xe4, 0x5a, 0x07, 0xe1,
+ 0x39, 0x78, 0x1f, 0x48, 0xe5, 0xfc, 0x2d, 0x13, 0x58, 0xa9, 0xcb, 0xf2,
+ 0x4e, 0xc8, 0x59, 0xcb, 0xf3, 0xfd, 0x25, 0x36, 0x72, 0xff, 0xc9, 0x36,
+ 0xf8, 0xb8, 0xce, 0x00, 0x9c, 0xb7, 0x35, 0x53, 0x47, 0xd1, 0x77, 0x4e,
+ 0x04, 0x7b, 0xc5, 0xfc, 0x4a, 0x14, 0x2a, 0xae, 0x6a, 0xa1, 0x3f, 0x94,
+ 0x29, 0x73, 0x3a, 0x72, 0xfd, 0xa5, 0xbb, 0xac, 0xd1, 0x72, 0xaf, 0xe7,
+ 0x0f, 0x60, 0x67, 0x39, 0x6e, 0x61, 0x3f, 0x8c, 0x17, 0xe9, 0xa5, 0xfb,
+ 0x4b, 0x77, 0x59, 0xa2, 0xed, 0x5e, 0x9f, 0x1b, 0x39, 0x7f, 0xc9, 0x29,
+ 0x20, 0xff, 0x12, 0x39, 0x7c, 0x9a, 0x7f, 0xce, 0x5b, 0x9e, 0x22, 0xb1,
+ 0x86, 0x8e, 0x3d, 0xb3, 0x8a, 0x87, 0xc9, 0x14, 0x9c, 0xaa, 0x54, 0x98,
+ 0xb0, 0xc7, 0x3f, 0x86, 0xea, 0xd3, 0x2b, 0xd2, 0xd0, 0x5b, 0xb5, 0xc2,
+ 0xef, 0xb3, 0xad, 0x63, 0x48, 0x31, 0xdc, 0x29, 0xfd, 0x0e, 0x2b, 0xfd,
+ 0xcf, 0x34, 0xb7, 0x75, 0x9a, 0x2a, 0x75, 0xf8, 0x79, 0xeb, 0x7b, 0x39,
+ 0x74, 0xec, 0x39, 0x7e, 0xf9, 0x8e, 0xe2, 0x72, 0x82, 0x6f, 0xc0, 0x31,
+ 0x6f, 0x1c, 0xbf, 0xe8, 0x79, 0xf9, 0x7d, 0xb8, 0x09, 0xca, 0x43, 0xcd,
+ 0x11, 0x1b, 0xe5, 0xbb, 0xac, 0xd1, 0x5c, 0xaf, 0xf7, 0x3c, 0xd2, 0xdd,
+ 0xd6, 0x68, 0xb3, 0x97, 0x3c, 0x8e, 0x5f, 0xd2, 0xf7, 0xcb, 0x4d, 0x9c,
+ 0xa7, 0x3c, 0x50, 0x0b, 0x5f, 0xc9, 0xbc, 0x17, 0x6c, 0xe5, 0x69, 0x30,
+ 0x1e, 0x97, 0x0c, 0x21, 0xbc, 0x43, 0x7f, 0xfb, 0xd1, 0xbe, 0x40, 0xdf,
+ 0xa2, 0x69, 0x90, 0xe5, 0xfc, 0x8c, 0x9c, 0x1a, 0x91, 0xcb, 0xf3, 0x32,
+ 0x67, 0xfc, 0xe5, 0xf4, 0xfd, 0x7f, 0x1c, 0xa7, 0x3c, 0xc0, 0x14, 0xdf,
+ 0xe8, 0xef, 0x26, 0x35, 0x7c, 0x27, 0x8e, 0x56, 0x26, 0x55, 0xd4, 0xe1,
+ 0x7b, 0xe2, 0x43, 0x7f, 0xc3, 0x0c, 0xd8, 0x24, 0xea, 0x9c, 0xbf, 0x6b,
+ 0x3c, 0x8c, 0x39, 0x7c, 0xe3, 0x01, 0x39, 0x7e, 0x9a, 0x19, 0x0a, 0x1c,
+ 0xba, 0x4c, 0x39, 0x58, 0x78, 0x02, 0x53, 0x7f, 0xfb, 0xa9, 0xcb, 0xae,
+ 0x9e, 0x8c, 0x0a, 0x1c, 0xbf, 0x69, 0x6e, 0xeb, 0x34, 0x48, 0x4b, 0xff,
+ 0xfb, 0x69, 0xa5, 0xf7, 0x39, 0x6b, 0x58, 0xdb, 0x48, 0x61, 0xcb, 0xff,
+ 0x63, 0x31, 0xf5, 0x3f, 0x2f, 0x98, 0x72, 0xff, 0x7d, 0xbf, 0x0c, 0x33,
+ 0x67, 0x2f, 0xff, 0x38, 0xaf, 0x90, 0x45, 0xe5, 0xd7, 0x91, 0xca, 0x43,
+ 0xfe, 0x01, 0xa5, 0xfd, 0x82, 0x9f, 0xee, 0x0e, 0x5b, 0x9c, 0x93, 0xea,
+ 0xc4, 0x9f, 0x8d, 0x3a, 0xc1, 0xfc, 0x30, 0x36, 0x43, 0x72, 0x74, 0xe5,
+ 0xff, 0x9d, 0x49, 0x85, 0x3c, 0x31, 0xf9, 0xca, 0x92, 0x2e, 0xfe, 0x66,
+ 0xf0, 0xb5, 0xff, 0xdd, 0x46, 0x66, 0xf9, 0x7d, 0x2c, 0xf1, 0xcb, 0xe9,
+ 0x75, 0x4d, 0x9c, 0xa8, 0x3e, 0xbc, 0x47, 0xbe, 0x6a, 0xfb, 0x0c, 0x39,
+ 0x7f, 0x77, 0x7b, 0xcd, 0x4e, 0x72, 0xe8, 0x6c, 0xe5, 0xff, 0x7f, 0x81,
+ 0x17, 0xfe, 0x38, 0x9c, 0xac, 0x44, 0x0a, 0x17, 0xb8, 0xbd, 0xe6, 0x71,
+ 0x91, 0xcb, 0xff, 0xdd, 0x8f, 0xd8, 0xf2, 0xdf, 0xb3, 0x18, 0x72, 0xdc,
+ 0xe7, 0x64, 0x5c, 0x05, 0xbb, 0x23, 0x21, 0x48, 0xdb, 0x26, 0x3e, 0xd1,
+ 0xcb, 0x09, 0xfa, 0xc0, 0xf2, 0xb1, 0x46, 0x13, 0x9b, 0x20, 0xf4, 0x2a,
+ 0x00, 0x5a, 0xa0, 0xfd, 0xff, 0xec, 0xfb, 0x98, 0x40, 0xfa, 0x97, 0x5b,
+ 0x73, 0x97, 0xff, 0x73, 0xeb, 0xec, 0x73, 0xde, 0x8f, 0xce, 0x5f, 0xfe,
+ 0xe6, 0xc7, 0x97, 0x3c, 0xd2, 0xdd, 0xd6, 0x68, 0x9f, 0x14, 0xb6, 0x59,
+ 0xba, 0x20, 0xb5, 0xd2, 0x48, 0x75, 0x0e, 0x76, 0x27, 0x75, 0x1a, 0xff,
+ 0xfe, 0x00, 0xba, 0xbc, 0xbc, 0xac, 0x0c, 0xb3, 0xa8, 0xc3, 0x97, 0x27,
+ 0xc7, 0x2f, 0xff, 0xa5, 0x3f, 0x0a, 0x86, 0xae, 0x75, 0xeb, 0x97, 0x2e,
+ 0xb4, 0x39, 0x52, 0x3f, 0xcf, 0xc5, 0xef, 0xff, 0x0c, 0xfd, 0x84, 0xf6,
+ 0xd0, 0x7e, 0x91, 0xcb, 0xff, 0x79, 0x58, 0x19, 0x67, 0x51, 0x87, 0x2f,
+ 0xf9, 0x58, 0x19, 0x67, 0x51, 0x87, 0x2f, 0x80, 0x2e, 0xaf, 0x23, 0xf6,
+ 0xf1, 0xf5, 0xfb, 0x5f, 0xa7, 0x60, 0xe5, 0x30, 0xf8, 0xc0, 0x77, 0x7e,
+ 0xcd, 0x66, 0x4c, 0x72, 0xdc, 0xd8, 0xa9, 0xa3, 0xb0, 0xd9, 0x72, 0x3d,
+ 0xc6, 0x46, 0xa1, 0x15, 0xfb, 0x4b, 0x77, 0x59, 0xa2, 0xb2, 0x5f, 0xf9,
+ 0xe5, 0xcf, 0x34, 0xb7, 0x75, 0x9a, 0x26, 0xe5, 0xb9, 0xe2, 0x20, 0x18,
+ 0x69, 0x4b, 0x4c, 0x25, 0x21, 0xbf, 0x7c, 0xb7, 0x75, 0x9a, 0x25, 0x65,
+ 0xff, 0xf6, 0xa7, 0x18, 0xd3, 0x84, 0x5f, 0x51, 0xc4, 0xe5, 0x68, 0xff,
+ 0x80, 0x5d, 0x7e, 0x18, 0x0b, 0xf4, 0xe5, 0xfe, 0x84, 0x18, 0x94, 0x70,
+ 0x1c, 0xbf, 0x73, 0x63, 0xcb, 0x9e, 0x1f, 0xda, 0x11, 0x6c, 0x9a, 0xff,
+ 0xde, 0xce, 0x79, 0xa4, 0x9d, 0xd8, 0x72, 0xff, 0xf3, 0x52, 0xd5, 0x70,
+ 0x9b, 0xc7, 0x92, 0x66, 0xb0, 0xe5, 0xff, 0x93, 0x60, 0x60, 0xa7, 0x10,
+ 0x39, 0xcb, 0xfa, 0x05, 0xd6, 0xed, 0x67, 0x2a, 0x47, 0xda, 0xc3, 0xfb,
+ 0x83, 0xa3, 0x97, 0xed, 0x2d, 0xdd, 0x66, 0x89, 0x71, 0x7f, 0xc8, 0xf2,
+ 0xf0, 0xc3, 0x36, 0x72, 0xfd, 0x26, 0x89, 0xd7, 0x39, 0x7a, 0x1a, 0x41,
+ 0xcb, 0xff, 0xfb, 0x00, 0xbe, 0xc0, 0xc4, 0x9c, 0x31, 0xf6, 0x90, 0xe5,
+ 0xe4, 0x18, 0x39, 0x52, 0x45, 0xc8, 0x4a, 0x5a, 0xc7, 0x78, 0xac, 0xdf,
+ 0xfc, 0x09, 0x0a, 0x4a, 0x3c, 0x20, 0x91, 0xcb, 0xf4, 0x6f, 0xf6, 0x78,
+ 0xe5, 0xcf, 0xe4, 0x3e, 0xce, 0xa1, 0xdf, 0xd2, 0xee, 0x0e, 0x2c, 0xe5,
+ 0xe9, 0x77, 0xc7, 0x2e, 0xec, 0x21, 0xe4, 0xf4, 0xb2, 0xff, 0xe1, 0x4f,
+ 0xf7, 0xa8, 0x49, 0x3e, 0xce, 0x56, 0x1f, 0x7a, 0x16, 0x5f, 0xda, 0x46,
+ 0x0b, 0xc8, 0xe5, 0xff, 0xbe, 0x96, 0x7b, 0x34, 0xb8, 0xc3, 0x97, 0x9e,
+ 0x5c, 0xda, 0x8a, 0xe1, 0xec, 0x43, 0x12, 0x44, 0x58, 0x2f, 0xd3, 0x47,
+ 0x87, 0x86, 0xe1, 0x5d, 0xe8, 0x72, 0x00, 0x83, 0x80, 0xb2, 0xff, 0xc0,
+ 0x67, 0x3d, 0xc0, 0xfb, 0x34, 0x72, 0xff, 0x83, 0x9c, 0xe3, 0x49, 0xd0,
+ 0x1c, 0xb7, 0x34, 0x5d, 0xb2, 0x64, 0xe3, 0xee, 0xe1, 0x76, 0x04, 0x0b,
+ 0xff, 0xb9, 0xbc, 0xb9, 0xe6, 0x96, 0xee, 0xb3, 0x44, 0x76, 0xbf, 0xef,
+ 0x77, 0x25, 0xcd, 0xc7, 0x67, 0x2f, 0xee, 0x18, 0x61, 0x78, 0x27, 0x2e,
+ 0x07, 0x4e, 0x5f, 0xdc, 0x20, 0xe7, 0x5f, 0xc7, 0x2f, 0xff, 0xef, 0x49,
+ 0x03, 0xd4, 0xe3, 0xcb, 0x03, 0xa4, 0x02, 0xce, 0x5f, 0xec, 0x6f, 0x70,
+ 0x3e, 0xd9, 0xcb, 0xfb, 0xf1, 0xcf, 0xbd, 0x87, 0x2f, 0xce, 0xaf, 0x73,
+ 0xf3, 0x97, 0xf0, 0xfe, 0xfa, 0x75, 0x0e, 0x54, 0x22, 0x17, 0x45, 0xce,
+ 0x53, 0x7f, 0xff, 0xfe, 0xec, 0x77, 0xae, 0x11, 0x7e, 0x5b, 0xec, 0x6f,
+ 0x90, 0x1f, 0x94, 0xb3, 0x8c, 0x1c, 0xbf, 0xf2, 0x6b, 0x96, 0xc7, 0x19,
+ 0x0b, 0x39, 0x7f, 0x81, 0xe4, 0x7e, 0x2f, 0x23, 0x97, 0xf3, 0xf1, 0x0e,
+ 0x0a, 0xa7, 0x2d, 0x02, 0x7c, 0x6a, 0x1a, 0x5f, 0xf8, 0x41, 0x2e, 0x58,
+ 0x83, 0x0c, 0x39, 0x7c, 0xb7, 0x75, 0x9a, 0x2a, 0x15, 0xff, 0x67, 0x70,
+ 0x5f, 0x5a, 0x43, 0x95, 0x24, 0xfd, 0x15, 0x84, 0x4a, 0xe1, 0x44, 0x84,
+ 0xfa, 0x3e, 0xd9, 0x75, 0xe6, 0xb7, 0x83, 0x97, 0x4b, 0x0e, 0x5f, 0xf4,
+ 0xbc, 0x9a, 0x75, 0xa0, 0x9c, 0xbd, 0xfe, 0xf0, 0xe5, 0xfe, 0xd8, 0x26,
+ 0x70, 0xbc, 0xc7, 0x2a, 0x47, 0xa5, 0xf0, 0xed, 0xfa, 0x43, 0x0c, 0x54,
+ 0xe5, 0xff, 0xcc, 0xcd, 0x0e, 0x27, 0x14, 0xd3, 0x9c, 0xaf, 0x8f, 0xad,
+ 0xca, 0x2f, 0xfc, 0x39, 0x37, 0xbb, 0x9a, 0x4d, 0x9c, 0xbf, 0xf9, 0xd9,
+ 0xc9, 0x8f, 0xee, 0x5d, 0xf6, 0x8e, 0x57, 0x51, 0x0e, 0x27, 0xd7, 0xef,
+ 0x85, 0x18, 0x87, 0x2f, 0xd1, 0xc3, 0x4f, 0x8d, 0x9c, 0xa8, 0x4c, 0x83,
+ 0x21, 0x52, 0x84, 0x5a, 0x27, 0xbf, 0xd1, 0xe7, 0xef, 0x20, 0xc1, 0xcb,
+ 0xfd, 0xed, 0xa0, 0xaf, 0xb0, 0x72, 0xff, 0xd9, 0xed, 0xeb, 0x26, 0xea,
+ 0x2a, 0x72, 0xff, 0xc3, 0x8a, 0xe3, 0x11, 0xa4, 0x30, 0xe5, 0xff, 0x72,
+ 0x71, 0xce, 0x0e, 0x5d, 0x01, 0xca, 0x84, 0x78, 0x21, 0x93, 0xa0, 0x00,
+ 0xfe, 0xff, 0x4a, 0x35, 0x3c, 0x6a, 0x73, 0x97, 0xfe, 0xde, 0x0f, 0xb7,
+ 0x92, 0x4e, 0x9c, 0xbf, 0xb7, 0x9c, 0x46, 0x3e, 0x39, 0x5b, 0x3e, 0xcf,
+ 0x1e, 0xdf, 0xff, 0x47, 0xf8, 0x3c, 0x9f, 0xdc, 0xbb, 0x9f, 0xb9, 0xcb,
+ 0x86, 0x73, 0x95, 0x09, 0x96, 0xe4, 0x28, 0x50, 0x88, 0x54, 0xef, 0xee,
+ 0x2e, 0xce, 0xb6, 0xe7, 0x2f, 0xff, 0xf2, 0x47, 0x9f, 0xbc, 0xf7, 0xdc,
+ 0x1f, 0x72, 0xfe, 0x5b, 0x39, 0x48, 0x89, 0x51, 0x30, 0xbd, 0xb0, 0x68,
+ 0xe5, 0xfd, 0xa7, 0x1f, 0xff, 0x83, 0x95, 0x87, 0xd8, 0x84, 0x2a, 0x0e,
+ 0xde, 0xf6, 0x4e, 0x72, 0xfd, 0x8b, 0x03, 0xce, 0x72, 0xba, 0x78, 0xa2,
+ 0x3b, 0x7f, 0xff, 0xb1, 0x6f, 0xdc, 0x94, 0x6a, 0x3f, 0xd4, 0x28, 0xe2,
+ 0x72, 0xfd, 0x93, 0xb8, 0xf1, 0x39, 0x7f, 0xff, 0xff, 0xa2, 0x5c, 0xbd,
+ 0xd4, 0x8d, 0xf2, 0xc0, 0x2e, 0x38, 0xf2, 0xcd, 0x6b, 0x38, 0x81, 0xfa,
+ 0x72, 0xfb, 0xa2, 0xfc, 0x07, 0x2b, 0x13, 0x64, 0xe9, 0x08, 0xaf, 0xec,
+ 0xa7, 0xd0, 0x97, 0xbf, 0xff, 0xe0, 0x3b, 0x5a, 0x4f, 0xd7, 0x4f, 0x47,
+ 0x53, 0xdb, 0xc0, 0x9c, 0xbf, 0xfc, 0x39, 0xc5, 0xe5, 0x82, 0x11, 0x89,
+ 0x1c, 0xb7, 0x3e, 0x11, 0x9a, 0xbc, 0xd5, 0x98, 0x70, 0xc2, 0xf0, 0x63,
+ 0x3a, 0xf8, 0x61, 0x71, 0x92, 0x88, 0x95, 0x62, 0x58, 0xf7, 0xc2, 0xc9,
+ 0x08, 0x9d, 0x47, 0x5c, 0xc4, 0x0e, 0xc6, 0x48, 0x31, 0xb3, 0xee, 0x34,
+ 0x0f, 0x47, 0xae, 0xd1, 0x39, 0x46, 0x8b, 0xe5, 0xbb, 0xac, 0xd1, 0x54,
+ 0x2f, 0xf6, 0xa3, 0x8f, 0xd2, 0xcf, 0x1c, 0xad, 0x1f, 0x20, 0x0b, 0xaf,
+ 0xfc, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x13, 0x5a, 0xfa, 0x35, 0x1e,
+ 0x39, 0x73, 0xf8, 0xe5, 0x04, 0xdb, 0xb0, 0x86, 0xdc, 0xf1, 0x18, 0xcc,
+ 0x22, 0x78, 0x41, 0xdf, 0xb4, 0xb7, 0x75, 0x9a, 0x2a, 0xc5, 0xff, 0x44,
+ 0xa3, 0x53, 0xc6, 0xa7, 0x39, 0x6e, 0x78, 0x7d, 0xc2, 0x69, 0x7f, 0xdd,
+ 0x8f, 0xbd, 0x1d, 0x76, 0xb3, 0x97, 0xff, 0x7f, 0x83, 0xce, 0x5f, 0xee,
+ 0x77, 0x13, 0x95, 0xcd, 0x10, 0x90, 0x79, 0x7e, 0xdc, 0x4d, 0x1f, 0x1c,
+ 0xbf, 0xe9, 0x73, 0xcd, 0x2d, 0xdd, 0x66, 0x89, 0x11, 0x7f, 0x4f, 0x1a,
+ 0xeb, 0xa1, 0xcb, 0x73, 0xc4, 0x4e, 0xb9, 0x4e, 0xd1, 0xef, 0xda, 0x5b,
+ 0xba, 0xcd, 0x16, 0x92, 0xff, 0xcf, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1,
+ 0x3e, 0xad, 0xcf, 0x11, 0x00, 0xc3, 0x4b, 0xff, 0xdc, 0xd8, 0xf2, 0xe7,
+ 0x9a, 0x5b, 0xba, 0xcd, 0x14, 0x22, 0xff, 0xec, 0x6f, 0x9f, 0x95, 0x7d,
+ 0xa7, 0xa0, 0xe5, 0xfb, 0xc0, 0x5b, 0xec, 0xe5, 0xf2, 0x4f, 0x1a, 0x39,
+ 0x4c, 0x3c, 0xae, 0x94, 0x5f, 0xb4, 0xb7, 0x75, 0x9a, 0x28, 0xf5, 0xff,
+ 0x44, 0xa3, 0x53, 0xc6, 0xa7, 0x39, 0x7f, 0xff, 0xff, 0x94, 0x4d, 0x4d,
+ 0x1d, 0xd6, 0x75, 0xd4, 0xde, 0x2a, 0xe3, 0xfc, 0x0c, 0x4d, 0xd8, 0x39,
+ 0x7e, 0x7d, 0xa7, 0xa0, 0xe5, 0xff, 0x44, 0xd0, 0x31, 0x37, 0x60, 0xe5,
+ 0x42, 0x3b, 0x95, 0x84, 0x80, 0x93, 0x5f, 0xff, 0xd8, 0x1e, 0xc2, 0x9c,
+ 0xfc, 0x2f, 0xfe, 0xf7, 0x1f, 0x94, 0xbc, 0xf2, 0xe7, 0x0a, 0x84, 0x70,
+ 0x88, 0x4d, 0x3d, 0x19, 0x43, 0x43, 0x4b, 0xff, 0xb3, 0xbc, 0xfc, 0xab,
+ 0xed, 0x3d, 0x07, 0x2d, 0xce, 0x75, 0x69, 0x8c, 0x95, 0x45, 0xe6, 0x4a,
+ 0x86, 0xf6, 0x52, 0x79, 0xe0, 0x09, 0x2a, 0x62, 0xa2, 0xb4, 0xd9, 0x85,
+ 0xca, 0x76, 0xfa, 0x15, 0x29, 0x0a, 0xc9, 0xa1, 0x83, 0xd8, 0x5b, 0x7e,
+ 0x55, 0xe9, 0x74, 0xd7, 0xfb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x44, 0x4b,
+ 0xfb, 0x34, 0xb7, 0x75, 0x9a, 0x22, 0xb5, 0xff, 0x35, 0xf3, 0xcd, 0x2d,
+ 0xdd, 0x66, 0x8a, 0xe1, 0x5c, 0xd1, 0x06, 0xe7, 0x37, 0xff, 0xbf, 0x81,
+ 0x5f, 0x37, 0xf7, 0xea, 0x0c, 0x8e, 0x5f, 0x73, 0x9e, 0x66, 0xb3, 0x96,
+ 0x4f, 0x8f, 0xe3, 0xf4, 0xeb, 0xec, 0xeb, 0xf8, 0xe5, 0xfe, 0xc4, 0xd7,
+ 0xff, 0x83, 0x67, 0x2d, 0xc2, 0x09, 0xeb, 0x6c, 0x86, 0xff, 0xfe, 0xf6,
+ 0xd3, 0xae, 0x92, 0x41, 0xf0, 0x3b, 0xac, 0x39, 0x7e, 0xd2, 0xdd, 0xd6,
+ 0x68, 0xa7, 0x97, 0xf8, 0x3f, 0xf2, 0x86, 0xb8, 0x91, 0xcb, 0xfc, 0xc4,
+ 0x08, 0x1f, 0x52, 0x39, 0x73, 0x10, 0xe5, 0x41, 0xe4, 0xac, 0xce, 0xff,
+ 0xfe, 0x8f, 0x6c, 0x0c, 0x5a, 0x7f, 0x19, 0xd4, 0x02, 0xce, 0x5f, 0xd0,
+ 0xcd, 0xc2, 0x4e, 0x72, 0xa4, 0x88, 0x8f, 0x2d, 0xdf, 0x4a, 0x32, 0x73,
+ 0x97, 0xff, 0xed, 0x03, 0x5a, 0x81, 0xc5, 0x53, 0xbd, 0xc5, 0x0e, 0x57,
+ 0xc7, 0xf1, 0xa2, 0x2b, 0xff, 0x92, 0x58, 0x3f, 0xc3, 0x13, 0x52, 0x39,
+ 0x7f, 0xa5, 0x1a, 0x9e, 0x35, 0x39, 0xcb, 0xee, 0x42, 0xf2, 0x39, 0x7e,
+ 0x7c, 0xea, 0x30, 0xe5, 0x6c, 0xf2, 0x78, 0x91, 0xd4, 0x22, 0x8b, 0x1f,
+ 0xaf, 0xfb, 0x8b, 0xb3, 0x90, 0x7a, 0x8c, 0x39, 0x7f, 0xc3, 0x0c, 0x89,
+ 0x0e, 0x30, 0xe5, 0x61, 0xf9, 0xa1, 0xed, 0xff, 0x40, 0xaf, 0x38, 0xe7,
+ 0xb6, 0x72, 0xfc, 0xf3, 0xc6, 0x80, 0x72, 0xb8, 0x65, 0xc9, 0xc8, 0x2c,
+ 0xc5, 0x95, 0x4d, 0x17, 0x08, 0x2f, 0xa1, 0x52, 0x90, 0x9b, 0x72, 0x31,
+ 0x87, 0x2e, 0xe1, 0x29, 0xc4, 0x81, 0xa1, 0xcd, 0xff, 0xe7, 0x97, 0x30,
+ 0x8b, 0xb7, 0xbd, 0xc7, 0xe7, 0x2f, 0xff, 0x7f, 0xf8, 0x37, 0xcd, 0x41,
+ 0x76, 0x0c, 0x1c, 0xbf, 0xf8, 0x73, 0xf7, 0x1f, 0xf9, 0xb1, 0x18, 0x72,
+ 0xb4, 0x89, 0x4f, 0x27, 0x5f, 0xff, 0xe4, 0x1f, 0xc7, 0x3d, 0xdc, 0xe7,
+ 0xd7, 0xef, 0x52, 0x63, 0x95, 0xcd, 0x51, 0x68, 0x61, 0x8e, 0x90, 0xe1,
+ 0xd9, 0x1d, 0xb0, 0xe5, 0xf8, 0x60, 0x1c, 0x3e, 0xce, 0x5f, 0xca, 0xe9,
+ 0xc2, 0xe2, 0x72, 0x82, 0x7d, 0x38, 0x20, 0xe5, 0x97, 0xff, 0x20, 0x74,
+ 0xff, 0x73, 0xd6, 0xa2, 0x73, 0x95, 0xcc, 0xfd, 0x7a, 0x5b, 0x70, 0x60,
+ 0xe5, 0xff, 0xfb, 0xb1, 0xac, 0x92, 0x3f, 0xb0, 0x28, 0x05, 0x94, 0xbf,
+ 0x44, 0xbf, 0x04, 0x8e, 0x5f, 0x2d, 0xdd, 0x66, 0x8a, 0xcd, 0x53, 0x1e,
+ 0xbe, 0x8a, 0x6f, 0xbc, 0x8c, 0xd9, 0xcb, 0xca, 0xed, 0x53, 0x97, 0xf7,
+ 0x11, 0x18, 0x6b, 0x98, 0xe5, 0xf9, 0x90, 0x32, 0xd9, 0xca, 0x83, 0xd9,
+ 0x9c, 0xca, 0xfb, 0xdb, 0x53, 0x67, 0x2c, 0xe7, 0x2b, 0x0d, 0xa6, 0xc9,
+ 0x2e, 0x9d, 0x0e, 0x5f, 0xed, 0xcc, 0x83, 0xdc, 0xf8, 0xe5, 0x41, 0xe5,
+ 0xe0, 0xbd, 0xfb, 0xdf, 0xa8, 0x32, 0x39, 0x7f, 0xfd, 0x0c, 0xf6, 0x60,
+ 0xfb, 0x7d, 0xcf, 0xdc, 0xe5, 0xe0, 0x3e, 0xce, 0x5f, 0xf6, 0x49, 0x00,
+ 0xd6, 0xd5, 0xfe, 0xc3, 0x96, 0x43, 0x97, 0xf7, 0x70, 0x45, 0xfc, 0x73,
+ 0x65, 0x85, 0xfb, 0x26, 0x9c, 0x1f, 0x9c, 0xbf, 0xbd, 0x1a, 0xfe, 0x26,
+ 0x39, 0x6e, 0x70, 0xaf, 0x60, 0x22, 0xd9, 0x0a, 0xaf, 0x88, 0xd0, 0x8b,
+ 0x4f, 0x0c, 0x56, 0xeb, 0x5b, 0x90, 0x7e, 0x54, 0x29, 0xdb, 0x1c, 0xf2,
+ 0x92, 0x87, 0x5c, 0x05, 0x77, 0xfe, 0xea, 0x79, 0xf5, 0x3c, 0x20, 0x4e,
+ 0x5f, 0xfb, 0xc0, 0x66, 0x2f, 0x5f, 0x3b, 0x67, 0x2f, 0xf6, 0xa1, 0x5c,
+ 0x14, 0x54, 0xe5, 0xff, 0xe8, 0x6d, 0x46, 0x0e, 0x7d, 0xe8, 0xc6, 0xce,
+ 0x5f, 0xbc, 0x83, 0x8c, 0x39, 0x7d, 0x27, 0x1e, 0x78, 0x99, 0x27, 0xc7,
+ 0xda, 0x41, 0x50, 0xcf, 0x81, 0x32, 0xff, 0xcf, 0x2e, 0x79, 0xa5, 0xbb,
+ 0xac, 0xd1, 0x22, 0xaf, 0xff, 0xde, 0xee, 0x0f, 0x3f, 0x3b, 0xfd, 0xb5,
+ 0x55, 0x73, 0x97, 0xfe, 0x7f, 0x73, 0x84, 0xd2, 0x78, 0x07, 0x2b, 0x9a,
+ 0x39, 0x21, 0x31, 0xd6, 0x6f, 0xec, 0xd2, 0xdd, 0xd6, 0x68, 0xb2, 0x57,
+ 0xe9, 0xd0, 0x65, 0xb3, 0x97, 0xf8, 0x13, 0xf6, 0x3d, 0xb4, 0x39, 0x7e,
+ 0xf6, 0xd4, 0xdf, 0x3c, 0x3d, 0xcd, 0x14, 0x57, 0x34, 0x6b, 0xe4, 0x25,
+ 0x6f, 0xf7, 0x02, 0x32, 0x3a, 0xa0, 0x4e, 0x5f, 0xdd, 0x4d, 0x44, 0xb6,
+ 0x72, 0xfe, 0x67, 0x93, 0xae, 0xc3, 0x97, 0xff, 0x93, 0xdd, 0xcf, 0x60,
+ 0xc7, 0xa0, 0x27, 0x2a, 0x0f, 0xd1, 0xcb, 0x6f, 0xf9, 0xd3, 0xc0, 0xd3,
+ 0xef, 0x9e, 0x23, 0xe1, 0x66, 0xfd, 0x85, 0x0d, 0xfd, 0x9a, 0x5b, 0xba,
+ 0xcd, 0x16, 0xc2, 0xff, 0xfe, 0xe1, 0x3b, 0xc8, 0x73, 0x5e, 0xdf, 0x66,
+ 0xe5, 0xcb, 0xad, 0x0e, 0x5e, 0xd0, 0x3a, 0x72, 0xef, 0x73, 0x84, 0x44,
+ 0x69, 0xae, 0xb9, 0xa3, 0xc5, 0x21, 0x83, 0x7b, 0x37, 0x87, 0x2f, 0x96,
+ 0xee, 0xb3, 0x45, 0xb6, 0xbe, 0xdc, 0xef, 0xa3, 0x95, 0xa3, 0xd1, 0xf1,
+ 0x75, 0xfc, 0x9d, 0xf2, 0x7e, 0x03, 0x97, 0xfd, 0x12, 0x8d, 0x4f, 0x1a,
+ 0x9c, 0xe5, 0xf4, 0x4d, 0xb4, 0x39, 0x52, 0x4c, 0x63, 0x1b, 0x26, 0x22,
+ 0x12, 0xee, 0x03, 0xab, 0xff, 0x07, 0x48, 0x09, 0xf9, 0xef, 0x5e, 0x39,
+ 0x5c, 0xd1, 0x21, 0x89, 0xb7, 0xff, 0xb0, 0x7f, 0xe6, 0xc7, 0x0e, 0x60,
+ 0xaa, 0x72, 0xf7, 0x0d, 0xd0, 0x9c, 0xbd, 0x3f, 0x50, 0xe5, 0xff, 0xb8,
+ 0x6e, 0x1b, 0x85, 0xfd, 0xdc, 0x18, 0xfc, 0xe5, 0xe6, 0xa3, 0xc2, 0xcd,
+ 0x44, 0xe5, 0xfd, 0x03, 0x20, 0x81, 0x87, 0x2f, 0xfb, 0x35, 0xa8, 0x93,
+ 0xfc, 0xd9, 0xcb, 0xe5, 0xbb, 0xac, 0xd1, 0x78, 0x2f, 0xde, 0xf9, 0x69,
+ 0xa3, 0x97, 0xfe, 0x7f, 0x47, 0x1d, 0x6b, 0x3e, 0xd9, 0xca, 0xd2, 0x26,
+ 0x18, 0x5c, 0x25, 0x37, 0xde, 0x69, 0x9d, 0x39, 0x7e, 0x64, 0x0c, 0x9c,
+ 0xe5, 0xfd, 0x03, 0xee, 0x2e, 0xb3, 0x97, 0xf4, 0xa3, 0x8c, 0x6b, 0xe3,
+ 0x95, 0x23, 0xde, 0xc2, 0xeb, 0xfd, 0x1e, 0x7e, 0xf2, 0x0c, 0x1c, 0xbf,
+ 0xf2, 0x8c, 0xfa, 0x5e, 0xc1, 0xf6, 0xce, 0x5d, 0x8a, 0x9c, 0xa8, 0x3d,
+ 0x8c, 0x41, 0xbe, 0x49, 0xf1, 0x87, 0x2f, 0xd8, 0x3f, 0xf0, 0x41, 0xcb,
+ 0xf4, 0x28, 0x07, 0xd9, 0xcb, 0xff, 0x99, 0x0b, 0xe5, 0x82, 0x09, 0x66,
+ 0xce, 0x5f, 0xee, 0xa3, 0x6a, 0xe9, 0xdb, 0x39, 0x7f, 0xff, 0xe7, 0x4f,
+ 0x3b, 0x1c, 0x7f, 0x5f, 0x53, 0x52, 0x52, 0x58, 0x27, 0x2f, 0xe8, 0xfb,
+ 0xe9, 0x3f, 0xc7, 0x2b, 0x13, 0x16, 0x5a, 0x2f, 0x4d, 0x80, 0xd7, 0x7f,
+ 0xf6, 0x77, 0xaf, 0x26, 0x24, 0x6a, 0x47, 0x2f, 0xa0, 0x64, 0xd6, 0x72,
+ 0xe8, 0xfc, 0xe5, 0x48, 0xff, 0x95, 0x43, 0xf1, 0x25, 0x70, 0x8b, 0xba,
+ 0xfc, 0x31, 0x13, 0x51, 0x1d, 0xe1, 0x65, 0x09, 0xcc, 0x02, 0x5b, 0x90,
+ 0xd2, 0xf8, 0xbd, 0x09, 0x26, 0x84, 0x23, 0x08, 0x7b, 0x08, 0xc7, 0x20,
+ 0xfc, 0x88, 0x4a, 0xb7, 0x19, 0xf7, 0xa1, 0x77, 0x7f, 0xbe, 0xe7, 0x9f,
+ 0xbe, 0xb6, 0x72, 0xff, 0x7f, 0xce, 0x69, 0x40, 0xf8, 0xe5, 0x73, 0x4e,
+ 0x22, 0x23, 0x1a, 0xd1, 0xbd, 0xe4, 0xcf, 0x8e, 0x5f, 0x2d, 0xdd, 0x66,
+ 0x8b, 0xd1, 0x7f, 0xe4, 0xf7, 0x45, 0xe5, 0xfb, 0xfe, 0x72, 0xb4, 0x7d,
+ 0xac, 0x2e, 0xbf, 0xf3, 0xa7, 0x81, 0xa7, 0xe3, 0x81, 0x39, 0x79, 0x89,
+ 0xe3, 0x97, 0xfc, 0xfe, 0x94, 0x2b, 0xe4, 0x9c, 0xe5, 0x30, 0xf5, 0x84,
+ 0x72, 0xfd, 0x8c, 0xeb, 0x84, 0xe5, 0x05, 0x38, 0x8c, 0x84, 0x4f, 0x48,
+ 0x94, 0x84, 0xaf, 0x01, 0x0d, 0xff, 0xd8, 0x1e, 0xe3, 0x18, 0xf2, 0xc1,
+ 0x39, 0x78, 0x11, 0xf9, 0xcb, 0xee, 0x38, 0x3c, 0xc2, 0x7b, 0xfa, 0x42,
+ 0xbf, 0xdc, 0xfd, 0x93, 0x49, 0xc2, 0x72, 0x90, 0xfc, 0xba, 0x79, 0x5c,
+ 0xd3, 0x4a, 0xc8, 0xca, 0x6a, 0x1d, 0x0b, 0x3c, 0xf0, 0xc4, 0x94, 0x27,
+ 0x32, 0x7d, 0x21, 0x71, 0x94, 0x24, 0xbf, 0xc9, 0xa5, 0x00, 0x6a, 0x34,
+ 0xb6, 0x46, 0x0f, 0xd8, 0xc8, 0x7f, 0x8d, 0x50, 0x63, 0xd1, 0xd9, 0x20,
+ 0x27, 0xea, 0x9b, 0x96, 0x15, 0x70, 0x3a, 0x72, 0xff, 0xe0, 0x44, 0xc3,
+ 0x9c, 0x5d, 0x8c, 0x43, 0x97, 0xd9, 0xd7, 0xf1, 0xcb, 0xfd, 0x89, 0xaf,
+ 0xff, 0x06, 0xce, 0x5b, 0x84, 0x55, 0x13, 0x62, 0x8b, 0xb2, 0x1b, 0xff,
+ 0xde, 0xd8, 0x23, 0x79, 0xe4, 0x63, 0xc8, 0xe5, 0xe8, 0xfa, 0x73, 0x94,
+ 0x27, 0xcf, 0xe4, 0x9b, 0xfe, 0xf6, 0xf3, 0xe9, 0x74, 0x0a, 0x9c, 0xbd,
+ 0xb8, 0x98, 0xe5, 0x21, 0xfd, 0x09, 0x0e, 0xcf, 0x2f, 0xa3, 0x8c, 0x48,
+ 0xe5, 0xfc, 0xfa, 0x90, 0x81, 0xce, 0x5c, 0x8c, 0x39, 0x40, 0x3c, 0x2e,
+ 0x02, 0xcb, 0xce, 0xeb, 0x34, 0x44, 0x6b, 0xe5, 0x56, 0xfa, 0x39, 0x4b,
+ 0x3c, 0xb4, 0x28, 0xbf, 0x70, 0xde, 0xdb, 0xfe, 0x72, 0xb4, 0x79, 0xec,
+ 0x21, 0xbf, 0xfe, 0xe8, 0x37, 0xbc, 0x60, 0xe7, 0x1e, 0x50, 0xd4, 0x9c,
+ 0xbf, 0xe8, 0x9f, 0x59, 0xef, 0x27, 0x8e, 0x5e, 0x18, 0xf8, 0xe5, 0x48,
+ 0xf5, 0x42, 0x73, 0x7f, 0xd9, 0xac, 0xde, 0x38, 0xce, 0x72, 0xf6, 0x05,
+ 0x87, 0x2f, 0xff, 0xf7, 0x5d, 0x3d, 0x1d, 0x1c, 0xf7, 0x53, 0xb8, 0x8d,
+ 0x9c, 0xbf, 0xff, 0xfd, 0xef, 0x23, 0x34, 0x99, 0xf0, 0x83, 0xd1, 0xde,
+ 0x5c, 0x53, 0xd3, 0x41, 0xcb, 0xfe, 0xc7, 0x1f, 0xf4, 0x08, 0xfc, 0xe5,
+ 0x42, 0x62, 0x78, 0xbd, 0xa7, 0xcb, 0xfc, 0xec, 0xcd, 0x4a, 0x18, 0x72,
+ 0xe9, 0xd8, 0x52, 0xe6, 0xdb, 0x29, 0x7f, 0xee, 0x6b, 0xea, 0x4d, 0xd8,
+ 0x9f, 0x9f, 0xe6, 0xc5, 0xb1, 0x8b, 0xee, 0x31, 0xe8, 0x39, 0x52, 0x44,
+ 0x02, 0x2e, 0xdf, 0xd8, 0xec, 0xcf, 0xbc, 0x72, 0xff, 0x81, 0x1d, 0xc9,
+ 0xa4, 0xf3, 0x9c, 0xbf, 0xb9, 0xed, 0x34, 0xff, 0x9c, 0xac, 0x3e, 0xa7,
+ 0x3a, 0xb3, 0x59, 0xcb, 0xfe, 0x8c, 0xfa, 0x1e, 0x4f, 0x23, 0x97, 0xf8,
+ 0x39, 0xff, 0x21, 0xcf, 0xce, 0x5f, 0x33, 0xdf, 0xb9, 0xca, 0x6a, 0x91,
+ 0x48, 0x11, 0x4c, 0x37, 0x73, 0x6b, 0xf0, 0xe7, 0x5f, 0xc7, 0x2f, 0x72,
+ 0xda, 0xce, 0x53, 0x59, 0xe2, 0xf4, 0x9a, 0xff, 0x23, 0xff, 0xad, 0x03,
+ 0xa7, 0x2f, 0xe8, 0x57, 0x05, 0x15, 0x39, 0x7f, 0x67, 0xb8, 0x3d, 0x9d,
+ 0x39, 0x58, 0x8b, 0x6e, 0x92, 0x89, 0xa6, 0xcb, 0x6f, 0xff, 0xe5, 0xf3,
+ 0xd3, 0x8a, 0x7b, 0x9e, 0xa3, 0xc2, 0xff, 0x9c, 0xbf, 0xfb, 0xc3, 0x1f,
+ 0xbf, 0xbf, 0x50, 0x64, 0x72, 0x9a, 0xb6, 0x50, 0xff, 0x0d, 0x0b, 0x28,
+ 0x8c, 0x72, 0x45, 0xa1, 0x65, 0xc8, 0x5f, 0xac, 0x8b, 0xe8, 0x56, 0xa1,
+ 0x14, 0xc6, 0xfa, 0x8c, 0xbf, 0xa5, 0xef, 0x0e, 0x3f, 0xc8, 0x86, 0x12,
+ 0xfb, 0x86, 0x27, 0xa3, 0x3b, 0xe2, 0x76, 0xa2, 0xf5, 0xdc, 0x1d, 0x39,
+ 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0x8b, 0x97, 0xef, 0x7e, 0xa0, 0xc8, 0xa5,
+ 0xfb, 0x7e, 0xec, 0x7e, 0x72, 0xfc, 0xf3, 0xc6, 0x80, 0x72, 0xdc, 0xe7,
+ 0x46, 0x4e, 0x0d, 0x39, 0xa0, 0x0a, 0x9a, 0x14, 0xd7, 0x35, 0x4b, 0x72,
+ 0x94, 0x11, 0x7f, 0xf3, 0x1e, 0x5c, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0x66,
+ 0x5f, 0xdc, 0x2b, 0x85, 0xf8, 0x4d, 0xc7, 0x8e, 0x5e, 0xfa, 0x36, 0x72,
+ 0xff, 0xf7, 0x09, 0xe9, 0x67, 0x7a, 0xf2, 0x44, 0x13, 0x97, 0x96, 0x8c,
+ 0x39, 0x7d, 0xc3, 0x79, 0xc4, 0xe5, 0xcd, 0x1a, 0xa3, 0x97, 0x60, 0x0e,
+ 0x5f, 0xfd, 0x0c, 0x7f, 0x67, 0xdf, 0xb1, 0x4e, 0x9c, 0xbf, 0xfe, 0x85,
+ 0xe8, 0x13, 0xfd, 0xb4, 0xd2, 0xfb, 0x87, 0x2b, 0xa8, 0x99, 0x14, 0x7b,
+ 0xe4, 0x9c, 0x02, 0x72, 0xfd, 0x93, 0xe7, 0xf3, 0x1c, 0xae, 0x47, 0x99,
+ 0xe2, 0x2b, 0xfd, 0xcb, 0x05, 0xf5, 0xfb, 0x43, 0x97, 0xff, 0xe6, 0x3f,
+ 0x73, 0xef, 0xfa, 0xdb, 0xf6, 0x6e, 0x80, 0xe5, 0xfd, 0x9b, 0x85, 0x06,
+ 0x0e, 0x50, 0x51, 0x7b, 0x86, 0xfd, 0x5a, 0xbb, 0x78, 0x72, 0xee, 0x0f,
+ 0x1c, 0xb7, 0x0e, 0x72, 0xdf, 0xc1, 0xb0, 0x00, 0xd5, 0xff, 0xff, 0x90,
+ 0x61, 0x63, 0x0c, 0xe5, 0x1a, 0xd2, 0x71, 0xd3, 0xbf, 0xe7, 0x2f, 0x93,
+ 0xd1, 0x23, 0x94, 0xd5, 0x2b, 0x46, 0x58, 0xf2, 0x42, 0xbe, 0x66, 0xee,
+ 0xc3, 0x85, 0xcb, 0xff, 0x46, 0xf1, 0x3f, 0x16, 0xdb, 0xf9, 0xb8, 0x11,
+ 0xcf, 0x1c, 0xbe, 0x7e, 0xa4, 0xc7, 0x2f, 0xbb, 0x34, 0x04, 0xe5, 0x61,
+ 0xf8, 0xac, 0xb1, 0xc8, 0xaf, 0xf2, 0xd3, 0x04, 0x3d, 0x83, 0x94, 0x72,
+ 0xfb, 0x51, 0x82, 0x72, 0xf9, 0xfd, 0x2f, 0xce, 0x5f, 0xf6, 0xd1, 0x6f,
+ 0x9a, 0xcf, 0x1c, 0xbf, 0xcf, 0xa4, 0x86, 0xb4, 0x61, 0xca, 0x62, 0x2b,
+ 0xba, 0x41, 0xe2, 0x3e, 0x26, 0xf7, 0xff, 0xb9, 0x75, 0xd3, 0xdf, 0x80,
+ 0x45, 0xe4, 0x72, 0xff, 0x94, 0x66, 0x6d, 0xdf, 0xe9, 0x1c, 0xbc, 0xd4,
+ 0x5a, 0xae, 0x10, 0xe5, 0x62, 0x7b, 0x6b, 0x31, 0x48, 0x5c, 0xb0, 0xff,
+ 0xf4, 0xb1, 0x3a, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0xd4, 0x78, 0x4c, 0x6a,
+ 0x3c, 0x37, 0x0b, 0xf0, 0xba, 0xf8, 0x78, 0xe1, 0x6e, 0x1b, 0x53, 0xf0,
+ 0x60, 0x02, 0xd4, 0x21, 0xa7, 0xca, 0x77, 0x86, 0x88, 0xe1, 0x9a, 0xf8,
+ 0x57, 0xb9, 0x72, 0xeb, 0x43, 0x97, 0xff, 0xef, 0xfe, 0x97, 0x41, 0x1a,
+ 0xe7, 0xd4, 0x5b, 0xe8, 0xe5, 0xff, 0xbb, 0x83, 0x8a, 0xe0, 0xe0, 0x4e,
+ 0x5f, 0xfd, 0xf3, 0x71, 0xe0, 0xa3, 0x5e, 0xe1, 0x87, 0x2f, 0x90, 0x7d,
+ 0xb3, 0x97, 0xff, 0xfc, 0xc4, 0xd7, 0x41, 0xb9, 0x47, 0x1d, 0x40, 0xfb,
+ 0xb9, 0x23, 0x95, 0x24, 0x44, 0xa1, 0x0d, 0xff, 0x93, 0xc8, 0xb4, 0x0f,
+ 0xb1, 0x67, 0x2a, 0x49, 0xb6, 0xe1, 0xe7, 0xa1, 0xa5, 0xc0, 0x45, 0x7d,
+ 0xe6, 0x99, 0xd3, 0x97, 0xff, 0xf9, 0xc5, 0x63, 0x81, 0xe8, 0x39, 0x76,
+ 0x25, 0xa8, 0x9c, 0xe5, 0x62, 0x21, 0x80, 0x49, 0x7f, 0xff, 0x9d, 0x51,
+ 0xcf, 0xc1, 0xbe, 0x52, 0x4e, 0xc2, 0xc5, 0xce, 0x5f, 0x37, 0x0c, 0xf1,
+ 0xcb, 0xc9, 0xd4, 0x39, 0x50, 0x6f, 0xbc, 0x47, 0x7f, 0xcf, 0xa9, 0x72,
+ 0xc5, 0x87, 0x0e, 0x57, 0x0c, 0xb9, 0xc3, 0x11, 0x99, 0xe4, 0x78, 0xfd,
+ 0x86, 0x5b, 0x91, 0x0c, 0x28, 0x00, 0x41, 0x6d, 0x1c, 0xbf, 0xbd, 0x8c,
+ 0xfb, 0x18, 0x72, 0xdd, 0xc3, 0x7e, 0x82, 0x37, 0xf8, 0x01, 0x79, 0x6d,
+ 0x24, 0x72, 0xfc, 0xb0, 0x0f, 0xb6, 0x72, 0xfa, 0x24, 0xd1, 0xb3, 0x97,
+ 0xfe, 0x18, 0x5a, 0xaf, 0x9a, 0x4f, 0xce, 0x5f, 0xdb, 0xc4, 0xd6, 0x9c,
+ 0xe5, 0x4e, 0x7d, 0x5f, 0x9f, 0x5f, 0xff, 0x20, 0xcf, 0x9b, 0x47, 0xef,
+ 0x36, 0xdb, 0x6c, 0xa5, 0x41, 0xfc, 0x04, 0x92, 0xfe, 0xfb, 0x3a, 0x0f,
+ 0xbf, 0x39, 0x7e, 0xec, 0x4f, 0xd0, 0x1c, 0xac, 0x3d, 0xaf, 0x18, 0xdf,
+ 0xf0, 0xe4, 0x2a, 0xfe, 0x75, 0x4e, 0x5f, 0xa5, 0xbf, 0xc1, 0x31, 0xcb,
+ 0xcb, 0x02, 0xce, 0x57, 0xc7, 0x90, 0x02, 0xbb, 0xfe, 0x9f, 0x3f, 0x08,
+ 0x1f, 0x52, 0x39, 0x7f, 0x3b, 0x87, 0x8e, 0x04, 0xe5, 0xe7, 0x75, 0x9a,
+ 0x2c, 0xf5, 0xfd, 0xfb, 0x8c, 0x91, 0x87, 0x2a, 0x74, 0x5f, 0x04, 0xed,
+ 0x65, 0xdf, 0x94, 0x5f, 0xee, 0xfb, 0x6f, 0xf2, 0x8c, 0x39, 0x7f, 0xdd,
+ 0x89, 0x27, 0xa3, 0xdb, 0x39, 0x50, 0x7d, 0xc8, 0x6d, 0x7f, 0xfb, 0x5d,
+ 0x7e, 0x59, 0xc4, 0x73, 0x78, 0x27, 0x2f, 0xfa, 0x10, 0x38, 0xc6, 0xf3,
+ 0xa7, 0x2f, 0xfe, 0xdf, 0x92, 0x66, 0xdc, 0x31, 0xf6, 0xce, 0x52, 0x23,
+ 0x29, 0xd2, 0xc0, 0x71, 0x79, 0xb6, 0xdb, 0x29, 0x7f, 0xe7, 0x96, 0xc7,
+ 0x16, 0x1c, 0xd1, 0x4e, 0x66, 0x82, 0xfd, 0xc0, 0x06, 0x60, 0x4e, 0x5f,
+ 0xef, 0x77, 0x38, 0xf2, 0x93, 0x0e, 0x56, 0x1f, 0x18, 0x0a, 0xef, 0xfd,
+ 0xf4, 0x84, 0x1f, 0xf2, 0x5b, 0x3f, 0x39, 0x74, 0x2a, 0x72, 0xff, 0x83,
+ 0x03, 0x1f, 0xcb, 0xa8, 0x72, 0xa1, 0x12, 0x93, 0xa2, 0xa0, 0xbd, 0xfe,
+ 0xea, 0x04, 0x5d, 0xe6, 0x39, 0x7f, 0x83, 0xd0, 0x3f, 0xed, 0x30, 0xe5,
+ 0x41, 0xf4, 0x21, 0x95, 0xfe, 0x8e, 0x5e, 0xcd, 0xee, 0x0e, 0x5f, 0xc1,
+ 0x50, 0x20, 0xf6, 0xce, 0x59, 0x34, 0x7c, 0x82, 0x69, 0x7a, 0x05, 0x53,
+ 0x95, 0x26, 0x41, 0x68, 0x49, 0x70, 0xcd, 0x52, 0x85, 0xc6, 0x0f, 0xf3,
+ 0xda, 0x10, 0xcd, 0x08, 0x0d, 0x43, 0x85, 0x90, 0xad, 0xec, 0x3a, 0xbf,
+ 0x4e, 0x18, 0x59, 0x6e, 0x16, 0xbe, 0x84, 0xbf, 0x18, 0x42, 0x28, 0x4d,
+ 0x77, 0xfb, 0x39, 0x7f, 0xc0, 0xf6, 0xc7, 0x26, 0x86, 0x1c, 0xbe, 0xfd,
+ 0xdb, 0xf1, 0xcb, 0xfc, 0xed, 0xf5, 0x23, 0x50, 0x72, 0x82, 0x8a, 0x75,
+ 0x46, 0x10, 0xe7, 0x44, 0x97, 0xfe, 0xd2, 0x6e, 0x4a, 0x76, 0x06, 0x0e,
+ 0x5f, 0x69, 0x21, 0x87, 0x2f, 0xff, 0xde, 0x54, 0x11, 0x81, 0xee, 0x6f,
+ 0xe9, 0x47, 0x4e, 0x56, 0x91, 0x6c, 0xc3, 0xe1, 0x21, 0xb9, 0xe4, 0x72,
+ 0xff, 0xff, 0xfe, 0x17, 0x6f, 0xd9, 0xd1, 0xcf, 0x03, 0xf6, 0x3c, 0x9c,
+ 0x30, 0x2f, 0xa7, 0x91, 0xcb, 0xfd, 0x9d, 0xe8, 0x3c, 0xe2, 0x72, 0xe4,
+ 0x09, 0xcb, 0xfb, 0xab, 0x7d, 0x3c, 0x8e, 0x59, 0x72, 0x3c, 0x3c, 0x16,
+ 0xbc, 0x93, 0x6c, 0xe5, 0x41, 0xe2, 0x30, 0x9e, 0xc8, 0x14, 0xdd, 0xa6,
+ 0x16, 0xd4, 0x21, 0x99, 0x0b, 0x9b, 0xfb, 0x92, 0x75, 0xd8, 0x87, 0x2f,
+ 0x71, 0xc0, 0x9c, 0xb6, 0xa7, 0x3c, 0xc9, 0x8b, 0xaf, 0xfd, 0x8d, 0xf0,
+ 0x6b, 0x38, 0x04, 0x0d, 0x9c, 0xa8, 0x55, 0x5f, 0xd8, 0xe9, 0x5e, 0x13,
+ 0x42, 0x55, 0x7f, 0xff, 0xfd, 0xfe, 0xf3, 0x05, 0x55, 0x34, 0x31, 0x9d,
+ 0xe7, 0xb1, 0xc9, 0xd9, 0x8c, 0x39, 0x7e, 0x52, 0x05, 0x46, 0x1c, 0xac,
+ 0x45, 0x4f, 0xa1, 0x01, 0x77, 0xfb, 0x39, 0x7c, 0xfd, 0x85, 0x0e, 0x56,
+ 0x1b, 0xae, 0x23, 0x17, 0xff, 0xc0, 0xfa, 0x5b, 0x0f, 0x63, 0x41, 0x77,
+ 0x6c, 0xe5, 0x62, 0x35, 0x51, 0x84, 0x48, 0xaf, 0x0b, 0x10, 0xe5, 0xed,
+ 0xc4, 0xe7, 0x2f, 0x06, 0x24, 0x72, 0xff, 0xa3, 0x17, 0xd4, 0xe2, 0xfa,
+ 0x39, 0x76, 0x74, 0xe5, 0x39, 0xf5, 0x88, 0xe3, 0x43, 0x9b, 0xb0, 0x27,
+ 0x2a, 0x49, 0x8a, 0xe1, 0x6e, 0xc6, 0xfd, 0x08, 0x8e, 0x25, 0xf7, 0xba,
+ 0x06, 0xce, 0x5e, 0xfc, 0x0b, 0x39, 0x7b, 0xd8, 0xa1, 0xcb, 0xfd, 0x0c,
+ 0x06, 0xfd, 0x9e, 0x39, 0x7f, 0x47, 0xdb, 0xe5, 0xa8, 0x39, 0x78, 0x20,
+ 0x59, 0xcb, 0xe0, 0x8c, 0x48, 0xe5, 0x21, 0xbe, 0x71, 0xda, 0x0a, 0x63,
+ 0x3f, 0x0f, 0x20, 0xf4, 0xc3, 0xac, 0x33, 0xeb, 0x75, 0xfe, 0x49, 0x9c,
+ 0x53, 0xed, 0x9c, 0xbb, 0x16, 0x72, 0xff, 0x0f, 0xb6, 0x31, 0xed, 0x9c,
+ 0xbf, 0x27, 0x1c, 0x1d, 0x9c, 0xac, 0x3d, 0xad, 0x19, 0x5f, 0xdf, 0x7b,
+ 0x3a, 0x06, 0xb3, 0x97, 0xf6, 0xb3, 0xbd, 0x07, 0x8e, 0x5f, 0xba, 0x31,
+ 0x9a, 0x31, 0x7f, 0x66, 0xa7, 0x03, 0x84, 0xd1, 0x06, 0xb9, 0x9a, 0x6b,
+ 0x6a, 0x74, 0x50, 0xc9, 0x52, 0xf8, 0x7b, 0x9f, 0x1c, 0xa8, 0x4c, 0x7d,
+ 0x21, 0xa6, 0xe5, 0x57, 0xe7, 0x5a, 0x32, 0x0e, 0x5f, 0xd2, 0xe8, 0xbf,
+ 0xde, 0x39, 0x4b, 0x3d, 0x41, 0x26, 0xbe, 0x50, 0x5e, 0x73, 0x95, 0x87,
+ 0x89, 0xb2, 0x1b, 0xf4, 0x7b, 0x93, 0x1b, 0x39, 0x7f, 0xa4, 0x8c, 0x8e,
+ 0xa8, 0x13, 0x97, 0xff, 0xa3, 0x07, 0xef, 0x66, 0x92, 0x77, 0x61, 0xcb,
+ 0xf3, 0xb7, 0xec, 0xee, 0xcf, 0xf7, 0xc6, 0x95, 0xc9, 0x5d, 0xb3, 0x56,
+ 0x67, 0x0e, 0x12, 0x8d, 0x03, 0x21, 0x97, 0xa2, 0x11, 0x85, 0x45, 0xed,
+ 0xe4, 0x8e, 0x5d, 0x8a, 0x1c, 0xbe, 0xff, 0xb0, 0x13, 0x97, 0xfd, 0x1f,
+ 0xb2, 0x30, 0x7d, 0xb3, 0x94, 0x87, 0xb7, 0xd2, 0x3b, 0xf2, 0x7d, 0x24,
+ 0x13, 0x97, 0x93, 0xb8, 0x72, 0xe8, 0x66, 0x1e, 0x12, 0xc9, 0xef, 0xe6,
+ 0xf1, 0x91, 0xa5, 0x4e, 0x5f, 0x07, 0x7d, 0x83, 0x97, 0xe1, 0xd3, 0x6f,
+ 0x39, 0xca, 0x83, 0xfa, 0xc2, 0xf7, 0x22, 0xbf, 0x67, 0xb6, 0x8c, 0x39,
+ 0x70, 0x04, 0xe5, 0x42, 0xa0, 0x09, 0x0e, 0x63, 0x92, 0x31, 0xea, 0x14,
+ 0xc2, 0x59, 0xb2, 0x7b, 0xdd, 0xc1, 0x39, 0x7f, 0xb0, 0x73, 0xef, 0x49,
+ 0x87, 0x2e, 0xf4, 0x1c, 0xa8, 0x3c, 0x97, 0x33, 0xbf, 0xd3, 0x44, 0xec,
+ 0x79, 0xa0, 0xe5, 0xff, 0xf3, 0xab, 0xe8, 0xd7, 0xfa, 0x8f, 0x0b, 0xfe,
+ 0x72, 0xfe, 0x1c, 0xff, 0x06, 0x47, 0x2f, 0xff, 0x95, 0xe4, 0xa0, 0xbf,
+ 0xb6, 0x9f, 0x75, 0x1b, 0x39, 0x61, 0xc4, 0x40, 0xb9, 0x65, 0x62, 0x76,
+ 0x3a, 0x64, 0x72, 0x01, 0x35, 0x04, 0x34, 0xae, 0xdf, 0x13, 0x97, 0x27,
+ 0x8e, 0x5f, 0x20, 0xb8, 0x4e, 0x5f, 0xf9, 0x99, 0xed, 0xa9, 0xb7, 0x96,
+ 0x1c, 0xbf, 0x6e, 0x35, 0xe8, 0x39, 0xcc, 0xdf, 0xd0, 0x51, 0x31, 0xb5,
+ 0xfb, 0xf2, 0x93, 0x3b, 0xe8, 0xe5, 0xf7, 0x71, 0x38, 0x9c, 0xbf, 0xb6,
+ 0x9a, 0xc0, 0x68, 0xe5, 0xff, 0xfd, 0x37, 0x24, 0x58, 0x35, 0xb0, 0x72,
+ 0x62, 0x7b, 0xa8, 0x72, 0xe8, 0x54, 0xe5, 0x41, 0xfc, 0x23, 0x0d, 0x62,
+ 0x7f, 0x6a, 0x8c, 0xa4, 0x2b, 0x98, 0x47, 0xd2, 0x9f, 0x11, 0xf0, 0x42,
+ 0x96, 0xe6, 0x70, 0x86, 0x8b, 0xf1, 0x7d, 0xbd, 0x66, 0x1c, 0xbf, 0xfa,
+ 0x5e, 0x04, 0xa4, 0xcf, 0x7a, 0x18, 0x72, 0xff, 0x7b, 0x71, 0x3e, 0x6c,
+ 0x27, 0x2e, 0xee, 0x1c, 0xbf, 0xfe, 0xec, 0x07, 0x17, 0xcb, 0x07, 0x03,
+ 0xd8, 0x39, 0x7f, 0xda, 0x8e, 0xa7, 0x1d, 0x44, 0x8e, 0x5f, 0xfc, 0x98,
+ 0x39, 0x9b, 0xe5, 0x2d, 0xb0, 0xe5, 0xff, 0x9e, 0x3e, 0x97, 0x2d, 0xfc,
+ 0x18, 0x39, 0x41, 0x4f, 0x03, 0xe2, 0x14, 0x46, 0x6b, 0x34, 0x98, 0x5b,
+ 0x49, 0xfb, 0x3a, 0xf2, 0x25, 0xe5, 0x63, 0x47, 0x2f, 0xe0, 0xc7, 0xfa,
+ 0xcf, 0x8e, 0x57, 0x33, 0xcc, 0x60, 0xed, 0xcb, 0x9c, 0xe5, 0xfe, 0x86,
+ 0x62, 0x6a, 0x69, 0x1c, 0xb9, 0x26, 0x39, 0x7f, 0xb5, 0x0a, 0x84, 0x63,
+ 0xe3, 0x97, 0xff, 0xbd, 0x1d, 0x17, 0x9e, 0x35, 0xa7, 0x91, 0xcb, 0xde,
+ 0x49, 0xce, 0x5f, 0xbf, 0x7f, 0xa2, 0x63, 0x97, 0x86, 0x16, 0x72, 0xff,
+ 0xe0, 0xa4, 0xdd, 0x8d, 0x7d, 0x28, 0xd1, 0xcb, 0xff, 0xc8, 0x2f, 0xf6,
+ 0xf7, 0x9a, 0x0f, 0x70, 0xe5, 0x72, 0x4e, 0x16, 0x42, 0xe8, 0x68, 0xc4,
+ 0x97, 0x1d, 0x12, 0xad, 0x8d, 0xf0, 0x23, 0x5a, 0x0e, 0x5e, 0xea, 0x78,
+ 0xe5, 0xb8, 0xe1, 0xac, 0x50, 0x42, 0xa1, 0x77, 0x64, 0x2e, 0x39, 0x1f,
+ 0x4a, 0x43, 0x09, 0x84, 0x9d, 0x18, 0x78, 0xee, 0x3f, 0x85, 0x05, 0xe6,
+ 0x3a, 0x87, 0x2f, 0xfb, 0x06, 0x43, 0x8c, 0x85, 0x9c, 0xbf, 0x75, 0x38,
+ 0xe0, 0x4e, 0x5f, 0xf8, 0x30, 0x38, 0x20, 0x96, 0x6c, 0xe5, 0xf9, 0xd8,
+ 0x9c, 0x18, 0x72, 0xfe, 0xce, 0xbf, 0x9e, 0x63, 0x97, 0x47, 0xc7, 0x2b,
+ 0xe3, 0xc4, 0xf1, 0x6d, 0x62, 0x24, 0x1d, 0xb6, 0xf4, 0x24, 0xc7, 0x2e,
+ 0xd6, 0x1c, 0xbc, 0x2d, 0x57, 0x01, 0xcb, 0xf6, 0x4e, 0xc8, 0xd9, 0xcb,
+ 0xff, 0xff, 0x47, 0x51, 0x9c, 0xe6, 0x93, 0xe9, 0x4e, 0xa7, 0xdb, 0x5a,
+ 0x4e, 0x72, 0xa7, 0x54, 0xb2, 0x11, 0xd5, 0x4d, 0x90, 0xa6, 0x68, 0x66,
+ 0x74, 0x87, 0xf1, 0xc1, 0x16, 0xd9, 0x27, 0x01, 0x45, 0xe4, 0xee, 0xce,
+ 0x5f, 0x72, 0x79, 0x35, 0x27, 0x2f, 0xfe, 0xce, 0x38, 0x1c, 0x10, 0x4b,
+ 0x36, 0x72, 0xfd, 0xa8, 0xea, 0x81, 0x39, 0x5a, 0x3e, 0xd7, 0x44, 0xbe,
+ 0x84, 0x9e, 0x0e, 0x5f, 0x36, 0xf9, 0xb3, 0x97, 0xf0, 0x63, 0xf1, 0xcf,
+ 0x8e, 0x5f, 0xf4, 0x98, 0xf2, 0xf6, 0xe1, 0x53, 0x95, 0x08, 0x8a, 0xc2,
+ 0x27, 0x2e, 0xbd, 0xb4, 0x13, 0x97, 0xe1, 0x5f, 0x2d, 0xfc, 0x72, 0xff,
+ 0x29, 0x28, 0xe2, 0x83, 0xf9, 0xca, 0xc3, 0xfc, 0x71, 0xb1, 0x2b, 0xac,
+ 0x54, 0xa6, 0xd6, 0x38, 0xf0, 0x96, 0xfc, 0x84, 0x61, 0x56, 0x08, 0x54,
+ 0xdd, 0x3c, 0x8e, 0x5e, 0x4e, 0xa1, 0xca, 0xf8, 0xd9, 0xf8, 0x62, 0xf9,
+ 0x40, 0x3e, 0xce, 0x5f, 0xf2, 0x2b, 0x01, 0x8e, 0x39, 0xd3, 0x97, 0xfd,
+ 0xd4, 0x6f, 0xe9, 0x6f, 0x16, 0x72, 0xfe, 0x06, 0xe2, 0x60, 0x68, 0xe5,
+ 0xe0, 0x67, 0xc7, 0x2b, 0xa7, 0x99, 0xe2, 0xfb, 0xfd, 0x20, 0x0c, 0xfb,
+ 0x4f, 0x8e, 0x5f, 0x7f, 0xfe, 0x7c, 0x72, 0xfe, 0xe0, 0xf6, 0x38, 0xac,
+ 0xe5, 0xff, 0x01, 0xe4, 0x1c, 0xcf, 0xf6, 0x72, 0xff, 0xdf, 0x4b, 0xb0,
+ 0xc7, 0xfa, 0x58, 0x72, 0xfe, 0x4f, 0xbe, 0x96, 0x78, 0xe5, 0x61, 0xf7,
+ 0xfe, 0x81, 0x5d, 0x46, 0x56, 0xe1, 0x51, 0x7e, 0xfb, 0x6c, 0x46, 0xb3,
+ 0x97, 0xff, 0xec, 0xdf, 0x2e, 0xba, 0x7b, 0xf0, 0x08, 0xbc, 0x8e, 0x54,
+ 0x22, 0x08, 0x4b, 0x2f, 0xe7, 0x9f, 0xf7, 0x10, 0x9c, 0xa9, 0xd5, 0x97,
+ 0x84, 0xe9, 0x70, 0x87, 0x98, 0x8b, 0x46, 0xbd, 0x25, 0xf4, 0x3e, 0x78,
+ 0xc2, 0xa9, 0xa1, 0x0d, 0xef, 0x60, 0x9c, 0xbd, 0xd7, 0x6b, 0x39, 0x7f,
+ 0x94, 0x85, 0xb4, 0xcd, 0x41, 0xcb, 0xfe, 0x0e, 0x03, 0x53, 0xad, 0x27,
+ 0x39, 0x7f, 0x47, 0x53, 0x50, 0xc3, 0x95, 0x24, 0x6b, 0x2a, 0x37, 0xd1,
+ 0xf7, 0x35, 0xf1, 0xdd, 0x42, 0xe8, 0x3e, 0x4b, 0x52, 0x78, 0xda, 0xee,
+ 0x98, 0x07, 0x2c, 0xc3, 0x95, 0xf1, 0xa9, 0xe1, 0xc6, 0x2f, 0xf7, 0xbf,
+ 0x00, 0xed, 0x02, 0x72, 0xfd, 0x2f, 0xf3, 0x02, 0x72, 0xfa, 0x35, 0x9c,
+ 0x50, 0xf7, 0x1c, 0xd2, 0xff, 0xf4, 0xc3, 0x1e, 0xdf, 0xbe, 0x5a, 0x0c,
+ 0xe7, 0x2f, 0xc8, 0xc5, 0x26, 0xd9, 0xcb, 0xf9, 0xfe, 0x90, 0xc0, 0x4e,
+ 0x5f, 0xf4, 0x7d, 0x24, 0x16, 0x3f, 0x8e, 0x52, 0x23, 0x6f, 0xa9, 0x8e,
+ 0x54, 0x25, 0xb7, 0xe7, 0x96, 0x4f, 0x07, 0x2f, 0xfe, 0x8d, 0xef, 0x19,
+ 0xe1, 0x86, 0x6c, 0xe5, 0xfe, 0x0e, 0xd3, 0xbd, 0xc0, 0x9c, 0xbf, 0xf9,
+ 0x23, 0x62, 0xf2, 0xe5, 0xbc, 0xd1, 0xcb, 0xff, 0xfc, 0x9b, 0x9f, 0x1b,
+ 0xc1, 0x07, 0x04, 0x73, 0xc1, 0x7d, 0x1c, 0xbf, 0xdf, 0x4b, 0x73, 0x4a,
+ 0x27, 0x39, 0x41, 0x4d, 0xf1, 0x64, 0xee, 0x86, 0x26, 0x7e, 0x44, 0x03,
+ 0x25, 0xff, 0xff, 0xba, 0x9f, 0x7b, 0x3e, 0xf6, 0xb5, 0x1e, 0xfd, 0x41,
+ 0x97, 0x70, 0xe5, 0xfb, 0xb1, 0xc4, 0x30, 0x72, 0xf0, 0x5c, 0x4e, 0x5b,
+ 0x89, 0xcb, 0xf7, 0xde, 0x18, 0xe9, 0xcb, 0x6a, 0x0d, 0xdb, 0x89, 0xdc,
+ 0x0d, 0x1c, 0xa9, 0x22, 0xec, 0x25, 0x3a, 0x56, 0xd9, 0x2d, 0xff, 0xa5,
+ 0x03, 0xed, 0x27, 0x1c, 0x09, 0xcb, 0xff, 0x3f, 0xb6, 0x09, 0x28, 0x14,
+ 0xf1, 0xcb, 0xd8, 0x9b, 0x39, 0x7f, 0xfd, 0x3b, 0xf7, 0x03, 0xcb, 0x04,
+ 0x71, 0x3f, 0x39, 0x53, 0x9f, 0x5e, 0x86, 0xef, 0xfb, 0xab, 0x47, 0xe5,
+ 0xb7, 0xe9, 0xca, 0xc3, 0xdd, 0x72, 0x3b, 0xfb, 0xae, 0x3f, 0x49, 0x0e,
+ 0x5f, 0xff, 0xb6, 0x3c, 0xba, 0xe9, 0xef, 0xc0, 0x22, 0xf2, 0x39, 0x7f,
+ 0xba, 0x8a, 0xb4, 0x06, 0x95, 0x39, 0x7f, 0xd0, 0xdb, 0x3b, 0x08, 0x33,
+ 0x9c, 0xbf, 0xfe, 0x1c, 0xde, 0x32, 0x17, 0x9e, 0x4d, 0x61, 0xcb, 0x62,
+ 0xd1, 0x7b, 0xe3, 0x8e, 0x27, 0x37, 0xf4, 0xf9, 0xa4, 0x5c, 0x1c, 0xbe,
+ 0x10, 0xc3, 0x0e, 0x5f, 0xff, 0x00, 0x7d, 0xbe, 0xa4, 0xc3, 0x0c, 0x79,
+ 0x1c, 0xbe, 0xc1, 0x03, 0x9c, 0xa6, 0x1f, 0x7f, 0x14, 0xfb, 0xf9, 0xff,
+ 0xc0, 0xbc, 0x8e, 0x54, 0x23, 0x87, 0x21, 0x20, 0x84, 0x94, 0x89, 0xa0,
+ 0x76, 0x30, 0xea, 0x86, 0x4a, 0x8c, 0xf0, 0x83, 0x0c, 0x62, 0x79, 0x1d,
+ 0xb2, 0xd5, 0x92, 0x32, 0xb9, 0x8f, 0x58, 0x7f, 0xd8, 0xc2, 0x1c, 0x83,
+ 0xf2, 0xd1, 0x8c, 0x4f, 0xd1, 0xbb, 0xdf, 0xfd, 0x83, 0xfe, 0x66, 0xb7,
+ 0xe8, 0xc3, 0x97, 0xfd, 0xf7, 0xb3, 0x49, 0x3b, 0xb0, 0xe5, 0xec, 0xe3,
+ 0x87, 0x2d, 0x9f, 0xa2, 0x64, 0x50, 0xb6, 0x75, 0x7b, 0x87, 0x92, 0x1c,
+ 0xbe, 0x81, 0x79, 0x1c, 0xbf, 0x63, 0x5b, 0x8f, 0xfc, 0x8f, 0x07, 0x44,
+ 0x37, 0xf7, 0x1e, 0xa4, 0x6b, 0x67, 0x2f, 0xfd, 0xd4, 0x60, 0x72, 0x68,
+ 0xcd, 0x1c, 0xbd, 0x28, 0xf8, 0xe5, 0xf4, 0x7e, 0xec, 0x39, 0x70, 0xcb,
+ 0x0f, 0xf6, 0x63, 0xe1, 0x1d, 0xbe, 0xda, 0x7a, 0x0e, 0x54, 0x1e, 0xd3,
+ 0x9c, 0xdf, 0xfc, 0xb4, 0xd7, 0x21, 0x79, 0xc6, 0x3e, 0x39, 0x7c, 0xbe,
+ 0xa4, 0xc7, 0x2f, 0xff, 0xc3, 0x8a, 0xaa, 0x81, 0xea, 0x4d, 0xd4, 0xfb,
+ 0xc7, 0x2a, 0x0f, 0xef, 0x08, 0xef, 0x2d, 0xf4, 0x72, 0xfd, 0xb5, 0xc6,
+ 0x95, 0x39, 0x7f, 0x27, 0xff, 0x4b, 0x3c, 0x72, 0xba, 0x7e, 0x9f, 0x8e,
+ 0x71, 0x29, 0xbf, 0xa5, 0x88, 0x1e, 0xa1, 0xcb, 0xcf, 0xa5, 0x4e, 0x56,
+ 0x1e, 0x4b, 0x96, 0x5f, 0xfd, 0x9f, 0x7b, 0x68, 0x31, 0xfb, 0xb0, 0xe5,
+ 0xe9, 0x33, 0xa7, 0x2a, 0x73, 0xe1, 0xf2, 0x25, 0xfd, 0xf6, 0xf1, 0x90,
+ 0xd6, 0x72, 0xf2, 0xa8, 0xd9, 0xcb, 0xf3, 0x69, 0x82, 0xa9, 0xca, 0x43,
+ 0xc6, 0x00, 0xf5, 0x62, 0x2e, 0xdc, 0x8c, 0x5d, 0xee, 0xe5, 0x87, 0x2f,
+ 0xb6, 0x30, 0xc3, 0x95, 0x06, 0xe7, 0xe1, 0x8b, 0xdd, 0x93, 0x0e, 0x5d,
+ 0xd4, 0x39, 0x58, 0x6c, 0xfc, 0x3b, 0x50, 0xbb, 0x8b, 0x27, 0x6c, 0x43,
+ 0x56, 0x30, 0x6f, 0x88, 0x3b, 0x0c, 0x17, 0x84, 0xa0, 0xbd, 0xee, 0x33,
+ 0xc0, 0x33, 0x34, 0x54, 0xbf, 0xd1, 0x32, 0x7d, 0xb0, 0x30, 0xe5, 0xcc,
+ 0x59, 0xca, 0x9c, 0xf3, 0x02, 0x6b, 0x7f, 0x2c, 0x29, 0xc6, 0x02, 0x72,
+ 0xdd, 0x39, 0x6f, 0xce, 0x5d, 0xb9, 0x1c, 0xa7, 0x3e, 0x9f, 0xcb, 0xf6,
+ 0x22, 0x01, 0x2b, 0xfa, 0x79, 0xa5, 0xc3, 0x6a, 0x73, 0x97, 0x9f, 0x34,
+ 0x72, 0xf0, 0xe7, 0x8e, 0x57, 0x4d, 0xb0, 0x8d, 0xdd, 0xe1, 0x39, 0x7a,
+ 0x3e, 0xd9, 0xcb, 0xe4, 0x19, 0x61, 0xcb, 0xd3, 0xb8, 0x9c, 0xa0, 0x9e,
+ 0xcb, 0x07, 0x7c, 0x41, 0x7e, 0xcf, 0x75, 0x3c, 0x72, 0xfc, 0xff, 0x67,
+ 0xde, 0x39, 0x65, 0x7a, 0x7a, 0x1e, 0x27, 0xb4, 0xe7, 0x2d, 0xa3, 0x95,
+ 0x39, 0xa3, 0x41, 0x2b, 0xfa, 0x7e, 0x53, 0xbb, 0xf4, 0xe5, 0x35, 0x4a,
+ 0x86, 0x61, 0xb6, 0x44, 0x18, 0xde, 0x8f, 0xfd, 0x4c, 0x72, 0x1b, 0xfe,
+ 0xc0, 0x85, 0x3e, 0xcf, 0xbc, 0x72, 0xf9, 0x63, 0x12, 0x39, 0x5d, 0x3d,
+ 0xb7, 0x3a, 0xbf, 0xd1, 0x9e, 0x8e, 0xb8, 0x4e, 0x54, 0xe7, 0xa4, 0x12,
+ 0x1b, 0xec, 0xc1, 0xf1, 0xcb, 0xf0, 0x40, 0xfa, 0x91, 0xcb, 0xff, 0x83,
+ 0x01, 0xd4, 0x79, 0x16, 0x81, 0x39, 0x7d, 0x34, 0x70, 0x48, 0xe5, 0xfd,
+ 0xe5, 0x84, 0x2c, 0xd1, 0xcb, 0xfe, 0x9b, 0x7c, 0x5c, 0x67, 0x00, 0x4e,
+ 0x5f, 0x67, 0xb1, 0x87, 0x2e, 0x15, 0x4e, 0x5b, 0x6e, 0x6e, 0x00, 0x43,
+ 0x7f, 0x74, 0x13, 0xcd, 0xd4, 0x39, 0x7f, 0xf8, 0x41, 0x2c, 0xda, 0xfa,
+ 0x82, 0xf3, 0x9c, 0xbc, 0x39, 0xe3, 0x94, 0x87, 0xc8, 0x29, 0x35, 0x0a,
+ 0x94, 0xa7, 0x23, 0x91, 0x00, 0x4a, 0x31, 0x0d, 0x52, 0x64, 0x2f, 0x99,
+ 0xd7, 0xa4, 0xde, 0x84, 0xa5, 0xfd, 0xca, 0x68, 0xf0, 0xf1, 0x39, 0x7f,
+ 0xf8, 0x63, 0x8e, 0xa3, 0x58, 0x9d, 0x80, 0x9c, 0xb9, 0xd8, 0x72, 0xe9,
+ 0x9a, 0x1c, 0xa1, 0x36, 0x1c, 0x45, 0xaa, 0x48, 0xcd, 0xc3, 0x24, 0x79,
+ 0xb7, 0x36, 0xa9, 0xf5, 0x47, 0xda, 0xb4, 0x0e, 0x18, 0x77, 0x85, 0xd3,
+ 0x5a, 0x80, 0xe4, 0x4b, 0x6c, 0x9e, 0x30, 0x29, 0x4a, 0x08, 0x0c, 0xe9,
+ 0xe6, 0x52, 0x3a, 0x95, 0x8f, 0x0d, 0x72, 0xe8, 0xbe, 0x95, 0xb4, 0x91,
+ 0xb5, 0x4d, 0x38, 0x1f, 0xa9, 0x4f, 0x4c, 0x94, 0x31, 0xda, 0x41, 0x0b,
+ 0xca, 0xe0, 0xfe, 0x57, 0x57, 0x0f, 0x09, 0xc1, 0x9d, 0x29, 0xdd, 0x26,
+ 0xdf, 0xd3, 0xe7, 0x60, 0x87, 0xeb, 0x70, 0x8c, 0x69, 0x29, 0x55, 0x49,
+ 0x6c, 0xdc, 0x11, 0xaf, 0xd7, 0x37, 0xd7, 0xd2, 0xed, 0xea, 0xb8, 0xdf,
+ 0xfe, 0xe6, 0xc7, 0x97, 0x3c, 0xd2, 0xdd, 0xd6, 0x68, 0x9b, 0x17, 0xfb,
+ 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x55, 0xab, 0xfd, 0x29, 0x03, 0xc3, 0x12,
+ 0x39, 0x7d, 0x9d, 0x7f, 0x1c, 0xb7, 0x09, 0x87, 0xa8, 0x26, 0x77, 0xff,
+ 0xfe, 0x94, 0x71, 0x84, 0xd2, 0xd1, 0x8f, 0x24, 0x1c, 0x0e, 0x2a, 0x72,
+ 0xff, 0xf6, 0x92, 0x59, 0x2c, 0x79, 0x0c, 0x30, 0xe5, 0xfe, 0xd6, 0x2e,
+ 0x3f, 0x51, 0x87, 0x2f, 0xf7, 0x62, 0x7d, 0x46, 0x04, 0xe5, 0xff, 0xfa,
+ 0x27, 0x8d, 0x43, 0x22, 0x3d, 0xd4, 0xfd, 0x87, 0x2a, 0x11, 0x11, 0xd3,
+ 0x3a, 0x92, 0x72, 0x28, 0xd7, 0xa4, 0x7e, 0xc2, 0xf6, 0xfb, 0x4c, 0xe8,
+ 0x4e, 0x5f, 0xfd, 0xa9, 0x0e, 0x7b, 0x70, 0xcf, 0x2c, 0xe5, 0x41, 0xf3,
+ 0x80, 0x8e, 0xf0, 0x70, 0x4e, 0x5e, 0x77, 0x59, 0xa2, 0xb4, 0x5f, 0x95,
+ 0xfb, 0x60, 0xf8, 0xe5, 0x2c, 0xf5, 0x10, 0xa2, 0xff, 0xf2, 0x7a, 0x50,
+ 0xbe, 0xa7, 0xb6, 0xff, 0x1c, 0xad, 0x1f, 0x5f, 0x12, 0x1b, 0xfc, 0x1f,
+ 0xf9, 0x66, 0x91, 0x53, 0x97, 0xff, 0xba, 0x8c, 0x85, 0xe3, 0x30, 0x7c,
+ 0xd0, 0xe5, 0xe9, 0x7d, 0x23, 0x97, 0xff, 0xf3, 0xa7, 0x04, 0x08, 0x24,
+ 0x9b, 0xdc, 0x72, 0x62, 0xce, 0x5f, 0xff, 0x2e, 0x35, 0x9f, 0xbb, 0x1e,
+ 0x50, 0x8b, 0x39, 0x7f, 0xfd, 0x2d, 0xe0, 0xc3, 0x1f, 0x3d, 0xe8, 0x61,
+ 0xcb, 0x7a, 0x11, 0x36, 0xe9, 0xd5, 0xd4, 0xc8, 0x3d, 0x0f, 0x9b, 0xff,
+ 0xff, 0xd1, 0xc5, 0x3d, 0xbc, 0x55, 0x7d, 0x4f, 0x64, 0xc3, 0x0c, 0x9f,
+ 0x1b, 0x39, 0x7f, 0xa3, 0xcf, 0xde, 0x41, 0x83, 0x97, 0xd2, 0xf2, 0x4e,
+ 0x72, 0xfc, 0xa7, 0x86, 0x3f, 0x39, 0x5f, 0x1e, 0x67, 0x12, 0x3b, 0xfc,
+ 0xf2, 0xf2, 0x4f, 0xd4, 0x39, 0x50, 0x7b, 0x08, 0x4b, 0x7e, 0xce, 0xa6,
+ 0x30, 0xe5, 0xf9, 0x3f, 0x62, 0x68, 0xe5, 0xff, 0xc2, 0xe8, 0xbe, 0xb8,
+ 0x27, 0xd2, 0x1c, 0xa9, 0xd1, 0x22, 0x12, 0x6e, 0x94, 0x5f, 0xe9, 0x46,
+ 0xa7, 0x8d, 0x4e, 0x72, 0xfa, 0x5a, 0xc6, 0x1c, 0xbd, 0x9a, 0xfc, 0xe5,
+ 0xfa, 0x6c, 0x0b, 0x1a, 0xce, 0x5f, 0xc3, 0x0d, 0xfd, 0x2d, 0x9c, 0xaf,
+ 0x91, 0x34, 0x84, 0x53, 0x0e, 0xf0, 0x16, 0x54, 0x26, 0x21, 0x90, 0xcf,
+ 0xbf, 0xff, 0xff, 0xb1, 0x17, 0x9e, 0x81, 0xf6, 0xf9, 0x42, 0x07, 0x19,
+ 0xcb, 0x50, 0x92, 0x7d, 0x9c, 0xbf, 0xb3, 0xce, 0x3f, 0x80, 0xe5, 0xfd,
+ 0xde, 0x49, 0x3b, 0x89, 0xcb, 0xfd, 0x0c, 0xd8, 0x45, 0xdb, 0x39, 0x7c,
+ 0xff, 0xb8, 0x4e, 0x54, 0x91, 0x63, 0x85, 0xa2, 0x5f, 0xb3, 0x3b, 0x73,
+ 0xe1, 0x99, 0x49, 0x91, 0x1d, 0xe4, 0xf0, 0xa9, 0x09, 0x0e, 0x43, 0x69,
+ 0x52, 0x45, 0x9b, 0xfc, 0x94, 0x91, 0x9f, 0x68, 0xa5, 0x8f, 0x7d, 0x86,
+ 0xc3, 0xc2, 0xc4, 0x63, 0x41, 0xd9, 0x3f, 0xa3, 0x39, 0xbf, 0x69, 0x6e,
+ 0xeb, 0x34, 0x58, 0x0b, 0xf3, 0xad, 0x4e, 0xcc, 0x72, 0xdc, 0xf0, 0xf7,
+ 0xb6, 0x69, 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0x9d, 0x57, 0xff, 0xfb, 0xb1,
+ 0x38, 0x71, 0x9c, 0xf7, 0xbc, 0xea, 0x6c, 0x13, 0x9c, 0xbf, 0x73, 0x63,
+ 0xcb, 0x9e, 0x22, 0x66, 0x63, 0x4b, 0xff, 0xfd, 0x02, 0x08, 0xf6, 0xf0,
+ 0x79, 0xff, 0xfc, 0x75, 0xe7, 0x39, 0x79, 0x58, 0x61, 0xcb, 0xe7, 0x5a,
+ 0x8c, 0x39, 0x7a, 0x5b, 0xe6, 0xa9, 0xe0, 0x71, 0x1d, 0xbf, 0x69, 0x6e,
+ 0xeb, 0x34, 0x5b, 0x2b, 0xfb, 0xcf, 0xde, 0x41, 0x83, 0x97, 0xff, 0xf4,
+ 0xb9, 0xee, 0x13, 0x02, 0x99, 0xbc, 0xf0, 0xc1, 0xca, 0x84, 0x44, 0x39,
+ 0x7d, 0xfa, 0x50, 0x9c, 0x60, 0xe5, 0xff, 0x46, 0xf9, 0xf5, 0x16, 0xfa,
+ 0x39, 0x50, 0x7c, 0x5f, 0x94, 0x5f, 0xf4, 0x4a, 0x35, 0x3c, 0x6a, 0x73,
+ 0x96, 0xe7, 0x89, 0xcd, 0xb2, 0x17, 0x8f, 0x08, 0x31, 0x22, 0xbf, 0xf0,
+ 0xf3, 0x60, 0x13, 0xc2, 0xfc, 0x07, 0x2f, 0xfe, 0x06, 0xf9, 0xe6, 0x9f,
+ 0x7d, 0x79, 0x1c, 0xb9, 0xff, 0xc4, 0x44, 0x7e, 0x85, 0x77, 0xcb, 0x39,
+ 0x7c, 0xb7, 0x75, 0x9a, 0x2e, 0x65, 0x98, 0x72, 0xb4, 0x6f, 0xdb, 0x2e,
+ 0xbf, 0xda, 0x1c, 0xfb, 0xf4, 0x91, 0xcb, 0xa6, 0x61, 0xca, 0x39, 0x6e,
+ 0x70, 0x8d, 0x0c, 0x57, 0x42, 0x26, 0xcd, 0x1a, 0x0c, 0x5f, 0xb4, 0xb7,
+ 0x75, 0x9a, 0x2e, 0xf5, 0xfe, 0x97, 0x3d, 0xeb, 0x48, 0xd9, 0xcb, 0x73,
+ 0xc3, 0xeb, 0x73, 0x4b, 0xee, 0x6a, 0x87, 0xf3, 0x95, 0x0f, 0xd6, 0x85,
+ 0x97, 0xb0, 0x00, 0xb3, 0x8f, 0x96, 0x92, 0x95, 0xc3, 0xa8, 0xdc, 0x99,
+ 0x0c, 0x2e, 0xa2, 0x3c, 0x28, 0xff, 0x8f, 0x50, 0x61, 0xab, 0xb8, 0x7f,
+ 0xfa, 0x17, 0xaa, 0x14, 0x5f, 0xf9, 0xb7, 0x19, 0xf6, 0x83, 0xf4, 0x8e,
+ 0x5f, 0xfd, 0x93, 0xe3, 0x7d, 0xcd, 0xe2, 0x09, 0xcb, 0x93, 0x9f, 0x51,
+ 0x06, 0x28, 0x17, 0xed, 0xed, 0x8f, 0x23, 0x97, 0xff, 0xff, 0xfe, 0xea,
+ 0x75, 0x20, 0x7c, 0x2e, 0xae, 0x78, 0x1e, 0x4f, 0x6f, 0xa9, 0xa8, 0x9d,
+ 0xf4, 0xb3, 0x97, 0x6e, 0x0e, 0x5f, 0xfd, 0xf2, 0xc0, 0xff, 0x7b, 0x30,
+ 0x55, 0x39, 0x78, 0x5f, 0x9c, 0x26, 0x38, 0xb2, 0x8d, 0xc2, 0x63, 0xc2,
+ 0xd7, 0x80, 0xec, 0x39, 0x7e, 0xce, 0x0f, 0x42, 0xa7, 0x2d, 0xc0, 0x72,
+ 0xa7, 0x37, 0xf8, 0x57, 0x5a, 0x3f, 0xc1, 0x5b, 0xbf, 0xf6, 0xdd, 0x5e,
+ 0xa4, 0x08, 0x20, 0xe5, 0xff, 0xba, 0xfe, 0x7e, 0xfd, 0x2c, 0xf1, 0xca,
+ 0xc3, 0xfc, 0x43, 0xdb, 0x9f, 0xf3, 0x97, 0xff, 0xff, 0x85, 0xdb, 0x1c,
+ 0xf7, 0xb2, 0x78, 0x17, 0x57, 0x6c, 0x8c, 0x10, 0x9c, 0xbd, 0x8a, 0x6c,
+ 0xe5, 0x62, 0x2a, 0x74, 0x2f, 0xc0, 0xeb, 0x7f, 0xbb, 0x81, 0x4e, 0x3a,
+ 0xc3, 0x97, 0xf9, 0xe5, 0xac, 0x68, 0x9f, 0x9c, 0xbc, 0xee, 0xb3, 0x44,
+ 0xae, 0xbf, 0xca, 0xb8, 0xff, 0xec, 0xe9, 0xca, 0x59, 0xee, 0x21, 0x45,
+ 0xfe, 0xf8, 0x5d, 0x57, 0xf4, 0x8e, 0x5f, 0xfd, 0xdc, 0x92, 0xfa, 0x81,
+ 0x81, 0xf1, 0xca, 0x43, 0xf7, 0xf1, 0xa5, 0x49, 0x37, 0xe0, 0x9a, 0x6a,
+ 0x12, 0x23, 0x09, 0x8b, 0xfd, 0x1a, 0x79, 0x3f, 0xd2, 0x39, 0x7f, 0xff,
+ 0xfd, 0xa7, 0x15, 0x23, 0xfc, 0x97, 0x63, 0x88, 0x63, 0x9e, 0x08, 0x25,
+ 0x9b, 0x39, 0x74, 0xa7, 0x39, 0x7f, 0xff, 0x9f, 0xed, 0xe6, 0xbd, 0xe7,
+ 0x9d, 0x46, 0x07, 0xa8, 0xa9, 0xcb, 0xfe, 0xc4, 0xe2, 0x31, 0x9a, 0x91,
+ 0xcb, 0xff, 0xf7, 0xa5, 0x8d, 0x6e, 0x3f, 0xfd, 0xed, 0x46, 0x36, 0x71,
+ 0xb3, 0x71, 0x7e, 0xfb, 0xdd, 0x8f, 0xce, 0x53, 0xa2, 0x54, 0x0d, 0x77,
+ 0xff, 0xa6, 0x18, 0xf6, 0xfd, 0xf2, 0xd0, 0x67, 0x39, 0x7f, 0xce, 0xd8,
+ 0x7b, 0x13, 0xe3, 0x67, 0x29, 0x11, 0x0e, 0x29, 0x97, 0xff, 0xec, 0x4f,
+ 0xf1, 0x89, 0xed, 0xc3, 0x1f, 0xef, 0x1c, 0xbf, 0xe8, 0x67, 0xb2, 0x69,
+ 0x27, 0x8e, 0x54, 0x91, 0x1d, 0xe5, 0x5b, 0xe0, 0x3e, 0xa4, 0x72, 0xfe,
+ 0x18, 0x9f, 0xf7, 0xf1, 0xcb, 0xfc, 0xe1, 0x53, 0x82, 0x06, 0x47, 0x2d,
+ 0x0b, 0x3e, 0x46, 0x17, 0x5f, 0xff, 0xe4, 0xf3, 0xb1, 0xc7, 0xfe, 0xb6,
+ 0xe3, 0x3a, 0xd2, 0x73, 0x94, 0x14, 0xc3, 0xd2, 0x10, 0xce, 0x4f, 0x7f,
+ 0xc0, 0xfd, 0x8f, 0x2d, 0xe8, 0x27, 0x2f, 0xff, 0xf6, 0x20, 0xfb, 0x07,
+ 0x90, 0xb8, 0x60, 0x67, 0x8d, 0x1c, 0xb6, 0x79, 0x13, 0x3c, 0x4e, 0xef,
+ 0xfb, 0xef, 0xf3, 0x59, 0x9e, 0xd9, 0xca, 0x0a, 0xb1, 0x2c, 0x85, 0x7f,
+ 0x63, 0x32, 0x18, 0x66, 0xa8, 0x55, 0x7f, 0xec, 0xef, 0x5e, 0x5f, 0xeb,
+ 0x3e, 0x39, 0x7f, 0xd9, 0xf6, 0xc3, 0x0e, 0x33, 0x9c, 0xbf, 0xe7, 0x96,
+ 0xfb, 0x1a, 0x50, 0x27, 0x2a, 0x48, 0xb3, 0xc4, 0x0f, 0x1c, 0xdf, 0xfd,
+ 0xe4, 0xe2, 0x9e, 0x9a, 0x50, 0x3e, 0x39, 0x7f, 0xf9, 0xf2, 0x5d, 0xc4,
+ 0x1c, 0xfd, 0xa6, 0x1c, 0xbc, 0xf2, 0xe7, 0x0c, 0xae, 0x19, 0x42, 0x74,
+ 0x30, 0xc9, 0xc8, 0xec, 0x3e, 0x47, 0xd1, 0x9b, 0x21, 0x01, 0xf8, 0xc0,
+ 0xc6, 0x65, 0xb9, 0x77, 0x7e, 0x8c, 0x39, 0x42, 0xfe, 0x04, 0x6b, 0xff,
+ 0xd9, 0xde, 0x63, 0x81, 0x41, 0xf6, 0x74, 0xe5, 0xef, 0x40, 0x4a, 0x5f,
+ 0xfe, 0xeb, 0xa7, 0xa2, 0x49, 0xa9, 0xc1, 0xf9, 0x4b, 0xfc, 0xeb, 0xe6,
+ 0x1d, 0x70, 0xfc, 0xe0, 0xf9, 0xf6, 0x39, 0x6e, 0x61, 0x67, 0x79, 0xae,
+ 0x34, 0xb6, 0x52, 0xec, 0x7d, 0x0f, 0x4e, 0x30, 0xb0, 0xbf, 0xfd, 0xcd,
+ 0x8f, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x30, 0xaf, 0xff, 0xec, 0xe2,
+ 0xe1, 0xec, 0x73, 0xf7, 0x70, 0x20, 0xf6, 0xce, 0x5f, 0xfe, 0xd3, 0xff,
+ 0xcd, 0x5f, 0x49, 0xb8, 0xdc, 0x8e, 0x5d, 0x9c, 0xc5, 0x15, 0xea, 0x2f,
+ 0xdc, 0xce, 0x27, 0x2f, 0xfe, 0xe1, 0x33, 0xe9, 0x01, 0xfc, 0x31, 0x23,
+ 0x97, 0xe6, 0xad, 0xab, 0x6a, 0x5a, 0x35, 0x47, 0x2f, 0xd8, 0xce, 0x5f,
+ 0x35, 0x9c, 0xbf, 0xa1, 0x99, 0xfc, 0x71, 0x39, 0x41, 0x3d, 0xde, 0x97,
+ 0x5f, 0xed, 0x62, 0xe3, 0xf5, 0x18, 0x72, 0xfe, 0x8d, 0x43, 0x13, 0x47,
+ 0x2f, 0xdd, 0x80, 0xa2, 0xa7, 0x29, 0x11, 0x57, 0xa2, 0x26, 0x1a, 0xf0,
+ 0x16, 0x5e, 0xe2, 0xfb, 0x39, 0x7f, 0xa1, 0xe7, 0xf2, 0xaf, 0xa3, 0x97,
+ 0xe7, 0xd4, 0x9d, 0x87, 0x2b, 0x0f, 0xe4, 0x47, 0x80, 0x69, 0x7f, 0xb7,
+ 0x18, 0x21, 0xec, 0x1c, 0xbf, 0xa3, 0x04, 0x3d, 0x83, 0x97, 0x81, 0xa9,
+ 0xb9, 0x1e, 0xe6, 0xcc, 0x6f, 0xff, 0x69, 0x01, 0x8a, 0xe7, 0x81, 0x1f,
+ 0x04, 0xe5, 0xff, 0xf9, 0x35, 0xd7, 0xe4, 0x1c, 0x97, 0x63, 0x88, 0x60,
+ 0xe5, 0xff, 0x36, 0xa7, 0x61, 0x7d, 0x49, 0x8e, 0x5f, 0x01, 0x98, 0x13,
+ 0x96, 0xcf, 0x8f, 0x7b, 0x80, 0xf2, 0xfe, 0x8d, 0x44, 0xb7, 0x87, 0x29,
+ 0x69, 0xc7, 0xe8, 0xdf, 0xa9, 0x63, 0x0b, 0x6f, 0x15, 0xdf, 0xfe, 0x85,
+ 0xec, 0x1e, 0x4e, 0xa2, 0xbd, 0x43, 0x97, 0xf3, 0x23, 0x07, 0xcd, 0x0e,
+ 0x5b, 0x67, 0x2f, 0xd1, 0x83, 0xe6, 0x87, 0x2f, 0x6d, 0xfe, 0xe4, 0x7c,
+ 0xf3, 0x17, 0x30, 0x46, 0x98, 0x8f, 0x5f, 0x42, 0xc6, 0xff, 0x9a, 0xf0,
+ 0x3d, 0x86, 0xb1, 0x83, 0x94, 0x87, 0xca, 0xe5, 0x17, 0xfd, 0xa9, 0xd7,
+ 0xd4, 0xe8, 0x3c, 0x72, 0xba, 0x7b, 0x6e, 0x41, 0x7f, 0x7a, 0x19, 0xc7,
+ 0xf9, 0x1c, 0xbb, 0xc8, 0x72, 0xa4, 0x78, 0xea, 0x98, 0xde, 0xd0, 0x36,
+ 0x72, 0xff, 0xfb, 0xb0, 0x39, 0xee, 0xe7, 0xbb, 0x00, 0xe1, 0xce, 0x5f,
+ 0xff, 0xe6, 0xf8, 0x3d, 0x9d, 0xe4, 0x39, 0x3a, 0x60, 0xfd, 0x2d, 0x9c,
+ 0xbf, 0x37, 0xec, 0xea, 0xce, 0x56, 0x22, 0x41, 0xd9, 0xeb, 0x13, 0x21,
+ 0x41, 0xd1, 0x87, 0x1d, 0xff, 0xef, 0x0b, 0xff, 0xdc, 0x40, 0x83, 0xdb,
+ 0x39, 0x7d, 0xc7, 0x03, 0x07, 0x2f, 0xfa, 0x27, 0x52, 0x5d, 0x03, 0xce,
+ 0x72, 0xa1, 0x15, 0x38, 0x95, 0xa2, 0x3b, 0xff, 0xb3, 0xe9, 0x72, 0xeb,
+ 0xae, 0x04, 0x27, 0x2f, 0x92, 0x3e, 0xd9, 0xcb, 0xf2, 0x9e, 0x18, 0xfc,
+ 0xe5, 0x78, 0xf2, 0xf8, 0x91, 0x5f, 0x7b, 0xd8, 0xd9, 0xcb, 0xff, 0xd1,
+ 0xef, 0xe2, 0x59, 0xf7, 0xa7, 0x03, 0x67, 0x2f, 0x6d, 0xff, 0x39, 0x50,
+ 0x8b, 0x2c, 0x24, 0x42, 0x3f, 0x27, 0x5c, 0xf2, 0x39, 0x7f, 0xf9, 0x37,
+ 0x12, 0xe5, 0x9d, 0x4d, 0x75, 0xce, 0x53, 0x59, 0xf0, 0x74, 0x5a, 0xfe,
+ 0x7f, 0xf5, 0xa4, 0xd1, 0xcb, 0xde, 0xe5, 0x87, 0x2b, 0xf3, 0xcc, 0x50,
+ 0xba, 0xfb, 0xa0, 0xfb, 0xc7, 0x2f, 0xfd, 0xd4, 0xf2, 0x63, 0x07, 0x27,
+ 0x39, 0x7f, 0x6d, 0x15, 0x63, 0xf8, 0xe5, 0xff, 0xb8, 0xc2, 0xb2, 0x41,
+ 0x8d, 0x41, 0xcb, 0xff, 0xff, 0x6b, 0x38, 0xc0, 0xfb, 0x92, 0x83, 0x1d,
+ 0x74, 0xf4, 0x7b, 0x67, 0x2f, 0xe1, 0xcd, 0xf2, 0x5f, 0x0c, 0x72, 0x96,
+ 0x9a, 0x67, 0xc7, 0xa8, 0x5d, 0xa3, 0xfe, 0x2d, 0xd7, 0xdc, 0xb8, 0xf0,
+ 0x4e, 0x72, 0x82, 0x9f, 0x46, 0x46, 0xe0, 0xaa, 0x6d, 0x9a, 0xce, 0x5f,
+ 0x99, 0xac, 0x0f, 0x8e, 0x5d, 0xec, 0x39, 0x7f, 0xc1, 0x81, 0x8f, 0xdd,
+ 0xf8, 0x0e, 0x5f, 0xb7, 0x9e, 0xd4, 0x1c, 0xbf, 0xfd, 0xc3, 0x8c, 0x31,
+ 0xd3, 0xaf, 0xee, 0xc1, 0xca, 0x84, 0x61, 0xa0, 0xb6, 0xce, 0x80, 0x4f,
+ 0x73, 0xac, 0xe5, 0xfc, 0x93, 0x3a, 0xf7, 0x23, 0x94, 0xb3, 0xc4, 0xe8,
+ 0xb5, 0xff, 0xfe, 0xea, 0x08, 0x75, 0x8b, 0xec, 0x77, 0x35, 0xa8, 0x54,
+ 0xe5, 0xf8, 0x1c, 0x09, 0x8c, 0x39, 0x7e, 0xf3, 0xb1, 0x3c, 0x72, 0x95,
+ 0x3d, 0x11, 0x2a, 0xbf, 0xf2, 0x78, 0x1a, 0x7d, 0xf2, 0x67, 0x8e, 0x54,
+ 0x1f, 0x1b, 0x91, 0x5f, 0xf6, 0x26, 0x30, 0x72, 0x77, 0x39, 0x7e, 0x8f,
+ 0x6f, 0xf0, 0x1c, 0xa6, 0xa9, 0x59, 0x9c, 0x0a, 0x64, 0x3a, 0xd6, 0xff,
+ 0x31, 0x17, 0x63, 0x14, 0x12, 0x0f, 0x1b, 0x5f, 0xff, 0xba, 0x39, 0xee,
+ 0xa6, 0x7d, 0xec, 0xe3, 0x1b, 0x39, 0x7c, 0xfb, 0xf4, 0xe7, 0x2f, 0xfe,
+ 0x71, 0xec, 0x20, 0x53, 0x79, 0x23, 0x97, 0xa3, 0xf5, 0x0e, 0x5f, 0xd9,
+ 0xc7, 0xa9, 0xfc, 0xc7, 0x2b, 0x13, 0x09, 0x55, 0x59, 0xc8, 0xc5, 0x07,
+ 0x63, 0xd7, 0xdd, 0x8d, 0xc1, 0xcb, 0xca, 0x07, 0x0e, 0x5e, 0xe1, 0xf7,
+ 0xc3, 0x1c, 0xa0, 0x9f, 0x2b, 0x90, 0xec, 0x76, 0xfb, 0x93, 0x39, 0x2c,
+ 0xe5, 0xec, 0x58, 0x4e, 0x5f, 0x7b, 0x07, 0xf3, 0x97, 0xf3, 0xb7, 0x1e,
+ 0xc9, 0xce, 0x56, 0x1f, 0x62, 0x0e, 0x09, 0x15, 0xf3, 0x73, 0x6e, 0x0e,
+ 0x5f, 0xf9, 0xfd, 0xb0, 0xe9, 0xfd, 0xd0, 0x1c, 0xaf, 0x8f, 0x8c, 0x49,
+ 0x2d, 0xcd, 0xaa, 0x6d, 0x28, 0x78, 0x61, 0x96, 0xa0, 0x93, 0x11, 0xa3,
+ 0x86, 0x17, 0x19, 0x28, 0x61, 0x72, 0x81, 0x3e, 0x68, 0x9a, 0x34, 0x4d,
+ 0x43, 0x71, 0x85, 0xdd, 0x8d, 0x0d, 0xe1, 0x35, 0xfb, 0x88, 0xca, 0x0c,
+ 0xdc, 0xb6, 0xaf, 0x47, 0x14, 0x08, 0x57, 0x36, 0x5c, 0xd2, 0x12, 0x6a,
+ 0x42, 0x3e, 0xff, 0xfb, 0x49, 0xf4, 0xb6, 0x9e, 0xec, 0x6b, 0xd0, 0x72,
+ 0xf3, 0xba, 0xcd, 0x15, 0x72, 0xfe, 0x75, 0x3b, 0xd7, 0x61, 0xca, 0x59,
+ 0xeb, 0x74, 0xa2, 0xfe, 0x4d, 0x75, 0xd4, 0x61, 0xca, 0xd1, 0xe8, 0x74,
+ 0x8a, 0xf8, 0x78, 0x36, 0xe7, 0x2f, 0x6a, 0x18, 0x72, 0xff, 0x46, 0xbd,
+ 0x03, 0x1f, 0x9c, 0xbf, 0xdc, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0x3c, 0x5f,
+ 0xf6, 0x07, 0x3a, 0x9a, 0xeb, 0x9c, 0xa9, 0x1f, 0xc3, 0x10, 0x6f, 0xfa,
+ 0x25, 0x1a, 0x9e, 0x35, 0x39, 0xcb, 0xfe, 0xf2, 0x03, 0x87, 0xc9, 0x4f,
+ 0x31, 0xcb, 0xf8, 0x73, 0xdb, 0xc6, 0xce, 0x54, 0x1f, 0x6b, 0xa0, 0x5f,
+ 0xf7, 0xcb, 0x4d, 0xf5, 0x3c, 0x87, 0x2f, 0xde, 0xf6, 0x0f, 0xe7, 0x2f,
+ 0xf7, 0x03, 0x86, 0x30, 0x28, 0x72, 0xdc, 0xc2, 0xae, 0x03, 0x21, 0xec,
+ 0x84, 0x5a, 0x24, 0xe8, 0xe3, 0xc2, 0xa8, 0x48, 0xb7, 0x0a, 0x7f, 0x10,
+ 0x28, 0x73, 0xc0, 0x51, 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0xb0, 0x57, 0x95,
+ 0x89, 0xce, 0x5f, 0xff, 0xc2, 0x07, 0x9d, 0x98, 0xd0, 0x1a, 0xcd, 0x49,
+ 0x49, 0x1c, 0xbf, 0x60, 0xe7, 0xb6, 0x72, 0xff, 0x69, 0xd8, 0xa6, 0x9f,
+ 0xe3, 0x96, 0xe7, 0x89, 0x86, 0x2a, 0x68, 0xb1, 0xe7, 0x5f, 0x50, 0x9a,
+ 0xff, 0x73, 0xcd, 0x2d, 0xdd, 0x66, 0x8b, 0x29, 0x7e, 0xd2, 0xdd, 0xd6,
+ 0x68, 0xb4, 0xd7, 0xfc, 0xe1, 0xeb, 0xcd, 0xd4, 0x61, 0xcb, 0x73, 0xc3,
+ 0xed, 0x61, 0xa5, 0xfb, 0x85, 0xda, 0x8b, 0x54, 0xd5, 0x35, 0x67, 0x2f,
+ 0xfb, 0x86, 0xea, 0x36, 0x17, 0x75, 0x9c, 0xbf, 0x70, 0xbf, 0x09, 0xbc,
+ 0x83, 0x97, 0xf9, 0x46, 0x67, 0xb6, 0x9b, 0x39, 0x64, 0x39, 0x5c, 0x31,
+ 0xe2, 0x34, 0x34, 0xbf, 0xd1, 0x3e, 0x9c, 0x33, 0xb9, 0xcb, 0xff, 0xf7,
+ 0x5c, 0x7d, 0x2c, 0xd6, 0x40, 0x8e, 0x78, 0xe5, 0x49, 0x10, 0xa8, 0x69,
+ 0x7e, 0xe2, 0xe1, 0xc6, 0x1c, 0xbe, 0x64, 0x7d, 0xb3, 0x97, 0xff, 0x26,
+ 0x3f, 0xf1, 0x2d, 0x46, 0x09, 0xcb, 0xe4, 0xe3, 0xde, 0x27, 0x2f, 0xf7,
+ 0x02, 0x7f, 0xc9, 0xfa, 0x03, 0x95, 0x24, 0xc3, 0xb0, 0x8a, 0x62, 0x91,
+ 0x23, 0xda, 0x0f, 0x01, 0x35, 0xfe, 0x62, 0x8c, 0xfd, 0x89, 0xf9, 0xcb,
+ 0xf7, 0x2d, 0x68, 0x1d, 0x39, 0x7e, 0x45, 0x60, 0x56, 0x72, 0xb6, 0x7a,
+ 0x5e, 0x2b, 0xa8, 0x45, 0x5e, 0x42, 0x26, 0xff, 0xf8, 0x57, 0xd4, 0xea,
+ 0x6a, 0x26, 0x6f, 0x3a, 0x72, 0xff, 0xdb, 0x4e, 0x5d, 0x7d, 0x47, 0x18,
+ 0x39, 0x7f, 0xcc, 0x79, 0x34, 0x07, 0x53, 0x47, 0x2b, 0x47, 0xf8, 0xc4,
+ 0x1b, 0xf3, 0xef, 0xd0, 0x13, 0x95, 0x07, 0x92, 0x02, 0x2b, 0xfc, 0xfa,
+ 0x93, 0xf9, 0xd6, 0x72, 0xa1, 0x36, 0x8e, 0xc6, 0x2a, 0x02, 0x1b, 0xe8,
+ 0x52, 0x3a, 0x72, 0xf9, 0x6e, 0xeb, 0x34, 0x5b, 0x8b, 0xe9, 0xa0, 0x38,
+ 0x72, 0xff, 0xd9, 0xac, 0x1e, 0x5d, 0xcf, 0x9b, 0x39, 0x7e, 0x1f, 0xdf,
+ 0xed, 0x9c, 0xa8, 0x3e, 0xa7, 0x41, 0xaf, 0x91, 0xf9, 0xa2, 0x27, 0x2e,
+ 0xdc, 0x23, 0x2f, 0xf3, 0x8f, 0xf3, 0x0c, 0x30, 0xe5, 0xe6, 0x0a, 0x1c,
+ 0xb0, 0x9c, 0xbf, 0xee, 0x81, 0xf7, 0x98, 0x2a, 0x9c, 0xbf, 0x6d, 0xfe,
+ 0x70, 0x9c, 0xb2, 0x04, 0xf8, 0x3c, 0x71, 0x50, 0x8b, 0x2c, 0x1b, 0xeb,
+ 0x85, 0xff, 0x43, 0x8f, 0x73, 0x05, 0x67, 0x2f, 0xf7, 0xbc, 0x93, 0xb2,
+ 0x04, 0xe5, 0x48, 0xfa, 0x30, 0xd6, 0xff, 0xa0, 0x40, 0xc8, 0xdf, 0x90,
+ 0xe5, 0xe8, 0xcd, 0x1c, 0xbf, 0xdd, 0x89, 0x23, 0x4c, 0x61, 0xca, 0x09,
+ 0xe7, 0xec, 0x6e, 0xfd, 0xcb, 0xed, 0xa2, 0xa7, 0x2c, 0xf3, 0x9e, 0x77,
+ 0xc4, 0x57, 0xff, 0x4b, 0x3a, 0x9a, 0x0f, 0x60, 0x56, 0x72, 0xff, 0x7d,
+ 0x28, 0x1f, 0x67, 0xe7, 0x2f, 0xb7, 0xfa, 0x78, 0xe5, 0x3a, 0x30, 0xf6,
+ 0x52, 0x04, 0x35, 0x0d, 0x2f, 0xcf, 0xaf, 0x67, 0x4e, 0x5f, 0xf9, 0x3f,
+ 0x89, 0x07, 0xb0, 0x2b, 0x39, 0x52, 0x3e, 0x5f, 0x13, 0xdf, 0xde, 0x96,
+ 0x6b, 0x36, 0x72, 0x8e, 0x5e, 0x03, 0xf8, 0xe5, 0xc0, 0x83, 0x95, 0x23,
+ 0x65, 0xe1, 0xca, 0x39, 0x7d, 0xf2, 0xd3, 0x47, 0x2f, 0x43, 0x39, 0xe2,
+ 0x23, 0x3e, 0x3d, 0x61, 0x0f, 0x82, 0xef, 0xf8, 0x7d, 0xd7, 0x90, 0x1d,
+ 0x43, 0x95, 0x09, 0xb2, 0x61, 0x12, 0x42, 0xe5, 0xd4, 0x2f, 0x0f, 0x9a,
+ 0x1c, 0xbd, 0xc9, 0xab, 0x6a, 0xce, 0x5f, 0xf4, 0xb9, 0xe6, 0x96, 0xee,
+ 0xb3, 0x45, 0x0e, 0xa4, 0x44, 0x74, 0xc3, 0xce, 0x53, 0x7e, 0xfe, 0x17,
+ 0x8c, 0x39, 0x7d, 0x13, 0x60, 0x4e, 0x56, 0x8f, 0x2b, 0x65, 0x17, 0xfd,
+ 0x90, 0x1e, 0xc7, 0x04, 0x4c, 0x72, 0xff, 0x7e, 0x9d, 0xee, 0x7e, 0xe7,
+ 0x29, 0x87, 0xdf, 0xf9, 0xdd, 0x42, 0x2d, 0x1e, 0x12, 0x37, 0xfe, 0x70,
+ 0xc0, 0x7a, 0x82, 0x8c, 0x39, 0x7f, 0xee, 0x2f, 0xad, 0xbf, 0x77, 0x13,
+ 0x9c, 0xbf, 0xdb, 0x02, 0xf3, 0xc3, 0x07, 0x29, 0x88, 0xaf, 0xe9, 0xe7,
+ 0x90, 0x6f, 0xfe, 0x04, 0xba, 0xfa, 0xfb, 0xd0, 0x93, 0x9c, 0xbf, 0xd2,
+ 0x8d, 0x4f, 0x1a, 0x9c, 0xe5, 0xf9, 0xf7, 0xc7, 0x36, 0x72, 0xa0, 0xf7,
+ 0xbf, 0x35, 0xbf, 0x72, 0xee, 0x7e, 0xe7, 0x2f, 0xe9, 0x3e, 0xb3, 0xef,
+ 0x1c, 0xbf, 0x82, 0xec, 0xea, 0x36, 0x72, 0xa0, 0xf7, 0x30, 0xba, 0xff,
+ 0xb3, 0xdb, 0x53, 0x7a, 0x7d, 0x9c, 0xbf, 0x27, 0xb6, 0xe8, 0x72, 0xff,
+ 0xb5, 0xfe, 0x9c, 0x7d, 0x9f, 0x9c, 0xa9, 0xd3, 0x40, 0xd4, 0x21, 0x98,
+ 0x41, 0xf9, 0xd0, 0x09, 0xaf, 0x29, 0xa9, 0x1c, 0xbf, 0x94, 0xf0, 0x23,
+ 0x27, 0x39, 0x7f, 0x7f, 0xd7, 0x4e, 0x80, 0xe5, 0x48, 0xfe, 0xe6, 0x1e,
+ 0xd1, 0x7d, 0xff, 0xcb, 0x18, 0xf0, 0xe7, 0x1c, 0xd4, 0x8e, 0x5f, 0xf0,
+ 0x05, 0x55, 0x3b, 0xd0, 0x6c, 0xe5, 0xff, 0x29, 0x1f, 0xcd, 0x28, 0xd4,
+ 0xe7, 0x2f, 0xe1, 0x7f, 0x29, 0x0b, 0x39, 0x4c, 0x3e, 0xa1, 0x3d, 0xbe,
+ 0x1f, 0xe7, 0xfc, 0xe5, 0x61, 0xe3, 0x21, 0x0d, 0xfe, 0xdf, 0x2f, 0x72,
+ 0x0e, 0x09, 0xcb, 0x7e, 0x72, 0xc9, 0xf1, 0xe4, 0xe8, 0xde, 0xfc, 0xff,
+ 0x6f, 0xc8, 0x72, 0xa1, 0x50, 0xce, 0x18, 0x22, 0x27, 0x61, 0xd8, 0x2d,
+ 0x3b, 0x28, 0xbf, 0x38, 0x15, 0x85, 0x0e, 0x5f, 0xb8, 0x6c, 0xd4, 0x6c,
+ 0xe5, 0x4c, 0x7a, 0xa2, 0x53, 0x7f, 0x67, 0x90, 0x38, 0xc3, 0x97, 0xc3,
+ 0x24, 0x61, 0xcb, 0x72, 0x98, 0xf3, 0x5c, 0xb2, 0xff, 0x6e, 0x26, 0xfa,
+ 0x59, 0xc4, 0xe5, 0x04, 0xf8, 0x5c, 0xaa, 0xff, 0xfc, 0x1e, 0xc2, 0x9c,
+ 0xfc, 0x2f, 0xfe, 0xf7, 0x1f, 0x94, 0xb8, 0x38, 0x72, 0xfd, 0x3c, 0x4e,
+ 0xfb, 0x39, 0x58, 0x89, 0x94, 0x5a, 0x71, 0x6b, 0xbf, 0x01, 0xcb, 0xf9,
+ 0xff, 0x98, 0x60, 0x27, 0x2f, 0xf8, 0x72, 0x70, 0xf7, 0x07, 0xc7, 0x2a,
+ 0x0f, 0xfb, 0xa3, 0x02, 0x5d, 0x4d, 0x4b, 0x6d, 0xe4, 0xd5, 0xa2, 0xb5,
+ 0x13, 0xee, 0x14, 0xef, 0x11, 0xde, 0x4a, 0x30, 0x50, 0xc7, 0x1d, 0x91,
+ 0x99, 0x2a, 0x84, 0xb8, 0x72, 0xfd, 0x09, 0x64, 0x21, 0x9a, 0x39, 0x7d,
+ 0x4a, 0x06, 0x64, 0x33, 0x7b, 0x19, 0x6b, 0xc3, 0x57, 0xf3, 0x01, 0x85,
+ 0x26, 0xe3, 0x62, 0xf4, 0xae, 0x60, 0x42, 0xbf, 0x8c, 0x34, 0x1a, 0x42,
+ 0xe9, 0x48, 0x55, 0xdf, 0xff, 0x97, 0xcf, 0xfd, 0x67, 0xcb, 0xea, 0x7b,
+ 0x6f, 0xf1, 0xca, 0xe6, 0xa8, 0xb4, 0x11, 0xe9, 0x5f, 0x46, 0xa4, 0xc3,
+ 0x97, 0xdf, 0x6d, 0xda, 0xce, 0x5e, 0x7d, 0x2a, 0x72, 0xdc, 0xe7, 0x3e,
+ 0x54, 0x22, 0x6c, 0x9a, 0xff, 0x73, 0xcd, 0x2d, 0xdd, 0x66, 0x8b, 0xcd,
+ 0x50, 0xee, 0x1a, 0x24, 0xe2, 0x18, 0xc2, 0x72, 0xb4, 0xd1, 0xfa, 0x74,
+ 0x33, 0x51, 0xde, 0xb1, 0x4f, 0xb0, 0xae, 0x1a, 0xe5, 0x23, 0x70, 0x92,
+ 0xe2, 0x71, 0x7f, 0xb9, 0xe6, 0x96, 0xee, 0xb3, 0x45, 0x2c, 0xbf, 0x69,
+ 0x6e, 0xeb, 0x34, 0x58, 0x4b, 0xff, 0xec, 0x10, 0xc7, 0x63, 0xef, 0x60,
+ 0xbb, 0x0e, 0x5e, 0x10, 0x2c, 0xe5, 0x41, 0xf4, 0xba, 0x6d, 0xb6, 0x72,
+ 0xfe, 0x06, 0x92, 0x77, 0x61, 0xcb, 0x73, 0xc4, 0x7e, 0x32, 0x13, 0xbb,
+ 0x20, 0x68, 0x23, 0x7f, 0xb9, 0xe6, 0x96, 0xee, 0xb3, 0x45, 0x96, 0xb4,
+ 0x8e, 0x5d, 0xa5, 0x4e, 0x5f, 0x73, 0x57, 0x85, 0x35, 0x27, 0x28, 0xa5,
+ 0xee, 0x6a, 0x30, 0xe5, 0x2c, 0xf7, 0x36, 0x62, 0x00, 0xba, 0x55, 0x16,
+ 0x82, 0x23, 0xb7, 0x4b, 0xa3, 0xa7, 0x2d, 0xf9, 0xcb, 0x95, 0x9c, 0xe5,
+ 0xb5, 0x23, 0x57, 0x82, 0x54, 0xb3, 0xe7, 0x74, 0x1b, 0x93, 0xf3, 0x97,
+ 0xfc, 0xff, 0x0e, 0x7d, 0xe8, 0x54, 0xe5, 0xfe, 0x9f, 0xed, 0xc0, 0x7c,
+ 0x87, 0x2f, 0xd1, 0x9c, 0x63, 0x67, 0x2d, 0x0e, 0x7b, 0xad, 0x9a, 0xd3,
+ 0xa2, 0xf8, 0x61, 0x2f, 0x7c, 0xf2, 0x90, 0x4e, 0x5f, 0xcf, 0xa8, 0xf3,
+ 0xf4, 0xe5, 0xe6, 0xdb, 0x6c, 0xa5, 0xff, 0x44, 0xbe, 0xf6, 0xa3, 0x3e,
+ 0x29, 0xcc, 0xd0, 0x5f, 0xf0, 0x1f, 0xec, 0xf2, 0x7c, 0xd9, 0xcb, 0xa3,
+ 0x67, 0x28, 0x29, 0x85, 0xf4, 0x88, 0x53, 0x36, 0x99, 0xc4, 0xee, 0xee,
+ 0x14, 0xd4, 0x9c, 0xbf, 0x91, 0xf7, 0xfe, 0xc0, 0x72, 0xff, 0xe4, 0x93,
+ 0xed, 0xc4, 0x0b, 0xcd, 0x94, 0xbf, 0xff, 0xba, 0x9e, 0xee, 0x6c, 0x71,
+ 0x80, 0xdf, 0x5e, 0x47, 0x2f, 0xf4, 0x4b, 0xcf, 0xd7, 0x09, 0xca, 0x84,
+ 0x67, 0x62, 0x16, 0x96, 0xad, 0x23, 0x96, 0x91, 0xcb, 0x48, 0xe5, 0x96,
+ 0x72, 0xa0, 0xf1, 0x15, 0x11, 0x41, 0x1f, 0xc4, 0x6f, 0xe0, 0x6f, 0xaf,
+ 0x2c, 0x39, 0x7f, 0xfd, 0xb4, 0x5e, 0x0e, 0xa0, 0x70, 0x38, 0xa9, 0xca,
+ 0x61, 0xfd, 0x78, 0xb6, 0xdf, 0x1c, 0xb2, 0xa7, 0x2c, 0x03, 0x94, 0x26,
+ 0x8f, 0x62, 0x55, 0x87, 0xef, 0xb2, 0x2f, 0x1a, 0xdd, 0xb5, 0x4e, 0x5b,
+ 0x0e, 0x5c, 0x0f, 0xe0, 0xd4, 0x04, 0x62, 0xe4, 0x83, 0x97, 0xf0, 0xc3,
+ 0x06, 0x30, 0xe5, 0xff, 0xd0, 0xfa, 0xf7, 0x70, 0x20, 0xf6, 0xce, 0x5d,
+ 0x28, 0x39, 0x7b, 0x61, 0x54, 0xe5, 0x4e, 0x8e, 0x40, 0x96, 0xcc, 0x2b,
+ 0xd2, 0xa0, 0x22, 0x28, 0x2d, 0x7f, 0xff, 0xfd, 0xd8, 0xf6, 0xd3, 0x7b,
+ 0x8f, 0x75, 0x23, 0x5f, 0xb1, 0xe5, 0x2f, 0x2a, 0x72, 0xe4, 0xf8, 0xe5,
+ 0xd0, 0xc3, 0x97, 0xff, 0xe8, 0x10, 0x4a, 0x51, 0xee, 0xe3, 0x14, 0x8f,
+ 0xce, 0x5f, 0xff, 0x20, 0x82, 0x59, 0xbd, 0x42, 0x49, 0xf6, 0x52, 0xa4,
+ 0x8a, 0x3f, 0x2b, 0x5c, 0xbe, 0x70, 0xc8, 0xcd, 0x9e, 0x12, 0xf2, 0x21,
+ 0x0c, 0x35, 0x72, 0x33, 0x15, 0x53, 0x16, 0x45, 0xa8, 0x7e, 0x3b, 0x90,
+ 0xc6, 0x5b, 0xb8, 0xce, 0xbc, 0xb5, 0xc5, 0xfd, 0xa0, 0xba, 0x90, 0xb9,
+ 0xbf, 0xfd, 0xcd, 0x8f, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x46, 0x2f,
+ 0xdc, 0x63, 0x51, 0xf9, 0xcb, 0xf0, 0xbf, 0xf0, 0xa1, 0xcb, 0xff, 0x27,
+ 0xd2, 0xd8, 0xe7, 0xba, 0x03, 0x97, 0xfc, 0x9a, 0xee, 0x60, 0xcb, 0x67,
+ 0x2d, 0xf4, 0x8f, 0xd9, 0x67, 0xf7, 0xfe, 0x79, 0x2f, 0xa8, 0xc8, 0xd2,
+ 0xa7, 0x2d, 0xce, 0x13, 0x30, 0xe9, 0x57, 0xa1, 0x3c, 0xd9, 0x4d, 0x49,
+ 0x9c, 0x4d, 0xa8, 0xcf, 0x58, 0x96, 0xf4, 0x9c, 0x2d, 0xc6, 0x0f, 0xe8,
+ 0xe2, 0xaf, 0xfe, 0xe6, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x11, 0xca,
+ 0xff, 0xf7, 0x36, 0x3c, 0xb9, 0xe6, 0x96, 0xee, 0xb3, 0x44, 0xe4, 0xbf,
+ 0xdc, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0xcc, 0x5f, 0xf4, 0xb6, 0xec, 0xe7,
+ 0xdf, 0x7e, 0x72, 0xff, 0xb8, 0x58, 0x38, 0xc8, 0xfa, 0x18, 0x72, 0xff,
+ 0x6a, 0x3d, 0xd7, 0xfa, 0x47, 0x2f, 0xff, 0xff, 0xa2, 0x6e, 0xc7, 0xa1,
+ 0x44, 0xd4, 0xd1, 0xdc, 0xe3, 0x9d, 0xc0, 0xf1, 0xc3, 0x95, 0xfa, 0x2d,
+ 0x44, 0xd2, 0xff, 0xb3, 0x6f, 0xef, 0xd4, 0x19, 0x1c, 0xbf, 0xd9, 0xbd,
+ 0x6b, 0x3e, 0xd9, 0xcb, 0xda, 0xc6, 0x1c, 0xbe, 0x41, 0xcd, 0x9c, 0xb6,
+ 0x78, 0xde, 0x70, 0x0e, 0x5f, 0xf9, 0x06, 0x37, 0x1e, 0x9f, 0x1b, 0x39,
+ 0x77, 0x25, 0x0e, 0x5f, 0xda, 0x5f, 0x5d, 0x38, 0x73, 0x97, 0xe7, 0x18,
+ 0xe2, 0x03, 0x97, 0x7c, 0xc3, 0x97, 0xff, 0x34, 0x71, 0xff, 0x3d, 0x02,
+ 0x9f, 0x9c, 0xb7, 0x36, 0xa5, 0x57, 0xd4, 0x43, 0xd6, 0x72, 0x39, 0x1d,
+ 0x05, 0xc1, 0x85, 0x3b, 0x3e, 0x00, 0xd7, 0x13, 0x26, 0x85, 0x0a, 0x0c,
+ 0x5f, 0xee, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x6e, 0xaf, 0xe1, 0x7e, 0x7a,
+ 0x9f, 0xa7, 0x2f, 0x27, 0xdf, 0x9c, 0xbf, 0xfb, 0x4e, 0xbf, 0xc1, 0xbf,
+ 0x47, 0xcd, 0x9c, 0xb8, 0x55, 0x39, 0x7c, 0xb7, 0x75, 0x9a, 0x29, 0x05,
+ 0x61, 0xe2, 0xe8, 0x5e, 0xff, 0x4b, 0xc8, 0xde, 0xff, 0x43, 0x97, 0xfe,
+ 0xce, 0xa7, 0x1e, 0xe6, 0x0a, 0xce, 0x5e, 0x79, 0x73, 0x0a, 0x64, 0x39,
+ 0x08, 0xdf, 0x88, 0x76, 0x6b, 0x7f, 0x90, 0x20, 0xf6, 0xd8, 0x27, 0x2f,
+ 0x38, 0xc8, 0xe5, 0xb9, 0xad, 0x50, 0x9e, 0x8c, 0x19, 0x19, 0xfb, 0xab,
+ 0x36, 0x67, 0x7f, 0xf7, 0x37, 0x97, 0x3c, 0xd2, 0xdd, 0xd6, 0x68, 0x94,
+ 0x95, 0x3a, 0xfe, 0xcc, 0xca, 0x8c, 0x5a, 0x74, 0x1f, 0xe5, 0x9b, 0x8c,
+ 0x2c, 0x7d, 0x29, 0x53, 0x81, 0x6a, 0xfe, 0x41, 0xf6, 0x20, 0x4e, 0x5d,
+ 0x2f, 0x1c, 0xbc, 0x30, 0xd9, 0xcb, 0xa3, 0x9e, 0x8d, 0x98, 0x8b, 0xd4,
+ 0x91, 0x17, 0xe5, 0xeb, 0xdb, 0x03, 0x0e, 0x5b, 0x9f, 0xc7, 0x80, 0x84,
+ 0x77, 0x85, 0xe4, 0x72, 0xfd, 0xa5, 0xbb, 0xac, 0xd1, 0x3b, 0x2f, 0xfe,
+ 0xce, 0x8b, 0xc8, 0x1f, 0xb1, 0xe4, 0x72, 0xf3, 0xcb, 0x9e, 0x1f, 0xc0,
+ 0x9a, 0x5d, 0x3b, 0x59, 0xcb, 0xff, 0xf2, 0x04, 0x0c, 0x8e, 0x07, 0x08,
+ 0xc0, 0xe2, 0xce, 0x5f, 0xe9, 0x46, 0xa7, 0x8d, 0x4e, 0x72, 0xff, 0xdd,
+ 0x17, 0x90, 0x3f, 0x63, 0xc8, 0xe5, 0x41, 0xfa, 0x61, 0xad, 0xb9, 0xe2,
+ 0x79, 0x4c, 0x84, 0x9f, 0x4c, 0xdc, 0x6c, 0x61, 0x93, 0x7c, 0x9a, 0x8e,
+ 0x27, 0x2f, 0xfe, 0x68, 0xe3, 0xfe, 0x7a, 0x05, 0x3f, 0x39, 0x6e, 0x7b,
+ 0x3e, 0x85, 0x08, 0xef, 0xfe, 0x76, 0x77, 0x16, 0xfd, 0x85, 0x24, 0x72,
+ 0xf2, 0x05, 0xce, 0x5f, 0xfc, 0x39, 0xd7, 0x9f, 0x36, 0x2f, 0xf1, 0xcb,
+ 0x9a, 0x73, 0x0a, 0x28, 0xba, 0x89, 0xb1, 0xba, 0x92, 0xbc, 0x36, 0x47,
+ 0xe9, 0xb8, 0x61, 0x34, 0x86, 0x6d, 0xff, 0xfc, 0x17, 0xf7, 0x3c, 0xdc,
+ 0x0f, 0xdf, 0xef, 0x71, 0xf9, 0xcb, 0xf6, 0x96, 0xee, 0xb3, 0x44, 0x58,
+ 0xbf, 0xf3, 0xcb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x4b, 0xab, 0xff, 0xfb,
+ 0x03, 0xd8, 0x53, 0x9f, 0x85, 0xff, 0xde, 0xe3, 0xf2, 0x96, 0xe7, 0x88,
+ 0xdf, 0x61, 0xa3, 0x44, 0xcb, 0xff, 0x98, 0xf2, 0xe7, 0x9a, 0x5b, 0xba,
+ 0xcd, 0x13, 0x12, 0xff, 0xfb, 0x17, 0x1c, 0xfa, 0xe8, 0xd1, 0x3f, 0xc0,
+ 0x9c, 0xae, 0x68, 0xa4, 0xea, 0x95, 0xfb, 0x4b, 0x77, 0x59, 0xa2, 0xa9,
+ 0x5b, 0x0e, 0x56, 0x1e, 0x22, 0xa6, 0x97, 0xfe, 0x03, 0xea, 0x43, 0x8d,
+ 0xbf, 0xe7, 0x2f, 0xfe, 0x7d, 0xe9, 0x1b, 0xf7, 0x53, 0x52, 0x39, 0x7f,
+ 0xda, 0x7e, 0xfd, 0x2c, 0xf7, 0x30, 0xa2, 0x13, 0xa7, 0xf5, 0xcd, 0x1f,
+ 0x4f, 0x0a, 0x6b, 0xff, 0xdc, 0xd8, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd,
+ 0x13, 0xa2, 0xff, 0x23, 0xea, 0x24, 0xfc, 0x4e, 0x5f, 0xa6, 0x89, 0xa3,
+ 0x67, 0x2f, 0xe6, 0xf1, 0x38, 0xe0, 0x9c, 0xa4, 0x3d, 0x7d, 0x94, 0xde,
+ 0x4e, 0xc1, 0xce, 0x66, 0x86, 0xff, 0xe0, 0x6f, 0xd1, 0xf7, 0x30, 0x4c,
+ 0x8c, 0x39, 0x4c, 0x3f, 0x6e, 0x96, 0xdf, 0xf9, 0xe5, 0xcf, 0x34, 0xb7,
+ 0x75, 0x9a, 0x27, 0x75, 0xfb, 0xc0, 0x76, 0x21, 0x4b, 0xff, 0x0c, 0x7b,
+ 0x37, 0x99, 0xf4, 0x8e, 0x50, 0x53, 0xf3, 0xc8, 0xc8, 0x58, 0x44, 0xe9,
+ 0x9e, 0x27, 0xbf, 0xe0, 0xc4, 0xa3, 0x9b, 0x7b, 0xfc, 0xe5, 0xfd, 0x1c,
+ 0xff, 0x1c, 0x09, 0xca, 0xe6, 0x8b, 0xbc, 0x4f, 0x13, 0xdb, 0xff, 0xdc,
+ 0xd8, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x14, 0x2a, 0xff, 0xf9, 0xfd,
+ 0x2c, 0x14, 0x0f, 0x3d, 0xcf, 0x1a, 0x39, 0x7f, 0xff, 0xfb, 0xa0, 0x63,
+ 0x1e, 0x5c, 0xd7, 0xd0, 0x7a, 0x07, 0x27, 0x54, 0x11, 0x31, 0xcb, 0xf0,
+ 0x3e, 0xf2, 0x2c, 0xe5, 0xfb, 0x3f, 0xc7, 0x13, 0x97, 0xdb, 0x46, 0xfc,
+ 0x72, 0xf4, 0x7f, 0xce, 0x73, 0xf2, 0x12, 0x9f, 0x13, 0x52, 0x26, 0x64,
+ 0x30, 0xef, 0xbf, 0xfd, 0xcd, 0x8f, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1,
+ 0x49, 0x2f, 0xff, 0xf6, 0x6f, 0x9a, 0x99, 0x37, 0x5d, 0x9e, 0xec, 0x78,
+ 0x0c, 0x39, 0x50, 0xc9, 0xa2, 0x9e, 0x33, 0xe9, 0x43, 0x75, 0x71, 0xb1,
+ 0xe8, 0xa5, 0x92, 0xc2, 0x3f, 0x30, 0x15, 0xaf, 0x47, 0x06, 0x02, 0x76,
+ 0x8b, 0x57, 0xfb, 0x9e, 0x69, 0x6e, 0xeb, 0x34, 0x44, 0x8b, 0xff, 0xdc,
+ 0xd8, 0xf2, 0xe7, 0x9a, 0x5b, 0xba, 0xcd, 0x12, 0xf2, 0xff, 0xe8, 0xe2,
+ 0xf3, 0x26, 0xbe, 0x94, 0x4c, 0x72, 0xf3, 0x52, 0xcf, 0xce, 0x5f, 0x68,
+ 0x1e, 0xd9, 0xcb, 0xf6, 0xbf, 0x62, 0x6c, 0xe5, 0xe8, 0x1f, 0x8e, 0x5f,
+ 0xbc, 0xa3, 0x06, 0x0e, 0x59, 0x3a, 0x78, 0x82, 0x39, 0x7f, 0xfb, 0xbc,
+ 0x60, 0x7f, 0x6b, 0xc0, 0xe6, 0xbe, 0x39, 0x74, 0x78, 0xe5, 0xff, 0x3c,
+ 0xfa, 0x8f, 0xa4, 0x8c, 0x39, 0x7f, 0xf8, 0x01, 0x4d, 0x29, 0x37, 0x00,
+ 0x1c, 0x66, 0x39, 0x52, 0x4c, 0x59, 0x09, 0xbf, 0x50, 0x11, 0x6d, 0x9d,
+ 0x5f, 0xdf, 0xf6, 0x34, 0x8c, 0x39, 0x7f, 0xe9, 0xb7, 0x1c, 0x5f, 0xb1,
+ 0xf4, 0xc7, 0x2a, 0x0f, 0xc5, 0xcb, 0xaf, 0x93, 0x81, 0x46, 0x1c, 0xbf,
+ 0x64, 0xf9, 0xb6, 0x1c, 0xbf, 0x9e, 0x77, 0xdb, 0xfe, 0x72, 0xff, 0xe9,
+ 0xb9, 0x28, 0x31, 0xc5, 0xf8, 0xc4, 0xc7, 0x28, 0xe5, 0xfa, 0x4f, 0xe7,
+ 0xe2, 0x72, 0xfc, 0xfb, 0x8e, 0x38, 0x72, 0xa6, 0x3d, 0x1e, 0x25, 0x35,
+ 0x08, 0xcd, 0xc4, 0xc7, 0x5c, 0xbb, 0x50, 0x72, 0x82, 0xb8, 0x1a, 0x84,
+ 0x73, 0x47, 0x07, 0xa8, 0x5d, 0xf4, 0x80, 0x49, 0xbc, 0x51, 0xc6, 0x1f,
+ 0x7c, 0x05, 0xb7, 0x60, 0x9c, 0xbf, 0xb9, 0x6f, 0xb8, 0x9e, 0x39, 0x41,
+ 0x3c, 0x44, 0x15, 0xb8, 0x3f, 0x1c, 0xbf, 0x84, 0x1e, 0x9a, 0x15, 0x39,
+ 0x7b, 0x87, 0x4d, 0x1c, 0xb2, 0x39, 0xe8, 0x00, 0xbe, 0xfc, 0x39, 0x3a,
+ 0x9c, 0x4e, 0x5f, 0x64, 0xea, 0x71, 0x39, 0x7e, 0x0c, 0x7c, 0x17, 0xe4,
+ 0x7a, 0x22, 0x57, 0x7f, 0xfc, 0x9a, 0xe5, 0xd8, 0x4f, 0x6c, 0x0b, 0x04,
+ 0x1c, 0xbe, 0x49, 0xff, 0x6b, 0x39, 0x7c, 0xb7, 0x75, 0x9a, 0x29, 0x75,
+ 0xf0, 0xfa, 0x34, 0x72, 0xff, 0xb3, 0x4d, 0x78, 0x1c, 0xd7, 0xc7, 0x29,
+ 0x0f, 0x77, 0x89, 0x0d, 0x49, 0x36, 0x65, 0x50, 0x26, 0x51, 0xd1, 0x3f,
+ 0x61, 0x17, 0x7f, 0x07, 0xe8, 0xd2, 0x7c, 0x72, 0xfb, 0xd3, 0xe3, 0x67,
+ 0x29, 0x0f, 0x4c, 0x4b, 0xef, 0xc8, 0xae, 0xb3, 0x67, 0x2f, 0xfd, 0x03,
+ 0x1d, 0xe4, 0x01, 0x02, 0xce, 0x5e, 0x03, 0xec, 0xe5, 0xf4, 0xc0, 0x79,
+ 0x8e, 0x5f, 0xa3, 0xf7, 0xfb, 0x67, 0x2f, 0x0a, 0x7e, 0x72, 0xf6, 0x7b,
+ 0x67, 0x2a, 0x0d, 0xc6, 0xc7, 0x2a, 0x49, 0x94, 0x04, 0xa2, 0x63, 0xfe,
+ 0x8e, 0x7e, 0x49, 0xe6, 0x1b, 0xf3, 0x5b, 0x88, 0x78, 0x0e, 0x5d, 0x1f,
+ 0x1c, 0xbf, 0xef, 0xf7, 0xa8, 0xfa, 0x48, 0xc3, 0x97, 0xbc, 0xfc, 0x4e,
+ 0x5f, 0xa7, 0x04, 0xd0, 0xd6, 0x72, 0xf8, 0x13, 0x43, 0x59, 0xcb, 0x9e,
+ 0x7e, 0x47, 0xa7, 0x39, 0x6d, 0x42, 0x37, 0x5c, 0xec, 0x0e, 0x37, 0xfc,
+ 0x9b, 0x99, 0x07, 0xd1, 0xf9, 0xcb, 0xff, 0x87, 0xdc, 0x63, 0x5b, 0x71,
+ 0x86, 0xb3, 0x95, 0x24, 0x57, 0x30, 0xbb, 0x67, 0x37, 0xfa, 0x1a, 0xf7,
+ 0x0c, 0x7f, 0x1c, 0xb9, 0xc4, 0xe5, 0xff, 0x47, 0xfc, 0xbb, 0x0c, 0x71,
+ 0x39, 0x5f, 0x1e, 0x7f, 0x11, 0x5a, 0x92, 0x2a, 0x75, 0x08, 0x4b, 0xfa,
+ 0x1b, 0x4e, 0x81, 0xac, 0xe5, 0xfd, 0xf4, 0xb6, 0xe3, 0xf1, 0xca, 0x85,
+ 0x66, 0x12, 0x2d, 0xc8, 0xe8, 0x92, 0x1b, 0x3a, 0x28, 0x50, 0xc6, 0xff,
+ 0xc3, 0x37, 0x2d, 0x47, 0xd2, 0x46, 0x1c, 0xba, 0x18, 0x72, 0xa0, 0xf6,
+ 0x34, 0x85, 0x7f, 0x40, 0xcd, 0xe4, 0x54, 0xe5, 0xff, 0x4b, 0x35, 0x36,
+ 0x0c, 0x30, 0xe5, 0xfb, 0xf8, 0x5e, 0x30, 0xe5, 0xfe, 0xc9, 0xf7, 0x13,
+ 0x03, 0x47, 0x29, 0x11, 0x2b, 0xa3, 0x81, 0x28, 0xba, 0x58, 0x72, 0xfd,
+ 0xb5, 0x74, 0xed, 0x9c, 0xbc, 0x30, 0xc3, 0x94, 0x13, 0xc5, 0xd1, 0x55,
+ 0xe8, 0xff, 0x67, 0x2a, 0x11, 0x90, 0x12, 0xec, 0x5b, 0x6c, 0x8a, 0xf9,
+ 0xfa, 0xf3, 0x9c, 0xbf, 0x74, 0x0a, 0xe0, 0x9c, 0xbf, 0xcd, 0x8b, 0xfa,
+ 0x4e, 0x13, 0x97, 0xef, 0x29, 0x3c, 0x74, 0xe5, 0xff, 0x47, 0x76, 0xfe,
+ 0x8d, 0x70, 0x1c, 0xbf, 0xf3, 0x1c, 0x2a, 0x4d, 0x28, 0x1f, 0x8e, 0x50,
+ 0x4f, 0xf1, 0x0e, 0xef, 0xb5, 0xfa, 0x9c, 0x4e, 0x5e, 0x46, 0xfc, 0x72,
+ 0xba, 0x78, 0x9b, 0x27, 0xa9, 0xd3, 0xaa, 0x09, 0x17, 0xc5, 0x13, 0x19,
+ 0xf6, 0x14, 0xde, 0x65, 0xbf, 0xc3, 0xec, 0xda, 0x3f, 0x4e, 0x5f, 0xf7,
+ 0xe9, 0xdc, 0xd3, 0xcd, 0xb3, 0x97, 0xff, 0xe8, 0x90, 0xc4, 0xea, 0x4d,
+ 0xbe, 0xe7, 0x06, 0xbf, 0x39, 0x7f, 0x72, 0x66, 0x79, 0xfc, 0x72, 0xfe,
+ 0xea, 0x05, 0x34, 0xb3, 0x96, 0x59, 0xcb, 0xbe, 0xde, 0x1f, 0x6a, 0xcb,
+ 0xdc, 0xb6, 0xf4, 0x20, 0x4e, 0x54, 0x27, 0x13, 0xf1, 0x8b, 0x0e, 0x9e,
+ 0x19, 0x3b, 0x3a, 0xbf, 0xd8, 0xdc, 0x93, 0x60, 0x61, 0xcb, 0xb8, 0xec,
+ 0xe5, 0xfc, 0x0d, 0xc4, 0xc0, 0xd1, 0xcb, 0xf6, 0x4f, 0x9d, 0xd9, 0xca,
+ 0x83, 0xf0, 0xe8, 0xc8, 0x97, 0xde, 0xcd, 0x6c, 0xe5, 0x2c, 0xf2, 0x78,
+ 0x96, 0xdf, 0xf7, 0xf1, 0xfa, 0x9c, 0x60, 0x78, 0x0e, 0x54, 0x26, 0xa3,
+ 0x90, 0xed, 0x42, 0x4b, 0xff, 0xff, 0xbb, 0x1a, 0xf9, 0x69, 0xf7, 0x25,
+ 0x5f, 0x96, 0xfa, 0xeb, 0x81, 0x09, 0xcb, 0xe4, 0x55, 0xa6, 0x1c, 0xbf,
+ 0x94, 0xf4, 0x4e, 0x3f, 0x1c, 0xbc, 0x28, 0xc3, 0x95, 0xa3, 0xef, 0xfc,
+ 0x93, 0xc6, 0x17, 0xf8, 0x61, 0xc7, 0xd8, 0x27, 0x2f, 0xf4, 0x7d, 0xb6,
+ 0xb8, 0xd2, 0xa7, 0x2f, 0xf7, 0x5e, 0x64, 0xd4, 0x4e, 0x72, 0xfe, 0xce,
+ 0x06, 0x46, 0x78, 0xe5, 0xd8, 0xc3, 0x94, 0x14, 0xfd, 0xf2, 0x1c, 0xec,
+ 0x30, 0xe9, 0x7b, 0x9c, 0x00, 0xd3, 0x89, 0x7d, 0xfb, 0x81, 0x19, 0x1b,
+ 0x39, 0x7e, 0x7e, 0x39, 0xad, 0x9c, 0xa0, 0x9e, 0x9b, 0x0a, 0xaf, 0xdd,
+ 0x71, 0x46, 0x1c, 0xbe, 0x56, 0x6d, 0xc1, 0xcb, 0xfb, 0xff, 0xbf, 0xcd,
+ 0x61, 0xcb, 0xf9, 0x70, 0x9e, 0x49, 0x1c, 0xbf, 0x9f, 0xf6, 0x46, 0x78,
+ 0xe5, 0x42, 0x22, 0x70, 0xc1, 0x0b, 0x2f, 0xf3, 0xff, 0xb8, 0xec, 0x6c,
+ 0xe5, 0xfb, 0xef, 0x6f, 0x27, 0x39, 0x76, 0x4e, 0x72, 0x9c, 0xf0, 0x44,
+ 0xaa, 0xa1, 0x3b, 0x6c, 0x22, 0x42, 0x6e, 0xc2, 0xb4, 0x4b, 0x76, 0xe9,
+ 0x77, 0xeb, 0x39, 0x6d, 0x9c, 0xb9, 0x15, 0xd9, 0xa9, 0x00, 0xc5, 0xef,
+ 0xdd, 0x67, 0x2f, 0x9b, 0x9b, 0x70, 0x72, 0xfe, 0xd8, 0xbc, 0xf1, 0xe3,
+ 0x97, 0xe9, 0xdf, 0x79, 0x23, 0x97, 0xff, 0xc1, 0xce, 0x2f, 0xa9, 0x94,
+ 0x93, 0xf9, 0xd8, 0x72, 0xa0, 0xfe, 0xd0, 0xa2, 0xfe, 0x7f, 0xbf, 0x62,
+ 0x6c, 0xe5, 0x42, 0x67, 0x1f, 0x0e, 0xcc, 0x49, 0xa8, 0x54, 0x74, 0x82,
+ 0xff, 0x79, 0x1b, 0x79, 0xa1, 0x87, 0x2d, 0xcf, 0x84, 0x6f, 0x03, 0x1a,
+ 0xb4, 0x88, 0x9c, 0x30, 0x9e, 0x1b, 0x32, 0x21, 0x0b, 0x46, 0x47, 0xbb,
+ 0xf4, 0x29, 0x52, 0x34, 0x89, 0xa5, 0xc5, 0x6a, 0x17, 0x4c, 0x21, 0xec,
+ 0x71, 0x6f, 0x1f, 0x37, 0xf1, 0xf4, 0x8c, 0x74, 0x1b, 0x94, 0x55, 0xe9,
+ 0x4e, 0x6d, 0x21, 0x04, 0xa4, 0x6c, 0xbc, 0x0a, 0x37, 0xfb, 0x9e, 0x69,
+ 0x6e, 0xeb, 0x34, 0x53, 0x8b, 0xfc, 0xc8, 0x66, 0x70, 0x47, 0x8e, 0x5f,
+ 0x66, 0xd4, 0x91, 0xcb, 0xff, 0x26, 0x9f, 0x7d, 0xcc, 0x15, 0x9c, 0xbf,
+ 0x33, 0x5a, 0xcd, 0x9c, 0xbf, 0xff, 0x74, 0x1e, 0xd4, 0x7b, 0x78, 0xbd,
+ 0xc6, 0x96, 0x72, 0xff, 0xb6, 0x8a, 0xe4, 0xa3, 0xfd, 0x9c, 0xbf, 0xff,
+ 0xbd, 0x93, 0x0a, 0x6f, 0xd0, 0xa2, 0x6a, 0x68, 0xe9, 0xcb, 0xfc, 0x8c,
+ 0x0c, 0x6c, 0x02, 0x72, 0xfe, 0x7f, 0xb7, 0xcb, 0x6a, 0x1c, 0xbf, 0x7b,
+ 0xe9, 0x43, 0x67, 0x2f, 0xe7, 0x53, 0x38, 0xc6, 0xce, 0x56, 0x1e, 0xc8,
+ 0x0a, 0xaf, 0xfc, 0x9f, 0x6c, 0x70, 0x3d, 0x76, 0xce, 0x5f, 0xff, 0x64,
+ 0xf9, 0xf7, 0xb6, 0x83, 0x1f, 0xbb, 0x0e, 0x52, 0xa8, 0x8f, 0xd9, 0xfd,
+ 0xff, 0xb3, 0xb1, 0xac, 0xe6, 0xdb, 0x6d, 0x94, 0xb9, 0x1b, 0x39, 0x74,
+ 0xfc, 0xe1, 0x5c, 0x9c, 0x8d, 0x42, 0x47, 0x87, 0x8b, 0x28, 0xf9, 0x59,
+ 0x0e, 0xba, 0xb9, 0xf9, 0x90, 0xc2, 0x2f, 0xd0, 0xb0, 0x68, 0x49, 0xc0,
+ 0x87, 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0xaf, 0x17, 0xff, 0xf6, 0x07, 0xb0,
+ 0xa7, 0x3f, 0x0b, 0xff, 0xbd, 0xc7, 0xe5, 0x2d, 0xcf, 0x11, 0x26, 0xd0,
+ 0xd2, 0xff, 0xee, 0x6f, 0x2e, 0x79, 0xa5, 0xbb, 0xac, 0xd1, 0x23, 0xaf,
+ 0x2f, 0x18, 0x72, 0xf2, 0x7f, 0x07, 0x2f, 0x2f, 0x18, 0x53, 0x99, 0x79,
+ 0x7e, 0xd2, 0xdd, 0xd6, 0x68, 0x92, 0x17, 0xff, 0xf4, 0x26, 0x93, 0x82,
+ 0x06, 0x78, 0xf2, 0x75, 0xe7, 0x39, 0x7f, 0xf9, 0xfd, 0x36, 0xf0, 0x21,
+ 0x03, 0xea, 0x47, 0x2f, 0xff, 0x0e, 0x7e, 0xd3, 0x35, 0x13, 0xbe, 0x96,
+ 0x72, 0xe9, 0x73, 0x84, 0xd5, 0x30, 0xb7, 0xa6, 0x9f, 0xae, 0x79, 0x2e,
+ 0xfd, 0x9d, 0xe7, 0x8c, 0x39, 0x6e, 0x70, 0xa8, 0x35, 0xe3, 0x8c, 0xf2,
+ 0xc5, 0xff, 0xdc, 0xde, 0x5c, 0xf3, 0x4b, 0x77, 0x59, 0xa2, 0x4a, 0x5f,
+ 0xb4, 0xb7, 0x75, 0x9a, 0x2f, 0x15, 0xff, 0x4b, 0x9e, 0x69, 0x6e, 0xeb,
+ 0x34, 0x49, 0xab, 0x73, 0xc3, 0xfb, 0x73, 0x4b, 0xfe, 0xd2, 0xe2, 0x7c,
+ 0xc1, 0xf1, 0xcb, 0xfa, 0x36, 0x8c, 0x89, 0x8e, 0x5b, 0xa7, 0x29, 0x0f,
+ 0xd9, 0x87, 0x0d, 0x96, 0xdf, 0xf6, 0x7e, 0x1e, 0xc0, 0xc3, 0x67, 0x2f,
+ 0xbf, 0xde, 0x09, 0xca, 0x83, 0xdb, 0x43, 0x9b, 0xff, 0x90, 0x0b, 0xde,
+ 0xdf, 0x5e, 0x85, 0x4e, 0x5f, 0x48, 0x11, 0xf1, 0xcb, 0xff, 0xe0, 0x3f,
+ 0xd9, 0x8a, 0xaa, 0xf2, 0xcf, 0xbc, 0x72, 0xa4, 0x8d, 0xa0, 0x90, 0x4c,
+ 0x8b, 0xb2, 0x3b, 0xff, 0x24, 0x33, 0xb8, 0x10, 0xa7, 0xc7, 0x2f, 0xb8,
+ 0x12, 0x15, 0x39, 0x7a, 0x5f, 0x2a, 0x72, 0xf0, 0x03, 0xf1, 0xcb, 0xff,
+ 0x9f, 0xf5, 0xf5, 0x34, 0x29, 0xed, 0x9c, 0xb8, 0x67, 0x39, 0x50, 0x8b,
+ 0xd0, 0x92, 0xa0, 0xfb, 0x8f, 0x28, 0x89, 0x6f, 0x1c, 0xbb, 0x58, 0x72,
+ 0xb4, 0x69, 0xff, 0x11, 0xbf, 0xf6, 0x80, 0xce, 0xa4, 0x31, 0xc4, 0xe5,
+ 0xff, 0x6e, 0x18, 0x39, 0x28, 0x13, 0x95, 0xa3, 0xf3, 0xf1, 0xed, 0xe6,
+ 0x9c, 0x33, 0x67, 0x2b, 0x0f, 0x1f, 0x80, 0x8a, 0xfd, 0xe4, 0xec, 0x71,
+ 0x39, 0x70, 0xce, 0x72, 0xf7, 0xa3, 0x47, 0x2a, 0x0f, 0x72, 0x62, 0x90,
+ 0x0b, 0xdc, 0xeb, 0x39, 0x7f, 0x2c, 0x20, 0x9d, 0x46, 0x1c, 0xbe, 0x0e,
+ 0x76, 0x0e, 0x54, 0x1f, 0x46, 0x0b, 0x39, 0x8d, 0xfa, 0x6d, 0xed, 0x18,
+ 0x72, 0xff, 0xfa, 0x76, 0xde, 0x5b, 0xde, 0x69, 0xb8, 0xd2, 0xa7, 0x2c,
+ 0x27, 0x2e, 0x51, 0x43, 0x95, 0x88, 0xa6, 0x72, 0x9f, 0xd5, 0x14, 0x10,
+ 0xb9, 0xa7, 0x38, 0x5e, 0x0e, 0xc8, 0xd9, 0x34, 0x7d, 0xd8, 0x7d, 0xbb,
+ 0x78, 0xc3, 0x73, 0x70, 0x80, 0xf4, 0x25, 0xd4, 0x86, 0x95, 0x43, 0xae,
+ 0x62, 0x9d, 0x06, 0x55, 0xe3, 0x30, 0x63, 0x91, 0x49, 0x7a, 0x93, 0x46,
+ 0xc6, 0xc2, 0xce, 0xca, 0x61, 0xf1, 0xf0, 0x21, 0x9e, 0xa4, 0xf5, 0x65,
+ 0x44, 0xef, 0x31, 0x24, 0xf2, 0xd0, 0xe5, 0x3d, 0xde, 0x19, 0xf0, 0x6c,
+ 0xc6, 0x91, 0x7a, 0xb4, 0x81, 0x95, 0xdf, 0xb6, 0x87, 0xd5, 0xed, 0xea,
+ 0x53, 0x4c, 0x5a, 0xe5, 0x1f, 0x4d, 0x78, 0xf7, 0x9a, 0xb6, 0x57, 0x6c,
+ 0xd4, 0x32, 0x55, 0xda, 0x7d, 0x7b, 0xde, 0x52, 0xff, 0xf4, 0xc2, 0x7e,
+ 0x1e, 0x5e, 0xe0, 0xd7, 0xd6, 0xbb, 0xb4, 0x48, 0xde, 0xbf, 0x8e, 0x10,
+ 0x5e, 0x46, 0xe7, 0x1a, 0x77, 0xb3, 0x74, 0x84, 0xe6, 0x93, 0xa3, 0x2a,
+ 0x52, 0x7c, 0xf8, 0x2d, 0x78, 0xf5, 0x00,
};
-static const unsigned kPreloadedHSTSBits = 265770;
+static const unsigned kPreloadedHSTSBits = 394224;
-static const unsigned kHSTSRootPosition = 265157;
+static const unsigned kHSTSRootPosition = 393600;
#endif // NET_HTTP_TRANSPORT_SECURITY_STATE_STATIC_H_
diff --git a/chromium/net/http/transport_security_state_static.json b/chromium/net/http/transport_security_state_static.json
index 4bff1eab791..cd69dd6451a 100644
--- a/chromium/net/http/transport_security_state_static.json
+++ b/chromium/net/http/transport_security_state_static.json
@@ -31,6 +31,11 @@
// mode: (optional string) "force-https" iff covered names should require
// HTTPS
// pins: (optional string) the |name| member of an object in |pinsets|
+// expect_ct: (optional boolean) true if the site expects Certificate
+// Transparency information to be present on requests to |name|
+// expect_ct_report_uri: (optional string) if expect_ct is true, the
+// URI to which reports should be sent when valid Certificate
+// Transparency information is not present
{
"pinsets": [
@@ -56,14 +61,15 @@
"DigiCertEVRoot",
"Tor1",
"Tor2",
- "Tor3"
+ "Tor3",
+ "LetsEncryptAuthorityX1",
+ "LetsEncryptAuthorityX2"
]
},
{
"name": "twitterCom",
"static_spki_hashes": [
"VeriSignClass1",
- "VeriSignClass3",
"VeriSignClass3_G4",
"VeriSignClass4_G3",
"VeriSignClass3_G3",
@@ -90,7 +96,6 @@
"name": "twitterCDN",
"static_spki_hashes": [
"VeriSignClass1",
- "VeriSignClass3",
"VeriSignClass3_G4",
"VeriSignClass4_G3",
"VeriSignClass3_G3",
@@ -176,94 +181,115 @@
"SpiderOak2",
"SpiderOak3"
]
+ },
+ {
+ "name": "yahoo",
+ "static_spki_hashes": [
+ "VeriSignClass2_G2",
+ "VeriSignClass2_G3",
+ "VeriSignClass3_G3",
+ "VeriSignClass3_G4",
+ "VeriSignClass3_G5",
+ "VeriSignUniversal",
+ "GeoTrustGlobal",
+ "GeoTrustPrimary",
+ "GeoTrustPrimary_G2",
+ "GeoTrustPrimary_G3",
+ "GeoTrustUniversal",
+ "DigiCertGlobalRoot",
+ "DigiCertEVRoot",
+ "YahooBackup1",
+ "YahooBackup2"
+ ]
}
],
"entries": [
- // Dummy entry to test certificate pinning.
+ // Dummy entries to test certificate pinning and expect-CT.
{ "name": "pinningtest.appspot.com", "include_subdomains": true, "pins": "test" },
-
- // (*.)google.com, iff using SSL, must use an acceptable certificate.
- { "name": "google.com", "include_subdomains": true, "pins": "google" },
+ { "name": "pinning-test.badssl.com", "include_subdomains": true, "pins": "test" },
+ { "name": "preloaded-expect-ct.badssl.com", "expect_ct": true, "expect_ct_report_uri": "https://report.badssl.com/expect-ct" },
// Now we force HTTPS for subtrees of google.com.
- { "name": "wallet.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "accounts.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "admin.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "appengine.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "checkout.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "chrome.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "cloud.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "contributor.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "docs.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "domains.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "sites.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "spreadsheets.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "appengine.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "encrypted.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "accounts.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "profiles.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "fi.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "glass.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "goto.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "hangouts.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "history.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "hostedtalkgadget.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "inbox.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "login.corp.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "mail.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "mail-settings.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "inbox.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "talkgadget.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "talk.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "hostedtalkgadget.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "myaccount.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "passwords.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "pixel.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "play.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "plus.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "plus.sandbox.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "profiles.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "script.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "hangouts.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "history.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "security.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "goto.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "cloud.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "glass.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "admin.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "login.corp.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "play.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "passwords.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "myaccount.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "contributor.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "fi.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "sites.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "spreadsheets.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "talkgadget.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "talk.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "wallet.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "xn--7xa.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "pixel.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
// Other Google-related domains that must use HTTPS.
- { "name": "google", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "gmail.com", "mode": "force-https", "pins": "google" },
- { "name": "googlemail.com", "mode": "force-https", "pins": "google" },
- { "name": "www.gmail.com", "mode": "force-https", "pins": "google" },
- { "name": "www.googlemail.com", "mode": "force-https", "pins": "google" },
- { "name": "chrome.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "market.android.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "ssl.google-analytics.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "drive.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "googleplex.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "groups.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "apis.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "chromiumcodereview.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "build.chromium.org", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "chrome.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "chrome-devtools-frontend.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "chromiumcodereview.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "code.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "codereview.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "codereview.chromium.org", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "code.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "googlecode.com", "include_subdomains": true, "pins": "google" },
{ "name": "dl.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "translate.googleapis.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "drive.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "g4w.co", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "gmail.com", "mode": "force-https", "pins": "google" },
+ { "name": "googlecode.com", "include_subdomains": true, "pins": "google" },
+ { "name": "google", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "googlemail.com", "mode": "force-https", "pins": "google" },
+ { "name": "googleplex.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "groups.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "gvt2.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "gvt3.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "withyoutube.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "market.android.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "ssl.google-analytics.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "translate.googleapis.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "withgoogle.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "withyoutube.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "www.gmail.com", "mode": "force-https", "pins": "google" },
+ { "name": "www.googlemail.com", "mode": "force-https", "pins": "google" },
{ "name": "webfilings.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "webfilings-mirror-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "webfilings-eu.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "webfilings-eu-mirror.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "webfilings-mirror-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "wf-bigsky-master.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "wf-demo-eu.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "wf-demo-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "wf-dogfood-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "wf-pentest.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "wf-trial-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "xbrlsuccess.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "w-spotlight.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "wf-training-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "wf-bigsky-master.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "wf-staging-hr.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "wf-training-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "wf-training-master.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
- { "name": "wf-dogfood-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "wf-trial-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "w-spotlight.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "xbrlsuccess.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
// chart.apis.google.com is *not* HSTS because the certificate doesn't match
// and there are lots of links out there that still use the name. The correct
@@ -272,36 +298,23 @@
// Other Google-related domains that must use an acceptable certificate
// iff using SSL.
- { "name": "blogger.com", "include_subdomains": true, "pins": "google" },
- { "name": "google-analytics.com", "include_subdomains": true, "pins": "google" },
- { "name": "googlegroups.com", "include_subdomains": true, "pins": "google" },
- { "name": "ytimg.com", "include_subdomains": true, "pins": "google" },
- { "name": "googleusercontent.com", "include_subdomains": true, "pins": "google" },
- { "name": "youtube.com", "include_subdomains": true, "pins": "google" },
- { "name": "youtube-nocookie.com", "include_subdomains": true, "pins": "google" },
- { "name": "googleapis.com", "include_subdomains": true, "pins": "google" },
- { "name": "googleadservices.com", "include_subdomains": true, "pins": "google" },
- { "name": "appspot.com", "include_subdomains": true, "pins": "google" },
- { "name": "googlesyndication.com", "include_subdomains": true, "pins": "google" },
- { "name": "doubleclick.net", "include_subdomains": true, "pins": "google" },
{ "name": "2mdn.net", "include_subdomains": true, "pins": "google" },
- { "name": "gstatic.com", "include_subdomains": true, "pins": "google" },
- { "name": "youtu.be", "include_subdomains": true, "pins": "google" },
{ "name": "android.com", "include_subdomains": true, "pins": "google" },
- { "name": "googlecommerce.com", "include_subdomains": true, "pins": "google" },
- { "name": "urchin.com", "include_subdomains": true, "pins": "google" },
- { "name": "goo.gl", "include_subdomains": true, "pins": "google" },
+ { "name": "appspot.com", "include_subdomains": true, "pins": "google" },
+ { "name": "blogger.com", "include_subdomains": true, "pins": "google" },
+ { "name": "blogspot.com", "include_subdomains": true, "pins": "google" },
+ { "name": "doubleclick.net", "include_subdomains": true, "pins": "google" },
{ "name": "g.co", "include_subdomains": true, "pins": "google" },
- { "name": "googletagmanager.com", "include_subdomains": true, "pins": "google" },
- { "name": "googletagservices.com", "include_subdomains": true, "pins": "google" },
{ "name": "ggpht.com", "include_subdomains": true, "pins": "google" },
- { "name": "blogspot.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.ac", "include_subdomains": true, "pins": "google" },
{ "name": "google.ad", "include_subdomains": true, "pins": "google" },
+ { "name": "googleadservices.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.ae", "include_subdomains": true, "pins": "google" },
{ "name": "google.af", "include_subdomains": true, "pins": "google" },
{ "name": "google.ag", "include_subdomains": true, "pins": "google" },
{ "name": "google.am", "include_subdomains": true, "pins": "google" },
+ { "name": "google-analytics.com", "include_subdomains": true, "pins": "google" },
+ { "name": "googleapis.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.as", "include_subdomains": true, "pins": "google" },
{ "name": "google.at", "include_subdomains": true, "pins": "google" },
{ "name": "google.az", "include_subdomains": true, "pins": "google" },
@@ -338,22 +351,10 @@
{ "name": "google.co.ke", "include_subdomains": true, "pins": "google" },
{ "name": "google.co.kr", "include_subdomains": true, "pins": "google" },
{ "name": "google.co.ls", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.ma", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.mz", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.nz", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.th", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.tz", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.ug", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.uk", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.uz", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.ve", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.vi", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.za", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.zm", "include_subdomains": true, "pins": "google" },
- { "name": "google.co.zw", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.af", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.ag", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.ai", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.ma", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.ar", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.au", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.bd", "include_subdomains": true, "pins": "google" },
@@ -378,6 +379,7 @@
{ "name": "google.com.gr", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.gt", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.hk", "include_subdomains": true, "pins": "google" },
+ { "name": "google.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.iq", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.jm", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.jo", "include_subdomains": true, "pins": "google" },
@@ -385,6 +387,7 @@
{ "name": "google.com.kw", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.lb", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.ly", "include_subdomains": true, "pins": "google" },
+ { "name": "googlecommerce.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.mt", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.mx", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.my", "include_subdomains": true, "pins": "google" },
@@ -418,6 +421,18 @@
{ "name": "google.com.vc", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.ve", "include_subdomains": true, "pins": "google" },
{ "name": "google.com.vn", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.mz", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.nz", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.th", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.tz", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.ug", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.uk", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.uz", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.ve", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.vi", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.za", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.zm", "include_subdomains": true, "pins": "google" },
+ { "name": "google.co.zw", "include_subdomains": true, "pins": "google" },
{ "name": "google.cv", "include_subdomains": true, "pins": "google" },
{ "name": "google.cz", "include_subdomains": true, "pins": "google" },
{ "name": "google.de", "include_subdomains": true, "pins": "google" },
@@ -437,6 +452,7 @@
{ "name": "google.gm", "include_subdomains": true, "pins": "google" },
{ "name": "google.gp", "include_subdomains": true, "pins": "google" },
{ "name": "google.gr", "include_subdomains": true, "pins": "google" },
+ { "name": "googlegroups.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.gy", "include_subdomains": true, "pins": "google" },
{ "name": "google.hk", "include_subdomains": true, "pins": "google" },
{ "name": "google.hn", "include_subdomains": true, "pins": "google" },
@@ -448,11 +464,11 @@
{ "name": "google.info", "include_subdomains": true, "pins": "google" },
{ "name": "google.iq", "include_subdomains": true, "pins": "google" },
{ "name": "google.is", "include_subdomains": true, "pins": "google" },
- { "name": "google.it", "include_subdomains": true, "pins": "google" },
{ "name": "google.it.ao", "include_subdomains": true, "pins": "google" },
+ { "name": "google.it", "include_subdomains": true, "pins": "google" },
{ "name": "google.je", "include_subdomains": true, "pins": "google" },
- { "name": "google.jo", "include_subdomains": true, "pins": "google" },
{ "name": "google.jobs", "include_subdomains": true, "pins": "google" },
+ { "name": "google.jo", "include_subdomains": true, "pins": "google" },
{ "name": "google.jp", "include_subdomains": true, "pins": "google" },
{ "name": "google.kg", "include_subdomains": true, "pins": "google" },
{ "name": "google.ki", "include_subdomains": true, "pins": "google" },
@@ -499,6 +515,9 @@
{ "name": "google.sn", "include_subdomains": true, "pins": "google" },
{ "name": "google.so", "include_subdomains": true, "pins": "google" },
{ "name": "google.st", "include_subdomains": true, "pins": "google" },
+ { "name": "googlesyndication.com", "include_subdomains": true, "pins": "google" },
+ { "name": "googletagmanager.com", "include_subdomains": true, "pins": "google" },
+ { "name": "googletagservices.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.td", "include_subdomains": true, "pins": "google" },
{ "name": "google.tg", "include_subdomains": true, "pins": "google" },
{ "name": "google.tk", "include_subdomains": true, "pins": "google" },
@@ -507,11 +526,22 @@
{ "name": "google.tn", "include_subdomains": true, "pins": "google" },
{ "name": "google.to", "include_subdomains": true, "pins": "google" },
{ "name": "google.tt", "include_subdomains": true, "pins": "google" },
+ { "name": "googleusercontent.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.us", "include_subdomains": true, "pins": "google" },
{ "name": "google.uz", "include_subdomains": true, "pins": "google" },
{ "name": "google.vg", "include_subdomains": true, "pins": "google" },
+ { "name": "googlevideo.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.vu", "include_subdomains": true, "pins": "google" },
+ { "name": "googleweblight.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.ws", "include_subdomains": true, "pins": "google" },
+ { "name": "goo.gl", "include_subdomains": true, "pins": "google" },
+ { "name": "gstatic.com", "include_subdomains": true, "pins": "google" },
+ { "name": "static.googleadsserving.cn", "include_subdomains": true, "pins": "google" },
+ { "name": "urchin.com", "include_subdomains": true, "pins": "google" },
+ { "name": "youtube.com", "include_subdomains": true, "pins": "google" },
+ { "name": "youtu.be", "include_subdomains": true, "pins": "google" },
+ { "name": "youtube-nocookie.com", "include_subdomains": true, "pins": "google" },
+ { "name": "ytimg.com", "include_subdomains": true, "pins": "google" },
// Exclude the learn.doubleclick.net subdomain because it uses a different
// CA.
{ "name": "learn.doubleclick.net", "include_subdomains": true },
@@ -1273,90 +1303,90 @@
{ "name": "zixiao.wang", "include_subdomains": true, "mode": "force-https" },
- { "name": "at.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "au.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "az.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "be.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "bi.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "br.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ca.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "cd.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "cg.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "chfr.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "chit.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ch.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "cl.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "cn.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "co.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "cr.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ct.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "de.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "dk.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "do.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "en-maktoob.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "espanol.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "es.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "fi.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "fj.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "fr.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "gl.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "gm.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "gr.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "hk.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "hn.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "hu.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "id.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ie.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "in.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "it.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "kr.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "kz.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "li.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "lt.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "lu.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "lv.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "maktoob.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "malaysia.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "mt.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "mu.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "mw.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "mx.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ni.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "nl.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "no.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "np.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "nz.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "pa.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "pe.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ph.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "pk.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "pl.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "pr.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "py.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "qc.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ro.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ru.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "rw.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "se.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "sg.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "sv.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "th.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "tr.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "tv.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "tw.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ua.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "uk.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "uy.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "uz.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "ve.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "vn.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "xa.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "za.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "zh.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "login.yahoo.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "mail.yahoo.com", "include_subdomains": false, "mode": "force-https" },
- { "name": "edit.yahoo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "at.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "au.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "az.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "be.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "bi.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "br.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ca.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "cd.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "cg.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "chfr.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "chit.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ch.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "cl.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "cn.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "co.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "cr.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ct.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "de.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "dk.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "do.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "en-maktoob.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "espanol.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "es.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "fi.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "fj.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "fr.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "gl.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "gm.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "gr.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "hk.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "hn.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "hu.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "id.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ie.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "in.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "it.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "kr.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "kz.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "li.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "lt.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "lu.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "lv.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "maktoob.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "malaysia.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "mt.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "mu.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "mw.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "mx.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ni.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "nl.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "no.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "np.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "nz.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "pa.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "pe.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ph.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "pk.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "pl.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "pr.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "py.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "qc.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ro.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ru.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "rw.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "se.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "sg.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "sv.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "th.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "tr.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "tv.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "tw.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ua.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "uk.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "uy.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "uz.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "ve.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "vn.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "xa.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "za.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "zh.search.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "login.yahoo.com", "include_subdomains": true, "mode": "force-https", "pins": "yahoo" },
+ { "name": "mail.yahoo.com", "include_subdomains": false, "mode": "force-https", "pins": "yahoo" },
+ { "name": "edit.yahoo.com", "include_subdomains": true, "mode": "force-https", "pins": "yahoo" },
{ "name": "ahoyconference.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "balcan-underground.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "baldwinkoo.com", "include_subdomains": true, "mode": "force-https" },
@@ -2217,8 +2247,6 @@
{ "name": "domainkauf.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "emptypath.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "eromixx.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "ezequiel-garzon.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "ezequiel-garzon.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "fa-works.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "flagspot.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "getmango.com", "include_subdomains": true, "mode": "force-https" },
@@ -2353,7 +2381,6 @@
{ "name": "ecake.in", "include_subdomains": true, "mode": "force-https" },
{ "name": "ego4u.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "ego4u.de", "include_subdomains": true, "mode": "force-https" },
- { "name": "etoprekrasno.ru", "include_subdomains": true, "mode": "force-https" },
{ "name": "fish-hook.ru", "include_subdomains": true, "mode": "force-https" },
{ "name": "fniephaus.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "forgix.com", "include_subdomains": true, "mode": "force-https" },
@@ -2460,7 +2487,6 @@
{ "name": "ethercalc.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "ethercalc.org", "include_subdomains": true, "mode": "force-https" },
{ "name": "fluxfingers.net", "include_subdomains": true, "mode": "force-https" },
- { "name": "haber1903.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "initrd.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "integromat.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "lookyman.net", "include_subdomains": true, "mode": "force-https" },
@@ -2656,7 +2682,7 @@
{ "name": "bigdinosaur.org", "include_subdomains": true, "mode": "force-https" },
{ "name": "bownty.dk", "include_subdomains": true, "mode": "force-https" },
{ "name": "braineet.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "branchtrack.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "branchtrack.com", "mode": "force-https" },
{ "name": "brks.xyz", "include_subdomains": true, "mode": "force-https" },
{ "name": "businesshosting.nl", "include_subdomains": true, "mode": "force-https" },
{ "name": "bygningsregistrering.dk", "include_subdomains": true, "mode": "force-https" },
@@ -3177,7 +3203,6 @@
{ "name": "eroticen.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "eucl3d.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "firmapi.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "formationsfactory.co.uk", "include_subdomains": true, "mode": "force-https" },
{ "name": "freeweibo.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "funchestra.at", "include_subdomains": true, "mode": "force-https" },
{ "name": "gamenected.com", "include_subdomains": true, "mode": "force-https" },
@@ -3481,7 +3506,6 @@
{ "name": "sobabox.ru", "include_subdomains": true, "mode": "force-https" },
{ "name": "soply.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "sweetll.me", "include_subdomains": true, "mode": "force-https" },
- { "name": "taskstream.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "thedreamtravelgroup.co.uk", "include_subdomains": true, "mode": "force-https" },
{ "name": "thehotfix.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "tiffnix.com", "include_subdomains": true, "mode": "force-https" },
@@ -3512,7 +3536,7 @@
{ "name": "dolphin-hosting.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "dolphin-it.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "enquos.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "flipagram.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flipagram.com", "include_subdomains": false, "mode": "force-https" },
{ "name": "gravity-net.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "gtanda.tk", "include_subdomains": true, "mode": "force-https" },
{ "name": "hannover-banditen.de", "include_subdomains": true, "mode": "force-https" },
@@ -3642,7 +3666,6 @@
{ "name": "americanbio.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "amoory.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "appmobile.io", "include_subdomains": true, "mode": "force-https" },
- { "name": "attotech.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "aussiecable.org", "include_subdomains": true, "mode": "force-https" },
{ "name": "avarty.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "aylak.com", "include_subdomains": true, "mode": "force-https" },
@@ -3756,7 +3779,7 @@
{ "name": "wait.jp", "include_subdomains": true, "mode": "force-https" },
{ "name": "wdesk.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "wohnsitz-ausland.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "woima.fi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "woima.fi", "include_subdomains": false, "mode": "force-https" },
{ "name": "wolfemg.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "wrldevelopment.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "xiaody.me", "include_subdomains": true, "mode": "force-https" },
@@ -3819,7 +3842,6 @@
{ "name": "nettopower.dk", "include_subdomains": true, "mode": "force-https" },
{ "name": "nicestresser.fr", "include_subdomains": true, "mode": "force-https" },
{ "name": "nsboston.org", "include_subdomains": true, "mode": "force-https" },
- { "name": "o7.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "onet.space", "include_subdomains": true, "mode": "force-https" },
{ "name": "oopsmycase.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "opennippon.com", "include_subdomains": true, "mode": "force-https" },
@@ -3852,7 +3874,1753 @@
{ "name": "wjglerum.nl", "include_subdomains": true, "mode": "force-https" },
{ "name": "wp-tao.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "yoloprod.fr", "include_subdomains": true, "mode": "force-https" },
- { "name": "zzsec.org", "include_subdomains": true, "mode": "force-https" }
+ { "name": "zzsec.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "my.swedbank.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "internetbank.swedbank.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "demo.swedbank.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lana.swedbank.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "online.swedbank.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "33-km.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "42ms.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "abeestrada.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "accountradar.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adamradocz.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aladdin.ie", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alarmsystemreviews.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "allthingswild.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "amerimarkdirect.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "andreypopp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ankaraprofesyonelnakliyat.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aojf.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "apachelounge.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "apstudynotes.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "areatrend.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "atgseed.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "atgseed.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "authint.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "basnoslovno.com.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "basnoslovno.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beans-one.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bettrlifeapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "billninja.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bionicspirit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bitlish.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blackburn.link", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blazor.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blechschmidt.saarland", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bugginslab.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bwcscorecard.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "certcenter.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cesobaly.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "checktype.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chloe.re", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chrst.ph", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coldhak.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "comarkinstruments.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "consciousandglamorous.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crestoncottage.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crl-autos.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crossfitblackwater.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "csgodicegame.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cvmu.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "de-medici.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "decoder.link", "include_subdomains": true, "mode": "force-https" },
+ { "name": "depixion.agency", "include_subdomains": true, "mode": "force-https" },
+ { "name": "devopps.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dhautefeuille.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "droidwiki.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dubrovskiy.pro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "edakoe.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "edgereinvent.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elsitar.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "espgg.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "etherpad.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "evomon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "expresshosting.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fig.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "finkelstein.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flow.su", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fr33d0m.link", "include_subdomains": true, "mode": "force-https" },
+ { "name": "getbox.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ggp2.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gigacloud.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "globalexpert.co.nz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grh.am", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hawkeyeinsight.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hencagon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hetmer.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hilahdih.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hrbatypes.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hroschyk.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ichronos.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "idaspis.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ifleurs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iggprivate.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iggsoft.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iggsoftware.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ihsbsd.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "illjinx.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "incparadise.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "institutolancaster.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "integrationinc.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ipv6cloud.club", "include_subdomains": true, "mode": "force-https" },
+ { "name": "joelj.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kba-online.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "knygos.lt", "include_subdomains": true, "mode": "force-https" },
+ { "name": "koukni.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kpinvest.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kristofferkoch.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kweddingplanning.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kylinj.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lagoza.name", "include_subdomains": true, "mode": "force-https" },
+ { "name": "latenitefilms.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "laylo.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lentri.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "litespeed.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "loancompare.co.za", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lsky.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "makerstuff.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "malinator.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marie-curie.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "markusehrlicher.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marumagic.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mcrn.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "meetscompany.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "meta.sc", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mnium.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparcraft.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparcraft.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparcraft.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparisthebest.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparisthebest.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparisthebest.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparisthebest.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparisthebest.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moparscape.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "my-pawnshop.com.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myfrm.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mygov.scot", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nagb.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nagb.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "najedlo.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "newmediaone.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nodetemple.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "noworrywp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "o6asan.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "panthur.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "perfektesgewicht.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "perfektesgewicht.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "perplex.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pettsy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "please-deny.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pm13.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "postbox.life", "include_subdomains": true, "mode": "force-https" },
+ { "name": "postscheduler.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "potbar.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "potbox.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "privacy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "privacyinternational.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "publicsuffix.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "punchr-kamikazee.rhcloud.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "recyclingpromotions.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "reddiseals.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "regenerescence.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "repaxan.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "robtex.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "roomhub.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rsajeey.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rubi-ka.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ryanhowell.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ryansmithphotography.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "schnell-gold.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "segurosocial.gov", "include_subdomains": false, "mode": "force-https" },
+ { "name": "selectel.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sevsopr.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "silver-heart.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "slamix.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smartpolicingplatform.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "socialsecurity.gov", "include_subdomains": false, "mode": "force-https" },
+ { "name": "splikity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "square.gs", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ssa.gov", "include_subdomains": false, "mode": "force-https" },
+ { "name": "ssl.rip", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stellenticket.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "subdimension.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "syezd.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tafoma.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "takkaaaaa.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "techcentric.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thebreakroom.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thecloudmigrator.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thego2swatking.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thehackerblog.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "theitsage.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "theyosh.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tobiassachs.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "topnovini.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trendberry.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trybind.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "uberfunction.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ulrik.moe", "include_subdomains": true, "mode": "force-https" },
+ { "name": "utopians.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vanetv.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "varunagw.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vistb.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vyber-odhadce.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "webyazilimankara.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whyworldhot.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "witae.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "withinsecurity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "woodlandschurch.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "woodlandsmetro.church", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wordsmart.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "workwithgo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yoloboatrentals.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yoloseo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zen-trader.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "andreas-kluge.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "andreaskluge.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fastaim.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "matrip.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "reporturi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "reporturi.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "report-uri.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "18f.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "1co-jp.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "1password.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ad-notam.pt", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adblock.ovh", "include_subdomains": true, "mode": "force-https" },
+ { "name": "admsel.ec", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alltheducks.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alphassl.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "altedirect.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "altestore.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ankaraprofesyonelnakliyat.com.tr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ankaraprofesyonelwebtasarim.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ankarauzmanlarnakliyat.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "anzeiger.ag", "include_subdomains": true, "mode": "force-https" },
+ { "name": "apnakliyat.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aryasenna.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "askwhy.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "askwhy.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "atisoft.com.tr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "atisoft.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "atisoft.net.tr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "atisoft.web.tr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "balboa.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bcsytv.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beholdthehurricane.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beranovi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "betterhelp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "borysek.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "broadsheet.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "broersma.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brownfieldstsc.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bulmafox.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "byrtz.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "callsigns.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chimeratool.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "classicspublishing.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clickandgo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "colognegaming.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "compucorner.mx", "include_subdomains": true, "mode": "force-https" },
+ { "name": "concentrade.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crepererum.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cryptoparty.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dannyrohde.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "devdoodle.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "diasp.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dime-staging.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "docket.news", "include_subdomains": true, "mode": "force-https" },
+ { "name": "econsumer.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elephpant.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elimdengelen.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elisa.ee", "include_subdomains": true, "mode": "force-https" },
+ { "name": "entersynapse.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "epay.bg", "include_subdomains": true, "mode": "force-https" },
+ { "name": "escalate.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "espci.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ev-zertifikate.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "evdenevenakliyatankara.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "exfiles.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "expxkcd.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eyyit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fandomservices.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fasdoutreach.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fca-tools.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fetch.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "findmybottleshop.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flamewall.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "freelance.boutique", "include_subdomains": true, "mode": "force-https" },
+ { "name": "freifunk-luenen.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "frtr.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "g-m-w.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gamingzoneservers.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "garbage-juice.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "getbutterfly.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "glws.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gmw-ingenieurbuero.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "granular.ag", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gsm-map.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gyboche.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "harristony.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "harvester.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "haselsteiner.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "helgakristoffer.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "helgakristoffer.wedding", "include_subdomains": true, "mode": "force-https" },
+ { "name": "heutger.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hpkp-faq.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "imoni-blog.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "insideaudit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "instela.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "interisaudit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "intxt.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "itsg-faq.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "j3e.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jakubboucek.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jennedebleser.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jhalderm.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jirav.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "josefjanosec.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "klasfauseweh.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lashstuff.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "linux.fi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "linuxgeek.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "liquid.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lukasunger.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mac-torrents.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marlen.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maveris.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "melted.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mexicansbook.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "milanpala.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "missdream.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moreapp.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "murraycoin.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nakliyatsirketi.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nbb.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nder.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "netwarc.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nikao-tech.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nikobradshaw.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nikolasbradshaw.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nomial.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "npmcdn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nutritionculture.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oasis.mobi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "offshoot.rentals", "include_subdomains": true, "mode": "force-https" },
+ { "name": "opsbears.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "otchecker.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "penfold.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pgmann.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pier28.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "piligrimname.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "poleartschool.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "posterspy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "postn.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "powercloud.technology", "include_subdomains": true, "mode": "force-https" },
+ { "name": "proos.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "psw-group.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "psw.academy", "include_subdomains": true, "mode": "force-https" },
+ { "name": "psw.consulting", "include_subdomains": true, "mode": "force-https" },
+ { "name": "psw.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "realcapoeira.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ricki-z.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "right-to-love.name", "include_subdomains": true, "mode": "force-https" },
+ { "name": "robandjanine.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "robspc.repair", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rodolfo.gs", "include_subdomains": true, "mode": "force-https" },
+ { "name": "safematix.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sanderdorigo.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sandervankasteel.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sdrobs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "securedevelop.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shopbakersnook.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "signing-milter.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simonkjellberg.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simphony.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "snapappts.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "socialhead.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sogutma.com.tr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "soporte.cc", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ssl-zertifikate.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sslzilla.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "steamdb.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stupus.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "taborsky.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "teampaddymurphy.ie", "include_subdomains": true, "mode": "force-https" },
+ { "name": "teampoint.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "therewill.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thomspooren.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "threelions.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tm-solutions.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tomasjacik.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trainex.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trinitycore.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "twaka.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "twist.party", "include_subdomains": true, "mode": "force-https" },
+ { "name": "urandom.eu.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vallis.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "viscopic.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "viva-french.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vyberodhadce.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "webtasarim.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "welldrake.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "werdeeintimo.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wo2forum.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wrara.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wyeworks.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xetown.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xss.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yingyj.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zgrep.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zortium.report", "include_subdomains": true, "mode": "force-https" },
+ { "name": "0x90.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alexwardweb.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "another.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "atolm.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "avastantivirus.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beeksnetwork.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bergstoneware.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "berst.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bigbluedoor.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "binaryevolved.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bitcoinhk.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blackdragoninc.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bockenauer.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brainster.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "c16t.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cabarave.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cannyfoxx.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cattivo.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clmde.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "codeux.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "constructionjobs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "conversiones.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "converter.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "couragewhispers.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dale-electric.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "danpiel.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "darioturchetti.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "datasharesystem.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "david.kitchen", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dden.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "deviltraxxx.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "diversityflags.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dnscrypt.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "docloh.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dolphincorp.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "domodedovo.travel", "include_subdomains": true, "mode": "force-https" },
+ { "name": "doyoucheck.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dziekonski.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "easyhaul.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "easykonto.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "edpubs.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eeqj.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elitefishtank.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "endofnet.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "englerts.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eugenekay.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "evasovova.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eyasc.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eydesignguidelines.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fedrtc.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fiilr.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "frillip.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fsapubs.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gfwsb.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "giftservices.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "goabonga.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grace-wan.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "greenteamtwente.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gregmilton.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hackcraft.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "helix.am", "include_subdomains": true, "mode": "force-https" },
+ { "name": "herpaderp.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hlavacek.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hobby-gamerz-community.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hochhaus.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "holisticon.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hopewellproperties.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hostinghelp.guru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ikk.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "indybay.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "itinsight.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jacobhaug.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jaroslavtrsek.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jav-collective.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jlkhosting.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "juniwalk.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kiebel.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kimmel.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kynaston.org.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "larrysalibra.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lateralsecurity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lemp.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "letras.mus.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "librelamp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "libsodium.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "linux.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "livedemo.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lukasberan.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lukasunger.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "macker.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maco.org.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "makowitz.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "melcher.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mercamaris.es", "include_subdomains": true, "mode": "force-https" },
+ { "name": "micro-rain-systems.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mlpepilepsy.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mnetworkingsolutions.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mortgagecentersmo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mrs-shop.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "muguayuan.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "musthavesforreal.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mybudget.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myg21.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nagoya-kyuyo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nametiles.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "neosolution.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "netbrief.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nevadafiber.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "noima.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "noisetrap.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onespiritinc.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "orderswift.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "otoy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "override.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pacoda.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "paratlan.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pcloud.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "peytonfarrar.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "phpdorset.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pimpmymac.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pirateproxy.la", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pirateproxy.pl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "piwko.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pjuu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "polis.to", "include_subdomains": true, "mode": "force-https" },
+ { "name": "poon.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "poon.tech", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pr1sm.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "premierheart.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pressrush.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "proxybay.la", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ptm.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "qlrace.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "qualityedgarsolutions.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ramon-c.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "realmofespionage.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ringh.am", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rmb.li", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rngmeme.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "roeckx.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "roeitijd.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "roombase.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ruxit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ryanteck.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "safar.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "samegoal.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "samegoal.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "schwinabart.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "selfici.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shiroki-k.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skipfault.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "spdf.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ss.lv", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stirlingpoon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stirlingpoon.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stomt.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "talado.gr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "taskulu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tazemama.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "the-paddies.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thepartywarehouse.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thorbis.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tidycustoms.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tiens-ib.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tucny.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ukas.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ultros.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unpr.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "utdsgda.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "valordolarblue.com.ar", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vanlaanen.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "verizonguidelines.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vieclam24h.vn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vm0.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vnvisa.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "watersb.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "watertrails.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "westerhoud.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whatsapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whey-protein.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wiire.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "williamfeely.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "workray.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yobst.tk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yombo.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zking.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "secure.advancepayroll.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "www.captaintrain.com", "mode": "force-https" },
+ { "name": "0x1337.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "206rc.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "360gradus.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adimaja.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "akhilindurti.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alcazaar.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alfredxing.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "allcarepharmacy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "amdouglas.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aniplus.gq", "include_subdomains": true, "mode": "force-https" },
+ { "name": "apiomat.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "arnor.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "arrakis.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "artofwhere.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "asset-alive.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "asset-alive.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "avacariu.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "badkamergigant.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "badlink.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bajic.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bendechrai.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "besthost.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bets.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bigclassaction.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blackpayment.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blaise.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bonobo.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "borrelioz.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brandon.so", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brightstarkids.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bsidessf.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bunbun.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "burtrum.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "buzzconf.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "byronwade.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bytejail.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "caesreon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "calaborlawnews.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "carboneselectricosnettosl.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "carsforbackpackers.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cecipu.gob.cl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "centricweb.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chcemvediet.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "christiaanconover.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "christianbro.gq", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cidbot.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cidr.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cig-dem.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cirope.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clearviewwealthprojector.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clickclickphish.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clintonbloodworth.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloud.wtf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudily.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "comparejewelleryprices.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "compucorner.com.mx", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cormilu.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cortexitrecruitment.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "countermail.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cqchome.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crazydomains.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crow.tw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cryptopartyutah.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cryptoseb.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ctoforhire.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "daemon.xin", "include_subdomains": true, "mode": "force-https" },
+ { "name": "daniel-steuer.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dario.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dark-x.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dataretention.solutions", "include_subdomains": true, "mode": "force-https" },
+ { "name": "datatekniikka.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "datatekniikka.fi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dbmteam.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "delfic.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "detector.exposed", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dgeex.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dhauwer.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "die-partei-reutlingen.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dime.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dinkum.online", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dise-online.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dmxledlights.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "docemeldoces.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "doctorwho.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "domainstaff.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dopost.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dot.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dyrenesverden.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eagleyecs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "easy-rpg.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eduvance.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elementalrobotics.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "enteente.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "esg-abi2001.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "essoduke.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "expressfinance.co.za", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fahrenwal.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fahrenwalde.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fatlossguide.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fbox.li", "include_subdomains": true, "mode": "force-https" },
+ { "name": "firefall.rocks", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flamingcow.tv", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fliexer.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "floort.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "foray-jero.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fordbydesign.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fotofaerie.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "foxdev.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "free.com.tw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fsfi.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gehaowu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "genshiken.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "genyaa.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "geschwinder.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gha.st", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gilly.berlin", "include_subdomains": true, "mode": "force-https" },
+ { "name": "globalcomix.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "globalperspectivescanada.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "goat.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gotocloud.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gpfclan.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grandmasfridge.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "graymalk.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gregmilton.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gs-net.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hack.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hardfalcon.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "healtheffectsofasbestos.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hejsupport.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "helpconnect.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "henrock.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hompus.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hoodoo.tech", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hoton.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hymerscollege.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ideation-inc.co.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "idvl.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iec.pe", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ifcfg.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ifoss.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "imagescostumes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "imrejonk.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "inboxen.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "infinitusgaming.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "infocommsociety.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "instant.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "involved-it.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ipcfg.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ipswitch.com.tw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iready.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "istorrent.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "itfh.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "itpol.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "j-navi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jaba.hosting", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jackfahnestock.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jamonsilva.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jonathandowning.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "joshi.su", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jrvar.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kamisama.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kaplatz.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kbjorklu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kindof.ninja", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kinnon.enterprises", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kleppe.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "konijntjes.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kraft.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kredietpaspoort.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kurtmclester.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "labs.directory", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lambda-complex.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "leppis-it.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "liceserv.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "limpido.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "linuxbierwanderung.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lmintlcx.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "locomore.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "logfile.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lusis.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lusis.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "macgeneral.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "machbach.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mailgarant.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "management-companie.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "masa.li", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mathiasgarbe.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "matspar.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mavensecurity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maximeferon.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mchristopher.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "media-courses.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "megasslstore.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "melitopol.co.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "meozcraft.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mfcatalin.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "michalborka.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mijailovic.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mijnkredietpaspoort.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "monitman.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "monitman.solutions", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mpintaamalabanna.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "muabannhanh.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mycieokien.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myhostname.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myiocc.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "n2x.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nanogeneinc.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "naval.tf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "neel.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "netlocal.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nicoborghuis.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nidux.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "niho.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nodebrewery.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nope.website", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nystart.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "olliespage.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "online-casino.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onlinecensorship.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onlinelegalmarketing.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onlinelegalmedia.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onlinewetten.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onlyshopstation.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "open-mesh.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "openstreetmap.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "osm.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ossbinaries.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ourcloud.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "owncloud.help", "include_subdomains": true, "mode": "force-https" },
+ { "name": "paku.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "palationtrade.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "papayapythons.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "paragonie.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "parkingplus.co.il", "include_subdomains": true, "mode": "force-https" },
+ { "name": "partirkyoto.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "partyvan.moe", "include_subdomains": true, "mode": "force-https" },
+ { "name": "peissen.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "peterdavehello.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "phunehehe.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pic.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pileofgarbage.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pm13.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pointiswunderland.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pokemori.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "post4me.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "practicallabs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "prayerrequest.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "preisser-it.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "priva.si", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pro-bike.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "profundr.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "proxybay.al", "include_subdomains": true, "mode": "force-https" },
+ { "name": "purplemoon.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "qiliang.wang", "include_subdomains": true, "mode": "force-https" },
+ { "name": "quotehex.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "redshield.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "responsibledisclosure.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rewrite3.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rinobroer.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rootrelativity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rsi.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "safemovescheme.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "saharalondon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sandor.wtf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sb-group.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "scanpay.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "scooshonline.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sebastianboegl.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "seo-nerd.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "seo.consulting", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sequencing.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "serized.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "seyr.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shaitan.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shan.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sheilasdrivingschool.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "silkebaekken.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skoda-service-team-cup.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sobie.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "square-gaming.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "squawk.cc", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sqzryang.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "srrr.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sslpoint.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stalkerhispano.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "star-citizen.wiki", "include_subdomains": true, "mode": "force-https" },
+ { "name": "staticisnoise.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "statuscode.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "storycollective.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stricted.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "strugee.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sumoscout.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sweetstreats.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sykepleien.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "synchtu.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tacticalsquare.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tazj.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tdelmas.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "technosavvyport.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "telekollektiv.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "teleogistic.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "telescam.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "textualapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "theater.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thebigwave.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thegraciousgourmet.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thehistory.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thestagchorleywood.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thorbiswebsitedesign.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tlo.network", "include_subdomains": true, "mode": "force-https" },
+ { "name": "torprojects.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "torrent.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "totalchecklist.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tpe-edu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trollme.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trufflemonkey.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ttz.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tvtubeflix.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "twopif.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tyche.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "uasmi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unblocked-networks.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "uni-games.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unila.edu.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unitel2000.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unixadm.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unoccupyabq.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unterschicht.tv", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unwiredbrain.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "uvarov.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "valentin-sundermann.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "veriny.tf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vincentcox.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vissanum.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vsund.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "walkeryoung.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wallpapers.pub", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wangqiliang.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wangqiliang.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wartorngalaxy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wealthprojector.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wealthprojector.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "weathermyway.rocks", "include_subdomains": true, "mode": "force-https" },
+ { "name": "web4all.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "webscale.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "webtorrent.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "weeblr.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wettbuero.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wetten.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wetttipps.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wetttipps.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whatsupgold.com.tw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whocalled.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "willosagiede.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wodka-division.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wohlgemuth.rocks", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wrwg.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xatr0z.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xng.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yawnbox.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yetzt.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yplanapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zacarias.com.ar", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ze3kr.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zett4.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zirtue.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zoneminder.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thundr.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudflare.com", "include_subdomains": false, "mode": "force-https" },
+ { "name": "www.cloudflare.com", "include_subdomains": false, "mode": "force-https" },
+ { "name": "api.cloudflare.com", "include_subdomains": false, "mode": "force-https" },
+ { "name": "6969.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aaeblog.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "advancis.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ahxxm.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "anitube-nocookie.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "anitube.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "appartementhaus-badria.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "appson.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "arjandejong.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aunali1.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "avantmfg.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "b3orion.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bandrcrafts.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beaglewatch.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bermeitinger.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bettween.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bike-shack.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bildermachr.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bitok.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bizcms.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blmiller.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "boxintense.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brightstarkids.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brightstarkids.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brightstarkids.sg", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bsklabels.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "btsoft.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "budgetalk.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "burningflipside.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "casperpanel.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cfa.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chic-leather.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chijiokeindustries.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chun.pro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cip.md", "include_subdomains": true, "mode": "force-https" },
+ { "name": "citiagent.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cmdline.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cojo.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "concord-group.co.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "count.sh", "include_subdomains": true, "mode": "force-https" },
+ { "name": "culinae.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cvjm-memmingen.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "david-schiffmann.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "decafu.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dergeilstestammderwelt.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "detteflies.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dibiphp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "disruptivelabs.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "disruptivelabs.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "divingwithnic.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "doktorsitesi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dovetailnow.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dukun.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elpo.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "englishbulgaria.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ethicalexploiting.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eurostrategy.vn.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eveseat.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "exekutori.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "familieholme.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fastcomcorp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "felisslovakia.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ff-bad-hoehenstadt.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fhcdn.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "filoo.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flajshans.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flat.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "florian-schlachter.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fortress.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "freeutopia.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gosuland.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "guguke.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hacker.one", "include_subdomains": true, "mode": "force-https" },
+ { "name": "haucke.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hdm.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hds-lan.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "henriksen.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hiddenmail.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hohm.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "holifestival-freyung.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "huaxueba.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ideadozz.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "idealsvdr.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ikvts.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "interaffairs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "isitamor.pm", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jamesconroyfinn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jameshost.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "johngallias.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kanna.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kcolford.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kilobyte22.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "komoju.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kotonehoko.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kreen.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kropkait.pl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kryx.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "laserfuchs.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lawformt.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "levinus.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lightme.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "limeyeti.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "logopaediereinhard.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lottosonline.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "macleod.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "masa-yoga.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mathhire.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mattwb65.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mavenclinic.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "meditek-dv.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "micro-dv.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mind-moves.es", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraft-forum.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraft-forum.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraft-forum.gq", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraft-forum.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraft-forums.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraft-forums.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraft-forums.gq", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraftforum.ovh", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraftforums.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraftforums.gq", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraftforums.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "misterl.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mittelunsachlich.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "multigeist.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "narfation.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ne-on.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nettefoundation.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "network-notes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "neveta.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "niftiestsoftware.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nullpoint.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "open-bs.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oxygaming.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oxymc.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "paulproell.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "peerherrmann.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pixelcode.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "planet-work.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "posobota.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ppmoon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pretix.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "privacyrup.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pt-server.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "purplemoon.mobi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "purplestar.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "purplestar.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "purplestar.mobi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pushapp.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pyplo.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rentcarassist.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rmstudio.tw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "roave.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rotzonline.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "samaritansnet.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sandbagexpress.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "schelberts.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "selfici.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simply-premium.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "slovakiana.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sniep.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "solsystems.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "soondy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "spacefish.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stjohnmiami.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "streampanel.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stuartbell.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "suche.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sveneckelmann.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "texy.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "the-construct.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thebrotherswarde.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thelocals.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thomas-grobelny.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tifan.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tobiassattler.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tomcort.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tonburi.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "totch.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "untoldstory.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unun.fi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "valmagus.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vanitas.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vansieleghem.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vfdworld.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "viperdns.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vitalorange.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "w.wiki", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wevolver.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wf-hosting.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wfh.ovh", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wfh.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wiseloan.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wje-online.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wxcafe.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xellos.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xett.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yecl.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yolobert.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ys-shop.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zooparadies.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "0paste.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "1km.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "2nerds1bit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "403.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "acr.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adevel.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adrl.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aishnair.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alair.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alexbaker.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "altesses.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "altonblom.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "amishsecurity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "andreasfeusi.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "anedot.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aniplus.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "anshuman-chatterjee.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "asandu.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aspires.co.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "augustiner-kantorei-erfurt.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "augustiner-kantorei.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "avalon-island.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "avec-ou-sans-ordonnance.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aviacao.pt", "include_subdomains": true, "mode": "force-https" },
+ { "name": "babarkata.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "babyfotograf-schweiz.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bacchanallia.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "balkonien.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bananabandy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "baofengtech.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "baud.ninja", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beachi.es", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bentley.link", "include_subdomains": true, "mode": "force-https" },
+ { "name": "berra.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bfw-online.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bgmn.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "biasmath.es", "include_subdomains": true, "mode": "force-https" },
+ { "name": "biou.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bitcoinworld.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blauwwit.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blendle.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bluemosh.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bonapp.restaurant", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bonifacius.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "boringsecurity.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bougeret.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bowling.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brasalcosmetics.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bratteng.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bugcrowd.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cadoth.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "caffeinatedcode.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cais.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "caja-pdf.es", "include_subdomains": true, "mode": "force-https" },
+ { "name": "calvinallen.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "camperverzekerd.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "canadasmotorcycle.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "car-navi.ph", "include_subdomains": true, "mode": "force-https" },
+ { "name": "carck.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cardrecovery.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cativa.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ccayearbook.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cctech.ph", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cementscience.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "centralync.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cevrimici.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chaoschemnitz.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chch.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chocolah.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "choosemypc.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chriswells.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ciat.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clintonbloodworth.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudcy.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clouddesktop.co.nz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cmci.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "co50.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coiffeurschnittstelle.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "comitesaustria.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "consonare.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coopens.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "custodyxchange.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cvursache.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cyph.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cyph.video", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cysec.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "d3xt3r01.tk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "daimadi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "datorb.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "decomplify.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "deepserve.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dentaldomain.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dentaldomain.ph", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dereferenced.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "devh.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "devolution.ws", "include_subdomains": true, "mode": "force-https" },
+ { "name": "die-blahuts.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "diegelernten.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dmlogic.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dmwall.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dogan.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dutchrank.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dynamize.solutions", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dzimejl.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eagletechz.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "echomanchester.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ecnetworker.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "efficienthealth.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "electronicfasteners.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elemental.software", "include_subdomains": true, "mode": "force-https" },
+ { "name": "endlesstone.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eriix.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "expo-designers.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ezmod.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "f-thie.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "faesser.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "faizan.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "faizan.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "federicomigliavacca.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "file-pdf.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "findtutorsnearme.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flawlesscowboy.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "floorball-haunwoehr.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flowersandclouds.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fmarchal.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "focusmark.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "frankierprofi.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "franzt.ovh", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fredvoyage.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fukushima-web.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fzn.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "geek-hub.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "geeky.software", "include_subdomains": true, "mode": "force-https" },
+ { "name": "genshiken-itb.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "genslerwisp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "genxnotes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "getvdownloader.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "glidingshop.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gowe.wang", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gracesofgrief.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grantedby.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grazetech.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grcnode.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gtmasterclub.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "habarisoft.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hackthissite.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hakase.kr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "handmadetutorials.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "harbor-light.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "harringtonca.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hduin.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hexo.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "homads.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hoodoo.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hoshisato.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "huffduffer.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hund.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iainsimms.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ilhadocaranguejo.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "imlonghao.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "imququ.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "imreh.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "indust.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "inksay.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "institutoflordelavida.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "interfug.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "inwesttitle.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iocheck.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "isaacman.tech", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iskaz.rs", "include_subdomains": true, "mode": "force-https" },
+ { "name": "isondo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "istanbul.systems", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jacobphono.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jamesrains.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jayharris.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jcraft.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jennythebaker.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jetmirshatri.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jimmycai.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jobss.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jonaskjodt.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jonathan-apps.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jonathancarter.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jonfor.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jorgemesa.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "josephrees.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "joyofcookingandbaking.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kachlikova2.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kanotijd.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "katka.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kd-plus.pp.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "keke-shop.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kengilmour.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kikuzuki.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kinderwagen-test24.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kitsostech.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "klif1.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kodokushi.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kokenmetaanbiedingen.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kreavis.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "latus.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "legendofkrystal.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "levendwater.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lewisjuggins.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "liftcannabis.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "limalama.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "listafirmelor.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lothai.re", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ltn-tom-morel.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "luehne.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lunakit.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "m3-gmbh.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "manoirdecontres.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marcoslater.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marktcontact.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mattberryman.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maxwell-english.co.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mazz-tech.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mcc.re", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mcgarderen.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mcpart.land", "include_subdomains": true, "mode": "force-https" },
+ { "name": "medirich.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "medo64.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "medwayindia.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "meizufans.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "metebalci.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "michaelcullen.name", "include_subdomains": true, "mode": "force-https" },
+ { "name": "michaelleibundgut.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "michal-kral.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "microme.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "midonet.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "misskey.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mizd.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "monnyonle.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mpc-hc.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mtasa.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "multitheftauto.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mushikabu.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myonline.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myzina.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nabytko.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nakedalarmclock.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nanogi.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "narach.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "narthollis.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nb.zone", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nbg-ha.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "negai.moe", "include_subdomains": true, "mode": "force-https" },
+ { "name": "neko-life.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "netfs.pl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "netfxharmonics.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "netsparker.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "newcitygas.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nyffo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "obdolbacca.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "obscuredfiles.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "okane.love", "include_subdomains": true, "mode": "force-https" },
+ { "name": "omifind.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ondrej.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onlinedemo.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "openprovider.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "optmos.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oszri.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "otya.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "overclockers.ge", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pan.digital", "include_subdomains": true, "mode": "force-https" },
+ { "name": "per-pedes.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "performaterm.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "peter.org.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pfadfinder-aurich.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "phparcade.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pierre-denoblens.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "playnation.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "plogable.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pretty.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "principaltoolbox.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "profi-durchgangsmelder.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "profpay.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ptgoldensun.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "quai10.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "quantenteranik.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "quantumcourse.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "r811.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "racermaster.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rcpcbd.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "relisten.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "retcor.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rhdigital.pro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "riiconnect24.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ronwo.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rootwpn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "russmarshall.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rww.name", "include_subdomains": true, "mode": "force-https" },
+ { "name": "saltercane.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "saveyour.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "scienceathome.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "screenresolution.space", "include_subdomains": true, "mode": "force-https" },
+ { "name": "secpatrol.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "securitystreak.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "serbanpaun.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "serverstuff.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "seryo.moe", "include_subdomains": true, "mode": "force-https" },
+ { "name": "seryovpn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shtorku.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "siebens.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sightcure.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "silverpvp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sinoscandinavia.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skia.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skyminds.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "slightfuture.click", "include_subdomains": true, "mode": "force-https" },
+ { "name": "slightfuture.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smares.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sms1.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "socomponents.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sosecu.red", "include_subdomains": true, "mode": "force-https" },
+ { "name": "soved.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "spark.team", "include_subdomains": true, "mode": "force-https" },
+ { "name": "speich.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "spicymatch.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sritest.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sstewartgallus.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "starcomproj.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stbennett.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "steakovercooked.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stkbn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stopwoodfin.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stressfreehousehold.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "student-scientist.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "studentloans.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "studentresearcher.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "styles.pm", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sulek.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "susanbpilates.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "susanbpilates.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "synony.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "taskstats.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tcl.ath.cx", "include_subdomains": true, "mode": "force-https" },
+ { "name": "teamzeus.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "techelements.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "techpivot.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "teddy.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tetsumaki.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "textracer.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tf2b.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thedark1337.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "themicrocapital.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "theojones.name", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thesession.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tls.builders", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tmaward.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tmpsantos.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tobiasmathes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tobiasmathes.name", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tommyads.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "toolbox.ninja", "include_subdomains": true, "mode": "force-https" },
+ { "name": "touhou.cc", "include_subdomains": true, "mode": "force-https" },
+ { "name": "treebaglia.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trophee-discount.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "truweight.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tryoneday.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trywesayyes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "typecodes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ukwct.org.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "undone.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unionplat.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "uno-pizza.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "uripura.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "use.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "valis.sx", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vapordepot.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "varghese.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vgatest.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "videnskabsklubben.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vikashkumar.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vimeo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "volcrado.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vpnhot.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "w4xzr.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wallingford.cc", "include_subdomains": true, "mode": "force-https" },
+ { "name": "warandpeace.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "warr.ath.cx", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wasema.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "webseitendesigner.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "westeros.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wiimotion.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "winclient.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "winmodels.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "winmodels.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "winterfeldt.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wolfachtal-alpaka.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wolfsden.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wolfwings.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "woodbury.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "woodomat.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "workingclassmedia.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wpfortify.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wpvulndb.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xdd.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xiangweiqing.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xkviz.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xuexb.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xwaretech.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "y-s.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "youcontrol.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "youyoulemon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ytvwld.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yuyu.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yvesx.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zhanghao.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zorz.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "0au.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "692b8c32.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "abury.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adam-kostecki.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adjagu.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aiflab.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "akostecki.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alaricfavier.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alexvetter.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alkami.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alkamitech.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "andrewbroekman.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "angristan.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "annabellaw.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "approlys.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aquilaguild.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "arabdigitalexpression.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "assdecoeur.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "b-root-force.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bastianstalder.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bbnx.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bettercrypto.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bienici.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "biosignalanalytics.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blendle.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blumenfeldart.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bogosity.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "calculator-imt.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "certcenter.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "charmander.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudstorm.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "convert.zone", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cowboyim.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crizk.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cryptoparty.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "csohack.tk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cyph.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "daniel-ruf.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "darkdestiny.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "davidgow.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ddatsh.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dennisdoes.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dicgaming.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "digitkon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dinube.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dislocated.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "domfee.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "donner-reuschel.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "drupal.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dutchrank.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "edoss.co.za", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elpo.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "embracethedarkness.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "emirabiz.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "europop.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "evrial.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fallenangeldrinks.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fallenangeldrinks.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fallenangeldrinks.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fallenangelspirits.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fallenangelspirits.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fallenangelspirits.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fallenspirits.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "faspirits.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "faspirits.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fdsys.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "feezmodo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "floridaescapes.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "florismouwen.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fotostudio-schweiz.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "freiwurst.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "genxbeats.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gm-assicurazioni.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "goggs.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gpo.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grannyshouse.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gurom.lv", "include_subdomains": true, "mode": "force-https" },
+ { "name": "haozi.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "havelland-obstler.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hotchillibox.co.za", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hotchillibox.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "icusignature.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "internethering.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "inusasha.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "invictusmc.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ionlabs.kr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ip6.li", "include_subdomains": true, "mode": "force-https" },
+ { "name": "isopres.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jagerman.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jean-remy.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jonlabelle.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jordanhamilton.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "joshgrancell.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jrmd.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kassa.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "keganthorrez.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kjarrval.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kurehun.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lafkor.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "leob.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "loacg.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "loucanfixit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marcoececilia.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marie.club", "include_subdomains": true, "mode": "force-https" },
+ { "name": "markusweimar.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mctherealm.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "memo-linux.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mobilemedics.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mobocasino.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myvpl.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nedcdata.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nowak.ninja", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nusatrip-api.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nyantec.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oliverdunk.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "one---line.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "online-bouwmaterialen.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oprechtgezegd.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pariga.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "paul.reviews", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pepchid.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "piconepress.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pirateproxy.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pmponline.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "polimat.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "prediksisydney.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "press-anime-nenkan.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "privytime.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "queercinema.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "realmic.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rene-schwarz.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rhinelander.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rickyromero.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "robud.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rocketmill.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "romainmuller.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "royalpalacenogent.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "scs-simulatoren.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sdcardrecovery.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "seiko-dojo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "selent.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sendya.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shukatsu-note.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "singul4rity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "speedtest-russia.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "spira.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "starstreak.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "taxbench.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "temizmama.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "the-gist.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thegoldregister.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thejserver.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tlo.hosting", "include_subdomains": true, "mode": "force-https" },
+ { "name": "treeby.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "truckstop-magazin.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ttcf.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tuningblog.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tuntitili.fi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "umwandeln-online.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "w4nvu.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wanban.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wdbgroup.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "webm.to", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wenjs.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "winter.engineering", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wis.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wisweb.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wrightdoumawedding.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ww2onlineshop.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yellowcar.website", "include_subdomains": true, "mode": "force-https" },
+ { "name": "youcancraft.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yunity.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zhangyuhao.com", "include_subdomains": true, "mode": "force-https" }
],
// |ReportUMAOnPinFailure| uses these to report which domain was associated
@@ -4126,6 +5894,12 @@
"DROPBOXSTATIC_COM",
"DROPBOXUSERCONTENT_COM",
"WITHYOUTUBE_COM",
- "WITHGOOGLE_COM"
+ "WITHGOOGLE_COM",
+ "G4W_CO",
+ "BADSSL_COM",
+ "YAHOO_COM",
+ "GOOGLEVIDEO_COM",
+ "GOOGLEWEBLIGHT_COM",
+ "GOOGLEADSSERVING_CN"
]
}
diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc
index 96d6231f5cc..75c7c751904 100644
--- a/chromium/net/http/transport_security_state_unittest.cc
+++ b/chromium/net/http/transport_security_state_unittest.cc
@@ -191,6 +191,10 @@ class TransportSecurityStateTest : public testing::Test {
state->enable_static_pins_ = true;
}
+ static void EnableStaticExpectCT(TransportSecurityState* state) {
+ state->enable_static_expect_ct_ = true;
+ }
+
static HashValueVector GetSampleSPKIHashes() {
HashValueVector spki_hashes;
HashValue hash(HASH_VALUE_SHA256);
@@ -1162,69 +1166,6 @@ TEST_F(TransportSecurityStateTest, OverrideBuiltins) {
EXPECT_TRUE(state.ShouldUpgradeToSSL("www.google.com"));
}
-TEST_F(TransportSecurityStateTest, GooglePinnedProperties) {
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "www.example.com"));
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "www.paypal.com"));
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "mail.twitter.com"));
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "www.google.com.int"));
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "jottit.com"));
- // learn.doubleclick.net has a more specific match than
- // *.doubleclick.com, and has 0 or NULL for its required certs.
- // This test ensures that the exact-match-preferred behavior
- // works.
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "learn.doubleclick.net"));
-
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "encrypted.google.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "mail.google.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "accounts.google.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "doubleclick.net"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "ad.doubleclick.net"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "youtube.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "www.profiles.google.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "checkout.google.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "googleadservices.com"));
-
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "www.example.com"));
- EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
- "www.paypal.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "checkout.google.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "googleadservices.com"));
-
- // Test some SNI hosts:
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "gmail.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "googlegroups.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "www.googlegroups.com"));
-
- // These hosts used to only be HSTS when SNI was available.
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "gmail.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "googlegroups.com"));
- EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
- "www.googlegroups.com"));
-}
-
TEST_F(TransportSecurityStateTest, HPKPReporting) {
HostPortPair host_port_pair(kHost, kPort);
HostPortPair subdomain_host_port_pair(kSubdomain, kPort);
@@ -1317,12 +1258,6 @@ TEST_F(TransportSecurityStateTest, HPKPReportOnly) {
MockCertificateReportSender mock_report_sender;
state.SetReportSender(&mock_report_sender);
- // Check that a report is not sent for a Report-Only header with no
- // violation.
- std::string header =
- "pin-sha256=\"" + std::string(kGoodPin1) + "\";pin-sha256=\"" +
- std::string(kGoodPin2) + "\";pin-sha256=\"" + std::string(kGoodPin3) +
- "\";report-uri=\"" + report_uri.spec() + "\";includeSubdomains";
SSLInfo ssl_info;
ssl_info.is_issued_by_known_root = true;
ssl_info.unverified_cert = cert1;
@@ -1330,6 +1265,25 @@ TEST_F(TransportSecurityStateTest, HPKPReportOnly) {
for (size_t i = 0; kGoodPath[i]; i++)
EXPECT_TRUE(AddHash(kGoodPath[i], &ssl_info.public_key_hashes));
+ // HTTPS report URIs on the same host as the pin violation should not
+ // be allowed, to avoid going into a report-sending loop.
+ std::string header = "pin-sha256=\"" + std::string(kGoodPin1) +
+ "\";pin-sha256=\"" + std::string(kGoodPin2) +
+ "\";pin-sha256=\"" + std::string(kGoodPin3) +
+ "\";report-uri=\"https://" + host_port_pair.host() +
+ "/report\";includeSubdomains";
+ EXPECT_TRUE(
+ state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
+ EXPECT_TRUE(mock_report_sender.latest_report_uri().is_empty());
+
+ // Check that a report is not sent for a Report-Only header with no
+ // violation.
+ mock_report_sender.Clear();
+ header = "pin-sha256=\"" + std::string(kGoodPin1) + "\";pin-sha256=\"" +
+ std::string(kGoodPin2) + "\";pin-sha256=\"" +
+ std::string(kGoodPin3) + "\";report-uri=\"" + report_uri.spec() +
+ "\";includeSubdomains";
+
EXPECT_TRUE(
state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
@@ -1349,17 +1303,6 @@ TEST_F(TransportSecurityStateTest, HPKPReportOnly) {
ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report, host_port_pair, true, kHost,
cert1.get(), cert2.get(),
ssl_info.public_key_hashes));
-
- // HTTPS report URIs on the same host as the pin violation should not
- // be allowed, to avoid going into a report-sending loop.
- mock_report_sender.Clear();
- header = "pin-sha256=\"" + std::string(kGoodPin1) + "\";pin-sha256=\"" +
- std::string(kGoodPin2) + "\";pin-sha256=\"" +
- std::string(kGoodPin3) + "\";report-uri=\"https://" +
- host_port_pair.host() + "/report\";includeSubdomains";
- EXPECT_TRUE(
- state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
- EXPECT_TRUE(mock_report_sender.latest_report_uri().is_empty());
}
// Tests that Report-Only reports are not sent on certs that chain to
@@ -1446,14 +1389,13 @@ TEST_F(TransportSecurityStateTest, PreloadedPKPReportUri) {
MockCertificateReportSender mock_report_sender;
state.SetReportSender(&mock_report_sender);
- ASSERT_TRUE(
- TransportSecurityState::IsGooglePinnedProperty(kPreloadedPinDomain));
EnableStaticPins(&state);
TransportSecurityState::PKPState pkp_state;
TransportSecurityState::STSState unused_sts_state;
ASSERT_TRUE(state.GetStaticDomainState(kPreloadedPinDomain, &unused_sts_state,
&pkp_state));
+ ASSERT_TRUE(pkp_state.HasPublicKeyPins());
GURL report_uri = pkp_state.report_uri;
ASSERT_TRUE(report_uri.is_valid());
@@ -1538,4 +1480,89 @@ TEST_F(TransportSecurityStateTest, HPKPReportUriToSameHost) {
EXPECT_EQ(http_report_uri, mock_report_sender.latest_report_uri());
}
+// Tests that redundant reports are rate-limited.
+TEST_F(TransportSecurityStateTest, HPKPReportRateLimiting) {
+ HostPortPair host_port_pair(kHost, kPort);
+ HostPortPair subdomain_host_port_pair(kSubdomain, kPort);
+ GURL report_uri(kReportUri);
+ // Two dummy certs to use as the server-sent and validated chains. The
+ // contents don't matter.
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert1);
+ ASSERT_TRUE(cert2);
+
+ HashValueVector good_hashes, bad_hashes;
+
+ for (size_t i = 0; kGoodPath[i]; i++)
+ EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
+ for (size_t i = 0; kBadPath[i]; i++)
+ EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
+
+ TransportSecurityState state;
+ MockCertificateReportSender mock_report_sender;
+ state.SetReportSender(&mock_report_sender);
+
+ const base::Time current_time = base::Time::Now();
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+ state.AddHPKP(kHost, expiry, true, good_hashes, report_uri);
+
+ EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
+ EXPECT_EQ(std::string(), mock_report_sender.latest_report());
+
+ std::string failure_log;
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+
+ // A report should have been sent. Check that it contains the
+ // right information.
+ EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
+ std::string report = mock_report_sender.latest_report();
+ ASSERT_FALSE(report.empty());
+ ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report, host_port_pair, true, kHost,
+ cert1.get(), cert2.get(),
+ good_hashes));
+ mock_report_sender.Clear();
+
+ // Now trigger the same violation; a duplicative report should not be
+ // sent.
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
+ EXPECT_EQ(std::string(), mock_report_sender.latest_report());
+
+ // Trigger the same violation but with a different report-uri: it
+ // should be sent.
+ GURL report_uri2("http://report-example2.test/test");
+ state.AddHPKP(kHost, expiry, true, good_hashes, report_uri2);
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(report_uri2, mock_report_sender.latest_report_uri());
+ report = mock_report_sender.latest_report();
+ ASSERT_FALSE(report.empty());
+ ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report, host_port_pair, true, kHost,
+ cert1.get(), cert2.get(),
+ good_hashes));
+ mock_report_sender.Clear();
+}
+
+// Tests that static (preloaded) expect CT state is read correctly.
+TEST_F(TransportSecurityStateTest, PreloadedExpectCT) {
+ const char kHostname[] = "preloaded-expect-ct.badssl.com";
+ TransportSecurityState state;
+ TransportSecurityStateTest::EnableStaticExpectCT(&state);
+ TransportSecurityState::ExpectCTState expect_ct_state;
+ EXPECT_TRUE(state.GetStaticExpectCTState(kHostname, &expect_ct_state));
+ EXPECT_EQ(kHostname, expect_ct_state.domain);
+ EXPECT_EQ(GURL("https://report.badssl.com/expect-ct"),
+ expect_ct_state.report_uri);
+ EXPECT_FALSE(state.GetStaticExpectCTState("pinning-test.badssl.com",
+ &expect_ct_state));
+}
+
} // namespace net
diff --git a/chromium/net/http/url_security_manager.cc b/chromium/net/http/url_security_manager.cc
index 4ff0f654dac..8565fac5b59 100644
--- a/chromium/net/http/url_security_manager.cc
+++ b/chromium/net/http/url_security_manager.cc
@@ -4,16 +4,13 @@
#include "net/http/url_security_manager.h"
+#include <utility>
+
#include "net/http/http_auth_filter.h"
namespace net {
-URLSecurityManagerWhitelist::URLSecurityManagerWhitelist(
- const HttpAuthFilter* whitelist_default,
- const HttpAuthFilter* whitelist_delegate)
- : whitelist_default_(whitelist_default),
- whitelist_delegate_(whitelist_delegate) {
-}
+URLSecurityManagerWhitelist::URLSecurityManagerWhitelist() {}
URLSecurityManagerWhitelist::~URLSecurityManagerWhitelist() {}
@@ -30,4 +27,18 @@ bool URLSecurityManagerWhitelist::CanDelegate(const GURL& auth_origin) const {
return false;
}
+void URLSecurityManagerWhitelist::SetDefaultWhitelist(
+ scoped_ptr<HttpAuthFilter> whitelist_default) {
+ whitelist_default_ = std::move(whitelist_default);
+}
+
+void URLSecurityManagerWhitelist::SetDelegateWhitelist(
+ scoped_ptr<HttpAuthFilter> whitelist_delegate) {
+ whitelist_delegate_ = std::move(whitelist_delegate);
+}
+
+bool URLSecurityManagerWhitelist::HasDefaultWhitelist() const {
+ return whitelist_default_.get() != nullptr;
+}
+
} // namespace net
diff --git a/chromium/net/http/url_security_manager.h b/chromium/net/http/url_security_manager.h
index c0d93a23296..694e606751d 100644
--- a/chromium/net/http/url_security_manager.h
+++ b/chromium/net/http/url_security_manager.h
@@ -5,7 +5,7 @@
#ifndef NET_HTTP_URL_SECURITY_MANAGER_H_
#define NET_HTTP_URL_SECURITY_MANAGER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -17,32 +17,30 @@ class HttpAuthFilter;
// The URL security manager controls the policies (allow, deny, prompt user)
// regarding URL actions (e.g., sending the default credentials to a server).
-class NET_EXPORT URLSecurityManager {
+class NET_EXPORT_PRIVATE URLSecurityManager {
public:
URLSecurityManager() {}
virtual ~URLSecurityManager() {}
// Creates a platform-dependent instance of URLSecurityManager.
//
- // |whitelist_default| is the whitelist of servers that default credentials
- // can be used with during NTLM or Negotiate authentication. If
- // |whitelist_default| is NULL and the platform is Windows, it indicates
+ // A security manager has two whitelists, a "default whitelist" that is a
+ // whitelist of servers with which default credentials can be used, and a
+ // "delegate whitelist" that is the whitelist of servers that are allowed to
+ // have delegated Kerberos tickets.
+ //
+ // On creation both whitelists are NULL.
+ //
+ // If the default whitelist is NULL and the platform is Windows, it indicates
// that security zone mapping should be used to determine whether default
- // credentials sxhould be used. If |whitelist_default| is NULL and the
+ // credentials should be used. If the default whitelist is NULL and the
// platform is non-Windows, it indicates that no servers should be
// whitelisted.
//
- // |whitelist_delegate| is the whitelist of servers that are allowed
- // to have Delegated Kerberos tickets. If |whitelist_delegate| is NULL,
- // no servers can have delegated Kerberos tickets.
- //
- // Both |whitelist_default| and |whitelist_delegate| will be owned by
- // the created URLSecurityManager.
+ // If the delegate whitelist is NULL no servers can have delegated Kerberos
+ // tickets.
//
- // TODO(cbentzel): Perhaps it's better to make a non-abstract HttpAuthFilter
- // and just copy into the URLSecurityManager?
- static URLSecurityManager* Create(const HttpAuthFilter* whitelist_default,
- const HttpAuthFilter* whitelist_delegate);
+ static URLSecurityManager* Create();
// Returns true if we can send the default credentials to the server at
// |auth_origin| for HTTP NTLM or Negotiate authentication.
@@ -52,20 +50,30 @@ class NET_EXPORT URLSecurityManager {
// |auth_origin| for HTTP Negotiate authentication.
virtual bool CanDelegate(const GURL& auth_origin) const = 0;
+ virtual void SetDefaultWhitelist(
+ scoped_ptr<HttpAuthFilter> whitelist_default) = 0;
+ virtual void SetDelegateWhitelist(
+ scoped_ptr<HttpAuthFilter> whitelist_delegate) = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(URLSecurityManager);
};
class URLSecurityManagerWhitelist : public URLSecurityManager {
public:
- // The URLSecurityManagerWhitelist takes ownership of the whitelists.
- URLSecurityManagerWhitelist(const HttpAuthFilter* whitelist_default,
- const HttpAuthFilter* whitelist_delegation);
+ URLSecurityManagerWhitelist();
~URLSecurityManagerWhitelist() override;
// URLSecurityManager methods.
bool CanUseDefaultCredentials(const GURL& auth_origin) const override;
bool CanDelegate(const GURL& auth_origin) const override;
+ void SetDefaultWhitelist(
+ scoped_ptr<HttpAuthFilter> whitelist_default) override;
+ void SetDelegateWhitelist(
+ scoped_ptr<HttpAuthFilter> whitelist_delegate) override;
+
+ protected:
+ bool HasDefaultWhitelist() const;
private:
scoped_ptr<const HttpAuthFilter> whitelist_default_;
diff --git a/chromium/net/http/url_security_manager_posix.cc b/chromium/net/http/url_security_manager_posix.cc
index d3b42fb743f..b3e8cd3d610 100644
--- a/chromium/net/http/url_security_manager_posix.cc
+++ b/chromium/net/http/url_security_manager_posix.cc
@@ -9,10 +9,8 @@
namespace net {
// static
-URLSecurityManager* URLSecurityManager::Create(
- const HttpAuthFilter* whitelist_default,
- const HttpAuthFilter* whitelist_delegate) {
- return new URLSecurityManagerWhitelist(whitelist_default, whitelist_delegate);
+URLSecurityManager* URLSecurityManager::Create() {
+ return new URLSecurityManagerWhitelist;
}
} // namespace net
diff --git a/chromium/net/http/url_security_manager_unittest.cc b/chromium/net/http/url_security_manager_unittest.cc
index 8e6d8c5cb9c..7120f54b146 100644
--- a/chromium/net/http/url_security_manager_unittest.cc
+++ b/chromium/net/http/url_security_manager_unittest.cc
@@ -4,7 +4,8 @@
#include "net/http/url_security_manager.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "net/base/net_errors.h"
#include "net/http/http_auth_filter.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -44,12 +45,13 @@ const TestData kTestDataList[] = {
} // namespace
TEST(URLSecurityManager, UseDefaultCredentials) {
- HttpAuthFilterWhitelist* auth_filter = new HttpAuthFilterWhitelist(
- kTestAuthWhitelist);
+ scoped_ptr<HttpAuthFilter> auth_filter(
+ new HttpAuthFilterWhitelist(kTestAuthWhitelist));
ASSERT_TRUE(auth_filter);
// The URL security manager takes ownership of |auth_filter|.
scoped_ptr<URLSecurityManager> url_security_manager(
- URLSecurityManager::Create(auth_filter, NULL));
+ URLSecurityManager::Create());
+ url_security_manager->SetDefaultWhitelist(std::move(auth_filter));
ASSERT_TRUE(url_security_manager.get());
for (size_t i = 0; i < arraysize(kTestDataList); ++i) {
@@ -63,12 +65,13 @@ TEST(URLSecurityManager, UseDefaultCredentials) {
}
TEST(URLSecurityManager, CanDelegate) {
- HttpAuthFilterWhitelist* auth_filter = new HttpAuthFilterWhitelist(
- kTestAuthWhitelist);
+ scoped_ptr<HttpAuthFilter> auth_filter(
+ new HttpAuthFilterWhitelist(kTestAuthWhitelist));
ASSERT_TRUE(auth_filter);
// The URL security manager takes ownership of |auth_filter|.
scoped_ptr<URLSecurityManager> url_security_manager(
- URLSecurityManager::Create(NULL, auth_filter));
+ URLSecurityManager::Create());
+ url_security_manager->SetDelegateWhitelist(std::move(auth_filter));
ASSERT_TRUE(url_security_manager.get());
for (size_t i = 0; i < arraysize(kTestDataList); ++i) {
@@ -82,7 +85,7 @@ TEST(URLSecurityManager, CanDelegate) {
TEST(URLSecurityManager, CanDelegate_NoWhitelist) {
// Nothing can delegate in this case.
scoped_ptr<URLSecurityManager> url_security_manager(
- URLSecurityManager::Create(NULL, NULL));
+ URLSecurityManager::Create());
ASSERT_TRUE(url_security_manager.get());
for (size_t i = 0; i < arraysize(kTestDataList); ++i) {
diff --git a/chromium/net/http/url_security_manager_win.cc b/chromium/net/http/url_security_manager_win.cc
index b0dcaa0beb8..19d2550784c 100644
--- a/chromium/net/http/url_security_manager_win.cc
+++ b/chromium/net/http/url_security_manager_win.cc
@@ -7,6 +7,7 @@
#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_comptr.h"
@@ -26,30 +27,29 @@
namespace net {
-class URLSecurityManagerWin : public URLSecurityManager {
+class URLSecurityManagerWin : public URLSecurityManagerWhitelist {
public:
- explicit URLSecurityManagerWin(const HttpAuthFilter* whitelist_delegate);
+ URLSecurityManagerWin();
+ ~URLSecurityManagerWin() override;
// URLSecurityManager methods:
bool CanUseDefaultCredentials(const GURL& auth_origin) const override;
- bool CanDelegate(const GURL& auth_origin) const override;
private:
bool EnsureSystemSecurityManager();
base::win::ScopedComPtr<IInternetSecurityManager> security_manager_;
- scoped_ptr<const HttpAuthFilter> whitelist_delegate_;
DISALLOW_COPY_AND_ASSIGN(URLSecurityManagerWin);
};
-URLSecurityManagerWin::URLSecurityManagerWin(
- const HttpAuthFilter* whitelist_delegate)
- : whitelist_delegate_(whitelist_delegate) {
-}
+URLSecurityManagerWin::URLSecurityManagerWin() {}
+URLSecurityManagerWin::~URLSecurityManagerWin() {}
bool URLSecurityManagerWin::CanUseDefaultCredentials(
const GURL& auth_origin) const {
+ if (HasDefaultWhitelist())
+ return URLSecurityManagerWhitelist::CanUseDefaultCredentials(auth_origin);
if (!const_cast<URLSecurityManagerWin*>(this)->EnsureSystemSecurityManager())
return false;
@@ -101,14 +101,7 @@ bool URLSecurityManagerWin::CanUseDefaultCredentials(
return false;
}
}
-
-bool URLSecurityManagerWin::CanDelegate(const GURL& auth_origin) const {
- // TODO(cbentzel): Could this just use the security zone as well? Apparently
- // this is what IE does as well.
- if (whitelist_delegate_.get())
- return whitelist_delegate_->IsValid(auth_origin, HttpAuth::AUTH_SERVER);
- return false;
-}
+// TODO(cbentzel): Could CanDelegate use the security zone as well?
bool URLSecurityManagerWin::EnsureSystemSecurityManager() {
if (!security_manager_.get()) {
@@ -124,14 +117,8 @@ bool URLSecurityManagerWin::EnsureSystemSecurityManager() {
}
// static
-URLSecurityManager* URLSecurityManager::Create(
- const HttpAuthFilter* whitelist_default,
- const HttpAuthFilter* whitelist_delegate) {
- // If we have a whitelist, just use that.
- if (whitelist_default)
- return new URLSecurityManagerWhitelist(whitelist_default,
- whitelist_delegate);
- return new URLSecurityManagerWin(whitelist_delegate);
+URLSecurityManager* URLSecurityManager::Create() {
+ return new URLSecurityManagerWin;
}
} // namespace net
diff --git a/chromium/net/interfaces/BUILD.gn b/chromium/net/interfaces/BUILD.gn
index 03a07785251..4a5b7991582 100644
--- a/chromium/net/interfaces/BUILD.gn
+++ b/chromium/net/interfaces/BUILD.gn
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni")
+import("//mojo/public/tools/bindings/mojom.gni")
mojom("interfaces") {
sources = [
diff --git a/chromium/net/log/net_log.cc b/chromium/net/log/net_log.cc
index def248d39ff..a3fde008141 100644
--- a/chromium/net/log/net_log.cc
+++ b/chromium/net/log/net_log.cc
@@ -4,6 +4,8 @@
#include "net/log/net_log.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/debug/alias.h"
#include "base/logging.h"
@@ -29,7 +31,7 @@ scoped_ptr<base::Value> BytesTransferredCallback(
dict->SetInteger("byte_count", byte_count);
if (capture_mode.include_socket_bytes() && byte_count > 0)
dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, byte_count));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> SourceEventParametersCallback(
@@ -39,7 +41,7 @@ scoped_ptr<base::Value> SourceEventParametersCallback(
return scoped_ptr<base::Value>();
scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
source.AddToEventParameters(event_params.get());
- return event_params.Pass();
+ return std::move(event_params);
}
scoped_ptr<base::Value> NetLogBoolCallback(
@@ -48,25 +50,25 @@ scoped_ptr<base::Value> NetLogBoolCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
event_params->SetBoolean(name, value);
- return event_params.Pass();
+ return std::move(event_params);
}
-scoped_ptr<base::Value> NetLogIntegerCallback(
+scoped_ptr<base::Value> NetLogIntCallback(
const char* name,
int value,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
event_params->SetInteger(name, value);
- return event_params.Pass();
+ return std::move(event_params);
}
scoped_ptr<base::Value> NetLogInt64Callback(
const char* name,
- int64 value,
+ int64_t value,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
event_params->SetString(name, base::Int64ToString(value));
- return event_params.Pass();
+ return std::move(event_params);
}
scoped_ptr<base::Value> NetLogStringCallback(
@@ -75,7 +77,7 @@ scoped_ptr<base::Value> NetLogStringCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
event_params->SetString(name, *value);
- return event_params.Pass();
+ return std::move(event_params);
}
scoped_ptr<base::Value> NetLogString16Callback(
@@ -84,19 +86,18 @@ scoped_ptr<base::Value> NetLogString16Callback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
event_params->SetString(name, *value);
- return event_params.Pass();
+ return std::move(event_params);
}
} // namespace
// LoadTimingInfo requires this be 0.
-const uint32 NetLog::Source::kInvalidId = 0;
+const uint32_t NetLog::Source::kInvalidId = 0;
NetLog::Source::Source() : type(SOURCE_NONE), id(kInvalidId) {
}
-NetLog::Source::Source(SourceType type, uint32 id) : type(type), id(id) {
-}
+NetLog::Source::Source(SourceType type, uint32_t id) : type(type), id(id) {}
bool NetLog::Source::IsValid() const {
return id != kInvalidId;
@@ -107,7 +108,7 @@ void NetLog::Source::AddToEventParameters(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("type", static_cast<int>(type));
dict->SetInteger("id", static_cast<int>(id));
- event_params->Set("source_dependency", dict.Pass());
+ event_params->Set("source_dependency", std::move(dict));
}
NetLog::ParametersCallback NetLog::Source::ToEventParametersCallback() const {
@@ -144,7 +145,7 @@ base::Value* NetLog::Entry::ToValue() const {
scoped_ptr<base::DictionaryValue> source_dict(new base::DictionaryValue());
source_dict->SetInteger("id", data_->source.id);
source_dict->SetInteger("type", static_cast<int>(data_->source.type));
- entry_dict->Set("source", source_dict.Pass());
+ entry_dict->Set("source", std::move(source_dict));
// Set the event info.
entry_dict->SetInteger("type", static_cast<int>(data_->type));
@@ -155,16 +156,16 @@ base::Value* NetLog::Entry::ToValue() const {
scoped_ptr<base::Value> value(
data_->parameters_callback->Run(capture_mode_));
if (value)
- entry_dict->Set("params", value.Pass());
+ entry_dict->Set("params", std::move(value));
}
return entry_dict.release();
}
-base::Value* NetLog::Entry::ParametersToValue() const {
+scoped_ptr<base::Value> NetLog::Entry::ParametersToValue() const {
if (data_->parameters_callback)
- return data_->parameters_callback->Run(capture_mode_).release();
- return NULL;
+ return data_->parameters_callback->Run(capture_mode_);
+ return nullptr;
}
NetLog::EntryData::EntryData(EventType type,
@@ -230,7 +231,7 @@ void NetLog::AddGlobalEntry(
&parameters_callback);
}
-uint32 NetLog::NextID() {
+uint32_t NetLog::NextID() {
return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
}
@@ -277,7 +278,7 @@ void NetLog::UpdateIsCapturing() {
// static
std::string NetLog::TickCountToString(const base::TimeTicks& time) {
- int64 delta_time = (time - base::TimeTicks()).InMilliseconds();
+ int64_t delta_time = (time - base::TimeTicks()).InMilliseconds();
return base::Int64ToString(delta_time);
}
@@ -347,14 +348,13 @@ NetLog::ParametersCallback NetLog::BoolCallback(const char* name, bool value) {
}
// static
-NetLog::ParametersCallback NetLog::IntegerCallback(const char* name,
- int value) {
- return base::Bind(&NetLogIntegerCallback, name, value);
+NetLog::ParametersCallback NetLog::IntCallback(const char* name, int value) {
+ return base::Bind(&NetLogIntCallback, name, value);
}
// static
NetLog::ParametersCallback NetLog::Int64Callback(const char* name,
- int64 value) {
+ int64_t value) {
return base::Bind(&NetLogInt64Callback, name, value);
}
@@ -446,7 +446,7 @@ void BoundNetLog::AddEventWithNetErrorCode(NetLog::EventType event_type,
if (net_error >= 0) {
AddEvent(event_type);
} else {
- AddEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
+ AddEvent(event_type, NetLog::IntCallback("net_error", net_error));
}
}
@@ -456,7 +456,7 @@ void BoundNetLog::EndEventWithNetErrorCode(NetLog::EventType event_type,
if (net_error >= 0) {
EndEvent(event_type);
} else {
- EndEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
+ EndEvent(event_type, NetLog::IntCallback("net_error", net_error));
}
}
diff --git a/chromium/net/log/net_log.h b/chromium/net/log/net_log.h
index 7104022e573..87141079e39 100644
--- a/chromium/net/log/net_log.h
+++ b/chromium/net/log/net_log.h
@@ -5,14 +5,17 @@
#ifndef NET_LOG_NET_LOG_H_
#define NET_LOG_NET_LOG_H_
+#include <stdint.h>
+
#include <string>
#include "build/build_config.h"
#include "base/atomicops.h"
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
@@ -78,10 +81,10 @@ class NET_EXPORT NetLog {
// uniquely identify the source, and is used by log observers to infer
// message groupings. Can use NetLog::NextID() to create unique IDs.
struct NET_EXPORT Source {
- static const uint32 kInvalidId;
+ static const uint32_t kInvalidId;
Source();
- Source(SourceType type, uint32 id);
+ Source(SourceType type, uint32_t id);
bool IsValid() const;
// Adds the source to a DictionaryValue containing event parameters,
@@ -99,7 +102,7 @@ class NET_EXPORT NetLog {
static bool FromEventParameters(base::Value* event_params, Source* source);
SourceType type;
- uint32 id;
+ uint32_t id;
};
struct NET_EXPORT EntryData {
@@ -136,7 +139,7 @@ class NET_EXPORT NetLog {
// Returns the parameters as a Value. Returns NULL if there are no
// parameters. Caller takes ownership of returned Value.
- base::Value* ParametersToValue() const;
+ scoped_ptr<base::Value> ParametersToValue() const;
private:
const EntryData* const data_;
@@ -206,7 +209,7 @@ class NET_EXPORT NetLog {
// Returns a unique ID which can be used as a source ID. All returned IDs
// will be unique and greater than 0.
- uint32 NextID();
+ uint32_t NextID();
// Returns true if there are any observers attached to the NetLog. This can be
// used as an optimization to avoid emitting log entries when there is no
@@ -268,14 +271,13 @@ class NET_EXPORT NetLog {
static ParametersCallback BoolCallback(const char* name, bool value);
// Warning: |name| must remain valid for the life of the callback.
- // TODO(mmenke): Rename this to be consistent with Int64Callback.
- static ParametersCallback IntegerCallback(const char* name, int value);
+ static ParametersCallback IntCallback(const char* name, int value);
- // Creates a ParametersCallback that encapsulates a single int64. The
+ // Creates a ParametersCallback that encapsulates a single int64_t. The
// callback will return the value as a StringValue, since IntegerValues
// only support 32-bit values.
// Warning: |name| must remain valid for the life of the callback.
- static ParametersCallback Int64Callback(const char* name, int64 value);
+ static ParametersCallback Int64Callback(const char* name, int64_t value);
// Creates a ParametersCallback that encapsulates a single UTF8 string. Takes
// |value| as a pointer to avoid copying, and emphasize it must be valid for
diff --git a/chromium/net/log/net_log_capture_mode.cc b/chromium/net/log/net_log_capture_mode.cc
index 606dec6e524..a8914d46df8 100644
--- a/chromium/net/log/net_log_capture_mode.cc
+++ b/chromium/net/log/net_log_capture_mode.cc
@@ -14,12 +14,13 @@ namespace {
// for methods of NetLogCaptureMode, which expect that higher values represent a
// strict superset of the capabilities of lower values.
enum InternalValue {
- // Log all events, but do not include the actual transferred bytes and
- // remove cookies and HTTP credentials.
+ // Log all events, but do not include the actual transferred bytes, and
+ // remove cookies and HTTP credentials and HTTP/2 GOAWAY frame debug data.
DEFAULT,
// Log all events, but do not include the actual transferred bytes as
// parameters for bytes sent/received events.
+ // TODO(bnc): Consider renaming to INCLUDE_PRIVACY_INFO.
INCLUDE_COOKIES_AND_CREDENTIALS,
// Log everything possible, even if it is slow and memory expensive.
diff --git a/chromium/net/log/net_log_capture_mode.h b/chromium/net/log/net_log_capture_mode.h
index e08e2ad436a..a2555d6a7ba 100644
--- a/chromium/net/log/net_log_capture_mode.h
+++ b/chromium/net/log/net_log_capture_mode.h
@@ -6,6 +6,7 @@
#define NET_LOG_NET_LOG_CAPTURE_MODE_H_
#include <stdint.h>
+
#include <string>
#include "net/base/net_export.h"
@@ -32,6 +33,7 @@ class NET_EXPORT NetLogCaptureMode {
// no effort to strip cookies and credentials.
// include_cookies_and_credentials() --> true
// include_socket_bytes() --> false
+ // TODO(bnc): Consider renaming to IncludePrivacyInfo().
static NetLogCaptureMode IncludeCookiesAndCredentials();
// Constructs a capture mode which logs the data sent/received from sockets.
@@ -41,6 +43,7 @@ class NET_EXPORT NetLogCaptureMode {
// If include_cookies_and_credentials() is true , then it is OK to log
// events which contain cookies, credentials or other privacy sensitive data.
+ // TODO(bnc): Consider renaming to include_privacy_info().
bool include_cookies_and_credentials() const;
// If include_socket_bytes() is true, then it is OK to output the actual
diff --git a/chromium/net/log/net_log_event_type_list.h b/chromium/net/log/net_log_event_type_list.h
index 0e512897224..966819eec8c 100644
--- a/chromium/net/log/net_log_event_type_list.h
+++ b/chromium/net/log/net_log_event_type_list.h
@@ -253,6 +253,14 @@ EVENT_TYPE(PROXY_SERVICE_WAITING_FOR_INIT_PAC)
// }
EVENT_TYPE(PROXY_SERVICE_RESOLVED_PROXY_LIST)
+// This event is emitted after proxies marked as bad have been deprioritized.
+//
+// It contains these parameters:
+// {
+// "pac_string": <List of valid proxy servers, in PAC format>,
+// }
+EVENT_TYPE(PROXY_SERVICE_DEPRIORITIZED_BAD_PROXIES)
+
// This event is emitted whenever the proxy settings used by ProxyService
// change.
//
@@ -453,7 +461,12 @@ EVENT_TYPE(SSL_SERVER_HANDSHAKE)
// The SSL server requested a client certificate.
EVENT_TYPE(SSL_CLIENT_CERT_REQUESTED)
-// The SSL stack blocked on a private key operation.
+// The SSL stack blocked on a private key operation. The following parameters
+// are attached to the event.
+// {
+// "type": <type of the key>,
+// "hash": <hash function used>,
+// }
EVENT_TYPE(SSL_PRIVATE_KEY_OPERATION)
// The start/end of getting a domain-bound certificate and private key.
@@ -918,7 +931,7 @@ EVENT_TYPE(ENTRY_WRITE_DATA)
// For the BEGIN phase, the following parameters are attached:
// {
// "offset": <Offset at which to start reading>,
-// "buff_len": <Bytes to read/write>,
+// "buf_len": <Bytes to read/write>,
// }
EVENT_TYPE(SPARSE_READ)
EVENT_TYPE(SPARSE_WRITE)
@@ -937,7 +950,7 @@ EVENT_TYPE(SPARSE_WRITE_CHILD_DATA)
//
// For the BEGIN phase, the following parameters are attached:
// {
-// "buff_len": <Bytes to read/write>,
+// "buf_len": <Bytes to read/write>,
// "offset": <Offset at which to start reading>,
// }
//
@@ -1313,10 +1326,6 @@ EVENT_TYPE(HTTP2_SESSION_CLOSE)
// the maximum number of concurrent streams.
EVENT_TYPE(HTTP2_SESSION_STALLED_MAX_STREAMS)
-// Received a value for initial window size in SETTINGS frame with
-// flow control turned off.
-EVENT_TYPE(HTTP2_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL)
-
// Received an out-of-range value for initial window size in SETTINGS
// frame.
// {
@@ -1860,6 +1869,10 @@ EVENT_TYPE(SERVICE_WORKER_ERROR_NO_ACTIVE_VERSION)
EVENT_TYPE(SERVICE_WORKER_ERROR_NO_REQUEST)
// This event is emitted when Service Worker fails to respond because
+// the job delegate behaved incorrectly.
+EVENT_TYPE(SERVICE_WORKER_ERROR_BAD_DELEGATE)
+
+// This event is emitted when Service Worker fails to respond because
// the fetch event could not be dispatched to the worker.
EVENT_TYPE(SERVICE_WORKER_ERROR_FETCH_EVENT_DISPATCH)
@@ -2409,14 +2422,12 @@ EVENT_TYPE(SIMPLE_CACHE_ENTRY_CREATE_BEGIN)
// }
EVENT_TYPE(SIMPLE_CACHE_ENTRY_CREATE_END)
-// This event is created when ReadEntry is called.
+// This event is created when ReadData is called.
// It contains the following parameters:
// {
// "index": <Index being read/written>,
// "offset": <Offset being read/written>,
// "buf_len": <Length of buffer being read to/written from>,
-// "truncate": <If present for a write, the truncate flag is set to true.
-// Not present in reads or writes where it is false>,
// }
EVENT_TYPE(SIMPLE_CACHE_ENTRY_READ_CALL)
@@ -2427,12 +2438,10 @@ EVENT_TYPE(SIMPLE_CACHE_ENTRY_READ_CALL)
// "index": <Index being read/written>,
// "offset": <Offset being read/written>,
// "buf_len": <Length of buffer being read to/written from>,
-// "truncate": <If present for a write, the truncate flag is set to true.
-// Not present in reads or writes where it is false>,
// }
EVENT_TYPE(SIMPLE_CACHE_ENTRY_READ_BEGIN)
-// This event is created when the Simple Cache finishes a ReadEntry call.
+// This event is created when the Simple Cache finishes a ReadData call.
// It contains the following parameters:
// {
// "bytes_copied": <Number of bytes copied. Not present on error>,
@@ -2453,7 +2462,7 @@ EVENT_TYPE(SIMPLE_CACHE_ENTRY_CHECKSUM_BEGIN)
// }
EVENT_TYPE(SIMPLE_CACHE_ENTRY_CHECKSUM_END)
-// This event is created when WriteEntry is called.
+// This event is created when WriteData is called.
// It contains the following parameters:
// {
// "index": <Index being read/written>,
@@ -2485,7 +2494,7 @@ EVENT_TYPE(SIMPLE_CACHE_ENTRY_WRITE_OPTIMISTIC)
// }
EVENT_TYPE(SIMPLE_CACHE_ENTRY_WRITE_BEGIN)
-// This event is created when the Simple Cache finishes a WriteEntry call.
+// This event is created when the Simple Cache finishes a WriteData call.
// It contains the following parameters:
// {
// "bytes_copied": <Number of bytes copied. Not present on error>,
@@ -2493,6 +2502,60 @@ EVENT_TYPE(SIMPLE_CACHE_ENTRY_WRITE_BEGIN)
// }
EVENT_TYPE(SIMPLE_CACHE_ENTRY_WRITE_END)
+// This event is created when ReadSparseData is called.
+// It contains the following parameters:
+// {
+// "offset": <Offset being read/written>,
+// "buf_len": <Length of buffer being read to/written from>,
+// "truncate": <If present for a write, the truncate flag is set to true.
+// Not present in reads or writes where it is false>,
+// }
+EVENT_TYPE(SIMPLE_CACHE_ENTRY_READ_SPARSE_CALL)
+
+// This event is created when the Simple Cache actually begins reading sparse
+// data from the cache entry.
+// It contains the following parameters:
+// {
+// "offset": <Offset being read/written>,
+// "buf_len": <Length of buffer being read to/written from>,
+// "truncate": <If present for a write, the truncate flag is set to true.
+// Not present in reads or writes where it is false>,
+// }
+EVENT_TYPE(SIMPLE_CACHE_ENTRY_READ_SPARSE_BEGIN)
+
+// This event is created when the Simple Cache finishes a ReadSparseData call.
+// It contains the following parameters:
+// {
+// "bytes_copied": <Number of bytes copied. Not present on error>,
+// "net_error": <Network error code. Only present on error>,
+// }
+EVENT_TYPE(SIMPLE_CACHE_ENTRY_READ_SPARSE_END)
+
+// This event is created when WriteSparseData is called.
+// It contains the following parameters:
+// {
+// "offset": <Offset being read/written>,
+// "buf_len": <Length of buffer being read to/written from>,
+// }
+EVENT_TYPE(SIMPLE_CACHE_ENTRY_WRITE_SPARSE_CALL)
+
+// This event is created when the Simple Cache actually begins writing sparse
+// data to the cache entry.
+// It contains the following parameters:
+// {
+// "offset": <Offset being read/written>,
+// "buf_len": <Length of buffer being read to/written from>,
+// }
+EVENT_TYPE(SIMPLE_CACHE_ENTRY_WRITE_SPARSE_BEGIN)
+
+// This event is created when the Simple Cache finishes a WriteSparseData call.
+// It contains the following parameters:
+// {
+// "bytes_copied": <Number of bytes copied. Not present on error>,
+// "net_error": <Network error code. Only present on error>,
+// }
+EVENT_TYPE(SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END)
+
// This event is created when DoomEntry is called. It contains no parameters.
EVENT_TYPE(SIMPLE_CACHE_ENTRY_DOOM_CALL)
diff --git a/chromium/net/log/net_log_source_type_list.h b/chromium/net/log/net_log_source_type_list.h
index 79af389c284..aaaa7713108 100644
--- a/chromium/net/log/net_log_source_type_list.h
+++ b/chromium/net/log/net_log_source_type_list.h
@@ -25,6 +25,8 @@ SOURCE_TYPE(DOWNLOAD)
SOURCE_TYPE(FILESTREAM)
SOURCE_TYPE(DNS_PROBER)
SOURCE_TYPE(PROXY_CLIENT_SOCKET)
+SOURCE_TYPE(PROXY_CLIENT_SOCKET_WRAPPER)
SOURCE_TYPE(DATA_REDUCTION_PROXY)
SOURCE_TYPE(IOS_WEB_VIEW_CERT_VERIFIER)
SOURCE_TYPE(SAFE_BROWSING)
+SOURCE_TYPE(BIDIRECTIONAL_STREAM)
diff --git a/chromium/net/log/net_log_unittest.cc b/chromium/net/log/net_log_unittest.cc
index 0046b4699f9..1a16facf22f 100644
--- a/chromium/net/log/net_log_unittest.cc
+++ b/chromium/net/log/net_log_unittest.cc
@@ -4,8 +4,10 @@
#include "net/log/net_log.h"
+#include <utility>
+
#include "base/bind.h"
-#include "base/memory/scoped_vector.h"
+#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/simple_thread.h"
#include "base/values.h"
@@ -44,7 +46,7 @@ scoped_ptr<base::Value> CaptureModeToValue(NetLogCaptureMode capture_mode) {
scoped_ptr<base::Value> NetCaptureModeCallback(NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->Set("capture_mode", CaptureModeToValue(capture_mode));
- return dict.Pass();
+ return std::move(dict);
}
TEST(NetLogTest, Basic) {
@@ -128,17 +130,19 @@ class LoggingObserver : public NetLog::ThreadSafeObserver {
}
void OnAddEntry(const NetLog::Entry& entry) override {
- base::Value* value = entry.ToValue();
- base::DictionaryValue* dict = NULL;
- ASSERT_TRUE(value->GetAsDictionary(&dict));
- values_.push_back(dict);
+ scoped_ptr<base::DictionaryValue> dict =
+ base::DictionaryValue::From(make_scoped_ptr(entry.ToValue()));
+ ASSERT_TRUE(dict);
+ values_.push_back(std::move(dict));
}
size_t GetNumValues() const { return values_.size(); }
- base::DictionaryValue* GetValue(size_t index) const { return values_[index]; }
+ base::DictionaryValue* GetValue(size_t index) const {
+ return values_[index].get();
+ }
private:
- ScopedVector<base::DictionaryValue> values_;
+ std::vector<scoped_ptr<base::DictionaryValue>> values_;
};
void AddEvent(NetLog* net_log) {
diff --git a/chromium/net/log/net_log_util.cc b/chromium/net/log/net_log_util.cc
index 46282f7df0b..f79be1797b2 100644
--- a/chromium/net/log/net_log_util.cc
+++ b/chromium/net/log/net_log_util.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -153,7 +154,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
for (size_t i = 0; i < arraysize(kCertStatusFlags); i++)
dict->SetInteger(kCertStatusFlags[i].name, kCertStatusFlags[i].constant);
- constants_dict->Set("certStatusFlag", dict.Pass());
+ constants_dict->Set("certStatusFlag", std::move(dict));
}
// Add a dictionary with information about the relationship between load flag
@@ -164,7 +165,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
for (size_t i = 0; i < arraysize(kLoadFlags); i++)
dict->SetInteger(kLoadFlags[i].name, kLoadFlags[i].constant);
- constants_dict->Set("loadFlag", dict.Pass());
+ constants_dict->Set("loadFlag", std::move(dict));
}
// Add a dictionary with information about the relationship between load state
@@ -175,7 +176,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
for (size_t i = 0; i < arraysize(kLoadStateTable); i++)
dict->SetInteger(kLoadStateTable[i].name, kLoadStateTable[i].constant);
- constants_dict->Set("loadState", dict.Pass());
+ constants_dict->Set("loadState", std::move(dict));
}
{
@@ -184,7 +185,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
dict->SetInteger(string, NET_INFO_##label);
#include "net/base/net_info_source_list.h"
#undef NET_INFO_SOURCE
- constants_dict->Set("netInfoSources", dict.Pass());
+ constants_dict->Set("netInfoSources", std::move(dict));
}
// Add information on the relationship between net error codes and their
@@ -195,7 +196,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
for (size_t i = 0; i < arraysize(kNetErrors); i++)
dict->SetInteger(ErrorToShortString(kNetErrors[i]), kNetErrors[i]);
- constants_dict->Set("netError", dict.Pass());
+ constants_dict->Set("netError", std::move(dict));
}
// Add information on the relationship between QUIC error codes and their
@@ -209,7 +210,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
static_cast<int>(error));
}
- constants_dict->Set("quicError", dict.Pass());
+ constants_dict->Set("quicError", std::move(dict));
}
// Add information on the relationship between QUIC RST_STREAM error codes
@@ -224,7 +225,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
static_cast<int>(error));
}
- constants_dict->Set("quicRstStreamError", dict.Pass());
+ constants_dict->Set("quicRstStreamError", std::move(dict));
}
// Add information on the relationship between SDCH problem codes and their
@@ -235,7 +236,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
for (size_t i = 0; i < arraysize(kSdchProblems); i++)
dict->SetInteger(kSdchProblems[i].name, kSdchProblems[i].constant);
- constants_dict->Set("sdchProblemCode", dict.Pass());
+ constants_dict->Set("sdchProblemCode", std::move(dict));
}
// Information about the relationship between event phase enums and their
@@ -247,7 +248,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
dict->SetInteger("PHASE_END", NetLog::PHASE_END);
dict->SetInteger("PHASE_NONE", NetLog::PHASE_NONE);
- constants_dict->Set("logEventPhase", dict.Pass());
+ constants_dict->Set("logEventPhase", std::move(dict));
}
// Information about the relationship between source type enums and
@@ -268,14 +269,14 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
dict->SetInteger("ADDRESS_FAMILY_IPV4", ADDRESS_FAMILY_IPV4);
dict->SetInteger("ADDRESS_FAMILY_IPV6", ADDRESS_FAMILY_IPV6);
- constants_dict->Set("addressFamily", dict.Pass());
+ constants_dict->Set("addressFamily", std::move(dict));
}
// Information about how the "time ticks" values we have given it relate to
// actual system times. Time ticks are used throughout since they are stable
// across system clock changes.
{
- int64 tick_to_unix_time_ms =
+ int64_t tick_to_unix_time_ms =
(base::TimeTicks() - base::TimeTicks::UnixEpoch()).InMilliseconds();
// Pass it as a string, since it may be too large to fit in an integer.
@@ -300,7 +301,7 @@ scoped_ptr<base::DictionaryValue> GetNetConstants() {
constants_dict->Set("activeFieldTrialGroups", field_trial_groups);
}
- return constants_dict.Pass();
+ return constants_dict;
}
NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
@@ -323,7 +324,7 @@ NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
dict->Set("effective", proxy_service->config().ToValue());
net_info_dict->Set(NetInfoSourceToString(NET_INFO_PROXY_SETTINGS),
- dict.Pass());
+ std::move(dict));
}
if (info_sources & NET_INFO_BAD_PROXIES) {
@@ -342,7 +343,7 @@ NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
dict->SetString("bad_until",
NetLog::TickCountToString(retry_info.bad_until));
- list->Append(dict.Pass());
+ list->Append(std::move(dict));
}
net_info_dict->Set(NetInfoSourceToString(NET_INFO_BAD_PROXIES), list);
@@ -354,9 +355,9 @@ NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
HostCache* cache = host_resolver->GetHostCache();
if (cache) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- base::Value* dns_config = host_resolver->GetDnsConfigAsValue();
+ scoped_ptr<base::Value> dns_config = host_resolver->GetDnsConfigAsValue();
if (dns_config)
- dict->Set("dns_config", dns_config);
+ dict->Set("dns_config", std::move(dns_config));
base::DictionaryValue* cache_info_dict = new base::DictionaryValue();
@@ -395,7 +396,7 @@ NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
cache_info_dict->Set("entries", entry_list);
dict->Set("cache", cache_info_dict);
net_info_dict->Set(NetInfoSourceToString(NET_INFO_HOST_RESOLVER),
- dict.Pass());
+ std::move(dict));
}
}
@@ -420,16 +421,28 @@ NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
"use_alternative_services",
http_network_session->params().use_alternative_services);
- NextProtoVector next_protos;
- http_network_session->GetNextProtos(&next_protos);
- if (!next_protos.empty()) {
+ NextProtoVector alpn_protos;
+ http_network_session->GetAlpnProtos(&alpn_protos);
+ if (!alpn_protos.empty()) {
std::string next_protos_string;
- for (const NextProto proto : next_protos) {
+ for (NextProto proto : alpn_protos) {
if (!next_protos_string.empty())
next_protos_string.append(",");
next_protos_string.append(SSLClientSocket::NextProtoToString(proto));
}
- status_dict->SetString("next_protos", next_protos_string);
+ status_dict->SetString("alpn_protos", next_protos_string);
+ }
+
+ NextProtoVector npn_protos;
+ http_network_session->GetNpnProtos(&npn_protos);
+ if (!npn_protos.empty()) {
+ std::string next_protos_string;
+ for (NextProto proto : npn_protos) {
+ if (!next_protos_string.empty())
+ next_protos_string.append(",");
+ next_protos_string.append(SSLClientSocket::NextProtoToString(proto));
+ }
+ status_dict->SetString("npn_protos", next_protos_string);
}
net_info_dict->Set(NetInfoSourceToString(NET_INFO_SPDY_STATUS),
@@ -477,10 +490,11 @@ NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
} else {
info_dict.reset(new base::DictionaryValue());
}
- net_info_dict->Set(NetInfoSourceToString(NET_INFO_SDCH), info_dict.Pass());
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_SDCH),
+ std::move(info_dict));
}
- return net_info_dict.Pass();
+ return net_info_dict;
}
NET_EXPORT void CreateNetLogEntriesForActiveObjects(
@@ -502,7 +516,6 @@ NET_EXPORT void CreateNetLogEntriesForActiveObjects(
std::sort(requests.begin(), requests.end(), RequestCreatedBefore);
// Create fake events.
- ScopedVector<NetLog::Entry> entries;
for (const auto& request : requests) {
NetLog::ParametersCallback callback =
base::Bind(&GetRequestStateAsValue, base::Unretained(request));
diff --git a/chromium/net/log/net_log_util_unittest.cc b/chromium/net/log/net_log_util_unittest.cc
index 1f9db74568c..c4c04697ae9 100644
--- a/chromium/net/log/net_log_util_unittest.cc
+++ b/chromium/net/log/net_log_util_unittest.cc
@@ -5,6 +5,7 @@
#include "net/log/net_log_util.h"
#include <set>
+#include <vector>
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
@@ -15,7 +16,6 @@
#include "net/http/http_transaction.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -64,11 +64,10 @@ TEST(NetLogUtil, CreateNetLogEntriesForActiveObjectsOneContext) {
context.Init();
TestDelegate delegate;
for (size_t num_requests = 0; num_requests < 5; ++num_requests) {
- ScopedVector<URLRequest> requests;
+ std::vector<scoped_ptr<URLRequest>> requests;
for (size_t i = 0; i < num_requests; ++i) {
requests.push_back(context.CreateRequest(GURL("about:life"),
- DEFAULT_PRIORITY,
- &delegate).release());
+ DEFAULT_PRIORITY, &delegate));
}
std::set<URLRequestContext*> contexts;
contexts.insert(&context);
@@ -90,18 +89,16 @@ TEST(NetLogUtil, CreateNetLogEntriesForActiveObjectsMultipleContexts) {
TestDelegate delegate;
for (size_t num_requests = 0; num_requests < 5; ++num_requests) {
NetLog net_log;
- ScopedVector<TestURLRequestContext> contexts;
- ScopedVector<URLRequest> requests;
+ std::vector<scoped_ptr<TestURLRequestContext>> contexts;
+ std::vector<scoped_ptr<URLRequest>> requests;
std::set<URLRequestContext*> context_set;
for (size_t i = 0; i < num_requests; ++i) {
- contexts.push_back(new TestURLRequestContext(true));
+ contexts.push_back(make_scoped_ptr(new TestURLRequestContext(true)));
contexts[i]->set_net_log(&net_log);
contexts[i]->Init();
- context_set.insert(contexts[i]);
- requests.push_back(
- contexts[i]
- ->CreateRequest(GURL("about:hats"), DEFAULT_PRIORITY, &delegate)
- .release());
+ context_set.insert(contexts[i].get());
+ requests.push_back(contexts[i]->CreateRequest(
+ GURL("about:hats"), DEFAULT_PRIORITY, &delegate));
}
TestNetLog test_net_log;
CreateNetLogEntriesForActiveObjects(context_set,
diff --git a/chromium/net/log/test_net_log.cc b/chromium/net/log/test_net_log.cc
index a1b383e8bce..c8d04cb71f1 100644
--- a/chromium/net/log/test_net_log.cc
+++ b/chromium/net/log/test_net_log.cc
@@ -4,6 +4,7 @@
#include "net/log/test_net_log.h"
+#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/values.h"
@@ -49,16 +50,14 @@ class TestNetLog::Observer : public NetLog::ThreadSafeObserver {
void OnAddEntry(const NetLog::Entry& entry) override {
// Using Dictionaries instead of Values makes checking values a little
// simpler.
- base::DictionaryValue* param_dict = nullptr;
- base::Value* param_value = entry.ParametersToValue();
- if (param_value && !param_value->GetAsDictionary(&param_dict))
- delete param_value;
+ scoped_ptr<base::DictionaryValue> param_dict =
+ base::DictionaryValue::From(entry.ParametersToValue());
// Only need to acquire the lock when accessing class variables.
base::AutoLock lock(lock_);
- entry_list_.push_back(TestNetLogEntry(
- entry.type(), base::TimeTicks::Now(), entry.source(), entry.phase(),
- scoped_ptr<base::DictionaryValue>(param_dict)));
+ entry_list_.push_back(TestNetLogEntry(entry.type(), base::TimeTicks::Now(),
+ entry.source(), entry.phase(),
+ std::move(param_dict)));
}
// Needs to be "mutable" to use it in GetEntries().
diff --git a/chromium/net/log/test_net_log.h b/chromium/net/log/test_net_log.h
index 7dc30114736..3605a9c89e7 100644
--- a/chromium/net/log/test_net_log.h
+++ b/chromium/net/log/test_net_log.h
@@ -5,11 +5,13 @@
#ifndef NET_LOG_TEST_NET_LOG_H_
#define NET_LOG_TEST_NET_LOG_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/log/net_log.h"
#include "net/log/test_net_log_entry.h"
diff --git a/chromium/net/log/test_net_log_entry.cc b/chromium/net/log/test_net_log_entry.cc
index 34e9ffa6dc0..e9fd982217e 100644
--- a/chromium/net/log/test_net_log_entry.cc
+++ b/chromium/net/log/test_net_log_entry.cc
@@ -4,6 +4,8 @@
#include "net/log/test_net_log_entry.h"
+#include <utility>
+
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/values.h"
@@ -19,7 +21,7 @@ TestNetLogEntry::TestNetLogEntry(NetLog::EventType type,
time(time),
source(source),
phase(phase),
- params(params.Pass()) {
+ params(std::move(params)) {
// Only entries without a NetLog should have an invalid source.
CHECK(source.IsValid());
}
diff --git a/chromium/net/log/test_net_log_util.h b/chromium/net/log/test_net_log_util.h
index b0e4503e33a..8734cea9530 100644
--- a/chromium/net/log/test_net_log_util.h
+++ b/chromium/net/log/test_net_log_util.h
@@ -5,6 +5,8 @@
#ifndef NET_LOG_TEST_NET_LOG_UTIL_H_
#define NET_LOG_TEST_NET_LOG_UTIL_H_
+#include <stddef.h>
+
#include "net/log/net_log.h"
#include "net/log/test_net_log_entry.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/log/trace_net_log_observer.cc b/chromium/net/log/trace_net_log_observer.cc
index 4978e64c79e..6a64e506644 100644
--- a/chromium/net/log/trace_net_log_observer.cc
+++ b/chromium/net/log/trace_net_log_observer.cc
@@ -5,8 +5,8 @@
#include "net/log/trace_net_log_observer.h"
#include <stdio.h>
-
#include <string>
+#include <utility>
#include "base/json/json_writer.h"
#include "base/logging.h"
@@ -24,7 +24,8 @@ const char kNetLogTracingCategory[] = "netlog";
class TracedValue : public base::trace_event::ConvertableToTraceFormat {
public:
- explicit TracedValue(scoped_ptr<base::Value> value) : value_(value.Pass()) {}
+ explicit TracedValue(scoped_ptr<base::Value> value)
+ : value_(std::move(value)) {}
private:
~TracedValue() override {}
@@ -62,7 +63,7 @@ void TraceNetLogObserver::OnAddEntry(const NetLog::Entry& entry) {
entry.source().id, "source_type",
NetLog::SourceTypeToString(entry.source().type), "params",
scoped_refptr<base::trace_event::ConvertableToTraceFormat>(
- new TracedValue(params.Pass())));
+ new TracedValue(std::move(params))));
break;
case NetLog::PHASE_END:
TRACE_EVENT_NESTABLE_ASYNC_END2(
@@ -70,7 +71,7 @@ void TraceNetLogObserver::OnAddEntry(const NetLog::Entry& entry) {
entry.source().id, "source_type",
NetLog::SourceTypeToString(entry.source().type), "params",
scoped_refptr<base::trace_event::ConvertableToTraceFormat>(
- new TracedValue(params.Pass())));
+ new TracedValue(std::move(params))));
break;
case NetLog::PHASE_NONE:
TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(
@@ -78,7 +79,7 @@ void TraceNetLogObserver::OnAddEntry(const NetLog::Entry& entry) {
entry.source().id, "source_type",
NetLog::SourceTypeToString(entry.source().type), "params",
scoped_refptr<base::trace_event::ConvertableToTraceFormat>(
- new TracedValue(params.Pass())));
+ new TracedValue(std::move(params))));
break;
}
}
diff --git a/chromium/net/log/trace_net_log_observer_unittest.cc b/chromium/net/log/trace_net_log_observer_unittest.cc
index 4adcd0f7097..a56ab4c17b4 100644
--- a/chromium/net/log/trace_net_log_observer_unittest.cc
+++ b/chromium/net/log/trace_net_log_observer_unittest.cc
@@ -128,7 +128,7 @@ class TraceNetLogObserverTest : public testing::Test {
continue;
filtered_trace_events->Append(dict->DeepCopy());
}
- return filtered_trace_events.Pass();
+ return filtered_trace_events;
}
base::ListValue* trace_events() const { return trace_events_.get(); }
diff --git a/chromium/net/log/write_to_file_net_log_observer.cc b/chromium/net/log/write_to_file_net_log_observer.cc
index 5c4f95142d1..3bc78141b38 100644
--- a/chromium/net/log/write_to_file_net_log_observer.cc
+++ b/chromium/net/log/write_to_file_net_log_observer.cc
@@ -5,8 +5,8 @@
#include "net/log/write_to_file_net_log_observer.h"
#include <stdio.h>
-
#include <set>
+#include <utility>
#include "base/json/json_writer.h"
#include "base/logging.h"
@@ -36,7 +36,7 @@ void WriteToFileNetLogObserver::StartObserving(
base::Value* constants,
URLRequestContext* url_request_context) {
DCHECK(file.get());
- file_ = file.Pass();
+ file_ = std::move(file);
added_events_ = false;
// Write constants to the output file. This allows loading files that have
diff --git a/chromium/net/log/write_to_file_net_log_observer_unittest.cc b/chromium/net/log/write_to_file_net_log_observer_unittest.cc
index 6a8280e6270..ddc8aa978db 100644
--- a/chromium/net/log/write_to_file_net_log_observer_unittest.cc
+++ b/chromium/net/log/write_to_file_net_log_observer_unittest.cc
@@ -4,6 +4,8 @@
#include "net/log/write_to_file_net_log_observer.h"
+#include <utility>
+
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
@@ -40,7 +42,7 @@ TEST_F(WriteToFileNetLogObserverTest, GeneratesValidJSONForNoEvents) {
base::ScopedFILE file(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
scoped_ptr<WriteToFileNetLogObserver> logger(new WriteToFileNetLogObserver());
- logger->StartObserving(&net_log_, file.Pass(), nullptr, nullptr);
+ logger->StartObserving(&net_log_, std::move(file), nullptr, nullptr);
logger->StopObserving(nullptr);
logger.reset();
@@ -65,14 +67,14 @@ TEST_F(WriteToFileNetLogObserverTest, CaptureMode) {
base::ScopedFILE file(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
WriteToFileNetLogObserver logger;
- logger.StartObserving(&net_log_, file.Pass(), nullptr, nullptr);
+ logger.StartObserving(&net_log_, std::move(file), nullptr, nullptr);
EXPECT_EQ(NetLogCaptureMode::Default(), logger.capture_mode());
logger.StopObserving(nullptr);
file.reset(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
logger.set_capture_mode(NetLogCaptureMode::IncludeCookiesAndCredentials());
- logger.StartObserving(&net_log_, file.Pass(), nullptr, nullptr);
+ logger.StartObserving(&net_log_, std::move(file), nullptr, nullptr);
EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(),
logger.capture_mode());
logger.StopObserving(nullptr);
@@ -82,7 +84,7 @@ TEST_F(WriteToFileNetLogObserverTest, GeneratesValidJSONWithOneEvent) {
base::ScopedFILE file(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
scoped_ptr<WriteToFileNetLogObserver> logger(new WriteToFileNetLogObserver());
- logger->StartObserving(&net_log_, file.Pass(), nullptr, nullptr);
+ logger->StartObserving(&net_log_, std::move(file), nullptr, nullptr);
const int kDummyId = 1;
NetLog::Source source(NetLog::SOURCE_HTTP2_SESSION, kDummyId);
@@ -112,7 +114,7 @@ TEST_F(WriteToFileNetLogObserverTest, GeneratesValidJSONWithMultipleEvents) {
base::ScopedFILE file(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
scoped_ptr<WriteToFileNetLogObserver> logger(new WriteToFileNetLogObserver());
- logger->StartObserving(&net_log_, file.Pass(), nullptr, nullptr);
+ logger->StartObserving(&net_log_, std::move(file), nullptr, nullptr);
const int kDummyId = 1;
NetLog::Source source(NetLog::SOURCE_HTTP2_SESSION, kDummyId);
@@ -147,7 +149,7 @@ TEST_F(WriteToFileNetLogObserverTest, CustomConstants) {
base::ScopedFILE file(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
scoped_ptr<WriteToFileNetLogObserver> logger(new WriteToFileNetLogObserver());
- logger->StartObserving(&net_log_, file.Pass(), constants.get(), nullptr);
+ logger->StartObserving(&net_log_, std::move(file), constants.get(), nullptr);
logger->StopObserving(nullptr);
logger.reset();
@@ -175,7 +177,7 @@ TEST_F(WriteToFileNetLogObserverTest, GeneratesValidJSONWithContext) {
base::ScopedFILE file(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
scoped_ptr<WriteToFileNetLogObserver> logger(new WriteToFileNetLogObserver());
- logger->StartObserving(&net_log_, file.Pass(), nullptr, &context);
+ logger->StartObserving(&net_log_, std::move(file), nullptr, &context);
logger->StopObserving(&context);
logger.reset();
@@ -214,7 +216,7 @@ TEST_F(WriteToFileNetLogObserverTest,
base::ScopedFILE file(base::OpenFile(log_path_, "w"));
ASSERT_TRUE(file);
scoped_ptr<WriteToFileNetLogObserver> logger(new WriteToFileNetLogObserver());
- logger->StartObserving(&net_log_, file.Pass(), nullptr, &context);
+ logger->StartObserving(&net_log_, std::move(file), nullptr, &context);
logger->StopObserving(&context);
logger.reset();
diff --git a/chromium/net/net.gyp b/chromium/net/net.gyp
index 2b2b343ddbe..1a5690786ca 100644
--- a/chromium/net/net.gyp
+++ b/chromium/net/net.gyp
@@ -6,6 +6,8 @@
'variables': {
'chromium_code': 1,
'linux_link_kerberos%': 0,
+ # Enables BidirectionalStream; Used in cronet, disabled by default.
+ 'enable_bidirectional_stream%': 0,
'conditions': [
['chromeos==1 or embedded==1 or OS=="ios"', {
# Disable Kerberos on ChromeOS and iOS, at least for now.
@@ -53,6 +55,7 @@
'base/registry_controlled_domains/effective_tld_names_unittest4.gperf',
'base/registry_controlled_domains/effective_tld_names_unittest5.gperf',
'base/registry_controlled_domains/effective_tld_names_unittest6.gperf',
+ 'base/stale_while_revalidate_experiment_domains.gperf',
],
'rules': [
{
@@ -62,11 +65,11 @@
'<(SHARED_INTERMEDIATE_DIR)/net/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT)-inc.cc',
],
'inputs': [
- 'tools/tld_cleanup/make_dafsa.py',
+ 'tools/dafsa/make_dafsa.py',
],
'action': [
'python',
- 'tools/tld_cleanup/make_dafsa.py',
+ 'tools/dafsa/make_dafsa.py',
'<(RULE_INPUT_PATH)',
'<(SHARED_INTERMEDIATE_DIR)/net/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT)-inc.cc',
],
@@ -80,7 +83,7 @@
},
{
# Protobuf compiler / generator for QUIC crypto protocol buffer.
- # GN version: //net/quic/proto
+ # GN version: //net:net_quic_proto
'target_name': 'net_quic_proto',
'type': 'static_library',
'sources': [
@@ -106,20 +109,33 @@
'target_name': 'net',
'dependencies': [
'../base/base.gyp:base_i18n',
+ '../third_party/brotli/brotli.gyp:brotli',
'../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc',
'../third_party/protobuf/protobuf.gyp:protobuf_lite',
'../url/url.gyp:url_lib',
+ 'net_features',
'net_quic_proto',
],
'sources': [
'base/filename_util_icu.cc',
'base/net_string_util_icu.cc',
- 'base/net_util_icu.cc',
+ 'filter/brotli_filter.cc',
],
'includes': [ 'net_common.gypi' ],
},
{
+ # GN version: //net:features
+ 'target_name': 'net_features',
+ 'includes': [ '../build/buildflag_header.gypi' ],
+ 'variables': {
+ 'buildflag_header_path': 'net/net_features.h',
+ 'buildflag_flags': [
+ 'ENABLE_BIDIRECTIONAL_STREAM=<(enable_bidirectional_stream)',
+ ],
+ },
+ },
+ {
# GN version: //net:net_unittests
'target_name': 'net_unittests',
'type': '<(gtest_target_type)',
@@ -142,6 +158,7 @@
'net_extras',
'net_test_support',
'simple_quic_tools',
+ 'stale_while_revalidate_experiment_domains',
],
'sources': [
'<@(net_test_sources)',
@@ -233,25 +250,19 @@
'http/http_auth_handler_negotiate_unittest.cc',
],
}],
- [ 'use_openssl == 1 or (desktop_linux == 0 and chromeos == 0 and OS != "ios")', {
- # Only include this test when on Posix and using NSS for
- # cert verification or on iOS (which also uses NSS for certs).
+ [ 'use_nss_certs == 0 and OS != "ios"', {
+ # Only include this test when using system NSS for cert verification
+ # or on iOS (which also uses NSS for certs).
'sources!': [
'cert_net/nss_ocsp_unittest.cc',
],
}],
[ 'use_openssl==1', {
- # When building for OpenSSL, we need to exclude NSS specific tests
- # or functionality not supported by OpenSSL yet.
- # TODO(bulach): Add equivalent tests when the underlying
- # functionality is ported to OpenSSL.
'sources!': [
- 'cert/x509_util_nss_unittest.cc',
'quic/test_tools/crypto_test_utils_nss.cc',
],
}, { # else !use_openssl: remove the unneeded files and pull in NSS.
'sources!': [
- 'cert/x509_util_openssl_unittest.cc',
'quic/test_tools/crypto_test_utils_openssl.cc',
'socket/ssl_client_socket_openssl_unittest.cc',
'ssl/ssl_client_session_cache_openssl_unittest.cc',
@@ -275,6 +286,7 @@
['disable_file_support==1', {
'sources!': [
'base/directory_lister_unittest.cc',
+ 'base/directory_listing_unittest.cc',
'url_request/url_request_file_job_unittest.cc',
],
}],
@@ -287,6 +299,12 @@
],
},
],
+ [ 'enable_bidirectional_stream!=1', {
+ 'sources!': [
+ 'http/bidirectional_stream_unittest.cc',
+ ],
+ },
+ ],
[ 'enable_built_in_dns!=1', {
'sources!': [
'dns/address_sorter_posix_unittest.cc',
@@ -360,11 +378,14 @@
'action_name': 'copy_test_data',
'variables': {
'test_data_files': [
+ 'data/certificate_policies_unittest/',
+ 'data/name_constraints_unittest/',
+ 'data/parse_certificate_unittest/',
'data/ssl/certificates/',
'data/test.html',
'data/url_request_unittest/',
+ 'data/verify_certificate_chain_unittest/',
'data/verify_name_match_unittest/names/',
- 'data/parse_certificate_unittest/',
],
'test_data_prefix': 'net',
},
@@ -379,6 +400,7 @@
'disk_cache/backend_unittest.cc',
'disk_cache/blockfile/block_files_unittest.cc',
# Need to read input data files.
+ 'filter/brotli_filter_unittest.cc',
'filter/gzip_filter_unittest.cc',
# Need TestServer.
"cert_net/cert_net_fetcher_impl_unittest.cc",
@@ -523,6 +545,7 @@
'cookies/cookie_store_test_callbacks.h',
'cookies/cookie_store_test_helpers.cc',
'cookies/cookie_store_test_helpers.h',
+ 'cookies/cookie_store_unittest.h',
'disk_cache/disk_cache_test_base.cc',
'disk_cache/disk_cache_test_base.h',
'disk_cache/disk_cache_test_util.cc',
@@ -556,6 +579,8 @@
'test/channel_id_test_util.h',
'test/ct_test_util.cc',
'test/ct_test_util.h',
+ 'test/embedded_test_server/default_handlers.cc',
+ 'test/embedded_test_server/default_handlers.h',
'test/embedded_test_server/embedded_test_server.cc',
'test/embedded_test_server/embedded_test_server.h',
'test/embedded_test_server/http_connection.cc',
@@ -564,10 +589,8 @@
'test/embedded_test_server/http_request.h',
'test/embedded_test_server/http_response.cc',
'test/embedded_test_server/http_response.h',
- 'test/embedded_test_server/stream_listen_socket.cc',
- 'test/embedded_test_server/stream_listen_socket.h',
- 'test/embedded_test_server/tcp_listen_socket.cc',
- 'test/embedded_test_server/tcp_listen_socket.h',
+ 'test/embedded_test_server/request_handler_util.cc',
+ 'test/embedded_test_server/request_handler_util.h',
'test/event_waiter.h',
'test/net_test_suite.cc',
'test/net_test_suite.h',
@@ -580,6 +603,7 @@
'test/spawned_test_server/local_test_server_posix.cc',
'test/spawned_test_server/local_test_server_win.cc',
'test/spawned_test_server/spawned_test_server.h',
+ 'test/test_certificate_data.h',
'test/url_request/ssl_certificate_error_job.cc',
'test/url_request/ssl_certificate_error_job.h',
'test/url_request/url_request_failed_job.cc',
@@ -638,8 +662,6 @@
'net_test_jni_headers',
],
'sources': [
- 'test/android/net_test_jni_onload.cc',
- 'test/android/net_test_jni_onload.h',
'test/embedded_test_server/android/embedded_test_server_android.cc',
'test/embedded_test_server/android/embedded_test_server_android.h',
'test/spawned_test_server/remote_test_server.cc',
@@ -824,8 +846,8 @@
'tools/quic/quic_in_memory_cache.h',
'tools/quic/quic_per_connection_packet_writer.cc',
'tools/quic/quic_per_connection_packet_writer.h',
- 'tools/quic/quic_server_session.cc',
- 'tools/quic/quic_server_session.h',
+ 'tools/quic/quic_server_session_base.cc',
+ 'tools/quic/quic_server_session_base.h',
'tools/quic/quic_simple_client.cc',
'tools/quic/quic_simple_client.h',
'tools/quic/quic_simple_per_connection_packet_writer.cc',
@@ -834,16 +856,32 @@
'tools/quic/quic_simple_server.h',
'tools/quic/quic_simple_server_packet_writer.cc',
'tools/quic/quic_simple_server_packet_writer.h',
+ 'tools/quic/quic_simple_server_session.cc',
+ 'tools/quic/quic_simple_server_session.h',
'tools/quic/quic_spdy_client_stream.cc',
'tools/quic/quic_spdy_client_stream.h',
- 'tools/quic/quic_spdy_server_stream.cc',
- 'tools/quic/quic_spdy_server_stream.h',
+ 'tools/quic/quic_simple_server_stream.cc',
+ 'tools/quic/quic_simple_server_stream.h',
'tools/quic/quic_time_wait_list_manager.cc',
'tools/quic/quic_time_wait_list_manager.h',
'tools/quic/synchronous_host_resolver.cc',
'tools/quic/synchronous_host_resolver.h',
],
},
+ {
+ # GN version: //net:stale_while_revalidate_experiment_domains
+ 'target_name': 'stale_while_revalidate_experiment_domains',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ 'net',
+ 'net_derived_sources',
+ ],
+ 'sources': [
+ 'base/stale_while_revalidate_experiment_domains.cc',
+ 'base/stale_while_revalidate_experiment_domains.h',
+ ],
+ },
],
'conditions': [
['use_v8_in_net == 1', {
@@ -1199,7 +1237,6 @@
'tools/flip_server/flip_config.h',
'tools/flip_server/http_interface.cc',
'tools/flip_server/http_interface.h',
- 'tools/flip_server/loadtime_measurement.h',
'tools/flip_server/mem_cache.cc',
'tools/flip_server/mem_cache.h',
'tools/flip_server/output_ordering.cc',
@@ -1332,6 +1369,7 @@
},
'dependencies': [
'../url/url.gyp:url_lib_use_icu_alternatives_on_android',
+ 'net_features',
],
'defines': [
'USE_ICU_ALTERNATIVES_ON_ANDROID=1',
@@ -1339,6 +1377,7 @@
'DISABLE_FTP_SUPPORT=1',
],
'sources': [
+ 'filter/brotli_filter_disabled.cc',
'base/net_string_util_icu_alternatives_android.cc',
'base/net_string_util_icu_alternatives_android.h',
],
@@ -1351,7 +1390,6 @@
'android/java/src/org/chromium/net/AndroidCertVerifyResult.java',
'android/java/src/org/chromium/net/AndroidKeyStore.java',
'android/java/src/org/chromium/net/AndroidNetworkLibrary.java',
- 'android/java/src/org/chromium/net/AndroidPrivateKey.java',
'android/java/src/org/chromium/net/AndroidTrafficStats.java',
'android/java/src/org/chromium/net/GURLUtils.java',
'android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java',
@@ -1370,7 +1408,7 @@
'type': 'none',
'sources': [
'android/javatests/src/org/chromium/net/AndroidKeyStoreTestUtil.java',
- 'test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java',
+ 'test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java',
'test/android/javatests/src/org/chromium/net/test/DummySpnegoAuthenticator.java',
],
'variables': {
@@ -1389,24 +1427,21 @@
'cert_verify_status_android_java',
'certificate_mime_types_java',
'network_change_notifier_types_java',
+ 'network_change_notifier_android_types_java',
'net_errors_java',
'private_key_types_java',
- 'remote_android_keystore_aidl',
'traffic_stats_error_java',
],
'includes': [ '../build/java.gypi' ],
},
{
- # Processes the interface files for communication with an Android KeyStore
- # running in a separate process.
- 'target_name': 'remote_android_keystore_aidl',
+ 'target_name': 'embedded_test_server_aidl',
'type': 'none',
'variables': {
- 'aidl_interface_file': '../net/android/java/src/org/chromium/net/IRemoteAndroidKeyStoreInterface.aidl',
+ 'aidl_interface_file': '../net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerInterface.aidl',
},
'sources': [
- '../net/android/java/src/org/chromium/net/IRemoteAndroidKeyStore.aidl',
- '../net/android/java/src/org/chromium/net/IRemoteAndroidKeyStoreCallbacks.aidl',
+ '../net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl',
],
'includes': [ '../build/java_aidl.gypi' ],
},
@@ -1419,15 +1454,71 @@
'chromium_code': 0,
},
'dependencies': [
+ 'embedded_test_server_aidl',
'net_java',
- 'net_test_support',
'url_request_failed_job_java',
'../base/base.gyp:base_java',
+ '../base/base.gyp:base_java_test_support',
'../third_party/android_tools/android_tools.gyp:legacy_http_javalib',
],
'includes': [ '../build/java.gypi' ],
},
{
+ 'target_name': 'libnet_java_test_support',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'net_test_support',
+ '../base/base.gyp:base',
+ ],
+ 'sources': [
+ 'test/android/net_test_entry_point.cc',
+ 'test/android/net_test_jni_onload.cc',
+ 'test/android/net_test_jni_onload.h',
+ ],
+ },
+ {
+ 'target_name': 'net_test_support_apk',
+ 'type': 'none',
+ 'dependencies': [
+ 'net_java_test_support',
+ ],
+ 'variables': {
+ 'android_manifest_path': 'test/android/javatests/AndroidManifest.xml',
+ 'apk_name': 'ChromiumNetTestSupport',
+ 'is_test_apk': 1,
+ 'java_in_dir': 'test/android/javatests',
+ 'java_in_dir_suffix': '/src_dummy',
+ 'native_lib_target': 'libnet_java_test_support',
+ },
+ 'includes': [
+ '../build/java_apk.gypi',
+ ],
+ },
+ {
+ # Targets that need the net test support APK should depend on this
+ # target. It ensures that the APK is built without passing the
+ # classpath on to dependent targets.
+ 'target_name': 'require_net_test_support_apk',
+ 'type': 'none',
+ 'actions': [
+ {
+ 'action_name': 'require_ChromiumNetTestSupport',
+ 'variables': {
+ 'required_file': '<(PRODUCT_DIR)/net_test_support_apk/ChromiumNetTestSupport.apk.required',
+ },
+ 'inputs': [
+ '<(PRODUCT_DIR)/apks/ChromiumNetTestSupport.apk',
+ ],
+ 'outputs': [
+ '<(required_file)',
+ ],
+ 'action': [
+ 'python', '../build/android/gyp/touch.py', '<(required_file)',
+ ],
+ },
+ ],
+ },
+ {
'target_name': 'url_request_failed_job_java',
'type': 'none',
'variables': {
@@ -1445,6 +1536,7 @@
'../base/base.gyp:base',
'../base/base.gyp:base_java_test_support',
'net_java',
+ 'net_java_test_support',
],
'includes': [ '../build/java.gypi' ],
},
@@ -1485,6 +1577,14 @@
'includes': [ '../build/android/java_cpp_enum.gypi' ],
},
{
+ 'target_name': 'network_change_notifier_android_types_java',
+ 'type': 'none',
+ 'variables': {
+ 'source_file': 'android/network_change_notifier_android.cc',
+ },
+ 'includes': [ '../build/android/java_cpp_enum.gypi' ],
+ },
+ {
'target_name': 'private_key_types_java',
'type': 'none',
'variables': {
@@ -1514,15 +1614,19 @@
'dependencies': [
'../v8/tools/gyp/v8.gyp:v8_external_snapshot',
],
- 'copies': [
- {
- 'destination': '<(asset_location)',
- 'files': [
- '<(PRODUCT_DIR)/natives_blob.bin',
- '<(PRODUCT_DIR)/snapshot_blob.bin',
- ],
- },
- ],
+ 'variables': {
+ 'dest_path': '<(asset_location)',
+ 'renaming_sources': [
+ '<(PRODUCT_DIR)/natives_blob.bin',
+ '<(PRODUCT_DIR)/snapshot_blob.bin',
+ ],
+ 'renaming_destinations': [
+ 'natives_blob_<(arch_suffix).bin',
+ 'snapshot_blob_<(arch_suffix).bin',
+ ],
+ 'clear': 1,
+ },
+ 'includes': ['../build/android/copy_ex.gypi'],
}],
],
'variables': {
@@ -1534,13 +1638,16 @@
['v8_use_external_startup_data==1', {
'asset_location': '<(PRODUCT_DIR)/net_unittests_apk/assets',
'additional_input_paths': [
- '<(PRODUCT_DIR)/net_unittests_apk/assets/natives_blob.bin',
- '<(PRODUCT_DIR)/net_unittests_apk/assets/snapshot_blob.bin',
+ '<(PRODUCT_DIR)/net_unittests_apk/assets/natives_blob_<(arch_suffix).bin',
+ '<(PRODUCT_DIR)/net_unittests_apk/assets/snapshot_blob_<(arch_suffix).bin',
],
}],
],
},
- 'includes': [ '../build/apk_test.gypi' ],
+ 'includes': [
+ '../build/apk_test.gypi',
+ '../build/android/v8_external_startup_data_arch_suffix.gypi',
+ ],
},
{
'target_name': 'net_junit_tests',
@@ -1562,7 +1669,27 @@
'../build/host_jar.gypi',
],
},
-
+ ],
+ 'conditions': [
+ ['test_isolation_mode != "noop"',
+ {
+ 'targets': [
+ {
+ 'target_name': 'net_unittests_apk_run',
+ 'type': 'none',
+ 'dependencies': [
+ 'net_unittests_apk',
+ ],
+ 'includes': [
+ '../build/isolate.gypi',
+ ],
+ 'sources': [
+ 'net_unittests_apk.isolate',
+ ],
+ },
+ ]
+ }
+ ],
],
}],
['OS == "android" or OS == "linux"', {
diff --git a/chromium/net/net.gypi b/chromium/net/net.gypi
index 0ba77a87deb..6214b52ace8 100644
--- a/chromium/net/net.gypi
+++ b/chromium/net/net.gypi
@@ -11,6 +11,7 @@
# These files must not depend on files listed in sources list in the net
# target.
'net_nacl_common_sources' : [
+ 'base/address_family.cc',
'base/address_family.h',
'base/address_list.cc',
'base/address_list.h',
@@ -19,8 +20,6 @@
'base/completion_callback.h',
'base/connection_type_histograms.cc',
'base/connection_type_histograms.h',
- 'base/dns_util.cc',
- 'base/dns_util.h',
'base/escape.cc',
'base/escape.h',
'base/hash_value.cc',
@@ -29,12 +28,17 @@
'base/host_port_pair.h',
'base/io_buffer.cc',
'base/io_buffer.h',
+ 'base/ip_address.cc',
+ 'base/ip_address.h',
'base/ip_address_number.cc',
'base/ip_address_number.h',
'base/ip_endpoint.cc',
'base/ip_endpoint.h',
'base/load_timing_info.cc',
'base/load_timing_info.h',
+ 'base/lookup_string_in_fixed_set.cc',
+ 'base/lookup_string_in_fixed_set.h',
+ 'base/net_error_details.h',
'base/net_error_list.h',
'base/net_errors.cc',
'base/net_errors.h',
@@ -56,7 +60,14 @@
'base/rand_callback.h',
'base/registry_controlled_domains/registry_controlled_domain.cc',
'base/registry_controlled_domains/registry_controlled_domain.h',
+ 'base/sockaddr_storage.cc',
+ 'base/sockaddr_storage.h',
+ 'base/socket_performance_watcher.cc',
+ 'base/socket_performance_watcher.h',
+ 'base/socket_performance_watcher_factory.h',
'base/sys_addrinfo.h',
+ 'base/url_util.cc',
+ 'base/url_util.h',
'base/zap.cc',
'base/zap.h',
'cert/asn1_util.cc',
@@ -64,8 +75,6 @@
'cert/cert_database.cc',
'cert/cert_database.h',
'cert/cert_database_openssl.cc',
- 'cert/cert_policy_enforcer.cc',
- 'cert/cert_policy_enforcer.h',
'cert/cert_status_flags.cc',
'cert/cert_status_flags.h',
'cert/cert_verifier.cc',
@@ -74,17 +83,28 @@
'cert/cert_verify_result.h',
'cert/crl_set.cc',
'cert/crl_set.h',
+ 'cert/ct_known_logs.cc',
+ 'cert/ct_known_logs.h',
+ 'cert/ct_known_logs_static.h',
+ 'cert/ct_policy_enforcer.cc',
+ 'cert/ct_policy_enforcer.h',
'cert/ct_verifier.h',
'cert/ct_verify_result.cc',
'cert/ct_verify_result.h',
+ 'cert/internal/certificate_policies.cc',
+ 'cert/internal/certificate_policies.h',
'cert/internal/extended_key_usage.cc',
'cert/internal/extended_key_usage.h',
+ 'cert/internal/name_constraints.cc',
+ 'cert/internal/name_constraints.h',
'cert/internal/parse_certificate.cc',
'cert/internal/parse_certificate.h',
'cert/internal/signature_algorithm.cc',
'cert/internal/signature_algorithm.h',
'cert/internal/signature_policy.cc',
'cert/internal/signature_policy.h',
+ 'cert/internal/verify_certificate_chain.cc',
+ 'cert/internal/verify_certificate_chain.h',
'cert/internal/verify_name_match.cc',
'cert/internal/verify_name_match.h',
'cert/internal/verify_signed_data.cc',
@@ -115,8 +135,12 @@
'der/parser.h',
'der/tag.cc',
'der/tag.h',
+ 'dns/dns_util.cc',
+ 'dns/dns_util.h',
'http/http_auth_challenge_tokenizer.cc',
'http/http_auth_challenge_tokenizer.h',
+ 'http/http_auth_scheme.cc',
+ 'http/http_auth_scheme.h',
'http/http_byte_range.cc',
'http/http_byte_range.h',
'http/http_log_util.cc',
@@ -186,6 +210,8 @@
'ssl/ssl_info.cc',
'ssl/ssl_info.h',
'ssl/ssl_private_key.h',
+ 'ssl/ssl_server_config.cc',
+ 'ssl/ssl_server_config.h',
# Most files in net/quic are in net_nacl_common_sources, except for the
# files that have dependency on SPDY (net/spdy) or NSS.
@@ -193,6 +219,8 @@
'quic/congestion_control/cubic.h',
'quic/congestion_control/cubic_bytes.cc',
'quic/congestion_control/cubic_bytes.h',
+ 'quic/congestion_control/general_loss_algorithm.cc',
+ 'quic/congestion_control/general_loss_algorithm.h',
'quic/congestion_control/hybrid_slow_start.cc',
'quic/congestion_control/hybrid_slow_start.h',
'quic/congestion_control/loss_detection_interface.cc',
@@ -225,6 +253,10 @@
'quic/crypto/chacha20_poly1305_decrypter_openssl.cc',
'quic/crypto/chacha20_poly1305_encrypter.h',
'quic/crypto/chacha20_poly1305_encrypter_openssl.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_decrypter.h',
+ 'quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_encrypter.h',
+ 'quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc',
'quic/crypto/channel_id.cc',
'quic/crypto/channel_id.h',
'quic/crypto/channel_id_chromium.cc',
@@ -261,6 +293,8 @@
'quic/crypto/proof_verifier.h',
'quic/crypto/proof_verifier_chromium.cc',
'quic/crypto/proof_verifier_chromium.h',
+ 'quic/crypto/properties_based_quic_server_info.cc',
+ 'quic/crypto/properties_based_quic_server_info.h',
'quic/crypto/quic_decrypter.cc',
'quic/crypto/quic_decrypter.h',
'quic/crypto/quic_encrypter.cc',
@@ -288,16 +322,14 @@
'quic/p2p/quic_p2p_stream.h',
'quic/port_suggester.cc',
'quic/port_suggester.h',
- 'quic/quic_ack_notifier.cc',
- 'quic/quic_ack_notifier.h',
- 'quic/quic_ack_notifier_manager.cc',
- 'quic/quic_ack_notifier_manager.h',
+ 'quic/quic_ack_listener_interface.h',
'quic/quic_address_mismatch.cc',
'quic/quic_address_mismatch.h',
'quic/quic_alarm.cc',
'quic/quic_alarm.h',
'quic/quic_bandwidth.cc',
'quic/quic_bandwidth.h',
+ 'quic/quic_bug_tracker.h',
'quic/quic_blocked_writer_interface.h',
'quic/quic_clock.cc',
'quic/quic_clock.h',
@@ -305,14 +337,14 @@
'quic/quic_config.h',
'quic/quic_connection.cc',
'quic/quic_connection.h',
- 'quic/quic_connection_helper.cc',
- 'quic/quic_connection_helper.h',
'quic/quic_connection_logger.cc',
'quic/quic_connection_logger.h',
'quic/quic_connection_stats.cc',
'quic/quic_connection_stats.h',
'quic/quic_crypto_stream.cc',
'quic/quic_crypto_stream.h',
+ 'quic/quic_chromium_connection_helper.cc',
+ 'quic/quic_chromium_connection_helper.h',
'quic/quic_data_reader.cc',
'quic/quic_data_reader.h',
'quic/quic_data_writer.cc',
@@ -321,12 +353,20 @@
'quic/quic_default_packet_writer.h',
'quic/quic_fec_group.cc',
'quic/quic_fec_group.h',
+ 'quic/quic_fec_group_interface.cc',
+ 'quic/quic_fec_group_interface.h',
'quic/quic_flags.cc',
'quic/quic_flags.h',
'quic/quic_flow_controller.cc',
'quic/quic_flow_controller.h',
+ 'quic/quic_frame_list.cc',
+ 'quic/quic_frame_list.h',
'quic/quic_framer.cc',
'quic/quic_framer.h',
+ 'quic/quic_multipath_received_packet_manager.cc',
+ 'quic/quic_multipath_received_packet_manager.h',
+ 'quic/quic_multipath_transmissions_map.cc',
+ 'quic/quic_multipath_transmissions_map.h',
'quic/quic_packet_creator.cc',
'quic/quic_packet_creator.h',
'quic/quic_packet_generator.cc',
@@ -346,10 +386,13 @@
'quic/quic_server_id.h',
'quic/quic_session.cc',
'quic/quic_session.h',
+ 'quic/quic_simple_buffer_allocator.cc',
+ 'quic/quic_simple_buffer_allocator.h',
'quic/quic_socket_address_coder.cc',
'quic/quic_socket_address_coder.h',
'quic/quic_stream_sequencer.cc',
'quic/quic_stream_sequencer.h',
+ 'quic/quic_stream_sequencer_buffer_interface.h',
'quic/quic_sustained_bandwidth_recorder.cc',
'quic/quic_sustained_bandwidth_recorder.h',
'quic/quic_time.cc',
@@ -365,10 +408,10 @@
'quic/quic_write_blocked_list.h',
'quic/reliable_quic_stream.cc',
'quic/reliable_quic_stream.h',
+ 'quic/stream_sequencer_buffer.cc',
+ 'quic/stream_sequencer_buffer.h',
],
'net_non_nacl_sources': [
- 'android/android_private_key.cc',
- 'android/android_private_key.h',
'android/cert_verify_result_android.cc',
'android/cert_verify_result_android.h',
'android/gurl_utils.cc',
@@ -406,8 +449,6 @@
'base/crypto_module_openssl.cc',
'base/data_url.cc',
'base/data_url.h',
- 'base/dns_reloader.cc',
- 'base/dns_reloader.h',
'base/elements_upload_data_stream.cc',
'base/elements_upload_data_stream.h',
'base/expiring_cache.h',
@@ -495,8 +536,6 @@
'base/sdch_observer.h',
'base/sdch_problem_code_list.h',
'base/sdch_problem_codes.h',
- 'base/socket_performance_watcher.h',
- 'base/socket_performance_watcher_factory.h',
'base/static_cookie_policy.cc',
'base/static_cookie_policy.h',
'base/test_data_stream.cc',
@@ -510,8 +549,6 @@
'base/upload_file_element_reader.cc',
'base/upload_file_element_reader.h',
'base/upload_progress.h',
- 'base/url_util.cc',
- 'base/url_util.h',
'base/winsock_init.cc',
'base/winsock_init.h',
'base/winsock_util.cc',
@@ -540,15 +577,14 @@
'cert/crl_set_storage.cc',
'cert/crl_set_storage.h',
'cert/ct_ev_whitelist.h',
- 'cert/ct_known_logs.cc',
- 'cert/ct_known_logs.h',
- 'cert/ct_known_logs_static.h',
'cert/ct_log_response_parser.cc',
'cert/ct_log_response_parser.h',
'cert/ct_log_verifier.cc',
'cert/ct_log_verifier.h',
'cert/ct_log_verifier_nss.cc',
'cert/ct_log_verifier_openssl.cc',
+ 'cert/ct_log_verifier_util.cc',
+ 'cert/ct_log_verifier_util.h',
'cert/ct_objects_extractor.h',
'cert/ct_objects_extractor_nss.cc',
'cert/ct_objects_extractor_openssl.cc',
@@ -561,6 +597,8 @@
'cert/jwk_serializer.h',
'cert/jwk_serializer_nss.cc',
'cert/jwk_serializer_openssl.cc',
+ 'cert/merkle_consistency_proof.cc',
+ 'cert/merkle_consistency_proof.h',
'cert/multi_log_ct_verifier.cc',
'cert/multi_log_ct_verifier.h',
'cert/multi_threaded_cert_verifier.cc',
@@ -742,6 +780,8 @@
'dns/dns_protocol.h',
'dns/dns_query.cc',
'dns/dns_query.h',
+ 'dns/dns_reloader.cc',
+ 'dns/dns_reloader.h',
'dns/dns_response.cc',
'dns/dns_response.h',
'dns/dns_session.cc',
@@ -819,6 +859,8 @@
'http/http_auth_handler_ntlm_win.cc',
'http/http_auth_multi_round_parse.cc',
'http/http_auth_multi_round_parse.h',
+ 'http/http_auth_preferences.cc',
+ 'http/http_auth_preferences.h',
'http/http_auth_sspi_win.cc',
'http/http_auth_sspi_win.h',
'http/http_basic_state.cc',
@@ -845,6 +887,8 @@
'http/http_proxy_client_socket.h',
'http/http_proxy_client_socket_pool.cc',
'http/http_proxy_client_socket_pool.h',
+ 'http/http_proxy_client_socket_wrapper.cc',
+ 'http/http_proxy_client_socket_wrapper.h',
'http/http_request_info.cc',
'http/http_request_info.h',
'http/http_response_body_drainer.cc',
@@ -951,45 +995,48 @@
'quic/crypto/aead_base_encrypter_nss.cc',
'quic/crypto/aes_128_gcm_12_decrypter_nss.cc',
'quic/crypto/aes_128_gcm_12_encrypter_nss.cc',
+ 'quic/crypto/cert_compressor.cc',
+ 'quic/crypto/cert_compressor.h',
'quic/crypto/chacha20_poly1305_decrypter_nss.cc',
'quic/crypto/chacha20_poly1305_encrypter_nss.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_encrypter_nss.cc',
'quic/crypto/channel_id_nss.cc',
'quic/crypto/p256_key_exchange_nss.cc',
'quic/crypto/proof_source_chromium.h',
'quic/crypto/proof_source_chromium_nss.cc',
'quic/crypto/proof_source_chromium_openssl.cc',
- 'quic/quic_chromium_client_session.cc',
- 'quic/quic_chromium_client_session.h',
- 'quic/quic_client_session_base.cc',
- 'quic/quic_client_session_base.h',
- 'quic/quic_headers_stream.cc',
- 'quic/quic_headers_stream.h',
- 'quic/quic_http_stream.cc',
- 'quic/quic_http_stream.h',
- 'quic/quic_http_utils.cc',
- 'quic/quic_http_utils.h',
- 'quic/quic_stream_factory.cc',
- 'quic/quic_stream_factory.h',
- 'quic/spdy_utils.cc',
- 'quic/crypto/cert_compressor.cc',
- 'quic/crypto/cert_compressor.h',
'quic/crypto/quic_crypto_client_config.cc',
'quic/crypto/quic_crypto_client_config.h',
'quic/crypto/quic_crypto_server_config.cc',
'quic/crypto/quic_crypto_server_config.h',
'quic/network_connection.cc',
'quic/network_connection.h',
+ 'quic/quic_chromium_client_session.cc',
+ 'quic/quic_chromium_client_session.h',
+ 'quic/quic_chromium_client_stream.cc',
+ 'quic/quic_chromium_client_stream.h',
+ 'quic/quic_client_session_base.cc',
+ 'quic/quic_client_session_base.h',
'quic/quic_crypto_client_stream.cc',
'quic/quic_crypto_client_stream.h',
+ 'quic/quic_crypto_client_stream_factory.cc',
'quic/quic_crypto_client_stream_factory.h',
'quic/quic_crypto_server_stream.cc',
'quic/quic_crypto_server_stream.h',
- 'quic/quic_data_stream.cc',
- 'quic/quic_data_stream.h',
- 'quic/quic_reliable_client_stream.cc',
- 'quic/quic_reliable_client_stream.h',
+ 'quic/quic_headers_stream.cc',
+ 'quic/quic_headers_stream.h',
+ 'quic/quic_http_stream.cc',
+ 'quic/quic_http_stream.h',
+ 'quic/quic_http_utils.cc',
+ 'quic/quic_http_utils.h',
'quic/quic_spdy_session.cc',
'quic/quic_spdy_session.h',
+ 'quic/quic_spdy_stream.cc',
+ 'quic/quic_spdy_stream.h',
+ 'quic/quic_stream_factory.cc',
+ 'quic/quic_stream_factory.h',
+ 'quic/spdy_utils.cc',
'quic/spdy_utils.h',
'sdch/sdch_owner.cc',
'sdch/sdch_owner.h',
@@ -1065,6 +1112,8 @@
'spdy/hpack/hpack_entry.h',
'spdy/hpack/hpack_header_table.cc',
'spdy/hpack/hpack_header_table.h',
+ 'spdy/hpack/hpack_huffman_decoder.cc',
+ 'spdy/hpack/hpack_huffman_decoder.h',
'spdy/hpack/hpack_huffman_table.cc',
'spdy/hpack/hpack_huffman_table.h',
'spdy/hpack/hpack_input_stream.cc',
@@ -1073,6 +1122,7 @@
'spdy/hpack/hpack_output_stream.h',
'spdy/hpack/hpack_static_table.cc',
'spdy/hpack/hpack_static_table.h',
+ 'spdy/priority_write_scheduler.h',
'spdy/spdy_alt_svc_wire_format.cc',
'spdy/spdy_alt_svc_wire_format.h',
'spdy/spdy_bitmasks.h',
@@ -1126,10 +1176,14 @@
'ssl/client_cert_store_win.h',
'ssl/ssl_config_service_defaults.cc',
'ssl/ssl_config_service_defaults.h',
+ 'ssl/ssl_key_logger.cc',
+ 'ssl/ssl_key_logger.h',
'ssl/ssl_platform_key.h',
'ssl/ssl_platform_key_android.cc',
'ssl/ssl_platform_key_mac.cc',
'ssl/ssl_platform_key_nss.cc',
+ 'ssl/ssl_platform_key_task_runner.cc',
+ 'ssl/ssl_platform_key_task_runner.h',
'ssl/ssl_platform_key_win.cc',
'ssl/threaded_ssl_private_key.cc',
'ssl/threaded_ssl_private_key.h',
@@ -1142,6 +1196,7 @@
'udp/datagram_client_socket.h',
'udp/datagram_server_socket.h',
'udp/datagram_socket.h',
+ 'udp/diff_serv_code_point.h',
'udp/udp_client_socket.cc',
'udp/udp_client_socket.h',
'udp/udp_net_log_parameters.cc',
@@ -1244,6 +1299,7 @@
'android/keystore_unittest.cc',
'android/network_change_notifier_android_unittest.cc',
'android/traffic_stats_unittest.cc',
+ 'base/address_family_unittest.cc',
'base/address_list_unittest.cc',
'base/address_tracker_linux_unittest.cc',
'base/backoff_entry_serializer_unittest.cc',
@@ -1251,7 +1307,7 @@
'base/chunked_upload_data_stream_unittest.cc',
'base/data_url_unittest.cc',
'base/directory_lister_unittest.cc',
- 'base/dns_util_unittest.cc',
+ 'base/directory_listing_unittest.cc',
'base/elements_upload_data_stream_unittest.cc',
'base/escape_unittest.cc',
'base/expiring_cache_unittest.cc',
@@ -1261,13 +1317,14 @@
'base/host_port_pair_unittest.cc',
'base/int128_unittest.cc',
'base/ip_address_number_unittest.cc',
+ 'base/ip_address_unittest.cc',
'base/ip_endpoint_unittest.cc',
'base/ip_pattern_unittest.cc',
'base/keygen_handler_unittest.cc',
'base/layered_network_delegate_unittest.cc',
+ 'base/lookup_string_in_fixed_set_unittest.cc',
'base/mime_sniffer_unittest.cc',
'base/mime_util_unittest.cc',
- 'base/net_util_icu_unittest.cc',
'base/net_util_unittest.cc',
'base/network_activity_monitor_unittest.cc',
'base/network_change_notifier_unittest.cc',
@@ -1280,12 +1337,13 @@
'base/registry_controlled_domains/registry_controlled_domain_unittest.cc',
'base/sdch_dictionary_unittest.cc',
'base/sdch_manager_unittest.cc',
+ 'base/stale_while_revalidate_experiment_domains_unittest.cc',
'base/static_cookie_policy_unittest.cc',
'base/test_completion_callback_unittest.cc',
'base/upload_bytes_element_reader_unittest.cc',
'base/upload_file_element_reader_unittest.cc',
'base/url_util_unittest.cc',
- 'cert/cert_policy_enforcer_unittest.cc',
+ 'cert/ct_policy_enforcer_unittest.cc',
'cert/cert_verify_proc_unittest.cc',
'cert/cert_verify_proc_whitelist_unittest.cc',
'cert/crl_set_unittest.cc',
@@ -1294,11 +1352,14 @@
'cert/ct_objects_extractor_unittest.cc',
'cert/ct_serialization_unittest.cc',
'cert/ev_root_ca_metadata_unittest.cc',
+ 'cert/internal/certificate_policies_unittest.cc',
'cert/internal/extended_key_usage_unittest.cc',
+ 'cert/internal/name_constraints_unittest.cc',
'cert/internal/parse_certificate_unittest.cc',
'cert/internal/signature_algorithm_unittest.cc',
'cert/internal/test_helpers.cc',
'cert/internal/test_helpers.h',
+ 'cert/internal/verify_certificate_chain_unittest.cc',
'cert/internal/verify_name_match_unittest.cc',
'cert/internal/verify_signed_data_unittest.cc',
'cert/jwk_serializer_unittest.cc',
@@ -1313,14 +1374,12 @@
'cert/test_root_certs_unittest.cc',
'cert/x509_cert_types_unittest.cc',
'cert/x509_certificate_unittest.cc',
- 'cert/x509_util_openssl_unittest.cc',
'cert/x509_util_unittest.cc',
'cert_net/cert_net_fetcher_impl_unittest.cc',
'cert_net/nss_ocsp_unittest.cc',
'cookies/canonical_cookie_unittest.cc',
'cookies/cookie_constants_unittest.cc',
'cookies/cookie_monster_unittest.cc',
- 'cookies/cookie_store_unittest.h',
'cookies/cookie_util_unittest.cc',
'cookies/parsed_cookie_unittest.cc',
'der/input_unittest.cc',
@@ -1353,6 +1412,7 @@
'dns/dns_response_unittest.cc',
'dns/dns_session_unittest.cc',
'dns/dns_transaction_unittest.cc',
+ 'dns/dns_util_unittest.cc',
'dns/host_cache_unittest.cc',
'dns/host_resolver_impl_unittest.cc',
'dns/host_resolver_mojo_unittest.cc',
@@ -1366,6 +1426,7 @@
'dns/single_request_host_resolver_unittest.cc',
'extras/sqlite/sqlite_channel_id_store_unittest.cc',
'extras/sqlite/sqlite_persistent_cookie_store_unittest.cc',
+ 'filter/brotli_filter_unittest.cc',
'filter/filter_unittest.cc',
'filter/gzip_filter_unittest.cc',
'filter/mock_filter_context.cc',
@@ -1380,6 +1441,7 @@
'ftp/ftp_directory_listing_parser_windows_unittest.cc',
'ftp/ftp_network_transaction_unittest.cc',
'ftp/ftp_util_unittest.cc',
+ 'http/bidirectional_stream_unittest.cc',
'http/des_unittest.cc',
'http/disk_based_cert_cache_unittest.cc',
'http/disk_cache_based_quic_server_info_unittest.cc',
@@ -1396,6 +1458,7 @@
'http/http_auth_handler_negotiate_unittest.cc',
'http/http_auth_handler_unittest.cc',
'http/http_auth_multi_round_parse_unittest.cc',
+ 'http/http_auth_preferences_unittest.cc',
'http/http_auth_sspi_win_unittest.cc',
'http/http_auth_unittest.cc',
'http/http_basic_state_unittest.cc',
@@ -1422,8 +1485,8 @@
'http/http_stream_parser_unittest.cc',
'http/http_util_unittest.cc',
'http/http_vary_data_unittest.cc',
- 'http/mock_allow_url_security_manager.cc',
- 'http/mock_allow_url_security_manager.h',
+ 'http/mock_allow_http_auth_preferences.cc',
+ 'http/mock_allow_http_auth_preferences.h',
'http/mock_gssapi_library_posix.cc',
'http/mock_gssapi_library_posix.h',
'http/mock_http_cache.cc',
@@ -1464,6 +1527,7 @@
'proxy/proxy_service_unittest.cc',
'quic/congestion_control/cubic_bytes_test.cc',
'quic/congestion_control/cubic_test.cc',
+ 'quic/congestion_control/general_loss_algorithm_test.cc',
'quic/congestion_control/hybrid_slow_start_test.cc',
'quic/congestion_control/pacing_sender_test.cc',
'quic/congestion_control/prr_sender_test.cc',
@@ -1479,9 +1543,12 @@
'quic/crypto/cert_compressor_test.cc',
'quic/crypto/chacha20_poly1305_decrypter_test.cc',
'quic/crypto/chacha20_poly1305_encrypter_test.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc',
'quic/crypto/channel_id_test.cc',
'quic/crypto/common_cert_set_test.cc',
'quic/crypto/crypto_framer_test.cc',
+ 'quic/crypto/crypto_handshake_message_test.cc',
'quic/crypto/crypto_secret_boxer_test.cc',
'quic/crypto/crypto_server_test.cc',
'quic/crypto/crypto_utils_test.cc',
@@ -1492,31 +1559,30 @@
'quic/crypto/p256_key_exchange_test.cc',
'quic/crypto/proof_test.cc',
'quic/crypto/proof_verifier_chromium_test.cc',
+ 'quic/crypto/properties_based_quic_server_info_test.cc',
'quic/crypto/quic_crypto_client_config_test.cc',
'quic/crypto/quic_crypto_server_config_test.cc',
'quic/crypto/quic_random_test.cc',
'quic/crypto/strike_register_test.cc',
- 'quic/interval_test.cc',
'quic/interval_set_test.cc',
+ 'quic/interval_test.cc',
'quic/iovector_test.cc',
'quic/network_connection_unittest.cc',
'quic/p2p/quic_p2p_session_test.cc',
'quic/port_suggester_unittest.cc',
- 'quic/quic_ack_notifier_manager_test.cc',
- 'quic/quic_ack_notifier_test.cc',
'quic/quic_address_mismatch_test.cc',
'quic/quic_alarm_test.cc',
'quic/quic_bandwidth_test.cc',
'quic/quic_chromium_client_session_test.cc',
+ 'quic/quic_chromium_client_stream_test.cc',
+ 'quic/quic_chromium_connection_helper_test.cc',
'quic/quic_clock_test.cc',
'quic/quic_config_test.cc',
- 'quic/quic_connection_helper_test.cc',
'quic/quic_connection_logger_unittest.cc',
'quic/quic_connection_test.cc',
'quic/quic_crypto_client_stream_test.cc',
'quic/quic_crypto_server_stream_test.cc',
'quic/quic_crypto_stream_test.cc',
- 'quic/quic_data_stream_test.cc',
'quic/quic_data_writer_test.cc',
'quic/quic_fec_group_test.cc',
'quic/quic_flow_controller_test.cc',
@@ -1524,17 +1590,20 @@
'quic/quic_headers_stream_test.cc',
'quic/quic_http_stream_test.cc',
'quic/quic_http_utils_test.cc',
+ 'quic/quic_multipath_received_packet_manager_test.cc',
+ 'quic/quic_multipath_transmissions_map_test.cc',
'quic/quic_network_transaction_unittest.cc',
'quic/quic_packet_creator_test.cc',
'quic/quic_packet_generator_test.cc',
'quic/quic_protocol_test.cc',
'quic/quic_received_packet_manager_test.cc',
- 'quic/quic_reliable_client_stream_test.cc',
'quic/quic_sent_entropy_manager_test.cc',
'quic/quic_sent_packet_manager_test.cc',
'quic/quic_server_id_test.cc',
'quic/quic_session_test.cc',
+ 'quic/quic_simple_buffer_allocator_test.cc',
'quic/quic_socket_address_coder_test.cc',
+ 'quic/quic_spdy_stream_test.cc',
'quic/quic_stream_factory_test.cc',
'quic/quic_stream_sequencer_test.cc',
'quic/quic_sustained_bandwidth_recorder_test.cc',
@@ -1544,6 +1613,8 @@
'quic/quic_utils_test.cc',
'quic/quic_write_blocked_list_test.cc',
'quic/reliable_quic_stream_test.cc',
+ 'quic/spdy_utils_test.cc',
+ 'quic/stream_sequencer_buffer_test.cc',
'quic/test_tools/crypto_test_utils.cc',
'quic/test_tools/crypto_test_utils.h',
'quic/test_tools/crypto_test_utils_chromium.cc',
@@ -1561,16 +1632,12 @@
'quic/test_tools/mock_quic_dispatcher.h',
'quic/test_tools/mock_random.cc',
'quic/test_tools/mock_random.h',
- 'quic/test_tools/quic_ack_notifier_manager_peer.cc',
- 'quic/test_tools/quic_ack_notifier_manager_peer.h',
'quic/test_tools/quic_chromium_client_session_peer.cc',
'quic/test_tools/quic_chromium_client_session_peer.h',
'quic/test_tools/quic_config_peer.cc',
'quic/test_tools/quic_config_peer.h',
'quic/test_tools/quic_connection_peer.cc',
'quic/test_tools/quic_connection_peer.h',
- 'quic/test_tools/quic_data_stream_peer.cc',
- 'quic/test_tools/quic_data_stream_peer.h',
'quic/test_tools/quic_flow_controller_peer.cc',
'quic/test_tools/quic_flow_controller_peer.h',
'quic/test_tools/quic_framer_peer.cc',
@@ -1587,6 +1654,10 @@
'quic/test_tools/quic_session_peer.h',
'quic/test_tools/quic_spdy_session_peer.cc',
'quic/test_tools/quic_spdy_session_peer.h',
+ 'quic/test_tools/quic_spdy_stream_peer.cc',
+ 'quic/test_tools/quic_spdy_stream_peer.h',
+ 'quic/test_tools/quic_stream_factory_peer.cc',
+ 'quic/test_tools/quic_stream_factory_peer.h',
'quic/test_tools/quic_stream_sequencer_peer.cc',
'quic/test_tools/quic_stream_sequencer_peer.h',
'quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc',
@@ -1609,7 +1680,6 @@
'server/http_server_unittest.cc',
'server/web_socket_encoder_unittest.cc',
'socket/client_socket_pool_base_unittest.cc',
- 'socket/deterministic_socket_data_unittest.cc',
'socket/mock_client_socket_pool_manager.cc',
'socket/mock_client_socket_pool_manager.h',
'socket/sequenced_socket_data_unittest.cc',
@@ -1637,6 +1707,7 @@
'spdy/hpack/hpack_encoder_test.cc',
'spdy/hpack/hpack_entry_test.cc',
'spdy/hpack/hpack_header_table_test.cc',
+ 'spdy/hpack/hpack_huffman_decoder_test.cc',
'spdy/hpack/hpack_huffman_table_test.cc',
'spdy/hpack/hpack_input_stream_test.cc',
'spdy/hpack/hpack_output_stream_test.cc',
@@ -1644,6 +1715,7 @@
'spdy/hpack/hpack_static_table_test.cc',
'spdy/mock_spdy_framer_visitor.cc',
'spdy/mock_spdy_framer_visitor.h',
+ 'spdy/priority_write_scheduler_test.cc',
'spdy/spdy_alt_svc_wire_format_test.cc',
'spdy/spdy_buffer_unittest.cc',
'spdy/spdy_frame_builder_test.cc',
@@ -1689,17 +1761,16 @@
'test/embedded_test_server/embedded_test_server_unittest.cc',
'test/embedded_test_server/http_request_unittest.cc',
'test/embedded_test_server/http_response_unittest.cc',
- 'test/embedded_test_server/tcp_listen_socket_unittest.cc',
- 'test/embedded_test_server/tcp_listen_socket_unittest.h',
'test/gtest_util.h',
'test/python_utils_unittest.cc',
'test/run_all_unittests.cc',
'test/scoped_disable_exit_on_dfatal.cc',
'test/scoped_disable_exit_on_dfatal.h',
- 'test/test_certificate_data.h',
'tools/balsa/balsa_frame_test.cc',
'tools/balsa/balsa_headers_test.cc',
'tools/quic/quic_simple_client_test.cc',
+ 'tools/quic/test_tools/mock_quic_server_session_visitor.cc',
+ 'tools/quic/test_tools/mock_quic_server_session_visitor.h',
'tools/tld_cleanup/tld_cleanup_util_unittest.cc',
'udp/udp_socket_unittest.cc',
'url_request/certificate_report_sender_unittest.cc',
@@ -1753,11 +1824,11 @@
'tools/quic/quic_epoll_clock_test.cc',
'tools/quic/quic_epoll_connection_helper_test.cc',
'tools/quic/quic_in_memory_cache_test.cc',
- 'tools/quic/quic_server_session_test.cc',
+ 'tools/quic/quic_server_session_base_test.cc',
'tools/quic/quic_server_test.cc',
+ 'tools/quic/quic_simple_server_session_test.cc',
'tools/quic/quic_simple_server_test.cc',
'tools/quic/quic_spdy_client_stream_test.cc',
- 'tools/quic/quic_spdy_server_stream_test.cc',
'tools/quic/quic_time_wait_list_manager_test.cc',
'tools/quic/spdy_balsa_utils_test.cc',
'tools/quic/test_tools/http_message.cc',
@@ -1766,8 +1837,6 @@
'tools/quic/test_tools/limited_mtu_test_writer.h',
'tools/quic/test_tools/mock_epoll_server.cc',
'tools/quic/test_tools/mock_epoll_server.h',
- 'tools/quic/test_tools/mock_quic_server_session_visitor.cc',
- 'tools/quic/test_tools/mock_quic_server_session_visitor.h',
'tools/quic/test_tools/mock_quic_time_wait_list_manager.cc',
'tools/quic/test_tools/mock_quic_time_wait_list_manager.h',
'tools/quic/test_tools/packet_dropping_test_writer.cc',
@@ -1782,6 +1851,8 @@
'tools/quic/test_tools/quic_server_peer.h',
'tools/quic/test_tools/quic_test_client.cc',
'tools/quic/test_tools/quic_test_client.h',
+ 'tools/quic/test_tools/quic_test_server.cc',
+ 'tools/quic/test_tools/quic_test_server.h',
'tools/quic/test_tools/server_thread.cc',
'tools/quic/test_tools/server_thread.h',
'tools/quic/test_tools/simple_client.cc',
@@ -1797,6 +1868,8 @@
'net_file_support_sources': [
"base/directory_lister.cc",
"base/directory_lister.h",
+ "base/directory_listing.cc",
+ "base/directory_listing.h",
"url_request/file_protocol_handler.cc",
"url_request/file_protocol_handler.h",
"url_request/url_request_file_dir_job.cc",
@@ -1837,6 +1910,16 @@
"url_request/url_request_ftp_job.cc",
"url_request/url_request_ftp_job.h",
],
+ 'net_bidirectional_stream_sources': [
+ 'http/bidirectional_stream.cc',
+ 'http/bidirectional_stream.h',
+ 'http/bidirectional_stream_job.cc',
+ 'http/bidirectional_stream_job.h',
+ 'http/bidirectional_stream_request_info.cc',
+ 'http/bidirectional_stream_request_info.h',
+ 'spdy/bidirectional_stream_spdy_job.cc',
+ 'spdy/bidirectional_stream_spdy_job.h',
+ ],
'net_websockets_sources': [
"websockets/websocket_basic_handshake_stream.cc",
"websockets/websocket_basic_handshake_stream.h",
@@ -1887,6 +1970,7 @@
'docs/bug-triage-labels.md',
'docs/bug-triage-suggested-workflow.md',
'docs/code-patterns.md',
+ 'docs/crash-course-in-net-internals.md',
'docs/life-of-a-url-request.md',
'sdch/README.md',
],
diff --git a/chromium/net/net_common.gypi b/chromium/net/net_common.gypi
index bb38097517c..a6da6a899e4 100644
--- a/chromium/net/net_common.gypi
+++ b/chromium/net/net_common.gypi
@@ -15,6 +15,7 @@
'../third_party/protobuf/protobuf.gyp:protobuf_lite',
'../third_party/zlib/zlib.gyp:zlib',
'net_derived_sources',
+ 'net_features',
'net_quic_proto',
'net_resources',
],
@@ -95,6 +96,9 @@
['disable_ftp_support!=1', {
'sources': ['<@(net_ftp_support_sources)']
}],
+ ['enable_bidirectional_stream==1', {
+ 'sources': ['<@(net_bidirectional_stream_sources)']
+ }],
['enable_built_in_dns==1', {
'defines': [
'ENABLE_BUILT_IN_DNS',
@@ -121,6 +125,8 @@
'quic/crypto/aes_128_gcm_12_encrypter_nss.cc',
'quic/crypto/chacha20_poly1305_decrypter_nss.cc',
'quic/crypto/chacha20_poly1305_encrypter_nss.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_encrypter_nss.cc',
'quic/crypto/channel_id_nss.cc',
'quic/crypto/p256_key_exchange_nss.cc',
'quic/crypto/proof_source_chromium_nss.cc',
@@ -148,6 +154,8 @@
'quic/crypto/aes_128_gcm_12_encrypter_openssl.cc',
'quic/crypto/chacha20_poly1305_decrypter_openssl.cc',
'quic/crypto/chacha20_poly1305_encrypter_openssl.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc',
+ 'quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc',
'quic/crypto/channel_id_openssl.cc',
'quic/crypto/p256_key_exchange_openssl.cc',
'quic/crypto/proof_source_chromium_openssl.cc',
@@ -163,8 +171,12 @@
'ssl/openssl_ssl_util.h',
'ssl/ssl_client_session_cache_openssl.cc',
'ssl/ssl_client_session_cache_openssl.h',
+ 'ssl/ssl_key_logger.cc',
+ 'ssl/ssl_key_logger.h',
'ssl/ssl_platform_key.h',
'ssl/ssl_platform_key_nss.cc',
+ 'ssl/ssl_platform_key_task_runner.cc',
+ 'ssl/ssl_platform_key_task_runner.h',
'ssl/threaded_ssl_private_key.cc',
'ssl/threaded_ssl_private_key.h',
],
diff --git a/chromium/net/net_unittests_apk.isolate b/chromium/net/net_unittests_apk.isolate
new file mode 100644
index 00000000000..b1e945beb95
--- /dev/null
+++ b/chromium/net/net_unittests_apk.isolate
@@ -0,0 +1,25 @@
+# Copyright 2015 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.
+{
+ 'includes': [
+ '../build/android/android.isolate',
+ 'net_unittests.isolate',
+ 'tools/testserver/testserver.isolate',
+ ],
+ 'variables': {
+ 'command': [
+ '<(PRODUCT_DIR)/bin/run_net_unittests',
+ ],
+ 'files': [
+ '../base/base.isolate',
+ '../build/config/',
+ '../gin/v8.isolate',
+ '../third_party/icu/icu.isolate',
+ '../third_party/instrumented_libraries/instrumented_libraries.isolate',
+ '<(PRODUCT_DIR)/bin/run_net_unittests',
+ '<(PRODUCT_DIR)/net_unittests_apk/',
+ 'net_unittests.isolate',
+ ]
+ },
+}
diff --git a/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h b/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h
index 5e5a691b7cc..e3699aa9c10 100644
--- a/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h
+++ b/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h
@@ -5,8 +5,11 @@
#ifndef NET_PROXY_DHCP_PROXY_SCRIPT_ADAPTER_FETCHER_WIN_H_
#define NET_PROXY_DHCP_PROXY_SCRIPT_ADAPTER_FETCHER_WIN_H_
+#include <stddef.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc b/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc
index fd227dfdded..5fae7a41fce 100644
--- a/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc
+++ b/chromium/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc
@@ -13,7 +13,7 @@
#include "net/base/test_completion_callback.h"
#include "net/proxy/mock_proxy_script_fetcher.h"
#include "net/proxy/proxy_script_fetcher_impl.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -283,14 +283,12 @@ class MockDhcpRealFetchProxyScriptAdapterFetcher
};
TEST(DhcpProxyScriptAdapterFetcher, MockDhcpRealFetch) {
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath(
- FILE_PATH_LITERAL("net/data/proxy_script_fetcher_unittest")));
+ EmbeddedTestServer test_server;
+ test_server.ServeFilesFromSourceDirectory(
+ "net/data/proxy_script_fetcher_unittest");
ASSERT_TRUE(test_server.Start());
- GURL configured_url = test_server.GetURL("files/downloadable.pac");
+ GURL configured_url = test_server.GetURL("/downloadable.pac");
FetcherClient client;
TestURLRequestContext url_request_context;
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher.h b/chromium/net/proxy/dhcp_proxy_script_fetcher.h
index 85d4df845b4..2d33e2fe785 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher.h
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher.h
@@ -5,8 +5,8 @@
#ifndef NET_PROXY_DHCP_SCRIPT_FETCHER_H_
#define NET_PROXY_DHCP_SCRIPT_FETCHER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc b/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc
index ab89118b2cb..75c0913cba1 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc
@@ -29,7 +29,7 @@ scoped_ptr<DhcpProxyScriptFetcher> DhcpProxyScriptFetcherFactory::Create(
ret.reset(new DhcpProxyScriptFetcherWin(context));
#endif
DCHECK(ret);
- return ret.Pass();
+ return ret;
}
}
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.h b/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.h
index 1c315ad8138..b017bb63c65 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.h
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.h
@@ -5,7 +5,7 @@
#ifndef NET_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_
#define NET_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher_win.cc b/chromium/net/proxy/dhcp_proxy_script_fetcher_win.cc
index bf3e9d65836..263b50f1fbc 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher_win.cc
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher_win.cc
@@ -4,8 +4,11 @@
#include "net/proxy/dhcp_proxy_script_fetcher_win.h"
+#include <vector>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/memory/scoped_ptr.h"
#include "base/profiler/scoped_tracker.h"
#include "base/threading/sequenced_worker_pool.h"
#include "net/base/net_errors.h"
@@ -173,11 +176,12 @@ void DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone(
for (std::set<std::string>::const_iterator it = adapter_names.begin();
it != adapter_names.end();
++it) {
- DhcpProxyScriptAdapterFetcher* fetcher(ImplCreateAdapterFetcher());
+ scoped_ptr<DhcpProxyScriptAdapterFetcher> fetcher(
+ ImplCreateAdapterFetcher());
fetcher->Fetch(
*it, base::Bind(&DhcpProxyScriptFetcherWin::OnFetcherDone,
base::Unretained(this)));
- fetchers_.push_back(fetcher);
+ fetchers_.push_back(std::move(fetcher));
}
num_pending_fetchers_ = fetchers_.size();
}
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher_win.h b/chromium/net/proxy/dhcp_proxy_script_fetcher_win.h
index decb795e96e..2620fc5f64d 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher_win.h
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher_win.h
@@ -7,9 +7,11 @@
#include <set>
#include <string>
+#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
@@ -142,7 +144,7 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
// Vector, in Windows' network adapter preference order, of
// DhcpProxyScriptAdapterFetcher objects that are or were attempting
// to fetch a PAC file based on DHCP configuration.
- typedef ScopedVector<DhcpProxyScriptAdapterFetcher> FetcherVector;
+ using FetcherVector = std::vector<scoped_ptr<DhcpProxyScriptAdapterFetcher>>;
FetcherVector fetchers_;
// Number of fetchers we are waiting for.
diff --git a/chromium/net/proxy/in_process_mojo_proxy_resolver_factory.cc b/chromium/net/proxy/in_process_mojo_proxy_resolver_factory.cc
index 3e58b011bc1..5e1574b92dd 100644
--- a/chromium/net/proxy/in_process_mojo_proxy_resolver_factory.cc
+++ b/chromium/net/proxy/in_process_mojo_proxy_resolver_factory.cc
@@ -4,6 +4,8 @@
#include "net/proxy/in_process_mojo_proxy_resolver_factory.h"
+#include <utility>
+
#include "base/memory/singleton.h"
#include "net/proxy/mojo_proxy_resolver_factory_impl.h"
@@ -30,7 +32,7 @@ InProcessMojoProxyResolverFactory::CreateResolver(
const mojo::String& pac_script,
mojo::InterfaceRequest<interfaces::ProxyResolver> req,
interfaces::ProxyResolverFactoryRequestClientPtr client) {
- factory_->CreateResolver(pac_script, req.Pass(), client.Pass());
+ factory_->CreateResolver(pac_script, std::move(req), std::move(client));
return nullptr;
}
diff --git a/chromium/net/proxy/mock_proxy_resolver.cc b/chromium/net/proxy/mock_proxy_resolver.cc
index 9c5cb036107..21cac0026cb 100644
--- a/chromium/net/proxy/mock_proxy_resolver.cc
+++ b/chromium/net/proxy/mock_proxy_resolver.cc
@@ -4,6 +4,8 @@
#include "net/proxy/mock_proxy_resolver.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
@@ -21,26 +23,23 @@ MockAsyncProxyResolver::Request::Request(MockAsyncProxyResolver* resolver,
}
void MockAsyncProxyResolver::Request::CompleteNow(int rv) {
- CompletionCallback callback = callback_;
+ CompletionCallback callback = callback_;
- // May delete |this|.
- resolver_->RemovePendingRequest(this);
+ // May delete |this|.
+ resolver_->RemovePendingRequest(this);
- callback.Run(rv);
- }
+ callback.Run(rv);
+}
- MockAsyncProxyResolver::Request::~Request() {
- }
+MockAsyncProxyResolver::Request::~Request() {}
- MockAsyncProxyResolver::~MockAsyncProxyResolver() {
- }
+MockAsyncProxyResolver::~MockAsyncProxyResolver() {}
- int MockAsyncProxyResolver::GetProxyForURL(
- const GURL& url,
- ProxyInfo* results,
- const CompletionCallback& callback,
- RequestHandle* request_handle,
- const BoundNetLog& /*net_log*/) {
+int MockAsyncProxyResolver::GetProxyForURL(const GURL& url,
+ ProxyInfo* results,
+ const CompletionCallback& callback,
+ RequestHandle* request_handle,
+ const BoundNetLog& /*net_log*/) {
scoped_refptr<Request> request = new Request(this, url, results, callback);
pending_requests_.push_back(request);
@@ -89,7 +88,7 @@ MockAsyncProxyResolverFactory::Request::~Request() {
void MockAsyncProxyResolverFactory::Request::CompleteNow(
int rv,
scoped_ptr<ProxyResolver> resolver) {
- *resolver_ = resolver.Pass();
+ *resolver_ = std::move(resolver);
// RemovePendingRequest may remove the last external reference to |this|.
scoped_refptr<MockAsyncProxyResolverFactory::Request> keep_alive(this);
diff --git a/chromium/net/proxy/mock_proxy_resolver.h b/chromium/net/proxy/mock_proxy_resolver.h
index aec843227b9..9ed3348b3fa 100644
--- a/chromium/net/proxy/mock_proxy_resolver.h
+++ b/chromium/net/proxy/mock_proxy_resolver.h
@@ -7,6 +7,7 @@
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_resolver.h"
diff --git a/chromium/net/proxy/mock_proxy_script_fetcher.cc b/chromium/net/proxy/mock_proxy_script_fetcher.cc
index 7604b5b34b1..e7cf7a3a444 100644
--- a/chromium/net/proxy/mock_proxy_script_fetcher.cc
+++ b/chromium/net/proxy/mock_proxy_script_fetcher.cc
@@ -30,7 +30,7 @@ int MockProxyScriptFetcher::Fetch(const GURL& url, base::string16* text,
pending_request_text_ = text;
if (waiting_for_fetch_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
return ERR_IO_PENDING;
}
diff --git a/chromium/net/proxy/mojo_proxy_resolver_factory.h b/chromium/net/proxy/mojo_proxy_resolver_factory.h
index 2163cb0cad3..98cb3475f8f 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_factory.h
+++ b/chromium/net/proxy/mojo_proxy_resolver_factory.h
@@ -7,9 +7,9 @@
#include "base/callback_helpers.h"
#include "base/memory/scoped_ptr.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/interfaces/host_resolver_service.mojom.h"
#include "net/interfaces/proxy_resolver_service.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
namespace net {
diff --git a/chromium/net/proxy/mojo_proxy_resolver_factory_impl.cc b/chromium/net/proxy/mojo_proxy_resolver_factory_impl.cc
index a24edc22c47..49b23ea25fb 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_factory_impl.cc
+++ b/chromium/net/proxy/mojo_proxy_resolver_factory_impl.cc
@@ -5,7 +5,9 @@
#include "net/proxy/mojo_proxy_resolver_factory_impl.h"
#include <string>
+#include <utility>
+#include "base/macros.h"
#include "base/stl_util.h"
#include "net/base/net_errors.h"
#include "net/proxy/mojo_proxy_resolver_impl.h"
@@ -37,8 +39,8 @@ class MojoProxyResolverHolder {
MojoProxyResolverHolder::MojoProxyResolverHolder(
scoped_ptr<ProxyResolverV8Tracing> proxy_resolver_impl,
mojo::InterfaceRequest<interfaces::ProxyResolver> request)
- : mojo_proxy_resolver_(proxy_resolver_impl.Pass()),
- binding_(&mojo_proxy_resolver_, request.Pass()) {
+ : mojo_proxy_resolver_(std::move(proxy_resolver_impl)),
+ binding_(&mojo_proxy_resolver_, std::move(request)) {
binding_.set_connection_error_handler(base::Bind(
&MojoProxyResolverHolder::OnConnectionError, base::Unretained(this)));
}
@@ -81,9 +83,9 @@ MojoProxyResolverFactoryImpl::Job::Job(
mojo::InterfaceRequest<interfaces::ProxyResolver> request,
interfaces::ProxyResolverFactoryRequestClientPtr client)
: parent_(factory),
- proxy_request_(request.Pass()),
+ proxy_request_(std::move(request)),
factory_(proxy_resolver_factory),
- client_ptr_(client.Pass()) {
+ client_ptr_(std::move(client)) {
client_ptr_.set_connection_error_handler(
base::Bind(&MojoProxyResolverFactoryImpl::Job::OnConnectionError,
base::Unretained(this)));
@@ -109,8 +111,8 @@ void MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated(int error) {
if (error == OK) {
// The MojoProxyResolverHolder will delete itself if |proxy_request_|
// encounters a connection error.
- new MojoProxyResolverHolder(proxy_resolver_impl_.Pass(),
- proxy_request_.Pass());
+ new MojoProxyResolverHolder(std::move(proxy_resolver_impl_),
+ std::move(proxy_request_));
}
client_ptr_->ReportResult(error);
parent_->RemoveJob(this);
@@ -119,15 +121,13 @@ void MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated(int error) {
MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl(
scoped_ptr<ProxyResolverV8TracingFactory> proxy_resolver_factory,
mojo::InterfaceRequest<interfaces::ProxyResolverFactory> request)
- : proxy_resolver_impl_factory_(proxy_resolver_factory.Pass()),
- binding_(this, request.Pass()) {
-}
+ : proxy_resolver_impl_factory_(std::move(proxy_resolver_factory)),
+ binding_(this, std::move(request)) {}
MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl(
mojo::InterfaceRequest<interfaces::ProxyResolverFactory> request)
: MojoProxyResolverFactoryImpl(ProxyResolverV8TracingFactory::Create(),
- request.Pass()) {
-}
+ std::move(request)) {}
MojoProxyResolverFactoryImpl::~MojoProxyResolverFactoryImpl() {
STLDeleteElements(&jobs_);
@@ -141,7 +141,8 @@ void MojoProxyResolverFactoryImpl::CreateResolver(
// finishes or |request| or |client| encounters a connection error.
jobs_.insert(new Job(
this, ProxyResolverScriptData::FromUTF8(pac_script.To<std::string>()),
- proxy_resolver_impl_factory_.get(), request.Pass(), client.Pass()));
+ proxy_resolver_impl_factory_.get(), std::move(request),
+ std::move(client)));
}
void MojoProxyResolverFactoryImpl::RemoveJob(Job* job) {
diff --git a/chromium/net/proxy/mojo_proxy_resolver_factory_impl.h b/chromium/net/proxy/mojo_proxy_resolver_factory_impl.h
index dcc7b482bf6..44646e70148 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_factory_impl.h
+++ b/chromium/net/proxy/mojo_proxy_resolver_factory_impl.h
@@ -8,8 +8,9 @@
#include <set>
#include "base/callback.h"
+#include "base/macros.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/interfaces/proxy_resolver_service.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
namespace net {
class HostResolver;
diff --git a/chromium/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc b/chromium/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc
index 0262d647cc1..c7fb51bcb8b 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc
+++ b/chromium/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc
@@ -4,13 +4,15 @@
#include "net/proxy/mojo_proxy_resolver_factory_impl.h"
+#include <utility>
+
#include "base/strings/utf_string_conversions.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/test_completion_callback.h"
#include "net/proxy/mock_proxy_resolver.h"
#include "net/proxy/proxy_resolver_v8_tracing.h"
#include "net/test/event_waiter.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
namespace net {
namespace {
@@ -133,7 +135,8 @@ TEST_F(MojoProxyResolverFactoryImplTest, DisconnectProxyResolverClient) {
mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
this, mojo::GetProxy(&client_ptr));
factory_->CreateResolver(mojo::String::From(kScriptData),
- mojo::GetProxy(&proxy_resolver), client_ptr.Pass());
+ mojo::GetProxy(&proxy_resolver),
+ std::move(client_ptr));
proxy_resolver.set_connection_error_handler(
base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError,
base::Unretained(this)));
@@ -160,7 +163,8 @@ TEST_F(MojoProxyResolverFactoryImplTest, Error) {
mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
this, mojo::GetProxy(&client_ptr));
factory_->CreateResolver(mojo::String::From(kScriptData),
- mojo::GetProxy(&proxy_resolver), client_ptr.Pass());
+ mojo::GetProxy(&proxy_resolver),
+ std::move(client_ptr));
proxy_resolver.set_connection_error_handler(
base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError,
base::Unretained(this)));
@@ -181,7 +185,8 @@ TEST_F(MojoProxyResolverFactoryImplTest,
mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
this, mojo::GetProxy(&client_ptr));
factory_->CreateResolver(mojo::String::From(kScriptData),
- mojo::GetProxy(&proxy_resolver), client_ptr.Pass());
+ mojo::GetProxy(&proxy_resolver),
+ std::move(client_ptr));
proxy_resolver.set_connection_error_handler(
base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError,
base::Unretained(this)));
@@ -199,7 +204,8 @@ TEST_F(MojoProxyResolverFactoryImplTest,
mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
this, mojo::GetProxy(&client_ptr));
factory_->CreateResolver(mojo::String::From(kScriptData),
- mojo::GetProxy(&proxy_resolver), client_ptr.Pass());
+ mojo::GetProxy(&proxy_resolver),
+ std::move(client_ptr));
proxy_resolver.set_connection_error_handler(
base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError,
base::Unretained(this)));
diff --git a/chromium/net/proxy/mojo_proxy_resolver_impl.cc b/chromium/net/proxy/mojo_proxy_resolver_impl.cc
index c5ae034040b..bbac2e72cca 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_impl.cc
+++ b/chromium/net/proxy/mojo_proxy_resolver_impl.cc
@@ -4,6 +4,9 @@
#include "net/proxy/mojo_proxy_resolver_impl.h"
+#include <utility>
+
+#include "base/macros.h"
#include "base/stl_util.h"
#include "mojo/common/url_type_converters.h"
#include "net/base/net_errors.h"
@@ -45,8 +48,7 @@ class MojoProxyResolverImpl::Job {
MojoProxyResolverImpl::MojoProxyResolverImpl(
scoped_ptr<ProxyResolverV8Tracing> resolver)
- : resolver_(resolver.Pass()) {
-}
+ : resolver_(std::move(resolver)) {}
MojoProxyResolverImpl::~MojoProxyResolverImpl() {
STLDeleteElements(&resolve_jobs_);
@@ -56,7 +58,7 @@ void MojoProxyResolverImpl::GetProxyForUrl(
const mojo::String& url,
interfaces::ProxyResolverRequestClientPtr client) {
DVLOG(1) << "GetProxyForUrl(" << url << ")";
- Job* job = new Job(client.Pass(), this, url.To<GURL>());
+ Job* job = new Job(std::move(client), this, url.To<GURL>());
bool inserted = resolve_jobs_.insert(job).second;
DCHECK(inserted);
job->Start();
@@ -73,7 +75,7 @@ MojoProxyResolverImpl::Job::Job(
MojoProxyResolverImpl* resolver,
const GURL& url)
: resolver_(resolver),
- client_(client.Pass()),
+ client_(std::move(client)),
url_(url),
request_handle_(nullptr),
done_(false) {}
@@ -105,7 +107,7 @@ void MojoProxyResolverImpl::Job::GetProxyDone(int error) {
result = mojo::Array<interfaces::ProxyServerPtr>::From(
result_.proxy_list().GetAll());
}
- client_->ReportResult(error, result.Pass());
+ client_->ReportResult(error, std::move(result));
resolver_->DeleteJob(this);
}
diff --git a/chromium/net/proxy/mojo_proxy_resolver_impl.h b/chromium/net/proxy/mojo_proxy_resolver_impl.h
index 479fcfca222..75280042f5e 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_impl.h
+++ b/chromium/net/proxy/mojo_proxy_resolver_impl.h
@@ -9,6 +9,7 @@
#include <queue>
#include <set>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/interfaces/proxy_resolver_service.mojom.h"
diff --git a/chromium/net/proxy/mojo_proxy_resolver_impl_unittest.cc b/chromium/net/proxy/mojo_proxy_resolver_impl_unittest.cc
index bfc777325a7..b045b27b300 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_impl_unittest.cc
+++ b/chromium/net/proxy/mojo_proxy_resolver_impl_unittest.cc
@@ -5,9 +5,11 @@
#include "net/proxy/mojo_proxy_resolver_impl.h"
#include <string>
+#include <utility>
#include <vector>
#include "base/run_loop.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/net_errors.h"
#include "net/proxy/mock_proxy_resolver.h"
#include "net/proxy/mojo_proxy_type_converters.h"
@@ -16,7 +18,6 @@
#include "net/proxy/proxy_server.h"
#include "net/test/event_waiter.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
namespace net {
namespace {
@@ -60,7 +61,7 @@ class TestRequestClient : public interfaces::ProxyResolverRequestClient {
TestRequestClient::TestRequestClient(
mojo::InterfaceRequest<interfaces::ProxyResolverRequestClient> request)
- : binding_(this, request.Pass()) {
+ : binding_(this, std::move(request)) {
binding_.set_connection_error_handler(base::Bind(
&TestRequestClient::OnConnectionError, base::Unretained(this)));
}
@@ -79,7 +80,7 @@ void TestRequestClient::ReportResult(
event_waiter_.NotifyEvent(RESULT_RECEIVED);
ASSERT_FALSE(done_);
error_ = static_cast<Error>(error);
- results_ = results.Pass();
+ results_ = std::move(results);
done_ = true;
}
@@ -177,7 +178,7 @@ class MojoProxyResolverImplTest : public testing::Test {
scoped_ptr<MockProxyResolverV8Tracing> mock_resolver(
new MockProxyResolverV8Tracing);
mock_proxy_resolver_ = mock_resolver.get();
- resolver_impl_.reset(new MojoProxyResolverImpl(mock_resolver.Pass()));
+ resolver_impl_.reset(new MojoProxyResolverImpl(std::move(mock_resolver)));
resolver_ = resolver_impl_.get();
}
@@ -191,7 +192,7 @@ TEST_F(MojoProxyResolverImplTest, GetProxyForUrl) {
interfaces::ProxyResolverRequestClientPtr client_ptr;
TestRequestClient client(mojo::GetProxy(&client_ptr));
- resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
+ resolver_->GetProxyForUrl("http://example.com", std::move(client_ptr));
ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
const MockProxyResolverV8Tracing::Request& request =
mock_proxy_resolver_->pending_requests()[0];
@@ -238,7 +239,7 @@ TEST_F(MojoProxyResolverImplTest, GetProxyForUrlFailure) {
interfaces::ProxyResolverRequestClientPtr client_ptr;
TestRequestClient client(mojo::GetProxy(&client_ptr));
- resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
+ resolver_->GetProxyForUrl("http://example.com", std::move(client_ptr));
ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
const MockProxyResolverV8Tracing::Request& request =
mock_proxy_resolver_->pending_requests()[0];
@@ -258,8 +259,8 @@ TEST_F(MojoProxyResolverImplTest, GetProxyForUrlMultiple) {
interfaces::ProxyResolverRequestClientPtr client_ptr2;
TestRequestClient client2(mojo::GetProxy(&client_ptr2));
- resolver_->GetProxyForUrl("http://example.com", client_ptr1.Pass());
- resolver_->GetProxyForUrl("https://example.com", client_ptr2.Pass());
+ resolver_->GetProxyForUrl("http://example.com", std::move(client_ptr1));
+ resolver_->GetProxyForUrl("https://example.com", std::move(client_ptr2));
ASSERT_EQ(2u, mock_proxy_resolver_->pending_requests().size());
const MockProxyResolverV8Tracing::Request& request1 =
mock_proxy_resolver_->pending_requests()[0];
@@ -298,7 +299,7 @@ TEST_F(MojoProxyResolverImplTest, DestroyClient) {
scoped_ptr<TestRequestClient> client(
new TestRequestClient(mojo::GetProxy(&client_ptr)));
- resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
+ resolver_->GetProxyForUrl("http://example.com", std::move(client_ptr));
ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
const MockProxyResolverV8Tracing::Request& request =
mock_proxy_resolver_->pending_requests()[0];
@@ -312,7 +313,7 @@ TEST_F(MojoProxyResolverImplTest, DestroyService) {
interfaces::ProxyResolverRequestClientPtr client_ptr;
TestRequestClient client(mojo::GetProxy(&client_ptr));
- resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
+ resolver_->GetProxyForUrl("http://example.com", std::move(client_ptr));
ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
resolver_impl_.reset();
client.event_waiter().WaitForEvent(TestRequestClient::CONNECTION_ERROR);
diff --git a/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings.h b/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings.h
index 70ebe3c4983..e4b84bdae3a 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings.h
+++ b/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings.h
@@ -5,6 +5,8 @@
#ifndef NET_PROXY_MOJO_PROXY_RESOLVER_V8_TRACING_BINDINGS_H_
#define NET_PROXY_MOJO_PROXY_RESOLVER_V8_TRACING_BINDINGS_H_
+#include <utility>
+
#include "base/threading/thread_checker.h"
#include "mojo/common/common_type_converters.h"
#include "net/dns/host_resolver_mojo.h"
@@ -54,7 +56,7 @@ class MojoProxyResolverV8TracingBindings
void ResolveDns(interfaces::HostResolverRequestInfoPtr request_info,
interfaces::HostResolverRequestClientPtr client) {
DCHECK(thread_checker_.CalledOnValidThread());
- client_->ResolveDns(request_info.Pass(), client.Pass());
+ client_->ResolveDns(std::move(request_info), std::move(client));
}
base::ThreadChecker thread_checker_;
diff --git a/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings_unittest.cc b/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings_unittest.cc
index ce11b7108d7..60058a7be12 100644
--- a/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings_unittest.cc
+++ b/chromium/net/proxy/mojo_proxy_resolver_v8_tracing_bindings_unittest.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/proxy/mojo_proxy_type_converters.cc b/chromium/net/proxy/mojo_proxy_type_converters.cc
index 00aed7ab682..c927534d10b 100644
--- a/chromium/net/proxy/mojo_proxy_type_converters.cc
+++ b/chromium/net/proxy/mojo_proxy_type_converters.cc
@@ -70,7 +70,7 @@ TypeConverter<net::interfaces::ProxyServerPtr, net::ProxyServer>::Convert(
server->host = obj.host_port_pair().host();
server->port = obj.host_port_pair().port();
}
- return server.Pass();
+ return server;
}
// static
diff --git a/chromium/net/proxy/mojo_proxy_type_converters.h b/chromium/net/proxy/mojo_proxy_type_converters.h
index 55ea69df919..51b0e380c66 100644
--- a/chromium/net/proxy/mojo_proxy_type_converters.h
+++ b/chromium/net/proxy/mojo_proxy_type_converters.h
@@ -5,8 +5,8 @@
#ifndef NET_PROXY_MOJO_PROXY_TYPE_CONVERTERS_H_
#define NET_PROXY_MOJO_PROXY_TYPE_CONVERTERS_H_
+#include "mojo/public/cpp/bindings/type_converter.h"
#include "net/interfaces/proxy_resolver_service.mojom.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/type_converter.h"
namespace net {
class ProxyInfo;
diff --git a/chromium/net/proxy/multi_threaded_proxy_resolver.cc b/chromium/net/proxy/multi_threaded_proxy_resolver.cc
index 6c6fa699534..5eae4f744e8 100644
--- a/chromium/net/proxy/multi_threaded_proxy_resolver.cc
+++ b/chromium/net/proxy/multi_threaded_proxy_resolver.cc
@@ -5,6 +5,7 @@
#include "net/proxy/multi_threaded_proxy_resolver.h"
#include <deque>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -64,7 +65,7 @@ class Executor : public base::RefCountedThreadSafe<Executor> {
int thread_number() const { return thread_number_; }
void set_resolver(scoped_ptr<ProxyResolver> resolver) {
- resolver_ = resolver.Pass();
+ resolver_ = std::move(resolver);
}
void set_coordinator(Coordinator* coordinator) {
@@ -261,7 +262,7 @@ class CreateResolverJob : public Job {
// The task may have been cancelled after it was started.
if (!was_cancelled()) {
DCHECK(executor());
- executor()->set_resolver(resolver_.Pass());
+ executor()->set_resolver(std::move(resolver_));
}
OnJobCompleted();
}
@@ -305,7 +306,7 @@ class MultiThreadedProxyResolver::GetProxyForURLJob : public Job {
net_log_.AddEvent(
NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD,
- NetLog::IntegerCallback("thread_number", executor()->thread_number()));
+ NetLog::IntCallback("thread_number", executor()->thread_number()));
}
// Runs on the worker thread.
@@ -422,7 +423,7 @@ MultiThreadedProxyResolver::MultiThreadedProxyResolver(
size_t max_num_threads,
const scoped_refptr<ProxyResolverScriptData>& script_data,
scoped_refptr<Executor> executor)
- : resolver_factory_(resolver_factory.Pass()),
+ : resolver_factory_(std::move(resolver_factory)),
max_num_threads_(max_num_threads),
script_data_(script_data) {
DCHECK(script_data_);
@@ -549,7 +550,7 @@ class MultiThreadedProxyResolverFactory::Job
const CompletionCallback& callback)
: factory_(factory),
resolver_out_(resolver),
- resolver_factory_(resolver_factory.Pass()),
+ resolver_factory_(std::move(resolver_factory)),
max_num_threads_(max_num_threads),
script_data_(script_data),
executor_(new Executor(this, 0)),
@@ -576,8 +577,8 @@ class MultiThreadedProxyResolverFactory::Job
int error = OK;
if (executor->resolver()) {
resolver_out_->reset(new MultiThreadedProxyResolver(
- resolver_factory_.Pass(), max_num_threads_, script_data_.Pass(),
- executor_));
+ std::move(resolver_factory_), max_num_threads_,
+ std::move(script_data_), executor_));
} else {
error = ERR_PAC_SCRIPT_FAILED;
executor_->Destroy();
@@ -619,7 +620,7 @@ int MultiThreadedProxyResolverFactory::CreateProxyResolver(
CreateProxyResolverFactory(), max_num_threads_,
callback));
jobs_.insert(job.get());
- *request = job.Pass();
+ *request = std::move(job);
return ERR_IO_PENDING;
}
diff --git a/chromium/net/proxy/multi_threaded_proxy_resolver.h b/chromium/net/proxy/multi_threaded_proxy_resolver.h
index 30a7b1b1ee6..f00249f4fb2 100644
--- a/chromium/net/proxy/multi_threaded_proxy_resolver.h
+++ b/chromium/net/proxy/multi_threaded_proxy_resolver.h
@@ -5,9 +5,10 @@
#ifndef NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_
#define NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_
+#include <stddef.h>
+
#include <set>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc b/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc
index dd30370a33a..29e49c34a80 100644
--- a/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc
+++ b/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc
@@ -4,6 +4,7 @@
#include "net/proxy/multi_threaded_proxy_resolver.h"
+#include <utility>
#include <vector>
#include "base/message_loop/message_loop.h"
@@ -179,11 +180,11 @@ class SingleShotMultiThreadedProxyResolverFactory
size_t max_num_threads,
scoped_ptr<ProxyResolverFactory> factory)
: MultiThreadedProxyResolverFactory(max_num_threads, false),
- factory_(factory.Pass()) {}
+ factory_(std::move(factory)) {}
scoped_ptr<ProxyResolverFactory> CreateProxyResolverFactory() override {
DCHECK(factory_);
- return factory_.Pass();
+ return std::move(factory_);
}
private:
@@ -197,7 +198,7 @@ class MultiThreadedProxyResolverTest : public testing::Test {
new BlockableProxyResolverFactory);
factory_ = factory_owner.get();
resolver_factory_.reset(new SingleShotMultiThreadedProxyResolverFactory(
- num_threads, factory_owner.Pass()));
+ num_threads, std::move(factory_owner)));
TestCompletionCallback ready_callback;
scoped_ptr<ProxyResolverFactory::Request> request;
resolver_factory_->CreateProxyResolver(
@@ -230,7 +231,13 @@ class MultiThreadedProxyResolverTest : public testing::Test {
scoped_ptr<ProxyResolver> resolver_;
};
-TEST_F(MultiThreadedProxyResolverTest, SingleThread_Basic) {
+// Flaky on Android. See http://crbug.com/547786
+#if defined(OS_ANDROID)
+#define MAYBE_SingleThread_Basic DISABLED_SingleThread_Basic
+#else
+#define MAYBE_SingleThread_Basic SingleThread_Basic
+#endif
+TEST_F(MultiThreadedProxyResolverTest, MAYBE_SingleThread_Basic) {
const size_t kNumThreads = 1u;
ASSERT_NO_FATAL_FAILURE(Init(kNumThreads));
diff --git a/chromium/net/proxy/network_delegate_error_observer.cc b/chromium/net/proxy/network_delegate_error_observer.cc
index 1bb0537d6cd..b5d85c479ea 100644
--- a/chromium/net/proxy/network_delegate_error_observer.cc
+++ b/chromium/net/proxy/network_delegate_error_observer.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "net/base/net_errors.h"
#include "net/base/network_delegate.h"
diff --git a/chromium/net/proxy/network_delegate_error_observer.h b/chromium/net/proxy/network_delegate_error_observer.h
index 2463913ff65..50a3f647e4c 100644
--- a/chromium/net/proxy/network_delegate_error_observer.h
+++ b/chromium/net/proxy/network_delegate_error_observer.h
@@ -6,6 +6,7 @@
#define NET_PROXY_NETWORK_DELEGATE_ERROR_OBSERVER_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/proxy/proxy_resolver_error_observer.h"
diff --git a/chromium/net/proxy/polling_proxy_config_service.h b/chromium/net/proxy/polling_proxy_config_service.h
index c8230561f7f..f4db0df6648 100644
--- a/chromium/net/proxy/polling_proxy_config_service.h
+++ b/chromium/net/proxy/polling_proxy_config_service.h
@@ -6,6 +6,7 @@
#define NET_PROXY_POLLING_PROXY_CONFIG_SERVICE_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/proxy/proxy_config_service.h"
diff --git a/chromium/net/proxy/proxy_bypass_rules.h b/chromium/net/proxy/proxy_bypass_rules.h
index c8fe0693f5c..c7960743f81 100644
--- a/chromium/net/proxy/proxy_bypass_rules.h
+++ b/chromium/net/proxy/proxy_bypass_rules.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "url/gurl.h"
diff --git a/chromium/net/proxy/proxy_config.cc b/chromium/net/proxy/proxy_config.cc
index 2ac6de1b328..78d6ef3b9cf 100644
--- a/chromium/net/proxy/proxy_config.cc
+++ b/chromium/net/proxy/proxy_config.cc
@@ -4,9 +4,11 @@
#include "net/proxy/proxy_config.h"
+#include <utility>
+
#include "base/logging.h"
-#include "base/strings/string_util.h"
#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
#include "base/values.h"
#include "net/proxy/proxy_info.h"
@@ -258,7 +260,7 @@ scoped_ptr<base::DictionaryValue> ProxyConfig::ToValue() const {
AddProxyListToValue("ftp", proxy_rules_.proxies_for_ftp, dict2.get());
AddProxyListToValue("fallback", proxy_rules_.fallback_proxies,
dict2.get());
- dict->Set("proxy_per_scheme", dict2.Pass());
+ dict->Set("proxy_per_scheme", std::move(dict2));
break;
}
default:
@@ -286,7 +288,7 @@ scoped_ptr<base::DictionaryValue> ProxyConfig::ToValue() const {
// Output the source.
dict->SetString("source", ProxyConfigSourceToString(source_));
- return dict.Pass();
+ return dict;
}
} // namespace net
diff --git a/chromium/net/proxy/proxy_config.h b/chromium/net/proxy/proxy_config.h
index 303aa10b09a..2e91923a83c 100644
--- a/chromium/net/proxy/proxy_config.h
+++ b/chromium/net/proxy/proxy_config.h
@@ -37,8 +37,8 @@ class NET_EXPORT ProxyConfig {
public:
// ProxyRules describes the "manual" proxy settings.
// TODO(eroman): Turn this into a class.
- // TODO(marq): Update the enum names; "TYPE_SINGLE_PROXY" really means
- // the same set of proxies are used for all requests.
+ // TODO(crbug.com/546383): Update the enum names; "TYPE_SINGLE_PROXY" really
+ // means the same set of proxies are used for all requests.
struct NET_EXPORT ProxyRules {
enum Type {
TYPE_NO_RULES,
diff --git a/chromium/net/proxy/proxy_config_service_android.cc b/chromium/net/proxy/proxy_config_service_android.cc
index 66065fb1c66..990b614fb8b 100644
--- a/chromium/net/proxy/proxy_config_service_android.cc
+++ b/chromium/net/proxy/proxy_config_service_android.cc
@@ -6,14 +6,15 @@
#include <sys/system_properties.h>
+#include "base/android/context_utils.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "base/sequenced_task_runner.h"
@@ -59,8 +60,7 @@ ProxyServer ConstructProxyServer(ProxyServer::Scheme scheme,
return ProxyServer();
DCHECK(port_as_int > 0);
return ProxyServer(
- scheme,
- HostPortPair(proxy_host, static_cast<uint16>(port_as_int)));
+ scheme, HostPortPair(proxy_host, static_cast<uint16_t>(port_as_int)));
}
ProxyServer LookupProxy(const std::string& prefix,
@@ -99,11 +99,6 @@ void AddBypassRules(const std::string& scheme,
// http.nonProxyHosts property to *.android.com|*.kernel.org will cause
// requests to http://developer.android.com to be made without a proxy.
- // Force localhost to be on the proxy exclusion list;
- // otherwise all localhost traffic is routed through
- // the proxy which is not desired.
- bypass_rules->AddRuleToBypassLocal();
-
std::string non_proxy_hosts =
get_property.Run(scheme + ".nonProxyHosts");
if (non_proxy_hosts.empty())
@@ -302,12 +297,13 @@ class ProxyConfigServiceAndroid::Delegate
explicit JNIDelegateImpl(Delegate* delegate) : delegate_(delegate) {}
// ProxyConfigServiceAndroid::JNIDelegate overrides.
- void ProxySettingsChangedTo(JNIEnv* env,
- jobject jself,
- jstring jhost,
- jint jport,
- jstring jpac_url,
- jobjectArray jexclusion_list) override {
+ void ProxySettingsChangedTo(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& jself,
+ const JavaParamRef<jstring>& jhost,
+ jint jport,
+ const JavaParamRef<jstring>& jpac_url,
+ const JavaParamRef<jobjectArray>& jexclusion_list) override {
std::string host = ConvertJavaStringToUTF8(env, jhost);
std::string pac_url;
if (jpac_url)
@@ -318,7 +314,8 @@ class ProxyConfigServiceAndroid::Delegate
delegate_->ProxySettingsChangedTo(host, jport, pac_url, exclusion_list);
}
- void ProxySettingsChanged(JNIEnv* env, jobject self) override {
+ void ProxySettingsChanged(JNIEnv* env,
+ const JavaParamRef<jobject>& self) override {
delegate_->ProxySettingsChanged();
}
diff --git a/chromium/net/proxy/proxy_config_service_android.h b/chromium/net/proxy/proxy_config_service_android.h
index 64e6b4939b6..1b45eb102de 100644
--- a/chromium/net/proxy/proxy_config_service_android.h
+++ b/chromium/net/proxy/proxy_config_service_android.h
@@ -8,9 +8,9 @@
#include <string>
#include "base/android/jni_android.h"
-#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/proxy/proxy_config_service.h"
@@ -43,16 +43,19 @@ class NET_EXPORT ProxyConfigServiceAndroid : public ProxyConfigService {
// are either a host/port pair or ("", 0) to indicate "no proxy".
// The third argument indicates the PAC url.
// The fourth argument is the proxy exclusion list.
- virtual void ProxySettingsChangedTo(JNIEnv*,
- jobject,
- jstring,
- jint,
- jstring,
- jobjectArray) = 0;
+ virtual void ProxySettingsChangedTo(
+ JNIEnv*,
+ const base::android::JavaParamRef<jobject>&,
+ const base::android::JavaParamRef<jstring>&,
+ jint,
+ const base::android::JavaParamRef<jstring>&,
+ const base::android::JavaParamRef<jobjectArray>&) = 0;
// Called from Java (on JNI thread) to signal that the proxy settings have
// changed. New proxy settings are fetched from the system property store.
- virtual void ProxySettingsChanged(JNIEnv*, jobject) = 0;
+ virtual void ProxySettingsChanged(
+ JNIEnv*,
+ const base::android::JavaParamRef<jobject>&) = 0;
};
ProxyConfigServiceAndroid(
diff --git a/chromium/net/proxy/proxy_config_service_ios.h b/chromium/net/proxy/proxy_config_service_ios.h
index c79a6b6d84f..d239f37652a 100644
--- a/chromium/net/proxy/proxy_config_service_ios.h
+++ b/chromium/net/proxy/proxy_config_service_ios.h
@@ -5,6 +5,7 @@
#ifndef NET_PROXY_PROXY_CONFIG_SERVICE_IOS_H_
#define NET_PROXY_PROXY_CONFIG_SERVICE_IOS_H_
+#include "base/macros.h"
#include "net/proxy/polling_proxy_config_service.h"
namespace net {
diff --git a/chromium/net/proxy/proxy_config_service_linux.cc b/chromium/net/proxy/proxy_config_service_linux.cc
index dc4f3d0d6c6..139e30840dd 100644
--- a/chromium/net/proxy/proxy_config_service_linux.cc
+++ b/chromium/net/proxy/proxy_config_service_linux.cc
@@ -5,7 +5,6 @@
#include "net/proxy/proxy_config_service_linux.h"
#include <errno.h>
-#include <fcntl.h>
#if defined(USE_GCONF)
#include <gconf/gconf-client.h>
#endif // defined(USE_GCONF)
@@ -25,6 +24,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/nix/xdg_util.h"
#include "base/single_thread_task_runner.h"
@@ -949,9 +949,8 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter,
PLOG(ERROR) << "inotify_init failed";
return false;
}
- int flags = fcntl(inotify_fd_, F_GETFL);
- if (fcntl(inotify_fd_, F_SETFL, flags | O_NONBLOCK) < 0) {
- PLOG(ERROR) << "fcntl failed";
+ if (!base::SetNonBlocking(inotify_fd_)) {
+ PLOG(ERROR) << "base::SetNonBlocking failed";
close(inotify_fd_);
inotify_fd_ = -1;
return false;
diff --git a/chromium/net/proxy/proxy_config_service_linux.h b/chromium/net/proxy/proxy_config_service_linux.h
index 311f81f2f55..d6faab01cd9 100644
--- a/chromium/net/proxy/proxy_config_service_linux.h
+++ b/chromium/net/proxy/proxy_config_service_linux.h
@@ -5,12 +5,14 @@
#ifndef NET_PROXY_PROXY_CONFIG_SERVICE_LINUX_H_
#define NET_PROXY_PROXY_CONFIG_SERVICE_LINUX_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/environment.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
diff --git a/chromium/net/proxy/proxy_config_service_mac.h b/chromium/net/proxy/proxy_config_service_mac.h
index 01a0e26b0f3..b81ffa05731 100644
--- a/chromium/net/proxy/proxy_config_service_mac.h
+++ b/chromium/net/proxy/proxy_config_service_mac.h
@@ -5,8 +5,8 @@
#ifndef NET_PROXY_PROXY_CONFIG_SERVICE_MAC_H_
#define NET_PROXY_PROXY_CONFIG_SERVICE_MAC_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
diff --git a/chromium/net/proxy/proxy_config_source.cc b/chromium/net/proxy/proxy_config_source.cc
index f3137ff57c5..6dd6071a653 100644
--- a/chromium/net/proxy/proxy_config_source.cc
+++ b/chromium/net/proxy/proxy_config_source.cc
@@ -4,7 +4,6 @@
#include "net/proxy/proxy_config_source.h"
-#include "base/basictypes.h"
#include "base/logging.h"
namespace net {
diff --git a/chromium/net/proxy/proxy_list.cc b/chromium/net/proxy/proxy_list.cc
index 1d24b6d113b..a7b7aef82b1 100644
--- a/chromium/net/proxy/proxy_list.cc
+++ b/chromium/net/proxy/proxy_list.cc
@@ -146,7 +146,7 @@ scoped_ptr<base::ListValue> ProxyList::ToValue() const {
scoped_ptr<base::ListValue> list(new base::ListValue());
for (size_t i = 0; i < proxies_.size(); ++i)
list->AppendString(proxies_[i].ToURI());
- return list.Pass();
+ return list;
}
bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info,
diff --git a/chromium/net/proxy/proxy_list.h b/chromium/net/proxy/proxy_list.h
index 97e0af65ee1..82c637d0cc7 100644
--- a/chromium/net/proxy/proxy_list.h
+++ b/chromium/net/proxy/proxy_list.h
@@ -5,6 +5,8 @@
#ifndef NET_PROXY_PROXY_LIST_H_
#define NET_PROXY_PROXY_LIST_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
diff --git a/chromium/net/proxy/proxy_resolver.h b/chromium/net/proxy/proxy_resolver.h
index b303e2b1491..81efe0577ba 100644
--- a/chromium/net/proxy/proxy_resolver.h
+++ b/chromium/net/proxy/proxy_resolver.h
@@ -7,6 +7,7 @@
#include "base/callback_forward.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "net/base/completion_callback.h"
diff --git a/chromium/net/proxy/proxy_resolver_error_observer.h b/chromium/net/proxy/proxy_resolver_error_observer.h
index 190b78759ba..0212f829570 100644
--- a/chromium/net/proxy/proxy_resolver_error_observer.h
+++ b/chromium/net/proxy/proxy_resolver_error_observer.h
@@ -5,7 +5,7 @@
#ifndef NET_PROXY_PROXY_RESOLVER_ERROR_OBSERVER_H_
#define NET_PROXY_PROXY_RESOLVER_ERROR_OBSERVER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/proxy/proxy_resolver_factory.h b/chromium/net/proxy/proxy_resolver_factory.h
index 282dd24a7e8..0cc98df91a7 100644
--- a/chromium/net/proxy/proxy_resolver_factory.h
+++ b/chromium/net/proxy/proxy_resolver_factory.h
@@ -7,6 +7,7 @@
#include <set>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
diff --git a/chromium/net/proxy/proxy_resolver_factory_mojo.cc b/chromium/net/proxy/proxy_resolver_factory_mojo.cc
index 32c1203e19b..4203eea39cd 100644
--- a/chromium/net/proxy/proxy_resolver_factory_mojo.cc
+++ b/chromium/net/proxy/proxy_resolver_factory_mojo.cc
@@ -5,14 +5,17 @@
#include "net/proxy/proxy_resolver_factory_mojo.h"
#include <set>
+#include <utility>
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/stl_util.h"
#include "base/threading/thread_checker.h"
#include "base/values.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/common/url_type_converters.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
#include "net/dns/mojo_host_resolver_impl.h"
@@ -24,7 +27,6 @@
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_resolver_error_observer.h"
#include "net/proxy/proxy_resolver_script_data.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
namespace net {
namespace {
@@ -36,7 +38,7 @@ scoped_ptr<base::Value> NetLogErrorCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("line_number", line_number);
dict->SetString("message", *message);
- return dict.Pass();
+ return std::move(dict);
}
// A mixin that forwards logging to (Bound)NetLog and ProxyResolverErrorObserver
@@ -75,7 +77,7 @@ class ClientMixin : public ClientInterface {
void ResolveDns(interfaces::HostResolverRequestInfoPtr request_info,
interfaces::HostResolverRequestClientPtr client) override {
- host_resolver_.Resolve(request_info.Pass(), client.Pass());
+ host_resolver_.Resolve(std::move(request_info), std::move(client));
}
protected:
@@ -196,13 +198,12 @@ ProxyResolverMojo::Job::Job(ProxyResolverMojo* resolver,
results_(results),
callback_(callback),
binding_(this) {
- binding_.set_connection_error_handler(base::Bind(
- &ProxyResolverMojo::Job::OnConnectionError, base::Unretained(this)));
-
interfaces::ProxyResolverRequestClientPtr client_ptr;
binding_.Bind(mojo::GetProxy(&client_ptr));
+ binding_.set_connection_error_handler(base::Bind(
+ &ProxyResolverMojo::Job::OnConnectionError, base::Unretained(this)));
resolver_->mojo_proxy_resolver_ptr_->GetProxyForUrl(mojo::String::From(url_),
- client_ptr.Pass());
+ std::move(client_ptr));
}
ProxyResolverMojo::Job::~Job() {
@@ -251,11 +252,11 @@ ProxyResolverMojo::ProxyResolverMojo(
scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner,
scoped_ptr<ProxyResolverErrorObserver> error_observer,
NetLog* net_log)
- : mojo_proxy_resolver_ptr_(resolver_ptr.Pass()),
+ : mojo_proxy_resolver_ptr_(std::move(resolver_ptr)),
host_resolver_(host_resolver),
- error_observer_(error_observer.Pass()),
+ error_observer_(std::move(error_observer)),
net_log_(net_log),
- on_delete_callback_runner_(on_delete_callback_runner.Pass()) {
+ on_delete_callback_runner_(std::move(on_delete_callback_runner)) {
mojo_proxy_resolver_ptr_.set_connection_error_handler(base::Bind(
&ProxyResolverMojo::OnConnectionError, base::Unretained(this)));
}
@@ -338,12 +339,12 @@ class ProxyResolverFactoryMojo::Job
resolver_(resolver),
callback_(callback),
binding_(this),
- error_observer_(error_observer.Pass()) {
+ error_observer_(std::move(error_observer)) {
interfaces::ProxyResolverFactoryRequestClientPtr client_ptr;
binding_.Bind(mojo::GetProxy(&client_ptr));
on_delete_callback_runner_ = factory_->mojo_proxy_factory_->CreateResolver(
mojo::String::From(pac_script->utf16()), mojo::GetProxy(&resolver_ptr_),
- client_ptr.Pass());
+ std::move(client_ptr));
resolver_ptr_.set_connection_error_handler(
base::Bind(&ProxyResolverFactoryMojo::Job::OnConnectionError,
base::Unretained(this)));
@@ -359,10 +360,10 @@ class ProxyResolverFactoryMojo::Job
resolver_ptr_.set_connection_error_handler(mojo::Closure());
binding_.set_connection_error_handler(mojo::Closure());
if (error == OK) {
- resolver_->reset(
- new ProxyResolverMojo(resolver_ptr_.Pass(), factory_->host_resolver_,
- on_delete_callback_runner_.Pass(),
- error_observer_.Pass(), factory_->net_log_));
+ resolver_->reset(new ProxyResolverMojo(
+ std::move(resolver_ptr_), factory_->host_resolver_,
+ std::move(on_delete_callback_runner_), std::move(error_observer_),
+ factory_->net_log_));
}
on_delete_callback_runner_.reset();
callback_.Run(error);
diff --git a/chromium/net/proxy/proxy_resolver_factory_mojo.h b/chromium/net/proxy/proxy_resolver_factory_mojo.h
index 65e4866a99b..f3e8483c793 100644
--- a/chromium/net/proxy/proxy_resolver_factory_mojo.h
+++ b/chromium/net/proxy/proxy_resolver_factory_mojo.h
@@ -5,11 +5,12 @@
#ifndef NET_PROXY_PROXY_RESOLVER_FACTORY_MOJO_H_
#define NET_PROXY_PROXY_RESOLVER_FACTORY_MOJO_H_
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/completion_callback.h"
#include "net/proxy/proxy_resolver_factory.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
namespace net {
class HostResolver;
diff --git a/chromium/net/proxy/proxy_resolver_factory_mojo_unittest.cc b/chromium/net/proxy/proxy_resolver_factory_mojo_unittest.cc
index d0fd4ec1e59..9fa4ef587ec 100644
--- a/chromium/net/proxy/proxy_resolver_factory_mojo_unittest.cc
+++ b/chromium/net/proxy/proxy_resolver_factory_mojo_unittest.cc
@@ -8,14 +8,16 @@
#include <map>
#include <queue>
#include <string>
+#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "mojo/common/common_type_converters.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
@@ -29,7 +31,6 @@
#include "net/proxy/proxy_resolver_script_data.h"
#include "net/test/event_waiter.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
#include "url/gurl.h"
namespace net {
@@ -201,7 +202,8 @@ class MockMojoProxyResolver : public interfaces::ProxyResolver {
base::Closure quit_closure_;
- ScopedVector<interfaces::ProxyResolverRequestClientPtr> blocked_clients_;
+ std::vector<scoped_ptr<interfaces::ProxyResolverRequestClientPtr>>
+ blocked_clients_;
mojo::Binding<interfaces::ProxyResolver> binding_;
};
@@ -237,7 +239,7 @@ void MockMojoProxyResolver::AddConnection(
mojo::InterfaceRequest<interfaces::ProxyResolver> req) {
if (binding_.is_bound())
binding_.Close();
- binding_.Bind(req.Pass());
+ binding_.Bind(std::move(req));
}
void MockMojoProxyResolver::GetProxyForUrl(
@@ -252,7 +254,7 @@ void MockMojoProxyResolver::GetProxyForUrl(
client->OnError(12345, url);
switch (action.action) {
case GetProxyForUrlAction::COMPLETE: {
- client->ReportResult(action.error, action.proxy_servers.Pass());
+ client->ReportResult(action.error, std::move(action.proxy_servers));
break;
}
case GetProxyForUrlAction::DROP: {
@@ -274,9 +276,9 @@ void MockMojoProxyResolver::GetProxyForUrl(
request->port = 12345;
interfaces::HostResolverRequestClientPtr dns_client;
mojo::GetProxy(&dns_client);
- client->ResolveDns(request.Pass(), dns_client.Pass());
- blocked_clients_.push_back(
- new interfaces::ProxyResolverRequestClientPtr(client.Pass()));
+ client->ResolveDns(std::move(request), std::move(dns_client));
+ blocked_clients_.push_back(make_scoped_ptr(
+ new interfaces::ProxyResolverRequestClientPtr(std::move(client))));
break;
}
}
@@ -291,7 +293,6 @@ class Request {
void Cancel();
int WaitForResult();
- int error() const { return error_; }
const ProxyInfo& results() const { return results_; }
LoadState load_state() { return resolver_->GetLoadState(handle_); }
BoundTestNetLog& net_log() { return net_log_; }
@@ -352,9 +353,9 @@ class MockMojoProxyResolverFactory : public interfaces::ProxyResolverFactory {
base::Closure quit_closure_;
- ScopedVector<interfaces::ProxyResolverFactoryRequestClientPtr>
+ std::vector<scoped_ptr<interfaces::ProxyResolverFactoryRequestClientPtr>>
blocked_clients_;
- ScopedVector<mojo::InterfaceRequest<interfaces::ProxyResolver>>
+ std::vector<scoped_ptr<mojo::InterfaceRequest<interfaces::ProxyResolver>>>
blocked_resolver_requests_;
mojo::Binding<interfaces::ProxyResolverFactory> binding_;
};
@@ -362,8 +363,7 @@ class MockMojoProxyResolverFactory : public interfaces::ProxyResolverFactory {
MockMojoProxyResolverFactory::MockMojoProxyResolverFactory(
MockMojoProxyResolver* resolver,
mojo::InterfaceRequest<interfaces::ProxyResolverFactory> req)
- : resolver_(resolver), binding_(this, req.Pass()) {
-}
+ : resolver_(resolver), binding_(this, std::move(req)) {}
MockMojoProxyResolverFactory::~MockMojoProxyResolverFactory() {
EXPECT_TRUE(create_resolver_actions_.empty())
@@ -405,21 +405,22 @@ void MockMojoProxyResolverFactory::CreateResolver(
switch (action.action) {
case CreateProxyResolverAction::COMPLETE: {
if (action.error == OK)
- resolver_->AddConnection(request.Pass());
+ resolver_->AddConnection(std::move(request));
client->ReportResult(action.error);
break;
}
case CreateProxyResolverAction::DROP_CLIENT: {
// Save |request| so its pipe isn't closed.
blocked_resolver_requests_.push_back(
- new mojo::InterfaceRequest<interfaces::ProxyResolver>(
- request.Pass()));
+ make_scoped_ptr(new mojo::InterfaceRequest<interfaces::ProxyResolver>(
+ std::move(request))));
break;
}
case CreateProxyResolverAction::DROP_RESOLVER: {
// Save |client| so its pipe isn't closed.
blocked_clients_.push_back(
- new interfaces::ProxyResolverFactoryRequestClientPtr(client.Pass()));
+ make_scoped_ptr(new interfaces::ProxyResolverFactoryRequestClientPtr(
+ std::move(client))));
break;
}
case CreateProxyResolverAction::DROP_BOTH: {
@@ -437,9 +438,10 @@ void MockMojoProxyResolverFactory::CreateResolver(
request->port = 12345;
interfaces::HostResolverRequestClientPtr dns_client;
mojo::GetProxy(&dns_client);
- client->ResolveDns(request.Pass(), dns_client.Pass());
+ client->ResolveDns(std::move(request), std::move(dns_client));
blocked_clients_.push_back(
- new interfaces::ProxyResolverFactoryRequestClientPtr(client.Pass()));
+ make_scoped_ptr(new interfaces::ProxyResolverFactoryRequestClientPtr(
+ std::move(client))));
break;
}
}
@@ -524,7 +526,7 @@ class ProxyResolverFactoryMojoTest : public testing::Test,
const mojo::String& pac_script,
mojo::InterfaceRequest<interfaces::ProxyResolver> req,
interfaces::ProxyResolverFactoryRequestClientPtr client) override {
- factory_ptr_->CreateResolver(pac_script, req.Pass(), client.Pass());
+ factory_ptr_->CreateResolver(pac_script, std::move(req), std::move(client));
return make_scoped_ptr(
new base::ScopedClosureRunner(on_delete_callback_.closure()));
}
@@ -566,8 +568,8 @@ class ProxyResolverFactoryMojoTest : public testing::Test,
scoped_ptr<ProxyResolverFactory> proxy_resolver_factory_mojo_;
MockMojoProxyResolver mock_proxy_resolver_;
- scoped_ptr<ProxyResolver> proxy_resolver_mojo_;
TestClosure on_delete_callback_;
+ scoped_ptr<ProxyResolver> proxy_resolver_mojo_;
};
TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver) {
diff --git a/chromium/net/proxy/proxy_resolver_mac.h b/chromium/net/proxy/proxy_resolver_mac.h
index 6d89ef539d5..f8650212209 100644
--- a/chromium/net/proxy/proxy_resolver_mac.h
+++ b/chromium/net/proxy/proxy_resolver_mac.h
@@ -6,6 +6,7 @@
#define NET_PROXY_PROXY_RESOLVER_MAC_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/proxy/proxy_resolver_factory.h"
#include "url/gurl.h"
diff --git a/chromium/net/proxy/proxy_resolver_perftest.cc b/chromium/net/proxy/proxy_resolver_perftest.cc
index 939018150bb..7aae5b21b38 100644
--- a/chromium/net/proxy/proxy_resolver_perftest.cc
+++ b/chromium/net/proxy/proxy_resolver_perftest.cc
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/base_paths.h"
#include "base/compiler_specific.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
@@ -15,7 +18,7 @@
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_resolver_factory.h"
#include "net/proxy/proxy_resolver_v8.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_WIN)
@@ -90,12 +93,10 @@ class PacPerfSuiteRunner {
// |resolver_name| is the label used when logging the results.
PacPerfSuiteRunner(ProxyResolverFactory* factory,
const std::string& resolver_name)
- : factory_(factory),
- resolver_name_(resolver_name),
- test_server_(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL(
- "net/data/proxy_resolver_perftest"))) {}
+ : factory_(factory), resolver_name_(resolver_name) {
+ test_server_.ServeFilesFromSourceDirectory(
+ "net/data/proxy_resolver_perftest");
+ }
void RunAllTests() {
ASSERT_TRUE(test_server_.Start());
@@ -113,8 +114,7 @@ class PacPerfSuiteRunner {
int queries_len) {
scoped_ptr<ProxyResolver> resolver;
if (!factory_->expects_pac_bytes()) {
- GURL pac_url =
- test_server_.GetURL(std::string("files/") + script_name);
+ GURL pac_url = test_server_.GetURL(std::string("/") + script_name);
int rv = factory_->CreateProxyResolver(
ProxyResolverScriptData::FromURL(pac_url), &resolver,
CompletionCallback(), nullptr);
@@ -189,7 +189,7 @@ class PacPerfSuiteRunner {
ProxyResolverFactory* factory_;
std::string resolver_name_;
- SpawnedTestServer test_server_;
+ EmbeddedTestServer test_server_;
};
#if defined(OS_WIN)
@@ -229,7 +229,7 @@ class ProxyResolverV8Wrapper : public ProxyResolver {
public:
ProxyResolverV8Wrapper(scoped_ptr<ProxyResolverV8> resolver,
scoped_ptr<MockJSBindings> bindings)
- : resolver_(resolver.Pass()), bindings_(bindings.Pass()) {}
+ : resolver_(std::move(resolver)), bindings_(std::move(bindings)) {}
int GetProxyForURL(const GURL& url,
ProxyInfo* results,
@@ -266,8 +266,8 @@ class ProxyResolverV8Factory : public ProxyResolverFactory {
int result =
ProxyResolverV8::Create(pac_script, js_bindings_.get(), &v8_resolver);
if (result == OK) {
- resolver->reset(
- new ProxyResolverV8Wrapper(v8_resolver.Pass(), js_bindings_.Pass()));
+ resolver->reset(new ProxyResolverV8Wrapper(std::move(v8_resolver),
+ std::move(js_bindings_)));
}
return result;
}
diff --git a/chromium/net/proxy/proxy_resolver_v8.cc b/chromium/net/proxy/proxy_resolver_v8.cc
index 73f0428a2cf..80ae06b7e55 100644
--- a/chromium/net/proxy/proxy_resolver_v8.cc
+++ b/chromium/net/proxy/proxy_resolver_v8.cc
@@ -6,13 +6,14 @@
#include <algorithm>
#include <cstdio>
+#include <utility>
#include "base/auto_reset.h"
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/debug/leak_annotations.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -97,7 +98,7 @@ class V8ExternalStringFromScriptData
: script_data_(script_data) {}
const uint16_t* data() const override {
- return reinterpret_cast<const uint16*>(script_data_->utf16().data());
+ return reinterpret_cast<const uint16_t*>(script_data_->utf16().data());
}
size_t length() const override { return script_data_->utf16().size(); }
@@ -372,8 +373,16 @@ class SharedIsolateFactory {
gin::V8Initializer::LoadV8Natives();
#endif
+ // The performance of the proxy resolver is limited by DNS resolution,
+ // and not V8, so tune down V8 to use as little memory as possible.
+ static const char kOptimizeForSize[] = "--optimize_for_size";
+ v8::V8::SetFlagsFromString(kOptimizeForSize, strlen(kOptimizeForSize));
+ static const char kNoOpt[] = "--noopt";
+ v8::V8::SetFlagsFromString(kNoOpt, strlen(kNoOpt));
+
gin::IsolateHolder::Initialize(
gin::IsolateHolder::kNonStrictMode,
+ gin::IsolateHolder::kStableV8Extras,
gin::ArrayBufferAllocator::SharedInstance());
has_initialized_v8_ = true;
@@ -825,7 +834,7 @@ class ProxyResolverV8::Context {
// ProxyResolverV8 ------------------------------------------------------------
ProxyResolverV8::ProxyResolverV8(scoped_ptr<Context> context)
- : context_(context.Pass()) {
+ : context_(std::move(context)) {
DCHECK(context_);
}
@@ -853,7 +862,7 @@ int ProxyResolverV8::Create(
new Context(g_isolate_factory.Get().GetSharedIsolate()));
int rv = context->InitV8(script_data, js_bindings);
if (rv == OK)
- resolver->reset(new ProxyResolverV8(context.Pass()));
+ resolver->reset(new ProxyResolverV8(std::move(context)));
return rv;
}
diff --git a/chromium/net/proxy/proxy_resolver_v8.h b/chromium/net/proxy/proxy_resolver_v8.h
index 98746ac0279..abd2e94a413 100644
--- a/chromium/net/proxy/proxy_resolver_v8.h
+++ b/chromium/net/proxy/proxy_resolver_v8.h
@@ -5,7 +5,10 @@
#ifndef NET_PROXY_PROXY_RESOLVER_V8_H_
#define NET_PROXY_PROXY_RESOLVER_V8_H_
+#include <stddef.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing.cc b/chromium/net/proxy/proxy_resolver_v8_tracing.cc
index 27cf5f7b788..94ad9f0d6c4 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing.cc
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing.cc
@@ -6,9 +6,11 @@
#include <map>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/cancellation_flag.h"
@@ -331,7 +333,7 @@ Job::Job(const Job::Params* params,
scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings)
: origin_runner_(base::ThreadTaskRunnerHandle::Get()),
params_(params),
- bindings_(bindings.Pass()),
+ bindings_(std::move(bindings)),
event_(true, false),
last_num_dns_(0),
pending_dns_(NULL) {
@@ -553,7 +555,7 @@ int Job::ExecuteProxyResolver() {
scoped_ptr<ProxyResolverV8> resolver;
result = ProxyResolverV8::Create(script_data_, this, &resolver);
if (result == OK)
- *resolver_out_ = resolver.Pass();
+ *resolver_out_ = std::move(resolver);
break;
}
case GET_PROXY_FOR_URL: {
@@ -916,9 +918,9 @@ ProxyResolverV8TracingImpl::ProxyResolverV8TracingImpl(
scoped_ptr<base::Thread> thread,
scoped_ptr<ProxyResolverV8> resolver,
scoped_ptr<Job::Params> job_params)
- : thread_(thread.Pass()),
- v8_resolver_(resolver.Pass()),
- job_params_(job_params.Pass()),
+ : thread_(std::move(thread)),
+ v8_resolver_(std::move(resolver)),
+ job_params_(std::move(job_params)),
num_outstanding_callbacks_(0) {
job_params_->num_outstanding_callbacks = &num_outstanding_callbacks_;
}
@@ -941,7 +943,7 @@ void ProxyResolverV8TracingImpl::GetProxyForURL(
DCHECK(CalledOnValidThread());
DCHECK(!callback.is_null());
- scoped_refptr<Job> job = new Job(job_params_.get(), bindings.Pass());
+ scoped_refptr<Job> job = new Job(job_params_.get(), std::move(bindings));
if (request)
*request = job.get();
@@ -1002,7 +1004,7 @@ class ProxyResolverV8TracingFactoryImpl::CreateJob
CHECK(thread_->StartWithOptions(options));
job_params_.reset(
new Job::Params(thread_->task_runner(), &num_outstanding_callbacks_));
- create_resolver_job_ = new Job(job_params_.get(), bindings.Pass());
+ create_resolver_job_ = new Job(job_params_.get(), std::move(bindings));
create_resolver_job_->StartCreateV8Resolver(
pac_script, &v8_resolver_,
base::Bind(
@@ -1033,7 +1035,7 @@ class ProxyResolverV8TracingFactoryImpl::CreateJob
if (error == OK) {
job_params_->v8_resolver = v8_resolver_.get();
resolver_out_->reset(new ProxyResolverV8TracingImpl(
- thread_.Pass(), v8_resolver_.Pass(), job_params_.Pass()));
+ std::move(thread_), std::move(v8_resolver_), std::move(job_params_)));
} else {
StopWorkerThread();
}
@@ -1078,9 +1080,9 @@ void ProxyResolverV8TracingFactoryImpl::CreateProxyResolverV8Tracing(
const CompletionCallback& callback,
scoped_ptr<ProxyResolverFactory::Request>* request) {
scoped_ptr<CreateJob> job(
- new CreateJob(this, bindings.Pass(), pac_script, resolver, callback));
+ new CreateJob(this, std::move(bindings), pac_script, resolver, callback));
jobs_.insert(job.get());
- *request = job.Pass();
+ *request = std::move(job);
}
void ProxyResolverV8TracingFactoryImpl::RemoveJob(
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing.h b/chromium/net/proxy/proxy_resolver_v8_tracing.h
index cd9ae6c8eff..f5f66cf7486 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing.h
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing.h
@@ -5,7 +5,7 @@
#ifndef NET_PROXY_PROXY_RESOLVER_V8_TRACING_H_
#define NET_PROXY_PROXY_RESOLVER_V8_TRACING_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc b/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc
index 3bec37031d8..888dd18af57 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc
@@ -5,6 +5,7 @@
#include "net/proxy/proxy_resolver_v8_tracing.h"
#include <string>
+#include <utility>
#include "base/files/file_util.h"
#include "base/path_service.h"
@@ -142,11 +143,11 @@ scoped_ptr<ProxyResolverV8Tracing> CreateResolver(
TestCompletionCallback callback;
scoped_ptr<ProxyResolverFactory::Request> request;
factory->CreateProxyResolverV8Tracing(LoadScriptData(filename),
- bindings.Pass(), &resolver,
+ std::move(bindings), &resolver,
callback.callback(), &request);
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(resolver);
- return resolver.Pass();
+ return resolver;
}
TEST_F(ProxyResolverV8TracingTest, Simple) {
@@ -688,7 +689,7 @@ class BlockableHostResolver : public HostResolver {
// Indicate to the caller that a request was received.
EXPECT_TRUE(waiting_for_resolve_);
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
// This line is intentionally after action_.Run(), since one of the
// tests does a cancellation inside of Resolve(), and it is more
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.cc b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.cc
index 01dde664872..25144b61813 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.cc
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.cc
@@ -5,8 +5,10 @@
#include "net/proxy/proxy_resolver_v8_tracing_wrapper.h"
#include <string>
+#include <utility>
#include "base/bind.h"
+#include "base/macros.h"
#include "base/values.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
@@ -23,7 +25,7 @@ scoped_ptr<base::Value> NetLogErrorCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("line_number", line_number);
dict->SetString("message", *message);
- return dict.Pass();
+ return std::move(dict);
}
class BindingsImpl : public ProxyResolverV8Tracing::Bindings {
@@ -107,11 +109,10 @@ ProxyResolverV8TracingWrapper::ProxyResolverV8TracingWrapper(
NetLog* net_log,
HostResolver* host_resolver,
scoped_ptr<ProxyResolverErrorObserver> error_observer)
- : resolver_impl_(resolver_impl.Pass()),
+ : resolver_impl_(std::move(resolver_impl)),
net_log_(net_log),
host_resolver_(host_resolver),
- error_observer_(error_observer.Pass()) {
-}
+ error_observer_(std::move(error_observer)) {}
int ProxyResolverV8TracingWrapper::GetProxyForURL(
const GURL& url,
@@ -185,7 +186,8 @@ void ProxyResolverFactoryV8TracingWrapper::OnProxyResolverCreated(
int error) {
if (error == OK) {
resolver->reset(new ProxyResolverV8TracingWrapper(
- v8_resolver->Pass(), net_log_, host_resolver_, error_observer.Pass()));
+ std::move(*v8_resolver), net_log_, host_resolver_,
+ std::move(error_observer)));
}
callback.Run(error);
}
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.h b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.h
index 28343d80736..000f94db1c3 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.h
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper.h
@@ -5,7 +5,7 @@
#ifndef NET_PROXY_PROXY_RESOLVER_V8_TRACING_WRAPPER_H_
#define NET_PROXY_PROXY_RESOLVER_V8_TRACING_WRAPPER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
index c83f6553796..946d4bf47a3 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
@@ -84,7 +84,7 @@ scoped_ptr<ProxyResolver> CreateResolver(
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(resolver);
- return resolver.Pass();
+ return resolver;
}
class MockErrorObserver : public ProxyResolverErrorObserver {
@@ -774,7 +774,7 @@ class BlockableHostResolver : public HostResolver {
// Indicate to the caller that a request was received.
EXPECT_TRUE(waiting_for_resolve_);
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
// This line is intentionally after action_.Run(), since one of the
// tests does a cancellation inside of Resolve(), and it is more
diff --git a/chromium/net/proxy/proxy_resolver_winhttp.cc b/chromium/net/proxy/proxy_resolver_winhttp.cc
index bfdce33252f..7dccbf0b93c 100644
--- a/chromium/net/proxy/proxy_resolver_winhttp.cc
+++ b/chromium/net/proxy/proxy_resolver_winhttp.cc
@@ -7,6 +7,7 @@
#include <windows.h>
#include <winhttp.h>
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
diff --git a/chromium/net/proxy/proxy_resolver_winhttp.h b/chromium/net/proxy/proxy_resolver_winhttp.h
index 843711caca1..c6e8ac5ebdb 100644
--- a/chromium/net/proxy/proxy_resolver_winhttp.h
+++ b/chromium/net/proxy/proxy_resolver_winhttp.h
@@ -6,6 +6,7 @@
#define NET_PROXY_PROXY_RESOLVER_WINHTTP_H_
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/proxy/proxy_resolver_factory.h"
#include "url/gurl.h"
diff --git a/chromium/net/proxy/proxy_script_decider.cc b/chromium/net/proxy/proxy_script_decider.cc
index f30c162a06b..d131725cc8f 100644
--- a/chromium/net/proxy/proxy_script_decider.cc
+++ b/chromium/net/proxy/proxy_script_decider.cc
@@ -4,6 +4,8 @@
#include "net/proxy/proxy_script_decider.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
@@ -72,7 +74,7 @@ scoped_ptr<base::Value> ProxyScriptDecider::PacSource::NetLogCallback(
break;
}
dict->SetString("source", source);
- return dict.Pass();
+ return std::move(dict);
}
ProxyScriptDecider::ProxyScriptDecider(
diff --git a/chromium/net/proxy/proxy_script_decider.h b/chromium/net/proxy/proxy_script_decider.h
index cf5edff54f4..60cb24b0806 100644
--- a/chromium/net/proxy/proxy_script_decider.h
+++ b/chromium/net/proxy/proxy_script_decider.h
@@ -5,9 +5,12 @@
#ifndef NET_PROXY_PROXY_SCRIPT_DECIDER_H_
#define NET_PROXY_PROXY_SCRIPT_DECIDER_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
diff --git a/chromium/net/proxy/proxy_script_decider_unittest.cc b/chromium/net/proxy/proxy_script_decider_unittest.cc
index cc320a432af..33e8aa505d7 100644
--- a/chromium/net/proxy/proxy_script_decider_unittest.cc
+++ b/chromium/net/proxy/proxy_script_decider_unittest.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
diff --git a/chromium/net/proxy/proxy_script_fetcher_impl.h b/chromium/net/proxy/proxy_script_fetcher_impl.h
index b02c9fc5db7..fe0bf33d772 100644
--- a/chromium/net/proxy/proxy_script_fetcher_impl.h
+++ b/chromium/net/proxy/proxy_script_fetcher_impl.h
@@ -5,10 +5,12 @@
#ifndef NET_PROXY_PROXY_SCRIPT_FETCHER_IMPL_H_
#define NET_PROXY_PROXY_SCRIPT_FETCHER_IMPL_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc b/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc
index 62a332bdcf8..a230ab34ae8 100644
--- a/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc
+++ b/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -5,9 +5,11 @@
#include "net/proxy/proxy_script_fetcher_impl.h"
#include <string>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/path_service.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
@@ -24,7 +26,7 @@
#include "net/http/http_server_properties_impl.h"
#include "net/http/transport_security_state.h"
#include "net/ssl/ssl_config_service_defaults.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.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"
@@ -76,12 +78,11 @@ class RequestContext : public URLRequestContext {
params.proxy_service = proxy_service();
params.ssl_config_service = ssl_config_service();
params.http_server_properties = http_server_properties();
- scoped_refptr<HttpNetworkSession> network_session(
- new HttpNetworkSession(params));
- storage_.set_http_transaction_factory(
- make_scoped_ptr(new HttpCache(network_session.get(),
- HttpCache::DefaultBackend::InMemory(0)))
- .Pass());
+ storage_.set_http_network_session(
+ make_scoped_ptr(new HttpNetworkSession(params)));
+ storage_.set_http_transaction_factory(make_scoped_ptr(
+ new HttpCache(storage_.http_network_session(),
+ HttpCache::DefaultBackend::InMemory(0), false)));
scoped_ptr<URLRequestJobFactoryImpl> job_factory =
make_scoped_ptr(new URLRequestJobFactoryImpl());
#if !defined(DISABLE_FILE_SUPPORT)
@@ -89,7 +90,7 @@ class RequestContext : public URLRequestContext {
make_scoped_ptr(new FileProtocolHandler(
base::ThreadTaskRunnerHandle::Get())));
#endif
- storage_.set_job_factory(job_factory.Pass());
+ storage_.set_job_factory(std::move(job_factory));
}
~RequestContext() override { AssertNoURLRequests(); }
@@ -187,15 +188,13 @@ class BasicNetworkDelegate : public NetworkDelegateImpl {
class ProxyScriptFetcherImplTest : public PlatformTest {
public:
- ProxyScriptFetcherImplTest()
- : test_server_(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath(kDocRoot)) {
+ ProxyScriptFetcherImplTest() {
+ test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
context_.set_network_delegate(&network_delegate_);
}
protected:
- SpawnedTestServer test_server_;
+ EmbeddedTestServer test_server_;
BasicNetworkDelegate network_delegate_;
RequestContext context_;
};
@@ -233,7 +232,7 @@ TEST_F(ProxyScriptFetcherImplTest, HttpMimeType) {
ProxyScriptFetcherImpl pac_fetcher(&context_);
{ // Fetch a PAC with mime type "text/plain"
- GURL url(test_server_.GetURL("files/pac.txt"));
+ GURL url(test_server_.GetURL("/pac.txt"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -242,7 +241,7 @@ TEST_F(ProxyScriptFetcherImplTest, HttpMimeType) {
EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
}
{ // Fetch a PAC with mime type "text/html"
- GURL url(test_server_.GetURL("files/pac.html"));
+ GURL url(test_server_.GetURL("/pac.html"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -251,7 +250,7 @@ TEST_F(ProxyScriptFetcherImplTest, HttpMimeType) {
EXPECT_EQ(ASCIIToUTF16("-pac.html-\n"), text);
}
{ // Fetch a PAC with mime type "application/x-ns-proxy-autoconfig"
- GURL url(test_server_.GetURL("files/pac.nsproxy"));
+ GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -267,7 +266,7 @@ TEST_F(ProxyScriptFetcherImplTest, HttpStatusCode) {
ProxyScriptFetcherImpl pac_fetcher(&context_);
{ // Fetch a PAC which gives a 500 -- FAIL
- GURL url(test_server_.GetURL("files/500.pac"));
+ GURL url(test_server_.GetURL("/500.pac"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -276,7 +275,7 @@ TEST_F(ProxyScriptFetcherImplTest, HttpStatusCode) {
EXPECT_TRUE(text.empty());
}
{ // Fetch a PAC which gives a 404 -- FAIL
- GURL url(test_server_.GetURL("files/404.pac"));
+ GURL url(test_server_.GetURL("/404.pac"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -293,7 +292,7 @@ TEST_F(ProxyScriptFetcherImplTest, ContentDisposition) {
// Fetch PAC scripts via HTTP with a Content-Disposition header -- should
// have no effect.
- GURL url(test_server_.GetURL("files/downloadable.pac"));
+ GURL url(test_server_.GetURL("/downloadable.pac"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -309,7 +308,7 @@ TEST_F(ProxyScriptFetcherImplTest, NoCache) {
ProxyScriptFetcherImpl pac_fetcher(&context_);
// Fetch a PAC script whose HTTP headers make it cacheable for 1 hour.
- GURL url(test_server_.GetURL("files/cacheable_1hr.pac"));
+ GURL url(test_server_.GetURL("/cacheable_1hr.pac"));
{
base::string16 text;
TestCompletionCallback callback;
@@ -320,7 +319,7 @@ TEST_F(ProxyScriptFetcherImplTest, NoCache) {
}
// Kill the HTTP server.
- ASSERT_TRUE(test_server_.Stop());
+ ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
// Try to fetch the file again. Since the server is not running anymore, the
// call should fail, thus indicating that the file was not fetched from the
@@ -346,7 +345,7 @@ TEST_F(ProxyScriptFetcherImplTest, TooLarge) {
// These two URLs are the same file, but are http:// vs file://
GURL urls[] = {
- test_server_.GetURL("files/large-pac.nsproxy"),
+ test_server_.GetURL("/large-pac.nsproxy"),
#if !defined(DISABLE_FILE_SUPPORT)
GetTestFileUrl("large-pac.nsproxy")
#endif
@@ -368,7 +367,7 @@ TEST_F(ProxyScriptFetcherImplTest, TooLarge) {
pac_fetcher.SetSizeConstraint(prev_size);
{ // Make sure we can still fetch regular URLs.
- GURL url(test_server_.GetURL("files/pac.nsproxy"));
+ GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -390,7 +389,7 @@ TEST_F(ProxyScriptFetcherImplTest, Hang) {
// Try fetching a URL which takes 1.2 seconds. We should abort the request
// after 500 ms, and fail with a timeout error.
{
- GURL url(test_server_.GetURL("slow/proxy.pac?1.2"));
+ GURL url(test_server_.GetURL("/slow/proxy.pac?1.2"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -403,7 +402,7 @@ TEST_F(ProxyScriptFetcherImplTest, Hang) {
pac_fetcher.SetTimeoutConstraint(prev_timeout);
{ // Make sure we can still fetch regular URLs.
- GURL url(test_server_.GetURL("files/pac.nsproxy"));
+ GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -423,7 +422,7 @@ TEST_F(ProxyScriptFetcherImplTest, Encodings) {
// Test a response that is gzip-encoded -- should get inflated.
{
- GURL url(test_server_.GetURL("files/gzipped_pac"));
+ GURL url(test_server_.GetURL("/gzipped_pac"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
@@ -435,7 +434,7 @@ TEST_F(ProxyScriptFetcherImplTest, Encodings) {
// Test a response that was served as UTF-16 (BE). It should
// be converted to UTF8.
{
- GURL url(test_server_.GetURL("files/utf16be_pac"));
+ GURL url(test_server_.GetURL("/utf16be_pac"));
base::string16 text;
TestCompletionCallback callback;
int result = pac_fetcher.Fetch(url, &text, callback.callback());
diff --git a/chromium/net/proxy/proxy_server.cc b/chromium/net/proxy/proxy_server.cc
index e451265cbb9..d3ba5ba1e67 100644
--- a/chromium/net/proxy/proxy_server.cc
+++ b/chromium/net/proxy/proxy_server.cc
@@ -6,7 +6,6 @@
#include <algorithm>
-#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "net/base/net_util.h"
#include "net/http/http_util.h"
@@ -236,7 +235,7 @@ ProxyServer ProxyServer::FromSchemeHostAndPort(
if (port == -1)
port = GetDefaultPortForScheme(scheme);
- host_port_pair = HostPortPair(host, static_cast<uint16>(port));
+ host_port_pair = HostPortPair(host, static_cast<uint16_t>(port));
}
return ProxyServer(scheme, host_port_pair);
diff --git a/chromium/net/proxy/proxy_server.h b/chromium/net/proxy/proxy_server.h
index 1ff65367285..12ec217506e 100644
--- a/chromium/net/proxy/proxy_server.h
+++ b/chromium/net/proxy/proxy_server.h
@@ -12,6 +12,8 @@
#endif
#include <string>
+#include <tuple>
+
#include "net/base/host_port_pair.h"
#include "net/base/net_export.h"
@@ -149,9 +151,8 @@ class NET_EXPORT ProxyServer {
// Comparator function so this can be placed in a std::map.
bool operator<(const ProxyServer& other) const {
- if (scheme_ != other.scheme_)
- return scheme_ < other.scheme_;
- return host_port_pair_ < other.host_port_pair_;
+ return std::tie(scheme_, host_port_pair_) <
+ std::tie(other.scheme_, other.host_port_pair_);
}
private:
diff --git a/chromium/net/proxy/proxy_server_unittest.cc b/chromium/net/proxy/proxy_server_unittest.cc
index 25ad4345c63..3589517b2d9 100644
--- a/chromium/net/proxy/proxy_server_unittest.cc
+++ b/chromium/net/proxy/proxy_server_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 "base/basictypes.h"
+#include "base/macros.h"
#include "net/proxy/proxy_server.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/proxy/proxy_service.cc b/chromium/net/proxy/proxy_service.cc
index 2beb7e8c816..2c30f745290 100644
--- a/chromium/net/proxy/proxy_service.cc
+++ b/chromium/net/proxy/proxy_service.cc
@@ -5,12 +5,14 @@
#include "net/proxy/proxy_service.h"
#include <algorithm>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
@@ -74,7 +76,7 @@ namespace {
// set up. Network failures can happen at any time though, so we additionally
// poll the PAC script for changes, which will allow us to recover from these
// sorts of problems.
-const int64 kDelayAfterNetworkChangesMs = 2000;
+const int64_t kDelayAfterNetworkChangesMs = 2000;
// This is the default policy for polling the PAC script.
//
@@ -302,7 +304,7 @@ scoped_ptr<base::Value> NetLogProxyConfigChangedCallback(
if (old_config->is_valid())
dict->Set("old_config", old_config->ToValue());
dict->Set("new_config", new_config->ToValue());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogBadProxyListCallback(
@@ -316,7 +318,7 @@ scoped_ptr<base::Value> NetLogBadProxyListCallback(
list->Append(new base::StringValue(iter->first));
}
dict->Set("bad_proxy_list", list);
- return dict.Pass();
+ return std::move(dict);
}
// Returns NetLog parameters on a successfuly proxy resolution.
@@ -325,7 +327,7 @@ scoped_ptr<base::Value> NetLogFinishedResolvingProxyCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("pac_string", result->ToPacString());
- return dict.Pass();
+ return std::move(dict);
}
#if defined(OS_CHROMEOS)
@@ -922,7 +924,7 @@ class ProxyService::PacRequest
ProxyService::ProxyService(scoped_ptr<ProxyConfigService> config_service,
scoped_ptr<ProxyResolverFactory> resolver_factory,
NetLog* net_log)
- : resolver_factory_(resolver_factory.Pass()),
+ : resolver_factory_(std::move(resolver_factory)),
next_config_id_(1),
current_state_(STATE_NONE),
net_log_(net_log),
@@ -931,7 +933,7 @@ ProxyService::ProxyService(scoped_ptr<ProxyConfigService> config_service,
quick_check_enabled_(true) {
NetworkChangeNotifier::AddIPAddressObserver(this);
NetworkChangeNotifier::AddDNSObserver(this);
- ResetConfigService(config_service.Pass());
+ ResetConfigService(std::move(config_service));
}
// static
@@ -943,14 +945,14 @@ scoped_ptr<ProxyService> ProxyService::CreateUsingSystemProxyResolver(
if (!ProxyResolverFactoryForSystem::IsSupported()) {
VLOG(1) << "PAC support disabled because there is no system implementation";
- return CreateWithoutProxyResolver(proxy_config_service.Pass(), net_log);
+ return CreateWithoutProxyResolver(std::move(proxy_config_service), net_log);
}
if (num_pac_threads == 0)
num_pac_threads = kDefaultNumPacThreads;
return make_scoped_ptr(new ProxyService(
- proxy_config_service.Pass(),
+ std::move(proxy_config_service),
make_scoped_ptr(new ProxyResolverFactoryForSystem(num_pac_threads)),
net_log));
}
@@ -960,7 +962,7 @@ scoped_ptr<ProxyService> ProxyService::CreateWithoutProxyResolver(
scoped_ptr<ProxyConfigService> proxy_config_service,
NetLog* net_log) {
return make_scoped_ptr(new ProxyService(
- proxy_config_service.Pass(),
+ std::move(proxy_config_service),
make_scoped_ptr(new ProxyResolverFactoryForNullResolver), net_log));
}
@@ -1000,7 +1002,7 @@ scoped_ptr<ProxyService> ProxyService::CreateFixedFromPacResult(
new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect()));
return make_scoped_ptr(new ProxyService(
- proxy_config_service.Pass(),
+ std::move(proxy_config_service),
make_scoped_ptr(new ProxyResolverFactoryForPacResult(pac_string)), NULL));
}
@@ -1391,13 +1393,17 @@ int ProxyService::DidFinishResolvingProxy(const GURL& url,
if (network_delegate)
network_delegate->NotifyResolveProxy(url, load_flags, *this, result);
- // When logging all events is enabled, dump the proxy list.
- if (net_log.IsCapturing()) {
+ net_log.AddEvent(NetLog::TYPE_PROXY_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(
- NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
+ NetLog::TYPE_PROXY_SERVICE_DEPRIORITIZED_BAD_PROXIES,
base::Bind(&NetLogFinishedResolvingProxyCallback, result));
}
- result->DeprioritizeBadProxies(proxy_retry_info_);
} else {
net_log.AddEventWithNetErrorCode(
NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST, result_code);
@@ -1441,7 +1447,7 @@ void ProxyService::SetProxyScriptFetchers(
DCHECK(CalledOnValidThread());
State previous_state = ResetProxyConfig(false);
proxy_script_fetcher_.reset(proxy_script_fetcher);
- dhcp_proxy_script_fetcher_ = dhcp_proxy_script_fetcher.Pass();
+ dhcp_proxy_script_fetcher_ = std::move(dhcp_proxy_script_fetcher);
if (previous_state != STATE_NONE)
ApplyProxyConfigIfAvailable();
}
@@ -1479,7 +1485,7 @@ void ProxyService::ResetConfigService(
config_service_->RemoveObserver(this);
// Set the new configuration service.
- config_service_ = new_proxy_config_service.Pass();
+ config_service_ = std::move(new_proxy_config_service);
config_service_->AddObserver(this);
if (previous_state != STATE_NONE)
@@ -1524,7 +1530,7 @@ scoped_ptr<ProxyConfigService> ProxyService::CreateSystemProxyConfigService(
linux_config_service->SetupAndFetchInitialConfig(
glib_thread_task_runner, io_task_runner, file_task_runner);
- return linux_config_service.Pass();
+ return std::move(linux_config_service);
#elif defined(OS_ANDROID)
return make_scoped_ptr(new ProxyConfigServiceAndroid(
io_task_runner, base::ThreadTaskRunnerHandle::Get()));
diff --git a/chromium/net/proxy/proxy_service.h b/chromium/net/proxy/proxy_service.h
index c8bf0adb673..e71fe9b9c0f 100644
--- a/chromium/net/proxy/proxy_service.h
+++ b/chromium/net/proxy/proxy_service.h
@@ -5,11 +5,14 @@
#ifndef NET_PROXY_PROXY_SERVICE_H_
#define NET_PROXY_PROXY_SERVICE_H_
+#include <stddef.h>
+
#include <set>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/waitable_event.h"
@@ -286,8 +289,6 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
quick_check_enabled_ = value;
}
- bool quick_check_enabled() const { return quick_check_enabled_; }
-
private:
FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigAfterFailedAutodetect);
FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigFromPACToDirect);
diff --git a/chromium/net/proxy/proxy_service_mojo.cc b/chromium/net/proxy/proxy_service_mojo.cc
index b7910ad0208..41bbc3c2700 100644
--- a/chromium/net/proxy/proxy_service_mojo.cc
+++ b/chromium/net/proxy/proxy_service_mojo.cc
@@ -4,6 +4,8 @@
#include "net/proxy/proxy_service_mojo.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/thread_task_runner_handle.h"
@@ -34,7 +36,7 @@ scoped_ptr<ProxyService> CreateProxyServiceUsingMojoFactory(
DCHECK(host_resolver);
scoped_ptr<ProxyService> proxy_service(new ProxyService(
- proxy_config_service.Pass(),
+ std::move(proxy_config_service),
make_scoped_ptr(new ProxyResolverFactoryMojo(
mojo_proxy_factory, host_resolver,
base::Bind(&NetworkDelegateErrorObserver::Create, network_delegate,
@@ -44,7 +46,7 @@ scoped_ptr<ProxyService> CreateProxyServiceUsingMojoFactory(
// Configure fetchers to use for PAC script downloads and auto-detect.
proxy_service->SetProxyScriptFetchers(proxy_script_fetcher,
- dhcp_proxy_script_fetcher.Pass());
+ std::move(dhcp_proxy_script_fetcher));
return proxy_service;
}
@@ -58,8 +60,8 @@ scoped_ptr<ProxyService> CreateProxyServiceUsingMojoInProcess(
NetworkDelegate* network_delegate) {
return CreateProxyServiceUsingMojoFactory(
InProcessMojoProxyResolverFactory::GetInstance(),
- proxy_config_service.Pass(), proxy_script_fetcher,
- dhcp_proxy_script_fetcher.Pass(), host_resolver, net_log,
+ std::move(proxy_config_service), proxy_script_fetcher,
+ std::move(dhcp_proxy_script_fetcher), host_resolver, net_log,
network_delegate);
}
diff --git a/chromium/net/proxy/proxy_service_mojo.h b/chromium/net/proxy/proxy_service_mojo.h
index 8fc88c09432..a728337b28e 100644
--- a/chromium/net/proxy/proxy_service_mojo.h
+++ b/chromium/net/proxy/proxy_service_mojo.h
@@ -5,7 +5,6 @@
#ifndef NET_PROXY_PROXY_SERVICE_MOJO_H_
#define NET_PROXY_PROXY_SERVICE_MOJO_H_
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/proxy/dhcp_proxy_script_fetcher.h"
diff --git a/chromium/net/proxy/proxy_service_mojo_unittest.cc b/chromium/net/proxy/proxy_service_mojo_unittest.cc
index 2d7ae076152..5dd94b00cfb 100644
--- a/chromium/net/proxy/proxy_service_mojo_unittest.cc
+++ b/chromium/net/proxy/proxy_service_mojo_unittest.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <string>
+#include <utility>
#include "base/callback_helpers.h"
#include "base/memory/scoped_ptr.h"
@@ -138,7 +139,7 @@ class ProxyServiceMojoTest : public testing::Test,
mojo::InterfaceRequest<interfaces::ProxyResolver> req,
interfaces::ProxyResolverFactoryRequestClientPtr client) override {
InProcessMojoProxyResolverFactory::GetInstance()->CreateResolver(
- pac_script, req.Pass(), client.Pass());
+ pac_script, std::move(req), std::move(client));
return make_scoped_ptr(
new base::ScopedClosureRunner(on_delete_closure_.closure()));
}
@@ -147,8 +148,8 @@ class ProxyServiceMojoTest : public testing::Test,
LoggingMockHostResolver mock_host_resolver_;
MockProxyScriptFetcher* fetcher_; // Owned by |proxy_service_|.
TestNetLog net_log_;
- scoped_ptr<ProxyService> proxy_service_;
TestClosure on_delete_closure_;
+ scoped_ptr<ProxyService> proxy_service_;
};
TEST_F(ProxyServiceMojoTest, Basic) {
diff --git a/chromium/net/proxy/proxy_service_unittest.cc b/chromium/net/proxy/proxy_service_unittest.cc
index 6e8dcdb7db3..3d23b583345 100644
--- a/chromium/net/proxy/proxy_service_unittest.cc
+++ b/chromium/net/proxy/proxy_service_unittest.cc
@@ -9,6 +9,7 @@
#include "base/format_macros.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/load_flags.h"
diff --git a/chromium/net/proxy/proxy_service_v8.cc b/chromium/net/proxy/proxy_service_v8.cc
index 358a244a11b..4c344921fea 100644
--- a/chromium/net/proxy/proxy_service_v8.cc
+++ b/chromium/net/proxy/proxy_service_v8.cc
@@ -4,6 +4,8 @@
#include "net/proxy/proxy_service_v8.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/thread_task_runner_handle.h"
@@ -30,7 +32,7 @@ scoped_ptr<ProxyService> CreateProxyServiceUsingV8ProxyResolver(
DCHECK(host_resolver);
scoped_ptr<ProxyService> proxy_service(new ProxyService(
- proxy_config_service.Pass(),
+ std::move(proxy_config_service),
make_scoped_ptr(new ProxyResolverFactoryV8TracingWrapper(
host_resolver, net_log,
base::Bind(&NetworkDelegateErrorObserver::Create, network_delegate,
@@ -39,7 +41,7 @@ scoped_ptr<ProxyService> CreateProxyServiceUsingV8ProxyResolver(
// Configure fetchers to use for PAC script downloads and auto-detect.
proxy_service->SetProxyScriptFetchers(proxy_script_fetcher,
- dhcp_proxy_script_fetcher.Pass());
+ std::move(dhcp_proxy_script_fetcher));
return proxy_service;
}
diff --git a/chromium/net/proxy/proxy_service_v8.h b/chromium/net/proxy/proxy_service_v8.h
index 88e7fcc0716..29195531b44 100644
--- a/chromium/net/proxy/proxy_service_v8.h
+++ b/chromium/net/proxy/proxy_service_v8.h
@@ -5,7 +5,6 @@
#ifndef NET_PROXY_PROXY_SERVICE_V8_H_
#define NET_PROXY_PROXY_SERVICE_V8_H_
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/proxy/dhcp_proxy_script_fetcher.h"
diff --git a/chromium/net/quic/congestion_control/cubic.cc b/chromium/net/quic/congestion_control/cubic.cc
index a0ad51a7364..9a924b5b3ca 100644
--- a/chromium/net/quic/congestion_control/cubic.cc
+++ b/chromium/net/quic/congestion_control/cubic.cc
@@ -8,7 +8,6 @@
#include <algorithm>
#include <cmath>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"
@@ -27,10 +26,10 @@ const int kCubeScale = 40; // 1024*1024^3 (first 1024 is from 0.100^3)
// where 0.100 is 100 ms which is the scaling
// round trip time.
const int kCubeCongestionWindowScale = 410;
-const uint64 kCubeFactor = (UINT64_C(1) << kCubeScale) /
- kCubeCongestionWindowScale;
+const uint64_t kCubeFactor =
+ (UINT64_C(1) << kCubeScale) / kCubeCongestionWindowScale;
-const uint32 kDefaultNumConnections = 2;
+const uint32_t kDefaultNumConnections = 2;
const float kBeta = 0.7f; // Default Cubic backoff factor.
// Additional backoff factor when loss occurs in the concave part of the Cubic
// curve. This additional backoff factor is expected to give up bandwidth to
@@ -43,6 +42,7 @@ Cubic::Cubic(const QuicClock* clock)
: clock_(clock),
num_connections_(kDefaultNumConnections),
epoch_(QuicTime::Zero()),
+ app_limited_start_time_(QuicTime::Zero()),
last_update_time_(QuicTime::Zero()) {
Reset();
}
@@ -69,6 +69,7 @@ float Cubic::Beta() const {
void Cubic::Reset() {
epoch_ = QuicTime::Zero(); // Reset time.
+ app_limited_start_time_ = QuicTime::Zero();
last_update_time_ = QuicTime::Zero(); // Reset time.
last_congestion_window_ = 0;
last_max_congestion_window_ = 0;
@@ -80,15 +81,18 @@ void Cubic::Reset() {
}
void Cubic::OnApplicationLimited() {
- // When sender is not using the available congestion window, the window does
- // not grow. But to be RTT-independent, Cubic assumes that the sender has been
- // using the entire window during the time since the beginning of the current
- // "epoch" (the end of the last loss recovery period). Since
- // application-limited periods break this assumption, we reset the epoch when
- // in such a period. This reset effectively freezes congestion window growth
- // through application-limited periods and allows Cubic growth to continue
- // when the entire window is being used.
- epoch_ = QuicTime::Zero();
+ if (FLAGS_shift_quic_cubic_epoch_when_app_limited) {
+ // When sender is not using the available congestion window, Cubic's epoch
+ // should not continue growing. Record the time when sender goes into an
+ // app-limited period here, to compensate later when cwnd growth happens.
+ if (app_limited_start_time_ == QuicTime::Zero()) {
+ app_limited_start_time_ = clock_->ApproximateNow();
+ }
+ } else {
+ // When sender is not using the available congestion window, Cubic's epoch
+ // should not continue growing. Reset the epoch when in such a period.
+ epoch_ = QuicTime::Zero();
+ }
}
QuicPacketCount Cubic::CongestionWindowAfterPacketLoss(
@@ -122,8 +126,7 @@ QuicPacketCount Cubic::CongestionWindowAfterAck(
if (!epoch_.IsInitialized()) {
// First ACK after a loss event.
- DVLOG(1) << "Start of epoch";
- epoch_ = current_time; // Start of epoch.
+ epoch_ = current_time; // Start of epoch.
acked_packets_count_ = 1; // Reset count.
// Reset estimated_tcp_congestion_window_ to be in sync with cubic.
estimated_tcp_congestion_window_ = current_congestion_window;
@@ -131,22 +134,34 @@ QuicPacketCount Cubic::CongestionWindowAfterAck(
time_to_origin_point_ = 0;
origin_point_congestion_window_ = current_congestion_window;
} else {
- time_to_origin_point_ =
- static_cast<uint32>(cbrt(kCubeFactor * (last_max_congestion_window_ -
- current_congestion_window)));
+ time_to_origin_point_ = static_cast<uint32_t>(
+ cbrt(kCubeFactor *
+ (last_max_congestion_window_ - current_congestion_window)));
origin_point_congestion_window_ = last_max_congestion_window_;
}
+ } else {
+ // If sender was app-limited, then freeze congestion window growth during
+ // app-limited period. Continue growth now by shifting the epoch-start
+ // through the app-limited period.
+ if (FLAGS_shift_quic_cubic_epoch_when_app_limited &&
+ app_limited_start_time_ != QuicTime::Zero()) {
+ QuicTime::Delta shift = current_time.Subtract(app_limited_start_time_);
+ DVLOG(1) << "Shifting epoch for quiescence by " << shift.ToMicroseconds();
+ epoch_ = epoch_.Add(shift);
+ app_limited_start_time_ = QuicTime::Zero();
+ }
}
+
// Change the time unit from microseconds to 2^10 fractions per second. Take
// the round trip time in account. This is done to allow us to use shift as a
// divide operator.
- int64 elapsed_time =
+ int64_t elapsed_time =
(current_time.Add(delay_min).Subtract(epoch_).ToMicroseconds() << 10) /
kNumMicrosPerSecond;
- int64 offset = time_to_origin_point_ - elapsed_time;
- QuicPacketCount delta_congestion_window = (kCubeCongestionWindowScale
- * offset * offset * offset) >> kCubeScale;
+ int64_t offset = time_to_origin_point_ - elapsed_time;
+ QuicPacketCount delta_congestion_window =
+ (kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale;
QuicPacketCount target_congestion_window =
origin_point_congestion_window_ - delta_congestion_window;
diff --git a/chromium/net/quic/congestion_control/cubic.h b/chromium/net/quic/congestion_control/cubic.h
index effa736264e..493cc58d6bf 100644
--- a/chromium/net/quic/congestion_control/cubic.h
+++ b/chromium/net/quic/congestion_control/cubic.h
@@ -8,7 +8,9 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_CUBIC_H_
#define NET_QUIC_CONGESTION_CONTROL_CUBIC_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_clock.h"
@@ -60,6 +62,10 @@ class NET_EXPORT_PRIVATE Cubic {
// Time when this cycle started, after last loss event.
QuicTime epoch_;
+ // Time when sender went into application-limited period. Zero if not in
+ // application-limited period.
+ QuicTime app_limited_start_time_;
+
// Time when we updated last_congestion_window.
QuicTime last_update_time_;
@@ -81,7 +87,7 @@ class NET_EXPORT_PRIVATE Cubic {
QuicPacketCount origin_point_congestion_window_;
// Time to origin point of cubic function in 2^10 fractions of a second.
- uint32 time_to_origin_point_;
+ uint32_t time_to_origin_point_;
// Last congestion window in packets computed by cubic function.
QuicPacketCount last_target_congestion_window_;
diff --git a/chromium/net/quic/congestion_control/cubic_bytes.cc b/chromium/net/quic/congestion_control/cubic_bytes.cc
index ae35ae4a695..e09cc76eac7 100644
--- a/chromium/net/quic/congestion_control/cubic_bytes.cc
+++ b/chromium/net/quic/congestion_control/cubic_bytes.cc
@@ -8,7 +8,6 @@
#include <algorithm>
#include <cmath>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "net/quic/quic_protocol.h"
@@ -26,10 +25,10 @@ const int kCubeScale = 40; // 1024*1024^3 (first 1024 is from 0.100^3)
// round trip time.
const int kCubeCongestionWindowScale = 410;
// The cube factor for packets in bytes.
-const uint64 kCubeFactor = (UINT64_C(1) << kCubeScale) /
- kCubeCongestionWindowScale / kDefaultTCPMSS;
+const uint64_t kCubeFactor =
+ (UINT64_C(1) << kCubeScale) / kCubeCongestionWindowScale / kDefaultTCPMSS;
-const uint32 kDefaultNumConnections = 2;
+const uint32_t kDefaultNumConnections = 2;
const float kBeta = 0.7f; // Default Cubic backoff factor.
// Additional backoff factor when loss occurs in the concave part of the Cubic
// curve. This additional backoff factor is expected to give up bandwidth to
@@ -131,20 +130,20 @@ QuicByteCount CubicBytes::CongestionWindowAfterAck(
time_to_origin_point_ = 0;
origin_point_congestion_window_ = current_congestion_window;
} else {
- time_to_origin_point_ =
- static_cast<uint32>(cbrt(kCubeFactor * (last_max_congestion_window_ -
- current_congestion_window)));
+ time_to_origin_point_ = static_cast<uint32_t>(
+ cbrt(kCubeFactor *
+ (last_max_congestion_window_ - current_congestion_window)));
origin_point_congestion_window_ = last_max_congestion_window_;
}
}
// Change the time unit from microseconds to 2^10 fractions per second. Take
// the round trip time in account. This is done to allow us to use shift as a
// divide operator.
- int64 elapsed_time =
+ int64_t elapsed_time =
(current_time.Add(delay_min).Subtract(epoch_).ToMicroseconds() << 10) /
kNumMicrosPerSecond;
- int64 offset = time_to_origin_point_ - elapsed_time;
+ int64_t offset = time_to_origin_point_ - elapsed_time;
QuicByteCount delta_congestion_window =
((kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale) *
kDefaultTCPMSS;
diff --git a/chromium/net/quic/congestion_control/cubic_bytes.h b/chromium/net/quic/congestion_control/cubic_bytes.h
index 9b4e2ad9dba..b1b4344fd84 100644
--- a/chromium/net/quic/congestion_control/cubic_bytes.h
+++ b/chromium/net/quic/congestion_control/cubic_bytes.h
@@ -8,7 +8,9 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_CUBIC_BYTES_H_
#define NET_QUIC_CONGESTION_CONTROL_CUBIC_BYTES_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_clock.h"
@@ -82,7 +84,7 @@ class NET_EXPORT_PRIVATE CubicBytes {
QuicByteCount origin_point_congestion_window_;
// Time to origin point of cubic function in 2^10 fractions of a second.
- uint32 time_to_origin_point_;
+ uint32_t time_to_origin_point_;
// Last congestion window in packets computed by cubic function.
QuicByteCount last_target_congestion_window_;
diff --git a/chromium/net/quic/congestion_control/cubic_bytes_test.cc b/chromium/net/quic/congestion_control/cubic_bytes_test.cc
index 3de1651076c..1d4b94ec500 100644
--- a/chromium/net/quic/congestion_control/cubic_bytes_test.cc
+++ b/chromium/net/quic/congestion_control/cubic_bytes_test.cc
@@ -4,7 +4,6 @@
#include "net/quic/congestion_control/cubic_bytes.h"
-#include "base/basictypes.h"
#include "base/logging.h"
#include "net/quic/quic_connection_stats.h"
#include "net/quic/test_tools/mock_clock.h"
@@ -14,7 +13,7 @@ namespace net {
namespace test {
const float kBeta = 0.7f; // Default Cubic backoff factor.
-const uint32 kNumConnections = 2;
+const uint32_t kNumConnections = 2;
const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
(1 - kNConnectionBeta) / (1 + kNConnectionBeta);
diff --git a/chromium/net/quic/congestion_control/cubic_test.cc b/chromium/net/quic/congestion_control/cubic_test.cc
index 9be0d7907f3..fb88de60bf2 100644
--- a/chromium/net/quic/congestion_control/cubic_test.cc
+++ b/chromium/net/quic/congestion_control/cubic_test.cc
@@ -4,7 +4,6 @@
#include "net/quic/congestion_control/cubic.h"
-#include "base/basictypes.h"
#include "base/logging.h"
#include "net/quic/quic_connection_stats.h"
#include "net/quic/test_tools/mock_clock.h"
@@ -14,10 +13,10 @@ namespace net {
namespace test {
const float kBeta = 0.7f; // Default Cubic backoff factor.
-const uint32 kNumConnections = 2;
+const uint32_t kNumConnections = 2;
const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
- (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
+ (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
class CubicTest : public ::testing::Test {
protected:
@@ -66,8 +65,8 @@ TEST_F(CubicTest, AboveOrigin) {
// Total time elapsed so far; add min_rtt (0.1s) here as well.
float elapsed_time_s = 10.0f + 0.1f;
// |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
- expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410)
- / 1024;
+ expected_cwnd =
+ 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
EXPECT_EQ(expected_cwnd, current_cwnd);
}
@@ -102,7 +101,6 @@ TEST_F(CubicTest, CwndIncreaseStatsDuringConvexRegion) {
}
}
-
TEST_F(CubicTest, LossEvents) {
const QuicTime::Delta rtt_min = hundred_ms_;
QuicPacketCount current_cwnd = 422;
@@ -135,7 +133,7 @@ TEST_F(CubicTest, BelowOrigin) {
// First update after loss to initialize the epoch.
current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
// Cubic phase.
- for (int i = 0; i < 40 ; ++i) {
+ for (int i = 0; i < 40; ++i) {
clock_.AdvanceTime(hundred_ms_);
current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
}
diff --git a/chromium/net/quic/congestion_control/general_loss_algorithm.cc b/chromium/net/quic/congestion_control/general_loss_algorithm.cc
new file mode 100644
index 00000000000..887341f5adb
--- /dev/null
+++ b/chromium/net/quic/congestion_control/general_loss_algorithm.cc
@@ -0,0 +1,122 @@
+// Copyright 2015 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/congestion_control/general_loss_algorithm.h"
+
+#include "net/quic/congestion_control/rtt_stats.h"
+#include "net/quic/quic_protocol.h"
+
+namespace net {
+
+namespace {
+
+// The minimum delay before a packet will be considered lost,
+// regardless of SRTT. Half of the minimum TLP, since the loss algorithm only
+// triggers when a nack has been receieved for the packet.
+static const size_t kMinLossDelayMs = 5;
+
+// How many RTTs the algorithm waits before determining a packet is lost due
+// to early retransmission or by time based loss detection.
+static const double kLossDelayMultiplier = 1.25;
+
+} // namespace
+
+GeneralLossAlgorithm::GeneralLossAlgorithm()
+ : loss_type_(kNack), loss_detection_timeout_(QuicTime::Zero()) {}
+
+GeneralLossAlgorithm::GeneralLossAlgorithm(LossDetectionType loss_type)
+ : loss_type_(loss_type), loss_detection_timeout_(QuicTime::Zero()) {}
+
+LossDetectionType GeneralLossAlgorithm::GetLossDetectionType() const {
+ return loss_type_;
+}
+
+PacketNumberSet GeneralLossAlgorithm::DetectLostPackets(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ QuicPacketNumber largest_observed,
+ const RttStats& rtt_stats) {
+ SendAlgorithmInterface::CongestionVector packets_lost;
+ DetectLosses(unacked_packets, time, rtt_stats, &packets_lost);
+ PacketNumberSet lost_packets;
+ for (const std::pair<QuicPacketNumber, QuicPacketLength>& pair :
+ packets_lost) {
+ lost_packets.insert(pair.first);
+ }
+ return lost_packets;
+}
+
+// Uses nack counts to decide when packets are lost.
+void GeneralLossAlgorithm::DetectLosses(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost) {
+ const QuicPacketNumber largest_observed = unacked_packets.largest_observed();
+ loss_detection_timeout_ = QuicTime::Zero();
+ QuicTime::Delta loss_delay = QuicTime::Delta::Max(
+ QuicTime::Delta::FromMilliseconds(kMinLossDelayMs),
+ QuicTime::Delta::Max(rtt_stats.smoothed_rtt(), rtt_stats.latest_rtt())
+ .Multiply(kLossDelayMultiplier));
+
+ QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked();
+ for (QuicUnackedPacketMap::const_iterator it = unacked_packets.begin();
+ it != unacked_packets.end() && packet_number <= largest_observed;
+ ++it, ++packet_number) {
+ if (!it->in_flight) {
+ continue;
+ }
+
+ // TODO(ianswett): Combine this and the time based detection for FACK.
+ if (loss_type_ == kTime) {
+ QuicTime when_lost = it->sent_time.Add(loss_delay);
+ if (time < when_lost) {
+ loss_detection_timeout_ = when_lost;
+ break;
+ }
+ packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent));
+ continue;
+ }
+
+ // FACK based loss detection.
+ LOG_IF(DFATAL, it->nack_count == 0 && it->sent_time.IsInitialized())
+ << "All packets less than largest observed should have been nacked."
+ << "packet_number:" << packet_number
+ << " largest_observed:" << largest_observed;
+ if (it->nack_count >= kNumberOfNacksBeforeRetransmission) {
+ packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent));
+ continue;
+ }
+
+ // NACK-based loss detection allows for a max reordering window of 1 RTT.
+ if (it->sent_time.Add(rtt_stats.smoothed_rtt()) <
+ unacked_packets.GetTransmissionInfo(largest_observed).sent_time) {
+ packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent));
+ continue;
+ }
+
+ // Only early retransmit(RFC5827) when the last packet gets acked and
+ // there are retransmittable packets in flight.
+ // This also implements a timer-protected variant of FACK.
+ if (it->retransmittable_frames &&
+ unacked_packets.largest_sent_packet() == largest_observed) {
+ // Early retransmit marks the packet as lost once 1.25RTTs have passed
+ // since the packet was sent and otherwise sets an alarm.
+ if (time >= it->sent_time.Add(loss_delay)) {
+ packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent));
+ } else {
+ // Set the timeout for the earliest retransmittable packet where early
+ // retransmit applies.
+ loss_detection_timeout_ = it->sent_time.Add(loss_delay);
+ break;
+ }
+ }
+ }
+}
+
+QuicTime GeneralLossAlgorithm::GetLossTimeout() const {
+ return loss_detection_timeout_;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/congestion_control/general_loss_algorithm.h b/chromium/net/quic/congestion_control/general_loss_algorithm.h
new file mode 100644
index 00000000000..54c170fcbca
--- /dev/null
+++ b/chromium/net/quic/congestion_control/general_loss_algorithm.h
@@ -0,0 +1,61 @@
+// Copyright 2015 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_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
+#define NET_QUIC_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
+
+#include <algorithm>
+#include <map>
+
+#include "base/macros.h"
+#include "net/quic/congestion_control/loss_detection_interface.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_time.h"
+#include "net/quic/quic_unacked_packet_map.h"
+
+namespace net {
+
+// Class which can be configured to implement's TCP's approach of detecting loss
+// when 3 nacks have been received for a packet or with a time threshold.
+// Also implements TCP's early retransmit(RFC5827).
+class NET_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
+ public:
+ // TCP retransmits after 3 nacks.
+ static const QuicPacketCount kNumberOfNacksBeforeRetransmission = 3;
+
+ GeneralLossAlgorithm();
+ explicit GeneralLossAlgorithm(LossDetectionType loss_type);
+ ~GeneralLossAlgorithm() override {}
+
+ LossDetectionType GetLossDetectionType() const override;
+ void SetLossDetectionType(LossDetectionType loss_type) {
+ loss_type_ = loss_type;
+ }
+
+ // Only supported for tests.
+ PacketNumberSet DetectLostPackets(const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ QuicPacketNumber largest_observed,
+ const RttStats& rtt_stats) override;
+
+ // Uses |largest_observed| and time to decide when packets are lost.
+ void DetectLosses(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost) override;
+
+ // Returns a non-zero value when the early retransmit timer is active.
+ QuicTime GetLossTimeout() const override;
+
+ private:
+ LossDetectionType loss_type_;
+ QuicTime loss_detection_timeout_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeneralLossAlgorithm);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
diff --git a/chromium/net/quic/congestion_control/general_loss_algorithm_test.cc b/chromium/net/quic/congestion_control/general_loss_algorithm_test.cc
new file mode 100644
index 00000000000..f6ea74280fc
--- /dev/null
+++ b/chromium/net/quic/congestion_control/general_loss_algorithm_test.cc
@@ -0,0 +1,307 @@
+// Copyright 2015 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/congestion_control/general_loss_algorithm.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "net/quic/congestion_control/rtt_stats.h"
+#include "net/quic/quic_unacked_packet_map.h"
+#include "net/quic/test_tools/mock_clock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using std::vector;
+
+namespace net {
+namespace test {
+namespace {
+
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+class GeneralLossAlgorithmTest : public ::testing::Test {
+ protected:
+ GeneralLossAlgorithmTest() {
+ rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+ QuicTime::Delta::Zero(), clock_.Now());
+ }
+
+ ~GeneralLossAlgorithmTest() override { STLDeleteElements(&packets_); }
+
+ void SendDataPacket(QuicPacketNumber packet_number) {
+ packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
+ RetransmittableFrames* frames = new RetransmittableFrames();
+ QuicStreamFrame* frame = new QuicStreamFrame();
+ frame->stream_id = kHeadersStreamId;
+ frames->AddFrame(QuicFrame(frame));
+ SerializedPacket packet(kDefaultPathId, packet_number,
+ PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
+ frames, false, false);
+ unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, clock_.Now(),
+ 1000, true);
+ }
+
+ void VerifyLosses(QuicPacketNumber largest_observed,
+ QuicPacketNumber* losses_expected,
+ size_t num_losses) {
+ unacked_packets_.IncreaseLargestObserved(largest_observed);
+ PacketNumberSet lost_packets = loss_algorithm_.DetectLostPackets(
+ unacked_packets_, clock_.Now(), largest_observed, rtt_stats_);
+ EXPECT_EQ(num_losses, lost_packets.size());
+ for (size_t i = 0; i < num_losses; ++i) {
+ EXPECT_TRUE(ContainsKey(lost_packets, losses_expected[i]));
+ }
+ }
+
+ vector<QuicEncryptedPacket*> packets_;
+ QuicUnackedPacketMap unacked_packets_;
+ GeneralLossAlgorithm loss_algorithm_;
+ RttStats rtt_stats_;
+ MockClock clock_;
+};
+
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
+ const size_t kNumSentPackets = 5;
+ // Transmit 5 packets.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ }
+ // No loss on one ack.
+ unacked_packets_.RemoveFromInFlight(2);
+ unacked_packets_.NackPacket(1, 1);
+ VerifyLosses(2, nullptr, 0);
+ // No loss on two acks.
+ unacked_packets_.RemoveFromInFlight(3);
+ unacked_packets_.NackPacket(1, 2);
+ VerifyLosses(3, nullptr, 0);
+ // Loss on three acks.
+ unacked_packets_.RemoveFromInFlight(4);
+ unacked_packets_.NackPacket(1, 3);
+ QuicPacketNumber lost[] = {1};
+ VerifyLosses(4, lost, arraysize(lost));
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+// A stretch ack is an ack that covers more than 1 packet of previously
+// unacknowledged data.
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketWith1StretchAck) {
+ const size_t kNumSentPackets = 10;
+ // Transmit 10 packets.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ }
+
+ // Nack the first packet 3 times in a single StretchAck.
+ unacked_packets_.NackPacket(1, 3);
+ unacked_packets_.RemoveFromInFlight(2);
+ unacked_packets_.RemoveFromInFlight(3);
+ unacked_packets_.RemoveFromInFlight(4);
+ QuicPacketNumber lost[] = {1};
+ VerifyLosses(4, lost, arraysize(lost));
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+// Ack a packet 3 packets ahead, causing a retransmit.
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketSingleAck) {
+ const size_t kNumSentPackets = 10;
+ // Transmit 10 packets.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ }
+
+ // Nack the first packet 3 times in an AckFrame with three missing packets.
+ unacked_packets_.NackPacket(1, 3);
+ unacked_packets_.NackPacket(2, 2);
+ unacked_packets_.NackPacket(3, 1);
+ unacked_packets_.RemoveFromInFlight(4);
+ QuicPacketNumber lost[] = {1};
+ VerifyLosses(4, lost, arraysize(lost));
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
+ const size_t kNumSentPackets = 2;
+ // Transmit 2 packets.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ }
+ // Early retransmit when the final packet gets acked and the first is nacked.
+ unacked_packets_.RemoveFromInFlight(2);
+ unacked_packets_.NackPacket(1, 1);
+ VerifyLosses(2, nullptr, 0);
+ EXPECT_EQ(clock_.Now().Add(rtt_stats_.smoothed_rtt().Multiply(1.25)),
+ loss_algorithm_.GetLossTimeout());
+
+ clock_.AdvanceTime(rtt_stats_.latest_rtt().Multiply(1.25));
+ QuicPacketNumber lost[] = {1};
+ VerifyLosses(2, lost, arraysize(lost));
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitAllPackets) {
+ const size_t kNumSentPackets = 5;
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ // Advance the time 1/4 RTT between 3 and 4.
+ if (i == 3) {
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt().Multiply(0.25));
+ }
+ }
+
+ // Early retransmit when the final packet gets acked and 1.25 RTTs have
+ // elapsed since the packets were sent.
+ unacked_packets_.RemoveFromInFlight(kNumSentPackets);
+ // This simulates a single ack following multiple missing packets with FACK.
+ for (size_t i = 1; i < kNumSentPackets; ++i) {
+ unacked_packets_.NackPacket(i, kNumSentPackets - i);
+ }
+ QuicPacketNumber lost[] = {1, 2};
+ VerifyLosses(kNumSentPackets, lost, arraysize(lost));
+ // The time has already advanced 1/4 an RTT, so ensure the timeout is set
+ // 1.25 RTTs after the earliest pending packet(3), not the last(4).
+ EXPECT_EQ(clock_.Now().Add(rtt_stats_.smoothed_rtt()),
+ loss_algorithm_.GetLossTimeout());
+
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+ QuicPacketNumber lost2[] = {1, 2, 3};
+ VerifyLosses(kNumSentPackets, lost2, arraysize(lost2));
+ EXPECT_EQ(clock_.Now().Add(rtt_stats_.smoothed_rtt().Multiply(0.25)),
+ loss_algorithm_.GetLossTimeout());
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt().Multiply(0.25));
+ QuicPacketNumber lost3[] = {1, 2, 3, 4};
+ VerifyLosses(kNumSentPackets, lost3, arraysize(lost3));
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) {
+ const size_t kNumSentPackets = 2;
+ // Transmit 2 packets.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ }
+ // Neuter packet 1.
+ unacked_packets_.RemoveRetransmittability(1);
+
+ // Early retransmit when the final packet gets acked and the first is nacked.
+ unacked_packets_.IncreaseLargestObserved(2);
+ unacked_packets_.RemoveFromInFlight(2);
+ unacked_packets_.NackPacket(1, 1);
+ VerifyLosses(2, nullptr, 0);
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, AlwaysLosePacketSent1RTTEarlier) {
+ // Transmit 1 packet and then wait an rtt plus 1ms.
+ SendDataPacket(1);
+ clock_.AdvanceTime(
+ rtt_stats_.smoothed_rtt().Add(QuicTime::Delta::FromMilliseconds(1)));
+
+ // Transmit 2 packets.
+ SendDataPacket(2);
+ SendDataPacket(3);
+
+ // Wait another RTT and ack 2.
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+ unacked_packets_.IncreaseLargestObserved(2);
+ unacked_packets_.RemoveFromInFlight(2);
+ unacked_packets_.NackPacket(1, 1);
+ QuicPacketNumber lost[] = {1};
+ VerifyLosses(2, lost, arraysize(lost));
+}
+
+// Time-based loss detection tests.
+TEST_F(GeneralLossAlgorithmTest, NoLossFor500Nacks) {
+ loss_algorithm_.SetLossDetectionType(kTime);
+ const size_t kNumSentPackets = 5;
+ // Transmit 5 packets.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ }
+ unacked_packets_.RemoveFromInFlight(2);
+ for (size_t i = 1; i < 500; ++i) {
+ unacked_packets_.NackPacket(1, i);
+ VerifyLosses(2, nullptr, 0);
+ }
+ EXPECT_EQ(rtt_stats_.smoothed_rtt().Multiply(1.25),
+ loss_algorithm_.GetLossTimeout().Subtract(clock_.Now()));
+}
+
+TEST_F(GeneralLossAlgorithmTest, NoLossUntilTimeout) {
+ loss_algorithm_.SetLossDetectionType(kTime);
+ const size_t kNumSentPackets = 10;
+ // Transmit 10 packets at 1/10th an RTT interval.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt().Multiply(0.1));
+ }
+ // Expect the timer to not be set.
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+ // The packet should not be lost until 1.25 RTTs pass.
+ unacked_packets_.NackPacket(1, 1);
+ unacked_packets_.RemoveFromInFlight(2);
+ VerifyLosses(2, nullptr, 0);
+ // Expect the timer to be set to 0.25 RTT's in the future.
+ EXPECT_EQ(rtt_stats_.smoothed_rtt().Multiply(0.25),
+ loss_algorithm_.GetLossTimeout().Subtract(clock_.Now()));
+ unacked_packets_.NackPacket(1, 5);
+ VerifyLosses(2, nullptr, 0);
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt().Multiply(0.25));
+ QuicPacketNumber lost[] = {1};
+ VerifyLosses(2, lost, arraysize(lost));
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, NoLossWithoutNack) {
+ loss_algorithm_.SetLossDetectionType(kTime);
+ const size_t kNumSentPackets = 10;
+ // Transmit 10 packets at 1/10th an RTT interval.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt().Multiply(0.1));
+ }
+ // Expect the timer to not be set.
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+ // The packet should not be lost without a nack.
+ unacked_packets_.RemoveFromInFlight(1);
+ VerifyLosses(1, nullptr, 0);
+ // The timer should still not be set.
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt().Multiply(0.25));
+ VerifyLosses(1, nullptr, 0);
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+ VerifyLosses(1, nullptr, 0);
+
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, MultipleLossesAtOnce) {
+ loss_algorithm_.SetLossDetectionType(kTime);
+ const size_t kNumSentPackets = 10;
+ // Transmit 10 packets at once and then go forward an RTT.
+ for (size_t i = 1; i <= kNumSentPackets; ++i) {
+ SendDataPacket(i);
+ }
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+ // Expect the timer to not be set.
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+ // The packet should not be lost until 1.25 RTTs pass.
+ for (size_t i = 1; i < kNumSentPackets; ++i) {
+ unacked_packets_.NackPacket(i, 1);
+ }
+ unacked_packets_.RemoveFromInFlight(10);
+ VerifyLosses(10, nullptr, 0);
+ // Expect the timer to be set to 0.25 RTT's in the future.
+ EXPECT_EQ(rtt_stats_.smoothed_rtt().Multiply(0.25),
+ loss_algorithm_.GetLossTimeout().Subtract(clock_.Now()));
+ clock_.AdvanceTime(rtt_stats_.smoothed_rtt().Multiply(0.25));
+ QuicPacketNumber lost[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ VerifyLosses(10, lost, arraysize(lost));
+ EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+} // namespace
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/congestion_control/hybrid_slow_start.cc b/chromium/net/quic/congestion_control/hybrid_slow_start.cc
index 7c0ba21e658..a5f53f967d9 100644
--- a/chromium/net/quic/congestion_control/hybrid_slow_start.cc
+++ b/chromium/net/quic/congestion_control/hybrid_slow_start.cc
@@ -13,14 +13,14 @@ namespace net {
// Note(pwestin): the magic clamping numbers come from the original code in
// tcp_cubic.c.
-const int64 kHybridStartLowWindow = 16;
+const int64_t kHybridStartLowWindow = 16;
// Number of delay samples for detecting the increase of delay.
-const uint32 kHybridStartMinSamples = 8;
+const uint32_t kHybridStartMinSamples = 8;
// Exit slow start if the min rtt has increased by more than 1/8th.
const int kHybridStartDelayFactorExp = 3; // 2^3 = 8
// The original paper specifies 2 and 8ms, but those have changed over time.
-const int64 kHybridStartDelayMinThresholdUs = 4000;
-const int64 kHybridStartDelayMaxThresholdUs = 16000;
+const int64_t kHybridStartDelayMinThresholdUs = 4000;
+const int64_t kHybridStartDelayMaxThresholdUs = 16000;
HybridSlowStart::HybridSlowStart()
: started_(false),
@@ -86,23 +86,23 @@ bool HybridSlowStart::ShouldExitSlowStart(QuicTime::Delta latest_rtt,
// We only need to check this once per round.
if (rtt_sample_count_ == kHybridStartMinSamples) {
// Divide min_rtt by 8 to get a rtt increase threshold for exiting.
- int64 min_rtt_increase_threshold_us = min_rtt.ToMicroseconds() >>
- kHybridStartDelayFactorExp;
+ int64_t min_rtt_increase_threshold_us =
+ min_rtt.ToMicroseconds() >> kHybridStartDelayFactorExp;
// Ensure the rtt threshold is never less than 2ms or more than 16ms.
- min_rtt_increase_threshold_us = min(min_rtt_increase_threshold_us,
- kHybridStartDelayMaxThresholdUs);
+ min_rtt_increase_threshold_us =
+ min(min_rtt_increase_threshold_us, kHybridStartDelayMaxThresholdUs);
QuicTime::Delta min_rtt_increase_threshold =
QuicTime::Delta::FromMicroseconds(max(min_rtt_increase_threshold_us,
kHybridStartDelayMinThresholdUs));
if (current_min_rtt_ > min_rtt.Add(min_rtt_increase_threshold)) {
- hystart_found_= DELAY;
+ hystart_found_ = DELAY;
}
}
// Exit from slow start if the cwnd is greater than 16 and
// increasing delay is found.
return congestion_window >= kHybridStartLowWindow &&
- hystart_found_ != NOT_FOUND;
+ hystart_found_ != NOT_FOUND;
}
} // namespace net
diff --git a/chromium/net/quic/congestion_control/hybrid_slow_start.h b/chromium/net/quic/congestion_control/hybrid_slow_start.h
index 457ef3e30df..cf752f65464 100644
--- a/chromium/net/quic/congestion_control/hybrid_slow_start.h
+++ b/chromium/net/quic/congestion_control/hybrid_slow_start.h
@@ -16,7 +16,9 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
#define NET_QUIC_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
@@ -54,9 +56,7 @@ class NET_EXPORT_PRIVATE HybridSlowStart {
void StartReceiveRound(QuicPacketNumber last_sent);
// Whether slow start has started.
- bool started() const {
- return started_;
- }
+ bool started() const { return started_; }
private:
// Whether a condition for exiting slow start has been found.
@@ -73,7 +73,7 @@ class NET_EXPORT_PRIVATE HybridSlowStart {
// Variables for tracking acks received during a slow start round.
QuicPacketNumber end_packet_number_; // End of the receive round.
- uint32 rtt_sample_count_; // Number of rtt samples in the current round.
+ uint32_t rtt_sample_count_; // Number of rtt samples in the current round.
QuicTime::Delta current_min_rtt_; // The minimum rtt of current round.
DISALLOW_COPY_AND_ASSIGN(HybridSlowStart);
diff --git a/chromium/net/quic/congestion_control/hybrid_slow_start_test.cc b/chromium/net/quic/congestion_control/hybrid_slow_start_test.cc
index d3974c2bcb1..d3d0fda0978 100644
--- a/chromium/net/quic/congestion_control/hybrid_slow_start_test.cc
+++ b/chromium/net/quic/congestion_control/hybrid_slow_start_test.cc
@@ -14,9 +14,8 @@ namespace test {
class HybridSlowStartTest : public ::testing::Test {
protected:
HybridSlowStartTest()
- : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- rtt_(QuicTime::Delta::FromMilliseconds(60)) {
- }
+ : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
+ rtt_(QuicTime::Delta::FromMilliseconds(60)) {}
void SetUp() override { slow_start_.reset(new HybridSlowStart()); }
const QuicTime::Delta one_ms_;
const QuicTime::Delta rtt_;
diff --git a/chromium/net/quic/congestion_control/loss_detection_interface.cc b/chromium/net/quic/congestion_control/loss_detection_interface.cc
index df2983f2079..4db56c99435 100644
--- a/chromium/net/quic/congestion_control/loss_detection_interface.cc
+++ b/chromium/net/quic/congestion_control/loss_detection_interface.cc
@@ -4,14 +4,19 @@
#include "net/quic/congestion_control/loss_detection_interface.h"
+#include "net/quic/congestion_control/general_loss_algorithm.h"
#include "net/quic/congestion_control/tcp_loss_algorithm.h"
#include "net/quic/congestion_control/time_loss_algorithm.h"
+#include "net/quic/quic_flags.h"
namespace net {
// Factory for loss detection algorithm.
LossDetectionInterface* LossDetectionInterface::Create(
LossDetectionType loss_type) {
+ if (FLAGS_quic_general_loss_algorithm) {
+ return new GeneralLossAlgorithm(loss_type);
+ }
switch (loss_type) {
case kNack:
return new TCPLossAlgorithm();
diff --git a/chromium/net/quic/congestion_control/loss_detection_interface.h b/chromium/net/quic/congestion_control/loss_detection_interface.h
index d10f24ae4a3..d337dbe2033 100644
--- a/chromium/net/quic/congestion_control/loss_detection_interface.h
+++ b/chromium/net/quic/congestion_control/loss_detection_interface.h
@@ -7,7 +7,7 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
#define NET_QUIC_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
-#include "base/basictypes.h"
+#include "net/quic/congestion_control/send_algorithm_interface.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
@@ -32,6 +32,12 @@ class NET_EXPORT_PRIVATE LossDetectionInterface {
QuicPacketNumber largest_observed,
const RttStats& rtt_stats) = 0;
+ virtual void DetectLosses(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost) = 0;
+
// Get the time the LossDetectionAlgorithm wants to re-evaluate losses.
// Returns QuicTime::Zero if no alarm needs to be set.
virtual QuicTime GetLossTimeout() const = 0;
diff --git a/chromium/net/quic/congestion_control/pacing_sender.cc b/chromium/net/quic/congestion_control/pacing_sender.cc
index c5a9fa63ed7..040310f5b90 100644
--- a/chromium/net/quic/congestion_control/pacing_sender.cc
+++ b/chromium/net/quic/congestion_control/pacing_sender.cc
@@ -10,15 +10,14 @@ namespace net {
PacingSender::PacingSender(SendAlgorithmInterface* sender,
QuicTime::Delta alarm_granularity,
- uint32 initial_packet_burst)
+ uint32_t initial_packet_burst)
: sender_(sender),
alarm_granularity_(alarm_granularity),
initial_packet_burst_(initial_packet_burst),
burst_tokens_(initial_packet_burst),
last_delayed_packet_sent_time_(QuicTime::Zero()),
ideal_next_packet_send_time_(QuicTime::Zero()),
- was_last_send_delayed_(false) {
-}
+ was_last_send_delayed_(false) {}
PacingSender::~PacingSender() {}
@@ -46,8 +45,8 @@ void PacingSender::OnCongestionEvent(bool rtt_updated,
QuicByteCount bytes_in_flight,
const CongestionVector& acked_packets,
const CongestionVector& lost_packets) {
- sender_->OnCongestionEvent(
- rtt_updated, bytes_in_flight, acked_packets, lost_packets);
+ sender_->OnCongestionEvent(rtt_updated, bytes_in_flight, acked_packets,
+ lost_packets);
}
bool PacingSender::OnPacketSent(
@@ -69,7 +68,7 @@ bool PacingSender::OnPacketSent(
// current CWND in packets.
burst_tokens_ = min(
initial_packet_burst_,
- static_cast<uint32>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
+ static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
}
if (burst_tokens_ > 0) {
--burst_tokens_;
@@ -113,9 +112,9 @@ void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
}
QuicTime::Delta PacingSender::TimeUntilSend(
- QuicTime now,
- QuicByteCount bytes_in_flight,
- HasRetransmittableData has_retransmittable_data) const {
+ QuicTime now,
+ QuicByteCount bytes_in_flight,
+ HasRetransmittableData has_retransmittable_data) const {
QuicTime::Delta time_until_send =
sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data);
if (burst_tokens_ > 0 || bytes_in_flight == 0) {
diff --git a/chromium/net/quic/congestion_control/pacing_sender.h b/chromium/net/quic/congestion_control/pacing_sender.h
index f9c3f7b6458..185fec435f6 100644
--- a/chromium/net/quic/congestion_control/pacing_sender.h
+++ b/chromium/net/quic/congestion_control/pacing_sender.h
@@ -11,9 +11,11 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_PACING_SENDER_H_
#define NET_QUIC_CONGESTION_CONTROL_PACING_SENDER_H_
+#include <stdint.h>
+
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
#include "net/quic/quic_bandwidth.h"
@@ -31,7 +33,7 @@ class NET_EXPORT_PRIVATE PacingSender : public SendAlgorithmInterface {
// the number of packets sent without pacing after quiescence.
PacingSender(SendAlgorithmInterface* sender,
QuicTime::Delta alarm_granularity,
- uint32 initial_packet_burst);
+ uint32_t initial_packet_burst);
~PacingSender() override;
// SendAlgorithmInterface methods.
@@ -52,6 +54,7 @@ class NET_EXPORT_PRIVATE PacingSender : public SendAlgorithmInterface {
QuicByteCount bytes,
HasRetransmittableData is_retransmittable) override;
void OnRetransmissionTimeout(bool packets_retransmitted) override;
+ void OnConnectionMigration() override {}
QuicTime::Delta TimeUntilSend(
QuicTime now,
QuicByteCount bytes_in_flight,
@@ -72,9 +75,9 @@ class NET_EXPORT_PRIVATE PacingSender : public SendAlgorithmInterface {
const QuicTime::Delta alarm_granularity_;
// Configured maximum size of the burst coming out of quiescence. The burst
// is never larger than the current CWND in packets.
- const uint32 initial_packet_burst_;
+ const uint32_t initial_packet_burst_;
// Number of unpaced packets to be sent before packets are delayed.
- uint32 burst_tokens_;
+ uint32_t burst_tokens_;
// Send time of the last packet considered delayed.
QuicTime last_delayed_packet_sent_time_;
QuicTime ideal_next_packet_send_time_; // When can the next packet be sent.
diff --git a/chromium/net/quic/congestion_control/pacing_sender_test.cc b/chromium/net/quic/congestion_control/pacing_sender_test.cc
index cf069efe806..4320b91820c 100644
--- a/chromium/net/quic/congestion_control/pacing_sender_test.cc
+++ b/chromium/net/quic/congestion_control/pacing_sender_test.cc
@@ -86,15 +86,14 @@ class PacingSenderTest : public ::testing::Test {
// In order for the packet to be sendable, the underlying sender must
// permit it to be sent immediately.
for (int i = 0; i < 2; ++i) {
- EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
- kBytesInFlight,
+ EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), kBytesInFlight,
HAS_RETRANSMITTABLE_DATA))
.WillOnce(Return(zero_time_));
// Verify that the packet is delayed.
EXPECT_EQ(delay.ToMicroseconds(),
- pacing_sender_->TimeUntilSend(
- clock_.Now(), kBytesInFlight,
- HAS_RETRANSMITTABLE_DATA).ToMicroseconds());
+ pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight,
+ HAS_RETRANSMITTABLE_DATA)
+ .ToMicroseconds());
}
}
@@ -115,26 +114,22 @@ class PacingSenderTest : public ::testing::Test {
TEST_F(PacingSenderTest, NoSend) {
for (int i = 0; i < 2; ++i) {
- EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
- kBytesInFlight,
+ EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), kBytesInFlight,
HAS_RETRANSMITTABLE_DATA))
.WillOnce(Return(infinite_time_));
EXPECT_EQ(infinite_time_,
- pacing_sender_->TimeUntilSend(clock_.Now(),
- kBytesInFlight,
+ pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight,
HAS_RETRANSMITTABLE_DATA));
}
}
TEST_F(PacingSenderTest, SendNow) {
for (int i = 0; i < 2; ++i) {
- EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
- kBytesInFlight,
+ EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), kBytesInFlight,
HAS_RETRANSMITTABLE_DATA))
.WillOnce(Return(zero_time_));
EXPECT_EQ(zero_time_,
- pacing_sender_->TimeUntilSend(clock_.Now(),
- kBytesInFlight,
+ pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight,
HAS_RETRANSMITTABLE_DATA));
}
}
@@ -211,7 +206,7 @@ TEST_F(PacingSenderTest, InitialBurst) {
UpdateRtt();
// Send 10 packets, and verify that they are not paced.
- for (int i = 0 ; i < kInitialBurstPackets; ++i) {
+ for (int i = 0; i < kInitialBurstPackets; ++i) {
CheckPacketIsSentImmediately();
}
@@ -246,7 +241,7 @@ TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) {
EXPECT_CALL(*mock_sender_, GetCongestionWindow())
.WillOnce(Return(10 * kDefaultTCPMSS));
// Send 10 packets, and verify that they are not paced.
- for (int i = 0 ; i < kInitialBurstPackets; ++i) {
+ for (int i = 0; i < kInitialBurstPackets; ++i) {
CheckPacketIsSentImmediately();
}
@@ -256,7 +251,6 @@ TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) {
CheckPacketIsSentImmediately();
CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
CheckPacketIsSentImmediately();
diff --git a/chromium/net/quic/congestion_control/prr_sender.cc b/chromium/net/quic/congestion_control/prr_sender.cc
index e84bae8b7cb..b3f5f8b0337 100644
--- a/chromium/net/quic/congestion_control/prr_sender.cc
+++ b/chromium/net/quic/congestion_control/prr_sender.cc
@@ -17,11 +17,10 @@ PrrSender::PrrSender()
: bytes_sent_since_loss_(0),
bytes_delivered_since_loss_(0),
ack_count_since_loss_(0),
- bytes_in_flight_before_loss_(0) {
-}
+ bytes_in_flight_before_loss_(0) {}
void PrrSender::OnPacketSent(QuicByteCount sent_bytes) {
- bytes_sent_since_loss_ += sent_bytes;
+ bytes_sent_since_loss_ += sent_bytes;
}
void PrrSender::OnPacketLost(QuicByteCount bytes_in_flight) {
diff --git a/chromium/net/quic/congestion_control/prr_sender.h b/chromium/net/quic/congestion_control/prr_sender.h
index c7836688360..df73a9fbc6b 100644
--- a/chromium/net/quic/congestion_control/prr_sender.h
+++ b/chromium/net/quic/congestion_control/prr_sender.h
@@ -7,6 +7,8 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_PRR_SENDER_H_
#define NET_QUIC_CONGESTION_CONTROL_PRR_SENDER_H_
+#include <stddef.h>
+
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_time.h"
diff --git a/chromium/net/quic/congestion_control/prr_sender_test.cc b/chromium/net/quic/congestion_control/prr_sender_test.cc
index ed8397fb50e..f7082f2f83c 100644
--- a/chromium/net/quic/congestion_control/prr_sender_test.cc
+++ b/chromium/net/quic/congestion_control/prr_sender_test.cc
@@ -46,7 +46,7 @@ TEST_F(PrrSenderTest, SingleLossResultsInSendOnEveryOtherAck) {
// One packet is lost, and one ack was consumed above. PRR now paces
// transmissions through the remaining 48 acks. PRR will alternatively
// disallow and allow a packet to be sent in response to an ack.
- for (uint64 i = 0; i < ssthresh_after_loss - 1; ++i) {
+ for (uint64_t i = 0; i < ssthresh_after_loss - 1; ++i) {
// Ack a packet. PRR shouldn't allow sending a packet in response.
prr.OnPacketAcked(kMaxSegmentSize);
bytes_in_flight -= kMaxSegmentSize;
diff --git a/chromium/net/quic/congestion_control/rtt_stats.cc b/chromium/net/quic/congestion_control/rtt_stats.cc
index 02a5dfbd045..2e66c8e564c 100644
--- a/chromium/net/quic/congestion_control/rtt_stats.cc
+++ b/chromium/net/quic/congestion_control/rtt_stats.cc
@@ -32,7 +32,7 @@ RttStats::RttStats()
num_min_rtt_samples_remaining_(0),
recent_min_rtt_window_(QuicTime::Delta::Infinite()) {}
-void RttStats::SampleNewRecentMinRtt(uint32 num_samples) {
+void RttStats::SampleNewRecentMinRtt(uint32_t num_samples) {
num_min_rtt_samples_remaining_ = num_samples;
new_min_rtt_ = RttSample();
}
@@ -76,14 +76,14 @@ void RttStats::UpdateRtt(QuicTime::Delta send_delta,
// First time call.
if (smoothed_rtt_.IsZero()) {
smoothed_rtt_ = rtt_sample;
- mean_deviation_ = QuicTime::Delta::FromMicroseconds(
- rtt_sample.ToMicroseconds() / 2);
+ mean_deviation_ =
+ QuicTime::Delta::FromMicroseconds(rtt_sample.ToMicroseconds() / 2);
} else {
- mean_deviation_ = QuicTime::Delta::FromMicroseconds(static_cast<int64>(
+ mean_deviation_ = QuicTime::Delta::FromMicroseconds(static_cast<int64_t>(
kOneMinusBeta * mean_deviation_.ToMicroseconds() +
kBeta * std::abs(smoothed_rtt_.Subtract(rtt_sample).ToMicroseconds())));
- smoothed_rtt_ = smoothed_rtt_.Multiply(kOneMinusAlpha).Add(
- rtt_sample.Multiply(kAlpha));
+ smoothed_rtt_ =
+ smoothed_rtt_.Multiply(kOneMinusAlpha).Add(rtt_sample.Multiply(kAlpha));
DVLOG(1) << " smoothed_rtt(us):" << smoothed_rtt_.ToMicroseconds()
<< " mean_deviation(us):" << mean_deviation_.ToMicroseconds();
}
@@ -118,13 +118,24 @@ void RttStats::UpdateRecentMinRtt(QuicTime::Delta rtt_sample, QuicTime now) {
half_window_rtt_ = quarter_window_rtt_;
quarter_window_rtt_ = RttSample(rtt_sample, now);
} else if (half_window_rtt_.time <
- now.Subtract(recent_min_rtt_window_.Multiply(kHalfWindow))) {
+ now.Subtract(recent_min_rtt_window_.Multiply(kHalfWindow))) {
half_window_rtt_ = quarter_window_rtt_;
quarter_window_rtt_ = RttSample(rtt_sample, now);
} else if (quarter_window_rtt_.time <
- now.Subtract(recent_min_rtt_window_.Multiply(kQuarterWindow))) {
+ now.Subtract(recent_min_rtt_window_.Multiply(kQuarterWindow))) {
quarter_window_rtt_ = RttSample(rtt_sample, now);
}
}
+void RttStats::OnConnectionMigration() {
+ latest_rtt_ = QuicTime::Delta::Zero();
+ min_rtt_ = QuicTime::Delta::Zero();
+ smoothed_rtt_ = QuicTime::Delta::Zero();
+ mean_deviation_ = QuicTime::Delta::Zero();
+ initial_rtt_us_ = kInitialRttMs * kNumMicrosPerMilli;
+ num_min_rtt_samples_remaining_ = 0;
+ recent_min_rtt_window_ = QuicTime::Delta::Infinite();
+ recent_min_rtt_ = half_window_rtt_ = quarter_window_rtt_ = RttSample();
+}
+
} // namespace net
diff --git a/chromium/net/quic/congestion_control/rtt_stats.h b/chromium/net/quic/congestion_control/rtt_stats.h
index a14cfcb3e26..0827fa3c5b0 100644
--- a/chromium/net/quic/congestion_control/rtt_stats.h
+++ b/chromium/net/quic/congestion_control/rtt_stats.h
@@ -7,9 +7,11 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_RTT_STATS_H_
#define NET_QUIC_CONGESTION_CONTROL_RTT_STATS_H_
+#include <stdint.h>
+
#include <algorithm>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
@@ -36,20 +38,19 @@ class NET_EXPORT_PRIVATE RttStats {
// Forces RttStats to sample a new recent min rtt within the next
// |num_samples| UpdateRtt calls.
- void SampleNewRecentMinRtt(uint32 num_samples);
+ void SampleNewRecentMinRtt(uint32_t num_samples);
+
+ // Called when connection migrates and rtt measurement needs to be reset.
+ void OnConnectionMigration();
// Returns the EWMA smoothed RTT for the connection.
// May return Zero if no valid updates have occurred.
- QuicTime::Delta smoothed_rtt() const {
- return smoothed_rtt_;
- }
+ QuicTime::Delta smoothed_rtt() const { return smoothed_rtt_; }
- int64 initial_rtt_us() const {
- return initial_rtt_us_;
- }
+ int64_t initial_rtt_us() const { return initial_rtt_us_; }
// Sets an initial RTT to be used for SmoothedRtt before any RTT updates.
- void set_initial_rtt_us(int64 initial_rtt_us) {
+ void set_initial_rtt_us(int64_t initial_rtt_us) {
if (initial_rtt_us <= 0) {
LOG(DFATAL) << "Attempt to set initial rtt to <= 0.";
return;
@@ -59,25 +60,17 @@ class NET_EXPORT_PRIVATE RttStats {
// The most recent rtt measurement.
// May return Zero if no valid updates have occurred.
- QuicTime::Delta latest_rtt() const {
- return latest_rtt_;
- }
+ QuicTime::Delta latest_rtt() const { return latest_rtt_; }
// Returns the min_rtt for the entire connection.
// May return Zero if no valid updates have occurred.
- QuicTime::Delta min_rtt() const {
- return min_rtt_;
- }
+ QuicTime::Delta min_rtt() const { return min_rtt_; }
// Returns the min_rtt since SampleNewRecentMinRtt has been called, or the
// min_rtt for the entire connection if SampleNewMinRtt was never called.
- QuicTime::Delta recent_min_rtt() const {
- return recent_min_rtt_.rtt;
- }
+ QuicTime::Delta recent_min_rtt() const { return recent_min_rtt_.rtt; }
- QuicTime::Delta mean_deviation() const {
- return mean_deviation_;
- }
+ QuicTime::Delta mean_deviation() const { return mean_deviation_; }
// Sets how old a recent min rtt sample can be.
void set_recent_min_rtt_window(QuicTime::Delta recent_min_rtt_window) {
@@ -89,8 +82,8 @@ class NET_EXPORT_PRIVATE RttStats {
// Used to track a sampled RTT window.
struct RttSample {
- RttSample() : rtt(QuicTime::Delta::Zero()), time(QuicTime::Zero()) { }
- RttSample(QuicTime::Delta rtt, QuicTime time) : rtt(rtt), time(time) { }
+ RttSample() : rtt(QuicTime::Delta::Zero()), time(QuicTime::Zero()) {}
+ RttSample(QuicTime::Delta rtt, QuicTime time) : rtt(rtt), time(time) {}
QuicTime::Delta rtt;
QuicTime time; // Time the rtt sample was recorded.
@@ -106,15 +99,15 @@ class NET_EXPORT_PRIVATE RttStats {
// Approximation of standard deviation, the error is roughly 1.25 times
// larger than the standard deviation, for a normally distributed signal.
QuicTime::Delta mean_deviation_;
- int64 initial_rtt_us_;
+ int64_t initial_rtt_us_;
RttSample new_min_rtt_;
- uint32 num_min_rtt_samples_remaining_;
+ uint32_t num_min_rtt_samples_remaining_;
// State variables for Kathleen Nichols MinRTT algorithm.
QuicTime::Delta recent_min_rtt_window_;
- RttSample recent_min_rtt_; // a in the windowed algorithm.
- RttSample half_window_rtt_; // b in the sampled algorithm.
+ RttSample recent_min_rtt_; // a in the windowed algorithm.
+ RttSample half_window_rtt_; // b in the sampled algorithm.
RttSample quarter_window_rtt_; // c in the sampled algorithm.
DISALLOW_COPY_AND_ASSIGN(RttStats);
diff --git a/chromium/net/quic/congestion_control/rtt_stats_test.cc b/chromium/net/quic/congestion_control/rtt_stats_test.cc
index 86c79734d65..21464905120 100644
--- a/chromium/net/quic/congestion_control/rtt_stats_test.cc
+++ b/chromium/net/quic/congestion_control/rtt_stats_test.cc
@@ -54,63 +54,55 @@ TEST_F(RttStatsTest, SmoothedRtt) {
TEST_F(RttStatsTest, MinRtt) {
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Delta::Zero(),
- QuicTime::Zero());
+ QuicTime::Delta::Zero(), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
rtt_stats_.recent_min_rtt());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(),
- QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(10)));
+ rtt_stats_.UpdateRtt(
+ QuicTime::Delta::FromMilliseconds(10), QuicTime::Delta::Zero(),
+ QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(10)));
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(),
- QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(20)));
+ rtt_stats_.UpdateRtt(
+ QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+ QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(20)));
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(),
- QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(30)));
+ rtt_stats_.UpdateRtt(
+ QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+ QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(30)));
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt());
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(),
- QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(40)));
+ rtt_stats_.UpdateRtt(
+ QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+ QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(40)));
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt());
// Verify that ack_delay does not go into recording of min_rtt_.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(7),
- QuicTime::Delta::FromMilliseconds(2),
- QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(50)));
+ rtt_stats_.UpdateRtt(
+ QuicTime::Delta::FromMilliseconds(7),
+ QuicTime::Delta::FromMilliseconds(2),
+ QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(50)));
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_.recent_min_rtt());
}
TEST_F(RttStatsTest, RecentMinRtt) {
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
- QuicTime::Delta::Zero(),
- QuicTime::Zero());
+ QuicTime::Delta::Zero(), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt());
rtt_stats_.SampleNewRecentMinRtt(4);
for (int i = 0; i < 3; ++i) {
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(),
- QuicTime::Zero());
+ QuicTime::Delta::Zero(), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
rtt_stats_.recent_min_rtt());
}
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(),
- QuicTime::Zero());
+ QuicTime::Delta::Zero(), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), rtt_stats_.recent_min_rtt());
}
@@ -157,8 +149,7 @@ TEST_F(RttStatsTest, WindowedRecentMinRtt) {
EXPECT_EQ(rtt_sample, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_));
EXPECT_EQ(rtt_sample.Subtract(QuicTime::Delta::FromMilliseconds(5)),
RttStatsPeer::GetHalfWindowRtt(&rtt_stats_));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
- rtt_stats_.recent_min_rtt());
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70), rtt_stats_.recent_min_rtt());
// A new half rtt low sets that and the quarter rtt low.
rtt_sample = rtt_sample.Subtract(QuicTime::Delta::FromMilliseconds(15));
@@ -166,8 +157,7 @@ TEST_F(RttStatsTest, WindowedRecentMinRtt) {
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
EXPECT_EQ(rtt_sample, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_));
EXPECT_EQ(rtt_sample, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_));
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
- rtt_stats_.recent_min_rtt());
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70), rtt_stats_.recent_min_rtt());
// A new full window loss sets the recent_min_rtt, but not min_rtt.
rtt_sample = QuicTime::Delta::FromMilliseconds(65);
@@ -232,10 +222,9 @@ TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
for (QuicTime::Delta bad_send_delta : bad_send_deltas) {
SCOPED_TRACE(Message() << "bad_send_delta = "
- << bad_send_delta.ToMicroseconds());
- EXPECT_CALL(log, Log(LOG_WARNING, _, _, _, HasSubstr("Ignoring")));
- rtt_stats_.UpdateRtt(bad_send_delta,
- QuicTime::Delta::Zero(),
+ << bad_send_delta.ToMicroseconds());
+ EXPECT_CALL(log, Log(LOG_WARNING, _, _, _, HasSubstr("Ignoring")));
+ rtt_stats_.UpdateRtt(bad_send_delta, QuicTime::Delta::Zero(),
QuicTime::Zero());
EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
EXPECT_EQ(initial_rtt, rtt_stats_.recent_min_rtt());
@@ -243,5 +232,23 @@ TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
}
}
+TEST_F(RttStatsTest, ResetAfterConnectionMigrations) {
+ 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());
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.min_rtt());
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+ rtt_stats_.recent_min_rtt());
+
+ // Reset rtt stats on connection migrations.
+ rtt_stats_.OnConnectionMigration();
+ EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.latest_rtt());
+ EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
+ EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
+ EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.recent_min_rtt());
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/congestion_control/send_algorithm_interface.cc b/chromium/net/quic/congestion_control/send_algorithm_interface.cc
index d1b0ec57865..d8a9c93c396 100644
--- a/chromium/net/quic/congestion_control/send_algorithm_interface.cc
+++ b/chromium/net/quic/congestion_control/send_algorithm_interface.cc
@@ -40,7 +40,7 @@ SendAlgorithmInterface* SendAlgorithmInterface::Create(
initial_congestion_window,
max_congestion_window, stats);
case kBBR:
- // TODO(rtenneti): Enable BbrTcpSender.
+// TODO(rtenneti): Enable BbrTcpSender.
#if 0
return new BbrTcpSender(clock, rtt_stats, initial_congestion_window,
max_congestion_window, stats, true);
diff --git a/chromium/net/quic/congestion_control/send_algorithm_interface.h b/chromium/net/quic/congestion_control/send_algorithm_interface.h
index 3daee5532c0..fcd9db449bd 100644
--- a/chromium/net/quic/congestion_control/send_algorithm_interface.h
+++ b/chromium/net/quic/congestion_control/send_algorithm_interface.h
@@ -10,7 +10,6 @@
#include <algorithm>
#include <map>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_clock.h"
@@ -27,7 +26,7 @@ class RttStats;
class NET_EXPORT_PRIVATE SendAlgorithmInterface {
public:
// A sorted vector of packets.
- typedef std::vector<std::pair<QuicPacketNumber, TransmissionInfo>>
+ typedef std::vector<std::pair<QuicPacketNumber, QuicPacketLength>>
CongestionVector;
static SendAlgorithmInterface* Create(
@@ -75,6 +74,9 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface {
// nor OnPacketLost will be called for these packets.
virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
+ // Called when connection migrates and cwnd needs to be reset.
+ virtual void OnConnectionMigration() = 0;
+
// Calculate the time until we can send the next packet.
virtual QuicTime::Delta TimeUntilSend(
QuicTime now,
diff --git a/chromium/net/quic/congestion_control/send_algorithm_simulator.cc b/chromium/net/quic/congestion_control/send_algorithm_simulator.cc
index ff580901d16..83326f38120 100644
--- a/chromium/net/quic/congestion_control/send_algorithm_simulator.cc
+++ b/chromium/net/quic/congestion_control/send_algorithm_simulator.cc
@@ -4,6 +4,8 @@
#include "net/quic/congestion_control/send_algorithm_simulator.h"
+#include <stdint.h>
+
#include <limits>
#include "base/logging.h"
@@ -56,10 +58,9 @@ SendAlgorithmSimulator::Transfer::Transfer(Sender* sender,
start_time(start_time),
name(name) {}
-SendAlgorithmSimulator::SendAlgorithmSimulator(
- MockClock* clock,
- QuicBandwidth bandwidth,
- QuicTime::Delta rtt)
+SendAlgorithmSimulator::SendAlgorithmSimulator(MockClock* clock,
+ QuicBandwidth bandwidth,
+ QuicTime::Delta rtt)
: clock_(clock),
lose_next_ack_(false),
forward_loss_rate_(0),
@@ -69,7 +70,7 @@ SendAlgorithmSimulator::SendAlgorithmSimulator(
rtt_(rtt),
buffer_size_(1000000),
delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) {
- uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
+ uint32_t seed = base::RandInt(0, std::numeric_limits<int32_t>::max());
DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed;
simple_random_.set_seed(seed);
}
@@ -81,25 +82,27 @@ void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) {
StringPrintf("#%zu", pending_transfers_.size()));
}
-void SendAlgorithmSimulator::AddTransfer(
- Sender* sender, size_t num_bytes, QuicTime start_time, string name) {
+void SendAlgorithmSimulator::AddTransfer(Sender* sender,
+ size_t num_bytes,
+ QuicTime start_time,
+ string name) {
pending_transfers_.push_back(Transfer(sender, num_bytes, start_time, name));
// Record initial stats from when the transfer begins.
pending_transfers_.back().sender->RecordStats();
}
void SendAlgorithmSimulator::TransferBytes() {
- TransferBytes(kuint64max, QuicTime::Delta::Infinite());
+ TransferBytes(std::numeric_limits<uint64_t>::max(),
+ QuicTime::Delta::Infinite());
}
void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes,
QuicTime::Delta max_time) {
- const QuicTime end_time = max_time.IsInfinite() ?
- QuicTime::Zero().Add(QuicTime::Delta::Infinite()) :
- clock_->Now().Add(max_time);
+ const QuicTime end_time =
+ max_time.IsInfinite() ? QuicTime::Zero().Add(QuicTime::Delta::Infinite())
+ : clock_->Now().Add(max_time);
QuicByteCount bytes_sent = 0;
- while (!pending_transfers_.empty() &&
- clock_->Now() < end_time &&
+ while (!pending_transfers_.empty() && clock_->Now() < end_time &&
bytes_sent < max_bytes) {
// Determine the times of next send and of the next ack arrival.
PacketEvent send_event = NextSendEvent();
@@ -114,8 +117,9 @@ void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes,
SendDataNow(&pending_transfers_.front());
} else if (ack_event.time_delta < send_event.time_delta) {
DVLOG(1) << "Handling ack of largest observed:"
- << ack_event.transfer->sender->next_acked << ", advancing time:"
- << ack_event.time_delta.ToMicroseconds() << "us";
+ << ack_event.transfer->sender->next_acked
+ << ", advancing time:" << ack_event.time_delta.ToMicroseconds()
+ << "us";
// Ack data all the data up to ack time and lose any missing packet
// numbers.
clock_->AdvanceTime(ack_event.time_delta);
@@ -143,9 +147,8 @@ SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() {
// If the flow hasn't started, use the start time.
QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now());
if (clock_->Now() >= it->start_time) {
- transfer_send_time =
- it->sender->send_algorithm->TimeUntilSend(
- clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA);
+ transfer_send_time = it->sender->send_algorithm->TimeUntilSend(
+ clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA);
}
if (transfer_send_time < next_send_time) {
next_send_time = transfer_send_time;
@@ -186,8 +189,8 @@ QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) {
Sender* sender = transfer->sender;
if (sender->next_acked == sender->last_acked) {
// Determine if the next ack is lost only once, to ensure determinism.
- lose_next_ack_ =
- reverse_loss_rate_ * kuint64max > simple_random_.RandUint64();
+ lose_next_ack_ = reverse_loss_rate_ * std::numeric_limits<uint64_t>::max() >
+ simple_random_.RandUint64();
}
QuicPacketNumber next_acked = sender->last_acked;
@@ -264,12 +267,12 @@ bool SendAlgorithmSimulator::HasRecentLostPackets(
}
void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
- Sender* sender = transfer->sender;
+ Sender* sender = transfer->sender;
DCHECK_LT(sender->last_acked, sender->next_acked);
SendAlgorithmInterface::CongestionVector acked_packets;
SendAlgorithmInterface::CongestionVector lost_packets;
- DVLOG(1) << "Acking packets from:" << sender->last_acked
- << " to " << sender->next_acked
+ DVLOG(1) << "Acking packets from:" << sender->last_acked << " to "
+ << sender->next_acked
<< " bytes_in_flight:" << transfer->bytes_in_flight
<< " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
// Some entries may be missing from the sent_packets_ array, if they were
@@ -278,9 +281,6 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
list<SentPacket>::iterator it = sent_packets_.begin();
while (sender->last_acked < sender->next_acked) {
++sender->last_acked;
- TransmissionInfo info = TransmissionInfo();
- info.bytes_sent = kPacketSize;
- info.in_flight = true;
// Find the next SentPacket for this transfer.
while (it->transfer != transfer) {
DCHECK(it != sent_packets_.end());
@@ -290,13 +290,13 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
if (it->packet_number > sender->last_acked) {
DVLOG(1) << "Lost packet:" << sender->last_acked
<< " dropped by buffer overflow.";
- lost_packets.push_back(std::make_pair(sender->last_acked, info));
+ lost_packets.push_back(std::make_pair(sender->last_acked, kPacketSize));
continue;
}
if (it->lost) {
- lost_packets.push_back(std::make_pair(sender->last_acked, info));
+ lost_packets.push_back(std::make_pair(sender->last_acked, kPacketSize));
} else {
- acked_packets.push_back(std::make_pair(sender->last_acked, info));
+ acked_packets.push_back(std::make_pair(sender->last_acked, kPacketSize));
}
// This packet has been acked or lost, remove it from sent_packets_.
largest_observed = *it;
@@ -305,16 +305,15 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
DCHECK(!largest_observed.lost);
DVLOG(1) << "Updating RTT from send_time:"
- << largest_observed.send_time.ToDebuggingValue() << " to ack_time:"
- << largest_observed.ack_time.ToDebuggingValue();
+ << largest_observed.send_time.ToDebuggingValue()
+ << " to ack_time:" << largest_observed.ack_time.ToDebuggingValue();
QuicTime::Delta measured_rtt =
largest_observed.ack_time.Subtract(largest_observed.send_time);
DCHECK_GE(measured_rtt.ToMicroseconds(), rtt_.ToMicroseconds());
- sender->rtt_stats->UpdateRtt(measured_rtt,
- QuicTime::Delta::Zero(),
+ sender->rtt_stats->UpdateRtt(measured_rtt, QuicTime::Delta::Zero(),
clock_->Now());
- sender->send_algorithm->OnCongestionEvent(
- true, transfer->bytes_in_flight, acked_packets, lost_packets);
+ sender->send_algorithm->OnCongestionEvent(true, transfer->bytes_in_flight,
+ acked_packets, lost_packets);
DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()),
transfer->bytes_in_flight);
transfer->bytes_in_flight -=
@@ -327,11 +326,11 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
// Remove completed transfers and record transfer bandwidth.
QuicTime::Delta transfer_time =
clock_->Now().Subtract(transfer->start_time);
- sender->last_transfer_loss_rate = static_cast<float>(transfer->bytes_lost) /
+ sender->last_transfer_loss_rate =
+ static_cast<float>(transfer->bytes_lost) /
(transfer->bytes_lost + transfer->bytes_acked);
- sender->last_transfer_bandwidth =
- QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes,
- transfer_time);
+ sender->last_transfer_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
+ transfer->num_bytes, transfer_time);
DCHECK_GE(bandwidth_.ToBitsPerSecond(),
sender->last_transfer_bandwidth.ToBitsPerSecond());
for (vector<Transfer>::iterator it = pending_transfers_.begin();
@@ -345,25 +344,27 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
}
void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
- Sender* sender = transfer->sender;
+ Sender* sender = transfer->sender;
++sender->last_sent;
DVLOG(1) << "Sending packet:" << sender->last_sent
<< " name:" << transfer->name
<< " bytes_in_flight:" << transfer->bytes_in_flight
<< " cwnd:" << sender->send_algorithm->GetCongestionWindow()
<< " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
- sender->send_algorithm->OnPacketSent(
- clock_->Now(), transfer->bytes_in_flight,
- sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA);
+ sender->send_algorithm->OnPacketSent(clock_->Now(), transfer->bytes_in_flight,
+ sender->last_sent, kPacketSize,
+ HAS_RETRANSMITTABLE_DATA);
// Lose the packet immediately if the buffer is full.
if (sent_packets_.size() * kPacketSize < buffer_size_) {
// TODO(ianswett): This buffer simulation is an approximation.
// An ack time of zero means loss.
bool packet_lost =
- forward_loss_rate_ * kuint64max > simple_random_.RandUint64();
+ forward_loss_rate_ * std::numeric_limits<uint64_t>::max() >
+ simple_random_.RandUint64();
// Handle correlated loss.
if (!sent_packets_.empty() && sent_packets_.back().lost &&
- loss_correlation_ * kuint64max > simple_random_.RandUint64()) {
+ loss_correlation_ * std::numeric_limits<uint64_t>::max() >
+ simple_random_.RandUint64()) {
packet_lost = true;
}
DVLOG(1) << "losing packet:" << sender->last_sent
@@ -376,11 +377,13 @@ void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
if (kPacketSize > bdp) {
ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp));
}
- QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() :
- sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize));
+ QuicTime queue_ack_time = sent_packets_.empty()
+ ? QuicTime::Zero()
+ : sent_packets_.back().ack_time.Add(
+ bandwidth_.TransferTime(kPacketSize));
ack_time = QuicTime::Max(ack_time, queue_ack_time);
- sent_packets_.push_back(SentPacket(
- sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer));
+ sent_packets_.push_back(SentPacket(sender->last_sent, clock_->Now(),
+ ack_time, packet_lost, transfer));
} else {
DVLOG(1) << "losing packet:" << sender->last_sent
<< " name:" << transfer->name << " because the buffer was full.";
diff --git a/chromium/net/quic/congestion_control/send_algorithm_simulator.h b/chromium/net/quic/congestion_control/send_algorithm_simulator.h
index 4f96bb8e3ea..7fe0f011466 100644
--- a/chromium/net/quic/congestion_control/send_algorithm_simulator.h
+++ b/chromium/net/quic/congestion_control/send_algorithm_simulator.h
@@ -7,12 +7,14 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_SEND_ALGORITHM_SIMULATOR_H_
#define NET_QUIC_CONGESTION_CONTROL_SEND_ALGORITHM_SIMULATOR_H_
+#include <stddef.h>
+
#include <algorithm>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/format_macros.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
#include "net/quic/quic_protocol.h"
@@ -27,8 +29,7 @@ namespace net {
class SendAlgorithmSimulator {
public:
struct Sender {
- Sender(SendAlgorithmInterface* send_algorithm,
- RttStats* rtt_stats);
+ Sender(SendAlgorithmInterface* send_algorithm, RttStats* rtt_stats);
Sender(SendAlgorithmInterface* send_algorithm,
RttStats* rtt_stats,
QuicTime::Delta additional_rtt);
@@ -46,13 +47,12 @@ class SendAlgorithmSimulator {
std::string DebugString() {
return StringPrintf("observed goodput(bytes/s):%" PRId64
" loss rate:%f"
- " cwnd:%" PRIu64
- " max_cwnd:%" PRIu64 " min_cwnd:%" PRIu64
- " max_cwnd_drop:%" PRIu64,
+ " cwnd:%" PRIu64 " max_cwnd:%" PRIu64
+ " min_cwnd:%" PRIu64 " max_cwnd_drop:%" PRIu64,
last_transfer_bandwidth.ToBytesPerSecond(),
last_transfer_loss_rate,
- send_algorithm->GetCongestionWindow(),
- max_cwnd, min_cwnd, max_cwnd_drop);
+ send_algorithm->GetCongestionWindow(), max_cwnd,
+ min_cwnd, max_cwnd_drop);
}
SendAlgorithmInterface* send_algorithm;
@@ -123,9 +123,7 @@ class SendAlgorithmSimulator {
~SendAlgorithmSimulator();
// For local ad-hoc testing.
- void set_bandwidth(QuicBandwidth bandwidth) {
- bandwidth_ = bandwidth;
- }
+ void set_bandwidth(QuicBandwidth bandwidth) { bandwidth_ = bandwidth; }
void set_forward_loss_rate(float loss_rate) {
DCHECK_LT(loss_rate, 1.0f);
@@ -178,8 +176,7 @@ class SendAlgorithmSimulator {
// A pending packet event, either a send or an ack.
struct PacketEvent {
PacketEvent(QuicTime::Delta time_delta, Transfer* transfer)
- : time_delta(time_delta),
- transfer(transfer) {}
+ : time_delta(time_delta), transfer(transfer) {}
QuicTime::Delta time_delta;
Transfer* transfer;
@@ -230,7 +227,7 @@ class SendAlgorithmSimulator {
float loss_correlation_; // Likelihood the subsequent packet is lost.
QuicBandwidth bandwidth_;
QuicTime::Delta rtt_;
- size_t buffer_size_; // In bytes.
+ size_t buffer_size_; // In bytes.
QuicTime::Delta delayed_ack_timer_;
DISALLOW_COPY_AND_ASSIGN(SendAlgorithmSimulator);
diff --git a/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.cc b/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
index c123fd24fb9..ef6172a9293 100644
--- a/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
+++ b/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.cc
@@ -22,10 +22,9 @@ namespace {
// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
// fast retransmission.
const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
-const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
-const QuicByteCount kMaxBurstBytes = 3 * kMaxSegmentSize;
+const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
const float kRenoBeta = 0.7f; // Reno backoff factor.
-const uint32 kDefaultNumConnections = 2; // N-connection emulation.
+const uint32_t kDefaultNumConnections = 2; // N-connection emulation.
} // namespace
TcpCubicBytesSender::TcpCubicBytesSender(
@@ -44,16 +43,19 @@ TcpCubicBytesSender::TcpCubicBytesSender(
largest_sent_packet_number_(0),
largest_acked_packet_number_(0),
largest_sent_at_last_cutback_(0),
- congestion_window_(initial_tcp_congestion_window * kMaxSegmentSize),
+ congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
min_congestion_window_(kDefaultMinimumCongestionWindow),
min4_mode_(false),
- max_congestion_window_(max_congestion_window * kMaxSegmentSize),
- slowstart_threshold_(max_congestion_window * kMaxSegmentSize),
+ max_congestion_window_(max_congestion_window * kDefaultTCPMSS),
+ slowstart_threshold_(max_congestion_window * kDefaultTCPMSS),
last_cutback_exited_slowstart_(false),
- clock_(clock) {}
+ initial_tcp_congestion_window_(initial_tcp_congestion_window *
+ kDefaultTCPMSS),
+ initial_max_tcp_congestion_window_(max_congestion_window *
+ kDefaultTCPMSS),
+ slow_start_large_reduction_(false) {}
-TcpCubicBytesSender::~TcpCubicBytesSender() {
-}
+TcpCubicBytesSender::~TcpCubicBytesSender() {}
void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
@@ -61,18 +63,23 @@ void TcpCubicBytesSender::SetFromConfig(const QuicConfig& config,
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
// Initial window experiment.
- congestion_window_ = 10 * kMaxSegmentSize;
+ congestion_window_ = 10 * kDefaultTCPMSS;
}
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
// Min CWND experiment.
- min_congestion_window_ = kMaxSegmentSize;
+ min_congestion_window_ = kDefaultTCPMSS;
}
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
// Min CWND of 4 experiment.
min4_mode_ = true;
- min_congestion_window_ = kMaxSegmentSize;
+ min_congestion_window_ = kDefaultTCPMSS;
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
+ // Slow Start Fast Exit experiment.
+ slow_start_large_reduction_ = true;
}
}
}
@@ -90,8 +97,8 @@ void TcpCubicBytesSender::ResumeConnectionState(
// Make sure CWND is in appropriate range (in case of bad data).
QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt_ms);
congestion_window_ =
- max(min(new_congestion_window, kMaxCongestionWindow * kMaxSegmentSize),
- kMinCongestionWindowForBandwidthResumption * kMaxSegmentSize);
+ max(min(new_congestion_window, kMaxCongestionWindow * kDefaultTCPMSS),
+ kMinCongestionWindowForBandwidthResumption * kDefaultTCPMSS);
}
void TcpCubicBytesSender::SetNumEmulatedConnections(int num_connections) {
@@ -120,7 +127,7 @@ void TcpCubicBytesSender::OnCongestionEvent(
if (rtt_updated && InSlowStart() &&
hybrid_slow_start_.ShouldExitSlowStart(
rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
- congestion_window_ / kMaxSegmentSize)) {
+ congestion_window_ / kDefaultTCPMSS)) {
slowstart_threshold_ = congestion_window_;
}
for (CongestionVector::const_iterator it = lost_packets.begin();
@@ -129,7 +136,7 @@ void TcpCubicBytesSender::OnCongestionEvent(
}
for (CongestionVector::const_iterator it = acked_packets.begin();
it != acked_packets.end(); ++it) {
- OnPacketAcked(it->first, it->second.bytes_sent, bytes_in_flight);
+ OnPacketAcked(it->first, it->second, bytes_in_flight);
}
}
@@ -155,6 +162,12 @@ void TcpCubicBytesSender::OnPacketLost(QuicPacketNumber packet_number,
if (packet_number <= largest_sent_at_last_cutback_) {
if (last_cutback_exited_slowstart_) {
++stats_->slowstart_packets_lost;
+ if (slow_start_large_reduction_) {
+ // Reduce congestion window by 1 MSS for every loss.
+ congestion_window_ =
+ max(congestion_window_ - kDefaultTCPMSS, min_congestion_window_);
+ slowstart_threshold_ = congestion_window_;
+ }
}
DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
<< " because it was sent prior to the last CWND cutback.";
@@ -168,17 +181,21 @@ void TcpCubicBytesSender::OnPacketLost(QuicPacketNumber packet_number,
prr_.OnPacketLost(bytes_in_flight);
- if (reno_) {
+ // TODO(jri): Separate out all of slow start into a separate class.
+ if (slow_start_large_reduction_) {
+ DCHECK_LT(kDefaultTCPMSS, congestion_window_);
+ congestion_window_ = congestion_window_ - kDefaultTCPMSS;
+ } else if (reno_) {
congestion_window_ = congestion_window_ * RenoBeta();
} else {
congestion_window_ =
cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
}
- slowstart_threshold_ = congestion_window_;
// Enforce TCP's minimum congestion window of 2*MSS.
if (congestion_window_ < min_congestion_window_) {
congestion_window_ = min_congestion_window_;
}
+ slowstart_threshold_ = congestion_window_;
largest_sent_at_last_cutback_ = largest_sent_packet_number_;
// Reset packet count from congestion avoidance mode. We start counting again
// when we're out of recovery.
@@ -216,6 +233,7 @@ QuicTime::Delta TcpCubicBytesSender::TimeUntilSend(
QuicByteCount bytes_in_flight,
HasRetransmittableData has_retransmittable_data) const {
if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
+ DCHECK(!FLAGS_quic_respect_send_alarm2);
// For TCP we can always send an ACK immediately.
return QuicTime::Delta::Zero();
}
@@ -227,7 +245,7 @@ QuicTime::Delta TcpCubicBytesSender::TimeUntilSend(
if (GetCongestionWindow() > bytes_in_flight) {
return QuicTime::Delta::Zero();
}
- if (min4_mode_ && bytes_in_flight < 4 * kMaxSegmentSize) {
+ if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
return QuicTime::Delta::Zero();
}
return QuicTime::Delta::Infinite();
@@ -297,12 +315,10 @@ void TcpCubicBytesSender::MaybeIncreaseCwnd(
QuicByteCount acked_bytes,
QuicByteCount bytes_in_flight) {
LOG_IF(DFATAL, InRecovery()) << "Never increase the CWND during recovery.";
+ // Do not increase the congestion window unless the sender is close to using
+ // the current window.
if (!IsCwndLimited(bytes_in_flight)) {
- // Do not increase the congestion window unless the sender is close to using
- // the current window.
- if (FLAGS_reset_cubic_epoch_when_app_limited) {
- cubic_.OnApplicationLimited();
- }
+ cubic_.OnApplicationLimited();
return;
}
if (congestion_window_ >= max_congestion_window_) {
@@ -310,7 +326,7 @@ void TcpCubicBytesSender::MaybeIncreaseCwnd(
}
if (InSlowStart()) {
// TCP slow start, exponential growth, increase by one for each ACK.
- congestion_window_ += kMaxSegmentSize;
+ congestion_window_ += kDefaultTCPMSS;
DVLOG(1) << "Slow start; congestion window: " << congestion_window_
<< " slowstart threshold: " << slowstart_threshold_;
return;
@@ -322,8 +338,8 @@ void TcpCubicBytesSender::MaybeIncreaseCwnd(
// Divide by num_connections to smoothly increase the CWND at a faster rate
// than conventional Reno.
if (num_acked_packets_ * num_connections_ >=
- congestion_window_ / kMaxSegmentSize) {
- congestion_window_ += kMaxSegmentSize;
+ congestion_window_ / kDefaultTCPMSS) {
+ congestion_window_ += kDefaultTCPMSS;
num_acked_packets_ = 0;
}
@@ -355,4 +371,18 @@ CongestionControlType TcpCubicBytesSender::GetCongestionControlType() const {
return reno_ ? kRenoBytes : kCubicBytes;
}
+void TcpCubicBytesSender::OnConnectionMigration() {
+ hybrid_slow_start_.Restart();
+ cubic_.Reset();
+ prr_ = PrrSender();
+ num_acked_packets_ = 0;
+ largest_sent_packet_number_ = 0;
+ largest_acked_packet_number_ = 0;
+ largest_sent_at_last_cutback_ = 0;
+ congestion_window_ = initial_tcp_congestion_window_;
+ max_congestion_window_ = initial_max_tcp_congestion_window_;
+ slowstart_threshold_ = initial_max_tcp_congestion_window_;
+ last_cutback_exited_slowstart_ = false;
+}
+
} // namespace net
diff --git a/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.h b/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.h
index 7a345f62194..e1b0185f6c1 100644
--- a/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.h
+++ b/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender.h
@@ -7,7 +7,9 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_BYTES_SENDER_H_
#define NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_BYTES_SENDER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/congestion_control/cubic_bytes.h"
#include "net/quic/congestion_control/hybrid_slow_start.h"
@@ -54,6 +56,7 @@ class NET_EXPORT_PRIVATE TcpCubicBytesSender : public SendAlgorithmInterface {
QuicByteCount bytes,
HasRetransmittableData is_retransmittable) override;
void OnRetransmissionTimeout(bool packets_retransmitted) override;
+ void OnConnectionMigration() override;
QuicTime::Delta TimeUntilSend(
QuicTime now,
QuicByteCount bytes_in_flight,
@@ -96,10 +99,10 @@ class NET_EXPORT_PRIVATE TcpCubicBytesSender : public SendAlgorithmInterface {
const bool reno_;
// Number of connections to simulate.
- uint32 num_connections_;
+ uint32_t num_connections_;
// ACK counter for the Reno implementation.
- uint64 num_acked_packets_;
+ uint64_t num_acked_packets_;
// Track the largest packet that has been sent.
QuicPacketNumber largest_sent_packet_number_;
@@ -129,7 +132,16 @@ class NET_EXPORT_PRIVATE TcpCubicBytesSender : public SendAlgorithmInterface {
// collection of slowstart_packets_lost.
bool last_cutback_exited_slowstart_;
- const QuicClock* clock_;
+ // Initial TCP congestion window in bytes. This variable can only be set when
+ // this algorithm is created.
+ const QuicByteCount initial_tcp_congestion_window_;
+
+ // Initial maximum TCP congestion window in bytes. This variable can only be
+ // set when this algorithm is created.
+ const QuicByteCount initial_max_tcp_congestion_window_;
+
+ // When true, exit slow start with large cutback of congestion window.
+ bool slow_start_large_reduction_;
DISALLOW_COPY_AND_ASSIGN(TcpCubicBytesSender);
};
diff --git a/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc b/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc
index ff30bb5a422..308943565dd 100644
--- a/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc
+++ b/chromium/net/quic/congestion_control/tcp_cubic_bytes_sender_test.cc
@@ -24,9 +24,9 @@ namespace test {
// TODO(ianswett): A number of theses tests were written with the assumption of
// an initial CWND of 10. They have carefully calculated values which should be
-// updated to be based on kInitialCongestionWindowInsecure.
-const uint32 kInitialCongestionWindowPackets = 10;
-const uint32 kDefaultWindowTCP =
+// updated to be based on kInitialCongestionWindow.
+const uint32_t kInitialCongestionWindowPackets = 10;
+const uint32_t kDefaultWindowTCP =
kInitialCongestionWindowPackets * kDefaultTCPMSS;
const float kRenoBeta = 0.7f; // Reno backoff factor.
@@ -57,22 +57,22 @@ class TcpCubicBytesSenderTest : public ::testing::Test {
sender_(new TcpCubicBytesSenderPeer(&clock_, true)),
packet_number_(1),
acked_packet_number_(0),
- bytes_in_flight_(0) {
- standard_packet_.bytes_sent = kDefaultTCPMSS;
- }
+ bytes_in_flight_(0) {}
int SendAvailableSendWindow() {
// Send as long as TimeUntilSend returns Zero.
int packets_sent = 0;
bool can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA).IsZero();
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero();
while (can_send) {
sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, packet_number_++,
kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
++packets_sent;
bytes_in_flight_ += kDefaultTCPMSS;
can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA).IsZero();
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero();
}
return packets_sent;
}
@@ -86,7 +86,7 @@ class TcpCubicBytesSenderTest : public ::testing::Test {
for (int i = 0; i < n; ++i) {
++acked_packet_number_;
acked_packets.push_back(
- std::make_pair(acked_packet_number_, standard_packet_));
+ std::make_pair(acked_packet_number_, kDefaultTCPMSS));
}
sender_->OnCongestionEvent(true, bytes_in_flight_, acked_packets,
lost_packets);
@@ -100,7 +100,7 @@ class TcpCubicBytesSenderTest : public ::testing::Test {
for (int i = 0; i < n; ++i) {
++acked_packet_number_;
lost_packets.push_back(
- std::make_pair(acked_packet_number_, standard_packet_));
+ std::make_pair(acked_packet_number_, kDefaultTCPMSS));
}
sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
lost_packets);
@@ -111,7 +111,7 @@ class TcpCubicBytesSenderTest : public ::testing::Test {
void LosePacket(QuicPacketNumber packet_number) {
SendAlgorithmInterface::CongestionVector acked_packets;
SendAlgorithmInterface::CongestionVector lost_packets;
- lost_packets.push_back(std::make_pair(packet_number, standard_packet_));
+ lost_packets.push_back(std::make_pair(packet_number, kDefaultTCPMSS));
sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
lost_packets);
bytes_in_flight_ -= kDefaultTCPMSS;
@@ -123,18 +123,17 @@ class TcpCubicBytesSenderTest : public ::testing::Test {
QuicPacketNumber packet_number_;
QuicPacketNumber acked_packet_number_;
QuicByteCount bytes_in_flight_;
- TransmissionInfo standard_packet_;
};
TEST_F(TcpCubicBytesSenderTest, SimpleSender) {
// At startup make sure we are at the default.
EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
// At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
// Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
// And that window is un-affected.
EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
@@ -142,18 +141,19 @@ TEST_F(TcpCubicBytesSenderTest, SimpleSender) {
SendAvailableSendWindow();
EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
sender_->GetCongestionWindow(),
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
}
TEST_F(TcpCubicBytesSenderTest, ApplicationLimitedSlowStart) {
// Send exactly 10 packets and ensure the CWND ends at 14 packets.
const int kNumberOfAcks = 5;
// At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
// Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
SendAvailableSendWindow();
for (int i = 0; i < kNumberOfAcks; ++i) {
@@ -168,12 +168,12 @@ TEST_F(TcpCubicBytesSenderTest, ApplicationLimitedSlowStart) {
TEST_F(TcpCubicBytesSenderTest, ExponentialSlowStart) {
const int kNumberOfAcks = 20;
// At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
// Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
for (int i = 0; i < kNumberOfAcks; ++i) {
// Send our full send window.
@@ -232,6 +232,63 @@ TEST_F(TcpCubicBytesSenderTest, SlowStartPacketLoss) {
EXPECT_FALSE(sender_->hybrid_slow_start().started());
}
+TEST_F(TcpCubicBytesSenderTest, SlowStartPacketLossWithLargeReduction) {
+ QuicConfig config;
+ QuicTagVector options;
+ options.push_back(kSSLR);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+ sender_->SetNumEmulatedConnections(1);
+ const int kNumberOfAcks = 10;
+ for (int i = 0; i < kNumberOfAcks; ++i) {
+ // Send our full send window.
+ SendAvailableSendWindow();
+ AckNPackets(2);
+ }
+ SendAvailableSendWindow();
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Lose a packet to exit slow start. We should now have fallen out of
+ // slow start with a window reduced by 1.
+ LoseNPackets(1);
+ expected_send_window -= kDefaultTCPMSS;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Lose 5 packets in recovery and verify that congestion window is reduced
+ // further.
+ LoseNPackets(5);
+ expected_send_window -= 5 * kDefaultTCPMSS;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
+
+ // Recovery phase. We need to ack every packet in the recovery window before
+ // we exit recovery.
+ size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+ DVLOG(1) << "number_packets: " << number_of_packets_in_window;
+ AckNPackets(packets_in_recovery_window);
+ SendAvailableSendWindow();
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // We need to ack an entire window before we increase CWND by 1.
+ AckNPackets(number_of_packets_in_window - 1);
+ SendAvailableSendWindow();
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Next ack should increase cwnd by 1.
+ AckNPackets(1);
+ expected_send_window += kDefaultTCPMSS;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Now RTO and ensure slow start gets reset.
+ EXPECT_TRUE(sender_->hybrid_slow_start().started());
+ sender_->OnRetransmissionTimeout(true);
+ EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
TEST_F(TcpCubicBytesSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
SendAvailableSendWindow();
LoseNPackets(kInitialCongestionWindowPackets - 1);
@@ -320,7 +377,8 @@ TEST_F(TcpCubicBytesSenderTest, SlowStartBurstPacketLossPRR) {
// Immediately after the loss, ensure at least one packet can be sent.
// Losses without subsequent acks can occur with timer based loss detection.
EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
AckNPackets(1);
// We should now have fallen out of slow start with a reduced window.
@@ -370,8 +428,8 @@ TEST_F(TcpCubicBytesSenderTest, RTOCongestionWindowNoRetransmission) {
}
TEST_F(TcpCubicBytesSenderTest, RetransmissionDelay) {
- const int64 kRttMs = 10;
- const int64 kDeviationMs = 3;
+ const int64_t kRttMs = 10;
+ const int64_t kDeviationMs = 3;
EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
@@ -398,14 +456,13 @@ TEST_F(TcpCubicBytesSenderTest, RetransmissionDelay) {
EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
EXPECT_NEAR(expected_delay.ToMilliseconds(),
sender_->RetransmissionDelay().ToMilliseconds(), 1);
- EXPECT_EQ(
- static_cast<int64>(sender_->GetCongestionWindow() * kNumMicrosPerSecond /
- sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
- sender_->BandwidthEstimate().ToBytesPerSecond());
+ EXPECT_EQ(static_cast<int64_t>(
+ sender_->GetCongestionWindow() * kNumMicrosPerSecond /
+ sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
+ sender_->BandwidthEstimate().ToBytesPerSecond());
}
TEST_F(TcpCubicBytesSenderTest, TcpCubicResetEpochOnQuiescence) {
- ValueRestore<bool> old_flag(&FLAGS_reset_cubic_epoch_when_app_limited, true);
const int kMaxCongestionWindow = 50;
const QuicByteCount kMaxCongestionWindowBytes =
kMaxCongestionWindow * kDefaultTCPMSS;
@@ -571,7 +628,7 @@ TEST_F(TcpCubicBytesSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
EXPECT_FALSE(sender_->InRecovery());
// Out of recovery now. Congestion window should not grow during RTT.
- for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
+ for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
// Send our full send window.
SendAvailableSendWindow();
AckNPackets(2);
@@ -638,13 +695,48 @@ TEST_F(TcpCubicBytesSenderTest, PaceBelowCWND) {
sender_->OnRetransmissionTimeout(true);
EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_FALSE(sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
+}
+
+TEST_F(TcpCubicBytesSenderTest, ResetAfterConnectionMigration) {
+ // Starts from slow start.
+ sender_->SetNumEmulatedConnections(1);
+ const int kNumberOfAcks = 10;
+ for (int i = 0; i < kNumberOfAcks; ++i) {
+ // Send our full send window.
+ SendAvailableSendWindow();
+ AckNPackets(2);
+ }
+ SendAvailableSendWindow();
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Loses a packet to exit slow start.
+ LoseNPackets(1);
+
+ // We should now have fallen out of slow start with a reduced window. Slow
+ // start threshold is also updated.
+ expected_send_window *= kRenoBeta;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+ EXPECT_EQ(expected_send_window, sender_->GetSlowStartThreshold());
+
+ // Resets cwnd and slow start threshold on connection migrations.
+ sender_->OnConnectionMigration();
+ EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+ EXPECT_EQ(kMaxCongestionWindow * kDefaultTCPMSS,
+ sender_->GetSlowStartThreshold());
+ EXPECT_FALSE(sender_->hybrid_slow_start().started());
}
} // namespace test
diff --git a/chromium/net/quic/congestion_control/tcp_cubic_sender.cc b/chromium/net/quic/congestion_control/tcp_cubic_sender.cc
index 352886ca455..ac94217f8f2 100644
--- a/chromium/net/quic/congestion_control/tcp_cubic_sender.cc
+++ b/chromium/net/quic/congestion_control/tcp_cubic_sender.cc
@@ -23,10 +23,9 @@ namespace {
// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
// fast retransmission. The cwnd after a timeout is still 1.
const QuicPacketCount kDefaultMinimumCongestionWindow = 2;
-const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
-const QuicByteCount kMaxBurstBytes = 3 * kMaxSegmentSize;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-const uint32 kDefaultNumConnections = 2; // N-connection emulation.
+const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
+const float kRenoBeta = 0.7f; // Reno backoff factor.
+const uint32_t kDefaultNumConnections = 2; // N-connection emulation.
} // namespace
TcpCubicSender::TcpCubicSender(const QuicClock* clock,
@@ -50,7 +49,9 @@ TcpCubicSender::TcpCubicSender(const QuicClock* clock,
slowstart_threshold_(max_tcp_congestion_window),
last_cutback_exited_slowstart_(false),
max_tcp_congestion_window_(max_tcp_congestion_window),
- clock_(clock) {}
+ initial_tcp_congestion_window_(initial_tcp_congestion_window),
+ initial_max_tcp_congestion_window_(max_tcp_congestion_window),
+ slow_start_large_reduction_(false) {}
TcpCubicSender::~TcpCubicSender() {
UMA_HISTOGRAM_COUNTS("Net.QuicSession.FinalTcpCwnd", congestion_window_);
@@ -90,6 +91,11 @@ void TcpCubicSender::SetFromConfig(const QuicConfig& config,
min4_mode_ = true;
min_congestion_window_ = 1;
}
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
+ // Slow Start Fast Exit experiment.
+ slow_start_large_reduction_ = true;
+ }
}
}
@@ -105,7 +111,7 @@ void TcpCubicSender::ResumeConnectionState(
// Make sure CWND is in appropriate range (in case of bad data).
QuicPacketCount new_congestion_window =
- bandwidth.ToBytesPerPeriod(rtt_ms) / kMaxPacketSize;
+ bandwidth.ToBytesPerPeriod(rtt_ms) / kDefaultTCPMSS;
congestion_window_ = max(min(new_congestion_window, kMaxCongestionWindow),
kMinCongestionWindowForBandwidthResumption);
}
@@ -117,7 +123,7 @@ void TcpCubicSender::SetNumEmulatedConnections(int num_connections) {
void TcpCubicSender::SetMaxCongestionWindow(
QuicByteCount max_congestion_window) {
- max_tcp_congestion_window_ = max_congestion_window / kMaxPacketSize;
+ max_tcp_congestion_window_ = max_congestion_window / kDefaultTCPMSS;
}
float TcpCubicSender::RenoBeta() const {
@@ -128,11 +134,10 @@ float TcpCubicSender::RenoBeta() const {
return (num_connections_ - 1 + kRenoBeta) / num_connections_;
}
-void TcpCubicSender::OnCongestionEvent(
- bool rtt_updated,
- QuicByteCount bytes_in_flight,
- const CongestionVector& acked_packets,
- const CongestionVector& lost_packets) {
+void TcpCubicSender::OnCongestionEvent(bool rtt_updated,
+ QuicByteCount bytes_in_flight,
+ const CongestionVector& acked_packets,
+ const CongestionVector& lost_packets) {
if (rtt_updated && InSlowStart() &&
hybrid_slow_start_.ShouldExitSlowStart(rtt_stats_->latest_rtt(),
rtt_stats_->min_rtt(),
@@ -145,7 +150,7 @@ void TcpCubicSender::OnCongestionEvent(
}
for (CongestionVector::const_iterator it = acked_packets.begin();
it != acked_packets.end(); ++it) {
- OnPacketAcked(it->first, it->second.bytes_sent, bytes_in_flight);
+ OnPacketAcked(it->first, it->second, bytes_in_flight);
}
}
@@ -171,6 +176,12 @@ void TcpCubicSender::OnPacketLost(QuicPacketNumber packet_number,
if (packet_number <= largest_sent_at_last_cutback_) {
if (last_cutback_exited_slowstart_) {
++stats_->slowstart_packets_lost;
+ if (slow_start_large_reduction_) {
+ // Reduce congestion window by 1 for every loss.
+ congestion_window_ =
+ max(congestion_window_ - 1, min_congestion_window_);
+ slowstart_threshold_ = congestion_window_;
+ }
}
DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
<< " because it was sent prior to the last CWND cutback.";
@@ -184,17 +195,21 @@ void TcpCubicSender::OnPacketLost(QuicPacketNumber packet_number,
prr_.OnPacketLost(bytes_in_flight);
- if (reno_) {
+ // TODO(jri): Separate out all of slow start into a separate class.
+ if (slow_start_large_reduction_) {
+ DCHECK_LT(1u, congestion_window_);
+ congestion_window_ = congestion_window_ - 1;
+ } else if (reno_) {
congestion_window_ = congestion_window_ * RenoBeta();
} else {
congestion_window_ =
cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
}
- slowstart_threshold_ = congestion_window_;
// Enforce a minimum congestion window.
if (congestion_window_ < min_congestion_window_) {
congestion_window_ = min_congestion_window_;
}
+ slowstart_threshold_ = congestion_window_;
largest_sent_at_last_cutback_ = largest_sent_packet_number_;
// reset packet count from congestion avoidance mode. We start
// counting again when we're out of recovery.
@@ -231,18 +246,19 @@ QuicTime::Delta TcpCubicSender::TimeUntilSend(
QuicByteCount bytes_in_flight,
HasRetransmittableData has_retransmittable_data) const {
if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
+ DCHECK(!FLAGS_quic_respect_send_alarm2);
// For TCP we can always send an ACK immediately.
return QuicTime::Delta::Zero();
}
if (InRecovery()) {
// PRR is used when in recovery.
return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight,
- slowstart_threshold_ * kMaxSegmentSize);
+ slowstart_threshold_ * kDefaultTCPMSS);
}
if (GetCongestionWindow() > bytes_in_flight) {
return QuicTime::Delta::Zero();
}
- if (min4_mode_ && bytes_in_flight < 4 * kMaxSegmentSize) {
+ if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
return QuicTime::Delta::Zero();
}
return QuicTime::Delta::Infinite();
@@ -279,7 +295,7 @@ QuicTime::Delta TcpCubicSender::RetransmissionDelay() const {
}
QuicByteCount TcpCubicSender::GetCongestionWindow() const {
- return congestion_window_ * kMaxSegmentSize;
+ return congestion_window_ * kDefaultTCPMSS;
}
bool TcpCubicSender::InSlowStart() const {
@@ -287,7 +303,7 @@ bool TcpCubicSender::InSlowStart() const {
}
QuicByteCount TcpCubicSender::GetSlowStartThreshold() const {
- return slowstart_threshold_ * kMaxSegmentSize;
+ return slowstart_threshold_ * kDefaultTCPMSS;
}
bool TcpCubicSender::IsCwndLimited(QuicByteCount bytes_in_flight) const {
@@ -297,8 +313,8 @@ bool TcpCubicSender::IsCwndLimited(QuicByteCount bytes_in_flight) const {
}
const QuicByteCount available_bytes =
congestion_window_bytes - bytes_in_flight;
- const bool slow_start_limited = InSlowStart() &&
- bytes_in_flight > congestion_window_bytes / 2;
+ const bool slow_start_limited =
+ InSlowStart() && bytes_in_flight > congestion_window_bytes / 2;
return slow_start_limited || available_bytes <= kMaxBurstBytes;
}
@@ -312,12 +328,10 @@ bool TcpCubicSender::InRecovery() const {
void TcpCubicSender::MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
QuicByteCount bytes_in_flight) {
LOG_IF(DFATAL, InRecovery()) << "Never increase the CWND during recovery.";
+ // Do not increase the congestion window unless the sender is close to using
+ // the current window.
if (!IsCwndLimited(bytes_in_flight)) {
- // Do not increase the congestion window unless the sender is close to using
- // the current window.
- if (FLAGS_reset_cubic_epoch_when_app_limited) {
- cubic_.OnApplicationLimited();
- }
+ cubic_.OnApplicationLimited();
return;
}
if (congestion_window_ >= max_tcp_congestion_window_) {
@@ -364,6 +378,20 @@ void TcpCubicSender::OnRetransmissionTimeout(bool packets_retransmitted) {
congestion_window_ = min_congestion_window_;
}
+void TcpCubicSender::OnConnectionMigration() {
+ hybrid_slow_start_.Restart();
+ cubic_.Reset();
+ prr_ = PrrSender();
+ congestion_window_count_ = 0;
+ largest_sent_packet_number_ = 0;
+ largest_acked_packet_number_ = 0;
+ largest_sent_at_last_cutback_ = 0;
+ congestion_window_ = initial_tcp_congestion_window_;
+ slowstart_threshold_ = initial_max_tcp_congestion_window_;
+ last_cutback_exited_slowstart_ = false;
+ max_tcp_congestion_window_ = initial_max_tcp_congestion_window_;
+}
+
CongestionControlType TcpCubicSender::GetCongestionControlType() const {
return reno_ ? kReno : kCubic;
}
diff --git a/chromium/net/quic/congestion_control/tcp_cubic_sender.h b/chromium/net/quic/congestion_control/tcp_cubic_sender.h
index 1e824016b7c..9b253a38b17 100644
--- a/chromium/net/quic/congestion_control/tcp_cubic_sender.h
+++ b/chromium/net/quic/congestion_control/tcp_cubic_sender.h
@@ -7,8 +7,10 @@
#ifndef NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_SENDER_H_
#define NET_QUIC_CONGESTION_CONTROL_TCP_CUBIC_SENDER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/congestion_control/cubic.h"
#include "net/quic/congestion_control/hybrid_slow_start.h"
@@ -56,6 +58,7 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface {
QuicByteCount bytes,
HasRetransmittableData is_retransmittable) override;
void OnRetransmissionTimeout(bool packets_retransmitted) override;
+ void OnConnectionMigration() override;
QuicTime::Delta TimeUntilSend(
QuicTime now,
QuicByteCount bytes_in_flight,
@@ -97,10 +100,10 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface {
const bool reno_;
// Number of connections to simulate.
- uint32 num_connections_;
+ uint32_t num_connections_;
// ACK counter for the Reno implementation.
- uint64 congestion_window_count_;
+ uint64_t congestion_window_count_;
// Track the largest packet that has been sent.
QuicPacketNumber largest_sent_packet_number_;
@@ -130,7 +133,16 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface {
// Maximum number of outstanding packets for tcp.
QuicPacketCount max_tcp_congestion_window_;
- const QuicClock* clock_;
+ // Initial TCP congestion window. This variable can only be set when this
+ // algorithm is created.
+ const QuicPacketCount initial_tcp_congestion_window_;
+
+ // Initial maximum TCP congestion window. This variable can only be set when
+ // this algorithm is created.
+ const QuicPacketCount initial_max_tcp_congestion_window_;
+
+ // When true, exit slow start with large cutback of congestion window.
+ bool slow_start_large_reduction_;
DISALLOW_COPY_AND_ASSIGN(TcpCubicSender);
};
diff --git a/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc b/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc
index 26041ae018a..13ae6c1c2f8 100644
--- a/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc
+++ b/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc
@@ -26,9 +26,9 @@ namespace test {
// TODO(ianswett): A number of theses tests were written with the assumption of
// an initial CWND of 10. They have carefully calculated values which should be
-// updated to be based on kInitialCongestionWindowInsecure.
-const uint32 kInitialCongestionWindowPackets = 10;
-const uint32 kDefaultWindowTCP =
+// updated to be based on kInitialCongestionWindow.
+const uint32_t kInitialCongestionWindowPackets = 10;
+const uint32_t kDefaultWindowTCP =
kInitialCongestionWindowPackets * kDefaultTCPMSS;
const float kRenoBeta = 0.7f; // Reno backoff factor.
@@ -44,21 +44,15 @@ class TcpCubicSenderPeer : public TcpCubicSender {
max_tcp_congestion_window,
&stats_) {}
- QuicPacketCount congestion_window() {
- return congestion_window_;
- }
+ QuicPacketCount congestion_window() { return congestion_window_; }
- QuicPacketCount slowstart_threshold() {
- return slowstart_threshold_;
- }
+ QuicPacketCount slowstart_threshold() { return slowstart_threshold_; }
const HybridSlowStart& hybrid_slow_start() const {
return hybrid_slow_start_;
}
- float GetRenoBeta() const {
- return RenoBeta();
- }
+ float GetRenoBeta() const { return RenoBeta(); }
RttStats rtt_stats_;
QuicConnectionStats stats_;
@@ -71,22 +65,22 @@ class TcpCubicSenderTest : public ::testing::Test {
sender_(new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindow)),
packet_number_(1),
acked_packet_number_(0),
- bytes_in_flight_(0) {
- standard_packet_.bytes_sent = kDefaultTCPMSS;
- }
+ bytes_in_flight_(0) {}
int SendAvailableSendWindow() {
// Send as long as TimeUntilSend returns Zero.
int packets_sent = 0;
- bool can_send = sender_->TimeUntilSend(
- clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
+ bool can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero();
while (can_send) {
sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, packet_number_++,
kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
++packets_sent;
bytes_in_flight_ += kDefaultTCPMSS;
- can_send = sender_->TimeUntilSend(
- clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
+ can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero();
}
return packets_sent;
}
@@ -94,17 +88,16 @@ class TcpCubicSenderTest : public ::testing::Test {
// Normal is that TCP acks every other segment.
void AckNPackets(int n) {
sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
- QuicTime::Delta::Zero(),
- clock_.Now());
+ QuicTime::Delta::Zero(), clock_.Now());
SendAlgorithmInterface::CongestionVector acked_packets;
SendAlgorithmInterface::CongestionVector lost_packets;
for (int i = 0; i < n; ++i) {
++acked_packet_number_;
acked_packets.push_back(
- std::make_pair(acked_packet_number_, standard_packet_));
+ std::make_pair(acked_packet_number_, kDefaultTCPMSS));
}
- sender_->OnCongestionEvent(
- true, bytes_in_flight_, acked_packets, lost_packets);
+ sender_->OnCongestionEvent(true, bytes_in_flight_, acked_packets,
+ lost_packets);
bytes_in_flight_ -= n * kDefaultTCPMSS;
clock_.AdvanceTime(one_ms_);
}
@@ -115,10 +108,10 @@ class TcpCubicSenderTest : public ::testing::Test {
for (int i = 0; i < n; ++i) {
++acked_packet_number_;
lost_packets.push_back(
- std::make_pair(acked_packet_number_, standard_packet_));
+ std::make_pair(acked_packet_number_, kDefaultTCPMSS));
}
- sender_->OnCongestionEvent(
- false, bytes_in_flight_, acked_packets, lost_packets);
+ sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
+ lost_packets);
bytes_in_flight_ -= n * kDefaultTCPMSS;
}
@@ -126,9 +119,9 @@ class TcpCubicSenderTest : public ::testing::Test {
void LosePacket(QuicPacketNumber packet_number) {
SendAlgorithmInterface::CongestionVector acked_packets;
SendAlgorithmInterface::CongestionVector lost_packets;
- lost_packets.push_back(std::make_pair(packet_number, standard_packet_));
- sender_->OnCongestionEvent(
- false, bytes_in_flight_, acked_packets, lost_packets);
+ lost_packets.push_back(std::make_pair(packet_number, kDefaultTCPMSS));
+ sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
+ lost_packets);
bytes_in_flight_ -= kDefaultTCPMSS;
}
@@ -138,20 +131,17 @@ class TcpCubicSenderTest : public ::testing::Test {
QuicPacketNumber packet_number_;
QuicPacketNumber acked_packet_number_;
QuicByteCount bytes_in_flight_;
- TransmissionInfo standard_packet_;
};
TEST_F(TcpCubicSenderTest, SimpleSender) {
// At startup make sure we are at the default.
EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
// At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
- 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
// Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
- 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
// And that window is un-affected.
EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
@@ -159,20 +149,19 @@ TEST_F(TcpCubicSenderTest, SimpleSender) {
SendAvailableSendWindow();
EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
sender_->GetCongestionWindow(),
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
}
TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) {
// Send exactly 10 packets and ensure the CWND ends at 14 packets.
const int kNumberOfAcks = 5;
// At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
- 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
// Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
- 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
SendAvailableSendWindow();
for (int i = 0; i < kNumberOfAcks; ++i) {
@@ -181,21 +170,18 @@ TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) {
QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
// It's expected 2 acks will arrive when the bytes_in_flight are greater than
// half the CWND.
- EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2,
- bytes_to_send);
+ EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
}
TEST_F(TcpCubicSenderTest, ExponentialSlowStart) {
const int kNumberOfAcks = 20;
// At startup make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
- 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
// Make sure we can send.
- EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
- 0,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
for (int i = 0; i < kNumberOfAcks; ++i) {
// Send our full send window.
@@ -218,8 +204,8 @@ TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
AckNPackets(2);
}
SendAvailableSendWindow();
- QuicByteCount expected_send_window = kDefaultWindowTCP +
- (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
// Lose a packet to exit slow start.
@@ -254,6 +240,63 @@ TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
EXPECT_FALSE(sender_->hybrid_slow_start().started());
}
+TEST_F(TcpCubicSenderTest, SlowStartPacketLossWithLargeReduction) {
+ QuicConfig config;
+ QuicTagVector options;
+ options.push_back(kSSLR);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+ sender_->SetNumEmulatedConnections(1);
+ const int kNumberOfAcks = 10;
+ for (int i = 0; i < kNumberOfAcks; ++i) {
+ // Send our full send window.
+ SendAvailableSendWindow();
+ AckNPackets(2);
+ }
+ SendAvailableSendWindow();
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Lose a packet to exit slow start. We should now have fallen out of
+ // slow start with a window reduced by 1.
+ LoseNPackets(1);
+ expected_send_window -= kDefaultTCPMSS;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Lose 5 packets in recovery and verify that congestion window is reduced
+ // further.
+ LoseNPackets(5);
+ expected_send_window -= 5 * kDefaultTCPMSS;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
+
+ // Recovery phase. We need to ack every packet in the recovery window before
+ // we exit recovery.
+ size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+ DVLOG(1) << "number_packets: " << number_of_packets_in_window;
+ AckNPackets(packets_in_recovery_window);
+ SendAvailableSendWindow();
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // We need to ack the rest of the window before cwnd increases by 1.
+ AckNPackets(number_of_packets_in_window - 1);
+ SendAvailableSendWindow();
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Next ack should increase cwnd by 1.
+ AckNPackets(1);
+ expected_send_window += kDefaultTCPMSS;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Now RTO and ensure slow start gets reset.
+ EXPECT_TRUE(sender_->hybrid_slow_start().started());
+ sender_->OnRetransmissionTimeout(true);
+ EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
SendAvailableSendWindow();
LoseNPackets(kInitialCongestionWindowPackets - 1);
@@ -278,8 +321,8 @@ TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) {
AckNPackets(2);
}
SendAvailableSendWindow();
- QuicByteCount expected_send_window = kDefaultWindowTCP +
- (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
LoseNPackets(1);
@@ -329,8 +372,8 @@ TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) {
AckNPackets(2);
}
SendAvailableSendWindow();
- QuicByteCount expected_send_window = kDefaultWindowTCP +
- (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
// Lose one more than the congestion window reduction, so that after loss,
@@ -341,8 +384,9 @@ TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) {
LoseNPackets(num_packets_to_lose);
// Immediately after the loss, ensure at least one packet can be sent.
// Losses without subsequent acks can occur with timer based loss detection.
- EXPECT_TRUE(sender_->TimeUntilSend(
- clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero());
+ EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
AckNPackets(1);
// We should now have fallen out of slow start with a reduced window.
@@ -394,8 +438,8 @@ TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) {
}
TEST_F(TcpCubicSenderTest, RetransmissionDelay) {
- const int64 kRttMs = 10;
- const int64 kDeviationMs = 3;
+ const int64_t kRttMs = 10;
+ const int64_t kDeviationMs = 3;
EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
@@ -421,9 +465,8 @@ TEST_F(TcpCubicSenderTest, RetransmissionDelay) {
EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
EXPECT_NEAR(expected_delay.ToMilliseconds(),
- sender_->RetransmissionDelay().ToMilliseconds(),
- 1);
- EXPECT_EQ(static_cast<int64>(
+ sender_->RetransmissionDelay().ToMilliseconds(), 1);
+ EXPECT_EQ(static_cast<int64_t>(
sender_->GetCongestionWindow() * kNumMicrosPerSecond /
sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
sender_->BandwidthEstimate().ToBytesPerSecond());
@@ -488,7 +531,6 @@ TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) {
}
TEST_F(TcpCubicSenderTest, TcpCubicResetEpochOnQuiescence) {
- ValueRestore<bool> old_flag(&FLAGS_reset_cubic_epoch_when_app_limited, true);
const int kMaxCongestionWindow = 50;
const QuicByteCount kMaxCongestionWindowBytes =
kMaxCongestionWindow * kDefaultTCPMSS;
@@ -529,6 +571,49 @@ TEST_F(TcpCubicSenderTest, TcpCubicResetEpochOnQuiescence) {
EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
}
+TEST_F(TcpCubicSenderTest, TcpCubicShiftedEpochOnQuiescence) {
+ ValueRestore<bool> old_flag(&FLAGS_shift_quic_cubic_epoch_when_app_limited,
+ true);
+ const int kMaxCongestionWindow = 50;
+ const QuicByteCount kMaxCongestionWindowBytes =
+ kMaxCongestionWindow * kDefaultTCPMSS;
+ sender_.reset(new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindow));
+
+ int num_sent = SendAvailableSendWindow();
+
+ // Make sure we fall out of slow start.
+ QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
+ LoseNPackets(1);
+ EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
+
+ // Ack the rest of the outstanding packets to get out of recovery.
+ for (int i = 1; i < num_sent; ++i) {
+ AckNPackets(1);
+ }
+ EXPECT_EQ(0u, bytes_in_flight_);
+
+ // Send a new window of data and ack all; cubic growth should occur.
+ saved_cwnd = sender_->GetCongestionWindow();
+ num_sent = SendAvailableSendWindow();
+ for (int i = 0; i < num_sent; ++i) {
+ AckNPackets(1);
+ }
+ EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
+ EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
+ EXPECT_EQ(0u, bytes_in_flight_);
+
+ // Quiescent time of 100 seconds
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(100));
+
+ // Send new window of data and ack one packet. Cubic epoch should have
+ // been reset; ensure cwnd increase is not dramatic.
+ saved_cwnd = sender_->GetCongestionWindow();
+ SendAvailableSendWindow();
+ AckNPackets(1);
+ EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
+ EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
+}
+
TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) {
SendAvailableSendWindow();
const QuicByteCount initial_window = sender_->GetCongestionWindow();
@@ -607,8 +692,8 @@ TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
AckNPackets(2);
}
SendAvailableSendWindow();
- QuicByteCount expected_send_window = kDefaultWindowTCP +
- (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
LoseNPackets(1);
@@ -663,8 +748,8 @@ TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
AckNPackets(2);
}
SendAvailableSendWindow();
- QuicByteCount expected_send_window = kDefaultWindowTCP +
- (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
LoseNPackets(1);
@@ -685,7 +770,7 @@ TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
EXPECT_FALSE(sender_->InRecovery());
// Out of recovery now. Congestion window should not grow during RTT.
- for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
+ for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
// Send our full send window.
SendAvailableSendWindow();
AckNPackets(2);
@@ -708,7 +793,7 @@ TEST_F(TcpCubicSenderTest, BandwidthResumption) {
CachedNetworkParameters cached_network_params;
const QuicPacketCount kNumberOfPackets = 123;
const int kBandwidthEstimateBytesPerSecond =
- kNumberOfPackets * kMaxPacketSize;
+ kNumberOfPackets * kDefaultTCPMSS;
cached_network_params.set_bandwidth_estimate_bytes_per_second(
kBandwidthEstimateBytesPerSecond);
cached_network_params.set_min_rtt_ms(1000);
@@ -721,12 +806,12 @@ TEST_F(TcpCubicSenderTest, BandwidthResumption) {
// Resumed CWND is limited to be in a sensible range.
cached_network_params.set_bandwidth_estimate_bytes_per_second(
- (kMaxCongestionWindow + 1) * kMaxPacketSize);
+ (kMaxCongestionWindow + 1) * kDefaultTCPMSS);
sender_->ResumeConnectionState(cached_network_params, false);
EXPECT_EQ(kMaxCongestionWindow, sender_->congestion_window());
cached_network_params.set_bandwidth_estimate_bytes_per_second(
- (kMinCongestionWindowForBandwidthResumption - 1) * kMaxPacketSize);
+ (kMinCongestionWindowForBandwidthResumption - 1) * kDefaultTCPMSS);
sender_->ResumeConnectionState(cached_network_params, false);
EXPECT_EQ(kMinCongestionWindowForBandwidthResumption,
sender_->congestion_window());
@@ -751,13 +836,51 @@ TEST_F(TcpCubicSenderTest, PaceBelowCWND) {
sender_->OnRetransmissionTimeout(true);
EXPECT_EQ(1u, sender_->congestion_window());
EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
EXPECT_FALSE(sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS,
- HAS_RETRANSMITTABLE_DATA).IsZero());
+ HAS_RETRANSMITTABLE_DATA)
+ .IsZero());
+}
+
+TEST_F(TcpCubicSenderTest, ResetAfterConnectionMigration) {
+ EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+ EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold());
+
+ // Starts with slow start.
+ sender_->SetNumEmulatedConnections(1);
+ const int kNumberOfAcks = 10;
+ for (int i = 0; i < kNumberOfAcks; ++i) {
+ // Send our full send window.
+ SendAvailableSendWindow();
+ AckNPackets(2);
+ }
+ SendAvailableSendWindow();
+ QuicByteCount expected_send_window =
+ kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+ // Loses a packet to exit slow start.
+ LoseNPackets(1);
+
+ // We should now have fallen out of slow start with a reduced window. Slow
+ // start threshold is also updated.
+ expected_send_window *= kRenoBeta;
+ EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+ EXPECT_EQ(expected_send_window / kDefaultTCPMSS,
+ sender_->slowstart_threshold());
+
+ // Resets cwnd and slow start threshold on connection migrations.
+ sender_->OnConnectionMigration();
+ EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+ EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold());
+ EXPECT_FALSE(sender_->hybrid_slow_start().started());
}
} // namespace test
diff --git a/chromium/net/quic/congestion_control/tcp_loss_algorithm.cc b/chromium/net/quic/congestion_control/tcp_loss_algorithm.cc
index 2302d9fc132..f493d961ef1 100644
--- a/chromium/net/quic/congestion_control/tcp_loss_algorithm.cc
+++ b/chromium/net/quic/congestion_control/tcp_loss_algorithm.cc
@@ -23,7 +23,7 @@ static const double kEarlyRetransmitLossDelayMultiplier = 1.25;
} // namespace
TCPLossAlgorithm::TCPLossAlgorithm()
- : loss_detection_timeout_(QuicTime::Zero()) { }
+ : loss_detection_timeout_(QuicTime::Zero()) {}
LossDetectionType TCPLossAlgorithm::GetLossDetectionType() const {
return kNack;
@@ -89,6 +89,14 @@ PacketNumberSet TCPLossAlgorithm::DetectLostPackets(
return lost_packets;
}
+void TCPLossAlgorithm::DetectLosses(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost) {
+ LOG(DFATAL) << "DetectLoss is unsupported by TCPLossAlgorithm.";
+}
+
QuicTime TCPLossAlgorithm::GetLossTimeout() const {
return loss_detection_timeout_;
}
diff --git a/chromium/net/quic/congestion_control/tcp_loss_algorithm.h b/chromium/net/quic/congestion_control/tcp_loss_algorithm.h
index 9894c6bb380..35f04ce7945 100644
--- a/chromium/net/quic/congestion_control/tcp_loss_algorithm.h
+++ b/chromium/net/quic/congestion_control/tcp_loss_algorithm.h
@@ -8,7 +8,7 @@
#include <algorithm>
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
@@ -33,6 +33,12 @@ class NET_EXPORT_PRIVATE TCPLossAlgorithm : public LossDetectionInterface {
const QuicTime& time,
QuicPacketNumber largest_observed,
const RttStats& rtt_stats) override;
+ // Unsupported.
+ void DetectLosses(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost) override;
// Returns a non-zero value when the early retransmit timer is active.
QuicTime GetLossTimeout() const override;
diff --git a/chromium/net/quic/congestion_control/tcp_loss_algorithm_test.cc b/chromium/net/quic/congestion_control/tcp_loss_algorithm_test.cc
index 80474f45cda..da51adfd762 100644
--- a/chromium/net/quic/congestion_control/tcp_loss_algorithm_test.cc
+++ b/chromium/net/quic/congestion_control/tcp_loss_algorithm_test.cc
@@ -9,7 +9,6 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "net/quic/congestion_control/rtt_stats.h"
-#include "net/quic/quic_ack_notifier_manager.h"
#include "net/quic/quic_unacked_packet_map.h"
#include "net/quic/test_tools/mock_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,26 +20,27 @@ namespace test {
namespace {
// Default packet length.
-const uint32 kDefaultLength = 1000;
+const uint32_t kDefaultLength = 1000;
class TcpLossAlgorithmTest : public ::testing::Test {
protected:
- TcpLossAlgorithmTest() : unacked_packets_(&ack_notifier_manager_) {
+ TcpLossAlgorithmTest() {
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(),
- clock_.Now());
+ QuicTime::Delta::Zero(), clock_.Now());
}
- ~TcpLossAlgorithmTest() override {
- STLDeleteElements(&packets_);
- }
+ ~TcpLossAlgorithmTest() override { STLDeleteElements(&packets_); }
void SendDataPacket(QuicPacketNumber packet_number) {
packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
- SerializedPacket packet(
- packet_number, PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
- new RetransmittableFrames(ENCRYPTION_NONE), false, false);
- unacked_packets_.AddSentPacket(packet, 0, NOT_RETRANSMISSION, clock_.Now(),
+ RetransmittableFrames* frames = new RetransmittableFrames();
+ QuicStreamFrame* frame = new QuicStreamFrame();
+ frame->stream_id = kHeadersStreamId;
+ frames->AddFrame(QuicFrame(frame));
+ SerializedPacket packet(kDefaultPathId, packet_number,
+ PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
+ frames, false, false);
+ unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, clock_.Now(),
1000, true);
}
@@ -56,7 +56,6 @@ class TcpLossAlgorithmTest : public ::testing::Test {
}
vector<QuicEncryptedPacket*> packets_;
- AckNotifierManager ack_notifier_manager_;
QuicUnackedPacketMap unacked_packets_;
TCPLossAlgorithm loss_algorithm_;
RttStats rtt_stats_;
@@ -156,7 +155,7 @@ TEST_F(TcpLossAlgorithmTest, EarlyRetransmitAllPackets) {
unacked_packets_.RemoveFromInFlight(kNumSentPackets);
// This simulates a single ack following multiple missing packets with FACK.
for (size_t i = 1; i < kNumSentPackets; ++i) {
- unacked_packets_.NackPacket(i, kNumSentPackets - i);
+ unacked_packets_.NackPacket(i, static_cast<uint16_t>(kNumSentPackets - i));
}
QuicPacketNumber lost[] = {1, 2};
VerifyLosses(kNumSentPackets, lost, arraysize(lost));
diff --git a/chromium/net/quic/congestion_control/time_loss_algorithm.cc b/chromium/net/quic/congestion_control/time_loss_algorithm.cc
index 3d500dc614e..fbca9da99e7 100644
--- a/chromium/net/quic/congestion_control/time_loss_algorithm.cc
+++ b/chromium/net/quic/congestion_control/time_loss_algorithm.cc
@@ -21,7 +21,7 @@ static const double kLossDelayMultiplier = 1.25;
} // namespace
TimeLossAlgorithm::TimeLossAlgorithm()
- : loss_detection_timeout_(QuicTime::Zero()) { }
+ : loss_detection_timeout_(QuicTime::Zero()) {}
LossDetectionType TimeLossAlgorithm::GetLossDetectionType() const {
return kTime;
@@ -64,6 +64,14 @@ PacketNumberSet TimeLossAlgorithm::DetectLostPackets(
return lost_packets;
}
+void TimeLossAlgorithm::DetectLosses(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost) {
+ LOG(DFATAL) << "DetectLoss is unsupported by TimeLossAlgorithm.";
+}
+
// loss_time_ is updated in DetectLostPackets, which must be called every time
// an ack is received or the timeout expires.
QuicTime TimeLossAlgorithm::GetLossTimeout() const {
diff --git a/chromium/net/quic/congestion_control/time_loss_algorithm.h b/chromium/net/quic/congestion_control/time_loss_algorithm.h
index bf1224e8f15..6c1359eda2d 100644
--- a/chromium/net/quic/congestion_control/time_loss_algorithm.h
+++ b/chromium/net/quic/congestion_control/time_loss_algorithm.h
@@ -8,7 +8,7 @@
#include <algorithm>
#include <map>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
@@ -33,6 +33,13 @@ class NET_EXPORT_PRIVATE TimeLossAlgorithm : public LossDetectionInterface {
QuicPacketNumber largest_observed,
const RttStats& rtt_stats) override;
+ // Unsupported.
+ void DetectLosses(
+ const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost) override;
+
// Returns the time the next packet will be lost, or zero if there
// are no nacked pending packets outstanding.
// TODO(ianswett): Ideally the RTT variance and the RTT would be used to
diff --git a/chromium/net/quic/congestion_control/time_loss_algorithm_test.cc b/chromium/net/quic/congestion_control/time_loss_algorithm_test.cc
index fb3d75220c0..cbdc794611e 100644
--- a/chromium/net/quic/congestion_control/time_loss_algorithm_test.cc
+++ b/chromium/net/quic/congestion_control/time_loss_algorithm_test.cc
@@ -9,7 +9,6 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "net/quic/congestion_control/rtt_stats.h"
-#include "net/quic/quic_ack_notifier_manager.h"
#include "net/quic/quic_unacked_packet_map.h"
#include "net/quic/test_tools/mock_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,26 +20,23 @@ namespace test {
namespace {
// Default packet length.
-const uint32 kDefaultLength = 1000;
+const uint32_t kDefaultLength = 1000;
class TimeLossAlgorithmTest : public ::testing::Test {
protected:
- TimeLossAlgorithmTest() : unacked_packets_(&ack_notifier_manager_) {
+ TimeLossAlgorithmTest() {
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(),
- clock_.Now());
+ QuicTime::Delta::Zero(), clock_.Now());
}
- ~TimeLossAlgorithmTest() override {
- STLDeleteElements(&packets_);
- }
+ ~TimeLossAlgorithmTest() override { STLDeleteElements(&packets_); }
void SendDataPacket(QuicPacketNumber packet_number) {
packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
- SerializedPacket packet(
- packet_number, PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
- new RetransmittableFrames(ENCRYPTION_NONE), false, false);
- unacked_packets_.AddSentPacket(packet, 0, NOT_RETRANSMISSION, clock_.Now(),
+ SerializedPacket packet(kDefaultPathId, packet_number,
+ PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
+ new RetransmittableFrames(), false, false);
+ unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, clock_.Now(),
1000, true);
}
@@ -56,7 +52,6 @@ class TimeLossAlgorithmTest : public ::testing::Test {
}
vector<QuicEncryptedPacket*> packets_;
- AckNotifierManager ack_notifier_manager_;
QuicUnackedPacketMap unacked_packets_;
TimeLossAlgorithm loss_algorithm_;
RttStats rtt_stats_;
@@ -70,7 +65,7 @@ TEST_F(TimeLossAlgorithmTest, NoLossFor500Nacks) {
SendDataPacket(i);
}
unacked_packets_.RemoveFromInFlight(2);
- for (size_t i = 1; i < 500; ++i) {
+ for (uint16_t i = 1; i < 500; ++i) {
unacked_packets_.NackPacket(1, i);
VerifyLosses(2, nullptr, 0);
}
diff --git a/chromium/net/quic/crypto/aead_base_decrypter.h b/chromium/net/quic/crypto/aead_base_decrypter.h
index edb06d0f6a0..39cc555fb52 100644
--- a/chromium/net/quic/crypto/aead_base_decrypter.h
+++ b/chromium/net/quic/crypto/aead_base_decrypter.h
@@ -5,7 +5,10 @@
#ifndef NET_QUIC_CRYPTO_AEAD_BASE_DECRYPTER_H_
#define NET_QUIC_CRYPTO_AEAD_BASE_DECRYPTER_H_
+#include <stddef.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/quic/crypto/quic_decrypter.h"
#if defined(USE_OPENSSL)
diff --git a/chromium/net/quic/crypto/aead_base_decrypter_nss.cc b/chromium/net/quic/crypto/aead_base_decrypter_nss.cc
index 806abe25267..9036681a1d6 100644
--- a/chromium/net/quic/crypto/aead_base_decrypter_nss.cc
+++ b/chromium/net/quic/crypto/aead_base_decrypter_nss.cc
@@ -55,7 +55,7 @@ bool AeadBaseDecrypter::DecryptPacket(QuicPacketNumber packet_number,
return false;
}
- uint8 nonce[sizeof(nonce_prefix_) + sizeof(packet_number)];
+ uint8_t nonce[sizeof(nonce_prefix_) + sizeof(packet_number)];
const size_t nonce_size = nonce_prefix_size_ + sizeof(packet_number);
DCHECK_LE(nonce_size, sizeof(nonce));
memcpy(nonce, nonce_prefix_, nonce_prefix_size_);
@@ -99,7 +99,7 @@ bool AeadBaseDecrypter::DecryptPacket(QuicPacketNumber packet_number,
unsigned int output_len;
if (PK11_Decrypt(aead_key.get(), aead_mechanism_, &param,
- reinterpret_cast<uint8*>(output), &output_len,
+ reinterpret_cast<uint8_t*>(output), &output_len,
max_output_length,
reinterpret_cast<const unsigned char*>(ciphertext.data()),
ciphertext.length()) != SECSuccess) {
diff --git a/chromium/net/quic/crypto/aead_base_decrypter_openssl.cc b/chromium/net/quic/crypto/aead_base_decrypter_openssl.cc
index 8ebc4ba11a6..3a4e4648fa8 100644
--- a/chromium/net/quic/crypto/aead_base_decrypter_openssl.cc
+++ b/chromium/net/quic/crypto/aead_base_decrypter_openssl.cc
@@ -17,7 +17,8 @@ namespace {
// Clear OpenSSL error stack.
void ClearOpenSslErrors() {
- while (ERR_get_error()) {}
+ while (ERR_get_error()) {
+ }
}
// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
@@ -58,8 +59,8 @@ bool AeadBaseDecrypter::SetKey(StringPiece key) {
memcpy(key_, key.data(), key.size());
EVP_AEAD_CTX_cleanup(ctx_.get());
- if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_,
- auth_tag_size_, nullptr)) {
+ if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
+ nullptr)) {
DLogOpenSslErrors();
return false;
}
@@ -86,7 +87,7 @@ bool AeadBaseDecrypter::DecryptPacket(QuicPacketNumber packet_number,
return false;
}
- uint8 nonce[sizeof(nonce_prefix_) + sizeof(packet_number)];
+ uint8_t nonce[sizeof(nonce_prefix_) + sizeof(packet_number)];
const size_t nonce_size = nonce_prefix_size_ + sizeof(packet_number);
memcpy(nonce, nonce_prefix_, nonce_prefix_size_);
memcpy(nonce + nonce_prefix_size_, &packet_number, sizeof(packet_number));
diff --git a/chromium/net/quic/crypto/aead_base_encrypter.h b/chromium/net/quic/crypto/aead_base_encrypter.h
index 25bef1d78dc..74219d67546 100644
--- a/chromium/net/quic/crypto/aead_base_encrypter.h
+++ b/chromium/net/quic/crypto/aead_base_encrypter.h
@@ -5,7 +5,10 @@
#ifndef NET_QUIC_CRYPTO_AEAD_BASE_ENCRYPTER_H_
#define NET_QUIC_CRYPTO_AEAD_BASE_ENCRYPTER_H_
+#include <stddef.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/quic/crypto/quic_encrypter.h"
#if defined(USE_OPENSSL)
diff --git a/chromium/net/quic/crypto/aead_base_encrypter_nss.cc b/chromium/net/quic/crypto/aead_base_encrypter_nss.cc
index 37a5c890452..b586a1d3301 100644
--- a/chromium/net/quic/crypto/aead_base_encrypter_nss.cc
+++ b/chromium/net/quic/crypto/aead_base_encrypter_nss.cc
@@ -13,6 +13,14 @@ using base::StringPiece;
namespace net {
+namespace {
+
+// The maximum size in bytes of the nonce, including 8 bytes of sequence number.
+// ChaCha20 uses only the 8 byte sequence number and AES-GCM uses 12 bytes.
+const size_t kMaxNonceSize = 12;
+
+} // namespace
+
AeadBaseEncrypter::AeadBaseEncrypter(CK_MECHANISM_TYPE aead_mechanism,
size_t key_size,
size_t auth_tag_size,
@@ -23,6 +31,7 @@ AeadBaseEncrypter::AeadBaseEncrypter(CK_MECHANISM_TYPE aead_mechanism,
nonce_prefix_size_(nonce_prefix_size) {
DCHECK_LE(key_size_, sizeof(key_));
DCHECK_LE(nonce_prefix_size_, sizeof(nonce_prefix_));
+ DCHECK_GE(kMaxNonceSize, nonce_prefix_size_);
}
AeadBaseEncrypter::~AeadBaseEncrypter() {}
@@ -83,10 +92,18 @@ bool AeadBaseEncrypter::Encrypt(StringPiece nonce,
param.data = reinterpret_cast<unsigned char*>(&aead_params.data);
param.len = aead_params.len;
+ if (plaintext.size() > kMaxPacketSize) {
+ DLOG(FATAL) << "Plaintext too large";
+ return false;
+ }
+ // NSS doesn't support inplace encryption, so copy plaintext to a temporary
+ // buffer.
+ unsigned char temp_plaintext[kMaxPacketSize];
+ memcpy(temp_plaintext, plaintext.data(), plaintext.size());
+
unsigned int output_len;
if (PK11_Encrypt(aead_key.get(), aead_mechanism_, &param, output, &output_len,
- ciphertext_size,
- reinterpret_cast<const unsigned char*>(plaintext.data()),
+ ciphertext_size, temp_plaintext,
plaintext.size()) != SECSuccess) {
DVLOG(1) << "PK11_Encrypt failed";
return false;
@@ -113,17 +130,21 @@ bool AeadBaseEncrypter::EncryptPacket(QuicPacketNumber packet_number,
// TODO(ianswett): Introduce a check to ensure that we don't encrypt with the
// same packet number twice.
const size_t nonce_size = nonce_prefix_size_ + sizeof(packet_number);
- memcpy(output, nonce_prefix_, nonce_prefix_size_);
- memcpy(output + nonce_prefix_size_, &packet_number, sizeof(packet_number));
- if (!Encrypt(StringPiece(output, nonce_size), associated_data, plaintext,
- reinterpret_cast<unsigned char*>(output))) {
+ ALIGNAS(4) char nonce_buffer[kMaxNonceSize];
+ memcpy(nonce_buffer, nonce_prefix_, nonce_prefix_size_);
+ memcpy(nonce_buffer + nonce_prefix_size_, &packet_number,
+ sizeof(packet_number));
+ if (!Encrypt(StringPiece(nonce_buffer, nonce_size), associated_data,
+ plaintext, reinterpret_cast<unsigned char*>(output))) {
return false;
}
*output_length = ciphertext_size;
return true;
}
-size_t AeadBaseEncrypter::GetKeySize() const { return key_size_; }
+size_t AeadBaseEncrypter::GetKeySize() const {
+ return key_size_;
+}
size_t AeadBaseEncrypter::GetNoncePrefixSize() const {
return nonce_prefix_size_;
diff --git a/chromium/net/quic/crypto/aead_base_encrypter_openssl.cc b/chromium/net/quic/crypto/aead_base_encrypter_openssl.cc
index 91906cc2e0d..2408cecc955 100644
--- a/chromium/net/quic/crypto/aead_base_encrypter_openssl.cc
+++ b/chromium/net/quic/crypto/aead_base_encrypter_openssl.cc
@@ -16,11 +16,16 @@ namespace net {
namespace {
+// The maximum size in bytes of the nonce, including 8 bytes of sequence number.
+// ChaCha20 uses only the 8 byte sequence number and AES-GCM uses 12 bytes.
+const size_t kMaxNonceSize = 12;
+
// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
// stack.
void DLogOpenSslErrors() {
#ifdef NDEBUG
- while (ERR_get_error()) {}
+ while (ERR_get_error()) {
+ }
#else
while (unsigned long error = ERR_get_error()) {
char buf[120];
@@ -42,6 +47,7 @@ AeadBaseEncrypter::AeadBaseEncrypter(const EVP_AEAD* aead_alg,
nonce_prefix_size_(nonce_prefix_size) {
DCHECK_LE(key_size_, sizeof(key_));
DCHECK_LE(nonce_prefix_size_, sizeof(nonce_prefix_));
+ DCHECK_GE(kMaxNonceSize, nonce_prefix_size_);
}
AeadBaseEncrypter::~AeadBaseEncrypter() {}
@@ -55,8 +61,8 @@ bool AeadBaseEncrypter::SetKey(StringPiece key) {
EVP_AEAD_CTX_cleanup(ctx_.get());
- if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_,
- auth_tag_size_, nullptr)) {
+ if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
+ nullptr)) {
DLogOpenSslErrors();
return false;
}
@@ -109,17 +115,21 @@ bool AeadBaseEncrypter::EncryptPacket(QuicPacketNumber packet_number,
// TODO(ianswett): Introduce a check to ensure that we don't encrypt with the
// same packet number twice.
const size_t nonce_size = nonce_prefix_size_ + sizeof(packet_number);
- memcpy(output, nonce_prefix_, nonce_prefix_size_);
- memcpy(output + nonce_prefix_size_, &packet_number, sizeof(packet_number));
- if (!Encrypt(StringPiece(output, nonce_size), associated_data, plaintext,
- reinterpret_cast<unsigned char*>(output))) {
+ ALIGNAS(4) char nonce_buffer[kMaxNonceSize];
+ memcpy(nonce_buffer, nonce_prefix_, nonce_prefix_size_);
+ memcpy(nonce_buffer + nonce_prefix_size_, &packet_number,
+ sizeof(packet_number));
+ if (!Encrypt(StringPiece(nonce_buffer, nonce_size), associated_data,
+ plaintext, reinterpret_cast<unsigned char*>(output))) {
return false;
}
*output_length = ciphertext_size;
return true;
}
-size_t AeadBaseEncrypter::GetKeySize() const { return key_size_; }
+size_t AeadBaseEncrypter::GetKeySize() const {
+ return key_size_;
+}
size_t AeadBaseEncrypter::GetNoncePrefixSize() const {
return nonce_prefix_size_;
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter.h b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter.h
index 3d81dba06c8..d0d305ab3d5 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter.h
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter.h
@@ -5,6 +5,10 @@
#ifndef NET_QUIC_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
#define NET_QUIC_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/quic/crypto/aead_base_decrypter.h"
namespace net {
@@ -35,7 +39,7 @@ class NET_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AeadBaseDecrypter {
#endif
const char* cipher_name() const override;
- uint32 cipher_id() const override;
+ uint32_t cipher_id() const override;
private:
DISALLOW_COPY_AND_ASSIGN(Aes128Gcm12Decrypter);
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc
index aa7e17a5714..abbc5658672 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_nss.cc
@@ -33,8 +33,7 @@ void Aes128Gcm12Decrypter::FillAeadParams(StringPiece nonce,
AeadParams* aead_params) const {
aead_params->len = sizeof(aead_params->data.gcm_params);
CK_GCM_PARAMS* gcm_params = &aead_params->data.gcm_params;
- gcm_params->pIv =
- reinterpret_cast<CK_BYTE*>(const_cast<char*>(nonce.data()));
+ gcm_params->pIv = reinterpret_cast<CK_BYTE*>(const_cast<char*>(nonce.data()));
gcm_params->ulIvLen = nonce.size();
gcm_params->pAAD =
reinterpret_cast<CK_BYTE*>(const_cast<char*>(associated_data.data()));
@@ -49,7 +48,7 @@ const char* Aes128Gcm12Decrypter::cipher_name() const {
return "ECDHE-RSA-AES128-GCM-SHA256";
}
-uint32 Aes128Gcm12Decrypter::cipher_id() const {
+uint32_t Aes128Gcm12Decrypter::cipher_id() const {
// TODO(rtenneti): when Chromium requires NSS 3.15.2 or later, use
// TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 instead of 0xC02F.
// Or'ed with 0x03000000 to match OpenSSL/BoringSSL implementations.
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_openssl.cc b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_openssl.cc
index 1647fa7331d..e0d500aa86e 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_openssl.cc
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_openssl.cc
@@ -17,7 +17,9 @@ const size_t kNoncePrefixSize = 4;
} // namespace
Aes128Gcm12Decrypter::Aes128Gcm12Decrypter()
- : AeadBaseDecrypter(EVP_aead_aes_128_gcm(), kKeySize, kAuthTagSize,
+ : AeadBaseDecrypter(EVP_aead_aes_128_gcm(),
+ kKeySize,
+ kAuthTagSize,
kNoncePrefixSize) {
static_assert(kKeySize <= kMaxKeySize, "key size too big");
static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
@@ -30,7 +32,7 @@ const char* Aes128Gcm12Decrypter::cipher_name() const {
return TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
}
-uint32 Aes128Gcm12Decrypter::cipher_id() const {
+uint32_t Aes128Gcm12Decrypter::cipher_id() const {
// This OpenSSL macro has the value 0x0300C02F. The two most significant bytes
// 0x0300 are OpenSSL specific and are NOT part of the TLS CipherSuite value
// for TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc
index 521654d17a0..27afc290ec7 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc
@@ -53,7 +53,7 @@ struct TestGroupInfo {
};
// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a NULL |key|
+// The strings may be empty (zero length). A test vector with a nullptr |key|
// marks the end of an array of test vectors.
struct TestVector {
// Input:
@@ -70,180 +70,122 @@ struct TestVector {
};
const TestGroupInfo test_group_info[] = {
- { 128, 96, 0, 0, 128 },
- { 128, 96, 0, 128, 128 },
- { 128, 96, 128, 0, 128 },
- { 128, 96, 408, 160, 128 },
- { 128, 96, 408, 720, 128 },
- { 128, 96, 104, 0, 128 },
+ {128, 96, 0, 0, 128}, {128, 96, 0, 128, 128}, {128, 96, 128, 0, 128},
+ {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
};
const TestVector test_group_0[] = {
- { "cf063a34d4a9a76c2c86787d3f96db71",
- "113b9785971864c83b01c787",
- "",
- "",
- "72ac8493e3a5228b5d130a69d2510e42",
- ""
- },
- { "a49a5e26a2f8cb63d05546c2a62f5343",
- "907763b19b9b4ab6bd4f0281",
- "",
- "",
- "a2be08210d8c470a8df6e8fbd79ec5cf",
- NULL // FAIL
- },
- { NULL }
-};
+ {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
+ "72ac8493e3a5228b5d130a69d2510e42", ""},
+ {
+ "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
+ "a2be08210d8c470a8df6e8fbd79ec5cf",
+ nullptr // FAIL
+ },
+ {nullptr}};
const TestVector test_group_1[] = {
- { "d1f6af919cde85661208bdce0c27cb22",
- "898c6929b435017bf031c3c5",
- "",
- "7c5faa40e636bbc91107e68010c92b9f",
- "ae45f11777540a2caeb128be8092468a",
- NULL // FAIL
- },
- { "2370e320d4344208e0ff5683f243b213",
- "04dbb82f044d30831c441228",
- "",
- "d43a8e5089eea0d026c03a85178b27da",
- "2a049c049d25aa95969b451d93c31c6e",
- ""
- },
- { NULL }
-};
+ {
+ "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
+ "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
+ nullptr // FAIL
+ },
+ {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
+ "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
+ ""},
+ {nullptr}};
const TestVector test_group_2[] = {
- { "e98b72a9881a84ca6b76e0f43e68647a",
- "8b23299fde174053f3d652ba",
- "5a3c1cf1985dbb8bed818036fdd5ab42",
- "",
- "23c7ab0f952b7091cd324835043b5eb5",
- "28286a321293253c3e0aa2704a278032"
- },
- { "33240636cd3236165f1a553b773e728e",
- "17c4d61493ecdc8f31700b12",
- "47bb7e23f7bdfe05a8091ac90e4f8b2e",
- "",
- "b723c70e931d9785f40fd4ab1d612dc9",
- "95695a5b12f2870b9cc5fdc8f218a97d"
- },
- { "5164df856f1e9cac04a79b808dc5be39",
- "e76925d5355e0584ce871b2b",
- "0216c899c88d6e32c958c7e553daa5bc",
- "",
- "a145319896329c96df291f64efbe0e3a",
- NULL // FAIL
- },
- { NULL }
-};
+ {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
+ "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
+ "28286a321293253c3e0aa2704a278032"},
+ {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
+ "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
+ "95695a5b12f2870b9cc5fdc8f218a97d"},
+ {
+ "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
+ "0216c899c88d6e32c958c7e553daa5bc", "",
+ "a145319896329c96df291f64efbe0e3a",
+ nullptr // FAIL
+ },
+ {nullptr}};
const TestVector test_group_3[] = {
- { "af57f42c60c0fc5a09adb81ab86ca1c3",
- "a2dc01871f37025dc0fc9a79",
- "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
- "338b22f9bad09093276a331e9c79c7f4",
- "41dc38988945fcb44faf2ef72d0061289ef8efd8",
- "4f71e72bde0018f555c5adcce062e005",
- "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
- "5b2f69b041596e8817d0a3c16f8fadeb"
- },
- { "ebc753e5422b377d3cb64b58ffa41b61",
- "2e1821efaced9acf1f241c9b",
- "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
- "f401823e04b05817243d2142a3589878",
- "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
- "534d9234d2351cf30e565de47baece0b",
- "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
- "353a18017f5b36bfc00b1f6dcb7ed485"
- },
- { "52bdbbf9cf477f187ec010589cb39d58",
- "d3be36d3393134951d324b31",
- "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
- "32b992760b3a5f99e9a47838867000a9",
- "93c4fc6a4135f54d640b0c976bf755a06a292c33",
- "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
- NULL // FAIL
- },
- { NULL }
-};
+ {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
+ "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
+ "338b22f9bad09093276a331e9c79c7f4",
+ "41dc38988945fcb44faf2ef72d0061289ef8efd8",
+ "4f71e72bde0018f555c5adcce062e005",
+ "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
+ "5b2f69b041596e8817d0a3c16f8fadeb"},
+ {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
+ "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
+ "f401823e04b05817243d2142a3589878",
+ "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
+ "534d9234d2351cf30e565de47baece0b",
+ "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
+ "353a18017f5b36bfc00b1f6dcb7ed485"},
+ {
+ "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
+ "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
+ "32b992760b3a5f99e9a47838867000a9",
+ "93c4fc6a4135f54d640b0c976bf755a06a292c33",
+ "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
+ nullptr // FAIL
+ },
+ {nullptr}};
const TestVector test_group_4[] = {
- { "da2bb7d581493d692380c77105590201",
- "44aa3e7856ca279d2eb020c6",
- "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
- "f4ee16c761b3c9aeac3da03aa9889c88",
- "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
- "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
- "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
- "9e3ac938d3eb0cadd6f5c9e35d22ba38",
- "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
- "d65dbd1378b196ac270588dd0621f642"
- },
- { "d74e4958717a9d5c0e235b76a926cae8",
- "0b7471141e0c70b1995fd7b1",
- "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
- "b0f1420be29ea547d42c713bc6af66aa",
- "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
- "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
- "34a6039312774cedebf4961f3978b14a26509f96",
- "e192c23cb036f0b31592989119eed55d",
- "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
- "f0a34bc305b88b804c60b90add594a17"
- },
- { "1986310c725ac94ecfe6422e75fc3ee7",
- "93ec4214fa8e6dc4e3afc775",
- "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
- "43edfd365b90d5b325950df0ada058f9",
- "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
- "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
- "72c2cb136c8fd091cc4539877a5d1e72d607f960",
- "8b347853f11d75e81e8a95010be81f17",
- NULL // FAIL
- },
- { NULL }
-};
+ {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
+ "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
+ "f4ee16c761b3c9aeac3da03aa9889c88",
+ "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
+ "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
+ "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
+ "9e3ac938d3eb0cadd6f5c9e35d22ba38",
+ "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
+ "d65dbd1378b196ac270588dd0621f642"},
+ {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
+ "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
+ "b0f1420be29ea547d42c713bc6af66aa",
+ "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
+ "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
+ "34a6039312774cedebf4961f3978b14a26509f96",
+ "e192c23cb036f0b31592989119eed55d",
+ "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
+ "f0a34bc305b88b804c60b90add594a17"},
+ {
+ "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
+ "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
+ "43edfd365b90d5b325950df0ada058f9",
+ "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
+ "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
+ "72c2cb136c8fd091cc4539877a5d1e72d607f960",
+ "8b347853f11d75e81e8a95010be81f17",
+ nullptr // FAIL
+ },
+ {nullptr}};
const TestVector test_group_5[] = {
- { "387218b246c1a8257748b56980e50c94",
- "dd7e014198672be39f95b69d",
- "cdba9e73eaf3d38eceb2b04a8d",
- "",
- "ecf90f4a47c9c626d6fb2c765d201556",
- "48f5b426baca03064554cc2b30"
- },
- { "294de463721e359863887c820524b3d4",
- "3338b35c9d57a5d28190e8c9",
- "2f46634e74b8e4c89812ac83b9",
- "",
- "dabd506764e68b82a7e720aa18da0abe",
- "46a2e55c8e264df211bd112685"
- },
- { "28ead7fd2179e0d12aa6d5d88c58c2dc",
- "5055347f18b4d5add0ae5c41",
- "142d8210c3fb84774cdbd0447a",
- "",
- "5fd321d9cdb01952dc85f034736c2a7d",
- "3b95b981086ee73cc4d0cc1422"
- },
- { "7d7b6c988137b8d470c57bf674a09c87",
- "9edf2aa970d016ac962e1fd8",
- "a85b66c3cb5eab91d5bdc8bc0e",
- "",
- "dc054efc01f3afd21d9c2484819f569a",
- NULL // FAIL
- },
- { NULL }
-};
+ {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
+ "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
+ "48f5b426baca03064554cc2b30"},
+ {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
+ "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
+ "46a2e55c8e264df211bd112685"},
+ {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
+ "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
+ "3b95b981086ee73cc4d0cc1422"},
+ {
+ "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
+ "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
+ nullptr // FAIL
+ },
+ {nullptr}};
const TestVector* const test_group_array[] = {
- test_group_0,
- test_group_1,
- test_group_2,
- test_group_3,
- test_group_4,
- test_group_5,
+ test_group_0, test_group_1, test_group_2,
+ test_group_3, test_group_4, test_group_5,
};
} // namespace
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h
index 2b432fbc262..f2f7b4145f7 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
#define NET_QUIC_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/crypto/aead_base_encrypter.h"
namespace net {
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc
index 847f29dc27c..78c1d3dc847 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc
@@ -33,8 +33,7 @@ void Aes128Gcm12Encrypter::FillAeadParams(StringPiece nonce,
AeadParams* aead_params) const {
aead_params->len = sizeof(aead_params->data.gcm_params);
CK_GCM_PARAMS* gcm_params = &aead_params->data.gcm_params;
- gcm_params->pIv =
- reinterpret_cast<CK_BYTE*>(const_cast<char*>(nonce.data()));
+ gcm_params->pIv = reinterpret_cast<CK_BYTE*>(const_cast<char*>(nonce.data()));
gcm_params->ulIvLen = nonce.size();
gcm_params->pAAD =
reinterpret_cast<CK_BYTE*>(const_cast<char*>(associated_data.data()));
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc
index b87d0fc4245..2d7ea8f22a2 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc
@@ -16,7 +16,9 @@ const size_t kNoncePrefixSize = 4;
} // namespace
Aes128Gcm12Encrypter::Aes128Gcm12Encrypter()
- : AeadBaseEncrypter(EVP_aead_aes_128_gcm(), kKeySize, kAuthTagSize,
+ : AeadBaseEncrypter(EVP_aead_aes_128_gcm(),
+ kKeySize,
+ kAuthTagSize,
kNoncePrefixSize) {
static_assert(kKeySize <= kMaxKeySize, "key size too big");
static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
index b7345b5c458..82539a2f84b 100644
--- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
+++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
@@ -53,7 +53,7 @@ struct TestGroupInfo {
};
// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a NULL |key|
+// The strings may be empty (zero length). A test vector with a nullptr |key|
// marks the end of an array of test vectors.
struct TestVector {
const char* key;
@@ -65,141 +65,85 @@ struct TestVector {
};
const TestGroupInfo test_group_info[] = {
- { 128, 96, 0, 0, 128 },
- { 128, 96, 0, 128, 128 },
- { 128, 96, 128, 0, 128 },
- { 128, 96, 408, 160, 128 },
- { 128, 96, 408, 720, 128 },
- { 128, 96, 104, 0, 128 },
+ {128, 96, 0, 0, 128}, {128, 96, 0, 128, 128}, {128, 96, 128, 0, 128},
+ {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
};
const TestVector test_group_0[] = {
- { "11754cd72aec309bf52f7687212e8957",
- "3c819d9a9bed087615030b65",
- "",
- "",
- "",
- "250327c674aaf477aef2675748cf6971"
- },
- { "ca47248ac0b6f8372a97ac43508308ed",
- "ffd2b598feabc9019262d2be",
- "",
- "",
- "",
- "60d20404af527d248d893ae495707d1a"
- },
- { NULL }
-};
+ {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
+ "250327c674aaf477aef2675748cf6971"},
+ {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
+ "60d20404af527d248d893ae495707d1a"},
+ {nullptr}};
const TestVector test_group_1[] = {
- { "77be63708971c4e240d1cb79e8d77feb",
- "e0e00f19fed7ba0136a797f3",
- "",
- "7a43ec1d9c0a5a78a0b16533a6213cab",
- "",
- "209fcc8d3675ed938e9c7166709dd946"
- },
- { "7680c5d3ca6154758e510f4d25b98820",
- "f8f105f9c3df4965780321f8",
- "",
- "c94c410194c765e3dcc7964379758ed3",
- "",
- "94dca8edfcf90bb74b153c8d48a17930"
- },
- { NULL }
-};
+ {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
+ "7a43ec1d9c0a5a78a0b16533a6213cab", "",
+ "209fcc8d3675ed938e9c7166709dd946"},
+ {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
+ "c94c410194c765e3dcc7964379758ed3", "",
+ "94dca8edfcf90bb74b153c8d48a17930"},
+ {nullptr}};
const TestVector test_group_2[] = {
- { "7fddb57453c241d03efbed3ac44e371c",
- "ee283a3fc75575e33efd4887",
- "d5de42b461646c255c87bd2962d3b9a2",
- "",
- "2ccda4a5415cb91e135c2a0f78c9b2fd",
- "b36d1df9b9d5e596f83e8b7f52971cb3"
- },
- { "ab72c77b97cb5fe9a382d9fe81ffdbed",
- "54cc7dc2c37ec006bcc6d1da",
- "007c5e5b3e59df24a7c355584fc1518d",
- "",
- "0e1bde206a07a9c2c1b65300f8c64997",
- "2b4401346697138c7a4891ee59867d0c"
- },
- { NULL }
-};
+ {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
+ "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
+ "b36d1df9b9d5e596f83e8b7f52971cb3"},
+ {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
+ "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
+ "2b4401346697138c7a4891ee59867d0c"},
+ {nullptr}};
const TestVector test_group_3[] = {
- { "fe47fcce5fc32665d2ae399e4eec72ba",
- "5adb9609dbaeb58cbd6e7275",
- "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
- "b840382c4bccaf3bafb4ca8429bea063",
- "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
- "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
- "3ddbc5db8778371495da76d269e5db3e",
- "291ef1982e4defedaa2249f898556b47"
- },
- { "ec0c2ba17aa95cd6afffe949da9cc3a8",
- "296bce5b50b7d66096d627ef",
- "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
- "b764b9611f6c0f8641843d5d58f3a242",
- "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
- "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
- "5506fde6309ffc19e716eddf1a828c5a",
- "890147971946b627c40016da1ecf3e77"
- },
- { NULL }
-};
+ {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
+ "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
+ "b840382c4bccaf3bafb4ca8429bea063",
+ "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
+ "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
+ "3ddbc5db8778371495da76d269e5db3e",
+ "291ef1982e4defedaa2249f898556b47"},
+ {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
+ "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
+ "b764b9611f6c0f8641843d5d58f3a242",
+ "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
+ "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
+ "5506fde6309ffc19e716eddf1a828c5a",
+ "890147971946b627c40016da1ecf3e77"},
+ {nullptr}};
const TestVector test_group_4[] = {
- { "2c1f21cf0f6fb3661943155c3e3d8492",
- "23cb5ff362e22426984d1907",
- "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
- "8b5615ba7c1220ff6510e259f06655d8",
- "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
- "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
- "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
- "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
- "b6ad57af43e1895df9dca2a5344a62cc",
- "57a3ee28136e94c74838997ae9823f3a"
- },
- { "d9f7d2411091f947b4d6f1e2d1f0fb2e",
- "e1934f5db57cc983e6b180e7",
- "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
- "c2c6f6166f4a59431e182663fcaea05a",
- "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
- "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
- "15d2e51398344b16bee1ed7c499b353d6c597af8",
- "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
- "3c7891c2a91fbc48db29967ec9542b23",
- "21b51ca862cb637cdd03b99a0f93b134"
- },
- { NULL }
-};
+ {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
+ "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
+ "8b5615ba7c1220ff6510e259f06655d8",
+ "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
+ "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
+ "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
+ "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
+ "b6ad57af43e1895df9dca2a5344a62cc",
+ "57a3ee28136e94c74838997ae9823f3a"},
+ {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
+ "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
+ "c2c6f6166f4a59431e182663fcaea05a",
+ "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
+ "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
+ "15d2e51398344b16bee1ed7c499b353d6c597af8",
+ "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
+ "3c7891c2a91fbc48db29967ec9542b23",
+ "21b51ca862cb637cdd03b99a0f93b134"},
+ {nullptr}};
const TestVector test_group_5[] = {
- { "fe9bb47deb3a61e423c2231841cfd1fb",
- "4d328eb776f500a2f7fb47aa",
- "f1cc3818e421876bb6b8bbd6c9",
- "",
- "b88c5c1977b35b517b0aeae967",
- "43fd4727fe5cdb4b5b42818dea7ef8c9"
- },
- { "6703df3701a7f54911ca72e24dca046a",
- "12823ab601c350ea4bc2488c",
- "793cd125b0b84a043e3ac67717",
- "",
- "b2051c80014f42f08735a7b0cd",
- "38e6bcd29962e5f2c13626b85a877101"
- },
- { NULL }
-};
+ {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
+ "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
+ "43fd4727fe5cdb4b5b42818dea7ef8c9"},
+ {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
+ "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
+ "38e6bcd29962e5f2c13626b85a877101"},
+ {nullptr}};
const TestVector* const test_group_array[] = {
- test_group_0,
- test_group_1,
- test_group_2,
- test_group_3,
- test_group_4,
- test_group_5,
+ test_group_0, test_group_1, test_group_2,
+ test_group_3, test_group_4, test_group_5,
};
} // namespace
diff --git a/chromium/net/quic/crypto/cert_compressor.cc b/chromium/net/quic/crypto/cert_compressor.cc
index cb44d355a8d..5851bd95b2a 100644
--- a/chromium/net/quic/crypto/cert_compressor.cc
+++ b/chromium/net/quic/crypto/cert_compressor.cc
@@ -21,130 +21,130 @@ namespace {
// in order to help zlib. This was generated via a fairly dumb algorithm from
// the Alexa Top 5000 set - we could probably do better.
static const unsigned char kCommonCertSubstrings[] = {
- 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
- 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
- 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
- 0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01,
- 0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07,
- 0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
- 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34,
- 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
- 0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
- 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65,
- 0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
- 0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
- 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2,
- 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
- 0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
- 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03,
- 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
- 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08,
- 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30,
- 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74,
- 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33,
- 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
- 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
- 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55,
- 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37,
- 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
- 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c,
- 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
- 0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
- 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
- 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
- 0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
- 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
- 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
- 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
- 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
- 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
- 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
- 0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17,
- 0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01,
- 0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
- 0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
- 0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17,
- 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72,
- 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
- 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65,
- 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
- 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73,
- 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68,
- 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76,
- 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e,
- 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11,
- 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11,
- 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01,
- 0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50,
- 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
- 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30,
- 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61,
- 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56,
- 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31,
- 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65,
- 0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63,
- 0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53,
- 0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41,
- 0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
- 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72,
- 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a,
- 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72,
- 0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72,
- 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e,
- 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
- 0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63,
- 0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
- 0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
- 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06,
- 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64,
- 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
- 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74,
- 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72,
- 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
- 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee,
- 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27,
- 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30,
- 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+ 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
+ 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+ 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
+ 0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01,
+ 0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07,
+ 0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
+ 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34,
+ 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+ 0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
+ 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+ 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65,
+ 0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
+ 0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2,
+ 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+ 0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
+ 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+ 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08,
+ 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30,
+ 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74,
+ 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
+ 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33,
+ 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
+ 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+ 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55,
+ 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37,
+ 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
+ 0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+ 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+ 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
+ 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
+ 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
+ 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
+ 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
+ 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
+ 0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17,
+ 0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
+ 0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17,
+ 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72,
+ 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+ 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65,
+ 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
+ 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39,
+ 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73,
+ 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68,
+ 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76,
+ 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11,
+ 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11,
+ 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01,
+ 0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50,
+ 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
+ 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61,
+ 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56,
+ 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31,
+ 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65,
+ 0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63,
+ 0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53,
+ 0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41,
+ 0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+ 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72,
+ 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a,
+ 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72,
+ 0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63,
+ 0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
+ 0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
+ 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+ 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64,
+ 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
+ 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74,
+ 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72,
+ 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee,
+ 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27,
+ 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
};
// CertEntry represents a certificate in compressed form. Each entry is one of
@@ -166,9 +166,9 @@ struct CertEntry {
};
Type type;
- uint64 hash;
- uint64 set_hash;
- uint32 index;
+ uint64_t hash;
+ uint64_t set_hash;
+ uint32_t index;
};
// MatchCerts returns a vector of CertEntries describing how to most
@@ -183,23 +183,23 @@ vector<CertEntry> MatchCerts(const vector<string>& certs,
entries.reserve(certs.size());
const bool cached_valid =
- client_cached_cert_hashes.size() % sizeof(uint64) == 0 &&
+ client_cached_cert_hashes.size() % sizeof(uint64_t) == 0 &&
!client_cached_cert_hashes.empty();
- for (vector<string>::const_iterator i = certs.begin();
- i != certs.end(); ++i) {
+ for (vector<string>::const_iterator i = certs.begin(); i != certs.end();
+ ++i) {
CertEntry entry;
if (cached_valid) {
bool cached = false;
- uint64 hash = QuicUtils::FNV1a_64_Hash(i->data(), i->size());
+ uint64_t hash = QuicUtils::FNV1a_64_Hash(i->data(), i->size());
// This assumes that the machine is little-endian.
for (size_t j = 0; j < client_cached_cert_hashes.size();
- j += sizeof(uint64)) {
- uint64 cached_hash;
+ j += sizeof(uint64_t)) {
+ uint64_t cached_hash;
memcpy(&cached_hash, client_cached_cert_hashes.data() + j,
- sizeof(uint64));
+ sizeof(uint64_t));
if (hash != cached_hash) {
continue;
}
@@ -216,8 +216,9 @@ vector<CertEntry> MatchCerts(const vector<string>& certs,
}
}
- if (common_sets && common_sets->MatchCert(*i, client_common_set_hashes,
- &entry.set_hash, &entry.index)) {
+ if (common_sets &&
+ common_sets->MatchCert(*i, client_common_set_hashes, &entry.set_hash,
+ &entry.index)) {
entry.type = CertEntry::COMMON;
entries.push_back(entry);
continue;
@@ -242,10 +243,10 @@ size_t CertEntriesSize(const vector<CertEntry>& entries) {
case CertEntry::COMPRESSED:
break;
case CertEntry::CACHED:
- entries_size += sizeof(uint64);
+ entries_size += sizeof(uint64_t);
break;
case CertEntry::COMMON:
- entries_size += sizeof(uint64) + sizeof(uint32);
+ entries_size += sizeof(uint64_t) + sizeof(uint32_t);
break;
}
}
@@ -257,23 +258,23 @@ size_t CertEntriesSize(const vector<CertEntry>& entries) {
// SerializeCertEntries serialises |entries| to |out|, which must have enough
// space to contain them.
-void SerializeCertEntries(uint8* out, const vector<CertEntry>& entries) {
+void SerializeCertEntries(uint8_t* out, const vector<CertEntry>& entries) {
for (vector<CertEntry>::const_iterator i = entries.begin();
i != entries.end(); ++i) {
- *out++ = static_cast<uint8>(i->type);
+ *out++ = static_cast<uint8_t>(i->type);
switch (i->type) {
case CertEntry::COMPRESSED:
break;
case CertEntry::CACHED:
memcpy(out, &i->hash, sizeof(i->hash));
- out += sizeof(uint64);
+ out += sizeof(uint64_t);
break;
case CertEntry::COMMON:
// Assumes a little-endian machine.
memcpy(out, &i->set_hash, sizeof(i->set_hash));
out += sizeof(i->set_hash);
- memcpy(out, &i->index, sizeof(uint32));
- out += sizeof(uint32);
+ memcpy(out, &i->index, sizeof(uint32_t));
+ out += sizeof(uint32_t);
break;
}
}
@@ -317,12 +318,12 @@ string ZlibDictForEntries(const vector<CertEntry>& entries,
}
// HashCerts returns the FNV-1a hashes of |certs|.
-vector<uint64> HashCerts(const vector<string>& certs) {
- vector<uint64> ret;
+vector<uint64_t> HashCerts(const vector<string>& certs) {
+ vector<uint64_t> ret;
ret.reserve(certs.size());
- for (vector<string>::const_iterator i = certs.begin();
- i != certs.end(); ++i) {
+ for (vector<string>::const_iterator i = certs.begin(); i != certs.end();
+ ++i) {
ret.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size()));
}
@@ -339,7 +340,7 @@ bool ParseEntries(StringPiece* in_out,
vector<CertEntry>* out_entries,
vector<string>* out_certs) {
StringPiece in = *in_out;
- vector<uint64> cached_hashes;
+ vector<uint64_t> cached_hashes;
out_entries->clear();
out_certs->clear();
@@ -349,7 +350,7 @@ bool ParseEntries(StringPiece* in_out,
return false;
}
CertEntry entry;
- const uint8 type_byte = in[0];
+ const uint8_t type_byte = in[0];
in.remove_prefix(1);
if (type_byte == 0) {
@@ -363,11 +364,11 @@ bool ParseEntries(StringPiece* in_out,
out_certs->push_back(string());
break;
case CertEntry::CACHED: {
- if (in.size() < sizeof(uint64)) {
+ if (in.size() < sizeof(uint64_t)) {
return false;
}
- memcpy(&entry.hash, in.data(), sizeof(uint64));
- in.remove_prefix(sizeof(uint64));
+ memcpy(&entry.hash, in.data(), sizeof(uint64_t));
+ in.remove_prefix(sizeof(uint64_t));
if (cached_hashes.size() != cached_certs.size()) {
cached_hashes = HashCerts(cached_certs);
@@ -389,13 +390,13 @@ bool ParseEntries(StringPiece* in_out,
if (!common_sets) {
return false;
}
- if (in.size() < sizeof(uint64) + sizeof(uint32)) {
+ if (in.size() < sizeof(uint64_t) + sizeof(uint32_t)) {
return false;
}
- memcpy(&entry.set_hash, in.data(), sizeof(uint64));
- in.remove_prefix(sizeof(uint64));
- memcpy(&entry.index, in.data(), sizeof(uint32));
- in.remove_prefix(sizeof(uint32));
+ memcpy(&entry.set_hash, in.data(), sizeof(uint64_t));
+ in.remove_prefix(sizeof(uint64_t));
+ memcpy(&entry.index, in.data(), sizeof(uint32_t));
+ in.remove_prefix(sizeof(uint32_t));
StringPiece cert = common_sets->GetCert(entry.set_hash, entry.index);
if (cert.empty()) {
@@ -429,9 +430,7 @@ class ScopedZLib {
z_ = z;
}
- ~ScopedZLib() {
- Clear();
- }
+ ~ScopedZLib() { Clear(); }
private:
void Clear() {
@@ -453,7 +452,6 @@ class ScopedZLib {
} // anonymous namespace
-
// static
string CertCompressor::CompressChain(const vector<string>& certs,
StringPiece client_common_set_hashes,
@@ -466,7 +464,7 @@ string CertCompressor::CompressChain(const vector<string>& certs,
size_t uncompressed_size = 0;
for (size_t i = 0; i < entries.size(); i++) {
if (entries[i].type == CertEntry::COMPRESSED) {
- uncompressed_size += 4 /* uint32 length */ + certs[i].size();
+ uncompressed_size += 4 /* uint32_t length */ + certs[i].size();
}
}
@@ -485,8 +483,8 @@ string CertCompressor::CompressChain(const vector<string>& certs,
string zlib_dict = ZlibDictForEntries(entries, certs);
- rv = deflateSetDictionary(&z, reinterpret_cast<const uint8*>(&zlib_dict[0]),
- zlib_dict.size());
+ rv = deflateSetDictionary(
+ &z, reinterpret_cast<const uint8_t*>(&zlib_dict[0]), zlib_dict.size());
DCHECK_EQ(Z_OK, rv);
if (rv != Z_OK) {
return "";
@@ -501,7 +499,7 @@ string CertCompressor::CompressChain(const vector<string>& certs,
result.resize(entries_size + (uncompressed_size > 0 ? 4 : 0) +
compressed_size);
- uint8* j = reinterpret_cast<uint8*>(&result[0]);
+ uint8_t* j = reinterpret_cast<uint8_t*>(&result[0]);
SerializeCertEntries(j, entries);
j += entries_size;
@@ -509,9 +507,9 @@ string CertCompressor::CompressChain(const vector<string>& certs,
return result;
}
- uint32 uncompressed_size_32 = uncompressed_size;
- memcpy(j, &uncompressed_size_32, sizeof(uint32));
- j += sizeof(uint32);
+ uint32_t uncompressed_size_32 = uncompressed_size;
+ memcpy(j, &uncompressed_size_32, sizeof(uint32_t));
+ j += sizeof(uint32_t);
int rv;
@@ -523,8 +521,8 @@ string CertCompressor::CompressChain(const vector<string>& certs,
continue;
}
- uint32 length32 = certs[i].size();
- z.next_in = reinterpret_cast<uint8*>(&length32);
+ uint32_t length32 = certs[i].size();
+ z.next_in = reinterpret_cast<uint8_t*>(&length32);
z.avail_in = sizeof(length32);
rv = deflate(&z, Z_NO_FLUSH);
DCHECK_EQ(Z_OK, rv);
@@ -534,7 +532,7 @@ string CertCompressor::CompressChain(const vector<string>& certs,
}
z.next_in =
- const_cast<uint8*>(reinterpret_cast<const uint8*>(certs[i].data()));
+ const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(certs[i].data()));
z.avail_in = certs[i].size();
rv = deflate(&z, Z_NO_FLUSH);
DCHECK_EQ(Z_OK, rv);
@@ -566,30 +564,31 @@ bool CertCompressor::DecompressChain(StringPiece in,
}
DCHECK_EQ(entries.size(), out_certs->size());
- scoped_ptr<uint8[]> uncompressed_data;
+ scoped_ptr<uint8_t[]> uncompressed_data;
StringPiece uncompressed;
if (!in.empty()) {
- if (in.size() < sizeof(uint32)) {
+ if (in.size() < sizeof(uint32_t)) {
return false;
}
- uint32 uncompressed_size;
+ uint32_t uncompressed_size;
memcpy(&uncompressed_size, in.data(), sizeof(uncompressed_size));
- in.remove_prefix(sizeof(uint32));
+ in.remove_prefix(sizeof(uint32_t));
if (uncompressed_size > 128 * 1024) {
return false;
}
- uncompressed_data.reset(new uint8[uncompressed_size]);
+ uncompressed_data.reset(new uint8_t[uncompressed_size]);
z_stream z;
ScopedZLib scoped_z(ScopedZLib::INFLATE);
memset(&z, 0, sizeof(z));
z.next_out = uncompressed_data.get();
z.avail_out = uncompressed_size;
- z.next_in = const_cast<uint8*>(reinterpret_cast<const uint8*>(in.data()));
+ z.next_in =
+ const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(in.data()));
z.avail_in = in.size();
if (Z_OK != inflateInit(&z)) {
@@ -600,7 +599,7 @@ bool CertCompressor::DecompressChain(StringPiece in,
int rv = inflate(&z, Z_FINISH);
if (rv == Z_NEED_DICT) {
string zlib_dict = ZlibDictForEntries(entries, *out_certs);
- const uint8* dict = reinterpret_cast<const uint8*>(zlib_dict.data());
+ const uint8_t* dict = reinterpret_cast<const uint8_t*>(zlib_dict.data());
if (Z_OK != inflateSetDictionary(&z, dict, zlib_dict.size())) {
return false;
}
@@ -618,12 +617,12 @@ bool CertCompressor::DecompressChain(StringPiece in,
for (size_t i = 0; i < entries.size(); i++) {
switch (entries[i].type) {
case CertEntry::COMPRESSED:
- if (uncompressed.size() < sizeof(uint32)) {
+ if (uncompressed.size() < sizeof(uint32_t)) {
return false;
}
- uint32 cert_len;
+ uint32_t cert_len;
memcpy(&cert_len, uncompressed.data(), sizeof(cert_len));
- uncompressed.remove_prefix(sizeof(uint32));
+ uncompressed.remove_prefix(sizeof(uint32_t));
if (uncompressed.size() < cert_len) {
return false;
}
diff --git a/chromium/net/quic/crypto/cert_compressor.h b/chromium/net/quic/crypto/cert_compressor.h
index d95c5bce540..c700f7ce616 100644
--- a/chromium/net/quic/crypto/cert_compressor.h
+++ b/chromium/net/quic/crypto/cert_compressor.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/quic/crypto/common_cert_set.h"
diff --git a/chromium/net/quic/crypto/cert_compressor_test.cc b/chromium/net/quic/crypto/cert_compressor_test.cc
index 1b3c28af47a..baefae548f0 100644
--- a/chromium/net/quic/crypto/cert_compressor_test.cc
+++ b/chromium/net/quic/crypto/cert_compressor_test.cc
@@ -46,17 +46,18 @@ TEST(CertCompressor, Compressed) {
TEST(CertCompressor, Common) {
vector<string> chain;
chain.push_back("testcert");
- static const uint64 set_hash = 42;
+ static const uint64_t set_hash = 42;
scoped_ptr<CommonCertSets> common_sets(
CryptoTestUtils::MockCommonCertSets(chain[0], set_hash, 1));
const string compressed = CertCompressor::CompressChain(
chain,
StringPiece(reinterpret_cast<const char*>(&set_hash), sizeof(set_hash)),
StringPiece(), common_sets.get());
- const string common("03" /* common */
- "2A00000000000000" /* set hash 42 */
- "01000000" /* index 1 */
- "00" /* end of list */);
+ const string common(
+ "03" /* common */
+ "2A00000000000000" /* set hash 42 */
+ "01000000" /* index 1 */
+ "00" /* end of list */);
EXPECT_EQ(common.data(),
base::HexEncode(compressed.data(), compressed.size()));
@@ -70,14 +71,14 @@ TEST(CertCompressor, Common) {
TEST(CertCompressor, Cached) {
vector<string> chain;
chain.push_back("testcert");
- uint64 hash = QuicUtils::FNV1a_64_Hash(chain[0].data(), chain[0].size());
+ uint64_t hash = QuicUtils::FNV1a_64_Hash(chain[0].data(), chain[0].size());
StringPiece hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash));
const string compressed =
CertCompressor::CompressChain(chain, StringPiece(), hash_bytes, nullptr);
EXPECT_EQ("02" /* cached */ +
- base::HexEncode(hash_bytes.data(), hash_bytes.size()) +
- "00" /* end of list */,
+ base::HexEncode(hash_bytes.data(), hash_bytes.size()) +
+ "00" /* end of list */,
base::HexEncode(compressed.data(), compressed.size()));
vector<string> cached_certs, chain2;
@@ -94,14 +95,14 @@ TEST(CertCompressor, BadInputs) {
/* bad entry type */
const string bad_entry("04");
EXPECT_FALSE(CertCompressor::DecompressChain(
- base::HexEncode(bad_entry.data(), bad_entry.size()),
- cached_certs, nullptr, &chain));
+ base::HexEncode(bad_entry.data(), bad_entry.size()), cached_certs,
+ nullptr, &chain));
/* no terminator */
const string no_terminator("01");
EXPECT_FALSE(CertCompressor::DecompressChain(
- base::HexEncode(no_terminator.data(), no_terminator.size()),
- cached_certs, nullptr, &chain));
+ base::HexEncode(no_terminator.data(), no_terminator.size()), cached_certs,
+ nullptr, &chain));
/* hash truncated */
const string hash_truncated("0200");
@@ -118,7 +119,9 @@ TEST(CertCompressor, BadInputs) {
/* without a CommonCertSets */
const string without_a_common_cert_set(
- "03" "0000000000000000" "00000000");
+ "03"
+ "0000000000000000"
+ "00000000");
EXPECT_FALSE(CertCompressor::DecompressChain(
base::HexEncode(without_a_common_cert_set.data(),
without_a_common_cert_set.size()),
@@ -129,7 +132,9 @@ TEST(CertCompressor, BadInputs) {
/* incorrect hash and index */
const string incorrect_hash_and_index(
- "03" "a200000000000000" "00000000");
+ "03"
+ "a200000000000000"
+ "00000000");
EXPECT_FALSE(CertCompressor::DecompressChain(
base::HexEncode(incorrect_hash_and_index.data(),
incorrect_hash_and_index.size()),
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_decrypter.h b/chromium/net/quic/crypto/chacha20_poly1305_decrypter.h
index 2ca1b60a5e3..fad9bbbe5fb 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_decrypter.h
+++ b/chromium/net/quic/crypto/chacha20_poly1305_decrypter.h
@@ -5,6 +5,10 @@
#ifndef NET_QUIC_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
#define NET_QUIC_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/quic/crypto/aead_base_decrypter.h"
namespace net {
@@ -26,9 +30,6 @@ class NET_EXPORT_PRIVATE ChaCha20Poly1305Decrypter : public AeadBaseDecrypter {
ChaCha20Poly1305Decrypter();
~ChaCha20Poly1305Decrypter() override;
- // Returns true if the underlying crypto library supports ChaCha20+Poly1305.
- static bool IsSupported();
-
#if !defined(USE_OPENSSL)
protected:
// AeadBaseDecrypter methods:
@@ -39,7 +40,7 @@ class NET_EXPORT_PRIVATE ChaCha20Poly1305Decrypter : public AeadBaseDecrypter {
#endif
const char* cipher_name() const override;
- uint32 cipher_id() const override;
+ uint32_t cipher_id() const override;
private:
DISALLOW_COPY_AND_ASSIGN(ChaCha20Poly1305Decrypter);
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc b/chromium/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc
index d69097e44e6..893f8a7cdb8 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc
+++ b/chromium/net/quic/crypto/chacha20_poly1305_decrypter_nss.cc
@@ -29,11 +29,6 @@ ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
-// static
-bool ChaCha20Poly1305Decrypter::IsSupported() {
- return true;
-}
-
void ChaCha20Poly1305Decrypter::FillAeadParams(
StringPiece nonce,
const StringPiece& associated_data,
@@ -57,7 +52,7 @@ const char* ChaCha20Poly1305Decrypter::cipher_name() const {
return "ECDHE-RSA-CHACHA20-POLY1305";
}
-uint32 ChaCha20Poly1305Decrypter::cipher_id() const {
+uint32_t ChaCha20Poly1305Decrypter::cipher_id() const {
// TODO(rtenneti): when Chromium requires NSS 3.15.2 or later, use
// TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 instead of 0xCC13.
// "OR" 0x03000000 to match OpenSSL/BoringSSL implementations.
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_decrypter_openssl.cc b/chromium/net/quic/crypto/chacha20_poly1305_decrypter_openssl.cc
index 78c988df6eb..683f13b763e 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_decrypter_openssl.cc
+++ b/chromium/net/quic/crypto/chacha20_poly1305_decrypter_openssl.cc
@@ -16,8 +16,12 @@ const size_t kNoncePrefixSize = 0;
} // namespace
+// QUIC currently uses the draft-agl-tls-chacha20poly1305-04 ChaCha20-Poly1305
+// construction rather than RFC 7539.
ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
- : AeadBaseDecrypter(EVP_aead_chacha20_poly1305(), kKeySize, kAuthTagSize,
+ : AeadBaseDecrypter(EVP_aead_chacha20_poly1305_old(),
+ kKeySize,
+ kAuthTagSize,
kNoncePrefixSize) {
static_assert(kKeySize <= kMaxKeySize, "key size too big");
static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
@@ -26,15 +30,12 @@ ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
-// static
-bool ChaCha20Poly1305Decrypter::IsSupported() { return true; }
-
const char* ChaCha20Poly1305Decrypter::cipher_name() const {
- return TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305;
+ return TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD;
}
-uint32 ChaCha20Poly1305Decrypter::cipher_id() const {
- return TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305;
+uint32_t ChaCha20Poly1305Decrypter::cipher_id() const {
+ return TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD;
}
} // namespace net
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_decrypter_test.cc b/chromium/net/quic/crypto/chacha20_poly1305_decrypter_test.cc
index 86362db94ff..665595dd7f5 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_decrypter_test.cc
+++ b/chromium/net/quic/crypto/chacha20_poly1305_decrypter_test.cc
@@ -14,7 +14,7 @@ namespace {
// The test vectors come from draft-agl-tls-chacha20poly1305-04 Section 7.
// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a NULL |key|
+// The strings may be empty (zero length). A test vector with a nullptr |key|
// marks the end of an array of test vectors.
struct TestVector {
// Input:
@@ -30,39 +30,39 @@ struct TestVector {
};
const TestVector test_vectors[] = {
- { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
+ {"4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
+ "0a1007",
+ "cd7cf67be39c794a", "87e229d4500845a079c0",
+ "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475", // "3896e1d6" truncated.
+ "86d09974840bded2a5ca"},
+ // Modify the ciphertext (ChaCha20 encryption output).
+ {
+ "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
"0a1007",
- "cd7cf67be39c794a",
- "87e229d4500845a079c0",
- "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475", // "3896e1d6" truncated.
- "86d09974840bded2a5ca"
- },
- // Modify the ciphertext (ChaCha20 encryption output).
- { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
+ "cd7cf67be39c794a", "87e229d4500845a079c0",
+ "f3e446f7ede9a19b62a4677dabf4e3d24b876bb28475", // "3896e1d6"
+ // truncated.
+ nullptr // FAIL
+ },
+ // Modify the ciphertext (Poly1305 authenticator).
+ {
+ "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
"0a1007",
- "cd7cf67be39c794a",
- "87e229d4500845a079c0",
- "f3e446f7ede9a19b62a4677dabf4e3d24b876bb28475", // "3896e1d6" truncated.
- NULL // FAIL
- },
- // Modify the ciphertext (Poly1305 authenticator).
- { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
+ "cd7cf67be39c794a", "87e229d4500845a079c0",
+ "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28476", // "3896e1d6"
+ // truncated.
+ nullptr // FAIL
+ },
+ // Modify the associated data.
+ {
+ "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
"0a1007",
- "cd7cf67be39c794a",
- "87e229d4500845a079c0",
- "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28476", // "3896e1d6" truncated.
- NULL // FAIL
- },
- // Modify the associated data.
- { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
- "0a1007",
- "dd7cf67be39c794a",
- "87e229d4500845a079c0",
- "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475", // "3896e1d6" truncated.
- NULL // FAIL
- },
- { NULL }
-};
+ "dd7cf67be39c794a", "87e229d4500845a079c0",
+ "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475", // "3896e1d6"
+ // truncated.
+ nullptr // FAIL
+ },
+ {nullptr}};
} // namespace
@@ -92,11 +92,6 @@ QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter,
}
TEST(ChaCha20Poly1305DecrypterTest, Decrypt) {
- if (!ChaCha20Poly1305Decrypter::IsSupported()) {
- LOG(INFO) << "ChaCha20+Poly1305 not supported. Test skipped.";
- return;
- }
-
for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
// If not present then decryption is expected to fail.
bool has_pt = test_vectors[i].pt;
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_encrypter.h b/chromium/net/quic/crypto/chacha20_poly1305_encrypter.h
index 6504970929b..dfdfffe4547 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_encrypter.h
+++ b/chromium/net/quic/crypto/chacha20_poly1305_encrypter.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
#define NET_QUIC_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/crypto/aead_base_encrypter.h"
namespace net {
@@ -26,9 +29,6 @@ class NET_EXPORT_PRIVATE ChaCha20Poly1305Encrypter : public AeadBaseEncrypter {
ChaCha20Poly1305Encrypter();
~ChaCha20Poly1305Encrypter() override;
- // Returns true if the underlying crypto library supports ChaCha20+Poly1305.
- static bool IsSupported();
-
#if !defined(USE_OPENSSL)
protected:
// AeadBaseEncrypter methods:
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_encrypter_nss.cc b/chromium/net/quic/crypto/chacha20_poly1305_encrypter_nss.cc
index cdb21dd4785..9b0e9bfb3d8 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_encrypter_nss.cc
+++ b/chromium/net/quic/crypto/chacha20_poly1305_encrypter_nss.cc
@@ -29,11 +29,6 @@ ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter()
ChaCha20Poly1305Encrypter::~ChaCha20Poly1305Encrypter() {}
-// static
-bool ChaCha20Poly1305Encrypter::IsSupported() {
- return true;
-}
-
void ChaCha20Poly1305Encrypter::FillAeadParams(StringPiece nonce,
StringPiece associated_data,
size_t auth_tag_size,
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_encrypter_openssl.cc b/chromium/net/quic/crypto/chacha20_poly1305_encrypter_openssl.cc
index 91e75d04482..9a75eec135f 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_encrypter_openssl.cc
+++ b/chromium/net/quic/crypto/chacha20_poly1305_encrypter_openssl.cc
@@ -15,8 +15,12 @@ const size_t kNoncePrefixSize = 0;
} // namespace
+// QUIC currently uses the draft-agl-tls-chacha20poly1305-04 ChaCha20-Poly1305
+// construction rather than RFC 7539.
ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter()
- : AeadBaseEncrypter(EVP_aead_chacha20_poly1305(), kKeySize, kAuthTagSize,
+ : AeadBaseEncrypter(EVP_aead_chacha20_poly1305_old(),
+ kKeySize,
+ kAuthTagSize,
kNoncePrefixSize) {
static_assert(kKeySize <= kMaxKeySize, "key size too big");
static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
@@ -25,7 +29,4 @@ ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter()
ChaCha20Poly1305Encrypter::~ChaCha20Poly1305Encrypter() {}
-// static
-bool ChaCha20Poly1305Encrypter::IsSupported() { return true; }
-
} // namespace net
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_encrypter_test.cc b/chromium/net/quic/crypto/chacha20_poly1305_encrypter_test.cc
index 5b05c7f03c5..0c4918208e1 100644
--- a/chromium/net/quic/crypto/chacha20_poly1305_encrypter_test.cc
+++ b/chromium/net/quic/crypto/chacha20_poly1305_encrypter_test.cc
@@ -14,7 +14,7 @@ namespace {
// The test vectors come from draft-agl-tls-chacha20poly1305-04 Section 7.
// Each test vector consists of five strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a NULL |key|
+// The strings may be empty (zero length). A test vector with a nullptr |key|
// marks the end of an array of test vectors.
struct TestVector {
const char* key;
@@ -25,15 +25,13 @@ struct TestVector {
};
const TestVector test_vectors[] = {
- { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
+ {
+ "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
"0a1007",
- "86d09974840bded2a5ca",
- "cd7cf67be39c794a",
- "87e229d4500845a079c0",
- "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475" // "3896e1d6" truncated.
- },
- { NULL }
-};
+ "86d09974840bded2a5ca", "cd7cf67be39c794a", "87e229d4500845a079c0",
+ "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475" // "3896e1d6" truncated.
+ },
+ {nullptr}};
} // namespace
@@ -58,11 +56,6 @@ QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter,
}
TEST(ChaCha20Poly1305EncrypterTest, Encrypt) {
- if (!ChaCha20Poly1305Encrypter::IsSupported()) {
- LOG(INFO) << "ChaCha20+Poly1305 not supported. Test skipped.";
- return;
- }
-
for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
// Decode the test vector.
string key;
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h
new file mode 100644
index 00000000000..3889216226a
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h
@@ -0,0 +1,56 @@
+// Copyright 2014 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_CRYPTO_CHACHA20_POLY1305_RFC7539_DECRYPTER_H_
+#define NET_QUIC_CRYPTO_CHACHA20_POLY1305_RFC7539_DECRYPTER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "net/quic/crypto/aead_base_decrypter.h"
+
+namespace net {
+
+// A ChaCha20Poly1305Rfc7539Decrypter is a QuicDecrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in
+// draft-agl-tls-chacha20poly1305-04, except that it truncates the Poly1305
+// authenticator to 12 bytes. Create an instance by calling
+// QuicDecrypter::Create(kCC12).
+//
+// It uses an authentication tag of 16 bytes (128 bits). There is no
+// fixed nonce prefix.
+class NET_EXPORT_PRIVATE ChaCha20Poly1305Rfc7539Decrypter
+ : public AeadBaseDecrypter {
+ public:
+ enum {
+ kAuthTagSize = 12,
+ };
+
+ ChaCha20Poly1305Rfc7539Decrypter();
+ ~ChaCha20Poly1305Rfc7539Decrypter() override;
+
+ // Returns true if the underlying crypto library supports the RFC 7539
+ // variant of ChaCha20+Poly1305.
+ static bool IsSupported();
+
+ const char* cipher_name() const override;
+ uint32_t cipher_id() const override;
+
+#if !defined(USE_OPENSSL)
+ protected:
+ // AeadBaseDecrypter methods:
+ void FillAeadParams(base::StringPiece nonce,
+ const base::StringPiece& associated_data,
+ size_t auth_tag_size,
+ AeadParams* aead_params) const override;
+#endif
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ChaCha20Poly1305Rfc7539Decrypter);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CRYPTO_CHACHA20_POLY1305_RFC7539_DECRYPTER_H_
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc
new file mode 100644
index 00000000000..8c830e93c60
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_nss.cc
@@ -0,0 +1,50 @@
+// Copyright 2014 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/crypto/chacha20_poly1305_rfc7539_decrypter.h"
+
+#include <pk11pub.h>
+
+using base::StringPiece;
+
+namespace net {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNoncePrefixSize = 4;
+
+} // namespace
+
+ChaCha20Poly1305Rfc7539Decrypter::ChaCha20Poly1305Rfc7539Decrypter()
+ : AeadBaseDecrypter(CKM_NSS_CHACHA20_POLY1305,
+ kKeySize,
+ kAuthTagSize,
+ kNoncePrefixSize) {
+ static_assert(kKeySize <= kMaxKeySize, "key size too big");
+ static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
+ "nonce prefix size too big");
+}
+
+ChaCha20Poly1305Rfc7539Decrypter::~ChaCha20Poly1305Rfc7539Decrypter() {}
+
+bool ChaCha20Poly1305Rfc7539Decrypter::IsSupported() {
+ return false;
+}
+
+const char* ChaCha20Poly1305Rfc7539Decrypter::cipher_name() const {
+ return "";
+}
+
+uint32_t ChaCha20Poly1305Rfc7539Decrypter::cipher_id() const {
+ return 0;
+}
+
+void ChaCha20Poly1305Rfc7539Decrypter::FillAeadParams(
+ base::StringPiece nonce,
+ const base::StringPiece& associated_data,
+ size_t auth_tag_size,
+ AeadParams* aead_params) const {}
+
+} // namespace net
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc
new file mode 100644
index 00000000000..2c85aa2a9a6
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc
@@ -0,0 +1,43 @@
+// Copyright 2014 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/crypto/chacha20_poly1305_rfc7539_decrypter.h"
+
+#include <openssl/evp.h>
+#include <openssl/tls1.h>
+
+namespace net {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNoncePrefixSize = 4;
+
+} // namespace
+
+ChaCha20Poly1305Rfc7539Decrypter::ChaCha20Poly1305Rfc7539Decrypter()
+ : AeadBaseDecrypter(EVP_aead_chacha20_poly1305_rfc7539(),
+ kKeySize,
+ kAuthTagSize,
+ kNoncePrefixSize) {
+ static_assert(kKeySize <= kMaxKeySize, "key size too big");
+ static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
+ "nonce prefix size too big");
+}
+
+ChaCha20Poly1305Rfc7539Decrypter::~ChaCha20Poly1305Rfc7539Decrypter() {}
+
+bool ChaCha20Poly1305Rfc7539Decrypter::IsSupported() {
+ return true;
+}
+
+const char* ChaCha20Poly1305Rfc7539Decrypter::cipher_name() const {
+ return TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD;
+}
+
+uint32_t ChaCha20Poly1305Rfc7539Decrypter::cipher_id() const {
+ return TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc
new file mode 100644
index 00000000000..0cee4b407b8
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc
@@ -0,0 +1,178 @@
+// Copyright 2014 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/crypto/chacha20_poly1305_rfc7539_decrypter.h"
+
+#include "net/quic/test_tools/quic_test_utils.h"
+
+using base::StringPiece;
+using std::string;
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+ // Input:
+ const char* key;
+ const char* iv;
+ const char* fixed;
+ const char* aad;
+ const char* ct;
+
+ // Expected output:
+ const char* pt; // An empty string "" means decryption succeeded and
+ // the plaintext is zero-length. NULL means decryption
+ // failed.
+};
+
+const TestVector test_vectors[] = {
+ {"808182838485868788898a8b8c8d8e8f"
+ "909192939495969798999a9b9c9d9e9f",
+
+ "4041424344454647",
+
+ "07000000",
+
+ "50515253c0c1c2c3c4c5c6c7",
+
+ "d31a8d34648e60db7b86afbc53ef7ec2"
+ "a4aded51296e08fea9e2b5a736ee62d6"
+ "3dbea45e8ca9671282fafb69da92728b"
+ "1a71de0a9e060b2905d6a5b67ecd3b36"
+ "92ddbd7f2d778b8c9803aee328091b58"
+ "fab324e4fad675945585808b4831d7bc"
+ "3ff4def08e4b7a9de576d26586cec64b"
+ "6116"
+ "1ae10b594f09e26a7e902ecb", // "d0600691" truncated
+
+ "4c616469657320616e642047656e746c"
+ "656d656e206f662074686520636c6173"
+ "73206f66202739393a20496620492063"
+ "6f756c64206f6666657220796f75206f"
+ "6e6c79206f6e652074697020666f7220"
+ "746865206675747572652c2073756e73"
+ "637265656e20776f756c642062652069"
+ "742e"},
+ // Modify the ciphertext (Poly1305 authenticator).
+ {"808182838485868788898a8b8c8d8e8f"
+ "909192939495969798999a9b9c9d9e9f",
+
+ "4041424344454647",
+
+ "07000000",
+
+ "50515253c0c1c2c3c4c5c6c7",
+
+ "d31a8d34648e60db7b86afbc53ef7ec2"
+ "a4aded51296e08fea9e2b5a736ee62d6"
+ "3dbea45e8ca9671282fafb69da92728b"
+ "1a71de0a9e060b2905d6a5b67ecd3b36"
+ "92ddbd7f2d778b8c9803aee328091b58"
+ "fab324e4fad675945585808b4831d7bc"
+ "3ff4def08e4b7a9de576d26586cec64b"
+ "6116"
+ "1ae10b594f09e26a7e902ecc", // "d0600691" truncated
+
+ nullptr},
+ // Modify the associated data.
+ {"808182838485868788898a8b8c8d8e8f"
+ "909192939495969798999a9b9c9d9e9f",
+
+ "4041424344454647",
+
+ "07000000",
+
+ "60515253c0c1c2c3c4c5c6c7",
+
+ "d31a8d34648e60db7b86afbc53ef7ec2"
+ "a4aded51296e08fea9e2b5a736ee62d6"
+ "3dbea45e8ca9671282fafb69da92728b"
+ "1a71de0a9e060b2905d6a5b67ecd3b36"
+ "92ddbd7f2d778b8c9803aee328091b58"
+ "fab324e4fad675945585808b4831d7bc"
+ "3ff4def08e4b7a9de576d26586cec64b"
+ "6116"
+ "1ae10b594f09e26a7e902ecb", // "d0600691" truncated
+
+ nullptr},
+ {nullptr}};
+
+} // namespace
+
+namespace net {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(ChaCha20Poly1305Rfc7539Decrypter* decrypter,
+ StringPiece nonce,
+ StringPiece associated_data,
+ StringPiece ciphertext) {
+ QuicPacketNumber packet_number;
+ StringPiece nonce_prefix(nonce.data(), nonce.size() - sizeof(packet_number));
+ decrypter->SetNoncePrefix(nonce_prefix);
+ memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
+ sizeof(packet_number));
+ scoped_ptr<char[]> output(new char[ciphertext.length()]);
+ size_t output_length = 0;
+ const bool success = decrypter->DecryptPacket(
+ packet_number, associated_data, ciphertext, output.get(), &output_length,
+ ciphertext.length());
+ if (!success) {
+ return nullptr;
+ }
+ return new QuicData(output.release(), output_length, true);
+}
+
+TEST(ChaCha20Poly1305Rfc7539DecrypterTest, Decrypt) {
+ if (!ChaCha20Poly1305Rfc7539Decrypter::IsSupported()) {
+ VLOG(1) << "ChaCha20+Poly1305 not supported. Test skipped.";
+ return;
+ }
+ for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+ // If not present then decryption is expected to fail.
+ bool has_pt = test_vectors[i].pt;
+
+ // Decode the test vector.
+ string key;
+ string iv;
+ string fixed;
+ string aad;
+ string ct;
+ string pt;
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].key, &key));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].iv, &iv));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].fixed, &fixed));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].aad, &aad));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].ct, &ct));
+ if (has_pt) {
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].pt, &pt));
+ }
+
+ ChaCha20Poly1305Rfc7539Decrypter decrypter;
+ ASSERT_TRUE(decrypter.SetKey(key));
+ scoped_ptr<QuicData> decrypted(DecryptWithNonce(
+ &decrypter, fixed + iv,
+ // This deliberately tests that the decrypter can handle an AAD that
+ // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+ StringPiece(aad.length() ? aad.data() : nullptr, aad.length()), ct));
+ if (!decrypted.get()) {
+ EXPECT_FALSE(has_pt);
+ continue;
+ }
+ EXPECT_TRUE(has_pt);
+
+ EXPECT_EQ(12u, ct.size() - decrypted->length());
+ ASSERT_EQ(pt.length(), decrypted->length());
+ test::CompareCharArraysWithHexError("plaintext", decrypted->data(),
+ pt.length(), pt.data(), pt.length());
+ }
+}
+
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h
new file mode 100644
index 00000000000..7b6e0b4e205
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h
@@ -0,0 +1,51 @@
+// Copyright 2014 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_CRYPTO_CHACHA20_POLY1305_RFC7539_ENCRYPTER_H_
+#define NET_QUIC_CRYPTO_CHACHA20_POLY1305_RFC7539_ENCRYPTER_H_
+
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "net/quic/crypto/aead_base_encrypter.h"
+
+namespace net {
+
+// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
+// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
+// by calling QuicEncrypter::Create(kCC12).
+//
+// It uses an authentication tag of 16 bytes (128 bits). There is no
+// fixed nonce prefix.
+class NET_EXPORT_PRIVATE ChaCha20Poly1305Rfc7539Encrypter
+ : public AeadBaseEncrypter {
+ public:
+ enum {
+ kAuthTagSize = 12,
+ };
+
+ ChaCha20Poly1305Rfc7539Encrypter();
+ ~ChaCha20Poly1305Rfc7539Encrypter() override;
+
+ // Returns true if the underlying crypto library supports the RFC 7539
+ // variant of ChaCha20+Poly1305.
+ static bool IsSupported();
+
+#if !defined(USE_OPENSSL)
+ protected:
+ // AeadBaseEncrypter methods:
+ void FillAeadParams(base::StringPiece nonce,
+ base::StringPiece associated_data,
+ size_t auth_tag_size,
+ AeadParams* aead_params) const override;
+#endif
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ChaCha20Poly1305Rfc7539Encrypter);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CRYPTO_CHACHA20_POLY1305_RFC7539_ENCRYPTER_H_
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_nss.cc b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_nss.cc
new file mode 100644
index 00000000000..34b404ef4e4
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_nss.cc
@@ -0,0 +1,42 @@
+// Copyright 2014 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/crypto/chacha20_poly1305_rfc7539_encrypter.h"
+
+#include <pk11pub.h>
+
+using base::StringPiece;
+
+namespace net {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNoncePrefixSize = 4;
+
+} // namespace
+
+ChaCha20Poly1305Rfc7539Encrypter::ChaCha20Poly1305Rfc7539Encrypter()
+ : AeadBaseEncrypter(CKM_NSS_CHACHA20_POLY1305,
+ kKeySize,
+ kAuthTagSize,
+ kNoncePrefixSize) {
+ static_assert(kKeySize <= kMaxKeySize, "key size too big");
+ static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
+ "nonce prefix size too big");
+}
+
+ChaCha20Poly1305Rfc7539Encrypter::~ChaCha20Poly1305Rfc7539Encrypter() {}
+
+bool ChaCha20Poly1305Rfc7539Encrypter::IsSupported() {
+ return false;
+}
+
+void ChaCha20Poly1305Rfc7539Encrypter::FillAeadParams(
+ StringPiece nonce,
+ StringPiece associated_data,
+ size_t auth_tag_size,
+ AeadParams* aead_params) const {}
+
+} // namespace net
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc
new file mode 100644
index 00000000000..6912f9256e0
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc
@@ -0,0 +1,34 @@
+// Copyright 2014 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/crypto/chacha20_poly1305_rfc7539_encrypter.h"
+
+#include <openssl/evp.h>
+
+namespace net {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNoncePrefixSize = 4;
+
+} // namespace
+
+ChaCha20Poly1305Rfc7539Encrypter::ChaCha20Poly1305Rfc7539Encrypter()
+ : AeadBaseEncrypter(EVP_aead_chacha20_poly1305_rfc7539(),
+ kKeySize,
+ kAuthTagSize,
+ kNoncePrefixSize) {
+ static_assert(kKeySize <= kMaxKeySize, "key size too big");
+ static_assert(kNoncePrefixSize <= kMaxNoncePrefixSize,
+ "nonce prefix size too big");
+}
+
+ChaCha20Poly1305Rfc7539Encrypter::~ChaCha20Poly1305Rfc7539Encrypter() {}
+
+bool ChaCha20Poly1305Rfc7539Encrypter::IsSupported() {
+ return true;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc
new file mode 100644
index 00000000000..1654ea35a96
--- /dev/null
+++ b/chromium/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc
@@ -0,0 +1,178 @@
+// Copyright 2014 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/crypto/chacha20_poly1305_rfc7539_encrypter.h"
+
+#include <stdint.h>
+
+#include "net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h"
+#include "net/quic/test_tools/quic_test_utils.h"
+
+using base::StringPiece;
+using std::string;
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of five strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+ const char* key;
+ const char* pt;
+ const char* iv;
+ const char* fixed;
+ const char* aad;
+ const char* ct;
+};
+
+const TestVector test_vectors[] = {
+ {
+ "808182838485868788898a8b8c8d8e8f"
+ "909192939495969798999a9b9c9d9e9f",
+
+ "4c616469657320616e642047656e746c"
+ "656d656e206f662074686520636c6173"
+ "73206f66202739393a20496620492063"
+ "6f756c64206f6666657220796f75206f"
+ "6e6c79206f6e652074697020666f7220"
+ "746865206675747572652c2073756e73"
+ "637265656e20776f756c642062652069"
+ "742e",
+
+ "4041424344454647",
+
+ "07000000",
+
+ "50515253c0c1c2c3c4c5c6c7",
+
+ "d31a8d34648e60db7b86afbc53ef7ec2"
+ "a4aded51296e08fea9e2b5a736ee62d6"
+ "3dbea45e8ca9671282fafb69da92728b"
+ "1a71de0a9e060b2905d6a5b67ecd3b36"
+ "92ddbd7f2d778b8c9803aee328091b58"
+ "fab324e4fad675945585808b4831d7bc"
+ "3ff4def08e4b7a9de576d26586cec64b"
+ "6116"
+ "1ae10b594f09e26a7e902ecb", // "d0600691" truncated
+ },
+ {nullptr}};
+
+} // namespace
+
+namespace net {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(ChaCha20Poly1305Rfc7539Encrypter* encrypter,
+ StringPiece nonce,
+ StringPiece associated_data,
+ StringPiece plaintext) {
+ size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+ scoped_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+ if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+ reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+ return nullptr;
+ }
+
+ return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+TEST(ChaCha20Poly1305Rfc7539EncrypterTest, EncryptThenDecrypt) {
+ if (!ChaCha20Poly1305Rfc7539Encrypter::IsSupported()) {
+ VLOG(1) << "ChaCha20+Poly1305 not supported. Test skipped.";
+ return;
+ }
+
+ ChaCha20Poly1305Rfc7539Encrypter encrypter;
+ ChaCha20Poly1305Rfc7539Decrypter decrypter;
+
+ string key;
+ DecodeHexString(test_vectors[0].key, &key);
+ ASSERT_TRUE(encrypter.SetKey(key));
+ ASSERT_TRUE(decrypter.SetKey(key));
+ ASSERT_TRUE(encrypter.SetNoncePrefix("abcd"));
+ ASSERT_TRUE(decrypter.SetNoncePrefix("abcd"));
+
+ QuicPacketNumber packet_number = UINT64_C(0x123456789ABC);
+ string associated_data = "associated_data";
+ string plaintext = "plaintext";
+ char encrypted[1024];
+ size_t len;
+ ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
+ encrypted, &len, arraysize(encrypted)));
+ StringPiece ciphertext(encrypted, len);
+ char decrypted[1024];
+ ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
+ ciphertext, decrypted, &len,
+ arraysize(decrypted)));
+}
+
+TEST(ChaCha20Poly1305Rfc7539EncrypterTest, Encrypt) {
+ if (!ChaCha20Poly1305Rfc7539Encrypter::IsSupported()) {
+ VLOG(1) << "ChaCha20+Poly1305 not supported. Test skipped.";
+ return;
+ }
+
+ for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+ // Decode the test vector.
+ string key;
+ string pt;
+ string iv;
+ string fixed;
+ string aad;
+ string ct;
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].key, &key));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].pt, &pt));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].iv, &iv));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].fixed, &fixed));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].aad, &aad));
+ ASSERT_TRUE(DecodeHexString(test_vectors[i].ct, &ct));
+
+ ChaCha20Poly1305Rfc7539Encrypter encrypter;
+ ASSERT_TRUE(encrypter.SetKey(key));
+ scoped_ptr<QuicData> encrypted(EncryptWithNonce(
+ &encrypter, fixed + iv,
+ // This deliberately tests that the encrypter can handle an AAD that
+ // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+ StringPiece(aad.length() ? aad.data() : nullptr, aad.length()), pt));
+ ASSERT_TRUE(encrypted.get());
+ EXPECT_EQ(12u, ct.size() - pt.size());
+ EXPECT_EQ(12u, encrypted->length() - pt.size());
+
+ test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
+ encrypted->length(), ct.data(),
+ ct.length());
+ }
+}
+
+TEST(ChaCha20Poly1305Rfc7539EncrypterTest, GetMaxPlaintextSize) {
+ if (!ChaCha20Poly1305Rfc7539Encrypter::IsSupported()) {
+ VLOG(1) << "ChaCha20+Poly1305 not supported. Test skipped.";
+ return;
+ }
+
+ ChaCha20Poly1305Rfc7539Encrypter encrypter;
+ EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+ EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+ EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+}
+
+TEST(ChaCha20Poly1305Rfc7539EncrypterTest, GetCiphertextSize) {
+ if (!ChaCha20Poly1305Rfc7539Encrypter::IsSupported()) {
+ VLOG(1) << "ChaCha20+Poly1305 not supported. Test skipped.";
+ return;
+ }
+
+ ChaCha20Poly1305Rfc7539Encrypter encrypter;
+ EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+ EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+ EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+}
+
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/crypto/channel_id.h b/chromium/net/quic/crypto/channel_id.h
index bd335fb0c90..0ec1d4dd817 100644
--- a/chromium/net/quic/crypto/channel_id.h
+++ b/chromium/net/quic/crypto/channel_id.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/quic/crypto/channel_id_chromium.cc b/chromium/net/quic/crypto/channel_id_chromium.cc
index a4d6d919c55..3f50b768302 100644
--- a/chromium/net/quic/crypto/channel_id_chromium.cc
+++ b/chromium/net/quic/crypto/channel_id_chromium.cc
@@ -5,7 +5,9 @@
#include "net/quic/crypto/channel_id_chromium.h"
#include <string>
+#include <utility>
+#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "crypto/ec_private_key.h"
@@ -18,8 +20,7 @@ namespace net {
ChannelIDKeyChromium::ChannelIDKeyChromium(
scoped_ptr<crypto::ECPrivateKey> ec_private_key)
- : ec_private_key_(ec_private_key.Pass()) {
-}
+ : ec_private_key_(std::move(ec_private_key)) {}
ChannelIDKeyChromium::~ChannelIDKeyChromium() {}
@@ -32,15 +33,15 @@ bool ChannelIDKeyChromium::Sign(base::StringPiece signed_data,
}
const size_t len1 = strlen(ChannelIDVerifier::kContextStr) + 1;
const size_t len2 = strlen(ChannelIDVerifier::kClientToServerStr) + 1;
- std::vector<uint8> data(len1 + len2 + signed_data.size());
+ std::vector<uint8_t> data(len1 + len2 + signed_data.size());
memcpy(&data[0], ChannelIDVerifier::kContextStr, len1);
memcpy(&data[len1], ChannelIDVerifier::kClientToServerStr, len2);
memcpy(&data[len1 + len2], signed_data.data(), signed_data.size());
- std::vector<uint8> der_signature;
+ std::vector<uint8_t> der_signature;
if (!sig_creator->Sign(&data[0], data.size(), &der_signature)) {
return false;
}
- std::vector<uint8> raw_signature;
+ std::vector<uint8_t> raw_signature;
if (!sig_creator->DecodeSignature(der_signature, &raw_signature)) {
return false;
}
@@ -103,13 +104,11 @@ class ChannelIDSourceChromium::Job {
DISALLOW_COPY_AND_ASSIGN(Job);
};
-ChannelIDSourceChromium::Job::Job(
- ChannelIDSourceChromium* channel_id_source,
- ChannelIDService* channel_id_service)
+ChannelIDSourceChromium::Job::Job(ChannelIDSourceChromium* channel_id_source,
+ ChannelIDService* channel_id_service)
: channel_id_source_(channel_id_source),
channel_id_service_(channel_id_service),
- next_state_(STATE_NONE) {
-}
+ next_state_(STATE_NONE) {}
QuicAsyncStatus ChannelIDSourceChromium::Job::GetChannelIDKey(
const std::string& hostname,
@@ -197,15 +196,14 @@ int ChannelIDSourceChromium::Job::DoGetChannelIDKeyComplete(int result) {
return ERR_UNEXPECTED;
}
channel_id_key_.reset(
- new ChannelIDKeyChromium(channel_id_crypto_key_.Pass()));
+ new ChannelIDKeyChromium(std::move(channel_id_crypto_key_)));
return result;
}
ChannelIDSourceChromium::ChannelIDSourceChromium(
ChannelIDService* channel_id_service)
- : channel_id_service_(channel_id_service) {
-}
+ : channel_id_service_(channel_id_service) {}
ChannelIDSourceChromium::~ChannelIDSourceChromium() {
STLDeleteElements(&active_jobs_);
@@ -216,8 +214,8 @@ QuicAsyncStatus ChannelIDSourceChromium::GetChannelIDKey(
scoped_ptr<ChannelIDKey>* channel_id_key,
ChannelIDSourceCallback* callback) {
scoped_ptr<Job> job(new Job(this, channel_id_service_));
- QuicAsyncStatus status = job->GetChannelIDKey(hostname, channel_id_key,
- callback);
+ QuicAsyncStatus status =
+ job->GetChannelIDKey(hostname, channel_id_key, callback);
if (status == QUIC_PENDING) {
active_jobs_.insert(job.release());
}
diff --git a/chromium/net/quic/crypto/channel_id_chromium.h b/chromium/net/quic/crypto/channel_id_chromium.h
index 43a1ed390b6..7dfb9b52d0d 100644
--- a/chromium/net/quic/crypto/channel_id_chromium.h
+++ b/chromium/net/quic/crypto/channel_id_chromium.h
@@ -7,6 +7,7 @@
#include <set>
+#include "base/macros.h"
#include "net/quic/crypto/channel_id.h"
namespace crypto {
@@ -17,7 +18,7 @@ namespace net {
class ChannelIDService;
-class NET_EXPORT_PRIVATE ChannelIDKeyChromium: public ChannelIDKey {
+class NET_EXPORT_PRIVATE ChannelIDKeyChromium : public ChannelIDKey {
public:
explicit ChannelIDKeyChromium(
scoped_ptr<crypto::ECPrivateKey> ec_private_key);
@@ -35,8 +36,7 @@ class NET_EXPORT_PRIVATE ChannelIDKeyChromium: public ChannelIDKey {
// ChannelIDSourceChromium implements the QUIC ChannelIDSource interface.
class ChannelIDSourceChromium : public ChannelIDSource {
public:
- explicit ChannelIDSourceChromium(
- ChannelIDService* channel_id_service);
+ explicit ChannelIDSourceChromium(ChannelIDService* channel_id_service);
~ChannelIDSourceChromium() override;
// ChannelIDSource interface
diff --git a/chromium/net/quic/crypto/channel_id_nss.cc b/chromium/net/quic/crypto/channel_id_nss.cc
index 748e4ef14b0..522b2f61509 100644
--- a/chromium/net/quic/crypto/channel_id_nss.cc
+++ b/chromium/net/quic/crypto/channel_id_nss.cc
@@ -24,8 +24,7 @@ bool ChannelIDVerifier::VerifyRaw(StringPiece key,
StringPiece signed_data,
StringPiece signature,
bool is_channel_id_signature) {
- if (key.size() != 32 * 2 ||
- signature.size() != 32 * 2) {
+ if (key.size() != 32 * 2 || signature.size() != 32 * 2) {
return false;
}
@@ -34,9 +33,8 @@ bool ChannelIDVerifier::VerifyRaw(StringPiece key,
// DER encoding of the object identifier (OID) of the named curve P-256
// (1.2.840.10045.3.1.7). See RFC 6637 Section 11.
- static const unsigned char p256_oid[] = {
- 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
- };
+ static const unsigned char p256_oid[] = {0x06, 0x08, 0x2a, 0x86, 0x48,
+ 0xce, 0x3d, 0x03, 0x01, 0x07};
public_key.keyType = ecKey;
public_key.u.ec.DEREncodedParams.type = siBuffer;
public_key.u.ec.DEREncodedParams.data = const_cast<unsigned char*>(p256_oid);
@@ -49,14 +47,12 @@ bool ChannelIDVerifier::VerifyRaw(StringPiece key,
public_key.u.ec.publicValue.data = key_buf;
public_key.u.ec.publicValue.len = sizeof(key_buf);
- SECItem signature_item = {
- siBuffer,
- reinterpret_cast<unsigned char*>(const_cast<char*>(signature.data())),
- static_cast<unsigned int>(signature.size())
- };
+ SECItem signature_item = {siBuffer, reinterpret_cast<unsigned char*>(
+ const_cast<char*>(signature.data())),
+ static_cast<unsigned int>(signature.size())};
unsigned char hash_buf[SHA256_LENGTH];
- SECItem hash_item = { siBuffer, hash_buf, sizeof(hash_buf) };
+ SECItem hash_item = {siBuffer, hash_buf, sizeof(hash_buf)};
HASHContext* sha256 = HASH_Create(HASH_AlgSHA256);
if (!sha256) {
diff --git a/chromium/net/quic/crypto/channel_id_openssl.cc b/chromium/net/quic/crypto/channel_id_openssl.cc
index 97dc32e2d89..4e576ae7906 100644
--- a/chromium/net/quic/crypto/channel_id_openssl.cc
+++ b/chromium/net/quic/crypto/channel_id_openssl.cc
@@ -29,8 +29,7 @@ bool ChannelIDVerifier::VerifyRaw(StringPiece key,
StringPiece signed_data,
StringPiece signature,
bool is_channel_id_signature) {
- if (key.size() != 32 * 2 ||
- signature.size() != 32 * 2) {
+ if (key.size() != 32 * 2 || signature.size() != 32 * 2) {
return false;
}
@@ -45,13 +44,13 @@ bool ChannelIDVerifier::VerifyRaw(StringPiece key,
sig.r = r.get();
sig.s = s.get();
- const uint8* key_bytes = reinterpret_cast<const uint8*>(key.data());
- const uint8* signature_bytes =
- reinterpret_cast<const uint8*>(signature.data());
+ const uint8_t* key_bytes = reinterpret_cast<const uint8_t*>(key.data());
+ const uint8_t* signature_bytes =
+ reinterpret_cast<const uint8_t*>(signature.data());
- if (BN_bin2bn(key_bytes + 0, 32, x.get()) == nullptr ||
- BN_bin2bn(key_bytes + 32, 32, y.get()) == nullptr ||
- BN_bin2bn(signature_bytes + 0, 32, sig.r) == nullptr ||
+ if (BN_bin2bn(key_bytes + 0, 32, x.get()) == nullptr ||
+ BN_bin2bn(key_bytes + 32, 32, y.get()) == nullptr ||
+ BN_bin2bn(signature_bytes + 0, 32, sig.r) == nullptr ||
BN_bin2bn(signature_bytes + 32, 32, sig.s) == nullptr) {
return false;
}
diff --git a/chromium/net/quic/crypto/channel_id_test.cc b/chromium/net/quic/crypto/channel_id_test.cc
index 73927239f27..8aa2f74fb09 100644
--- a/chromium/net/quic/crypto/channel_id_test.cc
+++ b/chromium/net/quic/crypto/channel_id_test.cc
@@ -33,158 +33,172 @@ struct TestVector {
};
const TestVector test_vector[] = {
- { "e4796db5f785f207aa30d311693b3702821dff1168fd2e04c0836825aefd850d"
- "9aa60326d88cde1a23c7745351392ca2288d632c264f197d05cd424a30336c19"
- "fd09bb229654f0222fcb881a4b35c290a093ac159ce13409111ff0358411133c"
- "24f5b8e2090d6db6558afc36f06ca1f6ef779785adba68db27a409859fc4c4a0",
- "87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555",
- "e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9",
- "d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0",
- "a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6",
- false // F (3 - S changed)
- },
- { "069a6e6b93dfee6df6ef6997cd80dd2182c36653cef10c655d524585655462d6"
- "83877f95ecc6d6c81623d8fac4e900ed0019964094e7de91f1481989ae187300"
- "4565789cbf5dc56c62aedc63f62f3b894c9c6f7788c8ecaadc9bd0e81ad91b2b"
- "3569ea12260e93924fdddd3972af5273198f5efda0746219475017557616170e",
- "5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2",
- "ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85",
- "dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693",
- "d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c",
- false // F (2 - R changed)
- },
- { "df04a346cf4d0e331a6db78cca2d456d31b0a000aa51441defdb97bbeb20b94d"
- "8d746429a393ba88840d661615e07def615a342abedfa4ce912e562af7149598"
- "96858af817317a840dcff85a057bb91a3c2bf90105500362754a6dd321cdd861"
- "28cfc5f04667b57aa78c112411e42da304f1012d48cd6a7052d7de44ebcc01de",
- "2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb",
- "5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64",
- "9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8",
- "9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc",
- false // F (4 - Q changed)
- },
- { "e1130af6a38ccb412a9c8d13e15dbfc9e69a16385af3c3f1e5da954fd5e7c45f"
- "d75e2b8c36699228e92840c0562fbf3772f07e17f1add56588dd45f7450e1217"
- "ad239922dd9c32695dc71ff2424ca0dec1321aa47064a044b7fe3c2b97d03ce4"
- "70a592304c5ef21eed9f93da56bb232d1eeb0035f9bf0dfafdcc4606272b20a3",
- "e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c",
- "970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927",
- "bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f",
- "17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c",
- true // P (0 )
- },
- { "73c5f6a67456ae48209b5f85d1e7de7758bf235300c6ae2bdceb1dcb27a7730f"
- "b68c950b7fcada0ecc4661d3578230f225a875e69aaa17f1e71c6be5c831f226"
- "63bac63d0c7a9635edb0043ff8c6f26470f02a7bc56556f1437f06dfa27b487a"
- "6c4290d8bad38d4879b334e341ba092dde4e4ae694a9c09302e2dbf443581c08",
- "e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864",
- "7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a",
- "1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407",
- "cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a",
- true // P (0 )
- },
- { "666036d9b4a2426ed6585a4e0fd931a8761451d29ab04bd7dc6d0c5b9e38e6c2"
- "b263ff6cb837bd04399de3d757c6c7005f6d7a987063cf6d7e8cb38a4bf0d74a"
- "282572bd01d0f41e3fd066e3021575f0fa04f27b700d5b7ddddf50965993c3f9"
- "c7118ed78888da7cb221849b3260592b8e632d7c51e935a0ceae15207bedd548",
- "a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86",
- "bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471",
- "25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6",
- "9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537",
- false // F (2 - R changed)
- },
- { "7e80436bce57339ce8da1b5660149a20240b146d108deef3ec5da4ae256f8f89"
- "4edcbbc57b34ce37089c0daa17f0c46cd82b5a1599314fd79d2fd2f446bd5a25"
- "b8e32fcf05b76d644573a6df4ad1dfea707b479d97237a346f1ec632ea5660ef"
- "b57e8717a8628d7f82af50a4e84b11f21bdff6839196a880ae20b2a0918d58cd",
- "3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df",
- "f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb",
- "548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a",
- "e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75",
- false // F (4 - Q changed)
- },
- { "1669bfb657fdc62c3ddd63269787fc1c969f1850fb04c933dda063ef74a56ce1"
- "3e3a649700820f0061efabf849a85d474326c8a541d99830eea8131eaea584f2"
- "2d88c353965dabcdc4bf6b55949fd529507dfb803ab6b480cd73ca0ba00ca19c"
- "438849e2cea262a1c57d8f81cd257fb58e19dec7904da97d8386e87b84948169",
- "69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214",
- "d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f",
- "288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790",
- "247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979",
- false // F (1 - Message changed)
- },
- { "3fe60dd9ad6caccf5a6f583b3ae65953563446c4510b70da115ffaa0ba04c076"
- "115c7043ab8733403cd69c7d14c212c655c07b43a7c71b9a4cffe22c2684788e"
- "c6870dc2013f269172c822256f9e7cc674791bf2d8486c0f5684283e1649576e"
- "fc982ede17c7b74b214754d70402fb4bb45ad086cf2cf76b3d63f7fce39ac970",
- "bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682",
- "069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03",
- "f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad",
- "049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d",
- false // F (3 - S changed)
- },
- { "983a71b9994d95e876d84d28946a041f8f0a3f544cfcc055496580f1dfd4e312"
- "a2ad418fe69dbc61db230cc0c0ed97e360abab7d6ff4b81ee970a7e97466acfd"
- "9644f828ffec538abc383d0e92326d1c88c55e1f46a668a039beaa1be631a891"
- "29938c00a81a3ae46d4aecbf9707f764dbaccea3ef7665e4c4307fa0b0a3075c",
- "224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de",
- "178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9",
- "87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2",
- "4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66",
- false // F (2 - R changed)
- },
- { "4a8c071ac4fd0d52faa407b0fe5dab759f7394a5832127f2a3498f34aac28733"
- "9e043b4ffa79528faf199dc917f7b066ad65505dab0e11e6948515052ce20cfd"
- "b892ffb8aa9bf3f1aa5be30a5bbe85823bddf70b39fd7ebd4a93a2f75472c1d4"
- "f606247a9821f1a8c45a6cb80545de2e0c6c0174e2392088c754e9c8443eb5af",
- "43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369",
- "f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac",
- "8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce",
- "cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154",
- false // F (3 - S changed)
- },
- { "0a3a12c3084c865daf1d302c78215d39bfe0b8bf28272b3c0b74beb4b7409db0"
- "718239de700785581514321c6440a4bbaea4c76fa47401e151e68cb6c29017f0"
- "bce4631290af5ea5e2bf3ed742ae110b04ade83a5dbd7358f29a85938e23d87a"
- "c8233072b79c94670ff0959f9c7f4517862ff829452096c78f5f2e9a7e4e9216",
- "9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596",
- "972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405",
- "dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb",
- "8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2",
- false // F (1 - Message changed)
- },
- { "785d07a3c54f63dca11f5d1a5f496ee2c2f9288e55007e666c78b007d95cc285"
- "81dce51f490b30fa73dc9e2d45d075d7e3a95fb8a9e1465ad191904124160b7c"
- "60fa720ef4ef1c5d2998f40570ae2a870ef3e894c2bc617d8a1dc85c3c557749"
- "28c38789b4e661349d3f84d2441a3b856a76949b9f1f80bc161648a1cad5588e",
- "072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda",
- "9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5",
- "09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19",
- "a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d",
- false // F (4 - Q changed)
- },
- { "76f987ec5448dd72219bd30bf6b66b0775c80b394851a43ff1f537f140a6e722"
- "9ef8cd72ad58b1d2d20298539d6347dd5598812bc65323aceaf05228f738b5ad"
- "3e8d9fe4100fd767c2f098c77cb99c2992843ba3eed91d32444f3b6db6cd212d"
- "d4e5609548f4bb62812a920f6e2bf1581be1ebeebdd06ec4e971862cc42055ca",
- "09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24",
- "f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5",
- "5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73",
- "9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7",
- false // F (1 - Message changed)
- },
- { "60cd64b2cd2be6c33859b94875120361a24085f3765cb8b2bf11e026fa9d8855"
- "dbe435acf7882e84f3c7857f96e2baab4d9afe4588e4a82e17a78827bfdb5ddb"
- "d1c211fbc2e6d884cddd7cb9d90d5bf4a7311b83f352508033812c776a0e00c0"
- "03c7e0d628e50736c7512df0acfa9f2320bd102229f46495ae6d0857cc452a84",
- "2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d",
- "9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a",
- "06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959",
- "62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce",
- true // P (0 )
- },
- { NULL }
-};
+ {
+ "e4796db5f785f207aa30d311693b3702821dff1168fd2e04c0836825aefd850d"
+ "9aa60326d88cde1a23c7745351392ca2288d632c264f197d05cd424a30336c19"
+ "fd09bb229654f0222fcb881a4b35c290a093ac159ce13409111ff0358411133c"
+ "24f5b8e2090d6db6558afc36f06ca1f6ef779785adba68db27a409859fc4c4a0",
+ "87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555",
+ "e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9",
+ "d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0",
+ "a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6",
+ false // F (3 - S changed)
+ },
+ {
+ "069a6e6b93dfee6df6ef6997cd80dd2182c36653cef10c655d524585655462d6"
+ "83877f95ecc6d6c81623d8fac4e900ed0019964094e7de91f1481989ae187300"
+ "4565789cbf5dc56c62aedc63f62f3b894c9c6f7788c8ecaadc9bd0e81ad91b2b"
+ "3569ea12260e93924fdddd3972af5273198f5efda0746219475017557616170e",
+ "5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2",
+ "ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85",
+ "dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693",
+ "d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c",
+ false // F (2 - R changed)
+ },
+ {
+ "df04a346cf4d0e331a6db78cca2d456d31b0a000aa51441defdb97bbeb20b94d"
+ "8d746429a393ba88840d661615e07def615a342abedfa4ce912e562af7149598"
+ "96858af817317a840dcff85a057bb91a3c2bf90105500362754a6dd321cdd861"
+ "28cfc5f04667b57aa78c112411e42da304f1012d48cd6a7052d7de44ebcc01de",
+ "2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb",
+ "5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64",
+ "9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8",
+ "9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc",
+ false // F (4 - Q changed)
+ },
+ {
+ "e1130af6a38ccb412a9c8d13e15dbfc9e69a16385af3c3f1e5da954fd5e7c45f"
+ "d75e2b8c36699228e92840c0562fbf3772f07e17f1add56588dd45f7450e1217"
+ "ad239922dd9c32695dc71ff2424ca0dec1321aa47064a044b7fe3c2b97d03ce4"
+ "70a592304c5ef21eed9f93da56bb232d1eeb0035f9bf0dfafdcc4606272b20a3",
+ "e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c",
+ "970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927",
+ "bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f",
+ "17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c",
+ true // P (0 )
+ },
+ {
+ "73c5f6a67456ae48209b5f85d1e7de7758bf235300c6ae2bdceb1dcb27a7730f"
+ "b68c950b7fcada0ecc4661d3578230f225a875e69aaa17f1e71c6be5c831f226"
+ "63bac63d0c7a9635edb0043ff8c6f26470f02a7bc56556f1437f06dfa27b487a"
+ "6c4290d8bad38d4879b334e341ba092dde4e4ae694a9c09302e2dbf443581c08",
+ "e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864",
+ "7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a",
+ "1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407",
+ "cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a",
+ true // P (0 )
+ },
+ {
+ "666036d9b4a2426ed6585a4e0fd931a8761451d29ab04bd7dc6d0c5b9e38e6c2"
+ "b263ff6cb837bd04399de3d757c6c7005f6d7a987063cf6d7e8cb38a4bf0d74a"
+ "282572bd01d0f41e3fd066e3021575f0fa04f27b700d5b7ddddf50965993c3f9"
+ "c7118ed78888da7cb221849b3260592b8e632d7c51e935a0ceae15207bedd548",
+ "a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86",
+ "bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471",
+ "25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6",
+ "9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537",
+ false // F (2 - R changed)
+ },
+ {
+ "7e80436bce57339ce8da1b5660149a20240b146d108deef3ec5da4ae256f8f89"
+ "4edcbbc57b34ce37089c0daa17f0c46cd82b5a1599314fd79d2fd2f446bd5a25"
+ "b8e32fcf05b76d644573a6df4ad1dfea707b479d97237a346f1ec632ea5660ef"
+ "b57e8717a8628d7f82af50a4e84b11f21bdff6839196a880ae20b2a0918d58cd",
+ "3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df",
+ "f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb",
+ "548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a",
+ "e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75",
+ false // F (4 - Q changed)
+ },
+ {
+ "1669bfb657fdc62c3ddd63269787fc1c969f1850fb04c933dda063ef74a56ce1"
+ "3e3a649700820f0061efabf849a85d474326c8a541d99830eea8131eaea584f2"
+ "2d88c353965dabcdc4bf6b55949fd529507dfb803ab6b480cd73ca0ba00ca19c"
+ "438849e2cea262a1c57d8f81cd257fb58e19dec7904da97d8386e87b84948169",
+ "69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214",
+ "d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f",
+ "288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790",
+ "247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979",
+ false // F (1 - Message changed)
+ },
+ {
+ "3fe60dd9ad6caccf5a6f583b3ae65953563446c4510b70da115ffaa0ba04c076"
+ "115c7043ab8733403cd69c7d14c212c655c07b43a7c71b9a4cffe22c2684788e"
+ "c6870dc2013f269172c822256f9e7cc674791bf2d8486c0f5684283e1649576e"
+ "fc982ede17c7b74b214754d70402fb4bb45ad086cf2cf76b3d63f7fce39ac970",
+ "bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682",
+ "069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03",
+ "f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad",
+ "049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d",
+ false // F (3 - S changed)
+ },
+ {
+ "983a71b9994d95e876d84d28946a041f8f0a3f544cfcc055496580f1dfd4e312"
+ "a2ad418fe69dbc61db230cc0c0ed97e360abab7d6ff4b81ee970a7e97466acfd"
+ "9644f828ffec538abc383d0e92326d1c88c55e1f46a668a039beaa1be631a891"
+ "29938c00a81a3ae46d4aecbf9707f764dbaccea3ef7665e4c4307fa0b0a3075c",
+ "224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de",
+ "178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9",
+ "87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2",
+ "4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66",
+ false // F (2 - R changed)
+ },
+ {
+ "4a8c071ac4fd0d52faa407b0fe5dab759f7394a5832127f2a3498f34aac28733"
+ "9e043b4ffa79528faf199dc917f7b066ad65505dab0e11e6948515052ce20cfd"
+ "b892ffb8aa9bf3f1aa5be30a5bbe85823bddf70b39fd7ebd4a93a2f75472c1d4"
+ "f606247a9821f1a8c45a6cb80545de2e0c6c0174e2392088c754e9c8443eb5af",
+ "43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369",
+ "f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac",
+ "8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce",
+ "cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154",
+ false // F (3 - S changed)
+ },
+ {
+ "0a3a12c3084c865daf1d302c78215d39bfe0b8bf28272b3c0b74beb4b7409db0"
+ "718239de700785581514321c6440a4bbaea4c76fa47401e151e68cb6c29017f0"
+ "bce4631290af5ea5e2bf3ed742ae110b04ade83a5dbd7358f29a85938e23d87a"
+ "c8233072b79c94670ff0959f9c7f4517862ff829452096c78f5f2e9a7e4e9216",
+ "9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596",
+ "972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405",
+ "dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb",
+ "8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2",
+ false // F (1 - Message changed)
+ },
+ {
+ "785d07a3c54f63dca11f5d1a5f496ee2c2f9288e55007e666c78b007d95cc285"
+ "81dce51f490b30fa73dc9e2d45d075d7e3a95fb8a9e1465ad191904124160b7c"
+ "60fa720ef4ef1c5d2998f40570ae2a870ef3e894c2bc617d8a1dc85c3c557749"
+ "28c38789b4e661349d3f84d2441a3b856a76949b9f1f80bc161648a1cad5588e",
+ "072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda",
+ "9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5",
+ "09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19",
+ "a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d",
+ false // F (4 - Q changed)
+ },
+ {
+ "76f987ec5448dd72219bd30bf6b66b0775c80b394851a43ff1f537f140a6e722"
+ "9ef8cd72ad58b1d2d20298539d6347dd5598812bc65323aceaf05228f738b5ad"
+ "3e8d9fe4100fd767c2f098c77cb99c2992843ba3eed91d32444f3b6db6cd212d"
+ "d4e5609548f4bb62812a920f6e2bf1581be1ebeebdd06ec4e971862cc42055ca",
+ "09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24",
+ "f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5",
+ "5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73",
+ "9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7",
+ false // F (1 - Message changed)
+ },
+ {
+ "60cd64b2cd2be6c33859b94875120361a24085f3765cb8b2bf11e026fa9d8855"
+ "dbe435acf7882e84f3c7857f96e2baab4d9afe4588e4a82e17a78827bfdb5ddb"
+ "d1c211fbc2e6d884cddd7cb9d90d5bf4a7311b83f352508033812c776a0e00c0"
+ "03c7e0d628e50736c7512df0acfa9f2320bd102229f46495ae6d0857cc452a84",
+ "2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d",
+ "9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a",
+ "06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959",
+ "62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce",
+ true // P (0 )
+ },
+ {nullptr}};
} // namespace
@@ -242,8 +256,8 @@ TEST(ChannelIDTest, SignAndVerify) {
scoped_ptr<char[]> bad_key(new char[key.size()]);
memcpy(bad_key.get(), key.data(), key.size());
bad_key[1] ^= 0x80;
- EXPECT_FALSE(ChannelIDVerifier::Verify(
- string(bad_key.get(), key.size()), signed_data, signature));
+ EXPECT_FALSE(ChannelIDVerifier::Verify(string(bad_key.get(), key.size()),
+ signed_data, signature));
scoped_ptr<char[]> bad_signature(new char[signature.size()]);
memcpy(bad_signature.get(), signature.data(), signature.size());
@@ -251,8 +265,7 @@ TEST(ChannelIDTest, SignAndVerify) {
EXPECT_FALSE(ChannelIDVerifier::Verify(
key, signed_data, string(bad_signature.get(), signature.size())));
- EXPECT_FALSE(ChannelIDVerifier::Verify(
- key, "wrong signed data", signature));
+ EXPECT_FALSE(ChannelIDVerifier::Verify(key, "wrong signed data", signature));
}
} // namespace test
diff --git a/chromium/net/quic/crypto/common_cert_set.cc b/chromium/net/quic/crypto/common_cert_set.cc
index d4603c71f01..b771fa002f6 100644
--- a/chromium/net/quic/crypto/common_cert_set.cc
+++ b/chromium/net/quic/crypto/common_cert_set.cc
@@ -4,8 +4,8 @@
#include "net/quic/crypto/common_cert_set.h"
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "net/quic/quic_utils.h"
@@ -17,6 +17,10 @@ namespace common_cert_set_1 {
#include "net/quic/crypto/common_cert_set_1.c"
}
+namespace common_cert_set_2 {
+#include "net/quic/crypto/common_cert_set_2.c"
+}
+
namespace {
struct CertSet {
@@ -28,20 +32,22 @@ struct CertSet {
// of each certificate.
const size_t* lens;
// hash contains the 64-bit, FNV-1a hash of this set.
- uint64 hash;
+ uint64_t hash;
};
const CertSet kSets[] = {
- {
- common_cert_set_1::kNumCerts,
- common_cert_set_1::kCerts,
- common_cert_set_1::kLens,
- common_cert_set_1::kHash,
- },
+ {
+ common_cert_set_1::kNumCerts, common_cert_set_1::kCerts,
+ common_cert_set_1::kLens, common_cert_set_1::kHash,
+ },
+ {
+ common_cert_set_2::kNumCerts, common_cert_set_2::kCerts,
+ common_cert_set_2::kLens, common_cert_set_2::kHash,
+ },
};
-const uint64 kSetHashes[] = {
- common_cert_set_1::kHash,
+const uint64_t kSetHashes[] = {
+ common_cert_set_1::kHash, common_cert_set_2::kHash,
};
// Compare returns a value less than, equal to or greater than zero if |a| is
@@ -71,10 +77,10 @@ class CommonCertSetsQUIC : public CommonCertSets {
// CommonCertSets interface.
StringPiece GetCommonHashes() const override {
return StringPiece(reinterpret_cast<const char*>(kSetHashes),
- sizeof(uint64) * arraysize(kSetHashes));
+ sizeof(uint64_t) * arraysize(kSetHashes));
}
- StringPiece GetCert(uint64 hash, uint32 index) const override {
+ StringPiece GetCert(uint64_t hash, uint32_t index) const override {
for (size_t i = 0; i < arraysize(kSets); i++) {
if (kSets[i].hash == hash) {
if (index < kSets[i].num_certs) {
@@ -91,16 +97,16 @@ class CommonCertSetsQUIC : public CommonCertSets {
bool MatchCert(StringPiece cert,
StringPiece common_set_hashes,
- uint64* out_hash,
- uint32* out_index) const override {
- if (common_set_hashes.size() % sizeof(uint64) != 0) {
+ uint64_t* out_hash,
+ uint32_t* out_index) const override {
+ if (common_set_hashes.size() % sizeof(uint64_t) != 0) {
return false;
}
- for (size_t i = 0; i < common_set_hashes.size() / sizeof(uint64); i++) {
- uint64 hash;
- memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64),
- sizeof(uint64));
+ for (size_t i = 0; i < common_set_hashes.size() / sizeof(uint64_t); i++) {
+ uint64_t hash;
+ memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64_t),
+ sizeof(uint64_t));
for (size_t j = 0; j < arraysize(kSets); j++) {
if (kSets[j].hash != hash) {
diff --git a/chromium/net/quic/crypto/common_cert_set.h b/chromium/net/quic/crypto/common_cert_set.h
index a9e93045f57..b4fbfac0a11 100644
--- a/chromium/net/quic/crypto/common_cert_set.h
+++ b/chromium/net/quic/crypto/common_cert_set.h
@@ -5,7 +5,8 @@
#ifndef NET_QUIC_CRYPTO_COMMON_CERT_SET_H_
#define NET_QUIC_CRYPTO_COMMON_CERT_SET_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -30,7 +31,7 @@ class NET_EXPORT_PRIVATE CommonCertSets {
// GetCert returns a specific certificate (at index |index|) in the common
// set identified by |hash|. If no such certificate is known, an empty
// StringPiece is returned.
- virtual base::StringPiece GetCert(uint64 hash, uint32 index) const = 0;
+ virtual base::StringPiece GetCert(uint64_t hash, uint32_t index) const = 0;
// MatchCert tries to find |cert| in one of the common certificate sets
// identified by |common_set_hashes|. On success it puts the hash of the
@@ -38,8 +39,8 @@ class NET_EXPORT_PRIVATE CommonCertSets {
// returns true. Otherwise it returns false.
virtual bool MatchCert(base::StringPiece cert,
base::StringPiece common_set_hashes,
- uint64* out_hash,
- uint32* out_index) const = 0;
+ uint64_t* out_hash,
+ uint32_t* out_index) const = 0;
};
} // namespace net
diff --git a/chromium/net/quic/crypto/common_cert_set_1.c b/chromium/net/quic/crypto/common_cert_set_1.c
index aa436e2e926..e8325758811 100644
--- a/chromium/net/quic/crypto/common_cert_set_1.c
+++ b/chromium/net/quic/crypto/common_cert_set_1.c
@@ -6,6 +6,8 @@
/* This file contains common certificates. It's designed to be #included in
* another file, in a namespace. */
+#include <stdint.h>
+
#include "net/quic/crypto/common_cert_set_1a.inc"
#include "net/quic/crypto/common_cert_set_1b.inc"
@@ -140,4 +142,4 @@ static const size_t kLens[] = {
1770,
};
-static const uint64 kHash = UINT64_C(0xff715ce4e7e9267b);
+static const uint64_t kHash = UINT64_C(0xff715ce4e7e9267b);
diff --git a/chromium/net/quic/crypto/common_cert_set_2.c b/chromium/net/quic/crypto/common_cert_set_2.c
new file mode 100644
index 00000000000..a10e892b832
--- /dev/null
+++ b/chromium/net/quic/crypto/common_cert_set_2.c
@@ -0,0 +1,129 @@
+/* Copyright (c) 2015 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.
+ */
+
+/* This file contains common certificates. It's designed to be #included in
+ * another file, in a namespace. */
+
+#include <stdint.h>
+
+#include "net/quic/crypto/common_cert_set_2a.inc"
+#include "net/quic/crypto/common_cert_set_2b.inc"
+
+static const size_t kNumCerts = 54;
+static const unsigned char* const kCerts[] = {
+ kDERCert0,
+ kDERCert1,
+ kDERCert2,
+ kDERCert3,
+ kDERCert4,
+ kDERCert5,
+ kDERCert6,
+ kDERCert7,
+ kDERCert8,
+ kDERCert9,
+ kDERCert10,
+ kDERCert11,
+ kDERCert12,
+ kDERCert13,
+ kDERCert14,
+ kDERCert15,
+ kDERCert16,
+ kDERCert17,
+ kDERCert18,
+ kDERCert19,
+ kDERCert20,
+ kDERCert21,
+ kDERCert22,
+ kDERCert23,
+ kDERCert24,
+ kDERCert25,
+ kDERCert26,
+ kDERCert27,
+ kDERCert28,
+ kDERCert29,
+ kDERCert30,
+ kDERCert31,
+ kDERCert32,
+ kDERCert33,
+ kDERCert34,
+ kDERCert35,
+ kDERCert36,
+ kDERCert37,
+ kDERCert38,
+ kDERCert39,
+ kDERCert40,
+ kDERCert41,
+ kDERCert42,
+ kDERCert43,
+ kDERCert44,
+ kDERCert45,
+ kDERCert46,
+ kDERCert47,
+ kDERCert48,
+ kDERCert49,
+ kDERCert50,
+ kDERCert51,
+ kDERCert52,
+ kDERCert53,
+};
+
+static const size_t kLens[] = {
+ 897,
+ 911,
+ 985,
+ 1012,
+ 1049,
+ 1062,
+ 1065,
+ 1071,
+ 1084,
+ 1096,
+ 1097,
+ 1105,
+ 1107,
+ 1117,
+ 1127,
+ 1133,
+ 1136,
+ 1138,
+ 1153,
+ 1171,
+ 1172,
+ 1176,
+ 1182,
+ 1188,
+ 1194,
+ 1203,
+ 1205,
+ 1206,
+ 1210,
+ 1222,
+ 1226,
+ 1236,
+ 1236,
+ 1236,
+ 1238,
+ 1256,
+ 1270,
+ 1280,
+ 1283,
+ 1284,
+ 1287,
+ 1315,
+ 1327,
+ 1340,
+ 1418,
+ 1447,
+ 1509,
+ 1520,
+ 1570,
+ 1581,
+ 1592,
+ 1628,
+ 1632,
+ 1770,
+};
+
+static const uint64_t kHash = UINT64_C(0xe81a92926081e801);
diff --git a/chromium/net/quic/crypto/common_cert_set_2a.inc b/chromium/net/quic/crypto/common_cert_set_2a.inc
new file mode 100644
index 00000000000..f71001f5a3a
--- /dev/null
+++ b/chromium/net/quic/crypto/common_cert_set_2a.inc
@@ -0,0 +1,5627 @@
+/* Copyright (c) 2015 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.
+ */
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1227750 (0x12bbe6)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
+ Validity
+ Not Before: May 21 04:00:00 2002 GMT
+ Not After : Aug 21 04:00:00 2018 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df:
+ 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8:
+ 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29:
+ bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4:
+ 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3:
+ ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92:
+ 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d:
+ 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14:
+ 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd:
+ d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6:
+ d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5:
+ 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39:
+ 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05:
+ 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2:
+ fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32:
+ eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07:
+ 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b:
+ e4:f9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
+
+ X509v3 Subject Key Identifier:
+ C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.geotrust.com/crls/secureca.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.geotrust.com/resources/repository
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 76:e1:12:6e:4e:4b:16:12:86:30:06:b2:81:08:cf:f0:08:c7:
+ c7:71:7e:66:ee:c2:ed:d4:3b:1f:ff:f0:f0:c8:4e:d6:43:38:
+ b0:b9:30:7d:18:d0:55:83:a2:6a:cb:36:11:9c:e8:48:66:a3:
+ 6d:7f:b8:13:d4:47:fe:8b:5a:5c:73:fc:ae:d9:1b:32:19:38:
+ ab:97:34:14:aa:96:d2:eb:a3:1c:14:08:49:b6:bb:e5:91:ef:
+ 83:36:eb:1d:56:6f:ca:da:bc:73:63:90:e4:7f:7b:3e:22:cb:
+ 3d:07:ed:5f:38:74:9c:e3:03:50:4e:a1:af:98:ee:61:f2:84:
+ 3f:12
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
+MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
+aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
+WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
+AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
+OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
+T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
+JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
+Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
+PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
+aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
+TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
+LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
+BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
+dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
+AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
+NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
+b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert0[] = {
+ 0x30, 0x82, 0x03, 0x7d, 0x30, 0x82, 0x02, 0xe6, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x12, 0xbb, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45,
+ 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03,
+ 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
+ 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+ 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30,
+ 0x35, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
+ 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30,
+ 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01,
+ 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+ 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0xcc, 0x18, 0x63, 0x30, 0xfd,
+ 0xf4, 0x17, 0x23, 0x1a, 0x56, 0x7e, 0x5b, 0xdf, 0x3c, 0x6c, 0x38, 0xe4,
+ 0x71, 0xb7, 0x78, 0x91, 0xd4, 0xbc, 0xa1, 0xd8, 0x4c, 0xf8, 0xa8, 0x43,
+ 0xb6, 0x03, 0xe9, 0x4d, 0x21, 0x07, 0x08, 0x88, 0xda, 0x58, 0x2f, 0x66,
+ 0x39, 0x29, 0xbd, 0x05, 0x78, 0x8b, 0x9d, 0x38, 0xe8, 0x05, 0xb7, 0x6a,
+ 0x7e, 0x71, 0xa4, 0xe6, 0xc4, 0x60, 0xa6, 0xb0, 0xef, 0x80, 0xe4, 0x89,
+ 0x28, 0x0f, 0x9e, 0x25, 0xd6, 0xed, 0x83, 0xf3, 0xad, 0xa6, 0x91, 0xc7,
+ 0x98, 0xc9, 0x42, 0x18, 0x35, 0x14, 0x9d, 0xad, 0x98, 0x46, 0x92, 0x2e,
+ 0x4f, 0xca, 0xf1, 0x87, 0x43, 0xc1, 0x16, 0x95, 0x57, 0x2d, 0x50, 0xef,
+ 0x89, 0x2d, 0x80, 0x7a, 0x57, 0xad, 0xf2, 0xee, 0x5f, 0x6b, 0xd2, 0x00,
+ 0x8d, 0xb9, 0x14, 0xf8, 0x14, 0x15, 0x35, 0xd9, 0xc0, 0x46, 0xa3, 0x7b,
+ 0x72, 0xc8, 0x91, 0xbf, 0xc9, 0x55, 0x2b, 0xcd, 0xd0, 0x97, 0x3e, 0x9c,
+ 0x26, 0x64, 0xcc, 0xdf, 0xce, 0x83, 0x19, 0x71, 0xca, 0x4e, 0xe6, 0xd4,
+ 0xd5, 0x7b, 0xa9, 0x19, 0xcd, 0x55, 0xde, 0xc8, 0xec, 0xd2, 0x5e, 0x38,
+ 0x53, 0xe5, 0x5c, 0x4f, 0x8c, 0x2d, 0xfe, 0x50, 0x23, 0x36, 0xfc, 0x66,
+ 0xe6, 0xcb, 0x8e, 0xa4, 0x39, 0x19, 0x00, 0xb7, 0x95, 0x02, 0x39, 0x91,
+ 0x0b, 0x0e, 0xfe, 0x38, 0x2e, 0xd1, 0x1d, 0x05, 0x9a, 0xf6, 0x4d, 0x3e,
+ 0x6f, 0x0f, 0x07, 0x1d, 0xaf, 0x2c, 0x1e, 0x8f, 0x60, 0x39, 0xe2, 0xfa,
+ 0x36, 0x53, 0x13, 0x39, 0xd4, 0x5e, 0x26, 0x2b, 0xdb, 0x3d, 0xa8, 0x14,
+ 0xbd, 0x32, 0xeb, 0x18, 0x03, 0x28, 0x52, 0x04, 0x71, 0xe5, 0xab, 0x33,
+ 0x3d, 0xe1, 0x38, 0xbb, 0x07, 0x36, 0x84, 0x62, 0x9c, 0x79, 0xea, 0x16,
+ 0x30, 0xf4, 0x5f, 0xc0, 0x2b, 0xe8, 0x71, 0x6b, 0xe4, 0xf9, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x81, 0xf0, 0x30, 0x81, 0xed, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6,
+ 0x68, 0xf9, 0x2b, 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10,
+ 0x4f, 0x33, 0x98, 0x90, 0x9f, 0xd4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
+ 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
+ 0x4e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+ 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a,
+ 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0,
+ 0x2d, 0xa0, 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65,
+ 0x63, 0x75, 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4e,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43, 0x06,
+ 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f,
+ 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65,
+ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x70, 0x6f,
+ 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81,
+ 0x00, 0x76, 0xe1, 0x12, 0x6e, 0x4e, 0x4b, 0x16, 0x12, 0x86, 0x30, 0x06,
+ 0xb2, 0x81, 0x08, 0xcf, 0xf0, 0x08, 0xc7, 0xc7, 0x71, 0x7e, 0x66, 0xee,
+ 0xc2, 0xed, 0xd4, 0x3b, 0x1f, 0xff, 0xf0, 0xf0, 0xc8, 0x4e, 0xd6, 0x43,
+ 0x38, 0xb0, 0xb9, 0x30, 0x7d, 0x18, 0xd0, 0x55, 0x83, 0xa2, 0x6a, 0xcb,
+ 0x36, 0x11, 0x9c, 0xe8, 0x48, 0x66, 0xa3, 0x6d, 0x7f, 0xb8, 0x13, 0xd4,
+ 0x47, 0xfe, 0x8b, 0x5a, 0x5c, 0x73, 0xfc, 0xae, 0xd9, 0x1b, 0x32, 0x19,
+ 0x38, 0xab, 0x97, 0x34, 0x14, 0xaa, 0x96, 0xd2, 0xeb, 0xa3, 0x1c, 0x14,
+ 0x08, 0x49, 0xb6, 0xbb, 0xe5, 0x91, 0xef, 0x83, 0x36, 0xeb, 0x1d, 0x56,
+ 0x6f, 0xca, 0xda, 0xbc, 0x73, 0x63, 0x90, 0xe4, 0x7f, 0x7b, 0x3e, 0x22,
+ 0xcb, 0x3d, 0x07, 0xed, 0x5f, 0x38, 0x74, 0x9c, 0xe3, 0x03, 0x50, 0x4e,
+ 0xa1, 0xaf, 0x98, 0xee, 0x61, 0xf2, 0x84, 0x3f, 0x12,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 880226 (0xd6e62)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
+ Validity
+ Not Before: Nov 27 00:00:00 2006 GMT
+ Not After : Aug 21 16:15:00 2018 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8:
+ 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44:
+ 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02:
+ bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e:
+ 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed:
+ 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0:
+ 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75:
+ e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30:
+ 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a:
+ 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8:
+ 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68:
+ 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df:
+ be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42:
+ 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af:
+ 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f:
+ fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef:
+ 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70:
+ 71:35
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
+ X509v3 Authority Key Identifier:
+ keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.geotrust.com/crls/secureca.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.geotrust.com/resources/cps
+
+ Signature Algorithm: sha1WithRSAEncryption
+ af:f3:0e:d6:72:ab:c7:a9:97:ca:2a:6b:84:39:de:79:a9:f0:
+ 81:e5:08:67:ab:d7:2f:20:02:01:71:0c:04:22:c9:1e:88:95:
+ 03:c9:49:3a:af:67:08:49:b0:d5:08:f5:20:3d:80:91:a0:c5:
+ 87:a3:fb:c9:a3:17:91:f9:a8:2f:ae:e9:0f:df:96:72:0f:75:
+ 17:80:5d:78:01:4d:9f:1f:6d:7b:d8:f5:42:38:23:1a:99:93:
+ f4:83:be:3b:35:74:e7:37:13:35:7a:ac:b4:b6:90:82:6c:27:
+ a4:e0:ec:9e:35:bd:bf:e5:29:a1:47:9f:5b:32:fc:e9:99:7d:
+ 2b:39
+-----BEGIN CERTIFICATE-----
+MIIDizCCAvSgAwIBAgIDDW5iMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
+MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
+aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMTI3MDAwMDAwWhcNMTgwODIxMTYxNTAw
+WjBYMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UE
+AxMoR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64FXv/1Hx9Z62DZHvIQlMt3/aE
+CCBh1gFZapxEEa/vdv2Vfs5hMLt6g18CvQFmyu4VjW+hMJy9oYWelDrzVogAMc/Y
+7mqWAtntA4z7dW3n6rhVFgUWmvTgXrGIwGSFXBVNiMe3uuB16a0FPZ3HiUjguyjI
+A+Ewk2ReUsBZcCI1V4iK8ZUKg9e8MXMBNO3vRnHgawKoNXJrl5tm4MsceV/YGgRo
+HkcC5p1g4jaXAd/ONZLfvmfHbXdZO4+d1pAVlLxCNBDBOfmxJz5+1op1xbKvltOi
+3pvkmL594emBrbZv/NcO2uA0sA0ad+fjCJjvWPqchLc2r8LfrNL0EAZwcTUCAwEA
+AaOB6DCB5TAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCzVUEGXFYvwjzZhW0r7
+a9mZyTOSMB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMA8GA1UdEwEB
+/wQFMAMBAf8wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5j
+b20vY3Jscy9zZWN1cmVjYS5jcmwwRgYDVR0gBD8wPTA7BgRVHSAAMDMwMQYIKwYB
+BQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwDQYJ
+KoZIhvcNAQEFBQADgYEAr/MO1nKrx6mXyiprhDneeanwgeUIZ6vXLyACAXEMBCLJ
+HoiVA8lJOq9nCEmw1Qj1ID2AkaDFh6P7yaMXkfmoL67pD9+Wcg91F4BdeAFNnx9t
+e9j1QjgjGpmT9IO+OzV05zcTNXqstLaQgmwnpODsnjW9v+UpoUefWzL86Zl9Kzk=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert1[] = {
+ 0x30, 0x82, 0x03, 0x8b, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x0d, 0x6e, 0x62, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45,
+ 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03,
+ 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
+ 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+ 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31,
+ 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d,
+ 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x31, 0x36, 0x31, 0x35, 0x30, 0x30,
+ 0x5a, 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+ 0x82, 0x01, 0x01, 0x00, 0xbe, 0xb8, 0x15, 0x7b, 0xff, 0xd4, 0x7c, 0x7d,
+ 0x67, 0xad, 0x83, 0x64, 0x7b, 0xc8, 0x42, 0x53, 0x2d, 0xdf, 0xf6, 0x84,
+ 0x08, 0x20, 0x61, 0xd6, 0x01, 0x59, 0x6a, 0x9c, 0x44, 0x11, 0xaf, 0xef,
+ 0x76, 0xfd, 0x95, 0x7e, 0xce, 0x61, 0x30, 0xbb, 0x7a, 0x83, 0x5f, 0x02,
+ 0xbd, 0x01, 0x66, 0xca, 0xee, 0x15, 0x8d, 0x6f, 0xa1, 0x30, 0x9c, 0xbd,
+ 0xa1, 0x85, 0x9e, 0x94, 0x3a, 0xf3, 0x56, 0x88, 0x00, 0x31, 0xcf, 0xd8,
+ 0xee, 0x6a, 0x96, 0x02, 0xd9, 0xed, 0x03, 0x8c, 0xfb, 0x75, 0x6d, 0xe7,
+ 0xea, 0xb8, 0x55, 0x16, 0x05, 0x16, 0x9a, 0xf4, 0xe0, 0x5e, 0xb1, 0x88,
+ 0xc0, 0x64, 0x85, 0x5c, 0x15, 0x4d, 0x88, 0xc7, 0xb7, 0xba, 0xe0, 0x75,
+ 0xe9, 0xad, 0x05, 0x3d, 0x9d, 0xc7, 0x89, 0x48, 0xe0, 0xbb, 0x28, 0xc8,
+ 0x03, 0xe1, 0x30, 0x93, 0x64, 0x5e, 0x52, 0xc0, 0x59, 0x70, 0x22, 0x35,
+ 0x57, 0x88, 0x8a, 0xf1, 0x95, 0x0a, 0x83, 0xd7, 0xbc, 0x31, 0x73, 0x01,
+ 0x34, 0xed, 0xef, 0x46, 0x71, 0xe0, 0x6b, 0x02, 0xa8, 0x35, 0x72, 0x6b,
+ 0x97, 0x9b, 0x66, 0xe0, 0xcb, 0x1c, 0x79, 0x5f, 0xd8, 0x1a, 0x04, 0x68,
+ 0x1e, 0x47, 0x02, 0xe6, 0x9d, 0x60, 0xe2, 0x36, 0x97, 0x01, 0xdf, 0xce,
+ 0x35, 0x92, 0xdf, 0xbe, 0x67, 0xc7, 0x6d, 0x77, 0x59, 0x3b, 0x8f, 0x9d,
+ 0xd6, 0x90, 0x15, 0x94, 0xbc, 0x42, 0x34, 0x10, 0xc1, 0x39, 0xf9, 0xb1,
+ 0x27, 0x3e, 0x7e, 0xd6, 0x8a, 0x75, 0xc5, 0xb2, 0xaf, 0x96, 0xd3, 0xa2,
+ 0xde, 0x9b, 0xe4, 0x98, 0xbe, 0x7d, 0xe1, 0xe9, 0x81, 0xad, 0xb6, 0x6f,
+ 0xfc, 0xd7, 0x0e, 0xda, 0xe0, 0x34, 0xb0, 0x0d, 0x1a, 0x77, 0xe7, 0xe3,
+ 0x08, 0x98, 0xef, 0x58, 0xfa, 0x9c, 0x84, 0xb7, 0x36, 0xaf, 0xc2, 0xdf,
+ 0xac, 0xd2, 0xf4, 0x10, 0x06, 0x70, 0x71, 0x35, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x81, 0xe8, 0x30, 0x81, 0xe5, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2c, 0xd5,
+ 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb,
+ 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6, 0x68, 0xf9, 0x2b,
+ 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10, 0x4f, 0x33, 0x98,
+ 0x90, 0x9f, 0xd4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3a, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0,
+ 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65, 0x63, 0x75,
+ 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x03,
+ 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55,
+ 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75,
+ 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x81, 0x81, 0x00, 0xaf, 0xf3, 0x0e, 0xd6, 0x72, 0xab, 0xc7, 0xa9, 0x97,
+ 0xca, 0x2a, 0x6b, 0x84, 0x39, 0xde, 0x79, 0xa9, 0xf0, 0x81, 0xe5, 0x08,
+ 0x67, 0xab, 0xd7, 0x2f, 0x20, 0x02, 0x01, 0x71, 0x0c, 0x04, 0x22, 0xc9,
+ 0x1e, 0x88, 0x95, 0x03, 0xc9, 0x49, 0x3a, 0xaf, 0x67, 0x08, 0x49, 0xb0,
+ 0xd5, 0x08, 0xf5, 0x20, 0x3d, 0x80, 0x91, 0xa0, 0xc5, 0x87, 0xa3, 0xfb,
+ 0xc9, 0xa3, 0x17, 0x91, 0xf9, 0xa8, 0x2f, 0xae, 0xe9, 0x0f, 0xdf, 0x96,
+ 0x72, 0x0f, 0x75, 0x17, 0x80, 0x5d, 0x78, 0x01, 0x4d, 0x9f, 0x1f, 0x6d,
+ 0x7b, 0xd8, 0xf5, 0x42, 0x38, 0x23, 0x1a, 0x99, 0x93, 0xf4, 0x83, 0xbe,
+ 0x3b, 0x35, 0x74, 0xe7, 0x37, 0x13, 0x35, 0x7a, 0xac, 0xb4, 0xb6, 0x90,
+ 0x82, 0x6c, 0x27, 0xa4, 0xe0, 0xec, 0x9e, 0x35, 0xbd, 0xbf, 0xe5, 0x29,
+ 0xa1, 0x47, 0x9f, 0x5b, 0x32, 0xfc, 0xe9, 0x99, 0x7d, 0x2b, 0x39,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 145105 (0x236d1)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Validity
+ Not Before: Feb 19 22:45:05 2010 GMT
+ Not After : Feb 18 22:45:05 2020 GMT
+ Subject: C=US, O=GeoTrust, Inc., CN=RapidSSL CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c7:71:f8:56:c7:1e:d9:cc:b5:ad:f6:b4:97:a3:
+ fb:a1:e6:0b:50:5f:50:aa:3a:da:0f:fc:3d:29:24:
+ 43:c6:10:29:c1:fc:55:40:72:ee:bd:ea:df:9f:b6:
+ 41:f4:48:4b:c8:6e:fe:4f:57:12:8b:5b:fa:92:dd:
+ 5e:e8:ad:f3:f0:1b:b1:7b:4d:fb:cf:fd:d1:e5:f8:
+ e3:dc:e7:f5:73:7f:df:01:49:cf:8c:56:c1:bd:37:
+ e3:5b:be:b5:4f:8b:8b:f0:da:4f:c7:e3:dd:55:47:
+ 69:df:f2:5b:7b:07:4f:3d:e5:ac:21:c1:c8:1d:7a:
+ e8:e7:f6:0f:a1:aa:f5:6f:de:a8:65:4f:10:89:9c:
+ 03:f3:89:7a:a5:5e:01:72:33:ed:a9:e9:5a:1e:79:
+ f3:87:c8:df:c8:c5:fc:37:c8:9a:9a:d7:b8:76:cc:
+ b0:3e:e7:fd:e6:54:ea:df:5f:52:41:78:59:57:ad:
+ f1:12:d6:7f:bc:d5:9f:70:d3:05:6c:fa:a3:7d:67:
+ 58:dd:26:62:1d:31:92:0c:79:79:1c:8e:cf:ca:7b:
+ c1:66:af:a8:74:48:fb:8e:82:c2:9e:2c:99:5c:7b:
+ 2d:5d:9b:bc:5b:57:9e:7c:3a:7a:13:ad:f2:a3:18:
+ 5b:2b:59:0f:cd:5c:3a:eb:68:33:c6:28:1d:82:d1:
+ 50:8b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 6B:69:3D:6A:18:42:4A:DD:8F:02:65:39:FD:35:24:86:78:91:16:30
+ X509v3 Authority Key Identifier:
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.geotrust.com/crls/gtglobal.crl
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.geotrust.com
+
+ Signature Algorithm: sha1WithRSAEncryption
+ ab:bc:bc:0a:5d:18:94:e3:c1:b1:c3:a8:4c:55:d6:be:b4:98:
+ f1:ee:3c:1c:cd:cf:f3:24:24:5c:96:03:27:58:fc:36:ae:a2:
+ 2f:8f:f1:fe:da:2b:02:c3:33:bd:c8:dd:48:22:2b:60:0f:a5:
+ 03:10:fd:77:f8:d0:ed:96:67:4f:fd:ea:47:20:70:54:dc:a9:
+ 0c:55:7e:e1:96:25:8a:d9:b5:da:57:4a:be:8d:8e:49:43:63:
+ a5:6c:4e:27:87:25:eb:5b:6d:fe:a2:7f:38:28:e0:36:ab:ad:
+ 39:a5:a5:62:c4:b7:5c:58:2c:aa:5d:01:60:a6:62:67:a3:c0:
+ c7:62:23:f4:e7:6c:46:ee:b5:d3:80:6a:22:13:d2:2d:3f:74:
+ 4f:ea:af:8c:5f:b4:38:9c:db:ae:ce:af:84:1e:a6:f6:34:51:
+ 59:79:d3:e3:75:dc:bc:d7:f3:73:df:92:ec:d2:20:59:6f:9c:
+ fb:95:f8:92:76:18:0a:7c:0f:2c:a6:ca:de:8a:62:7b:d8:f3:
+ ce:5f:68:bd:8f:3e:c1:74:bb:15:72:3a:16:83:a9:0b:e6:4d:
+ 99:9c:d8:57:ec:a8:01:51:c7:6f:57:34:5e:ab:4a:2c:42:f6:
+ 4f:1c:89:78:de:26:4e:f5:6f:93:4c:15:6b:27:56:4d:00:54:
+ 6c:7a:b7:b7
+-----BEGIN CERTIFICATE-----
+MIID1TCCAr2gAwIBAgIDAjbRMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTAwMjE5MjI0NTA1WhcNMjAwMjE4MjI0NTA1WjA8MQswCQYDVQQG
+EwJVUzEXMBUGA1UEChMOR2VvVHJ1c3QsIEluYy4xFDASBgNVBAMTC1JhcGlkU1NM
+IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3H4Vsce2cy1rfa0
+l6P7oeYLUF9QqjraD/w9KSRDxhApwfxVQHLuverfn7ZB9EhLyG7+T1cSi1v6kt1e
+6K3z8Buxe037z/3R5fjj3Of1c3/fAUnPjFbBvTfjW761T4uL8NpPx+PdVUdp3/Jb
+ewdPPeWsIcHIHXro5/YPoar1b96oZU8QiZwD84l6pV4BcjPtqelaHnnzh8jfyMX8
+N8iamte4dsywPuf95lTq319SQXhZV63xEtZ/vNWfcNMFbPqjfWdY3SZiHTGSDHl5
+HI7PynvBZq+odEj7joLCniyZXHstXZu8W1eefDp6E63yoxhbK1kPzVw662gzxigd
+gtFQiwIDAQABo4HZMIHWMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUa2k9ahhC
+St2PAmU5/TUkhniRFjAwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4w
+EgYDVR0TAQH/BAgwBgEB/wIBADA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3Js
+Lmdlb3RydXN0LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDA0BggrBgEFBQcBAQQoMCYw
+JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdlb3RydXN0LmNvbTANBgkqhkiG9w0B
+AQUFAAOCAQEAq7y8Cl0YlOPBscOoTFXWvrSY8e48HM3P8yQkXJYDJ1j8Nq6iL4/x
+/torAsMzvcjdSCIrYA+lAxD9d/jQ7ZZnT/3qRyBwVNypDFV+4ZYlitm12ldKvo2O
+SUNjpWxOJ4cl61tt/qJ/OCjgNqutOaWlYsS3XFgsql0BYKZiZ6PAx2Ij9OdsRu61
+04BqIhPSLT90T+qvjF+0OJzbrs6vhB6m9jRRWXnT43XcvNfzc9+S7NIgWW+c+5X4
+knYYCnwPLKbK3opie9jzzl9ovY8+wXS7FXI6FoOpC+ZNmZzYV+yoAVHHb1c0XqtK
+LEL2TxyJeN4mTvVvk0wVaydWTQBUbHq3tw==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert2[] = {
+ 0x30, 0x82, 0x03, 0xd5, 0x30, 0x82, 0x02, 0xbd, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x36, 0xd1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30,
+ 0x32, 0x31, 0x39, 0x32, 0x32, 0x34, 0x35, 0x30, 0x35, 0x5a, 0x17, 0x0d,
+ 0x32, 0x30, 0x30, 0x32, 0x31, 0x38, 0x32, 0x32, 0x34, 0x35, 0x30, 0x35,
+ 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0e, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2c,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x0b, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c,
+ 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xc7, 0x71, 0xf8, 0x56, 0xc7, 0x1e, 0xd9, 0xcc, 0xb5, 0xad, 0xf6, 0xb4,
+ 0x97, 0xa3, 0xfb, 0xa1, 0xe6, 0x0b, 0x50, 0x5f, 0x50, 0xaa, 0x3a, 0xda,
+ 0x0f, 0xfc, 0x3d, 0x29, 0x24, 0x43, 0xc6, 0x10, 0x29, 0xc1, 0xfc, 0x55,
+ 0x40, 0x72, 0xee, 0xbd, 0xea, 0xdf, 0x9f, 0xb6, 0x41, 0xf4, 0x48, 0x4b,
+ 0xc8, 0x6e, 0xfe, 0x4f, 0x57, 0x12, 0x8b, 0x5b, 0xfa, 0x92, 0xdd, 0x5e,
+ 0xe8, 0xad, 0xf3, 0xf0, 0x1b, 0xb1, 0x7b, 0x4d, 0xfb, 0xcf, 0xfd, 0xd1,
+ 0xe5, 0xf8, 0xe3, 0xdc, 0xe7, 0xf5, 0x73, 0x7f, 0xdf, 0x01, 0x49, 0xcf,
+ 0x8c, 0x56, 0xc1, 0xbd, 0x37, 0xe3, 0x5b, 0xbe, 0xb5, 0x4f, 0x8b, 0x8b,
+ 0xf0, 0xda, 0x4f, 0xc7, 0xe3, 0xdd, 0x55, 0x47, 0x69, 0xdf, 0xf2, 0x5b,
+ 0x7b, 0x07, 0x4f, 0x3d, 0xe5, 0xac, 0x21, 0xc1, 0xc8, 0x1d, 0x7a, 0xe8,
+ 0xe7, 0xf6, 0x0f, 0xa1, 0xaa, 0xf5, 0x6f, 0xde, 0xa8, 0x65, 0x4f, 0x10,
+ 0x89, 0x9c, 0x03, 0xf3, 0x89, 0x7a, 0xa5, 0x5e, 0x01, 0x72, 0x33, 0xed,
+ 0xa9, 0xe9, 0x5a, 0x1e, 0x79, 0xf3, 0x87, 0xc8, 0xdf, 0xc8, 0xc5, 0xfc,
+ 0x37, 0xc8, 0x9a, 0x9a, 0xd7, 0xb8, 0x76, 0xcc, 0xb0, 0x3e, 0xe7, 0xfd,
+ 0xe6, 0x54, 0xea, 0xdf, 0x5f, 0x52, 0x41, 0x78, 0x59, 0x57, 0xad, 0xf1,
+ 0x12, 0xd6, 0x7f, 0xbc, 0xd5, 0x9f, 0x70, 0xd3, 0x05, 0x6c, 0xfa, 0xa3,
+ 0x7d, 0x67, 0x58, 0xdd, 0x26, 0x62, 0x1d, 0x31, 0x92, 0x0c, 0x79, 0x79,
+ 0x1c, 0x8e, 0xcf, 0xca, 0x7b, 0xc1, 0x66, 0xaf, 0xa8, 0x74, 0x48, 0xfb,
+ 0x8e, 0x82, 0xc2, 0x9e, 0x2c, 0x99, 0x5c, 0x7b, 0x2d, 0x5d, 0x9b, 0xbc,
+ 0x5b, 0x57, 0x9e, 0x7c, 0x3a, 0x7a, 0x13, 0xad, 0xf2, 0xa3, 0x18, 0x5b,
+ 0x2b, 0x59, 0x0f, 0xcd, 0x5c, 0x3a, 0xeb, 0x68, 0x33, 0xc6, 0x28, 0x1d,
+ 0x82, 0xd1, 0x50, 0x8b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xd9,
+ 0x30, 0x81, 0xd6, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6b, 0x69, 0x3d, 0x6a, 0x18, 0x42,
+ 0x4a, 0xdd, 0x8f, 0x02, 0x65, 0x39, 0xfd, 0x35, 0x24, 0x86, 0x78, 0x91,
+ 0x16, 0x30, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+ 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05,
+ 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30,
+ 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
+ 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3a, 0x06, 0x03, 0x55,
+ 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b,
+ 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+ 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f,
+ 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30,
+ 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
+ 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
+ 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xab, 0xbc, 0xbc,
+ 0x0a, 0x5d, 0x18, 0x94, 0xe3, 0xc1, 0xb1, 0xc3, 0xa8, 0x4c, 0x55, 0xd6,
+ 0xbe, 0xb4, 0x98, 0xf1, 0xee, 0x3c, 0x1c, 0xcd, 0xcf, 0xf3, 0x24, 0x24,
+ 0x5c, 0x96, 0x03, 0x27, 0x58, 0xfc, 0x36, 0xae, 0xa2, 0x2f, 0x8f, 0xf1,
+ 0xfe, 0xda, 0x2b, 0x02, 0xc3, 0x33, 0xbd, 0xc8, 0xdd, 0x48, 0x22, 0x2b,
+ 0x60, 0x0f, 0xa5, 0x03, 0x10, 0xfd, 0x77, 0xf8, 0xd0, 0xed, 0x96, 0x67,
+ 0x4f, 0xfd, 0xea, 0x47, 0x20, 0x70, 0x54, 0xdc, 0xa9, 0x0c, 0x55, 0x7e,
+ 0xe1, 0x96, 0x25, 0x8a, 0xd9, 0xb5, 0xda, 0x57, 0x4a, 0xbe, 0x8d, 0x8e,
+ 0x49, 0x43, 0x63, 0xa5, 0x6c, 0x4e, 0x27, 0x87, 0x25, 0xeb, 0x5b, 0x6d,
+ 0xfe, 0xa2, 0x7f, 0x38, 0x28, 0xe0, 0x36, 0xab, 0xad, 0x39, 0xa5, 0xa5,
+ 0x62, 0xc4, 0xb7, 0x5c, 0x58, 0x2c, 0xaa, 0x5d, 0x01, 0x60, 0xa6, 0x62,
+ 0x67, 0xa3, 0xc0, 0xc7, 0x62, 0x23, 0xf4, 0xe7, 0x6c, 0x46, 0xee, 0xb5,
+ 0xd3, 0x80, 0x6a, 0x22, 0x13, 0xd2, 0x2d, 0x3f, 0x74, 0x4f, 0xea, 0xaf,
+ 0x8c, 0x5f, 0xb4, 0x38, 0x9c, 0xdb, 0xae, 0xce, 0xaf, 0x84, 0x1e, 0xa6,
+ 0xf6, 0x34, 0x51, 0x59, 0x79, 0xd3, 0xe3, 0x75, 0xdc, 0xbc, 0xd7, 0xf3,
+ 0x73, 0xdf, 0x92, 0xec, 0xd2, 0x20, 0x59, 0x6f, 0x9c, 0xfb, 0x95, 0xf8,
+ 0x92, 0x76, 0x18, 0x0a, 0x7c, 0x0f, 0x2c, 0xa6, 0xca, 0xde, 0x8a, 0x62,
+ 0x7b, 0xd8, 0xf3, 0xce, 0x5f, 0x68, 0xbd, 0x8f, 0x3e, 0xc1, 0x74, 0xbb,
+ 0x15, 0x72, 0x3a, 0x16, 0x83, 0xa9, 0x0b, 0xe6, 0x4d, 0x99, 0x9c, 0xd8,
+ 0x57, 0xec, 0xa8, 0x01, 0x51, 0xc7, 0x6f, 0x57, 0x34, 0x5e, 0xab, 0x4a,
+ 0x2c, 0x42, 0xf6, 0x4f, 0x1c, 0x89, 0x78, 0xde, 0x26, 0x4e, 0xf5, 0x6f,
+ 0x93, 0x4c, 0x15, 0x6b, 0x27, 0x56, 0x4d, 0x00, 0x54, 0x6c, 0x7a, 0xb7,
+ 0xb7,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 146051 (0x23a83)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Validity
+ Not Before: Apr 5 15:15:56 2013 GMT
+ Not After : Dec 31 23:59:59 2016 GMT
+ Subject: C=US, O=Google Inc, CN=Google Internet Authority G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9c:2a:04:77:5c:d8:50:91:3a:06:a3:82:e0:d8:
+ 50:48:bc:89:3f:f1:19:70:1a:88:46:7e:e0:8f:c5:
+ f1:89:ce:21:ee:5a:fe:61:0d:b7:32:44:89:a0:74:
+ 0b:53:4f:55:a4:ce:82:62:95:ee:eb:59:5f:c6:e1:
+ 05:80:12:c4:5e:94:3f:bc:5b:48:38:f4:53:f7:24:
+ e6:fb:91:e9:15:c4:cf:f4:53:0d:f4:4a:fc:9f:54:
+ de:7d:be:a0:6b:6f:87:c0:d0:50:1f:28:30:03:40:
+ da:08:73:51:6c:7f:ff:3a:3c:a7:37:06:8e:bd:4b:
+ 11:04:eb:7d:24:de:e6:f9:fc:31:71:fb:94:d5:60:
+ f3:2e:4a:af:42:d2:cb:ea:c4:6a:1a:b2:cc:53:dd:
+ 15:4b:8b:1f:c8:19:61:1f:cd:9d:a8:3e:63:2b:84:
+ 35:69:65:84:c8:19:c5:46:22:f8:53:95:be:e3:80:
+ 4a:10:c6:2a:ec:ba:97:20:11:c7:39:99:10:04:a0:
+ f0:61:7a:95:25:8c:4e:52:75:e2:b6:ed:08:ca:14:
+ fc:ce:22:6a:b3:4e:cf:46:03:97:97:03:7e:c0:b1:
+ de:7b:af:45:33:cf:ba:3e:71:b7:de:f4:25:25:c2:
+ 0d:35:89:9d:9d:fb:0e:11:79:89:1e:37:c5:af:8e:
+ 72:69
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+
+ X509v3 Subject Key Identifier:
+ 4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://g.symcd.com
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://g.symcb.com/crls/gtglobal.crl
+
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.11129.2.5.1
+
+ Signature Algorithm: sha256WithRSAEncryption
+ aa:fa:a9:20:cd:6a:67:83:ed:5e:d4:7e:de:1d:c4:7f:e0:25:
+ 06:00:c5:24:fb:a9:c8:2d:6d:7e:de:9d:82:65:2c:81:63:34:
+ 66:3e:e9:52:c2:08:b4:cb:2f:f7:5f:99:3a:6a:9c:50:7a:85:
+ 05:8c:7d:d1:2a:48:84:d3:09:6c:7c:c2:cd:35:9f:f3:82:ee:
+ 52:de:68:5f:e4:00:8a:17:20:96:f7:29:8d:9a:4d:cb:a8:de:
+ 86:c8:0d:6f:56:87:03:7d:03:3f:dc:fa:79:7d:21:19:f9:c8:
+ 3a:2f:51:76:8c:c7:41:92:71:8f:25:ce:37:f8:4a:4c:00:23:
+ ef:c4:35:10:ae:e0:23:80:73:7c:4d:34:2e:c8:6e:90:d6:10:
+ 1e:99:84:73:1a:70:f2:ed:55:0e:ee:17:06:ea:67:ee:32:eb:
+ 2c:dd:67:07:3f:f6:8b:c2:70:de:5b:00:e6:bb:1b:d3:36:1a:
+ 22:6c:6c:b0:35:42:6c:90:09:3d:93:e9:64:09:22:0e:85:06:
+ 9f:c2:73:21:d3:e6:5f:80:e4:8d:85:22:3a:73:03:b1:60:8e:
+ ae:68:e2:f4:3e:97:e7:60:12:09:68:36:de:3a:d6:e2:43:95:
+ 5b:37:81:92:81:1f:bb:8d:d7:ad:52:64:16:57:96:d9:5e:34:
+ 7e:c8:35:d8
+-----BEGIN CERTIFICATE-----
+MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG
+EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
+bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
+VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
+h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
+ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
+EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
+DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7
+qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD
+VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov
+L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig
+JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ
+MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+
+3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI
+hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI
+Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X
+Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm
+X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40
+fsg12A==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert3[] = {
+ 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
+ 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x36, 0x5a, 0x17, 0x0d,
+ 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
+ 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+ 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
+ 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
+ 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
+ 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
+ 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
+ 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
+ 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
+ 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
+ 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
+ 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
+ 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
+ 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
+ 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
+ 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
+ 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
+ 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
+ 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
+ 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
+ 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
+ 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
+ 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
+ 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
+ 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
+ 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+ 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
+ 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
+ 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
+ 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
+ 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+ 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
+ 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
+ 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
+ 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
+ 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
+ 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
+ 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+ 0xaa, 0xfa, 0xa9, 0x20, 0xcd, 0x6a, 0x67, 0x83, 0xed, 0x5e, 0xd4, 0x7e,
+ 0xde, 0x1d, 0xc4, 0x7f, 0xe0, 0x25, 0x06, 0x00, 0xc5, 0x24, 0xfb, 0xa9,
+ 0xc8, 0x2d, 0x6d, 0x7e, 0xde, 0x9d, 0x82, 0x65, 0x2c, 0x81, 0x63, 0x34,
+ 0x66, 0x3e, 0xe9, 0x52, 0xc2, 0x08, 0xb4, 0xcb, 0x2f, 0xf7, 0x5f, 0x99,
+ 0x3a, 0x6a, 0x9c, 0x50, 0x7a, 0x85, 0x05, 0x8c, 0x7d, 0xd1, 0x2a, 0x48,
+ 0x84, 0xd3, 0x09, 0x6c, 0x7c, 0xc2, 0xcd, 0x35, 0x9f, 0xf3, 0x82, 0xee,
+ 0x52, 0xde, 0x68, 0x5f, 0xe4, 0x00, 0x8a, 0x17, 0x20, 0x96, 0xf7, 0x29,
+ 0x8d, 0x9a, 0x4d, 0xcb, 0xa8, 0xde, 0x86, 0xc8, 0x0d, 0x6f, 0x56, 0x87,
+ 0x03, 0x7d, 0x03, 0x3f, 0xdc, 0xfa, 0x79, 0x7d, 0x21, 0x19, 0xf9, 0xc8,
+ 0x3a, 0x2f, 0x51, 0x76, 0x8c, 0xc7, 0x41, 0x92, 0x71, 0x8f, 0x25, 0xce,
+ 0x37, 0xf8, 0x4a, 0x4c, 0x00, 0x23, 0xef, 0xc4, 0x35, 0x10, 0xae, 0xe0,
+ 0x23, 0x80, 0x73, 0x7c, 0x4d, 0x34, 0x2e, 0xc8, 0x6e, 0x90, 0xd6, 0x10,
+ 0x1e, 0x99, 0x84, 0x73, 0x1a, 0x70, 0xf2, 0xed, 0x55, 0x0e, 0xee, 0x17,
+ 0x06, 0xea, 0x67, 0xee, 0x32, 0xeb, 0x2c, 0xdd, 0x67, 0x07, 0x3f, 0xf6,
+ 0x8b, 0xc2, 0x70, 0xde, 0x5b, 0x00, 0xe6, 0xbb, 0x1b, 0xd3, 0x36, 0x1a,
+ 0x22, 0x6c, 0x6c, 0xb0, 0x35, 0x42, 0x6c, 0x90, 0x09, 0x3d, 0x93, 0xe9,
+ 0x64, 0x09, 0x22, 0x0e, 0x85, 0x06, 0x9f, 0xc2, 0x73, 0x21, 0xd3, 0xe6,
+ 0x5f, 0x80, 0xe4, 0x8d, 0x85, 0x22, 0x3a, 0x73, 0x03, 0xb1, 0x60, 0x8e,
+ 0xae, 0x68, 0xe2, 0xf4, 0x3e, 0x97, 0xe7, 0x60, 0x12, 0x09, 0x68, 0x36,
+ 0xde, 0x3a, 0xd6, 0xe2, 0x43, 0x95, 0x5b, 0x37, 0x81, 0x92, 0x81, 0x1f,
+ 0xbb, 0x8d, 0xd7, 0xad, 0x52, 0x64, 0x16, 0x57, 0x96, 0xd9, 0x5e, 0x34,
+ 0x7e, 0xc8, 0x35, 0xd8,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 120033005 (0x7278eed)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root
+ Validity
+ Not Before: Apr 18 16:36:18 2012 GMT
+ Not After : Aug 13 16:35:17 2018 GMT
+ Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79:
+ d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a:
+ 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2:
+ 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01:
+ 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7:
+ 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6:
+ 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c:
+ a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70:
+ 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77:
+ d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae:
+ 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18:
+ 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85:
+ ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9:
+ 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5:
+ c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a:
+ ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0:
+ 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27:
+ 1a:39
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:3
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://cybertrust.omniroot.com/repository
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Authority Key Identifier:
+ DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
+ serial:01:A5
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 93:1d:fe:8b:ae:46:ec:cb:a9:0f:ab:e5:ef:ca:b2:68:16:68:
+ d8:8f:fa:13:a9:af:b3:cb:2d:e7:4b:6e:8e:69:2a:c2:2b:10:
+ 0a:8d:f6:ae:73:b6:b9:fb:14:fd:5f:6d:b8:50:b6:c4:8a:d6:
+ 40:7e:d7:c3:cb:73:dc:c9:5d:5b:af:b0:41:b5:37:eb:ea:dc:
+ 20:91:c4:34:6a:f4:a1:f3:96:9d:37:86:97:e1:71:a4:dd:7d:
+ fa:44:84:94:ae:d7:09:04:22:76:0f:64:51:35:a9:24:0f:f9:
+ 0b:db:32:da:c2:fe:c1:b9:2a:5c:7a:27:13:ca:b1:48:3a:71:
+ d0:43
+-----BEGIN CERTIFICATE-----
+MIIEFTCCA36gAwIBAgIEByeO7TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
+cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
+b2JhbCBSb290MB4XDTEyMDQxODE2MzYxOFoXDTE4MDgxMzE2MzUxN1owWjELMAkG
+A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz
+dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO
+KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn
+c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP
+wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg
+kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc
+B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAUcw
+ggFDMBIGA1UdEwEB/wQIMAYBAf8CAQMwSgYDVR0gBEMwQTA/BgRVHSAAMDcwNQYI
+KwYBBQUHAgEWKWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0
+b3J5MA4GA1UdDwEB/wQEAwIBBjCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYT
+AlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJl
+clRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3Qg
+R2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVi
+bGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwDQYJKoZIhvcN
+AQEFBQADgYEAkx3+i65G7MupD6vl78qyaBZo2I/6E6mvs8st50tujmkqwisQCo32
+rnO2ufsU/V9tuFC2xIrWQH7Xw8tz3MldW6+wQbU36+rcIJHENGr0ofOWnTeGl+Fx
+pN19+kSElK7XCQQidg9kUTWpJA/5C9sy2sL+wbkqXHonE8qxSDpx0EM=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert4[] = {
+ 0x30, 0x82, 0x04, 0x15, 0x30, 0x82, 0x03, 0x7e, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x07, 0x27, 0x8e, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f,
+ 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43,
+ 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c,
+ 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x32, 0x30, 0x34, 0x31, 0x38, 0x31, 0x36, 0x33, 0x36, 0x31,
+ 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x33, 0x31, 0x36,
+ 0x33, 0x35, 0x31, 0x37, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69,
+ 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19,
+ 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79,
+ 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
+ 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+ 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x04,
+ 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79,
+ 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e,
+ 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d,
+ 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12,
+ 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88,
+ 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7,
+ 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5,
+ 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab,
+ 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5,
+ 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f,
+ 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77,
+ 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0,
+ 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd,
+ 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0,
+ 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4,
+ 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9,
+ 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c,
+ 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c,
+ 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b,
+ 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76,
+ 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27,
+ 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x47, 0x30,
+ 0x82, 0x01, 0x43, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30,
+ 0x4a, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x43, 0x30, 0x41, 0x30, 0x3f,
+ 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x37, 0x30, 0x35, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
+ 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x81, 0x89, 0x06, 0x03,
+ 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f, 0xa1, 0x79, 0xa4, 0x77,
+ 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65,
+ 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23,
+ 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45,
+ 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x82,
+ 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3e,
+ 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36, 0x86, 0x34, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x70, 0x75, 0x62,
+ 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, 0x2f, 0x43, 0x52,
+ 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63, 0x64, 0x70, 0x2e, 0x63,
+ 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x93, 0x1d, 0xfe,
+ 0x8b, 0xae, 0x46, 0xec, 0xcb, 0xa9, 0x0f, 0xab, 0xe5, 0xef, 0xca, 0xb2,
+ 0x68, 0x16, 0x68, 0xd8, 0x8f, 0xfa, 0x13, 0xa9, 0xaf, 0xb3, 0xcb, 0x2d,
+ 0xe7, 0x4b, 0x6e, 0x8e, 0x69, 0x2a, 0xc2, 0x2b, 0x10, 0x0a, 0x8d, 0xf6,
+ 0xae, 0x73, 0xb6, 0xb9, 0xfb, 0x14, 0xfd, 0x5f, 0x6d, 0xb8, 0x50, 0xb6,
+ 0xc4, 0x8a, 0xd6, 0x40, 0x7e, 0xd7, 0xc3, 0xcb, 0x73, 0xdc, 0xc9, 0x5d,
+ 0x5b, 0xaf, 0xb0, 0x41, 0xb5, 0x37, 0xeb, 0xea, 0xdc, 0x20, 0x91, 0xc4,
+ 0x34, 0x6a, 0xf4, 0xa1, 0xf3, 0x96, 0x9d, 0x37, 0x86, 0x97, 0xe1, 0x71,
+ 0xa4, 0xdd, 0x7d, 0xfa, 0x44, 0x84, 0x94, 0xae, 0xd7, 0x09, 0x04, 0x22,
+ 0x76, 0x0f, 0x64, 0x51, 0x35, 0xa9, 0x24, 0x0f, 0xf9, 0x0b, 0xdb, 0x32,
+ 0xda, 0xc2, 0xfe, 0xc1, 0xb9, 0x2a, 0x5c, 0x7a, 0x27, 0x13, 0xca, 0xb1,
+ 0x48, 0x3a, 0x71, 0xd0, 0x43,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 146041 (0x23a79)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Validity
+ Not Before: Sep 8 20:41:10 2014 GMT
+ Not After : May 20 20:41:10 2022 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G4
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9a:7d:98:68:11:40:c1:5f:72:ec:55:b3:b1:63:
+ f3:32:22:72:91:c6:16:05:bb:08:82:31:b4:f6:ee:
+ d4:18:39:11:2f:2e:da:47:fe:51:31:6e:5b:f2:a9:
+ 0a:eb:2f:bb:f5:61:59:65:57:02:cd:80:ff:c7:70:
+ 32:54:89:fd:db:ae:99:72:d4:4f:0c:26:b9:2e:63:
+ 30:7d:de:14:5b:6a:d7:52:78:21:f9:bf:bc:50:d5:
+ 54:12:59:d8:b5:36:d9:21:47:b8:3f:6a:58:1d:8c:
+ 72:e1:97:95:d3:e1:45:a8:f1:5a:e5:be:fe:e3:53:
+ 7c:a5:f0:52:e0:cf:39:94:0c:19:71:f2:c0:25:07:
+ 48:7d:1c:e6:f1:39:25:2f:98:79:43:e8:18:72:f4:
+ 65:86:98:5a:00:04:47:da:4b:58:1e:7c:86:b1:4b:
+ 35:a6:20:00:1c:cd:1b:3b:22:5d:d1:93:28:33:12:
+ 23:94:08:aa:c3:3a:f5:d1:c6:8c:7e:99:d3:18:a0:
+ ad:9d:18:cf:49:ad:10:03:f7:99:33:26:86:46:9a:
+ 2f:a0:ba:6c:6e:c8:88:02:b7:6e:fa:7a:9e:98:4a:
+ ee:9a:31:7d:19:14:60:0c:ec:8f:20:23:3c:da:97:
+ 26:b6:ea:80:6c:8a:57:9e:20:ee:6f:17:25:4a:32:
+ ad:35
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+
+ X509v3 Subject Key Identifier:
+ AC:32:ED:5A:C9:E0:DE:30:9C:90:58:55:26:63:F6:72:A6:54:5F:E3
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://g.symcb.com/crls/gtglobal.crl
+
+ Authority Information Access:
+ OCSP - URI:http://g.symcd.com
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: http://www.geotrust.com/resources/cps
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 61:40:ad:21:0f:03:bb:95:dc:89:fc:a3:cb:05:71:e9:1c:59:
+ 97:35:c2:fa:6b:05:a4:16:c6:56:46:37:74:1b:1b:f1:3e:2c:
+ e8:37:19:b7:94:d2:0f:0e:c5:bf:14:07:2b:34:cd:5b:b4:8d:
+ c7:56:9d:19:fc:02:b4:9e:90:31:fa:a4:44:c6:75:dd:dd:1f:
+ 25:54:a3:30:4c:ac:db:fe:c4:88:f7:31:26:18:47:ae:4c:20:
+ 19:1a:c7:ae:3e:98:0a:16:3d:d2:c2:a6:5d:0d:2e:29:7d:b2:
+ 9d:c7:41:32:17:ca:9d:ae:39:bf:91:98:de:e7:44:e2:95:9c:
+ 94:5c:6c:42:1b:59:c9:7b:68:13:a8:96:09:74:ee:40:14:a4:
+ d5:d7:c9:7b:33:a3:0f:5a:69:9c:1a:fa:6f:12:47:1c:df:1e:
+ 4c:70:4e:6d:dd:fe:1c:87:b5:9d:e1:54:07:09:8a:cd:be:aa:
+ a8:46:78:6e:16:f2:e7:91:0e:c3:af:da:76:00:d1:d8:a2:46:
+ 24:03:a5:1a:85:81:56:83:63:27:ba:90:8e:f9:62:11:ba:a7:
+ 7c:90:a9:1a:66:b4:c5:bc:8f:29:41:ab:eb:8d:99:a6:cc:91:
+ 64:ba:dc:c6:a6:4c:b3:b4:23:26:51:72:56:f9:f3:74:55:9f:
+ 25:75:4f:2b
+-----BEGIN CERTIFICATE-----
+MIIEIjCCAwqgAwIBAgIDAjp5MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTQwOTA4MjA0MTEwWhcNMjIwNTIwMjA0MTEwWjBEMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
+U1NMIENBIC0gRzQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCafZho
+EUDBX3LsVbOxY/MyInKRxhYFuwiCMbT27tQYOREvLtpH/lExblvyqQrrL7v1YVll
+VwLNgP/HcDJUif3brply1E8MJrkuYzB93hRbatdSeCH5v7xQ1VQSWdi1NtkhR7g/
+algdjHLhl5XT4UWo8Vrlvv7jU3yl8FLgzzmUDBlx8sAlB0h9HObxOSUvmHlD6Bhy
+9GWGmFoABEfaS1gefIaxSzWmIAAczRs7Il3RkygzEiOUCKrDOvXRxox+mdMYoK2d
+GM9JrRAD95kzJoZGmi+gumxuyIgCt276ep6YSu6aMX0ZFGAM7I8gIzzalya26oBs
+ileeIO5vFyVKMq01AgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7qwVk
+DBF9qn1luMrMTjAdBgNVHQ4EFgQUrDLtWsng3jCckFhVJmP2cqZUX+MwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCigJoYk
+aHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUFBwEB
+BCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARFMEMw
+QQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0
+LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQBhQK0hDwO7ldyJ
+/KPLBXHpHFmXNcL6awWkFsZWRjd0GxvxPizoNxm3lNIPDsW/FAcrNM1btI3HVp0Z
+/AK0npAx+qRExnXd3R8lVKMwTKzb/sSI9zEmGEeuTCAZGseuPpgKFj3SwqZdDS4p
+fbKdx0EyF8qdrjm/kZje50TilZyUXGxCG1nJe2gTqJYJdO5AFKTV18l7M6MPWmmc
+GvpvEkcc3x5McE5t3f4ch7Wd4VQHCYrNvqqoRnhuFvLnkQ7Dr9p2ANHYokYkA6Ua
+hYFWg2MnupCO+WIRuqd8kKkaZrTFvI8pQavrjZmmzJFkutzGpkyztCMmUXJW+fN0
+VZ8ldU8r
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert5[] = {
+ 0x30, 0x82, 0x04, 0x22, 0x30, 0x82, 0x03, 0x0a, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
+ 0x39, 0x30, 0x38, 0x32, 0x30, 0x34, 0x31, 0x31, 0x30, 0x5a, 0x17, 0x0d,
+ 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x30, 0x34, 0x31, 0x31, 0x30,
+ 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30,
+ 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+ 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x9a, 0x7d, 0x98, 0x68,
+ 0x11, 0x40, 0xc1, 0x5f, 0x72, 0xec, 0x55, 0xb3, 0xb1, 0x63, 0xf3, 0x32,
+ 0x22, 0x72, 0x91, 0xc6, 0x16, 0x05, 0xbb, 0x08, 0x82, 0x31, 0xb4, 0xf6,
+ 0xee, 0xd4, 0x18, 0x39, 0x11, 0x2f, 0x2e, 0xda, 0x47, 0xfe, 0x51, 0x31,
+ 0x6e, 0x5b, 0xf2, 0xa9, 0x0a, 0xeb, 0x2f, 0xbb, 0xf5, 0x61, 0x59, 0x65,
+ 0x57, 0x02, 0xcd, 0x80, 0xff, 0xc7, 0x70, 0x32, 0x54, 0x89, 0xfd, 0xdb,
+ 0xae, 0x99, 0x72, 0xd4, 0x4f, 0x0c, 0x26, 0xb9, 0x2e, 0x63, 0x30, 0x7d,
+ 0xde, 0x14, 0x5b, 0x6a, 0xd7, 0x52, 0x78, 0x21, 0xf9, 0xbf, 0xbc, 0x50,
+ 0xd5, 0x54, 0x12, 0x59, 0xd8, 0xb5, 0x36, 0xd9, 0x21, 0x47, 0xb8, 0x3f,
+ 0x6a, 0x58, 0x1d, 0x8c, 0x72, 0xe1, 0x97, 0x95, 0xd3, 0xe1, 0x45, 0xa8,
+ 0xf1, 0x5a, 0xe5, 0xbe, 0xfe, 0xe3, 0x53, 0x7c, 0xa5, 0xf0, 0x52, 0xe0,
+ 0xcf, 0x39, 0x94, 0x0c, 0x19, 0x71, 0xf2, 0xc0, 0x25, 0x07, 0x48, 0x7d,
+ 0x1c, 0xe6, 0xf1, 0x39, 0x25, 0x2f, 0x98, 0x79, 0x43, 0xe8, 0x18, 0x72,
+ 0xf4, 0x65, 0x86, 0x98, 0x5a, 0x00, 0x04, 0x47, 0xda, 0x4b, 0x58, 0x1e,
+ 0x7c, 0x86, 0xb1, 0x4b, 0x35, 0xa6, 0x20, 0x00, 0x1c, 0xcd, 0x1b, 0x3b,
+ 0x22, 0x5d, 0xd1, 0x93, 0x28, 0x33, 0x12, 0x23, 0x94, 0x08, 0xaa, 0xc3,
+ 0x3a, 0xf5, 0xd1, 0xc6, 0x8c, 0x7e, 0x99, 0xd3, 0x18, 0xa0, 0xad, 0x9d,
+ 0x18, 0xcf, 0x49, 0xad, 0x10, 0x03, 0xf7, 0x99, 0x33, 0x26, 0x86, 0x46,
+ 0x9a, 0x2f, 0xa0, 0xba, 0x6c, 0x6e, 0xc8, 0x88, 0x02, 0xb7, 0x6e, 0xfa,
+ 0x7a, 0x9e, 0x98, 0x4a, 0xee, 0x9a, 0x31, 0x7d, 0x19, 0x14, 0x60, 0x0c,
+ 0xec, 0x8f, 0x20, 0x23, 0x3c, 0xda, 0x97, 0x26, 0xb6, 0xea, 0x80, 0x6c,
+ 0x8a, 0x57, 0x9e, 0x20, 0xee, 0x6f, 0x17, 0x25, 0x4a, 0x32, 0xad, 0x35,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d, 0x30, 0x82, 0x01,
+ 0x19, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
+ 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
+ 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xac, 0x32, 0xed,
+ 0x5a, 0xc9, 0xe0, 0xde, 0x30, 0x9c, 0x90, 0x58, 0x55, 0x26, 0x63, 0xf6,
+ 0x72, 0xa6, 0x54, 0x5f, 0xe3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+ 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d,
+ 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f,
+ 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c,
+ 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+ 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30,
+ 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07,
+ 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
+ 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x01, 0x00, 0x61, 0x40, 0xad, 0x21, 0x0f, 0x03, 0xbb, 0x95, 0xdc, 0x89,
+ 0xfc, 0xa3, 0xcb, 0x05, 0x71, 0xe9, 0x1c, 0x59, 0x97, 0x35, 0xc2, 0xfa,
+ 0x6b, 0x05, 0xa4, 0x16, 0xc6, 0x56, 0x46, 0x37, 0x74, 0x1b, 0x1b, 0xf1,
+ 0x3e, 0x2c, 0xe8, 0x37, 0x19, 0xb7, 0x94, 0xd2, 0x0f, 0x0e, 0xc5, 0xbf,
+ 0x14, 0x07, 0x2b, 0x34, 0xcd, 0x5b, 0xb4, 0x8d, 0xc7, 0x56, 0x9d, 0x19,
+ 0xfc, 0x02, 0xb4, 0x9e, 0x90, 0x31, 0xfa, 0xa4, 0x44, 0xc6, 0x75, 0xdd,
+ 0xdd, 0x1f, 0x25, 0x54, 0xa3, 0x30, 0x4c, 0xac, 0xdb, 0xfe, 0xc4, 0x88,
+ 0xf7, 0x31, 0x26, 0x18, 0x47, 0xae, 0x4c, 0x20, 0x19, 0x1a, 0xc7, 0xae,
+ 0x3e, 0x98, 0x0a, 0x16, 0x3d, 0xd2, 0xc2, 0xa6, 0x5d, 0x0d, 0x2e, 0x29,
+ 0x7d, 0xb2, 0x9d, 0xc7, 0x41, 0x32, 0x17, 0xca, 0x9d, 0xae, 0x39, 0xbf,
+ 0x91, 0x98, 0xde, 0xe7, 0x44, 0xe2, 0x95, 0x9c, 0x94, 0x5c, 0x6c, 0x42,
+ 0x1b, 0x59, 0xc9, 0x7b, 0x68, 0x13, 0xa8, 0x96, 0x09, 0x74, 0xee, 0x40,
+ 0x14, 0xa4, 0xd5, 0xd7, 0xc9, 0x7b, 0x33, 0xa3, 0x0f, 0x5a, 0x69, 0x9c,
+ 0x1a, 0xfa, 0x6f, 0x12, 0x47, 0x1c, 0xdf, 0x1e, 0x4c, 0x70, 0x4e, 0x6d,
+ 0xdd, 0xfe, 0x1c, 0x87, 0xb5, 0x9d, 0xe1, 0x54, 0x07, 0x09, 0x8a, 0xcd,
+ 0xbe, 0xaa, 0xa8, 0x46, 0x78, 0x6e, 0x16, 0xf2, 0xe7, 0x91, 0x0e, 0xc3,
+ 0xaf, 0xda, 0x76, 0x00, 0xd1, 0xd8, 0xa2, 0x46, 0x24, 0x03, 0xa5, 0x1a,
+ 0x85, 0x81, 0x56, 0x83, 0x63, 0x27, 0xba, 0x90, 0x8e, 0xf9, 0x62, 0x11,
+ 0xba, 0xa7, 0x7c, 0x90, 0xa9, 0x1a, 0x66, 0xb4, 0xc5, 0xbc, 0x8f, 0x29,
+ 0x41, 0xab, 0xeb, 0x8d, 0x99, 0xa6, 0xcc, 0x91, 0x64, 0xba, 0xdc, 0xc6,
+ 0xa6, 0x4c, 0xb3, 0xb4, 0x23, 0x26, 0x51, 0x72, 0x56, 0xf9, 0xf3, 0x74,
+ 0x55, 0x9f, 0x25, 0x75, 0x4f, 0x2b,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 146039 (0x23a77)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Validity
+ Not Before: Aug 29 21:39:32 2014 GMT
+ Not After : May 20 21:39:32 2022 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:af:54:9b:d9:58:5d:1e:2c:56:c6:d5:e8:7f:f4:
+ 7d:16:03:ff:d0:8b:5a:e4:8e:a7:dd:54:2e:d4:04:
+ c0:5d:98:9c:8d:90:0f:bc:10:65:5f:da:9a:d6:44:
+ 7c:c0:9f:b5:e9:4a:8c:0b:06:43:04:bb:f4:96:e2:
+ 26:f6:61:01:91:66:31:22:c3:34:34:5f:3f:3f:91:
+ 2f:44:5f:dc:c7:14:b6:03:9f:86:4b:0e:a3:ff:a0:
+ 80:02:83:c3:d3:1f:69:52:d6:9d:64:0f:c9:83:e7:
+ 1b:c4:70:ac:94:e7:c3:a4:6a:2c:bd:b8:9e:69:d8:
+ be:0a:8f:16:63:5a:68:71:80:7b:30:de:15:04:bf:
+ cc:d3:bf:3e:48:05:55:7a:b3:d7:10:0c:03:fc:9b:
+ fd:08:a7:8c:8c:db:a7:8e:f1:1e:63:dc:b3:01:2f:
+ 7f:af:57:c3:3c:48:a7:83:68:21:a7:2f:e7:a7:3f:
+ f0:b5:0c:fc:f5:84:d1:53:bc:0e:72:4f:60:0c:42:
+ b8:98:ad:19:88:57:d7:04:ec:87:bf:7e:87:4e:a3:
+ 21:f9:53:fd:36:98:48:8d:d6:f8:bb:48:f2:29:c8:
+ 64:d1:cc:54:48:53:8b:af:b7:65:1e:bf:29:33:29:
+ d9:29:60:48:f8:ff:91:bc:57:58:e5:35:2e:bb:69:
+ b6:59
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+
+ X509v3 Subject Key Identifier:
+ C3:9C:F3:FC:D3:46:08:34:BB:CE:46:7F:A0:7C:5B:F3:E2:08:CB:59
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://g.symcb.com/crls/gtglobal.crl
+
+ Authority Information Access:
+ OCSP - URI:http://g.symcd.com
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: http://www.geotrust.com/resources/cps
+
+ Signature Algorithm: sha256WithRSAEncryption
+ a3:58:1e:c6:43:32:ac:ac:2f:93:78:b7:ea:ae:54:40:47:2d:
+ 7e:78:8d:50:f6:f8:66:ac:d6:4f:73:d6:44:ef:af:0b:cc:5b:
+ c1:f4:4f:9a:8f:49:7e:60:af:c2:27:c7:16:f1:fb:93:81:90:
+ a9:7c:ef:6f:7e:6e:45:94:16:84:bd:ec:49:f1:c4:0e:f4:af:
+ 04:59:83:87:0f:2c:3b:97:c3:5a:12:9b:7b:04:35:7b:a3:95:
+ 33:08:7b:93:71:22:42:b3:a9:d9:6f:4f:81:92:fc:07:b6:79:
+ bc:84:4a:9d:77:09:f1:c5:89:f2:f0:b4:9c:54:aa:12:7b:0d:
+ ba:4f:ef:93:19:ec:ef:7d:4e:61:a3:8e:76:9c:59:cf:8c:94:
+ b1:84:97:f7:1a:b9:07:b8:b2:c6:4f:13:79:db:bf:4f:51:1b:
+ 7f:69:0d:51:2a:c1:d6:15:ff:37:51:34:65:51:f4:1e:be:38:
+ 6a:ec:0e:ab:bf:3d:7b:39:05:7b:f4:f3:fb:1a:a1:d0:c8:7e:
+ 4e:64:8d:cd:8c:61:55:90:fe:3a:ca:5d:25:0f:f8:1d:a3:4a:
+ 74:56:4f:1a:55:40:70:75:25:a6:33:2e:ba:4b:a5:5d:53:9a:
+ 0d:30:e1:8d:5f:61:2c:af:cc:ef:b0:99:a1:80:ff:0b:f2:62:
+ 4c:70:26:98
+-----BEGIN CERTIFICATE-----
+MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTQwODI5MjEzOTMyWhcNMjIwNTIwMjEzOTMyWjBHMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXUmFwaWRTU0wg
+U0hBMjU2IENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
+VJvZWF0eLFbG1eh/9H0WA//Qi1rkjqfdVC7UBMBdmJyNkA+8EGVf2prWRHzAn7Xp
+SowLBkMEu/SW4ib2YQGRZjEiwzQ0Xz8/kS9EX9zHFLYDn4ZLDqP/oIACg8PTH2lS
+1p1kD8mD5xvEcKyU58Okaiy9uJ5p2L4KjxZjWmhxgHsw3hUEv8zTvz5IBVV6s9cQ
+DAP8m/0Ip4yM26eO8R5j3LMBL3+vV8M8SKeDaCGnL+enP/C1DPz1hNFTvA5yT2AM
+QriYrRmIV9cE7Ie/fodOoyH5U/02mEiN1vi7SPIpyGTRzFRIU4uvt2UevykzKdkp
+YEj4/5G8V1jlNS67abZZAgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7
+qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUw5zz/NNGCDS7zkZ/oHxb8+IIy1kwEgYD
+VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig
+JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF
+BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARF
+MEMwQQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3Ry
+dXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQCjWB7GQzKs
+rC+TeLfqrlRARy1+eI1Q9vhmrNZPc9ZE768LzFvB9E+aj0l+YK/CJ8cW8fuTgZCp
+fO9vfm5FlBaEvexJ8cQO9K8EWYOHDyw7l8NaEpt7BDV7o5UzCHuTcSJCs6nZb0+B
+kvwHtnm8hEqddwnxxYny8LScVKoSew26T++TGezvfU5ho452nFnPjJSxhJf3GrkH
+uLLGTxN5279PURt/aQ1RKsHWFf83UTRlUfQevjhq7A6rvz17OQV79PP7GqHQyH5O
+ZI3NjGFVkP46yl0lD/gdo0p0Vk8aVUBwdSWmMy66S6VdU5oNMOGNX2Esr8zvsJmh
+gP8L8mJMcCaY
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert6[] = {
+ 0x30, 0x82, 0x04, 0x25, 0x30, 0x82, 0x03, 0x0d, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x77, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
+ 0x38, 0x32, 0x39, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32, 0x5a, 0x17, 0x0d,
+ 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32,
+ 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c, 0x20,
+ 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20,
+ 0x47, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf,
+ 0x54, 0x9b, 0xd9, 0x58, 0x5d, 0x1e, 0x2c, 0x56, 0xc6, 0xd5, 0xe8, 0x7f,
+ 0xf4, 0x7d, 0x16, 0x03, 0xff, 0xd0, 0x8b, 0x5a, 0xe4, 0x8e, 0xa7, 0xdd,
+ 0x54, 0x2e, 0xd4, 0x04, 0xc0, 0x5d, 0x98, 0x9c, 0x8d, 0x90, 0x0f, 0xbc,
+ 0x10, 0x65, 0x5f, 0xda, 0x9a, 0xd6, 0x44, 0x7c, 0xc0, 0x9f, 0xb5, 0xe9,
+ 0x4a, 0x8c, 0x0b, 0x06, 0x43, 0x04, 0xbb, 0xf4, 0x96, 0xe2, 0x26, 0xf6,
+ 0x61, 0x01, 0x91, 0x66, 0x31, 0x22, 0xc3, 0x34, 0x34, 0x5f, 0x3f, 0x3f,
+ 0x91, 0x2f, 0x44, 0x5f, 0xdc, 0xc7, 0x14, 0xb6, 0x03, 0x9f, 0x86, 0x4b,
+ 0x0e, 0xa3, 0xff, 0xa0, 0x80, 0x02, 0x83, 0xc3, 0xd3, 0x1f, 0x69, 0x52,
+ 0xd6, 0x9d, 0x64, 0x0f, 0xc9, 0x83, 0xe7, 0x1b, 0xc4, 0x70, 0xac, 0x94,
+ 0xe7, 0xc3, 0xa4, 0x6a, 0x2c, 0xbd, 0xb8, 0x9e, 0x69, 0xd8, 0xbe, 0x0a,
+ 0x8f, 0x16, 0x63, 0x5a, 0x68, 0x71, 0x80, 0x7b, 0x30, 0xde, 0x15, 0x04,
+ 0xbf, 0xcc, 0xd3, 0xbf, 0x3e, 0x48, 0x05, 0x55, 0x7a, 0xb3, 0xd7, 0x10,
+ 0x0c, 0x03, 0xfc, 0x9b, 0xfd, 0x08, 0xa7, 0x8c, 0x8c, 0xdb, 0xa7, 0x8e,
+ 0xf1, 0x1e, 0x63, 0xdc, 0xb3, 0x01, 0x2f, 0x7f, 0xaf, 0x57, 0xc3, 0x3c,
+ 0x48, 0xa7, 0x83, 0x68, 0x21, 0xa7, 0x2f, 0xe7, 0xa7, 0x3f, 0xf0, 0xb5,
+ 0x0c, 0xfc, 0xf5, 0x84, 0xd1, 0x53, 0xbc, 0x0e, 0x72, 0x4f, 0x60, 0x0c,
+ 0x42, 0xb8, 0x98, 0xad, 0x19, 0x88, 0x57, 0xd7, 0x04, 0xec, 0x87, 0xbf,
+ 0x7e, 0x87, 0x4e, 0xa3, 0x21, 0xf9, 0x53, 0xfd, 0x36, 0x98, 0x48, 0x8d,
+ 0xd6, 0xf8, 0xbb, 0x48, 0xf2, 0x29, 0xc8, 0x64, 0xd1, 0xcc, 0x54, 0x48,
+ 0x53, 0x8b, 0xaf, 0xb7, 0x65, 0x1e, 0xbf, 0x29, 0x33, 0x29, 0xd9, 0x29,
+ 0x60, 0x48, 0xf8, 0xff, 0x91, 0xbc, 0x57, 0x58, 0xe5, 0x35, 0x2e, 0xbb,
+ 0x69, 0xb6, 0x59, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d,
+ 0x30, 0x82, 0x01, 0x19, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
+ 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
+ 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0xc3, 0x9c, 0xf3, 0xfc, 0xd3, 0x46, 0x08, 0x34, 0xbb, 0xce, 0x46, 0x7f,
+ 0xa0, 0x7c, 0x5b, 0xf3, 0xe2, 0x08, 0xcb, 0x59, 0x30, 0x12, 0x06, 0x03,
+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
+ 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
+ 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
+ 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
+ 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45,
+ 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+ 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x58, 0x1e, 0xc6, 0x43, 0x32, 0xac,
+ 0xac, 0x2f, 0x93, 0x78, 0xb7, 0xea, 0xae, 0x54, 0x40, 0x47, 0x2d, 0x7e,
+ 0x78, 0x8d, 0x50, 0xf6, 0xf8, 0x66, 0xac, 0xd6, 0x4f, 0x73, 0xd6, 0x44,
+ 0xef, 0xaf, 0x0b, 0xcc, 0x5b, 0xc1, 0xf4, 0x4f, 0x9a, 0x8f, 0x49, 0x7e,
+ 0x60, 0xaf, 0xc2, 0x27, 0xc7, 0x16, 0xf1, 0xfb, 0x93, 0x81, 0x90, 0xa9,
+ 0x7c, 0xef, 0x6f, 0x7e, 0x6e, 0x45, 0x94, 0x16, 0x84, 0xbd, 0xec, 0x49,
+ 0xf1, 0xc4, 0x0e, 0xf4, 0xaf, 0x04, 0x59, 0x83, 0x87, 0x0f, 0x2c, 0x3b,
+ 0x97, 0xc3, 0x5a, 0x12, 0x9b, 0x7b, 0x04, 0x35, 0x7b, 0xa3, 0x95, 0x33,
+ 0x08, 0x7b, 0x93, 0x71, 0x22, 0x42, 0xb3, 0xa9, 0xd9, 0x6f, 0x4f, 0x81,
+ 0x92, 0xfc, 0x07, 0xb6, 0x79, 0xbc, 0x84, 0x4a, 0x9d, 0x77, 0x09, 0xf1,
+ 0xc5, 0x89, 0xf2, 0xf0, 0xb4, 0x9c, 0x54, 0xaa, 0x12, 0x7b, 0x0d, 0xba,
+ 0x4f, 0xef, 0x93, 0x19, 0xec, 0xef, 0x7d, 0x4e, 0x61, 0xa3, 0x8e, 0x76,
+ 0x9c, 0x59, 0xcf, 0x8c, 0x94, 0xb1, 0x84, 0x97, 0xf7, 0x1a, 0xb9, 0x07,
+ 0xb8, 0xb2, 0xc6, 0x4f, 0x13, 0x79, 0xdb, 0xbf, 0x4f, 0x51, 0x1b, 0x7f,
+ 0x69, 0x0d, 0x51, 0x2a, 0xc1, 0xd6, 0x15, 0xff, 0x37, 0x51, 0x34, 0x65,
+ 0x51, 0xf4, 0x1e, 0xbe, 0x38, 0x6a, 0xec, 0x0e, 0xab, 0xbf, 0x3d, 0x7b,
+ 0x39, 0x05, 0x7b, 0xf4, 0xf3, 0xfb, 0x1a, 0xa1, 0xd0, 0xc8, 0x7e, 0x4e,
+ 0x64, 0x8d, 0xcd, 0x8c, 0x61, 0x55, 0x90, 0xfe, 0x3a, 0xca, 0x5d, 0x25,
+ 0x0f, 0xf8, 0x1d, 0xa3, 0x4a, 0x74, 0x56, 0x4f, 0x1a, 0x55, 0x40, 0x70,
+ 0x75, 0x25, 0xa6, 0x33, 0x2e, 0xba, 0x4b, 0xa5, 0x5d, 0x53, 0x9a, 0x0d,
+ 0x30, 0xe1, 0x8d, 0x5f, 0x61, 0x2c, 0xaf, 0xcc, 0xef, 0xb0, 0x99, 0xa1,
+ 0x80, 0xff, 0x0b, 0xf2, 0x62, 0x4c, 0x70, 0x26, 0x98,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 11:20:96:f6:c8:03:7c:9e:07:b1:38:bf:2e:72:10:8a:d7:ed
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=FR, O=Certplus, CN=Class 2 Primary CA
+ Validity
+ Not Before: Jun 5 00:00:00 2007 GMT
+ Not After : Jun 20 00:00:00 2019 GMT
+ Subject: C=FR, O=KEYNECTIS, CN=CLASS 2 KEYNECTIS CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c6:be:fe:44:23:04:d4:ef:2f:3b:86:aa:35:58:
+ 81:d1:e1:9a:d6:b1:d4:27:45:28:fc:d1:1e:46:85:
+ ba:54:23:11:7d:e0:66:3f:d4:a3:57:66:78:f9:6b:
+ eb:74:7c:2a:b8:37:a5:e8:70:ae:82:b5:4e:d4:81:
+ fe:5b:e2:ea:e7:22:16:f8:f9:d7:ba:3a:f6:88:56:
+ dc:c4:f2:a0:a4:e5:75:06:60:72:2b:fb:f5:94:ee:
+ 2c:83:28:de:91:9a:b3:83:3a:b0:9f:08:fa:dd:d8:
+ 9e:8c:24:e6:df:66:5b:c8:7e:a3:62:4d:3f:3a:85:
+ 23:ec:e8:71:8f:0a:00:ac:89:6d:7e:d8:72:e5:dd:
+ c1:94:8e:5f:e4:73:e6:c1:c6:0c:87:58:4f:37:da:
+ d1:a9:88:26:76:b4:ee:11:8d:f6:ad:b2:a7:bc:73:
+ c4:cd:1c:6e:1a:e6:8d:72:56:44:a0:98:f7:92:f9:
+ d7:79:9b:03:e6:68:5f:a4:5c:7c:3d:50:b4:83:cc:
+ e5:ac:0d:e1:3e:4f:14:f2:b4:e4:7d:bf:71:a4:c3:
+ 97:73:38:d6:52:7c:c8:a4:b5:ea:e9:b2:54:56:d4:
+ eb:b8:57:3a:40:52:5a:5e:46:27:a3:7b:30:2d:08:
+ 3d:85:1e:9a:f0:32:a8:f2:10:a2:83:9b:e2:28:f6:
+ 9d:cb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.4.1.22234.2.5.3.3
+ CPS: http://www.keynectis.com/PC
+ Policy: 1.3.6.4.1.22234.2.5.1.3
+ CPS: http://www.keynectis.com/PC
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://www.certplus.com/CRL/class2.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 00:11:41:DF:3B:9D:3B:CB:B8:A2:C1:33:92:A8:81:CC:E5:7D:E7:99
+ X509v3 Authority Key Identifier:
+ keyid:E3:73:2D:DF:CB:0E:28:0C:DE:DD:B3:A4:CA:79:B8:8E:BB:E8:30:89
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 08:88:fe:1f:a2:ca:cd:e2:a0:f1:2e:7c:67:49:fb:dc:94:ac:
+ 7f:41:0d:78:01:ba:31:f7:9b:fb:31:18:77:2f:66:25:94:b8:
+ 6d:16:74:81:f1:c0:ae:67:c6:14:45:7a:01:d1:13:88:fc:e2:
+ 8d:22:1d:bd:1e:0c:c7:a9:7e:d0:c3:97:f6:37:5b:41:5e:67:
+ 94:8e:ab:69:02:17:18:f5:4d:38:c2:49:28:09:6e:5a:9b:a6:
+ 27:db:c0:5f:8f:44:9c:90:65:99:d8:b3:2e:c1:92:ee:1a:9d:
+ 0f:72:45:20:fa:2c:0c:9c:5d:cd:5b:54:41:54:4f:d3:e2:c7:
+ 59:84:3f:17:7b:7d:0e:c2:ef:62:c7:ba:b1:26:6c:83:4e:d3:
+ 19:c5:ff:56:a7:b4:45:3f:7a:9e:fa:d0:39:3e:80:46:75:5d:
+ 5a:79:7a:33:c5:01:bc:02:44:ce:1b:c0:31:4e:47:96:15:6e:
+ e7:e4:76:f0:c2:90:0d:a1:78:f4:38:00:91:2b:65:7c:79:13:
+ a8:3e:91:14:dc:88:05:08:d7:6f:53:f6:15:43:ee:c5:53:56:
+ 1a:02:b5:a6:a2:46:8d:1e:13:e4:67:c2:45:5f:40:5e:10:42:
+ 58:b5:cd:44:a3:94:4c:1c:54:90:4d:91:9a:26:8b:ad:a2:80:
+ 50:8d:14:14
+-----BEGIN CERTIFICATE-----
+MIIEKzCCAxOgAwIBAgISESCW9sgDfJ4HsTi/LnIQitftMA0GCSqGSIb3DQEBBQUA
+MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xh
+c3MgMiBQcmltYXJ5IENBMB4XDTA3MDYwNTAwMDAwMFoXDTE5MDYyMDAwMDAwMFow
+QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoTCUtFWU5FQ1RJUzEdMBsGA1UEAxMUQ0xB
+U1MgMiBLRVlORUNUSVMgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDGvv5EIwTU7y87hqo1WIHR4ZrWsdQnRSj80R5GhbpUIxF94GY/1KNXZnj5a+t0
+fCq4N6XocK6CtU7Ugf5b4urnIhb4+de6OvaIVtzE8qCk5XUGYHIr+/WU7iyDKN6R
+mrODOrCfCPrd2J6MJObfZlvIfqNiTT86hSPs6HGPCgCsiW1+2HLl3cGUjl/kc+bB
+xgyHWE832tGpiCZ2tO4Rjfatsqe8c8TNHG4a5o1yVkSgmPeS+dd5mwPmaF+kXHw9
+ULSDzOWsDeE+TxTytOR9v3Gkw5dzONZSfMikterpslRW1Ou4VzpAUlpeRiejezAt
+CD2FHprwMqjyEKKDm+Io9p3LAgMBAAGjggEgMIIBHDASBgNVHRMBAf8ECDAGAQH/
+AgEAMH0GA1UdIAR2MHQwOAYLKwYEAYGtWgIFAwMwKTAnBggrBgEFBQcCARYbaHR0
+cDovL3d3dy5rZXluZWN0aXMuY29tL1BDMDgGCysGBAGBrVoCBQEDMCkwJwYIKwYB
+BQUHAgEWG2h0dHA6Ly93d3cua2V5bmVjdGlzLmNvbS9QQzA3BgNVHR8EMDAuMCyg
+KqAohiZodHRwOi8vd3d3LmNlcnRwbHVzLmNvbS9DUkwvY2xhc3MyLmNybDAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAARQd87nTvLuKLBM5KogczlfeeZMB8GA1Ud
+IwQYMBaAFONzLd/LDigM3t2zpMp5uI676DCJMA0GCSqGSIb3DQEBBQUAA4IBAQAI
+iP4fosrN4qDxLnxnSfvclKx/QQ14Abox95v7MRh3L2YllLhtFnSB8cCuZ8YURXoB
+0ROI/OKNIh29HgzHqX7Qw5f2N1tBXmeUjqtpAhcY9U04wkkoCW5am6Yn28Bfj0Sc
+kGWZ2LMuwZLuGp0PckUg+iwMnF3NW1RBVE/T4sdZhD8Xe30Owu9ix7qxJmyDTtMZ
+xf9Wp7RFP3qe+tA5PoBGdV1aeXozxQG8AkTOG8AxTkeWFW7n5HbwwpANoXj0OACR
+K2V8eROoPpEU3IgFCNdvU/YVQ+7FU1YaArWmokaNHhPkZ8JFX0BeEEJYtc1Eo5RM
+HFSQTZGaJoutooBQjRQU
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert7[] = {
+ 0x30, 0x82, 0x04, 0x2b, 0x30, 0x82, 0x03, 0x13, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x12, 0x11, 0x20, 0x96, 0xf6, 0xc8, 0x03, 0x7c, 0x9e, 0x07,
+ 0xb1, 0x38, 0xbf, 0x2e, 0x72, 0x10, 0x8a, 0xd7, 0xed, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+ 0x30, 0x3d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x46, 0x52, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x08, 0x43, 0x65, 0x72, 0x74, 0x70, 0x6c, 0x75, 0x73, 0x31, 0x1b,
+ 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x43, 0x6c, 0x61,
+ 0x73, 0x73, 0x20, 0x32, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
+ 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x30,
+ 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39,
+ 0x30, 0x36, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
+ 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x09, 0x4b, 0x45, 0x59, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x53, 0x31, 0x1d,
+ 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x43, 0x4c, 0x41,
+ 0x53, 0x53, 0x20, 0x32, 0x20, 0x4b, 0x45, 0x59, 0x4e, 0x45, 0x43, 0x54,
+ 0x49, 0x53, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+ 0x01, 0x00, 0xc6, 0xbe, 0xfe, 0x44, 0x23, 0x04, 0xd4, 0xef, 0x2f, 0x3b,
+ 0x86, 0xaa, 0x35, 0x58, 0x81, 0xd1, 0xe1, 0x9a, 0xd6, 0xb1, 0xd4, 0x27,
+ 0x45, 0x28, 0xfc, 0xd1, 0x1e, 0x46, 0x85, 0xba, 0x54, 0x23, 0x11, 0x7d,
+ 0xe0, 0x66, 0x3f, 0xd4, 0xa3, 0x57, 0x66, 0x78, 0xf9, 0x6b, 0xeb, 0x74,
+ 0x7c, 0x2a, 0xb8, 0x37, 0xa5, 0xe8, 0x70, 0xae, 0x82, 0xb5, 0x4e, 0xd4,
+ 0x81, 0xfe, 0x5b, 0xe2, 0xea, 0xe7, 0x22, 0x16, 0xf8, 0xf9, 0xd7, 0xba,
+ 0x3a, 0xf6, 0x88, 0x56, 0xdc, 0xc4, 0xf2, 0xa0, 0xa4, 0xe5, 0x75, 0x06,
+ 0x60, 0x72, 0x2b, 0xfb, 0xf5, 0x94, 0xee, 0x2c, 0x83, 0x28, 0xde, 0x91,
+ 0x9a, 0xb3, 0x83, 0x3a, 0xb0, 0x9f, 0x08, 0xfa, 0xdd, 0xd8, 0x9e, 0x8c,
+ 0x24, 0xe6, 0xdf, 0x66, 0x5b, 0xc8, 0x7e, 0xa3, 0x62, 0x4d, 0x3f, 0x3a,
+ 0x85, 0x23, 0xec, 0xe8, 0x71, 0x8f, 0x0a, 0x00, 0xac, 0x89, 0x6d, 0x7e,
+ 0xd8, 0x72, 0xe5, 0xdd, 0xc1, 0x94, 0x8e, 0x5f, 0xe4, 0x73, 0xe6, 0xc1,
+ 0xc6, 0x0c, 0x87, 0x58, 0x4f, 0x37, 0xda, 0xd1, 0xa9, 0x88, 0x26, 0x76,
+ 0xb4, 0xee, 0x11, 0x8d, 0xf6, 0xad, 0xb2, 0xa7, 0xbc, 0x73, 0xc4, 0xcd,
+ 0x1c, 0x6e, 0x1a, 0xe6, 0x8d, 0x72, 0x56, 0x44, 0xa0, 0x98, 0xf7, 0x92,
+ 0xf9, 0xd7, 0x79, 0x9b, 0x03, 0xe6, 0x68, 0x5f, 0xa4, 0x5c, 0x7c, 0x3d,
+ 0x50, 0xb4, 0x83, 0xcc, 0xe5, 0xac, 0x0d, 0xe1, 0x3e, 0x4f, 0x14, 0xf2,
+ 0xb4, 0xe4, 0x7d, 0xbf, 0x71, 0xa4, 0xc3, 0x97, 0x73, 0x38, 0xd6, 0x52,
+ 0x7c, 0xc8, 0xa4, 0xb5, 0xea, 0xe9, 0xb2, 0x54, 0x56, 0xd4, 0xeb, 0xb8,
+ 0x57, 0x3a, 0x40, 0x52, 0x5a, 0x5e, 0x46, 0x27, 0xa3, 0x7b, 0x30, 0x2d,
+ 0x08, 0x3d, 0x85, 0x1e, 0x9a, 0xf0, 0x32, 0xa8, 0xf2, 0x10, 0xa2, 0x83,
+ 0x9b, 0xe2, 0x28, 0xf6, 0x9d, 0xcb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+ 0x82, 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x12, 0x06, 0x03, 0x55,
+ 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+ 0x02, 0x01, 0x00, 0x30, 0x7d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x76,
+ 0x30, 0x74, 0x30, 0x38, 0x06, 0x0b, 0x2b, 0x06, 0x04, 0x01, 0x81, 0xad,
+ 0x5a, 0x02, 0x05, 0x03, 0x03, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1b, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6b, 0x65, 0x79, 0x6e,
+ 0x65, 0x63, 0x74, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x43,
+ 0x30, 0x38, 0x06, 0x0b, 0x2b, 0x06, 0x04, 0x01, 0x81, 0xad, 0x5a, 0x02,
+ 0x05, 0x01, 0x03, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6b, 0x65, 0x79, 0x6e, 0x65, 0x63,
+ 0x74, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x43, 0x30, 0x37,
+ 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30, 0x30, 0x2e, 0x30, 0x2c, 0xa0,
+ 0x2a, 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x77, 0x77, 0x77, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x70, 0x6c, 0x75, 0x73,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x63, 0x6c, 0x61,
+ 0x73, 0x73, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x00, 0x11,
+ 0x41, 0xdf, 0x3b, 0x9d, 0x3b, 0xcb, 0xb8, 0xa2, 0xc1, 0x33, 0x92, 0xa8,
+ 0x81, 0xcc, 0xe5, 0x7d, 0xe7, 0x99, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe3, 0x73, 0x2d, 0xdf, 0xcb,
+ 0x0e, 0x28, 0x0c, 0xde, 0xdd, 0xb3, 0xa4, 0xca, 0x79, 0xb8, 0x8e, 0xbb,
+ 0xe8, 0x30, 0x89, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08,
+ 0x88, 0xfe, 0x1f, 0xa2, 0xca, 0xcd, 0xe2, 0xa0, 0xf1, 0x2e, 0x7c, 0x67,
+ 0x49, 0xfb, 0xdc, 0x94, 0xac, 0x7f, 0x41, 0x0d, 0x78, 0x01, 0xba, 0x31,
+ 0xf7, 0x9b, 0xfb, 0x31, 0x18, 0x77, 0x2f, 0x66, 0x25, 0x94, 0xb8, 0x6d,
+ 0x16, 0x74, 0x81, 0xf1, 0xc0, 0xae, 0x67, 0xc6, 0x14, 0x45, 0x7a, 0x01,
+ 0xd1, 0x13, 0x88, 0xfc, 0xe2, 0x8d, 0x22, 0x1d, 0xbd, 0x1e, 0x0c, 0xc7,
+ 0xa9, 0x7e, 0xd0, 0xc3, 0x97, 0xf6, 0x37, 0x5b, 0x41, 0x5e, 0x67, 0x94,
+ 0x8e, 0xab, 0x69, 0x02, 0x17, 0x18, 0xf5, 0x4d, 0x38, 0xc2, 0x49, 0x28,
+ 0x09, 0x6e, 0x5a, 0x9b, 0xa6, 0x27, 0xdb, 0xc0, 0x5f, 0x8f, 0x44, 0x9c,
+ 0x90, 0x65, 0x99, 0xd8, 0xb3, 0x2e, 0xc1, 0x92, 0xee, 0x1a, 0x9d, 0x0f,
+ 0x72, 0x45, 0x20, 0xfa, 0x2c, 0x0c, 0x9c, 0x5d, 0xcd, 0x5b, 0x54, 0x41,
+ 0x54, 0x4f, 0xd3, 0xe2, 0xc7, 0x59, 0x84, 0x3f, 0x17, 0x7b, 0x7d, 0x0e,
+ 0xc2, 0xef, 0x62, 0xc7, 0xba, 0xb1, 0x26, 0x6c, 0x83, 0x4e, 0xd3, 0x19,
+ 0xc5, 0xff, 0x56, 0xa7, 0xb4, 0x45, 0x3f, 0x7a, 0x9e, 0xfa, 0xd0, 0x39,
+ 0x3e, 0x80, 0x46, 0x75, 0x5d, 0x5a, 0x79, 0x7a, 0x33, 0xc5, 0x01, 0xbc,
+ 0x02, 0x44, 0xce, 0x1b, 0xc0, 0x31, 0x4e, 0x47, 0x96, 0x15, 0x6e, 0xe7,
+ 0xe4, 0x76, 0xf0, 0xc2, 0x90, 0x0d, 0xa1, 0x78, 0xf4, 0x38, 0x00, 0x91,
+ 0x2b, 0x65, 0x7c, 0x79, 0x13, 0xa8, 0x3e, 0x91, 0x14, 0xdc, 0x88, 0x05,
+ 0x08, 0xd7, 0x6f, 0x53, 0xf6, 0x15, 0x43, 0xee, 0xc5, 0x53, 0x56, 0x1a,
+ 0x02, 0xb5, 0xa6, 0xa2, 0x46, 0x8d, 0x1e, 0x13, 0xe4, 0x67, 0xc2, 0x45,
+ 0x5f, 0x40, 0x5e, 0x10, 0x42, 0x58, 0xb5, 0xcd, 0x44, 0xa3, 0x94, 0x4c,
+ 0x1c, 0x54, 0x90, 0x4d, 0x91, 0x9a, 0x26, 0x8b, 0xad, 0xa2, 0x80, 0x50,
+ 0x8d, 0x14, 0x14,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 120024505 (0x7276db9)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root
+ Validity
+ Not Before: Nov 30 16:35:21 2010 GMT
+ Not After : Aug 10 15:34:26 2018 GMT
+ Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79:
+ d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a:
+ 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2:
+ 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01:
+ 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7:
+ 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6:
+ 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c:
+ a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70:
+ 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77:
+ d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae:
+ 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18:
+ 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85:
+ ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9:
+ 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5:
+ c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a:
+ ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0:
+ 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27:
+ 1a:39
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:3
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://cybertrust.omniroot.com/repository.cfm
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Authority Key Identifier:
+ DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
+ serial:01:A5
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl
+
+ X509v3 Subject Key Identifier:
+ E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
+ Signature Algorithm: sha1WithRSAEncryption
+ 16:b4:2c:c9:f1:5e:e1:a2:7b:9b:78:20:7a:4a:70:70:86:19:
+ 00:b7:05:2a:e8:c9:25:39:0f:c3:64:3c:75:09:d9:89:15:80:
+ 07:c2:8d:bc:29:a5:64:50:cf:71:75:47:23:bd:4d:d8:7f:77:
+ 9a:51:10:6e:4e:1f:20:3c:47:9c:43:74:7f:96:84:10:4c:13:
+ 43:be:f8:e0:72:2e:ff:bf:ae:3c:0a:03:60:82:4b:6f:f9:9a:
+ c5:1e:f6:af:90:3b:9f:61:3b:3e:de:9b:05:1a:c6:2c:3c:57:
+ 21:08:0f:54:fa:28:63:6c:e8:1b:9c:0f:cf:dd:30:44:13:b9:
+ 57:fe
+-----BEGIN CERTIFICATE-----
+MIIEODCCA6GgAwIBAgIEBydtuTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
+cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
+b2JhbCBSb290MB4XDTEwMTEzMDE2MzUyMVoXDTE4MDgxMDE1MzQyNlowWjELMAkG
+A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz
+dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO
+KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn
+c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP
+wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg
+kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc
+B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAWow
+ggFmMBIGA1UdEwEB/wQIMAYBAf8CAQMwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYI
+KwYBBQUHAgEWLWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0
+b3J5LmNmbTAOBgNVHQ8BAf8EBAMCAQYwgYkGA1UdIwSBgTB/oXmkdzB1MQswCQYD
+VQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUg
+Q3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRy
+dXN0IEdsb2JhbCBSb290ggIBpTBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vd3d3
+LnB1YmxpYy10cnVzdC5jb20vY2dpLWJpbi9DUkwvMjAxOC9jZHAuY3JsMB0GA1Ud
+DgQWBBTlnVkwgkdYzKz6CFQ2hns6tQRN8DANBgkqhkiG9w0BAQUFAAOBgQAWtCzJ
+8V7honubeCB6SnBwhhkAtwUq6MklOQ/DZDx1CdmJFYAHwo28KaVkUM9xdUcjvU3Y
+f3eaURBuTh8gPEecQ3R/loQQTBNDvvjgci7/v648CgNggktv+ZrFHvavkDufYTs+
+3psFGsYsPFchCA9U+ihjbOgbnA/P3TBEE7lX/g==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert8[] = {
+ 0x30, 0x82, 0x04, 0x38, 0x30, 0x82, 0x03, 0xa1, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x07, 0x27, 0x6d, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f,
+ 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43,
+ 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c,
+ 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x30, 0x31, 0x31, 0x33, 0x30, 0x31, 0x36, 0x33, 0x35, 0x32,
+ 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x30, 0x31, 0x35,
+ 0x33, 0x34, 0x32, 0x36, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69,
+ 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19,
+ 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79,
+ 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
+ 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+ 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x04,
+ 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79,
+ 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e,
+ 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d,
+ 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12,
+ 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88,
+ 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7,
+ 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5,
+ 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab,
+ 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5,
+ 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f,
+ 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77,
+ 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0,
+ 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd,
+ 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0,
+ 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4,
+ 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9,
+ 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c,
+ 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c,
+ 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b,
+ 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76,
+ 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27,
+ 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x6a, 0x30,
+ 0x82, 0x01, 0x66, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30,
+ 0x4e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43,
+ 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
+ 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
+ 0x81, 0x89, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f,
+ 0xa1, 0x79, 0xa4, 0x77, 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06,
+ 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f,
+ 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30,
+ 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20,
+ 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53,
+ 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
+ 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52,
+ 0x6f, 0x6f, 0x74, 0x82, 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55,
+ 0x1d, 0x1f, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36,
+ 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+ 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69,
+ 0x6e, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63,
+ 0x64, 0x70, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58,
+ 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d,
+ 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x16, 0xb4, 0x2c, 0xc9,
+ 0xf1, 0x5e, 0xe1, 0xa2, 0x7b, 0x9b, 0x78, 0x20, 0x7a, 0x4a, 0x70, 0x70,
+ 0x86, 0x19, 0x00, 0xb7, 0x05, 0x2a, 0xe8, 0xc9, 0x25, 0x39, 0x0f, 0xc3,
+ 0x64, 0x3c, 0x75, 0x09, 0xd9, 0x89, 0x15, 0x80, 0x07, 0xc2, 0x8d, 0xbc,
+ 0x29, 0xa5, 0x64, 0x50, 0xcf, 0x71, 0x75, 0x47, 0x23, 0xbd, 0x4d, 0xd8,
+ 0x7f, 0x77, 0x9a, 0x51, 0x10, 0x6e, 0x4e, 0x1f, 0x20, 0x3c, 0x47, 0x9c,
+ 0x43, 0x74, 0x7f, 0x96, 0x84, 0x10, 0x4c, 0x13, 0x43, 0xbe, 0xf8, 0xe0,
+ 0x72, 0x2e, 0xff, 0xbf, 0xae, 0x3c, 0x0a, 0x03, 0x60, 0x82, 0x4b, 0x6f,
+ 0xf9, 0x9a, 0xc5, 0x1e, 0xf6, 0xaf, 0x90, 0x3b, 0x9f, 0x61, 0x3b, 0x3e,
+ 0xde, 0x9b, 0x05, 0x1a, 0xc6, 0x2c, 0x3c, 0x57, 0x21, 0x08, 0x0f, 0x54,
+ 0xfa, 0x28, 0x63, 0x6c, 0xe8, 0x1b, 0x9c, 0x0f, 0xcf, 0xdd, 0x30, 0x44,
+ 0x13, 0xb9, 0x57, 0xfe,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 146040 (0x23a78)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Validity
+ Not Before: Aug 29 22:24:58 2014 GMT
+ Not After : May 20 22:24:58 2022 GMT
+ Subject: C=US, O=GeoTrust Inc., OU=Domain Validated SSL, CN=GeoTrust DV SSL CA - G4
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:df:41:94:7a:da:f7:e4:31:43:b6:ea:01:1b:5c:
+ ce:63:ea:fa:6d:a3:d9:6a:ee:2d:9a:75:f9:d5:9c:
+ 5b:bd:34:df:d8:1c:c9:6d:d8:04:88:da:6e:b5:b7:
+ b5:f0:30:ae:40:d6:5d:fa:c4:53:c1:d4:22:9d:04:
+ 4e:11:a6:95:d5:45:7c:41:05:58:e0:4c:dd:f9:ee:
+ 55:bd:5f:46:dc:ad:13:08:9d:2c:e4:f7:82:e6:07:
+ 2b:9e:0e:8c:34:a1:ce:c4:a1:e0:81:70:86:00:06:
+ 3f:2d:ea:7c:9b:28:ae:1b:28:8b:39:09:d3:e7:f0:
+ 45:a4:b1:ba:11:67:90:55:7b:8f:de:ed:38:5c:a1:
+ e1:e3:83:c4:c3:72:91:4f:98:ee:1c:c2:80:aa:64:
+ a5:3e:83:62:1c:cc:e0:9e:f8:5a:c0:13:12:7d:a2:
+ a7:8b:a3:e7:9f:2a:d7:9b:ca:cb:ed:97:01:9c:28:
+ 84:51:04:50:41:bc:b4:fc:78:e9:1b:cf:14:ea:1f:
+ 0f:fc:2e:01:32:8d:b6:35:cb:0a:18:3b:ec:5a:3e:
+ 3c:1b:d3:99:43:1e:2f:f7:bd:f3:5b:12:b9:07:5e:
+ ed:3e:d1:a9:87:cc:77:72:27:d4:d9:75:a2:63:4b:
+ 93:36:bd:e5:5c:d7:bf:5f:79:0d:b3:32:a7:0b:b2:
+ 63:23
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+
+ X509v3 Subject Key Identifier:
+ 0B:50:EC:77:EF:2A:9B:FF:EC:03:A1:0A:FF:AD:C6:E4:2A:18:C7:3E
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://g.symcb.com/crls/gtglobal.crl
+
+ Authority Information Access:
+ OCSP - URI:http://g.symcd.com
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: http://www.geotrust.com/resources/cps
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 33:24:d5:90:aa:29:0c:35:b9:2f:c3:c7:42:93:c0:c6:10:4b:
+ 03:08:76:84:10:a2:e0:e7:53:12:27:f2:0a:da:7f:3a:dc:fd:
+ 5c:79:5a:8f:17:74:43:53:b1:d5:d1:5d:59:b9:a6:84:64:ca:
+ f1:3a:0a:59:96:10:bf:a9:81:57:8b:5c:87:dc:7f:e3:e4:bb:
+ 05:7a:a0:32:09:13:4e:10:81:28:1f:9c:03:62:bc:f4:01:b5:
+ 29:83:46:07:b9:e7:b8:5d:c8:e9:d1:dd:ad:3b:f8:34:db:c1:
+ d1:95:a9:91:18:ed:3c:2c:37:11:4d:cc:fe:53:3e:50:43:f9:
+ c3:56:41:ac:53:9b:6c:05:b2:9a:e2:e0:59:57:30:32:b6:26:
+ 4e:13:25:cd:fa:48:70:0f:75:55:60:11:f5:3b:d5:5e:5a:3c:
+ 8b:5b:0f:0f:62:42:48:61:85:8b:10:f4:c1:88:bf:7f:5f:8a:
+ c2:d7:cd:2b:94:5c:1f:34:4a:08:af:eb:ae:89:a8:48:75:55:
+ 95:1d:bb:c0:9a:01:b9:f4:03:22:3e:d4:e6:52:30:0d:67:b9:
+ c0:91:fd:2d:4c:30:8e:bd:8c:a5:04:91:bb:a4:ab:7f:0f:d8:
+ 6f:f0:66:00:c9:a3:5c:f5:b0:8f:83:e6:9c:5a:e6:b6:b9:c5:
+ bc:be:e4:02
+-----BEGIN CERTIFICATE-----
+MIIERDCCAyygAwIBAgIDAjp4MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTQwODI5MjIyNDU4WhcNMjIwNTIwMjIyNDU4WjBmMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh
+bGlkYXRlZCBTU0wxIDAeBgNVBAMTF0dlb1RydXN0IERWIFNTTCBDQSAtIEc0MIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA30GUetr35DFDtuoBG1zOY+r6
+baPZau4tmnX51ZxbvTTf2BzJbdgEiNputbe18DCuQNZd+sRTwdQinQROEaaV1UV8
+QQVY4Ezd+e5VvV9G3K0TCJ0s5PeC5gcrng6MNKHOxKHggXCGAAY/Lep8myiuGyiL
+OQnT5/BFpLG6EWeQVXuP3u04XKHh44PEw3KRT5juHMKAqmSlPoNiHMzgnvhawBMS
+faKni6PnnyrXm8rL7ZcBnCiEUQRQQby0/HjpG88U6h8P/C4BMo22NcsKGDvsWj48
+G9OZQx4v973zWxK5B17tPtGph8x3cifU2XWiY0uTNr3lXNe/X3kNszKnC7JjIwID
+AQABo4IBHTCCARkwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4wHQYD
+VR0OBBYEFAtQ7HfvKpv/7AOhCv+txuQqGMc+MBIGA1UdEwEB/wQIMAYBAf8CAQAw
+DgYDVR0PAQH/BAQDAgEGMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9nLnN5bWNi
+LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAuBggrBgEFBQcBAQQiMCAwHgYIKwYBBQUH
+MAGGEmh0dHA6Ly9nLnN5bWNkLmNvbTBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYw
+MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2Vz
+L2NwczANBgkqhkiG9w0BAQsFAAOCAQEAMyTVkKopDDW5L8PHQpPAxhBLAwh2hBCi
+4OdTEifyCtp/Otz9XHlajxd0Q1Ox1dFdWbmmhGTK8ToKWZYQv6mBV4tch9x/4+S7
+BXqgMgkTThCBKB+cA2K89AG1KYNGB7nnuF3I6dHdrTv4NNvB0ZWpkRjtPCw3EU3M
+/lM+UEP5w1ZBrFObbAWymuLgWVcwMrYmThMlzfpIcA91VWAR9TvVXlo8i1sPD2JC
+SGGFixD0wYi/f1+KwtfNK5RcHzRKCK/rromoSHVVlR27wJoBufQDIj7U5lIwDWe5
+wJH9LUwwjr2MpQSRu6Srfw/Yb/BmAMmjXPWwj4PmnFrmtrnFvL7kAg==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert9[] = {
+ 0x30, 0x82, 0x04, 0x44, 0x30, 0x82, 0x03, 0x2c, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
+ 0x38, 0x32, 0x39, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38, 0x5a, 0x17, 0x0d,
+ 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38,
+ 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x13, 0x14, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61,
+ 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31,
+ 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x47, 0x65,
+ 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x44, 0x56, 0x20, 0x53, 0x53,
+ 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30, 0x82, 0x01,
+ 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+ 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdf, 0x41, 0x94, 0x7a, 0xda, 0xf7,
+ 0xe4, 0x31, 0x43, 0xb6, 0xea, 0x01, 0x1b, 0x5c, 0xce, 0x63, 0xea, 0xfa,
+ 0x6d, 0xa3, 0xd9, 0x6a, 0xee, 0x2d, 0x9a, 0x75, 0xf9, 0xd5, 0x9c, 0x5b,
+ 0xbd, 0x34, 0xdf, 0xd8, 0x1c, 0xc9, 0x6d, 0xd8, 0x04, 0x88, 0xda, 0x6e,
+ 0xb5, 0xb7, 0xb5, 0xf0, 0x30, 0xae, 0x40, 0xd6, 0x5d, 0xfa, 0xc4, 0x53,
+ 0xc1, 0xd4, 0x22, 0x9d, 0x04, 0x4e, 0x11, 0xa6, 0x95, 0xd5, 0x45, 0x7c,
+ 0x41, 0x05, 0x58, 0xe0, 0x4c, 0xdd, 0xf9, 0xee, 0x55, 0xbd, 0x5f, 0x46,
+ 0xdc, 0xad, 0x13, 0x08, 0x9d, 0x2c, 0xe4, 0xf7, 0x82, 0xe6, 0x07, 0x2b,
+ 0x9e, 0x0e, 0x8c, 0x34, 0xa1, 0xce, 0xc4, 0xa1, 0xe0, 0x81, 0x70, 0x86,
+ 0x00, 0x06, 0x3f, 0x2d, 0xea, 0x7c, 0x9b, 0x28, 0xae, 0x1b, 0x28, 0x8b,
+ 0x39, 0x09, 0xd3, 0xe7, 0xf0, 0x45, 0xa4, 0xb1, 0xba, 0x11, 0x67, 0x90,
+ 0x55, 0x7b, 0x8f, 0xde, 0xed, 0x38, 0x5c, 0xa1, 0xe1, 0xe3, 0x83, 0xc4,
+ 0xc3, 0x72, 0x91, 0x4f, 0x98, 0xee, 0x1c, 0xc2, 0x80, 0xaa, 0x64, 0xa5,
+ 0x3e, 0x83, 0x62, 0x1c, 0xcc, 0xe0, 0x9e, 0xf8, 0x5a, 0xc0, 0x13, 0x12,
+ 0x7d, 0xa2, 0xa7, 0x8b, 0xa3, 0xe7, 0x9f, 0x2a, 0xd7, 0x9b, 0xca, 0xcb,
+ 0xed, 0x97, 0x01, 0x9c, 0x28, 0x84, 0x51, 0x04, 0x50, 0x41, 0xbc, 0xb4,
+ 0xfc, 0x78, 0xe9, 0x1b, 0xcf, 0x14, 0xea, 0x1f, 0x0f, 0xfc, 0x2e, 0x01,
+ 0x32, 0x8d, 0xb6, 0x35, 0xcb, 0x0a, 0x18, 0x3b, 0xec, 0x5a, 0x3e, 0x3c,
+ 0x1b, 0xd3, 0x99, 0x43, 0x1e, 0x2f, 0xf7, 0xbd, 0xf3, 0x5b, 0x12, 0xb9,
+ 0x07, 0x5e, 0xed, 0x3e, 0xd1, 0xa9, 0x87, 0xcc, 0x77, 0x72, 0x27, 0xd4,
+ 0xd9, 0x75, 0xa2, 0x63, 0x4b, 0x93, 0x36, 0xbd, 0xe5, 0x5c, 0xd7, 0xbf,
+ 0x5f, 0x79, 0x0d, 0xb3, 0x32, 0xa7, 0x0b, 0xb2, 0x63, 0x23, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11,
+ 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0b, 0x50, 0xec, 0x77, 0xef,
+ 0x2a, 0x9b, 0xff, 0xec, 0x03, 0xa1, 0x0a, 0xff, 0xad, 0xc6, 0xe4, 0x2a,
+ 0x18, 0xc7, 0x3e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
+ 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
+ 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2e,
+ 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74,
+ 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x2e,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22,
+ 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67,
+ 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4c,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06,
+ 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30,
+ 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+ 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+ 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
+ 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+ 0x33, 0x24, 0xd5, 0x90, 0xaa, 0x29, 0x0c, 0x35, 0xb9, 0x2f, 0xc3, 0xc7,
+ 0x42, 0x93, 0xc0, 0xc6, 0x10, 0x4b, 0x03, 0x08, 0x76, 0x84, 0x10, 0xa2,
+ 0xe0, 0xe7, 0x53, 0x12, 0x27, 0xf2, 0x0a, 0xda, 0x7f, 0x3a, 0xdc, 0xfd,
+ 0x5c, 0x79, 0x5a, 0x8f, 0x17, 0x74, 0x43, 0x53, 0xb1, 0xd5, 0xd1, 0x5d,
+ 0x59, 0xb9, 0xa6, 0x84, 0x64, 0xca, 0xf1, 0x3a, 0x0a, 0x59, 0x96, 0x10,
+ 0xbf, 0xa9, 0x81, 0x57, 0x8b, 0x5c, 0x87, 0xdc, 0x7f, 0xe3, 0xe4, 0xbb,
+ 0x05, 0x7a, 0xa0, 0x32, 0x09, 0x13, 0x4e, 0x10, 0x81, 0x28, 0x1f, 0x9c,
+ 0x03, 0x62, 0xbc, 0xf4, 0x01, 0xb5, 0x29, 0x83, 0x46, 0x07, 0xb9, 0xe7,
+ 0xb8, 0x5d, 0xc8, 0xe9, 0xd1, 0xdd, 0xad, 0x3b, 0xf8, 0x34, 0xdb, 0xc1,
+ 0xd1, 0x95, 0xa9, 0x91, 0x18, 0xed, 0x3c, 0x2c, 0x37, 0x11, 0x4d, 0xcc,
+ 0xfe, 0x53, 0x3e, 0x50, 0x43, 0xf9, 0xc3, 0x56, 0x41, 0xac, 0x53, 0x9b,
+ 0x6c, 0x05, 0xb2, 0x9a, 0xe2, 0xe0, 0x59, 0x57, 0x30, 0x32, 0xb6, 0x26,
+ 0x4e, 0x13, 0x25, 0xcd, 0xfa, 0x48, 0x70, 0x0f, 0x75, 0x55, 0x60, 0x11,
+ 0xf5, 0x3b, 0xd5, 0x5e, 0x5a, 0x3c, 0x8b, 0x5b, 0x0f, 0x0f, 0x62, 0x42,
+ 0x48, 0x61, 0x85, 0x8b, 0x10, 0xf4, 0xc1, 0x88, 0xbf, 0x7f, 0x5f, 0x8a,
+ 0xc2, 0xd7, 0xcd, 0x2b, 0x94, 0x5c, 0x1f, 0x34, 0x4a, 0x08, 0xaf, 0xeb,
+ 0xae, 0x89, 0xa8, 0x48, 0x75, 0x55, 0x95, 0x1d, 0xbb, 0xc0, 0x9a, 0x01,
+ 0xb9, 0xf4, 0x03, 0x22, 0x3e, 0xd4, 0xe6, 0x52, 0x30, 0x0d, 0x67, 0xb9,
+ 0xc0, 0x91, 0xfd, 0x2d, 0x4c, 0x30, 0x8e, 0xbd, 0x8c, 0xa5, 0x04, 0x91,
+ 0xbb, 0xa4, 0xab, 0x7f, 0x0f, 0xd8, 0x6f, 0xf0, 0x66, 0x00, 0xc9, 0xa3,
+ 0x5c, 0xf5, 0xb0, 0x8f, 0x83, 0xe6, 0x9c, 0x5a, 0xe6, 0xb6, 0xb9, 0xc5,
+ 0xbc, 0xbe, 0xe4, 0x02,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 33:65:50:08:79:ad:73:e2:30:b9:e0:1d:0d:7f:ac:91
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
+ Validity
+ Not Before: Nov 17 00:00:00 2006 GMT
+ Not After : Dec 30 23:59:59 2020 GMT
+ Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59:
+ 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49:
+ 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c:
+ e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4:
+ 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd:
+ 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a:
+ 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9:
+ fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e:
+ 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22:
+ 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9:
+ 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e:
+ dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6:
+ d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9:
+ 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d:
+ 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50:
+ 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b:
+ 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d:
+ d5:9d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.thawte.com/cps
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.thawte.com/ThawtePremiumServerCA.crl
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 84:a8:4c:c9:3e:2a:bc:9a:e2:cc:8f:0b:b2:25:77:c4:61:89:
+ 89:63:5a:d4:a3:15:40:d4:fb:5e:3f:b4:43:ea:63:17:2b:6b:
+ 99:74:9e:09:a8:dd:d4:56:15:2e:7a:79:31:5f:63:96:53:1b:
+ 34:d9:15:ea:4f:6d:70:ca:be:f6:82:a9:ed:da:85:77:cc:76:
+ 1c:6a:81:0a:21:d8:41:99:7f:5e:2e:82:c1:e8:aa:f7:93:81:
+ 05:aa:92:b4:1f:b7:9a:c0:07:17:f5:cb:c6:b4:4c:0e:d7:56:
+ dc:71:20:74:38:d6:74:c6:d6:8f:6b:af:8b:8d:a0:6c:29:0b:
+ 61:e0
+-----BEGIN CERTIFICATE-----
+MIIERTCCA66gAwIBAgIQM2VQCHmtc+IwueAdDX+skTANBgkqhkiG9w0BAQUFADCB
+zjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ
+Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE
+CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhh
+d3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl
+cnZlckB0aGF3dGUuY29tMB4XDTA2MTExNzAwMDAwMFoXDTIwMTIzMDIzNTk1OVow
+gakxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xKDAmBgNVBAsT
+H0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xODA2BgNVBAsTLyhjKSAy
+MDA2IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD
+VQQDExZ0aGF3dGUgUHJpbWFyeSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEArKDw+4BZ1JzHpM+doVlzCRBFDA0sbmjxbFtIaElZN/wLMxnC
+d3/MEC2VNBzm600JpxzSuMmXNgK3idQkXwbAzESUlI0CYm/rWt0RjSiaXISQEHoN
+vXRmL2o4oOLVVETrHQefB7pv7un9Tgsp9T6EoAHxnKv4HH6JpOih2HFlDaNRe+68
+0iJgDblbnd+6/FFbC6+Ysuku6QToYofeK8jXTsFMZB7dz4dYukpPymgHHRydSsbV
+L5HMfHFyHMXAZ+sy/cmSXJTahcCbv1N9Kwn0jJ2RH5dqUsveCTakd9h7h1BE1T5u
+KWn7OUkmHgmlgHtALevoJ4XJ/mH9fuZ8lx3VnQIDAQABo4HCMIG/MA8GA1UdEwEB
+/wQFMAMBAf8wOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBz
+Oi8vd3d3LnRoYXd0ZS5jb20vY3BzMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
+e1tFz6/Oy3r9MZIaarbzRutXSFAwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cDovL2Ny
+bC50aGF3dGUuY29tL1RoYXd0ZVByZW1pdW1TZXJ2ZXJDQS5jcmwwDQYJKoZIhvcN
+AQEFBQADgYEAhKhMyT4qvJrizI8LsiV3xGGJiWNa1KMVQNT7Xj+0Q+pjFytrmXSe
+Cajd1FYVLnp5MV9jllMbNNkV6k9tcMq+9oKp7dqFd8x2HGqBCiHYQZl/Xi6Cweiq
+95OBBaqStB+3msAHF/XLxrRMDtdW3HEgdDjWdMbWj2uvi42gbCkLYeA=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert10[] = {
+ 0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0xae, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x33, 0x65, 0x50, 0x08, 0x79, 0xad, 0x73, 0xe2, 0x30,
+ 0xb9, 0xe0, 0x1d, 0x0d, 0x7f, 0xac, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+ 0xce, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x5a, 0x41, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+ 0x0c, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x43, 0x61, 0x70,
+ 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09,
+ 0x43, 0x61, 0x70, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x1d, 0x30,
+ 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x54, 0x68, 0x61, 0x77,
+ 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e,
+ 0x67, 0x20, 0x63, 0x63, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x13, 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+ 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x21,
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x54, 0x68, 0x61,
+ 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20,
+ 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x31, 0x28, 0x30,
+ 0x26, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
+ 0x16, 0x19, 0x70, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x2d, 0x73, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x40, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31,
+ 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30,
+ 0x31, 0x32, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
+ 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20,
+ 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36,
+ 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32,
+ 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61,
+ 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73,
+ 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+ 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+ 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xac, 0xa0, 0xf0, 0xfb, 0x80, 0x59, 0xd4, 0x9c, 0xc7, 0xa4, 0xcf, 0x9d,
+ 0xa1, 0x59, 0x73, 0x09, 0x10, 0x45, 0x0c, 0x0d, 0x2c, 0x6e, 0x68, 0xf1,
+ 0x6c, 0x5b, 0x48, 0x68, 0x49, 0x59, 0x37, 0xfc, 0x0b, 0x33, 0x19, 0xc2,
+ 0x77, 0x7f, 0xcc, 0x10, 0x2d, 0x95, 0x34, 0x1c, 0xe6, 0xeb, 0x4d, 0x09,
+ 0xa7, 0x1c, 0xd2, 0xb8, 0xc9, 0x97, 0x36, 0x02, 0xb7, 0x89, 0xd4, 0x24,
+ 0x5f, 0x06, 0xc0, 0xcc, 0x44, 0x94, 0x94, 0x8d, 0x02, 0x62, 0x6f, 0xeb,
+ 0x5a, 0xdd, 0x11, 0x8d, 0x28, 0x9a, 0x5c, 0x84, 0x90, 0x10, 0x7a, 0x0d,
+ 0xbd, 0x74, 0x66, 0x2f, 0x6a, 0x38, 0xa0, 0xe2, 0xd5, 0x54, 0x44, 0xeb,
+ 0x1d, 0x07, 0x9f, 0x07, 0xba, 0x6f, 0xee, 0xe9, 0xfd, 0x4e, 0x0b, 0x29,
+ 0xf5, 0x3e, 0x84, 0xa0, 0x01, 0xf1, 0x9c, 0xab, 0xf8, 0x1c, 0x7e, 0x89,
+ 0xa4, 0xe8, 0xa1, 0xd8, 0x71, 0x65, 0x0d, 0xa3, 0x51, 0x7b, 0xee, 0xbc,
+ 0xd2, 0x22, 0x60, 0x0d, 0xb9, 0x5b, 0x9d, 0xdf, 0xba, 0xfc, 0x51, 0x5b,
+ 0x0b, 0xaf, 0x98, 0xb2, 0xe9, 0x2e, 0xe9, 0x04, 0xe8, 0x62, 0x87, 0xde,
+ 0x2b, 0xc8, 0xd7, 0x4e, 0xc1, 0x4c, 0x64, 0x1e, 0xdd, 0xcf, 0x87, 0x58,
+ 0xba, 0x4a, 0x4f, 0xca, 0x68, 0x07, 0x1d, 0x1c, 0x9d, 0x4a, 0xc6, 0xd5,
+ 0x2f, 0x91, 0xcc, 0x7c, 0x71, 0x72, 0x1c, 0xc5, 0xc0, 0x67, 0xeb, 0x32,
+ 0xfd, 0xc9, 0x92, 0x5c, 0x94, 0xda, 0x85, 0xc0, 0x9b, 0xbf, 0x53, 0x7d,
+ 0x2b, 0x09, 0xf4, 0x8c, 0x9d, 0x91, 0x1f, 0x97, 0x6a, 0x52, 0xcb, 0xde,
+ 0x09, 0x36, 0xa4, 0x77, 0xd8, 0x7b, 0x87, 0x50, 0x44, 0xd5, 0x3e, 0x6e,
+ 0x29, 0x69, 0xfb, 0x39, 0x49, 0x26, 0x1e, 0x09, 0xa5, 0x80, 0x7b, 0x40,
+ 0x2d, 0xeb, 0xe8, 0x27, 0x85, 0xc9, 0xfe, 0x61, 0xfd, 0x7e, 0xe6, 0x7c,
+ 0x97, 0x1d, 0xd5, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc2,
+ 0x30, 0x81, 0xbf, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3b, 0x06, 0x03,
+ 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55,
+ 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73,
+ 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74,
+ 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+ 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a,
+ 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x40, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0,
+ 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x72, 0x65, 0x6d, 0x69,
+ 0x75, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 0x2e, 0x63,
+ 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x84, 0xa8, 0x4c,
+ 0xc9, 0x3e, 0x2a, 0xbc, 0x9a, 0xe2, 0xcc, 0x8f, 0x0b, 0xb2, 0x25, 0x77,
+ 0xc4, 0x61, 0x89, 0x89, 0x63, 0x5a, 0xd4, 0xa3, 0x15, 0x40, 0xd4, 0xfb,
+ 0x5e, 0x3f, 0xb4, 0x43, 0xea, 0x63, 0x17, 0x2b, 0x6b, 0x99, 0x74, 0x9e,
+ 0x09, 0xa8, 0xdd, 0xd4, 0x56, 0x15, 0x2e, 0x7a, 0x79, 0x31, 0x5f, 0x63,
+ 0x96, 0x53, 0x1b, 0x34, 0xd9, 0x15, 0xea, 0x4f, 0x6d, 0x70, 0xca, 0xbe,
+ 0xf6, 0x82, 0xa9, 0xed, 0xda, 0x85, 0x77, 0xcc, 0x76, 0x1c, 0x6a, 0x81,
+ 0x0a, 0x21, 0xd8, 0x41, 0x99, 0x7f, 0x5e, 0x2e, 0x82, 0xc1, 0xe8, 0xaa,
+ 0xf7, 0x93, 0x81, 0x05, 0xaa, 0x92, 0xb4, 0x1f, 0xb7, 0x9a, 0xc0, 0x07,
+ 0x17, 0xf5, 0xcb, 0xc6, 0xb4, 0x4c, 0x0e, 0xd7, 0x56, 0xdc, 0x71, 0x20,
+ 0x74, 0x38, 0xd6, 0x74, 0xc6, 0xd6, 0x8f, 0x6b, 0xaf, 0x8b, 0x8d, 0xa0,
+ 0x6c, 0x29, 0x0b, 0x61, 0xe0,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 04:00:00:00:00:01:44:4e:f0:36:31
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
+ Validity
+ Not Before: Feb 20 10:00:00 2014 GMT
+ Not After : Feb 20 10:00:00 2024 GMT
+ Subject: C=BE, O=GlobalSign nv-sa, CN=AlphaSSL CA - SHA256 - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:da:01:ec:e4:ec:73:60:fb:7e:8f:6a:b7:c6:17:
+ e3:92:64:32:d4:ac:00:d9:a2:0f:b9:ed:ee:6b:8a:
+ 86:ca:92:67:d9:74:d7:5d:47:02:3c:8f:40:d6:9e:
+ 6d:14:cd:c3:da:29:39:a7:0f:05:0a:68:a2:66:1a:
+ 1e:c4:b2:8b:76:58:e5:ab:5d:1d:8f:40:b3:39:8b:
+ ef:1e:83:7d:22:d0:e3:a9:00:2e:ec:53:cf:62:19:
+ 85:44:28:4c:c0:27:cb:7b:0e:ec:10:64:00:10:a4:
+ 05:cc:a0:72:be:41:6c:31:5b:48:e4:b1:ec:b9:23:
+ eb:55:4d:d0:7d:62:4a:a5:b4:a5:a4:59:85:c5:25:
+ 91:a6:fe:a6:09:9f:06:10:6d:8f:81:0c:64:40:5e:
+ 73:00:9a:e0:2e:65:98:54:10:00:70:98:c8:e1:ed:
+ 34:5f:d8:9c:c7:0d:c0:d6:23:59:45:fc:fe:55:7a:
+ 86:ee:94:60:22:f1:ae:d1:e6:55:46:f6:99:c5:1b:
+ 08:74:5f:ac:b0:64:84:8f:89:38:1c:a1:a7:90:21:
+ 4f:02:6e:bd:e0:61:67:d4:f8:42:87:0f:0a:f7:c9:
+ 04:6d:2a:a9:2f:ef:42:a5:df:dd:a3:53:db:98:1e:
+ 81:f9:9a:72:7b:5a:de:4f:3e:7f:a2:58:a0:e2:17:
+ ad:67
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Subject Key Identifier:
+ F5:CD:D5:3C:08:50:F9:6A:4F:3A:B7:97:DA:56:83:E6:69:D2:68:F7
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.alphassl.com/repository/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.globalsign.net/root.crl
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.globalsign.com/rootr1
+
+ X509v3 Authority Key Identifier:
+ keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 60:40:68:16:47:e7:16:8d:db:5c:a1:56:2a:cb:f4:5c:9b:b0:
+ 1e:a2:4b:f5:cb:02:3f:f8:0b:a1:f2:a7:42:d4:b7:4c:eb:e3:
+ 66:80:f3:25:43:78:2e:1b:17:56:07:52:18:cb:d1:a8:ec:e6:
+ fb:73:3e:a4:62:8c:80:b4:d2:c5:12:73:a3:d3:fa:02:38:be:
+ 63:3d:84:b8:99:c1:f1:ba:f7:9f:c3:40:d1:58:18:53:c1:62:
+ dd:af:18:42:7f:34:4e:c5:43:d5:71:b0:30:00:c7:e3:90:ae:
+ 3f:57:86:97:ce:ea:0c:12:8e:22:70:e3:66:a7:54:7f:2e:28:
+ cb:d4:54:d0:b3:1e:62:67:08:f9:27:e1:cb:e3:66:b8:24:1b:
+ 89:6a:89:44:65:f2:d9:4c:d2:58:1c:8c:4e:c0:95:a1:d4:ef:
+ 67:2f:38:20:e8:2e:ff:96:51:f0:ba:d8:3d:92:70:47:65:1c:
+ 9e:73:72:b4:60:0c:5c:e2:d1:73:76:e0:af:4e:e2:e5:37:a5:
+ 45:2f:8a:23:3e:87:c7:30:e6:31:38:7c:f4:dd:52:ca:f3:53:
+ 04:25:57:56:66:94:e8:0b:ee:e6:03:14:4e:ee:fd:6d:94:64:
+ 9e:5e:ce:79:d4:b2:a6:cf:40:b1:44:a8:3e:87:19:5e:e9:f8:
+ 21:16:59:53
+-----BEGIN CERTIFICATE-----
+MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
+MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj
+kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL
+dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs
+MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA
+cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn
+kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het
+ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
+AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE
+VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw
+b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu
+Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6
+Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X
+yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0
+XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS
+xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG
+l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV
+odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm
+MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZ
+Uw==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert11[] = {
+ 0x30, 0x82, 0x04, 0x4d, 0x30, 0x82, 0x03, 0x35, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
+ 0x36, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
+ 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
+ 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
+ 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
+ 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
+ 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
+ 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41,
+ 0x6c, 0x70, 0x68, 0x61, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d,
+ 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32,
+ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0x01, 0xec,
+ 0xe4, 0xec, 0x73, 0x60, 0xfb, 0x7e, 0x8f, 0x6a, 0xb7, 0xc6, 0x17, 0xe3,
+ 0x92, 0x64, 0x32, 0xd4, 0xac, 0x00, 0xd9, 0xa2, 0x0f, 0xb9, 0xed, 0xee,
+ 0x6b, 0x8a, 0x86, 0xca, 0x92, 0x67, 0xd9, 0x74, 0xd7, 0x5d, 0x47, 0x02,
+ 0x3c, 0x8f, 0x40, 0xd6, 0x9e, 0x6d, 0x14, 0xcd, 0xc3, 0xda, 0x29, 0x39,
+ 0xa7, 0x0f, 0x05, 0x0a, 0x68, 0xa2, 0x66, 0x1a, 0x1e, 0xc4, 0xb2, 0x8b,
+ 0x76, 0x58, 0xe5, 0xab, 0x5d, 0x1d, 0x8f, 0x40, 0xb3, 0x39, 0x8b, 0xef,
+ 0x1e, 0x83, 0x7d, 0x22, 0xd0, 0xe3, 0xa9, 0x00, 0x2e, 0xec, 0x53, 0xcf,
+ 0x62, 0x19, 0x85, 0x44, 0x28, 0x4c, 0xc0, 0x27, 0xcb, 0x7b, 0x0e, 0xec,
+ 0x10, 0x64, 0x00, 0x10, 0xa4, 0x05, 0xcc, 0xa0, 0x72, 0xbe, 0x41, 0x6c,
+ 0x31, 0x5b, 0x48, 0xe4, 0xb1, 0xec, 0xb9, 0x23, 0xeb, 0x55, 0x4d, 0xd0,
+ 0x7d, 0x62, 0x4a, 0xa5, 0xb4, 0xa5, 0xa4, 0x59, 0x85, 0xc5, 0x25, 0x91,
+ 0xa6, 0xfe, 0xa6, 0x09, 0x9f, 0x06, 0x10, 0x6d, 0x8f, 0x81, 0x0c, 0x64,
+ 0x40, 0x5e, 0x73, 0x00, 0x9a, 0xe0, 0x2e, 0x65, 0x98, 0x54, 0x10, 0x00,
+ 0x70, 0x98, 0xc8, 0xe1, 0xed, 0x34, 0x5f, 0xd8, 0x9c, 0xc7, 0x0d, 0xc0,
+ 0xd6, 0x23, 0x59, 0x45, 0xfc, 0xfe, 0x55, 0x7a, 0x86, 0xee, 0x94, 0x60,
+ 0x22, 0xf1, 0xae, 0xd1, 0xe6, 0x55, 0x46, 0xf6, 0x99, 0xc5, 0x1b, 0x08,
+ 0x74, 0x5f, 0xac, 0xb0, 0x64, 0x84, 0x8f, 0x89, 0x38, 0x1c, 0xa1, 0xa7,
+ 0x90, 0x21, 0x4f, 0x02, 0x6e, 0xbd, 0xe0, 0x61, 0x67, 0xd4, 0xf8, 0x42,
+ 0x87, 0x0f, 0x0a, 0xf7, 0xc9, 0x04, 0x6d, 0x2a, 0xa9, 0x2f, 0xef, 0x42,
+ 0xa5, 0xdf, 0xdd, 0xa3, 0x53, 0xdb, 0x98, 0x1e, 0x81, 0xf9, 0x9a, 0x72,
+ 0x7b, 0x5a, 0xde, 0x4f, 0x3e, 0x7f, 0xa2, 0x58, 0xa0, 0xe2, 0x17, 0xad,
+ 0x67, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x23, 0x30, 0x82,
+ 0x01, 0x1f, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+ 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
+ 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0xf5, 0xcd, 0xd5, 0x3c, 0x08, 0x50, 0xf9, 0x6a, 0x4f, 0x3a, 0xb7,
+ 0x97, 0xda, 0x56, 0x83, 0xe6, 0x69, 0xd2, 0x68, 0xf7, 0x30, 0x45, 0x06,
+ 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x04,
+ 0x55, 0x1d, 0x20, 0x00, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x24, 0x68, 0x74, 0x74, 0x70,
+ 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x6c, 0x70, 0x68,
+ 0x61, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70,
+ 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0,
+ 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e,
+ 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
+ 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
+ 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61,
+ 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f,
+ 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97,
+ 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd,
+ 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x60, 0x40, 0x68,
+ 0x16, 0x47, 0xe7, 0x16, 0x8d, 0xdb, 0x5c, 0xa1, 0x56, 0x2a, 0xcb, 0xf4,
+ 0x5c, 0x9b, 0xb0, 0x1e, 0xa2, 0x4b, 0xf5, 0xcb, 0x02, 0x3f, 0xf8, 0x0b,
+ 0xa1, 0xf2, 0xa7, 0x42, 0xd4, 0xb7, 0x4c, 0xeb, 0xe3, 0x66, 0x80, 0xf3,
+ 0x25, 0x43, 0x78, 0x2e, 0x1b, 0x17, 0x56, 0x07, 0x52, 0x18, 0xcb, 0xd1,
+ 0xa8, 0xec, 0xe6, 0xfb, 0x73, 0x3e, 0xa4, 0x62, 0x8c, 0x80, 0xb4, 0xd2,
+ 0xc5, 0x12, 0x73, 0xa3, 0xd3, 0xfa, 0x02, 0x38, 0xbe, 0x63, 0x3d, 0x84,
+ 0xb8, 0x99, 0xc1, 0xf1, 0xba, 0xf7, 0x9f, 0xc3, 0x40, 0xd1, 0x58, 0x18,
+ 0x53, 0xc1, 0x62, 0xdd, 0xaf, 0x18, 0x42, 0x7f, 0x34, 0x4e, 0xc5, 0x43,
+ 0xd5, 0x71, 0xb0, 0x30, 0x00, 0xc7, 0xe3, 0x90, 0xae, 0x3f, 0x57, 0x86,
+ 0x97, 0xce, 0xea, 0x0c, 0x12, 0x8e, 0x22, 0x70, 0xe3, 0x66, 0xa7, 0x54,
+ 0x7f, 0x2e, 0x28, 0xcb, 0xd4, 0x54, 0xd0, 0xb3, 0x1e, 0x62, 0x67, 0x08,
+ 0xf9, 0x27, 0xe1, 0xcb, 0xe3, 0x66, 0xb8, 0x24, 0x1b, 0x89, 0x6a, 0x89,
+ 0x44, 0x65, 0xf2, 0xd9, 0x4c, 0xd2, 0x58, 0x1c, 0x8c, 0x4e, 0xc0, 0x95,
+ 0xa1, 0xd4, 0xef, 0x67, 0x2f, 0x38, 0x20, 0xe8, 0x2e, 0xff, 0x96, 0x51,
+ 0xf0, 0xba, 0xd8, 0x3d, 0x92, 0x70, 0x47, 0x65, 0x1c, 0x9e, 0x73, 0x72,
+ 0xb4, 0x60, 0x0c, 0x5c, 0xe2, 0xd1, 0x73, 0x76, 0xe0, 0xaf, 0x4e, 0xe2,
+ 0xe5, 0x37, 0xa5, 0x45, 0x2f, 0x8a, 0x23, 0x3e, 0x87, 0xc7, 0x30, 0xe6,
+ 0x31, 0x38, 0x7c, 0xf4, 0xdd, 0x52, 0xca, 0xf3, 0x53, 0x04, 0x25, 0x57,
+ 0x56, 0x66, 0x94, 0xe8, 0x0b, 0xee, 0xe6, 0x03, 0x14, 0x4e, 0xee, 0xfd,
+ 0x6d, 0x94, 0x64, 0x9e, 0x5e, 0xce, 0x79, 0xd4, 0xb2, 0xa6, 0xcf, 0x40,
+ 0xb1, 0x44, 0xa8, 0x3e, 0x87, 0x19, 0x5e, 0xe9, 0xf8, 0x21, 0x16, 0x59,
+ 0x53,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 146031 (0x23a6f)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Validity
+ Not Before: Nov 5 21:36:50 2013 GMT
+ Not After : May 20 21:36:50 2022 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e3:be:7e:0a:86:a3:cf:6b:6d:3d:2b:a1:97:ad:
+ 49:24:4d:d7:77:b9:34:79:08:a5:9e:a2:9e:de:47:
+ 12:92:3d:7e:ea:19:86:b1:e8:4f:3d:5f:f7:d0:a7:
+ 77:9a:5b:1f:0a:03:b5:19:53:db:a5:21:94:69:63:
+ 9d:6a:4c:91:0c:10:47:be:11:fa:6c:86:25:b7:ab:
+ 04:68:42:38:09:65:f0:14:da:19:9e:fa:6b:0b:ab:
+ 62:ef:8d:a7:ef:63:70:23:a8:af:81:f3:d1:6e:88:
+ 67:53:ec:12:a4:29:75:8a:a7:f2:57:3d:a2:83:98:
+ 97:f2:0a:7d:d4:e7:43:6e:30:78:62:22:59:59:b8:
+ 71:27:45:aa:0f:66:c6:55:3f:fa:32:17:2b:31:8f:
+ 46:a0:fa:69:14:7c:9d:9f:5a:e2:eb:33:4e:10:a6:
+ b3:ed:77:63:d8:c3:9e:f4:dd:df:79:9a:7a:d4:ee:
+ de:dd:9a:cc:c3:b7:a9:5d:cc:11:3a:07:bb:6f:97:
+ a4:01:23:47:95:1f:a3:77:fa:58:92:c6:c7:d0:bd:
+ cf:93:18:42:b7:7e:f7:9e:65:ea:d5:3b:ca:ed:ac:
+ c5:70:a1:fe:d4:10:9a:f0:12:04:44:ac:1a:5b:78:
+ 50:45:57:4c:6f:bd:80:cb:81:5c:2d:b3:bc:76:a1:
+ 1e:65
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+
+ X509v3 Subject Key Identifier:
+ D2:6F:F7:96:F4:85:3F:72:3C:30:7D:23:DA:85:78:9B:A3:7C:5A:7C
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://g1.symcb.com/crls/gtglobal.crl
+
+ Authority Information Access:
+ OCSP - URI:http://g2.symcb.com
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: http://www.geotrust.com/resources/cps
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=SymantecPKI-1-539
+ Signature Algorithm: sha256WithRSAEncryption
+ a0:d4:f7:2c:fb:74:0b:7f:64:f1:cd:43:6a:9f:62:53:1c:02:
+ 7c:98:90:a2:ee:4f:68:d4:20:1a:73:12:3e:77:b3:50:eb:72:
+ bc:ee:88:be:7f:17:ea:77:8f:83:61:95:4f:84:a1:cb:32:4f:
+ 6c:21:be:d2:69:96:7d:63:bd:dc:2b:a8:1f:d0:13:84:70:fe:
+ f6:35:95:89:f9:a6:77:b0:46:c8:bb:b7:13:f5:c9:60:69:d6:
+ 4c:fe:d2:8e:ef:d3:60:c1:80:80:e1:e7:fb:8b:6f:21:79:4a:
+ e0:dc:a9:1b:c1:b7:fb:c3:49:59:5c:b5:77:07:44:d4:97:fc:
+ 49:00:89:6f:06:4e:01:70:19:ac:2f:11:c0:e2:e6:0f:2f:86:
+ 4b:8d:7b:c3:b9:a7:2e:f4:f1:ac:16:3e:39:49:51:9e:17:4b:
+ 4f:10:3a:5b:a5:a8:92:6f:fd:fa:d6:0b:03:4d:47:56:57:19:
+ f3:cb:6b:f5:f3:d6:cf:b0:f5:f5:a3:11:d2:20:53:13:34:37:
+ 05:2c:43:5a:63:df:8d:40:d6:85:1e:51:e9:51:17:1e:03:56:
+ c9:f1:30:ad:e7:9b:11:a2:b9:d0:31:81:9b:68:b1:d9:e8:f3:
+ e6:94:7e:c7:ae:13:2f:87:ed:d0:25:b0:68:f9:de:08:5a:f3:
+ 29:cc:d4:92
+-----BEGIN CERTIFICATE-----
+MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
+U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K
+hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ
+U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B
+89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx
+j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB
+I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv
+vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk
+DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl
+aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB
+AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw
+QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1
+c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5
+bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq
+n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9
+Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg
+3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45
+SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N
+QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp
+zNSS
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert12[] = {
+ 0x30, 0x82, 0x04, 0x4f, 0x30, 0x82, 0x03, 0x37, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x6f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31,
+ 0x31, 0x30, 0x35, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30, 0x5a, 0x17, 0x0d,
+ 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30,
+ 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30,
+ 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+ 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe3, 0xbe, 0x7e, 0x0a,
+ 0x86, 0xa3, 0xcf, 0x6b, 0x6d, 0x3d, 0x2b, 0xa1, 0x97, 0xad, 0x49, 0x24,
+ 0x4d, 0xd7, 0x77, 0xb9, 0x34, 0x79, 0x08, 0xa5, 0x9e, 0xa2, 0x9e, 0xde,
+ 0x47, 0x12, 0x92, 0x3d, 0x7e, 0xea, 0x19, 0x86, 0xb1, 0xe8, 0x4f, 0x3d,
+ 0x5f, 0xf7, 0xd0, 0xa7, 0x77, 0x9a, 0x5b, 0x1f, 0x0a, 0x03, 0xb5, 0x19,
+ 0x53, 0xdb, 0xa5, 0x21, 0x94, 0x69, 0x63, 0x9d, 0x6a, 0x4c, 0x91, 0x0c,
+ 0x10, 0x47, 0xbe, 0x11, 0xfa, 0x6c, 0x86, 0x25, 0xb7, 0xab, 0x04, 0x68,
+ 0x42, 0x38, 0x09, 0x65, 0xf0, 0x14, 0xda, 0x19, 0x9e, 0xfa, 0x6b, 0x0b,
+ 0xab, 0x62, 0xef, 0x8d, 0xa7, 0xef, 0x63, 0x70, 0x23, 0xa8, 0xaf, 0x81,
+ 0xf3, 0xd1, 0x6e, 0x88, 0x67, 0x53, 0xec, 0x12, 0xa4, 0x29, 0x75, 0x8a,
+ 0xa7, 0xf2, 0x57, 0x3d, 0xa2, 0x83, 0x98, 0x97, 0xf2, 0x0a, 0x7d, 0xd4,
+ 0xe7, 0x43, 0x6e, 0x30, 0x78, 0x62, 0x22, 0x59, 0x59, 0xb8, 0x71, 0x27,
+ 0x45, 0xaa, 0x0f, 0x66, 0xc6, 0x55, 0x3f, 0xfa, 0x32, 0x17, 0x2b, 0x31,
+ 0x8f, 0x46, 0xa0, 0xfa, 0x69, 0x14, 0x7c, 0x9d, 0x9f, 0x5a, 0xe2, 0xeb,
+ 0x33, 0x4e, 0x10, 0xa6, 0xb3, 0xed, 0x77, 0x63, 0xd8, 0xc3, 0x9e, 0xf4,
+ 0xdd, 0xdf, 0x79, 0x9a, 0x7a, 0xd4, 0xee, 0xde, 0xdd, 0x9a, 0xcc, 0xc3,
+ 0xb7, 0xa9, 0x5d, 0xcc, 0x11, 0x3a, 0x07, 0xbb, 0x6f, 0x97, 0xa4, 0x01,
+ 0x23, 0x47, 0x95, 0x1f, 0xa3, 0x77, 0xfa, 0x58, 0x92, 0xc6, 0xc7, 0xd0,
+ 0xbd, 0xcf, 0x93, 0x18, 0x42, 0xb7, 0x7e, 0xf7, 0x9e, 0x65, 0xea, 0xd5,
+ 0x3b, 0xca, 0xed, 0xac, 0xc5, 0x70, 0xa1, 0xfe, 0xd4, 0x10, 0x9a, 0xf0,
+ 0x12, 0x04, 0x44, 0xac, 0x1a, 0x5b, 0x78, 0x50, 0x45, 0x57, 0x4c, 0x6f,
+ 0xbd, 0x80, 0xcb, 0x81, 0x5c, 0x2d, 0xb3, 0xbc, 0x76, 0xa1, 0x1e, 0x65,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4a, 0x30, 0x82, 0x01,
+ 0x46, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
+ 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
+ 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd2, 0x6f, 0xf7,
+ 0x96, 0xf4, 0x85, 0x3f, 0x72, 0x3c, 0x30, 0x7d, 0x23, 0xda, 0x85, 0x78,
+ 0x9b, 0xa3, 0x7c, 0x5a, 0x7c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+ 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79,
+ 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73,
+ 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72,
+ 0x6c, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
+ 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30,
+ 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45,
+ 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75,
+ 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03,
+ 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
+ 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79,
+ 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d,
+ 0x35, 0x33, 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa0,
+ 0xd4, 0xf7, 0x2c, 0xfb, 0x74, 0x0b, 0x7f, 0x64, 0xf1, 0xcd, 0x43, 0x6a,
+ 0x9f, 0x62, 0x53, 0x1c, 0x02, 0x7c, 0x98, 0x90, 0xa2, 0xee, 0x4f, 0x68,
+ 0xd4, 0x20, 0x1a, 0x73, 0x12, 0x3e, 0x77, 0xb3, 0x50, 0xeb, 0x72, 0xbc,
+ 0xee, 0x88, 0xbe, 0x7f, 0x17, 0xea, 0x77, 0x8f, 0x83, 0x61, 0x95, 0x4f,
+ 0x84, 0xa1, 0xcb, 0x32, 0x4f, 0x6c, 0x21, 0xbe, 0xd2, 0x69, 0x96, 0x7d,
+ 0x63, 0xbd, 0xdc, 0x2b, 0xa8, 0x1f, 0xd0, 0x13, 0x84, 0x70, 0xfe, 0xf6,
+ 0x35, 0x95, 0x89, 0xf9, 0xa6, 0x77, 0xb0, 0x46, 0xc8, 0xbb, 0xb7, 0x13,
+ 0xf5, 0xc9, 0x60, 0x69, 0xd6, 0x4c, 0xfe, 0xd2, 0x8e, 0xef, 0xd3, 0x60,
+ 0xc1, 0x80, 0x80, 0xe1, 0xe7, 0xfb, 0x8b, 0x6f, 0x21, 0x79, 0x4a, 0xe0,
+ 0xdc, 0xa9, 0x1b, 0xc1, 0xb7, 0xfb, 0xc3, 0x49, 0x59, 0x5c, 0xb5, 0x77,
+ 0x07, 0x44, 0xd4, 0x97, 0xfc, 0x49, 0x00, 0x89, 0x6f, 0x06, 0x4e, 0x01,
+ 0x70, 0x19, 0xac, 0x2f, 0x11, 0xc0, 0xe2, 0xe6, 0x0f, 0x2f, 0x86, 0x4b,
+ 0x8d, 0x7b, 0xc3, 0xb9, 0xa7, 0x2e, 0xf4, 0xf1, 0xac, 0x16, 0x3e, 0x39,
+ 0x49, 0x51, 0x9e, 0x17, 0x4b, 0x4f, 0x10, 0x3a, 0x5b, 0xa5, 0xa8, 0x92,
+ 0x6f, 0xfd, 0xfa, 0xd6, 0x0b, 0x03, 0x4d, 0x47, 0x56, 0x57, 0x19, 0xf3,
+ 0xcb, 0x6b, 0xf5, 0xf3, 0xd6, 0xcf, 0xb0, 0xf5, 0xf5, 0xa3, 0x11, 0xd2,
+ 0x20, 0x53, 0x13, 0x34, 0x37, 0x05, 0x2c, 0x43, 0x5a, 0x63, 0xdf, 0x8d,
+ 0x40, 0xd6, 0x85, 0x1e, 0x51, 0xe9, 0x51, 0x17, 0x1e, 0x03, 0x56, 0xc9,
+ 0xf1, 0x30, 0xad, 0xe7, 0x9b, 0x11, 0xa2, 0xb9, 0xd0, 0x31, 0x81, 0x9b,
+ 0x68, 0xb1, 0xd9, 0xe8, 0xf3, 0xe6, 0x94, 0x7e, 0xc7, 0xae, 0x13, 0x2f,
+ 0x87, 0xed, 0xd0, 0x25, 0xb0, 0x68, 0xf9, 0xde, 0x08, 0x5a, 0xf3, 0x29,
+ 0xcc, 0xd4, 0x92,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 146019 (0x23a63)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
+ Validity
+ Not Before: Aug 27 20:40:40 2012 GMT
+ Not After : May 20 20:40:40 2022 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b9:27:f9:4f:d8:f6:b7:15:3f:8f:cd:ce:d6:8d:
+ 1c:6b:fd:7f:da:54:21:4e:03:d8:ca:d0:72:52:15:
+ b8:c9:82:5b:58:79:84:ff:24:72:6f:f2:69:7f:bc:
+ 96:d9:9a:7a:c3:3e:a9:cf:50:22:13:0e:86:19:db:
+ e8:49:ef:8b:e6:d6:47:f2:fd:73:45:08:ae:8f:ac:
+ 5e:b6:f8:9e:7c:f7:10:ff:92:43:66:ef:1c:d4:ee:
+ a1:46:88:11:89:49:79:7a:25:ce:4b:6a:f0:d7:1c:
+ 76:1a:29:3c:c9:e4:fd:1e:85:dc:e0:31:65:05:47:
+ 16:ac:0a:07:4b:2e:70:5e:6b:06:a7:6b:3a:6c:af:
+ 05:12:c4:b2:11:25:d6:3e:97:29:f0:83:6c:57:1c:
+ d8:a5:ef:cc:ec:fd:d6:12:f1:3f:db:40:b4:ae:0f:
+ 18:d3:c5:af:40:92:5d:07:5e:4e:fe:62:17:37:89:
+ e9:8b:74:26:a2:ed:b8:0a:e7:6c:15:5b:35:90:72:
+ dd:d8:4d:21:d4:40:23:5c:8f:ee:80:31:16:ab:68:
+ 55:f4:0e:3b:54:e9:04:4d:f0:cc:4e:81:5e:e9:6f:
+ 52:69:4e:be:a6:16:6d:42:f5:51:ff:e0:0b:56:3c:
+ 98:4f:73:8f:0e:6f:1a:23:f1:c9:c8:d9:df:bc:ec:
+ 52:d7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
+
+ X509v3 Subject Key Identifier:
+ 11:4A:D0:73:39:D5:5B:69:08:5C:BA:3D:BF:64:9A:A8:8B:1C:55:BC
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.geotrust.com/crls/gtglobal.crl
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.geotrust.com
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: http://www.geotrust.com/resources/cps
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=VeriSignMPKI-2-254
+ Signature Algorithm: sha1WithRSAEncryption
+ 3c:e5:3d:5a:1b:a2:37:2a:e3:46:cf:36:96:18:3c:7b:f1:84:
+ c5:57:86:77:40:9d:35:f0:12:f0:78:18:fb:22:a4:de:98:4b:
+ 78:81:e6:4d:86:e3:91:0f:42:e3:b9:dc:a0:d6:ff:a9:f8:b1:
+ 79:97:99:d1:c3:6c:42:a5:92:94:e0:5d:0c:33:18:25:c9:2b:
+ 95:53:e0:e5:a9:0c:7d:47:fe:7f:51:31:44:5e:f7:2a:1e:35:
+ a2:94:32:f7:c9:ee:c0:b6:c6:9a:ac:de:99:21:6a:23:a0:38:
+ 64:ee:a3:c4:88:73:32:3b:50:ce:bf:ad:d3:75:1e:a6:f4:e9:
+ f9:42:6b:60:b2:dd:45:fd:5d:57:08:ce:2d:50:e6:12:32:16:
+ 13:8a:f2:94:a2:9b:47:a8:86:7f:d9:98:e5:f7:e5:76:74:64:
+ d8:91:bc:84:16:28:d8:25:44:30:7e:82:d8:ac:b1:e4:c0:e4:
+ 15:6c:db:b6:24:27:02:2a:01:12:85:ba:31:88:58:47:74:e3:
+ b8:d2:64:a6:c3:32:59:2e:29:4b:45:f1:5b:89:49:2e:82:9a:
+ c6:18:15:44:d0:2e:64:01:15:68:38:f9:f6:f9:66:03:0c:55:
+ 1b:9d:bf:00:40:ae:f0:48:27:4c:e0:80:5e:2d:b9:2a:15:7a:
+ bc:66:f8:35
+-----BEGIN CERTIFICATE-----
+MIIEWTCCA0GgAwIBAgIDAjpjMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTIwODI3MjA0MDQwWhcNMjIwNTIwMjA0MDQwWjBEMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
+U1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5J/lP
+2Pa3FT+Pzc7WjRxr/X/aVCFOA9jK0HJSFbjJgltYeYT/JHJv8ml/vJbZmnrDPqnP
+UCITDoYZ2+hJ74vm1kfy/XNFCK6PrF62+J589xD/kkNm7xzU7qFGiBGJSXl6Jc5L
+avDXHHYaKTzJ5P0ehdzgMWUFRxasCgdLLnBeawanazpsrwUSxLIRJdY+lynwg2xX
+HNil78zs/dYS8T/bQLSuDxjTxa9Akl0HXk7+Yhc3iemLdCai7bgK52wVWzWQct3Y
+TSHUQCNcj+6AMRaraFX0DjtU6QRN8MxOgV7pb1JpTr6mFm1C9VH/4AtWPJhPc48O
+bxoj8cnI2d+87FLXAgMBAAGjggFUMIIBUDAfBgNVHSMEGDAWgBTAephojYn7qwVk
+DBF9qn1luMrMTjAdBgNVHQ4EFgQUEUrQcznVW2kIXLo9v2SaqIscVbwwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2gK4Yp
+aHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYB
+BQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20w
+TAYDVR0gBEUwQzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93
+d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwKgYDVR0RBCMwIaQfMB0xGzAZ
+BgNVBAMTElZlcmlTaWduTVBLSS0yLTI1NDANBgkqhkiG9w0BAQUFAAOCAQEAPOU9
+WhuiNyrjRs82lhg8e/GExVeGd0CdNfAS8HgY+yKk3phLeIHmTYbjkQ9C47ncoNb/
+qfixeZeZ0cNsQqWSlOBdDDMYJckrlVPg5akMfUf+f1ExRF73Kh41opQy98nuwLbG
+mqzemSFqI6A4ZO6jxIhzMjtQzr+t03UepvTp+UJrYLLdRf1dVwjOLVDmEjIWE4ry
+lKKbR6iGf9mY5ffldnRk2JG8hBYo2CVEMH6C2Kyx5MDkFWzbtiQnAioBEoW6MYhY
+R3TjuNJkpsMyWS4pS0XxW4lJLoKaxhgVRNAuZAEVaDj59vlmAwxVG52/AECu8Egn
+TOCAXi25KhV6vGb4NQ==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert13[] = {
+ 0x30, 0x82, 0x04, 0x59, 0x30, 0x82, 0x03, 0x41, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x63, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30,
+ 0x38, 0x32, 0x37, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, 0x5a, 0x17, 0x0d,
+ 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30,
+ 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+ 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30,
+ 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+ 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb9, 0x27, 0xf9, 0x4f,
+ 0xd8, 0xf6, 0xb7, 0x15, 0x3f, 0x8f, 0xcd, 0xce, 0xd6, 0x8d, 0x1c, 0x6b,
+ 0xfd, 0x7f, 0xda, 0x54, 0x21, 0x4e, 0x03, 0xd8, 0xca, 0xd0, 0x72, 0x52,
+ 0x15, 0xb8, 0xc9, 0x82, 0x5b, 0x58, 0x79, 0x84, 0xff, 0x24, 0x72, 0x6f,
+ 0xf2, 0x69, 0x7f, 0xbc, 0x96, 0xd9, 0x9a, 0x7a, 0xc3, 0x3e, 0xa9, 0xcf,
+ 0x50, 0x22, 0x13, 0x0e, 0x86, 0x19, 0xdb, 0xe8, 0x49, 0xef, 0x8b, 0xe6,
+ 0xd6, 0x47, 0xf2, 0xfd, 0x73, 0x45, 0x08, 0xae, 0x8f, 0xac, 0x5e, 0xb6,
+ 0xf8, 0x9e, 0x7c, 0xf7, 0x10, 0xff, 0x92, 0x43, 0x66, 0xef, 0x1c, 0xd4,
+ 0xee, 0xa1, 0x46, 0x88, 0x11, 0x89, 0x49, 0x79, 0x7a, 0x25, 0xce, 0x4b,
+ 0x6a, 0xf0, 0xd7, 0x1c, 0x76, 0x1a, 0x29, 0x3c, 0xc9, 0xe4, 0xfd, 0x1e,
+ 0x85, 0xdc, 0xe0, 0x31, 0x65, 0x05, 0x47, 0x16, 0xac, 0x0a, 0x07, 0x4b,
+ 0x2e, 0x70, 0x5e, 0x6b, 0x06, 0xa7, 0x6b, 0x3a, 0x6c, 0xaf, 0x05, 0x12,
+ 0xc4, 0xb2, 0x11, 0x25, 0xd6, 0x3e, 0x97, 0x29, 0xf0, 0x83, 0x6c, 0x57,
+ 0x1c, 0xd8, 0xa5, 0xef, 0xcc, 0xec, 0xfd, 0xd6, 0x12, 0xf1, 0x3f, 0xdb,
+ 0x40, 0xb4, 0xae, 0x0f, 0x18, 0xd3, 0xc5, 0xaf, 0x40, 0x92, 0x5d, 0x07,
+ 0x5e, 0x4e, 0xfe, 0x62, 0x17, 0x37, 0x89, 0xe9, 0x8b, 0x74, 0x26, 0xa2,
+ 0xed, 0xb8, 0x0a, 0xe7, 0x6c, 0x15, 0x5b, 0x35, 0x90, 0x72, 0xdd, 0xd8,
+ 0x4d, 0x21, 0xd4, 0x40, 0x23, 0x5c, 0x8f, 0xee, 0x80, 0x31, 0x16, 0xab,
+ 0x68, 0x55, 0xf4, 0x0e, 0x3b, 0x54, 0xe9, 0x04, 0x4d, 0xf0, 0xcc, 0x4e,
+ 0x81, 0x5e, 0xe9, 0x6f, 0x52, 0x69, 0x4e, 0xbe, 0xa6, 0x16, 0x6d, 0x42,
+ 0xf5, 0x51, 0xff, 0xe0, 0x0b, 0x56, 0x3c, 0x98, 0x4f, 0x73, 0x8f, 0x0e,
+ 0x6f, 0x1a, 0x23, 0xf1, 0xc9, 0xc8, 0xd9, 0xdf, 0xbc, 0xec, 0x52, 0xd7,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x54, 0x30, 0x82, 0x01,
+ 0x50, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
+ 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d,
+ 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0x4a, 0xd0,
+ 0x73, 0x39, 0xd5, 0x5b, 0x69, 0x08, 0x5c, 0xba, 0x3d, 0xbf, 0x64, 0x9a,
+ 0xa8, 0x8b, 0x1c, 0x55, 0xbc, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+ 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b, 0x86, 0x29,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67,
+ 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61,
+ 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
+ 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+ 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41,
+ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36,
+ 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+ 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+ 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11,
+ 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53,
+ 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32, 0x35,
+ 0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3c, 0xe5, 0x3d,
+ 0x5a, 0x1b, 0xa2, 0x37, 0x2a, 0xe3, 0x46, 0xcf, 0x36, 0x96, 0x18, 0x3c,
+ 0x7b, 0xf1, 0x84, 0xc5, 0x57, 0x86, 0x77, 0x40, 0x9d, 0x35, 0xf0, 0x12,
+ 0xf0, 0x78, 0x18, 0xfb, 0x22, 0xa4, 0xde, 0x98, 0x4b, 0x78, 0x81, 0xe6,
+ 0x4d, 0x86, 0xe3, 0x91, 0x0f, 0x42, 0xe3, 0xb9, 0xdc, 0xa0, 0xd6, 0xff,
+ 0xa9, 0xf8, 0xb1, 0x79, 0x97, 0x99, 0xd1, 0xc3, 0x6c, 0x42, 0xa5, 0x92,
+ 0x94, 0xe0, 0x5d, 0x0c, 0x33, 0x18, 0x25, 0xc9, 0x2b, 0x95, 0x53, 0xe0,
+ 0xe5, 0xa9, 0x0c, 0x7d, 0x47, 0xfe, 0x7f, 0x51, 0x31, 0x44, 0x5e, 0xf7,
+ 0x2a, 0x1e, 0x35, 0xa2, 0x94, 0x32, 0xf7, 0xc9, 0xee, 0xc0, 0xb6, 0xc6,
+ 0x9a, 0xac, 0xde, 0x99, 0x21, 0x6a, 0x23, 0xa0, 0x38, 0x64, 0xee, 0xa3,
+ 0xc4, 0x88, 0x73, 0x32, 0x3b, 0x50, 0xce, 0xbf, 0xad, 0xd3, 0x75, 0x1e,
+ 0xa6, 0xf4, 0xe9, 0xf9, 0x42, 0x6b, 0x60, 0xb2, 0xdd, 0x45, 0xfd, 0x5d,
+ 0x57, 0x08, 0xce, 0x2d, 0x50, 0xe6, 0x12, 0x32, 0x16, 0x13, 0x8a, 0xf2,
+ 0x94, 0xa2, 0x9b, 0x47, 0xa8, 0x86, 0x7f, 0xd9, 0x98, 0xe5, 0xf7, 0xe5,
+ 0x76, 0x74, 0x64, 0xd8, 0x91, 0xbc, 0x84, 0x16, 0x28, 0xd8, 0x25, 0x44,
+ 0x30, 0x7e, 0x82, 0xd8, 0xac, 0xb1, 0xe4, 0xc0, 0xe4, 0x15, 0x6c, 0xdb,
+ 0xb6, 0x24, 0x27, 0x02, 0x2a, 0x01, 0x12, 0x85, 0xba, 0x31, 0x88, 0x58,
+ 0x47, 0x74, 0xe3, 0xb8, 0xd2, 0x64, 0xa6, 0xc3, 0x32, 0x59, 0x2e, 0x29,
+ 0x4b, 0x45, 0xf1, 0x5b, 0x89, 0x49, 0x2e, 0x82, 0x9a, 0xc6, 0x18, 0x15,
+ 0x44, 0xd0, 0x2e, 0x64, 0x01, 0x15, 0x68, 0x38, 0xf9, 0xf6, 0xf9, 0x66,
+ 0x03, 0x0c, 0x55, 0x1b, 0x9d, 0xbf, 0x00, 0x40, 0xae, 0xf0, 0x48, 0x27,
+ 0x4c, 0xe0, 0x80, 0x5e, 0x2d, 0xb9, 0x2a, 0x15, 0x7a, 0xbc, 0x66, 0xf8,
+ 0x35,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 04:00:00:00:00:01:44:4e:f0:3e:20
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
+ Validity
+ Not Before: Feb 20 10:00:00 2014 GMT
+ Not After : Feb 20 10:00:00 2024 GMT
+ Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Domain Validation CA - SHA256 - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a9:dd:cc:0e:b3:e2:32:39:dd:49:22:a8:13:69:
+ 93:87:88:e1:0c:ee:71:7d:bd:90:87:96:5d:59:f2:
+ cc:b3:d2:58:57:57:f9:46:ef:6c:26:d8:36:42:8e:
+ 7e:30:b3:2f:9a:3e:53:7b:1f:6e:b6:a2:4c:45:1f:
+ 3c:d3:15:93:1c:89:ed:3c:f4:57:de:ca:bd:ec:06:
+ 9a:6a:2a:a0:19:52:7f:51:d1:74:39:08:9f:ab:eb:
+ d7:86:13:15:97:ae:36:c3:54:66:0e:5a:f2:a0:73:
+ 85:31:e3:b2:64:14:6a:ff:a5:a2:8e:24:bb:bd:85:
+ 52:15:a2:79:ee:f0:b5:ee:3d:b8:f4:7d:80:bc:d9:
+ 90:35:65:b8:17:a9:ad:b3:98:9f:a0:7e:7d:6e:fb:
+ 3f:ad:7c:c2:1b:59:36:96:da:37:32:4b:4b:5d:35:
+ 02:63:8e:db:a7:cf:62:ee:cc:2e:d4:8d:c9:bd:3c:
+ 6a:91:72:a2:22:a7:72:2d:20:d1:fa:ca:37:da:18:
+ 98:e6:16:24:71:25:4b:c4:e5:7b:89:52:09:02:fd:
+ 59:2b:04:6e:ca:07:81:d4:b3:da:da:db:e3:cc:80:
+ a8:56:07:06:7c:96:08:37:9d:db:38:b6:62:34:91:
+ 62:07:74:01:38:d8:72:30:e2:eb:90:71:26:62:c0:
+ 57:f3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Subject Key Identifier:
+ EA:4E:7C:D4:80:2D:E5:15:81:86:26:8C:82:6D:C0:98:A4:CF:97:0F
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.globalsign.com/repository/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.globalsign.net/root.crl
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.globalsign.com/rootr1
+
+ X509v3 Authority Key Identifier:
+ keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
+
+ Signature Algorithm: sha256WithRSAEncryption
+ d7:45:9e:a0:dc:e0:e3:61:5a:0b:7d:77:84:17:2d:65:5a:82:
+ 9a:8d:a3:27:2a:85:f7:c9:ef:e9:86:fd:d4:47:cd:01:52:96:
+ c5:43:bd:37:b1:e1:b8:f2:a9:d2:8a:11:84:71:91:15:89:dc:
+ 02:9d:0b:cb:6c:33:85:34:28:9e:20:b2:b1:97:dc:6d:0b:10:
+ c1:3c:cd:5f:ea:5d:d7:98:31:c5:34:99:5c:00:61:55:c4:1b:
+ 02:5b:c5:e3:89:c8:b4:b8:6f:1e:38:f2:56:26:e9:41:ef:3d:
+ cd:ac:99:4f:59:4a:57:2d:4b:7d:ae:c7:88:fb:d6:98:3b:f5:
+ e5:f0:e8:89:89:b9:8b:03:cb:5a:23:1f:a4:fd:b8:ea:fb:2e:
+ 9d:ae:6a:73:09:bc:fc:d5:a0:b5:44:82:ab:44:91:2e:50:2e:
+ 57:c1:43:d8:91:04:8b:e9:11:2e:5f:b4:3f:79:df:1e:fb:3f:
+ 30:00:8b:53:e3:b7:2c:1d:3b:4d:8b:dc:e4:64:1d:04:58:33:
+ af:1b:55:e7:ab:0c:bf:30:04:74:e4:f3:0e:2f:30:39:8d:4b:
+ 04:8c:1e:75:66:66:49:e0:be:40:34:c7:5c:5a:51:92:ba:12:
+ 3c:52:d5:04:82:55:2d:67:a5:df:b7:95:7c:ee:3f:c3:08:ba:
+ 04:be:c0:46
+-----BEGIN CERTIFICATE-----
+MIIEYzCCA0ugAwIBAgILBAAAAAABRE7wPiAwDQYJKoZIhvcNAQELBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
+MDBaFw0yNDAyMjAxMDAwMDBaMGAxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMTYwNAYDVQQDEy1HbG9iYWxTaWduIERvbWFpbiBWYWxpZGF0
+aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCp3cwOs+IyOd1JIqgTaZOHiOEM7nF9vZCHll1Z8syz0lhXV/lG72wm2DZC
+jn4wsy+aPlN7H262okxFHzzTFZMcie089Ffeyr3sBppqKqAZUn9R0XQ5CJ+r69eG
+ExWXrjbDVGYOWvKgc4Ux47JkFGr/paKOJLu9hVIVonnu8LXuPbj0fYC82ZA1ZbgX
+qa2zmJ+gfn1u+z+tfMIbWTaW2jcyS0tdNQJjjtunz2LuzC7Ujcm9PGqRcqIip3It
+INH6yjfaGJjmFiRxJUvE5XuJUgkC/VkrBG7KB4HUs9ra2+PMgKhWBwZ8lgg3nds4
+tmI0kWIHdAE42HIw4uuQcSZiwFfzAgMBAAGjggElMIIBITAOBgNVHQ8BAf8EBAMC
+AQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU6k581IAt5RWBhiaMgm3A
+mKTPlw8wRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v
+d3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSG
+Imh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYBBQUHAQEE
+MTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290
+cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEL
+BQADggEBANdFnqDc4ONhWgt9d4QXLWVagpqNoycqhffJ7+mG/dRHzQFSlsVDvTex
+4bjyqdKKEYRxkRWJ3AKdC8tsM4U0KJ4gsrGX3G0LEME8zV/qXdeYMcU0mVwAYVXE
+GwJbxeOJyLS4bx448lYm6UHvPc2smU9ZSlctS32ux4j71pg79eXw6ImJuYsDy1oj
+H6T9uOr7Lp2uanMJvPzVoLVEgqtEkS5QLlfBQ9iRBIvpES5ftD953x77PzAAi1Pj
+tywdO02L3ORkHQRYM68bVeerDL8wBHTk8w4vMDmNSwSMHnVmZkngvkA0x1xaUZK6
+EjxS1QSCVS1npd+3lXzuP8MIugS+wEY=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert14[] = {
+ 0x30, 0x82, 0x04, 0x63, 0x30, 0x82, 0x03, 0x4b, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
+ 0x3e, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
+ 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
+ 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
+ 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
+ 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x60, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
+ 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
+ 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x47,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x44, 0x6f,
+ 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41,
+ 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xa9, 0xdd, 0xcc, 0x0e, 0xb3, 0xe2, 0x32,
+ 0x39, 0xdd, 0x49, 0x22, 0xa8, 0x13, 0x69, 0x93, 0x87, 0x88, 0xe1, 0x0c,
+ 0xee, 0x71, 0x7d, 0xbd, 0x90, 0x87, 0x96, 0x5d, 0x59, 0xf2, 0xcc, 0xb3,
+ 0xd2, 0x58, 0x57, 0x57, 0xf9, 0x46, 0xef, 0x6c, 0x26, 0xd8, 0x36, 0x42,
+ 0x8e, 0x7e, 0x30, 0xb3, 0x2f, 0x9a, 0x3e, 0x53, 0x7b, 0x1f, 0x6e, 0xb6,
+ 0xa2, 0x4c, 0x45, 0x1f, 0x3c, 0xd3, 0x15, 0x93, 0x1c, 0x89, 0xed, 0x3c,
+ 0xf4, 0x57, 0xde, 0xca, 0xbd, 0xec, 0x06, 0x9a, 0x6a, 0x2a, 0xa0, 0x19,
+ 0x52, 0x7f, 0x51, 0xd1, 0x74, 0x39, 0x08, 0x9f, 0xab, 0xeb, 0xd7, 0x86,
+ 0x13, 0x15, 0x97, 0xae, 0x36, 0xc3, 0x54, 0x66, 0x0e, 0x5a, 0xf2, 0xa0,
+ 0x73, 0x85, 0x31, 0xe3, 0xb2, 0x64, 0x14, 0x6a, 0xff, 0xa5, 0xa2, 0x8e,
+ 0x24, 0xbb, 0xbd, 0x85, 0x52, 0x15, 0xa2, 0x79, 0xee, 0xf0, 0xb5, 0xee,
+ 0x3d, 0xb8, 0xf4, 0x7d, 0x80, 0xbc, 0xd9, 0x90, 0x35, 0x65, 0xb8, 0x17,
+ 0xa9, 0xad, 0xb3, 0x98, 0x9f, 0xa0, 0x7e, 0x7d, 0x6e, 0xfb, 0x3f, 0xad,
+ 0x7c, 0xc2, 0x1b, 0x59, 0x36, 0x96, 0xda, 0x37, 0x32, 0x4b, 0x4b, 0x5d,
+ 0x35, 0x02, 0x63, 0x8e, 0xdb, 0xa7, 0xcf, 0x62, 0xee, 0xcc, 0x2e, 0xd4,
+ 0x8d, 0xc9, 0xbd, 0x3c, 0x6a, 0x91, 0x72, 0xa2, 0x22, 0xa7, 0x72, 0x2d,
+ 0x20, 0xd1, 0xfa, 0xca, 0x37, 0xda, 0x18, 0x98, 0xe6, 0x16, 0x24, 0x71,
+ 0x25, 0x4b, 0xc4, 0xe5, 0x7b, 0x89, 0x52, 0x09, 0x02, 0xfd, 0x59, 0x2b,
+ 0x04, 0x6e, 0xca, 0x07, 0x81, 0xd4, 0xb3, 0xda, 0xda, 0xdb, 0xe3, 0xcc,
+ 0x80, 0xa8, 0x56, 0x07, 0x06, 0x7c, 0x96, 0x08, 0x37, 0x9d, 0xdb, 0x38,
+ 0xb6, 0x62, 0x34, 0x91, 0x62, 0x07, 0x74, 0x01, 0x38, 0xd8, 0x72, 0x30,
+ 0xe2, 0xeb, 0x90, 0x71, 0x26, 0x62, 0xc0, 0x57, 0xf3, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25, 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
+ 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+ 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d,
+ 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xea, 0x4e, 0x7c,
+ 0xd4, 0x80, 0x2d, 0xe5, 0x15, 0x81, 0x86, 0x26, 0x8c, 0x82, 0x6d, 0xc0,
+ 0x98, 0xa4, 0xcf, 0x97, 0x0f, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20,
+ 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
+ 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+ 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
+ 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
+ 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
+ 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
+ 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
+ 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e,
+ 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+ 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73,
+ 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74,
+ 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+ 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89,
+ 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xd7, 0x45, 0x9e, 0xa0, 0xdc,
+ 0xe0, 0xe3, 0x61, 0x5a, 0x0b, 0x7d, 0x77, 0x84, 0x17, 0x2d, 0x65, 0x5a,
+ 0x82, 0x9a, 0x8d, 0xa3, 0x27, 0x2a, 0x85, 0xf7, 0xc9, 0xef, 0xe9, 0x86,
+ 0xfd, 0xd4, 0x47, 0xcd, 0x01, 0x52, 0x96, 0xc5, 0x43, 0xbd, 0x37, 0xb1,
+ 0xe1, 0xb8, 0xf2, 0xa9, 0xd2, 0x8a, 0x11, 0x84, 0x71, 0x91, 0x15, 0x89,
+ 0xdc, 0x02, 0x9d, 0x0b, 0xcb, 0x6c, 0x33, 0x85, 0x34, 0x28, 0x9e, 0x20,
+ 0xb2, 0xb1, 0x97, 0xdc, 0x6d, 0x0b, 0x10, 0xc1, 0x3c, 0xcd, 0x5f, 0xea,
+ 0x5d, 0xd7, 0x98, 0x31, 0xc5, 0x34, 0x99, 0x5c, 0x00, 0x61, 0x55, 0xc4,
+ 0x1b, 0x02, 0x5b, 0xc5, 0xe3, 0x89, 0xc8, 0xb4, 0xb8, 0x6f, 0x1e, 0x38,
+ 0xf2, 0x56, 0x26, 0xe9, 0x41, 0xef, 0x3d, 0xcd, 0xac, 0x99, 0x4f, 0x59,
+ 0x4a, 0x57, 0x2d, 0x4b, 0x7d, 0xae, 0xc7, 0x88, 0xfb, 0xd6, 0x98, 0x3b,
+ 0xf5, 0xe5, 0xf0, 0xe8, 0x89, 0x89, 0xb9, 0x8b, 0x03, 0xcb, 0x5a, 0x23,
+ 0x1f, 0xa4, 0xfd, 0xb8, 0xea, 0xfb, 0x2e, 0x9d, 0xae, 0x6a, 0x73, 0x09,
+ 0xbc, 0xfc, 0xd5, 0xa0, 0xb5, 0x44, 0x82, 0xab, 0x44, 0x91, 0x2e, 0x50,
+ 0x2e, 0x57, 0xc1, 0x43, 0xd8, 0x91, 0x04, 0x8b, 0xe9, 0x11, 0x2e, 0x5f,
+ 0xb4, 0x3f, 0x79, 0xdf, 0x1e, 0xfb, 0x3f, 0x30, 0x00, 0x8b, 0x53, 0xe3,
+ 0xb7, 0x2c, 0x1d, 0x3b, 0x4d, 0x8b, 0xdc, 0xe4, 0x64, 0x1d, 0x04, 0x58,
+ 0x33, 0xaf, 0x1b, 0x55, 0xe7, 0xab, 0x0c, 0xbf, 0x30, 0x04, 0x74, 0xe4,
+ 0xf3, 0x0e, 0x2f, 0x30, 0x39, 0x8d, 0x4b, 0x04, 0x8c, 0x1e, 0x75, 0x66,
+ 0x66, 0x49, 0xe0, 0xbe, 0x40, 0x34, 0xc7, 0x5c, 0x5a, 0x51, 0x92, 0xba,
+ 0x12, 0x3c, 0x52, 0xd5, 0x04, 0x82, 0x55, 0x2d, 0x67, 0xa5, 0xdf, 0xb7,
+ 0x95, 0x7c, 0xee, 0x3f, 0xc3, 0x08, 0xba, 0x04, 0xbe, 0xc0, 0x46,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 04:00:00:00:00:01:44:4e:f0:42:47
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
+ Validity
+ Not Before: Feb 20 10:00:00 2014 GMT
+ Not After : Feb 20 10:00:00 2024 GMT
+ Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c7:0e:6c:3f:23:93:7f:cc:70:a5:9d:20:c3:0e:
+ 53:3f:7e:c0:4e:c2:98:49:ca:47:d5:23:ef:03:34:
+ 85:74:c8:a3:02:2e:46:5c:0b:7d:c9:88:9d:4f:8b:
+ f0:f8:9c:6c:8c:55:35:db:bf:f2:b3:ea:fb:e3:56:
+ e7:4a:46:d9:13:22:ca:36:d5:9b:c1:a8:e3:96:43:
+ 93:f2:0c:bc:e6:f9:e6:e8:99:c8:63:48:78:7f:57:
+ 36:69:1a:19:1d:5a:d1:d4:7d:c2:9c:d4:7f:e1:80:
+ 12:ae:7a:ea:88:ea:57:d8:ca:0a:0a:3a:12:49:a2:
+ 62:19:7a:0d:24:f7:37:eb:b4:73:92:7b:05:23:9b:
+ 12:b5:ce:eb:29:df:a4:14:02:b9:01:a5:d4:a6:9c:
+ 43:64:88:de:f8:7e:fe:e3:f5:1e:e5:fe:dc:a3:a8:
+ e4:66:31:d9:4c:25:e9:18:b9:89:59:09:ae:e9:9d:
+ 1c:6d:37:0f:4a:1e:35:20:28:e2:af:d4:21:8b:01:
+ c4:45:ad:6e:2b:63:ab:92:6b:61:0a:4d:20:ed:73:
+ ba:7c:ce:fe:16:b5:db:9f:80:f0:d6:8b:6c:d9:08:
+ 79:4a:4f:78:65:da:92:bc:be:35:f9:b3:c4:f9:27:
+ 80:4e:ff:96:52:e6:02:20:e1:07:73:e9:5d:2b:bd:
+ b2:f1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Subject Key Identifier:
+ 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.globalsign.com/repository/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.globalsign.net/root.crl
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.globalsign.com/rootr1
+
+ X509v3 Authority Key Identifier:
+ keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 46:2a:ee:5e:bd:ae:01:60:37:31:11:86:71:74:b6:46:49:c8:
+ 10:16:fe:2f:62:23:17:ab:1f:87:f8:82:ed:ca:df:0e:2c:df:
+ 64:75:8e:e5:18:72:a7:8c:3a:8b:c9:ac:a5:77:50:f7:ef:9e:
+ a4:e0:a0:8f:14:57:a3:2a:5f:ec:7e:6d:10:e6:ba:8d:b0:08:
+ 87:76:0e:4c:b2:d9:51:bb:11:02:f2:5c:dd:1c:bd:f3:55:96:
+ 0f:d4:06:c0:fc:e2:23:8a:24:70:d3:bb:f0:79:1a:a7:61:70:
+ 83:8a:af:06:c5:20:d8:a1:63:d0:6c:ae:4f:32:d7:ae:7c:18:
+ 45:75:05:29:77:df:42:40:64:64:86:be:2a:76:09:31:6f:1d:
+ 24:f4:99:d0:85:fe:f2:21:08:f9:c6:f6:f1:d0:59:ed:d6:56:
+ 3c:08:28:03:67:ba:f0:f9:f1:90:16:47:ae:67:e6:bc:80:48:
+ e9:42:76:34:97:55:69:24:0e:83:d6:a0:2d:b4:f5:f3:79:8a:
+ 49:28:74:1a:41:a1:c2:d3:24:88:35:30:60:94:17:b4:e1:04:
+ 22:31:3d:3b:2f:17:06:b2:b8:9d:86:2b:5a:69:ef:83:f5:4b:
+ c4:aa:b4:2a:f8:7c:a1:b1:85:94:8c:f4:0c:87:0c:f4:ac:40:
+ f8:59:49:98
+-----BEGIN CERTIFICATE-----
+MIIEaTCCA1GgAwIBAgILBAAAAAABRE7wQkcwDQYJKoZIhvcNAQELBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
+MDBaFw0yNDAyMjAxMDAwMDBaMGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMTwwOgYDVQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBW
+YWxpZGF0aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDHDmw/I5N/zHClnSDDDlM/fsBOwphJykfVI+8DNIV0yKMCLkZc
+C33JiJ1Pi/D4nGyMVTXbv/Kz6vvjVudKRtkTIso21ZvBqOOWQ5PyDLzm+ebomchj
+SHh/VzZpGhkdWtHUfcKc1H/hgBKueuqI6lfYygoKOhJJomIZeg0k9zfrtHOSewUj
+mxK1zusp36QUArkBpdSmnENkiN74fv7j9R7l/tyjqORmMdlMJekYuYlZCa7pnRxt
+Nw9KHjUgKOKv1CGLAcRFrW4rY6uSa2EKTSDtc7p8zv4WtdufgPDWi2zZCHlKT3hl
+2pK8vjX5s8T5J4BO/5ZS5gIg4Qdz6V0rvbLxAgMBAAGjggElMIIBITAOBgNVHQ8B
+Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUlt5h8b0cFilT
+HMDMfTuDAEDmGnwwRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0
+dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCow
+KKAmoCSGImh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYB
+BQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNv
+bS9yb290cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZI
+hvcNAQELBQADggEBAEYq7l69rgFgNzERhnF0tkZJyBAW/i9iIxerH4f4gu3K3w4s
+32R1juUYcqeMOovJrKV3UPfvnqTgoI8UV6MqX+x+bRDmuo2wCId2Dkyy2VG7EQLy
+XN0cvfNVlg/UBsD84iOKJHDTu/B5GqdhcIOKrwbFINihY9Bsrk8y1658GEV1BSl3
+30JAZGSGvip2CTFvHST0mdCF/vIhCPnG9vHQWe3WVjwIKANnuvD58ZAWR65n5ryA
+SOlCdjSXVWkkDoPWoC209fN5ikkodBpBocLTJIg1MGCUF7ThBCIxPTsvFwayuJ2G
+K1pp74P1S8SqtCr4fKGxhZSM9AyHDPSsQPhZSZg=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert15[] = {
+ 0x30, 0x82, 0x04, 0x69, 0x30, 0x82, 0x03, 0x51, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0,
+ 0x42, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61,
+ 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f,
+ 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
+ 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
+ 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30,
+ 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
+ 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x33, 0x47,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x72,
+ 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56,
+ 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41,
+ 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20,
+ 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc7,
+ 0x0e, 0x6c, 0x3f, 0x23, 0x93, 0x7f, 0xcc, 0x70, 0xa5, 0x9d, 0x20, 0xc3,
+ 0x0e, 0x53, 0x3f, 0x7e, 0xc0, 0x4e, 0xc2, 0x98, 0x49, 0xca, 0x47, 0xd5,
+ 0x23, 0xef, 0x03, 0x34, 0x85, 0x74, 0xc8, 0xa3, 0x02, 0x2e, 0x46, 0x5c,
+ 0x0b, 0x7d, 0xc9, 0x88, 0x9d, 0x4f, 0x8b, 0xf0, 0xf8, 0x9c, 0x6c, 0x8c,
+ 0x55, 0x35, 0xdb, 0xbf, 0xf2, 0xb3, 0xea, 0xfb, 0xe3, 0x56, 0xe7, 0x4a,
+ 0x46, 0xd9, 0x13, 0x22, 0xca, 0x36, 0xd5, 0x9b, 0xc1, 0xa8, 0xe3, 0x96,
+ 0x43, 0x93, 0xf2, 0x0c, 0xbc, 0xe6, 0xf9, 0xe6, 0xe8, 0x99, 0xc8, 0x63,
+ 0x48, 0x78, 0x7f, 0x57, 0x36, 0x69, 0x1a, 0x19, 0x1d, 0x5a, 0xd1, 0xd4,
+ 0x7d, 0xc2, 0x9c, 0xd4, 0x7f, 0xe1, 0x80, 0x12, 0xae, 0x7a, 0xea, 0x88,
+ 0xea, 0x57, 0xd8, 0xca, 0x0a, 0x0a, 0x3a, 0x12, 0x49, 0xa2, 0x62, 0x19,
+ 0x7a, 0x0d, 0x24, 0xf7, 0x37, 0xeb, 0xb4, 0x73, 0x92, 0x7b, 0x05, 0x23,
+ 0x9b, 0x12, 0xb5, 0xce, 0xeb, 0x29, 0xdf, 0xa4, 0x14, 0x02, 0xb9, 0x01,
+ 0xa5, 0xd4, 0xa6, 0x9c, 0x43, 0x64, 0x88, 0xde, 0xf8, 0x7e, 0xfe, 0xe3,
+ 0xf5, 0x1e, 0xe5, 0xfe, 0xdc, 0xa3, 0xa8, 0xe4, 0x66, 0x31, 0xd9, 0x4c,
+ 0x25, 0xe9, 0x18, 0xb9, 0x89, 0x59, 0x09, 0xae, 0xe9, 0x9d, 0x1c, 0x6d,
+ 0x37, 0x0f, 0x4a, 0x1e, 0x35, 0x20, 0x28, 0xe2, 0xaf, 0xd4, 0x21, 0x8b,
+ 0x01, 0xc4, 0x45, 0xad, 0x6e, 0x2b, 0x63, 0xab, 0x92, 0x6b, 0x61, 0x0a,
+ 0x4d, 0x20, 0xed, 0x73, 0xba, 0x7c, 0xce, 0xfe, 0x16, 0xb5, 0xdb, 0x9f,
+ 0x80, 0xf0, 0xd6, 0x8b, 0x6c, 0xd9, 0x08, 0x79, 0x4a, 0x4f, 0x78, 0x65,
+ 0xda, 0x92, 0xbc, 0xbe, 0x35, 0xf9, 0xb3, 0xc4, 0xf9, 0x27, 0x80, 0x4e,
+ 0xff, 0x96, 0x52, 0xe6, 0x02, 0x20, 0xe1, 0x07, 0x73, 0xe9, 0x5d, 0x2b,
+ 0xbd, 0xb2, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25,
+ 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03,
+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
+ 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0x96, 0xde, 0x61, 0xf1, 0xbd, 0x1c, 0x16, 0x29, 0x53,
+ 0x1c, 0xc0, 0xcc, 0x7d, 0x3b, 0x83, 0x00, 0x40, 0xe6, 0x1a, 0x7c, 0x30,
+ 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c,
+ 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74,
+ 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c,
+ 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
+ 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30,
+ 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
+ 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f,
+ 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03,
+ 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66,
+ 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34,
+ 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+ 0x00, 0x46, 0x2a, 0xee, 0x5e, 0xbd, 0xae, 0x01, 0x60, 0x37, 0x31, 0x11,
+ 0x86, 0x71, 0x74, 0xb6, 0x46, 0x49, 0xc8, 0x10, 0x16, 0xfe, 0x2f, 0x62,
+ 0x23, 0x17, 0xab, 0x1f, 0x87, 0xf8, 0x82, 0xed, 0xca, 0xdf, 0x0e, 0x2c,
+ 0xdf, 0x64, 0x75, 0x8e, 0xe5, 0x18, 0x72, 0xa7, 0x8c, 0x3a, 0x8b, 0xc9,
+ 0xac, 0xa5, 0x77, 0x50, 0xf7, 0xef, 0x9e, 0xa4, 0xe0, 0xa0, 0x8f, 0x14,
+ 0x57, 0xa3, 0x2a, 0x5f, 0xec, 0x7e, 0x6d, 0x10, 0xe6, 0xba, 0x8d, 0xb0,
+ 0x08, 0x87, 0x76, 0x0e, 0x4c, 0xb2, 0xd9, 0x51, 0xbb, 0x11, 0x02, 0xf2,
+ 0x5c, 0xdd, 0x1c, 0xbd, 0xf3, 0x55, 0x96, 0x0f, 0xd4, 0x06, 0xc0, 0xfc,
+ 0xe2, 0x23, 0x8a, 0x24, 0x70, 0xd3, 0xbb, 0xf0, 0x79, 0x1a, 0xa7, 0x61,
+ 0x70, 0x83, 0x8a, 0xaf, 0x06, 0xc5, 0x20, 0xd8, 0xa1, 0x63, 0xd0, 0x6c,
+ 0xae, 0x4f, 0x32, 0xd7, 0xae, 0x7c, 0x18, 0x45, 0x75, 0x05, 0x29, 0x77,
+ 0xdf, 0x42, 0x40, 0x64, 0x64, 0x86, 0xbe, 0x2a, 0x76, 0x09, 0x31, 0x6f,
+ 0x1d, 0x24, 0xf4, 0x99, 0xd0, 0x85, 0xfe, 0xf2, 0x21, 0x08, 0xf9, 0xc6,
+ 0xf6, 0xf1, 0xd0, 0x59, 0xed, 0xd6, 0x56, 0x3c, 0x08, 0x28, 0x03, 0x67,
+ 0xba, 0xf0, 0xf9, 0xf1, 0x90, 0x16, 0x47, 0xae, 0x67, 0xe6, 0xbc, 0x80,
+ 0x48, 0xe9, 0x42, 0x76, 0x34, 0x97, 0x55, 0x69, 0x24, 0x0e, 0x83, 0xd6,
+ 0xa0, 0x2d, 0xb4, 0xf5, 0xf3, 0x79, 0x8a, 0x49, 0x28, 0x74, 0x1a, 0x41,
+ 0xa1, 0xc2, 0xd3, 0x24, 0x88, 0x35, 0x30, 0x60, 0x94, 0x17, 0xb4, 0xe1,
+ 0x04, 0x22, 0x31, 0x3d, 0x3b, 0x2f, 0x17, 0x06, 0xb2, 0xb8, 0x9d, 0x86,
+ 0x2b, 0x5a, 0x69, 0xef, 0x83, 0xf5, 0x4b, 0xc4, 0xaa, 0xb4, 0x2a, 0xf8,
+ 0x7c, 0xa1, 0xb1, 0x85, 0x94, 0x8c, 0xf4, 0x0c, 0x87, 0x0c, 0xf4, 0xac,
+ 0x40, 0xf8, 0x59, 0x49, 0x98,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 4d:5f:2c:34:08:b2:4c:20:cd:6d:50:7e:24:4d:c9:ec
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
+ Validity
+ Not Before: Feb 8 00:00:00 2010 GMT
+ Not After : Feb 7 23:59:59 2020 GMT
+ Subject: C=US, O=Thawte, Inc., CN=Thawte SSL CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:99:e4:85:5b:76:49:7d:2f:05:d8:c5:ac:c8:c8:
+ a9:d3:dc:98:e6:d7:34:a6:2f:0c:f2:22:26:d8:a3:
+ c9:14:4c:8f:05:a4:45:e8:14:0c:58:90:05:1a:b7:
+ c5:c1:06:a5:80:af:bb:1d:49:6b:52:34:88:c3:59:
+ e7:ef:6b:c4:27:41:8c:2b:66:1d:d0:e0:a3:97:98:
+ 19:34:4b:41:d5:98:d5:c7:05:ad:a2:e4:d7:ed:0c:
+ ad:4f:c1:b5:b0:21:fd:3e:50:53:b2:c4:90:d0:d4:
+ 30:67:6c:9a:f1:0e:74:c4:c2:dc:8a:e8:97:ff:c9:
+ 92:ae:01:8a:56:0a:98:32:b0:00:23:ec:90:1a:60:
+ c3:ed:bb:3a:cb:0f:63:9f:0d:44:c9:52:e1:25:96:
+ bf:ed:50:95:89:7f:56:14:b1:b7:61:1d:1c:07:8c:
+ 3a:2c:f7:ff:80:de:39:45:d5:af:1a:d1:78:d8:c7:
+ 71:6a:a3:19:a7:32:50:21:e9:f2:0e:a1:c6:13:03:
+ 44:48:d1:66:a8:52:57:d7:11:b4:93:8b:e5:99:9f:
+ 5d:e7:78:51:e5:4d:f6:b7:59:b4:76:b5:09:37:4d:
+ 06:38:13:7a:1c:08:98:5c:c4:48:4a:cb:52:a0:a9:
+ f8:b1:9d:8e:7b:79:b0:20:2f:3c:96:a8:11:62:47:
+ bb:11
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ OCSP - URI:http://ocsp.thawte.com
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.thawte.com/ThawtePCA.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Alternative Name:
+ DirName:/CN=VeriSignMPKI-2-9
+ X509v3 Subject Key Identifier:
+ A7:A2:83:BB:34:45:40:3D:FC:D5:30:4F:12:B9:3E:A1:01:9F:F6:DB
+ X509v3 Authority Key Identifier:
+ keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 80:22:80:e0:6c:c8:95:16:d7:57:26:87:f3:72:34:db:c6:72:
+ 56:27:3e:d3:96:f6:2e:25:91:a5:3e:33:97:a7:4b:e5:2f:fb:
+ 25:7d:2f:07:61:fa:6f:83:74:4c:4c:53:72:20:a4:7a:cf:51:
+ 51:56:81:88:b0:6d:1f:36:2c:c8:2b:b1:88:99:c1:fe:44:ab:
+ 48:51:7c:d8:f2:44:64:2a:d8:71:a7:fb:1a:2f:f9:19:8d:34:
+ b2:23:bf:c4:4c:55:1d:8e:44:e8:aa:5d:9a:dd:9f:fd:03:c7:
+ ba:24:43:8d:2d:47:44:db:f6:d8:98:c8:b2:f9:da:ef:ed:29:
+ 5c:69:12:fa:d1:23:96:0f:bf:9c:0d:f2:79:45:53:37:9a:56:
+ 2f:e8:57:10:70:f6:ee:89:0c:49:89:9a:c1:23:f5:c2:2a:cc:
+ 41:cf:22:ab:65:6e:b7:94:82:6d:2f:40:5f:58:de:eb:95:2b:
+ a6:72:68:52:19:91:2a:ae:75:9d:4e:92:e6:ca:de:54:ea:18:
+ ab:25:3c:e6:64:a6:79:1f:26:7d:61:ed:7d:d2:e5:71:55:d8:
+ 93:17:7c:14:38:30:3c:df:86:e3:4c:ad:49:e3:97:59:ce:1b:
+ 9b:2b:ce:dc:65:d4:0b:28:6b:4e:84:46:51:44:f7:33:08:2d:
+ 58:97:21:ae
+-----BEGIN CERTIFICATE-----
+MIIEbDCCA1SgAwIBAgIQTV8sNAiyTCDNbVB+JE3J7DANBgkqhkiG9w0BAQUFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTAwMjA4MDAwMDAwWhcNMjAw
+MjA3MjM1OTU5WjA8MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMu
+MRYwFAYDVQQDEw1UaGF3dGUgU1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAmeSFW3ZJfS8F2MWsyMip09yY5tc0pi8M8iIm2KPJFEyPBaRF6BQM
+WJAFGrfFwQalgK+7HUlrUjSIw1nn72vEJ0GMK2Yd0OCjl5gZNEtB1ZjVxwWtouTX
+7QytT8G1sCH9PlBTssSQ0NQwZ2ya8Q50xMLciuiX/8mSrgGKVgqYMrAAI+yQGmDD
+7bs6yw9jnw1EyVLhJZa/7VCViX9WFLG3YR0cB4w6LPf/gN45RdWvGtF42MdxaqMZ
+pzJQIenyDqHGEwNESNFmqFJX1xG0k4vlmZ9d53hR5U32t1m0drUJN00GOBN6HAiY
+XMRISstSoKn4sZ2Oe3mwIC88lqgRYke7EQIDAQABo4H7MIH4MDIGCCsGAQUFBwEB
+BCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AudGhhd3RlLmNvbTASBgNVHRMB
+Af8ECDAGAQH/AgEAMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudGhhd3Rl
+LmNvbS9UaGF3dGVQQ0EuY3JsMA4GA1UdDwEB/wQEAwIBBjAoBgNVHREEITAfpB0w
+GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItOTAdBgNVHQ4EFgQUp6KDuzRFQD38
+1TBPErk+oQGf9tswHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutXSFAwDQYJ
+KoZIhvcNAQEFBQADggEBAIAigOBsyJUW11cmh/NyNNvGclYnPtOW9i4lkaU+M5en
+S+Uv+yV9Lwdh+m+DdExMU3IgpHrPUVFWgYiwbR82LMgrsYiZwf5Eq0hRfNjyRGQq
+2HGn+xov+RmNNLIjv8RMVR2OROiqXZrdn/0Dx7okQ40tR0Tb9tiYyLL52u/tKVxp
+EvrRI5YPv5wN8nlFUzeaVi/oVxBw9u6JDEmJmsEj9cIqzEHPIqtlbreUgm0vQF9Y
+3uuVK6ZyaFIZkSqudZ1OkubK3lTqGKslPOZkpnkfJn1h7X3S5XFV2JMXfBQ4MDzf
+huNMrUnjl1nOG5srztxl1Asoa06ERlFE9zMILViXIa4=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert16[] = {
+ 0x30, 0x82, 0x04, 0x6c, 0x30, 0x82, 0x03, 0x54, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x4d, 0x5f, 0x2c, 0x34, 0x08, 0xb2, 0x4c, 0x20, 0xcd,
+ 0x6d, 0x50, 0x7e, 0x24, 0x4d, 0xc9, 0xec, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+ 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+ 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+ 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+ 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+ 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30,
+ 0x32, 0x30, 0x37, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x3c,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54,
+ 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
+ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x99, 0xe4, 0x85,
+ 0x5b, 0x76, 0x49, 0x7d, 0x2f, 0x05, 0xd8, 0xc5, 0xac, 0xc8, 0xc8, 0xa9,
+ 0xd3, 0xdc, 0x98, 0xe6, 0xd7, 0x34, 0xa6, 0x2f, 0x0c, 0xf2, 0x22, 0x26,
+ 0xd8, 0xa3, 0xc9, 0x14, 0x4c, 0x8f, 0x05, 0xa4, 0x45, 0xe8, 0x14, 0x0c,
+ 0x58, 0x90, 0x05, 0x1a, 0xb7, 0xc5, 0xc1, 0x06, 0xa5, 0x80, 0xaf, 0xbb,
+ 0x1d, 0x49, 0x6b, 0x52, 0x34, 0x88, 0xc3, 0x59, 0xe7, 0xef, 0x6b, 0xc4,
+ 0x27, 0x41, 0x8c, 0x2b, 0x66, 0x1d, 0xd0, 0xe0, 0xa3, 0x97, 0x98, 0x19,
+ 0x34, 0x4b, 0x41, 0xd5, 0x98, 0xd5, 0xc7, 0x05, 0xad, 0xa2, 0xe4, 0xd7,
+ 0xed, 0x0c, 0xad, 0x4f, 0xc1, 0xb5, 0xb0, 0x21, 0xfd, 0x3e, 0x50, 0x53,
+ 0xb2, 0xc4, 0x90, 0xd0, 0xd4, 0x30, 0x67, 0x6c, 0x9a, 0xf1, 0x0e, 0x74,
+ 0xc4, 0xc2, 0xdc, 0x8a, 0xe8, 0x97, 0xff, 0xc9, 0x92, 0xae, 0x01, 0x8a,
+ 0x56, 0x0a, 0x98, 0x32, 0xb0, 0x00, 0x23, 0xec, 0x90, 0x1a, 0x60, 0xc3,
+ 0xed, 0xbb, 0x3a, 0xcb, 0x0f, 0x63, 0x9f, 0x0d, 0x44, 0xc9, 0x52, 0xe1,
+ 0x25, 0x96, 0xbf, 0xed, 0x50, 0x95, 0x89, 0x7f, 0x56, 0x14, 0xb1, 0xb7,
+ 0x61, 0x1d, 0x1c, 0x07, 0x8c, 0x3a, 0x2c, 0xf7, 0xff, 0x80, 0xde, 0x39,
+ 0x45, 0xd5, 0xaf, 0x1a, 0xd1, 0x78, 0xd8, 0xc7, 0x71, 0x6a, 0xa3, 0x19,
+ 0xa7, 0x32, 0x50, 0x21, 0xe9, 0xf2, 0x0e, 0xa1, 0xc6, 0x13, 0x03, 0x44,
+ 0x48, 0xd1, 0x66, 0xa8, 0x52, 0x57, 0xd7, 0x11, 0xb4, 0x93, 0x8b, 0xe5,
+ 0x99, 0x9f, 0x5d, 0xe7, 0x78, 0x51, 0xe5, 0x4d, 0xf6, 0xb7, 0x59, 0xb4,
+ 0x76, 0xb5, 0x09, 0x37, 0x4d, 0x06, 0x38, 0x13, 0x7a, 0x1c, 0x08, 0x98,
+ 0x5c, 0xc4, 0x48, 0x4a, 0xcb, 0x52, 0xa0, 0xa9, 0xf8, 0xb1, 0x9d, 0x8e,
+ 0x7b, 0x79, 0xb0, 0x20, 0x2f, 0x3c, 0x96, 0xa8, 0x11, 0x62, 0x47, 0xbb,
+ 0x11, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfb, 0x30, 0x81, 0xf8,
+ 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+ 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+ 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
+ 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30,
+ 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50,
+ 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x28,
+ 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30,
+ 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10,
+ 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
+ 0x2d, 0x32, 0x2d, 0x39, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0xa7, 0xa2, 0x83, 0xbb, 0x34, 0x45, 0x40, 0x3d, 0xfc,
+ 0xd5, 0x30, 0x4f, 0x12, 0xb9, 0x3e, 0xa1, 0x01, 0x9f, 0xf6, 0xdb, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a,
+ 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x80, 0x22, 0x80, 0xe0, 0x6c, 0xc8, 0x95, 0x16,
+ 0xd7, 0x57, 0x26, 0x87, 0xf3, 0x72, 0x34, 0xdb, 0xc6, 0x72, 0x56, 0x27,
+ 0x3e, 0xd3, 0x96, 0xf6, 0x2e, 0x25, 0x91, 0xa5, 0x3e, 0x33, 0x97, 0xa7,
+ 0x4b, 0xe5, 0x2f, 0xfb, 0x25, 0x7d, 0x2f, 0x07, 0x61, 0xfa, 0x6f, 0x83,
+ 0x74, 0x4c, 0x4c, 0x53, 0x72, 0x20, 0xa4, 0x7a, 0xcf, 0x51, 0x51, 0x56,
+ 0x81, 0x88, 0xb0, 0x6d, 0x1f, 0x36, 0x2c, 0xc8, 0x2b, 0xb1, 0x88, 0x99,
+ 0xc1, 0xfe, 0x44, 0xab, 0x48, 0x51, 0x7c, 0xd8, 0xf2, 0x44, 0x64, 0x2a,
+ 0xd8, 0x71, 0xa7, 0xfb, 0x1a, 0x2f, 0xf9, 0x19, 0x8d, 0x34, 0xb2, 0x23,
+ 0xbf, 0xc4, 0x4c, 0x55, 0x1d, 0x8e, 0x44, 0xe8, 0xaa, 0x5d, 0x9a, 0xdd,
+ 0x9f, 0xfd, 0x03, 0xc7, 0xba, 0x24, 0x43, 0x8d, 0x2d, 0x47, 0x44, 0xdb,
+ 0xf6, 0xd8, 0x98, 0xc8, 0xb2, 0xf9, 0xda, 0xef, 0xed, 0x29, 0x5c, 0x69,
+ 0x12, 0xfa, 0xd1, 0x23, 0x96, 0x0f, 0xbf, 0x9c, 0x0d, 0xf2, 0x79, 0x45,
+ 0x53, 0x37, 0x9a, 0x56, 0x2f, 0xe8, 0x57, 0x10, 0x70, 0xf6, 0xee, 0x89,
+ 0x0c, 0x49, 0x89, 0x9a, 0xc1, 0x23, 0xf5, 0xc2, 0x2a, 0xcc, 0x41, 0xcf,
+ 0x22, 0xab, 0x65, 0x6e, 0xb7, 0x94, 0x82, 0x6d, 0x2f, 0x40, 0x5f, 0x58,
+ 0xde, 0xeb, 0x95, 0x2b, 0xa6, 0x72, 0x68, 0x52, 0x19, 0x91, 0x2a, 0xae,
+ 0x75, 0x9d, 0x4e, 0x92, 0xe6, 0xca, 0xde, 0x54, 0xea, 0x18, 0xab, 0x25,
+ 0x3c, 0xe6, 0x64, 0xa6, 0x79, 0x1f, 0x26, 0x7d, 0x61, 0xed, 0x7d, 0xd2,
+ 0xe5, 0x71, 0x55, 0xd8, 0x93, 0x17, 0x7c, 0x14, 0x38, 0x30, 0x3c, 0xdf,
+ 0x86, 0xe3, 0x4c, 0xad, 0x49, 0xe3, 0x97, 0x59, 0xce, 0x1b, 0x9b, 0x2b,
+ 0xce, 0xdc, 0x65, 0xd4, 0x0b, 0x28, 0x6b, 0x4e, 0x84, 0x46, 0x51, 0x44,
+ 0xf7, 0x33, 0x08, 0x2d, 0x58, 0x97, 0x21, 0xae,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 6e:8a:90:eb:cf:f0:44:8a:72:0d:08:05:d0:82:a5:44
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
+ Validity
+ Not Before: Oct 31 00:00:00 2013 GMT
+ Not After : Oct 30 23:59:59 2023 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust EV SSL CA - G4
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d9:b4:05:f2:38:67:0f:09:e7:7c:f5:63:2a:e5:
+ b9:5e:a8:11:ae:75:71:d9:4c:84:67:ad:89:5d:fc:
+ 28:3d:2a:b0:a5:d5:d4:e6:30:0a:84:d4:e4:18:cb:
+ 85:37:c5:46:71:eb:1c:7b:69:db:65:69:8c:30:05:
+ 3e:07:e1:6f:3c:c1:0b:61:e6:38:44:fc:bc:8c:2f:
+ 4e:75:57:f5:96:99:7c:3e:87:1f:0f:90:4b:70:c3:
+ 3f:39:45:3b:3a:6b:cb:bb:7b:40:54:d1:8b:4b:a1:
+ 72:d2:04:e9:e0:72:1a:93:11:7a:2f:f1:ab:9d:9c:
+ 98:58:ae:2c:ea:77:5f:2f:2e:87:af:b8:6b:e3:e2:
+ e2:3f:d6:3d:e0:96:44:df:11:55:63:52:2f:f4:26:
+ 78:c4:0f:20:4d:0a:c0:68:70:15:86:38:ee:b7:76:
+ 88:ab:18:8f:4f:35:1e:d4:8c:c9:db:7e:3d:44:d4:
+ 36:8c:c1:37:b5:59:5b:87:f9:e9:f1:d4:c5:28:bd:
+ 1d:dc:cc:96:72:d1:7a:a1:a7:20:b5:b8:af:f8:6e:
+ a5:60:7b:2b:8d:1f:ee:f4:2b:d6:69:cd:af:ca:80:
+ 58:29:e8:4c:00:20:8a:49:0a:6e:8e:8c:a8:d1:00:
+ 12:84:b6:c5:e2:95:a2:c0:3b:a4:6b:f0:82:d0:96:
+ 5d:25
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://g2.symcb.com
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.geotrust.com/resources/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://g1.symcb.com/GeoTrustPCA.crl
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=SymantecPKI-1-538
+ X509v3 Subject Key Identifier:
+ DE:CF:5C:50:B7:AE:02:1F:15:17:AA:16:E8:0D:B5:28:9D:6A:5A:F3
+ X509v3 Authority Key Identifier:
+ keyid:2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
+
+ Signature Algorithm: sha256WithRSAEncryption
+ b4:8e:bd:07:b9:9a:85:ec:3b:67:bd:07:60:61:e6:84:d1:d4:
+ ef:eb:1b:ba:0b:82:4b:95:64:b6:66:53:23:bd:b7:84:dd:e4:
+ 7b:8d:09:da:cf:b2:f5:f1:c3:bf:87:84:be:4e:a6:a8:c2:e7:
+ 12:39:28:34:e0:a4:56:44:40:0c:9f:88:a3:15:d3:e8:d3:5e:
+ e3:1c:04:60:fb:69:36:4f:6a:7e:0c:2a:28:c1:f3:aa:58:0e:
+ 6c:ce:1d:07:c3:4a:c0:9c:8d:c3:74:b1:ae:82:f0:1a:e1:f9:
+ 4e:29:bd:46:de:b7:1d:f9:7d:db:d9:0f:84:cb:92:45:cc:1c:
+ b3:18:f6:a0:cf:71:6f:0c:2e:9b:d2:2d:b3:99:93:83:44:ac:
+ 15:aa:9b:2e:67:ec:4f:88:69:05:56:7b:8b:b2:43:a9:3a:6c:
+ 1c:13:33:25:1b:fd:a8:c8:57:02:fb:1c:e0:d1:bd:3b:56:44:
+ 65:c3:63:f5:1b:ef:ec:30:d9:e3:6e:2e:13:e9:39:08:2a:0c:
+ 72:f3:9a:cc:f6:27:29:84:d3:ef:4c:c7:84:11:65:1f:c6:e3:
+ 81:03:db:87:cc:78:f7:b5:9d:96:3e:6a:7f:bc:11:85:7a:75:
+ e6:41:7d:0d:cf:f9:e5:85:69:25:8f:c7:8d:07:2d:f8:69:0f:
+ cb:41:53:00
+-----BEGIN CERTIFICATE-----
+MIIEbjCCA1agAwIBAgIQboqQ68/wRIpyDQgF0IKlRDANBgkqhkiG9w0BAQsFADBY
+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
+R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMzEw
+MzEwMDAwMDBaFw0yMzEwMzAyMzU5NTlaMEcxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMSAwHgYDVQQDExdHZW9UcnVzdCBFViBTU0wgQ0EgLSBH
+NDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANm0BfI4Zw8J53z1Yyrl
+uV6oEa51cdlMhGetiV38KD0qsKXV1OYwCoTU5BjLhTfFRnHrHHtp22VpjDAFPgfh
+bzzBC2HmOET8vIwvTnVX9ZaZfD6HHw+QS3DDPzlFOzpry7t7QFTRi0uhctIE6eBy
+GpMRei/xq52cmFiuLOp3Xy8uh6+4a+Pi4j/WPeCWRN8RVWNSL/QmeMQPIE0KwGhw
+FYY47rd2iKsYj081HtSMydt+PUTUNozBN7VZW4f56fHUxSi9HdzMlnLReqGnILW4
+r/hupWB7K40f7vQr1mnNr8qAWCnoTAAgikkKbo6MqNEAEoS2xeKVosA7pGvwgtCW
+XSUCAwEAAaOCAUMwggE/MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD
+AgEGMC8GCCsGAQUFBwEBBCMwITAfBggrBgEFBQcwAYYTaHR0cDovL2cyLnN5bWNi
+LmNvbTBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93
+d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwNAYDVR0fBC0wKzApoCegJYYj
+aHR0cDovL2cxLnN5bWNiLmNvbS9HZW9UcnVzdFBDQS5jcmwwKQYDVR0RBCIwIKQe
+MBwxGjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTM4MB0GA1UdDgQWBBTez1xQt64C
+HxUXqhboDbUonWpa8zAfBgNVHSMEGDAWgBQs1VBBlxWL8I82YVtK+2vZmckzkjAN
+BgkqhkiG9w0BAQsFAAOCAQEAtI69B7mahew7Z70HYGHmhNHU7+sbuguCS5VktmZT
+I723hN3ke40J2s+y9fHDv4eEvk6mqMLnEjkoNOCkVkRADJ+IoxXT6NNe4xwEYPtp
+Nk9qfgwqKMHzqlgObM4dB8NKwJyNw3SxroLwGuH5Tim9Rt63Hfl929kPhMuSRcwc
+sxj2oM9xbwwum9Its5mTg0SsFaqbLmfsT4hpBVZ7i7JDqTpsHBMzJRv9qMhXAvsc
+4NG9O1ZEZcNj9Rvv7DDZ424uE+k5CCoMcvOazPYnKYTT70zHhBFlH8bjgQPbh8x4
+97Wdlj5qf7wRhXp15kF9Dc/55YVpJY/HjQct+GkPy0FTAA==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert17[] = {
+ 0x30, 0x82, 0x04, 0x6e, 0x30, 0x82, 0x03, 0x56, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x6e, 0x8a, 0x90, 0xeb, 0xcf, 0xf0, 0x44, 0x8a, 0x72,
+ 0x0d, 0x08, 0x05, 0xd0, 0x82, 0xa5, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x58,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
+ 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28,
+ 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
+ 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30,
+ 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32,
+ 0x33, 0x31, 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
+ 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x17, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
+ 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47,
+ 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+ 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd9, 0xb4,
+ 0x05, 0xf2, 0x38, 0x67, 0x0f, 0x09, 0xe7, 0x7c, 0xf5, 0x63, 0x2a, 0xe5,
+ 0xb9, 0x5e, 0xa8, 0x11, 0xae, 0x75, 0x71, 0xd9, 0x4c, 0x84, 0x67, 0xad,
+ 0x89, 0x5d, 0xfc, 0x28, 0x3d, 0x2a, 0xb0, 0xa5, 0xd5, 0xd4, 0xe6, 0x30,
+ 0x0a, 0x84, 0xd4, 0xe4, 0x18, 0xcb, 0x85, 0x37, 0xc5, 0x46, 0x71, 0xeb,
+ 0x1c, 0x7b, 0x69, 0xdb, 0x65, 0x69, 0x8c, 0x30, 0x05, 0x3e, 0x07, 0xe1,
+ 0x6f, 0x3c, 0xc1, 0x0b, 0x61, 0xe6, 0x38, 0x44, 0xfc, 0xbc, 0x8c, 0x2f,
+ 0x4e, 0x75, 0x57, 0xf5, 0x96, 0x99, 0x7c, 0x3e, 0x87, 0x1f, 0x0f, 0x90,
+ 0x4b, 0x70, 0xc3, 0x3f, 0x39, 0x45, 0x3b, 0x3a, 0x6b, 0xcb, 0xbb, 0x7b,
+ 0x40, 0x54, 0xd1, 0x8b, 0x4b, 0xa1, 0x72, 0xd2, 0x04, 0xe9, 0xe0, 0x72,
+ 0x1a, 0x93, 0x11, 0x7a, 0x2f, 0xf1, 0xab, 0x9d, 0x9c, 0x98, 0x58, 0xae,
+ 0x2c, 0xea, 0x77, 0x5f, 0x2f, 0x2e, 0x87, 0xaf, 0xb8, 0x6b, 0xe3, 0xe2,
+ 0xe2, 0x3f, 0xd6, 0x3d, 0xe0, 0x96, 0x44, 0xdf, 0x11, 0x55, 0x63, 0x52,
+ 0x2f, 0xf4, 0x26, 0x78, 0xc4, 0x0f, 0x20, 0x4d, 0x0a, 0xc0, 0x68, 0x70,
+ 0x15, 0x86, 0x38, 0xee, 0xb7, 0x76, 0x88, 0xab, 0x18, 0x8f, 0x4f, 0x35,
+ 0x1e, 0xd4, 0x8c, 0xc9, 0xdb, 0x7e, 0x3d, 0x44, 0xd4, 0x36, 0x8c, 0xc1,
+ 0x37, 0xb5, 0x59, 0x5b, 0x87, 0xf9, 0xe9, 0xf1, 0xd4, 0xc5, 0x28, 0xbd,
+ 0x1d, 0xdc, 0xcc, 0x96, 0x72, 0xd1, 0x7a, 0xa1, 0xa7, 0x20, 0xb5, 0xb8,
+ 0xaf, 0xf8, 0x6e, 0xa5, 0x60, 0x7b, 0x2b, 0x8d, 0x1f, 0xee, 0xf4, 0x2b,
+ 0xd6, 0x69, 0xcd, 0xaf, 0xca, 0x80, 0x58, 0x29, 0xe8, 0x4c, 0x00, 0x20,
+ 0x8a, 0x49, 0x0a, 0x6e, 0x8e, 0x8c, 0xa8, 0xd1, 0x00, 0x12, 0x84, 0xb6,
+ 0xc5, 0xe2, 0x95, 0xa2, 0xc0, 0x3b, 0xa4, 0x6b, 0xf0, 0x82, 0xd0, 0x96,
+ 0x5d, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x43, 0x30,
+ 0x82, 0x01, 0x3f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
+ 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
+ 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30,
+ 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+ 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
+ 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+ 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79,
+ 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+ 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e,
+ 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49,
+ 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x38, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0xde, 0xcf, 0x5c, 0x50, 0xb7, 0xae, 0x02,
+ 0x1f, 0x15, 0x17, 0xaa, 0x16, 0xe8, 0x0d, 0xb5, 0x28, 0x9d, 0x6a, 0x5a,
+ 0xf3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0x2c, 0xd5, 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36,
+ 0x61, 0x5b, 0x4a, 0xfb, 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb4, 0x8e, 0xbd, 0x07, 0xb9, 0x9a,
+ 0x85, 0xec, 0x3b, 0x67, 0xbd, 0x07, 0x60, 0x61, 0xe6, 0x84, 0xd1, 0xd4,
+ 0xef, 0xeb, 0x1b, 0xba, 0x0b, 0x82, 0x4b, 0x95, 0x64, 0xb6, 0x66, 0x53,
+ 0x23, 0xbd, 0xb7, 0x84, 0xdd, 0xe4, 0x7b, 0x8d, 0x09, 0xda, 0xcf, 0xb2,
+ 0xf5, 0xf1, 0xc3, 0xbf, 0x87, 0x84, 0xbe, 0x4e, 0xa6, 0xa8, 0xc2, 0xe7,
+ 0x12, 0x39, 0x28, 0x34, 0xe0, 0xa4, 0x56, 0x44, 0x40, 0x0c, 0x9f, 0x88,
+ 0xa3, 0x15, 0xd3, 0xe8, 0xd3, 0x5e, 0xe3, 0x1c, 0x04, 0x60, 0xfb, 0x69,
+ 0x36, 0x4f, 0x6a, 0x7e, 0x0c, 0x2a, 0x28, 0xc1, 0xf3, 0xaa, 0x58, 0x0e,
+ 0x6c, 0xce, 0x1d, 0x07, 0xc3, 0x4a, 0xc0, 0x9c, 0x8d, 0xc3, 0x74, 0xb1,
+ 0xae, 0x82, 0xf0, 0x1a, 0xe1, 0xf9, 0x4e, 0x29, 0xbd, 0x46, 0xde, 0xb7,
+ 0x1d, 0xf9, 0x7d, 0xdb, 0xd9, 0x0f, 0x84, 0xcb, 0x92, 0x45, 0xcc, 0x1c,
+ 0xb3, 0x18, 0xf6, 0xa0, 0xcf, 0x71, 0x6f, 0x0c, 0x2e, 0x9b, 0xd2, 0x2d,
+ 0xb3, 0x99, 0x93, 0x83, 0x44, 0xac, 0x15, 0xaa, 0x9b, 0x2e, 0x67, 0xec,
+ 0x4f, 0x88, 0x69, 0x05, 0x56, 0x7b, 0x8b, 0xb2, 0x43, 0xa9, 0x3a, 0x6c,
+ 0x1c, 0x13, 0x33, 0x25, 0x1b, 0xfd, 0xa8, 0xc8, 0x57, 0x02, 0xfb, 0x1c,
+ 0xe0, 0xd1, 0xbd, 0x3b, 0x56, 0x44, 0x65, 0xc3, 0x63, 0xf5, 0x1b, 0xef,
+ 0xec, 0x30, 0xd9, 0xe3, 0x6e, 0x2e, 0x13, 0xe9, 0x39, 0x08, 0x2a, 0x0c,
+ 0x72, 0xf3, 0x9a, 0xcc, 0xf6, 0x27, 0x29, 0x84, 0xd3, 0xef, 0x4c, 0xc7,
+ 0x84, 0x11, 0x65, 0x1f, 0xc6, 0xe3, 0x81, 0x03, 0xdb, 0x87, 0xcc, 0x78,
+ 0xf7, 0xb5, 0x9d, 0x96, 0x3e, 0x6a, 0x7f, 0xbc, 0x11, 0x85, 0x7a, 0x75,
+ 0xe6, 0x41, 0x7d, 0x0d, 0xcf, 0xf9, 0xe5, 0x85, 0x69, 0x25, 0x8f, 0xc7,
+ 0x8d, 0x07, 0x2d, 0xf8, 0x69, 0x0f, 0xcb, 0x41, 0x53, 0x00,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1828629 (0x1be715)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
+ Validity
+ Not Before: Jan 1 07:00:00 2014 GMT
+ Not After : May 30 07:00:00 2031 GMT
+ Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7:
+ 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1:
+ e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98:
+ c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30:
+ 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39:
+ 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f:
+ a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19:
+ 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00:
+ 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60:
+ b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d:
+ 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61:
+ 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e:
+ 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1:
+ 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56:
+ 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d:
+ 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f:
+ 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3:
+ e0:47
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
+ X509v3 Authority Key Identifier:
+ keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.godaddy.com/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.godaddy.com/gdroot.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://certs.godaddy.com/repository/
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 59:0b:53:bd:92:86:11:a7:24:7b:ed:5b:31:cf:1d:1f:6c:70:
+ c5:b8:6e:be:4e:bb:f6:be:97:50:e1:30:7f:ba:28:5c:62:94:
+ c2:e3:7e:33:f7:fb:42:76:85:db:95:1c:8c:22:58:75:09:0c:
+ 88:65:67:39:0a:16:09:c5:a0:38:97:a4:c5:23:93:3f:b4:18:
+ a6:01:06:44:91:e3:a7:69:27:b4:5a:25:7f:3a:b7:32:cd:dd:
+ 84:ff:2a:38:29:33:a4:dd:67:b2:85:fe:a1:88:20:1c:50:89:
+ c8:dc:2a:f6:42:03:37:4c:e6:88:df:d5:af:24:f2:b1:c3:df:
+ cc:b5:ec:e0:99:5e:b7:49:54:20:3c:94:18:0c:c7:1c:52:18:
+ 49:a4:6d:e1:b3:58:0b:c9:d8:ec:d9:ae:1c:32:8e:28:70:0d:
+ e2:fe:a6:17:9e:84:0f:bd:57:70:b3:5a:e9:1f:a0:86:53:bb:
+ ef:7c:ff:69:0b:e0:48:c3:b7:93:0b:c8:0a:54:c4:ac:5d:14:
+ 67:37:6c:ca:a5:2f:31:08:37:aa:6e:6f:8c:bc:9b:e2:57:5d:
+ 24:81:af:97:97:9c:84:ad:6c:ac:37:4c:66:f3:61:91:11:20:
+ e4:be:30:9f:7a:a4:29:09:b0:e1:34:5f:64:77:18:40:51:df:
+ 8c:30:a6:af
+-----BEGIN CERTIFICATE-----
+MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT
+MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv
+IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx
+MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
+B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku
+Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1
+dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi
+CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H
+Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/
+3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+
+6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI
+gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E
+GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud
+IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr
+BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al
+oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9
+MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv
+bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d
+H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg
+OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq
+9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO
+KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3
+qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm
+rw==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert18[] = {
+ 0x30, 0x82, 0x04, 0x7d, 0x30, 0x82, 0x03, 0x65, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x1b, 0xe7, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x63, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54,
+ 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20,
+ 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+ 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f,
+ 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
+ 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x31, 0x30, 0x31,
+ 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30,
+ 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81,
+ 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+ 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11,
+ 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74,
+ 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55,
+ 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30,
+ 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44,
+ 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32,
+ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbf, 0x71, 0x62,
+ 0x08, 0xf1, 0xfa, 0x59, 0x34, 0xf7, 0x1b, 0xc9, 0x18, 0xa3, 0xf7, 0x80,
+ 0x49, 0x58, 0xe9, 0x22, 0x83, 0x13, 0xa6, 0xc5, 0x20, 0x43, 0x01, 0x3b,
+ 0x84, 0xf1, 0xe6, 0x85, 0x49, 0x9f, 0x27, 0xea, 0xf6, 0x84, 0x1b, 0x4e,
+ 0xa0, 0xb4, 0xdb, 0x70, 0x98, 0xc7, 0x32, 0x01, 0xb1, 0x05, 0x3e, 0x07,
+ 0x4e, 0xee, 0xf4, 0xfa, 0x4f, 0x2f, 0x59, 0x30, 0x22, 0xe7, 0xab, 0x19,
+ 0x56, 0x6b, 0xe2, 0x80, 0x07, 0xfc, 0xf3, 0x16, 0x75, 0x80, 0x39, 0x51,
+ 0x7b, 0xe5, 0xf9, 0x35, 0xb6, 0x74, 0x4e, 0xa9, 0x8d, 0x82, 0x13, 0xe4,
+ 0xb6, 0x3f, 0xa9, 0x03, 0x83, 0xfa, 0xa2, 0xbe, 0x8a, 0x15, 0x6a, 0x7f,
+ 0xde, 0x0b, 0xc3, 0xb6, 0x19, 0x14, 0x05, 0xca, 0xea, 0xc3, 0xa8, 0x04,
+ 0x94, 0x3b, 0x46, 0x7c, 0x32, 0x0d, 0xf3, 0x00, 0x66, 0x22, 0xc8, 0x8d,
+ 0x69, 0x6d, 0x36, 0x8c, 0x11, 0x18, 0xb7, 0xd3, 0xb2, 0x1c, 0x60, 0xb4,
+ 0x38, 0xfa, 0x02, 0x8c, 0xce, 0xd3, 0xdd, 0x46, 0x07, 0xde, 0x0a, 0x3e,
+ 0xeb, 0x5d, 0x7c, 0xc8, 0x7c, 0xfb, 0xb0, 0x2b, 0x53, 0xa4, 0x92, 0x62,
+ 0x69, 0x51, 0x25, 0x05, 0x61, 0x1a, 0x44, 0x81, 0x8c, 0x2c, 0xa9, 0x43,
+ 0x96, 0x23, 0xdf, 0xac, 0x3a, 0x81, 0x9a, 0x0e, 0x29, 0xc5, 0x1c, 0xa9,
+ 0xe9, 0x5d, 0x1e, 0xb6, 0x9e, 0x9e, 0x30, 0x0a, 0x39, 0xce, 0xf1, 0x88,
+ 0x80, 0xfb, 0x4b, 0x5d, 0xcc, 0x32, 0xec, 0x85, 0x62, 0x43, 0x25, 0x34,
+ 0x02, 0x56, 0x27, 0x01, 0x91, 0xb4, 0x3b, 0x70, 0x2a, 0x3f, 0x6e, 0xb1,
+ 0xe8, 0x9c, 0x88, 0x01, 0x7d, 0x9f, 0xd4, 0xf9, 0xdb, 0x53, 0x6d, 0x60,
+ 0x9d, 0xbf, 0x2c, 0xe7, 0x58, 0xab, 0xb8, 0x5f, 0x46, 0xfc, 0xce, 0xc4,
+ 0x1b, 0x03, 0x3c, 0x09, 0xeb, 0x49, 0x31, 0x5c, 0x69, 0x46, 0xb3, 0xe0,
+ 0x47, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x17, 0x30, 0x82,
+ 0x01, 0x13, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+ 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3a, 0x9a,
+ 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef, 0xf6, 0xbd, 0x05, 0x41, 0x6e,
+ 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, 0x91,
+ 0xd4, 0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, 0xa8,
+ 0x6a, 0xd4, 0xe3, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
+ 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x32, 0x06,
+ 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25,
+ 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+ 0x72, 0x6c, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x67, 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
+ 0x6c, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d,
+ 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25,
+ 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74,
+ 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
+ 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x0b, 0x53,
+ 0xbd, 0x92, 0x86, 0x11, 0xa7, 0x24, 0x7b, 0xed, 0x5b, 0x31, 0xcf, 0x1d,
+ 0x1f, 0x6c, 0x70, 0xc5, 0xb8, 0x6e, 0xbe, 0x4e, 0xbb, 0xf6, 0xbe, 0x97,
+ 0x50, 0xe1, 0x30, 0x7f, 0xba, 0x28, 0x5c, 0x62, 0x94, 0xc2, 0xe3, 0x7e,
+ 0x33, 0xf7, 0xfb, 0x42, 0x76, 0x85, 0xdb, 0x95, 0x1c, 0x8c, 0x22, 0x58,
+ 0x75, 0x09, 0x0c, 0x88, 0x65, 0x67, 0x39, 0x0a, 0x16, 0x09, 0xc5, 0xa0,
+ 0x38, 0x97, 0xa4, 0xc5, 0x23, 0x93, 0x3f, 0xb4, 0x18, 0xa6, 0x01, 0x06,
+ 0x44, 0x91, 0xe3, 0xa7, 0x69, 0x27, 0xb4, 0x5a, 0x25, 0x7f, 0x3a, 0xb7,
+ 0x32, 0xcd, 0xdd, 0x84, 0xff, 0x2a, 0x38, 0x29, 0x33, 0xa4, 0xdd, 0x67,
+ 0xb2, 0x85, 0xfe, 0xa1, 0x88, 0x20, 0x1c, 0x50, 0x89, 0xc8, 0xdc, 0x2a,
+ 0xf6, 0x42, 0x03, 0x37, 0x4c, 0xe6, 0x88, 0xdf, 0xd5, 0xaf, 0x24, 0xf2,
+ 0xb1, 0xc3, 0xdf, 0xcc, 0xb5, 0xec, 0xe0, 0x99, 0x5e, 0xb7, 0x49, 0x54,
+ 0x20, 0x3c, 0x94, 0x18, 0x0c, 0xc7, 0x1c, 0x52, 0x18, 0x49, 0xa4, 0x6d,
+ 0xe1, 0xb3, 0x58, 0x0b, 0xc9, 0xd8, 0xec, 0xd9, 0xae, 0x1c, 0x32, 0x8e,
+ 0x28, 0x70, 0x0d, 0xe2, 0xfe, 0xa6, 0x17, 0x9e, 0x84, 0x0f, 0xbd, 0x57,
+ 0x70, 0xb3, 0x5a, 0xe9, 0x1f, 0xa0, 0x86, 0x53, 0xbb, 0xef, 0x7c, 0xff,
+ 0x69, 0x0b, 0xe0, 0x48, 0xc3, 0xb7, 0x93, 0x0b, 0xc8, 0x0a, 0x54, 0xc4,
+ 0xac, 0x5d, 0x14, 0x67, 0x37, 0x6c, 0xca, 0xa5, 0x2f, 0x31, 0x08, 0x37,
+ 0xaa, 0x6e, 0x6f, 0x8c, 0xbc, 0x9b, 0xe2, 0x57, 0x5d, 0x24, 0x81, 0xaf,
+ 0x97, 0x97, 0x9c, 0x84, 0xad, 0x6c, 0xac, 0x37, 0x4c, 0x66, 0xf3, 0x61,
+ 0x91, 0x11, 0x20, 0xe4, 0xbe, 0x30, 0x9f, 0x7a, 0xa4, 0x29, 0x09, 0xb0,
+ 0xe1, 0x34, 0x5f, 0x64, 0x77, 0x18, 0x40, 0x51, 0xdf, 0x8c, 0x30, 0xa6,
+ 0xaf,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 06:9e:1d:b7:7f:cf:1d:fb:a9:7a:f5:e5:c9:a2:40:37
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ Validity
+ Not Before: Mar 8 12:00:00 2013 GMT
+ Not After : Mar 8 12:00:00 2023 GMT
+ Subject: C=US, O=DigiCert Inc, CN=DigiCert Secure Server CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bb:57:e4:21:a9:d5:9b:60:37:7e:8e:a1:61:7f:
+ 81:e2:1a:c2:75:64:d9:91:50:0b:e4:36:44:24:6e:
+ 30:d2:9b:7a:27:fa:c2:6a:ae:6a:70:09:38:b9:20:
+ 0a:c8:65:10:4a:88:ac:31:f2:dc:92:f2:63:a1:5d:
+ 80:63:59:80:92:23:1c:e6:ef:76:4a:50:35:c9:d8:
+ 71:38:b9:ed:f0:e6:42:ae:d3:38:26:79:30:f9:22:
+ 94:c6:db:a6:3f:41:78:90:d8:de:5c:7e:69:7d:f8:
+ 90:15:3a:d0:a1:a0:be:fa:b2:b2:19:a1:d8:2b:d1:
+ ce:bf:6b:dd:49:ab:a3:92:fe:b5:ab:c8:c1:3e:ee:
+ 01:00:d8:a9:44:b8:42:73:88:c3:61:f5:ab:4a:83:
+ 28:0a:d2:d4:49:fa:6a:b1:cd:df:57:2c:94:e5:e2:
+ ca:83:5f:b7:ba:62:5c:2f:68:a5:f0:c0:b9:fd:2b:
+ d1:e9:1f:d8:1a:62:15:bd:ff:3d:a6:f7:cb:ef:e6:
+ db:65:2f:25:38:ec:fb:e6:20:66:58:96:34:19:d2:
+ 15:ce:21:d3:24:cc:d9:14:6f:d8:fe:55:c7:e7:6f:
+ b6:0f:1a:8c:49:be:29:f2:ba:5a:9a:81:26:37:24:
+ 6f:d7:48:12:6c:2e:59:f5:9c:18:bb:d9:f6:68:e2:
+ df:45
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://ocsp.digicert.com
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
+
+ Full Name:
+ URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.digicert.com/CPS
+
+ X509v3 Subject Key Identifier:
+ 90:71:DB:37:EB:73:C8:EF:DC:D5:1E:12:B6:34:BA:2B:5A:A0:A6:92
+ X509v3 Authority Key Identifier:
+ keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 30:ce:d1:95:51:00:ae:06:0b:a1:0e:02:c0:17:ac:b6:7f:8f:
+ 20:f6:40:75:74:1c:cc:78:b1:a4:4f:ea:f4:d0:c4:9d:a2:de:
+ 81:07:26:1f:40:88:51:f0:1f:cf:b7:4c:40:99:d0:f4:3c:71:
+ 98:73:88:97:2c:19:d7:6e:84:8f:a4:1f:9c:5a:20:e3:51:5c:
+ b0:c5:9e:99:6a:4f:c8:69:f7:10:ff:4e:ad:19:d9:c9:58:b3:
+ 33:ae:0c:d9:96:29:9e:71:b2:70:63:a3:b6:99:16:42:1d:65:
+ f3:f7:a0:1e:7d:c5:d4:65:14:b2:62:84:d4:6c:5c:08:0c:d8:
+ 6c:93:2b:b4:76:59:8a:d1:7f:ff:03:d8:c2:5d:b8:2f:22:d6:
+ 38:f0:f6:9c:6b:7d:46:eb:99:74:f7:eb:4a:0e:a9:a6:04:eb:
+ 7b:ce:f0:5c:6b:98:31:5a:98:40:eb:69:c4:05:f4:20:a8:ca:
+ 08:3a:65:6c:38:15:f5:5c:2c:b2:55:e4:2c:6b:41:f0:be:5c:
+ 46:ca:4a:29:a0:48:5e:20:d2:45:ff:05:de:34:af:70:4b:81:
+ 39:e2:ca:07:57:7c:b6:31:dc:21:29:e2:be:97:0e:77:90:14:
+ 51:40:e1:bf:e3:cc:1b:19:9c:25:ca:a7:06:b2:53:df:23:b2:
+ cf:12:19:a3
+-----BEGIN CERTIFICATE-----
+MIIEjzCCA3egAwIBAgIQBp4dt3/PHfupevXlyaJANzANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEgxCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxIjAgBgNVBAMTGURpZ2lDZXJ0IFNlY3Vy
+ZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7V+Qh
+qdWbYDd+jqFhf4HiGsJ1ZNmRUAvkNkQkbjDSm3on+sJqrmpwCTi5IArIZRBKiKwx
+8tyS8mOhXYBjWYCSIxzm73ZKUDXJ2HE4ue3w5kKu0zgmeTD5IpTG26Y/QXiQ2N5c
+fml9+JAVOtChoL76srIZodgr0c6/a91Jq6OS/rWryME+7gEA2KlEuEJziMNh9atK
+gygK0tRJ+mqxzd9XLJTl4sqDX7e6YlwvaKXwwLn9K9HpH9gaYhW9/z2m98vv5ttl
+LyU47PvmIGZYljQZ0hXOIdMkzNkUb9j+Vcfnb7YPGoxJvinyulqagSY3JG/XSBJs
+Lln1nBi72fZo4t9FAgMBAAGjggFaMIIBVjASBgNVHRMBAf8ECDAGAQH/AgEAMA4G
+A1UdDwEB/wQEAwIBhjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6
+Ly9vY3NwLmRpZ2ljZXJ0LmNvbTB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3Js
+My5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3JsMDegNaAzhjFo
+dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3Js
+MD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k
+aWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBSQcds363PI79zVHhK2NLorWqCmkjAf
+BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTANBgkqhkiG9w0BAQUFAAOC
+AQEAMM7RlVEArgYLoQ4CwBestn+PIPZAdXQczHixpE/q9NDEnaLegQcmH0CIUfAf
+z7dMQJnQ9DxxmHOIlywZ126Ej6QfnFog41FcsMWemWpPyGn3EP9OrRnZyVizM64M
+2ZYpnnGycGOjtpkWQh1l8/egHn3F1GUUsmKE1GxcCAzYbJMrtHZZitF//wPYwl24
+LyLWOPD2nGt9RuuZdPfrSg6ppgTre87wXGuYMVqYQOtpxAX0IKjKCDplbDgV9Vws
+slXkLGtB8L5cRspKKaBIXiDSRf8F3jSvcEuBOeLKB1d8tjHcISnivpcOd5AUUUDh
+v+PMGxmcJcqnBrJT3yOyzxIZow==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert19[] = {
+ 0x30, 0x82, 0x04, 0x8f, 0x30, 0x82, 0x03, 0x77, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x06, 0x9e, 0x1d, 0xb7, 0x7f, 0xcf, 0x1d, 0xfb, 0xa9,
+ 0x7a, 0xf5, 0xe5, 0xc9, 0xa2, 0x40, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x61,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
+ 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
+ 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31,
+ 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33,
+ 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x48, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44,
+ 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31,
+ 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x44, 0x69,
+ 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
+ 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30,
+ 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+ 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbb, 0x57, 0xe4, 0x21,
+ 0xa9, 0xd5, 0x9b, 0x60, 0x37, 0x7e, 0x8e, 0xa1, 0x61, 0x7f, 0x81, 0xe2,
+ 0x1a, 0xc2, 0x75, 0x64, 0xd9, 0x91, 0x50, 0x0b, 0xe4, 0x36, 0x44, 0x24,
+ 0x6e, 0x30, 0xd2, 0x9b, 0x7a, 0x27, 0xfa, 0xc2, 0x6a, 0xae, 0x6a, 0x70,
+ 0x09, 0x38, 0xb9, 0x20, 0x0a, 0xc8, 0x65, 0x10, 0x4a, 0x88, 0xac, 0x31,
+ 0xf2, 0xdc, 0x92, 0xf2, 0x63, 0xa1, 0x5d, 0x80, 0x63, 0x59, 0x80, 0x92,
+ 0x23, 0x1c, 0xe6, 0xef, 0x76, 0x4a, 0x50, 0x35, 0xc9, 0xd8, 0x71, 0x38,
+ 0xb9, 0xed, 0xf0, 0xe6, 0x42, 0xae, 0xd3, 0x38, 0x26, 0x79, 0x30, 0xf9,
+ 0x22, 0x94, 0xc6, 0xdb, 0xa6, 0x3f, 0x41, 0x78, 0x90, 0xd8, 0xde, 0x5c,
+ 0x7e, 0x69, 0x7d, 0xf8, 0x90, 0x15, 0x3a, 0xd0, 0xa1, 0xa0, 0xbe, 0xfa,
+ 0xb2, 0xb2, 0x19, 0xa1, 0xd8, 0x2b, 0xd1, 0xce, 0xbf, 0x6b, 0xdd, 0x49,
+ 0xab, 0xa3, 0x92, 0xfe, 0xb5, 0xab, 0xc8, 0xc1, 0x3e, 0xee, 0x01, 0x00,
+ 0xd8, 0xa9, 0x44, 0xb8, 0x42, 0x73, 0x88, 0xc3, 0x61, 0xf5, 0xab, 0x4a,
+ 0x83, 0x28, 0x0a, 0xd2, 0xd4, 0x49, 0xfa, 0x6a, 0xb1, 0xcd, 0xdf, 0x57,
+ 0x2c, 0x94, 0xe5, 0xe2, 0xca, 0x83, 0x5f, 0xb7, 0xba, 0x62, 0x5c, 0x2f,
+ 0x68, 0xa5, 0xf0, 0xc0, 0xb9, 0xfd, 0x2b, 0xd1, 0xe9, 0x1f, 0xd8, 0x1a,
+ 0x62, 0x15, 0xbd, 0xff, 0x3d, 0xa6, 0xf7, 0xcb, 0xef, 0xe6, 0xdb, 0x65,
+ 0x2f, 0x25, 0x38, 0xec, 0xfb, 0xe6, 0x20, 0x66, 0x58, 0x96, 0x34, 0x19,
+ 0xd2, 0x15, 0xce, 0x21, 0xd3, 0x24, 0xcc, 0xd9, 0x14, 0x6f, 0xd8, 0xfe,
+ 0x55, 0xc7, 0xe7, 0x6f, 0xb6, 0x0f, 0x1a, 0x8c, 0x49, 0xbe, 0x29, 0xf2,
+ 0xba, 0x5a, 0x9a, 0x81, 0x26, 0x37, 0x24, 0x6f, 0xd7, 0x48, 0x12, 0x6c,
+ 0x2e, 0x59, 0xf5, 0x9c, 0x18, 0xbb, 0xd9, 0xf6, 0x68, 0xe2, 0xdf, 0x45,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5a, 0x30, 0x82, 0x01,
+ 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+ 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+ 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
+ 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63,
+ 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x7b, 0x06, 0x03, 0x55,
+ 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33,
+ 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+ 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x47,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64,
+ 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c,
+ 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30,
+ 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
+ 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64,
+ 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+ 0x04, 0x14, 0x90, 0x71, 0xdb, 0x37, 0xeb, 0x73, 0xc8, 0xef, 0xdc, 0xd5,
+ 0x1e, 0x12, 0xb6, 0x34, 0xba, 0x2b, 0x5a, 0xa0, 0xa6, 0x92, 0x30, 0x1f,
+ 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x03,
+ 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, 0x66, 0xf0, 0xa3, 0xe2, 0x1b,
+ 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x01, 0x00, 0x30, 0xce, 0xd1, 0x95, 0x51, 0x00, 0xae, 0x06, 0x0b,
+ 0xa1, 0x0e, 0x02, 0xc0, 0x17, 0xac, 0xb6, 0x7f, 0x8f, 0x20, 0xf6, 0x40,
+ 0x75, 0x74, 0x1c, 0xcc, 0x78, 0xb1, 0xa4, 0x4f, 0xea, 0xf4, 0xd0, 0xc4,
+ 0x9d, 0xa2, 0xde, 0x81, 0x07, 0x26, 0x1f, 0x40, 0x88, 0x51, 0xf0, 0x1f,
+ 0xcf, 0xb7, 0x4c, 0x40, 0x99, 0xd0, 0xf4, 0x3c, 0x71, 0x98, 0x73, 0x88,
+ 0x97, 0x2c, 0x19, 0xd7, 0x6e, 0x84, 0x8f, 0xa4, 0x1f, 0x9c, 0x5a, 0x20,
+ 0xe3, 0x51, 0x5c, 0xb0, 0xc5, 0x9e, 0x99, 0x6a, 0x4f, 0xc8, 0x69, 0xf7,
+ 0x10, 0xff, 0x4e, 0xad, 0x19, 0xd9, 0xc9, 0x58, 0xb3, 0x33, 0xae, 0x0c,
+ 0xd9, 0x96, 0x29, 0x9e, 0x71, 0xb2, 0x70, 0x63, 0xa3, 0xb6, 0x99, 0x16,
+ 0x42, 0x1d, 0x65, 0xf3, 0xf7, 0xa0, 0x1e, 0x7d, 0xc5, 0xd4, 0x65, 0x14,
+ 0xb2, 0x62, 0x84, 0xd4, 0x6c, 0x5c, 0x08, 0x0c, 0xd8, 0x6c, 0x93, 0x2b,
+ 0xb4, 0x76, 0x59, 0x8a, 0xd1, 0x7f, 0xff, 0x03, 0xd8, 0xc2, 0x5d, 0xb8,
+ 0x2f, 0x22, 0xd6, 0x38, 0xf0, 0xf6, 0x9c, 0x6b, 0x7d, 0x46, 0xeb, 0x99,
+ 0x74, 0xf7, 0xeb, 0x4a, 0x0e, 0xa9, 0xa6, 0x04, 0xeb, 0x7b, 0xce, 0xf0,
+ 0x5c, 0x6b, 0x98, 0x31, 0x5a, 0x98, 0x40, 0xeb, 0x69, 0xc4, 0x05, 0xf4,
+ 0x20, 0xa8, 0xca, 0x08, 0x3a, 0x65, 0x6c, 0x38, 0x15, 0xf5, 0x5c, 0x2c,
+ 0xb2, 0x55, 0xe4, 0x2c, 0x6b, 0x41, 0xf0, 0xbe, 0x5c, 0x46, 0xca, 0x4a,
+ 0x29, 0xa0, 0x48, 0x5e, 0x20, 0xd2, 0x45, 0xff, 0x05, 0xde, 0x34, 0xaf,
+ 0x70, 0x4b, 0x81, 0x39, 0xe2, 0xca, 0x07, 0x57, 0x7c, 0xb6, 0x31, 0xdc,
+ 0x21, 0x29, 0xe2, 0xbe, 0x97, 0x0e, 0x77, 0x90, 0x14, 0x51, 0x40, 0xe1,
+ 0xbf, 0xe3, 0xcc, 0x1b, 0x19, 0x9c, 0x25, 0xca, 0xa7, 0x06, 0xb2, 0x53,
+ 0xdf, 0x23, 0xb2, 0xcf, 0x12, 0x19, 0xa3,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 1b:09:3b:78:60:96:da:37:bb:a4:51:94:46:c8:96:78
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ Validity
+ Not Before: Nov 8 00:00:00 2006 GMT
+ Not After : Nov 7 23:59:59 2021 GMT
+ Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
+ 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
+ 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
+ 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
+ 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
+ a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
+ 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
+ d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
+ 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
+ bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
+ f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
+ ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
+ f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
+ 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
+ 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
+ ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
+ 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
+ 25:15
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.verisign.com/pca3.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.verisign.com/cps
+
+ X509v3 Subject Key Identifier:
+ 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+ 1.3.6.1.5.5.7.1.12:
+ 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
+ Authority Information Access:
+ OCSP - URI:http://ocsp.verisign.com
+
+ Signature Algorithm: sha1WithRSAEncryption
+ a3:cd:7d:1e:f7:c7:75:8d:48:e7:56:34:4c:00:90:75:a9:51:
+ a5:56:c1:6d:bc:fe:f5:53:22:e9:98:a2:ac:9a:7e:70:1e:b3:
+ 8e:3b:45:e3:86:95:31:da:6d:4c:fb:34:50:80:96:cd:24:f2:
+ 40:df:04:3f:e2:65:ce:34:22:61:15:ea:66:70:64:d2:f1:6e:
+ f3:ca:18:59:6a:41:46:7e:82:de:19:b0:70:31:56:69:0d:0c:
+ e6:1d:9d:71:58:dc:cc:de:62:f5:e1:7a:10:02:d8:7a:dc:3b:
+ fa:57:bd:c9:e9:8f:46:21:39:9f:51:65:4c:8e:3a:be:28:41:
+ 70:1d
+-----BEGIN CERTIFICATE-----
+MIIEkDCCA/mgAwIBAgIQGwk7eGCW2je7pFGURsiWeDANBgkqhkiG9w0BAQUFADBf
+MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
+LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
+FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
+dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
+ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
+RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
+ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
+TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
+Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
+iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
+AAGjggFbMIIBVzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
+dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
+BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
+aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI
+KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU
+j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t
+L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
+b2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAo819HvfHdY1I51Y0
+TACQdalRpVbBbbz+9VMi6ZiirJp+cB6zjjtF44aVMdptTPs0UICWzSTyQN8EP+Jl
+zjQiYRXqZnBk0vFu88oYWWpBRn6C3hmwcDFWaQ0M5h2dcVjczN5i9eF6EALYetw7
++le9yemPRiE5n1FlTI46vihBcB0=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert20[] = {
+ 0x30, 0x82, 0x04, 0x90, 0x30, 0x82, 0x03, 0xf9, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x1b, 0x09, 0x3b, 0x78, 0x60, 0x96, 0xda, 0x37, 0xbb,
+ 0xa4, 0x51, 0x94, 0x46, 0xc8, 0x96, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
+ 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
+ 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+ 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
+ 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
+ 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
+ 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+ 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
+ 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
+ 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
+ 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+ 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+ 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
+ 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
+ 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
+ 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
+ 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
+ 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
+ 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
+ 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
+ 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
+ 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
+ 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
+ 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
+ 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
+ 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
+ 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
+ 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
+ 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
+ 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
+ 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
+ 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
+ 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
+ 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5b, 0x30, 0x82, 0x01, 0x57, 0x30, 0x0f,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
+ 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
+ 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
+ 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
+ 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
+ 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
+ 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
+ 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
+ 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f,
+ 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
+ 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30,
+ 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
+ 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80,
+ 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30,
+ 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
+ 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00,
+ 0xa3, 0xcd, 0x7d, 0x1e, 0xf7, 0xc7, 0x75, 0x8d, 0x48, 0xe7, 0x56, 0x34,
+ 0x4c, 0x00, 0x90, 0x75, 0xa9, 0x51, 0xa5, 0x56, 0xc1, 0x6d, 0xbc, 0xfe,
+ 0xf5, 0x53, 0x22, 0xe9, 0x98, 0xa2, 0xac, 0x9a, 0x7e, 0x70, 0x1e, 0xb3,
+ 0x8e, 0x3b, 0x45, 0xe3, 0x86, 0x95, 0x31, 0xda, 0x6d, 0x4c, 0xfb, 0x34,
+ 0x50, 0x80, 0x96, 0xcd, 0x24, 0xf2, 0x40, 0xdf, 0x04, 0x3f, 0xe2, 0x65,
+ 0xce, 0x34, 0x22, 0x61, 0x15, 0xea, 0x66, 0x70, 0x64, 0xd2, 0xf1, 0x6e,
+ 0xf3, 0xca, 0x18, 0x59, 0x6a, 0x41, 0x46, 0x7e, 0x82, 0xde, 0x19, 0xb0,
+ 0x70, 0x31, 0x56, 0x69, 0x0d, 0x0c, 0xe6, 0x1d, 0x9d, 0x71, 0x58, 0xdc,
+ 0xcc, 0xde, 0x62, 0xf5, 0xe1, 0x7a, 0x10, 0x02, 0xd8, 0x7a, 0xdc, 0x3b,
+ 0xfa, 0x57, 0xbd, 0xc9, 0xe9, 0x8f, 0x46, 0x21, 0x39, 0x9f, 0x51, 0x65,
+ 0x4c, 0x8e, 0x3a, 0xbe, 0x28, 0x41, 0x70, 0x1d,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 01:fd:a3:eb:6e:ca:75:c8:88:43:8b:72:4b:cf:bc:91
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ Validity
+ Not Before: Mar 8 12:00:00 2013 GMT
+ Not After : Mar 8 12:00:00 2023 GMT
+ Subject: C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:dc:ae:58:90:4d:c1:c4:30:15:90:35:5b:6e:3c:
+ 82:15:f5:2c:5c:bd:e3:db:ff:71:43:fa:64:25:80:
+ d4:ee:18:a2:4d:f0:66:d0:0a:73:6e:11:98:36:17:
+ 64:af:37:9d:fd:fa:41:84:af:c7:af:8c:fe:1a:73:
+ 4d:cf:33:97:90:a2:96:87:53:83:2b:b9:a6:75:48:
+ 2d:1d:56:37:7b:da:31:32:1a:d7:ac:ab:06:f4:aa:
+ 5d:4b:b7:47:46:dd:2a:93:c3:90:2e:79:80:80:ef:
+ 13:04:6a:14:3b:b5:9b:92:be:c2:07:65:4e:fc:da:
+ fc:ff:7a:ae:dc:5c:7e:55:31:0c:e8:39:07:a4:d7:
+ be:2f:d3:0b:6a:d2:b1:df:5f:fe:57:74:53:3b:35:
+ 80:dd:ae:8e:44:98:b3:9f:0e:d3:da:e0:d7:f4:6b:
+ 29:ab:44:a7:4b:58:84:6d:92:4b:81:c3:da:73:8b:
+ 12:97:48:90:04:45:75:1a:dd:37:31:97:92:e8:cd:
+ 54:0d:3b:e4:c1:3f:39:5e:2e:b8:f3:5c:7e:10:8e:
+ 86:41:00:8d:45:66:47:b0:a1:65:ce:a0:aa:29:09:
+ 4e:f3:97:eb:e8:2e:ab:0f:72:a7:30:0e:fa:c7:f4:
+ fd:14:77:c3:a4:5b:28:57:c2:b3:f9:82:fd:b7:45:
+ 58:9b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://ocsp.digicert.com
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
+
+ Full Name:
+ URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.digicert.com/CPS
+
+ X509v3 Subject Key Identifier:
+ 0F:80:61:1C:82:31:61:D5:2F:28:E7:8D:46:38:B4:2C:E1:C6:D9:E2
+ X509v3 Authority Key Identifier:
+ keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 23:3e:df:4b:d2:31:42:a5:b6:7e:42:5c:1a:44:cc:69:d1:68:
+ b4:5d:4b:e0:04:21:6c:4b:e2:6d:cc:b1:e0:97:8f:a6:53:09:
+ cd:aa:2a:65:e5:39:4f:1e:83:a5:6e:5c:98:a2:24:26:e6:fb:
+ a1:ed:93:c7:2e:02:c6:4d:4a:bf:b0:42:df:78:da:b3:a8:f9:
+ 6d:ff:21:85:53:36:60:4c:76:ce:ec:38:dc:d6:51:80:f0:c5:
+ d6:e5:d4:4d:27:64:ab:9b:c7:3e:71:fb:48:97:b8:33:6d:c9:
+ 13:07:ee:96:a2:1b:18:15:f6:5c:4c:40:ed:b3:c2:ec:ff:71:
+ c1:e3:47:ff:d4:b9:00:b4:37:42:da:20:c9:ea:6e:8a:ee:14:
+ 06:ae:7d:a2:59:98:88:a8:1b:6f:2d:f4:f2:c9:14:5f:26:cf:
+ 2c:8d:7e:ed:37:c0:a9:d5:39:b9:82:bf:19:0c:ea:34:af:00:
+ 21:68:f8:ad:73:e2:c9:32:da:38:25:0b:55:d3:9a:1d:f0:68:
+ 86:ed:2e:41:34:ef:7c:a5:50:1d:bf:3a:f9:d3:c1:08:0c:e6:
+ ed:1e:8a:58:25:e4:b8:77:ad:2d:6e:f5:52:dd:b4:74:8f:ab:
+ 49:2e:9d:3b:93:34:28:1f:78:ce:94:ea:c7:bd:d3:c9:6d:1c:
+ de:5c:32:f3
+-----BEGIN CERTIFICATE-----
+MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
+U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
+nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
+KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
+/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
+kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
+/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
+AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
+aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
+Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
+oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
+QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
+d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
+xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
+CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
+5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
+8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
+2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
+c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
+j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert21[] = {
+ 0x30, 0x82, 0x04, 0x94, 0x30, 0x82, 0x03, 0x7c, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x01, 0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88,
+ 0x43, 0x8b, 0x72, 0x4b, 0xcf, 0xbc, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x61,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
+ 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
+ 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31,
+ 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33,
+ 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4d, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44,
+ 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31,
+ 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1e, 0x44, 0x69,
+ 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, 0x32, 0x20,
+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65,
+ 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0xdc, 0xae, 0x58, 0x90, 0x4d, 0xc1, 0xc4, 0x30, 0x15, 0x90, 0x35,
+ 0x5b, 0x6e, 0x3c, 0x82, 0x15, 0xf5, 0x2c, 0x5c, 0xbd, 0xe3, 0xdb, 0xff,
+ 0x71, 0x43, 0xfa, 0x64, 0x25, 0x80, 0xd4, 0xee, 0x18, 0xa2, 0x4d, 0xf0,
+ 0x66, 0xd0, 0x0a, 0x73, 0x6e, 0x11, 0x98, 0x36, 0x17, 0x64, 0xaf, 0x37,
+ 0x9d, 0xfd, 0xfa, 0x41, 0x84, 0xaf, 0xc7, 0xaf, 0x8c, 0xfe, 0x1a, 0x73,
+ 0x4d, 0xcf, 0x33, 0x97, 0x90, 0xa2, 0x96, 0x87, 0x53, 0x83, 0x2b, 0xb9,
+ 0xa6, 0x75, 0x48, 0x2d, 0x1d, 0x56, 0x37, 0x7b, 0xda, 0x31, 0x32, 0x1a,
+ 0xd7, 0xac, 0xab, 0x06, 0xf4, 0xaa, 0x5d, 0x4b, 0xb7, 0x47, 0x46, 0xdd,
+ 0x2a, 0x93, 0xc3, 0x90, 0x2e, 0x79, 0x80, 0x80, 0xef, 0x13, 0x04, 0x6a,
+ 0x14, 0x3b, 0xb5, 0x9b, 0x92, 0xbe, 0xc2, 0x07, 0x65, 0x4e, 0xfc, 0xda,
+ 0xfc, 0xff, 0x7a, 0xae, 0xdc, 0x5c, 0x7e, 0x55, 0x31, 0x0c, 0xe8, 0x39,
+ 0x07, 0xa4, 0xd7, 0xbe, 0x2f, 0xd3, 0x0b, 0x6a, 0xd2, 0xb1, 0xdf, 0x5f,
+ 0xfe, 0x57, 0x74, 0x53, 0x3b, 0x35, 0x80, 0xdd, 0xae, 0x8e, 0x44, 0x98,
+ 0xb3, 0x9f, 0x0e, 0xd3, 0xda, 0xe0, 0xd7, 0xf4, 0x6b, 0x29, 0xab, 0x44,
+ 0xa7, 0x4b, 0x58, 0x84, 0x6d, 0x92, 0x4b, 0x81, 0xc3, 0xda, 0x73, 0x8b,
+ 0x12, 0x97, 0x48, 0x90, 0x04, 0x45, 0x75, 0x1a, 0xdd, 0x37, 0x31, 0x97,
+ 0x92, 0xe8, 0xcd, 0x54, 0x0d, 0x3b, 0xe4, 0xc1, 0x3f, 0x39, 0x5e, 0x2e,
+ 0xb8, 0xf3, 0x5c, 0x7e, 0x10, 0x8e, 0x86, 0x41, 0x00, 0x8d, 0x45, 0x66,
+ 0x47, 0xb0, 0xa1, 0x65, 0xce, 0xa0, 0xaa, 0x29, 0x09, 0x4e, 0xf3, 0x97,
+ 0xeb, 0xe8, 0x2e, 0xab, 0x0f, 0x72, 0xa7, 0x30, 0x0e, 0xfa, 0xc7, 0xf4,
+ 0xfd, 0x14, 0x77, 0xc3, 0xa4, 0x5b, 0x28, 0x57, 0xc2, 0xb3, 0xf9, 0x82,
+ 0xfd, 0xb7, 0x45, 0x58, 0x9b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+ 0x01, 0x5a, 0x30, 0x82, 0x01, 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
+ 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+ 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+ 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30,
+ 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63,
+ 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69,
+ 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f,
+ 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35,
+ 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+ 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72,
+ 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43,
+ 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20,
+ 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
+ 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+ 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0f, 0x80, 0x61, 0x1c, 0x82,
+ 0x31, 0x61, 0xd5, 0x2f, 0x28, 0xe7, 0x8d, 0x46, 0x38, 0xb4, 0x2c, 0xe1,
+ 0xc6, 0xd9, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb,
+ 0x66, 0xf0, 0xa3, 0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x23, 0x3e, 0xdf, 0x4b,
+ 0xd2, 0x31, 0x42, 0xa5, 0xb6, 0x7e, 0x42, 0x5c, 0x1a, 0x44, 0xcc, 0x69,
+ 0xd1, 0x68, 0xb4, 0x5d, 0x4b, 0xe0, 0x04, 0x21, 0x6c, 0x4b, 0xe2, 0x6d,
+ 0xcc, 0xb1, 0xe0, 0x97, 0x8f, 0xa6, 0x53, 0x09, 0xcd, 0xaa, 0x2a, 0x65,
+ 0xe5, 0x39, 0x4f, 0x1e, 0x83, 0xa5, 0x6e, 0x5c, 0x98, 0xa2, 0x24, 0x26,
+ 0xe6, 0xfb, 0xa1, 0xed, 0x93, 0xc7, 0x2e, 0x02, 0xc6, 0x4d, 0x4a, 0xbf,
+ 0xb0, 0x42, 0xdf, 0x78, 0xda, 0xb3, 0xa8, 0xf9, 0x6d, 0xff, 0x21, 0x85,
+ 0x53, 0x36, 0x60, 0x4c, 0x76, 0xce, 0xec, 0x38, 0xdc, 0xd6, 0x51, 0x80,
+ 0xf0, 0xc5, 0xd6, 0xe5, 0xd4, 0x4d, 0x27, 0x64, 0xab, 0x9b, 0xc7, 0x3e,
+ 0x71, 0xfb, 0x48, 0x97, 0xb8, 0x33, 0x6d, 0xc9, 0x13, 0x07, 0xee, 0x96,
+ 0xa2, 0x1b, 0x18, 0x15, 0xf6, 0x5c, 0x4c, 0x40, 0xed, 0xb3, 0xc2, 0xec,
+ 0xff, 0x71, 0xc1, 0xe3, 0x47, 0xff, 0xd4, 0xb9, 0x00, 0xb4, 0x37, 0x42,
+ 0xda, 0x20, 0xc9, 0xea, 0x6e, 0x8a, 0xee, 0x14, 0x06, 0xae, 0x7d, 0xa2,
+ 0x59, 0x98, 0x88, 0xa8, 0x1b, 0x6f, 0x2d, 0xf4, 0xf2, 0xc9, 0x14, 0x5f,
+ 0x26, 0xcf, 0x2c, 0x8d, 0x7e, 0xed, 0x37, 0xc0, 0xa9, 0xd5, 0x39, 0xb9,
+ 0x82, 0xbf, 0x19, 0x0c, 0xea, 0x34, 0xaf, 0x00, 0x21, 0x68, 0xf8, 0xad,
+ 0x73, 0xe2, 0xc9, 0x32, 0xda, 0x38, 0x25, 0x0b, 0x55, 0xd3, 0x9a, 0x1d,
+ 0xf0, 0x68, 0x86, 0xed, 0x2e, 0x41, 0x34, 0xef, 0x7c, 0xa5, 0x50, 0x1d,
+ 0xbf, 0x3a, 0xf9, 0xd3, 0xc1, 0x08, 0x0c, 0xe6, 0xed, 0x1e, 0x8a, 0x58,
+ 0x25, 0xe4, 0xb8, 0x77, 0xad, 0x2d, 0x6e, 0xf5, 0x52, 0xdd, 0xb4, 0x74,
+ 0x8f, 0xab, 0x49, 0x2e, 0x9d, 0x3b, 0x93, 0x34, 0x28, 0x1f, 0x78, 0xce,
+ 0x94, 0xea, 0xc7, 0xbd, 0xd3, 0xc9, 0x6d, 0x1c, 0xde, 0x5c, 0x32, 0xf3,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0b:1d:b1:a9:19:f2:4c:3c:4e:fc:b5:7a:6a:4e:6c:bf
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
+ Validity
+ Not Before: Aug 23 00:00:00 2012 GMT
+ Not After : Aug 22 23:59:59 2022 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Extended Validation SSL CA - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9e:c6:21:cd:2e:3d:d0:bb:2a:4d:a4:7b:1f:a8:
+ 1a:c2:03:a6:ff:43:62:5b:bf:91:d1:66:52:a9:81:
+ 90:68:31:86:16:bb:1d:85:58:a9:7e:91:6a:1e:4c:
+ 31:ca:21:c4:be:70:1b:9f:8c:e4:05:2d:9c:ed:11:
+ 79:ad:8f:9c:25:86:4c:ba:f2:e5:62:79:8e:22:5f:
+ 85:7c:22:35:38:23:8d:80:3c:ac:cc:2d:fc:58:f2:
+ 35:bf:66:5b:eb:c1:24:f8:70:80:74:32:f9:46:de:
+ 32:19:80:8c:b7:e7:1a:a1:aa:64:98:8d:ca:ce:0e:
+ dc:6b:f7:e2:90:0a:6c:1c:a5:f4:90:32:52:e5:f1:
+ 00:42:31:91:48:42:89:a8:5d:7f:63:8d:31:b2:d6:
+ 48:5c:45:45:22:c9:c5:59:12:ab:41:94:ea:fe:9c:
+ 46:4d:9a:bc:9c:e0:e2:c6:46:b3:e6:7f:dc:f5:0f:
+ a3:13:45:86:6d:79:78:fc:e1:50:cf:09:86:e5:9f:
+ bf:cb:3a:d4:e0:b1:d4:ff:a8:3f:7d:62:1f:c0:6d:
+ 78:48:c3:d7:a3:a5:23:61:c5:3e:35:4d:b2:e5:f8:
+ fd:94:4b:bc:73:53:af:e3:9a:69:55:be:cb:67:ab:
+ e1:be:ef:1b:c2:4d:ac:cb:29:5c:bc:ed:b8:62:9d:
+ 10:e9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ OCSP - URI:http://EVSecure-ocsp.geotrust.com
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.geotrust.com/resources/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://EVSecure-crl.geotrust.com/GeoTrustPCA.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Alternative Name:
+ DirName:/CN=VeriSignMPKI-2-253
+ X509v3 Subject Key Identifier:
+ 6F:26:56:D9:5C:E7:F7:C9:04:20:F8:1E:BA:7C:91:27:2F:8C:FA:07
+ X509v3 Authority Key Identifier:
+ keyid:2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 92:77:e9:57:c9:eb:c4:45:6f:c9:4c:6e:7d:00:12:71:a5:e3:
+ 39:fe:13:84:49:6c:e7:49:71:f5:2c:c7:c0:36:c2:08:58:f3:
+ 83:75:c5:72:d8:8d:78:f4:65:ea:8c:d5:e3:a5:0e:a9:ad:eb:
+ e3:a1:23:ae:93:b7:d8:75:75:4a:59:cb:f2:9e:db:40:bf:4e:
+ 89:fe:95:42:29:34:7b:f4:dd:6a:0d:74:5f:c7:11:13:2e:dd:
+ 11:6e:c6:e3:5b:b3:cf:a6:8d:e5:f7:67:7b:ba:b3:b3:69:70:
+ 14:b0:c2:99:b4:d2:76:5b:38:17:39:45:1b:82:f1:53:b8:3d:
+ 55:39:0b:7f:ff:98:ad:6e:96:9a:b6:6a:4c:7a:5e:bd:b1:86:
+ 12:9d:7c:2c:62:bb:09:93:5f:3f:d8:b5:8a:c3:49:28:0f:0b:
+ f9:39:22:1a:fe:5d:d3:e8:18:5f:9d:5f:b4:c0:20:c6:a9:49:
+ 0d:55:73:6a:09:7a:ff:a2:99:bf:d8:bb:91:dc:30:39:ae:28:
+ 4b:f6:c5:77:24:e8:d6:c6:a7:a0:4e:f2:a6:99:75:cd:dd:57:
+ dd:0a:47:92:cb:bb:b7:48:fa:21:f0:69:21:ff:e5:0c:aa:0c:
+ b1:ea:dd:05:1c:19:8e:d1:2a:79:68:02:5e:cc:38:e6:29:c4:
+ 77:f5:19:1c
+-----BEGIN CERTIFICATE-----
+MIIEmjCCA4KgAwIBAgIQCx2xqRnyTDxO/LV6ak5svzANBgkqhkiG9w0BAQUFADBY
+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
+R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMjA4
+MjMwMDAwMDBaFw0yMjA4MjIyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBFeHRlbmRlZCBWYWxp
+ZGF0aW9uIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAnsYhzS490LsqTaR7H6gawgOm/0NiW7+R0WZSqYGQaDGGFrsdhVipfpFqHkwx
+yiHEvnAbn4zkBS2c7RF5rY+cJYZMuvLlYnmOIl+FfCI1OCONgDyszC38WPI1v2Zb
+68Ek+HCAdDL5Rt4yGYCMt+caoapkmI3Kzg7ca/fikApsHKX0kDJS5fEAQjGRSEKJ
+qF1/Y40xstZIXEVFIsnFWRKrQZTq/pxGTZq8nODixkaz5n/c9Q+jE0WGbXl4/OFQ
+zwmG5Z+/yzrU4LHU/6g/fWIfwG14SMPXo6UjYcU+NU2y5fj9lEu8c1Ov45ppVb7L
+Z6vhvu8bwk2syylcvO24Yp0Q6QIDAQABo4IBXjCCAVowPQYIKwYBBQUHAQEEMTAv
+MC0GCCsGAQUFBzABhiFodHRwOi8vRVZTZWN1cmUtb2NzcC5nZW90cnVzdC5jb20w
+EgYDVR0TAQH/BAgwBgEB/wIBADBGBgNVHSAEPzA9MDsGBFUdIAAwMzAxBggrBgEF
+BQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczBBBgNV
+HR8EOjA4MDagNKAyhjBodHRwOi8vRVZTZWN1cmUtY3JsLmdlb3RydXN0LmNvbS9H
+ZW9UcnVzdFBDQS5jcmwwDgYDVR0PAQH/BAQDAgEGMCoGA1UdEQQjMCGkHzAdMRsw
+GQYDVQQDExJWZXJpU2lnbk1QS0ktMi0yNTMwHQYDVR0OBBYEFG8mVtlc5/fJBCD4
+Hrp8kScvjPoHMB8GA1UdIwQYMBaAFCzVUEGXFYvwjzZhW0r7a9mZyTOSMA0GCSqG
+SIb3DQEBBQUAA4IBAQCSd+lXyevERW/JTG59ABJxpeM5/hOESWznSXH1LMfANsII
+WPODdcVy2I149GXqjNXjpQ6prevjoSOuk7fYdXVKWcvynttAv06J/pVCKTR79N1q
+DXRfxxETLt0RbsbjW7PPpo3l92d7urOzaXAUsMKZtNJ2WzgXOUUbgvFTuD1VOQt/
+/5itbpaatmpMel69sYYSnXwsYrsJk18/2LWKw0koDwv5OSIa/l3T6BhfnV+0wCDG
+qUkNVXNqCXr/opm/2LuR3DA5rihL9sV3JOjWxqegTvKmmXXN3VfdCkeSy7u3SPoh
+8Gkh/+UMqgyx6t0FHBmO0Sp5aAJezDjmKcR39Rkc
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert22[] = {
+ 0x30, 0x82, 0x04, 0x9a, 0x30, 0x82, 0x03, 0x82, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x0b, 0x1d, 0xb1, 0xa9, 0x19, 0xf2, 0x4c, 0x3c, 0x4e,
+ 0xfc, 0xb5, 0x7a, 0x6a, 0x4e, 0x6c, 0xbf, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x58,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
+ 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28,
+ 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
+ 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x38,
+ 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32,
+ 0x32, 0x30, 0x38, 0x32, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
+ 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
+ 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69,
+ 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43,
+ 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+ 0x01, 0x01, 0x00, 0x9e, 0xc6, 0x21, 0xcd, 0x2e, 0x3d, 0xd0, 0xbb, 0x2a,
+ 0x4d, 0xa4, 0x7b, 0x1f, 0xa8, 0x1a, 0xc2, 0x03, 0xa6, 0xff, 0x43, 0x62,
+ 0x5b, 0xbf, 0x91, 0xd1, 0x66, 0x52, 0xa9, 0x81, 0x90, 0x68, 0x31, 0x86,
+ 0x16, 0xbb, 0x1d, 0x85, 0x58, 0xa9, 0x7e, 0x91, 0x6a, 0x1e, 0x4c, 0x31,
+ 0xca, 0x21, 0xc4, 0xbe, 0x70, 0x1b, 0x9f, 0x8c, 0xe4, 0x05, 0x2d, 0x9c,
+ 0xed, 0x11, 0x79, 0xad, 0x8f, 0x9c, 0x25, 0x86, 0x4c, 0xba, 0xf2, 0xe5,
+ 0x62, 0x79, 0x8e, 0x22, 0x5f, 0x85, 0x7c, 0x22, 0x35, 0x38, 0x23, 0x8d,
+ 0x80, 0x3c, 0xac, 0xcc, 0x2d, 0xfc, 0x58, 0xf2, 0x35, 0xbf, 0x66, 0x5b,
+ 0xeb, 0xc1, 0x24, 0xf8, 0x70, 0x80, 0x74, 0x32, 0xf9, 0x46, 0xde, 0x32,
+ 0x19, 0x80, 0x8c, 0xb7, 0xe7, 0x1a, 0xa1, 0xaa, 0x64, 0x98, 0x8d, 0xca,
+ 0xce, 0x0e, 0xdc, 0x6b, 0xf7, 0xe2, 0x90, 0x0a, 0x6c, 0x1c, 0xa5, 0xf4,
+ 0x90, 0x32, 0x52, 0xe5, 0xf1, 0x00, 0x42, 0x31, 0x91, 0x48, 0x42, 0x89,
+ 0xa8, 0x5d, 0x7f, 0x63, 0x8d, 0x31, 0xb2, 0xd6, 0x48, 0x5c, 0x45, 0x45,
+ 0x22, 0xc9, 0xc5, 0x59, 0x12, 0xab, 0x41, 0x94, 0xea, 0xfe, 0x9c, 0x46,
+ 0x4d, 0x9a, 0xbc, 0x9c, 0xe0, 0xe2, 0xc6, 0x46, 0xb3, 0xe6, 0x7f, 0xdc,
+ 0xf5, 0x0f, 0xa3, 0x13, 0x45, 0x86, 0x6d, 0x79, 0x78, 0xfc, 0xe1, 0x50,
+ 0xcf, 0x09, 0x86, 0xe5, 0x9f, 0xbf, 0xcb, 0x3a, 0xd4, 0xe0, 0xb1, 0xd4,
+ 0xff, 0xa8, 0x3f, 0x7d, 0x62, 0x1f, 0xc0, 0x6d, 0x78, 0x48, 0xc3, 0xd7,
+ 0xa3, 0xa5, 0x23, 0x61, 0xc5, 0x3e, 0x35, 0x4d, 0xb2, 0xe5, 0xf8, 0xfd,
+ 0x94, 0x4b, 0xbc, 0x73, 0x53, 0xaf, 0xe3, 0x9a, 0x69, 0x55, 0xbe, 0xcb,
+ 0x67, 0xab, 0xe1, 0xbe, 0xef, 0x1b, 0xc2, 0x4d, 0xac, 0xcb, 0x29, 0x5c,
+ 0xbc, 0xed, 0xb8, 0x62, 0x9d, 0x10, 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x82, 0x01, 0x5e, 0x30, 0x82, 0x01, 0x5a, 0x30, 0x3d, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f,
+ 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
+ 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67,
+ 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+ 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
+ 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x46, 0x06, 0x03, 0x55,
+ 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d,
+ 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x41, 0x06, 0x03, 0x55,
+ 0x1d, 0x1f, 0x04, 0x3a, 0x30, 0x38, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32,
+ 0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65,
+ 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2e, 0x63,
+ 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+ 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d,
+ 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30,
+ 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32,
+ 0x35, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0x6f, 0x26, 0x56, 0xd9, 0x5c, 0xe7, 0xf7, 0xc9, 0x04, 0x20, 0xf8,
+ 0x1e, 0xba, 0x7c, 0x91, 0x27, 0x2f, 0x8c, 0xfa, 0x07, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2c, 0xd5,
+ 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb,
+ 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x01, 0x00, 0x92, 0x77, 0xe9, 0x57, 0xc9, 0xeb, 0xc4, 0x45, 0x6f, 0xc9,
+ 0x4c, 0x6e, 0x7d, 0x00, 0x12, 0x71, 0xa5, 0xe3, 0x39, 0xfe, 0x13, 0x84,
+ 0x49, 0x6c, 0xe7, 0x49, 0x71, 0xf5, 0x2c, 0xc7, 0xc0, 0x36, 0xc2, 0x08,
+ 0x58, 0xf3, 0x83, 0x75, 0xc5, 0x72, 0xd8, 0x8d, 0x78, 0xf4, 0x65, 0xea,
+ 0x8c, 0xd5, 0xe3, 0xa5, 0x0e, 0xa9, 0xad, 0xeb, 0xe3, 0xa1, 0x23, 0xae,
+ 0x93, 0xb7, 0xd8, 0x75, 0x75, 0x4a, 0x59, 0xcb, 0xf2, 0x9e, 0xdb, 0x40,
+ 0xbf, 0x4e, 0x89, 0xfe, 0x95, 0x42, 0x29, 0x34, 0x7b, 0xf4, 0xdd, 0x6a,
+ 0x0d, 0x74, 0x5f, 0xc7, 0x11, 0x13, 0x2e, 0xdd, 0x11, 0x6e, 0xc6, 0xe3,
+ 0x5b, 0xb3, 0xcf, 0xa6, 0x8d, 0xe5, 0xf7, 0x67, 0x7b, 0xba, 0xb3, 0xb3,
+ 0x69, 0x70, 0x14, 0xb0, 0xc2, 0x99, 0xb4, 0xd2, 0x76, 0x5b, 0x38, 0x17,
+ 0x39, 0x45, 0x1b, 0x82, 0xf1, 0x53, 0xb8, 0x3d, 0x55, 0x39, 0x0b, 0x7f,
+ 0xff, 0x98, 0xad, 0x6e, 0x96, 0x9a, 0xb6, 0x6a, 0x4c, 0x7a, 0x5e, 0xbd,
+ 0xb1, 0x86, 0x12, 0x9d, 0x7c, 0x2c, 0x62, 0xbb, 0x09, 0x93, 0x5f, 0x3f,
+ 0xd8, 0xb5, 0x8a, 0xc3, 0x49, 0x28, 0x0f, 0x0b, 0xf9, 0x39, 0x22, 0x1a,
+ 0xfe, 0x5d, 0xd3, 0xe8, 0x18, 0x5f, 0x9d, 0x5f, 0xb4, 0xc0, 0x20, 0xc6,
+ 0xa9, 0x49, 0x0d, 0x55, 0x73, 0x6a, 0x09, 0x7a, 0xff, 0xa2, 0x99, 0xbf,
+ 0xd8, 0xbb, 0x91, 0xdc, 0x30, 0x39, 0xae, 0x28, 0x4b, 0xf6, 0xc5, 0x77,
+ 0x24, 0xe8, 0xd6, 0xc6, 0xa7, 0xa0, 0x4e, 0xf2, 0xa6, 0x99, 0x75, 0xcd,
+ 0xdd, 0x57, 0xdd, 0x0a, 0x47, 0x92, 0xcb, 0xbb, 0xb7, 0x48, 0xfa, 0x21,
+ 0xf0, 0x69, 0x21, 0xff, 0xe5, 0x0c, 0xaa, 0x0c, 0xb1, 0xea, 0xdd, 0x05,
+ 0x1c, 0x19, 0x8e, 0xd1, 0x2a, 0x79, 0x68, 0x02, 0x5e, 0xcc, 0x38, 0xe6,
+ 0x29, 0xc4, 0x77, 0xf5, 0x19, 0x1c,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3740804 (0x391484)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
+ Validity
+ Not Before: Jan 1 07:00:00 2014 GMT
+ Not After : May 30 07:00:00 2031 GMT
+ Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bd:ed:c1:03:fc:f6:8f:fc:02:b1:6f:5b:9f:48:
+ d9:9d:79:e2:a2:b7:03:61:56:18:c3:47:b6:d7:ca:
+ 3d:35:2e:89:43:f7:a1:69:9b:de:8a:1a:fd:13:20:
+ 9c:b4:49:77:32:29:56:fd:b9:ec:8c:dd:22:fa:72:
+ dc:27:61:97:ee:f6:5a:84:ec:6e:19:b9:89:2c:dc:
+ 84:5b:d5:74:fb:6b:5f:c5:89:a5:10:52:89:46:55:
+ f4:b8:75:1c:e6:7f:e4:54:ae:4b:f8:55:72:57:02:
+ 19:f8:17:71:59:eb:1e:28:07:74:c5:9d:48:be:6c:
+ b4:f4:a4:b0:f3:64:37:79:92:c0:ec:46:5e:7f:e1:
+ 6d:53:4c:62:af:cd:1f:0b:63:bb:3a:9d:fb:fc:79:
+ 00:98:61:74:cf:26:82:40:63:f3:b2:72:6a:19:0d:
+ 99:ca:d4:0e:75:cc:37:fb:8b:89:c1:59:f1:62:7f:
+ 5f:b3:5f:65:30:f8:a7:b7:4d:76:5a:1e:76:5e:34:
+ c0:e8:96:56:99:8a:b3:f0:7f:a4:cd:bd:dc:32:31:
+ 7c:91:cf:e0:5f:11:f8:6b:aa:49:5c:d1:99:94:d1:
+ a2:e3:63:5b:09:76:b5:56:62:e1:4b:74:1d:96:d4:
+ 26:d4:08:04:59:d0:98:0e:0e:e6:de:fc:c3:ec:1f:
+ 90:f1
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
+ X509v3 Authority Key Identifier:
+ keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.starfieldtech.com/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.starfieldtech.com/sfroot.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://certs.starfieldtech.com/repository/
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 85:63:c1:d9:dd:b9:ff:a9:bd:a6:19:dc:bf:13:3a:11:38:22:
+ 54:b1:ac:05:10:fb:7c:b3:96:3f:31:8b:66:ff:88:f3:e1:bf:
+ fb:c7:1f:00:ff:46:6a:8b:61:32:c9:01:51:76:fb:9a:c6:fa:
+ 20:51:c8:46:c4:98:d7:79:a3:e3:04:72:3f:8b:4d:34:53:67:
+ ec:33:2c:7b:e8:94:01:28:7c:3a:34:5b:02:77:16:8d:40:25:
+ 33:b0:bc:6c:97:d7:05:7a:ff:8c:85:ce:6f:a0:53:00:17:6e:
+ 1e:6c:bd:22:d7:0a:88:37:f6:7d:eb:99:41:ef:27:cb:8c:60:
+ 6b:4c:01:7e:65:50:0b:4f:b8:95:9a:9a:6e:34:fd:73:3a:33:
+ f1:91:d5:f3:4e:2d:74:e8:ef:d3:90:35:f1:06:68:64:d4:d0:
+ 13:fd:52:d3:c6:6d:c1:3a:8a:31:dd:05:26:35:4a:8c:65:b8:
+ 52:6b:81:ec:d2:9c:b5:34:10:97:9c:3e:c6:2f:ed:8e:42:42:
+ 24:2e:e9:73:9a:25:f9:11:f1:f2:23:69:cb:e5:94:69:a0:d2:
+ dc:b0:fc:44:89:ac:17:a8:cc:d5:37:77:16:c5:80:b9:0c:8f:
+ 57:02:55:99:85:7b:49:f0:2e:5b:a0:c2:57:53:5d:a2:e8:a6:
+ 37:c3:01:fa
+-----BEGIN CERTIFICATE-----
+MIIEoDCCA4igAwIBAgIDORSEMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNVBAYTAlVT
+MSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQL
+EylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NDAxMDEwNzAwMDBaFw0zMTA1MzAwNzAwMDBaMIGPMQswCQYDVQQGEwJVUzEQMA4G
+A1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UEChMcU3Rh
+cmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UEAxMpU3RhcmZpZWxkIFJv
+b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQC97cED/PaP/AKxb1ufSNmdeeKitwNhVhjDR7bXyj01LolD
+96Fpm96KGv0TIJy0SXcyKVb9ueyM3SL6ctwnYZfu9lqE7G4ZuYks3IRb1XT7a1/F
+iaUQUolGVfS4dRzmf+RUrkv4VXJXAhn4F3FZ6x4oB3TFnUi+bLT0pLDzZDd5ksDs
+Rl5/4W1TTGKvzR8LY7s6nfv8eQCYYXTPJoJAY/OycmoZDZnK1A51zDf7i4nBWfFi
+f1+zX2Uw+Ke3TXZaHnZeNMDollaZirPwf6TNvdwyMXyRz+BfEfhrqklc0ZmU0aLj
+Y1sJdrVWYuFLdB2W1CbUCARZ0JgODube/MPsH5DxAgMBAAGjggEpMIIBJTAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfAwyH6fZMH/E
+fWijYqihzqsHWycwHwYDVR0jBBgwFoAUv1+30c7dH4b0W1Ws3NcQwg6piOcwOgYI
+KwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0
+ZWNoLmNvbS8wOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL2NybC5zdGFyZmllbGR0
+ZWNoLmNvbS9zZnJvb3QuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
+BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
+MA0GCSqGSIb3DQEBCwUAA4IBAQCFY8HZ3bn/qb2mGdy/EzoROCJUsawFEPt8s5Y/
+MYtm/4jz4b/7xx8A/0Zqi2EyyQFRdvuaxvogUchGxJjXeaPjBHI/i000U2fsMyx7
+6JQBKHw6NFsCdxaNQCUzsLxsl9cFev+Mhc5voFMAF24ebL0i1wqIN/Z965lB7yfL
+jGBrTAF+ZVALT7iVmppuNP1zOjPxkdXzTi106O/TkDXxBmhk1NAT/VLTxm3BOoox
+3QUmNUqMZbhSa4Hs0py1NBCXnD7GL+2OQkIkLulzmiX5EfHyI2nL5ZRpoNLcsPxE
+iawXqMzVN3cWxYC5DI9XAlWZhXtJ8C5boMJXU12i6KY3wwH6
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert23[] = {
+ 0x30, 0x82, 0x04, 0xa0, 0x30, 0x82, 0x03, 0x88, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x39, 0x14, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x68, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53,
+ 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63,
+ 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20,
+ 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+ 0x34, 0x30, 0x31, 0x30, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a,
+ 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30,
+ 0x30, 0x30, 0x5a, 0x30, 0x81, 0x8f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e,
+ 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a,
+ 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25,
+ 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61,
+ 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e,
+ 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29,
+ 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x52, 0x6f,
+ 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+ 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+ 0x01, 0x00, 0xbd, 0xed, 0xc1, 0x03, 0xfc, 0xf6, 0x8f, 0xfc, 0x02, 0xb1,
+ 0x6f, 0x5b, 0x9f, 0x48, 0xd9, 0x9d, 0x79, 0xe2, 0xa2, 0xb7, 0x03, 0x61,
+ 0x56, 0x18, 0xc3, 0x47, 0xb6, 0xd7, 0xca, 0x3d, 0x35, 0x2e, 0x89, 0x43,
+ 0xf7, 0xa1, 0x69, 0x9b, 0xde, 0x8a, 0x1a, 0xfd, 0x13, 0x20, 0x9c, 0xb4,
+ 0x49, 0x77, 0x32, 0x29, 0x56, 0xfd, 0xb9, 0xec, 0x8c, 0xdd, 0x22, 0xfa,
+ 0x72, 0xdc, 0x27, 0x61, 0x97, 0xee, 0xf6, 0x5a, 0x84, 0xec, 0x6e, 0x19,
+ 0xb9, 0x89, 0x2c, 0xdc, 0x84, 0x5b, 0xd5, 0x74, 0xfb, 0x6b, 0x5f, 0xc5,
+ 0x89, 0xa5, 0x10, 0x52, 0x89, 0x46, 0x55, 0xf4, 0xb8, 0x75, 0x1c, 0xe6,
+ 0x7f, 0xe4, 0x54, 0xae, 0x4b, 0xf8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xf8,
+ 0x17, 0x71, 0x59, 0xeb, 0x1e, 0x28, 0x07, 0x74, 0xc5, 0x9d, 0x48, 0xbe,
+ 0x6c, 0xb4, 0xf4, 0xa4, 0xb0, 0xf3, 0x64, 0x37, 0x79, 0x92, 0xc0, 0xec,
+ 0x46, 0x5e, 0x7f, 0xe1, 0x6d, 0x53, 0x4c, 0x62, 0xaf, 0xcd, 0x1f, 0x0b,
+ 0x63, 0xbb, 0x3a, 0x9d, 0xfb, 0xfc, 0x79, 0x00, 0x98, 0x61, 0x74, 0xcf,
+ 0x26, 0x82, 0x40, 0x63, 0xf3, 0xb2, 0x72, 0x6a, 0x19, 0x0d, 0x99, 0xca,
+ 0xd4, 0x0e, 0x75, 0xcc, 0x37, 0xfb, 0x8b, 0x89, 0xc1, 0x59, 0xf1, 0x62,
+ 0x7f, 0x5f, 0xb3, 0x5f, 0x65, 0x30, 0xf8, 0xa7, 0xb7, 0x4d, 0x76, 0x5a,
+ 0x1e, 0x76, 0x5e, 0x34, 0xc0, 0xe8, 0x96, 0x56, 0x99, 0x8a, 0xb3, 0xf0,
+ 0x7f, 0xa4, 0xcd, 0xbd, 0xdc, 0x32, 0x31, 0x7c, 0x91, 0xcf, 0xe0, 0x5f,
+ 0x11, 0xf8, 0x6b, 0xaa, 0x49, 0x5c, 0xd1, 0x99, 0x94, 0xd1, 0xa2, 0xe3,
+ 0x63, 0x5b, 0x09, 0x76, 0xb5, 0x56, 0x62, 0xe1, 0x4b, 0x74, 0x1d, 0x96,
+ 0xd4, 0x26, 0xd4, 0x08, 0x04, 0x59, 0xd0, 0x98, 0x0e, 0x0e, 0xe6, 0xde,
+ 0xfc, 0xc3, 0xec, 0x1f, 0x90, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+ 0x82, 0x01, 0x29, 0x30, 0x82, 0x01, 0x25, 0x30, 0x0f, 0x06, 0x03, 0x55,
+ 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
+ 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
+ 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0x7c, 0x0c, 0x32, 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4,
+ 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1, 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0xbf, 0x5f, 0xb7, 0xd1, 0xce, 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55, 0xac,
+ 0xdc, 0xd7, 0x10, 0xc2, 0x0e, 0xa9, 0x88, 0xe7, 0x30, 0x3a, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c,
+ 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
+ 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
+ 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74,
+ 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x38, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0,
+ 0x29, 0x86, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74,
+ 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f,
+ 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d,
+ 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20,
+ 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+ 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66,
+ 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x85, 0x63, 0xc1, 0xd9,
+ 0xdd, 0xb9, 0xff, 0xa9, 0xbd, 0xa6, 0x19, 0xdc, 0xbf, 0x13, 0x3a, 0x11,
+ 0x38, 0x22, 0x54, 0xb1, 0xac, 0x05, 0x10, 0xfb, 0x7c, 0xb3, 0x96, 0x3f,
+ 0x31, 0x8b, 0x66, 0xff, 0x88, 0xf3, 0xe1, 0xbf, 0xfb, 0xc7, 0x1f, 0x00,
+ 0xff, 0x46, 0x6a, 0x8b, 0x61, 0x32, 0xc9, 0x01, 0x51, 0x76, 0xfb, 0x9a,
+ 0xc6, 0xfa, 0x20, 0x51, 0xc8, 0x46, 0xc4, 0x98, 0xd7, 0x79, 0xa3, 0xe3,
+ 0x04, 0x72, 0x3f, 0x8b, 0x4d, 0x34, 0x53, 0x67, 0xec, 0x33, 0x2c, 0x7b,
+ 0xe8, 0x94, 0x01, 0x28, 0x7c, 0x3a, 0x34, 0x5b, 0x02, 0x77, 0x16, 0x8d,
+ 0x40, 0x25, 0x33, 0xb0, 0xbc, 0x6c, 0x97, 0xd7, 0x05, 0x7a, 0xff, 0x8c,
+ 0x85, 0xce, 0x6f, 0xa0, 0x53, 0x00, 0x17, 0x6e, 0x1e, 0x6c, 0xbd, 0x22,
+ 0xd7, 0x0a, 0x88, 0x37, 0xf6, 0x7d, 0xeb, 0x99, 0x41, 0xef, 0x27, 0xcb,
+ 0x8c, 0x60, 0x6b, 0x4c, 0x01, 0x7e, 0x65, 0x50, 0x0b, 0x4f, 0xb8, 0x95,
+ 0x9a, 0x9a, 0x6e, 0x34, 0xfd, 0x73, 0x3a, 0x33, 0xf1, 0x91, 0xd5, 0xf3,
+ 0x4e, 0x2d, 0x74, 0xe8, 0xef, 0xd3, 0x90, 0x35, 0xf1, 0x06, 0x68, 0x64,
+ 0xd4, 0xd0, 0x13, 0xfd, 0x52, 0xd3, 0xc6, 0x6d, 0xc1, 0x3a, 0x8a, 0x31,
+ 0xdd, 0x05, 0x26, 0x35, 0x4a, 0x8c, 0x65, 0xb8, 0x52, 0x6b, 0x81, 0xec,
+ 0xd2, 0x9c, 0xb5, 0x34, 0x10, 0x97, 0x9c, 0x3e, 0xc6, 0x2f, 0xed, 0x8e,
+ 0x42, 0x42, 0x24, 0x2e, 0xe9, 0x73, 0x9a, 0x25, 0xf9, 0x11, 0xf1, 0xf2,
+ 0x23, 0x69, 0xcb, 0xe5, 0x94, 0x69, 0xa0, 0xd2, 0xdc, 0xb0, 0xfc, 0x44,
+ 0x89, 0xac, 0x17, 0xa8, 0xcc, 0xd5, 0x37, 0x77, 0x16, 0xc5, 0x80, 0xb9,
+ 0x0c, 0x8f, 0x57, 0x02, 0x55, 0x99, 0x85, 0x7b, 0x49, 0xf0, 0x2e, 0x5b,
+ 0xa0, 0xc2, 0x57, 0x53, 0x5d, 0xa2, 0xe8, 0xa6, 0x37, 0xc3, 0x01, 0xfa,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 28:1c:89:29:66:14:43:80:42:63:55:3a:32:40:ae:b3
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
+ Validity
+ Not Before: Jun 30 00:00:00 2015 GMT
+ Not After : Jun 29 23:59:59 2025 GMT
+ Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G4
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c0:9e:3a:0f:9a:b2:ba:d3:d2:dc:15:ec:d0:30:
+ 54:59:30:4d:40:51:ae:42:71:71:d2:8d:53:73:81:
+ fe:b8:e0:c4:96:c5:8e:7e:c2:f1:b7:63:4a:cf:a7:
+ 1e:3f:a8:e7:ce:53:a0:fa:2d:f7:d6:e6:ce:70:11:
+ a6:ee:e1:03:52:d2:68:de:3d:08:0d:87:fd:1c:d7:
+ 0b:97:62:6d:82:30:76:1b:47:3a:c4:f7:ce:ed:1d:
+ 7c:8c:b7:17:8e:53:80:1e:1d:0f:5d:8c:f9:90:e4:
+ 04:1e:02:7e:cb:b0:49:ef:da:52:25:fb:fb:67:ed:
+ dd:84:74:59:84:0e:f3:de:70:66:8d:e4:52:38:f7:
+ 53:5a:37:13:67:0b:3e:bb:a8:58:b7:2e:ed:ff:b7:
+ 5e:11:73:b9:77:45:52:67:46:ae:c4:dc:24:81:89:
+ 76:0a:ca:a1:6c:66:73:04:82:aa:f5:70:6c:5f:1b:
+ 9a:00:79:46:d6:7f:7a:26:17:30:cf:39:4b:2c:74:
+ d9:89:44:76:10:d0:ed:f7:8b:bb:89:05:75:4d:0b:
+ 0d:b3:da:e9:bf:f1:6a:7d:2a:11:db:1e:9f:8c:e3:
+ c4:06:69:e1:1d:88:45:39:d1:6e:55:d8:aa:b7:9b:
+ 6f:ea:f4:de:ac:17:11:92:5d:40:9b:83:7b:9a:e2:
+ f7:a9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ OCSP - URI:http://g.symcd.com
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 2.23.140.1.2.1
+ CPS: https://www.geotrust.com/resources/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://g.symcb.com/GeoTrustPCA-G3.crl
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ F3:B5:56:0C:C4:09:B0:B4:CF:1F:AA:F9:DD:23:56:F0:77:E8:A1:F9
+ X509v3 Authority Key Identifier:
+ keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D
+
+ Signature Algorithm: sha256WithRSAEncryption
+ c3:7e:d8:83:4b:04:4c:55:29:2a:4f:14:9d:9a:6e:de:90:70:
+ c1:a4:26:4c:88:8e:78:48:ef:bd:9c:b0:a0:f5:f0:66:fc:fe:
+ 59:26:e1:79:ef:c8:b7:60:64:a8:8b:47:ea:2f:e0:83:99:da:
+ 41:19:d7:c5:be:05:fa:f2:90:11:f0:0a:ff:6c:dc:05:b4:d8:
+ 06:6f:a4:6f:8d:be:20:2b:54:db:f9:a2:45:83:9a:1e:a5:21:
+ 89:35:1d:7c:20:5c:17:fd:04:2e:45:d8:b2:c6:f8:42:99:fc:
+ 54:08:4e:4b:80:5f:39:37:ba:95:4e:a6:37:0a:9e:93:5e:87:
+ 5b:e9:90:d6:a8:b6:65:08:8d:61:49:eb:83:20:a9:5d:1b:16:
+ 60:62:6b:2f:54:fb:5a:02:0d:7a:27:e2:4b:e1:05:14:c2:e4:
+ e9:f9:70:c0:d9:f7:34:65:0e:a2:91:4b:ac:28:f2:b7:08:0f:
+ 98:ca:d7:3e:70:b6:c8:0b:f1:8b:9c:51:f8:c6:10:6c:d2:53:
+ 4f:62:8c:11:00:3e:88:df:bf:e6:d2:cc:70:bd:ed:25:9c:fb:
+ dd:24:0a:bd:59:91:4a:42:03:38:12:71:32:88:76:a0:8e:7c:
+ bb:32:ef:88:2a:1b:d4:6a:6f:50:b9:52:67:8b:ab:30:fa:1f:
+ fd:e3:24:9a
+-----BEGIN CERTIFICATE-----
+MIIEpjCCA46gAwIBAgIQKByJKWYUQ4BCY1U6MkCuszANBgkqhkiG9w0BAQsFADCB
+mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
+MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
+cml0eSAtIEczMB4XDTE1MDYzMDAwMDAwMFoXDTI1MDYyOTIzNTk1OVowRzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlk
+U1NMIFNIQTI1NiBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAwJ46D5qyutPS3BXs0DBUWTBNQFGuQnFx0o1Tc4H+uODElsWOfsLxt2NKz6ce
+P6jnzlOg+i331ubOcBGm7uEDUtJo3j0IDYf9HNcLl2JtgjB2G0c6xPfO7R18jLcX
+jlOAHh0PXYz5kOQEHgJ+y7BJ79pSJfv7Z+3dhHRZhA7z3nBmjeRSOPdTWjcTZws+
+u6hYty7t/7deEXO5d0VSZ0auxNwkgYl2CsqhbGZzBIKq9XBsXxuaAHlG1n96Jhcw
+zzlLLHTZiUR2ENDt94u7iQV1TQsNs9rpv/FqfSoR2x6fjOPEBmnhHYhFOdFuVdiq
+t5tv6vTerBcRkl1Am4N7muL3qQIDAQABo4IBOjCCATYwLgYIKwYBBQUHAQEEIjAg
+MB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wEgYDVR0TAQH/BAgwBgEB
+/wIBADBJBgNVHSAEQjBAMD4GBmeBDAECATA0MDIGCCsGAQUFBwIBFiZodHRwczov
+L3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA2BgNVHR8ELzAtMCugKaAn
+hiVodHRwOi8vZy5zeW1jYi5jb20vR2VvVHJ1c3RQQ0EtRzMuY3JsMB0GA1UdJQQW
+MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FPO1VgzECbC0zx+q+d0jVvB36KH5MB8GA1UdIwQYMBaAFMR5yo6hTgMdHNxr2zFb
+lD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQDDftiDSwRMVSkqTxSdmm7ekHDBpCZM
+iI54SO+9nLCg9fBm/P5ZJuF578i3YGSoi0fqL+CDmdpBGdfFvgX68pAR8Ar/bNwF
+tNgGb6Rvjb4gK1Tb+aJFg5oepSGJNR18IFwX/QQuRdiyxvhCmfxUCE5LgF85N7qV
+TqY3Cp6TXodb6ZDWqLZlCI1hSeuDIKldGxZgYmsvVPtaAg16J+JL4QUUwuTp+XDA
+2fc0ZQ6ikUusKPK3CA+Yytc+cLbIC/GLnFH4xhBs0lNPYowRAD6I37/m0sxwve0l
+nPvdJAq9WZFKQgM4EnEyiHagjny7Mu+IKhvUam9QuVJni6sw+h/94ySa
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert24[] = {
+ 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x28, 0x1c, 0x89, 0x29, 0x66, 0x14, 0x43, 0x80, 0x42,
+ 0x63, 0x55, 0x3a, 0x32, 0x40, 0xae, 0xb3, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65,
+ 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
+ 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c,
+ 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d,
+ 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
+ 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x35, 0x30, 0x36, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x36, 0x32, 0x39, 0x32, 0x33,
+ 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14,
+ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72,
+ 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64,
+ 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43,
+ 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+ 0x01, 0x01, 0x00, 0xc0, 0x9e, 0x3a, 0x0f, 0x9a, 0xb2, 0xba, 0xd3, 0xd2,
+ 0xdc, 0x15, 0xec, 0xd0, 0x30, 0x54, 0x59, 0x30, 0x4d, 0x40, 0x51, 0xae,
+ 0x42, 0x71, 0x71, 0xd2, 0x8d, 0x53, 0x73, 0x81, 0xfe, 0xb8, 0xe0, 0xc4,
+ 0x96, 0xc5, 0x8e, 0x7e, 0xc2, 0xf1, 0xb7, 0x63, 0x4a, 0xcf, 0xa7, 0x1e,
+ 0x3f, 0xa8, 0xe7, 0xce, 0x53, 0xa0, 0xfa, 0x2d, 0xf7, 0xd6, 0xe6, 0xce,
+ 0x70, 0x11, 0xa6, 0xee, 0xe1, 0x03, 0x52, 0xd2, 0x68, 0xde, 0x3d, 0x08,
+ 0x0d, 0x87, 0xfd, 0x1c, 0xd7, 0x0b, 0x97, 0x62, 0x6d, 0x82, 0x30, 0x76,
+ 0x1b, 0x47, 0x3a, 0xc4, 0xf7, 0xce, 0xed, 0x1d, 0x7c, 0x8c, 0xb7, 0x17,
+ 0x8e, 0x53, 0x80, 0x1e, 0x1d, 0x0f, 0x5d, 0x8c, 0xf9, 0x90, 0xe4, 0x04,
+ 0x1e, 0x02, 0x7e, 0xcb, 0xb0, 0x49, 0xef, 0xda, 0x52, 0x25, 0xfb, 0xfb,
+ 0x67, 0xed, 0xdd, 0x84, 0x74, 0x59, 0x84, 0x0e, 0xf3, 0xde, 0x70, 0x66,
+ 0x8d, 0xe4, 0x52, 0x38, 0xf7, 0x53, 0x5a, 0x37, 0x13, 0x67, 0x0b, 0x3e,
+ 0xbb, 0xa8, 0x58, 0xb7, 0x2e, 0xed, 0xff, 0xb7, 0x5e, 0x11, 0x73, 0xb9,
+ 0x77, 0x45, 0x52, 0x67, 0x46, 0xae, 0xc4, 0xdc, 0x24, 0x81, 0x89, 0x76,
+ 0x0a, 0xca, 0xa1, 0x6c, 0x66, 0x73, 0x04, 0x82, 0xaa, 0xf5, 0x70, 0x6c,
+ 0x5f, 0x1b, 0x9a, 0x00, 0x79, 0x46, 0xd6, 0x7f, 0x7a, 0x26, 0x17, 0x30,
+ 0xcf, 0x39, 0x4b, 0x2c, 0x74, 0xd9, 0x89, 0x44, 0x76, 0x10, 0xd0, 0xed,
+ 0xf7, 0x8b, 0xbb, 0x89, 0x05, 0x75, 0x4d, 0x0b, 0x0d, 0xb3, 0xda, 0xe9,
+ 0xbf, 0xf1, 0x6a, 0x7d, 0x2a, 0x11, 0xdb, 0x1e, 0x9f, 0x8c, 0xe3, 0xc4,
+ 0x06, 0x69, 0xe1, 0x1d, 0x88, 0x45, 0x39, 0xd1, 0x6e, 0x55, 0xd8, 0xaa,
+ 0xb7, 0x9b, 0x6f, 0xea, 0xf4, 0xde, 0xac, 0x17, 0x11, 0x92, 0x5d, 0x40,
+ 0x9b, 0x83, 0x7b, 0x9a, 0xe2, 0xf7, 0xa9, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x82, 0x01, 0x3a, 0x30, 0x82, 0x01, 0x36, 0x30, 0x2e, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20,
+ 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
+ 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73,
+ 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03,
+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
+ 0xff, 0x02, 0x01, 0x00, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x42, 0x30, 0x40, 0x30, 0x3e, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02,
+ 0x01, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x36, 0x06, 0x03, 0x55,
+ 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27,
+ 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73,
+ 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f,
+ 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16,
+ 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
+ 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0xf3, 0xb5, 0x56, 0x0c, 0xc4, 0x09, 0xb0, 0xb4, 0xcf, 0x1f, 0xaa,
+ 0xf9, 0xdd, 0x23, 0x56, 0xf0, 0x77, 0xe8, 0xa1, 0xf9, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc4, 0x79,
+ 0xca, 0x8e, 0xa1, 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b, 0xdb, 0x31, 0x5b,
+ 0x94, 0x3e, 0x3f, 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x01, 0x00, 0xc3, 0x7e, 0xd8, 0x83, 0x4b, 0x04, 0x4c, 0x55, 0x29, 0x2a,
+ 0x4f, 0x14, 0x9d, 0x9a, 0x6e, 0xde, 0x90, 0x70, 0xc1, 0xa4, 0x26, 0x4c,
+ 0x88, 0x8e, 0x78, 0x48, 0xef, 0xbd, 0x9c, 0xb0, 0xa0, 0xf5, 0xf0, 0x66,
+ 0xfc, 0xfe, 0x59, 0x26, 0xe1, 0x79, 0xef, 0xc8, 0xb7, 0x60, 0x64, 0xa8,
+ 0x8b, 0x47, 0xea, 0x2f, 0xe0, 0x83, 0x99, 0xda, 0x41, 0x19, 0xd7, 0xc5,
+ 0xbe, 0x05, 0xfa, 0xf2, 0x90, 0x11, 0xf0, 0x0a, 0xff, 0x6c, 0xdc, 0x05,
+ 0xb4, 0xd8, 0x06, 0x6f, 0xa4, 0x6f, 0x8d, 0xbe, 0x20, 0x2b, 0x54, 0xdb,
+ 0xf9, 0xa2, 0x45, 0x83, 0x9a, 0x1e, 0xa5, 0x21, 0x89, 0x35, 0x1d, 0x7c,
+ 0x20, 0x5c, 0x17, 0xfd, 0x04, 0x2e, 0x45, 0xd8, 0xb2, 0xc6, 0xf8, 0x42,
+ 0x99, 0xfc, 0x54, 0x08, 0x4e, 0x4b, 0x80, 0x5f, 0x39, 0x37, 0xba, 0x95,
+ 0x4e, 0xa6, 0x37, 0x0a, 0x9e, 0x93, 0x5e, 0x87, 0x5b, 0xe9, 0x90, 0xd6,
+ 0xa8, 0xb6, 0x65, 0x08, 0x8d, 0x61, 0x49, 0xeb, 0x83, 0x20, 0xa9, 0x5d,
+ 0x1b, 0x16, 0x60, 0x62, 0x6b, 0x2f, 0x54, 0xfb, 0x5a, 0x02, 0x0d, 0x7a,
+ 0x27, 0xe2, 0x4b, 0xe1, 0x05, 0x14, 0xc2, 0xe4, 0xe9, 0xf9, 0x70, 0xc0,
+ 0xd9, 0xf7, 0x34, 0x65, 0x0e, 0xa2, 0x91, 0x4b, 0xac, 0x28, 0xf2, 0xb7,
+ 0x08, 0x0f, 0x98, 0xca, 0xd7, 0x3e, 0x70, 0xb6, 0xc8, 0x0b, 0xf1, 0x8b,
+ 0x9c, 0x51, 0xf8, 0xc6, 0x10, 0x6c, 0xd2, 0x53, 0x4f, 0x62, 0x8c, 0x11,
+ 0x00, 0x3e, 0x88, 0xdf, 0xbf, 0xe6, 0xd2, 0xcc, 0x70, 0xbd, 0xed, 0x25,
+ 0x9c, 0xfb, 0xdd, 0x24, 0x0a, 0xbd, 0x59, 0x91, 0x4a, 0x42, 0x03, 0x38,
+ 0x12, 0x71, 0x32, 0x88, 0x76, 0xa0, 0x8e, 0x7c, 0xbb, 0x32, 0xef, 0x88,
+ 0x2a, 0x1b, 0xd4, 0x6a, 0x6f, 0x50, 0xb9, 0x52, 0x67, 0x8b, 0xab, 0x30,
+ 0xfa, 0x1f, 0xfd, 0xe3, 0x24, 0x9a,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 5d:72:fb:33:76:20:f6:4c:72:80:db:e9:12:81:ff:6a
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
+ Validity
+ Not Before: Oct 31 00:00:00 2013 GMT
+ Not After : Oct 30 23:59:59 2023 GMT
+ Subject: C=US, O=thawte, Inc., CN=thawte EV SSL CA - G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c4:dd:da:94:1e:32:b2:2e:a0:83:c0:a6:7d:5f:
+ 65:2d:fd:27:b8:73:0e:f8:0b:a9:d4:56:26:69:98:
+ 67:35:39:64:58:ce:82:6f:98:94:d1:8f:e0:90:d6:
+ ed:55:4b:98:4b:d7:10:59:34:02:1b:e7:51:31:51:
+ c4:38:c2:bc:db:03:5c:ca:e1:7c:dc:4f:59:97:ea:
+ 07:7f:0f:85:3e:92:ea:aa:a7:d9:be:01:41:e4:62:
+ 56:47:36:bd:57:91:e6:21:d3:f8:41:0b:d8:ba:e8:
+ ed:81:ad:70:c0:8b:6e:f3:89:6e:27:9e:a6:a6:73:
+ 59:bb:71:00:d4:4f:4b:48:e9:d5:c9:27:36:9c:7c:
+ 1c:02:aa:ac:bd:3b:d1:53:83:6a:1f:e6:08:47:33:
+ a7:b1:9f:02:be:9b:47:ed:33:04:dc:1c:80:27:d1:
+ 4a:33:a0:8c:eb:01:47:a1:32:90:64:7b:c4:e0:84:
+ c9:32:e9:dd:34:1f:8a:68:67:f3:ad:10:63:eb:ee:
+ 8a:9a:b1:2a:1b:26:74:a1:2a:b0:8f:fe:52:98:46:
+ 97:cf:a3:56:1c:6f:6e:99:97:8d:26:0e:a9:ec:c2:
+ 53:70:fc:7a:a5:19:49:bd:b5:17:82:55:de:97:e0:
+ 5d:62:84:81:f0:70:a8:34:53:4f:14:fd:3d:5d:3d:
+ 6f:b9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://t2.symcb.com
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.thawte.com/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://t1.symcb.com/ThawtePCA.crl
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=SymantecPKI-1-536
+ X509v3 Subject Key Identifier:
+ F0:70:51:DA:D3:2A:91:4F:52:77:D7:86:77:74:0F:CE:71:1A:6C:22
+ X509v3 Authority Key Identifier:
+ keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
+
+ Signature Algorithm: sha256WithRSAEncryption
+ a1:2e:94:3e:9b:16:f4:58:1a:6f:c1:fa:c1:7e:43:93:b2:c3:
+ f7:89:eb:13:62:5d:dd:cc:61:13:2b:1d:4e:88:79:11:62:14:
+ 37:30:46:ff:89:62:10:85:2a:87:1e:f8:e2:af:fe:93:02:93:
+ ca:f2:e9:46:03:6b:a1:1a:ac:d5:f0:80:1b:98:6f:b8:3a:50:
+ f8:54:71:06:03:e7:84:cc:8e:61:d2:5f:4d:0c:97:02:65:b5:
+ 8c:26:bc:05:98:f4:dc:c6:af:e4:57:7f:e3:dc:a1:d7:27:47:
+ 2a:e0:2c:3f:09:74:dc:5a:e5:b5:7c:fa:82:9a:15:fa:74:2b:
+ 84:2e:6b:ac:ef:35:a6:30:fa:47:4a:aa:36:44:f6:5a:91:07:
+ d3:e4:4e:97:3f:a6:53:d8:29:33:32:6f:8b:3d:b5:a5:0d:e5:
+ e4:8a:e8:f5:c0:fa:af:d8:37:28:27:c3:ed:34:31:d9:7c:a6:
+ af:4d:12:4f:d0:2b:92:9c:69:95:f2:28:a6:fe:a8:c6:e0:2c:
+ 4d:36:eb:11:34:d6:e1:81:99:9d:41:f2:e7:c5:57:05:0e:19:
+ ca:af:42:39:1f:a7:27:5e:e0:0a:17:b8:ae:47:ab:92:f1:8a:
+ 04:df:30:e0:bb:4f:8a:f9:1b:88:4f:03:b4:25:7a:78:de:2e:
+ 7d:29:d1:31
+-----BEGIN CERTIFICATE-----
+MIIErzCCA5egAwIBAgIQXXL7M3Yg9kxygNvpEoH/ajANBgkqhkiG9w0BAQsFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx
+MDMwMjM1OTU5WjBEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
+MR4wHAYDVQQDExV0aGF3dGUgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDE3dqUHjKyLqCDwKZ9X2Ut/Se4cw74C6nUViZpmGc1
+OWRYzoJvmJTRj+CQ1u1VS5hL1xBZNAIb51ExUcQ4wrzbA1zK4XzcT1mX6gd/D4U+
+kuqqp9m+AUHkYlZHNr1XkeYh0/hBC9i66O2BrXDAi27ziW4nnqamc1m7cQDUT0tI
+6dXJJzacfBwCqqy9O9FTg2of5ghHM6exnwK+m0ftMwTcHIAn0UozoIzrAUehMpBk
+e8TghMky6d00H4poZ/OtEGPr7oqasSobJnShKrCP/lKYRpfPo1Ycb26Zl40mDqns
+wlNw/HqlGUm9tReCVd6X4F1ihIHwcKg0U08U/T1dPW+5AgMBAAGjggE1MIIBMTAS
+BgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQj
+MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly90Mi5zeW1jYi5jb20wOwYDVR0gBDQwMjAw
+BgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3Bz
+MDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly90MS5zeW1jYi5jb20vVGhhd3RlUENB
+LmNybDApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01MzYw
+HQYDVR0OBBYEFPBwUdrTKpFPUnfXhnd0D85xGmwiMB8GA1UdIwQYMBaAFHtbRc+v
+zst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQChLpQ+mxb0WBpvwfrB
+fkOTssP3iesTYl3dzGETKx1OiHkRYhQ3MEb/iWIQhSqHHvjir/6TApPK8ulGA2uh
+GqzV8IAbmG+4OlD4VHEGA+eEzI5h0l9NDJcCZbWMJrwFmPTcxq/kV3/j3KHXJ0cq
+4Cw/CXTcWuW1fPqCmhX6dCuELmus7zWmMPpHSqo2RPZakQfT5E6XP6ZT2CkzMm+L
+PbWlDeXkiuj1wPqv2DcoJ8PtNDHZfKavTRJP0CuSnGmV8iim/qjG4CxNNusRNNbh
+gZmdQfLnxVcFDhnKr0I5H6cnXuAKF7iuR6uS8YoE3zDgu0+K+RuITwO0JXp43i59
+KdEx
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert25[] = {
+ 0x30, 0x82, 0x04, 0xaf, 0x30, 0x82, 0x03, 0x97, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x5d, 0x72, 0xfb, 0x33, 0x76, 0x20, 0xf6, 0x4c, 0x72,
+ 0x80, 0xdb, 0xe9, 0x12, 0x81, 0xff, 0x6a, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+ 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+ 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+ 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+ 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31,
+ 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x44,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74,
+ 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c,
+ 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xdd, 0xda, 0x94, 0x1e, 0x32, 0xb2,
+ 0x2e, 0xa0, 0x83, 0xc0, 0xa6, 0x7d, 0x5f, 0x65, 0x2d, 0xfd, 0x27, 0xb8,
+ 0x73, 0x0e, 0xf8, 0x0b, 0xa9, 0xd4, 0x56, 0x26, 0x69, 0x98, 0x67, 0x35,
+ 0x39, 0x64, 0x58, 0xce, 0x82, 0x6f, 0x98, 0x94, 0xd1, 0x8f, 0xe0, 0x90,
+ 0xd6, 0xed, 0x55, 0x4b, 0x98, 0x4b, 0xd7, 0x10, 0x59, 0x34, 0x02, 0x1b,
+ 0xe7, 0x51, 0x31, 0x51, 0xc4, 0x38, 0xc2, 0xbc, 0xdb, 0x03, 0x5c, 0xca,
+ 0xe1, 0x7c, 0xdc, 0x4f, 0x59, 0x97, 0xea, 0x07, 0x7f, 0x0f, 0x85, 0x3e,
+ 0x92, 0xea, 0xaa, 0xa7, 0xd9, 0xbe, 0x01, 0x41, 0xe4, 0x62, 0x56, 0x47,
+ 0x36, 0xbd, 0x57, 0x91, 0xe6, 0x21, 0xd3, 0xf8, 0x41, 0x0b, 0xd8, 0xba,
+ 0xe8, 0xed, 0x81, 0xad, 0x70, 0xc0, 0x8b, 0x6e, 0xf3, 0x89, 0x6e, 0x27,
+ 0x9e, 0xa6, 0xa6, 0x73, 0x59, 0xbb, 0x71, 0x00, 0xd4, 0x4f, 0x4b, 0x48,
+ 0xe9, 0xd5, 0xc9, 0x27, 0x36, 0x9c, 0x7c, 0x1c, 0x02, 0xaa, 0xac, 0xbd,
+ 0x3b, 0xd1, 0x53, 0x83, 0x6a, 0x1f, 0xe6, 0x08, 0x47, 0x33, 0xa7, 0xb1,
+ 0x9f, 0x02, 0xbe, 0x9b, 0x47, 0xed, 0x33, 0x04, 0xdc, 0x1c, 0x80, 0x27,
+ 0xd1, 0x4a, 0x33, 0xa0, 0x8c, 0xeb, 0x01, 0x47, 0xa1, 0x32, 0x90, 0x64,
+ 0x7b, 0xc4, 0xe0, 0x84, 0xc9, 0x32, 0xe9, 0xdd, 0x34, 0x1f, 0x8a, 0x68,
+ 0x67, 0xf3, 0xad, 0x10, 0x63, 0xeb, 0xee, 0x8a, 0x9a, 0xb1, 0x2a, 0x1b,
+ 0x26, 0x74, 0xa1, 0x2a, 0xb0, 0x8f, 0xfe, 0x52, 0x98, 0x46, 0x97, 0xcf,
+ 0xa3, 0x56, 0x1c, 0x6f, 0x6e, 0x99, 0x97, 0x8d, 0x26, 0x0e, 0xa9, 0xec,
+ 0xc2, 0x53, 0x70, 0xfc, 0x7a, 0xa5, 0x19, 0x49, 0xbd, 0xb5, 0x17, 0x82,
+ 0x55, 0xde, 0x97, 0xe0, 0x5d, 0x62, 0x84, 0x81, 0xf0, 0x70, 0xa8, 0x34,
+ 0x53, 0x4f, 0x14, 0xfd, 0x3d, 0x5d, 0x3d, 0x6f, 0xb9, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x35, 0x30, 0x82, 0x01, 0x31, 0x30, 0x12,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
+ 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23,
+ 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74,
+ 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+ 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30,
+ 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74,
+ 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68,
+ 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73,
+ 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30,
+ 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x74, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41,
+ 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
+ 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74,
+ 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x36, 0x30,
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf0, 0x70,
+ 0x51, 0xda, 0xd3, 0x2a, 0x91, 0x4f, 0x52, 0x77, 0xd7, 0x86, 0x77, 0x74,
+ 0x0f, 0xce, 0x71, 0x1a, 0x6c, 0x22, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf,
+ 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb,
+ 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa1,
+ 0x2e, 0x94, 0x3e, 0x9b, 0x16, 0xf4, 0x58, 0x1a, 0x6f, 0xc1, 0xfa, 0xc1,
+ 0x7e, 0x43, 0x93, 0xb2, 0xc3, 0xf7, 0x89, 0xeb, 0x13, 0x62, 0x5d, 0xdd,
+ 0xcc, 0x61, 0x13, 0x2b, 0x1d, 0x4e, 0x88, 0x79, 0x11, 0x62, 0x14, 0x37,
+ 0x30, 0x46, 0xff, 0x89, 0x62, 0x10, 0x85, 0x2a, 0x87, 0x1e, 0xf8, 0xe2,
+ 0xaf, 0xfe, 0x93, 0x02, 0x93, 0xca, 0xf2, 0xe9, 0x46, 0x03, 0x6b, 0xa1,
+ 0x1a, 0xac, 0xd5, 0xf0, 0x80, 0x1b, 0x98, 0x6f, 0xb8, 0x3a, 0x50, 0xf8,
+ 0x54, 0x71, 0x06, 0x03, 0xe7, 0x84, 0xcc, 0x8e, 0x61, 0xd2, 0x5f, 0x4d,
+ 0x0c, 0x97, 0x02, 0x65, 0xb5, 0x8c, 0x26, 0xbc, 0x05, 0x98, 0xf4, 0xdc,
+ 0xc6, 0xaf, 0xe4, 0x57, 0x7f, 0xe3, 0xdc, 0xa1, 0xd7, 0x27, 0x47, 0x2a,
+ 0xe0, 0x2c, 0x3f, 0x09, 0x74, 0xdc, 0x5a, 0xe5, 0xb5, 0x7c, 0xfa, 0x82,
+ 0x9a, 0x15, 0xfa, 0x74, 0x2b, 0x84, 0x2e, 0x6b, 0xac, 0xef, 0x35, 0xa6,
+ 0x30, 0xfa, 0x47, 0x4a, 0xaa, 0x36, 0x44, 0xf6, 0x5a, 0x91, 0x07, 0xd3,
+ 0xe4, 0x4e, 0x97, 0x3f, 0xa6, 0x53, 0xd8, 0x29, 0x33, 0x32, 0x6f, 0x8b,
+ 0x3d, 0xb5, 0xa5, 0x0d, 0xe5, 0xe4, 0x8a, 0xe8, 0xf5, 0xc0, 0xfa, 0xaf,
+ 0xd8, 0x37, 0x28, 0x27, 0xc3, 0xed, 0x34, 0x31, 0xd9, 0x7c, 0xa6, 0xaf,
+ 0x4d, 0x12, 0x4f, 0xd0, 0x2b, 0x92, 0x9c, 0x69, 0x95, 0xf2, 0x28, 0xa6,
+ 0xfe, 0xa8, 0xc6, 0xe0, 0x2c, 0x4d, 0x36, 0xeb, 0x11, 0x34, 0xd6, 0xe1,
+ 0x81, 0x99, 0x9d, 0x41, 0xf2, 0xe7, 0xc5, 0x57, 0x05, 0x0e, 0x19, 0xca,
+ 0xaf, 0x42, 0x39, 0x1f, 0xa7, 0x27, 0x5e, 0xe0, 0x0a, 0x17, 0xb8, 0xae,
+ 0x47, 0xab, 0x92, 0xf1, 0x8a, 0x04, 0xdf, 0x30, 0xe0, 0xbb, 0x4f, 0x8a,
+ 0xf9, 0x1b, 0x88, 0x4f, 0x03, 0xb4, 0x25, 0x7a, 0x78, 0xde, 0x2e, 0x7d,
+ 0x29, 0xd1, 0x31,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 04:e1:e7:a4:dc:5c:f2:f3:6d:c0:2b:42:b8:5d:15:9f
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
+ Validity
+ Not Before: Oct 22 12:00:00 2013 GMT
+ Not After : Oct 22 12:00:00 2028 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b6:e0:2f:c2:24:06:c8:6d:04:5f:d7:ef:0a:64:
+ 06:b2:7d:22:26:65:16:ae:42:40:9b:ce:dc:9f:9f:
+ 76:07:3e:c3:30:55:87:19:b9:4f:94:0e:5a:94:1f:
+ 55:56:b4:c2:02:2a:af:d0:98:ee:0b:40:d7:c4:d0:
+ 3b:72:c8:14:9e:ef:90:b1:11:a9:ae:d2:c8:b8:43:
+ 3a:d9:0b:0b:d5:d5:95:f5:40:af:c8:1d:ed:4d:9c:
+ 5f:57:b7:86:50:68:99:f5:8a:da:d2:c7:05:1f:a8:
+ 97:c9:dc:a4:b1:82:84:2d:c6:ad:a5:9c:c7:19:82:
+ a6:85:0f:5e:44:58:2a:37:8f:fd:35:f1:0b:08:27:
+ 32:5a:f5:bb:8b:9e:a4:bd:51:d0:27:e2:dd:3b:42:
+ 33:a3:05:28:c4:bb:28:cc:9a:ac:2b:23:0d:78:c6:
+ 7b:e6:5e:71:b7:4a:3e:08:fb:81:b7:16:16:a1:9d:
+ 23:12:4d:e5:d7:92:08:ac:75:a4:9c:ba:cd:17:b2:
+ 1e:44:35:65:7f:53:25:39:d1:1c:0a:9a:63:1b:19:
+ 92:74:68:0a:37:c2:c2:52:48:cb:39:5a:a2:b6:e1:
+ 5d:c1:dd:a0:20:b8:21:a2:93:26:6f:14:4a:21:41:
+ c7:ed:6d:9b:f2:48:2f:f3:03:f5:a2:68:92:53:2f:
+ 5e:e3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Authority Information Access:
+ OCSP - URI:http://ocsp.digicert.com
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.digicert.com/CPS
+
+ X509v3 Subject Key Identifier:
+ 51:68:FF:90:AF:02:07:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B
+ X509v3 Authority Key Identifier:
+ keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 18:8a:95:89:03:e6:6d:df:5c:fc:1d:68:ea:4a:8f:83:d6:51:
+ 2f:8d:6b:44:16:9e:ac:63:f5:d2:6e:6c:84:99:8b:aa:81:71:
+ 84:5b:ed:34:4e:b0:b7:79:92:29:cc:2d:80:6a:f0:8e:20:e1:
+ 79:a4:fe:03:47:13:ea:f5:86:ca:59:71:7d:f4:04:96:6b:d3:
+ 59:58:3d:fe:d3:31:25:5c:18:38:84:a3:e6:9f:82:fd:8c:5b:
+ 98:31:4e:cd:78:9e:1a:fd:85:cb:49:aa:f2:27:8b:99:72:fc:
+ 3e:aa:d5:41:0b:da:d5:36:a1:bf:1c:6e:47:49:7f:5e:d9:48:
+ 7c:03:d9:fd:8b:49:a0:98:26:42:40:eb:d6:92:11:a4:64:0a:
+ 57:54:c4:f5:1d:d6:02:5e:6b:ac:ee:c4:80:9a:12:72:fa:56:
+ 93:d7:ff:bf:30:85:06:30:bf:0b:7f:4e:ff:57:05:9d:24:ed:
+ 85:c3:2b:fb:a6:75:a8:ac:2d:16:ef:7d:79:27:b2:eb:c2:9d:
+ 0b:07:ea:aa:85:d3:01:a3:20:28:41:59:43:28:d2:81:e3:aa:
+ f6:ec:7b:3b:77:b6:40:62:80:05:41:45:01:ef:17:06:3e:de:
+ c0:33:9b:67:d3:61:2e:72:87:e4:69:fc:12:00:57:40:1e:70:
+ f5:1e:c9:b4
+-----BEGIN CERTIFICATE-----
+MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy
+YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2
+4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC
+Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1
+itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn
+4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X
+sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft
+bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA
+MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
+NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
+dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t
+L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG
+BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ
+UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D
+aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd
+aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH
+E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly
+/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu
+xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF
+0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae
+cPUeybQ=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert26[] = {
+ 0x30, 0x82, 0x04, 0xb1, 0x30, 0x82, 0x03, 0x99, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x04, 0xe1, 0xe7, 0xa4, 0xdc, 0x5c, 0xf2, 0xf3, 0x6d,
+ 0xc0, 0x2b, 0x42, 0xb8, 0x5d, 0x15, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
+ 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
+ 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
+ 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+ 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32,
+ 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32,
+ 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x70, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
+ 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
+ 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
+ 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41,
+ 0x32, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72,
+ 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
+ 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6,
+ 0xe0, 0x2f, 0xc2, 0x24, 0x06, 0xc8, 0x6d, 0x04, 0x5f, 0xd7, 0xef, 0x0a,
+ 0x64, 0x06, 0xb2, 0x7d, 0x22, 0x26, 0x65, 0x16, 0xae, 0x42, 0x40, 0x9b,
+ 0xce, 0xdc, 0x9f, 0x9f, 0x76, 0x07, 0x3e, 0xc3, 0x30, 0x55, 0x87, 0x19,
+ 0xb9, 0x4f, 0x94, 0x0e, 0x5a, 0x94, 0x1f, 0x55, 0x56, 0xb4, 0xc2, 0x02,
+ 0x2a, 0xaf, 0xd0, 0x98, 0xee, 0x0b, 0x40, 0xd7, 0xc4, 0xd0, 0x3b, 0x72,
+ 0xc8, 0x14, 0x9e, 0xef, 0x90, 0xb1, 0x11, 0xa9, 0xae, 0xd2, 0xc8, 0xb8,
+ 0x43, 0x3a, 0xd9, 0x0b, 0x0b, 0xd5, 0xd5, 0x95, 0xf5, 0x40, 0xaf, 0xc8,
+ 0x1d, 0xed, 0x4d, 0x9c, 0x5f, 0x57, 0xb7, 0x86, 0x50, 0x68, 0x99, 0xf5,
+ 0x8a, 0xda, 0xd2, 0xc7, 0x05, 0x1f, 0xa8, 0x97, 0xc9, 0xdc, 0xa4, 0xb1,
+ 0x82, 0x84, 0x2d, 0xc6, 0xad, 0xa5, 0x9c, 0xc7, 0x19, 0x82, 0xa6, 0x85,
+ 0x0f, 0x5e, 0x44, 0x58, 0x2a, 0x37, 0x8f, 0xfd, 0x35, 0xf1, 0x0b, 0x08,
+ 0x27, 0x32, 0x5a, 0xf5, 0xbb, 0x8b, 0x9e, 0xa4, 0xbd, 0x51, 0xd0, 0x27,
+ 0xe2, 0xdd, 0x3b, 0x42, 0x33, 0xa3, 0x05, 0x28, 0xc4, 0xbb, 0x28, 0xcc,
+ 0x9a, 0xac, 0x2b, 0x23, 0x0d, 0x78, 0xc6, 0x7b, 0xe6, 0x5e, 0x71, 0xb7,
+ 0x4a, 0x3e, 0x08, 0xfb, 0x81, 0xb7, 0x16, 0x16, 0xa1, 0x9d, 0x23, 0x12,
+ 0x4d, 0xe5, 0xd7, 0x92, 0x08, 0xac, 0x75, 0xa4, 0x9c, 0xba, 0xcd, 0x17,
+ 0xb2, 0x1e, 0x44, 0x35, 0x65, 0x7f, 0x53, 0x25, 0x39, 0xd1, 0x1c, 0x0a,
+ 0x9a, 0x63, 0x1b, 0x19, 0x92, 0x74, 0x68, 0x0a, 0x37, 0xc2, 0xc2, 0x52,
+ 0x48, 0xcb, 0x39, 0x5a, 0xa2, 0xb6, 0xe1, 0x5d, 0xc1, 0xdd, 0xa0, 0x20,
+ 0xb8, 0x21, 0xa2, 0x93, 0x26, 0x6f, 0x14, 0x4a, 0x21, 0x41, 0xc7, 0xed,
+ 0x6d, 0x9b, 0xf2, 0x48, 0x2f, 0xf3, 0x03, 0xf5, 0xa2, 0x68, 0x92, 0x53,
+ 0x2f, 0x5e, 0xe3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x49,
+ 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+ 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
+ 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
+ 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
+ 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+ 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
+ 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e,
+ 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67,
+ 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56,
+ 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
+ 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67,
+ 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50,
+ 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x51, 0x68, 0xff, 0x90, 0xaf, 0x02, 0x07, 0x75, 0x3c, 0xcc, 0xd9, 0x65,
+ 0x64, 0x62, 0xa2, 0x12, 0xb8, 0x59, 0x72, 0x3b, 0x30, 0x1f, 0x06, 0x03,
+ 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3,
+ 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02,
+ 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+ 0x00, 0x18, 0x8a, 0x95, 0x89, 0x03, 0xe6, 0x6d, 0xdf, 0x5c, 0xfc, 0x1d,
+ 0x68, 0xea, 0x4a, 0x8f, 0x83, 0xd6, 0x51, 0x2f, 0x8d, 0x6b, 0x44, 0x16,
+ 0x9e, 0xac, 0x63, 0xf5, 0xd2, 0x6e, 0x6c, 0x84, 0x99, 0x8b, 0xaa, 0x81,
+ 0x71, 0x84, 0x5b, 0xed, 0x34, 0x4e, 0xb0, 0xb7, 0x79, 0x92, 0x29, 0xcc,
+ 0x2d, 0x80, 0x6a, 0xf0, 0x8e, 0x20, 0xe1, 0x79, 0xa4, 0xfe, 0x03, 0x47,
+ 0x13, 0xea, 0xf5, 0x86, 0xca, 0x59, 0x71, 0x7d, 0xf4, 0x04, 0x96, 0x6b,
+ 0xd3, 0x59, 0x58, 0x3d, 0xfe, 0xd3, 0x31, 0x25, 0x5c, 0x18, 0x38, 0x84,
+ 0xa3, 0xe6, 0x9f, 0x82, 0xfd, 0x8c, 0x5b, 0x98, 0x31, 0x4e, 0xcd, 0x78,
+ 0x9e, 0x1a, 0xfd, 0x85, 0xcb, 0x49, 0xaa, 0xf2, 0x27, 0x8b, 0x99, 0x72,
+ 0xfc, 0x3e, 0xaa, 0xd5, 0x41, 0x0b, 0xda, 0xd5, 0x36, 0xa1, 0xbf, 0x1c,
+ 0x6e, 0x47, 0x49, 0x7f, 0x5e, 0xd9, 0x48, 0x7c, 0x03, 0xd9, 0xfd, 0x8b,
+ 0x49, 0xa0, 0x98, 0x26, 0x42, 0x40, 0xeb, 0xd6, 0x92, 0x11, 0xa4, 0x64,
+ 0x0a, 0x57, 0x54, 0xc4, 0xf5, 0x1d, 0xd6, 0x02, 0x5e, 0x6b, 0xac, 0xee,
+ 0xc4, 0x80, 0x9a, 0x12, 0x72, 0xfa, 0x56, 0x93, 0xd7, 0xff, 0xbf, 0x30,
+ 0x85, 0x06, 0x30, 0xbf, 0x0b, 0x7f, 0x4e, 0xff, 0x57, 0x05, 0x9d, 0x24,
+ 0xed, 0x85, 0xc3, 0x2b, 0xfb, 0xa6, 0x75, 0xa8, 0xac, 0x2d, 0x16, 0xef,
+ 0x7d, 0x79, 0x27, 0xb2, 0xeb, 0xc2, 0x9d, 0x0b, 0x07, 0xea, 0xaa, 0x85,
+ 0xd3, 0x01, 0xa3, 0x20, 0x28, 0x41, 0x59, 0x43, 0x28, 0xd2, 0x81, 0xe3,
+ 0xaa, 0xf6, 0xec, 0x7b, 0x3b, 0x77, 0xb6, 0x40, 0x62, 0x80, 0x05, 0x41,
+ 0x45, 0x01, 0xef, 0x17, 0x06, 0x3e, 0xde, 0xc0, 0x33, 0x9b, 0x67, 0xd3,
+ 0x61, 0x2e, 0x72, 0x87, 0xe4, 0x69, 0xfc, 0x12, 0x00, 0x57, 0x40, 0x1e,
+ 0x70, 0xf5, 0x1e, 0xc9, 0xb4,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 16:87:d6:88:6d:e2:30:06:85:23:3d:bf:11:bf:65:97
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
+ Validity
+ Not Before: Oct 31 00:00:00 2013 GMT
+ Not After : Oct 30 23:59:59 2023 GMT
+ Subject: C=US, O=thawte, Inc., CN=thawte SSL CA - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b2:fc:06:fb:04:93:d2:ea:59:20:3b:44:85:97:
+ 52:39:e7:10:f0:7a:e0:b0:94:40:da:46:f8:0c:28:
+ bb:b9:ce:60:38:3f:d2:d8:11:42:1b:91:ad:49:ee:
+ 8f:c7:de:6c:de:37:6f:fd:8b:20:3c:6d:e7:74:d3:
+ dc:d5:24:88:41:80:89:ee:36:be:c4:d5:be:8d:53:
+ 13:aa:e4:a5:b8:93:0a:be:ec:da:cd:3c:d4:32:56:
+ ef:d0:4e:a0:b8:97:bb:39:50:1e:6e:65:c3:fd:b2:
+ ce:e0:59:a9:48:09:c6:fe:be:ae:fc:3e:3b:81:20:
+ 97:8b:8f:46:df:60:64:07:75:bb:1b:86:38:9f:47:
+ 7b:34:ce:a1:d1:97:ad:76:d8:9f:b7:26:db:79:80:
+ 36:48:f2:c5:37:f8:d9:32:ae:7c:a4:53:81:c7:99:
+ a1:54:38:2f:4f:75:a0:bb:5a:a5:bb:cd:ac:02:5b:
+ 19:02:d5:13:18:a7:ce:ac:74:55:12:05:8b:9b:a2:
+ 95:46:64:72:38:cd:5a:1b:3a:16:a7:be:71:99:8c:
+ 54:03:b8:96:6c:01:d3:3e:06:98:3f:21:81:3b:02:
+ 7e:00:47:53:01:1e:0e:46:43:fb:4b:2d:dc:0b:1a:
+ e8:2f:98:f8:7e:d1:99:ab:13:6c:a4:17:de:6f:f6:
+ 15:f5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://t1.symcb.com/ThawtePCA.crl
+
+ Authority Information Access:
+ OCSP - URI:http://t2.symcb.com
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: https://www.thawte.com/cps
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=SymantecPKI-1-537
+ X509v3 Subject Key Identifier:
+ C2:4F:48:57:FC:D1:4F:9A:C0:5D:38:7D:0E:05:DB:D9:2E:B5:52:60
+ X509v3 Authority Key Identifier:
+ keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 8d:06:de:43:c9:76:02:ca:d9:23:97:5e:f3:63:d7:7d:44:c2:
+ 0f:6b:0a:f5:07:e5:8b:b8:fa:e0:a3:fa:6b:80:92:b5:03:2c:
+ c5:37:e0:c2:e5:95:b5:92:70:18:28:42:94:ee:4b:77:6a:01:
+ 0f:8b:23:ec:56:4d:f4:00:69:e5:84:c8:e2:ea:de:5b:3e:f6:
+ 3c:07:3a:94:ca:6c:27:b1:cc:83:1a:60:71:27:d2:bf:02:f5:
+ 1e:44:d3:48:d5:a6:d3:76:21:00:9c:fa:98:64:eb:17:36:3f:
+ eb:1b:3c:3e:a6:b1:d9:58:06:0e:72:d9:68:be:f1:a7:20:d7:
+ 52:e4:a4:77:1f:71:70:9d:55:35:85:37:e1:1d:4d:94:c2:70:
+ 7f:95:40:6e:4b:7d:b2:b4:29:2a:03:79:c8:b9:4c:67:61:04:
+ a0:8b:27:ff:59:00:eb:55:7f:c6:b7:33:35:2d:5e:4e:ac:b8:
+ ea:12:c5:e8:f7:b9:ab:be:74:92:2c:b7:d9:4d:ca:84:2f:1c:
+ c2:f0:72:7c:b2:31:6e:cf:80:e5:88:07:36:51:7b:ba:61:af:
+ 6d:8d:23:5b:34:a3:95:bc:a2:31:7f:f2:f5:e7:b7:e8:ef:c4:
+ b5:27:32:e9:f7:9e:69:c7:2b:e8:be:bb:0c:aa:e7:ea:60:12:
+ ea:26:8a:78
+-----BEGIN CERTIFICATE-----
+MIIEsjCCA5qgAwIBAgIQFofWiG3iMAaFIz2/Eb9llzANBgkqhkiG9w0BAQsFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx
+MDMwMjM1OTU5WjBBMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
+MRswGQYDVQQDExJ0aGF3dGUgU1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCy/Ab7BJPS6lkgO0SFl1I55xDweuCwlEDaRvgMKLu5zmA4
+P9LYEUIbka1J7o/H3mzeN2/9iyA8bed009zVJIhBgInuNr7E1b6NUxOq5KW4kwq+
+7NrNPNQyVu/QTqC4l7s5UB5uZcP9ss7gWalICcb+vq78PjuBIJeLj0bfYGQHdbsb
+hjifR3s0zqHRl6122J+3Jtt5gDZI8sU3+NkyrnykU4HHmaFUOC9PdaC7WqW7zawC
+WxkC1RMYp86sdFUSBYubopVGZHI4zVobOhanvnGZjFQDuJZsAdM+Bpg/IYE7An4A
+R1MBHg5GQ/tLLdwLGugvmPh+0ZmrE2ykF95v9hX1AgMBAAGjggE7MIIBNzASBgNV
+HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAyBgNVHR8EKzApMCegJaAj
+hiFodHRwOi8vdDEuc3ltY2IuY29tL1RoYXd0ZVBDQS5jcmwwLwYIKwYBBQUHAQEE
+IzAhMB8GCCsGAQUFBzABhhNodHRwOi8vdDIuc3ltY2IuY29tMEEGA1UdIAQ6MDgw
+NgYKYIZIAYb4RQEHNjAoMCYGCCsGAQUFBwIBFhpodHRwczovL3d3dy50aGF3dGUu
+Y29tL2NwczApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01
+MzcwHQYDVR0OBBYEFMJPSFf80U+awF04fQ4F29kutVJgMB8GA1UdIwQYMBaAFHtb
+Rc+vzst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQCNBt5DyXYCytkj
+l17zY9d9RMIPawr1B+WLuPrgo/prgJK1AyzFN+DC5ZW1knAYKEKU7kt3agEPiyPs
+Vk30AGnlhMji6t5bPvY8BzqUymwnscyDGmBxJ9K/AvUeRNNI1abTdiEAnPqYZOsX
+Nj/rGzw+prHZWAYOctlovvGnINdS5KR3H3FwnVU1hTfhHU2UwnB/lUBuS32ytCkq
+A3nIuUxnYQSgiyf/WQDrVX/GtzM1LV5OrLjqEsXo97mrvnSSLLfZTcqELxzC8HJ8
+sjFuz4DliAc2UXu6Ya9tjSNbNKOVvKIxf/L157fo78S1JzLp955pxyvovrsMqufq
+YBLqJop4
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert27[] = {
+ 0x30, 0x82, 0x04, 0xb2, 0x30, 0x82, 0x03, 0x9a, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x16, 0x87, 0xd6, 0x88, 0x6d, 0xe2, 0x30, 0x06, 0x85,
+ 0x23, 0x3d, 0xbf, 0x11, 0xbf, 0x65, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+ 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+ 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+ 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+ 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31,
+ 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x41,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x74,
+ 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
+ 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
+ 0x01, 0x00, 0xb2, 0xfc, 0x06, 0xfb, 0x04, 0x93, 0xd2, 0xea, 0x59, 0x20,
+ 0x3b, 0x44, 0x85, 0x97, 0x52, 0x39, 0xe7, 0x10, 0xf0, 0x7a, 0xe0, 0xb0,
+ 0x94, 0x40, 0xda, 0x46, 0xf8, 0x0c, 0x28, 0xbb, 0xb9, 0xce, 0x60, 0x38,
+ 0x3f, 0xd2, 0xd8, 0x11, 0x42, 0x1b, 0x91, 0xad, 0x49, 0xee, 0x8f, 0xc7,
+ 0xde, 0x6c, 0xde, 0x37, 0x6f, 0xfd, 0x8b, 0x20, 0x3c, 0x6d, 0xe7, 0x74,
+ 0xd3, 0xdc, 0xd5, 0x24, 0x88, 0x41, 0x80, 0x89, 0xee, 0x36, 0xbe, 0xc4,
+ 0xd5, 0xbe, 0x8d, 0x53, 0x13, 0xaa, 0xe4, 0xa5, 0xb8, 0x93, 0x0a, 0xbe,
+ 0xec, 0xda, 0xcd, 0x3c, 0xd4, 0x32, 0x56, 0xef, 0xd0, 0x4e, 0xa0, 0xb8,
+ 0x97, 0xbb, 0x39, 0x50, 0x1e, 0x6e, 0x65, 0xc3, 0xfd, 0xb2, 0xce, 0xe0,
+ 0x59, 0xa9, 0x48, 0x09, 0xc6, 0xfe, 0xbe, 0xae, 0xfc, 0x3e, 0x3b, 0x81,
+ 0x20, 0x97, 0x8b, 0x8f, 0x46, 0xdf, 0x60, 0x64, 0x07, 0x75, 0xbb, 0x1b,
+ 0x86, 0x38, 0x9f, 0x47, 0x7b, 0x34, 0xce, 0xa1, 0xd1, 0x97, 0xad, 0x76,
+ 0xd8, 0x9f, 0xb7, 0x26, 0xdb, 0x79, 0x80, 0x36, 0x48, 0xf2, 0xc5, 0x37,
+ 0xf8, 0xd9, 0x32, 0xae, 0x7c, 0xa4, 0x53, 0x81, 0xc7, 0x99, 0xa1, 0x54,
+ 0x38, 0x2f, 0x4f, 0x75, 0xa0, 0xbb, 0x5a, 0xa5, 0xbb, 0xcd, 0xac, 0x02,
+ 0x5b, 0x19, 0x02, 0xd5, 0x13, 0x18, 0xa7, 0xce, 0xac, 0x74, 0x55, 0x12,
+ 0x05, 0x8b, 0x9b, 0xa2, 0x95, 0x46, 0x64, 0x72, 0x38, 0xcd, 0x5a, 0x1b,
+ 0x3a, 0x16, 0xa7, 0xbe, 0x71, 0x99, 0x8c, 0x54, 0x03, 0xb8, 0x96, 0x6c,
+ 0x01, 0xd3, 0x3e, 0x06, 0x98, 0x3f, 0x21, 0x81, 0x3b, 0x02, 0x7e, 0x00,
+ 0x47, 0x53, 0x01, 0x1e, 0x0e, 0x46, 0x43, 0xfb, 0x4b, 0x2d, 0xdc, 0x0b,
+ 0x1a, 0xe8, 0x2f, 0x98, 0xf8, 0x7e, 0xd1, 0x99, 0xab, 0x13, 0x6c, 0xa4,
+ 0x17, 0xde, 0x6f, 0xf6, 0x15, 0xf5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+ 0x82, 0x01, 0x3b, 0x30, 0x82, 0x01, 0x37, 0x30, 0x12, 0x06, 0x03, 0x55,
+ 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+ 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x32, 0x06, 0x03, 0x55,
+ 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23,
+ 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74, 0x31, 0x2e,
+ 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68,
+ 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+ 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x74, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38, 0x30,
+ 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07,
+ 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55,
+ 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a,
+ 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d,
+ 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35,
+ 0x33, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0xc2, 0x4f, 0x48, 0x57, 0xfc, 0xd1, 0x4f, 0x9a, 0xc0, 0x5d, 0x38,
+ 0x7d, 0x0e, 0x05, 0xdb, 0xd9, 0x2e, 0xb5, 0x52, 0x60, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b,
+ 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6,
+ 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x01, 0x00, 0x8d, 0x06, 0xde, 0x43, 0xc9, 0x76, 0x02, 0xca, 0xd9, 0x23,
+ 0x97, 0x5e, 0xf3, 0x63, 0xd7, 0x7d, 0x44, 0xc2, 0x0f, 0x6b, 0x0a, 0xf5,
+ 0x07, 0xe5, 0x8b, 0xb8, 0xfa, 0xe0, 0xa3, 0xfa, 0x6b, 0x80, 0x92, 0xb5,
+ 0x03, 0x2c, 0xc5, 0x37, 0xe0, 0xc2, 0xe5, 0x95, 0xb5, 0x92, 0x70, 0x18,
+ 0x28, 0x42, 0x94, 0xee, 0x4b, 0x77, 0x6a, 0x01, 0x0f, 0x8b, 0x23, 0xec,
+ 0x56, 0x4d, 0xf4, 0x00, 0x69, 0xe5, 0x84, 0xc8, 0xe2, 0xea, 0xde, 0x5b,
+ 0x3e, 0xf6, 0x3c, 0x07, 0x3a, 0x94, 0xca, 0x6c, 0x27, 0xb1, 0xcc, 0x83,
+ 0x1a, 0x60, 0x71, 0x27, 0xd2, 0xbf, 0x02, 0xf5, 0x1e, 0x44, 0xd3, 0x48,
+ 0xd5, 0xa6, 0xd3, 0x76, 0x21, 0x00, 0x9c, 0xfa, 0x98, 0x64, 0xeb, 0x17,
+ 0x36, 0x3f, 0xeb, 0x1b, 0x3c, 0x3e, 0xa6, 0xb1, 0xd9, 0x58, 0x06, 0x0e,
+ 0x72, 0xd9, 0x68, 0xbe, 0xf1, 0xa7, 0x20, 0xd7, 0x52, 0xe4, 0xa4, 0x77,
+ 0x1f, 0x71, 0x70, 0x9d, 0x55, 0x35, 0x85, 0x37, 0xe1, 0x1d, 0x4d, 0x94,
+ 0xc2, 0x70, 0x7f, 0x95, 0x40, 0x6e, 0x4b, 0x7d, 0xb2, 0xb4, 0x29, 0x2a,
+ 0x03, 0x79, 0xc8, 0xb9, 0x4c, 0x67, 0x61, 0x04, 0xa0, 0x8b, 0x27, 0xff,
+ 0x59, 0x00, 0xeb, 0x55, 0x7f, 0xc6, 0xb7, 0x33, 0x35, 0x2d, 0x5e, 0x4e,
+ 0xac, 0xb8, 0xea, 0x12, 0xc5, 0xe8, 0xf7, 0xb9, 0xab, 0xbe, 0x74, 0x92,
+ 0x2c, 0xb7, 0xd9, 0x4d, 0xca, 0x84, 0x2f, 0x1c, 0xc2, 0xf0, 0x72, 0x7c,
+ 0xb2, 0x31, 0x6e, 0xcf, 0x80, 0xe5, 0x88, 0x07, 0x36, 0x51, 0x7b, 0xba,
+ 0x61, 0xaf, 0x6d, 0x8d, 0x23, 0x5b, 0x34, 0xa3, 0x95, 0xbc, 0xa2, 0x31,
+ 0x7f, 0xf2, 0xf5, 0xe7, 0xb7, 0xe8, 0xef, 0xc4, 0xb5, 0x27, 0x32, 0xe9,
+ 0xf7, 0x9e, 0x69, 0xc7, 0x2b, 0xe8, 0xbe, 0xbb, 0x0c, 0xaa, 0xe7, 0xea,
+ 0x60, 0x12, 0xea, 0x26, 0x8a, 0x78,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0c:79:a9:44:b0:8c:11:95:20:92:61:5f:e2:6b:1d:83
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
+ Validity
+ Not Before: Oct 22 12:00:00 2013 GMT
+ Not After : Oct 22 12:00:00 2028 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d7:53:a4:04:51:f8:99:a6:16:48:4b:67:27:aa:
+ 93:49:d0:39:ed:0c:b0:b0:00:87:f1:67:28:86:85:
+ 8c:8e:63:da:bc:b1:40:38:e2:d3:f5:ec:a5:05:18:
+ b8:3d:3e:c5:99:17:32:ec:18:8c:fa:f1:0c:a6:64:
+ 21:85:cb:07:10:34:b0:52:88:2b:1f:68:9b:d2:b1:
+ 8f:12:b0:b3:d2:e7:88:1f:1f:ef:38:77:54:53:5f:
+ 80:79:3f:2e:1a:aa:a8:1e:4b:2b:0d:ab:b7:63:b9:
+ 35:b7:7d:14:bc:59:4b:df:51:4a:d2:a1:e2:0c:e2:
+ 90:82:87:6a:ae:ea:d7:64:d6:98:55:e8:fd:af:1a:
+ 50:6c:54:bc:11:f2:fd:4a:f2:9d:bb:7f:0e:f4:d5:
+ be:8e:16:89:12:55:d8:c0:71:34:ee:f6:dc:2d:ec:
+ c4:87:25:86:8d:d8:21:e4:b0:4d:0c:89:dc:39:26:
+ 17:dd:f6:d7:94:85:d8:04:21:70:9d:6f:6f:ff:5c:
+ ba:19:e1:45:cb:56:57:28:7e:1c:0d:41:57:aa:b7:
+ b8:27:bb:b1:e4:fa:2a:ef:21:23:75:1a:ad:2d:9b:
+ 86:35:8c:9c:77:b5:73:ad:d8:94:2d:e4:f3:0c:9d:
+ ee:c1:4e:62:7e:17:c0:71:9e:2c:de:f1:f9:10:28:
+ 19:33
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Authority Information Access:
+ OCSP - URI:http://ocsp.digicert.com
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.digicert.com/CPS
+
+ X509v3 Subject Key Identifier:
+ 3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F
+ X509v3 Authority Key Identifier:
+ keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 9d:b6:d0:90:86:e1:86:02:ed:c5:a0:f0:34:1c:74:c1:8d:76:
+ cc:86:0a:a8:f0:4a:8a:42:d6:3f:c8:a9:4d:ad:7c:08:ad:e6:
+ b6:50:b8:a2:1a:4d:88:07:b1:29:21:dc:e7:da:c6:3c:21:e0:
+ e3:11:49:70:ac:7a:1d:01:a4:ca:11:3a:57:ab:7d:57:2a:40:
+ 74:fd:d3:1d:85:18:50:df:57:47:75:a1:7d:55:20:2e:47:37:
+ 50:72:8c:7f:82:1b:d2:62:8f:2d:03:5a:da:c3:c8:a1:ce:2c:
+ 52:a2:00:63:eb:73:ba:71:c8:49:27:23:97:64:85:9e:38:0e:
+ ad:63:68:3c:ba:52:81:58:79:a3:2c:0c:df:de:6d:eb:31:f2:
+ ba:a0:7c:6c:f1:2c:d4:e1:bd:77:84:37:03:ce:32:b5:c8:9a:
+ 81:1a:4a:92:4e:3b:46:9a:85:fe:83:a2:f9:9e:8c:a3:cc:0d:
+ 5e:b3:3d:cf:04:78:8f:14:14:7b:32:9c:c7:00:a6:5c:c4:b5:
+ a1:55:8d:5a:56:68:a4:22:70:aa:3c:81:71:d9:9d:a8:45:3b:
+ f4:e5:f6:a2:51:dd:c7:7b:62:e8:6f:0c:74:eb:b8:da:f8:bf:
+ 87:0d:79:50:91:90:9b:18:3b:91:59:27:f1:35:28:13:ab:26:
+ 7e:d5:f7:7a
+-----BEGIN CERTIFICATE-----
+MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW
+YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY
+uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/
+LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy
+/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh
+cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k
+8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB
+Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
+BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
+Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy
+dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2
+MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j
+b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW
+gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh
+hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg
+4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa
+2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs
+1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1
+oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn
+8TUoE6smftX3eg==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert28[] = {
+ 0x30, 0x82, 0x04, 0xb6, 0x30, 0x82, 0x03, 0x9e, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x0c, 0x79, 0xa9, 0x44, 0xb0, 0x8c, 0x11, 0x95, 0x20,
+ 0x92, 0x61, 0x5f, 0xe2, 0x6b, 0x1d, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
+ 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
+ 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
+ 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+ 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32,
+ 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32,
+ 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x75, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
+ 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
+ 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
+ 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41,
+ 0x32, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56,
+ 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+ 0x82, 0x01, 0x01, 0x00, 0xd7, 0x53, 0xa4, 0x04, 0x51, 0xf8, 0x99, 0xa6,
+ 0x16, 0x48, 0x4b, 0x67, 0x27, 0xaa, 0x93, 0x49, 0xd0, 0x39, 0xed, 0x0c,
+ 0xb0, 0xb0, 0x00, 0x87, 0xf1, 0x67, 0x28, 0x86, 0x85, 0x8c, 0x8e, 0x63,
+ 0xda, 0xbc, 0xb1, 0x40, 0x38, 0xe2, 0xd3, 0xf5, 0xec, 0xa5, 0x05, 0x18,
+ 0xb8, 0x3d, 0x3e, 0xc5, 0x99, 0x17, 0x32, 0xec, 0x18, 0x8c, 0xfa, 0xf1,
+ 0x0c, 0xa6, 0x64, 0x21, 0x85, 0xcb, 0x07, 0x10, 0x34, 0xb0, 0x52, 0x88,
+ 0x2b, 0x1f, 0x68, 0x9b, 0xd2, 0xb1, 0x8f, 0x12, 0xb0, 0xb3, 0xd2, 0xe7,
+ 0x88, 0x1f, 0x1f, 0xef, 0x38, 0x77, 0x54, 0x53, 0x5f, 0x80, 0x79, 0x3f,
+ 0x2e, 0x1a, 0xaa, 0xa8, 0x1e, 0x4b, 0x2b, 0x0d, 0xab, 0xb7, 0x63, 0xb9,
+ 0x35, 0xb7, 0x7d, 0x14, 0xbc, 0x59, 0x4b, 0xdf, 0x51, 0x4a, 0xd2, 0xa1,
+ 0xe2, 0x0c, 0xe2, 0x90, 0x82, 0x87, 0x6a, 0xae, 0xea, 0xd7, 0x64, 0xd6,
+ 0x98, 0x55, 0xe8, 0xfd, 0xaf, 0x1a, 0x50, 0x6c, 0x54, 0xbc, 0x11, 0xf2,
+ 0xfd, 0x4a, 0xf2, 0x9d, 0xbb, 0x7f, 0x0e, 0xf4, 0xd5, 0xbe, 0x8e, 0x16,
+ 0x89, 0x12, 0x55, 0xd8, 0xc0, 0x71, 0x34, 0xee, 0xf6, 0xdc, 0x2d, 0xec,
+ 0xc4, 0x87, 0x25, 0x86, 0x8d, 0xd8, 0x21, 0xe4, 0xb0, 0x4d, 0x0c, 0x89,
+ 0xdc, 0x39, 0x26, 0x17, 0xdd, 0xf6, 0xd7, 0x94, 0x85, 0xd8, 0x04, 0x21,
+ 0x70, 0x9d, 0x6f, 0x6f, 0xff, 0x5c, 0xba, 0x19, 0xe1, 0x45, 0xcb, 0x56,
+ 0x57, 0x28, 0x7e, 0x1c, 0x0d, 0x41, 0x57, 0xaa, 0xb7, 0xb8, 0x27, 0xbb,
+ 0xb1, 0xe4, 0xfa, 0x2a, 0xef, 0x21, 0x23, 0x75, 0x1a, 0xad, 0x2d, 0x9b,
+ 0x86, 0x35, 0x8c, 0x9c, 0x77, 0xb5, 0x73, 0xad, 0xd8, 0x94, 0x2d, 0xe4,
+ 0xf3, 0x0c, 0x9d, 0xee, 0xc1, 0x4e, 0x62, 0x7e, 0x17, 0xc0, 0x71, 0x9e,
+ 0x2c, 0xde, 0xf1, 0xf9, 0x10, 0x28, 0x19, 0x33, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x82, 0x01, 0x49, 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06,
+ 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01,
+ 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+ 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06,
+ 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x02, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69,
+ 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b,
+ 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0,
+ 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65,
+ 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61,
+ 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36,
+ 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a,
+ 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
+ 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+ 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3d, 0xd3, 0x50, 0xa5, 0xd6, 0xa0, 0xad,
+ 0xee, 0xf3, 0x4a, 0x60, 0x0a, 0x65, 0xd3, 0x21, 0xd4, 0xf8, 0xf8, 0xd6,
+ 0x0f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4,
+ 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xb6, 0xd0, 0x90, 0x86, 0xe1,
+ 0x86, 0x02, 0xed, 0xc5, 0xa0, 0xf0, 0x34, 0x1c, 0x74, 0xc1, 0x8d, 0x76,
+ 0xcc, 0x86, 0x0a, 0xa8, 0xf0, 0x4a, 0x8a, 0x42, 0xd6, 0x3f, 0xc8, 0xa9,
+ 0x4d, 0xad, 0x7c, 0x08, 0xad, 0xe6, 0xb6, 0x50, 0xb8, 0xa2, 0x1a, 0x4d,
+ 0x88, 0x07, 0xb1, 0x29, 0x21, 0xdc, 0xe7, 0xda, 0xc6, 0x3c, 0x21, 0xe0,
+ 0xe3, 0x11, 0x49, 0x70, 0xac, 0x7a, 0x1d, 0x01, 0xa4, 0xca, 0x11, 0x3a,
+ 0x57, 0xab, 0x7d, 0x57, 0x2a, 0x40, 0x74, 0xfd, 0xd3, 0x1d, 0x85, 0x18,
+ 0x50, 0xdf, 0x57, 0x47, 0x75, 0xa1, 0x7d, 0x55, 0x20, 0x2e, 0x47, 0x37,
+ 0x50, 0x72, 0x8c, 0x7f, 0x82, 0x1b, 0xd2, 0x62, 0x8f, 0x2d, 0x03, 0x5a,
+ 0xda, 0xc3, 0xc8, 0xa1, 0xce, 0x2c, 0x52, 0xa2, 0x00, 0x63, 0xeb, 0x73,
+ 0xba, 0x71, 0xc8, 0x49, 0x27, 0x23, 0x97, 0x64, 0x85, 0x9e, 0x38, 0x0e,
+ 0xad, 0x63, 0x68, 0x3c, 0xba, 0x52, 0x81, 0x58, 0x79, 0xa3, 0x2c, 0x0c,
+ 0xdf, 0xde, 0x6d, 0xeb, 0x31, 0xf2, 0xba, 0xa0, 0x7c, 0x6c, 0xf1, 0x2c,
+ 0xd4, 0xe1, 0xbd, 0x77, 0x84, 0x37, 0x03, 0xce, 0x32, 0xb5, 0xc8, 0x9a,
+ 0x81, 0x1a, 0x4a, 0x92, 0x4e, 0x3b, 0x46, 0x9a, 0x85, 0xfe, 0x83, 0xa2,
+ 0xf9, 0x9e, 0x8c, 0xa3, 0xcc, 0x0d, 0x5e, 0xb3, 0x3d, 0xcf, 0x04, 0x78,
+ 0x8f, 0x14, 0x14, 0x7b, 0x32, 0x9c, 0xc7, 0x00, 0xa6, 0x5c, 0xc4, 0xb5,
+ 0xa1, 0x55, 0x8d, 0x5a, 0x56, 0x68, 0xa4, 0x22, 0x70, 0xaa, 0x3c, 0x81,
+ 0x71, 0xd9, 0x9d, 0xa8, 0x45, 0x3b, 0xf4, 0xe5, 0xf6, 0xa2, 0x51, 0xdd,
+ 0xc7, 0x7b, 0x62, 0xe8, 0x6f, 0x0c, 0x74, 0xeb, 0xb8, 0xda, 0xf8, 0xbf,
+ 0x87, 0x0d, 0x79, 0x50, 0x91, 0x90, 0x9b, 0x18, 0x3b, 0x91, 0x59, 0x27,
+ 0xf1, 0x35, 0x28, 0x13, 0xab, 0x26, 0x7e, 0xd5, 0xf7, 0x7a,
+};
diff --git a/chromium/net/quic/crypto/common_cert_set_2b.inc b/chromium/net/quic/crypto/common_cert_set_2b.inc
new file mode 100644
index 00000000000..55f120d3ae5
--- /dev/null
+++ b/chromium/net/quic/crypto/common_cert_set_2b.inc
@@ -0,0 +1,5744 @@
+/* Copyright (c) 2015 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.
+ */
+
+/* This file contains common certificates. It's designed to be #included in
+ * another file, in a namespace. */
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 36:34:9e:18:c9:9c:26:69:b6:56:2e:6c:e5:ad:71:32
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
+ Validity
+ Not Before: May 23 00:00:00 2013 GMT
+ Not After : May 22 23:59:59 2023 GMT
+ Subject: C=US, O=thawte, Inc., CN=thawte SHA256 SSL CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a3:63:2b:d4:ba:5d:38:ae:b0:cf:b9:4c:38:df:
+ 20:7d:f1:2b:47:71:1d:8b:68:f3:56:f9:9c:da:aa:
+ e5:84:26:de:a5:71:30:bc:f3:31:23:9d:e8:3b:80:
+ c8:66:57:75:b6:57:0e:db:93:f5:26:8e:70:ba:64:
+ 52:66:8a:2a:88:5c:44:18:4d:a8:a2:7c:bd:56:61:
+ 32:90:12:f9:35:87:48:60:b0:6e:90:67:44:01:8d:
+ e7:c9:0d:63:68:72:72:ab:63:3c:86:b8:1f:7d:ad:
+ 88:25:a7:6a:88:29:fb:59:c6:78:71:5f:2c:ba:89:
+ e6:d3:80:fd:57:ec:b9:51:5f:43:33:2e:7e:25:3b:
+ a4:04:d1:60:8c:b3:44:33:93:0c:ad:2a:b6:44:a2:
+ 19:3b:af:c4:90:6f:7b:05:87:86:9b:2c:6a:9d:2b:
+ 6c:77:c9:00:9f:c9:cf:ac:ed:3e:1b:f7:c3:f3:d9:
+ f8:6c:d4:a0:57:c4:fb:28:32:aa:33:f0:e6:ba:98:
+ df:e5:c2:4e:9c:74:bf:8a:48:c2:f2:1b:f0:77:40:
+ 41:07:04:b2:3a:d5:4c:c4:29:a9:11:40:3f:02:46:
+ f0:91:d5:d2:81:83:86:13:b3:31:ed:46:ab:a8:87:
+ 76:a9:99:7d:bc:cd:31:50:f4:a5:b5:dc:a5:32:b3:
+ 8b:8b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ OCSP - URI:http://ocsp.thawte.com
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: https://www.thawte.com/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.thawte.com/ThawtePCA-G3.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Alternative Name:
+ DirName:/CN=VeriSignMPKI-2-415
+ X509v3 Subject Key Identifier:
+ 2B:9A:35:AE:01:18:38:30:E1:70:7A:05:E0:11:76:A3:CE:BD:90:14
+ X509v3 Authority Key Identifier:
+ keyid:AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 74:a6:56:e8:af:93:96:19:fb:26:f9:0d:b0:44:a5:cd:e9:7a:
+ 48:03:74:01:6c:13:71:b7:e0:82:90:99:62:23:e3:d6:99:af:
+ f0:c7:1e:9e:a8:18:21:db:b4:94:3f:34:56:1b:99:55:2f:8e:
+ f0:45:33:32:b7:72:c1:13:5b:34:d3:f5:60:e5:2e:18:d1:5c:
+ c5:6a:c1:aa:87:50:0c:1c:9d:64:2b:ff:1b:dc:d5:2e:61:0b:
+ e7:b9:b6:91:53:86:d9:03:2a:d1:3d:7b:4a:da:2b:07:be:29:
+ f2:60:42:a9:91:1a:0e:2e:3c:d1:7d:a5:13:14:02:fa:ee:8b:
+ 8d:b6:c8:b8:3e:56:81:57:21:24:3f:65:c3:b4:c9:ce:5c:8d:
+ 46:ac:53:f3:f9:55:74:c8:2b:fd:d2:78:70:f5:f8:11:e5:f4:
+ a7:ad:20:f5:9d:f1:ec:70:f6:13:ac:e6:8c:8d:db:3f:c6:f2:
+ 79:0e:ab:52:f2:cc:1b:79:27:cf:16:b3:d6:f3:c6:36:80:43:
+ ec:c5:94:f0:dd:90:8d:f8:c6:52:46:56:eb:74:47:be:a6:f3:
+ 19:ae:71:4c:c0:e1:e7:d4:cf:ed:d4:06:28:2a:11:3c:ba:d9:
+ 41:6e:00:e7:81:37:93:e4:da:62:c6:1d:67:6f:63:b4:14:86:
+ d9:a6:62:f0
+-----BEGIN CERTIFICATE-----
+MIIEwjCCA6qgAwIBAgIQNjSeGMmcJmm2Vi5s5a1xMjANBgkqhkiG9w0BAQsFADCB
+rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
+BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0xMzA1MjMwMDAwMDBa
+Fw0yMzA1MjIyMzU5NTlaMEMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUs
+IEluYy4xHTAbBgNVBAMTFHRoYXd0ZSBTSEEyNTYgU1NMIENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo2Mr1LpdOK6wz7lMON8gffErR3Edi2jzVvmc
+2qrlhCbepXEwvPMxI53oO4DIZld1tlcO25P1Jo5wumRSZooqiFxEGE2oony9VmEy
+kBL5NYdIYLBukGdEAY3nyQ1jaHJyq2M8hrgffa2IJadqiCn7WcZ4cV8suonm04D9
+V+y5UV9DMy5+JTukBNFgjLNEM5MMrSq2RKIZO6/EkG97BYeGmyxqnStsd8kAn8nP
+rO0+G/fD89n4bNSgV8T7KDKqM/Dmupjf5cJOnHS/ikjC8hvwd0BBBwSyOtVMxCmp
+EUA/AkbwkdXSgYOGE7Mx7UarqId2qZl9vM0xUPSltdylMrOLiwIDAQABo4IBRDCC
+AUAwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3
+dGUuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwQQYDVR0gBDowODA2BgpghkgBhvhF
+AQc2MCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3BzMDcG
+A1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQQ0Et
+RzMuY3JsMA4GA1UdDwEB/wQEAwIBBjAqBgNVHREEIzAhpB8wHTEbMBkGA1UEAxMS
+VmVyaVNpZ25NUEtJLTItNDE1MB0GA1UdDgQWBBQrmjWuARg4MOFwegXgEXajzr2Q
+FDAfBgNVHSMEGDAWgBStbKqUYJzt5P/6Pgp0K2MD97ZZvzANBgkqhkiG9w0BAQsF
+AAOCAQEAdKZW6K+Tlhn7JvkNsESlzel6SAN0AWwTcbfggpCZYiPj1pmv8McenqgY
+Idu0lD80VhuZVS+O8EUzMrdywRNbNNP1YOUuGNFcxWrBqodQDBydZCv/G9zVLmEL
+57m2kVOG2QMq0T17StorB74p8mBCqZEaDi480X2lExQC+u6LjbbIuD5WgVchJD9l
+w7TJzlyNRqxT8/lVdMgr/dJ4cPX4EeX0p60g9Z3x7HD2E6zmjI3bP8byeQ6rUvLM
+G3knzxaz1vPGNoBD7MWU8N2QjfjGUkZW63RHvqbzGa5xTMDh59TP7dQGKCoRPLrZ
+QW4A54E3k+TaYsYdZ29jtBSG2aZi8A==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert29[] = {
+ 0x30, 0x82, 0x04, 0xc2, 0x30, 0x82, 0x03, 0xaa, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x36, 0x34, 0x9e, 0x18, 0xc9, 0x9c, 0x26, 0x69, 0xb6,
+ 0x56, 0x2e, 0x6c, 0xe5, 0xad, 0x71, 0x32, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+ 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+ 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+ 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x1b, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+ 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+ 0x33, 0x30, 0x35, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+ 0x17, 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x32, 0x32, 0x33, 0x35, 0x39,
+ 0x35, 0x39, 0x5a, 0x30, 0x43, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
+ 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x14, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53,
+ 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41,
+ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x63, 0x2b,
+ 0xd4, 0xba, 0x5d, 0x38, 0xae, 0xb0, 0xcf, 0xb9, 0x4c, 0x38, 0xdf, 0x20,
+ 0x7d, 0xf1, 0x2b, 0x47, 0x71, 0x1d, 0x8b, 0x68, 0xf3, 0x56, 0xf9, 0x9c,
+ 0xda, 0xaa, 0xe5, 0x84, 0x26, 0xde, 0xa5, 0x71, 0x30, 0xbc, 0xf3, 0x31,
+ 0x23, 0x9d, 0xe8, 0x3b, 0x80, 0xc8, 0x66, 0x57, 0x75, 0xb6, 0x57, 0x0e,
+ 0xdb, 0x93, 0xf5, 0x26, 0x8e, 0x70, 0xba, 0x64, 0x52, 0x66, 0x8a, 0x2a,
+ 0x88, 0x5c, 0x44, 0x18, 0x4d, 0xa8, 0xa2, 0x7c, 0xbd, 0x56, 0x61, 0x32,
+ 0x90, 0x12, 0xf9, 0x35, 0x87, 0x48, 0x60, 0xb0, 0x6e, 0x90, 0x67, 0x44,
+ 0x01, 0x8d, 0xe7, 0xc9, 0x0d, 0x63, 0x68, 0x72, 0x72, 0xab, 0x63, 0x3c,
+ 0x86, 0xb8, 0x1f, 0x7d, 0xad, 0x88, 0x25, 0xa7, 0x6a, 0x88, 0x29, 0xfb,
+ 0x59, 0xc6, 0x78, 0x71, 0x5f, 0x2c, 0xba, 0x89, 0xe6, 0xd3, 0x80, 0xfd,
+ 0x57, 0xec, 0xb9, 0x51, 0x5f, 0x43, 0x33, 0x2e, 0x7e, 0x25, 0x3b, 0xa4,
+ 0x04, 0xd1, 0x60, 0x8c, 0xb3, 0x44, 0x33, 0x93, 0x0c, 0xad, 0x2a, 0xb6,
+ 0x44, 0xa2, 0x19, 0x3b, 0xaf, 0xc4, 0x90, 0x6f, 0x7b, 0x05, 0x87, 0x86,
+ 0x9b, 0x2c, 0x6a, 0x9d, 0x2b, 0x6c, 0x77, 0xc9, 0x00, 0x9f, 0xc9, 0xcf,
+ 0xac, 0xed, 0x3e, 0x1b, 0xf7, 0xc3, 0xf3, 0xd9, 0xf8, 0x6c, 0xd4, 0xa0,
+ 0x57, 0xc4, 0xfb, 0x28, 0x32, 0xaa, 0x33, 0xf0, 0xe6, 0xba, 0x98, 0xdf,
+ 0xe5, 0xc2, 0x4e, 0x9c, 0x74, 0xbf, 0x8a, 0x48, 0xc2, 0xf2, 0x1b, 0xf0,
+ 0x77, 0x40, 0x41, 0x07, 0x04, 0xb2, 0x3a, 0xd5, 0x4c, 0xc4, 0x29, 0xa9,
+ 0x11, 0x40, 0x3f, 0x02, 0x46, 0xf0, 0x91, 0xd5, 0xd2, 0x81, 0x83, 0x86,
+ 0x13, 0xb3, 0x31, 0xed, 0x46, 0xab, 0xa8, 0x87, 0x76, 0xa9, 0x99, 0x7d,
+ 0xbc, 0xcd, 0x31, 0x50, 0xf4, 0xa5, 0xb5, 0xdc, 0xa5, 0x32, 0xb3, 0x8b,
+ 0x8b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x44, 0x30, 0x82,
+ 0x01, 0x40, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x01, 0x01, 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77,
+ 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
+ 0x01, 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30,
+ 0x38, 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45,
+ 0x01, 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73,
+ 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74,
+ 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x37, 0x06,
+ 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30, 0x30, 0x2e, 0x30, 0x2c, 0xa0, 0x2a,
+ 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+ 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2d,
+ 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2a,
+ 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30,
+ 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12,
+ 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
+ 0x2d, 0x32, 0x2d, 0x34, 0x31, 0x35, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x9a, 0x35, 0xae, 0x01, 0x18, 0x38,
+ 0x30, 0xe1, 0x70, 0x7a, 0x05, 0xe0, 0x11, 0x76, 0xa3, 0xce, 0xbd, 0x90,
+ 0x14, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0xad, 0x6c, 0xaa, 0x94, 0x60, 0x9c, 0xed, 0xe4, 0xff, 0xfa,
+ 0x3e, 0x0a, 0x74, 0x2b, 0x63, 0x03, 0xf7, 0xb6, 0x59, 0xbf, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0xa6, 0x56, 0xe8, 0xaf, 0x93,
+ 0x96, 0x19, 0xfb, 0x26, 0xf9, 0x0d, 0xb0, 0x44, 0xa5, 0xcd, 0xe9, 0x7a,
+ 0x48, 0x03, 0x74, 0x01, 0x6c, 0x13, 0x71, 0xb7, 0xe0, 0x82, 0x90, 0x99,
+ 0x62, 0x23, 0xe3, 0xd6, 0x99, 0xaf, 0xf0, 0xc7, 0x1e, 0x9e, 0xa8, 0x18,
+ 0x21, 0xdb, 0xb4, 0x94, 0x3f, 0x34, 0x56, 0x1b, 0x99, 0x55, 0x2f, 0x8e,
+ 0xf0, 0x45, 0x33, 0x32, 0xb7, 0x72, 0xc1, 0x13, 0x5b, 0x34, 0xd3, 0xf5,
+ 0x60, 0xe5, 0x2e, 0x18, 0xd1, 0x5c, 0xc5, 0x6a, 0xc1, 0xaa, 0x87, 0x50,
+ 0x0c, 0x1c, 0x9d, 0x64, 0x2b, 0xff, 0x1b, 0xdc, 0xd5, 0x2e, 0x61, 0x0b,
+ 0xe7, 0xb9, 0xb6, 0x91, 0x53, 0x86, 0xd9, 0x03, 0x2a, 0xd1, 0x3d, 0x7b,
+ 0x4a, 0xda, 0x2b, 0x07, 0xbe, 0x29, 0xf2, 0x60, 0x42, 0xa9, 0x91, 0x1a,
+ 0x0e, 0x2e, 0x3c, 0xd1, 0x7d, 0xa5, 0x13, 0x14, 0x02, 0xfa, 0xee, 0x8b,
+ 0x8d, 0xb6, 0xc8, 0xb8, 0x3e, 0x56, 0x81, 0x57, 0x21, 0x24, 0x3f, 0x65,
+ 0xc3, 0xb4, 0xc9, 0xce, 0x5c, 0x8d, 0x46, 0xac, 0x53, 0xf3, 0xf9, 0x55,
+ 0x74, 0xc8, 0x2b, 0xfd, 0xd2, 0x78, 0x70, 0xf5, 0xf8, 0x11, 0xe5, 0xf4,
+ 0xa7, 0xad, 0x20, 0xf5, 0x9d, 0xf1, 0xec, 0x70, 0xf6, 0x13, 0xac, 0xe6,
+ 0x8c, 0x8d, 0xdb, 0x3f, 0xc6, 0xf2, 0x79, 0x0e, 0xab, 0x52, 0xf2, 0xcc,
+ 0x1b, 0x79, 0x27, 0xcf, 0x16, 0xb3, 0xd6, 0xf3, 0xc6, 0x36, 0x80, 0x43,
+ 0xec, 0xc5, 0x94, 0xf0, 0xdd, 0x90, 0x8d, 0xf8, 0xc6, 0x52, 0x46, 0x56,
+ 0xeb, 0x74, 0x47, 0xbe, 0xa6, 0xf3, 0x19, 0xae, 0x71, 0x4c, 0xc0, 0xe1,
+ 0xe7, 0xd4, 0xcf, 0xed, 0xd4, 0x06, 0x28, 0x2a, 0x11, 0x3c, 0xba, 0xd9,
+ 0x41, 0x6e, 0x00, 0xe7, 0x81, 0x37, 0x93, 0xe4, 0xda, 0x62, 0xc6, 0x1d,
+ 0x67, 0x6f, 0x63, 0xb4, 0x14, 0x86, 0xd9, 0xa6, 0x62, 0xf0,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 35:97:31:87:f3:87:3a:07:32:7e:ce:58:0c:9b:7e:da
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ Validity
+ Not Before: Nov 8 00:00:00 2006 GMT
+ Not After : Nov 7 23:59:59 2021 GMT
+ Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
+ 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
+ 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
+ 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
+ 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
+ a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
+ 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
+ d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
+ 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
+ bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
+ f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
+ ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
+ f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
+ 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
+ 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
+ ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
+ 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
+ 25:15
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.verisign.com/pca3.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.verisign.com/cps
+
+ X509v3 Subject Key Identifier:
+ 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+ X509v3 Extended Key Usage:
+ Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1, TLS Web Server Authentication, TLS Web Client Authentication
+ 1.3.6.1.5.5.7.1.12:
+ 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
+ Authority Information Access:
+ OCSP - URI:http://ocsp.verisign.com
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 0f:25:ae:48:ed:1b:33:85:4c:0c:b5:c2:d7:fe:4d:d6:83:28:
+ 4c:41:65:60:00:0b:77:48:71:82:fe:7f:db:5a:0e:20:cc:d2:
+ ea:47:bc:64:42:61:44:34:74:30:81:81:26:8a:4a:f7:44:5d:
+ 7e:34:80:a8:b8:83:e2:09:d7:6d:23:dd:89:ed:28:08:bd:63:
+ 5a:11:57:08:c4:9e:da:e2:68:28:af:dd:50:3c:ec:82:21:d8:
+ 00:c2:55:44:50:70:41:ad:83:17:79:ba:08:f3:2b:de:ed:34:
+ 1d:44:9e:d2:04:93:f4:cb:05:17:2d:09:2d:2d:63:ef:f6:26:
+ 0b:7b
+-----BEGIN CERTIFICATE-----
+MIIExjCCBC+gAwIBAgIQNZcxh/OHOgcyfs5YDJt+2jANBgkqhkiG9w0BAQUFADBf
+MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
+LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
+FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
+dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
+ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
+RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
+ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
+TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
+Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
+iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
+AAGjggGRMIIBjTAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
+dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
+BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
+aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwNAYD
+VR0lBC0wKwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBBggrBgEFBQcDAQYIKwYBBQUH
+AwIwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUr
+DgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNp
+Z24uY29tL3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhho
+dHRwOi8vb2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEADyWuSO0b
+M4VMDLXC1/5N1oMoTEFlYAALd0hxgv5/21oOIMzS6ke8ZEJhRDR0MIGBJopK90Rd
+fjSAqLiD4gnXbSPdie0oCL1jWhFXCMSe2uJoKK/dUDzsgiHYAMJVRFBwQa2DF3m6
+CPMr3u00HUSe0gST9MsFFy0JLS1j7/YmC3s=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert30[] = {
+ 0x30, 0x82, 0x04, 0xc6, 0x30, 0x82, 0x04, 0x2f, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x35, 0x97, 0x31, 0x87, 0xf3, 0x87, 0x3a, 0x07, 0x32,
+ 0x7e, 0xce, 0x58, 0x0c, 0x9b, 0x7e, 0xda, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
+ 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
+ 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+ 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
+ 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
+ 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
+ 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+ 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
+ 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
+ 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
+ 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+ 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+ 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
+ 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
+ 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
+ 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
+ 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
+ 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
+ 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
+ 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
+ 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
+ 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
+ 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
+ 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
+ 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
+ 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
+ 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
+ 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
+ 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
+ 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
+ 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
+ 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
+ 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
+ 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x91, 0x30, 0x82, 0x01, 0x8d, 0x30, 0x0f,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
+ 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
+ 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
+ 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
+ 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
+ 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
+ 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
+ 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
+ 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x34, 0x06, 0x03,
+ 0x55, 0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01,
+ 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x03, 0x02, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59,
+ 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
+ 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b,
+ 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac,
+ 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b,
+ 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69,
+ 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67,
+ 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76,
+ 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+ 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x0f, 0x25, 0xae, 0x48, 0xed, 0x1b,
+ 0x33, 0x85, 0x4c, 0x0c, 0xb5, 0xc2, 0xd7, 0xfe, 0x4d, 0xd6, 0x83, 0x28,
+ 0x4c, 0x41, 0x65, 0x60, 0x00, 0x0b, 0x77, 0x48, 0x71, 0x82, 0xfe, 0x7f,
+ 0xdb, 0x5a, 0x0e, 0x20, 0xcc, 0xd2, 0xea, 0x47, 0xbc, 0x64, 0x42, 0x61,
+ 0x44, 0x34, 0x74, 0x30, 0x81, 0x81, 0x26, 0x8a, 0x4a, 0xf7, 0x44, 0x5d,
+ 0x7e, 0x34, 0x80, 0xa8, 0xb8, 0x83, 0xe2, 0x09, 0xd7, 0x6d, 0x23, 0xdd,
+ 0x89, 0xed, 0x28, 0x08, 0xbd, 0x63, 0x5a, 0x11, 0x57, 0x08, 0xc4, 0x9e,
+ 0xda, 0xe2, 0x68, 0x28, 0xaf, 0xdd, 0x50, 0x3c, 0xec, 0x82, 0x21, 0xd8,
+ 0x00, 0xc2, 0x55, 0x44, 0x50, 0x70, 0x41, 0xad, 0x83, 0x17, 0x79, 0xba,
+ 0x08, 0xf3, 0x2b, 0xde, 0xed, 0x34, 0x1d, 0x44, 0x9e, 0xd2, 0x04, 0x93,
+ 0xf4, 0xcb, 0x05, 0x17, 0x2d, 0x09, 0x2d, 0x2d, 0x63, 0xef, 0xf6, 0x26,
+ 0x0b, 0x7b,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 7 (0x7)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
+ Validity
+ Not Before: May 3 07:00:00 2011 GMT
+ Not After : May 3 07:00:00 2031 GMT
+ Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b9:e0:cb:10:d4:af:76:bd:d4:93:62:eb:30:64:
+ b8:81:08:6c:c3:04:d9:62:17:8e:2f:ff:3e:65:cf:
+ 8f:ce:62:e6:3c:52:1c:da:16:45:4b:55:ab:78:6b:
+ 63:83:62:90:ce:0f:69:6c:99:c8:1a:14:8b:4c:cc:
+ 45:33:ea:88:dc:9e:a3:af:2b:fe:80:61:9d:79:57:
+ c4:cf:2e:f4:3f:30:3c:5d:47:fc:9a:16:bc:c3:37:
+ 96:41:51:8e:11:4b:54:f8:28:be:d0:8c:be:f0:30:
+ 38:1e:f3:b0:26:f8:66:47:63:6d:de:71:26:47:8f:
+ 38:47:53:d1:46:1d:b4:e3:dc:00:ea:45:ac:bd:bc:
+ 71:d9:aa:6f:00:db:db:cd:30:3a:79:4f:5f:4c:47:
+ f8:1d:ef:5b:c2:c4:9d:60:3b:b1:b2:43:91:d8:a4:
+ 33:4e:ea:b3:d6:27:4f:ad:25:8a:a5:c6:f4:d5:d0:
+ a6:ae:74:05:64:57:88:b5:44:55:d4:2d:2a:3a:3e:
+ f8:b8:bd:e9:32:0a:02:94:64:c4:16:3a:50:f1:4a:
+ ae:e7:79:33:af:0c:20:07:7f:e8:df:04:39:c2:69:
+ 02:6c:63:52:fa:77:c1:1b:c8:74:87:c8:b9:93:18:
+ 50:54:35:4b:69:4e:bc:3b:d3:49:2e:1f:dc:c1:d2:
+ 52:fb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
+ X509v3 Authority Key Identifier:
+ keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.godaddy.com/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.godaddy.com/gdroot-g2.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://certs.godaddy.com/repository/
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 08:7e:6c:93:10:c8:38:b8:96:a9:90:4b:ff:a1:5f:4f:04:ef:
+ 6c:3e:9c:88:06:c9:50:8f:a6:73:f7:57:31:1b:be:bc:e4:2f:
+ db:f8:ba:d3:5b:e0:b4:e7:e6:79:62:0e:0c:a2:d7:6a:63:73:
+ 31:b5:f5:a8:48:a4:3b:08:2d:a2:5d:90:d7:b4:7c:25:4f:11:
+ 56:30:c4:b6:44:9d:7b:2c:9d:e5:5e:e6:ef:0c:61:aa:bf:e4:
+ 2a:1b:ee:84:9e:b8:83:7d:c1:43:ce:44:a7:13:70:0d:91:1f:
+ f4:c8:13:ad:83:60:d9:d8:72:a8:73:24:1e:b5:ac:22:0e:ca:
+ 17:89:62:58:44:1b:ab:89:25:01:00:0f:cd:c4:1b:62:db:51:
+ b4:d3:0f:51:2a:9b:f4:bc:73:fc:76:ce:36:a4:cd:d9:d8:2c:
+ ea:ae:9b:f5:2a:b2:90:d1:4d:75:18:8a:3f:8a:41:90:23:7d:
+ 5b:4b:fe:a4:03:58:9b:46:b2:c3:60:60:83:f8:7d:50:41:ce:
+ c2:a1:90:c3:bb:ef:02:2f:d2:15:54:ee:44:15:d9:0a:ae:a7:
+ 8a:33:ed:b1:2d:76:36:26:dc:04:eb:9f:f7:61:1f:15:dc:87:
+ 6f:ee:46:96:28:ad:a1:26:7d:0a:09:a7:2e:04:a3:8d:bc:f8:
+ bc:04:30:01
+-----BEGIN CERTIFICATE-----
+MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3
+MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE
+CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD
+EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD
+BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv
+K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e
+cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY
+pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n
+eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB
+AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv
+9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
+b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n
+b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG
+CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
+MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz
+91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2
+RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi
+DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11
+GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x
+LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert31[] = {
+ 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72,
+ 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61,
+ 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64,
+ 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30,
+ 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37,
+ 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xb4, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30,
+ 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a,
+ 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07,
+ 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65,
+ 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47,
+ 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20,
+ 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x13, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65,
+ 0x72, 0x74, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f,
+ 0x72, 0x79, 0x2f, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x2a, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
+ 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+ 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xb9, 0xe0, 0xcb, 0x10, 0xd4, 0xaf, 0x76,
+ 0xbd, 0xd4, 0x93, 0x62, 0xeb, 0x30, 0x64, 0xb8, 0x81, 0x08, 0x6c, 0xc3,
+ 0x04, 0xd9, 0x62, 0x17, 0x8e, 0x2f, 0xff, 0x3e, 0x65, 0xcf, 0x8f, 0xce,
+ 0x62, 0xe6, 0x3c, 0x52, 0x1c, 0xda, 0x16, 0x45, 0x4b, 0x55, 0xab, 0x78,
+ 0x6b, 0x63, 0x83, 0x62, 0x90, 0xce, 0x0f, 0x69, 0x6c, 0x99, 0xc8, 0x1a,
+ 0x14, 0x8b, 0x4c, 0xcc, 0x45, 0x33, 0xea, 0x88, 0xdc, 0x9e, 0xa3, 0xaf,
+ 0x2b, 0xfe, 0x80, 0x61, 0x9d, 0x79, 0x57, 0xc4, 0xcf, 0x2e, 0xf4, 0x3f,
+ 0x30, 0x3c, 0x5d, 0x47, 0xfc, 0x9a, 0x16, 0xbc, 0xc3, 0x37, 0x96, 0x41,
+ 0x51, 0x8e, 0x11, 0x4b, 0x54, 0xf8, 0x28, 0xbe, 0xd0, 0x8c, 0xbe, 0xf0,
+ 0x30, 0x38, 0x1e, 0xf3, 0xb0, 0x26, 0xf8, 0x66, 0x47, 0x63, 0x6d, 0xde,
+ 0x71, 0x26, 0x47, 0x8f, 0x38, 0x47, 0x53, 0xd1, 0x46, 0x1d, 0xb4, 0xe3,
+ 0xdc, 0x00, 0xea, 0x45, 0xac, 0xbd, 0xbc, 0x71, 0xd9, 0xaa, 0x6f, 0x00,
+ 0xdb, 0xdb, 0xcd, 0x30, 0x3a, 0x79, 0x4f, 0x5f, 0x4c, 0x47, 0xf8, 0x1d,
+ 0xef, 0x5b, 0xc2, 0xc4, 0x9d, 0x60, 0x3b, 0xb1, 0xb2, 0x43, 0x91, 0xd8,
+ 0xa4, 0x33, 0x4e, 0xea, 0xb3, 0xd6, 0x27, 0x4f, 0xad, 0x25, 0x8a, 0xa5,
+ 0xc6, 0xf4, 0xd5, 0xd0, 0xa6, 0xae, 0x74, 0x05, 0x64, 0x57, 0x88, 0xb5,
+ 0x44, 0x55, 0xd4, 0x2d, 0x2a, 0x3a, 0x3e, 0xf8, 0xb8, 0xbd, 0xe9, 0x32,
+ 0x0a, 0x02, 0x94, 0x64, 0xc4, 0x16, 0x3a, 0x50, 0xf1, 0x4a, 0xae, 0xe7,
+ 0x79, 0x33, 0xaf, 0x0c, 0x20, 0x07, 0x7f, 0xe8, 0xdf, 0x04, 0x39, 0xc2,
+ 0x69, 0x02, 0x6c, 0x63, 0x52, 0xfa, 0x77, 0xc1, 0x1b, 0xc8, 0x74, 0x87,
+ 0xc8, 0xb9, 0x93, 0x18, 0x50, 0x54, 0x35, 0x4b, 0x69, 0x4e, 0xbc, 0x3b,
+ 0xd3, 0x49, 0x2e, 0x1f, 0xdc, 0xc1, 0xd2, 0x52, 0xfb, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1a, 0x30, 0x82, 0x01, 0x16, 0x30, 0x0f,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
+ 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x40, 0xc2, 0xbd, 0x27, 0x8e, 0xcc,
+ 0x34, 0x83, 0x30, 0xa2, 0x33, 0xd7, 0xfb, 0x6c, 0xb3, 0xf0, 0xb4, 0x2c,
+ 0x80, 0xce, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+ 0x16, 0x80, 0x14, 0x3a, 0x9a, 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef,
+ 0xf6, 0xbd, 0x05, 0x41, 0x6e, 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30,
+ 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67,
+ 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67,
+ 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c,
+ 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30,
+ 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68,
+ 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73,
+ 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0x7e, 0x6c, 0x93,
+ 0x10, 0xc8, 0x38, 0xb8, 0x96, 0xa9, 0x90, 0x4b, 0xff, 0xa1, 0x5f, 0x4f,
+ 0x04, 0xef, 0x6c, 0x3e, 0x9c, 0x88, 0x06, 0xc9, 0x50, 0x8f, 0xa6, 0x73,
+ 0xf7, 0x57, 0x31, 0x1b, 0xbe, 0xbc, 0xe4, 0x2f, 0xdb, 0xf8, 0xba, 0xd3,
+ 0x5b, 0xe0, 0xb4, 0xe7, 0xe6, 0x79, 0x62, 0x0e, 0x0c, 0xa2, 0xd7, 0x6a,
+ 0x63, 0x73, 0x31, 0xb5, 0xf5, 0xa8, 0x48, 0xa4, 0x3b, 0x08, 0x2d, 0xa2,
+ 0x5d, 0x90, 0xd7, 0xb4, 0x7c, 0x25, 0x4f, 0x11, 0x56, 0x30, 0xc4, 0xb6,
+ 0x44, 0x9d, 0x7b, 0x2c, 0x9d, 0xe5, 0x5e, 0xe6, 0xef, 0x0c, 0x61, 0xaa,
+ 0xbf, 0xe4, 0x2a, 0x1b, 0xee, 0x84, 0x9e, 0xb8, 0x83, 0x7d, 0xc1, 0x43,
+ 0xce, 0x44, 0xa7, 0x13, 0x70, 0x0d, 0x91, 0x1f, 0xf4, 0xc8, 0x13, 0xad,
+ 0x83, 0x60, 0xd9, 0xd8, 0x72, 0xa8, 0x73, 0x24, 0x1e, 0xb5, 0xac, 0x22,
+ 0x0e, 0xca, 0x17, 0x89, 0x62, 0x58, 0x44, 0x1b, 0xab, 0x89, 0x25, 0x01,
+ 0x00, 0x0f, 0xcd, 0xc4, 0x1b, 0x62, 0xdb, 0x51, 0xb4, 0xd3, 0x0f, 0x51,
+ 0x2a, 0x9b, 0xf4, 0xbc, 0x73, 0xfc, 0x76, 0xce, 0x36, 0xa4, 0xcd, 0xd9,
+ 0xd8, 0x2c, 0xea, 0xae, 0x9b, 0xf5, 0x2a, 0xb2, 0x90, 0xd1, 0x4d, 0x75,
+ 0x18, 0x8a, 0x3f, 0x8a, 0x41, 0x90, 0x23, 0x7d, 0x5b, 0x4b, 0xfe, 0xa4,
+ 0x03, 0x58, 0x9b, 0x46, 0xb2, 0xc3, 0x60, 0x60, 0x83, 0xf8, 0x7d, 0x50,
+ 0x41, 0xce, 0xc2, 0xa1, 0x90, 0xc3, 0xbb, 0xef, 0x02, 0x2f, 0xd2, 0x15,
+ 0x54, 0xee, 0x44, 0x15, 0xd9, 0x0a, 0xae, 0xa7, 0x8a, 0x33, 0xed, 0xb1,
+ 0x2d, 0x76, 0x36, 0x26, 0xdc, 0x04, 0xeb, 0x9f, 0xf7, 0x61, 0x1f, 0x15,
+ 0xdc, 0x87, 0x6f, 0xee, 0x46, 0x96, 0x28, 0xad, 0xa1, 0x26, 0x7d, 0x0a,
+ 0x09, 0xa7, 0x2e, 0x04, 0xa3, 0x8d, 0xbc, 0xf8, 0xbc, 0x04, 0x30, 0x01,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0a:48:9e:88:53:7e:8a:a6:45:4d:6e:2c:4b:2a:eb:20
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
+ Validity
+ Not Before: Apr 9 00:00:00 2013 GMT
+ Not After : Apr 8 23:59:59 2023 GMT
+ Subject: C=US, O=thawte, Inc., CN=thawte Extended Validation SHA256 SSL CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:f2:c4:bc:74:e8:25:f6:00:62:28:e3:4c:e8:b8:
+ df:13:9f:8b:07:37:ef:62:4a:f1:57:09:f6:82:e8:
+ 75:f0:0a:a9:27:cf:93:3b:ec:36:89:a5:6e:1d:d6:
+ 54:f3:b8:04:97:72:b4:69:25:cc:d1:42:0e:5b:d5:
+ 1c:7f:a2:60:6e:b1:52:1a:db:93:2f:bb:0b:0d:64:
+ 53:16:cb:1c:09:24:95:29:22:b4:8a:18:00:89:fe:
+ f7:1f:72:c8:e8:5c:2f:1a:1b:a2:18:b8:ef:18:5c:
+ cb:b5:db:3a:4e:db:0f:ae:df:c4:79:e3:1e:aa:5c:
+ a3:a4:e5:ac:61:9b:37:85:8f:48:75:1b:b9:d5:68:
+ 96:e9:27:79:70:57:23:1a:bb:6c:93:90:c7:45:d7:
+ 17:d2:37:2a:76:b3:cd:82:a9:4f:c0:03:7b:e1:3d:
+ 7a:7e:5b:b8:85:f2:f5:15:fb:70:a9:bd:f5:50:65:
+ 16:9d:e3:b6:6b:61:6e:a1:7a:9e:e8:0d:1c:f7:2a:
+ 8e:69:7e:43:30:8e:78:ce:ee:65:1e:3b:9b:87:1e:
+ 49:1c:f8:32:46:5d:28:46:79:2a:4e:27:5d:17:58:
+ a8:37:fe:a8:13:a9:69:15:df:36:22:89:75:ba:ca:
+ 01:40:2e:ed:9d:d7:0c:aa:31:ce:27:ae:57:d5:d2:
+ 51:fb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://ocsp.thawte.com
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.thawte.com/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.thawte.com/ThawtePCA-G3.crl
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=VeriSignMPKI-2-374
+ X509v3 Subject Key Identifier:
+ 3B:24:C8:31:A0:B7:5A:D0:6A:B8:D2:CA:07:74:CC:1E:24:D4:C4:DC
+ X509v3 Authority Key Identifier:
+ keyid:AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 68:98:26:aa:d4:33:c9:ba:75:70:d4:9f:49:ad:d6:c1:54:dc:
+ ee:aa:56:1f:78:a7:f0:a1:a4:ee:0b:f9:12:af:df:a6:b8:ee:
+ c3:cb:35:13:6a:59:2a:f8:c9:e9:4c:2f:bc:b1:bc:2b:c2:02:
+ 30:e1:c3:be:c2:f0:81:8c:99:77:89:58:00:a3:cc:7f:a3:02:
+ 4c:53:b2:6e:36:4f:fe:df:87:76:b3:3f:ec:5a:62:50:b6:00:
+ 45:58:f2:87:ac:77:e6:d0:20:50:63:c5:e4:b2:70:15:18:90:
+ 05:7b:7b:af:2b:46:be:6b:4e:1f:53:fc:84:27:ae:83:d2:8d:
+ 47:53:a7:0e:1f:63:b5:ba:db:16:d8:6a:09:25:55:7d:8f:3d:
+ 4a:c1:83:f9:b3:b9:a7:04:5a:c8:f3:11:04:91:53:30:d9:52:
+ 87:cb:39:00:9c:ec:53:c3:02:09:7e:a7:36:8e:72:21:2f:23:
+ bb:4c:c6:47:a5:a1:ee:67:c4:2f:5c:3a:47:38:61:e2:c3:1e:
+ 37:92:9e:c8:2f:6b:fa:ef:d2:c3:cd:29:8d:98:f8:52:17:ed:
+ b5:53:3c:df:af:c9:1b:62:ad:df:02:ee:5d:34:f6:41:4b:cb:
+ c3:55:af:b1:cb:da:9c:73:d5:02:a8:2d:a7:ac:fc:e1:e5:07:
+ d0:51:e8:35
+-----BEGIN CERTIFICATE-----
+MIIE0DCCA7igAwIBAgIQCkieiFN+iqZFTW4sSyrrIDANBgkqhkiG9w0BAQsFADCB
+rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
+BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0xMzA0MDkwMDAwMDBa
+Fw0yMzA0MDgyMzU5NTlaMFcxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUs
+IEluYy4xMTAvBgNVBAMTKHRoYXd0ZSBFeHRlbmRlZCBWYWxpZGF0aW9uIFNIQTI1
+NiBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyxLx06CX2
+AGIo40zouN8Tn4sHN+9iSvFXCfaC6HXwCqknz5M77DaJpW4d1lTzuASXcrRpJczR
+Qg5b1Rx/omBusVIa25MvuwsNZFMWyxwJJJUpIrSKGACJ/vcfcsjoXC8aG6IYuO8Y
+XMu12zpO2w+u38R54x6qXKOk5axhmzeFj0h1G7nVaJbpJ3lwVyMau2yTkMdF1xfS
+Nyp2s82CqU/AA3vhPXp+W7iF8vUV+3CpvfVQZRad47ZrYW6hep7oDRz3Ko5pfkMw
+jnjO7mUeO5uHHkkc+DJGXShGeSpOJ10XWKg3/qgTqWkV3zYiiXW6ygFALu2d1wyq
+Mc4nrlfV0lH7AgMBAAGjggE+MIIBOjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1Ud
+DwEB/wQEAwIBBjAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9v
+Y3NwLnRoYXd0ZS5jb20wOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEW
+Gmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3BzMDcGA1UdHwQwMC4wLKAqoCiGJmh0
+dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQQ0EtRzMuY3JsMCoGA1UdEQQjMCGk
+HzAdMRswGQYDVQQDExJWZXJpU2lnbk1QS0ktMi0zNzQwHQYDVR0OBBYEFDskyDGg
+t1rQarjSygd0zB4k1MTcMB8GA1UdIwQYMBaAFK1sqpRgnO3k//o+CnQrYwP3tlm/
+MA0GCSqGSIb3DQEBCwUAA4IBAQBomCaq1DPJunVw1J9JrdbBVNzuqlYfeKfwoaTu
+C/kSr9+muO7DyzUTalkq+MnpTC+8sbwrwgIw4cO+wvCBjJl3iVgAo8x/owJMU7Ju
+Nk/+34d2sz/sWmJQtgBFWPKHrHfm0CBQY8XksnAVGJAFe3uvK0a+a04fU/yEJ66D
+0o1HU6cOH2O1utsW2GoJJVV9jz1KwYP5s7mnBFrI8xEEkVMw2VKHyzkAnOxTwwIJ
+fqc2jnIhLyO7TMZHpaHuZ8QvXDpHOGHiwx43kp7IL2v679LDzSmNmPhSF+21Uzzf
+r8kbYq3fAu5dNPZBS8vDVa+xy9qcc9UCqC2nrPzh5QfQUeg1
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert32[] = {
+ 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x0a, 0x48, 0x9e, 0x88, 0x53, 0x7e, 0x8a, 0xa6, 0x45,
+ 0x4d, 0x6e, 0x2c, 0x4b, 0x2a, 0xeb, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+ 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+ 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+ 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x1b, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+ 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+ 0x33, 0x30, 0x34, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+ 0x17, 0x0d, 0x32, 0x33, 0x30, 0x34, 0x30, 0x38, 0x32, 0x33, 0x35, 0x39,
+ 0x35, 0x39, 0x5a, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
+ 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x28, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45,
+ 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69,
+ 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35,
+ 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xf2, 0xc4, 0xbc, 0x74, 0xe8, 0x25, 0xf6,
+ 0x00, 0x62, 0x28, 0xe3, 0x4c, 0xe8, 0xb8, 0xdf, 0x13, 0x9f, 0x8b, 0x07,
+ 0x37, 0xef, 0x62, 0x4a, 0xf1, 0x57, 0x09, 0xf6, 0x82, 0xe8, 0x75, 0xf0,
+ 0x0a, 0xa9, 0x27, 0xcf, 0x93, 0x3b, 0xec, 0x36, 0x89, 0xa5, 0x6e, 0x1d,
+ 0xd6, 0x54, 0xf3, 0xb8, 0x04, 0x97, 0x72, 0xb4, 0x69, 0x25, 0xcc, 0xd1,
+ 0x42, 0x0e, 0x5b, 0xd5, 0x1c, 0x7f, 0xa2, 0x60, 0x6e, 0xb1, 0x52, 0x1a,
+ 0xdb, 0x93, 0x2f, 0xbb, 0x0b, 0x0d, 0x64, 0x53, 0x16, 0xcb, 0x1c, 0x09,
+ 0x24, 0x95, 0x29, 0x22, 0xb4, 0x8a, 0x18, 0x00, 0x89, 0xfe, 0xf7, 0x1f,
+ 0x72, 0xc8, 0xe8, 0x5c, 0x2f, 0x1a, 0x1b, 0xa2, 0x18, 0xb8, 0xef, 0x18,
+ 0x5c, 0xcb, 0xb5, 0xdb, 0x3a, 0x4e, 0xdb, 0x0f, 0xae, 0xdf, 0xc4, 0x79,
+ 0xe3, 0x1e, 0xaa, 0x5c, 0xa3, 0xa4, 0xe5, 0xac, 0x61, 0x9b, 0x37, 0x85,
+ 0x8f, 0x48, 0x75, 0x1b, 0xb9, 0xd5, 0x68, 0x96, 0xe9, 0x27, 0x79, 0x70,
+ 0x57, 0x23, 0x1a, 0xbb, 0x6c, 0x93, 0x90, 0xc7, 0x45, 0xd7, 0x17, 0xd2,
+ 0x37, 0x2a, 0x76, 0xb3, 0xcd, 0x82, 0xa9, 0x4f, 0xc0, 0x03, 0x7b, 0xe1,
+ 0x3d, 0x7a, 0x7e, 0x5b, 0xb8, 0x85, 0xf2, 0xf5, 0x15, 0xfb, 0x70, 0xa9,
+ 0xbd, 0xf5, 0x50, 0x65, 0x16, 0x9d, 0xe3, 0xb6, 0x6b, 0x61, 0x6e, 0xa1,
+ 0x7a, 0x9e, 0xe8, 0x0d, 0x1c, 0xf7, 0x2a, 0x8e, 0x69, 0x7e, 0x43, 0x30,
+ 0x8e, 0x78, 0xce, 0xee, 0x65, 0x1e, 0x3b, 0x9b, 0x87, 0x1e, 0x49, 0x1c,
+ 0xf8, 0x32, 0x46, 0x5d, 0x28, 0x46, 0x79, 0x2a, 0x4e, 0x27, 0x5d, 0x17,
+ 0x58, 0xa8, 0x37, 0xfe, 0xa8, 0x13, 0xa9, 0x69, 0x15, 0xdf, 0x36, 0x22,
+ 0x89, 0x75, 0xba, 0xca, 0x01, 0x40, 0x2e, 0xed, 0x9d, 0xd7, 0x0c, 0xaa,
+ 0x31, 0xce, 0x27, 0xae, 0x57, 0xd5, 0xd2, 0x51, 0xfb, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x30, 0x12,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
+ 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x32,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x26,
+ 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f,
+ 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30,
+ 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30,
+ 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
+ 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+ 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x63, 0x70, 0x73, 0x30, 0x37, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30,
+ 0x30, 0x2e, 0x30, 0x2c, 0xa0, 0x2a, 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61,
+ 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77,
+ 0x74, 0x65, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c,
+ 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4,
+ 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50,
+ 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x33, 0x37, 0x34, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3b, 0x24, 0xc8, 0x31, 0xa0,
+ 0xb7, 0x5a, 0xd0, 0x6a, 0xb8, 0xd2, 0xca, 0x07, 0x74, 0xcc, 0x1e, 0x24,
+ 0xd4, 0xc4, 0xdc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0xad, 0x6c, 0xaa, 0x94, 0x60, 0x9c, 0xed, 0xe4,
+ 0xff, 0xfa, 0x3e, 0x0a, 0x74, 0x2b, 0x63, 0x03, 0xf7, 0xb6, 0x59, 0xbf,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x68, 0x98, 0x26, 0xaa,
+ 0xd4, 0x33, 0xc9, 0xba, 0x75, 0x70, 0xd4, 0x9f, 0x49, 0xad, 0xd6, 0xc1,
+ 0x54, 0xdc, 0xee, 0xaa, 0x56, 0x1f, 0x78, 0xa7, 0xf0, 0xa1, 0xa4, 0xee,
+ 0x0b, 0xf9, 0x12, 0xaf, 0xdf, 0xa6, 0xb8, 0xee, 0xc3, 0xcb, 0x35, 0x13,
+ 0x6a, 0x59, 0x2a, 0xf8, 0xc9, 0xe9, 0x4c, 0x2f, 0xbc, 0xb1, 0xbc, 0x2b,
+ 0xc2, 0x02, 0x30, 0xe1, 0xc3, 0xbe, 0xc2, 0xf0, 0x81, 0x8c, 0x99, 0x77,
+ 0x89, 0x58, 0x00, 0xa3, 0xcc, 0x7f, 0xa3, 0x02, 0x4c, 0x53, 0xb2, 0x6e,
+ 0x36, 0x4f, 0xfe, 0xdf, 0x87, 0x76, 0xb3, 0x3f, 0xec, 0x5a, 0x62, 0x50,
+ 0xb6, 0x00, 0x45, 0x58, 0xf2, 0x87, 0xac, 0x77, 0xe6, 0xd0, 0x20, 0x50,
+ 0x63, 0xc5, 0xe4, 0xb2, 0x70, 0x15, 0x18, 0x90, 0x05, 0x7b, 0x7b, 0xaf,
+ 0x2b, 0x46, 0xbe, 0x6b, 0x4e, 0x1f, 0x53, 0xfc, 0x84, 0x27, 0xae, 0x83,
+ 0xd2, 0x8d, 0x47, 0x53, 0xa7, 0x0e, 0x1f, 0x63, 0xb5, 0xba, 0xdb, 0x16,
+ 0xd8, 0x6a, 0x09, 0x25, 0x55, 0x7d, 0x8f, 0x3d, 0x4a, 0xc1, 0x83, 0xf9,
+ 0xb3, 0xb9, 0xa7, 0x04, 0x5a, 0xc8, 0xf3, 0x11, 0x04, 0x91, 0x53, 0x30,
+ 0xd9, 0x52, 0x87, 0xcb, 0x39, 0x00, 0x9c, 0xec, 0x53, 0xc3, 0x02, 0x09,
+ 0x7e, 0xa7, 0x36, 0x8e, 0x72, 0x21, 0x2f, 0x23, 0xbb, 0x4c, 0xc6, 0x47,
+ 0xa5, 0xa1, 0xee, 0x67, 0xc4, 0x2f, 0x5c, 0x3a, 0x47, 0x38, 0x61, 0xe2,
+ 0xc3, 0x1e, 0x37, 0x92, 0x9e, 0xc8, 0x2f, 0x6b, 0xfa, 0xef, 0xd2, 0xc3,
+ 0xcd, 0x29, 0x8d, 0x98, 0xf8, 0x52, 0x17, 0xed, 0xb5, 0x53, 0x3c, 0xdf,
+ 0xaf, 0xc9, 0x1b, 0x62, 0xad, 0xdf, 0x02, 0xee, 0x5d, 0x34, 0xf6, 0x41,
+ 0x4b, 0xcb, 0xc3, 0x55, 0xaf, 0xb1, 0xcb, 0xda, 0x9c, 0x73, 0xd5, 0x02,
+ 0xa8, 0x2d, 0xa7, 0xac, 0xfc, 0xe1, 0xe5, 0x07, 0xd0, 0x51, 0xe8, 0x35,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 25:0c:e8:e0:30:61:2e:9f:2b:89:f7:05:4d:7c:f8:fd
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
+ Validity
+ Not Before: Nov 8 00:00:00 2006 GMT
+ Not After : Nov 7 23:59:59 2021 GMT
+ Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
+ 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
+ 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
+ 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
+ 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
+ a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
+ 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
+ d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
+ 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
+ bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
+ f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
+ ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
+ f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
+ 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
+ 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
+ ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
+ 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
+ 25:15
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.verisign.com/pca3.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.verisign.com/cps
+
+ X509v3 Subject Key Identifier:
+ 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+ 1.3.6.1.5.5.7.1.12:
+ 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
+ Authority Information Access:
+ OCSP - URI:http://ocsp.verisign.com
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1
+ Signature Algorithm: sha1WithRSAEncryption
+ 13:02:dd:f8:e8:86:00:f2:5a:f8:f8:20:0c:59:88:62:07:ce:
+ ce:f7:4e:f9:bb:59:a1:98:e5:e1:38:dd:4e:bc:66:18:d3:ad:
+ eb:18:f2:0d:c9:6d:3e:4a:94:20:c3:3c:ba:bd:65:54:c6:af:
+ 44:b3:10:ad:2c:6b:3e:ab:d7:07:b6:b8:81:63:c5:f9:5e:2e:
+ e5:2a:67:ce:cd:33:0c:2a:d7:89:56:03:23:1f:b3:be:e8:3a:
+ 08:59:b4:ec:45:35:f7:8a:5b:ff:66:cf:50:af:c6:6d:57:8d:
+ 19:78:b7:b9:a2:d1:57:ea:1f:9a:4b:af:ba:c9:8e:12:7e:c6:
+ bd:ff
+-----BEGIN CERTIFICATE-----
+MIIE0DCCBDmgAwIBAgIQJQzo4DBhLp8rifcFTXz4/TANBgkqhkiG9w0BAQUFADBf
+MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
+LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx
+FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
+dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv
+ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz
+IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8
+RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb
+ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR
+TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
+Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH
+iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB
+AAGjggGbMIIBlzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0
+dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9
+BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy
+aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI
+KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU
+j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t
+L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
+b2NzcC52ZXJpc2lnbi5jb20wPgYDVR0lBDcwNQYIKwYBBQUHAwEGCCsGAQUFBwMC
+BggrBgEFBQcDAwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUA
+A4GBABMC3fjohgDyWvj4IAxZiGIHzs73Tvm7WaGY5eE43U68ZhjTresY8g3JbT5K
+lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ
+tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert33[] = {
+ 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x04, 0x39, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x25, 0x0c, 0xe8, 0xe0, 0x30, 0x61, 0x2e, 0x9f, 0x2b,
+ 0x89, 0xf7, 0x05, 0x4d, 0x7c, 0xf8, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
+ 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
+ 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
+ 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
+ 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30,
+ 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20,
+ 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+ 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
+ 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
+ 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30,
+ 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+ 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+ 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35,
+ 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c,
+ 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3,
+ 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22,
+ 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1,
+ 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb,
+ 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0,
+ 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85,
+ 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33,
+ 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51,
+ 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74,
+ 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0,
+ 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06,
+ 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff,
+ 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4,
+ 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19,
+ 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe,
+ 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47,
+ 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5,
+ 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14,
+ 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f,
+ 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x9b, 0x30, 0x82, 0x01, 0x97, 0x30, 0x0f,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
+ 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a,
+ 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72,
+ 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
+ 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06,
+ 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
+ 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
+ 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
+ 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f,
+ 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09,
+ 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30,
+ 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14,
+ 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80,
+ 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30,
+ 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
+ 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x1d, 0x25,
+ 0x04, 0x37, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
+ 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+ 0x03, 0x81, 0x81, 0x00, 0x13, 0x02, 0xdd, 0xf8, 0xe8, 0x86, 0x00, 0xf2,
+ 0x5a, 0xf8, 0xf8, 0x20, 0x0c, 0x59, 0x88, 0x62, 0x07, 0xce, 0xce, 0xf7,
+ 0x4e, 0xf9, 0xbb, 0x59, 0xa1, 0x98, 0xe5, 0xe1, 0x38, 0xdd, 0x4e, 0xbc,
+ 0x66, 0x18, 0xd3, 0xad, 0xeb, 0x18, 0xf2, 0x0d, 0xc9, 0x6d, 0x3e, 0x4a,
+ 0x94, 0x20, 0xc3, 0x3c, 0xba, 0xbd, 0x65, 0x54, 0xc6, 0xaf, 0x44, 0xb3,
+ 0x10, 0xad, 0x2c, 0x6b, 0x3e, 0xab, 0xd7, 0x07, 0xb6, 0xb8, 0x81, 0x63,
+ 0xc5, 0xf9, 0x5e, 0x2e, 0xe5, 0x2a, 0x67, 0xce, 0xcd, 0x33, 0x0c, 0x2a,
+ 0xd7, 0x89, 0x56, 0x03, 0x23, 0x1f, 0xb3, 0xbe, 0xe8, 0x3a, 0x08, 0x59,
+ 0xb4, 0xec, 0x45, 0x35, 0xf7, 0x8a, 0x5b, 0xff, 0x66, 0xcf, 0x50, 0xaf,
+ 0xc6, 0x6d, 0x57, 0x8d, 0x19, 0x78, 0xb7, 0xb9, 0xa2, 0xd1, 0x57, 0xea,
+ 0x1f, 0x9a, 0x4b, 0xaf, 0xba, 0xc9, 0x8e, 0x12, 0x7e, 0xc6, 0xbd, 0xff,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 2c:69:e1:2f:6a:67:0b:d9:9d:d2:0f:91:9e:f0:9e:51
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
+ Validity
+ Not Before: Jun 10 00:00:00 2014 GMT
+ Not After : Jun 9 23:59:59 2024 GMT
+ Subject: C=US, O=thawte, Inc., OU=Domain Validated SSL, CN=thawte DV SSL CA - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ea:94:07:85:c8:41:2c:f6:83:12:6c:92:5f:ab:
+ 1f:00:d4:96:6f:74:cd:2e:11:e9:6c:0f:39:01:b9:
+ 48:90:40:39:4d:c4:a2:c8:79:6a:a5:9a:bd:91:44:
+ 65:77:54:ad:ff:25:5f:ee:42:fb:b3:02:0f:ea:5d:
+ 7a:dd:1a:54:9e:d7:73:42:9b:cc:79:5f:c5:4d:f4:
+ b7:0b:18:39:20:7a:dd:50:01:5d:34:45:5f:4c:11:
+ 0e:f5:87:26:26:b4:b0:f3:7e:71:a0:31:71:50:89:
+ 68:5a:63:8a:14:62:e5:8c:3a:16:55:0d:3e:eb:aa:
+ 80:1d:71:7a:e3:87:07:ab:bd:a2:74:cd:da:08:01:
+ 9d:1b:cc:27:88:8c:47:d4:69:25:42:d6:bb:50:6d:
+ 85:50:d0:48:82:0d:08:9f:e9:23:e3:42:c6:3c:98:
+ b8:bb:6e:c5:70:13:df:19:1d:01:fd:d2:b5:4e:e6:
+ 62:f4:07:fa:6b:7d:11:77:c4:62:4f:40:4e:a5:78:
+ 97:ab:2c:4d:0c:a7:7c:c3:c4:50:32:9f:d0:70:9b:
+ 0f:ff:ff:75:59:34:85:ad:49:d5:35:ee:4f:5b:d4:
+ d4:36:95:a0:7e:e8:c5:a1:1c:bd:13:4e:7d:ee:63:
+ 6a:96:19:99:c8:a7:2a:00:e6:51:8d:46:eb:30:58:
+ e8:2d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: https://www.thawte.com/cps
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://t.symcd.com
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://t.symcb.com/ThawtePCA.crl
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=SymantecPKI-1-698
+ X509v3 Subject Key Identifier:
+ 9F:B8:C1:A9:6C:F2:F5:C0:22:2A:94:ED:5C:99:AC:D4:EC:D7:C6:07
+ X509v3 Authority Key Identifier:
+ keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 53:54:f2:47:a8:02:d7:ef:aa:35:78:be:4a:08:0d:90:18:4b:
+ 6d:9e:2a:53:2b:e9:54:17:77:74:29:7e:d0:37:07:05:b8:e4:
+ fa:b8:b4:63:98:44:dc:c6:4f:81:06:8c:3a:be:c7:30:57:c6:
+ 70:fc:d6:93:19:9f:c3:55:d7:3e:1f:72:8a:9d:30:5a:35:97:
+ 32:cb:63:e4:c6:72:df:fb:68:ca:69:2f:db:cd:50:38:3e:2b:
+ bb:ab:3b:82:c7:fd:4b:9b:bd:7c:41:98:ef:01:53:d8:35:8f:
+ 25:c9:03:06:e6:9c:57:c1:51:0f:9e:f6:7d:93:4d:f8:76:c8:
+ 3a:6b:f4:c4:8f:33:32:7f:9d:21:84:34:d9:a7:f9:92:fa:41:
+ 91:61:84:05:9d:a3:79:46:ce:67:e7:81:f2:5e:ac:4c:bc:a8:
+ ab:6a:6d:15:e2:9c:4e:5a:d9:63:80:bc:f7:42:eb:9a:44:c6:
+ 8c:6b:06:36:b4:8b:32:89:de:c2:f1:a8:26:aa:a9:ac:ff:ea:
+ 71:a6:e7:8c:41:fa:17:35:bb:b3:87:31:a9:93:c2:c8:58:e1:
+ 0a:4e:95:83:9c:b9:ed:3b:a5:ef:08:e0:74:f9:c3:1b:e6:07:
+ a3:ee:07:d7:42:22:79:21:a0:a1:d4:1d:26:d3:d0:d6:a6:5d:
+ 2b:41:c0:79
+-----BEGIN CERTIFICATE-----
+MIIE0jCCA7qgAwIBAgIQLGnhL2pnC9md0g+RnvCeUTANBgkqhkiG9w0BAQsFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTQwNjEwMDAwMDAwWhcNMjQw
+NjA5MjM1OTU5WjBjMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu
+MR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEeMBwGA1UEAxMVdGhhd3Rl
+IERWIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+6pQHhchBLPaDEmySX6sfANSWb3TNLhHpbA85AblIkEA5TcSiyHlqpZq9kURld1St
+/yVf7kL7swIP6l163RpUntdzQpvMeV/FTfS3Cxg5IHrdUAFdNEVfTBEO9YcmJrSw
+835xoDFxUIloWmOKFGLljDoWVQ0+66qAHXF644cHq72idM3aCAGdG8wniIxH1Gkl
+Qta7UG2FUNBIgg0In+kj40LGPJi4u27FcBPfGR0B/dK1TuZi9Af6a30Rd8RiT0BO
+pXiXqyxNDKd8w8RQMp/QcJsP//91WTSFrUnVNe5PW9TUNpWgfujFoRy9E0597mNq
+lhmZyKcqAOZRjUbrMFjoLQIDAQABo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIB
+ADBBBgNVHSAEOjA4MDYGCmCGSAGG+EUBBzYwKDAmBggrBgEFBQcCARYaaHR0cHM6
+Ly93d3cudGhhd3RlLmNvbS9jcHMwDgYDVR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEB
+BCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL3Quc3ltY2QuY29tMDEGA1UdHwQqMCgw
+JqAkoCKGIGh0dHA6Ly90LnN5bWNiLmNvbS9UaGF3dGVQQ0EuY3JsMCkGA1UdEQQi
+MCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTY5ODAdBgNVHQ4EFgQUn7jB
+qWzy9cAiKpTtXJms1OzXxgcwHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutX
+SFAwDQYJKoZIhvcNAQELBQADggEBAFNU8keoAtfvqjV4vkoIDZAYS22eKlMr6VQX
+d3QpftA3BwW45Pq4tGOYRNzGT4EGjDq+xzBXxnD81pMZn8NV1z4fcoqdMFo1lzLL
+Y+TGct/7aMppL9vNUDg+K7urO4LH/UubvXxBmO8BU9g1jyXJAwbmnFfBUQ+e9n2T
+Tfh2yDpr9MSPMzJ/nSGENNmn+ZL6QZFhhAWdo3lGzmfngfJerEy8qKtqbRXinE5a
+2WOAvPdC65pExoxrBja0izKJ3sLxqCaqqaz/6nGm54xB+hc1u7OHMamTwshY4QpO
+lYOcue07pe8I4HT5wxvmB6PuB9dCInkhoKHUHSbT0NamXStBwHk=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert34[] = {
+ 0x30, 0x82, 0x04, 0xd2, 0x30, 0x82, 0x03, 0xba, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x2c, 0x69, 0xe1, 0x2f, 0x6a, 0x67, 0x0b, 0xd9, 0x9d,
+ 0xd2, 0x0f, 0x91, 0x9e, 0xf0, 0x9e, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+ 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+ 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+ 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+ 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30,
+ 0x36, 0x30, 0x39, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x63,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x14, 0x44,
+ 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
+ 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
+ 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d,
+ 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xea, 0x94, 0x07, 0x85, 0xc8, 0x41, 0x2c, 0xf6, 0x83, 0x12, 0x6c, 0x92,
+ 0x5f, 0xab, 0x1f, 0x00, 0xd4, 0x96, 0x6f, 0x74, 0xcd, 0x2e, 0x11, 0xe9,
+ 0x6c, 0x0f, 0x39, 0x01, 0xb9, 0x48, 0x90, 0x40, 0x39, 0x4d, 0xc4, 0xa2,
+ 0xc8, 0x79, 0x6a, 0xa5, 0x9a, 0xbd, 0x91, 0x44, 0x65, 0x77, 0x54, 0xad,
+ 0xff, 0x25, 0x5f, 0xee, 0x42, 0xfb, 0xb3, 0x02, 0x0f, 0xea, 0x5d, 0x7a,
+ 0xdd, 0x1a, 0x54, 0x9e, 0xd7, 0x73, 0x42, 0x9b, 0xcc, 0x79, 0x5f, 0xc5,
+ 0x4d, 0xf4, 0xb7, 0x0b, 0x18, 0x39, 0x20, 0x7a, 0xdd, 0x50, 0x01, 0x5d,
+ 0x34, 0x45, 0x5f, 0x4c, 0x11, 0x0e, 0xf5, 0x87, 0x26, 0x26, 0xb4, 0xb0,
+ 0xf3, 0x7e, 0x71, 0xa0, 0x31, 0x71, 0x50, 0x89, 0x68, 0x5a, 0x63, 0x8a,
+ 0x14, 0x62, 0xe5, 0x8c, 0x3a, 0x16, 0x55, 0x0d, 0x3e, 0xeb, 0xaa, 0x80,
+ 0x1d, 0x71, 0x7a, 0xe3, 0x87, 0x07, 0xab, 0xbd, 0xa2, 0x74, 0xcd, 0xda,
+ 0x08, 0x01, 0x9d, 0x1b, 0xcc, 0x27, 0x88, 0x8c, 0x47, 0xd4, 0x69, 0x25,
+ 0x42, 0xd6, 0xbb, 0x50, 0x6d, 0x85, 0x50, 0xd0, 0x48, 0x82, 0x0d, 0x08,
+ 0x9f, 0xe9, 0x23, 0xe3, 0x42, 0xc6, 0x3c, 0x98, 0xb8, 0xbb, 0x6e, 0xc5,
+ 0x70, 0x13, 0xdf, 0x19, 0x1d, 0x01, 0xfd, 0xd2, 0xb5, 0x4e, 0xe6, 0x62,
+ 0xf4, 0x07, 0xfa, 0x6b, 0x7d, 0x11, 0x77, 0xc4, 0x62, 0x4f, 0x40, 0x4e,
+ 0xa5, 0x78, 0x97, 0xab, 0x2c, 0x4d, 0x0c, 0xa7, 0x7c, 0xc3, 0xc4, 0x50,
+ 0x32, 0x9f, 0xd0, 0x70, 0x9b, 0x0f, 0xff, 0xff, 0x75, 0x59, 0x34, 0x85,
+ 0xad, 0x49, 0xd5, 0x35, 0xee, 0x4f, 0x5b, 0xd4, 0xd4, 0x36, 0x95, 0xa0,
+ 0x7e, 0xe8, 0xc5, 0xa1, 0x1c, 0xbd, 0x13, 0x4e, 0x7d, 0xee, 0x63, 0x6a,
+ 0x96, 0x19, 0x99, 0xc8, 0xa7, 0x2a, 0x00, 0xe6, 0x51, 0x8d, 0x46, 0xeb,
+ 0x30, 0x58, 0xe8, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+ 0x39, 0x30, 0x82, 0x01, 0x35, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38,
+ 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01,
+ 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
+ 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+ 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30,
+ 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22,
+ 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65,
+ 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x36, 0x39, 0x38, 0x30, 0x1d,
+ 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9f, 0xb8, 0xc1,
+ 0xa9, 0x6c, 0xf2, 0xf5, 0xc0, 0x22, 0x2a, 0x94, 0xed, 0x5c, 0x99, 0xac,
+ 0xd4, 0xec, 0xd7, 0xc6, 0x07, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
+ 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce,
+ 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57,
+ 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x53, 0x54,
+ 0xf2, 0x47, 0xa8, 0x02, 0xd7, 0xef, 0xaa, 0x35, 0x78, 0xbe, 0x4a, 0x08,
+ 0x0d, 0x90, 0x18, 0x4b, 0x6d, 0x9e, 0x2a, 0x53, 0x2b, 0xe9, 0x54, 0x17,
+ 0x77, 0x74, 0x29, 0x7e, 0xd0, 0x37, 0x07, 0x05, 0xb8, 0xe4, 0xfa, 0xb8,
+ 0xb4, 0x63, 0x98, 0x44, 0xdc, 0xc6, 0x4f, 0x81, 0x06, 0x8c, 0x3a, 0xbe,
+ 0xc7, 0x30, 0x57, 0xc6, 0x70, 0xfc, 0xd6, 0x93, 0x19, 0x9f, 0xc3, 0x55,
+ 0xd7, 0x3e, 0x1f, 0x72, 0x8a, 0x9d, 0x30, 0x5a, 0x35, 0x97, 0x32, 0xcb,
+ 0x63, 0xe4, 0xc6, 0x72, 0xdf, 0xfb, 0x68, 0xca, 0x69, 0x2f, 0xdb, 0xcd,
+ 0x50, 0x38, 0x3e, 0x2b, 0xbb, 0xab, 0x3b, 0x82, 0xc7, 0xfd, 0x4b, 0x9b,
+ 0xbd, 0x7c, 0x41, 0x98, 0xef, 0x01, 0x53, 0xd8, 0x35, 0x8f, 0x25, 0xc9,
+ 0x03, 0x06, 0xe6, 0x9c, 0x57, 0xc1, 0x51, 0x0f, 0x9e, 0xf6, 0x7d, 0x93,
+ 0x4d, 0xf8, 0x76, 0xc8, 0x3a, 0x6b, 0xf4, 0xc4, 0x8f, 0x33, 0x32, 0x7f,
+ 0x9d, 0x21, 0x84, 0x34, 0xd9, 0xa7, 0xf9, 0x92, 0xfa, 0x41, 0x91, 0x61,
+ 0x84, 0x05, 0x9d, 0xa3, 0x79, 0x46, 0xce, 0x67, 0xe7, 0x81, 0xf2, 0x5e,
+ 0xac, 0x4c, 0xbc, 0xa8, 0xab, 0x6a, 0x6d, 0x15, 0xe2, 0x9c, 0x4e, 0x5a,
+ 0xd9, 0x63, 0x80, 0xbc, 0xf7, 0x42, 0xeb, 0x9a, 0x44, 0xc6, 0x8c, 0x6b,
+ 0x06, 0x36, 0xb4, 0x8b, 0x32, 0x89, 0xde, 0xc2, 0xf1, 0xa8, 0x26, 0xaa,
+ 0xa9, 0xac, 0xff, 0xea, 0x71, 0xa6, 0xe7, 0x8c, 0x41, 0xfa, 0x17, 0x35,
+ 0xbb, 0xb3, 0x87, 0x31, 0xa9, 0x93, 0xc2, 0xc8, 0x58, 0xe1, 0x0a, 0x4e,
+ 0x95, 0x83, 0x9c, 0xb9, 0xed, 0x3b, 0xa5, 0xef, 0x08, 0xe0, 0x74, 0xf9,
+ 0xc3, 0x1b, 0xe6, 0x07, 0xa3, 0xee, 0x07, 0xd7, 0x42, 0x22, 0x79, 0x21,
+ 0xa0, 0xa1, 0xd4, 0x1d, 0x26, 0xd3, 0xd0, 0xd6, 0xa6, 0x5d, 0x2b, 0x41,
+ 0xc0, 0x79,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 4f:e3:e2:65:21:07:ab:20:37:41:6e:48:70:ce:d2:c2
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
+ Validity
+ Not Before: May 25 00:00:00 2010 GMT
+ Not After : May 30 10:48:38 2020 GMT
+ Subject: C=US, O=Trusted Secure Certificate Authority, CN=Trusted Secure Certificate Authority
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:80:0b:42:c6:06:6c:cf:22:b3:1a:9e:11:2e:42:
+ 6e:39:bf:e8:12:af:3c:42:21:12:95:40:5d:32:b1:
+ 6d:1c:21:d1:34:e5:4f:a8:d1:43:a2:26:4e:30:7d:
+ 73:44:2c:73:aa:c5:4d:66:01:19:d2:ea:50:59:65:
+ d0:68:9d:05:a0:7c:a1:79:53:d0:21:90:59:0e:37:
+ db:1e:dc:92:a7:8b:0d:c4:f5:f8:e6:ff:b5:35:1a:
+ da:a8:b6:9b:20:85:65:c4:a2:4d:df:f3:94:4d:63:
+ 7e:ee:89:07:af:fe:e1:ba:00:15:2d:c6:77:8e:a3:
+ fe:ad:cf:26:54:5a:df:fc:d2:de:c2:ad:f6:b2:23:
+ fd:a8:83:e5:65:bd:27:f7:27:1a:18:59:6a:9e:14:
+ f6:b4:86:ff:1c:58:14:43:73:96:24:bf:10:43:d5:
+ 5c:89:f0:ce:f7:e1:96:16:5e:18:4a:27:28:90:80:
+ 18:fc:32:fe:f4:c7:b8:d6:82:3d:35:af:bb:4a:1c:
+ 5b:05:78:f6:fd:55:3e:82:74:b2:73:b8:89:4e:f7:
+ 1b:85:9a:d8:ca:b1:5a:b1:00:20:41:14:30:2b:14:
+ 24:ed:37:0e:32:3e:23:88:39:7e:b9:d9:38:03:e2:
+ 4c:d9:0d:43:41:33:10:eb:30:72:53:88:f7:52:9b:
+ 4f:81
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
+
+ X509v3 Subject Key Identifier:
+ CC:03:5B:96:5A:9E:16:CC:26:1E:BD:A3:70:FB:E3:CB:79:19:FC:4D
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.6449.1.2.2.8
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
+
+ Authority Information Access:
+ CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c
+ CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt
+ OCSP - URI:http://ocsp.usertrust.com
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 7b:f0:fc:a1:28:47:bc:2b:b4:04:73:3f:4b:dd:1e:d1:b9:cd:
+ 1c:ed:7d:e5:e8:cb:51:f4:92:bf:dd:9c:0d:5c:6e:1d:95:ed:
+ 5b:70:50:89:d4:67:9a:15:54:d1:90:0a:fa:09:68:06:18:bb:
+ d7:27:e4:93:ff:43:48:81:3b:c8:59:49:35:ea:ac:b6:ae:46:
+ b5:d4:f3:b8:c3:c6:e4:91:bf:c9:34:fd:7e:d0:59:6e:61:a1:
+ 1f:48:63:54:b2:7d:46:bf:c8:fa:c3:bf:48:58:98:f6:69:84:
+ a7:16:69:08:27:a4:22:cb:a2:2c:c8:df:6e:a9:ee:f8:41:df:
+ 1b:a8:b7:f3:e3:ae:ce:a3:fe:d9:27:60:50:3f:04:7d:7a:44:
+ ea:76:42:5c:d3:55:46:ef:27:c5:6a:4a:80:e7:35:a0:91:c6:
+ 1b:a6:86:9c:5a:3b:04:83:54:34:d7:d1:88:a6:36:e9:7f:40:
+ 27:da:56:0a:50:21:9d:29:8b:a0:84:ec:fe:71:23:53:04:18:
+ 19:70:67:86:44:95:72:40:55:f6:dd:a3:b4:3d:2d:09:60:a5:
+ e7:5f:fc:ac:3b:ec:0c:91:9f:f8:ee:6a:ba:b2:3c:fd:95:7d:
+ 9a:07:f4:b0:65:43:a2:f6:df:7d:b8:21:49:84:04:ee:bd:ce:
+ 53:8f:0f:29
+-----BEGIN CERTIFICATE-----
+MIIE5DCCA8ygAwIBAgIQT+PiZSEHqyA3QW5IcM7SwjANBgkqhkiG9w0BAQUFADBv
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
+ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
+eHRlcm5hbCBDQSBSb290MB4XDTEwMDUyNTAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
+azELMAkGA1UEBhMCVVMxLTArBgNVBAoTJFRydXN0ZWQgU2VjdXJlIENlcnRpZmlj
+YXRlIEF1dGhvcml0eTEtMCsGA1UEAxMkVHJ1c3RlZCBTZWN1cmUgQ2VydGlmaWNh
+dGUgQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgAtC
+xgZszyKzGp4RLkJuOb/oEq88QiESlUBdMrFtHCHRNOVPqNFDoiZOMH1zRCxzqsVN
+ZgEZ0upQWWXQaJ0FoHyheVPQIZBZDjfbHtySp4sNxPX45v+1NRraqLabIIVlxKJN
+3/OUTWN+7okHr/7hugAVLcZ3jqP+rc8mVFrf/NLewq32siP9qIPlZb0n9ycaGFlq
+nhT2tIb/HFgUQ3OWJL8QQ9VcifDO9+GWFl4YSicokIAY/DL+9Me41oI9Na+7Shxb
+BXj2/VU+gnSyc7iJTvcbhZrYyrFasQAgQRQwKxQk7TcOMj4jiDl+udk4A+JM2Q1D
+QTMQ6zByU4j3UptPgQIDAQABo4IBfjCCAXowHwYDVR0jBBgwFoAUrb2YejS0Jvf6
+xCZU7wO94CTLVBowHQYDVR0OBBYEFMwDW5ZanhbMJh69o3D748t5GfxNMA4GA1Ud
+DwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYB
+BAGyMQECAggwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3Qu
+Y29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMIGzBggrBgEFBQcBAQSBpjCB
+ozA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL0FkZFRydXN0
+RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsGAQUFBzAChi1odHRwOi8vY3J0LnVzZXJ0
+cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0NDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6
+Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEFBQADggEBAHvw/KEoR7wr
+tARzP0vdHtG5zRztfeXoy1H0kr/dnA1cbh2V7VtwUInUZ5oVVNGQCvoJaAYYu9cn
+5JP/Q0iBO8hZSTXqrLauRrXU87jDxuSRv8k0/X7QWW5hoR9IY1SyfUa/yPrDv0hY
+mPZphKcWaQgnpCLLoizI326p7vhB3xuot/Pjrs6j/tknYFA/BH16ROp2QlzTVUbv
+J8VqSoDnNaCRxhumhpxaOwSDVDTX0YimNul/QCfaVgpQIZ0pi6CE7P5xI1MEGBlw
+Z4ZElXJAVfbdo7Q9LQlgpedf/Kw77AyRn/juarqyPP2VfZoH9LBlQ6L23324IUmE
+BO69zlOPDyk=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert35[] = {
+ 0x30, 0x82, 0x04, 0xe4, 0x30, 0x82, 0x03, 0xcc, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x4f, 0xe3, 0xe2, 0x65, 0x21, 0x07, 0xab, 0x20, 0x37,
+ 0x41, 0x6e, 0x48, 0x70, 0xce, 0xd2, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53,
+ 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+ 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31,
+ 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64,
+ 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77,
+ 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
+ 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52,
+ 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x35, 0x32,
+ 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30,
+ 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30,
+ 0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x24, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x63,
+ 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24,
+ 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75,
+ 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x80, 0x0b, 0x42,
+ 0xc6, 0x06, 0x6c, 0xcf, 0x22, 0xb3, 0x1a, 0x9e, 0x11, 0x2e, 0x42, 0x6e,
+ 0x39, 0xbf, 0xe8, 0x12, 0xaf, 0x3c, 0x42, 0x21, 0x12, 0x95, 0x40, 0x5d,
+ 0x32, 0xb1, 0x6d, 0x1c, 0x21, 0xd1, 0x34, 0xe5, 0x4f, 0xa8, 0xd1, 0x43,
+ 0xa2, 0x26, 0x4e, 0x30, 0x7d, 0x73, 0x44, 0x2c, 0x73, 0xaa, 0xc5, 0x4d,
+ 0x66, 0x01, 0x19, 0xd2, 0xea, 0x50, 0x59, 0x65, 0xd0, 0x68, 0x9d, 0x05,
+ 0xa0, 0x7c, 0xa1, 0x79, 0x53, 0xd0, 0x21, 0x90, 0x59, 0x0e, 0x37, 0xdb,
+ 0x1e, 0xdc, 0x92, 0xa7, 0x8b, 0x0d, 0xc4, 0xf5, 0xf8, 0xe6, 0xff, 0xb5,
+ 0x35, 0x1a, 0xda, 0xa8, 0xb6, 0x9b, 0x20, 0x85, 0x65, 0xc4, 0xa2, 0x4d,
+ 0xdf, 0xf3, 0x94, 0x4d, 0x63, 0x7e, 0xee, 0x89, 0x07, 0xaf, 0xfe, 0xe1,
+ 0xba, 0x00, 0x15, 0x2d, 0xc6, 0x77, 0x8e, 0xa3, 0xfe, 0xad, 0xcf, 0x26,
+ 0x54, 0x5a, 0xdf, 0xfc, 0xd2, 0xde, 0xc2, 0xad, 0xf6, 0xb2, 0x23, 0xfd,
+ 0xa8, 0x83, 0xe5, 0x65, 0xbd, 0x27, 0xf7, 0x27, 0x1a, 0x18, 0x59, 0x6a,
+ 0x9e, 0x14, 0xf6, 0xb4, 0x86, 0xff, 0x1c, 0x58, 0x14, 0x43, 0x73, 0x96,
+ 0x24, 0xbf, 0x10, 0x43, 0xd5, 0x5c, 0x89, 0xf0, 0xce, 0xf7, 0xe1, 0x96,
+ 0x16, 0x5e, 0x18, 0x4a, 0x27, 0x28, 0x90, 0x80, 0x18, 0xfc, 0x32, 0xfe,
+ 0xf4, 0xc7, 0xb8, 0xd6, 0x82, 0x3d, 0x35, 0xaf, 0xbb, 0x4a, 0x1c, 0x5b,
+ 0x05, 0x78, 0xf6, 0xfd, 0x55, 0x3e, 0x82, 0x74, 0xb2, 0x73, 0xb8, 0x89,
+ 0x4e, 0xf7, 0x1b, 0x85, 0x9a, 0xd8, 0xca, 0xb1, 0x5a, 0xb1, 0x00, 0x20,
+ 0x41, 0x14, 0x30, 0x2b, 0x14, 0x24, 0xed, 0x37, 0x0e, 0x32, 0x3e, 0x23,
+ 0x88, 0x39, 0x7e, 0xb9, 0xd9, 0x38, 0x03, 0xe2, 0x4c, 0xd9, 0x0d, 0x43,
+ 0x41, 0x33, 0x10, 0xeb, 0x30, 0x72, 0x53, 0x88, 0xf7, 0x52, 0x9b, 0x4f,
+ 0x81, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7e, 0x30, 0x82,
+ 0x01, 0x7a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+ 0x16, 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa,
+ 0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30,
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcc, 0x03,
+ 0x5b, 0x96, 0x5a, 0x9e, 0x16, 0xcc, 0x26, 0x1e, 0xbd, 0xa3, 0x70, 0xfb,
+ 0xe3, 0xcb, 0x79, 0x19, 0xfc, 0x4d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
+ 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x18, 0x06, 0x03, 0x55, 0x1d,
+ 0x20, 0x04, 0x11, 0x30, 0x0f, 0x30, 0x0d, 0x06, 0x0b, 0x2b, 0x06, 0x01,
+ 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x02, 0x08, 0x30, 0x44, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0,
+ 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
+ 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
+ 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, 0x81,
+ 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
+ 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
+ 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
+ 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64,
+ 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43,
+ 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x7b, 0xf0, 0xfc, 0xa1, 0x28, 0x47, 0xbc, 0x2b,
+ 0xb4, 0x04, 0x73, 0x3f, 0x4b, 0xdd, 0x1e, 0xd1, 0xb9, 0xcd, 0x1c, 0xed,
+ 0x7d, 0xe5, 0xe8, 0xcb, 0x51, 0xf4, 0x92, 0xbf, 0xdd, 0x9c, 0x0d, 0x5c,
+ 0x6e, 0x1d, 0x95, 0xed, 0x5b, 0x70, 0x50, 0x89, 0xd4, 0x67, 0x9a, 0x15,
+ 0x54, 0xd1, 0x90, 0x0a, 0xfa, 0x09, 0x68, 0x06, 0x18, 0xbb, 0xd7, 0x27,
+ 0xe4, 0x93, 0xff, 0x43, 0x48, 0x81, 0x3b, 0xc8, 0x59, 0x49, 0x35, 0xea,
+ 0xac, 0xb6, 0xae, 0x46, 0xb5, 0xd4, 0xf3, 0xb8, 0xc3, 0xc6, 0xe4, 0x91,
+ 0xbf, 0xc9, 0x34, 0xfd, 0x7e, 0xd0, 0x59, 0x6e, 0x61, 0xa1, 0x1f, 0x48,
+ 0x63, 0x54, 0xb2, 0x7d, 0x46, 0xbf, 0xc8, 0xfa, 0xc3, 0xbf, 0x48, 0x58,
+ 0x98, 0xf6, 0x69, 0x84, 0xa7, 0x16, 0x69, 0x08, 0x27, 0xa4, 0x22, 0xcb,
+ 0xa2, 0x2c, 0xc8, 0xdf, 0x6e, 0xa9, 0xee, 0xf8, 0x41, 0xdf, 0x1b, 0xa8,
+ 0xb7, 0xf3, 0xe3, 0xae, 0xce, 0xa3, 0xfe, 0xd9, 0x27, 0x60, 0x50, 0x3f,
+ 0x04, 0x7d, 0x7a, 0x44, 0xea, 0x76, 0x42, 0x5c, 0xd3, 0x55, 0x46, 0xef,
+ 0x27, 0xc5, 0x6a, 0x4a, 0x80, 0xe7, 0x35, 0xa0, 0x91, 0xc6, 0x1b, 0xa6,
+ 0x86, 0x9c, 0x5a, 0x3b, 0x04, 0x83, 0x54, 0x34, 0xd7, 0xd1, 0x88, 0xa6,
+ 0x36, 0xe9, 0x7f, 0x40, 0x27, 0xda, 0x56, 0x0a, 0x50, 0x21, 0x9d, 0x29,
+ 0x8b, 0xa0, 0x84, 0xec, 0xfe, 0x71, 0x23, 0x53, 0x04, 0x18, 0x19, 0x70,
+ 0x67, 0x86, 0x44, 0x95, 0x72, 0x40, 0x55, 0xf6, 0xdd, 0xa3, 0xb4, 0x3d,
+ 0x2d, 0x09, 0x60, 0xa5, 0xe7, 0x5f, 0xfc, 0xac, 0x3b, 0xec, 0x0c, 0x91,
+ 0x9f, 0xf8, 0xee, 0x6a, 0xba, 0xb2, 0x3c, 0xfd, 0x95, 0x7d, 0x9a, 0x07,
+ 0xf4, 0xb0, 0x65, 0x43, 0xa2, 0xf6, 0xdf, 0x7d, 0xb8, 0x21, 0x49, 0x84,
+ 0x04, 0xee, 0xbd, 0xce, 0x53, 0x8f, 0x0f, 0x29,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 946072060 (0x3863e9fc)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
+ Validity
+ Not Before: Dec 10 20:43:54 2009 GMT
+ Not After : Dec 10 21:13:54 2019 GMT
+ Subject: C=US, O=Entrust, Inc., OU=www.entrust.net/rpa is incorporated by reference, OU=(c) 2009 Entrust, Inc., CN=Entrust Certification Authority - L1C
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:97:a3:2d:3c:9e:de:05:da:13:c2:11:8d:9d:8e:
+ e3:7f:c7:4b:7e:5a:9f:b3:ff:62:ab:73:c8:28:6b:
+ ba:10:64:82:87:13:cd:57:18:ff:28:ce:c0:e6:0e:
+ 06:91:50:29:83:d1:f2:c3:2a:db:d8:db:4e:04:cc:
+ 00:eb:8b:b6:96:dc:bc:aa:fa:52:77:04:c1:db:19:
+ e4:ae:9c:fd:3c:8b:03:ef:4d:bc:1a:03:65:f9:c1:
+ b1:3f:72:86:f2:38:aa:19:ae:10:88:78:28:da:75:
+ c3:3d:02:82:02:9c:b9:c1:65:77:76:24:4c:98:f7:
+ 6d:31:38:fb:db:fe:db:37:02:76:a1:18:97:a6:cc:
+ de:20:09:49:36:24:69:42:f6:e4:37:62:f1:59:6d:
+ a9:3c:ed:34:9c:a3:8e:db:dc:3a:d7:f7:0a:6f:ef:
+ 2e:d8:d5:93:5a:7a:ed:08:49:68:e2:41:e3:5a:90:
+ c1:86:55:fc:51:43:9d:e0:b2:c4:67:b4:cb:32:31:
+ 25:f0:54:9f:4b:d1:6f:db:d4:dd:fc:af:5e:6c:78:
+ 90:95:de:ca:3a:48:b9:79:3c:9b:19:d6:75:05:a0:
+ f9:88:d7:c1:e8:a5:09:e4:1a:15:dc:87:23:aa:b2:
+ 75:8c:63:25:87:d8:f8:3d:a6:c2:cc:66:ff:a5:66:
+ 68:55
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Authority Information Access:
+ OCSP - URI:http://ocsp.entrust.net
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.entrust.net/2048ca.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.entrust.net/rpa
+
+ X509v3 Subject Key Identifier:
+ 1E:F1:AB:89:06:F8:49:0F:01:33:77:EE:14:7A:EE:19:7C:93:28:4D
+ X509v3 Authority Key Identifier:
+ keyid:55:E4:81:D1:11:80:BE:D8:89:B9:08:A3:31:F9:A1:24:09:16:B9:70
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 07:f6:5f:82:84:7f:80:40:c7:90:34:46:42:24:03:ce:2f:ab:
+ ba:83:9e:25:73:0d:ed:ac:05:69:c6:87:ed:a3:5c:f2:57:c1:
+ b1:49:76:9a:4d:f2:3f:dd:e4:0e:fe:0b:3e:b9:98:d9:32:95:
+ 1d:32:f4:01:ee:9c:c8:c8:e5:3f:e0:53:76:62:fc:dd:ab:6d:
+ 3d:94:90:f2:c0:b3:3c:98:27:36:5e:28:97:22:fc:1b:40:d3:
+ 2b:0d:ad:b5:57:6d:df:0f:e3:4b:ef:73:02:10:65:fa:1b:d0:
+ ac:31:d5:e3:0f:e8:ba:32:30:83:ee:4a:d0:bf:df:22:90:7a:
+ be:ec:3a:1b:c4:49:04:1d:f1:ae:80:77:3c:42:08:db:a7:3b:
+ 28:a6:80:01:03:e6:39:a3:eb:df:80:59:1b:f3:2c:be:dc:72:
+ 44:79:a0:6c:07:a5:6d:4d:44:8e:42:68:ca:94:7c:2e:36:ba:
+ 85:9e:cd:aa:c4:5e:3c:54:be:fe:2f:ea:69:9d:1c:1e:29:9b:
+ 96:d8:c8:fe:51:90:f1:24:a6:90:06:b3:f0:29:a2:ff:78:2e:
+ 77:5c:45:21:d9:44:00:31:f3:be:32:4f:f5:0a:32:0d:fc:fc:
+ ba:16:76:56:b2:d6:48:92:f2:8b:a6:3e:b7:ac:5c:69:ea:0b:
+ 3f:66:45:b9
+-----BEGIN CERTIFICATE-----
+MIIE8jCCA9qgAwIBAgIEOGPp/DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0wOTEyMTAyMDQzNTRaFw0xOTEy
+MTAyMTEzNTRaMIGxMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5j
+LjE5MDcGA1UECxMwd3d3LmVudHJ1c3QubmV0L3JwYSBpcyBpbmNvcnBvcmF0ZWQg
+YnkgcmVmZXJlbmNlMR8wHQYDVQQLExYoYykgMjAwOSBFbnRydXN0LCBJbmMuMS4w
+LAYDVQQDEyVFbnRydXN0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gTDFDMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl6MtPJ7eBdoTwhGNnY7jf8dL
+flqfs/9iq3PIKGu6EGSChxPNVxj/KM7A5g4GkVApg9Hywyrb2NtOBMwA64u2lty8
+qvpSdwTB2xnkrpz9PIsD7028GgNl+cGxP3KG8jiqGa4QiHgo2nXDPQKCApy5wWV3
+diRMmPdtMTj72/7bNwJ2oRiXpszeIAlJNiRpQvbkN2LxWW2pPO00nKOO29w61/cK
+b+8u2NWTWnrtCElo4kHjWpDBhlX8UUOd4LLEZ7TLMjEl8FSfS9Fv29Td/K9ebHiQ
+ld7KOki5eTybGdZ1BaD5iNfB6KUJ5BoV3IcjqrJ1jGMlh9j4PabCzGb/pWZoVQID
+AQABo4IBCzCCAQcwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wMwYI
+KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l
+dDAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLmVudHJ1c3QubmV0LzIwNDhj
+YS5jcmwwOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93
+d3cuZW50cnVzdC5uZXQvcnBhMB0GA1UdDgQWBBQe8auJBvhJDwEzd+4Ueu4ZfJMo
+TTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDANBgkqhkiG9w0BAQUF
+AAOCAQEAB/ZfgoR/gEDHkDRGQiQDzi+ruoOeJXMN7awFacaH7aNc8lfBsUl2mk3y
+P93kDv4LPrmY2TKVHTL0Ae6cyMjlP+BTdmL83attPZSQ8sCzPJgnNl4olyL8G0DT
+Kw2ttVdt3w/jS+9zAhBl+hvQrDHV4w/oujIwg+5K0L/fIpB6vuw6G8RJBB3xroB3
+PEII26c7KKaAAQPmOaPr34BZG/MsvtxyRHmgbAelbU1EjkJoypR8Lja6hZ7NqsRe
+PFS+/i/qaZ0cHimbltjI/lGQ8SSmkAaz8Cmi/3gud1xFIdlEADHzvjJP9QoyDfz8
+uhZ2VrLWSJLyi6Y+t6xcaeoLP2ZFuQ==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert36[] = {
+ 0x30, 0x82, 0x04, 0xf2, 0x30, 0x82, 0x03, 0xda, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x38, 0x63, 0xe9, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+ 0xb4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+ 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x31,
+ 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x37, 0x77, 0x77,
+ 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
+ 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x20, 0x69,
+ 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65,
+ 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x20, 0x6c,
+ 0x69, 0x61, 0x62, 0x2e, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x1c, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39,
+ 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74,
+ 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, 0x30, 0x31,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x45, 0x6e, 0x74, 0x72, 0x75,
+ 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, 0x34, 0x38,
+ 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x31, 0x30, 0x32,
+ 0x30, 0x34, 0x33, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32,
+ 0x31, 0x30, 0x32, 0x31, 0x31, 0x33, 0x35, 0x34, 0x5a, 0x30, 0x81, 0xb1,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d,
+ 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30,
+ 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x69, 0x73, 0x20, 0x69,
+ 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20,
+ 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x28,
+ 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30,
+ 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x4c, 0x31, 0x43, 0x30, 0x82, 0x01,
+ 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+ 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde,
+ 0x05, 0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3, 0x7f, 0xc7, 0x4b,
+ 0x7e, 0x5a, 0x9f, 0xb3, 0xff, 0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba,
+ 0x10, 0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff, 0x28, 0xce, 0xc0,
+ 0xe6, 0x0e, 0x06, 0x91, 0x50, 0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb,
+ 0xd8, 0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6, 0x96, 0xdc, 0xbc,
+ 0xaa, 0xfa, 0x52, 0x77, 0x04, 0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd,
+ 0x3c, 0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65, 0xf9, 0xc1, 0xb1,
+ 0x3f, 0x72, 0x86, 0xf2, 0x38, 0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28,
+ 0xda, 0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9, 0xc1, 0x65, 0x77,
+ 0x76, 0x24, 0x4c, 0x98, 0xf7, 0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb,
+ 0x37, 0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde, 0x20, 0x09, 0x49,
+ 0x36, 0x24, 0x69, 0x42, 0xf6, 0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9,
+ 0x3c, 0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a, 0xd7, 0xf7, 0x0a,
+ 0x6f, 0xef, 0x2e, 0xd8, 0xd5, 0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68,
+ 0xe2, 0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc, 0x51, 0x43, 0x9d,
+ 0xe0, 0xb2, 0xc4, 0x67, 0xb4, 0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f,
+ 0x4b, 0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e, 0x6c, 0x78, 0x90,
+ 0x95, 0xde, 0xca, 0x3a, 0x48, 0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75,
+ 0x05, 0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09, 0xe4, 0x1a, 0x15,
+ 0xdc, 0x87, 0x23, 0xaa, 0xb2, 0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8,
+ 0x3d, 0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68, 0x55, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0b, 0x30, 0x82, 0x01, 0x07, 0x30,
+ 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
+ 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+ 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x33, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25,
+ 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
+ 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
+ 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
+ 0x74, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29,
+ 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75,
+ 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x32, 0x30, 0x34, 0x38, 0x63,
+ 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20,
+ 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
+ 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+ 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e,
+ 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0x1e, 0xf1, 0xab, 0x89, 0x06, 0xf8, 0x49,
+ 0x0f, 0x01, 0x33, 0x77, 0xee, 0x14, 0x7a, 0xee, 0x19, 0x7c, 0x93, 0x28,
+ 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0x55, 0xe4, 0x81, 0xd1, 0x11, 0x80, 0xbe, 0xd8, 0x89, 0xb9,
+ 0x08, 0xa3, 0x31, 0xf9, 0xa1, 0x24, 0x09, 0x16, 0xb9, 0x70, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, 0xf6, 0x5f, 0x82, 0x84, 0x7f,
+ 0x80, 0x40, 0xc7, 0x90, 0x34, 0x46, 0x42, 0x24, 0x03, 0xce, 0x2f, 0xab,
+ 0xba, 0x83, 0x9e, 0x25, 0x73, 0x0d, 0xed, 0xac, 0x05, 0x69, 0xc6, 0x87,
+ 0xed, 0xa3, 0x5c, 0xf2, 0x57, 0xc1, 0xb1, 0x49, 0x76, 0x9a, 0x4d, 0xf2,
+ 0x3f, 0xdd, 0xe4, 0x0e, 0xfe, 0x0b, 0x3e, 0xb9, 0x98, 0xd9, 0x32, 0x95,
+ 0x1d, 0x32, 0xf4, 0x01, 0xee, 0x9c, 0xc8, 0xc8, 0xe5, 0x3f, 0xe0, 0x53,
+ 0x76, 0x62, 0xfc, 0xdd, 0xab, 0x6d, 0x3d, 0x94, 0x90, 0xf2, 0xc0, 0xb3,
+ 0x3c, 0x98, 0x27, 0x36, 0x5e, 0x28, 0x97, 0x22, 0xfc, 0x1b, 0x40, 0xd3,
+ 0x2b, 0x0d, 0xad, 0xb5, 0x57, 0x6d, 0xdf, 0x0f, 0xe3, 0x4b, 0xef, 0x73,
+ 0x02, 0x10, 0x65, 0xfa, 0x1b, 0xd0, 0xac, 0x31, 0xd5, 0xe3, 0x0f, 0xe8,
+ 0xba, 0x32, 0x30, 0x83, 0xee, 0x4a, 0xd0, 0xbf, 0xdf, 0x22, 0x90, 0x7a,
+ 0xbe, 0xec, 0x3a, 0x1b, 0xc4, 0x49, 0x04, 0x1d, 0xf1, 0xae, 0x80, 0x77,
+ 0x3c, 0x42, 0x08, 0xdb, 0xa7, 0x3b, 0x28, 0xa6, 0x80, 0x01, 0x03, 0xe6,
+ 0x39, 0xa3, 0xeb, 0xdf, 0x80, 0x59, 0x1b, 0xf3, 0x2c, 0xbe, 0xdc, 0x72,
+ 0x44, 0x79, 0xa0, 0x6c, 0x07, 0xa5, 0x6d, 0x4d, 0x44, 0x8e, 0x42, 0x68,
+ 0xca, 0x94, 0x7c, 0x2e, 0x36, 0xba, 0x85, 0x9e, 0xcd, 0xaa, 0xc4, 0x5e,
+ 0x3c, 0x54, 0xbe, 0xfe, 0x2f, 0xea, 0x69, 0x9d, 0x1c, 0x1e, 0x29, 0x9b,
+ 0x96, 0xd8, 0xc8, 0xfe, 0x51, 0x90, 0xf1, 0x24, 0xa6, 0x90, 0x06, 0xb3,
+ 0xf0, 0x29, 0xa2, 0xff, 0x78, 0x2e, 0x77, 0x5c, 0x45, 0x21, 0xd9, 0x44,
+ 0x00, 0x31, 0xf3, 0xbe, 0x32, 0x4f, 0xf5, 0x0a, 0x32, 0x0d, 0xfc, 0xfc,
+ 0xba, 0x16, 0x76, 0x56, 0xb2, 0xd6, 0x48, 0x92, 0xf2, 0x8b, 0xa6, 0x3e,
+ 0xb7, 0xac, 0x5c, 0x69, 0xea, 0x0b, 0x3f, 0x66, 0x45, 0xb9,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 16:90:c3:29:b6:78:06:07:51:1f:05:b0:34:48:46:cb
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
+ Validity
+ Not Before: Apr 16 00:00:00 2010 GMT
+ Not After : May 30 10:48:38 2020 GMT
+ Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO High-Assurance Secure Server CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e7:87:da:c0:77:e4:bb:3a:fa:6a:24:c8:80:41:
+ ac:d2:16:13:15:3d:fa:f7:f8:2a:76:dc:a8:2d:39:
+ 08:ce:48:4a:be:0f:7d:f0:de:ba:bb:47:d5:bd:2d:
+ d7:1b:ab:0f:20:81:23:08:72:b1:c0:11:95:0d:e6:
+ ea:a9:87:ff:c7:6e:1e:4f:66:32:ba:53:bc:05:aa:
+ 1c:2c:0c:ef:4d:37:47:6b:10:0c:db:c5:a0:98:7e:
+ 58:db:37:d6:ae:e9:06:bd:d7:a8:65:f3:37:b9:c7:
+ 6d:ce:77:c7:26:e0:d7:74:1f:a6:98:16:bb:0c:6b:
+ c8:be:77:d0:ef:58:a7:29:a0:b9:b8:69:05:36:cb:
+ b2:da:58:a3:0b:75:ad:3d:8b:22:82:20:3e:70:86:
+ 99:1c:b9:4f:cf:77:a4:07:1a:23:63:d1:38:56:84:
+ ec:bf:8f:c5:4e:f4:18:96:9b:1a:e8:93:ec:8d:af:
+ 15:9c:24:f0:5a:3b:e8:0f:b9:a8:5a:01:d3:b2:1c:
+ 60:c9:9c:52:04:dd:92:a7:fe:0c:ac:e2:45:8d:03:
+ 61:bc:79:e0:77:2e:87:41:3c:58:5f:cb:f5:c5:77:
+ f2:58:c8:4d:28:d0:9a:fa:f3:73:09:24:68:74:bc:
+ 20:4c:d8:2c:b0:aa:e8:d9:4e:6d:f2:8c:24:d3:93:
+ 5d:91
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Authority Key Identifier:
+ keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
+
+ X509v3 Subject Key Identifier:
+ 3F:D5:B5:D0:D6:44:79:50:4A:17:A3:9B:8C:4A:DC:B8:B0:22:64:6B
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
+
+ Authority Information Access:
+ CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c
+ CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt
+ OCSP - URI:http://ocsp.usertrust.com
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 13:85:1f:52:80:18:c9:53:f7:fe:2e:1a:af:cc:d9:0b:3c:c2:
+ d3:85:81:10:f0:28:8d:b9:40:7e:2c:9e:8f:d6:36:86:0a:4c:
+ 14:2d:d6:97:43:92:41:19:37:4b:96:9e:eb:a9:30:79:12:95:
+ b3:02:36:57:ed:2b:b9:1d:98:1a:a3:18:0a:3f:9b:39:8b:cd:
+ a1:49:29:4c:2f:f9:d0:95:8c:c8:4d:95:ba:a8:43:cf:33:aa:
+ 25:2a:5a:0e:aa:27:c9:4e:6b:b1:e6:73:1f:b3:74:04:c3:f3:
+ 4c:e2:a8:eb:67:b7:5d:b8:08:05:1a:56:9a:54:29:85:f5:29:
+ 4e:80:3b:95:d0:7b:53:96:11:56:c1:02:d3:ea:b2:7f:ca:8f:
+ 9c:70:4a:14:8d:5a:b9:16:60:75:d6:cd:27:1e:16:cd:5b:33:
+ 8e:79:40:cf:28:48:e7:dc:71:16:4e:74:91:75:b9:2a:8c:f1:
+ 70:ac:26:dd:04:b9:40:c2:85:de:1c:93:40:d0:cc:6e:c3:9b:
+ aa:ef:60:65:df:60:22:f0:5a:a5:7a:a2:2f:e4:70:73:ee:3c:
+ d4:26:2b:68:07:c1:20:7a:e8:98:5a:3e:7b:9f:02:8b:62:c0:
+ 85:81:80:60:35:7e:a5:1d:0c:d2:9c:df:62:45:0d:db:fc:37:
+ fb:f5:25:22
+-----BEGIN CERTIFICATE-----
+MIIE/DCCA+SgAwIBAgIQFpDDKbZ4BgdRHwWwNEhGyzANBgkqhkiG9w0BAQUFADBv
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
+ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
+eHRlcm5hbCBDQSBSb290MB4XDTEwMDQxNjAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
+gYkxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
+BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMS8wLQYD
+VQQDEyZDT01PRE8gSGlnaC1Bc3N1cmFuY2UgU2VjdXJlIFNlcnZlciBDQTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOeH2sB35Ls6+mokyIBBrNIWExU9
++vf4KnbcqC05CM5ISr4PffDeurtH1b0t1xurDyCBIwhyscARlQ3m6qmH/8duHk9m
+MrpTvAWqHCwM7003R2sQDNvFoJh+WNs31q7pBr3XqGXzN7nHbc53xybg13QfppgW
+uwxryL530O9YpymgubhpBTbLstpYowt1rT2LIoIgPnCGmRy5T893pAcaI2PROFaE
+7L+PxU70GJabGuiT7I2vFZwk8Fo76A+5qFoB07IcYMmcUgTdkqf+DKziRY0DYbx5
+4Hcuh0E8WF/L9cV38ljITSjQmvrzcwkkaHS8IEzYLLCq6NlObfKMJNOTXZECAwEA
+AaOCAXcwggFzMB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8DveAky1QaMB0GA1Ud
+DgQWBBQ/1bXQ1kR5UEoXo5uMSty4sCJkazAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0T
+AQH/BAgwBgEB/wIBADARBgNVHSAECjAIMAYGBFUdIAAwRAYDVR0fBD0wOzA5oDeg
+NYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJv
+b3QuY3JsMIGzBggrBgEFBQcBAQSBpjCBozA/BggrBgEFBQcwAoYzaHR0cDovL2Ny
+dC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsG
+AQUFBzAChi1odHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0ND
+QS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJ
+KoZIhvcNAQEFBQADggEBABOFH1KAGMlT9/4uGq/M2Qs8wtOFgRDwKI25QH4sno/W
+NoYKTBQt1pdDkkEZN0uWnuupMHkSlbMCNlftK7kdmBqjGAo/mzmLzaFJKUwv+dCV
+jMhNlbqoQ88zqiUqWg6qJ8lOa7Hmcx+zdATD80ziqOtnt124CAUaVppUKYX1KU6A
+O5XQe1OWEVbBAtPqsn/Kj5xwShSNWrkWYHXWzSceFs1bM455QM8oSOfccRZOdJF1
+uSqM8XCsJt0EuUDChd4ck0DQzG7Dm6rvYGXfYCLwWqV6oi/kcHPuPNQmK2gHwSB6
+6JhaPnufAotiwIWBgGA1fqUdDNKc32JFDdv8N/v1JSI=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert37[] = {
+ 0x30, 0x82, 0x04, 0xfc, 0x30, 0x82, 0x03, 0xe4, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x16, 0x90, 0xc3, 0x29, 0xb6, 0x78, 0x06, 0x07, 0x51,
+ 0x1f, 0x05, 0xb0, 0x34, 0x48, 0x46, 0xcb, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53,
+ 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b,
+ 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31,
+ 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64,
+ 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77,
+ 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45,
+ 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52,
+ 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x34, 0x31,
+ 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30,
+ 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30,
+ 0x81, 0x89, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08,
+ 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61,
+ 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f,
+ 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c,
+ 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x26, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20,
+ 0x48, 0x69, 0x67, 0x68, 0x2d, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e,
+ 0x63, 0x65, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+ 0x82, 0x01, 0x01, 0x00, 0xe7, 0x87, 0xda, 0xc0, 0x77, 0xe4, 0xbb, 0x3a,
+ 0xfa, 0x6a, 0x24, 0xc8, 0x80, 0x41, 0xac, 0xd2, 0x16, 0x13, 0x15, 0x3d,
+ 0xfa, 0xf7, 0xf8, 0x2a, 0x76, 0xdc, 0xa8, 0x2d, 0x39, 0x08, 0xce, 0x48,
+ 0x4a, 0xbe, 0x0f, 0x7d, 0xf0, 0xde, 0xba, 0xbb, 0x47, 0xd5, 0xbd, 0x2d,
+ 0xd7, 0x1b, 0xab, 0x0f, 0x20, 0x81, 0x23, 0x08, 0x72, 0xb1, 0xc0, 0x11,
+ 0x95, 0x0d, 0xe6, 0xea, 0xa9, 0x87, 0xff, 0xc7, 0x6e, 0x1e, 0x4f, 0x66,
+ 0x32, 0xba, 0x53, 0xbc, 0x05, 0xaa, 0x1c, 0x2c, 0x0c, 0xef, 0x4d, 0x37,
+ 0x47, 0x6b, 0x10, 0x0c, 0xdb, 0xc5, 0xa0, 0x98, 0x7e, 0x58, 0xdb, 0x37,
+ 0xd6, 0xae, 0xe9, 0x06, 0xbd, 0xd7, 0xa8, 0x65, 0xf3, 0x37, 0xb9, 0xc7,
+ 0x6d, 0xce, 0x77, 0xc7, 0x26, 0xe0, 0xd7, 0x74, 0x1f, 0xa6, 0x98, 0x16,
+ 0xbb, 0x0c, 0x6b, 0xc8, 0xbe, 0x77, 0xd0, 0xef, 0x58, 0xa7, 0x29, 0xa0,
+ 0xb9, 0xb8, 0x69, 0x05, 0x36, 0xcb, 0xb2, 0xda, 0x58, 0xa3, 0x0b, 0x75,
+ 0xad, 0x3d, 0x8b, 0x22, 0x82, 0x20, 0x3e, 0x70, 0x86, 0x99, 0x1c, 0xb9,
+ 0x4f, 0xcf, 0x77, 0xa4, 0x07, 0x1a, 0x23, 0x63, 0xd1, 0x38, 0x56, 0x84,
+ 0xec, 0xbf, 0x8f, 0xc5, 0x4e, 0xf4, 0x18, 0x96, 0x9b, 0x1a, 0xe8, 0x93,
+ 0xec, 0x8d, 0xaf, 0x15, 0x9c, 0x24, 0xf0, 0x5a, 0x3b, 0xe8, 0x0f, 0xb9,
+ 0xa8, 0x5a, 0x01, 0xd3, 0xb2, 0x1c, 0x60, 0xc9, 0x9c, 0x52, 0x04, 0xdd,
+ 0x92, 0xa7, 0xfe, 0x0c, 0xac, 0xe2, 0x45, 0x8d, 0x03, 0x61, 0xbc, 0x79,
+ 0xe0, 0x77, 0x2e, 0x87, 0x41, 0x3c, 0x58, 0x5f, 0xcb, 0xf5, 0xc5, 0x77,
+ 0xf2, 0x58, 0xc8, 0x4d, 0x28, 0xd0, 0x9a, 0xfa, 0xf3, 0x73, 0x09, 0x24,
+ 0x68, 0x74, 0xbc, 0x20, 0x4c, 0xd8, 0x2c, 0xb0, 0xaa, 0xe8, 0xd9, 0x4e,
+ 0x6d, 0xf2, 0x8c, 0x24, 0xd3, 0x93, 0x5d, 0x91, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x82, 0x01, 0x77, 0x30, 0x82, 0x01, 0x73, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xad, 0xbd,
+ 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03,
+ 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3f, 0xd5, 0xb5, 0xd0, 0xd6, 0x44, 0x79,
+ 0x50, 0x4a, 0x17, 0xa3, 0x9b, 0x8c, 0x4a, 0xdc, 0xb8, 0xb0, 0x22, 0x64,
+ 0x6b, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+ 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08,
+ 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x44, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0,
+ 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
+ 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
+ 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, 0x81,
+ 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
+ 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
+ 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f,
+ 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64,
+ 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43,
+ 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x13, 0x85, 0x1f, 0x52, 0x80, 0x18, 0xc9, 0x53,
+ 0xf7, 0xfe, 0x2e, 0x1a, 0xaf, 0xcc, 0xd9, 0x0b, 0x3c, 0xc2, 0xd3, 0x85,
+ 0x81, 0x10, 0xf0, 0x28, 0x8d, 0xb9, 0x40, 0x7e, 0x2c, 0x9e, 0x8f, 0xd6,
+ 0x36, 0x86, 0x0a, 0x4c, 0x14, 0x2d, 0xd6, 0x97, 0x43, 0x92, 0x41, 0x19,
+ 0x37, 0x4b, 0x96, 0x9e, 0xeb, 0xa9, 0x30, 0x79, 0x12, 0x95, 0xb3, 0x02,
+ 0x36, 0x57, 0xed, 0x2b, 0xb9, 0x1d, 0x98, 0x1a, 0xa3, 0x18, 0x0a, 0x3f,
+ 0x9b, 0x39, 0x8b, 0xcd, 0xa1, 0x49, 0x29, 0x4c, 0x2f, 0xf9, 0xd0, 0x95,
+ 0x8c, 0xc8, 0x4d, 0x95, 0xba, 0xa8, 0x43, 0xcf, 0x33, 0xaa, 0x25, 0x2a,
+ 0x5a, 0x0e, 0xaa, 0x27, 0xc9, 0x4e, 0x6b, 0xb1, 0xe6, 0x73, 0x1f, 0xb3,
+ 0x74, 0x04, 0xc3, 0xf3, 0x4c, 0xe2, 0xa8, 0xeb, 0x67, 0xb7, 0x5d, 0xb8,
+ 0x08, 0x05, 0x1a, 0x56, 0x9a, 0x54, 0x29, 0x85, 0xf5, 0x29, 0x4e, 0x80,
+ 0x3b, 0x95, 0xd0, 0x7b, 0x53, 0x96, 0x11, 0x56, 0xc1, 0x02, 0xd3, 0xea,
+ 0xb2, 0x7f, 0xca, 0x8f, 0x9c, 0x70, 0x4a, 0x14, 0x8d, 0x5a, 0xb9, 0x16,
+ 0x60, 0x75, 0xd6, 0xcd, 0x27, 0x1e, 0x16, 0xcd, 0x5b, 0x33, 0x8e, 0x79,
+ 0x40, 0xcf, 0x28, 0x48, 0xe7, 0xdc, 0x71, 0x16, 0x4e, 0x74, 0x91, 0x75,
+ 0xb9, 0x2a, 0x8c, 0xf1, 0x70, 0xac, 0x26, 0xdd, 0x04, 0xb9, 0x40, 0xc2,
+ 0x85, 0xde, 0x1c, 0x93, 0x40, 0xd0, 0xcc, 0x6e, 0xc3, 0x9b, 0xaa, 0xef,
+ 0x60, 0x65, 0xdf, 0x60, 0x22, 0xf0, 0x5a, 0xa5, 0x7a, 0xa2, 0x2f, 0xe4,
+ 0x70, 0x73, 0xee, 0x3c, 0xd4, 0x26, 0x2b, 0x68, 0x07, 0xc1, 0x20, 0x7a,
+ 0xe8, 0x98, 0x5a, 0x3e, 0x7b, 0x9f, 0x02, 0x8b, 0x62, 0xc0, 0x85, 0x81,
+ 0x80, 0x60, 0x35, 0x7e, 0xa5, 0x1d, 0x0c, 0xd2, 0x9c, 0xdf, 0x62, 0x45,
+ 0x0d, 0xdb, 0xfc, 0x37, 0xfb, 0xf5, 0x25, 0x22,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1372799044 (0x51d34044)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority
+ Validity
+ Not Before: Sep 22 17:14:57 2014 GMT
+ Not After : Sep 23 01:31:53 2024 GMT
+ Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ba:84:b6:72:db:9e:0c:6b:e2:99:e9:30:01:a7:
+ 76:ea:32:b8:95:41:1a:c9:da:61:4e:58:72:cf:fe:
+ f6:82:79:bf:73:61:06:0a:a5:27:d8:b3:5f:d3:45:
+ 4e:1c:72:d6:4e:32:f2:72:8a:0f:f7:83:19:d0:6a:
+ 80:80:00:45:1e:b0:c7:e7:9a:bf:12:57:27:1c:a3:
+ 68:2f:0a:87:bd:6a:6b:0e:5e:65:f3:1c:77:d5:d4:
+ 85:8d:70:21:b4:b3:32:e7:8b:a2:d5:86:39:02:b1:
+ b8:d2:47:ce:e4:c9:49:c4:3b:a7:de:fb:54:7d:57:
+ be:f0:e8:6e:c2:79:b2:3a:0b:55:e2:50:98:16:32:
+ 13:5c:2f:78:56:c1:c2:94:b3:f2:5a:e4:27:9a:9f:
+ 24:d7:c6:ec:d0:9b:25:82:e3:cc:c2:c4:45:c5:8c:
+ 97:7a:06:6b:2a:11:9f:a9:0a:6e:48:3b:6f:db:d4:
+ 11:19:42:f7:8f:07:bf:f5:53:5f:9c:3e:f4:17:2c:
+ e6:69:ac:4e:32:4c:62:77:ea:b7:e8:e5:bb:34:bc:
+ 19:8b:ae:9c:51:e7:b7:7e:b5:53:b1:33:22:e5:6d:
+ cf:70:3c:1a:fa:e2:9b:67:b6:83:f4:8d:a5:af:62:
+ 4c:4d:e0:58:ac:64:34:12:03:f8:b6:8d:94:63:24:
+ a4:71
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:1
+ Authority Information Access:
+ OCSP - URI:http://ocsp.entrust.net
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.entrust.net/rootca1.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.entrust.net/CPS
+
+ X509v3 Subject Key Identifier:
+ 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
+ X509v3 Authority Key Identifier:
+ keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 69:33:83:fc:28:7a:6f:7d:ef:9d:55:eb:c5:3e:7a:9d:75:b3:
+ cc:c3:38:36:d9:34:a2:28:68:18:ea:1e:69:d3:bd:e7:d0:77:
+ da:b8:00:83:4e:4a:cf:6f:d1:f1:c1:22:3f:74:e4:f7:98:49:
+ 9e:9b:b6:9e:e1:db:98:77:2d:56:34:b1:a8:3c:d9:fd:c0:cd:
+ c7:bf:05:03:d4:02:c5:f1:e5:c6:da:08:a5:13:c7:62:23:11:
+ d1:61:30:1d:60:84:45:ef:79:a8:c6:26:93:a4:b7:cd:34:b8:
+ 69:c5:13:f6:91:b3:c9:45:73:76:b6:92:f6:76:0a:5b:e1:03:
+ 47:b7:e9:29:4c:91:32:23:37:4a:9c:35:d8:78:fd:1d:1f:e4:
+ 83:89:24:80:ad:b7:f9:cf:e4:5d:a5:d4:71:c4:85:5b:70:1f:
+ db:3f:1c:01:eb:1a:45:26:31:14:cc:65:bf:67:de:ca:cc:33:
+ 65:e5:41:91:d7:37:be:41:1a:96:9d:e6:8a:97:9d:a7:ce:ac:
+ 4e:9a:3d:bd:01:a0:6a:d9:4f:22:00:8b:44:d5:69:62:7b:2e:
+ eb:cc:ba:e7:92:7d:69:67:3d:fc:b8:7c:de:41:87:d0:69:ea:
+ ba:0a:18:7a:1a:95:43:b3:79:71:28:76:6d:a1:fb:57:4a:ec:
+ 4d:c8:0e:10
+-----BEGIN CERTIFICATE-----
+MIIE/zCCA+egAwIBAgIEUdNARDANBgkqhkiG9w0BAQsFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MDkyMjE3MTQ1N1oXDTI0MDkyMzAx
+MzE1M1owgb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgw
+JgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQL
+EzAoYykgMjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9u
+bHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuoS2ctueDGvi
+mekwAad26jK4lUEaydphTlhyz/72gnm/c2EGCqUn2LNf00VOHHLWTjLycooP94MZ
+0GqAgABFHrDH55q/ElcnHKNoLwqHvWprDl5l8xx31dSFjXAhtLMy54ui1YY5ArG4
+0kfO5MlJxDun3vtUfVe+8OhuwnmyOgtV4lCYFjITXC94VsHClLPyWuQnmp8k18bs
+0JslguPMwsRFxYyXegZrKhGfqQpuSDtv29QRGUL3jwe/9VNfnD70FyzmaaxOMkxi
+d+q36OW7NLwZi66cUee3frVTsTMi5W3PcDwa+uKbZ7aD9I2lr2JMTeBYrGQ0EgP4
+to2UYySkcQIDAQABo4IBDzCCAQswDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI
+MAYBAf8CAQEwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz
+cC5lbnRydXN0Lm5ldDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1
+c3QubmV0L3Jvb3RjYTEuY3JsMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUF
+BwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NQUzAdBgNVHQ4EFgQUanImetAe
+733nO2lR1GyNn5ASZqswHwYDVR0jBBgwFoAUaJDkZ6SmU4DHhmak8fdLQ/uEvW0w
+DQYJKoZIhvcNAQELBQADggEBAGkzg/woem99751V68U+ep11s8zDODbZNKIoaBjq
+HmnTvefQd9q4AINOSs9v0fHBIj905PeYSZ6btp7h25h3LVY0sag82f3Azce/BQPU
+AsXx5cbaCKUTx2IjEdFhMB1ghEXveajGJpOkt800uGnFE/aRs8lFc3a2kvZ2Clvh
+A0e36SlMkTIjN0qcNdh4/R0f5IOJJICtt/nP5F2l1HHEhVtwH9s/HAHrGkUmMRTM
+Zb9n3srMM2XlQZHXN75BGpad5oqXnafOrE6aPb0BoGrZTyIAi0TVaWJ7LuvMuueS
+fWlnPfy4fN5Bh9Bp6roKGHoalUOzeXEodm2h+1dK7E3IDhA=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert38[] = {
+ 0x30, 0x82, 0x04, 0xff, 0x30, 0x82, 0x03, 0xe7, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x51, 0xd3, 0x40, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xb0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x30, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
+ 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x69, 0x73, 0x20,
+ 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64,
+ 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
+ 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16,
+ 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, 0x6e, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d,
+ 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, 0x6e, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+ 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x34, 0x30, 0x39, 0x32, 0x32, 0x31, 0x37, 0x31, 0x34, 0x35,
+ 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x39, 0x32, 0x33, 0x30, 0x31,
+ 0x33, 0x31, 0x35, 0x33, 0x5a, 0x30, 0x81, 0xbe, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30,
+ 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, 0x30,
+ 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, 0x20,
+ 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, 0x65,
+ 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45,
+ 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e,
+ 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
+ 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+ 0x01, 0x01, 0x00, 0xba, 0x84, 0xb6, 0x72, 0xdb, 0x9e, 0x0c, 0x6b, 0xe2,
+ 0x99, 0xe9, 0x30, 0x01, 0xa7, 0x76, 0xea, 0x32, 0xb8, 0x95, 0x41, 0x1a,
+ 0xc9, 0xda, 0x61, 0x4e, 0x58, 0x72, 0xcf, 0xfe, 0xf6, 0x82, 0x79, 0xbf,
+ 0x73, 0x61, 0x06, 0x0a, 0xa5, 0x27, 0xd8, 0xb3, 0x5f, 0xd3, 0x45, 0x4e,
+ 0x1c, 0x72, 0xd6, 0x4e, 0x32, 0xf2, 0x72, 0x8a, 0x0f, 0xf7, 0x83, 0x19,
+ 0xd0, 0x6a, 0x80, 0x80, 0x00, 0x45, 0x1e, 0xb0, 0xc7, 0xe7, 0x9a, 0xbf,
+ 0x12, 0x57, 0x27, 0x1c, 0xa3, 0x68, 0x2f, 0x0a, 0x87, 0xbd, 0x6a, 0x6b,
+ 0x0e, 0x5e, 0x65, 0xf3, 0x1c, 0x77, 0xd5, 0xd4, 0x85, 0x8d, 0x70, 0x21,
+ 0xb4, 0xb3, 0x32, 0xe7, 0x8b, 0xa2, 0xd5, 0x86, 0x39, 0x02, 0xb1, 0xb8,
+ 0xd2, 0x47, 0xce, 0xe4, 0xc9, 0x49, 0xc4, 0x3b, 0xa7, 0xde, 0xfb, 0x54,
+ 0x7d, 0x57, 0xbe, 0xf0, 0xe8, 0x6e, 0xc2, 0x79, 0xb2, 0x3a, 0x0b, 0x55,
+ 0xe2, 0x50, 0x98, 0x16, 0x32, 0x13, 0x5c, 0x2f, 0x78, 0x56, 0xc1, 0xc2,
+ 0x94, 0xb3, 0xf2, 0x5a, 0xe4, 0x27, 0x9a, 0x9f, 0x24, 0xd7, 0xc6, 0xec,
+ 0xd0, 0x9b, 0x25, 0x82, 0xe3, 0xcc, 0xc2, 0xc4, 0x45, 0xc5, 0x8c, 0x97,
+ 0x7a, 0x06, 0x6b, 0x2a, 0x11, 0x9f, 0xa9, 0x0a, 0x6e, 0x48, 0x3b, 0x6f,
+ 0xdb, 0xd4, 0x11, 0x19, 0x42, 0xf7, 0x8f, 0x07, 0xbf, 0xf5, 0x53, 0x5f,
+ 0x9c, 0x3e, 0xf4, 0x17, 0x2c, 0xe6, 0x69, 0xac, 0x4e, 0x32, 0x4c, 0x62,
+ 0x77, 0xea, 0xb7, 0xe8, 0xe5, 0xbb, 0x34, 0xbc, 0x19, 0x8b, 0xae, 0x9c,
+ 0x51, 0xe7, 0xb7, 0x7e, 0xb5, 0x53, 0xb1, 0x33, 0x22, 0xe5, 0x6d, 0xcf,
+ 0x70, 0x3c, 0x1a, 0xfa, 0xe2, 0x9b, 0x67, 0xb6, 0x83, 0xf4, 0x8d, 0xa5,
+ 0xaf, 0x62, 0x4c, 0x4d, 0xe0, 0x58, 0xac, 0x64, 0x34, 0x12, 0x03, 0xf8,
+ 0xb6, 0x8d, 0x94, 0x63, 0x24, 0xa4, 0x71, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x82, 0x01, 0x0f, 0x30, 0x82, 0x01, 0x0b, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
+ 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
+ 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x33, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25,
+ 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
+ 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
+ 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
+ 0x74, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a,
+ 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75,
+ 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x63,
+ 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d,
+ 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20,
+ 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0, 0x1e,
+ 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90, 0x12,
+ 0x66, 0xab, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+ 0x16, 0x80, 0x14, 0x68, 0x90, 0xe4, 0x67, 0xa4, 0xa6, 0x53, 0x80, 0xc7,
+ 0x86, 0x66, 0xa4, 0xf1, 0xf7, 0x4b, 0x43, 0xfb, 0x84, 0xbd, 0x6d, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x33, 0x83, 0xfc, 0x28,
+ 0x7a, 0x6f, 0x7d, 0xef, 0x9d, 0x55, 0xeb, 0xc5, 0x3e, 0x7a, 0x9d, 0x75,
+ 0xb3, 0xcc, 0xc3, 0x38, 0x36, 0xd9, 0x34, 0xa2, 0x28, 0x68, 0x18, 0xea,
+ 0x1e, 0x69, 0xd3, 0xbd, 0xe7, 0xd0, 0x77, 0xda, 0xb8, 0x00, 0x83, 0x4e,
+ 0x4a, 0xcf, 0x6f, 0xd1, 0xf1, 0xc1, 0x22, 0x3f, 0x74, 0xe4, 0xf7, 0x98,
+ 0x49, 0x9e, 0x9b, 0xb6, 0x9e, 0xe1, 0xdb, 0x98, 0x77, 0x2d, 0x56, 0x34,
+ 0xb1, 0xa8, 0x3c, 0xd9, 0xfd, 0xc0, 0xcd, 0xc7, 0xbf, 0x05, 0x03, 0xd4,
+ 0x02, 0xc5, 0xf1, 0xe5, 0xc6, 0xda, 0x08, 0xa5, 0x13, 0xc7, 0x62, 0x23,
+ 0x11, 0xd1, 0x61, 0x30, 0x1d, 0x60, 0x84, 0x45, 0xef, 0x79, 0xa8, 0xc6,
+ 0x26, 0x93, 0xa4, 0xb7, 0xcd, 0x34, 0xb8, 0x69, 0xc5, 0x13, 0xf6, 0x91,
+ 0xb3, 0xc9, 0x45, 0x73, 0x76, 0xb6, 0x92, 0xf6, 0x76, 0x0a, 0x5b, 0xe1,
+ 0x03, 0x47, 0xb7, 0xe9, 0x29, 0x4c, 0x91, 0x32, 0x23, 0x37, 0x4a, 0x9c,
+ 0x35, 0xd8, 0x78, 0xfd, 0x1d, 0x1f, 0xe4, 0x83, 0x89, 0x24, 0x80, 0xad,
+ 0xb7, 0xf9, 0xcf, 0xe4, 0x5d, 0xa5, 0xd4, 0x71, 0xc4, 0x85, 0x5b, 0x70,
+ 0x1f, 0xdb, 0x3f, 0x1c, 0x01, 0xeb, 0x1a, 0x45, 0x26, 0x31, 0x14, 0xcc,
+ 0x65, 0xbf, 0x67, 0xde, 0xca, 0xcc, 0x33, 0x65, 0xe5, 0x41, 0x91, 0xd7,
+ 0x37, 0xbe, 0x41, 0x1a, 0x96, 0x9d, 0xe6, 0x8a, 0x97, 0x9d, 0xa7, 0xce,
+ 0xac, 0x4e, 0x9a, 0x3d, 0xbd, 0x01, 0xa0, 0x6a, 0xd9, 0x4f, 0x22, 0x00,
+ 0x8b, 0x44, 0xd5, 0x69, 0x62, 0x7b, 0x2e, 0xeb, 0xcc, 0xba, 0xe7, 0x92,
+ 0x7d, 0x69, 0x67, 0x3d, 0xfc, 0xb8, 0x7c, 0xde, 0x41, 0x87, 0xd0, 0x69,
+ 0xea, 0xba, 0x0a, 0x18, 0x7a, 0x1a, 0x95, 0x43, 0xb3, 0x79, 0x71, 0x28,
+ 0x76, 0x6d, 0xa1, 0xfb, 0x57, 0x4a, 0xec, 0x4d, 0xc8, 0x0e, 0x10,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 7 (0x7)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
+ Validity
+ Not Before: May 3 07:00:00 2011 GMT
+ Not After : May 3 07:00:00 2031 GMT
+ Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., OU=http://certs.starfieldtech.com/repository/, CN=Starfield Secure Certificate Authority - G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e5:90:66:4b:ec:f9:46:71:a9:20:83:be:e9:6c:
+ bf:4a:c9:48:69:81:75:4e:6d:24:f6:cb:17:13:f8:
+ b0:71:59:84:7a:6b:2b:85:a4:34:b5:16:e5:cb:cc:
+ e9:41:70:2c:a4:2e:d6:fa:32:7d:e1:a8:de:94:10:
+ ac:31:c1:c0:d8:6a:ff:59:27:ab:76:d6:fc:0b:74:
+ 6b:b8:a7:ae:3f:c4:54:f4:b4:31:44:dd:93:56:8c:
+ a4:4c:5e:9b:89:cb:24:83:9b:e2:57:7d:b7:d8:12:
+ 1f:c9:85:6d:f4:d1:80:f1:50:9b:87:ae:d4:0b:10:
+ 05:fb:27:ba:28:6d:17:e9:0e:d6:4d:b9:39:55:06:
+ ff:0a:24:05:7e:2f:c6:1d:72:6c:d4:8b:29:8c:57:
+ 7d:da:d9:eb:66:1a:d3:4f:a7:df:7f:52:c4:30:c5:
+ a5:c9:0e:02:c5:53:bf:77:38:68:06:24:c3:66:c8:
+ 37:7e:30:1e:45:71:23:35:ff:90:d8:2a:9d:8d:e7:
+ b0:92:4d:3c:7f:2a:0a:93:dc:cd:16:46:65:f7:60:
+ 84:8b:76:4b:91:27:73:14:92:e0:ea:ee:8f:16:ea:
+ 8d:0e:3e:76:17:bf:7d:89:80:80:44:43:e7:2d:e0:
+ 43:09:75:da:36:e8:ad:db:89:3a:f5:5d:12:8e:23:
+ 04:83
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 25:45:81:68:50:26:38:3D:3B:2D:2C:BE:CD:6A:D9:B6:3D:B3:66:63
+ X509v3 Authority Key Identifier:
+ keyid:7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.starfieldtech.com/
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.starfieldtech.com/sfroot-g2.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://certs.starfieldtech.com/repository/
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 56:65:ca:fe:f3:3f:0a:a8:93:8b:18:c7:de:43:69:13:34:20:
+ be:4e:5f:78:a8:6b:9c:db:6a:4d:41:db:c1:13:ec:dc:31:00:
+ 22:5e:f7:00:9e:0c:e0:34:65:34:f9:b1:3a:4e:48:c8:12:81:
+ 88:5c:5b:3e:08:53:7a:f7:1a:64:df:b8:50:61:cc:53:51:40:
+ 29:4b:c2:f4:ae:3a:5f:e4:ca:ad:26:cc:4e:61:43:e5:fd:57:
+ a6:37:70:ce:43:2b:b0:94:c3:92:e9:e1:5f:aa:10:49:b7:69:
+ e4:e0:d0:1f:64:a4:2b:cd:1f:6f:a0:f8:84:24:18:ce:79:3d:
+ a9:91:bf:54:18:13:89:99:54:11:0d:55:c5:26:0b:79:4f:5a:
+ 1c:6e:f9:63:db:14:80:a4:07:ab:fa:b2:a5:b9:88:dd:91:fe:
+ 65:3b:a4:a3:79:be:89:4d:e1:d0:b0:f4:c8:17:0c:0a:96:14:
+ 7c:09:b7:6c:e1:c2:d8:55:d4:18:a0:aa:41:69:70:24:a3:b9:
+ ef:e9:5a:dc:3e:eb:94:4a:f0:b7:de:5f:0e:76:fa:fb:fb:69:
+ 03:45:40:50:ee:72:0c:a4:12:86:81:cd:13:d1:4e:c4:3c:ca:
+ 4e:0d:d2:26:f1:00:b7:b4:a6:a2:e1:6e:7a:81:fd:30:ac:7a:
+ 1f:c7:59:7b
+-----BEGIN CERTIFICATE-----
+MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw
+MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk
+dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg
+Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF
+pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE
+3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV
+Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+
+MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX
+v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+
+zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB
+BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo
+LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo
+LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF
+BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv
+MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN
+QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0
+rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO
+eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ
+sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ
+7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert39[] = {
+ 0x30, 0x82, 0x05, 0x00, 0x30, 0x82, 0x03, 0xe8, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8f, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72,
+ 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61,
+ 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54,
+ 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c,
+ 0x64, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30,
+ 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37,
+ 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30,
+ 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a,
+ 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07,
+ 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65,
+ 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53,
+ 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63,
+ 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72,
+ 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64,
+ 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70,
+ 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x31, 0x34, 0x30, 0x32,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, 0x53, 0x74, 0x61, 0x72, 0x66,
+ 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
+ 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+ 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe5,
+ 0x90, 0x66, 0x4b, 0xec, 0xf9, 0x46, 0x71, 0xa9, 0x20, 0x83, 0xbe, 0xe9,
+ 0x6c, 0xbf, 0x4a, 0xc9, 0x48, 0x69, 0x81, 0x75, 0x4e, 0x6d, 0x24, 0xf6,
+ 0xcb, 0x17, 0x13, 0xf8, 0xb0, 0x71, 0x59, 0x84, 0x7a, 0x6b, 0x2b, 0x85,
+ 0xa4, 0x34, 0xb5, 0x16, 0xe5, 0xcb, 0xcc, 0xe9, 0x41, 0x70, 0x2c, 0xa4,
+ 0x2e, 0xd6, 0xfa, 0x32, 0x7d, 0xe1, 0xa8, 0xde, 0x94, 0x10, 0xac, 0x31,
+ 0xc1, 0xc0, 0xd8, 0x6a, 0xff, 0x59, 0x27, 0xab, 0x76, 0xd6, 0xfc, 0x0b,
+ 0x74, 0x6b, 0xb8, 0xa7, 0xae, 0x3f, 0xc4, 0x54, 0xf4, 0xb4, 0x31, 0x44,
+ 0xdd, 0x93, 0x56, 0x8c, 0xa4, 0x4c, 0x5e, 0x9b, 0x89, 0xcb, 0x24, 0x83,
+ 0x9b, 0xe2, 0x57, 0x7d, 0xb7, 0xd8, 0x12, 0x1f, 0xc9, 0x85, 0x6d, 0xf4,
+ 0xd1, 0x80, 0xf1, 0x50, 0x9b, 0x87, 0xae, 0xd4, 0x0b, 0x10, 0x05, 0xfb,
+ 0x27, 0xba, 0x28, 0x6d, 0x17, 0xe9, 0x0e, 0xd6, 0x4d, 0xb9, 0x39, 0x55,
+ 0x06, 0xff, 0x0a, 0x24, 0x05, 0x7e, 0x2f, 0xc6, 0x1d, 0x72, 0x6c, 0xd4,
+ 0x8b, 0x29, 0x8c, 0x57, 0x7d, 0xda, 0xd9, 0xeb, 0x66, 0x1a, 0xd3, 0x4f,
+ 0xa7, 0xdf, 0x7f, 0x52, 0xc4, 0x30, 0xc5, 0xa5, 0xc9, 0x0e, 0x02, 0xc5,
+ 0x53, 0xbf, 0x77, 0x38, 0x68, 0x06, 0x24, 0xc3, 0x66, 0xc8, 0x37, 0x7e,
+ 0x30, 0x1e, 0x45, 0x71, 0x23, 0x35, 0xff, 0x90, 0xd8, 0x2a, 0x9d, 0x8d,
+ 0xe7, 0xb0, 0x92, 0x4d, 0x3c, 0x7f, 0x2a, 0x0a, 0x93, 0xdc, 0xcd, 0x16,
+ 0x46, 0x65, 0xf7, 0x60, 0x84, 0x8b, 0x76, 0x4b, 0x91, 0x27, 0x73, 0x14,
+ 0x92, 0xe0, 0xea, 0xee, 0x8f, 0x16, 0xea, 0x8d, 0x0e, 0x3e, 0x76, 0x17,
+ 0xbf, 0x7d, 0x89, 0x80, 0x80, 0x44, 0x43, 0xe7, 0x2d, 0xe0, 0x43, 0x09,
+ 0x75, 0xda, 0x36, 0xe8, 0xad, 0xdb, 0x89, 0x3a, 0xf5, 0x5d, 0x12, 0x8e,
+ 0x23, 0x04, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x2c,
+ 0x30, 0x82, 0x01, 0x28, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+ 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+ 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x25, 0x45, 0x81, 0x68, 0x50, 0x26, 0x38, 0x3d, 0x3b, 0x2d, 0x2c, 0xbe,
+ 0xcd, 0x6a, 0xd9, 0xb6, 0x3d, 0xb3, 0x66, 0x63, 0x30, 0x1f, 0x06, 0x03,
+ 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7c, 0x0c, 0x32,
+ 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4, 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1,
+ 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1e, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73,
+ 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0, 0x2e, 0xa0, 0x2c, 0x86, 0x2a,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73,
+ 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f, 0x6f, 0x74, 0x2d,
+ 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d,
+ 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20,
+ 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+ 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66,
+ 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x56, 0x65, 0xca, 0xfe,
+ 0xf3, 0x3f, 0x0a, 0xa8, 0x93, 0x8b, 0x18, 0xc7, 0xde, 0x43, 0x69, 0x13,
+ 0x34, 0x20, 0xbe, 0x4e, 0x5f, 0x78, 0xa8, 0x6b, 0x9c, 0xdb, 0x6a, 0x4d,
+ 0x41, 0xdb, 0xc1, 0x13, 0xec, 0xdc, 0x31, 0x00, 0x22, 0x5e, 0xf7, 0x00,
+ 0x9e, 0x0c, 0xe0, 0x34, 0x65, 0x34, 0xf9, 0xb1, 0x3a, 0x4e, 0x48, 0xc8,
+ 0x12, 0x81, 0x88, 0x5c, 0x5b, 0x3e, 0x08, 0x53, 0x7a, 0xf7, 0x1a, 0x64,
+ 0xdf, 0xb8, 0x50, 0x61, 0xcc, 0x53, 0x51, 0x40, 0x29, 0x4b, 0xc2, 0xf4,
+ 0xae, 0x3a, 0x5f, 0xe4, 0xca, 0xad, 0x26, 0xcc, 0x4e, 0x61, 0x43, 0xe5,
+ 0xfd, 0x57, 0xa6, 0x37, 0x70, 0xce, 0x43, 0x2b, 0xb0, 0x94, 0xc3, 0x92,
+ 0xe9, 0xe1, 0x5f, 0xaa, 0x10, 0x49, 0xb7, 0x69, 0xe4, 0xe0, 0xd0, 0x1f,
+ 0x64, 0xa4, 0x2b, 0xcd, 0x1f, 0x6f, 0xa0, 0xf8, 0x84, 0x24, 0x18, 0xce,
+ 0x79, 0x3d, 0xa9, 0x91, 0xbf, 0x54, 0x18, 0x13, 0x89, 0x99, 0x54, 0x11,
+ 0x0d, 0x55, 0xc5, 0x26, 0x0b, 0x79, 0x4f, 0x5a, 0x1c, 0x6e, 0xf9, 0x63,
+ 0xdb, 0x14, 0x80, 0xa4, 0x07, 0xab, 0xfa, 0xb2, 0xa5, 0xb9, 0x88, 0xdd,
+ 0x91, 0xfe, 0x65, 0x3b, 0xa4, 0xa3, 0x79, 0xbe, 0x89, 0x4d, 0xe1, 0xd0,
+ 0xb0, 0xf4, 0xc8, 0x17, 0x0c, 0x0a, 0x96, 0x14, 0x7c, 0x09, 0xb7, 0x6c,
+ 0xe1, 0xc2, 0xd8, 0x55, 0xd4, 0x18, 0xa0, 0xaa, 0x41, 0x69, 0x70, 0x24,
+ 0xa3, 0xb9, 0xef, 0xe9, 0x5a, 0xdc, 0x3e, 0xeb, 0x94, 0x4a, 0xf0, 0xb7,
+ 0xde, 0x5f, 0x0e, 0x76, 0xfa, 0xfb, 0xfb, 0x69, 0x03, 0x45, 0x40, 0x50,
+ 0xee, 0x72, 0x0c, 0xa4, 0x12, 0x86, 0x81, 0xcd, 0x13, 0xd1, 0x4e, 0xc4,
+ 0x3c, 0xca, 0x4e, 0x0d, 0xd2, 0x26, 0xf1, 0x00, 0xb7, 0xb4, 0xa6, 0xa2,
+ 0xe1, 0x6e, 0x7a, 0x81, 0xfd, 0x30, 0xac, 0x7a, 0x1f, 0xc7, 0x59, 0x7b,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1372807406 (0x51d360ee)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
+ Validity
+ Not Before: Oct 22 17:05:14 2014 GMT
+ Not After : Oct 23 07:33:22 2024 GMT
+ Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:da:3f:96:d0:4d:b9:2f:44:e7:db:39:5e:9b:50:
+ ee:5c:a5:61:da:41:67:53:09:aa:00:9a:8e:57:7f:
+ 29:6b:db:c7:e1:21:24:aa:3a:d0:8d:47:23:d2:ed:
+ 72:16:f0:91:21:d2:5d:b7:b8:4b:a8:83:8f:b7:91:
+ 32:68:cf:ce:25:93:2c:b2:7d:97:c8:fe:c1:b4:17:
+ ba:09:9e:03:90:93:7b:7c:49:83:22:68:8a:9b:de:
+ 47:c3:31:98:7a:2e:7d:40:0b:d2:ef:3e:d3:b2:8c:
+ aa:8f:48:a9:ff:00:e8:29:58:06:f7:b6:93:5a:94:
+ 73:26:26:ad:58:0e:e5:42:b8:d5:ea:73:79:64:68:
+ 53:25:b8:84:cf:94:7a:ae:06:45:0c:a3:6b:4d:d0:
+ c6:be:ea:18:a4:36:f0:92:b2:ba:1c:88:8f:3a:52:
+ 7f:f7:5e:6d:83:1c:9d:f0:1f:e5:c3:d6:dd:a5:78:
+ 92:3d:b0:6d:2c:ea:c9:cf:94:41:19:71:44:68:ba:
+ 47:3c:04:e9:5d:ba:3e:f0:35:f7:15:b6:9e:f2:2e:
+ 15:1e:3f:47:c8:c8:38:a7:73:45:5d:4d:b0:3b:b1:
+ 8e:17:29:37:ea:dd:05:01:22:bb:94:36:2a:8d:5b:
+ 35:fe:53:19:2f:08:46:c1:2a:b3:1a:62:1d:4e:2b:
+ d9:1b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints:
+ CA:TRUE, pathlen:0
+ Authority Information Access:
+ OCSP - URI:http://ocsp.entrust.net
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.entrust.net/g2ca.crl
+
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.entrust.net/rpa
+
+ X509v3 Subject Key Identifier:
+ 82:A2:70:74:DD:BC:53:3F:CF:7B:D4:F7:CD:7F:A7:60:C6:0A:4C:BF
+ X509v3 Authority Key Identifier:
+ keyid:6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 3f:1c:1a:5b:ff:40:22:1d:8f:35:0c:2d:aa:99:27:ab:c0:11:
+ 32:70:d7:36:28:69:a5:8d:b1:27:99:42:be:c4:93:eb:48:57:
+ 43:71:23:c4:e5:4e:ad:ae:43:6f:92:76:c5:19:ef:ca:bc:6f:
+ 42:4c:16:9a:86:a9:04:38:c7:65:f0:f5:0c:e0:4a:df:a2:fa:
+ ce:1a:11:a8:9c:69:2f:1b:df:ea:e2:32:f3:ce:4c:bc:46:0c:
+ c0:89:80:d1:87:6b:a2:cf:6b:d4:7f:fd:f5:60:52:67:57:a0:
+ 6d:d1:64:41:14:6d:34:62:ed:06:6c:24:f2:06:bc:28:02:af:
+ 03:2d:c2:33:05:fb:cb:aa:16:e8:65:10:43:f5:69:5c:e3:81:
+ 58:99:cd:6b:d3:b8:c7:7b:19:55:c9:40:ce:79:55:b8:73:89:
+ e9:5c:40:66:43:12:7f:07:b8:65:56:d5:8d:c3:a7:f5:b1:b6:
+ 65:9e:c0:83:36:7f:16:45:3c:74:4b:93:8a:3c:f1:2b:f5:35:
+ 70:73:7b:e7:82:04:b1:18:98:0e:d4:9c:6f:1a:fc:fc:a7:33:
+ a5:bb:bb:18:f3:6b:7a:5d:32:87:f7:6d:25:e4:e2:76:86:21:
+ 1e:11:46:cd:76:0e:6f:4f:a4:21:71:0a:84:a7:2d:36:a9:48:
+ 22:51:7e:82
+-----BEGIN CERTIFICATE-----
+MIIFAzCCA+ugAwIBAgIEUdNg7jANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
+cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
+IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
+dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMTQxMDIyMTcw
+NTE0WhcNMjQxMDIzMDczMzIyWjCBujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
+dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
+dGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
+aG9yaXplZCB1c2Ugb25seTEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eSAtIEwxSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ANo/ltBNuS9E59s5XptQ7lylYdpBZ1MJqgCajld/KWvbx+EhJKo60I1HI9Ltchbw
+kSHSXbe4S6iDj7eRMmjPziWTLLJ9l8j+wbQXugmeA5CTe3xJgyJoipveR8MxmHou
+fUAL0u8+07KMqo9Iqf8A6ClYBve2k1qUcyYmrVgO5UK41epzeWRoUyW4hM+Ueq4G
+RQyja03Qxr7qGKQ28JKyuhyIjzpSf/debYMcnfAf5cPW3aV4kj2wbSzqyc+UQRlx
+RGi6RzwE6V26PvA19xW2nvIuFR4/R8jIOKdzRV1NsDuxjhcpN+rdBQEiu5Q2Ko1b
+Nf5TGS8IRsEqsxpiHU4r2RsCAwEAAaOCAQkwggEFMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMECDAGAQH/AgEAMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0
+cDovL29jc3AuZW50cnVzdC5uZXQwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL2Ny
+bC5lbnRydXN0Lm5ldC9nMmNhLmNybDA7BgNVHSAENDAyMDAGBFUdIAAwKDAmBggr
+BgEFBQcCARYaaHR0cDovL3d3dy5lbnRydXN0Lm5ldC9ycGEwHQYDVR0OBBYEFIKi
+cHTdvFM/z3vU981/p2DGCky/MB8GA1UdIwQYMBaAFGpyJnrQHu995ztpUdRsjZ+Q
+EmarMA0GCSqGSIb3DQEBCwUAA4IBAQA/HBpb/0AiHY81DC2qmSerwBEycNc2KGml
+jbEnmUK+xJPrSFdDcSPE5U6trkNvknbFGe/KvG9CTBaahqkEOMdl8PUM4ErfovrO
+GhGonGkvG9/q4jLzzky8RgzAiYDRh2uiz2vUf/31YFJnV6Bt0WRBFG00Yu0GbCTy
+BrwoAq8DLcIzBfvLqhboZRBD9Wlc44FYmc1r07jHexlVyUDOeVW4c4npXEBmQxJ/
+B7hlVtWNw6f1sbZlnsCDNn8WRTx0S5OKPPEr9TVwc3vnggSxGJgO1JxvGvz8pzOl
+u7sY82t6XTKH920l5OJ2hiEeEUbNdg5vT6QhcQqEpy02qUgiUX6C
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert40[] = {
+ 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x51, 0xd3, 0x60, 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xbe, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x1f, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67,
+ 0x61, 0x6c, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37,
+ 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32,
+ 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c,
+ 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20,
+ 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75,
+ 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30,
+ 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, 0x32, 0x32, 0x31, 0x37, 0x30,
+ 0x35, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x31, 0x30, 0x32, 0x33,
+ 0x30, 0x37, 0x33, 0x33, 0x32, 0x32, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e,
+ 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+ 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65,
+ 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73,
+ 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d,
+ 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x31, 0x32,
+ 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20,
+ 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43,
+ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d,
+ 0x20, 0x4c, 0x31, 0x4b, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0xda, 0x3f, 0x96, 0xd0, 0x4d, 0xb9, 0x2f, 0x44, 0xe7, 0xdb, 0x39,
+ 0x5e, 0x9b, 0x50, 0xee, 0x5c, 0xa5, 0x61, 0xda, 0x41, 0x67, 0x53, 0x09,
+ 0xaa, 0x00, 0x9a, 0x8e, 0x57, 0x7f, 0x29, 0x6b, 0xdb, 0xc7, 0xe1, 0x21,
+ 0x24, 0xaa, 0x3a, 0xd0, 0x8d, 0x47, 0x23, 0xd2, 0xed, 0x72, 0x16, 0xf0,
+ 0x91, 0x21, 0xd2, 0x5d, 0xb7, 0xb8, 0x4b, 0xa8, 0x83, 0x8f, 0xb7, 0x91,
+ 0x32, 0x68, 0xcf, 0xce, 0x25, 0x93, 0x2c, 0xb2, 0x7d, 0x97, 0xc8, 0xfe,
+ 0xc1, 0xb4, 0x17, 0xba, 0x09, 0x9e, 0x03, 0x90, 0x93, 0x7b, 0x7c, 0x49,
+ 0x83, 0x22, 0x68, 0x8a, 0x9b, 0xde, 0x47, 0xc3, 0x31, 0x98, 0x7a, 0x2e,
+ 0x7d, 0x40, 0x0b, 0xd2, 0xef, 0x3e, 0xd3, 0xb2, 0x8c, 0xaa, 0x8f, 0x48,
+ 0xa9, 0xff, 0x00, 0xe8, 0x29, 0x58, 0x06, 0xf7, 0xb6, 0x93, 0x5a, 0x94,
+ 0x73, 0x26, 0x26, 0xad, 0x58, 0x0e, 0xe5, 0x42, 0xb8, 0xd5, 0xea, 0x73,
+ 0x79, 0x64, 0x68, 0x53, 0x25, 0xb8, 0x84, 0xcf, 0x94, 0x7a, 0xae, 0x06,
+ 0x45, 0x0c, 0xa3, 0x6b, 0x4d, 0xd0, 0xc6, 0xbe, 0xea, 0x18, 0xa4, 0x36,
+ 0xf0, 0x92, 0xb2, 0xba, 0x1c, 0x88, 0x8f, 0x3a, 0x52, 0x7f, 0xf7, 0x5e,
+ 0x6d, 0x83, 0x1c, 0x9d, 0xf0, 0x1f, 0xe5, 0xc3, 0xd6, 0xdd, 0xa5, 0x78,
+ 0x92, 0x3d, 0xb0, 0x6d, 0x2c, 0xea, 0xc9, 0xcf, 0x94, 0x41, 0x19, 0x71,
+ 0x44, 0x68, 0xba, 0x47, 0x3c, 0x04, 0xe9, 0x5d, 0xba, 0x3e, 0xf0, 0x35,
+ 0xf7, 0x15, 0xb6, 0x9e, 0xf2, 0x2e, 0x15, 0x1e, 0x3f, 0x47, 0xc8, 0xc8,
+ 0x38, 0xa7, 0x73, 0x45, 0x5d, 0x4d, 0xb0, 0x3b, 0xb1, 0x8e, 0x17, 0x29,
+ 0x37, 0xea, 0xdd, 0x05, 0x01, 0x22, 0xbb, 0x94, 0x36, 0x2a, 0x8d, 0x5b,
+ 0x35, 0xfe, 0x53, 0x19, 0x2f, 0x08, 0x46, 0xc1, 0x2a, 0xb3, 0x1a, 0x62,
+ 0x1d, 0x4e, 0x2b, 0xd9, 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+ 0x01, 0x09, 0x30, 0x82, 0x01, 0x05, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f,
+ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+ 0x02, 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x65, 0x6e, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x30, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0,
+ 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
+ 0x74, 0x2f, 0x67, 0x32, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06,
+ 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72,
+ 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30,
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x82, 0xa2,
+ 0x70, 0x74, 0xdd, 0xbc, 0x53, 0x3f, 0xcf, 0x7b, 0xd4, 0xf7, 0xcd, 0x7f,
+ 0xa7, 0x60, 0xc6, 0x0a, 0x4c, 0xbf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0,
+ 0x1e, 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90,
+ 0x12, 0x66, 0xab, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3f,
+ 0x1c, 0x1a, 0x5b, 0xff, 0x40, 0x22, 0x1d, 0x8f, 0x35, 0x0c, 0x2d, 0xaa,
+ 0x99, 0x27, 0xab, 0xc0, 0x11, 0x32, 0x70, 0xd7, 0x36, 0x28, 0x69, 0xa5,
+ 0x8d, 0xb1, 0x27, 0x99, 0x42, 0xbe, 0xc4, 0x93, 0xeb, 0x48, 0x57, 0x43,
+ 0x71, 0x23, 0xc4, 0xe5, 0x4e, 0xad, 0xae, 0x43, 0x6f, 0x92, 0x76, 0xc5,
+ 0x19, 0xef, 0xca, 0xbc, 0x6f, 0x42, 0x4c, 0x16, 0x9a, 0x86, 0xa9, 0x04,
+ 0x38, 0xc7, 0x65, 0xf0, 0xf5, 0x0c, 0xe0, 0x4a, 0xdf, 0xa2, 0xfa, 0xce,
+ 0x1a, 0x11, 0xa8, 0x9c, 0x69, 0x2f, 0x1b, 0xdf, 0xea, 0xe2, 0x32, 0xf3,
+ 0xce, 0x4c, 0xbc, 0x46, 0x0c, 0xc0, 0x89, 0x80, 0xd1, 0x87, 0x6b, 0xa2,
+ 0xcf, 0x6b, 0xd4, 0x7f, 0xfd, 0xf5, 0x60, 0x52, 0x67, 0x57, 0xa0, 0x6d,
+ 0xd1, 0x64, 0x41, 0x14, 0x6d, 0x34, 0x62, 0xed, 0x06, 0x6c, 0x24, 0xf2,
+ 0x06, 0xbc, 0x28, 0x02, 0xaf, 0x03, 0x2d, 0xc2, 0x33, 0x05, 0xfb, 0xcb,
+ 0xaa, 0x16, 0xe8, 0x65, 0x10, 0x43, 0xf5, 0x69, 0x5c, 0xe3, 0x81, 0x58,
+ 0x99, 0xcd, 0x6b, 0xd3, 0xb8, 0xc7, 0x7b, 0x19, 0x55, 0xc9, 0x40, 0xce,
+ 0x79, 0x55, 0xb8, 0x73, 0x89, 0xe9, 0x5c, 0x40, 0x66, 0x43, 0x12, 0x7f,
+ 0x07, 0xb8, 0x65, 0x56, 0xd5, 0x8d, 0xc3, 0xa7, 0xf5, 0xb1, 0xb6, 0x65,
+ 0x9e, 0xc0, 0x83, 0x36, 0x7f, 0x16, 0x45, 0x3c, 0x74, 0x4b, 0x93, 0x8a,
+ 0x3c, 0xf1, 0x2b, 0xf5, 0x35, 0x70, 0x73, 0x7b, 0xe7, 0x82, 0x04, 0xb1,
+ 0x18, 0x98, 0x0e, 0xd4, 0x9c, 0x6f, 0x1a, 0xfc, 0xfc, 0xa7, 0x33, 0xa5,
+ 0xbb, 0xbb, 0x18, 0xf3, 0x6b, 0x7a, 0x5d, 0x32, 0x87, 0xf7, 0x6d, 0x25,
+ 0xe4, 0xe2, 0x76, 0x86, 0x21, 0x1e, 0x11, 0x46, 0xcd, 0x76, 0x0e, 0x6f,
+ 0x4f, 0xa4, 0x21, 0x71, 0x0a, 0x84, 0xa7, 0x2d, 0x36, 0xa9, 0x48, 0x22,
+ 0x51, 0x7e, 0x82,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 120038507 (0x727a46b)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
+ Validity
+ Not Before: Apr 2 14:36:10 2014 GMT
+ Not After : Apr 2 14:35:52 2021 GMT
+ Subject: C=NL, L=Amsterdam, O=Verizon Enterprise Solutions, OU=Cybertrust, CN=Verizon Akamai SureServer CA G14-SHA2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:dd:6e:9e:02:69:02:b5:a3:99:2e:08:64:32:6a:
+ 59:f3:c6:9e:a6:20:07:d2:48:d1:a8:93:c7:ea:47:
+ 8f:83:39:40:d7:20:5d:8d:9a:ba:ab:d8:70:ec:9d:
+ 88:d1:bd:62:f6:db:ec:9d:5e:35:01:76:03:23:e5:
+ 6f:d2:af:46:35:59:5a:5c:d1:a8:23:c1:eb:e9:20:
+ d4:49:d6:3f:00:d8:a8:22:de:43:79:81:ac:e9:a4:
+ 92:f5:77:70:05:1e:5c:b6:a0:f7:90:a4:cd:ab:28:
+ 2c:90:c2:e7:0f:c3:af:1c:47:59:d5:84:2e:df:26:
+ 07:45:23:5a:c6:e8:90:c8:85:4b:8c:16:1e:60:f9:
+ 01:13:f1:14:1f:e6:e8:14:ed:c5:d2:6f:63:28:6e:
+ 72:8c:49:ae:08:72:c7:93:95:b4:0b:0c:ae:8f:9a:
+ 67:84:f5:57:1b:db:81:d7:17:9d:41:11:43:19:bd:
+ 6d:4a:85:ed:8f:70:25:ab:66:ab:f6:fa:6d:1c:3c:
+ ab:ed:17:bd:56:84:e1:db:75:33:b2:28:4b:99:8e:
+ f9:4b:82:33:50:9f:92:53:ed:fa:ad:0f:95:9c:a3:
+ f2:cb:60:f0:77:1d:c9:01:8b:5f:2d:86:be:bf:36:
+ b8:24:96:13:7c:c1:86:5a:6c:c1:48:2a:7f:3e:93:
+ 60:c5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:2
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.6334.1.50
+ CPS: https://secure.omniroot.com/repository
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.omniroot.com/baltimoreroot
+ CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.crt
+ CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.der
+
+ X509v3 Key Usage: critical
+ Digital Signature, Non Repudiation, Certificate Sign, CRL Sign
+ X509v3 Authority Key Identifier:
+ keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
+
+ X509v3 Subject Key Identifier:
+ F8:BD:FA:AF:73:77:C6:C7:1B:F9:4B:4D:11:A7:D1:33:AF:AF:72:11
+ Signature Algorithm: sha256WithRSAEncryption
+ 80:d9:7a:ed:72:05:37:8f:61:aa:73:7c:9a:6a:fc:fe:01:e2:
+ 19:81:70:07:25:32:b0:f0:6f:3b:c7:6a:28:3d:e4:51:87:e6:
+ 7e:82:ec:ae:48:a7:b1:77:38:c2:d6:56:af:8f:f2:01:fc:65:
+ 65:10:09:f7:74:29:b5:0e:92:ee:90:98:d1:88:a2:65:b7:cd:
+ 9c:0e:a7:86:98:28:bc:ae:15:83:b6:1a:d7:1d:ec:19:da:7a:
+ 8e:40:f9:99:15:d5:7d:a5:ba:ab:fd:26:98:6e:9c:41:3b:b6:
+ 81:18:ec:70:48:d7:6e:7f:a6:e1:77:25:d6:dd:62:e8:52:f3:
+ 8c:16:39:67:e2:22:0d:77:2e:fb:11:6c:e4:dd:38:b4:27:5f:
+ 03:a8:3d:44:e2:f2:84:4b:84:fd:56:a6:9e:4d:7b:a2:16:4f:
+ 07:f5:34:24:72:a5:a2:fa:16:66:2a:a4:4a:0e:c8:0d:27:44:
+ 9c:77:d4:12:10:87:d2:00:2c:7a:bb:8e:88:22:91:15:be:a2:
+ 59:ca:34:e0:1c:61:94:86:20:33:cd:e7:4c:5d:3b:92:3e:cb:
+ d6:2d:ea:54:fa:fb:af:54:f5:a8:c5:0b:ca:8b:87:00:e6:9f:
+ e6:95:bf:b7:c4:a3:59:f5:16:6c:5f:3e:69:55:80:39:f6:75:
+ 50:14:3e:32
+-----BEGIN CERTIFICATE-----
+MIIFHzCCBAegAwIBAgIEByekazANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDQwMjE0MzYxMFoX
+DTIxMDQwMjE0MzU1MlowgY0xCzAJBgNVBAYTAk5MMRIwEAYDVQQHEwlBbXN0ZXJk
+YW0xJTAjBgNVBAoTHFZlcml6b24gRW50ZXJwcmlzZSBTb2x1dGlvbnMxEzARBgNV
+BAsTCkN5YmVydHJ1c3QxLjAsBgNVBAMTJVZlcml6b24gQWthbWFpIFN1cmVTZXJ2
+ZXIgQ0EgRzE0LVNIQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDd
+bp4CaQK1o5kuCGQyalnzxp6mIAfSSNGok8fqR4+DOUDXIF2Nmrqr2HDsnYjRvWL2
+2+ydXjUBdgMj5W/Sr0Y1WVpc0agjwevpINRJ1j8A2Kgi3kN5gazppJL1d3AFHly2
+oPeQpM2rKCyQwucPw68cR1nVhC7fJgdFI1rG6JDIhUuMFh5g+QET8RQf5ugU7cXS
+b2MobnKMSa4IcseTlbQLDK6PmmeE9Vcb24HXF51BEUMZvW1Khe2PcCWrZqv2+m0c
+PKvtF71WhOHbdTOyKEuZjvlLgjNQn5JT7fqtD5Wco/LLYPB3HckBi18thr6/Nrgk
+lhN8wYZabMFIKn8+k2DFAgMBAAGjggG3MIIBszASBgNVHRMBAf8ECDAGAQH/AgEC
+MEwGA1UdIARFMEMwQQYJKwYBBAGxPgEyMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v
+c2VjdXJlLm9tbmlyb290LmNvbS9yZXBvc2l0b3J5MIG6BggrBgEFBQcBAQSBrTCB
+qjAyBggrBgEFBQcwAYYmaHR0cDovL29jc3Aub21uaXJvb3QuY29tL2JhbHRpbW9y
+ZXJvb3QwOQYIKwYBBQUHMAKGLWh0dHBzOi8vY2FjZXJ0Lm9tbmlyb290LmNvbS9i
+YWx0aW1vcmVyb290LmNydDA5BggrBgEFBQcwAoYtaHR0cHM6Ly9jYWNlcnQub21u
+aXJvb3QuY29tL2JhbHRpbW9yZXJvb3QuZGVyMA4GA1UdDwEB/wQEAwIBxjAfBgNV
+HSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DBCBgNVHR8EOzA5MDegNaAzhjFo
+dHRwOi8vY2RwMS5wdWJsaWMtdHJ1c3QuY29tL0NSTC9PbW5pcm9vdDIwMjUuY3Js
+MB0GA1UdDgQWBBT4vfqvc3fGxxv5S00Rp9Ezr69yETANBgkqhkiG9w0BAQsFAAOC
+AQEAgNl67XIFN49hqnN8mmr8/gHiGYFwByUysPBvO8dqKD3kUYfmfoLsrkinsXc4
+wtZWr4/yAfxlZRAJ93QptQ6S7pCY0YiiZbfNnA6nhpgovK4Vg7Ya1x3sGdp6jkD5
+mRXVfaW6q/0mmG6cQTu2gRjscEjXbn+m4Xcl1t1i6FLzjBY5Z+IiDXcu+xFs5N04
+tCdfA6g9ROLyhEuE/Vamnk17ohZPB/U0JHKlovoWZiqkSg7IDSdEnHfUEhCH0gAs
+eruOiCKRFb6iWco04BxhlIYgM83nTF07kj7L1i3qVPr7r1T1qMULyouHAOaf5pW/
+t8SjWfUWbF8+aVWAOfZ1UBQ+Mg==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert41[] = {
+ 0x30, 0x82, 0x05, 0x1f, 0x30, 0x82, 0x04, 0x07, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x07, 0x27, 0xa4, 0x6b, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
+ 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
+ 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
+ 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
+ 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
+ 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34,
+ 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x36, 0x31, 0x30, 0x5a, 0x17,
+ 0x0d, 0x32, 0x31, 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x35, 0x35,
+ 0x32, 0x5a, 0x30, 0x81, 0x8d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
+ 0x55, 0x04, 0x07, 0x13, 0x09, 0x41, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64,
+ 0x61, 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x1c, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x74,
+ 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x53, 0x6f, 0x6c, 0x75,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75,
+ 0x73, 0x74, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x25, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x41, 0x6b, 0x61,
+ 0x6d, 0x61, 0x69, 0x20, 0x53, 0x75, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76,
+ 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x47, 0x31, 0x34, 0x2d, 0x53, 0x48,
+ 0x41, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdd,
+ 0x6e, 0x9e, 0x02, 0x69, 0x02, 0xb5, 0xa3, 0x99, 0x2e, 0x08, 0x64, 0x32,
+ 0x6a, 0x59, 0xf3, 0xc6, 0x9e, 0xa6, 0x20, 0x07, 0xd2, 0x48, 0xd1, 0xa8,
+ 0x93, 0xc7, 0xea, 0x47, 0x8f, 0x83, 0x39, 0x40, 0xd7, 0x20, 0x5d, 0x8d,
+ 0x9a, 0xba, 0xab, 0xd8, 0x70, 0xec, 0x9d, 0x88, 0xd1, 0xbd, 0x62, 0xf6,
+ 0xdb, 0xec, 0x9d, 0x5e, 0x35, 0x01, 0x76, 0x03, 0x23, 0xe5, 0x6f, 0xd2,
+ 0xaf, 0x46, 0x35, 0x59, 0x5a, 0x5c, 0xd1, 0xa8, 0x23, 0xc1, 0xeb, 0xe9,
+ 0x20, 0xd4, 0x49, 0xd6, 0x3f, 0x00, 0xd8, 0xa8, 0x22, 0xde, 0x43, 0x79,
+ 0x81, 0xac, 0xe9, 0xa4, 0x92, 0xf5, 0x77, 0x70, 0x05, 0x1e, 0x5c, 0xb6,
+ 0xa0, 0xf7, 0x90, 0xa4, 0xcd, 0xab, 0x28, 0x2c, 0x90, 0xc2, 0xe7, 0x0f,
+ 0xc3, 0xaf, 0x1c, 0x47, 0x59, 0xd5, 0x84, 0x2e, 0xdf, 0x26, 0x07, 0x45,
+ 0x23, 0x5a, 0xc6, 0xe8, 0x90, 0xc8, 0x85, 0x4b, 0x8c, 0x16, 0x1e, 0x60,
+ 0xf9, 0x01, 0x13, 0xf1, 0x14, 0x1f, 0xe6, 0xe8, 0x14, 0xed, 0xc5, 0xd2,
+ 0x6f, 0x63, 0x28, 0x6e, 0x72, 0x8c, 0x49, 0xae, 0x08, 0x72, 0xc7, 0x93,
+ 0x95, 0xb4, 0x0b, 0x0c, 0xae, 0x8f, 0x9a, 0x67, 0x84, 0xf5, 0x57, 0x1b,
+ 0xdb, 0x81, 0xd7, 0x17, 0x9d, 0x41, 0x11, 0x43, 0x19, 0xbd, 0x6d, 0x4a,
+ 0x85, 0xed, 0x8f, 0x70, 0x25, 0xab, 0x66, 0xab, 0xf6, 0xfa, 0x6d, 0x1c,
+ 0x3c, 0xab, 0xed, 0x17, 0xbd, 0x56, 0x84, 0xe1, 0xdb, 0x75, 0x33, 0xb2,
+ 0x28, 0x4b, 0x99, 0x8e, 0xf9, 0x4b, 0x82, 0x33, 0x50, 0x9f, 0x92, 0x53,
+ 0xed, 0xfa, 0xad, 0x0f, 0x95, 0x9c, 0xa3, 0xf2, 0xcb, 0x60, 0xf0, 0x77,
+ 0x1d, 0xc9, 0x01, 0x8b, 0x5f, 0x2d, 0x86, 0xbe, 0xbf, 0x36, 0xb8, 0x24,
+ 0x96, 0x13, 0x7c, 0xc1, 0x86, 0x5a, 0x6c, 0xc1, 0x48, 0x2a, 0x7f, 0x3e,
+ 0x93, 0x60, 0xc5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xb7,
+ 0x30, 0x82, 0x01, 0xb3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+ 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02,
+ 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30,
+ 0x41, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x32,
+ 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+ 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72,
+ 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f,
+ 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x81, 0xba, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xad, 0x30, 0x81,
+ 0xaa, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
+ 0x01, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
+ 0x73, 0x70, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72,
+ 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73,
+ 0x3a, 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d,
+ 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62,
+ 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74,
+ 0x2e, 0x63, 0x72, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+ 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d, 0x6e,
+ 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61,
+ 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x2e,
+ 0x64, 0x65, 0x72, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0xc6, 0x30, 0x1f, 0x06, 0x03, 0x55,
+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30,
+ 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a,
+ 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+ 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70,
+ 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69,
+ 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c,
+ 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf8,
+ 0xbd, 0xfa, 0xaf, 0x73, 0x77, 0xc6, 0xc7, 0x1b, 0xf9, 0x4b, 0x4d, 0x11,
+ 0xa7, 0xd1, 0x33, 0xaf, 0xaf, 0x72, 0x11, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x01, 0x00, 0x80, 0xd9, 0x7a, 0xed, 0x72, 0x05, 0x37, 0x8f, 0x61,
+ 0xaa, 0x73, 0x7c, 0x9a, 0x6a, 0xfc, 0xfe, 0x01, 0xe2, 0x19, 0x81, 0x70,
+ 0x07, 0x25, 0x32, 0xb0, 0xf0, 0x6f, 0x3b, 0xc7, 0x6a, 0x28, 0x3d, 0xe4,
+ 0x51, 0x87, 0xe6, 0x7e, 0x82, 0xec, 0xae, 0x48, 0xa7, 0xb1, 0x77, 0x38,
+ 0xc2, 0xd6, 0x56, 0xaf, 0x8f, 0xf2, 0x01, 0xfc, 0x65, 0x65, 0x10, 0x09,
+ 0xf7, 0x74, 0x29, 0xb5, 0x0e, 0x92, 0xee, 0x90, 0x98, 0xd1, 0x88, 0xa2,
+ 0x65, 0xb7, 0xcd, 0x9c, 0x0e, 0xa7, 0x86, 0x98, 0x28, 0xbc, 0xae, 0x15,
+ 0x83, 0xb6, 0x1a, 0xd7, 0x1d, 0xec, 0x19, 0xda, 0x7a, 0x8e, 0x40, 0xf9,
+ 0x99, 0x15, 0xd5, 0x7d, 0xa5, 0xba, 0xab, 0xfd, 0x26, 0x98, 0x6e, 0x9c,
+ 0x41, 0x3b, 0xb6, 0x81, 0x18, 0xec, 0x70, 0x48, 0xd7, 0x6e, 0x7f, 0xa6,
+ 0xe1, 0x77, 0x25, 0xd6, 0xdd, 0x62, 0xe8, 0x52, 0xf3, 0x8c, 0x16, 0x39,
+ 0x67, 0xe2, 0x22, 0x0d, 0x77, 0x2e, 0xfb, 0x11, 0x6c, 0xe4, 0xdd, 0x38,
+ 0xb4, 0x27, 0x5f, 0x03, 0xa8, 0x3d, 0x44, 0xe2, 0xf2, 0x84, 0x4b, 0x84,
+ 0xfd, 0x56, 0xa6, 0x9e, 0x4d, 0x7b, 0xa2, 0x16, 0x4f, 0x07, 0xf5, 0x34,
+ 0x24, 0x72, 0xa5, 0xa2, 0xfa, 0x16, 0x66, 0x2a, 0xa4, 0x4a, 0x0e, 0xc8,
+ 0x0d, 0x27, 0x44, 0x9c, 0x77, 0xd4, 0x12, 0x10, 0x87, 0xd2, 0x00, 0x2c,
+ 0x7a, 0xbb, 0x8e, 0x88, 0x22, 0x91, 0x15, 0xbe, 0xa2, 0x59, 0xca, 0x34,
+ 0xe0, 0x1c, 0x61, 0x94, 0x86, 0x20, 0x33, 0xcd, 0xe7, 0x4c, 0x5d, 0x3b,
+ 0x92, 0x3e, 0xcb, 0xd6, 0x2d, 0xea, 0x54, 0xfa, 0xfb, 0xaf, 0x54, 0xf5,
+ 0xa8, 0xc5, 0x0b, 0xca, 0x8b, 0x87, 0x00, 0xe6, 0x9f, 0xe6, 0x95, 0xbf,
+ 0xb7, 0xc4, 0xa3, 0x59, 0xf5, 0x16, 0x6c, 0x5f, 0x3e, 0x69, 0x55, 0x80,
+ 0x39, 0xf6, 0x75, 0x50, 0x14, 0x3e, 0x32,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 7e:e1:4a:6f:6f:ef:f2:d3:7f:3f:ad:65:4d:3a:da:b4
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Validity
+ Not Before: Oct 31 00:00:00 2013 GMT
+ Not After : Oct 30 23:59:59 2023 GMT
+ Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL CA - G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d8:a1:65:74:23:e8:2b:64:e2:32:d7:33:37:3d:
+ 8e:f5:34:16:48:dd:4f:7f:87:1c:f8:44:23:13:8e:
+ fb:11:d8:44:5a:18:71:8e:60:16:26:92:9b:fd:17:
+ 0b:e1:71:70:42:fe:bf:fa:1c:c0:aa:a3:a7:b5:71:
+ e8:ff:18:83:f6:df:10:0a:13:62:c8:3d:9c:a7:de:
+ 2e:3f:0c:d9:1d:e7:2e:fb:2a:ce:c8:9a:7f:87:bf:
+ d8:4c:04:15:32:c9:d1:cc:95:71:a0:4e:28:4f:84:
+ d9:35:fb:e3:86:6f:94:53:e6:72:8a:63:67:2e:be:
+ 69:f6:f7:6e:8e:9c:60:04:eb:29:fa:c4:47:42:d2:
+ 78:98:e3:ec:0b:a5:92:dc:b7:9a:bd:80:64:2b:38:
+ 7c:38:09:5b:66:f6:2d:95:7a:86:b2:34:2e:85:9e:
+ 90:0e:5f:b7:5d:a4:51:72:46:70:13:bf:67:f2:b6:
+ a7:4d:14:1e:6c:b9:53:ee:23:1a:4e:8d:48:55:43:
+ 41:b1:89:75:6a:40:28:c5:7d:dd:d2:6e:d2:02:19:
+ 2f:7b:24:94:4b:eb:f1:1a:a9:9b:e3:23:9a:ea:fa:
+ 33:ab:0a:2c:b7:f4:60:08:dd:9f:1c:cd:dd:2d:01:
+ 66:80:af:b3:2f:29:1d:23:b8:8a:e1:a1:70:07:0c:
+ 34:0f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ OCSP - URI:http://s2.symcb.com
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: http://www.symauth.com/cps
+ User Notice:
+ Explicit Text: http://www.symauth.com/rpa
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://s1.symcb.com/pca3-g5.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Alternative Name:
+ DirName:/CN=SymantecPKI-1-533
+ X509v3 Subject Key Identifier:
+ 01:59:AB:E7:DD:3A:0B:59:A6:64:63:D6:CF:20:07:57:D5:91:E7:6A
+ X509v3 Authority Key Identifier:
+ keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 42:01:55:7b:d0:16:1a:5d:58:e8:bb:9b:a8:4d:d7:f3:d7:eb:
+ 13:94:86:d6:7f:21:0b:47:bc:57:9b:92:5d:4f:05:9f:38:a4:
+ 10:7c:cf:83:be:06:43:46:8d:08:bc:6a:d7:10:a6:fa:ab:af:
+ 2f:61:a8:63:f2:65:df:7f:4c:88:12:88:4f:b3:69:d9:ff:27:
+ c0:0a:97:91:8f:56:fb:89:c4:a8:bb:92:2d:1b:73:b0:c6:ab:
+ 36:f4:96:6c:20:08:ef:0a:1e:66:24:45:4f:67:00:40:c8:07:
+ 54:74:33:3b:a6:ad:bb:23:9f:66:ed:a2:44:70:34:fb:0e:ea:
+ 01:fd:cf:78:74:df:a7:ad:55:b7:5f:4d:f6:d6:3f:e0:86:ce:
+ 24:c7:42:a9:13:14:44:35:4b:b6:df:c9:60:ac:0c:7f:d9:93:
+ 21:4b:ee:9c:e4:49:02:98:d3:60:7b:5c:bc:d5:30:2f:07:ce:
+ 44:42:c4:0b:99:fe:e6:9f:fc:b0:78:86:51:6d:d1:2c:9d:c6:
+ 96:fb:85:82:bb:04:2f:f7:62:80:ef:62:da:7f:f6:0e:ac:90:
+ b8:56:bd:79:3f:f2:80:6e:a3:d9:b9:0f:5d:3a:07:1d:91:93:
+ 86:4b:29:4c:e1:dc:b5:e1:e0:33:9d:b3:cb:36:91:4b:fe:a1:
+ b4:ee:f0:f9
+-----BEGIN CERTIFICATE-----
+MIIFKzCCBBOgAwIBAgIQfuFKb2/v8tN/P61lTTratDANBgkqhkiG9w0BAQsFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB3MQsw
+CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
+BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVjIENs
+YXNzIDMgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDYoWV0I+grZOIy1zM3PY71NBZI3U9/hxz4RCMTjvsR2ERaGHGOYBYmkpv9
+FwvhcXBC/r/6HMCqo6e1cej/GIP23xAKE2LIPZyn3i4/DNkd5y77Ks7Imn+Hv9hM
+BBUyydHMlXGgTihPhNk1++OGb5RT5nKKY2cuvmn2926OnGAE6yn6xEdC0niY4+wL
+pZLct5q9gGQrOHw4CVtm9i2VeoayNC6FnpAOX7ddpFFyRnATv2fytqdNFB5suVPu
+IxpOjUhVQ0GxiXVqQCjFfd3SbtICGS97JJRL6/EaqZvjI5rq+jOrCiy39GAI3Z8c
+zd0tAWaAr7MvKR0juIrhoXAHDDQPAgMBAAGjggFdMIIBWTAvBggrBgEFBQcBAQQj
+MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wEgYDVR0TAQH/BAgw
+BgEB/wIBADBlBgNVHSAEXjBcMFoGBFUdIAAwUjAmBggrBgEFBQcCARYaaHR0cDov
+L3d3dy5zeW1hdXRoLmNvbS9jcHMwKAYIKwYBBQUHAgIwHBoaaHR0cDovL3d3dy5z
+eW1hdXRoLmNvbS9ycGEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3MxLnN5bWNi
+LmNvbS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKQYDVR0RBCIwIKQeMBwx
+GjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTMzMB0GA1UdDgQWBBQBWavn3ToLWaZk
+Y9bPIAdX1ZHnajAfBgNVHSMEGDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzANBgkq
+hkiG9w0BAQsFAAOCAQEAQgFVe9AWGl1Y6LubqE3X89frE5SG1n8hC0e8V5uSXU8F
+nzikEHzPg74GQ0aNCLxq1xCm+quvL2GoY/Jl339MiBKIT7Np2f8nwAqXkY9W+4nE
+qLuSLRtzsMarNvSWbCAI7woeZiRFT2cAQMgHVHQzO6atuyOfZu2iRHA0+w7qAf3P
+eHTfp61Vt19N9tY/4IbOJMdCqRMURDVLtt/JYKwMf9mTIUvunORJApjTYHtcvNUw
+LwfORELEC5n+5p/8sHiGUW3RLJ3GlvuFgrsEL/digO9i2n/2DqyQuFa9eT/ygG6j
+2bkPXToHHZGThkspTOHcteHgM52zyzaRS/6htO7w+Q==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert42[] = {
+ 0x30, 0x82, 0x05, 0x2b, 0x30, 0x82, 0x04, 0x13, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x7e, 0xe1, 0x4a, 0x6f, 0x6f, 0xef, 0xf2, 0xd3, 0x7f,
+ 0x3f, 0xad, 0x65, 0x4d, 0x3a, 0xda, 0xb4, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+ 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
+ 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
+ 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+ 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
+ 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x77, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d,
+ 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d,
+ 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
+ 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+ 0x72, 0x6b, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x1f, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c,
+ 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c,
+ 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0xa1, 0x65, 0x74, 0x23, 0xe8, 0x2b,
+ 0x64, 0xe2, 0x32, 0xd7, 0x33, 0x37, 0x3d, 0x8e, 0xf5, 0x34, 0x16, 0x48,
+ 0xdd, 0x4f, 0x7f, 0x87, 0x1c, 0xf8, 0x44, 0x23, 0x13, 0x8e, 0xfb, 0x11,
+ 0xd8, 0x44, 0x5a, 0x18, 0x71, 0x8e, 0x60, 0x16, 0x26, 0x92, 0x9b, 0xfd,
+ 0x17, 0x0b, 0xe1, 0x71, 0x70, 0x42, 0xfe, 0xbf, 0xfa, 0x1c, 0xc0, 0xaa,
+ 0xa3, 0xa7, 0xb5, 0x71, 0xe8, 0xff, 0x18, 0x83, 0xf6, 0xdf, 0x10, 0x0a,
+ 0x13, 0x62, 0xc8, 0x3d, 0x9c, 0xa7, 0xde, 0x2e, 0x3f, 0x0c, 0xd9, 0x1d,
+ 0xe7, 0x2e, 0xfb, 0x2a, 0xce, 0xc8, 0x9a, 0x7f, 0x87, 0xbf, 0xd8, 0x4c,
+ 0x04, 0x15, 0x32, 0xc9, 0xd1, 0xcc, 0x95, 0x71, 0xa0, 0x4e, 0x28, 0x4f,
+ 0x84, 0xd9, 0x35, 0xfb, 0xe3, 0x86, 0x6f, 0x94, 0x53, 0xe6, 0x72, 0x8a,
+ 0x63, 0x67, 0x2e, 0xbe, 0x69, 0xf6, 0xf7, 0x6e, 0x8e, 0x9c, 0x60, 0x04,
+ 0xeb, 0x29, 0xfa, 0xc4, 0x47, 0x42, 0xd2, 0x78, 0x98, 0xe3, 0xec, 0x0b,
+ 0xa5, 0x92, 0xdc, 0xb7, 0x9a, 0xbd, 0x80, 0x64, 0x2b, 0x38, 0x7c, 0x38,
+ 0x09, 0x5b, 0x66, 0xf6, 0x2d, 0x95, 0x7a, 0x86, 0xb2, 0x34, 0x2e, 0x85,
+ 0x9e, 0x90, 0x0e, 0x5f, 0xb7, 0x5d, 0xa4, 0x51, 0x72, 0x46, 0x70, 0x13,
+ 0xbf, 0x67, 0xf2, 0xb6, 0xa7, 0x4d, 0x14, 0x1e, 0x6c, 0xb9, 0x53, 0xee,
+ 0x23, 0x1a, 0x4e, 0x8d, 0x48, 0x55, 0x43, 0x41, 0xb1, 0x89, 0x75, 0x6a,
+ 0x40, 0x28, 0xc5, 0x7d, 0xdd, 0xd2, 0x6e, 0xd2, 0x02, 0x19, 0x2f, 0x7b,
+ 0x24, 0x94, 0x4b, 0xeb, 0xf1, 0x1a, 0xa9, 0x9b, 0xe3, 0x23, 0x9a, 0xea,
+ 0xfa, 0x33, 0xab, 0x0a, 0x2c, 0xb7, 0xf4, 0x60, 0x08, 0xdd, 0x9f, 0x1c,
+ 0xcd, 0xdd, 0x2d, 0x01, 0x66, 0x80, 0xaf, 0xb3, 0x2f, 0x29, 0x1d, 0x23,
+ 0xb8, 0x8a, 0xe1, 0xa1, 0x70, 0x07, 0x0c, 0x34, 0x0f, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5d, 0x30, 0x82, 0x01, 0x59, 0x30, 0x2f,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23,
+ 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+ 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+ 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
+ 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x65, 0x06, 0x03, 0x55,
+ 0x1d, 0x20, 0x04, 0x5e, 0x30, 0x5c, 0x30, 0x5a, 0x06, 0x04, 0x55, 0x1d,
+ 0x20, 0x00, 0x30, 0x52, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73,
+ 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72,
+ 0x70, 0x61, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30,
+ 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35,
+ 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x29, 0x06, 0x03,
+ 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31,
+ 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79,
+ 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d,
+ 0x35, 0x33, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+ 0x04, 0x14, 0x01, 0x59, 0xab, 0xe7, 0xdd, 0x3a, 0x0b, 0x59, 0xa6, 0x64,
+ 0x63, 0xd6, 0xcf, 0x20, 0x07, 0x57, 0xd5, 0x91, 0xe7, 0x6a, 0x30, 0x1f,
+ 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f,
+ 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43,
+ 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x01, 0x00, 0x42, 0x01, 0x55, 0x7b, 0xd0, 0x16, 0x1a, 0x5d, 0x58,
+ 0xe8, 0xbb, 0x9b, 0xa8, 0x4d, 0xd7, 0xf3, 0xd7, 0xeb, 0x13, 0x94, 0x86,
+ 0xd6, 0x7f, 0x21, 0x0b, 0x47, 0xbc, 0x57, 0x9b, 0x92, 0x5d, 0x4f, 0x05,
+ 0x9f, 0x38, 0xa4, 0x10, 0x7c, 0xcf, 0x83, 0xbe, 0x06, 0x43, 0x46, 0x8d,
+ 0x08, 0xbc, 0x6a, 0xd7, 0x10, 0xa6, 0xfa, 0xab, 0xaf, 0x2f, 0x61, 0xa8,
+ 0x63, 0xf2, 0x65, 0xdf, 0x7f, 0x4c, 0x88, 0x12, 0x88, 0x4f, 0xb3, 0x69,
+ 0xd9, 0xff, 0x27, 0xc0, 0x0a, 0x97, 0x91, 0x8f, 0x56, 0xfb, 0x89, 0xc4,
+ 0xa8, 0xbb, 0x92, 0x2d, 0x1b, 0x73, 0xb0, 0xc6, 0xab, 0x36, 0xf4, 0x96,
+ 0x6c, 0x20, 0x08, 0xef, 0x0a, 0x1e, 0x66, 0x24, 0x45, 0x4f, 0x67, 0x00,
+ 0x40, 0xc8, 0x07, 0x54, 0x74, 0x33, 0x3b, 0xa6, 0xad, 0xbb, 0x23, 0x9f,
+ 0x66, 0xed, 0xa2, 0x44, 0x70, 0x34, 0xfb, 0x0e, 0xea, 0x01, 0xfd, 0xcf,
+ 0x78, 0x74, 0xdf, 0xa7, 0xad, 0x55, 0xb7, 0x5f, 0x4d, 0xf6, 0xd6, 0x3f,
+ 0xe0, 0x86, 0xce, 0x24, 0xc7, 0x42, 0xa9, 0x13, 0x14, 0x44, 0x35, 0x4b,
+ 0xb6, 0xdf, 0xc9, 0x60, 0xac, 0x0c, 0x7f, 0xd9, 0x93, 0x21, 0x4b, 0xee,
+ 0x9c, 0xe4, 0x49, 0x02, 0x98, 0xd3, 0x60, 0x7b, 0x5c, 0xbc, 0xd5, 0x30,
+ 0x2f, 0x07, 0xce, 0x44, 0x42, 0xc4, 0x0b, 0x99, 0xfe, 0xe6, 0x9f, 0xfc,
+ 0xb0, 0x78, 0x86, 0x51, 0x6d, 0xd1, 0x2c, 0x9d, 0xc6, 0x96, 0xfb, 0x85,
+ 0x82, 0xbb, 0x04, 0x2f, 0xf7, 0x62, 0x80, 0xef, 0x62, 0xda, 0x7f, 0xf6,
+ 0x0e, 0xac, 0x90, 0xb8, 0x56, 0xbd, 0x79, 0x3f, 0xf2, 0x80, 0x6e, 0xa3,
+ 0xd9, 0xb9, 0x0f, 0x5d, 0x3a, 0x07, 0x1d, 0x91, 0x93, 0x86, 0x4b, 0x29,
+ 0x4c, 0xe1, 0xdc, 0xb5, 0xe1, 0xe0, 0x33, 0x9d, 0xb3, 0xcb, 0x36, 0x91,
+ 0x4b, 0xfe, 0xa1, 0xb4, 0xee, 0xf0, 0xf9,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 51:3f:b9:74:38:70:b7:34:40:41:8d:30:93:06:99:ff
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Validity
+ Not Before: Oct 31 00:00:00 2013 GMT
+ Not After : Oct 30 23:59:59 2023 GMT
+ Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 Secure Server CA - G4
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b2:d8:05:ca:1c:74:2d:b5:17:56:39:c5:4a:52:
+ 09:96:e8:4b:d8:0c:f1:68:9f:9a:42:28:62:c3:a5:
+ 30:53:7e:55:11:82:5b:03:7a:0d:2f:e1:79:04:c9:
+ b4:96:77:19:81:01:94:59:f9:bc:f7:7a:99:27:82:
+ 2d:b7:83:dd:5a:27:7f:b2:03:7a:9c:53:25:e9:48:
+ 1f:46:4f:c8:9d:29:f8:be:79:56:f6:f7:fd:d9:3a:
+ 68:da:8b:4b:82:33:41:12:c3:c8:3c:cc:d6:96:7a:
+ 84:21:1a:22:04:03:27:17:8b:1c:68:61:93:0f:0e:
+ 51:80:33:1d:b4:b5:ce:eb:7e:d0:62:ac:ee:b3:7b:
+ 01:74:ef:69:35:eb:ca:d5:3d:a9:ee:97:98:ca:8d:
+ aa:44:0e:25:99:4a:15:96:a4:ce:6d:02:54:1f:2a:
+ 6a:26:e2:06:3a:63:48:ac:b4:4c:d1:75:93:50:ff:
+ 13:2f:d6:da:e1:c6:18:f5:9f:c9:25:5d:f3:00:3a:
+ de:26:4d:b4:29:09:cd:0f:3d:23:6f:16:4a:81:16:
+ fb:f2:83:10:c3:b8:d6:d8:55:32:3d:f1:bd:0f:bd:
+ 8c:52:95:4a:16:97:7a:52:21:63:75:2f:16:f9:c4:
+ 66:be:f5:b5:09:d8:ff:27:00:cd:44:7c:6f:4b:3f:
+ b0:f7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://s1.symcb.com/pca3-g5.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://s2.symcb.com
+
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.54
+ CPS: http://www.symauth.com/cps
+ User Notice:
+ Explicit Text: http://www.symauth.com/rpa
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=SymantecPKI-1-534
+ X509v3 Subject Key Identifier:
+ 5F:60:CF:61:90:55:DF:84:43:14:8A:60:2A:B2:F5:7A:F4:43:18:EF
+ X509v3 Authority Key Identifier:
+ keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 5e:94:56:49:dd:8e:2d:65:f5:c1:36:51:b6:03:e3:da:9e:73:
+ 19:f2:1f:59:ab:58:7e:6c:26:05:2c:fa:81:d7:5c:23:17:22:
+ 2c:37:93:f7:86:ec:85:e6:b0:a3:fd:1f:e2:32:a8:45:6f:e1:
+ d9:fb:b9:af:d2:70:a0:32:42:65:bf:84:fe:16:2a:8f:3f:c5:
+ a6:d6:a3:93:7d:43:e9:74:21:91:35:28:f4:63:e9:2e:ed:f7:
+ f5:5c:7f:4b:9a:b5:20:e9:0a:bd:e0:45:10:0c:14:94:9a:5d:
+ a5:e3:4b:91:e8:24:9b:46:40:65:f4:22:72:cd:99:f8:88:11:
+ f5:f3:7f:e6:33:82:e6:a8:c5:7e:fe:d0:08:e2:25:58:08:71:
+ 68:e6:cd:a2:e6:14:de:4e:52:24:2d:fd:e5:79:13:53:e7:5e:
+ 2f:2d:4d:1b:6d:40:15:52:2b:f7:87:89:78:12:81:6e:d9:4d:
+ aa:2d:78:d4:c2:2c:3d:08:5f:87:91:9e:1f:0e:b0:de:30:52:
+ 64:86:89:aa:9d:66:9c:0e:76:0c:80:f2:74:d8:2a:f8:b8:3a:
+ ce:d7:d6:0f:11:be:6b:ab:14:f5:bd:41:a0:22:63:89:f1:ba:
+ 0f:6f:29:63:66:2d:3f:ac:8c:72:c5:fb:c7:e4:d4:0f:f2:3b:
+ 4f:8c:29:c7
+-----BEGIN CERTIFICATE-----
+MIIFODCCBCCgAwIBAgIQUT+5dDhwtzRAQY0wkwaZ/zANBgkqhkiG9w0BAQsFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB+MQsw
+CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
+BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVjIENs
+YXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAstgFyhx0LbUXVjnFSlIJluhL2AzxaJ+aQihiw6UwU35VEYJb
+A3oNL+F5BMm0lncZgQGUWfm893qZJ4Itt4PdWid/sgN6nFMl6UgfRk/InSn4vnlW
+9vf92Tpo2otLgjNBEsPIPMzWlnqEIRoiBAMnF4scaGGTDw5RgDMdtLXO637QYqzu
+s3sBdO9pNevK1T2p7peYyo2qRA4lmUoVlqTObQJUHypqJuIGOmNIrLRM0XWTUP8T
+L9ba4cYY9Z/JJV3zADreJk20KQnNDz0jbxZKgRb78oMQw7jW2FUyPfG9D72MUpVK
+Fpd6UiFjdS8W+cRmvvW1Cdj/JwDNRHxvSz+w9wIDAQABo4IBYzCCAV8wEgYDVR0T
+AQH/BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2Iu
+Y29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQjMCEw
+HwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wawYDVR0gBGQwYjBgBgpg
+hkgBhvhFAQc2MFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20v
+Y3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMCkG
+A1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTUzNDAdBgNVHQ4E
+FgQUX2DPYZBV34RDFIpgKrL1evRDGO8wHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnz
+Qzn6Aq8zMTMwDQYJKoZIhvcNAQELBQADggEBAF6UVkndji1l9cE2UbYD49qecxny
+H1mrWH5sJgUs+oHXXCMXIiw3k/eG7IXmsKP9H+IyqEVv4dn7ua/ScKAyQmW/hP4W
+Ko8/xabWo5N9Q+l0IZE1KPRj6S7t9/Vcf0uatSDpCr3gRRAMFJSaXaXjS5HoJJtG
+QGX0InLNmfiIEfXzf+YzguaoxX7+0AjiJVgIcWjmzaLmFN5OUiQt/eV5E1PnXi8t
+TRttQBVSK/eHiXgSgW7ZTaoteNTCLD0IX4eRnh8OsN4wUmSGiaqdZpwOdgyA8nTY
+Kvi4Os7X1g8RvmurFPW9QaAiY4nxug9vKWNmLT+sjHLF+8fk1A/yO0+MKcc=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert43[] = {
+ 0x30, 0x82, 0x05, 0x38, 0x30, 0x82, 0x04, 0x20, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x51, 0x3f, 0xb9, 0x74, 0x38, 0x70, 0xb7, 0x34, 0x40,
+ 0x41, 0x8d, 0x30, 0x93, 0x06, 0x99, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81,
+ 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+ 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
+ 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
+ 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+ 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
+ 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x7e, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d,
+ 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d,
+ 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63,
+ 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+ 0x72, 0x6b, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x26, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c,
+ 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
+ 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d,
+ 0x20, 0x47, 0x34, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xb2, 0xd8, 0x05, 0xca, 0x1c, 0x74, 0x2d, 0xb5, 0x17, 0x56, 0x39, 0xc5,
+ 0x4a, 0x52, 0x09, 0x96, 0xe8, 0x4b, 0xd8, 0x0c, 0xf1, 0x68, 0x9f, 0x9a,
+ 0x42, 0x28, 0x62, 0xc3, 0xa5, 0x30, 0x53, 0x7e, 0x55, 0x11, 0x82, 0x5b,
+ 0x03, 0x7a, 0x0d, 0x2f, 0xe1, 0x79, 0x04, 0xc9, 0xb4, 0x96, 0x77, 0x19,
+ 0x81, 0x01, 0x94, 0x59, 0xf9, 0xbc, 0xf7, 0x7a, 0x99, 0x27, 0x82, 0x2d,
+ 0xb7, 0x83, 0xdd, 0x5a, 0x27, 0x7f, 0xb2, 0x03, 0x7a, 0x9c, 0x53, 0x25,
+ 0xe9, 0x48, 0x1f, 0x46, 0x4f, 0xc8, 0x9d, 0x29, 0xf8, 0xbe, 0x79, 0x56,
+ 0xf6, 0xf7, 0xfd, 0xd9, 0x3a, 0x68, 0xda, 0x8b, 0x4b, 0x82, 0x33, 0x41,
+ 0x12, 0xc3, 0xc8, 0x3c, 0xcc, 0xd6, 0x96, 0x7a, 0x84, 0x21, 0x1a, 0x22,
+ 0x04, 0x03, 0x27, 0x17, 0x8b, 0x1c, 0x68, 0x61, 0x93, 0x0f, 0x0e, 0x51,
+ 0x80, 0x33, 0x1d, 0xb4, 0xb5, 0xce, 0xeb, 0x7e, 0xd0, 0x62, 0xac, 0xee,
+ 0xb3, 0x7b, 0x01, 0x74, 0xef, 0x69, 0x35, 0xeb, 0xca, 0xd5, 0x3d, 0xa9,
+ 0xee, 0x97, 0x98, 0xca, 0x8d, 0xaa, 0x44, 0x0e, 0x25, 0x99, 0x4a, 0x15,
+ 0x96, 0xa4, 0xce, 0x6d, 0x02, 0x54, 0x1f, 0x2a, 0x6a, 0x26, 0xe2, 0x06,
+ 0x3a, 0x63, 0x48, 0xac, 0xb4, 0x4c, 0xd1, 0x75, 0x93, 0x50, 0xff, 0x13,
+ 0x2f, 0xd6, 0xda, 0xe1, 0xc6, 0x18, 0xf5, 0x9f, 0xc9, 0x25, 0x5d, 0xf3,
+ 0x00, 0x3a, 0xde, 0x26, 0x4d, 0xb4, 0x29, 0x09, 0xcd, 0x0f, 0x3d, 0x23,
+ 0x6f, 0x16, 0x4a, 0x81, 0x16, 0xfb, 0xf2, 0x83, 0x10, 0xc3, 0xb8, 0xd6,
+ 0xd8, 0x55, 0x32, 0x3d, 0xf1, 0xbd, 0x0f, 0xbd, 0x8c, 0x52, 0x95, 0x4a,
+ 0x16, 0x97, 0x7a, 0x52, 0x21, 0x63, 0x75, 0x2f, 0x16, 0xf9, 0xc4, 0x66,
+ 0xbe, 0xf5, 0xb5, 0x09, 0xd8, 0xff, 0x27, 0x00, 0xcd, 0x44, 0x7c, 0x6f,
+ 0x4b, 0x3f, 0xb0, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
+ 0x63, 0x30, 0x82, 0x01, 0x5f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27,
+ 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30,
+ 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86,
+ 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x32, 0x2e, 0x73,
+ 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x6b, 0x06, 0x03,
+ 0x55, 0x1d, 0x20, 0x04, 0x64, 0x30, 0x62, 0x30, 0x60, 0x06, 0x0a, 0x60,
+ 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x52, 0x30,
+ 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
+ 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+ 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74,
+ 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x29, 0x06,
+ 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c,
+ 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53,
+ 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31,
+ 0x2d, 0x35, 0x33, 0x34, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0x5f, 0x60, 0xcf, 0x61, 0x90, 0x55, 0xdf, 0x84, 0x43,
+ 0x14, 0x8a, 0x60, 0x2a, 0xb2, 0xf5, 0x7a, 0xf4, 0x43, 0x18, 0xef, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
+ 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x5e, 0x94, 0x56, 0x49, 0xdd, 0x8e, 0x2d, 0x65,
+ 0xf5, 0xc1, 0x36, 0x51, 0xb6, 0x03, 0xe3, 0xda, 0x9e, 0x73, 0x19, 0xf2,
+ 0x1f, 0x59, 0xab, 0x58, 0x7e, 0x6c, 0x26, 0x05, 0x2c, 0xfa, 0x81, 0xd7,
+ 0x5c, 0x23, 0x17, 0x22, 0x2c, 0x37, 0x93, 0xf7, 0x86, 0xec, 0x85, 0xe6,
+ 0xb0, 0xa3, 0xfd, 0x1f, 0xe2, 0x32, 0xa8, 0x45, 0x6f, 0xe1, 0xd9, 0xfb,
+ 0xb9, 0xaf, 0xd2, 0x70, 0xa0, 0x32, 0x42, 0x65, 0xbf, 0x84, 0xfe, 0x16,
+ 0x2a, 0x8f, 0x3f, 0xc5, 0xa6, 0xd6, 0xa3, 0x93, 0x7d, 0x43, 0xe9, 0x74,
+ 0x21, 0x91, 0x35, 0x28, 0xf4, 0x63, 0xe9, 0x2e, 0xed, 0xf7, 0xf5, 0x5c,
+ 0x7f, 0x4b, 0x9a, 0xb5, 0x20, 0xe9, 0x0a, 0xbd, 0xe0, 0x45, 0x10, 0x0c,
+ 0x14, 0x94, 0x9a, 0x5d, 0xa5, 0xe3, 0x4b, 0x91, 0xe8, 0x24, 0x9b, 0x46,
+ 0x40, 0x65, 0xf4, 0x22, 0x72, 0xcd, 0x99, 0xf8, 0x88, 0x11, 0xf5, 0xf3,
+ 0x7f, 0xe6, 0x33, 0x82, 0xe6, 0xa8, 0xc5, 0x7e, 0xfe, 0xd0, 0x08, 0xe2,
+ 0x25, 0x58, 0x08, 0x71, 0x68, 0xe6, 0xcd, 0xa2, 0xe6, 0x14, 0xde, 0x4e,
+ 0x52, 0x24, 0x2d, 0xfd, 0xe5, 0x79, 0x13, 0x53, 0xe7, 0x5e, 0x2f, 0x2d,
+ 0x4d, 0x1b, 0x6d, 0x40, 0x15, 0x52, 0x2b, 0xf7, 0x87, 0x89, 0x78, 0x12,
+ 0x81, 0x6e, 0xd9, 0x4d, 0xaa, 0x2d, 0x78, 0xd4, 0xc2, 0x2c, 0x3d, 0x08,
+ 0x5f, 0x87, 0x91, 0x9e, 0x1f, 0x0e, 0xb0, 0xde, 0x30, 0x52, 0x64, 0x86,
+ 0x89, 0xaa, 0x9d, 0x66, 0x9c, 0x0e, 0x76, 0x0c, 0x80, 0xf2, 0x74, 0xd8,
+ 0x2a, 0xf8, 0xb8, 0x3a, 0xce, 0xd7, 0xd6, 0x0f, 0x11, 0xbe, 0x6b, 0xab,
+ 0x14, 0xf5, 0xbd, 0x41, 0xa0, 0x22, 0x63, 0x89, 0xf1, 0xba, 0x0f, 0x6f,
+ 0x29, 0x63, 0x66, 0x2d, 0x3f, 0xac, 0x8c, 0x72, 0xc5, 0xfb, 0xc7, 0xe4,
+ 0xd4, 0x0f, 0xf2, 0x3b, 0x4f, 0x8c, 0x29, 0xc7,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 120036009 (0x7279aa9)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
+ Validity
+ Not Before: Dec 19 20:07:32 2013 GMT
+ Not After : Dec 19 20:06:55 2017 GMT
+ Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24:
+ 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72:
+ 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88:
+ 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1:
+ d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03:
+ e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42:
+ f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe:
+ 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29:
+ e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18:
+ 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51:
+ af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41:
+ 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a:
+ 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a:
+ 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94:
+ 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67:
+ 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae:
+ ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be:
+ ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34:
+ 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f:
+ e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29:
+ 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d:
+ 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08:
+ 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf:
+ ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2:
+ 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08:
+ 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0:
+ 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70:
+ 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7:
+ d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09:
+ c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18:
+ 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33:
+ a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13:
+ 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01:
+ a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41:
+ 4a:a8:fb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.6334.1.0
+ CPS: http://cybertrust.omniroot.com/repository.cfm
+
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Authority Key Identifier:
+ keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
+
+ X509v3 Subject Key Identifier:
+ 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5
+ Signature Algorithm: sha256WithRSAEncryption
+ 76:85:c5:23:31:1f:b4:73:ea:a0:bc:a5:ed:df:45:43:6a:7f:
+ 69:20:1b:80:b2:fb:1c:dd:aa:7f:88:d3:31:41:36:f7:fb:fb:
+ 6b:ad:98:8c:78:1f:9d:11:67:3a:cd:4b:ec:a8:bc:9d:15:19:
+ c4:3b:0b:a7:93:ce:e8:fc:9d:5b:e8:1f:cb:56:ae:76:43:2b:
+ c7:13:51:77:41:a8:66:4c:5f:a7:d1:d7:aa:75:c5:1b:29:4c:
+ c9:f4:6d:a1:5e:a1:85:93:16:c2:cb:3b:ab:14:7d:44:fd:da:
+ 25:29:86:2a:fe:63:20:ca:d2:0b:c2:34:15:bb:af:5b:7f:8a:
+ e0:aa:ed:45:a6:ea:79:db:d8:35:66:54:43:de:37:33:d1:e4:
+ e0:cd:57:ca:71:b0:7d:e9:16:77:64:e8:59:97:b9:d5:2e:d1:
+ b4:91:da:77:71:f3:4a:0f:48:d2:34:99:60:95:37:ac:1f:01:
+ cd:10:9d:e8:2a:a5:20:c7:50:9b:b3:6c:49:78:2b:58:92:64:
+ 89:b8:95:36:a8:34:aa:f0:41:d2:95:5a:24:54:97:4d:6e:05:
+ c4:95:ad:c4:7a:a3:39:fb:79:06:8a:9b:a6:4f:d9:22:fa:44:
+ 4e:36:f3:c9:0f:a6:39:e7:80:b2:5e:bf:bd:39:d1:46:e5:55:
+ 47:db:bc:6e
+-----BEGIN CERTIFICATE-----
+MIIFhjCCBG6gAwIBAgIEByeaqTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEzMTIxOTIwMDczMloX
+DTE3MTIxOTIwMDY1NVowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
+dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
+YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0
+IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3
+p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu
+e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA
+iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R
+PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg
+lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU
+mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R
+DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV
+S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq
+qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE
+OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o
+/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCASAwggEcMBIGA1Ud
+EwEB/wQIMAYBAf8CAQAwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEF
+BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku
+Y2ZtMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
+AwIwHwYDVR0jBBgwFoAU5Z1ZMIJHWMys+ghUNoZ7OrUETfAwQgYDVR0fBDswOTA3
+oDWgM4YxaHR0cDovL2NkcDEucHVibGljLXRydXN0LmNvbS9DUkwvT21uaXJvb3Qy
+MDI1LmNybDAdBgNVHQ4EFgQUUa8kJpz0aCJXgCYrO0ZiFXsezKUwDQYJKoZIhvcN
+AQELBQADggEBAHaFxSMxH7Rz6qC8pe3fRUNqf2kgG4Cy+xzdqn+I0zFBNvf7+2ut
+mIx4H50RZzrNS+yovJ0VGcQ7C6eTzuj8nVvoH8tWrnZDK8cTUXdBqGZMX6fR16p1
+xRspTMn0baFeoYWTFsLLO6sUfUT92iUphir+YyDK0gvCNBW7r1t/iuCq7UWm6nnb
+2DVmVEPeNzPR5ODNV8pxsH3pFndk6FmXudUu0bSR2ndx80oPSNI0mWCVN6wfAc0Q
+negqpSDHUJuzbEl4K1iSZIm4lTaoNKrwQdKVWiRUl01uBcSVrcR6ozn7eQaKm6ZP
+2SL6RE4288kPpjnngLJev7050UblVUfbvG4=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert44[] = {
+ 0x30, 0x82, 0x05, 0x86, 0x30, 0x82, 0x04, 0x6e, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x07, 0x27, 0x9a, 0xa9, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
+ 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
+ 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
+ 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
+ 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
+ 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33,
+ 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x37, 0x33, 0x32, 0x5a, 0x17,
+ 0x0d, 0x31, 0x37, 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x36, 0x35,
+ 0x35, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+ 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
+ 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
+ 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30,
+ 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72,
+ 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
+ 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
+ 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32,
+ 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
+ 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37,
+ 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37,
+ 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d,
+ 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10,
+ 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae,
+ 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30,
+ 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2,
+ 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77,
+ 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0,
+ 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9,
+ 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09,
+ 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57,
+ 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1,
+ 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb,
+ 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8,
+ 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21,
+ 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60,
+ 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb,
+ 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4,
+ 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a,
+ 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14,
+ 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae,
+ 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca,
+ 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99,
+ 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11,
+ 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b,
+ 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57,
+ 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02,
+ 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5,
+ 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c,
+ 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb,
+ 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90,
+ 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa,
+ 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d,
+ 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae,
+ 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86,
+ 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4,
+ 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a,
+ 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6,
+ 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8,
+ 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68,
+ 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0,
+ 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10,
+ 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+ 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
+ 0x01, 0x00, 0x30, 0x53, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30,
+ 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e,
+ 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e,
+ 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x03, 0x02, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+ 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac,
+ 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30,
+ 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37,
+ 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
+ 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43,
+ 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32,
+ 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4,
+ 0x68, 0x22, 0x57, 0x80, 0x26, 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e,
+ 0xcc, 0xa5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x76, 0x85,
+ 0xc5, 0x23, 0x31, 0x1f, 0xb4, 0x73, 0xea, 0xa0, 0xbc, 0xa5, 0xed, 0xdf,
+ 0x45, 0x43, 0x6a, 0x7f, 0x69, 0x20, 0x1b, 0x80, 0xb2, 0xfb, 0x1c, 0xdd,
+ 0xaa, 0x7f, 0x88, 0xd3, 0x31, 0x41, 0x36, 0xf7, 0xfb, 0xfb, 0x6b, 0xad,
+ 0x98, 0x8c, 0x78, 0x1f, 0x9d, 0x11, 0x67, 0x3a, 0xcd, 0x4b, 0xec, 0xa8,
+ 0xbc, 0x9d, 0x15, 0x19, 0xc4, 0x3b, 0x0b, 0xa7, 0x93, 0xce, 0xe8, 0xfc,
+ 0x9d, 0x5b, 0xe8, 0x1f, 0xcb, 0x56, 0xae, 0x76, 0x43, 0x2b, 0xc7, 0x13,
+ 0x51, 0x77, 0x41, 0xa8, 0x66, 0x4c, 0x5f, 0xa7, 0xd1, 0xd7, 0xaa, 0x75,
+ 0xc5, 0x1b, 0x29, 0x4c, 0xc9, 0xf4, 0x6d, 0xa1, 0x5e, 0xa1, 0x85, 0x93,
+ 0x16, 0xc2, 0xcb, 0x3b, 0xab, 0x14, 0x7d, 0x44, 0xfd, 0xda, 0x25, 0x29,
+ 0x86, 0x2a, 0xfe, 0x63, 0x20, 0xca, 0xd2, 0x0b, 0xc2, 0x34, 0x15, 0xbb,
+ 0xaf, 0x5b, 0x7f, 0x8a, 0xe0, 0xaa, 0xed, 0x45, 0xa6, 0xea, 0x79, 0xdb,
+ 0xd8, 0x35, 0x66, 0x54, 0x43, 0xde, 0x37, 0x33, 0xd1, 0xe4, 0xe0, 0xcd,
+ 0x57, 0xca, 0x71, 0xb0, 0x7d, 0xe9, 0x16, 0x77, 0x64, 0xe8, 0x59, 0x97,
+ 0xb9, 0xd5, 0x2e, 0xd1, 0xb4, 0x91, 0xda, 0x77, 0x71, 0xf3, 0x4a, 0x0f,
+ 0x48, 0xd2, 0x34, 0x99, 0x60, 0x95, 0x37, 0xac, 0x1f, 0x01, 0xcd, 0x10,
+ 0x9d, 0xe8, 0x2a, 0xa5, 0x20, 0xc7, 0x50, 0x9b, 0xb3, 0x6c, 0x49, 0x78,
+ 0x2b, 0x58, 0x92, 0x64, 0x89, 0xb8, 0x95, 0x36, 0xa8, 0x34, 0xaa, 0xf0,
+ 0x41, 0xd2, 0x95, 0x5a, 0x24, 0x54, 0x97, 0x4d, 0x6e, 0x05, 0xc4, 0x95,
+ 0xad, 0xc4, 0x7a, 0xa3, 0x39, 0xfb, 0x79, 0x06, 0x8a, 0x9b, 0xa6, 0x4f,
+ 0xd9, 0x22, 0xfa, 0x44, 0x4e, 0x36, 0xf3, 0xc9, 0x0f, 0xa6, 0x39, 0xe7,
+ 0x80, 0xb2, 0x5e, 0xbf, 0xbd, 0x39, 0xd1, 0x46, 0xe5, 0x55, 0x47, 0xdb,
+ 0xbc, 0x6e,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 67:3f:33:4f:21:53:36:52:c3:5e:15:d2:fd:b3:02:0f
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
+ Validity
+ Not Before: Aug 8 01:00:05 2009 GMT
+ Not After : Aug 8 01:00:05 2024 GMT
+ Subject: C=CN, O=WoSign CA Limited, CN=WoSign Class 3 OV Server CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bc:89:be:61:51:53:c8:2b:96:75:b3:5a:d3:0e:
+ 34:fe:4a:c2:9f:a3:18:83:a2:ac:e3:2e:5e:93:79:
+ 0b:13:49:5e:93:b2:8f:84:10:ed:91:8f:82:ba:ad:
+ 67:df:33:1b:ae:84:f2:55:b0:5b:f4:b3:9e:bc:e6:
+ 04:0f:1d:ef:04:5a:a8:0b:ec:12:6d:56:19:64:70:
+ 49:0f:57:92:f3:5f:21:a6:4d:b4:d2:96:2b:3c:32:
+ b3:ef:8f:59:0b:14:ba:6e:a2:9e:71:db:f2:88:3f:
+ 28:3b:ec:ce:be:47:ac:45:c7:8a:9e:fa:61:93:c5:
+ 49:17:b6:46:b6:f7:99:16:8c:1c:6e:31:ae:69:ce:
+ ed:c6:24:92:70:a1:cb:96:c3:6c:16:d0:ee:cc:4f:
+ 86:33:b3:41:e6:3d:3d:db:0e:8c:33:74:bb:c3:fc:
+ 0b:a7:fc:d1:71:e2:c1:0c:d4:f7:ba:3e:80:90:d4:
+ 48:eb:a2:83:70:d8:db:30:07:29:89:f9:81:21:2c:
+ ff:eb:47:f6:7a:6d:43:96:67:17:3e:f3:e2:73:51:
+ c7:76:1e:e9:1c:a0:ec:11:1a:b1:cf:1e:2d:9c:55:
+ ee:3b:c6:2d:ae:dc:66:65:91:a2:66:9c:ac:82:f1:
+ a4:17:b5:d7:43:83:c3:88:a0:64:de:ca:72:45:dc:
+ 38:fb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Extended Key Usage:
+ TLS Web Client Authentication, TLS Web Server Authentication
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crls1.wosign.com/ca1.crl
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp1.wosign.com/ca1
+ CA Issuers - URI:http://aia1.wosign.com/ca1-class3-server.cer
+
+ X509v3 Subject Key Identifier:
+ 62:2E:81:D9:E3:42:79:14:A3:CD:D9:54:8A:6E:F8:DE:95:AA:8F:98
+ X509v3 Authority Key Identifier:
+ keyid:E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E
+
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.36305.1.3.2
+ CPS: http://www.wosign.com/policy/
+
+ Signature Algorithm: sha1WithRSAEncryption
+ ab:70:aa:64:c4:0b:34:91:b9:63:20:5e:b0:9c:21:ff:25:79:
+ 6c:57:4e:56:44:58:83:b9:00:ce:2d:65:a8:6d:95:38:ea:82:
+ 2d:55:18:60:12:7e:1a:1d:6b:62:34:2c:d9:cd:17:00:43:84:
+ 3e:ad:bc:ff:26:85:1f:4a:a7:46:13:b0:7d:3b:0b:d9:4b:9d:
+ b0:cf:8d:f4:05:cb:12:29:fe:e1:97:c7:b7:c7:aa:53:7e:39:
+ 2d:9d:f6:d4:5e:b7:8c:15:6a:81:d2:37:1a:43:0e:cb:e6:30:
+ 21:43:83:69:0f:ef:6b:cd:10:f9:84:60:cf:89:e9:88:10:01:
+ af:09:f3:48:bb:07:09:75:01:84:fa:b1:1e:51:19:8f:c6:c9:
+ 85:65:16:5f:e0:56:7e:b7:bf:40:c2:d4:d0:05:1f:93:63:c9:
+ 24:08:3b:91:b2:35:e1:a4:8f:35:db:24:58:75:39:e4:dd:10:
+ 1a:b0:df:13:12:73:9e:6d:e7:67:3c:db:1c:1c:dd:10:dd:cc:
+ f4:07:09:b9:2e:e5:75:6d:97:b7:60:5b:89:70:81:d2:26:d8:
+ c6:09:2b:b2:05:7f:c4:b8:14:41:1e:07:f0:48:41:63:cb:0c:
+ aa:45:7e:84:f9:33:b3:58:87:bc:b1:d6:c2:65:c7:57:c6:95:
+ e8:85:90:b0:62:50:f5:ee:12:f1:d8:7e:73:cb:c0:c3:a0:25:
+ 17:23:37:91:ba:63:bd:84:af:f3:89:e0:51:c2:73:35:6d:63:
+ 86:21:f2:73:bd:c2:47:e0:4d:7e:46:37:4b:d0:f7:61:2a:c7:
+ 94:50:25:36:e8:ae:da:2e:1f:b8:08:b2:55:7c:6b:66:43:8f:
+ 02:1d:dd:a7:eb:98:00:a7:25:74:f5:93:1b:6d:26:bb:1d:e5:
+ b7:fc:21:25:26:d1:77:1b:a8:6e:aa:c3:4b:64:51:7f:91:0e:
+ 41:5c:19:83:a1:a8:1f:94:99:43:0f:99:db:18:dc:21:6f:76:
+ d1:9e:ea:a3:76:e0:f0:09:bc:b9:b4:f7:43:6c:1f:d3:2a:86:
+ 6a:2f:e0:6c:f1:83:39:d7:70:db:a2:91:ab:54:be:f4:47:88:
+ 8c:f0:10:d2:e4:ad:eb:7e:b1:ba:08:4b:67:04:a3:f2:e9:90:
+ 2b:81:e3:74:76:3d:00:9d:d2:bb:fc:a5:a0:15:1c:28:df:10:
+ 4f:47:d7:33:46:9d:b2:57:d2:c6:1f:fb:e4:59:4a:2b:28:a9:
+ 13:dd:b9:e9:93:b4:88:ee:e2:5b:a0:07:25:fe:8a:2e:78:e4:
+ b4:e1:d5:1d:f6:1a:3a:e3:1c:01:2a:1e:a1:86:54:9e:49:dc:
+ c9:59:e3:0d:6d:5a:13:36
+-----BEGIN CERTIFICATE-----
+MIIFozCCA4ugAwIBAgIQZz8zTyFTNlLDXhXS/bMCDzANBgkqhkiG9w0BAQUFADBV
+MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
+BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
+MTAwMDVaFw0yNDA4MDgwMTAwMDVaME8xCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
+b1NpZ24gQ0EgTGltaXRlZDEkMCIGA1UEAxMbV29TaWduIENsYXNzIDMgT1YgU2Vy
+dmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvIm+YVFTyCuW
+dbNa0w40/krCn6MYg6Ks4y5ek3kLE0lek7KPhBDtkY+Cuq1n3zMbroTyVbBb9LOe
+vOYEDx3vBFqoC+wSbVYZZHBJD1eS818hpk200pYrPDKz749ZCxS6bqKecdvyiD8o
+O+zOvkesRceKnvphk8VJF7ZGtveZFowcbjGuac7txiSScKHLlsNsFtDuzE+GM7NB
+5j092w6MM3S7w/wLp/zRceLBDNT3uj6AkNRI66KDcNjbMAcpifmBISz/60f2em1D
+lmcXPvPic1HHdh7pHKDsERqxzx4tnFXuO8YtrtxmZZGiZpysgvGkF7XXQ4PDiKBk
+3spyRdw4+wIDAQABo4IBczCCAW8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQWMBQG
+CCsGAQUFBwMCBggrBgEFBQcDATASBgNVHRMBAf8ECDAGAQH/AgEAMDAGA1UdHwQp
+MCcwJaAjoCGGH2h0dHA6Ly9jcmxzMS53b3NpZ24uY29tL2NhMS5jcmwwcQYIKwYB
+BQUHAQEEZTBjMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcDEud29zaWduLmNvbS9j
+YTEwOAYIKwYBBQUHMAKGLGh0dHA6Ly9haWExLndvc2lnbi5jb20vY2ExLWNsYXNz
+My1zZXJ2ZXIuY2VyMB0GA1UdDgQWBBRiLoHZ40J5FKPN2VSKbvjelaqPmDAfBgNV
+HSMEGDAWgBThZs8O0fGzS7cGIBT+hxLV9v77PjBFBgNVHSAEPjA8MDoGCysGAQQB
+gptRAQMCMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cud29zaWduLmNvbS9wb2xp
+Y3kvMA0GCSqGSIb3DQEBBQUAA4ICAQCrcKpkxAs0kbljIF6wnCH/JXlsV05WRFiD
+uQDOLWWobZU46oItVRhgEn4aHWtiNCzZzRcAQ4Q+rbz/JoUfSqdGE7B9OwvZS52w
+z430BcsSKf7hl8e3x6pTfjktnfbUXreMFWqB0jcaQw7L5jAhQ4NpD+9rzRD5hGDP
+iemIEAGvCfNIuwcJdQGE+rEeURmPxsmFZRZf4FZ+t79AwtTQBR+TY8kkCDuRsjXh
+pI812yRYdTnk3RAasN8TEnOebednPNscHN0Q3cz0Bwm5LuV1bZe3YFuJcIHSJtjG
+CSuyBX/EuBRBHgfwSEFjywyqRX6E+TOzWIe8sdbCZcdXxpXohZCwYlD17hLx2H5z
+y8DDoCUXIzeRumO9hK/zieBRwnM1bWOGIfJzvcJH4E1+RjdL0PdhKseUUCU26K7a
+Lh+4CLJVfGtmQ48CHd2n65gApyV09ZMbbSa7HeW3/CElJtF3G6huqsNLZFF/kQ5B
+XBmDoagflJlDD5nbGNwhb3bRnuqjduDwCby5tPdDbB/TKoZqL+Bs8YM513DbopGr
+VL70R4iM8BDS5K3rfrG6CEtnBKPy6ZArgeN0dj0AndK7/KWgFRwo3xBPR9czRp2y
+V9LGH/vkWUorKKkT3bnpk7SI7uJboAcl/ooueOS04dUd9ho64xwBKh6hhlSeSdzJ
+WeMNbVoTNg==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert45[] = {
+ 0x30, 0x82, 0x05, 0xa3, 0x30, 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x67, 0x3f, 0x33, 0x4f, 0x21, 0x53, 0x36, 0x52, 0xc3,
+ 0x5e, 0x15, 0xd2, 0xfd, 0xb3, 0x02, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x55,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43,
+ 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11,
+ 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69,
+ 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67,
+ 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x38, 0x30, 0x38, 0x30,
+ 0x31, 0x30, 0x30, 0x30, 0x35, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x38,
+ 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x30, 0x35, 0x5a, 0x30, 0x4f, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e,
+ 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57,
+ 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d,
+ 0x69, 0x74, 0x65, 0x64, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x1b, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c,
+ 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x4f, 0x56, 0x20, 0x53, 0x65, 0x72,
+ 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+ 0x01, 0x01, 0x00, 0xbc, 0x89, 0xbe, 0x61, 0x51, 0x53, 0xc8, 0x2b, 0x96,
+ 0x75, 0xb3, 0x5a, 0xd3, 0x0e, 0x34, 0xfe, 0x4a, 0xc2, 0x9f, 0xa3, 0x18,
+ 0x83, 0xa2, 0xac, 0xe3, 0x2e, 0x5e, 0x93, 0x79, 0x0b, 0x13, 0x49, 0x5e,
+ 0x93, 0xb2, 0x8f, 0x84, 0x10, 0xed, 0x91, 0x8f, 0x82, 0xba, 0xad, 0x67,
+ 0xdf, 0x33, 0x1b, 0xae, 0x84, 0xf2, 0x55, 0xb0, 0x5b, 0xf4, 0xb3, 0x9e,
+ 0xbc, 0xe6, 0x04, 0x0f, 0x1d, 0xef, 0x04, 0x5a, 0xa8, 0x0b, 0xec, 0x12,
+ 0x6d, 0x56, 0x19, 0x64, 0x70, 0x49, 0x0f, 0x57, 0x92, 0xf3, 0x5f, 0x21,
+ 0xa6, 0x4d, 0xb4, 0xd2, 0x96, 0x2b, 0x3c, 0x32, 0xb3, 0xef, 0x8f, 0x59,
+ 0x0b, 0x14, 0xba, 0x6e, 0xa2, 0x9e, 0x71, 0xdb, 0xf2, 0x88, 0x3f, 0x28,
+ 0x3b, 0xec, 0xce, 0xbe, 0x47, 0xac, 0x45, 0xc7, 0x8a, 0x9e, 0xfa, 0x61,
+ 0x93, 0xc5, 0x49, 0x17, 0xb6, 0x46, 0xb6, 0xf7, 0x99, 0x16, 0x8c, 0x1c,
+ 0x6e, 0x31, 0xae, 0x69, 0xce, 0xed, 0xc6, 0x24, 0x92, 0x70, 0xa1, 0xcb,
+ 0x96, 0xc3, 0x6c, 0x16, 0xd0, 0xee, 0xcc, 0x4f, 0x86, 0x33, 0xb3, 0x41,
+ 0xe6, 0x3d, 0x3d, 0xdb, 0x0e, 0x8c, 0x33, 0x74, 0xbb, 0xc3, 0xfc, 0x0b,
+ 0xa7, 0xfc, 0xd1, 0x71, 0xe2, 0xc1, 0x0c, 0xd4, 0xf7, 0xba, 0x3e, 0x80,
+ 0x90, 0xd4, 0x48, 0xeb, 0xa2, 0x83, 0x70, 0xd8, 0xdb, 0x30, 0x07, 0x29,
+ 0x89, 0xf9, 0x81, 0x21, 0x2c, 0xff, 0xeb, 0x47, 0xf6, 0x7a, 0x6d, 0x43,
+ 0x96, 0x67, 0x17, 0x3e, 0xf3, 0xe2, 0x73, 0x51, 0xc7, 0x76, 0x1e, 0xe9,
+ 0x1c, 0xa0, 0xec, 0x11, 0x1a, 0xb1, 0xcf, 0x1e, 0x2d, 0x9c, 0x55, 0xee,
+ 0x3b, 0xc6, 0x2d, 0xae, 0xdc, 0x66, 0x65, 0x91, 0xa2, 0x66, 0x9c, 0xac,
+ 0x82, 0xf1, 0xa4, 0x17, 0xb5, 0xd7, 0x43, 0x83, 0xc3, 0x88, 0xa0, 0x64,
+ 0xde, 0xca, 0x72, 0x45, 0xdc, 0x38, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x82, 0x01, 0x73, 0x30, 0x82, 0x01, 0x6f, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
+ 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x12, 0x06, 0x03, 0x55,
+ 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+ 0x02, 0x01, 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29,
+ 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x31, 0x2e, 0x77,
+ 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61,
+ 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x71, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x27, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x31, 0x2e,
+ 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
+ 0x61, 0x31, 0x30, 0x38, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x02, 0x86, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61,
+ 0x69, 0x61, 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x31, 0x2d, 0x63, 0x6c, 0x61, 0x73, 0x73,
+ 0x33, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x63, 0x65, 0x72,
+ 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x62,
+ 0x2e, 0x81, 0xd9, 0xe3, 0x42, 0x79, 0x14, 0xa3, 0xcd, 0xd9, 0x54, 0x8a,
+ 0x6e, 0xf8, 0xde, 0x95, 0xaa, 0x8f, 0x98, 0x30, 0x1f, 0x06, 0x03, 0x55,
+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe1, 0x66, 0xcf, 0x0e,
+ 0xd1, 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14, 0xfe, 0x87, 0x12, 0xd5,
+ 0xf6, 0xfe, 0xfb, 0x3e, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01,
+ 0x82, 0x9b, 0x51, 0x01, 0x03, 0x02, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x73,
+ 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6c, 0x69,
+ 0x63, 0x79, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0xab,
+ 0x70, 0xaa, 0x64, 0xc4, 0x0b, 0x34, 0x91, 0xb9, 0x63, 0x20, 0x5e, 0xb0,
+ 0x9c, 0x21, 0xff, 0x25, 0x79, 0x6c, 0x57, 0x4e, 0x56, 0x44, 0x58, 0x83,
+ 0xb9, 0x00, 0xce, 0x2d, 0x65, 0xa8, 0x6d, 0x95, 0x38, 0xea, 0x82, 0x2d,
+ 0x55, 0x18, 0x60, 0x12, 0x7e, 0x1a, 0x1d, 0x6b, 0x62, 0x34, 0x2c, 0xd9,
+ 0xcd, 0x17, 0x00, 0x43, 0x84, 0x3e, 0xad, 0xbc, 0xff, 0x26, 0x85, 0x1f,
+ 0x4a, 0xa7, 0x46, 0x13, 0xb0, 0x7d, 0x3b, 0x0b, 0xd9, 0x4b, 0x9d, 0xb0,
+ 0xcf, 0x8d, 0xf4, 0x05, 0xcb, 0x12, 0x29, 0xfe, 0xe1, 0x97, 0xc7, 0xb7,
+ 0xc7, 0xaa, 0x53, 0x7e, 0x39, 0x2d, 0x9d, 0xf6, 0xd4, 0x5e, 0xb7, 0x8c,
+ 0x15, 0x6a, 0x81, 0xd2, 0x37, 0x1a, 0x43, 0x0e, 0xcb, 0xe6, 0x30, 0x21,
+ 0x43, 0x83, 0x69, 0x0f, 0xef, 0x6b, 0xcd, 0x10, 0xf9, 0x84, 0x60, 0xcf,
+ 0x89, 0xe9, 0x88, 0x10, 0x01, 0xaf, 0x09, 0xf3, 0x48, 0xbb, 0x07, 0x09,
+ 0x75, 0x01, 0x84, 0xfa, 0xb1, 0x1e, 0x51, 0x19, 0x8f, 0xc6, 0xc9, 0x85,
+ 0x65, 0x16, 0x5f, 0xe0, 0x56, 0x7e, 0xb7, 0xbf, 0x40, 0xc2, 0xd4, 0xd0,
+ 0x05, 0x1f, 0x93, 0x63, 0xc9, 0x24, 0x08, 0x3b, 0x91, 0xb2, 0x35, 0xe1,
+ 0xa4, 0x8f, 0x35, 0xdb, 0x24, 0x58, 0x75, 0x39, 0xe4, 0xdd, 0x10, 0x1a,
+ 0xb0, 0xdf, 0x13, 0x12, 0x73, 0x9e, 0x6d, 0xe7, 0x67, 0x3c, 0xdb, 0x1c,
+ 0x1c, 0xdd, 0x10, 0xdd, 0xcc, 0xf4, 0x07, 0x09, 0xb9, 0x2e, 0xe5, 0x75,
+ 0x6d, 0x97, 0xb7, 0x60, 0x5b, 0x89, 0x70, 0x81, 0xd2, 0x26, 0xd8, 0xc6,
+ 0x09, 0x2b, 0xb2, 0x05, 0x7f, 0xc4, 0xb8, 0x14, 0x41, 0x1e, 0x07, 0xf0,
+ 0x48, 0x41, 0x63, 0xcb, 0x0c, 0xaa, 0x45, 0x7e, 0x84, 0xf9, 0x33, 0xb3,
+ 0x58, 0x87, 0xbc, 0xb1, 0xd6, 0xc2, 0x65, 0xc7, 0x57, 0xc6, 0x95, 0xe8,
+ 0x85, 0x90, 0xb0, 0x62, 0x50, 0xf5, 0xee, 0x12, 0xf1, 0xd8, 0x7e, 0x73,
+ 0xcb, 0xc0, 0xc3, 0xa0, 0x25, 0x17, 0x23, 0x37, 0x91, 0xba, 0x63, 0xbd,
+ 0x84, 0xaf, 0xf3, 0x89, 0xe0, 0x51, 0xc2, 0x73, 0x35, 0x6d, 0x63, 0x86,
+ 0x21, 0xf2, 0x73, 0xbd, 0xc2, 0x47, 0xe0, 0x4d, 0x7e, 0x46, 0x37, 0x4b,
+ 0xd0, 0xf7, 0x61, 0x2a, 0xc7, 0x94, 0x50, 0x25, 0x36, 0xe8, 0xae, 0xda,
+ 0x2e, 0x1f, 0xb8, 0x08, 0xb2, 0x55, 0x7c, 0x6b, 0x66, 0x43, 0x8f, 0x02,
+ 0x1d, 0xdd, 0xa7, 0xeb, 0x98, 0x00, 0xa7, 0x25, 0x74, 0xf5, 0x93, 0x1b,
+ 0x6d, 0x26, 0xbb, 0x1d, 0xe5, 0xb7, 0xfc, 0x21, 0x25, 0x26, 0xd1, 0x77,
+ 0x1b, 0xa8, 0x6e, 0xaa, 0xc3, 0x4b, 0x64, 0x51, 0x7f, 0x91, 0x0e, 0x41,
+ 0x5c, 0x19, 0x83, 0xa1, 0xa8, 0x1f, 0x94, 0x99, 0x43, 0x0f, 0x99, 0xdb,
+ 0x18, 0xdc, 0x21, 0x6f, 0x76, 0xd1, 0x9e, 0xea, 0xa3, 0x76, 0xe0, 0xf0,
+ 0x09, 0xbc, 0xb9, 0xb4, 0xf7, 0x43, 0x6c, 0x1f, 0xd3, 0x2a, 0x86, 0x6a,
+ 0x2f, 0xe0, 0x6c, 0xf1, 0x83, 0x39, 0xd7, 0x70, 0xdb, 0xa2, 0x91, 0xab,
+ 0x54, 0xbe, 0xf4, 0x47, 0x88, 0x8c, 0xf0, 0x10, 0xd2, 0xe4, 0xad, 0xeb,
+ 0x7e, 0xb1, 0xba, 0x08, 0x4b, 0x67, 0x04, 0xa3, 0xf2, 0xe9, 0x90, 0x2b,
+ 0x81, 0xe3, 0x74, 0x76, 0x3d, 0x00, 0x9d, 0xd2, 0xbb, 0xfc, 0xa5, 0xa0,
+ 0x15, 0x1c, 0x28, 0xdf, 0x10, 0x4f, 0x47, 0xd7, 0x33, 0x46, 0x9d, 0xb2,
+ 0x57, 0xd2, 0xc6, 0x1f, 0xfb, 0xe4, 0x59, 0x4a, 0x2b, 0x28, 0xa9, 0x13,
+ 0xdd, 0xb9, 0xe9, 0x93, 0xb4, 0x88, 0xee, 0xe2, 0x5b, 0xa0, 0x07, 0x25,
+ 0xfe, 0x8a, 0x2e, 0x78, 0xe4, 0xb4, 0xe1, 0xd5, 0x1d, 0xf6, 0x1a, 0x3a,
+ 0xe3, 0x1c, 0x01, 0x2a, 0x1e, 0xa1, 0x86, 0x54, 0x9e, 0x49, 0xdc, 0xc9,
+ 0x59, 0xe3, 0x0d, 0x6d, 0x5a, 0x13, 0x36,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 120040007 (0x727aa47)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
+ Validity
+ Not Before: May 7 17:04:09 2014 GMT
+ Not After : May 7 17:03:30 2018 GMT
+ Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24:
+ 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72:
+ 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88:
+ 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1:
+ d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03:
+ e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42:
+ f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe:
+ 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29:
+ e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18:
+ 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51:
+ af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41:
+ 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a:
+ 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a:
+ 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94:
+ 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67:
+ 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae:
+ ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be:
+ ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34:
+ 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f:
+ e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29:
+ 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d:
+ 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08:
+ 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf:
+ ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2:
+ 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08:
+ 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0:
+ 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70:
+ 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7:
+ d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09:
+ c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18:
+ 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33:
+ a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13:
+ 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01:
+ a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41:
+ 4a:a8:fb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.6334.1.0
+ CPS: http://cybertrust.omniroot.com/repository.cfm
+ Policy: 1.3.6.1.4.1.311.42.1
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.omniroot.com/baltimoreroot
+
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication, OCSP Signing
+ X509v3 Authority Key Identifier:
+ keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl
+
+ X509v3 Subject Key Identifier:
+ 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5
+ Signature Algorithm: sha256WithRSAEncryption
+ 69:62:f6:84:91:00:c4:6f:82:7b:24:e1:42:a2:a5:8b:82:5c:
+ a7:c5:44:cb:e7:52:76:63:d3:76:9e:78:e2:69:35:b1:38:ba:
+ b0:96:c6:1f:ac:7b:c6:b2:65:77:8b:7d:8d:ae:64:b9:a5:8c:
+ 17:ca:58:65:c3:ad:82:f5:c5:a2:f5:01:13:93:c6:7e:44:e5:
+ c4:61:fa:03:b6:56:c1:72:e1:c8:28:c5:69:21:8f:ac:6e:fd:
+ 7f:43:83:36:b8:c0:d6:a0:28:fe:1a:45:be:fd:93:8c:8d:a4:
+ 64:79:1f:14:db:a1:9f:21:dc:c0:4e:7b:17:22:17:b1:b6:3c:
+ d3:9b:e2:0a:a3:7e:99:b0:c1:ac:d8:f4:86:df:3c:da:7d:14:
+ 9c:40:c1:7c:d2:18:6f:f1:4f:26:45:09:95:94:5c:da:d0:98:
+ f8:f4:4c:82:96:10:de:ac:30:cb:2b:ae:f9:92:ea:bf:79:03:
+ fc:1e:3f:ac:09:a4:3f:65:fd:91:4f:96:24:a7:ce:b4:4e:6a:
+ 96:29:17:ae:c0:a8:df:17:22:f4:17:e3:dc:1c:39:06:56:10:
+ ea:ea:b5:74:17:3c:4e:dd:7e:91:0a:a8:0b:78:07:a7:31:44:
+ 08:31:ab:18:84:0f:12:9c:e7:de:84:2c:e9:6d:93:45:bf:a8:
+ c1:3f:34:dc
+-----BEGIN CERTIFICATE-----
+MIIF4TCCBMmgAwIBAgIEByeqRzANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDUwNzE3MDQwOVoX
+DTE4MDUwNzE3MDMzMFowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
+dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
+YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0
+IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3
+p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu
+e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA
+iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R
+PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg
+lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU
+mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R
+DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV
+S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq
+qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE
+OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o
+/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCAXswggF3MBIGA1Ud
+EwEB/wQIMAYBAf8CAQAwYAYDVR0gBFkwVzBIBgkrBgEEAbE+AQAwOzA5BggrBgEF
+BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku
+Y2ZtMAsGCSsGAQQBgjcqATBCBggrBgEFBQcBAQQ2MDQwMgYIKwYBBQUHMAGGJmh0
+dHA6Ly9vY3NwLm9tbmlyb290LmNvbS9iYWx0aW1vcmVyb290MA4GA1UdDwEB/wQE
+AwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMJMB8G
+A1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaGezq1BE3wMEIGA1UdHwQ7MDkwN6A1oDOG
+MWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVzdC5jb20vQ1JML09tbmlyb290MjAyNS5j
+cmwwHQYDVR0OBBYEFFGvJCac9GgiV4AmKztGYhV7HsylMA0GCSqGSIb3DQEBCwUA
+A4IBAQBpYvaEkQDEb4J7JOFCoqWLglynxUTL51J2Y9N2nnjiaTWxOLqwlsYfrHvG
+smV3i32NrmS5pYwXylhlw62C9cWi9QETk8Z+ROXEYfoDtlbBcuHIKMVpIY+sbv1/
+Q4M2uMDWoCj+GkW+/ZOMjaRkeR8U26GfIdzATnsXIhextjzTm+IKo36ZsMGs2PSG
+3zzafRScQMF80hhv8U8mRQmVlFza0Jj49EyClhDerDDLK675kuq/eQP8Hj+sCaQ/
+Zf2RT5Ykp860TmqWKReuwKjfFyL0F+PcHDkGVhDq6rV0FzxO3X6RCqgLeAenMUQI
+MasYhA8SnOfehCzpbZNFv6jBPzTc
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert46[] = {
+ 0x30, 0x82, 0x05, 0xe1, 0x30, 0x82, 0x04, 0xc9, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x04, 0x07, 0x27, 0xaa, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49,
+ 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09,
+ 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30,
+ 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65,
+ 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f,
+ 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34,
+ 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x34, 0x30, 0x39, 0x5a, 0x17,
+ 0x0d, 0x31, 0x38, 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x33, 0x33,
+ 0x30, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+ 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
+ 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
+ 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30,
+ 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72,
+ 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
+ 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
+ 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
+ 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32,
+ 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
+ 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37,
+ 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37,
+ 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d,
+ 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10,
+ 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae,
+ 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30,
+ 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2,
+ 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77,
+ 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0,
+ 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9,
+ 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09,
+ 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57,
+ 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1,
+ 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb,
+ 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8,
+ 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21,
+ 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60,
+ 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb,
+ 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4,
+ 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a,
+ 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14,
+ 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae,
+ 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca,
+ 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99,
+ 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11,
+ 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b,
+ 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57,
+ 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02,
+ 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5,
+ 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c,
+ 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb,
+ 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90,
+ 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa,
+ 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d,
+ 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae,
+ 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86,
+ 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4,
+ 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a,
+ 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6,
+ 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8,
+ 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68,
+ 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0,
+ 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10,
+ 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+ 0x01, 0x7b, 0x30, 0x82, 0x01, 0x77, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
+ 0x01, 0x00, 0x30, 0x60, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x59, 0x30,
+ 0x57, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e,
+ 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e,
+ 0x63, 0x66, 0x6d, 0x30, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
+ 0x82, 0x37, 0x2a, 0x01, 0x30, 0x42, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x01, 0x01, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x26, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x6f, 0x6d,
+ 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62,
+ 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74,
+ 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04,
+ 0x03, 0x02, 0x01, 0x86, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
+ 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+ 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d,
+ 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86,
+ 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d,
+ 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86,
+ 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31,
+ 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d,
+ 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63,
+ 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4, 0x68, 0x22, 0x57, 0x80, 0x26,
+ 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e, 0xcc, 0xa5, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x62, 0xf6, 0x84, 0x91, 0x00, 0xc4,
+ 0x6f, 0x82, 0x7b, 0x24, 0xe1, 0x42, 0xa2, 0xa5, 0x8b, 0x82, 0x5c, 0xa7,
+ 0xc5, 0x44, 0xcb, 0xe7, 0x52, 0x76, 0x63, 0xd3, 0x76, 0x9e, 0x78, 0xe2,
+ 0x69, 0x35, 0xb1, 0x38, 0xba, 0xb0, 0x96, 0xc6, 0x1f, 0xac, 0x7b, 0xc6,
+ 0xb2, 0x65, 0x77, 0x8b, 0x7d, 0x8d, 0xae, 0x64, 0xb9, 0xa5, 0x8c, 0x17,
+ 0xca, 0x58, 0x65, 0xc3, 0xad, 0x82, 0xf5, 0xc5, 0xa2, 0xf5, 0x01, 0x13,
+ 0x93, 0xc6, 0x7e, 0x44, 0xe5, 0xc4, 0x61, 0xfa, 0x03, 0xb6, 0x56, 0xc1,
+ 0x72, 0xe1, 0xc8, 0x28, 0xc5, 0x69, 0x21, 0x8f, 0xac, 0x6e, 0xfd, 0x7f,
+ 0x43, 0x83, 0x36, 0xb8, 0xc0, 0xd6, 0xa0, 0x28, 0xfe, 0x1a, 0x45, 0xbe,
+ 0xfd, 0x93, 0x8c, 0x8d, 0xa4, 0x64, 0x79, 0x1f, 0x14, 0xdb, 0xa1, 0x9f,
+ 0x21, 0xdc, 0xc0, 0x4e, 0x7b, 0x17, 0x22, 0x17, 0xb1, 0xb6, 0x3c, 0xd3,
+ 0x9b, 0xe2, 0x0a, 0xa3, 0x7e, 0x99, 0xb0, 0xc1, 0xac, 0xd8, 0xf4, 0x86,
+ 0xdf, 0x3c, 0xda, 0x7d, 0x14, 0x9c, 0x40, 0xc1, 0x7c, 0xd2, 0x18, 0x6f,
+ 0xf1, 0x4f, 0x26, 0x45, 0x09, 0x95, 0x94, 0x5c, 0xda, 0xd0, 0x98, 0xf8,
+ 0xf4, 0x4c, 0x82, 0x96, 0x10, 0xde, 0xac, 0x30, 0xcb, 0x2b, 0xae, 0xf9,
+ 0x92, 0xea, 0xbf, 0x79, 0x03, 0xfc, 0x1e, 0x3f, 0xac, 0x09, 0xa4, 0x3f,
+ 0x65, 0xfd, 0x91, 0x4f, 0x96, 0x24, 0xa7, 0xce, 0xb4, 0x4e, 0x6a, 0x96,
+ 0x29, 0x17, 0xae, 0xc0, 0xa8, 0xdf, 0x17, 0x22, 0xf4, 0x17, 0xe3, 0xdc,
+ 0x1c, 0x39, 0x06, 0x56, 0x10, 0xea, 0xea, 0xb5, 0x74, 0x17, 0x3c, 0x4e,
+ 0xdd, 0x7e, 0x91, 0x0a, 0xa8, 0x0b, 0x78, 0x07, 0xa7, 0x31, 0x44, 0x08,
+ 0x31, 0xab, 0x18, 0x84, 0x0f, 0x12, 0x9c, 0xe7, 0xde, 0x84, 0x2c, 0xe9,
+ 0x6d, 0x93, 0x45, 0xbf, 0xa8, 0xc1, 0x3f, 0x34, 0xdc,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 6e:cc:7a:a5:a7:03:20:09:b8:ce:bc:f4:e9:52:d4:91
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Validity
+ Not Before: Feb 8 00:00:00 2010 GMT
+ Not After : Feb 7 23:59:59 2020 GMT
+ Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 Secure Server CA - G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b1:87:84:1f:c2:0c:45:f5:bc:ab:25:97:a7:ad:
+ a2:3e:9c:ba:f6:c1:39:b8:8b:ca:c2:ac:56:c6:e5:
+ bb:65:8e:44:4f:4d:ce:6f:ed:09:4a:d4:af:4e:10:
+ 9c:68:8b:2e:95:7b:89:9b:13:ca:e2:34:34:c1:f3:
+ 5b:f3:49:7b:62:83:48:81:74:d1:88:78:6c:02:53:
+ f9:bc:7f:43:26:57:58:33:83:3b:33:0a:17:b0:d0:
+ 4e:91:24:ad:86:7d:64:12:dc:74:4a:34:a1:1d:0a:
+ ea:96:1d:0b:15:fc:a3:4b:3b:ce:63:88:d0:f8:2d:
+ 0c:94:86:10:ca:b6:9a:3d:ca:eb:37:9c:00:48:35:
+ 86:29:50:78:e8:45:63:cd:19:41:4f:f5:95:ec:7b:
+ 98:d4:c4:71:b3:50:be:28:b3:8f:a0:b9:53:9c:f5:
+ ca:2c:23:a9:fd:14:06:e8:18:b4:9a:e8:3c:6e:81:
+ fd:e4:cd:35:36:b3:51:d3:69:ec:12:ba:56:6e:6f:
+ 9b:57:c5:8b:14:e7:0e:c7:9c:ed:4a:54:6a:c9:4d:
+ c5:bf:11:b1:ae:1c:67:81:cb:44:55:33:99:7f:24:
+ 9b:3f:53:45:7f:86:1a:f3:3c:fa:6d:7f:81:f5:b8:
+ 4a:d3:f5:85:37:1c:b5:a6:d0:09:e4:18:7b:38:4e:
+ fa:0f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ Authority Information Access:
+ OCSP - URI:http://ocsp.verisign.com
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.23.3
+ CPS: https://www.verisign.com/cps
+ User Notice:
+ Explicit Text: https://www.verisign.com/rpa
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.verisign.com/pca3-g5.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ 1.3.6.1.5.5.7.1.12:
+ 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
+ X509v3 Subject Alternative Name:
+ DirName:/CN=VeriSignMPKI-2-6
+ X509v3 Subject Key Identifier:
+ 0D:44:5C:16:53:44:C1:82:7E:1D:20:AB:25:F4:01:63:D8:BE:79:A5
+ X509v3 Authority Key Identifier:
+ keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 0c:83:24:ef:dd:c3:0c:d9:58:9c:fe:36:b6:eb:8a:80:4b:d1:
+ a3:f7:9d:f3:cc:53:ef:82:9e:a3:a1:e6:97:c1:58:9d:75:6c:
+ e0:1d:1b:4c:fa:d1:c1:2d:05:c0:ea:6e:b2:22:70:55:d9:20:
+ 33:40:33:07:c2:65:83:fa:8f:43:37:9b:ea:0e:9a:6c:70:ee:
+ f6:9c:80:3b:d9:37:f4:7a:6d:ec:d0:18:7d:49:4a:ca:99:c7:
+ 19:28:a2:be:d8:77:24:f7:85:26:86:6d:87:05:40:41:67:d1:
+ 27:3a:ed:dc:48:1d:22:cd:0b:0b:8b:bc:f4:b1:7b:fd:b4:99:
+ a8:e9:76:2a:e1:1a:2d:87:6e:74:d3:88:dd:1e:22:c6:df:16:
+ b6:2b:82:14:0a:94:5c:f2:50:ec:af:ce:ff:62:37:0d:ad:65:
+ d3:06:41:53:ed:02:14:c8:b5:58:28:a1:ac:e0:5b:ec:b3:7f:
+ 95:4a:fb:03:c8:ad:26:db:e6:66:78:12:4a:d9:9f:42:fb:e1:
+ 98:e6:42:83:9b:8f:8f:67:24:e8:61:19:b5:dd:cd:b5:0b:26:
+ 05:8e:c3:6e:c4:c8:75:b8:46:cf:e2:18:06:5e:a9:ae:a8:81:
+ 9a:47:16:de:0c:28:6c:25:27:b9:de:b7:84:58:c6:1f:38:1e:
+ a4:c4:cb:66
+-----BEGIN CERTIFICATE-----
+MIIF7DCCBNSgAwIBAgIQbsx6pacDIAm4zrz06VLUkTANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBtTEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
+aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMmVmVy
+aVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCxh4QfwgxF9byrJZenraI+nLr2wTm4i8rCrFbG
+5btljkRPTc5v7QlK1K9OEJxoiy6Ve4mbE8riNDTB81vzSXtig0iBdNGIeGwCU/m8
+f0MmV1gzgzszChew0E6RJK2GfWQS3HRKNKEdCuqWHQsV/KNLO85jiND4LQyUhhDK
+tpo9yus3nABINYYpUHjoRWPNGUFP9ZXse5jUxHGzUL4os4+guVOc9cosI6n9FAbo
+GLSa6Dxugf3kzTU2s1HTaewSulZub5tXxYsU5w7HnO1KVGrJTcW/EbGuHGeBy0RV
+M5l/JJs/U0V/hhrzPPptf4H1uErT9YU3HLWm0AnkGHs4TvoPAgMBAAGjggHfMIIB
+2zA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlz
+aWduLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4
+RQEHFwMwVjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nw
+czAqBggrBgEFBQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQG
+A1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUu
+Y3JsMA4GA1UdDwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglp
+bWFnZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNo
+dHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjAoBgNVHREEITAfpB0w
+GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItNjAdBgNVHQ4EFgQUDURcFlNEwYJ+
+HSCrJfQBY9i+eaUwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJ
+KoZIhvcNAQEFBQADggEBAAyDJO/dwwzZWJz+NrbrioBL0aP3nfPMU++CnqOh5pfB
+WJ11bOAdG0z60cEtBcDqbrIicFXZIDNAMwfCZYP6j0M3m+oOmmxw7vacgDvZN/R6
+bezQGH1JSsqZxxkoor7YdyT3hSaGbYcFQEFn0Sc67dxIHSLNCwuLvPSxe/20majp
+dirhGi2HbnTTiN0eIsbfFrYrghQKlFzyUOyvzv9iNw2tZdMGQVPtAhTItVgooazg
+W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4
+Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert47[] = {
+ 0x30, 0x82, 0x05, 0xec, 0x30, 0x82, 0x04, 0xd4, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x6e, 0xcc, 0x7a, 0xa5, 0xa7, 0x03, 0x20, 0x09, 0xb8,
+ 0xce, 0xbc, 0xf4, 0xe9, 0x52, 0xd4, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+ 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+ 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
+ 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
+ 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+ 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
+ 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x32, 0x30, 0x37,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
+ 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30,
+ 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d,
+ 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
+ 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x31, 0x30, 0x31, 0x2f,
+ 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x56, 0x65, 0x72,
+ 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+ 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
+ 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30,
+ 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+ 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb1, 0x87, 0x84, 0x1f,
+ 0xc2, 0x0c, 0x45, 0xf5, 0xbc, 0xab, 0x25, 0x97, 0xa7, 0xad, 0xa2, 0x3e,
+ 0x9c, 0xba, 0xf6, 0xc1, 0x39, 0xb8, 0x8b, 0xca, 0xc2, 0xac, 0x56, 0xc6,
+ 0xe5, 0xbb, 0x65, 0x8e, 0x44, 0x4f, 0x4d, 0xce, 0x6f, 0xed, 0x09, 0x4a,
+ 0xd4, 0xaf, 0x4e, 0x10, 0x9c, 0x68, 0x8b, 0x2e, 0x95, 0x7b, 0x89, 0x9b,
+ 0x13, 0xca, 0xe2, 0x34, 0x34, 0xc1, 0xf3, 0x5b, 0xf3, 0x49, 0x7b, 0x62,
+ 0x83, 0x48, 0x81, 0x74, 0xd1, 0x88, 0x78, 0x6c, 0x02, 0x53, 0xf9, 0xbc,
+ 0x7f, 0x43, 0x26, 0x57, 0x58, 0x33, 0x83, 0x3b, 0x33, 0x0a, 0x17, 0xb0,
+ 0xd0, 0x4e, 0x91, 0x24, 0xad, 0x86, 0x7d, 0x64, 0x12, 0xdc, 0x74, 0x4a,
+ 0x34, 0xa1, 0x1d, 0x0a, 0xea, 0x96, 0x1d, 0x0b, 0x15, 0xfc, 0xa3, 0x4b,
+ 0x3b, 0xce, 0x63, 0x88, 0xd0, 0xf8, 0x2d, 0x0c, 0x94, 0x86, 0x10, 0xca,
+ 0xb6, 0x9a, 0x3d, 0xca, 0xeb, 0x37, 0x9c, 0x00, 0x48, 0x35, 0x86, 0x29,
+ 0x50, 0x78, 0xe8, 0x45, 0x63, 0xcd, 0x19, 0x41, 0x4f, 0xf5, 0x95, 0xec,
+ 0x7b, 0x98, 0xd4, 0xc4, 0x71, 0xb3, 0x50, 0xbe, 0x28, 0xb3, 0x8f, 0xa0,
+ 0xb9, 0x53, 0x9c, 0xf5, 0xca, 0x2c, 0x23, 0xa9, 0xfd, 0x14, 0x06, 0xe8,
+ 0x18, 0xb4, 0x9a, 0xe8, 0x3c, 0x6e, 0x81, 0xfd, 0xe4, 0xcd, 0x35, 0x36,
+ 0xb3, 0x51, 0xd3, 0x69, 0xec, 0x12, 0xba, 0x56, 0x6e, 0x6f, 0x9b, 0x57,
+ 0xc5, 0x8b, 0x14, 0xe7, 0x0e, 0xc7, 0x9c, 0xed, 0x4a, 0x54, 0x6a, 0xc9,
+ 0x4d, 0xc5, 0xbf, 0x11, 0xb1, 0xae, 0x1c, 0x67, 0x81, 0xcb, 0x44, 0x55,
+ 0x33, 0x99, 0x7f, 0x24, 0x9b, 0x3f, 0x53, 0x45, 0x7f, 0x86, 0x1a, 0xf3,
+ 0x3c, 0xfa, 0x6d, 0x7f, 0x81, 0xf5, 0xb8, 0x4a, 0xd3, 0xf5, 0x85, 0x37,
+ 0x1c, 0xb5, 0xa6, 0xd0, 0x09, 0xe4, 0x18, 0x7b, 0x38, 0x4e, 0xfa, 0x0f,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01,
+ 0xdb, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
+ 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+ 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55,
+ 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+ 0x02, 0x01, 0x00, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x69,
+ 0x30, 0x67, 0x30, 0x65, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+ 0x45, 0x01, 0x07, 0x17, 0x03, 0x30, 0x56, 0x30, 0x28, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74,
+ 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
+ 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70,
+ 0x73, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
+ 0x02, 0x30, 0x1e, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
+ 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x34, 0x06,
+ 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27,
+ 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+ 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1,
+ 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69,
+ 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f,
+ 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f,
+ 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a,
+ 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76,
+ 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x28,
+ 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30,
+ 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10,
+ 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49,
+ 0x2d, 0x32, 0x2d, 0x36, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0x0d, 0x44, 0x5c, 0x16, 0x53, 0x44, 0xc1, 0x82, 0x7e,
+ 0x1d, 0x20, 0xab, 0x25, 0xf4, 0x01, 0x63, 0xd8, 0xbe, 0x79, 0xa5, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3,
+ 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x0c, 0x83, 0x24, 0xef, 0xdd, 0xc3, 0x0c, 0xd9,
+ 0x58, 0x9c, 0xfe, 0x36, 0xb6, 0xeb, 0x8a, 0x80, 0x4b, 0xd1, 0xa3, 0xf7,
+ 0x9d, 0xf3, 0xcc, 0x53, 0xef, 0x82, 0x9e, 0xa3, 0xa1, 0xe6, 0x97, 0xc1,
+ 0x58, 0x9d, 0x75, 0x6c, 0xe0, 0x1d, 0x1b, 0x4c, 0xfa, 0xd1, 0xc1, 0x2d,
+ 0x05, 0xc0, 0xea, 0x6e, 0xb2, 0x22, 0x70, 0x55, 0xd9, 0x20, 0x33, 0x40,
+ 0x33, 0x07, 0xc2, 0x65, 0x83, 0xfa, 0x8f, 0x43, 0x37, 0x9b, 0xea, 0x0e,
+ 0x9a, 0x6c, 0x70, 0xee, 0xf6, 0x9c, 0x80, 0x3b, 0xd9, 0x37, 0xf4, 0x7a,
+ 0x6d, 0xec, 0xd0, 0x18, 0x7d, 0x49, 0x4a, 0xca, 0x99, 0xc7, 0x19, 0x28,
+ 0xa2, 0xbe, 0xd8, 0x77, 0x24, 0xf7, 0x85, 0x26, 0x86, 0x6d, 0x87, 0x05,
+ 0x40, 0x41, 0x67, 0xd1, 0x27, 0x3a, 0xed, 0xdc, 0x48, 0x1d, 0x22, 0xcd,
+ 0x0b, 0x0b, 0x8b, 0xbc, 0xf4, 0xb1, 0x7b, 0xfd, 0xb4, 0x99, 0xa8, 0xe9,
+ 0x76, 0x2a, 0xe1, 0x1a, 0x2d, 0x87, 0x6e, 0x74, 0xd3, 0x88, 0xdd, 0x1e,
+ 0x22, 0xc6, 0xdf, 0x16, 0xb6, 0x2b, 0x82, 0x14, 0x0a, 0x94, 0x5c, 0xf2,
+ 0x50, 0xec, 0xaf, 0xce, 0xff, 0x62, 0x37, 0x0d, 0xad, 0x65, 0xd3, 0x06,
+ 0x41, 0x53, 0xed, 0x02, 0x14, 0xc8, 0xb5, 0x58, 0x28, 0xa1, 0xac, 0xe0,
+ 0x5b, 0xec, 0xb3, 0x7f, 0x95, 0x4a, 0xfb, 0x03, 0xc8, 0xad, 0x26, 0xdb,
+ 0xe6, 0x66, 0x78, 0x12, 0x4a, 0xd9, 0x9f, 0x42, 0xfb, 0xe1, 0x98, 0xe6,
+ 0x42, 0x83, 0x9b, 0x8f, 0x8f, 0x67, 0x24, 0xe8, 0x61, 0x19, 0xb5, 0xdd,
+ 0xcd, 0xb5, 0x0b, 0x26, 0x05, 0x8e, 0xc3, 0x6e, 0xc4, 0xc8, 0x75, 0xb8,
+ 0x46, 0xcf, 0xe2, 0x18, 0x06, 0x5e, 0xa9, 0xae, 0xa8, 0x81, 0x9a, 0x47,
+ 0x16, 0xde, 0x0c, 0x28, 0x6c, 0x25, 0x27, 0xb9, 0xde, 0xb7, 0x84, 0x58,
+ 0xc6, 0x1f, 0x38, 0x1e, 0xa4, 0xc4, 0xcb, 0x66,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 2c:48:dd:93:0d:f5:59:8e:f9:3c:99:54:7a:60:ed:43
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Validity
+ Not Before: Nov 8 00:00:00 2006 GMT
+ Not After : Nov 7 23:59:59 2016 GMT
+ Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)06, CN=VeriSign Class 3 Extended Validation SSL SGC CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bd:56:88:ba:88:34:64:64:cf:cd:ca:b0:ee:e7:
+ 19:73:c5:72:d9:bb:45:bc:b5:a8:ff:83:be:1c:03:
+ db:ed:89:b7:2e:10:1a:25:bc:55:ca:41:a1:9f:0b:
+ cf:19:5e:70:b9:5e:39:4b:9e:31:1c:5f:87:ae:2a:
+ aa:a8:2b:a2:1b:3b:10:23:5f:13:b1:dd:08:8c:4e:
+ 14:da:83:81:e3:b5:8c:e3:68:ed:24:67:ce:56:b6:
+ ac:9b:73:96:44:db:8a:8c:b3:d6:f0:71:93:8e:db:
+ 71:54:4a:eb:73:59:6a:8f:70:51:2c:03:9f:97:d1:
+ cc:11:7a:bc:62:0d:95:2a:c9:1c:75:57:e9:f5:c7:
+ ea:ba:84:35:cb:c7:85:5a:7e:e4:4d:e1:11:97:7d:
+ 0e:20:34:45:db:f1:a2:09:eb:eb:3d:9e:b8:96:43:
+ 5e:34:4b:08:25:1e:43:1a:a2:d9:b7:8a:01:34:3d:
+ c3:f8:e5:af:4f:8c:ff:cd:65:f0:23:4e:c5:97:b3:
+ 5c:da:90:1c:82:85:0d:06:0d:c1:22:b6:7b:28:a4:
+ 03:c3:4c:53:d1:58:bc:72:bc:08:39:fc:a0:76:a8:
+ a8:e9:4b:6e:88:3d:e3:b3:31:25:8c:73:29:48:0e:
+ 32:79:06:ed:3d:43:f4:f6:e4:e9:fc:7d:be:8e:08:
+ d5:1f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 4E:43:C8:1D:76:EF:37:53:7A:4F:F2:58:6F:94:F3:38:E2:D5:BD:DF
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://www.verisign.com/cps
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://EVSecure-crl.verisign.com/pca3-g5.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Netscape Cert Type:
+ SSL CA, S/MIME CA
+ 1.3.6.1.5.5.7.1.12:
+ 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
+ X509v3 Subject Alternative Name:
+ DirName:/CN=Class3CA2048-1-48
+ X509v3 Authority Key Identifier:
+ keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+
+ Authority Information Access:
+ OCSP - URI:http://EVSecure-ocsp.verisign.com
+
+ X509v3 Extended Key Usage:
+ Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1, TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha1WithRSAEncryption
+ 27:74:a6:34:ea:1d:9d:e1:53:d6:1c:9d:0c:a7:5b:4c:a9:67:
+ f2:f0:32:b7:01:0f:fb:42:18:38:de:e4:ee:49:c8:13:c9:0b:
+ ec:04:c3:40:71:18:72:76:43:02:23:5d:ab:7b:c8:48:14:1a:
+ c8:7b:1d:fc:f6:0a:9f:36:a1:d2:09:73:71:66:96:75:51:34:
+ bf:99:30:51:67:9d:54:b7:26:45:ac:73:08:23:86:26:99:71:
+ f4:8e:d7:ea:39:9b:06:09:23:bf:62:dd:a8:c4:b6:7d:a4:89:
+ 07:3e:f3:6d:ae:40:59:50:79:97:37:3d:32:78:7d:b2:63:4b:
+ f9:ea:08:69:0e:13:ed:e8:cf:bb:ac:05:86:ca:22:cf:88:62:
+ 5d:3c:22:49:d8:63:d5:24:a6:bd:ef:5c:e3:cc:20:3b:22:ea:
+ fc:44:c6:a8:e5:1f:e1:86:cd:0c:4d:8f:93:53:d9:7f:ee:a1:
+ 08:a7:b3:30:96:49:70:6e:a3:6c:3d:d0:63:ef:25:66:63:cc:
+ aa:b7:18:17:4e:ea:70:76:f6:ba:42:a6:80:37:09:4e:9f:66:
+ 88:2e:6b:33:66:c8:c0:71:a4:41:eb:5a:e3:fc:14:2e:4b:88:
+ fd:ae:6e:5b:65:e9:27:e4:bf:e4:b0:23:c1:b2:7d:5b:62:25:
+ d7:3e:10:d4
+-----BEGIN CERTIFICATE-----
+MIIGHjCCBQagAwIBAgIQLEjdkw31WY75PJlUemDtQzANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMTYxMTA3MjM1OTU5WjCBvjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
+aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMvVmVy
+aVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9Voi6iDRkZM/NyrDu5xlzxXLZ
+u0W8taj/g74cA9vtibcuEBolvFXKQaGfC88ZXnC5XjlLnjEcX4euKqqoK6IbOxAj
+XxOx3QiMThTag4HjtYzjaO0kZ85Wtqybc5ZE24qMs9bwcZOO23FUSutzWWqPcFEs
+A5+X0cwRerxiDZUqyRx1V+n1x+q6hDXLx4VafuRN4RGXfQ4gNEXb8aIJ6+s9nriW
+Q140SwglHkMaotm3igE0PcP45a9PjP/NZfAjTsWXs1zakByChQ0GDcEitnsopAPD
+TFPRWLxyvAg5/KB2qKjpS26IPeOzMSWMcylIDjJ5Bu09Q/T25On8fb6OCNUfAgMB
+AAGjggIIMIICBDAdBgNVHQ4EFgQUTkPIHXbvN1N6T/JYb5TzOOLVvd8wEgYDVR0T
+AQH/BAgwBgEB/wIBADA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYc
+aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2NwczA9BgNVHR8ENjA0MDKgMKAuhixo
+dHRwOi8vRVZTZWN1cmUtY3JsLnZlcmlzaWduLmNvbS9wY2EzLWc1LmNybDAOBgNV
+HQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgEGMG0GCCsGAQUFBwEMBGEwX6Fd
+oFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrU
+SBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMCkG
+A1UdEQQiMCCkHjAcMRowGAYDVQQDExFDbGFzczNDQTIwNDgtMS00ODAfBgNVHSME
+GDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzA9BggrBgEFBQcBAQQxMC8wLQYIKwYB
+BQUHMAGGIWh0dHA6Ly9FVlNlY3VyZS1vY3NwLnZlcmlzaWduLmNvbTA0BgNVHSUE
+LTArBglghkgBhvhCBAEGCmCGSAGG+EUBCAEGCCsGAQUFBwMBBggrBgEFBQcDAjAN
+BgkqhkiG9w0BAQUFAAOCAQEAJ3SmNOodneFT1hydDKdbTKln8vAytwEP+0IYON7k
+7knIE8kL7ATDQHEYcnZDAiNdq3vISBQayHsd/PYKnzah0glzcWaWdVE0v5kwUWed
+VLcmRaxzCCOGJplx9I7X6jmbBgkjv2LdqMS2faSJBz7zba5AWVB5lzc9Mnh9smNL
++eoIaQ4T7ejPu6wFhsoiz4hiXTwiSdhj1SSmve9c48wgOyLq/ETGqOUf4YbNDE2P
+k1PZf+6hCKezMJZJcG6jbD3QY+8lZmPMqrcYF07qcHb2ukKmgDcJTp9miC5rM2bI
+wHGkQeta4/wULkuI/a5uW2XpJ+S/5LAjwbJ9W2Il1z4Q1A==
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert48[] = {
+ 0x30, 0x82, 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x2c, 0x48, 0xdd, 0x93, 0x0d, 0xf5, 0x59, 0x8e, 0xf9,
+ 0x3c, 0x99, 0x54, 0x7a, 0x60, 0xed, 0x43, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+ 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+ 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
+ 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
+ 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+ 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
+ 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x30, 0x37,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xbe, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
+ 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30,
+ 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d,
+ 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
+ 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x36, 0x31, 0x38,
+ 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2f, 0x56, 0x65, 0x72,
+ 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+ 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56,
+ 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x53,
+ 0x4c, 0x20, 0x53, 0x47, 0x43, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0x56, 0x88, 0xba, 0x88, 0x34, 0x64,
+ 0x64, 0xcf, 0xcd, 0xca, 0xb0, 0xee, 0xe7, 0x19, 0x73, 0xc5, 0x72, 0xd9,
+ 0xbb, 0x45, 0xbc, 0xb5, 0xa8, 0xff, 0x83, 0xbe, 0x1c, 0x03, 0xdb, 0xed,
+ 0x89, 0xb7, 0x2e, 0x10, 0x1a, 0x25, 0xbc, 0x55, 0xca, 0x41, 0xa1, 0x9f,
+ 0x0b, 0xcf, 0x19, 0x5e, 0x70, 0xb9, 0x5e, 0x39, 0x4b, 0x9e, 0x31, 0x1c,
+ 0x5f, 0x87, 0xae, 0x2a, 0xaa, 0xa8, 0x2b, 0xa2, 0x1b, 0x3b, 0x10, 0x23,
+ 0x5f, 0x13, 0xb1, 0xdd, 0x08, 0x8c, 0x4e, 0x14, 0xda, 0x83, 0x81, 0xe3,
+ 0xb5, 0x8c, 0xe3, 0x68, 0xed, 0x24, 0x67, 0xce, 0x56, 0xb6, 0xac, 0x9b,
+ 0x73, 0x96, 0x44, 0xdb, 0x8a, 0x8c, 0xb3, 0xd6, 0xf0, 0x71, 0x93, 0x8e,
+ 0xdb, 0x71, 0x54, 0x4a, 0xeb, 0x73, 0x59, 0x6a, 0x8f, 0x70, 0x51, 0x2c,
+ 0x03, 0x9f, 0x97, 0xd1, 0xcc, 0x11, 0x7a, 0xbc, 0x62, 0x0d, 0x95, 0x2a,
+ 0xc9, 0x1c, 0x75, 0x57, 0xe9, 0xf5, 0xc7, 0xea, 0xba, 0x84, 0x35, 0xcb,
+ 0xc7, 0x85, 0x5a, 0x7e, 0xe4, 0x4d, 0xe1, 0x11, 0x97, 0x7d, 0x0e, 0x20,
+ 0x34, 0x45, 0xdb, 0xf1, 0xa2, 0x09, 0xeb, 0xeb, 0x3d, 0x9e, 0xb8, 0x96,
+ 0x43, 0x5e, 0x34, 0x4b, 0x08, 0x25, 0x1e, 0x43, 0x1a, 0xa2, 0xd9, 0xb7,
+ 0x8a, 0x01, 0x34, 0x3d, 0xc3, 0xf8, 0xe5, 0xaf, 0x4f, 0x8c, 0xff, 0xcd,
+ 0x65, 0xf0, 0x23, 0x4e, 0xc5, 0x97, 0xb3, 0x5c, 0xda, 0x90, 0x1c, 0x82,
+ 0x85, 0x0d, 0x06, 0x0d, 0xc1, 0x22, 0xb6, 0x7b, 0x28, 0xa4, 0x03, 0xc3,
+ 0x4c, 0x53, 0xd1, 0x58, 0xbc, 0x72, 0xbc, 0x08, 0x39, 0xfc, 0xa0, 0x76,
+ 0xa8, 0xa8, 0xe9, 0x4b, 0x6e, 0x88, 0x3d, 0xe3, 0xb3, 0x31, 0x25, 0x8c,
+ 0x73, 0x29, 0x48, 0x0e, 0x32, 0x79, 0x06, 0xed, 0x3d, 0x43, 0xf4, 0xf6,
+ 0xe4, 0xe9, 0xfc, 0x7d, 0xbe, 0x8e, 0x08, 0xd5, 0x1f, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x82, 0x02, 0x08, 0x30, 0x82, 0x02, 0x04, 0x30, 0x1d,
+ 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4e, 0x43, 0xc8,
+ 0x1d, 0x76, 0xef, 0x37, 0x53, 0x7a, 0x4f, 0xf2, 0x58, 0x6f, 0x94, 0xf3,
+ 0x38, 0xe2, 0xd5, 0xbd, 0xdf, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13,
+ 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34,
+ 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c,
+ 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x63, 0x70, 0x73, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+ 0x36, 0x30, 0x34, 0x30, 0x32, 0xa0, 0x30, 0xa0, 0x2e, 0x86, 0x2c, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75,
+ 0x72, 0x65, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+ 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33,
+ 0x2d, 0x67, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
+ 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01,
+ 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d,
+ 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d,
+ 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30,
+ 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5,
+ 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4,
+ 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65,
+ 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76,
+ 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x29, 0x06,
+ 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c,
+ 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43,
+ 0x6c, 0x61, 0x73, 0x73, 0x33, 0x43, 0x41, 0x32, 0x30, 0x34, 0x38, 0x2d,
+ 0x31, 0x2d, 0x34, 0x38, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec,
+ 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31,
+ 0x33, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
+ 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f,
+ 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
+ 0x2d, 0x30, 0x2b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42,
+ 0x04, 0x01, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01,
+ 0x08, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x27, 0x74, 0xa6, 0x34, 0xea, 0x1d,
+ 0x9d, 0xe1, 0x53, 0xd6, 0x1c, 0x9d, 0x0c, 0xa7, 0x5b, 0x4c, 0xa9, 0x67,
+ 0xf2, 0xf0, 0x32, 0xb7, 0x01, 0x0f, 0xfb, 0x42, 0x18, 0x38, 0xde, 0xe4,
+ 0xee, 0x49, 0xc8, 0x13, 0xc9, 0x0b, 0xec, 0x04, 0xc3, 0x40, 0x71, 0x18,
+ 0x72, 0x76, 0x43, 0x02, 0x23, 0x5d, 0xab, 0x7b, 0xc8, 0x48, 0x14, 0x1a,
+ 0xc8, 0x7b, 0x1d, 0xfc, 0xf6, 0x0a, 0x9f, 0x36, 0xa1, 0xd2, 0x09, 0x73,
+ 0x71, 0x66, 0x96, 0x75, 0x51, 0x34, 0xbf, 0x99, 0x30, 0x51, 0x67, 0x9d,
+ 0x54, 0xb7, 0x26, 0x45, 0xac, 0x73, 0x08, 0x23, 0x86, 0x26, 0x99, 0x71,
+ 0xf4, 0x8e, 0xd7, 0xea, 0x39, 0x9b, 0x06, 0x09, 0x23, 0xbf, 0x62, 0xdd,
+ 0xa8, 0xc4, 0xb6, 0x7d, 0xa4, 0x89, 0x07, 0x3e, 0xf3, 0x6d, 0xae, 0x40,
+ 0x59, 0x50, 0x79, 0x97, 0x37, 0x3d, 0x32, 0x78, 0x7d, 0xb2, 0x63, 0x4b,
+ 0xf9, 0xea, 0x08, 0x69, 0x0e, 0x13, 0xed, 0xe8, 0xcf, 0xbb, 0xac, 0x05,
+ 0x86, 0xca, 0x22, 0xcf, 0x88, 0x62, 0x5d, 0x3c, 0x22, 0x49, 0xd8, 0x63,
+ 0xd5, 0x24, 0xa6, 0xbd, 0xef, 0x5c, 0xe3, 0xcc, 0x20, 0x3b, 0x22, 0xea,
+ 0xfc, 0x44, 0xc6, 0xa8, 0xe5, 0x1f, 0xe1, 0x86, 0xcd, 0x0c, 0x4d, 0x8f,
+ 0x93, 0x53, 0xd9, 0x7f, 0xee, 0xa1, 0x08, 0xa7, 0xb3, 0x30, 0x96, 0x49,
+ 0x70, 0x6e, 0xa3, 0x6c, 0x3d, 0xd0, 0x63, 0xef, 0x25, 0x66, 0x63, 0xcc,
+ 0xaa, 0xb7, 0x18, 0x17, 0x4e, 0xea, 0x70, 0x76, 0xf6, 0xba, 0x42, 0xa6,
+ 0x80, 0x37, 0x09, 0x4e, 0x9f, 0x66, 0x88, 0x2e, 0x6b, 0x33, 0x66, 0xc8,
+ 0xc0, 0x71, 0xa4, 0x41, 0xeb, 0x5a, 0xe3, 0xfc, 0x14, 0x2e, 0x4b, 0x88,
+ 0xfd, 0xae, 0x6e, 0x5b, 0x65, 0xe9, 0x27, 0xe4, 0xbf, 0xe4, 0xb0, 0x23,
+ 0xc1, 0xb2, 0x7d, 0x5b, 0x62, 0x25, 0xd7, 0x3e, 0x10, 0xd4,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 64:1b:e8:20:ce:02:08:13:f3:2d:4d:2d:95:d6:7e:67
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
+ Validity
+ Not Before: Feb 8 00:00:00 2010 GMT
+ Not After : Feb 7 23:59:59 2020 GMT
+ Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 International Server CA - G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:99:d6:9c:62:f0:15:f4:81:9a:41:08:59:8f:13:
+ 9d:17:c9:9f:51:dc:da:b1:52:ef:ff:e3:41:dd:e0:
+ df:c4:28:c6:e3:ad:79:1f:27:10:98:b8:bb:20:97:
+ c1:28:44:41:0f:ea:a9:a8:52:cf:4d:4e:1b:8b:bb:
+ b5:c4:76:d9:cc:56:06:ee:b3:55:20:2a:de:15:8d:
+ 71:cb:54:c8:6f:17:cd:89:00:e4:dc:ff:e1:c0:1f:
+ 68:71:e9:c7:29:2e:7e:bc:3b:fc:e5:bb:ab:26:54:
+ 8b:66:90:cd:f6:92:b9:31:24:80:bc:9e:6c:d5:fc:
+ 7e:d2:e1:4b:8c:dc:42:fa:44:4b:5f:f8:18:b5:2e:
+ 30:f4:3d:12:98:d3:62:05:73:54:a6:9c:a2:1d:be:
+ 52:83:3a:07:46:c4:3b:02:56:21:bf:f2:51:4f:d0:
+ a6:99:39:e9:ae:a5:3f:89:9b:9c:7d:fe:4d:60:07:
+ 25:20:f7:bb:d7:69:83:2b:82:93:43:37:d9:83:41:
+ 1b:6b:0b:ab:4a:66:84:4f:4a:8e:de:7e:34:99:8e:
+ 68:d6:ca:39:06:9b:4c:b3:9a:48:4d:13:46:b4:58:
+ 21:04:c4:fb:a0:4d:ac:2e:4b:62:12:e3:fb:4d:f6:
+ c9:51:00:01:1f:fc:1e:6a:81:2a:38:e0:b9:4f:d6:
+ 2d:45
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.113733.1.7.23.3
+ CPS: https://www.verisign.com/cps
+ User Notice:
+ Explicit Text: https://www.verisign.com/rpa
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ 1.3.6.1.5.5.7.1.12:
+ 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1
+ Authority Information Access:
+ OCSP - URI:http://ocsp.verisign.com
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.verisign.com/pca3-g5.crl
+
+ X509v3 Subject Alternative Name:
+ DirName:/CN=VeriSignMPKI-2-7
+ X509v3 Subject Key Identifier:
+ D7:9B:7C:D8:22:A0:15:F7:DD:AD:5F:CE:29:9B:58:C3:BC:46:00:B5
+ X509v3 Authority Key Identifier:
+ keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 71:b5:7d:73:52:4a:dd:d7:4d:34:2b:2e:af:94:46:a5:49:50:
+ 02:4f:f8:2f:17:70:f2:13:dc:1f:21:86:aa:c2:4f:7c:37:3c:
+ d4:46:78:ae:5d:78:6f:d1:ba:5a:bc:10:ab:58:36:c5:8c:62:
+ 15:45:60:17:21:e2:d5:42:a8:77:a1:55:d8:43:04:51:f6:6e:
+ ba:48:e6:5d:4c:b7:44:d3:3e:a4:d5:d6:33:9a:9f:0d:e6:d7:
+ 4e:96:44:95:5a:6c:d6:a3:16:53:0e:98:43:ce:a4:b8:c3:66:
+ 7a:05:5c:62:10:e8:1b:12:db:7d:2e:76:50:ff:df:d7:6b:1b:
+ cc:8a:cc:71:fa:b3:40:56:7c:33:7a:77:94:5b:f5:0b:53:fb:
+ 0e:5f:bc:68:fb:af:2a:ee:30:37:79:16:93:25:7f:4d:10:ff:
+ 57:fb:bf:6e:3b:33:21:de:79:dc:86:17:59:2d:43:64:b7:a6:
+ 66:87:ea:bc:96:46:19:1a:86:8b:6f:d7:b7:49:00:5b:db:a3:
+ bf:29:9a:ee:f7:d3:33:ae:a3:f4:9e:4c:ca:5e:69:d4:1b:ad:
+ b7:90:77:6a:d8:59:6f:79:ab:01:fa:55:f0:8a:21:66:e5:65:
+ 6e:fd:7c:d3:df:1e:eb:7e:3f:06:90:fb:19:0b:d3:06:02:1b:
+ 78:43:99:a8
+-----BEGIN CERTIFICATE-----
+MIIGKTCCBRGgAwIBAgIQZBvoIM4CCBPzLU0tldZ+ZzANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBvDEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
+aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMtVmVy
+aVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdacYvAV9IGaQQhZjxOdF8mfUdza
+sVLv/+NB3eDfxCjG4615HycQmLi7IJfBKERBD+qpqFLPTU4bi7u1xHbZzFYG7rNV
+ICreFY1xy1TIbxfNiQDk3P/hwB9ocenHKS5+vDv85burJlSLZpDN9pK5MSSAvJ5s
+1fx+0uFLjNxC+kRLX/gYtS4w9D0SmNNiBXNUppyiHb5SgzoHRsQ7AlYhv/JRT9Cm
+mTnprqU/iZucff5NYAclIPe712mDK4KTQzfZg0EbawurSmaET0qO3n40mY5o1so5
+BptMs5pITRNGtFghBMT7oE2sLktiEuP7TfbJUQABH/weaoEqOOC5T9YtRQIDAQAB
+o4ICFTCCAhEwEgYDVR0TAQH/BAgwBgEB/wIBADBwBgNVHSAEaTBnMGUGC2CGSAGG
++EUBBxcDMFYwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9j
+cHMwKgYIKwYBBQUHAgIwHhocaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTAO
+BgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
+Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDov
+L2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwNAYDVR0lBC0wKwYIKwYBBQUH
+AwEGCCsGAQUFBwMCBglghkgBhvhCBAEGCmCGSAGG+EUBCAEwNAYIKwYBBQUHAQEE
+KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC52ZXJpc2lnbi5jb20wNAYDVR0f
+BC0wKzApoCegJYYjaHR0cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy1nNS5jcmww
+KAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFZlcmlTaWduTVBLSS0yLTcwHQYDVR0O
+BBYEFNebfNgioBX33a1fzimbWMO8RgC1MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ
+80M5+gKvMzEzMA0GCSqGSIb3DQEBBQUAA4IBAQBxtX1zUkrd1000Ky6vlEalSVAC
+T/gvF3DyE9wfIYaqwk98NzzURniuXXhv0bpavBCrWDbFjGIVRWAXIeLVQqh3oVXY
+QwRR9m66SOZdTLdE0z6k1dYzmp8N5tdOlkSVWmzWoxZTDphDzqS4w2Z6BVxiEOgb
+Ett9LnZQ/9/XaxvMisxx+rNAVnwzeneUW/ULU/sOX7xo+68q7jA3eRaTJX9NEP9X
++79uOzMh3nnchhdZLUNkt6Zmh+q8lkYZGoaLb9e3SQBb26O/KZru99MzrqP0nkzK
+XmnUG623kHdq2FlveasB+lXwiiFm5WVu/XzT3x7rfj8GkPsZC9MGAht4Q5mo
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert49[] = {
+ 0x30, 0x82, 0x06, 0x29, 0x30, 0x82, 0x05, 0x11, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x64, 0x1b, 0xe8, 0x20, 0xce, 0x02, 0x08, 0x13, 0xf3,
+ 0x2d, 0x4d, 0x2d, 0x95, 0xd6, 0x7e, 0x67, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81,
+ 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
+ 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+ 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28,
+ 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69,
+ 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
+ 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+ 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
+ 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+ 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30,
+ 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x32, 0x30, 0x37,
+ 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xbc, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65,
+ 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56,
+ 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+ 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30,
+ 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d,
+ 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20,
+ 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+ 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x31, 0x30, 0x31, 0x36,
+ 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x56, 0x65, 0x72,
+ 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+ 0x33, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43,
+ 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+ 0x01, 0x01, 0x00, 0x99, 0xd6, 0x9c, 0x62, 0xf0, 0x15, 0xf4, 0x81, 0x9a,
+ 0x41, 0x08, 0x59, 0x8f, 0x13, 0x9d, 0x17, 0xc9, 0x9f, 0x51, 0xdc, 0xda,
+ 0xb1, 0x52, 0xef, 0xff, 0xe3, 0x41, 0xdd, 0xe0, 0xdf, 0xc4, 0x28, 0xc6,
+ 0xe3, 0xad, 0x79, 0x1f, 0x27, 0x10, 0x98, 0xb8, 0xbb, 0x20, 0x97, 0xc1,
+ 0x28, 0x44, 0x41, 0x0f, 0xea, 0xa9, 0xa8, 0x52, 0xcf, 0x4d, 0x4e, 0x1b,
+ 0x8b, 0xbb, 0xb5, 0xc4, 0x76, 0xd9, 0xcc, 0x56, 0x06, 0xee, 0xb3, 0x55,
+ 0x20, 0x2a, 0xde, 0x15, 0x8d, 0x71, 0xcb, 0x54, 0xc8, 0x6f, 0x17, 0xcd,
+ 0x89, 0x00, 0xe4, 0xdc, 0xff, 0xe1, 0xc0, 0x1f, 0x68, 0x71, 0xe9, 0xc7,
+ 0x29, 0x2e, 0x7e, 0xbc, 0x3b, 0xfc, 0xe5, 0xbb, 0xab, 0x26, 0x54, 0x8b,
+ 0x66, 0x90, 0xcd, 0xf6, 0x92, 0xb9, 0x31, 0x24, 0x80, 0xbc, 0x9e, 0x6c,
+ 0xd5, 0xfc, 0x7e, 0xd2, 0xe1, 0x4b, 0x8c, 0xdc, 0x42, 0xfa, 0x44, 0x4b,
+ 0x5f, 0xf8, 0x18, 0xb5, 0x2e, 0x30, 0xf4, 0x3d, 0x12, 0x98, 0xd3, 0x62,
+ 0x05, 0x73, 0x54, 0xa6, 0x9c, 0xa2, 0x1d, 0xbe, 0x52, 0x83, 0x3a, 0x07,
+ 0x46, 0xc4, 0x3b, 0x02, 0x56, 0x21, 0xbf, 0xf2, 0x51, 0x4f, 0xd0, 0xa6,
+ 0x99, 0x39, 0xe9, 0xae, 0xa5, 0x3f, 0x89, 0x9b, 0x9c, 0x7d, 0xfe, 0x4d,
+ 0x60, 0x07, 0x25, 0x20, 0xf7, 0xbb, 0xd7, 0x69, 0x83, 0x2b, 0x82, 0x93,
+ 0x43, 0x37, 0xd9, 0x83, 0x41, 0x1b, 0x6b, 0x0b, 0xab, 0x4a, 0x66, 0x84,
+ 0x4f, 0x4a, 0x8e, 0xde, 0x7e, 0x34, 0x99, 0x8e, 0x68, 0xd6, 0xca, 0x39,
+ 0x06, 0x9b, 0x4c, 0xb3, 0x9a, 0x48, 0x4d, 0x13, 0x46, 0xb4, 0x58, 0x21,
+ 0x04, 0xc4, 0xfb, 0xa0, 0x4d, 0xac, 0x2e, 0x4b, 0x62, 0x12, 0xe3, 0xfb,
+ 0x4d, 0xf6, 0xc9, 0x51, 0x00, 0x01, 0x1f, 0xfc, 0x1e, 0x6a, 0x81, 0x2a,
+ 0x38, 0xe0, 0xb9, 0x4f, 0xd6, 0x2d, 0x45, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x82, 0x02, 0x15, 0x30, 0x82, 0x02, 0x11, 0x30, 0x12, 0x06, 0x03,
+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
+ 0xff, 0x02, 0x01, 0x00, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
+ 0xf8, 0x45, 0x01, 0x07, 0x17, 0x03, 0x30, 0x56, 0x30, 0x28, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
+ 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
+ 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
+ 0x70, 0x73, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x02, 0x30, 0x1e, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69,
+ 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
+ 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59,
+ 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
+ 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b,
+ 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac,
+ 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b,
+ 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69,
+ 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67,
+ 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x25,
+ 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
+ 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06,
+ 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30,
+ 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
+ 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+ 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76,
+ 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+ 0x28, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d,
+ 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x10, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b,
+ 0x49, 0x2d, 0x32, 0x2d, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+ 0x04, 0x16, 0x04, 0x14, 0xd7, 0x9b, 0x7c, 0xd8, 0x22, 0xa0, 0x15, 0xf7,
+ 0xdd, 0xad, 0x5f, 0xce, 0x29, 0x9b, 0x58, 0xc3, 0xbc, 0x46, 0x00, 0xb5,
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
+ 0x14, 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09,
+ 0xf3, 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0x71, 0xb5, 0x7d, 0x73, 0x52, 0x4a, 0xdd,
+ 0xd7, 0x4d, 0x34, 0x2b, 0x2e, 0xaf, 0x94, 0x46, 0xa5, 0x49, 0x50, 0x02,
+ 0x4f, 0xf8, 0x2f, 0x17, 0x70, 0xf2, 0x13, 0xdc, 0x1f, 0x21, 0x86, 0xaa,
+ 0xc2, 0x4f, 0x7c, 0x37, 0x3c, 0xd4, 0x46, 0x78, 0xae, 0x5d, 0x78, 0x6f,
+ 0xd1, 0xba, 0x5a, 0xbc, 0x10, 0xab, 0x58, 0x36, 0xc5, 0x8c, 0x62, 0x15,
+ 0x45, 0x60, 0x17, 0x21, 0xe2, 0xd5, 0x42, 0xa8, 0x77, 0xa1, 0x55, 0xd8,
+ 0x43, 0x04, 0x51, 0xf6, 0x6e, 0xba, 0x48, 0xe6, 0x5d, 0x4c, 0xb7, 0x44,
+ 0xd3, 0x3e, 0xa4, 0xd5, 0xd6, 0x33, 0x9a, 0x9f, 0x0d, 0xe6, 0xd7, 0x4e,
+ 0x96, 0x44, 0x95, 0x5a, 0x6c, 0xd6, 0xa3, 0x16, 0x53, 0x0e, 0x98, 0x43,
+ 0xce, 0xa4, 0xb8, 0xc3, 0x66, 0x7a, 0x05, 0x5c, 0x62, 0x10, 0xe8, 0x1b,
+ 0x12, 0xdb, 0x7d, 0x2e, 0x76, 0x50, 0xff, 0xdf, 0xd7, 0x6b, 0x1b, 0xcc,
+ 0x8a, 0xcc, 0x71, 0xfa, 0xb3, 0x40, 0x56, 0x7c, 0x33, 0x7a, 0x77, 0x94,
+ 0x5b, 0xf5, 0x0b, 0x53, 0xfb, 0x0e, 0x5f, 0xbc, 0x68, 0xfb, 0xaf, 0x2a,
+ 0xee, 0x30, 0x37, 0x79, 0x16, 0x93, 0x25, 0x7f, 0x4d, 0x10, 0xff, 0x57,
+ 0xfb, 0xbf, 0x6e, 0x3b, 0x33, 0x21, 0xde, 0x79, 0xdc, 0x86, 0x17, 0x59,
+ 0x2d, 0x43, 0x64, 0xb7, 0xa6, 0x66, 0x87, 0xea, 0xbc, 0x96, 0x46, 0x19,
+ 0x1a, 0x86, 0x8b, 0x6f, 0xd7, 0xb7, 0x49, 0x00, 0x5b, 0xdb, 0xa3, 0xbf,
+ 0x29, 0x9a, 0xee, 0xf7, 0xd3, 0x33, 0xae, 0xa3, 0xf4, 0x9e, 0x4c, 0xca,
+ 0x5e, 0x69, 0xd4, 0x1b, 0xad, 0xb7, 0x90, 0x77, 0x6a, 0xd8, 0x59, 0x6f,
+ 0x79, 0xab, 0x01, 0xfa, 0x55, 0xf0, 0x8a, 0x21, 0x66, 0xe5, 0x65, 0x6e,
+ 0xfd, 0x7c, 0xd3, 0xdf, 0x1e, 0xeb, 0x7e, 0x3f, 0x06, 0x90, 0xfb, 0x19,
+ 0x0b, 0xd3, 0x06, 0x02, 0x1b, 0x78, 0x43, 0x99, 0xa8,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 26 (0x1a)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
+ Validity
+ Not Before: Oct 24 20:57:09 2007 GMT
+ Not After : Oct 24 20:57:09 2017 GMT
+ Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Class 2 Primary Intermediate Server CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e2:4f:39:2f:a1:8c:9a:85:ad:08:0e:08:3e:57:
+ f2:88:01:21:1b:94:a9:6c:e2:b8:db:aa:19:18:46:
+ 3a:52:a1:f5:0f:f4:6e:8c:ea:96:8c:96:87:79:13:
+ 40:51:2f:22:f2:0c:8b:87:0f:65:df:71:74:34:43:
+ 55:b1:35:09:9b:d9:bc:1f:fa:eb:42:d0:97:40:72:
+ b7:43:96:3d:ba:96:9d:5d:50:02:1c:9b:91:8d:9c:
+ c0:ac:d7:bb:2f:17:d7:cb:3e:82:9d:73:eb:07:42:
+ 92:b2:cd:64:b3:74:55:1b:b4:4b:86:21:2c:f7:78:
+ 87:32:e0:16:e4:da:bd:4c:95:ea:a4:0a:7e:b6:0a:
+ 0d:2e:8a:cf:55:ab:c3:e5:dd:41:8a:4e:e6:6f:65:
+ 6c:b2:40:cf:17:5d:b9:c3:6a:0b:27:11:84:77:61:
+ f6:c2:7c:ed:c0:8d:78:14:18:99:81:99:75:63:b7:
+ e8:53:d3:ba:61:e9:0e:fa:a2:30:f3:46:a2:b9:c9:
+ 1f:6c:80:5a:40:ac:27:ed:48:47:33:b0:54:c6:46:
+ 1a:f3:35:61:c1:02:29:90:54:7e:64:4d:c4:30:52:
+ 02:82:d7:df:ce:21:6e:18:91:d7:b8:ab:8c:27:17:
+ b5:f0:a3:01:2f:8e:d2:2e:87:3a:3d:b4:29:67:8a:
+ c4:03
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 11:DB:23:45:FD:54:CC:6A:71:6F:84:8A:03:D7:BE:F7:01:2F:26:86
+ X509v3 Authority Key Identifier:
+ keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.startssl.com/ca
+ CA Issuers - URI:http://www.startssl.com/sfsca.crt
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://www.startssl.com/sfsca.crl
+
+ Full Name:
+ URI:http://crl.startssl.com/sfsca.crl
+
+ X509v3 Certificate Policies:
+ Policy: 1.3.6.1.4.1.23223.1.2.1
+ CPS: http://www.startssl.com/policy.pdf
+ CPS: http://www.startssl.com/intermediate.pdf
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 9d:07:e1:ee:90:76:31:67:16:45:70:8c:cb:84:8b:4b:57:68:
+ 44:a5:89:c1:f2:7e:cb:28:8b:f5:e7:70:77:d5:b6:f4:0b:21:
+ 60:a5:a1:74:73:24:22:80:d6:d8:ba:8d:a2:62:5d:09:35:42:
+ 29:fb:39:63:45:0b:a4:b0:38:1a:68:f4:95:13:cc:e0:43:94:
+ ec:eb:39:1a:ec:57:29:d9:99:6d:f5:84:cd:8e:73:ae:c9:dc:
+ 6a:fa:9e:9d:16:64:93:08:c7:1c:c2:89:54:9e:77:80:90:f6:
+ b9:29:76:eb:13:67:48:59:f8:2e:3a:31:b8:c9:d3:88:e5:5f:
+ 4e:d2:19:3d:43:8e:d7:92:ff:cf:38:b6:e1:5b:8a:53:1d:ce:
+ ac:b4:76:2f:d8:f7:40:63:d5:ee:69:f3:45:7d:a0:62:c1:61:
+ c3:75:ed:b2:7b:4d:ac:21:27:30:4e:59:46:6a:93:17:ca:c8:
+ 39:2d:01:73:65:5b:e9:41:9b:11:17:9c:c8:c8:4a:ef:a1:76:
+ 60:2d:ae:93:ff:0c:d5:33:13:9f:4f:13:ce:dd:86:f1:fc:f8:
+ 35:54:15:a8:5b:e7:85:7e:fa:37:09:ff:8b:b8:31:49:9e:0d:
+ 6e:de:b4:d2:12:2d:b8:ed:c8:c3:f1:b6:42:a0:4c:97:79:df:
+ fe:c3:a3:9f:a1:f4:6d:2c:84:77:a4:a2:05:e1:17:ff:31:dd:
+ 9a:f3:b8:7a:c3:52:c2:11:11:b7:50:31:8a:7f:cc:e7:5a:89:
+ cc:f7:86:9a:61:92:4f:2f:94:b6:98:c7:78:e0:62:4b:43:7d:
+ 3c:de:d6:9a:b4:10:a1:40:9c:4b:2a:dc:b8:d0:d4:9e:fd:f1:
+ 84:78:1b:0e:57:8f:69:54:42:68:7b:ea:a0:ef:75:0f:07:a2:
+ 8c:73:99:ab:55:f5:07:09:d2:af:38:03:6a:90:03:0c:2f:8f:
+ e2:e8:43:c2:31:e9:6f:ad:87:e5:8d:bd:4e:2c:89:4b:51:e6:
+ 9c:4c:54:76:c0:12:81:53:9b:ec:a0:fc:2c:9c:da:18:95:6e:
+ 1e:38:26:42:27:78:60:08:df:7f:6d:32:e8:d8:c0:6f:1f:eb:
+ 26:75:9f:93:fc:7b:1b:fe:35:90:dc:53:a3:07:a6:3f:83:55:
+ 0a:2b:4e:62:82:25:ce:66:30:5d:2c:e0:f9:19:1b:75:b9:9d:
+ 98:56:a6:83:27:7a:d1:8f:8d:59:93:fc:3f:73:d7:2e:b4:2c:
+ 95:d8:8b:f7:c9:7e:c7:fc:9d:ac:72:04:1f:d2:cc:17:f4:ed:
+ 34:60:9b:9e:4a:97:04:fe:dd:72:0e:57:54:51:06:70:4d:ef:
+ aa:1c:a4:82:e0:33:c7:f4
+-----BEGIN CERTIFICATE-----
+MIIGNDCCBBygAwIBAgIBGjANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NzA5WhcNMTcxMDI0MjA1NzA5WjCB
+jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
+IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
+YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4k85L6GMmoWtCA4IPlfyiAEh
+G5SpbOK426oZGEY6UqH1D/RujOqWjJaHeRNAUS8i8gyLhw9l33F0NENVsTUJm9m8
+H/rrQtCXQHK3Q5Y9upadXVACHJuRjZzArNe7LxfXyz6CnXPrB0KSss1ks3RVG7RL
+hiEs93iHMuAW5Nq9TJXqpAp+tgoNLorPVavD5d1Bik7mb2VsskDPF125w2oLJxGE
+d2H2wnztwI14FBiZgZl1Y7foU9O6YekO+qIw80aiuckfbIBaQKwn7UhHM7BUxkYa
+8zVhwQIpkFR+ZE3EMFICgtffziFuGJHXuKuMJxe18KMBL47SLoc6PbQpZ4rEAwID
+AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFBHbI0X9VMxqcW+EigPXvvcBLyaGMB8GA1UdIwQYMBaAFE4L7xqkQFul
+F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
+L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
+YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
+dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
+c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
+BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
+BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
+LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAnQfh7pB2MWcWRXCMy4SLS1doRKWJwfJ+
+yyiL9edwd9W29AshYKWhdHMkIoDW2LqNomJdCTVCKfs5Y0ULpLA4Gmj0lRPM4EOU
+7Os5GuxXKdmZbfWEzY5zrsncavqenRZkkwjHHMKJVJ53gJD2uSl26xNnSFn4Ljox
+uMnTiOVfTtIZPUOO15L/zzi24VuKUx3OrLR2L9j3QGPV7mnzRX2gYsFhw3XtsntN
+rCEnME5ZRmqTF8rIOS0Bc2Vb6UGbERecyMhK76F2YC2uk/8M1TMTn08Tzt2G8fz4
+NVQVqFvnhX76Nwn/i7gxSZ4Nbt600hItuO3Iw/G2QqBMl3nf/sOjn6H0bSyEd6Si
+BeEX/zHdmvO4esNSwhERt1Axin/M51qJzPeGmmGSTy+UtpjHeOBiS0N9PN7WmrQQ
+oUCcSyrcuNDUnv3xhHgbDlePaVRCaHvqoO91DweijHOZq1X1BwnSrzgDapADDC+P
+4uhDwjHpb62H5Y29TiyJS1HmnExUdsASgVOb7KD8LJzaGJVuHjgmQid4YAjff20y
+6NjAbx/rJnWfk/x7G/41kNxTowemP4NVCitOYoIlzmYwXSzg+RkbdbmdmFamgyd6
+0Y+NWZP8P3PXLrQsldiL98l+x/ydrHIEH9LMF/TtNGCbnkqXBP7dcg5XVFEGcE3v
+qhykguAzx/Q=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert50[] = {
+ 0x30, 0x82, 0x06, 0x34, 0x30, 0x82, 0x04, 0x1c, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x01, 0x1a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30,
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16,
+ 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2b,
+ 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x22, 0x53, 0x65, 0x63,
+ 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
+ 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x29, 0x30, 0x27, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43,
+ 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x31, 0x30, 0x32, 0x34,
+ 0x32, 0x30, 0x35, 0x37, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x31,
+ 0x30, 0x32, 0x34, 0x32, 0x30, 0x35, 0x37, 0x30, 0x39, 0x5a, 0x30, 0x81,
+ 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74,
+ 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69,
+ 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31,
+ 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2f, 0x53, 0x74,
+ 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
+ 0x20, 0x32, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x49,
+ 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20,
+ 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01,
+ 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+ 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe2, 0x4f, 0x39, 0x2f, 0xa1, 0x8c,
+ 0x9a, 0x85, 0xad, 0x08, 0x0e, 0x08, 0x3e, 0x57, 0xf2, 0x88, 0x01, 0x21,
+ 0x1b, 0x94, 0xa9, 0x6c, 0xe2, 0xb8, 0xdb, 0xaa, 0x19, 0x18, 0x46, 0x3a,
+ 0x52, 0xa1, 0xf5, 0x0f, 0xf4, 0x6e, 0x8c, 0xea, 0x96, 0x8c, 0x96, 0x87,
+ 0x79, 0x13, 0x40, 0x51, 0x2f, 0x22, 0xf2, 0x0c, 0x8b, 0x87, 0x0f, 0x65,
+ 0xdf, 0x71, 0x74, 0x34, 0x43, 0x55, 0xb1, 0x35, 0x09, 0x9b, 0xd9, 0xbc,
+ 0x1f, 0xfa, 0xeb, 0x42, 0xd0, 0x97, 0x40, 0x72, 0xb7, 0x43, 0x96, 0x3d,
+ 0xba, 0x96, 0x9d, 0x5d, 0x50, 0x02, 0x1c, 0x9b, 0x91, 0x8d, 0x9c, 0xc0,
+ 0xac, 0xd7, 0xbb, 0x2f, 0x17, 0xd7, 0xcb, 0x3e, 0x82, 0x9d, 0x73, 0xeb,
+ 0x07, 0x42, 0x92, 0xb2, 0xcd, 0x64, 0xb3, 0x74, 0x55, 0x1b, 0xb4, 0x4b,
+ 0x86, 0x21, 0x2c, 0xf7, 0x78, 0x87, 0x32, 0xe0, 0x16, 0xe4, 0xda, 0xbd,
+ 0x4c, 0x95, 0xea, 0xa4, 0x0a, 0x7e, 0xb6, 0x0a, 0x0d, 0x2e, 0x8a, 0xcf,
+ 0x55, 0xab, 0xc3, 0xe5, 0xdd, 0x41, 0x8a, 0x4e, 0xe6, 0x6f, 0x65, 0x6c,
+ 0xb2, 0x40, 0xcf, 0x17, 0x5d, 0xb9, 0xc3, 0x6a, 0x0b, 0x27, 0x11, 0x84,
+ 0x77, 0x61, 0xf6, 0xc2, 0x7c, 0xed, 0xc0, 0x8d, 0x78, 0x14, 0x18, 0x99,
+ 0x81, 0x99, 0x75, 0x63, 0xb7, 0xe8, 0x53, 0xd3, 0xba, 0x61, 0xe9, 0x0e,
+ 0xfa, 0xa2, 0x30, 0xf3, 0x46, 0xa2, 0xb9, 0xc9, 0x1f, 0x6c, 0x80, 0x5a,
+ 0x40, 0xac, 0x27, 0xed, 0x48, 0x47, 0x33, 0xb0, 0x54, 0xc6, 0x46, 0x1a,
+ 0xf3, 0x35, 0x61, 0xc1, 0x02, 0x29, 0x90, 0x54, 0x7e, 0x64, 0x4d, 0xc4,
+ 0x30, 0x52, 0x02, 0x82, 0xd7, 0xdf, 0xce, 0x21, 0x6e, 0x18, 0x91, 0xd7,
+ 0xb8, 0xab, 0x8c, 0x27, 0x17, 0xb5, 0xf0, 0xa3, 0x01, 0x2f, 0x8e, 0xd2,
+ 0x2e, 0x87, 0x3a, 0x3d, 0xb4, 0x29, 0x67, 0x8a, 0xc4, 0x03, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xad, 0x30, 0x82, 0x01, 0xa9, 0x30,
+ 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
+ 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0xdb, 0x23, 0x45, 0xfd,
+ 0x54, 0xcc, 0x6a, 0x71, 0x6f, 0x84, 0x8a, 0x03, 0xd7, 0xbe, 0xf7, 0x01,
+ 0x2f, 0x26, 0x86, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef, 0x1a, 0xa4, 0x40, 0x5b, 0xa5,
+ 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68, 0x43, 0xd0, 0x41, 0xae, 0xf2,
+ 0x30, 0x66, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+ 0x04, 0x5a, 0x30, 0x58, 0x30, 0x27, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73,
+ 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x30, 0x2d, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x21, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x74,
+ 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73,
+ 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x5b, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x54, 0x30, 0x52, 0x30, 0x27, 0xa0, 0x25, 0xa0,
+ 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+ 0x77, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c,
+ 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70,
+ 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74,
+ 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x73, 0x63,
+ 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0x80, 0x06, 0x03, 0x55, 0x1d,
+ 0x20, 0x04, 0x79, 0x30, 0x77, 0x30, 0x75, 0x06, 0x0b, 0x2b, 0x06, 0x01,
+ 0x04, 0x01, 0x81, 0xb5, 0x37, 0x01, 0x02, 0x01, 0x30, 0x66, 0x30, 0x2e,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x22,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x64, 0x66, 0x30, 0x34,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x28,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65,
+ 0x2e, 0x70, 0x64, 0x66, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00,
+ 0x9d, 0x07, 0xe1, 0xee, 0x90, 0x76, 0x31, 0x67, 0x16, 0x45, 0x70, 0x8c,
+ 0xcb, 0x84, 0x8b, 0x4b, 0x57, 0x68, 0x44, 0xa5, 0x89, 0xc1, 0xf2, 0x7e,
+ 0xcb, 0x28, 0x8b, 0xf5, 0xe7, 0x70, 0x77, 0xd5, 0xb6, 0xf4, 0x0b, 0x21,
+ 0x60, 0xa5, 0xa1, 0x74, 0x73, 0x24, 0x22, 0x80, 0xd6, 0xd8, 0xba, 0x8d,
+ 0xa2, 0x62, 0x5d, 0x09, 0x35, 0x42, 0x29, 0xfb, 0x39, 0x63, 0x45, 0x0b,
+ 0xa4, 0xb0, 0x38, 0x1a, 0x68, 0xf4, 0x95, 0x13, 0xcc, 0xe0, 0x43, 0x94,
+ 0xec, 0xeb, 0x39, 0x1a, 0xec, 0x57, 0x29, 0xd9, 0x99, 0x6d, 0xf5, 0x84,
+ 0xcd, 0x8e, 0x73, 0xae, 0xc9, 0xdc, 0x6a, 0xfa, 0x9e, 0x9d, 0x16, 0x64,
+ 0x93, 0x08, 0xc7, 0x1c, 0xc2, 0x89, 0x54, 0x9e, 0x77, 0x80, 0x90, 0xf6,
+ 0xb9, 0x29, 0x76, 0xeb, 0x13, 0x67, 0x48, 0x59, 0xf8, 0x2e, 0x3a, 0x31,
+ 0xb8, 0xc9, 0xd3, 0x88, 0xe5, 0x5f, 0x4e, 0xd2, 0x19, 0x3d, 0x43, 0x8e,
+ 0xd7, 0x92, 0xff, 0xcf, 0x38, 0xb6, 0xe1, 0x5b, 0x8a, 0x53, 0x1d, 0xce,
+ 0xac, 0xb4, 0x76, 0x2f, 0xd8, 0xf7, 0x40, 0x63, 0xd5, 0xee, 0x69, 0xf3,
+ 0x45, 0x7d, 0xa0, 0x62, 0xc1, 0x61, 0xc3, 0x75, 0xed, 0xb2, 0x7b, 0x4d,
+ 0xac, 0x21, 0x27, 0x30, 0x4e, 0x59, 0x46, 0x6a, 0x93, 0x17, 0xca, 0xc8,
+ 0x39, 0x2d, 0x01, 0x73, 0x65, 0x5b, 0xe9, 0x41, 0x9b, 0x11, 0x17, 0x9c,
+ 0xc8, 0xc8, 0x4a, 0xef, 0xa1, 0x76, 0x60, 0x2d, 0xae, 0x93, 0xff, 0x0c,
+ 0xd5, 0x33, 0x13, 0x9f, 0x4f, 0x13, 0xce, 0xdd, 0x86, 0xf1, 0xfc, 0xf8,
+ 0x35, 0x54, 0x15, 0xa8, 0x5b, 0xe7, 0x85, 0x7e, 0xfa, 0x37, 0x09, 0xff,
+ 0x8b, 0xb8, 0x31, 0x49, 0x9e, 0x0d, 0x6e, 0xde, 0xb4, 0xd2, 0x12, 0x2d,
+ 0xb8, 0xed, 0xc8, 0xc3, 0xf1, 0xb6, 0x42, 0xa0, 0x4c, 0x97, 0x79, 0xdf,
+ 0xfe, 0xc3, 0xa3, 0x9f, 0xa1, 0xf4, 0x6d, 0x2c, 0x84, 0x77, 0xa4, 0xa2,
+ 0x05, 0xe1, 0x17, 0xff, 0x31, 0xdd, 0x9a, 0xf3, 0xb8, 0x7a, 0xc3, 0x52,
+ 0xc2, 0x11, 0x11, 0xb7, 0x50, 0x31, 0x8a, 0x7f, 0xcc, 0xe7, 0x5a, 0x89,
+ 0xcc, 0xf7, 0x86, 0x9a, 0x61, 0x92, 0x4f, 0x2f, 0x94, 0xb6, 0x98, 0xc7,
+ 0x78, 0xe0, 0x62, 0x4b, 0x43, 0x7d, 0x3c, 0xde, 0xd6, 0x9a, 0xb4, 0x10,
+ 0xa1, 0x40, 0x9c, 0x4b, 0x2a, 0xdc, 0xb8, 0xd0, 0xd4, 0x9e, 0xfd, 0xf1,
+ 0x84, 0x78, 0x1b, 0x0e, 0x57, 0x8f, 0x69, 0x54, 0x42, 0x68, 0x7b, 0xea,
+ 0xa0, 0xef, 0x75, 0x0f, 0x07, 0xa2, 0x8c, 0x73, 0x99, 0xab, 0x55, 0xf5,
+ 0x07, 0x09, 0xd2, 0xaf, 0x38, 0x03, 0x6a, 0x90, 0x03, 0x0c, 0x2f, 0x8f,
+ 0xe2, 0xe8, 0x43, 0xc2, 0x31, 0xe9, 0x6f, 0xad, 0x87, 0xe5, 0x8d, 0xbd,
+ 0x4e, 0x2c, 0x89, 0x4b, 0x51, 0xe6, 0x9c, 0x4c, 0x54, 0x76, 0xc0, 0x12,
+ 0x81, 0x53, 0x9b, 0xec, 0xa0, 0xfc, 0x2c, 0x9c, 0xda, 0x18, 0x95, 0x6e,
+ 0x1e, 0x38, 0x26, 0x42, 0x27, 0x78, 0x60, 0x08, 0xdf, 0x7f, 0x6d, 0x32,
+ 0xe8, 0xd8, 0xc0, 0x6f, 0x1f, 0xeb, 0x26, 0x75, 0x9f, 0x93, 0xfc, 0x7b,
+ 0x1b, 0xfe, 0x35, 0x90, 0xdc, 0x53, 0xa3, 0x07, 0xa6, 0x3f, 0x83, 0x55,
+ 0x0a, 0x2b, 0x4e, 0x62, 0x82, 0x25, 0xce, 0x66, 0x30, 0x5d, 0x2c, 0xe0,
+ 0xf9, 0x19, 0x1b, 0x75, 0xb9, 0x9d, 0x98, 0x56, 0xa6, 0x83, 0x27, 0x7a,
+ 0xd1, 0x8f, 0x8d, 0x59, 0x93, 0xfc, 0x3f, 0x73, 0xd7, 0x2e, 0xb4, 0x2c,
+ 0x95, 0xd8, 0x8b, 0xf7, 0xc9, 0x7e, 0xc7, 0xfc, 0x9d, 0xac, 0x72, 0x04,
+ 0x1f, 0xd2, 0xcc, 0x17, 0xf4, 0xed, 0x34, 0x60, 0x9b, 0x9e, 0x4a, 0x97,
+ 0x04, 0xfe, 0xdd, 0x72, 0x0e, 0x57, 0x54, 0x51, 0x06, 0x70, 0x4d, 0xef,
+ 0xaa, 0x1c, 0xa4, 0x82, 0xe0, 0x33, 0xc7, 0xf4,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0a:5f:11:4d:03:5b:17:91:17:d2:ef:d4:03:8c:3f:3b
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
+ Validity
+ Not Before: Apr 2 12:00:00 2008 GMT
+ Not After : Apr 3 00:00:00 2022 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance CA-3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:61:0a:29:10:1f:5e:fe:34:37:51:08:f8:1e:
+ fb:22:ed:61:be:0b:0d:70:4c:50:63:26:75:15:b9:
+ 41:88:97:b6:f0:a0:15:bb:08:60:e0:42:e8:05:29:
+ 10:87:36:8a:28:65:a8:ef:31:07:74:6d:36:97:2f:
+ 28:46:66:04:c7:2a:79:26:7a:99:d5:8e:c3:6d:4f:
+ a0:5e:ad:bc:3d:91:c2:59:7b:5e:36:6c:c0:53:cf:
+ 00:08:32:3e:10:64:58:10:13:69:c7:0c:ee:9c:42:
+ 51:00:f9:05:44:ee:24:ce:7a:1f:ed:8c:11:bd:12:
+ a8:f3:15:f4:1c:7a:31:69:01:1b:a7:e6:5d:c0:9a:
+ 6c:7e:09:9e:e7:52:44:4a:10:3a:23:e4:9b:b6:03:
+ af:a8:9c:b4:5b:9f:d4:4b:ad:92:8c:ce:b5:11:2a:
+ aa:37:18:8d:b4:c2:b8:d8:5c:06:8c:f8:ff:23:bd:
+ 35:5e:d4:7c:3e:7e:83:0e:91:96:05:98:c3:b2:1f:
+ e3:c8:65:eb:a9:7b:5d:a0:2c:cc:fc:3c:d9:6d:ed:
+ cc:fa:4b:43:8c:c9:d4:b8:a5:61:1c:b2:40:b6:28:
+ 12:df:b9:f8:5f:fe:d3:b2:c9:ef:3d:b4:1e:4b:7c:
+ 1c:4c:99:36:9e:3d:eb:ec:a7:68:5e:1d:df:67:6e:
+ 5e:fb
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.114412.1.3.0.2
+ CPS: http://www.digicert.com/ssl-cps-repository.htm
+ User Notice:
+ Explicit Text:
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ Authority Information Access:
+ OCSP - URI:http://ocsp.digicert.com
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl3.digicert.com/DigiCertHighAssuranceEVRootCA.crl
+
+ Full Name:
+ URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
+
+ X509v3 Authority Key Identifier:
+ keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
+
+ X509v3 Subject Key Identifier:
+ 50:EA:73:89:DB:29:FB:10:8F:9E:E5:01:20:D4:DE:79:99:48:83:F7
+ Signature Algorithm: sha1WithRSAEncryption
+ 1e:e2:a5:48:9e:6c:db:53:38:0f:ef:a6:1a:2a:ac:e2:03:43:
+ ed:9a:bc:3e:8e:75:1b:f0:fd:2e:22:59:ac:13:c0:61:e2:e7:
+ fa:e9:99:cd:87:09:75:54:28:bf:46:60:dc:be:51:2c:92:f3:
+ 1b:91:7c:31:08:70:e2:37:b9:c1:5b:a8:bd:a3:0b:00:fb:1a:
+ 15:fd:03:ad:58:6a:c5:c7:24:99:48:47:46:31:1e:92:ef:b4:
+ 5f:4e:34:c7:90:bf:31:c1:f8:b1:84:86:d0:9c:01:aa:df:8a:
+ 56:06:ce:3a:e9:0e:ae:97:74:5d:d7:71:9a:42:74:5f:de:8d:
+ 43:7c:de:e9:55:ed:69:00:cb:05:e0:7a:61:61:33:d1:19:4d:
+ f9:08:ee:a0:39:c5:25:35:b7:2b:c4:0f:b2:dd:f1:a5:b7:0e:
+ 24:c4:26:28:8d:79:77:f5:2f:f0:57:ba:7c:07:d4:e1:fc:cd:
+ 5a:30:57:7e:86:10:47:dd:31:1f:d7:fc:a2:c2:bf:30:7c:5d:
+ 24:aa:e8:f9:ae:5f:6a:74:c2:ce:6b:b3:46:d8:21:be:29:d4:
+ 8e:5e:15:d6:42:4a:e7:32:6f:a4:b1:6b:51:83:58:be:3f:6d:
+ c7:fb:da:03:21:cb:6a:16:19:4e:0a:f0:ad:84:ca:5d:94:b3:
+ 5a:76:f7:61
+-----BEGIN CERTIFICATE-----
+MIIGWDCCBUCgAwIBAgIQCl8RTQNbF5EX0u/UA4w/OzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA4MDQwMjEyMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR
+CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv
+KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5
+BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf
+1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs
+zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d
+32duXvsCAwEAAaOCAvowggL2MA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w
+ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3
+LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH
+AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy
+AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj
+AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg
+AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ
+AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt
+AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj
+AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl
+AHIAZQBuAGMAZQAuMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAm
+MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSB
+hzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGln
+aEFzc3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNl
+cnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSME
+GDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUB
+INTeeZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAB7ipUiebNtTOA/vphoqrOIDQ+2a
+vD6OdRvw/S4iWawTwGHi5/rpmc2HCXVUKL9GYNy+USyS8xuRfDEIcOI3ucFbqL2j
+CwD7GhX9A61YasXHJJlIR0YxHpLvtF9ONMeQvzHB+LGEhtCcAarfilYGzjrpDq6X
+dF3XcZpCdF/ejUN83ulV7WkAywXgemFhM9EZTfkI7qA5xSU1tyvED7Ld8aW3DiTE
+JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY
+Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E=
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert51[] = {
+ 0x30, 0x82, 0x06, 0x58, 0x30, 0x82, 0x05, 0x40, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x0a, 0x5f, 0x11, 0x4d, 0x03, 0x5b, 0x17, 0x91, 0x17,
+ 0xd2, 0xef, 0xd4, 0x03, 0x8c, 0x3f, 0x3b, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6c,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
+ 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
+ 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
+ 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+ 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x34, 0x30, 0x32, 0x31, 0x32,
+ 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x34, 0x30,
+ 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
+ 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
+ 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
+ 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67,
+ 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20,
+ 0x43, 0x41, 0x2d, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0xbf, 0x61, 0x0a, 0x29, 0x10, 0x1f, 0x5e, 0xfe, 0x34, 0x37, 0x51,
+ 0x08, 0xf8, 0x1e, 0xfb, 0x22, 0xed, 0x61, 0xbe, 0x0b, 0x0d, 0x70, 0x4c,
+ 0x50, 0x63, 0x26, 0x75, 0x15, 0xb9, 0x41, 0x88, 0x97, 0xb6, 0xf0, 0xa0,
+ 0x15, 0xbb, 0x08, 0x60, 0xe0, 0x42, 0xe8, 0x05, 0x29, 0x10, 0x87, 0x36,
+ 0x8a, 0x28, 0x65, 0xa8, 0xef, 0x31, 0x07, 0x74, 0x6d, 0x36, 0x97, 0x2f,
+ 0x28, 0x46, 0x66, 0x04, 0xc7, 0x2a, 0x79, 0x26, 0x7a, 0x99, 0xd5, 0x8e,
+ 0xc3, 0x6d, 0x4f, 0xa0, 0x5e, 0xad, 0xbc, 0x3d, 0x91, 0xc2, 0x59, 0x7b,
+ 0x5e, 0x36, 0x6c, 0xc0, 0x53, 0xcf, 0x00, 0x08, 0x32, 0x3e, 0x10, 0x64,
+ 0x58, 0x10, 0x13, 0x69, 0xc7, 0x0c, 0xee, 0x9c, 0x42, 0x51, 0x00, 0xf9,
+ 0x05, 0x44, 0xee, 0x24, 0xce, 0x7a, 0x1f, 0xed, 0x8c, 0x11, 0xbd, 0x12,
+ 0xa8, 0xf3, 0x15, 0xf4, 0x1c, 0x7a, 0x31, 0x69, 0x01, 0x1b, 0xa7, 0xe6,
+ 0x5d, 0xc0, 0x9a, 0x6c, 0x7e, 0x09, 0x9e, 0xe7, 0x52, 0x44, 0x4a, 0x10,
+ 0x3a, 0x23, 0xe4, 0x9b, 0xb6, 0x03, 0xaf, 0xa8, 0x9c, 0xb4, 0x5b, 0x9f,
+ 0xd4, 0x4b, 0xad, 0x92, 0x8c, 0xce, 0xb5, 0x11, 0x2a, 0xaa, 0x37, 0x18,
+ 0x8d, 0xb4, 0xc2, 0xb8, 0xd8, 0x5c, 0x06, 0x8c, 0xf8, 0xff, 0x23, 0xbd,
+ 0x35, 0x5e, 0xd4, 0x7c, 0x3e, 0x7e, 0x83, 0x0e, 0x91, 0x96, 0x05, 0x98,
+ 0xc3, 0xb2, 0x1f, 0xe3, 0xc8, 0x65, 0xeb, 0xa9, 0x7b, 0x5d, 0xa0, 0x2c,
+ 0xcc, 0xfc, 0x3c, 0xd9, 0x6d, 0xed, 0xcc, 0xfa, 0x4b, 0x43, 0x8c, 0xc9,
+ 0xd4, 0xb8, 0xa5, 0x61, 0x1c, 0xb2, 0x40, 0xb6, 0x28, 0x12, 0xdf, 0xb9,
+ 0xf8, 0x5f, 0xfe, 0xd3, 0xb2, 0xc9, 0xef, 0x3d, 0xb4, 0x1e, 0x4b, 0x7c,
+ 0x1c, 0x4c, 0x99, 0x36, 0x9e, 0x3d, 0xeb, 0xec, 0xa7, 0x68, 0x5e, 0x1d,
+ 0xdf, 0x67, 0x6e, 0x5e, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82,
+ 0x02, 0xfa, 0x30, 0x82, 0x02, 0xf6, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+ 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x82,
+ 0x01, 0xc6, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0xbd, 0x30,
+ 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0xb5, 0x06, 0x0b, 0x60, 0x86, 0x48,
+ 0x01, 0x86, 0xfd, 0x6c, 0x01, 0x03, 0x00, 0x02, 0x30, 0x82, 0x01, 0xa4,
+ 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01,
+ 0x16, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+ 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x73, 0x73, 0x6c, 0x2d, 0x63, 0x70, 0x73, 0x2d, 0x72, 0x65,
+ 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x68, 0x74, 0x6d,
+ 0x30, 0x82, 0x01, 0x64, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x02, 0x30, 0x82, 0x01, 0x56, 0x1e, 0x82, 0x01, 0x52, 0x00, 0x41,
+ 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65,
+ 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68,
+ 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72,
+ 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61,
+ 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e,
+ 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x75, 0x00, 0x74,
+ 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63, 0x00, 0x63,
+ 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
+ 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74,
+ 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x44, 0x00, 0x69, 0x00, 0x67,
+ 0x00, 0x69, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x20,
+ 0x00, 0x43, 0x00, 0x50, 0x00, 0x2f, 0x00, 0x43, 0x00, 0x50, 0x00, 0x53,
+ 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74,
+ 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6c,
+ 0x00, 0x79, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x50,
+ 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x41,
+ 0x00, 0x67, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65,
+ 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x77, 0x00, 0x68, 0x00, 0x69,
+ 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6d,
+ 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x61,
+ 0x00, 0x62, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79,
+ 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x61,
+ 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x63,
+ 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61,
+ 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x68, 0x00, 0x65,
+ 0x00, 0x72, 0x00, 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x62,
+ 0x00, 0x79, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x66, 0x00, 0x65,
+ 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x2e,
+ 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
+ 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x34, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26,
+ 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
+ 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73,
+ 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x30, 0x81, 0x8f, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81,
+ 0x87, 0x30, 0x81, 0x84, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e,
+ 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67,
+ 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56,
+ 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x40,
+ 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65,
+ 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43,
+ 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72,
+ 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41,
+ 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf,
+ 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b,
+ 0xc3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x50, 0xea, 0x73, 0x89, 0xdb, 0x29, 0xfb, 0x10, 0x8f, 0x9e, 0xe5, 0x01,
+ 0x20, 0xd4, 0xde, 0x79, 0x99, 0x48, 0x83, 0xf7, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x1e, 0xe2, 0xa5, 0x48, 0x9e, 0x6c, 0xdb, 0x53,
+ 0x38, 0x0f, 0xef, 0xa6, 0x1a, 0x2a, 0xac, 0xe2, 0x03, 0x43, 0xed, 0x9a,
+ 0xbc, 0x3e, 0x8e, 0x75, 0x1b, 0xf0, 0xfd, 0x2e, 0x22, 0x59, 0xac, 0x13,
+ 0xc0, 0x61, 0xe2, 0xe7, 0xfa, 0xe9, 0x99, 0xcd, 0x87, 0x09, 0x75, 0x54,
+ 0x28, 0xbf, 0x46, 0x60, 0xdc, 0xbe, 0x51, 0x2c, 0x92, 0xf3, 0x1b, 0x91,
+ 0x7c, 0x31, 0x08, 0x70, 0xe2, 0x37, 0xb9, 0xc1, 0x5b, 0xa8, 0xbd, 0xa3,
+ 0x0b, 0x00, 0xfb, 0x1a, 0x15, 0xfd, 0x03, 0xad, 0x58, 0x6a, 0xc5, 0xc7,
+ 0x24, 0x99, 0x48, 0x47, 0x46, 0x31, 0x1e, 0x92, 0xef, 0xb4, 0x5f, 0x4e,
+ 0x34, 0xc7, 0x90, 0xbf, 0x31, 0xc1, 0xf8, 0xb1, 0x84, 0x86, 0xd0, 0x9c,
+ 0x01, 0xaa, 0xdf, 0x8a, 0x56, 0x06, 0xce, 0x3a, 0xe9, 0x0e, 0xae, 0x97,
+ 0x74, 0x5d, 0xd7, 0x71, 0x9a, 0x42, 0x74, 0x5f, 0xde, 0x8d, 0x43, 0x7c,
+ 0xde, 0xe9, 0x55, 0xed, 0x69, 0x00, 0xcb, 0x05, 0xe0, 0x7a, 0x61, 0x61,
+ 0x33, 0xd1, 0x19, 0x4d, 0xf9, 0x08, 0xee, 0xa0, 0x39, 0xc5, 0x25, 0x35,
+ 0xb7, 0x2b, 0xc4, 0x0f, 0xb2, 0xdd, 0xf1, 0xa5, 0xb7, 0x0e, 0x24, 0xc4,
+ 0x26, 0x28, 0x8d, 0x79, 0x77, 0xf5, 0x2f, 0xf0, 0x57, 0xba, 0x7c, 0x07,
+ 0xd4, 0xe1, 0xfc, 0xcd, 0x5a, 0x30, 0x57, 0x7e, 0x86, 0x10, 0x47, 0xdd,
+ 0x31, 0x1f, 0xd7, 0xfc, 0xa2, 0xc2, 0xbf, 0x30, 0x7c, 0x5d, 0x24, 0xaa,
+ 0xe8, 0xf9, 0xae, 0x5f, 0x6a, 0x74, 0xc2, 0xce, 0x6b, 0xb3, 0x46, 0xd8,
+ 0x21, 0xbe, 0x29, 0xd4, 0x8e, 0x5e, 0x15, 0xd6, 0x42, 0x4a, 0xe7, 0x32,
+ 0x6f, 0xa4, 0xb1, 0x6b, 0x51, 0x83, 0x58, 0xbe, 0x3f, 0x6d, 0xc7, 0xfb,
+ 0xda, 0x03, 0x21, 0xcb, 0x6a, 0x16, 0x19, 0x4e, 0x0a, 0xf0, 0xad, 0x84,
+ 0xca, 0x5d, 0x94, 0xb3, 0x5a, 0x76, 0xf7, 0x61,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 7250751724796726 (0x19c28530e93b36)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
+ Validity
+ Not Before: Sep 17 22:46:36 2006 GMT
+ Not After : Dec 31 23:59:59 2019 GMT
+ Subject: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:bd:ca:8d:ac:b8:91:15:56:97:7b:6b:5c:7a:c2:
+ de:6b:d9:a1:b0:c3:10:23:fa:a7:a1:b2:cc:31:fa:
+ 3e:d9:a6:29:6f:16:3d:e0:6b:f8:b8:40:5f:db:39:
+ a8:00:7a:8b:a0:4d:54:7d:c2:22:78:fc:8e:09:b8:
+ a8:85:d7:cc:95:97:4b:74:d8:9e:7e:f0:00:e4:0e:
+ 89:ae:49:28:44:1a:10:99:32:0f:25:88:53:a4:0d:
+ b3:0f:12:08:16:0b:03:71:27:1c:7f:e1:db:d2:fd:
+ 67:68:c4:05:5d:0a:0e:5d:70:d7:d8:97:a0:bc:53:
+ 41:9a:91:8d:f4:9e:36:66:7a:7e:56:c1:90:5f:e6:
+ b1:68:20:36:a4:8c:24:2c:2c:47:0b:59:76:66:30:
+ b5:be:de:ed:8f:f8:9d:d3:bb:01:30:e6:f2:f3:0e:
+ e0:2c:92:80:f3:85:f9:28:8a:b4:54:2e:9a:ed:f7:
+ 76:fc:15:68:16:eb:4a:6c:eb:2e:12:8f:d4:cf:fe:
+ 0c:c7:5c:1d:0b:7e:05:32:be:5e:b0:09:2a:42:d5:
+ c9:4e:90:b3:59:0d:bb:7a:7e:cd:d5:08:5a:b4:7f:
+ d8:1c:69:11:f9:27:0f:7b:06:af:54:83:18:7b:e1:
+ dd:54:7a:51:68:6e:77:fc:c6:bf:52:4a:66:46:a1:
+ b2:67:1a:bb:a3:4f:77:a0:be:5d:ff:fc:56:0b:43:
+ 72:77:90:ca:9e:f9:f2:39:f5:0d:a9:f4:ea:d7:e7:
+ b3:10:2f:30:42:37:21:cc:30:70:c9:86:98:0f:cc:
+ 58:4d:83:bb:7d:e5:1a:a5:37:8d:b6:ac:32:97:00:
+ 3a:63:71:24:1e:9e:37:c4:ff:74:d4:37:c0:e2:fe:
+ 88:46:60:11:dd:08:3f:50:36:ab:b8:7a:a4:95:62:
+ 6a:6e:b0:ca:6a:21:5a:69:f3:f3:fb:1d:70:39:95:
+ f3:a7:6e:a6:81:89:a1:88:c5:3b:71:ca:a3:52:ee:
+ 83:bb:fd:a0:77:f4:e4:6f:e7:42:db:6d:4a:99:8a:
+ 34:48:bc:17:dc:e4:80:08:22:b6:f2:31:c0:3f:04:
+ 3e:eb:9f:20:79:d6:b8:06:64:64:02:31:d7:a9:cd:
+ 52:fb:84:45:69:09:00:2a:dc:55:8b:c4:06:46:4b:
+ c0:4a:1d:09:5b:39:28:fd:a9:ab:ce:00:f9:2e:48:
+ 4b:26:e6:30:4c:a5:58:ca:b4:44:82:4f:e7:91:1e:
+ 33:c3:b0:93:ff:11:fc:81:d2:ca:1f:71:29:dd:76:
+ 4f:92:25:af:1d:81:b7:0f:2f:8c:c3:06:cc:2f:27:
+ a3:4a:e4:0e:99:ba:7c:1e:45:1f:7f:aa:19:45:96:
+ fd:fc:3d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:2
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E
+ X509v3 Authority Key Identifier:
+ keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.startssl.com/ca
+ CA Issuers - URI:http://aia.startssl.com/certs/ca.crt
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl.startssl.com/sfsca.crl
+
+ Signature Algorithm: sha256WithRSAEncryption
+ b6:6d:f8:70:fb:e2:0d:4c:98:b3:07:49:15:f5:04:c4:6c:ca:
+ ca:f5:68:a0:08:fe:12:6d:9c:04:06:c9:ad:9a:91:52:3e:78:
+ c4:5c:ee:9f:54:1d:ee:e3:f1:5e:30:c9:49:e1:39:e0:a6:9d:
+ 36:6c:57:fa:e6:34:4f:55:e8:87:a8:2c:dd:05:f1:58:12:91:
+ e8:ca:ce:28:78:8f:df:07:85:01:a5:dc:45:96:05:d4:80:b2:
+ 2b:05:9a:cb:9a:a5:8b:e0:3a:67:e6:73:47:be:4a:fd:27:b1:
+ 88:ef:e6:ca:cf:8d:0e:26:9f:fa:5f:57:78:ad:6d:fe:ae:9b:
+ 35:08:b1:c3:ba:c1:00:4a:4b:7d:14:bd:f7:f1:d3:55:18:ac:
+ d0:33:70:88:6d:c4:09:71:14:a6:2b:4f:88:81:e7:0b:00:37:
+ a9:15:7d:7e:d7:01:96:3f:2f:af:7b:62:ae:0a:4a:bf:4b:39:
+ 2e:35:10:8b:fe:04:39:e4:3c:3a:0c:09:56:40:3a:b5:f4:c2:
+ 68:0c:b5:f9:52:cd:ee:9d:f8:98:fc:78:e7:58:47:8f:1c:73:
+ 58:69:33:ab:ff:dd:df:8e:24:01:77:98:19:3a:b0:66:79:bc:
+ e1:08:a3:0e:4f:c1:04:b3:f3:01:c8:eb:d3:59:1c:35:d2:93:
+ 1e:70:65:82:7f:db:cf:fb:c8:99:12:60:c3:44:6f:3a:80:4b:
+ d7:be:21:aa:14:7a:64:cb:dd:37:43:45:5b:32:2e:45:f0:d9:
+ 59:1f:6b:18:f0:7c:e9:55:36:19:61:5f:b5:7d:f1:8d:bd:88:
+ e4:75:4b:98:dd:27:b0:e4:84:44:2a:61:84:57:05:82:11:1f:
+ aa:35:58:f3:20:0e:af:59:ef:fa:55:72:72:0d:26:d0:9b:53:
+ 49:ac:ce:37:2e:65:61:ff:f6:ec:1b:ea:f6:f1:a6:d3:d1:b5:
+ 7b:be:35:f4:22:c1:bc:8d:01:bd:68:5e:83:0d:2f:ec:d6:da:
+ 63:0c:27:d1:54:3e:e4:a8:d3:ce:4b:32:b8:91:94:ff:fb:5b:
+ 49:2d:75:18:a8:ba:71:9a:3b:ae:d9:c0:a9:4f:87:91:ed:8b:
+ 7b:6b:20:98:89:39:83:4f:80:c4:69:cc:17:c9:c8:4e:be:e4:
+ a9:a5:81:76:70:06:04:32:cd:83:65:f4:bc:7d:3e:13:bc:d2:
+ e8:6f:63:aa:b5:3b:da:8d:86:32:82:78:9d:d9:cc:ff:bf:57:
+ 64:74:ed:28:3d:44:62:15:61:4b:f7:94:b0:0d:2a:67:1c:f0:
+ cb:9b:a5:92:bf:f8:41:5a:c1:3d:60:ed:9f:bb:b8:6d:9b:ce:
+ a9:6a:16:3f:7e:ea:06:f1
+-----BEGIN CERTIFICATE-----
+MIIGXDCCBESgAwIBAgIHGcKFMOk7NjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG
+EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
+Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MjI0NjM2WhcNMTkxMjMxMjM1
+OTU5WjBVMQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQx
+KjAoBgNVBAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL3Kjay4kRVWl3trXHrC3mvZobDD
+ECP6p6GyzDH6PtmmKW8WPeBr+LhAX9s5qAB6i6BNVH3CInj8jgm4qIXXzJWXS3TY
+nn7wAOQOia5JKEQaEJkyDyWIU6QNsw8SCBYLA3EnHH/h29L9Z2jEBV0KDl1w19iX
+oLxTQZqRjfSeNmZ6flbBkF/msWggNqSMJCwsRwtZdmYwtb7e7Y/4ndO7ATDm8vMO
+4CySgPOF+SiKtFQumu33dvwVaBbrSmzrLhKP1M/+DMdcHQt+BTK+XrAJKkLVyU6Q
+s1kNu3p+zdUIWrR/2BxpEfknD3sGr1SDGHvh3VR6UWhud/zGv1JKZkahsmcau6NP
+d6C+Xf/8VgtDcneQyp758jn1Dan06tfnsxAvMEI3IcwwcMmGmA/MWE2Du33lGqU3
+jbasMpcAOmNxJB6eN8T/dNQ3wOL+iEZgEd0IP1A2q7h6pJViam6wymohWmnz8/sd
+cDmV86dupoGJoYjFO3HKo1Lug7v9oHf05G/nQtttSpmKNEi8F9zkgAgitvIxwD8E
+PuufIHnWuAZkZAIx16nNUvuERWkJACrcVYvEBkZLwEodCVs5KP2pq84A+S5ISybm
+MEylWMq0RIJP55EeM8Owk/8R/IHSyh9xKd12T5Ilrx2Btw8vjMMGzC8no0rkDpm6
+fB5FH3+qGUWW/fw9AgMBAAGjggEHMIIBAzASBgNVHRMBAf8ECDAGAQH/AgECMA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU4WbPDtHxs0u3BiAU/ocS1fb++z4wHwYD
+VR0jBBgwFoAUTgvvGqRAW6UXaYcwyjRoQ9BBrvIwaQYIKwYBBQUHAQEEXTBbMCcG
+CCsGAQUFBzABhhtodHRwOi8vb2NzcC5zdGFydHNzbC5jb20vY2EwMAYIKwYBBQUH
+MAKGJGh0dHA6Ly9haWEuc3RhcnRzc2wuY29tL2NlcnRzL2NhLmNydDAyBgNVHR8E
+KzApMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5jcmwwDQYJ
+KoZIhvcNAQELBQADggIBALZt+HD74g1MmLMHSRX1BMRsysr1aKAI/hJtnAQGya2a
+kVI+eMRc7p9UHe7j8V4wyUnhOeCmnTZsV/rmNE9V6IeoLN0F8VgSkejKzih4j98H
+hQGl3EWWBdSAsisFmsuapYvgOmfmc0e+Sv0nsYjv5srPjQ4mn/pfV3itbf6umzUI
+scO6wQBKS30Uvffx01UYrNAzcIhtxAlxFKYrT4iB5wsAN6kVfX7XAZY/L697Yq4K
+Sr9LOS41EIv+BDnkPDoMCVZAOrX0wmgMtflSze6d+Jj8eOdYR48cc1hpM6v/3d+O
+JAF3mBk6sGZ5vOEIow5PwQSz8wHI69NZHDXSkx5wZYJ/28/7yJkSYMNEbzqAS9e+
+IaoUemTL3TdDRVsyLkXw2VkfaxjwfOlVNhlhX7V98Y29iOR1S5jdJ7DkhEQqYYRX
+BYIRH6o1WPMgDq9Z7/pVcnINJtCbU0mszjcuZWH/9uwb6vbxptPRtXu+NfQiwbyN
+Ab1oXoMNL+zW2mMMJ9FUPuSo085LMriRlP/7W0ktdRiounGaO67ZwKlPh5Hti3tr
+IJiJOYNPgMRpzBfJyE6+5KmlgXZwBgQyzYNl9Lx9PhO80uhvY6q1O9qNhjKCeJ3Z
+zP+/V2R07Sg9RGIVYUv3lLANKmcc8MubpZK/+EFawT1g7Z+7uG2bzqlqFj9+6gbx
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert52[] = {
+ 0x30, 0x82, 0x06, 0x5c, 0x30, 0x82, 0x04, 0x44, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x07, 0x19, 0xc2, 0x85, 0x30, 0xe9, 0x3b, 0x36, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
+ 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20,
+ 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04,
+ 0x0b, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69,
+ 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+ 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
+ 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20,
+ 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+ 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d,
+ 0x30, 0x36, 0x30, 0x39, 0x31, 0x37, 0x32, 0x32, 0x34, 0x36, 0x33, 0x36,
+ 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35,
+ 0x39, 0x35, 0x39, 0x5a, 0x30, 0x55, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06,
+ 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e,
+ 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31,
+ 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x43, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+ 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66,
+ 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x30, 0x82, 0x02, 0x22, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+ 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02,
+ 0x82, 0x02, 0x01, 0x00, 0xbd, 0xca, 0x8d, 0xac, 0xb8, 0x91, 0x15, 0x56,
+ 0x97, 0x7b, 0x6b, 0x5c, 0x7a, 0xc2, 0xde, 0x6b, 0xd9, 0xa1, 0xb0, 0xc3,
+ 0x10, 0x23, 0xfa, 0xa7, 0xa1, 0xb2, 0xcc, 0x31, 0xfa, 0x3e, 0xd9, 0xa6,
+ 0x29, 0x6f, 0x16, 0x3d, 0xe0, 0x6b, 0xf8, 0xb8, 0x40, 0x5f, 0xdb, 0x39,
+ 0xa8, 0x00, 0x7a, 0x8b, 0xa0, 0x4d, 0x54, 0x7d, 0xc2, 0x22, 0x78, 0xfc,
+ 0x8e, 0x09, 0xb8, 0xa8, 0x85, 0xd7, 0xcc, 0x95, 0x97, 0x4b, 0x74, 0xd8,
+ 0x9e, 0x7e, 0xf0, 0x00, 0xe4, 0x0e, 0x89, 0xae, 0x49, 0x28, 0x44, 0x1a,
+ 0x10, 0x99, 0x32, 0x0f, 0x25, 0x88, 0x53, 0xa4, 0x0d, 0xb3, 0x0f, 0x12,
+ 0x08, 0x16, 0x0b, 0x03, 0x71, 0x27, 0x1c, 0x7f, 0xe1, 0xdb, 0xd2, 0xfd,
+ 0x67, 0x68, 0xc4, 0x05, 0x5d, 0x0a, 0x0e, 0x5d, 0x70, 0xd7, 0xd8, 0x97,
+ 0xa0, 0xbc, 0x53, 0x41, 0x9a, 0x91, 0x8d, 0xf4, 0x9e, 0x36, 0x66, 0x7a,
+ 0x7e, 0x56, 0xc1, 0x90, 0x5f, 0xe6, 0xb1, 0x68, 0x20, 0x36, 0xa4, 0x8c,
+ 0x24, 0x2c, 0x2c, 0x47, 0x0b, 0x59, 0x76, 0x66, 0x30, 0xb5, 0xbe, 0xde,
+ 0xed, 0x8f, 0xf8, 0x9d, 0xd3, 0xbb, 0x01, 0x30, 0xe6, 0xf2, 0xf3, 0x0e,
+ 0xe0, 0x2c, 0x92, 0x80, 0xf3, 0x85, 0xf9, 0x28, 0x8a, 0xb4, 0x54, 0x2e,
+ 0x9a, 0xed, 0xf7, 0x76, 0xfc, 0x15, 0x68, 0x16, 0xeb, 0x4a, 0x6c, 0xeb,
+ 0x2e, 0x12, 0x8f, 0xd4, 0xcf, 0xfe, 0x0c, 0xc7, 0x5c, 0x1d, 0x0b, 0x7e,
+ 0x05, 0x32, 0xbe, 0x5e, 0xb0, 0x09, 0x2a, 0x42, 0xd5, 0xc9, 0x4e, 0x90,
+ 0xb3, 0x59, 0x0d, 0xbb, 0x7a, 0x7e, 0xcd, 0xd5, 0x08, 0x5a, 0xb4, 0x7f,
+ 0xd8, 0x1c, 0x69, 0x11, 0xf9, 0x27, 0x0f, 0x7b, 0x06, 0xaf, 0x54, 0x83,
+ 0x18, 0x7b, 0xe1, 0xdd, 0x54, 0x7a, 0x51, 0x68, 0x6e, 0x77, 0xfc, 0xc6,
+ 0xbf, 0x52, 0x4a, 0x66, 0x46, 0xa1, 0xb2, 0x67, 0x1a, 0xbb, 0xa3, 0x4f,
+ 0x77, 0xa0, 0xbe, 0x5d, 0xff, 0xfc, 0x56, 0x0b, 0x43, 0x72, 0x77, 0x90,
+ 0xca, 0x9e, 0xf9, 0xf2, 0x39, 0xf5, 0x0d, 0xa9, 0xf4, 0xea, 0xd7, 0xe7,
+ 0xb3, 0x10, 0x2f, 0x30, 0x42, 0x37, 0x21, 0xcc, 0x30, 0x70, 0xc9, 0x86,
+ 0x98, 0x0f, 0xcc, 0x58, 0x4d, 0x83, 0xbb, 0x7d, 0xe5, 0x1a, 0xa5, 0x37,
+ 0x8d, 0xb6, 0xac, 0x32, 0x97, 0x00, 0x3a, 0x63, 0x71, 0x24, 0x1e, 0x9e,
+ 0x37, 0xc4, 0xff, 0x74, 0xd4, 0x37, 0xc0, 0xe2, 0xfe, 0x88, 0x46, 0x60,
+ 0x11, 0xdd, 0x08, 0x3f, 0x50, 0x36, 0xab, 0xb8, 0x7a, 0xa4, 0x95, 0x62,
+ 0x6a, 0x6e, 0xb0, 0xca, 0x6a, 0x21, 0x5a, 0x69, 0xf3, 0xf3, 0xfb, 0x1d,
+ 0x70, 0x39, 0x95, 0xf3, 0xa7, 0x6e, 0xa6, 0x81, 0x89, 0xa1, 0x88, 0xc5,
+ 0x3b, 0x71, 0xca, 0xa3, 0x52, 0xee, 0x83, 0xbb, 0xfd, 0xa0, 0x77, 0xf4,
+ 0xe4, 0x6f, 0xe7, 0x42, 0xdb, 0x6d, 0x4a, 0x99, 0x8a, 0x34, 0x48, 0xbc,
+ 0x17, 0xdc, 0xe4, 0x80, 0x08, 0x22, 0xb6, 0xf2, 0x31, 0xc0, 0x3f, 0x04,
+ 0x3e, 0xeb, 0x9f, 0x20, 0x79, 0xd6, 0xb8, 0x06, 0x64, 0x64, 0x02, 0x31,
+ 0xd7, 0xa9, 0xcd, 0x52, 0xfb, 0x84, 0x45, 0x69, 0x09, 0x00, 0x2a, 0xdc,
+ 0x55, 0x8b, 0xc4, 0x06, 0x46, 0x4b, 0xc0, 0x4a, 0x1d, 0x09, 0x5b, 0x39,
+ 0x28, 0xfd, 0xa9, 0xab, 0xce, 0x00, 0xf9, 0x2e, 0x48, 0x4b, 0x26, 0xe6,
+ 0x30, 0x4c, 0xa5, 0x58, 0xca, 0xb4, 0x44, 0x82, 0x4f, 0xe7, 0x91, 0x1e,
+ 0x33, 0xc3, 0xb0, 0x93, 0xff, 0x11, 0xfc, 0x81, 0xd2, 0xca, 0x1f, 0x71,
+ 0x29, 0xdd, 0x76, 0x4f, 0x92, 0x25, 0xaf, 0x1d, 0x81, 0xb7, 0x0f, 0x2f,
+ 0x8c, 0xc3, 0x06, 0xcc, 0x2f, 0x27, 0xa3, 0x4a, 0xe4, 0x0e, 0x99, 0xba,
+ 0x7c, 0x1e, 0x45, 0x1f, 0x7f, 0xaa, 0x19, 0x45, 0x96, 0xfd, 0xfc, 0x3d,
+ 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x07, 0x30, 0x82, 0x01,
+ 0x03, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+ 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+ 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0xe1, 0x66, 0xcf, 0x0e, 0xd1, 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14,
+ 0xfe, 0x87, 0x12, 0xd5, 0xf6, 0xfe, 0xfb, 0x3e, 0x30, 0x1f, 0x06, 0x03,
+ 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef,
+ 0x1a, 0xa4, 0x40, 0x5b, 0xa5, 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68,
+ 0x43, 0xd0, 0x41, 0xae, 0xf2, 0x30, 0x69, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x5d, 0x30, 0x5b, 0x30, 0x27, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x63, 0x61, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x02, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61,
+ 0x69, 0x61, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x63, 0x61,
+ 0x2e, 0x63, 0x72, 0x74, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+ 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74,
+ 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73,
+ 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+ 0x82, 0x02, 0x01, 0x00, 0xb6, 0x6d, 0xf8, 0x70, 0xfb, 0xe2, 0x0d, 0x4c,
+ 0x98, 0xb3, 0x07, 0x49, 0x15, 0xf5, 0x04, 0xc4, 0x6c, 0xca, 0xca, 0xf5,
+ 0x68, 0xa0, 0x08, 0xfe, 0x12, 0x6d, 0x9c, 0x04, 0x06, 0xc9, 0xad, 0x9a,
+ 0x91, 0x52, 0x3e, 0x78, 0xc4, 0x5c, 0xee, 0x9f, 0x54, 0x1d, 0xee, 0xe3,
+ 0xf1, 0x5e, 0x30, 0xc9, 0x49, 0xe1, 0x39, 0xe0, 0xa6, 0x9d, 0x36, 0x6c,
+ 0x57, 0xfa, 0xe6, 0x34, 0x4f, 0x55, 0xe8, 0x87, 0xa8, 0x2c, 0xdd, 0x05,
+ 0xf1, 0x58, 0x12, 0x91, 0xe8, 0xca, 0xce, 0x28, 0x78, 0x8f, 0xdf, 0x07,
+ 0x85, 0x01, 0xa5, 0xdc, 0x45, 0x96, 0x05, 0xd4, 0x80, 0xb2, 0x2b, 0x05,
+ 0x9a, 0xcb, 0x9a, 0xa5, 0x8b, 0xe0, 0x3a, 0x67, 0xe6, 0x73, 0x47, 0xbe,
+ 0x4a, 0xfd, 0x27, 0xb1, 0x88, 0xef, 0xe6, 0xca, 0xcf, 0x8d, 0x0e, 0x26,
+ 0x9f, 0xfa, 0x5f, 0x57, 0x78, 0xad, 0x6d, 0xfe, 0xae, 0x9b, 0x35, 0x08,
+ 0xb1, 0xc3, 0xba, 0xc1, 0x00, 0x4a, 0x4b, 0x7d, 0x14, 0xbd, 0xf7, 0xf1,
+ 0xd3, 0x55, 0x18, 0xac, 0xd0, 0x33, 0x70, 0x88, 0x6d, 0xc4, 0x09, 0x71,
+ 0x14, 0xa6, 0x2b, 0x4f, 0x88, 0x81, 0xe7, 0x0b, 0x00, 0x37, 0xa9, 0x15,
+ 0x7d, 0x7e, 0xd7, 0x01, 0x96, 0x3f, 0x2f, 0xaf, 0x7b, 0x62, 0xae, 0x0a,
+ 0x4a, 0xbf, 0x4b, 0x39, 0x2e, 0x35, 0x10, 0x8b, 0xfe, 0x04, 0x39, 0xe4,
+ 0x3c, 0x3a, 0x0c, 0x09, 0x56, 0x40, 0x3a, 0xb5, 0xf4, 0xc2, 0x68, 0x0c,
+ 0xb5, 0xf9, 0x52, 0xcd, 0xee, 0x9d, 0xf8, 0x98, 0xfc, 0x78, 0xe7, 0x58,
+ 0x47, 0x8f, 0x1c, 0x73, 0x58, 0x69, 0x33, 0xab, 0xff, 0xdd, 0xdf, 0x8e,
+ 0x24, 0x01, 0x77, 0x98, 0x19, 0x3a, 0xb0, 0x66, 0x79, 0xbc, 0xe1, 0x08,
+ 0xa3, 0x0e, 0x4f, 0xc1, 0x04, 0xb3, 0xf3, 0x01, 0xc8, 0xeb, 0xd3, 0x59,
+ 0x1c, 0x35, 0xd2, 0x93, 0x1e, 0x70, 0x65, 0x82, 0x7f, 0xdb, 0xcf, 0xfb,
+ 0xc8, 0x99, 0x12, 0x60, 0xc3, 0x44, 0x6f, 0x3a, 0x80, 0x4b, 0xd7, 0xbe,
+ 0x21, 0xaa, 0x14, 0x7a, 0x64, 0xcb, 0xdd, 0x37, 0x43, 0x45, 0x5b, 0x32,
+ 0x2e, 0x45, 0xf0, 0xd9, 0x59, 0x1f, 0x6b, 0x18, 0xf0, 0x7c, 0xe9, 0x55,
+ 0x36, 0x19, 0x61, 0x5f, 0xb5, 0x7d, 0xf1, 0x8d, 0xbd, 0x88, 0xe4, 0x75,
+ 0x4b, 0x98, 0xdd, 0x27, 0xb0, 0xe4, 0x84, 0x44, 0x2a, 0x61, 0x84, 0x57,
+ 0x05, 0x82, 0x11, 0x1f, 0xaa, 0x35, 0x58, 0xf3, 0x20, 0x0e, 0xaf, 0x59,
+ 0xef, 0xfa, 0x55, 0x72, 0x72, 0x0d, 0x26, 0xd0, 0x9b, 0x53, 0x49, 0xac,
+ 0xce, 0x37, 0x2e, 0x65, 0x61, 0xff, 0xf6, 0xec, 0x1b, 0xea, 0xf6, 0xf1,
+ 0xa6, 0xd3, 0xd1, 0xb5, 0x7b, 0xbe, 0x35, 0xf4, 0x22, 0xc1, 0xbc, 0x8d,
+ 0x01, 0xbd, 0x68, 0x5e, 0x83, 0x0d, 0x2f, 0xec, 0xd6, 0xda, 0x63, 0x0c,
+ 0x27, 0xd1, 0x54, 0x3e, 0xe4, 0xa8, 0xd3, 0xce, 0x4b, 0x32, 0xb8, 0x91,
+ 0x94, 0xff, 0xfb, 0x5b, 0x49, 0x2d, 0x75, 0x18, 0xa8, 0xba, 0x71, 0x9a,
+ 0x3b, 0xae, 0xd9, 0xc0, 0xa9, 0x4f, 0x87, 0x91, 0xed, 0x8b, 0x7b, 0x6b,
+ 0x20, 0x98, 0x89, 0x39, 0x83, 0x4f, 0x80, 0xc4, 0x69, 0xcc, 0x17, 0xc9,
+ 0xc8, 0x4e, 0xbe, 0xe4, 0xa9, 0xa5, 0x81, 0x76, 0x70, 0x06, 0x04, 0x32,
+ 0xcd, 0x83, 0x65, 0xf4, 0xbc, 0x7d, 0x3e, 0x13, 0xbc, 0xd2, 0xe8, 0x6f,
+ 0x63, 0xaa, 0xb5, 0x3b, 0xda, 0x8d, 0x86, 0x32, 0x82, 0x78, 0x9d, 0xd9,
+ 0xcc, 0xff, 0xbf, 0x57, 0x64, 0x74, 0xed, 0x28, 0x3d, 0x44, 0x62, 0x15,
+ 0x61, 0x4b, 0xf7, 0x94, 0xb0, 0x0d, 0x2a, 0x67, 0x1c, 0xf0, 0xcb, 0x9b,
+ 0xa5, 0x92, 0xbf, 0xf8, 0x41, 0x5a, 0xc1, 0x3d, 0x60, 0xed, 0x9f, 0xbb,
+ 0xb8, 0x6d, 0x9b, 0xce, 0xa9, 0x6a, 0x16, 0x3f, 0x7e, 0xea, 0x06, 0xf1,
+};
+
+#if 0
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 03:37:b9:28:34:7c:60:a6:ae:c5:ad:b1:21:7f:38:60
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
+ Validity
+ Not Before: Nov 9 12:00:00 2007 GMT
+ Not After : Nov 10 00:00:00 2021 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV CA-1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:f3:96:62:d8:75:6e:19:ff:3f:34:7c:49:4f:31:
+ 7e:0d:04:4e:99:81:e2:b3:85:55:91:30:b1:c0:af:
+ 70:bb:2c:a8:e7:18:aa:3f:78:f7:90:68:52:86:01:
+ 88:97:e2:3b:06:65:90:aa:bd:65:76:c2:ec:be:10:
+ 5b:37:78:83:60:75:45:c6:bd:74:aa:b6:9f:a4:3a:
+ 01:50:17:c4:39:69:b9:f1:4f:ef:82:c1:ca:f3:4a:
+ db:cc:9e:50:4f:4d:40:a3:3a:90:e7:86:66:bc:f0:
+ 3e:76:28:4c:d1:75:80:9e:6a:35:14:35:03:9e:db:
+ 0c:8c:c2:28:ad:50:b2:ce:f6:91:a3:c3:a5:0a:58:
+ 49:f6:75:44:6c:ba:f9:ce:e9:ab:3a:02:e0:4d:f3:
+ ac:e2:7a:e0:60:22:05:3c:82:d3:52:e2:f3:9c:47:
+ f8:3b:d8:b2:4b:93:56:4a:bf:70:ab:3e:e9:68:c8:
+ 1d:8f:58:1d:2a:4d:5e:27:3d:ad:0a:59:2f:5a:11:
+ 20:40:d9:68:04:68:2d:f4:c0:84:0b:0a:1b:78:df:
+ ed:1a:58:dc:fb:41:5a:6d:6b:f2:ed:1c:ee:5c:32:
+ b6:5c:ec:d7:a6:03:32:a6:e8:de:b7:28:27:59:88:
+ 80:ff:7b:ad:89:58:d5:1e:14:a4:f2:b0:70:d4:a0:
+ 3e:a7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, E-mail Protection, Time Stamping
+ X509v3 Certificate Policies:
+ Policy: 2.16.840.1.114412.2.1
+ CPS: http://www.digicert.com/ssl-cps-repository.htm
+ User Notice:
+ Explicit Text:
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:0
+ Authority Information Access:
+ OCSP - URI:http://ocsp.digicert.com
+ CA Issuers - URI:http://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://crl3.digicert.com/DigiCertHighAssuranceEVRootCA.crl
+
+ Full Name:
+ URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl
+
+ X509v3 Subject Key Identifier:
+ 4C:58:CB:25:F0:41:4F:52:F4:28:C8:81:43:9B:A6:A8:A0:E6:92:E5
+ X509v3 Authority Key Identifier:
+ keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 4c:7a:17:87:28:5d:17:bc:b2:32:73:bf:cd:2e:f5:58:31:1d:
+ f0:b1:71:54:9c:d6:9b:67:93:db:2f:03:3e:16:6f:1e:03:c9:
+ 53:84:a3:56:60:1e:78:94:1b:a2:a8:6f:a3:a4:8b:52:91:d7:
+ dd:5c:95:bb:ef:b5:16:49:e9:a5:42:4f:34:f2:47:ff:ae:81:
+ 7f:13:54:b7:20:c4:70:15:cb:81:0a:81:cb:74:57:dc:9c:df:
+ 24:a4:29:0c:18:f0:1c:e4:ae:07:33:ec:f1:49:3e:55:cf:6e:
+ 4f:0d:54:7b:d3:c9:e8:15:48:d4:c5:bb:dc:35:1c:77:45:07:
+ 48:45:85:bd:d7:7e:53:b8:c0:16:d9:95:cd:8b:8d:7d:c9:60:
+ 4f:d1:a2:9b:e3:d0:30:d6:b4:73:36:e6:d2:f9:03:b2:e3:a4:
+ f5:e5:b8:3e:04:49:00:ba:2e:a6:4a:72:83:72:9d:f7:0b:8c:
+ a9:89:e7:b3:d7:64:1f:d6:e3:60:cb:03:c4:dc:88:e9:9d:25:
+ 01:00:71:cb:03:b4:29:60:25:8f:f9:46:d1:7b:71:ae:cd:53:
+ 12:5b:84:8e:c2:0f:c7:ed:93:19:d9:c9:fa:8f:58:34:76:32:
+ 2f:ae:e1:50:14:61:d4:a8:58:a3:c8:30:13:23:ef:c6:25:8c:
+ 36:8f:1c:80
+-----BEGIN CERTIFICATE-----
+MIIG5jCCBc6gAwIBAgIQAze5KDR8YKauxa2xIX84YDANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA3MTEwOTEyMDAwMFoXDTIxMTExMDAwMDAwMFowaTEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTEoMCYGA1UEAxMfRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgQ0EtMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPOWYth1bhn/
+PzR8SU8xfg0ETpmB4rOFVZEwscCvcLssqOcYqj9495BoUoYBiJfiOwZlkKq9ZXbC
+7L4QWzd4g2B1Rca9dKq2n6Q6AVAXxDlpufFP74LByvNK28yeUE9NQKM6kOeGZrzw
+PnYoTNF1gJ5qNRQ1A57bDIzCKK1Qss72kaPDpQpYSfZ1RGy6+c7pqzoC4E3zrOJ6
+4GAiBTyC01Li85xH+DvYskuTVkq/cKs+6WjIHY9YHSpNXic9rQpZL1oRIEDZaARo
+LfTAhAsKG3jf7RpY3PtBWm1r8u0c7lwytlzs16YDMqbo3rcoJ1mIgP97rYlY1R4U
+pPKwcNSgPqcCAwEAAaOCA4UwggOBMA4GA1UdDwEB/wQEAwIBhjA7BgNVHSUENDAy
+BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUH
+AwgwggHEBgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwCATCCAaQwOgYIKwYBBQUH
+AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5o
+dG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0
+AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1
+AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABp
+AGcAaQBDAGUAcgB0ACAARQBWACAAQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBl
+AGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBo
+AGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAg
+AGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAg
+AGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wEgYDVR0TAQH/BAgwBgEB/wIBADCB
+gwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
+dC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NBQ2Vy
+dHMvRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3J0MIGPBgNVHR8EgYcw
+gYQwQKA+oDyGOmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hB
+c3N1cmFuY2VFVlJvb3RDQS5jcmwwQKA+oDyGOmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0
+LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwHQYDVR0OBBYE
+FExYyyXwQU9S9CjIgUObpqig5pLlMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSYJhoI
+Au9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQBMeheHKF0XvLIyc7/NLvVYMR3wsXFU
+nNabZ5PbLwM+Fm8eA8lThKNWYB54lBuiqG+jpItSkdfdXJW777UWSemlQk808kf/
+roF/E1S3IMRwFcuBCoHLdFfcnN8kpCkMGPAc5K4HM+zxST5Vz25PDVR708noFUjU
+xbvcNRx3RQdIRYW9135TuMAW2ZXNi419yWBP0aKb49Aw1rRzNubS+QOy46T15bg+
+BEkAui6mSnKDcp33C4ypieez12Qf1uNgywPE3IjpnSUBAHHLA7QpYCWP+UbRe3Gu
+zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
+-----END CERTIFICATE-----
+#endif
+static const unsigned char kDERCert53[] = {
+ 0x30, 0x82, 0x06, 0xe6, 0x30, 0x82, 0x05, 0xce, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x10, 0x03, 0x37, 0xb9, 0x28, 0x34, 0x7c, 0x60, 0xa6, 0xae,
+ 0xc5, 0xad, 0xb1, 0x21, 0x7f, 0x38, 0x60, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6c,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+ 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63,
+ 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77,
+ 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
+ 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
+ 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+ 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x31, 0x31, 0x30, 0x39, 0x31, 0x32,
+ 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x31,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x69, 0x31, 0x0b,
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69,
+ 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19,
+ 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77,
+ 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1f,
+ 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67,
+ 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20,
+ 0x45, 0x56, 0x20, 0x43, 0x41, 0x2d, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
+ 0x82, 0x01, 0x01, 0x00, 0xf3, 0x96, 0x62, 0xd8, 0x75, 0x6e, 0x19, 0xff,
+ 0x3f, 0x34, 0x7c, 0x49, 0x4f, 0x31, 0x7e, 0x0d, 0x04, 0x4e, 0x99, 0x81,
+ 0xe2, 0xb3, 0x85, 0x55, 0x91, 0x30, 0xb1, 0xc0, 0xaf, 0x70, 0xbb, 0x2c,
+ 0xa8, 0xe7, 0x18, 0xaa, 0x3f, 0x78, 0xf7, 0x90, 0x68, 0x52, 0x86, 0x01,
+ 0x88, 0x97, 0xe2, 0x3b, 0x06, 0x65, 0x90, 0xaa, 0xbd, 0x65, 0x76, 0xc2,
+ 0xec, 0xbe, 0x10, 0x5b, 0x37, 0x78, 0x83, 0x60, 0x75, 0x45, 0xc6, 0xbd,
+ 0x74, 0xaa, 0xb6, 0x9f, 0xa4, 0x3a, 0x01, 0x50, 0x17, 0xc4, 0x39, 0x69,
+ 0xb9, 0xf1, 0x4f, 0xef, 0x82, 0xc1, 0xca, 0xf3, 0x4a, 0xdb, 0xcc, 0x9e,
+ 0x50, 0x4f, 0x4d, 0x40, 0xa3, 0x3a, 0x90, 0xe7, 0x86, 0x66, 0xbc, 0xf0,
+ 0x3e, 0x76, 0x28, 0x4c, 0xd1, 0x75, 0x80, 0x9e, 0x6a, 0x35, 0x14, 0x35,
+ 0x03, 0x9e, 0xdb, 0x0c, 0x8c, 0xc2, 0x28, 0xad, 0x50, 0xb2, 0xce, 0xf6,
+ 0x91, 0xa3, 0xc3, 0xa5, 0x0a, 0x58, 0x49, 0xf6, 0x75, 0x44, 0x6c, 0xba,
+ 0xf9, 0xce, 0xe9, 0xab, 0x3a, 0x02, 0xe0, 0x4d, 0xf3, 0xac, 0xe2, 0x7a,
+ 0xe0, 0x60, 0x22, 0x05, 0x3c, 0x82, 0xd3, 0x52, 0xe2, 0xf3, 0x9c, 0x47,
+ 0xf8, 0x3b, 0xd8, 0xb2, 0x4b, 0x93, 0x56, 0x4a, 0xbf, 0x70, 0xab, 0x3e,
+ 0xe9, 0x68, 0xc8, 0x1d, 0x8f, 0x58, 0x1d, 0x2a, 0x4d, 0x5e, 0x27, 0x3d,
+ 0xad, 0x0a, 0x59, 0x2f, 0x5a, 0x11, 0x20, 0x40, 0xd9, 0x68, 0x04, 0x68,
+ 0x2d, 0xf4, 0xc0, 0x84, 0x0b, 0x0a, 0x1b, 0x78, 0xdf, 0xed, 0x1a, 0x58,
+ 0xdc, 0xfb, 0x41, 0x5a, 0x6d, 0x6b, 0xf2, 0xed, 0x1c, 0xee, 0x5c, 0x32,
+ 0xb6, 0x5c, 0xec, 0xd7, 0xa6, 0x03, 0x32, 0xa6, 0xe8, 0xde, 0xb7, 0x28,
+ 0x27, 0x59, 0x88, 0x80, 0xff, 0x7b, 0xad, 0x89, 0x58, 0xd5, 0x1e, 0x14,
+ 0xa4, 0xf2, 0xb0, 0x70, 0xd4, 0xa0, 0x3e, 0xa7, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x82, 0x03, 0x85, 0x30, 0x82, 0x03, 0x81, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+ 0x86, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x34, 0x30, 0x32,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x04, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x03, 0x08, 0x30, 0x82, 0x01, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+ 0x82, 0x01, 0xbb, 0x30, 0x82, 0x01, 0xb7, 0x30, 0x82, 0x01, 0xb3, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6c, 0x02, 0x01, 0x30, 0x82,
+ 0x01, 0xa4, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x02, 0x01, 0x16, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+ 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x73, 0x6c, 0x2d, 0x63, 0x70, 0x73, 0x2d,
+ 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x68,
+ 0x74, 0x6d, 0x30, 0x82, 0x01, 0x64, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x02, 0x02, 0x30, 0x82, 0x01, 0x56, 0x1e, 0x82, 0x01, 0x52,
+ 0x00, 0x41, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73,
+ 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74,
+ 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65,
+ 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63,
+ 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f,
+ 0x00, 0x6e, 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x75,
+ 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63,
+ 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e,
+ 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20,
+ 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x44, 0x00, 0x69,
+ 0x00, 0x67, 0x00, 0x69, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74,
+ 0x00, 0x20, 0x00, 0x45, 0x00, 0x56, 0x00, 0x20, 0x00, 0x43, 0x00, 0x50,
+ 0x00, 0x53, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20,
+ 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65,
+ 0x00, 0x6c, 0x00, 0x79, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20,
+ 0x00, 0x50, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20,
+ 0x00, 0x41, 0x00, 0x67, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6d,
+ 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x77, 0x00, 0x68,
+ 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69,
+ 0x00, 0x6d, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69,
+ 0x00, 0x61, 0x00, 0x62, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x74,
+ 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20,
+ 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e,
+ 0x00, 0x63, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72,
+ 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x68,
+ 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20,
+ 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x66,
+ 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65,
+ 0x00, 0x2e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+ 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x81,
+ 0x83, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x77, 0x30, 0x75, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+ 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4d, 0x06, 0x08, 0x2b, 0x06, 0x01,
+ 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65,
+ 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x41, 0x43, 0x65, 0x72,
+ 0x74, 0x73, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48,
+ 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65,
+ 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74,
+ 0x30, 0x81, 0x8f, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81, 0x87, 0x30,
+ 0x81, 0x84, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69,
+ 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44,
+ 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41,
+ 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f,
+ 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x40, 0xa0, 0x3e,
+ 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
+ 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72,
+ 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e,
+ 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63,
+ 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0x4c, 0x58, 0xcb, 0x25, 0xf0, 0x41, 0x4f, 0x52, 0xf4, 0x28, 0xc8,
+ 0x81, 0x43, 0x9b, 0xa6, 0xa8, 0xa0, 0xe6, 0x92, 0xe5, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e,
+ 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08,
+ 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x01, 0x00, 0x4c, 0x7a, 0x17, 0x87, 0x28, 0x5d, 0x17, 0xbc, 0xb2, 0x32,
+ 0x73, 0xbf, 0xcd, 0x2e, 0xf5, 0x58, 0x31, 0x1d, 0xf0, 0xb1, 0x71, 0x54,
+ 0x9c, 0xd6, 0x9b, 0x67, 0x93, 0xdb, 0x2f, 0x03, 0x3e, 0x16, 0x6f, 0x1e,
+ 0x03, 0xc9, 0x53, 0x84, 0xa3, 0x56, 0x60, 0x1e, 0x78, 0x94, 0x1b, 0xa2,
+ 0xa8, 0x6f, 0xa3, 0xa4, 0x8b, 0x52, 0x91, 0xd7, 0xdd, 0x5c, 0x95, 0xbb,
+ 0xef, 0xb5, 0x16, 0x49, 0xe9, 0xa5, 0x42, 0x4f, 0x34, 0xf2, 0x47, 0xff,
+ 0xae, 0x81, 0x7f, 0x13, 0x54, 0xb7, 0x20, 0xc4, 0x70, 0x15, 0xcb, 0x81,
+ 0x0a, 0x81, 0xcb, 0x74, 0x57, 0xdc, 0x9c, 0xdf, 0x24, 0xa4, 0x29, 0x0c,
+ 0x18, 0xf0, 0x1c, 0xe4, 0xae, 0x07, 0x33, 0xec, 0xf1, 0x49, 0x3e, 0x55,
+ 0xcf, 0x6e, 0x4f, 0x0d, 0x54, 0x7b, 0xd3, 0xc9, 0xe8, 0x15, 0x48, 0xd4,
+ 0xc5, 0xbb, 0xdc, 0x35, 0x1c, 0x77, 0x45, 0x07, 0x48, 0x45, 0x85, 0xbd,
+ 0xd7, 0x7e, 0x53, 0xb8, 0xc0, 0x16, 0xd9, 0x95, 0xcd, 0x8b, 0x8d, 0x7d,
+ 0xc9, 0x60, 0x4f, 0xd1, 0xa2, 0x9b, 0xe3, 0xd0, 0x30, 0xd6, 0xb4, 0x73,
+ 0x36, 0xe6, 0xd2, 0xf9, 0x03, 0xb2, 0xe3, 0xa4, 0xf5, 0xe5, 0xb8, 0x3e,
+ 0x04, 0x49, 0x00, 0xba, 0x2e, 0xa6, 0x4a, 0x72, 0x83, 0x72, 0x9d, 0xf7,
+ 0x0b, 0x8c, 0xa9, 0x89, 0xe7, 0xb3, 0xd7, 0x64, 0x1f, 0xd6, 0xe3, 0x60,
+ 0xcb, 0x03, 0xc4, 0xdc, 0x88, 0xe9, 0x9d, 0x25, 0x01, 0x00, 0x71, 0xcb,
+ 0x03, 0xb4, 0x29, 0x60, 0x25, 0x8f, 0xf9, 0x46, 0xd1, 0x7b, 0x71, 0xae,
+ 0xcd, 0x53, 0x12, 0x5b, 0x84, 0x8e, 0xc2, 0x0f, 0xc7, 0xed, 0x93, 0x19,
+ 0xd9, 0xc9, 0xfa, 0x8f, 0x58, 0x34, 0x76, 0x32, 0x2f, 0xae, 0xe1, 0x50,
+ 0x14, 0x61, 0xd4, 0xa8, 0x58, 0xa3, 0xc8, 0x30, 0x13, 0x23, 0xef, 0xc6,
+ 0x25, 0x8c, 0x36, 0x8f, 0x1c, 0x80,
+};
diff --git a/chromium/net/quic/crypto/common_cert_set_test.cc b/chromium/net/quic/crypto/common_cert_set_test.cc
index 09b06d18eb5..e98194ca3a2 100644
--- a/chromium/net/quic/crypto/common_cert_set_test.cc
+++ b/chromium/net/quic/crypto/common_cert_set_test.cc
@@ -14,91 +14,178 @@ namespace net {
namespace test {
static const unsigned char kGIACertificate1[] = {
- 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
- 0x02, 0x02, 0x03, 0x02, 0x3a, 0x76, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31,
- 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
- 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
- 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
- 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
- 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x35, 0x5a, 0x17, 0x0d,
- 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
- 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
- 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
- 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
- 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
- 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
- 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
- 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
- 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
- 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
- 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
- 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
- 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
- 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
- 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
- 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
- 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
- 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
- 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
- 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
- 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
- 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
- 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
- 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
- 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
- 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
- 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
- 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
- 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
- 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
- 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
- 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
- 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x12, 0x06, 0x03,
- 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
- 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
- 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03,
- 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
- 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
- 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
- 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e,
- 0x63, 0x6f, 0x6d, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
- 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
- 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
- 0x27, 0x8c, 0xcf, 0xe9, 0xc7, 0x3b, 0xbe, 0xc0, 0x6f, 0xe8, 0x96, 0x84,
- 0xfb, 0x9c, 0x5c, 0x5d, 0x90, 0xe4, 0x77, 0xdb, 0x8b, 0x32, 0x60, 0x9b,
- 0x65, 0xd8, 0x85, 0x26, 0xb5, 0xba, 0x9f, 0x1e, 0xde, 0x64, 0x4e, 0x1f,
- 0xc6, 0xc8, 0x20, 0x5b, 0x09, 0x9f, 0xab, 0xa9, 0xe0, 0x09, 0x34, 0x45,
- 0xa2, 0x65, 0x25, 0x37, 0x3d, 0x7f, 0x5a, 0x6f, 0x20, 0xcc, 0xf9, 0xfa,
- 0xf1, 0x1d, 0x8f, 0x10, 0x0c, 0x02, 0x3a, 0xc4, 0xc9, 0x01, 0x76, 0x96,
- 0xbe, 0x9b, 0xf9, 0x15, 0xd8, 0x39, 0xd1, 0xc5, 0x03, 0x47, 0x76, 0xb8,
- 0x8a, 0x8c, 0x31, 0xd6, 0x60, 0xd5, 0xe4, 0x8f, 0xdb, 0xfa, 0x3c, 0xc6,
- 0xd5, 0x98, 0x28, 0xf8, 0x1c, 0x8f, 0x17, 0x91, 0x34, 0xcb, 0xcb, 0x52,
- 0x7a, 0xd1, 0xfb, 0x3a, 0x20, 0xe4, 0xe1, 0x86, 0xb1, 0xd8, 0x18, 0x0f,
- 0xbe, 0xd6, 0x87, 0x64, 0x8d, 0xc5, 0x0a, 0x25, 0x42, 0x51, 0xef, 0xb2,
- 0x38, 0xb8, 0xe0, 0x1d, 0xd0, 0xe1, 0xfc, 0xe6, 0xf4, 0xaf, 0x46, 0xba,
- 0xef, 0xc0, 0xbf, 0xc5, 0xb4, 0x05, 0xf5, 0x94, 0x75, 0x0c, 0xfe, 0xa2,
- 0xbe, 0x02, 0xba, 0xea, 0x86, 0x5b, 0xf9, 0x35, 0xb3, 0x66, 0xf5, 0xc5,
- 0x8d, 0x85, 0xa1, 0x1a, 0x23, 0x77, 0x1a, 0x19, 0x17, 0x54, 0x13, 0x60,
- 0x9f, 0x0b, 0xe1, 0xb4, 0x9c, 0x28, 0x2a, 0xf9, 0xae, 0x02, 0x34, 0x6d,
- 0x25, 0x93, 0x9c, 0x82, 0xa8, 0x17, 0x7b, 0xf1, 0x85, 0xb0, 0xd3, 0x0f,
- 0x58, 0xe1, 0xfb, 0xb1, 0xfe, 0x9c, 0xa1, 0xa3, 0xe8, 0xfd, 0xc9, 0x3f,
- 0xf4, 0xd7, 0x71, 0xdc, 0xbd, 0x8c, 0xa4, 0x19, 0xe0, 0x21, 0x23, 0x23,
- 0x55, 0x13, 0x8f, 0xa4, 0x16, 0x02, 0x09, 0x7e, 0xb9, 0xaf, 0xee, 0xdb,
- 0x53, 0x64, 0xbd, 0x71, 0x2f, 0xb9, 0x39, 0xce, 0x30, 0xb7, 0xb4, 0xbc,
- 0x54, 0xe0, 0x47, 0x07,
+ 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x76, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
+ 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x35, 0x5a, 0x17, 0x0d,
+ 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
+ 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+ 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
+ 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
+ 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
+ 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
+ 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
+ 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
+ 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
+ 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
+ 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
+ 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
+ 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
+ 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
+ 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
+ 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
+ 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
+ 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
+ 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
+ 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
+ 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
+ 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
+ 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
+ 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
+ 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
+ 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+ 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
+ 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
+ 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
+ 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x12, 0x06, 0x03,
+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01,
+ 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
+ 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
+ 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
+ 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+ 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
+ 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
+ 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+ 0x27, 0x8c, 0xcf, 0xe9, 0xc7, 0x3b, 0xbe, 0xc0, 0x6f, 0xe8, 0x96, 0x84,
+ 0xfb, 0x9c, 0x5c, 0x5d, 0x90, 0xe4, 0x77, 0xdb, 0x8b, 0x32, 0x60, 0x9b,
+ 0x65, 0xd8, 0x85, 0x26, 0xb5, 0xba, 0x9f, 0x1e, 0xde, 0x64, 0x4e, 0x1f,
+ 0xc6, 0xc8, 0x20, 0x5b, 0x09, 0x9f, 0xab, 0xa9, 0xe0, 0x09, 0x34, 0x45,
+ 0xa2, 0x65, 0x25, 0x37, 0x3d, 0x7f, 0x5a, 0x6f, 0x20, 0xcc, 0xf9, 0xfa,
+ 0xf1, 0x1d, 0x8f, 0x10, 0x0c, 0x02, 0x3a, 0xc4, 0xc9, 0x01, 0x76, 0x96,
+ 0xbe, 0x9b, 0xf9, 0x15, 0xd8, 0x39, 0xd1, 0xc5, 0x03, 0x47, 0x76, 0xb8,
+ 0x8a, 0x8c, 0x31, 0xd6, 0x60, 0xd5, 0xe4, 0x8f, 0xdb, 0xfa, 0x3c, 0xc6,
+ 0xd5, 0x98, 0x28, 0xf8, 0x1c, 0x8f, 0x17, 0x91, 0x34, 0xcb, 0xcb, 0x52,
+ 0x7a, 0xd1, 0xfb, 0x3a, 0x20, 0xe4, 0xe1, 0x86, 0xb1, 0xd8, 0x18, 0x0f,
+ 0xbe, 0xd6, 0x87, 0x64, 0x8d, 0xc5, 0x0a, 0x25, 0x42, 0x51, 0xef, 0xb2,
+ 0x38, 0xb8, 0xe0, 0x1d, 0xd0, 0xe1, 0xfc, 0xe6, 0xf4, 0xaf, 0x46, 0xba,
+ 0xef, 0xc0, 0xbf, 0xc5, 0xb4, 0x05, 0xf5, 0x94, 0x75, 0x0c, 0xfe, 0xa2,
+ 0xbe, 0x02, 0xba, 0xea, 0x86, 0x5b, 0xf9, 0x35, 0xb3, 0x66, 0xf5, 0xc5,
+ 0x8d, 0x85, 0xa1, 0x1a, 0x23, 0x77, 0x1a, 0x19, 0x17, 0x54, 0x13, 0x60,
+ 0x9f, 0x0b, 0xe1, 0xb4, 0x9c, 0x28, 0x2a, 0xf9, 0xae, 0x02, 0x34, 0x6d,
+ 0x25, 0x93, 0x9c, 0x82, 0xa8, 0x17, 0x7b, 0xf1, 0x85, 0xb0, 0xd3, 0x0f,
+ 0x58, 0xe1, 0xfb, 0xb1, 0xfe, 0x9c, 0xa1, 0xa3, 0xe8, 0xfd, 0xc9, 0x3f,
+ 0xf4, 0xd7, 0x71, 0xdc, 0xbd, 0x8c, 0xa4, 0x19, 0xe0, 0x21, 0x23, 0x23,
+ 0x55, 0x13, 0x8f, 0xa4, 0x16, 0x02, 0x09, 0x7e, 0xb9, 0xaf, 0xee, 0xdb,
+ 0x53, 0x64, 0xbd, 0x71, 0x2f, 0xb9, 0x39, 0xce, 0x30, 0xb7, 0xb4, 0xbc,
+ 0x54, 0xe0, 0x47, 0x07,
+};
+static const unsigned char kGIACertificate2[] = {
+ 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x03, 0x02, 0x3a, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31,
+ 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+ 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47,
+ 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
+ 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x36, 0x5a, 0x17, 0x0d,
+ 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39,
+ 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
+ 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c,
+ 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
+ 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x20, 0x47, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3,
+ 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a,
+ 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a,
+ 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f,
+ 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1,
+ 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4,
+ 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53,
+ 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f,
+ 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73,
+ 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b,
+ 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb,
+ 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4,
+ 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19,
+ 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65,
+ 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80,
+ 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99,
+ 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75,
+ 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e,
+ 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf,
+ 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2,
+ 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37,
+ 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+ 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb,
+ 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc,
+ 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
+ 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81,
+ 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
+ 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
+ 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
+ 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03,
+ 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0,
+ 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e,
+ 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72,
+ 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
+ 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10,
+ 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
+ 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
+ 0xaa, 0xfa, 0xa9, 0x20, 0xcd, 0x6a, 0x67, 0x83, 0xed, 0x5e, 0xd4, 0x7e,
+ 0xde, 0x1d, 0xc4, 0x7f, 0xe0, 0x25, 0x06, 0x00, 0xc5, 0x24, 0xfb, 0xa9,
+ 0xc8, 0x2d, 0x6d, 0x7e, 0xde, 0x9d, 0x82, 0x65, 0x2c, 0x81, 0x63, 0x34,
+ 0x66, 0x3e, 0xe9, 0x52, 0xc2, 0x08, 0xb4, 0xcb, 0x2f, 0xf7, 0x5f, 0x99,
+ 0x3a, 0x6a, 0x9c, 0x50, 0x7a, 0x85, 0x05, 0x8c, 0x7d, 0xd1, 0x2a, 0x48,
+ 0x84, 0xd3, 0x09, 0x6c, 0x7c, 0xc2, 0xcd, 0x35, 0x9f, 0xf3, 0x82, 0xee,
+ 0x52, 0xde, 0x68, 0x5f, 0xe4, 0x00, 0x8a, 0x17, 0x20, 0x96, 0xf7, 0x29,
+ 0x8d, 0x9a, 0x4d, 0xcb, 0xa8, 0xde, 0x86, 0xc8, 0x0d, 0x6f, 0x56, 0x87,
+ 0x03, 0x7d, 0x03, 0x3f, 0xdc, 0xfa, 0x79, 0x7d, 0x21, 0x19, 0xf9, 0xc8,
+ 0x3a, 0x2f, 0x51, 0x76, 0x8c, 0xc7, 0x41, 0x92, 0x71, 0x8f, 0x25, 0xce,
+ 0x37, 0xf8, 0x4a, 0x4c, 0x00, 0x23, 0xef, 0xc4, 0x35, 0x10, 0xae, 0xe0,
+ 0x23, 0x80, 0x73, 0x7c, 0x4d, 0x34, 0x2e, 0xc8, 0x6e, 0x90, 0xd6, 0x10,
+ 0x1e, 0x99, 0x84, 0x73, 0x1a, 0x70, 0xf2, 0xed, 0x55, 0x0e, 0xee, 0x17,
+ 0x06, 0xea, 0x67, 0xee, 0x32, 0xeb, 0x2c, 0xdd, 0x67, 0x07, 0x3f, 0xf6,
+ 0x8b, 0xc2, 0x70, 0xde, 0x5b, 0x00, 0xe6, 0xbb, 0x1b, 0xd3, 0x36, 0x1a,
+ 0x22, 0x6c, 0x6c, 0xb0, 0x35, 0x42, 0x6c, 0x90, 0x09, 0x3d, 0x93, 0xe9,
+ 0x64, 0x09, 0x22, 0x0e, 0x85, 0x06, 0x9f, 0xc2, 0x73, 0x21, 0xd3, 0xe6,
+ 0x5f, 0x80, 0xe4, 0x8d, 0x85, 0x22, 0x3a, 0x73, 0x03, 0xb1, 0x60, 0x8e,
+ 0xae, 0x68, 0xe2, 0xf4, 0x3e, 0x97, 0xe7, 0x60, 0x12, 0x09, 0x68, 0x36,
+ 0xde, 0x3a, 0xd6, 0xe2, 0x43, 0x95, 0x5b, 0x37, 0x81, 0x92, 0x81, 0x1f,
+ 0xbb, 0x8d, 0xd7, 0xad, 0x52, 0x64, 0x16, 0x57, 0x96, 0xd9, 0x5e, 0x34,
+ 0x7e, 0xc8, 0x35, 0xd8,
};
TEST(CommonCertSets, FindGIA_1) {
@@ -106,9 +193,31 @@ TEST(CommonCertSets, FindGIA_1) {
sizeof(kGIACertificate1));
const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC());
- const uint64 in_hash = UINT64_C(0xff715ce4e7e9267b);
- uint64 hash;
- uint32 index;
+ // Common Cert Set 1's hash.
+ const uint64_t in_hash = UINT64_C(0xff715ce4e7e9267b);
+ uint64_t hash;
+ uint32_t index;
+ ASSERT_TRUE(sets->MatchCert(
+ gia,
+ StringPiece(reinterpret_cast<const char*>(&in_hash), sizeof(in_hash)),
+ &hash, &index));
+ EXPECT_EQ(in_hash, hash);
+
+ StringPiece gia_copy = sets->GetCert(hash, index);
+ EXPECT_FALSE(gia_copy.empty());
+ ASSERT_EQ(gia.size(), gia_copy.size());
+ EXPECT_EQ(0, memcmp(gia.data(), gia_copy.data(), gia.size()));
+}
+
+TEST(CommonCertSets, FindGIA_2) {
+ StringPiece gia(reinterpret_cast<const char*>(kGIACertificate2),
+ sizeof(kGIACertificate2));
+
+ const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC());
+ // Common Cert Set 2's hash.
+ const uint64_t in_hash = UINT64_C(0xe81a92926081e801);
+ uint64_t hash;
+ uint32_t index;
ASSERT_TRUE(sets->MatchCert(
gia,
StringPiece(reinterpret_cast<const char*>(&in_hash), sizeof(in_hash)),
@@ -124,9 +233,9 @@ TEST(CommonCertSets, FindGIA_1) {
TEST(CommonCertSets, NonMatch) {
const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC());
StringPiece not_a_cert("hello");
- const uint64 in_hash = UINT64_C(0xc9fef74053f99f39);
- uint64 hash;
- uint32 index;
+ const uint64_t in_hash = UINT64_C(0xc9fef74053f99f39);
+ uint64_t hash;
+ uint32_t index;
EXPECT_FALSE(sets->MatchCert(
not_a_cert,
StringPiece(reinterpret_cast<const char*>(&in_hash), sizeof(in_hash)),
diff --git a/chromium/net/quic/crypto/crypto_framer.cc b/chromium/net/quic/crypto/crypto_framer.cc
index fe76a7ff1d3..2d809807c2b 100644
--- a/chromium/net/quic/crypto/crypto_framer.cc
+++ b/chromium/net/quic/crypto/crypto_framer.cc
@@ -4,6 +4,7 @@
#include "net/quic/crypto/crypto_framer.h"
+#include "base/strings/stringprintf.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_data_reader.h"
#include "net/quic/quic_data_writer.h"
@@ -16,9 +17,9 @@ namespace net {
namespace {
-const size_t kQuicTagSize = sizeof(uint32);
-const size_t kCryptoEndOffsetSize = sizeof(uint32);
-const size_t kNumEntriesSize = sizeof(uint16);
+const size_t kQuicTagSize = sizeof(uint32_t);
+const size_t kCryptoEndOffsetSize = sizeof(uint32_t);
+const size_t kNumEntriesSize = sizeof(uint16_t);
// OneShotVisitor is a framer visitor that records a single handshake message.
class OneShotVisitor : public CryptoFramerVisitorInterface {
@@ -43,9 +44,7 @@ class OneShotVisitor : public CryptoFramerVisitorInterface {
} // namespace
CryptoFramer::CryptoFramer()
- : visitor_(nullptr),
- num_entries_(0),
- values_len_(0) {
+ : visitor_(nullptr), error_detail_(""), num_entries_(0), values_len_(0) {
Clear();
}
@@ -72,6 +71,7 @@ bool CryptoFramer::ProcessInput(StringPiece input) {
}
error_ = Process(input);
if (error_ != QUIC_NO_ERROR) {
+ DCHECK(!error_detail_.empty());
visitor_->OnError(this);
return false;
}
@@ -111,7 +111,7 @@ QuicData* CryptoFramer::ConstructHandshakeMessage(
DCHECK(false) << "Failed to write message tag.";
return nullptr;
}
- if (!writer.WriteUInt16(static_cast<uint16>(num_entries))) {
+ if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) {
DCHECK(false) << "Failed to write size.";
return nullptr;
}
@@ -120,7 +120,7 @@ QuicData* CryptoFramer::ConstructHandshakeMessage(
return nullptr;
}
- uint32 end_offset = 0;
+ uint32_t end_offset = 0;
// Tags and offsets
for (QuicTagValueMap::const_iterator it = message.tag_value_map().begin();
it != message.tag_value_map().end(); ++it) {
@@ -187,6 +187,7 @@ void CryptoFramer::Clear() {
message_.Clear();
tags_and_lengths_.clear();
error_ = QUIC_NO_ERROR;
+ error_detail_ = "";
state_ = STATE_READING_TAG;
}
@@ -205,14 +206,15 @@ QuicErrorCode CryptoFramer::Process(StringPiece input) {
message_.set_tag(message_tag);
state_ = STATE_READING_NUM_ENTRIES;
case STATE_READING_NUM_ENTRIES:
- if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16)) {
+ if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) {
break;
}
reader.ReadUInt16(&num_entries_);
if (num_entries_ > kMaxEntries) {
+ error_detail_ = base::StringPrintf("%u entries", num_entries_);
return QUIC_CRYPTO_TOO_MANY_ENTRIES;
}
- uint16 padding;
+ uint16_t padding;
reader.ReadUInt16(&padding);
tags_and_lengths_.reserve(num_entries_);
@@ -220,25 +222,29 @@ QuicErrorCode CryptoFramer::Process(StringPiece input) {
values_len_ = 0;
case STATE_READING_TAGS_AND_LENGTHS: {
if (reader.BytesRemaining() <
- num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
+ num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
break;
}
- uint32 last_end_offset = 0;
+ uint32_t last_end_offset = 0;
for (unsigned i = 0; i < num_entries_; ++i) {
QuicTag tag;
reader.ReadUInt32(&tag);
- if (i > 0 && tag <= tags_and_lengths_[i-1].first) {
- if (tag == tags_and_lengths_[i-1].first) {
+ if (i > 0 && tag <= tags_and_lengths_[i - 1].first) {
+ if (tag == tags_and_lengths_[i - 1].first) {
+ error_detail_ = base::StringPrintf("Duplicate tag:%u", tag);
return QUIC_CRYPTO_DUPLICATE_TAG;
}
+ error_detail_ = base::StringPrintf("Tag %u out of order", tag);
return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
}
- uint32 end_offset;
+ uint32_t end_offset;
reader.ReadUInt32(&end_offset);
if (end_offset < last_end_offset) {
+ error_detail_ = base::StringPrintf("End offset: %u vs %u", end_offset,
+ last_end_offset);
return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
}
tags_and_lengths_.push_back(std::make_pair(
@@ -270,7 +276,7 @@ QuicErrorCode CryptoFramer::Process(StringPiece input) {
// static
bool CryptoFramer::WritePadTag(QuicDataWriter* writer,
size_t pad_length,
- uint32* end_offset) {
+ uint32_t* end_offset) {
if (!writer->WriteUInt32(kPAD)) {
DCHECK(false) << "Failed to write tag.";
return false;
diff --git a/chromium/net/quic/crypto/crypto_framer.h b/chromium/net/quic/crypto/crypto_framer.h
index 64137a20d26..150b05a0c78 100644
--- a/chromium/net/quic/crypto/crypto_framer.h
+++ b/chromium/net/quic/crypto/crypto_framer.h
@@ -5,10 +5,12 @@
#ifndef NET_QUIC_CRYPTO_CRYPTO_FRAMER_H_
#define NET_QUIC_CRYPTO_CRYPTO_FRAMER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -55,6 +57,7 @@ class NET_EXPORT_PRIVATE CryptoFramer {
}
QuicErrorCode error() const { return error_; }
+ const std::string& error_detail() const { return error_detail_; }
// Processes input data, which must be delivered in order. Returns
// false if there was an error, and true otherwise.
@@ -79,7 +82,7 @@ class NET_EXPORT_PRIVATE CryptoFramer {
static bool WritePadTag(QuicDataWriter* writer,
size_t pad_length,
- uint32* end_offset);
+ uint32_t* end_offset);
// Represents the current state of the parsing state machine.
enum CryptoFramerState {
@@ -99,8 +102,10 @@ class NET_EXPORT_PRIVATE CryptoFramer {
CryptoFramerState state_;
// The message currently being parsed.
CryptoHandshakeMessage message_;
+ // The issue which caused |error_|
+ std::string error_detail_;
// Number of entires in the message currently being parsed.
- uint16 num_entries_;
+ uint16_t num_entries_;
// tags_and_lengths_ contains the tags that are currently being parsed and
// their lengths.
std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
diff --git a/chromium/net/quic/crypto/crypto_framer_test.cc b/chromium/net/quic/crypto/crypto_framer_test.cc
index cdbf548ea7b..f60380fd0a5 100644
--- a/chromium/net/quic/crypto/crypto_framer_test.cc
+++ b/chromium/net/quic/crypto/crypto_framer_test.cc
@@ -24,7 +24,9 @@ namespace net {
namespace {
-char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
+char* AsChars(unsigned char* data) {
+ return reinterpret_cast<char*>(data);
+}
} // namespace
@@ -57,33 +59,30 @@ TEST(CryptoFramerTest, ConstructHandshakeMessage) {
message.SetStringPiece(0x1234567A, "lmnopqr");
unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x03, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // tag 3
- 0x7A, 0x56, 0x34, 0x12,
- // end offset 3
- 0x12, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd',
- 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j',
- 'k',
- // value 3
- 'l', 'm', 'n', 'o',
- 'p', 'q', 'r',
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x03, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x06, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 2
+ 0x0b, 0x00, 0x00, 0x00,
+ // tag 3
+ 0x7A, 0x56, 0x34, 0x12,
+ // end offset 3
+ 0x12, 0x00, 0x00, 0x00,
+ // value 1
+ 'a', 'b', 'c', 'd', 'e', 'f',
+ // value 2
+ 'g', 'h', 'i', 'j', 'k',
+ // value 3
+ 'l', 'm', 'n', 'o', 'p', 'q', 'r',
};
CryptoFramer framer;
@@ -101,26 +100,24 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
message.SetStringPiece(0x12345679, "ghijk");
unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd',
- 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j',
- 'k',
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x06, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 2
+ 0x0b, 0x00, 0x00, 0x00,
+ // value 1
+ 'a', 'b', 'c', 'd', 'e', 'f',
+ // value 2
+ 'g', 'h', 'i', 'j', 'k',
};
CryptoFramer framer;
@@ -138,16 +135,16 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
message.SetStringPiece(0x12345678, "");
unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x01, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x00, 0x00, 0x00, 0x00,
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x01, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x00, 0x00, 0x00, 0x00,
};
CryptoFramer framer;
@@ -162,7 +159,7 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
CryptoHandshakeMessage message;
message.set_tag(0xFFAA7733);
- for (uint32 key = 1; key <= kMaxEntries + 1; ++key) {
+ for (uint32_t key = 1; key <= kMaxEntries + 1; ++key) {
message.SetStringPiece(key, "abcdef");
}
@@ -178,28 +175,26 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
message.set_minimum_size(64);
unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 'P', 'A', 'D', 0,
- // end offset 1
- 0x24, 0x00, 0x00, 0x00,
- // tag 2
- 0x04, 0x03, 0x02, 0x01,
- // end offset 2
- 0x28, 0x00, 0x00, 0x00,
- // 36 bytes of padding.
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-',
- // value 2
- 't', 'e', 's', 't',
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 'P', 'A', 'D', 0,
+ // end offset 1
+ 0x24, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x04, 0x03, 0x02, 0x01,
+ // end offset 2
+ 0x28, 0x00, 0x00, 0x00,
+ // 36 bytes of padding.
+ '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+ '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+ '-', '-', '-', '-', '-', '-',
+ // value 2
+ 't', 'e', 's', 't',
};
CryptoFramer framer;
@@ -218,26 +213,24 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
message.set_minimum_size(64);
unsigned char packet[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x01, 0x00, 0x00, 0x00,
- // end offset 1
- 0x00, 0x00, 0x00, 0x00,
- // tag 2
- 'P', 'A', 'D', 0,
- // end offset 2
- 0x28, 0x00, 0x00, 0x00,
- // 40 bytes of padding.
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-',
- '-', '-', '-', '-', '-', '-', '-', '-',
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x01, 0x00, 0x00, 0x00,
+ // end offset 1
+ 0x00, 0x00, 0x00, 0x00,
+ // tag 2
+ 'P', 'A', 'D', 0,
+ // end offset 2
+ 0x28, 0x00, 0x00, 0x00,
+ // 40 bytes of padding.
+ '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+ '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+ '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
};
CryptoFramer framer;
@@ -255,26 +248,24 @@ TEST(CryptoFramerTest, ProcessInput) {
framer.set_visitor(&visitor);
unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd',
- 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j',
- 'k',
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x06, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 2
+ 0x0b, 0x00, 0x00, 0x00,
+ // value 1
+ 'a', 'b', 'c', 'd', 'e', 'f',
+ // value 2
+ 'g', 'h', 'i', 'j', 'k',
};
EXPECT_TRUE(
@@ -295,33 +286,30 @@ TEST(CryptoFramerTest, ProcessInputWithThreeKeys) {
framer.set_visitor(&visitor);
unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x03, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // tag 3
- 0x7A, 0x56, 0x34, 0x12,
- // end offset 3
- 0x12, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd',
- 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j',
- 'k',
- // value 3
- 'l', 'm', 'n', 'o',
- 'p', 'q', 'r',
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x03, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x06, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 2
+ 0x0b, 0x00, 0x00, 0x00,
+ // tag 3
+ 0x7A, 0x56, 0x34, 0x12,
+ // end offset 3
+ 0x12, 0x00, 0x00, 0x00,
+ // value 1
+ 'a', 'b', 'c', 'd', 'e', 'f',
+ // value 2
+ 'g', 'h', 'i', 'j', 'k',
+ // value 3
+ 'l', 'm', 'n', 'o', 'p', 'q', 'r',
};
EXPECT_TRUE(
@@ -343,26 +331,24 @@ TEST(CryptoFramerTest, ProcessInputIncrementally) {
framer.set_visitor(&visitor);
unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x06, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x0b, 0x00, 0x00, 0x00,
- // value 1
- 'a', 'b', 'c', 'd',
- 'e', 'f',
- // value 2
- 'g', 'h', 'i', 'j',
- 'k',
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x06, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 2
+ 0x0b, 0x00, 0x00, 0x00,
+ // value 1
+ 'a', 'b', 'c', 'd', 'e', 'f',
+ // value 2
+ 'g', 'h', 'i', 'j', 'k',
};
for (size_t i = 0; i < arraysize(input); i++) {
@@ -383,20 +369,20 @@ TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
framer.set_visitor(&visitor);
unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x13,
- // end offset 1
- 0x01, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x02, 0x00, 0x00, 0x00,
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x13,
+ // end offset 1
+ 0x01, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 2
+ 0x02, 0x00, 0x00, 0x00,
};
EXPECT_FALSE(
@@ -411,20 +397,20 @@ TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
framer.set_visitor(&visitor);
unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x79, 0x56, 0x34, 0x12,
- // end offset 1
- 0x01, 0x00, 0x00, 0x00,
- // tag 2
- 0x78, 0x56, 0x34, 0x13,
- // end offset 2
- 0x00, 0x00, 0x00, 0x00,
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x01, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x78, 0x56, 0x34, 0x13,
+ // end offset 2
+ 0x00, 0x00, 0x00, 0x00,
};
EXPECT_FALSE(
@@ -439,12 +425,12 @@ TEST(CryptoFramerTest, ProcessInputTooManyEntries) {
framer.set_visitor(&visitor);
unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0xA0, 0x00,
- // padding
- 0x00, 0x00,
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0xA0, 0x00,
+ // padding
+ 0x00, 0x00,
};
EXPECT_FALSE(
@@ -459,20 +445,20 @@ TEST(CryptoFramerTest, ProcessInputZeroLength) {
framer.set_visitor(&visitor);
unsigned char input[] = {
- // tag
- 0x33, 0x77, 0xAA, 0xFF,
- // num entries
- 0x02, 0x00,
- // padding
- 0x00, 0x00,
- // tag 1
- 0x78, 0x56, 0x34, 0x12,
- // end offset 1
- 0x00, 0x00, 0x00, 0x00,
- // tag 2
- 0x79, 0x56, 0x34, 0x12,
- // end offset 2
- 0x05, 0x00, 0x00, 0x00,
+ // tag
+ 0x33, 0x77, 0xAA, 0xFF,
+ // num entries
+ 0x02, 0x00,
+ // padding
+ 0x00, 0x00,
+ // tag 1
+ 0x78, 0x56, 0x34, 0x12,
+ // end offset 1
+ 0x00, 0x00, 0x00, 0x00,
+ // tag 2
+ 0x79, 0x56, 0x34, 0x12,
+ // end offset 2
+ 0x05, 0x00, 0x00, 0x00,
};
EXPECT_TRUE(
diff --git a/chromium/net/quic/crypto/crypto_handshake.cc b/chromium/net/quic/crypto/crypto_handshake.cc
index c790814c072..afe599160f0 100644
--- a/chromium/net/quic/crypto/crypto_handshake.cc
+++ b/chromium/net/quic/crypto/crypto_handshake.cc
@@ -14,8 +14,10 @@ namespace net {
QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
: key_exchange(0),
aead(0),
+ token_binding_key_param(0),
x509_ecdsa_supported(false),
- x509_supported(false) {}
+ x509_supported(false),
+ sct_supported_by_client(false) {}
QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {}
@@ -37,8 +39,7 @@ const char QuicCryptoConfig::kForwardSecureLabel[] =
"QUIC forward secure key expansion";
QuicCryptoConfig::QuicCryptoConfig()
- : common_cert_sets(CommonCertSets::GetInstanceQUIC()) {
-}
+ : common_cert_sets(CommonCertSets::GetInstanceQUIC()) {}
QuicCryptoConfig::~QuicCryptoConfig() {}
diff --git a/chromium/net/quic/crypto/crypto_handshake.h b/chromium/net/quic/crypto/crypto_handshake.h
index 74671caea38..71792bac58a 100644
--- a/chromium/net/quic/crypto/crypto_handshake.h
+++ b/chromium/net/quic/crypto/crypto_handshake.h
@@ -5,9 +5,12 @@
#ifndef NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_
#define NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
@@ -83,7 +86,8 @@ enum HandshakeFailureReason {
MAX_FAILURE_REASON = 22,
};
-// These errors will be packed into an uint32 and we don't want to set the most
+// These errors will be packed into an uint32_t and we don't want to set the
+// most
// significant bit, which may be misinterpreted as the sign bit.
static_assert(MAX_FAILURE_REASON <= 32, "failure reason out of sync");
@@ -129,6 +133,7 @@ struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters {
// bytes of x coordinate, followed by 32 bytes of y coordinate. Both values
// are big-endian and the pair is a P-256 public key.
std::string channel_id;
+ QuicTag token_binding_key_param;
// Used when generating proof signature when sending server config updates.
bool x509_ecdsa_supported;
@@ -137,6 +142,10 @@ struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters {
// Used to generate cert chain when sending server config updates.
std::string client_common_set_hashes;
std::string client_cached_cert_hashes;
+
+ // Default to false; set to true if the client indicates that it supports sct
+ // by sending CSCT tag with an empty value in client hello.
+ bool sct_supported_by_client;
};
struct NET_EXPORT_PRIVATE QuicCryptoProof {
@@ -146,6 +155,9 @@ struct NET_EXPORT_PRIVATE QuicCryptoProof {
std::string signature;
// QuicCryptoProof does not take ownership of |certs|.
const std::vector<std::string>* certs;
+ std::string cert_sct;
+ // The SCID of the server config whose signature is |signature|.
+ std::string primary_scid;
};
// QuicCryptoConfig contains common configuration between clients and servers.
@@ -174,6 +186,10 @@ class NET_EXPORT_PRIVATE QuicCryptoConfig {
// Authenticated encryption with associated data (AEAD) algorithms.
QuicTagVector aead;
+ // Supported Token Binding key parameters that can be negotiated in the client
+ // hello.
+ QuicTagVector tb_key_params;
+
const CommonCertSets* common_cert_sets;
private:
diff --git a/chromium/net/quic/crypto/crypto_handshake_message.cc b/chromium/net/quic/crypto/crypto_handshake_message.cc
index 9cf25adc0d4..b81b4629c7b 100644
--- a/chromium/net/quic/crypto/crypto_handshake_message.cc
+++ b/chromium/net/quic/crypto/crypto_handshake_message.cc
@@ -4,10 +4,11 @@
#include "net/quic/crypto/crypto_handshake_message.h"
-#include "base/strings/stringprintf.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
#include "net/quic/crypto/crypto_framer.h"
#include "net/quic/crypto/crypto_protocol.h"
+#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/quic_socket_address_coder.h"
#include "net/quic/quic_utils.h"
@@ -18,9 +19,7 @@ using std::vector;
namespace net {
-CryptoHandshakeMessage::CryptoHandshakeMessage()
- : tag_(0),
- minimum_size_(0) {}
+CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0), minimum_size_(0) {}
CryptoHandshakeMessage::CryptoHandshakeMessage(
const CryptoHandshakeMessage& other)
@@ -166,20 +165,19 @@ QuicErrorCode CryptoHandshakeMessage::GetNthValue24(QuicTag tag,
}
QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
- uint32* out) const {
- return GetPOD(tag, out, sizeof(uint32));
+ uint32_t* out) const {
+ return GetPOD(tag, out, sizeof(uint32_t));
}
QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
- uint64* out) const {
- return GetPOD(tag, out, sizeof(uint64));
+ uint64_t* out) const {
+ return GetPOD(tag, out, sizeof(uint64_t));
}
size_t CryptoHandshakeMessage::size() const {
- size_t ret = sizeof(QuicTag) +
- sizeof(uint16) /* number of entries */ +
- sizeof(uint16) /* padding */;
- ret += (sizeof(QuicTag) + sizeof(uint32) /* end offset */) *
+ size_t ret = sizeof(QuicTag) + sizeof(uint16_t) /* number of entries */ +
+ sizeof(uint16_t) /* padding */;
+ ret += (sizeof(QuicTag) + sizeof(uint32_t) /* end offset */) *
tag_value_map_.size();
for (QuicTagValueMap::const_iterator i = tag_value_map_.begin();
i != tag_value_map_.end(); ++i) {
@@ -205,8 +203,9 @@ string CryptoHandshakeMessage::DebugString() const {
return DebugStringInternal(0);
}
-QuicErrorCode CryptoHandshakeMessage::GetPOD(
- QuicTag tag, void* out, size_t len) const {
+QuicErrorCode CryptoHandshakeMessage::GetPOD(QuicTag tag,
+ void* out,
+ size_t len) const {
QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
QuicErrorCode ret = QUIC_NO_ERROR;
@@ -241,14 +240,15 @@ string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
case kMSPC:
case kSRBF:
case kSWND:
- // uint32 value
+ // uint32_t value
if (it->second.size() == 4) {
- uint32 value;
+ uint32_t value;
memcpy(&value, it->second.data(), sizeof(value));
ret += base::UintToString(value);
done = true;
}
break;
+ case kTBKP:
case kKEXS:
case kAEAD:
case kCOPT:
@@ -267,6 +267,21 @@ string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
done = true;
}
break;
+ case kRREJ:
+ // uint32_t lists
+ if (it->second.size() % sizeof(uint32_t) == 0) {
+ for (size_t j = 0; j < it->second.size(); j += sizeof(uint32_t)) {
+ uint32_t value;
+ memcpy(&value, it->second.data() + j, sizeof(value));
+ if (j > 0) {
+ ret += ",";
+ }
+ ret += CryptoUtils::HandshakeFailureReasonToString(
+ static_cast<HandshakeFailureReason>(value));
+ }
+ done = true;
+ }
+ break;
case kCADR:
// IP address and port
if (!it->second.empty()) {
diff --git a/chromium/net/quic/crypto/crypto_handshake_message.h b/chromium/net/quic/crypto/crypto_handshake_message.h
index 7b686596ce6..a3778cb7be2 100644
--- a/chromium/net/quic/crypto/crypto_handshake_message.h
+++ b/chromium/net/quic/crypto/crypto_handshake_message.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
#define NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -37,14 +40,16 @@ class NET_EXPORT_PRIVATE CryptoHandshakeMessage {
// SetValue sets an element with the given tag to the raw, memory contents of
// |v|.
- template<class T> void SetValue(QuicTag tag, const T& v) {
+ template <class T>
+ void SetValue(QuicTag tag, const T& v) {
tag_value_map_[tag] =
std::string(reinterpret_cast<const char*>(&v), sizeof(v));
}
// SetVector sets an element with the given tag to the raw contents of an
// array of elements in |v|.
- template<class T> void SetVector(QuicTag tag, const std::vector<T>& v) {
+ template <class T>
+ void SetVector(QuicTag tag, const std::vector<T>& v) {
if (v.empty()) {
tag_value_map_[tag] = std::string();
} else {
@@ -74,7 +79,8 @@ class NET_EXPORT_PRIVATE CryptoHandshakeMessage {
// |out_tags| and |out_len| to point to the array of tags and returns true.
// The array points into the CryptoHandshakeMessage and is valid only for as
// long as the CryptoHandshakeMessage exists and is not modified.
- QuicErrorCode GetTaglist(QuicTag tag, const QuicTag** out_tags,
+ QuicErrorCode GetTaglist(QuicTag tag,
+ const QuicTag** out_tags,
size_t* out_len) const;
bool GetStringPiece(QuicTag tag, base::StringPiece* out) const;
@@ -85,10 +91,10 @@ class NET_EXPORT_PRIVATE CryptoHandshakeMessage {
QuicErrorCode GetNthValue24(QuicTag tag,
unsigned index,
base::StringPiece* out) const;
- QuicErrorCode GetUint32(QuicTag tag, uint32* out) const;
- QuicErrorCode GetUint64(QuicTag tag, uint64* out) const;
+ QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const;
+ QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const;
- // size returns 4 (message tag) + 2 (uint16, number of entries) +
+ // size returns 4 (message tag) + 2 (uint16_t, number of entries) +
// (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
size_t size() const;
diff --git a/chromium/net/quic/crypto/crypto_handshake_message_test.cc b/chromium/net/quic/crypto/crypto_handshake_message_test.cc
new file mode 100644
index 00000000000..1bda50f0b2c
--- /dev/null
+++ b/chromium/net/quic/crypto/crypto_handshake_message_test.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2015 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/crypto/crypto_handshake_message.h"
+
+#include "net/quic/crypto/crypto_handshake.h"
+#include "net/quic/crypto/crypto_protocol.h"
+#include "net/test/gtest_util.h"
+
+namespace net {
+namespace test {
+namespace {
+
+TEST(CryptoHandshakeMessageTest, DebugString) {
+ CryptoHandshakeMessage message;
+ message.set_tag(kSHLO);
+ EXPECT_EQ("SHLO<\n>", message.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, DebugStringWithUintVector) {
+ CryptoHandshakeMessage message;
+ message.set_tag(kREJ);
+ std::vector<uint32_t> reasons = {
+ SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+ CLIENT_NONCE_NOT_UNIQUE_FAILURE};
+ message.SetVector(kRREJ, reasons);
+ EXPECT_EQ(
+ "REJ <\n RREJ: "
+ "SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,"
+ "CLIENT_NONCE_NOT_UNIQUE_FAILURE\n>",
+ message.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, DebugStringWithTagVector) {
+ CryptoHandshakeMessage message;
+ message.set_tag(kCHLO);
+ message.SetTaglist(kCOPT, kTBBR, kPAD, kBYTE, 0);
+ EXPECT_EQ("CHLO<\n COPT: 'TBBR','PAD ','BYTE'\n>", message.DebugString());
+}
+
+} // namespace
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/crypto/crypto_protocol.h b/chromium/net/quic/crypto/crypto_protocol.h
index ff238ec2fab..1e0fcb963ea 100644
--- a/chromium/net/quic/crypto/crypto_protocol.h
+++ b/chromium/net/quic/crypto/crypto_protocol.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_CRYPTO_CRYPTO_PROTOCOL_H_
#define NET_QUIC_CRYPTO_CRYPTO_PROTOCOL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "net/base/net_export.h"
@@ -14,13 +17,13 @@
// representation of the name of the tag. For example
// the client hello tag (CHLO) will be written as the
// following 4 bytes: 'C' 'H' 'L' 'O'. Since it is
-// stored in memory as a little endian uint32, we need
+// stored in memory as a little endian uint32_t, we need
// to reverse the order of the bytes.
//
// We use a macro to ensure that no static initialisers are created. Use the
// MakeQuicTag function in normal code.
#define TAG(a, b, c, d) \
- static_cast<QuicTag>((d << 24) + (c << 16) + (b << 8) + a)
+ static_cast<QuicTag>((d << 24) + (c << 16) + (b << 8) + a)
namespace net {
@@ -45,6 +48,7 @@ const QuicTag kC255 = TAG('C', '2', '5', '5'); // ECDH, Curve25519
const QuicTag kNULL = TAG('N', 'U', 'L', 'N'); // null algorithm
const QuicTag kAESG = TAG('A', 'E', 'S', 'G'); // AES128 + GCM-12
const QuicTag kCC12 = TAG('C', 'C', '1', '2'); // ChaCha20 + Poly1305
+const QuicTag kCC20 = TAG('C', 'C', '2', '0'); // ChaCha20 + Poly1305 RFC7539
// Socket receive buffer
const QuicTag kSRBF = TAG('S', 'R', 'B', 'F'); // Socket receive buffer
@@ -84,12 +88,17 @@ const QuicTag kMIN4 = TAG('M', 'I', 'N', '4'); // Min CWND of 4 packets,
// with a min rate of 1 BDP.
const QuicTag kTLPR = TAG('T', 'L', 'P', 'R'); // Tail loss probe delay of
// 0.5RTT.
+const QuicTag kACKD = TAG('A', 'C', 'K', 'D'); // Ack decimation style acking.
+const QuicTag kSSLR = TAG('S', 'S', 'L', 'R'); // Slow Start Large Reduction.
// Optional support of truncated Connection IDs. If sent by a peer, the value
// is the minimum number of bytes allowed for the connection ID sent to the
// peer.
const QuicTag kTCID = TAG('T', 'C', 'I', 'D'); // Connection ID truncation.
+// Multipath option.
+const QuicTag kMPTH = TAG('M', 'P', 'T', 'H'); // Enable multipath.
+
// FEC options
const QuicTag kFHDR = TAG('F', 'H', 'D', 'R'); // FEC protect headers
const QuicTag kFSTR = TAG('F', 'S', 'T', 'R'); // FEC protect all streams
@@ -147,6 +156,7 @@ const QuicTag kCFCW = TAG('C', 'F', 'C', 'W'); // Initial session/connection
// flow control receive window.
const QuicTag kUAID = TAG('U', 'A', 'I', 'D'); // Client's User Agent ID.
const QuicTag kXLCT = TAG('X', 'L', 'C', 'T'); // Expected leaf certificate.
+const QuicTag kTBKP = TAG('T', 'B', 'K', 'P'); // Token Binding key params.
// Rejection tags
const QuicTag kRREJ = TAG('R', 'R', 'E', 'J'); // Reasons for server sending
@@ -185,12 +195,12 @@ const QuicTag kFIXD = TAG('F', 'I', 'X', 'D'); // Client hello
// message because the server mightn't hold state for a rejected client hello
// and therefore the client may have issues reassembling the rejection message
// in the event that it sent two client hellos.
-const QuicTag kServerNonceTag =
- TAG('S', 'N', 'O', 0); // The server's nonce
+const QuicTag kServerNonceTag = TAG('S', 'N', 'O', 0); // The server's nonce
const QuicTag kSourceAddressTokenTag =
TAG('S', 'T', 'K', 0); // Source-address token
-const QuicTag kCertificateTag =
- TAG('C', 'R', 'T', 255); // Certificate chain
+const QuicTag kCertificateTag = TAG('C', 'R', 'T', 255); // Certificate chain
+const QuicTag kCertificateSCTTag =
+ TAG('C', 'S', 'C', 'T'); // Signed cert timestamp (RFC6962) of leaf cert.
#undef TAG
diff --git a/chromium/net/quic/crypto/crypto_secret_boxer.cc b/chromium/net/quic/crypto/crypto_secret_boxer.cc
index 4e95442f3ff..6a7eecbb56c 100644
--- a/chromium/net/quic/crypto/crypto_secret_boxer.cc
+++ b/chromium/net/quic/crypto/crypto_secret_boxer.cc
@@ -35,7 +35,9 @@ static const size_t kKeySize = 16;
static const size_t kBoxNonceSize = 12;
// static
-size_t CryptoSecretBoxer::GetKeySize() { return kKeySize; }
+size_t CryptoSecretBoxer::GetKeySize() {
+ return kKeySize;
+}
void CryptoSecretBoxer::SetKey(StringPiece key) {
DCHECK_EQ(kKeySize, key.size());
@@ -59,9 +61,9 @@ string CryptoSecretBoxer::Box(QuicRandom* rand, StringPiece plaintext) const {
rand->RandBytes(data, kBoxNonceSize);
memcpy(data + kBoxNonceSize, plaintext.data(), plaintext.size());
- if (!encrypter->Encrypt(StringPiece(data, kBoxNonceSize), StringPiece(),
- plaintext, reinterpret_cast<unsigned char*>(
- data + kBoxNonceSize))) {
+ if (!encrypter->Encrypt(
+ StringPiece(data, kBoxNonceSize), StringPiece(), plaintext,
+ reinterpret_cast<unsigned char*>(data + kBoxNonceSize))) {
DLOG(DFATAL) << "CryptoSecretBoxer's Encrypt failed.";
return string();
}
diff --git a/chromium/net/quic/crypto/crypto_secret_boxer.h b/chromium/net/quic/crypto/crypto_secret_boxer.h
index 38b8fb339ec..266b34a5631 100644
--- a/chromium/net/quic/crypto/crypto_secret_boxer.h
+++ b/chromium/net/quic/crypto/crypto_secret_boxer.h
@@ -5,8 +5,11 @@
#ifndef NET_QUIC_CRYPTO_CRYPTO_SECRET_BOXER_H_
#define NET_QUIC_CRYPTO_CRYPTO_SECRET_BOXER_H_
+#include <stddef.h>
+
#include <string>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/quic/crypto/crypto_secret_boxer_test.cc b/chromium/net/quic/crypto/crypto_secret_boxer_test.cc
index 427d052d011..185e0a70141 100644
--- a/chromium/net/quic/crypto/crypto_secret_boxer_test.cc
+++ b/chromium/net/quic/crypto/crypto_secret_boxer_test.cc
@@ -17,7 +17,7 @@ namespace test {
TEST(CryptoSecretBoxerTest, BoxAndUnbox) {
StringPiece message("hello world");
const size_t key_size = CryptoSecretBoxer::GetKeySize();
- scoped_ptr<uint8[]> key(new uint8[key_size]);
+ scoped_ptr<uint8_t[]> key(new uint8_t[key_size]);
memset(key.get(), 0x11, key_size);
CryptoSecretBoxer boxer;
@@ -33,8 +33,9 @@ TEST(CryptoSecretBoxerTest, BoxAndUnbox) {
EXPECT_FALSE(boxer.Unbox(string(1, 'X') + box, &storage, &result));
EXPECT_FALSE(boxer.Unbox(box.substr(1, string::npos), &storage, &result));
EXPECT_FALSE(boxer.Unbox(string(), &storage, &result));
- EXPECT_FALSE(boxer.Unbox(string(1, box[0]^0x80) + box.substr(1, string::npos),
- &storage, &result));
+ EXPECT_FALSE(
+ boxer.Unbox(string(1, box[0] ^ 0x80) + box.substr(1, string::npos),
+ &storage, &result));
}
} // namespace test
diff --git a/chromium/net/quic/crypto/crypto_server_config_protobuf.cc b/chromium/net/quic/crypto/crypto_server_config_protobuf.cc
index d292f9e9db9..e574faac50e 100644
--- a/chromium/net/quic/crypto/crypto_server_config_protobuf.cc
+++ b/chromium/net/quic/crypto/crypto_server_config_protobuf.cc
@@ -10,9 +10,7 @@
namespace net {
QuicServerConfigProtobuf::QuicServerConfigProtobuf()
- : primary_time_(QuicWallTime::Zero().ToUNIXSeconds()),
- priority_(0) {
-}
+ : primary_time_(QuicWallTime::Zero().ToUNIXSeconds()), priority_(0) {}
QuicServerConfigProtobuf::~QuicServerConfigProtobuf() {
STLDeleteElements(&keys_);
diff --git a/chromium/net/quic/crypto/crypto_server_config_protobuf.h b/chromium/net/quic/crypto/crypto_server_config_protobuf.h
index fca5f0a51b8..9e1f9d3be3f 100644
--- a/chromium/net/quic/crypto/crypto_server_config_protobuf.h
+++ b/chromium/net/quic/crypto/crypto_server_config_protobuf.h
@@ -5,10 +5,14 @@
#ifndef NET_QUIC_CRYPTO_CRYPTO_SERVER_CONFIG_PROTOBUF_H_
#define NET_QUIC_CRYPTO_CRYPTO_SERVER_CONFIG_PROTOBUF_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -26,15 +30,9 @@ class NET_EXPORT_PRIVATE QuicServerConfigProtobuf {
// private key is specific to the algorithm in question.
class NET_EXPORT_PRIVATE PrivateKey {
public:
- QuicTag tag() const {
- return tag_;
- }
- void set_tag(QuicTag tag) {
- tag_ = tag;
- }
- std::string private_key() const {
- return private_key_;
- }
+ QuicTag tag() const { return tag_; }
+ void set_tag(QuicTag tag) { tag_ = tag; }
+ std::string private_key() const { return private_key_; }
void set_private_key(const std::string& key) { private_key_ = key; }
private:
@@ -45,55 +43,35 @@ class NET_EXPORT_PRIVATE QuicServerConfigProtobuf {
QuicServerConfigProtobuf();
~QuicServerConfigProtobuf();
- size_t key_size() const {
- return keys_.size();
- }
+ size_t key_size() const { return keys_.size(); }
const PrivateKey& key(size_t i) const {
DCHECK_GT(keys_.size(), i);
return *keys_[i];
}
- std::string config() const {
- return config_;
- }
+ std::string config() const { return config_; }
- void set_config(base::StringPiece config) {
- config.CopyToString(&config_);
- }
+ void set_config(base::StringPiece config) { config.CopyToString(&config_); }
QuicServerConfigProtobuf::PrivateKey* add_key() {
keys_.push_back(new PrivateKey);
return keys_.back();
}
- void clear_key() {
- STLDeleteElements(&keys_);
- }
+ void clear_key() { STLDeleteElements(&keys_); }
- bool has_primary_time() const {
- return primary_time_ > 0;
- }
+ bool has_primary_time() const { return primary_time_ > 0; }
- int64 primary_time() const {
- return primary_time_;
- }
+ int64_t primary_time() const { return primary_time_; }
- void set_primary_time(int64 primary_time) {
- primary_time_ = primary_time;
- }
+ void set_primary_time(int64_t primary_time) { primary_time_ = primary_time; }
- bool has_priority() const {
- return priority_ > 0;
- }
+ bool has_priority() const { return priority_ > 0; }
- uint64 priority() const {
- return priority_;
- }
+ uint64_t priority() const { return priority_; }
- void set_priority(int64 priority) {
- priority_ = priority;
- }
+ void set_priority(int64_t priority) { priority_ = priority; }
bool has_source_address_token_secret_override() const {
return !source_address_token_secret_override_.empty();
@@ -117,12 +95,12 @@ class NET_EXPORT_PRIVATE QuicServerConfigProtobuf {
// primary_time_ contains a UNIX epoch seconds value that indicates when this
// config should become primary.
- int64 primary_time_;
+ int64_t primary_time_;
// Relative priority of this config vs other configs with the same
// primary time. For use as a secondary sort key when selecting the
// primary config.
- uint64 priority_;
+ uint64_t priority_;
// Optional override to the secret used to box/unbox source address
// tokens when talking to clients that select this server config.
diff --git a/chromium/net/quic/crypto/crypto_server_test.cc b/chromium/net/quic/crypto/crypto_server_test.cc
index 4ff446be2c8..b2fa3472e18 100644
--- a/chromium/net/quic/crypto/crypto_server_test.cc
+++ b/chromium/net/quic/crypto/crypto_server_test.cc
@@ -5,10 +5,12 @@
#include <ostream>
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/secure_hash.h"
+#include "net/quic/crypto/cert_compressor.h"
+#include "net/quic/crypto/common_cert_set.h"
#include "net/quic/crypto/crypto_handshake.h"
+#include "net/quic/crypto/crypto_server_config_protobuf.h"
#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/crypto/proof_source.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
@@ -32,6 +34,24 @@ using std::vector;
namespace net {
namespace test {
+namespace {
+
+class DummyProofVerifierCallback : public ProofVerifierCallback {
+ public:
+ DummyProofVerifierCallback() {}
+ ~DummyProofVerifierCallback() override {}
+
+ void Run(bool ok,
+ const std::string& error_details,
+ scoped_ptr<ProofVerifyDetails>* details) override {
+ // Do nothing
+ }
+};
+
+const char kOldConfigId[] = "old-config-id";
+
+} // namespace
+
class QuicCryptoServerConfigPeer {
public:
explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
@@ -48,19 +68,24 @@ class QuicCryptoServerConfigPeer {
// Run tests with both parities of
// FLAGS_use_early_return_when_verifying_chlo.
struct TestParams {
- explicit TestParams(bool use_early_return_when_verifying_chlo,
- bool enable_stateless_rejects,
- bool use_stateless_rejects)
+ TestParams(bool use_early_return_when_verifying_chlo,
+ bool enable_stateless_rejects,
+ bool use_stateless_rejects,
+ QuicVersionVector supported_versions)
: use_early_return_when_verifying_chlo(
use_early_return_when_verifying_chlo),
enable_stateless_rejects(enable_stateless_rejects),
- use_stateless_rejects(use_stateless_rejects) {}
+ use_stateless_rejects(use_stateless_rejects),
+ supported_versions(supported_versions) {}
friend ostream& operator<<(ostream& os, const TestParams& p) {
os << "{ use_early_return_when_verifying_chlo: "
- << p.use_early_return_when_verifying_chlo << endl;
- os << " enable_stateless_rejects: " << p.enable_stateless_rejects << endl;
- os << " use_stateless_rejects: " << p.use_stateless_rejects << " }";
+ << p.use_early_return_when_verifying_chlo << std::endl;
+ os << " enable_stateless_rejects: " << p.enable_stateless_rejects
+ << std::endl;
+ os << " use_stateless_rejects: " << p.use_stateless_rejects << std::endl;
+ os << " versions: " << QuicVersionVectorToString(p.supported_versions)
+ << " }";
return os;
}
@@ -72,6 +97,8 @@ struct TestParams {
// rejecting messages. This should be a no-op if
// enable_stateless_rejects is false.
bool use_stateless_rejects;
+ // Versions supported by client and server.
+ QuicVersionVector supported_versions;
};
// Constructs various test permutations.
@@ -81,8 +108,14 @@ vector<TestParams> GetTestParams() {
for (bool use_early_return : kTrueFalse) {
for (bool enable_stateless_rejects : kTrueFalse) {
for (bool use_stateless_rejects : kTrueFalse) {
- params.push_back(TestParams(use_early_return, enable_stateless_rejects,
- use_stateless_rejects));
+ // Start with all versions, remove highest on each iteration.
+ QuicVersionVector supported_versions = QuicSupportedVersions();
+ while (!supported_versions.empty()) {
+ params.push_back(
+ TestParams(use_early_return, enable_stateless_rejects,
+ use_stateless_rejects, supported_versions));
+ supported_versions.erase(supported_versions.begin());
+ }
}
}
}
@@ -94,15 +127,15 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
CryptoServerTest()
: rand_(QuicRandom::GetInstance()),
client_address_(Loopback4(), 1234),
- config_(QuicCryptoServerConfig::TESTING, rand_) {
-#if defined(USE_OPENSSL)
- config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting());
-#else
- config_.SetProofSource(CryptoTestUtils::FakeProofSourceForTesting());
-#endif
- supported_versions_ = QuicSupportedVersions();
- client_version_ = QuicUtils::TagToString(
- QuicVersionToQuicTag(supported_versions_.front()));
+ config_(QuicCryptoServerConfig::TESTING,
+ rand_,
+ CryptoTestUtils::ProofSourceForTesting()) {
+ supported_versions_ = GetParam().supported_versions;
+ config_.set_enable_serving_sct(true);
+
+ client_version_ = supported_versions_.front();
+ client_version_string_ =
+ QuicUtils::TagToString(QuicVersionToQuicTag(client_version_));
FLAGS_use_early_return_when_verifying_chlo =
GetParam().use_early_return_when_verifying_chlo;
@@ -112,8 +145,15 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
}
void SetUp() override {
+ QuicCryptoServerConfig::ConfigOptions old_config_options;
+ old_config_options.id = kOldConfigId;
+ delete config_.AddDefaultConfig(rand_, &clock_, old_config_options);
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+ scoped_ptr<QuicServerConfigProtobuf> primary_config(
+ config_.GenerateConfig(rand_, &clock_, config_options_));
+ primary_config->set_primary_time(clock_.WallNow().ToUNIXSeconds());
scoped_ptr<CryptoHandshakeMessage> msg(
- config_.AddDefaultConfig(rand_, &clock_, config_options_));
+ config_.AddConfig(primary_config.get(), clock_.WallNow()));
StringPiece orbit;
CHECK(msg->GetStringPiece(kORBT, &orbit));
@@ -134,7 +174,8 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
"KEXS", "C255",
"PUBS", pub_hex_.c_str(),
"NONC", nonce_hex_.c_str(),
- "VER\0", client_version_.data(),
+ "CSCT", "",
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -203,9 +244,9 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
const QuicTag* versions;
size_t num_versions;
server_hello.GetTaglist(kVER, &versions, &num_versions);
- ASSERT_EQ(QuicSupportedVersions().size(), num_versions);
+ ASSERT_EQ(supported_versions_.size(), num_versions);
for (size_t i = 0; i < num_versions; ++i) {
- EXPECT_EQ(QuicVersionToQuicTag(QuicSupportedVersions()[i]), versions[i]);
+ EXPECT_EQ(QuicVersionToQuicTag(supported_versions_[i]), versions[i]);
}
StringPiece address;
@@ -282,9 +323,9 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
void CheckRejectReasons(
const HandshakeFailureReason* expected_handshake_failures,
size_t expected_count) {
- const uint32* reject_reasons;
+ const uint32_t* reject_reasons;
size_t num_reject_reasons;
- COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync);
+ static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header_out_of_sync");
QuicErrorCode error_code =
out_.GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons);
ASSERT_EQ(QUIC_NO_ERROR, error_code);
@@ -318,9 +359,9 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
void CheckRejectTag() {
if (RejectsAreStateless()) {
- ASSERT_EQ(kSREJ, out_.tag());
+ ASSERT_EQ(kSREJ, out_.tag()) << QuicUtils::TagToString(out_.tag());
} else {
- ASSERT_EQ(kREJ, out_.tag());
+ ASSERT_EQ(kREJ, out_.tag()) << QuicUtils::TagToString(out_.tag());
}
}
@@ -333,22 +374,18 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
const vector<string>* certs;
IPAddressNumber server_ip;
string sig;
-#if defined(USE_OPENSSL)
+ string cert_sct;
scoped_ptr<ProofSource> proof_source(
CryptoTestUtils::ProofSourceForTesting());
-#else
- scoped_ptr<ProofSource> proof_source(
- CryptoTestUtils::FakeProofSourceForTesting());
-#endif
- if (!proof_source->GetProof(server_ip, "", "", false, &certs, &sig) ||
+ if (!proof_source->GetProof(server_ip, "", "", false, &certs, &sig,
+ &cert_sct) ||
certs->empty()) {
return "#0100000000000000";
}
std::ostringstream xlct_stream;
- uint64 xlct =
- QuicUtils::FNV1a_64_Hash(certs->at(0).data(), certs->at(0).length());
-
+ uint64_t xlct =
+ QuicUtils::FNV1a_64_Hash(certs->at(0).c_str(), certs->at(0).length());
return "#" + base::HexEncode(reinterpret_cast<char*>(&xlct), sizeof(xlct));
}
@@ -356,15 +393,16 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
QuicRandom* const rand_;
MockRandom rand_for_id_generation_;
MockClock clock_;
- const IPEndPoint client_address_;
+ IPEndPoint client_address_;
QuicVersionVector supported_versions_;
- string client_version_;
+ QuicVersion client_version_;
+ string client_version_string_;
QuicCryptoServerConfig config_;
QuicCryptoServerConfig::ConfigOptions config_options_;
QuicCryptoNegotiatedParameters params_;
QuicCryptoProof crypto_proof_;
CryptoHandshakeMessage out_;
- uint8 orbit_[kOrbitSize];
+ uint8_t orbit_[kOrbitSize];
bool use_stateless_rejects_;
// These strings contain hex escaped values from the server suitable for using
@@ -391,15 +429,12 @@ TEST_P(CryptoServerTest, BadSNI) {
};
// clang-format on
- string client_version =
- QuicUtils::TagToString(QuicVersionToQuicTag(supported_versions_.front()));
-
for (size_t i = 0; i < arraysize(kBadSNIs); i++) {
// clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",
"SNI", kBadSNIs[i],
- "VER\0", client_version.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -410,35 +445,128 @@ TEST_P(CryptoServerTest, BadSNI) {
}
}
-// TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource.
-// See http://crbug.com/514472.
TEST_P(CryptoServerTest, DefaultCert) {
// Check that the server replies with a default certificate when no SNI is
- // specified.
+ // specified. The CHLO is constructed to generate a REJ with certs, so must
+ // not contain a valid STK, and must include PDMD.
// clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",
"AEAD", "AESG",
"KEXS", "C255",
- "SCID", scid_hex_.c_str(),
- "#004b5453", srct_hex_.c_str(),
"PUBS", pub_hex_.c_str(),
"NONC", nonce_hex_.c_str(),
"PDMD", "X509",
- "XLCT", XlctHexString().c_str(),
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
ShouldSucceed(msg);
- StringPiece cert, proof;
+ StringPiece cert, proof, cert_sct;
EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+ EXPECT_EQ(client_version_ > QUIC_VERSION_29,
+ out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
EXPECT_NE(0u, cert.size());
EXPECT_NE(0u, proof.size());
const HandshakeFailureReason kRejectReasons[] = {
- CLIENT_NONCE_INVALID_TIME_FAILURE};
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ EXPECT_EQ(client_version_ > QUIC_VERSION_29, cert_sct.size() > 0);
+}
+
+TEST_P(CryptoServerTest, RejectTooLarge) {
+ // Check that the server replies with no certificate when a CHLO is
+ // constructed with a PDMD but no SKT when the REJ would be too large.
+ // clang-format off
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "PDMD", "X509",
+ "VER\0", client_version_string_.c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
+
+ // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+ config_.set_chlo_multiplier(1);
+
+ ShouldSucceed(msg);
+ StringPiece cert, proof, cert_sct;
+ EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
+ EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
+ EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_validate_stk_without_scid, true);
+ // Check that the server replies with no certificate when a CHLO is
+ // constructed with a PDMD but no SKT when the REJ would be too large.
+ // clang-format off
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PDMD", "X509",
+ "VER\0", client_version_string_.c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
+
+ // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+ config_.set_chlo_multiplier(1);
+
+ ShouldSucceed(msg);
+ StringPiece cert, proof, cert_sct;
+ EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+ EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+ EXPECT_EQ(client_version_ > QUIC_VERSION_29,
+ out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+ EXPECT_NE(0u, cert.size());
+ EXPECT_NE(0u, proof.size());
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, RejectTooLargeButValidSTKWithoutFlag) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_validate_stk_without_scid, false);
+ // Check that the server replies with no certificate when a CHLO is
+ // constructed with a PDMD but no SKT when the REJ would be too large.
+ // clang-format off
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PDMD", "X509",
+ "VER\0", client_version_string_.c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
+
+ // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+ config_.set_chlo_multiplier(1);
+
+ ShouldSucceed(msg);
+ StringPiece cert, proof, cert_sct;
+ EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
+ EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
+ EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
@@ -446,7 +574,7 @@ TEST_P(CryptoServerTest, TooSmall) {
// clang-format off
ShouldFailMentioning("too small", CryptoTestUtils::Message(
"CHLO",
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
nullptr));
// clang-format on
const HandshakeFailureReason kRejectReasons[] = {
@@ -470,7 +598,7 @@ TEST_P(CryptoServerTest, BadSourceAddressToken) {
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",
"STK", kBadSourceAddressTokens[i],
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize), nullptr);
// clang-format on
ShouldSucceed(msg);
@@ -495,7 +623,7 @@ TEST_P(CryptoServerTest, BadClientNonce) {
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",
"NONC", kBadNonces[i],
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -519,7 +647,7 @@ TEST_P(CryptoServerTest, DowngradeAttack) {
// clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",
- "VER\0", bad_version.data(),
+ "VER\0", bad_version.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -540,7 +668,7 @@ TEST_P(CryptoServerTest, CorruptServerConfig) {
"#004b5453", srct_hex_.c_str(),
"PUBS", pub_hex_.c_str(),
"NONC", nonce_hex_.c_str(),
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -563,7 +691,7 @@ TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
"PUBS", pub_hex_.c_str(),
"NONC", nonce_hex_.c_str(),
"XLCT", XlctHexString().c_str(),
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -586,7 +714,7 @@ TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
"PUBS", pub_hex_.c_str(),
"NONC", (string(1, 'X') + nonce_hex_).c_str(),
"XLCT", XlctHexString().c_str(),
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -610,20 +738,30 @@ TEST_P(CryptoServerTest, CorruptMultipleTags) {
"NONC", (string(1, 'X') + nonce_hex_).c_str(),
"SNO\0", (string(1, 'X') + nonce_hex_).c_str(),
"XLCT", XlctHexString().c_str(),
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
ShouldSucceed(msg);
CheckRejectTag();
- const HandshakeFailureReason kRejectReasons[] = {
- SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE,
- SERVER_NONCE_DECRYPTION_FAILURE,
+
+ if (client_version_ <= QUIC_VERSION_30) {
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE,
+ SERVER_NONCE_DECRYPTION_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ } else {
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
TEST_P(CryptoServerTest, ReplayProtection) {
+ if (client_version_ > QUIC_VERSION_30) {
+ return;
+ }
+ FLAGS_require_strike_register_or_server_nonce = false;
// This tests that disabling replay protection works.
// clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
@@ -635,7 +773,7 @@ TEST_P(CryptoServerTest, ReplayProtection) {
"PUBS", pub_hex_.c_str(),
"NONC", nonce_hex_.c_str(),
"XLCT", XlctHexString().c_str(),
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -661,31 +799,163 @@ TEST_P(CryptoServerTest, ReplayProtection) {
CheckServerHello(out_);
}
+TEST_P(CryptoServerTest, NoServerNonce) {
+ FLAGS_require_strike_register_or_server_nonce = true;
+ // When no server nonce is present and no strike register is configured,
+ // the CHLO should be rejected.
+ // clang-format off
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "XLCT", XlctHexString().c_str(),
+ "VER\0", client_version_string_.c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
+
+ ShouldSucceed(msg);
+
+ CheckRejectTag();
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_NONCE_REQUIRED_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_use_primary_config_for_proof, true);
+ client_address_ = IPEndPoint(Loopback6(), 1234);
+ // clang-format off
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "PDMD", "X509",
+ "SCID", kOldConfigId,
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_string_.c_str(),
+ "XLCT", XlctHexString().c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
+ ShouldSucceed(msg);
+ // The message should be rejected because the source-address token is no
+ // longer valid.
+ CheckRejectTag();
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE};
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+
+ StringPiece cert, proof, scfg_str;
+ EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+ EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+ EXPECT_TRUE(out_.GetStringPiece(kSCFG, &scfg_str));
+ scoped_ptr<CryptoHandshakeMessage> scfg(CryptoFramer::ParseMessage(scfg_str));
+ StringPiece scid;
+ EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
+ EXPECT_NE(scid, kOldConfigId);
+
+ // Get certs from compressed certs.
+ const CommonCertSets* common_cert_sets(CommonCertSets::GetInstanceQUIC());
+ vector<string> cached_certs;
+
+ vector<string> certs;
+ ASSERT_TRUE(CertCompressor::DecompressChain(cert, cached_certs,
+ common_cert_sets, &certs));
+
+ // Check that the proof in the REJ message is valid.
+ scoped_ptr<ProofVerifier> proof_verifier(
+ CryptoTestUtils::ProofVerifierForTesting());
+ scoped_ptr<ProofVerifyContext> verify_context(
+ CryptoTestUtils::ProofVerifyContextForTesting());
+ scoped_ptr<ProofVerifyDetails> details;
+ string error_details;
+ DummyProofVerifierCallback callback;
+ EXPECT_EQ(QUIC_SUCCESS, proof_verifier->VerifyProof(
+ "test.example.com", scfg_str.as_string(), certs,
+ "", proof.as_string(), verify_context.get(),
+ &error_details, &details, &callback));
+}
+
TEST_P(CryptoServerTest, RejectInvalidXlct) {
+ if (client_version_ <= QUIC_VERSION_25) {
+ // XLCT tag introduced in QUIC_VERSION_26.
+ return;
+ }
+ // clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
- "CHLO", "AEAD", "AESG", "KEXS", "C255", "SCID", scid_hex_.c_str(),
- "#004b5453", srct_hex_.c_str(), "PUBS", pub_hex_.c_str(), "NONC",
- nonce_hex_.c_str(), "VER\0", client_version_.data(), "XLCT",
- "#0102030405060708", "$padding",
- static_cast<int>(kClientHelloMinimumSize), nullptr);
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_string_.c_str(),
+ "XLCT", "#0102030405060708",
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
// If replay protection isn't disabled, then
// QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
// and cause ProcessClientHello to exit early (and generate a REJ message).
config_.set_replay_protection(false);
ShouldSucceed(msg);
+ // clang-format off
const HandshakeFailureReason kRejectReasons[] = {
- INVALID_EXPECTED_LEAF_CERTIFICATE};
+ INVALID_EXPECTED_LEAF_CERTIFICATE
+ };
+ // clang-format on
CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
TEST_P(CryptoServerTest, ValidXlct) {
+ // clang-format off
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_string_.c_str(),
+ "XLCT", XlctHexString().c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
+ // If replay protection isn't disabled, then
+ // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+ // and cause ProcessClientHello to exit early (and generate a REJ message).
+ config_.set_replay_protection(false);
+
+ ShouldSucceed(msg);
+ EXPECT_EQ(kSHLO, out_.tag());
+}
+
+TEST_P(CryptoServerTest, NonceInSHLO) {
+ // After QUIC_VERSION_27, the SHLO should contain a nonce.
+ // clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
- "CHLO", "AEAD", "AESG", "KEXS", "C255", "SCID", scid_hex_.c_str(),
- "#004b5453", srct_hex_.c_str(), "PUBS", pub_hex_.c_str(), "NONC",
- nonce_hex_.c_str(), "VER\0", client_version_.data(), "XLCT",
- XlctHexString().c_str(), "$padding",
- static_cast<int>(kClientHelloMinimumSize), nullptr);
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_string_.c_str(),
+ "XLCT", XlctHexString().c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
// If replay protection isn't disabled, then
// QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
// and cause ProcessClientHello to exit early (and generate a REJ message).
@@ -693,6 +963,13 @@ TEST_P(CryptoServerTest, ValidXlct) {
ShouldSucceed(msg);
EXPECT_EQ(kSHLO, out_.tag());
+
+ StringPiece nonce;
+ if (client_version_ <= QUIC_VERSION_26) {
+ EXPECT_FALSE(out_.GetStringPiece(kServerNonceTag, &nonce));
+ } else {
+ EXPECT_TRUE(out_.GetStringPiece(kServerNonceTag, &nonce));
+ }
}
TEST(CryptoServerConfigGenerationTest, Determinism) {
@@ -703,8 +980,10 @@ TEST(CryptoServerConfigGenerationTest, Determinism) {
const QuicCryptoServerConfig::ConfigOptions options;
MockClock clock;
- QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a);
- QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b);
+ QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+ CryptoTestUtils::ProofSourceForTesting());
+ QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
+ CryptoTestUtils::ProofSourceForTesting());
scoped_ptr<CryptoHandshakeMessage> scfg_a(
a.AddDefaultConfig(&rand_a, &clock, options));
scoped_ptr<CryptoHandshakeMessage> scfg_b(
@@ -721,9 +1000,11 @@ TEST(CryptoServerConfigGenerationTest, SCIDVaries) {
const QuicCryptoServerConfig::ConfigOptions options;
MockClock clock;
- QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a);
+ QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+ CryptoTestUtils::ProofSourceForTesting());
rand_b.ChangeValue();
- QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b);
+ QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
+ CryptoTestUtils::ProofSourceForTesting());
scoped_ptr<CryptoHandshakeMessage> scfg_a(
a.AddDefaultConfig(&rand_a, &clock, options));
scoped_ptr<CryptoHandshakeMessage> scfg_b(
@@ -741,7 +1022,8 @@ TEST(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
const QuicCryptoServerConfig::ConfigOptions options;
MockClock clock;
- QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a);
+ QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+ CryptoTestUtils::ProofSourceForTesting());
scoped_ptr<CryptoHandshakeMessage> scfg(
a.AddDefaultConfig(&rand_a, &clock, options));
@@ -757,11 +1039,11 @@ TEST(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
scoped_ptr<crypto::SecureHash> hash(
crypto::SecureHash::Create(crypto::SecureHash::SHA256));
hash->Update(serialized.data(), serialized.length());
- uint8 digest[16];
+ uint8_t digest[16];
hash->Finish(digest, sizeof(digest));
ASSERT_EQ(scid.size(), sizeof(digest));
- EXPECT_EQ(0, memcmp(digest, scid_str.data(), sizeof(digest)));
+ EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), sizeof(digest)));
}
class CryptoServerTestNoConfig : public CryptoServerTest {
@@ -775,7 +1057,7 @@ TEST_P(CryptoServerTestNoConfig, DontCrash) {
// clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -789,19 +1071,28 @@ TEST_P(CryptoServerTestNoConfig, DontCrash) {
class CryptoServerTestOldVersion : public CryptoServerTest {
public:
void SetUp() override {
- client_version_ = QuicUtils::TagToString(
- QuicVersionToQuicTag(supported_versions_.back()));
+ client_version_ = supported_versions_.back();
+ client_version_string_ =
+ QuicUtils::TagToString(QuicVersionToQuicTag(client_version_));
CryptoServerTest::SetUp();
}
};
TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) {
+ // clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
- "CHLO", "AEAD", "AESG", "KEXS", "C255", "SCID", scid_hex_.c_str(),
- "#004b5453", srct_hex_.c_str(), "PUBS", pub_hex_.c_str(), "NONC",
- nonce_hex_.c_str(), "VER\0", client_version_.data(), "XLCT",
- "#0100000000000000", "$padding",
- static_cast<int>(kClientHelloMinimumSize), nullptr);
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_string_.c_str(),
+ "XLCT", "#0100000000000000",
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
// If replay protection isn't disabled, then
// QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
// and cause ProcessClientHello to exit early (and generate a REJ message).
@@ -812,11 +1103,19 @@ TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) {
}
TEST_P(CryptoServerTestOldVersion, XlctNotRequired) {
+ // clang-format off
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
- "CHLO", "AEAD", "AESG", "KEXS", "C255", "SCID", scid_hex_.c_str(),
- "#004b5453", srct_hex_.c_str(), "PUBS", pub_hex_.c_str(), "NONC",
- nonce_hex_.c_str(), "VER\0", client_version_.data(), "$padding",
- static_cast<int>(kClientHelloMinimumSize), nullptr);
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_string_.c_str(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ nullptr);
+ // clang-format on
// If replay protection isn't disabled, then
// QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
// and cause ProcessClientHello to exit early (and generate a REJ message).
@@ -835,9 +1134,9 @@ class AsyncStrikeServerVerificationTest : public CryptoServerTest {
config_options_.orbit = kOrbit;
strike_register_client_ = new DelayedVerifyStrikeRegisterClient(
10000, // strike_register_max_entries
- static_cast<uint32>(clock_.WallNow().ToUNIXSeconds()),
+ static_cast<uint32_t>(clock_.WallNow().ToUNIXSeconds()),
60, // strike_register_window_secs
- reinterpret_cast<const uint8*>(kOrbit.data()),
+ reinterpret_cast<const uint8_t*>(kOrbit.c_str()),
StrikeRegister::NO_STARTUP_PERIOD_NEEDED);
config_.SetStrikeRegisterClient(strike_register_client_);
CryptoServerTest::SetUp();
@@ -858,7 +1157,7 @@ TEST_P(AsyncStrikeServerVerificationTest, AsyncReplayProtection) {
"#004b5453", srct_hex_.c_str(),
"PUBS", pub_hex_.c_str(),
"NONC", nonce_hex_.c_str(),
- "VER\0", client_version_.data(),
+ "VER\0", client_version_string_.c_str(),
"$padding", static_cast<int>(kClientHelloMinimumSize),
nullptr);
// clang-format on
@@ -868,9 +1167,9 @@ TEST_P(AsyncStrikeServerVerificationTest, AsyncReplayProtection) {
bool called = false;
IPAddressNumber server_ip;
- config_.ValidateClientHello(
- msg, client_address_.address(), server_ip, supported_versions_.front(),
- &clock_, &crypto_proof_, new ValidateCallback(this, true, "", &called));
+ config_.ValidateClientHello(msg, client_address_.address(), server_ip,
+ client_version_, &clock_, &crypto_proof_,
+ new ValidateCallback(this, true, "", &called));
// The verification request was queued.
ASSERT_FALSE(called);
EXPECT_EQ(0u, out_.tag());
@@ -884,9 +1183,9 @@ TEST_P(AsyncStrikeServerVerificationTest, AsyncReplayProtection) {
EXPECT_EQ(kSHLO, out_.tag());
// Rejected if replayed.
- config_.ValidateClientHello(
- msg, client_address_.address(), server_ip, supported_versions_.front(),
- &clock_, &crypto_proof_, new ValidateCallback(this, true, "", &called));
+ config_.ValidateClientHello(msg, client_address_.address(), server_ip,
+ client_version_, &clock_, &crypto_proof_,
+ new ValidateCallback(this, true, "", &called));
// The verification request was queued.
ASSERT_FALSE(called);
EXPECT_EQ(1, strike_register_client_->PendingVerifications());
diff --git a/chromium/net/quic/crypto/crypto_utils.cc b/chromium/net/quic/crypto/crypto_utils.cc
index 6021dc63b3c..0c6a4a742f6 100644
--- a/chromium/net/quic/crypto/crypto_utils.cc
+++ b/chromium/net/quic/crypto/crypto_utils.cc
@@ -30,7 +30,7 @@ void CryptoUtils::GenerateNonce(QuicWallTime now,
nonce->reserve(kNonceSize);
nonce->resize(kNonceSize);
- uint32 gmt_unix_time = static_cast<uint32>(now.ToUNIXSeconds());
+ uint32_t gmt_unix_time = static_cast<uint32_t>(now.ToUNIXSeconds());
// The time in the nonce must be encoded in big-endian because the
// strike-register depends on the nonces being ordered by time.
(*nonce)[0] = static_cast<char>(gmt_unix_time >> 24);
@@ -58,8 +58,8 @@ bool CryptoUtils::IsValidSNI(StringPiece sni) {
url::CanonHostInfo host_info;
string canonicalized_host(CanonicalizeHost(sni.as_string(), &host_info));
return !host_info.IsIPAddress() &&
- IsCanonicalizedHostCompliant(canonicalized_host) &&
- sni.find_last_of('.') != string::npos;
+ IsCanonicalizedHostCompliant(canonicalized_host) &&
+ sni.find_last_of('.') != string::npos;
}
// static
@@ -140,29 +140,138 @@ bool CryptoUtils::ExportKeyingMaterial(StringPiece subkey_secret,
}
}
// Create HKDF info input: null-terminated label + length-prefixed context
- if (context.length() >= numeric_limits<uint32>::max()) {
+ if (context.length() >= numeric_limits<uint32_t>::max()) {
LOG(ERROR) << "Context value longer than 2^32";
return false;
}
- uint32 context_length = static_cast<uint32>(context.length());
+ uint32_t context_length = static_cast<uint32_t>(context.length());
string info = label.as_string();
info.push_back('\0');
info.append(reinterpret_cast<char*>(&context_length), sizeof(context_length));
info.append(context.data(), context.length());
- crypto::HKDF hkdf(subkey_secret,
- StringPiece() /* no salt */,
- info,
- result_len,
- 0 /* no fixed IV */,
- 0 /* no subkey secret */);
+ crypto::HKDF hkdf(subkey_secret, StringPiece() /* no salt */, info,
+ result_len, 0 /* no fixed IV */, 0 /* no subkey secret */);
hkdf.client_write_key().CopyToString(result);
return true;
}
// static
-uint64 CryptoUtils::ComputeLeafCertHash(const std::string& cert) {
+uint64_t CryptoUtils::ComputeLeafCertHash(const std::string& cert) {
return QuicUtils::FNV1a_64_Hash(cert.data(), cert.size());
}
+QuicErrorCode CryptoUtils::ValidateServerHello(
+ const CryptoHandshakeMessage& server_hello,
+ const QuicVersionVector& negotiated_versions,
+ string* error_details) {
+ DCHECK(error_details != nullptr);
+
+ if (server_hello.tag() != kSHLO) {
+ *error_details = "Bad tag";
+ return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+ }
+
+ const QuicTag* supported_version_tags;
+ size_t num_supported_versions;
+
+ if (server_hello.GetTaglist(kVER, &supported_version_tags,
+ &num_supported_versions) != QUIC_NO_ERROR) {
+ *error_details = "server hello missing version list";
+ return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+ }
+ if (!negotiated_versions.empty()) {
+ bool mismatch = num_supported_versions != negotiated_versions.size();
+ for (size_t i = 0; i < num_supported_versions && !mismatch; ++i) {
+ mismatch = QuicTagToQuicVersion(supported_version_tags[i]) !=
+ negotiated_versions[i];
+ }
+ // The server sent a list of supported versions, and the connection
+ // reports that there was a version negotiation during the handshake.
+ // Ensure that these two lists are identical.
+ if (mismatch) {
+ *error_details = "Downgrade attack detected";
+ return QUIC_VERSION_NEGOTIATION_MISMATCH;
+ }
+ }
+ return QUIC_NO_ERROR;
+}
+
+QuicErrorCode CryptoUtils::ValidateClientHello(
+ const CryptoHandshakeMessage& client_hello,
+ QuicVersion version,
+ const QuicVersionVector& supported_versions,
+ string* error_details) {
+ if (client_hello.tag() != kCHLO) {
+ *error_details = "Bad tag";
+ return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+ }
+
+ // If the client's preferred version is not the version we are currently
+ // speaking, then the client went through a version negotiation. In this
+ // case, we need to make sure that we actually do not support this version
+ // and that it wasn't a downgrade attack.
+ QuicTag client_version_tag;
+ if (client_hello.GetUint32(kVER, &client_version_tag) != QUIC_NO_ERROR) {
+ *error_details = "client hello missing version list";
+ return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+ }
+ QuicVersion client_version = QuicTagToQuicVersion(client_version_tag);
+ if (client_version != version) {
+ // Just because client_version is a valid version enum doesn't mean that
+ // this server actually supports that version, so we check to see if
+ // it's actually in the supported versions list.
+ for (size_t i = 0; i < supported_versions.size(); ++i) {
+ if (client_version == supported_versions[i]) {
+ *error_details = "Downgrade attack detected";
+ return QUIC_VERSION_NEGOTIATION_MISMATCH;
+ }
+ }
+ }
+ return QUIC_NO_ERROR;
+}
+
+#define RETURN_STRING_LITERAL(x) \
+ case x: \
+ return #x
+
+// Returns the name of the HandshakeFailureReason as a char*
+// static
+const char* CryptoUtils::HandshakeFailureReasonToString(
+ HandshakeFailureReason reason) {
+ switch (reason) {
+ RETURN_STRING_LITERAL(HANDSHAKE_OK);
+ RETURN_STRING_LITERAL(CLIENT_NONCE_UNKNOWN_FAILURE);
+ RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_FAILURE);
+ RETURN_STRING_LITERAL(CLIENT_NONCE_NOT_UNIQUE_FAILURE);
+ RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_ORBIT_FAILURE);
+ RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_TIME_FAILURE);
+ RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT);
+ RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_FAILURE);
+
+ RETURN_STRING_LITERAL(SERVER_NONCE_DECRYPTION_FAILURE);
+ RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_FAILURE);
+ RETURN_STRING_LITERAL(SERVER_NONCE_NOT_UNIQUE_FAILURE);
+ RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_TIME_FAILURE);
+ RETURN_STRING_LITERAL(SERVER_NONCE_REQUIRED_FAILURE);
+
+ RETURN_STRING_LITERAL(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
+ RETURN_STRING_LITERAL(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
+
+ RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_INVALID_FAILURE);
+ RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE);
+ RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_PARSE_FAILURE);
+ RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE);
+ RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE);
+ RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE);
+
+ RETURN_STRING_LITERAL(INVALID_EXPECTED_LEAF_CERTIFICATE);
+ RETURN_STRING_LITERAL(MAX_FAILURE_REASON);
+ }
+ // Return a default value so that we return this when |reason| doesn't match
+ // any HandshakeFailureReason.. This can happen when the message by the peer
+ // (attacker) has invalid reason.
+ return "INVALID_HANDSHAKE_FAILURE_REASON";
+}
+
} // namespace net
diff --git a/chromium/net/quic/crypto/crypto_utils.h b/chromium/net/quic/crypto/crypto_utils.h
index 436f178e14f..b4e40e9043c 100644
--- a/chromium/net/quic/crypto/crypto_utils.h
+++ b/chromium/net/quic/crypto/crypto_utils.h
@@ -7,11 +7,16 @@
#ifndef NET_QUIC_CRYPTO_CRYPTO_UTILS_H_
#define NET_QUIC_CRYPTO_CRYPTO_UTILS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/quic/crypto/crypto_handshake.h"
+#include "net/quic/crypto/crypto_handshake_message.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
@@ -72,7 +77,33 @@ class NET_EXPORT_PRIVATE CryptoUtils {
// Computes the FNV-1a hash of the provided DER-encoded cert for use in the
// XLCT tag.
- static uint64 ComputeLeafCertHash(const std::string& cert);
+ static uint64_t ComputeLeafCertHash(const std::string& cert);
+
+ // Validates that |server_hello| is actually an SHLO message and that it is
+ // not part of a downgrade attack.
+ //
+ // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+ // code and sets |error_details|.
+ static QuicErrorCode ValidateServerHello(
+ const CryptoHandshakeMessage& server_hello,
+ const QuicVersionVector& negotiated_versions,
+ std::string* error_details);
+
+ // Validates that |client_hello| is actually a CHLO and that this is not part
+ // of a downgrade attack.
+ // This includes verifiying versions and detecting downgrade attacks.
+ //
+ // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+ // code and sets |error_details|.
+ static QuicErrorCode ValidateClientHello(
+ const CryptoHandshakeMessage& client_hello,
+ QuicVersion version,
+ const QuicVersionVector& supported_versions,
+ std::string* error_details);
+
+ // Returns the name of the HandshakeFailureReason as a char*
+ static const char* HandshakeFailureReasonToString(
+ HandshakeFailureReason reason);
private:
DISALLOW_COPY_AND_ASSIGN(CryptoUtils);
diff --git a/chromium/net/quic/crypto/crypto_utils_test.cc b/chromium/net/quic/crypto/crypto_utils_test.cc
index 1395cc31372..c8be70022b3 100644
--- a/chromium/net/quic/crypto/crypto_utils_test.cc
+++ b/chromium/net/quic/crypto/crypto_utils_test.cc
@@ -33,12 +33,24 @@ TEST(CryptoUtilsTest, NormalizeHostname) {
struct {
const char *input, *expected;
} tests[] = {
- { "www.google.com", "www.google.com", },
- { "WWW.GOOGLE.COM", "www.google.com", },
- { "www.google.com.", "www.google.com", },
- { "www.google.COM.", "www.google.com", },
- { "www.google.com..", "www.google.com", },
- { "www.google.com........", "www.google.com", },
+ {
+ "www.google.com", "www.google.com",
+ },
+ {
+ "WWW.GOOGLE.COM", "www.google.com",
+ },
+ {
+ "www.google.com.", "www.google.com",
+ },
+ {
+ "www.google.COM.", "www.google.com",
+ },
+ {
+ "www.google.com..", "www.google.com",
+ },
+ {
+ "www.google.com........", "www.google.com",
+ },
};
for (size_t i = 0; i < arraysize(tests); ++i) {
@@ -58,41 +70,24 @@ TEST(CryptoUtilsTest, TestExportKeyingMaterial) {
// Expected output (string of hexadecimal digits):
const char* expected; // Null if it should fail.
} test_vector[] = {
- // Try a typical input
- { "4823c1189ecc40fce888fbb4cf9ae6254f19ba12e6d9af54788f195a6f509ca3",
- "e934f78d7a71dd85420fceeb8cea0317",
- "b8d766b5d3c8aba0009c7ed3de553eba53b4de1030ea91383dcdf724cd8b7217",
- 32,
- "a9979da0d5f1c1387d7cbe68f5c4163ddb445a03c4ad6ee72cb49d56726d679e"
- },
- // Don't let the label contain nulls
- { "14fe51e082ffee7d1b4d8d4ab41f8c55",
- "3132333435363700",
- "58585858585858585858585858585858",
- 16,
- nullptr
- },
- // Make sure nulls in the context are fine
- { "d862c2e36b0a42f7827c67ebc8d44df7",
- "7a5b95e4e8378123",
- "4142434445464700",
- 16,
- "12d418c6d0738a2e4d85b2d0170f76e1"
- },
- // ... and give a different result than without
- { "d862c2e36b0a42f7827c67ebc8d44df7",
- "7a5b95e4e8378123",
- "41424344454647",
- 16,
- "abfa1c479a6e3ffb98a11dee7d196408"
- },
- // Try weird lengths
- { "d0ec8a34f6cc9a8c96",
- "49711798cc6251",
- "933d4a2f30d22f089cfba842791116adc121e0",
- 23,
- "c9a46ed0757bd1812f1f21b4d41e62125fec8364a21db7"
- },
+ // Try a typical input
+ {"4823c1189ecc40fce888fbb4cf9ae6254f19ba12e6d9af54788f195a6f509ca3",
+ "e934f78d7a71dd85420fceeb8cea0317",
+ "b8d766b5d3c8aba0009c7ed3de553eba53b4de1030ea91383dcdf724cd8b7217", 32,
+ "a9979da0d5f1c1387d7cbe68f5c4163ddb445a03c4ad6ee72cb49d56726d679e"},
+ // Don't let the label contain nulls
+ {"14fe51e082ffee7d1b4d8d4ab41f8c55", "3132333435363700",
+ "58585858585858585858585858585858", 16, nullptr},
+ // Make sure nulls in the context are fine
+ {"d862c2e36b0a42f7827c67ebc8d44df7", "7a5b95e4e8378123",
+ "4142434445464700", 16, "12d418c6d0738a2e4d85b2d0170f76e1"},
+ // ... and give a different result than without
+ {"d862c2e36b0a42f7827c67ebc8d44df7", "7a5b95e4e8378123", "41424344454647",
+ 16, "abfa1c479a6e3ffb98a11dee7d196408"},
+ // Try weird lengths
+ {"d0ec8a34f6cc9a8c96", "49711798cc6251",
+ "933d4a2f30d22f089cfba842791116adc121e0", 23,
+ "c9a46ed0757bd1812f1f21b4d41e62125fec8364a21db7"},
};
for (size_t i = 0; i < arraysize(test_vector); i++) {
@@ -111,23 +106,92 @@ TEST(CryptoUtilsTest, TestExportKeyingMaterial) {
}
string result;
- bool ok = CryptoUtils::ExportKeyingMaterial(subkey_secret,
- label,
- context,
- result_len,
- &result);
+ bool ok = CryptoUtils::ExportKeyingMaterial(subkey_secret, label, context,
+ result_len, &result);
EXPECT_EQ(expect_ok, ok);
if (expect_ok) {
EXPECT_EQ(result_len, result.length());
- test::CompareCharArraysWithHexError("HKDF output",
- result.data(),
- result.length(),
- expected.data(),
+ test::CompareCharArraysWithHexError("HKDF output", result.data(),
+ result.length(), expected.data(),
expected.length());
}
}
}
+TEST(CryptoUtilsTest, HandshakeFailureReasonToString) {
+ EXPECT_STREQ("HANDSHAKE_OK",
+ CryptoUtils::HandshakeFailureReasonToString(HANDSHAKE_OK));
+ EXPECT_STREQ("CLIENT_NONCE_UNKNOWN_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ CLIENT_NONCE_UNKNOWN_FAILURE));
+ EXPECT_STREQ("CLIENT_NONCE_INVALID_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ CLIENT_NONCE_INVALID_FAILURE));
+ EXPECT_STREQ("CLIENT_NONCE_NOT_UNIQUE_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ CLIENT_NONCE_NOT_UNIQUE_FAILURE));
+ EXPECT_STREQ("CLIENT_NONCE_INVALID_ORBIT_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ CLIENT_NONCE_INVALID_ORBIT_FAILURE));
+ EXPECT_STREQ("CLIENT_NONCE_INVALID_TIME_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ CLIENT_NONCE_INVALID_TIME_FAILURE));
+ EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT",
+ CryptoUtils::HandshakeFailureReasonToString(
+ CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT));
+ EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ CLIENT_NONCE_STRIKE_REGISTER_FAILURE));
+ EXPECT_STREQ("SERVER_NONCE_DECRYPTION_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SERVER_NONCE_DECRYPTION_FAILURE));
+ EXPECT_STREQ("SERVER_NONCE_INVALID_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SERVER_NONCE_INVALID_FAILURE));
+ EXPECT_STREQ("SERVER_NONCE_NOT_UNIQUE_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SERVER_NONCE_NOT_UNIQUE_FAILURE));
+ EXPECT_STREQ("SERVER_NONCE_INVALID_TIME_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SERVER_NONCE_INVALID_TIME_FAILURE));
+ EXPECT_STREQ("SERVER_NONCE_REQUIRED_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SERVER_NONCE_REQUIRED_FAILURE));
+ EXPECT_STREQ("SERVER_CONFIG_INCHOATE_HELLO_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE));
+ EXPECT_STREQ("SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE));
+ EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_INVALID_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SOURCE_ADDRESS_TOKEN_INVALID_FAILURE));
+ EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE));
+ EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_PARSE_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SOURCE_ADDRESS_TOKEN_PARSE_FAILURE));
+ EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE));
+ EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE));
+ EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE));
+ EXPECT_STREQ("INVALID_EXPECTED_LEAF_CERTIFICATE",
+ CryptoUtils::HandshakeFailureReasonToString(
+ INVALID_EXPECTED_LEAF_CERTIFICATE));
+ EXPECT_STREQ("MAX_FAILURE_REASON",
+ CryptoUtils::HandshakeFailureReasonToString(MAX_FAILURE_REASON));
+ EXPECT_STREQ(
+ "INVALID_HANDSHAKE_FAILURE_REASON",
+ CryptoUtils::HandshakeFailureReasonToString(
+ static_cast<HandshakeFailureReason>(MAX_FAILURE_REASON + 1)));
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/crypto/curve25519_key_exchange.cc b/chromium/net/quic/crypto/curve25519_key_exchange.cc
index f3d39e76001..cf97addb50a 100644
--- a/chromium/net/quic/crypto/curve25519_key_exchange.cc
+++ b/chromium/net/quic/crypto/curve25519_key_exchange.cc
@@ -4,7 +4,6 @@
#include "net/quic/crypto/curve25519_key_exchange.h"
-#include "base/basictypes.h"
#include "base/logging.h"
#include "crypto/curve25519.h"
#include "net/quic/crypto/quic_random.h"
@@ -43,7 +42,7 @@ Curve25519KeyExchange* Curve25519KeyExchange::New(
// static
string Curve25519KeyExchange::NewPrivateKey(QuicRandom* rand) {
- uint8 private_key[crypto::curve25519::kScalarBytes];
+ uint8_t private_key[crypto::curve25519::kScalarBytes];
rand->RandBytes(private_key, sizeof(private_key));
// This makes |private_key| a valid scalar, as specified on
@@ -66,11 +65,12 @@ bool Curve25519KeyExchange::CalculateSharedKey(
return false;
}
- uint8 result[crypto::curve25519::kBytes];
- crypto::curve25519::ScalarMult(
- private_key_,
- reinterpret_cast<const uint8*>(peer_public_value.data()),
- result);
+ uint8_t result[crypto::curve25519::kBytes];
+ if (!crypto::curve25519::ScalarMult(
+ private_key_,
+ reinterpret_cast<const uint8_t*>(peer_public_value.data()), result)) {
+ return false;
+ }
out_result->assign(reinterpret_cast<char*>(result), sizeof(result));
return true;
@@ -81,6 +81,8 @@ StringPiece Curve25519KeyExchange::public_value() const {
sizeof(public_key_));
}
-QuicTag Curve25519KeyExchange::tag() const { return kC255; }
+QuicTag Curve25519KeyExchange::tag() const {
+ return kC255;
+}
} // namespace net
diff --git a/chromium/net/quic/crypto/curve25519_key_exchange.h b/chromium/net/quic/crypto/curve25519_key_exchange.h
index cdb6d1a2c4f..1637bbb481d 100644
--- a/chromium/net/quic/crypto/curve25519_key_exchange.h
+++ b/chromium/net/quic/crypto/curve25519_key_exchange.h
@@ -5,6 +5,8 @@
#ifndef NET_QUIC_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
#define NET_QUIC_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
+#include <stdint.h>
+
#include <string>
#include "base/compiler_specific.h"
@@ -40,8 +42,8 @@ class NET_EXPORT_PRIVATE Curve25519KeyExchange : public KeyExchange {
private:
Curve25519KeyExchange();
- uint8 private_key_[32];
- uint8 public_key_[32];
+ uint8_t private_key_[32];
+ uint8_t public_key_[32];
};
} // namespace net
diff --git a/chromium/net/quic/crypto/local_strike_register_client.cc b/chromium/net/quic/crypto/local_strike_register_client.cc
index 71d222448f1..1d009a947e1 100644
--- a/chromium/net/quic/crypto/local_strike_register_client.cc
+++ b/chromium/net/quic/crypto/local_strike_register_client.cc
@@ -13,13 +13,15 @@ namespace net {
LocalStrikeRegisterClient::LocalStrikeRegisterClient(
unsigned max_entries,
- uint32 current_time_external,
- uint32 window_secs,
- const uint8 orbit[8],
+ uint32_t current_time_external,
+ uint32_t window_secs,
+ const uint8_t orbit[8],
StrikeRegister::StartupType startup)
- : strike_register_(max_entries, current_time_external, window_secs,
- orbit, startup) {
-}
+ : strike_register_(max_entries,
+ current_time_external,
+ window_secs,
+ orbit,
+ startup) {}
bool LocalStrikeRegisterClient::IsKnownOrbit(StringPiece orbit) const {
base::AutoLock lock(m_);
@@ -38,9 +40,9 @@ void LocalStrikeRegisterClient::VerifyNonceIsValidAndUnique(
nonce_error = NONCE_INVALID_FAILURE;
} else {
base::AutoLock lock(m_);
- nonce_error = strike_register_.Insert(
- reinterpret_cast<const uint8*>(nonce.data()),
- static_cast<uint32>(now.ToUNIXSeconds()));
+ nonce_error =
+ strike_register_.Insert(reinterpret_cast<const uint8_t*>(nonce.data()),
+ static_cast<uint32_t>(now.ToUNIXSeconds()));
}
// m_ must not be held when the ResultCallback runs.
diff --git a/chromium/net/quic/crypto/local_strike_register_client.h b/chromium/net/quic/crypto/local_strike_register_client.h
index 5f576e99d38..8e10497efb6 100644
--- a/chromium/net/quic/crypto/local_strike_register_client.h
+++ b/chromium/net/quic/crypto/local_strike_register_client.h
@@ -5,7 +5,9 @@
#ifndef NET_QUIC_CRYPTO_LOCAL_STRIKE_REGISTER_CLIENT_H_
#define NET_QUIC_CRYPTO_LOCAL_STRIKE_REGISTER_CLIENT_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"
#include "net/base/net_export.h"
@@ -21,9 +23,9 @@ class NET_EXPORT_PRIVATE LocalStrikeRegisterClient
: public StrikeRegisterClient {
public:
LocalStrikeRegisterClient(unsigned max_entries,
- uint32 current_time_external,
- uint32 window_secs,
- const uint8 orbit[8],
+ uint32_t current_time_external,
+ uint32_t window_secs,
+ const uint8_t orbit[8],
StrikeRegister::StartupType startup);
bool IsKnownOrbit(base::StringPiece orbit) const override;
diff --git a/chromium/net/quic/crypto/local_strike_register_client_test.cc b/chromium/net/quic/crypto/local_strike_register_client_test.cc
index 5665cb6b234..74bf095fb04 100644
--- a/chromium/net/quic/crypto/local_strike_register_client_test.cc
+++ b/chromium/net/quic/crypto/local_strike_register_client_test.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "base/sys_byteorder.h"
@@ -50,15 +51,14 @@ class RecordResultCallback : public StrikeRegisterClient::ResultCallback {
DISALLOW_COPY_AND_ASSIGN(RecordResultCallback);
};
-const uint8 kOrbit[] = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0";
-const uint32 kCurrentTimeExternalSecs = 12345678;
+const uint8_t kOrbit[] = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0";
+const uint32_t kCurrentTimeExternalSecs = 12345678;
size_t kMaxEntries = 100;
-uint32 kWindowSecs = 60;
+uint32_t kWindowSecs = 60;
class LocalStrikeRegisterClientTest : public ::testing::Test {
protected:
- LocalStrikeRegisterClientTest() {
- }
+ LocalStrikeRegisterClientTest() {}
void SetUp() override {
strike_register_.reset(new LocalStrikeRegisterClient(
@@ -82,7 +82,7 @@ TEST_F(LocalStrikeRegisterClientTest, CheckOrbit) {
TEST_F(LocalStrikeRegisterClientTest, IncorrectNonceLength) {
string valid_nonce;
- uint32 norder = htonl(kCurrentTimeExternalSecs);
+ uint32_t norder = htonl(kCurrentTimeExternalSecs);
valid_nonce.assign(reinterpret_cast<const char*>(&norder), sizeof(norder));
valid_nonce.append(string(reinterpret_cast<const char*>(kOrbit), kOrbitSize));
valid_nonce.append(string(20, '\x17')); // 20 'random' bytes.
@@ -94,8 +94,7 @@ TEST_F(LocalStrikeRegisterClientTest, IncorrectNonceLength) {
InsertStatus nonce_error = NONCE_UNKNOWN_FAILURE;
string short_nonce = valid_nonce.substr(0, valid_nonce.length() - 1);
strike_register_->VerifyNonceIsValidAndUnique(
- short_nonce,
- QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
+ short_nonce, QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
new RecordResultCallback(&called, &is_valid, &nonce_error));
EXPECT_TRUE(called);
EXPECT_FALSE(is_valid);
@@ -110,8 +109,7 @@ TEST_F(LocalStrikeRegisterClientTest, IncorrectNonceLength) {
string long_nonce(valid_nonce);
long_nonce.append("a");
strike_register_->VerifyNonceIsValidAndUnique(
- long_nonce,
- QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
+ long_nonce, QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
new RecordResultCallback(&called, &is_valid, &nonce_error));
EXPECT_TRUE(called);
EXPECT_FALSE(is_valid);
@@ -124,8 +122,7 @@ TEST_F(LocalStrikeRegisterClientTest, IncorrectNonceLength) {
bool is_valid = false;
InsertStatus nonce_error = NONCE_UNKNOWN_FAILURE;
strike_register_->VerifyNonceIsValidAndUnique(
- valid_nonce,
- QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
+ valid_nonce, QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
new RecordResultCallback(&called, &is_valid, &nonce_error));
EXPECT_TRUE(called);
EXPECT_TRUE(is_valid);
diff --git a/chromium/net/quic/crypto/null_decrypter.cc b/chromium/net/quic/crypto/null_decrypter.cc
index cad2f7e2d28..67709c3d51c 100644
--- a/chromium/net/quic/crypto/null_decrypter.cc
+++ b/chromium/net/quic/crypto/null_decrypter.cc
@@ -6,8 +6,8 @@
#include <stdint.h>
-#include "net/quic/quic_utils.h"
#include "net/quic/quic_data_reader.h"
+#include "net/quic/quic_utils.h"
using base::StringPiece;
using std::string;
@@ -16,7 +16,9 @@ namespace net {
NullDecrypter::NullDecrypter() {}
-bool NullDecrypter::SetKey(StringPiece key) { return key.empty(); }
+bool NullDecrypter::SetKey(StringPiece key) {
+ return key.empty();
+}
bool NullDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
return nonce_prefix.empty();
@@ -49,23 +51,26 @@ bool NullDecrypter::DecryptPacket(QuicPacketNumber /*packet_number*/,
return true;
}
-StringPiece NullDecrypter::GetKey() const { return StringPiece(); }
+StringPiece NullDecrypter::GetKey() const {
+ return StringPiece();
+}
-StringPiece NullDecrypter::GetNoncePrefix() const { return StringPiece(); }
+StringPiece NullDecrypter::GetNoncePrefix() const {
+ return StringPiece();
+}
const char* NullDecrypter::cipher_name() const {
return "NULL";
}
-uint32 NullDecrypter::cipher_id() const {
+uint32_t NullDecrypter::cipher_id() const {
return 0;
}
bool NullDecrypter::ReadHash(QuicDataReader* reader, uint128* hash) {
- uint64 lo;
- uint32 hi;
- if (!reader->ReadUInt64(&lo) ||
- !reader->ReadUInt32(&hi)) {
+ uint64_t lo;
+ uint32_t hi;
+ if (!reader->ReadUInt64(&lo) || !reader->ReadUInt32(&hi)) {
return false;
}
*hash = hi;
@@ -74,8 +79,8 @@ bool NullDecrypter::ReadHash(QuicDataReader* reader, uint128* hash) {
return true;
}
-uint128 NullDecrypter::ComputeHash(const StringPiece& data1,
- const StringPiece& data2) const {
+uint128 NullDecrypter::ComputeHash(const StringPiece data1,
+ const StringPiece data2) const {
uint128 correct_hash = QuicUtils::FNV1a_128_Hash_Two(
data1.data(), data1.length(), data2.data(), data2.length());
uint128 mask(UINT64_C(0x0), UINT64_C(0xffffffff));
diff --git a/chromium/net/quic/crypto/null_decrypter.h b/chromium/net/quic/crypto/null_decrypter.h
index 414d2a16f8a..64a6a19b20a 100644
--- a/chromium/net/quic/crypto/null_decrypter.h
+++ b/chromium/net/quic/crypto/null_decrypter.h
@@ -5,7 +5,11 @@
#ifndef NET_QUIC_CRYPTO_NULL_DECRYPTER_H_
#define NET_QUIC_CRYPTO_NULL_DECRYPTER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/crypto/quic_decrypter.h"
@@ -34,12 +38,12 @@ class NET_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
base::StringPiece GetNoncePrefix() const override;
const char* cipher_name() const override;
- uint32 cipher_id() const override;
+ uint32_t cipher_id() const override;
private:
bool ReadHash(QuicDataReader* reader, uint128* hash);
- uint128 ComputeHash(const base::StringPiece& data1,
- const base::StringPiece& data2) const;
+ uint128 ComputeHash(const base::StringPiece data1,
+ const base::StringPiece data2) const;
DISALLOW_COPY_AND_ASSIGN(NullDecrypter);
};
diff --git a/chromium/net/quic/crypto/null_decrypter_test.cc b/chromium/net/quic/crypto/null_decrypter_test.cc
index 4c8bae4ff5f..4e533755357 100644
--- a/chromium/net/quic/crypto/null_decrypter_test.cc
+++ b/chromium/net/quic/crypto/null_decrypter_test.cc
@@ -10,18 +10,14 @@ using base::StringPiece;
namespace net {
namespace test {
-class NullDecrypterTest : public ::testing::TestWithParam<bool> {
-};
+class NullDecrypterTest : public ::testing::TestWithParam<bool> {};
TEST_F(NullDecrypterTest, Decrypt) {
unsigned char expected[] = {
- // fnv hash
- 0xa0, 0x6f, 0x44, 0x8a,
- 0x44, 0xf8, 0x18, 0x3b,
- 0x47, 0x91, 0xb2, 0x13,
- // payload
- 'g', 'o', 'o', 'd',
- 'b', 'y', 'e', '!',
+ // fnv hash
+ 0xa0, 0x6f, 0x44, 0x8a, 0x44, 0xf8, 0x18, 0x3b, 0x47, 0x91, 0xb2, 0x13,
+ // payload
+ 'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
const char* data = reinterpret_cast<const char*>(expected);
size_t len = arraysize(expected);
@@ -36,13 +32,10 @@ TEST_F(NullDecrypterTest, Decrypt) {
TEST_F(NullDecrypterTest, BadHash) {
unsigned char expected[] = {
- // fnv hash
- 0x46, 0x11, 0xea, 0x5f,
- 0xcf, 0x1d, 0x66, 0x5b,
- 0xba, 0xf0, 0xbc, 0xfd,
- // payload
- 'g', 'o', 'o', 'd',
- 'b', 'y', 'e', '!',
+ // fnv hash
+ 0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc, 0xfd,
+ // payload
+ 'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
const char* data = reinterpret_cast<const char*>(expected);
size_t len = arraysize(expected);
@@ -55,10 +48,8 @@ TEST_F(NullDecrypterTest, BadHash) {
TEST_F(NullDecrypterTest, ShortInput) {
unsigned char expected[] = {
- // fnv hash (truncated)
- 0x46, 0x11, 0xea, 0x5f,
- 0xcf, 0x1d, 0x66, 0x5b,
- 0xba, 0xf0, 0xbc,
+ // fnv hash (truncated)
+ 0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc,
};
const char* data = reinterpret_cast<const char*>(expected);
size_t len = arraysize(expected);
diff --git a/chromium/net/quic/crypto/null_encrypter.cc b/chromium/net/quic/crypto/null_encrypter.cc
index 5606c9917ea..470674b1e5c 100644
--- a/chromium/net/quic/crypto/null_encrypter.cc
+++ b/chromium/net/quic/crypto/null_encrypter.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "net/quic/crypto/null_encrypter.h"
+
#include "net/quic/quic_data_writer.h"
#include "net/quic/quic_utils.h"
@@ -15,7 +16,9 @@ const size_t kHashSizeShort = 12; // size of uint128 serialized short
NullEncrypter::NullEncrypter() {}
-bool NullEncrypter::SetKey(StringPiece key) { return key.empty(); }
+bool NullEncrypter::SetKey(StringPiece key) {
+ return key.empty();
+}
bool NullEncrypter::SetNoncePrefix(StringPiece nonce_prefix) {
return nonce_prefix.empty();
@@ -34,16 +37,22 @@ bool NullEncrypter::EncryptPacket(QuicPacketNumber /*packet_number*/,
uint128 hash = QuicUtils::FNV1a_128_Hash_Two(
associated_data.data(), associated_data.size(), plaintext.data(),
plaintext.size());
+ // TODO(ianswett): memmove required for in place encryption. Placing the
+ // hash at the end would allow use of memcpy, doing nothing for in place.
+ memmove(output + GetHashLength(), plaintext.data(), plaintext.length());
QuicUtils::SerializeUint128Short(hash,
reinterpret_cast<unsigned char*>(output));
- memcpy(output + GetHashLength(), plaintext.data(), plaintext.length());
*output_length = len;
return true;
}
-size_t NullEncrypter::GetKeySize() const { return 0; }
+size_t NullEncrypter::GetKeySize() const {
+ return 0;
+}
-size_t NullEncrypter::GetNoncePrefixSize() const { return 0; }
+size_t NullEncrypter::GetNoncePrefixSize() const {
+ return 0;
+}
size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
return ciphertext_size - GetHashLength();
@@ -53,9 +62,13 @@ size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const {
return plaintext_size + GetHashLength();
}
-StringPiece NullEncrypter::GetKey() const { return StringPiece(); }
+StringPiece NullEncrypter::GetKey() const {
+ return StringPiece();
+}
-StringPiece NullEncrypter::GetNoncePrefix() const { return StringPiece(); }
+StringPiece NullEncrypter::GetNoncePrefix() const {
+ return StringPiece();
+}
size_t NullEncrypter::GetHashLength() const {
return kHashSizeShort;
diff --git a/chromium/net/quic/crypto/null_encrypter.h b/chromium/net/quic/crypto/null_encrypter.h
index f9a54a006c7..c07495e7b51 100644
--- a/chromium/net/quic/crypto/null_encrypter.h
+++ b/chromium/net/quic/crypto/null_encrypter.h
@@ -5,7 +5,10 @@
#ifndef NET_QUIC_CRYPTO_NULL_ENCRYPTER_H_
#define NET_QUIC_CRYPTO_NULL_ENCRYPTER_H_
+#include <stddef.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/crypto/quic_encrypter.h"
diff --git a/chromium/net/quic/crypto/null_encrypter_test.cc b/chromium/net/quic/crypto/null_encrypter_test.cc
index e9ae773e97a..02a2f73a0df 100644
--- a/chromium/net/quic/crypto/null_encrypter_test.cc
+++ b/chromium/net/quic/crypto/null_encrypter_test.cc
@@ -10,18 +10,14 @@ using base::StringPiece;
namespace net {
namespace test {
-class NullEncrypterTest : public ::testing::TestWithParam<bool> {
-};
+class NullEncrypterTest : public ::testing::TestWithParam<bool> {};
TEST_F(NullEncrypterTest, Encrypt) {
unsigned char expected[] = {
- // fnv hash
- 0xa0, 0x6f, 0x44, 0x8a,
- 0x44, 0xf8, 0x18, 0x3b,
- 0x47, 0x91, 0xb2, 0x13,
- // payload
- 'g', 'o', 'o', 'd',
- 'b', 'y', 'e', '!',
+ // fnv hash
+ 0xa0, 0x6f, 0x44, 0x8a, 0x44, 0xf8, 0x18, 0x3b, 0x47, 0x91, 0xb2, 0x13,
+ // payload
+ 'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
NullEncrypter encrypter;
char encrypted[256];
diff --git a/chromium/net/quic/crypto/p256_key_exchange.h b/chromium/net/quic/crypto/p256_key_exchange.h
index 9e22a335df8..e6855aa31a5 100644
--- a/chromium/net/quic/crypto/p256_key_exchange.h
+++ b/chromium/net/quic/crypto/p256_key_exchange.h
@@ -5,8 +5,11 @@
#ifndef NET_QUIC_CRYPTO_P256_KEY_EXCHANGE_H_
#define NET_QUIC_CRYPTO_P256_KEY_EXCHANGE_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -59,18 +62,18 @@ class NET_EXPORT_PRIVATE P256KeyExchange : public KeyExchange {
#if defined(USE_OPENSSL)
// P256KeyExchange takes ownership of |private_key|, and expects
// |public_key| consists of |kUncompressedP256PointBytes| bytes.
- P256KeyExchange(EC_KEY* private_key, const uint8* public_key);
+ P256KeyExchange(EC_KEY* private_key, const uint8_t* public_key);
crypto::ScopedEC_KEY private_key_;
#else
// P256KeyExchange takes ownership of |key_pair|, and expects
// |public_key| consists of |kUncompressedP256PointBytes| bytes.
- P256KeyExchange(crypto::ECPrivateKey* key_pair, const uint8* public_key);
+ P256KeyExchange(crypto::ECPrivateKey* key_pair, const uint8_t* public_key);
scoped_ptr<crypto::ECPrivateKey> key_pair_;
#endif
// The public key stored as an uncompressed P-256 point.
- uint8 public_key_[kUncompressedP256PointBytes];
+ uint8_t public_key_[kUncompressedP256PointBytes];
DISALLOW_COPY_AND_ASSIGN(P256KeyExchange);
};
diff --git a/chromium/net/quic/crypto/p256_key_exchange_nss.cc b/chromium/net/quic/crypto/p256_key_exchange_nss.cc
index 3296a6f566b..576825f96f3 100644
--- a/chromium/net/quic/crypto/p256_key_exchange_nss.cc
+++ b/chromium/net/quic/crypto/p256_key_exchange_nss.cc
@@ -22,21 +22,20 @@ namespace {
// use the same approach.
const char kExportPassword[] = "";
-// Convert StringPiece to vector of uint8.
-static vector<uint8> StringPieceToVector(StringPiece piece) {
- return vector<uint8>(piece.data(), piece.data() + piece.length());
+// Convert StringPiece to vector of uint8_t.
+static vector<uint8_t> StringPieceToVector(StringPiece piece) {
+ return vector<uint8_t>(piece.data(), piece.data() + piece.length());
}
} // namespace
P256KeyExchange::P256KeyExchange(crypto::ECPrivateKey* key_pair,
- const uint8* public_key)
+ const uint8_t* public_key)
: key_pair_(key_pair) {
memcpy(public_key_, public_key, sizeof(public_key_));
}
-P256KeyExchange::~P256KeyExchange() {
-}
+P256KeyExchange::~P256KeyExchange() {}
// static
P256KeyExchange* P256KeyExchange::New(StringPiece key) {
@@ -45,9 +44,9 @@ P256KeyExchange* P256KeyExchange::New(StringPiece key) {
return nullptr;
}
- const uint8* data = reinterpret_cast<const uint8*>(key.data());
- size_t size = static_cast<size_t>(data[0]) |
- (static_cast<size_t>(data[1]) << 8);
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(key.data());
+ size_t size =
+ static_cast<size_t>(data[0]) | (static_cast<size_t>(data[1]) << 8);
key.remove_prefix(2);
if (key.size() < size) {
DVLOG(1) << "Key pair does not contain key material.";
@@ -96,8 +95,8 @@ P256KeyExchange* P256KeyExchange::New(StringPiece key) {
!public_key->u.ec.DEREncodedParams.data ||
public_key->u.ec.DEREncodedParams.data[0] != SEC_ASN1_OBJECT_ID ||
public_key->u.ec.DEREncodedParams.data[1] != oid_data->oid.len ||
- memcmp(public_key->u.ec.DEREncodedParams.data + 2,
- oid_data->oid.data, oid_data->oid.len) != 0) {
+ memcmp(public_key->u.ec.DEREncodedParams.data + 2, oid_data->oid.data,
+ oid_data->oid.len) != 0) {
DVLOG(1) << "Key is invalid.";
}
@@ -114,9 +113,8 @@ string P256KeyExchange::NewPrivateKey() {
return string();
}
- vector<uint8> private_key;
- if (!key_pair->ExportEncryptedPrivateKey(kExportPassword,
- 1 /* iteration */,
+ vector<uint8_t> private_key;
+ if (!key_pair->ExportEncryptedPrivateKey(kExportPassword, 1 /* iteration */,
&private_key)) {
DVLOG(1) << "Can't export private key.";
return string();
@@ -125,17 +123,16 @@ string P256KeyExchange::NewPrivateKey() {
// NSS lacks the ability to import an ECC private key without
// also importing the public key, so it is necessary to also
// store the public key.
- vector<uint8> public_key;
+ vector<uint8_t> public_key;
if (!key_pair->ExportPublicKey(&public_key)) {
DVLOG(1) << "Can't export public key.";
return string();
}
// TODO(thaidn): determine how large encrypted private key can be
- uint16 private_key_size = base::checked_cast<uint16>(private_key.size());
- const size_t result_size = sizeof(private_key_size) +
- private_key_size +
- public_key.size();
+ uint16_t private_key_size = base::checked_cast<uint16_t>(private_key.size());
+ const size_t result_size =
+ sizeof(private_key_size) + private_key_size + public_key.size();
vector<char> result(result_size);
char* resultp = &result[0];
// Export the key string.
@@ -179,7 +176,7 @@ bool P256KeyExchange::CalculateSharedKey(const StringPiece& peer_public_value,
peer_public_key.u.ec.publicValue.type = siBuffer;
peer_public_key.u.ec.publicValue.data =
- reinterpret_cast<uint8*>(const_cast<char*>(peer_public_value.data()));
+ reinterpret_cast<uint8_t*>(const_cast<char*>(peer_public_value.data()));
peer_public_key.u.ec.publicValue.len = peer_public_value.size();
// The NSS function performing ECDH key exchange is PK11_PubDeriveWithKDF.
@@ -189,19 +186,11 @@ bool P256KeyExchange::CalculateSharedKey(const StringPiece& peer_public_value,
// |CalculateSharedKey| is the actual ECDH shared key, not any derived keys
// from it.
crypto::ScopedPK11SymKey premaster_secret(
- PK11_PubDeriveWithKDF(
- key_pair_->key(),
- &peer_public_key,
- PR_FALSE,
- nullptr,
- nullptr,
- CKM_ECDH1_DERIVE, /* mechanism */
- CKM_GENERIC_SECRET_KEY_GEN, /* target */
- CKA_DERIVE,
- 0,
- CKD_NULL, /* kdf */
- nullptr,
- nullptr));
+ PK11_PubDeriveWithKDF(key_pair_->key(), &peer_public_key, PR_FALSE,
+ nullptr, nullptr, CKM_ECDH1_DERIVE, /* mechanism */
+ CKM_GENERIC_SECRET_KEY_GEN, /* target */
+ CKA_DERIVE, 0, CKD_NULL, /* kdf */
+ nullptr, nullptr));
if (!premaster_secret.get()) {
DVLOG(1) << "Can't derive ECDH shared key.";
@@ -228,6 +217,8 @@ StringPiece P256KeyExchange::public_value() const {
sizeof(public_key_));
}
-QuicTag P256KeyExchange::tag() const { return kP256; }
+QuicTag P256KeyExchange::tag() const {
+ return kP256;
+}
} // namespace net
diff --git a/chromium/net/quic/crypto/p256_key_exchange_openssl.cc b/chromium/net/quic/crypto/p256_key_exchange_openssl.cc
index 88d45c8e4a2..7a9707e308d 100644
--- a/chromium/net/quic/crypto/p256_key_exchange_openssl.cc
+++ b/chromium/net/quic/crypto/p256_key_exchange_openssl.cc
@@ -15,7 +15,7 @@ using std::string;
namespace net {
-P256KeyExchange::P256KeyExchange(EC_KEY* private_key, const uint8* public_key)
+P256KeyExchange::P256KeyExchange(EC_KEY* private_key, const uint8_t* public_key)
: private_key_(private_key) {
memcpy(public_key_, public_key, sizeof(public_key_));
}
@@ -29,15 +29,15 @@ P256KeyExchange* P256KeyExchange::New(StringPiece key) {
return nullptr;
}
- const uint8* keyp = reinterpret_cast<const uint8*>(key.data());
- crypto::ScopedEC_KEY private_key(d2i_ECPrivateKey(nullptr, &keyp,
- key.size()));
+ const uint8_t* keyp = reinterpret_cast<const uint8_t*>(key.data());
+ crypto::ScopedEC_KEY private_key(
+ d2i_ECPrivateKey(nullptr, &keyp, key.size()));
if (!private_key.get() || !EC_KEY_check_key(private_key.get())) {
DVLOG(1) << "Private key is invalid.";
return nullptr;
}
- uint8 public_key[kUncompressedP256PointBytes];
+ uint8_t public_key[kUncompressedP256PointBytes];
if (EC_POINT_point2oct(EC_KEY_get0_group(private_key.get()),
EC_KEY_get0_public_key(private_key.get()),
POINT_CONVERSION_UNCOMPRESSED, public_key,
@@ -62,8 +62,8 @@ string P256KeyExchange::NewPrivateKey() {
DVLOG(1) << "Can't convert private key to string";
return string();
}
- scoped_ptr<uint8[]> private_key(new uint8[key_len]);
- uint8* keyp = private_key.get();
+ scoped_ptr<uint8_t[]> private_key(new uint8_t[key_len]);
+ uint8_t* keyp = private_key.get();
if (!i2d_ECPrivateKey(key.get(), &keyp)) {
DVLOG(1) << "Can't convert private key to string.";
return string();
@@ -89,14 +89,14 @@ bool P256KeyExchange::CalculateSharedKey(const StringPiece& peer_public_value,
if (!point ||
!EC_POINT_oct2point(/* also test if point is on curve */
EC_KEY_get0_group(private_key_.get()), point.get(),
- reinterpret_cast<const uint8*>(
+ reinterpret_cast<const uint8_t*>(
peer_public_value.data()),
peer_public_value.size(), nullptr)) {
DVLOG(1) << "Can't convert peer public value to curve point.";
return false;
}
- uint8 result[kP256FieldBytes];
+ uint8_t result[kP256FieldBytes];
if (ECDH_compute_key(result, sizeof(result), point.get(), private_key_.get(),
nullptr) != sizeof(result)) {
DVLOG(1) << "Can't compute ECDH shared key.";
@@ -112,6 +112,8 @@ StringPiece P256KeyExchange::public_value() const {
sizeof(public_key_));
}
-QuicTag P256KeyExchange::tag() const { return kP256; }
+QuicTag P256KeyExchange::tag() const {
+ return kP256;
+}
} // namespace net
diff --git a/chromium/net/quic/crypto/p256_key_exchange_test.cc b/chromium/net/quic/crypto/p256_key_exchange_test.cc
index 54c99a0324a..4052c2dae2b 100644
--- a/chromium/net/quic/crypto/p256_key_exchange_test.cc
+++ b/chromium/net/quic/crypto/p256_key_exchange_test.cc
@@ -41,4 +41,3 @@ TEST(P256KeyExchange, SharedKey) {
} // namespace test
} // namespace net
-
diff --git a/chromium/net/quic/crypto/proof_source.h b/chromium/net/quic/crypto/proof_source.h
index f6eac21364d..235b972b898 100644
--- a/chromium/net/quic/crypto/proof_source.h
+++ b/chromium/net/quic/crypto/proof_source.h
@@ -8,8 +8,8 @@
#include <string>
#include <vector>
+#include "net/base/ip_address_number.h"
#include "net/base/net_export.h"
-#include "net/base/net_util.h"
namespace net {
@@ -45,13 +45,16 @@ class NET_EXPORT_PRIVATE ProofSource {
// |hostname| may be empty to signify that a default certificate should be
// used.
//
+ // |out_leaf_cert_sct| points to the signed timestamp (RFC6962) of the leaf
+ // cert.
// This function may be called concurrently.
virtual bool GetProof(const IPAddressNumber& server_ip,
const std::string& hostname,
const std::string& server_config,
bool ecdsa_ok,
const std::vector<std::string>** out_certs,
- std::string* out_signature) = 0;
+ std::string* out_signature,
+ std::string* out_leaf_cert_sct) = 0;
};
} // namespace net
diff --git a/chromium/net/quic/crypto/proof_source_chromium.h b/chromium/net/quic/crypto/proof_source_chromium.h
index ef5e6768c34..cfed05f4185 100644
--- a/chromium/net/quic/crypto/proof_source_chromium.h
+++ b/chromium/net/quic/crypto/proof_source_chromium.h
@@ -8,9 +8,9 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "crypto/rsa_private_key.h"
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
@@ -26,9 +26,11 @@ class NET_EXPORT_PRIVATE ProofSourceChromium : public ProofSource {
~ProofSourceChromium() override;
// Initializes this object based on the certificate chain in |cert_path|,
- // and the PKCS#8 RSA private key in |key_path|.
+ // and the PKCS#8 RSA private key in |key_path|. Signed certificate
+ // timestamp may be loaded from |sct_path| if it is non-empty.
bool Initialize(const base::FilePath& cert_path,
- const base::FilePath& key_path);
+ const base::FilePath& key_path,
+ const base::FilePath& sct_path);
// ProofSource interface
bool GetProof(const IPAddressNumber& server_ip,
@@ -36,11 +38,13 @@ class NET_EXPORT_PRIVATE ProofSourceChromium : public ProofSource {
const std::string& server_config,
bool ecdsa_ok,
const std::vector<std::string>** out_certs,
- std::string* out_signature) override;
+ std::string* out_signature,
+ std::string* out_leaf_cert_sct) override;
private:
scoped_ptr<crypto::RSAPrivateKey> private_key_;
std::vector<std::string> certificates_;
+ std::string signed_certificate_timestamp_;
DISALLOW_COPY_AND_ASSIGN(ProofSourceChromium);
};
diff --git a/chromium/net/quic/crypto/proof_source_chromium_nss.cc b/chromium/net/quic/crypto/proof_source_chromium_nss.cc
index f73a6ac0a42..407089a87b9 100644
--- a/chromium/net/quic/crypto/proof_source_chromium_nss.cc
+++ b/chromium/net/quic/crypto/proof_source_chromium_nss.cc
@@ -14,7 +14,8 @@ ProofSourceChromium::ProofSourceChromium() {}
ProofSourceChromium::~ProofSourceChromium() {}
bool ProofSourceChromium::Initialize(const base::FilePath& cert_path,
- const base::FilePath& key_path) {
+ const base::FilePath& key_path,
+ const base::FilePath& sct_path) {
return false;
}
@@ -23,7 +24,8 @@ bool ProofSourceChromium::GetProof(const IPAddressNumber& server_ip,
const string& server_config,
bool ecdsa_ok,
const vector<string>** out_certs,
- string* out_signature) {
+ string* out_signature,
+ string* out_leaf_cert_sct) {
return false;
}
diff --git a/chromium/net/quic/crypto/proof_source_chromium_openssl.cc b/chromium/net/quic/crypto/proof_source_chromium_openssl.cc
index e122687dc93..ec0bdea9d56 100644
--- a/chromium/net/quic/crypto/proof_source_chromium_openssl.cc
+++ b/chromium/net/quic/crypto/proof_source_chromium_openssl.cc
@@ -23,7 +23,8 @@ ProofSourceChromium::ProofSourceChromium() {}
ProofSourceChromium::~ProofSourceChromium() {}
bool ProofSourceChromium::Initialize(const base::FilePath& cert_path,
- const base::FilePath& key_path) {
+ const base::FilePath& key_path,
+ const base::FilePath& sct_path) {
crypto::EnsureOpenSSLInit();
std::string cert_data;
@@ -63,6 +64,16 @@ bool ProofSourceChromium::Initialize(const base::FilePath& cert_path,
DLOG(FATAL) << "Unable to create private key.";
return false;
}
+
+ // Loading of the signed certificate timestamp is optional.
+ if (sct_path.empty())
+ return true;
+
+ if (!base::ReadFileToString(sct_path, &signed_certificate_timestamp_)) {
+ DLOG(FATAL) << "Unable to read signed certificate timestamp.";
+ return false;
+ }
+
return true;
}
@@ -71,7 +82,8 @@ bool ProofSourceChromium::GetProof(const IPAddressNumber& server_ip,
const string& server_config,
bool ecdsa_ok,
const vector<string>** out_certs,
- string* out_signature) {
+ string* out_signature,
+ string* out_leaf_cert_sct) {
DCHECK(private_key_.get()) << " this: " << this;
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
@@ -81,12 +93,14 @@ bool ProofSourceChromium::GetProof(const IPAddressNumber& server_ip,
private_key_->key()) ||
!EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
!EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) ||
- !EVP_DigestSignUpdate(sign_context.get(), reinterpret_cast<const uint8*>(
- kProofSignatureLabel),
- sizeof(kProofSignatureLabel)) ||
- !EVP_DigestSignUpdate(sign_context.get(), reinterpret_cast<const uint8*>(
- server_config.data()),
- server_config.size())) {
+ !EVP_DigestSignUpdate(
+ sign_context.get(),
+ reinterpret_cast<const uint8_t*>(kProofSignatureLabel),
+ sizeof(kProofSignatureLabel)) ||
+ !EVP_DigestSignUpdate(
+ sign_context.get(),
+ reinterpret_cast<const uint8_t*>(server_config.data()),
+ server_config.size())) {
return false;
}
@@ -97,16 +111,16 @@ bool ProofSourceChromium::GetProof(const IPAddressNumber& server_ip,
}
std::vector<uint8_t> signature(len);
// Sign it.
- if (!EVP_DigestSignFinal(sign_context.get(), vector_as_array(&signature),
- &len)) {
+ if (!EVP_DigestSignFinal(sign_context.get(), signature.data(), &len)) {
return false;
}
signature.resize(len);
- out_signature->assign(reinterpret_cast<const char*>(&signature[0]),
+ out_signature->assign(reinterpret_cast<const char*>(signature.data()),
signature.size());
*out_certs = &certificates_;
VLOG(1) << "signature: "
<< base::HexEncode(out_signature->data(), out_signature->size());
+ *out_leaf_cert_sct = signed_certificate_timestamp_;
return true;
}
diff --git a/chromium/net/quic/crypto/proof_test.cc b/chromium/net/quic/crypto/proof_test.cc
index b493f225fd6..3ee3781aa44 100644
--- a/chromium/net/quic/crypto/proof_test.cc
+++ b/chromium/net/quic/crypto/proof_test.cc
@@ -35,9 +35,7 @@ class TestProofVerifierCallback : public ProofVerifierCallback {
TestProofVerifierCallback(TestCompletionCallback* comp_callback,
bool* ok,
string* error_details)
- : comp_callback_(comp_callback),
- ok_(ok),
- error_details_(error_details) {}
+ : comp_callback_(comp_callback), ok_(ok), error_details_(error_details) {}
void Run(bool ok,
const string& error_details,
@@ -72,7 +70,7 @@ void RunVerification(ProofVerifier* verifier,
new TestProofVerifierCallback(&comp_callback, &ok, &error_details);
QuicAsyncStatus status = verifier->VerifyProof(
- hostname, server_config, certs, proof, verify_context.get(),
+ hostname, server_config, certs, "", proof, verify_context.get(),
&error_details, &details, callback);
switch (status) {
@@ -118,41 +116,40 @@ TEST(ProofTest, DISABLED_Verify) {
const string hostname = "test.example.com";
const vector<string>* certs;
const vector<string>* first_certs;
- string error_details, signature, first_signature;
+ string error_details, signature, first_signature, first_cert_sct, cert_sct;
IPAddressNumber server_ip;
ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config,
false /* no ECDSA */, &first_certs,
- &first_signature));
+ &first_signature, &first_cert_sct));
ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config,
- false /* no ECDSA */, &certs, &signature));
+ false /* no ECDSA */, &certs, &signature,
+ &cert_sct));
// Check that the proof source is caching correctly:
ASSERT_EQ(first_certs, certs);
ASSERT_EQ(signature, first_signature);
+ ASSERT_EQ(first_cert_sct, cert_sct);
- RunVerification(
- verifier.get(), hostname, server_config, *certs, signature, true);
+ RunVerification(verifier.get(), hostname, server_config, *certs, signature,
+ true);
- RunVerification(
- verifier.get(), "foo.com", server_config, *certs, signature, false);
+ RunVerification(verifier.get(), "foo.com", server_config, *certs, signature,
+ false);
- RunVerification(
- verifier.get(), server_config.substr(1, string::npos), server_config,
- *certs, signature, false);
+ RunVerification(verifier.get(), server_config.substr(1, string::npos),
+ server_config, *certs, signature, false);
const string corrupt_signature = "1" + signature;
- RunVerification(
- verifier.get(), hostname, server_config, *certs, corrupt_signature,
- false);
+ RunVerification(verifier.get(), hostname, server_config, *certs,
+ corrupt_signature, false);
vector<string> wrong_certs;
for (size_t i = 1; i < certs->size(); i++) {
wrong_certs.push_back((*certs)[i]);
}
- RunVerification(
- verifier.get(), "foo.com", server_config, wrong_certs, corrupt_signature,
- false);
+ RunVerification(verifier.get(), "foo.com", server_config, wrong_certs,
+ corrupt_signature, false);
}
// A known answer test that allows us to test ProofVerifier without a working
@@ -161,80 +158,80 @@ TEST(ProofTest, VerifyRSAKnownAnswerTest) {
// These sample signatures were generated by running the Proof.Verify test
// and dumping the bytes of the |signature| output of ProofSource::GetProof().
static const unsigned char signature_data_0[] = {
- 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
- 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
- 0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
- 0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
- 0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
- 0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
- 0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
- 0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
- 0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
- 0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
- 0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
- 0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
- 0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
- 0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
- 0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
- 0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
- 0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
- 0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
- 0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
- 0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
- 0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
- 0xc4, 0x4b, 0x53, 0x54,
+ 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
+ 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
+ 0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
+ 0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
+ 0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
+ 0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
+ 0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
+ 0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
+ 0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
+ 0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
+ 0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
+ 0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
+ 0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
+ 0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
+ 0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
+ 0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
+ 0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
+ 0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
+ 0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
+ 0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
+ 0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
+ 0xc4, 0x4b, 0x53, 0x54,
};
static const unsigned char signature_data_1[] = {
- 0x01, 0x7b, 0x52, 0x35, 0xe3, 0x51, 0xdd, 0xf1, 0x67, 0x8d, 0x31, 0x5e,
- 0xa3, 0x75, 0x1f, 0x68, 0x6c, 0xdd, 0x41, 0x7a, 0x18, 0x25, 0xe0, 0x12,
- 0x6e, 0x84, 0x46, 0x5e, 0xb2, 0x98, 0xd7, 0x84, 0xe1, 0x62, 0xe0, 0xc1,
- 0xc4, 0xd7, 0x4f, 0x4f, 0x80, 0xc1, 0x92, 0xd6, 0x02, 0xaf, 0xca, 0x28,
- 0x9f, 0xe0, 0xf3, 0x74, 0xd7, 0xf1, 0x44, 0x67, 0x59, 0x27, 0xc8, 0xc2,
- 0x8b, 0xd4, 0xe5, 0x4a, 0x07, 0xfd, 0x00, 0xd6, 0x8a, 0xbf, 0x8b, 0xcd,
- 0x6a, 0xe0, 0x1d, 0xf6, 0x4b, 0x68, 0x0f, 0xcf, 0xb9, 0xd0, 0xa1, 0xbc,
- 0x2e, 0xcf, 0x7c, 0x03, 0x47, 0x11, 0xe4, 0x4c, 0xbc, 0x1b, 0x6b, 0xa5,
- 0x2a, 0x82, 0x86, 0xa4, 0x7f, 0x1d, 0x85, 0x64, 0x21, 0x10, 0xd2, 0xb2,
- 0xa0, 0x31, 0xa2, 0x78, 0xe6, 0xf2, 0xea, 0x96, 0x38, 0x8c, 0x9a, 0xe1,
- 0x01, 0xab, 0x8e, 0x95, 0x66, 0xc8, 0xe5, 0xcc, 0x80, 0xa3, 0xbd, 0x16,
- 0xa7, 0x79, 0x19, 0x39, 0x61, 0x3d, 0xff, 0x37, 0xca, 0x9f, 0x97, 0x05,
- 0xc7, 0xcb, 0xf0, 0xea, 0xaf, 0x64, 0x07, 0xc0, 0xed, 0x2a, 0x98, 0xa4,
- 0xaf, 0x04, 0x6f, 0xf2, 0xc9, 0xb2, 0x73, 0x9a, 0x56, 0x85, 0x43, 0x64,
- 0x5f, 0xaa, 0xb7, 0xff, 0x31, 0x4c, 0x2e, 0x6c, 0x17, 0xcf, 0xe5, 0xbe,
- 0x7f, 0x7e, 0xad, 0xf5, 0x6f, 0x84, 0x50, 0x20, 0x29, 0xb3, 0x57, 0xe7,
- 0xb1, 0xdc, 0x2c, 0x95, 0x48, 0xfe, 0xb0, 0xc1, 0x92, 0xda, 0xc5, 0x58,
- 0x95, 0xb0, 0x1a, 0x3a, 0x05, 0x71, 0x3c, 0x6d, 0x20, 0x01, 0x4c, 0xa9,
- 0xe4, 0x38, 0x08, 0x65, 0xb4, 0xbd, 0x86, 0x76, 0xbd, 0xad, 0x25, 0x06,
- 0x74, 0x0b, 0xca, 0x95, 0x27, 0x0c, 0x13, 0x08, 0x7e, 0x30, 0xcf, 0xf6,
- 0xb5, 0xc1, 0x2a, 0x08, 0xfc, 0x4b, 0xc6, 0xb5, 0x2f, 0x23, 0x27, 0x32,
- 0x89, 0xdb, 0x0e, 0x4a,
+ 0x01, 0x7b, 0x52, 0x35, 0xe3, 0x51, 0xdd, 0xf1, 0x67, 0x8d, 0x31, 0x5e,
+ 0xa3, 0x75, 0x1f, 0x68, 0x6c, 0xdd, 0x41, 0x7a, 0x18, 0x25, 0xe0, 0x12,
+ 0x6e, 0x84, 0x46, 0x5e, 0xb2, 0x98, 0xd7, 0x84, 0xe1, 0x62, 0xe0, 0xc1,
+ 0xc4, 0xd7, 0x4f, 0x4f, 0x80, 0xc1, 0x92, 0xd6, 0x02, 0xaf, 0xca, 0x28,
+ 0x9f, 0xe0, 0xf3, 0x74, 0xd7, 0xf1, 0x44, 0x67, 0x59, 0x27, 0xc8, 0xc2,
+ 0x8b, 0xd4, 0xe5, 0x4a, 0x07, 0xfd, 0x00, 0xd6, 0x8a, 0xbf, 0x8b, 0xcd,
+ 0x6a, 0xe0, 0x1d, 0xf6, 0x4b, 0x68, 0x0f, 0xcf, 0xb9, 0xd0, 0xa1, 0xbc,
+ 0x2e, 0xcf, 0x7c, 0x03, 0x47, 0x11, 0xe4, 0x4c, 0xbc, 0x1b, 0x6b, 0xa5,
+ 0x2a, 0x82, 0x86, 0xa4, 0x7f, 0x1d, 0x85, 0x64, 0x21, 0x10, 0xd2, 0xb2,
+ 0xa0, 0x31, 0xa2, 0x78, 0xe6, 0xf2, 0xea, 0x96, 0x38, 0x8c, 0x9a, 0xe1,
+ 0x01, 0xab, 0x8e, 0x95, 0x66, 0xc8, 0xe5, 0xcc, 0x80, 0xa3, 0xbd, 0x16,
+ 0xa7, 0x79, 0x19, 0x39, 0x61, 0x3d, 0xff, 0x37, 0xca, 0x9f, 0x97, 0x05,
+ 0xc7, 0xcb, 0xf0, 0xea, 0xaf, 0x64, 0x07, 0xc0, 0xed, 0x2a, 0x98, 0xa4,
+ 0xaf, 0x04, 0x6f, 0xf2, 0xc9, 0xb2, 0x73, 0x9a, 0x56, 0x85, 0x43, 0x64,
+ 0x5f, 0xaa, 0xb7, 0xff, 0x31, 0x4c, 0x2e, 0x6c, 0x17, 0xcf, 0xe5, 0xbe,
+ 0x7f, 0x7e, 0xad, 0xf5, 0x6f, 0x84, 0x50, 0x20, 0x29, 0xb3, 0x57, 0xe7,
+ 0xb1, 0xdc, 0x2c, 0x95, 0x48, 0xfe, 0xb0, 0xc1, 0x92, 0xda, 0xc5, 0x58,
+ 0x95, 0xb0, 0x1a, 0x3a, 0x05, 0x71, 0x3c, 0x6d, 0x20, 0x01, 0x4c, 0xa9,
+ 0xe4, 0x38, 0x08, 0x65, 0xb4, 0xbd, 0x86, 0x76, 0xbd, 0xad, 0x25, 0x06,
+ 0x74, 0x0b, 0xca, 0x95, 0x27, 0x0c, 0x13, 0x08, 0x7e, 0x30, 0xcf, 0xf6,
+ 0xb5, 0xc1, 0x2a, 0x08, 0xfc, 0x4b, 0xc6, 0xb5, 0x2f, 0x23, 0x27, 0x32,
+ 0x89, 0xdb, 0x0e, 0x4a,
};
static const unsigned char signature_data_2[] = {
- 0x6d, 0x7d, 0x22, 0x8c, 0x85, 0xc4, 0x8a, 0x80, 0x05, 0xe4, 0x3c, 0xaf,
- 0x10, 0x3b, 0xe3, 0x51, 0xb1, 0x86, 0x52, 0x63, 0xb6, 0x17, 0x33, 0xbd,
- 0x1b, 0x1e, 0xc4, 0x50, 0x10, 0xfc, 0xcc, 0xea, 0x6b, 0x11, 0xeb, 0x6d,
- 0x5e, 0x00, 0xe7, 0xf3, 0x67, 0x99, 0x74, 0x53, 0x12, 0x8f, 0xe4, 0x3e,
- 0x20, 0x17, 0x8e, 0x83, 0xe6, 0xdc, 0x83, 0x91, 0x0e, 0xf3, 0x69, 0x22,
- 0x95, 0x14, 0xdf, 0xc1, 0xda, 0xb5, 0xdb, 0x6a, 0x1a, 0xb4, 0x4f, 0x26,
- 0xd0, 0x32, 0x1d, 0x73, 0x95, 0x1f, 0x39, 0x1d, 0x00, 0xcb, 0xc3, 0x92,
- 0x49, 0x53, 0xcb, 0x5c, 0x36, 0x70, 0x19, 0xd9, 0x64, 0x36, 0xda, 0xfb,
- 0x20, 0xe5, 0x47, 0xd9, 0x08, 0xc6, 0x5a, 0x9e, 0x87, 0x1a, 0xdb, 0x11,
- 0x7b, 0x17, 0xfc, 0x53, 0x7b, 0xc1, 0xa0, 0xc0, 0x33, 0xcf, 0x96, 0xba,
- 0x03, 0x79, 0x8e, 0xc6, 0x05, 0xd2, 0xb7, 0xa2, 0xe2, 0xc1, 0x67, 0xb7,
- 0x6a, 0xeb, 0xb1, 0x40, 0xbb, 0x7d, 0x57, 0xcb, 0xc2, 0x60, 0x9f, 0xf1,
- 0x72, 0xe5, 0xad, 0xce, 0x95, 0x45, 0x7c, 0xbc, 0x75, 0x81, 0x45, 0x19,
- 0xe1, 0xa7, 0x2f, 0x05, 0x52, 0xeb, 0xed, 0xdd, 0x19, 0xd9, 0x1a, 0xc9,
- 0x5a, 0x06, 0x8e, 0x29, 0x54, 0xb5, 0x4f, 0x80, 0xaa, 0x36, 0x36, 0xc0,
- 0xff, 0x64, 0xac, 0xe8, 0x0f, 0x99, 0x35, 0x5e, 0xc6, 0x72, 0x1f, 0x8c,
- 0xc4, 0x2b, 0x7d, 0xc1, 0xfb, 0xf0, 0x12, 0x61, 0xb1, 0x18, 0x65, 0xdd,
- 0xc2, 0x38, 0x92, 0xba, 0x84, 0xf8, 0xc8, 0x5e, 0x17, 0x63, 0xe0, 0x9c,
- 0x2c, 0xe6, 0x70, 0x71, 0xdc, 0xe5, 0xc1, 0xea, 0xb3, 0x9a, 0xb6, 0x91,
- 0xdc, 0xc5, 0x56, 0x84, 0x8a, 0x31, 0x31, 0x23, 0x61, 0x94, 0x7e, 0x01,
- 0x22, 0x49, 0xf3, 0xcb, 0x0e, 0x31, 0x03, 0x04, 0x1b, 0x14, 0x43, 0x7c,
- 0xad, 0x42, 0xe5, 0x55,
+ 0x6d, 0x7d, 0x22, 0x8c, 0x85, 0xc4, 0x8a, 0x80, 0x05, 0xe4, 0x3c, 0xaf,
+ 0x10, 0x3b, 0xe3, 0x51, 0xb1, 0x86, 0x52, 0x63, 0xb6, 0x17, 0x33, 0xbd,
+ 0x1b, 0x1e, 0xc4, 0x50, 0x10, 0xfc, 0xcc, 0xea, 0x6b, 0x11, 0xeb, 0x6d,
+ 0x5e, 0x00, 0xe7, 0xf3, 0x67, 0x99, 0x74, 0x53, 0x12, 0x8f, 0xe4, 0x3e,
+ 0x20, 0x17, 0x8e, 0x83, 0xe6, 0xdc, 0x83, 0x91, 0x0e, 0xf3, 0x69, 0x22,
+ 0x95, 0x14, 0xdf, 0xc1, 0xda, 0xb5, 0xdb, 0x6a, 0x1a, 0xb4, 0x4f, 0x26,
+ 0xd0, 0x32, 0x1d, 0x73, 0x95, 0x1f, 0x39, 0x1d, 0x00, 0xcb, 0xc3, 0x92,
+ 0x49, 0x53, 0xcb, 0x5c, 0x36, 0x70, 0x19, 0xd9, 0x64, 0x36, 0xda, 0xfb,
+ 0x20, 0xe5, 0x47, 0xd9, 0x08, 0xc6, 0x5a, 0x9e, 0x87, 0x1a, 0xdb, 0x11,
+ 0x7b, 0x17, 0xfc, 0x53, 0x7b, 0xc1, 0xa0, 0xc0, 0x33, 0xcf, 0x96, 0xba,
+ 0x03, 0x79, 0x8e, 0xc6, 0x05, 0xd2, 0xb7, 0xa2, 0xe2, 0xc1, 0x67, 0xb7,
+ 0x6a, 0xeb, 0xb1, 0x40, 0xbb, 0x7d, 0x57, 0xcb, 0xc2, 0x60, 0x9f, 0xf1,
+ 0x72, 0xe5, 0xad, 0xce, 0x95, 0x45, 0x7c, 0xbc, 0x75, 0x81, 0x45, 0x19,
+ 0xe1, 0xa7, 0x2f, 0x05, 0x52, 0xeb, 0xed, 0xdd, 0x19, 0xd9, 0x1a, 0xc9,
+ 0x5a, 0x06, 0x8e, 0x29, 0x54, 0xb5, 0x4f, 0x80, 0xaa, 0x36, 0x36, 0xc0,
+ 0xff, 0x64, 0xac, 0xe8, 0x0f, 0x99, 0x35, 0x5e, 0xc6, 0x72, 0x1f, 0x8c,
+ 0xc4, 0x2b, 0x7d, 0xc1, 0xfb, 0xf0, 0x12, 0x61, 0xb1, 0x18, 0x65, 0xdd,
+ 0xc2, 0x38, 0x92, 0xba, 0x84, 0xf8, 0xc8, 0x5e, 0x17, 0x63, 0xe0, 0x9c,
+ 0x2c, 0xe6, 0x70, 0x71, 0xdc, 0xe5, 0xc1, 0xea, 0xb3, 0x9a, 0xb6, 0x91,
+ 0xdc, 0xc5, 0x56, 0x84, 0x8a, 0x31, 0x31, 0x23, 0x61, 0x94, 0x7e, 0x01,
+ 0x22, 0x49, 0xf3, 0xcb, 0x0e, 0x31, 0x03, 0x04, 0x1b, 0x14, 0x43, 0x7c,
+ 0xad, 0x42, 0xe5, 0x55,
};
scoped_ptr<ProofVerifier> verifier(
- CryptoTestUtils::ProofVerifierForTesting());
+ CryptoTestUtils::RealProofVerifierForTesting());
const string server_config = "server config bytes";
const string hostname = "test.example.com";
@@ -256,18 +253,17 @@ TEST(ProofTest, VerifyRSAKnownAnswerTest) {
for (size_t i = 0; i < signatures.size(); i++) {
const string& signature = signatures[i];
- RunVerification(
- verifier.get(), hostname, server_config, certs, signature, true);
- RunVerification(
- verifier.get(), "foo.com", server_config, certs, signature, false);
- RunVerification(
- verifier.get(), hostname, server_config.substr(1, string::npos),
- certs, signature, false);
+ RunVerification(verifier.get(), hostname, server_config, certs, signature,
+ true);
+ RunVerification(verifier.get(), "foo.com", server_config, certs, signature,
+ false);
+ RunVerification(verifier.get(), hostname,
+ server_config.substr(1, string::npos), certs, signature,
+ false);
const string corrupt_signature = "1" + signature;
- RunVerification(
- verifier.get(), hostname, server_config, certs, corrupt_signature,
- false);
+ RunVerification(verifier.get(), hostname, server_config, certs,
+ corrupt_signature, false);
vector<string> wrong_certs;
for (size_t i = 1; i < certs.size(); i++) {
@@ -281,7 +277,7 @@ TEST(ProofTest, VerifyRSAKnownAnswerTest) {
// A known answer test that allows us to test ProofVerifier without a working
// ProofSource.
TEST(ProofTest, VerifyECDSAKnownAnswerTest) {
- // Disable this test on platforms that do not support ECDSA certificates.
+// Disable this test on platforms that do not support ECDSA certificates.
#if defined(OS_WIN)
if (base::win::GetVersion() < base::win::VERSION_VISTA)
return;
@@ -291,32 +287,32 @@ TEST(ProofTest, VerifyECDSAKnownAnswerTest) {
// (modified to use ECDSA for signing proofs) and dumping the bytes of the
// |signature| output of ProofSource::GetProof().
static const unsigned char signature_data_0[] = {
- 0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0xc4, 0x7d, 0x08, 0xd1, 0x49, 0x19,
- 0x6c, 0xd1, 0x7c, 0xb9, 0x25, 0xe0, 0xe3, 0xbd, 0x6a, 0x5c, 0xd7, 0xaa,
- 0x0c, 0xdc, 0x4f, 0x8e, 0xeb, 0xde, 0xbf, 0x32, 0xf8, 0xd1, 0x84, 0x95,
- 0x97, 0x02, 0x20, 0x29, 0x3d, 0x49, 0x22, 0x73, 0xed, 0x8b, 0xde, 0x3d,
- 0xc2, 0xa4, 0x20, 0xcc, 0xe7, 0xc8, 0x2a, 0x85, 0x20, 0x9b, 0x5b, 0xda,
- 0xcd, 0x58, 0x23, 0xbe, 0x89, 0x73, 0x31, 0x87, 0x51, 0xd1, 0x01,
+ 0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0xc4, 0x7d, 0x08, 0xd1, 0x49, 0x19,
+ 0x6c, 0xd1, 0x7c, 0xb9, 0x25, 0xe0, 0xe3, 0xbd, 0x6a, 0x5c, 0xd7, 0xaa,
+ 0x0c, 0xdc, 0x4f, 0x8e, 0xeb, 0xde, 0xbf, 0x32, 0xf8, 0xd1, 0x84, 0x95,
+ 0x97, 0x02, 0x20, 0x29, 0x3d, 0x49, 0x22, 0x73, 0xed, 0x8b, 0xde, 0x3d,
+ 0xc2, 0xa4, 0x20, 0xcc, 0xe7, 0xc8, 0x2a, 0x85, 0x20, 0x9b, 0x5b, 0xda,
+ 0xcd, 0x58, 0x23, 0xbe, 0x89, 0x73, 0x31, 0x87, 0x51, 0xd1, 0x01,
};
static const unsigned char signature_data_1[] = {
- 0x30, 0x46, 0x02, 0x21, 0x00, 0xec, 0xdf, 0x69, 0xc8, 0x24, 0x59, 0x93,
- 0xda, 0x49, 0xee, 0x37, 0x28, 0xaf, 0xeb, 0x0e, 0x2f, 0x80, 0x17, 0x4b,
- 0x3b, 0xf6, 0x54, 0xcd, 0x3b, 0x86, 0xc5, 0x98, 0x0d, 0xff, 0xc6, 0xb1,
- 0xe7, 0x02, 0x21, 0x00, 0xe1, 0x36, 0x8c, 0xc0, 0xf4, 0x50, 0x5f, 0xba,
- 0xfb, 0xe2, 0xff, 0x1d, 0x5d, 0x64, 0xe4, 0x07, 0xbb, 0x5a, 0x4b, 0x19,
- 0xb6, 0x39, 0x7a, 0xc4, 0x12, 0xc6, 0xe5, 0x42, 0xc8, 0x78, 0x33, 0xcd,
+ 0x30, 0x46, 0x02, 0x21, 0x00, 0xec, 0xdf, 0x69, 0xc8, 0x24, 0x59, 0x93,
+ 0xda, 0x49, 0xee, 0x37, 0x28, 0xaf, 0xeb, 0x0e, 0x2f, 0x80, 0x17, 0x4b,
+ 0x3b, 0xf6, 0x54, 0xcd, 0x3b, 0x86, 0xc5, 0x98, 0x0d, 0xff, 0xc6, 0xb1,
+ 0xe7, 0x02, 0x21, 0x00, 0xe1, 0x36, 0x8c, 0xc0, 0xf4, 0x50, 0x5f, 0xba,
+ 0xfb, 0xe2, 0xff, 0x1d, 0x5d, 0x64, 0xe4, 0x07, 0xbb, 0x5a, 0x4b, 0x19,
+ 0xb6, 0x39, 0x7a, 0xc4, 0x12, 0xc6, 0xe5, 0x42, 0xc8, 0x78, 0x33, 0xcd,
};
static const unsigned char signature_data_2[] = {
- 0x30, 0x45, 0x02, 0x20, 0x09, 0x51, 0xe9, 0xde, 0xdb, 0x01, 0xfd, 0xb4,
- 0xd8, 0x20, 0xbb, 0xad, 0x41, 0xe3, 0xaa, 0xe7, 0xa3, 0xc3, 0x32, 0x10,
- 0x9d, 0xfa, 0x37, 0xce, 0x17, 0xd1, 0x29, 0xf9, 0xd4, 0x1d, 0x0d, 0x19,
- 0x02, 0x21, 0x00, 0xc6, 0x20, 0xd4, 0x28, 0xf9, 0x70, 0xb5, 0xb4, 0xff,
- 0x4a, 0x35, 0xba, 0xa0, 0xf2, 0x8e, 0x00, 0xf7, 0xcb, 0x43, 0xaf, 0x2d,
- 0x1f, 0xce, 0x92, 0x05, 0xca, 0x29, 0xfe, 0xd2, 0x8f, 0xd9, 0x31,
+ 0x30, 0x45, 0x02, 0x20, 0x09, 0x51, 0xe9, 0xde, 0xdb, 0x01, 0xfd, 0xb4,
+ 0xd8, 0x20, 0xbb, 0xad, 0x41, 0xe3, 0xaa, 0xe7, 0xa3, 0xc3, 0x32, 0x10,
+ 0x9d, 0xfa, 0x37, 0xce, 0x17, 0xd1, 0x29, 0xf9, 0xd4, 0x1d, 0x0d, 0x19,
+ 0x02, 0x21, 0x00, 0xc6, 0x20, 0xd4, 0x28, 0xf9, 0x70, 0xb5, 0xb4, 0xff,
+ 0x4a, 0x35, 0xba, 0xa0, 0xf2, 0x8e, 0x00, 0xf7, 0xcb, 0x43, 0xaf, 0x2d,
+ 0x1f, 0xce, 0x92, 0x05, 0xca, 0x29, 0xfe, 0xd2, 0x8f, 0xd9, 0x31,
};
scoped_ptr<ProofVerifier> verifier(
- CryptoTestUtils::ProofVerifierForTesting());
+ CryptoTestUtils::RealProofVerifierForTesting());
const string server_config = "server config bytes";
const string hostname = "test.example.com";
@@ -338,35 +334,32 @@ TEST(ProofTest, VerifyECDSAKnownAnswerTest) {
for (size_t i = 0; i < signatures.size(); i++) {
const string& signature = signatures[i];
- RunVerification(
- verifier.get(), hostname, server_config, certs, signature, true);
- RunVerification(
- verifier.get(), "foo.com", server_config, certs, signature, false);
- RunVerification(
- verifier.get(), hostname, server_config.substr(1, string::npos),
- certs, signature, false);
+ RunVerification(verifier.get(), hostname, server_config, certs, signature,
+ true);
+ RunVerification(verifier.get(), "foo.com", server_config, certs, signature,
+ false);
+ RunVerification(verifier.get(), hostname,
+ server_config.substr(1, string::npos), certs, signature,
+ false);
// An ECDSA signature is DER-encoded. Corrupt the last byte so that the
// signature can still be DER-decoded correctly.
string corrupt_signature = signature;
corrupt_signature[corrupt_signature.size() - 1] += 1;
- RunVerification(
- verifier.get(), hostname, server_config, certs, corrupt_signature,
- false);
+ RunVerification(verifier.get(), hostname, server_config, certs,
+ corrupt_signature, false);
// Prepending a "1" makes the DER invalid.
const string bad_der_signature1 = "1" + signature;
- RunVerification(
- verifier.get(), hostname, server_config, certs, bad_der_signature1,
- false);
+ RunVerification(verifier.get(), hostname, server_config, certs,
+ bad_der_signature1, false);
vector<string> wrong_certs;
for (size_t i = 1; i < certs.size(); i++) {
wrong_certs.push_back(certs[i]);
}
- RunVerification(
- verifier.get(), hostname, server_config, wrong_certs, signature,
- false);
+ RunVerification(verifier.get(), hostname, server_config, wrong_certs,
+ signature, false);
}
}
diff --git a/chromium/net/quic/crypto/proof_verifier.h b/chromium/net/quic/crypto/proof_verifier.h
index 87339da4208..0ec346aeb13 100644
--- a/chromium/net/quic/crypto/proof_verifier.h
+++ b/chromium/net/quic/crypto/proof_verifier.h
@@ -76,6 +76,7 @@ class NET_EXPORT_PRIVATE ProofVerifier {
virtual QuicAsyncStatus VerifyProof(const std::string& hostname,
const std::string& server_config,
const std::vector<std::string>& certs,
+ const std::string& cert_sct,
const std::string& signature,
const ProofVerifyContext* context,
std::string* error_details,
diff --git a/chromium/net/quic/crypto/proof_verifier_chromium.cc b/chromium/net/quic/crypto/proof_verifier_chromium.cc
index 6b91d653dc9..e9191a76c2b 100644
--- a/chromium/net/quic/crypto/proof_verifier_chromium.cc
+++ b/chromium/net/quic/crypto/proof_verifier_chromium.cc
@@ -4,24 +4,26 @@
#include "net/quic/crypto/proof_verifier_chromium.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "crypto/signature_verifier.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
-#include "net/cert/cert_policy_enforcer.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_result.h"
-#include "net/cert/ct_verify_result.h"
+#include "net/cert/ct_policy_enforcer.h"
+#include "net/cert/ct_verifier.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
#include "net/http/transport_security_state.h"
@@ -39,6 +41,7 @@ namespace net {
ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
other->cert_verify_result = cert_verify_result;
+ other->ct_verify_result = ct_verify_result;
return other;
}
@@ -49,16 +52,19 @@ class ProofVerifierChromium::Job {
public:
Job(ProofVerifierChromium* proof_verifier,
CertVerifier* cert_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
TransportSecurityState* transport_security_state,
+ CTVerifier* cert_transparency_verifier,
int cert_verify_flags,
const BoundNetLog& net_log);
+ ~Job();
// Starts the proof verification. If |QUIC_PENDING| is returned, then
// |callback| will be invoked asynchronously when the verification completes.
QuicAsyncStatus VerifyProof(const std::string& hostname,
const std::string& server_config,
const std::vector<std::string>& certs,
+ const std::string& cert_sct,
const std::string& signature,
std::string* error_details,
scoped_ptr<ProofVerifyDetails>* verify_details,
@@ -87,10 +93,12 @@ class ProofVerifierChromium::Job {
CertVerifier* verifier_;
scoped_ptr<CertVerifier::Request> cert_verifier_request_;
- CertPolicyEnforcer* policy_enforcer_;
+ CTPolicyEnforcer* policy_enforcer_;
TransportSecurityState* transport_security_state_;
+ CTVerifier* cert_transparency_verifier_;
+
// |hostname| specifies the hostname for which |certs| is a valid chain.
std::string hostname_;
@@ -107,6 +115,8 @@ class ProofVerifierChromium::Job {
State next_state_;
+ base::TimeTicks start_time_;
+
BoundNetLog net_log_;
DISALLOW_COPY_AND_ASSIGN(Job);
@@ -115,22 +125,37 @@ class ProofVerifierChromium::Job {
ProofVerifierChromium::Job::Job(
ProofVerifierChromium* proof_verifier,
CertVerifier* cert_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
TransportSecurityState* transport_security_state,
+ CTVerifier* cert_transparency_verifier,
int cert_verify_flags,
const BoundNetLog& net_log)
: proof_verifier_(proof_verifier),
verifier_(cert_verifier),
- policy_enforcer_(cert_policy_enforcer),
+ policy_enforcer_(ct_policy_enforcer),
transport_security_state_(transport_security_state),
+ cert_transparency_verifier_(cert_transparency_verifier),
cert_verify_flags_(cert_verify_flags),
next_state_(STATE_NONE),
+ start_time_(base::TimeTicks::Now()),
net_log_(net_log) {}
+ProofVerifierChromium::Job::~Job() {
+ base::TimeTicks end_time = base::TimeTicks::Now();
+ UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime",
+ end_time - start_time_);
+ // |hostname_| will always be canonicalized to lowercase.
+ if (hostname_.compare("www.google.com") == 0) {
+ UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.google",
+ end_time - start_time_);
+ }
+}
+
QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
const string& hostname,
const string& server_config,
const vector<string>& certs,
+ const std::string& cert_sct,
const string& signature,
std::string* error_details,
scoped_ptr<ProofVerifyDetails>* verify_details,
@@ -153,7 +178,7 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
*error_details = "Failed to create certificate chain. Certs are empty.";
DLOG(WARNING) << *error_details;
verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
- *verify_details = verify_details_.Pass();
+ *verify_details = std::move(verify_details_);
return QUIC_FAILURE;
}
@@ -167,17 +192,26 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
*error_details = "Failed to create certificate chain";
DLOG(WARNING) << *error_details;
verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
- *verify_details = verify_details_.Pass();
+ *verify_details = std::move(verify_details_);
return QUIC_FAILURE;
}
+ if (cert_transparency_verifier_ && !cert_sct.empty()) {
+ // Note that this is a completely synchronous operation: The CT Log Verifier
+ // gets all the data it needs for SCT verification and does not do any
+ // external communication.
+ cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct,
+ &verify_details_->ct_verify_result,
+ net_log_);
+ }
+
// We call VerifySignature first to avoid copying of server_config and
// signature.
if (!VerifySignature(server_config, signature, certs[0])) {
*error_details = "Failed to verify signature of server config";
DLOG(WARNING) << *error_details;
verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
- *verify_details = verify_details_.Pass();
+ *verify_details = std::move(verify_details_);
return QUIC_FAILURE;
}
@@ -186,14 +220,14 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
next_state_ = STATE_VERIFY_CERT;
switch (DoLoop(OK)) {
case OK:
- *verify_details = verify_details_.Pass();
+ *verify_details = std::move(verify_details_);
return QUIC_SUCCESS;
case ERR_IO_PENDING:
callback_.reset(callback);
return QUIC_PENDING;
default:
*error_details = error_details_;
- *verify_details = verify_details_.Pass();
+ *verify_details = std::move(verify_details_);
return QUIC_FAILURE;
}
}
@@ -224,9 +258,9 @@ int ProofVerifierChromium::Job::DoLoop(int last_result) {
void ProofVerifierChromium::Job::OnIOComplete(int result) {
int rv = DoLoop(result);
if (rv != ERR_IO_PENDING) {
- scoped_ptr<ProofVerifierCallback> callback(callback_.Pass());
+ scoped_ptr<ProofVerifierCallback> callback(std::move(callback_));
// Callback expects ProofVerifyDetails not ProofVerifyDetailsChromium.
- scoped_ptr<ProofVerifyDetails> verify_details(verify_details_.Pass());
+ scoped_ptr<ProofVerifyDetails> verify_details(std::move(verify_details_));
callback->Run(rv == OK, error_details_, &verify_details);
// Will delete |this|.
proof_verifier_->OnJobComplete(this);
@@ -252,13 +286,10 @@ int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
const CertStatus cert_status = cert_verify_result.cert_status;
if (result == OK && policy_enforcer_ &&
(cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
- // QUIC does not support OCSP stapling or the CT TLS extension; as a
- // result, CT can never be verified, thus the result is always empty.
- ct::CTVerifyResult empty_ct_result;
if (!policy_enforcer_->DoesConformToCTEVPolicy(
cert_verify_result.verified_cert.get(),
- SSLConfigService::GetEVCertsWhitelist().get(), empty_ct_result,
- net_log_)) {
+ SSLConfigService::GetEVCertsWhitelist().get(),
+ verify_details_->ct_verify_result, net_log_)) {
verify_details_->cert_verify_result.cert_status |=
CERT_STATUS_CT_COMPLIANCE_FAILED;
verify_details_->cert_verify_result.cert_status &= ~CERT_STATUS_IS_EV;
@@ -294,11 +325,6 @@ int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
const string& signature,
const string& cert) {
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "422516 ProofVerifierChromium::Job::VerifySignature"));
-
StringPiece spki;
if (!asn1::ExtractSPKIFromDERCert(cert, &spki)) {
DLOG(WARNING) << "ExtractSPKIFromDERCert failed";
@@ -309,8 +335,7 @@ bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
size_t size_bits;
X509Certificate::PublicKeyType type;
- X509Certificate::GetPublicKeyInfo(cert_->os_cert_handle(), &size_bits,
- &type);
+ X509Certificate::GetPublicKeyInfo(cert_->os_cert_handle(), &size_bits, &type);
if (type == X509Certificate::kPublicKeyTypeRSA) {
crypto::SignatureVerifier::HashAlgorithm hash_alg =
crypto::SignatureVerifier::SHA256;
@@ -319,8 +344,8 @@ bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
bool ok = verifier.VerifyInitRSAPSS(
hash_alg, mask_hash_alg, hash_len,
- reinterpret_cast<const uint8*>(signature.data()), signature.size(),
- reinterpret_cast<const uint8*>(spki.data()), spki.size());
+ reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
+ reinterpret_cast<const uint8_t*>(spki.data()), spki.size());
if (!ok) {
DLOG(WARNING) << "VerifyInitRSAPSS failed";
return false;
@@ -338,17 +363,14 @@ bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
// component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
// SHA384, or ecdsa-with-SHA512.
// See also RFC 5480, Appendix A.
- static const uint8 kECDSAWithSHA256AlgorithmID[] = {
- 0x30, 0x0a,
- 0x06, 0x08,
- 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
+ static const uint8_t kECDSAWithSHA256AlgorithmID[] = {
+ 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
};
if (!verifier.VerifyInit(
kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
- reinterpret_cast<const uint8*>(signature.data()),
- signature.size(),
- reinterpret_cast<const uint8*>(spki.data()),
+ reinterpret_cast<const uint8_t*>(signature.data()),
+ signature.size(), reinterpret_cast<const uint8_t*>(spki.data()),
spki.size())) {
DLOG(WARNING) << "VerifyInit failed";
return false;
@@ -358,9 +380,9 @@ bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
return false;
}
- verifier.VerifyUpdate(reinterpret_cast<const uint8*>(kProofSignatureLabel),
+ verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(kProofSignatureLabel),
sizeof(kProofSignatureLabel));
- verifier.VerifyUpdate(reinterpret_cast<const uint8*>(signed_data.data()),
+ verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(signed_data.data()),
signed_data.size());
if (!verifier.VerifyFinal()) {
@@ -374,11 +396,13 @@ bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
ProofVerifierChromium::ProofVerifierChromium(
CertVerifier* cert_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
- TransportSecurityState* transport_security_state)
+ CTPolicyEnforcer* ct_policy_enforcer,
+ TransportSecurityState* transport_security_state,
+ CTVerifier* cert_transparency_verifier)
: cert_verifier_(cert_verifier),
- cert_policy_enforcer_(cert_policy_enforcer),
- transport_security_state_(transport_security_state) {}
+ ct_policy_enforcer_(ct_policy_enforcer),
+ transport_security_state_(transport_security_state),
+ cert_transparency_verifier_(cert_transparency_verifier) {}
ProofVerifierChromium::~ProofVerifierChromium() {
STLDeleteElements(&active_jobs_);
@@ -388,6 +412,7 @@ QuicAsyncStatus ProofVerifierChromium::VerifyProof(
const std::string& hostname,
const std::string& server_config,
const std::vector<std::string>& certs,
+ const std::string& cert_sct,
const std::string& signature,
const ProofVerifyContext* verify_context,
std::string* error_details,
@@ -399,12 +424,13 @@ QuicAsyncStatus ProofVerifierChromium::VerifyProof(
}
const ProofVerifyContextChromium* chromium_context =
reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
- scoped_ptr<Job> job(new Job(
- this, cert_verifier_, cert_policy_enforcer_, transport_security_state_,
- chromium_context->cert_verify_flags, chromium_context->net_log));
+ scoped_ptr<Job> job(
+ new Job(this, cert_verifier_, ct_policy_enforcer_,
+ transport_security_state_, cert_transparency_verifier_,
+ chromium_context->cert_verify_flags, chromium_context->net_log));
QuicAsyncStatus status =
- job->VerifyProof(hostname, server_config, certs, signature, error_details,
- verify_details, callback);
+ job->VerifyProof(hostname, server_config, certs, cert_sct, signature,
+ error_details, verify_details, callback);
if (status == QUIC_PENDING) {
active_jobs_.insert(job.release());
}
diff --git a/chromium/net/quic/crypto/proof_verifier_chromium.h b/chromium/net/quic/crypto/proof_verifier_chromium.h
index 46d63e16e5c..fd7f345a705 100644
--- a/chromium/net/quic/crypto/proof_verifier_chromium.h
+++ b/chromium/net/quic/crypto/proof_verifier_chromium.h
@@ -9,19 +9,21 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/cert/cert_verify_result.h"
+#include "net/cert/ct_verify_result.h"
#include "net/cert/x509_certificate.h"
#include "net/log/net_log.h"
#include "net/quic/crypto/proof_verifier.h"
namespace net {
-class CertPolicyEnforcer;
+class CTPolicyEnforcer;
class CertVerifier;
+class CTVerifier;
class TransportSecurityState;
// ProofVerifyDetailsChromium is the implementation-specific information that a
@@ -29,11 +31,11 @@ class TransportSecurityState;
class NET_EXPORT_PRIVATE ProofVerifyDetailsChromium
: public ProofVerifyDetails {
public:
-
// ProofVerifyDetails implementation
ProofVerifyDetails* Clone() const override;
CertVerifyResult cert_verify_result;
+ ct::CTVerifyResult ct_verify_result;
// pinning_failure_log contains a message produced by
// TransportSecurityState::PKPState::CheckPublicKeyPins in the event of a
@@ -57,14 +59,16 @@ struct ProofVerifyContextChromium : public ProofVerifyContext {
class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier {
public:
ProofVerifierChromium(CertVerifier* cert_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
- TransportSecurityState* transport_security_state);
+ CTPolicyEnforcer* ct_policy_enforcer,
+ TransportSecurityState* transport_security_state,
+ CTVerifier* cert_transparency_verifier);
~ProofVerifierChromium() override;
// ProofVerifier interface
QuicAsyncStatus VerifyProof(const std::string& hostname,
const std::string& server_config,
const std::vector<std::string>& certs,
+ const std::string& cert_sct,
const std::string& signature,
const ProofVerifyContext* verify_context,
std::string* error_details,
@@ -82,9 +86,10 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier {
// Underlying verifier used to verify certificates.
CertVerifier* const cert_verifier_;
- CertPolicyEnforcer* const cert_policy_enforcer_;
+ CTPolicyEnforcer* const ct_policy_enforcer_;
TransportSecurityState* const transport_security_state_;
+ CTVerifier* const cert_transparency_verifier_;
DISALLOW_COPY_AND_ASSIGN(ProofVerifierChromium);
};
diff --git a/chromium/net/quic/crypto/proof_verifier_chromium_test.cc b/chromium/net/quic/crypto/proof_verifier_chromium_test.cc
index 9e0f5987f24..96c40138080 100644
--- a/chromium/net/quic/crypto/proof_verifier_chromium_test.cc
+++ b/chromium/net/quic/crypto/proof_verifier_chromium_test.cc
@@ -8,15 +8,20 @@
#include "base/memory/scoped_ptr.h"
#include "net/base/net_errors.h"
#include "net/base/test_data_directory.h"
-#include "net/cert/cert_policy_enforcer.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
+#include "net/cert/ct_log_verifier.h"
+#include "net/cert/ct_policy_enforcer.h"
+#include "net/cert/ct_serialization.h"
+#include "net/cert/ct_verify_result.h"
#include "net/cert/mock_cert_verifier.h"
+#include "net/cert/multi_log_ct_verifier.h"
#include "net/cert/x509_certificate.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
#include "net/quic/crypto/proof_verifier.h"
#include "net/test/cert_test_util.h"
+#include "net/test/ct_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -45,28 +50,28 @@ class FailsTestCertVerifier : public CertVerifier {
}
};
-// CertPolicyEnforcer that will fail the test if it is ever called.
-class FailsTestCertPolicyEnforcer : public CertPolicyEnforcer {
+// CTPolicyEnforcer that will fail the test if it is ever called.
+class FailsTestCTPolicyEnforcer : public CTPolicyEnforcer {
public:
- FailsTestCertPolicyEnforcer() {}
- ~FailsTestCertPolicyEnforcer() override {}
+ FailsTestCTPolicyEnforcer() {}
+ ~FailsTestCTPolicyEnforcer() override {}
bool DoesConformToCTEVPolicy(X509Certificate* cert,
const ct::EVCertsWhitelist* ev_whitelist,
const ct::CTVerifyResult& ct_result,
const BoundNetLog& net_log) override {
- ADD_FAILURE() << "CertPolicyEnforcer::DoesConformToCTEVPolicy() should "
+ ADD_FAILURE() << "CTPolicyEnforcer::DoesConformToCTEVPolicy() should "
<< "not be called";
return false;
}
};
-// CertPolicyEnforcer that can simulate whether or not a given certificate
+// CTPolicyEnforcer that can simulate whether or not a given certificate
// conforms to the CT/EV policy.
-class MockCertPolicyEnforcer : public CertPolicyEnforcer {
+class MockCTPolicyEnforcer : public CTPolicyEnforcer {
public:
- MockCertPolicyEnforcer(bool is_ev) : is_ev_(is_ev) {}
- ~MockCertPolicyEnforcer() override {}
+ MockCTPolicyEnforcer(bool is_ev) : is_ev_(is_ev) {}
+ ~MockCTPolicyEnforcer() override {}
bool DoesConformToCTEVPolicy(X509Certificate* cert,
const ct::EVCertsWhitelist* ev_whitelist,
@@ -91,107 +96,213 @@ class DummyProofVerifierCallback : public ProofVerifierCallback {
}
};
-scoped_refptr<X509Certificate> GetTestServerCertificate() {
- static const char kTestCert[] = "quic_test.example.com.crt";
- return ImportCertFromFile(GetTestCertsDirectory(), kTestCert);
-}
+const char kTestHostname[] = "test.example.com";
+const char kTestConfig[] = "server config bytes";
+const char kLogDescription[] = "somelog";
-void GetTestCertificates(std::vector<std::string>* certs) {
- scoped_refptr<X509Certificate> cert = GetTestServerCertificate();
- ASSERT_TRUE(cert);
+} // namespace
- std::string der_bytes;
- ASSERT_TRUE(
- X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes));
+class ProofVerifierChromiumTest : public ::testing::Test {
+ public:
+ ProofVerifierChromiumTest()
+ : verify_context_(new ProofVerifyContextChromium(0 /*cert_verify_flags*/,
+ BoundNetLog())) {}
- certs->clear();
- certs->push_back(der_bytes);
-}
+ void SetUp() override {
+ scoped_refptr<const CTLogVerifier> log(CTLogVerifier::Create(
+ ct::GetTestPublicKey(), kLogDescription, "https://test.example.com"));
+ ASSERT_TRUE(log);
+ log_verifiers_.push_back(log);
-std::string GetTestSignature() {
- // Sample known answer test from ProofTest.VerifyRSAKnownAnswerTest.
- // Generated by dumping the bytes of the |signature| output of
- // ProofSource::GetProof().
- static const unsigned char kTestSignature[] = {
- 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
- 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
- 0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
- 0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
- 0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
- 0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
- 0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
- 0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
- 0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
- 0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
- 0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
- 0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
- 0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
- 0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
- 0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
- 0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
- 0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
- 0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
- 0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
- 0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
- 0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
- 0xc4, 0x4b, 0x53, 0x54,
- };
- return std::string(reinterpret_cast<const char*>(kTestSignature),
- sizeof(kTestSignature));
-}
+ ct_verifier_.reset(new MultiLogCTVerifier());
+ ct_verifier_->AddLogs(log_verifiers_);
-const char kTestHostname[] = "test.example.com";
-const char kTestConfig[] = "server config bytes";
+ ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs_));
+ }
-} // namespace
+ scoped_refptr<X509Certificate> GetTestServerCertificate() {
+ static const char kTestCert[] = "quic_test.example.com.crt";
+ return ImportCertFromFile(GetTestCertsDirectory(), kTestCert);
+ }
+
+ void GetTestCertificates(std::vector<std::string>* certs) {
+ scoped_refptr<X509Certificate> cert = GetTestServerCertificate();
+ ASSERT_TRUE(cert);
+
+ std::string der_bytes;
+ ASSERT_TRUE(
+ X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes));
+
+ certs->clear();
+ certs->push_back(der_bytes);
+ }
+
+ std::string GetTestSignature() {
+ // Sample known answer test from ProofTest.VerifyRSAKnownAnswerTest.
+ // Generated by dumping the bytes of the |signature| output of
+ // ProofSource::GetProof().
+ static const unsigned char kTestSignature[] = {
+ 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
+ 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
+ 0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
+ 0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
+ 0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
+ 0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
+ 0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
+ 0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
+ 0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
+ 0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
+ 0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
+ 0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
+ 0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
+ 0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
+ 0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
+ 0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
+ 0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
+ 0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
+ 0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
+ 0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
+ 0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
+ 0xc4, 0x4b, 0x53, 0x54,
+ };
+ return std::string(reinterpret_cast<const char*>(kTestSignature),
+ sizeof(kTestSignature));
+ }
+
+ void GetSCTTestCertificates(std::vector<std::string>* certs) {
+ std::string der_test_cert(ct::GetDerEncodedX509Cert());
+ scoped_refptr<X509Certificate> test_cert = X509Certificate::CreateFromBytes(
+ der_test_cert.data(), der_test_cert.length());
+ ASSERT_TRUE(test_cert.get());
+
+ std::string der_bytes;
+ ASSERT_TRUE(X509Certificate::GetDEREncoded(test_cert->os_cert_handle(),
+ &der_bytes));
+
+ certs->clear();
+ certs->push_back(der_bytes);
+ }
+
+ std::string GetSCTListForTesting() {
+ const std::string sct = ct::GetTestSignedCertificateTimestamp();
+ std::string sct_list;
+ ct::EncodeSCTListForTesting(sct, &sct_list);
+ return sct_list;
+ }
+
+ std::string GetCorruptSCTListForTesting() {
+ std::string sct = ct::GetTestSignedCertificateTimestamp();
+ sct[15] = 't'; // Corrupt a byte inside SCT.
+ std::string sct_list;
+ ct::EncodeSCTListForTesting(sct, &sct_list);
+ return sct_list;
+ }
+
+ bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result) {
+ return (result.verified_scts.size() == 1U) && result.invalid_scts.empty() &&
+ result.unknown_logs_scts.empty() &&
+ result.verified_scts[0]->log_description == kLogDescription;
+ }
+
+ bool CheckForSCTOrigin(const ct::CTVerifyResult& result,
+ ct::SignedCertificateTimestamp::Origin origin) {
+ return (result.verified_scts.size() > 0) &&
+ (result.verified_scts[0]->origin == origin);
+ }
+
+ void CheckSCT(bool sct_expected_ok) {
+ ProofVerifyDetailsChromium* proof_details =
+ reinterpret_cast<ProofVerifyDetailsChromium*>(details_.get());
+ const ct::CTVerifyResult& ct_verify_result =
+ proof_details->ct_verify_result;
+ if (sct_expected_ok) {
+ ASSERT_TRUE(CheckForSingleVerifiedSCTInResult(ct_verify_result));
+ ASSERT_TRUE(CheckForSCTOrigin(
+ ct_verify_result,
+ ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION));
+ } else {
+ EXPECT_EQ(1U, ct_verify_result.unknown_logs_scts.size());
+ }
+ }
+
+ protected:
+ scoped_ptr<MultiLogCTVerifier> ct_verifier_;
+ std::vector<scoped_refptr<const CTLogVerifier>> log_verifiers_;
+ scoped_ptr<ProofVerifyContext> verify_context_;
+ scoped_ptr<ProofVerifyDetails> details_;
+ std::string error_details_;
+ std::vector<std::string> certs_;
+};
// Tests that the ProofVerifier fails verification if certificate
// verification fails.
-TEST(ProofVerifierChromiumTest, FailsIfCertFails) {
+TEST_F(ProofVerifierChromiumTest, FailsIfCertFails) {
MockCertVerifier dummy_verifier;
- ProofVerifierChromium proof_verifier(&dummy_verifier, nullptr, nullptr);
+ ProofVerifierChromium proof_verifier(&dummy_verifier, nullptr, nullptr,
+ ct_verifier_.get());
- scoped_ptr<ProofVerifyContext> verify_context(
- new ProofVerifyContextChromium(0 /*cert_verify_flags*/, BoundNetLog()));
- scoped_ptr<ProofVerifyDetails> details;
- std::string error_details;
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
+ QuicAsyncStatus status = proof_verifier.VerifyProof(
+ kTestHostname, kTestConfig, certs_, "", GetTestSignature(),
+ verify_context_.get(), &error_details_, &details_, callback.get());
+ ASSERT_EQ(QUIC_FAILURE, status);
+}
+
+// Valid SCT, but invalid signature.
+TEST_F(ProofVerifierChromiumTest, ValidSCTList) {
+ // Use different certificates for SCT tests.
+ ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_));
- std::vector<std::string> certs;
- ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs));
+ MockCertVerifier cert_verifier;
+ ProofVerifierChromium proof_verifier(&cert_verifier, nullptr, nullptr,
+ ct_verifier_.get());
- DummyProofVerifierCallback* callback = new DummyProofVerifierCallback;
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestConfig, certs, GetTestSignature(),
- verify_context.get(), &error_details, &details, callback);
+ kTestHostname, kTestConfig, certs_, GetSCTListForTesting(), "",
+ verify_context_.get(), &error_details_, &details_, callback.get());
ASSERT_EQ(QUIC_FAILURE, status);
- delete callback;
+ CheckSCT(/*sct_expected_ok=*/true);
+}
+
+// Invalid SCT and signature.
+TEST_F(ProofVerifierChromiumTest, InvalidSCTList) {
+ // Use different certificates for SCT tests.
+ ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_));
+
+ MockCertVerifier cert_verifier;
+ ProofVerifierChromium proof_verifier(&cert_verifier, nullptr, nullptr,
+ ct_verifier_.get());
+
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
+ QuicAsyncStatus status = proof_verifier.VerifyProof(
+ kTestHostname, kTestConfig, certs_, GetCorruptSCTListForTesting(), "",
+ verify_context_.get(), &error_details_, &details_, callback.get());
+ ASSERT_EQ(QUIC_FAILURE, status);
+ CheckSCT(/*sct_expected_ok=*/false);
}
// Tests that the ProofVerifier doesn't verify certificates if the config
// signature fails.
-TEST(ProofVerifierChromiumTest, FailsIfSignatureFails) {
+TEST_F(ProofVerifierChromiumTest, FailsIfSignatureFails) {
FailsTestCertVerifier cert_verifier;
- ProofVerifierChromium proof_verifier(&cert_verifier, nullptr, nullptr);
-
- scoped_ptr<ProofVerifyContext> verify_context(
- new ProofVerifyContextChromium(0 /*cert_verify_flags*/, BoundNetLog()));
- scoped_ptr<ProofVerifyDetails> details;
- std::string error_details;
+ ProofVerifierChromium proof_verifier(&cert_verifier, nullptr, nullptr,
+ ct_verifier_.get());
- std::vector<std::string> certs;
- ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs));
-
- DummyProofVerifierCallback* callback = new DummyProofVerifierCallback;
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestConfig, certs, kTestConfig, verify_context.get(),
- &error_details, &details, callback);
+ kTestHostname, kTestConfig, certs_, "", kTestConfig,
+ verify_context_.get(), &error_details_, &details_, callback.get());
ASSERT_EQ(QUIC_FAILURE, status);
- delete callback;
}
// Tests that EV certificates are left as EV if there is no certificate
// policy enforcement.
-TEST(ProofVerifierChromiumTest, PreservesEVIfNoPolicy) {
+TEST_F(ProofVerifierChromiumTest, PreservesEVIfNoPolicy) {
scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
ASSERT_TRUE(test_cert);
@@ -202,33 +313,26 @@ TEST(ProofVerifierChromiumTest, PreservesEVIfNoPolicy) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, nullptr, nullptr);
-
- scoped_ptr<ProofVerifyContext> verify_context(
- new ProofVerifyContextChromium(0 /*cert_verify_flags*/, BoundNetLog()));
- scoped_ptr<ProofVerifyDetails> details;
- std::string error_details;
-
- std::vector<std::string> certs;
- ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs));
+ ProofVerifierChromium proof_verifier(&dummy_verifier, nullptr, nullptr,
+ ct_verifier_.get());
- DummyProofVerifierCallback* callback = new DummyProofVerifierCallback;
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestConfig, certs, GetTestSignature(),
- verify_context.get(), &error_details, &details, callback);
+ kTestHostname, kTestConfig, certs_, "", GetTestSignature(),
+ verify_context_.get(), &error_details_, &details_, callback.get());
ASSERT_EQ(QUIC_SUCCESS, status);
- delete callback;
- ASSERT_TRUE(details.get());
+ ASSERT_TRUE(details_.get());
ProofVerifyDetailsChromium* verify_details =
- static_cast<ProofVerifyDetailsChromium*>(details.get());
+ static_cast<ProofVerifyDetailsChromium*>(details_.get());
EXPECT_EQ(dummy_result.cert_status,
verify_details->cert_verify_result.cert_status);
}
// Tests that the certificate policy enforcer is consulted for EV
// and the certificate is allowed to be EV.
-TEST(ProofVerifierChromiumTest, PreservesEVIfAllowed) {
+TEST_F(ProofVerifierChromiumTest, PreservesEVIfAllowed) {
scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
ASSERT_TRUE(test_cert);
@@ -239,36 +343,28 @@ TEST(ProofVerifierChromiumTest, PreservesEVIfAllowed) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
- MockCertPolicyEnforcer policy_enforcer(true /*is_ev*/);
+ MockCTPolicyEnforcer policy_enforcer(true /*is_ev*/);
ProofVerifierChromium proof_verifier(&dummy_verifier, &policy_enforcer,
- nullptr);
+ nullptr, ct_verifier_.get());
- scoped_ptr<ProofVerifyContext> verify_context(
- new ProofVerifyContextChromium(0 /*cert_verify_flags*/, BoundNetLog()));
- scoped_ptr<ProofVerifyDetails> details;
- std::string error_details;
-
- std::vector<std::string> certs;
- ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs));
-
- DummyProofVerifierCallback* callback = new DummyProofVerifierCallback;
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestConfig, certs, GetTestSignature(),
- verify_context.get(), &error_details, &details, callback);
+ kTestHostname, kTestConfig, certs_, "", GetTestSignature(),
+ verify_context_.get(), &error_details_, &details_, callback.get());
ASSERT_EQ(QUIC_SUCCESS, status);
- delete callback;
- ASSERT_TRUE(details.get());
+ ASSERT_TRUE(details_.get());
ProofVerifyDetailsChromium* verify_details =
- static_cast<ProofVerifyDetailsChromium*>(details.get());
+ static_cast<ProofVerifyDetailsChromium*>(details_.get());
EXPECT_EQ(dummy_result.cert_status,
verify_details->cert_verify_result.cert_status);
}
// Tests that the certificate policy enforcer is consulted for EV
// and the certificate is not allowed to be EV.
-TEST(ProofVerifierChromiumTest, StripsEVIfNotAllowed) {
+TEST_F(ProofVerifierChromiumTest, StripsEVIfNotAllowed) {
scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
ASSERT_TRUE(test_cert);
@@ -279,29 +375,21 @@ TEST(ProofVerifierChromiumTest, StripsEVIfNotAllowed) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
- MockCertPolicyEnforcer policy_enforcer(false /*is_ev*/);
+ MockCTPolicyEnforcer policy_enforcer(false /*is_ev*/);
ProofVerifierChromium proof_verifier(&dummy_verifier, &policy_enforcer,
- nullptr);
-
- scoped_ptr<ProofVerifyContext> verify_context(
- new ProofVerifyContextChromium(0 /*cert_verify_flags*/, BoundNetLog()));
- scoped_ptr<ProofVerifyDetails> details;
- std::string error_details;
+ nullptr, ct_verifier_.get());
- std::vector<std::string> certs;
- ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs));
-
- DummyProofVerifierCallback* callback = new DummyProofVerifierCallback;
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestConfig, certs, GetTestSignature(),
- verify_context.get(), &error_details, &details, callback);
+ kTestHostname, kTestConfig, certs_, "", GetTestSignature(),
+ verify_context_.get(), &error_details_, &details_, callback.get());
ASSERT_EQ(QUIC_SUCCESS, status);
- delete callback;
- ASSERT_TRUE(details.get());
+ ASSERT_TRUE(details_.get());
ProofVerifyDetailsChromium* verify_details =
- static_cast<ProofVerifyDetailsChromium*>(details.get());
+ static_cast<ProofVerifyDetailsChromium*>(details_.get());
EXPECT_EQ(CERT_STATUS_CT_COMPLIANCE_FAILED,
verify_details->cert_verify_result.cert_status &
(CERT_STATUS_CT_COMPLIANCE_FAILED | CERT_STATUS_IS_EV));
@@ -309,7 +397,7 @@ TEST(ProofVerifierChromiumTest, StripsEVIfNotAllowed) {
// Tests that the certificate policy enforcer is not consulted if
// the certificate is not EV.
-TEST(ProofVerifierChromiumTest, IgnoresPolicyEnforcerIfNotEV) {
+TEST_F(ProofVerifierChromiumTest, IgnoresPolicyEnforcerIfNotEV) {
scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
ASSERT_TRUE(test_cert);
@@ -320,29 +408,21 @@ TEST(ProofVerifierChromiumTest, IgnoresPolicyEnforcerIfNotEV) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
- FailsTestCertPolicyEnforcer policy_enforcer;
+ FailsTestCTPolicyEnforcer policy_enforcer;
ProofVerifierChromium proof_verifier(&dummy_verifier, &policy_enforcer,
- nullptr);
-
- scoped_ptr<ProofVerifyContext> verify_context(
- new ProofVerifyContextChromium(0 /*cert_verify_flags*/, BoundNetLog()));
- scoped_ptr<ProofVerifyDetails> details;
- std::string error_details;
-
- std::vector<std::string> certs;
- ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs));
+ nullptr, ct_verifier_.get());
- DummyProofVerifierCallback* callback = new DummyProofVerifierCallback;
+ scoped_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestConfig, certs, GetTestSignature(),
- verify_context.get(), &error_details, &details, callback);
+ kTestHostname, kTestConfig, certs_, "", GetTestSignature(),
+ verify_context_.get(), &error_details_, &details_, callback.get());
ASSERT_EQ(QUIC_SUCCESS, status);
- delete callback;
- ASSERT_TRUE(details.get());
+ ASSERT_TRUE(details_.get());
ProofVerifyDetailsChromium* verify_details =
- static_cast<ProofVerifyDetailsChromium*>(details.get());
+ static_cast<ProofVerifyDetailsChromium*>(details_.get());
EXPECT_EQ(0u, verify_details->cert_verify_result.cert_status);
}
diff --git a/chromium/net/quic/crypto/properties_based_quic_server_info.cc b/chromium/net/quic/crypto/properties_based_quic_server_info.cc
new file mode 100644
index 00000000000..708f44a4f4a
--- /dev/null
+++ b/chromium/net/quic/crypto/properties_based_quic_server_info.cc
@@ -0,0 +1,68 @@
+// Copyright 2015 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/crypto/properties_based_quic_server_info.h"
+
+#include "base/base64.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_server_properties.h"
+
+using std::string;
+
+namespace net {
+
+PropertiesBasedQuicServerInfo::PropertiesBasedQuicServerInfo(
+ const QuicServerId& server_id,
+ base::WeakPtr<HttpServerProperties> http_server_properties)
+ : QuicServerInfo(server_id),
+ http_server_properties_(http_server_properties) {
+ DCHECK(http_server_properties_);
+}
+
+PropertiesBasedQuicServerInfo::~PropertiesBasedQuicServerInfo() {}
+
+void PropertiesBasedQuicServerInfo::Start() {}
+
+int PropertiesBasedQuicServerInfo::WaitForDataReady(
+ const CompletionCallback& callback) {
+ const string* data = http_server_properties_->GetQuicServerInfo(server_id_);
+ string decoded;
+ if (!data || !base::Base64Decode(*data, &decoded) || !Parse(decoded)) {
+ return ERR_FAILED;
+ }
+ return OK;
+}
+
+void PropertiesBasedQuicServerInfo::ResetWaitForDataReadyCallback() {}
+
+void PropertiesBasedQuicServerInfo::CancelWaitForDataReadyCallback() {}
+
+bool PropertiesBasedQuicServerInfo::IsDataReady() {
+ return true;
+}
+
+bool PropertiesBasedQuicServerInfo::IsReadyToPersist() {
+ return true;
+}
+
+void PropertiesBasedQuicServerInfo::Persist() {
+ string encoded;
+ base::Base64Encode(Serialize(), &encoded);
+ http_server_properties_->SetQuicServerInfo(server_id_, encoded);
+}
+
+void PropertiesBasedQuicServerInfo::OnExternalCacheHit() {}
+
+PropertiesBasedQuicServerInfoFactory::PropertiesBasedQuicServerInfoFactory(
+ base::WeakPtr<HttpServerProperties> http_server_properties)
+ : http_server_properties_(http_server_properties) {}
+
+PropertiesBasedQuicServerInfoFactory::~PropertiesBasedQuicServerInfoFactory() {}
+
+QuicServerInfo* PropertiesBasedQuicServerInfoFactory::GetForServer(
+ const QuicServerId& server_id) {
+ return new PropertiesBasedQuicServerInfo(server_id, http_server_properties_);
+}
+
+} // namespace net
diff --git a/chromium/net/quic/crypto/properties_based_quic_server_info.h b/chromium/net/quic/crypto/properties_based_quic_server_info.h
new file mode 100644
index 00000000000..c7189ab4810
--- /dev/null
+++ b/chromium/net/quic/crypto/properties_based_quic_server_info.h
@@ -0,0 +1,64 @@
+// Copyright 2015 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_CRYPTO_PROPERTIES_BASED_QUIC_SERVER_INFO_H_
+#define NET_QUIC_CRYPTO_PROPERTIES_BASED_QUIC_SERVER_INFO_H_
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+#include "net/quic/crypto/quic_server_info.h"
+
+namespace net {
+
+class HttpServerProperties;
+
+// PropertiesBasedQuicServerInfo fetches information about a QUIC server from
+// HttpServerProperties. Since the information is defined to be non-sensitive,
+// it's ok for us to keep it on disk.
+class NET_EXPORT_PRIVATE PropertiesBasedQuicServerInfo : public QuicServerInfo {
+ public:
+ PropertiesBasedQuicServerInfo(
+ const QuicServerId& server_id,
+ base::WeakPtr<HttpServerProperties> http_server_properties);
+ ~PropertiesBasedQuicServerInfo() override;
+
+ // QuicServerInfo implementation.
+ void Start() override;
+ int WaitForDataReady(const CompletionCallback& callback) override;
+ void ResetWaitForDataReadyCallback() override;
+ void CancelWaitForDataReadyCallback() override;
+ bool IsDataReady() override;
+ bool IsReadyToPersist() override;
+ void Persist() override;
+ void OnExternalCacheHit() override;
+
+ private:
+ base::WeakPtr<HttpServerProperties> http_server_properties_;
+
+ DISALLOW_COPY_AND_ASSIGN(PropertiesBasedQuicServerInfo);
+};
+
+class NET_EXPORT_PRIVATE PropertiesBasedQuicServerInfoFactory
+ : public QuicServerInfoFactory {
+ public:
+ explicit PropertiesBasedQuicServerInfoFactory(
+ base::WeakPtr<HttpServerProperties> http_server_properties);
+ ~PropertiesBasedQuicServerInfoFactory() override;
+
+ QuicServerInfo* GetForServer(const QuicServerId& server_id) override;
+
+ private:
+ base::WeakPtr<HttpServerProperties> http_server_properties_;
+
+ DISALLOW_COPY_AND_ASSIGN(PropertiesBasedQuicServerInfoFactory);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CRYPTO_PROPERTIES_BASED_QUIC_SERVER_INFO_H_
diff --git a/chromium/net/quic/crypto/properties_based_quic_server_info_test.cc b/chromium/net/quic/crypto/properties_based_quic_server_info_test.cc
new file mode 100644
index 00000000000..2e9c2d371a2
--- /dev/null
+++ b/chromium/net/quic/crypto/properties_based_quic_server_info_test.cc
@@ -0,0 +1,101 @@
+// Copyright 2015 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/crypto/properties_based_quic_server_info.h"
+
+#include <string>
+
+#include "net/base/net_errors.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/quic/crypto/quic_server_info.h"
+#include "net/quic/quic_server_id.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace test {
+
+namespace {
+const std::string kServerConfigA("server_config_a");
+const std::string kSourceAddressTokenA("source_address_token_a");
+const std::string kServerConfigSigA("server_config_sig_a");
+const std::string kCertA("cert_a");
+const std::string kCertB("cert_b");
+} // namespace
+
+class PropertiesBasedQuicServerInfoTest : public ::testing::Test {
+ protected:
+ PropertiesBasedQuicServerInfoTest()
+ : server_id_("www.google.com", 443, PRIVACY_MODE_DISABLED),
+ server_info_(server_id_, http_server_properties_.GetWeakPtr()) {}
+
+ // Initialize |server_info_| object and persist it.
+ void InitializeAndPersist() {
+ server_info_.Start();
+ EXPECT_TRUE(server_info_.IsDataReady());
+ QuicServerInfo::State* state = server_info_.mutable_state();
+ EXPECT_TRUE(state->certs.empty());
+
+ state->server_config = kServerConfigA;
+ state->source_address_token = kSourceAddressTokenA;
+ state->server_config_sig = kServerConfigSigA;
+ state->certs.push_back(kCertA);
+ EXPECT_TRUE(server_info_.IsReadyToPersist());
+ server_info_.Persist();
+ EXPECT_TRUE(server_info_.IsReadyToPersist());
+ EXPECT_TRUE(server_info_.IsDataReady());
+ server_info_.OnExternalCacheHit();
+ }
+
+ // Verify the data that is persisted in InitializeAndPersist().
+ void VerifyInitialData(const QuicServerInfo::State& state) {
+ EXPECT_EQ(kServerConfigA, state.server_config);
+ EXPECT_EQ(kSourceAddressTokenA, state.source_address_token);
+ EXPECT_EQ(kServerConfigSigA, state.server_config_sig);
+ EXPECT_EQ(kCertA, state.certs[0]);
+ }
+
+ HttpServerPropertiesImpl http_server_properties_;
+ QuicServerId server_id_;
+ PropertiesBasedQuicServerInfo server_info_;
+ CompletionCallback callback_;
+};
+
+// Test persisting, reading and verifying and then updating and verifing.
+TEST_F(PropertiesBasedQuicServerInfoTest, Update) {
+ InitializeAndPersist();
+
+ // Read the persisted data and verify we have read the data correctly.
+ PropertiesBasedQuicServerInfo server_info1(
+ server_id_, http_server_properties_.GetWeakPtr());
+ server_info1.Start();
+ EXPECT_EQ(OK, server_info1.WaitForDataReady(callback_)); // Read the data.
+ EXPECT_TRUE(server_info1.IsDataReady());
+
+ // Verify the data.
+ const QuicServerInfo::State& state1 = server_info1.state();
+ EXPECT_EQ(1U, state1.certs.size());
+ VerifyInitialData(state1);
+
+ // Update the data, by adding another cert.
+ QuicServerInfo::State* state2 = server_info1.mutable_state();
+ state2->certs.push_back(kCertB);
+ EXPECT_TRUE(server_info_.IsReadyToPersist());
+ server_info1.Persist();
+
+ // Read the persisted data and verify we have read the data correctly.
+ PropertiesBasedQuicServerInfo server_info2(
+ server_id_, http_server_properties_.GetWeakPtr());
+ server_info2.Start();
+ EXPECT_EQ(OK, server_info2.WaitForDataReady(callback_)); // Read the data.
+ EXPECT_TRUE(server_info1.IsDataReady());
+
+ // Verify updated data.
+ const QuicServerInfo::State& state3 = server_info2.state();
+ VerifyInitialData(state3);
+ EXPECT_EQ(2U, state3.certs.size());
+ EXPECT_EQ(kCertB, state3.certs[1]);
+}
+
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/crypto/quic_crypto_client_config.cc b/chromium/net/quic/crypto/quic_crypto_client_config.cc
index ce48352a1d1..febb1a0e6da 100644
--- a/chromium/net/quic/crypto/quic_crypto_client_config.cc
+++ b/chromium/net/quic/crypto/quic_crypto_client_config.cc
@@ -5,11 +5,10 @@
#include "net/quic/crypto/quic_crypto_client_config.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "net/quic/crypto/cert_compressor.h"
-#include "net/quic/crypto/chacha20_poly1305_encrypter.h"
+#include "net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h"
#include "net/quic/crypto/channel_id.h"
#include "net/quic/crypto/common_cert_set.h"
#include "net/quic/crypto/crypto_framer.h"
@@ -19,6 +18,7 @@
#include "net/quic/crypto/p256_key_exchange.h"
#include "net/quic/crypto/proof_verifier.h"
#include "net/quic/crypto/quic_encrypter.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_utils.h"
using base::StringPiece;
@@ -50,8 +50,9 @@ void RecordDiskCacheServerConfigState(
} // namespace
-QuicCryptoClientConfig::QuicCryptoClientConfig()
- : disable_ecdsa_(false) {
+QuicCryptoClientConfig::QuicCryptoClientConfig(ProofVerifier* proof_verifier)
+ : proof_verifier_(proof_verifier), disable_ecdsa_(false) {
+ DCHECK(proof_verifier_.get());
SetDefaults();
}
@@ -60,8 +61,7 @@ QuicCryptoClientConfig::~QuicCryptoClientConfig() {
}
QuicCryptoClientConfig::CachedState::CachedState()
- : server_config_valid_(false),
- generation_counter_(0) {}
+ : server_config_valid_(false), generation_counter_(0) {}
QuicCryptoClientConfig::CachedState::~CachedState() {}
@@ -84,7 +84,7 @@ bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
return false;
}
- uint64 expiry_seconds;
+ uint64_t expiry_seconds;
if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
RecordInchoateClientHelloReason(SERVER_CONFIG_INVALID_EXPIRY);
return false;
@@ -138,8 +138,9 @@ bool QuicCryptoClientConfig::CachedState::has_server_nonce() const {
}
QuicCryptoClientConfig::CachedState::ServerConfigState
-QuicCryptoClientConfig::CachedState::SetServerConfig(
- StringPiece server_config, QuicWallTime now, string* error_details) {
+QuicCryptoClientConfig::CachedState::SetServerConfig(StringPiece server_config,
+ QuicWallTime now,
+ string* error_details) {
const bool matches_existing = server_config == server_config_;
// Even if the new server config matches the existing one, we still wish to
@@ -159,7 +160,7 @@ QuicCryptoClientConfig::CachedState::SetServerConfig(
return SERVER_CONFIG_INVALID;
}
- uint64 expiry_seconds;
+ uint64_t expiry_seconds;
if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
*error_details = "SCFG missing EXPY";
return SERVER_CONFIG_INVALID_EXPIRY;
@@ -187,6 +188,7 @@ void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
}
void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs,
+ StringPiece cert_sct,
StringPiece signature) {
bool has_changed =
signature != server_config_sig_ || certs_.size() != certs.size();
@@ -207,6 +209,7 @@ void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs,
// If the proof has changed then it needs to be revalidated.
SetProofInvalid();
certs_ = certs;
+ cert_sct_ = cert_sct.as_string();
server_config_sig_ = signature.as_string();
}
@@ -214,6 +217,7 @@ void QuicCryptoClientConfig::CachedState::Clear() {
server_config_.clear();
source_address_token_.clear();
certs_.clear();
+ cert_sct_.clear();
server_config_sig_.clear();
server_config_valid_ = false;
proof_verify_details_.reset();
@@ -226,6 +230,7 @@ void QuicCryptoClientConfig::CachedState::Clear() {
void QuicCryptoClientConfig::CachedState::ClearProof() {
SetProofInvalid();
certs_.clear();
+ cert_sct_.clear();
server_config_sig_.clear();
}
@@ -242,6 +247,7 @@ bool QuicCryptoClientConfig::CachedState::Initialize(
StringPiece server_config,
StringPiece source_address_token,
const vector<string>& certs,
+ const string& cert_sct,
StringPiece signature,
QuicWallTime now) {
DCHECK(server_config_.empty());
@@ -252,8 +258,7 @@ bool QuicCryptoClientConfig::CachedState::Initialize(
}
string error_details;
- ServerConfigState state = SetServerConfig(server_config, now,
- &error_details);
+ ServerConfigState state = SetServerConfig(server_config, now, &error_details);
RecordDiskCacheServerConfigState(state);
if (state != SERVER_CONFIG_VALID) {
DVLOG(1) << "SetServerConfig failed with " << error_details;
@@ -263,6 +268,7 @@ bool QuicCryptoClientConfig::CachedState::Initialize(
signature.CopyToString(&server_config_sig_);
source_address_token.CopyToString(&source_address_token_);
certs_ = certs;
+ cert_sct_ = cert_sct;
return true;
}
@@ -270,8 +276,8 @@ const string& QuicCryptoClientConfig::CachedState::server_config() const {
return server_config_;
}
-const string&
-QuicCryptoClientConfig::CachedState::source_address_token() const {
+const string& QuicCryptoClientConfig::CachedState::source_address_token()
+ const {
return source_address_token_;
}
@@ -279,6 +285,10 @@ const vector<string>& QuicCryptoClientConfig::CachedState::certs() const {
return certs_;
}
+const string& QuicCryptoClientConfig::CachedState::cert_sct() const {
+ return cert_sct_;
+}
+
const string& QuicCryptoClientConfig::CachedState::signature() const {
return server_config_sig_;
}
@@ -287,7 +297,7 @@ bool QuicCryptoClientConfig::CachedState::proof_valid() const {
return server_config_valid_;
}
-uint64 QuicCryptoClientConfig::CachedState::generation_counter() const {
+uint64_t QuicCryptoClientConfig::CachedState::generation_counter() const {
return generation_counter_;
}
@@ -301,6 +311,10 @@ void QuicCryptoClientConfig::CachedState::set_source_address_token(
source_address_token_ = token.as_string();
}
+void QuicCryptoClientConfig::CachedState::set_cert_sct(StringPiece cert_sct) {
+ cert_sct_ = cert_sct.as_string();
+}
+
void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails(
ProofVerifyDetails* details) {
proof_verify_details_.reset(details);
@@ -313,6 +327,7 @@ void QuicCryptoClientConfig::CachedState::InitializeFrom(
server_config_ = other.server_config_;
source_address_token_ = other.source_address_token_;
certs_ = other.certs_;
+ cert_sct_ = other.cert_sct_;
server_config_sig_ = other.server_config_sig_;
server_config_valid_ = other.server_config_valid_;
server_designated_connection_ids_ = other.server_designated_connection_ids_;
@@ -325,7 +340,7 @@ void QuicCryptoClientConfig::CachedState::InitializeFrom(
QuicConnectionId
QuicCryptoClientConfig::CachedState::GetNextServerDesignatedConnectionId() {
if (server_designated_connection_ids_.empty()) {
- LOG(DFATAL)
+ QUIC_BUG
<< "Attempting to consume a connection id that was never designated.";
return 0;
}
@@ -336,7 +351,7 @@ QuicCryptoClientConfig::CachedState::GetNextServerDesignatedConnectionId() {
string QuicCryptoClientConfig::CachedState::GetNextServerNonce() {
if (server_nonces_.empty()) {
- LOG(DFATAL)
+ QUIC_BUG
<< "Attempting to consume a server nonce that was never designated.";
return "";
}
@@ -351,11 +366,12 @@ void QuicCryptoClientConfig::SetDefaults() {
kexs[0] = kC255;
kexs[1] = kP256;
- // Authenticated encryption algorithms. Prefer ChaCha20 by default.
+ // Authenticated encryption algorithms. Prefer RFC 7539 ChaCha20 by default.
aead.clear();
- if (ChaCha20Poly1305Encrypter::IsSupported()) {
- aead.push_back(kCC12);
+ if (ChaCha20Poly1305Rfc7539Encrypter::IsSupported()) {
+ aead.push_back(kCC20);
}
+ aead.push_back(kCC12);
aead.push_back(kAESG);
disable_ecdsa_ = false;
@@ -404,22 +420,34 @@ void QuicCryptoClientConfig::FillInchoateClientHello(
out->SetStringPiece(kUAID, user_agent_id_);
}
+ // Even though this is an inchoate CHLO, send the SCID so that
+ // the STK can be validated by the server.
+ const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
+ if (scfg != nullptr) {
+ StringPiece scid;
+ if (scfg->GetStringPiece(kSCID, &scid)) {
+ out->SetStringPiece(kSCID, scid);
+ }
+ }
+
if (!cached->source_address_token().empty()) {
out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token());
}
- if (server_id.is_https()) {
- if (disable_ecdsa_) {
- out->SetTaglist(kPDMD, kX59R, 0);
- } else {
- out->SetTaglist(kPDMD, kX509, 0);
- }
+ if (disable_ecdsa_) {
+ out->SetTaglist(kPDMD, kX59R, 0);
+ } else {
+ out->SetTaglist(kPDMD, kX509, 0);
}
if (common_cert_sets) {
out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes());
}
+ if (preferred_version > QUIC_VERSION_29) {
+ out->SetStringPiece(kCertificateSCTTag, "");
+ }
+
const vector<string>& certs = cached->certs();
// We save |certs| in the QuicCryptoNegotiatedParameters so that, if the
// client config is being used for multiple connections, another connection
@@ -427,10 +455,10 @@ void QuicCryptoClientConfig::FillInchoateClientHello(
// process the server's compressed certificate chain.
out_params->cached_certs = certs;
if (!certs.empty()) {
- vector<uint64> hashes;
+ vector<uint64_t> hashes;
hashes.reserve(certs.size());
- for (vector<string>::const_iterator i = certs.begin();
- i != certs.end(); ++i) {
+ for (vector<string>::const_iterator i = certs.begin(); i != certs.end();
+ ++i) {
hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size()));
}
out->SetVector(kCCRT, hashes);
@@ -450,8 +478,8 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
string* error_details) const {
DCHECK(error_details != nullptr);
- FillInchoateClientHello(server_id, preferred_version, cached,
- out_params, out);
+ FillInchoateClientHello(server_id, preferred_version, cached, out_params,
+ out);
const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
if (!scfg) {
@@ -468,13 +496,17 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
}
out->SetStringPiece(kSCID, scid);
+ if (preferred_version > QUIC_VERSION_29) {
+ out->SetStringPiece(kCertificateSCTTag, "");
+ }
+
const QuicTag* their_aeads;
const QuicTag* their_key_exchanges;
size_t num_their_aeads, num_their_key_exchanges;
- if (scfg->GetTaglist(kAEAD, &their_aeads,
- &num_their_aeads) != QUIC_NO_ERROR ||
- scfg->GetTaglist(kKEXS, &their_key_exchanges,
- &num_their_key_exchanges) != QUIC_NO_ERROR) {
+ if (scfg->GetTaglist(kAEAD, &their_aeads, &num_their_aeads) !=
+ QUIC_NO_ERROR ||
+ scfg->GetTaglist(kKEXS, &their_key_exchanges, &num_their_key_exchanges) !=
+ QUIC_NO_ERROR) {
*error_details = "Missing AEAD or KEXS";
return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
}
@@ -485,9 +517,9 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
// Key exchange: the client does more work than the server, so favor the
// client's preference.
size_t key_exchange_index;
- if (!QuicUtils::FindMutualTag(
- aead, their_aeads, num_their_aeads, QuicUtils::LOCAL_PRIORITY,
- &out_params->aead, nullptr) ||
+ if (!QuicUtils::FindMutualTag(aead, their_aeads, num_their_aeads,
+ QuicUtils::LOCAL_PRIORITY, &out_params->aead,
+ nullptr) ||
!QuicUtils::FindMutualTag(
kexs, their_key_exchanges, num_their_key_exchanges,
QuicUtils::LOCAL_PRIORITY, &out_params->key_exchange,
@@ -498,9 +530,29 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
out->SetTaglist(kAEAD, out_params->aead, 0);
out->SetTaglist(kKEXS, out_params->key_exchange, 0);
+ if (!tb_key_params.empty()) {
+ const QuicTag* their_tbkps;
+ size_t num_their_tbkps;
+ switch (scfg->GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) {
+ case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+ break;
+ case QUIC_NO_ERROR:
+ if (QuicUtils::FindMutualTag(tb_key_params, their_tbkps,
+ num_their_tbkps, QuicUtils::LOCAL_PRIORITY,
+ &out_params->token_binding_key_param,
+ nullptr)) {
+ out->SetTaglist(kTBKP, out_params->token_binding_key_param, 0);
+ }
+ break;
+ default:
+ *error_details = "Invalid TBKP";
+ return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+ }
+ }
+
StringPiece public_value;
if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) !=
- QUIC_NO_ERROR) {
+ QUIC_NO_ERROR) {
*error_details = "Missing public value";
return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
}
@@ -523,8 +575,8 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
Curve25519KeyExchange::NewPrivateKey(rand)));
break;
case kP256:
- out_params->client_key_exchange.reset(P256KeyExchange::New(
- P256KeyExchange::NewPrivateKey()));
+ out_params->client_key_exchange.reset(
+ P256KeyExchange::New(P256KeyExchange::NewPrivateKey()));
break;
default:
DCHECK(false);
@@ -540,7 +592,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value());
const vector<string>& certs = cached->certs();
- if (preferred_version > QUIC_VERSION_25 && proof_verifier()) {
+ if (preferred_version > QUIC_VERSION_25) {
if (certs.empty()) {
*error_details = "No certs to calculate XLCT";
return QUIC_CRYPTO_INTERNAL_ERROR;
@@ -617,7 +669,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
out_params->hkdf_input_suffix.append(client_hello_serialized.data(),
client_hello_serialized.length());
out_params->hkdf_input_suffix.append(cached->server_config());
- if (preferred_version > QUIC_VERSION_25 && proof_verifier()) {
+ if (preferred_version > QUIC_VERSION_25) {
if (certs.empty()) {
*error_details = "No certs found to include in KDF";
return QUIC_CRYPTO_INTERNAL_ERROR;
@@ -646,6 +698,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
const CryptoHandshakeMessage& message,
QuicWallTime now,
+ const QuicVersion version,
const vector<string>& cached_certs,
CachedState* cached,
string* error_details) {
@@ -657,8 +710,8 @@ QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
}
- CachedState::ServerConfigState state = cached->SetServerConfig(
- scfg, now, error_details);
+ CachedState::ServerConfigState state =
+ cached->SetServerConfig(scfg, now, error_details);
if (state == CachedState::SERVER_CONFIG_EXPIRED) {
return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
}
@@ -673,7 +726,7 @@ QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
cached->set_source_address_token(token);
}
- StringPiece proof, cert_bytes;
+ StringPiece proof, cert_bytes, cert_sct;
bool has_proof = message.GetStringPiece(kPROF, &proof);
bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes);
if (has_proof && has_cert) {
@@ -684,13 +737,14 @@ QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
}
- cached->SetProof(certs, proof);
- } else {
- if (proof_verifier() != nullptr) {
- // Secure QUIC: clear existing proof as we have been sent a new SCFG
- // without matching proof/certs.
- cached->ClearProof();
+ if (version > QUIC_VERSION_29) {
+ message.GetStringPiece(kCertificateSCTTag, &cert_sct);
}
+ cached->SetProof(certs, cert_sct, proof);
+ } else {
+ // Secure QUIC: clear existing proof as we have been sent a new SCFG
+ // without matching proof/certs.
+ cached->ClearProof();
if (has_proof && !has_cert) {
*error_details = "Certificate missing";
@@ -709,8 +763,8 @@ QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
const CryptoHandshakeMessage& rej,
QuicWallTime now,
+ const QuicVersion version,
CachedState* cached,
- bool is_https,
QuicCryptoNegotiatedParameters* out_params,
string* error_details) {
DCHECK(error_details != nullptr);
@@ -720,8 +774,8 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
return QUIC_CRYPTO_INTERNAL_ERROR;
}
- QuicErrorCode error = CacheNewServerConfig(rej, now, out_params->cached_certs,
- cached, error_details);
+ QuicErrorCode error = CacheNewServerConfig(
+ rej, now, version, out_params->cached_certs, cached, error_details);
if (error != QUIC_NO_ERROR) {
return error;
}
@@ -731,31 +785,6 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
out_params->server_nonce = nonce.as_string();
}
- const uint32* reject_reasons;
- size_t num_reject_reasons;
- static_assert(sizeof(QuicTag) == sizeof(uint32), "header out of sync");
- if (rej.GetTaglist(kRREJ, &reject_reasons,
- &num_reject_reasons) == QUIC_NO_ERROR) {
- uint32 packed_error = 0;
- for (size_t i = 0; i < num_reject_reasons; ++i) {
- // HANDSHAKE_OK is 0 and don't report that as error.
- if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
- continue;
- }
- HandshakeFailureReason reason =
- static_cast<HandshakeFailureReason>(reject_reasons[i]);
- packed_error |= 1 << (reason - 1);
- }
- DVLOG(1) << "Reasons for rejection: " << packed_error;
- if (is_https) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Secure",
- packed_error);
- } else {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Insecure",
- packed_error);
- }
- }
-
if (rej.tag() == kSREJ) {
QuicConnectionId connection_id;
if (rej.GetUint64(kRCID, &connection_id) != QUIC_NO_ERROR) {
@@ -775,38 +804,17 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
const CryptoHandshakeMessage& server_hello,
QuicConnectionId connection_id,
+ QuicVersion version,
const QuicVersionVector& negotiated_versions,
CachedState* cached,
QuicCryptoNegotiatedParameters* out_params,
string* error_details) {
DCHECK(error_details != nullptr);
- if (server_hello.tag() != kSHLO) {
- *error_details = "Bad tag";
- return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
- }
-
- const QuicTag* supported_version_tags;
- size_t num_supported_versions;
-
- if (server_hello.GetTaglist(kVER, &supported_version_tags,
- &num_supported_versions) != QUIC_NO_ERROR) {
- *error_details = "server hello missing version list";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
- if (!negotiated_versions.empty()) {
- bool mismatch = num_supported_versions != negotiated_versions.size();
- for (size_t i = 0; i < num_supported_versions && !mismatch; ++i) {
- mismatch = QuicTagToQuicVersion(supported_version_tags[i]) !=
- negotiated_versions[i];
- }
- // The server sent a list of supported versions, and the connection
- // reports that there was a version negotiation during the handshake.
- // Ensure that these two lists are identical.
- if (mismatch) {
- *error_details = "Downgrade attack detected";
- return QUIC_VERSION_NEGOTIATION_MISMATCH;
- }
+ QuicErrorCode valid = CryptoUtils::ValidateServerHello(
+ server_hello, negotiated_versions, error_details);
+ if (valid != QUIC_NO_ERROR) {
+ return valid;
}
// Learn about updated source address tokens.
@@ -815,6 +823,13 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
cached->set_source_address_token(token);
}
+ StringPiece shlo_nonce;
+ if (version > QUIC_VERSION_26 &&
+ !server_hello.GetStringPiece(kServerNonceTag, &shlo_nonce)) {
+ *error_details = "server hello missing server nonce";
+ return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+ }
+
// TODO(agl):
// learn about updated SCFGs.
@@ -838,9 +853,10 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
if (!CryptoUtils::DeriveKeys(
out_params->forward_secure_premaster_secret, out_params->aead,
- out_params->client_nonce, out_params->server_nonce, hkdf_input,
- Perspective::IS_CLIENT, &out_params->forward_secure_crypters,
- &out_params->subkey_secret)) {
+ out_params->client_nonce,
+ shlo_nonce.empty() ? out_params->server_nonce : shlo_nonce,
+ hkdf_input, Perspective::IS_CLIENT,
+ &out_params->forward_secure_crypters, &out_params->subkey_secret)) {
*error_details = "Symmetric key setup failed";
return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
}
@@ -851,6 +867,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate(
const CryptoHandshakeMessage& server_config_update,
QuicWallTime now,
+ const QuicVersion version,
CachedState* cached,
QuicCryptoNegotiatedParameters* out_params,
string* error_details) {
@@ -860,8 +877,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate(
*error_details = "ServerConfigUpdate must have kSCUP tag.";
return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
}
-
- return CacheNewServerConfig(server_config_update, now,
+ return CacheNewServerConfig(server_config_update, now, version,
out_params->cached_certs, cached, error_details);
}
@@ -869,10 +885,6 @@ ProofVerifier* QuicCryptoClientConfig::proof_verifier() const {
return proof_verifier_.get();
}
-void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) {
- proof_verifier_.reset(verifier);
-}
-
ChannelIDSource* QuicCryptoClientConfig::channel_id_source() const {
return channel_id_source_.get();
}
@@ -930,7 +942,6 @@ bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
}
QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(),
- server_id.is_https(),
server_id.privacy_mode());
if (!ContainsKey(canonical_server_map_, suffix_server_id)) {
// This is the first host we've seen which matches the suffix, so make it
diff --git a/chromium/net/quic/crypto/quic_crypto_client_config.h b/chromium/net/quic/crypto/quic_crypto_client_config.h
index 5df84032093..34be5484c07 100644
--- a/chromium/net/quic/crypto/quic_crypto_client_config.h
+++ b/chromium/net/quic/crypto/quic_crypto_client_config.h
@@ -5,11 +5,14 @@
#ifndef NET_QUIC_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
#define NET_QUIC_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
+#include <stdint.h>
+
#include <map>
#include <queue>
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -82,6 +85,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
// SetProof stores a certificate chain and signature.
void SetProof(const std::vector<std::string>& certs,
+ base::StringPiece cert_sct,
base::StringPiece signature);
// Clears all the data.
@@ -103,13 +107,16 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
const std::string& server_config() const;
const std::string& source_address_token() const;
const std::vector<std::string>& certs() const;
+ const std::string& cert_sct() const;
const std::string& signature() const;
bool proof_valid() const;
- uint64 generation_counter() const;
+ uint64_t generation_counter() const;
const ProofVerifyDetails* proof_verify_details() const;
void set_source_address_token(base::StringPiece token);
+ void set_cert_sct(base::StringPiece cert_sct);
+
// Adds the connection ID to the queue of server-designated connection-ids.
void add_server_designated_connection_id(QuicConnectionId connection_id);
@@ -150,6 +157,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
bool Initialize(base::StringPiece server_config,
base::StringPiece source_address_token,
const std::vector<std::string>& certs,
+ const std::string& cert_sct,
base::StringPiece signature,
QuicWallTime now);
@@ -158,6 +166,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
std::string source_address_token_; // An opaque proof of IP ownership.
std::vector<std::string> certs_; // A list of certificates in leaf-first
// order.
+ std::string cert_sct_; // Signed timestamp of the leaf cert.
std::string server_config_sig_; // A signature of |server_config_|.
bool server_config_valid_; // True if |server_config_| is correctly
// signed and |certs_| has been
@@ -165,7 +174,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
// Generation counter associated with the |server_config_|, |certs_| and
// |server_config_sig_| combination. It is incremented whenever we set
// server_config_valid_ to false.
- uint64 generation_counter_;
+ uint64_t generation_counter_;
scoped_ptr<ProofVerifyDetails> proof_verify_details_;
@@ -181,7 +190,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
DISALLOW_COPY_AND_ASSIGN(CachedState);
};
- QuicCryptoClientConfig();
+ explicit QuicCryptoClientConfig(ProofVerifier* proof_verifier);
~QuicCryptoClientConfig();
// LookupOrCreate returns a CachedState for the given |server_id|. If no such
@@ -234,12 +243,11 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
// true for that server's CachedState. If the rejection message contains state
// about a future handshake (i.e. an nonce value from the server), then it
// will be saved in |out_params|. |now| is used to judge whether the server
- // config in the rejection message has expired. |is_https| is used to track
- // reject reason for secure vs insecure QUIC.
+ // config in the rejection message has expired.
QuicErrorCode ProcessRejection(const CryptoHandshakeMessage& rej,
QuicWallTime now,
+ QuicVersion version,
CachedState* cached,
- bool is_https,
QuicCryptoNegotiatedParameters* out_params,
std::string* error_details);
@@ -247,12 +255,14 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
// cached information about that server, writes the negotiated parameters to
// |out_params| and returns QUIC_NO_ERROR. If |server_hello| is unacceptable
// then it puts an error message in |error_details| and returns an error
- // code. |negotiated_versions| contains the list of version, if any, that were
+ // code. |version| is the QUIC version for the current connection.
+ // |negotiated_versions| contains the list of version, if any, that were
// present in a version negotiation packet previously recevied from the
// server. The contents of this list will be compared against the list of
// versions provided in the VER tag of the server hello.
QuicErrorCode ProcessServerHello(const CryptoHandshakeMessage& server_hello,
QuicConnectionId connection_id,
+ QuicVersion version,
const QuicVersionVector& negotiated_versions,
CachedState* cached,
QuicCryptoNegotiatedParameters* out_params,
@@ -266,18 +276,13 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
QuicErrorCode ProcessServerConfigUpdate(
const CryptoHandshakeMessage& server_update,
QuicWallTime now,
+ const QuicVersion version,
CachedState* cached,
QuicCryptoNegotiatedParameters* out_params,
std::string* error_details);
ProofVerifier* proof_verifier() const;
- // SetProofVerifier takes ownership of a |ProofVerifier| that clients are
- // free to use in order to verify certificate chains from servers. If a
- // ProofVerifier is set then the client will request a certificate chain from
- // the server.
- void SetProofVerifier(ProofVerifier* verifier);
-
ChannelIDSource* channel_id_source() const;
// SetChannelIDSource sets a ChannelIDSource that will be called, when the
@@ -327,6 +332,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
QuicErrorCode CacheNewServerConfig(
const CryptoHandshakeMessage& message,
QuicWallTime now,
+ const QuicVersion version,
const std::vector<std::string>& cached_certs,
CachedState* cached,
std::string* error_details);
diff --git a/chromium/net/quic/crypto/quic_crypto_client_config_test.cc b/chromium/net/quic/crypto/quic_crypto_client_config_test.cc
index 804a96316f5..2e6866ccb64 100644
--- a/chromium/net/quic/crypto/quic_crypto_client_config_test.cc
+++ b/chromium/net/quic/crypto/quic_crypto_client_config_test.cc
@@ -152,12 +152,12 @@ TEST(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
TEST(QuicCryptoClientConfigTest, InchoateChlo) {
QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
QuicCryptoNegotiatedParameters params;
CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 80, false, PRIVACY_MODE_DISABLED);
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state,
- &params, &msg);
+ QuicServerId server_id("www.google.com", 80, PRIVACY_MODE_DISABLED);
+ config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &params,
+ &msg);
QuicTag cver;
EXPECT_EQ(QUIC_NO_ERROR, msg.GetUint32(kVER, &cver));
@@ -165,7 +165,7 @@ TEST(QuicCryptoClientConfigTest, InchoateChlo) {
}
TEST(QuicCryptoClientConfigTest, PreferAesGcm) {
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
if (config.aead.size() > 1)
EXPECT_NE(kAESG, config.aead[0]);
config.PreferAesGcm();
@@ -174,27 +174,52 @@ TEST(QuicCryptoClientConfigTest, PreferAesGcm) {
TEST(QuicCryptoClientConfigTest, InchoateChloSecure) {
QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
QuicCryptoNegotiatedParameters params;
CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state,
- &params, &msg);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
+ config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &params,
+ &msg);
QuicTag pdmd;
EXPECT_EQ(QUIC_NO_ERROR, msg.GetUint32(kPDMD, &pdmd));
EXPECT_EQ(kX509, pdmd);
+ StringPiece scid;
+ EXPECT_FALSE(msg.GetStringPiece(kSCID, &scid));
+}
+
+TEST(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
+ QuicCryptoClientConfig::CachedState state;
+ CryptoHandshakeMessage scfg;
+ scfg.set_tag(kSCFG);
+ uint64_t future = 1;
+ scfg.SetValue(kEXPY, future);
+ scfg.SetStringPiece(kSCID, "12345678");
+ string details;
+ state.SetServerConfig(scfg.GetSerialized().AsStringPiece(),
+ QuicWallTime::FromUNIXSeconds(0), &details);
+
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ QuicCryptoNegotiatedParameters params;
+ CryptoHandshakeMessage msg;
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
+ config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &params,
+ &msg);
+
+ StringPiece scid;
+ EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
+ EXPECT_EQ("12345678", scid);
}
TEST(QuicCryptoClientConfigTest, InchoateChloSecureNoEcdsa) {
QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
config.DisableEcdsa();
QuicCryptoNegotiatedParameters params;
CryptoHandshakeMessage msg;
- QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED);
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state,
- &params, &msg);
+ QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
+ config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &params,
+ &msg);
QuicTag pdmd;
EXPECT_EQ(QUIC_NO_ERROR, msg.GetUint32(kPDMD, &pdmd));
@@ -203,23 +228,17 @@ TEST(QuicCryptoClientConfigTest, InchoateChloSecureNoEcdsa) {
TEST(QuicCryptoClientConfigTest, FillClientHello) {
QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
QuicCryptoNegotiatedParameters params;
QuicConnectionId kConnectionId = 1234;
string error_details;
MockRandom rand;
CryptoHandshakeMessage chlo;
- QuicServerId server_id("www.google.com", 80, false, PRIVACY_MODE_DISABLED);
- config.FillClientHello(server_id,
- kConnectionId,
- QuicVersionMax(),
- &state,
- QuicWallTime::Zero(),
- &rand,
+ QuicServerId server_id("www.google.com", 80, PRIVACY_MODE_DISABLED);
+ config.FillClientHello(server_id, kConnectionId, QuicVersionMax(), &state,
+ QuicWallTime::Zero(), &rand,
nullptr, // channel_id_key
- &params,
- &chlo,
- &error_details);
+ &params, &chlo, &error_details);
// Verify that certain QuicTags have been set correctly in the CHLO.
QuicTag cver;
@@ -245,25 +264,24 @@ TEST(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
QuicCryptoClientConfig::CachedState cached;
QuicCryptoNegotiatedParameters out_params;
string error;
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
EXPECT_EQ(QUIC_VERSION_NEGOTIATION_MISMATCH,
- config.ProcessServerHello(msg, 0, supported_versions,
- &cached, &out_params, &error));
+ config.ProcessServerHello(msg, 0, supported_versions.front(),
+ supported_versions, &cached, &out_params,
+ &error));
EXPECT_EQ("Downgrade attack detected", error);
}
TEST(QuicCryptoClientConfigTest, InitializeFrom) {
- QuicCryptoClientConfig config;
- QuicServerId canonical_server_id("www.google.com", 80, false,
- PRIVACY_MODE_DISABLED);
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ QuicServerId canonical_server_id("www.google.com", 80, PRIVACY_MODE_DISABLED);
QuicCryptoClientConfig::CachedState* state =
config.LookupOrCreate(canonical_server_id);
// TODO(rch): Populate other fields of |state|.
state->set_source_address_token("TOKEN");
state->SetProofValid();
- QuicServerId other_server_id("mail.google.com", 80, false,
- PRIVACY_MODE_DISABLED);
+ QuicServerId other_server_id("mail.google.com", 80, PRIVACY_MODE_DISABLED);
config.InitializeFrom(other_server_id, canonical_server_id, &config);
QuicCryptoClientConfig::CachedState* other =
config.LookupOrCreate(other_server_id);
@@ -275,12 +293,10 @@ TEST(QuicCryptoClientConfigTest, InitializeFrom) {
}
TEST(QuicCryptoClientConfigTest, Canonical) {
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
config.AddCanonicalSuffix(".google.com");
- QuicServerId canonical_id1("www.google.com", 80, false,
- PRIVACY_MODE_DISABLED);
- QuicServerId canonical_id2("mail.google.com", 80, false,
- PRIVACY_MODE_DISABLED);
+ QuicServerId canonical_id1("www.google.com", 80, PRIVACY_MODE_DISABLED);
+ QuicServerId canonical_id2("mail.google.com", 80, PRIVACY_MODE_DISABLED);
QuicCryptoClientConfig::CachedState* state =
config.LookupOrCreate(canonical_id1);
// TODO(rch): Populate other fields of |state|.
@@ -296,18 +312,15 @@ TEST(QuicCryptoClientConfigTest, Canonical) {
EXPECT_EQ(state->certs(), other->certs());
EXPECT_EQ(1u, other->generation_counter());
- QuicServerId different_id("mail.google.org", 80, false,
- PRIVACY_MODE_DISABLED);
+ QuicServerId different_id("mail.google.org", 80, PRIVACY_MODE_DISABLED);
EXPECT_TRUE(config.LookupOrCreate(different_id)->IsEmpty());
}
TEST(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
- QuicCryptoClientConfig config;
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
config.AddCanonicalSuffix(".google.com");
- QuicServerId canonical_id1("www.google.com", 80, false,
- PRIVACY_MODE_DISABLED);
- QuicServerId canonical_id2("mail.google.com", 80, false,
- PRIVACY_MODE_DISABLED);
+ QuicServerId canonical_id1("www.google.com", 80, PRIVACY_MODE_DISABLED);
+ QuicServerId canonical_id2("mail.google.com", 80, PRIVACY_MODE_DISABLED);
QuicCryptoClientConfig::CachedState* state =
config.LookupOrCreate(canonical_id1);
// TODO(rch): Populate other fields of |state|.
@@ -319,13 +332,13 @@ TEST(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
}
TEST(QuicCryptoClientConfigTest, ClearCachedStates) {
- QuicCryptoClientConfig config;
- QuicServerId server_id("www.google.com", 80, false, PRIVACY_MODE_DISABLED);
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ QuicServerId server_id("www.google.com", 80, PRIVACY_MODE_DISABLED);
QuicCryptoClientConfig::CachedState* state = config.LookupOrCreate(server_id);
// TODO(rch): Populate other fields of |state|.
vector<string> certs(1);
certs[0] = "Hello Cert";
- state->SetProof(certs, "signature");
+ state->SetProof(certs, "cert_sct", "signature");
state->set_source_address_token("TOKEN");
state->SetProofValid();
EXPECT_EQ(1u, state->generation_counter());
@@ -347,6 +360,7 @@ TEST(QuicCryptoClientConfigTest, ClearCachedStates) {
EXPECT_FALSE(cleared_cache->proof_valid());
EXPECT_TRUE(cleared_cache->server_config().empty());
EXPECT_TRUE(cleared_cache->certs().empty());
+ EXPECT_TRUE(cleared_cache->cert_sct().empty());
EXPECT_TRUE(cleared_cache->signature().empty());
EXPECT_EQ(2u, cleared_cache->generation_counter());
}
@@ -359,11 +373,11 @@ TEST(QuicCryptoClientConfigTest, ProcessReject) {
QuicCryptoClientConfig::CachedState cached;
QuicCryptoNegotiatedParameters out_params;
string error;
- QuicCryptoClientConfig config;
- EXPECT_EQ(QUIC_NO_ERROR, config.ProcessRejection(
- rej, QuicWallTime::FromUNIXSeconds(0), &cached,
- true, // is_https
- &out_params, &error));
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ EXPECT_EQ(QUIC_NO_ERROR,
+ config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0),
+ QuicSupportedVersions().front(), &cached,
+ &out_params, &error));
EXPECT_FALSE(cached.has_server_designated_connection_id());
EXPECT_FALSE(cached.has_server_nonce());
}
@@ -381,11 +395,11 @@ TEST(QuicCryptoClientConfigTest, ProcessStatelessReject) {
QuicCryptoClientConfig::CachedState cached;
QuicCryptoNegotiatedParameters out_params;
string error;
- QuicCryptoClientConfig config;
- EXPECT_EQ(QUIC_NO_ERROR, config.ProcessRejection(
- rej, QuicWallTime::FromUNIXSeconds(0), &cached,
- true, // is_https
- &out_params, &error));
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ EXPECT_EQ(QUIC_NO_ERROR,
+ config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0),
+ QuicSupportedVersions().front(), &cached,
+ &out_params, &error));
EXPECT_TRUE(cached.has_server_designated_connection_id());
EXPECT_EQ(kConnectionId, cached.GetNextServerDesignatedConnectionId());
EXPECT_EQ(server_nonce, cached.GetNextServerNonce());
@@ -401,15 +415,61 @@ TEST(QuicCryptoClientConfigTest, BadlyFormattedStatelessReject) {
QuicCryptoClientConfig::CachedState cached;
QuicCryptoNegotiatedParameters out_params;
string error;
- QuicCryptoClientConfig config;
- EXPECT_EQ(
- QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND,
- config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), &cached,
- true, // is_https
- &out_params, &error));
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND,
+ config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0),
+ QuicSupportedVersions().front(), &cached,
+ &out_params, &error));
EXPECT_FALSE(cached.has_server_designated_connection_id());
EXPECT_EQ("Missing kRCID", error);
}
+TEST(QuicCryptoClientConfigTest, ServerNonceinSHLO_BeforeQ027) {
+ // Test that in QUIC_VERSION_26 and lower, the the server does not need to
+ // include a nonce in the SHLO.
+ CryptoHandshakeMessage msg;
+ msg.set_tag(kSHLO);
+ // Choose the lowest version.
+ QuicVersionVector supported_versions;
+ QuicVersion version = QuicSupportedVersions().back();
+ supported_versions.push_back(version);
+ EXPECT_LE(version, QUIC_VERSION_26);
+ QuicTagVector versions;
+ versions.push_back(QuicVersionToQuicTag(version));
+ msg.SetVector(kVER, versions);
+
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ QuicCryptoClientConfig::CachedState cached;
+ QuicCryptoNegotiatedParameters out_params;
+ string error_details;
+ config.ProcessServerHello(msg, 0, version, supported_versions, &cached,
+ &out_params, &error_details);
+ EXPECT_NE("server hello missing server nonce", error_details);
+}
+
+TEST(QuicCryptoClientConfigTest, ServerNonceinSHLO_AfterQ027) {
+ // Test that in QUIC_VERSION_27 and higher, the the server must include a
+ // nonce in the SHLO.
+ CryptoHandshakeMessage msg;
+ msg.set_tag(kSHLO);
+ // Choose the latest version.
+ QuicVersionVector supported_versions;
+ QuicVersion version = QuicSupportedVersions().front();
+ supported_versions.push_back(version);
+ EXPECT_LE(QUIC_VERSION_27, version);
+ QuicTagVector versions;
+ versions.push_back(QuicVersionToQuicTag(version));
+ msg.SetVector(kVER, versions);
+
+ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting());
+ QuicCryptoClientConfig::CachedState cached;
+ QuicCryptoNegotiatedParameters out_params;
+ string error_details;
+ EXPECT_EQ(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+ config.ProcessServerHello(msg, 0, version, supported_versions,
+ &cached, &out_params, &error_details));
+ EXPECT_EQ("server hello missing server nonce", error_details);
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/crypto/quic_crypto_server_config.cc b/chromium/net/quic/crypto/quic_crypto_server_config.cc
index b8c6c7367cc..f2475bad3cb 100644
--- a/chromium/net/quic/crypto/quic_crypto_server_config.cc
+++ b/chromium/net/quic/crypto/quic_crypto_server_config.cc
@@ -5,8 +5,10 @@
#include "net/quic/crypto/quic_crypto_server_config.h"
#include <stdlib.h>
+
#include <algorithm>
+#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/hkdf.h"
@@ -15,7 +17,7 @@
#include "net/quic/crypto/aes_128_gcm_12_decrypter.h"
#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
#include "net/quic/crypto/cert_compressor.h"
-#include "net/quic/crypto/chacha20_poly1305_encrypter.h"
+#include "net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h"
#include "net/quic/crypto/channel_id.h"
#include "net/quic/crypto/crypto_framer.h"
#include "net/quic/crypto/crypto_handshake_message.h"
@@ -50,14 +52,18 @@ namespace net {
namespace {
+// kMultiplier is the multiple of the CHLO message size that a REJ message
+// must stay under when the client doesn't present a valid source-address
+// token. This is used to protect QUIC from amplification attacks.
+// TODO(rch): Reduce this to 2 again once b/25933682 is fixed.
+const size_t kMultiplier = 3;
+
const int kMaxTokenAddresses = 4;
string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) {
- crypto::HKDF hkdf(source_address_token_secret,
- StringPiece() /* no salt */,
+ crypto::HKDF hkdf(source_address_token_secret, StringPiece() /* no salt */,
"QUIC source address token key",
- CryptoSecretBoxer::GetKeySize(),
- 0 /* no fixed IV needed */,
+ CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */,
0 /* no subkey secret */);
return hkdf.server_write_key().as_string();
}
@@ -75,8 +81,7 @@ class ValidateClientHelloHelper {
public:
ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result,
ValidateClientHelloResultCallback* done_cb)
- : result_(result), done_cb_(done_cb) {
- }
+ : result_(result), done_cb_(done_cb) {}
~ValidateClientHelloHelper() {
LOG_IF(DFATAL, done_cb_ != nullptr)
@@ -90,9 +95,7 @@ class ValidateClientHelloHelper {
DetachCallback();
}
- void StartedAsyncCallback() {
- DetachCallback();
- }
+ void StartedAsyncCallback() { DetachCallback(); }
private:
void DetachCallback() {
@@ -112,15 +115,13 @@ class VerifyNonceIsValidAndUniqueCallback
VerifyNonceIsValidAndUniqueCallback(
ValidateClientHelloResultCallback::Result* result,
ValidateClientHelloResultCallback* done_cb)
- : result_(result), done_cb_(done_cb) {
- }
+ : result_(result), done_cb_(done_cb) {}
protected:
void RunImpl(bool nonce_is_valid_and_unique,
InsertStatus nonce_error) override {
DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique
<< " nonce_error: " << nonce_error;
- result_->info.unique = nonce_is_valid_and_unique;
if (!nonce_is_valid_and_unique) {
HandshakeFailureReason client_nonce_error;
switch (nonce_error) {
@@ -168,21 +169,13 @@ const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
ClientHelloInfo::ClientHelloInfo(const IPAddressNumber& in_client_ip,
QuicWallTime in_now)
- : client_ip(in_client_ip),
- now(in_now),
- valid_source_address_token(false),
- client_nonce_well_formed(false),
- unique(false) {
-}
+ : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {}
-ClientHelloInfo::~ClientHelloInfo() {
-}
+ClientHelloInfo::~ClientHelloInfo() {}
-PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {
-}
+PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {}
-PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {
-}
+PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {}
ValidateClientHelloResultCallback::Result::Result(
const CryptoHandshakeMessage& in_client_hello,
@@ -190,17 +183,13 @@ ValidateClientHelloResultCallback::Result::Result(
QuicWallTime in_now)
: client_hello(in_client_hello),
info(in_client_ip, in_now),
- error_code(QUIC_NO_ERROR) {
-}
+ error_code(QUIC_NO_ERROR) {}
-ValidateClientHelloResultCallback::Result::~Result() {
-}
+ValidateClientHelloResultCallback::Result::~Result() {}
-ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {
-}
+ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {}
-ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {
-}
+ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {}
void ValidateClientHelloResultCallback::Run(const Result* result) {
RunImpl(result->client_hello, *result);
@@ -211,31 +200,38 @@ void ValidateClientHelloResultCallback::Run(const Result* result) {
QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
: expiry_time(QuicWallTime::Zero()),
channel_id_enabled(false),
+ token_binding_enabled(false),
p256(false) {}
QuicCryptoServerConfig::QuicCryptoServerConfig(
StringPiece source_address_token_secret,
- QuicRandom* rand)
+ QuicRandom* server_nonce_entropy,
+ ProofSource* proof_source)
: replay_protection_(true),
+ chlo_multiplier_(kMultiplier),
configs_lock_(),
primary_config_(nullptr),
next_config_promotion_time_(QuicWallTime::Zero()),
server_nonce_strike_register_lock_(),
+ proof_source_(proof_source),
strike_register_no_startup_period_(false),
strike_register_max_entries_(1 << 10),
strike_register_window_secs_(600),
source_address_token_future_secs_(3600),
source_address_token_lifetime_secs_(86400),
server_nonce_strike_register_max_entries_(1 << 10),
- server_nonce_strike_register_window_secs_(120) {
+ server_nonce_strike_register_window_secs_(120),
+ enable_serving_sct_(false) {
+ DCHECK(proof_source_.get());
default_source_address_token_boxer_.SetKey(
DeriveSourceAddressTokenKey(source_address_token_secret));
// Generate a random key and orbit for server nonces.
- rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_));
+ server_nonce_entropy->RandBytes(server_nonce_orbit_,
+ sizeof(server_nonce_orbit_));
const size_t key_size = server_nonce_boxer_.GetKeySize();
- scoped_ptr<uint8[]> key_bytes(new uint8[key_size]);
- rand->RandBytes(key_bytes.get(), key_size);
+ scoped_ptr<uint8_t[]> key_bytes(new uint8_t[key_size]);
+ server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
server_nonce_boxer_.SetKey(
StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size));
@@ -293,10 +289,11 @@ QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig(
} else {
msg.SetTaglist(kKEXS, kC255, 0);
}
- if (ChaCha20Poly1305Encrypter::IsSupported()) {
- msg.SetTaglist(kAEAD, kAESG, kCC12, 0);
+ if (FLAGS_quic_use_rfc7539 &&
+ ChaCha20Poly1305Rfc7539Encrypter::IsSupported()) {
+ msg.SetTaglist(kAEAD, kAESG, kCC12, kCC20, 0);
} else {
- msg.SetTaglist(kAEAD, kAESG, 0);
+ msg.SetTaglist(kAEAD, kAESG, kCC12, 0);
}
msg.SetStringPiece(kPUBS, encoded_public_values);
@@ -304,7 +301,7 @@ QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig(
const QuicWallTime now = clock->WallNow();
const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds(
60 * 60 * 24 * 180 /* 180 days, ~six months */));
- const uint64 expiry_seconds = expiry.ToUNIXSeconds();
+ const uint64_t expiry_seconds = expiry.ToUNIXSeconds();
msg.SetValue(kEXPY, expiry_seconds);
} else {
msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds());
@@ -323,6 +320,10 @@ QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig(
msg.SetTaglist(kPDMD, kCHID, 0);
}
+ if (options.token_binding_enabled) {
+ msg.SetTaglist(kTBKP, kP256, 0);
+ }
+
if (options.id.empty()) {
// We need to ensure that the SCID changes whenever the server config does
// thus we make it a hash of the rest of the server config.
@@ -405,7 +406,7 @@ CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig(
bool QuicCryptoServerConfig::SetConfigs(
const vector<QuicServerConfigProtobuf*>& protobufs,
const QuicWallTime now) {
- vector<scoped_refptr<Config> > parsed_configs;
+ vector<scoped_refptr<Config>> parsed_configs;
bool ok = true;
for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin();
@@ -432,31 +433,32 @@ bool QuicCryptoServerConfig::SetConfigs(
base::AutoLock locked(configs_lock_);
ConfigMap new_configs;
- for (vector<scoped_refptr<Config> >::const_iterator i =
+ for (vector<scoped_refptr<Config>>::const_iterator i =
parsed_configs.begin();
i != parsed_configs.end(); ++i) {
scoped_refptr<Config> config = *i;
ConfigMap::iterator it = configs_.find(config->id);
if (it != configs_.end()) {
- VLOG(1)
- << "Keeping scid: " << base::HexEncode(
- config->id.data(), config->id.size())
- << " orbit: " << base::HexEncode(
- reinterpret_cast<const char *>(config->orbit), kOrbitSize)
- << " new primary_time " << config->primary_time.ToUNIXSeconds()
- << " old primary_time " << it->second->primary_time.ToUNIXSeconds()
- << " new priority " << config->priority
- << " old priority " << it->second->priority;
+ VLOG(1) << "Keeping scid: "
+ << base::HexEncode(config->id.data(), config->id.size())
+ << " orbit: "
+ << base::HexEncode(reinterpret_cast<const char*>(config->orbit),
+ kOrbitSize)
+ << " new primary_time " << config->primary_time.ToUNIXSeconds()
+ << " old primary_time "
+ << it->second->primary_time.ToUNIXSeconds() << " new priority "
+ << config->priority << " old priority " << it->second->priority;
// Update primary_time and priority.
it->second->primary_time = config->primary_time;
it->second->priority = config->priority;
new_configs.insert(*it);
} else {
- VLOG(1) << "Adding scid: " << base::HexEncode(
- config->id.data(), config->id.size())
- << " orbit: " << base::HexEncode(
- reinterpret_cast<const char *>(config->orbit), kOrbitSize)
+ VLOG(1) << "Adding scid: "
+ << base::HexEncode(config->id.data(), config->id.size())
+ << " orbit: "
+ << base::HexEncode(reinterpret_cast<const char*>(config->orbit),
+ kOrbitSize)
<< " primary_time " << config->primary_time.ToUNIXSeconds()
<< " priority " << config->priority;
new_configs.insert(std::make_pair(config->id, config));
@@ -474,8 +476,8 @@ bool QuicCryptoServerConfig::SetConfigs(
void QuicCryptoServerConfig::GetConfigIds(vector<string>* scids) const {
base::AutoLock locked(configs_lock_);
- for (ConfigMap::const_iterator it = configs_.begin();
- it != configs_.end(); ++it) {
+ for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end();
+ ++it) {
scids->push_back(it->first);
}
}
@@ -491,14 +493,15 @@ void QuicCryptoServerConfig::ValidateClientHello(
const QuicWallTime now(clock->WallNow());
ValidateClientHelloResultCallback::Result* result =
- new ValidateClientHelloResultCallback::Result(
- client_hello, client_ip, now);
+ new ValidateClientHelloResultCallback::Result(client_hello, client_ip,
+ now);
StringPiece requested_scid;
client_hello.GetStringPiece(kSCID, &requested_scid);
- uint8 primary_orbit[kOrbitSize];
+ uint8_t primary_orbit[kOrbitSize];
scoped_refptr<Config> requested_config;
+ scoped_refptr<Config> primary_config;
{
base::AutoLock locked(configs_lock_);
@@ -517,11 +520,13 @@ void QuicCryptoServerConfig::ValidateClientHello(
}
requested_config = GetConfigWithScid(requested_scid);
+ primary_config = primary_config_;
+ crypto_proof->primary_scid = primary_config->id;
}
if (result->error_code == QUIC_NO_ERROR) {
EvaluateClientHello(server_ip, version, primary_orbit, requested_config,
- crypto_proof, result, done_cb);
+ primary_config, crypto_proof, result, done_cb);
} else {
done_cb->Run(result);
}
@@ -548,27 +553,10 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
validate_chlo_result.client_hello;
const ClientHelloInfo& info = validate_chlo_result.info;
- // If the client's preferred version is not the version we are currently
- // speaking, then the client went through a version negotiation. In this
- // case, we need to make sure that we actually do not support this version
- // and that it wasn't a downgrade attack.
- QuicTag client_version_tag;
- if (client_hello.GetUint32(kVER, &client_version_tag) != QUIC_NO_ERROR) {
- *error_details = "client hello missing version list";
- return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
- }
- QuicVersion client_version = QuicTagToQuicVersion(client_version_tag);
- if (client_version != version) {
- // Just because client_version is a valid version enum doesn't mean that
- // this server actually supports that version, so we check to see if
- // it's actually in the supported versions list.
- for (size_t i = 0; i < supported_versions.size(); ++i) {
- if (client_version == supported_versions[i]) {
- *error_details = "Downgrade attack detected";
- return QUIC_VERSION_NEGOTIATION_MISMATCH;
- }
- }
- }
+ QuicErrorCode valid = CryptoUtils::ValidateClientHello(
+ client_hello, version, supported_versions, error_details);
+ if (valid != QUIC_NO_ERROR)
+ return valid;
StringPiece requested_scid;
client_hello.GetStringPiece(kSCID, &requested_scid);
@@ -594,7 +582,16 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
// We'll use the config that the client requested in order to do
// key-agreement. Otherwise we'll give it a copy of |primary_config_|
// to use.
- primary_config = primary_config_;
+ if (FLAGS_quic_use_primary_config_for_proof) {
+ primary_config = GetConfigWithScid(crypto_proof->primary_scid);
+ if (!primary_config) {
+ *error_details = "Configuration not found";
+ LOG(DFATAL) << "Primary config not found";
+ return QUIC_CRYPTO_INTERNAL_ERROR;
+ }
+ } else {
+ primary_config = primary_config_;
+ }
requested_config = GetConfigWithScid(requested_scid);
}
@@ -609,19 +606,25 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
bool x509_supported = false;
bool x509_ecdsa_supported = false;
ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
- if (proof_source_.get() && !crypto_proof->certs &&
+ DCHECK(proof_source_.get());
+ if (!crypto_proof->certs &&
!proof_source_->GetProof(server_ip, info.sni.as_string(),
primary_config->serialized, x509_ecdsa_supported,
- &crypto_proof->certs,
- &crypto_proof->signature)) {
+ &crypto_proof->certs, &crypto_proof->signature,
+ &crypto_proof->cert_sct)) {
return QUIC_HANDSHAKE_FAILED;
}
- if (!info.valid_source_address_token ||
- !info.client_nonce_well_formed ||
- !info.unique ||
- !requested_config.get()) {
- BuildRejection(*primary_config, client_hello, info,
+ if (version > QUIC_VERSION_29) {
+ StringPiece cert_sct;
+ if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) &&
+ cert_sct.empty()) {
+ params->sct_supported_by_client = true;
+ }
+ }
+
+ if (!info.reject_reasons.empty() || !requested_config.get()) {
+ BuildRejection(version, *primary_config, client_hello, info,
validate_chlo_result.cached_network_params,
use_stateless_rejects, server_designated_connection_id, rand,
params, *crypto_proof, out);
@@ -631,12 +634,11 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
const QuicTag* their_aeads;
const QuicTag* their_key_exchanges;
size_t num_their_aeads, num_their_key_exchanges;
- if (client_hello.GetTaglist(kAEAD, &their_aeads,
- &num_their_aeads) != QUIC_NO_ERROR ||
+ if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) !=
+ QUIC_NO_ERROR ||
client_hello.GetTaglist(kKEXS, &their_key_exchanges,
&num_their_key_exchanges) != QUIC_NO_ERROR ||
- num_their_aeads != 1 ||
- num_their_key_exchanges != 1) {
+ num_their_aeads != 1 || num_their_key_exchanges != 1) {
*error_details = "Missing or invalid AEAD or KEXS";
return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
}
@@ -645,14 +647,33 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads,
num_their_aeads, QuicUtils::LOCAL_PRIORITY,
&params->aead, nullptr) ||
- !QuicUtils::FindMutualTag(
- requested_config->kexs, their_key_exchanges, num_their_key_exchanges,
- QuicUtils::LOCAL_PRIORITY, &params->key_exchange,
- &key_exchange_index)) {
+ !QuicUtils::FindMutualTag(requested_config->kexs, their_key_exchanges,
+ num_their_key_exchanges,
+ QuicUtils::LOCAL_PRIORITY,
+ &params->key_exchange, &key_exchange_index)) {
*error_details = "Unsupported AEAD or KEXS";
return QUIC_CRYPTO_NO_SUPPORT;
}
+ if (!requested_config->tb_key_params.empty()) {
+ const QuicTag* their_tbkps;
+ size_t num_their_tbkps;
+ switch (client_hello.GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) {
+ case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+ break;
+ case QUIC_NO_ERROR:
+ if (QuicUtils::FindMutualTag(
+ requested_config->tb_key_params, their_tbkps, num_their_tbkps,
+ QuicUtils::LOCAL_PRIORITY, &params->token_binding_key_param,
+ nullptr)) {
+ break;
+ }
+ default:
+ *error_details = "Invalid Token Binding key parameter";
+ return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+ }
+ }
+
StringPiece public_value;
if (!client_hello.GetStringPiece(kPUBS, &public_value)) {
*error_details = "Missing public value";
@@ -683,12 +704,8 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
hkdf_suffix.append(client_hello_serialized.data(),
client_hello_serialized.length());
hkdf_suffix.append(requested_config->serialized);
- // The addition of x509_supported in this if statement is so that an insecure
- // quic client talking to a secure quic server will not result in the secure
- // quic server adding the cert to the kdf.
- // TODO(nharper): Should a server that is configured to be secure (i.e. one
- // that has a proof_source_) be accepting responses from an insecure client?
- if (version > QUIC_VERSION_25 && proof_source_.get() && x509_supported) {
+ DCHECK(proof_source_.get());
+ if (version > QUIC_VERSION_25) {
if (crypto_proof->certs->empty()) {
*error_details = "Failed to get certs";
return QUIC_CRYPTO_INTERNAL_ERROR;
@@ -790,11 +807,17 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
label_len);
forward_secure_hkdf_input.append(hkdf_suffix);
+ string shlo_nonce;
+ if (version > QUIC_VERSION_26) {
+ shlo_nonce = NewServerNonce(rand, info.now);
+ out->SetStringPiece(kServerNonceTag, shlo_nonce);
+ }
if (!CryptoUtils::DeriveKeys(
params->forward_secure_premaster_secret, params->aead,
- info.client_nonce, info.server_nonce, forward_secure_hkdf_input,
- Perspective::IS_SERVER, &params->forward_secure_crypters,
- &params->subkey_secret)) {
+ info.client_nonce,
+ shlo_nonce.empty() ? info.server_nonce : shlo_nonce,
+ forward_secure_hkdf_input, Perspective::IS_SERVER,
+ &params->forward_secure_crypters, &params->subkey_secret)) {
*error_details = "Symmetric key setup failed";
return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
}
@@ -802,8 +825,8 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
out->set_tag(kSHLO);
QuicTagVector supported_version_tags;
for (size_t i = 0; i < supported_versions.size(); ++i) {
- supported_version_tags.push_back
- (QuicVersionToQuicTag(supported_versions[i]));
+ supported_version_tags.push_back(
+ QuicVersionToQuicTag(supported_versions[i]));
}
out->SetVector(kVER, supported_version_tags);
out->SetStringPiece(
@@ -856,11 +879,11 @@ bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
void QuicCryptoServerConfig::SelectNewPrimaryConfig(
const QuicWallTime now) const {
- vector<scoped_refptr<Config> > configs;
+ vector<scoped_refptr<Config>> configs;
configs.reserve(configs_.size());
- for (ConfigMap::const_iterator it = configs_.begin();
- it != configs_.end(); ++it) {
+ for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end();
+ ++it) {
// TODO(avd) Exclude expired configs?
configs.push_back(it->second);
}
@@ -909,8 +932,8 @@ void QuicCryptoServerConfig::SelectNewPrimaryConfig(
new_primary->is_primary = true;
DVLOG(1) << "New primary config. orbit: "
<< base::HexEncode(
- reinterpret_cast<const char*>(primary_config_->orbit),
- kOrbitSize);
+ reinterpret_cast<const char*>(primary_config_->orbit),
+ kOrbitSize);
if (primary_config_changed_cb_.get() != nullptr) {
primary_config_changed_cb_->Run(primary_config_->id);
}
@@ -928,8 +951,8 @@ void QuicCryptoServerConfig::SelectNewPrimaryConfig(
new_primary->is_primary = true;
DVLOG(1) << "New primary config. orbit: "
<< base::HexEncode(
- reinterpret_cast<const char*>(primary_config_->orbit),
- kOrbitSize)
+ reinterpret_cast<const char*>(primary_config_->orbit),
+ kOrbitSize)
<< " scid: " << base::HexEncode(primary_config_->id.data(),
primary_config_->id.size());
next_config_promotion_time_ = QuicWallTime::Zero();
@@ -941,15 +964,15 @@ void QuicCryptoServerConfig::SelectNewPrimaryConfig(
void QuicCryptoServerConfig::EvaluateClientHello(
const IPAddressNumber& server_ip,
QuicVersion version,
- const uint8* primary_orbit,
+ const uint8_t* primary_orbit,
scoped_refptr<Config> requested_config,
+ scoped_refptr<Config> primary_config,
QuicCryptoProof* crypto_proof,
ValidateClientHelloResultCallback::Result* client_hello_state,
ValidateClientHelloResultCallback* done_cb) const {
ValidateClientHelloHelper helper(client_hello_state, done_cb);
- const CryptoHandshakeMessage& client_hello =
- client_hello_state->client_hello;
+ const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello;
ClientHelloInfo* info = &(client_hello_state->info);
if (client_hello.size() < kClientHelloMinimumSize) {
@@ -967,6 +990,27 @@ void QuicCryptoServerConfig::EvaluateClientHello(
client_hello.GetStringPiece(kUAID, &info->user_agent_id);
+ HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON;
+ StringPiece srct;
+ if (FLAGS_quic_validate_stk_without_scid) {
+ if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
+ Config& config =
+ requested_config != nullptr ? *requested_config : *primary_config;
+ source_address_token_error =
+ ParseSourceAddressToken(config, srct, &info->source_address_tokens);
+
+ if (source_address_token_error == HANDSHAKE_OK) {
+ source_address_token_error = ValidateSourceAddressTokens(
+ info->source_address_tokens, info->client_ip, info->now,
+ &client_hello_state->cached_network_params);
+ }
+ info->valid_source_address_token =
+ (source_address_token_error == HANDSHAKE_OK);
+ } else {
+ source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
+ }
+ }
+
if (!requested_config.get()) {
StringPiece requested_scid;
if (client_hello.GetStringPiece(kSCID, &requested_scid)) {
@@ -979,21 +1023,21 @@ void QuicCryptoServerConfig::EvaluateClientHello(
return;
}
- HandshakeFailureReason source_address_token_error;
- StringPiece srct;
- if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
- source_address_token_error = ParseSourceAddressToken(
- *requested_config, srct, &info->source_address_tokens);
-
- if (source_address_token_error == HANDSHAKE_OK) {
- source_address_token_error = ValidateSourceAddressTokens(
- info->source_address_tokens, info->client_ip, info->now,
- &client_hello_state->cached_network_params);
+ if (!FLAGS_quic_validate_stk_without_scid) {
+ if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
+ source_address_token_error = ParseSourceAddressToken(
+ *requested_config, srct, &info->source_address_tokens);
+
+ if (source_address_token_error == HANDSHAKE_OK) {
+ source_address_token_error = ValidateSourceAddressTokens(
+ info->source_address_tokens, info->client_ip, info->now,
+ &client_hello_state->cached_network_params);
+ }
+ info->valid_source_address_token =
+ (source_address_token_error == HANDSHAKE_OK);
+ } else {
+ source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
}
- info->valid_source_address_token =
- (source_address_token_error == HANDSHAKE_OK);
- } else {
- source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
}
bool found_error = false;
@@ -1007,29 +1051,20 @@ void QuicCryptoServerConfig::EvaluateClientHello(
found_error = true;
}
- if (client_hello.GetStringPiece(kNONC, &info->client_nonce) &&
- info->client_nonce.size() == kNonceSize) {
- info->client_nonce_well_formed = true;
- } else {
- info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
- // Invalid client nonce.
- DVLOG(1) << "Invalid client nonce.";
- if (FLAGS_use_early_return_when_verifying_chlo) {
- helper.ValidationComplete(QUIC_NO_ERROR, "");
- return;
- }
- found_error = true;
- }
-
if (version > QUIC_VERSION_25) {
bool x509_supported = false;
bool x509_ecdsa_supported = false;
ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
- if (proof_source_.get() &&
- !proof_source_->GetProof(server_ip, info->sni.as_string(),
- requested_config->serialized,
- x509_ecdsa_supported, &crypto_proof->certs,
- &crypto_proof->signature)) {
+ string serialized_config;
+ if (FLAGS_quic_use_primary_config_for_proof) {
+ serialized_config = primary_config->serialized;
+ } else {
+ serialized_config = requested_config->serialized;
+ }
+ if (!proof_source_->GetProof(server_ip, info->sni.as_string(),
+ serialized_config, x509_ecdsa_supported,
+ &crypto_proof->certs, &crypto_proof->signature,
+ &crypto_proof->cert_sct)) {
found_error = true;
info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
}
@@ -1040,27 +1075,48 @@ void QuicCryptoServerConfig::EvaluateClientHello(
}
}
- if (!replay_protection_) {
- if (!found_error) {
- info->unique = true;
+ if (!client_hello.GetStringPiece(kNONC, &info->client_nonce) ||
+ info->client_nonce.size() != kNonceSize) {
+ info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
+ // Invalid client nonce.
+ DVLOG(1) << "Invalid client nonce.";
+ if (FLAGS_use_early_return_when_verifying_chlo) {
+ helper.ValidationComplete(QUIC_NO_ERROR, "");
+ return;
+ }
+ found_error = true;
+ }
+
+ // Server nonce is optional, and used for key derivation if present.
+ client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
+
+ if (version > QUIC_VERSION_30) {
+ DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_31 and higher.";
+ // If the server nonce is empty and we're requiring handshake confirmation
+ // for DoS reasons then we must reject the CHLO.
+ if (FLAGS_quic_require_handshake_confirmation &&
+ info->server_nonce.empty()) {
+ info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
}
+ helper.ValidationComplete(QUIC_NO_ERROR, "");
+ return;
+ }
+
+ if (!replay_protection_) {
DVLOG(1) << "No replay protection.";
helper.ValidationComplete(QUIC_NO_ERROR, "");
return;
}
- client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
if (!info->server_nonce.empty()) {
// If the server nonce is present, use it to establish uniqueness.
HandshakeFailureReason server_nonce_error =
ValidateServerNonce(info->server_nonce, info->now);
- if (server_nonce_error == HANDSHAKE_OK) {
- info->unique = true;
- } else {
+ bool is_unique = server_nonce_error == HANDSHAKE_OK;
+ if (!is_unique) {
info->reject_reasons.push_back(server_nonce_error);
- info->unique = false;
}
- DVLOG(1) << "Using server nonce, unique: " << info->unique;
+ DVLOG(1) << "Using server nonce, unique: " << is_unique;
helper.ValidationComplete(QUIC_NO_ERROR, "");
return;
}
@@ -1086,26 +1142,36 @@ void QuicCryptoServerConfig::EvaluateClientHello(
base::AutoLock locked(strike_register_client_lock_);
if (strike_register_client_.get() == nullptr) {
- strike_register_client_.reset(new LocalStrikeRegisterClient(
- strike_register_max_entries_,
- static_cast<uint32>(info->now.ToUNIXSeconds()),
- strike_register_window_secs_,
- primary_orbit,
- strike_register_no_startup_period_ ?
- StrikeRegister::NO_STARTUP_PERIOD_NEEDED :
- StrikeRegister::DENY_REQUESTS_AT_STARTUP));
+ if (!FLAGS_require_strike_register_or_server_nonce) {
+ strike_register_client_.reset(new LocalStrikeRegisterClient(
+ strike_register_max_entries_,
+ static_cast<uint32_t>(info->now.ToUNIXSeconds()),
+ strike_register_window_secs_, primary_orbit,
+ strike_register_no_startup_period_
+ ? StrikeRegister::NO_STARTUP_PERIOD_NEEDED
+ : StrikeRegister::DENY_REQUESTS_AT_STARTUP));
+ }
}
strike_register_client = strike_register_client_.get();
}
+ if (!strike_register_client) {
+ // Either a valid server nonces or a strike register is required.
+ // Since neither are present, reject the handshake which will send a
+ // server nonce to the client.
+ info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
+ helper.ValidationComplete(QUIC_NO_ERROR, "");
+ return;
+ }
+
strike_register_client->VerifyNonceIsValidAndUnique(
- info->client_nonce,
- info->now,
+ info->client_nonce, info->now,
new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb));
helper.StartedAsyncCallback();
}
bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
+ QuicVersion version,
const SourceAddressTokens& previous_source_address_tokens,
const IPAddressNumber& server_ip,
const IPAddressNumber& client_ip,
@@ -1123,16 +1189,12 @@ bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
previous_source_address_tokens, client_ip, rand,
clock->WallNow(), cached_network_params));
- if (proof_source_ == nullptr) {
- // Insecure QUIC, can send SCFG without proof.
- return true;
- }
-
const vector<string>* certs;
string signature;
+ string cert_sct;
if (!proof_source_->GetProof(
server_ip, params.sni, primary_config_->serialized,
- params.x509_ecdsa_supported, &certs, &signature)) {
+ params.x509_ecdsa_supported, &certs, &signature, &cert_sct)) {
DVLOG(1) << "Server: failed to get proof.";
return false;
}
@@ -1143,10 +1205,19 @@ bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
out->SetStringPiece(kCertificateTag, compressed);
out->SetStringPiece(kPROF, signature);
+ if (params.sct_supported_by_client && version > QUIC_VERSION_29 &&
+ enable_serving_sct_) {
+ if (cert_sct.empty()) {
+ DLOG(WARNING) << "SCT is expected but it is empty.";
+ } else {
+ out->SetStringPiece(kCertificateSCTTag, cert_sct);
+ }
+ }
return true;
}
void QuicCryptoServerConfig::BuildRejection(
+ QuicVersion version,
const Config& config,
const CryptoHandshakeMessage& client_hello,
const ClientHelloInfo& info,
@@ -1187,10 +1258,6 @@ void QuicCryptoServerConfig::BuildRejection(
return;
}
- if (!proof_source_.get()) {
- return;
- }
-
StringPiece client_common_set_hashes;
if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) {
params->client_common_set_hashes = client_common_set_hashes.as_string();
@@ -1213,21 +1280,28 @@ void QuicCryptoServerConfig::BuildRejection(
// SCID: 16 bytes
// PUBS: 38 bytes
const size_t kREJOverheadBytes = 166;
- // kMultiplier is the multiple of the CHLO message size that a REJ message
- // must stay under when the client doesn't present a valid source-address
- // token.
- const size_t kMultiplier = 2;
- // max_unverified_size is the number of bytes that the certificate chain
- // and signature can consume before we will demand a valid source-address
- // token.
+ // max_unverified_size is the number of bytes that the certificate chain,
+ // signature, and (optionally) signed certificate timestamp can consume before
+ // we will demand a valid source-address token.
const size_t max_unverified_size =
- client_hello.size() * kMultiplier - kREJOverheadBytes;
+ client_hello.size() * chlo_multiplier_ - kREJOverheadBytes;
static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes,
- "overhead calculation may overflow");
+ "overhead calculation may underflow");
+ bool should_return_sct = params->sct_supported_by_client &&
+ version > QUIC_VERSION_29 && enable_serving_sct_;
+ const size_t sct_size = should_return_sct ? crypto_proof.cert_sct.size() : 0;
if (info.valid_source_address_token ||
- crypto_proof.signature.size() + compressed.size() < max_unverified_size) {
+ crypto_proof.signature.size() + compressed.size() + sct_size <
+ max_unverified_size) {
out->SetStringPiece(kCertificateTag, compressed);
out->SetStringPiece(kPROF, crypto_proof.signature);
+ if (should_return_sct) {
+ if (crypto_proof.cert_sct.empty()) {
+ DLOG(WARNING) << "SCT is expected but it is empty.";
+ } else {
+ out->SetStringPiece(kCertificateSCTTag, crypto_proof.cert_sct);
+ }
+ }
}
}
@@ -1287,6 +1361,17 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
return nullptr;
}
+ const QuicTag* tbkp_tags;
+ size_t tbkp_len;
+ QuicErrorCode err;
+ if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) !=
+ QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND &&
+ err != QUIC_NO_ERROR) {
+ LOG(WARNING) << "Server config message is missing or has invalid TBKP";
+ return nullptr;
+ }
+ config->tb_key_params = vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len);
+
StringPiece orbit;
if (!msg->GetStringPiece(kORBT, &orbit)) {
LOG(WARNING) << "Server config message is missing ORBT";
@@ -1295,7 +1380,8 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
if (orbit.size() != kOrbitSize) {
LOG(WARNING) << "Orbit value in server config is the wrong length."
- " Got " << orbit.size() << " want " << kOrbitSize;
+ " Got "
+ << orbit.size() << " want " << kOrbitSize;
return nullptr;
}
static_assert(sizeof(config->orbit) == kOrbitSize,
@@ -1313,7 +1399,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
!strike_register_client->IsKnownOrbit(orbit)) {
LOG(WARNING)
<< "Rejecting server config with orbit that the strike register "
- "client doesn't know about.";
+ "client doesn't know about.";
return nullptr;
}
}
@@ -1353,7 +1439,8 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
if (private_key.empty()) {
LOG(WARNING) << "Server config contains key exchange method without "
- "corresponding private key: " << tag;
+ "corresponding private key: "
+ << tag;
return nullptr;
}
@@ -1377,7 +1464,8 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
break;
default:
LOG(WARNING) << "Server config message contains unknown key exchange "
- "method: " << tag;
+ "method: "
+ << tag;
return nullptr;
}
@@ -1394,10 +1482,6 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
return config;
}
-void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) {
- proof_source_.reset(proof_source);
-}
-
void QuicCryptoServerConfig::SetEphemeralKeySource(
EphemeralKeySource* ephemeral_key_source) {
ephemeral_key_source_.reset(ephemeral_key_source);
@@ -1414,6 +1498,10 @@ void QuicCryptoServerConfig::set_replay_protection(bool on) {
replay_protection_ = on;
}
+void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) {
+ chlo_multiplier_ = multiplier;
+}
+
void QuicCryptoServerConfig::set_strike_register_no_startup_period() {
base::AutoLock locker(strike_register_client_lock_);
DCHECK(!strike_register_client_.get());
@@ -1421,41 +1509,45 @@ void QuicCryptoServerConfig::set_strike_register_no_startup_period() {
}
void QuicCryptoServerConfig::set_strike_register_max_entries(
- uint32 max_entries) {
+ uint32_t max_entries) {
base::AutoLock locker(strike_register_client_lock_);
DCHECK(!strike_register_client_.get());
strike_register_max_entries_ = max_entries;
}
void QuicCryptoServerConfig::set_strike_register_window_secs(
- uint32 window_secs) {
+ uint32_t window_secs) {
base::AutoLock locker(strike_register_client_lock_);
DCHECK(!strike_register_client_.get());
strike_register_window_secs_ = window_secs;
}
void QuicCryptoServerConfig::set_source_address_token_future_secs(
- uint32 future_secs) {
+ uint32_t future_secs) {
source_address_token_future_secs_ = future_secs;
}
void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
- uint32 lifetime_secs) {
+ uint32_t lifetime_secs) {
source_address_token_lifetime_secs_ = lifetime_secs;
}
void QuicCryptoServerConfig::set_server_nonce_strike_register_max_entries(
- uint32 max_entries) {
+ uint32_t max_entries) {
DCHECK(!server_nonce_strike_register_.get());
server_nonce_strike_register_max_entries_ = max_entries;
}
void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs(
- uint32 window_secs) {
+ uint32_t window_secs) {
DCHECK(!server_nonce_strike_register_.get());
server_nonce_strike_register_window_secs_ = window_secs;
}
+void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) {
+ enable_serving_sct_ = enable_serving_sct;
+}
+
void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
PrimaryConfigChangedCallback* cb) {
base::AutoLock locked(configs_lock_);
@@ -1500,10 +1592,6 @@ string QuicCryptoServerConfig::NewSourceAddressToken(
rand, source_address_tokens.SerializeAsString());
}
-bool QuicCryptoServerConfig::HasProofSource() const {
- return proof_source_ != nullptr;
-}
-
int QuicCryptoServerConfig::NumberOfConfigs() const {
base::AutoLock locked(configs_lock_);
return configs_.size();
@@ -1594,14 +1682,14 @@ static const size_t kServerNoncePlaintextSize =
string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
QuicWallTime now) const {
- const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds());
+ const uint32_t timestamp = static_cast<uint32_t>(now.ToUNIXSeconds());
- uint8 server_nonce[kServerNoncePlaintextSize];
+ uint8_t server_nonce[kServerNoncePlaintextSize];
static_assert(sizeof(server_nonce) > sizeof(timestamp), "nonce too small");
- server_nonce[0] = static_cast<uint8>(timestamp >> 24);
- server_nonce[1] = static_cast<uint8>(timestamp >> 16);
- server_nonce[2] = static_cast<uint8>(timestamp >> 8);
- server_nonce[3] = static_cast<uint8>(timestamp);
+ server_nonce[0] = static_cast<uint8_t>(timestamp >> 24);
+ server_nonce[1] = static_cast<uint8_t>(timestamp >> 16);
+ server_nonce[2] = static_cast<uint8_t>(timestamp >> 8);
+ server_nonce[3] = static_cast<uint8_t>(timestamp);
rand->RandBytes(&server_nonce[sizeof(timestamp)],
sizeof(server_nonce) - sizeof(timestamp));
@@ -1620,8 +1708,8 @@ HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce(
}
// plaintext contains:
- // uint32 timestamp
- // uint8[20] random bytes
+ // uint32_t timestamp
+ // uint8_t[20] random bytes
if (plaintext.size() != kServerNoncePlaintextSize) {
// This should never happen because the value decrypted correctly.
@@ -1629,7 +1717,7 @@ HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce(
return SERVER_NONCE_INVALID_FAILURE;
}
- uint8 server_nonce[32];
+ uint8_t server_nonce[32];
memcpy(server_nonce, plaintext.data(), 4);
memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_));
memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4,
@@ -1643,12 +1731,12 @@ HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce(
if (server_nonce_strike_register_.get() == nullptr) {
server_nonce_strike_register_.reset(new StrikeRegister(
server_nonce_strike_register_max_entries_,
- static_cast<uint32>(now.ToUNIXSeconds()),
+ static_cast<uint32_t>(now.ToUNIXSeconds()),
server_nonce_strike_register_window_secs_, server_nonce_orbit_,
StrikeRegister::NO_STARTUP_PERIOD_NEEDED));
}
nonce_error = server_nonce_strike_register_->Insert(
- server_nonce, static_cast<uint32>(now.ToUNIXSeconds()));
+ server_nonce, static_cast<uint32_t>(now.ToUNIXSeconds()));
}
switch (nonce_error) {
@@ -1673,16 +1761,11 @@ HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce(
bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
const CryptoHandshakeMessage& client_hello,
const QuicCryptoProof& crypto_proof) const {
- // If the server doesn't use https, then the client won't send XLCT and
- // proof_source_ will be null, so in this case return true.
- if (!proof_source_.get()) {
- return true;
- }
if (crypto_proof.certs->empty()) {
return false;
}
- uint64 hash_from_client;
+ uint64_t hash_from_client;
if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
return false;
}
@@ -1697,8 +1780,7 @@ void QuicCryptoServerConfig::ParseProofDemand(
const QuicTag* their_proof_demands;
size_t num_their_proof_demands;
- if (proof_source_.get() == nullptr ||
- client_hello.GetTaglist(kPDMD, &their_proof_demands,
+ if (client_hello.GetTaglist(kPDMD, &their_proof_demands,
&num_their_proof_demands) != QUIC_NO_ERROR) {
return;
}
@@ -1724,6 +1806,8 @@ QuicCryptoServerConfig::Config::Config()
priority(0),
source_address_token_boxer(nullptr) {}
-QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
+QuicCryptoServerConfig::Config::~Config() {
+ STLDeleteElements(&key_exchanges);
+}
} // namespace net
diff --git a/chromium/net/quic/crypto/quic_crypto_server_config.h b/chromium/net/quic/crypto/quic_crypto_server_config.h
index 2ab58a2b250..0aba62e2253 100644
--- a/chromium/net/quic/crypto/quic_crypto_server_config.h
+++ b/chromium/net/quic/crypto/quic_crypto_server_config.h
@@ -5,17 +5,21 @@
#ifndef NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
#define NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"
+#include "net/base/ip_address_number.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
-#include "net/base/net_util.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/crypto_handshake_message.h"
#include "net/quic/crypto/crypto_protocol.h"
@@ -50,8 +54,6 @@ struct ClientHelloInfo {
// Outputs from EvaluateClientHello.
bool valid_source_address_token;
- bool client_nonce_well_formed;
- bool unique;
base::StringPiece sni;
base::StringPiece client_nonce;
base::StringPiece server_nonce;
@@ -59,8 +61,8 @@ struct ClientHelloInfo {
SourceAddressTokens source_address_tokens;
// Errors from EvaluateClientHello.
- std::vector<uint32> reject_reasons;
- static_assert(sizeof(QuicTag) == sizeof(uint32), "header out of sync");
+ std::vector<uint32_t> reject_reasons;
+ static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
};
namespace test {
@@ -127,6 +129,9 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// channel_id_enabled controls whether the server config will indicate
// support for ChannelIDs.
bool channel_id_enabled;
+ // token_binding_enabled controls whether the server config will indicate
+ // support for Token Binding.
+ bool token_binding_enabled;
// id contains the server config id for the resulting config. If empty, a
// random id is generated.
std::string id;
@@ -145,9 +150,12 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// into a KDF before use. In tests, use TESTING.
// |server_nonce_entropy|: an entropy source used to generate the orbit and
// key for server nonces, which are always local to a given instance of a
- // server.
+ // server. Not owned.
+ // |proof_source|: provides certificate chains and signatures. This class
+ // takes ownership of |proof_source|.
QuicCryptoServerConfig(base::StringPiece source_address_token_secret,
- QuicRandom* server_nonce_entropy);
+ QuicRandom* server_nonce_entropy,
+ ProofSource* proof_source);
~QuicCryptoServerConfig();
// TESTING is a magic parameter for passing to the constructor in tests.
@@ -155,10 +163,9 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// Generates a QuicServerConfigProtobuf protobuf suitable for
// AddConfig and SetConfigs.
- static QuicServerConfigProtobuf* GenerateConfig(
- QuicRandom* rand,
- const QuicClock* clock,
- const ConfigOptions& options);
+ static QuicServerConfigProtobuf* GenerateConfig(QuicRandom* rand,
+ const QuicClock* clock,
+ const ConfigOptions& options);
// AddConfig adds a QuicServerConfigProtobuf to the availible configurations.
// It returns the SCFG message from the config if successful. The caller
@@ -171,10 +178,9 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// AddDefaultConfig calls DefaultConfig to create a config and then calls
// AddConfig to add it. See the comment for |DefaultConfig| for details of
// the arguments.
- CryptoHandshakeMessage* AddDefaultConfig(
- QuicRandom* rand,
- const QuicClock* clock,
- const ConfigOptions& options);
+ CryptoHandshakeMessage* AddDefaultConfig(QuicRandom* rand,
+ const QuicClock* clock,
+ const ConfigOptions& options);
// SetConfigs takes a vector of config protobufs and the current time.
// Configs are assumed to be uniquely identified by their server config ID.
@@ -206,7 +212,7 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// version: protocol version used for this connection.
// clock: used to validate client nonces and ephemeral keys.
// crypto_proof: output structure containing the crypto proof used in reply to
- // a proof demand.
+ // a proof demand.
// done_cb: single-use callback that accepts an opaque
// ValidatedClientHelloMsg token that holds information about
// the client hello. The callback will always be called exactly
@@ -270,6 +276,7 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
//
// |cached_network_params| is optional, and can be nullptr.
bool BuildServerConfigUpdateMessage(
+ QuicVersion version,
const SourceAddressTokens& previous_source_address_tokens,
const IPAddressNumber& server_ip,
const IPAddressNumber& client_ip,
@@ -279,10 +286,6 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
const CachedNetworkParameters* cached_network_params,
CryptoHandshakeMessage* out) const;
- // SetProofSource installs |proof_source| as the ProofSource for handshakes.
- // This object takes ownership of |proof_source|.
- void SetProofSource(ProofSource* proof_source);
-
// SetEphemeralKeySource installs an object that can cache ephemeral keys for
// a short period of time. This object takes ownership of
// |ephemeral_key_source|. If not set then ephemeral keys will be generated
@@ -301,6 +304,11 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// request to be processed twice.
void set_replay_protection(bool on);
+ // set_chlo_multiplier specifies the multiple of the CHLO message size
+ // that a REJ message must stay under when the client doesn't present a
+ // valid source-address token.
+ void set_chlo_multiplier(size_t multiplier);
+
// set_strike_register_no_startup_period configures the strike register to
// not have a startup period.
void set_strike_register_no_startup_period();
@@ -308,23 +316,23 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// set_strike_register_max_entries sets the maximum number of entries that
// the internal strike register will hold. If the strike register fills up
// then the oldest entries (by the client's clock) will be dropped.
- void set_strike_register_max_entries(uint32 max_entries);
+ void set_strike_register_max_entries(uint32_t max_entries);
// set_strike_register_window_secs sets the number of seconds around the
// current time that the strike register will attempt to be authoritative
// for. Setting a larger value allows for greater client clock-skew, but
// means that the quiescent startup period must be longer.
- void set_strike_register_window_secs(uint32 window_secs);
+ void set_strike_register_window_secs(uint32_t window_secs);
// set_source_address_token_future_secs sets the number of seconds into the
// future that source-address tokens will be accepted from. Since
// source-address tokens are authenticated, this should only happen if
// another, valid server has clock-skew.
- void set_source_address_token_future_secs(uint32 future_secs);
+ void set_source_address_token_future_secs(uint32_t future_secs);
// set_source_address_token_lifetime_secs sets the number of seconds that a
// source-address token will be valid for.
- void set_source_address_token_lifetime_secs(uint32 lifetime_secs);
+ void set_source_address_token_lifetime_secs(uint32_t lifetime_secs);
// set_server_nonce_strike_register_max_entries sets the number of entries in
// the server-nonce strike-register. This is used to record that server nonce
@@ -332,21 +340,22 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// which are depending on server nonces may fail to handshake because their
// nonce has expired in the amount of time it took to go from the server to
// the client and back.
- void set_server_nonce_strike_register_max_entries(uint32 max_entries);
+ void set_server_nonce_strike_register_max_entries(uint32_t max_entries);
// set_server_nonce_strike_register_window_secs sets the number of seconds
// around the current time that the server-nonce strike-register will accept
// nonces from. Setting a larger value allows for clients to delay follow-up
// client hellos for longer and still use server nonces as proofs of
// uniqueness.
- void set_server_nonce_strike_register_window_secs(uint32 window_secs);
+ void set_server_nonce_strike_register_window_secs(uint32_t window_secs);
+
+ // set_enable_serving_sct enables or disables serving signed cert timestamp
+ // (RFC6962) in server hello.
+ void set_enable_serving_sct(bool enable_serving_sct);
// Set and take ownership of the callback to invoke on primary config changes.
void AcquirePrimaryConfigChangedCb(PrimaryConfigChangedCallback* cb);
- // Returns true if this config has a |proof_source_|.
- bool HasProofSource() const;
-
// Returns the number of configs this object owns.
int NumberOfConfigs() const;
@@ -395,7 +404,7 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// Secondary sort key for use when selecting primary configs and
// there are multiple configs with the same primary time.
// Smaller numbers mean higher priority.
- uint64 priority;
+ uint64_t priority;
// source_address_token_boxer_ is used to protect the
// source-address tokens that are given to clients.
@@ -416,7 +425,7 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
DISALLOW_COPY_AND_ASSIGN(Config);
};
- typedef std::map<ServerConfigID, scoped_refptr<Config> > ConfigMap;
+ typedef std::map<ServerConfigID, scoped_refptr<Config>> ConfigMap;
// Get a ref to the config with a given server config id.
scoped_refptr<Config> GetConfigWithScid(
@@ -437,14 +446,16 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
void EvaluateClientHello(
const IPAddressNumber& server_ip,
QuicVersion version,
- const uint8* primary_orbit,
+ const uint8_t* primary_orbit,
scoped_refptr<Config> requested_config,
+ scoped_refptr<Config> primary_config,
QuicCryptoProof* crypto_proof,
ValidateClientHelloResultCallback::Result* client_hello_state,
ValidateClientHelloResultCallback* done_cb) const;
// BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
- void BuildRejection(const Config& config,
+ void BuildRejection(QuicVersion version,
+ const Config& config,
const CryptoHandshakeMessage& client_hello,
const ClientHelloInfo& info,
const CachedNetworkParameters& cached_network_params,
@@ -538,6 +549,11 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// aren't replays.
bool replay_protection_;
+ // The multiple of the CHLO message size that a REJ message must stay under
+ // when the client doesn't present a valid source-address token. This is
+ // used to protect QUIC from amplification attacks.
+ size_t chlo_multiplier_;
+
// configs_ satisfies the following invariants:
// 1) configs_.empty() <-> primary_config_ == nullptr
// 2) primary_config_ != nullptr -> primary_config_->is_primary
@@ -573,7 +589,7 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// server_nonce_orbit_ contains the random, per-server orbit values that this
// server will use to generate server nonces (the moral equivalent of a SYN
// cookies).
- uint8 server_nonce_orbit_[8];
+ uint8_t server_nonce_orbit_[8];
mutable base::Lock server_nonce_strike_register_lock_;
// server_nonce_strike_register_ contains a data structure that keeps track of
@@ -592,12 +608,15 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// These fields store configuration values. See the comments for their
// respective setter functions.
bool strike_register_no_startup_period_;
- uint32 strike_register_max_entries_;
- uint32 strike_register_window_secs_;
- uint32 source_address_token_future_secs_;
- uint32 source_address_token_lifetime_secs_;
- uint32 server_nonce_strike_register_max_entries_;
- uint32 server_nonce_strike_register_window_secs_;
+ uint32_t strike_register_max_entries_;
+ uint32_t strike_register_window_secs_;
+ uint32_t source_address_token_future_secs_;
+ uint32_t source_address_token_lifetime_secs_;
+ uint32_t server_nonce_strike_register_max_entries_;
+ uint32_t server_nonce_strike_register_window_secs_;
+
+ // Enable serving SCT or not.
+ bool enable_serving_sct_;
DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerConfig);
};
diff --git a/chromium/net/quic/crypto/quic_crypto_server_config_test.cc b/chromium/net/quic/crypto/quic_crypto_server_config_test.cc
index 4b0aa5a5722..d7a887ed837 100644
--- a/chromium/net/quic/crypto/quic_crypto_server_config_test.cc
+++ b/chromium/net/quic/crypto/quic_crypto_server_config_test.cc
@@ -15,6 +15,7 @@
#include "net/quic/crypto/strike_register_client.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_time.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -186,9 +187,7 @@ class QuicCryptoServerConfigPeer {
class TestStrikeRegisterClient : public StrikeRegisterClient {
public:
explicit TestStrikeRegisterClient(QuicCryptoServerConfig* config)
- : config_(config),
- is_known_orbit_called_(false) {
- }
+ : config_(config), is_known_orbit_called_(false) {}
bool IsKnownOrbit(StringPiece orbit) const override {
// Ensure that the strike register client lock is not held.
@@ -218,17 +217,18 @@ class TestStrikeRegisterClient : public StrikeRegisterClient {
TEST(QuicCryptoServerConfigTest, ServerConfig) {
QuicRandom* rand = QuicRandom::GetInstance();
- QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
+ QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+ CryptoTestUtils::ProofSourceForTesting());
MockClock clock;
- scoped_ptr<CryptoHandshakeMessage>(
- server.AddDefaultConfig(rand, &clock,
- QuicCryptoServerConfig::ConfigOptions()));
+ scoped_ptr<CryptoHandshakeMessage>(server.AddDefaultConfig(
+ rand, &clock, QuicCryptoServerConfig::ConfigOptions()));
}
TEST(QuicCryptoServerConfigTest, GetOrbitIsCalledWithoutTheStrikeRegisterLock) {
QuicRandom* rand = QuicRandom::GetInstance();
- QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
+ QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+ CryptoTestUtils::ProofSourceForTesting());
MockClock clock;
TestStrikeRegisterClient* strike_register =
@@ -249,7 +249,9 @@ class SourceAddressTokenTest : public ::testing::Test {
ip6_(Loopback6()),
original_time_(QuicWallTime::Zero()),
rand_(QuicRandom::GetInstance()),
- server_(QuicCryptoServerConfig::TESTING, rand_),
+ server_(QuicCryptoServerConfig::TESTING,
+ rand_,
+ CryptoTestUtils::ProofSourceForTesting()),
peer_(&server_) {
// Advance the clock to some non-zero time.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
@@ -272,14 +274,14 @@ class SourceAddressTokenTest : public ::testing::Test {
}
string NewSourceAddressToken(string config_id, const IPAddressNumber& ip) {
- return NewSourceAddressToken(config_id, ip, NULL);
+ return NewSourceAddressToken(config_id, ip, nullptr);
}
string NewSourceAddressToken(string config_id,
const IPAddressNumber& ip,
const SourceAddressTokens& previous_tokens) {
return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
- clock_.WallNow(), NULL);
+ clock_.WallNow(), nullptr);
}
string NewSourceAddressToken(string config_id,
@@ -294,7 +296,7 @@ class SourceAddressTokenTest : public ::testing::Test {
string config_id,
StringPiece srct,
const IPAddressNumber& ip) {
- return ValidateSourceAddressTokens(config_id, srct, ip, NULL);
+ return ValidateSourceAddressTokens(config_id, srct, ip, nullptr);
}
HandshakeFailureReason ValidateSourceAddressTokens(
@@ -422,12 +424,13 @@ TEST_F(SourceAddressTokenTest, SourceAddressTokenMultipleAddresses) {
TEST(QuicCryptoServerConfigTest, ValidateServerNonce) {
QuicRandom* rand = QuicRandom::GetInstance();
- QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
+ QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+ CryptoTestUtils::ProofSourceForTesting());
QuicCryptoServerConfigPeer peer(&server);
StringPiece message("hello world");
const size_t key_size = CryptoSecretBoxer::GetKeySize();
- scoped_ptr<uint8[]> key(new uint8[key_size]);
+ scoped_ptr<uint8_t[]> key(new uint8_t[key_size]);
memset(key.get(), 0x11, key_size);
CryptoSecretBoxer boxer;
@@ -453,7 +456,9 @@ class CryptoServerConfigsTest : public ::testing::Test {
public:
CryptoServerConfigsTest()
: rand_(QuicRandom::GetInstance()),
- config_(QuicCryptoServerConfig::TESTING, rand_),
+ config_(QuicCryptoServerConfig::TESTING,
+ rand_,
+ CryptoTestUtils::ProofSourceForTesting()),
test_peer_(&config_) {}
void SetUp() override {
@@ -537,221 +542,99 @@ TEST_F(CryptoServerConfigsTest, NoConfigs) {
TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
// Make sure that "b" is primary even though "a" comes first.
- SetConfigs("a", 1100, 1,
- "b", 900, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- nullptr);
+ SetConfigs("a", 1100, 1, "b", 900, 1, nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, nullptr);
}
TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
// Make sure that a remains primary after b is added.
- SetConfigs("a", 900, 1,
- "b", 1100, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", true,
- "b", false,
- nullptr);
+ SetConfigs("a", 900, 1, "b", 1100, 1, nullptr);
+ test_peer_.CheckConfigs("a", true, "b", false, nullptr);
}
TEST_F(CryptoServerConfigsTest, Delete) {
// Ensure that configs get deleted when removed.
- SetConfigs("a", 800, 1,
- "b", 900, 1,
- "c", 1100, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- "c", false,
- nullptr);
- SetConfigs("b", 900, 1,
- "c", 1100, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "b", true,
- "c", false,
- nullptr);
+ SetConfigs("a", 800, 1, "b", 900, 1, "c", 1100, 1, nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr);
+ SetConfigs("b", 900, 1, "c", 1100, 1, nullptr);
+ test_peer_.CheckConfigs("b", true, "c", false, nullptr);
}
TEST_F(CryptoServerConfigsTest, DeletePrimary) {
// Ensure that deleting the primary config works.
- SetConfigs("a", 800, 1,
- "b", 900, 1,
- "c", 1100, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- "c", false,
- nullptr);
- SetConfigs("a", 800, 1,
- "c", 1100, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", true,
- "c", false,
- nullptr);
+ SetConfigs("a", 800, 1, "b", 900, 1, "c", 1100, 1, nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr);
+ SetConfigs("a", 800, 1, "c", 1100, 1, nullptr);
+ test_peer_.CheckConfigs("a", true, "c", false, nullptr);
}
TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
// Ensure that configs get deleted when removed.
- SetConfigs("a", 800, 1,
- "b", 900, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- nullptr);
+ SetConfigs("a", 800, 1, "b", 900, 1, nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, nullptr);
SetConfigs(nullptr);
// Config change is rejected, still using old configs.
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, nullptr);
}
TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
// Check that updates to primary time get picked up.
- SetConfigs("a", 400, 1,
- "b", 800, 1,
- "c", 1200, 1,
- nullptr);
+ SetConfigs("a", 400, 1, "b", 800, 1, "c", 1200, 1, nullptr);
test_peer_.SelectNewPrimaryConfig(500);
- test_peer_.CheckConfigs(
- "a", true,
- "b", false,
- "c", false,
- nullptr);
- SetConfigs("a", 1200, 1,
- "b", 800, 1,
- "c", 400, 1,
- nullptr);
+ test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr);
+ SetConfigs("a", 1200, 1, "b", 800, 1, "c", 400, 1, nullptr);
test_peer_.SelectNewPrimaryConfig(500);
- test_peer_.CheckConfigs(
- "a", false,
- "b", false,
- "c", true,
- nullptr);
+ test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr);
}
TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
// Check that the most recent config is selected.
- SetConfigs("a", 400, 1,
- "b", 800, 1,
- "c", 1200, 1,
- nullptr);
+ SetConfigs("a", 400, 1, "b", 800, 1, "c", 1200, 1, nullptr);
test_peer_.SelectNewPrimaryConfig(1500);
- test_peer_.CheckConfigs(
- "a", false,
- "b", false,
- "c", true,
- nullptr);
+ test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr);
}
TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
// Check that the first config is selected.
- SetConfigs("a", 400, 1,
- "b", 800, 1,
- "c", 1200, 1,
- nullptr);
+ SetConfigs("a", 400, 1, "b", 800, 1, "c", 1200, 1, nullptr);
test_peer_.SelectNewPrimaryConfig(100);
- test_peer_.CheckConfigs(
- "a", true,
- "b", false,
- "c", false,
- nullptr);
+ test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr);
}
TEST_F(CryptoServerConfigsTest, SortByPriority) {
// Check that priority is used to decide on a primary config when
// configs have the same primary time.
- SetConfigs("a", 900, 1,
- "b", 900, 2,
- "c", 900, 3,
- nullptr);
- test_peer_.CheckConfigs(
- "a", true,
- "b", false,
- "c", false,
- nullptr);
+ SetConfigs("a", 900, 1, "b", 900, 2, "c", 900, 3, nullptr);
+ test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr);
test_peer_.SelectNewPrimaryConfig(800);
- test_peer_.CheckConfigs(
- "a", true,
- "b", false,
- "c", false,
- nullptr);
+ test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr);
test_peer_.SelectNewPrimaryConfig(1000);
- test_peer_.CheckConfigs(
- "a", true,
- "b", false,
- "c", false,
- nullptr);
+ test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr);
// Change priorities and expect sort order to change.
- SetConfigs("a", 900, 2,
- "b", 900, 1,
- "c", 900, 0,
- nullptr);
- test_peer_.CheckConfigs(
- "a", false,
- "b", false,
- "c", true,
- nullptr);
+ SetConfigs("a", 900, 2, "b", 900, 1, "c", 900, 0, nullptr);
+ test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr);
test_peer_.SelectNewPrimaryConfig(800);
- test_peer_.CheckConfigs(
- "a", false,
- "b", false,
- "c", true,
- nullptr);
+ test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr);
test_peer_.SelectNewPrimaryConfig(1000);
- test_peer_.CheckConfigs(
- "a", false,
- "b", false,
- "c", true,
- nullptr);
+ test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr);
}
TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
// Check that a new primary config is enabled at the right time.
- SetConfigs("a", 900, 1,
- "b", 1100, 1,
- nullptr);
+ SetConfigs("a", 900, 1, "b", 1100, 1, nullptr);
test_peer_.SelectNewPrimaryConfig(1000);
- test_peer_.CheckConfigs(
- "a", true,
- "b", false,
- nullptr);
+ test_peer_.CheckConfigs("a", true, "b", false, nullptr);
test_peer_.SelectNewPrimaryConfig(1101);
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, nullptr);
}
TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
// Ensure that invalid configs don't change anything.
- SetConfigs("a", 800, 1,
- "b", 900, 1,
- "c", 1100, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- "c", false,
- nullptr);
- SetConfigs("a", 800, 1,
- "c", 1100, 1,
- "INVALID1", 1000, 1,
- nullptr);
- test_peer_.CheckConfigs(
- "a", false,
- "b", true,
- "c", false,
- nullptr);
+ SetConfigs("a", 800, 1, "b", 900, 1, "c", 1100, 1, nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr);
+ SetConfigs("a", 800, 1, "c", 1100, 1, "INVALID1", 1000, 1, nullptr);
+ test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr);
}
} // namespace test
diff --git a/chromium/net/quic/crypto/quic_decrypter.cc b/chromium/net/quic/crypto/quic_decrypter.cc
index b7cb089e5fe..1253b872b38 100644
--- a/chromium/net/quic/crypto/quic_decrypter.cc
+++ b/chromium/net/quic/crypto/quic_decrypter.cc
@@ -6,6 +6,7 @@
#include "net/quic/crypto/aes_128_gcm_12_decrypter.h"
#include "net/quic/crypto/chacha20_poly1305_decrypter.h"
+#include "net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/null_decrypter.h"
@@ -18,6 +19,8 @@ QuicDecrypter* QuicDecrypter::Create(QuicTag algorithm) {
return new Aes128Gcm12Decrypter();
case kCC12:
return new ChaCha20Poly1305Decrypter();
+ case kCC20:
+ return new ChaCha20Poly1305Rfc7539Decrypter();
case kNULL:
return new NullDecrypter();
default:
diff --git a/chromium/net/quic/crypto/quic_decrypter.h b/chromium/net/quic/crypto/quic_decrypter.h
index 21ff8b32b51..4363e709df0 100644
--- a/chromium/net/quic/crypto/quic_decrypter.h
+++ b/chromium/net/quic/crypto/quic_decrypter.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_CRYPTO_QUIC_DECRYPTER_H_
#define NET_QUIC_CRYPTO_QUIC_DECRYPTER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
@@ -58,7 +61,7 @@ class NET_EXPORT_PRIVATE QuicDecrypter {
virtual const char* cipher_name() const = 0;
// The ID of the cipher. Return 0x03000000 ORed with the 'cryptographic suite
// selector'.
- virtual uint32 cipher_id() const = 0;
+ virtual uint32_t cipher_id() const = 0;
// For use by unit tests only.
virtual base::StringPiece GetKey() const = 0;
diff --git a/chromium/net/quic/crypto/quic_encrypter.cc b/chromium/net/quic/crypto/quic_encrypter.cc
index 298a15a58f5..0cd727b0940 100644
--- a/chromium/net/quic/crypto/quic_encrypter.cc
+++ b/chromium/net/quic/crypto/quic_encrypter.cc
@@ -6,6 +6,7 @@
#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
#include "net/quic/crypto/chacha20_poly1305_encrypter.h"
+#include "net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/null_encrypter.h"
@@ -18,6 +19,8 @@ QuicEncrypter* QuicEncrypter::Create(QuicTag algorithm) {
return new Aes128Gcm12Encrypter();
case kCC12:
return new ChaCha20Poly1305Encrypter();
+ case kCC20:
+ return new ChaCha20Poly1305Rfc7539Encrypter();
case kNULL:
return new NullEncrypter();
default:
diff --git a/chromium/net/quic/crypto/quic_encrypter.h b/chromium/net/quic/crypto/quic_encrypter.h
index ed6823310ea..72701743c80 100644
--- a/chromium/net/quic/crypto/quic_encrypter.h
+++ b/chromium/net/quic/crypto/quic_encrypter.h
@@ -5,6 +5,8 @@
#ifndef NET_QUIC_CRYPTO_QUIC_ENCRYPTER_H_
#define NET_QUIC_CRYPTO_QUIC_ENCRYPTER_H_
+#include <stddef.h>
+
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
@@ -39,10 +41,13 @@ class NET_EXPORT_PRIVATE QuicEncrypter {
// packet number, even when retransmitting a lost packet.
virtual bool SetNoncePrefix(base::StringPiece nonce_prefix) = 0;
- // Returns a newly created QuicData object containing the encrypted
- // |plaintext| as well as a MAC over both |plaintext| and |associated_data|,
- // or nullptr if there is an error. |packet_number| is appended to the
- // |nonce_prefix| value provided in SetNoncePrefix() to form the nonce.
+ // Writes encrypted |plaintext| and a MAC over |plaintext| and
+ // |associated_data| into output. Sets |output_length| to the number of
+ // bytes written. Returns true on success or false if there was an error.
+ // |packet_number| is appended to the |nonce_prefix| value provided in
+ // SetNoncePrefix() to form the nonce. |output| must not overlap with
+ // |associated_data|. If |output| overlaps with |plaintext| then
+ // |plaintext| must be <= |output|.
virtual bool EncryptPacket(QuicPacketNumber packet_number,
base::StringPiece associated_data,
base::StringPiece plaintext,
diff --git a/chromium/net/quic/crypto/quic_random.cc b/chromium/net/quic/crypto/quic_random.cc
index 941b3891176..ad130a0858d 100644
--- a/chromium/net/quic/crypto/quic_random.cc
+++ b/chromium/net/quic/crypto/quic_random.cc
@@ -5,6 +5,7 @@
#include "net/quic/crypto/quic_random.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "crypto/random.h"
@@ -18,11 +19,11 @@ class DefaultRandom : public QuicRandom {
// QuicRandom implementation
void RandBytes(void* data, size_t len) override;
- uint64 RandUint64() override;
+ uint64_t RandUint64() override;
void Reseed(const void* additional_entropy, size_t entropy_len) override;
private:
- DefaultRandom() {};
+ DefaultRandom() {}
~DefaultRandom() override {}
friend struct base::DefaultSingletonTraits<DefaultRandom>;
@@ -37,8 +38,8 @@ void DefaultRandom::RandBytes(void* data, size_t len) {
crypto::RandBytes(data, len);
}
-uint64 DefaultRandom::RandUint64() {
- uint64 value;
+uint64_t DefaultRandom::RandUint64() {
+ uint64_t value;
RandBytes(&value, sizeof(value));
return value;
}
@@ -50,6 +51,8 @@ void DefaultRandom::Reseed(const void* additional_entropy, size_t entropy_len) {
} // namespace
// static
-QuicRandom* QuicRandom::GetInstance() { return DefaultRandom::GetInstance(); }
+QuicRandom* QuicRandom::GetInstance() {
+ return DefaultRandom::GetInstance();
+}
} // namespace net
diff --git a/chromium/net/quic/crypto/quic_random.h b/chromium/net/quic/crypto/quic_random.h
index ac69b8567a9..e723241bd4f 100644
--- a/chromium/net/quic/crypto/quic_random.h
+++ b/chromium/net/quic/crypto/quic_random.h
@@ -6,8 +6,8 @@
#define NET_QUIC_CRYPTO_QUIC_RANDOM_H_
#include <stddef.h>
+#include <stdint.h>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
namespace net {
@@ -25,7 +25,7 @@ class NET_EXPORT_PRIVATE QuicRandom {
virtual void RandBytes(void* data, size_t len) = 0;
// Returns a random number in the range [0, kuint64max].
- virtual uint64 RandUint64() = 0;
+ virtual uint64_t RandUint64() = 0;
// Reseeds the random number generator with additional entropy input.
// NOTE: the constructor of a QuicRandom object is responsible for seeding
diff --git a/chromium/net/quic/crypto/quic_random_test.cc b/chromium/net/quic/crypto/quic_random_test.cc
index a76262572b1..431a22118da 100644
--- a/chromium/net/quic/crypto/quic_random_test.cc
+++ b/chromium/net/quic/crypto/quic_random_test.cc
@@ -23,8 +23,8 @@ TEST(QuicRandomTest, RandBytes) {
TEST(QuicRandomTest, RandUint64) {
QuicRandom* rng = QuicRandom::GetInstance();
- uint64 value1 = rng->RandUint64();
- uint64 value2 = rng->RandUint64();
+ uint64_t value1 = rng->RandUint64();
+ uint64_t value2 = rng->RandUint64();
EXPECT_NE(value1, value2);
}
diff --git a/chromium/net/quic/crypto/quic_server_info.cc b/chromium/net/quic/crypto/quic_server_info.cc
index 40111519fc2..2627fb48609 100644
--- a/chromium/net/quic/crypto/quic_server_info.cc
+++ b/chromium/net/quic/crypto/quic_server_info.cc
@@ -30,11 +30,9 @@ void QuicServerInfo::State::Clear() {
}
QuicServerInfo::QuicServerInfo(const QuicServerId& server_id)
- : server_id_(server_id) {
-}
+ : server_id_(server_id) {}
-QuicServerInfo::~QuicServerInfo() {
-}
+QuicServerInfo::~QuicServerInfo() {}
const QuicServerInfo::State& QuicServerInfo::state() const {
return state_;
@@ -91,13 +89,13 @@ bool QuicServerInfo::ParseInner(const string& data) {
}
// Read certs.
- uint32 num_certs;
+ uint32_t num_certs;
if (!iter.ReadUInt32(&num_certs)) {
DVLOG(1) << "Malformed num_certs";
return false;
}
- for (uint32 i = 0; i < num_certs; i++) {
+ for (uint32_t i = 0; i < num_certs; i++) {
string cert;
if (!iter.ReadString(&cert)) {
DVLOG(1) << "Malformed cert";
@@ -122,7 +120,7 @@ string QuicServerInfo::SerializeInner() const {
!p.WriteString(state_.server_config) ||
!p.WriteString(state_.source_address_token) ||
!p.WriteString(state_.server_config_sig) ||
- state_.certs.size() > std::numeric_limits<uint32>::max() ||
+ state_.certs.size() > std::numeric_limits<uint32_t>::max() ||
!p.WriteUInt32(state_.certs.size())) {
return string();
}
@@ -133,7 +131,7 @@ string QuicServerInfo::SerializeInner() const {
}
}
- return string(reinterpret_cast<const char *>(p.data()), p.size());
+ return string(reinterpret_cast<const char*>(p.data()), p.size());
}
QuicServerInfoFactory::~QuicServerInfoFactory() {}
diff --git a/chromium/net/quic/crypto/quic_server_info.h b/chromium/net/quic/crypto/quic_server_info.h
index 1e4e1bd4874..be15240805f 100644
--- a/chromium/net/quic/crypto/quic_server_info.h
+++ b/chromium/net/quic/crypto/quic_server_info.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
@@ -107,12 +108,17 @@ class NET_EXPORT_PRIVATE QuicServerInfo {
// fields will be set to something sane in any case.
bool Parse(const std::string& data);
std::string Serialize();
+
State state_;
// Time when WaitForDataReady was called and when it has finished.
base::TimeTicks wait_for_data_start_time_;
base::TimeTicks wait_for_data_end_time_;
+ // This is the QUIC server (hostname, port, is_https, privacy_mode) tuple for
+ // which we restore the crypto_config.
+ const QuicServerId server_id_;
+
private:
// ParseInner is a helper function for Parse.
bool ParseInner(const std::string& data);
@@ -120,10 +126,6 @@ class NET_EXPORT_PRIVATE QuicServerInfo {
// SerializeInner is a helper function for Serialize.
std::string SerializeInner() const;
- // This is the QUIC server (hostname, port, is_https, privacy_mode) tuple for
- // which we restore the crypto_config.
- const QuicServerId server_id_;
-
DISALLOW_COPY_AND_ASSIGN(QuicServerInfo);
};
diff --git a/chromium/net/quic/crypto/scoped_evp_aead_ctx.h b/chromium/net/quic/crypto/scoped_evp_aead_ctx.h
index f0f04c1caaf..d8067fc0d9e 100644
--- a/chromium/net/quic/crypto/scoped_evp_aead_ctx.h
+++ b/chromium/net/quic/crypto/scoped_evp_aead_ctx.h
@@ -7,7 +7,7 @@
#include <openssl/evp.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
namespace net {
diff --git a/chromium/net/quic/crypto/strike_register.cc b/chromium/net/quic/crypto/strike_register.cc
index c9b13539d12..9cea0f11f8c 100644
--- a/chromium/net/quic/crypto/strike_register.cc
+++ b/chromium/net/quic/crypto/strike_register.cc
@@ -4,6 +4,7 @@
#include "net/quic/crypto/strike_register.h"
+#include <algorithm>
#include <limits>
#include "base/logging.h"
@@ -16,9 +17,9 @@ namespace net {
namespace {
-uint32 GetInitialHorizon(uint32 current_time_internal,
- uint32 window_secs,
- StrikeRegister::StartupType startup) {
+uint32_t GetInitialHorizon(uint32_t current_time_internal,
+ uint32_t window_secs,
+ StrikeRegister::StartupType startup) {
if (startup == StrikeRegister::DENY_REQUESTS_AT_STARTUP) {
// The horizon is initially set |window_secs| into the future because, if
// we just crashed, then we may have accepted nonces in the span
@@ -35,50 +36,50 @@ uint32 GetInitialHorizon(uint32 current_time_internal,
} // namespace
// static
-const uint32 StrikeRegister::kExternalNodeSize = 24;
+const uint32_t StrikeRegister::kExternalNodeSize = 24;
// static
-const uint32 StrikeRegister::kNil = (1u << 31) | 1;
+const uint32_t StrikeRegister::kNil = (1u << 31) | 1;
// static
-const uint32 StrikeRegister::kExternalFlag = 1 << 23;
+const uint32_t StrikeRegister::kExternalFlag = 1 << 23;
// InternalNode represents a non-leaf node in the critbit tree. See the comment
// in the .h file for details.
class StrikeRegister::InternalNode {
public:
- void SetChild(unsigned direction, uint32 child) {
+ void SetChild(unsigned direction, uint32_t child) {
data_[direction] = (data_[direction] & 0xff) | (child << 8);
}
- void SetCritByte(uint8 critbyte) {
+ void SetCritByte(uint8_t critbyte) {
data_[0] = (data_[0] & 0xffffff00) | critbyte;
}
- void SetOtherBits(uint8 otherbits) {
+ void SetOtherBits(uint8_t otherbits) {
data_[1] = (data_[1] & 0xffffff00) | otherbits;
}
- void SetNextPtr(uint32 next) { data_[0] = next; }
+ void SetNextPtr(uint32_t next) { data_[0] = next; }
- uint32 next() const { return data_[0]; }
+ uint32_t next() const { return data_[0]; }
- uint32 child(unsigned n) const { return data_[n] >> 8; }
+ uint32_t child(unsigned n) const { return data_[n] >> 8; }
- uint8 critbyte() const { return static_cast<uint8>(data_[0]); }
+ uint8_t critbyte() const { return static_cast<uint8_t>(data_[0]); }
- uint8 otherbits() const { return static_cast<uint8>(data_[1]); }
+ uint8_t otherbits() const { return static_cast<uint8_t>(data_[1]); }
// These bytes are organised thus:
// <24 bits> left child
// <8 bits> crit-byte
// <24 bits> right child
// <8 bits> other-bits
- uint32 data_[2];
+ uint32_t data_[2];
};
// kCreationTimeFromInternalEpoch contains the number of seconds between the
// start of the internal epoch and the creation time. This allows us
// to consider times that are before the creation time.
-static const uint32 kCreationTimeFromInternalEpoch = 63115200; // 2 years.
+static const uint32_t kCreationTimeFromInternalEpoch = 63115200; // 2 years.
void StrikeRegister::ValidateStrikeRegisterConfig(unsigned max_entries) {
// We only have 23 bits of index available.
@@ -88,27 +89,30 @@ void StrikeRegister::ValidateStrikeRegisterConfig(unsigned max_entries) {
}
StrikeRegister::StrikeRegister(unsigned max_entries,
- uint32 current_time,
- uint32 window_secs,
- const uint8 orbit[8],
+ uint32_t current_time,
+ uint32_t window_secs,
+ const uint8_t orbit[8],
StartupType startup)
: max_entries_(max_entries),
window_secs_(window_secs),
internal_epoch_(current_time > kCreationTimeFromInternalEpoch
? current_time - kCreationTimeFromInternalEpoch
: 0),
- horizon_(GetInitialHorizon(
- ExternalTimeToInternal(current_time), window_secs, startup)) {
+ horizon_(GetInitialHorizon(ExternalTimeToInternal(current_time),
+ window_secs,
+ startup)) {
memcpy(orbit_, orbit, sizeof(orbit_));
ValidateStrikeRegisterConfig(max_entries);
internal_nodes_ = new InternalNode[max_entries];
- external_nodes_.reset(new uint8[kExternalNodeSize * max_entries]);
+ external_nodes_.reset(new uint8_t[kExternalNodeSize * max_entries]);
Reset();
}
-StrikeRegister::~StrikeRegister() { delete[] internal_nodes_; }
+StrikeRegister::~StrikeRegister() {
+ delete[] internal_nodes_;
+}
void StrikeRegister::Reset() {
// Thread a free list through all of the internal nodes.
@@ -129,32 +133,31 @@ void StrikeRegister::Reset() {
internal_node_head_ = kNil;
}
-InsertStatus StrikeRegister::Insert(const uint8 nonce[32],
- uint32 current_time_external) {
+InsertStatus StrikeRegister::Insert(const uint8_t nonce[32],
+ uint32_t current_time_external) {
// Make space for the insertion if the strike register is full.
- while (external_node_free_head_ == kNil ||
- internal_node_free_head_ == kNil) {
+ while (external_node_free_head_ == kNil || internal_node_free_head_ == kNil) {
DropOldestNode();
}
- const uint32 current_time = ExternalTimeToInternal(current_time_external);
+ const uint32_t current_time = ExternalTimeToInternal(current_time_external);
// Check to see if the orbit is correct.
if (memcmp(nonce + sizeof(current_time), orbit_, sizeof(orbit_))) {
return NONCE_INVALID_ORBIT_FAILURE;
}
- const uint32 nonce_time = ExternalTimeToInternal(TimeFromBytes(nonce));
+ const uint32_t nonce_time = ExternalTimeToInternal(TimeFromBytes(nonce));
// Check that the timestamp is in the valid range.
- pair<uint32, uint32> valid_range =
+ pair<uint32_t, uint32_t> valid_range =
StrikeRegister::GetValidRange(current_time);
if (nonce_time < valid_range.first || nonce_time > valid_range.second) {
return NONCE_INVALID_TIME_FAILURE;
}
// We strip the orbit out of the nonce.
- uint8 value[24];
+ uint8_t value[24];
memcpy(value, nonce, sizeof(nonce_time));
memcpy(value + sizeof(nonce_time),
nonce + sizeof(nonce_time) + sizeof(orbit_),
@@ -163,25 +166,25 @@ InsertStatus StrikeRegister::Insert(const uint8 nonce[32],
// Find the best match to |value| in the crit-bit tree. The best match is
// simply the value which /could/ match |value|, if any does, so we still
// need a memcmp to check.
- uint32 best_match_index = BestMatch(value);
+ uint32_t best_match_index = BestMatch(value);
if (best_match_index == kNil) {
// Empty tree. Just insert the new value at the root.
- uint32 index = GetFreeExternalNode();
+ uint32_t index = GetFreeExternalNode();
memcpy(external_node(index), value, sizeof(value));
internal_node_head_ = (index | kExternalFlag) << 8;
DCHECK_LE(horizon_, nonce_time);
return NONCE_OK;
}
- const uint8* best_match = external_node(best_match_index);
+ const uint8_t* best_match = external_node(best_match_index);
if (memcmp(best_match, value, sizeof(value)) == 0) {
// We found the value in the tree.
return NONCE_NOT_UNIQUE_FAILURE;
}
// We are going to insert a new entry into the tree, so get the nodes now.
- uint32 internal_node_index = GetFreeInternalNode();
- uint32 external_node_index = GetFreeExternalNode();
+ uint32_t internal_node_index = GetFreeInternalNode();
+ uint32_t external_node_index = GetFreeExternalNode();
// If we just evicted the best match, then we have to try and match again.
// We know that we didn't just empty the tree because we require that
@@ -193,8 +196,8 @@ InsertStatus StrikeRegister::Insert(const uint8 nonce[32],
}
// Now we need to find the first bit where we differ from |best_match|.
- uint8 differing_byte;
- uint8 new_other_bits;
+ uint8_t differing_byte;
+ uint8_t new_other_bits;
for (differing_byte = 0; differing_byte < arraysize(value);
differing_byte++) {
new_other_bits = value[differing_byte] ^ best_match[differing_byte];
@@ -232,13 +235,13 @@ InsertStatus StrikeRegister::Insert(const uint8 nonce[32],
inode->SetCritByte(differing_byte);
inode->SetOtherBits(new_other_bits);
- // |where_index| is a pointer to the uint32 which needs to be updated in
+ // |where_index| is a pointer to the uint32_t which needs to be updated in
// order to insert the new internal node into the tree. The internal nodes
// store the child indexes in the top 24-bits of a 32-bit word and, to keep
// the code simple, we define that |internal_node_head_| is organised the
// same way.
DCHECK_EQ(internal_node_head_ & 0xff, 0u);
- uint32* where_index = &internal_node_head_;
+ uint32_t* where_index = &internal_node_head_;
while (((*where_index >> 8) & kExternalFlag) == 0) {
InternalNode* node = &internal_nodes_[*where_index >> 8];
if (node->critbyte() > differing_byte) {
@@ -253,7 +256,7 @@ InsertStatus StrikeRegister::Insert(const uint8 nonce[32],
CHECK(false);
}
- uint8 c = value[node->critbyte()];
+ uint8_t c = value[node->critbyte()];
const int direction =
(1 + static_cast<unsigned>(node->otherbits() | c)) >> 8;
where_index = &node->data_[direction];
@@ -266,15 +269,15 @@ InsertStatus StrikeRegister::Insert(const uint8 nonce[32],
return NONCE_OK;
}
-const uint8* StrikeRegister::orbit() const {
+const uint8_t* StrikeRegister::orbit() const {
return orbit_;
}
-uint32 StrikeRegister::GetCurrentValidWindowSecs(
- uint32 current_time_external) const {
- uint32 current_time = ExternalTimeToInternal(current_time_external);
- pair<uint32, uint32> valid_range = StrikeRegister::GetValidRange(
- current_time);
+uint32_t StrikeRegister::GetCurrentValidWindowSecs(
+ uint32_t current_time_external) const {
+ uint32_t current_time = ExternalTimeToInternal(current_time_external);
+ pair<uint32_t, uint32_t> valid_range =
+ StrikeRegister::GetValidRange(current_time);
if (valid_range.second >= valid_range.first) {
return valid_range.second - current_time + 1;
} else {
@@ -283,24 +286,24 @@ uint32 StrikeRegister::GetCurrentValidWindowSecs(
}
void StrikeRegister::Validate() {
- set<uint32> free_internal_nodes;
- for (uint32 i = internal_node_free_head_; i != kNil;
+ set<uint32_t> free_internal_nodes;
+ for (uint32_t i = internal_node_free_head_; i != kNil;
i = internal_nodes_[i].next()) {
CHECK_LT(i, max_entries_);
CHECK_EQ(free_internal_nodes.count(i), 0u);
free_internal_nodes.insert(i);
}
- set<uint32> free_external_nodes;
- for (uint32 i = external_node_free_head_; i != kNil;
+ set<uint32_t> free_external_nodes;
+ for (uint32_t i = external_node_free_head_; i != kNil;
i = external_node_next_ptr(i)) {
CHECK_LT(i, max_entries_);
CHECK_EQ(free_external_nodes.count(i), 0u);
free_external_nodes.insert(i);
}
- set<uint32> used_external_nodes;
- set<uint32> used_internal_nodes;
+ set<uint32_t> used_external_nodes;
+ set<uint32_t> used_internal_nodes;
if (internal_node_head_ != kNil &&
((internal_node_head_ >> 8) & kExternalFlag) == 0) {
@@ -312,21 +315,19 @@ void StrikeRegister::Validate() {
}
// static
-uint32 StrikeRegister::TimeFromBytes(const uint8 d[4]) {
- return static_cast<uint32>(d[0]) << 24 |
- static_cast<uint32>(d[1]) << 16 |
- static_cast<uint32>(d[2]) << 8 |
- static_cast<uint32>(d[3]);
+uint32_t StrikeRegister::TimeFromBytes(const uint8_t d[4]) {
+ return static_cast<uint32_t>(d[0]) << 24 | static_cast<uint32_t>(d[1]) << 16 |
+ static_cast<uint32_t>(d[2]) << 8 | static_cast<uint32_t>(d[3]);
}
-pair<uint32, uint32> StrikeRegister::GetValidRange(
- uint32 current_time_internal) const {
+pair<uint32_t, uint32_t> StrikeRegister::GetValidRange(
+ uint32_t current_time_internal) const {
if (current_time_internal < horizon_) {
// Empty valid range.
- return std::make_pair(std::numeric_limits<uint32>::max(), 0);
+ return std::make_pair(std::numeric_limits<uint32_t>::max(), 0);
}
- uint32 lower_bound;
+ uint32_t lower_bound;
if (current_time_internal >= window_secs_) {
lower_bound = std::max(horizon_, current_time_internal - window_secs_);
} else {
@@ -339,25 +340,26 @@ pair<uint32, uint32> StrikeRegister::GetValidRange(
// allows the strike server to degrade optimally in cases where the
// insert rate exceeds |max_entries_ / (2 * window_secs_)| entries
// per second.
- uint32 upper_bound = current_time_internal +
- std::min(current_time_internal - horizon_, window_secs_);
+ uint32_t upper_bound =
+ current_time_internal +
+ std::min(current_time_internal - horizon_, window_secs_);
return std::make_pair(lower_bound, upper_bound);
}
-uint32 StrikeRegister::ExternalTimeToInternal(uint32 external_time) const {
+uint32_t StrikeRegister::ExternalTimeToInternal(uint32_t external_time) const {
return external_time - internal_epoch_;
}
-uint32 StrikeRegister::BestMatch(const uint8 v[24]) const {
+uint32_t StrikeRegister::BestMatch(const uint8_t v[24]) const {
if (internal_node_head_ == kNil) {
return kNil;
}
- uint32 next = internal_node_head_ >> 8;
+ uint32_t next = internal_node_head_ >> 8;
while ((next & kExternalFlag) == 0) {
InternalNode* node = &internal_nodes_[next];
- uint8 b = v[node->critbyte()];
+ uint8_t b = v[node->critbyte()];
unsigned direction =
(1 + static_cast<unsigned>(node->otherbits() | b)) >> 8;
next = node->child(direction);
@@ -366,23 +368,23 @@ uint32 StrikeRegister::BestMatch(const uint8 v[24]) const {
return next & ~kExternalFlag;
}
-uint32& StrikeRegister::external_node_next_ptr(unsigned i) {
- return *reinterpret_cast<uint32*>(&external_nodes_[i * kExternalNodeSize]);
+uint32_t& StrikeRegister::external_node_next_ptr(unsigned i) {
+ return *reinterpret_cast<uint32_t*>(&external_nodes_[i * kExternalNodeSize]);
}
-uint8* StrikeRegister::external_node(unsigned i) {
+uint8_t* StrikeRegister::external_node(unsigned i) {
return &external_nodes_[i * kExternalNodeSize];
}
-uint32 StrikeRegister::GetFreeExternalNode() {
- uint32 index = external_node_free_head_;
+uint32_t StrikeRegister::GetFreeExternalNode() {
+ uint32_t index = external_node_free_head_;
DCHECK(index != kNil);
external_node_free_head_ = external_node_next_ptr(index);
return index;
}
-uint32 StrikeRegister::GetFreeInternalNode() {
- uint32 index = internal_node_free_head_;
+uint32_t StrikeRegister::GetFreeInternalNode() {
+ uint32_t index = internal_node_free_head_;
DCHECK(index != kNil);
internal_node_free_head_ = internal_nodes_[index].next();
return index;
@@ -398,8 +400,8 @@ void StrikeRegister::DropOldestNode() {
// to do that we keep pointers to the parent (wherep) and grandparent
// (whereq) when walking down the tree.
- uint32 p = internal_node_head_ >> 8, *wherep = &internal_node_head_,
- *whereq = nullptr;
+ uint32_t p = internal_node_head_ >> 8, *wherep = &internal_node_head_,
+ *whereq = nullptr;
while ((p & kExternalFlag) == 0) {
whereq = wherep;
InternalNode* inode = &internal_nodes_[p];
@@ -409,9 +411,9 @@ void StrikeRegister::DropOldestNode() {
p = (*wherep) >> 8;
}
- const uint32 ext_index = p & ~kExternalFlag;
- const uint8* ext_node = external_node(ext_index);
- uint32 new_horizon = ExternalTimeToInternal(TimeFromBytes(ext_node)) + 1;
+ const uint32_t ext_index = p & ~kExternalFlag;
+ const uint8_t* ext_node = external_node(ext_index);
+ uint32_t new_horizon = ExternalTimeToInternal(TimeFromBytes(ext_node)) + 1;
DCHECK_LE(horizon_, new_horizon);
horizon_ = new_horizon;
@@ -424,29 +426,29 @@ void StrikeRegister::DropOldestNode() {
// |wherep| points to the left child pointer in the parent so we can add
// one and dereference to get the right child.
- const uint32 other_child = wherep[1];
+ const uint32_t other_child = wherep[1];
FreeInternalNode((*whereq) >> 8);
*whereq = (*whereq & 0xff) | (other_child & 0xffffff00);
FreeExternalNode(ext_index);
}
-void StrikeRegister::FreeExternalNode(uint32 index) {
+void StrikeRegister::FreeExternalNode(uint32_t index) {
external_node_next_ptr(index) = external_node_free_head_;
external_node_free_head_ = index;
}
-void StrikeRegister::FreeInternalNode(uint32 index) {
+void StrikeRegister::FreeInternalNode(uint32_t index) {
internal_nodes_[index].SetNextPtr(internal_node_free_head_);
internal_node_free_head_ = index;
}
-void StrikeRegister::ValidateTree(uint32 internal_node,
+void StrikeRegister::ValidateTree(uint32_t internal_node,
int last_bit,
const vector<pair<unsigned, bool>>& bits,
- const set<uint32>& free_internal_nodes,
- const set<uint32>& free_external_nodes,
- set<uint32>* used_internal_nodes,
- set<uint32>* used_external_nodes) {
+ const set<uint32_t>& free_internal_nodes,
+ const set<uint32_t>& free_external_nodes,
+ set<uint32_t>* used_internal_nodes,
+ set<uint32_t>* used_external_nodes) {
CHECK_LT(internal_node, max_entries_);
const InternalNode* i = &internal_nodes_[internal_node];
unsigned bit = 0;
@@ -488,21 +490,21 @@ void StrikeRegister::ValidateTree(uint32 internal_node,
for (unsigned child = 0; child < 2; child++) {
if (i->child(child) & kExternalFlag) {
- uint32 ext = i->child(child) & ~kExternalFlag;
+ uint32_t ext = i->child(child) & ~kExternalFlag;
CHECK_EQ(free_external_nodes.count(ext), 0u);
CHECK_EQ(used_external_nodes->count(ext), 0u);
used_external_nodes->insert(ext);
- const uint8* bytes = external_node(ext);
+ const uint8_t* bytes = external_node(ext);
for (const pair<unsigned, bool>& pair : bits) {
unsigned byte = pair.first / 8;
DCHECK_LE(byte, 0xffu);
unsigned bit_new = pair.first % 8;
- static const uint8 kMasks[8] =
- {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+ static const uint8_t kMasks[8] = {0x80, 0x40, 0x20, 0x10,
+ 0x08, 0x04, 0x02, 0x01};
CHECK_EQ((bytes[byte] & kMasks[bit_new]) != 0, pair.second);
}
} else {
- uint32 inter = i->child(child);
+ uint32_t inter = i->child(child);
vector<pair<unsigned, bool>> new_bits(bits);
new_bits.push_back(pair<unsigned, bool>(bit, child != 0));
CHECK_EQ(free_internal_nodes.count(inter), 0u);
diff --git a/chromium/net/quic/crypto/strike_register.h b/chromium/net/quic/crypto/strike_register.h
index cbd0b8ececc..fd3f5a7d25e 100644
--- a/chromium/net/quic/crypto/strike_register.h
+++ b/chromium/net/quic/crypto/strike_register.h
@@ -5,11 +5,13 @@
#ifndef NET_QUIC_CRYPTO_STRIKE_REGISTER_H_
#define NET_QUIC_CRYPTO_STRIKE_REGISTER_H_
+#include <stdint.h>
+
#include <set>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -89,17 +91,17 @@ class NET_EXPORT_PRIVATE StrikeRegister {
};
// An external node takes 24 bytes as we don't record the orbit.
- static const uint32 kExternalNodeSize;
+ static const uint32_t kExternalNodeSize;
// We address the nodes by their index in the array. This means that 0 is a
// valid index. Therefore this is our invalid index. It also has a one bit
// in the LSB position because we tend to store indexes shifted up 8 bits
// and this distinguishes kNil from (kExternalFlag | 0) << 8.
- static const uint32 kNil;
+ static const uint32_t kNil;
// Our pointers from internal nodes can either point to an internal or
// external node. We flag the 24th bit to mark a pointer as external.
- static const uint32 kExternalFlag;
+ static const uint32_t kExternalFlag;
// Allows early validation before a strike register is created.
static void ValidateStrikeRegisterConfig(unsigned max_entries);
@@ -113,9 +115,9 @@ class NET_EXPORT_PRIVATE StrikeRegister {
// (Note that this code is independent of the actual units of time used, but
// you should use seconds.)
StrikeRegister(unsigned max_entries,
- uint32 current_time_external,
- uint32 window_secs,
- const uint8 orbit[8],
+ uint32_t current_time_external,
+ uint32_t window_secs,
+ const uint8_t orbit[8],
StartupType startup);
~StrikeRegister();
@@ -137,14 +139,14 @@ class NET_EXPORT_PRIVATE StrikeRegister {
// 20 bytes of random data
//
// Otherwise, it inserts |nonce| into the observed set and returns NONCE_OK.
- InsertStatus Insert(const uint8 nonce[32], uint32 current_time);
+ InsertStatus Insert(const uint8_t nonce[32], uint32_t current_time);
// orbit returns a pointer to the 8-byte orbit value for this
// strike-register.
- const uint8* orbit() const;
+ const uint8_t* orbit() const;
// Time window for which the strike register has complete information.
- uint32 GetCurrentValidWindowSecs(uint32 current_time_external) const;
+ uint32_t GetCurrentValidWindowSecs(uint32_t current_time_external) const;
// This is a debugging aid which checks the tree for sanity.
void Validate();
@@ -152,65 +154,66 @@ class NET_EXPORT_PRIVATE StrikeRegister {
private:
class InternalNode;
- // TimeFromBytes returns a big-endian uint32 from |d|.
- static uint32 TimeFromBytes(const uint8 d[4]);
+ // TimeFromBytes returns a big-endian uint32_t from |d|.
+ static uint32_t TimeFromBytes(const uint8_t d[4]);
// Range of internal times for which the strike register has
// complete information. A nonce is within the valid range of the
// strike register if:
// valid_range.first <= nonce_time_internal <= valid_range.second
- std::pair<uint32, uint32> GetValidRange(uint32 current_time_internal) const;
+ std::pair<uint32_t, uint32_t> GetValidRange(
+ uint32_t current_time_internal) const;
// ExternalTimeToInternal converts an external time value into an internal
// time value using |internal_epoch_|.
- uint32 ExternalTimeToInternal(uint32 external_time) const;
+ uint32_t ExternalTimeToInternal(uint32_t external_time) const;
// BestMatch returns either kNil, or an external node index which could
// possibly match |v|.
- uint32 BestMatch(const uint8 v[24]) const;
+ uint32_t BestMatch(const uint8_t v[24]) const;
// external_node_next_ptr returns the 'next' pointer embedded in external
// node |i|. This is used to thread a free list through the external nodes.
- uint32& external_node_next_ptr(unsigned i);
+ uint32_t& external_node_next_ptr(unsigned i);
- uint8* external_node(unsigned i);
+ uint8_t* external_node(unsigned i);
- uint32 GetFreeExternalNode();
+ uint32_t GetFreeExternalNode();
- uint32 GetFreeInternalNode();
+ uint32_t GetFreeInternalNode();
// DropOldestNode removes the oldest node in the tree and updates |horizon_|
// accordingly.
void DropOldestNode();
- void FreeExternalNode(uint32 index);
+ void FreeExternalNode(uint32_t index);
- void FreeInternalNode(uint32 index);
+ void FreeInternalNode(uint32_t index);
- void ValidateTree(uint32 internal_node,
+ void ValidateTree(uint32_t internal_node,
int last_bit,
const std::vector<std::pair<unsigned, bool>>& bits,
- const std::set<uint32>& free_internal_nodes,
- const std::set<uint32>& free_external_nodes,
- std::set<uint32>* used_internal_nodes,
- std::set<uint32>* used_external_nodes);
+ const std::set<uint32_t>& free_internal_nodes,
+ const std::set<uint32_t>& free_external_nodes,
+ std::set<uint32_t>* used_internal_nodes,
+ std::set<uint32_t>* used_external_nodes);
- const uint32 max_entries_;
- const uint32 window_secs_;
+ const uint32_t max_entries_;
+ const uint32_t window_secs_;
// internal_epoch_ contains the external time value of the start of internal
// time.
- const uint32 internal_epoch_;
- uint8 orbit_[8];
+ const uint32_t internal_epoch_;
+ uint8_t orbit_[8];
// The strike register will reject nonces with internal times < |horizon_| .
- uint32 horizon_;
+ uint32_t horizon_;
- uint32 internal_node_free_head_;
- uint32 external_node_free_head_;
- uint32 internal_node_head_;
+ uint32_t internal_node_free_head_;
+ uint32_t external_node_free_head_;
+ uint32_t internal_node_head_;
// internal_nodes_ can't be a scoped_ptr because the type isn't defined in
// this header.
InternalNode* internal_nodes_;
- scoped_ptr<uint8[]> external_nodes_;
+ scoped_ptr<uint8_t[]> external_nodes_;
DISALLOW_COPY_AND_ASSIGN(StrikeRegister);
};
diff --git a/chromium/net/quic/crypto/strike_register_client.h b/chromium/net/quic/crypto/strike_register_client.h
index dae35197a36..2bbf5b6d63c 100644
--- a/chromium/net/quic/crypto/strike_register_client.h
+++ b/chromium/net/quic/crypto/strike_register_client.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/quic/crypto/strike_register.h"
@@ -47,10 +47,9 @@ class NET_EXPORT_PRIVATE StrikeRegisterClient {
// Will invoke cb->Run(ValidateResponse::nonce_is_valid_and_unique(),
// ValidateResponse::nonce_error())
// once the asynchronous operation is complete.
- virtual void VerifyNonceIsValidAndUnique(
- base::StringPiece nonce,
- QuicWallTime now,
- ResultCallback* cb) = 0;
+ virtual void VerifyNonceIsValidAndUnique(base::StringPiece nonce,
+ QuicWallTime now,
+ ResultCallback* cb) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(StrikeRegisterClient);
diff --git a/chromium/net/quic/crypto/strike_register_test.cc b/chromium/net/quic/crypto/strike_register_test.cc
index cbb189ab2fa..2fca33fcff4 100644
--- a/chromium/net/quic/crypto/strike_register_test.cc
+++ b/chromium/net/quic/crypto/strike_register_test.cc
@@ -7,7 +7,6 @@
#include <set>
#include <string>
-#include "base/basictypes.h"
#include "base/rand_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -20,11 +19,11 @@ using std::pair;
using std::set;
using std::string;
-const uint8 kOrbit[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+const uint8_t kOrbit[8] = {1, 2, 3, 4, 5, 6, 7, 8};
// StrikeRegisterTests don't look at the random bytes so this function can
// simply set the random bytes to 0.
-void SetNonce(uint8 nonce[32], unsigned time, const uint8 orbit[8]) {
+void SetNonce(uint8_t nonce[32], unsigned time, const uint8_t orbit[8]) {
nonce[0] = time >> 24;
nonce[1] = time >> 16;
nonce[2] = time >> 8;
@@ -38,7 +37,7 @@ TEST(StrikeRegisterTest, SimpleHorizon) {
StrikeRegister set(10 /* max size */, 1000 /* current time */,
100 /* window secs */, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP);
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, 999, kOrbit);
EXPECT_EQ(NONCE_INVALID_TIME_FAILURE, set.Insert(nonce, 1000));
SetNonce(nonce, 1000, kOrbit);
@@ -58,7 +57,7 @@ TEST(StrikeRegisterTest, NoStartupMode) {
StrikeRegister set(10 /* max size */, 1000 /* current time */,
100 /* window secs */, kOrbit,
StrikeRegister::NO_STARTUP_PERIOD_NEEDED);
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, 1000, kOrbit);
EXPECT_EQ(NONCE_OK, set.Insert(nonce, 1000));
EXPECT_EQ(NONCE_NOT_UNIQUE_FAILURE, set.Insert(nonce, 1000));
@@ -75,7 +74,7 @@ TEST(StrikeRegisterTest, WindowFuture) {
StrikeRegister set(10 /* max size */, 1000 /* current time */,
100 /* window secs */, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP);
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, 1101, kOrbit);
EXPECT_EQ(NONCE_INVALID_TIME_FAILURE, set.Insert(nonce, 1000));
SetNonce(nonce, 999, kOrbit);
@@ -87,8 +86,8 @@ TEST(StrikeRegisterTest, BadOrbit) {
StrikeRegister set(10 /* max size */, 1000 /* current time */,
100 /* window secs */, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP);
- uint8 nonce[32];
- static const uint8 kBadOrbit[8] = { 0, 0, 0, 0, 1, 1, 1, 1 };
+ uint8_t nonce[32];
+ static const uint8_t kBadOrbit[8] = {0, 0, 0, 0, 1, 1, 1, 1};
SetNonce(nonce, 1101, kBadOrbit);
EXPECT_EQ(NONCE_INVALID_ORBIT_FAILURE, set.Insert(nonce, 1100));
}
@@ -97,7 +96,7 @@ TEST(StrikeRegisterTest, OneValue) {
StrikeRegister set(10 /* max size */, 1000 /* current time */,
100 /* window secs */, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP);
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, 1101, kOrbit);
EXPECT_EQ(NONCE_OK, set.Insert(nonce, 1101));
}
@@ -107,7 +106,7 @@ TEST(StrikeRegisterTest, RejectDuplicate) {
StrikeRegister set(10 /* max size */, 1000 /* current time */,
100 /* window secs */, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP);
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, 1101, kOrbit);
EXPECT_EQ(NONCE_OK, set.Insert(nonce, 1101));
EXPECT_EQ(NONCE_NOT_UNIQUE_FAILURE, set.Insert(nonce, 1101));
@@ -115,15 +114,13 @@ TEST(StrikeRegisterTest, RejectDuplicate) {
TEST(StrikeRegisterTest, HorizonUpdating) {
StrikeRegister::StartupType startup_types[] = {
- StrikeRegister::DENY_REQUESTS_AT_STARTUP,
- StrikeRegister::NO_STARTUP_PERIOD_NEEDED
- };
+ StrikeRegister::DENY_REQUESTS_AT_STARTUP,
+ StrikeRegister::NO_STARTUP_PERIOD_NEEDED};
for (size_t type_idx = 0; type_idx < arraysize(startup_types); ++type_idx) {
StrikeRegister set(5 /* max size */, 500 /* current time */,
- 100 /* window secs */, kOrbit,
- startup_types[type_idx]);
- uint8 nonce[6][32];
+ 100 /* window secs */, kOrbit, startup_types[type_idx]);
+ uint8_t nonce[6][32];
for (unsigned i = 0; i < 5; i++) {
SetNonce(nonce[i], 1101 + i, kOrbit);
nonce[i][31] = i;
@@ -172,16 +169,15 @@ TEST(StrikeRegisterTest, InsertMany) {
500 /* window secs */, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP);
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, 1101, kOrbit);
for (unsigned i = 0; i < 100000; i++) {
- SetNonce(nonce, 1101 + i/500, kOrbit);
+ SetNonce(nonce, 1101 + i / 500, kOrbit);
memcpy(nonce + 12, &i, sizeof(i));
EXPECT_EQ(NONCE_INVALID_TIME_FAILURE, set.Insert(nonce, 1100));
}
}
-
// For the following test we create a slow, but simple, version of a
// StrikeRegister. The behaviour of this object is much easier to understand
// than the fully fledged version. We then create a test to show, empirically,
@@ -192,8 +188,10 @@ TEST(StrikeRegisterTest, InsertMany) {
// empirically test that their behaviours are identical.
class SlowStrikeRegister {
public:
- SlowStrikeRegister(unsigned max_entries, uint32 current_time,
- uint32 window_secs, const uint8 orbit[8])
+ SlowStrikeRegister(unsigned max_entries,
+ uint32_t current_time,
+ uint32_t window_secs,
+ const uint8_t orbit[8])
: max_entries_(max_entries),
window_secs_(window_secs),
creation_time_(current_time),
@@ -201,20 +199,20 @@ class SlowStrikeRegister {
memcpy(orbit_, orbit, sizeof(orbit_));
}
- InsertStatus Insert(const uint8 nonce_bytes[32],
- const uint32 nonce_time_external,
- const uint32 current_time_external) {
+ InsertStatus Insert(const uint8_t nonce_bytes[32],
+ const uint32_t nonce_time_external,
+ const uint32_t current_time_external) {
if (nonces_.size() == max_entries_) {
DropOldestEntry();
}
- const uint32 current_time = ExternalTimeToInternal(current_time_external);
+ const uint32_t current_time = ExternalTimeToInternal(current_time_external);
// Check to see if the orbit is correct.
if (memcmp(nonce_bytes + 4, orbit_, sizeof(orbit_))) {
return NONCE_INVALID_ORBIT_FAILURE;
}
- const uint32 nonce_time =
+ const uint32_t nonce_time =
ExternalTimeToInternal(TimeFromBytes(nonce_bytes));
EXPECT_EQ(ExternalTimeToInternal(nonce_time_external), nonce_time);
// We have dropped one or more nonces with a time value of |horizon_ - 1|,
@@ -231,10 +229,10 @@ class SlowStrikeRegister {
return NONCE_INVALID_TIME_FAILURE;
}
- pair<uint32, string> nonce = std::make_pair(
+ pair<uint32_t, string> nonce = std::make_pair(
nonce_time, string(reinterpret_cast<const char*>(nonce_bytes), 32));
- set<pair<uint32, string>>::const_iterator it = nonces_.find(nonce);
+ set<pair<uint32_t, string>>::const_iterator it = nonces_.find(nonce);
if (it != nonces_.end()) {
return NONCE_NOT_UNIQUE_FAILURE;
}
@@ -243,8 +241,9 @@ class SlowStrikeRegister {
return NONCE_OK;
}
- uint32 GetCurrentValidWindowSecs(const uint32 current_time_external) const {
- const uint32 current_time = ExternalTimeToInternal(current_time_external);
+ uint32_t GetCurrentValidWindowSecs(
+ const uint32_t current_time_external) const {
+ const uint32_t current_time = ExternalTimeToInternal(current_time_external);
if (horizon_ > current_time) {
return 0;
}
@@ -252,17 +251,16 @@ class SlowStrikeRegister {
}
private:
- // TimeFromBytes returns a big-endian uint32 from |d|.
- static uint32 TimeFromBytes(const uint8 d[4]) {
- return static_cast<uint32>(d[0]) << 24 |
- static_cast<uint32>(d[1]) << 16 |
- static_cast<uint32>(d[2]) << 8 |
- static_cast<uint32>(d[3]);
+ // TimeFromBytes returns a big-endian uint32_t from |d|.
+ static uint32_t TimeFromBytes(const uint8_t d[4]) {
+ return static_cast<uint32_t>(d[0]) << 24 |
+ static_cast<uint32_t>(d[1]) << 16 |
+ static_cast<uint32_t>(d[2]) << 8 | static_cast<uint32_t>(d[3]);
}
- uint32 ExternalTimeToInternal(uint32 external_time) const {
- static const uint32 kCreationTimeFromInternalEpoch = 63115200.0;
- uint32 internal_epoch = 0;
+ uint32_t ExternalTimeToInternal(uint32_t external_time) const {
+ static const uint32_t kCreationTimeFromInternalEpoch = 63115200.0;
+ uint32_t internal_epoch = 0;
if (creation_time_ > kCreationTimeFromInternalEpoch) {
internal_epoch = creation_time_ - kCreationTimeFromInternalEpoch;
}
@@ -271,45 +269,44 @@ class SlowStrikeRegister {
}
void DropOldestEntry() {
- set<pair<uint32, string>>::iterator oldest = nonces_.begin();
+ set<pair<uint32_t, string>>::iterator oldest = nonces_.begin();
horizon_ = oldest->first + 1;
nonces_.erase(oldest);
}
const unsigned max_entries_;
const unsigned window_secs_;
- const uint32 creation_time_;
- uint8 orbit_[8];
- uint32 horizon_;
+ const uint32_t creation_time_;
+ uint8_t orbit_[8];
+ uint32_t horizon_;
- set<pair<uint32, string>> nonces_;
+ set<pair<uint32_t, string>> nonces_;
};
-class StrikeRegisterStressTest : public ::testing::Test {
-};
+class StrikeRegisterStressTest : public ::testing::Test {};
TEST_F(StrikeRegisterStressTest, InOrderInsertion) {
// Fixed seed gives reproducibility for this test.
srand(42);
unsigned max_entries = 64;
- uint32 current_time = 10000, window = 200;
+ uint32_t current_time = 10000, window = 200;
scoped_ptr<StrikeRegister> s1(
new StrikeRegister(max_entries, current_time, window, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP));
scoped_ptr<SlowStrikeRegister> s2(
new SlowStrikeRegister(max_entries, current_time, window, kOrbit));
- uint64 i;
- const uint64 kMaxIterations = 10000;
+ uint64_t i;
+ const uint64_t kMaxIterations = 10000;
for (i = 0; i < kMaxIterations; i++) {
- const uint32 time = current_time + i;
+ const uint32_t time = current_time + i;
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, time, kOrbit);
// There are 2048 possible nonce values:
- const uint32 v = rand() % 2048;
+ const uint32_t v = rand() % 2048;
nonce[30] = v >> 8;
nonce[31] = v;
@@ -344,18 +341,18 @@ TEST_F(StrikeRegisterStressTest, Stress) {
// Fixed seed gives reproducibility for this test.
srand(42);
unsigned max_entries = 64;
- uint32 current_time = 10000, window = 200;
+ uint32_t current_time = 10000, window = 200;
scoped_ptr<StrikeRegister> s1(
new StrikeRegister(max_entries, current_time, window, kOrbit,
StrikeRegister::DENY_REQUESTS_AT_STARTUP));
scoped_ptr<SlowStrikeRegister> s2(
new SlowStrikeRegister(max_entries, current_time, window, kOrbit));
- uint64 i;
+ uint64_t i;
// When making changes it's worth removing the limit on this test and running
// it for a while. For the initial development an opt binary was left running
// for 10 minutes.
- const uint64 kMaxIterations = 10000;
+ const uint64_t kMaxIterations = 10000;
for (i = 0; i < kMaxIterations; i++) {
if (rand() % 1000 == 0) {
// 0.1% chance of resetting the sets.
@@ -368,18 +365,18 @@ TEST_F(StrikeRegisterStressTest, Stress) {
new SlowStrikeRegister(max_entries, current_time, window, kOrbit));
}
- int32 time_delta = rand() % (window * 4);
+ int32_t time_delta = rand() % (window * 4);
time_delta -= window * 2;
- const uint32 time = current_time + time_delta;
+ const uint32_t time = current_time + time_delta;
if (time_delta < 0 && time > current_time) {
continue; // overflow
}
- uint8 nonce[32];
+ uint8_t nonce[32];
SetNonce(nonce, time, kOrbit);
// There are 2048 possible nonce values:
- const uint32 v = rand() % 2048;
+ const uint32_t v = rand() % 2048;
nonce[30] = v >> 8;
nonce[31] = v;
diff --git a/chromium/net/quic/interval_set.h b/chromium/net/quic/interval_set.h
index eae4fd7e705..e7e4b6d2f74 100644
--- a/chromium/net/quic/interval_set.h
+++ b/chromium/net/quic/interval_set.h
@@ -53,6 +53,7 @@
#define NET_QUIC_INTERVAL_SET_H_
#include <stddef.h>
+
#include <algorithm>
#include <set>
#include <string>
diff --git a/chromium/net/quic/interval_set_test.cc b/chromium/net/quic/interval_set_test.cc
index e3c351f8205..d09c8170823 100644
--- a/chromium/net/quic/interval_set_test.cc
+++ b/chromium/net/quic/interval_set_test.cc
@@ -417,8 +417,8 @@ TEST_F(IntervalSetTest, IntervalSetIntersectionMineBeforeTheirs) {
#if 0
TEST_F(IntervalSetTest,
IntervalSetIntersectionTheirsBeforeMineInt64Singletons) {
- IntervalSet<int64> mine({{10, 15}});
- IntervalSet<int64> theirs({{-20, -5}});
+ IntervalSet<int64_t> mine({{10, 15}});
+ IntervalSet<int64_t> theirs({{-20, -5}});
EXPECT_FALSE(mine.Intersects(theirs));
EXPECT_FALSE(theirs.Intersects(mine));
mine.Intersection(theirs);
@@ -439,8 +439,8 @@ TEST_F(IntervalSetTest, IntervalSetIntersectionMineBeforeTheirsIntSingletons) {
}
TEST_F(IntervalSetTest, IntervalSetIntersectionTheirsBetweenMine) {
- IntervalSet<int64> mine({{0, 5}, {40, 50}});
- IntervalSet<int64> theirs({{10, 15}});
+ IntervalSet<int64_t> mine({{0, 5}, {40, 50}});
+ IntervalSet<int64_t> theirs({{10, 15}});
EXPECT_FALSE(mine.Intersects(theirs));
EXPECT_FALSE(theirs.Intersects(mine));
mine.Intersection(theirs);
@@ -489,18 +489,18 @@ TEST_F(IntervalSetTest,
result1.Intersection(y1);
EXPECT_TRUE(result1.Empty()) << result1;
- const IntervalSet<int16> x2({{0, 10}, {20, 30}, {40, 90}});
- const IntervalSet<int16> y2(
+ const IntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
+ const IntervalSet<int16_t> y2(
{{-50, -40}, {-2, 0}, {10, 20}, {32, 40}, {90, 95}});
- IntervalSet<int16> result2 = x2;
+ IntervalSet<int16_t> result2 = x2;
result2.Intersection(y2);
EXPECT_TRUE(result2.Empty()) << result2;
- const IntervalSet<int64> x3({{-1, 5}, {5, 10}});
- const IntervalSet<int64> y3({{-10, -1}, {10, 95}});
+ const IntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
+ const IntervalSet<int64_t> y3({{-10, -1}, {10, 95}});
- IntervalSet<int64> result3 = x3;
+ IntervalSet<int64_t> result3 = x3;
result3.Intersection(y3);
EXPECT_TRUE(result3.Empty()) << result3;
}
@@ -515,21 +515,21 @@ TEST_F(IntervalSetTest,
result1.Intersection(y1);
EXPECT_EQ(result1, expected_result1);
- const IntervalSet<int16> x2({{0, 10}, {20, 30}, {40, 90}});
- const IntervalSet<int16> y2(
+ const IntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
+ const IntervalSet<int16_t> y2(
{{-50, -40}, {-2, 2}, {9, 21}, {32, 41}, {85, 95}});
- const IntervalSet<int16> expected_result2(
+ const IntervalSet<int16_t> expected_result2(
{{0, 2}, {9, 10}, {20, 21}, {40, 41}, {85, 90}});
- IntervalSet<int16> result2 = x2;
+ IntervalSet<int16_t> result2 = x2;
result2.Intersection(y2);
EXPECT_EQ(result2, expected_result2);
- const IntervalSet<int64> x3({{-1, 5}, {5, 10}});
- const IntervalSet<int64> y3({{-10, 3}, {4, 95}});
- const IntervalSet<int64> expected_result3({{-1, 3}, {4, 10}});
+ const IntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
+ const IntervalSet<int64_t> y3({{-10, 3}, {4, 95}});
+ const IntervalSet<int64_t> expected_result3({{-1, 3}, {4, 10}});
- IntervalSet<int64> result3 = x3;
+ IntervalSet<int64_t> result3 = x3;
result3.Intersection(y3);
EXPECT_EQ(result3, expected_result3);
}
diff --git a/chromium/net/quic/interval_test.cc b/chromium/net/quic/interval_test.cc
index 0157124edf0..ec2fd22bec3 100644
--- a/chromium/net/quic/interval_test.cc
+++ b/chromium/net/quic/interval_test.cc
@@ -14,7 +14,6 @@
#include <string>
#include <utility>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "net/test/gtest_util.h"
@@ -34,12 +33,12 @@ class IntervalTest : public ::testing::Test {
// i1.IntersectWith(i2) and vice versa. The intersection should change i1 iff
// changes_i1 is true, and the same for changes_i2. The resulting
// intersection should be result.
- void TestIntersect(const Interval<int64>& i1,
- const Interval<int64>& i2,
+ void TestIntersect(const Interval<int64_t>& i1,
+ const Interval<int64_t>& i2,
bool changes_i1,
bool changes_i2,
- const Interval<int64>& result) {
- Interval<int64> i;
+ const Interval<int64_t>& result) {
+ Interval<int64_t> i;
i.CopyFrom(i1);
EXPECT_TRUE(i.IntersectWith(i2) == changes_i1 && i.Equals(result));
i.CopyFrom(i2);
@@ -48,14 +47,14 @@ class IntervalTest : public ::testing::Test {
};
TEST_F(IntervalTest, ConstructorsCopyAndClear) {
- Interval<int32> empty;
+ Interval<int32_t> empty;
EXPECT_TRUE(empty.Empty());
- Interval<int32> d2(0, 100);
+ Interval<int32_t> d2(0, 100);
EXPECT_EQ(0, d2.min());
EXPECT_EQ(100, d2.max());
- EXPECT_EQ(Interval<int32>(0, 100), d2);
- EXPECT_NE(Interval<int32>(0, 99), d2);
+ EXPECT_EQ(Interval<int32_t>(0, 100), d2);
+ EXPECT_NE(Interval<int32_t>(0, 99), d2);
empty.CopyFrom(d2);
EXPECT_EQ(0, d2.min());
@@ -65,7 +64,7 @@ TEST_F(IntervalTest, ConstructorsCopyAndClear) {
EXPECT_TRUE(d2.Equals(empty));
EXPECT_EQ(d2, empty);
- Interval<int32> max_less_than_min(40, 20);
+ Interval<int32_t> max_less_than_min(40, 20);
EXPECT_TRUE(max_less_than_min.Empty());
EXPECT_EQ(40, max_less_than_min.min());
EXPECT_EQ(20, max_less_than_min.max());
@@ -76,7 +75,7 @@ TEST_F(IntervalTest, ConstructorsCopyAndClear) {
}
TEST_F(IntervalTest, GettersSetters) {
- Interval<int32> d1(100, 200);
+ Interval<int32_t> d1(100, 200);
// SetMin:
d1.SetMin(30);
@@ -95,7 +94,7 @@ TEST_F(IntervalTest, GettersSetters) {
EXPECT_EQ(220, d1.max());
// SpanningUnion:
- Interval<int32> d2;
+ Interval<int32_t> d2;
EXPECT_TRUE(!d1.SpanningUnion(d2));
EXPECT_EQ(30, d1.min());
EXPECT_EQ(220, d1.max());
@@ -139,16 +138,16 @@ TEST_F(IntervalTest, GettersSetters) {
}
TEST_F(IntervalTest, CoveringOps) {
- const Interval<int64> empty;
- const Interval<int64> d(100, 200);
- const Interval<int64> d1(0, 50);
- const Interval<int64> d2(50, 110);
- const Interval<int64> d3(110, 180);
- const Interval<int64> d4(180, 220);
- const Interval<int64> d5(220, 300);
- const Interval<int64> d6(100, 150);
- const Interval<int64> d7(150, 200);
- const Interval<int64> d8(0, 300);
+ const Interval<int64_t> empty;
+ const Interval<int64_t> d(100, 200);
+ const Interval<int64_t> d1(0, 50);
+ const Interval<int64_t> d2(50, 110);
+ const Interval<int64_t> d3(110, 180);
+ const Interval<int64_t> d4(180, 220);
+ const Interval<int64_t> d5(220, 300);
+ const Interval<int64_t> d6(100, 150);
+ const Interval<int64_t> d7(150, 200);
+ const Interval<int64_t> d8(0, 300);
// Intersection:
EXPECT_TRUE(d.Intersects(d));
@@ -162,16 +161,16 @@ TEST_F(IntervalTest, CoveringOps) {
EXPECT_TRUE(d.Intersects(d7) && d7.Intersects(d));
EXPECT_TRUE(d.Intersects(d8) && d8.Intersects(d));
- Interval<int64> i;
+ Interval<int64_t> i;
EXPECT_TRUE(d.Intersects(d, &i) && d.Equals(i));
EXPECT_TRUE(!empty.Intersects(d, NULL) && !d.Intersects(empty, NULL));
EXPECT_TRUE(!d.Intersects(d1, NULL) && !d1.Intersects(d, NULL));
- EXPECT_TRUE(d.Intersects(d2, &i) && i.Equals(Interval<int64>(100, 110)));
- EXPECT_TRUE(d2.Intersects(d, &i) && i.Equals(Interval<int64>(100, 110)));
+ EXPECT_TRUE(d.Intersects(d2, &i) && i.Equals(Interval<int64_t>(100, 110)));
+ EXPECT_TRUE(d2.Intersects(d, &i) && i.Equals(Interval<int64_t>(100, 110)));
EXPECT_TRUE(d.Intersects(d3, &i) && i.Equals(d3));
EXPECT_TRUE(d3.Intersects(d, &i) && i.Equals(d3));
- EXPECT_TRUE(d.Intersects(d4, &i) && i.Equals(Interval<int64>(180, 200)));
- EXPECT_TRUE(d4.Intersects(d, &i) && i.Equals(Interval<int64>(180, 200)));
+ EXPECT_TRUE(d.Intersects(d4, &i) && i.Equals(Interval<int64_t>(180, 200)));
+ EXPECT_TRUE(d4.Intersects(d, &i) && i.Equals(Interval<int64_t>(180, 200)));
EXPECT_TRUE(!d.Intersects(d5, NULL) && !d5.Intersects(d, NULL));
EXPECT_TRUE(d.Intersects(d6, &i) && i.Equals(d6));
EXPECT_TRUE(d6.Intersects(d, &i) && i.Equals(d6));
@@ -185,7 +184,7 @@ TEST_F(IntervalTest, CoveringOps) {
TestIntersect(empty, d, false, true, empty);
TestIntersect(d, d1, true, true, empty);
TestIntersect(d1, d2, true, true, empty);
- TestIntersect(d, d2, true, true, Interval<int64>(100, 110));
+ TestIntersect(d, d2, true, true, Interval<int64_t>(100, 110));
TestIntersect(d8, d, true, false, d);
TestIntersect(d8, d1, true, false, d1);
TestIntersect(d8, d5, true, false, d5);
@@ -209,7 +208,7 @@ TEST_F(IntervalTest, CoveringOps) {
EXPECT_TRUE(!d.Contains(201));
// Difference:
- vector<Interval<int64>*> diff;
+ vector<Interval<int64_t>*> diff;
EXPECT_TRUE(!d.Difference(empty, &diff));
EXPECT_EQ(1u, diff.size());
@@ -225,8 +224,8 @@ TEST_F(IntervalTest, CoveringOps) {
EXPECT_EQ(200u, diff[0]->max());
STLDeleteElements(&diff);
- Interval<int64> lo;
- Interval<int64> hi;
+ Interval<int64_t> lo;
+ Interval<int64_t> hi;
EXPECT_TRUE(d.Difference(d2, &lo, &hi));
EXPECT_TRUE(lo.Empty());
diff --git a/chromium/net/quic/iovector.h b/chromium/net/quic/iovector.h
index fcf50e87d57..0ea57bb05c1 100644
--- a/chromium/net/quic/iovector.h
+++ b/chromium/net/quic/iovector.h
@@ -6,10 +6,10 @@
#define NET_QUIC_IOVECTOR_H_
#include <stddef.h>
+
#include <algorithm>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "net/base/iovec.h"
#include "net/base/net_export.h"
@@ -118,7 +118,8 @@ class NET_EXPORT_PRIVATE IOVector {
// It returns the number of bytes actually consumed (it'll only be smaller
// than the requested number if the IOVector contains less data).
size_t Consume(size_t length) {
- if (length == 0) return 0;
+ if (length == 0)
+ return 0;
size_t bytes_to_consume = length;
std::vector<struct iovec>::iterator iter = iovec_.begin();
@@ -198,7 +199,9 @@ class NET_EXPORT_PRIVATE IOVector {
// Returns the pointer to the beginning of the iovec to be used for vector
// I/O operations. If the IOVector has no blocks appened, this function
// returns NULL.
- struct iovec* iovec() { return !Empty() ? &iovec_[0] : NULL; }
+ struct iovec* iovec() {
+ return !Empty() ? &iovec_[0] : NULL;
+ }
// Const version.
const struct iovec* iovec() const { return !Empty() ? &iovec_[0] : NULL; }
@@ -206,17 +209,16 @@ class NET_EXPORT_PRIVATE IOVector {
// Returns a pointer to one past the last byte of the last block. If the
// IOVector is empty, NULL is returned.
const char* LastBlockEnd() const {
- return iovec_.size() > 0 ?
- static_cast<char *>(iovec_.back().iov_base) + iovec_.back().iov_len :
- NULL;
+ return iovec_.size() > 0
+ ? static_cast<char*>(iovec_.back().iov_base) +
+ iovec_.back().iov_len
+ : NULL;
}
// Returns the total number of bytes in the IOVector.
size_t TotalBufferSize() const { return TotalIovecLength(iovec(), Size()); }
- void Resize(size_t count) {
- iovec_.resize(count);
- }
+ void Resize(size_t count) { iovec_.resize(count); }
private:
std::vector<struct iovec> iovec_;
diff --git a/chromium/net/quic/iovector_test.cc b/chromium/net/quic/iovector_test.cc
index f25ae1b5f51..7a1d00a8e33 100644
--- a/chromium/net/quic/iovector_test.cc
+++ b/chromium/net/quic/iovector_test.cc
@@ -18,10 +18,8 @@ namespace test {
namespace {
const char* const test_data[] = {
- "test string 1, a medium size one.",
- "test string2",
- "test string 3, a looooooooooooong loooooooooooooooong string"
-};
+ "test string 1, a medium size one.", "test string2",
+ "test string 3, a looooooooooooong loooooooooooooooong string"};
TEST(IOVectorTest, CopyConstructor) {
IOVector iov1;
@@ -88,11 +86,9 @@ TEST(IOVectorTest, Append) {
TEST(IOVectorTest, AppendIovec) {
IOVector iov;
- const struct iovec test_iov[] = {
- {const_cast<char*>("foo"), 3},
- {const_cast<char*>("bar"), 3},
- {const_cast<char*>("buzzzz"), 6}
- };
+ const struct iovec test_iov[] = {{const_cast<char*>("foo"), 3},
+ {const_cast<char*>("bar"), 3},
+ {const_cast<char*>("buzzzz"), 6}};
iov.AppendIovec(test_iov, arraysize(test_iov));
for (size_t i = 0; i < arraysize(test_iov); ++i) {
EXPECT_EQ(test_iov[i].iov_base, iov.iovec()[i].iov_base);
@@ -199,9 +195,8 @@ TEST(IOVectorTest, ConsumeTooMuch) {
}
int consumed = 0;
- EXPECT_DFATAL(
- {consumed = iov.Consume(length + 1);},
- "Attempting to consume 1 non-existent bytes.");
+ EXPECT_DFATAL({ consumed = iov.Consume(length + 1); },
+ "Attempting to consume 1 non-existent bytes.");
ASSERT_EQ(length, consumed);
const struct iovec* iov2 = iov.iovec();
ASSERT_EQ(0u, iov.Size());
diff --git a/chromium/net/quic/network_connection.cc b/chromium/net/quic/network_connection.cc
index 8984b16e04a..a105b9076da 100644
--- a/chromium/net/quic/network_connection.cc
+++ b/chromium/net/quic/network_connection.cc
@@ -10,8 +10,7 @@ namespace net {
NetworkConnection::NetworkConnection()
: connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN),
- connection_description_(nullptr) {
-}
+ connection_description_(nullptr) {}
const char* NetworkConnection::GetDescription() {
NetworkChangeNotifier::ConnectionType type =
diff --git a/chromium/net/quic/network_connection.h b/chromium/net/quic/network_connection.h
index e4fde102a05..089fe34ced5 100644
--- a/chromium/net/quic/network_connection.h
+++ b/chromium/net/quic/network_connection.h
@@ -5,7 +5,7 @@
#ifndef NET_QUIC_NETWORK_CONNECTION_H_
#define NET_QUIC_NETWORK_CONNECTION_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
diff --git a/chromium/net/quic/p2p/quic_p2p_crypto_stream.cc b/chromium/net/quic/p2p/quic_p2p_crypto_stream.cc
index c8a3e6c4a94..f5acb98b1b9 100644
--- a/chromium/net/quic/p2p/quic_p2p_crypto_stream.cc
+++ b/chromium/net/quic/p2p/quic_p2p_crypto_stream.cc
@@ -38,7 +38,11 @@ bool QuicP2PCryptoStream::Connect() {
session()->connection()->OnHandshakeComplete();
handshake_confirmed_ = true;
session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
-
+ if (session()->connection()->perspective() == Perspective::IS_CLIENT) {
+ // Send a ping from the client to the server to satisfy QUIC's version
+ // negotiation.
+ session()->connection()->SendPing();
+ }
return true;
}
diff --git a/chromium/net/quic/p2p/quic_p2p_crypto_stream.h b/chromium/net/quic/p2p/quic_p2p_crypto_stream.h
index 82ff785ac15..185a8f81437 100644
--- a/chromium/net/quic/p2p/quic_p2p_crypto_stream.h
+++ b/chromium/net/quic/p2p/quic_p2p_crypto_stream.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_P2P_QUIC_P2P_CRYPTO_STREAM_H_
#define NET_QUIC_P2P_QUIC_P2P_CRYPTO_STREAM_H_
+#include "base/macros.h"
#include "net/quic/p2p/quic_p2p_crypto_config.h"
#include "net/quic/quic_crypto_stream.h"
diff --git a/chromium/net/quic/p2p/quic_p2p_session.cc b/chromium/net/quic/p2p/quic_p2p_session.cc
index c8cc5819c0c..e326a011a2a 100644
--- a/chromium/net/quic/p2p/quic_p2p_session.cc
+++ b/chromium/net/quic/p2p/quic_p2p_session.cc
@@ -4,6 +4,8 @@
#include "net/quic/p2p/quic_p2p_session.h"
+#include <utility>
+
#include "base/callback_helpers.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -19,7 +21,7 @@ QuicP2PSession::QuicP2PSession(const QuicConfig& config,
scoped_ptr<QuicConnection> connection,
scoped_ptr<net::Socket> socket)
: QuicSession(connection.release(), config),
- socket_(socket.Pass()),
+ socket_(std::move(socket)),
crypto_stream_(new QuicP2PCryptoStream(this, crypto_config)),
read_buffer_(new net::IOBuffer(static_cast<size_t>(kMaxPacketSize))) {
DCHECK(config.negotiated());
@@ -56,8 +58,9 @@ QuicP2PStream* QuicP2PSession::CreateIncomingDynamicStream(QuicStreamId id) {
return stream;
}
-QuicP2PStream* QuicP2PSession::CreateOutgoingDynamicStream() {
- QuicP2PStream* stream = new QuicP2PStream(GetNextStreamId(), this);
+QuicP2PStream* QuicP2PSession::CreateOutgoingDynamicStream(
+ net::SpdyPriority priority) {
+ QuicP2PStream* stream = new QuicP2PStream(GetNextOutgoingStreamId(), this);
if (stream) {
ActivateStream(stream);
}
diff --git a/chromium/net/quic/p2p/quic_p2p_session.h b/chromium/net/quic/p2p/quic_p2p_session.h
index 992e7b59c6c..697f6006317 100644
--- a/chromium/net/quic/p2p/quic_p2p_session.h
+++ b/chromium/net/quic/p2p/quic_p2p_session.h
@@ -5,7 +5,7 @@
#ifndef NET_QUIC_P2P_QUIC_P2P_SESSION_H_
#define NET_QUIC_P2P_QUIC_P2P_SESSION_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/quic/p2p/quic_p2p_stream.h"
@@ -48,7 +48,8 @@ class NET_EXPORT QuicP2PSession : public QuicSession {
// QuicSession overrides.
void Initialize() override;
- QuicP2PStream* CreateOutgoingDynamicStream() override;
+ QuicP2PStream* CreateOutgoingDynamicStream(
+ net::SpdyPriority priority) override;
// QuicConnectionVisitorInterface overrides.
void OnConnectionClosed(QuicErrorCode error, bool from_peer) override;
diff --git a/chromium/net/quic/p2p/quic_p2p_session_test.cc b/chromium/net/quic/p2p/quic_p2p_session_test.cc
index 0a3c14448dc..544c082d6c2 100644
--- a/chromium/net/quic/p2p/quic_p2p_session_test.cc
+++ b/chromium/net/quic/p2p/quic_p2p_session_test.cc
@@ -4,8 +4,11 @@
#include "net/quic/p2p/quic_p2p_session.h"
+#include <utility>
+
#include "base/callback_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -15,7 +18,7 @@
#include "net/quic/crypto/quic_random.h"
#include "net/quic/p2p/quic_p2p_crypto_config.h"
#include "net/quic/p2p/quic_p2p_stream.h"
-#include "net/quic/quic_connection_helper.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_default_packet_writer.h"
#include "net/socket/socket.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -102,11 +105,11 @@ class FakeP2PDatagramSocket : public Socket {
return buf_len;
}
- int SetReceiveBufferSize(int32 size) override {
+ int SetReceiveBufferSize(int32_t size) override {
NOTIMPLEMENTED();
return ERR_NOT_IMPLEMENTED;
}
- int SetSendBufferSize(int32 size) override {
+ int SetSendBufferSize(int32_t size) override {
NOTIMPLEMENTED();
return ERR_NOT_IMPLEMENTED;
}
@@ -126,22 +129,6 @@ class FakeP2PDatagramSocket : public Socket {
base::WeakPtrFactory<FakeP2PDatagramSocket> weak_factory_;
};
-class DefaultPacketWriterFactory : public QuicConnection::PacketWriterFactory {
- public:
- explicit DefaultPacketWriterFactory(Socket* socket) : socket_(socket) {}
- ~DefaultPacketWriterFactory() override {}
-
- QuicPacketWriter* Create(QuicConnection* connection) const override {
- scoped_ptr<net::QuicDefaultPacketWriter> writer(
- new net::QuicDefaultPacketWriter(socket_));
- writer->SetConnection(connection);
- return writer.release();
- }
-
- private:
- Socket* socket_;
-};
-
class TestP2PStreamDelegate : public QuicP2PStream::Delegate {
public:
TestP2PStreamDelegate() {}
@@ -229,26 +216,28 @@ class QuicP2PSessionTest : public ::testing::Test {
QuicP2PCryptoConfig crypto_config(kTestSharedKey);
- session1_ =
- CreateP2PSession(socket1.Pass(), crypto_config, Perspective::IS_SERVER);
- session2_ =
- CreateP2PSession(socket2.Pass(), crypto_config, Perspective::IS_CLIENT);
+ session1_ = CreateP2PSession(std::move(socket1), crypto_config,
+ Perspective::IS_SERVER);
+ session2_ = CreateP2PSession(std::move(socket2), crypto_config,
+ Perspective::IS_CLIENT);
}
scoped_ptr<QuicP2PSession> CreateP2PSession(scoped_ptr<Socket> socket,
QuicP2PCryptoConfig crypto_config,
Perspective perspective) {
- DefaultPacketWriterFactory writer_factory(socket.get());
+ net::QuicDefaultPacketWriter* writer =
+ new net::QuicDefaultPacketWriter(socket.get());
net::IPAddressNumber ip(net::kIPv4AddressSize, 0);
- scoped_ptr<QuicConnection> quic_connection1(
- new QuicConnection(0, net::IPEndPoint(ip, 0), &quic_helper_,
- writer_factory, true /* owns_writer */, perspective,
- true /* is_secuire */, QuicSupportedVersions()));
-
- scoped_ptr<QuicP2PSession> result(new QuicP2PSession(
- config_, crypto_config, quic_connection1.Pass(), socket.Pass()));
+ scoped_ptr<QuicConnection> quic_connection1(new QuicConnection(
+ 0, net::IPEndPoint(ip, 0), &quic_helper_, writer,
+ true /* owns_writer */, perspective, QuicSupportedVersions()));
+ writer->SetConnection(quic_connection1.get());
+
+ scoped_ptr<QuicP2PSession> result(
+ new QuicP2PSession(config_, crypto_config, std::move(quic_connection1),
+ std::move(socket)));
result->Initialize();
- return result.Pass();
+ return result;
}
void TestStreamConnection(QuicP2PSession* from_session,
@@ -256,7 +245,7 @@ class QuicP2PSessionTest : public ::testing::Test {
QuicStreamId expected_stream_id);
QuicClock quic_clock_;
- QuicConnectionHelper quic_helper_;
+ QuicChromiumConnectionHelper quic_helper_;
QuicConfig config_;
base::WeakPtr<FakeP2PDatagramSocket> socket1_;
@@ -273,7 +262,8 @@ void QuicP2PSessionTest::OnWriteResult(int result) {
void QuicP2PSessionTest::TestStreamConnection(QuicP2PSession* from_session,
QuicP2PSession* to_session,
QuicStreamId expected_stream_id) {
- QuicP2PStream* outgoing_stream = from_session->CreateOutgoingDynamicStream();
+ QuicP2PStream* outgoing_stream =
+ from_session->CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_TRUE(outgoing_stream);
TestP2PStreamDelegate outgoing_stream_delegate;
outgoing_stream->SetDelegate(&outgoing_stream_delegate);
@@ -340,7 +330,8 @@ TEST_F(QuicP2PSessionTest, TransportWriteError) {
TestP2PSessionDelegate session_delegate;
session1_->SetDelegate(&session_delegate);
- QuicP2PStream* stream = session1_->CreateOutgoingDynamicStream();
+ QuicP2PStream* stream =
+ session1_->CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_TRUE(stream);
TestP2PStreamDelegate stream_delegate;
stream->SetDelegate(&stream_delegate);
@@ -370,7 +361,8 @@ TEST_F(QuicP2PSessionTest, TransportReceiveError) {
TestP2PSessionDelegate session_delegate;
session1_->SetDelegate(&session_delegate);
- QuicP2PStream* stream = session1_->CreateOutgoingDynamicStream();
+ QuicP2PStream* stream =
+ session1_->CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_TRUE(stream);
TestP2PStreamDelegate stream_delegate;
stream->SetDelegate(&stream_delegate);
diff --git a/chromium/net/quic/p2p/quic_p2p_stream.cc b/chromium/net/quic/p2p/quic_p2p_stream.cc
index af31f3cff43..a8e00c6313c 100644
--- a/chromium/net/quic/p2p/quic_p2p_stream.cc
+++ b/chromium/net/quic/p2p/quic_p2p_stream.cc
@@ -49,7 +49,7 @@ void QuicP2PStream::OnCanWrite() {
}
}
-QuicPriority QuicP2PStream::EffectivePriority() const {
+SpdyPriority QuicP2PStream::Priority() const {
return priority_;
}
diff --git a/chromium/net/quic/p2p/quic_p2p_stream.h b/chromium/net/quic/p2p/quic_p2p_stream.h
index 5a1abcccdef..a2747e8e4cb 100644
--- a/chromium/net/quic/p2p/quic_p2p_stream.h
+++ b/chromium/net/quic/p2p/quic_p2p_stream.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_P2P_QUIC_P2P_STREAM_H_
#define NET_QUIC_P2P_QUIC_P2P_STREAM_H_
+#include "base/macros.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/quic/reliable_quic_stream.h"
@@ -40,7 +41,7 @@ class NET_EXPORT QuicP2PStream : public ReliableQuicStream {
void OnDataAvailable() override;
void OnClose() override;
void OnCanWrite() override;
- QuicPriority EffectivePriority() const override;
+ SpdyPriority Priority() const override;
void WriteHeader(base::StringPiece data);
@@ -52,7 +53,7 @@ class NET_EXPORT QuicP2PStream : public ReliableQuicStream {
private:
Delegate* delegate_ = nullptr;
- QuicPriority priority_ = 0;
+ SpdyPriority priority_ = 0;
CompletionCallback write_callback_;
int last_write_size_ = 0;
diff --git a/chromium/net/quic/port_suggester.cc b/chromium/net/quic/port_suggester.cc
index b1dfa484fd5..569a0fdfe31 100644
--- a/chromium/net/quic/port_suggester.cc
+++ b/chromium/net/quic/port_suggester.cc
@@ -9,9 +9,8 @@
namespace net {
-PortSuggester::PortSuggester(const HostPortPair& server, uint64 seed)
- : call_count_(0),
- previous_suggestion_(-1) {
+PortSuggester::PortSuggester(const HostPortPair& server, uint64_t seed)
+ : call_count_(0), previous_suggestion_(-1) {
unsigned char hash_bytes[base::kSHA1Length];
base::SHA1HashBytes(
reinterpret_cast<const unsigned char*>(server.host().data()),
@@ -27,7 +26,7 @@ int PortSuggester::SuggestPort(int min, int max) {
if (++call_count_ > 1) {
// Evolve the seed.
unsigned char hash_bytes[base::kSHA1Length];
- base::SHA1HashBytes(reinterpret_cast<const unsigned char *>(&seed_),
+ base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(&seed_),
sizeof(seed_), hash_bytes);
memcpy(&seed_, hash_bytes, sizeof(seed_));
}
diff --git a/chromium/net/quic/port_suggester.h b/chromium/net/quic/port_suggester.h
index 0074f7c7459..458ddfa3071 100644
--- a/chromium/net/quic/port_suggester.h
+++ b/chromium/net/quic/port_suggester.h
@@ -5,7 +5,9 @@
#ifndef NET_QUIC_PORT_SUGGESTER_H_
#define NET_QUIC_PORT_SUGGESTER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sha1.h"
#include "net/base/net_export.h"
@@ -23,13 +25,13 @@ class HostPortPair;
class NET_EXPORT_PRIVATE PortSuggester
: public base::RefCounted<PortSuggester> {
public:
- PortSuggester(const HostPortPair& server, uint64 seed);
+ PortSuggester(const HostPortPair& server, uint64_t seed);
// Generate a pseudo-random int in the inclusive range from |min| to |max|.
// Will (probably) return different numbers when called repeatedly.
int SuggestPort(int min, int max);
- uint32 call_count() const { return call_count_; }
+ uint32_t call_count() const { return call_count_; }
int previous_suggestion() const;
private:
@@ -38,8 +40,8 @@ class NET_EXPORT_PRIVATE PortSuggester
virtual ~PortSuggester() {}
// We maintain the first 8 bytes of a hash as our seed_ state.
- uint64 seed_;
- uint32 call_count_; // Number of suggestions made.
+ uint64_t seed_;
+ uint32_t call_count_; // Number of suggestions made.
int previous_suggestion_;
DISALLOW_COPY_AND_ASSIGN(PortSuggester);
diff --git a/chromium/net/quic/port_suggester_unittest.cc b/chromium/net/quic/port_suggester_unittest.cc
index add52584509..d62f024cea2 100644
--- a/chromium/net/quic/port_suggester_unittest.cc
+++ b/chromium/net/quic/port_suggester_unittest.cc
@@ -6,7 +6,6 @@
#include <set>
-#include "base/basictypes.h"
#include "net/base/host_port_pair.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -18,10 +17,9 @@ class PortSuggesterTest : public ::testing::Test {
PortSuggesterTest()
: entropy_(1345689),
min_ephemeral_port_(1025),
- max_ephemeral_port_(65535) {
- }
+ max_ephemeral_port_(65535) {}
- uint64 entropy_;
+ uint64_t entropy_;
int min_ephemeral_port_;
int max_ephemeral_port_;
};
@@ -44,11 +42,11 @@ TEST_F(PortSuggesterTest, SuggestAllPorts) {
scoped_refptr<PortSuggester> port_suggester =
new PortSuggester(HostPortPair("www.example.com", 443), entropy_);
std::set<int> ports;
- const uint32 port_range = 20;
+ const uint32_t port_range = 20;
const int insertion_limit = 200; // We should be done by then.
for (int i = 0; i < insertion_limit; ++i) {
- ports.insert(port_suggester->SuggestPort(min_ephemeral_port_,
- min_ephemeral_port_ + port_range - 1));
+ ports.insert(port_suggester->SuggestPort(
+ min_ephemeral_port_, min_ephemeral_port_ + port_range - 1));
if (ports.size() == port_range) {
break;
}
@@ -64,8 +62,8 @@ TEST_F(PortSuggesterTest, AvoidDuplication) {
std::set<int> ports;
const size_t port_count = 200;
for (size_t i = 0; i < port_count; ++i) {
- ports.insert(port_suggester->SuggestPort(min_ephemeral_port_,
- max_ephemeral_port_));
+ ports.insert(
+ port_suggester->SuggestPort(min_ephemeral_port_, max_ephemeral_port_));
}
EXPECT_EQ(port_suggester->call_count(), port_count);
EXPECT_EQ(port_count, ports.size());
@@ -79,10 +77,9 @@ TEST_F(PortSuggesterTest, ConsistentPorts) {
scoped_refptr<PortSuggester> port_suggester2 =
new PortSuggester(HostPortPair("www.example.com", 443), entropy_);
for (int test_count = 20; test_count > 0; --test_count) {
- EXPECT_EQ(port_suggester1->SuggestPort(min_ephemeral_port_,
- min_ephemeral_port_),
- port_suggester2->SuggestPort(min_ephemeral_port_,
- min_ephemeral_port_));
+ EXPECT_EQ(
+ port_suggester1->SuggestPort(min_ephemeral_port_, min_ephemeral_port_),
+ port_suggester2->SuggestPort(min_ephemeral_port_, min_ephemeral_port_));
}
}
@@ -100,9 +97,9 @@ TEST_F(PortSuggesterTest, DifferentHostPortEntropy) {
size_t insertion_count = 0;
for (size_t j = 0; j < arraysize(port_suggester); ++j) {
for (int i = 0; i < port_count; ++i) {
- ports.insert(port_suggester[j]->SuggestPort(min_ephemeral_port_,
- max_ephemeral_port_));
- ++insertion_count;
+ ports.insert(port_suggester[j]->SuggestPort(min_ephemeral_port_,
+ max_ephemeral_port_));
+ ++insertion_count;
}
}
EXPECT_EQ(insertion_count, ports.size());
diff --git a/chromium/net/quic/quic_ack_listener_interface.h b/chromium/net/quic/quic_ack_listener_interface.h
new file mode 100644
index 00000000000..c2bd6fee97b
--- /dev/null
+++ b/chromium/net/quic/quic_ack_listener_interface.h
@@ -0,0 +1,38 @@
+// Copyright 2013 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_QUIC_ACK_LISTENER_INTERFACE_H_
+#define NET_QUIC_QUIC_ACK_LISTENER_INTERFACE_H_
+
+#include "base/memory/ref_counted.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_time.h"
+
+namespace net {
+
+// Pure virtual class to listen for packet acknowledgements.
+class NET_EXPORT_PRIVATE QuicAckListenerInterface
+ : public base::RefCounted<QuicAckListenerInterface> {
+ public:
+ QuicAckListenerInterface() {}
+
+ // Called when a packet is acked. Called once per packet.
+ // |acked_bytes| is the number of data bytes acked.
+ virtual void OnPacketAcked(int acked_bytes,
+ QuicTime::Delta delta_largest_observed) = 0;
+
+ // Called when a packet is retransmitted. Called once per packet.
+ // |retransmitted_bytes| is the number of data bytes retransmitted.
+ virtual void OnPacketRetransmitted(int retransmitted_bytes) = 0;
+
+ protected:
+ friend class base::RefCounted<QuicAckListenerInterface>;
+
+ // Delegates are ref counted.
+ virtual ~QuicAckListenerInterface() {}
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_ACK_LISTENER_INTERFACE_H_
diff --git a/chromium/net/quic/quic_ack_notifier.cc b/chromium/net/quic/quic_ack_notifier.cc
deleted file mode 100644
index 187e3a8501a..00000000000
--- a/chromium/net/quic/quic_ack_notifier.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2013 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/quic_ack_notifier.h"
-
-#include <set>
-
-#include "base/logging.h"
-#include "base/stl_util.h"
-
-using base::hash_map;
-using std::make_pair;
-
-namespace net {
-
-QuicAckNotifier::DelegateInterface::DelegateInterface() {}
-
-QuicAckNotifier::DelegateInterface::~DelegateInterface() {}
-
-QuicAckNotifier::QuicAckNotifier(DelegateInterface* delegate)
- : delegate_(delegate),
- unacked_packets_(0),
- retransmitted_packet_count_(0),
- retransmitted_byte_count_(0) {
- DCHECK(delegate);
-}
-
-QuicAckNotifier::~QuicAckNotifier() {
-}
-
-void QuicAckNotifier::OnSerializedPacket() {
- ++unacked_packets_;
-}
-
-bool QuicAckNotifier::OnAck(QuicTime::Delta delta_largest_observed) {
- if (unacked_packets_ <= 0) {
- LOG(DFATAL) << "Acked more packets than were tracked."
- << " unacked_packets:" << unacked_packets_;
- return true;
- }
- --unacked_packets_;
- if (!HasUnackedPackets()) {
- // We have seen all the packet numbers we were waiting for, trigger
- // callback notification.
- delegate_->OnAckNotification(retransmitted_packet_count_,
- retransmitted_byte_count_,
- delta_largest_observed);
- return true;
- }
- return false;
-}
-
-bool QuicAckNotifier::OnPacketAbandoned() {
- if (unacked_packets_ <= 0) {
- LOG(DFATAL) << "Abandoned more packets than were tracked."
- << " unacked_packets:" << unacked_packets_;
- return true;
- }
- --unacked_packets_;
- return unacked_packets_ == 0;
-}
-
-void QuicAckNotifier::OnPacketRetransmitted(int packet_payload_size) {
- ++retransmitted_packet_count_;
- retransmitted_byte_count_ += packet_payload_size;
-}
-
-} // namespace net
diff --git a/chromium/net/quic/quic_ack_notifier.h b/chromium/net/quic/quic_ack_notifier.h
deleted file mode 100644
index bfa41918565..00000000000
--- a/chromium/net/quic/quic_ack_notifier.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 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_QUIC_ACK_NOTIFIER_H_
-#define NET_QUIC_QUIC_ACK_NOTIFIER_H_
-
-#include "base/memory/ref_counted.h"
-#include "net/quic/quic_protocol.h"
-
-namespace net {
-
-// Used to register with a QuicConnection for notification once a set of packets
-// have all been ACKed.
-// The connection informs this class of newly ACKed packet numbers, and once
-// we have seen ACKs for all the packet numbers we are interested in, we
-// trigger a call to a provided Closure.
-class NET_EXPORT_PRIVATE QuicAckNotifier {
- public:
- class NET_EXPORT_PRIVATE DelegateInterface
- : public base::RefCounted<DelegateInterface> {
- public:
- DelegateInterface();
- // Args:
- // num_retransmitted_packets - Number of packets that had to be
- // retransmitted.
- // num_retransmitted_bytes - Number of bytes that had to be retransmitted.
- virtual void OnAckNotification(int num_retransmitted_packets,
- int num_retransmitted_bytes,
- QuicTime::Delta delta_largest_observed) = 0;
-
- protected:
- friend class base::RefCounted<DelegateInterface>;
-
- // Delegates are ref counted.
- virtual ~DelegateInterface();
- };
-
- // QuicAckNotifier is expected to keep its own reference to the delegate.
- explicit QuicAckNotifier(DelegateInterface* delegate);
- virtual ~QuicAckNotifier();
-
- // Register a serialized packet the notifier should track.
- void OnSerializedPacket();
-
- // Called on receipt of new ACK frame for an unacked packet.
- // Decrements the number of unacked packets and if there are none left, calls
- // the stored delegate's OnAckNotification method.
- //
- // Returns true if the delegate was called, false otherwise.
- bool OnAck(QuicTime::Delta delta_largest_observed);
-
- // Called when we've given up waiting for a packet number, typically when
- // the connection is torn down.
- // Returns true if there are no more unacked packets being tracked.
- bool OnPacketAbandoned();
-
- bool HasUnackedPackets() const { return unacked_packets_ > 0; }
-
- // If a packet is retransmitted by the connection, it will be sent with a
- // different packet number.
- void OnPacketRetransmitted(int packet_payload_size);
-
- private:
- // The delegate's OnAckNotification() method will be called once we have been
- // notified of ACKs for all the packet numbers we are tracking.
- // This is not owned by OnAckNotifier and must outlive it.
- scoped_refptr<DelegateInterface> delegate_;
-
- // The number of unacked packets being tracked.
- int unacked_packets_;
-
- // Number of packets that had to be retransmitted.
- int retransmitted_packet_count_;
- // Number of bytes that had to be retransmitted.
- int retransmitted_byte_count_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicAckNotifier);
-};
-
-} // namespace net
-
-#endif // NET_QUIC_QUIC_ACK_NOTIFIER_H_
diff --git a/chromium/net/quic/quic_ack_notifier_manager.cc b/chromium/net/quic/quic_ack_notifier_manager.cc
deleted file mode 100644
index df4a87c2208..00000000000
--- a/chromium/net/quic/quic_ack_notifier_manager.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2013 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/quic_ack_notifier_manager.h"
-
-#include <stddef.h>
-#include <list>
-#include <map>
-#include <utility>
-#include <vector>
-
-#include "base/stl_util.h"
-#include "net/quic/quic_ack_notifier.h"
-#include "net/quic/quic_flags.h"
-#include "net/quic/quic_protocol.h"
-
-namespace net {
-
-AckNotifierManager::AckNotifierManager() {}
-
-AckNotifierManager::~AckNotifierManager() {
- for (const auto& pair : ack_notifier_map_) {
- for (QuicAckNotifier* notifier : pair.second) {
- if (notifier->OnPacketAbandoned()) {
- delete notifier;
- }
- }
- }
-}
-
-void AckNotifierManager::OnPacketAcked(QuicPacketNumber packet_number,
- QuicTime::Delta delta_largest_observed) {
- // Inform all the registered AckNotifiers of the new ACK.
- auto map_it = ack_notifier_map_.find(packet_number);
- if (map_it == ack_notifier_map_.end()) {
- // No AckNotifier is interested in this packet number.
- return;
- }
-
- // One or more AckNotifiers are registered as interested in this sequence
- // number. Iterate through them and call OnAck on each.
- for (QuicAckNotifier* ack_notifier : map_it->second) {
- if (ack_notifier->OnAck(delta_largest_observed)) {
- // If this has resulted in an empty AckNotifer, erase it.
- delete ack_notifier;
- }
- }
-
- // Remove the packet number from the map as we have notified all the
- // registered AckNotifiers, and we won't see it again.
- ack_notifier_map_.erase(map_it);
-}
-
-void AckNotifierManager::OnPacketRetransmitted(
- QuicPacketNumber old_packet_number,
- QuicPacketNumber new_packet_number,
- int packet_payload_size) {
- auto map_it = ack_notifier_map_.find(old_packet_number);
- if (map_it == ack_notifier_map_.end()) {
- // No AckNotifiers are interested in the old packet number.
- return;
- }
-
- // Update the existing QuicAckNotifiers to the new packet number.
- AckNotifierList& ack_notifier_list = map_it->second;
- for (QuicAckNotifier* ack_notifier : ack_notifier_list) {
- ack_notifier->OnPacketRetransmitted(packet_payload_size);
- }
-
- // The old packet number is no longer of interest, copy the updated
- // AckNotifiers to the new packet number before deleting the old.
- // TODO(rtenneti): use std::move when chromium supports it.
- // ack_notifier_map_[new_packet_number] = std::move(ack_notifier_list);
- ack_notifier_map_[new_packet_number] = ack_notifier_list;
- ack_notifier_map_.erase(map_it);
-}
-
-void AckNotifierManager::OnSerializedPacket(
- const SerializedPacket& serialized_packet) {
- if (serialized_packet.notifiers.empty()) {
- return;
- }
- // Inform each attached AckNotifier of the packet's serialization.
- AckNotifierList& notifier_list =
- ack_notifier_map_[serialized_packet.packet_number];
- for (QuicAckNotifier* notifier : serialized_packet.notifiers) {
- if (notifier == nullptr) {
- LOG(DFATAL) << "AckNotifier should not be nullptr.";
- continue;
- }
- notifier->OnSerializedPacket();
- notifier_list.push_back(notifier);
- }
-}
-
-void AckNotifierManager::OnPacketRemoved(QuicPacketNumber packet_number) {
- // Determine if there are any notifiers interested in this packet.
- auto map_it = ack_notifier_map_.find(packet_number);
- if (map_it == ack_notifier_map_.end()) {
- return;
- }
-
- // Notify all of the interested notifiers that the packet is abandoned.
- for (QuicAckNotifier* ack_notifier : map_it->second) {
- DCHECK(ack_notifier);
- if (ack_notifier->OnPacketAbandoned()) {
- // If this has resulted in an empty AckNotifer, erase it.
- delete ack_notifier;
- }
- }
-
- // Remove the packet with given packet number from the map.
- ack_notifier_map_.erase(map_it);
-}
-
-} // namespace net
diff --git a/chromium/net/quic/quic_ack_notifier_manager.h b/chromium/net/quic/quic_ack_notifier_manager.h
deleted file mode 100644
index 79a0b9efb04..00000000000
--- a/chromium/net/quic/quic_ack_notifier_manager.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2013 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_QUIC_ACK_NOTIFIER_MANAGER_H_
-#define NET_QUIC_QUIC_ACK_NOTIFIER_MANAGER_H_
-
-#include <list>
-#include <map>
-
-#include "base/containers/hash_tables.h"
-#include "net/quic/quic_protocol.h"
-
-namespace net {
-
-class QuicAckNotifier;
-
-namespace test {
-class AckNotifierManagerPeer;
-}
-
-// The AckNotifierManager is used by the QuicSentPacketManager to keep track of
-// all the AckNotifiers currently active. It owns the AckNotifiers which it gets
-// from the serialized packets passed into OnSerializedPacket. It maintains both
-// a set of AckNotifiers and a map from packet number to AckNotifier the sake
-// of efficiency - we can quickly check the map to see if any AckNotifiers are
-// interested in a given packet number.
-class NET_EXPORT_PRIVATE AckNotifierManager {
- public:
- AckNotifierManager();
- virtual ~AckNotifierManager();
-
- // Called when the connection receives a new AckFrame. If |packet_number|
- // exists in ack_notifier_map_ then the corresponding AckNotifiers will have
- // their OnAck method called.
- void OnPacketAcked(QuicPacketNumber packet_number,
- QuicTime::Delta delta_largest_observed);
-
- // If a packet has been retransmitted with a new packet number, then this
- // will be called. It updates the mapping in ack_notifier_map_, and also
- // updates the internal set of packet numbers in each matching AckNotifier.
- void OnPacketRetransmitted(QuicPacketNumber old_packet_number,
- QuicPacketNumber new_packet_number,
- int packet_payload_size);
-
- // This is called after a packet has been serialized, is ready to be sent, and
- // contains retransmittable frames (which may have associated AckNotifiers).
- // If any of the retransmittable frames included in |serialized_packet| have
- // AckNotifiers registered, then add them to our internal map and additionally
- // inform the AckNotifier of the packet number which it should track.
- void OnSerializedPacket(const SerializedPacket& serialized_packet);
-
- // This method is invoked when a packet is removed from the list of unacked
- // packets, and it is no longer necessary to keep track of the notifier.
- void OnPacketRemoved(QuicPacketNumber packet_number);
-
- private:
- friend class test::AckNotifierManagerPeer;
-
- typedef std::list<QuicAckNotifier*> AckNotifierList;
- // TODO(ianswett): Further improvement may come from changing this to a deque.
- typedef base::hash_map<QuicPacketNumber, AckNotifierList> AckNotifierMap;
-
- // Maps from packet number to the AckNotifiers which are registered
- // for that packet number. On receipt of an ACK for a given sequence
- // number, call OnAck for all mapped AckNotifiers.
- // When the last reference is removed from the map, the notifier is deleted.
- AckNotifierMap ack_notifier_map_;
-
- DISALLOW_COPY_AND_ASSIGN(AckNotifierManager);
-};
-
-} // namespace net
-
-#endif // NET_QUIC_QUIC_ACK_NOTIFIER_MANAGER_H_
diff --git a/chromium/net/quic/quic_ack_notifier_manager_test.cc b/chromium/net/quic/quic_ack_notifier_manager_test.cc
deleted file mode 100644
index 643fe3d7ee5..00000000000
--- a/chromium/net/quic/quic_ack_notifier_manager_test.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2015 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/quic_ack_notifier_manager.h"
-
-#include "net/quic/quic_ack_notifier.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/test_tools/quic_ack_notifier_manager_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace test {
-namespace {
-
-// Test fixture for testing AckNotifierManager. Instantiates a manager and
-// provides shared code for adding notifiers and verifying the contents of the
-// manager.
-class QuicAckNotifierManagerTest : public ::testing::Test {
- protected:
- AckNotifierManager manager_;
- scoped_refptr<MockAckNotifierDelegate> delegate_;
- QuicTime::Delta zero_;
-
- QuicAckNotifierManagerTest() : zero_(QuicTime::Delta::Zero()) {
- delegate_ = new MockAckNotifierDelegate;
- }
-
- ~QuicAckNotifierManagerTest() override {}
-
- size_t CountPackets() const {
- return AckNotifierManagerPeer::GetNumberOfRegisteredPackets(&manager_);
- }
-
- // Add a mock packet with specified parameters. The packet with given
- // packet number must not exist in the map before.
- void AddPacket(QuicPacketNumber packet_number, bool retransmittable) {
- // Create a mock packet.
- RetransmittableFrames frames(ENCRYPTION_NONE);
- SerializedPacket packet(packet_number, PACKET_4BYTE_PACKET_NUMBER,
- /*packet=*/nullptr,
- /*entropy_hash=*/0,
- retransmittable ? &frames : nullptr,
- /*has_ack=*/false,
- /*has_stop_waiting=*/false);
-
- // Create and register a notifier. Normally, this would be created by
- // QuicPacketGenerator.
- QuicAckNotifier* notifier = new QuicAckNotifier(delegate_.get());
- packet.notifiers.push_back(notifier);
-
- // Ensure that exactly one packet is added.
- const size_t old_packet_count = CountPackets();
-
- // Actually add the packet.
- manager_.OnSerializedPacket(packet);
-
- // Ensure the change in the number of packets.
- EXPECT_EQ(old_packet_count + 1, CountPackets());
- }
-};
-
-// This test verifies that QuicAckNotifierManager can handle the trivial case of
-// received packet notification.
-TEST_F(QuicAckNotifierManagerTest, SimpleAck) {
- AddPacket(1, false);
- AddPacket(2, true);
-
- EXPECT_CALL(*delegate_, OnAckNotification(0, 0, zero_)).Times(2);
- manager_.OnPacketAcked(1, zero_);
- EXPECT_EQ(1u, CountPackets());
- manager_.OnPacketAcked(2, zero_);
- EXPECT_EQ(0u, CountPackets());
-
- manager_.OnPacketRemoved(1);
- manager_.OnPacketRemoved(2);
- EXPECT_EQ(0u, CountPackets());
-}
-
-// This test verifies that QuicAckNotifierManager can correctly handle the case
-// when some of the packets are lost, which causes retransmission and removal
-// from the unacked packet map.
-TEST_F(QuicAckNotifierManagerTest, AckWithLosses) {
- const size_t retransmitted_packet_size = kDefaultMaxPacketSize;
-
- // Here, we simulate the following scenario:
- // 1. We send packets 1 to 5, where only odd-numbered packets are
- // retransmittable.
- // 2. The peer acks 1, 2 and 5, but not 3 and 4.
- // 3. We retransmit 3 as 6.
- // 4. We remove 1 and 2, since we no longer care about them.
- // 4. The peer acks 6.
- // 5. We remove packets 3 to 6.
-
- // Step 1: send five packets.
- AddPacket(1, true);
- AddPacket(2, false);
- AddPacket(3, true);
- AddPacket(4, false);
- AddPacket(5, true);
-
- // Step 2: handle acks from peer.
- EXPECT_CALL(*delegate_, OnAckNotification(0, 0, zero_)).Times(3);
- manager_.OnPacketAcked(1, zero_);
- EXPECT_EQ(4u, CountPackets());
- manager_.OnPacketAcked(2, zero_);
- EXPECT_EQ(3u, CountPackets());
- manager_.OnPacketAcked(5, zero_);
- EXPECT_EQ(2u, CountPackets());
-
- // Step 3: retransmit 3 as 6.
- manager_.OnPacketRetransmitted(3, 6, retransmitted_packet_size);
- EXPECT_EQ(2u, CountPackets());
-
- // Step 4: remove 1 and 2.
- manager_.OnPacketRemoved(1);
- manager_.OnPacketRemoved(2);
- EXPECT_EQ(2u, CountPackets());
-
- // Step 4: ack packet 6.
- EXPECT_CALL(*delegate_,
- OnAckNotification(1, retransmitted_packet_size, zero_)).Times(1);
- manager_.OnPacketAcked(6, zero_);
- EXPECT_EQ(1u, CountPackets());
-
- // Step 5: remove all packets. This causes packet 4 to be dropped from the
- // map.
- manager_.OnPacketRemoved(3);
- manager_.OnPacketRemoved(4);
- manager_.OnPacketRemoved(5);
- manager_.OnPacketRemoved(6);
- EXPECT_EQ(0u, CountPackets());
-}
-
-// This test verifies that the QuicAckNotifierManager behaves correctly when
-// there are many retransmissions.
-TEST_F(QuicAckNotifierManagerTest, RepeatedRetransmission) {
- AddPacket(1, true);
-
- const size_t packet_size = kDefaultMaxPacketSize;
- const size_t times_lost = 100;
- const size_t total_size_lost = packet_size * times_lost;
- const QuicPacketNumber last_packet = times_lost + 1;
-
- // Retransmit the packet many times.
- for (size_t packet_number = 1; packet_number < last_packet; packet_number++) {
- manager_.OnPacketRetransmitted(packet_number, packet_number + 1,
- packet_size);
- EXPECT_EQ(1u, CountPackets());
- }
-
- // Remove all lost packets.
- for (QuicPacketNumber packet = 1; packet < last_packet; packet++) {
- manager_.OnPacketRemoved(packet);
- }
- EXPECT_EQ(1u, CountPackets());
-
- // Finally get the packet acknowledged.
- EXPECT_CALL(*delegate_, OnAckNotification(times_lost, total_size_lost, zero_))
- .Times(1);
- manager_.OnPacketAcked(last_packet, zero_);
- EXPECT_EQ(0u, CountPackets());
-
- // Remove the last packet.
- manager_.OnPacketRemoved(last_packet);
- EXPECT_EQ(0u, CountPackets());
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/quic/quic_ack_notifier_test.cc b/chromium/net/quic/quic_ack_notifier_test.cc
deleted file mode 100644
index d57235f91c9..00000000000
--- a/chromium/net/quic/quic_ack_notifier_test.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2013 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/quic_ack_notifier.h"
-
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::_;
-
-namespace net {
-namespace test {
-namespace {
-
-class QuicAckNotifierTest : public ::testing::Test {
- protected:
- QuicAckNotifierTest() : zero_(QuicTime::Delta::Zero()) {}
-
- void SetUp() override {
- delegate_ = new MockAckNotifierDelegate;
- notifier_.reset(new QuicAckNotifier(delegate_));
-
- notifier_->OnSerializedPacket();
- notifier_->OnSerializedPacket();
- notifier_->OnSerializedPacket();
- }
-
- MockAckNotifierDelegate* delegate_;
- scoped_ptr<QuicAckNotifier> notifier_;
- QuicTime::Delta zero_;
-};
-
-// Should trigger callback when we receive acks for all the registered packet
-// numbers.
-TEST_F(QuicAckNotifierTest, TriggerCallback) {
- EXPECT_CALL(*delegate_, OnAckNotification(0, 0, zero_)).Times(1);
- EXPECT_FALSE(notifier_->OnAck(zero_));
- EXPECT_FALSE(notifier_->OnAck(zero_));
- EXPECT_TRUE(notifier_->OnAck(zero_));
-}
-
-// Should not trigger callback if we never provide all the packet numbers.
-TEST_F(QuicAckNotifierTest, DoesNotTrigger) {
- // Should not trigger callback as not all packets have been seen.
- EXPECT_CALL(*delegate_, OnAckNotification(_, _, _)).Times(0);
- EXPECT_FALSE(notifier_->OnAck(zero_));
- EXPECT_FALSE(notifier_->OnAck(zero_));
-}
-
-// Should not trigger callback if we abandon all three packets.
-TEST_F(QuicAckNotifierTest, AbandonDoesNotTrigger) {
- // Should not trigger callback as not all packets have been seen.
- EXPECT_CALL(*delegate_, OnAckNotification(_, _, _)).Times(0);
- EXPECT_FALSE(notifier_->OnPacketAbandoned());
- EXPECT_FALSE(notifier_->OnPacketAbandoned());
- EXPECT_TRUE(notifier_->OnPacketAbandoned());
-}
-
-// Should trigger even after updating packet numbers and receiving ACKs for
-// new packet numbers.
-TEST_F(QuicAckNotifierTest, UpdatePacketNumbers) {
- // Update a couple of the packet numbers (i.e. retransmitted packets)
- notifier_->OnPacketRetransmitted(20);
- notifier_->OnPacketRetransmitted(3);
-
- EXPECT_CALL(*delegate_, OnAckNotification(2, 20 + 3, _)).Times(1);
- EXPECT_FALSE(notifier_->OnAck(zero_)); // original
- EXPECT_FALSE(notifier_->OnAck(zero_)); // updated
- EXPECT_TRUE(notifier_->OnAck(zero_)); // updated
-}
-
-// Make sure the delegate is called with the delta time from the last ACK.
-TEST_F(QuicAckNotifierTest, DeltaTime) {
- const QuicTime::Delta first_delta = QuicTime::Delta::FromSeconds(5);
- const QuicTime::Delta second_delta = QuicTime::Delta::FromSeconds(33);
- const QuicTime::Delta third_delta = QuicTime::Delta::FromSeconds(10);
-
- EXPECT_CALL(*delegate_, OnAckNotification(0, 0, third_delta)).Times(1);
- EXPECT_FALSE(notifier_->OnAck(first_delta));
- EXPECT_FALSE(notifier_->OnAck(second_delta));
- EXPECT_TRUE(notifier_->OnAck(third_delta));
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/quic/quic_address_mismatch_test.cc b/chromium/net/quic/quic_address_mismatch_test.cc
index b7c683b5a48..02f3dcc0653 100644
--- a/chromium/net/quic/quic_address_mismatch_test.cc
+++ b/chromium/net/quic/quic_address_mismatch_test.cc
@@ -34,8 +34,7 @@ TEST(QuicAddressMismatchTest, GetAddressMismatch) {
EXPECT_EQ(-1, GetAddressMismatch(IPEndPoint(ip4_1, 443), IPEndPoint()));
EXPECT_EQ(QUIC_ADDRESS_AND_PORT_MATCH_V4_V4,
- GetAddressMismatch(IPEndPoint(ip4_1, 443),
- IPEndPoint(ip4_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip4_1, 443), IPEndPoint(ip4_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_AND_PORT_MATCH_V4_V4,
GetAddressMismatch(IPEndPoint(ip4_1, 443),
IPEndPoint(ip4_mapped_1, 443)));
@@ -43,25 +42,21 @@ TEST(QuicAddressMismatchTest, GetAddressMismatch) {
GetAddressMismatch(IPEndPoint(ip4_mapped_1, 443),
IPEndPoint(ip4_mapped_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_AND_PORT_MATCH_V6_V6,
- GetAddressMismatch(IPEndPoint(ip6_1, 443),
- IPEndPoint(ip6_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip6_1, 443), IPEndPoint(ip6_1, 443)));
EXPECT_EQ(QUIC_PORT_MISMATCH_V4_V4,
- GetAddressMismatch(IPEndPoint(ip4_1, 80),
- IPEndPoint(ip4_1, 443)));
- EXPECT_EQ(QUIC_PORT_MISMATCH_V4_V4,
- GetAddressMismatch(IPEndPoint(ip4_1, 80),
- IPEndPoint(ip4_mapped_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip4_1, 80), IPEndPoint(ip4_1, 443)));
+ EXPECT_EQ(
+ QUIC_PORT_MISMATCH_V4_V4,
+ GetAddressMismatch(IPEndPoint(ip4_1, 80), IPEndPoint(ip4_mapped_1, 443)));
EXPECT_EQ(QUIC_PORT_MISMATCH_V4_V4,
GetAddressMismatch(IPEndPoint(ip4_mapped_1, 80),
IPEndPoint(ip4_mapped_1, 443)));
EXPECT_EQ(QUIC_PORT_MISMATCH_V6_V6,
- GetAddressMismatch(IPEndPoint(ip6_1, 80),
- IPEndPoint(ip6_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip6_1, 80), IPEndPoint(ip6_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V4,
- GetAddressMismatch(IPEndPoint(ip4_1, 443),
- IPEndPoint(ip4_2, 443)));
+ GetAddressMismatch(IPEndPoint(ip4_1, 443), IPEndPoint(ip4_2, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V4,
GetAddressMismatch(IPEndPoint(ip4_1, 443),
IPEndPoint(ip4_mapped_2, 443)));
@@ -69,44 +64,37 @@ TEST(QuicAddressMismatchTest, GetAddressMismatch) {
GetAddressMismatch(IPEndPoint(ip4_mapped_1, 443),
IPEndPoint(ip4_mapped_2, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V4,
- GetAddressMismatch(IPEndPoint(ip4_1, 80),
- IPEndPoint(ip4_2, 443)));
- EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V4,
- GetAddressMismatch(IPEndPoint(ip4_1, 80),
- IPEndPoint(ip4_mapped_2, 443)));
+ GetAddressMismatch(IPEndPoint(ip4_1, 80), IPEndPoint(ip4_2, 443)));
+ EXPECT_EQ(
+ QUIC_ADDRESS_MISMATCH_V4_V4,
+ GetAddressMismatch(IPEndPoint(ip4_1, 80), IPEndPoint(ip4_mapped_2, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V4,
GetAddressMismatch(IPEndPoint(ip4_mapped_1, 80),
IPEndPoint(ip4_mapped_2, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V6,
- GetAddressMismatch(IPEndPoint(ip6_1, 443),
- IPEndPoint(ip6_2, 443)));
+ GetAddressMismatch(IPEndPoint(ip6_1, 443), IPEndPoint(ip6_2, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V6,
- GetAddressMismatch(IPEndPoint(ip6_1, 80),
- IPEndPoint(ip6_2, 443)));
+ GetAddressMismatch(IPEndPoint(ip6_1, 80), IPEndPoint(ip6_2, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V6,
- GetAddressMismatch(IPEndPoint(ip4_1, 443),
- IPEndPoint(ip6_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip4_1, 443), IPEndPoint(ip6_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V6,
GetAddressMismatch(IPEndPoint(ip4_mapped_1, 443),
IPEndPoint(ip6_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V6,
- GetAddressMismatch(IPEndPoint(ip4_1, 80),
- IPEndPoint(ip6_1, 443)));
- EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V6,
- GetAddressMismatch(IPEndPoint(ip4_mapped_1, 80),
- IPEndPoint(ip6_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip4_1, 80), IPEndPoint(ip6_1, 443)));
+ EXPECT_EQ(
+ QUIC_ADDRESS_MISMATCH_V4_V6,
+ GetAddressMismatch(IPEndPoint(ip4_mapped_1, 80), IPEndPoint(ip6_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V4,
- GetAddressMismatch(IPEndPoint(ip6_1, 443),
- IPEndPoint(ip4_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip6_1, 443), IPEndPoint(ip4_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V4,
GetAddressMismatch(IPEndPoint(ip6_1, 443),
IPEndPoint(ip4_mapped_1, 443)));
EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V4,
- GetAddressMismatch(IPEndPoint(ip6_1, 80),
- IPEndPoint(ip4_1, 443)));
- EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V4,
- GetAddressMismatch(IPEndPoint(ip6_1, 80),
- IPEndPoint(ip4_mapped_1, 443)));
+ GetAddressMismatch(IPEndPoint(ip6_1, 80), IPEndPoint(ip4_1, 443)));
+ EXPECT_EQ(
+ QUIC_ADDRESS_MISMATCH_V6_V4,
+ GetAddressMismatch(IPEndPoint(ip6_1, 80), IPEndPoint(ip4_mapped_1, 443)));
}
} // namespace test
diff --git a/chromium/net/quic/quic_alarm.cc b/chromium/net/quic/quic_alarm.cc
index b5aca8caa17..6df6492698d 100644
--- a/chromium/net/quic/quic_alarm.cc
+++ b/chromium/net/quic/quic_alarm.cc
@@ -9,9 +9,7 @@
namespace net {
QuicAlarm::QuicAlarm(Delegate* delegate)
- : delegate_(delegate),
- deadline_(QuicTime::Zero()) {
-}
+ : delegate_(delegate), deadline_(QuicTime::Zero()) {}
QuicAlarm::~QuicAlarm() {}
@@ -33,7 +31,7 @@ void QuicAlarm::Update(QuicTime deadline, QuicTime::Delta granularity) {
return;
}
if (std::abs(deadline.Subtract(deadline_).ToMicroseconds()) <
- granularity.ToMicroseconds()) {
+ granularity.ToMicroseconds()) {
return;
}
Cancel();
diff --git a/chromium/net/quic/quic_alarm.h b/chromium/net/quic/quic_alarm.h
index 5df4fe05160..48cd5ef0b3f 100644
--- a/chromium/net/quic/quic_alarm.h
+++ b/chromium/net/quic/quic_alarm.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_QUIC_ALARM_H_
#define NET_QUIC_QUIC_ALARM_H_
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/quic/quic_time.h"
diff --git a/chromium/net/quic/quic_alarm_test.cc b/chromium/net/quic/quic_alarm_test.cc
index dfd40ed6f32..42d44a2042b 100644
--- a/chromium/net/quic/quic_alarm_test.cc
+++ b/chromium/net/quic/quic_alarm_test.cc
@@ -53,12 +53,9 @@ class QuicAlarmTest : public ::testing::Test {
alarm_(delegate_),
deadline_(QuicTime::Zero().Add(QuicTime::Delta::FromSeconds(7))),
deadline2_(QuicTime::Zero().Add(QuicTime::Delta::FromSeconds(14))),
- new_deadline_(QuicTime::Zero()) {
- }
+ new_deadline_(QuicTime::Zero()) {}
- void ResetAlarm() {
- alarm_.Set(new_deadline_);
- }
+ void ResetAlarm() { alarm_.Set(new_deadline_); }
MockDelegate* delegate_; // not owned
TestAlarm alarm_;
@@ -129,9 +126,9 @@ TEST_F(QuicAlarmTest, FireAndResetViaReturn) {
TEST_F(QuicAlarmTest, FireAndResetViaSet) {
alarm_.Set(deadline_);
new_deadline_ = deadline2_;
- EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(DoAll(
- Invoke(this, &QuicAlarmTest::ResetAlarm),
- Return(QuicTime::Zero())));
+ EXPECT_CALL(*delegate_, OnAlarm())
+ .WillOnce(DoAll(Invoke(this, &QuicAlarmTest::ResetAlarm),
+ Return(QuicTime::Zero())));
alarm_.FireAlarm();
EXPECT_TRUE(alarm_.IsSet());
EXPECT_TRUE(alarm_.scheduled());
diff --git a/chromium/net/quic/quic_bandwidth.cc b/chromium/net/quic/quic_bandwidth.cc
index 911eb6c83cf..b7fe66dfd23 100644
--- a/chromium/net/quic/quic_bandwidth.cc
+++ b/chromium/net/quic/quic_bandwidth.cc
@@ -13,7 +13,7 @@
namespace net {
// Highest number that QuicBandwidth can hold.
-const int64 kQuicInfiniteBandwidth = INT64_C(0x7fffffffffffffff);
+const int64_t kQuicInfiniteBandwidth = INT64_C(0x7fffffffffffffff);
// static
QuicBandwidth QuicBandwidth::Zero() {
@@ -21,24 +21,24 @@ QuicBandwidth QuicBandwidth::Zero() {
}
// static
-QuicBandwidth QuicBandwidth::FromBitsPerSecond(int64 bits_per_second) {
+QuicBandwidth QuicBandwidth::FromBitsPerSecond(int64_t bits_per_second) {
return QuicBandwidth(bits_per_second);
}
// static
-QuicBandwidth QuicBandwidth::FromKBitsPerSecond(int64 k_bits_per_second) {
+QuicBandwidth QuicBandwidth::FromKBitsPerSecond(int64_t k_bits_per_second) {
DCHECK(k_bits_per_second < kQuicInfiniteBandwidth / 1000);
return QuicBandwidth(k_bits_per_second * 1000);
}
// static
-QuicBandwidth QuicBandwidth::FromBytesPerSecond(int64 bytes_per_second) {
+QuicBandwidth QuicBandwidth::FromBytesPerSecond(int64_t bytes_per_second) {
DCHECK(bytes_per_second < kQuicInfiniteBandwidth / 8);
return QuicBandwidth(bytes_per_second * 8);
}
// static
-QuicBandwidth QuicBandwidth::FromKBytesPerSecond(int64 k_bytes_per_second) {
+QuicBandwidth QuicBandwidth::FromKBytesPerSecond(int64_t k_bytes_per_second) {
DCHECK(k_bytes_per_second < kQuicInfiniteBandwidth / 8000);
return QuicBandwidth(k_bytes_per_second * 8000);
}
@@ -46,31 +46,31 @@ QuicBandwidth QuicBandwidth::FromKBytesPerSecond(int64 k_bytes_per_second) {
// static
QuicBandwidth QuicBandwidth::FromBytesAndTimeDelta(QuicByteCount bytes,
QuicTime::Delta delta) {
- DCHECK_LT(bytes, static_cast<uint64>(kQuicInfiniteBandwidth /
- (8 * kNumMicrosPerSecond)));
- int64 bytes_per_second =
+ DCHECK_LT(bytes, static_cast<uint64_t>(kQuicInfiniteBandwidth /
+ (8 * kNumMicrosPerSecond)));
+ int64_t bytes_per_second =
(bytes * kNumMicrosPerSecond) / delta.ToMicroseconds();
return QuicBandwidth(bytes_per_second * 8);
}
-QuicBandwidth::QuicBandwidth(int64 bits_per_second)
+QuicBandwidth::QuicBandwidth(int64_t bits_per_second)
: bits_per_second_(bits_per_second) {
DCHECK_GE(bits_per_second, 0);
}
-int64 QuicBandwidth::ToBitsPerSecond() const {
+int64_t QuicBandwidth::ToBitsPerSecond() const {
return bits_per_second_;
}
-int64 QuicBandwidth::ToKBitsPerSecond() const {
+int64_t QuicBandwidth::ToKBitsPerSecond() const {
return bits_per_second_ / 1000;
}
-int64 QuicBandwidth::ToBytesPerSecond() const {
+int64_t QuicBandwidth::ToBytesPerSecond() const {
return bits_per_second_ / 8;
}
-int64 QuicBandwidth::ToKBytesPerSecond() const {
+int64_t QuicBandwidth::ToKBytesPerSecond() const {
return bits_per_second_ / 8000;
}
@@ -80,7 +80,7 @@ QuicByteCount QuicBandwidth::ToBytesPerPeriod(
kNumMicrosPerSecond;
}
-int64 QuicBandwidth::ToKBytesPerPeriod(QuicTime::Delta time_period) const {
+int64_t QuicBandwidth::ToKBytesPerPeriod(QuicTime::Delta time_period) const {
return ToKBytesPerSecond() * time_period.ToMicroseconds() /
kNumMicrosPerSecond;
}
@@ -98,7 +98,7 @@ QuicBandwidth QuicBandwidth::Subtract(const QuicBandwidth& delta) const {
}
QuicBandwidth QuicBandwidth::Scale(float scale_factor) const {
- return QuicBandwidth(static_cast<int64>(bits_per_second_ * scale_factor));
+ return QuicBandwidth(static_cast<int64_t>(bits_per_second_ * scale_factor));
}
QuicTime::Delta QuicBandwidth::TransferTime(QuicByteCount bytes) const {
diff --git a/chromium/net/quic/quic_bandwidth.h b/chromium/net/quic/quic_bandwidth.h
index aa7a6cc2851..8c092beeeda 100644
--- a/chromium/net/quic/quic_bandwidth.h
+++ b/chromium/net/quic/quic_bandwidth.h
@@ -7,13 +7,15 @@
#ifndef NET_QUIC_QUIC_BANDWIDTH_H_
#define NET_QUIC_QUIC_BANDWIDTH_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/compiler_specific.h"
#include "net/quic/quic_time.h"
namespace net {
-typedef uint64 QuicByteCount;
-typedef uint64 QuicPacketCount;
+typedef uint64_t QuicByteCount;
+typedef uint64_t QuicPacketCount;
class NET_EXPORT_PRIVATE QuicBandwidth {
public:
@@ -21,46 +23,46 @@ class NET_EXPORT_PRIVATE QuicBandwidth {
static QuicBandwidth Zero();
// Create a new QuicBandwidth holding the bits per second.
- static QuicBandwidth FromBitsPerSecond(int64 bits_per_second);
+ static QuicBandwidth FromBitsPerSecond(int64_t bits_per_second);
// Create a new QuicBandwidth holding the kilo bits per second.
- static QuicBandwidth FromKBitsPerSecond(int64 k_bits_per_second);
+ static QuicBandwidth FromKBitsPerSecond(int64_t k_bits_per_second);
// Create a new QuicBandwidth holding the bytes per second.
- static QuicBandwidth FromBytesPerSecond(int64 bytes_per_second);
+ static QuicBandwidth FromBytesPerSecond(int64_t bytes_per_second);
// Create a new QuicBandwidth holding the kilo bytes per second.
- static QuicBandwidth FromKBytesPerSecond(int64 k_bytes_per_second);
+ static QuicBandwidth FromKBytesPerSecond(int64_t k_bytes_per_second);
// Create a new QuicBandwidth based on the bytes per the elapsed delta.
static QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes,
QuicTime::Delta delta);
- int64 ToBitsPerSecond() const;
+ int64_t ToBitsPerSecond() const;
- int64 ToKBitsPerSecond() const;
+ int64_t ToKBitsPerSecond() const;
- int64 ToBytesPerSecond() const;
+ int64_t ToBytesPerSecond() const;
- int64 ToKBytesPerSecond() const;
+ int64_t ToKBytesPerSecond() const;
QuicByteCount ToBytesPerPeriod(QuicTime::Delta time_period) const;
- int64 ToKBytesPerPeriod(QuicTime::Delta time_period) const;
+ int64_t ToKBytesPerPeriod(QuicTime::Delta time_period) const;
bool IsZero() const;
- QuicBandwidth Add(const QuicBandwidth& delta) const;
+ QuicBandwidth Add(const QuicBandwidth& delta) const WARN_UNUSED_RESULT;
- QuicBandwidth Subtract(const QuicBandwidth& delta) const;
+ QuicBandwidth Subtract(const QuicBandwidth& delta) const WARN_UNUSED_RESULT;
- QuicBandwidth Scale(float scale_factor) const;
+ QuicBandwidth Scale(float scale_factor) const WARN_UNUSED_RESULT;
QuicTime::Delta TransferTime(QuicByteCount bytes) const;
private:
- explicit QuicBandwidth(int64 bits_per_second);
- int64 bits_per_second_;
+ explicit QuicBandwidth(int64_t bits_per_second);
+ int64_t bits_per_second_;
};
// Non-member relational operators for QuicBandwidth.
diff --git a/chromium/net/quic/quic_bandwidth_test.cc b/chromium/net/quic/quic_bandwidth_test.cc
index 7f07a6a68fa..191405c61d7 100644
--- a/chromium/net/quic/quic_bandwidth_test.cc
+++ b/chromium/net/quic/quic_bandwidth_test.cc
@@ -8,8 +8,7 @@
namespace net {
namespace test {
-class QuicBandwidthTest : public ::testing::Test {
-};
+class QuicBandwidthTest : public ::testing::Test {};
TEST_F(QuicBandwidthTest, FromTo) {
EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(1),
@@ -66,16 +65,15 @@ TEST_F(QuicBandwidthTest, Scale) {
QuicBandwidth::FromKBytesPerSecond(1000).Scale(1.25f));
}
-
TEST_F(QuicBandwidthTest, BytesPerPeriod) {
- EXPECT_EQ(2000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(1)));
- EXPECT_EQ(2u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(1)));
+ EXPECT_EQ(2000u, QuicBandwidth::FromKBytesPerSecond(2000)
+ .ToBytesPerPeriod(QuicTime::Delta::FromMilliseconds(1)));
+ EXPECT_EQ(2u, QuicBandwidth::FromKBytesPerSecond(2000)
+ .ToKBytesPerPeriod(QuicTime::Delta::FromMilliseconds(1)));
EXPECT_EQ(200000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(100)));
+ QuicTime::Delta::FromMilliseconds(100)));
EXPECT_EQ(200u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(100)));
+ QuicTime::Delta::FromMilliseconds(100)));
}
TEST_F(QuicBandwidthTest, TransferTime) {
diff --git a/chromium/net/quic/quic_blocked_writer_interface.h b/chromium/net/quic/quic_blocked_writer_interface.h
index 1c3a6fed9a8..78a270af12f 100644
--- a/chromium/net/quic/quic_blocked_writer_interface.h
+++ b/chromium/net/quic/quic_blocked_writer_interface.h
@@ -9,6 +9,8 @@
#ifndef NET_QUIC_QUIC_BLOCKED_WRITER_INTERFACE_H_
#define NET_QUIC_QUIC_BLOCKED_WRITER_INTERFACE_H_
+#include <stddef.h>
+
#include "net/base/net_export.h"
namespace net {
diff --git a/chromium/net/quic/quic_bug_tracker.h b/chromium/net/quic/quic_bug_tracker.h
new file mode 100644
index 00000000000..bbec94bd09d
--- /dev/null
+++ b/chromium/net/quic/quic_bug_tracker.h
@@ -0,0 +1,10 @@
+// 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_QUIC_BUG_TRACKER_H_
+#define NET_QUIC_QUIC_BUG_TRACKER_H_
+
+// For external QUIC, QUIC_BUG should be #defined to LOG(DFATAL) as client-side
+// log rate limiting is less important and chrome doesn't LOG_FIRST_N anyway.
+#define QUIC_BUG LOG(DFATAL)
+#endif // NET_QUIC_QUIC_BUG_TRACKER_H_
diff --git a/chromium/net/quic/quic_chromium_client_session.cc b/chromium/net/quic/quic_chromium_client_session.cc
index 1abab6ba7af..c30b69fc6c1 100644
--- a/chromium/net/quic/quic_chromium_client_session.cc
+++ b/chromium/net/quic/quic_chromium_client_session.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_chromium_client_session.h"
+#include <utility>
+
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
@@ -19,7 +21,7 @@
#include "net/http/transport_security_state.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
#include "net/quic/crypto/quic_server_info.h"
-#include "net/quic/quic_connection_helper.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_crypto_client_stream_factory.h"
#include "net/quic/quic_server_id.h"
#include "net/quic/quic_stream_factory.h"
@@ -40,6 +42,11 @@ const int k0RttHandshakeTimeoutMs = 300;
// IPv6 packets have an additional 20 bytes of overhead than IPv4 packets.
const size_t kAdditionalOverheadForIPv6 = 20;
+// Maximum number of Readers that are created for any session due to
+// connection migration. A new Reader is created every time this endpoint's
+// IP address changes.
+const size_t kMaxReadersPerQuicSession = 5;
+
// 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
@@ -106,12 +113,11 @@ scoped_ptr<base::Value> NetLogQuicClientSessionCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host", server_id->host());
dict->SetInteger("port", server_id->port());
- dict->SetBoolean("is_https", server_id->is_https());
dict->SetBoolean("privacy_mode",
server_id->privacy_mode() == PRIVACY_MODE_ENABLED);
dict->SetBoolean("require_confirmation", require_confirmation);
dict->SetInteger("cert_verify_flags", cert_verify_flags);
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
@@ -124,7 +130,7 @@ QuicChromiumClientSession::StreamRequest::~StreamRequest() {
int QuicChromiumClientSession::StreamRequest::StartRequest(
const base::WeakPtr<QuicChromiumClientSession>& session,
- QuicReliableClientStream** stream,
+ QuicChromiumClientStream** stream,
const CompletionCallback& callback) {
session_ = session;
stream_ = stream;
@@ -144,7 +150,7 @@ void QuicChromiumClientSession::StreamRequest::CancelRequest() {
}
void QuicChromiumClientSession::StreamRequest::OnRequestCompleteSuccess(
- QuicReliableClientStream* stream) {
+ QuicChromiumClientStream* stream) {
session_.reset();
*stream_ = stream;
ResetAndReturn(&callback_).Run(OK);
@@ -179,34 +185,28 @@ QuicChromiumClientSession::QuicChromiumClientSession(
server_id_(server_id),
require_confirmation_(false),
stream_factory_(stream_factory),
- socket_(socket.Pass()),
transport_security_state_(transport_security_state),
- server_info_(server_info.Pass()),
+ server_info_(std::move(server_info)),
num_total_streams_(0),
task_runner_(task_runner),
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_QUIC_SESSION)),
- packet_reader_(socket_.get(),
- clock,
- this,
- yield_after_packets,
- yield_after_duration,
- net_log_),
dns_resolution_end_time_(dns_resolution_end_time),
logger_(new QuicConnectionLogger(this,
connection_description,
- socket_performance_watcher.Pass(),
+ std::move(socket_performance_watcher),
net_log_)),
going_away_(false),
disabled_reason_(QUIC_DISABLED_NOT),
weak_factory_(this) {
+ sockets_.push_back(std::move(socket));
+ packet_readers_.push_back(make_scoped_ptr(new QuicPacketReader(
+ sockets_.back().get(), clock, this, yield_after_packets,
+ yield_after_duration, net_log_)));
crypto_stream_.reset(
- crypto_client_stream_factory
- ? crypto_client_stream_factory->CreateQuicCryptoClientStream(
- server_id, this, crypto_config)
- : new QuicCryptoClientStream(
- server_id, this,
- new ProofVerifyContextChromium(cert_verify_flags, net_log_),
- crypto_config));
+ crypto_client_stream_factory->CreateQuicCryptoClientStream(
+ server_id, this, make_scoped_ptr(new ProofVerifyContextChromium(
+ cert_verify_flags, net_log_)),
+ crypto_config));
connection->set_debug_visitor(logger_.get());
net_log_.BeginEvent(NetLog::TYPE_QUIC_SESSION,
base::Bind(NetLogQuicClientSessionCallback, &server_id,
@@ -274,20 +274,8 @@ QuicChromiumClientSession::~QuicChromiumClientSession() {
bool port_selected = stream_factory_->enable_port_selection();
SSLInfo ssl_info;
- if (!GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) {
- if (port_selected) {
- UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectSelectPortForHTTP",
- round_trip_handshakes, 0, 3, 4);
- } else {
- UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectRandomPortForHTTP",
- round_trip_handshakes, 0, 3, 4);
- if (require_confirmation_) {
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Net.QuicSession.ConnectRandomPortRequiringConfirmationForHTTP",
- round_trip_handshakes, 0, 3, 4);
- }
- }
- } else {
+ // QUIC supports only secure urls.
+ if (GetSSLInfo(&ssl_info) && ssl_info.cert.get()) {
if (port_selected) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectSelectPortForHTTPS",
round_trip_handshakes, 0, 3, 4);
@@ -350,6 +338,13 @@ QuicChromiumClientSession::~QuicChromiumClientSession() {
static_cast<base::HistogramBase::Sample>(stats.max_sequence_reordering));
}
+void QuicChromiumClientSession::OnHeadersHeadOfLineBlocking(
+ QuicTime::Delta delta) {
+ UMA_HISTOGRAM_TIMES(
+ "Net.QuicSession.HeadersHOLBlockedTime",
+ base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()));
+}
+
void QuicChromiumClientSession::OnStreamFrame(const QuicStreamFrame& frame) {
// Record total number of stream frames.
UMA_HISTOGRAM_COUNTS("Net.QuicNumStreamFramesInPacket", 1);
@@ -378,7 +373,7 @@ void QuicChromiumClientSession::RemoveObserver(Observer* observer) {
int QuicChromiumClientSession::TryCreateStream(
StreamRequest* request,
- QuicReliableClientStream** stream) {
+ QuicChromiumClientStream** stream) {
if (!crypto_stream_->encryption_established()) {
DLOG(DFATAL) << "Encryption not established.";
return ERR_CONNECTION_CLOSED;
@@ -399,7 +394,7 @@ int QuicChromiumClientSession::TryCreateStream(
return ERR_CONNECTION_CLOSED;
}
- if (GetNumOpenStreams() < get_max_open_streams()) {
+ if (GetNumOpenOutgoingStreams() < get_max_open_streams()) {
*stream = CreateOutgoingReliableStreamImpl();
return OK;
}
@@ -418,15 +413,15 @@ void QuicChromiumClientSession::CancelRequest(StreamRequest* request) {
}
}
-QuicReliableClientStream*
-QuicChromiumClientSession::CreateOutgoingDynamicStream() {
+QuicChromiumClientStream*
+QuicChromiumClientSession::CreateOutgoingDynamicStream(SpdyPriority priority) {
if (!crypto_stream_->encryption_established()) {
DVLOG(1) << "Encryption not active so no outgoing stream created.";
return nullptr;
}
- if (GetNumOpenStreams() >= get_max_open_streams()) {
+ if (GetNumOpenOutgoingStreams() >= get_max_open_streams()) {
DVLOG(1) << "Failed to create a new outgoing stream. "
- << "Already " << GetNumOpenStreams() << " open.";
+ << "Already " << GetNumOpenOutgoingStreams() << " open.";
return nullptr;
}
if (goaway_received()) {
@@ -441,18 +436,19 @@ QuicChromiumClientSession::CreateOutgoingDynamicStream() {
return CreateOutgoingReliableStreamImpl();
}
-QuicReliableClientStream*
+QuicChromiumClientStream*
QuicChromiumClientSession::CreateOutgoingReliableStreamImpl() {
DCHECK(connection()->connected());
- QuicReliableClientStream* stream =
- new QuicReliableClientStream(GetNextStreamId(), this, net_log_);
+ QuicChromiumClientStream* stream =
+ new QuicChromiumClientStream(GetNextOutgoingStreamId(), this, net_log_);
ActivateStream(stream);
++num_total_streams_;
- UMA_HISTOGRAM_COUNTS("Net.QuicSession.NumOpenStreams", GetNumOpenStreams());
+ UMA_HISTOGRAM_COUNTS("Net.QuicSession.NumOpenStreams",
+ GetNumOpenOutgoingStreams());
// The previous histogram puts 100 in a bucket betweeen 86-113 which does
// not shed light on if chrome ever things it has more than 100 streams open.
UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.TooManyOpenStreams",
- GetNumOpenStreams() > 100);
+ GetNumOpenOutgoingStreams() > 100);
return stream;
}
@@ -475,7 +471,7 @@ bool QuicChromiumClientSession::GetSSLInfo(SSLInfo* ssl_info) const {
// Report the TLS cipher suite that most closely resembles the crypto
// parameters of the QUIC connection.
QuicTag aead = crypto_stream_->crypto_negotiated_params().aead;
- uint16 cipher_suite;
+ uint16_t cipher_suite;
int security_bits;
switch (aead) {
case kAESG:
@@ -486,6 +482,10 @@ bool QuicChromiumClientSession::GetSSLInfo(SSLInfo* ssl_info) const {
cipher_suite = 0xcc13; // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
security_bits = 256;
break;
+ case kCC20:
+ cipher_suite = 0xcc13; // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+ security_bits = 256;
+ break;
default:
NOTREACHED();
return false;
@@ -506,6 +506,9 @@ bool QuicChromiumClientSession::GetSSLInfo(SSLInfo* ssl_info) const {
ssl_info->security_bits = security_bits;
ssl_info->handshake_type = SSLInfo::HANDSHAKE_FULL;
ssl_info->pinning_failure_log = pinning_failure_log_;
+
+ ssl_info->UpdateSignedCertificateTimestamps(*ct_verify_result_);
+
return true;
}
@@ -562,15 +565,15 @@ bool QuicChromiumClientSession::CanPool(const std::string& hostname,
}
SSLInfo ssl_info;
if (!GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) {
- // We can always pool with insecure QUIC sessions.
- return true;
+ NOTREACHED() << "QUIC should always have certificates.";
+ return false;
}
return SpdySession::CanPool(transport_security_state_, ssl_info,
server_id_.host(), hostname);
}
-QuicDataStream* QuicChromiumClientSession::CreateIncomingDynamicStream(
+QuicSpdyStream* QuicChromiumClientSession::CreateIncomingDynamicStream(
QuicStreamId id) {
DLOG(ERROR) << "Server push not supported";
return nullptr;
@@ -594,7 +597,7 @@ void QuicChromiumClientSession::SendRstStream(QuicStreamId id,
}
void QuicChromiumClientSession::OnClosedStream() {
- if (GetNumOpenStreams() < get_max_open_streams() &&
+ if (GetNumOpenOutgoingStreams() < get_max_open_streams() &&
!stream_requests_.empty() && crypto_stream_->encryption_established() &&
!goaway_received() && !going_away_ && connection()->connected()) {
StreamRequest* request = stream_requests_.front();
@@ -602,7 +605,7 @@ void QuicChromiumClientSession::OnClosedStream() {
request->OnRequestCompleteSuccess(CreateOutgoingReliableStreamImpl());
}
- if (GetNumOpenStreams() == 0) {
+ if (GetNumOpenOutgoingStreams() == 0) {
stream_factory_->OnIdleSession(this);
}
}
@@ -664,6 +667,12 @@ void QuicChromiumClientSession::OnCryptoHandshakeEvent(
void QuicChromiumClientSession::OnCryptoHandshakeMessageSent(
const CryptoHandshakeMessage& message) {
logger_->OnCryptoHandshakeMessageSent(message);
+
+ if (message.tag() == kREJ || message.tag() == kSREJ) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.RejectLength",
+ message.GetSerialized().length(), 1000, 10000,
+ 50);
+ }
}
void QuicChromiumClientSession::OnCryptoHandshakeMessageReceived(
@@ -676,6 +685,11 @@ void QuicChromiumClientSession::OnGoAway(const QuicGoAwayFrame& frame) {
NotifyFactoryOfSessionGoingAway();
}
+void QuicChromiumClientSession::OnRstStream(const QuicRstStreamFrame& frame) {
+ QuicSession::OnRstStream(frame);
+ OnClosedStream();
+}
+
void QuicChromiumClientSession::OnConnectionClosed(QuicErrorCode error,
bool from_peer) {
DCHECK(!connection()->connected());
@@ -701,9 +715,9 @@ void QuicChromiumClientSession::OnConnectionClosed(QuicErrorCode error,
if (error == QUIC_CONNECTION_TIMED_OUT) {
UMA_HISTOGRAM_COUNTS(
"Net.QuicSession.ConnectionClose.NumOpenStreams.TimedOut",
- GetNumOpenStreams());
+ GetNumOpenOutgoingStreams());
if (IsCryptoHandshakeConfirmed()) {
- if (GetNumOpenStreams() > 0) {
+ if (GetNumOpenOutgoingStreams() > 0) {
disabled_reason_ = QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS;
UMA_HISTOGRAM_BOOLEAN(
"Net.QuicSession.TimedOutWithOpenStreams.HasUnackedPackets",
@@ -730,7 +744,7 @@ void QuicChromiumClientSession::OnConnectionClosed(QuicErrorCode error,
} else {
UMA_HISTOGRAM_COUNTS(
"Net.QuicSession.ConnectionClose.NumOpenStreams.HandshakeTimedOut",
- GetNumOpenStreams());
+ GetNumOpenOutgoingStreams());
UMA_HISTOGRAM_COUNTS(
"Net.QuicSession.ConnectionClose.NumTotalStreams.HandshakeTimedOut",
num_total_streams_);
@@ -761,7 +775,10 @@ void QuicChromiumClientSession::OnConnectionClosed(QuicErrorCode error,
if (!callback_.is_null()) {
base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR);
}
- socket_->Close();
+
+ for (auto& socket : sockets_) {
+ socket->Close();
+ }
QuicSession::OnConnectionClosed(error, from_peer);
DCHECK(dynamic_streams().empty());
CloseAllStreams(ERR_UNEXPECTED);
@@ -797,15 +814,19 @@ void QuicChromiumClientSession::OnProofVerifyDetailsAvailable(
const ProofVerifyDetails& verify_details) {
const ProofVerifyDetailsChromium* verify_details_chromium =
reinterpret_cast<const ProofVerifyDetailsChromium*>(&verify_details);
- CertVerifyResult* result_copy = new CertVerifyResult;
- result_copy->CopyFrom(verify_details_chromium->cert_verify_result);
- cert_verify_result_.reset(result_copy);
+ cert_verify_result_.reset(new CertVerifyResult);
+ cert_verify_result_->CopyFrom(verify_details_chromium->cert_verify_result);
pinning_failure_log_ = verify_details_chromium->pinning_failure_log;
+ scoped_ptr<ct::CTVerifyResult> ct_verify_result_copy(
+ new ct::CTVerifyResult(verify_details_chromium->ct_verify_result));
+ ct_verify_result_ = std::move(ct_verify_result_copy);
logger_->OnCertificateVerified(*cert_verify_result_);
}
void QuicChromiumClientSession::StartReading() {
- packet_reader_.StartReading();
+ for (auto& packet_reader : packet_readers_) {
+ packet_reader->StartReading();
+ }
}
void QuicChromiumClientSession::CloseSessionOnError(int error,
@@ -837,7 +858,7 @@ void QuicChromiumClientSession::CloseSessionOnErrorInner(
CloseAllStreams(net_error);
CloseAllObservers(net_error);
net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_CLOSE_ON_ERROR,
- NetLog::IntegerCallback("net_error", net_error));
+ NetLog::IntCallback("net_error", net_error));
if (connection()->connected())
connection()->CloseConnection(quic_error, false);
@@ -848,7 +869,7 @@ void QuicChromiumClientSession::CloseAllStreams(int net_error) {
while (!dynamic_streams().empty()) {
ReliableQuicStream* stream = dynamic_streams().begin()->second;
QuicStreamId id = stream->id();
- static_cast<QuicReliableClientStream*>(stream)->OnError(net_error);
+ static_cast<QuicChromiumClientStream*>(stream)->OnError(net_error);
CloseStream(id);
}
}
@@ -865,7 +886,7 @@ scoped_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
const std::set<HostPortPair>& aliases) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("version", QuicVersionToString(connection()->version()));
- dict->SetInteger("open_streams", GetNumOpenStreams());
+ dict->SetInteger("open_streams", GetNumOpenOutgoingStreams());
scoped_ptr<base::ListValue> stream_list(new base::ListValue());
for (base::hash_map<QuicStreamId, ReliableQuicStream*>::const_iterator it =
dynamic_streams().begin();
@@ -873,7 +894,7 @@ scoped_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
stream_list->Append(
new base::StringValue(base::UintToString(it->second->id())));
}
- dict->Set("active_streams", stream_list.Pass());
+ dict->Set("active_streams", std::move(stream_list));
dict->SetInteger("total_streams", num_total_streams_);
dict->SetString("peer_address", peer_address().ToString());
@@ -891,9 +912,9 @@ scoped_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
it != aliases.end(); it++) {
alias_list->Append(new base::StringValue(it->ToString()));
}
- dict->Set("aliases", alias_list.Pass());
+ dict->Set("aliases", std::move(alias_list));
- return dict.Pass();
+ return std::move(dict);
}
base::WeakPtr<QuicChromiumClientSession>
@@ -901,7 +922,15 @@ QuicChromiumClientSession::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
-void QuicChromiumClientSession::OnReadError(int result) {
+void QuicChromiumClientSession::OnReadError(
+ int result,
+ const DatagramClientSocket* socket) {
+ DCHECK(socket != nullptr);
+ if (socket != GetDefaultSocket()) {
+ // Ignore read errors from old sockets that are no longer active.
+ // TODO(jri): Maybe clean up old sockets on error.
+ return;
+ }
DVLOG(1) << "Closing session on read error: " << result;
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ReadError", -result);
NotifyFactoryOfSessionGoingAway();
@@ -934,7 +963,7 @@ void QuicChromiumClientSession::NotifyFactoryOfSessionClosedLater() {
RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER);
going_away_ = true;
- DCHECK_EQ(0u, GetNumOpenStreams());
+ DCHECK_EQ(0u, GetNumActiveStreams());
DCHECK(!connection()->connected());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -950,7 +979,7 @@ void QuicChromiumClientSession::NotifyFactoryOfSessionClosed() {
RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED);
going_away_ = true;
- DCHECK_EQ(0u, GetNumOpenStreams());
+ DCHECK_EQ(0u, GetNumActiveStreams());
// Will delete |this|.
if (stream_factory_)
stream_factory_->OnSessionClosed(this);
@@ -967,7 +996,31 @@ void QuicChromiumClientSession::OnConnectTimeout() {
// if (stream_factory_)
// stream_factory_->OnSessionConnectTimeout(this);
// CloseAllStreams(ERR_QUIC_HANDSHAKE_FAILED);
- // DCHECK_EQ(0u, GetNumOpenStreams());
+ // DCHECK_EQ(0u, GetNumOpenOutgoingStreams());
+}
+
+bool QuicChromiumClientSession::MigrateToSocket(
+ scoped_ptr<DatagramClientSocket> socket,
+ scoped_ptr<QuicPacketReader> reader,
+ scoped_ptr<QuicPacketWriter> writer) {
+ DCHECK_EQ(sockets_.size(), packet_readers_.size());
+ if (sockets_.size() >= kMaxReadersPerQuicSession) {
+ return false;
+ }
+ // TODO(jri): Make SetQuicPacketWriter take a scoped_ptr.
+ connection()->SetQuicPacketWriter(writer.release(), /*owns_writer=*/true);
+ packet_readers_.push_back(std::move(reader));
+ sockets_.push_back(std::move(socket));
+ StartReading();
+ connection()->SendPing();
+ return true;
+}
+
+const DatagramClientSocket* QuicChromiumClientSession::GetDefaultSocket()
+ const {
+ DCHECK(sockets_.back().get() != nullptr);
+ // The most recently added socket is the currently active one.
+ return sockets_.back().get();
}
} // namespace net
diff --git a/chromium/net/quic/quic_chromium_client_session.h b/chromium/net/quic/quic_chromium_client_session.h
index 0a1ac868ce0..e47f4146788 100644
--- a/chromium/net/quic/quic_chromium_client_session.h
+++ b/chromium/net/quic/quic_chromium_client_session.h
@@ -10,28 +10,31 @@
#ifndef NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_
#define NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "net/base/completion_callback.h"
#include "net/base/socket_performance_watcher.h"
+#include "net/cert/ct_verify_result.h"
#include "net/proxy/proxy_server.h"
+#include "net/quic/quic_chromium_client_stream.h"
#include "net/quic/quic_client_session_base.h"
#include "net/quic/quic_connection_logger.h"
#include "net/quic/quic_crypto_client_stream.h"
#include "net/quic/quic_packet_reader.h"
#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_reliable_client_stream.h"
#include "net/quic/quic_time.h"
namespace net {
class CertVerifyResult;
class DatagramClientSocket;
-class QuicConnectionHelper;
+class QuicChromiumConnectionHelper;
class QuicCryptoClientStreamFactory;
class QuicServerId;
class QuicServerInfo;
@@ -78,7 +81,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// ERR_IO_PENDING is returned, then when the request is eventuallly
// complete |callback| will be called.
int StartRequest(const base::WeakPtr<QuicChromiumClientSession>& session,
- QuicReliableClientStream** stream,
+ QuicChromiumClientStream** stream,
const CompletionCallback& callback);
// Cancels any pending stream creation request. May be called
@@ -90,7 +93,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// Called by |session_| for an asynchronous request when the stream
// request has finished successfully.
- void OnRequestCompleteSuccess(QuicReliableClientStream* stream);
+ void OnRequestCompleteSuccess(QuicChromiumClientStream* stream);
// Called by |session_| for an asynchronous request when the stream
// request has finished with an error. Also called with ERR_ABORTED
@@ -99,7 +102,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
base::WeakPtr<QuicChromiumClientSession> session_;
CompletionCallback callback_;
- QuicReliableClientStream** stream_;
+ QuicChromiumClientStream** stream_;
DISALLOW_COPY_AND_ASSIGN(StreamRequest);
};
@@ -139,14 +142,18 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// TODO(rch): remove |stream| from this and use setter on |request|
// and fix in spdy too.
int TryCreateStream(StreamRequest* request,
- QuicReliableClientStream** stream);
+ QuicChromiumClientStream** stream);
// Cancels the pending stream creation request.
void CancelRequest(StreamRequest* request);
+ // QuicSpdySession methods:
+ void OnHeadersHeadOfLineBlocking(QuicTime::Delta delta) override;
+
// QuicSession methods:
void OnStreamFrame(const QuicStreamFrame& frame) override;
- QuicReliableClientStream* CreateOutgoingDynamicStream() override;
+ QuicChromiumClientStream* CreateOutgoingDynamicStream(
+ SpdyPriority priority) override;
QuicCryptoClientStream* GetCryptoStream() override;
void CloseStream(QuicStreamId stream_id) override;
void SendRstStream(QuicStreamId id,
@@ -158,6 +165,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
void OnCryptoHandshakeMessageReceived(
const CryptoHandshakeMessage& message) override;
void OnGoAway(const QuicGoAwayFrame& frame) override;
+ void OnRstStream(const QuicRstStreamFrame& frame) override;
// QuicClientSessionBase methods:
void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
@@ -169,7 +177,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
void OnSuccessfulVersionNegotiation(const QuicVersion& version) override;
// QuicPacketReader::Visitor methods:
- void OnReadError(int result) override;
+ void OnReadError(int result, const DatagramClientSocket* socket) override;
bool OnPacket(const QuicEncryptedPacket& packet,
IPEndPoint local_address,
IPEndPoint peer_address) override;
@@ -184,7 +192,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// Resumes a crypto handshake with the server after a timeout.
int ResumeCryptoConnect(const CompletionCallback& callback);
- // Causes the QuicConnectionHelper to start reading from the socket
+ // Causes the QuicConnectionHelper to start reading from all sockets
// and passing the data along to the QuicConnection.
void StartReading();
@@ -217,9 +225,24 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
QuicDisabledReason disabled_reason() const { return disabled_reason_; }
+ // Migrates session onto new socket, i.e., starts reading from |socket|
+ // in addition to any previous sockets, and sets |writer| to be the new
+ // default writer. Returns true if socket was successfully added to the
+ // session and the session was successfully migrated to using the new socket.
+ // Returns false if number of migrations exceeds kMaxReadersPerQuicSession.
+ // Takes ownership of |socket|, |reader|, and |writer|.
+ bool MigrateToSocket(scoped_ptr<DatagramClientSocket> socket,
+ scoped_ptr<QuicPacketReader> reader,
+ scoped_ptr<QuicPacketWriter> writer);
+
+ // Returns current default socket. This is the socket over which all
+ // QUIC packets are sent. This default socket can change, so do not store the
+ // returned socket.
+ const DatagramClientSocket* GetDefaultSocket() const;
+
protected:
// QuicSession methods:
- QuicDataStream* CreateIncomingDynamicStream(QuicStreamId id) override;
+ QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override;
private:
friend class test::QuicChromiumClientSessionPeer;
@@ -227,7 +250,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
typedef std::set<Observer*> ObserverSet;
typedef std::list<StreamRequest*> StreamRequestQueue;
- QuicReliableClientStream* CreateOutgoingReliableStreamImpl();
+ QuicChromiumClientStream* CreateOutgoingReliableStreamImpl();
// A completion callback invoked when a read completes.
void OnReadComplete(int result);
@@ -266,10 +289,11 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
bool require_confirmation_;
scoped_ptr<QuicCryptoClientStream> crypto_stream_;
QuicStreamFactory* stream_factory_;
- scoped_ptr<DatagramClientSocket> socket_;
+ std::vector<scoped_ptr<DatagramClientSocket>> sockets_;
TransportSecurityState* transport_security_state_;
scoped_ptr<QuicServerInfo> server_info_;
scoped_ptr<CertVerifyResult> cert_verify_result_;
+ scoped_ptr<ct::CTVerifyResult> ct_verify_result_;
std::string pinning_failure_log_;
ObserverSet observers_;
StreamRequestQueue stream_requests_;
@@ -277,7 +301,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
size_t num_total_streams_;
base::TaskRunner* task_runner_;
BoundNetLog net_log_;
- QuicPacketReader packet_reader_;
+ std::vector<scoped_ptr<QuicPacketReader>> packet_readers_;
base::TimeTicks dns_resolution_end_time_;
base::TimeTicks handshake_start_; // Time the handshake was started.
scoped_ptr<QuicConnectionLogger> logger_;
diff --git a/chromium/net/quic/quic_chromium_client_session_test.cc b/chromium/net/quic/quic_chromium_client_session_test.cc
index f22ccde4875..6d0288a703f 100644
--- a/chromium/net/quic/quic_chromium_client_session_test.cc
+++ b/chromium/net/quic/quic_chromium_client_session_test.cc
@@ -22,10 +22,19 @@
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/crypto/quic_server_info.h"
+#include "net/quic/quic_chromium_connection_helper.h"
+#include "net/quic/quic_crypto_client_stream_factory.h"
+#include "net/quic/quic_default_packet_writer.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_http_utils.h"
#include "net/quic/quic_packet_reader.h"
+#include "net/quic/quic_packet_writer.h"
+#include "net/quic/quic_protocol.h"
#include "net/quic/test_tools/crypto_test_utils.h"
+#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
#include "net/quic/test_tools/quic_chromium_client_session_peer.h"
#include "net/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/quic/test_tools/quic_test_packet_maker.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/simple_quic_framer.h"
#include "net/socket/socket_test_util.h"
@@ -39,72 +48,90 @@ namespace net {
namespace test {
namespace {
-const char kServerHostname[] = "www.example.org";
-const uint16 kServerPort = 80;
+const IPEndPoint kIpEndPoint(IPAddressNumber(kIPv4AddressSize, 0), 0);
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+const size_t kMaxReadersPerQuicSession = 5;
class QuicChromiumClientSessionTest
: public ::testing::TestWithParam<QuicVersion> {
protected:
QuicChromiumClientSessionTest()
- : connection_(new PacketSavingConnection(Perspective::IS_CLIENT,
- SupportedVersions(GetParam()))),
- session_(connection_,
- GetSocket().Pass(),
- /*stream_factory=*/nullptr,
- /*crypto_client_stream_factory=*/nullptr,
- &clock_,
- &transport_security_state_,
- make_scoped_ptr((QuicServerInfo*)nullptr),
- QuicServerId(kServerHostname,
- kServerPort,
- /*is_secure=*/false,
- PRIVACY_MODE_DISABLED),
- kQuicYieldAfterPacketsRead,
- QuicTime::Delta::FromMilliseconds(
- kQuicYieldAfterDurationMilliseconds),
- /*cert_verify_flags=*/0,
- DefaultQuicConfig(),
- &crypto_config_,
- "CONNECTION_UNKNOWN",
- base::TimeTicks::Now(),
- base::ThreadTaskRunnerHandle::Get().get(),
- /*socket_performance_watcher=*/nullptr,
- &net_log_) {
- session_.Initialize();
+ : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
+ default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
+ socket_data_(
+ new SequencedSocketData(default_read_.get(), 1, nullptr, 0)),
+ random_(0),
+ helper_(base::ThreadTaskRunnerHandle::Get().get(), &clock_, &random_),
+ maker_(GetParam(), 0, &clock_, kServerHostname) {}
+
+ void Initialize() {
+ socket_factory_.AddSocketDataProvider(socket_data_.get());
+ scoped_ptr<DatagramClientSocket> socket =
+ socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
+ base::Bind(&base::RandInt),
+ &net_log_, NetLog::Source());
+ socket->Connect(kIpEndPoint);
+ QuicDefaultPacketWriter* writer =
+ new net::QuicDefaultPacketWriter(socket.get());
+ QuicConnection* connection = new QuicConnection(
+ 0, kIpEndPoint, &helper_, writer, true, Perspective::IS_CLIENT,
+ SupportedVersions(GetParam()));
+ writer->SetConnection(connection);
+ session_.reset(new QuicChromiumClientSession(
+ connection, std::move(socket),
+ /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
+ &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
+ QuicServerId(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
+ kQuicYieldAfterPacketsRead,
+ QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
+ /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
+ "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
+ base::ThreadTaskRunnerHandle::Get().get(),
+ /*socket_performance_watcher=*/nullptr, &net_log_));
+
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
+ verify_details_.cert_verify_result.verified_cert = cert;
+ verify_details_.cert_verify_result.is_issued_by_known_root = true;
// Advance the time, because timers do not like uninitialized times.
- connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ session_->Initialize();
+ session_->StartReading();
}
void TearDown() override {
- session_.CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
+ session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
}
- scoped_ptr<DatagramClientSocket> GetSocket() {
- socket_factory_.AddSocketDataProvider(&socket_data_);
- return socket_factory_.CreateDatagramClientSocket(
- DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt), &net_log_,
- NetLog::Source());
+ void CompleteCryptoHandshake() {
+ ASSERT_EQ(OK, session_->CryptoConnect(false, callback_.callback()));
}
- void CompleteCryptoHandshake() {
- ASSERT_EQ(ERR_IO_PENDING,
- session_.CryptoConnect(false, callback_.callback()));
- CryptoTestUtils::HandshakeWithFakeServer(connection_,
- session_.GetCryptoStream());
- ASSERT_EQ(OK, callback_.WaitForResult());
+ QuicPacketWriter* CreateQuicPacketWriter(DatagramClientSocket* socket,
+ QuicConnection* connection) const {
+ scoped_ptr<QuicDefaultPacketWriter> writer(
+ new QuicDefaultPacketWriter(socket));
+ writer->SetConnection(connection);
+ return writer.release();
}
- PacketSavingConnection* connection_;
+ QuicCryptoClientConfig crypto_config_;
TestNetLog net_log_;
+ BoundTestNetLog bound_net_log_;
MockClientSocketFactory socket_factory_;
- StaticSocketDataProvider socket_data_;
- TransportSecurityState transport_security_state_;
- QuicChromiumClientSession session_;
+ scoped_ptr<MockRead> default_read_;
+ scoped_ptr<SequencedSocketData> socket_data_;
MockClock clock_;
MockRandom random_;
+ QuicChromiumConnectionHelper helper_;
+ TransportSecurityState transport_security_state_;
+ MockCryptoClientStreamFactory crypto_client_stream_factory_;
+ scoped_ptr<QuicChromiumClientSession> session_;
QuicConnectionVisitorInterface* visitor_;
TestCompletionCallback callback_;
- QuicCryptoClientConfig crypto_config_;
+ QuicTestPacketMaker maker_;
+ ProofVerifyDetailsChromium verify_details_;
};
INSTANTIATE_TEST_CASE_P(Tests,
@@ -112,60 +139,96 @@ INSTANTIATE_TEST_CASE_P(Tests,
::testing::ValuesIn(QuicSupportedVersions()));
TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
+ Initialize();
CompleteCryptoHandshake();
}
TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) {
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
+ 1, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT));
+ MockWrite writes[] = {
+ MockWrite(ASYNC, client_rst->data(), client_rst->length(), 1)};
+ socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes,
+ arraysize(writes)));
+
+ Initialize();
CompleteCryptoHandshake();
+ const size_t kMaxOpenStreams = session_->get_max_open_streams();
- std::vector<QuicReliableClientStream*> streams;
- for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
- QuicReliableClientStream* stream = session_.CreateOutgoingDynamicStream();
+ std::vector<QuicChromiumClientStream*> streams;
+ for (size_t i = 0; i < kMaxOpenStreams; i++) {
+ QuicChromiumClientStream* stream =
+ session_->CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_TRUE(stream);
streams.push_back(stream);
}
- EXPECT_FALSE(session_.CreateOutgoingDynamicStream());
+ EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
+
+ EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
// Close a stream and ensure I can now open a new one.
- session_.CloseStream(streams[0]->id());
- EXPECT_TRUE(session_.CreateOutgoingDynamicStream());
+ QuicStreamId stream_id = streams[0]->id();
+ session_->CloseStream(stream_id);
+
+ EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
+ QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0);
+ session_->OnRstStream(rst1);
+ EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
+ EXPECT_TRUE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
}
TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
+ 1, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT));
+ MockWrite writes[] = {
+ MockWrite(ASYNC, client_rst->data(), client_rst->length(), 1)};
+ socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes,
+ arraysize(writes)));
+
+ Initialize();
CompleteCryptoHandshake();
+ const size_t kMaxOpenStreams = session_->get_max_open_streams();
- std::vector<QuicReliableClientStream*> streams;
- for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
- QuicReliableClientStream* stream = session_.CreateOutgoingDynamicStream();
+ std::vector<QuicChromiumClientStream*> streams;
+ for (size_t i = 0; i < kMaxOpenStreams; i++) {
+ QuicChromiumClientStream* stream =
+ session_->CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_TRUE(stream);
streams.push_back(stream);
}
- QuicReliableClientStream* stream;
+ QuicChromiumClientStream* stream;
QuicChromiumClientSession::StreamRequest stream_request;
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING,
- stream_request.StartRequest(session_.GetWeakPtr(), &stream,
+ stream_request.StartRequest(session_->GetWeakPtr(), &stream,
callback.callback()));
// Close a stream and ensure I can now open a new one.
- session_.CloseStream(streams[0]->id());
+ QuicStreamId stream_id = streams[0]->id();
+ session_->CloseStream(stream_id);
+ QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0);
+ session_->OnRstStream(rst1);
ASSERT_TRUE(callback.have_result());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(stream != nullptr);
}
TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) {
+ Initialize();
CompleteCryptoHandshake();
// After receiving a GoAway, I should no longer be able to create outgoing
// streams.
- session_.connection()->OnGoAwayFrame(
+ session_->connection()->OnGoAwayFrame(
QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
- EXPECT_EQ(nullptr, session_.CreateOutgoingDynamicStream());
+ EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream(kDefaultPriority));
}
TEST_P(QuicChromiumClientSessionTest, CanPool) {
+ Initialize();
// Load a cert that is valid for:
// www.example.org
// mail.example.org
@@ -176,17 +239,18 @@ TEST_P(QuicChromiumClientSessionTest, CanPool) {
ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
- session_.OnProofVerifyDetailsAvailable(details);
CompleteCryptoHandshake();
+ session_->OnProofVerifyDetailsAvailable(details);
- EXPECT_TRUE(session_.CanPool("www.example.org", PRIVACY_MODE_DISABLED));
- EXPECT_FALSE(session_.CanPool("www.example.org", PRIVACY_MODE_ENABLED));
- EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
- EXPECT_TRUE(session_.CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
- EXPECT_FALSE(session_.CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
+ EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED));
+ EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED));
+ EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
+ EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
+ EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
}
TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithTlsChannelId) {
+ Initialize();
// Load a cert that is valid for:
// www.example.org
// mail.example.org
@@ -197,20 +261,23 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithTlsChannelId) {
ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
- session_.OnProofVerifyDetailsAvailable(details);
CompleteCryptoHandshake();
- QuicChromiumClientSessionPeer::SetChannelIDSent(&session_, true);
-
- EXPECT_TRUE(session_.CanPool("www.example.org", PRIVACY_MODE_DISABLED));
- EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
- EXPECT_FALSE(session_.CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
- EXPECT_FALSE(session_.CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
+ session_->OnProofVerifyDetailsAvailable(details);
+ QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
+ QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
+
+ EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED));
+ EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
+ EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
+ EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
}
TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
- uint8 primary_pin = 1;
- uint8 backup_pin = 2;
- uint8 bad_pin = 3;
+ Initialize();
+
+ uint8_t primary_pin = 1;
+ uint8_t backup_pin = 2;
+ uint8_t bad_pin = 3;
AddPin(&transport_security_state_, "mail.example.org", primary_pin,
backup_pin);
@@ -223,16 +290,19 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
- session_.OnProofVerifyDetailsAvailable(details);
CompleteCryptoHandshake();
- QuicChromiumClientSessionPeer::SetChannelIDSent(&session_, true);
+ session_->OnProofVerifyDetailsAvailable(details);
+ QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
+ QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
- EXPECT_FALSE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
+ EXPECT_FALSE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
}
TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
- uint8 primary_pin = 1;
- uint8 backup_pin = 2;
+ Initialize();
+
+ uint8_t primary_pin = 1;
+ uint8_t backup_pin = 2;
AddPin(&transport_security_state_, "mail.example.org", primary_pin,
backup_pin);
@@ -245,11 +315,209 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
- session_.OnProofVerifyDetailsAvailable(details);
CompleteCryptoHandshake();
- QuicChromiumClientSessionPeer::SetChannelIDSent(&session_, true);
+ session_->OnProofVerifyDetailsAvailable(details);
+ QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
+ QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
+
+ EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
+}
+
+TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
+ Initialize();
+ CompleteCryptoHandshake();
+
+ char data[] = "ABCD";
+ scoped_ptr<QuicEncryptedPacket> ping(
+ maker_.MakePingPacket(1, /*include_version=*/false));
+ scoped_ptr<QuicEncryptedPacket> ack_and_data_out(maker_.MakeAckAndDataPacket(
+ 2, false, 5, 1, 1, false, 0, StringPiece(data)));
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ping->data(), ping->length(), 0),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
+ MockWrite writes[] = {MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 2),
+ MockWrite(SYNCHRONOUS, ack_and_data_out->data(),
+ ack_and_data_out->length(), 3)};
+ StaticSocketDataProvider socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create connected socket.
+ scoped_ptr<DatagramClientSocket> new_socket =
+ socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
+ base::Bind(&base::RandInt),
+ &net_log_, NetLog::Source());
+ EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
+
+ // Create reader and writer.
+ scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader(
+ new_socket.get(), &clock_, session_.get(), kQuicYieldAfterPacketsRead,
+ QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
+ bound_net_log_.bound()));
+ scoped_ptr<QuicPacketWriter> new_writer(
+ CreateQuicPacketWriter(new_socket.get(), session_->connection()));
+
+ // Migrate session.
+ EXPECT_TRUE(session_->MigrateToSocket(
+ std::move(new_socket), std::move(new_reader), std::move(new_writer)));
+
+ // Write data to session.
+ struct iovec iov[1];
+ iov[0].iov_base = data;
+ iov[0].iov_len = 4;
+ session_->WritevData(5, QuicIOVector(iov, arraysize(iov), 4), 0, false,
+ MAY_FEC_PROTECT, nullptr);
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
+ Initialize();
+ CompleteCryptoHandshake();
+
+ for (size_t i = 0; i < kMaxReadersPerQuicSession; ++i) {
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
+ scoped_ptr<QuicEncryptedPacket> ping_out(
+ maker_.MakePingPacket(i + 1, /*include_version=*/true));
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, ping_out->data(), ping_out->length(), i + 2)};
+ StaticSocketDataProvider socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create connected socket.
+ scoped_ptr<DatagramClientSocket> new_socket =
+ socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
+ base::Bind(&base::RandInt),
+ &net_log_, NetLog::Source());
+ EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
+
+ // Create reader and writer.
+ scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader(
+ new_socket.get(), &clock_, session_.get(), kQuicYieldAfterPacketsRead,
+ QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
+ bound_net_log_.bound()));
+ scoped_ptr<QuicPacketWriter> new_writer(
+ CreateQuicPacketWriter(new_socket.get(), session_->connection()));
+
+ // Migrate session.
+ if (i < kMaxReadersPerQuicSession - 1) {
+ EXPECT_TRUE(session_->MigrateToSocket(
+ std::move(new_socket), std::move(new_reader), std::move(new_writer)));
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ } else {
+ // Max readers exceeded.
+ EXPECT_FALSE(session_->MigrateToSocket(
+ std::move(new_socket), std::move(new_reader), std::move(new_writer)));
+
+ EXPECT_FALSE(socket_data.AllReadDataConsumed());
+ EXPECT_FALSE(socket_data.AllWriteDataConsumed());
+ }
+ }
+}
+
+TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
+ scoped_ptr<QuicEncryptedPacket> ping(
+ maker_.MakePingPacket(1, /*include_version=*/true));
+ MockRead old_reads[] = {
+ MockRead(SYNCHRONOUS, ping->data(), ping->length(), 0),
+ MockRead(ASYNC, ERR_IO_PENDING, 1), // causes reading to pause.
+ MockRead(ASYNC, ERR_NETWORK_CHANGED, 2)};
+ socket_data_.reset(
+ new SequencedSocketData(old_reads, arraysize(old_reads), nullptr, 0));
+ Initialize();
+ CompleteCryptoHandshake();
+
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 1)};
+ MockRead new_reads[] = {
+ MockRead(SYNCHRONOUS, ping->data(), ping->length(), 0),
+ MockRead(ASYNC, ERR_IO_PENDING, 2), // pause reading.
+ MockRead(ASYNC, ping->data(), ping->length(), 3),
+ MockRead(ASYNC, ERR_IO_PENDING, 4), // pause reading
+ MockRead(ASYNC, ERR_NETWORK_CHANGED, 5)};
+ SequencedSocketData new_socket_data(new_reads, arraysize(new_reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&new_socket_data);
+
+ // Create connected socket.
+ scoped_ptr<DatagramClientSocket> new_socket =
+ socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
+ base::Bind(&base::RandInt),
+ &net_log_, NetLog::Source());
+ EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
+
+ // Create reader and writer.
+ scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader(
+ new_socket.get(), &clock_, session_.get(), kQuicYieldAfterPacketsRead,
+ QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
+ bound_net_log_.bound()));
+ scoped_ptr<QuicPacketWriter> new_writer(
+ CreateQuicPacketWriter(new_socket.get(), session_->connection()));
+
+ // Store old socket and migrate session.
+ EXPECT_TRUE(session_->MigrateToSocket(
+ std::move(new_socket), std::move(new_reader), std::move(new_writer)));
+
+ // Read error on old socket does not impact session.
+ EXPECT_TRUE(socket_data_->IsPaused());
+ socket_data_->Resume();
+ EXPECT_TRUE(session_->connection()->connected());
+ EXPECT_TRUE(new_socket_data.IsPaused());
+ new_socket_data.Resume();
+
+ // Read error on new socket causes session close.
+ EXPECT_TRUE(new_socket_data.IsPaused());
+ EXPECT_TRUE(session_->connection()->connected());
+ new_socket_data.Resume();
+ EXPECT_FALSE(session_->connection()->connected());
+
+ EXPECT_TRUE(socket_data_->AllReadDataConsumed());
+ EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
+ EXPECT_TRUE(new_socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(new_socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicChromiumClientSessionTest, MigrateToSocketWriteError) {
+ Initialize();
+ CompleteCryptoHandshake();
- EXPECT_TRUE(session_.CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
+ scoped_ptr<QuicEncryptedPacket> ping(
+ maker_.MakePingPacket(1, /*include_version=*/true));
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ MockWrite writes[] = {MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 1),
+ MockWrite(SYNCHRONOUS, ERR_FAILED, 2)};
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create connected socket.
+ scoped_ptr<DatagramClientSocket> new_socket =
+ socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
+ base::Bind(&base::RandInt),
+ &net_log_, NetLog::Source());
+ EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
+
+ // Create reader and writer.
+ scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader(
+ new_socket.get(), &clock_, session_.get(), kQuicYieldAfterPacketsRead,
+ QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
+ bound_net_log_.bound()));
+ scoped_ptr<QuicPacketWriter> new_writer(
+ CreateQuicPacketWriter(new_socket.get(), session_->connection()));
+
+ // Migrate session.
+ EXPECT_TRUE(session_->MigrateToSocket(
+ std::move(new_socket), std::move(new_reader), std::move(new_writer)));
+
+ // Write error on new socket causes session close.
+ EXPECT_TRUE(session_->connection()->connected());
+ session_->connection()->SendPing();
+ EXPECT_FALSE(session_->connection()->connected());
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
} // namespace
diff --git a/chromium/net/quic/quic_reliable_client_stream.cc b/chromium/net/quic/quic_chromium_client_stream.cc
index f5000b29bb9..2c558e55369 100644
--- a/chromium/net/quic/quic_reliable_client_stream.cc
+++ b/chromium/net/quic/quic_chromium_client_stream.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/quic/quic_reliable_client_stream.h"
+#include "net/quic/quic_chromium_client_stream.h"
#include "base/callback_helpers.h"
#include "base/location.h"
@@ -15,28 +15,28 @@
namespace net {
-QuicReliableClientStream::QuicReliableClientStream(QuicStreamId id,
+QuicChromiumClientStream::QuicChromiumClientStream(QuicStreamId id,
QuicSpdySession* session,
const BoundNetLog& net_log)
- : QuicDataStream(id, session),
+ : QuicSpdyStream(id, session),
net_log_(net_log),
delegate_(nullptr),
headers_delivered_(false),
weak_factory_(this) {}
-QuicReliableClientStream::~QuicReliableClientStream() {
+QuicChromiumClientStream::~QuicChromiumClientStream() {
if (delegate_)
delegate_->OnClose(connection_error());
}
-void QuicReliableClientStream::OnStreamHeadersComplete(bool fin,
+void QuicChromiumClientStream::OnStreamHeadersComplete(bool fin,
size_t frame_len) {
- QuicDataStream::OnStreamHeadersComplete(fin, frame_len);
+ QuicSpdyStream::OnStreamHeadersComplete(fin, frame_len);
// The delegate will read the headers via a posted task.
NotifyDelegateOfHeadersCompleteLater(frame_len);
}
-void QuicReliableClientStream::OnDataAvailable() {
+void QuicChromiumClientStream::OnDataAvailable() {
// TODO(rch): buffer data if we don't have a delegate.
if (!delegate_) {
DLOG(ERROR) << "Missing delegate";
@@ -54,7 +54,7 @@ void QuicReliableClientStream::OnDataAvailable() {
NotifyDelegateOfDataAvailableLater();
}
-void QuicReliableClientStream::OnClose() {
+void QuicChromiumClientStream::OnClose() {
if (delegate_) {
delegate_->OnClose(connection_error());
delegate_ = nullptr;
@@ -62,7 +62,7 @@ void QuicReliableClientStream::OnClose() {
ReliableQuicStream::OnClose();
}
-void QuicReliableClientStream::OnCanWrite() {
+void QuicChromiumClientStream::OnCanWrite() {
ReliableQuicStream::OnCanWrite();
if (!HasBufferedData() && !callback_.is_null()) {
@@ -70,14 +70,14 @@ void QuicReliableClientStream::OnCanWrite() {
}
}
-QuicPriority QuicReliableClientStream::EffectivePriority() const {
+SpdyPriority QuicChromiumClientStream::Priority() const {
if (delegate_ && delegate_->HasSendHeadersComplete()) {
- return QuicDataStream::EffectivePriority();
+ return QuicSpdyStream::Priority();
}
- return QuicWriteBlockedList::kHighestPriority;
+ return net::kV3HighestPriority;
}
-int QuicReliableClientStream::WriteStreamData(
+int QuicChromiumClientStream::WriteStreamData(
base::StringPiece data,
bool fin,
const CompletionCallback& callback) {
@@ -93,8 +93,8 @@ int QuicReliableClientStream::WriteStreamData(
return ERR_IO_PENDING;
}
-void QuicReliableClientStream::SetDelegate(
- QuicReliableClientStream::Delegate* delegate) {
+void QuicChromiumClientStream::SetDelegate(
+ QuicChromiumClientStream::Delegate* delegate) {
DCHECK(!(delegate_ && delegate));
delegate_ = delegate;
if (delegate == nullptr && sequencer()->IsClosed()) {
@@ -102,15 +102,15 @@ void QuicReliableClientStream::SetDelegate(
}
}
-void QuicReliableClientStream::OnError(int error) {
+void QuicChromiumClientStream::OnError(int error) {
if (delegate_) {
- QuicReliableClientStream::Delegate* delegate = delegate_;
+ QuicChromiumClientStream::Delegate* delegate = delegate_;
delegate_ = nullptr;
delegate->OnError(error);
}
}
-int QuicReliableClientStream::Read(IOBuffer* buf, int buf_len) {
+int QuicChromiumClientStream::Read(IOBuffer* buf, int buf_len) {
if (sequencer()->IsClosed())
return 0; // EOF
@@ -123,55 +123,54 @@ int QuicReliableClientStream::Read(IOBuffer* buf, int buf_len) {
return Readv(&iov, 1);
}
-bool QuicReliableClientStream::CanWrite(const CompletionCallback& callback) {
- bool can_write = session()->connection()->CanWrite(HAS_RETRANSMITTABLE_DATA);
+bool QuicChromiumClientStream::CanWrite(const CompletionCallback& callback) {
+ bool can_write = session()->connection()->CanWrite(HAS_RETRANSMITTABLE_DATA);
if (!can_write) {
- session()->MarkConnectionLevelWriteBlocked(id(), EffectivePriority());
+ session()->MarkConnectionLevelWriteBlocked(id(), Priority());
DCHECK(callback_.is_null());
callback_ = callback;
}
return can_write;
}
-void QuicReliableClientStream::NotifyDelegateOfHeadersCompleteLater(
+void QuicChromiumClientStream::NotifyDelegateOfHeadersCompleteLater(
size_t frame_len) {
DCHECK(delegate_);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&QuicReliableClientStream::NotifyDelegateOfHeadersComplete,
+ base::Bind(&QuicChromiumClientStream::NotifyDelegateOfHeadersComplete,
weak_factory_.GetWeakPtr(), frame_len));
}
-void QuicReliableClientStream::NotifyDelegateOfHeadersComplete(
+void QuicChromiumClientStream::NotifyDelegateOfHeadersComplete(
size_t frame_len) {
if (!delegate_)
return;
size_t headers_len = decompressed_headers().length();
SpdyHeaderBlock headers;
- SpdyFramer framer(SpdyUtils::GetSpdyVersionForQuicVersion(version()));
- size_t len = framer.ParseHeaderBlockInBuffer(decompressed_headers().data(),
- headers_len, &headers);
- MarkHeadersConsumed(headers_len);
- headers_delivered_ = true;
- if (len == 0 || len != headers_len) {
+ SpdyFramer framer(HTTP2);
+ if (!framer.ParseHeaderBlockInBuffer(decompressed_headers().data(),
+ headers_len, &headers)) {
DLOG(WARNING) << "Invalid headers";
Reset(QUIC_BAD_APPLICATION_PAYLOAD);
return;
}
+ MarkHeadersConsumed(headers_len);
+ headers_delivered_ = true;
delegate_->OnHeadersAvailable(headers, frame_len);
}
-void QuicReliableClientStream::NotifyDelegateOfDataAvailableLater() {
+void QuicChromiumClientStream::NotifyDelegateOfDataAvailableLater() {
DCHECK(delegate_);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&QuicReliableClientStream::NotifyDelegateOfDataAvailable,
+ base::Bind(&QuicChromiumClientStream::NotifyDelegateOfDataAvailable,
weak_factory_.GetWeakPtr()));
}
-void QuicReliableClientStream::NotifyDelegateOfDataAvailable() {
+void QuicChromiumClientStream::NotifyDelegateOfDataAvailable() {
if (delegate_)
delegate_->OnDataAvailable();
}
diff --git a/chromium/net/quic/quic_reliable_client_stream.h b/chromium/net/quic/quic_chromium_client_stream.h
index 98d2757fe63..5a8ddf55cc6 100644
--- a/chromium/net/quic/quic_reliable_client_stream.h
+++ b/chromium/net/quic/quic_chromium_client_stream.h
@@ -7,12 +7,15 @@
#ifndef NET_QUIC_QUIC_RELIABLE_CLIENT_STREAM_H_
#define NET_QUIC_QUIC_RELIABLE_CLIENT_STREAM_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "net/base/upload_data_stream.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_info.h"
#include "net/http/http_stream.h"
-#include "net/quic/quic_data_stream.h"
+#include "net/quic/quic_spdy_stream.h"
namespace net {
@@ -20,7 +23,7 @@ class QuicSpdySession;
// A client-initiated ReliableQuicStream. Instances of this class
// are owned by the QuicClientSession which created them.
-class NET_EXPORT_PRIVATE QuicReliableClientStream : public QuicDataStream {
+class NET_EXPORT_PRIVATE QuicChromiumClientStream : public QuicSpdyStream {
public:
// Delegate handles protocol specific behavior of a quic stream.
class NET_EXPORT_PRIVATE Delegate {
@@ -50,22 +53,22 @@ class NET_EXPORT_PRIVATE QuicReliableClientStream : public QuicDataStream {
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
- QuicReliableClientStream(QuicStreamId id,
+ QuicChromiumClientStream(QuicStreamId id,
QuicSpdySession* session,
const BoundNetLog& net_log);
- ~QuicReliableClientStream() override;
+ ~QuicChromiumClientStream() override;
- // QuicDataStream
+ // QuicSpdyStream
void OnStreamHeadersComplete(bool fin, size_t frame_len) override;
void OnDataAvailable() override;
void OnClose() override;
void OnCanWrite() override;
- QuicPriority EffectivePriority() const override;
+ SpdyPriority Priority() const override;
// While the server's set_priority shouldn't be called externally, the creator
// of client-side streams should be able to set the priority.
- using QuicDataStream::set_priority;
+ using QuicSpdyStream::SetPriority;
int WriteStreamData(base::StringPiece data,
bool fin,
@@ -88,7 +91,7 @@ class NET_EXPORT_PRIVATE QuicReliableClientStream : public QuicDataStream {
const BoundNetLog& net_log() const { return net_log_; }
- using QuicDataStream::HasBufferedData;
+ using QuicSpdyStream::HasBufferedData;
private:
void NotifyDelegateOfHeadersCompleteLater(size_t frame_len);
@@ -103,9 +106,9 @@ class NET_EXPORT_PRIVATE QuicReliableClientStream : public QuicDataStream {
CompletionCallback callback_;
- base::WeakPtrFactory<QuicReliableClientStream> weak_factory_;
+ base::WeakPtrFactory<QuicChromiumClientStream> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(QuicReliableClientStream);
+ DISALLOW_COPY_AND_ASSIGN(QuicChromiumClientStream);
};
} // namespace net
diff --git a/chromium/net/quic/quic_reliable_client_stream_test.cc b/chromium/net/quic/quic_chromium_client_stream_test.cc
index 043e4d3bc30..b8ea0527930 100644
--- a/chromium/net/quic/quic_reliable_client_stream_test.cc
+++ b/chromium/net/quic/quic_chromium_client_stream_test.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/quic/quic_reliable_client_stream.h"
+#include "net/quic/quic_chromium_client_stream.h"
+#include "base/macros.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_utils.h"
#include "net/quic/spdy_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gmock_mutant.h"
@@ -26,7 +28,7 @@ namespace {
const QuicStreamId kTestStreamId = 5u;
-class MockDelegate : public QuicReliableClientStream::Delegate {
+class MockDelegate : public QuicChromiumClientStream::Delegate {
public:
MockDelegate() {}
@@ -43,14 +45,16 @@ class MockDelegate : public QuicReliableClientStream::Delegate {
DISALLOW_COPY_AND_ASSIGN(MockDelegate);
};
-class QuicReliableClientStreamTest
+class QuicChromiumClientStreamTest
: public ::testing::TestWithParam<QuicVersion> {
public:
- QuicReliableClientStreamTest()
- : session_(new MockConnection(Perspective::IS_CLIENT,
+ QuicChromiumClientStreamTest()
+ : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
+ session_(new MockConnection(&helper_,
+ Perspective::IS_CLIENT,
SupportedVersions(GetParam()))) {
stream_ =
- new QuicReliableClientStream(kTestStreamId, &session_, BoundNetLog());
+ new QuicChromiumClientStream(kTestStreamId, &session_, BoundNetLog());
session_.ActivateStream(stream_);
stream_->SetDelegate(&delegate_);
}
@@ -93,20 +97,22 @@ class QuicReliableClientStreamTest
StringPiece(buffer->data(), expected_data.length()));
}
+ QuicCryptoClientConfig crypto_config_;
testing::StrictMock<MockDelegate> delegate_;
+ MockConnectionHelper helper_;
MockQuicSpdySession session_;
- QuicReliableClientStream* stream_;
- QuicCryptoClientConfig crypto_config_;
+ QuicChromiumClientStream* stream_;
SpdyHeaderBlock headers_;
};
-INSTANTIATE_TEST_CASE_P(Version, QuicReliableClientStreamTest,
+INSTANTIATE_TEST_CASE_P(Version,
+ QuicChromiumClientStreamTest,
::testing::ValuesIn(QuicSupportedVersions()));
-TEST_P(QuicReliableClientStreamTest, OnFinRead) {
+TEST_P(QuicChromiumClientStreamTest, OnFinRead) {
InitializeHeaders();
std::string uncompressed_headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
QuicStreamOffset offset = 0;
stream_->OnStreamHeaders(uncompressed_headers);
stream_->OnStreamHeadersComplete(false, uncompressed_headers.length());
@@ -121,17 +127,17 @@ TEST_P(QuicReliableClientStreamTest, OnFinRead) {
stream_->OnStreamFrame(frame2);
}
-TEST_P(QuicReliableClientStreamTest, OnDataAvailableBeforeHeaders) {
+TEST_P(QuicChromiumClientStreamTest, OnDataAvailableBeforeHeaders) {
EXPECT_CALL(delegate_, OnClose(QUIC_NO_ERROR));
EXPECT_CALL(delegate_, OnDataAvailable()).Times(0);
stream_->OnDataAvailable();
}
-TEST_P(QuicReliableClientStreamTest, OnDataAvailable) {
+TEST_P(QuicChromiumClientStreamTest, OnDataAvailable) {
InitializeHeaders();
std::string uncompressed_headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
stream_->OnStreamHeaders(uncompressed_headers);
stream_->OnStreamHeadersComplete(false, uncompressed_headers.length());
@@ -146,14 +152,14 @@ TEST_P(QuicReliableClientStreamTest, OnDataAvailable) {
EXPECT_CALL(delegate_, OnDataAvailable())
.WillOnce(testing::Invoke(
- CreateFunctor(this, &QuicReliableClientStreamTest::ReadData,
+ CreateFunctor(this, &QuicChromiumClientStreamTest::ReadData,
StringPiece(data, arraysize(data) - 1))));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_CALL(delegate_, OnClose(QUIC_NO_ERROR));
}
-TEST_P(QuicReliableClientStreamTest, ProcessHeadersWithError) {
+TEST_P(QuicChromiumClientStreamTest, ProcessHeadersWithError) {
std::string bad_headers = "...";
stream_->OnStreamHeaders(StringPiece(bad_headers));
stream_->OnStreamHeadersComplete(false, bad_headers.length());
@@ -165,10 +171,10 @@ TEST_P(QuicReliableClientStreamTest, ProcessHeadersWithError) {
EXPECT_CALL(delegate_, OnClose(QUIC_NO_ERROR));
}
-TEST_P(QuicReliableClientStreamTest, OnDataAvailableWithError) {
+TEST_P(QuicChromiumClientStreamTest, OnDataAvailableWithError) {
InitializeHeaders();
std::string uncompressed_headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
stream_->OnStreamHeaders(uncompressed_headers);
stream_->OnStreamHeadersComplete(false, uncompressed_headers.length());
@@ -182,34 +188,34 @@ TEST_P(QuicReliableClientStreamTest, OnDataAvailableWithError) {
/*offset=*/0, data));
EXPECT_CALL(delegate_, OnDataAvailable())
.WillOnce(testing::Invoke(CreateFunctor(
- stream_, &QuicReliableClientStream::Reset, QUIC_STREAM_CANCELLED)));
+ stream_, &QuicChromiumClientStream::Reset, QUIC_STREAM_CANCELLED)));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_CALL(delegate_, OnClose(QUIC_NO_ERROR));
}
-TEST_P(QuicReliableClientStreamTest, OnError) {
+TEST_P(QuicChromiumClientStreamTest, OnError) {
EXPECT_CALL(delegate_, OnError(ERR_INTERNET_DISCONNECTED));
stream_->OnError(ERR_INTERNET_DISCONNECTED);
EXPECT_FALSE(stream_->GetDelegate());
}
-TEST_P(QuicReliableClientStreamTest, WriteStreamData) {
+TEST_P(QuicChromiumClientStreamTest, WriteStreamData) {
EXPECT_CALL(delegate_, OnClose(QUIC_NO_ERROR));
const char kData1[] = "hello world";
const size_t kDataLen = arraysize(kData1);
// All data written.
- EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _)).WillOnce(
- Return(QuicConsumedData(kDataLen, true)));
+ EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen, true)));
TestCompletionCallback callback;
EXPECT_EQ(OK, stream_->WriteStreamData(base::StringPiece(kData1, kDataLen),
true, callback.callback()));
}
-TEST_P(QuicReliableClientStreamTest, WriteStreamDataAsync) {
+TEST_P(QuicChromiumClientStreamTest, WriteStreamDataAsync) {
EXPECT_CALL(delegate_, HasSendHeadersComplete()).Times(AnyNumber());
EXPECT_CALL(delegate_, OnClose(QUIC_NO_ERROR));
@@ -217,17 +223,17 @@ TEST_P(QuicReliableClientStreamTest, WriteStreamDataAsync) {
const size_t kDataLen = arraysize(kData1);
// No data written.
- EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _)).WillOnce(
- Return(QuicConsumedData(0, false)));
+ EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(0, false)));
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- stream_->WriteStreamData(base::StringPiece(kData1, kDataLen),
- true, callback.callback()));
+ stream_->WriteStreamData(base::StringPiece(kData1, kDataLen), true,
+ callback.callback()));
ASSERT_FALSE(callback.have_result());
// All data written.
- EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _)).WillOnce(
- Return(QuicConsumedData(kDataLen, true)));
+ EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen, true)));
stream_->OnCanWrite();
ASSERT_TRUE(callback.have_result());
EXPECT_EQ(OK, callback.WaitForResult());
diff --git a/chromium/net/quic/quic_connection_helper.cc b/chromium/net/quic/quic_chromium_connection_helper.cc
index 195dfb3bdf2..68c0a105061 100644
--- a/chromium/net/quic/quic_connection_helper.cc
+++ b/chromium/net/quic/quic_chromium_connection_helper.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/quic/quic_connection_helper.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "base/location.h"
#include "base/logging.h"
@@ -43,7 +43,7 @@ class QuicChromeAlarm : public QuicAlarm {
weak_factory_.InvalidateWeakPtrs();
}
- int64 delay_us = deadline().Subtract(clock_->Now()).ToMicroseconds();
+ int64_t delay_us = deadline().Subtract(clock_->Now()).ToMicroseconds();
if (delay_us < 0) {
delay_us = 0;
}
@@ -91,28 +91,32 @@ class QuicChromeAlarm : public QuicAlarm {
} // namespace
-QuicConnectionHelper::QuicConnectionHelper(base::TaskRunner* task_runner,
- const QuicClock* clock,
- QuicRandom* random_generator)
+QuicChromiumConnectionHelper::QuicChromiumConnectionHelper(
+ base::TaskRunner* task_runner,
+ const QuicClock* clock,
+ QuicRandom* random_generator)
: task_runner_(task_runner),
clock_(clock),
random_generator_(random_generator),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
-QuicConnectionHelper::~QuicConnectionHelper() {
-}
+QuicChromiumConnectionHelper::~QuicChromiumConnectionHelper() {}
-const QuicClock* QuicConnectionHelper::GetClock() const {
+const QuicClock* QuicChromiumConnectionHelper::GetClock() const {
return clock_;
}
-QuicRandom* QuicConnectionHelper::GetRandomGenerator() {
+QuicRandom* QuicChromiumConnectionHelper::GetRandomGenerator() {
return random_generator_;
}
-QuicAlarm* QuicConnectionHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
+QuicAlarm* QuicChromiumConnectionHelper::CreateAlarm(
+ QuicAlarm::Delegate* delegate) {
return new QuicChromeAlarm(clock_, task_runner_, delegate);
}
+QuicBufferAllocator* QuicChromiumConnectionHelper::GetBufferAllocator() {
+ return &buffer_allocator_;
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_connection_helper.h b/chromium/net/quic/quic_chromium_connection_helper.h
index 140bf9aac5c..2b0464945d9 100644
--- a/chromium/net/quic/quic_connection_helper.h
+++ b/chromium/net/quic/quic_chromium_connection_helper.h
@@ -8,14 +8,14 @@
#ifndef NET_QUIC_QUIC_CONNECTION_HELPER_H_
#define NET_QUIC_QUIC_CONNECTION_HELPER_H_
-#include "net/quic/quic_connection.h"
-
#include <set>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/ip_endpoint.h"
+#include "net/quic/quic_connection.h"
#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_simple_buffer_allocator.h"
#include "net/quic/quic_time.h"
#include "net/udp/datagram_client_socket.h"
@@ -28,26 +28,28 @@ namespace net {
class QuicClock;
class QuicRandom;
-class NET_EXPORT_PRIVATE QuicConnectionHelper
+class NET_EXPORT_PRIVATE QuicChromiumConnectionHelper
: public QuicConnectionHelperInterface {
public:
- QuicConnectionHelper(base::TaskRunner* task_runner,
- const QuicClock* clock,
- QuicRandom* random_generator);
- ~QuicConnectionHelper() override;
+ QuicChromiumConnectionHelper(base::TaskRunner* task_runner,
+ const QuicClock* clock,
+ QuicRandom* random_generator);
+ ~QuicChromiumConnectionHelper() override;
// QuicConnectionHelperInterface
const QuicClock* GetClock() const override;
QuicRandom* GetRandomGenerator() override;
QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+ QuicBufferAllocator* GetBufferAllocator() override;
private:
base::TaskRunner* task_runner_;
const QuicClock* clock_;
QuicRandom* random_generator_;
- base::WeakPtrFactory<QuicConnectionHelper> weak_factory_;
+ SimpleBufferAllocator buffer_allocator_;
+ base::WeakPtrFactory<QuicChromiumConnectionHelper> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(QuicConnectionHelper);
+ DISALLOW_COPY_AND_ASSIGN(QuicChromiumConnectionHelper);
};
} // namespace net
diff --git a/chromium/net/quic/quic_connection_helper_test.cc b/chromium/net/quic/quic_chromium_connection_helper_test.cc
index f5a690750af..aefa22ac90e 100644
--- a/chromium/net/quic/quic_connection_helper_test.cc
+++ b/chromium/net/quic/quic_chromium_connection_helper_test.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/quic/quic_connection_helper.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
@@ -23,34 +23,33 @@ class TestDelegate : public QuicAlarm::Delegate {
}
bool fired() const { return fired_; }
- void Clear() { fired_= false; }
+ void Clear() { fired_ = false; }
private:
bool fired_;
};
-class QuicConnectionHelperTest : public ::testing::Test {
+class QuicChromiumConnectionHelperTest : public ::testing::Test {
protected:
- QuicConnectionHelperTest()
+ QuicChromiumConnectionHelperTest()
: runner_(new TestTaskRunner(&clock_)),
- helper_(runner_.get(), &clock_, &random_generator_) {
- }
+ helper_(runner_.get(), &clock_, &random_generator_) {}
scoped_refptr<TestTaskRunner> runner_;
- QuicConnectionHelper helper_;
+ QuicChromiumConnectionHelper helper_;
MockClock clock_;
MockRandom random_generator_;
};
-TEST_F(QuicConnectionHelperTest, GetClock) {
+TEST_F(QuicChromiumConnectionHelperTest, GetClock) {
EXPECT_EQ(&clock_, helper_.GetClock());
}
-TEST_F(QuicConnectionHelperTest, GetRandomGenerator) {
+TEST_F(QuicChromiumConnectionHelperTest, GetRandomGenerator) {
EXPECT_EQ(&random_generator_, helper_.GetRandomGenerator());
}
-TEST_F(QuicConnectionHelperTest, CreateAlarm) {
+TEST_F(QuicChromiumConnectionHelperTest, CreateAlarm) {
TestDelegate* delegate = new TestDelegate();
scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
@@ -67,7 +66,7 @@ TEST_F(QuicConnectionHelperTest, CreateAlarm) {
EXPECT_TRUE(delegate->fired());
}
-TEST_F(QuicConnectionHelperTest, CreateAlarmAndCancel) {
+TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndCancel) {
TestDelegate* delegate = new TestDelegate();
scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
@@ -85,7 +84,7 @@ TEST_F(QuicConnectionHelperTest, CreateAlarmAndCancel) {
EXPECT_FALSE(delegate->fired());
}
-TEST_F(QuicConnectionHelperTest, CreateAlarmAndReset) {
+TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndReset) {
TestDelegate* delegate = new TestDelegate();
scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
@@ -112,7 +111,7 @@ TEST_F(QuicConnectionHelperTest, CreateAlarmAndReset) {
EXPECT_TRUE(delegate->fired());
}
-TEST_F(QuicConnectionHelperTest, CreateAlarmAndResetEarlier) {
+TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndResetEarlier) {
TestDelegate* delegate = new TestDelegate();
scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
@@ -141,7 +140,7 @@ TEST_F(QuicConnectionHelperTest, CreateAlarmAndResetEarlier) {
EXPECT_FALSE(delegate->fired());
}
-TEST_F(QuicConnectionHelperTest, CreateAlarmAndUpdate) {
+TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndUpdate) {
TestDelegate* delegate = new TestDelegate();
scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
@@ -167,10 +166,9 @@ TEST_F(QuicConnectionHelperTest, CreateAlarmAndUpdate) {
QuicTime::Delta::FromMicroseconds(2));
ASSERT_EQ(1u, runner_->GetPostedTasks().size());
- EXPECT_EQ(
- base::TimeDelta::FromMicroseconds(
- new_delta.Subtract(delta).ToMicroseconds()),
- runner_->GetPostedTasks()[0].delay);
+ EXPECT_EQ(base::TimeDelta::FromMicroseconds(
+ new_delta.Subtract(delta).ToMicroseconds()),
+ runner_->GetPostedTasks()[0].delay);
runner_->RunNextTask();
EXPECT_EQ(start.Add(new_delta), clock->Now());
EXPECT_TRUE(delegate->fired());
diff --git a/chromium/net/quic/quic_client_session_base.cc b/chromium/net/quic/quic_client_session_base.cc
index 12173e51019..5ff7d12aa60 100644
--- a/chromium/net/quic/quic_client_session_base.cc
+++ b/chromium/net/quic/quic_client_session_base.cc
@@ -10,8 +10,7 @@ namespace net {
QuicClientSessionBase::QuicClientSessionBase(QuicConnection* connection,
const QuicConfig& config)
- : QuicSpdySession(connection, config) {
-}
+ : QuicSpdySession(connection, config) {}
QuicClientSessionBase::~QuicClientSessionBase() {}
@@ -19,8 +18,7 @@ void QuicClientSessionBase::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
QuicSession::OnCryptoHandshakeEvent(event);
// Set FEC policy for streams immediately after sending CHLO and before any
// more data is sent.
- if (!FLAGS_enable_quic_fec ||
- event != ENCRYPTION_FIRST_ESTABLISHED ||
+ if (!FLAGS_enable_quic_fec || event != ENCRYPTION_FIRST_ESTABLISHED ||
!config()->HasSendConnectionOptions() ||
!ContainsQuicTag(config()->SendConnectionOptions(), kFHDR)) {
return;
@@ -30,4 +28,35 @@ void QuicClientSessionBase::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
headers_stream()->set_fec_policy(FEC_PROTECT_ALWAYS);
}
+void QuicClientSessionBase::OnPromiseHeaders(QuicStreamId stream_id,
+ StringPiece headers_data) {
+ QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
+ if (!stream) {
+ // It's quite possible to receive headers after a stream has been reset.
+ return;
+ }
+ stream->OnPromiseHeaders(headers_data);
+}
+
+void QuicClientSessionBase::OnPromiseHeadersComplete(
+ QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len) {
+ if (promised_stream_id != kInvalidStreamId &&
+ promised_stream_id <= largest_promised_stream_id_) {
+ CloseConnectionWithDetails(QUIC_INVALID_STREAM_ID,
+ "Received push stream id lesser or equal to the"
+ " last accepted before");
+ return;
+ }
+ largest_promised_stream_id_ = promised_stream_id;
+
+ QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
+ if (!stream) {
+ // It's quite possible to receive headers after a stream has been reset.
+ return;
+ }
+ stream->OnPromiseHeadersComplete(promised_stream_id, frame_len);
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_client_session_base.h b/chromium/net/quic/quic_client_session_base.h
index 0e3c0fa3ff3..ae65ab01aa4 100644
--- a/chromium/net/quic/quic_client_session_base.h
+++ b/chromium/net/quic/quic_client_session_base.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_QUIC_CLIENT_SESSION_BASE_H_
#define NET_QUIC_QUIC_CLIENT_SESSION_BASE_H_
+#include "base/macros.h"
#include "net/quic/quic_crypto_client_stream.h"
#include "net/quic/quic_spdy_session.h"
@@ -13,16 +14,13 @@ namespace net {
// Base class for all client-specific QuicSession subclasses.
class NET_EXPORT_PRIVATE QuicClientSessionBase : public QuicSpdySession {
public:
- QuicClientSessionBase(QuicConnection* connection,
- const QuicConfig& config);
+ QuicClientSessionBase(QuicConnection* connection, const QuicConfig& config);
~QuicClientSessionBase() override;
// Called when the proof in |cached| is marked valid. If this is a secure
// QUIC session, then this will happen only after the proof verifier
- // completes. If this is an insecure QUIC connection, this will happen
- // as soon as a valid config is discovered (either from the cache or
- // from the server).
+ // completes.
virtual void OnProofValid(
const QuicCryptoClientConfig::CachedState& cached) = 0;
@@ -35,7 +33,21 @@ class NET_EXPORT_PRIVATE QuicClientSessionBase : public QuicSpdySession {
// Override base class to set FEC policy before any data is sent by client.
void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
+ // Called by |headers_stream_| when push promise headers have been
+ // received for a stream.
+ void OnPromiseHeaders(QuicStreamId stream_id,
+ StringPiece headers_data) override;
+
+ // Called by |headers_stream_| when push promise headers have been
+ // completely received. |fin| will be true if the fin flag was set
+ // in the headers.
+ void OnPromiseHeadersComplete(QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len) override;
+
private:
+ QuicStreamId largest_promised_stream_id_;
+
DISALLOW_COPY_AND_ASSIGN(QuicClientSessionBase);
};
diff --git a/chromium/net/quic/quic_clock.cc b/chromium/net/quic/quic_clock.cc
index 9d5ac6d17ab..61a271606b1 100644
--- a/chromium/net/quic/quic_clock.cc
+++ b/chromium/net/quic/quic_clock.cc
@@ -8,8 +8,7 @@
namespace net {
-QuicClock::QuicClock() {
-}
+QuicClock::QuicClock() {}
QuicClock::~QuicClock() {}
@@ -24,7 +23,8 @@ QuicTime QuicClock::Now() const {
}
QuicWallTime QuicClock::WallNow() const {
- return QuicWallTime::FromUNIXSeconds(base::Time::Now().ToTimeT());
+ return QuicWallTime::FromUNIXMicroseconds(base::Time::Now().ToJavaTime() *
+ 1000);
}
} // namespace net
diff --git a/chromium/net/quic/quic_clock.h b/chromium/net/quic/quic_clock.h
index 4e96d4c781e..4700edd2d97 100644
--- a/chromium/net/quic/quic_clock.h
+++ b/chromium/net/quic/quic_clock.h
@@ -5,7 +5,7 @@
#ifndef NET_QUIC_QUIC_CLOCK_H_
#define NET_QUIC_QUIC_CLOCK_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/quic_time.h"
diff --git a/chromium/net/quic/quic_clock_test.cc b/chromium/net/quic/quic_clock_test.cc
index 6ee4540889f..b6800611ebe 100644
--- a/chromium/net/quic/quic_clock_test.cc
+++ b/chromium/net/quic/quic_clock_test.cc
@@ -29,8 +29,8 @@ TEST(QuicClockTest, WallNow) {
// If end > start, then we can check now is between start and end.
if (end > start) {
- EXPECT_LE(static_cast<uint64>(start.ToTimeT()), now.ToUNIXSeconds());
- EXPECT_LE(now.ToUNIXSeconds(), static_cast<uint64>(end.ToTimeT()));
+ EXPECT_LE(static_cast<uint64_t>(start.ToTimeT()), now.ToUNIXSeconds());
+ EXPECT_LE(now.ToUNIXSeconds(), static_cast<uint64_t>(end.ToTimeT()));
}
}
diff --git a/chromium/net/quic/quic_config.cc b/chromium/net/quic/quic_config.cc
index d91fd7bc9ed..7dc93e5fc7c 100644
--- a/chromium/net/quic/quic_config.cc
+++ b/chromium/net/quic/quic_config.cc
@@ -22,8 +22,8 @@ namespace net {
QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
QuicTag tag,
QuicConfigPresence presence,
- uint32 default_value,
- uint32* out,
+ uint32_t default_value,
+ uint32_t* out,
string* error_details) {
DCHECK(error_details != nullptr);
QuicErrorCode error = msg.GetUint32(tag, out);
@@ -45,18 +45,13 @@ QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
return error;
}
-QuicConfigValue::QuicConfigValue(QuicTag tag,
- QuicConfigPresence presence)
- : tag_(tag),
- presence_(presence) {
-}
+QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
+ : tag_(tag), presence_(presence) {}
QuicConfigValue::~QuicConfigValue() {}
QuicNegotiableValue::QuicNegotiableValue(QuicTag tag,
QuicConfigPresence presence)
- : QuicConfigValue(tag, presence),
- negotiated_(false) {
-}
+ : QuicConfigValue(tag, presence), negotiated_(false) {}
QuicNegotiableValue::~QuicNegotiableValue() {}
QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag,
@@ -64,17 +59,16 @@ QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag,
: QuicNegotiableValue(tag, presence),
max_value_(0),
default_value_(0),
- negotiated_value_(0) {
-}
+ negotiated_value_(0) {}
QuicNegotiableUint32::~QuicNegotiableUint32() {}
-void QuicNegotiableUint32::set(uint32 max, uint32 default_value) {
+void QuicNegotiableUint32::set(uint32_t max, uint32_t default_value) {
DCHECK_LE(default_value, max);
max_value_ = max;
default_value_ = default_value;
}
-uint32 QuicNegotiableUint32::GetUint32() const {
+uint32_t QuicNegotiableUint32::GetUint32() const {
if (negotiated()) {
return negotiated_value_;
}
@@ -96,13 +90,9 @@ QuicErrorCode QuicNegotiableUint32::ProcessPeerHello(
string* error_details) {
DCHECK(!negotiated());
DCHECK(error_details != nullptr);
- uint32 value;
- QuicErrorCode error = ReadUint32(peer_hello,
- tag_,
- presence_,
- default_value_,
- &value,
- error_details);
+ uint32_t value;
+ QuicErrorCode error = ReadUint32(peer_hello, tag_, presence_, default_value_,
+ &value, error_details);
if (error != QUIC_NO_ERROR) {
return error;
}
@@ -120,8 +110,7 @@ QuicErrorCode QuicNegotiableUint32::ProcessPeerHello(
QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, QuicConfigPresence presence)
: QuicNegotiableValue(tag, presence),
negotiated_tag_(0),
- default_value_(0) {
-}
+ default_value_(0) {}
QuicNegotiableTag::~QuicNegotiableTag() {}
@@ -142,11 +131,10 @@ void QuicNegotiableTag::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
}
}
-QuicErrorCode QuicNegotiableTag::ReadVector(
- const CryptoHandshakeMessage& msg,
- const QuicTag** out,
- size_t* out_length,
- string* error_details) const {
+QuicErrorCode QuicNegotiableTag::ReadVector(const CryptoHandshakeMessage& msg,
+ const QuicTag** out,
+ size_t* out_length,
+ string* error_details) const {
DCHECK(error_details != nullptr);
QuicErrorCode error = msg.GetTaglist(tag_, out, out_length);
switch (error) {
@@ -184,19 +172,16 @@ QuicErrorCode QuicNegotiableTag::ProcessPeerHello(
if (hello_type == SERVER) {
if (received_tags_length != 1 ||
- !ContainsQuicTag(possible_values_, *received_tags)) {
+ !ContainsQuicTag(possible_values_, *received_tags)) {
*error_details = "Invalid " + QuicUtils::TagToString(tag_);
return QUIC_INVALID_NEGOTIATED_VALUE;
}
negotiated_tag_ = *received_tags;
} else {
QuicTag negotiated_tag;
- if (!QuicUtils::FindMutualTag(possible_values_,
- received_tags,
- received_tags_length,
- QuicUtils::LOCAL_PRIORITY,
- &negotiated_tag,
- nullptr)) {
+ if (!QuicUtils::FindMutualTag(
+ possible_values_, received_tags, received_tags_length,
+ QuicUtils::LOCAL_PRIORITY, &negotiated_tag, nullptr)) {
*error_details = "Unsupported " + QuicUtils::TagToString(tag_);
return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP;
}
@@ -210,21 +195,20 @@ QuicErrorCode QuicNegotiableTag::ProcessPeerHello(
QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
: QuicConfigValue(tag, presence),
has_send_value_(false),
- has_receive_value_(false) {
-}
+ has_receive_value_(false) {}
QuicFixedUint32::~QuicFixedUint32() {}
bool QuicFixedUint32::HasSendValue() const {
return has_send_value_;
}
-uint32 QuicFixedUint32::GetSendValue() const {
- LOG_IF(DFATAL, !has_send_value_)
- << "No send value to get for tag:" << QuicUtils::TagToString(tag_);
+uint32_t QuicFixedUint32::GetSendValue() const {
+ LOG_IF(DFATAL, !has_send_value_) << "No send value to get for tag:"
+ << QuicUtils::TagToString(tag_);
return send_value_;
}
-void QuicFixedUint32::SetSendValue(uint32 value) {
+void QuicFixedUint32::SetSendValue(uint32_t value) {
has_send_value_ = true;
send_value_ = value;
}
@@ -233,13 +217,13 @@ bool QuicFixedUint32::HasReceivedValue() const {
return has_receive_value_;
}
-uint32 QuicFixedUint32::GetReceivedValue() const {
- LOG_IF(DFATAL, !has_receive_value_)
- << "No receive value to get for tag:" << QuicUtils::TagToString(tag_);
+uint32_t QuicFixedUint32::GetReceivedValue() const {
+ LOG_IF(DFATAL, !has_receive_value_) << "No receive value to get for tag:"
+ << QuicUtils::TagToString(tag_);
return receive_value_;
}
-void QuicFixedUint32::SetReceivedValue(uint32 value) {
+void QuicFixedUint32::SetReceivedValue(uint32_t value) {
has_receive_value_ = true;
receive_value_ = value;
}
@@ -277,8 +261,7 @@ QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
QuicConfigPresence presence)
: QuicConfigValue(name, presence),
has_send_values_(false),
- has_receive_values_(false) {
-}
+ has_receive_values_(false) {}
QuicFixedTagVector::~QuicFixedTagVector() {}
@@ -287,8 +270,8 @@ bool QuicFixedTagVector::HasSendValues() const {
}
QuicTagVector QuicFixedTagVector::GetSendValues() const {
- LOG_IF(DFATAL, !has_send_values_)
- << "No send values to get for tag:" << QuicUtils::TagToString(tag_);
+ LOG_IF(DFATAL, !has_send_values_) << "No send values to get for tag:"
+ << QuicUtils::TagToString(tag_);
return send_values_;
}
@@ -302,8 +285,8 @@ bool QuicFixedTagVector::HasReceivedValues() const {
}
QuicTagVector QuicFixedTagVector::GetReceivedValues() const {
- LOG_IF(DFATAL, !has_receive_values_)
- << "No receive value to get for tag:" << QuicUtils::TagToString(tag_);
+ LOG_IF(DFATAL, !has_receive_values_) << "No receive value to get for tag:"
+ << QuicUtils::TagToString(tag_);
return receive_values_;
}
@@ -360,7 +343,8 @@ 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) {
+ socket_receive_buffer_(kSRBF, PRESENCE_OPTIONAL),
+ multipath_enabled_(kMPTH, PRESENCE_OPTIONAL) {
SetDefaults();
}
@@ -416,8 +400,8 @@ void QuicConfig::SetIdleConnectionStateLifetime(
QuicTime::Delta max_idle_connection_state_lifetime,
QuicTime::Delta default_idle_conection_state_lifetime) {
idle_connection_state_lifetime_seconds_.set(
- static_cast<uint32>(max_idle_connection_state_lifetime.ToSeconds()),
- static_cast<uint32>(default_idle_conection_state_lifetime.ToSeconds()));
+ static_cast<uint32_t>(max_idle_connection_state_lifetime.ToSeconds()),
+ static_cast<uint32_t>(default_idle_conection_state_lifetime.ToSeconds()));
}
QuicTime::Delta QuicConfig::IdleConnectionStateLifetime() const {
@@ -439,7 +423,7 @@ void QuicConfig::SetMaxStreamsPerConnection(size_t max_streams,
max_streams_per_connection_.set(max_streams, default_streams);
}
-uint32 QuicConfig::MaxStreamsPerConnection() const {
+uint32_t QuicConfig::MaxStreamsPerConnection() const {
return max_streams_per_connection_.GetUint32();
}
@@ -447,7 +431,7 @@ bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
return bytes_for_connection_id_.HasSendValue();
}
-void QuicConfig::SetBytesForConnectionIdToSend(uint32 bytes) {
+void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
bytes_for_connection_id_.SetSendValue(bytes);
}
@@ -455,11 +439,11 @@ bool QuicConfig::HasReceivedBytesForConnectionId() const {
return bytes_for_connection_id_.HasReceivedValue();
}
-uint32 QuicConfig::ReceivedBytesForConnectionId() const {
+uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
return bytes_for_connection_id_.GetReceivedValue();
}
-void QuicConfig::SetInitialRoundTripTimeUsToSend(uint32 rtt) {
+void QuicConfig::SetInitialRoundTripTimeUsToSend(uint32_t rtt) {
initial_round_trip_time_us_.SetSendValue(rtt);
}
@@ -467,7 +451,7 @@ bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
return initial_round_trip_time_us_.HasReceivedValue();
}
-uint32 QuicConfig::ReceivedInitialRoundTripTimeUs() const {
+uint32_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
return initial_round_trip_time_us_.GetReceivedValue();
}
@@ -475,11 +459,12 @@ bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
return initial_round_trip_time_us_.HasSendValue();
}
-uint32 QuicConfig::GetInitialRoundTripTimeUsToSend() const {
+uint32_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
return initial_round_trip_time_us_.GetSendValue();
}
-void QuicConfig::SetInitialStreamFlowControlWindowToSend(uint32 window_bytes) {
+void QuicConfig::SetInitialStreamFlowControlWindowToSend(
+ uint32_t window_bytes) {
if (window_bytes < kMinimumFlowControlSendWindow) {
LOG(DFATAL) << "Initial stream flow control receive window ("
<< window_bytes << ") cannot be set lower than default ("
@@ -489,7 +474,7 @@ void QuicConfig::SetInitialStreamFlowControlWindowToSend(uint32 window_bytes) {
initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
}
-uint32 QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
+uint32_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
return initial_stream_flow_control_window_bytes_.GetSendValue();
}
@@ -497,11 +482,12 @@ bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
return initial_stream_flow_control_window_bytes_.HasReceivedValue();
}
-uint32 QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
+uint32_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
return initial_stream_flow_control_window_bytes_.GetReceivedValue();
}
-void QuicConfig::SetInitialSessionFlowControlWindowToSend(uint32 window_bytes) {
+void QuicConfig::SetInitialSessionFlowControlWindowToSend(
+ uint32_t window_bytes) {
if (window_bytes < kMinimumFlowControlSendWindow) {
LOG(DFATAL) << "Initial session flow control receive window ("
<< window_bytes << ") cannot be set lower than default ("
@@ -511,7 +497,7 @@ void QuicConfig::SetInitialSessionFlowControlWindowToSend(uint32 window_bytes) {
initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
}
-uint32 QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
+uint32_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
return initial_session_flow_control_window_bytes_.GetSendValue();
}
@@ -519,11 +505,11 @@ bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
return initial_session_flow_control_window_bytes_.HasReceivedValue();
}
-uint32 QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
+uint32_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
return initial_session_flow_control_window_bytes_.GetReceivedValue();
}
-void QuicConfig::SetSocketReceiveBufferToSend(uint32 tcp_receive_window) {
+void QuicConfig::SetSocketReceiveBufferToSend(uint32_t tcp_receive_window) {
socket_receive_buffer_.SetSendValue(tcp_receive_window);
}
@@ -531,10 +517,19 @@ bool QuicConfig::HasReceivedSocketReceiveBuffer() const {
return socket_receive_buffer_.HasReceivedValue();
}
-uint32 QuicConfig::ReceivedSocketReceiveBuffer() const {
+uint32_t QuicConfig::ReceivedSocketReceiveBuffer() const {
return socket_receive_buffer_.GetReceivedValue();
}
+void QuicConfig::SetMultipathEnabled(bool multipath_enabled) {
+ uint32_t value = multipath_enabled ? 1 : 0;
+ multipath_enabled_.set(value, value);
+}
+
+bool QuicConfig::MultipathEnabled() const {
+ return multipath_enabled_.GetUint32() > 0;
+}
+
bool QuicConfig::negotiated() const {
// TODO(ianswett): Add the negotiated parameters once and iterate over all
// of them in negotiated, ToHandshakeMessage, ProcessClientHello, and
@@ -587,16 +582,16 @@ QuicErrorCode QuicConfig::ProcessPeerHello(
silent_close_.ProcessPeerHello(peer_hello, hello_type, error_details);
}
if (error == QUIC_NO_ERROR) {
- error = max_streams_per_connection_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
+ error = max_streams_per_connection_.ProcessPeerHello(peer_hello, hello_type,
+ error_details);
}
if (error == QUIC_NO_ERROR) {
- error = bytes_for_connection_id_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
+ error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
+ error_details);
}
if (error == QUIC_NO_ERROR) {
- error = initial_round_trip_time_us_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
+ error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
+ error_details);
}
if (error == QUIC_NO_ERROR) {
error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
@@ -607,12 +602,12 @@ QuicErrorCode QuicConfig::ProcessPeerHello(
peer_hello, hello_type, error_details);
}
if (error == QUIC_NO_ERROR) {
- error = socket_receive_buffer_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
+ error = socket_receive_buffer_.ProcessPeerHello(peer_hello, hello_type,
+ error_details);
}
if (error == QUIC_NO_ERROR) {
- error = connection_options_.ProcessPeerHello(
- peer_hello, hello_type, error_details);
+ error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
+ error_details);
}
return error;
}
diff --git a/chromium/net/quic/quic_config.h b/chromium/net/quic/quic_config.h
index 755aa3922ca..1fbb4b73ceb 100644
--- a/chromium/net/quic/quic_config.h
+++ b/chromium/net/quic/quic_config.h
@@ -5,9 +5,11 @@
#ifndef NET_QUIC_QUIC_CONFIG_H_
#define NET_QUIC_QUIC_CONFIG_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
@@ -63,9 +65,7 @@ class NET_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue {
QuicNegotiableValue(QuicTag tag, QuicConfigPresence presence);
~QuicNegotiableValue() override;
- bool negotiated() const {
- return negotiated_;
- }
+ bool negotiated() const { return negotiated_; }
protected:
void set_negotiated(bool negotiated) { negotiated_ = negotiated; }
@@ -75,6 +75,8 @@ class NET_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue {
};
class NET_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue {
+ // TODO(fayang): some negotiated values use uint32 as bool (e.g., silent
+ // close). Consider adding a QuicNegotiableBool type.
public:
// Default and max values default to 0.
QuicNegotiableUint32(QuicTag name, QuicConfigPresence presence);
@@ -84,11 +86,11 @@ class NET_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue {
// also the default values to be assumed if PRESENCE_OPTIONAL and the *HLO msg
// doesn't contain a value corresponding to |name_|. |max| is serialised via
// ToHandshakeMessage call if |negotiated_| is false.
- void set(uint32 max, uint32 default_value);
+ void set(uint32_t max, uint32_t default_value);
// Returns the value negotiated if |negotiated_| is true, otherwise returns
// default_value_ (used to set default values before negotiation finishes).
- uint32 GetUint32() const;
+ uint32_t GetUint32() const;
// Serialises |name_| and value to |out|. If |negotiated_| is true then
// |negotiated_value_| is serialised, otherwise |max_value_| is serialised.
@@ -103,9 +105,9 @@ class NET_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue {
std::string* error_details) override;
private:
- uint32 max_value_;
- uint32 default_value_;
- uint32 negotiated_value_;
+ uint32_t max_value_;
+ uint32_t default_value_;
+ uint32_t negotiated_value_;
};
class NET_EXPORT_PRIVATE QuicNegotiableTag : public QuicNegotiableValue {
@@ -144,7 +146,7 @@ class NET_EXPORT_PRIVATE QuicNegotiableTag : public QuicNegotiableValue {
QuicTag default_value_;
};
-// Stores uint32 from CHLO or SHLO messages that are not negotiated.
+// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
class NET_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
public:
QuicFixedUint32(QuicTag name, QuicConfigPresence presence);
@@ -152,15 +154,15 @@ class NET_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
bool HasSendValue() const;
- uint32 GetSendValue() const;
+ uint32_t GetSendValue() const;
- void SetSendValue(uint32 value);
+ void SetSendValue(uint32_t value);
bool HasReceivedValue() const;
- uint32 GetReceivedValue() const;
+ uint32_t GetReceivedValue() const;
- void SetReceivedValue(uint32 value);
+ void SetReceivedValue(uint32_t value);
// If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
@@ -171,9 +173,9 @@ class NET_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
std::string* error_details) override;
private:
- uint32 send_value_;
+ uint32_t send_value_;
bool has_send_value_;
- uint32 receive_value_;
+ uint32_t receive_value_;
bool has_receive_value_;
};
@@ -253,7 +255,7 @@ class NET_EXPORT_PRIVATE QuicConfig {
void SetMaxStreamsPerConnection(size_t max_streams, size_t default_streams);
- uint32 MaxStreamsPerConnection() const;
+ uint32_t MaxStreamsPerConnection() const;
void set_max_time_before_crypto_handshake(
QuicTime::Delta max_time_before_crypto_handshake) {
@@ -285,47 +287,51 @@ class NET_EXPORT_PRIVATE QuicConfig {
bool HasSetBytesForConnectionIdToSend() const;
// Sets the peer's connection id length, in bytes.
- void SetBytesForConnectionIdToSend(uint32 bytes);
+ void SetBytesForConnectionIdToSend(uint32_t bytes);
bool HasReceivedBytesForConnectionId() const;
- uint32 ReceivedBytesForConnectionId() const;
+ uint32_t ReceivedBytesForConnectionId() const;
// Sets an estimated initial round trip time in us.
- void SetInitialRoundTripTimeUsToSend(uint32 rtt_us);
+ void SetInitialRoundTripTimeUsToSend(uint32_t rtt_us);
bool HasReceivedInitialRoundTripTimeUs() const;
- uint32 ReceivedInitialRoundTripTimeUs() const;
+ uint32_t ReceivedInitialRoundTripTimeUs() const;
bool HasInitialRoundTripTimeUsToSend() const;
- uint32 GetInitialRoundTripTimeUsToSend() const;
+ uint32_t GetInitialRoundTripTimeUsToSend() const;
// Sets an initial stream flow control window size to transmit to the peer.
- void SetInitialStreamFlowControlWindowToSend(uint32 window_bytes);
+ void SetInitialStreamFlowControlWindowToSend(uint32_t window_bytes);
- uint32 GetInitialStreamFlowControlWindowToSend() const;
+ uint32_t GetInitialStreamFlowControlWindowToSend() const;
bool HasReceivedInitialStreamFlowControlWindowBytes() const;
- uint32 ReceivedInitialStreamFlowControlWindowBytes() const;
+ uint32_t ReceivedInitialStreamFlowControlWindowBytes() const;
// Sets an initial session flow control window size to transmit to the peer.
- void SetInitialSessionFlowControlWindowToSend(uint32 window_bytes);
+ void SetInitialSessionFlowControlWindowToSend(uint32_t window_bytes);
- uint32 GetInitialSessionFlowControlWindowToSend() const;
+ uint32_t GetInitialSessionFlowControlWindowToSend() const;
bool HasReceivedInitialSessionFlowControlWindowBytes() const;
- uint32 ReceivedInitialSessionFlowControlWindowBytes() const;
+ uint32_t ReceivedInitialSessionFlowControlWindowBytes() const;
// Sets socket receive buffer to transmit to the peer.
- void SetSocketReceiveBufferToSend(uint32 window_bytes);
+ void SetSocketReceiveBufferToSend(uint32_t window_bytes);
bool HasReceivedSocketReceiveBuffer() const;
- uint32 ReceivedSocketReceiveBuffer() const;
+ uint32_t ReceivedSocketReceiveBuffer() const;
+
+ void SetMultipathEnabled(bool multipath_enabled);
+
+ bool MultipathEnabled() const;
bool negotiated() const;
@@ -373,6 +379,9 @@ class NET_EXPORT_PRIVATE QuicConfig {
// Socket receive buffer in bytes.
QuicFixedUint32 socket_receive_buffer_;
+
+ // Whether to support multipath for this connection.
+ QuicNegotiableUint32 multipath_enabled_;
};
} // namespace net
diff --git a/chromium/net/quic/quic_config_test.cc b/chromium/net/quic/quic_config_test.cc
index 0a568c2ffef..ec1c6aa38fb 100644
--- a/chromium/net/quic/quic_config_test.cc
+++ b/chromium/net/quic/quic_config_test.cc
@@ -38,7 +38,7 @@ TEST_F(QuicConfigTest, ToHandshakeMessage) {
CryptoHandshakeMessage msg;
config_.ToHandshakeMessage(&msg);
- uint32 value;
+ uint32_t value;
QuicErrorCode error = msg.GetUint32(kICSL, &value);
EXPECT_EQ(QUIC_NO_ERROR, error);
EXPECT_EQ(5u, value);
@@ -67,8 +67,8 @@ TEST_F(QuicConfigTest, ProcessClientHello) {
client_config.SetIdleConnectionStateLifetime(
QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
- client_config.SetMaxStreamsPerConnection(
- 2 * kDefaultMaxStreamsPerConnection, kDefaultMaxStreamsPerConnection);
+ client_config.SetMaxStreamsPerConnection(2 * kDefaultMaxStreamsPerConnection,
+ kDefaultMaxStreamsPerConnection);
client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
client_config.SetInitialStreamFlowControlWindowToSend(
2 * kInitialStreamFlowControlWindowForTest);
@@ -99,8 +99,7 @@ TEST_F(QuicConfigTest, ProcessClientHello) {
EXPECT_TRUE(config_.negotiated());
EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
config_.IdleConnectionStateLifetime());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- config_.MaxStreamsPerConnection());
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection, config_.MaxStreamsPerConnection());
EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
EXPECT_TRUE(config_.HasReceivedConnectionOptions());
EXPECT_EQ(3u, config_.ReceivedConnectionOptions().size());
@@ -111,8 +110,7 @@ TEST_F(QuicConfigTest, ProcessClientHello) {
2 * kInitialStreamFlowControlWindowForTest);
EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
2 * kInitialSessionFlowControlWindowForTest);
- EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
- kDefaultSocketReceiveBuffer);
+ EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(), kDefaultSocketReceiveBuffer);
}
TEST_F(QuicConfigTest, ProcessServerHello) {
@@ -122,9 +120,8 @@ TEST_F(QuicConfigTest, ProcessServerHello) {
server_config.SetIdleConnectionStateLifetime(
QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
- server_config.SetMaxStreamsPerConnection(
- kDefaultMaxStreamsPerConnection / 2,
- kDefaultMaxStreamsPerConnection / 2);
+ server_config.SetMaxStreamsPerConnection(kDefaultMaxStreamsPerConnection / 2,
+ kDefaultMaxStreamsPerConnection / 2);
server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
server_config.SetInitialStreamFlowControlWindowToSend(
2 * kInitialStreamFlowControlWindowForTest);
@@ -147,8 +144,7 @@ TEST_F(QuicConfigTest, ProcessServerHello) {
2 * kInitialStreamFlowControlWindowForTest);
EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
2 * kInitialSessionFlowControlWindowForTest);
- EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
- kDefaultSocketReceiveBuffer);
+ EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(), kDefaultSocketReceiveBuffer);
}
TEST_F(QuicConfigTest, MissingOptionalValuesInCHLO) {
@@ -220,7 +216,7 @@ TEST_F(QuicConfigTest, InvalidFlowControlWindow) {
// QuicConfig should not accept an invalid flow control window to send to the
// peer: the receive window must be at least the default of 16 Kb.
QuicConfig config;
- const uint64 kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+ const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
EXPECT_DFATAL(config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
"Initial stream flow control receive window");
diff --git a/chromium/net/quic/quic_connection.cc b/chromium/net/quic/quic_connection.cc
index a3fa3d93313..df2efe48f22 100644
--- a/chromium/net/quic/quic_connection.cc
+++ b/chromium/net/quic/quic_connection.cc
@@ -16,8 +16,8 @@
#include "base/format_macros.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "net/base/net_errors.h"
@@ -26,6 +26,7 @@
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/proto/cached_network_parameters.pb.h"
#include "net/quic/quic_bandwidth.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_config.h"
#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_flags.h"
@@ -63,6 +64,15 @@ const size_t kMaxFecGroups = 2;
// Maximum number of acks received before sending an ack in response.
const QuicPacketCount kMaxPacketsReceivedBeforeAckSend = 20;
+// Maximum number of retransmittable packets received before sending an ack.
+const QuicPacketCount kDefaultRetransmittablePacketsBeforeAck = 2;
+// Minimum number of packets received before ack decimation is enabled.
+// This intends to avoid the beginning of slow start, when CWNDs may be
+// rapidly increasing.
+const QuicPacketCount kMinReceivedBeforeAckDecimation = 100;
+// Wait for up to 10 retransmittable packets before sending an ack.
+const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10;
+
bool Near(QuicPacketNumber a, QuicPacketNumber b) {
QuicPacketNumber delta = (a > b) ? a - b : b - a;
return delta <= kMaxPacketGap;
@@ -71,11 +81,10 @@ bool Near(QuicPacketNumber a, QuicPacketNumber b) {
// An alarm that is scheduled to send an ack if a timeout occurs.
class AckAlarm : public QuicAlarm::Delegate {
public:
- explicit AckAlarm(QuicConnection* connection)
- : connection_(connection) {
- }
+ explicit AckAlarm(QuicConnection* connection) : connection_(connection) {}
QuicTime OnAlarm() override {
+ DCHECK(connection_->ack_frame_updated());
connection_->SendAck();
return QuicTime::Zero();
}
@@ -92,8 +101,7 @@ class AckAlarm : public QuicAlarm::Delegate {
class RetransmissionAlarm : public QuicAlarm::Delegate {
public:
explicit RetransmissionAlarm(QuicConnection* connection)
- : connection_(connection) {
- }
+ : connection_(connection) {}
QuicTime OnAlarm() override {
connection_->OnRetransmissionTimeout();
@@ -110,9 +118,7 @@ class RetransmissionAlarm : public QuicAlarm::Delegate {
// before sending packets and fires when the packet may be sent.
class SendAlarm : public QuicAlarm::Delegate {
public:
- explicit SendAlarm(QuicConnection* connection)
- : connection_(connection) {
- }
+ explicit SendAlarm(QuicConnection* connection) : connection_(connection) {}
QuicTime OnAlarm() override {
connection_->WriteIfNotBlocked();
@@ -128,9 +134,7 @@ class SendAlarm : public QuicAlarm::Delegate {
class TimeoutAlarm : public QuicAlarm::Delegate {
public:
- explicit TimeoutAlarm(QuicConnection* connection)
- : connection_(connection) {
- }
+ explicit TimeoutAlarm(QuicConnection* connection) : connection_(connection) {}
QuicTime OnAlarm() override {
connection_->CheckForTimeout();
@@ -146,12 +150,10 @@ class TimeoutAlarm : public QuicAlarm::Delegate {
class PingAlarm : public QuicAlarm::Delegate {
public:
- explicit PingAlarm(QuicConnection* connection)
- : connection_(connection) {
- }
+ explicit PingAlarm(QuicConnection* connection) : connection_(connection) {}
QuicTime OnAlarm() override {
- connection_->SendPing();
+ connection_->OnPingTimeout();
return QuicTime::Zero();
}
@@ -197,25 +199,30 @@ class FecAlarm : public QuicAlarm::Delegate {
// Listens for acks of MTU discovery packets and raises the maximum packet size
// of the connection if the probe succeeds.
-class MtuDiscoveryAckListener : public QuicAckNotifier::DelegateInterface {
+class MtuDiscoveryAckListener : public QuicAckListenerInterface {
public:
MtuDiscoveryAckListener(QuicConnection* connection, QuicByteCount probe_size)
: connection_(connection), probe_size_(probe_size) {}
- void OnAckNotification(int /*num_retransmittable_packets*/,
- int /*num_retransmittable_bytes*/,
- QuicTime::Delta /*delta_largest_observed*/) override {
- // Since the probe was successful, increase the maximum packet size to that.
- if (probe_size_ > connection_->max_packet_length()) {
- connection_->SetMaxPacketLength(probe_size_);
- }
+ void OnPacketAcked(int /*acked_bytes*/,
+ QuicTime::Delta /*delta_largest_observed*/) override {
+ // MTU discovery packets are not retransmittable, so it must be acked.
+ MaybeIncreaseMtu();
}
+ void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
+
protected:
// MtuDiscoveryAckListener is ref counted.
~MtuDiscoveryAckListener() override {}
private:
+ void MaybeIncreaseMtu() {
+ if (probe_size_ > connection_->max_packet_length()) {
+ connection_->SetMaxPacketLength(probe_size_);
+ }
+ }
+
QuicConnection* connection_;
QuicByteCount probe_size_;
@@ -224,39 +231,21 @@ class MtuDiscoveryAckListener : public QuicAckNotifier::DelegateInterface {
} // namespace
-QuicConnection::QueuedPacket::QueuedPacket(SerializedPacket packet,
- EncryptionLevel level)
- : serialized_packet(packet),
- encryption_level(level),
- transmission_type(NOT_RETRANSMISSION),
- original_packet_number(0) {}
-
-QuicConnection::QueuedPacket::QueuedPacket(
- SerializedPacket packet,
- EncryptionLevel level,
- TransmissionType transmission_type,
- QuicPacketNumber original_packet_number)
- : serialized_packet(packet),
- encryption_level(level),
- transmission_type(transmission_type),
- original_packet_number(original_packet_number) {}
-
#define ENDPOINT \
(perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
QuicConnection::QuicConnection(QuicConnectionId connection_id,
IPEndPoint address,
QuicConnectionHelperInterface* helper,
- const PacketWriterFactory& writer_factory,
+ QuicPacketWriter* writer,
bool owns_writer,
Perspective perspective,
- bool is_secure,
const QuicVersionVector& supported_versions)
: framer_(supported_versions,
helper->GetClock()->ApproximateNow(),
perspective),
helper_(helper),
- writer_(writer_factory.Create(this)),
+ writer_(writer),
owns_writer_(owns_writer),
encryption_level_(ENCRYPTION_NONE),
has_forward_secure_encrypter_(false),
@@ -275,11 +264,14 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
largest_seen_packet_with_stop_waiting_(0),
max_undecryptable_packets_(0),
pending_version_negotiation_packet_(false),
+ save_crypto_packets_as_termination_packets_(false),
silent_close_enabled_(false),
received_packet_manager_(&stats_),
ack_queued_(false),
+ num_retransmittable_packets_received_since_last_ack_sent_(0),
num_packets_received_since_last_ack_sent_(0),
stop_waiting_count_(0),
+ ack_decimation_enabled_(false),
delay_setting_retransmission_alarm_(false),
pending_retransmission_alarm_(false),
ack_alarm_(helper->CreateAlarm(new AckAlarm(this))),
@@ -291,20 +283,25 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
mtu_discovery_alarm_(helper->CreateAlarm(new MtuDiscoveryAlarm(this))),
visitor_(nullptr),
debug_visitor_(nullptr),
- packet_generator_(connection_id_, &framer_, random_generator_, this),
+ packet_generator_(connection_id_,
+ &framer_,
+ random_generator_,
+ helper->GetBufferAllocator(),
+ this),
fec_alarm_(helper->CreateAlarm(new FecAlarm(&packet_generator_))),
idle_network_timeout_(QuicTime::Delta::Infinite()),
overall_connection_timeout_(QuicTime::Delta::Infinite()),
time_of_last_received_packet_(clock_->ApproximateNow()),
time_of_last_sent_new_packet_(clock_->ApproximateNow()),
+ last_send_for_timeout_(clock_->ApproximateNow()),
packet_number_of_last_sent_packet_(0),
sent_packet_manager_(
perspective,
+ kDefaultPathId,
clock_,
&stats_,
FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic,
- FLAGS_quic_use_time_loss_detection ? kTime : kNack,
- is_secure),
+ FLAGS_quic_use_time_loss_detection ? kTime : kNack),
version_negotiation_state_(START_NEGOTIATION),
perspective_(perspective),
connected_(true),
@@ -313,16 +310,16 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
self_ip_changed_(false),
self_port_changed_(false),
can_truncate_connection_ids_(true),
- is_secure_(is_secure),
mtu_discovery_target_(0),
mtu_probe_count_(0),
packets_between_mtu_probes_(kPacketsBetweenMtuProbesBase),
next_mtu_probe_at_(kPacketsBetweenMtuProbesBase),
largest_received_packet_size_(0),
goaway_sent_(false),
- goaway_received_(false) {
- DVLOG(1) << ENDPOINT << "Created connection with connection_id: "
- << connection_id;
+ goaway_received_(false),
+ multipath_enabled_(false) {
+ DVLOG(1) << ENDPOINT
+ << "Created connection with connection_id: " << connection_id;
framer_.set_visitor(this);
framer_.set_received_entropy_calculator(&received_packet_manager_);
last_stop_waiting_frame_.least_unacked = 0;
@@ -340,6 +337,9 @@ QuicConnection::~QuicConnection() {
delete writer_;
}
STLDeleteElements(&undecryptable_packets_);
+ if (termination_packets_.get() != nullptr) {
+ STLDeleteElements(termination_packets_.get());
+ }
STLDeleteValues(&group_map_);
ClearQueuedPackets();
}
@@ -347,8 +347,8 @@ QuicConnection::~QuicConnection() {
void QuicConnection::ClearQueuedPackets() {
for (QueuedPacketList::iterator it = queued_packets_.begin();
it != queued_packets_.end(); ++it) {
- delete it->serialized_packet.retransmittable_frames;
- delete it->serialized_packet.packet;
+ delete it->retransmittable_frames;
+ delete it->packet;
}
queued_packets_.clear();
}
@@ -360,6 +360,9 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
if (config.SilentClose()) {
silent_close_enabled_ = true;
}
+ if (FLAGS_quic_enable_multipath && config.MultipathEnabled()) {
+ multipath_enabled_ = true;
+ }
} else {
SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
config.max_idle_time_before_crypto_handshake());
@@ -389,6 +392,13 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
if (config.HasClientSentConnectionOption(kMTUL, perspective_)) {
SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
}
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnSetFromConfig(config);
+ }
+ if (FLAGS_quic_ack_decimation &&
+ config.HasClientSentConnectionOption(kACKD, perspective_)) {
+ ack_decimation_enabled_ = true;
+ }
}
void QuicConnection::OnSendConnectionState(
@@ -420,8 +430,7 @@ bool QuicConnection::SelectMutualVersion(
const QuicVersionVector& supported_versions = framer_.supported_versions();
for (size_t i = 0; i < supported_versions.size(); ++i) {
const QuicVersion& version = supported_versions[i];
- if (std::find(available_versions.begin(), available_versions.end(),
- version) != available_versions.end()) {
+ if (ContainsValue(available_versions, version)) {
framer_.set_version(version);
return true;
}
@@ -548,9 +557,7 @@ void QuicConnection::OnVersionNegotiationPacket(
return;
}
- if (std::find(packet.versions.begin(),
- packet.versions.end(), version()) !=
- packet.versions.end()) {
+ if (ContainsValue(packet.versions, version())) {
DLOG(WARNING) << ENDPOINT << "The server already supports our version. "
<< "It should have accepted our connection.";
// Just drop the connection.
@@ -571,8 +578,7 @@ void QuicConnection::OnVersionNegotiationPacket(
RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
}
-void QuicConnection::OnRevivedPacket() {
-}
+void QuicConnection::OnRevivedPacket() {}
bool QuicConnection::OnUnauthenticatedPublicHeader(
const QuicPacketPublicHeader& header) {
@@ -602,6 +608,20 @@ bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
// routed to this QuicConnection has been redirected before control reaches
// here.
DCHECK_EQ(connection_id_, header.public_header.connection_id);
+
+ // If this packet has already been seen, or the sender has told us that it
+ // will not be retransmitted, then stop processing the packet.
+ if (FLAGS_quic_drop_non_awaited_packets &&
+ !received_packet_manager_.IsAwaitingPacket(header.packet_number)) {
+ DVLOG(1) << ENDPOINT << "Packet " << header.packet_number
+ << " no longer being waited for. Discarding.";
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnDuplicatePacket(header.packet_number);
+ }
+ ++stats_.packets_dropped;
+ return false;
+ }
+
return true;
}
@@ -621,65 +641,13 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
debug_visitor_->OnPacketHeader(header);
}
- if (!ProcessValidatedPacket()) {
- return false;
- }
-
// Will be decremented below if we fall through to return true.
++stats_.packets_dropped;
- if (!Near(header.packet_packet_number, last_header_.packet_packet_number)) {
- DVLOG(1) << ENDPOINT << "Packet " << header.packet_packet_number
- << " out of bounds. Discarding";
- SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER,
- "packet number out of bounds");
+ if (!ProcessValidatedPacket(header)) {
return false;
}
- // If this packet has already been seen, or the sender has told us that it
- // will not be retransmitted, then stop processing the packet.
- if (!received_packet_manager_.IsAwaitingPacket(header.packet_packet_number)) {
- DVLOG(1) << ENDPOINT << "Packet " << header.packet_packet_number
- << " no longer being waited for. Discarding.";
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnDuplicatePacket(header.packet_packet_number);
- }
- return false;
- }
-
- if (version_negotiation_state_ != NEGOTIATED_VERSION) {
- if (perspective_ == Perspective::IS_SERVER) {
- if (!header.public_header.version_flag) {
- DLOG(WARNING) << ENDPOINT << "Packet " << header.packet_packet_number
- << " without version flag before version negotiated.";
- // Packets should have the version flag till version negotiation is
- // done.
- CloseConnection(QUIC_INVALID_VERSION, false);
- return false;
- } else {
- DCHECK_EQ(1u, header.public_header.versions.size());
- DCHECK_EQ(header.public_header.versions[0], version());
- version_negotiation_state_ = NEGOTIATED_VERSION;
- visitor_->OnSuccessfulVersionNegotiation(version());
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSuccessfulVersionNegotiation(version());
- }
- }
- } else {
- DCHECK(!header.public_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());
- }
- }
- }
-
- DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_);
-
--stats_.packets_dropped;
DVLOG(1) << ENDPOINT << "Received packet header: " << header;
last_header_ = header;
@@ -705,11 +673,12 @@ bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
last_decrypted_packet_level_ == ENCRYPTION_NONE) {
DLOG(WARNING) << ENDPOINT
<< "Received an unencrypted data frame: closing connection";
- SendConnectionClose(QUIC_UNENCRYPTED_STREAM_DATA);
+ SendConnectionCloseWithDetails(QUIC_UNENCRYPTED_STREAM_DATA,
+ "Unencrypted stream data seen");
return false;
}
visitor_->OnStreamFrame(frame);
- stats_.stream_bytes_received += frame.data.size();
+ stats_.stream_bytes_received += frame.frame_length;
should_last_packet_instigate_acks_ = true;
return connected_;
}
@@ -721,16 +690,20 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
}
DVLOG(1) << ENDPOINT << "OnAckFrame: " << incoming_ack;
- if (last_header_.packet_packet_number <= largest_seen_packet_with_ack_) {
+ if (last_header_.packet_number <= largest_seen_packet_with_ack_) {
DVLOG(1) << ENDPOINT << "Received an old ack frame: ignoring";
return true;
}
- if (!ValidateAckFrame(incoming_ack)) {
- SendConnectionClose(QUIC_INVALID_ACK_DATA);
+ const char* error = ValidateAckFrame(incoming_ack);
+ if (error != nullptr) {
+ SendConnectionCloseWithDetails(QUIC_INVALID_ACK_DATA, error);
return false;
}
+ if (FLAGS_quic_respect_send_alarm2 && send_alarm_->IsSet()) {
+ send_alarm_->Cancel();
+ }
ProcessAckFrame(incoming_ack);
if (incoming_ack.is_truncated) {
should_last_packet_instigate_acks_ = true;
@@ -748,7 +721,7 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
}
void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) {
- largest_seen_packet_with_ack_ = last_header_.packet_packet_number;
+ largest_seen_packet_with_ack_ = last_header_.packet_number;
sent_packet_manager_.OnIncomingAck(incoming_ack,
time_of_last_received_packet_);
sent_entropy_manager_.ClearEntropyBefore(
@@ -761,7 +734,7 @@ void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) {
void QuicConnection::ProcessStopWaitingFrame(
const QuicStopWaitingFrame& stop_waiting) {
- largest_seen_packet_with_stop_waiting_ = last_header_.packet_packet_number;
+ largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
received_packet_manager_.UpdatePacketInformationSentByPeer(stop_waiting);
// Possibly close any FecGroups which are now irrelevant.
CloseFecGroupsBefore(stop_waiting.least_unacked + 1);
@@ -770,14 +743,14 @@ void QuicConnection::ProcessStopWaitingFrame(
bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
DCHECK(connected_);
- if (last_header_.packet_packet_number <=
- largest_seen_packet_with_stop_waiting_) {
+ if (last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
DVLOG(1) << ENDPOINT << "Received an old stop waiting frame: ignoring";
return true;
}
- if (!ValidateStopWaitingFrame(frame)) {
- SendConnectionClose(QUIC_INVALID_STOP_WAITING_DATA);
+ const char* error = ValidateStopWaitingFrame(frame);
+ if (error != nullptr) {
+ SendConnectionCloseWithDetails(QUIC_INVALID_STOP_WAITING_DATA, error);
return false;
}
@@ -798,62 +771,61 @@ bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
return true;
}
-bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
+const char* QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
if (incoming_ack.largest_observed > packet_generator_.packet_number()) {
- DLOG(ERROR) << ENDPOINT << "Peer's observed unsent packet:"
- << incoming_ack.largest_observed << " vs "
- << packet_generator_.packet_number();
+ LOG(WARNING) << ENDPOINT << "Peer's observed unsent packet:"
+ << incoming_ack.largest_observed << " vs "
+ << packet_generator_.packet_number();
// We got an error for data we have not sent. Error out.
- return false;
+ return "Largest observed too high";
}
if (incoming_ack.largest_observed < sent_packet_manager_.largest_observed()) {
- DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:"
- << incoming_ack.largest_observed << " vs "
- << sent_packet_manager_.largest_observed();
+ LOG(WARNING) << ENDPOINT << "Peer's largest_observed packet decreased:"
+ << incoming_ack.largest_observed << " vs "
+ << sent_packet_manager_.largest_observed();
// A new ack has a diminished largest_observed value. Error out.
// If this was an old packet, we wouldn't even have checked.
- return false;
+ return "Largest observed too low";
}
if (!incoming_ack.missing_packets.Empty() &&
incoming_ack.missing_packets.Max() > incoming_ack.largest_observed) {
- DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
- << incoming_ack.missing_packets.Max()
- << " which is greater than largest observed: "
- << incoming_ack.largest_observed;
- return false;
+ LOG(WARNING) << ENDPOINT << "Peer sent missing packet: "
+ << incoming_ack.missing_packets.Max()
+ << " which is greater than largest observed: "
+ << incoming_ack.largest_observed;
+ return "Missing packet higher than largest observed";
}
if (!incoming_ack.missing_packets.Empty() &&
incoming_ack.missing_packets.Min() <
sent_packet_manager_.least_packet_awaited_by_peer()) {
- DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
- << incoming_ack.missing_packets.Min()
- << " which is smaller than least_packet_awaited_by_peer_: "
- << sent_packet_manager_.least_packet_awaited_by_peer();
- return false;
+ LOG(WARNING) << ENDPOINT << "Peer sent missing packet: "
+ << incoming_ack.missing_packets.Min()
+ << " which is smaller than least_packet_awaited_by_peer_: "
+ << sent_packet_manager_.least_packet_awaited_by_peer();
+ return "Missing packet smaller than least awaited";
}
- if (!sent_entropy_manager_.IsValidEntropy(
- incoming_ack.largest_observed,
- incoming_ack.missing_packets,
- incoming_ack.entropy_hash)) {
- DLOG(ERROR) << ENDPOINT << "Peer sent invalid entropy.";
- return false;
+ if (!sent_entropy_manager_.IsValidEntropy(incoming_ack.largest_observed,
+ incoming_ack.missing_packets,
+ incoming_ack.entropy_hash)) {
+ LOG(WARNING) << ENDPOINT << "Peer sent invalid entropy.";
+ return "Invalid entropy";
}
- for (QuicPacketNumber revived_packet : incoming_ack.revived_packets) {
- if (!incoming_ack.missing_packets.Contains(revived_packet)) {
- DLOG(ERROR) << ENDPOINT
- << "Peer specified revived packet which was not missing.";
- return false;
- }
+ if (incoming_ack.latest_revived_packet != 0 &&
+ !incoming_ack.missing_packets.Contains(
+ incoming_ack.latest_revived_packet)) {
+ LOG(WARNING) << ENDPOINT
+ << "Peer specified revived packet which was not missing.";
+ return "Invalid revived packet";
}
- return true;
+ return nullptr;
}
-bool QuicConnection::ValidateStopWaitingFrame(
+const char* QuicConnection::ValidateStopWaitingFrame(
const QuicStopWaitingFrame& stop_waiting) {
if (stop_waiting.least_unacked <
received_packet_manager_.peer_least_packet_awaiting_ack()) {
@@ -861,27 +833,26 @@ bool QuicConnection::ValidateStopWaitingFrame(
<< stop_waiting.least_unacked << " vs "
<< received_packet_manager_.peer_least_packet_awaiting_ack();
// We never process old ack frames, so this number should only increase.
- return false;
+ return "Least unacked too small";
}
- if (stop_waiting.least_unacked > last_header_.packet_packet_number) {
+ if (stop_waiting.least_unacked > last_header_.packet_number) {
DLOG(ERROR) << ENDPOINT
<< "Peer sent least_unacked:" << stop_waiting.least_unacked
<< " greater than the enclosing packet number:"
- << last_header_.packet_packet_number;
- return false;
+ << last_header_.packet_number;
+ return "Least unacked too large";
}
- return true;
+ return nullptr;
}
-void QuicConnection::OnFecData(const QuicFecData& fec) {
+void QuicConnection::OnFecData(StringPiece redundancy) {
DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group);
DCHECK_NE(0u, last_header_.fec_group);
QuicFecGroup* group = GetFecGroup();
if (group != nullptr) {
- group->UpdateFec(last_decrypted_packet_level_,
- last_header_.packet_packet_number, fec);
+ group->UpdateFec(last_decrypted_packet_level_, last_header_, redundancy);
}
}
@@ -962,28 +933,26 @@ void QuicConnection::OnPacketComplete() {
}
DVLOG(1) << ENDPOINT << (last_packet_revived_ ? "Revived" : "Got")
- << " packet " << last_header_.packet_packet_number << "for "
+ << " packet " << last_header_.packet_number << " for "
<< last_header_.public_header.connection_id;
- ++num_packets_received_since_last_ack_sent_;
-
- // Call MaybeQueueAck() before recording the received packet, since we want
- // to trigger an ack if the newly received packet was previously missing.
- MaybeQueueAck();
+ // An ack will be sent if a missing retransmittable packet was received;
+ const bool was_missing =
+ should_last_packet_instigate_acks_ &&
+ received_packet_manager_.IsMissing(last_header_.packet_number);
// Record received or revived packet to populate ack info correctly before
// processing stream frames, since the processing may result in a response
// packet with a bundled ack.
if (last_packet_revived_) {
- received_packet_manager_.RecordPacketRevived(
- last_header_.packet_packet_number);
+ received_packet_manager_.RecordPacketRevived(last_header_.packet_number);
} else {
received_packet_manager_.RecordPacketReceived(
last_size_, last_header_, time_of_last_received_packet_);
}
- // Continue to process stop waiting frames later, because the packet needs
- // to be considered 'received' before the entropy can be updated.
+ // Process stop waiting frames here, instead of inline, because the packet
+ // needs to be considered 'received' before the entropy can be updated.
if (last_stop_waiting_frame_.least_unacked > 0) {
ProcessStopWaitingFrame(last_stop_waiting_frame_);
if (!connected_) {
@@ -991,33 +960,59 @@ void QuicConnection::OnPacketComplete() {
}
}
- // If there are new missing packets to report, send an ack immediately.
- if (ShouldLastPacketInstigateAck() &&
- received_packet_manager_.HasNewMissingPackets()) {
- ack_queued_ = true;
- ack_alarm_->Cancel();
- }
+ MaybeQueueAck(was_missing);
ClearLastFrames();
MaybeCloseIfTooManyOutstandingPackets();
+ MaybeProcessRevivedPacket();
}
-void QuicConnection::MaybeQueueAck() {
- // If the last packet is an ack, don't ack it.
- if (!ShouldLastPacketInstigateAck()) {
- return;
+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
+ // information from the SentPacketManager and provide an RTT measurement.
+ if (num_packets_received_since_last_ack_sent_ >=
+ kMaxPacketsReceivedBeforeAckSend) {
+ ack_queued_ = true;
}
- // If the incoming packet was missing, send an ack immediately.
- ack_queued_ =
- received_packet_manager_.IsMissing(last_header_.packet_packet_number);
- if (!ack_queued_) {
- if (ack_alarm_->IsSet()) {
- ack_queued_ = true;
+ // Determine whether the newly received packet was missing before recording
+ // the received packet.
+ if (was_missing) {
+ ack_queued_ = true;
+ }
+
+ if (should_last_packet_instigate_acks_ && !ack_queued_) {
+ ++num_retransmittable_packets_received_since_last_ack_sent_;
+ if (ack_decimation_enabled_ &&
+ last_header_.packet_number > kMinReceivedBeforeAckDecimation) {
+ // Ack up to 10 packets at once.
+ if (num_retransmittable_packets_received_since_last_ack_sent_ >=
+ kMaxRetransmittablePacketsBeforeAck) {
+ ack_queued_ = true;
+ } else if (!ack_alarm_->IsSet()) {
+ // Wait the minimum of a quarter min_rtt and the delayed ack time.
+ QuicTime::Delta ack_delay = QuicTime::Delta::Min(
+ sent_packet_manager_.DelayedAckTime(),
+ sent_packet_manager_.GetRttStats()->min_rtt().Multiply(0.25));
+ ack_alarm_->Set(clock_->ApproximateNow().Add(ack_delay));
+ }
} else {
- ack_alarm_->Set(
- clock_->ApproximateNow().Add(sent_packet_manager_.DelayedAckTime()));
- DVLOG(1) << "Ack timer set; next packet or timer will trigger ACK.";
+ // Ack with a timer or every 2 packets by default.
+ if (num_retransmittable_packets_received_since_last_ack_sent_ >=
+ kDefaultRetransmittablePacketsBeforeAck) {
+ ack_queued_ = true;
+ } else if (!ack_alarm_->IsSet()) {
+ ack_alarm_->Set(clock_->ApproximateNow().Add(
+ sent_packet_manager_.DelayedAckTime()));
+ }
+ }
+
+ // If there are new missing packets to report, send an ack immediately.
+ // TODO(ianswett): Consider allowing 1ms of reordering for the
+ // ack decimation experiment.
+ if (received_packet_manager_.HasNewMissingPackets()) {
+ ack_queued_ = true;
}
}
@@ -1035,7 +1030,7 @@ void QuicConnection::MaybeCloseIfTooManyOutstandingPackets() {
// This occurs if we don't discard old packets we've sent fast enough.
// It's possible largest observed is less than least unacked.
if (sent_packet_manager_.largest_observed() >
- (sent_packet_manager_.GetLeastUnacked() + kMaxTrackedPackets)) {
+ (sent_packet_manager_.GetLeastUnacked() + kMaxTrackedPackets)) {
SendConnectionCloseWithDetails(
QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
StringPrintf("More than %" PRIu64 " outstanding.", kMaxTrackedPackets));
@@ -1061,19 +1056,6 @@ void QuicConnection::PopulateStopWaitingFrame(
stop_waiting->least_unacked - 1);
}
-bool QuicConnection::ShouldLastPacketInstigateAck() const {
- if (should_last_packet_instigate_acks_) {
- return true;
- }
- // Always send an ack every 20 packets in order to allow the peer to discard
- // information from the SentPacketManager and provide an RTT measurement.
- if (num_packets_received_since_last_ack_sent_ >=
- kMaxPacketsReceivedBeforeAckSend) {
- return true;
- }
- return false;
-}
-
QuicPacketNumber QuicConnection::GetLeastUnacked() const {
return sent_packet_manager_.GetLeastUnacked();
}
@@ -1101,13 +1083,12 @@ void QuicConnection::SendVersionNegotiationPacket() {
scoped_ptr<QuicEncryptedPacket> version_packet(
packet_generator_.SerializeVersionNegotiationPacket(
framer_.supported_versions()));
- WriteResult result = writer_->WritePacket(
- version_packet->data(), version_packet->length(),
- self_address().address(), peer_address());
+ WriteResult result =
+ writer_->WritePacket(version_packet->data(), version_packet->length(),
+ self_address().address(), peer_address());
if (result.status == WRITE_STATUS_ERROR) {
- // We can't send an error as the socket is presumably borked.
- CloseConnection(QUIC_PACKET_WRITE_ERROR, false);
+ OnWriteError(result.error_code);
return;
}
if (result.status == WRITE_STATUS_BLOCKED) {
@@ -1123,19 +1104,13 @@ void QuicConnection::SendVersionNegotiationPacket() {
QuicConsumedData QuicConnection::SendStreamData(
QuicStreamId id,
- const QuicIOVector& iov,
+ QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* listener) {
if (!fin && iov.total_length == 0) {
- LOG(DFATAL) << "Attempt to send empty stream frame";
- return QuicConsumedData(0, false);
- }
- if (FLAGS_quic_never_write_unencrypted_data && id != kCryptoStreamId &&
- encryption_level_ == ENCRYPTION_NONE) {
- LOG(DFATAL) << "Cannot send stream data without encryption.";
- CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA, false);
+ QUIC_BUG << "Attempt to send empty stream frame";
return QuicConsumedData(0, false);
}
@@ -1155,7 +1130,7 @@ QuicConsumedData QuicConnection::SendStreamData(
ScopedRetransmissionScheduler alarm_delayer(this);
ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK);
return packet_generator_.ConsumeData(id, iov, offset, fin, fec_protection,
- delegate);
+ listener);
}
void QuicConnection::SendRstStream(QuicStreamId id,
@@ -1166,12 +1141,18 @@ void QuicConnection::SendRstStream(QuicStreamId id,
packet_generator_.AddControlFrame(QuicFrame(new QuicRstStreamFrame(
id, AdjustErrorForVersion(error, version()), bytes_written)));
+ if (error == QUIC_STREAM_NO_ERROR && version() > QUIC_VERSION_28) {
+ // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
+ // be received by the peer.
+ return;
+ }
+
sent_packet_manager_.CancelRetransmissionsForStream(id);
// Remove all queued packets which only contain data for the reset stream.
QueuedPacketList::iterator packet_iterator = queued_packets_.begin();
while (packet_iterator != queued_packets_.end()) {
RetransmittableFrames* retransmittable_frames =
- packet_iterator->serialized_packet.retransmittable_frames;
+ packet_iterator->retransmittable_frames;
if (!retransmittable_frames) {
++packet_iterator;
continue;
@@ -1181,10 +1162,10 @@ void QuicConnection::SendRstStream(QuicStreamId id,
++packet_iterator;
continue;
}
- delete packet_iterator->serialized_packet.retransmittable_frames;
- delete packet_iterator->serialized_packet.packet;
- packet_iterator->serialized_packet.retransmittable_frames = nullptr;
- packet_iterator->serialized_packet.packet = nullptr;
+ delete packet_iterator->retransmittable_frames;
+ delete packet_iterator->packet;
+ packet_iterator->retransmittable_frames = nullptr;
+ packet_iterator->packet = nullptr;
packet_iterator = queued_packets_.erase(packet_iterator);
}
}
@@ -1233,10 +1214,6 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
if (!connected_) {
return;
}
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/462789 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "462789 QuicConnection::ProcessUdpPacket"));
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
}
@@ -1260,19 +1237,18 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
}
}
DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: "
- << last_header_.packet_packet_number;
+ << last_header_.packet_number;
return;
}
++stats_.packets_processed;
MaybeProcessUndecryptablePackets();
- MaybeProcessRevivedPacket();
MaybeSendInResponseToPacket();
SetPingAlarm();
}
-void QuicConnection::CheckForAddressMigration(
- const IPEndPoint& self_address, const IPEndPoint& peer_address) {
+void QuicConnection::CheckForAddressMigration(const IPEndPoint& self_address,
+ const IPEndPoint& peer_address) {
peer_ip_changed_ = false;
peer_port_changed_ = false;
self_ip_changed_ = false;
@@ -1322,15 +1298,14 @@ void QuicConnection::OnCanWrite() {
return;
}
- { // Limit the scope of the bundler. ACK inclusion happens elsewhere.
+ { // Limit the scope of the bundler. ACK inclusion happens elsewhere.
ScopedPacketBundler bundler(this, NO_ACK);
visitor_->OnCanWrite();
}
// After the visitor writes, it may have caused the socket to become write
// blocked or the congestion manager to prohibit sending, so check again.
- if (visitor_->WillingAndAbleToWrite() &&
- !resume_writes_alarm_->IsSet() &&
+ if (visitor_->WillingAndAbleToWrite() && !resume_writes_alarm_->IsSet() &&
CanWrite(HAS_RETRANSMITTABLE_DATA)) {
// We're not write blocked, but some stream didn't write out all of its
// bytes. Register for 'immediate' resumption so we'll keep writing after
@@ -1345,13 +1320,78 @@ void QuicConnection::WriteIfNotBlocked() {
}
}
-bool QuicConnection::ProcessValidatedPacket() {
+bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
if (self_ip_changed_ || self_port_changed_) {
SendConnectionCloseWithDetails(QUIC_ERROR_MIGRATING_ADDRESS,
"Self address migration is not supported.");
return false;
}
+ PeerAddressChangeType type = NO_CHANGE;
+ if (peer_ip_changed_ || peer_port_changed_) {
+ type = DeterminePeerAddressChangeType();
+ if (type != NO_CHANGE && type != UNKNOWN &&
+ (FLAGS_quic_disable_non_nat_address_migration &&
+ type != NAT_PORT_REBINDING && type != IPV4_SUBNET_REBINDING)) {
+ SendConnectionCloseWithDetails(QUIC_ERROR_MIGRATING_ADDRESS,
+ "Invalid peer address migration.");
+ return false;
+ }
+ }
+
+ if (!Near(header.packet_number, last_header_.packet_number)) {
+ DVLOG(1) << ENDPOINT << "Packet " << header.packet_number
+ << " out of bounds. Discarding";
+ SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER,
+ "packet number out of bounds");
+ return false;
+ }
+
+ // If this packet has already been seen, or the sender has told us that it
+ // will not be retransmitted, then stop processing the packet.
+ if (!FLAGS_quic_drop_non_awaited_packets &&
+ !received_packet_manager_.IsAwaitingPacket(header.packet_number)) {
+ DVLOG(1) << ENDPOINT << "Packet " << header.packet_number
+ << " no longer being waited for. Discarding.";
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnDuplicatePacket(header.packet_number);
+ }
+ return false;
+ }
+
+ if (version_negotiation_state_ != NEGOTIATED_VERSION) {
+ if (perspective_ == Perspective::IS_SERVER) {
+ if (!header.public_header.version_flag) {
+ DLOG(WARNING) << ENDPOINT << "Packet " << header.packet_number
+ << " without version flag before version negotiated.";
+ // Packets should have the version flag till version negotiation is
+ // done.
+ CloseConnection(QUIC_INVALID_VERSION, false);
+ return false;
+ } else {
+ DCHECK_EQ(1u, header.public_header.versions.size());
+ DCHECK_EQ(header.public_header.versions[0], version());
+ version_negotiation_state_ = NEGOTIATED_VERSION;
+ visitor_->OnSuccessfulVersionNegotiation(version());
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnSuccessfulVersionNegotiation(version());
+ }
+ }
+ } else {
+ DCHECK(!header.public_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());
+ }
+ }
+ }
+
+ DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_);
+
if (peer_ip_changed_ || peer_port_changed_) {
IPEndPoint old_peer_address = peer_address_;
peer_address_ = IPEndPoint(
@@ -1362,9 +1402,9 @@ bool QuicConnection::ProcessValidatedPacket() {
<< old_peer_address.ToString() << " to "
<< peer_address_.ToString() << ", migrating connection.";
- if (FLAGS_send_goaway_after_client_migration) {
- visitor_->OnConnectionMigration();
- }
+ visitor_->OnConnectionMigration();
+ DCHECK_NE(type, NO_CHANGE);
+ sent_packet_manager_.OnConnectionMigration(type);
}
time_of_last_received_packet_ = clock_->Now();
@@ -1417,20 +1457,22 @@ void QuicConnection::WritePendingRetransmissions() {
packet_generator_.FlushAllQueuedFrames();
char buffer[kMaxPacketSize];
SerializedPacket serialized_packet = packet_generator_.ReserializeAllFrames(
- pending.retransmittable_frames, pending.packet_number_length, buffer,
- kMaxPacketSize);
+ pending.retransmittable_frames, pending.encryption_level,
+ pending.packet_number_length, buffer, kMaxPacketSize);
if (serialized_packet.packet == nullptr) {
// We failed to serialize the packet, so close the connection.
// CloseConnection does not send close packet, so no infinite loop here.
+ // TODO(ianswett): This is actually an internal error, not an encryption
+ // failure.
CloseConnection(QUIC_ENCRYPTION_FAILURE, false);
return;
}
DVLOG(1) << ENDPOINT << "Retransmitting " << pending.packet_number << " as "
<< serialized_packet.packet_number;
- SendOrQueuePacket(QueuedPacket(
- serialized_packet, pending.retransmittable_frames.encryption_level(),
- pending.transmission_type, pending.packet_number));
+ serialized_packet.original_packet_number = pending.packet_number;
+ serialized_packet.transmission_type = pending.transmission_type;
+ SendOrQueuePacket(&serialized_packet);
}
}
@@ -1469,9 +1511,22 @@ bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
return false;
}
+ if (FLAGS_quic_respect_send_alarm2) {
+ // Allow acks to be sent immediately.
+ // TODO(ianswett): Remove retransmittable from
+ // SendAlgorithmInterface::TimeUntilSend.
+ if (retransmittable == NO_RETRANSMITTABLE_DATA) {
+ return true;
+ }
+ // If the send alarm is set, wait for it to fire.
+ if (send_alarm_->IsSet()) {
+ return false;
+ }
+ }
+
QuicTime now = clock_->Now();
- QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend(
- now, retransmittable);
+ QuicTime::Delta delay =
+ sent_packet_manager_.TimeUntilSend(now, retransmittable);
if (delay.IsInfinite()) {
send_alarm_->Cancel();
return false;
@@ -1484,28 +1539,27 @@ bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
<< "ms";
return false;
}
- send_alarm_->Cancel();
+ if (!FLAGS_quic_respect_send_alarm2) {
+ send_alarm_->Cancel();
+ }
return true;
}
-bool QuicConnection::WritePacket(QueuedPacket* packet) {
+bool QuicConnection::WritePacket(SerializedPacket* packet) {
if (!WritePacketInner(packet)) {
return false;
}
- delete packet->serialized_packet.retransmittable_frames;
- delete packet->serialized_packet.packet;
- packet->serialized_packet.retransmittable_frames = nullptr;
- packet->serialized_packet.packet = nullptr;
+ delete packet->retransmittable_frames;
+ delete packet->packet;
+ packet->retransmittable_frames = nullptr;
+ packet->packet = nullptr;
return true;
}
-bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
- if (FLAGS_quic_close_connection_out_of_order_sending &&
- packet->serialized_packet.packet_number <
- sent_packet_manager_.largest_sent_packet()) {
- LOG(DFATAL) << "Attempt to write packet:"
- << packet->serialized_packet.packet_number
- << " after:" << sent_packet_manager_.largest_sent_packet();
+bool QuicConnection::WritePacketInner(SerializedPacket* packet) {
+ if (packet->packet_number < sent_packet_manager_.largest_sent_packet()) {
+ QUIC_BUG << "Attempt to write packet:" << packet->packet_number
+ << " after:" << sent_packet_manager_.largest_sent_packet();
SendConnectionCloseWithDetails(QUIC_INTERNAL_ERROR,
"Packet written out of order.");
return true;
@@ -1514,23 +1568,25 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
++stats_.packets_discarded;
return true;
}
- // Connection close packets are encrypted and saved, so don't exit early.
- const bool is_connection_close = IsConnectionClose(*packet);
- if (writer_->IsWriteBlocked() && !is_connection_close) {
+ // Termination packets are encrypted and saved, so don't exit early.
+ const bool is_termination_packet = IsTerminationPacket(*packet);
+ if (writer_->IsWriteBlocked() && !is_termination_packet) {
return false;
}
- QuicPacketNumber packet_number = packet->serialized_packet.packet_number;
+ QuicPacketNumber packet_number = packet->packet_number;
DCHECK_LE(packet_number_of_last_sent_packet_, packet_number);
packet_number_of_last_sent_packet_ = packet_number;
- QuicEncryptedPacket* encrypted = packet->serialized_packet.packet;
- // Connection close packets are eventually owned by TimeWaitListManager.
+ QuicEncryptedPacket* encrypted = packet->packet;
+ // Termination packets are eventually owned by TimeWaitListManager.
// Others are deleted at the end of this call.
- if (is_connection_close) {
- DCHECK(connection_close_packet_.get() == nullptr);
+ if (is_termination_packet) {
+ if (termination_packets_.get() == nullptr) {
+ termination_packets_.reset(new std::vector<QuicEncryptedPacket*>);
+ }
// Clone the packet so it's owned in the future.
- connection_close_packet_.reset(encrypted->Clone());
+ termination_packets_->push_back(encrypted->Clone());
// This assures we won't try to write *forced* packets when blocked.
// Return true to stop processing.
if (writer_->IsWriteBlocked()) {
@@ -1539,12 +1595,10 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
}
}
- if (!FLAGS_quic_allow_oversized_packets_for_test) {
- DCHECK_LE(encrypted->length(), kMaxPacketSize);
- }
+ DCHECK_LE(encrypted->length(), kMaxPacketSize);
DCHECK_LE(encrypted->length(), packet_generator_.GetMaxPacketLength());
DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
- << (packet->serialized_packet.is_fec_packet
+ << (packet->is_fec_packet
? "FEC "
: (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
? "data bearing "
@@ -1559,10 +1613,9 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
// min_rtt_, especially in cases where the thread blocks or gets swapped out
// during the WritePacket below.
QuicTime packet_send_time = clock_->Now();
- WriteResult result = writer_->WritePacket(encrypted->data(),
- encrypted->length(),
- self_address().address(),
- peer_address());
+ WriteResult result =
+ writer_->WritePacket(encrypted->data(), encrypted->length(),
+ self_address().address(), peer_address());
if (result.error_code == ERR_IO_PENDING) {
DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status);
}
@@ -1579,13 +1632,16 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
}
if (result.status != WRITE_STATUS_ERROR && debug_visitor_ != nullptr) {
// Pass the write result to the visitor.
- debug_visitor_->OnPacketSent(
- packet->serialized_packet, packet->original_packet_number,
- packet->encryption_level, packet->transmission_type, *encrypted,
- packet_send_time);
+ debug_visitor_->OnPacketSent(*packet, packet->original_packet_number,
+ packet->transmission_type, encrypted->length(),
+ packet_send_time);
}
if (packet->transmission_type == NOT_RETRANSMISSION) {
time_of_last_sent_new_packet_ = packet_send_time;
+ if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA &&
+ last_send_for_timeout_ <= time_of_last_received_packet_) {
+ last_send_for_timeout_ = packet_send_time;
+ }
}
SetPingAlarm();
MaybeSetFecAlarm(packet_number);
@@ -1601,8 +1657,8 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent(
- &packet->serialized_packet, packet->original_packet_number,
- packet_send_time, encrypted->length(), packet->transmission_type,
+ packet, packet->original_packet_number, packet_send_time,
+ encrypted->length(), packet->transmission_type,
IsRetransmittable(*packet));
if (reset_retransmission_alarm || !retransmission_alarm_->IsSet()) {
@@ -1620,7 +1676,9 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
OnWriteError(result.error_code);
DLOG(ERROR) << ENDPOINT << "failed writing " << encrypted->length()
<< " bytes "
- << " from host " << self_address().ToStringWithoutPort()
+ << " from host " << (self_address().address().empty()
+ ? " empty address "
+ : self_address().ToStringWithoutPort())
<< " to address " << peer_address().ToString();
return false;
}
@@ -1628,14 +1686,13 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
return true;
}
-bool QuicConnection::ShouldDiscardPacket(const QueuedPacket& packet) {
+bool QuicConnection::ShouldDiscardPacket(const SerializedPacket& packet) {
if (!connected_) {
- DVLOG(1) << ENDPOINT
- << "Not sending packet as connection is disconnected.";
+ DVLOG(1) << ENDPOINT << "Not sending packet as connection is disconnected.";
return true;
}
- QuicPacketNumber packet_number = packet.serialized_packet.packet_number;
+ QuicPacketNumber packet_number = packet.packet_number;
if (encryption_level_ == ENCRYPTION_FORWARD_SECURE &&
packet.encryption_level == ENCRYPTION_NONE) {
// Drop packets that are NULL encrypted since the peer won't accept them
@@ -1660,26 +1717,27 @@ bool QuicConnection::ShouldDiscardPacket(const QueuedPacket& packet) {
}
void QuicConnection::OnWriteError(int error_code) {
- DVLOG(1) << ENDPOINT << "Write failed with error: " << error_code
- << " (" << ErrorToString(error_code) << ")";
+ DVLOG(1) << ENDPOINT << "Write failed with error: " << error_code << " ("
+ << ErrorToString(error_code) << ")";
// We can't send an error as the socket is presumably borked.
CloseConnection(QUIC_PACKET_WRITE_ERROR, false);
}
-void QuicConnection::OnSerializedPacket(
- const SerializedPacket& serialized_packet) {
- if (serialized_packet.packet == nullptr) {
+void QuicConnection::OnSerializedPacket(SerializedPacket* serialized_packet) {
+ DCHECK_NE(kInvalidPathId, serialized_packet->path_id);
+ if (serialized_packet->packet == nullptr) {
// We failed to serialize the packet, so close the connection.
// CloseConnection does not send close packet, so no infinite loop here.
+ // TODO(ianswett): This is actually an internal error, not an encryption
+ // failure.
CloseConnection(QUIC_ENCRYPTION_FAILURE, false);
return;
}
- sent_packet_manager_.OnSerializedPacket(serialized_packet);
- if (serialized_packet.is_fec_packet && fec_alarm_->IsSet()) {
+ if (serialized_packet->is_fec_packet && fec_alarm_->IsSet()) {
// If an FEC packet is serialized with the FEC alarm set, cancel the alarm.
fec_alarm_->Cancel();
}
- SendOrQueuePacket(QueuedPacket(serialized_packet, encryption_level_));
+ SendOrQueuePacket(serialized_packet);
}
void QuicConnection::OnResetFecGroup() {
@@ -1712,34 +1770,31 @@ void QuicConnection::OnHandshakeComplete() {
sent_packet_manager_.SetHandshakeConfirmed();
// The client should immediately ack the SHLO to confirm the handshake is
// complete with the server.
- if (perspective_ == Perspective::IS_CLIENT && !ack_queued_) {
+ if (perspective_ == Perspective::IS_CLIENT && !ack_queued_ &&
+ ack_frame_updated()) {
ack_alarm_->Cancel();
ack_alarm_->Set(clock_->ApproximateNow());
}
}
-void QuicConnection::SendOrQueuePacket(QueuedPacket packet) {
+void QuicConnection::SendOrQueuePacket(SerializedPacket* packet) {
// The caller of this function is responsible for checking CanWrite().
- if (packet.serialized_packet.packet == nullptr) {
- LOG(DFATAL)
- << "packet.serialized_packet.packet == nullptr in to SendOrQueuePacket";
+ if (packet->packet == nullptr) {
+ QUIC_BUG << "packet.packet == nullptr in to SendOrQueuePacket";
return;
}
- sent_entropy_manager_.RecordPacketEntropyHash(
- packet.serialized_packet.packet_number,
- packet.serialized_packet.entropy_hash);
+ sent_entropy_manager_.RecordPacketEntropyHash(packet->packet_number,
+ packet->entropy_hash);
// If there are already queued packets, queue this one immediately to ensure
// it's written in sequence number order.
- if (!queued_packets_.empty() || !WritePacket(&packet)) {
+ if (!queued_packets_.empty() || !WritePacket(packet)) {
// Take ownership of the underlying encrypted packet.
- if (!packet.serialized_packet.packet->owns_buffer()) {
- scoped_ptr<QuicEncryptedPacket> encrypted_deleter(
- packet.serialized_packet.packet);
- packet.serialized_packet.packet =
- packet.serialized_packet.packet->Clone();
+ if (!packet->packet->owns_buffer()) {
+ scoped_ptr<QuicEncryptedPacket> encrypted_deleter(packet->packet);
+ packet->packet = packet->packet->Clone();
}
- queued_packets_.push_back(packet);
+ queued_packets_.push_back(*packet);
}
// If a forward-secure encrypter is available but is not being used and the
@@ -1747,23 +1802,30 @@ void QuicConnection::SendOrQueuePacket(QueuedPacket packet) {
// forward security, start using the forward-secure encrypter.
if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
has_forward_secure_encrypter_ &&
- packet.serialized_packet.packet_number >=
- first_required_forward_secure_packet_ - 1) {
+ packet->packet_number >= first_required_forward_secure_packet_ - 1) {
SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
}
}
-void QuicConnection::SendPing() {
- if (retransmission_alarm_->IsSet()) {
- return;
+PeerAddressChangeType QuicConnection::DeterminePeerAddressChangeType() {
+ return UNKNOWN;
+}
+
+void QuicConnection::OnPingTimeout() {
+ if (!retransmission_alarm_->IsSet()) {
+ SendPing();
}
- packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame));
+}
+
+void QuicConnection::SendPing() {
+ packet_generator_.AddControlFrame(QuicFrame(QuicPingFrame()));
}
void QuicConnection::SendAck() {
ack_alarm_->Cancel();
ack_queued_ = false;
stop_waiting_count_ = 0;
+ num_retransmittable_packets_received_since_last_ack_sent_ = 0;
num_packets_received_since_last_ack_sent_ = 0;
packet_generator_.SetShouldSendAck(true);
@@ -1899,7 +1961,7 @@ void QuicConnection::MaybeProcessRevivedPacket() {
revived_header.is_in_fec_group = NOT_IN_FEC_GROUP;
revived_header.fec_group = 0;
group_map_.erase(last_header_.fec_group);
- last_decrypted_packet_level_ = group->effective_encryption_level();
+ last_decrypted_packet_level_ = group->EffectiveEncryptionLevel();
DCHECK_LT(last_decrypted_packet_level_, NUM_ENCRYPTION_LEVELS);
delete group;
@@ -1916,7 +1978,15 @@ void QuicConnection::MaybeProcessRevivedPacket() {
QuicFecGroup* QuicConnection::GetFecGroup() {
QuicFecGroupNumber fec_group_num = last_header_.fec_group;
- if (fec_group_num == 0) {
+ if (fec_group_num == 0 ||
+ (FLAGS_quic_drop_non_awaited_packets &&
+ fec_group_num <
+ received_packet_manager_.peer_least_packet_awaiting_ack() &&
+ !ContainsKey(group_map_, fec_group_num))) {
+ // If the group number is below peer_least_packet_awaiting_ack and this
+ // group does not exist, which means this group has missing packets below
+ // |peer_least_packet_awaiting_ack| which we would never receive, so return
+ // nullptr.
return nullptr;
}
if (!ContainsKey(group_map_, fec_group_num)) {
@@ -1930,15 +2000,11 @@ QuicFecGroup* QuicConnection::GetFecGroup() {
delete group_map_.begin()->second;
group_map_.erase(group_map_.begin());
}
- group_map_[fec_group_num] = new QuicFecGroup();
+ group_map_[fec_group_num] = new QuicFecGroup(fec_group_num);
}
return group_map_[fec_group_num];
}
-void QuicConnection::SendConnectionClose(QuicErrorCode error) {
- SendConnectionCloseWithDetails(error, string());
-}
-
void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error,
const string& details) {
// If we're write blocked, WritePacket() will not send, but will capture the
@@ -1949,9 +2015,9 @@ void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error,
void QuicConnection::SendConnectionClosePacket(QuicErrorCode error,
const string& details) {
- DVLOG(1) << ENDPOINT << "Force closing " << connection_id()
- << " with error " << QuicUtils::ErrorToString(error)
- << " (" << error << ") " << details;
+ DVLOG(1) << ENDPOINT << "Force closing " << connection_id() << " with error "
+ << QuicUtils::ErrorToString(error) << " (" << error << ") "
+ << details;
// Don't send explicit connection close packets for timeouts.
// This is particularly important on mobile, where connections are short.
if (silent_close_enabled_ &&
@@ -1973,11 +2039,11 @@ void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) {
return;
}
connected_ = false;
+ DCHECK(visitor_ != nullptr);
+ visitor_->OnConnectionClosed(error, from_peer);
if (debug_visitor_ != nullptr) {
debug_visitor_->OnConnectionClosed(error, from_peer);
}
- DCHECK(visitor_ != nullptr);
- visitor_->OnConnectionClosed(error, from_peer);
// Cancel the alarms so they don't trigger any action now that the
// connection is closed.
ack_alarm_->Cancel();
@@ -1999,8 +2065,7 @@ void QuicConnection::SendGoAway(QuicErrorCode error,
goaway_sent_ = true;
DVLOG(1) << ENDPOINT << "Going away with error "
- << QuicUtils::ErrorToString(error)
- << " (" << error << ")";
+ << QuicUtils::ErrorToString(error) << " (" << error << ")";
// Opportunistically bundle an ack with this outgoing packet.
ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK);
@@ -2011,10 +2076,10 @@ void QuicConnection::SendGoAway(QuicErrorCode error,
void QuicConnection::CloseFecGroupsBefore(QuicPacketNumber packet_number) {
FecGroupMap::iterator it = group_map_.begin();
while (it != group_map_.end()) {
- // If this is the current group or the group doesn't protect this packet
- // we can ignore it.
- if (last_header_.fec_group == it->first ||
- !it->second->ProtectsPacketsBefore(packet_number)) {
+ // If the group doesn't protect this packet we can ignore it.
+ if ((!FLAGS_quic_drop_non_awaited_packets &&
+ last_header_.fec_group == it->first) ||
+ !it->second->IsWaitingForPacketBefore(packet_number)) {
++it;
continue;
}
@@ -2038,8 +2103,12 @@ void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
}
bool QuicConnection::HasQueuedData() const {
- return pending_version_negotiation_packet_ ||
- !queued_packets_.empty() || packet_generator_.HasQueuedFrames();
+ return pending_version_negotiation_packet_ || !queued_packets_.empty() ||
+ packet_generator_.HasQueuedFrames();
+}
+
+void QuicConnection::EnableSavingCryptoPackets() {
+ save_crypto_packets_as_termination_packets_ = true;
}
bool QuicConnection::CanWriteStreamData() {
@@ -2049,8 +2118,8 @@ bool QuicConnection::CanWriteStreamData() {
return false;
}
- IsHandshake pending_handshake = visitor_->HasPendingHandshake() ?
- IS_HANDSHAKE : NOT_HANDSHAKE;
+ IsHandshake pending_handshake =
+ visitor_->HasPendingHandshake() ? IS_HANDSHAKE : NOT_HANDSHAKE;
// Sending queued packets may have caused the socket to become write blocked,
// or the congestion manager to prohibit sending. If we've sent everything
// we had queued and we're still not blocked, let the visitor know it can
@@ -2078,8 +2147,14 @@ void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout,
void QuicConnection::CheckForTimeout() {
QuicTime now = clock_->ApproximateNow();
- QuicTime time_of_last_packet = max(time_of_last_received_packet_,
- time_of_last_sent_new_packet_);
+ QuicTime time_of_last_packet = QuicTime::Zero();
+ if (!FLAGS_quic_use_new_idle_timeout) {
+ time_of_last_packet =
+ max(time_of_last_received_packet_, time_of_last_sent_new_packet_);
+ } else {
+ time_of_last_packet =
+ max(time_of_last_received_packet_, last_send_for_timeout_);
+ }
// |delta| can be < 0 as |now| is approximate time but |time_of_last_packet|
// is accurate time. However, this should not change the behavior of
@@ -2093,20 +2168,23 @@ void QuicConnection::CheckForTimeout() {
<< idle_network_timeout_.ToMicroseconds();
if (idle_duration >= idle_network_timeout_) {
DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity.";
- SendConnectionClose(QUIC_CONNECTION_TIMED_OUT);
+ SendConnectionCloseWithDetails(QUIC_CONNECTION_TIMED_OUT,
+ "No recent network activity");
return;
}
if (!overall_connection_timeout_.IsInfinite()) {
QuicTime::Delta connected_duration =
now.Subtract(stats_.connection_creation_time);
- DVLOG(1) << ENDPOINT << "connection time: "
- << connected_duration.ToMicroseconds() << " overall timeout: "
+ DVLOG(1) << ENDPOINT
+ << "connection time: " << connected_duration.ToMicroseconds()
+ << " overall timeout: "
<< overall_connection_timeout_.ToMicroseconds();
if (connected_duration >= overall_connection_timeout_) {
- DVLOG(1) << ENDPOINT <<
- "Connection timedout due to overall connection timeout.";
- SendConnectionClose(QUIC_CONNECTION_OVERALL_TIMED_OUT);
+ DVLOG(1) << ENDPOINT
+ << "Connection timedout due to overall connection timeout.";
+ SendConnectionCloseWithDetails(QUIC_CONNECTION_OVERALL_TIMED_OUT,
+ "Overall timeout expired");
return;
}
}
@@ -2115,14 +2193,14 @@ void QuicConnection::CheckForTimeout() {
}
void QuicConnection::SetTimeoutAlarm() {
- QuicTime time_of_last_packet = max(time_of_last_received_packet_,
- time_of_last_sent_new_packet_);
+ QuicTime time_of_last_packet =
+ max(time_of_last_received_packet_, time_of_last_sent_new_packet_);
QuicTime deadline = time_of_last_packet.Add(idle_network_timeout_);
if (!overall_connection_timeout_.IsInfinite()) {
- deadline = min(deadline,
- stats_.connection_creation_time.Add(
- overall_connection_timeout_));
+ deadline =
+ min(deadline,
+ stats_.connection_creation_time.Add(overall_connection_timeout_));
}
timeout_alarm_->Cancel();
@@ -2198,6 +2276,8 @@ QuicConnection::ScopedPacketBundler::ScopedPacketBundler(
connection_->ack_alarm_->IsSet() || connection_->stop_waiting_count_ > 1;
if (send_ack == SEND_ACK || (send_ack == BUNDLE_PENDING_ACK && ack_pending)) {
DVLOG(1) << "Bundling ack with outgoing packet.";
+ DCHECK(send_ack == SEND_ACK || connection_->ack_frame_updated() ||
+ connection_->stop_waiting_count_ > 1);
connection_->SendAck();
}
}
@@ -2235,27 +2315,30 @@ QuicConnection::ScopedRetransmissionScheduler::
}
HasRetransmittableData QuicConnection::IsRetransmittable(
- const QueuedPacket& packet) {
+ const SerializedPacket& packet) {
// Retransmitted packets retransmittable frames are owned by the unacked
// packet map, but are not present in the serialized packet.
if (packet.transmission_type != NOT_RETRANSMISSION ||
- packet.serialized_packet.retransmittable_frames != nullptr) {
+ packet.retransmittable_frames != nullptr) {
return HAS_RETRANSMITTABLE_DATA;
} else {
return NO_RETRANSMITTABLE_DATA;
}
}
-bool QuicConnection::IsConnectionClose(const QueuedPacket& packet) {
- const RetransmittableFrames* retransmittable_frames =
- packet.serialized_packet.retransmittable_frames;
- if (retransmittable_frames == nullptr) {
+bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet) {
+ if (packet.retransmittable_frames == nullptr) {
return false;
}
- for (const QuicFrame& frame : retransmittable_frames->frames()) {
+ for (const QuicFrame& frame : packet.retransmittable_frames->frames()) {
if (frame.type == CONNECTION_CLOSE_FRAME) {
return true;
}
+ if (save_crypto_packets_as_termination_packets_ &&
+ frame.type == STREAM_FRAME &&
+ frame.stream_frame->stream_id == kCryptoStreamId) {
+ return true;
+ }
}
return false;
}
@@ -2266,10 +2349,6 @@ void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
QuicByteCount QuicConnection::LimitMaxPacketSize(
QuicByteCount suggested_max_packet_size) {
- if (FLAGS_quic_allow_oversized_packets_for_test) {
- return suggested_max_packet_size;
- }
-
if (peer_address_.address().empty()) {
LOG(DFATAL) << "Attempted to use a connection without a valid peer address";
return suggested_max_packet_size;
@@ -2326,4 +2405,8 @@ void QuicConnection::DiscoverMtu() {
DCHECK(!mtu_discovery_alarm_->IsSet());
}
+bool QuicConnection::ack_frame_updated() const {
+ return received_packet_manager_.ack_frame_updated();
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_connection.h b/chromium/net/quic/quic_connection.h
index 1d7715e7ee3..8a69f77c947 100644
--- a/chromium/net/quic/quic_connection.h
+++ b/chromium/net/quic/quic_connection.h
@@ -17,6 +17,8 @@
#define NET_QUIC_QUIC_CONNECTION_H_
#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <list>
#include <map>
@@ -24,17 +26,16 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/crypto/quic_decrypter.h"
-#include "net/quic/quic_ack_notifier.h"
-#include "net/quic/quic_ack_notifier_manager.h"
#include "net/quic/quic_alarm.h"
#include "net/quic/quic_blocked_writer_interface.h"
-#include "net/quic/quic_connection_stats.h"
+#include "net/quic/quic_fec_group.h"
+#include "net/quic/quic_framer.h"
#include "net/quic/quic_packet_creator.h"
#include "net/quic/quic_packet_generator.h"
#include "net/quic/quic_packet_writer.h"
@@ -50,7 +51,6 @@ namespace net {
class QuicClock;
class QuicConfig;
class QuicConnection;
-class QuicDecrypter;
class QuicEncrypter;
class QuicFecGroup;
class QuicRandom;
@@ -150,7 +150,7 @@ class NET_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// points. Implementations must not mutate the state of the connection
// as a result of these callbacks.
class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor
- : public QuicPacketGenerator::DebugDelegate,
+ : public QuicPacketCreator::DebugDelegate,
public QuicSentPacketManager::DebugDelegate {
public:
~QuicConnectionDebugVisitor() override {}
@@ -158,9 +158,8 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor
// Called when a packet has been sent.
virtual void OnPacketSent(const SerializedPacket& serialized_packet,
QuicPacketNumber original_packet_number,
- EncryptionLevel level,
TransmissionType transmission_type,
- const QuicEncryptedPacket& packet,
+ size_t encrypted_length,
QuicTime sent_time) {}
// Called when a packet has been received, but before it is
@@ -174,8 +173,7 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor
// Called when a packet is received with a connection id that does not
// match the ID of this connection.
- virtual void OnIncorrectConnectionId(
- QuicConnectionId connection_id) {}
+ virtual void OnIncorrectConnectionId(QuicConnectionId connection_id) {}
// Called when an undecryptable packet has been received.
virtual void OnUndecryptablePacket() {}
@@ -209,8 +207,7 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor
virtual void OnRstStreamFrame(const QuicRstStreamFrame& frame) {}
// Called when a ConnectionCloseFrame has been parsed.
- virtual void OnConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame) {}
+ virtual void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) {}
// Called when a WindowUpdate has been parsed.
virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {}
@@ -244,6 +241,10 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor
virtual void OnResumeConnectionState(
const CachedNetworkParameters& cached_network_params) {}
+ // Called when the connection parameters are set from the supplied
+ // |config|.
+ virtual void OnSetFromConfig(const QuicConfig& config) {}
+
// Called when RTT may have changed, including when an RTT is read from
// the config.
virtual void OnRttChanged(QuicTime::Delta rtt) const {}
@@ -263,6 +264,9 @@ class NET_EXPORT_PRIVATE QuicConnectionHelperInterface {
// notify |delegate| when the alarm fires. Caller takes ownership
// of the new alarm, which will not yet be "set" to fire.
virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) = 0;
+
+ // Returns a QuicBufferAllocator to be used for all stream frame buffers.
+ virtual QuicBufferAllocator* GetBufferAllocator() = 0;
};
class NET_EXPORT_PRIVATE QuicConnection
@@ -277,24 +281,15 @@ class NET_EXPORT_PRIVATE QuicConnection
BUNDLE_PENDING_ACK = 2,
};
- class PacketWriterFactory {
- public:
- virtual ~PacketWriterFactory() {}
-
- virtual QuicPacketWriter* Create(QuicConnection* connection) const = 0;
- };
-
- // Constructs a new QuicConnection for |connection_id| and |address|. Invokes
- // writer_factory->Create() to get a writer; |owns_writer| specifies whether
- // the connection takes ownership of the returned writer. |helper| must
- // outlive this connection.
+ // Constructs a new QuicConnection for |connection_id| and |address| using
+ // |writer| to write packets. |owns_writer| specifies whether the connection
+ // takes ownership of |writer|. |helper| must outlive this connection.
QuicConnection(QuicConnectionId connection_id,
IPEndPoint address,
QuicConnectionHelperInterface* helper,
- const PacketWriterFactory& writer_factory,
+ QuicPacketWriter* writer,
bool owns_writer,
Perspective perspective,
- bool is_secure,
const QuicVersionVector& supported_versions);
~QuicConnection() override;
@@ -321,15 +316,15 @@ class NET_EXPORT_PRIVATE QuicConnection
// data is to be FEC protected. Note that data that is sent immediately
// following MUST_FEC_PROTECT data may get protected by falling within the
// same FEC group.
- // If |delegate| is provided, then it will be informed once ACKs have been
+ // If |listener| is provided, then it will be informed once ACKs have been
// received for all the packets written in this call.
- // The |delegate| is not owned by the QuicConnection and must outlive it.
- QuicConsumedData SendStreamData(QuicStreamId id,
- const QuicIOVector& iov,
- QuicStreamOffset offset,
- bool fin,
- FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* delegate);
+ // The |listener| is not owned by the QuicConnection and must outlive it.
+ virtual QuicConsumedData SendStreamData(QuicStreamId id,
+ QuicIOVector iov,
+ QuicStreamOffset offset,
+ bool fin,
+ FecProtection fec_protection,
+ QuicAckListenerInterface* listener);
// Send a RST_STREAM frame to the peer.
virtual void SendRstStream(QuicStreamId id,
@@ -340,8 +335,7 @@ class NET_EXPORT_PRIVATE QuicConnection
virtual void SendBlocked(QuicStreamId id);
// Send a WINDOW_UPDATE frame to the peer.
- virtual void SendWindowUpdate(QuicStreamId id,
- QuicStreamOffset byte_offset);
+ virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
// Sends the connection close packet without affecting the state of the
// connection. This should only be called if the session is actively being
@@ -351,7 +345,6 @@ class NET_EXPORT_PRIVATE QuicConnection
// Sends a connection close frame to the peer, and closes the connection by
// calling CloseConnection(notifying the visitor as it does so).
- virtual void SendConnectionClose(QuicErrorCode error);
virtual void SendConnectionCloseWithDetails(QuicErrorCode error,
const std::string& details);
// Notifies the visitor of the close and marks the connection as disconnected.
@@ -388,6 +381,10 @@ class NET_EXPORT_PRIVATE QuicConnection
// Set the packet writer.
void SetQuicPacketWriter(QuicPacketWriter* writer, bool owns_writer) {
+ DCHECK(writer != nullptr);
+ if (writer_ != nullptr && owns_writer_) {
+ delete writer_;
+ }
writer_ = writer;
owns_writer_ = owns_writer;
}
@@ -426,7 +423,7 @@ class NET_EXPORT_PRIVATE QuicConnection
bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
- void OnFecData(const QuicFecData& fec) override;
+ void OnFecData(base::StringPiece redundnancy) override;
void OnPacketComplete() override;
// QuicPacketGenerator::DelegateInterface
@@ -434,7 +431,9 @@ class NET_EXPORT_PRIVATE QuicConnection
IsHandshake handshake) override;
void PopulateAckFrame(QuicAckFrame* ack) override;
void PopulateStopWaitingFrame(QuicStopWaitingFrame* stop_waiting) override;
- void OnSerializedPacket(const SerializedPacket& packet) override;
+
+ // QuicPacketCreator::DelegateInterface
+ void OnSerializedPacket(SerializedPacket* packet) override;
void OnResetFecGroup() override;
// QuicSentPacketManager::NetworkChangeVisitor
@@ -482,9 +481,9 @@ class NET_EXPORT_PRIVATE QuicConnection
// Testing only.
size_t NumQueuedPackets() const { return queued_packets_.size(); }
- QuicEncryptedPacket* ReleaseConnectionClosePacket() {
- return connection_close_packet_.release();
- }
+ // Once called, any sent crypto packets to be saved as the
+ // termination packet, for use with stateless rejections.
+ void EnableSavingCryptoPackets();
// Returns true if the underlying UDP socket is writable, there is
// no queued data and the connection is not congestion-control
@@ -502,7 +501,11 @@ class NET_EXPORT_PRIVATE QuicConnection
// Otherwise, it will reschedule the timeout alarm.
void CheckForTimeout();
- // Sends a ping, and resets the ping alarm.
+ // Called when the ping alarm fires. Causes a ping frame to be sent only
+ // 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.
@@ -575,7 +578,7 @@ class NET_EXPORT_PRIVATE QuicConnection
// as densely as possible into packets. In addition, this bundler
// can be configured to ensure that an ACK frame is included in the
// first packet created, if there's new ack information to be sent.
- class ScopedPacketBundler {
+ class NET_EXPORT_PRIVATE ScopedPacketBundler {
public:
// In addition to all outgoing frames being bundled when the
// bundler is in scope, setting |include_ack| to true ensures that
@@ -611,8 +614,6 @@ class NET_EXPORT_PRIVATE QuicConnection
QuicPacketWriter* writer() { return writer_; }
const QuicPacketWriter* writer() const { return writer_; }
- bool is_secure() const { return is_secure_; }
-
// Sends an MTU discovery packet of size |target_mtu|. If the packet is
// acknowledged by the peer, the maximum packet size will be increased to
// |target_mtu|.
@@ -625,38 +626,30 @@ class NET_EXPORT_PRIVATE QuicConnection
// Return the name of the cipher of the primary decrypter of the framer.
const char* cipher_name() const { return framer_.decrypter()->cipher_name(); }
// Return the id of the cipher of the primary decrypter of the framer.
- uint32 cipher_id() const { return framer_.decrypter()->cipher_id(); }
+ uint32_t cipher_id() const { return framer_.decrypter()->cipher_id(); }
- protected:
- // Packets which have not been written to the wire.
- // Owns the QuicPacket* packet.
- struct QueuedPacket {
- QueuedPacket(SerializedPacket packet,
- EncryptionLevel level);
- QueuedPacket(SerializedPacket packet,
- EncryptionLevel level,
- TransmissionType transmission_type,
- QuicPacketNumber original_packet_number);
-
- SerializedPacket serialized_packet;
- const EncryptionLevel encryption_level;
- TransmissionType transmission_type;
- // The packet's original packet number if it is a retransmission.
- // Otherwise it must be 0.
- QuicPacketNumber original_packet_number;
- };
+ std::vector<QuicEncryptedPacket*>* termination_packets() {
+ return termination_packets_.get();
+ }
+
+ bool ack_frame_updated() const;
+ protected:
// Do any work which logically would be done in OnPacket but can not be
// safely done until the packet is validated. Returns true if the packet
- // can be handled, false otherwise.
- virtual bool ProcessValidatedPacket();
+ // can be handled, false otherwise. Also migrates the connection if the packet
+ // can be handled and peer address changes.
+ virtual bool ProcessValidatedPacket(const QuicPacketHeader& header);
// Send a packet to the peer, and takes ownership of the packet if the packet
// cannot be written immediately.
- virtual void SendOrQueuePacket(QueuedPacket packet);
+ virtual void SendOrQueuePacket(SerializedPacket* packet);
QuicConnectionHelperInterface* helper() { return helper_; }
+ // On peer address changes, determine and return the change type.
+ virtual PeerAddressChangeType DeterminePeerAddressChangeType();
+
// 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.
@@ -666,11 +659,15 @@ class NET_EXPORT_PRIVATE QuicConnection
bool peer_port_changed() const { return peer_port_changed_; }
+ const IPAddressNumber& migrating_peer_ip() const {
+ return migrating_peer_ip_;
+ }
+
private:
friend class test::QuicConnectionPeer;
friend class test::PacketSavingConnection;
- typedef std::list<QueuedPacket> QueuedPacketList;
+ typedef std::list<SerializedPacket> QueuedPacketList;
typedef std::map<QuicFecGroupNumber, QuicFecGroup*> FecGroupMap;
// Writes the given packet to socket, encrypted with packet's
@@ -680,17 +677,21 @@ class NET_EXPORT_PRIVATE QuicConnection
// retransmittable frames to nullptr.
// Saves the connection close packet for later transmission, even if the
// writer is write blocked.
- bool WritePacket(QueuedPacket* packet);
+ bool WritePacket(SerializedPacket* packet);
// Does the main work of WritePacket, but does not delete the packet or
// retransmittable frames upon success.
- bool WritePacketInner(QueuedPacket* packet);
+ bool WritePacketInner(SerializedPacket* packet);
// Make sure an ack we got from our peer is sane.
- bool ValidateAckFrame(const QuicAckFrame& incoming_ack);
+ // Returns nullptr for valid acks or an error std::string if it was invalid.
+ const char* ValidateAckFrame(const QuicAckFrame& incoming_ack);
// Make sure a stop waiting we got from our peer is sane.
- bool ValidateStopWaitingFrame(const QuicStopWaitingFrame& stop_waiting);
+ // Returns nullptr if the frame is valid or an error std::string if it was
+ // invalid.
+ const char* ValidateStopWaitingFrame(
+ const QuicStopWaitingFrame& stop_waiting);
// Sends a version negotiation packet to the peer.
void SendVersionNegotiationPacket();
@@ -698,7 +699,7 @@ class NET_EXPORT_PRIVATE QuicConnection
// Clears any accumulated frames from the last received packet.
void ClearLastFrames();
- // Deletes and clears any QueuedPackets.
+ // Deletes and clears any queued packets.
void ClearQueuedPackets();
// Closes the connection if the sent or received packet manager are tracking
@@ -713,7 +714,7 @@ class NET_EXPORT_PRIVATE QuicConnection
void WritePendingRetransmissions();
// Returns true if the packet should be discarded and not sent.
- bool ShouldDiscardPacket(const QueuedPacket& packet);
+ bool ShouldDiscardPacket(const SerializedPacket& packet);
// Queues |packet| in the hopes that it can be decrypted in the
// future, when a new key is installed.
@@ -730,17 +731,14 @@ class NET_EXPORT_PRIVATE QuicConnection
void ProcessStopWaitingFrame(const QuicStopWaitingFrame& stop_waiting);
- // Queues an ack or sets the ack alarm when an incoming packet arrives that
- // should be acked.
- void MaybeQueueAck();
-
- // Checks if the last packet should instigate an ack.
- bool ShouldLastPacketInstigateAck() const;
-
// Sends any packets which are a response to the last packet, including both
// acks and pending writes if an ack opened the congestion window.
void MaybeSendInResponseToPacket();
+ // Queue an ack or set the ack alarm if needed. |was_missing| is true if
+ // the most recently received packet was formerly missing.
+ void MaybeQueueAck(bool was_missing);
+
// Gets the least unacked packet number, which is the next packet number
// to be sent if there are no outstanding packets.
QuicPacketNumber GetLeastUnacked() const;
@@ -769,8 +767,8 @@ class NET_EXPORT_PRIVATE QuicConnection
void CheckForAddressMigration(const IPEndPoint& self_address,
const IPEndPoint& peer_address);
- HasRetransmittableData IsRetransmittable(const QueuedPacket& packet);
- bool IsConnectionClose(const QueuedPacket& packet);
+ HasRetransmittableData IsRetransmittable(const SerializedPacket& packet);
+ bool IsTerminationPacket(const SerializedPacket& packet);
// Set the size of the packet we are targeting while doing path MTU discovery.
void SetMtuDiscoveryTarget(QuicByteCount target);
@@ -803,13 +801,13 @@ class NET_EXPORT_PRIVATE QuicConnection
// Used to store latest peer IP address for IP address migration.
IPAddressNumber migrating_peer_ip_;
// Used to store latest peer port to possibly migrate to later.
- uint16 migrating_peer_port_;
+ uint16_t migrating_peer_port_;
// True if the last packet has gotten far enough in the framer to be
// decrypted.
bool last_packet_decrypted_;
bool last_packet_revived_; // True if the last packet was revived from FEC.
- QuicByteCount last_size_; // Size of the last received packet.
+ QuicByteCount last_size_; // Size of the last received packet.
EncryptionLevel last_decrypted_packet_level_;
QuicPacketHeader last_header_;
QuicStopWaitingFrame last_stop_waiting_frame_;
@@ -840,8 +838,11 @@ class NET_EXPORT_PRIVATE QuicConnection
// unacked_packets_ if they are to be retransmitted.
QueuedPacketList queued_packets_;
- // Contains the connection close packet if the connection has been closed.
- scoped_ptr<QuicEncryptedPacket> connection_close_packet_;
+ // If true, then crypto packets will be saved as termination packets.
+ bool save_crypto_packets_as_termination_packets_;
+
+ // Contains the connection close packets if the connection has been closed.
+ scoped_ptr<std::vector<QuicEncryptedPacket*>> termination_packets_;
// When true, the connection does not send a close packet on timeout.
bool silent_close_enabled_;
@@ -853,11 +854,15 @@ class NET_EXPORT_PRIVATE QuicConnection
// Indicates whether an ack should be sent the next time we try to write.
bool ack_queued_;
- // Indicates how many consecutive packets have arrived without sending an ack.
+ // How many retransmittable packets have arrived without sending an ack.
+ QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_;
+ // How many consecutive packets have arrived without sending an ack.
QuicPacketCount num_packets_received_since_last_ack_sent_;
// Indicates how many consecutive times an ack has arrived which indicates
// the peer needs to stop waiting for some packets.
int stop_waiting_count_;
+ // When true, ack only every 10 packets as long as they arrive close together.
+ bool ack_decimation_enabled_;
// Indicates the retransmit alarm is going to be set by the
// ScopedRetransmitAlarmDelayer
@@ -907,6 +912,10 @@ class NET_EXPORT_PRIVATE QuicConnection
// packet.
QuicTime time_of_last_sent_new_packet_;
+ // The the send time of the first retransmittable packet sent after
+ // |time_of_last_received_packet_|.
+ QuicTime last_send_for_timeout_;
+
// packet number of the last sent packet. Packets are guaranteed to be sent
// in packet number order.
QuicPacketNumber packet_number_of_last_sent_packet_;
@@ -948,9 +957,6 @@ class NET_EXPORT_PRIVATE QuicConnection
// version negotiation packet.
QuicVersionVector server_supported_versions_;
- // True if this is a secure QUIC connection.
- bool is_secure_;
-
// The size of the packet we are targeting while doing path MTU discovery.
QuicByteCount mtu_discovery_target_;
@@ -973,6 +979,9 @@ class NET_EXPORT_PRIVATE QuicConnection
// Whether a GoAway has been received.
bool goaway_received_;
+ // If true, multipath is enabled for this connection.
+ bool multipath_enabled_;
+
DISALLOW_COPY_AND_ASSIGN(QuicConnection);
};
diff --git a/chromium/net/quic/quic_connection_logger.cc b/chromium/net/quic/quic_connection_logger.cc
index 9be77b9de07..33fa4e0c68b 100644
--- a/chromium/net/quic/quic_connection_logger.cc
+++ b/chromium/net/quic/quic_connection_logger.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/callback.h"
@@ -14,7 +15,6 @@
#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
-#include "net/base/net_util.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/x509_certificate.h"
#include "net/log/net_log.h"
@@ -45,25 +45,23 @@ scoped_ptr<base::Value> NetLogQuicPacketCallback(
dict->SetString("self_address", self_address->ToString());
dict->SetString("peer_address", peer_address->ToString());
dict->SetInteger("size", packet_size);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicPacketSentCallback(
const SerializedPacket& serialized_packet,
- EncryptionLevel level,
TransmissionType transmission_type,
size_t packet_size,
QuicTime sent_time,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetInteger("encryption_level", level);
dict->SetInteger("transmission_type", transmission_type);
dict->SetString("packet_number",
base::Uint64ToString(serialized_packet.packet_number));
dict->SetInteger("size", packet_size);
dict->SetString("sent_time_us",
base::Int64ToString(sent_time.ToDebuggingValue()));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicPacketRetransmittedCallback(
@@ -73,7 +71,7 @@ scoped_ptr<base::Value> NetLogQuicPacketRetransmittedCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("old_packet_number", base::Uint64ToString(old_packet_number));
dict->SetString("new_packet_number", base::Uint64ToString(new_packet_number));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicDuplicatePacketCallback(
@@ -81,7 +79,7 @@ scoped_ptr<base::Value> NetLogQuicDuplicatePacketCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("packet_number", base::Uint64ToString(packet_number));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicPacketHeaderCallback(
@@ -92,12 +90,11 @@ scoped_ptr<base::Value> NetLogQuicPacketHeaderCallback(
base::Uint64ToString(header->public_header.connection_id));
dict->SetInteger("reset_flag", header->public_header.reset_flag);
dict->SetInteger("version_flag", header->public_header.version_flag);
- dict->SetString("packet_number",
- base::Uint64ToString(header->packet_packet_number));
+ dict->SetString("packet_number", base::Uint64ToString(header->packet_number));
dict->SetInteger("entropy_flag", header->entropy_flag);
dict->SetInteger("fec_flag", header->fec_flag);
dict->SetInteger("fec_group", static_cast<int>(header->fec_group));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicStreamFrameCallback(
@@ -107,8 +104,8 @@ scoped_ptr<base::Value> NetLogQuicStreamFrameCallback(
dict->SetInteger("stream_id", frame->stream_id);
dict->SetBoolean("fin", frame->fin);
dict->SetString("offset", base::Uint64ToString(frame->offset));
- dict->SetInteger("length", frame->data.size());
- return dict.Pass();
+ dict->SetInteger("length", frame->frame_length);
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicAckFrameCallback(
@@ -120,8 +117,7 @@ scoped_ptr<base::Value> NetLogQuicAckFrameCallback(
dict->SetString(
"delta_time_largest_observed_us",
base::Int64ToString(frame->delta_time_largest_observed.ToMicroseconds()));
- dict->SetInteger("entropy_hash",
- frame->entropy_hash);
+ dict->SetInteger("entropy_hash", frame->entropy_hash);
dict->SetBoolean("truncated", frame->is_truncated);
base::ListValue* missing = new base::ListValue();
@@ -129,18 +125,13 @@ scoped_ptr<base::Value> NetLogQuicAckFrameCallback(
for (QuicPacketNumber packet : frame->missing_packets)
missing->AppendString(base::Uint64ToString(packet));
- base::ListValue* revived = new base::ListValue();
- dict->Set("revived_packets", revived);
- const PacketNumberSet& revived_packets = frame->revived_packets;
- for (PacketNumberSet::const_iterator it = revived_packets.begin();
- it != revived_packets.end(); ++it) {
- revived->AppendString(base::Uint64ToString(*it));
- }
+ dict->SetString("latest_revived_packet",
+ base::Int64ToString(frame->latest_revived_packet));
base::ListValue* received = new base::ListValue();
dict->Set("received_packet_times", received);
- const PacketTimeList& received_times = frame->received_packet_times;
- for (PacketTimeList::const_iterator it = received_times.begin();
+ const PacketTimeVector& received_times = frame->received_packet_times;
+ for (PacketTimeVector::const_iterator it = received_times.begin();
it != received_times.end(); ++it) {
base::DictionaryValue* info = new base::DictionaryValue();
info->SetInteger("packet_number", static_cast<int>(it->first));
@@ -149,7 +140,7 @@ scoped_ptr<base::Value> NetLogQuicAckFrameCallback(
received->Append(info);
}
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicRstStreamFrameCallback(
@@ -158,8 +149,7 @@ scoped_ptr<base::Value> NetLogQuicRstStreamFrameCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", frame->stream_id);
dict->SetInteger("quic_rst_stream_error", frame->error_code);
- dict->SetString("details", frame->error_details);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicConnectionCloseFrameCallback(
@@ -168,7 +158,7 @@ scoped_ptr<base::Value> NetLogQuicConnectionCloseFrameCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("quic_error", frame->error_code);
dict->SetString("details", frame->error_details);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicWindowUpdateFrameCallback(
@@ -177,7 +167,7 @@ scoped_ptr<base::Value> NetLogQuicWindowUpdateFrameCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", frame->stream_id);
dict->SetString("byte_offset", base::Uint64ToString(frame->byte_offset));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicBlockedFrameCallback(
@@ -185,7 +175,7 @@ scoped_ptr<base::Value> NetLogQuicBlockedFrameCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", frame->stream_id);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicGoAwayFrameCallback(
@@ -195,7 +185,7 @@ scoped_ptr<base::Value> NetLogQuicGoAwayFrameCallback(
dict->SetInteger("quic_error", frame->error_code);
dict->SetInteger("last_good_stream_id", frame->last_good_stream_id);
dict->SetString("reason_phrase", frame->reason_phrase);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicStopWaitingFrameCallback(
@@ -206,7 +196,7 @@ scoped_ptr<base::Value> NetLogQuicStopWaitingFrameCallback(
dict->Set("sent_info", sent_info);
sent_info->SetString("least_unacked",
base::Uint64ToString(frame->least_unacked));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicVersionNegotiationPacketCallback(
@@ -219,7 +209,7 @@ scoped_ptr<base::Value> NetLogQuicVersionNegotiationPacketCallback(
it != packet->versions.end(); ++it) {
versions->AppendString(QuicVersionToString(*it));
}
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicCryptoHandshakeMessageCallback(
@@ -227,7 +217,7 @@ scoped_ptr<base::Value> NetLogQuicCryptoHandshakeMessageCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("quic_crypto_handshake_message", message->DebugString());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicOnConnectionClosedCallback(
@@ -237,7 +227,7 @@ scoped_ptr<base::Value> NetLogQuicOnConnectionClosedCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("quic_error", error);
dict->SetBoolean("from_peer", from_peer);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogQuicCertificateVerifiedCallback(
@@ -254,7 +244,7 @@ scoped_ptr<base::Value> NetLogQuicCertificateVerifiedCallback(
subjects->Append(new base::StringValue(*it));
}
dict->Set("subjects", subjects);
- return dict.Pass();
+ return std::move(dict);
}
void UpdatePacketGapSentHistogram(size_t num_consecutive_missing_packets) {
@@ -278,8 +268,8 @@ void UpdatePublicResetAddressMismatchHistogram(
// If |address| is an IPv4-mapped IPv6 address, returns ADDRESS_FAMILY_IPV4
// instead of ADDRESS_FAMILY_IPV6. Othewise, behaves like GetAddressFamily().
AddressFamily GetRealAddressFamily(const IPAddressNumber& address) {
- return IsIPv4Mapped(address) ? ADDRESS_FAMILY_IPV4 :
- GetAddressFamily(address);
+ return IsIPv4Mapped(address) ? ADDRESS_FAMILY_IPV4
+ : GetAddressFamily(address);
}
} // namespace
@@ -310,7 +300,7 @@ QuicConnectionLogger::QuicConnectionLogger(
num_blocked_frames_received_(0),
num_blocked_frames_sent_(0),
connection_description_(connection_description),
- socket_performance_watcher_(socket_performance_watcher.Pass()) {}
+ socket_performance_watcher_(std::move(socket_performance_watcher)) {}
QuicConnectionLogger::~QuicConnectionLogger() {
UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderPacketsReceived",
@@ -345,7 +335,6 @@ QuicConnectionLogger::~QuicConnectionLogger() {
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Net.QuicSession.StreamFrameDuplicatedLongConnection",
duplicate_stream_frame_per_thousand, 1, 1000, 75);
-
}
}
@@ -367,7 +356,7 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
base::Bind(&NetLogQuicAckFrameCallback, frame.ack_frame));
const PacketNumberQueue& missing_packets =
frame.ack_frame->missing_packets;
- const uint8 max_ranges = std::numeric_limits<uint8>::max();
+ const uint8_t max_ranges = std::numeric_limits<uint8_t>::max();
// Compute an upper bound on the number of NACK ranges. If the bound
// is below the max, then it clearly isn't truncated.
if (missing_packets.NumPacketsSlow() < max_ranges ||
@@ -389,41 +378,35 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
case RST_STREAM_FRAME:
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.RstStreamErrorCodeClient",
frame.rst_stream_frame->error_code);
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_RST_STREAM_FRAME_SENT,
- base::Bind(&NetLogQuicRstStreamFrameCallback,
- frame.rst_stream_frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_RST_STREAM_FRAME_SENT,
+ base::Bind(&NetLogQuicRstStreamFrameCallback,
+ frame.rst_stream_frame));
break;
case CONNECTION_CLOSE_FRAME:
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_CONNECTION_CLOSE_FRAME_SENT,
- base::Bind(&NetLogQuicConnectionCloseFrameCallback,
- frame.connection_close_frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_CONNECTION_CLOSE_FRAME_SENT,
+ base::Bind(&NetLogQuicConnectionCloseFrameCallback,
+ frame.connection_close_frame));
break;
case GOAWAY_FRAME:
net_log_.AddEvent(
NetLog::TYPE_QUIC_SESSION_GOAWAY_FRAME_SENT,
- base::Bind(&NetLogQuicGoAwayFrameCallback,
- frame.goaway_frame));
+ base::Bind(&NetLogQuicGoAwayFrameCallback, frame.goaway_frame));
break;
case WINDOW_UPDATE_FRAME:
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_WINDOW_UPDATE_FRAME_SENT,
- base::Bind(&NetLogQuicWindowUpdateFrameCallback,
- frame.window_update_frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_WINDOW_UPDATE_FRAME_SENT,
+ base::Bind(&NetLogQuicWindowUpdateFrameCallback,
+ frame.window_update_frame));
break;
case BLOCKED_FRAME:
++num_blocked_frames_sent_;
net_log_.AddEvent(
NetLog::TYPE_QUIC_SESSION_BLOCKED_FRAME_SENT,
- base::Bind(&NetLogQuicBlockedFrameCallback,
- frame.blocked_frame));
+ base::Bind(&NetLogQuicBlockedFrameCallback, frame.blocked_frame));
break;
case STOP_WAITING_FRAME:
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_STOP_WAITING_FRAME_SENT,
- base::Bind(&NetLogQuicStopWaitingFrameCallback,
- frame.stop_waiting_frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_STOP_WAITING_FRAME_SENT,
+ base::Bind(&NetLogQuicStopWaitingFrameCallback,
+ frame.stop_waiting_frame));
break;
case PING_FRAME:
UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectionFlowControlBlocked",
@@ -445,16 +428,15 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
void QuicConnectionLogger::OnPacketSent(
const SerializedPacket& serialized_packet,
QuicPacketNumber original_packet_number,
- EncryptionLevel level,
TransmissionType transmission_type,
- const QuicEncryptedPacket& packet,
+ size_t encrypted_length,
QuicTime sent_time) {
if (original_packet_number == 0) {
net_log_.AddEvent(
NetLog::TYPE_QUIC_SESSION_PACKET_SENT,
base::Bind(&NetLogQuicPacketSentCallback, serialized_packet,
- level, transmission_type, packet.length(), sent_time));
- } else {
+ transmission_type, encrypted_length, sent_time));
+ } else {
net_log_.AddEvent(
NetLog::TYPE_QUIC_SESSION_PACKET_RETRANSMITTED,
base::Bind(&NetLogQuicPacketRetransmittedCallback,
@@ -484,10 +466,9 @@ void QuicConnectionLogger::OnPacketReceived(const IPEndPoint& self_address,
previous_received_packet_size_ = last_received_packet_size_;
last_received_packet_size_ = packet.length();
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
- base::Bind(&NetLogQuicPacketCallback, &self_address, &peer_address,
- packet.length()));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
+ base::Bind(&NetLogQuicPacketCallback, &self_address,
+ &peer_address, packet.length()));
}
void QuicConnectionLogger::OnUnauthenticatedHeader(
@@ -521,9 +502,9 @@ void QuicConnectionLogger::OnProtocolVersionMismatch(
void QuicConnectionLogger::OnPacketHeader(const QuicPacketHeader& header) {
net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_PACKET_AUTHENTICATED);
++num_packets_received_;
- if (largest_received_packet_number_ < header.packet_packet_number) {
+ if (largest_received_packet_number_ < header.packet_number) {
QuicPacketNumber delta =
- header.packet_packet_number - largest_received_packet_number_;
+ header.packet_number - largest_received_packet_number_;
if (delta > 1) {
// There is a gap between the largest packet previously received and
// the current packet. This indicates either loss, or out-of-order
@@ -531,33 +512,31 @@ void QuicConnectionLogger::OnPacketHeader(const QuicPacketHeader& header) {
UMA_HISTOGRAM_COUNTS("Net.QuicSession.PacketGapReceived",
static_cast<base::HistogramBase::Sample>(delta - 1));
}
- largest_received_packet_number_ = header.packet_packet_number;
+ largest_received_packet_number_ = header.packet_number;
}
- if (header.packet_packet_number < received_packets_.size()) {
- received_packets_[static_cast<size_t>(header.packet_packet_number)] = true;
+ if (header.packet_number < received_packets_.size()) {
+ received_packets_[static_cast<size_t>(header.packet_number)] = true;
}
- if (header.packet_packet_number < last_received_packet_number_) {
+ if (header.packet_number < last_received_packet_number_) {
++num_out_of_order_received_packets_;
if (previous_received_packet_size_ < last_received_packet_size_)
++num_out_of_order_large_received_packets_;
UMA_HISTOGRAM_COUNTS(
"Net.QuicSession.OutOfOrderGapReceived",
static_cast<base::HistogramBase::Sample>(last_received_packet_number_ -
- header.packet_packet_number));
+ header.packet_number));
}
- last_received_packet_number_ = header.packet_packet_number;
+ last_received_packet_number_ = header.packet_number;
}
void QuicConnectionLogger::OnStreamFrame(const QuicStreamFrame& frame) {
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
- base::Bind(&NetLogQuicStreamFrameCallback, &frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
+ base::Bind(&NetLogQuicStreamFrameCallback, &frame));
}
void QuicConnectionLogger::OnAckFrame(const QuicAckFrame& frame) {
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_ACK_FRAME_RECEIVED,
- base::Bind(&NetLogQuicAckFrameCallback, &frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_ACK_FRAME_RECEIVED,
+ base::Bind(&NetLogQuicAckFrameCallback, &frame));
const size_t kApproximateLargestSoloAckBytes = 100;
if (last_received_packet_number_ < received_acks_.size() &&
@@ -605,17 +584,15 @@ void QuicConnectionLogger::OnAckFrame(const QuicAckFrame& frame) {
void QuicConnectionLogger::OnStopWaitingFrame(
const QuicStopWaitingFrame& frame) {
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_STOP_WAITING_FRAME_RECEIVED,
- base::Bind(&NetLogQuicStopWaitingFrameCallback, &frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_STOP_WAITING_FRAME_RECEIVED,
+ base::Bind(&NetLogQuicStopWaitingFrameCallback, &frame));
}
void QuicConnectionLogger::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.RstStreamErrorCodeServer",
frame.error_code);
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_RST_STREAM_FRAME_RECEIVED,
- base::Bind(&NetLogQuicRstStreamFrameCallback, &frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_RST_STREAM_FRAME_RECEIVED,
+ base::Bind(&NetLogQuicRstStreamFrameCallback, &frame));
}
void QuicConnectionLogger::OnConnectionCloseFrame(
@@ -627,22 +604,19 @@ void QuicConnectionLogger::OnConnectionCloseFrame(
void QuicConnectionLogger::OnWindowUpdateFrame(
const QuicWindowUpdateFrame& frame) {
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_WINDOW_UPDATE_FRAME_RECEIVED,
- base::Bind(&NetLogQuicWindowUpdateFrameCallback, &frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_WINDOW_UPDATE_FRAME_RECEIVED,
+ base::Bind(&NetLogQuicWindowUpdateFrameCallback, &frame));
}
void QuicConnectionLogger::OnBlockedFrame(const QuicBlockedFrame& frame) {
++num_blocked_frames_received_;
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_BLOCKED_FRAME_RECEIVED,
- base::Bind(&NetLogQuicBlockedFrameCallback, &frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_BLOCKED_FRAME_RECEIVED,
+ base::Bind(&NetLogQuicBlockedFrameCallback, &frame));
}
void QuicConnectionLogger::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
- net_log_.AddEvent(
- NetLog::TYPE_QUIC_SESSION_GOAWAY_FRAME_RECEIVED,
- base::Bind(&NetLogQuicGoAwayFrameCallback, &frame));
+ net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_GOAWAY_FRAME_RECEIVED,
+ base::Bind(&NetLogQuicGoAwayFrameCallback, &frame));
}
void QuicConnectionLogger::OnPingFrame(const QuicPingFrame& frame) {
@@ -684,10 +658,10 @@ void QuicConnectionLogger::OnCryptoHandshakeMessageReceived(
if (message.GetStringPiece(kCADR, &address) &&
decoder.Decode(address.data(), address.size())) {
local_address_from_shlo_ = IPEndPoint(decoder.ip(), decoder.port());
- UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionTypeFromPeer",
- GetRealAddressFamily(
- local_address_from_shlo_.address()),
- ADDRESS_FAMILY_LAST);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.QuicSession.ConnectionTypeFromPeer",
+ GetRealAddressFamily(local_address_from_shlo_.address()),
+ ADDRESS_FAMILY_LAST);
}
}
}
@@ -738,8 +712,8 @@ base::HistogramBase* QuicConnectionLogger::GetPacketNumberHistogram(
const char* statistic_name) const {
string prefix("Net.QuicSession.PacketReceived_");
return base::LinearHistogram::FactoryGet(
- prefix + statistic_name + connection_description_,
- 1, received_packets_.size(), received_packets_.size() + 1,
+ prefix + statistic_name + connection_description_, 1,
+ received_packets_.size(), received_packets_.size() + 1,
base::HistogramBase::kUmaTargetedHistogramFlag);
}
@@ -754,7 +728,7 @@ base::HistogramBase* QuicConnectionLogger::Get6PacketHistogram(
}
base::HistogramBase* QuicConnectionLogger::Get21CumulativeHistogram(
- const char* which_21) const {
+ const char* which_21) const {
// This histogram contains, for each sequence of 21 packets, the results from
// 21 distinct questions about that sequence. Conceptually the histogtram is
// broken into 21 distinct ranges, and one sample is added into each of those
@@ -770,8 +744,8 @@ base::HistogramBase* QuicConnectionLogger::Get21CumulativeHistogram(
// etc.
string prefix("Net.QuicSession.21CumulativePacketsReceived_");
return base::LinearHistogram::FactoryGet(
- prefix + which_21 + connection_description_,
- 1, kBoundingSampleInCumulativeHistogram,
+ prefix + which_21 + connection_description_, 1,
+ kBoundingSampleInCumulativeHistogram,
kBoundingSampleInCumulativeHistogram + 1,
base::HistogramBase::kUmaTargetedHistogramFlag);
}
diff --git a/chromium/net/quic/quic_connection_logger.h b/chromium/net/quic/quic_connection_logger.h
index 9e687f2a62d..6d414905f9e 100644
--- a/chromium/net/quic/quic_connection_logger.h
+++ b/chromium/net/quic/quic_connection_logger.h
@@ -5,8 +5,11 @@
#ifndef NET_QUIC_QUIC_CONNECTION_LOGGER_H_
#define NET_QUIC_QUIC_CONNECTION_LOGGER_H_
+#include <stddef.h>
+
#include <bitset>
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "net/base/network_change_notifier.h"
#include "net/base/socket_performance_watcher.h"
@@ -42,9 +45,8 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger
// QuicConnectionDebugVisitorInterface
void OnPacketSent(const SerializedPacket& serialized_packet,
QuicPacketNumber original_packet_number,
- EncryptionLevel level,
TransmissionType transmission_type,
- const QuicEncryptedPacket& packet,
+ size_t encrypted_length,
QuicTime sent_time) override;
void OnPacketReceived(const IPEndPoint& self_address,
const IPEndPoint& peer_address,
@@ -73,10 +75,8 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger
void OnSuccessfulVersionNegotiation(const QuicVersion& version) override;
void OnRttChanged(QuicTime::Delta rtt) const override;
- void OnCryptoHandshakeMessageReceived(
- const CryptoHandshakeMessage& message);
- void OnCryptoHandshakeMessageSent(
- const CryptoHandshakeMessage& message);
+ void OnCryptoHandshakeMessageReceived(const CryptoHandshakeMessage& message);
+ void OnCryptoHandshakeMessageSent(const CryptoHandshakeMessage& message);
void UpdateReceivedFrameCounts(QuicStreamId stream_id,
int num_frames_received,
int num_duplicate_frames_received);
diff --git a/chromium/net/quic/quic_connection_logger_unittest.cc b/chromium/net/quic/quic_connection_logger_unittest.cc
index 3d66f3fa6de..ebaa12dbfec 100644
--- a/chromium/net/quic/quic_connection_logger_unittest.cc
+++ b/chromium/net/quic/quic_connection_logger_unittest.cc
@@ -32,13 +32,14 @@ class QuicConnectionLoggerPeer {
class QuicConnectionLoggerTest : public ::testing::Test {
protected:
QuicConnectionLoggerTest()
- : session_(new MockConnection(Perspective::IS_CLIENT)),
+ : session_(new MockConnection(&helper_, Perspective::IS_CLIENT)),
logger_(&session_,
"CONNECTION_UNKNOWN",
/*socket_performance_watcher=*/nullptr,
net_log_) {}
BoundNetLog net_log_;
+ MockConnectionHelper helper_;
MockQuicSpdySession session_;
QuicConnectionLogger logger_;
};
diff --git a/chromium/net/quic/quic_connection_stats.cc b/chromium/net/quic/quic_connection_stats.cc
index e581c17c254..2c98fcca57d 100644
--- a/chromium/net/quic/quic_connection_stats.cc
+++ b/chromium/net/quic/quic_connection_stats.cc
@@ -39,8 +39,7 @@ QuicConnectionStats::QuicConnectionStats()
max_sequence_reordering(0),
max_time_reordering_us(0),
tcp_loss_events(0),
- connection_creation_time(QuicTime::Zero()) {
-}
+ connection_creation_time(QuicTime::Zero()) {}
QuicConnectionStats::~QuicConnectionStats() {}
diff --git a/chromium/net/quic/quic_connection_stats.h b/chromium/net/quic/quic_connection_stats.h
index 14f2c2c52ad..655ab321f83 100644
--- a/chromium/net/quic/quic_connection_stats.h
+++ b/chromium/net/quic/quic_connection_stats.h
@@ -5,9 +5,11 @@
#ifndef NET_QUIC_QUIC_CONNECTION_STATS_H_
#define NET_QUIC_QUIC_CONNECTION_STATS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <ostream>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_protocol.h"
@@ -20,7 +22,8 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats {
~QuicConnectionStats();
NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicConnectionStats& s);
+ std::ostream& os,
+ const QuicConnectionStats& s);
QuicByteCount bytes_sent; // Includes retransmissions, fec.
QuicPacketCount packets_sent;
@@ -60,8 +63,8 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats {
size_t tlp_count;
size_t rto_count; // Count of times the rto timer fired.
- int64 min_rtt_us; // Minimum RTT in microseconds.
- int64 srtt_us; // Smoothed RTT in microseconds.
+ int64_t min_rtt_us; // Minimum RTT in microseconds.
+ int64_t srtt_us; // Smoothed RTT in microseconds.
QuicByteCount max_packet_size;
QuicByteCount max_received_packet_size;
QuicBandwidth estimated_bandwidth;
@@ -72,12 +75,12 @@ struct NET_EXPORT_PRIVATE QuicConnectionStats {
// Maximum reordering observed in packet number space.
QuicPacketNumber max_sequence_reordering;
// Maximum reordering observed in microseconds
- int64 max_time_reordering_us;
+ int64_t max_time_reordering_us;
// The following stats are used only in TcpCubicSender.
// The number of loss events from TCP's perspective. Each loss event includes
// one or more lost packets.
- uint32 tcp_loss_events;
+ uint32_t tcp_loss_events;
// Creation time, as reported by the QuicClock.
QuicTime connection_creation_time;
diff --git a/chromium/net/quic/quic_connection_test.cc b/chromium/net/quic/quic_connection_test.cc
index 13128011b45..c29ded9c9ff 100644
--- a/chromium/net/quic/quic_connection_test.cc
+++ b/chromium/net/quic/quic_connection_test.cc
@@ -6,8 +6,8 @@
#include <ostream>
-#include "base/basictypes.h"
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "net/base/net_errors.h"
@@ -16,9 +16,9 @@
#include "net/quic/crypto/null_encrypter.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
-#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_simple_buffer_allocator.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
@@ -49,6 +49,7 @@ using testing::NiceMock;
using testing::Ref;
using testing::Return;
using testing::SaveArg;
+using testing::SetArgPointee;
using testing::StrictMock;
using testing::_;
@@ -61,6 +62,7 @@ const char data2[] = "bar";
const bool kFin = true;
const bool kEntropyFlag = true;
+const bool kHasStopWaiting = true;
const QuicPacketEntropyHash kTestEntropyHash = 76;
@@ -72,9 +74,7 @@ const IPEndPoint kSelfAddress = IPEndPoint(Loopback6(), /*port=*/443);
// TaggingEncrypter appends kTagSize bytes of |tag| to the end of each message.
class TaggingEncrypter : public QuicEncrypter {
public:
- explicit TaggingEncrypter(uint8 tag)
- : tag_(tag) {
- }
+ explicit TaggingEncrypter(uint8_t tag) : tag_(tag) {}
~TaggingEncrypter() override {}
@@ -93,7 +93,7 @@ class TaggingEncrypter : public QuicEncrypter {
if (max_output_length < len) {
return false;
}
- memcpy(output, plaintext.data(), plaintext.size());
+ memmove(output, plaintext.data(), plaintext.size());
output += plaintext.size();
memset(output, tag_, kTagSize);
*output_length = len;
@@ -120,7 +120,7 @@ class TaggingEncrypter : public QuicEncrypter {
kTagSize = 12,
};
- const uint8 tag_;
+ const uint8_t tag_;
DISALLOW_COPY_AND_ASSIGN(TaggingEncrypter);
};
@@ -157,11 +157,11 @@ class TaggingDecrypter : public QuicDecrypter {
StringPiece GetNoncePrefix() const override { return StringPiece(); }
const char* cipher_name() const override { return "Tagging"; }
// Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
- uint32 cipher_id() const override { return 0xFFFFFFF0; }
+ uint32_t cipher_id() const override { return 0xFFFFFFF0; }
protected:
- virtual uint8 GetTag(StringPiece ciphertext) {
- return ciphertext.data()[ciphertext.size()-1];
+ virtual uint8_t GetTag(StringPiece ciphertext) {
+ return ciphertext.data()[ciphertext.size() - 1];
}
private:
@@ -169,7 +169,7 @@ class TaggingDecrypter : public QuicDecrypter {
kTagSize = 12,
};
- bool CheckTag(StringPiece ciphertext, uint8 tag) {
+ bool CheckTag(StringPiece ciphertext, uint8_t tag) {
for (size_t i = ciphertext.size() - kTagSize; i < ciphertext.size(); i++) {
if (ciphertext.data()[i] != tag) {
return false;
@@ -184,27 +184,25 @@ class TaggingDecrypter : public QuicDecrypter {
// match the expected value.
class StrictTaggingDecrypter : public TaggingDecrypter {
public:
- explicit StrictTaggingDecrypter(uint8 tag) : tag_(tag) {}
+ explicit StrictTaggingDecrypter(uint8_t tag) : tag_(tag) {}
~StrictTaggingDecrypter() override {}
// TaggingQuicDecrypter
- uint8 GetTag(StringPiece ciphertext) override { return tag_; }
+ uint8_t GetTag(StringPiece ciphertext) override { return tag_; }
const char* cipher_name() const override { return "StrictTagging"; }
// Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
- uint32 cipher_id() const override { return 0xFFFFFFF1; }
+ uint32_t cipher_id() const override { return 0xFFFFFFF1; }
private:
- const uint8 tag_;
+ const uint8_t tag_;
};
class TestConnectionHelper : public QuicConnectionHelperInterface {
public:
class TestAlarm : public QuicAlarm {
public:
- explicit TestAlarm(QuicAlarm::Delegate* delegate)
- : QuicAlarm(delegate) {
- }
+ explicit TestAlarm(QuicAlarm::Delegate* delegate) : QuicAlarm(delegate) {}
void SetImpl() override {}
void CancelImpl() override {}
@@ -212,8 +210,7 @@ class TestConnectionHelper : public QuicConnectionHelperInterface {
};
TestConnectionHelper(MockClock* clock, MockRandom* random_generator)
- : clock_(clock),
- random_generator_(random_generator) {
+ : clock_(clock), random_generator_(random_generator) {
clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
@@ -226,9 +223,14 @@ class TestConnectionHelper : public QuicConnectionHelperInterface {
return new TestAlarm(delegate);
}
+ QuicBufferAllocator* GetBufferAllocator() override {
+ return &buffer_allocator_;
+ }
+
private:
MockClock* clock_;
MockRandom* random_generator_;
+ SimpleBufferAllocator buffer_allocator_;
DISALLOW_COPY_AND_ASSIGN(TestConnectionHelper);
};
@@ -240,6 +242,7 @@ class TestPacketWriter : public QuicPacketWriter {
framer_(SupportedVersions(version_)),
last_packet_size_(0),
write_blocked_(false),
+ write_should_fail_(false),
block_on_next_write_(false),
is_write_blocked_data_buffered_(false),
final_bytes_of_last_packet_(0),
@@ -275,6 +278,11 @@ class TestPacketWriter : public QuicPacketWriter {
if (IsWriteBlocked()) {
return WriteResult(WRITE_STATUS_BLOCKED, -1);
}
+
+ if (ShouldWriteFail()) {
+ return WriteResult(WRITE_STATUS_ERROR, 0);
+ }
+
last_packet_size_ = packet.length();
if (!write_pause_time_delta_.IsZero()) {
@@ -287,10 +295,14 @@ class TestPacketWriter : public QuicPacketWriter {
return is_write_blocked_data_buffered_;
}
+ bool ShouldWriteFail() { return write_should_fail_; }
+
bool IsWriteBlocked() const override { return write_blocked_; }
void SetWritable() override { write_blocked_ = false; }
+ void SetShouldWriteFail() { write_should_fail_ = true; }
+
QuicByteCount GetMaxPacketSize(
const IPEndPoint& /*peer_address*/) const override {
return max_packet_size_;
@@ -323,7 +335,7 @@ class TestPacketWriter : public QuicPacketWriter {
return framer_.rst_stream_frames();
}
- const vector<QuicStreamFrame>& stream_frames() const {
+ const vector<QuicStreamFrame*>& stream_frames() const {
return framer_.stream_frames();
}
@@ -331,9 +343,7 @@ class TestPacketWriter : public QuicPacketWriter {
return framer_.ping_frames();
}
- size_t last_packet_size() {
- return last_packet_size_;
- }
+ size_t last_packet_size() { return last_packet_size_; }
const QuicVersionNegotiationPacket* version_negotiation_packet() {
return framer_.version_negotiation_packet();
@@ -353,21 +363,19 @@ class TestPacketWriter : public QuicPacketWriter {
}
// final_bytes_of_last_packet_ returns the last four bytes of the previous
- // packet as a little-endian, uint32. This is intended to be used with a
+ // packet as a little-endian, uint32_t. This is intended to be used with a
// TaggingEncrypter so that tests can determine which encrypter was used for
// a given packet.
- uint32 final_bytes_of_last_packet() { return final_bytes_of_last_packet_; }
+ uint32_t final_bytes_of_last_packet() { return final_bytes_of_last_packet_; }
// Returns the final bytes of the second to last packet.
- uint32 final_bytes_of_previous_packet() {
+ uint32_t final_bytes_of_previous_packet() {
return final_bytes_of_previous_packet_;
}
- void use_tagging_decrypter() {
- use_tagging_decrypter_ = true;
- }
+ void use_tagging_decrypter() { use_tagging_decrypter_ = true; }
- uint32 packets_write_attempts() { return packets_write_attempts_; }
+ uint32_t packets_write_attempts() { return packets_write_attempts_; }
void Reset() { framer_.Reset(); }
@@ -384,13 +392,14 @@ class TestPacketWriter : public QuicPacketWriter {
SimpleQuicFramer framer_;
size_t last_packet_size_;
bool write_blocked_;
+ bool write_should_fail_;
bool block_on_next_write_;
bool is_write_blocked_data_buffered_;
- uint32 final_bytes_of_last_packet_;
- uint32 final_bytes_of_previous_packet_;
+ uint32_t final_bytes_of_last_packet_;
+ uint32_t final_bytes_of_previous_packet_;
bool use_tagging_decrypter_;
- uint32 packets_write_attempts_;
- MockClock *clock_;
+ uint32_t packets_write_attempts_;
+ MockClock* clock_;
// If non-zero, the clock will pause during WritePacket for this amount of
// time.
QuicTime::Delta write_pause_time_delta_;
@@ -404,26 +413,23 @@ class TestConnection : public QuicConnection {
TestConnection(QuicConnectionId connection_id,
IPEndPoint address,
TestConnectionHelper* helper,
- const PacketWriterFactory& factory,
+ TestPacketWriter* writer,
Perspective perspective,
QuicVersion version)
: QuicConnection(connection_id,
address,
helper,
- factory,
+ writer,
/* owns_writer= */ false,
perspective,
- /* is_secure= */ false,
SupportedVersions(version)) {
// Disable tail loss probes for most tests.
QuicSentPacketManagerPeer::SetMaxTailLossProbes(
QuicConnectionPeer::GetSentPacketManager(this), 0);
- writer()->set_perspective(perspective);
+ writer->set_perspective(perspective);
}
- void SendAck() {
- QuicConnectionPeer::SendAck(this);
- }
+ void SendAck() { QuicConnectionPeer::SendAck(this); }
void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
@@ -443,16 +449,18 @@ class TestConnection : public QuicConnection {
bool has_pending_frames) {
RetransmittableFrames* retransmittable_frames =
retransmittable == HAS_RETRANSMITTABLE_DATA
- ? new RetransmittableFrames(ENCRYPTION_NONE)
+ ? new RetransmittableFrames()
: nullptr;
char buffer[kMaxPacketSize];
- QuicEncryptedPacket* encrypted =
+ size_t encrypted_length =
QuicConnectionPeer::GetFramer(this)->EncryptPayload(
ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
delete packet;
- OnSerializedPacket(SerializedPacket(
- packet_number, PACKET_6BYTE_PACKET_NUMBER, encrypted, entropy_hash,
- retransmittable_frames, has_ack, has_pending_frames));
+ SerializedPacket serialized_packet(
+ kDefaultPathId, packet_number, PACKET_6BYTE_PACKET_NUMBER, buffer,
+ encrypted_length, false, entropy_hash, retransmittable_frames, has_ack,
+ has_pending_frames, ENCRYPTION_NONE);
+ OnSerializedPacket(&serialized_packet);
}
QuicConsumedData SendStreamDataWithString(
@@ -460,9 +468,9 @@ class TestConnection : public QuicConnection {
StringPiece data,
QuicStreamOffset offset,
bool fin,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* listener) {
return SendStreamDataWithStringHelper(id, data, offset, fin,
- MAY_FEC_PROTECT, delegate);
+ MAY_FEC_PROTECT, listener);
}
QuicConsumedData SendStreamDataWithStringWithFec(
@@ -470,9 +478,9 @@ class TestConnection : public QuicConnection {
StringPiece data,
QuicStreamOffset offset,
bool fin,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* listener) {
return SendStreamDataWithStringHelper(id, data, offset, fin,
- MUST_FEC_PROTECT, delegate);
+ MUST_FEC_PROTECT, listener);
}
QuicConsumedData SendStreamDataWithStringHelper(
@@ -481,11 +489,11 @@ class TestConnection : public QuicConnection {
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* listener) {
struct iovec iov;
QuicIOVector data_iov(MakeIOVector(data, &iov));
return QuicConnection::SendStreamData(id, data_iov, offset, fin,
- fec_protection, delegate);
+ fec_protection, listener);
}
QuicConsumedData SendStreamData3() {
@@ -606,8 +614,7 @@ class TestConnection : public QuicConnection {
};
// Used for testing packets revived from FEC packets.
-class FecQuicConnectionDebugVisitor
- : public QuicConnectionDebugVisitor {
+class FecQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
public:
void OnRevivedPacket(const QuicPacketHeader& header,
StringPiece data) override {
@@ -615,24 +622,12 @@ class FecQuicConnectionDebugVisitor
}
// Public accessor method.
- QuicPacketHeader revived_header() const {
- return revived_header_;
- }
+ QuicPacketHeader revived_header() const { return revived_header_; }
private:
QuicPacketHeader revived_header_;
};
-class MockPacketWriterFactory : public QuicConnection::PacketWriterFactory {
- public:
- explicit MockPacketWriterFactory(QuicPacketWriter* writer) {
- ON_CALL(*this, Create(_)).WillByDefault(Return(writer));
- }
- ~MockPacketWriterFactory() override {}
-
- MOCK_CONST_METHOD1(Create, QuicPacketWriter*(QuicConnection* connection));
-};
-
// Run tests with combinations of {QuicVersion, fec_send_policy}.
struct TestParams {
TestParams(QuicVersion version, FecSendPolicy fec_send_policy)
@@ -666,16 +661,19 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
framer_(SupportedVersions(version()),
QuicTime::Zero(),
Perspective::IS_CLIENT),
- peer_creator_(connection_id_, &framer_, &random_generator_),
send_algorithm_(new StrictMock<MockSendAlgorithm>),
loss_algorithm_(new MockLossAlgorithm()),
helper_(new TestConnectionHelper(&clock_, &random_generator_)),
+ peer_creator_(connection_id_,
+ &framer_,
+ &random_generator_,
+ &buffer_allocator_,
+ /*delegate=*/nullptr),
writer_(new TestPacketWriter(version(), &clock_)),
- factory_(writer_.get()),
connection_(connection_id_,
kPeerAddress,
helper_.get(),
- factory_,
+ writer_.get(),
Perspective::IS_CLIENT,
version()),
creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
@@ -685,6 +683,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
frame2_(1, false, 3, StringPiece(data2)),
packet_number_length_(PACKET_6BYTE_PACKET_NUMBER),
connection_id_length_(PACKET_8BYTE_CONNECTION_ID) {
+ FLAGS_quic_always_log_bugs_for_tests = true;
connection_.set_visitor(&visitor_);
connection_.SetSendAlgorithm(send_algorithm_);
connection_.SetLossAlgorithm(loss_algorithm_);
@@ -718,11 +717,17 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
EXPECT_CALL(*loss_algorithm_, GetLossTimeout())
.WillRepeatedly(Return(QuicTime::Zero()));
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillRepeatedly(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .Times(AnyNumber());
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillRepeatedly(Return(PacketNumberSet()));
+ }
// TODO(ianswett): Fix QuicConnectionTests so they don't attempt to write
// non-crypto stream data at ENCRYPTION_NONE.
FLAGS_quic_never_write_unencrypted_data = false;
+ FLAGS_quic_no_unencrypted_fec = false;
}
QuicVersion version() { return GetParam().version; }
@@ -744,9 +749,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
return writer_->stop_waiting_frames()[0].least_unacked;
}
- void use_tagging_decrypter() {
- writer_->use_tagging_decrypter();
- }
+ void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
void ProcessPacket(QuicPacketNumber number) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -767,43 +770,82 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
return serialized_packet.entropy_hash;
}
+ QuicPacketEntropyHash ProcessFramePacketAtLevel(QuicPacketNumber number,
+ QuicFrame frame,
+ EncryptionLevel level) {
+ QuicPacketHeader header;
+ header.public_header.connection_id = connection_id_;
+ header.public_header.packet_number_length = packet_number_length_;
+ header.public_header.connection_id_length = connection_id_length_;
+ header.packet_number = number;
+ QuicFrames frames;
+ frames.push_back(frame);
+ scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+
+ char buffer[kMaxPacketSize];
+ size_t encrypted_length =
+ framer_.EncryptPayload(level, number, *packet, buffer, kMaxPacketSize);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
+ return base::checked_cast<QuicPacketEntropyHash>(encrypted_length);
+ }
+
size_t ProcessDataPacket(QuicPacketNumber number,
QuicFecGroupNumber fec_group,
bool entropy_flag) {
- return ProcessDataPacketAtLevel(number, fec_group, entropy_flag,
+ return ProcessDataPacketAtLevel(number, fec_group, entropy_flag, false,
ENCRYPTION_NONE);
}
size_t ProcessDataPacketAtLevel(QuicPacketNumber number,
QuicFecGroupNumber fec_group,
bool entropy_flag,
+ bool has_stop_waiting,
EncryptionLevel level) {
- scoped_ptr<QuicPacket> packet(ConstructDataPacket(number, fec_group,
- entropy_flag));
+ scoped_ptr<QuicPacket> packet(
+ ConstructDataPacket(number, fec_group, entropy_flag, has_stop_waiting));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(
- framer_.EncryptPayload(level, number, *packet, buffer, kMaxPacketSize));
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
- return encrypted->length();
+ size_t encrypted_length =
+ framer_.EncryptPayload(level, number, *packet, buffer, kMaxPacketSize);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
+ return encrypted_length;
}
void ProcessClosePacket(QuicPacketNumber number,
QuicFecGroupNumber fec_group) {
scoped_ptr<QuicPacket> packet(ConstructClosePacket(number, fec_group));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, number, *packet, buffer, kMaxPacketSize));
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ size_t encrypted_length = framer_.EncryptPayload(
+ ENCRYPTION_NONE, number, *packet, buffer, kMaxPacketSize);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
}
size_t ProcessFecProtectedPacket(QuicPacketNumber number,
bool expect_revival,
- bool entropy_flag) {
+ bool entropy_flag,
+ bool has_stop_waiting) {
+ return ProcessFecProtectedPacketAtLevel(number, 1, expect_revival,
+ entropy_flag, has_stop_waiting,
+ ENCRYPTION_NONE);
+ }
+
+ size_t ProcessFecProtectedPacketAtLevel(QuicPacketNumber number,
+ QuicFecGroupNumber fec_group,
+ bool expect_revival,
+ bool entropy_flag,
+ bool has_stop_waiting,
+ EncryptionLevel level) {
if (expect_revival) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
}
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1).RetiresOnSaturation();
- return ProcessDataPacket(number, 1, entropy_flag);
+ return ProcessDataPacketAtLevel(number, fec_group, entropy_flag,
+ has_stop_waiting, level);
}
// Processes an FEC packet that covers the packets that would have been
@@ -813,6 +855,18 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
bool expect_revival,
bool entropy_flag,
QuicPacket* packet) {
+ return ProcessFecPacketAtLevel(number, min_protected_packet, expect_revival,
+ entropy_flag, packet, ENCRYPTION_NONE);
+ }
+
+ // Processes an FEC packet that covers the packets that would have been
+ // received.
+ size_t ProcessFecPacketAtLevel(QuicPacketNumber number,
+ QuicPacketNumber min_protected_packet,
+ bool expect_revival,
+ bool entropy_flag,
+ QuicPacket* packet,
+ EncryptionLevel level) {
if (expect_revival) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
}
@@ -824,20 +878,19 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
if (packet) {
data_packet.reset(packet);
} else {
- data_packet.reset(ConstructDataPacket(number, 1, !kEntropyFlag));
+ data_packet.reset(
+ ConstructDataPacket(number, 1, !kEntropyFlag, !kHasStopWaiting));
}
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.packet_number_length = packet_number_length_;
header.public_header.connection_id_length = connection_id_length_;
- header.packet_packet_number = number;
+ header.packet_number = number;
header.entropy_flag = entropy_flag;
header.fec_flag = true;
header.is_in_fec_group = IN_FEC_GROUP;
header.fec_group = min_protected_packet;
- QuicFecData fec_data;
- fec_data.fec_group = header.fec_group;
// Since all data packets in this test have the same payload, the
// redundancy is either equal to that payload or the xor of that payload
@@ -851,15 +904,17 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
data_packet->mutable_data()[i] ^= data_packet->data()[i];
}
}
- fec_data.redundancy = data_packet->FecProtectedData();
- scoped_ptr<QuicPacket> fec_packet(framer_.BuildFecPacket(header, fec_data));
+ scoped_ptr<QuicPacket> fec_packet(
+ framer_.BuildFecPacket(header, data_packet->FecProtectedData()));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, number, *fec_packet, buffer, kMaxPacketSize));
+ size_t encrypted_length = framer_.EncryptPayload(level, number, *fec_packet,
+ buffer, kMaxPacketSize);
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
- return encrypted->length();
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
+ return encrypted_length;
}
QuicByteCount SendStreamDataToPeer(QuicStreamId id,
@@ -899,6 +954,14 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
return ProcessFramePacket(QuicFrame(frame));
}
+ QuicPacketEntropyHash ProcessStopWaitingPacketAtLevel(
+ QuicPacketNumber number,
+ QuicStopWaitingFrame* frame,
+ EncryptionLevel level) {
+ return ProcessFramePacketAtLevel(number, QuicFrame(frame),
+ ENCRYPTION_INITIAL);
+ }
+
QuicPacketEntropyHash ProcessGoAwayPacket(QuicGoAwayFrame* frame) {
return ProcessFramePacket(QuicFrame(frame));
}
@@ -915,18 +978,22 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
QuicPacket* ConstructDataPacket(QuicPacketNumber number,
QuicFecGroupNumber fec_group,
- bool entropy_flag) {
+ bool entropy_flag,
+ bool has_stop_waiting) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.packet_number_length = packet_number_length_;
header.public_header.connection_id_length = connection_id_length_;
header.entropy_flag = entropy_flag;
- header.packet_packet_number = number;
+ header.packet_number = number;
header.is_in_fec_group = fec_group == 0u ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
header.fec_group = fec_group;
QuicFrames frames;
frames.push_back(QuicFrame(&frame1_));
+ if (has_stop_waiting) {
+ frames.push_back(QuicFrame(&stop_waiting_));
+ }
return ConstructPacket(header, frames);
}
@@ -934,7 +1001,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
QuicFecGroupNumber fec_group) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
- header.packet_packet_number = number;
+ header.packet_number = number;
header.is_in_fec_group = fec_group == 0u ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
header.fec_group = fec_group;
@@ -958,9 +1025,8 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
const QuicAckFrame InitAckFrame(QuicPacketNumber largest_observed) {
QuicAckFrame frame(MakeAckFrame(largest_observed));
if (largest_observed > 0) {
- frame.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_,
- largest_observed);
+ frame.entropy_hash = QuicConnectionPeer::GetSentEntropyHash(
+ &connection_, largest_observed);
}
return frame;
}
@@ -1008,29 +1074,27 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> {
}
void CongestionBlockWrites() {
- EXPECT_CALL(*send_algorithm_,
- TimeUntilSend(_, _, _)).WillRepeatedly(
- testing::Return(QuicTime::Delta::FromSeconds(1)));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillRepeatedly(testing::Return(QuicTime::Delta::FromSeconds(1)));
}
void CongestionUnblockWrites() {
- EXPECT_CALL(*send_algorithm_,
- TimeUntilSend(_, _, _)).WillRepeatedly(
- testing::Return(QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
}
QuicConnectionId connection_id_;
QuicFramer framer_;
- QuicPacketCreator peer_creator_;
MockEntropyCalculator entropy_calculator_;
MockSendAlgorithm* send_algorithm_;
MockLossAlgorithm* loss_algorithm_;
MockClock clock_;
MockRandom random_generator_;
+ SimpleBufferAllocator buffer_allocator_;
scoped_ptr<TestConnectionHelper> helper_;
+ QuicPacketCreator peer_creator_;
scoped_ptr<TestPacketWriter> writer_;
- NiceMock<MockPacketWriterFactory> factory_;
TestConnection connection_;
QuicPacketCreator* creator_;
QuicPacketGenerator* generator_;
@@ -1061,7 +1125,7 @@ TEST_P(QuicConnectionTest, MaxPacketSize) {
TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) {
QuicConnectionId connection_id = 42;
TestConnection connection(connection_id, kPeerAddress, helper_.get(),
- factory_, Perspective::IS_SERVER, version());
+ writer_.get(), Perspective::IS_SERVER, version());
EXPECT_EQ(Perspective::IS_SERVER, connection.perspective());
EXPECT_EQ(1000u, connection.max_packet_length());
}
@@ -1075,21 +1139,23 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.version_flag = true;
- header.packet_packet_number = 1;
+ header.packet_number = 1;
QuicFrames frames;
QuicPaddingFrame padding;
frames.push_back(QuicFrame(&frame1_));
- frames.push_back(QuicFrame(&padding));
+ frames.push_back(QuicFrame(padding));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize));
- EXPECT_EQ(kMaxPacketSize, encrypted->length());
+ size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
+ buffer, kMaxPacketSize);
+ EXPECT_EQ(kMaxPacketSize, encrypted_length);
framer_.set_version(version());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
EXPECT_EQ(kMaxPacketSize, connection_.max_packet_length());
}
@@ -1106,21 +1172,23 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.version_flag = true;
- header.packet_packet_number = 1;
+ header.packet_number = 1;
QuicFrames frames;
QuicPaddingFrame padding;
frames.push_back(QuicFrame(&frame1_));
- frames.push_back(QuicFrame(&padding));
+ frames.push_back(QuicFrame(padding));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize));
- EXPECT_EQ(kMaxPacketSize, encrypted->length());
+ size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
+ buffer, kMaxPacketSize);
+ EXPECT_EQ(kMaxPacketSize, encrypted_length);
framer_.set_version(version());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
// Here, the limit imposed by the writer is lower than the size of the packet
// received, so the writer max packet size is used.
@@ -1143,7 +1211,7 @@ TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriterForNewConnection) {
const QuicByteCount lower_max_packet_size = 1240;
writer_->set_max_packet_size(lower_max_packet_size);
TestConnection connection(connection_id, kPeerAddress, helper_.get(),
- factory_, Perspective::IS_CLIENT, version());
+ writer_.get(), Perspective::IS_CLIENT, version());
EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective());
EXPECT_EQ(lower_max_packet_size, connection.max_packet_length());
}
@@ -1230,8 +1298,7 @@ TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
}
TEST_P(QuicConnectionTest, RejectPacketTooFarOut) {
- EXPECT_CALL(visitor_,
- OnConnectionClosed(QUIC_INVALID_PACKET_HEADER, false));
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_PACKET_HEADER, false));
// Call ProcessDataPacket rather than ProcessPacket, as we should not get a
// packet call to the visitor.
ProcessDataPacket(6000, 0, !kEntropyFlag);
@@ -1243,8 +1310,8 @@ TEST_P(QuicConnectionTest, RejectUnencryptedStreamData) {
// Process an unencrypted packet from the non-crypto stream.
frame1_.stream_id = 3;
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_UNENCRYPTED_STREAM_DATA,
- false));
+ EXPECT_CALL(visitor_,
+ OnConnectionClosed(QUIC_UNENCRYPTED_STREAM_DATA, false));
ProcessDataPacket(1, 0, !kEntropyFlag);
EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
nullptr);
@@ -1271,8 +1338,12 @@ TEST_P(QuicConnectionTest, TruncatedAck) {
lost_packets.insert(i * 2);
}
}
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(entropy_calculator_, EntropyHash(511))
.WillOnce(Return(static_cast<QuicPacketEntropyHash>(0)));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
@@ -1285,8 +1356,12 @@ TEST_P(QuicConnectionTest, TruncatedAck) {
// Removing one missing packet allows us to ack 192 and one more range, but
// 192 has already been declared lost, so it doesn't register as an ack.
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&frame);
EXPECT_EQ(num_packets, manager_->largest_observed());
@@ -1297,16 +1372,16 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSendBadEntropy) {
ProcessPacket(1);
// Delay sending, then queue up an ack.
- EXPECT_CALL(*send_algorithm_,
- TimeUntilSend(_, _, _)).WillOnce(
- testing::Return(QuicTime::Delta::FromMicroseconds(1)));
+ if (!FLAGS_quic_respect_send_alarm2) {
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillOnce(testing::Return(QuicTime::Delta::FromMicroseconds(1)));
+ }
QuicConnectionPeer::SendAck(&connection_);
// Process an ack with a least unacked of the received ack.
// This causes an ack to be sent when TimeUntilSend returns 0.
- EXPECT_CALL(*send_algorithm_,
- TimeUntilSend(_, _, _)).WillRepeatedly(
- testing::Return(QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
// Skip a packet and then record an ack.
QuicAckFrame frame = InitAckFrame(0);
ProcessAckPacket(3, &frame);
@@ -1357,16 +1432,23 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
QuicPacketNumber original;
QuicByteCount packet_size;
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(DoAll(SaveArg<2>(&original), SaveArg<3>(&packet_size),
- Return(true)));
+ .WillOnce(
+ DoAll(SaveArg<2>(&original), SaveArg<3>(&packet_size), Return(true)));
connection_.SendStreamDataWithString(3, "foo", 0, !kFin, nullptr);
QuicAckFrame frame = InitAckFrame(original);
NackPacket(original, &frame);
// First nack triggers early retransmit.
- PacketNumberSet lost_packets;
- lost_packets.insert(1);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(1, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
QuicPacketNumber retransmission;
EXPECT_CALL(*send_algorithm_,
@@ -1378,26 +1460,34 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
QuicAckFrame frame2 = InitAckFrame(retransmission);
NackPacket(original, &frame2);
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
ProcessAckPacket(&frame2);
// Now if the peer sends an ack which still reports the retransmitted packet
// as missing, that will bundle an ack with data after two acks in a row
// indicate the high water mark needs to be raised.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _,
- HAS_RETRANSMITTABLE_DATA));
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
connection_.SendStreamDataWithString(3, "foo", 3, !kFin, nullptr);
// No ack sent.
EXPECT_EQ(1u, writer_->frame_count());
EXPECT_EQ(1u, writer_->stream_frames().size());
// No more packet loss for the rest of the test.
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillRepeatedly(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _)).Times(AnyNumber());
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillRepeatedly(Return(PacketNumberSet()));
+ }
ProcessAckPacket(&frame2);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _,
- HAS_RETRANSMITTABLE_DATA));
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
connection_.SendStreamDataWithString(3, "foo", 3, !kFin, nullptr);
// Ack bundled.
EXPECT_EQ(3u, writer_->frame_count());
@@ -1419,13 +1509,14 @@ TEST_P(QuicConnectionTest, 20AcksCausesAckSend) {
// But an ack with no missing packets will not send an ack.
QuicAckFrame frame = InitAckFrame(1);
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillRepeatedly(Return(PacketNumberSet()));
- for (int i = 0; i < 20; ++i) {
- EXPECT_FALSE(ack_alarm->IsSet());
+ for (int i = 0; i < 19; ++i) {
ProcessAckPacket(&frame);
+ EXPECT_FALSE(ack_alarm->IsSet());
}
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_EQ(1u, writer_->packets_write_attempts());
+ // The 20th ack packet will cause an ack to be sent.
+ ProcessAckPacket(&frame);
+ EXPECT_EQ(2u, writer_->packets_write_attempts());
}
TEST_P(QuicConnectionTest, LeastUnackedLower) {
@@ -1541,8 +1632,8 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
writer_->header().public_header.packet_number_length);
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
- Return(kMaxPacketSize * 256));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(kMaxPacketSize * 256));
SendStreamDataToPeer(1, "bar", 3, !kFin, &last_packet);
EXPECT_EQ(2u, last_packet);
@@ -1553,8 +1644,8 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
writer_->header().public_header.packet_number_length);
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
- Return(kMaxPacketSize * 256 * 256));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(kMaxPacketSize * 256 * 256));
SendStreamDataToPeer(1, "foo", 6, !kFin, &last_packet);
EXPECT_EQ(3u, last_packet);
@@ -1563,8 +1654,8 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
writer_->header().public_header.packet_number_length);
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
- Return(kMaxPacketSize * 256 * 256 * 256));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(kMaxPacketSize * 256 * 256 * 256));
SendStreamDataToPeer(1, "bar", 9, !kFin, &last_packet);
EXPECT_EQ(4u, last_packet);
@@ -1573,8 +1664,8 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
writer_->header().public_header.packet_number_length);
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
- Return(kMaxPacketSize * 256 * 256 * 256 * 256));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(kMaxPacketSize * 256 * 256 * 256 * 256));
SendStreamDataToPeer(1, "foo", 12, !kFin, &last_packet);
EXPECT_EQ(5u, last_packet);
@@ -1664,7 +1755,7 @@ TEST_P(QuicConnectionTest, BasicSending) {
ProcessAckPacket(&frame2); // Acks don't instigate acks.
// Verify that we did not send an ack.
- EXPECT_EQ(6u, writer_->header().packet_packet_number);
+ EXPECT_EQ(6u, writer_->header().packet_number);
// So the last ack has not changed.
EXPECT_EQ(4u, least_unacked());
@@ -1731,18 +1822,20 @@ TEST_P(QuicConnectionTest, FECSending) {
if (generator_->fec_send_policy() == FEC_ALARM_TRIGGER) {
// Send 4 protected data packets. FEC packet is not sent.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(4);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(4);
} else {
// Send 4 protected data packets, which should also trigger 1 FEC packet.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(5);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(5);
}
// The first stream frame will have 2 fewer overhead bytes than the other 3.
const string payload(payload_length * 4 + 2, 'a');
connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
// Expect the FEC group to be closed after SendStreamDataWithString.
EXPECT_FALSE(creator_->IsFecGroupOpen());
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicConnectionTest, FECQueueing) {
@@ -1752,14 +1845,14 @@ TEST_P(QuicConnectionTest, FECQueueing) {
connection_.version(), kIncludeVersion, PACKET_8BYTE_CONNECTION_ID,
PACKET_1BYTE_PACKET_NUMBER, IN_FEC_GROUP, &payload_length);
connection_.SetMaxPacketLength(length);
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_EQ(0u, connection_.NumQueuedPackets());
BlockOnNextWrite();
const string payload(payload_length, 'a');
connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
EXPECT_FALSE(creator_->IsFecGroupOpen());
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
if (generator_->fec_send_policy() == FEC_ALARM_TRIGGER) {
// Expect the first data packet to be queued and not the FEC packet.
EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -1770,7 +1863,7 @@ TEST_P(QuicConnectionTest, FECQueueing) {
}
TEST_P(QuicConnectionTest, FECAlarmStoppedWhenFECPacketSent) {
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
@@ -1778,7 +1871,8 @@ TEST_P(QuicConnectionTest, FECAlarmStoppedWhenFECPacketSent) {
// 1 Data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, true, nullptr);
EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
@@ -1786,11 +1880,13 @@ TEST_P(QuicConnectionTest, FECAlarmStoppedWhenFECPacketSent) {
// If FEC send policy is FEC_ALARM_TRIGGER, FEC packet is not sent.
// FEC alarm should not be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
} else {
// Second data packet triggers FEC packet out. FEC alarm should not be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(2);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(2);
}
connection_.SendStreamDataWithStringWithFec(5, "foo", 0, true, nullptr);
if (generator_->fec_send_policy() == FEC_ANY_TRIGGER) {
@@ -1801,13 +1897,14 @@ TEST_P(QuicConnectionTest, FECAlarmStoppedWhenFECPacketSent) {
}
TEST_P(QuicConnectionTest, FECAlarmStoppedOnConnectionClose) {
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
creator_->set_max_packets_per_fec_group(100);
// 1 Data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
@@ -1819,13 +1916,14 @@ TEST_P(QuicConnectionTest, FECAlarmStoppedOnConnectionClose) {
TEST_P(QuicConnectionTest, RemoveFECFromInflightOnRetransmissionTimeout) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
// 1 Data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
size_t protected_packet =
@@ -1833,7 +1931,8 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnRetransmissionTimeout) {
// Force FEC timeout to send FEC packet out.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.GetFecAlarm()->Fire();
EXPECT_TRUE(writer_->header().fec_flag);
@@ -1861,10 +1960,17 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnRetransmissionTimeout) {
QuicAckFrame ack = InitAckFrame(3);
NackPacket(1, &ack);
NackPacket(2, &ack);
- PacketNumberSet lost_packets;
- lost_packets.insert(1);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(1, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&ack);
@@ -1874,12 +1980,13 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnRetransmissionTimeout) {
}
TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
// 1 FEC-protected data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
size_t protected_packet =
@@ -1887,7 +1994,8 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
// Force FEC timeout to send FEC packet out.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.GetFecAlarm()->Fire();
EXPECT_TRUE(writer_->header().fec_flag);
size_t fec_packet = protected_packet;
@@ -1897,7 +2005,8 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
// Send more data to trigger NACKs. Note that all data starts at stream offset
// 0 to ensure the same packet size, for ease of testing.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(4);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(4);
connection_.SendStreamDataWithString(5, "foo", 0, kFin, nullptr);
connection_.SendStreamDataWithString(7, "foo", 0, kFin, nullptr);
connection_.SendStreamDataWithString(9, "foo", 0, kFin, nullptr);
@@ -1913,18 +2022,27 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
// Ack data packets, and NACK FEC packet and one data packet. Triggers
// NACK-based loss detection of both packets, but only data packet is
- // retransmitted and considered oustanding.
+ // retransmitted and considered outstanding.
QuicAckFrame ack = InitAckFrame(6);
NackPacket(2, &ack);
NackPacket(3, &ack);
- PacketNumberSet lost_packets;
- lost_packets.insert(2);
- lost_packets.insert(3);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(2, kMaxPacketSize));
+ lost_packets.push_back(std::make_pair(3, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(2);
+ lost_packets.insert(3);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
ProcessAckPacket(&ack);
// On receiving this ack from the server, the client will no longer send
@@ -1937,9 +2055,12 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
QuicAckFrame ack2 = InitAckFrame(7);
NackPacket(2, &ack2);
NackPacket(3, &ack2);
- PacketNumberSet lost_packets2;
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets2));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&ack2);
EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
@@ -1951,13 +2072,14 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfEarlierData) {
// retransmission alarm fires.
// Turn on TLP for this test.
QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
// 1 Data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
size_t protected_packet =
@@ -1966,7 +2088,8 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfEarlierData) {
// Force FEC timeout to send FEC packet out.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.GetFecAlarm()->Fire();
EXPECT_TRUE(writer_->header().fec_flag);
size_t fec_packet = protected_packet;
@@ -1981,7 +2104,8 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfEarlierData) {
// algorithm's OnRetransmissionTimeout is not called.
clock_.AdvanceTime(retransmission_time.Subtract(clock_.Now()));
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.GetRetransmissionAlarm()->Fire();
// The TLP retransmission of packet 1 will be 3 bytes smaller than packet 1,
// since packet 1 will have 1 byte for FEC group number and 2 bytes of stream
@@ -1997,13 +2121,14 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfLaterData) {
// sent for data packet 2 when the retransmission alarm fires. Turn on TLP for
// this test.
QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
// 1 Data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
size_t protected_packet =
@@ -2012,7 +2137,8 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfLaterData) {
// Force FEC timeout to send FEC packet out.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.GetFecAlarm()->Fire();
EXPECT_TRUE(writer_->header().fec_flag);
// Protected data packet and FEC packet oustanding.
@@ -2022,7 +2148,8 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfLaterData) {
// Send 1 unprotected data packet. No FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithString(5, "foo", 0, kFin, nullptr);
EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
// Protected data packet, FEC packet, and unprotected data packet oustanding.
@@ -2051,7 +2178,8 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfLaterData) {
// algorithm's OnRetransmissionTimeout is not called.
clock_.AdvanceTime(retransmission_time.Subtract(clock_.Now()));
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, 4u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, 4u, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.GetRetransmissionAlarm()->Fire();
// Having received an ack from the server, the client will no longer send
@@ -2064,17 +2192,19 @@ TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfLaterData) {
TEST_P(QuicConnectionTest, NoTLPForFECPacket) {
// Turn on TLP for this test.
QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
- EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
// Send 1 FEC-protected data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
// Force FEC timeout to send FEC packet out.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA))
+ .Times(1);
connection_.GetFecAlarm()->Fire();
EXPECT_TRUE(writer_->header().fec_flag);
@@ -2099,19 +2229,14 @@ TEST_P(QuicConnectionTest, NoTLPForFECPacket) {
}
TEST_P(QuicConnectionTest, FramePacking) {
- CongestionBlockWrites();
-
// Send an ack and two stream frames in 1 packet by queueing them.
- connection_.SendAck();
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData3)),
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData5))));
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- CongestionUnblockWrites();
- connection_.GetSendAlarm()->Fire();
+ {
+ QuicConnection::ScopedPacketBundler bundler(&connection_,
+ QuicConnection::SEND_ACK);
+ connection_.SendStreamData3();
+ connection_.SendStreamData5();
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ }
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
@@ -2121,75 +2246,60 @@ TEST_P(QuicConnectionTest, FramePacking) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
EXPECT_FALSE(writer_->ack_frames().empty());
ASSERT_EQ(2u, writer_->stream_frames().size());
- EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0].stream_id);
- EXPECT_EQ(kClientDataStreamId2, writer_->stream_frames()[1].stream_id);
+ EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
+ EXPECT_EQ(kClientDataStreamId2, writer_->stream_frames()[1]->stream_id);
}
TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) {
- CongestionBlockWrites();
-
// Send an ack and two stream frames (one non-crypto, then one crypto) in 2
// packets by queueing them.
- connection_.SendAck();
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData3)),
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendCryptoStreamData))));
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- CongestionUnblockWrites();
- connection_.GetSendAlarm()->Fire();
+ {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+ QuicConnection::ScopedPacketBundler bundler(&connection_,
+ QuicConnection::SEND_ACK);
+ connection_.SendStreamData3();
+ connection_.SendCryptoStreamData();
+ }
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
// Parse the last packet and ensure it's the crypto stream frame.
EXPECT_EQ(1u, writer_->frame_count());
ASSERT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(kCryptoStreamId, writer_->stream_frames()[0].stream_id);
+ EXPECT_EQ(kCryptoStreamId, writer_->stream_frames()[0]->stream_id);
}
TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
- CongestionBlockWrites();
-
// Send an ack and two stream frames (one crypto, then one non-crypto) in 2
// packets by queueing them.
- connection_.SendAck();
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendCryptoStreamData)),
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData3))));
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- CongestionUnblockWrites();
- connection_.GetSendAlarm()->Fire();
+ {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+ QuicConnection::ScopedPacketBundler bundler(&connection_,
+ QuicConnection::SEND_ACK);
+ connection_.SendCryptoStreamData();
+ connection_.SendStreamData3();
+ }
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
// Parse the last packet and ensure it's the stream frame from stream 3.
EXPECT_EQ(1u, writer_->frame_count());
ASSERT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0].stream_id);
+ EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
}
TEST_P(QuicConnectionTest, FramePackingFEC) {
- EXPECT_TRUE(creator_->IsFecEnabled());
-
- CongestionBlockWrites();
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(creator_));
// Queue an ack and two stream frames. Ack gets flushed when FEC is turned on
// for sending protected data; two stream frames are packed in 1 packet.
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
- IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendStreamData3WithFec)),
- IgnoreResult(InvokeWithoutArgs(
- &connection_, &TestConnection::SendStreamData5WithFec))));
- connection_.SendAck();
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- CongestionUnblockWrites();
- connection_.GetSendAlarm()->Fire();
+ {
+ QuicConnection::ScopedPacketBundler bundler(&connection_,
+ QuicConnection::SEND_ACK);
+ connection_.SendStreamData3WithFec();
+ connection_.SendStreamData5WithFec();
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ }
EXPECT_EQ(0u, connection_.NumQueuedPackets());
EXPECT_FALSE(connection_.HasQueuedData());
@@ -2207,11 +2317,11 @@ TEST_P(QuicConnectionTest, FramePackingAckResponse) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacket(1, 1, kEntropyFlag);
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData3)),
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData5))));
+ EXPECT_CALL(visitor_, OnCanWrite())
+ .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
+ &connection_, &TestConnection::SendStreamData3)),
+ IgnoreResult(InvokeWithoutArgs(
+ &connection_, &TestConnection::SendStreamData5))));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
@@ -2228,8 +2338,8 @@ TEST_P(QuicConnectionTest, FramePackingAckResponse) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
EXPECT_FALSE(writer_->ack_frames().empty());
ASSERT_EQ(2u, writer_->stream_frames().size());
- EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0].stream_id);
- EXPECT_EQ(kClientDataStreamId2, writer_->stream_frames()[1].stream_id);
+ EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
+ EXPECT_EQ(kClientDataStreamId2, writer_->stream_frames()[1]->stream_id);
}
TEST_P(QuicConnectionTest, FramePackingSendv) {
@@ -2253,9 +2363,9 @@ TEST_P(QuicConnectionTest, FramePackingSendv) {
// been packed into a single stream frame from one stream.
EXPECT_EQ(1u, writer_->frame_count());
EXPECT_EQ(1u, writer_->stream_frames().size());
- QuicStreamFrame frame = writer_->stream_frames()[0];
- EXPECT_EQ(1u, frame.stream_id);
- EXPECT_EQ("ABCD", frame.data);
+ QuicStreamFrame* frame = writer_->stream_frames()[0];
+ EXPECT_EQ(1u, frame->stream_id);
+ EXPECT_EQ("ABCD", StringPiece(frame->frame_buffer, frame->frame_length));
}
TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
@@ -2283,7 +2393,7 @@ TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
// Parse the last packet and ensure it's one stream frame from one stream.
EXPECT_EQ(1u, writer_->frame_count());
EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(1u, writer_->stream_frames()[0].stream_id);
+ EXPECT_EQ(1u, writer_->stream_frames()[0]->stream_id);
}
TEST_P(QuicConnectionTest, SendingZeroBytes) {
@@ -2298,21 +2408,20 @@ TEST_P(QuicConnectionTest, SendingZeroBytes) {
// Parse the last packet and ensure it's one stream frame from one stream.
EXPECT_EQ(1u, writer_->frame_count());
EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_EQ(1u, writer_->stream_frames()[0].stream_id);
- EXPECT_TRUE(writer_->stream_frames()[0].fin);
+ EXPECT_EQ(1u, writer_->stream_frames()[0]->stream_id);
+ EXPECT_TRUE(writer_->stream_frames()[0]->fin);
}
TEST_P(QuicConnectionTest, OnCanWrite) {
// Visitor's OnCanWrite will send data, but will have more pending writes.
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData3)),
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendStreamData5))));
+ EXPECT_CALL(visitor_, OnCanWrite())
+ .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
+ &connection_, &TestConnection::SendStreamData3)),
+ IgnoreResult(InvokeWithoutArgs(
+ &connection_, &TestConnection::SendStreamData5))));
EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillOnce(Return(true));
- EXPECT_CALL(*send_algorithm_,
- TimeUntilSend(_, _, _)).WillRepeatedly(
- testing::Return(QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
connection_.OnCanWrite();
@@ -2320,8 +2429,8 @@ TEST_P(QuicConnectionTest, OnCanWrite) {
// two different streams.
EXPECT_EQ(2u, writer_->frame_count());
EXPECT_EQ(2u, writer_->stream_frames().size());
- EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0].stream_id);
- EXPECT_EQ(kClientDataStreamId2, writer_->stream_frames()[1].stream_id);
+ EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
+ EXPECT_EQ(kClientDataStreamId2, writer_->stream_frames()[1]->stream_id);
}
TEST_P(QuicConnectionTest, RetransmitOnNack) {
@@ -2330,7 +2439,7 @@ TEST_P(QuicConnectionTest, RetransmitOnNack) {
SendStreamDataToPeer(3, "foo", 0, !kFin, &last_packet); // Packet 1
second_packet_size =
SendStreamDataToPeer(3, "foos", 3, !kFin, &last_packet); // Packet 2
- SendStreamDataToPeer(3, "fooos", 7, !kFin, &last_packet); // Packet 3
+ SendStreamDataToPeer(3, "fooos", 7, !kFin, &last_packet); // Packet 3
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -2342,14 +2451,21 @@ TEST_P(QuicConnectionTest, RetransmitOnNack) {
// Lose a packet and ensure it triggers retransmission.
QuicAckFrame nack_two = InitAckFrame(3);
NackPacket(2, &nack_two);
- PacketNumberSet lost_packets;
- lost_packets.insert(2);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(2, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(2);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, second_packet_size - kQuicVersionSize, _)).
- Times(1);
+ OnPacketSent(_, _, _, second_packet_size - kQuicVersionSize, _))
+ .Times(1);
ProcessAckPacket(&nack_two);
}
@@ -2361,7 +2477,7 @@ TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) {
connection_.SendStreamDataWithString(stream_id, "foo", 0, !kFin, nullptr);
// Now that there is a queued packet, reset the stream.
- connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14);
+ connection_.SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 14);
// Unblock the connection and verify that only the RST_STREAM is sent.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
@@ -2371,6 +2487,30 @@ TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) {
EXPECT_EQ(1u, writer_->rst_stream_frames().size());
}
+TEST_P(QuicConnectionTest, SendQueuedPacketForQuicRstStreamNoError) {
+ // Block the connection to queue the packet.
+ BlockOnNextWrite();
+
+ QuicStreamId stream_id = 2;
+ connection_.SendStreamDataWithString(stream_id, "foo", 0, !kFin, nullptr);
+
+ // Now that there is a queued packet, reset the stream.
+ connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14);
+
+ // Unblock the connection and verify that the RST_STREAM is sent and the data
+ // packet is sent on QUIC_VERSION_29 or later versions.
+ if (version() > QUIC_VERSION_28) {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .Times(AtLeast(2));
+ } else {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ }
+ writer_->SetWritable();
+ connection_.OnCanWrite();
+ EXPECT_EQ(1u, writer_->frame_count());
+ EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+}
+
TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnNack) {
QuicStreamId stream_id = 2;
QuicPacketNumber last_packet;
@@ -2379,29 +2519,69 @@ TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnNack) {
SendStreamDataToPeer(stream_id, "fooos", 7, !kFin, &last_packet);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14);
+ connection_.SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 14);
// Lose a packet and ensure it does not trigger retransmission.
QuicAckFrame nack_two = InitAckFrame(last_packet);
NackPacket(last_packet - 1, &nack_two);
- PacketNumberSet lost_packets;
- lost_packets.insert(last_packet - 1);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(last_packet - 1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
ProcessAckPacket(&nack_two);
}
-TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) {
+TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnNack) {
QuicStreamId stream_id = 2;
QuicPacketNumber last_packet;
SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_packet);
+ SendStreamDataToPeer(stream_id, "foos", 3, !kFin, &last_packet);
+ SendStreamDataToPeer(stream_id, "fooos", 7, !kFin, &last_packet);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14);
+ // Lose a packet, ensure it triggers retransmission on QUIC_VERSION_29
+ // or later versions.
+ QuicAckFrame nack_two = InitAckFrame(last_packet);
+ NackPacket(last_packet - 1, &nack_two);
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(last_packet - 1, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(last_packet - 1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+ if (version() > QUIC_VERSION_28) {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .Times(AtLeast(1));
+ } else {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+ }
+ ProcessAckPacket(&nack_two);
+}
+
+TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) {
+ QuicStreamId stream_id = 2;
+ QuicPacketNumber last_packet;
+ SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_packet);
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ connection_.SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 14);
+
// Fire the RTO and verify that the RST_STREAM is resent, not stream data.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
clock_.AdvanceTime(DefaultRetransmissionTime());
@@ -2411,6 +2591,29 @@ TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) {
EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
}
+TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnRTO) {
+ QuicStreamId stream_id = 2;
+ QuicPacketNumber last_packet;
+ SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_packet);
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14);
+
+ // Fire the RTO and verify that the RST_STREAM is resent, the stream data
+ // is only sent on QUIC_VERSION_29 or later versions.
+ if (version() > QUIC_VERSION_28) {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .Times(AtLeast(2));
+ } else {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ }
+ clock_.AdvanceTime(DefaultRetransmissionTime());
+ connection_.GetRetransmissionAlarm()->Fire();
+ EXPECT_EQ(1u, writer_->frame_count());
+ EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+ EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+}
+
TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
QuicStreamId stream_id = 2;
QuicPacketNumber last_packet;
@@ -2425,13 +2628,17 @@ TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
PacketNumberSet lost_packets;
lost_packets.insert(last_packet - 1);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
ProcessAckPacket(&ack);
- connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14);
+ connection_.SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 14);
// Unblock the connection and verify that the RST_STREAM is sent but not the
// second data packet nor a retransmit.
@@ -2443,10 +2650,59 @@ TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
}
+TEST_P(QuicConnectionTest, SendPendingRetransmissionForQuicRstStreamNoError) {
+ QuicStreamId stream_id = 2;
+ QuicPacketNumber last_packet;
+ SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_packet);
+ SendStreamDataToPeer(stream_id, "foos", 3, !kFin, &last_packet);
+ BlockOnNextWrite();
+ connection_.SendStreamDataWithString(stream_id, "fooos", 7, !kFin, nullptr);
+
+ // Lose a packet which will trigger a pending retransmission.
+ QuicAckFrame ack = InitAckFrame(last_packet);
+ NackPacket(last_packet - 1, &ack);
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(last_packet - 1, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(last_packet - 1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+ ProcessAckPacket(&ack);
+
+ connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14);
+
+ // Unblock the connection and verify that the RST_STREAM is sent and the
+ // second data packet or a retransmit is only sent on QUIC_VERSION_29 or
+ // later versions.
+ if (version() > QUIC_VERSION_28) {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .Times(AtLeast(2));
+ } else {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ }
+ writer_->SetWritable();
+ connection_.OnCanWrite();
+ EXPECT_EQ(1u, writer_->frame_count());
+ if (version() > QUIC_VERSION_28) {
+ EXPECT_EQ(0u, writer_->rst_stream_frames().size());
+ } else {
+ EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+ EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+ }
+}
+
TEST_P(QuicConnectionTest, DiscardRetransmit) {
QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet); // Packet 1
- SendStreamDataToPeer(1, "foos", 3, !kFin, &last_packet); // Packet 2
+ SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet); // Packet 1
+ SendStreamDataToPeer(1, "foos", 3, !kFin, &last_packet); // Packet 2
SendStreamDataToPeer(1, "fooos", 7, !kFin, &last_packet); // Packet 3
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -2457,25 +2713,36 @@ TEST_P(QuicConnectionTest, DiscardRetransmit) {
// The first nack should trigger a fast retransmission, but we'll be
// write blocked, so the packet will be queued.
BlockOnNextWrite();
- PacketNumberSet lost_packets;
- lost_packets.insert(2);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(2, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(2);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&nack_two);
EXPECT_EQ(1u, connection_.NumQueuedPackets());
// Now, ack the previous transmission.
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
QuicAckFrame ack_all = InitAckFrame(3);
ProcessAckPacket(&ack_all);
// Unblock the socket and attempt to send the queued packets. However,
// since the previous transmission has been acked, we will not
// send the retransmission.
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
writer_->SetWritable();
connection_.OnCanWrite();
@@ -2495,10 +2762,17 @@ TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
QuicAckFrame frame = InitAckFrame(1);
NackPacket(largest_observed, &frame);
// The first nack should retransmit the largest observed packet.
- PacketNumberSet lost_packets;
- lost_packets.insert(1);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(1, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, _, _, packet_size - kQuicVersionSize, _));
@@ -2611,17 +2885,28 @@ TEST_P(QuicConnectionTest, NoLimitPacketsPerNack) {
}
// Ack 15, nack 1-14.
- PacketNumberSet lost_packets;
+
QuicAckFrame nack = InitAckFrame(15);
for (int i = 1; i < 15; ++i) {
NackPacket(i, &nack);
- lost_packets.insert(i);
}
- // 14 packets have been NACK'd and lost. In TCP cubic, PRR limits
- // the retransmission rate in the case of burst losses.
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ // 14 packets have been NACK'd and lost.
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ for (int i = 1; i < 15; ++i) {
+ lost_packets.push_back(std::make_pair(i, kMaxPacketSize));
+ }
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ for (int i = 1; i < 15; ++i) {
+ lost_packets.insert(i);
+ }
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(14);
ProcessAckPacket(&nack);
@@ -2634,7 +2919,7 @@ TEST_P(QuicConnectionTest, MultipleAcks) {
EXPECT_EQ(1u, last_packet);
SendStreamDataToPeer(3, "foo", 0, !kFin, &last_packet); // Packet 2
EXPECT_EQ(2u, last_packet);
- SendAckPacketToPeer(); // Packet 3
+ SendAckPacketToPeer(); // Packet 3
SendStreamDataToPeer(5, "foo", 0, !kFin, &last_packet); // Packet 4
EXPECT_EQ(4u, last_packet);
SendStreamDataToPeer(1, "foo", 3, !kFin, &last_packet); // Packet 5
@@ -2659,7 +2944,7 @@ TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
SendStreamDataToPeer(1, "foo", 0, !kFin, nullptr); // Packet 1;
// From now on, we send acks, so the send algorithm won't mark them pending.
ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillByDefault(Return(false));
+ .WillByDefault(Return(false));
SendAckPacketToPeer(); // Packet 2
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -2692,18 +2977,18 @@ TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
ProcessAckPacket(&frame);
ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillByDefault(Return(true));
+ .WillByDefault(Return(true));
SendStreamDataToPeer(1, "bar", 3, false, nullptr); // Packet 4
EXPECT_EQ(4u, stop_waiting()->least_unacked);
ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillByDefault(Return(false));
+ .WillByDefault(Return(false));
SendAckPacketToPeer(); // Packet 5
EXPECT_EQ(4u, least_unacked());
// Send two data packets at the end, and ensure if the last one is acked,
// the least unacked is raised above the ack packets.
ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillByDefault(Return(true));
+ .WillByDefault(Return(true));
SendStreamDataToPeer(1, "bar", 6, false, nullptr); // Packet 6
SendStreamDataToPeer(1, "bar", 9, false, nullptr); // Packet 7
@@ -2763,10 +3048,9 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketWithVaryingConnectionIdLengths) {
connection_.set_debug_visitor(fec_visitor.get());
QuicPacketNumber fec_packet = 0;
- QuicConnectionIdLength lengths[] = {PACKET_8BYTE_CONNECTION_ID,
- PACKET_4BYTE_CONNECTION_ID,
- PACKET_1BYTE_CONNECTION_ID,
- PACKET_0BYTE_CONNECTION_ID};
+ QuicConnectionIdLength lengths[] = {
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_CONNECTION_ID,
+ PACKET_1BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID};
// For each connection id length size, revive a packet and check connection
// id length in the revived packet.
for (size_t i = 0; i < arraysize(lengths); ++i) {
@@ -2785,7 +3069,7 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketWithVaryingConnectionIdLengths) {
TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacketThenFecPacket) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessFecProtectedPacket(1, false, kEntropyFlag);
+ ProcessFecProtectedPacket(1, false, kEntropyFlag, !kHasStopWaiting);
// Don't send missing packet 2.
ProcessFecPacket(3, 1, true, !kEntropyFlag, nullptr);
// Entropy flag should be true, so entropy should not be 0.
@@ -2795,9 +3079,9 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacketThenFecPacket) {
TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacketsThenFecPacket) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessFecProtectedPacket(1, false, !kEntropyFlag);
+ ProcessFecProtectedPacket(1, false, !kEntropyFlag, !kHasStopWaiting);
// Don't send missing packet 2.
- ProcessFecProtectedPacket(3, false, !kEntropyFlag);
+ ProcessFecProtectedPacket(3, false, !kEntropyFlag, !kHasStopWaiting);
ProcessFecPacket(4, 1, true, kEntropyFlag, nullptr);
// Ensure QUIC no longer revives entropy for lost packets.
EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
@@ -2810,7 +3094,7 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacket) {
// Don't send missing packet 1.
ProcessFecPacket(3, 1, false, !kEntropyFlag, nullptr);
// Out of order.
- ProcessFecProtectedPacket(2, true, !kEntropyFlag);
+ ProcessFecProtectedPacket(2, true, !kEntropyFlag, !kHasStopWaiting);
// Entropy flag should be false, so entropy should be 0.
EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
}
@@ -2818,12 +3102,12 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPacket) {
TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPackets) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessFecProtectedPacket(1, false, !kEntropyFlag);
+ ProcessFecProtectedPacket(1, false, !kEntropyFlag, !kHasStopWaiting);
// Don't send missing packet 2.
ProcessFecPacket(6, 1, false, kEntropyFlag, nullptr);
- ProcessFecProtectedPacket(3, false, kEntropyFlag);
- ProcessFecProtectedPacket(4, false, kEntropyFlag);
- ProcessFecProtectedPacket(5, true, !kEntropyFlag);
+ ProcessFecProtectedPacket(3, false, kEntropyFlag, !kHasStopWaiting);
+ ProcessFecProtectedPacket(4, false, kEntropyFlag, !kHasStopWaiting);
+ ProcessFecProtectedPacket(5, true, !kEntropyFlag, !kHasStopWaiting);
// Ensure entropy is not revived for the missing packet.
EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 3));
@@ -2838,38 +3122,38 @@ TEST_P(QuicConnectionTest, TLP) {
connection_.GetRetransmissionAlarm()->deadline();
EXPECT_NE(QuicTime::Zero(), retransmission_time);
- EXPECT_EQ(1u, writer_->header().packet_packet_number);
+ EXPECT_EQ(1u, writer_->header().packet_number);
// Simulate the retransmission alarm firing and sending a tlp,
// so send algorithm's OnRetransmissionTimeout is not called.
clock_.AdvanceTime(retransmission_time.Subtract(clock_.Now()));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(2u, writer_->header().packet_packet_number);
+ EXPECT_EQ(2u, writer_->header().packet_number);
// We do not raise the high water mark yet.
EXPECT_EQ(1u, stop_waiting()->least_unacked);
}
TEST_P(QuicConnectionTest, RTO) {
- QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
- DefaultRetransmissionTime());
+ QuicTime default_retransmission_time =
+ clock_.ApproximateNow().Add(DefaultRetransmissionTime());
SendStreamDataToPeer(3, "foo", 0, !kFin, nullptr);
EXPECT_EQ(1u, stop_waiting()->least_unacked);
- EXPECT_EQ(1u, writer_->header().packet_packet_number);
+ EXPECT_EQ(1u, writer_->header().packet_number);
EXPECT_EQ(default_retransmission_time,
connection_.GetRetransmissionAlarm()->deadline());
// Simulate the retransmission alarm firing.
clock_.AdvanceTime(DefaultRetransmissionTime());
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(2u, writer_->header().packet_packet_number);
+ EXPECT_EQ(2u, writer_->header().packet_number);
// We do not raise the high water mark yet.
EXPECT_EQ(1u, stop_waiting()->least_unacked);
}
TEST_P(QuicConnectionTest, RTOWithSameEncryptionLevel) {
- QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
- DefaultRetransmissionTime());
+ QuicTime default_retransmission_time =
+ clock_.ApproximateNow().Add(DefaultRetransmissionTime());
use_tagging_decrypter();
// A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
@@ -2909,9 +3193,8 @@ TEST_P(QuicConnectionTest, SendHandshakeMessages) {
connection_.SetEncrypter(ENCRYPTION_NONE, new TaggingEncrypter(0x01));
// Attempt to send a handshake message and have the socket block.
- EXPECT_CALL(*send_algorithm_,
- TimeUntilSend(_, _, _)).WillRepeatedly(
- testing::Return(QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
BlockOnNextWrite();
connection_.SendStreamDataWithString(1, "foo", 0, !kFin, nullptr);
// The packet should be serialized, but not queued.
@@ -2949,8 +3232,7 @@ TEST_P(QuicConnectionTest,
connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
connection_.NeuterUnencryptedPackets();
- EXPECT_EQ(QuicTime::Zero(),
- connection_.GetRetransmissionAlarm()->deadline());
+ EXPECT_EQ(QuicTime::Zero(), connection_.GetRetransmissionAlarm()->deadline());
// Unblock the socket and ensure that no packets are sent.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
writer_->SetWritable();
@@ -2999,8 +3281,8 @@ TEST_P(QuicConnectionTest, DelayForwardSecureEncryptionUntilClientIsReady) {
TEST_P(QuicConnectionTest, DelayForwardSecureEncryptionUntilManyPacketSent) {
// Set a congestion window of 10 packets.
QuicPacketCount congestion_window = 10;
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
- Return(congestion_window * kDefaultMaxPacketSize));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(congestion_window * kDefaultMaxPacketSize));
// A TaggingEncrypter puts kTagSize copies of the given byte (0x02 here) at
// the end of the packet. We can test this to check which encrypter was used.
@@ -3019,7 +3301,7 @@ TEST_P(QuicConnectionTest, DelayForwardSecureEncryptionUntilManyPacketSent) {
// Now send a packet "Far enough" after the encrypter was set and verify that
// the forward-secure encrypter is now used.
- for (uint64 i = 0; i < 3 * congestion_window - 1; ++i) {
+ for (uint64_t i = 0; i < 3 * congestion_window - 1; ++i) {
EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
SendAckPacketToPeer();
}
@@ -3034,12 +3316,13 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
use_tagging_decrypter();
- const uint8 tag = 0x07;
+ const uint8_t tag = 0x07;
framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
// Process an encrypted packet which can not yet be decrypted which should
// result in the packet being buffered.
- ProcessDataPacketAtLevel(1, 0, kEntropyFlag, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(1, 0, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
// Transition to the new encryption state and process another encrypted packet
// which should result in the original packet being processed.
@@ -3047,12 +3330,52 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
- ProcessDataPacketAtLevel(2, 0, kEntropyFlag, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(2, 0, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
// Finally, process a third packet and note that we do not reprocess the
// buffered packet.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(3, 0, kEntropyFlag, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(3, 0, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
+}
+
+TEST_P(QuicConnectionTest, ProcessBufferedFECGroup) {
+ // SetFromConfig is always called after construction from InitializeSession.
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ config.set_max_undecryptable_packets(100);
+ connection_.SetFromConfig(config);
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ use_tagging_decrypter();
+
+ const uint8_t tag = 0x07;
+ framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+
+ // Don't send packet 1 and buffer initially encrypted packets.
+ ProcessFecProtectedPacketAtLevel(2, 1, false, !kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
+ ProcessFecPacketAtLevel(3, 1, false, kEntropyFlag, nullptr,
+ ENCRYPTION_INITIAL);
+ // Since the packets were buffered, no FEC group should be open.
+ ASSERT_EQ(0u, connection_.NumFecGroups());
+
+ // Now send non-fec protected ack packet and close the group.
+ QuicStopWaitingFrame frame = InitStopWaitingFrame(4);
+ ProcessStopWaitingPacketAtLevel(4, &frame, ENCRYPTION_INITIAL);
+
+ // Transition to the new encryption state and process another encrypted packet
+ // which should result in the original packets being processed. The missing
+ // packet should be revived before the STOP_WAITING packet is processed.
+ connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2).RetiresOnSaturation();
+ ProcessDataPacketAtLevel(5, 0, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
+ const QuicConnectionStats& stats = connection_.GetStats();
+ EXPECT_EQ(1u, stats.packets_revived);
}
TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
@@ -3064,13 +3387,14 @@ TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
use_tagging_decrypter();
- const uint8 tag = 0x07;
+ const uint8_t tag = 0x07;
framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
// Process an encrypted packet which can not yet be decrypted which should
// result in the packet being buffered.
for (QuicPacketNumber i = 1; i <= 100; ++i) {
- ProcessDataPacketAtLevel(i, 0, kEntropyFlag, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(i, 0, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
}
// Transition to the new encryption state and process another encrypted packet
@@ -3079,33 +3403,33 @@ TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(101);
- ProcessDataPacketAtLevel(101, 0, kEntropyFlag, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(101, 0, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
// Finally, process a third packet and note that we do not reprocess the
// buffered packet.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(102, 0, kEntropyFlag, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(102, 0, kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
}
TEST_P(QuicConnectionTest, TestRetransmitOrder) {
QuicByteCount first_packet_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillOnce(
- DoAll(SaveArg<3>(&first_packet_size), Return(true)));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<3>(&first_packet_size), Return(true)));
connection_.SendStreamDataWithString(3, "first_packet", 0, !kFin, nullptr);
QuicByteCount second_packet_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillOnce(
- DoAll(SaveArg<3>(&second_packet_size), Return(true)));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<3>(&second_packet_size), Return(true)));
connection_.SendStreamDataWithString(3, "second_packet", 12, !kFin, nullptr);
EXPECT_NE(first_packet_size, second_packet_size);
// Advance the clock by huge time to make sure packets will be retransmitted.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
{
InSequence s;
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, first_packet_size, _));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, second_packet_size, _));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
}
connection_.GetRetransmissionAlarm()->Fire();
@@ -3113,10 +3437,8 @@ TEST_P(QuicConnectionTest, TestRetransmitOrder) {
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
{
InSequence s;
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, first_packet_size, _));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, second_packet_size, _));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
}
connection_.GetRetransmissionAlarm()->Fire();
}
@@ -3135,8 +3457,7 @@ TEST_P(QuicConnectionTest, SetRTOAfterWritingToSocket) {
TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(2);
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
connection_.SendStreamDataWithString(2, "foo", 0, !kFin, nullptr);
connection_.SendStreamDataWithString(3, "bar", 0, !kFin, nullptr);
QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
@@ -3188,7 +3509,7 @@ TEST_P(QuicConnectionTest, CloseFecGroup) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
// Don't send missing packet 1.
// Don't send missing packet 2.
- ProcessFecProtectedPacket(3, false, !kEntropyFlag);
+ ProcessFecProtectedPacket(3, false, !kEntropyFlag, !kHasStopWaiting);
// Don't send missing FEC packet 3.
ASSERT_EQ(1u, connection_.NumFecGroups());
@@ -3199,6 +3520,46 @@ TEST_P(QuicConnectionTest, CloseFecGroup) {
ASSERT_EQ(0u, connection_.NumFecGroups());
}
+TEST_P(QuicConnectionTest, FailedToCloseFecGroupWithFecProtectedStopWaiting) {
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ ValueRestore<bool> old_flag(&FLAGS_quic_drop_non_awaited_packets, false);
+ // Don't send missing packet 1.
+ ProcessFecProtectedPacket(2, false, !kEntropyFlag, !kHasStopWaiting);
+ EXPECT_EQ(1u, connection_.NumFecGroups());
+ stop_waiting_ = InitStopWaitingFrame(3);
+ ProcessFecProtectedPacket(3, false, !kEntropyFlag, kHasStopWaiting);
+ // This Fec group would be closed but created again.
+ EXPECT_EQ(1u, connection_.NumFecGroups());
+}
+
+TEST_P(QuicConnectionTest,
+ CloseFecGroupUnderStopWaitingAndWaitingForPacketsBelowStopWaiting) {
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ ValueRestore<bool> old_flag(&FLAGS_quic_drop_non_awaited_packets, true);
+ // Don't send missing packet 1.
+ ProcessFecProtectedPacket(2, false, !kEntropyFlag, !kHasStopWaiting);
+ EXPECT_EQ(1u, connection_.NumFecGroups());
+ stop_waiting_ = InitStopWaitingFrame(2);
+ ProcessFecProtectedPacket(3, false, !kEntropyFlag, kHasStopWaiting);
+ // This Fec group would be closed.
+ EXPECT_EQ(0u, connection_.NumFecGroups());
+}
+
+TEST_P(QuicConnectionTest,
+ DoNotCloseFecGroupUnderStopWaitingButNotWaitingForPacketsBelow) {
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ ValueRestore<bool> old_flag(&FLAGS_quic_drop_non_awaited_packets, true);
+ ProcessFecProtectedPacket(1, false, !kEntropyFlag, !kHasStopWaiting);
+ ProcessFecProtectedPacket(2, false, !kEntropyFlag, !kHasStopWaiting);
+ // Don't send missing packet 3.
+ EXPECT_EQ(1u, connection_.NumFecGroups());
+ stop_waiting_ = InitStopWaitingFrame(2);
+ ProcessFecProtectedPacket(3, false, !kEntropyFlag, kHasStopWaiting);
+ // This group will not be closed because this group is not waiting for packets
+ // below stop waiting.
+ EXPECT_EQ(1u, connection_.NumFecGroups());
+}
+
TEST_P(QuicConnectionTest, InitialTimeout) {
EXPECT_TRUE(connection_.connected());
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
@@ -3215,8 +3576,7 @@ TEST_P(QuicConnectionTest, InitialTimeout) {
EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
// Simulate the timeout alarm firing.
- clock_.AdvanceTime(
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1));
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1));
connection_.GetTimeoutAlarm()->Fire();
EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
@@ -3298,7 +3658,8 @@ TEST_P(QuicConnectionTest, PingAfterSend) {
EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
// The ping timer is set slightly less than 15 seconds in the future, because
// of the 1s ping timer alarm granularity.
- EXPECT_EQ(clock_.ApproximateNow().Add(QuicTime::Delta::FromSeconds(15))
+ EXPECT_EQ(clock_.ApproximateNow()
+ .Add(QuicTime::Delta::FromSeconds(15))
.Subtract(QuicTime::Delta::FromMilliseconds(5)),
connection_.GetPingAlarm()->deadline());
@@ -3547,7 +3908,8 @@ TEST_P(QuicConnectionTest, NoMtuDiscoveryAfterConnectionClosed) {
EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
}
-TEST_P(QuicConnectionTest, TimeoutAfterSend) {
+TEST_P(QuicConnectionTest, OldTimeoutAfterSend) {
+ ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, false);
EXPECT_TRUE(connection_.connected());
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
QuicConfig config;
@@ -3587,7 +3949,8 @@ TEST_P(QuicConnectionTest, TimeoutAfterSend) {
EXPECT_FALSE(connection_.connected());
}
-TEST_P(QuicConnectionTest, TimeoutAfterSendSilentClose) {
+TEST_P(QuicConnectionTest, OldTimeoutAfterSendSilentClose) {
+ ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, false);
// Same test as above, but complete a handshake which enables silent close,
// causing no connection close packet to be sent.
EXPECT_TRUE(connection_.connected());
@@ -3645,17 +4008,244 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendSilentClose) {
EXPECT_FALSE(connection_.connected());
}
+TEST_P(QuicConnectionTest, TimeoutAfterSend) {
+ ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ connection_.SetFromConfig(config);
+ EXPECT_FALSE(QuicConnectionPeer::IsSilentCloseEnabled(&connection_));
+
+ const QuicTime::Delta initial_idle_timeout =
+ QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+ const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+ QuicTime default_timeout = clock_.ApproximateNow().Add(initial_idle_timeout);
+
+ // When we send a packet, the timeout will change to 5ms +
+ // kInitialIdleTimeoutSecs.
+ clock_.AdvanceTime(five_ms);
+ SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, kFin, nullptr);
+ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+ // Now send more data. This will not move the timeout becase
+ // no data has been recieved since the previous write.
+ clock_.AdvanceTime(five_ms);
+ SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, kFin, nullptr);
+ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+ // The original alarm will fire. We should not time out because we had a
+ // network event at t=5ms. The alarm will reregister.
+ clock_.AdvanceTime(initial_idle_timeout.Subtract(five_ms).Subtract(five_ms));
+ EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+ connection_.GetTimeoutAlarm()->Fire();
+ EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_EQ(default_timeout.Add(five_ms).Add(five_ms),
+ connection_.GetTimeoutAlarm()->deadline());
+
+ // This time, we should time out.
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+ clock_.AdvanceTime(five_ms);
+ EXPECT_EQ(default_timeout.Add(five_ms), clock_.ApproximateNow());
+ connection_.GetTimeoutAlarm()->Fire();
+ EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+ EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, NewTimeoutAfterSendSilentClose) {
+ ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
+ // Same test as above, but complete a handshake which enables silent close,
+ // causing no connection close packet to be sent.
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+
+ // Create a handshake message that also enables silent close.
+ CryptoHandshakeMessage msg;
+ string error_details;
+ QuicConfig client_config;
+ client_config.SetInitialStreamFlowControlWindowToSend(
+ kInitialStreamFlowControlWindowForTest);
+ client_config.SetInitialSessionFlowControlWindowToSend(
+ kInitialSessionFlowControlWindowForTest);
+ client_config.SetIdleConnectionStateLifetime(
+ QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs),
+ QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs));
+ client_config.ToHandshakeMessage(&msg);
+ const QuicErrorCode error =
+ config.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+
+ connection_.SetFromConfig(config);
+ EXPECT_TRUE(QuicConnectionPeer::IsSilentCloseEnabled(&connection_));
+
+ const QuicTime::Delta default_idle_timeout =
+ QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs - 1);
+ const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+ QuicTime default_timeout = clock_.ApproximateNow().Add(default_idle_timeout);
+
+ // When we send a packet, the timeout will change to 5ms +
+ // kInitialIdleTimeoutSecs.
+ clock_.AdvanceTime(five_ms);
+ SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, kFin, nullptr);
+ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+ // Now send more data. This will not move the timeout becase
+ // no data has been recieved since the previous write.
+ clock_.AdvanceTime(five_ms);
+ SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, kFin, nullptr);
+ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+ // The original alarm will fire. We should not time out because we had a
+ // network event at t=5ms. The alarm will reregister.
+ clock_.AdvanceTime(default_idle_timeout.Subtract(five_ms).Subtract(five_ms));
+ EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+ connection_.GetTimeoutAlarm()->Fire();
+ EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_EQ(default_timeout.Add(five_ms).Add(five_ms),
+ connection_.GetTimeoutAlarm()->deadline());
+
+ // This time, we should time out.
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
+ clock_.AdvanceTime(five_ms);
+ EXPECT_EQ(default_timeout.Add(five_ms), clock_.ApproximateNow());
+ connection_.GetTimeoutAlarm()->Fire();
+ EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+ EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterReceive) {
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ connection_.SetFromConfig(config);
+ EXPECT_FALSE(QuicConnectionPeer::IsSilentCloseEnabled(&connection_));
+
+ const QuicTime::Delta initial_idle_timeout =
+ QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+ const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+ QuicTime default_timeout = clock_.ApproximateNow().Add(initial_idle_timeout);
+
+ connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 0, !kFin,
+ nullptr);
+ connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 3, !kFin,
+ nullptr);
+
+ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+ clock_.AdvanceTime(five_ms);
+
+ // When we receive a packet, the timeout will change to 5ms +
+ // kInitialIdleTimeoutSecs.
+ QuicAckFrame ack = InitAckFrame(2);
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+ ProcessAckPacket(&ack);
+
+ // The original alarm will fire. We should not time out because we had a
+ // network event at t=5ms. The alarm will reregister.
+ clock_.AdvanceTime(initial_idle_timeout.Subtract(five_ms));
+ EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+ connection_.GetTimeoutAlarm()->Fire();
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+ EXPECT_EQ(default_timeout.Add(five_ms),
+ connection_.GetTimeoutAlarm()->deadline());
+
+ // This time, we should time out.
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+ clock_.AdvanceTime(five_ms);
+ EXPECT_EQ(default_timeout.Add(five_ms), clock_.ApproximateNow());
+ connection_.GetTimeoutAlarm()->Fire();
+ EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+ EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
+ ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ connection_.SetFromConfig(config);
+ EXPECT_FALSE(QuicConnectionPeer::IsSilentCloseEnabled(&connection_));
+
+ const QuicTime::Delta initial_idle_timeout =
+ QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+ connection_.SetNetworkTimeouts(
+ QuicTime::Delta::Infinite(),
+ initial_idle_timeout.Add(QuicTime::Delta::FromSeconds(1)));
+ const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+ QuicTime default_timeout = clock_.ApproximateNow().Add(initial_idle_timeout);
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+ connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 0, !kFin,
+ nullptr);
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+ connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 3, !kFin,
+ nullptr);
+
+ EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+ clock_.AdvanceTime(five_ms);
+
+ // When we receive a packet, the timeout will change to 5ms +
+ // kInitialIdleTimeoutSecs.
+ QuicAckFrame ack = InitAckFrame(2);
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+ ProcessAckPacket(&ack);
+
+ // The original alarm will fire. We should not time out because we had a
+ // network event at t=5ms. The alarm will reregister.
+ clock_.AdvanceTime(initial_idle_timeout.Subtract(five_ms));
+ EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+ connection_.GetTimeoutAlarm()->Fire();
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+ EXPECT_EQ(default_timeout.Add(five_ms),
+ connection_.GetTimeoutAlarm()->deadline());
+
+ // Now, send packets while advancing the time and verify that the connection
+ // eventually times out.
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+ for (int i = 0; i < 100 && connection_.connected(); ++i) {
+ VLOG(1) << "sending data packet";
+ connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 0, !kFin,
+ nullptr);
+ connection_.GetTimeoutAlarm()->Fire();
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ }
+ EXPECT_FALSE(connection_.connected());
+ EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+}
+
TEST_P(QuicConnectionTest, SendScheduler) {
// Test that if we send a packet without delay, it is not queued.
- QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
+ QuicPacket* packet =
+ ConstructDataPacket(1, 0, !kEntropyFlag, !kHasStopWaiting);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
connection_.SendPacket(ENCRYPTION_NONE, 1, packet, kTestEntropyHash,
HAS_RETRANSMITTABLE_DATA, false, false);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
}
+TEST_P(QuicConnectionTest, FailToSendFirstPacket) {
+ // Test that the connection does not crash when it fails to send the first
+ // packet at which point self_address_ might be uninitialized.
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
+ QuicPacket* packet =
+ ConstructDataPacket(1, 0, !kEntropyFlag, !kHasStopWaiting);
+ writer_->SetShouldWriteFail();
+ connection_.SendPacket(ENCRYPTION_NONE, 1, packet, kTestEntropyHash,
+ HAS_RETRANSMITTABLE_DATA, false, false);
+}
+
TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
- QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
+ QuicPacket* packet =
+ ConstructDataPacket(1, 0, !kEntropyFlag, !kHasStopWaiting);
BlockOnNextWrite();
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
connection_.SendPacket(ENCRYPTION_NONE, 1, packet, kTestEntropyHash,
@@ -3672,12 +4262,12 @@ TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
connection_.SetMaxPacketLength(length);
// Queue the first packet.
- EXPECT_CALL(*send_algorithm_,
- TimeUntilSend(_, _, _)).WillOnce(
- testing::Return(QuicTime::Delta::FromMicroseconds(10)));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillOnce(testing::Return(QuicTime::Delta::FromMicroseconds(10)));
const string payload(payload_length, 'a');
- EXPECT_EQ(0u, connection_.SendStreamDataWithString(3, payload, 0, !kFin,
- nullptr).bytes_consumed);
+ EXPECT_EQ(0u,
+ connection_.SendStreamDataWithString(3, payload, 0, !kFin, nullptr)
+ .bytes_consumed);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
}
@@ -3713,8 +4303,8 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
// Now send some packets with no truncation.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
EXPECT_EQ(payload.size(),
- connection_.SendStreamDataWithString(
- 3, payload, 0, !kFin, nullptr).bytes_consumed);
+ connection_.SendStreamDataWithString(3, payload, 0, !kFin, nullptr)
+ .bytes_consumed);
// Track the size of the second packet here. The overhead will be the largest
// we see in this test, due to the non-truncated connection id.
size_t non_truncated_packet_size = writer_->last_packet_size();
@@ -3725,8 +4315,8 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
connection_.SetFromConfig(config);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
EXPECT_EQ(payload.size(),
- connection_.SendStreamDataWithString(
- 3, payload, 0, !kFin, nullptr).bytes_consumed);
+ connection_.SendStreamDataWithString(3, payload, 0, !kFin, nullptr)
+ .bytes_consumed);
// Verify that we have 8 fewer bytes than in the non-truncated case. The
// first packet got 4 bytes of extra payload due to the truncation, and the
// headers here are also 4 byte smaller.
@@ -3737,8 +4327,8 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
connection_.SetFromConfig(config);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
EXPECT_EQ(payload.size(),
- connection_.SendStreamDataWithString(
- 3, payload, 0, !kFin, nullptr).bytes_consumed);
+ connection_.SendStreamDataWithString(3, payload, 0, !kFin, nullptr)
+ .bytes_consumed);
// Just like above, we save 7 bytes on payload, and 7 on truncation.
EXPECT_EQ(non_truncated_packet_size, writer_->last_packet_size() + 7 * 2);
@@ -3747,8 +4337,8 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
connection_.SetFromConfig(config);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
EXPECT_EQ(payload.size(),
- connection_.SendStreamDataWithString(
- 3, payload, 0, !kFin, nullptr).bytes_consumed);
+ connection_.SendStreamDataWithString(3, payload, 0, !kFin, nullptr)
+ .bytes_consumed);
// Just like above, we save 8 bytes on payload, and 8 on truncation.
EXPECT_EQ(non_truncated_packet_size, writer_->last_packet_size() + 8 * 2);
}
@@ -3757,7 +4347,7 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
QuicTime ack_time = clock_.ApproximateNow().Add(DefaultDelayedAckTime());
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
- const uint8 tag = 0x07;
+ const uint8_t tag = 0x07;
connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
// Process a packet from the non-crypto stream.
@@ -3766,7 +4356,8 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
// The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
// instead of ENCRYPTION_NONE.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
- ProcessDataPacketAtLevel(1, 0, !kEntropyFlag, ENCRYPTION_INITIAL);
+ ProcessDataPacketAtLevel(1, 0, !kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
// Check if delayed ack timer is running for the expected interval.
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3780,6 +4371,57 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
}
+TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
+ QuicConnectionPeer::EnableAckDecimation(&connection_);
+
+ const size_t kMinRttMs = 40;
+ RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(manager_);
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ // The ack time should be based on min_rtt/4, since it's less than the
+ // default delayed ack time.
+ QuicTime ack_time = clock_.ApproximateNow().Add(
+ QuicTime::Delta::FromMilliseconds(kMinRttMs / 4));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ const uint8_t tag = 0x07;
+ connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
+ framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ // Process a packet from the non-crypto stream.
+ frame1_.stream_id = 3;
+
+ // Process all the initial packets in order so there aren't missing packets.
+ QuicPacketNumber kFirstDecimatedPacket = 101;
+ for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(1 + i, 0, !kEntropyFlag, !kHasStopWaiting,
+ ENCRYPTION_INITIAL);
+ }
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
+ // instead of ENCRYPTION_NONE.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kFirstDecimatedPacket, 0, !kEntropyFlag,
+ !kHasStopWaiting, ENCRYPTION_INITIAL);
+
+ // Check if delayed ack timer is running for the expected interval.
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+ // The 10th received packet causes an ack to be sent.
+ for (int i = 0; i < 9; ++i) {
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, 0, !kEntropyFlag,
+ !kHasStopWaiting, ENCRYPTION_INITIAL);
+ }
+ // Check that ack is sent and that delayed ack alarm is reset.
+ EXPECT_EQ(2u, writer_->frame_count());
+ EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+}
+
TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
ProcessPacket(1);
@@ -3880,9 +4522,9 @@ TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(
- IgnoreResult(InvokeWithoutArgs(&connection_,
- &TestConnection::SendCryptoStreamData)));
+ EXPECT_CALL(visitor_, OnCanWrite())
+ .WillOnce(IgnoreResult(InvokeWithoutArgs(
+ &connection_, &TestConnection::SendCryptoStreamData)));
// Process a packet from the crypto stream, which is frame1_'s default.
// Receiving the CHLO as packet 2 first will cause the connection to
// immediately send an ack, due to the packet gap.
@@ -3904,10 +4546,17 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
// Ack the second packet, which will retransmit the first packet.
QuicAckFrame ack = InitAckFrame(2);
NackPacket(1, &ack);
- PacketNumberSet lost_packets;
- lost_packets.insert(1);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(1, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&ack);
EXPECT_EQ(1u, writer_->frame_count());
@@ -3918,8 +4567,12 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
// and see if there is more data to send.
ack = InitAckFrame(3);
NackPacket(1, &ack);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&ack);
@@ -3931,12 +4584,15 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
// Send the same ack, but send both data and an ack together.
ack = InitAckFrame(3);
NackPacket(1, &ack);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(PacketNumberSet()));
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(
- IgnoreResult(InvokeWithoutArgs(
- &connection_,
- &TestConnection::EnsureWritableAndSendStreamData5)));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
+ EXPECT_CALL(visitor_, OnCanWrite())
+ .WillOnce(IgnoreResult(InvokeWithoutArgs(
+ &connection_, &TestConnection::EnsureWritableAndSendStreamData5)));
ProcessAckPacket(&ack);
// Check that ack is bundled with outgoing data and the delayed ack
@@ -3962,7 +4618,8 @@ TEST_P(QuicConnectionTest, SendWhenDisconnected) {
connection_.CloseConnection(QUIC_PEER_GOING_AWAY, false);
EXPECT_FALSE(connection_.connected());
EXPECT_FALSE(connection_.CanWriteStreamData());
- QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
+ QuicPacket* packet =
+ ConstructDataPacket(1, 0, !kEntropyFlag, !kHasStopWaiting);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
connection_.SendPacket(ENCRYPTION_NONE, 1, packet, kTestEntropyHash,
HAS_RETRANSMITTABLE_DATA, false, false);
@@ -4109,8 +4766,8 @@ TEST_P(QuicConnectionTest, EntropyCalculationForTruncatedAck) {
ProcessDataPacket(i, 1, entropy_flag);
}
for (int i = 1; i < 50; ++i) {
- EXPECT_EQ(entropy[i], QuicConnectionPeer::ReceivedEntropyHash(
- &connection_, i));
+ EXPECT_EQ(entropy[i],
+ QuicConnectionPeer::ReceivedEntropyHash(&connection_, i));
}
}
@@ -4121,18 +4778,20 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacket) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.version_flag = true;
- header.packet_packet_number = 12;
+ header.packet_number = 12;
QuicFrames frames;
frames.push_back(QuicFrame(&frame1_));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize));
+ size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
+ buffer, kMaxPacketSize);
framer_.set_version(version());
connection_.set_perspective(Perspective::IS_SERVER);
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
EXPECT_TRUE(writer_->version_negotiation_packet() != nullptr);
size_t num_versions = arraysize(kSupportedQuicVersions);
@@ -4154,19 +4813,21 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.version_flag = true;
- header.packet_packet_number = 12;
+ header.packet_number = 12;
QuicFrames frames;
frames.push_back(QuicFrame(&frame1_));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize));
+ size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
+ buffer, kMaxPacketSize);
framer_.set_version(version());
connection_.set_perspective(Perspective::IS_SERVER);
BlockOnNextWrite();
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
EXPECT_EQ(0u, writer_->last_packet_size());
EXPECT_TRUE(connection_.HasQueuedData());
@@ -4194,80 +4855,67 @@ TEST_P(QuicConnectionTest,
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.version_flag = true;
- header.packet_packet_number = 12;
+ header.packet_number = 12;
QuicFrames frames;
frames.push_back(QuicFrame(&frame1_));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize));
+ size_t encryped_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
+ buffer, kMaxPacketSize);
framer_.set_version(version());
connection_.set_perspective(Perspective::IS_SERVER);
BlockOnNextWrite();
writer_->set_is_write_blocked_data_buffered(true);
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encryped_length, false));
EXPECT_EQ(0u, writer_->last_packet_size());
EXPECT_FALSE(connection_.HasQueuedData());
}
TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
// Start out with some unsupported version.
- QuicConnectionPeer::GetFramer(&connection_)->set_version_for_tests(
- QUIC_VERSION_UNSUPPORTED);
-
- QuicPacketHeader header;
- header.public_header.connection_id = connection_id_;
- header.public_header.version_flag = true;
- header.packet_packet_number = 12;
-
- QuicVersionVector supported_versions;
- for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
- supported_versions.push_back(kSupportedQuicVersions[i]);
- }
+ QuicConnectionPeer::GetFramer(&connection_)
+ ->set_version_for_tests(QUIC_VERSION_UNSUPPORTED);
// Send a version negotiation packet.
scoped_ptr<QuicEncryptedPacket> encrypted(
- framer_.BuildVersionNegotiationPacket(
- header.public_header, supported_versions));
+ framer_.BuildVersionNegotiationPacket(connection_id_,
+ QuicSupportedVersions()));
connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
// Now force another packet. The connection should transition into
// NEGOTIATED_VERSION state and tell the packet creator to StopSendingVersion.
+ QuicPacketHeader header;
+ header.public_header.connection_id = connection_id_;
+ header.packet_number = 12;
header.public_header.version_flag = false;
QuicFrames frames;
frames.push_back(QuicFrame(&frame1_));
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
char buffer[kMaxPacketSize];
- encrypted.reset(framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet, buffer,
- kMaxPacketSize));
+ size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
+ buffer, kMaxPacketSize);
+ ASSERT_NE(0u, encrypted_length);
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
ASSERT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
}
TEST_P(QuicConnectionTest, BadVersionNegotiation) {
- QuicPacketHeader header;
- header.public_header.connection_id = connection_id_;
- header.public_header.version_flag = true;
- header.packet_packet_number = 12;
-
- QuicVersionVector supported_versions;
- for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
- supported_versions.push_back(kSupportedQuicVersions[i]);
- }
-
// Send a version negotiation packet with the version the client started with.
// It should be rejected.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(QUIC_INVALID_VERSION_NEGOTIATION_PACKET,
- false));
+ EXPECT_CALL(visitor_, OnConnectionClosed(
+ QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false));
scoped_ptr<QuicEncryptedPacket> encrypted(
- framer_.BuildVersionNegotiationPacket(
- header.public_header, supported_versions));
+ framer_.BuildVersionNegotiationPacket(connection_id_,
+ QuicSupportedVersions()));
connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
}
@@ -4292,18 +4940,26 @@ TEST_P(QuicConnectionTest, CheckSendStats) {
QuicAckFrame nack_three = InitAckFrame(4);
NackPacket(3, &nack_three);
NackPacket(1, &nack_three);
- PacketNumberSet lost_packets;
- lost_packets.insert(1);
- lost_packets.insert(3);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(1, kMaxPacketSize));
+ lost_packets.push_back(std::make_pair(3, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(1);
+ lost_packets.insert(3);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(visitor_, OnCanWrite());
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
ProcessAckPacket(&nack_three);
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(
- Return(QuicBandwidth::Zero()));
+ EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+ .WillOnce(Return(QuicBandwidth::Zero()));
const QuicConnectionStats& stats = connection_.GetStats();
EXPECT_EQ(3 * first_packet_size + 2 * second_packet_size - kQuicVersionSize,
@@ -4320,14 +4976,16 @@ TEST_P(QuicConnectionTest, CheckReceiveStats) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
size_t received_bytes = 0;
- received_bytes += ProcessFecProtectedPacket(1, false, !kEntropyFlag);
- received_bytes += ProcessFecProtectedPacket(3, false, !kEntropyFlag);
+ received_bytes +=
+ ProcessFecProtectedPacket(1, false, !kEntropyFlag, !kHasStopWaiting);
+ received_bytes +=
+ ProcessFecProtectedPacket(3, false, !kEntropyFlag, !kHasStopWaiting);
// Should be counted against dropped packets.
received_bytes += ProcessDataPacket(3, 1, !kEntropyFlag);
received_bytes += ProcessFecPacket(4, 1, true, !kEntropyFlag, nullptr);
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(
- Return(QuicBandwidth::Zero()));
+ EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+ .WillOnce(Return(QuicBandwidth::Zero()));
const QuicConnectionStats& stats = connection_.GetStats();
EXPECT_EQ(received_bytes, stats.bytes_received);
@@ -4363,7 +5021,7 @@ TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
// Construct a packet with stream frame and connection close frame.
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
- header.packet_packet_number = 1;
+ header.packet_number = 1;
header.public_header.version_flag = false;
QuicConnectionCloseFrame qccf;
@@ -4375,14 +5033,16 @@ TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
scoped_ptr<QuicPacket> packet(ConstructPacket(header, frames));
EXPECT_TRUE(nullptr != packet.get());
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, 1, *packet, buffer, kMaxPacketSize));
+ size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 1, *packet,
+ buffer, kMaxPacketSize);
EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, true));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *encrypted);
+ connection_.ProcessUdpPacket(
+ kSelfAddress, kPeerAddress,
+ QuicEncryptedPacket(buffer, encrypted_length, false));
}
TEST_P(QuicConnectionTest, SelectMutualVersion) {
@@ -4447,12 +5107,12 @@ TEST_P(QuicConnectionTest, ConnectionCloseWhenWriteBlocked) {
TEST_P(QuicConnectionTest, AckNotifierTriggerCallback) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Create a delegate which we expect to be called.
- scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
- EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _)).Times(1);
+ // Create a listener which we expect to be called.
+ scoped_refptr<MockAckListener> listener(new MockAckListener);
+ EXPECT_CALL(*listener, OnPacketAcked(_, _)).Times(1);
- // Send some data, which will register the delegate to be notified.
- connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
+ // Send some data, which will register the listener to be notified.
+ connection_.SendStreamDataWithString(1, "foo", 0, !kFin, listener.get());
// Process an ACK from the server which should trigger the callback.
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
@@ -4463,13 +5123,13 @@ TEST_P(QuicConnectionTest, AckNotifierTriggerCallback) {
TEST_P(QuicConnectionTest, AckNotifierFailToTriggerCallback) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Create a delegate which we don't expect to be called.
- scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
- EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _)).Times(0);
+ // Create a listener which we don't expect to be called.
+ scoped_refptr<MockAckListener> listener(new MockAckListener);
+ EXPECT_CALL(*listener, OnPacketAcked(_, _)).Times(0);
- // Send some data, which will register the delegate to be notified. This will
- // not be ACKed and so the delegate should never be called.
- connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
+ // Send some data, which will register the listener to be notified. This will
+ // not be ACKed and so the listener should never be called.
+ connection_.SendStreamDataWithString(1, "foo", 0, !kFin, listener.get());
// Send some other data which we will ACK.
connection_.SendStreamDataWithString(1, "foo", 0, !kFin, nullptr);
@@ -4479,10 +5139,17 @@ TEST_P(QuicConnectionTest, AckNotifierFailToTriggerCallback) {
// which we registered to be notified about.
QuicAckFrame frame = InitAckFrame(3);
NackPacket(1, &frame);
- PacketNumberSet lost_packets;
- lost_packets.insert(1);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(1, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(1);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&frame);
}
@@ -4490,31 +5157,43 @@ TEST_P(QuicConnectionTest, AckNotifierFailToTriggerCallback) {
TEST_P(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Create a delegate which we expect to be called.
- scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
- EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _)).Times(1);
+ // Create a listener which we expect to be called.
+ scoped_refptr<MockAckListener> listener(new MockAckListener);
+ EXPECT_CALL(*listener, OnPacketRetransmitted(3)).Times(1);
+ EXPECT_CALL(*listener, OnPacketAcked(3, _)).Times(1);
// Send four packets, and register to be notified on ACK of packet 2.
connection_.SendStreamDataWithString(3, "foo", 0, !kFin, nullptr);
- connection_.SendStreamDataWithString(3, "bar", 0, !kFin, delegate.get());
+ connection_.SendStreamDataWithString(3, "bar", 0, !kFin, listener.get());
connection_.SendStreamDataWithString(3, "baz", 0, !kFin, nullptr);
connection_.SendStreamDataWithString(3, "qux", 0, !kFin, nullptr);
// Now we receive ACK for packets 1, 3, and 4 and lose 2.
QuicAckFrame frame = InitAckFrame(4);
NackPacket(2, &frame);
- PacketNumberSet lost_packets;
- lost_packets.insert(2);
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(2, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(2);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
ProcessAckPacket(&frame);
// Now we get an ACK for packet 5 (retransmitted packet 2), which should
// trigger the callback.
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillRepeatedly(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
QuicAckFrame second_ack_frame = InitAckFrame(5);
ProcessAckPacket(&second_ack_frame);
@@ -4524,36 +5203,34 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
// out and was retransmitted, even though the retransmission has a
// different packet number.
TEST_P(QuicConnectionTest, AckNotifierCallbackForAckAfterRTO) {
- InSequence s;
+ // Create a listener which we expect to be called.
+ scoped_refptr<MockAckListener> listener(new StrictMock<MockAckListener>);
- // Create a delegate which we expect to be called.
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new StrictMock<MockAckNotifierDelegate>);
-
- QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
- DefaultRetransmissionTime());
- connection_.SendStreamDataWithString(3, "foo", 0, !kFin, delegate.get());
+ QuicTime default_retransmission_time =
+ clock_.ApproximateNow().Add(DefaultRetransmissionTime());
+ connection_.SendStreamDataWithString(3, "foo", 0, !kFin, listener.get());
EXPECT_EQ(1u, stop_waiting()->least_unacked);
- EXPECT_EQ(1u, writer_->header().packet_packet_number);
+ EXPECT_EQ(1u, writer_->header().packet_number);
EXPECT_EQ(default_retransmission_time,
connection_.GetRetransmissionAlarm()->deadline());
// Simulate the retransmission alarm firing.
clock_.AdvanceTime(DefaultRetransmissionTime());
+ EXPECT_CALL(*listener, OnPacketRetransmitted(3));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(2u, writer_->header().packet_packet_number);
+ EXPECT_EQ(2u, writer_->header().packet_number);
// We do not raise the high water mark yet.
EXPECT_EQ(1u, stop_waiting()->least_unacked);
// Ack the original packet, which will revert the RTO.
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*delegate, OnAckNotification(1, _, _));
+ EXPECT_CALL(*listener, OnPacketAcked(3, _));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
QuicAckFrame ack_frame = InitAckFrame(1);
ProcessAckPacket(&ack_frame);
- // Delegate is not notified again when the retransmit is acked.
+ // listener is not notified again when the retransmit is acked.
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
QuicAckFrame second_ack_frame = InitAckFrame(2);
ProcessAckPacket(&second_ack_frame);
@@ -4563,42 +5240,54 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckAfterRTO) {
// previously nacked, even though the retransmission has a different
// packet number.
TEST_P(QuicConnectionTest, AckNotifierCallbackForAckOfNackedPacket) {
- InSequence s;
-
- // Create a delegate which we expect to be called.
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new StrictMock<MockAckNotifierDelegate>);
+ // Create a listener which we expect to be called.
+ scoped_refptr<MockAckListener> listener(new StrictMock<MockAckListener>);
// Send four packets, and register to be notified on ACK of packet 2.
connection_.SendStreamDataWithString(3, "foo", 0, !kFin, nullptr);
- connection_.SendStreamDataWithString(3, "bar", 0, !kFin, delegate.get());
+ connection_.SendStreamDataWithString(3, "bar", 0, !kFin, listener.get());
connection_.SendStreamDataWithString(3, "baz", 0, !kFin, nullptr);
connection_.SendStreamDataWithString(3, "qux", 0, !kFin, nullptr);
// Now we receive ACK for packets 1, 3, and 4 and lose 2.
QuicAckFrame frame = InitAckFrame(4);
NackPacket(2, &frame);
- PacketNumberSet lost_packets;
- lost_packets.insert(2);
+ EXPECT_CALL(*listener, OnPacketRetransmitted(_));
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ SendAlgorithmInterface::CongestionVector lost_packets;
+ lost_packets.push_back(std::make_pair(2, kMaxPacketSize));
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _))
+ .WillOnce(SetArgPointee<3>(lost_packets));
+ } else {
+ PacketNumberSet lost_packets;
+ lost_packets.insert(2);
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(lost_packets));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
ProcessAckPacket(&frame);
// Now we get an ACK for packet 2, which was previously nacked.
- PacketNumberSet no_lost_packets;
- EXPECT_CALL(*delegate.get(), OnAckNotification(1, _, _));
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(no_lost_packets));
+ EXPECT_CALL(*listener, OnPacketAcked(3, _));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
QuicAckFrame second_ack_frame = InitAckFrame(4);
ProcessAckPacket(&second_ack_frame);
- // Verify that the delegate is not notified again when the
+ // Verify that the listener is not notified again when the
// retransmit is acked.
- EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(no_lost_packets));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
QuicAckFrame third_ack_frame = InitAckFrame(5);
ProcessAckPacket(&third_ack_frame);
@@ -4607,13 +5296,11 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckOfNackedPacket) {
TEST_P(QuicConnectionTest, AckNotifierFECTriggerCallback) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Create a delegate which we expect to be called.
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new MockAckNotifierDelegate);
- EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _)).Times(1);
-
- // Send some data, which will register the delegate to be notified.
- connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
+ // Create a listener which we expect to be called.
+ scoped_refptr<MockAckListener> listener(new MockAckListener);
+ EXPECT_CALL(*listener, OnPacketAcked(_, _)).Times(1);
+ // Send some data, which will register the listener to be notified.
+ connection_.SendStreamDataWithString(1, "foo", 0, !kFin, listener.get());
connection_.SendStreamDataWithString(2, "bar", 0, !kFin, nullptr);
// Process an ACK from the server with a revived packet, which should trigger
@@ -4621,7 +5308,7 @@ TEST_P(QuicConnectionTest, AckNotifierFECTriggerCallback) {
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
QuicAckFrame frame = InitAckFrame(2);
NackPacket(1, &frame);
- frame.revived_packets.insert(1);
+ frame.latest_revived_packet = 1;
ProcessAckPacket(&frame);
// If the ack is processed again, the notifier should not be called again.
ProcessAckPacket(&frame);
@@ -4631,15 +5318,15 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_CALL(visitor_, OnCanWrite());
- // Create a delegate which we expect to be called.
- scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
- EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _)).Times(1);
+ // Create a listener which we expect to be called.
+ scoped_refptr<MockAckListener> listener(new MockAckListener);
+ EXPECT_CALL(*listener, OnPacketAcked(_, _)).Times(1);
// Expect ACKs for 1 packet.
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
// Send one packet, and register to be notified on ACK.
- connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
+ connection_.SendStreamDataWithString(1, "foo", 0, !kFin, listener.get());
// Ack packet gets dropped, but we receive an FEC packet that covers it.
// Should recover the Ack packet and trigger the notification callback.
@@ -4657,7 +5344,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
ack_header.public_header.version_flag = false;
ack_header.entropy_flag = !kEntropyFlag;
ack_header.fec_flag = true;
- ack_header.packet_packet_number = 1;
+ ack_header.packet_number = 1;
ack_header.is_in_fec_group = IN_FEC_GROUP;
ack_header.fec_group = 1;
@@ -4676,8 +5363,8 @@ TEST_P(QuicConnectionTest, NetworkChangeVisitorCwndCallbackChangesFecState) {
EXPECT_TRUE(visitor);
// Increase FEC group size by increasing congestion window to a large number.
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
- Return(1000 * kDefaultTCPMSS));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(1000 * kDefaultTCPMSS));
visitor->OnCongestionWindowChange();
EXPECT_LT(max_packets_per_fec_group, creator_->max_packets_per_fec_group());
}
@@ -4687,7 +5374,7 @@ TEST_P(QuicConnectionTest, NetworkChangeVisitorConfigCallbackChangesFecState) {
QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
EXPECT_TRUE(visitor);
EXPECT_EQ(QuicTime::Delta::Zero(),
- QuicPacketGeneratorPeer::GetFecTimeout(generator_));
+ QuicPacketCreatorPeer::GetFecTimeout(creator_));
// Verify that sending a config with a new initial rtt changes fec timeout.
// Create and process a config with a non-zero initial RTT.
@@ -4696,7 +5383,7 @@ TEST_P(QuicConnectionTest, NetworkChangeVisitorConfigCallbackChangesFecState) {
config.SetInitialRoundTripTimeUsToSend(300000);
connection_.SetFromConfig(config);
EXPECT_LT(QuicTime::Delta::Zero(),
- QuicPacketGeneratorPeer::GetFecTimeout(generator_));
+ QuicPacketCreatorPeer::GetFecTimeout(creator_));
}
TEST_P(QuicConnectionTest, NetworkChangeVisitorRttCallbackChangesFecState) {
@@ -4705,7 +5392,7 @@ TEST_P(QuicConnectionTest, NetworkChangeVisitorRttCallbackChangesFecState) {
QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
EXPECT_TRUE(visitor);
EXPECT_EQ(QuicTime::Delta::Zero(),
- QuicPacketGeneratorPeer::GetFecTimeout(generator_));
+ QuicPacketCreatorPeer::GetFecTimeout(creator_));
// Increase FEC timeout by increasing RTT.
RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(manager_);
@@ -4713,7 +5400,7 @@ TEST_P(QuicConnectionTest, NetworkChangeVisitorRttCallbackChangesFecState) {
QuicTime::Delta::Zero(), QuicTime::Zero());
visitor->OnRttChange();
EXPECT_LT(QuicTime::Delta::Zero(),
- QuicPacketGeneratorPeer::GetFecTimeout(generator_));
+ QuicPacketCreatorPeer::GetFecTimeout(creator_));
}
TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
@@ -4723,19 +5410,23 @@ TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
new MockQuicConnectionDebugVisitor());
connection_.set_debug_visitor(debug_visitor.get());
EXPECT_CALL(*debug_visitor, OnPacketHeader(Ref(header))).Times(1);
+ if (FLAGS_quic_drop_non_awaited_packets) {
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(1);
+ EXPECT_CALL(*debug_visitor, OnSuccessfulVersionNegotiation(_)).Times(1);
+ }
connection_.OnPacketHeader(header);
}
TEST_P(QuicConnectionTest, Pacing) {
- TestConnection server(connection_id_, kSelfAddress, helper_.get(), factory_,
- Perspective::IS_SERVER, version());
- TestConnection client(connection_id_, kPeerAddress, helper_.get(), factory_,
- Perspective::IS_CLIENT, version());
+ TestConnection server(connection_id_, kSelfAddress, helper_.get(),
+ writer_.get(), Perspective::IS_SERVER, version());
+ TestConnection client(connection_id_, kPeerAddress, helper_.get(),
+ writer_.get(), Perspective::IS_CLIENT, version());
EXPECT_FALSE(client.sent_packet_manager().using_pacing());
EXPECT_FALSE(server.sent_packet_manager().using_pacing());
}
-TEST_P(QuicConnectionTest, ControlFramesInstigateAcks) {
+TEST_P(QuicConnectionTest, WindowUpdateInstigateAcks) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
// Send a WINDOW_UPDATE frame.
@@ -4748,13 +5439,19 @@ TEST_P(QuicConnectionTest, ControlFramesInstigateAcks) {
// Ensure that this has caused the ACK alarm to be set.
QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
EXPECT_TRUE(ack_alarm->IsSet());
+}
+
+TEST_P(QuicConnectionTest, BlockedFrameInstigateAcks) {
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Cancel alarm, and try again with BLOCKED frame.
- ack_alarm->Cancel();
+ // Send a BLOCKED frame.
QuicBlockedFrame blocked;
blocked.stream_id = 3;
EXPECT_CALL(visitor_, OnBlockedFrame(_));
ProcessFramePacket(QuicFrame(&blocked));
+
+ // Ensure that this has caused the ACK alarm to be set.
+ QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
EXPECT_TRUE(ack_alarm->IsSet());
}
@@ -4762,9 +5459,9 @@ TEST_P(QuicConnectionTest, NoDataNoFin) {
// Make sure that a call to SendStreamWithData, with no data and no FIN, does
// not result in a QuicAckNotifier being used-after-free (fail under ASAN).
// Regression test for b/18594622
- scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
+ scoped_refptr<MockAckListener> listener(new MockAckListener);
EXPECT_DFATAL(
- connection_.SendStreamDataWithString(3, "", 0, !kFin, delegate.get()),
+ connection_.SendStreamDataWithString(3, "", 0, !kFin, listener.get()),
"Attempt to send empty stream frame");
}
@@ -4798,11 +5495,11 @@ TEST_P(QuicConnectionTest, FecRTTMultiplierReceivedConnectionOption) {
copt.push_back(kFRTT);
QuicConfigPeer::SetReceivedConnectionOptions(&config, copt);
float rtt_multiplier_for_fec_timeout =
- generator_->rtt_multiplier_for_fec_timeout();
+ QuicPacketCreatorPeer::GetRttMultiplierForFecTimeout(creator_);
connection_.SetFromConfig(config);
// New RTT multiplier is half of the old RTT multiplier.
EXPECT_EQ(rtt_multiplier_for_fec_timeout,
- generator_->rtt_multiplier_for_fec_timeout() * 2);
+ QuicPacketCreatorPeer::GetRttMultiplierForFecTimeout(creator_) * 2);
}
TEST_P(QuicConnectionTest, DoNotSendGoAwayTwice) {
@@ -4814,6 +5511,46 @@ TEST_P(QuicConnectionTest, DoNotSendGoAwayTwice) {
connection_.SendGoAway(QUIC_PEER_GOING_AWAY, kHeadersStreamId, "Going Away.");
}
+TEST_P(QuicConnectionTest, ReevaluateTimeUntilSendOnAck) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_respect_send_alarm2, true);
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 0, !kFin,
+ nullptr);
+
+ // Evaluate CanWrite, and have it return a non-Zero value.
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillRepeatedly(Return(QuicTime::Delta::FromMilliseconds(1)));
+ connection_.OnCanWrite();
+ EXPECT_TRUE(connection_.GetSendAlarm()->IsSet());
+ EXPECT_EQ(clock_.Now().Add(QuicTime::Delta::FromMilliseconds(1)),
+ connection_.GetSendAlarm()->deadline());
+
+ // Process an ack and the send alarm will be set to the new 2ms delay.
+ QuicAckFrame ack = InitAckFrame(1);
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillRepeatedly(Return(QuicTime::Delta::FromMilliseconds(2)));
+ ProcessAckPacket(&ack);
+ EXPECT_EQ(1u, writer_->frame_count());
+ EXPECT_EQ(1u, writer_->stream_frames().size());
+ EXPECT_TRUE(connection_.GetSendAlarm()->IsSet());
+ EXPECT_EQ(clock_.Now().Add(QuicTime::Delta::FromMilliseconds(2)),
+ connection_.GetSendAlarm()->deadline());
+ writer_->Reset();
+}
+
+TEST_P(QuicConnectionTest, SendAcksImmediately) {
+ FLAGS_quic_respect_send_alarm2 = true;
+ CongestionBlockWrites();
+ SendAckPacketToPeer();
+}
+
TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
FLAGS_quic_never_write_unencrypted_data = true;
EXPECT_CALL(visitor_,
@@ -4823,6 +5560,32 @@ TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
EXPECT_FALSE(connection_.connected());
}
+TEST_P(QuicConnectionTest, EnableMultipathNegotiation) {
+ // Test multipath negotiation during crypto handshake. Multipath is enabled
+ // when both endpoints enable multipath.
+ ValueRestore<bool> old_flag(&FLAGS_quic_enable_multipath, true);
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_FALSE(QuicConnectionPeer::IsMultipathEnabled(&connection_));
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ // Enable multipath on server side.
+ config.SetMultipathEnabled(true);
+
+ // Create a handshake message enables multipath.
+ CryptoHandshakeMessage msg;
+ string error_details;
+ QuicConfig client_config;
+ // Enable multipath on client side.
+ client_config.SetMultipathEnabled(true);
+ client_config.ToHandshakeMessage(&msg);
+ const QuicErrorCode error =
+ config.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+
+ connection_.SetFromConfig(config);
+ EXPECT_TRUE(QuicConnectionPeer::IsMultipathEnabled(&connection_));
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_crypto_client_stream.cc b/chromium/net/quic/quic_crypto_client_stream.cc
index c5742da2c2e..1b9e20d97f6 100644
--- a/chromium/net/quic/quic_crypto_client_stream.cc
+++ b/chromium/net/quic/quic_crypto_client_stream.cc
@@ -7,7 +7,8 @@
#include <vector>
#include "base/metrics/histogram_macros.h"
-#include "base/profiler/scoped_tracker.h"
+#include "base/metrics/sparse_histogram.h"
+#include "base/strings/stringprintf.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/crypto/null_encrypter.h"
@@ -41,12 +42,16 @@ void AppendFixed(CryptoHandshakeMessage* message) {
} // namespace
+QuicCryptoClientStreamBase::QuicCryptoClientStreamBase(
+ QuicClientSessionBase* session)
+ : QuicCryptoStream(session) {}
+
QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
-ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream)
+ ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream)
: stream_(stream) {}
QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
-~ChannelIDSourceCallbackImpl() {}
+ ~ChannelIDSourceCallbackImpl() {}
void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Run(
scoped_ptr<ChannelIDKey>* channel_id_key) {
@@ -72,7 +77,7 @@ QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
: stream_(stream) {}
QuicCryptoClientStream::ProofVerifierCallbackImpl::
-~ProofVerifierCallbackImpl() {}
+ ~ProofVerifierCallbackImpl() {}
void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run(
bool ok,
@@ -101,7 +106,7 @@ QuicCryptoClientStream::QuicCryptoClientStream(
QuicClientSessionBase* session,
ProofVerifyContext* verify_context,
QuicCryptoClientConfig* crypto_config)
- : QuicCryptoStream(session),
+ : QuicCryptoClientStreamBase(session),
next_state_(STATE_IDLE),
num_client_hellos_(0),
crypto_config_(crypto_config),
@@ -127,11 +132,12 @@ QuicCryptoClientStream::~QuicCryptoClientStream() {
void QuicCryptoClientStream::OnHandshakeMessage(
const CryptoHandshakeMessage& message) {
- QuicCryptoStream::OnHandshakeMessage(message);
+ QuicCryptoClientStreamBase::OnHandshakeMessage(message);
if (message.tag() == kSCUP) {
if (!handshake_confirmed()) {
- CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE);
+ CloseConnectionWithDetails(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
+ "Early SCUP disallowed");
return;
}
@@ -143,7 +149,8 @@ void QuicCryptoClientStream::OnHandshakeMessage(
// Do not process handshake messages after the handshake is confirmed.
if (handshake_confirmed()) {
- CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
+ CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+ "Unexpected handshake message");
return;
}
@@ -175,10 +182,8 @@ void QuicCryptoClientStream::HandleServerConfigUpdateMessage(
QuicCryptoClientConfig::CachedState* cached =
crypto_config_->LookupOrCreate(server_id_);
QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
- server_config_update,
- session()->connection()->clock()->WallNow(),
- cached,
- &crypto_negotiated_params_,
+ server_config_update, session()->connection()->clock()->WallNow(),
+ session()->connection()->version(), cached, &crypto_negotiated_params_,
&error_details);
if (error != QUIC_NO_ERROR) {
@@ -195,8 +200,7 @@ void QuicCryptoClientStream::HandleServerConfigUpdateMessage(
DoHandshakeLoop(nullptr);
}
-void QuicCryptoClientStream::DoHandshakeLoop(
- const CryptoHandshakeMessage* in) {
+void QuicCryptoClientStream::DoHandshakeLoop(const CryptoHandshakeMessage* in) {
QuicCryptoClientConfig::CachedState* cached =
crypto_config_->LookupOrCreate(server_id_);
@@ -211,7 +215,7 @@ void QuicCryptoClientStream::DoHandshakeLoop(
DoInitialize(cached);
break;
case STATE_SEND_CHLO:
- DoSendCHLO(in, cached);
+ DoSendCHLO(cached);
return; // return waiting to hear from server.
case STATE_RECV_REJ:
DoReceiveREJ(in, cached);
@@ -233,7 +237,8 @@ void QuicCryptoClientStream::DoHandshakeLoop(
break;
case STATE_IDLE:
// This means that the peer sent us a message that we weren't expecting.
- CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
+ CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+ "Handshake in idle state");
return;
case STATE_INITIALIZE_SCUP:
DoInitializeServerConfigUpdate(cached);
@@ -247,13 +252,14 @@ void QuicCryptoClientStream::DoHandshakeLoop(
void QuicCryptoClientStream::DoInitialize(
QuicCryptoClientConfig::CachedState* cached) {
- if (!cached->IsEmpty() && !cached->signature().empty() &&
- server_id_.is_https()) {
+ if (!cached->IsEmpty() && !cached->signature().empty()) {
// Note that we verify the proof even if the cached proof is valid.
// This allows us to respond to CA trust changes or certificate
// expiration because it may have been a while since we last verified
// the proof.
DCHECK(crypto_config_->proof_verifier());
+ // Track proof verification time when cached server config is used.
+ proof_verify_start_time_ = base::TimeTicks::Now();
// If the cached state needs to be verified, do it now.
next_state_ = STATE_VERIFY_PROOF;
} else {
@@ -262,7 +268,6 @@ void QuicCryptoClientStream::DoInitialize(
}
void QuicCryptoClientStream::DoSendCHLO(
- const CryptoHandshakeMessage* in,
QuicCryptoClientConfig::CachedState* cached) {
if (stateless_reject_received_) {
// If we've gotten to this point, we've sent at least one hello
@@ -281,7 +286,9 @@ void QuicCryptoClientStream::DoSendCHLO(
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE);
encryption_established_ = false;
if (num_client_hellos_ > kMaxClientHellos) {
- CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS);
+ CloseConnectionWithDetails(
+ QUIC_CRYPTO_TOO_MANY_REJECTS,
+ base::StringPrintf("More than %u rejects", kMaxClientHellos).c_str());
return;
}
num_client_hellos_++;
@@ -293,15 +300,12 @@ void QuicCryptoClientStream::DoSendCHLO(
// inchoate or subsequent hello.
session()->config()->ToHandshakeMessage(&out);
- // This block and function should be removed after removing QUIC_VERSION_25.
- if (FLAGS_quic_require_fix) {
- AppendFixed(&out);
- }
+ // This call and function should be removed after removing QUIC_VERSION_25.
+ AppendFixed(&out);
if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
crypto_config_->FillInchoateClientHello(
- server_id_,
- session()->connection()->supported_versions().front(),
+ server_id_, session()->connection()->supported_versions().front(),
cached, &crypto_negotiated_params_, &out);
// Pad the inchoate client hello to fill up a packet.
const QuicByteCount kFramingOverhead = 50; // A rough estimate.
@@ -310,12 +314,13 @@ void QuicCryptoClientStream::DoSendCHLO(
if (max_packet_size <= kFramingOverhead) {
DLOG(DFATAL) << "max_packet_length (" << max_packet_size
<< ") has no room for framing overhead.";
- CloseConnection(QUIC_INTERNAL_ERROR);
+ CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
+ "max_packet_size too smalll");
return;
}
if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
DLOG(DFATAL) << "Client hello won't fit in a single packet.";
- CloseConnection(QUIC_INTERNAL_ERROR);
+ CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large");
return;
}
out.set_minimum_size(
@@ -336,16 +341,11 @@ void QuicCryptoClientStream::DoSendCHLO(
string error_details;
QuicErrorCode error = crypto_config_->FillClientHello(
- server_id_,
- session()->connection()->connection_id(),
- session()->connection()->supported_versions().front(),
- cached,
+ server_id_, session()->connection()->connection_id(),
+ session()->connection()->supported_versions().front(), cached,
session()->connection()->clock()->WallNow(),
- session()->connection()->random_generator(),
- channel_id_key_.get(),
- &crypto_negotiated_params_,
- &out,
- &error_details);
+ session()->connection()->random_generator(), channel_id_key_.get(),
+ &crypto_negotiated_params_, &out, &error_details);
if (error != QUIC_NO_ERROR) {
// Flush the cached config so that, if it's bad, the server has a
@@ -371,26 +371,19 @@ void QuicCryptoClientStream::DoSendCHLO(
session()->connection()->SetEncrypter(
ENCRYPTION_INITIAL,
crypto_negotiated_params_.initial_crypters.encrypter.release());
- session()->connection()->SetDefaultEncryptionLevel(
- ENCRYPTION_INITIAL);
+ session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
if (!encryption_established_) {
encryption_established_ = true;
session()->OnCryptoHandshakeEvent(
QuicSession::ENCRYPTION_FIRST_ESTABLISHED);
} else {
- session()->OnCryptoHandshakeEvent(
- QuicSession::ENCRYPTION_REESTABLISHED);
+ session()->OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_REESTABLISHED);
}
}
void QuicCryptoClientStream::DoReceiveREJ(
const CryptoHandshakeMessage* in,
QuicCryptoClientConfig::CachedState* cached) {
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "422516 QuicCryptoClientStream::DoReceiveREJ"));
-
// We sent a dummy CHLO because we didn't have enough information to
// perform a handshake, or we sent a full hello that the server
// rejected. Here we hope to have a REJ that contains the information
@@ -401,11 +394,37 @@ void QuicCryptoClientStream::DoReceiveREJ(
"Expected REJ");
return;
}
+
+ const uint32_t* reject_reasons;
+ size_t num_reject_reasons;
+ static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
+ if (in->GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons) ==
+ QUIC_NO_ERROR) {
+ uint32_t packed_error = 0;
+ for (size_t i = 0; i < num_reject_reasons; ++i) {
+ // HANDSHAKE_OK is 0 and don't report that as error.
+ if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
+ continue;
+ }
+ HandshakeFailureReason reason =
+ static_cast<HandshakeFailureReason>(reject_reasons[i]);
+ packed_error |= 1 << (reason - 1);
+ }
+ DVLOG(1) << "Reasons for rejection: " << packed_error;
+ if (num_client_hellos_ == kMaxClientHellos) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.TooMany",
+ packed_error);
+ }
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Secure",
+ packed_error);
+ }
+
stateless_reject_received_ = in->tag() == kSREJ;
string error_details;
QuicErrorCode error = crypto_config_->ProcessRejection(
- *in, session()->connection()->clock()->WallNow(), cached,
- server_id_.is_https(), &crypto_negotiated_params_, &error_details);
+ *in, session()->connection()->clock()->WallNow(),
+ session()->connection()->version(), cached, &crypto_negotiated_params_,
+ &error_details);
if (error != QUIC_NO_ERROR) {
next_state_ = STATE_NONE;
@@ -413,10 +432,7 @@ void QuicCryptoClientStream::DoReceiveREJ(
return;
}
if (!cached->proof_valid()) {
- if (!server_id_.is_https()) {
- // We don't check the certificates for insecure QUIC connections.
- SetCachedProofValid(cached);
- } else if (!cached->signature().empty()) {
+ if (!cached->signature().empty()) {
// Note that we only verify the proof if the cached proof is not
// valid. If the cached proof is valid here, someone else must have
// just added the server config to the cache and verified the proof,
@@ -443,8 +459,8 @@ QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
QuicAsyncStatus status = verifier->VerifyProof(
server_id_.host(), cached->server_config(), cached->certs(),
- cached->signature(), verify_context_.get(), &verify_error_details_,
- &verify_details_, proof_verify_callback);
+ cached->cert_sct(), cached->signature(), verify_context_.get(),
+ &verify_error_details_, &verify_details_, proof_verify_callback);
switch (status) {
case QUIC_PENDING:
@@ -464,15 +480,24 @@ QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
void QuicCryptoClientStream::DoVerifyProofComplete(
QuicCryptoClientConfig::CachedState* cached) {
+ if (!proof_verify_start_time_.is_null()) {
+ UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.CachedServerConfig",
+ base::TimeTicks::Now() - proof_verify_start_time_);
+ }
if (!verify_ok_) {
- next_state_ = STATE_NONE;
if (verify_details_.get()) {
client_session()->OnProofVerifyDetailsAvailable(*verify_details_);
}
+ if (num_client_hellos_ == 0) {
+ cached->Clear();
+ next_state_ = STATE_INITIALIZE;
+ return;
+ }
+ next_state_ = STATE_NONE;
UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed",
handshake_confirmed());
- CloseConnectionWithDetails(
- QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
+ CloseConnectionWithDetails(QUIC_PROOF_INVALID,
+ "Proof invalid: " + verify_error_details_);
return;
}
@@ -502,10 +527,8 @@ QuicAsyncStatus QuicCryptoClientStream::DoGetChannelID(
ChannelIDSourceCallbackImpl* channel_id_source_callback =
new ChannelIDSourceCallbackImpl(this);
- QuicAsyncStatus status =
- crypto_config_->channel_id_source()->GetChannelIDKey(
- server_id_.host(), &channel_id_key_,
- channel_id_source_callback);
+ QuicAsyncStatus status = crypto_config_->channel_id_source()->GetChannelIDKey(
+ server_id_.host(), &channel_id_key_, channel_id_source_callback);
switch (status) {
case QUIC_PENDING:
@@ -576,8 +599,9 @@ void QuicCryptoClientStream::DoReceiveSHLO(
string error_details;
QuicErrorCode error = crypto_config_->ProcessServerHello(
*in, session()->connection()->connection_id(),
- session()->connection()->server_supported_versions(),
- cached, &crypto_negotiated_params_, &error_details);
+ session()->connection()->version(),
+ session()->connection()->server_supported_versions(), cached,
+ &crypto_negotiated_params_, &error_details);
if (error != QUIC_NO_ERROR) {
CloseConnectionWithDetails(error, "Server hello invalid: " + error_details);
@@ -598,10 +622,9 @@ void QuicCryptoClientStream::DoReceiveSHLO(
session()->connection()->SetAlternativeDecrypter(
ENCRYPTION_FORWARD_SECURE, crypters->decrypter.release(),
false /* don't latch */);
- session()->connection()->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE, crypters->encrypter.release());
- session()->connection()->SetDefaultEncryptionLevel(
- ENCRYPTION_FORWARD_SECURE);
+ session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ crypters->encrypter.release());
+ session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
handshake_confirmed_ = true;
session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
@@ -611,11 +634,7 @@ void QuicCryptoClientStream::DoReceiveSHLO(
void QuicCryptoClientStream::DoInitializeServerConfigUpdate(
QuicCryptoClientConfig::CachedState* cached) {
bool update_ignored = false;
- if (!server_id_.is_https()) {
- // We don't check the certificates for insecure QUIC connections.
- SetCachedProofValid(cached);
- next_state_ = STATE_NONE;
- } else if (!cached->IsEmpty() && !cached->signature().empty()) {
+ if (!cached->IsEmpty() && !cached->signature().empty()) {
// Note that we verify the proof even if the cached proof is valid.
DCHECK(crypto_config_->proof_verifier());
next_state_ = STATE_VERIFY_PROOF;
@@ -635,8 +654,7 @@ void QuicCryptoClientStream::SetCachedProofValid(
bool QuicCryptoClientStream::RequiresChannelID(
QuicCryptoClientConfig::CachedState* cached) {
- if (!server_id_.is_https() ||
- server_id_.privacy_mode() == PRIVACY_MODE_ENABLED ||
+ if (server_id_.privacy_mode() == PRIVACY_MODE_ENABLED ||
!crypto_config_->channel_id_source()) {
return false;
}
@@ -646,8 +664,8 @@ bool QuicCryptoClientStream::RequiresChannelID(
}
const QuicTag* their_proof_demands;
size_t num_their_proof_demands;
- if (scfg->GetTaglist(kPDMD, &their_proof_demands,
- &num_their_proof_demands) != QUIC_NO_ERROR) {
+ if (scfg->GetTaglist(kPDMD, &their_proof_demands, &num_their_proof_demands) !=
+ QUIC_NO_ERROR) {
return false;
}
for (size_t i = 0; i < num_their_proof_demands; i++) {
diff --git a/chromium/net/quic/quic_crypto_client_stream.h b/chromium/net/quic/quic_crypto_client_stream.h
index edfc1f58e39..cd2e7da23d3 100644
--- a/chromium/net/quic/quic_crypto_client_stream.h
+++ b/chromium/net/quic/quic_crypto_client_stream.h
@@ -5,8 +5,11 @@
#ifndef NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_
#define NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "net/quic/crypto/channel_id.h"
#include "net/quic/crypto/proof_verifier.h"
#include "net/quic/crypto/quic_crypto_client_config.h"
@@ -23,7 +26,23 @@ class CryptoTestUtils;
class QuicChromiumClientSessionPeer;
} // namespace test
-class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
+class NET_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
+ public:
+ explicit QuicCryptoClientStreamBase(QuicClientSessionBase* session);
+
+ ~QuicCryptoClientStreamBase() override{};
+
+ // Performs a crypto handshake with the server.
+ virtual void CryptoConnect() = 0;
+
+ // num_sent_client_hellos returns the number of client hello messages that
+ // have been sent. If the handshake has completed then this is one greater
+ // than the number of round-trips needed for the handshake.
+ virtual int num_sent_client_hellos() const = 0;
+};
+
+class NET_EXPORT_PRIVATE QuicCryptoClientStream
+ : public QuicCryptoClientStreamBase {
public:
// kMaxClientHellos is the maximum number of times that we'll send a client
// hello. The value 3 accounts for:
@@ -32,24 +51,20 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
// the server being unwilling to send it without a valid source-address
// token.
static const int kMaxClientHellos = 3;
-
QuicCryptoClientStream(const QuicServerId& server_id,
QuicClientSessionBase* session,
ProofVerifyContext* verify_context,
QuicCryptoClientConfig* crypto_config);
+
~QuicCryptoClientStream() override;
+ // From QuicCryptoClientStreamBase
+ void CryptoConnect() override;
+ int num_sent_client_hellos() const override;
+
// CryptoFramerVisitorInterface implementation
void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
- // Performs a crypto handshake with the server.
- virtual void CryptoConnect();
-
- // num_sent_client_hellos returns the number of client hello messages that
- // have been sent. If the handshake has completed then this is one greater
- // than the number of round-trips needed for the handshake.
- int num_sent_client_hellos() const;
-
// Returns true if a channel ID was sent on this connection.
bool WasChannelIDSent() const;
@@ -128,8 +143,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
void DoInitialize(QuicCryptoClientConfig::CachedState* cached);
// Send either InchoateClientHello or ClientHello message to the server.
- void DoSendCHLO(const CryptoHandshakeMessage* in,
- QuicCryptoClientConfig::CachedState* cached);
+ void DoSendCHLO(QuicCryptoClientConfig::CachedState* cached);
// Process REJ message from the server.
void DoReceiveREJ(const CryptoHandshakeMessage* in,
@@ -184,7 +198,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
const QuicServerId server_id_;
// Generation counter from QuicCryptoClientConfig's CachedState.
- uint64 generation_counter_;
+ uint64_t generation_counter_;
// True if a channel ID was sent.
bool channel_id_sent_;
@@ -222,6 +236,8 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
// STATE_VERIFY_PROOF*, and subsequent STATE_SEND_CHLO state.
bool stateless_reject_received_;
+ base::TimeTicks proof_verify_start_time_;
+
DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientStream);
};
diff --git a/chromium/net/quic/quic_crypto_client_stream_factory.cc b/chromium/net/quic/quic_crypto_client_stream_factory.cc
new file mode 100644
index 00000000000..03565bae84f
--- /dev/null
+++ b/chromium/net/quic/quic_crypto_client_stream_factory.cc
@@ -0,0 +1,39 @@
+// 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/quic_crypto_client_stream_factory.h"
+
+#include "base/lazy_instance.h"
+#include "net/quic/crypto/proof_verifier_chromium.h"
+#include "net/quic/quic_chromium_client_session.h"
+#include "net/quic/quic_crypto_client_stream.h"
+
+namespace net {
+
+namespace {
+
+class DefaultCryptoStreamFactory : public QuicCryptoClientStreamFactory {
+ public:
+ QuicCryptoClientStream* CreateQuicCryptoClientStream(
+ const QuicServerId& server_id,
+ QuicChromiumClientSession* session,
+ scoped_ptr<ProofVerifyContext> proof_verify_context,
+ QuicCryptoClientConfig* crypto_config) override {
+ return new QuicCryptoClientStream(
+ server_id, session, proof_verify_context.release(), crypto_config);
+ }
+};
+
+static base::LazyInstance<DefaultCryptoStreamFactory>::Leaky
+ g_default_crypto_stream_factory = LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+// static
+QuicCryptoClientStreamFactory*
+QuicCryptoClientStreamFactory::GetDefaultFactory() {
+ return g_default_crypto_stream_factory.Pointer();
+}
+
+} // namespace net
diff --git a/chromium/net/quic/quic_crypto_client_stream_factory.h b/chromium/net/quic/quic_crypto_client_stream_factory.h
index 6c9194e5719..cd1d4302bfb 100644
--- a/chromium/net/quic/quic_crypto_client_stream_factory.h
+++ b/chromium/net/quic/quic_crypto_client_stream_factory.h
@@ -7,11 +7,14 @@
#include <string>
+#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
namespace net {
+class ProofVerifyContext;
class QuicChromiumClientSession;
+class QuicCryptoClientConfig;
class QuicCryptoClientStream;
class QuicServerId;
@@ -24,7 +27,10 @@ class NET_EXPORT QuicCryptoClientStreamFactory {
virtual QuicCryptoClientStream* CreateQuicCryptoClientStream(
const QuicServerId& server_id,
QuicChromiumClientSession* session,
+ scoped_ptr<ProofVerifyContext> proof_verify_context,
QuicCryptoClientConfig* crypto_config) = 0;
+
+ static QuicCryptoClientStreamFactory* GetDefaultFactory();
};
} // namespace net
diff --git a/chromium/net/quic/quic_crypto_client_stream_test.cc b/chromium/net/quic/quic_crypto_client_stream_test.cc
index 170a9218185..e95582c962d 100644
--- a/chromium/net/quic/quic_crypto_client_stream_test.cc
+++ b/chromium/net/quic/quic_crypto_client_stream_test.cc
@@ -19,23 +19,27 @@
#include "testing/gtest/include/gtest/gtest.h"
using std::string;
+using std::vector;
+
+using testing::_;
namespace net {
namespace test {
namespace {
-const char kServerHostname[] = "example.com";
-const uint16 kServerPort = 80;
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
class QuicCryptoClientStreamTest : public ::testing::Test {
public:
QuicCryptoClientStreamTest()
- : server_id_(kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED) {
+ : server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
+ crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) {
CreateConnection();
}
void CreateConnection() {
- connection_ = new PacketSavingConnection(Perspective::IS_CLIENT);
+ connection_ = new PacketSavingConnection(&helper_, Perspective::IS_CLIENT);
// Advance the time, because timers do not like uninitialized times.
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -45,7 +49,8 @@ class QuicCryptoClientStreamTest : public ::testing::Test {
void CompleteCryptoHandshake() {
stream()->CryptoConnect();
- CryptoTestUtils::HandshakeWithFakeServer(connection_, stream());
+ CryptoTestUtils::HandshakeWithFakeServer(&helper_, connection_, stream(),
+ server_options_);
}
void ConstructHandshakeMessage() {
@@ -55,12 +60,14 @@ class QuicCryptoClientStreamTest : public ::testing::Test {
QuicCryptoClientStream* stream() { return session_->GetCryptoStream(); }
+ MockConnectionHelper helper_;
PacketSavingConnection* connection_;
scoped_ptr<TestQuicSpdyClientSession> session_;
QuicServerId server_id_;
CryptoHandshakeMessage message_;
scoped_ptr<QuicData> message_data_;
QuicCryptoClientConfig crypto_config_;
+ CryptoTestUtils::FakeServerOptions server_options_;
};
TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
@@ -77,8 +84,9 @@ TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
CompleteCryptoHandshake();
- EXPECT_CALL(*connection_, SendConnectionClose(
- QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE));
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(
+ QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _));
message_.set_tag(kCHLO);
ConstructHandshakeMessage();
stream()->OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
@@ -92,21 +100,22 @@ TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
message_.set_tag(kCHLO);
ConstructHandshakeMessage();
- EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
- QUIC_INVALID_CRYPTO_MESSAGE_TYPE, "Expected REJ"));
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+ "Expected REJ"));
stream()->OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
/*offset=*/0,
message_data_->AsStringPiece()));
}
TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
+ FLAGS_quic_use_rfc7539 = true;
CompleteCryptoHandshake();
const QuicConfig* config = session_->config();
EXPECT_EQ(kMaximumIdleTimeoutSecs,
config->IdleConnectionStateLifetime().ToSeconds());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- config->MaxStreamsPerConnection());
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection, config->MaxStreamsPerConnection());
const QuicCryptoNegotiatedParameters& crypto_params(
stream()->crypto_negotiated_params());
@@ -114,17 +123,6 @@ TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
}
-TEST_F(QuicCryptoClientStreamTest, InvalidHostname) {
- server_id_ =
- QuicServerId("invalid", kServerPort, false, PRIVACY_MODE_DISABLED);
-
- CreateConnection();
-
- CompleteCryptoHandshake();
- EXPECT_TRUE(stream()->encryption_established());
- EXPECT_TRUE(stream()->handshake_confirmed());
-}
-
TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
// Seed the config with a cached server config.
CompleteCryptoHandshake();
@@ -142,6 +140,26 @@ TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
ASSERT_EQ(1u, connection_->encrypted_packets_.size());
}
+TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
+ // Seed the config with a cached server config.
+ CompleteCryptoHandshake();
+
+ // Recreate connection with the new config.
+ CreateConnection();
+
+ QuicCryptoClientConfig::CachedState* state =
+ crypto_config_.LookupOrCreate(server_id_);
+
+ vector<string> certs = state->certs();
+ string cert_sct = state->cert_sct();
+ string signature = state->signature();
+ state->SetProof(certs, cert_sct, signature + signature);
+
+ stream()->CryptoConnect();
+ // Check that a client hello was sent.
+ ASSERT_EQ(1u, connection_->encrypted_packets_.size());
+}
+
TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
// Test that the crypto client stream can receive server config updates after
// the connection has been established.
@@ -155,24 +173,21 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
// Initialize using {...} syntax to avoid trailing \0 if converting from
// string.
- unsigned char stk[] = { 'x', 's', 't', 'k' };
+ unsigned char stk[] = {'x', 's', 't', 'k'};
// Minimum SCFG that passes config validation checks.
- unsigned char scfg[] = {
- // SCFG
- 0x53, 0x43, 0x46, 0x47,
- // num entries
- 0x01, 0x00,
- // padding
- 0x00, 0x00,
- // EXPY
- 0x45, 0x58, 0x50, 0x59,
- // EXPY end offset
- 0x08, 0x00, 0x00, 0x00,
- // Value
- '1', '2', '3', '4',
- '5', '6', '7', '8'
- };
+ unsigned char scfg[] = {// SCFG
+ 0x53, 0x43, 0x46, 0x47,
+ // num entries
+ 0x01, 0x00,
+ // padding
+ 0x00, 0x00,
+ // EXPY
+ 0x45, 0x58, 0x50, 0x59,
+ // EXPY end offset
+ 0x08, 0x00, 0x00, 0x00,
+ // Value
+ '1', '2', '3', '4', '5', '6', '7', '8'};
CryptoHandshakeMessage server_config_update;
server_config_update.set_tag(kSCUP);
@@ -194,8 +209,9 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
}
TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
- EXPECT_CALL(*connection_, SendConnectionClose(
- QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE));
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(
+ QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _));
CryptoHandshakeMessage server_config_update;
server_config_update.set_tag(kSCUP);
scoped_ptr<QuicData> data(
@@ -204,18 +220,56 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
/*offset=*/0, data->AsStringPiece()));
}
+TEST_F(QuicCryptoClientStreamTest, TokenBindingNegotiation) {
+ server_options_.token_binding_enabled = true;
+ crypto_config_.tb_key_params.push_back(kP256);
+
+ CompleteCryptoHandshake();
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->handshake_confirmed());
+ EXPECT_EQ(kP256,
+ stream()->crypto_negotiated_params().token_binding_key_param);
+}
+
+TEST_F(QuicCryptoClientStreamTest, NoTokenBindingWithoutServerSupport) {
+ crypto_config_.tb_key_params.push_back(kP256);
+
+ CompleteCryptoHandshake();
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->handshake_confirmed());
+ EXPECT_EQ(0u, stream()->crypto_negotiated_params().token_binding_key_param);
+}
+
+TEST_F(QuicCryptoClientStreamTest, NoTokenBindingWithoutClientSupport) {
+ server_options_.token_binding_enabled = true;
+
+ CompleteCryptoHandshake();
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->handshake_confirmed());
+ EXPECT_EQ(0u, stream()->crypto_negotiated_params().token_binding_key_param);
+}
+
+TEST_F(QuicCryptoClientStreamTest, TokenBindingNotNegotiated) {
+ CompleteCryptoHandshake();
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->handshake_confirmed());
+ EXPECT_EQ(0u, stream()->crypto_negotiated_params().token_binding_key_param);
+}
+
class QuicCryptoClientStreamStatelessTest : public ::testing::Test {
public:
QuicCryptoClientStreamStatelessTest()
- : server_crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance()),
- server_id_(kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED) {
+ : client_crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
+ server_crypto_config_(QuicCryptoServerConfig::TESTING,
+ QuicRandom::GetInstance(),
+ CryptoTestUtils::ProofSourceForTesting()),
+ server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED) {
TestQuicSpdyClientSession* client_session = nullptr;
- CreateClientSessionForTest(server_id_,
- /* supports_stateless_rejects= */ true,
- QuicTime::Delta::FromSeconds(100000),
- &client_crypto_config_, &client_connection_,
- &client_session);
+ CreateClientSessionForTest(
+ server_id_,
+ /* supports_stateless_rejects= */ true,
+ QuicTime::Delta::FromSeconds(100000), QuicSupportedVersions(), &helper_,
+ &client_crypto_config_, &client_connection_, &client_session);
CHECK(client_session);
client_session_.reset(client_session);
}
@@ -235,16 +289,20 @@ class QuicCryptoClientStreamStatelessTest : public ::testing::Test {
void InitializeFakeStatelessRejectServer() {
TestQuicSpdyServerSession* server_session = nullptr;
CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
+ QuicSupportedVersions(), &helper_,
&server_crypto_config_, &server_connection_,
&server_session);
CHECK(server_session);
server_session_.reset(server_session);
+ CryptoTestUtils::FakeServerOptions options;
CryptoTestUtils::SetupCryptoServerConfigForTest(
server_connection_->clock(), server_connection_->random_generator(),
- server_session_->config(), &server_crypto_config_);
- server_stream()->set_use_stateless_rejects_if_peer_supported(true);
+ server_session_->config(), &server_crypto_config_, options);
+ FLAGS_enable_quic_stateless_reject_support = true;
}
+ MockConnectionHelper helper_;
+
// Client crypto stream state
PacketSavingConnection* client_connection_;
scoped_ptr<TestQuicSpdyClientSession> client_session_;
@@ -270,8 +328,8 @@ TEST_F(QuicCryptoClientStreamStatelessTest, StatelessReject) {
InitializeFakeStatelessRejectServer();
AdvanceHandshakeWithFakeServer();
- EXPECT_EQ(1, server_stream()->num_handshake_messages());
- EXPECT_EQ(0, server_stream()->num_handshake_messages_with_server_nonces());
+ EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
+ EXPECT_EQ(0, server_stream()->NumHandshakeMessagesWithServerNonces());
EXPECT_FALSE(client_session_->GetCryptoStream()->encryption_established());
EXPECT_FALSE(client_session_->GetCryptoStream()->handshake_confirmed());
diff --git a/chromium/net/quic/quic_crypto_server_stream.cc b/chromium/net/quic/quic_crypto_server_stream.cc
index fe1157b4f57..fc8281ead91 100644
--- a/chromium/net/quic/quic_crypto_server_stream.cc
+++ b/chromium/net/quic/quic_crypto_server_stream.cc
@@ -38,23 +38,26 @@ bool HasFixedTag(const CryptoHandshakeMessage& message) {
}
} // namespace
-void ServerHelloNotifier::OnAckNotification(
- int num_retransmitted_packets,
- int num_retransmitted_bytes,
+void ServerHelloNotifier::OnPacketAcked(
+ int acked_bytes,
QuicTime::Delta delta_largest_observed) {
+ // The SHLO is sent in one packet.
server_stream_->OnServerHelloAcked();
}
+void ServerHelloNotifier::OnPacketRetransmitted(int /*retransmitted_bytes*/) {}
+
QuicCryptoServerStream::QuicCryptoServerStream(
const QuicCryptoServerConfig* crypto_config,
QuicSession* session)
- : QuicCryptoStream(session),
+ : QuicCryptoServerStreamBase(session),
crypto_config_(crypto_config),
validate_client_hello_cb_(nullptr),
num_handshake_messages_(0),
num_handshake_messages_with_server_nonces_(0),
num_server_config_update_messages_sent_(0),
- use_stateless_rejects_if_peer_supported_(false),
+ use_stateless_rejects_if_peer_supported_(
+ FLAGS_enable_quic_stateless_reject_support),
peer_supports_stateless_rejects_(false) {
DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
}
@@ -67,28 +70,34 @@ void QuicCryptoServerStream::CancelOutstandingCallbacks() {
// Detach from the validation callback. Calling this multiple times is safe.
if (validate_client_hello_cb_ != nullptr) {
validate_client_hello_cb_->Cancel();
+ if (FLAGS_quic_set_client_hello_cb_nullptr) {
+ validate_client_hello_cb_ = nullptr;
+ }
}
}
void QuicCryptoServerStream::OnHandshakeMessage(
const CryptoHandshakeMessage& message) {
- QuicCryptoStream::OnHandshakeMessage(message);
+ QuicCryptoServerStreamBase::OnHandshakeMessage(message);
++num_handshake_messages_;
// This block should be removed with support for QUIC_VERSION_25.
if (FLAGS_quic_require_fix && !HasFixedTag(message)) {
- CloseConnection(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND);
+ CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND,
+ "Missing kFIXD");
return;
}
// Do not process handshake messages after the handshake is confirmed.
if (handshake_confirmed_) {
- CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
+ CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+ "Unexpected handshake message from client");
return;
}
if (message.tag() != kCHLO) {
- CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
+ CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+ "Handshake packet not CHLO");
return;
}
@@ -96,7 +105,9 @@ void QuicCryptoServerStream::OnHandshakeMessage(
// Already processing some other handshake message. The protocol
// does not allow for clients to send multiple handshake messages
// before the server has a chance to respond.
- CloseConnection(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO);
+ CloseConnectionWithDetails(
+ QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
+ "Unexpected handshake message while processing CHLO");
return;
}
@@ -115,7 +126,7 @@ void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
DCHECK(validate_client_hello_cb_ != nullptr);
validate_client_hello_cb_ = nullptr;
- if (FLAGS_enable_quic_stateless_reject_support) {
+ if (use_stateless_rejects_if_peer_supported_) {
peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message);
}
@@ -130,7 +141,26 @@ void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
}
if (reply.tag() != kSHLO) {
+ if (reply.tag() == kSREJ) {
+ DCHECK(use_stateless_rejects_if_peer_supported_);
+ DCHECK(peer_supports_stateless_rejects_);
+ // Before sending the SREJ, cause the connection to save crypto packets
+ // so that they can be added to the time wait list manager and
+ // retransmitted.
+ session()->connection()->EnableSavingCryptoPackets();
+ }
SendHandshakeMessage(reply);
+
+ if (reply.tag() == kSREJ) {
+ DCHECK(use_stateless_rejects_if_peer_supported_);
+ DCHECK(peer_supports_stateless_rejects_);
+ DCHECK(!handshake_confirmed());
+ DVLOG(1) << "Closing connection "
+ << session()->connection()->connection_id()
+ << " because of a stateless reject.";
+ session()->connection()->CloseConnection(
+ QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, /* from_peer */ false);
+ }
return;
}
@@ -191,7 +221,7 @@ void QuicCryptoServerStream::SendServerConfigUpdate(
CryptoHandshakeMessage server_config_update_message;
if (!crypto_config_->BuildServerConfigUpdateMessage(
- previous_source_address_tokens_,
+ session()->connection()->version(), previous_source_address_tokens_,
session()->connection()->self_address().address(),
session()->connection()->peer_address().address(),
session()->connection()->clock(),
@@ -214,7 +244,37 @@ void QuicCryptoServerStream::OnServerHelloAcked() {
session()->connection()->OnHandshakeComplete();
}
-void QuicCryptoServerStream::set_previous_cached_network_params(
+uint8_t QuicCryptoServerStream::NumHandshakeMessages() const {
+ return num_handshake_messages_;
+}
+
+uint8_t QuicCryptoServerStream::NumHandshakeMessagesWithServerNonces() const {
+ return num_handshake_messages_with_server_nonces_;
+}
+
+int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
+ return num_server_config_update_messages_sent_;
+}
+
+const CachedNetworkParameters*
+QuicCryptoServerStream::PreviousCachedNetworkParams() const {
+ return previous_cached_network_params_.get();
+}
+
+bool QuicCryptoServerStream::UseStatelessRejectsIfPeerSupported() const {
+ return use_stateless_rejects_if_peer_supported_;
+}
+
+bool QuicCryptoServerStream::PeerSupportsStatelessRejects() const {
+ return peer_supports_stateless_rejects_;
+}
+
+void QuicCryptoServerStream::SetPeerSupportsStatelessRejects(
+ bool peer_supports_stateless_rejects) {
+ peer_supports_stateless_rejects_ = peer_supports_stateless_rejects;
+}
+
+void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
CachedNetworkParameters cached_network_params) {
previous_cached_network_params_.reset(
new CachedNetworkParameters(cached_network_params));
@@ -231,11 +291,11 @@ bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
scoped_ptr<crypto::SecureHash> hash(
crypto::SecureHash::Create(crypto::SecureHash::SHA256));
hash->Update(channel_id.data(), channel_id.size());
- uint8 digest[32];
+ uint8_t digest[32];
hash->Finish(digest, sizeof(digest));
- base::Base64Encode(string(
- reinterpret_cast<const char*>(digest), sizeof(digest)), output);
+ base::Base64Encode(
+ string(reinterpret_cast<const char*>(digest), sizeof(digest)), output);
// Remove padding.
size_t len = output->size();
if (len >= 2) {
@@ -266,7 +326,6 @@ QuicErrorCode QuicCryptoServerStream::ProcessClientHello(
previous_source_address_tokens_ = result.info.source_address_tokens;
const bool use_stateless_rejects_in_crypto_config =
- FLAGS_enable_quic_stateless_reject_support &&
use_stateless_rejects_if_peer_supported_ &&
peer_supports_stateless_rejects_;
QuicConnection* connection = session()->connection();
@@ -282,19 +341,15 @@ QuicErrorCode QuicCryptoServerStream::ProcessClientHello(
&crypto_negotiated_params_, &crypto_proof_, reply, error_details);
}
-void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {
-}
-
-const CachedNetworkParameters*
-QuicCryptoServerStream::previous_cached_network_params() const {
- return previous_cached_network_params_.get();
-}
+void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {}
QuicCryptoServerStream::ValidateCallback::ValidateCallback(
- QuicCryptoServerStream* parent) : parent_(parent) {
-}
+ QuicCryptoServerStream* parent)
+ : parent_(parent) {}
-void QuicCryptoServerStream::ValidateCallback::Cancel() { parent_ = nullptr; }
+void QuicCryptoServerStream::ValidateCallback::Cancel() {
+ parent_ = nullptr;
+}
void QuicCryptoServerStream::ValidateCallback::RunImpl(
const CryptoHandshakeMessage& client_hello,
diff --git a/chromium/net/quic/quic_crypto_server_stream.h b/chromium/net/quic/quic_crypto_server_stream.h
index 0a0b37cac89..e8e708a5a2d 100644
--- a/chromium/net/quic/quic_crypto_server_stream.h
+++ b/chromium/net/quic/quic_crypto_server_stream.h
@@ -5,8 +5,11 @@
#ifndef NET_QUIC_QUIC_CRYPTO_SERVER_STREAM_H_
#define NET_QUIC_QUIC_CRYPTO_SERVER_STREAM_H_
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/proto/source_address_token.pb.h"
@@ -18,7 +21,7 @@ namespace net {
class CachedNetworkParameters;
class CryptoHandshakeMessage;
class QuicCryptoServerConfig;
-class QuicCryptoServerStream;
+class QuicCryptoServerStreamBase;
class QuicSession;
namespace test {
@@ -28,88 +31,89 @@ class QuicCryptoServerStreamPeer;
// Receives a notification when the server hello (SHLO) has been ACKed by the
// peer. At this point we disable HANDSHAKE_MODE in the sent packet manager.
-class NET_EXPORT_PRIVATE ServerHelloNotifier : public
- QuicAckNotifier::DelegateInterface {
+class NET_EXPORT_PRIVATE ServerHelloNotifier : public QuicAckListenerInterface {
public:
- explicit ServerHelloNotifier(QuicCryptoServerStream* stream)
+ explicit ServerHelloNotifier(QuicCryptoServerStreamBase* stream)
: server_stream_(stream) {}
- // QuicAckNotifier::DelegateInterface implementation
- void OnAckNotification(int num_retransmitted_packets,
- int num_retransmitted_bytes,
- QuicTime::Delta delta_largest_observed) override;
+ void OnPacketAcked(int acked_bytes,
+ QuicTime::Delta delta_largest_observed) override;
+
+ void OnPacketRetransmitted(int retransmitted_bytes) override;
private:
~ServerHelloNotifier() override {}
- QuicCryptoServerStream* server_stream_;
+ QuicCryptoServerStreamBase* server_stream_;
DISALLOW_COPY_AND_ASSIGN(ServerHelloNotifier);
};
-class NET_EXPORT_PRIVATE QuicCryptoServerStream : public QuicCryptoStream {
+// TODO(alyssar) see what can be moved out of QuicCryptoServerStream with
+// various code and test refactoring.
+class NET_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
public:
// |crypto_config| must outlive the stream.
- QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
- QuicSession* session);
- ~QuicCryptoServerStream() override;
+ explicit QuicCryptoServerStreamBase(QuicSession* session)
+ : QuicCryptoStream(session) {}
+ ~QuicCryptoServerStreamBase() override {}
// Cancel any outstanding callbacks, such as asynchronous validation of client
// hello.
- void CancelOutstandingCallbacks();
-
- // CryptoFramerVisitorInterface implementation
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+ virtual void CancelOutstandingCallbacks() = 0;
// GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
// SHA-256 hash of the client's ChannelID key and returns true, if the client
// presented a ChannelID. Otherwise it returns false.
- bool GetBase64SHA256ClientChannelID(std::string* output) const;
-
- uint8 num_handshake_messages() const { return num_handshake_messages_; }
+ virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0;
- uint8 num_handshake_messages_with_server_nonces() const {
- return num_handshake_messages_with_server_nonces_;
- }
-
- int num_server_config_update_messages_sent() const {
- return num_server_config_update_messages_sent_;
- }
+ virtual int NumServerConfigUpdateMessagesSent() const = 0;
// Sends the latest server config and source-address token to the client.
virtual void SendServerConfigUpdate(
- const CachedNetworkParameters* cached_network_params);
+ const CachedNetworkParameters* cached_network_params) = 0;
// Called by the ServerHello AckNotifier once the SHLO has been ACKed by the
// client.
- void OnServerHelloAcked();
-
- void set_previous_cached_network_params(
- CachedNetworkParameters cached_network_params);
-
- const CachedNetworkParameters* previous_cached_network_params() const;
-
- bool use_stateless_rejects_if_peer_supported() const {
- return use_stateless_rejects_if_peer_supported_;
- }
-
- // Used by the quic dispatcher to indicate that this crypto server
- // stream should use stateless rejects, so long as stateless rejects
- // are supported by the client.
- void set_use_stateless_rejects_if_peer_supported(
- bool use_stateless_rejects_if_peer_supported) {
- use_stateless_rejects_if_peer_supported_ =
- use_stateless_rejects_if_peer_supported;
- }
+ virtual void OnServerHelloAcked() = 0;
+
+ // These are all accessors and setters to their respective counters.
+ virtual uint8_t NumHandshakeMessages() const = 0;
+ virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0;
+ virtual bool UseStatelessRejectsIfPeerSupported() const = 0;
+ virtual bool PeerSupportsStatelessRejects() const = 0;
+ virtual void SetPeerSupportsStatelessRejects(bool set) = 0;
+ virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
+ const = 0;
+ virtual void SetPreviousCachedNetworkParams(
+ CachedNetworkParameters cached_network_params) = 0;
+};
- bool peer_supports_stateless_rejects() const {
- return peer_supports_stateless_rejects_;
- }
+class NET_EXPORT_PRIVATE QuicCryptoServerStream
+ : public QuicCryptoServerStreamBase {
+ public:
+ // |crypto_config| must outlive the stream.
+ QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+ QuicSession* session);
+ ~QuicCryptoServerStream() override;
- void set_peer_supports_stateless_rejects(
- bool peer_supports_stateless_rejects) {
- peer_supports_stateless_rejects_ = peer_supports_stateless_rejects;
- }
+ // From QuicCryptoServerStreamBase
+ void CancelOutstandingCallbacks() override;
+ void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+ bool GetBase64SHA256ClientChannelID(std::string* output) const override;
+ void SendServerConfigUpdate(
+ const CachedNetworkParameters* cached_network_params) override;
+ void OnServerHelloAcked() override;
+ uint8_t NumHandshakeMessages() const override;
+ uint8_t NumHandshakeMessagesWithServerNonces() const override;
+ int NumServerConfigUpdateMessagesSent() const override;
+ const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
+ bool UseStatelessRejectsIfPeerSupported() const override;
+ bool PeerSupportsStatelessRejects() const override;
+ void SetPeerSupportsStatelessRejects(
+ bool peer_supports_stateless_rejects) override;
+ void SetPreviousCachedNetworkParams(
+ CachedNetworkParameters cached_network_params) override;
protected:
virtual QuicErrorCode ProcessClientHello(
@@ -173,12 +177,12 @@ class NET_EXPORT_PRIVATE QuicCryptoServerStream : public QuicCryptoStream {
ValidateCallback* validate_client_hello_cb_;
// Number of handshake messages received by this stream.
- uint8 num_handshake_messages_;
+ uint8_t num_handshake_messages_;
// Number of handshake messages received by this stream that contain
// server nonces (indicating that this is a non-zero-RTT handshake
// attempt).
- uint8 num_handshake_messages_with_server_nonces_;
+ uint8_t num_handshake_messages_with_server_nonces_;
// Number of server config update (SCUP) messages sent by this stream.
int num_server_config_update_messages_sent_;
diff --git a/chromium/net/quic/quic_crypto_server_stream_test.cc b/chromium/net/quic/quic_crypto_server_stream_test.cc
index 7a205137f06..f783bef5fe7 100644
--- a/chromium/net/quic/quic_crypto_server_stream_test.cc
+++ b/chromium/net/quic/quic_crypto_server_stream_test.cc
@@ -8,6 +8,7 @@
#include <vector>
#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
#include "net/quic/crypto/crypto_framer.h"
#include "net/quic/crypto/crypto_handshake.h"
@@ -61,24 +62,21 @@ class QuicCryptoServerStreamPeer {
namespace {
const char kServerHostname[] = "test.example.com";
-const uint16 kServerPort = 443;
+const uint16_t kServerPort = 443;
class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
public:
QuicCryptoServerStreamTest()
: server_crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance()),
- server_id_(kServerHostname, kServerPort, true, PRIVACY_MODE_DISABLED) {
-#if defined(USE_OPENSSL)
- server_crypto_config_.SetProofSource(
- CryptoTestUtils::ProofSourceForTesting());
-#else
- // TODO(rch): Implement a NSS proof source.
- server_crypto_config_.SetProofSource(
- CryptoTestUtils::FakeProofSourceForTesting());
-#endif
+ QuicRandom::GetInstance(),
+ CryptoTestUtils::ProofSourceForTesting()),
+ server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
+ client_crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) {
+ FLAGS_enable_quic_stateless_reject_support = false;
server_crypto_config_.set_strike_register_no_startup_period();
+ }
+ void Initialize() {
InitializeServer();
if (AsyncStrikeRegisterVerification()) {
@@ -86,28 +84,41 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
QuicCryptoServerConfigPeer::GetPrimaryOrbit(server_crypto_config_);
strike_register_client_ = new DelayedVerifyStrikeRegisterClient(
10000, // strike_register_max_entries
- static_cast<uint32>(
+ static_cast<uint32_t>(
server_connection_->clock()->WallNow().ToUNIXSeconds()),
60, // strike_register_window_secs
- reinterpret_cast<const uint8*>(orbit.data()),
+ reinterpret_cast<const uint8_t*>(orbit.data()),
StrikeRegister::NO_STARTUP_PERIOD_NEEDED);
strike_register_client_->StartDelayingVerification();
server_crypto_config_.SetStrikeRegisterClient(strike_register_client_);
}
}
+ ~QuicCryptoServerStreamTest() override {
+ // Ensure that anything that might reference |helpers_| is destroyed before
+ // |helpers_| is destroyed.
+ server_session_.reset();
+ client_session_.reset();
+ STLDeleteElements(&helpers_);
+ }
+
// Initializes the crypto server stream state for testing. May be
// called multiple times.
void InitializeServer() {
TestQuicSpdyServerSession* server_session = nullptr;
+ helpers_.push_back(new MockConnectionHelper);
+
CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
+ supported_versions_, helpers_.back(),
&server_crypto_config_, &server_connection_,
&server_session);
CHECK(server_session);
server_session_.reset(server_session);
+ CryptoTestUtils::FakeServerOptions options;
+ options.token_binding_enabled = true;
CryptoTestUtils::SetupCryptoServerConfigForTest(
server_connection_->clock(), server_connection_->random_generator(),
- server_session_->config(), &server_crypto_config_);
+ server_session_->config(), &server_crypto_config_, options);
}
QuicCryptoServerStream* server_stream() {
@@ -122,25 +133,21 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
// testing. May be called multiple times.
void InitializeFakeClient(bool supports_stateless_rejects) {
TestQuicSpdyClientSession* client_session = nullptr;
+ helpers_.push_back(new MockConnectionHelper);
CreateClientSessionForTest(server_id_, supports_stateless_rejects,
QuicTime::Delta::FromSeconds(100000),
- &client_crypto_config_, &client_connection_,
- &client_session);
+ supported_versions_,
+
+ helpers_.back(), &client_crypto_config_,
+ &client_connection_, &client_session);
CHECK(client_session);
client_session_.reset(client_session);
- if (!client_options_.dont_verify_certs) {
-#if defined(USE_OPENSSL)
- client_crypto_config_.SetProofVerifier(
- CryptoTestUtils::ProofVerifierForTesting());
-#else
- // TODO(rch): Implement a NSS proof source.
- client_crypto_config_.SetProofVerifier(
- CryptoTestUtils::FakeProofVerifierForTesting());
-#endif
- }
}
bool AsyncStrikeRegisterVerification() {
+ if (server_connection_->version() > QUIC_VERSION_30) {
+ return false;
+ }
return GetParam();
}
@@ -153,7 +160,8 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
CHECK(server_connection_);
CHECK(server_session_ != nullptr);
return CryptoTestUtils::HandshakeWithFakeClient(
- server_connection_, server_stream(), server_id_, client_options_);
+ helpers_.back(), server_connection_, server_stream(), server_id_,
+ client_options_);
}
// Performs a single round of handshake message-exchange between the
@@ -169,6 +177,11 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
}
protected:
+ // Every connection gets its own MockConnectionHelper, tracked separately
+ // from the server and client state so their lifetimes persist through the
+ // whole test.
+ std::vector<MockConnectionHelper*> helpers_;
+
// Server state
PacketSavingConnection* server_connection_;
scoped_ptr<TestQuicSpdyServerSession> server_session_;
@@ -184,18 +197,23 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
scoped_ptr<QuicData> message_data_;
CryptoTestUtils::FakeClientOptions client_options_;
DelayedVerifyStrikeRegisterClient* strike_register_client_;
+
+ // Which QUIC versions the client and server support.
+ QuicVersionVector supported_versions_ = QuicSupportedVersions();
};
INSTANTIATE_TEST_CASE_P(Tests, QuicCryptoServerStreamTest, testing::Bool());
TEST_P(QuicCryptoServerStreamTest, NotInitiallyConected) {
+ Initialize();
EXPECT_FALSE(server_stream()->encryption_established());
EXPECT_FALSE(server_stream()->handshake_confirmed());
}
TEST_P(QuicCryptoServerStreamTest, NotInitiallySendingStatelessRejects) {
- EXPECT_FALSE(server_stream()->use_stateless_rejects_if_peer_supported());
- EXPECT_FALSE(server_stream()->peer_supports_stateless_rejects());
+ Initialize();
+ EXPECT_FALSE(server_stream()->UseStatelessRejectsIfPeerSupported());
+ EXPECT_FALSE(server_stream()->PeerSupportsStatelessRejects());
}
TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
@@ -203,6 +221,7 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
// test should send:
// * One to get a source-address token and certificates.
// * One to complete the handshake.
+ Initialize();
EXPECT_EQ(2, CompleteCryptoHandshake());
EXPECT_TRUE(server_stream()->encryption_established());
EXPECT_TRUE(server_stream()->handshake_confirmed());
@@ -211,7 +230,7 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) {
ValueRestore<bool> old_flag(&FLAGS_enable_quic_stateless_reject_support,
true);
- server_stream()->set_use_stateless_rejects_if_peer_supported(true);
+ Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ true);
AdvanceHandshakeWithFakeClient();
@@ -233,17 +252,17 @@ TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) {
const QuicConnectionId server_designated_connection_id =
client_state->GetNextServerDesignatedConnectionId();
const QuicConnectionId expected_id =
- reinterpret_cast<MockRandom*>(server_connection_->random_generator())
- ->RandUint64();
+ server_connection_->random_generator()->RandUint64();
EXPECT_EQ(expected_id, server_designated_connection_id);
EXPECT_FALSE(client_state->has_server_designated_connection_id());
ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
+ EXPECT_FALSE(server_connection_->connected());
}
TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
ValueRestore<bool> old_flag(&FLAGS_enable_quic_stateless_reject_support,
true);
- server_stream()->set_use_stateless_rejects_if_peer_supported(true);
+ Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ true);
AdvanceHandshakeWithFakeClient();
@@ -251,8 +270,8 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
// On the first round, encryption will not be established.
EXPECT_FALSE(server_stream()->encryption_established());
EXPECT_FALSE(server_stream()->handshake_confirmed());
- EXPECT_EQ(1, server_stream()->num_handshake_messages());
- EXPECT_EQ(0, server_stream()->num_handshake_messages_with_server_nonces());
+ EXPECT_EQ(1, server_stream()->NumHandshakeMessages());
+ EXPECT_EQ(0, server_stream()->NumHandshakeMessagesWithServerNonces());
// Now check the client state.
QuicCryptoClientConfig::CachedState* client_state =
@@ -262,8 +281,7 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
const QuicConnectionId server_designated_connection_id =
client_state->GetNextServerDesignatedConnectionId();
const QuicConnectionId expected_id =
- reinterpret_cast<MockRandom*>(server_connection_->random_generator())
- ->RandUint64();
+ server_connection_->random_generator()->RandUint64();
EXPECT_EQ(expected_id, server_designated_connection_id);
EXPECT_FALSE(client_state->has_server_designated_connection_id());
ASSERT_TRUE(client_state->IsComplete(QuicWallTime::FromUNIXSeconds(0)));
@@ -271,7 +289,6 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
// Now create new client and server streams with the existing config
// and try the handshake again (0-RTT handshake).
InitializeServer();
- server_stream()->set_use_stateless_rejects_if_peer_supported(true);
InitializeFakeClient(/* supports_stateless_rejects= */ true);
@@ -285,14 +302,14 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
// On the second round, encryption will be established.
EXPECT_TRUE(server_stream()->encryption_established());
EXPECT_TRUE(server_stream()->handshake_confirmed());
- EXPECT_EQ(2, server_stream()->num_handshake_messages());
- EXPECT_EQ(1, server_stream()->num_handshake_messages_with_server_nonces());
+ EXPECT_EQ(2, server_stream()->NumHandshakeMessages());
+ EXPECT_EQ(1, server_stream()->NumHandshakeMessagesWithServerNonces());
}
TEST_P(QuicCryptoServerStreamTest, NoStatelessRejectIfNoClientSupport) {
ValueRestore<bool> old_flag(&FLAGS_enable_quic_stateless_reject_support,
true);
- server_stream()->set_use_stateless_rejects_if_peer_supported(true);
+ Initialize();
// The server is configured to use stateless rejects, but the client does not
// support it.
@@ -313,6 +330,7 @@ TEST_P(QuicCryptoServerStreamTest, NoStatelessRejectIfNoClientSupport) {
}
TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
+ Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ false);
// Do a first handshake in order to prime the client config with the server's
@@ -359,15 +377,21 @@ TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
server_stream());
}
- EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
+ if (FLAGS_require_strike_register_or_server_nonce &&
+ !AsyncStrikeRegisterVerification()) {
+ EXPECT_EQ(2, client_stream()->num_sent_client_hellos());
+ } else {
+ EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
+ }
}
TEST_P(QuicCryptoServerStreamTest, MessageAfterHandshake) {
FLAGS_quic_require_fix = false;
+ Initialize();
CompleteCryptoHandshake();
- EXPECT_CALL(
- *server_connection_,
- SendConnectionClose(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE));
+ EXPECT_CALL(*server_connection_,
+ SendConnectionCloseWithDetails(
+ QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _));
message_.set_tag(kCHLO);
ConstructHandshakeMessage();
server_stream()->OnStreamFrame(
@@ -377,29 +401,20 @@ TEST_P(QuicCryptoServerStreamTest, MessageAfterHandshake) {
TEST_P(QuicCryptoServerStreamTest, BadMessageType) {
FLAGS_quic_require_fix = false;
+ Initialize();
+
message_.set_tag(kSHLO);
ConstructHandshakeMessage();
- EXPECT_CALL(*server_connection_,
- SendConnectionClose(QUIC_INVALID_CRYPTO_MESSAGE_TYPE));
+ EXPECT_CALL(*server_connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_CRYPTO_MESSAGE_TYPE, _));
server_stream()->OnStreamFrame(
QuicStreamFrame(kCryptoStreamId, /*fin=*/false, /*offset=*/0,
message_data_->AsStringPiece()));
}
-TEST_P(QuicCryptoServerStreamTest, WithoutCertificates) {
- server_crypto_config_.SetProofSource(nullptr);
- server_id_ =
- QuicServerId(kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED);
- client_options_.dont_verify_certs = true;
-
- // Only 2 client hellos need to be sent in the no-certs case: one to get the
- // source-address token and the second to finish.
- EXPECT_EQ(2, CompleteCryptoHandshake());
- EXPECT_TRUE(server_stream()->encryption_established());
- EXPECT_TRUE(server_stream()->handshake_confirmed());
-}
-
TEST_P(QuicCryptoServerStreamTest, ChannelID) {
+ Initialize();
+
client_options_.channel_id_enabled = true;
client_options_.channel_id_source_async = false;
// CompleteCryptoHandshake verifies
@@ -410,6 +425,8 @@ TEST_P(QuicCryptoServerStreamTest, ChannelID) {
}
TEST_P(QuicCryptoServerStreamTest, ChannelIDAsync) {
+ Initialize();
+
client_options_.channel_id_enabled = true;
client_options_.channel_id_source_async = true;
// CompleteCryptoHandshake verifies
@@ -421,11 +438,15 @@ TEST_P(QuicCryptoServerStreamTest, ChannelIDAsync) {
TEST_P(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
// An attempt to send a SCUP before completing handshake should fail.
+ Initialize();
+
server_stream()->SendServerConfigUpdate(nullptr);
- EXPECT_EQ(0, server_stream()->num_server_config_update_messages_sent());
+ EXPECT_EQ(0, server_stream()->NumServerConfigUpdateMessagesSent());
}
TEST_P(QuicCryptoServerStreamTest, DoesPeerSupportStatelessRejects) {
+ Initialize();
+
ConstructHandshakeMessage();
QuicConfig stateless_reject_config = DefaultQuicConfigStatelessRejects();
stateless_reject_config.ToHandshakeMessage(&message_);
@@ -439,6 +460,72 @@ TEST_P(QuicCryptoServerStreamTest, DoesPeerSupportStatelessRejects) {
QuicCryptoServerStreamPeer::DoesPeerSupportStatelessRejects(message_));
}
+TEST_P(QuicCryptoServerStreamTest, TokenBindingNegotiated) {
+ Initialize();
+
+ client_options_.token_binding_enabled = true;
+ CompleteCryptoHandshake();
+ EXPECT_EQ(
+ kP256,
+ server_stream()->crypto_negotiated_params().token_binding_key_param);
+ EXPECT_TRUE(server_stream()->encryption_established());
+ EXPECT_TRUE(server_stream()->handshake_confirmed());
+}
+
+TEST_P(QuicCryptoServerStreamTest, NoTokenBindingWithoutClientSupport) {
+ Initialize();
+
+ CompleteCryptoHandshake();
+ EXPECT_EQ(
+ 0u, server_stream()->crypto_negotiated_params().token_binding_key_param);
+ EXPECT_TRUE(server_stream()->encryption_established());
+ EXPECT_TRUE(server_stream()->handshake_confirmed());
+}
+
+TEST_P(QuicCryptoServerStreamTest, CancelRPCBeforeVerificationCompletes) {
+ // Tests that the client can close the connection while the remote strike
+ // register verification RPC is still pending.
+ ValueRestore<bool> old_flag(&FLAGS_quic_set_client_hello_cb_nullptr, true);
+
+ // Set version to QUIC_VERSION_25 as QUIC_VERSION_26 and later don't support
+ // asynchronous strike register RPCs.
+ supported_versions_ = {QUIC_VERSION_25};
+ Initialize();
+ if (!AsyncStrikeRegisterVerification()) {
+ return;
+ }
+ InitializeFakeClient(/* supports_stateless_rejects= */ false);
+
+ // Do a first handshake in order to prime the client config with the server's
+ // information.
+ AdvanceHandshakeWithFakeClient();
+
+ // Now start another handshake, this time the server will attempt to verify
+ // the client's nonce with the strike registers.
+ InitializeFakeClient(/* supports_stateless_rejects= */ false);
+ InitializeServer();
+ client_stream()->CryptoConnect();
+ EXPECT_FALSE(client_stream()->handshake_confirmed());
+ EXPECT_FALSE(server_stream()->handshake_confirmed());
+
+ // Advance the handshake. Expect that the server will be stuck waiting for
+ // client nonce verification to complete.
+ CryptoTestUtils::AdvanceHandshake(client_connection_, client_stream(), 0,
+ server_connection_, server_stream(), 0);
+ EXPECT_EQ(1, strike_register_client_->PendingVerifications());
+ EXPECT_FALSE(client_stream()->handshake_confirmed());
+ EXPECT_FALSE(server_stream()->handshake_confirmed());
+
+ // While waiting for the asynchronous verification to complete, the client
+ // decides to close the connection.
+ server_session_->connection()->CloseConnection(QUIC_NO_ERROR,
+ /*from_peer=*/true);
+
+ // The outstanding nonce verification RPC now completes.
+ strike_register_client_->RunPendingVerifications();
+}
+
} // namespace
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_crypto_stream.cc b/chromium/net/quic/quic_crypto_stream.cc
index 8561ab7f5fc..be4a3ca8882 100644
--- a/chromium/net/quic/quic_crypto_stream.cc
+++ b/chromium/net/quic/quic_crypto_stream.cc
@@ -15,6 +15,7 @@
using std::string;
using base::StringPiece;
+using net::SpdyPriority;
namespace net {
@@ -51,15 +52,16 @@ void QuicCryptoStream::OnDataAvailable() {
}
StringPiece data(static_cast<char*>(iov.iov_base), iov.iov_len);
if (!crypto_framer_.ProcessInput(data)) {
- CloseConnection(crypto_framer_.error());
+ CloseConnectionWithDetails(crypto_framer_.error(),
+ crypto_framer_.error_detail());
return;
}
sequencer()->MarkConsumed(iov.iov_len);
}
}
-QuicPriority QuicCryptoStream::EffectivePriority() const {
- return QuicUtils::HighestPriority();
+SpdyPriority QuicCryptoStream::Priority() const {
+ return net::kV3HighestPriority;
}
void QuicCryptoStream::SendHandshakeMessage(
@@ -69,29 +71,25 @@ void QuicCryptoStream::SendHandshakeMessage(
void QuicCryptoStream::SendHandshakeMessage(
const CryptoHandshakeMessage& message,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* listener) {
DVLOG(1) << ENDPOINT << "Sending " << message.DebugString();
session()->OnCryptoHandshakeMessageSent(message);
const QuicData& data = message.GetSerialized();
// TODO(wtc): check the return value.
- WriteOrBufferData(string(data.data(), data.length()), false, delegate);
+ WriteOrBufferData(string(data.data(), data.length()), false, listener);
}
-bool QuicCryptoStream::ExportKeyingMaterial(
- StringPiece label,
- StringPiece context,
- size_t result_len,
- string* result) const {
+bool QuicCryptoStream::ExportKeyingMaterial(StringPiece label,
+ StringPiece context,
+ size_t result_len,
+ string* result) const {
if (!handshake_confirmed()) {
DLOG(ERROR) << "ExportKeyingMaterial was called before forward-secure"
<< "encryption was established.";
return false;
}
return CryptoUtils::ExportKeyingMaterial(
- crypto_negotiated_params_.subkey_secret,
- label,
- context,
- result_len,
+ crypto_negotiated_params_.subkey_secret, label, context, result_len,
result);
}
diff --git a/chromium/net/quic/quic_crypto_stream.h b/chromium/net/quic/quic_crypto_stream.h
index ffae04b84f0..e794cb8025b 100644
--- a/chromium/net/quic/quic_crypto_stream.h
+++ b/chromium/net/quic/quic_crypto_stream.h
@@ -5,7 +5,9 @@
#ifndef NET_QUIC_QUIC_CRYPTO_STREAM_H_
#define NET_QUIC_QUIC_CRYPTO_STREAM_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/crypto/crypto_framer.h"
#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/quic_config.h"
@@ -39,7 +41,7 @@ class NET_EXPORT_PRIVATE QuicCryptoStream
// ReliableQuicStream implementation
void OnDataAvailable() override;
- QuicPriority EffectivePriority() const override;
+ SpdyPriority Priority() const override;
// Sends |message| to the peer.
// TODO(wtc): return a success/failure status.
@@ -47,7 +49,7 @@ class NET_EXPORT_PRIVATE QuicCryptoStream
// As above, but registers |delegate| for notification when |message| has been
// ACKed by the peer.
void SendHandshakeMessage(const CryptoHandshakeMessage& message,
- QuicAckNotifier::DelegateInterface* delegate);
+ QuicAckListenerInterface* listener);
// Performs key extraction to derive a new secret of |result_len| bytes
// dependent on |label|, |context|, and the stream's negotiated subkey secret.
diff --git a/chromium/net/quic/quic_crypto_stream_test.cc b/chromium/net/quic/quic_crypto_stream_test.cc
index 0393e97dc8f..0677a54d23a 100644
--- a/chromium/net/quic/quic_crypto_stream_test.cc
+++ b/chromium/net/quic/quic_crypto_stream_test.cc
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/crypto_protocol.h"
@@ -26,16 +27,13 @@ namespace {
class MockQuicCryptoStream : public QuicCryptoStream {
public:
explicit MockQuicCryptoStream(QuicSession* session)
- : QuicCryptoStream(session) {
- }
+ : QuicCryptoStream(session) {}
void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
messages_.push_back(message);
}
- vector<CryptoHandshakeMessage>* messages() {
- return &messages_;
- }
+ vector<CryptoHandshakeMessage>* messages() { return &messages_; }
private:
vector<CryptoHandshakeMessage> messages_;
@@ -46,7 +44,7 @@ class MockQuicCryptoStream : public QuicCryptoStream {
class QuicCryptoStreamTest : public ::testing::Test {
public:
QuicCryptoStreamTest()
- : connection_(new MockConnection(Perspective::IS_CLIENT)),
+ : connection_(new MockConnection(&helper_, Perspective::IS_CLIENT)),
session_(connection_),
stream_(&session_) {
message_.set_tag(kSHLO);
@@ -61,6 +59,7 @@ class QuicCryptoStreamTest : public ::testing::Test {
}
protected:
+ MockConnectionHelper helper_;
MockConnection* connection_;
MockQuicSpdySession session_;
MockQuicCryptoStream stream_;
@@ -90,14 +89,14 @@ TEST_F(QuicCryptoStreamTest, ProcessRawData) {
TEST_F(QuicCryptoStreamTest, ProcessBadData) {
string bad(message_data_->data(), message_data_->length());
- const int kFirstTagIndex = sizeof(uint32) + // message tag
- sizeof(uint16) + // number of tag-value pairs
- sizeof(uint16); // padding
+ const int kFirstTagIndex = sizeof(uint32_t) + // message tag
+ sizeof(uint16_t) + // number of tag-value pairs
+ sizeof(uint16_t); // padding
EXPECT_EQ(1, bad[kFirstTagIndex]);
bad[kFirstTagIndex] = 0x7F; // out of order tag
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_CRYPTO_TAGS_OUT_OF_ORDER, testing::_));
stream_.OnStreamFrame(
QuicStreamFrame(kCryptoStreamId, /*fin=*/false, /*offset=*/0, bad));
}
diff --git a/chromium/net/quic/quic_data_reader.cc b/chromium/net/quic/quic_data_reader.cc
index 7542c831139..191263b1b26 100644
--- a/chromium/net/quic/quic_data_reader.cc
+++ b/chromium/net/quic/quic_data_reader.cc
@@ -12,25 +12,22 @@ using base::StringPiece;
namespace net {
QuicDataReader::QuicDataReader(const char* data, const size_t len)
- : data_(data),
- len_(len),
- pos_(0) {
-}
+ : data_(data), len_(len), pos_(0) {}
-bool QuicDataReader::ReadUInt16(uint16* result) {
+bool QuicDataReader::ReadUInt16(uint16_t* result) {
return ReadBytes(result, sizeof(*result));
}
-bool QuicDataReader::ReadUInt32(uint32* result) {
+bool QuicDataReader::ReadUInt32(uint32_t* result) {
return ReadBytes(result, sizeof(*result));
}
-bool QuicDataReader::ReadUInt64(uint64* result) {
+bool QuicDataReader::ReadUInt64(uint64_t* result) {
return ReadBytes(result, sizeof(*result));
}
-bool QuicDataReader::ReadUFloat16(uint64* result) {
- uint16 value;
+bool QuicDataReader::ReadUFloat16(uint64_t* result) {
+ uint16_t value;
if (!ReadUInt16(&value)) {
return false;
}
@@ -44,7 +41,8 @@ bool QuicDataReader::ReadUFloat16(uint64* result) {
return true;
}
- uint16 exponent = value >> kUFloat16MantissaBits; // No sign extend on uint!
+ uint16_t exponent =
+ value >> kUFloat16MantissaBits; // No sign extend on uint!
// After the fast pass, the exponent is at least one (offset by one).
// Un-offset the exponent.
--exponent;
@@ -62,7 +60,7 @@ bool QuicDataReader::ReadUFloat16(uint64* result) {
bool QuicDataReader::ReadStringPiece16(StringPiece* result) {
// Read resultant length.
- uint16 result_len;
+ uint16_t result_len;
if (!ReadUInt16(&result_len)) {
// OnFailure() already called.
return false;
diff --git a/chromium/net/quic/quic_data_reader.h b/chromium/net/quic/quic_data_reader.h
index 5e05fcd25a7..970e5b208f3 100644
--- a/chromium/net/quic/quic_data_reader.h
+++ b/chromium/net/quic/quic_data_reader.h
@@ -5,9 +5,12 @@
#ifndef NET_QUIC_QUIC_DATA_READER_H_
#define NET_QUIC_QUIC_DATA_READER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <cstddef>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/int128.h"
#include "net/base/net_export.h"
@@ -39,22 +42,22 @@ class NET_EXPORT_PRIVATE QuicDataReader {
// Reads a 16-bit unsigned integer into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUInt16(uint16* result);
+ bool ReadUInt16(uint16_t* result);
// Reads a 32-bit unsigned integer into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUInt32(uint32* result);
+ bool ReadUInt32(uint32_t* result);
// Reads a 64-bit unsigned integer into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUInt64(uint64* result);
+ bool ReadUInt64(uint64_t* result);
// Reads a 16-bit unsigned float into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUFloat16(uint64* result);
+ bool ReadUFloat16(uint64_t* result);
// Reads a string prefixed with 16-bit length into the given output parameter.
//
diff --git a/chromium/net/quic/quic_data_stream.cc b/chromium/net/quic/quic_data_stream.cc
deleted file mode 100644
index af5c5de95b4..00000000000
--- a/chromium/net/quic/quic_data_stream.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2013 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/quic_data_stream.h"
-
-#include "base/logging.h"
-#include "net/quic/quic_spdy_session.h"
-#include "net/quic/quic_utils.h"
-#include "net/quic/quic_write_blocked_list.h"
-
-using base::StringPiece;
-using std::min;
-
-namespace net {
-
-#define ENDPOINT \
- (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client:" \
- " ")
-
-namespace {
-
-// 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.
-QuicPriority kDefaultPriority = 3;
-
-} // namespace
-
-QuicDataStream::QuicDataStream(QuicStreamId id, QuicSpdySession* spdy_session)
- : ReliableQuicStream(id, spdy_session),
- spdy_session_(spdy_session),
- visitor_(nullptr),
- headers_decompressed_(false),
- priority_(kDefaultPriority) {
- DCHECK_NE(kCryptoStreamId, id);
- // Don't receive any callbacks from the sequencer until headers
- // are complete.
- sequencer()->SetBlockedUntilFlush();
-}
-
-QuicDataStream::~QuicDataStream() {
-}
-
-size_t QuicDataStream::WriteHeaders(
- const SpdyHeaderBlock& header_block,
- bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
- size_t bytes_written = spdy_session_->WriteHeaders(
- id(), header_block, fin, priority_, ack_notifier_delegate);
- if (fin) {
- // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
- set_fin_sent(true);
- CloseWriteSide();
- }
- return bytes_written;
-}
-
-size_t QuicDataStream::Readv(const struct iovec* iov, size_t iov_len) {
- DCHECK(FinishedReadingHeaders());
- return sequencer()->Readv(iov, iov_len);
-}
-
-int QuicDataStream::GetReadableRegions(iovec* iov, size_t iov_len) const {
- DCHECK(FinishedReadingHeaders());
- return sequencer()->GetReadableRegions(iov, iov_len);
-}
-
-void QuicDataStream::MarkConsumed(size_t num_bytes) {
- DCHECK(FinishedReadingHeaders());
- return sequencer()->MarkConsumed(num_bytes);
-}
-
-bool QuicDataStream::IsDoneReading() const {
- if (!headers_decompressed_ || !decompressed_headers_.empty()) {
- return false;
- }
- return sequencer()->IsClosed();
-}
-
-bool QuicDataStream::HasBytesToRead() const {
- return !decompressed_headers_.empty() || sequencer()->HasBytesToRead();
-}
-
-void QuicDataStream::MarkHeadersConsumed(size_t bytes_consumed) {
- decompressed_headers_.erase(0, bytes_consumed);
- if (FinishedReadingHeaders()) {
- sequencer()->SetUnblocked();
- }
-}
-
-void QuicDataStream::set_priority(QuicPriority priority) {
- DCHECK_EQ(0u, stream_bytes_written());
- priority_ = priority;
-}
-
-QuicPriority QuicDataStream::EffectivePriority() const {
- return priority();
-}
-
-void QuicDataStream::OnStreamHeaders(StringPiece headers_data) {
- headers_data.AppendToString(&decompressed_headers_);
-}
-
-void QuicDataStream::OnStreamHeadersPriority(QuicPriority priority) {
- DCHECK_EQ(Perspective::IS_SERVER, session()->connection()->perspective());
- set_priority(priority);
-}
-
-void QuicDataStream::OnStreamHeadersComplete(bool fin, size_t frame_len) {
- headers_decompressed_ = true;
- if (fin) {
- OnStreamFrame(QuicStreamFrame(id(), fin, 0, StringPiece()));
- }
- if (FinishedReadingHeaders()) {
- sequencer()->SetUnblocked();
- }
-}
-
-void QuicDataStream::OnClose() {
- ReliableQuicStream::OnClose();
-
- if (visitor_) {
- Visitor* visitor = visitor_;
- // Calling Visitor::OnClose() may result the destruction of the visitor,
- // so we need to ensure we don't call it again.
- visitor_ = nullptr;
- visitor->OnClose(this);
- }
-}
-
-bool QuicDataStream::FinishedReadingHeaders() const {
- return headers_decompressed_ && decompressed_headers_.empty();
-}
-
-} // namespace net
diff --git a/chromium/net/quic/quic_data_stream.h b/chromium/net/quic/quic_data_stream.h
deleted file mode 100644
index 1b66f9a64c3..00000000000
--- a/chromium/net/quic/quic_data_stream.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2013 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.
-//
-// The base class for streams which deliver data to/from an application.
-// In each direction, the data on such a stream first contains compressed
-// headers then body data.
-
-#ifndef NET_QUIC_QUIC_DATA_STREAM_H_
-#define NET_QUIC_QUIC_DATA_STREAM_H_
-
-#include <sys/types.h>
-
-#include <list>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/strings/string_piece.h"
-#include "net/base/iovec.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_export.h"
-#include "net/quic/quic_ack_notifier.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_stream_sequencer.h"
-#include "net/quic/reliable_quic_stream.h"
-#include "net/spdy/spdy_framer.h"
-
-namespace net {
-
-namespace test {
-class QuicDataStreamPeer;
-class ReliableQuicStreamPeer;
-} // namespace test
-
-class QuicSpdySession;
-
-// A QUIC data stream that can also send and receive headers.
-class NET_EXPORT_PRIVATE QuicDataStream : public ReliableQuicStream {
- public:
- // Visitor receives callbacks from the stream.
- class NET_EXPORT_PRIVATE Visitor {
- public:
- Visitor() {}
-
- // Called when the stream is closed.
- virtual void OnClose(QuicDataStream* stream) = 0;
-
- protected:
- virtual ~Visitor() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Visitor);
- };
-
- QuicDataStream(QuicStreamId id, QuicSpdySession* spdy_session);
- ~QuicDataStream() override;
-
- // ReliableQuicStream implementation
- void OnClose() override;
-
- // By default, this is the same as priority(), however it allows streams
- // to temporarily alter effective priority. For example if a SPDY stream has
- // compressed but not written headers it can write the headers with a higher
- // priority.
- QuicPriority EffectivePriority() const override;
-
- // Called by the session when decompressed headers data is received
- // for this stream.
- // May be called multiple times, with each call providing additional headers
- // data until OnStreamHeadersComplete is called.
- virtual void OnStreamHeaders(base::StringPiece headers_data);
-
- // Called by the session when headers with a priority have been received
- // for this stream. This method will only be called for server streams.
- virtual void OnStreamHeadersPriority(QuicPriority priority);
-
- // Called by the session when decompressed headers have been completely
- // delilvered to this stream. If |fin| is true, then this stream
- // should be closed; no more data will be sent by the peer.
- virtual void OnStreamHeadersComplete(bool fin, size_t frame_len);
-
- // Writes the headers contained in |header_block| to the dedicated
- // headers stream.
- virtual size_t WriteHeaders(
- const SpdyHeaderBlock& header_block,
- bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
-
- // Marks |bytes_consumed| of the headers data as consumed.
- void MarkHeadersConsumed(size_t bytes_consumed);
-
- // This block of functions wraps the sequencer's functions of the same
- // name. These methods return uncompressed data until that has
- // been fully processed. Then they simply delegate to the sequencer.
- virtual size_t Readv(const struct iovec* iov, size_t iov_len);
- virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
- void MarkConsumed(size_t num_bytes);
-
- // Returns true when all data has been read from the peer, including the fin.
- bool IsDoneReading() const;
- bool HasBytesToRead() const;
-
- void set_visitor(Visitor* visitor) { visitor_ = visitor; }
-
- bool headers_decompressed() const { return headers_decompressed_; }
-
- const std::string& decompressed_headers() const {
- return decompressed_headers_;
- }
-
- protected:
- // Sets priority_ to priority. This should only be called before bytes are
- // written to the server.
- void set_priority(QuicPriority priority);
- // This is protected because external classes should use EffectivePriority
- // instead.
- QuicPriority priority() const { return priority_; }
-
- bool FinishedReadingHeaders() const;
-
- private:
- friend class test::QuicDataStreamPeer;
- friend class test::ReliableQuicStreamPeer;
- friend class QuicStreamUtils;
-
- QuicSpdySession* spdy_session_;
-
- Visitor* visitor_;
- // True if the headers have been completely decompressed.
- bool headers_decompressed_;
- // The priority of the stream, once parsed.
- QuicPriority priority_;
- // Contains a copy of the decompressed headers until they are consumed
- // via ProcessData or Readv.
- std::string decompressed_headers_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicDataStream);
-};
-
-} // namespace net
-
-#endif // NET_QUIC_QUIC_DATA_STREAM_H_
diff --git a/chromium/net/quic/quic_data_writer.cc b/chromium/net/quic/quic_data_writer.cc
index 49257829389..81cc7127f7e 100644
--- a/chromium/net/quic/quic_data_writer.cc
+++ b/chromium/net/quic/quic_data_writer.cc
@@ -14,54 +14,52 @@ using std::numeric_limits;
namespace net {
QuicDataWriter::QuicDataWriter(size_t size, char* buffer)
- : buffer_(buffer), capacity_(size), length_(0) {
-}
+ : buffer_(buffer), capacity_(size), length_(0) {}
-QuicDataWriter::~QuicDataWriter() {
-}
+QuicDataWriter::~QuicDataWriter() {}
char* QuicDataWriter::data() {
return buffer_;
}
-bool QuicDataWriter::WriteUInt8(uint8 value) {
+bool QuicDataWriter::WriteUInt8(uint8_t value) {
return WriteBytes(&value, sizeof(value));
}
-bool QuicDataWriter::WriteUInt16(uint16 value) {
+bool QuicDataWriter::WriteUInt16(uint16_t value) {
return WriteBytes(&value, sizeof(value));
}
-bool QuicDataWriter::WriteUInt32(uint32 value) {
+bool QuicDataWriter::WriteUInt32(uint32_t value) {
return WriteBytes(&value, sizeof(value));
}
-bool QuicDataWriter::WriteUInt48(uint64 value) {
- uint16 hi = static_cast<uint16>(value >> 32);
- uint32 lo = static_cast<uint32>(value);
+bool QuicDataWriter::WriteUInt48(uint64_t value) {
+ uint16_t hi = static_cast<uint16_t>(value >> 32);
+ uint32_t lo = static_cast<uint32_t>(value);
return WriteUInt32(lo) && WriteUInt16(hi);
}
-bool QuicDataWriter::WriteUInt64(uint64 value) {
+bool QuicDataWriter::WriteUInt64(uint64_t value) {
return WriteBytes(&value, sizeof(value));
}
-bool QuicDataWriter::WriteUFloat16(uint64 value) {
- uint16 result;
+bool QuicDataWriter::WriteUFloat16(uint64_t value) {
+ uint16_t result;
if (value < (UINT64_C(1) << kUFloat16MantissaEffectiveBits)) {
// Fast path: either the value is denormalized, or has exponent zero.
// Both cases are represented by the value itself.
- result = static_cast<uint16>(value);
+ result = static_cast<uint16_t>(value);
} else if (value >= kUFloat16MaxValue) {
// Value is out of range; clamp it to the maximum representable.
- result = numeric_limits<uint16>::max();
+ result = numeric_limits<uint16_t>::max();
} else {
// The highest bit is between position 13 and 42 (zero-based), which
// corresponds to exponent 1-30. In the output, mantissa is from 0 to 10,
// hidden bit is 11 and exponent is 11 to 15. Shift the highest bit to 11
// and count the shifts.
- uint16 exponent = 0;
- for (uint16 offset = 16; offset > 0; offset /= 2) {
+ uint16_t exponent = 0;
+ for (uint16_t offset = 16; offset > 0; offset /= 2) {
// Right-shift the value until the highest bit is in position 11.
// For offset of 16, 8, 4, 2 and 1 (binary search over 1-30),
// shift if the bit is at or above 11 + offset.
@@ -79,17 +77,17 @@ bool QuicDataWriter::WriteUFloat16(uint64 value) {
// Hidden bit (position 11) is set. We should remove it and increment the
// exponent. Equivalently, we just add it to the exponent.
// This hides the bit.
- result = static_cast<uint16>(value + (exponent << kUFloat16MantissaBits));
+ result = static_cast<uint16_t>(value + (exponent << kUFloat16MantissaBits));
}
return WriteBytes(&result, sizeof(result));
}
bool QuicDataWriter::WriteStringPiece16(StringPiece val) {
- if (val.size() > numeric_limits<uint16>::max()) {
+ if (val.size() > numeric_limits<uint16_t>::max()) {
return false;
}
- if (!WriteUInt16(static_cast<uint16>(val.size()))) {
+ if (!WriteUInt16(static_cast<uint16_t>(val.size()))) {
return false;
}
return WriteBytes(val.data(), val.size());
@@ -105,7 +103,7 @@ char* QuicDataWriter::BeginWrite(size_t length) {
}
#ifdef ARCH_CPU_64_BITS
- DCHECK_LE(length, std::numeric_limits<uint32>::max());
+ DCHECK_LE(length, std::numeric_limits<uint32_t>::max());
#endif
return buffer_ + length_;
@@ -123,7 +121,7 @@ bool QuicDataWriter::WriteBytes(const void* data, size_t data_len) {
return true;
}
-bool QuicDataWriter::WriteRepeatedByte(uint8 byte, size_t count) {
+bool QuicDataWriter::WriteRepeatedByte(uint8_t byte, size_t count) {
char* dest = BeginWrite(count);
if (!dest) {
return false;
@@ -144,5 +142,4 @@ void QuicDataWriter::WritePadding() {
length_ = capacity_;
}
-
} // namespace net
diff --git a/chromium/net/quic/quic_data_writer.h b/chromium/net/quic/quic_data_writer.h
index 0f1df204654..dfe0fdaab52 100644
--- a/chromium/net/quic/quic_data_writer.h
+++ b/chromium/net/quic/quic_data_writer.h
@@ -5,11 +5,14 @@
#ifndef NET_QUIC_QUIC_DATA_WRITER_H_
#define NET_QUIC_QUIC_DATA_WRITER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <cstddef>
#include <string>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/int128.h"
#include "net/base/net_export.h"
@@ -38,24 +41,22 @@ class NET_EXPORT_PRIVATE QuicDataWriter {
// Methods for adding to the payload. These values are appended to the end
// of the QuicDataWriter payload. Note - binary integers are written in
// host byte order (little endian) not network byte order (big endian).
- bool WriteUInt8(uint8 value);
- bool WriteUInt16(uint16 value);
- bool WriteUInt32(uint32 value);
- bool WriteUInt48(uint64 value);
- bool WriteUInt64(uint64 value);
+ bool WriteUInt8(uint8_t value);
+ bool WriteUInt16(uint16_t value);
+ bool WriteUInt32(uint32_t value);
+ bool WriteUInt48(uint64_t value);
+ bool WriteUInt64(uint64_t value);
// Write unsigned floating point corresponding to the value. Large values are
// clamped to the maximum representable (kUFloat16MaxValue). Values that can
// not be represented directly are rounded down.
- bool WriteUFloat16(uint64 value);
+ bool WriteUFloat16(uint64_t value);
bool WriteStringPiece16(base::StringPiece val);
bool WriteBytes(const void* data, size_t data_len);
- bool WriteRepeatedByte(uint8 byte, size_t count);
+ bool WriteRepeatedByte(uint8_t byte, size_t count);
// Fills the remaining buffer with null characters.
void WritePadding();
- size_t capacity() const {
- return capacity_;
- }
+ size_t capacity() const { return capacity_; }
private:
// Returns the location that the data should be written at, or nullptr if
diff --git a/chromium/net/quic/quic_data_writer_test.cc b/chromium/net/quic/quic_data_writer_test.cc
index d34e5cef570..b3d6e7770bd 100644
--- a/chromium/net/quic/quic_data_writer_test.cc
+++ b/chromium/net/quic/quic_data_writer_test.cc
@@ -26,34 +26,71 @@ TEST(QuicDataWriterTest, SanityCheckUFloat16Consts) {
TEST(QuicDataWriterTest, WriteUFloat16) {
struct TestCase {
- uint64 decoded;
- uint16 encoded;
+ uint64_t decoded;
+ uint16_t encoded;
};
TestCase test_cases[] = {
- // Small numbers represent themselves.
- { 0, 0 }, { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 },
- { 7, 7 }, { 15, 15 }, { 31, 31 }, { 42, 42 }, { 123, 123 }, { 1234, 1234 },
- // Check transition through 2^11.
- { 2046, 2046 }, { 2047, 2047 }, { 2048, 2048 }, { 2049, 2049 },
- // Running out of mantissa at 2^12.
- { 4094, 4094 }, { 4095, 4095 }, { 4096, 4096 }, { 4097, 4096 },
- { 4098, 4097 }, { 4099, 4097 }, { 4100, 4098 }, { 4101, 4098 },
- // Check transition through 2^13.
- { 8190, 6143 }, { 8191, 6143 }, { 8192, 6144 }, { 8193, 6144 },
- { 8194, 6144 }, { 8195, 6144 }, { 8196, 6145 }, { 8197, 6145 },
- // Half-way through the exponents.
- { 0x7FF8000, 0x87FF }, { 0x7FFFFFF, 0x87FF }, { 0x8000000, 0x8800 },
- { 0xFFF0000, 0x8FFF }, { 0xFFFFFFF, 0x8FFF }, { 0x10000000, 0x9000 },
- // Transition into the largest exponent.
- { 0x1FFFFFFFFFE, 0xF7FF}, { 0x1FFFFFFFFFF, 0xF7FF},
- { 0x20000000000, 0xF800}, { 0x20000000001, 0xF800},
- { 0x2003FFFFFFE, 0xF800}, { 0x2003FFFFFFF, 0xF800},
- { 0x20040000000, 0xF801}, { 0x20040000001, 0xF801},
- // Transition into the max value and clamping.
- { 0x3FF80000000, 0xFFFE}, { 0x3FFBFFFFFFF, 0xFFFE},
- { 0x3FFC0000000, 0xFFFF}, { 0x3FFC0000001, 0xFFFF},
- { 0x3FFFFFFFFFF, 0xFFFF}, { 0x40000000000, 0xFFFF},
- { 0xFFFFFFFFFFFFFFFF, 0xFFFF},
+ // Small numbers represent themselves.
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {4, 4},
+ {5, 5},
+ {6, 6},
+ {7, 7},
+ {15, 15},
+ {31, 31},
+ {42, 42},
+ {123, 123},
+ {1234, 1234},
+ // Check transition through 2^11.
+ {2046, 2046},
+ {2047, 2047},
+ {2048, 2048},
+ {2049, 2049},
+ // Running out of mantissa at 2^12.
+ {4094, 4094},
+ {4095, 4095},
+ {4096, 4096},
+ {4097, 4096},
+ {4098, 4097},
+ {4099, 4097},
+ {4100, 4098},
+ {4101, 4098},
+ // Check transition through 2^13.
+ {8190, 6143},
+ {8191, 6143},
+ {8192, 6144},
+ {8193, 6144},
+ {8194, 6144},
+ {8195, 6144},
+ {8196, 6145},
+ {8197, 6145},
+ // Half-way through the exponents.
+ {0x7FF8000, 0x87FF},
+ {0x7FFFFFF, 0x87FF},
+ {0x8000000, 0x8800},
+ {0xFFF0000, 0x8FFF},
+ {0xFFFFFFF, 0x8FFF},
+ {0x10000000, 0x9000},
+ // Transition into the largest exponent.
+ {0x1FFFFFFFFFE, 0xF7FF},
+ {0x1FFFFFFFFFF, 0xF7FF},
+ {0x20000000000, 0xF800},
+ {0x20000000001, 0xF800},
+ {0x2003FFFFFFE, 0xF800},
+ {0x2003FFFFFFF, 0xF800},
+ {0x20040000000, 0xF801},
+ {0x20040000001, 0xF801},
+ // Transition into the max value and clamping.
+ {0x3FF80000000, 0xFFFE},
+ {0x3FFBFFFFFFF, 0xFFFE},
+ {0x3FFC0000000, 0xFFFF},
+ {0x3FFC0000001, 0xFFFF},
+ {0x3FFFFFFFFFF, 0xFFFF},
+ {0x40000000000, 0xFFFF},
+ {0xFFFFFFFFFFFFFFFF, 0xFFFF},
};
int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
@@ -61,42 +98,66 @@ TEST(QuicDataWriterTest, WriteUFloat16) {
char buffer[2];
QuicDataWriter writer(2, buffer);
EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
- EXPECT_EQ(test_cases[i].encoded, *reinterpret_cast<uint16*>(writer.data()));
+ EXPECT_EQ(test_cases[i].encoded,
+ *reinterpret_cast<uint16_t*>(writer.data()));
}
}
TEST(QuicDataWriterTest, ReadUFloat16) {
struct TestCase {
- uint64 decoded;
- uint16 encoded;
+ uint64_t decoded;
+ uint16_t encoded;
};
TestCase test_cases[] = {
- // There are fewer decoding test cases because encoding truncates, and
- // decoding returns the smallest expansion.
- // Small numbers represent themselves.
- { 0, 0 }, { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 },
- { 7, 7 }, { 15, 15 }, { 31, 31 }, { 42, 42 }, { 123, 123 }, { 1234, 1234 },
- // Check transition through 2^11.
- { 2046, 2046 }, { 2047, 2047 }, { 2048, 2048 }, { 2049, 2049 },
- // Running out of mantissa at 2^12.
- { 4094, 4094 }, { 4095, 4095 }, { 4096, 4096 },
- { 4098, 4097 }, { 4100, 4098 },
- // Check transition through 2^13.
- { 8190, 6143 }, { 8192, 6144 }, { 8196, 6145 },
- // Half-way through the exponents.
- { 0x7FF8000, 0x87FF }, { 0x8000000, 0x8800 },
- { 0xFFF0000, 0x8FFF }, { 0x10000000, 0x9000 },
- // Transition into the largest exponent.
- { 0x1FFE0000000, 0xF7FF}, { 0x20000000000, 0xF800},
- { 0x20040000000, 0xF801},
- // Transition into the max value.
- { 0x3FF80000000, 0xFFFE}, { 0x3FFC0000000, 0xFFFF},
+ // There are fewer decoding test cases because encoding truncates, and
+ // decoding returns the smallest expansion.
+ // Small numbers represent themselves.
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {4, 4},
+ {5, 5},
+ {6, 6},
+ {7, 7},
+ {15, 15},
+ {31, 31},
+ {42, 42},
+ {123, 123},
+ {1234, 1234},
+ // Check transition through 2^11.
+ {2046, 2046},
+ {2047, 2047},
+ {2048, 2048},
+ {2049, 2049},
+ // Running out of mantissa at 2^12.
+ {4094, 4094},
+ {4095, 4095},
+ {4096, 4096},
+ {4098, 4097},
+ {4100, 4098},
+ // Check transition through 2^13.
+ {8190, 6143},
+ {8192, 6144},
+ {8196, 6145},
+ // Half-way through the exponents.
+ {0x7FF8000, 0x87FF},
+ {0x8000000, 0x8800},
+ {0xFFF0000, 0x8FFF},
+ {0x10000000, 0x9000},
+ // Transition into the largest exponent.
+ {0x1FFE0000000, 0xF7FF},
+ {0x20000000000, 0xF800},
+ {0x20040000000, 0xF801},
+ // Transition into the max value.
+ {0x3FF80000000, 0xFFFE},
+ {0x3FFC0000000, 0xFFFF},
};
int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
for (int i = 0; i < num_test_cases; ++i) {
QuicDataReader reader(reinterpret_cast<char*>(&test_cases[i].encoded), 2);
- uint64 value;
+ uint64_t value;
EXPECT_TRUE(reader.ReadUFloat16(&value));
EXPECT_EQ(test_cases[i].decoded, value);
}
@@ -104,11 +165,11 @@ TEST(QuicDataWriterTest, ReadUFloat16) {
TEST(QuicDataWriterTest, RoundTripUFloat16) {
// Just test all 16-bit encoded values. 0 and max already tested above.
- uint64 previous_value = 0;
- for (uint16 i = 1; i < 0xFFFF; ++i) {
+ uint64_t previous_value = 0;
+ for (uint16_t i = 1; i < 0xFFFF; ++i) {
// Read the two bytes.
QuicDataReader reader(reinterpret_cast<char*>(&i), 2);
- uint64 value;
+ uint64_t value;
// All values must be decodable.
EXPECT_TRUE(reader.ReadUFloat16(&value));
// Check that small numbers represent themselves
@@ -128,12 +189,12 @@ TEST(QuicDataWriterTest, RoundTripUFloat16) {
EXPECT_TRUE(writer.WriteUFloat16(value));
EXPECT_TRUE(writer.WriteUFloat16(value + 1));
// Check minimal decoding (previous decoding has previous encoding).
- EXPECT_EQ(i - 1, *reinterpret_cast<uint16*>(writer.data()));
+ EXPECT_EQ(i - 1, *reinterpret_cast<uint16_t*>(writer.data()));
// Check roundtrip.
- EXPECT_EQ(i, *reinterpret_cast<uint16*>(writer.data() + 2));
+ EXPECT_EQ(i, *reinterpret_cast<uint16_t*>(writer.data() + 2));
// Check next decoding.
EXPECT_EQ(i < 4096 ? i + 1 : i,
- *reinterpret_cast<uint16*>(writer.data() + 4));
+ *reinterpret_cast<uint16_t*>(writer.data() + 4));
}
}
diff --git a/chromium/net/quic/quic_default_packet_writer.cc b/chromium/net/quic/quic_default_packet_writer.cc
index f81a2272594..a8baf1bcd95 100644
--- a/chromium/net/quic/quic_default_packet_writer.cc
+++ b/chromium/net/quic/quic_default_packet_writer.cc
@@ -13,8 +13,7 @@
namespace net {
-QuicDefaultPacketWriter::QuicDefaultPacketWriter() : weak_factory_(this) {
-}
+QuicDefaultPacketWriter::QuicDefaultPacketWriter() : weak_factory_(this) {}
QuicDefaultPacketWriter::QuicDefaultPacketWriter(Socket* socket)
: socket_(socket), write_blocked_(false), weak_factory_(this) {}
@@ -30,8 +29,7 @@ WriteResult QuicDefaultPacketWriter::WritePacket(
new StringIOBuffer(std::string(buffer, buf_len)));
DCHECK(!IsWriteBlocked());
base::TimeTicks now = base::TimeTicks::Now();
- int rv = socket_->Write(buf.get(),
- buf_len,
+ int rv = socket_->Write(buf.get(), buf_len,
base::Bind(&QuicDefaultPacketWriter::OnWriteComplete,
weak_factory_.GetWeakPtr()));
WriteStatus status = WRITE_STATUS_OK;
diff --git a/chromium/net/quic/quic_default_packet_writer.h b/chromium/net/quic/quic_default_packet_writer.h
index a045ebdcb49..7d03a049d8e 100644
--- a/chromium/net/quic/quic_default_packet_writer.h
+++ b/chromium/net/quic/quic_default_packet_writer.h
@@ -5,7 +5,9 @@
#ifndef NET_QUIC_QUIC_DEFAULT_PACKET_WRITER_H_
#define NET_QUIC_QUIC_DEFAULT_PACKET_WRITER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_connection.h"
@@ -35,14 +37,10 @@ class NET_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
QuicByteCount GetMaxPacketSize(const IPEndPoint& peer_address) const override;
void OnWriteComplete(int rv);
- void SetConnection(QuicConnection* connection) {
- connection_ = connection;
- }
+ void SetConnection(QuicConnection* connection) { connection_ = connection; }
protected:
- void set_write_blocked(bool is_blocked) {
- write_blocked_ = is_blocked;
- }
+ void set_write_blocked(bool is_blocked) { write_blocked_ = is_blocked; }
private:
Socket* socket_;
diff --git a/chromium/net/quic/quic_end_to_end_unittest.cc b/chromium/net/quic/quic_end_to_end_unittest.cc
index 86bb9cdd23d..a37895bcef1 100644
--- a/chromium/net/quic/quic_end_to_end_unittest.cc
+++ b/chromium/net/quic/quic_end_to_end_unittest.cc
@@ -2,16 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
+#include <utility>
+#include <vector>
+
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/test_completion_callback.h"
+#include "net/base/test_data_directory.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_data_stream.h"
#include "net/cert/mock_cert_verifier.h"
+#include "net/cert/multi_log_ct_verifier.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
@@ -21,8 +25,10 @@
#include "net/http/http_transaction_test_util.h"
#include "net/http/transport_security_state.h"
#include "net/proxy/proxy_service.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/ssl/ssl_config_service_defaults.h"
+#include "net/test/cert_test_util.h"
#include "net/tools/quic/quic_in_memory_cache.h"
#include "net/tools/quic/quic_server.h"
#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
@@ -48,7 +54,7 @@ const char kResponseBody[] = "some arbitrary response body";
// Factory for creating HttpTransactions, used by TestTransactionConsumer.
class TestTransactionFactory : public HttpTransactionFactory {
public:
- TestTransactionFactory(const HttpNetworkSession::Params& params)
+ explicit TestTransactionFactory(const HttpNetworkSession::Params& params)
: session_(new HttpNetworkSession(params)) {}
~TestTransactionFactory() override {}
@@ -65,7 +71,7 @@ class TestTransactionFactory : public HttpTransactionFactory {
HttpNetworkSession* GetSession() override { return session_.get(); };
private:
- scoped_refptr<HttpNetworkSession> session_;
+ scoped_ptr<HttpNetworkSession> session_;
};
} // namespace
@@ -74,14 +80,15 @@ class QuicEndToEndTest : public PlatformTest {
protected:
QuicEndToEndTest()
: host_resolver_impl_(CreateResolverImpl()),
- host_resolver_(host_resolver_impl_.Pass()),
+ host_resolver_(std::move(host_resolver_impl_)),
+ cert_transparency_verifier_(new MultiLogCTVerifier()),
ssl_config_service_(new SSLConfigServiceDefaults),
proxy_service_(ProxyService::CreateDirect()),
auth_handler_factory_(
HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
strike_register_no_startup_period_(false) {
request_.method = "GET";
- request_.url = GURL("http://www.google.com/");
+ request_.url = GURL("https://test.example.com/");
request_.load_flags = 0;
params_.enable_quic = true;
@@ -90,17 +97,30 @@ class QuicEndToEndTest : public PlatformTest {
params_.host_resolver = &host_resolver_;
params_.cert_verifier = &cert_verifier_;
params_.transport_security_state = &transport_security_state_;
+ params_.cert_transparency_verifier = cert_transparency_verifier_.get();
params_.proxy_service = proxy_service_.get();
params_.ssl_config_service = ssl_config_service_.get();
params_.http_auth_handler_factory = auth_handler_factory_.get();
params_.http_server_properties = http_server_properties.GetWeakPtr();
+
+ net::CertVerifyResult verify_result;
+ verify_result.verified_cert = ImportCertFromFile(
+ GetTestCertsDirectory(), "quic_test.example.com.crt");
+ cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
+ "test.example.com", verify_result,
+ OK);
+ verify_result.verified_cert = ImportCertFromFile(
+ GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
+ cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
+ "test.example.com", verify_result,
+ OK);
}
- // Creates a mock host resolver in which www.google.com
+ // Creates a mock host resolver in which test.example.com
// resolves to localhost.
static MockHostResolver* CreateResolverImpl() {
MockHostResolver* resolver = new MockHostResolver();
- resolver->rules()->AddRule("www.google.com", "127.0.0.1");
+ resolver->rules()->AddRule("test.example.com", "127.0.0.1");
return resolver;
}
@@ -108,16 +128,16 @@ class QuicEndToEndTest : public PlatformTest {
QuicInMemoryCachePeer::ResetForTests();
StartServer();
- // Use a mapped host resolver so that request for www.google.com (port 80)
+ // Use a mapped host resolver so that request for test.example.com (port 80)
// reach the server running on localhost.
- std::string map_rule = "MAP www.google.com www.google.com:" +
- base::IntToString(server_thread_->GetPort());
+ std::string map_rule = "MAP test.example.com test.example.com:" +
+ base::IntToString(server_thread_->GetPort());
EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));
// To simplify the test, and avoid the race with the HTTP request, we force
// QUIC for these requests.
params_.origin_to_force_quic_on =
- HostPortPair::FromString("www.google.com:80");
+ HostPortPair::FromString("test.example.com:443");
transaction_factory_.reset(new TestTransactionFactory(params_));
}
@@ -136,13 +156,14 @@ class QuicEndToEndTest : public PlatformTest {
kInitialStreamFlowControlWindowForTest);
server_config_.SetInitialSessionFlowControlWindowToSend(
kInitialSessionFlowControlWindowForTest);
- server_thread_.reset(new ServerThread(
- new QuicServer(server_config_, QuicSupportedVersions()),
- /*is_secure=*/true, server_address_,
- strike_register_no_startup_period_));
+ QuicServer* server =
+ new QuicServer(CryptoTestUtils::ProofSourceForTesting(), server_config_,
+ QuicSupportedVersions());
+ server_thread_.reset(new ServerThread(server, server_address_,
+ strike_register_no_startup_period_));
server_thread_->Initialize();
- server_address_ = IPEndPoint(server_address_.address(),
- server_thread_->GetPort());
+ server_address_ =
+ IPEndPoint(server_address_.address(), server_thread_->GetPort());
server_thread_->Start();
server_started_ = true;
}
@@ -165,7 +186,7 @@ class QuicEndToEndTest : public PlatformTest {
StringPiece response_detail,
StringPiece body) {
QuicInMemoryCache::GetInstance()->AddSimpleResponse(
- "www.google.com", path, response_code, response_detail, body);
+ "test.example.com", path, response_code, body);
}
// Populates |request_body_| with |length_| ASCII bytes.
@@ -180,14 +201,13 @@ class QuicEndToEndTest : public PlatformTest {
// Initializes |request_| for a post of |length| bytes.
void InitializePostRequest(size_t length) {
GenerateBody(length);
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(
- new UploadBytesElementReader(request_body_.data(),
- request_body_.length()));
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+ request_body_.data(), request_body_.length())));
upload_data_stream_.reset(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
request_.method = "POST";
- request_.url = GURL("http://www.google.com/");
+ request_.url = GURL("https://test.example.com/");
request_.upload_data_stream = upload_data_stream_.get();
ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
}
@@ -197,9 +217,8 @@ class QuicEndToEndTest : public PlatformTest {
const std::string& status_line,
const std::string& body) {
ASSERT_TRUE(consumer.is_done());
- EXPECT_EQ(OK, consumer.error());
- EXPECT_EQ(status_line,
- consumer.response_info()->headers->GetStatusLine());
+ ASSERT_EQ(OK, consumer.error());
+ EXPECT_EQ(status_line, consumer.response_info()->headers->GetStatusLine());
EXPECT_EQ(body, consumer.content());
}
@@ -207,6 +226,7 @@ class QuicEndToEndTest : public PlatformTest {
MappedHostResolver host_resolver_;
MockCertVerifier cert_verifier_;
TransportSecurityState transport_security_state_;
+ scoped_ptr<CTVerifier> cert_transparency_verifier_;
scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
scoped_ptr<ProxyService> proxy_service_;
scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
@@ -236,12 +256,17 @@ TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
// Will terminate when the last consumer completes.
base::MessageLoop::current()->Run();
- CheckResponse(consumer, "HTTP/1.1 200 OK", response);
+ CheckResponse(consumer, "HTTP/1.1 200", response);
}
-// http://crbug.com/307284
-TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
- InitializePostRequest(10 * 1024 * 1024);
+// crbug.com/559173
+#if defined(THREAD_SANITIZER)
+#define MAYBE_LargePostWithNoPacketLoss DISABLED_LargePostWithNoPacketLoss
+#else
+#define MAYBE_LargePostWithNoPacketLoss LargePostWithNoPacketLoss
+#endif
+TEST_F(QuicEndToEndTest, MAYBE_LargePostWithNoPacketLoss) {
+ InitializePostRequest(1024 * 1024);
AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
@@ -252,10 +277,16 @@ TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
// Will terminate when the last consumer completes.
base::MessageLoop::current()->Run();
- CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody);
+ CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
}
-TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
+// crbug.com/559173
+#if defined(THREAD_SANITIZER)
+#define MAYBE_LargePostWithPacketLoss DISABLED_LargePostWithPacketLoss
+#else
+#define MAYBE_LargePostWithPacketLoss LargePostWithPacketLoss
+#endif
+TEST_F(QuicEndToEndTest, MAYBE_LargePostWithPacketLoss) {
// FLAGS_fake_packet_loss_percentage = 30;
InitializePostRequest(1024 * 1024);
@@ -269,7 +300,7 @@ TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
// Will terminate when the last consumer completes.
base::MessageLoop::current()->Run();
- CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody);
+ CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
}
// crbug.com/536845
@@ -287,18 +318,17 @@ TEST_F(QuicEndToEndTest, MAYBE_UberTest) {
std::vector<TestTransactionConsumer*> consumers;
size_t num_requests = 100;
for (size_t i = 0; i < num_requests; ++i) {
- TestTransactionConsumer* consumer =
- new TestTransactionConsumer(DEFAULT_PRIORITY,
- transaction_factory_.get());
- consumers.push_back(consumer);
- consumer->Start(&request_, BoundNetLog());
+ TestTransactionConsumer* consumer = new TestTransactionConsumer(
+ DEFAULT_PRIORITY, transaction_factory_.get());
+ consumers.push_back(consumer);
+ consumer->Start(&request_, BoundNetLog());
}
// Will terminate when the last consumer completes.
base::MessageLoop::current()->Run();
for (size_t i = 0; i < num_requests; ++i) {
- CheckResponse(*consumers[i], "HTTP/1.1 200 OK", kResponseBody);
+ CheckResponse(*consumers[i], "HTTP/1.1 200", kResponseBody);
}
STLDeleteElements(&consumers);
}
diff --git a/chromium/net/quic/quic_fec_group.cc b/chromium/net/quic/quic_fec_group.cc
index 8bc7601b474..b6ff37409a3 100644
--- a/chromium/net/quic/quic_fec_group.cc
+++ b/chromium/net/quic/quic_fec_group.cc
@@ -6,7 +6,6 @@
#include <limits>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/stl_util.h"
@@ -16,8 +15,9 @@ using std::set;
namespace net {
-QuicFecGroup::QuicFecGroup()
- : min_protected_packet_(kInvalidPacketNumber),
+QuicFecGroup::QuicFecGroup(QuicPacketNumber fec_group_number)
+ : QuicFecGroupInterface(),
+ min_protected_packet_(fec_group_number),
max_protected_packet_(kInvalidPacketNumber),
payload_parity_len_(0),
effective_encryption_level_(NUM_ENCRYPTION_LEVELS) {}
@@ -27,22 +27,22 @@ QuicFecGroup::~QuicFecGroup() {}
bool QuicFecGroup::Update(EncryptionLevel encryption_level,
const QuicPacketHeader& header,
StringPiece decrypted_payload) {
- DCHECK_NE(kInvalidPacketNumber, header.packet_packet_number);
- if (ContainsKey(received_packets_, header.packet_packet_number)) {
+ DCHECK_EQ(min_protected_packet_, header.fec_group);
+ DCHECK_NE(kInvalidPacketNumber, header.packet_number);
+ if (ContainsKey(received_packets_, header.packet_number)) {
return false;
}
- if (min_protected_packet_ != kInvalidPacketNumber &&
- max_protected_packet_ != kInvalidPacketNumber &&
- (header.packet_packet_number < min_protected_packet_ ||
- header.packet_packet_number > max_protected_packet_)) {
+ if (header.packet_number < min_protected_packet_ ||
+ (has_received_fec_packet() &&
+ header.packet_number > max_protected_packet_)) {
DLOG(ERROR) << "FEC group does not cover received packet: "
- << header.packet_packet_number;
+ << header.packet_number;
return false;
}
if (!UpdateParity(decrypted_payload)) {
return false;
}
- received_packets_.insert(header.packet_packet_number);
+ received_packets_.insert(header.packet_number);
if (encryption_level < effective_encryption_level_) {
effective_encryption_level_ = encryption_level;
}
@@ -50,26 +50,23 @@ bool QuicFecGroup::Update(EncryptionLevel encryption_level,
}
bool QuicFecGroup::UpdateFec(EncryptionLevel encryption_level,
- QuicPacketNumber fec_packet_packet_number,
- const QuicFecData& fec) {
- DCHECK_NE(kInvalidPacketNumber, fec_packet_packet_number);
- DCHECK_NE(kInvalidPacketNumber, fec.fec_group);
- if (min_protected_packet_ != kInvalidPacketNumber) {
+ const QuicPacketHeader& header,
+ StringPiece redundancy) {
+ DCHECK_EQ(min_protected_packet_, header.fec_group);
+ DCHECK_NE(kInvalidPacketNumber, header.packet_number);
+ if (has_received_fec_packet()) {
return false;
}
- PacketNumberSet::const_iterator it = received_packets_.begin();
- while (it != received_packets_.end()) {
- if ((*it < fec.fec_group) || (*it >= fec_packet_packet_number)) {
- DLOG(ERROR) << "FEC group does not cover received packet: " << *it;
+ for (QuicPacketNumber packet : received_packets_) {
+ if (packet >= header.packet_number) {
+ DLOG(ERROR) << "FEC group does not cover received packet: " << packet;
return false;
}
- ++it;
}
- if (!UpdateParity(fec.redundancy)) {
+ if (!UpdateParity(redundancy)) {
return false;
}
- min_protected_packet_ = fec.fec_group;
- max_protected_packet_ = fec_packet_packet_number - 1;
+ max_protected_packet_ = header.packet_number - 1;
if (encryption_level < effective_encryption_level_) {
effective_encryption_level_ = encryption_level;
}
@@ -113,20 +110,38 @@ size_t QuicFecGroup::Revive(QuicPacketHeader* header,
decrypted_payload[i] = payload_parity_[i];
}
- header->packet_packet_number = missing;
+ header->packet_number = missing;
header->entropy_flag = false; // Unknown entropy.
received_packets_.insert(missing);
return payload_parity_len_;
}
-bool QuicFecGroup::ProtectsPacketsBefore(QuicPacketNumber num) const {
- if (max_protected_packet_ != kInvalidPacketNumber) {
- return max_protected_packet_ < num;
+bool QuicFecGroup::IsWaitingForPacketBefore(QuicPacketNumber num) const {
+ // Entire range is larger than the threshold.
+ if (min_protected_packet_ >= num) {
+ return false;
+ }
+
+ // Entire range is smaller than the threshold.
+ if (received_packets_.size() > 0 ? *received_packets_.rbegin() + 1 < num
+ : min_protected_packet_ < num) {
+ return true;
+ }
+
+ // Range spans the threshold so look for a missing packet below the threshold.
+ QuicPacketNumber target = min_protected_packet_;
+ for (QuicPacketNumber packet : received_packets_) {
+ if (target++ != packet) {
+ return true;
+ }
+ if (target >= num) {
+ return false;
+ }
}
- // Since we might not yet have received the FEC packet, we must check
- // the packets we have received.
- return *received_packets_.begin() < num;
+
+ // No missing packets below the threshold.
+ return false;
}
bool QuicFecGroup::UpdateParity(StringPiece payload) {
@@ -138,8 +153,7 @@ bool QuicFecGroup::UpdateParity(StringPiece payload) {
if (payload_parity_len_ < payload.size()) {
payload_parity_len_ = payload.size();
}
- if (received_packets_.empty() &&
- min_protected_packet_ == kInvalidPacketNumber) {
+ if (received_packets_.empty() && !has_received_fec_packet()) {
// Initialize the parity to the value of this payload
memcpy(payload_parity_, payload.data(), payload.size());
if (payload.size() < kMaxPacketSize) {
@@ -155,7 +169,7 @@ bool QuicFecGroup::UpdateParity(StringPiece payload) {
}
QuicPacketCount QuicFecGroup::NumMissingPackets() const {
- if (min_protected_packet_ == kInvalidPacketNumber) {
+ if (!has_received_fec_packet()) {
return numeric_limits<QuicPacketCount>::max();
}
return static_cast<QuicPacketCount>(
@@ -163,39 +177,20 @@ QuicPacketCount QuicFecGroup::NumMissingPackets() const {
received_packets_.size());
}
-void QuicFecGroup::XorBuffers(const char* input,
- size_t size_in_bytes,
- char* output) {
-#if defined(__i386__) || defined(__x86_64__)
- // On x86, alignment is not required and casting bytes to words is safe.
-
- // size_t is a reasonable approximation of how large a general-purpose
- // register is for the platforms and compilers Chrome is built on.
- typedef size_t platform_word;
- const size_t size_in_words = size_in_bytes / sizeof(platform_word);
+const StringPiece QuicFecGroup::PayloadParity() const {
+ return StringPiece(payload_parity_, payload_parity_len_);
+}
- const platform_word* input_words =
- reinterpret_cast<const platform_word*>(input);
- platform_word* output_words = reinterpret_cast<platform_word*>(output);
+QuicPacketCount QuicFecGroup::NumReceivedPackets() const {
+ return received_packets_.size();
+}
- // Handle word-sized part of the buffer.
- size_t offset_in_words = 0;
- for (; offset_in_words < size_in_words; offset_in_words++) {
- output_words[offset_in_words] ^= input_words[offset_in_words];
- }
+EncryptionLevel QuicFecGroup::EffectiveEncryptionLevel() const {
+ return effective_encryption_level_;
+}
- // Handle the tail which does not fit into the word.
- for (size_t offset_in_bytes = offset_in_words * sizeof(platform_word);
- offset_in_bytes < size_in_bytes; offset_in_bytes++) {
- output[offset_in_bytes] ^= input[offset_in_bytes];
- }
-#else
- // On ARM and most other plaforms, the code above could fail due to the
- // alignment errors. Stick to byte-by-byte comparison.
- for (size_t offset = 0; offset < size_in_bytes; offset++) {
- output[offset] ^= input[offset];
- }
-#endif /* defined(__i386__) || defined(__x86_64__) */
+QuicFecGroupNumber QuicFecGroup::FecGroupNumber() const {
+ return min_protected_packet_;
}
} // namespace net
diff --git a/chromium/net/quic/quic_fec_group.h b/chromium/net/quic/quic_fec_group.h
index 2a1f53f1727..fe1471cf833 100644
--- a/chromium/net/quic/quic_fec_group.h
+++ b/chromium/net/quic/quic_fec_group.h
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Tracks information about an FEC group, including the packets
-// that have been seen, and the running parity. Provided the ability
+// that have been seen, and the running parity. Provides the ability
// to revive a dropped packet.
#ifndef NET_QUIC_QUIC_FEC_GROUP_H_
@@ -11,70 +11,35 @@
#include <cstddef>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
+#include "net/quic/quic_fec_group_interface.h"
#include "net/quic/quic_protocol.h"
namespace net {
-class NET_EXPORT_PRIVATE QuicFecGroup {
+class NET_EXPORT_PRIVATE QuicFecGroup : public QuicFecGroupInterface {
public:
- QuicFecGroup();
- ~QuicFecGroup();
+ explicit QuicFecGroup(QuicPacketNumber fec_group_number);
+ virtual ~QuicFecGroup();
- // Updates the FEC group based on the delivery of a data packet decrypted at
- // |encryption_level|. Returns false if this packet has already been seen,
- // true otherwise.
+ // Implementation of QuicFecGroupInterface.
bool Update(EncryptionLevel encryption_level,
const QuicPacketHeader& header,
- base::StringPiece decrypted_payload);
-
- // Updates the FEC group based on the delivery of an FEC packet decrypted at
- // |encryption_level|. Returns false if this packet has already been seen or
- // if it does not claim to protect all the packets previously seen in this
- // group.
+ base::StringPiece decrypted_payload) override;
bool UpdateFec(EncryptionLevel encryption_level,
- QuicPacketNumber fec_packet_packet_number,
- const QuicFecData& fec);
-
- // Returns true if a packet can be revived from this FEC group.
- bool CanRevive() const;
-
- // Returns true if all packets (FEC and data) from this FEC group have been
- // seen or revived
- bool IsFinished() const;
-
- // Revives the missing packet from this FEC group. This may return a packet
- // that is null padded to a greater length than the original packet, but
- // the framer will handle it correctly. Returns the length of the data
- // written to |decrypted_payload|, or 0 if the packet could not be revived.
+ const QuicPacketHeader& header,
+ base::StringPiece redundancy) override;
+ bool CanRevive() const override;
+ bool IsFinished() const override;
size_t Revive(QuicPacketHeader* header,
char* decrypted_payload,
- size_t decrypted_payload_len);
-
- // Returns true of this FEC group protects any packets with sequence
- // numbers less than |num|.
- bool ProtectsPacketsBefore(QuicPacketNumber num) const;
-
- const base::StringPiece payload_parity() const {
- return base::StringPiece(payload_parity_, payload_parity_len_);
- }
-
- QuicPacketNumber min_protected_packet() const {
- return min_protected_packet_;
- }
-
- QuicPacketCount NumReceivedPackets() const {
- return received_packets_.size();
- }
-
- // Returns the effective encryption level of the FEC group.
- EncryptionLevel effective_encryption_level() const {
- return effective_encryption_level_;
- }
-
- // An optimized version of running |output| ^= |input|, where ^ is
- // byte-by-byte XOR and both |output| and |input| are of size |size_in_bytes|.
- static void XorBuffers(const char* input, size_t size_in_bytes, char* output);
+ size_t decrypted_payload_len) override;
+ bool IsWaitingForPacketBefore(QuicPacketNumber num) const override;
+ const base::StringPiece PayloadParity() const override;
+ QuicPacketCount NumReceivedPackets() const override;
+ EncryptionLevel EffectiveEncryptionLevel() const override;
+ QuicFecGroupNumber FecGroupNumber() const override;
private:
bool UpdateParity(base::StringPiece payload);
@@ -82,12 +47,16 @@ class NET_EXPORT_PRIVATE QuicFecGroup {
// if the number of missing packets is not known.
QuicPacketCount NumMissingPackets() const;
+ bool has_received_fec_packet() const {
+ return max_protected_packet_ != kInvalidPacketNumber;
+ }
+
// Set of packets that we have recevied.
PacketNumberSet received_packets_;
// packet number of the first protected packet in this group (the one
// with the lowest packet number). Will only be set once the FEC
// packet has been seen.
- QuicPacketNumber min_protected_packet_;
+ const QuicPacketNumber min_protected_packet_;
// packet number of the last protected packet in this group (the one
// with the highest packet number). Will only be set once the FEC
// packet has been seen.
diff --git a/chromium/net/quic/quic_fec_group_interface.cc b/chromium/net/quic/quic_fec_group_interface.cc
new file mode 100644
index 00000000000..9422f1a458e
--- /dev/null
+++ b/chromium/net/quic/quic_fec_group_interface.cc
@@ -0,0 +1,49 @@
+// 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/quic_fec_group_interface.h"
+
+#include <limits>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+
+namespace net {
+
+void QuicFecGroupInterface::XorBuffers(const char* input,
+ size_t size_in_bytes,
+ char* output) {
+#if defined(__i386__) || defined(__x86_64__)
+ // On x86, alignment is not required and casting bytes to words is safe.
+
+ // size_t is a reasonable approximation of how large a general-purpose
+ // register is for the platforms and compilers Chrome is built on.
+ typedef size_t platform_word;
+ const size_t size_in_words = size_in_bytes / sizeof(platform_word);
+
+ const platform_word* input_words =
+ reinterpret_cast<const platform_word*>(input);
+ platform_word* output_words = reinterpret_cast<platform_word*>(output);
+
+ // Handle word-sized part of the buffer.
+ size_t offset_in_words = 0;
+ for (; offset_in_words < size_in_words; offset_in_words++) {
+ output_words[offset_in_words] ^= input_words[offset_in_words];
+ }
+
+ // Handle the tail which does not fit into the word.
+ for (size_t offset_in_bytes = offset_in_words * sizeof(platform_word);
+ offset_in_bytes < size_in_bytes; offset_in_bytes++) {
+ output[offset_in_bytes] ^= input[offset_in_bytes];
+ }
+#else
+ // On ARM and most other plaforms, the code above could fail due to the
+ // alignment errors. Stick to byte-by-byte comparison.
+ for (size_t offset = 0; offset < size_in_bytes; offset++) {
+ output[offset] ^= input[offset];
+ }
+#endif /* defined(__i386__) || defined(__x86_64__) */
+}
+
+} // namespace net
diff --git a/chromium/net/quic/quic_fec_group_interface.h b/chromium/net/quic/quic_fec_group_interface.h
new file mode 100644
index 00000000000..3f287a77af6
--- /dev/null
+++ b/chromium/net/quic/quic_fec_group_interface.h
@@ -0,0 +1,84 @@
+// 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.
+//
+// Tracks information about an FEC group, including the packets
+// that have been seen, and the running parity. Provides the ability
+// to revive a dropped packet.
+
+#ifndef NET_QUIC_QUIC_FEC_GROUP_INTERFACE_H_
+#define NET_QUIC_QUIC_FEC_GROUP_INTERFACE_H_
+
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "base/strings/string_piece.h"
+#include "net/base/net_export.h"
+#include "net/quic/quic_protocol.h"
+
+namespace net {
+
+class NET_EXPORT_PRIVATE QuicFecGroupInterface {
+ public:
+ ~QuicFecGroupInterface() {}
+
+ // Updates the FEC group based on the delivery of a data packet decrypted at
+ // |encryption_level|. Returns false if this packet has already been seen,
+ // true otherwise.
+ virtual bool Update(EncryptionLevel encryption_level,
+ const QuicPacketHeader& header,
+ base::StringPiece decrypted_payload) = 0;
+
+ // Updates the FEC group based on the delivery of an FEC packet decrypted at
+ // |encryption_level|. Returns false if this packet has already been seen or
+ // if it does not claim to protect all the packets previously seen in this
+ // group.
+ virtual bool UpdateFec(EncryptionLevel encryption_level,
+ const QuicPacketHeader& header,
+ base::StringPiece redundancy) = 0;
+
+ // Returns true if a packet can be revived from this FEC group.
+ virtual bool CanRevive() const = 0;
+
+ // Returns true if all packets (FEC and data) from this FEC group have been
+ // seen or revived.
+ virtual bool IsFinished() const = 0;
+
+ // Revives the missing packet from this FEC group. This may return a packet
+ // that is null padded to a greater length than the original packet, but
+ // the framer will handle it correctly. Returns the length of the data
+ // written to |decrypted_payload|, or 0 if the packet could not be revived.
+ virtual size_t Revive(QuicPacketHeader* header,
+ char* decrypted_payload,
+ size_t decrypted_payload_len) = 0;
+
+ // Returns true if the group is waiting for any packets with sequence numbers
+ // less than |num|.
+ virtual bool IsWaitingForPacketBefore(QuicPacketNumber num) const = 0;
+
+ // The FEC data in the FEC packet.
+ virtual const base::StringPiece PayloadParity() const = 0;
+
+ // Number of packets in the group.
+ virtual QuicPacketCount NumReceivedPackets() const = 0;
+
+ // Returns the effective encryption level of the FEC group.
+ virtual EncryptionLevel EffectiveEncryptionLevel() const = 0;
+
+ // Return the FEC group number of this group.
+ virtual QuicFecGroupNumber FecGroupNumber() const = 0;
+
+ // An optimized version of running |output| ^= |input|, where ^ is
+ // byte-by-byte XOR and both |output| and |input| are of size |size_in_bytes|.
+ static void XorBuffers(const char* input, size_t size_in_bytes, char* output);
+
+ protected:
+ QuicFecGroupInterface() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QuicFecGroupInterface);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_FEC_GROUP_INTERFACE_H_
diff --git a/chromium/net/quic/quic_fec_group_test.cc b/chromium/net/quic/quic_fec_group_test.cc
index 82076318996..5f5358dcdda 100644
--- a/chromium/net/quic/quic_fec_group_test.cc
+++ b/chromium/net/quic/quic_fec_group_test.cc
@@ -7,7 +7,6 @@
#include <algorithm>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -26,11 +25,7 @@ const char* kData[] = {
"", // dummy
// kData[1] must be at least as long as every element of kData[], because
// it is used to calculate kDataMaxLen.
- "abc12345678",
- "987defg",
- "ghi12345",
- "987jlkmno",
- "mno4567890",
+ "abc12345678", "987defg", "ghi12345", "987jlkmno", "mno4567890",
"789pqrstuvw",
};
// The maximum length of an element of kData.
@@ -40,12 +35,7 @@ const char* kDataSingle = kData[1];
const bool kEntropyFlag[] = {
false, // dummy
- false,
- true,
- true,
- false,
- true,
- true,
+ false, true, true, false, true, true,
};
} // namespace
@@ -63,12 +53,12 @@ class QuicFecGroupTest : public ::testing::Test {
// XOR in the packets.
for (size_t packet = 1; packet <= num_packets; ++packet) {
for (size_t i = 0; i < kDataMaxLen; i++) {
- uint8 byte = i > strlen(kData[packet]) ? 0x00 : kData[packet][i];
+ uint8_t byte = i > strlen(kData[packet]) ? 0x00 : kData[packet][i];
redundancy[i] = redundancy[i] ^ byte;
}
}
- QuicFecGroup group;
+ QuicFecGroup group(1);
// If we're out of order, send the FEC packet in the position of the
// lost packet. Otherwise send all (non-missing) packets, then FEC.
@@ -76,18 +66,19 @@ class QuicFecGroupTest : public ::testing::Test {
// Update the FEC state for each non-lost packet.
for (size_t packet = 1; packet <= num_packets; packet++) {
if (packet == lost_packet) {
+ QuicPacketHeader header;
+ header.packet_number = num_packets + 1;
+ header.fec_group = 1;
ASSERT_FALSE(group.IsFinished());
- QuicFecData fec;
- fec.fec_group = 1u;
- fec.redundancy = StringPiece(redundancy.get(), kDataMaxLen);
ASSERT_TRUE(
- group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets + 1, fec));
+ group.UpdateFec(ENCRYPTION_FORWARD_SECURE, header,
+ StringPiece(redundancy.get(), kDataMaxLen)));
} else {
QuicPacketHeader header;
- header.packet_packet_number = packet;
- header.entropy_flag = kEntropyFlag[packet];
- ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header,
- kData[packet]));
+ header.packet_number = packet;
+ header.fec_group = 1;
+ ASSERT_TRUE(
+ group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[packet]));
}
ASSERT_TRUE(group.CanRevive() == (packet == num_packets));
}
@@ -99,32 +90,31 @@ class QuicFecGroupTest : public ::testing::Test {
}
QuicPacketHeader header;
- header.packet_packet_number = packet;
+ header.packet_number = packet;
+ header.fec_group = 1;
header.entropy_flag = kEntropyFlag[packet];
- ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header,
- kData[packet]));
+ ASSERT_TRUE(
+ group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[packet]));
ASSERT_FALSE(group.CanRevive());
}
ASSERT_FALSE(group.IsFinished());
+ QuicPacketHeader header;
+ header.packet_number = num_packets + 1;
+ header.fec_group = 1;
// Attempt to revive the missing packet.
- QuicFecData fec;
- fec.fec_group = 1u;
- fec.redundancy = StringPiece(redundancy.get(), kDataMaxLen);
-
- ASSERT_TRUE(
- group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets + 1, fec));
+ ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, header,
+ StringPiece(redundancy.get(), kDataMaxLen)));
}
QuicPacketHeader header;
char recovered[kMaxPacketSize];
ASSERT_TRUE(group.CanRevive());
size_t len = group.Revive(&header, recovered, arraysize(recovered));
- ASSERT_NE(0u, len)
- << "Failed to revive packet " << lost_packet << " out of "
- << num_packets;
- EXPECT_EQ(lost_packet, header.packet_packet_number)
- << "Failed to revive packet " << lost_packet << " out of "
- << num_packets;
+ ASSERT_NE(0u, len) << "Failed to revive packet " << lost_packet
+ << " out of " << num_packets;
+ EXPECT_EQ(lost_packet, header.packet_number) << "Failed to revive packet "
+ << lost_packet << " out of "
+ << num_packets;
// Revived packets have an unknown entropy.
EXPECT_FALSE(header.entropy_flag);
ASSERT_GE(len, strlen(kData[lost_packet])) << "Incorrect length";
@@ -160,94 +150,113 @@ TEST_F(QuicFecGroupTest, UpdateFecIfReceivedPacketIsNotCovered) {
redundancy[i] = data1[i];
}
- QuicFecGroup group;
+ QuicFecGroup group(1);
QuicPacketHeader header;
- header.packet_packet_number = 3;
+ header.fec_group = 1;
+ header.packet_number = 3;
group.Update(ENCRYPTION_FORWARD_SECURE, header, data1);
- QuicFecData fec;
- fec.fec_group = 1u;
- fec.redundancy = redundancy;
-
- header.packet_packet_number = 2;
- ASSERT_FALSE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 2, fec));
+ header.packet_number = 2;
+ ASSERT_FALSE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, header, redundancy));
}
-TEST_F(QuicFecGroupTest, ProtectsPacketsBefore) {
+TEST_F(QuicFecGroupTest, IsWaitingForPacketBefore) {
QuicPacketHeader header;
- header.packet_packet_number = 3;
+ header.fec_group = 3;
+ header.packet_number = 3;
- QuicFecGroup group;
+ QuicFecGroup group(3);
ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
- EXPECT_FALSE(group.ProtectsPacketsBefore(1));
- EXPECT_FALSE(group.ProtectsPacketsBefore(2));
- EXPECT_FALSE(group.ProtectsPacketsBefore(3));
- EXPECT_TRUE(group.ProtectsPacketsBefore(4));
- EXPECT_TRUE(group.ProtectsPacketsBefore(5));
- EXPECT_TRUE(group.ProtectsPacketsBefore(50));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(1));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(2));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(3));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(4));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(5));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(50));
}
-TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithSeveralPackets) {
+TEST_F(QuicFecGroupTest, IsWaitingForPacketBeforeWithSeveralPackets) {
QuicPacketHeader header;
- header.packet_packet_number = 3;
+ header.fec_group = 3;
+ header.packet_number = 3;
- QuicFecGroup group;
+ QuicFecGroup group(3);
ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
- header.packet_packet_number = 7;
+ header.packet_number = 7;
ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
- header.packet_packet_number = 5;
+ header.packet_number = 5;
ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
- EXPECT_FALSE(group.ProtectsPacketsBefore(1));
- EXPECT_FALSE(group.ProtectsPacketsBefore(2));
- EXPECT_FALSE(group.ProtectsPacketsBefore(3));
- EXPECT_TRUE(group.ProtectsPacketsBefore(4));
- EXPECT_TRUE(group.ProtectsPacketsBefore(5));
- EXPECT_TRUE(group.ProtectsPacketsBefore(6));
- EXPECT_TRUE(group.ProtectsPacketsBefore(7));
- EXPECT_TRUE(group.ProtectsPacketsBefore(8));
- EXPECT_TRUE(group.ProtectsPacketsBefore(9));
- EXPECT_TRUE(group.ProtectsPacketsBefore(50));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(1));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(2));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(3));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(4));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(5));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(6));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(7));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(8));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(9));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(50));
}
-TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithFecData) {
- QuicFecData fec;
- fec.fec_group = 2u;
- fec.redundancy = kDataSingle;
+TEST_F(QuicFecGroupTest, IsWaitingForPacketBeforeWithFecData1) {
+ QuicFecGroup group(3);
+
+ QuicPacketHeader header;
+ header.fec_group = 3;
+ header.packet_number = 4;
+ ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
+
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(1));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(2));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(3));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(4));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(5));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(6));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(50));
+}
+
+TEST_F(QuicFecGroupTest, IsWaitingForPacketBeforeWithFecData2) {
+ QuicFecGroup group(3);
+
+ QuicPacketHeader header;
+ header.fec_group = 3;
+ header.packet_number = 3;
+ ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
- QuicFecGroup group;
- ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 3, fec));
+ header.packet_number = 5;
+ ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
- EXPECT_FALSE(group.ProtectsPacketsBefore(1));
- EXPECT_FALSE(group.ProtectsPacketsBefore(2));
- EXPECT_TRUE(group.ProtectsPacketsBefore(3));
- EXPECT_TRUE(group.ProtectsPacketsBefore(4));
- EXPECT_TRUE(group.ProtectsPacketsBefore(5));
- EXPECT_TRUE(group.ProtectsPacketsBefore(50));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(1));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(2));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(3));
+ EXPECT_FALSE(group.IsWaitingForPacketBefore(4));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(5));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(6));
+ EXPECT_TRUE(group.IsWaitingForPacketBefore(50));
}
TEST_F(QuicFecGroupTest, EffectiveEncryptionLevel) {
- QuicFecGroup group;
- EXPECT_EQ(NUM_ENCRYPTION_LEVELS, group.effective_encryption_level());
+ QuicFecGroup group(1);
+ EXPECT_EQ(NUM_ENCRYPTION_LEVELS, group.EffectiveEncryptionLevel());
QuicPacketHeader header;
- header.packet_packet_number = 5;
+ header.fec_group = 1;
+ header.packet_number = 5;
ASSERT_TRUE(group.Update(ENCRYPTION_INITIAL, header, kDataSingle));
- EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level());
+ EXPECT_EQ(ENCRYPTION_INITIAL, group.EffectiveEncryptionLevel());
- QuicFecData fec;
- fec.fec_group = 1u;
- fec.redundancy = kDataSingle;
- ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 7, fec));
- EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level());
+ header.packet_number = 7;
+ ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
+ EXPECT_EQ(ENCRYPTION_INITIAL, group.EffectiveEncryptionLevel());
- header.packet_packet_number = 3;
+ header.packet_number = 3;
ASSERT_TRUE(group.Update(ENCRYPTION_NONE, header, kDataSingle));
- EXPECT_EQ(ENCRYPTION_NONE, group.effective_encryption_level());
+ EXPECT_EQ(ENCRYPTION_NONE, group.EffectiveEncryptionLevel());
}
// Test the code assuming it is going to be operating in 128-bit chunks (which
diff --git a/chromium/net/quic/quic_flags.cc b/chromium/net/quic/quic_flags.cc
index c897b54ee84..86707d641bf 100644
--- a/chromium/net/quic/quic_flags.cc
+++ b/chromium/net/quic/quic_flags.cc
@@ -4,8 +4,6 @@
#include "net/quic/quic_flags.h"
-bool FLAGS_quic_allow_oversized_packets_for_test = false;
-
// When true, the use time based loss detection instead of nack.
bool FLAGS_quic_use_time_loss_detection = false;
@@ -16,7 +14,7 @@ bool FLAGS_use_early_return_when_verifying_chlo = true;
// If true, QUIC connections will support FEC protection of data while sending
// packets, to reduce latency of data delivery to the application. The client
// must also request FEC protection for the server to use FEC.
-bool FLAGS_enable_quic_fec = false;
+bool FLAGS_enable_quic_fec = true;
// When true, defaults to BBR congestion control instead of Cubic.
bool FLAGS_quic_use_bbr_congestion_control = false;
@@ -27,7 +25,7 @@ bool FLAGS_quic_allow_bbr = false;
// Time period for which a given connection_id should live in the time-wait
// state.
-int64 FLAGS_quic_time_wait_list_seconds = 200;
+int64_t FLAGS_quic_time_wait_list_seconds = 200;
// Currently, this number is quite conservative. The max QPS limit for an
// individual server silo is currently set to 1000 qps, though the actual max
@@ -38,41 +36,74 @@ int64 FLAGS_quic_time_wait_list_seconds = 200;
//
// Maximum number of connections on the time-wait list. A negative value implies
// no configured limit.
-int64 FLAGS_quic_time_wait_list_max_connections = 600000;
+int64_t FLAGS_quic_time_wait_list_max_connections = 600000;
// Enables server-side support for QUIC stateless rejects.
bool FLAGS_enable_quic_stateless_reject_support = true;
+// If ture, allow Ack Decimation to be used for QUIC when requested by the
+// client connection option ACKD.
+bool FLAGS_quic_ack_decimation = true;
+
+// This flag is not in use, just to keep consistency for shared code.
+bool FLAGS_quic_always_log_bugs_for_tests = false;
+
// If true, flow controller may grow the receive window size if necessary.
bool FLAGS_quic_auto_tune_receive_window = true;
+// If true, multipath is enabled for the connection.
+bool FLAGS_quic_enable_multipath = false;
+
// Limits QUIC's max CWND to 200 packets.
bool FLAGS_quic_limit_max_cwnd = true;
// If true, require handshake confirmation for QUIC connections, functionally
// disabling 0-rtt handshakes.
-// TODO(rtenneti): Enable this flag after fixing tests.
+// TODO(rtenneti): Enable this flag after CryptoServerTest's are fixed.
bool FLAGS_quic_require_handshake_confirmation = false;
-// Disables special treatment of truncated acks, since older retransmissions are
-// proactively discarded in QUIC.
-bool FLAGS_quic_disable_truncated_ack_handling = true;
+// If true, Cubic's epoch is shifted when the sender is application-limited.
+bool FLAGS_shift_quic_cubic_epoch_when_app_limited = true;
+
+// If true, QUIC will measure head of line (HOL) blocking due between
+// streams due to packet losses on the headers stream. The
+// measurements will be surfaced via UMA histogram
+// Net.QuicSession.HeadersHOLBlockedTime.
+bool FLAGS_quic_measure_headers_hol_blocking_time = true;
+
+// Disable QUIC's userspace pacing.
+bool FLAGS_quic_disable_pacing = false;
-// If true, after a server silo receives a packet from a migrated QUIC
-// client, a GO_AWAY frame is sent to the client.
-bool FLAGS_send_goaway_after_client_migration = true;
+// If true, Use QUIC's GeneralLossAlgorithm implementation instead of
+// TcpLossAlgorithm or TimeLossAlgorithm.
+bool FLAGS_quic_general_loss_algorithm = true;
-// Close the connection instead of attempting to write a packet out of sequence
-// number order.
-bool FLAGS_quic_close_connection_out_of_order_sending = true;
+// If true, only migrate QUIC connections when client address changes are
+// considered to be caused by NATs.
+bool FLAGS_quic_disable_non_nat_address_migration = true;
-// QUIC-specific flag. If true, Cubic's epoch is reset when the sender is
-// application-limited.
-bool FLAGS_reset_cubic_epoch_when_app_limited = true;
+// If true, QUIC connections will timeout when packets are not being recieved,
+// even if they are being sent.
+bool FLAGS_quic_use_new_idle_timeout = true;
-// If true, use an interval set as the internal representation of a packet queue
-// instead of a set.
-bool FLAGS_quic_packet_queue_use_interval_set = true;
+// If true, replace QuicFrameList with StreamSequencerBuffer as underlying data
+// structure for QuicStreamSequencer bufferring.
+bool FLAGS_quic_use_stream_sequencer_buffer = true;
+
+// If true, don't send QUIC packets if the send alarm is set.
+bool FLAGS_quic_respect_send_alarm2 = true;
+
+// If ture, sets callback pointer to nullptr after calling Cancel() in
+// QuicCryptoServerStream::CancelOutstandingCallbacks.
+bool FLAGS_quic_set_client_hello_cb_nullptr = true;
+
+// If treu, Only track a single retransmission in QUIC's TransmissionInfo
+// struct.
+bool FLAGS_quic_track_single_retransmission = true;
+
+// If true, allow each quic stream to write 16k blocks rather than doing a round
+// robin of one packet per session when ack clocked or paced.
+bool FLAGS_quic_batch_writes = true;
// If true, QUIC sessions will write block streams that attempt to write
// unencrypted data.
@@ -81,5 +112,44 @@ bool FLAGS_quic_block_unencrypted_writes = true;
// If true, Close the connection instead of writing unencrypted stream data.
bool FLAGS_quic_never_write_unencrypted_data = true;
+// If true, clear the FEC group instead of sending it with ENCRYPTION_NONE.
+// Close the connection if we ever try to serialized unencrypted FEC.
+bool FLAGS_quic_no_unencrypted_fec = true;
+
// If true, reject any incoming QUIC which does not have the FIXD tag.
bool FLAGS_quic_require_fix = true;
+
+// If true, QUIC supports sending trailers from Server to Client.
+bool FLAGS_quic_supports_trailers = true;
+
+// If true, headers stream will support receiving PUSH_PROMISE frames.
+bool FLAGS_quic_supports_push_promise = false;
+
+// Fixes a bug in QUIC_VERSION_26 by always using the primary config when
+// getting the proof of possession.
+bool FLAGS_quic_use_primary_config_for_proof = true;
+
+// Enable counters for incoming/outgoing streams which are used as condition
+// check while creating a new stream.
+bool FLAGS_quic_distinguish_incoming_outgoing_streams = true;
+
+// If true, QUIC servers will attempt to validate a client's source
+// address token using the primary config, even if no server config id
+// is present in the client hello.
+bool FLAGS_quic_validate_stk_without_scid = true;
+
+// If true, use the new write blocked list for QUIC.
+bool FLAGS_quic_new_blocked_list = true;
+
+// If true, QUIC will support RFC 7539 variants of ChaCha20 Poly1305.
+bool FLAGS_quic_use_rfc7539 = true;
+
+// If true, drop not awaited QUIC packets before decrypting them.
+bool FLAGS_quic_drop_non_awaited_packets = false;
+
+// If true, use the fast implementation of IncrementalHash/FNV1a_128_Hash.
+bool FLAGS_quic_utils_use_fast_incremental_hash = true;
+
+// If true, require QUIC connections to use a valid server nonce or a non-local
+// strike register.
+bool FLAGS_require_strike_register_or_server_nonce = true;
diff --git a/chromium/net/quic/quic_flags.h b/chromium/net/quic/quic_flags.h
index b6f1993367f..93da375ad53 100644
--- a/chromium/net/quic/quic_flags.h
+++ b/chromium/net/quic/quic_flags.h
@@ -5,29 +5,47 @@
#ifndef NET_QUIC_QUIC_FLAGS_H_
#define NET_QUIC_QUIC_FLAGS_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "net/base/net_export.h"
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_oversized_packets_for_test;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_time_loss_detection;
NET_EXPORT_PRIVATE extern bool FLAGS_use_early_return_when_verifying_chlo;
NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_fec;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_bbr_congestion_control;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_bbr;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_too_many_outstanding_packets;
-NET_EXPORT_PRIVATE extern int64 FLAGS_quic_time_wait_list_seconds;
-NET_EXPORT_PRIVATE extern int64 FLAGS_quic_time_wait_list_max_connections;
+NET_EXPORT_PRIVATE extern int64_t FLAGS_quic_time_wait_list_seconds;
+NET_EXPORT_PRIVATE extern int64_t FLAGS_quic_time_wait_list_max_connections;
NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_stateless_reject_support;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_ack_decimation;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_always_log_bugs_for_tests;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_auto_tune_receive_window;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_multipath;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_limit_max_cwnd;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_require_handshake_confirmation;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_disable_truncated_ack_handling;
-NET_EXPORT_PRIVATE extern bool FLAGS_send_goaway_after_client_migration;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_close_connection_out_of_order_sending;
-NET_EXPORT_PRIVATE extern bool FLAGS_reset_cubic_epoch_when_app_limited;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_packet_queue_use_interval_set;
+NET_EXPORT_PRIVATE extern bool FLAGS_shift_quic_cubic_epoch_when_app_limited;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_measure_headers_hol_blocking_time;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_disable_pacing;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_general_loss_algorithm;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_disable_non_nat_address_migration;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_new_idle_timeout;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_stream_sequencer_buffer;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_respect_send_alarm2;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_set_client_hello_cb_nullptr;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_track_single_retransmission;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_batch_writes;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_block_unencrypted_writes;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_never_write_unencrypted_data;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_no_unencrypted_fec;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_require_fix;
-
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_supports_trailers;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_supports_push_promise;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_primary_config_for_proof;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_distinguish_incoming_outgoing_streams;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_validate_stk_without_scid;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_new_blocked_list;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_rfc7539;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_drop_non_awaited_packets;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_utils_use_fast_incremental_hash;
+NET_EXPORT_PRIVATE extern bool FLAGS_require_strike_register_or_server_nonce;
#endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/chromium/net/quic/quic_flow_controller.cc b/chromium/net/quic/quic_flow_controller.cc
index 72f4c7fa2f1..020261d893a 100644
--- a/chromium/net/quic/quic_flow_controller.cc
+++ b/chromium/net/quic/quic_flow_controller.cc
@@ -4,18 +4,14 @@
#include "net/quic/quic_flow_controller.h"
-#include "base/basictypes.h"
+#include "base/strings/stringprintf.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"
namespace net {
-namespace {
-const QuicByteCount kStreamReceiveWindowLimit = 16 * 1024 * 1024; // 16 MB
-const QuicByteCount kSessionReceiveWindowLimit = 24 * 1024 * 1024; // 24 MB
-}
-
#define ENDPOINT \
(perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
@@ -78,7 +74,13 @@ void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
bytes_sent_ = send_window_offset_;
// This is an error on our side, close the connection as soon as possible.
- connection_->SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
+ connection_->SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA,
+ base::StringPrintf(
+ "%llu bytes over send window offset",
+ static_cast<unsigned long long>(send_window_offset_ -
+ (bytes_sent_ + bytes_sent)))
+ .c_str());
return;
}
@@ -88,9 +90,8 @@ void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
bool QuicFlowController::FlowControlViolation() {
if (highest_received_byte_offset_ > receive_window_offset_) {
- LOG(ERROR) << ENDPOINT << "Flow control violation on stream "
- << id_ << ", receive window offset: "
- << receive_window_offset_
+ LOG(ERROR) << ENDPOINT << "Flow control violation on stream " << id_
+ << ", receive window offset: " << receive_window_offset_
<< ", highest received byte offset: "
<< highest_received_byte_offset_;
return true;
@@ -176,7 +177,7 @@ void QuicFlowController::MaybeSendWindowUpdate() {
if (available_window >= threshold) {
DVLOG(1) << ENDPOINT << "Not sending WindowUpdate for stream " << id_
<< ", available window: " << available_window
- << ">= threshold: " << threshold;
+ << " >= threshold: " << threshold;
return;
}
@@ -234,7 +235,7 @@ bool QuicFlowController::IsBlocked() const {
return SendWindowSize() == 0;
}
-uint64 QuicFlowController::SendWindowSize() const {
+uint64_t QuicFlowController::SendWindowSize() const {
if (bytes_sent_ > send_window_offset_) {
return 0;
}
@@ -245,8 +246,8 @@ void QuicFlowController::UpdateReceiveWindowSize(QuicStreamOffset size) {
DVLOG(1) << ENDPOINT << "UpdateReceiveWindowSize for stream " << id_ << ": "
<< size;
if (receive_window_size_ != receive_window_offset_) {
- LOG(DFATAL) << "receive_window_size_:" << receive_window_size_
- << " != receive_window_offset:" << receive_window_offset_;
+ QUIC_BUG << "receive_window_size_:" << receive_window_size_
+ << " != receive_window_offset:" << receive_window_offset_;
return;
}
receive_window_size_ = size;
diff --git a/chromium/net/quic/quic_flow_controller.h b/chromium/net/quic/quic_flow_controller.h
index dad5b6658cb..62ae5b65664 100644
--- a/chromium/net/quic/quic_flow_controller.h
+++ b/chromium/net/quic/quic_flow_controller.h
@@ -5,7 +5,7 @@
#ifndef NET_QUIC_QUIC_FLOW_CONTROLLER_H_
#define NET_QUIC_QUIC_FLOW_CONTROLLER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
@@ -139,7 +139,6 @@ class NET_EXPORT_PRIVATE QuicFlowController {
// highest offset in a data frame, or a final value in a RST.
QuicStreamOffset highest_received_byte_offset_;
-
// The absolute offset in the incoming byte stream. The peer should never send
// us bytes which are beyond this offset.
QuicStreamOffset receive_window_offset_;
diff --git a/chromium/net/quic/quic_flow_controller_test.cc b/chromium/net/quic/quic_flow_controller_test.cc
index dffbd56d7f6..877175f595e 100644
--- a/chromium/net/quic/quic_flow_controller_test.cc
+++ b/chromium/net/quic/quic_flow_controller_test.cc
@@ -15,11 +15,13 @@
#include "net/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"
+using testing::_;
+
namespace net {
namespace test {
// Receive window auto-tuning uses RTT in its logic.
-const int64 kRtt = 100;
+const int64_t kRtt = 100;
class QuicFlowControllerTest : public ::testing::Test {
public:
@@ -27,7 +29,7 @@ class QuicFlowControllerTest : public ::testing::Test {
: stream_id_(1234),
send_window_(kInitialSessionFlowControlWindowForTest),
receive_window_(kInitialSessionFlowControlWindowForTest),
- connection_(Perspective::IS_CLIENT) {}
+ connection_(&helper_, Perspective::IS_CLIENT) {}
void Initialize() {
flow_controller_.reset(
@@ -40,6 +42,7 @@ class QuicFlowControllerTest : public ::testing::Test {
QuicByteCount send_window_;
QuicByteCount receive_window_;
scoped_ptr<QuicFlowController> flow_controller_;
+ MockConnectionHelper helper_;
MockConnection connection_;
};
@@ -74,12 +77,11 @@ TEST_F(QuicFlowControllerTest, SendingBytes) {
EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
// Try to send more bytes, violating flow control.
- EXPECT_CALL(connection_,
- SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA));
- EXPECT_DFATAL(
- flow_controller_->AddBytesSent(send_window_ * 10),
- base::StringPrintf("Trying to send an extra %" PRIu64 " bytes",
- send_window_ * 10));
+ EXPECT_CALL(connection_, SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, _));
+ EXPECT_DFATAL(flow_controller_->AddBytesSent(send_window_ * 10),
+ base::StringPrintf("Trying to send an extra %" PRIu64 " bytes",
+ send_window_ * 10));
EXPECT_TRUE(flow_controller_->IsBlocked());
EXPECT_EQ(0u, flow_controller_->SendWindowSize());
}
diff --git a/chromium/net/quic/quic_frame_list.cc b/chromium/net/quic/quic_frame_list.cc
new file mode 100644
index 00000000000..862e34f7ced
--- /dev/null
+++ b/chromium/net/quic/quic_frame_list.cc
@@ -0,0 +1,249 @@
+// Copyright (c) 2015 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/quic_frame_list.h"
+
+#include "base/logging.h"
+
+namespace net {
+
+QuicFrameList::FrameData::FrameData(QuicStreamOffset offset,
+ string segment,
+ const QuicTime timestamp)
+ : offset(offset), segment(segment), timestamp(timestamp) {}
+
+QuicFrameList::QuicFrameList() {}
+
+QuicFrameList::~QuicFrameList() {
+ Clear();
+}
+
+void QuicFrameList::Clear() {
+ frame_list_.clear();
+ num_bytes_buffered_ = 0;
+}
+
+bool QuicFrameList::Empty() const {
+ return frame_list_.empty();
+}
+
+QuicErrorCode QuicFrameList::OnStreamData(QuicStreamOffset offset,
+ StringPiece data,
+ QuicTime timestamp,
+ size_t* const bytes_buffered) {
+ *bytes_buffered = 0;
+ const size_t data_len = data.size();
+ auto insertion_point = FindInsertionPoint(offset, data_len);
+ if (IsDuplicate(offset, data_len, insertion_point)) {
+ return QUIC_NO_ERROR;
+ }
+
+ if (FrameOverlapsBufferedData(offset, data_len, insertion_point)) {
+ return QUIC_INVALID_STREAM_DATA;
+ }
+
+ DVLOG(1) << "Buffering stream data at offset " << offset;
+ // Inserting an empty string and then copying to avoid the extra copy.
+ insertion_point =
+ frame_list_.insert(insertion_point, FrameData(offset, "", timestamp));
+ data.CopyToString(&insertion_point->segment);
+ *bytes_buffered = data_len;
+ num_bytes_buffered_ += data_len;
+ return QUIC_NO_ERROR;
+}
+
+// Finds the place the frame should be inserted. If an identical frame is
+// present, stops on the identical frame.
+list<QuicFrameList::FrameData>::iterator QuicFrameList::FindInsertionPoint(
+ QuicStreamOffset offset,
+ size_t len) {
+ if (frame_list_.empty()) {
+ return frame_list_.begin();
+ }
+ // If it's after all buffered_frames, return the end.
+ if (offset >=
+ (frame_list_.rbegin()->offset + frame_list_.rbegin()->segment.length())) {
+ return frame_list_.end();
+ }
+ auto iter = frame_list_.begin();
+ // Only advance the iterator if the data begins after the already received
+ // frame. If the new frame overlaps with an existing frame, the iterator will
+ // still point to the frame it overlaps with.
+ while (iter != frame_list_.end() &&
+ offset >= iter->offset + iter->segment.length()) {
+ ++iter;
+ }
+ return iter;
+}
+
+// Returns true if |frame| contains data which overlaps buffered data
+// (indicating an invalid stream frame has been received).
+bool QuicFrameList::FrameOverlapsBufferedData(
+ QuicStreamOffset offset,
+ size_t data_len,
+ list<FrameData>::const_iterator insertion_point) const {
+ if (frame_list_.empty() || insertion_point == frame_list_.end()) {
+ return false;
+ }
+ // If there is a buffered frame with a higher starting offset, then check to
+ // see if the new frame overlaps the beginning of the higher frame.
+ if (offset < insertion_point->offset &&
+ offset + data_len > insertion_point->offset) {
+ DVLOG(1) << "New frame overlaps next frame: " << offset << " + " << data_len
+ << " > " << insertion_point->offset;
+ return true;
+ }
+ // If there is a buffered frame with a lower starting offset, then check to
+ // see if the buffered frame runs into the new frame.
+ if (offset >= insertion_point->offset &&
+ offset < insertion_point->offset + insertion_point->segment.length()) {
+ DVLOG(1) << "Preceeding frame overlaps new frame: "
+ << insertion_point->offset << " + "
+ << insertion_point->segment.length() << " > " << offset;
+ return true;
+ }
+
+ return false;
+}
+
+// Returns true if the sequencer has received this frame before.
+bool QuicFrameList::IsDuplicate(
+ QuicStreamOffset offset,
+ size_t data_len,
+ list<FrameData>::const_iterator insertion_point) const {
+ // A frame is duplicate if the frame offset is smaller than the bytes consumed
+ // or identical to an already received frame.
+ return offset < total_bytes_read_ || (insertion_point != frame_list_.end() &&
+ offset == insertion_point->offset);
+}
+
+int QuicFrameList::GetReadableRegions(struct iovec* iov, int iov_len) const {
+ list<FrameData>::const_iterator it = frame_list_.begin();
+ int index = 0;
+ QuicStreamOffset offset = total_bytes_read_;
+ while (it != frame_list_.end() && index < iov_len) {
+ if (it->offset != offset) {
+ return index;
+ }
+
+ iov[index].iov_base =
+ static_cast<void*>(const_cast<char*>(it->segment.data()));
+ iov[index].iov_len = it->segment.size();
+ offset += it->segment.size();
+
+ ++index;
+ ++it;
+ }
+ return index;
+}
+
+bool QuicFrameList::GetReadableRegion(iovec* iov, QuicTime* timestamp) const {
+ list<FrameData>::const_iterator it = frame_list_.begin();
+ if (it == frame_list_.end() || it->offset != total_bytes_read_) {
+ return false;
+ }
+ iov->iov_base = static_cast<void*>(const_cast<char*>(it->segment.data()));
+ iov->iov_len = it->segment.size();
+ *timestamp = it->timestamp;
+ return true;
+}
+
+bool QuicFrameList::MarkConsumed(size_t bytes_used) {
+ size_t end_offset = total_bytes_read_ + bytes_used;
+ while (!frame_list_.empty() && end_offset != total_bytes_read_) {
+ list<FrameData>::iterator it = frame_list_.begin();
+ if (it->offset != total_bytes_read_) {
+ return false;
+ }
+
+ if (it->offset + it->segment.length() <= end_offset) {
+ total_bytes_read_ += it->segment.length();
+ num_bytes_buffered_ -= it->segment.length();
+ // This chunk is entirely consumed.
+ frame_list_.erase(it);
+ continue;
+ }
+
+ // Partially consume this frame.
+ size_t delta = end_offset - it->offset;
+ total_bytes_read_ += delta;
+ num_bytes_buffered_ -= delta;
+ string new_data = it->segment.substr(delta);
+ const QuicTime timestamp = it->timestamp;
+ frame_list_.erase(it);
+ frame_list_.push_front(FrameData(total_bytes_read_, new_data, timestamp));
+ break;
+ }
+ return true;
+}
+
+size_t QuicFrameList::Readv(const struct iovec* iov, size_t iov_len) {
+ list<FrameData>::iterator it = frame_list_.begin();
+ size_t iov_index = 0;
+ size_t iov_offset = 0;
+ size_t frame_offset = 0;
+ QuicStreamOffset initial_bytes_consumed = total_bytes_read_;
+
+ while (iov_index < iov_len && it != frame_list_.end() &&
+ it->offset == total_bytes_read_) {
+ int bytes_to_read = std::min(iov[iov_index].iov_len - iov_offset,
+ it->segment.size() - frame_offset);
+
+ char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset;
+ memcpy(iov_ptr, it->segment.data() + frame_offset, bytes_to_read);
+ frame_offset += bytes_to_read;
+ iov_offset += bytes_to_read;
+
+ if (iov[iov_index].iov_len == iov_offset) {
+ // We've filled this buffer.
+ iov_offset = 0;
+ ++iov_index;
+ }
+ if (it->segment.size() == frame_offset) {
+ // We've copied this whole frame
+ total_bytes_read_ += it->segment.size();
+ num_bytes_buffered_ -= it->segment.size();
+ frame_list_.erase(it);
+ it = frame_list_.begin();
+ frame_offset = 0;
+ }
+ }
+ // Done copying. If there is a partial frame, update it.
+ if (frame_offset != 0) {
+ frame_list_.push_front(FrameData(it->offset + frame_offset,
+ it->segment.substr(frame_offset),
+ it->timestamp));
+ frame_list_.erase(it);
+ total_bytes_read_ += frame_offset;
+ num_bytes_buffered_ -= frame_offset;
+ }
+ return total_bytes_read_ - initial_bytes_consumed;
+}
+
+size_t QuicFrameList::FlushBufferedFrames() {
+ QuicStreamOffset initial_bytes_consumed = total_bytes_read_;
+ if (!frame_list_.empty()) {
+ // Consume all of the bytes up to the last byte yet seen, including the
+ // ones that haven't arrived yet.
+ auto it = frame_list_.back();
+ total_bytes_read_ = it.offset + it.segment.length();
+ frame_list_.clear();
+ }
+ return total_bytes_read_ - initial_bytes_consumed;
+}
+
+bool QuicFrameList::HasBytesToRead() const {
+ return !frame_list_.empty() &&
+ frame_list_.begin()->offset == total_bytes_read_;
+}
+
+QuicStreamOffset QuicFrameList::BytesConsumed() const {
+ return total_bytes_read_;
+}
+
+size_t QuicFrameList::BytesBuffered() const {
+ return num_bytes_buffered_;
+}
+
+} // namespace net_quic
diff --git a/chromium/net/quic/quic_frame_list.h b/chromium/net/quic/quic_frame_list.h
new file mode 100644
index 00000000000..a6235972a2c
--- /dev/null
+++ b/chromium/net/quic/quic_frame_list.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2015 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_QUIC_FRAME_LIST_H_
+#define NET_QUIC_QUIC_FRAME_LIST_H_
+
+#include <stddef.h>
+
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_stream_sequencer_buffer_interface.h"
+
+using base::StringPiece;
+using std::string;
+using std::list;
+
+namespace net {
+
+namespace test {
+class QuicStreamSequencerPeer;
+}
+
+class NET_EXPORT_PRIVATE QuicFrameList
+ : public QuicStreamSequencerBufferInterface {
+ public:
+ // A contiguous segment received by a QUIC stream.
+ struct FrameData {
+ FrameData(QuicStreamOffset offset,
+ string segment,
+ const QuicTime timestamp);
+
+ const QuicStreamOffset offset;
+ string segment;
+ const QuicTime timestamp;
+ };
+
+ explicit QuicFrameList();
+
+ ~QuicFrameList() override;
+
+ // QuicStreamSequencerBufferInterface implementation
+ void Clear() override;
+ bool Empty() const override;
+ QuicErrorCode OnStreamData(QuicStreamOffset offset,
+ StringPiece data,
+ QuicTime timestamp,
+ size_t* bytes_buffered) override;
+ size_t Readv(const struct iovec* iov, size_t iov_len) override;
+ int GetReadableRegions(struct iovec* iov, int iov_len) const override;
+ bool GetReadableRegion(iovec* iov, QuicTime* timestamp) const override;
+ bool MarkConsumed(size_t bytes_used) override;
+ size_t FlushBufferedFrames() override;
+ bool HasBytesToRead() const override;
+ QuicStreamOffset BytesConsumed() const override;
+ size_t BytesBuffered() const override;
+
+ private:
+ friend class test::QuicStreamSequencerPeer;
+
+ list<FrameData>::iterator FindInsertionPoint(QuicStreamOffset offset,
+ size_t len);
+
+ bool FrameOverlapsBufferedData(
+ QuicStreamOffset offset,
+ size_t data_len,
+ list<FrameData>::const_iterator insertion_point) const;
+
+ bool IsDuplicate(QuicStreamOffset offset,
+ size_t data_len,
+ list<FrameData>::const_iterator insertion_point) const;
+
+ list<FrameData> frame_list_;
+
+ // Number of bytes in buffer.
+ size_t num_bytes_buffered_ = 0;
+
+ QuicStreamOffset total_bytes_read_ = 0;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_FRAME_LIST_H_
diff --git a/chromium/net/quic/quic_framer.cc b/chromium/net/quic/quic_framer.cc
index a04824a0684..1370350cf17 100644
--- a/chromium/net/quic/quic_framer.cc
+++ b/chromium/net/quic/quic_framer.cc
@@ -6,7 +6,6 @@
#include <stdint.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/stl_util.h"
@@ -15,6 +14,7 @@
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_data_reader.h"
#include "net/quic/quic_data_writer.h"
#include "net/quic/quic_flags.h"
@@ -43,7 +43,7 @@ const QuicConnectionId k4ByteConnectionIdMask = UINT64_C(0x00000000FFFFFFFF);
// Number of bits the packet number length bits are shifted from the right
// edge of the public header.
-const uint8 kPublicHeaderSequenceNumberShift = 4;
+const uint8_t kPublicHeaderSequenceNumberShift = 4;
// New Frame Types, QUIC v. >= 10:
// There are two interpretations for the Frame Type byte in the QUIC protocol,
@@ -67,36 +67,36 @@ const uint8 kPublicHeaderSequenceNumberShift = 4;
// Masks to determine if the frame type is a special use
// and for specific special frame types.
-const uint8 kQuicFrameTypeSpecialMask = 0xE0; // 0b 11100000
-const uint8 kQuicFrameTypeStreamMask = 0x80;
-const uint8 kQuicFrameTypeAckMask = 0x40;
+const uint8_t kQuicFrameTypeSpecialMask = 0xE0; // 0b 11100000
+const uint8_t kQuicFrameTypeStreamMask = 0x80;
+const uint8_t kQuicFrameTypeAckMask = 0x40;
// Stream frame relative shifts and masks for interpreting the stream flags.
// StreamID may be 1, 2, 3, or 4 bytes.
-const uint8 kQuicStreamIdShift = 2;
-const uint8 kQuicStreamIDLengthMask = 0x03;
+const uint8_t kQuicStreamIdShift = 2;
+const uint8_t kQuicStreamIDLengthMask = 0x03;
// Offset may be 0, 2, 3, 4, 5, 6, 7, 8 bytes.
-const uint8 kQuicStreamOffsetShift = 3;
-const uint8 kQuicStreamOffsetMask = 0x07;
+const uint8_t kQuicStreamOffsetShift = 3;
+const uint8_t kQuicStreamOffsetMask = 0x07;
// Data length may be 0 or 2 bytes.
-const uint8 kQuicStreamDataLengthShift = 1;
-const uint8 kQuicStreamDataLengthMask = 0x01;
+const uint8_t kQuicStreamDataLengthShift = 1;
+const uint8_t kQuicStreamDataLengthMask = 0x01;
// Fin bit may be set or not.
-const uint8 kQuicStreamFinShift = 1;
-const uint8 kQuicStreamFinMask = 0x01;
+const uint8_t kQuicStreamFinShift = 1;
+const uint8_t kQuicStreamFinMask = 0x01;
// packet number size shift used in AckFrames.
-const uint8 kQuicSequenceNumberLengthShift = 2;
+const uint8_t kQuicSequenceNumberLengthShift = 2;
// Acks may be truncated.
-const uint8 kQuicAckTruncatedShift = 1;
-const uint8 kQuicAckTruncatedMask = 0x01;
+const uint8_t kQuicAckTruncatedShift = 1;
+const uint8_t kQuicAckTruncatedMask = 0x01;
// Acks may not have any nacks.
-const uint8 kQuicHasNacksMask = 0x01;
+const uint8_t kQuicHasNacksMask = 0x01;
// Returns the absolute value of the difference between |a| and |b|.
QuicPacketNumber Delta(QuicPacketNumber a, QuicPacketNumber b) {
@@ -113,7 +113,7 @@ QuicPacketNumber ClosestTo(QuicPacketNumber target,
return (Delta(target, a) < Delta(target, b)) ? a : b;
}
-QuicPacketNumberLength ReadSequenceNumberLength(uint8 flags) {
+QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) {
switch (flags & PACKET_FLAGS_6BYTE_PACKET) {
case PACKET_FLAGS_6BYTE_PACKET:
return PACKET_6BYTE_PACKET_NUMBER;
@@ -124,7 +124,7 @@ QuicPacketNumberLength ReadSequenceNumberLength(uint8 flags) {
case PACKET_FLAGS_1BYTE_PACKET:
return PACKET_1BYTE_PACKET_NUMBER;
default:
- LOG(DFATAL) << "Unreachable case statement.";
+ QUIC_BUG << "Unreachable case statement.";
return PACKET_6BYTE_PACKET_NUMBER;
}
}
@@ -138,6 +138,7 @@ QuicFramer::QuicFramer(const QuicVersionVector& supported_versions,
entropy_calculator_(nullptr),
error_(QUIC_NO_ERROR),
last_packet_number_(0),
+ last_path_id_(kInvalidPathId),
last_serialized_connection_id_(0),
supported_versions_(supported_versions),
decrypter_level_(ENCRYPTION_NONE),
@@ -160,18 +161,18 @@ size_t QuicFramer::GetMinStreamFrameSize(QuicStreamId stream_id,
QuicStreamOffset offset,
bool last_frame_in_packet,
InFecGroup is_in_fec_group) {
- bool no_stream_frame_length = last_frame_in_packet &&
- is_in_fec_group == NOT_IN_FEC_GROUP;
+ bool no_stream_frame_length =
+ last_frame_in_packet && is_in_fec_group == NOT_IN_FEC_GROUP;
return kQuicFrameTypeSize + GetStreamIdSize(stream_id) +
- GetStreamOffsetSize(offset) +
- (no_stream_frame_length ? 0 : kQuicStreamPayloadLengthSize);
+ GetStreamOffsetSize(offset) +
+ (no_stream_frame_length ? 0 : kQuicStreamPayloadLengthSize);
}
// static
size_t QuicFramer::GetMinAckFrameSize(
QuicPacketNumberLength largest_observed_length) {
- return kQuicFrameTypeSize + kQuicEntropyHashSize +
- largest_observed_length + kQuicDeltaTimeLargestObservedSize;
+ return kQuicFrameTypeSize + kQuicEntropyHashSize + largest_observed_length +
+ kQuicDeltaTimeLargestObservedSize;
}
// static
@@ -182,9 +183,8 @@ size_t QuicFramer::GetStopWaitingFrameSize(
// static
size_t QuicFramer::GetMinRstStreamFrameSize() {
- return kQuicFrameTypeSize + kQuicMaxStreamIdSize +
- kQuicMaxStreamOffsetSize + kQuicErrorCodeSize +
- kQuicErrorDetailsLengthSize;
+ return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize +
+ kQuicErrorCodeSize + kQuicErrorDetailsLengthSize;
}
// static
@@ -201,7 +201,7 @@ size_t QuicFramer::GetMinConnectionCloseFrameSize() {
// static
size_t QuicFramer::GetMinGoAwayFrameSize() {
return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize +
- kQuicMaxStreamIdSize;
+ kQuicMaxStreamIdSize;
}
// static
@@ -223,7 +223,7 @@ size_t QuicFramer::GetStreamIdSize(QuicStreamId stream_id) {
return i;
}
}
- LOG(DFATAL) << "Failed to determine StreamIDSize.";
+ QUIC_BUG << "Failed to determine StreamIDSize.";
return 4;
}
@@ -241,14 +241,14 @@ size_t QuicFramer::GetStreamOffsetSize(QuicStreamOffset offset) {
return i;
}
}
- LOG(DFATAL) << "Failed to determine StreamOffsetSize.";
+ QUIC_BUG << "Failed to determine StreamOffsetSize.";
return 8;
}
// static
size_t QuicFramer::GetVersionNegotiationPacketSize(size_t number_versions) {
return kPublicFlagsSize + PACKET_8BYTE_CONNECTION_ID +
- number_versions * kQuicVersionSize;
+ number_versions * kQuicVersionSize;
}
bool QuicFramer::IsSupportedVersion(const QuicVersion version) const {
@@ -268,13 +268,13 @@ size_t QuicFramer::GetSerializedFrameLength(
InFecGroup is_in_fec_group,
QuicPacketNumberLength packet_number_length) {
// Prevent a rare crash reported in b/19458523.
- if (frame.stream_frame == nullptr) {
- LOG(DFATAL) << "Cannot compute the length of a null frame. "
- << "type:" << frame.type << "free_bytes:" << free_bytes
- << " first_frame:" << first_frame
- << " last_frame:" << last_frame
- << " is_in_fec:" << is_in_fec_group
- << " seq num length:" << packet_number_length;
+ if ((frame.type == STREAM_FRAME || frame.type == ACK_FRAME) &&
+ frame.stream_frame == nullptr) {
+ QUIC_BUG << "Cannot compute the length of a null frame. "
+ << "type:" << frame.type << "free_bytes:" << free_bytes
+ << " first_frame:" << first_frame << " last_frame:" << last_frame
+ << " is_in_fec:" << is_in_fec_group
+ << " seq num length:" << packet_number_length;
set_error(QUIC_INTERNAL_ERROR);
visitor_->OnError(this);
return 0;
@@ -303,11 +303,7 @@ size_t QuicFramer::GetSerializedFrameLength(
DVLOG(1) << "Truncating large frame, free bytes: " << free_bytes;
return free_bytes;
}
- if (!FLAGS_quic_allow_oversized_packets_for_test) {
- return 0;
- }
- LOG(DFATAL) << "Packet size too small to fit frame.";
- return frame_len;
+ return 0;
}
QuicFramer::AckFrameInfo::AckFrameInfo() : max_delta(0) {}
@@ -317,17 +313,17 @@ QuicFramer::AckFrameInfo::~AckFrameInfo() {}
// static
QuicPacketEntropyHash QuicFramer::GetPacketEntropyHash(
const QuicPacketHeader& header) {
- return header.entropy_flag << (header.packet_packet_number % 8);
+ return header.entropy_flag << (header.packet_number % 8);
}
-QuicPacket* QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames,
- char* buffer,
- size_t packet_length) {
+size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
+ const QuicFrames& frames,
+ char* buffer,
+ size_t packet_length) {
QuicDataWriter writer(packet_length, buffer);
if (!AppendPacketHeader(header, &writer)) {
- LOG(DFATAL) << "AppendPacketHeader failed";
- return nullptr;
+ QUIC_BUG << "AppendPacketHeader failed";
+ return 0;
}
size_t i = 0;
@@ -337,8 +333,8 @@ QuicPacket* QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
(header.is_in_fec_group == NOT_IN_FEC_GROUP) &&
(i == frames.size() - 1);
if (!AppendTypeByte(frame, no_stream_frame_length, &writer)) {
- LOG(DFATAL) << "AppendTypeByte failed";
- return nullptr;
+ QUIC_BUG << "AppendTypeByte failed";
+ return 0;
}
switch (frame.type) {
@@ -346,24 +342,23 @@ QuicPacket* QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
writer.WritePadding();
break;
case STREAM_FRAME:
- if (!AppendStreamFrame(
- *frame.stream_frame, no_stream_frame_length, &writer)) {
- LOG(DFATAL) << "AppendStreamFrame failed";
- return nullptr;
+ if (!AppendStreamFrame(*frame.stream_frame, no_stream_frame_length,
+ &writer)) {
+ QUIC_BUG << "AppendStreamFrame failed";
+ return 0;
}
break;
case ACK_FRAME:
- if (!AppendAckFrameAndTypeByte(
- header, *frame.ack_frame, &writer)) {
- LOG(DFATAL) << "AppendAckFrameAndTypeByte failed";
- return nullptr;
+ if (!AppendAckFrameAndTypeByte(header, *frame.ack_frame, &writer)) {
+ QUIC_BUG << "AppendAckFrameAndTypeByte failed";
+ return 0;
}
break;
case STOP_WAITING_FRAME:
- if (!AppendStopWaitingFrame(
- header, *frame.stop_waiting_frame, &writer)) {
- LOG(DFATAL) << "AppendStopWaitingFrame failed";
- return nullptr;
+ if (!AppendStopWaitingFrame(header, *frame.stop_waiting_frame,
+ &writer)) {
+ QUIC_BUG << "AppendStopWaitingFrame failed";
+ return 0;
}
break;
case MTU_DISCOVERY_FRAME:
@@ -373,68 +368,62 @@ QuicPacket* QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
break;
case RST_STREAM_FRAME:
if (!AppendRstStreamFrame(*frame.rst_stream_frame, &writer)) {
- LOG(DFATAL) << "AppendRstStreamFrame failed";
- return nullptr;
+ QUIC_BUG << "AppendRstStreamFrame failed";
+ return 0;
}
break;
case CONNECTION_CLOSE_FRAME:
- if (!AppendConnectionCloseFrame(
- *frame.connection_close_frame, &writer)) {
- LOG(DFATAL) << "AppendConnectionCloseFrame failed";
- return nullptr;
+ if (!AppendConnectionCloseFrame(*frame.connection_close_frame,
+ &writer)) {
+ QUIC_BUG << "AppendConnectionCloseFrame failed";
+ return 0;
}
break;
case GOAWAY_FRAME:
if (!AppendGoAwayFrame(*frame.goaway_frame, &writer)) {
- LOG(DFATAL) << "AppendGoAwayFrame failed";
- return nullptr;
+ QUIC_BUG << "AppendGoAwayFrame failed";
+ return 0;
}
break;
case WINDOW_UPDATE_FRAME:
if (!AppendWindowUpdateFrame(*frame.window_update_frame, &writer)) {
- LOG(DFATAL) << "AppendWindowUpdateFrame failed";
- return nullptr;
+ QUIC_BUG << "AppendWindowUpdateFrame failed";
+ return 0;
}
break;
case BLOCKED_FRAME:
if (!AppendBlockedFrame(*frame.blocked_frame, &writer)) {
- LOG(DFATAL) << "AppendBlockedFrame failed";
- return nullptr;
+ QUIC_BUG << "AppendBlockedFrame failed";
+ return 0;
}
break;
default:
RaiseError(QUIC_INVALID_FRAME_DATA);
- LOG(DFATAL) << "QUIC_INVALID_FRAME_DATA";
- return nullptr;
+ QUIC_BUG << "QUIC_INVALID_FRAME_DATA";
+ return 0;
}
++i;
}
- QuicPacket* packet =
- new QuicPacket(writer.data(), writer.length(), false,
- header.public_header.connection_id_length,
- header.public_header.version_flag,
- header.public_header.packet_number_length);
-
- return packet;
+ return writer.length();
}
QuicPacket* QuicFramer::BuildFecPacket(const QuicPacketHeader& header,
- const QuicFecData& fec) {
+ StringPiece redundancy) {
DCHECK_EQ(IN_FEC_GROUP, header.is_in_fec_group);
DCHECK_NE(0u, header.fec_group);
size_t len = GetPacketHeaderSize(header);
- len += fec.redundancy.length();
+ len += redundancy.length();
scoped_ptr<char[]> buffer(new char[len]);
QuicDataWriter writer(len, buffer.get());
if (!AppendPacketHeader(header, &writer)) {
- LOG(DFATAL) << "AppendPacketHeader failed";
+ QUIC_BUG << "AppendPacketHeader failed";
return nullptr;
}
- if (!writer.WriteBytes(fec.redundancy.data(), fec.redundancy.length())) {
- LOG(DFATAL) << "Failed to add FEC";
+ if (!writer.WriteBytes(redundancy.data(), redundancy.length())) {
+ QUIC_BUG << "Failed to add FEC";
return nullptr;
}
@@ -469,8 +458,8 @@ QuicEncryptedPacket* QuicFramer::BuildPublicResetPacket(
scoped_ptr<char[]> buffer(new char[len]);
QuicDataWriter writer(len, buffer.get());
- uint8 flags = static_cast<uint8>(PACKET_PUBLIC_FLAGS_RST |
- PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
+ uint8_t flags = static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_RST |
+ PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
if (!writer.WriteUInt8(flags)) {
return nullptr;
}
@@ -486,26 +475,27 @@ QuicEncryptedPacket* QuicFramer::BuildPublicResetPacket(
return new QuicEncryptedPacket(buffer.release(), len, true);
}
+// static
QuicEncryptedPacket* QuicFramer::BuildVersionNegotiationPacket(
- const QuicPacketPublicHeader& header,
- const QuicVersionVector& supported_versions) {
- DCHECK(header.version_flag);
- size_t len = GetVersionNegotiationPacketSize(supported_versions.size());
+ QuicConnectionId connection_id,
+ const QuicVersionVector& versions) {
+ DCHECK(!versions.empty());
+ size_t len = GetVersionNegotiationPacketSize(versions.size());
scoped_ptr<char[]> buffer(new char[len]);
QuicDataWriter writer(len, buffer.get());
- uint8 flags = static_cast<uint8>(PACKET_PUBLIC_FLAGS_VERSION |
- PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
+ uint8_t flags = static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_VERSION |
+ PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
if (!writer.WriteUInt8(flags)) {
return nullptr;
}
- if (!writer.WriteUInt64(header.connection_id)) {
+ if (!writer.WriteUInt64(connection_id)) {
return nullptr;
}
- for (size_t i = 0; i < supported_versions.size(); ++i) {
- if (!writer.WriteUInt32(QuicVersionToQuicTag(supported_versions[i]))) {
+ for (QuicVersion version : versions) {
+ if (!writer.WriteUInt32(QuicVersionToQuicTag(version))) {
return nullptr;
}
}
@@ -612,7 +602,8 @@ bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader,
}
if (packet.length() > kMaxPacketSize) {
- DLOG(WARNING) << "Packet too large: " << packet.length();
+ // If the packet has gotten this far, it should not be too large.
+ LOG(DFATAL) << "Packet too large:" << packet.length();
return RaiseError(QUIC_PACKET_TOO_LARGE);
}
@@ -628,10 +619,7 @@ bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader,
return false;
}
} else {
- QuicFecData fec_data;
- fec_data.fec_group = header.fec_group;
- fec_data.redundancy = reader.ReadRemainingPayload();
- visitor_->OnFecData(fec_data);
+ visitor_->OnFecData(reader.ReadRemainingPayload());
}
visitor_->OnPacketComplete();
@@ -670,8 +658,8 @@ bool QuicFramer::ProcessPublicResetPacket(
if (reset->GetStringPiece(kCADR, &address)) {
QuicSocketAddressCoder address_coder;
if (address_coder.Decode(address.data(), address.length())) {
- packet.client_address = IPEndPoint(address_coder.ip(),
- address_coder.port());
+ packet.client_address =
+ IPEndPoint(address_coder.ip(), address_coder.port());
}
}
@@ -709,13 +697,16 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
QuicDataWriter* writer) {
DVLOG(1) << "Appending header: " << header;
DCHECK(header.fec_group > 0 || header.is_in_fec_group == NOT_IN_FEC_GROUP);
- uint8 public_flags = 0;
+ uint8_t public_flags = 0;
if (header.public_header.reset_flag) {
public_flags |= PACKET_PUBLIC_FLAGS_RST;
}
if (header.public_header.version_flag) {
public_flags |= PACKET_PUBLIC_FLAGS_VERSION;
}
+ if (header.public_header.multipath_flag) {
+ public_flags |= PACKET_PUBLIC_FLAGS_MULTIPATH;
+ }
public_flags |=
GetSequenceNumberFlags(header.public_header.packet_number_length)
@@ -723,34 +714,34 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
switch (header.public_header.connection_id_length) {
case PACKET_0BYTE_CONNECTION_ID:
- if (!writer->WriteUInt8(
- public_flags | PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
+ if (!writer->WriteUInt8(public_flags |
+ PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
return false;
}
break;
case PACKET_1BYTE_CONNECTION_ID:
- if (!writer->WriteUInt8(
- public_flags | PACKET_PUBLIC_FLAGS_1BYTE_CONNECTION_ID)) {
- return false;
+ if (!writer->WriteUInt8(public_flags |
+ PACKET_PUBLIC_FLAGS_1BYTE_CONNECTION_ID)) {
+ return false;
}
- if (!writer->WriteUInt8(
- header.public_header.connection_id & k1ByteConnectionIdMask)) {
+ if (!writer->WriteUInt8(header.public_header.connection_id &
+ k1ByteConnectionIdMask)) {
return false;
}
break;
case PACKET_4BYTE_CONNECTION_ID:
- if (!writer->WriteUInt8(
- public_flags | PACKET_PUBLIC_FLAGS_4BYTE_CONNECTION_ID)) {
- return false;
+ if (!writer->WriteUInt8(public_flags |
+ PACKET_PUBLIC_FLAGS_4BYTE_CONNECTION_ID)) {
+ return false;
}
- if (!writer->WriteUInt32(
- header.public_header.connection_id & k4ByteConnectionIdMask)) {
+ if (!writer->WriteUInt32(header.public_header.connection_id &
+ k4ByteConnectionIdMask)) {
return false;
}
break;
case PACKET_8BYTE_CONNECTION_ID:
- if (!writer->WriteUInt8(
- public_flags | PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID)) {
+ if (!writer->WriteUInt8(public_flags |
+ PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID)) {
return false;
}
if (!writer->WriteUInt64(header.public_header.connection_id)) {
@@ -768,12 +759,17 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
<< QuicUtils::TagToString(tag) << "'";
}
+ if (header.public_header.multipath_flag &&
+ !writer->WriteUInt8(header.path_id)) {
+ return false;
+ }
+
if (!AppendPacketSequenceNumber(header.public_header.packet_number_length,
- header.packet_packet_number, writer)) {
+ header.packet_number, writer)) {
return false;
}
- uint8 private_flags = 0;
+ uint8_t private_flags = 0;
if (header.entropy_flag) {
private_flags |= PACKET_PRIVATE_FLAGS_ENTROPY;
}
@@ -790,12 +786,12 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
// The FEC group number is the packet number of the first fec
// protected packet, or 0 if this packet is not protected.
if (header.is_in_fec_group == IN_FEC_GROUP) {
- DCHECK_LE(header.fec_group, header.packet_packet_number);
- DCHECK_LT(header.packet_packet_number - header.fec_group, 255u);
+ DCHECK_LE(header.fec_group, header.packet_number);
+ DCHECK_LT(header.packet_number - header.fec_group, 255u);
// Offset from the current packet number to the first fec
// protected packet.
- uint8 first_fec_protected_packet_offset =
- static_cast<uint8>(header.packet_packet_number - header.fec_group);
+ uint8_t first_fec_protected_packet_offset =
+ static_cast<uint8_t>(header.packet_number - header.fec_group);
if (!writer->WriteBytes(&first_fec_protected_packet_offset, 1)) {
return false;
}
@@ -805,7 +801,7 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
}
const QuicTime::Delta QuicFramer::CalculateTimestampFromWire(
- uint32 time_delta_us) {
+ uint32_t time_delta_us) {
// The new time_delta might have wrapped to the next epoch, or it
// might have reverse wrapped to the previous epoch, or it might
// remain in the same epoch. Select the time closest to the previous
@@ -813,24 +809,50 @@ const QuicTime::Delta QuicFramer::CalculateTimestampFromWire(
//
// epoch_delta is the delta between epochs. A delta is 4 bytes of
// microseconds.
- const uint64 epoch_delta = UINT64_C(1) << 32;
- uint64 epoch = last_timestamp_.ToMicroseconds() & ~(epoch_delta - 1);
+ const uint64_t epoch_delta = UINT64_C(1) << 32;
+ uint64_t epoch = last_timestamp_.ToMicroseconds() & ~(epoch_delta - 1);
// Wrapping is safe here because a wrapped value will not be ClosestTo below.
- uint64 prev_epoch = epoch - epoch_delta;
- uint64 next_epoch = epoch + epoch_delta;
+ uint64_t prev_epoch = epoch - epoch_delta;
+ uint64_t next_epoch = epoch + epoch_delta;
- uint64 time = ClosestTo(last_timestamp_.ToMicroseconds(),
- epoch + time_delta_us,
- ClosestTo(last_timestamp_.ToMicroseconds(),
- prev_epoch + time_delta_us,
- next_epoch + time_delta_us));
+ uint64_t time = ClosestTo(
+ last_timestamp_.ToMicroseconds(), epoch + time_delta_us,
+ ClosestTo(last_timestamp_.ToMicroseconds(), prev_epoch + time_delta_us,
+ next_epoch + time_delta_us));
return QuicTime::Delta::FromMicroseconds(time);
}
+bool QuicFramer::IsValidPath(QuicPathId path_id,
+ QuicPacketNumber* last_packet_number) {
+ if (ContainsKey(closed_paths_, path_id)) {
+ // Path is closed.
+ return false;
+ }
+
+ if (path_id == last_path_id_) {
+ *last_packet_number = last_packet_number_;
+ return true;
+ }
+
+ if (ContainsKey(last_packet_numbers_, path_id)) {
+ *last_packet_number = last_packet_numbers_[path_id];
+ } else {
+ *last_packet_number = 0;
+ }
+
+ return true;
+}
+
+void QuicFramer::OnPathClosed(QuicPathId path_id) {
+ closed_paths_.insert(path_id);
+ last_packet_numbers_.erase(path_id);
+}
+
QuicPacketNumber QuicFramer::CalculatePacketNumberFromWire(
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_packet_number) const {
+ QuicPacketNumber last_packet_number,
+ QuicPacketNumber packet_number) const {
// The new packet number might have wrapped to the next epoch, or
// it might have reverse wrapped to the previous epoch, or it might
// remain in the same epoch. Select the packet number closest to the
@@ -841,31 +863,32 @@ QuicPacketNumber QuicFramer::CalculatePacketNumberFromWire(
// number or an adjacent epoch.
const QuicPacketNumber epoch_delta = UINT64_C(1)
<< (8 * packet_number_length);
- QuicPacketNumber next_packet_number = last_packet_number_ + 1;
- QuicPacketNumber epoch = last_packet_number_ & ~(epoch_delta - 1);
+ QuicPacketNumber next_packet_number = last_packet_number + 1;
+ QuicPacketNumber epoch = last_packet_number & ~(epoch_delta - 1);
QuicPacketNumber prev_epoch = epoch - epoch_delta;
QuicPacketNumber next_epoch = epoch + epoch_delta;
- return ClosestTo(
- next_packet_number, epoch + packet_packet_number,
- ClosestTo(next_packet_number, prev_epoch + packet_packet_number,
- next_epoch + packet_packet_number));
+ return ClosestTo(next_packet_number, epoch + packet_number,
+ ClosestTo(next_packet_number, prev_epoch + packet_number,
+ next_epoch + packet_number));
}
bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
QuicPacketPublicHeader* public_header) {
- uint8 public_flags;
+ uint8_t public_flags;
if (!reader->ReadBytes(&public_flags, 1)) {
set_detailed_error("Unable to read public flags.");
return false;
}
+ public_header->multipath_flag =
+ (public_flags & PACKET_PUBLIC_FLAGS_MULTIPATH) != 0;
public_header->reset_flag = (public_flags & PACKET_PUBLIC_FLAGS_RST) != 0;
public_header->version_flag =
(public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
- if (validate_flags_ &&
- !public_header->version_flag && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+ if (validate_flags_ && !public_header->version_flag &&
+ public_flags > PACKET_PUBLIC_FLAGS_MAX) {
set_detailed_error("Illegal public flags value.");
return false;
}
@@ -893,9 +916,10 @@ bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
}
if (last_serialized_connection_id_ &&
(public_header->connection_id & k4ByteConnectionIdMask) !=
- (last_serialized_connection_id_ & k4ByteConnectionIdMask)) {
- set_detailed_error("Truncated 4 byte ConnectionId does not match "
- "previous connection_id.");
+ (last_serialized_connection_id_ & k4ByteConnectionIdMask)) {
+ set_detailed_error(
+ "Truncated 4 byte ConnectionId does not match "
+ "previous connection_id.");
return false;
}
public_header->connection_id_length = PACKET_4BYTE_CONNECTION_ID;
@@ -909,9 +933,10 @@ bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
}
if (last_serialized_connection_id_ &&
(public_header->connection_id & k1ByteConnectionIdMask) !=
- (last_serialized_connection_id_ & k1ByteConnectionIdMask)) {
- set_detailed_error("Truncated 1 byte ConnectionId does not match "
- "previous connection_id.");
+ (last_serialized_connection_id_ & k1ByteConnectionIdMask)) {
+ set_detailed_error(
+ "Truncated 1 byte ConnectionId does not match "
+ "previous connection_id.");
return false;
}
public_header->connection_id_length = PACKET_1BYTE_CONNECTION_ID;
@@ -963,7 +988,7 @@ QuicPacketNumberLength QuicFramer::GetMinSequenceNumberLength(
}
// static
-uint8 QuicFramer::GetSequenceNumberFlags(
+uint8_t QuicFramer::GetSequenceNumberFlags(
QuicPacketNumberLength packet_number_length) {
switch (packet_number_length) {
case PACKET_1BYTE_PACKET_NUMBER:
@@ -975,7 +1000,7 @@ uint8 QuicFramer::GetSequenceNumberFlags(
case PACKET_6BYTE_PACKET_NUMBER:
return PACKET_FLAGS_6BYTE_PACKET;
default:
- LOG(DFATAL) << "Unreachable case statement.";
+ QUIC_BUG << "Unreachable case statement.";
return PACKET_FLAGS_6BYTE_PACKET;
}
}
@@ -995,12 +1020,12 @@ QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
QuicPacketNumber last_missing = *iter;
++iter;
for (; iter != frame.missing_packets.end(); ++iter) {
- if (cur_range_length < numeric_limits<uint8>::max() &&
+ if (cur_range_length < numeric_limits<uint8_t>::max() &&
*iter == (last_missing + 1)) {
++cur_range_length;
} else {
ack_info.nack_ranges[last_missing - cur_range_length] =
- static_cast<uint8>(cur_range_length);
+ static_cast<uint8_t>(cur_range_length);
cur_range_length = 0;
}
ack_info.max_delta = max(ack_info.max_delta, *iter - last_missing);
@@ -1008,7 +1033,7 @@ QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
}
// Include the last nack range.
ack_info.nack_ranges[last_missing - cur_range_length] =
- static_cast<uint8>(cur_range_length);
+ static_cast<uint8_t>(cur_range_length);
// Include the range to the largest observed.
ack_info.max_delta =
max(ack_info.max_delta, frame.largest_observed - last_missing);
@@ -1017,14 +1042,27 @@ QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
QuicPacketHeader* header) {
- if (!ProcessPacketSequenceNumber(encrypted_reader,
- header->public_header.packet_number_length,
- &header->packet_packet_number)) {
+ if (header->public_header.multipath_flag &&
+ !ProcessPathId(encrypted_reader, &header->path_id)) {
+ set_detailed_error("Unable to read path id.");
+ return RaiseError(QUIC_INVALID_PACKET_HEADER);
+ }
+
+ QuicPacketNumber last_packet_number = last_packet_number_;
+ if (header->public_header.multipath_flag &&
+ !IsValidPath(header->path_id, &last_packet_number)) {
+ // Stop processing because path is closed.
+ return false;
+ }
+
+ if (!ProcessPacketSequenceNumber(
+ encrypted_reader, header->public_header.packet_number_length,
+ last_packet_number, &header->packet_number)) {
set_detailed_error("Unable to read packet number.");
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
- if (header->packet_packet_number == 0u) {
+ if (header->packet_number == 0u) {
set_detailed_error("packet numbers cannot be 0.");
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
@@ -1037,7 +1075,7 @@ bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
bool QuicFramer::ProcessAuthenticatedHeader(QuicDataReader* reader,
QuicPacketHeader* header) {
- uint8 private_flags;
+ uint8_t private_flags;
if (!reader->ReadBytes(&private_flags, 1)) {
set_detailed_error("Unable to read private flags.");
return RaiseError(QUIC_INVALID_PACKET_HEADER);
@@ -1053,31 +1091,49 @@ bool QuicFramer::ProcessAuthenticatedHeader(QuicDataReader* reader,
if ((private_flags & PACKET_PRIVATE_FLAGS_FEC_GROUP) != 0) {
header->is_in_fec_group = IN_FEC_GROUP;
- uint8 first_fec_protected_packet_offset;
+ uint8_t first_fec_protected_packet_offset;
if (!reader->ReadBytes(&first_fec_protected_packet_offset, 1)) {
set_detailed_error("Unable to read first fec protected packet offset.");
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
- if (first_fec_protected_packet_offset >= header->packet_packet_number) {
+ if (first_fec_protected_packet_offset >= header->packet_number) {
set_detailed_error(
"First fec protected packet offset must be less "
"than the packet number.");
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
header->fec_group =
- header->packet_packet_number - first_fec_protected_packet_offset;
+ header->packet_number - first_fec_protected_packet_offset;
}
header->entropy_hash = GetPacketEntropyHash(*header);
// Set the last packet number after we have decrypted the packet
// so we are confident is not attacker controlled.
- last_packet_number_ = header->packet_packet_number;
+ if (header->public_header.multipath_flag &&
+ header->path_id != last_path_id_) {
+ if (last_path_id_ != kInvalidPathId) {
+ // Save current last packet number before changing path.
+ last_packet_numbers_[last_path_id_] = last_packet_number_;
+ }
+ // Change path.
+ last_path_id_ = header->path_id;
+ }
+ last_packet_number_ = header->packet_number;
+ return true;
+}
+
+bool QuicFramer::ProcessPathId(QuicDataReader* reader, QuicPathId* path_id) {
+ if (!reader->ReadBytes(path_id, 1)) {
+ return false;
+ }
+
return true;
}
bool QuicFramer::ProcessPacketSequenceNumber(
QuicDataReader* reader,
QuicPacketNumberLength packet_number_length,
+ QuicPacketNumber last_packet_number,
QuicPacketNumber* packet_number) {
QuicPacketNumber wire_packet_number = 0u;
if (!reader->ReadBytes(&wire_packet_number, packet_number_length)) {
@@ -1086,8 +1142,8 @@ bool QuicFramer::ProcessPacketSequenceNumber(
// TODO(ianswett): Explore the usefulness of trying multiple packet numbers
// in case the first guess is incorrect.
- *packet_number =
- CalculatePacketNumberFromWire(packet_number_length, wire_packet_number);
+ *packet_number = CalculatePacketNumberFromWire(
+ packet_number_length, last_packet_number, wire_packet_number);
return true;
}
@@ -1098,7 +1154,7 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
return RaiseError(QUIC_MISSING_PAYLOAD);
}
while (!reader->IsDoneReading()) {
- uint8 frame_type;
+ uint8_t frame_type;
if (!reader->ReadBytes(&frame_type, 1)) {
set_detailed_error("Unable to read frame type.");
return RaiseError(QUIC_INVALID_FRAME_DATA);
@@ -1136,8 +1192,7 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
// This was a special frame type that did not match any
// of the known ones. Error.
set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
+ DLOG(WARNING) << "Illegal frame type: " << static_cast<int>(frame_type);
return RaiseError(QUIC_INVALID_FRAME_DATA);
}
@@ -1237,8 +1292,7 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
default:
set_detailed_error("Illegal frame type.");
- DLOG(WARNING) << "Illegal frame type: "
- << static_cast<int>(frame_type);
+ DLOG(WARNING) << "Illegal frame type: " << static_cast<int>(frame_type);
return RaiseError(QUIC_INVALID_FRAME_DATA);
}
}
@@ -1247,17 +1301,17 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
}
bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader,
- uint8 frame_type,
+ uint8_t frame_type,
QuicStreamFrame* frame) {
- uint8 stream_flags = frame_type;
+ uint8_t stream_flags = frame_type;
stream_flags &= ~kQuicFrameTypeStreamMask;
// Read from right to left: StreamID, Offset, Data Length, Fin.
- const uint8 stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
+ const uint8_t stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
stream_flags >>= kQuicStreamIdShift;
- uint8 offset_length = (stream_flags & kQuicStreamOffsetMask);
+ uint8_t offset_length = (stream_flags & kQuicStreamOffsetMask);
// There is no encoding for 1 byte, only 0 and 2 through 8.
if (offset_length > 0) {
offset_length += 1;
@@ -1282,23 +1336,27 @@ bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader,
return false;
}
+ // TODO(ianswett): Don't use StringPiece as an intermediary.
+ StringPiece data;
if (has_data_length) {
- if (!reader->ReadStringPiece16(&frame->data)) {
+ if (!reader->ReadStringPiece16(&data)) {
set_detailed_error("Unable to read frame data.");
return false;
}
} else {
- if (!reader->ReadStringPiece(&frame->data, reader->BytesRemaining())) {
+ if (!reader->ReadStringPiece(&data, reader->BytesRemaining())) {
set_detailed_error("Unable to read frame data.");
return false;
}
}
+ frame->frame_buffer = data.data();
+ frame->frame_length = static_cast<uint16_t>(data.length());
return true;
}
bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
- uint8 frame_type,
+ uint8_t frame_type,
QuicAckFrame* ack_frame) {
// Determine the three lengths from the frame type: largest observed length,
// missing packet number length, and missing range length.
@@ -1323,7 +1381,7 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
return false;
}
- uint64 delta_time_largest_observed_us;
+ uint64_t delta_time_largest_observed_us;
if (!reader->ReadUFloat16(&delta_time_largest_observed_us)) {
set_detailed_error("Unable to read delta time largest observed.");
return false;
@@ -1344,7 +1402,7 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
return true;
}
- uint8 num_missing_ranges;
+ uint8_t num_missing_ranges;
if (!reader->ReadBytes(&num_missing_ranges, 1)) {
set_detailed_error("Unable to read num missing packet ranges.");
return false;
@@ -1372,7 +1430,8 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
}
// Parse the revived packets list.
- uint8 num_revived_packets;
+ // TODO(ianswett): Change the ack frame so it only expresses one revived.
+ uint8_t num_revived_packets;
if (!reader->ReadBytes(&num_revived_packets, 1)) {
set_detailed_error("Unable to read num revived packets.");
return false;
@@ -1385,8 +1444,7 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
set_detailed_error("Unable to read revived packet.");
return false;
}
-
- ack_frame->revived_packets.insert(revived_packet);
+ ack_frame->latest_revived_packet = revived_packet;
}
return true;
@@ -1397,14 +1455,14 @@ bool QuicFramer::ProcessTimestampsInAckFrame(QuicDataReader* reader,
if (ack_frame->is_truncated) {
return true;
}
- uint8 num_received_packets;
+ uint8_t num_received_packets;
if (!reader->ReadBytes(&num_received_packets, 1)) {
set_detailed_error("Unable to read num received packets.");
return false;
}
if (num_received_packets > 0) {
- uint8 delta_from_largest_observed;
+ uint8_t delta_from_largest_observed;
if (!reader->ReadBytes(&delta_from_largest_observed,
PACKET_1BYTE_PACKET_NUMBER)) {
set_detailed_error("Unable to read sequence delta in received packets.");
@@ -1414,7 +1472,7 @@ bool QuicFramer::ProcessTimestampsInAckFrame(QuicDataReader* reader,
ack_frame->largest_observed - delta_from_largest_observed;
// Time delta from the framer creation.
- uint32 time_delta_us;
+ uint32_t time_delta_us;
if (!reader->ReadBytes(&time_delta_us, sizeof(time_delta_us))) {
set_detailed_error("Unable to read time delta in received packets.");
return false;
@@ -1422,10 +1480,11 @@ bool QuicFramer::ProcessTimestampsInAckFrame(QuicDataReader* reader,
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_.Add(last_timestamp_)));
- for (uint8 i = 1; i < num_received_packets; ++i) {
+ for (uint8_t i = 1; i < num_received_packets; ++i) {
if (!reader->ReadBytes(&delta_from_largest_observed,
PACKET_1BYTE_PACKET_NUMBER)) {
set_detailed_error(
@@ -1435,7 +1494,7 @@ bool QuicFramer::ProcessTimestampsInAckFrame(QuicDataReader* reader,
seq_num = ack_frame->largest_observed - delta_from_largest_observed;
// Time delta from the previous timestamp.
- uint64 incremental_time_delta_us;
+ uint64_t incremental_time_delta_us;
if (!reader->ReadUFloat16(&incremental_time_delta_us)) {
set_detailed_error(
"Unable to read incremental time delta in received packets.");
@@ -1465,9 +1524,8 @@ bool QuicFramer::ProcessStopWaitingFrame(QuicDataReader* reader,
set_detailed_error("Unable to read least unacked delta.");
return false;
}
- DCHECK_GE(header.packet_packet_number, least_unacked_delta);
- stop_waiting->least_unacked =
- header.packet_packet_number - least_unacked_delta;
+ DCHECK_GE(header.packet_number, least_unacked_delta);
+ stop_waiting->least_unacked = header.packet_number - least_unacked_delta;
return true;
}
@@ -1484,7 +1542,7 @@ bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
return false;
}
- uint32 error_code;
+ uint32_t error_code;
if (!reader->ReadUInt32(&error_code)) {
set_detailed_error("Unable to read rst stream error code.");
return false;
@@ -1496,21 +1554,12 @@ bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
}
frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code);
- if (quic_version_ <= QUIC_VERSION_24) {
- StringPiece error_details;
- if (!reader->ReadStringPiece16(&error_details)) {
- set_detailed_error("Unable to read rst stream error details.");
- return false;
- }
- frame->error_details = error_details.as_string();
- }
-
return true;
}
bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader,
QuicConnectionCloseFrame* frame) {
- uint32 error_code;
+ uint32_t error_code;
if (!reader->ReadUInt32(&error_code)) {
set_detailed_error("Unable to read connection close error code.");
return false;
@@ -1535,7 +1584,7 @@ bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader,
bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader,
QuicGoAwayFrame* frame) {
- uint32 error_code;
+ uint32_t error_code;
if (!reader->ReadUInt32(&error_code)) {
set_detailed_error("Unable to read go away error code.");
return false;
@@ -1547,7 +1596,7 @@ bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader,
return false;
}
- uint32 stream_id;
+ uint32_t stream_id;
if (!reader->ReadUInt32(&stream_id)) {
set_detailed_error("Unable to read last good stream id.");
return false;
@@ -1595,11 +1644,11 @@ StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket(
QuicConnectionIdLength connection_id_length,
bool includes_version,
QuicPacketNumberLength packet_number_length) {
+ // TODO(ianswett): This is identical to QuicData::AssociatedData.
return StringPiece(
- encrypted.data() + kStartOfHashData,
+ encrypted.data(),
GetStartOfEncryptedData(connection_id_length, includes_version,
- packet_number_length) -
- kStartOfHashData);
+ packet_number_length));
}
void QuicFramer::SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter) {
@@ -1625,52 +1674,34 @@ const QuicDecrypter* QuicFramer::alternative_decrypter() const {
return alternative_decrypter_.get();
}
-void QuicFramer::SetEncrypter(EncryptionLevel level,
- QuicEncrypter* encrypter) {
+void QuicFramer::SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter) {
DCHECK_GE(level, 0);
DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
encrypter_[level].reset(encrypter);
}
-QuicEncryptedPacket* QuicFramer::EncryptPayload(
- EncryptionLevel level,
- QuicPacketNumber packet_packet_number,
- const QuicPacket& packet,
- char* buffer,
- size_t buffer_len) {
+size_t QuicFramer::EncryptPayload(EncryptionLevel level,
+ QuicPacketNumber packet_number,
+ const QuicPacket& packet,
+ char* buffer,
+ size_t buffer_len) {
DCHECK(encrypter_[level].get() != nullptr);
- const size_t encrypted_len =
- encrypter_[level]->GetCiphertextSize(packet.Plaintext().length());
- StringPiece header_data = packet.BeforePlaintext();
- const size_t total_len = header_data.length() + encrypted_len;
-
- char* encryption_buffer = buffer;
- // Allocate a large enough buffer for the header and the encrypted data.
- const bool is_new_buffer = total_len > buffer_len;
- if (is_new_buffer) {
- if (!FLAGS_quic_allow_oversized_packets_for_test) {
- LOG(DFATAL) << "Buffer of length:" << buffer_len
- << " is not large enough to encrypt length " << total_len;
- return nullptr;
- }
- encryption_buffer = new char[total_len];
- }
+ StringPiece associated_data = packet.AssociatedData();
// Copy in the header, because the encrypter only populates the encrypted
// plaintext content.
- memcpy(encryption_buffer, header_data.data(), header_data.length());
+ const size_t ad_len = associated_data.length();
+ memmove(buffer, associated_data.data(), ad_len);
// Encrypt the plaintext into the buffer.
size_t output_length = 0;
- if (!encrypter_[level]->EncryptPacket(
- packet_packet_number, packet.AssociatedData(), packet.Plaintext(),
- encryption_buffer + header_data.length(), &output_length,
- encrypted_len)) {
+ if (!encrypter_[level]->EncryptPacket(packet_number, associated_data,
+ packet.Plaintext(), buffer + ad_len,
+ &output_length, buffer_len - ad_len)) {
RaiseError(QUIC_ENCRYPTION_FAILURE);
- return nullptr;
+ return 0;
}
- return new QuicEncryptedPacket(
- encryption_buffer, header_data.length() + output_length, is_new_buffer);
+ return ad_len + output_length;
}
size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
@@ -1703,14 +1734,14 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader,
header.public_header.version_flag,
header.public_header.packet_number_length);
bool success = decrypter_->DecryptPacket(
- header.packet_packet_number, associated_data, encrypted, decrypted_buffer,
+ header.packet_number, associated_data, encrypted, decrypted_buffer,
decrypted_length, buffer_length);
if (success) {
visitor_->OnDecryptedPacket(decrypter_level_);
} else if (alternative_decrypter_.get() != nullptr) {
success = alternative_decrypter_->DecryptPacket(
- header.packet_packet_number, associated_data, encrypted,
- decrypted_buffer, decrypted_length, buffer_length);
+ header.packet_number, associated_data, encrypted, decrypted_buffer,
+ decrypted_length, buffer_length);
if (success) {
visitor_->OnDecryptedPacket(alternative_decrypter_level_);
if (alternative_decrypter_latch_) {
@@ -1731,7 +1762,7 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader,
if (!success) {
DLOG(WARNING) << "DecryptPacket failed for packet_number:"
- << header.packet_packet_number;
+ << header.packet_number;
return false;
}
@@ -1749,11 +1780,12 @@ size_t QuicFramer::GetAckFrameSize(
size_t ack_size = GetMinAckFrameSize(largest_observed_length);
if (!ack_info.nack_ranges.empty()) {
- ack_size += kNumberOfNackRangesSize + kNumberOfRevivedPacketsSize;
+ ack_size += kNumberOfNackRangesSize + kNumberOfRevivedPacketsSize;
ack_size += min(ack_info.nack_ranges.size(), kMaxNackRanges) *
(missing_packet_number_length + PACKET_1BYTE_PACKET_NUMBER);
- ack_size += min(ack.revived_packets.size(),
- kMaxRevivedPackets) * largest_observed_length;
+ if (ack.latest_revived_packet != 0) {
+ ack_size += largest_observed_length;
+ }
}
// In version 23, if the ack will be truncated due to too many nack ranges,
@@ -1785,7 +1817,7 @@ size_t QuicFramer::ComputeFrameLength(
return GetMinStreamFrameSize(frame.stream_frame->stream_id,
frame.stream_frame->offset,
last_frame_in_packet, is_in_fec_group) +
- frame.stream_frame->data.length();
+ frame.stream_frame->frame_length;
case ACK_FRAME: {
return GetAckFrameSize(*frame.ack_frame, packet_number_length);
}
@@ -1797,14 +1829,10 @@ size_t QuicFramer::ComputeFrameLength(
// Ping has no payload.
return kQuicFrameTypeSize;
case RST_STREAM_FRAME:
- if (quic_version_ <= QUIC_VERSION_24) {
- return GetMinRstStreamFrameSize() +
- frame.rst_stream_frame->error_details.size();
- }
return GetRstStreamFrameSize();
case CONNECTION_CLOSE_FRAME:
return GetMinConnectionCloseFrameSize() +
- frame.connection_close_frame->error_details.size();
+ frame.connection_close_frame->error_details.size();
case GOAWAY_FRAME:
return GetMinGoAwayFrameSize() + frame.goaway_frame->reason_phrase.size();
case WINDOW_UPDATE_FRAME:
@@ -1827,18 +1855,18 @@ size_t QuicFramer::ComputeFrameLength(
bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
bool no_stream_frame_length,
QuicDataWriter* writer) {
- uint8 type_byte = 0;
+ uint8_t type_byte = 0;
switch (frame.type) {
case STREAM_FRAME: {
if (frame.stream_frame == nullptr) {
- LOG(DFATAL) << "Failed to append STREAM frame with no stream_frame.";
+ QUIC_BUG << "Failed to append STREAM frame with no stream_frame.";
}
// Fin bit.
type_byte |= frame.stream_frame->fin ? kQuicStreamFinMask : 0;
// Data Length bit.
type_byte <<= kQuicStreamDataLengthShift;
- type_byte |= no_stream_frame_length ? 0: kQuicStreamDataLengthMask;
+ type_byte |= no_stream_frame_length ? 0 : kQuicStreamDataLengthMask;
// Offset 3 bits.
type_byte <<= kQuicStreamOffsetShift;
@@ -1856,10 +1884,10 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
case ACK_FRAME:
return true;
case MTU_DISCOVERY_FRAME:
- type_byte = static_cast<uint8>(PING_FRAME);
+ type_byte = static_cast<uint8_t>(PING_FRAME);
break;
default:
- type_byte = static_cast<uint8>(frame.type);
+ type_byte = static_cast<uint8_t>(frame.type);
break;
}
@@ -1869,7 +1897,7 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
// static
bool QuicFramer::AppendPacketSequenceNumber(
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_packet_number,
+ QuicPacketNumber packet_number,
QuicDataWriter* writer) {
// Ensure the entire packet number can be written.
if (writer->capacity() - writer->length() <
@@ -1878,20 +1906,16 @@ bool QuicFramer::AppendPacketSequenceNumber(
}
switch (packet_number_length) {
case PACKET_1BYTE_PACKET_NUMBER:
- return writer->WriteUInt8(packet_packet_number &
- k1ByteSequenceNumberMask);
+ return writer->WriteUInt8(packet_number & k1ByteSequenceNumberMask);
break;
case PACKET_2BYTE_PACKET_NUMBER:
- return writer->WriteUInt16(packet_packet_number &
- k2ByteSequenceNumberMask);
+ return writer->WriteUInt16(packet_number & k2ByteSequenceNumberMask);
break;
case PACKET_4BYTE_PACKET_NUMBER:
- return writer->WriteUInt32(packet_packet_number &
- k4ByteSequenceNumberMask);
+ return writer->WriteUInt32(packet_number & k4ByteSequenceNumberMask);
break;
case PACKET_6BYTE_PACKET_NUMBER:
- return writer->WriteUInt48(packet_packet_number &
- k6ByteSequenceNumberMask);
+ return writer->WriteUInt48(packet_number & k6ByteSequenceNumberMask);
break;
default:
DCHECK(false) << "packet_number_length: " << packet_number_length;
@@ -1899,28 +1923,27 @@ bool QuicFramer::AppendPacketSequenceNumber(
}
}
-bool QuicFramer::AppendStreamFrame(
- const QuicStreamFrame& frame,
- bool no_stream_frame_length,
- QuicDataWriter* writer) {
+bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
+ bool no_stream_frame_length,
+ QuicDataWriter* writer) {
if (!writer->WriteBytes(&frame.stream_id, GetStreamIdSize(frame.stream_id))) {
- LOG(DFATAL) << "Writing stream id size failed.";
+ QUIC_BUG << "Writing stream id size failed.";
return false;
}
if (!writer->WriteBytes(&frame.offset, GetStreamOffsetSize(frame.offset))) {
- LOG(DFATAL) << "Writing offset size failed.";
+ QUIC_BUG << "Writing offset size failed.";
return false;
}
if (!no_stream_frame_length) {
- if ((frame.data.size() > numeric_limits<uint16>::max()) ||
- !writer->WriteUInt16(static_cast<uint16>(frame.data.size()))) {
- LOG(DFATAL) << "Writing stream frame length failed";
+ if ((frame.frame_length > numeric_limits<uint16_t>::max()) ||
+ !writer->WriteUInt16(static_cast<uint16_t>(frame.frame_length))) {
+ QUIC_BUG << "Writing stream frame length failed";
return false;
}
}
- if (!writer->WriteBytes(frame.data.data(), frame.data.size())) {
- LOG(DFATAL) << "Writing frame data failed.";
+ if (!writer->WriteBytes(frame.frame_buffer, frame.frame_length)) {
+ QUIC_BUG << "Writing frame data failed.";
return false;
}
return true;
@@ -1931,10 +1954,9 @@ void QuicFramer::set_version(const QuicVersion version) {
quic_version_ = version;
}
-bool QuicFramer::AppendAckFrameAndTypeByte(
- const QuicPacketHeader& header,
- const QuicAckFrame& frame,
- QuicDataWriter* writer) {
+bool QuicFramer::AppendAckFrameAndTypeByte(const QuicPacketHeader& header,
+ const QuicAckFrame& frame,
+ QuicDataWriter* writer) {
AckFrameInfo ack_info = GetAckFrameInfo(frame);
QuicPacketNumber ack_largest_observed = frame.largest_observed;
QuicPacketNumberLength largest_observed_length =
@@ -1956,7 +1978,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(
// Write out the type byte by setting the low order bits and doing shifts
// to make room for the next bit flags to be set.
// Whether there are any nacks.
- uint8 type_byte = ack_info.nack_ranges.empty() ? 0 : kQuicHasNacksMask;
+ uint8_t type_byte = ack_info.nack_ranges.empty() ? 0 : kQuicHasNacksMask;
// truncating bit.
type_byte <<= kQuicAckTruncatedShift;
@@ -1998,12 +2020,12 @@ bool QuicFramer::AppendAckFrameAndTypeByte(
return false;
}
- if (!AppendPacketSequenceNumber(largest_observed_length,
- ack_largest_observed, writer)) {
+ if (!AppendPacketSequenceNumber(largest_observed_length, ack_largest_observed,
+ writer)) {
return false;
}
- uint64 delta_time_largest_observed_us = kUFloat16MaxValue;
+ uint64_t delta_time_largest_observed_us = kUFloat16MaxValue;
if (!frame.delta_time_largest_observed.IsInfinite()) {
DCHECK_LE(0u, frame.delta_time_largest_observed.ToMicroseconds());
delta_time_largest_observed_us =
@@ -2025,8 +2047,8 @@ bool QuicFramer::AppendAckFrameAndTypeByte(
return true;
}
- const uint8 num_missing_ranges =
- static_cast<uint8>(min(ack_info.nack_ranges.size(), max_num_ranges));
+ const uint8_t num_missing_ranges =
+ static_cast<uint8_t>(min(ack_info.nack_ranges.size(), max_num_ranges));
if (!writer->WriteBytes(&num_missing_ranges, 1)) {
return false;
}
@@ -2053,20 +2075,20 @@ bool QuicFramer::AppendAckFrameAndTypeByte(
// Append revived packets.
// If not all the revived packets fit, only mention the ones that do.
- uint8 num_revived_packets =
- static_cast<uint8>(min(frame.revived_packets.size(), kMaxRevivedPackets));
- num_revived_packets = static_cast<uint8>(min(
- static_cast<size_t>(num_revived_packets),
- (writer->capacity() - writer->length()) / largest_observed_length));
+ uint8_t num_revived_packets = frame.latest_revived_packet == 0 ? 0 : 1;
+ if (((writer->capacity() - writer->length()) / largest_observed_length) ==
+ 0) {
+ num_revived_packets = 0;
+ }
if (!writer->WriteBytes(&num_revived_packets, 1)) {
return false;
}
- PacketNumberSet::const_iterator iter = frame.revived_packets.begin();
- for (int i = 0; i < num_revived_packets; ++i, ++iter) {
- LOG_IF(DFATAL, !frame.missing_packets.Contains(*iter));
+ if (num_revived_packets > 0) {
+ LOG_IF(DFATAL,
+ !frame.missing_packets.Contains(frame.latest_revived_packet));
if (!AppendPacketSequenceNumber(largest_observed_length,
- *iter, writer)) {
+ frame.latest_revived_packet, writer)) {
return false;
}
}
@@ -2076,14 +2098,13 @@ bool QuicFramer::AppendAckFrameAndTypeByte(
bool QuicFramer::AppendTimestampToAckFrame(const QuicAckFrame& frame,
QuicDataWriter* writer) {
- DCHECK_GE(numeric_limits<uint8>::max(), frame.received_packet_times.size());
+ DCHECK_GE(numeric_limits<uint8_t>::max(), frame.received_packet_times.size());
// num_received_packets is only 1 byte.
- if (frame.received_packet_times.size() > numeric_limits<uint8>::max()) {
+ if (frame.received_packet_times.size() > numeric_limits<uint8_t>::max()) {
return false;
}
- uint8 num_received_packets = frame.received_packet_times.size();
-
+ uint8_t num_received_packets = frame.received_packet_times.size();
if (!writer->WriteBytes(&num_received_packets, 1)) {
return false;
}
@@ -2091,26 +2112,26 @@ bool QuicFramer::AppendTimestampToAckFrame(const QuicAckFrame& frame,
return true;
}
- PacketTimeList::const_iterator it = frame.received_packet_times.begin();
+ PacketTimeVector::const_iterator it = frame.received_packet_times.begin();
QuicPacketNumber packet_number = it->first;
QuicPacketNumber delta_from_largest_observed =
frame.largest_observed - packet_number;
- DCHECK_GE(numeric_limits<uint8>::max(), delta_from_largest_observed);
- if (delta_from_largest_observed > numeric_limits<uint8>::max()) {
+ DCHECK_GE(numeric_limits<uint8_t>::max(), delta_from_largest_observed);
+ if (delta_from_largest_observed > numeric_limits<uint8_t>::max()) {
return false;
}
- if (!writer->WriteUInt8(
- delta_from_largest_observed & k1ByteSequenceNumberMask)) {
+ if (!writer->WriteUInt8(delta_from_largest_observed &
+ k1ByteSequenceNumberMask)) {
return false;
}
// Use the lowest 4 bytes of the time delta from the creation_time_.
- const uint64 time_epoch_delta_us = UINT64_C(1) << 32;
- uint32 time_delta_us =
- static_cast<uint32>(it->second.Subtract(creation_time_).ToMicroseconds()
- & (time_epoch_delta_us - 1));
+ const uint64_t time_epoch_delta_us = UINT64_C(1) << 32;
+ uint32_t time_delta_us = static_cast<uint32_t>(
+ it->second.Subtract(creation_time_).ToMicroseconds() &
+ (time_epoch_delta_us - 1));
if (!writer->WriteBytes(&time_delta_us, sizeof(time_delta_us))) {
return false;
}
@@ -2121,16 +2142,16 @@ bool QuicFramer::AppendTimestampToAckFrame(const QuicAckFrame& frame,
packet_number = it->first;
delta_from_largest_observed = frame.largest_observed - packet_number;
- if (delta_from_largest_observed > numeric_limits<uint8>::max()) {
+ if (delta_from_largest_observed > numeric_limits<uint8_t>::max()) {
return false;
}
- if (!writer->WriteUInt8(
- delta_from_largest_observed & k1ByteSequenceNumberMask)) {
+ if (!writer->WriteUInt8(delta_from_largest_observed &
+ k1ByteSequenceNumberMask)) {
return false;
}
- uint64 frame_time_delta_us =
+ uint64_t frame_time_delta_us =
it->second.Subtract(prev_time).ToMicroseconds();
prev_time = it->second;
if (!writer->WriteUFloat16(frame_time_delta_us)) {
@@ -2140,30 +2161,29 @@ bool QuicFramer::AppendTimestampToAckFrame(const QuicAckFrame& frame,
return true;
}
-bool QuicFramer::AppendStopWaitingFrame(
- const QuicPacketHeader& header,
- const QuicStopWaitingFrame& frame,
- QuicDataWriter* writer) {
- DCHECK_GE(header.packet_packet_number, frame.least_unacked);
+bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
+ const QuicStopWaitingFrame& frame,
+ QuicDataWriter* writer) {
+ DCHECK_GE(header.packet_number, frame.least_unacked);
const QuicPacketNumber least_unacked_delta =
- header.packet_packet_number - frame.least_unacked;
+ header.packet_number - frame.least_unacked;
const QuicPacketNumber length_shift =
header.public_header.packet_number_length * 8;
if (!writer->WriteUInt8(frame.entropy_hash)) {
- LOG(DFATAL) << " hash failed";
+ QUIC_BUG << " hash failed";
return false;
}
if (least_unacked_delta >> length_shift > 0) {
- LOG(DFATAL) << "packet_number_length "
- << header.public_header.packet_number_length
- << " is too small for least_unacked_delta: "
- << least_unacked_delta;
+ QUIC_BUG << "packet_number_length "
+ << header.public_header.packet_number_length
+ << " is too small for least_unacked_delta: "
+ << least_unacked_delta;
return false;
}
if (!AppendPacketSequenceNumber(header.public_header.packet_number_length,
least_unacked_delta, writer)) {
- LOG(DFATAL) << " seq failed: " << header.public_header.packet_number_length;
+ QUIC_BUG << " seq failed: " << header.public_header.packet_number_length;
return false;
}
@@ -2180,23 +2200,18 @@ bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
return false;
}
- uint32 error_code = static_cast<uint32>(frame.error_code);
+ uint32_t error_code = static_cast<uint32_t>(frame.error_code);
if (!writer->WriteUInt32(error_code)) {
return false;
}
- if (quic_version_ <= QUIC_VERSION_24) {
- if (!writer->WriteStringPiece16(frame.error_details)) {
- return false;
- }
- }
return true;
}
bool QuicFramer::AppendConnectionCloseFrame(
const QuicConnectionCloseFrame& frame,
QuicDataWriter* writer) {
- uint32 error_code = static_cast<uint32>(frame.error_code);
+ uint32_t error_code = static_cast<uint32_t>(frame.error_code);
if (!writer->WriteUInt32(error_code)) {
return false;
}
@@ -2208,11 +2223,11 @@ bool QuicFramer::AppendConnectionCloseFrame(
bool QuicFramer::AppendGoAwayFrame(const QuicGoAwayFrame& frame,
QuicDataWriter* writer) {
- uint32 error_code = static_cast<uint32>(frame.error_code);
+ uint32_t error_code = static_cast<uint32_t>(frame.error_code);
if (!writer->WriteUInt32(error_code)) {
return false;
}
- uint32 stream_id = static_cast<uint32>(frame.last_good_stream_id);
+ uint32_t stream_id = static_cast<uint32_t>(frame.last_good_stream_id);
if (!writer->WriteUInt32(stream_id)) {
return false;
}
@@ -2224,7 +2239,7 @@ bool QuicFramer::AppendGoAwayFrame(const QuicGoAwayFrame& frame,
bool QuicFramer::AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
QuicDataWriter* writer) {
- uint32 stream_id = static_cast<uint32>(frame.stream_id);
+ uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
if (!writer->WriteUInt32(stream_id)) {
return false;
}
@@ -2236,7 +2251,7 @@ bool QuicFramer::AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
bool QuicFramer::AppendBlockedFrame(const QuicBlockedFrame& frame,
QuicDataWriter* writer) {
- uint32 stream_id = static_cast<uint32>(frame.stream_id);
+ uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
if (!writer->WriteUInt32(stream_id)) {
return false;
}
diff --git a/chromium/net/quic/quic_framer.h b/chromium/net/quic/quic_framer.h
index 057dfadd806..a7fd9fa3662 100644
--- a/chromium/net/quic/quic_framer.h
+++ b/chromium/net/quic/quic_framer.h
@@ -5,11 +5,14 @@
#ifndef NET_QUIC_QUIC_FRAMER_H_
#define NET_QUIC_QUIC_FRAMER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -51,13 +54,11 @@ const size_t kQuicNumTimestampsSize = 1;
// Size in bytes reserved for the number of missing packets in ack frames.
const size_t kNumberOfNackRangesSize = 1;
// Maximum number of missing packet ranges that can fit within an ack frame.
-const size_t kMaxNackRanges =
- (1 << (kNumberOfNackRangesSize * 8)) - 1;
+const size_t kMaxNackRanges = (1 << (kNumberOfNackRangesSize * 8)) - 1;
// Size in bytes reserved for the number of revived packets in ack frames.
const size_t kNumberOfRevivedPacketsSize = 1;
// Maximum number of revived packets that can fit within an ack frame.
-const size_t kMaxRevivedPackets =
- (1 << (kNumberOfRevivedPacketsSize * 8)) - 1;
+const size_t kMaxRevivedPackets = (1 << (kNumberOfRevivedPacketsSize * 8)) - 1;
// This class receives callbacks from the framer when packets
// are processed.
@@ -81,8 +82,7 @@ class NET_EXPORT_PRIVATE QuicFramerVisitorInterface {
// Called when a public reset packet has been parsed but has not yet
// been validated.
- virtual void OnPublicResetPacket(
- const QuicPublicResetPacket& packet) = 0;
+ virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) = 0;
// Called only when |perspective_| is IS_CLIENT and a version negotiation
// packet has been parsed.
@@ -145,7 +145,7 @@ class NET_EXPORT_PRIVATE QuicFramerVisitorInterface {
virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
// Called when FEC data has been parsed.
- virtual void OnFecData(const QuicFecData& fec) = 0;
+ virtual void OnFecData(base::StringPiece redundancy) = 0;
// Called when a packet has been completely processed.
virtual void OnPacketComplete() = 0;
@@ -189,17 +189,13 @@ class NET_EXPORT_PRIVATE QuicFramer {
// else the framer will likely crash. It is acceptable for the visitor
// to do nothing. If this is called multiple times, only the last visitor
// will be used.
- void set_visitor(QuicFramerVisitorInterface* visitor) {
- visitor_ = visitor;
- }
+ void set_visitor(QuicFramerVisitorInterface* visitor) { visitor_ = visitor; }
const QuicVersionVector& supported_versions() const {
return supported_versions_;
}
- QuicVersion version() const {
- return quic_version_;
- }
+ QuicVersion version() const { return quic_version_; }
void set_version(const QuicVersion version);
@@ -218,9 +214,7 @@ class NET_EXPORT_PRIVATE QuicFramer {
entropy_calculator_ = entropy_calculator;
}
- QuicErrorCode error() const {
- return error_;
- }
+ QuicErrorCode error() const { return error_; }
// Pass a UDP packet into the framer for parsing.
// Return true if the packet was processed succesfully. |packet| must be a
@@ -286,27 +280,28 @@ class NET_EXPORT_PRIVATE QuicFramer {
bool includes_version,
QuicPacketNumberLength packet_number_length);
- // Returns a QuicPacket* that is owned by the caller, is created from
- // |frames|. Returns nullptr if the packet could not be created.
- // The packet must be of size |packet_size|.
- QuicPacket* BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames,
- char* buffer,
- size_t packet_length);
+ // Serializes a packet containing |frames| into |buffer|.
+ // Returns the length of the packet, which must not be longer than
+ // |packet_length|. Returns 0 if it fails to serialize.
+ size_t BuildDataPacket(const QuicPacketHeader& header,
+ const QuicFrames& frames,
+ char* buffer,
+ size_t packet_length);
// Returns a QuicPacket* that is owned by the caller, and is populated with
// the fields in |header| and |fec|. Returns nullptr if the packet could
// not be created.
QuicPacket* BuildFecPacket(const QuicPacketHeader& header,
- const QuicFecData& fec);
+ base::StringPiece redundancy);
// Returns a new public reset packet, owned by the caller.
static QuicEncryptedPacket* BuildPublicResetPacket(
const QuicPublicResetPacket& packet);
- QuicEncryptedPacket* BuildVersionNegotiationPacket(
- const QuicPacketPublicHeader& header,
- const QuicVersionVector& supported_versions);
+ // Returns a new version negotiation packet, owned by the caller.
+ static QuicEncryptedPacket* BuildVersionNegotiationPacket(
+ QuicConnectionId connection_id,
+ const QuicVersionVector& versions);
// SetDecrypter sets the primary decrypter, replacing any that already exists,
// and takes ownership. If an alternative decrypter is in place then the
@@ -332,14 +327,13 @@ class NET_EXPORT_PRIVATE QuicFramer {
// takes ownership of |encrypter|.
void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);
- // Returns a new encrypted packet, owned by the caller.
- // Encrypts into |buffer| if |buffer_len| is long enough, and otherwise
- // constructs a new buffer owned by the EncryptedPacket.
- QuicEncryptedPacket* EncryptPayload(EncryptionLevel level,
- QuicPacketNumber packet_number,
- const QuicPacket& packet,
- char* buffer,
- size_t buffer_len);
+ // Returns the length of the data encrypted into |buffer| if |buffer_len| is
+ // long enough, and otherwise 0.
+ size_t EncryptPayload(EncryptionLevel level,
+ QuicPacketNumber packet_number,
+ const QuicPacket& packet,
+ char* buffer,
+ size_t buffer_len);
// Returns the maximum length of plaintext that can be encrypted
// to ciphertext no larger than |ciphertext_size|.
@@ -363,10 +357,13 @@ class NET_EXPORT_PRIVATE QuicFramer {
static QuicPacketEntropyHash GetPacketEntropyHash(
const QuicPacketHeader& header);
+ // Called when a PATH_CLOSED frame has been sent/received on |path_id|.
+ void OnPathClosed(QuicPathId path_id);
+
private:
friend class test::QuicFramerPeer;
- typedef std::map<QuicPacketNumber, uint8> NackRangeMap;
+ typedef std::map<QuicPacketNumber, uint8_t> NackRangeMap;
struct AckFrameInfo {
AckFrameInfo();
@@ -403,15 +400,17 @@ class NET_EXPORT_PRIVATE QuicFramer {
bool ProcessAuthenticatedHeader(QuicDataReader* reader,
QuicPacketHeader* header);
+ bool ProcessPathId(QuicDataReader* reader, QuicPathId* path_id);
bool ProcessPacketSequenceNumber(QuicDataReader* reader,
QuicPacketNumberLength packet_number_length,
+ QuicPacketNumber last_packet_number,
QuicPacketNumber* packet_number);
bool ProcessFrameData(QuicDataReader* reader, const QuicPacketHeader& header);
bool ProcessStreamFrame(QuicDataReader* reader,
- uint8 frame_type,
+ uint8_t frame_type,
QuicStreamFrame* frame);
bool ProcessAckFrame(QuicDataReader* reader,
- uint8 frame_type,
+ uint8_t frame_type,
QuicAckFrame* frame);
bool ProcessTimestampsInAckFrame(QuicDataReader* reader, QuicAckFrame* frame);
bool ProcessStopWaitingFrame(QuicDataReader* reader,
@@ -432,15 +431,21 @@ class NET_EXPORT_PRIVATE QuicFramer {
size_t buffer_length,
size_t* decrypted_length);
+ // Checks if |path_id| is a viable path to receive packets on. Returns true
+ // and sets |last_packet_number| if the path is not closed. Returns false
+ // otherwise.
+ bool IsValidPath(QuicPathId path_id, QuicPacketNumber* last_packet_number);
+
// Returns the full packet number from the truncated
// wire format version and the last seen packet number.
QuicPacketNumber CalculatePacketNumberFromWire(
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_packet_number) const;
+ QuicPacketNumber last_packet_number,
+ QuicPacketNumber packet_number) const;
// Returns the QuicTime::Delta corresponding to the time from when the framer
// was created.
- const QuicTime::Delta CalculateTimestampFromWire(uint32 time_delta_us);
+ const QuicTime::Delta CalculateTimestampFromWire(uint32_t time_delta_us);
// Computes the wire size in bytes of the |ack| frame, assuming no truncation.
size_t GetAckFrameSize(const QuicAckFrame& ack,
@@ -454,10 +459,10 @@ class NET_EXPORT_PRIVATE QuicFramer {
static bool AppendPacketSequenceNumber(
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_packet_number,
+ QuicPacketNumber packet_number,
QuicDataWriter* writer);
- static uint8 GetSequenceNumberFlags(
+ static uint8_t GetSequenceNumberFlags(
QuicPacketNumberLength packet_number_length);
static AckFrameInfo GetAckFrameInfo(const QuicAckFrame& frame);
@@ -496,20 +501,26 @@ class NET_EXPORT_PRIVATE QuicFramer {
bool RaiseError(QuicErrorCode error);
- void set_error(QuicErrorCode error) {
- error_ = error;
- }
+ void set_error(QuicErrorCode error) { error_ = error; }
- void set_detailed_error(const char* error) {
- detailed_error_ = error;
- }
+ void set_detailed_error(const char* error) { detailed_error_ = error; }
std::string detailed_error_;
QuicFramerVisitorInterface* visitor_;
QuicReceivedEntropyHashCalculatorInterface* entropy_calculator_;
QuicErrorCode error_;
+ // Set of closed paths. A path is considered as closed if a PATH_CLOSED frame
+ // has been sent/received.
+ // TODO(fayang): this set is never cleaned up. A possible improvement is to
+ // use intervals.
+ base::hash_set<QuicPathId> closed_paths_;
+ // Map mapping path id to packet number of last successfully decrypted/revived
+ // received packet.
+ base::hash_map<QuicPathId, QuicPacketNumber> last_packet_numbers_;
// Updated by ProcessPacketHeader when it succeeds.
QuicPacketNumber last_packet_number_;
+ // The path on which last successfully decrypted/revived packet was received.
+ QuicPathId last_path_id_;
// Updated by WritePacketHeader.
QuicConnectionId last_serialized_connection_id_;
// Version of the protocol being used.
diff --git a/chromium/net/quic/quic_framer_test.cc b/chromium/net/quic/quic_framer_test.cc
index 45710c13e3a..da33b641eb3 100644
--- a/chromium/net/quic/quic_framer_test.cc
+++ b/chromium/net/quic/quic_framer_test.cc
@@ -40,6 +40,18 @@ namespace test {
const QuicPacketNumber kEpoch = UINT64_C(1) << 48;
const QuicPacketNumber kMask = kEpoch - 1;
+// 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 QuicPathId kPathId = 0x42;
+const QuicPacketNumber kPacketNumber = UINT64_C(0x123456789ABC);
+const QuicPacketNumber kLargestObserved = UINT64_C(0x0123456789ABF);
+const QuicPacketNumber kMissingPacket = UINT64_C(0x0123456789ABE);
+const QuicPacketNumber kLeastUnacked = UINT64_C(0x0123456789AA0);
+const QuicStreamId kStreamId = UINT64_C(0x01020304);
+const QuicStreamOffset kStreamOffset = UINT64_C(0xBA98FEDC32107654);
+const QuicPublicResetNonceProof kNonceProof = UINT64_C(0xABCDEF0123456789);
+
// Index into the connection_id offset in the header.
const size_t kConnectionIdOffset = kPublicFlagsSize;
// Index into the version string in the header. (if present).
@@ -51,49 +63,69 @@ size_t GetMinStreamFrameSize() {
return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
}
+// Index into the path id offset in the header (if present).
+size_t GetPathIdOffset(QuicConnectionIdLength connection_id_length,
+ bool include_version) {
+ return kConnectionIdOffset + connection_id_length +
+ (include_version ? kQuicVersionSize : 0);
+}
+
// Index into the packet number offset in the header.
size_t GetPacketNumberOffset(QuicConnectionIdLength connection_id_length,
- bool include_version) {
+ bool include_version,
+ bool include_path_id) {
return kConnectionIdOffset + connection_id_length +
- (include_version ? kQuicVersionSize : 0);
+ (include_version ? kQuicVersionSize : 0) +
+ (include_path_id ? kQuicPathIdSize : 0);
}
-size_t GetPacketNumberOffset(bool include_version) {
- return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
+size_t GetPacketNumberOffset(bool include_version, bool include_path_id) {
+ return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
+ include_path_id);
}
// Index into the private flags offset in the data packet header.
size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length,
- bool include_version) {
- return GetPacketNumberOffset(connection_id_length, include_version) +
+ bool include_version,
+ bool include_path_id) {
+ return GetPacketNumberOffset(connection_id_length, include_version,
+ include_path_id) +
PACKET_6BYTE_PACKET_NUMBER;
}
-size_t GetPrivateFlagsOffset(bool include_version) {
- return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
+size_t GetPrivateFlagsOffset(bool include_version, bool include_path_id) {
+ return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
+ include_path_id);
}
size_t GetPrivateFlagsOffset(bool include_version,
+ bool include_path_id,
QuicPacketNumberLength packet_number_length) {
- return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
+ return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
+ include_path_id) +
packet_number_length;
}
// Index into the fec group offset in the header.
size_t GetFecGroupOffset(QuicConnectionIdLength connection_id_length,
- bool include_version) {
- return GetPrivateFlagsOffset(connection_id_length, include_version) +
- kPrivateFlagsSize;
+ bool include_version,
+ bool include_path_id) {
+ return GetPrivateFlagsOffset(connection_id_length, include_version,
+ include_path_id) +
+ kPrivateFlagsSize;
}
-size_t GetFecGroupOffset(bool include_version) {
- return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
- kPrivateFlagsSize;
+size_t GetFecGroupOffset(bool include_version, bool include_path_id) {
+ return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
+ include_path_id) +
+ kPrivateFlagsSize;
}
size_t GetFecGroupOffset(bool include_version,
+ bool include_path_id,
QuicPacketNumberLength packet_number_length) {
- return GetPrivateFlagsOffset(include_version, packet_number_length) +
+ return GetPrivateFlagsOffset(include_version, include_path_id,
+ packet_number_length) +
kPrivateFlagsSize;
}
@@ -157,7 +189,7 @@ class TestDecrypter : public QuicDecrypter {
StringPiece GetNoncePrefix() const override { return StringPiece(); }
const char* cipher_name() const override { return "Test"; }
// Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
- uint32 cipher_id() const override { return 0xFFFFFFF2; }
+ uint32_t cipher_id() const override { return 0xFFFFFFF2; }
QuicPacketNumber packet_number_;
string associated_data_;
string ciphertext_;
@@ -174,17 +206,14 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
complete_packets_(0),
revived_packets_(0),
accept_packet_(true),
- accept_public_header_(true) {
- }
+ accept_public_header_(true) {}
~TestQuicVisitor() override {
STLDeleteElements(&stream_frames_);
STLDeleteElements(&ack_frames_);
STLDeleteElements(&stop_waiting_frames_);
STLDeleteElements(&ping_frames_);
- STLDeleteElements(&fec_data_);
STLDeleteElements(&stream_data_);
- STLDeleteElements(&fec_data_redundancy_);
}
void OnError(QuicFramer* f) override {
@@ -234,12 +263,11 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
++frame_count_;
// Save a copy of the data so it is valid after the packet is processed.
string* string_data = new string();
- frame.data.AppendToString(string_data);
+ StringPiece(frame.frame_buffer, frame.frame_length)
+ .AppendToString(string_data);
stream_data_.push_back(string_data);
- QuicStreamFrame* stream_frame = new QuicStreamFrame(frame);
- // Make sure that the stream frame points to this data.
- stream_frame->data = StringPiece(*string_data);
- stream_frames_.push_back(stream_frame);
+ stream_frames_.push_back(new QuicStreamFrame(frame.stream_id, frame.fin,
+ frame.offset, *string_data));
return true;
}
@@ -265,15 +293,9 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
return true;
}
- void OnFecData(const QuicFecData& fec) override {
+ void OnFecData(StringPiece redundancy) override {
++fec_count_;
- QuicFecData* fec_data = new QuicFecData();
- fec_data->fec_group = fec.fec_group;
- // Save a copy of the data so it is valid after the packet is processed.
- string* redundancy = new string(fec.redundancy.as_string());
- fec_data_redundancy_.push_back(redundancy);
- fec_data->redundancy = StringPiece(*redundancy);
- fec_data_.push_back(fec_data);
+ fec_data_redundancy_.push_back(redundancy.as_string());
}
void OnPacketComplete() override { ++complete_packets_; }
@@ -322,7 +344,6 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
vector<QuicAckFrame*> ack_frames_;
vector<QuicStopWaitingFrame*> stop_waiting_frames_;
vector<QuicPingFrame*> ping_frames_;
- vector<QuicFecData*> fec_data_;
string fec_protected_payload_;
QuicRstStreamFrame rst_stream_frame_;
QuicConnectionCloseFrame connection_close_frame_;
@@ -330,7 +351,7 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
QuicWindowUpdateFrame window_update_frame_;
QuicBlockedFrame blocked_frame_;
vector<string*> stream_data_;
- vector<string*> fec_data_redundancy_;
+ vector<string> fec_data_redundancy_;
};
class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
@@ -351,13 +372,13 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
// Helper function to get unsigned char representation of digit in the
// units place of the current QUIC version number.
unsigned char GetQuicVersionDigitOnes() {
- return static_cast<unsigned char> ('0' + version_%10);
+ return static_cast<unsigned char>('0' + version_ % 10);
}
// Helper function to get unsigned char representation of digit in the
// tens place of the current QUIC version number.
unsigned char GetQuicVersionDigitTens() {
- return static_cast<unsigned char> ('0' + (version_/10)%10);
+ return static_cast<unsigned char>('0' + (version_ / 10) % 10);
}
bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
@@ -368,14 +389,14 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
}
if (packet->AssociatedData() != encrypter_->associated_data_) {
LOG(ERROR) << "Encrypted incorrect associated data. expected "
- << packet->AssociatedData() << " actual: "
- << encrypter_->associated_data_;
+ << packet->AssociatedData()
+ << " actual: " << encrypter_->associated_data_;
return false;
}
if (packet->Plaintext() != encrypter_->plaintext_) {
LOG(ERROR) << "Encrypted incorrect plaintext data. expected "
- << packet->Plaintext() << " actual: "
- << encrypter_->plaintext_;
+ << packet->Plaintext()
+ << " actual: " << encrypter_->plaintext_;
return false;
}
return true;
@@ -383,9 +404,9 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
bool CheckDecryption(const QuicEncryptedPacket& encrypted,
bool includes_version) {
- if (visitor_.header_->packet_packet_number != decrypter_->packet_number_) {
+ if (visitor_.header_->packet_number != decrypter_->packet_number_) {
LOG(ERROR) << "Decrypted incorrect packet number. expected "
- << visitor_.header_->packet_packet_number
+ << visitor_.header_->packet_number
<< " actual: " << decrypter_->packet_number_;
return false;
}
@@ -404,16 +425,13 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
PACKET_6BYTE_PACKET_NUMBER)));
if (ciphertext != decrypter_->ciphertext_) {
LOG(ERROR) << "Decrypted incorrect ciphertext data. expected "
- << ciphertext << " actual: "
- << decrypter_->ciphertext_;
+ << ciphertext << " actual: " << decrypter_->ciphertext_;
return false;
}
return true;
}
- char* AsChars(unsigned char* data) {
- return reinterpret_cast<char*>(data);
- }
+ char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
void CheckProcessingFails(unsigned char* packet,
size_t len,
@@ -427,7 +445,7 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
// Checks if the supplied string matches data in the supplied StreamFrame.
void CheckStreamFrameData(string str, QuicStreamFrame* frame) {
- EXPECT_EQ(str, frame->data);
+ EXPECT_EQ(str, string(frame->frame_buffer, frame->frame_length));
}
void CheckStreamFrameBoundaries(unsigned char* packet,
@@ -447,7 +465,8 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, include_version,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_STREAM_DATA);
}
}
@@ -456,9 +475,11 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
QuicPacketNumber last_packet_number) {
QuicPacketNumber wire_packet_number = expected_packet_number & kMask;
QuicFramerPeer::SetLastPacketNumber(&framer_, last_packet_number);
- EXPECT_EQ(expected_packet_number,
- QuicFramerPeer::CalculatePacketNumberFromWire(
- &framer_, PACKET_6BYTE_PACKET_NUMBER, wire_packet_number))
+ EXPECT_EQ(
+ expected_packet_number,
+ QuicFramerPeer::CalculatePacketNumberFromWire(
+ &framer_, PACKET_6BYTE_PACKET_NUMBER,
+ QuicFramerPeer::GetLastPacketNumber(&framer_), wire_packet_number))
<< "last_packet_number: " << last_packet_number
<< " wire_packet_number: " << wire_packet_number;
}
@@ -495,14 +516,14 @@ TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
CheckCalculatePacketNumber(kEpoch, kMask);
// Cases where the last number was close to the start of the range.
- for (uint64 last = 0; last < 10; last++) {
+ for (uint64_t last = 0; last < 10; last++) {
// Small numbers should not wrap (even if they're out of order).
- for (uint64 j = 0; j < 10; j++) {
+ for (uint64_t j = 0; j < 10; j++) {
CheckCalculatePacketNumber(j, last);
}
// Large numbers should not wrap either (because we're near 0 already).
- for (uint64 j = 0; j < 10; j++) {
+ for (uint64_t j = 0; j < 10; j++) {
CheckCalculatePacketNumber(kEpoch - 1 - j, last);
}
}
@@ -510,16 +531,16 @@ TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) {
// Cases where the last number was close to the end of the range
- for (uint64 i = 0; i < 10; i++) {
+ for (uint64_t i = 0; i < 10; i++) {
QuicPacketNumber last = kEpoch - i;
// Small numbers should wrap.
- for (uint64 j = 0; j < 10; j++) {
+ for (uint64_t j = 0; j < 10; j++) {
CheckCalculatePacketNumber(kEpoch + j, last);
}
// Large numbers should not (even if they're out of order).
- for (uint64 j = 0; j < 10; j++) {
+ for (uint64_t j = 0; j < 10; j++) {
CheckCalculatePacketNumber(kEpoch - 1 - j, last);
}
}
@@ -528,69 +549,69 @@ TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) {
// Next check where we're in a non-zero epoch to verify we handle
// reverse wrapping, too.
TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearPrevEpoch) {
- const uint64 prev_epoch = 1 * kEpoch;
- const uint64 cur_epoch = 2 * kEpoch;
+ const uint64_t prev_epoch = 1 * kEpoch;
+ const uint64_t cur_epoch = 2 * kEpoch;
// Cases where the last number was close to the start of the range
- for (uint64 i = 0; i < 10; i++) {
- uint64 last = cur_epoch + i;
+ for (uint64_t i = 0; i < 10; i++) {
+ uint64_t last = cur_epoch + i;
// Small number should not wrap (even if they're out of order).
- for (uint64 j = 0; j < 10; j++) {
+ for (uint64_t j = 0; j < 10; j++) {
CheckCalculatePacketNumber(cur_epoch + j, last);
}
// But large numbers should reverse wrap.
- for (uint64 j = 0; j < 10; j++) {
- uint64 num = kEpoch - 1 - j;
+ for (uint64_t j = 0; j < 10; j++) {
+ uint64_t num = kEpoch - 1 - j;
CheckCalculatePacketNumber(prev_epoch + num, last);
}
}
}
TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextEpoch) {
- const uint64 cur_epoch = 2 * kEpoch;
- const uint64 next_epoch = 3 * kEpoch;
+ const uint64_t cur_epoch = 2 * kEpoch;
+ const uint64_t next_epoch = 3 * kEpoch;
// Cases where the last number was close to the end of the range
- for (uint64 i = 0; i < 10; i++) {
+ for (uint64_t i = 0; i < 10; i++) {
QuicPacketNumber last = next_epoch - 1 - i;
// Small numbers should wrap.
- for (uint64 j = 0; j < 10; j++) {
+ for (uint64_t j = 0; j < 10; j++) {
CheckCalculatePacketNumber(next_epoch + j, last);
}
// but large numbers should not (even if they're out of order).
- for (uint64 j = 0; j < 10; j++) {
- uint64 num = kEpoch - 1 - j;
+ for (uint64_t j = 0; j < 10; j++) {
+ uint64_t num = kEpoch - 1 - j;
CheckCalculatePacketNumber(cur_epoch + num, last);
}
}
}
TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextMax) {
- const uint64 max_number = numeric_limits<uint64>::max();
- const uint64 max_epoch = max_number & ~kMask;
+ const uint64_t max_number = numeric_limits<uint64_t>::max();
+ const uint64_t max_epoch = max_number & ~kMask;
// Cases where the last number was close to the end of the range
- for (uint64 i = 0; i < 10; i++) {
+ for (uint64_t i = 0; i < 10; i++) {
// Subtract 1, because the expected next packet number is 1 more than the
// last packet number.
QuicPacketNumber last = max_number - i - 1;
// Small numbers should not wrap, because they have nowhere to go.
- for (uint64 j = 0; j < 10; j++) {
+ for (uint64_t j = 0; j < 10; j++) {
CheckCalculatePacketNumber(max_epoch + j, last);
}
// Large numbers should not wrap either.
- for (uint64 j = 0; j < 10; j++) {
- uint64 num = kEpoch - 1 - j;
+ for (uint64_t j = 0; j < 10; j++) {
+ uint64_t num = kEpoch - 1 - j;
CheckCalculatePacketNumber(max_epoch + num, last);
}
}
}
TEST_P(QuicFramerTest, EmptyPacket) {
- char packet[] = { 0x00 };
+ char packet[] = {0x00};
QuicEncryptedPacket encrypted(packet, 0, false);
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error());
@@ -610,20 +631,19 @@ TEST_P(QuicFramerTest, LargePacket) {
};
memset(packet + GetPacketHeaderSize(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP), 0,
kMaxPacketSize - GetPacketHeaderSize(
- PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP) + 1);
// clang-format on
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
- EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+ EXPECT_DFATAL(framer_.ProcessPacket(encrypted), "Packet too large:1");
ASSERT_TRUE(visitor_.header_.get());
// Make sure we've parsed the packet header, so we can send an error.
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
// Make sure the correct error is propagated.
EXPECT_EQ(QUIC_PACKET_TOO_LARGE, framer_.error());
}
@@ -646,30 +666,31 @@ TEST_P(QuicFramerTest, PacketHeader) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
- } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
+ } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read ConnectionId.";
- } else if (i < GetPrivateFlagsOffset(!kIncludeVersion)) {
+ } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion)) {
+ } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read private flags.";
} else {
expected_error = "Unable to read first fec protected packet offset.";
@@ -679,8 +700,7 @@ TEST_P(QuicFramerTest, PacketHeader) {
}
TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
- QuicFramerPeer::SetLastSerializedConnectionId(
- &framer_, UINT64_C(0xFEDCBA9876543210));
+ QuicFramerPeer::SetLastSerializedConnectionId(&framer_, kConnectionId);
// clang-format off
unsigned char packet[] = {
@@ -699,33 +719,34 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_4BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
} else if (i < GetPacketNumberOffset(PACKET_4BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read ConnectionId.";
} else if (i < GetPrivateFlagsOffset(PACKET_4BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
} else if (i < GetFecGroupOffset(PACKET_4BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read private flags.";
} else {
expected_error = "Unable to read first fec protected packet offset.";
@@ -735,8 +756,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
}
TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
- QuicFramerPeer::SetLastSerializedConnectionId(
- &framer_, UINT64_C(0xFEDCBA9876543210));
+ QuicFramerPeer::SetLastSerializedConnectionId(&framer_, kConnectionId);
// clang-format off
unsigned char packet[] = {
@@ -755,33 +775,34 @@ TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_1BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
} else if (i < GetPacketNumberOffset(PACKET_1BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read ConnectionId.";
} else if (i < GetPrivateFlagsOffset(PACKET_1BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
} else if (i < GetFecGroupOffset(PACKET_1BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read private flags.";
} else {
expected_error = "Unable to read first fec protected packet offset.";
@@ -791,8 +812,7 @@ TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
}
TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
- QuicFramerPeer::SetLastSerializedConnectionId(
- &framer_, UINT64_C(0xFEDCBA9876543210));
+ QuicFramerPeer::SetLastSerializedConnectionId(&framer_, kConnectionId);
// clang-format off
unsigned char packet[] = {
@@ -811,33 +831,34 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
} else if (i < GetPacketNumberOffset(PACKET_0BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read ConnectionId.";
} else if (i < GetPrivateFlagsOffset(PACKET_0BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read packet number.";
} else if (i < GetFecGroupOffset(PACKET_0BYTE_CONNECTION_ID,
- !kIncludeVersion)) {
+ !kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read private flags.";
} else {
expected_error = "Unable to read first fec protected packet offset.";
@@ -866,33 +887,91 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_TRUE(visitor_.header_->public_header.version_flag);
EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
} else if (i < kVersionOffset) {
expected_error = "Unable to read ConnectionId.";
- } else if (i < GetPacketNumberOffset(kIncludeVersion)) {
+ } else if (i < GetPacketNumberOffset(kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read protocol version.";
- } else if (i < GetPrivateFlagsOffset(kIncludeVersion)) {
+ } else if (i < GetPrivateFlagsOffset(kIncludeVersion, !kIncludePathId)) {
+ expected_error = "Unable to read packet number.";
+ } else if (i < GetFecGroupOffset(kIncludeVersion, !kIncludePathId)) {
+ expected_error = "Unable to read private flags.";
+ } else {
+ expected_error = "Unable to read first fec protected packet offset.";
+ }
+ CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
+ }
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWithMultipathFlag) {
+ // clang-format off
+ unsigned char packet[] = {
+ // public flags (version)
+ 0x7C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+ // path_id
+ 0x42,
+ // packet number
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ // private flags
+ 0x00,
+ };
+ // clang-format on
+
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+ EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+ ASSERT_TRUE(visitor_.header_.get());
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_TRUE(visitor_.header_->public_header.multipath_flag);
+ EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
+ EXPECT_FALSE(visitor_.header_->public_header.version_flag);
+ EXPECT_FALSE(visitor_.header_->fec_flag);
+ EXPECT_FALSE(visitor_.header_->entropy_flag);
+ EXPECT_EQ(0, visitor_.header_->entropy_hash);
+ EXPECT_EQ(kPathId, visitor_.header_->path_id);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+ EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
+
+ // Now test framing boundaries.
+ for (size_t i = 0;
+ i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
+ ++i) {
+ string expected_error;
+ if (i < kConnectionIdOffset) {
+ expected_error = "Unable to read public flags.";
+ } else if (i <
+ GetPathIdOffset(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion)) {
+ expected_error = "Unable to read ConnectionId.";
+ } else if (i < GetPacketNumberOffset(!kIncludeVersion, kIncludePathId)) {
+ expected_error = "Unable to read path id.";
+ } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, kIncludePathId)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(kIncludeVersion)) {
+ } else if (i < GetFecGroupOffset(!kIncludeVersion, kIncludePathId)) {
expected_error = "Unable to read private flags.";
} else {
expected_error = "Unable to read first fec protected packet offset.";
@@ -901,8 +980,177 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
}
}
+TEST_P(QuicFramerTest, PacketHeaderWithBothVersionFlagAndMultipathFlag) {
+ // clang-format off
+ unsigned char packet[] = {
+ // public flags (version)
+ 0x7D,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+ // version tag
+ 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ // path_id
+ 0x42,
+ // packet number
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ // private flags
+ 0x00,
+ };
+ // clang-format on
+
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+ EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+ ASSERT_TRUE(visitor_.header_.get());
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_TRUE(visitor_.header_->public_header.multipath_flag);
+ EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
+ EXPECT_TRUE(visitor_.header_->public_header.version_flag);
+ EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]);
+ EXPECT_FALSE(visitor_.header_->fec_flag);
+ EXPECT_FALSE(visitor_.header_->entropy_flag);
+ EXPECT_EQ(0, visitor_.header_->entropy_hash);
+ EXPECT_EQ(kPathId, visitor_.header_->path_id);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+ EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
+
+ // Now test framing boundaries.
+ for (size_t i = 0;
+ i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
+ kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
+ ++i) {
+ string expected_error;
+ if (i < kConnectionIdOffset) {
+ expected_error = "Unable to read public flags.";
+ } else if (i < kVersionOffset) {
+ expected_error = "Unable to read ConnectionId.";
+ } else if (i <
+ GetPathIdOffset(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion)) {
+ expected_error = "Unable to read protocol version.";
+ } else if (i < GetPacketNumberOffset(kIncludeVersion, kIncludePathId)) {
+ expected_error = "Unable to read path id.";
+ } else if (i < GetPrivateFlagsOffset(kIncludeVersion, kIncludePathId)) {
+ expected_error = "Unable to read packet number.";
+ } else if (i < GetFecGroupOffset(kIncludeVersion, kIncludePathId)) {
+ expected_error = "Unable to read private flags.";
+ } else {
+ expected_error = "Unable to read first fec protected packet offset.";
+ }
+ CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
+ }
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWithPathChange) {
+ // Packet 1 from path 0x42.
+ // clang-format off
+ unsigned char packet1[] = {
+ // public flags (version)
+ 0x7C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+ // path_id
+ 0x42,
+ // packet number
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ // private flags
+ 0x00,
+ };
+ // clang-format on
+
+ EXPECT_EQ(0u, QuicFramerPeer::GetLastPacketNumber(&framer_));
+ EXPECT_EQ(kInvalidPathId, QuicFramerPeer::GetLastPathId(&framer_));
+ QuicEncryptedPacket encrypted1(AsChars(packet1), arraysize(packet1), false);
+ EXPECT_FALSE(framer_.ProcessPacket(encrypted1));
+ EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+ ASSERT_TRUE(visitor_.header_.get());
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kPathId, visitor_.header_->path_id);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+ EXPECT_EQ(kPacketNumber, QuicFramerPeer::GetLastPacketNumber(&framer_));
+ EXPECT_EQ(kPathId, QuicFramerPeer::GetLastPathId(&framer_));
+
+ // Packet 2 from default path.
+ // clang-format off
+ unsigned char packet2[] = {
+ // public flags (version)
+ 0x7C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+ // path_id
+ 0x00,
+ // packet number
+ 0xCC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ // private flags
+ 0x00,
+ };
+ // clang-format on
+
+ QuicEncryptedPacket encrypted2(AsChars(packet2), arraysize(packet2), false);
+ EXPECT_FALSE(framer_.ProcessPacket(encrypted2));
+ EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+ ASSERT_TRUE(visitor_.header_.get());
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kDefaultPathId, visitor_.header_->path_id);
+ EXPECT_EQ(kPacketNumber + 16, visitor_.header_->packet_number);
+ EXPECT_EQ(kPacketNumber + 16, QuicFramerPeer::GetLastPacketNumber(&framer_));
+ EXPECT_EQ(kDefaultPathId, QuicFramerPeer::GetLastPathId(&framer_));
+
+ // Packet 3 from path 0x42.
+ // clang-format off
+ unsigned char packet3[] = {
+ // public flags (version)
+ 0x7C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+ // path_id
+ 0x42,
+ // packet number
+ 0xBD, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ // private flags
+ 0x00,
+ };
+ // clang-format on
+
+ QuicEncryptedPacket encrypted3(AsChars(packet3), arraysize(packet3), false);
+ EXPECT_FALSE(framer_.ProcessPacket(encrypted3));
+ EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
+ ASSERT_TRUE(visitor_.header_.get());
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kPathId, visitor_.header_->path_id);
+ EXPECT_EQ(kPacketNumber + 1, visitor_.header_->packet_number);
+ EXPECT_EQ(kPacketNumber + 1, QuicFramerPeer::GetLastPacketNumber(&framer_));
+ EXPECT_EQ(kPathId, QuicFramerPeer::GetLastPathId(&framer_));
+}
+
+TEST_P(QuicFramerTest, ReceivedPacketOnClosedPath) {
+ // Packet 1 from path 0x42.
+ // clang-format off
+ unsigned char packet[] = {
+ // public flags (version)
+ 0x7C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+ // path_id
+ 0x42,
+ // packet number
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ // private flags
+ 0x00,
+ };
+ // clang-format on
+
+ framer_.OnPathClosed(kPathId);
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+ EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
+ EXPECT_EQ(0u, QuicFramerPeer::GetLastPacketNumber(&framer_));
+ EXPECT_EQ(kInvalidPathId, QuicFramerPeer::GetLastPathId(&framer_));
+}
+
TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
- QuicFramerPeer::SetLastPacketNumber(&framer_, UINT64_C(0x123456789ABA));
+ QuicFramerPeer::SetLastPacketNumber(&framer_, kPacketNumber - 2);
// clang-format off
unsigned char packet[] = {
@@ -921,31 +1169,32 @@ TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_4BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_4BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
- } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
+ } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read ConnectionId.";
- } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
+ } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId,
PACKET_4BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion,
+ } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId,
PACKET_4BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read private flags.";
} else {
@@ -956,7 +1205,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
}
TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
- QuicFramerPeer::SetLastPacketNumber(&framer_, UINT64_C(0x123456789ABA));
+ QuicFramerPeer::SetLastPacketNumber(&framer_, kPacketNumber - 2);
// clang-format off
unsigned char packet[] = {
@@ -975,31 +1224,32 @@ TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_2BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_2BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
- } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
+ } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read ConnectionId.";
- } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
+ } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId,
PACKET_2BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion,
+ } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId,
PACKET_2BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read private flags.";
} else {
@@ -1010,7 +1260,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
}
TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
- QuicFramerPeer::SetLastPacketNumber(&framer_, UINT64_C(0x123456789ABA));
+ QuicFramerPeer::SetLastPacketNumber(&framer_, kPacketNumber - 2);
// clang-format off
unsigned char packet[] = {
@@ -1029,31 +1279,32 @@ TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
+ EXPECT_FALSE(visitor_.header_->public_header.multipath_flag);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_FALSE(visitor_.header_->fec_flag);
EXPECT_FALSE(visitor_.header_->entropy_flag);
EXPECT_EQ(0, visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
// Now test framing boundaries.
for (size_t i = 0;
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ !kIncludePathId, PACKET_1BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP);
++i) {
string expected_error;
if (i < kConnectionIdOffset) {
expected_error = "Unable to read public flags.";
- } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
+ } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
expected_error = "Unable to read ConnectionId.";
- } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
+ } else if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId,
PACKET_1BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read packet number.";
- } else if (i < GetFecGroupOffset(!kIncludeVersion,
+ } else if (i < GetFecGroupOffset(!kIncludeVersion, !kIncludePathId,
PACKET_1BYTE_PACKET_NUMBER)) {
expected_error = "Unable to read private flags.";
} else {
@@ -1081,9 +1332,7 @@ TEST_P(QuicFramerTest, InvalidPublicFlag) {
};
// clang-format on
- CheckProcessingFails(packet,
- arraysize(packet),
- "Illegal public flags value.",
+ CheckProcessingFails(packet, arraysize(packet), "Illegal public flags value.",
QUIC_INVALID_PACKET_HEADER);
// Now turn off validation.
@@ -1096,7 +1345,7 @@ TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id and version flag and an unknown flag)
- 0x4D,
+ 0x8D,
// connection_id
0x10, 0x32, 0x54, 0x76,
0x98, 0xBA, 0xDC, 0xFE,
@@ -1113,9 +1362,7 @@ TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) {
0x00, 0x00, 0x00, 0x00
};
// clang-format on
- CheckProcessingFails(packet,
- arraysize(packet),
- "Illegal public flags value.",
+ CheckProcessingFails(packet, arraysize(packet), "Illegal public flags value.",
QUIC_INVALID_PACKET_HEADER);
};
@@ -1167,8 +1414,7 @@ TEST_P(QuicFramerTest, InvalidPrivateFlag) {
0x00, 0x00, 0x00, 0x00
};
// clang-format on
- CheckProcessingFails(packet,
- arraysize(packet),
+ CheckProcessingFails(packet, arraysize(packet),
"Illegal private flags value.",
QUIC_INVALID_PACKET_HEADER);
};
@@ -1240,7 +1486,8 @@ TEST_P(QuicFramerTest, PaddingFrame) {
// A packet with no frames is not acceptable.
CheckProcessingFails(
packet, GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
"Packet has no frames.", QUIC_MISSING_PAYLOAD);
}
@@ -1283,10 +1530,9 @@ TEST_P(QuicFramerTest, StreamFrame) {
ASSERT_EQ(1u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(static_cast<uint64>(0x01020304),
- visitor_.stream_frames_[0]->stream_id);
+ EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset);
+ EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
// Now test framing boundaries.
@@ -1332,9 +1578,10 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
ASSERT_EQ(1u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(UINT64_C(0x00020304), visitor_.stream_frames_[0]->stream_id);
+ // Stream ID should be the last 3 bytes of kStreamId.
+ EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset);
+ EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
// Now test framing boundaries.
@@ -1381,10 +1628,10 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
ASSERT_EQ(1u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(static_cast<uint64>(0x00000304),
- visitor_.stream_frames_[0]->stream_id);
+ // Stream ID should be the last 2 bytes of kStreamId.
+ EXPECT_EQ(0x0000FFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset);
+ EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
// Now test framing boundaries.
@@ -1431,10 +1678,10 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
ASSERT_EQ(1u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(static_cast<uint64>(0x00000004),
- visitor_.stream_frames_[0]->stream_id);
+ // Stream ID should be the last byte of kStreamId.
+ EXPECT_EQ(0x000000FF & kStreamId, visitor_.stream_frames_[0]->stream_id);
EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset);
+ EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
// Now test framing boundaries.
@@ -1485,10 +1732,9 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
ASSERT_EQ(1u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(static_cast<uint64>(0x01020304),
- visitor_.stream_frames_[0]->stream_id);
+ EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset);
+ EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
// Now test framing boundaries.
@@ -1579,39 +1825,36 @@ TEST_P(QuicFramerTest, RevivedStreamFrame) {
// clang-format on
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = true;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
// Do not encrypt the payload because the revived payload is post-encryption.
- EXPECT_TRUE(framer_.ProcessRevivedPacket(&header,
- StringPiece(AsChars(payload),
- arraysize(payload))));
+ EXPECT_TRUE(framer_.ProcessRevivedPacket(
+ &header, StringPiece(AsChars(payload), arraysize(payload))));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
ASSERT_EQ(1, visitor_.revived_packets_);
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
- visitor_.header_->public_header.connection_id);
+ EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id);
EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
EXPECT_FALSE(visitor_.header_->public_header.version_flag);
EXPECT_TRUE(visitor_.header_->fec_flag);
EXPECT_TRUE(visitor_.header_->entropy_flag);
- EXPECT_EQ(1 << (header.packet_packet_number % 8),
- visitor_.header_->entropy_hash);
- EXPECT_EQ(UINT64_C(0x123456789ABC), visitor_.header_->packet_packet_number);
+ EXPECT_EQ(1 << (header.packet_number % 8), visitor_.header_->entropy_hash);
+ EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(0x00u, visitor_.header_->fec_group);
+ EXPECT_EQ(0u, visitor_.header_->fec_group);
ASSERT_EQ(1u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id);
+ EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset);
+ EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
}
@@ -1625,7 +1868,7 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
0x98, 0xBA, 0xDC, 0xFE,
// packet number
0xBC, 0x9A, 0x78, 0x56,
- 0x12, 0x34,
+ 0x34, 0x12,
// private flags (fec group)
0x02,
// first fec protected packet offset
@@ -1654,7 +1897,7 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
EXPECT_EQ(IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
- EXPECT_EQ(UINT64_C(0x341256789ABA), visitor_.header_->fec_group);
+ EXPECT_EQ(kPacketNumber - 2, visitor_.header_->fec_group);
const size_t fec_offset = GetStartOfFecProtectedData(
PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, PACKET_6BYTE_PACKET_NUMBER);
EXPECT_EQ(
@@ -1663,9 +1906,9 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
ASSERT_EQ(1u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
- EXPECT_EQ(UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id);
+ EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
- EXPECT_EQ(UINT64_C(0xBA98FEDC32107654), visitor_.stream_frames_[0]->offset);
+ EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
}
@@ -1722,14 +1965,14 @@ TEST_P(QuicFramerTest, AckFrameTwoTimestamp) {
ASSERT_EQ(1u, visitor_.ack_frames_.size());
const QuicAckFrame& frame = *visitor_.ack_frames_[0];
EXPECT_EQ(0xBA, frame.entropy_hash);
- EXPECT_EQ(UINT64_C(0x0123456789ABF), frame.largest_observed);
+ EXPECT_EQ(kLargestObserved, frame.largest_observed);
ASSERT_EQ(1u, frame.missing_packets.NumPacketsSlow());
ASSERT_EQ(2u, frame.received_packet_times.size());
- EXPECT_EQ(UINT64_C(0x0123456789ABE), frame.missing_packets.Min());
+ EXPECT_EQ(kMissingPacket, frame.missing_packets.Min());
const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
- const size_t kLargestObservedOffset = kReceivedEntropyOffset +
- kQuicEntropyHashSize;
+ const size_t kLargestObservedOffset =
+ kReceivedEntropyOffset + kQuicEntropyHashSize;
const size_t kMissingDeltaTimeOffset =
kLargestObservedOffset + PACKET_6BYTE_PACKET_NUMBER;
const size_t kNumTimestampsOffset =
@@ -1784,7 +2027,8 @@ TEST_P(QuicFramerTest, AckFrameTwoTimestamp) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -1838,10 +2082,10 @@ TEST_P(QuicFramerTest, AckFrameOneTimestamp) {
ASSERT_EQ(1u, visitor_.ack_frames_.size());
const QuicAckFrame& frame = *visitor_.ack_frames_[0];
EXPECT_EQ(0xBA, frame.entropy_hash);
- EXPECT_EQ(UINT64_C(0x0123456789ABF), frame.largest_observed);
+ EXPECT_EQ(kLargestObserved, frame.largest_observed);
ASSERT_EQ(1u, frame.missing_packets.NumPacketsSlow());
ASSERT_EQ(1u, frame.received_packet_times.size());
- EXPECT_EQ(UINT64_C(0x0123456789ABE), frame.missing_packets.Min());
+ EXPECT_EQ(kMissingPacket, frame.missing_packets.Min());
const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
const size_t kLargestObservedOffset =
@@ -1853,7 +2097,7 @@ TEST_P(QuicFramerTest, AckFrameOneTimestamp) {
const size_t kTimestampDeltaLargestObserved =
kNumTimestampsOffset + kQuicNumTimestampsSize;
const size_t kTimestampTimeDeltaLargestObserved =
- kTimestampDeltaLargestObserved + 1;
+ kTimestampDeltaLargestObserved + 1;
const size_t kNumMissingPacketOffset = kTimestampTimeDeltaLargestObserved + 4;
const size_t kMissingPacketsOffset =
kNumMissingPacketOffset + kNumberOfNackRangesSize;
@@ -1890,7 +2134,8 @@ TEST_P(QuicFramerTest, AckFrameOneTimestamp) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -1940,21 +2185,21 @@ TEST_P(QuicFramerTest, AckFrame) {
ASSERT_EQ(1u, visitor_.ack_frames_.size());
const QuicAckFrame& frame = *visitor_.ack_frames_[0];
EXPECT_EQ(0xBA, frame.entropy_hash);
- EXPECT_EQ(UINT64_C(0x0123456789ABF), frame.largest_observed);
+ EXPECT_EQ(kLargestObserved, frame.largest_observed);
ASSERT_EQ(1u, frame.missing_packets.NumPacketsSlow());
- EXPECT_EQ(UINT64_C(0x0123456789ABE), frame.missing_packets.Min());
+ EXPECT_EQ(kMissingPacket, frame.missing_packets.Min());
const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
- const size_t kLargestObservedOffset = kReceivedEntropyOffset +
- kQuicEntropyHashSize;
+ const size_t kLargestObservedOffset =
+ kReceivedEntropyOffset + kQuicEntropyHashSize;
const size_t kMissingDeltaTimeOffset =
kLargestObservedOffset + PACKET_6BYTE_PACKET_NUMBER;
- const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
- kQuicDeltaTimeLargestObservedSize;
- const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
- kQuicNumTimestampsSize;
- const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
- kNumberOfNackRangesSize;
+ const size_t kNumTimestampsOffset =
+ kMissingDeltaTimeOffset + kQuicDeltaTimeLargestObservedSize;
+ const size_t kNumMissingPacketOffset =
+ kNumTimestampsOffset + kQuicNumTimestampsSize;
+ const size_t kMissingPacketsOffset =
+ kNumMissingPacketOffset + kNumberOfNackRangesSize;
const size_t kMissingPacketsRange =
kMissingPacketsOffset + PACKET_1BYTE_PACKET_NUMBER;
const size_t kRevivedPacketsLength =
@@ -1984,7 +2229,8 @@ TEST_P(QuicFramerTest, AckFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -2038,21 +2284,21 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
ASSERT_EQ(1u, visitor_.ack_frames_.size());
const QuicAckFrame& frame = *visitor_.ack_frames_[0];
EXPECT_EQ(0xBA, frame.entropy_hash);
- EXPECT_EQ(UINT64_C(0x0123456789ABF), frame.largest_observed);
+ EXPECT_EQ(kLargestObserved, frame.largest_observed);
ASSERT_EQ(1u, frame.missing_packets.NumPacketsSlow());
- EXPECT_EQ(UINT64_C(0x0123456789ABE), frame.missing_packets.Min());
+ EXPECT_EQ(kMissingPacket, frame.missing_packets.Min());
const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
- const size_t kLargestObservedOffset = kReceivedEntropyOffset +
- kQuicEntropyHashSize;
+ const size_t kLargestObservedOffset =
+ kReceivedEntropyOffset + kQuicEntropyHashSize;
const size_t kMissingDeltaTimeOffset =
kLargestObservedOffset + PACKET_6BYTE_PACKET_NUMBER;
- const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
- kQuicDeltaTimeLargestObservedSize;
- const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
- kQuicNumTimestampsSize;
- const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
- kNumberOfNackRangesSize;
+ const size_t kNumTimestampsOffset =
+ kMissingDeltaTimeOffset + kQuicDeltaTimeLargestObservedSize;
+ const size_t kNumMissingPacketOffset =
+ kNumTimestampsOffset + kQuicNumTimestampsSize;
+ const size_t kMissingPacketsOffset =
+ kNumMissingPacketOffset + kNumberOfNackRangesSize;
const size_t kMissingPacketsRange =
kMissingPacketsOffset + PACKET_1BYTE_PACKET_NUMBER;
const size_t kRevivedPacketsLength =
@@ -2088,7 +2334,8 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_ACK_DATA);
}
}
@@ -2130,7 +2377,7 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) {
ASSERT_EQ(1u, visitor_.ack_frames_.size());
QuicAckFrame* frame = visitor_.ack_frames_[0];
EXPECT_EQ(0xBA, frame->entropy_hash);
- EXPECT_EQ(UINT64_C(0x0123456789ABF), frame->largest_observed);
+ EXPECT_EQ(kLargestObserved, frame->largest_observed);
ASSERT_TRUE(frame->missing_packets.Empty());
// Verify that the packet re-serializes identically.
@@ -2195,11 +2442,11 @@ TEST_P(QuicFramerTest, AckFrame500Nacks) {
ASSERT_EQ(1u, visitor_.ack_frames_.size());
QuicAckFrame* frame = visitor_.ack_frames_[0];
EXPECT_EQ(0xBA, frame->entropy_hash);
- EXPECT_EQ(UINT64_C(0x0123456789ABF), frame->largest_observed);
- EXPECT_EQ(0u, frame->revived_packets.size());
+ EXPECT_EQ(kLargestObserved, frame->largest_observed);
+ EXPECT_EQ(0u, frame->latest_revived_packet);
ASSERT_EQ(500u, frame->missing_packets.NumPacketsSlow());
- EXPECT_EQ(UINT64_C(0x0123456789ABE) - 499, frame->missing_packets.Min());
- EXPECT_EQ(UINT64_C(0x0123456789ABE), frame->missing_packets.Max());
+ EXPECT_EQ(kMissingPacket - 499, frame->missing_packets.Min());
+ EXPECT_EQ(kMissingPacket, frame->missing_packets.Max());
// Verify that the packet re-serializes identically.
QuicFrames frames;
@@ -2207,9 +2454,9 @@ TEST_P(QuicFramerTest, AckFrame500Nacks) {
scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, StopWaitingFrame) {
@@ -2248,7 +2495,7 @@ TEST_P(QuicFramerTest, StopWaitingFrame) {
ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
EXPECT_EQ(0xAB, frame.entropy_hash);
- EXPECT_EQ(UINT64_C(0x0123456789AA0), frame.least_unacked);
+ EXPECT_EQ(kLeastUnacked, frame.least_unacked);
const size_t kSentEntropyOffset = kQuicFrameTypeSize;
const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
@@ -2263,94 +2510,13 @@ TEST_P(QuicFramerTest, StopWaitingFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_STOP_WAITING_DATA);
}
}
-TEST_P(QuicFramerTest, RstStreamFrameQuicVersion24) {
- if (version_ > QUIC_VERSION_24) {
- // QUIC_VERSION_25 removes the error_details field from QuicRstStreamFrame.
- return;
- }
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (rst stream frame)
- 0x01,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
-
- // sent byte offset
- 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
-
- // error code
- 0x01, 0x00, 0x00, 0x00,
-
- // error details length
- 0x0d, 0x00,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
- // clang-format on
-
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
- ASSERT_TRUE(visitor_.header_.get());
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
-
- EXPECT_EQ(UINT64_C(0x01020304), visitor_.rst_stream_frame_.stream_id);
- EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code);
- EXPECT_EQ("because I can", visitor_.rst_stream_frame_.error_details);
- EXPECT_EQ(UINT64_C(0x0807060504030201),
- visitor_.rst_stream_frame_.byte_offset);
-
- // Now test framing boundaries.
- for (size_t i = kQuicFrameTypeSize;
- i < QuicFramer::GetMinRstStreamFrameSize(); ++i) {
- string expected_error;
- if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) {
- expected_error = "Unable to read stream_id.";
- } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize +
- kQuicMaxStreamOffsetSize) {
- expected_error = "Unable to read rst stream sent byte offset.";
- } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize +
- kQuicMaxStreamOffsetSize + kQuicErrorCodeSize) {
- expected_error = "Unable to read rst stream error code.";
- } else {
- expected_error = "Unable to read rst stream error details.";
- }
- CheckProcessingFails(
- packet,
- i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
- expected_error, QUIC_INVALID_RST_STREAM_DATA);
- }
-}
-
TEST_P(QuicFramerTest, RstStreamFrameQuic) {
- if (version_ <= QUIC_VERSION_24) {
- // QUIC_VERSION_25 removes the error_details field from QuicRstStreamFrame.
- return;
- }
-
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -2370,8 +2536,8 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) {
0x04, 0x03, 0x02, 0x01,
// sent byte offset
- 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
+ 0x54, 0x76, 0x10, 0x32,
+ 0xDC, 0xFE, 0x98, 0xBA,
// error code
0x01, 0x00, 0x00, 0x00,
@@ -2385,10 +2551,9 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
- EXPECT_EQ(UINT64_C(0x01020304), visitor_.rst_stream_frame_.stream_id);
+ EXPECT_EQ(kStreamId, visitor_.rst_stream_frame_.stream_id);
EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code);
- EXPECT_EQ(UINT64_C(0x0807060504030201),
- visitor_.rst_stream_frame_.byte_offset);
+ EXPECT_EQ(kStreamOffset, visitor_.rst_stream_frame_.byte_offset);
// Now test framing boundaries.
for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetRstStreamFrameSize();
@@ -2406,7 +2571,8 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_RST_STREAM_DATA);
}
}
@@ -2466,7 +2632,8 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA);
}
}
@@ -2508,7 +2675,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
- EXPECT_EQ(UINT64_C(0x01020304), visitor_.goaway_frame_.last_good_stream_id);
+ EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
EXPECT_EQ(0x9, visitor_.goaway_frame_.error_code);
EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
@@ -2519,8 +2686,8 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
string expected_error;
if (i < kQuicFrameTypeSize + kQuicErrorCodeSize) {
expected_error = "Unable to read go away error code.";
- } else if (i < kQuicFrameTypeSize + kQuicErrorCodeSize +
- kQuicMaxStreamIdSize) {
+ } else if (i <
+ kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicMaxStreamIdSize) {
expected_error = "Unable to read last good stream id.";
} else {
expected_error = "Unable to read goaway reason.";
@@ -2528,7 +2695,8 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_GOAWAY_DATA);
}
}
@@ -2552,8 +2720,8 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
// stream id
0x04, 0x03, 0x02, 0x01,
// byte offset
- 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c,
+ 0x54, 0x76, 0x10, 0x32,
+ 0xDC, 0xFE, 0x98, 0xBA,
};
// clang-format on
@@ -2565,9 +2733,8 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
- EXPECT_EQ(UINT64_C(0x01020304), visitor_.window_update_frame_.stream_id);
- EXPECT_EQ(UINT64_C(0x0c0b0a0908070605),
- visitor_.window_update_frame_.byte_offset);
+ EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
+ EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.byte_offset);
// Now test framing boundaries.
for (size_t i = kQuicFrameTypeSize;
@@ -2581,7 +2748,8 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA);
}
}
@@ -2615,7 +2783,7 @@ TEST_P(QuicFramerTest, BlockedFrame) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
- EXPECT_EQ(UINT64_C(0x01020304), visitor_.blocked_frame_.stream_id);
+ EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
// Now test framing boundaries.
for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetBlockedFrameSize();
@@ -2624,7 +2792,8 @@ TEST_P(QuicFramerTest, BlockedFrame) {
CheckProcessingFails(
packet,
i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ !kIncludePathId, PACKET_6BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
expected_error, QUIC_INVALID_BLOCKED_DATA);
}
}
@@ -2693,16 +2862,15 @@ TEST_P(QuicFramerTest, PublicResetPacket) {
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
ASSERT_TRUE(visitor_.public_reset_packet_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
+ EXPECT_EQ(kConnectionId,
visitor_.public_reset_packet_->public_header.connection_id);
EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
- EXPECT_EQ(UINT64_C(0xABCDEF0123456789),
- visitor_.public_reset_packet_->nonce_proof);
- EXPECT_EQ(UINT64_C(0x123456789ABC),
+ EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+ EXPECT_EQ(kPacketNumber,
visitor_.public_reset_packet_->rejected_packet_number);
- EXPECT_TRUE(
- visitor_.public_reset_packet_->client_address.address().empty());
+ EXPECT_EQ(ADDRESS_FAMILY_UNSPECIFIED,
+ visitor_.public_reset_packet_->client_address.GetFamily());
// Now test framing boundaries.
for (size_t i = 0; i < arraysize(packet); ++i) {
@@ -2801,17 +2969,16 @@ TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
ASSERT_TRUE(visitor_.public_reset_packet_.get());
- EXPECT_EQ(UINT64_C(0xFEDCBA9876543210),
+ EXPECT_EQ(kConnectionId,
visitor_.public_reset_packet_->public_header.connection_id);
EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
- EXPECT_EQ(UINT64_C(0xABCDEF0123456789),
- visitor_.public_reset_packet_->nonce_proof);
- EXPECT_EQ(UINT64_C(0x123456789ABC),
+ EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+ EXPECT_EQ(kPacketNumber,
visitor_.public_reset_packet_->rejected_packet_number);
EXPECT_EQ("4.31.198.44",
- IPAddressToString(visitor_.public_reset_packet_->
- client_address.address()));
+ IPAddressToString(
+ visitor_.public_reset_packet_->client_address.address()));
EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port());
// Now test framing boundaries.
@@ -2906,25 +3073,23 @@ TEST_P(QuicFramerTest, FecPacket) {
EXPECT_EQ(0u, visitor_.stream_frames_.size());
EXPECT_EQ(0u, visitor_.ack_frames_.size());
ASSERT_EQ(1, visitor_.fec_count_);
- const QuicFecData& fec_data = *visitor_.fec_data_[0];
- EXPECT_EQ(UINT64_C(0x0123456789ABB), fec_data.fec_group);
- EXPECT_EQ("abcdefghijklmnop", fec_data.redundancy);
+ EXPECT_EQ("abcdefghijklmnop", visitor_.fec_data_redundancy_[0]);
}
TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = false;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -2945,35 +3110,34 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
};
// clang-format on
- uint64 header_size =
- GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size = GetPacketHeaderSize(
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
+ PACKET_6BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet),
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
arraysize(packet));
}
TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = false;
header.public_header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -2993,35 +3157,34 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
};
// clang-format on
- uint64 header_size =
- GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_4BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size = GetPacketHeaderSize(
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
+ PACKET_4BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet),
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
arraysize(packet));
}
TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = false;
header.public_header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -3041,35 +3204,34 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
};
// clang-format on
- uint64 header_size =
- GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_2BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size = GetPacketHeaderSize(
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
+ PACKET_2BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet),
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
arraysize(packet));
}
TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = false;
header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicPaddingFrame padding_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&padding_frame));
+ frames.push_back(QuicFrame(padding_frame));
// clang-format off
unsigned char packet[kMaxPacketSize] = {
@@ -3089,31 +3251,30 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
};
// clang-format on
- uint64 header_size =
- GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
+ uint64_t header_size = GetPacketHeaderSize(
+ PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId,
+ PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP);
memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet),
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
arraysize(packet));
}
TEST_P(QuicFramerTest, BuildStreamFramePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x77123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
- QuicStreamFrame stream_frame(0x01020304, true, UINT64_C(0xBA98FEDC32107654),
+ QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
StringPiece("hello world!"));
QuicFrames frames;
@@ -3149,23 +3310,23 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildStreamFramePacketInFecGroup) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x77123456789ABC);
+ header.packet_number = kPacketNumber;
header.is_in_fec_group = IN_FEC_GROUP;
- header.fec_group = UINT64_C(0x77123456789ABC);
+ header.fec_group = kPacketNumber;
- QuicStreamFrame stream_frame(0x01020304, true, UINT64_C(0xBA98FEDC32107654),
+ QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
StringPiece("hello world!"));
QuicFrames frames;
@@ -3198,22 +3359,22 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketInFecGroup) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = true;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x77123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
- QuicStreamFrame stream_frame(0x01020304, true, UINT64_C(0xBA98FEDC32107654),
+ QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
StringPiece("hello world!"));
QuicFrames frames;
@@ -3224,58 +3385,22 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
// public flags (version, 8 byte connection_id)
0x3D,
// connection_id
- 0x10,
- 0x32,
- 0x54,
- 0x76,
- 0x98,
- 0xBA,
- 0xDC,
- 0xFE,
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// version tag
- 'Q',
- '0',
- GetQuicVersionDigitTens(),
- GetQuicVersionDigitOnes(),
+ 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
// packet number
- 0xBC,
- 0x9A,
- 0x78,
- 0x56,
- 0x34,
- 0x12,
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
// private flags (entropy)
0x01,
// frame type (stream frame with fin and no length)
0xDF,
// stream id
- 0x04,
- 0x03,
- 0x02,
- 0x01,
+ 0x04, 0x03, 0x02, 0x01,
// offset
- 0x54,
- 0x76,
- 0x10,
- 0x32,
- 0xDC,
- 0xFE,
- 0x98,
- 0xBA,
+ 0x54, 0x76, 0x10, 0x32, 0xDC, 0xFE, 0x98, 0xBA,
// data
- 'h',
- 'e',
- 'l',
- 'l',
- 'o',
- ' ',
- 'w',
- 'o',
- 'r',
- 'l',
- 'd',
- '!',
+ 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
};
// clang-format on
@@ -3283,43 +3408,139 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
- QuicPacketPublicHeader header;
- header.connection_id = UINT64_C(0xFEDCBA9876543210);
- header.reset_flag = false;
- header.version_flag = true;
+TEST_P(QuicFramerTest, BuildStreamFramePacketWithMultipathFlag) {
+ QuicPacketHeader header;
+ header.public_header.connection_id = kConnectionId;
+ header.public_header.multipath_flag = true;
+ header.public_header.reset_flag = false;
+ header.public_header.version_flag = false;
+ header.fec_flag = false;
+ header.entropy_flag = true;
+ header.path_id = kPathId;
+ header.packet_number = kPacketNumber;
+ header.fec_group = 0;
+
+ QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+ StringPiece("hello world!"));
+
+ QuicFrames frames;
+ frames.push_back(QuicFrame(&stream_frame));
+
+ // clang-format off
+ unsigned char packet[] = {
+ // public flags (8 byte connection_id)
+ 0x7C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76,
+ 0x98, 0xBA, 0xDC, 0xFE,
+ // path_id
+ 0x42,
+ // packet number
+ 0xBC, 0x9A, 0x78, 0x56,
+ 0x34, 0x12,
+ // private flags (entropy)
+ 0x01,
+
+ // frame type (stream frame with fin and no length)
+ 0xDF,
+ // stream id
+ 0x04, 0x03, 0x02, 0x01,
+ // offset
+ 0x54, 0x76, 0x10, 0x32,
+ 0xDC, 0xFE, 0x98, 0xBA,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
+ };
+ // clang-format on
+
+ scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacketWithBothVersionAndMultipathFlag) {
+ QuicPacketHeader header;
+ header.public_header.connection_id = kConnectionId;
+ header.public_header.multipath_flag = true;
+ header.public_header.reset_flag = false;
+ header.public_header.version_flag = true;
+ header.fec_flag = false;
+ header.entropy_flag = true;
+ header.path_id = kPathId;
+ header.packet_number = kPacketNumber;
+ header.fec_group = 0;
+
+ QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+ StringPiece("hello world!"));
+
+ QuicFrames frames;
+ frames.push_back(QuicFrame(&stream_frame));
// clang-format off
unsigned char packet[] = {
+ // public flags (8 byte connection_id)
+ 0x7D,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76,
+ 0x98, 0xBA, 0xDC, 0xFE,
+ // version tag
+ 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ // path_id
+ 0x42,
+ // packet number
+ 0xBC, 0x9A, 0x78, 0x56,
+ 0x34, 0x12,
+ // private flags (entropy)
+ 0x01,
+
+ // frame type (stream frame with fin and no length)
+ 0xDF,
+ // stream id
+ 0x04, 0x03, 0x02, 0x01,
+ // offset
+ 0x54, 0x76, 0x10, 0x32,
+ 0xDC, 0xFE, 0x98, 0xBA,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
+ };
+ // clang-format on
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
+}
+
+TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
+ // clang-format off
+ unsigned char packet[] = {
// public flags (version, 8 byte connection_id)
0x0D,
// connection_id
- 0x10,
- 0x32,
- 0x54,
- 0x76,
- 0x98,
- 0xBA,
- 0xDC,
- 0xFE,
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// version tag
- 'Q',
- '0',
- GetQuicVersionDigitTens(),
- GetQuicVersionDigitOnes(),
+ 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
};
// clang-format on
- QuicVersionVector versions;
- versions.push_back(GetParam());
- scoped_ptr<QuicEncryptedPacket> data(
- framer_.BuildVersionNegotiationPacket(header, versions));
-
+ QuicConnectionId connection_id = kConnectionId;
+ scoped_ptr<QuicEncryptedPacket> data(framer_.BuildVersionNegotiationPacket(
+ connection_id, SupportedVersions(GetParam())));
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
arraysize(packet));
@@ -3327,19 +3548,19 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
TEST_P(QuicFramerTest, BuildAckFramePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x770123456789AA8);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicAckFrame ack_frame;
ack_frame.entropy_hash = 0x43;
- ack_frame.largest_observed = UINT64_C(0x770123456789ABF);
+ ack_frame.largest_observed = kLargestObserved;
ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
- ack_frame.missing_packets.Add(UINT64_C(0x770123456789ABE));
+ ack_frame.missing_packets.Add(kMissingPacket);
QuicFrames frames;
frames.push_back(QuicFrame(&ack_frame));
@@ -3351,7 +3572,7 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) {
// connection_id
0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// packet number
- 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
// private flags (entropy)
0x01,
@@ -3380,9 +3601,9 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
// TODO(jri): Add test for tuncated packets in which the original ack frame had
@@ -3390,12 +3611,12 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) {
TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x770123456789AA8);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicAckFrame ack_frame;
@@ -3419,7 +3640,7 @@ TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) {
// connection_id
0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// packet number
- 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
// private flags (entropy)
0x01,
@@ -3494,19 +3715,19 @@ TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x770123456789AA8);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicAckFrame ack_frame;
@@ -3530,7 +3751,7 @@ TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) {
// connection_id
0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// packet number
- 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
// private flags (entropy)
0x01,
@@ -3559,24 +3780,24 @@ TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) {
ASSERT_TRUE(data != nullptr);
// Expect 1 byte unused since at least 2 bytes are needed to fit more nacks.
EXPECT_EQ(36u, data->length());
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildStopWaitingPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x770123456789AA8);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicStopWaitingFrame stop_waiting_frame;
stop_waiting_frame.entropy_hash = 0x14;
- stop_waiting_frame.least_unacked = UINT64_C(0x770123456789AA0);
+ stop_waiting_frame.least_unacked = kLeastUnacked;
QuicFrames frames;
frames.push_back(QuicFrame(&stop_waiting_frame));
@@ -3589,8 +3810,7 @@ TEST_P(QuicFramerTest, BuildStopWaitingPacket) {
0x10, 0x32, 0x54, 0x76,
0x98, 0xBA, 0xDC, 0xFE,
// packet number
- 0xA8, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
// private flags (entropy)
0x01,
@@ -3599,7 +3819,7 @@ TEST_P(QuicFramerTest, BuildStopWaitingPacket) {
// entropy hash of sent packets till least awaiting - 1.
0x14,
// least packet number awaiting an ack, delta from packet number.
- 0x08, 0x00, 0x00, 0x00,
+ 0x1C, 0x00, 0x00, 0x00,
0x00, 0x00,
};
// clang-format on
@@ -3607,92 +3827,23 @@ TEST_P(QuicFramerTest, BuildStopWaitingPacket) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
-}
-
-TEST_P(QuicFramerTest, BuildRstFramePacketQuicVersion24) {
- if (version_ > QUIC_VERSION_24) {
- // QUIC_VERSION_25 removes the error_details field from QuicRstStreamFrame.
- return;
- }
-
- QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
- header.public_header.reset_flag = false;
- header.public_header.version_flag = false;
- header.fec_flag = false;
- header.entropy_flag = false;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
- header.fec_group = 0;
-
- QuicRstStreamFrame rst_frame;
- rst_frame.stream_id = 0x01020304;
- rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
- rst_frame.error_details = "because I can";
- rst_frame.byte_offset = 0x0807060504030201;
-
- // clang-format off
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (rst stream frame)
- 0x01,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
- // sent byte offset
- 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08,
- // error code
- 0x08, 0x07, 0x06, 0x05,
- // error details length
- 0x0d, 0x00,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
- // clang-format on
-
- QuicFrames frames;
- frames.push_back(QuicFrame(&rst_frame));
-
- scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
- ASSERT_TRUE(data != nullptr);
-
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
arraysize(packet));
}
TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
- if (version_ <= QUIC_VERSION_24) {
- // QUIC_VERSION_25 removes the error_details field from QuicRstStreamFrame.
- return;
- }
-
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = false;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicRstStreamFrame rst_frame;
- rst_frame.stream_id = 0x01020304;
+ rst_frame.stream_id = kStreamId;
rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
rst_frame.byte_offset = 0x0807060504030201;
@@ -3734,12 +3885,12 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
TEST_P(QuicFramerTest, BuildCloseFramePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicConnectionCloseFrame close_frame;
@@ -3779,24 +3930,24 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildGoAwayPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicGoAwayFrame goaway_frame;
goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
- goaway_frame.last_good_stream_id = 0x01020304;
+ goaway_frame.last_good_stream_id = kStreamId;
goaway_frame.reason_phrase = "because I can";
QuicFrames frames;
@@ -3834,23 +3985,23 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicWindowUpdateFrame window_update_frame;
- window_update_frame.stream_id = 0x01020304;
+ window_update_frame.stream_id = kStreamId;
window_update_frame.byte_offset = 0x1122334455667788;
QuicFrames frames;
@@ -3889,16 +4040,16 @@ TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
TEST_P(QuicFramerTest, BuildBlockedPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicBlockedFrame blocked_frame;
- blocked_frame.stream_id = 0x01020304;
+ blocked_frame.stream_id = kStreamId;
QuicFrames frames;
frames.push_back(QuicFrame(&blocked_frame));
@@ -3933,18 +4084,18 @@ TEST_P(QuicFramerTest, BuildBlockedPacket) {
TEST_P(QuicFramerTest, BuildPingPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicPingFrame ping_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&ping_frame));
+ frames.push_back(QuicFrame(ping_frame));
// clang-format off
unsigned char packet[] = {
@@ -3975,18 +4126,18 @@ TEST_P(QuicFramerTest, BuildPingPacket) {
// Test that the MTU discovery packet is serialized correctly as a PING packet.
TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicMtuDiscoveryFrame mtu_discovery_frame;
QuicFrames frames;
- frames.push_back(QuicFrame(&mtu_discovery_frame));
+ frames.push_back(QuicFrame(mtu_discovery_frame));
// clang-format off
unsigned char packet[] = {
@@ -4016,11 +4167,11 @@ TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
TEST_P(QuicFramerTest, BuildPublicResetPacket) {
QuicPublicResetPacket reset_packet;
- reset_packet.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ reset_packet.public_header.connection_id = kConnectionId;
reset_packet.public_header.reset_flag = true;
reset_packet.public_header.version_flag = false;
- reset_packet.rejected_packet_number = UINT64_C(0x123456789ABC);
- reset_packet.nonce_proof = UINT64_C(0xABCDEF0123456789);
+ reset_packet.rejected_packet_number = kPacketNumber;
+ reset_packet.nonce_proof = kNonceProof;
// clang-format off
unsigned char packet[] = {
@@ -4054,18 +4205,18 @@ TEST_P(QuicFramerTest, BuildPublicResetPacket) {
framer_.BuildPublicResetPacket(reset_packet));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
QuicPublicResetPacket reset_packet;
- reset_packet.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ reset_packet.public_header.connection_id = kConnectionId;
reset_packet.public_header.reset_flag = true;
reset_packet.public_header.version_flag = false;
- reset_packet.rejected_packet_number = UINT64_C(0x123456789ABC);
- reset_packet.nonce_proof = UINT64_C(0xABCDEF0123456789);
+ reset_packet.rejected_packet_number = kPacketNumber;
+ reset_packet.nonce_proof = kNonceProof;
reset_packet.client_address = IPEndPoint(Loopback4(), 0x1234);
// clang-format off
@@ -4108,25 +4259,23 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
framer_.BuildPublicResetPacket(reset_packet));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildFecPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = true;
header.entropy_flag = true;
- header.packet_packet_number = (UINT64_C(0x123456789ABC));
+ header.packet_number = kPacketNumber;
header.is_in_fec_group = IN_FEC_GROUP;
- header.fec_group = UINT64_C(0x123456789ABB);
+ header.fec_group = kPacketNumber - 1;
- QuicFecData fec_data;
- fec_data.fec_group = 1;
- fec_data.redundancy = "abcdefghijklmnop";
+ string redundancy = "abcdefghijklmnop";
// clang-format off
unsigned char packet[] = {
@@ -4151,16 +4300,16 @@ TEST_P(QuicFramerTest, BuildFecPacket) {
};
// clang-format on
- scoped_ptr<QuicPacket> data(framer_.BuildFecPacket(header, fec_data));
+ scoped_ptr<QuicPacket> data(framer_.BuildFecPacket(header, redundancy));
ASSERT_TRUE(data != nullptr);
- test::CompareCharArraysWithHexError("constructed packet",
- data->data(), data->length(),
- AsChars(packet), arraysize(packet));
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, EncryptPacket) {
- QuicPacketNumber packet_number = UINT64_C(0x123456789ABC);
+ QuicPacketNumber packet_number = kPacketNumber;
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -4188,15 +4337,15 @@ TEST_P(QuicFramerTest, EncryptPacket) {
AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID,
!kIncludeVersion, PACKET_6BYTE_PACKET_NUMBER));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize));
+ size_t encrypted_length = framer_.EncryptPayload(
+ ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
- ASSERT_TRUE(encrypted.get() != nullptr);
+ ASSERT_NE(0u, encrypted_length);
EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
}
TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
- QuicPacketNumber packet_number = UINT64_C(0x123456789ABC);
+ QuicPacketNumber packet_number = kPacketNumber;
// clang-format off
unsigned char packet[] = {
// public flags (version, 8 byte connection_id)
@@ -4226,21 +4375,21 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID,
kIncludeVersion, PACKET_6BYTE_PACKET_NUMBER));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize));
+ size_t encrypted_length = framer_.EncryptPayload(
+ ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
- ASSERT_TRUE(encrypted.get() != nullptr);
+ ASSERT_NE(0u, encrypted_length);
EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
}
TEST_P(QuicFramerTest, AckTruncationLargePacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = false;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
// Create a packet with just the ack.
@@ -4255,11 +4404,13 @@ TEST_P(QuicFramerTest, AckTruncationLargePacket) {
scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
ASSERT_TRUE(raw_ack_packet != nullptr);
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> ack_packet(
- framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_packet_number,
- *raw_ack_packet, buffer, kMaxPacketSize));
+ size_t encrypted_length =
+ framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_number,
+ *raw_ack_packet, buffer, kMaxPacketSize);
+ ASSERT_NE(0u, encrypted_length);
// Now make sure we can turn our ack packet back into an ack frame.
- ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
+ ASSERT_TRUE(framer_.ProcessPacket(
+ QuicEncryptedPacket(buffer, encrypted_length, false)));
ASSERT_EQ(1u, visitor_.ack_frames_.size());
QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
EXPECT_TRUE(processed_ack_frame.is_truncated);
@@ -4271,12 +4422,12 @@ TEST_P(QuicFramerTest, AckTruncationLargePacket) {
TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = false;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
// Create a packet with just the ack.
@@ -4291,11 +4442,13 @@ TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames, 500));
ASSERT_TRUE(raw_ack_packet != nullptr);
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> ack_packet(
- framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_packet_number,
- *raw_ack_packet, buffer, kMaxPacketSize));
+ size_t encrypted_length =
+ framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_number,
+ *raw_ack_packet, buffer, kMaxPacketSize);
+ ASSERT_NE(0u, encrypted_length);
// Now make sure we can turn our ack packet back into an ack frame.
- ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
+ ASSERT_TRUE(framer_.ProcessPacket(
+ QuicEncryptedPacket(buffer, encrypted_length, false)));
ASSERT_EQ(1u, visitor_.ack_frames_.size());
QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
EXPECT_TRUE(processed_ack_frame.is_truncated);
@@ -4307,12 +4460,12 @@ TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
TEST_P(QuicFramerTest, CleanTruncation) {
QuicPacketHeader header;
- header.public_header.connection_id = UINT64_C(0xFEDCBA9876543210);
+ header.public_header.connection_id = kConnectionId;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_packet_number = UINT64_C(0x123456789ABC);
+ header.packet_number = kPacketNumber;
header.fec_group = 0;
QuicAckFrame ack_frame;
@@ -4330,12 +4483,14 @@ TEST_P(QuicFramerTest, CleanTruncation) {
ASSERT_TRUE(raw_ack_packet != nullptr);
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> ack_packet(
- framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_packet_number,
- *raw_ack_packet, buffer, kMaxPacketSize));
+ size_t encrypted_length =
+ framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_number,
+ *raw_ack_packet, buffer, kMaxPacketSize);
+ ASSERT_NE(0u, encrypted_length);
// Now make sure we can turn our ack packet back into an ack frame.
- ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
+ ASSERT_TRUE(framer_.ProcessPacket(
+ QuicEncryptedPacket(buffer, encrypted_length, false)));
// Test for clean truncation of the ack by comparing the length of the
// original packets to the re-serialized packets.
@@ -4495,7 +4650,8 @@ static char kTestString[] = "At least 20 characters.";
static QuicStreamId kTestQuicStreamId = 1;
static bool ExpectedStreamFrame(const QuicStreamFrame& frame) {
return frame.stream_id == kTestQuicStreamId && !frame.fin &&
- frame.offset == 0 && frame.data == kTestString;
+ frame.offset == 0 &&
+ string(frame.frame_buffer, frame.frame_length) == kTestString;
// FIN is hard-coded false in ConstructEncryptedPacket.
// Offset 0 is hard-coded in ConstructEncryptedPacket.
}
@@ -4565,5 +4721,66 @@ TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error());
}
+// Tests for fuzzing with Dr. Fuzz
+// Xref http://www.chromium.org/developers/testing/dr-fuzz for more details.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// target function to be fuzzed by Dr. Fuzz
+void QuicFramerFuzzFunc(unsigned char* data, size_t size) {
+ QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(),
+ Perspective::IS_SERVER);
+ const char* const packet_bytes = reinterpret_cast<const char*>(data);
+
+ // Test the CryptoFramer.
+ StringPiece crypto_input(packet_bytes, size);
+ std::unique_ptr<CryptoHandshakeMessage> handshake_message(
+ CryptoFramer::ParseMessage(crypto_input));
+
+ // Test the regular QuicFramer with the same input.
+ NoOpFramerVisitor visitor;
+ framer.set_visitor(&visitor);
+ QuicEncryptedPacket packet(packet_bytes, size);
+ framer.ProcessPacket(packet);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+TEST_P(QuicFramerTest, FramerFuzzTest) {
+ // clang-format off
+ unsigned char packet[] = {
+ // public flags (8 byte connection_id)
+ 0x3C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76,
+ 0x98, 0xBA, 0xDC, 0xFE,
+ // packet number
+ 0xBC, 0x9A, 0x78, 0x56,
+ 0x34, 0x12,
+ // private flags
+ 0x00,
+
+ // frame type (stream frame with fin)
+ 0xFF,
+ // stream id
+ 0x04, 0x03, 0x02, 0x01,
+ // offset
+ 0x54, 0x76, 0x10, 0x32,
+ 0xDC, 0xFE, 0x98, 0xBA,
+ // data length
+ 0x0c, 0x00,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
+ };
+ // clang-format on
+
+ QuicFramerFuzzFunc(packet, arraysize(packet));
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_headers_stream.cc b/chromium/net/quic/quic_headers_stream.cc
index 584b87e57ad..abcaa719448 100644
--- a/chromium/net/quic/quic_headers_stream.cc
+++ b/chromium/net/quic/quic_headers_stream.cc
@@ -4,22 +4,24 @@
#include "net/quic/quic_headers_stream.h"
+#include "base/macros.h"
+#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
+#include "net/quic/quic_bug_tracker.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_headers_stream.h"
#include "net/quic/quic_spdy_session.h"
+#include "net/quic/quic_time.h"
using base::StringPiece;
+using net::HTTP2;
+using net::SpdyFrameType;
using std::string;
namespace net {
-namespace {
-
-const QuicStreamId kInvalidStreamId = 0;
-
-} // namespace
-
// A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to
-// the QuicDataStream, and closes the connection if any unexpected frames
+// the QuicSpdyStream, and closes the connection if any unexpected frames
// are received.
class QuicHeadersStream::SpdyFramerVisitor
: public SpdyFramerVisitorInterface,
@@ -67,6 +69,16 @@ class QuicHeadersStream::SpdyFramerVisitor
CloseConnection("SPDY frame padding received.");
}
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override {
+ LOG(FATAL);
+ return nullptr;
+ }
+
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override {
+ LOG(FATAL);
+ }
+
void OnError(SpdyFramer* framer) override {
CloseConnection(base::StringPrintf(
"SPDY framing error: %s",
@@ -84,7 +96,7 @@ class QuicHeadersStream::SpdyFramerVisitor
CloseConnection("SPDY RST_STREAM frame received.");
}
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override {
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {
CloseConnection("SPDY SETTINGS frame received.");
}
@@ -115,11 +127,8 @@ class QuicHeadersStream::SpdyFramerVisitor
if (!stream_->IsConnected()) {
return;
}
- if (has_priority) {
- stream_->OnSynStream(stream_id, priority, fin);
- } else {
- stream_->OnSynReply(stream_id, fin);
- }
+
+ stream_->OnHeaders(stream_id, has_priority, priority, fin);
}
void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {
@@ -129,11 +138,17 @@ class QuicHeadersStream::SpdyFramerVisitor
void OnPushPromise(SpdyStreamId stream_id,
SpdyStreamId promised_stream_id,
bool end) override {
- CloseConnection("SPDY PUSH_PROMISE frame received.");
+ if (!stream_->supports_push_promise()) {
+ CloseConnection("PUSH_PROMISE not supported.");
+ return;
+ }
+ if (!stream_->IsConnected()) {
+ return;
+ }
+ stream_->OnPushPromise(stream_id, promised_stream_id, end);
}
- void OnContinuation(SpdyStreamId stream_id, bool end) override {
- }
+ void OnContinuation(SpdyStreamId stream_id, bool end) override {}
bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override {
CloseConnection("Unknown frame type received.");
@@ -157,8 +172,8 @@ class QuicHeadersStream::SpdyFramerVisitor
private:
void CloseConnection(const string& details) {
if (stream_->IsConnected()) {
- stream_->CloseConnectionWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA, details);
+ stream_->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ details);
}
}
@@ -172,8 +187,15 @@ QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
: ReliableQuicStream(kHeadersStreamId, session),
spdy_session_(session),
stream_id_(kInvalidStreamId),
+ promised_stream_id_(kInvalidStreamId),
fin_(false),
frame_len_(0),
+ measure_headers_hol_blocking_time_(
+ FLAGS_quic_measure_headers_hol_blocking_time),
+ supports_push_promise_(session->perspective() == Perspective::IS_CLIENT &&
+ FLAGS_quic_supports_push_promise),
+ cur_max_timestamp_(QuicTime::Zero()),
+ prev_max_timestamp_(QuicTime::Zero()),
spdy_framer_(HTTP2),
spdy_framer_visitor_(new SpdyFramerVisitor(this)) {
spdy_framer_.set_visitor(spdy_framer_visitor_.get());
@@ -184,12 +206,11 @@ QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
QuicHeadersStream::~QuicHeadersStream() {}
-size_t QuicHeadersStream::WriteHeaders(
- QuicStreamId stream_id,
- const SpdyHeaderBlock& headers,
- bool fin,
- QuicPriority priority,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
+size_t QuicHeadersStream::WriteHeaders(QuicStreamId stream_id,
+ const SpdyHeaderBlock& headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicAckListenerInterface* ack_listener) {
SpdyHeadersIR headers_frame(stream_id);
headers_frame.set_header_block(headers);
headers_frame.set_fin(fin);
@@ -200,19 +221,52 @@ size_t QuicHeadersStream::WriteHeaders(
scoped_ptr<SpdySerializedFrame> frame(
spdy_framer_.SerializeFrame(headers_frame));
WriteOrBufferData(StringPiece(frame->data(), frame->size()), false,
- ack_notifier_delegate);
+ ack_listener);
+ return frame->size();
+}
+
+size_t QuicHeadersStream::WritePushPromise(
+ QuicStreamId original_stream_id,
+ QuicStreamId promised_stream_id,
+ const SpdyHeaderBlock& headers,
+ QuicAckListenerInterface* ack_listener) {
+ if (session()->perspective() == Perspective::IS_CLIENT) {
+ QUIC_BUG << "Client shouldn't send PUSH_PROMISE";
+ return 0;
+ }
+
+ SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id);
+ push_promise.set_header_block(headers);
+ // PUSH_PROMISE must not be the last frame sent out, at least followed by
+ // response headers.
+ push_promise.set_fin(false);
+
+ scoped_ptr<SpdySerializedFrame> frame(
+ spdy_framer_.SerializeFrame(push_promise));
+ WriteOrBufferData(StringPiece(frame->data(), frame->size()), false,
+ ack_listener);
return frame->size();
}
void QuicHeadersStream::OnDataAvailable() {
char buffer[1024];
struct iovec iov;
+ QuicTime timestamp(QuicTime::Zero());
while (true) {
iov.iov_base = buffer;
iov.iov_len = arraysize(buffer);
- if (sequencer()->GetReadableRegions(&iov, 1) != 1) {
- // No more data to read.
- break;
+ if (measure_headers_hol_blocking_time_) {
+ if (!sequencer()->GetReadableRegion(&iov, &timestamp)) {
+ // No more data to read.
+ break;
+ }
+ DCHECK(timestamp.IsInitialized());
+ cur_max_timestamp_ = QuicTime::Max(timestamp, cur_max_timestamp_);
+ } else {
+ if (sequencer()->GetReadableRegions(&iov, 1) != 1) {
+ // No more data to read.
+ break;
+ }
}
if (spdy_framer_.ProcessInput(static_cast<char*>(iov.iov_base),
iov.iov_len) != iov.iov_len) {
@@ -223,33 +277,46 @@ void QuicHeadersStream::OnDataAvailable() {
}
}
-QuicPriority QuicHeadersStream::EffectivePriority() const { return 0; }
+SpdyPriority QuicHeadersStream::Priority() const {
+ return net::kV3HighestPriority;
+}
-void QuicHeadersStream::OnSynStream(SpdyStreamId stream_id,
- SpdyPriority priority,
- bool fin) {
- if (session()->perspective() == Perspective::IS_CLIENT) {
- CloseConnectionWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY SYN_STREAM frame received at the client");
- return;
+void QuicHeadersStream::OnHeaders(SpdyStreamId stream_id,
+ bool has_priority,
+ SpdyPriority priority,
+ bool fin) {
+ if (has_priority) {
+ if (session()->perspective() == Perspective::IS_CLIENT) {
+ CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "Server must not send priorities.");
+ return;
+ }
+ spdy_session_->OnStreamHeadersPriority(stream_id, priority);
+ } else {
+ if (session()->perspective() == Perspective::IS_SERVER) {
+ CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "Client must send priorities.");
+ return;
+ }
}
DCHECK_EQ(kInvalidStreamId, stream_id_);
+ DCHECK_EQ(kInvalidStreamId, promised_stream_id_);
stream_id_ = stream_id;
fin_ = fin;
- spdy_session_->OnStreamHeadersPriority(stream_id, priority);
}
-void QuicHeadersStream::OnSynReply(SpdyStreamId stream_id, bool fin) {
- if (session()->perspective() == Perspective::IS_SERVER) {
- CloseConnectionWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY SYN_REPLY frame received at the server");
+void QuicHeadersStream::OnPushPromise(SpdyStreamId stream_id,
+ SpdyStreamId promised_stream_id,
+ bool end) {
+ if (!supports_push_promise_) {
+ CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "SPDY PUSH_PROMISE not supported.");
return;
}
DCHECK_EQ(kInvalidStreamId, stream_id_);
+ DCHECK_EQ(kInvalidStreamId, promised_stream_id_);
stream_id_ = stream_id;
- fin_ = fin;
+ promised_stream_id_ = promised_stream_id;
}
void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id,
@@ -259,13 +326,39 @@ void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id,
if (len == 0) {
DCHECK_NE(0u, stream_id_);
DCHECK_NE(0u, frame_len_);
- spdy_session_->OnStreamHeadersComplete(stream_id_, fin_, frame_len_);
+ if (measure_headers_hol_blocking_time_) {
+ if (prev_max_timestamp_ > cur_max_timestamp_) {
+ // prev_max_timestamp_ > cur_max_timestamp_ implies that
+ // headers from lower numbered streams actually came off the
+ // wire after headers for the current stream, hence there was
+ // HOL blocking.
+ QuicTime::Delta delta(prev_max_timestamp_.Subtract(cur_max_timestamp_));
+ DVLOG(1) << "stream " << stream_id
+ << ": Net.QuicSession.HeadersHOLBlockedTime "
+ << delta.ToMilliseconds();
+ spdy_session_->OnHeadersHeadOfLineBlocking(delta);
+ }
+ prev_max_timestamp_ = std::max(prev_max_timestamp_, cur_max_timestamp_);
+ cur_max_timestamp_ = QuicTime::Zero();
+ }
+ if (promised_stream_id_ == kInvalidStreamId) {
+ spdy_session_->OnStreamHeadersComplete(stream_id_, fin_, frame_len_);
+ } else {
+ spdy_session_->OnPromiseHeadersComplete(stream_id_, promised_stream_id_,
+ frame_len_);
+ }
// Reset state for the next frame.
+ promised_stream_id_ = kInvalidStreamId;
stream_id_ = kInvalidStreamId;
fin_ = false;
frame_len_ = 0;
} else {
- spdy_session_->OnStreamHeaders(stream_id_, StringPiece(header_data, len));
+ if (promised_stream_id_ == kInvalidStreamId) {
+ spdy_session_->OnStreamHeaders(stream_id_, StringPiece(header_data, len));
+ } else {
+ spdy_session_->OnPromiseHeaders(stream_id_,
+ StringPiece(header_data, len));
+ }
}
}
diff --git a/chromium/net/quic/quic_headers_stream.h b/chromium/net/quic/quic_headers_stream.h
index 52f7399a061..a8b466cd553 100644
--- a/chromium/net/quic/quic_headers_stream.h
+++ b/chromium/net/quic/quic_headers_stream.h
@@ -5,7 +5,9 @@
#ifndef NET_QUIC_QUIC_HEADERS_STREAM_H_
#define NET_QUIC_QUIC_HEADERS_STREAM_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
@@ -16,45 +18,56 @@ namespace net {
class QuicSpdySession;
-// Headers in QUIC are sent as SPDY SYN_STREAM or SYN_REPLY frames
-// over a reserved reliable stream with the id 3. Each endpoint (client
-// and server) will allocate an instance of QuicHeadersStream to send
-// and receive headers.
+// Headers in QUIC are sent as HTTP/2 HEADERS or PUSH_PROMISE frames
+// over a reserved reliable stream with the id 3. Each endpoint
+// (client and server) will allocate an instance of QuicHeadersStream
+// to send and receive headers.
class NET_EXPORT_PRIVATE QuicHeadersStream : public ReliableQuicStream {
public:
explicit QuicHeadersStream(QuicSpdySession* session);
~QuicHeadersStream() override;
- // Writes |headers| for |stream_id| in a SYN_STREAM or SYN_REPLY
- // frame to the peer. If |fin| is true, the fin flag will be set on
- // the SPDY frame. Returns the size, in bytes, of the resulting
- // SPDY frame.
- size_t WriteHeaders(
- QuicStreamId stream_id,
- const SpdyHeaderBlock& headers,
- bool fin,
- QuicPriority priority,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
+ // Writes |headers| for |stream_id| in an HTTP/2 HEADERS frame to the peer.
+ // If |fin| is true, the fin flag will be set on the HEADERS frame. Returns
+ // the size, in bytes, of the resulting HEADERS frame.
+ virtual size_t WriteHeaders(QuicStreamId stream_id,
+ const SpdyHeaderBlock& headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicAckListenerInterface* ack_listener);
+
+ // Write |headers| for |promised_stream_id| on |original_stream_id| in a
+ // PUSH_PROMISE frame to peer.
+ // Return the size, in bytes, of the resulting PUSH_PROMISE frame.
+ virtual size_t WritePushPromise(QuicStreamId original_stream_id,
+ QuicStreamId promised_stream_id,
+ const SpdyHeaderBlock& headers,
+ QuicAckListenerInterface* ack_listener);
// ReliableQuicStream implementation
void OnDataAvailable() override;
- QuicPriority EffectivePriority() const override;
+ SpdyPriority Priority() const override;
+
+ bool supports_push_promise() { return supports_push_promise_; }
private:
class SpdyFramerVisitor;
// The following methods are called by the SimpleVisitor.
- // Called when a SYN_STREAM frame has been received.
- void OnSynStream(SpdyStreamId stream_id,
- SpdyPriority priority,
- bool fin);
+ // Called when a HEADERS frame has been received.
+ void OnHeaders(SpdyStreamId stream_id,
+ bool has_priority,
+ SpdyPriority priority,
+ bool fin);
- // Called when a SYN_REPLY frame been received.
- void OnSynReply(SpdyStreamId stream_id, bool fin);
+ // Called when a PUSH_PROMISE frame has been received.
+ void OnPushPromise(SpdyStreamId stream_id,
+ SpdyStreamId promised_stream_id,
+ bool end);
// Called when a chunk of header data is available. This is called
- // after OnSynStream, or OnSynReply.
+ // after OnHeaders.
// |stream_id| The stream receiving the header data.
// |header_data| A buffer containing the header data chunk received.
// |len| The length of the header data buffer. A length of zero indicates
@@ -73,9 +86,23 @@ class NET_EXPORT_PRIVATE QuicHeadersStream : public ReliableQuicStream {
// Data about the stream whose headers are being processed.
QuicStreamId stream_id_;
+ QuicStreamId promised_stream_id_;
bool fin_;
size_t frame_len_;
+ // Helper variables that cache the corresponding feature flag.
+ bool measure_headers_hol_blocking_time_;
+ bool supports_push_promise_;
+
+ // Timestamps used to measure HOL blocking, these are recorded by
+ // the sequencer approximate to the time of arrival off the wire.
+ // |cur_max_timestamp_| tracks the most recent arrival time of
+ // frames for current (at the headers stream level) processed
+ // stream's headers, and |prev_max_timestamp_| tracks the most
+ // recent arrival time of lower numbered streams.
+ QuicTime cur_max_timestamp_;
+ QuicTime prev_max_timestamp_;
+
SpdyFramer spdy_framer_;
scoped_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
diff --git a/chromium/net/quic/quic_headers_stream_test.cc b/chromium/net/quic/quic_headers_stream_test.cc
index fd566bfbace..2425683a5b4 100644
--- a/chromium/net/quic/quic_headers_stream_test.cc
+++ b/chromium/net/quic/quic_headers_stream_test.cc
@@ -10,14 +10,18 @@
#include "net/quic/test_tools/quic_spdy_session_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/reliable_quic_stream_peer.h"
+#include "net/spdy/spdy_alt_svc_wire_format.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_test_utils.h"
+#include "net/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::StringPiece;
using std::ostream;
using std::string;
using std::vector;
+using testing::ElementsAre;
+using testing::InSequence;
using testing::Invoke;
using testing::StrictMock;
using testing::WithArgs;
@@ -27,35 +31,43 @@ namespace net {
namespace test {
namespace {
+// TODO(ckrasic): this workaround is due to absence of std::initializer_list
+const bool kFins[] = {false, true};
+
class MockVisitor : public SpdyFramerVisitorInterface {
public:
MOCK_METHOD1(OnError, void(SpdyFramer* framer));
- MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId stream_id,
- size_t length,
- bool fin));
- MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId stream_id,
- const char* data,
- size_t len,
- bool fin));
+ MOCK_METHOD3(OnDataFrameHeader,
+ void(SpdyStreamId stream_id, size_t length, bool fin));
+ MOCK_METHOD4(
+ OnStreamFrameData,
+ void(SpdyStreamId stream_id, const char* data, size_t len, bool fin));
MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId stream_id, size_t len));
- MOCK_METHOD3(OnControlFrameHeaderData, bool(SpdyStreamId stream_id,
- const char* header_data,
- size_t len));
- MOCK_METHOD5(OnSynStream, void(SpdyStreamId stream_id,
- SpdyStreamId associated_stream_id,
- SpdyPriority priority,
- bool fin,
- bool unidirectional));
+ MOCK_METHOD1(OnHeaderFrameStart,
+ SpdyHeadersHandlerInterface*(SpdyStreamId stream_id));
+ MOCK_METHOD2(OnHeaderFrameEnd, void(SpdyStreamId stream_id, bool end));
+ MOCK_METHOD3(OnControlFrameHeaderData,
+ bool(SpdyStreamId stream_id,
+ const char* header_data,
+ size_t len));
+ MOCK_METHOD5(OnSynStream,
+ void(SpdyStreamId stream_id,
+ SpdyStreamId associated_stream_id,
+ SpdyPriority priority,
+ bool fin,
+ bool unidirectional));
MOCK_METHOD2(OnSynReply, void(SpdyStreamId stream_id, bool fin));
- MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id,
- SpdyRstStreamStatus status));
+ MOCK_METHOD2(OnRstStream,
+ void(SpdyStreamId stream_id, SpdyRstStreamStatus status));
MOCK_METHOD1(OnSettings, void(bool clear_persisted));
- MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
+ MOCK_METHOD3(OnSetting,
+ void(SpdySettingsIds id, uint8_t flags, uint32_t value));
MOCK_METHOD0(OnSettingsAck, void());
MOCK_METHOD0(OnSettingsEnd, void());
MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
- MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status));
+ MOCK_METHOD2(OnGoAway,
+ void(SpdyStreamId last_accepted_stream_id,
+ SpdyGoAwayStatus status));
MOCK_METHOD7(OnHeaders,
void(SpdyStreamId stream_id,
bool has_priority,
@@ -66,12 +78,11 @@ class MockVisitor : public SpdyFramerVisitorInterface {
bool end));
MOCK_METHOD2(OnWindowUpdate,
void(SpdyStreamId stream_id, int delta_window_size));
- MOCK_METHOD2(OnCredentialFrameData, bool(const char* credential_data,
- size_t len));
MOCK_METHOD1(OnBlocked, void(SpdyStreamId stream_id));
- MOCK_METHOD3(OnPushPromise, void(SpdyStreamId stream_id,
- SpdyStreamId promised_stream_id,
- bool end));
+ MOCK_METHOD3(OnPushPromise,
+ void(SpdyStreamId stream_id,
+ SpdyStreamId promised_stream_id,
+ bool end));
MOCK_METHOD2(OnContinuation, void(SpdyStreamId stream_id, bool end));
MOCK_METHOD3(OnAltSvc,
void(SpdyStreamId stream_id,
@@ -104,32 +115,37 @@ vector<TestParams> GetTestParams() {
params.push_back(TestParams(version, Perspective::IS_CLIENT));
params.push_back(TestParams(version, Perspective::IS_SERVER));
}
+ FLAGS_quic_supports_push_promise = true;
return params;
}
class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
public:
QuicHeadersStreamTest()
- : connection_(
- new StrictMock<MockConnection>(perspective(), GetVersion())),
+ : connection_(new StrictMock<MockConnection>(&helper_,
+ perspective(),
+ GetVersion())),
session_(connection_),
headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)),
body_("hello world"),
framer_(HTTP2),
- stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, "") {
- headers_[":version"] = "HTTP/1.1";
+ stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""),
+ next_promised_stream_id_(2) {
+ FLAGS_quic_always_log_bugs_for_tests = true;
+ headers_[":version"] = "HTTP/1.1";
headers_[":status"] = "200 Ok";
headers_["content-length"] = "11";
framer_.set_visitor(&visitor_);
EXPECT_EQ(version(), session_.connection()->version());
EXPECT_TRUE(headers_stream_ != nullptr);
VLOG(1) << GetParam();
+ connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
}
QuicConsumedData SaveIov(const QuicIOVector& data) {
const iovec* iov = data.iov;
int count = data.iov_count;
- for (int i = 0 ; i < count; ++i) {
+ for (int i = 0; i < count; ++i) {
saved_data_.append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len);
}
return QuicConsumedData(saved_data_.length(), false);
@@ -146,18 +162,17 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
void WriteHeadersAndExpectSynStream(QuicStreamId stream_id,
bool fin,
- QuicPriority priority) {
+ SpdyPriority priority) {
WriteHeadersAndCheckData(stream_id, fin, priority, SYN_STREAM);
}
- void WriteHeadersAndExpectSynReply(QuicStreamId stream_id,
- bool fin) {
+ void WriteHeadersAndExpectSynReply(QuicStreamId stream_id, bool fin) {
WriteHeadersAndCheckData(stream_id, fin, 0, SYN_REPLY);
}
void WriteHeadersAndCheckData(QuicStreamId stream_id,
bool fin,
- QuicPriority priority,
+ SpdyPriority priority,
SpdyFrameType type) {
// Write the headers and capture the outgoing data
EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, _, false, _, nullptr))
@@ -166,11 +181,10 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
// Parse the outgoing data and check that it matches was was written.
if (type == SYN_STREAM) {
- EXPECT_CALL(visitor_, OnHeaders(stream_id, kHasPriority, priority,
- /*parent_stream_id=*/0,
- /*exclusive=*/false,
-
- fin, kFrameComplete));
+ EXPECT_CALL(visitor_,
+ OnHeaders(stream_id, kHasPriority, priority,
+ /*parent_stream_id=*/0,
+ /*exclusive=*/false, fin, kFrameComplete));
} else {
EXPECT_CALL(visitor_,
OnHeaders(stream_id, !kHasPriority,
@@ -194,11 +208,9 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
void CheckHeaders() {
SpdyHeaderBlock headers;
- EXPECT_EQ(saved_header_data_.length(),
- framer_.ParseHeaderBlockInBuffer(saved_header_data_.data(),
- saved_header_data_.length(),
- &headers));
- EXPECT_TRUE(CompareSpdyHeaderBlocks(headers_, headers));
+ EXPECT_TRUE(framer_.ParseHeaderBlockInBuffer(
+ saved_header_data_.data(), saved_header_data_.length(), &headers));
+ EXPECT_EQ(headers_, headers);
saved_header_data_.clear();
}
@@ -212,13 +224,14 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
return versions;
}
- void CloseConnection() {
- QuicConnectionPeer::CloseConnection(connection_);
- }
+ void CloseConnection() { QuicConnectionPeer::CloseConnection(connection_); }
+
+ QuicStreamId NextPromisedStreamId() { return next_promised_stream_id_ += 2; }
static const bool kFrameComplete = true;
static const bool kHasPriority = true;
+ MockConnectionHelper helper_;
StrictMock<MockConnection>* connection_;
StrictMock<MockQuicSpdySession> session_;
QuicHeadersStream* headers_stream_;
@@ -229,6 +242,7 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
SpdyFramer framer_;
StrictMock<MockVisitor> visitor_;
QuicStreamFrame stream_frame_;
+ QuicStreamId next_promised_stream_id_;
};
INSTANTIATE_TEST_CASE_P(Tests,
@@ -239,19 +253,18 @@ TEST_P(QuicHeadersStreamTest, StreamId) {
EXPECT_EQ(3u, headers_stream_->id());
}
-TEST_P(QuicHeadersStreamTest, EffectivePriority) {
- EXPECT_EQ(0u, headers_stream_->EffectivePriority());
+TEST_P(QuicHeadersStreamTest, Priority) {
+ EXPECT_EQ(0u, headers_stream_->Priority());
}
TEST_P(QuicHeadersStreamTest, WriteHeaders) {
for (QuicStreamId stream_id = kClientDataStreamId1;
stream_id < kClientDataStreamId3; stream_id += 2) {
- for (int count = 0; count < 2; ++count) {
- bool fin = (count == 0);
+ for (bool fin : kFins) {
if (perspective() == Perspective::IS_SERVER) {
WriteHeadersAndExpectSynReply(stream_id, fin);
} else {
- for (QuicPriority priority = 0; priority < 7; ++priority) {
+ for (SpdyPriority priority = 0; priority < 7; ++priority) {
// TODO(rch): implement priorities correctly.
WriteHeadersAndExpectSynStream(stream_id, fin, 0);
}
@@ -260,12 +273,42 @@ TEST_P(QuicHeadersStreamTest, WriteHeaders) {
}
}
+TEST_P(QuicHeadersStreamTest, WritePushPromises) {
+ for (QuicStreamId stream_id = kClientDataStreamId1;
+ stream_id < kClientDataStreamId3; stream_id += 2) {
+ QuicStreamId promised_stream_id = NextPromisedStreamId();
+ if (perspective() == Perspective::IS_SERVER) {
+ // Write the headers and capture the outgoing data
+ EXPECT_CALL(session_,
+ WritevData(kHeadersStreamId, _, _, false, _, nullptr))
+ .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
+ headers_stream_->WritePushPromise(stream_id, promised_stream_id, headers_,
+ nullptr);
+
+ // Parse the outgoing data and check that it matches was was written.
+ EXPECT_CALL(visitor_,
+ OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
+ EXPECT_CALL(visitor_, OnControlFrameHeaderData(stream_id, _, _))
+ .WillRepeatedly(WithArgs<1, 2>(
+ Invoke(this, &QuicHeadersStreamTest::SaveHeaderData)));
+ framer_.ProcessInput(saved_data_.data(), saved_data_.length());
+ EXPECT_FALSE(framer_.HasError())
+ << SpdyFramer::ErrorCodeToString(framer_.error_code());
+ CheckHeaders();
+ saved_data_.clear();
+ } else {
+ EXPECT_DFATAL(headers_stream_->WritePushPromise(
+ stream_id, promised_stream_id, headers_, nullptr),
+ "Client shouldn't send PUSH_PROMISE");
+ }
+ }
+}
+
TEST_P(QuicHeadersStreamTest, ProcessRawData) {
for (QuicStreamId stream_id = kClientDataStreamId1;
stream_id < kClientDataStreamId3; stream_id += 2) {
- for (int count = 0; count < 2; ++count) {
- bool fin = (count == 0);
- for (QuicPriority priority = 0; priority < 7; ++priority) {
+ for (bool fin : {false, true}) {
+ for (SpdyPriority priority = 0; priority < 7; ++priority) {
// Replace with "WriteHeadersAndSaveData"
scoped_ptr<SpdySerializedFrame> frame;
if (perspective() == Perspective::IS_SERVER) {
@@ -282,12 +325,12 @@ TEST_P(QuicHeadersStreamTest, ProcessRawData) {
frame.reset(framer_.SerializeFrame(headers_frame));
}
EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
- .WillRepeatedly(WithArgs<1>(
- Invoke(this,
- &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
+ .WillRepeatedly(WithArgs<1>(Invoke(
+ this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
EXPECT_CALL(session_,
OnStreamHeadersComplete(stream_id, fin, frame->size()));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
stream_frame_.offset += frame->size();
CheckHeaders();
@@ -296,6 +339,161 @@ TEST_P(QuicHeadersStreamTest, ProcessRawData) {
}
}
+TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
+ if (perspective() == Perspective::IS_SERVER)
+ return;
+ for (QuicStreamId stream_id = kClientDataStreamId1;
+ stream_id < kClientDataStreamId3; stream_id += 2) {
+ QuicStreamId promised_stream_id = NextPromisedStreamId();
+ scoped_ptr<SpdySerializedFrame> frame;
+ SpdyPushPromiseIR push_promise(stream_id, promised_stream_id);
+ push_promise.set_header_block(headers_);
+ frame.reset(framer_.SerializeFrame(push_promise));
+ if (perspective() == Perspective::IS_SERVER) {
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_HEADERS_STREAM_DATA,
+ "PUSH_PROMISE not supported."))
+ .WillRepeatedly(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ } else {
+ EXPECT_CALL(session_, OnPromiseHeaders(stream_id, _))
+ .WillRepeatedly(WithArgs<1>(
+ Invoke(this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
+ EXPECT_CALL(session_, OnPromiseHeadersComplete(
+ stream_id, promised_stream_id, frame->size()));
+ }
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
+ headers_stream_->OnStreamFrame(stream_frame_);
+ if (perspective() == Perspective::IS_CLIENT) {
+ stream_frame_.offset += frame->size();
+ CheckHeaders();
+ }
+ }
+}
+
+TEST_P(QuicHeadersStreamTest, PushPromiseOutOfOrder) {
+ if (perspective() == Perspective::IS_SERVER)
+ return;
+
+ QuicStreamId promised_stream_id = NextPromisedStreamId();
+ QuicStreamId stream_id = kClientDataStreamId1;
+
+ scoped_ptr<SpdySerializedFrame> frame;
+ SpdyPushPromiseIR push_promise(stream_id, promised_stream_id);
+ push_promise.set_header_block(headers_);
+ frame.reset(framer_.SerializeFrame(push_promise));
+ EXPECT_CALL(session_, OnPromiseHeaders(stream_id, _))
+ .WillRepeatedly(WithArgs<1>(
+ Invoke(this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
+ EXPECT_CALL(session_, OnPromiseHeadersComplete(stream_id, promised_stream_id,
+ frame->size()));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
+ headers_stream_->OnStreamFrame(stream_frame_);
+ if (perspective() == Perspective::IS_CLIENT) {
+ stream_frame_.offset += frame->size();
+ CheckHeaders();
+ }
+
+ stream_id += 2;
+ push_promise.set_stream_id(stream_id);
+ frame.reset(framer_.SerializeFrame(push_promise));
+ EXPECT_CALL(session_, OnPromiseHeaders(stream_id, _))
+ .WillRepeatedly(WithArgs<1>(
+ Invoke(this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
+ EXPECT_CALL(session_, OnPromiseHeadersComplete(stream_id, promised_stream_id,
+ frame->size()));
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_STREAM_ID,
+ "Received push stream id lesser or equal to the"
+ " last accepted before"))
+ .WillRepeatedly(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
+ headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, EmptyHeaderHOLBlockedTime) {
+ EXPECT_CALL(session_, OnHeadersHeadOfLineBlocking(_)).Times(0);
+ testing::InSequence seq;
+ bool fin = true;
+ for (int stream_num = 0; stream_num < 10; stream_num++) {
+ QuicStreamId stream_id = QuicClientDataStreamId(stream_num);
+ // Replace with "WriteHeadersAndSaveData"
+ scoped_ptr<SpdySerializedFrame> frame;
+ if (perspective() == Perspective::IS_SERVER) {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ headers_frame.set_has_priority(true);
+ frame.reset(framer_.SerializeFrame(headers_frame));
+ EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
+ } else {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ frame.reset(framer_.SerializeFrame(headers_frame));
+ }
+ EXPECT_CALL(session_, OnStreamHeaders(stream_id, _));
+ EXPECT_CALL(session_,
+ OnStreamHeadersComplete(stream_id, fin, frame->size()));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
+ headers_stream_->OnStreamFrame(stream_frame_);
+ connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+ stream_frame_.offset += frame->size();
+ }
+}
+
+TEST_P(QuicHeadersStreamTest, NonEmptyHeaderHOLBlockedTime) {
+ QuicStreamId stream_id;
+ bool fin = true;
+ QuicStreamFrame stream_frames[10];
+ scoped_ptr<SpdySerializedFrame> frames[10];
+ // First create all the frames in order
+ {
+ InSequence seq;
+ for (int stream_num = 0; stream_num < 10; ++stream_num) {
+ stream_id = QuicClientDataStreamId(stream_num);
+ if (perspective() == Perspective::IS_SERVER) {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ headers_frame.set_has_priority(true);
+ frames[stream_num].reset(framer_.SerializeFrame(headers_frame));
+ EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0)).Times(1);
+ } else {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ frames[stream_num].reset(framer_.SerializeFrame(headers_frame));
+ }
+ stream_frames[stream_num].stream_id = stream_frame_.stream_id;
+ stream_frames[stream_num].offset = stream_frame_.offset;
+ stream_frames[stream_num].frame_buffer = frames[stream_num]->data();
+ stream_frames[stream_num].frame_length = frames[stream_num]->size();
+ DVLOG(1) << "make frame for stream " << stream_num << " offset "
+ << stream_frames[stream_num].offset;
+ stream_frame_.offset += frames[stream_num]->size();
+ EXPECT_CALL(session_, OnStreamHeaders(stream_id, _)).Times(1);
+ EXPECT_CALL(session_, OnStreamHeadersComplete(stream_id, fin, _))
+ .Times(1);
+ }
+ }
+
+ // Actually writing the frames in reverse order will cause HOL blocking.
+ EXPECT_CALL(session_, OnHeadersHeadOfLineBlocking(_)).Times(9);
+
+ for (int stream_num = 9; stream_num >= 0; --stream_num) {
+ DVLOG(1) << "OnStreamFrame for stream " << stream_num << " offset "
+ << stream_frames[stream_num].offset;
+ headers_stream_->OnStreamFrame(stream_frames[stream_num]);
+ connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+ }
+}
+
TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
// We want to create a frame that is more than the SPDY Framer's max control
// frame size, which is 16K, but less than the HPACK decoders max decode
@@ -305,9 +503,8 @@ TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
headers_["key2"] = string(1 << 13, '.');
for (QuicStreamId stream_id = kClientDataStreamId1;
stream_id < kClientDataStreamId3; stream_id += 2) {
- for (int count = 0; count < 2; ++count) {
- bool fin = (count == 0);
- for (QuicPriority priority = 0; priority < 7; ++priority) {
+ for (bool fin : {false, true}) {
+ for (SpdyPriority priority = 0; priority < 7; ++priority) {
// Replace with "WriteHeadersAndSaveData"
scoped_ptr<SpdySerializedFrame> frame;
if (perspective() == Perspective::IS_SERVER) {
@@ -328,7 +525,8 @@ TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
EXPECT_CALL(session_,
OnStreamHeadersComplete(stream_id, fin, frame->size()));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
stream_frame_.offset += frame->size();
CheckHeaders();
@@ -342,7 +540,8 @@ TEST_P(QuicHeadersStreamTest, ProcessBadData) {
EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
QUIC_INVALID_HEADERS_STREAM_DATA, _))
.Times(::testing::AnyNumber());
- stream_frame_.data = StringPiece(kBadData, strlen(kBadData));
+ stream_frame_.frame_buffer = kBadData;
+ stream_frame_.frame_length = strlen(kBadData);
headers_stream_->OnStreamFrame(stream_frame_);
}
@@ -352,22 +551,23 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY DATA frame received."))
- .WillOnce(InvokeWithoutArgs(this,
- &QuicHeadersStreamTest::CloseConnection));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ .WillOnce(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
}
TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
- SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR, "");
+ SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR);
scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
EXPECT_CALL(*connection_,
- SendConnectionCloseWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY RST_STREAM frame received."))
- .WillOnce(InvokeWithoutArgs(this,
- &QuicHeadersStreamTest::CloseConnection));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "SPDY RST_STREAM frame received."))
+ .WillOnce(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
}
@@ -376,12 +576,12 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, true, true, 0);
scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
EXPECT_CALL(*connection_,
- SendConnectionCloseWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY SETTINGS frame received."))
- .WillOnce(InvokeWithoutArgs(this,
- &QuicHeadersStreamTest::CloseConnection));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "SPDY SETTINGS frame received."))
+ .WillOnce(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
}
@@ -391,9 +591,10 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY PING frame received."))
- .WillOnce(InvokeWithoutArgs(this,
- &QuicHeadersStreamTest::CloseConnection));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ .WillOnce(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
}
@@ -403,22 +604,23 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
EXPECT_CALL(*connection_,
SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
"SPDY GOAWAY frame received."))
- .WillOnce(InvokeWithoutArgs(this,
- &QuicHeadersStreamTest::CloseConnection));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ .WillOnce(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
}
TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
SpdyWindowUpdateIR data(1, 1);
scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
- EXPECT_CALL(*connection_,
- SendConnectionCloseWithDetails(
- QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY WINDOW_UPDATE frame received."))
- .WillOnce(InvokeWithoutArgs(this,
- &QuicHeadersStreamTest::CloseConnection));
- stream_frame_.data = StringPiece(frame->data(), frame->size());
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_HEADERS_STREAM_DATA,
+ "SPDY WINDOW_UPDATE frame received."))
+ .WillOnce(
+ InvokeWithoutArgs(this, &QuicHeadersStreamTest::CloseConnection));
+ stream_frame_.frame_buffer = frame->data();
+ stream_frame_.frame_length = frame->size();
headers_stream_->OnStreamFrame(stream_frame_);
}
diff --git a/chromium/net/quic/quic_http_stream.cc b/chromium/net/quic/quic_http_stream.cc
index 9245a131f62..20d1e365e76 100644
--- a/chromium/net/quic/quic_http_stream.cc
+++ b/chromium/net/quic/quic_http_stream.cc
@@ -12,8 +12,8 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/quic/quic_chromium_client_session.h"
+#include "net/quic/quic_chromium_client_stream.h"
#include "net/quic/quic_http_utils.h"
-#include "net/quic/quic_reliable_client_stream.h"
#include "net/quic/quic_utils.h"
#include "net/quic/spdy_utils.h"
#include "net/socket/next_proto.h"
@@ -42,6 +42,7 @@ QuicHttpStream::QuicHttpStream(
closed_stream_received_bytes_(0),
closed_stream_sent_bytes_(0),
user_buffer_len_(0),
+ quic_connection_error_(QUIC_NO_ERROR),
weak_factory_(this) {
DCHECK(session_);
session_->AddObserver(this);
@@ -59,31 +60,21 @@ int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
const CompletionCallback& callback) {
DCHECK(!stream_);
if (!session_)
- return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED :
- ERR_QUIC_HANDSHAKE_FAILED;
+ return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED
+ : ERR_QUIC_HANDSHAKE_FAILED;
stream_net_log.AddEvent(
NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION,
session_->net_log().source().ToEventParametersCallback());
- if (request_info->url.SchemeIsCryptographic()) {
- SSLInfo ssl_info;
- bool secure_session =
- session_->GetSSLInfo(&ssl_info) && ssl_info.cert.get();
- UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.SecureResourceSecureSession",
- secure_session);
- if (!secure_session)
- return ERR_REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC;
- }
-
stream_net_log_ = stream_net_log;
request_info_ = request_info;
request_time_ = base::Time::Now();
priority_ = priority;
int rv = stream_request_.StartRequest(
- session_, &stream_, base::Bind(&QuicHttpStream::OnStreamReady,
- weak_factory_.GetWeakPtr()));
+ session_, &stream_,
+ base::Bind(&QuicHttpStream::OnStreamReady, weak_factory_.GetWeakPtr()));
if (rv == ERR_IO_PENDING) {
callback_ = callback;
} else if (rv == OK) {
@@ -130,11 +121,10 @@ int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
return ERR_CONNECTION_CLOSED;
}
- QuicPriority priority = ConvertRequestPriorityToQuicPriority(priority_);
- stream_->set_priority(priority);
+ SpdyPriority priority = ConvertRequestPriorityToQuicPriority(priority_);
+ stream_->SetPriority(priority);
// Store the serialized request headers.
- CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
- GetSpdyVersion(),
+ CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, HTTP2,
/*direct=*/true, &request_headers_);
// Store the request body.
@@ -188,8 +178,9 @@ int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
return ERR_IO_PENDING;
}
-int QuicHttpStream::ReadResponseBody(
- IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
+int QuicHttpStream::ReadResponseBody(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
if (!stream_) {
// If the stream is already closed, there is no body to read.
return response_status_;
@@ -215,8 +206,8 @@ void QuicHttpStream::Close(bool not_reusable) {
stream_->SetDelegate(nullptr);
stream_->Reset(QUIC_STREAM_CANCELLED);
ResetStream();
- response_status_ = was_handshake_confirmed_ ?
- ERR_CONNECTION_CLOSED : ERR_QUIC_HANDSHAKE_FAILED;
+ response_status_ = was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED
+ : ERR_QUIC_HANDSHAKE_FAILED;
}
}
@@ -296,6 +287,11 @@ void QuicHttpStream::Drain(HttpNetworkSession* session) {
delete this;
}
+void QuicHttpStream::PopulateNetErrorDetails(NetErrorDetails* details) {
+ if (was_handshake_confirmed_)
+ details->quic_connection_error = quic_connection_error_;
+}
+
void QuicHttpStream::SetPriority(RequestPriority priority) {
priority_ = priority;
}
@@ -332,21 +328,23 @@ void QuicHttpStream::OnDataAvailable() {
void QuicHttpStream::OnClose(QuicErrorCode error) {
if (error != QUIC_NO_ERROR) {
- response_status_ = was_handshake_confirmed_ ?
- ERR_QUIC_PROTOCOL_ERROR : ERR_QUIC_HANDSHAKE_FAILED;
+ response_status_ = was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR
+ : ERR_QUIC_HANDSHAKE_FAILED;
} else if (!response_headers_received_) {
response_status_ = ERR_ABORTED;
}
ResetStream();
- if (!callback_.is_null())
+ if (!callback_.is_null()) {
+ quic_connection_error_ = error;
DoCallback(response_status_);
+ }
}
void QuicHttpStream::OnError(int error) {
ResetStream();
- response_status_ = was_handshake_confirmed_ ?
- error : ERR_QUIC_HANDSHAKE_FAILED;
+ response_status_ =
+ was_handshake_confirmed_ ? error : ERR_QUIC_HANDSHAKE_FAILED;
if (!callback_.is_null())
DoCallback(response_status_);
}
@@ -451,8 +449,11 @@ int QuicHttpStream::DoSendHeadersComplete(int rv) {
if (rv < 0)
return rv;
- next_state_ = request_body_stream_ ?
- STATE_READ_REQUEST_BODY : STATE_OPEN;
+ // If the stream is already closed, don't read the request the body.
+ if (!stream_)
+ return response_status_;
+
+ next_state_ = request_body_stream_ ? STATE_READ_REQUEST_BODY : STATE_OPEN;
return OK;
}
@@ -460,8 +461,7 @@ int QuicHttpStream::DoSendHeadersComplete(int rv) {
int QuicHttpStream::DoReadRequestBody() {
next_state_ = STATE_READ_REQUEST_BODY_COMPLETE;
return request_body_stream_->Read(
- raw_request_body_buf_.get(),
- raw_request_body_buf_->size(),
+ raw_request_body_buf_.get(), raw_request_body_buf_->size(),
base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
}
@@ -522,7 +522,7 @@ int QuicHttpStream::ProcessResponseHeaders(const SpdyHeaderBlock& headers) {
NetLog::TYPE_QUIC_HTTP_STREAM_READ_RESPONSE_HEADERS,
base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
- if (!SpdyHeadersToHttpResponse(headers, GetSpdyVersion(), response_info_)) {
+ if (!SpdyHeadersToHttpResponse(headers, HTTP2, response_info_)) {
DLOG(WARNING) << "Invalid headers";
return ERR_QUIC_PROTOCOL_ERROR;
}
@@ -531,8 +531,8 @@ int QuicHttpStream::ProcessResponseHeaders(const SpdyHeaderBlock& headers) {
response_info_->socket_address = HostPortPair::FromIPEndPoint(address);
response_info_->connection_info =
HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3;
- response_info_->vary_data
- .Init(*request_info_, *response_info_->headers.get());
+ response_info_->vary_data.Init(*request_info_,
+ *response_info_->headers.get());
response_info_->was_npn_negotiated = true;
response_info_->npn_negotiated_protocol = "quic/1+spdy/3";
response_info_->response_time = base::Time::Now();
@@ -552,10 +552,6 @@ int QuicHttpStream::ReadAvailableData(IOBuffer* buf, int buf_len) {
return rv;
}
-SpdyMajorVersion QuicHttpStream::GetSpdyVersion() {
- return SpdyUtils::GetSpdyVersionForQuicVersion(stream_->version());
-}
-
void QuicHttpStream::ResetStream() {
if (!stream_)
return;
diff --git a/chromium/net/quic/quic_http_stream.h b/chromium/net/quic/quic_http_stream.h
index f7605ca814c..7abdf8b646e 100644
--- a/chromium/net/quic/quic_http_stream.h
+++ b/chromium/net/quic/quic_http_stream.h
@@ -5,15 +5,17 @@
#ifndef NET_QUIC_QUIC_HTTP_STREAM_H_
#define NET_QUIC_QUIC_HTTP_STREAM_H_
+#include <stddef.h>
#include <stdint.h>
#include <list>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/io_buffer.h"
#include "net/http/http_stream.h"
#include "net/quic/quic_chromium_client_session.h"
-#include "net/quic/quic_reliable_client_stream.h"
+#include "net/quic/quic_chromium_client_stream.h"
namespace net {
@@ -22,11 +24,11 @@ class QuicHttpStreamPeer;
} // namespace test
// The QuicHttpStream is a QUIC-specific HttpStream subclass. It holds a
-// non-owning pointer to a QuicReliableClientStream which it uses to
+// non-owning pointer to a QuicChromiumClientStream which it uses to
// send and receive data.
class NET_EXPORT_PRIVATE QuicHttpStream
: public QuicChromiumClientSession::Observer,
- public QuicReliableClientStream::Delegate,
+ public QuicChromiumClientStream::Delegate,
public HttpStream {
public:
explicit QuicHttpStream(
@@ -60,9 +62,10 @@ class NET_EXPORT_PRIVATE QuicHttpStream
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
bool GetRemoteEndpoint(IPEndPoint* endpoint) override;
void Drain(HttpNetworkSession* session) override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) override;
void SetPriority(RequestPriority priority) override;
- // QuicReliableClientStream::Delegate implementation
+ // QuicChromiumClientStream::Delegate implementation
void OnHeadersAvailable(const SpdyHeaderBlock& headers,
size_t frame_len) override;
void OnDataAvailable() override;
@@ -106,17 +109,15 @@ class NET_EXPORT_PRIVATE QuicHttpStream
int ReadAvailableData(IOBuffer* buf, int buf_len);
- SpdyMajorVersion GetSpdyVersion();
-
void ResetStream();
State next_state_;
base::WeakPtr<QuicChromiumClientSession> session_;
- int session_error_; // Error code from the connection shutdown.
+ int session_error_; // Error code from the connection shutdown.
bool was_handshake_confirmed_; // True if the crypto handshake succeeded.
QuicChromiumClientSession::StreamRequest stream_request_;
- QuicReliableClientStream* stream_; // Non-owning.
+ QuicChromiumClientStream* stream_; // Non-owning.
// The following three fields are all owned by the caller and must
// outlive this object, according to the HttpStream contract.
@@ -170,6 +171,8 @@ class NET_EXPORT_PRIVATE QuicHttpStream
BoundNetLog stream_net_log_;
+ QuicErrorCode quic_connection_error_;
+
base::WeakPtrFactory<QuicHttpStream> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(QuicHttpStream);
diff --git a/chromium/net/quic/quic_http_stream_test.cc b/chromium/net/quic/quic_http_stream_test.cc
index deaf7b800a8..a92266b1d6e 100644
--- a/chromium/net/quic/quic_http_stream_test.cc
+++ b/chromium/net/quic/quic_http_stream_test.cc
@@ -8,6 +8,7 @@
#include <vector>
+#include "base/memory/scoped_ptr.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/chunked_upload_data_stream.h"
#include "net/base/elements_upload_data_stream.h"
@@ -23,14 +24,15 @@
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/crypto/quic_server_info.h"
#include "net/quic/quic_chromium_client_session.h"
+#include "net/quic/quic_chromium_client_stream.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_connection.h"
-#include "net/quic/quic_connection_helper.h"
#include "net/quic/quic_default_packet_writer.h"
#include "net/quic/quic_http_utils.h"
#include "net/quic/quic_packet_reader.h"
-#include "net/quic/quic_reliable_client_stream.h"
#include "net/quic/quic_write_blocked_list.h"
#include "net/quic/spdy_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
#include "net/quic/test_tools/mock_random.h"
@@ -56,22 +58,21 @@ namespace {
const char kUploadData[] = "Really nifty data!";
const char kDefaultServerHostName[] = "www.google.com";
-const uint16 kDefaultServerPort = 80;
+const uint16_t kDefaultServerPort = 80;
class TestQuicConnection : public QuicConnection {
public:
TestQuicConnection(const QuicVersionVector& versions,
QuicConnectionId connection_id,
IPEndPoint address,
- QuicConnectionHelper* helper,
- const QuicConnection::PacketWriterFactory& writer_factory)
+ QuicChromiumConnectionHelper* helper,
+ QuicPacketWriter* writer)
: QuicConnection(connection_id,
address,
helper,
- writer_factory,
+ writer,
true /* owns_writer */,
Perspective::IS_CLIENT,
- false /* is_secure */,
versions) {}
void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
@@ -95,28 +96,22 @@ class AutoClosingStream : public QuicHttpStream {
void OnDataAvailable() override { Close(false); }
};
-class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
- public:
- explicit TestPacketWriterFactory(DatagramClientSocket* socket)
- : socket_(socket) {}
- ~TestPacketWriterFactory() override {}
-
- QuicPacketWriter* Create(QuicConnection* connection) const override {
- return new QuicDefaultPacketWriter(socket_);
- }
-
- private:
- DatagramClientSocket* socket_;
-};
-
} // namespace
class QuicHttpStreamPeer {
public:
- static QuicReliableClientStream* GetQuicReliableClientStream(
+ static QuicChromiumClientStream* GetQuicChromiumClientStream(
QuicHttpStream* stream) {
return stream->stream_;
}
+
+ static bool WasHandshakeConfirmed(QuicHttpStream* stream) {
+ return stream->was_handshake_confirmed_;
+ }
+
+ static void SetHandshakeConfirmed(QuicHttpStream* stream, bool confirmed) {
+ stream->was_handshake_confirmed_ = confirmed;
+ }
};
class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
@@ -129,9 +124,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
// be used by the mock socket when performing the write.
struct PacketToWrite {
PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
- : mode(mode),
- packet(packet) {
- }
+ : mode(mode), packet(packet) {}
IoMode mode;
QuicEncryptedPacket* packet;
};
@@ -139,6 +132,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
QuicHttpStreamTest()
: net_log_(BoundNetLog()),
use_closing_stream_(false),
+ crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
read_buffer_(new IOBufferWithSize(4096)),
connection_id_(2),
stream_id_(kClientDataStreamId1),
@@ -164,9 +158,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
}
// Returns the packet to be written at position |pos|.
- QuicEncryptedPacket* GetWrite(size_t pos) {
- return writes_[pos].packet;
- }
+ QuicEncryptedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
bool AtEof() {
return socket_data_->AllReadDataConsumed() &&
@@ -181,23 +173,22 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
void Initialize() {
mock_writes_.reset(new MockWrite[writes_.size()]);
for (size_t i = 0; i < writes_.size(); i++) {
- mock_writes_[i] = MockWrite(writes_[i].mode,
- writes_[i].packet->data(),
+ mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
writes_[i].packet->length());
};
socket_data_.reset(new StaticSocketDataProvider(
nullptr, 0, mock_writes_.get(), writes_.size()));
- MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
- net_log_.net_log());
+ MockUDPClientSocket* socket =
+ new MockUDPClientSocket(socket_data_.get(), net_log_.net_log());
socket->Connect(peer_addr_);
runner_ = new TestTaskRunner(&clock_);
send_algorithm_ = new MockSendAlgorithm();
EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillRepeatedly(Return(true));
EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
.WillRepeatedly(Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
@@ -209,12 +200,11 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
.WillRepeatedly(Return(QuicBandwidth::Zero()));
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
- helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
- &random_generator_));
- TestPacketWriterFactory writer_factory(socket);
- connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
- connection_id_, peer_addr_,
- helper_.get(), writer_factory);
+ helper_.reset(new QuicChromiumConnectionHelper(runner_.get(), &clock_,
+ &random_generator_));
+ connection_ = new TestQuicConnection(
+ SupportedVersions(GetParam()), connection_id_, peer_addr_,
+ helper_.get(), new QuicDefaultPacketWriter(socket));
connection_->set_visitor(&visitor_);
connection_->SetSendAlgorithm(send_algorithm_);
session_.reset(new QuicChromiumClientSession(
@@ -222,7 +212,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
/*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
&transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
QuicServerId(kDefaultServerHostName, kDefaultServerPort,
- /*is_secure=*/false, PRIVACY_MODE_DISABLED),
+ PRIVACY_MODE_DISABLED),
kQuicYieldAfterPacketsRead,
QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
/*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
@@ -232,9 +222,9 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
session_->Initialize();
session_->GetCryptoStream()->CryptoConnect();
EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
- stream_.reset(use_closing_stream_ ?
- new AutoClosingStream(session_->GetWeakPtr()) :
- new QuicHttpStream(session_->GetWeakPtr()));
+ stream_.reset(use_closing_stream_
+ ? new AutoClosingStream(session_->GetWeakPtr())
+ : new QuicHttpStream(session_->GetWeakPtr()));
}
void SetRequest(const std::string& method,
@@ -263,7 +253,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
bool fin,
RequestPriority request_priority,
size_t* spdy_headers_frame_length) {
- QuicPriority priority =
+ SpdyPriority priority =
ConvertRequestPriorityToQuicPriority(request_priority);
return maker_.MakeRequestHeadersPacket(
packet_number, stream_id_, kIncludeVersion, fin, priority,
@@ -314,7 +304,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
scoped_ptr<MockWrite[]> mock_writes_;
MockClock clock_;
TestQuicConnection* connection_;
- scoped_ptr<QuicConnectionHelper> helper_;
+ scoped_ptr<QuicChromiumConnectionHelper> helper_;
testing::StrictMock<MockConnectionVisitor> visitor_;
scoped_ptr<QuicHttpStream> stream_;
TransportSecurityState transport_security_state_;
@@ -342,7 +332,8 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
std::vector<PacketToWrite> writes_;
};
-INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
+INSTANTIATE_TEST_CASE_P(Version,
+ QuicHttpStreamTest,
::testing::ValuesIn(QuicSupportedVersions()));
TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
@@ -365,16 +356,15 @@ TEST_P(QuicHttpStreamTest, GetRequest) {
request_.method = "GET";
request_.url = GURL("http://www.google.com/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
// Ack the request.
ProcessPacket(ConstructAckPacket(1, 0, 0));
- EXPECT_EQ(ERR_IO_PENDING,
- stream_->ReadResponseHeaders(callback_.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
SetResponse("404 Not Found", std::string());
size_t spdy_response_header_frame_length;
@@ -390,9 +380,9 @@ TEST_P(QuicHttpStreamTest, GetRequest) {
EXPECT_FALSE(response_.request_time.is_null());
// There is no body, so this should return immediately.
- EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
- read_buffer_->size(),
- callback_.callback()));
+ EXPECT_EQ(0,
+ stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
+ callback_.callback()));
EXPECT_TRUE(stream_->IsResponseBodyComplete());
EXPECT_TRUE(AtEof());
@@ -415,16 +405,15 @@ TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
request_.method = "GET";
request_.url = GURL("http://www.google.com/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
// Ack the request.
ProcessPacket(ConstructAckPacket(1, 0, 0));
- EXPECT_EQ(ERR_IO_PENDING,
- stream_->ReadResponseHeaders(callback_.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
SpdyHeaderBlock headers;
headers[":status"] = "200 OK";
@@ -444,9 +433,9 @@ TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
// There is no body, so this should return immediately.
- EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
- read_buffer_->size(),
- callback_.callback()));
+ EXPECT_EQ(0,
+ stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
+ callback_.callback()));
EXPECT_TRUE(stream_->IsResponseBodyComplete());
EXPECT_TRUE(AtEof());
@@ -466,19 +455,83 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
request_.method = "GET";
request_.url = GURL("http://www.google.com/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
EXPECT_EQ(ERR_CONNECTION_CLOSED,
- stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
EXPECT_EQ(0, stream_->GetTotalSentBytes());
EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
}
+TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
+ SetRequest("GET", "/", DEFAULT_PRIORITY);
+ size_t spdy_request_headers_frame_length;
+ AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
+ &spdy_request_headers_frame_length));
+ AddWrite(ConstructAckAndRstStreamPacket(2));
+ use_closing_stream_ = true;
+ Initialize();
+
+ request_.method = "GET";
+ request_.url = GURL("http://www.google.com/");
+
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
+
+ // Ack the request.
+ ProcessPacket(ConstructAckPacket(1, 0, 0));
+ EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
+
+ EXPECT_TRUE(QuicHttpStreamPeer::WasHandshakeConfirmed(stream_.get()));
+ stream_->OnClose(QUIC_PEER_GOING_AWAY);
+
+ NetErrorDetails details;
+ EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
+ stream_->PopulateNetErrorDetails(&details);
+ EXPECT_EQ(QUIC_PEER_GOING_AWAY, details.quic_connection_error);
+}
+
+TEST_P(QuicHttpStreamTest, DoNotLogGranularQuicErrorIfHandshakeNotConfirmed) {
+ SetRequest("GET", "/", DEFAULT_PRIORITY);
+ size_t spdy_request_headers_frame_length;
+ AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
+ &spdy_request_headers_frame_length));
+ AddWrite(ConstructAckAndRstStreamPacket(2));
+ use_closing_stream_ = true;
+ Initialize();
+
+ request_.method = "GET";
+ request_.url = GURL("http://www.google.com/");
+
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
+
+ // Ack the request.
+ ProcessPacket(ConstructAckPacket(1, 0, 0));
+ EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
+
+ // The test setup defaults handshake to be confirmed. Manually set
+ // it to be not confirmed.
+ // Granular errors shouldn't be reported if handshake not confirmed.
+ QuicHttpStreamPeer::SetHandshakeConfirmed(stream_.get(), false);
+
+ EXPECT_FALSE(QuicHttpStreamPeer::WasHandshakeConfirmed(stream_.get()));
+ stream_->OnClose(QUIC_PEER_GOING_AWAY);
+
+ NetErrorDetails details;
+ EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
+ stream_->PopulateNetErrorDetails(&details);
+ EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
+}
+
// Regression test for http://crbug.com/409871
TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
SetRequest("GET", "/", DEFAULT_PRIORITY);
@@ -490,11 +543,11 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
request_.method = "GET";
request_.url = GURL("http://www.google.com/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
@@ -517,19 +570,19 @@ TEST_P(QuicHttpStreamTest, SendPostRequest) {
Initialize();
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(
- new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(
+ new UploadBytesElementReader(kUploadData, strlen(kUploadData))));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
request_.method = "POST";
request_.url = GURL("http://www.google.com/");
request_.upload_data_stream = &upload_data_stream;
ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
// Ack both packets in the request.
ProcessPacket(ConstructAckPacket(1, 0, 0));
@@ -575,8 +628,8 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
- AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
- kUploadData));
+ AddWrite(
+ ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, kUploadData));
AddWrite(ConstructAckPacket(4, 3, 1));
Initialize();
@@ -587,12 +640,12 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
request_.url = GURL("http://www.google.com/");
request_.upload_data_stream = &upload_data_stream;
ASSERT_EQ(OK, request_.upload_data_stream->Init(
- TestCompletionCallback().callback()));
+ TestCompletionCallback().callback()));
- ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
- ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ ASSERT_EQ(ERR_IO_PENDING,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
upload_data_stream.AppendData(kUploadData, chunk_size, true);
EXPECT_EQ(OK, callback_.WaitForResult());
@@ -654,12 +707,12 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
request_.url = GURL("http://www.google.com/");
request_.upload_data_stream = &upload_data_stream;
ASSERT_EQ(OK, request_.upload_data_stream->Init(
- TestCompletionCallback().callback()));
+ TestCompletionCallback().callback()));
- ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
- ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ ASSERT_EQ(ERR_IO_PENDING,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
upload_data_stream.AppendData(nullptr, 0, true);
EXPECT_EQ(OK, callback_.WaitForResult());
@@ -716,12 +769,12 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
request_.url = GURL("http://www.google.com/");
request_.upload_data_stream = &upload_data_stream;
ASSERT_EQ(OK, request_.upload_data_stream->Init(
- TestCompletionCallback().callback()));
+ TestCompletionCallback().callback()));
- ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
- ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ ASSERT_EQ(ERR_IO_PENDING,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
upload_data_stream.AppendData(nullptr, 0, true);
EXPECT_EQ(OK, callback_.WaitForResult());
@@ -775,15 +828,14 @@ TEST_P(QuicHttpStreamTest, DestroyedEarly) {
request_.method = "GET";
request_.url = GURL("http://www.google.com/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_, callback_.callback()));
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
// Ack the request.
ProcessPacket(ConstructAckPacket(1, 0, 0));
- EXPECT_EQ(ERR_IO_PENDING,
- stream_->ReadResponseHeaders(callback_.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
// Send the response with a body.
SetResponse("404 OK", "hello world!");
@@ -814,27 +866,25 @@ TEST_P(QuicHttpStreamTest, Priority) {
request_.method = "GET";
request_.url = GURL("http://www.google.com/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
- net_log_, callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_,
+ callback_.callback()));
// Check that priority is highest.
- QuicReliableClientStream* reliable_stream =
- QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
+ QuicChromiumClientStream* reliable_stream =
+ QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
DCHECK(reliable_stream);
- DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
- reliable_stream->EffectivePriority());
+ DCHECK_EQ(kV3HighestPriority, reliable_stream->Priority());
- EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
- callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
// Check that priority has now dropped back to MEDIUM.
- DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
- reliable_stream->EffectivePriority()));
+ DCHECK_EQ(MEDIUM,
+ ConvertQuicPriorityToRequestPriority(reliable_stream->Priority()));
// Ack the request.
ProcessPacket(ConstructAckPacket(1, 0, 0));
- EXPECT_EQ(ERR_IO_PENDING,
- stream_->ReadResponseHeaders(callback_.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
// Send the response with a body.
SetResponse("404 OK", "hello world!");
@@ -865,23 +915,21 @@ TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
request_.method = "GET";
request_.url = GURL("http://www.google.com/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
- net_log_, callback_.callback()));
+ EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_,
+ callback_.callback()));
// Check that priority is highest.
- QuicReliableClientStream* reliable_stream =
- QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
+ QuicChromiumClientStream* reliable_stream =
+ QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
DCHECK(reliable_stream);
- QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
+ QuicChromiumClientStream::Delegate* delegate = reliable_stream->GetDelegate();
DCHECK(delegate);
- DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
- reliable_stream->EffectivePriority());
+ DCHECK_EQ(kV3HighestPriority, reliable_stream->Priority());
- // Set Delegate to nullptr and make sure EffectivePriority returns highest
+ // Set Delegate to nullptr and make sure Priority returns highest
// priority.
reliable_stream->SetDelegate(nullptr);
- DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
- reliable_stream->EffectivePriority());
+ DCHECK_EQ(kV3HighestPriority, reliable_stream->Priority());
reliable_stream->SetDelegate(delegate);
EXPECT_EQ(0, stream_->GetTotalSentBytes());
diff --git a/chromium/net/quic/quic_http_utils.cc b/chromium/net/quic/quic_http_utils.cc
index 60fbd9a4a7f..6091c08cf9e 100644
--- a/chromium/net/quic/quic_http_utils.cc
+++ b/chromium/net/quic/quic_http_utils.cc
@@ -4,32 +4,34 @@
#include "net/quic/quic_http_utils.h"
+#include <utility>
+
namespace net {
-QuicPriority ConvertRequestPriorityToQuicPriority(
+SpdyPriority ConvertRequestPriorityToQuicPriority(
const RequestPriority priority) {
DCHECK_GE(priority, MINIMUM_PRIORITY);
DCHECK_LE(priority, MAXIMUM_PRIORITY);
- return static_cast<QuicPriority>(HIGHEST - priority);
+ return static_cast<SpdyPriority>(HIGHEST - priority);
}
-NET_EXPORT_PRIVATE RequestPriority ConvertQuicPriorityToRequestPriority(
- QuicPriority priority) {
+NET_EXPORT_PRIVATE RequestPriority
+ConvertQuicPriorityToRequestPriority(SpdyPriority priority) {
// Handle invalid values gracefully.
- return (priority >= 5) ?
- IDLE : static_cast<RequestPriority>(HIGHEST - priority);
+ return (priority >= 5) ? IDLE
+ : static_cast<RequestPriority>(HIGHEST - priority);
}
scoped_ptr<base::Value> QuicRequestNetLogCallback(
QuicStreamId stream_id,
const SpdyHeaderBlock* headers,
- QuicPriority priority,
+ SpdyPriority priority,
NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(static_cast<base::DictionaryValue*>(
SpdyHeaderBlockNetLogCallback(headers, capture_mode).release()));
dict->SetInteger("quic_priority", static_cast<int>(priority));
dict->SetInteger("quic_stream_id", static_cast<int>(stream_id));
- return dict.Pass();
+ return std::move(dict);
}
} // namespace net
diff --git a/chromium/net/quic/quic_http_utils.h b/chromium/net/quic/quic_http_utils.h
index 82306d63ce2..1bde98a631b 100644
--- a/chromium/net/quic/quic_http_utils.h
+++ b/chromium/net/quic/quic_http_utils.h
@@ -10,20 +10,21 @@
#include "net/base/request_priority.h"
#include "net/quic/quic_protocol.h"
#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_protocol.h"
namespace net {
-NET_EXPORT_PRIVATE QuicPriority ConvertRequestPriorityToQuicPriority(
- RequestPriority priority);
+NET_EXPORT_PRIVATE SpdyPriority
+ConvertRequestPriorityToQuicPriority(RequestPriority priority);
-NET_EXPORT_PRIVATE RequestPriority ConvertQuicPriorityToRequestPriority(
- QuicPriority priority);
+NET_EXPORT_PRIVATE RequestPriority
+ConvertQuicPriorityToRequestPriority(SpdyPriority priority);
// Converts a SpdyHeaderBlock and priority into NetLog event parameters.
NET_EXPORT scoped_ptr<base::Value> QuicRequestNetLogCallback(
QuicStreamId stream_id,
const SpdyHeaderBlock* headers,
- QuicPriority priority,
+ SpdyPriority priority,
NetLogCaptureMode capture_mode);
} // namespace net
diff --git a/chromium/net/quic/quic_http_utils_test.cc b/chromium/net/quic/quic_http_utils_test.cc
index 93b62e2e9d7..5f33096a14b 100644
--- a/chromium/net/quic/quic_http_utils_test.cc
+++ b/chromium/net/quic/quic_http_utils_test.cc
@@ -4,6 +4,10 @@
#include "net/quic/quic_http_utils.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -25,8 +29,8 @@ TEST(QuicHttpUtilsTest, ConvertQuicPriorityToRequestPriority) {
EXPECT_EQ(IDLE, ConvertQuicPriorityToRequestPriority(4));
// These are invalid values, but we should still handle them
// gracefully. TODO(rtenneti): should we test for all possible values of
- // uint32?
- for (int i = 5; i < kuint8max; ++i) {
+ // uint32_t?
+ for (int i = 5; i < std::numeric_limits<uint8_t>::max(); ++i) {
EXPECT_EQ(IDLE, ConvertQuicPriorityToRequestPriority(i));
}
}
diff --git a/chromium/net/quic/quic_multipath_received_packet_manager.cc b/chromium/net/quic/quic_multipath_received_packet_manager.cc
new file mode 100644
index 00000000000..0dc45c09e64
--- /dev/null
+++ b/chromium/net/quic/quic_multipath_received_packet_manager.cc
@@ -0,0 +1,147 @@
+// Copyright (c) 2015 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/quic_multipath_received_packet_manager.h"
+
+#include "base/stl_util.h"
+
+namespace net {
+
+QuicMultipathReceivedPacketManager::QuicMultipathReceivedPacketManager(
+ QuicConnectionStats* stats) {
+ path_managers_[kDefaultPathId] = new QuicReceivedPacketManager(stats);
+}
+
+QuicMultipathReceivedPacketManager::~QuicMultipathReceivedPacketManager() {
+ STLDeleteValues(&path_managers_);
+}
+
+void QuicMultipathReceivedPacketManager::OnPathCreated(
+ QuicPathId path_id,
+ QuicConnectionStats* stats) {
+ if (path_managers_[path_id] != nullptr) {
+ LOG(DFATAL) << "Received packet manager of path already exists: "
+ << static_cast<uint32_t>(path_id);
+ return;
+ }
+
+ path_managers_[path_id] = new QuicReceivedPacketManager(stats);
+}
+
+void QuicMultipathReceivedPacketManager::OnPathClosed(QuicPathId path_id) {
+ QuicReceivedPacketManager* manager = path_managers_[path_id];
+ if (manager == nullptr) {
+ LOG(DFATAL) << "Received packet manager of path does not exist: "
+ << static_cast<uint32_t>(path_id);
+ return;
+ }
+
+ delete manager;
+ path_managers_.erase(path_id);
+}
+
+void QuicMultipathReceivedPacketManager::RecordPacketReceived(
+ QuicPathId path_id,
+ QuicByteCount bytes,
+ const QuicPacketHeader& header,
+ QuicTime receipt_time) {
+ QuicReceivedPacketManager* manager = path_managers_[path_id];
+ if (manager == nullptr) {
+ LOG(DFATAL) << "Received a packet on a non-existent path.";
+ return;
+ }
+
+ manager->RecordPacketReceived(bytes, header, receipt_time);
+}
+
+void QuicMultipathReceivedPacketManager::RecordPacketRevived(
+ QuicPathId path_id,
+ QuicPacketNumber packet_number) {
+ QuicReceivedPacketManager* manager = path_managers_[path_id];
+ if (manager == nullptr) {
+ LOG(DFATAL) << "Revived a packet on a non-existent path.";
+ return;
+ }
+
+ manager->RecordPacketRevived(packet_number);
+}
+
+bool QuicMultipathReceivedPacketManager::IsMissing(
+ QuicPathId path_id,
+ QuicPacketNumber packet_number) {
+ QuicReceivedPacketManager* manager = path_managers_[path_id];
+ if (manager == nullptr) {
+ LOG(DFATAL) << "Check whether a packet is missing on a non-existent path.";
+ return true;
+ }
+
+ return manager->IsMissing(packet_number);
+}
+
+bool QuicMultipathReceivedPacketManager::IsAwaitingPacket(
+ QuicPathId path_id,
+ QuicPacketNumber packet_number) {
+ QuicReceivedPacketManager* manager = path_managers_[path_id];
+ if (manager == nullptr) {
+ LOG(DFATAL) << "Check whether a packet is awaited on a non-existent path.";
+ return false;
+ }
+
+ return manager->IsAwaitingPacket(packet_number);
+}
+
+void QuicMultipathReceivedPacketManager::UpdateReceivedPacketInfo(
+ std::vector<QuicAckFrame>* ack_frames,
+ QuicTime approximate_now,
+ bool force_all_paths) {
+ QuicAckFrame ack_frame;
+ for (std::pair<QuicPathId, QuicReceivedPacketManager*>
+ per_path_received_packet_manager : path_managers_) {
+ if (!force_all_paths &&
+ !per_path_received_packet_manager.second->ack_frame_updated()) {
+ continue;
+ }
+ per_path_received_packet_manager.second->UpdateReceivedPacketInfo(
+ &ack_frame, approximate_now);
+ ack_frames->push_back(ack_frame);
+ }
+}
+
+void QuicMultipathReceivedPacketManager::UpdatePacketInformationSentByPeer(
+ const std::vector<QuicStopWaitingFrame>& stop_waitings) {
+ for (QuicStopWaitingFrame stop_waiting : stop_waitings) {
+ QuicReceivedPacketManager* manager = path_managers_[stop_waiting.path_id];
+ if (manager != nullptr) {
+ manager->UpdatePacketInformationSentByPeer(stop_waiting);
+ }
+ }
+}
+
+bool QuicMultipathReceivedPacketManager::HasNewMissingPackets(
+ QuicPathId path_id) const {
+ MultipathReceivedPacketManagerMap::const_iterator it =
+ path_managers_.find(path_id);
+ if (it == path_managers_.end()) {
+ LOG(DFATAL)
+ << "Check whether has new missing packets on a non-existent path.";
+ return false;
+ }
+
+ return it->second->HasNewMissingPackets();
+}
+
+QuicPacketNumber
+QuicMultipathReceivedPacketManager::GetPeerLeastPacketAwaitingAck(
+ QuicPathId path_id) {
+ QuicReceivedPacketManager* manager = path_managers_[path_id];
+ if (manager == nullptr) {
+ LOG(DFATAL)
+ << "Try to get peer_least_packet_awaiting_ack of a non-existent path.";
+ return false;
+ }
+
+ return manager->peer_least_packet_awaiting_ack();
+}
+
+} // namespace net
diff --git a/chromium/net/quic/quic_multipath_received_packet_manager.h b/chromium/net/quic/quic_multipath_received_packet_manager.h
new file mode 100644
index 00000000000..e33c5fccdb6
--- /dev/null
+++ b/chromium/net/quic/quic_multipath_received_packet_manager.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2015 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.
+
+// A connection level received packet manager which manages multiple per path
+// received packet managers.
+
+#ifndef NET_QUIC_QUIC_MULTIPATH_RECEIVED_PACKET_MANAGER_H_
+#define NET_QUIC_QUIC_MULTIPATH_RECEIVED_PACKET_MANAGER_H_
+
+#include <vector>
+
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_received_packet_manager.h"
+
+namespace net {
+
+namespace test {
+class QuicMultipathReceivedPacketManagerPeer;
+} // namespace test
+
+class NET_EXPORT_PRIVATE QuicMultipathReceivedPacketManager {
+ public:
+ typedef base::hash_map<QuicPathId, QuicReceivedPacketManager*>
+ MultipathReceivedPacketManagerMap;
+
+ explicit QuicMultipathReceivedPacketManager(QuicConnectionStats* stats);
+ ~QuicMultipathReceivedPacketManager();
+
+ // Called when a new path with |path_id| is created.
+ void OnPathCreated(QuicPathId path_id, QuicConnectionStats* stats);
+
+ // Called when path with |path_id| is closed.
+ void OnPathClosed(QuicPathId path_id);
+
+ // Records packet receipt information on path with |path_id|.
+ void RecordPacketReceived(QuicPathId path_id,
+ QuicByteCount bytes,
+ const QuicPacketHeader& header,
+ QuicTime receipt_time);
+
+ // Called when packet with |packet_number| is revived on path with |path_id|.
+ void RecordPacketRevived(QuicPathId path_id, QuicPacketNumber packet_number);
+
+ // Checks whether |packet_number| is missing on path with |path_id|.
+ bool IsMissing(QuicPathId path_id, QuicPacketNumber packet_number);
+
+ // Checks if we're still waiting for the packet with |packet_number| on path
+ // with |path_id|.
+ bool IsAwaitingPacket(QuicPathId path_id, QuicPacketNumber packet_number);
+
+ // If |force_all_paths| is false, populates ack information for paths whose
+ // ack has been updated since UpdateReceivedPacketInfo was called last time.
+ // Otherwise, populates ack for all paths.
+ void UpdateReceivedPacketInfo(std::vector<QuicAckFrame>* ack_frames,
+ QuicTime approximate_now,
+ bool force_all_paths);
+
+ // Updates internal state based on stop_waiting frames for corresponding path.
+ void UpdatePacketInformationSentByPeer(
+ const std::vector<QuicStopWaitingFrame>& stop_waitings);
+
+ // Returns true when there are new missing packets to be reported within 3
+ // packets of the largest observed on path with |path_id|.
+ bool HasNewMissingPackets(QuicPathId path_id) const;
+
+ QuicPacketNumber GetPeerLeastPacketAwaitingAck(QuicPathId path_id);
+
+ private:
+ friend class test::QuicMultipathReceivedPacketManagerPeer;
+
+ // Map mapping path id to path received packet manager.
+ MultipathReceivedPacketManagerMap path_managers_;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_MULTIPATH_RECEIVED_PACKET_MANAGER_H_
diff --git a/chromium/net/quic/quic_multipath_received_packet_manager_test.cc b/chromium/net/quic/quic_multipath_received_packet_manager_test.cc
new file mode 100644
index 00000000000..e342ae86f55
--- /dev/null
+++ b/chromium/net/quic/quic_multipath_received_packet_manager_test.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2015 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/quic_multipath_received_packet_manager.h"
+
+#include "net/quic/quic_connection_stats.h"
+#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/test/gtest_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::Return;
+using testing::_;
+
+namespace net {
+namespace test {
+
+class QuicMultipathReceivedPacketManagerPeer {
+ public:
+ static bool PathReceivedPacketManagerExists(
+ QuicMultipathReceivedPacketManager* multipath_manager,
+ QuicPathId path_id) {
+ return multipath_manager->path_managers_.count(path_id);
+ }
+
+ static void SetPathReceivedPacketManager(
+ QuicMultipathReceivedPacketManager* multipath_manager,
+ QuicPathId path_id,
+ QuicReceivedPacketManager* manager) {
+ delete multipath_manager->path_managers_[path_id];
+ multipath_manager->path_managers_[path_id] = manager;
+ }
+};
+
+namespace {
+
+const QuicPathId kPathId1 = 1;
+const QuicPathId kPathId2 = 2;
+const QuicPathId kPathId3 = 3;
+const QuicByteCount kBytes = 1350;
+
+class QuicMultipathReceivedPacketManagerTest : public testing::Test {
+ public:
+ QuicMultipathReceivedPacketManagerTest()
+ : multipath_manager_(&stats_),
+ manager_0_(new MockReceivedPacketManager(&stats_)),
+ manager_1_(new MockReceivedPacketManager(&stats_)) {
+ QuicMultipathReceivedPacketManagerPeer::SetPathReceivedPacketManager(
+ &multipath_manager_, kDefaultPathId, manager_0_);
+ QuicMultipathReceivedPacketManagerPeer::SetPathReceivedPacketManager(
+ &multipath_manager_, kPathId1, manager_1_);
+ }
+
+ QuicConnectionStats stats_;
+ QuicMultipathReceivedPacketManager multipath_manager_;
+ MockReceivedPacketManager* manager_0_;
+ MockReceivedPacketManager* manager_1_;
+ QuicPacketHeader header_;
+};
+
+TEST_F(QuicMultipathReceivedPacketManagerTest, OnPathCreatedAndClosed) {
+ EXPECT_TRUE(
+ QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
+ &multipath_manager_, kDefaultPathId));
+ EXPECT_TRUE(
+ QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
+ &multipath_manager_, kPathId1));
+ EXPECT_DFATAL(multipath_manager_.OnPathCreated(kDefaultPathId, &stats_),
+ "Received packet manager of path already exists");
+ // Path 2 created.
+ multipath_manager_.OnPathCreated(kPathId2, &stats_);
+ EXPECT_TRUE(
+ QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
+ &multipath_manager_, kPathId2));
+ EXPECT_FALSE(
+ QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
+ &multipath_manager_, kPathId3));
+ // Path 3 created.
+ multipath_manager_.OnPathCreated(kPathId3, &stats_);
+ EXPECT_TRUE(
+ QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
+ &multipath_manager_, kPathId3));
+
+ // Path 0 closed.
+ multipath_manager_.OnPathClosed(kDefaultPathId);
+ EXPECT_FALSE(
+ QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
+ &multipath_manager_, kDefaultPathId));
+ EXPECT_DFATAL(multipath_manager_.OnPathClosed(kDefaultPathId),
+ "Received packet manager of path does not exist");
+}
+
+TEST_F(QuicMultipathReceivedPacketManagerTest, RecordPacketReceived) {
+ EXPECT_CALL(*manager_0_, RecordPacketReceived(_, _, _)).Times(1);
+ multipath_manager_.RecordPacketReceived(kDefaultPathId, kBytes, header_,
+ QuicTime::Zero());
+ EXPECT_DFATAL(multipath_manager_.RecordPacketReceived(
+ kPathId2, kBytes, header_, QuicTime::Zero()),
+ "Received a packet on a non-existent path");
+}
+
+TEST_F(QuicMultipathReceivedPacketManagerTest, RecordPacketRevived) {
+ EXPECT_CALL(*manager_0_, RecordPacketRevived(_)).Times(1);
+ multipath_manager_.RecordPacketRevived(kDefaultPathId, header_.packet_number);
+ EXPECT_DFATAL(
+ multipath_manager_.RecordPacketRevived(kPathId2, header_.packet_number),
+ "Revived a packet on a non-existent path");
+}
+
+TEST_F(QuicMultipathReceivedPacketManagerTest, IsMissing) {
+ EXPECT_CALL(*manager_0_, IsMissing(header_.packet_number))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*manager_1_, IsMissing(header_.packet_number))
+ .WillOnce(Return(false));
+ EXPECT_TRUE(
+ multipath_manager_.IsMissing(kDefaultPathId, header_.packet_number));
+ EXPECT_FALSE(multipath_manager_.IsMissing(kPathId1, header_.packet_number));
+ EXPECT_DFATAL(multipath_manager_.IsMissing(kPathId2, header_.packet_number),
+ "Check whether a packet is missing on a non-existent path");
+}
+
+TEST_F(QuicMultipathReceivedPacketManagerTest, IsAwaitingPacket) {
+ EXPECT_CALL(*manager_0_, IsAwaitingPacket(header_.packet_number))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*manager_1_, IsAwaitingPacket(header_.packet_number))
+ .WillOnce(Return(false));
+ EXPECT_TRUE(multipath_manager_.IsAwaitingPacket(kDefaultPathId,
+ header_.packet_number));
+ EXPECT_FALSE(
+ multipath_manager_.IsAwaitingPacket(kPathId1, header_.packet_number));
+ EXPECT_DFATAL(
+ multipath_manager_.IsAwaitingPacket(kPathId2, header_.packet_number),
+ "Check whether a packet is awaited on a non-existent path");
+}
+
+TEST_F(QuicMultipathReceivedPacketManagerTest, UpdateReceivedPacketInfo) {
+ std::vector<QuicAckFrame> ack_frames;
+ EXPECT_EQ(static_cast<size_t>(0), ack_frames.size());
+ EXPECT_CALL(*manager_0_, ack_frame_updated()).WillOnce(Return(false));
+ EXPECT_CALL(*manager_1_, ack_frame_updated()).WillRepeatedly(Return(false));
+ multipath_manager_.UpdateReceivedPacketInfo(&ack_frames, QuicTime::Zero(),
+ /*force_all_paths=*/false);
+ EXPECT_EQ(static_cast<size_t>(0), ack_frames.size());
+ EXPECT_CALL(*manager_0_, ack_frame_updated()).WillOnce(Return(true));
+ multipath_manager_.UpdateReceivedPacketInfo(&ack_frames, QuicTime::Zero(),
+ /*force_all_paths=*/false);
+ EXPECT_EQ(static_cast<size_t>(1), ack_frames.size());
+
+ std::vector<QuicAckFrame> ack_frames_all;
+ multipath_manager_.UpdateReceivedPacketInfo(&ack_frames_all, QuicTime::Zero(),
+ /*force_all_paths=*/true);
+ EXPECT_EQ(static_cast<size_t>(2), ack_frames_all.size());
+}
+
+TEST_F(QuicMultipathReceivedPacketManagerTest,
+ UpdatePacketInformationSentByPeer) {
+ std::vector<QuicStopWaitingFrame> stop_waitings;
+ QuicStopWaitingFrame stop_waiting_0;
+ QuicStopWaitingFrame stop_waiting_1;
+ QuicStopWaitingFrame stop_waiting_2;
+ stop_waiting_0.path_id = kDefaultPathId;
+ stop_waiting_1.path_id = kPathId1;
+ stop_waiting_2.path_id = kPathId2;
+ stop_waitings.push_back(stop_waiting_0);
+ stop_waitings.push_back(stop_waiting_1);
+ stop_waitings.push_back(stop_waiting_2);
+ EXPECT_CALL(*manager_0_, UpdatePacketInformationSentByPeer(_)).Times(1);
+ EXPECT_CALL(*manager_1_, UpdatePacketInformationSentByPeer(_)).Times(1);
+ multipath_manager_.UpdatePacketInformationSentByPeer(stop_waitings);
+}
+
+TEST_F(QuicMultipathReceivedPacketManagerTest, HasNewMissingPackets) {
+ EXPECT_CALL(*manager_0_, HasNewMissingPackets()).WillOnce(Return(true));
+ EXPECT_CALL(*manager_1_, HasNewMissingPackets()).WillOnce(Return(false));
+ EXPECT_TRUE(multipath_manager_.HasNewMissingPackets(kDefaultPathId));
+ EXPECT_FALSE(multipath_manager_.HasNewMissingPackets(kPathId1));
+ EXPECT_DFATAL(multipath_manager_.HasNewMissingPackets(kPathId2),
+ "Check whether has new missing packets on a non-existent path");
+}
+
+} // namespace
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/quic_multipath_transmissions_map.cc b/chromium/net/quic/quic_multipath_transmissions_map.cc
new file mode 100644
index 00000000000..14655e375da
--- /dev/null
+++ b/chromium/net/quic/quic_multipath_transmissions_map.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2015 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/quic_multipath_transmissions_map.h"
+
+namespace net_quic {
+
+QuicMultipathTransmissionsMap::QuicMultipathTransmissionsMap() {}
+
+QuicMultipathTransmissionsMap::~QuicMultipathTransmissionsMap() {
+ for (std::pair<QuicPathIdPacketNumber, MultipathTransmissionsList*>
+ packet_transmissions : transmission_map_) {
+ packet_transmissions.second->pop_front();
+ if (packet_transmissions.second->empty()) {
+ delete packet_transmissions.second;
+ }
+ }
+}
+
+void QuicMultipathTransmissionsMap::OnPacketRetransmittedOnDifferentPath(
+ QuicPathIdPacketNumber original_path_id_packet_number,
+ QuicPathIdPacketNumber path_id_packet_number) {
+ MultipathTransmissionsList* across_paths_transmission_list = nullptr;
+ MultipathTransmissionsMap::iterator it =
+ transmission_map_.find(original_path_id_packet_number);
+ if (it != transmission_map_.end()) {
+ across_paths_transmission_list = it->second;
+ } else {
+ across_paths_transmission_list = new MultipathTransmissionsList();
+ across_paths_transmission_list->push_back(original_path_id_packet_number);
+ transmission_map_[original_path_id_packet_number] =
+ across_paths_transmission_list;
+ }
+
+ across_paths_transmission_list->push_back(path_id_packet_number);
+ transmission_map_[path_id_packet_number] = across_paths_transmission_list;
+}
+
+const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
+QuicMultipathTransmissionsMap::MaybeGetTransmissionsOnOtherPaths(
+ QuicPathIdPacketNumber path_id_packet_number) const {
+ MultipathTransmissionsMap::const_iterator it =
+ transmission_map_.find(path_id_packet_number);
+ if (it == transmission_map_.end()) {
+ return nullptr;
+ }
+
+ return it->second;
+}
+
+void QuicMultipathTransmissionsMap::OnPacketHandled(
+ QuicPathIdPacketNumber path_id_packet_number) {
+ MultipathTransmissionsMap::iterator it =
+ transmission_map_.find(path_id_packet_number);
+ if (it == transmission_map_.end()) {
+ return;
+ }
+
+ MultipathTransmissionsList* transmission_list = it->second;
+ MultipathTransmissionsList::iterator transmission_it;
+ // Remove all across paths transmissions of this packet from the map.
+ for (QuicPathIdPacketNumber path_id_packet_number : *transmission_list) {
+ transmission_map_.erase(path_id_packet_number);
+ }
+ // Remove the multipath transmissions list.
+ delete transmission_list;
+}
+
+} // namespace net_quic
diff --git a/chromium/net/quic/quic_multipath_transmissions_map.h b/chromium/net/quic/quic_multipath_transmissions_map.h
new file mode 100644
index 00000000000..121e63ee6a5
--- /dev/null
+++ b/chromium/net/quic/quic_multipath_transmissions_map.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2015 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.
+
+// A map manages packets which are transmitted across multiple paths.
+// For example, a packet is originally transmitted on path 1 with packet number
+// 1. Then this packet is retransmitted on path 2 with packet number 1. (1, 1)
+// and (2, 1) are inserted into this map. Suppose (2, 1) is detected lost and
+// gets retransmitted on path 2 with packet 2. (2, 2) will not be inserted
+// because this transmission does not "across" path compared to (2, 1).
+
+#ifndef NET_QUIC_QUIC_MULTIPATH_TRANSMISSIONS_MAP_H_
+#define NET_QUIC_QUIC_MULTIPATH_TRANSMISSIONS_MAP_H_
+
+#include <deque>
+
+#include "base/containers/hash_tables.h"
+#include "base/macros.h"
+#include "net/quic/quic_protocol.h"
+
+namespace net_quic {
+
+typedef std::pair<net::QuicPathId, net::QuicPacketNumber>
+ QuicPathIdPacketNumber;
+
+class NET_EXPORT_PRIVATE QuicMultipathTransmissionsMap {
+ public:
+ typedef std::deque<QuicPathIdPacketNumber> MultipathTransmissionsList;
+ typedef base::hash_map<QuicPathIdPacketNumber, MultipathTransmissionsList*>
+ MultipathTransmissionsMap;
+
+ QuicMultipathTransmissionsMap();
+ ~QuicMultipathTransmissionsMap();
+
+ // Called when a packet is retransmitted on a different path. Adds both
+ // |original_path_id_packet_number| (if not exists) and
+ // |path_id_packet_number| to |transmission_map_|.
+ void OnPacketRetransmittedOnDifferentPath(
+ QuicPathIdPacketNumber original_path_id_packet_number,
+ QuicPathIdPacketNumber path_id_packet_number);
+
+ // Returns all multipath transmissions list if |path_id_packet_number| has
+ // been transmitted across multiple paths, nullptr otherwise.
+ const MultipathTransmissionsList* MaybeGetTransmissionsOnOtherPaths(
+ QuicPathIdPacketNumber path_id_packet_number) const;
+
+ // Called after packet |path_id_packet_number| is received.
+ // If |path_id_packet_number| has been transmitted across multiple paths,
+ // clears all multipath transmissions list and removes each transmission from
+ // |transmission_map_|, does nothing otherwise.
+ void OnPacketHandled(QuicPathIdPacketNumber path_id_packet_number);
+
+ private:
+ // Keys of the map are QuicPathIdPacketNumber, and values are pointers to
+ // lists of multipath transmissions of the same packet. For example, if a
+ // packet has been transmitted as (1, 1) and (2, 1), two entries are added
+ // to this map and both values point to the same list: {(1, 1), (2, 1)}.
+ // The MultipathTransmissionsList is owned by the transmission which is
+ // received first (on any path).
+ MultipathTransmissionsMap transmission_map_;
+};
+
+} // namespace net_quic
+
+#endif // NET_QUIC_QUIC_MULTIPATH_TRANSMISSIONS_MAP_H_
diff --git a/chromium/net/quic/quic_multipath_transmissions_map_test.cc b/chromium/net/quic/quic_multipath_transmissions_map_test.cc
new file mode 100644
index 00000000000..fcae200772c
--- /dev/null
+++ b/chromium/net/quic/quic_multipath_transmissions_map_test.cc
@@ -0,0 +1,114 @@
+// Copyright (c) 2015 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/quic_multipath_transmissions_map.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net_quic {
+namespace test {
+namespace {
+
+TEST(QuicAcrossPathsTransmissionMapTest, OnPacketRetransmittedOnDifferentPath) {
+ QuicMultipathTransmissionsMap transmission_map;
+ // Packet0's original transmission sent on path 1 with packet number 1.
+ QuicPathIdPacketNumber packet0_0(1, 1);
+ // Packet0's retransmission sent on path 2 with packet number 1.
+ QuicPathIdPacketNumber packet0_1(2, 1);
+ // packet0's 2nd retransmission sent on path 3 with packet number 1.
+ QuicPathIdPacketNumber packet0_2(3, 1);
+
+ transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_0, packet0_1);
+ const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
+ transmission_list1 =
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0);
+ EXPECT_EQ(packet0_0, (*transmission_list1)[0]);
+ EXPECT_EQ(packet0_1, (*transmission_list1)[1]);
+
+ transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_1, packet0_2);
+ const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
+ transmission_list2 =
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0);
+ EXPECT_EQ(packet0_0, (*transmission_list2)[0]);
+ EXPECT_EQ(packet0_1, (*transmission_list2)[1]);
+ EXPECT_EQ(packet0_2, (*transmission_list2)[2]);
+ // Make sure there is no memory leakage.
+}
+
+TEST(QuicAcrossPathsTransmissionMapTest, MaybeGetTransmissionsOnOtherPaths) {
+ QuicMultipathTransmissionsMap transmission_map;
+ // Packet0's original transmission sent on path 1 with packet number 1.
+ QuicPathIdPacketNumber packet0_0(1, 1);
+ // Packet0's retransmission sent on path 2 with packet number 1.
+ QuicPathIdPacketNumber packet0_1(2, 1);
+ // packet0's 2nd retransmission sent on path 3 with packet number 1.
+ QuicPathIdPacketNumber packet0_2(3, 1);
+
+ transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_0, packet0_1);
+ transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_1, packet0_2);
+
+ const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
+ transmission_list1 =
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0);
+ const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
+ transmission_list2 =
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_1);
+ const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
+ transmission_list3 =
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_2);
+ // Make sure all three pointers point to the same list.
+ EXPECT_EQ(transmission_list1, transmission_list2);
+ EXPECT_EQ(transmission_list2, transmission_list3);
+ EXPECT_EQ(packet0_0, (*transmission_list1)[0]);
+ EXPECT_EQ(packet0_1, (*transmission_list1)[1]);
+ EXPECT_EQ(packet0_2, (*transmission_list1)[2]);
+
+ // Packet1 which is not transmitted across path.
+ QuicPathIdPacketNumber packet1_0(1, 2);
+ EXPECT_EQ(nullptr,
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_0));
+ // Make sure there is no memory leakage.
+}
+
+TEST(QuicAcrossPathsTransmissionMapTest, OnPacketHandled) {
+ QuicMultipathTransmissionsMap transmission_map;
+
+ // Packet's original transmission sent on path 1 with packet number 1.
+ QuicPathIdPacketNumber packet0_0(1, 1);
+ // Packet's retransmission sent on path 2 with packet number 1.
+ QuicPathIdPacketNumber packet0_1(2, 1);
+ // packet's 2nd retransmission sent on path 3 with packet number 1.
+ QuicPathIdPacketNumber packet0_2(3, 1);
+ transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_0, packet0_1);
+ transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_1, packet0_2);
+
+ // Packet1's original transmission sent on path 1 with packet number 2.
+ QuicPathIdPacketNumber packet1_0(1, 2);
+ // Packet1's retransmission sent on path 2 with packet number 2.
+ QuicPathIdPacketNumber packet1_1(2, 2);
+ transmission_map.OnPacketRetransmittedOnDifferentPath(packet1_0, packet1_1);
+
+ transmission_map.OnPacketHandled(packet0_0);
+ EXPECT_EQ(nullptr,
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0));
+ EXPECT_EQ(nullptr,
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_1));
+ EXPECT_EQ(nullptr,
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_2));
+ const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
+ transmission_list =
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_0);
+ EXPECT_EQ(packet1_0, (*transmission_list)[0]);
+ EXPECT_EQ(packet1_1, (*transmission_list)[1]);
+ // Packet 1 is received on path 2.
+ transmission_map.OnPacketHandled(packet1_1);
+ EXPECT_EQ(nullptr,
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_0));
+ EXPECT_EQ(nullptr,
+ transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_1));
+ // Make sure there is no memory leakage.
+}
+
+} // namespace
+} // namespace test
+} // namespace net_quic
diff --git a/chromium/net/quic/quic_network_transaction_unittest.cc b/chromium/net/quic/quic_network_transaction_unittest.cc
index a9da2e68bf6..d6f5c3c2c46 100644
--- a/chromium/net/quic/quic_network_transaction_unittest.cc
+++ b/chromium/net/quic/quic_network_transaction_unittest.cc
@@ -4,15 +4,19 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
+#include "net/base/chunked_upload_data_stream.h"
#include "net/base/network_quality_estimator.h"
#include "net/base/socket_performance_watcher.h"
#include "net/base/test_completion_callback.h"
#include "net/base/test_data_directory.h"
#include "net/cert/mock_cert_verifier.h"
+#include "net/cert/multi_log_ct_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
@@ -55,24 +59,20 @@ namespace test {
namespace {
-static const char kQuicAlternateProtocolHttpHeader[] =
- "Alternate-Protocol: 80:quic\r\n\r\n";
-static const char kQuicAlternateProtocol50pctHttpHeader[] =
- "Alternate-Protocol: 80:quic,p=.5\r\n\r\n";
-static const char kQuicAlternateProtocolDifferentPortHttpHeader[] =
- "Alternate-Protocol: 137:quic\r\n\r\n";
-static const char kQuicAlternateProtocolHttpsHeader[] =
+static const char kQuicAlternateProtocolHeader[] =
"Alternate-Protocol: 443:quic\r\n\r\n";
-static const char kQuicAlternativeServiceHttpHeader[] =
- "Alt-Svc: quic=\":80\"\r\n\r\n";
-static const char kQuicAlternativeService50pctHttpHeader[] =
- "Alt-Svc: quic=\":80\";p=\".5\"\r\n\r\n";
-static const char kQuicAlternativeServiceDifferentPortHttpHeader[] =
- "Alt-Svc: quic=\":137\"\r\n\r\n";
-static const char kQuicAlternativeServiceHttpsHeader[] =
+static const char kQuicAlternateProtocol50pctHeader[] =
+ "Alternate-Protocol: 443:quic,p=.5\r\n\r\n";
+static const char kQuicAlternateProtocolDifferentPortHeader[] =
+ "Alternate-Protocol: 137:quic\r\n\r\n";
+static const char kQuicAlternativeServiceHeader[] =
"Alt-Svc: quic=\":443\"\r\n\r\n";
+static const char kQuicAlternativeService50pctHeader[] =
+ "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
+static const char kQuicAlternativeServiceDifferentPortHeader[] =
+ "Alt-Svc: quic=\":137\"\r\n\r\n";
-const char kDefaultServerHostName[] = "www.google.com";
+const char kDefaultServerHostName[] = "mail.example.com";
} // namespace
@@ -82,9 +82,7 @@ class MockQuicData {
public:
MockQuicData() : packet_number_(0) {}
- ~MockQuicData() {
- STLDeleteElements(&packets_);
- }
+ ~MockQuicData() { STLDeleteElements(&packets_); }
void AddSynchronousRead(scoped_ptr<QuicEncryptedPacket> packet) {
reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
@@ -109,14 +107,14 @@ class MockQuicData {
}
void AddSocketDataToFactory(MockClientSocketFactory* factory) {
- MockRead* reads = reads_.empty() ? nullptr : &reads_[0];
- MockWrite* writes = writes_.empty() ? nullptr : &writes_[0];
+ MockRead* reads = reads_.empty() ? nullptr : &reads_[0];
+ MockWrite* writes = writes_.empty() ? nullptr : &writes_[0];
socket_data_.reset(
new SequencedSocketData(reads, reads_.size(), writes, writes_.size()));
factory->AddSocketDataProvider(socket_data_.get());
}
- void CompleteRead() { socket_data_->CompleteRead(); }
+ void Resume() { socket_data_->Resume(); }
private:
std::vector<QuicEncryptedPacket*> packets_;
@@ -141,59 +139,47 @@ class ProxyHeadersHandler {
bool was_called_;
};
-class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
+class TestNetworkQualityEstimator : public NetworkQualityEstimator {
public:
- TestSocketPerformanceWatcher()
- : received_updated_rtt_available_notification_(false) {}
+ TestNetworkQualityEstimator()
+ : NetworkQualityEstimator(scoped_ptr<net::ExternalEstimateProvider>(),
+ std::map<std::string, std::string>()),
+ watcher_count_(0) {}
- ~TestSocketPerformanceWatcher() override {}
+ ~TestNetworkQualityEstimator() override {}
- void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
- received_updated_rtt_available_notification_ = true;
+ scoped_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
+ const Protocol protocol) override {
+ if (protocol != PROTOCOL_QUIC) {
+ NOTIMPLEMENTED();
+ }
+ ++watcher_count_;
+ return NetworkQualityEstimator::CreateSocketPerformanceWatcher(protocol);
}
- bool received_updated_rtt_available_notification() const {
- return received_updated_rtt_available_notification_;
- }
+ size_t watcher_count() const { return watcher_count_; }
private:
- bool received_updated_rtt_available_notification_;
- DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
+ size_t watcher_count_;
+ DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator);
};
-class TestNetworkQualityEstimator : public NetworkQualityEstimator {
+class TestRTTObserver : public NetworkQualityEstimator::RTTObserver {
public:
- TestNetworkQualityEstimator()
- : NetworkQualityEstimator(scoped_ptr<net::ExternalEstimateProvider>(),
- std::map<std::string, std::string>()) {}
-
- ~TestNetworkQualityEstimator() override {}
-
- scoped_ptr<SocketPerformanceWatcher> CreateUDPSocketPerformanceWatcher()
- const override {
- TestSocketPerformanceWatcher* watcher = new TestSocketPerformanceWatcher();
- watchers_.push_back(watcher);
- return scoped_ptr<TestSocketPerformanceWatcher>(watcher);
- }
+ TestRTTObserver() : rtt_notification_received_(false) {}
- scoped_ptr<SocketPerformanceWatcher> CreateTCPSocketPerformanceWatcher()
- const override {
- NOTIMPLEMENTED();
- return nullptr;
- }
+ bool rtt_notification_received() const { return rtt_notification_received_; }
- bool IsRTTAvailableNotificationReceived() const {
- for (const auto& watcher : watchers_)
- if (watcher->received_updated_rtt_available_notification())
- return true;
- return false;
+ // NetworkQualityEstimator::RttObserver implementation:
+ void OnRTTObservation(
+ int32_t rtt_ms,
+ const base::TimeTicks& timestamp,
+ net::NetworkQualityEstimator::ObservationSource source) override {
+ rtt_notification_received_ = true;
}
- size_t GetWatchersCreated() const { return watchers_.size(); }
-
private:
- mutable std::vector<TestSocketPerformanceWatcher*> watchers_;
- DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator);
+ bool rtt_notification_received_;
};
class QuicNetworkTransactionTest
@@ -203,19 +189,26 @@ class QuicNetworkTransactionTest
QuicNetworkTransactionTest()
: clock_(new MockClock),
maker_(GetParam(), 0, clock_, kDefaultServerHostName),
+ cert_transparency_verifier_(new MultiLogCTVerifier()),
test_network_quality_estimator_(new TestNetworkQualityEstimator()),
ssl_config_service_(new SSLConfigServiceDefaults),
proxy_service_(ProxyService::CreateDirect()),
auth_handler_factory_(
HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
random_generator_(0),
- hanging_data_(nullptr, 0, nullptr, 0) {
+ ssl_data_(ASYNC, OK) {
request_.method = "GET";
- std::string url("http://");
+ std::string url("https://");
url.append(kDefaultServerHostName);
request_.url = GURL(url);
request_.load_flags = 0;
clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
+ verify_details_.cert_verify_result.verified_cert = cert;
+ verify_details_.cert_verify_result.is_issued_by_known_root = true;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
}
void SetUp() override {
@@ -240,19 +233,72 @@ class QuicNetworkTransactionTest
scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
QuicPacketNumber largest_received,
QuicPacketNumber least_unacked) {
- return maker_.MakeAckPacket(2, largest_received, least_unacked, true);
+ return maker_.MakeAckPacket(2, largest_received, least_unacked,
+ least_unacked, true);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
+ QuicPacketNumber largest_received,
+ QuicPacketNumber least_unacked,
+ QuicTestPacketMaker* maker) {
+ return maker->MakeAckPacket(2, largest_received, least_unacked,
+ least_unacked, true);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructAckAndConnectionClosePacket(
+ QuicPacketNumber packet_number,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber ack_least_unacked,
+ QuicPacketNumber stop_least_unacked) {
+ return maker_.MakeAckPacket(packet_number, largest_received,
+ ack_least_unacked, stop_least_unacked, true);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructAckAndConnectionClosePacket(
+ QuicPacketNumber num,
+ QuicTime::Delta delta_time_largest_observed,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber least_unacked,
+ QuicErrorCode quic_error,
+ std::string& quic_error_details) {
+ return maker_.MakeAckAndConnectionClosePacket(
+ num, false, delta_time_largest_observed, largest_received,
+ least_unacked, quic_error, quic_error_details);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
+ QuicPacketNumber num,
+ bool include_version,
+ QuicStreamId stream_id,
+ QuicRstStreamErrorCode error_code) {
+ return maker_.MakeRstPacket(num, include_version, stream_id, error_code);
}
+ // Uses default QuicTestPacketMaker.
SpdyHeaderBlock GetRequestHeaders(const std::string& method,
const std::string& scheme,
const std::string& path) {
- return maker_.GetRequestHeaders(method, scheme, path);
+ return GetRequestHeaders(method, scheme, path, maker_);
+ }
+
+ // Uses customized QuicTestPacketMaker.
+ SpdyHeaderBlock GetRequestHeaders(const std::string& method,
+ const std::string& scheme,
+ const std::string& path,
+ QuicTestPacketMaker& maker) {
+ return maker.GetRequestHeaders(method, scheme, path);
}
SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
return maker_.GetResponseHeaders(status);
}
+ // Appends alt_svc headers in the response headers.
+ SpdyHeaderBlock GetResponseHeaders(const std::string& status,
+ const std::string& alt_svc) {
+ return maker_.GetResponseHeaders(status, alt_svc);
+ }
+
scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
@@ -269,12 +315,50 @@ class QuicNetworkTransactionTest
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- const SpdyHeaderBlock& headers) {
- QuicPriority priority =
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset) {
+ SpdyPriority priority =
ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
- return maker_.MakeRequestHeadersPacket(packet_number, stream_id,
- should_include_version, fin,
- priority, headers);
+ return maker_.MakeRequestHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, priority,
+ headers, offset);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset,
+ QuicTestPacketMaker* maker) {
+ SpdyPriority priority =
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
+ return maker->MakeRequestHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, priority,
+ headers, offset);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers) {
+ return ConstructRequestHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, &maker_);
+ }
+ scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicTestPacketMaker* maker) {
+ return ConstructRequestHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, maker);
}
scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
@@ -283,14 +367,48 @@ class QuicNetworkTransactionTest
bool should_include_version,
bool fin,
const SpdyHeaderBlock& headers) {
- return maker_.MakeResponseHeadersPacket(
- packet_number, stream_id, should_include_version, fin, headers);
+ return ConstructResponseHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, &maker_);
}
- void CreateSession() {
- CreateSessionWithFactory(&socket_factory_, false);
+ scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicTestPacketMaker* maker) {
+ return ConstructResponseHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, maker);
}
+ scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset) {
+ return maker_.MakeResponseHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, headers, offset);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset,
+ QuicTestPacketMaker* maker) {
+ return maker->MakeResponseHeadersPacketWithOffsetTracking(
+ packet_number, stream_id, should_include_version, fin, headers, offset);
+ }
+
+ void CreateSession() { CreateSessionWithFactory(&socket_factory_, false); }
+
void CreateSessionWithNextProtos() {
CreateSessionWithFactory(&socket_factory_, true);
}
@@ -306,6 +424,7 @@ class QuicNetworkTransactionTest
params_.host_resolver = &host_resolver_;
params_.cert_verifier = &cert_verifier_;
params_.transport_security_state = &transport_security_state_;
+ params_.cert_transparency_verifier = cert_transparency_verifier_.get();
params_.socket_performance_watcher_factory =
test_network_quality_estimator_.get();
params_.proxy_service = proxy_service_.get();
@@ -313,13 +432,21 @@ class QuicNetworkTransactionTest
params_.http_auth_handler_factory = auth_handler_factory_.get();
params_.http_server_properties = http_server_properties_.GetWeakPtr();
params_.quic_supported_versions = SupportedVersions(GetParam());
+ for (const char* host :
+ {kDefaultServerHostName, "www.example.com", "news.example.com",
+ "bar.example.com", "foo.example.com", "www.example.org",
+ "invalid.example.org", "docs.example.org"}) {
+ params_.quic_host_whitelist.insert(host);
+ }
+
+ test_network_quality_estimator_->AddRTTObserver(&rtt_observer_);
if (use_next_protos) {
params_.use_alternative_services = true;
params_.next_protos = NextProtosWithSpdyAndQuic(true, true);
}
- session_ = new HttpNetworkSession(params_);
+ session_.reset(new HttpNetworkSession(params_));
session_->quic_stream_factory()->set_require_confirmation(false);
ASSERT_EQ(params_.quic_socket_receive_buffer_size,
session_->quic_stream_factory()->socket_receive_buffer_size());
@@ -337,7 +464,7 @@ class QuicNetworkTransactionTest
}
void CheckResponsePort(const scoped_ptr<HttpNetworkTransaction>& trans,
- uint16 port) {
+ uint16_t port) {
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != nullptr);
EXPECT_EQ(port, response->socket_address.port());
@@ -377,17 +504,17 @@ class QuicNetworkTransactionTest
}
void SendRequestAndExpectQuicResponse(const std::string& expected) {
- SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 80);
+ SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
}
void SendRequestAndExpectQuicResponseOnPort(const std::string& expected,
- uint16 port) {
+ uint16_t port) {
SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, port);
}
void SendRequestAndExpectQuicResponseFromProxyOnPort(
const std::string& expected,
- uint16 port) {
+ uint16_t port) {
SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
}
@@ -395,7 +522,7 @@ class QuicNetworkTransactionTest
MockCryptoClientStream::HandshakeMode handshake_mode) {
crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
HostPortPair host_port_pair = HostPortPair::FromURL(request_.url);
- AlternativeService alternative_service(QUIC, host_port_pair.host(), 80);
+ AlternativeService alternative_service(QUIC, host_port_pair.host(), 443);
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties_.SetAlternativeService(
host_port_pair, alternative_service, 1.0, expiration);
@@ -419,20 +546,27 @@ class QuicNetworkTransactionTest
}
void AddHangingNonAlternateProtocolSocketData() {
+ scoped_ptr<StaticSocketDataProvider> hanging_data;
+ hanging_data.reset(new StaticSocketDataProvider());
MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
- hanging_data_.set_connect_data(hanging_connect);
- socket_factory_.AddSocketDataProvider(&hanging_data_);
+ hanging_data->set_connect_data(hanging_connect);
+ hanging_data_.push_back(std::move(hanging_data));
+ socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
}
MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
QuicTestPacketMaker maker_;
- scoped_refptr<HttpNetworkSession> session_;
+ scoped_ptr<HttpNetworkSession> session_;
MockClientSocketFactory socket_factory_;
+ ProofVerifyDetailsChromium verify_details_;
MockCryptoClientStreamFactory crypto_client_stream_factory_;
MockHostResolver host_resolver_;
MockCertVerifier cert_verifier_;
TransportSecurityState transport_security_state_;
+ scoped_ptr<CTVerifier> cert_transparency_verifier_;
scoped_ptr<TestNetworkQualityEstimator> test_network_quality_estimator_;
+ TestRTTObserver rtt_observer_;
scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
scoped_ptr<ProxyService> proxy_service_;
scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
@@ -441,13 +575,14 @@ class QuicNetworkTransactionTest
HttpNetworkSession::Params params_;
HttpRequestInfo request_;
BoundTestNetLog net_log_;
- StaticSocketDataProvider hanging_data_;
+ std::vector<scoped_ptr<StaticSocketDataProvider>> hanging_data_;
+ SSLSocketDataProvider ssl_data_;
private:
void SendRequestAndExpectQuicResponseMaybeFromProxy(
const std::string& expected,
bool used_proxy,
- uint16 port) {
+ uint16_t port) {
scoped_ptr<HttpNetworkTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
ProxyHeadersHandler proxy_headers_handler;
@@ -462,26 +597,24 @@ class QuicNetworkTransactionTest
}
};
-INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest,
+INSTANTIATE_TEST_CASE_P(Version,
+ QuicNetworkTransactionTest,
::testing::ValuesIn(QuicSupportedVersions()));
TEST_P(QuicNetworkTransactionTest, ForceQuic) {
- // TODO(rch): switch these tests to use secure QUIC.
- params_.enable_insecure_quic = true;
params_.origin_to_force_quic_on =
- HostPortPair::FromString("www.google.com:80");
+ HostPortPair::FromString("mail.example.com:443");
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
- mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -491,11 +624,9 @@ TEST_P(QuicNetworkTransactionTest, ForceQuic) {
CreateSession();
- EXPECT_FALSE(
- test_network_quality_estimator_->IsRTTAvailableNotificationReceived());
+ EXPECT_FALSE(rtt_observer_.rtt_notification_received());
SendRequestAndExpectQuicResponse("hello!");
- EXPECT_TRUE(
- test_network_quality_estimator_->IsRTTAvailableNotificationReceived());
+ EXPECT_TRUE(rtt_observer_.rtt_notification_received());
// Check that the NetLog was filled reasonably.
TestNetLogEntry::List entries;
@@ -537,35 +668,33 @@ TEST_P(QuicNetworkTransactionTest, ForceQuic) {
}
TEST_P(QuicNetworkTransactionTest, QuicProxy) {
- params_.enable_insecure_quic = true;
params_.enable_quic_for_proxies = true;
- proxy_service_ = ProxyService::CreateFixedFromPacResult("QUIC myproxy:70");
+ proxy_service_ =
+ ProxyService::CreateFixedFromPacResult("QUIC mail.example.com:70");
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
- EXPECT_FALSE(
- test_network_quality_estimator_->IsRTTAvailableNotificationReceived());
+ EXPECT_FALSE(rtt_observer_.rtt_notification_received());
// There is no need to set up an alternate protocol job, because
// no attempt will be made to speak to the proxy over TCP.
+ request_.url = GURL("http://mail.example.com/");
CreateSession();
SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
- EXPECT_TRUE(
- test_network_quality_estimator_->IsRTTAvailableNotificationReceived());
+ EXPECT_TRUE(rtt_observer_.rtt_notification_received());
}
// Regression test for https://crbug.com/492458. Test that for an HTTP
@@ -575,7 +704,6 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
const std::string origin_host = "news.example.com";
const std::string proxy_host = "www.example.org";
- params_.enable_insecure_quic = true;
params_.enable_quic_for_proxies = true;
proxy_service_ =
ProxyService::CreateFixedFromPacResult("QUIC " + proxy_host + ":70");
@@ -591,7 +719,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0);
+ mock_quic_data.AddRead(ASYNC, 0);
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
scoped_refptr<X509Certificate> cert(
@@ -604,6 +732,9 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
ProofVerifyDetailsChromium verify_details;
verify_details.cert_verify_result.verified_cert = cert;
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ ProofVerifyDetailsChromium verify_details2;
+ verify_details2.cert_verify_result.verified_cert = cert;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
request_.url = GURL("http://" + origin_host);
AddHangingNonAlternateProtocolSocketData();
@@ -613,22 +744,23 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
}
TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
- params_.enable_insecure_quic = true;
params_.origin_to_force_quic_on =
- HostPortPair::FromString("www.google.com:80");
+ HostPortPair::FromString("mail.example.com:443");
MockQuicData mock_quic_data1;
mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
MockQuicData mock_quic_data2;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
CreateSession();
- EXPECT_EQ(0U, test_network_quality_estimator_->GetWatchersCreated());
+ EXPECT_EQ(0U, test_network_quality_estimator_->watcher_count());
for (size_t i = 0; i < 2; ++i) {
scoped_ptr<HttpNetworkTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
@@ -636,7 +768,7 @@ TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
- EXPECT_EQ(1 + i, test_network_quality_estimator_->GetWatchersCreated());
+ EXPECT_EQ(1 + i, test_network_quality_estimator_->watcher_count());
}
}
@@ -646,11 +778,9 @@ TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
HostPortPair::FromString("www.google.com:443");
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n\r\n"),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
StaticSocketDataProvider data(http_reads, arraysize(http_reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&data);
@@ -660,33 +790,32 @@ TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
CreateSession();
SendRequestAndExpectHttpResponse("hello world");
- EXPECT_EQ(0U, test_network_quality_estimator_->GetWatchersCreated());
+ EXPECT_EQ(0U, test_network_quality_estimator_->watcher_count());
}
TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternativeServiceHttpHeader), MockRead("hello world"),
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
+ MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -697,17 +826,11 @@ TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
SendRequestAndExpectQuicResponse("hello!");
}
-// When multiple alternative services are advertised,
-// HttpStreamFactoryImpl::RequestStreamInternal() only passes the first one to
-// Job. This is what the following test verifies.
-// TODO(bnc): Update this test when multiple alternative services are handled
-// properly.
-TEST_P(QuicNetworkTransactionTest, UseFirstAlternativeServiceForQuic) {
- params_.enable_insecure_quic = true;
-
+TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceQuicSupportedVersion) {
+ std::string altsvc_header = base::StringPrintf(
+ "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", GetParam());
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Alt-Svc: quic=\":443\", quic=\":1234\"\r\n\r\n"),
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
@@ -715,18 +838,19 @@ TEST_P(QuicNetworkTransactionTest, UseFirstAlternativeServiceForQuic) {
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -734,15 +858,373 @@ TEST_P(QuicNetworkTransactionTest, UseFirstAlternativeServiceForQuic) {
CreateSessionWithNextProtos();
SendRequestAndExpectHttpResponse("hello world");
+ SendRequestAndExpectQuicResponse("hello!");
+}
+
+TEST_P(QuicNetworkTransactionTest,
+ DoNotUseAlternativeServiceQuicUnsupportedVersion) {
+ std::string altsvc_header = base::StringPrintf(
+ "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", GetParam() - 1);
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ CreateSessionWithNextProtos();
+
+ SendRequestAndExpectHttpResponse("hello world");
+ 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.
+TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\"foo.example.com:443\", quic=\":444\"\r\n\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ QuicStreamOffset request_header_offset = 0;
+ QuicStreamOffset response_header_offset = 0;
+ // First QUIC request data.
+ // Open a session to foo.example.com:443 using the first entry of the
+ // alternative service list.
+ MockQuicData mock_quic_data;
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+
+ std::string alt_svc_list =
+ "quic=\"mail.example.com:444\", quic=\"foo.example.com:443\", "
+ "quic=\"bar.example.com:445\"";
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
+ mock_quic_data.AddRead(
+ ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+
+ // Second QUIC request data.
+ // Connection pooling, using existing session, no need to include version
+ // as version negotiation has been completed.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 3, kClientDataStreamId2, false, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 3, kClientDataStreamId2, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(
+ ConstructDataPacket(4, kClientDataStreamId2, false, true, 0, "hello!"));
+ mock_quic_data.AddWrite(ConstructAckAndConnectionClosePacket(4, 4, 3, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+
+ AddHangingNonAlternateProtocolSocketData();
+ CreateSessionWithNextProtos();
+
+ SendRequestAndExpectHttpResponse("hello world");
+
+ SendRequestAndExpectQuicResponseOnPort("hello!", 443);
SendRequestAndExpectQuicResponseOnPort("hello!", 443);
}
-TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
- params_.enable_insecure_quic = true;
+// When multiple alternative services that has existing QUIC session.
+// HttpStreamFactoryImpl::RequestStreamInternal() should select the first
+// alternative service which uses existing QUIC session.
+TEST_P(QuicNetworkTransactionTest, UseFirstExistingAlternativeServiceForQuic) {
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\"foo.example.com:443\", quic=\":446\"\r\n\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ QuicStreamOffset request_header_offset = 0;
+ QuicStreamOffset response_header_offset = 0;
+
+ QuicTestPacketMaker maker(GetParam(), 0, clock_, kDefaultServerHostName);
+
+ MockQuicData mock_quic_data;
+ MockQuicData mock_quic_data2;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
+ // First QUIC request data.
+ // Open a QUIC session to foo.example.com:443.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+
+ std::string alt_svc_list =
+ "quic=\"bar.example.com:444\", quic=\"frog.example.com:445\", "
+ "quic=\"mail.example.com:446\"";
+ // Response header from the server resets the alt_svc list for the origin.
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from foo!"));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+
+ // Second QUIC request data.
+ // Existing QUIC session to foo.example.com is not viable from the updated
+ // alt_svc. Unable to pool the existing QUIC session.
+ // Open a new QUIC session to bar.example.com:443.
+ mock_quic_data2.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &maker));
+ alt_svc_list =
+ "quic=\"foo.example.com:443\", quic=\"mail.example.com:446\", "
+ "quic=\"bar.example.com:444\"";
+ // Response header from the server resets the alt_svc list for the origin.
+ mock_quic_data2.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK", alt_svc_list), &maker));
+ mock_quic_data2.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from bar!"));
+ mock_quic_data2.AddWrite(ConstructAckPacket(2, 1, &maker));
+ mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data2.AddRead(ASYNC, 0); // EOF
+
+ // Third QUIC request data.
+ // Connection pooling, using the first existing session to foo.example.com
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 3, kClientDataStreamId2, false, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 3, kClientDataStreamId2, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(4, kClientDataStreamId2, false,
+ true, 0, "hello from foo!"));
+ mock_quic_data.AddWrite(ConstructAckAndConnectionClosePacket(4, 4, 3, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
+
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSessionWithNextProtos();
+
+ SendRequestAndExpectHttpResponse("hello world");
+ SendRequestAndExpectQuicResponseOnPort("hello from foo!", 443);
+ SendRequestAndExpectQuicResponseOnPort("hello from bar!", 444);
+ SendRequestAndExpectQuicResponseOnPort("hello from foo!", 443);
+}
+
+// Multiple origins have listed the same alternative services. When there's a
+// existing QUIC session opened by a request to other origin,
+// if the cert is valid, should select this QUIC session to make the request
+// if this is also the first existing QUIC session.
+TEST_P(QuicNetworkTransactionTest,
+ UseSharedExistingAlternativeServiceForQuicWithValidCert) {
+ // Default cert is valid for the following origins:
+ // mail.example.com, mail.example.org, and www.example.org.
+
+ // HTTP data for request to mail.example.com.
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
+ MockRead("hello world from mail.example.com"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ // HTTP data for request to mail.example.org.
+ MockRead http_reads2[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\":444\", quic=\"mail.example.com:443\"\r\n\r\n"),
+ MockRead("hello world from mail.example.org"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data2(http_reads2, arraysize(http_reads2),
+ nullptr, 0);
+ socket_factory_.AddSocketDataProvider(&http_data2);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ QuicStreamOffset request_header_offset = 0;
+ QuicStreamOffset response_header_offset = 0;
+
+ QuicTestPacketMaker maker(GetParam(), 0, clock_, kDefaultServerHostName);
+ maker.set_hostname("mail.example.org");
+ MockQuicData mock_quic_data;
+
+ // First QUIC request data.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from mail QUIC!"));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+
+ // Second QUIC request data.
+ mock_quic_data.AddWrite(ConstructRequestHeadersPacket(
+ 3, kClientDataStreamId2, false, true,
+ GetRequestHeaders("GET", "https", "/", maker), &request_header_offset,
+ &maker));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 3, kClientDataStreamId2, false, false, GetResponseHeaders("200 OK"),
+ &response_header_offset));
+ mock_quic_data.AddRead(ConstructDataPacket(4, kClientDataStreamId2, false,
+ true, 0, "hello from mail QUIC!"));
+ mock_quic_data.AddWrite(ConstructAckAndConnectionClosePacket(4, 4, 3, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSessionWithNextProtos();
+
+ // Send two HTTP requests, responses set up alt-svc lists for the origins.
+ SendRequestAndExpectHttpResponse("hello world from mail.example.com");
+ request_.url = GURL("https://mail.example.org/");
+ SendRequestAndExpectHttpResponse("hello world from mail.example.org");
+
+ // Open a QUIC session to mail.example.com:443 when making request
+ // to mail.example.com.
+ request_.url = GURL("https://mail.example.com/");
+ SendRequestAndExpectQuicResponseOnPort("hello from mail QUIC!", 443);
+
+ // Uses the existing QUIC session when making request to mail.example.org.
+ request_.url = GURL("https://mail.example.org/");
+ SendRequestAndExpectQuicResponseOnPort("hello from mail QUIC!", 443);
+}
+
+// Multiple origins have listed the same alternative services. When there's a
+// existing QUIC session opened by a request to other origin,
+// if the cert is NOT valid, should ignore this QUIC session.
+TEST_P(QuicNetworkTransactionTest,
+ DoNotUseSharedExistingAlternativeServiceForQuicWithInvalidCert) {
+ // Default cert is only valid for the following origins:
+ // mail.example.com, mail.example.org, and www.example.org.
+ // NOT valid for docs.example.org.
+
+ // HTTP data for request to mail.example.com.
MockRead http_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternativeServiceDifferentPortHttpHeader),
+ MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
+ MockRead("hello world from mail.example.com"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ // HTTP data for request to docs.example.org.
+ MockRead http_reads2[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: quic=\":444\", quic=\"mail.example.com:443\"\r\n\r\n"),
+ MockRead("hello world from docs.example.org"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+
+ StaticSocketDataProvider http_data2(http_reads2, arraysize(http_reads2),
+ nullptr, 0);
+ socket_factory_.AddSocketDataProvider(&http_data2);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ QuicTestPacketMaker maker(GetParam(), 0, clock_, kDefaultServerHostName);
+ maker.set_hostname("docs.example.org");
+ MockQuicData mock_quic_data;
+ MockQuicData mock_quic_data2;
+
+ // Adding a valid cert for *.example.org but not mail.example.com.
+ ProofVerifyDetailsChromium verify_details;
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
+ verify_details.cert_verify_result.verified_cert = cert;
+ verify_details.cert_verify_result.is_issued_by_known_root = true;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ // First QUIC request data.
+ mock_quic_data.AddWrite(
+ ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
+ mock_quic_data.AddRead(ConstructDataPacket(2, kClientDataStreamId1, false,
+ true, 0, "hello from mail QUIC!"));
+ mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+
+ // First QUIC request data.
+ mock_quic_data2.AddWrite(ConstructRequestHeadersPacket(
+ 1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/", maker), &maker));
+ mock_quic_data2.AddRead(
+ ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
+ GetResponseHeaders("200 OK"), &maker));
+ mock_quic_data2.AddRead(ConstructDataPacket(
+ 2, kClientDataStreamId1, false, true, 0, "hello from docs QUIC!"));
+ mock_quic_data2.AddWrite(ConstructAckPacket(2, 1, &maker));
+ mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data2.AddRead(ASYNC, 0); // EOF
+
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSessionWithNextProtos();
+
+ // Send HTTP requests, responses set up the alt-svc lists for the origins.
+ SendRequestAndExpectHttpResponse("hello world from mail.example.com");
+ request_.url = GURL("https://docs.example.org/");
+ SendRequestAndExpectHttpResponse("hello world from docs.example.org");
+
+ // Open a QUIC session to mail.example.com:443 when making request
+ // to mail.example.com.
+ request_.url = GURL("https://mail.example.com/");
+ SendRequestAndExpectQuicResponseOnPort("hello from mail QUIC!", 443);
+
+ // Open another new QUIC session to docs.example.org:444.
+ request_.url = GURL("https://docs.example.org/");
+ SendRequestAndExpectQuicResponseOnPort("hello from docs QUIC!", 444);
+}
+
+TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(kQuicAlternativeServiceDifferentPortHeader),
MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
@@ -750,18 +1232,19 @@ TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -773,22 +1256,21 @@ TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
}
TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternativeServiceHttpHeader), MockRead("hello world"),
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
+ MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
@@ -796,7 +1278,6 @@ TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddRead(ASYNC, 0); // EOF
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -813,36 +1294,35 @@ TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
SendRequestAndExpectHttpResponse("hello world");
SendRequestAndExpectQuicResponse("hello!");
- mock_quic_data.CompleteRead();
+ mock_quic_data.Resume();
EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
alternative_service));
}
TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceProbabilityForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternativeService50pctHttpHeader), MockRead("hello world"),
+ MockRead(kQuicAlternativeService50pctHeader), MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -856,18 +1336,18 @@ TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceProbabilityForQuic) {
TEST_P(QuicNetworkTransactionTest,
DontUseAlternativeServiceProbabilityForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternativeService50pctHttpHeader), MockRead("hello world"),
+ MockRead(kQuicAlternativeService50pctHeader), MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
params_.alternative_service_probability_threshold = 0.75;
CreateSessionWithNextProtos();
@@ -876,35 +1356,8 @@ TEST_P(QuicNetworkTransactionTest,
SendRequestAndExpectHttpResponse("hello world");
}
-TEST_P(QuicNetworkTransactionTest, DontUseAlternativeServiceForInsecureQuic) {
- params_.enable_insecure_quic = true;
-
- MockRead http_reads[] = {MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-length: 11\r\n"),
- MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
- MockRead("hello world"),
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-length: 11\r\n"),
- MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
- MockRead("hello world"),
- MockRead(ASYNC, OK)};
-
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
- 0);
- socket_factory_.AddSocketDataProvider(&http_data);
- socket_factory_.AddSocketDataProvider(&http_data);
-
- params_.enable_insecure_quic = false;
- CreateSessionWithNextProtos();
-
- SendRequestAndExpectHttpResponse("hello world");
- SendRequestAndExpectHttpResponse("hello world");
-}
-
TEST_P(QuicNetworkTransactionTest,
DontUseAlternativeServiceWithBadProbabilityForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
MockRead("Alt-Svc: quic=\":443\";p=2\r\n\r\n"), MockRead("hello world"),
@@ -914,7 +1367,9 @@ TEST_P(QuicNetworkTransactionTest,
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
params_.alternative_service_probability_threshold = 0.75;
CreateSessionWithNextProtos();
@@ -924,24 +1379,21 @@ TEST_P(QuicNetworkTransactionTest,
}
TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
- params_.enable_insecure_quic = true;
- params_.origin_to_force_quic_on =
- HostPortPair::FromString("www.google.com:443");
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternativeServiceHttpsHeader), MockRead("hello world"),
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
+ MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
@@ -959,32 +1411,28 @@ TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
}
TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternateProtocolHttpHeader),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternateProtocolHeader),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -999,11 +1447,9 @@ TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
}
TEST_P(QuicNetworkTransactionTest, AlternateProtocolDifferentPort) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternateProtocolDifferentPortHttpHeader),
+ MockRead(kQuicAlternateProtocolDifferentPortHeader),
MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
@@ -1011,18 +1457,19 @@ TEST_P(QuicNetworkTransactionTest, AlternateProtocolDifferentPort) {
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -1037,11 +1484,8 @@ TEST_P(QuicNetworkTransactionTest, AlternateProtocolDifferentPort) {
}
TEST_P(QuicNetworkTransactionTest, ConfirmAlternateProtocol) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternateProtocolHttpHeader),
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternateProtocolHeader),
MockRead("hello world"),
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead(ASYNC, OK)};
@@ -1049,11 +1493,12 @@ TEST_P(QuicNetworkTransactionTest, ConfirmAlternateProtocol) {
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddRead(ConstructResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
@@ -1061,7 +1506,6 @@ TEST_P(QuicNetworkTransactionTest, ConfirmAlternateProtocol) {
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddRead(ASYNC, 0); // EOF
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -1081,39 +1525,34 @@ TEST_P(QuicNetworkTransactionTest, ConfirmAlternateProtocol) {
SendRequestAndExpectHttpResponse("hello world");
SendRequestAndExpectQuicResponse("hello!");
- mock_quic_data.CompleteRead();
+ mock_quic_data.Resume();
EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
alternative_service));
}
TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolProbabilityForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternateProtocol50pctHttpHeader),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(kQuicAlternateProtocol50pctHeader), MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -1129,47 +1568,20 @@ TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolProbabilityForQuic) {
}
TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolProbabilityForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternateProtocol50pctHttpHeader),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
-
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
- socket_factory_.AddSocketDataProvider(&http_data);
- socket_factory_.AddSocketDataProvider(&http_data);
-
- params_.alternative_service_probability_threshold = .75;
- CreateSessionWithNextProtos();
-
- SendRequestAndExpectHttpResponse("hello world");
- SendRequestAndExpectHttpResponse("hello world");
-}
-
-TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolForInsecureQuic) {
- params_.enable_insecure_quic = true;
-
- MockRead http_reads[] = {MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-length: 11\r\n"),
- MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
- MockRead("hello world"),
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-length: 11\r\n"),
- MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
- MockRead("hello world"),
- MockRead(ASYNC, OK)};
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(kQuicAlternateProtocol50pctHeader), MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
- params_.enable_insecure_quic = false;
+ params_.alternative_service_probability_threshold = .75;
CreateSessionWithNextProtos();
SendRequestAndExpectHttpResponse("hello world");
@@ -1178,20 +1590,19 @@ TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolForInsecureQuic) {
TEST_P(QuicNetworkTransactionTest,
DontUseAlternateProtocolWithBadProbabilityForQuic) {
- params_.enable_insecure_quic = true;
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
params_.alternative_service_probability_threshold = .75;
CreateSessionWithNextProtos();
@@ -1201,34 +1612,27 @@ TEST_P(QuicNetworkTransactionTest,
}
TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
- params_.enable_insecure_quic = true;
- params_.origin_to_force_quic_on =
- HostPortPair::FromString("www.google.com:443");
-
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternateProtocolHttpsHeader),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternateProtocolHeader),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -1264,7 +1668,7 @@ class QuicAltSvcCertificateVerificationTest
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
- mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
+ mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
scoped_refptr<X509Certificate> cert(
@@ -1326,78 +1730,70 @@ TEST_P(QuicAltSvcCertificateVerificationTest,
}
TEST_P(QuicNetworkTransactionTest, HungAlternateProtocol) {
- params_.enable_insecure_quic = true;
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::COLD_START);
MockWrite http_writes[] = {
- MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
- MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
- MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
- };
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Host: mail.example.com\r\n"),
+ MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
MockRead http_reads[] = {
- MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
- MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
- MockRead(SYNCHRONOUS, 5, "hello world"),
- MockRead(SYNCHRONOUS, OK, 6)
- };
+ MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
+ MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHeader),
+ MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
- DeterministicMockClientSocketFactory socket_factory;
+ MockClientSocketFactory socket_factory;
- DeterministicSocketData http_data(http_reads, arraysize(http_reads),
- http_writes, arraysize(http_writes));
+ SequencedSocketData http_data(http_reads, arraysize(http_reads), http_writes,
+ arraysize(http_writes));
socket_factory.AddSocketDataProvider(&http_data);
+ socket_factory.AddSSLSocketDataProvider(&ssl_data_);
// The QUIC transaction will not be allowed to complete.
- MockWrite quic_writes[] = {
- MockWrite(ASYNC, ERR_IO_PENDING, 0)
- };
+ MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
MockRead quic_reads[] = {
- MockRead(ASYNC, ERR_IO_PENDING, 1),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
};
- DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
- quic_writes, arraysize(quic_writes));
+ SequencedSocketData quic_data(quic_reads, arraysize(quic_reads), quic_writes,
+ arraysize(quic_writes));
socket_factory.AddSocketDataProvider(&quic_data);
// The HTTP transaction will complete.
- DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
- http_writes, arraysize(http_writes));
+ SequencedSocketData http_data2(http_reads, arraysize(http_reads), http_writes,
+ arraysize(http_writes));
socket_factory.AddSocketDataProvider(&http_data2);
+ socket_factory.AddSSLSocketDataProvider(&ssl_data_);
CreateSessionWithFactory(&socket_factory, true);
// Run the first request.
- http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
SendRequestAndExpectHttpResponse("hello world");
ASSERT_TRUE(http_data.AllReadDataConsumed());
ASSERT_TRUE(http_data.AllWriteDataConsumed());
// Now run the second request in which the QUIC socket hangs,
// and verify the the transaction continues over HTTP.
- http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
SendRequestAndExpectHttpResponse("hello world");
+ base::RunLoop().RunUntilIdle();
ASSERT_TRUE(http_data2.AllReadDataConsumed());
ASSERT_TRUE(http_data2.AllWriteDataConsumed());
- ASSERT_TRUE(!quic_data.AllReadDataConsumed());
- ASSERT_TRUE(!quic_data.AllWriteDataConsumed());
+ ASSERT_TRUE(quic_data.AllReadDataConsumed());
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
- params_.enable_insecure_quic = true;
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -1411,34 +1807,29 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
- params_.enable_insecure_quic = true;
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
// In order for a new QUIC session to be established via alternate-protocol
// without racing an HTTP connection, we need the host resolution to happen
// synchronously.
host_resolver_.set_synchronous_mode(true);
- host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
- HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
+ host_resolver_.rules()->AddIPLiteralRule("mail.example.com", "192.168.0.1",
+ "");
+ HostResolver::RequestInfo info(HostPortPair("mail.example.com", 443));
AddressList address;
- host_resolver_.Resolve(info,
- DEFAULT_PRIORITY,
- &address,
- CompletionCallback(),
- nullptr,
- net_log_.bound());
+ host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
+ nullptr, net_log_.bound());
CreateSessionWithNextProtos();
AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
@@ -1446,22 +1837,18 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
- params_.enable_insecure_quic = true;
proxy_service_ = ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
// Since we are using a proxy, the QUIC job will not succeed.
MockWrite http_writes[] = {
- MockWrite(SYNCHRONOUS, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
- MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
- MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")
- };
+ MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.com/ HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Host: mail.example.com\r\n"),
+ MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
MockRead http_reads[] = {
- MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
- MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
- MockRead(SYNCHRONOUS, 5, "hello world"),
- MockRead(SYNCHRONOUS, OK, 6)
- };
+ MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
+ MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHeader),
+ MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
http_writes, arraysize(http_writes));
@@ -1471,34 +1858,30 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
// without racing an HTTP connection, we need the host resolution to happen
// synchronously.
host_resolver_.set_synchronous_mode(true);
- host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
- HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
+ host_resolver_.rules()->AddIPLiteralRule("mail.example.com", "192.168.0.1",
+ "");
+ HostResolver::RequestInfo info(HostPortPair("mail.example.com", 443));
AddressList address;
- host_resolver_.Resolve(info,
- DEFAULT_PRIORITY,
- &address,
- CompletionCallback(),
- nullptr,
- net_log_.bound());
+ host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
+ nullptr, net_log_.bound());
+ request_.url = GURL("http://mail.example.com/");
CreateSessionWithNextProtos();
AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
SendRequestAndExpectHttpResponse("hello world");
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
- params_.enable_insecure_quic = true;
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
- mock_quic_data.AddRead(
- ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
- GetResponseHeaders("200 OK")));
+ GetRequestHeaders("GET", "https", "/")));
+ mock_quic_data.AddRead(ConstructResponseHeadersPacket(
+ 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
- mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
// The non-alternate protocol job needs to hang in order to guarantee that
@@ -1511,11 +1894,12 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
// connection to the the server, in this test we require confirmation
// before encrypting so the HTTP job will still start.
host_resolver_.set_synchronous_mode(true);
- host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
- HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
+ host_resolver_.rules()->AddIPLiteralRule("mail.example.com", "192.168.0.1",
+ "");
+ HostResolver::RequestInfo info(HostPortPair("mail.example.com", 443));
AddressList address;
- host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
- CompletionCallback(), nullptr, net_log_.bound());
+ host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
+ nullptr, net_log_.bound());
CreateSessionWithNextProtos();
session_->quic_stream_factory()->set_require_confirmation(true);
@@ -1535,8 +1919,110 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
CheckResponseData(trans, "hello!");
}
+TEST_P(QuicNetworkTransactionTest,
+ LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
+ MockQuicData mock_quic_data;
+ mock_quic_data.AddWrite(
+ ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/")));
+ // Read a close connection packet with
+ // QuicErrorCode: QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
+ mock_quic_data.AddRead(ConstructConnectionClosePacket(1));
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+
+ // The non-alternate protocol job needs to hang in order to guarantee that
+ // the alternate-protocol job will "win".
+ AddHangingNonAlternateProtocolSocketData();
+
+ // In order for a new QUIC session to be established via alternate-protocol
+ // without racing an HTTP connection, we need the host resolution to happen
+ // synchronously. Of course, even though QUIC *could* perform a 0-RTT
+ // connection to the the server, in this test we require confirmation
+ // before encrypting so the HTTP job will still start.
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule("mail.example.com", "192.168.0.1",
+ "");
+ HostResolver::RequestInfo info(HostPortPair("mail.example.com", 443));
+ AddressList address;
+ host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
+ nullptr, net_log_.bound());
+
+ CreateSessionWithNextProtos();
+ session_->quic_stream_factory()->set_require_confirmation(true);
+ AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
+
+ scoped_ptr<HttpNetworkTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
+ QuicSession::HANDSHAKE_CONFIRMED);
+ EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
+
+ NetErrorDetails details;
+ EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
+
+ trans->PopulateNetErrorDetails(&details);
+ // Verify the error code logged is what sent by the peer.
+ EXPECT_EQ(QUIC_CRYPTO_VERSION_NOT_SUPPORTED, details.quic_connection_error);
+}
+
+TEST_P(QuicNetworkTransactionTest,
+ LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
+ MockQuicData mock_quic_data;
+ mock_quic_data.AddWrite(
+ ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
+ GetRequestHeaders("GET", "https", "/")));
+ // Peer sending an invalid stream frame with a invalid stream error causes
+ // this end to raise error and close connection.
+ mock_quic_data.AddRead(ConstructRstPacket(1, false, kClientDataStreamId1,
+ QUIC_STREAM_LAST_ERROR));
+ std::string quic_error_details = "Invalid rst stream error code.";
+ mock_quic_data.AddWrite(ConstructAckAndConnectionClosePacket(
+ 2, QuicTime::Delta::Infinite(), 0, 1, QUIC_INVALID_RST_STREAM_DATA,
+ quic_error_details));
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+
+ // The non-alternate protocol job needs to hang in order to guarantee that
+ // the alternate-protocol job will "win".
+ AddHangingNonAlternateProtocolSocketData();
+
+ // In order for a new QUIC session to be established via alternate-protocol
+ // without racing an HTTP connection, we need the host resolution to happen
+ // synchronously. Of course, even though QUIC *could* perform a 0-RTT
+ // connection to the the server, in this test we require confirmation
+ // before encrypting so the HTTP job will still start.
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule("mail.example.com", "192.168.0.1",
+ "");
+ HostResolver::RequestInfo info(HostPortPair("mail.example.com", 443));
+ AddressList address;
+ host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
+ nullptr, net_log_.bound());
+
+ CreateSessionWithNextProtos();
+ session_->quic_stream_factory()->set_require_confirmation(true);
+ AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
+
+ scoped_ptr<HttpNetworkTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
+ QuicSession::HANDSHAKE_CONFIRMED);
+ EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
+ NetErrorDetails details;
+ EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
+
+ trans->PopulateNetErrorDetails(&details);
+ EXPECT_EQ(QUIC_INVALID_RST_STREAM_DATA, details.quic_connection_error);
+}
+
TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
- params_.enable_insecure_quic = true;
// Alternate-protocol job
scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
MockRead quic_reads[] = {
@@ -1544,21 +2030,20 @@ TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
MockRead(ASYNC, OK), // EOF
};
- StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
- nullptr, 0);
+ StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&quic_data);
// Main job which will succeed even though the alternate job fails.
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n\r\n"),
- MockRead("hello from http"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
CreateSessionWithNextProtos();
AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
@@ -1567,26 +2052,24 @@ TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
}
TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
- params_.enable_insecure_quic = true;
// Alternate-protocol job
MockRead quic_reads[] = {
- MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
+ MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
};
- StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
- nullptr, 0);
+ StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&quic_data);
// Main job which will succeed even though the alternate job fails.
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n\r\n"),
- MockRead("hello from http"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
CreateSessionWithNextProtos();
@@ -1596,24 +2079,24 @@ TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
}
TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
- params_.enable_insecure_quic = true;
// Alternate-protocol job will fail when the session attempts to read.
MockRead quic_reads[] = {
- MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
+ MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
};
- StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
- nullptr, 0);
+ StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&quic_data);
// Main job will also fail.
MockRead http_reads[] = {
- MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
+ MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
CreateSessionWithNextProtos();
@@ -1628,13 +2111,12 @@ TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
}
TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
- params_.enable_insecure_quic = true;
// Alternate-protocol job
MockRead quic_reads[] = {
- MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
+ MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
};
- StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
- nullptr, 0);
+ StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&quic_data);
AddHangingNonAlternateProtocolSocketData();
@@ -1646,15 +2128,14 @@ TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
// Final job that will proceed when the QUIC job fails.
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n\r\n"),
- MockRead("hello from http"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
CreateSessionWithNextProtos();
@@ -1669,25 +2150,22 @@ TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
}
TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
- params_.enable_insecure_quic = true;
// Alternate-protocol job
MockRead quic_reads[] = {
- MockRead(ASYNC, ERR_IO_PENDING),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING),
};
- StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
- nullptr, 0);
+ StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&quic_data);
// Main job that will proceed when the QUIC job fails.
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n\r\n"),
- MockRead("hello from http"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
CreateSessionWithNextProtos();
@@ -1698,24 +2176,22 @@ TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
}
TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
- params_.enable_insecure_quic = true;
// Alternate-protocol job will fail before creating a QUIC session.
StaticSocketDataProvider quic_data(nullptr, 0, nullptr, 0);
- quic_data.set_connect_data(MockConnect(SYNCHRONOUS,
- ERR_INTERNET_DISCONNECTED));
+ quic_data.set_connect_data(
+ MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED));
socket_factory_.AddSocketDataProvider(&quic_data);
// Main job which will succeed even though the alternate job fails.
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n\r\n"),
- MockRead("hello from http"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
CreateSessionWithNextProtos();
AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
@@ -1725,53 +2201,45 @@ TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
}
TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
- params_.enable_insecure_quic = true;
MockQuicData mock_quic_data;
mock_quic_data.AddSynchronousRead(ConstructConnectionClosePacket(1));
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "http", "/")));
+ GetRequestHeaders("GET", "https", "/")));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
// When the QUIC connection fails, we will try the request again over HTTP.
MockRead http_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(kQuicAlternateProtocolHttpHeader),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternateProtocolHeader),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
- StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
- nullptr, 0);
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr,
+ 0);
socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
// In order for a new QUIC session to be established via alternate-protocol
// without racing an HTTP connection, we need the host resolution to happen
// synchronously.
host_resolver_.set_synchronous_mode(true);
- host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
- HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
+ host_resolver_.rules()->AddIPLiteralRule("mail.example.com", "192.168.0.1",
+ "");
+ HostResolver::RequestInfo info(HostPortPair("mail.example.com", 443));
AddressList address;
- host_resolver_.Resolve(info,
- DEFAULT_PRIORITY,
- &address,
- CompletionCallback(),
- nullptr,
- net_log_.bound());
+ host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
+ nullptr, net_log_.bound());
CreateSessionWithNextProtos();
AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
SendRequestAndExpectHttpResponse("hello world");
}
-// Test that a secure request over an insecure QUIC connection fails with
-// the appropriate error code. Note that this never happens in production,
-// because the handshake (which this test mocks) would fail in this scenario.
-TEST_P(QuicNetworkTransactionTest, SecureResourceOverInsecureQuic) {
- params_.enable_insecure_quic = true;
+TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
maker_.set_hostname("www.example.org");
+ EXPECT_FALSE(rtt_observer_.rtt_notification_received());
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
@@ -1781,55 +2249,44 @@ TEST_P(QuicNetworkTransactionTest, SecureResourceOverInsecureQuic) {
mock_quic_data.AddRead(
ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
- mock_quic_data.AddRead(SYNCHRONOUS, 0);
+ mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
request_.url = GURL("https://www.example.org:443");
AddHangingNonAlternateProtocolSocketData();
CreateSessionWithNextProtos();
AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
- scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
- TestCompletionCallback callback;
- int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
- EXPECT_EQ(ERR_REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC,
- callback.GetResult(rv));
+ SendRequestAndExpectQuicResponse("hello!");
+ EXPECT_TRUE(rtt_observer_.rtt_notification_received());
}
-TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
- params_.enable_insecure_quic = true;
- maker_.set_hostname("www.example.org");
- EXPECT_FALSE(
- test_network_quality_estimator_->IsRTTAvailableNotificationReceived());
- MockQuicData mock_quic_data;
- mock_quic_data.AddWrite(
- ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
- GetRequestHeaders("GET", "https", "/")));
- mock_quic_data.AddRead(ConstructResponseHeadersPacket(
- 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
- mock_quic_data.AddRead(
- ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
- mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
- mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
- mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+TEST_P(QuicNetworkTransactionTest, QuicUpload) {
+ params_.origin_to_force_quic_on =
+ HostPortPair::FromString("mail.example.com:443");
- scoped_refptr<X509Certificate> cert(
- ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
- ASSERT_TRUE(cert.get());
- bool common_name_fallback_used;
- EXPECT_TRUE(
- cert->VerifyNameMatch("www.example.org", &common_name_fallback_used));
- ProofVerifyDetailsChromium verify_details;
- verify_details.cert_verify_result.verified_cert = cert;
- crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
- request_.url = GURL("https://www.example.org:443");
+ // The non-alternate protocol job needs to hang in order to guarantee that
+ // the alternate-protocol job will "win".
AddHangingNonAlternateProtocolSocketData();
- CreateSessionWithNextProtos();
- AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
- SendRequestAndExpectQuicResponse("hello!");
- EXPECT_TRUE(
- test_network_quality_estimator_->IsRTTAvailableNotificationReceived());
+
+ CreateSession();
+ request_.method = "POST";
+ ChunkedUploadDataStream upload_data(0);
+ upload_data.AppendData("1", 1, true);
+
+ request_.upload_data_stream = &upload_data;
+
+ scoped_ptr<HttpNetworkTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_NE(OK, callback.WaitForResult());
}
} // namespace test
diff --git a/chromium/net/quic/quic_packet_creator.cc b/chromium/net/quic/quic_packet_creator.cc
index 3dcfe6e06b9..35072e9de66 100644
--- a/chromium/net/quic/quic_packet_creator.cc
+++ b/chromium/net/quic/quic_packet_creator.cc
@@ -6,12 +6,13 @@
#include <algorithm>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "net/quic/crypto/quic_random.h"
-#include "net/quic/quic_ack_notifier.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_data_writer.h"
#include "net/quic/quic_fec_group.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
using base::StringPiece;
@@ -30,6 +31,20 @@ static const size_t kDefaultMaxPacketsPerFecGroup = 10;
// Lowest max packets in an FEC group.
static const size_t kLowestMaxPacketsPerFecGroup = 2;
+// We want to put some space between a protected packet and the FEC packet to
+// avoid losing them both within the same loss episode. On the other hand, we
+// expect to be able to recover from any loss in about an RTT. We resolve this
+// tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half
+// the max number of in-flight packets, the first protected packet. Since we
+// don't want to delay an FEC packet past half an RTT, we set the max FEC group
+// size to be half the current congestion window.
+const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5;
+const float kRttMultiplierForFecTimeout = 0.5;
+
+// Minimum timeout for FEC alarm, set to half the minimum Tail Loss Probe
+// timeout of 10ms.
+const int64_t kMinFecTimeoutMs = 5u;
+
} // namespace
// A QuicRandom wrapper that gets a bucket of entropy and distributes it
@@ -39,9 +54,7 @@ class QuicRandomBoolSource {
public:
// random: Source of entropy. Not owned.
explicit QuicRandomBoolSource(QuicRandom* random)
- : random_(random),
- bit_bucket_(0),
- bit_mask_(0) {}
+ : random_(random), bit_bucket_(0), bit_mask_(0) {}
~QuicRandomBoolSource() {}
@@ -60,23 +73,31 @@ class QuicRandomBoolSource {
// Source of entropy.
QuicRandom* random_;
// Stored random bits.
- uint64 bit_bucket_;
+ uint64_t bit_bucket_;
// The next available bit has "1" in the mask. Zero means empty bucket.
- uint64 bit_mask_;
+ uint64_t bit_mask_;
DISALLOW_COPY_AND_ASSIGN(QuicRandomBoolSource);
};
QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
QuicFramer* framer,
- QuicRandom* random_generator)
- : connection_id_(connection_id),
+ QuicRandom* random_generator,
+ QuicBufferAllocator* buffer_allocator,
+ DelegateInterface* delegate)
+ : delegate_(delegate),
+ debug_delegate_(nullptr),
+ connection_id_(connection_id),
encryption_level_(ENCRYPTION_NONE),
+ has_ack_(false),
+ has_stop_waiting_(false),
framer_(framer),
random_bool_source_(new QuicRandomBoolSource(random_generator)),
+ current_path_(kDefaultPathId),
+ buffer_allocator_(buffer_allocator),
packet_number_(0),
- should_fec_protect_(false),
- fec_group_number_(0),
+ should_fec_protect_next_packet_(false),
+ fec_protect_(false),
send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
max_packet_length_(0),
max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup),
@@ -84,16 +105,19 @@ QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER),
packet_number_length_(next_packet_number_length_),
packet_size_(0),
- needs_padding_(false) {
+ needs_padding_(false),
+ fec_send_policy_(FEC_ANY_TRIGGER),
+ fec_timeout_(QuicTime::Delta::Zero()),
+ rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout) {
SetMaxPacketLength(kDefaultMaxPacketSize);
}
-QuicPacketCreator::~QuicPacketCreator() {
-}
+QuicPacketCreator::~QuicPacketCreator() {}
void QuicPacketCreator::OnBuiltFecProtectedPayload(
- const QuicPacketHeader& header, StringPiece payload) {
- if (fec_group_.get()) {
+ const QuicPacketHeader& header,
+ StringPiece payload) {
+ if (fec_group_.get() != nullptr) {
DCHECK_NE(0u, header.fec_group);
fec_group_->Update(encryption_level_, header, payload);
}
@@ -125,14 +149,14 @@ void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
void QuicPacketCreator::set_max_packets_per_fec_group(
size_t max_packets_per_fec_group) {
- max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup,
- max_packets_per_fec_group);
+ max_packets_per_fec_group_ =
+ max(kLowestMaxPacketsPerFecGroup, max_packets_per_fec_group);
DCHECK_LT(0u, max_packets_per_fec_group_);
}
bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
- DCHECK(!HasPendingFrames());
- return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 &&
+ return !HasPendingFrames() && fec_group_.get() != nullptr &&
+ fec_group_->NumReceivedPackets() > 0 &&
(force_close ||
fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_);
}
@@ -151,8 +175,8 @@ bool QuicPacketCreator::IsFecGroupOpen() const {
}
void QuicPacketCreator::StartFecProtectingPackets() {
- if (!IsFecEnabled()) {
- LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled.";
+ if (max_packets_per_fec_group_ == 0) {
+ QUIC_BUG << "Cannot start FEC protection when FEC is not enabled.";
return;
}
// TODO(jri): This currently requires that the generator flush out any
@@ -161,29 +185,20 @@ void QuicPacketCreator::StartFecProtectingPackets() {
// generator to check if the resulting expansion still allows the incoming
// frame to be added to the packet.
if (HasPendingFrames()) {
- LOG(DFATAL) << "Cannot start FEC protection with pending frames.";
+ QUIC_BUG << "Cannot start FEC protection with pending frames.";
return;
}
- DCHECK(!should_fec_protect_);
- should_fec_protect_ = true;
+ DCHECK(!fec_protect_);
+ fec_protect_ = true;
}
void QuicPacketCreator::StopFecProtectingPackets() {
if (fec_group_.get() != nullptr) {
- LOG(DFATAL) << "Cannot stop FEC protection with open FEC group.";
+ QUIC_BUG << "Cannot stop FEC protection with open FEC group.";
return;
}
- DCHECK(should_fec_protect_);
- should_fec_protect_ = false;
- fec_group_number_ = 0;
-}
-
-bool QuicPacketCreator::IsFecProtected() const {
- return should_fec_protect_;
-}
-
-bool QuicPacketCreator::IsFecEnabled() const {
- return max_packets_per_fec_group_ > 0;
+ DCHECK(fec_protect_);
+ fec_protect_ = false;
}
InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
@@ -200,13 +215,12 @@ InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
// Update packet number length only on packet and FEC group boundaries.
packet_number_length_ = next_packet_number_length_;
- if (!should_fec_protect_) {
+ if (!fec_protect_) {
return NOT_IN_FEC_GROUP;
}
// Start a new FEC group since protection is on. Set the fec group number to
// the packet number of the next packet.
- fec_group_number_ = packet_number() + 1;
- fec_group_.reset(new QuicFecGroup());
+ fec_group_.reset(new QuicFecGroup(packet_number_ + 1));
return IN_FEC_GROUP;
}
@@ -231,20 +245,52 @@ void QuicPacketCreator::UpdatePacketNumberLength(
const QuicPacketNumber current_delta = max_packets_per_fec_group_ +
packet_number_ + 1 -
least_packet_awaited_by_peer;
- const uint64 delta = max(current_delta, max_packets_in_flight);
+ const uint64_t delta = max(current_delta, max_packets_in_flight);
next_packet_number_length_ =
QuicFramer::GetMinSequenceNumberLength(delta * 4);
}
+bool QuicPacketCreator::ConsumeData(QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ bool needs_padding,
+ QuicFrame* frame,
+ FecProtection fec_protection) {
+ if (!HasRoomForStreamFrame(id, offset)) {
+ return false;
+ }
+ if (fec_protection == MUST_FEC_PROTECT) {
+ should_fec_protect_next_packet_ = true;
+ MaybeStartFecProtection();
+ }
+ CreateStreamFrame(id, iov, iov_offset, offset, fin, frame);
+ if (!AddFrame(*frame, /*save_retransmittable_frames=*/true)) {
+ // Fails if we try to write unencrypted stream data.
+ delete frame->stream_frame;
+ return false;
+ }
+ if (needs_padding) {
+ needs_padding_ = true;
+ }
+ if (fec_protection == MUST_FEC_PROTECT &&
+ iov_offset + frame->stream_frame->frame_length == iov.total_length) {
+ // Turn off FEC protection when we're done writing protected data.
+ DVLOG(1) << "Turning FEC protection OFF";
+ should_fec_protect_next_packet_ = false;
+ }
+ return true;
+}
+
bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
QuicStreamOffset offset) const {
// TODO(jri): This is a simple safe decision for now, but make
// is_in_fec_group a parameter. Same as with all public methods in
// QuicPacketCreator.
return BytesFree() >
- QuicFramer::GetMinStreamFrameSize(id, offset, true,
- should_fec_protect_ ? IN_FEC_GROUP :
- NOT_IN_FEC_GROUP);
+ QuicFramer::GetMinStreamFrameSize(
+ id, offset, true, fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
}
// static
@@ -255,23 +301,22 @@ size_t QuicPacketCreator::StreamFramePacketOverhead(
QuicStreamOffset offset,
InFecGroup is_in_fec_group) {
return GetPacketHeaderSize(connection_id_length, include_version,
- packet_number_length, is_in_fec_group) +
+ /*include_path_id=*/false, packet_number_length,
+ is_in_fec_group) +
// Assumes this is a stream with a single lone packet.
QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group);
}
size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
- const QuicIOVector& iov,
+ QuicIOVector iov,
size_t iov_offset,
QuicStreamOffset offset,
bool fin,
- QuicFrame* frame,
- scoped_ptr<char[]>* buffer) {
+ QuicFrame* frame) {
DCHECK_GT(max_packet_length_,
StreamFramePacketOverhead(connection_id_length_, kIncludeVersion,
PACKET_6BYTE_PACKET_NUMBER, offset,
IN_FEC_GROUP));
- DCHECK(buffer);
InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
@@ -281,8 +326,7 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
<< QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group);
if (iov_offset == iov.total_length) {
- LOG_IF(DFATAL, !fin)
- << "Creating a stream frame with no data or fin.";
+ LOG_IF(DFATAL, !fin) << "Creating a stream frame with no data or fin.";
// Create a new packet for the fin, if necessary.
*frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece()));
return 0;
@@ -294,15 +338,16 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size);
bool set_fin = fin && bytes_consumed == data_size; // Last frame.
- buffer->reset(new char[bytes_consumed]);
- CopyToBuffer(iov, iov_offset, bytes_consumed, buffer->get());
- *frame = QuicFrame(new QuicStreamFrame(
- id, set_fin, offset, StringPiece(buffer->get(), bytes_consumed)));
+ UniqueStreamBuffer buffer =
+ NewStreamBuffer(buffer_allocator_, bytes_consumed);
+ CopyToBuffer(iov, iov_offset, bytes_consumed, buffer.get());
+ *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, bytes_consumed,
+ std::move(buffer)));
return bytes_consumed;
}
// static
-void QuicPacketCreator::CopyToBuffer(const QuicIOVector& iov,
+void QuicPacketCreator::CopyToBuffer(QuicIOVector iov,
size_t iov_offset,
size_t length,
char* buffer) {
@@ -311,27 +356,59 @@ void QuicPacketCreator::CopyToBuffer(const QuicIOVector& iov,
iov_offset -= iov.iov[iovnum].iov_len;
++iovnum;
}
- while (iovnum < iov.iov_count && length > 0) {
- const size_t copy_len = min(length, iov.iov[iovnum].iov_len - iov_offset);
- memcpy(buffer, static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset,
- copy_len);
- iov_offset = 0;
+ DCHECK_LE(iovnum, iov.iov_count);
+ DCHECK_LE(iov_offset, iov.iov[iovnum].iov_len);
+ if (iovnum >= iov.iov_count || length == 0) {
+ return;
+ }
+
+ // Unroll the first iteration that handles iov_offset.
+ const size_t iov_available = iov.iov[iovnum].iov_len - iov_offset;
+ size_t copy_len = min(length, iov_available);
+
+ // Try to prefetch the next iov if there is at least one more after the
+ // current. Otherwise, it looks like an irregular access that the hardware
+ // prefetcher won't speculatively prefetch. Only prefetch one iov because
+ // generally, the iov_offset is not 0, input iov consists of 2K buffers and
+ // the output buffer is ~1.4K.
+ if (copy_len == iov_available && iovnum + 1 < iov.iov_count) {
+ // TODO(ckrasic) - this is unused without prefetch()
+ // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base);
+ // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base);
+ // Prefetch 2 cachelines worth of data to get the prefetcher started; leave
+ // it to the hardware prefetcher after that.
+ // TODO(ckrasic) - investigate what to do about prefetch directives.
+ // prefetch(next_base, PREFETCH_HINT_T0);
+ if (iov.iov[iovnum + 1].iov_len >= 64) {
+ // TODO(ckrasic) - investigate what to do about prefetch directives.
+ // prefetch(next_base + CACHELINE_SIZE, PREFETCH_HINT_T0);
+ }
+ }
+
+ const char* src = static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset;
+ while (true) {
+ memcpy(buffer, src, copy_len);
length -= copy_len;
buffer += copy_len;
- ++iovnum;
+ if (length == 0 || ++iovnum >= iov.iov_count) {
+ break;
+ }
+ src = static_cast<char*>(iov.iov[iovnum].iov_base);
+ copy_len = min(length, iov.iov[iovnum].iov_len);
}
LOG_IF(DFATAL, length > 0) << "Failed to copy entire length to buffer.";
}
SerializedPacket QuicPacketCreator::ReserializeAllFrames(
const RetransmittableFrames& frames,
+ EncryptionLevel original_encryption_level,
QuicPacketNumberLength original_length,
char* buffer,
size_t buffer_len) {
DCHECK(fec_group_.get() == nullptr);
const QuicPacketNumberLength saved_length = packet_number_length_;
const QuicPacketNumberLength saved_next_length = next_packet_number_length_;
- const bool saved_should_fec_protect = should_fec_protect_;
+ const bool saved_should_fec_protect = fec_protect_;
const bool needs_padding = needs_padding_;
const EncryptionLevel default_encryption_level = encryption_level_;
@@ -339,16 +416,21 @@ SerializedPacket QuicPacketCreator::ReserializeAllFrames(
// and change the encryption level.
packet_number_length_ = original_length;
next_packet_number_length_ = original_length;
- should_fec_protect_ = false;
- encryption_level_ = frames.encryption_level();
+ fec_protect_ = false;
needs_padding_ = frames.needs_padding();
+ // Only preserve the original encryption level if it's a handshake packet or
+ // if we haven't gone forward secure.
+ if (frames.HasCryptoHandshake() ||
+ encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
+ encryption_level_ = original_encryption_level;
+ }
// Serialize the packet and restore the FEC and packet number length state.
SerializedPacket serialized_packet =
SerializeAllFrames(frames.frames(), buffer, buffer_len);
packet_number_length_ = saved_length;
next_packet_number_length_ = saved_next_length;
- should_fec_protect_ = saved_should_fec_protect;
+ fec_protect_ = saved_should_fec_protect;
needs_padding_ = needs_padding;
encryption_level_ = default_encryption_level;
@@ -359,10 +441,9 @@ SerializedPacket QuicPacketCreator::SerializeAllFrames(const QuicFrames& frames,
char* buffer,
size_t buffer_len) {
LOG_IF(DFATAL, !queued_frames_.empty()) << "Frames already queued.";
- LOG_IF(DFATAL, frames.empty())
- << "Attempt to serialize empty packet";
+ LOG_IF(DFATAL, frames.empty()) << "Attempt to serialize empty packet";
for (const QuicFrame& frame : frames) {
- bool success = AddFrame(frame, false, false, nullptr);
+ bool success = AddFrame(frame, false);
DCHECK(success);
}
SerializedPacket packet = SerializePacket(buffer, buffer_len);
@@ -370,6 +451,41 @@ SerializedPacket QuicPacketCreator::SerializeAllFrames(const QuicFrames& frames,
return packet;
}
+void QuicPacketCreator::Flush() {
+ if (!HasPendingFrames()) {
+ return;
+ }
+
+ // TODO(rtenneti): Change the default 64 alignas value (used the default
+ // value from CACHELINE_SIZE).
+ ALIGNAS(64) char seralized_packet_buffer[kMaxPacketSize];
+ SerializedPacket serialized_packet =
+ SerializePacket(seralized_packet_buffer, kMaxPacketSize);
+ OnSerializedPacket(&serialized_packet);
+}
+
+void QuicPacketCreator::OnSerializedPacket(SerializedPacket* packet) {
+ if (packet->packet == nullptr) {
+ QUIC_BUG << "Failed to SerializePacket. fec_policy:" << fec_send_policy()
+ << " should_fec_protect_:" << should_fec_protect_next_packet_;
+ delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false);
+ return;
+ }
+ // There may be AckListeners interested in this packet.
+ packet->listeners.swap(ack_listeners_);
+ DCHECK(ack_listeners_.empty());
+ delegate_->OnSerializedPacket(packet);
+ has_ack_ = false;
+ has_stop_waiting_ = false;
+ MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false,
+ /*is_fec_timeout=*/false);
+ // Maximum packet size may be only enacted while no packet is currently being
+ // constructed, so here we have a good opportunity to actually change it.
+ if (CanSetMaxPacketLength()) {
+ SetMaxPacketLength(max_packet_length_);
+ }
+}
+
bool QuicPacketCreator::HasPendingFrames() const {
return !queued_frames_.empty();
}
@@ -381,8 +497,8 @@ bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
size_t QuicPacketCreator::ExpansionOnNewFrame() const {
// If packet is FEC protected, there's no expansion.
- if (should_fec_protect_) {
- return 0;
+ if (fec_protect_) {
+ return 0;
}
// If the last frame in the packet is a stream frame, then it will expand to
// include the stream_length field when a new frame is added.
@@ -393,8 +509,8 @@ size_t QuicPacketCreator::ExpansionOnNewFrame() const {
size_t QuicPacketCreator::BytesFree() const {
DCHECK_GE(max_plaintext_size_, PacketSize());
- return max_plaintext_size_ - min(max_plaintext_size_, PacketSize()
- + ExpansionOnNewFrame());
+ return max_plaintext_size_ -
+ min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
}
size_t QuicPacketCreator::PacketSize() const {
@@ -406,39 +522,41 @@ size_t QuicPacketCreator::PacketSize() const {
packet_number_length_ = next_packet_number_length_;
}
packet_size_ = GetPacketHeaderSize(
- connection_id_length_, send_version_in_packet_, packet_number_length_,
- should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
+ connection_id_length_, send_version_in_packet_, /*include_path_id=*/false,
+ packet_number_length_, fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
return packet_size_;
}
bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
- return AddFrame(frame,
- /*save_retransmittable_frames=*/true,
- /*needs_padding=*/false, nullptr);
+ return AddFrame(frame, /*save_retransmittable_frames=*/true);
}
-bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame, char* buffer) {
- return AddFrame(frame,
- /*save_retransmittable_frames=*/true,
- /*needs_padding=*/false, buffer);
+bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame) {
+ if (AddFrame(frame, /*save_retransmittable_frames=*/true)) {
+ needs_padding_ = true;
+ return true;
+ }
+ return false;
}
-bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame,
- char* buffer) {
- return AddFrame(frame,
- /*save_retransmittable_frames=*/true,
- /*needs_padding=*/true, buffer);
+void QuicPacketCreator::AddAckListener(QuicAckListenerInterface* listener,
+ QuicPacketLength length) {
+ DCHECK(!queued_frames_.empty());
+ ack_listeners_.push_back(AckListenerWrapper(listener, length));
}
SerializedPacket QuicPacketCreator::SerializePacket(
char* encrypted_buffer,
size_t encrypted_buffer_len) {
DCHECK_LT(0u, encrypted_buffer_len);
- LOG_IF(DFATAL, queued_frames_.empty())
- << "Attempt to serialize empty packet";
- DCHECK_GE(packet_number_ + 1, fec_group_number_);
+ LOG_IF(DFATAL, queued_frames_.empty()) << "Attempt to serialize empty packet";
+ if (fec_group_.get() != nullptr) {
+ DCHECK_GE(packet_number_ + 1, fec_group_->FecGroupNumber());
+ }
QuicPacketHeader header;
- FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header);
+ // FillPacketHeader increments packet_number_.
+ FillPacketHeader(fec_group_ != nullptr ? fec_group_->FecGroupNumber() : 0,
+ false, &header);
MaybeAddPadding();
@@ -450,39 +568,36 @@ SerializedPacket QuicPacketCreator::SerializePacket(
bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
queued_frames_.size() == 1 &&
queued_frames_.back().type == ACK_FRAME;
- char buffer[kMaxPacketSize];
- scoped_ptr<QuicPacket> packet;
// Use the packet_size_ instead of the buffer size to ensure smaller
// packet sizes are properly used.
- scoped_ptr<char[]> large_buffer;
- if (packet_size_ <= kMaxPacketSize) {
- packet.reset(
- framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_));
- } else {
- large_buffer.reset(new char[packet_size_]);
- packet.reset(framer_->BuildDataPacket(header, queued_frames_,
- large_buffer.get(), packet_size_));
- }
- if (packet == nullptr) {
- LOG(DFATAL) << "Failed to serialize " << queued_frames_.size()
- << " frames.";
+ size_t length = framer_->BuildDataPacket(header, queued_frames_,
+ encrypted_buffer, packet_size_);
+ if (length == 0) {
+ QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames.";
return NoPacket();
}
- OnBuiltFecProtectedPayload(header, packet->FecProtectedData());
+ // TODO(ianswett) Consider replacing QuicPacket with something else, since
+ // it's only used to provide convenience methods to FEC and encryption.
+ QuicPacket packet(encrypted_buffer, length,
+ /* owns_buffer */ false,
+ header.public_header.connection_id_length,
+ header.public_header.version_flag,
+ header.public_header.packet_number_length);
+ OnBuiltFecProtectedPayload(header, packet.FecProtectedData());
// Because of possible truncation, we can't be confident that our
// packet size calculation worked correctly.
if (!possibly_truncated_by_length) {
- DCHECK_EQ(packet_size_, packet->length());
+ DCHECK_EQ(packet_size_, length);
}
- // Immediately encrypt the packet, to ensure we don't encrypt the same packet
+ // Immediately encrypt the packet, to ensure we don't encrypt the same
// packet number multiple times.
- QuicEncryptedPacket* encrypted =
- framer_->EncryptPayload(encryption_level_, packet_number_, *packet,
+ size_t encrypted_length =
+ framer_->EncryptPayload(encryption_level_, packet_number_, packet,
encrypted_buffer, encrypted_buffer_len);
- if (encrypted == nullptr) {
- LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_;
+ if (encrypted_length == 0) {
+ QUIC_BUG << "Failed to encrypt packet number " << packet_number_;
return NoPacket();
}
@@ -494,54 +609,55 @@ SerializedPacket QuicPacketCreator::SerializePacket(
queued_retransmittable_frames_->set_needs_padding(needs_padding_);
}
- bool has_ack = false;
- bool has_stop_waiting = false;
- for (const QuicFrame& frame : queued_frames_) {
- has_ack |= frame.type == ACK_FRAME;
- has_stop_waiting |= frame.type == STOP_WAITING_FRAME;
- }
-
packet_size_ = 0;
queued_frames_.clear();
needs_padding_ = false;
- return SerializedPacket(
- header.packet_packet_number, header.public_header.packet_number_length,
- encrypted, QuicFramer::GetPacketEntropyHash(header),
- queued_retransmittable_frames_.release(), has_ack, has_stop_waiting);
+ return SerializedPacket(current_path_, header.packet_number,
+ header.public_header.packet_number_length,
+ encrypted_buffer, encrypted_length,
+ /* owns_buffer*/ false,
+ QuicFramer::GetPacketEntropyHash(header),
+ queued_retransmittable_frames_.release(), has_ack_,
+ has_stop_waiting_, encryption_level_);
}
SerializedPacket QuicPacketCreator::SerializeFec(char* buffer,
size_t buffer_len) {
DCHECK_LT(0u, buffer_len);
if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) {
- LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group.";
+ QUIC_BUG << "SerializeFEC called but no group or zero packets in group.";
// TODO(jri): Make this a public method of framer?
return NoPacket();
}
+ if (FLAGS_quic_no_unencrypted_fec && encryption_level_ == ENCRYPTION_NONE) {
+ LOG(DFATAL) << "SerializeFEC must be called with encryption.";
+ delegate_->CloseConnection(QUIC_UNENCRYPTED_FEC_DATA, false);
+ return NoPacket();
+ }
DCHECK_EQ(0u, queued_frames_.size());
QuicPacketHeader header;
- FillPacketHeader(fec_group_number_, true, &header);
- QuicFecData fec_data;
- fec_data.fec_group = fec_group_->min_protected_packet();
- fec_data.redundancy = fec_group_->payload_parity();
- scoped_ptr<QuicPacket> packet(framer_->BuildFecPacket(header, fec_data));
+ FillPacketHeader(fec_group_->FecGroupNumber(), true, &header);
+ scoped_ptr<QuicPacket> packet(
+ framer_->BuildFecPacket(header, fec_group_->PayloadParity()));
fec_group_.reset(nullptr);
packet_size_ = 0;
LOG_IF(DFATAL, packet == nullptr)
- << "Failed to serialize fec packet for group:" << fec_data.fec_group;
+ << "Failed to serialize fec packet for group:"
+ << fec_group_->FecGroupNumber();
DCHECK_GE(max_packet_length_, packet->length());
// Immediately encrypt the packet, to ensure we don't encrypt the same packet
// packet number multiple times.
- QuicEncryptedPacket* encrypted = framer_->EncryptPayload(
+ size_t encrypted_length = framer_->EncryptPayload(
encryption_level_, packet_number_, *packet, buffer, buffer_len);
- if (encrypted == nullptr) {
- LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_;
+ if (encrypted_length == 0) {
+ QUIC_BUG << "Failed to encrypt packet number " << packet_number_;
return NoPacket();
}
- SerializedPacket serialized(
- header.packet_packet_number, header.public_header.packet_number_length,
- encrypted, QuicFramer::GetPacketEntropyHash(header), nullptr, false,
- false);
+ SerializedPacket serialized(current_path_, header.packet_number,
+ header.public_header.packet_number_length, buffer,
+ encrypted_length, /* owns_buffer */ false,
+ QuicFramer::GetPacketEntropyHash(header), nullptr,
+ false, false, encryption_level_);
serialized.is_fec_packet = true;
return serialized;
}
@@ -549,21 +665,16 @@ SerializedPacket QuicPacketCreator::SerializeFec(char* buffer,
QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
const QuicVersionVector& supported_versions) {
DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
- QuicPacketPublicHeader header;
- header.connection_id = connection_id_;
- header.reset_flag = false;
- header.version_flag = true;
- header.versions = supported_versions;
- QuicEncryptedPacket* encrypted =
- framer_->BuildVersionNegotiationPacket(header, supported_versions);
+ QuicEncryptedPacket* encrypted = QuicFramer::BuildVersionNegotiationPacket(
+ connection_id_, supported_versions);
DCHECK(encrypted);
DCHECK_GE(max_packet_length_, encrypted->length());
return encrypted;
}
SerializedPacket QuicPacketCreator::NoPacket() {
- return SerializedPacket(0, PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, nullptr,
- false, false);
+ return SerializedPacket(kInvalidPathId, 0, PACKET_1BYTE_PACKET_NUMBER,
+ nullptr, 0, nullptr, false, false);
}
void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
@@ -574,7 +685,7 @@ void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
header->public_header.reset_flag = false;
header->public_header.version_flag = send_version_in_packet_;
header->fec_flag = fec_flag;
- header->packet_packet_number = ++packet_number_;
+ header->packet_number = ++packet_number_;
header->public_header.packet_number_length = packet_number_length_;
header->entropy_flag = random_bool_source_->RandBool();
header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
@@ -594,16 +705,23 @@ bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
}
bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
- bool save_retransmittable_frames,
- bool needs_padding,
- char* buffer) {
+ bool save_retransmittable_frames) {
DVLOG(1) << "Adding frame: " << frame;
+ if (FLAGS_quic_never_write_unencrypted_data && frame.type == STREAM_FRAME &&
+ frame.stream_frame->stream_id != kCryptoStreamId &&
+ encryption_level_ == ENCRYPTION_NONE) {
+ QUIC_BUG << "Cannot send stream data without encryption.";
+ delegate_->CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA, false);
+ return false;
+ }
InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
size_t frame_len = framer_->GetSerializedFrameLength(
frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
packet_number_length_);
if (frame_len == 0) {
+ // Current open packet is full.
+ Flush();
return false;
}
DCHECK_LT(0u, packet_size_);
@@ -611,17 +729,21 @@ bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
if (save_retransmittable_frames && ShouldRetransmit(frame)) {
if (queued_retransmittable_frames_.get() == nullptr) {
- queued_retransmittable_frames_.reset(
- new RetransmittableFrames(encryption_level_));
+ queued_retransmittable_frames_.reset(new RetransmittableFrames());
}
- queued_frames_.push_back(
- queued_retransmittable_frames_->AddFrame(frame, buffer));
+ queued_frames_.push_back(queued_retransmittable_frames_->AddFrame(frame));
} else {
queued_frames_.push_back(frame);
}
- if (needs_padding) {
- needs_padding_ = true;
+ if (frame.type == ACK_FRAME) {
+ has_ack_ = true;
+ }
+ if (frame.type == STOP_WAITING_FRAME) {
+ has_stop_waiting_ = true;
+ }
+ if (debug_delegate_ != nullptr) {
+ debug_delegate_->OnFrameAddedToPacket(frame);
}
return true;
@@ -637,9 +759,94 @@ void QuicPacketCreator::MaybeAddPadding() {
return;
}
- QuicPaddingFrame padding;
- bool success = AddFrame(QuicFrame(&padding), false, false, nullptr);
+ bool success = AddFrame(QuicFrame(QuicPaddingFrame()), false);
DCHECK(success);
}
+void QuicPacketCreator::MaybeStartFecProtection() {
+ if (max_packets_per_fec_group_ == 0 || fec_protect_) {
+ // Do not start FEC protection when FEC protection is not enabled or FEC
+ // protection is already on.
+ return;
+ }
+ DVLOG(1) << "Turning FEC protection ON";
+ // Flush current open packet.
+ Flush();
+
+ StartFecProtectingPackets();
+ DCHECK(fec_protect_);
+}
+
+void QuicPacketCreator::MaybeSendFecPacketAndCloseGroup(bool force_send_fec,
+ bool is_fec_timeout) {
+ if (ShouldSendFec(force_send_fec)) {
+ if ((FLAGS_quic_no_unencrypted_fec &&
+ encryption_level_ == ENCRYPTION_NONE) ||
+ (fec_send_policy_ == FEC_ALARM_TRIGGER && !is_fec_timeout)) {
+ ResetFecGroup();
+ delegate_->OnResetFecGroup();
+ } else {
+ // TODO(zhongyi): Change the default 64 alignas value (used the default
+ // value from CACHELINE_SIZE).
+ ALIGNAS(64) char seralized_fec_buffer[kMaxPacketSize];
+ SerializedPacket serialized_fec =
+ SerializeFec(seralized_fec_buffer, kMaxPacketSize);
+ OnSerializedPacket(&serialized_fec);
+ }
+ }
+
+ if (!should_fec_protect_next_packet_ && fec_protect_ && !IsFecGroupOpen()) {
+ StopFecProtectingPackets();
+ }
+}
+
+QuicTime::Delta QuicPacketCreator::GetFecTimeout(
+ QuicPacketNumber packet_number) {
+ // Do not set up FEC alarm for |packet_number| it is not the first packet in
+ // the current group.
+ if (fec_group_.get() != nullptr &&
+ (packet_number == fec_group_->FecGroupNumber())) {
+ return QuicTime::Delta::Max(
+ fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs));
+ }
+ return QuicTime::Delta::Infinite();
+}
+
+void QuicPacketCreator::OnCongestionWindowChange(
+ QuicPacketCount max_packets_in_flight) {
+ set_max_packets_per_fec_group(static_cast<size_t>(
+ kMaxPacketsInFlightMultiplierForFecGroupSize * max_packets_in_flight));
+}
+
+void QuicPacketCreator::OnRttChange(QuicTime::Delta rtt) {
+ fec_timeout_ = rtt.Multiply(rtt_multiplier_for_fec_timeout_);
+}
+
+void QuicPacketCreator::SetCurrentPath(
+ QuicPathId path_id,
+ QuicPacketNumber least_packet_awaited_by_peer,
+ QuicPacketCount max_packets_in_flight) {
+ if (current_path_ == path_id) {
+ return;
+ }
+
+ if (HasPendingFrames()) {
+ QUIC_BUG << "Unable to change paths when a packet is under construction.";
+ return;
+ }
+
+ // Send FEC packet and close FEC group.
+ MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
+ // Save current packet number and load switching path's packet number.
+ multipath_packet_number_[current_path_] = packet_number_;
+ hash_map<QuicPathId, QuicPacketNumber>::iterator it =
+ multipath_packet_number_.find(path_id);
+ // If path_id is not in the map, it's a new path. Set packet_number to 0.
+ packet_number_ = it == multipath_packet_number_.end() ? 0 : it->second;
+ current_path_ = path_id;
+ // Switching path needs to update packet number length.
+ UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_packet_creator.h b/chromium/net/quic/quic_packet_creator.h
index ee6e35cb4a1..ded7678a16d 100644
--- a/chromium/net/quic/quic_packet_creator.h
+++ b/chromium/net/quic/quic_packet_creator.h
@@ -4,66 +4,100 @@
//
// Accumulates frames for the next packet until more frames no longer fit or
// it's time to create a packet from them. Also provides packet creation of
-// FEC packets based on previously created packets.
+// FEC packets based on previously created packets. If multipath enabled, only
+// creates packets on one path at the same time. Currently, next packet number
+// is tracked per-path.
#ifndef NET_QUIC_QUIC_PACKET_CREATOR_H_
#define NET_QUIC_QUIC_PACKET_CREATOR_H_
+#include <stddef.h>
+
#include <string>
#include <utility>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
+using base::hash_map;
+
namespace net {
namespace test {
class QuicPacketCreatorPeer;
}
-class QuicAckNotifier;
class QuicRandom;
class QuicRandomBoolSource;
class NET_EXPORT_PRIVATE QuicPacketCreator {
public:
+ // A delegate interface for further processing serialized packet.
+ class NET_EXPORT_PRIVATE DelegateInterface {
+ public:
+ virtual ~DelegateInterface() {}
+ // Called when a packet is serialized. Delegate does not take the ownership
+ // of |serialized_packet|, but may take ownership of |packet.packet|
+ // and |packet.retransmittable_frames|. If it does so, they must be set
+ // to nullptr.
+ virtual void OnSerializedPacket(SerializedPacket* serialized_packet) = 0;
+ virtual void CloseConnection(QuicErrorCode error, bool from_peer) = 0;
+ // Called when current FEC group is reset (closed).
+ virtual void OnResetFecGroup() = 0;
+ };
+
+ // Interface which gets callbacks from the QuicPacketCreator at interesting
+ // points. Implementations must not mutate the state of the creator
+ // as a result of these callbacks.
+ class NET_EXPORT_PRIVATE DebugDelegate {
+ public:
+ virtual ~DebugDelegate() {}
+
+ // Called when a frame has been added to the current packet.
+ virtual void OnFrameAddedToPacket(const QuicFrame& frame) {}
+ };
+
// QuicRandom* required for packet entropy.
QuicPacketCreator(QuicConnectionId connection_id,
QuicFramer* framer,
- QuicRandom* random_generator);
+ QuicRandom* random_generator,
+ QuicBufferAllocator* buffer_allocator,
+ DelegateInterface* delegate);
~QuicPacketCreator();
- // Turn on FEC protection for subsequently created packets. FEC should be
- // enabled first (max_packets_per_fec_group should be non-zero) for FEC
- // protection to start.
- void StartFecProtectingPackets();
-
- // Turn off FEC protection for subsequently created packets. If the creator
- // has any open FEC group, call will fail. It is the caller's responsibility
- // to flush out FEC packets in generation, and to verify with ShouldSendFec()
- // that there is no open FEC group.
- void StopFecProtectingPackets();
-
// Checks if it's time to send an FEC packet. |force_close| forces this to
// return true if an FEC group is open.
bool ShouldSendFec(bool force_close) const;
- // Resets (closes) the FEC group. This method should only be called on a
- // packet boundary.
- void ResetFecGroup();
+ // If ShouldSendFec returns true, serializes currently constructed FEC packet
+ // and calls the delegate on the packet. Resets current FEC group if FEC
+ // protection policy is FEC_ALARM_TRIGGER but |is_fec_timeout| is false.
+ // Also tries to turn off FEC protection if should_fec_protect_next_packet is
+ // false.
+ void MaybeSendFecPacketAndCloseGroup(bool force_send_fec,
+ bool is_fec_timeout);
// Returns true if an FEC packet is under construction.
bool IsFecGroupOpen() const;
+ // Called after sending |packet_number| to determine whether an FEC alarm
+ // should be set for sending out an FEC packet. Returns a positive and finite
+ // timeout if an FEC alarm should be set, and infinite if no alarm should be
+ // set.
+ QuicTime::Delta GetFecTimeout(QuicPacketNumber packet_number);
+
// Makes the framer not serialize the protocol version in sent packets.
void StopSendingVersion();
// Update the packet number length to use in future packets as soon as it
// can be safely changed.
+ // TODO(fayang): Directly set packet number length instead of compute it in
+ // creator.
void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer,
QuicPacketCount max_packets_in_flight);
@@ -75,22 +109,25 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
QuicStreamOffset offset,
InFecGroup is_in_fec_group);
+ // Returns false and flushes all pending frames if current open packet is
+ // full.
+ // If current packet is not full, converts a raw payload into a stream frame
+ // that fits into the open packet and adds it to the packet.
+ // The payload begins at |iov_offset| into the |iov|.
+ // Also tries to start FEC protection depends on |fec_protection|.
+ bool ConsumeData(QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ bool needs_padding,
+ QuicFrame* frame,
+ FecProtection fec_protection);
+
+ // Returns true if current open packet can accommodate more stream frames of
+ // stream |id| at |offset|, false otherwise.
bool HasRoomForStreamFrame(QuicStreamId id, QuicStreamOffset offset) const;
- // Converts a raw payload to a frame which fits into the currently open
- // packet. The payload begins at |iov_offset| into the |iov|.
- // Returns the number of bytes consumed from data.
- // If data is empty and fin is true, the expected behavior is to consume the
- // fin but return 0. If any data is consumed, it will be copied into a
- // new buffer that |frame| will point to and will be stored in |buffer|.
- size_t CreateStreamFrame(QuicStreamId id,
- const QuicIOVector& iov,
- size_t iov_offset,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame,
- scoped_ptr<char[]>* buffer);
-
// Serializes all frames into a single packet. All frames must fit into a
// single packet. Also, sets the entropy hash of the serialized packet to a
// random bool and returns that value as a member of SerializedPacket.
@@ -103,10 +140,16 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Used for retransmitting packets to ensure they aren't too long.
// Caller must ensure that any open FEC group is closed before calling this
// method.
- SerializedPacket ReserializeAllFrames(const RetransmittableFrames& frames,
- QuicPacketNumberLength original_length,
- char* buffer,
- size_t buffer_len);
+ SerializedPacket ReserializeAllFrames(
+ const RetransmittableFrames& frames,
+ EncryptionLevel original_encryption_level,
+ QuicPacketNumberLength original_length,
+ char* buffer,
+ size_t buffer_len);
+
+ // Serializes all added frames into a single packet and invokes the delegate_
+ // to further process the SerializedPacket.
+ void Flush();
// Returns true if there are frames pending to be serialized.
bool HasPendingFrames() const;
@@ -114,17 +157,6 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Returns true if there are retransmittable frames pending to be serialized.
bool HasPendingRetransmittableFrames() const;
- // TODO(jri): Remove this method.
- // Returns whether FEC protection is currently enabled. Note: Enabled does not
- // mean that an FEC group is currently active; i.e., IsFecProtected() may
- // still return false.
- bool IsFecEnabled() const;
-
- // Returns true if subsequent packets will be FEC protected. Note: True does
- // not mean that an FEC packet is currently under construction; i.e.,
- // fec_group_.get() may still be nullptr, until MaybeStartFec() is called.
- bool IsFecProtected() const;
-
// Returns the number of bytes which are available to be used by additional
// frames in the packet. Since stream frames are slightly smaller when they
// are the last frame in a packet, this method will return a different
@@ -144,36 +176,19 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// in BytesFree.
size_t PacketSize() const;
- // TODO(jri): AddSavedFrame calls AddFrame, which only saves the frame
- // if it is a stream frame, not other types of frames. Fix this API;
- // add a AddNonSavedFrame method.
- // Adds |frame| to the packet creator's list of frames to be serialized.
- // Returns false if the frame doesn't fit into the current packet.
+ // Tries to add |frame| to the packet creator's list of frames to be
+ // serialized. If the frame does not fit into the current packet, flushes the
+ // packet and returns false.
bool AddSavedFrame(const QuicFrame& frame);
- // Identical to AddSavedFrame, but takes ownership of the buffer if it returns
- // true.
- bool AddSavedFrame(const QuicFrame& frame, char* buffer);
-
- // Identical to AddSavedFrame, but takes ownership of the buffer if it returns
- // true, and allows to cause the packet to be padded.
- bool AddPaddedSavedFrame(const QuicFrame& frame, char* buffer);
-
- // Serializes all frames which have been added and adds any which should be
- // retransmitted to |retransmittable_frames| if it's not nullptr. All frames
- // must fit into a single packet. Sets the entropy hash of the serialized
- // packet to a random bool and returns that value as a member of
- // SerializedPacket. Also, sets |serialized_frames| in the SerializedPacket to
- // the corresponding RetransmittableFrames if any frames are to be
- // retransmitted.
- // Fails if |buffer_len| isn't long enough for the encrypted packet.
- SerializedPacket SerializePacket(char* encrypted_buffer, size_t buffer_len);
+ // Identical to AddSavedFrame, but allows the frame to be padded.
+ bool AddPaddedSavedFrame(const QuicFrame& frame);
- // Packetize FEC data. All frames must fit into a single packet. Also, sets
- // the entropy hash of the serialized packet to a random bool and returns
- // that value as a member of SerializedPacket.
- // Fails if |buffer_len| isn't long enough for the encrypted packet.
- SerializedPacket SerializeFec(char* buffer, size_t buffer_len);
+ // Adds |listener| to the next serialized packet and notifies the
+ // std::listener
+ // with |length| as the number of acked bytes.
+ void AddAckListener(QuicAckListenerInterface* listener,
+ QuicPacketLength length);
// Creates a version negotiation packet which supports |supported_versions|.
// Caller owns the created packet. Also, sets the entropy hash of the
@@ -185,6 +200,12 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Returns a dummy packet that is valid but contains no useful information.
static SerializedPacket NoPacket();
+ // Called when the congestion window has changed.
+ void OnCongestionWindowChange(QuicPacketCount max_packets_in_flight);
+
+ // Called when the RTT may have changed.
+ void OnRttChange(QuicTime::Delta rtt);
+
// Sets the encryption level that will be applied to new packets.
void set_encryption_level(EncryptionLevel level) {
encryption_level_ = level;
@@ -202,9 +223,11 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
connection_id_length_ = length;
}
- QuicByteCount max_packet_length() const {
- return max_packet_length_;
- }
+ QuicByteCount max_packet_length() const { return max_packet_length_; }
+
+ bool has_ack() const { return has_ack_; }
+
+ bool has_stop_waiting() const { return has_stop_waiting_; }
// Sets the encrypter to use for the encryption level and updates the max
// plaintext size.
@@ -217,9 +240,18 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// Sets the maximum packet length.
void SetMaxPacketLength(QuicByteCount length);
+ // Sets the path on which subsequent packets will be created. It is the
+ // caller's responsibility to guarantee no packet is under construction before
+ // calling this function. If |path_id| is different from current_path_, the
+ // FEC packet (if exists) will be sent and next_packet_number_length_ is
+ // recalculated.
+ void SetCurrentPath(QuicPathId path_id,
+ QuicPacketNumber least_packet_awaited_by_peer,
+ QuicPacketCount max_packets_in_flight);
+
// Returns current max number of packets covered by an FEC group.
size_t max_packets_per_fec_group() const {
- return max_packets_per_fec_group_;
+ return max_packets_per_fec_group_;
}
// Sets creator's max number of packets covered by an FEC group.
@@ -228,20 +260,43 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
// To turn off FEC protection, use StopFecProtectingPackets().
void set_max_packets_per_fec_group(size_t max_packets_per_fec_group);
- // Returns the currently open FEC group's number. If there isn't an open FEC
- // group, returns the last closed FEC group number. Returns 0 when FEC is
- // disabled or no FEC group has been created yet.
- QuicFecGroupNumber fec_group_number() { return fec_group_number_; }
+ FecSendPolicy fec_send_policy() { return fec_send_policy_; }
+
+ void set_fec_send_policy(FecSendPolicy fec_send_policy) {
+ fec_send_policy_ = fec_send_policy;
+ }
+
+ void set_rtt_multiplier_for_fec_timeout(
+ float rtt_multiplier_for_fec_timeout) {
+ rtt_multiplier_for_fec_timeout_ = rtt_multiplier_for_fec_timeout;
+ }
+
+ void set_debug_delegate(DebugDelegate* debug_delegate) {
+ debug_delegate_ = debug_delegate;
+ }
private:
friend class test::QuicPacketCreatorPeer;
static bool ShouldRetransmit(const QuicFrame& frame);
+ // Converts a raw payload to a frame which fits into the current open
+ // packet. The payload begins at |iov_offset| into the |iov|.
+ // Returns the number of bytes consumed from data.
+ // If data is empty and fin is true, the expected behavior is to consume the
+ // fin but return 0. If any data is consumed, it will be copied into a
+ // new buffer that |frame| will point to and own.
+ size_t CreateStreamFrame(QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ QuicFrame* frame);
+
// Copies |length| bytes from iov starting at offset |iov_offset| into buffer.
// |iov| must be at least iov_offset+length total length and buffer must be
// at least |length| long.
- static void CopyToBuffer(const QuicIOVector& iov,
+ static void CopyToBuffer(QuicIOVector iov,
size_t iov_offset,
size_t length,
char* buffer);
@@ -259,26 +314,82 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
bool fec_flag,
QuicPacketHeader* header);
- // Allows a frame to be added without creating retransmittable frames.
- // Particularly useful for retransmits using SerializeAllFrames().
- bool AddFrame(const QuicFrame& frame,
- bool save_retransmittable_frames,
- bool needs_padding,
- char* buffer);
+ // Adds a |frame| if there is space and returns false and flushes all pending
+ // frames if there isn't room. If |save_retransmittable_frames| is true,
+ // saves the |frame| in the next SerializedPacket.
+ bool AddFrame(const QuicFrame& frame, bool save_retransmittable_frames);
// Adds a padding frame to the current packet only if the current packet
// contains a handshake message, and there is sufficient room to fit a
// padding frame.
void MaybeAddPadding();
+ // Serializes all frames which have been added and adds any which should be
+ // retransmitted to queued_retransmittable_frames_ if it's not nullptr. All
+ // frames must fit into a single packet. Sets the entropy hash of the
+ // serialized packet to a random bool and returns that value as a member of
+ // SerializedPacket. Also, sets |serialized_frames| in the SerializedPacket to
+ // the corresponding RetransmittableFrames if any frames are to be
+ // retransmitted.
+ // Fails if |buffer_len| isn't long enough for the encrypted packet.
+ SerializedPacket SerializePacket(char* encrypted_buffer, size_t buffer_len);
+
+ // Called after a new SerialiedPacket is created to call the delegate's
+ // OnSerializedPacket, reset state, and potentially flush FEC groups.
+ void OnSerializedPacket(SerializedPacket* packet);
+
+ // Turn on FEC protection for subsequent packets. If no FEC group is currently
+ // open, this method flushes current open packet and then turns FEC on.
+ void MaybeStartFecProtection();
+
+ // Turn on FEC protection for subsequently created packets. FEC should be
+ // enabled first (max_packets_per_fec_group should be non-zero) for FEC
+ // protection to start.
+ void StartFecProtectingPackets();
+
+ // Turn off FEC protection for subsequently created packets. If the creator
+ // has any open FEC group, call will fail. It is the caller's responsibility
+ // to flush out FEC packets in generation, and to verify with ShouldSendFec()
+ // that there is no open FEC group.
+ void StopFecProtectingPackets();
+
+ // Resets (closes) the FEC group. This method should only be called on a
+ // packet boundary.
+ void ResetFecGroup();
+
+ // Packetize FEC data. All frames must fit into a single packet. Also, sets
+ // the entropy hash of the serialized packet to a random bool and returns
+ // that value as a member of SerializedPacket.
+ // Fails if |buffer_len| isn't long enough for the encrypted packet.
+ SerializedPacket SerializeFec(char* buffer, size_t buffer_len);
+
+ // Does not own these delegates.
+ DelegateInterface* delegate_;
+ DebugDelegate* debug_delegate_;
+
QuicConnectionId connection_id_;
EncryptionLevel encryption_level_;
+ // True if an ack is queued in queued_frames_.
+ bool has_ack_;
+ // True if a stop waiting frame is queued in queued_frames_.
+ bool has_stop_waiting_;
QuicFramer* framer_;
scoped_ptr<QuicRandomBoolSource> random_bool_source_;
+ // Map mapping path_id to last sent packet number on the path.
+ hash_map<QuicPathId, QuicPacketNumber> multipath_packet_number_;
+ // The path which current constructed packet will be sent on.
+ QuicPathId current_path_;
+ QuicBufferAllocator* const buffer_allocator_;
QuicPacketNumber packet_number_;
+ // True when creator is requested to turn on FEC protection. False otherwise.
+ // There is a time difference between should_fec_protect_next_packet is
+ // true/false and FEC is actually turned on/off (e.g., The creator may have an
+ // open FEC group even if this variable is false).
+ bool should_fec_protect_next_packet_;
// If true, any created packets will be FEC protected.
- bool should_fec_protect_;
- QuicFecGroupNumber fec_group_number_;
+ // TODO(fayang): Combine should_fec_protect_next_packet and fec_protect_ to
+ // one variable.
+ bool fec_protect_;
scoped_ptr<QuicFecGroup> fec_group_;
// Controls whether protocol version should be included while serializing the
// packet.
@@ -306,6 +417,17 @@ class NET_EXPORT_PRIVATE QuicPacketCreator {
scoped_ptr<RetransmittableFrames> queued_retransmittable_frames_;
// If true, the packet will be padded up to |max_packet_length_|.
bool needs_padding_;
+ // Stores ack std::listeners that should be attached to the next packet.
+ std::list<AckListenerWrapper> ack_listeners_;
+
+ // FEC policy that specifies when to send FEC packet.
+ FecSendPolicy fec_send_policy_;
+ // Timeout used for FEC alarm. Can be set to zero initially or if the SRTT has
+ // not yet been set.
+ QuicTime::Delta fec_timeout_;
+ // The multiplication factor for FEC timeout based on RTT.
+ // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
+ float rtt_multiplier_for_fec_timeout_;
DISALLOW_COPY_AND_ASSIGN(QuicPacketCreator);
};
diff --git a/chromium/net/quic/quic_packet_creator_test.cc b/chromium/net/quic/quic_packet_creator_test.cc
index 962c1b5b4d8..2a1c4ea6152 100644
--- a/chromium/net/quic/quic_packet_creator_test.cc
+++ b/chromium/net/quic/quic_packet_creator_test.cc
@@ -6,10 +6,13 @@
#include <stdint.h>
+#include "base/macros.h"
#include "base/stl_util.h"
#include "net/quic/crypto/null_encrypter.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_simple_buffer_allocator.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/mock_random.h"
#include "net/quic/test_tools/quic_framer_peer.h"
@@ -26,6 +29,7 @@ using testing::DoAll;
using testing::InSequence;
using testing::Return;
using testing::SaveArg;
+using testing::StrictMock;
using testing::_;
namespace net {
@@ -39,8 +43,7 @@ struct TestParams {
QuicConnectionIdLength length)
: version(version),
connection_id_length(length),
- version_serialization(version_serialization) {
- }
+ version_serialization(version_serialization) {}
friend ostream& operator<<(ostream& os, const TestParams& p) {
os << "{ client_version: " << QuicVersionToString(p.version)
@@ -63,16 +66,50 @@ vector<TestParams> GetTestParams() {
params.push_back(TestParams(all_supported_versions[i], true, max));
params.push_back(TestParams(all_supported_versions[i], false, max));
}
- params.push_back(TestParams(
- all_supported_versions[0], true, PACKET_0BYTE_CONNECTION_ID));
- params.push_back(TestParams(
- all_supported_versions[0], true, PACKET_1BYTE_CONNECTION_ID));
- params.push_back(TestParams(
- all_supported_versions[0], true, PACKET_4BYTE_CONNECTION_ID));
+ params.push_back(
+ TestParams(all_supported_versions[0], true, PACKET_0BYTE_CONNECTION_ID));
+ params.push_back(
+ TestParams(all_supported_versions[0], true, PACKET_1BYTE_CONNECTION_ID));
+ params.push_back(
+ TestParams(all_supported_versions[0], true, PACKET_4BYTE_CONNECTION_ID));
+ params.push_back(TestParams(all_supported_versions[0], true, max));
return params;
}
+class MockDelegate : public QuicPacketCreator::DelegateInterface {
+ public:
+ MockDelegate() {}
+ ~MockDelegate() override {}
+
+ MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet));
+ MOCK_METHOD0(OnResetFecGroup, void());
+ MOCK_METHOD2(CloseConnection, void(QuicErrorCode, bool));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockDelegate);
+};
+
class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
+ public:
+ void ClearSerializedPacket(SerializedPacket* serialized_packet) {
+ if (serialized_packet == nullptr) {
+ return;
+ }
+
+ delete serialized_packet->retransmittable_frames;
+ delete serialized_packet->packet;
+ }
+
+ void SaveSerializedPacket(SerializedPacket* serialized_packet) {
+ if (serialized_packet == nullptr) {
+ return;
+ }
+
+ serialized_packet_ = *serialized_packet;
+ serialized_packet_.packet = serialized_packet->packet->Clone();
+ delete serialized_packet->packet;
+ }
+
protected:
QuicPacketCreatorTest()
: server_framer_(SupportedVersions(GetParam().version),
@@ -83,15 +120,35 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
Perspective::IS_CLIENT),
connection_id_(2),
data_("foo"),
- creator_(connection_id_, &client_framer_, &mock_random_) {
+ creator_(connection_id_,
+ &client_framer_,
+ &mock_random_,
+ &buffer_allocator_,
+ &delegate_),
+ serialized_packet_(creator_.NoPacket()) {
+ FLAGS_quic_always_log_bugs_for_tests = true;
creator_.set_connection_id_length(GetParam().connection_id_length);
+
+ creator_.SetEncrypter(ENCRYPTION_INITIAL, new NullEncrypter());
+ creator_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, new NullEncrypter());
client_framer_.set_visitor(&framer_visitor_);
client_framer_.set_received_entropy_calculator(&entropy_calculator_);
server_framer_.set_visitor(&framer_visitor_);
+ // TODO(ianswett): Fix this test so it uses a non-null encrypter.
+ FLAGS_quic_never_write_unencrypted_data = false;
+ FLAGS_quic_no_unencrypted_fec = false;
}
~QuicPacketCreatorTest() override {}
+ SerializedPacket SerializeAllFrames(const QuicFrames& frames) {
+ SerializedPacket packet =
+ creator_.SerializeAllFrames(frames, buffer_, kMaxPacketSize);
+ EXPECT_EQ(QuicPacketCreatorPeer::GetEncryptionLevel(&creator_),
+ packet.encryption_level);
+ return packet;
+ }
+
void ProcessPacket(QuicEncryptedPacket* encrypted) {
server_framer_.ProcessPacket(*encrypted);
}
@@ -104,7 +161,8 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
EXPECT_EQ(STREAM_FRAME, frame.type);
ASSERT_TRUE(frame.stream_frame);
EXPECT_EQ(stream_id, frame.stream_frame->stream_id);
- EXPECT_EQ(data, frame.stream_frame->data);
+ EXPECT_EQ(data, StringPiece(frame.stream_frame->frame_buffer,
+ frame.stream_frame->frame_length));
EXPECT_EQ(offset, frame.stream_frame->offset);
EXPECT_EQ(fin, frame.stream_frame->fin);
}
@@ -113,7 +171,7 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
// the version.
size_t GetPacketHeaderOverhead(InFecGroup is_in_fec_group) {
return GetPacketHeaderSize(
- creator_.connection_id_length(), kIncludeVersion,
+ creator_.connection_id_length(), kIncludeVersion, !kIncludePathId,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_),
is_in_fec_group);
}
@@ -121,8 +179,8 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
// Returns the number of bytes of overhead that will be added to a packet
// of maximum length.
size_t GetEncryptionOverhead() {
- return creator_.max_packet_length() - client_framer_.GetMaxPlaintextSize(
- creator_.max_packet_length());
+ return creator_.max_packet_length() -
+ client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
}
// Returns the number of bytes consumed by the non-data fields of a stream
@@ -132,29 +190,26 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> {
true, is_in_fec_group);
}
- // Enables and turns on FEC protection. Returns true if FEC protection is on.
- bool SwitchFecProtectionOn(size_t max_packets_per_fec_group) {
- creator_.set_max_packets_per_fec_group(max_packets_per_fec_group);
- creator_.StartFecProtectingPackets();
- return creator_.IsFecProtected();
- }
-
QuicIOVector MakeIOVector(StringPiece s) {
return ::net::MakeIOVector(s, &iov_);
}
static const QuicStreamOffset kOffset = 1u;
+ char buffer_[kMaxPacketSize];
QuicFrames frames_;
QuicFramer server_framer_;
QuicFramer client_framer_;
- testing::StrictMock<MockFramerVisitor> framer_visitor_;
+ StrictMock<MockFramerVisitor> framer_visitor_;
+ StrictMock<MockDelegate> delegate_;
QuicConnectionId connection_id_;
string data_;
struct iovec iov_;
MockRandom mock_random_;
+ SimpleBufferAllocator buffer_allocator_;
QuicPacketCreator creator_;
MockEntropyCalculator entropy_calculator_;
+ SerializedPacket serialized_packet_;
};
// Run all packet creator tests with all supported versions of QUIC, and with
@@ -165,47 +220,54 @@ INSTANTIATE_TEST_CASE_P(QuicPacketCreatorTests,
::testing::ValuesIn(GetTestParams()));
TEST_P(QuicPacketCreatorTest, SerializeFrames) {
- frames_.push_back(QuicFrame(new QuicAckFrame(MakeAckFrame(0u))));
- frames_.push_back(
- QuicFrame(new QuicStreamFrame(0u, false, 0u, StringPiece())));
- frames_.push_back(
- QuicFrame(new QuicStreamFrame(0u, true, 0u, StringPiece())));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
- delete frames_[0].ack_frame;
- delete frames_[1].stream_frame;
- delete frames_[2].stream_frame;
+ for (int i = ENCRYPTION_NONE; i < NUM_ENCRYPTION_LEVELS; ++i) {
+ EncryptionLevel level = static_cast<EncryptionLevel>(i);
+ creator_.set_encryption_level(level);
+ frames_.push_back(QuicFrame(new QuicAckFrame(MakeAckFrame(0u))));
+ frames_.push_back(
+ QuicFrame(new QuicStreamFrame(0u, false, 0u, StringPiece())));
+ frames_.push_back(
+ QuicFrame(new QuicStreamFrame(0u, true, 0u, StringPiece())));
+ SerializedPacket serialized = SerializeAllFrames(frames_);
+ EXPECT_EQ(level, serialized.encryption_level);
+ delete frames_[0].ack_frame;
+ delete frames_[1].stream_frame;
+ delete frames_[2].stream_frame;
+ frames_.clear();
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnAckFrame(_));
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnAckFrame(_));
+ EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+ EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
+ }
+ ProcessPacket(serialized.packet);
+ delete serialized.packet;
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
}
TEST_P(QuicPacketCreatorTest, SerializeWithFEC) {
- // Enable FEC protection, and send FEC packet every 6 packets.
- EXPECT_TRUE(SwitchFecProtectionOn(6));
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
// Should return false since we do not have enough packets in the FEC group to
// trigger an FEC packet.
ASSERT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
-
- frames_.push_back(
- QuicFrame(new QuicStreamFrame(0u, false, 0u, StringPiece())));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
- delete frames_[0].stream_frame;
+ // Turn on FEC protection.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+ // Serialize the packet.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
{
InSequence s;
@@ -218,8 +280,8 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFEC) {
EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
+ ProcessPacket(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
// Should return false since we do not have enough packets in the FEC group to
// trigger an FEC packet.
@@ -227,8 +289,11 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFEC) {
// Should return true since there are packets in the FEC group.
ASSERT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
- serialized = creator_.SerializeFec(buffer, kMaxPacketSize);
- ASSERT_EQ(2u, serialized.packet_number);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
+ ASSERT_EQ(2u, serialized_packet_.packet_number);
{
InSequence s;
EXPECT_CALL(framer_visitor_, OnPacket());
@@ -239,8 +304,8 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFEC) {
EXPECT_CALL(framer_visitor_, OnFecData(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
+ ProcessPacket(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
}
TEST_P(QuicPacketCreatorTest, SerializeChangingSequenceNumberLength) {
@@ -248,11 +313,14 @@ TEST_P(QuicPacketCreatorTest, SerializeChangingSequenceNumberLength) {
creator_.AddSavedFrame(frames_[0]);
QuicPacketCreatorPeer::SetNextPacketNumberLength(&creator_,
PACKET_4BYTE_PACKET_NUMBER);
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
+
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
// The packet number length will not change mid-packet.
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, serialized.packet_number_length);
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
{
InSequence s;
@@ -264,13 +332,14 @@ TEST_P(QuicPacketCreatorTest, SerializeChangingSequenceNumberLength) {
EXPECT_CALL(framer_visitor_, OnAckFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
+ ProcessPacket(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
creator_.AddSavedFrame(frames_[0]);
- serialized = creator_.SerializePacket(buffer, kMaxPacketSize);
+ creator_.Flush();
// Now the actual packet number length should have changed.
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, serialized.packet_number_length);
+ EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
delete frames_[0].ack_frame;
{
@@ -283,8 +352,8 @@ TEST_P(QuicPacketCreatorTest, SerializeChangingSequenceNumberLength) {
EXPECT_CALL(framer_visitor_, OnAckFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
+ ProcessPacket(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
}
TEST_P(QuicPacketCreatorTest, ChangeSequenceNumberLengthMidPacket) {
@@ -309,11 +378,13 @@ TEST_P(QuicPacketCreatorTest, ChangeSequenceNumberLengthMidPacket) {
EXPECT_TRUE(creator_.HasPendingFrames());
// Ensure the packet is successfully created.
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized.packet);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, serialized.packet_number_length);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
// Verify that header in transmitted packet has 1 byte sequence length.
QuicPacketHeader header;
@@ -323,16 +394,16 @@ TEST_P(QuicPacketCreatorTest, ChangeSequenceNumberLengthMidPacket) {
EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_)).WillOnce(
- DoAll(SaveArg<0>(&header), Return(true)));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+ .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
EXPECT_CALL(framer_visitor_, OnAckFrame(_));
EXPECT_CALL(framer_visitor_, OnStopWaitingFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
+ ProcessPacket(serialized_packet_.packet);
EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
header.public_header.packet_number_length);
- delete serialized.packet;
+ ClearSerializedPacket(&serialized_packet_);
// Packet 2.
EXPECT_FALSE(creator_.HasPendingFrames());
@@ -342,9 +413,10 @@ TEST_P(QuicPacketCreatorTest, ChangeSequenceNumberLengthMidPacket) {
EXPECT_TRUE(creator_.HasPendingFrames());
// Ensure the packet is successfully created.
- serialized = creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized.packet);
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, serialized.packet_number_length);
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
+ EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
// Verify that header in transmitted packet has 4 byte sequence length.
{
@@ -353,16 +425,16 @@ TEST_P(QuicPacketCreatorTest, ChangeSequenceNumberLengthMidPacket) {
EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_)).WillOnce(
- DoAll(SaveArg<0>(&header), Return(true)));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+ .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
EXPECT_CALL(framer_visitor_, OnStopWaitingFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
+ ProcessPacket(serialized_packet_.packet);
EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
header.public_header.packet_number_length);
- delete serialized.packet;
+ ClearSerializedPacket(&serialized_packet_);
delete ack_frame.ack_frame;
}
@@ -372,22 +444,26 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFECChangingSequenceNumberLength) {
// and we expect that packet number length should not change until the end
// of the open FEC group.
- // Enable FEC protection, and send FEC packet every 6 packets.
- EXPECT_TRUE(SwitchFecProtectionOn(6));
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
// Should return false since we do not have enough packets in the FEC group to
// trigger an FEC packet.
ASSERT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
- frames_.push_back(QuicFrame(new QuicAckFrame(MakeAckFrame(0u))));
// Generate Packet 1.
- creator_.AddSavedFrame(frames_[0]);
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
// Change the packet number length mid-FEC group and it should not change.
QuicPacketCreatorPeer::SetNextPacketNumberLength(&creator_,
PACKET_4BYTE_PACKET_NUMBER);
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, serialized.packet_number_length);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
{
InSequence s;
@@ -397,16 +473,18 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFECChangingSequenceNumberLength) {
EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
EXPECT_CALL(framer_visitor_, OnFecProtectedPayload(_));
- EXPECT_CALL(framer_visitor_, OnAckFrame(_));
+ EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
+ ProcessPacket(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
// Generate Packet 2.
- creator_.AddSavedFrame(frames_[0]);
- serialized = creator_.SerializePacket(buffer, kMaxPacketSize);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, serialized.packet_number_length);
+ ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ creator_.Flush();
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
{
InSequence s;
@@ -416,11 +494,11 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFECChangingSequenceNumberLength) {
EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
EXPECT_CALL(framer_visitor_, OnFecProtectedPayload(_));
- EXPECT_CALL(framer_visitor_, OnAckFrame(_));
+ EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
+ ProcessPacket(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
// Should return false since we do not have enough packets in the FEC group to
// trigger an FEC packet.
@@ -429,9 +507,14 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFECChangingSequenceNumberLength) {
ASSERT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
// Force generation of FEC packet.
- serialized = creator_.SerializeFec(buffer, kMaxPacketSize);
- EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, serialized.packet_number_length);
- ASSERT_EQ(3u, serialized.packet_number);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ // Turn off FEC protection.
+ creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
+ ASSERT_EQ(3u, serialized_packet_.packet_number);
{
InSequence s;
@@ -443,14 +526,19 @@ TEST_P(QuicPacketCreatorTest, SerializeWithFECChangingSequenceNumberLength) {
EXPECT_CALL(framer_visitor_, OnFecData(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
- ProcessPacket(serialized.packet);
- delete serialized.packet;
+ ProcessPacket(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
// Ensure the next FEC group starts using the new packet number length.
- serialized = creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
- EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, serialized.packet_number_length);
- delete frames_[0].ack_frame;
- delete serialized.packet;
+ ASSERT_TRUE(creator_.ConsumeData(3u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
+ EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+ serialized_packet_.packet_number_length);
+ ClearSerializedPacket(&serialized_packet_);
}
TEST_P(QuicPacketCreatorTest, ReserializeFramesWithSequenceNumberLength) {
@@ -463,11 +551,12 @@ TEST_P(QuicPacketCreatorTest, ReserializeFramesWithSequenceNumberLength) {
PACKET_2BYTE_PACKET_NUMBER);
QuicStreamFrame* stream_frame =
new QuicStreamFrame(kCryptoStreamId, /*fin=*/false, 0u, StringPiece());
- RetransmittableFrames frames(ENCRYPTION_NONE);
+ RetransmittableFrames frames;
frames.AddFrame(QuicFrame(stream_frame));
char buffer[kMaxPacketSize];
SerializedPacket serialized = creator_.ReserializeAllFrames(
- frames, PACKET_1BYTE_PACKET_NUMBER, buffer, kMaxPacketSize);
+ frames, ENCRYPTION_NONE, PACKET_1BYTE_PACKET_NUMBER, buffer,
+ kMaxPacketSize);
EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
@@ -488,26 +577,57 @@ TEST_P(QuicPacketCreatorTest, ReserializeFramesWithSequenceNumberLength) {
delete serialized.packet;
}
+TEST_P(QuicPacketCreatorTest, ReserializeCryptoFrameWithForwardSecurity) {
+ QuicStreamFrame* stream_frame =
+ new QuicStreamFrame(kCryptoStreamId, /*fin=*/false, 0u, StringPiece());
+ RetransmittableFrames frames;
+ frames.AddFrame(QuicFrame(stream_frame));
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+ char buffer[kMaxPacketSize];
+ SerializedPacket serialized = creator_.ReserializeAllFrames(
+ frames, ENCRYPTION_NONE,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_), buffer,
+ kMaxPacketSize);
+ EXPECT_EQ(ENCRYPTION_NONE, serialized.encryption_level);
+ delete serialized.packet;
+}
+
+TEST_P(QuicPacketCreatorTest, ReserializeFrameWithForwardSecurity) {
+ QuicStreamFrame* stream_frame =
+ new QuicStreamFrame(0u, /*fin=*/false, 0u, StringPiece());
+ RetransmittableFrames frames;
+ frames.AddFrame(QuicFrame(stream_frame));
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+ char buffer[kMaxPacketSize];
+ SerializedPacket serialized = creator_.ReserializeAllFrames(
+ frames, ENCRYPTION_NONE,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_), buffer,
+ kMaxPacketSize);
+ EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, serialized.encryption_level);
+ delete serialized.packet;
+}
+
TEST_P(QuicPacketCreatorTest, ReserializeFramesWithPadding) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("fake handshake message data"));
- scoped_ptr<char[]> stream_buffer;
- creator_.CreateStreamFrame(kCryptoStreamId, io_vector, 0u, 0u, false, &frame,
- &stream_buffer);
- RetransmittableFrames frames(ENCRYPTION_NONE);
+ QuicPacketCreatorPeer::CreateStreamFrame(&creator_, kCryptoStreamId,
+ io_vector, 0u, 0u, false, &frame);
+ RetransmittableFrames frames;
frames.AddFrame(frame);
frames.set_needs_padding(true);
char buffer[kMaxPacketSize];
SerializedPacket serialized = creator_.ReserializeAllFrames(
- frames, QuicPacketCreatorPeer::NextPacketNumberLength(&creator_), buffer,
+ frames, ENCRYPTION_NONE,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_), buffer,
kMaxPacketSize);
EXPECT_EQ(kDefaultMaxPacketSize, serialized.packet->length());
delete serialized.packet;
}
TEST_P(QuicPacketCreatorTest, ReserializeFramesWithFullPacketAndPadding) {
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP)
- + GetEncryptionOverhead() + GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
+ GetEncryptionOverhead() +
+ GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
size_t capacity = kDefaultMaxPacketSize - overhead;
for (int delta = -5; delta <= 0; ++delta) {
string data(capacity + delta, 'A');
@@ -515,16 +635,17 @@ TEST_P(QuicPacketCreatorTest, ReserializeFramesWithFullPacketAndPadding) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector(data));
- scoped_ptr<char[]> stream_buffer;
- creator_.CreateStreamFrame(kCryptoStreamId, io_vector, 0, kOffset, false,
- &frame, &stream_buffer);
- RetransmittableFrames frames(ENCRYPTION_NONE);
+ UniqueStreamBuffer stream_buffer;
+ QuicPacketCreatorPeer::CreateStreamFrame(
+ &creator_, kCryptoStreamId, io_vector, 0, kOffset, false, &frame);
+ RetransmittableFrames frames;
frames.AddFrame(frame);
frames.set_needs_padding(true);
char buffer[kMaxPacketSize];
SerializedPacket serialized = creator_.ReserializeAllFrames(
- frames, QuicPacketCreatorPeer::NextPacketNumberLength(&creator_),
- buffer, kMaxPacketSize);
+ frames, ENCRYPTION_NONE,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_), buffer,
+ kMaxPacketSize);
// If there is not enough space in the packet to fit a padding frame
// (1 byte) and to expand the stream frame (another 2 bytes) the packet
@@ -548,9 +669,8 @@ TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) {
QuicFrames frames;
frames.push_back(QuicFrame(&frame));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializeAllFrames(frames, buffer, kMaxPacketSize);
+ SerializedPacket serialized = SerializeAllFrames(frames);
+ EXPECT_EQ(ENCRYPTION_NONE, serialized.encryption_level);
ASSERT_EQ(1u, serialized.packet_number);
ASSERT_EQ(1u, creator_.packet_number());
@@ -567,35 +687,18 @@ TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) {
delete serialized.packet;
}
-TEST_P(QuicPacketCreatorTest, SwitchFecOnOffWithNoGroup) {
- // Enable FEC protection.
+TEST_P(QuicPacketCreatorTest, SwitchFecOnOffWithGroupInProgress) {
+ // Send FEC packet every 6 packets.
creator_.set_max_packets_per_fec_group(6);
- EXPECT_TRUE(creator_.IsFecEnabled());
- EXPECT_FALSE(creator_.IsFecProtected());
-
// Turn on FEC protection.
- creator_.StartFecProtectingPackets();
- EXPECT_TRUE(creator_.IsFecProtected());
- // We have no packets in the FEC group, so no FEC packet can be created.
- EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/true));
- // Since no packets are in FEC group yet, we should be able to turn FEC
- // off with no trouble.
- creator_.StopFecProtectingPackets();
- EXPECT_FALSE(creator_.IsFecProtected());
-}
-
-TEST_P(QuicPacketCreatorTest, SwitchFecOnOffWithGroupInProgress) {
- // Enable FEC protection, and send FEC packet every 6 packets.
- EXPECT_TRUE(SwitchFecProtectionOn(6));
- frames_.push_back(
- QuicFrame(new QuicStreamFrame(0u, false, 0u, StringPiece())));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
- delete frames_[0].stream_frame;
- delete serialized.packet;
-
- EXPECT_TRUE(creator_.IsFecProtected());
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
// We do not have enough packets in the FEC group to trigger an FEC packet.
EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
// Should return true since there are packets in the FEC group.
@@ -603,121 +706,133 @@ TEST_P(QuicPacketCreatorTest, SwitchFecOnOffWithGroupInProgress) {
// Switching FEC off should not change creator state, since there is an
// FEC packet under construction.
- EXPECT_DFATAL(creator_.StopFecProtectingPackets(),
+ EXPECT_DFATAL(QuicPacketCreatorPeer::StopFecProtectingPackets(&creator_),
"Cannot stop FEC protection with open FEC group.");
- EXPECT_TRUE(creator_.IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
// Confirm that FEC packet is still under construction.
EXPECT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
- serialized = creator_.SerializeFec(buffer, kMaxPacketSize);
- delete serialized.packet;
-
- // Switching FEC on/off should work now.
- creator_.StopFecProtectingPackets();
- EXPECT_FALSE(creator_.IsFecProtected());
- creator_.StartFecProtectingPackets();
- EXPECT_TRUE(creator_.IsFecProtected());
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ // Turn off FEC protection.
+ creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
}
TEST_P(QuicPacketCreatorTest, SwitchFecOnWithStreamFrameQueued) {
// Add a stream frame to the creator.
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(1u, io_vector, 0u, 0u, false,
- &frame, &stream_buffer);
- EXPECT_EQ(4u, consumed);
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
ASSERT_TRUE(frame.stream_frame);
- EXPECT_TRUE(creator_.AddSavedFrame(frame));
+ size_t consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
EXPECT_TRUE(creator_.HasPendingFrames());
// Enable FEC protection, and send FEC packet every 6 packets.
creator_.set_max_packets_per_fec_group(6);
- EXPECT_TRUE(creator_.IsFecEnabled());
- EXPECT_DFATAL(creator_.StartFecProtectingPackets(),
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecEnabled(&creator_));
+ EXPECT_DFATAL(QuicPacketCreatorPeer::StartFecProtectingPackets(&creator_),
"Cannot start FEC protection with pending frames.");
- EXPECT_FALSE(creator_.IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
- // Serialize packet for transmission.
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- delete serialized.packet;
- delete serialized.retransmittable_frames;
- EXPECT_FALSE(creator_.HasPendingFrames());
-
- // Since all pending frames have been serialized, turning FEC on should work.
- creator_.StartFecProtectingPackets();
- EXPECT_TRUE(creator_.IsFecProtected());
+ // Start FEC protection after current open packet is flushed.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
}
-TEST_P(QuicPacketCreatorTest, CreateStreamFrame) {
+TEST_P(QuicPacketCreatorTest, ConsumeData) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(1u, io_vector, 0u, 0u, false,
- &frame, &stream_buffer);
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
CheckStreamFrame(frame, 1u, "test", 0u, false);
- RetransmittableFrames cleanup_frames(ENCRYPTION_NONE);
- cleanup_frames.AddFrame(frame);
+ EXPECT_TRUE(creator_.HasPendingFrames());
}
-TEST_P(QuicPacketCreatorTest, CreateStreamFrameFin) {
+TEST_P(QuicPacketCreatorTest, ConsumeDataFin) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(1u, io_vector, 0u, 10u, true,
- &frame, &stream_buffer);
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 10u, true, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
CheckStreamFrame(frame, 1u, "test", 10u, true);
- RetransmittableFrames cleanup_frames(ENCRYPTION_NONE);
- cleanup_frames.AddFrame(frame);
+ EXPECT_TRUE(creator_.HasPendingFrames());
}
-TEST_P(QuicPacketCreatorTest, CreateStreamFrameFinOnly) {
+TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) {
QuicFrame frame;
QuicIOVector io_vector(nullptr, 0, 0);
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(1u, io_vector, 0u, 0u, true,
- &frame, &stream_buffer);
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, true, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(0u, consumed);
CheckStreamFrame(frame, 1u, string(), 0u, true);
- delete frame.stream_frame;
+ EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataWithFecProtect) {
+ creator_.set_max_packets_per_fec_group(6);
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ CheckStreamFrame(frame, 1u, "test", 0u, false);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
}
TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP)
- + GetEncryptionOverhead();
+ const size_t overhead =
+ GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) + GetEncryptionOverhead();
for (size_t i = overhead; i < overhead + 100; ++i) {
creator_.SetMaxPacketLength(i);
- const bool should_have_room = i > overhead + GetStreamFrameOverhead(
- NOT_IN_FEC_GROUP);
- ASSERT_EQ(should_have_room, creator_.HasRoomForStreamFrame(
- kClientDataStreamId1, kOffset));
+ const bool should_have_room =
+ i > overhead + GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ ASSERT_EQ(should_have_room,
+ creator_.HasRoomForStreamFrame(kClientDataStreamId1, kOffset));
if (should_have_room) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("testdata"));
- scoped_ptr<char[]> stream_buffer;
- size_t bytes_consumed =
- creator_.CreateStreamFrame(kClientDataStreamId1, io_vector, 0u,
- kOffset, false, &frame, &stream_buffer);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
+ kOffset, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t bytes_consumed = frame.stream_frame->frame_length;
EXPECT_LT(0u, bytes_consumed);
- ASSERT_TRUE(creator_.AddSavedFrame(frame));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized_packet =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized_packet.packet);
- delete serialized_packet.packet;
- delete serialized_packet.retransmittable_frames;
+ creator_.Flush();
}
}
}
TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
// Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP)
- + GetEncryptionOverhead() + GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
+ GetEncryptionOverhead() +
+ GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
size_t capacity = kDefaultMaxPacketSize - overhead;
// Now, test various sizes around this size.
for (int delta = -5; delta <= 5; ++delta) {
@@ -725,33 +840,42 @@ TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
size_t bytes_free = delta > 0 ? 0 : 0 - delta;
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector(data));
- scoped_ptr<char[]> stream_buffer;
- size_t bytes_consumed =
- creator_.CreateStreamFrame(kClientDataStreamId1, io_vector, 0u, kOffset,
- false, &frame, &stream_buffer);
- EXPECT_EQ(capacity - bytes_free, bytes_consumed);
+ ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
+ kOffset, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
- ASSERT_TRUE(creator_.AddSavedFrame(frame));
// BytesFree() returns bytes available for the next frame, which will
// be two bytes smaller since the stream frame would need to be grown.
EXPECT_EQ(2u, creator_.ExpansionOnNewFrame());
size_t expected_bytes_free = bytes_free < 3 ? 0 : bytes_free - 2;
EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta;
- char buffer[kMaxPacketSize];
- SerializedPacket serialized_packet =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized_packet.packet);
- delete serialized_packet.packet;
- delete serialized_packet.retransmittable_frames;
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
}
}
TEST_P(QuicPacketCreatorTest, StreamFrameConsumptionWithFec) {
- // Enable FEC protection, and send FEC packet every 6 packets.
- EXPECT_TRUE(SwitchFecProtectionOn(6));
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
+ // Turn on FEC protection.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+
+ // Serialize the packet.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
// Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(IN_FEC_GROUP)
- + GetEncryptionOverhead() + GetStreamFrameOverhead(IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead(IN_FEC_GROUP) +
+ GetEncryptionOverhead() +
+ GetStreamFrameOverhead(IN_FEC_GROUP);
size_t capacity = kDefaultMaxPacketSize - overhead;
// Now, test various sizes around this size.
for (int delta = -5; delta <= 5; ++delta) {
@@ -759,32 +883,38 @@ TEST_P(QuicPacketCreatorTest, StreamFrameConsumptionWithFec) {
size_t bytes_free = delta > 0 ? 0 : 0 - delta;
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector(data));
- scoped_ptr<char[]> stream_buffer;
- size_t bytes_consumed =
- creator_.CreateStreamFrame(kClientDataStreamId1, io_vector, 0u, kOffset,
- false, &frame, &stream_buffer);
- EXPECT_EQ(capacity - bytes_free, bytes_consumed);
-
- ASSERT_TRUE(creator_.AddSavedFrame(frame));
+ ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
+ kOffset, false, false, &frame,
+ MUST_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
// BytesFree() returns bytes available for the next frame. Since stream
// frame does not grow for FEC protected packets, this should be the same
// as bytes_free (bound by 0).
EXPECT_EQ(0u, creator_.ExpansionOnNewFrame());
size_t expected_bytes_free = bytes_free > 0 ? bytes_free : 0;
EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta;
- char buffer[kMaxPacketSize];
- SerializedPacket serialized_packet =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized_packet.packet);
- delete serialized_packet.packet;
- delete serialized_packet.retransmittable_frames;
+ {
+ InSequence s;
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ // Every 6th packet will generate an extra FEC packet.
+ if (delta == -1 || delta == 5) {
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(
+ Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ }
+ }
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
+ ClearSerializedPacket(&serialized_packet_);
}
}
TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
// Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP)
- + GetEncryptionOverhead() + GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
+ GetEncryptionOverhead() +
+ GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
ASSERT_GT(kMaxPacketSize, overhead);
size_t capacity = kDefaultMaxPacketSize - overhead;
// Now, test various sizes around this size.
@@ -794,33 +924,34 @@ TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector(data));
- scoped_ptr<char[]> stream_buffer;
- size_t bytes_consumed = creator_.CreateStreamFrame(
- kCryptoStreamId, io_vector, 0u, kOffset, false, &frame, &stream_buffer);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ ASSERT_TRUE(creator_.ConsumeData(kCryptoStreamId, io_vector, 0u, kOffset,
+ false, true, &frame, MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t bytes_consumed = frame.stream_frame->frame_length;
EXPECT_LT(0u, bytes_consumed);
- ASSERT_TRUE(creator_.AddPaddedSavedFrame(frame, nullptr));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized_packet =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized_packet.packet);
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
// If there is not enough space in the packet to fit a padding frame
// (1 byte) and to expand the stream frame (another 2 bytes) the packet
// will not be padded.
if (bytes_free < 3) {
EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
- serialized_packet.packet->length());
+ serialized_packet_.packet->length());
} else {
- EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet.packet->length());
+ EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_.packet->length());
}
- delete serialized_packet.packet;
- delete serialized_packet.retransmittable_frames;
+ ClearSerializedPacket(&serialized_packet_);
}
}
TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
// Compute the total overhead for a single frame in packet.
- const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP)
- + GetEncryptionOverhead() + GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
+ const size_t overhead = GetPacketHeaderOverhead(NOT_IN_FEC_GROUP) +
+ GetEncryptionOverhead() +
+ GetStreamFrameOverhead(NOT_IN_FEC_GROUP);
ASSERT_GT(kDefaultMaxPacketSize, overhead);
size_t capacity = kDefaultMaxPacketSize - overhead;
// Now, test various sizes around this size.
@@ -830,24 +961,23 @@ TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector(data));
- scoped_ptr<char[]> stream_buffer;
- size_t bytes_consumed =
- creator_.CreateStreamFrame(kClientDataStreamId1, io_vector, 0u, kOffset,
- false, &frame, &stream_buffer);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ ASSERT_TRUE(creator_.ConsumeData(kClientDataStreamId1, io_vector, 0u,
+ kOffset, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t bytes_consumed = frame.stream_frame->frame_length;
EXPECT_LT(0u, bytes_consumed);
- ASSERT_TRUE(creator_.AddSavedFrame(frame));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized_packet =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized_packet.packet);
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
if (bytes_free > 0) {
EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
- serialized_packet.packet->length());
+ serialized_packet_.packet->length());
} else {
- EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet.packet->length());
+ EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_.packet->length());
}
- delete serialized_packet.packet;
- delete serialized_packet.retransmittable_frames;
+ ClearSerializedPacket(&serialized_packet_);
}
}
@@ -929,9 +1059,7 @@ TEST_P(QuicPacketCreatorTest, SerializeFrame) {
}
frames_.push_back(
QuicFrame(new QuicStreamFrame(0u, false, 0u, StringPiece())));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
+ SerializedPacket serialized = SerializeAllFrames(frames_);
delete frames_[0].stream_frame;
QuicPacketHeader header;
@@ -941,8 +1069,8 @@ TEST_P(QuicPacketCreatorTest, SerializeFrame) {
EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_)).WillOnce(
- DoAll(SaveArg<0>(&header), Return(true)));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+ .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
@@ -952,7 +1080,7 @@ TEST_P(QuicPacketCreatorTest, SerializeFrame) {
delete serialized.packet;
}
-TEST_P(QuicPacketCreatorTest, CreateStreamFrameTooLarge) {
+TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) {
if (!GetParam().version_serialization) {
creator_.StopSendingVersion();
}
@@ -966,17 +1094,20 @@ TEST_P(QuicPacketCreatorTest, CreateStreamFrameTooLarge) {
QuicFrame frame;
const string too_long_payload(payload_length * 2, 'a');
QuicIOVector io_vector(MakeIOVector(too_long_payload));
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(1u, io_vector, 0u, 0u, true,
- &frame, &stream_buffer);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, true, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(payload_length, consumed);
const string payload(payload_length, 'a');
CheckStreamFrame(frame, 1u, payload, 0u, false);
- RetransmittableFrames cleanup_frames(ENCRYPTION_NONE);
- cleanup_frames.AddFrame(frame);
+ creator_.Flush();
+ ClearSerializedPacket(&serialized_packet_);
}
-TEST_P(QuicPacketCreatorTest, AddFrameAndSerialize) {
+TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
if (!GetParam().version_serialization) {
creator_.StopSendingVersion();
}
@@ -987,7 +1118,8 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndSerialize) {
GetPacketHeaderSize(
creator_.connection_id_length(),
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ /*include_path_id=*/false, PACKET_1BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
creator_.BytesFree());
// Add a variety of frame types and then a padding frame.
@@ -997,40 +1129,40 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndSerialize) {
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(1u, io_vector, 0u, 0u, false,
- &frame, &stream_buffer);
- EXPECT_EQ(4u, consumed);
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
ASSERT_TRUE(frame.stream_frame);
- EXPECT_TRUE(creator_.AddSavedFrame(frame));
+ size_t consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
EXPECT_TRUE(creator_.HasPendingFrames());
QuicPaddingFrame padding_frame;
- EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(&padding_frame)));
+ EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(padding_frame)));
EXPECT_TRUE(creator_.HasPendingFrames());
EXPECT_EQ(0u, creator_.BytesFree());
+ // Packet is full. Creator will flush.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
EXPECT_FALSE(creator_.AddSavedFrame(QuicFrame(&ack_frame)));
// Ensure the packet is successfully created.
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized.packet);
- delete serialized.packet;
- ASSERT_TRUE(serialized.retransmittable_frames);
- RetransmittableFrames* retransmittable = serialized.retransmittable_frames;
+ ASSERT_TRUE(serialized_packet_.packet);
+ ASSERT_TRUE(serialized_packet_.retransmittable_frames);
+ RetransmittableFrames* retransmittable =
+ serialized_packet_.retransmittable_frames;
ASSERT_EQ(1u, retransmittable->frames().size());
EXPECT_EQ(STREAM_FRAME, retransmittable->frames()[0].type);
ASSERT_TRUE(retransmittable->frames()[0].stream_frame);
- delete serialized.retransmittable_frames;
+ ClearSerializedPacket(&serialized_packet_);
EXPECT_FALSE(creator_.HasPendingFrames());
EXPECT_EQ(max_plaintext_size -
GetPacketHeaderSize(
creator_.connection_id_length(),
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- PACKET_1BYTE_PACKET_NUMBER, NOT_IN_FEC_GROUP),
+ /*include_path_id=*/false, PACKET_1BYTE_PACKET_NUMBER,
+ NOT_IN_FEC_GROUP),
creator_.BytesFree());
}
@@ -1056,29 +1188,26 @@ TEST_P(QuicPacketCreatorTest, SerializeTruncatedAckFrameWithLargePacketSize) {
EXPECT_LT(0u, creator_.BytesFree());
// Make sure that an additional stream frame can be added to the packet.
- QuicFrame stream_frame;
+ QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(2u, io_vector, 0u, 0u, false,
- &stream_frame, &stream_buffer);
+ ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
EXPECT_EQ(4u, consumed);
- ASSERT_TRUE(stream_frame.stream_frame);
- EXPECT_TRUE(creator_.AddSavedFrame(stream_frame));
EXPECT_TRUE(creator_.HasPendingFrames());
// Ensure the packet is successfully created, and the packet size estimate
// matches the serialized packet length.
- EXPECT_CALL(entropy_calculator_,
- EntropyHash(_)).WillOnce(testing::Return(0));
+ EXPECT_CALL(entropy_calculator_, EntropyHash(_)).WillOnce(testing::Return(0));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
size_t est_packet_size = creator_.PacketSize();
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized.packet);
- EXPECT_EQ(est_packet_size,
- client_framer_.GetMaxPlaintextSize(serialized.packet->length()));
- delete serialized.retransmittable_frames;
- delete serialized.packet;
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
+ EXPECT_EQ(est_packet_size, client_framer_.GetMaxPlaintextSize(
+ serialized_packet_.packet->length()));
+ ClearSerializedPacket(&serialized_packet_);
}
TEST_P(QuicPacketCreatorTest, SerializeTruncatedAckFrameWithSmallPacketSize) {
@@ -1108,34 +1237,30 @@ TEST_P(QuicPacketCreatorTest, SerializeTruncatedAckFrameWithSmallPacketSize) {
// Ensure the packet is successfully created, and the packet size estimate
// may not match the serialized packet length.
- EXPECT_CALL(entropy_calculator_,
- EntropyHash(_)).WillOnce(Return(0));
+ EXPECT_CALL(entropy_calculator_, EntropyHash(_)).WillOnce(Return(0));
size_t est_packet_size = creator_.PacketSize();
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- ASSERT_TRUE(serialized.packet);
- EXPECT_GE(est_packet_size,
- client_framer_.GetMaxPlaintextSize(serialized.packet->length()));
- delete serialized.packet;
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
+ ASSERT_TRUE(serialized_packet_.packet);
+ EXPECT_GE(est_packet_size, client_framer_.GetMaxPlaintextSize(
+ serialized_packet_.packet->length()));
+ ClearSerializedPacket(&serialized_packet_);
}
-
TEST_P(QuicPacketCreatorTest, EntropyFlag) {
frames_.push_back(
QuicFrame(new QuicStreamFrame(0u, false, 0u, StringPiece())));
- char buffer[kMaxPacketSize];
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 64; ++j) {
- SerializedPacket serialized =
- creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
+ SerializedPacket serialized = SerializeAllFrames(frames_);
// Verify both BoolSource and hash algorithm.
bool expected_rand_bool =
(mock_random_.RandUint64() & (UINT64_C(1) << j)) != 0;
bool observed_rand_bool =
- (serialized.entropy_hash & (1 << ((j+1) % 8))) != 0;
- uint8 rest_of_hash = serialized.entropy_hash & ~(1 << ((j+1) % 8));
+ (serialized.entropy_hash & (1 << ((j + 1) % 8))) != 0;
+ uint8_t rest_of_hash = serialized.entropy_hash & ~(1 << ((j + 1) % 8));
EXPECT_EQ(expected_rand_bool, observed_rand_bool);
EXPECT_EQ(0, rest_of_hash);
delete serialized.packet;
@@ -1148,41 +1273,51 @@ TEST_P(QuicPacketCreatorTest, EntropyFlag) {
}
TEST_P(QuicPacketCreatorTest, ResetFecGroup) {
- // Enable FEC protection, and send FEC packet every 6 packets.
- EXPECT_TRUE(SwitchFecProtectionOn(6));
- frames_.push_back(
- QuicFrame(new QuicStreamFrame(0u, false, 0u, StringPiece())));
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
- delete serialized.packet;
-
- EXPECT_TRUE(creator_.IsFecProtected());
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
+ // Add a stream frame and turn on FEC protection.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ // Serialize the packet.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
+
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
EXPECT_TRUE(creator_.IsFecGroupOpen());
// We do not have enough packets in the FEC group to trigger an FEC packet.
EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
// Should return true since there are packets in the FEC group.
EXPECT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
- // Close the FEC Group.
- creator_.ResetFecGroup();
- EXPECT_TRUE(creator_.IsFecProtected());
+ // FEC group will be reset if FEC police is alarm trigger but FEC alarm does
+ // not fire.
+ EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
+ creator_.set_fec_send_policy(FEC_ALARM_TRIGGER);
+ creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
EXPECT_FALSE(creator_.IsFecGroupOpen());
// We do not have enough packets in the FEC group to trigger an FEC packet.
EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
// Confirm that there is no FEC packet under construction.
EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/true));
- EXPECT_DFATAL(serialized = creator_.SerializeFec(buffer, kMaxPacketSize),
- "SerializeFEC called but no group or zero packets in group.");
- delete serialized.packet;
-
- // Start a new FEC packet.
- serialized = creator_.SerializeAllFrames(frames_, buffer, kMaxPacketSize);
- delete frames_[0].stream_frame;
- delete serialized.packet;
-
- EXPECT_TRUE(creator_.IsFecProtected());
+ char buffer[kMaxPacketSize];
+ EXPECT_DFATAL(
+ QuicPacketCreatorPeer::SerializeFec(&creator_, buffer, kMaxPacketSize),
+ "SerializeFEC called but no group or zero packets in group.");
+
+ // Create and send a new FEC protected packet.
+ ASSERT_TRUE(creator_.ConsumeData(2u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
+
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
EXPECT_TRUE(creator_.IsFecGroupOpen());
// We do not have enough packets in the FEC group to trigger an FEC packet.
EXPECT_FALSE(creator_.ShouldSendFec(/*force_close=*/false));
@@ -1195,38 +1330,315 @@ TEST_P(QuicPacketCreatorTest, ResetFecGroup) {
// Should return true since there are packets in the FEC group.
ASSERT_TRUE(creator_.ShouldSendFec(/*force_close=*/true));
- serialized = creator_.SerializeFec(buffer, kMaxPacketSize);
- ASSERT_EQ(3u, serialized.packet_number);
- delete serialized.packet;
+ // Change FEC policy, send FEC packet and close FEC group.
+ creator_.set_fec_send_policy(FEC_ANY_TRIGGER);
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
+ ASSERT_EQ(3u, serialized_packet_.packet_number);
+ ClearSerializedPacket(&serialized_packet_);
}
TEST_P(QuicPacketCreatorTest, ResetFecGroupWithQueuedFrames) {
- // Add a stream frame to the creator.
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
+ // Add a stream frame to the creator and turn on FEC protection.
QuicFrame frame;
QuicIOVector io_vector(MakeIOVector("test"));
- scoped_ptr<char[]> stream_buffer;
- size_t consumed = creator_.CreateStreamFrame(1u, io_vector, 0u, 0u, false,
- &frame, &stream_buffer);
- EXPECT_EQ(4u, consumed);
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
ASSERT_TRUE(frame.stream_frame);
- EXPECT_TRUE(creator_.AddSavedFrame(frame));
+ size_t consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
EXPECT_TRUE(creator_.HasPendingFrames());
- EXPECT_DFATAL(creator_.ResetFecGroup(),
+ EXPECT_DFATAL(QuicPacketCreatorPeer::ResetFecGroup(&creator_),
"Cannot reset FEC group with pending frames.");
- // Serialize packet for transmission.
- char buffer[kMaxPacketSize];
- SerializedPacket serialized =
- creator_.SerializePacket(buffer, kMaxPacketSize);
- delete serialized.packet;
- delete serialized.retransmittable_frames;
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
EXPECT_FALSE(creator_.HasPendingFrames());
- // Close the FEC Group.
- creator_.ResetFecGroup();
+ // FEC group will be reset if FEC police is alarm trigger but FEC alarm does
+ // not fire.
+ EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
+ creator_.set_fec_send_policy(FEC_ALARM_TRIGGER);
+ creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
EXPECT_FALSE(creator_.IsFecGroupOpen());
}
+TEST_P(QuicPacketCreatorTest, SetCurrentPath) {
+ // Current path is the default path.
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ // Add a stream frame to the creator.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ EXPECT_EQ(0u, creator_.packet_number());
+
+ // Change current path.
+ QuicPathId kPathId1 = 1;
+ EXPECT_DFATAL(creator_.SetCurrentPath(kPathId1, 1, 0),
+ "Unable to change paths when a packet is under construction");
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .Times(1)
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
+ EXPECT_FALSE(creator_.HasPendingFrames());
+ creator_.SetCurrentPath(kPathId1, 1, 0);
+ EXPECT_EQ(kPathId1, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_FALSE(creator_.HasPendingFrames());
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+
+ // Change current path back.
+ creator_.SetCurrentPath(kDefaultPathId, 2, 1);
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_EQ(1u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ // Add a stream frame to the creator.
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+
+ // Does not change current path.
+ creator_.SetCurrentPath(kDefaultPathId, 2, 0);
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ EXPECT_EQ(1u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, SetCurrentPathWithFec) {
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
+ // Current path is the default path.
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+ // Add a stream frame to the creator.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+
+ // Change current path.
+ QuicPathId kPathId1 = 1;
+ EXPECT_DFATAL(creator_.SetCurrentPath(kPathId1, 1, 0),
+ "Unable to change paths when a packet is under construction");
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .Times(2)
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
+ EXPECT_FALSE(creator_.HasPendingFrames());
+ creator_.SetCurrentPath(kPathId1, 1, 0);
+ EXPECT_EQ(kPathId1, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_FALSE(creator_.HasPendingFrames());
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+
+ // Change current path back.
+ creator_.SetCurrentPath(kDefaultPathId, 3, 2);
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ // FEC packet consumes a packet number.
+ EXPECT_EQ(2u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ // Add a stream frame to the creator.
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+
+ // Does not change current path.
+ creator_.SetCurrentPath(kDefaultPathId, 3, 0);
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ // FEC packet consumes a packet number.
+ EXPECT_EQ(2u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest,
+ SetCurrentPathWithFecAndUpdatePacketSequenceNumberLength) {
+ // Send FEC packet every 10 packets.
+ size_t max_packets_per_fec_group = 10;
+ creator_.set_max_packets_per_fec_group(max_packets_per_fec_group);
+ // Current path is the default path.
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+ QuicPacketCreatorPeer::SetPacketNumber(
+ &creator_, 64 * 256 - max_packets_per_fec_group - 2);
+ // Add a stream frame to the creator and send the packet.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MUST_FEC_PROTECT));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .Times(2)
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
+ EXPECT_EQ(64 * 256 - max_packets_per_fec_group - 1, creator_.packet_number());
+ creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
+ EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+
+ // Change current path.
+ QuicPathId kPathId1 = 1;
+ creator_.SetCurrentPath(kPathId1, 1, 0);
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+
+ // Change current path back.
+ creator_.SetCurrentPath(kDefaultPathId, 2, 10000 / kDefaultMaxPacketSize);
+ // FEC packet consumes a packet number.
+ EXPECT_EQ(64 * 256 - max_packets_per_fec_group, creator_.packet_number());
+ EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePacketOnDifferentPath) {
+ // Current path is the default path.
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_EQ(0u, creator_.packet_number());
+ // Add a stream frame to the creator and flush the packet.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ size_t consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillRepeatedly(
+ Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.Flush();
+ EXPECT_FALSE(creator_.HasPendingFrames());
+ EXPECT_EQ(1u, creator_.packet_number());
+ // Verify serialized data packet's path id.
+ EXPECT_EQ(kDefaultPathId, serialized_packet_.path_id);
+ ClearSerializedPacket(&serialized_packet_);
+
+ // Change to path 1.
+ QuicPathId kPathId1 = 1;
+ creator_.SetCurrentPath(kPathId1, 1, 0);
+ EXPECT_EQ(kPathId1, QuicPacketCreatorPeer::GetCurrentPath(&creator_));
+ EXPECT_FALSE(creator_.HasPendingFrames());
+ EXPECT_EQ(0u, creator_.packet_number());
+ EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+ QuicPacketCreatorPeer::NextPacketNumberLength(&creator_));
+
+ // Add a stream frame to the creator and flush the packet.
+ ASSERT_TRUE(creator_.ConsumeData(1u, io_vector, 0u, 0u, false, false, &frame,
+ MAY_FEC_PROTECT));
+ ASSERT_TRUE(frame.stream_frame);
+ consumed = frame.stream_frame->frame_length;
+ EXPECT_EQ(4u, consumed);
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ creator_.Flush();
+ // Verify serialized data packet's path id.
+ EXPECT_EQ(kPathId1, serialized_packet_.path_id);
+ ClearSerializedPacket(&serialized_packet_);
+}
+
+TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) {
+ FLAGS_quic_never_write_unencrypted_data = true;
+ EXPECT_CALL(delegate_, CloseConnection(_, _));
+ QuicStreamFrame stream_frame(kHeadersStreamId, /*fin=*/false, 0u,
+ StringPiece());
+ EXPECT_DFATAL(creator_.AddSavedFrame(QuicFrame(&stream_frame)),
+ "Cannot send stream data without encryption.");
+}
+
+TEST_P(QuicPacketCreatorTest, DontSendUnencryptedFec) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_no_unencrypted_fec, true);
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
+ // Send stream data encrypted with FEC protection.
+ creator_.set_encryption_level(ENCRYPTION_INITIAL);
+ // Turn on FEC protection.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(kHeadersStreamId, io_vector, 0u, 0u, false,
+ false, &frame, MUST_FEC_PROTECT));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+ // Serialize the packet.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
+
+ // The creator will clear the FEC group rather than try to send without
+ // encryption.
+ creator_.set_encryption_level(ENCRYPTION_NONE);
+ EXPECT_CALL(delegate_, OnResetFecGroup());
+ creator_.MaybeSendFecPacketAndCloseGroup(true, false);
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeUnencryptedFecClosesConnection) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_no_unencrypted_fec, true);
+ // Send FEC packet every 6 packets.
+ creator_.set_max_packets_per_fec_group(6);
+ // Send stream data encrypted with FEC protection.
+ creator_.set_encryption_level(ENCRYPTION_INITIAL);
+ // Turn on FEC protection.
+ QuicFrame frame;
+ QuicIOVector io_vector(MakeIOVector("test"));
+ ASSERT_TRUE(creator_.ConsumeData(kHeadersStreamId, io_vector, 0u, 0u, false,
+ false, &frame, MUST_FEC_PROTECT));
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(&creator_));
+ // Serialize the packet.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacket));
+ creator_.Flush();
+
+ // Try to send an FEC packet unencrypted.
+ creator_.set_encryption_level(ENCRYPTION_NONE);
+ EXPECT_CALL(delegate_, CloseConnection(QUIC_UNENCRYPTED_FEC_DATA, _));
+ char seralized_fec_buffer[kMaxPacketSize];
+ EXPECT_DFATAL(QuicPacketCreatorPeer::SerializeFec(
+ &creator_, seralized_fec_buffer, kMaxPacketSize),
+ "SerializeFEC must be called with encryption.");
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_packet_generator.cc b/chromium/net/quic/quic_packet_generator.cc
index c85411fbfe0..50d6af11eb0 100644
--- a/chromium/net/quic/quic_packet_generator.cc
+++ b/chromium/net/quic/quic_packet_generator.cc
@@ -4,9 +4,8 @@
#include "net/quic/quic_packet_generator.h"
-#include "base/basictypes.h"
#include "base/logging.h"
-#include "net/quic/quic_ack_notifier.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
@@ -15,49 +14,30 @@ using base::StringPiece;
namespace net {
-namespace {
-
-// We want to put some space between a protected packet and the FEC packet to
-// avoid losing them both within the same loss episode. On the other hand, we
-// expect to be able to recover from any loss in about an RTT. We resolve this
-// tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half
-// the max number of in-flight packets, the first protected packet. Since we
-// don't want to delay an FEC packet past half an RTT, we set the max FEC group
-// size to be half the current congestion window.
-const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5;
-const float kRttMultiplierForFecTimeout = 0.5;
-
-// Minimum timeout for FEC alarm, set to half the minimum Tail Loss Probe
-// timeout of 10ms.
-const int64 kMinFecTimeoutMs = 5u;
-
-} // namespace
-
class QuicAckNotifier;
QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
QuicFramer* framer,
QuicRandom* random_generator,
+ QuicBufferAllocator* buffer_allocator,
DelegateInterface* delegate)
: delegate_(delegate),
- debug_delegate_(nullptr),
- packet_creator_(connection_id, framer, random_generator),
+ packet_creator_(connection_id,
+ framer,
+ random_generator,
+ buffer_allocator,
+ delegate),
batch_mode_(false),
- fec_timeout_(QuicTime::Delta::Zero()),
- rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout),
- should_fec_protect_(false),
- fec_send_policy_(FEC_ANY_TRIGGER),
should_send_ack_(false),
should_send_stop_waiting_(false),
- ack_queued_(false),
- stop_waiting_queued_(false),
max_packet_length_(kDefaultMaxPacketSize) {}
QuicPacketGenerator::~QuicPacketGenerator() {
for (QuicFrame& frame : queued_control_frames_) {
switch (frame.type) {
case PADDING_FRAME:
- delete frame.padding_frame;
+ case MTU_DISCOVERY_FRAME:
+ case PING_FRAME:
break;
case STREAM_FRAME:
delete frame.stream_frame;
@@ -65,9 +45,6 @@ QuicPacketGenerator::~QuicPacketGenerator() {
case ACK_FRAME:
delete frame.ack_frame;
break;
- case MTU_DISCOVERY_FRAME:
- delete frame.mtu_discovery_frame;
- break;
case RST_STREAM_FRAME:
delete frame.rst_stream_frame;
break;
@@ -86,9 +63,6 @@ QuicPacketGenerator::~QuicPacketGenerator() {
case STOP_WAITING_FRAME:
delete frame.stop_waiting_frame;
break;
- case PING_FRAME:
- delete frame.ping_frame;
- break;
case NUM_FRAME_TYPES:
DCHECK(false) << "Cannot delete type: " << frame.type;
}
@@ -97,23 +71,21 @@ QuicPacketGenerator::~QuicPacketGenerator() {
void QuicPacketGenerator::OnCongestionWindowChange(
QuicPacketCount max_packets_in_flight) {
- packet_creator_.set_max_packets_per_fec_group(
- static_cast<size_t>(kMaxPacketsInFlightMultiplierForFecGroupSize *
- max_packets_in_flight));
+ packet_creator_.OnCongestionWindowChange(max_packets_in_flight);
}
void QuicPacketGenerator::OnRttChange(QuicTime::Delta rtt) {
- fec_timeout_ = rtt.Multiply(rtt_multiplier_for_fec_timeout_);
+ packet_creator_.OnRttChange(rtt);
}
void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) {
- if (ack_queued_) {
+ if (packet_creator_.has_ack()) {
// Ack already queued, nothing to do.
return;
}
- if (also_send_stop_waiting && stop_waiting_queued_) {
- LOG(DFATAL) << "Should only ever be one pending stop waiting frame.";
+ if (also_send_stop_waiting && packet_creator_.has_stop_waiting()) {
+ QUIC_BUG << "Should only ever be one pending stop waiting frame.";
return;
}
@@ -129,11 +101,11 @@ void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
QuicConsumedData QuicPacketGenerator::ConsumeData(
QuicStreamId id,
- const QuicIOVector& iov,
+ QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* listener) {
bool has_handshake = id == kCryptoStreamId;
// To make reasoning about crypto frames easier, we don't combine them with
// other retransmittable frames in a single packet.
@@ -145,79 +117,51 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
bool fin_consumed = false;
if (!packet_creator_.HasRoomForStreamFrame(id, offset)) {
- SerializeAndSendPacket();
- }
-
- if (fec_protection == MUST_FEC_PROTECT) {
- MaybeStartFecProtection();
- }
-
- // This notifier will be owned by the AckNotifierManager (or deleted below) if
- // not attached to a packet.
- QuicAckNotifier* notifier = nullptr;
- if (delegate != nullptr) {
- notifier = new QuicAckNotifier(delegate);
+ packet_creator_.Flush();
}
if (!fin && (iov.total_length == 0)) {
- LOG(DFATAL) << "Attempt to consume empty data without FIN.";
+ QUIC_BUG << "Attempt to consume empty data without FIN.";
return QuicConsumedData(0, false);
}
- int frames_created = 0;
while (delegate_->ShouldGeneratePacket(
HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
QuicFrame frame;
- scoped_ptr<char[]> buffer;
- size_t bytes_consumed = packet_creator_.CreateStreamFrame(
- id, iov, total_bytes_consumed, offset + total_bytes_consumed, fin,
- &frame, &buffer);
- ++frames_created;
-
- // We want to track which packet this stream frame ends up in.
- if (notifier != nullptr) {
- ack_notifiers_.push_back(notifier);
- }
-
- if (!AddFrame(frame, buffer.get(), has_handshake)) {
- LOG(DFATAL) << "Failed to add stream frame.";
- // Inability to add a STREAM frame creates an unrecoverable hole in a
- // the stream, so it's best to close the connection.
- delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false);
- delete notifier;
+ if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed,
+ offset + total_bytes_consumed, fin,
+ has_handshake, &frame, fec_protection)) {
+ // The creator is always flushed if there's not enough room for a new
+ // stream frame before ConsumeData, so ConsumeData should always succeed.
+ QUIC_BUG << "Failed to ConsumeData, stream:" << id;
return QuicConsumedData(0, false);
}
- // When AddFrame succeeds, it takes ownership of the buffer.
- ignore_result(buffer.release());
+ // A stream frame is created and added.
+ size_t bytes_consumed = frame.stream_frame->frame_length;
+ if (listener != nullptr) {
+ packet_creator_.AddAckListener(listener, bytes_consumed);
+ }
total_bytes_consumed += bytes_consumed;
fin_consumed = fin && total_bytes_consumed == iov.total_length;
DCHECK(total_bytes_consumed == iov.total_length ||
- packet_creator_.BytesFree() == 0u);
+ (bytes_consumed > 0 && packet_creator_.HasPendingFrames()));
- if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) {
+ if (!InBatchMode()) {
// TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside
// SerializeAndSendPacket() and make it an explicit call here (and
// elsewhere where we call SerializeAndSendPacket?).
- SerializeAndSendPacket();
+ packet_creator_.Flush();
}
if (total_bytes_consumed == iov.total_length) {
// We're done writing the data. Exit the loop.
// We don't make this a precondition because we could have 0 bytes of data
// if we're simply writing a fin.
- if (fec_protection == MUST_FEC_PROTECT) {
- // Turn off FEC protection when we're done writing protected data.
- DVLOG(1) << "Turning FEC protection OFF";
- should_fec_protect_ = false;
- }
break;
}
- }
-
- if (notifier != nullptr && frames_created == 0) {
- // Safe to delete the AckNotifer as it was never attached to a packet.
- delete notifier;
+ // TODO(ianswett): Move to having the creator flush itself when it's full.
+ packet_creator_.Flush();
}
// Don't allow the handshake to be bundled with other retransmittable frames.
@@ -226,8 +170,9 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
}
// Try to close FEC group since we've either run out of data to send or we're
- // blocked. If not in batch mode, force close the group.
- MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false);
+ // blocked.
+ packet_creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false,
+ /*is_fec_timeout=*/false);
DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames());
return QuicConsumedData(total_bytes_consumed, fin_consumed);
@@ -235,29 +180,23 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
void QuicPacketGenerator::GenerateMtuDiscoveryPacket(
QuicByteCount target_mtu,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* listener) {
// MTU discovery frames must be sent by themselves.
DCHECK(!InBatchMode() && !packet_creator_.HasPendingFrames());
-
- // If an ack notifier delegate is provided, register it.
- if (delegate) {
- QuicAckNotifier* ack_notifier = new QuicAckNotifier(delegate);
- // The notifier manager will take the ownership of the notifier after the
- // packet is sent.
- ack_notifiers_.push_back(ack_notifier);
- }
-
const QuicByteCount current_mtu = GetMaxPacketLength();
// The MTU discovery frame is allocated on the stack, since it is going to be
// serialized within this function.
QuicMtuDiscoveryFrame mtu_discovery_frame;
- QuicFrame frame(&mtu_discovery_frame);
+ QuicFrame frame(mtu_discovery_frame);
// Send the probe packet with the new length.
SetMaxPacketLength(target_mtu, /*force=*/true);
- const bool success = AddFrame(frame, nullptr, /*needs_padding=*/true);
- SerializeAndSendPacket();
+ const bool success = packet_creator_.AddPaddedSavedFrame(frame);
+ if (listener != nullptr) {
+ packet_creator_.AddAckListener(listener, 0);
+ }
+ packet_creator_.Flush();
// The only reason AddFrame can fail is that the packet is too full to fit in
// a ping. This is not possible for any sane MTU.
DCHECK(success);
@@ -273,7 +212,7 @@ bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
? NO_RETRANSMITTABLE_DATA
: HAS_RETRANSMITTABLE_DATA;
if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
- DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
+ DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
}
return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE);
}
@@ -282,102 +221,28 @@ void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) {
// Only add pending frames if we are SURE we can then send the whole packet.
while (HasPendingFrames() &&
(flush || CanSendWithNextPendingFrameAddition())) {
- if (!AddNextPendingFrame()) {
- // Packet was full, so serialize and send it.
- SerializeAndSendPacket();
- }
- }
- if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) {
- SerializeAndSendPacket();
- }
- MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout);
-}
-
-void QuicPacketGenerator::MaybeStartFecProtection() {
- if (!packet_creator_.IsFecEnabled()) {
- return;
- }
- DVLOG(1) << "Turning FEC protection ON";
- should_fec_protect_ = true;
- if (packet_creator_.IsFecProtected()) {
- // Only start creator's FEC protection if not already on.
- return;
- }
- if (HasQueuedFrames()) {
- // TODO(jri): This currently requires that the generator flush out any
- // pending frames when FEC protection is turned on. If current packet can be
- // converted to an FEC protected packet, do it. This will require the
- // generator to check if the resulting expansion still allows the incoming
- // frame to be added to the packet.
- SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false);
+ AddNextPendingFrame();
}
- packet_creator_.StartFecProtectingPackets();
- DCHECK(packet_creator_.IsFecProtected());
-}
-
-void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force,
- bool is_fec_timeout) {
- if (!ShouldSendFecPacket(force)) {
- return;
+ if (flush || !InBatchMode()) {
+ packet_creator_.Flush();
}
-
- // If we want to send FEC packet only when FEC alaram goes off and if it is
- // not a FEC timeout then close the group and dont send FEC packet.
- if (fec_send_policy_ == FEC_ALARM_TRIGGER && !is_fec_timeout) {
- ResetFecGroup();
- } else {
- // TODO(jri): SerializeFec can return a NULL packet, and this should
- // cause an early return, with a call to delegate_->OnPacketGenerationError.
- char buffer[kMaxPacketSize];
- SerializedPacket serialized_fec =
- packet_creator_.SerializeFec(buffer, kMaxPacketSize);
- DCHECK(serialized_fec.packet);
- delegate_->OnSerializedPacket(serialized_fec);
- }
- // Turn FEC protection off if creator's protection is on and the creator
- // does not have an open FEC group.
- // Note: We only wait until the frames queued in the creator are flushed;
- // pending frames in the generator will not keep us from turning FEC off.
- if (!should_fec_protect_ && !packet_creator_.IsFecGroupOpen()) {
- packet_creator_.StopFecProtectingPackets();
- DCHECK(!packet_creator_.IsFecProtected());
- }
-}
-
-bool QuicPacketGenerator::ShouldSendFecPacket(bool force) {
- return packet_creator_.IsFecProtected() &&
- !packet_creator_.HasPendingFrames() &&
- packet_creator_.ShouldSendFec(force);
-}
-
-void QuicPacketGenerator::ResetFecGroup() {
- DCHECK(packet_creator_.IsFecGroupOpen());
- packet_creator_.ResetFecGroup();
- delegate_->OnResetFecGroup();
+ packet_creator_.MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout);
}
void QuicPacketGenerator::OnFecTimeout() {
DCHECK(!InBatchMode());
- if (!ShouldSendFecPacket(true)) {
- LOG(DFATAL) << "No FEC packet to send on FEC timeout.";
+ if (!packet_creator_.ShouldSendFec(true)) {
+ QUIC_BUG << "No FEC packet to send on FEC timeout.";
return;
}
// Flush out any pending frames in the generator and the creator, and then
// send out FEC packet.
SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/true);
- MaybeSendFecPacketAndCloseGroup(/*force=*/true, /*is_fec_timeout=*/true);
}
QuicTime::Delta QuicPacketGenerator::GetFecTimeout(
QuicPacketNumber packet_number) {
- // Do not set up FEC alarm for |packet_number| it is not the first packet in
- // the current group.
- if (packet_creator_.IsFecGroupOpen() &&
- (packet_number == packet_creator_.fec_group_number())) {
- return QuicTime::Delta::Max(
- fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs));
- }
- return QuicTime::Delta::Infinite();
+ return packet_creator_.GetFecTimeout(packet_number);
}
bool QuicPacketGenerator::InBatchMode() {
@@ -409,10 +274,9 @@ bool QuicPacketGenerator::HasPendingFrames() const {
bool QuicPacketGenerator::AddNextPendingFrame() {
if (should_send_ack_) {
delegate_->PopulateAckFrame(&pending_ack_frame_);
- ack_queued_ = true;
// If we can't this add the frame now, then we still need to do so later.
- should_send_ack_ = !AddFrame(QuicFrame(&pending_ack_frame_), nullptr,
- /*needs_padding=*/false);
+ should_send_ack_ =
+ !packet_creator_.AddSavedFrame(QuicFrame(&pending_ack_frame_));
// Return success if we have cleared out this flag (i.e., added the frame).
// If we still need to send, then the frame is full, and we have failed.
return !should_send_ack_;
@@ -420,11 +284,9 @@ bool QuicPacketGenerator::AddNextPendingFrame() {
if (should_send_stop_waiting_) {
delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_);
- stop_waiting_queued_ = true;
// If we can't this add the frame now, then we still need to do so later.
should_send_stop_waiting_ =
- !AddFrame(QuicFrame(&pending_stop_waiting_frame_), nullptr,
- /*needs_padding=*/false);
+ !packet_creator_.AddSavedFrame(QuicFrame(&pending_stop_waiting_frame_));
// Return success if we have cleared out this flag (i.e., added the frame).
// If we still need to send, then the frame is full, and we have failed.
return !should_send_stop_waiting_;
@@ -432,8 +294,7 @@ bool QuicPacketGenerator::AddNextPendingFrame() {
LOG_IF(DFATAL, queued_control_frames_.empty())
<< "AddNextPendingFrame called with no queued control frames.";
- if (!AddFrame(queued_control_frames_.back(), nullptr,
- /*needs_padding=*/false)) {
+ if (!packet_creator_.AddSavedFrame(queued_control_frames_.back())) {
// Packet was full.
return false;
}
@@ -441,52 +302,6 @@ bool QuicPacketGenerator::AddNextPendingFrame() {
return true;
}
-bool QuicPacketGenerator::AddFrame(const QuicFrame& frame,
- char* buffer,
- bool needs_padding) {
- bool success = needs_padding
- ? packet_creator_.AddPaddedSavedFrame(frame, buffer)
- : packet_creator_.AddSavedFrame(frame, buffer);
- if (success && debug_delegate_) {
- debug_delegate_->OnFrameAddedToPacket(frame);
- }
- return success;
-}
-
-void QuicPacketGenerator::SerializeAndSendPacket() {
- // The optimized encryption algorithm implementations run faster when
- // operating on aligned memory.
- //
- // TODO(rtenneti): Change the default 64 alignas value (used the default
- // value from CACHELINE_SIZE).
- ALIGNAS(64) char buffer[kMaxPacketSize];
- SerializedPacket serialized_packet =
- packet_creator_.SerializePacket(buffer, kMaxPacketSize);
- if (serialized_packet.packet == nullptr) {
- LOG(DFATAL) << "Failed to SerializePacket. fec_policy:" << fec_send_policy_
- << " should_fec_protect_:" << should_fec_protect_;
- delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false);
- return;
- }
-
- // There may be AckNotifiers interested in this packet.
- serialized_packet.notifiers.swap(ack_notifiers_);
- ack_notifiers_.clear();
-
- delegate_->OnSerializedPacket(serialized_packet);
- MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false);
-
- // Maximum packet size may be only enacted while no packet is currently being
- // constructed, so here we have a good opportunity to actually change it.
- if (packet_creator_.CanSetMaxPacketLength()) {
- packet_creator_.SetMaxPacketLength(max_packet_length_);
- }
-
- // The packet has now been serialized, so the frames are no longer queued.
- ack_queued_ = false;
- stop_waiting_queued_ = false;
-}
-
void QuicPacketGenerator::StopSendingVersion() {
packet_creator_.StopSendingVersion();
}
@@ -509,7 +324,8 @@ void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length, bool force) {
// FEC group.
if (!packet_creator_.CanSetMaxPacketLength() && force) {
SendQueuedFrames(/*flush=*/true, /*is_fec_timeout=*/false);
- MaybeSendFecPacketAndCloseGroup(/*force=*/true, /*is_fec_timeout=*/false);
+ packet_creator_.MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true,
+ /*is_fec_timeout=*/false);
DCHECK(packet_creator_.CanSetMaxPacketLength());
}
@@ -526,11 +342,12 @@ QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket(
SerializedPacket QuicPacketGenerator::ReserializeAllFrames(
const RetransmittableFrames& frames,
+ EncryptionLevel original_encryption_level,
QuicPacketNumberLength original_length,
char* buffer,
size_t buffer_len) {
- return packet_creator_.ReserializeAllFrames(frames, original_length, buffer,
- buffer_len);
+ return packet_creator_.ReserializeAllFrames(
+ frames, original_encryption_level, original_length, buffer, buffer_len);
}
void QuicPacketGenerator::UpdateSequenceNumberLength(
@@ -540,7 +357,7 @@ void QuicPacketGenerator::UpdateSequenceNumberLength(
max_packets_in_flight);
}
-void QuicPacketGenerator::SetConnectionIdLength(uint32 length) {
+void QuicPacketGenerator::SetConnectionIdLength(uint32_t length) {
if (length == 0) {
packet_creator_.set_connection_id_length(PACKET_0BYTE_CONNECTION_ID);
} else if (length == 1) {
@@ -561,4 +378,26 @@ void QuicPacketGenerator::SetEncrypter(EncryptionLevel level,
packet_creator_.SetEncrypter(level, encrypter);
}
+void QuicPacketGenerator::SetCurrentPath(
+ QuicPathId path_id,
+ QuicPacketNumber least_packet_awaited_by_peer,
+ QuicPacketCount max_packets_in_flight) {
+ packet_creator_.SetCurrentPath(path_id, least_packet_awaited_by_peer,
+ max_packets_in_flight);
+}
+
+void QuicPacketGenerator::set_rtt_multiplier_for_fec_timeout(
+ float rtt_multiplier_for_fec_timeout) {
+ packet_creator_.set_rtt_multiplier_for_fec_timeout(
+ rtt_multiplier_for_fec_timeout);
+}
+
+FecSendPolicy QuicPacketGenerator::fec_send_policy() {
+ return packet_creator_.fec_send_policy();
+}
+
+void QuicPacketGenerator::set_fec_send_policy(FecSendPolicy fec_send_policy) {
+ packet_creator_.set_fec_send_policy(fec_send_policy);
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_packet_generator.h b/chromium/net/quic/quic_packet_generator.h
index 4f738bda3cf..8f3182d839e 100644
--- a/chromium/net/quic/quic_packet_generator.h
+++ b/chromium/net/quic/quic_packet_generator.h
@@ -53,9 +53,12 @@
#ifndef NET_QUIC_QUIC_PACKET_GENERATOR_H_
#define NET_QUIC_QUIC_PACKET_GENERATOR_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
-#include "net/quic/quic_ack_notifier.h"
+#include "base/macros.h"
#include "net/quic/quic_packet_creator.h"
#include "net/quic/quic_sent_packet_manager.h"
#include "net/quic/quic_types.h"
@@ -68,38 +71,25 @@ class QuicPacketGeneratorPeer;
class NET_EXPORT_PRIVATE QuicPacketGenerator {
public:
- class NET_EXPORT_PRIVATE DelegateInterface {
+ class NET_EXPORT_PRIVATE DelegateInterface
+ : public QuicPacketCreator::DelegateInterface {
public:
- virtual ~DelegateInterface() {}
+ ~DelegateInterface() override {}
+ // Consults delegate whether a packet should be generated.
virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
IsHandshake handshake) = 0;
virtual void PopulateAckFrame(QuicAckFrame* ack) = 0;
virtual void PopulateStopWaitingFrame(
QuicStopWaitingFrame* stop_waiting) = 0;
- // Takes ownership of |packet.packet| and |packet.retransmittable_frames|.
- virtual void OnSerializedPacket(const SerializedPacket& packet) = 0;
- virtual void CloseConnection(QuicErrorCode error, bool from_peer) = 0;
- // Called when a FEC Group is reset (closed).
- virtual void OnResetFecGroup() = 0;
- };
-
- // Interface which gets callbacks from the QuicPacketGenerator at interesting
- // points. Implementations must not mutate the state of the generator
- // as a result of these callbacks.
- class NET_EXPORT_PRIVATE DebugDelegate {
- public:
- virtual ~DebugDelegate() {}
-
- // Called when a frame has been added to the current packet.
- virtual void OnFrameAddedToPacket(const QuicFrame& frame) {}
};
QuicPacketGenerator(QuicConnectionId connection_id,
QuicFramer* framer,
QuicRandom* random_generator,
+ QuicBufferAllocator* buffer_allocator,
DelegateInterface* delegate);
- virtual ~QuicPacketGenerator();
+ ~QuicPacketGenerator();
// Called by the connection in the event of the congestion window changing.
void OnCongestionWindowChange(QuicPacketCount max_packets_in_flight);
@@ -122,15 +112,15 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// |delegate| (if not nullptr) will be informed once all packets sent as a
// result of this call are ACKed by the peer.
QuicConsumedData ConsumeData(QuicStreamId id,
- const QuicIOVector& iov,
+ QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* delegate);
+ QuicAckListenerInterface* listener);
// Generates an MTU discovery packet of specified size.
void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu,
- QuicAckNotifier::DelegateInterface* delegate);
+ QuicAckListenerInterface* listener);
// Indicates whether batch mode is currently enabled.
bool InBatchMode();
@@ -158,10 +148,12 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// Used for retransmitting packets to ensure they aren't too long.
// Caller must ensure that any open FEC group is closed before calling this
// method.
- SerializedPacket ReserializeAllFrames(const RetransmittableFrames& frames,
- QuicPacketNumberLength original_length,
- char* buffer,
- size_t buffer_len);
+ SerializedPacket ReserializeAllFrames(
+ const RetransmittableFrames& frames,
+ EncryptionLevel original_encryption_level,
+ QuicPacketNumberLength original_length,
+ char* buffer,
+ size_t buffer_len);
// Update the packet number length to use in future packets as soon as it
// can be safely changed.
@@ -169,7 +161,7 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
QuicPacketCount max_packets_in_flight);
// Set the minimum number of bytes for the connection id length;
- void SetConnectionIdLength(uint32 length);
+ void SetConnectionIdLength(uint32_t length);
// Called when the FEC alarm fires.
void OnFecTimeout();
@@ -204,68 +196,37 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// immediately. Otherwise, it is enacted at the next opportunity.
void SetMaxPacketLength(QuicByteCount length, bool force);
- void set_debug_delegate(DebugDelegate* debug_delegate) {
- debug_delegate_ = debug_delegate;
- }
+ // Sets |path_id| to be the path on which next packet is generated.
+ void SetCurrentPath(QuicPathId path_id,
+ QuicPacketNumber least_packet_awaited_by_peer,
+ QuicPacketCount max_packets_in_flight);
- // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
- float rtt_multiplier_for_fec_timeout() {
- return rtt_multiplier_for_fec_timeout_;
- }
- void set_rtt_multiplier_for_fec_timeout(
- float rtt_multiplier_for_fec_timeout) {
- rtt_multiplier_for_fec_timeout_ = rtt_multiplier_for_fec_timeout;
+ void set_debug_delegate(QuicPacketCreator::DebugDelegate* debug_delegate) {
+ packet_creator_.set_debug_delegate(debug_delegate);
}
- FecSendPolicy fec_send_policy() { return fec_send_policy_; }
- void set_fec_send_policy(FecSendPolicy fec_send_policy) {
- fec_send_policy_ = fec_send_policy;
- }
+ void set_rtt_multiplier_for_fec_timeout(float rtt_multiplier_for_fec_timeout);
+
+ FecSendPolicy fec_send_policy();
+ void set_fec_send_policy(FecSendPolicy fec_send_policy);
private:
friend class test::QuicPacketGeneratorPeer;
- // Turn on FEC protection for subsequent packets in the generator.
- // If no FEC group is currently open in the creator, this method flushes any
- // queued frames in the generator and in the creator, and it then turns FEC on
- // in the creator. This method may be called with an open FEC group in the
- // creator, in which case, only the generator's state is altered.
- void MaybeStartFecProtection();
-
- // Serializes and calls the delegate on an FEC packet if one was under
- // construction in the creator. When |force| is false, it relies on the
- // creator being ready to send an FEC packet, otherwise FEC packet is sent
- // as long as one is under construction in the creator. Also tries to turn
- // off FEC protection in the creator if it's off in the generator.
- // When |fec_send_policy_| is FEC_SEND_QUIESCENCE, then send FEC
- // packet if |is_fec_timeout| is true otherwise close the FEC group.
- void MaybeSendFecPacketAndCloseGroup(bool force, bool is_fec_timeout);
-
- // Returns true if an FEC packet should be generated based on |force| and
- // current state of the generator and the creator.
- bool ShouldSendFecPacket(bool force);
-
- // Resets (closes) the FEC group and calls the Delegate's OnResetFecGroup.
- // Asserts that FEC group is open.
- void ResetFecGroup();
-
void SendQueuedFrames(bool flush, bool is_fec_timeout);
// Test to see if we have pending ack, or control frames.
bool HasPendingFrames() const;
- // Test to see if the addition of a pending frame (which might be
+ // Returns true if addition of a pending frame (which might be
// retransmittable) would still allow the resulting packet to be sent now.
bool CanSendWithNextPendingFrameAddition() const;
// Add exactly one pending frame, preferring ack frames over control frames.
+ // Returns true if a pending frame is successfully added.
+ // Returns false and flushes current open packet if the pending frame cannot
+ // fit into current open packet.
bool AddNextPendingFrame();
- // Adds a frame and takes ownership of the underlying buffer if the addition
- // was successful.
- bool AddFrame(const QuicFrame& frame, char* buffer, bool needs_padding);
-
- void SerializeAndSendPacket();
DelegateInterface* delegate_;
- DebugDelegate* debug_delegate_;
QuicPacketCreator packet_creator_;
QuicFrames queued_control_frames_;
@@ -273,21 +234,6 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// True if batch mode is currently enabled.
bool batch_mode_;
- // Timeout used for FEC alarm. Can be set to zero initially or if the SRTT has
- // not yet been set.
- QuicTime::Delta fec_timeout_;
-
- // The multiplication factor for FEC timeout based on RTT.
- // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
- float rtt_multiplier_for_fec_timeout_;
-
- // True if FEC protection is on. The creator may have an open FEC group even
- // if this variable is false.
- bool should_fec_protect_;
-
- // FEC policy that specifies when to send FEC packet.
- FecSendPolicy fec_send_policy_;
-
// Flags to indicate the need for just-in-time construction of a frame.
bool should_send_ack_;
bool should_send_stop_waiting_;
@@ -297,13 +243,6 @@ class NET_EXPORT_PRIVATE QuicPacketGenerator {
// retransmitted.
QuicAckFrame pending_ack_frame_;
QuicStopWaitingFrame pending_stop_waiting_frame_;
- // True if an ack or stop waiting frame is already queued, and should not be
- // re-added.
- bool ack_queued_;
- bool stop_waiting_queued_;
-
- // Stores notifiers that should be attached to the next serialized packet.
- std::list<QuicAckNotifier*> ack_notifiers_;
// Stores the maximum packet size we are allowed to send. This might not be
// the maximum size we are actually using now, if we are in the middle of the
diff --git a/chromium/net/quic/quic_packet_generator_test.cc b/chromium/net/quic/quic_packet_generator_test.cc
index 7d99e158f08..4bd81a791c5 100644
--- a/chromium/net/quic/quic_packet_generator_test.cc
+++ b/chromium/net/quic/quic_packet_generator_test.cc
@@ -6,11 +6,13 @@
#include <string>
+#include "base/macros.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/null_encrypter.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/quic_flags.h"
+#include "net/quic/quic_simple_buffer_allocator.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/quic_packet_creator_peer.h"
#include "net/quic/test_tools/quic_packet_generator_peer.h"
@@ -32,11 +34,10 @@ namespace net {
namespace test {
namespace {
-const int64 kMinFecTimeoutMs = 5u;
+const int64_t kMinFecTimeoutMs = 5u;
static const FecSendPolicy kFecSendPolicyList[] = {
- FEC_ANY_TRIGGER,
- FEC_ALARM_TRIGGER,
+ FEC_ANY_TRIGGER, FEC_ALARM_TRIGGER,
};
class MockDelegate : public QuicPacketGenerator::DelegateInterface {
@@ -49,7 +50,7 @@ class MockDelegate : public QuicPacketGenerator::DelegateInterface {
IsHandshake handshake));
MOCK_METHOD1(PopulateAckFrame, void(QuicAckFrame*));
MOCK_METHOD1(PopulateStopWaitingFrame, void(QuicStopWaitingFrame*));
- MOCK_METHOD1(OnSerializedPacket, void(const SerializedPacket& packet));
+ MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet));
MOCK_METHOD2(CloseConnection, void(QuicErrorCode, bool));
MOCK_METHOD0(OnResetFecGroup, void());
@@ -113,9 +114,12 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
: framer_(QuicSupportedVersions(),
QuicTime::Zero(),
Perspective::IS_CLIENT),
- generator_(42, &framer_, &random_, &delegate_),
+ generator_(42, &framer_, &random_, &buffer_allocator_, &delegate_),
creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)) {
generator_.set_fec_send_policy(GetParam());
+ // TODO(ianswett): Fix this test so it uses a non-null encrypter.
+ FLAGS_quic_never_write_unencrypted_data = false;
+ FLAGS_quic_no_unencrypted_fec = false;
}
~QuicPacketGeneratorTest() override {
@@ -125,9 +129,9 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
}
}
- void SavePacket(const SerializedPacket& packet) {
- packets_.push_back(packet);
- ASSERT_FALSE(packet.packet->owns_buffer());
+ void SavePacket(SerializedPacket* packet) {
+ packets_.push_back(*packet);
+ ASSERT_FALSE(packet->packet->owns_buffer());
scoped_ptr<QuicEncryptedPacket> encrypted_deleter(packets_.back().packet);
packets_.back().packet = packets_.back().packet->Clone();
}
@@ -206,7 +210,6 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
ASSERT_TRUE(packet.packet != nullptr);
ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
EXPECT_TRUE(simple_framer_.header().fec_flag);
- EXPECT_EQ(fec_group, simple_framer_.fec_data().fec_group);
}
QuicIOVector CreateData(size_t len) {
@@ -223,6 +226,7 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
QuicFramer framer_;
MockRandom random_;
+ SimpleBufferAllocator buffer_allocator_;
StrictMock<MockDelegate> delegate_;
QuicPacketGenerator generator_;
QuicPacketCreator* creator_;
@@ -234,10 +238,9 @@ class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
struct iovec iov_;
};
-class MockDebugDelegate : public QuicPacketGenerator::DebugDelegate {
+class MockDebugDelegate : public QuicPacketCreator::DebugDelegate {
public:
- MOCK_METHOD1(OnFrameAddedToPacket,
- void(const QuicFrame&));
+ MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&));
};
// Run all end to end tests with all supported FEC send polocies.
@@ -500,7 +503,7 @@ TEST_P(QuicPacketGeneratorTest, ConsumeDataFecOnMaxGroupSize) {
CheckPacketIsFec(2, 1);
CheckPacketHasSingleStreamFrame(3);
}
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// If FEC send policy is FEC_ANY_TRIGGER, then the FEC packet under
// construction will be sent when one more packet is sent (since FEC group
@@ -530,7 +533,7 @@ TEST_P(QuicPacketGeneratorTest, ConsumeDataFecOnMaxGroupSize) {
CheckPacketHasSingleStreamFrame(4);
CheckPacketIsFec(5, 4);
}
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicPacketGeneratorTest, ConsumeDataSendsFecOnTimeout) {
@@ -546,7 +549,7 @@ TEST_P(QuicPacketGeneratorTest, ConsumeDataSendsFecOnTimeout) {
EXPECT_EQ(1u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
CheckPacketHasSingleStreamFrame(0);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Send more data with MAY_FEC_PROTECT. This packet should also be protected,
// and FEC packet is not yet sent.
@@ -556,14 +559,14 @@ TEST_P(QuicPacketGeneratorTest, ConsumeDataSendsFecOnTimeout) {
nullptr);
EXPECT_EQ(1u, consumed.bytes_consumed);
CheckPacketHasSingleStreamFrame(1);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Calling OnFecTimeout should cause the FEC packet to be emitted.
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
generator_.OnFecTimeout();
CheckPacketIsFec(2, 1);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Subsequent data is protected under the next FEC group. Send enough data to
// create 2 more packets: one full and one partial.
@@ -581,14 +584,14 @@ TEST_P(QuicPacketGeneratorTest, ConsumeDataSendsFecOnTimeout) {
EXPECT_TRUE(consumed.fin_consumed);
CheckPacketHasSingleStreamFrame(3);
CheckPacketHasSingleStreamFrame(4);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Calling OnFecTimeout should cause the FEC packet to be emitted.
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
generator_.OnFecTimeout();
CheckPacketIsFec(5, 4);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
@@ -613,7 +616,7 @@ TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
EXPECT_FALSE(generator_.HasQueuedFrames());
CheckPacketHasSingleStreamFrame(0);
CheckPacketHasSingleStreamFrame(1);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// GetFecTimeout returns finite timeout only for first packet in group.
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs),
@@ -628,7 +631,7 @@ TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
nullptr);
CheckPacketHasSingleStreamFrame(2);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// GetFecTimeout returns finite timeout only for first packet in group.
EXPECT_EQ(QuicTime::Delta::Infinite(),
@@ -639,7 +642,7 @@ TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
generator_.OnFecTimeout();
CheckPacketIsFec(3, /*fec_group=*/1u);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Subsequent data is protected under the next FEC group. Send enough data to
// create 2 more packets: one full and one partial.
@@ -657,7 +660,7 @@ TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
EXPECT_TRUE(consumed.fin_consumed);
CheckPacketHasSingleStreamFrame(4);
CheckPacketHasSingleStreamFrame(5);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// GetFecTimeout returns finite timeout for first packet in the new group.
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs),
@@ -670,7 +673,7 @@ TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
generator_.OnFecTimeout();
CheckPacketIsFec(6, /*fec_group=*/5u);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Send more data with MAY_FEC_PROTECT. No FEC protection, so GetFecTimeout
// returns infinite.
@@ -679,7 +682,7 @@ TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
consumed = generator_.ConsumeData(9, CreateData(1u), 0, true, MAY_FEC_PROTECT,
nullptr);
CheckPacketHasSingleStreamFrame(7);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
EXPECT_EQ(QuicTime::Delta::Infinite(),
generator_.GetFecTimeout(/*packet_number=*/8u));
}
@@ -690,7 +693,7 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
size_t length =
NullEncrypter().GetCiphertextSize(0) +
GetPacketHeaderSize(
- creator_->connection_id_length(), true,
+ creator_->connection_id_length(), true, /*include_path_id=*/false,
QuicPacketCreatorPeer::NextPacketNumberLength(creator_),
NOT_IN_FEC_GROUP) +
// Add an extra 3 bytes for the payload and 1 byte so BytesFree is larger
@@ -700,11 +703,11 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
generator_.SetMaxPacketLength(length, /*force=*/false);
delegate_.SetCanWriteAnything();
{
- InSequence dummy;
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
+ InSequence dummy;
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
}
generator_.StartBatchOperations();
// Queue enough data to prevent a stream frame with a non-zero offset from
@@ -717,12 +720,14 @@ TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
EXPECT_TRUE(generator_.HasQueuedFrames());
// This frame will not fit with the existing frame, causing the queued frame
- // to be serialized, and it will not fit with another frame like it, so it is
- // serialized by itself.
+ // to be serialized, and it will be added to a new open packet.
consumed = generator_.ConsumeData(kHeadersStreamId, MakeIOVector("bar"), 3,
true, MAY_FEC_PROTECT, nullptr);
EXPECT_EQ(3u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
+ EXPECT_TRUE(generator_.HasQueuedFrames());
+
+ creator_->Flush();
EXPECT_FALSE(generator_.HasQueuedFrames());
PacketContents contents;
@@ -765,10 +770,10 @@ TEST_P(QuicPacketGeneratorTest, NoFecPacketSentWhenBatchEnds) {
TEST_P(QuicPacketGeneratorTest, FecTimeoutOnRttChange) {
EXPECT_EQ(QuicTime::Delta::Zero(),
- QuicPacketGeneratorPeer::GetFecTimeout(&generator_));
+ QuicPacketCreatorPeer::GetFecTimeout(creator_));
generator_.OnRttChange(QuicTime::Delta::FromMilliseconds(300));
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
- QuicPacketGeneratorPeer::GetFecTimeout(&generator_));
+ QuicPacketCreatorPeer::GetFecTimeout(creator_));
}
TEST_P(QuicPacketGeneratorTest, FecGroupSizeOnCongestionWindowChange) {
@@ -842,13 +847,13 @@ TEST_P(QuicPacketGeneratorTest, FecGroupSizeChangeWithOpenGroup) {
CheckPacketIsFec(4, /*fec_group=*/1u);
}
EXPECT_FALSE(creator_->IsFecGroupOpen());
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicPacketGeneratorTest, SwitchFecOnOff) {
delegate_.SetCanWriteAnything();
creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Send one unprotected data packet.
EXPECT_CALL(delegate_, OnSerializedPacket(_))
@@ -857,7 +862,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOff) {
MAY_FEC_PROTECT, nullptr);
EXPECT_EQ(1u, consumed.bytes_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Verify that one data packet was sent.
PacketContents contents;
contents.num_stream_frames = 1;
@@ -917,7 +922,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOff) {
nullptr);
EXPECT_EQ(1u, consumed.bytes_consumed);
EXPECT_FALSE(generator_.HasQueuedFrames());
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Verify that one unprotected data packet was sent.
if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
CheckPacketContains(contents, 5);
@@ -942,7 +947,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFrameInCreator) {
// Queue protected data for sending. Should cause queued frames to be flushed.
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
MUST_FEC_PROTECT, nullptr);
EXPECT_EQ(1u, consumed.bytes_consumed);
@@ -950,7 +955,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFrameInCreator) {
contents.num_stream_frames = 1;
// Transmitted packet was not FEC protected.
CheckPacketContains(contents, 0);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
EXPECT_TRUE(creator_->HasPendingFrames());
}
@@ -971,7 +976,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFramesInGenerator) {
// Generator should have queued control frames, and creator should be empty.
EXPECT_TRUE(generator_.HasQueuedFrames());
EXPECT_FALSE(creator_->HasPendingFrames());
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Queue protected data for sending. Should cause queued frames to be flushed.
EXPECT_CALL(delegate_, OnSerializedPacket(_))
@@ -985,7 +990,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFramesInGenerator) {
CheckPacketContains(contents, 0);
// FEC protection should be on in creator.
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentFramesProtected) {
@@ -993,7 +998,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentFramesProtected) {
// Enable FEC.
creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Queue stream frame to be protected in creator.
generator_.StartBatchOperations();
@@ -1002,7 +1007,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentFramesProtected) {
EXPECT_EQ(1u, consumed.bytes_consumed);
// Creator has a pending protected frame.
EXPECT_TRUE(creator_->HasPendingFrames());
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Add enough unprotected data to exceed size of current packet, so that
// current packet is sent. Both frames will be sent out in a single packet.
@@ -1017,7 +1022,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentFramesProtected) {
contents.fec_group = 1u;
CheckPacketContains(contents, 0);
// FEC protection should still be on in creator.
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) {
@@ -1025,7 +1030,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) {
// Enable FEC.
creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Send first packet, FEC protected.
EXPECT_CALL(delegate_, OnSerializedPacket(_))
@@ -1039,7 +1044,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) {
CheckPacketContains(contents, 0);
// FEC should still be on in creator.
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Send unprotected data to cause second packet to be sent, which gets
// protected because it happens to fall within an open FEC group. Data packet
@@ -1066,7 +1071,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) {
}
// FEC protection should be off in creator.
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) {
@@ -1075,7 +1080,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) {
// Enable FEC.
creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Queue one byte of FEC protected data.
QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
@@ -1095,7 +1100,7 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) {
CheckPacketContains(contents, 0);
// FEC group is still open in creator.
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Add data that should be protected, large enough to cause second packet to
// be sent. Data packet should be followed by FEC packet.
@@ -1120,14 +1125,14 @@ TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) {
}
// FEC protection should remain on in creator.
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
TEST_P(QuicPacketGeneratorTest, ResetFecGroupNoTimeout) {
delegate_.SetCanWriteAnything();
// Send FEC packet after 2 packets.
creator_->set_max_packets_per_fec_group(2);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Send two packets so that when this data is consumed, two packets are sent
// out. In FEC_TRIGGER_ANY, this will cause an FEC packet to be sent out and
@@ -1168,7 +1173,7 @@ TEST_P(QuicPacketGeneratorTest, ResetFecGroupNoTimeout) {
CheckPacketIsFec(2, 1);
CheckPacketHasSingleStreamFrame(3);
}
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Do the same send (with MUST_FEC_PROTECT) on a different stream id.
{
@@ -1218,7 +1223,35 @@ TEST_P(QuicPacketGeneratorTest, ResetFecGroupNoTimeout) {
// FEC_ANY_TRIGGER.
CheckPacketIsFec(8, 7);
}
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
+
+ // Do the another send (with MAY_FEC_PROTECT) on a different stream id, which
+ // should not produce an FEC packet because the last FEC group has been
+ // closed.
+ {
+ InSequence dummy;
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
+ }
+ consumed = generator_.ConsumeData(9, CreateData(data_len), 0, true,
+ MAY_FEC_PROTECT, nullptr);
+ EXPECT_EQ(data_len, consumed.bytes_consumed);
+ EXPECT_TRUE(consumed.fin_consumed);
+ EXPECT_FALSE(generator_.HasQueuedFrames());
+ if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
+ CheckPacketHasSingleStreamFrame(6);
+ CheckPacketHasSingleStreamFrame(7);
+ CheckPacketHasSingleStreamFrame(8);
+ } else {
+ CheckPacketHasSingleStreamFrame(9);
+ CheckPacketHasSingleStreamFrame(10);
+ CheckPacketHasSingleStreamFrame(11);
+ }
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
// 1. Create and send one packet with MUST_FEC_PROTECT.
@@ -1227,7 +1260,7 @@ TEST_P(QuicPacketGeneratorTest, ResetFecGroupNoTimeout) {
TEST_P(QuicPacketGeneratorTest, FecPacketSentOnFecTimeout) {
delegate_.SetCanWriteAnything();
creator_->set_max_packets_per_fec_group(1000);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
for (int i = 1; i < 4; i = i + 2) {
// Send data with MUST_FEC_PROTECT flag. No FEC packet is emitted, but the
@@ -1239,14 +1272,14 @@ TEST_P(QuicPacketGeneratorTest, FecPacketSentOnFecTimeout) {
EXPECT_EQ(1u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
CheckPacketHasSingleStreamFrame(0);
- EXPECT_TRUE(creator_->IsFecProtected());
+ EXPECT_TRUE(QuicPacketCreatorPeer::IsFecProtected(creator_));
// Calling OnFecTimeout should cause the FEC packet to be emitted.
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
generator_.OnFecTimeout();
CheckPacketIsFec(i, i);
- EXPECT_FALSE(creator_->IsFecProtected());
+ EXPECT_FALSE(QuicPacketCreatorPeer::IsFecProtected(creator_));
}
}
@@ -1651,5 +1684,34 @@ TEST_P(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) {
"for least_unacked_delta: 1001");
}
+TEST_P(QuicPacketGeneratorTest, SetCurrentPath) {
+ delegate_.SetCanWriteAnything();
+ generator_.StartBatchOperations();
+
+ QuicConsumedData consumed = generator_.ConsumeData(
+ kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
+ EXPECT_EQ(3u, consumed.bytes_consumed);
+ EXPECT_TRUE(consumed.fin_consumed);
+ EXPECT_TRUE(generator_.HasQueuedFrames());
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(creator_));
+ // Does not change current path.
+ generator_.SetCurrentPath(kDefaultPathId, 1, 0);
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(creator_));
+
+ // Try to switch path when a packet is under construction.
+ QuicPathId kTestPathId1 = 1;
+ EXPECT_DFATAL(generator_.SetCurrentPath(kTestPathId1, 1, 0),
+ "Unable to change paths when a packet is under construction");
+ EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(creator_));
+
+ // Try to switch path after current open packet gets serialized.
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
+ generator_.FlushAllQueuedFrames();
+ EXPECT_FALSE(generator_.HasQueuedFrames());
+ generator_.SetCurrentPath(kTestPathId1, 1, 0);
+ EXPECT_EQ(kTestPathId1, QuicPacketCreatorPeer::GetCurrentPath(creator_));
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_packet_reader.cc b/chromium/net/quic/quic_packet_reader.cc
index 7b90dc9bb9e..c3e37edafdd 100644
--- a/chromium/net/quic/quic_packet_reader.cc
+++ b/chromium/net/quic/quic_packet_reader.cc
@@ -32,8 +32,7 @@ QuicPacketReader::QuicPacketReader(DatagramClientSocket* socket,
net_log_(net_log),
weak_factory_(this) {}
-QuicPacketReader::~QuicPacketReader() {
-}
+QuicPacketReader::~QuicPacketReader() {}
void QuicPacketReader::StartReading() {
if (read_pending_)
@@ -73,7 +72,7 @@ void QuicPacketReader::OnReadComplete(int result) {
result = ERR_CONNECTION_CLOSED;
if (result < 0) {
- visitor_->OnReadError(result);
+ visitor_->OnReadError(result, socket_);
return;
}
diff --git a/chromium/net/quic/quic_packet_reader.h b/chromium/net/quic/quic_packet_reader.h
index 02c38774999..56630346c03 100644
--- a/chromium/net/quic/quic_packet_reader.h
+++ b/chromium/net/quic/quic_packet_reader.h
@@ -6,6 +6,7 @@
#ifndef NET_QUIC_QUIC_PACKET_READER_H_
#define NET_QUIC_QUIC_PACKET_READER_H_
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/io_buffer.h"
#include "net/base/net_export.h"
@@ -28,8 +29,9 @@ class NET_EXPORT_PRIVATE QuicPacketReader {
public:
class NET_EXPORT_PRIVATE Visitor {
public:
- virtual ~Visitor() {};
- virtual void OnReadError(int result) = 0;
+ virtual ~Visitor(){};
+ virtual void OnReadError(int result,
+ const DatagramClientSocket* socket) = 0;
virtual bool OnPacket(const QuicEncryptedPacket& packet,
IPEndPoint local_address,
IPEndPoint peer_address) = 0;
diff --git a/chromium/net/quic/quic_packet_writer.h b/chromium/net/quic/quic_packet_writer.h
index b1eb148a520..4c9963adc0c 100644
--- a/chromium/net/quic/quic_packet_writer.h
+++ b/chromium/net/quic/quic_packet_writer.h
@@ -5,6 +5,8 @@
#ifndef NET_QUIC_QUIC_PACKET_WRITER_H_
#define NET_QUIC_QUIC_PACKET_WRITER_H_
+#include <stddef.h>
+
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_protocol.h"
@@ -23,10 +25,10 @@ class NET_EXPORT_PRIVATE QuicPacketWriter {
// status is WRITE_STATUS_OK and bytes_written is populated. If the write
// failed, the result's status is WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR
// and error_code is populated.
- virtual WriteResult WritePacket(
- const char* buffer, size_t buf_len,
- const IPAddressNumber& self_address,
- const IPEndPoint& peer_address) = 0;
+ virtual WriteResult WritePacket(const char* buffer,
+ size_t buf_len,
+ const IPAddressNumber& self_address,
+ const IPEndPoint& peer_address) = 0;
// Returns true if the writer buffers and subsequently rewrites data
// when an attempt to write results in the underlying socket becoming
diff --git a/chromium/net/quic/quic_protocol.cc b/chromium/net/quic/quic_protocol.cc
index 651ee84cd78..a5fb29cf2dd 100644
--- a/chromium/net/quic/quic_protocol.cc
+++ b/chromium/net/quic/quic_protocol.cc
@@ -16,19 +16,23 @@ using std::string;
namespace net {
+const char* const kFinalOffsetHeaderKey = ":final-offset";
+
size_t GetPacketHeaderSize(const QuicPacketHeader& header) {
- return GetPacketHeaderSize(header.public_header.connection_id_length,
- header.public_header.version_flag,
- header.public_header.packet_number_length,
- header.is_in_fec_group);
+ return GetPacketHeaderSize(
+ header.public_header.connection_id_length,
+ header.public_header.version_flag, header.public_header.multipath_flag,
+ header.public_header.packet_number_length, header.is_in_fec_group);
}
size_t GetPacketHeaderSize(QuicConnectionIdLength connection_id_length,
bool include_version,
+ bool include_path_id,
QuicPacketNumberLength packet_number_length,
InFecGroup is_in_fec_group) {
return kPublicFlagsSize + connection_id_length +
- (include_version ? kQuicVersionSize : 0) + packet_number_length +
+ (include_version ? kQuicVersionSize : 0) +
+ (include_path_id ? kQuicPathIdSize : 0) + packet_number_length +
kPrivateFlagsSize +
(is_in_fec_group == IN_FEC_GROUP ? kFecGroupSize : 0);
}
@@ -37,7 +41,8 @@ size_t GetStartOfFecProtectedData(QuicConnectionIdLength connection_id_length,
bool include_version,
QuicPacketNumberLength packet_number_length) {
return GetPacketHeaderSize(connection_id_length, include_version,
- packet_number_length, IN_FEC_GROUP);
+ /*include_path_id=*/false, packet_number_length,
+ IN_FEC_GROUP);
}
size_t GetStartOfEncryptedData(QuicConnectionIdLength connection_id_length,
@@ -45,13 +50,15 @@ size_t GetStartOfEncryptedData(QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length) {
// Don't include the fec size, since encryption starts before private flags.
return GetPacketHeaderSize(connection_id_length, include_version,
- packet_number_length, NOT_IN_FEC_GROUP) -
+ /*include_path_id=*/false, packet_number_length,
+ NOT_IN_FEC_GROUP) -
kPrivateFlagsSize;
}
QuicPacketPublicHeader::QuicPacketPublicHeader()
: connection_id(0),
connection_id_length(PACKET_8BYTE_CONNECTION_ID),
+ multipath_flag(false),
reset_flag(false),
version_flag(false),
packet_number_length(PACKET_6BYTE_PACKET_NUMBER) {}
@@ -60,6 +67,7 @@ QuicPacketPublicHeader::QuicPacketPublicHeader(
const QuicPacketPublicHeader& other)
: connection_id(other.connection_id),
connection_id_length(other.connection_id_length),
+ multipath_flag(other.multipath_flag),
reset_flag(other.reset_flag),
version_flag(other.version_flag),
packet_number_length(other.packet_number_length),
@@ -68,7 +76,8 @@ QuicPacketPublicHeader::QuicPacketPublicHeader(
QuicPacketPublicHeader::~QuicPacketPublicHeader() {}
QuicPacketHeader::QuicPacketHeader()
- : packet_packet_number(0),
+ : path_id(kDefaultPathId),
+ packet_number(0),
fec_flag(false),
entropy_flag(false),
entropy_hash(0),
@@ -77,7 +86,8 @@ QuicPacketHeader::QuicPacketHeader()
QuicPacketHeader::QuicPacketHeader(const QuicPacketPublicHeader& header)
: public_header(header),
- packet_packet_number(0),
+ path_id(kDefaultPathId),
+ packet_number(0),
fec_flag(false),
entropy_flag(false),
entropy_hash(0),
@@ -91,33 +101,77 @@ QuicPublicResetPacket::QuicPublicResetPacket(
const QuicPacketPublicHeader& header)
: public_header(header), nonce_proof(0), rejected_packet_number(0) {}
-QuicStreamFrame::QuicStreamFrame() : stream_id(0), fin(false), offset(0) {
+QuicBufferAllocator::~QuicBufferAllocator() = default;
+
+void StreamBufferDeleter::operator()(char* buffer) const {
+ if (allocator_ != nullptr && buffer != nullptr) {
+ allocator_->Delete(buffer);
+ }
}
-QuicStreamFrame::QuicStreamFrame(const QuicStreamFrame& frame)
- : stream_id(frame.stream_id),
- fin(frame.fin),
- offset(frame.offset),
- data(frame.data) {
+UniqueStreamBuffer NewStreamBuffer(QuicBufferAllocator* allocator,
+ size_t size) {
+ return UniqueStreamBuffer(allocator->New(size),
+ StreamBufferDeleter(allocator));
}
+QuicStreamFrame::QuicStreamFrame()
+ : QuicStreamFrame(0, false, 0, nullptr, 0, nullptr) {}
+
QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
bool fin,
QuicStreamOffset offset,
StringPiece data)
- : stream_id(stream_id), fin(fin), offset(offset), data(data) {
+ : QuicStreamFrame(stream_id,
+ fin,
+ offset,
+ data.data(),
+ data.length(),
+ nullptr) {}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+ bool fin,
+ QuicStreamOffset offset,
+ QuicPacketLength frame_length,
+ UniqueStreamBuffer buffer)
+ : QuicStreamFrame(stream_id,
+ fin,
+ offset,
+ nullptr,
+ frame_length,
+ std::move(buffer)) {
+ DCHECK(this->buffer != nullptr);
+ DCHECK_EQ(frame_buffer, this->buffer.get());
+}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+ bool fin,
+ QuicStreamOffset offset,
+ const char* frame_buffer,
+ QuicPacketLength frame_length,
+ UniqueStreamBuffer buffer)
+ : stream_id(stream_id),
+ fin(fin),
+ frame_length(frame_length),
+ frame_buffer(frame_buffer),
+ offset(offset),
+ buffer(std::move(buffer)) {
+ if (this->buffer != nullptr) {
+ DCHECK(frame_buffer == nullptr);
+ this->frame_buffer = this->buffer.get();
+ }
}
-uint32 MakeQuicTag(char a, char b, char c, char d) {
- return static_cast<uint32>(a) |
- static_cast<uint32>(b) << 8 |
- static_cast<uint32>(c) << 16 |
- static_cast<uint32>(d) << 24;
+QuicStreamFrame::~QuicStreamFrame() {}
+
+uint32_t MakeQuicTag(char a, char b, char c, char d) {
+ return static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
+ static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
}
bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) {
- return std::find(tag_vector.begin(), tag_vector.end(), tag)
- != tag_vector.end();
+ return std::find(tag_vector.begin(), tag_vector.end(), tag) !=
+ tag_vector.end();
}
QuicVersionVector QuicSupportedVersions() {
@@ -130,12 +184,18 @@ QuicVersionVector QuicSupportedVersions() {
QuicTag QuicVersionToQuicTag(const QuicVersion version) {
switch (version) {
- case QUIC_VERSION_24:
- return MakeQuicTag('Q', '0', '2', '4');
case QUIC_VERSION_25:
return MakeQuicTag('Q', '0', '2', '5');
case QUIC_VERSION_26:
return MakeQuicTag('Q', '0', '2', '6');
+ case QUIC_VERSION_27:
+ return MakeQuicTag('Q', '0', '2', '7');
+ case QUIC_VERSION_28:
+ return MakeQuicTag('Q', '0', '2', '8');
+ case QUIC_VERSION_29:
+ return MakeQuicTag('Q', '0', '2', '9');
+ case QUIC_VERSION_30:
+ return MakeQuicTag('Q', '0', '3', '0');
default:
// This shold be an ERROR because we should never attempt to convert an
// invalid QuicVersion to be written to the wire.
@@ -157,14 +217,17 @@ QuicVersion QuicTagToQuicVersion(const QuicTag version_tag) {
}
#define RETURN_STRING_LITERAL(x) \
-case x: \
-return #x
+ case x: \
+ return #x
string QuicVersionToString(const QuicVersion version) {
switch (version) {
- RETURN_STRING_LITERAL(QUIC_VERSION_24);
RETURN_STRING_LITERAL(QUIC_VERSION_25);
RETURN_STRING_LITERAL(QUIC_VERSION_26);
+ RETURN_STRING_LITERAL(QUIC_VERSION_27);
+ RETURN_STRING_LITERAL(QUIC_VERSION_28);
+ RETURN_STRING_LITERAL(QUIC_VERSION_29);
+ RETURN_STRING_LITERAL(QUIC_VERSION_30);
default:
return "QUIC_VERSION_UNSUPPORTED";
}
@@ -194,6 +257,7 @@ ostream& operator<<(ostream& os, const QuicPacketHeader& header) {
os << "{ connection_id: " << header.public_header.connection_id
<< ", connection_id_length:" << header.public_header.connection_id_length
<< ", packet_number_length:" << header.public_header.packet_number_length
+ << ", multipath_flag: " << header.public_header.multipath_flag
<< ", reset_flag: " << header.public_header.reset_flag
<< ", version_flag: " << header.public_header.version_flag;
if (header.public_header.version_flag) {
@@ -205,7 +269,8 @@ ostream& operator<<(ostream& os, const QuicPacketHeader& header) {
os << ", fec_flag: " << header.fec_flag
<< ", entropy_flag: " << header.entropy_flag
<< ", entropy hash: " << static_cast<int>(header.entropy_hash)
- << ", packet_number: " << header.packet_packet_number
+ << ", path_id: " << header.path_id
+ << ", packet_number: " << header.packet_number
<< ", is_in_fec_group:" << header.is_in_fec_group
<< ", fec_group: " << header.fec_group << "}\n";
return os;
@@ -218,23 +283,22 @@ bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
}
QuicStopWaitingFrame::QuicStopWaitingFrame()
- : entropy_hash(0),
- least_unacked(0) {
-}
+ : path_id(kDefaultPathId), entropy_hash(0), least_unacked(0) {}
QuicStopWaitingFrame::~QuicStopWaitingFrame() {}
QuicAckFrame::QuicAckFrame()
- : entropy_hash(0),
+ : path_id(kDefaultPathId),
+ entropy_hash(0),
+ is_truncated(false),
largest_observed(0),
delta_time_largest_observed(QuicTime::Delta::Infinite()),
- is_truncated(false) {}
+ latest_revived_packet(0) {}
QuicAckFrame::~QuicAckFrame() {}
-QuicRstStreamErrorCode AdjustErrorForVersion(
- QuicRstStreamErrorCode error_code,
- QuicVersion version) {
+QuicRstStreamErrorCode AdjustErrorForVersion(QuicRstStreamErrorCode error_code,
+ QuicVersion /*version*/) {
return error_code;
}
@@ -244,73 +308,46 @@ QuicRstStreamFrame::QuicRstStreamFrame()
QuicRstStreamFrame::QuicRstStreamFrame(QuicStreamId stream_id,
QuicRstStreamErrorCode error_code,
QuicStreamOffset bytes_written)
- : stream_id(stream_id),
- error_code(error_code),
- byte_offset(bytes_written) {
- DCHECK_LE(error_code, numeric_limits<uint8>::max());
+ : stream_id(stream_id), error_code(error_code), byte_offset(bytes_written) {
+ DCHECK_LE(error_code, numeric_limits<uint8_t>::max());
}
QuicConnectionCloseFrame::QuicConnectionCloseFrame()
- : error_code(QUIC_NO_ERROR) {
-}
+ : error_code(QUIC_NO_ERROR) {}
QuicFrame::QuicFrame() {}
-QuicFrame::QuicFrame(QuicPaddingFrame* padding_frame)
- : type(PADDING_FRAME),
- padding_frame(padding_frame) {
-}
+QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
+ : type(PADDING_FRAME), padding_frame(padding_frame) {}
QuicFrame::QuicFrame(QuicStreamFrame* stream_frame)
- : type(STREAM_FRAME),
- stream_frame(stream_frame) {
-}
+ : type(STREAM_FRAME), stream_frame(stream_frame) {}
-QuicFrame::QuicFrame(QuicAckFrame* frame)
- : type(ACK_FRAME),
- ack_frame(frame) {
-}
+QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}
-QuicFrame::QuicFrame(QuicMtuDiscoveryFrame* frame)
- : type(MTU_DISCOVERY_FRAME), mtu_discovery_frame(frame) {
-}
+QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
+ : type(MTU_DISCOVERY_FRAME), mtu_discovery_frame(frame) {}
QuicFrame::QuicFrame(QuicStopWaitingFrame* frame)
- : type(STOP_WAITING_FRAME),
- stop_waiting_frame(frame) {
-}
+ : type(STOP_WAITING_FRAME), stop_waiting_frame(frame) {}
-QuicFrame::QuicFrame(QuicPingFrame* frame)
- : type(PING_FRAME),
- ping_frame(frame) {
-}
+QuicFrame::QuicFrame(QuicPingFrame frame)
+ : type(PING_FRAME), ping_frame(frame) {}
QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
- : type(RST_STREAM_FRAME),
- rst_stream_frame(frame) {
-}
+ : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}
QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
- : type(CONNECTION_CLOSE_FRAME),
- connection_close_frame(frame) {
-}
+ : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}
QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
- : type(GOAWAY_FRAME),
- goaway_frame(frame) {
-}
+ : type(GOAWAY_FRAME), goaway_frame(frame) {}
QuicFrame::QuicFrame(QuicWindowUpdateFrame* frame)
- : type(WINDOW_UPDATE_FRAME),
- window_update_frame(frame) {
-}
+ : type(WINDOW_UPDATE_FRAME), window_update_frame(frame) {}
QuicFrame::QuicFrame(QuicBlockedFrame* frame)
- : type(BLOCKED_FRAME),
- blocked_frame(frame) {
-}
-
-QuicFecData::QuicFecData() : fec_group(0) {}
+ : type(BLOCKED_FRAME), blocked_frame(frame) {}
ostream& operator<<(ostream& os, const QuicStopWaitingFrame& sent_info) {
os << "entropy_hash: " << static_cast<int>(sent_info.entropy_hash)
@@ -319,17 +356,10 @@ ostream& operator<<(ostream& os, const QuicStopWaitingFrame& sent_info) {
}
PacketNumberQueue::const_iterator::const_iterator(
- PacketNumberSet::const_iterator set_iter)
- : use_interval_set_(false), set_iter_(set_iter) {}
-
-PacketNumberQueue::const_iterator::const_iterator(
IntervalSet<QuicPacketNumber>::const_iterator interval_set_iter,
QuicPacketNumber first,
QuicPacketNumber last)
- : use_interval_set_(true),
- interval_set_iter_(interval_set_iter),
- current_(first),
- last_(last) {}
+ : interval_set_iter_(interval_set_iter), current_(first), last_(last) {}
PacketNumberQueue::const_iterator::const_iterator(const const_iterator& other) =
default;
@@ -347,46 +377,30 @@ PacketNumberQueue::const_iterator& PacketNumberQueue::const_iterator::operator=(
bool PacketNumberQueue::const_iterator::operator!=(
const const_iterator& other) const {
- if (use_interval_set_) {
- return current_ != other.current_;
- } else {
- return set_iter_ != other.set_iter_;
- }
+ return current_ != other.current_;
}
bool PacketNumberQueue::const_iterator::operator==(
const const_iterator& other) const {
- if (use_interval_set_) {
- return current_ == other.current_;
- } else {
- return set_iter_ == other.set_iter_;
- }
+ return current_ == other.current_;
}
PacketNumberQueue::const_iterator::value_type
PacketNumberQueue::const_iterator::
operator*() const {
- if (use_interval_set_) {
- return current_;
- } else {
- return *set_iter_;
- }
+ return current_;
}
PacketNumberQueue::const_iterator& PacketNumberQueue::const_iterator::
operator++() {
- if (use_interval_set_) {
- ++current_;
- if (current_ < last_) {
- if (current_ >= interval_set_iter_->max()) {
- ++interval_set_iter_;
- current_ = interval_set_iter_->min();
- }
- } else {
- current_ = last_;
+ ++current_;
+ if (current_ < last_) {
+ if (current_ >= interval_set_iter_->max()) {
+ ++interval_set_iter_;
+ current_ = interval_set_iter_->min();
}
} else {
- ++set_iter_;
+ current_ = last_;
}
return *this;
}
@@ -398,9 +412,7 @@ PacketNumberQueue::const_iterator PacketNumberQueue::const_iterator::operator++(
return preincrement;
}
-PacketNumberQueue::PacketNumberQueue()
- : use_interval_set_(FLAGS_quic_packet_queue_use_interval_set) {}
-
+PacketNumberQueue::PacketNumberQueue() = default;
PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default;
// TODO(rtenneti): on windows RValue reference gives errors.
// PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default;
@@ -413,143 +425,89 @@ PacketNumberQueue& PacketNumberQueue::operator=(
// default;
void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
- if (use_interval_set_) {
- packet_number_intervals_.Add(packet_number, packet_number + 1);
- } else {
- packet_number_set_.insert(packet_number);
- }
+ packet_number_intervals_.Add(packet_number, packet_number + 1);
}
void PacketNumberQueue::Add(QuicPacketNumber lower, QuicPacketNumber higher) {
- if (use_interval_set_) {
- packet_number_intervals_.Add(lower, higher);
- } else {
- for (QuicPacketNumber packet_number = lower; packet_number < higher;
- ++packet_number) {
- Add(packet_number);
- }
- }
+ packet_number_intervals_.Add(lower, higher);
}
void PacketNumberQueue::Remove(QuicPacketNumber packet_number) {
- if (use_interval_set_) {
- packet_number_intervals_.Difference(packet_number, packet_number + 1);
- } else {
- packet_number_set_.erase(packet_number);
- }
+ packet_number_intervals_.Difference(packet_number, packet_number + 1);
}
bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
- if (use_interval_set_) {
- if (Empty()) {
- return false;
- }
- const QuicPacketNumber old_min = Min();
- packet_number_intervals_.Difference(0, higher);
- return Empty() || old_min != Min();
- } else {
- const size_t orig_size = packet_number_set_.size();
- packet_number_set_.erase(packet_number_set_.begin(),
- packet_number_set_.lower_bound(higher));
- return orig_size != packet_number_set_.size();
+ if (Empty()) {
+ return false;
}
+ const QuicPacketNumber old_min = Min();
+ packet_number_intervals_.Difference(0, higher);
+ return Empty() || old_min != Min();
}
bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
- if (use_interval_set_) {
- return packet_number_intervals_.Contains(packet_number);
- } else {
- return ContainsKey(packet_number_set_, packet_number);
- }
+ return packet_number_intervals_.Contains(packet_number);
}
bool PacketNumberQueue::Empty() const {
- if (use_interval_set_) {
- return packet_number_intervals_.Empty();
- } else {
- return packet_number_set_.empty();
- }
+ return packet_number_intervals_.Empty();
}
QuicPacketNumber PacketNumberQueue::Min() const {
DCHECK(!Empty());
- if (use_interval_set_) {
- return packet_number_intervals_.begin()->min();
- } else {
- return *packet_number_set_.begin();
- }
+ return packet_number_intervals_.begin()->min();
}
QuicPacketNumber PacketNumberQueue::Max() const {
DCHECK(!Empty());
- if (use_interval_set_) {
- return packet_number_intervals_.rbegin()->max() - 1;
- } else {
- return *packet_number_set_.rbegin();
- }
+ return packet_number_intervals_.rbegin()->max() - 1;
}
size_t PacketNumberQueue::NumPacketsSlow() const {
- if (use_interval_set_) {
- size_t num_packets = 0;
- for (const auto& interval : packet_number_intervals_) {
- num_packets += interval.Length();
- }
- return num_packets;
- } else {
- return packet_number_set_.size();
+ size_t num_packets = 0;
+ for (const auto& interval : packet_number_intervals_) {
+ num_packets += interval.Length();
}
+ return num_packets;
}
PacketNumberQueue::const_iterator PacketNumberQueue::begin() const {
- if (use_interval_set_) {
- QuicPacketNumber first;
- QuicPacketNumber last;
- if (packet_number_intervals_.Empty()) {
- first = 0;
- last = 0;
- } else {
- first = packet_number_intervals_.begin()->min();
- last = packet_number_intervals_.rbegin()->max();
- }
- return const_iterator(packet_number_intervals_.begin(), first, last);
+ QuicPacketNumber first;
+ QuicPacketNumber last;
+ if (packet_number_intervals_.Empty()) {
+ first = 0;
+ last = 0;
} else {
- return const_iterator(packet_number_set_.begin());
+ first = packet_number_intervals_.begin()->min();
+ last = packet_number_intervals_.rbegin()->max();
}
+ return const_iterator(packet_number_intervals_.begin(), first, last);
}
PacketNumberQueue::const_iterator PacketNumberQueue::end() const {
- if (use_interval_set_) {
- QuicPacketNumber last = packet_number_intervals_.Empty()
- ? 0
- : packet_number_intervals_.rbegin()->max();
- return const_iterator(packet_number_intervals_.end(), last, last);
- } else {
- return const_iterator(packet_number_set_.end());
- }
+ QuicPacketNumber last = packet_number_intervals_.Empty()
+ ? 0
+ : packet_number_intervals_.rbegin()->max();
+ return const_iterator(packet_number_intervals_.end(), last, last);
}
PacketNumberQueue::const_iterator PacketNumberQueue::lower_bound(
QuicPacketNumber packet_number) const {
- if (use_interval_set_) {
- QuicPacketNumber first;
- QuicPacketNumber last;
- if (packet_number_intervals_.Empty()) {
- first = 0;
- last = 0;
- return const_iterator(packet_number_intervals_.begin(), first, last);
- }
- if (!packet_number_intervals_.Contains(packet_number)) {
- return end();
- }
- IntervalSet<QuicPacketNumber>::const_iterator it =
- packet_number_intervals_.Find(packet_number);
- first = packet_number;
- last = packet_number_intervals_.rbegin()->max();
- return const_iterator(it, first, last);
- } else {
- return const_iterator(packet_number_set_.lower_bound(packet_number));
+ QuicPacketNumber first;
+ QuicPacketNumber last;
+ if (packet_number_intervals_.Empty()) {
+ first = 0;
+ last = 0;
+ return const_iterator(packet_number_intervals_.begin(), first, last);
}
+ if (!packet_number_intervals_.Contains(packet_number)) {
+ return end();
+ }
+ IntervalSet<QuicPacketNumber>::const_iterator it =
+ packet_number_intervals_.Find(packet_number);
+ first = packet_number;
+ last = packet_number_intervals_.rbegin()->max();
+ return const_iterator(it, first, last);
}
ostream& operator<<(ostream& os, const PacketNumberQueue& q) {
@@ -565,17 +523,12 @@ ostream& operator<<(ostream& os, const QuicAckFrame& ack_frame) {
<< " delta_time_largest_observed: "
<< ack_frame.delta_time_largest_observed.ToMicroseconds()
<< " missing_packets: [ " << ack_frame.missing_packets
- << " ] is_truncated: " << ack_frame.is_truncated;
- os << " revived_packets: [ ";
- for (PacketNumberSet::const_iterator it = ack_frame.revived_packets.begin();
- it != ack_frame.revived_packets.end(); ++it) {
- os << *it << " ";
- }
- os << " ] received_packets: [ ";
- for (PacketTimeList::const_iterator it =
- ack_frame.received_packet_times.begin();
- it != ack_frame.received_packet_times.end(); ++it) {
- os << it->first << " at " << it->second.ToDebuggingValue() << " ";
+ << " ] is_truncated: " << ack_frame.is_truncated
+ << " revived_packet: " << ack_frame.latest_revived_packet
+ << " received_packets: [ ";
+ for (const std::pair<QuicPacketNumber, QuicTime>& p :
+ ack_frame.received_packet_times) {
+ os << p.first << " at " << p.second.ToDebuggingValue() << " ";
}
os << " ]";
return os;
@@ -583,7 +536,7 @@ ostream& operator<<(ostream& os, const QuicAckFrame& ack_frame) {
ostream& operator<<(ostream& os, const QuicFrame& frame) {
switch (frame.type) {
- case PADDING_FRAME: {
+ case PADDING_FRAME: {
os << "type { PADDING_FRAME } ";
break;
}
@@ -638,8 +591,7 @@ ostream& operator<<(ostream& os, const QuicFrame& frame) {
ostream& operator<<(ostream& os, const QuicRstStreamFrame& rst_frame) {
os << "stream_id { " << rst_frame.stream_id << " } "
- << "error_code { " << rst_frame.error_code << " } "
- << "error_details { " << rst_frame.error_details << " }\n";
+ << "error_code { " << rst_frame.error_code << " }\n";
return os;
}
@@ -673,15 +625,12 @@ ostream& operator<<(ostream& os, const QuicStreamFrame& stream_frame) {
os << "stream_id { " << stream_frame.stream_id << " } "
<< "fin { " << stream_frame.fin << " } "
<< "offset { " << stream_frame.offset << " } "
- << "data { " << QuicUtils::StringToHexASCIIDump(stream_frame.data)
- << " }\n";
+ << "length { " << stream_frame.frame_length << " }\n";
return os;
}
QuicGoAwayFrame::QuicGoAwayFrame()
- : error_code(QUIC_NO_ERROR),
- last_good_stream_id(0) {
-}
+ : error_code(QUIC_NO_ERROR), last_good_stream_id(0) {}
QuicGoAwayFrame::QuicGoAwayFrame(QuicErrorCode error_code,
QuicStreamId last_good_stream_id,
@@ -689,34 +638,24 @@ QuicGoAwayFrame::QuicGoAwayFrame(QuicErrorCode error_code,
: error_code(error_code),
last_good_stream_id(last_good_stream_id),
reason_phrase(reason) {
- DCHECK_LE(error_code, numeric_limits<uint8>::max());
+ DCHECK_LE(error_code, numeric_limits<uint8_t>::max());
}
-QuicData::QuicData(const char* buffer,
- size_t length)
- : buffer_(buffer),
- length_(length),
- owns_buffer_(false) {
-}
+QuicData::QuicData(const char* buffer, size_t length)
+ : buffer_(buffer), length_(length), owns_buffer_(false) {}
-QuicData::QuicData(char* buffer,
- size_t length,
- bool owns_buffer)
- : buffer_(buffer),
- length_(length),
- owns_buffer_(owns_buffer) {
-}
+QuicData::QuicData(char* buffer, size_t length, bool owns_buffer)
+ : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
QuicData::~QuicData() {
if (owns_buffer_) {
- delete [] const_cast<char*>(buffer_);
+ delete[] const_cast<char*>(buffer_);
}
}
QuicWindowUpdateFrame::QuicWindowUpdateFrame(QuicStreamId stream_id,
QuicStreamOffset byte_offset)
- : stream_id(stream_id),
- byte_offset(byte_offset) {}
+ : stream_id(stream_id), byte_offset(byte_offset) {}
QuicBlockedFrame::QuicBlockedFrame(QuicStreamId stream_id)
: stream_id(stream_id) {}
@@ -733,16 +672,13 @@ QuicPacket::QuicPacket(char* buffer,
includes_version_(includes_version),
packet_number_length_(packet_number_length) {}
-QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
- size_t length)
- : QuicData(buffer, length) {
-}
+QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
+ : QuicData(buffer, length) {}
QuicEncryptedPacket::QuicEncryptedPacket(char* buffer,
size_t length,
bool owns_buffer)
- : QuicData(buffer, length, owns_buffer) {
-}
+ : QuicData(buffer, length, owns_buffer) {}
StringPiece QuicPacket::FecProtectedData() const {
const size_t start_of_fec = GetStartOfFecProtectedData(
@@ -752,14 +688,6 @@ StringPiece QuicPacket::FecProtectedData() const {
StringPiece QuicPacket::AssociatedData() const {
return StringPiece(
- data() + kStartOfHashData,
- GetStartOfEncryptedData(connection_id_length_, includes_version_,
- packet_number_length_) -
- kStartOfHashData);
-}
-
-StringPiece QuicPacket::BeforePlaintext() const {
- return StringPiece(
data(), GetStartOfEncryptedData(connection_id_length_, includes_version_,
packet_number_length_));
}
@@ -771,72 +699,58 @@ StringPiece QuicPacket::Plaintext() const {
length() - start_of_encrypted_data);
}
-RetransmittableFrames::RetransmittableFrames(EncryptionLevel level)
- : encryption_level_(level),
- has_crypto_handshake_(NOT_HANDSHAKE),
- needs_padding_(false) {
+RetransmittableFrames::RetransmittableFrames()
+ : has_crypto_handshake_(NOT_HANDSHAKE), needs_padding_(false) {
+ // TODO(ianswett): Consider using an inlined vector instead, since this
+ // is very frequently a single frame.
+ frames_.reserve(2);
}
RetransmittableFrames::~RetransmittableFrames() {
- for (QuicFrames::iterator it = frames_.begin(); it != frames_.end(); ++it) {
- switch (it->type) {
+ for (QuicFrame& frame : frames_) {
+ switch (frame.type) {
+ // Frames smaller than a pointer are inlined, so don't need to be deleted.
case PADDING_FRAME:
- delete it->padding_frame;
+ case MTU_DISCOVERY_FRAME:
+ case PING_FRAME:
break;
case STREAM_FRAME:
- delete it->stream_frame;
+ delete frame.stream_frame;
break;
case ACK_FRAME:
- delete it->ack_frame;
- break;
- case MTU_DISCOVERY_FRAME:
- delete it->mtu_discovery_frame;
+ delete frame.ack_frame;
break;
case STOP_WAITING_FRAME:
- delete it->stop_waiting_frame;
- break;
- case PING_FRAME:
- delete it->ping_frame;
+ delete frame.stop_waiting_frame;
break;
case RST_STREAM_FRAME:
- delete it->rst_stream_frame;
+ delete frame.rst_stream_frame;
break;
case CONNECTION_CLOSE_FRAME:
- delete it->connection_close_frame;
+ delete frame.connection_close_frame;
break;
case GOAWAY_FRAME:
- delete it->goaway_frame;
+ delete frame.goaway_frame;
break;
case WINDOW_UPDATE_FRAME:
- delete it->window_update_frame;
+ delete frame.window_update_frame;
break;
case BLOCKED_FRAME:
- delete it->blocked_frame;
+ delete frame.blocked_frame;
break;
case NUM_FRAME_TYPES:
- DCHECK(false) << "Cannot delete type: " << it->type;
+ DCHECK(false) << "Cannot delete type: " << frame.type;
}
}
- for (const char* buffer : stream_data_) {
- delete[] buffer;
- }
}
const QuicFrame& RetransmittableFrames::AddFrame(const QuicFrame& frame) {
- return AddFrame(frame, nullptr);
-}
-
-const QuicFrame& RetransmittableFrames::AddFrame(const QuicFrame& frame,
- char* buffer) {
if (frame.type == STREAM_FRAME &&
frame.stream_frame->stream_id == kCryptoStreamId) {
has_crypto_handshake_ = IS_HANDSHAKE;
}
- if (buffer != nullptr) {
- stream_data_.push_back(buffer);
- }
frames_.push_back(frame);
- return frames_.back();
+ return frame;
}
void RetransmittableFrames::RemoveFramesForStream(QuicStreamId stream_id) {
@@ -851,7 +765,16 @@ void RetransmittableFrames::RemoveFramesForStream(QuicStreamId stream_id) {
}
}
+AckListenerWrapper::AckListenerWrapper(QuicAckListenerInterface* listener,
+ QuicPacketLength data_length)
+ : ack_listener(listener), length(data_length) {
+ DCHECK(listener != nullptr);
+}
+
+AckListenerWrapper::~AckListenerWrapper() {}
+
SerializedPacket::SerializedPacket(
+ QuicPathId path_id,
QuicPacketNumber packet_number,
QuicPacketNumberLength packet_number_length,
QuicEncryptedPacket* packet,
@@ -861,12 +784,43 @@ SerializedPacket::SerializedPacket(
bool has_stop_waiting)
: packet(packet),
retransmittable_frames(retransmittable_frames),
+ path_id(path_id),
packet_number(packet_number),
packet_number_length(packet_number_length),
+ encryption_level(ENCRYPTION_NONE),
entropy_hash(entropy_hash),
is_fec_packet(false),
has_ack(has_ack),
- has_stop_waiting(has_stop_waiting) {}
+ has_stop_waiting(has_stop_waiting),
+ original_packet_number(0),
+ transmission_type(NOT_RETRANSMISSION) {}
+
+SerializedPacket::SerializedPacket(
+ QuicPathId path_id,
+ QuicPacketNumber packet_number,
+ QuicPacketNumberLength packet_number_length,
+ char* encrypted_buffer,
+ size_t encrypted_length,
+ bool owns_buffer,
+ QuicPacketEntropyHash entropy_hash,
+ RetransmittableFrames* retransmittable_frames,
+ bool has_ack,
+ bool has_stop_waiting,
+ EncryptionLevel level)
+ : SerializedPacket(path_id,
+ packet_number,
+ packet_number_length,
+ new QuicEncryptedPacket(encrypted_buffer,
+ encrypted_length,
+ owns_buffer),
+ entropy_hash,
+ retransmittable_frames,
+ has_ack,
+ has_stop_waiting) {
+ // TODO(ianswett): Move into the initializer list once SerializedPacket
+ // no longer contains an encrypted packet.
+ encryption_level = level;
+}
SerializedPacket::~SerializedPacket() {}
@@ -883,32 +837,39 @@ ostream& operator<<(ostream& os, const QuicEncryptedPacket& s) {
TransmissionInfo::TransmissionInfo()
: retransmittable_frames(nullptr),
+ encryption_level(ENCRYPTION_NONE),
packet_number_length(PACKET_1BYTE_PACKET_NUMBER),
- sent_time(QuicTime::Zero()),
bytes_sent(0),
nack_count(0),
+ sent_time(QuicTime::Zero()),
transmission_type(NOT_RETRANSMISSION),
- all_transmissions(nullptr),
in_flight(false),
is_unackable(false),
- is_fec_packet(false) {}
+ is_fec_packet(false),
+ all_transmissions(nullptr),
+ retransmission(0) {}
TransmissionInfo::TransmissionInfo(
RetransmittableFrames* retransmittable_frames,
+ EncryptionLevel level,
QuicPacketNumberLength packet_number_length,
TransmissionType transmission_type,
QuicTime sent_time,
- QuicByteCount bytes_sent,
+ QuicPacketLength bytes_sent,
bool is_fec_packet)
: retransmittable_frames(retransmittable_frames),
+ encryption_level(level),
packet_number_length(packet_number_length),
- sent_time(sent_time),
bytes_sent(bytes_sent),
nack_count(0),
+ sent_time(sent_time),
transmission_type(transmission_type),
- all_transmissions(nullptr),
in_flight(false),
is_unackable(false),
- is_fec_packet(is_fec_packet) {}
+ is_fec_packet(is_fec_packet),
+ all_transmissions(nullptr),
+ retransmission(0) {}
+
+TransmissionInfo::~TransmissionInfo() {}
} // namespace net
diff --git a/chromium/net/quic/quic_protocol.h b/chromium/net/quic/quic_protocol.h
index bfe7cc5f61f..29214034c0e 100644
--- a/chromium/net/quic/quic_protocol.h
+++ b/chromium/net/quic/quic_protocol.h
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <stdint.h>
+
#include <limits>
#include <list>
#include <map>
@@ -16,47 +17,49 @@
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/int128.h"
#include "net/base/iovec.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
#include "net/quic/interval_set.h"
+#include "net/quic/quic_ack_listener_interface.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_time.h"
#include "net/quic/quic_types.h"
namespace net {
-class QuicAckNotifier;
class QuicPacket;
struct QuicPacketHeader;
+class QuicAckListenerInterface;
-typedef uint64 QuicConnectionId;
-typedef uint32 QuicStreamId;
-typedef uint64 QuicStreamOffset;
-typedef uint64 QuicPacketNumber;
+typedef uint64_t QuicConnectionId;
+typedef uint32_t QuicStreamId;
+typedef uint64_t QuicStreamOffset;
+typedef uint64_t QuicPacketNumber;
+typedef uint8_t QuicPathId;
typedef QuicPacketNumber QuicFecGroupNumber;
-typedef uint64 QuicPublicResetNonceProof;
-typedef uint8 QuicPacketEntropyHash;
-typedef uint32 QuicHeaderId;
+typedef uint64_t QuicPublicResetNonceProof;
+typedef uint8_t QuicPacketEntropyHash;
+typedef uint32_t QuicHeaderId;
// QuicTag is the type of a tag in the wire protocol.
-typedef uint32 QuicTag;
+typedef uint32_t QuicTag;
typedef std::vector<QuicTag> QuicTagVector;
typedef std::map<QuicTag, std::string> QuicTagValueMap;
-// TODO(rtenneti): Didn't use SpdyPriority because SpdyPriority is uint8 and
-// QuicPriority is uint32. Use SpdyPriority when we change the QUIC_VERSION.
-typedef uint32 QuicPriority;
+typedef uint16_t QuicPacketLength;
// Default initial maximum size in bytes of a QUIC packet.
const QuicByteCount kDefaultMaxPacketSize = 1350;
// Default initial maximum size in bytes of a QUIC packet for servers.
const QuicByteCount kDefaultServerMaxPacketSize = 1000;
// The maximum packet size of any QUIC packet, based on ethernet's max size,
-// minus the IP and UDP headers. IPv6 has a 40 byte header, UPD adds an
+// minus the IP and UDP headers. IPv6 has a 40 byte header, UDP adds an
// additional 8 bytes. This is a total overhead of 48 bytes. Ethernet's
// max packet size is 1500 bytes, 1500 - 48 = 1452.
const QuicByteCount kMaxPacketSize = 1452;
@@ -64,13 +67,15 @@ const QuicByteCount kMaxPacketSize = 1452;
// Used in QUIC for congestion window computations in bytes.
const QuicByteCount kDefaultTCPMSS = 1460;
-// We match SPDY's use of 32 when secure (since we'd compete with SPDY).
-const QuicPacketCount kInitialCongestionWindowSecure = 32;
-// Be conservative, and just use double a typical TCP ICWND for HTTP.
-const QuicPacketCount kInitialCongestionWindowInsecure = 20;
+// We match SPDY's use of 32 (since we'd compete with SPDY).
+const QuicPacketCount kInitialCongestionWindow = 32;
// Minimum size of initial flow control window, for both stream and session.
-const uint32 kMinimumFlowControlSendWindow = 16 * 1024; // 16 KB
+const uint32_t kMinimumFlowControlSendWindow = 16 * 1024; // 16 KB
+
+// Maximum flow control receive window limits for connection and stream.
+const QuicByteCount kStreamReceiveWindowLimit = 16 * 1024 * 1024; // 16 MB
+const QuicByteCount kSessionReceiveWindowLimit = 24 * 1024 * 1024; // 24 MB
// Minimum size of the CWND, in packets, when doing bandwidth resumption.
const QuicPacketCount kMinCongestionWindowForBandwidthResumption = 10;
@@ -96,10 +101,10 @@ static const float kUsableRecieveBufferFraction = 0.95f;
static const float kConservativeReceiveBufferFraction = 0.6f;
// Don't allow a client to suggest an RTT shorter than 10ms.
-const uint32 kMinInitialRoundTripTimeUs = 10 * kNumMicrosPerMilli;
+const uint32_t kMinInitialRoundTripTimeUs = 10 * kNumMicrosPerMilli;
// Don't allow a client to suggest an RTT longer than 15 seconds.
-const uint32 kMaxInitialRoundTripTimeUs = 15 * kNumMicrosPerSecond;
+const uint32_t kMaxInitialRoundTripTimeUs = 15 * kNumMicrosPerSecond;
// Maximum number of open streams per connection.
const size_t kDefaultMaxStreamsPerConnection = 100;
@@ -108,6 +113,8 @@ const size_t kDefaultMaxStreamsPerConnection = 100;
const size_t kPublicFlagsSize = 1;
// Number of bytes reserved for version number in the packet header.
const size_t kQuicVersionSize = 4;
+// Number of bytes reserved for path id in the packet header.
+const size_t kQuicPathIdSize = 1;
// Number of bytes reserved for private flags in the packet header.
const size_t kPrivateFlagsSize = 1;
// Number of bytes reserved for FEC group in the packet header.
@@ -115,9 +122,11 @@ const size_t kFecGroupSize = 1;
// Signifies that the QuicPacket will contain version of the protocol.
const bool kIncludeVersion = true;
+// Signifies that the QuicPacket will contain path id.
+const bool kIncludePathId = true;
-// Index of the first byte in a QUIC packet which is used in hash calculation.
-const size_t kStartOfHashData = 0;
+// Stream ID is reserved to denote an invalid ID.
+const QuicStreamId kInvalidStreamId = 0;
// Reserved ID for the crypto stream.
const QuicStreamId kCryptoStreamId = 1;
@@ -125,24 +134,28 @@ const QuicStreamId kCryptoStreamId = 1;
// Reserved ID for the headers stream.
const QuicStreamId kHeadersStreamId = 3;
+// Header key used to identify final offset on data stream when sending HTTP/2
+// trailing headers over QUIC.
+NET_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
+
// Maximum delayed ack time, in ms.
-const int64 kMaxDelayedAckTimeMs = 25;
+const int64_t kMaxDelayedAckTimeMs = 25;
// The timeout before the handshake succeeds.
-const int64 kInitialIdleTimeoutSecs = 5;
+const int64_t kInitialIdleTimeoutSecs = 5;
// The default idle timeout.
-const int64 kDefaultIdleTimeoutSecs = 30;
+const int64_t kDefaultIdleTimeoutSecs = 30;
// The maximum idle timeout that can be negotiated.
-const int64 kMaximumIdleTimeoutSecs = 60 * 10; // 10 minutes.
+const int64_t kMaximumIdleTimeoutSecs = 60 * 10; // 10 minutes.
// The default timeout for a connection until the crypto handshake succeeds.
-const int64 kMaxTimeForCryptoHandshakeSecs = 10; // 10 secs.
+const int64_t kMaxTimeForCryptoHandshakeSecs = 10; // 10 secs.
// Default limit on the number of undecryptable packets the connection buffers
// before the CHLO/SHLO arrive.
const size_t kDefaultMaxUndecryptablePackets = 10;
// Default ping timeout.
-const int64 kPingTimeoutSecs = 15; // 15 secs.
+const int64_t kPingTimeoutSecs = 15; // 15 secs.
// Minimum number of RTTs between Server Config Updates (SCUP) sent to client.
const int kMinIntervalBetweenServerConfigUpdatesRTTs = 10;
@@ -162,32 +175,42 @@ const int kMinPacketsBetweenServerConfigUpdates = 100;
const float kMaxStreamsMultiplier = 1.1f;
const int kMaxStreamsMinimumIncrement = 10;
+// Available streams are ones with IDs less than the highest stream that has
+// been opened which have neither been opened or reset. The limit on the number
+// of available streams is 10 times the limit on the number of open streams.
+const int kMaxAvailableStreamsMultiplier = 10;
+
// We define an unsigned 16-bit floating point value, inspired by IEEE floats
// (http://en.wikipedia.org/wiki/Half_precision_floating-point_format),
// with 5-bit exponent (bias 1), 11-bit mantissa (effective 12 with hidden
// bit) and denormals, but without signs, transfinites or fractions. Wire format
// 16 bits (little-endian byte order) are split into exponent (high 5) and
// mantissa (low 11) and decoded as:
-// uint64 value;
+// uint64_t value;
// if (exponent == 0) value = mantissa;
// else value = (mantissa | 1 << 11) << (exponent - 1)
const int kUFloat16ExponentBits = 5;
-const int kUFloat16MaxExponent = (1 << kUFloat16ExponentBits) - 2; // 30
-const int kUFloat16MantissaBits = 16 - kUFloat16ExponentBits; // 11
+const int kUFloat16MaxExponent = (1 << kUFloat16ExponentBits) - 2; // 30
+const int kUFloat16MantissaBits = 16 - kUFloat16ExponentBits; // 11
const int kUFloat16MantissaEffectiveBits = kUFloat16MantissaBits + 1; // 12
-const uint64 kUFloat16MaxValue = // 0x3FFC0000000
- ((UINT64_C(1) << kUFloat16MantissaEffectiveBits) - 1) <<
- kUFloat16MaxExponent;
+const uint64_t kUFloat16MaxValue = // 0x3FFC0000000
+ ((UINT64_C(1) << kUFloat16MantissaEffectiveBits) - 1)
+ << kUFloat16MaxExponent;
+
+// Default path ID.
+const QuicPathId kDefaultPathId = 0;
+// Invalid path ID.
+const QuicPathId kInvalidPathId = 0xff;
enum TransmissionType {
NOT_RETRANSMISSION,
FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION,
- HANDSHAKE_RETRANSMISSION, // Retransmits due to handshake timeouts.
+ HANDSHAKE_RETRANSMISSION, // Retransmits due to handshake timeouts.
ALL_UNACKED_RETRANSMISSION, // Retransmits all unacked packets.
ALL_INITIAL_RETRANSMISSION, // Retransmits all initially encrypted packets.
- LOSS_RETRANSMISSION, // Retransmits due to loss detection.
- RTO_RETRANSMISSION, // Retransmits due to retransmit time out.
- TLP_RETRANSMISSION, // Tail loss probes.
+ LOSS_RETRANSMISSION, // Retransmits due to loss detection.
+ RTO_RETRANSMISSION, // Retransmits due to retransmit time out.
+ TLP_RETRANSMISSION, // Tail loss probes.
LAST_TRANSMISSION_TYPE = TLP_RETRANSMISSION,
};
@@ -196,10 +219,7 @@ enum HasRetransmittableData {
HAS_RETRANSMITTABLE_DATA,
};
-enum IsHandshake {
- NOT_HANDSHAKE,
- IS_HANDSHAKE
-};
+enum IsHandshake { NOT_HANDSHAKE, IS_HANDSHAKE };
enum class Perspective { IS_SERVER, IS_CLIENT };
@@ -304,8 +324,11 @@ enum QuicPacketPublicFlags {
PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4,
PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_6BYTE_PACKET << 4,
- // All bits set (bits 6 and 7 are not currently used): 00111111
- PACKET_PUBLIC_FLAGS_MAX = (1 << 6) - 1
+ // Bit 6: Does the packet header contain a path id?
+ PACKET_PUBLIC_FLAGS_MULTIPATH = 1 << 6,
+
+ // All bits set (bit7 are not currently used): 01111111
+ PACKET_PUBLIC_FLAGS_MAX = (1 << 7) - 1,
};
// The private flags are specified in one byte.
@@ -335,10 +358,13 @@ enum QuicVersion {
// Special case to indicate unknown/unsupported QUIC version.
QUIC_VERSION_UNSUPPORTED = 0,
- QUIC_VERSION_24 = 24, // SPDY/4 header compression.
QUIC_VERSION_25 = 25, // SPDY/4 header keys, and removal of error_details
// from QuicRstStreamFrame
QUIC_VERSION_26 = 26, // In CHLO, send XLCT tag containing hash of leaf cert
+ QUIC_VERSION_27 = 27, // Sends a nonce in the SHLO.
+ QUIC_VERSION_28 = 28, // Receiver can refuse to create a requested stream.
+ QUIC_VERSION_29 = 29, // Server and client honor QUIC_STREAM_NO_ERROR.
+ QUIC_VERSION_30 = 30, // Add server side support of cert transparency.
};
// This vector contains QUIC versions which we currently support.
@@ -349,7 +375,8 @@ enum QuicVersion {
// IMPORTANT: if you are adding to this list, follow the instructions at
// http://sites/quic/adding-and-removing-versions
static const QuicVersion kSupportedQuicVersions[] = {
- QUIC_VERSION_26, QUIC_VERSION_25, QUIC_VERSION_24};
+ QUIC_VERSION_30, QUIC_VERSION_29, QUIC_VERSION_28,
+ QUIC_VERSION_27, QUIC_VERSION_26, QUIC_VERSION_25};
typedef std::vector<QuicVersion> QuicVersionVector;
@@ -379,7 +406,7 @@ NET_EXPORT_PRIVATE std::string QuicVersionVectorToString(
// representation of the name of the tag. For example
// the client hello tag (CHLO) will be written as the
// following 4 bytes: 'C' 'H' 'L' 'O'. Since it is
-// stored in memory as a little endian uint32, we need
+// stored in memory as a little endian uint32_t, we need
// to reverse the order of the bytes.
// MakeQuicTag returns a value given the four bytes. For example:
@@ -396,6 +423,7 @@ NET_EXPORT_PRIVATE size_t GetPacketHeaderSize(const QuicPacketHeader& header);
NET_EXPORT_PRIVATE size_t
GetPacketHeaderSize(QuicConnectionIdLength connection_id_length,
bool include_version,
+ bool include_path_id,
QuicPacketNumberLength packet_number_length,
InFecGroup is_in_fec_group);
@@ -411,6 +439,8 @@ GetStartOfEncryptedData(QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length);
enum QuicRstStreamErrorCode {
+ // Complete response has been sent, sending a RST to ask the other endpoint
+ // to stop sending request data without discarding the response.
QUIC_STREAM_NO_ERROR = 0,
// There was some error which halted stream processing.
@@ -429,6 +459,10 @@ enum QuicRstStreamErrorCode {
// Closing stream locally, sending a RST to allow for proper flow control
// accounting. Sent in response to a RST from the peer.
QUIC_RST_ACKNOWLEDGEMENT,
+ // Receiver refused to create the stream (because its limit on open streams
+ // has been reached). The sender should retry the request later (using
+ // another stream).
+ QUIC_REFUSED_STREAM,
// No error. Used as bound while iterating.
QUIC_STREAM_LAST_ERROR,
@@ -437,13 +471,13 @@ enum QuicRstStreamErrorCode {
// Because receiving an unknown QuicRstStreamErrorCode results in connection
// teardown, we use this to make sure any errors predating a given version are
// downgraded to the most appropriate existing error.
-NET_EXPORT_PRIVATE QuicRstStreamErrorCode AdjustErrorForVersion(
- QuicRstStreamErrorCode error_code,
- QuicVersion version);
+NET_EXPORT_PRIVATE QuicRstStreamErrorCode
+AdjustErrorForVersion(QuicRstStreamErrorCode error_code, QuicVersion version);
// These values must remain stable as they are uploaded to UMA histograms.
// To add a new error code, use the current value of QUIC_LAST_ERROR and
// increment QUIC_LAST_ERROR.
+// last value = 78
enum QuicErrorCode {
QUIC_NO_ERROR = 0,
@@ -463,6 +497,8 @@ enum QuicErrorCode {
QUIC_INVALID_STREAM_DATA = 46,
// STREAM frame data is not encrypted.
QUIC_UNENCRYPTED_STREAM_DATA = 61,
+ // FEC frame data is not encrypted.
+ QUIC_UNENCRYPTED_FEC_DATA = 77,
// RST_STREAM frame data is malformed.
QUIC_INVALID_RST_STREAM_DATA = 6,
// CONNECTION_CLOSE frame data is malformed.
@@ -478,8 +514,6 @@ enum QuicErrorCode {
// ACK frame data is malformed.
QUIC_INVALID_ACK_DATA = 9,
- // deprecated: QUIC_INVALID_CONGESTION_FEEDBACK_DATA = 47,
-
// Version negotiation packet is malformed.
QUIC_INVALID_VERSION_NEGOTIATION_PACKET = 10,
// Public RST packet is malformed.
@@ -490,8 +524,6 @@ enum QuicErrorCode {
QUIC_ENCRYPTION_FAILURE = 13,
// The packet exceeded kMaxPacketSize.
QUIC_PACKET_TOO_LARGE = 14,
- // Data was sent for a stream which did not exist.
- QUIC_PACKET_FOR_NONEXISTENT_STREAM = 15,
// The peer is going away. May be a client or server.
QUIC_PEER_GOING_AWAY = 16,
// A stream ID was invalid.
@@ -500,15 +532,13 @@ enum QuicErrorCode {
QUIC_INVALID_PRIORITY = 49,
// Too many streams already open.
QUIC_TOO_MANY_OPEN_STREAMS = 18,
- // The peer must send a FIN/RST for each stream, and has not been doing so.
- QUIC_TOO_MANY_UNFINISHED_STREAMS = 66,
+ // The peer created too many available streams.
+ QUIC_TOO_MANY_AVAILABLE_STREAMS = 76,
// Received public reset for this connection.
QUIC_PUBLIC_RESET = 19,
// Invalid protocol version.
QUIC_INVALID_VERSION = 20,
- // deprecated: QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED = 21
-
// The Header ID for a stream was too far from the previous.
QUIC_INVALID_HEADER_ID = 22,
// Negotiable parameter received during handshake had invalid value.
@@ -609,10 +639,26 @@ enum QuicErrorCode {
// tampered with.
QUIC_VERSION_NEGOTIATION_MISMATCH = 55,
+ // IP address changed causing connection close.
+ QUIC_IP_ADDRESS_CHANGED = 78,
+
+ // Connection migration errors.
+ // Network changed, but connection had no migratable streams.
+ QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS = 79,
+ // Connection changed networks too many times.
+ QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES = 80,
+ // Connection migration was attempted, but there was no new network to
+ // migrate to.
+ QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK = 81,
+
// No error. Used as bound while iterating.
- QUIC_LAST_ERROR = 76,
+ QUIC_LAST_ERROR = 82,
};
+// Must be updated any time a QuicErrorCode is deprecated.
+const int kDeprecatedQuicErrorCount = 4;
+const int kActiveQuicErrorCount = QUIC_LAST_ERROR - kDeprecatedQuicErrorCount;
+
struct NET_EXPORT_PRIVATE QuicPacketPublicHeader {
QuicPacketPublicHeader();
explicit QuicPacketPublicHeader(const QuicPacketPublicHeader& other);
@@ -622,6 +668,7 @@ struct NET_EXPORT_PRIVATE QuicPacketPublicHeader {
// public flags.
QuicConnectionId connection_id;
QuicConnectionIdLength connection_id_length;
+ bool multipath_flag;
bool reset_flag;
bool version_flag;
QuicPacketNumberLength packet_number_length;
@@ -636,11 +683,12 @@ struct NET_EXPORT_PRIVATE QuicPacketHeader {
QuicPacketHeader();
explicit QuicPacketHeader(const QuicPacketPublicHeader& header);
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicPacketHeader& s);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+ const QuicPacketHeader& s);
QuicPacketPublicHeader public_header;
- QuicPacketNumber packet_packet_number;
+ QuicPathId path_id;
+ QuicPacketNumber packet_number;
bool fec_flag;
bool entropy_flag;
QuicPacketEntropyHash entropy_hash;
@@ -675,48 +723,103 @@ enum QuicVersionNegotiationState {
typedef QuicPacketPublicHeader QuicVersionNegotiationPacket;
// A padding frame contains no payload.
-struct NET_EXPORT_PRIVATE QuicPaddingFrame {
-};
+struct NET_EXPORT_PRIVATE QuicPaddingFrame {};
// A ping frame contains no payload, though it is retransmittable,
// and ACK'd just like other normal frames.
-struct NET_EXPORT_PRIVATE QuicPingFrame {
-};
+struct NET_EXPORT_PRIVATE QuicPingFrame {};
// A path MTU discovery frame contains no payload and is serialized as a ping
// frame.
struct NET_EXPORT_PRIVATE QuicMtuDiscoveryFrame {};
+class NET_EXPORT_PRIVATE QuicBufferAllocator {
+ public:
+ virtual ~QuicBufferAllocator();
+
+ // Returns or allocates a new buffer of |size|. Never returns null.
+ virtual char* New(size_t size) = 0;
+
+ // Releases a buffer.
+ virtual void Delete(char* buffer) = 0;
+};
+
+// Deleter for stream buffers. Copyable to support platforms where the deleter
+// of a unique_ptr must be copyable. Otherwise it would be nice for this to be
+// move-only.
+class NET_EXPORT_PRIVATE StreamBufferDeleter {
+ public:
+ StreamBufferDeleter() : allocator_(nullptr) {}
+ explicit StreamBufferDeleter(QuicBufferAllocator* allocator)
+ : allocator_(allocator) {}
+
+ // Deletes |buffer| using |allocator_|.
+ void operator()(char* buffer) const;
+
+ private:
+ // Not owned; must be valid so long as the buffer stored in the unique_ptr
+ // that owns |this| is valid.
+ QuicBufferAllocator* allocator_;
+};
+
+using UniqueStreamBuffer = std::unique_ptr<char[], StreamBufferDeleter>;
+
+// Allocates memory of size |size| using |allocator| for a QUIC stream buffer.
+NET_EXPORT_PRIVATE UniqueStreamBuffer
+NewStreamBuffer(QuicBufferAllocator* allocator, size_t size);
+
struct NET_EXPORT_PRIVATE QuicStreamFrame {
QuicStreamFrame();
- QuicStreamFrame(const QuicStreamFrame& frame);
QuicStreamFrame(QuicStreamId stream_id,
bool fin,
QuicStreamOffset offset,
base::StringPiece data);
+ QuicStreamFrame(QuicStreamId stream_id,
+ bool fin,
+ QuicStreamOffset offset,
+ QuicPacketLength frame_length,
+ UniqueStreamBuffer buffer);
+ ~QuicStreamFrame();
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicStreamFrame& s);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+ const QuicStreamFrame& s);
QuicStreamId stream_id;
bool fin;
+ QuicPacketLength frame_length;
+ const char* frame_buffer;
QuicStreamOffset offset; // Location of this data in the stream.
- base::StringPiece data;
-};
+ // nullptr when the QuicStreamFrame is received, and non-null when sent.
+ UniqueStreamBuffer buffer;
+
+ private:
+ QuicStreamFrame(QuicStreamId stream_id,
+ bool fin,
+ QuicStreamOffset offset,
+ const char* frame_buffer,
+ QuicPacketLength frame_length,
+ UniqueStreamBuffer buffer);
+ DISALLOW_COPY_AND_ASSIGN(QuicStreamFrame);
+};
+static_assert(sizeof(QuicStreamFrame) <= 64,
+ "Keep the QuicStreamFrame size to a cacheline.");
// TODO(ianswett): Re-evaluate the trade-offs of hash_set vs set when framing
// is finalized.
typedef std::set<QuicPacketNumber> PacketNumberSet;
typedef std::list<QuicPacketNumber> PacketNumberList;
-typedef std::list<std::pair<QuicPacketNumber, QuicTime>> PacketTimeList;
+typedef std::vector<std::pair<QuicPacketNumber, QuicTime>> PacketTimeVector;
struct NET_EXPORT_PRIVATE QuicStopWaitingFrame {
QuicStopWaitingFrame();
~QuicStopWaitingFrame();
NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicStopWaitingFrame& s);
+ std::ostream& os,
+ const QuicStopWaitingFrame& s);
+ // Path which this stop waiting frame belongs to.
+ QuicPathId path_id;
// Entropy hash of all packets up to, but not including, the least unacked
// packet.
QuicPacketEntropyHash entropy_hash;
@@ -729,8 +832,8 @@ struct NET_EXPORT_PRIVATE QuicStopWaitingFrame {
// larger new packet numbers are added, with the occasional random access.
class NET_EXPORT_PRIVATE PacketNumberQueue {
public:
- // TODO(jdorfman): Once this is completely switched over to IntervalSet,
- // remove const_iterator and change the callers to iterate over the intervals.
+ // TODO(jdorfman): remove const_iterator and change the callers to
+ // iterate over the intervals.
class NET_EXPORT_PRIVATE const_iterator
: public std::iterator<std::input_iterator_tag,
QuicPacketNumber,
@@ -758,8 +861,6 @@ class NET_EXPORT_PRIVATE PacketNumberQueue {
const_iterator operator++(int /* postincrement */);
private:
- bool use_interval_set_;
- PacketNumberSet::const_iterator set_iter_;
IntervalSet<QuicPacketNumber>::const_iterator interval_set_iter_;
QuicPacketNumber current_;
QuicPacketNumber last_;
@@ -816,8 +917,6 @@ class NET_EXPORT_PRIVATE PacketNumberQueue {
const PacketNumberQueue& q);
private:
- bool use_interval_set_;
- PacketNumberSet packet_number_set_;
IntervalSet<QuicPacketNumber> packet_number_intervals_;
};
@@ -825,13 +924,19 @@ struct NET_EXPORT_PRIVATE QuicAckFrame {
QuicAckFrame();
~QuicAckFrame();
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicAckFrame& s);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+ const QuicAckFrame& s);
+
+ // Path which this ack belongs to.
+ QuicPathId path_id;
// Entropy hash of all packets up to largest observed not including missing
// packets.
QuicPacketEntropyHash entropy_hash;
+ // Whether the ack had to be truncated when sent.
+ bool is_truncated;
+
// The highest packet number we've observed from the peer.
//
// In general, this should be the largest packet number we've received. In
@@ -846,18 +951,15 @@ struct NET_EXPORT_PRIVATE QuicAckFrame {
// sent.
QuicTime::Delta delta_time_largest_observed;
+ // Vector of <packet_number, time> for when packets arrived.
+ PacketTimeVector received_packet_times;
+
// The set of packets which we're expecting and have not received.
PacketNumberQueue missing_packets;
- // Whether the ack had to be truncated when sent.
- bool is_truncated;
-
- // Packets which have been revived via FEC.
- // All of these must also be in missing_packets.
- PacketNumberSet revived_packets;
-
- // List of <packet_number, time> for when packets arrived.
- PacketTimeList received_packet_times;
+ // Packet most recently revived via FEC, 0 if no packet was revived by FEC.
+ // If non-zero, must be present in missing_packets.
+ QuicPacketNumber latest_revived_packet;
};
// True if the packet number is greater than largest_observed or is listed
@@ -890,12 +992,11 @@ struct NET_EXPORT_PRIVATE QuicRstStreamFrame {
QuicStreamOffset bytes_written);
NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicRstStreamFrame& r);
+ std::ostream& os,
+ const QuicRstStreamFrame& r);
QuicStreamId stream_id;
QuicRstStreamErrorCode error_code;
- // Only used in versions <= QUIC_VERSION_24.
- std::string error_details;
// Used to update flow control windows. On termination of a stream, both
// endpoints must inform the peer of the number of bytes they have sent on
@@ -908,7 +1009,8 @@ struct NET_EXPORT_PRIVATE QuicConnectionCloseFrame {
QuicConnectionCloseFrame();
NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicConnectionCloseFrame& c);
+ std::ostream& os,
+ const QuicConnectionCloseFrame& c);
QuicErrorCode error_code;
std::string error_details;
@@ -920,8 +1022,8 @@ struct NET_EXPORT_PRIVATE QuicGoAwayFrame {
QuicStreamId last_good_stream_id,
const std::string& reason);
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicGoAwayFrame& g);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+ const QuicGoAwayFrame& g);
QuicErrorCode error_code;
QuicStreamId last_good_stream_id;
@@ -938,7 +1040,8 @@ struct NET_EXPORT_PRIVATE QuicWindowUpdateFrame {
QuicWindowUpdateFrame(QuicStreamId stream_id, QuicStreamOffset byte_offset);
NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicWindowUpdateFrame& w);
+ std::ostream& os,
+ const QuicWindowUpdateFrame& w);
// The stream this frame applies to. 0 is a special case meaning the overall
// connection rather than a specific stream.
@@ -957,8 +1060,8 @@ struct NET_EXPORT_PRIVATE QuicBlockedFrame {
QuicBlockedFrame() {}
explicit QuicBlockedFrame(QuicStreamId stream_id);
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicBlockedFrame& b);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+ const QuicBlockedFrame& b);
// The stream this frame applies to. 0 is a special case meaning the overall
// connection rather than a specific stream.
@@ -977,34 +1080,52 @@ enum EncryptionLevel {
NUM_ENCRYPTION_LEVELS,
};
+enum PeerAddressChangeType {
+ NO_CHANGE,
+ // Peer address changes which are considered to be cause by NATs. Currently,
+ // IPv4 address change with /24 does not change is considered to be cause by
+ // NATs.
+ NAT_PORT_REBINDING,
+ IPV4_SUBNET_REBINDING,
+ // IPv6 related address changes.
+ IPV4_TO_IPV6,
+ IPV6_TO_IPV4,
+ IPV6_TO_IPV6,
+ // This type is used when we always allow peer address changes.
+ UNKNOWN,
+ // All other peer address change types.
+ UNSPECIFIED,
+};
+
struct NET_EXPORT_PRIVATE QuicFrame {
QuicFrame();
- explicit QuicFrame(QuicPaddingFrame* padding_frame);
+ explicit QuicFrame(QuicPaddingFrame padding_frame);
+ explicit QuicFrame(QuicMtuDiscoveryFrame frame);
+ explicit QuicFrame(QuicPingFrame frame);
+
explicit QuicFrame(QuicStreamFrame* stream_frame);
explicit QuicFrame(QuicAckFrame* frame);
- explicit QuicFrame(QuicMtuDiscoveryFrame* frame);
-
explicit QuicFrame(QuicRstStreamFrame* frame);
explicit QuicFrame(QuicConnectionCloseFrame* frame);
explicit QuicFrame(QuicStopWaitingFrame* frame);
- explicit QuicFrame(QuicPingFrame* frame);
explicit QuicFrame(QuicGoAwayFrame* frame);
explicit QuicFrame(QuicWindowUpdateFrame* frame);
explicit QuicFrame(QuicBlockedFrame* frame);
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicFrame& frame);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+ const QuicFrame& frame);
QuicFrameType type;
union {
- QuicPaddingFrame* padding_frame;
+ // Frames smaller than a pointer are inline.
+ QuicPaddingFrame padding_frame;
+ QuicMtuDiscoveryFrame mtu_discovery_frame;
+ QuicPingFrame ping_frame;
+
+ // Frames larger than a pointer.
QuicStreamFrame* stream_frame;
QuicAckFrame* ack_frame;
- QuicMtuDiscoveryFrame* mtu_discovery_frame;
-
QuicStopWaitingFrame* stop_waiting_frame;
-
- QuicPingFrame* ping_frame;
QuicRstStreamFrame* rst_stream_frame;
QuicConnectionCloseFrame* connection_close_frame;
QuicGoAwayFrame* goaway_frame;
@@ -1012,19 +1133,12 @@ struct NET_EXPORT_PRIVATE QuicFrame {
QuicBlockedFrame* blocked_frame;
};
};
+// QuicFrameType consumes 8 bytes with padding.
+static_assert(sizeof(QuicFrame) <= 16,
+ "Frames larger than 8 bytes should be referenced by pointer.");
typedef std::vector<QuicFrame> QuicFrames;
-struct NET_EXPORT_PRIVATE QuicFecData {
- QuicFecData();
-
- // The FEC group number is also the packet number of the first
- // FEC protected packet. The last protected packet's packet number will
- // be one less than the packet number of the FEC packet.
- QuicFecGroupNumber fec_group;
- base::StringPiece redundancy;
-};
-
class NET_EXPORT_PRIVATE QuicData {
public:
QuicData(const char* buffer, size_t length);
@@ -1058,7 +1172,6 @@ class NET_EXPORT_PRIVATE QuicPacket : public QuicData {
base::StringPiece FecProtectedData() const;
base::StringPiece AssociatedData() const;
- base::StringPiece BeforePlaintext() const;
base::StringPiece Plaintext() const;
char* mutable_data() { return buffer_; }
@@ -1085,7 +1198,8 @@ class NET_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
// bytes, which causes the default gtest object printer to read
// uninitialize memory. So we need to teach gtest how to print this object.
NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicEncryptedPacket& s);
+ std::ostream& os,
+ const QuicEncryptedPacket& s);
private:
DISALLOW_COPY_AND_ASSIGN(QuicEncryptedPacket);
@@ -1093,25 +1207,17 @@ class NET_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
class NET_EXPORT_PRIVATE RetransmittableFrames {
public:
- explicit RetransmittableFrames(EncryptionLevel level);
+ RetransmittableFrames();
~RetransmittableFrames();
// Takes ownership of the frame inside |frame|.
const QuicFrame& AddFrame(const QuicFrame& frame);
- // Takes ownership of the frame inside |frame| and |buffer|.
- const QuicFrame& AddFrame(const QuicFrame& frame, char* buffer);
// Removes all stream frames associated with |stream_id|.
void RemoveFramesForStream(QuicStreamId stream_id);
const QuicFrames& frames() const { return frames_; }
- IsHandshake HasCryptoHandshake() const {
- return has_crypto_handshake_;
- }
-
- EncryptionLevel encryption_level() const {
- return encryption_level_;
- }
+ IsHandshake HasCryptoHandshake() const { return has_crypto_handshake_; }
bool needs_padding() const { return needs_padding_; }
@@ -1119,36 +1225,58 @@ class NET_EXPORT_PRIVATE RetransmittableFrames {
private:
QuicFrames frames_;
- const EncryptionLevel encryption_level_;
IsHandshake has_crypto_handshake_;
bool needs_padding_;
- // Data referenced by the StringPiece of a QuicStreamFrame.
- std::vector<const char*> stream_data_;
DISALLOW_COPY_AND_ASSIGN(RetransmittableFrames);
};
+struct NET_EXPORT_PRIVATE AckListenerWrapper {
+ AckListenerWrapper(QuicAckListenerInterface* listener,
+ QuicPacketLength data_length);
+ ~AckListenerWrapper();
+
+ scoped_refptr<QuicAckListenerInterface> ack_listener;
+ QuicPacketLength length;
+};
+
struct NET_EXPORT_PRIVATE SerializedPacket {
- SerializedPacket(QuicPacketNumber packet_number,
+ SerializedPacket(QuicPathId path_id,
+ QuicPacketNumber packet_number,
QuicPacketNumberLength packet_number_length,
QuicEncryptedPacket* packet,
QuicPacketEntropyHash entropy_hash,
RetransmittableFrames* retransmittable_frames,
bool has_ack,
bool has_stop_waiting);
+ SerializedPacket(QuicPathId path_id,
+ QuicPacketNumber packet_number,
+ QuicPacketNumberLength packet_number_length,
+ char* encrypted_buffer,
+ size_t encrypted_length,
+ bool owns_buffer,
+ QuicPacketEntropyHash entropy_hash,
+ RetransmittableFrames* retransmittable_frames,
+ bool has_ack,
+ bool has_stop_waiting,
+ EncryptionLevel level);
~SerializedPacket();
QuicEncryptedPacket* packet;
RetransmittableFrames* retransmittable_frames;
+ QuicPathId path_id;
QuicPacketNumber packet_number;
QuicPacketNumberLength packet_number_length;
+ EncryptionLevel encryption_level;
QuicPacketEntropyHash entropy_hash;
bool is_fec_packet;
bool has_ack;
bool has_stop_waiting;
+ QuicPacketNumber original_packet_number;
+ TransmissionType transmission_type;
// Optional notifiers which will be informed when this packet has been ACKed.
- std::list<QuicAckNotifier*> notifiers;
+ std::list<AckListenerWrapper> listeners;
};
struct NET_EXPORT_PRIVATE TransmissionInfo {
@@ -1158,29 +1286,41 @@ struct NET_EXPORT_PRIVATE TransmissionInfo {
// Constructs a Transmission with a new all_tranmissions set
// containing |packet_number|.
TransmissionInfo(RetransmittableFrames* retransmittable_frames,
+ EncryptionLevel level,
QuicPacketNumberLength packet_number_length,
TransmissionType transmission_type,
QuicTime sent_time,
- QuicByteCount bytes_sent,
+ QuicPacketLength bytes_sent,
bool is_fec_packet);
+ ~TransmissionInfo();
+
RetransmittableFrames* retransmittable_frames;
+ EncryptionLevel encryption_level;
QuicPacketNumberLength packet_number_length;
+ QuicPacketLength bytes_sent;
+ uint16_t nack_count;
QuicTime sent_time;
- QuicByteCount bytes_sent;
- QuicPacketCount nack_count;
// Reason why this packet was transmitted.
TransmissionType transmission_type;
- // Stores the packet numbers of all transmissions of this packet.
- // Must always be nullptr or have multiple elements.
- PacketNumberList* all_transmissions;
// In flight packets have not been abandoned or lost.
bool in_flight;
// True if the packet can never be acked, so it can be removed.
bool is_unackable;
// True if the packet is an FEC packet.
bool is_fec_packet;
+ // Stores the packet numbers of all transmissions of this packet.
+ // Must always be nullptr or have multiple elements.
+ // TODO(ianswett): Deprecate with quic_track_single_retransmission.
+ PacketNumberList* all_transmissions;
+ // Stores the packet number of the next retransmission of this packet.
+ // Zero if the packet has not been retransmitted.
+ QuicPacketNumber retransmission;
+ // Non-empty if there is a listener for this packet.
+ std::list<AckListenerWrapper> ack_listeners;
};
+static_assert(sizeof(QuicFrame) <= 64,
+ "Keep the TransmissionInfo size to a cacheline.");
// Convenience wrapper to wrap an iovec array and the total length, which must
// be less than or equal to the actual total length of the iovecs.
diff --git a/chromium/net/quic/quic_protocol_test.cc b/chromium/net/quic/quic_protocol_test.cc
index c74d3d108d6..7f9aaa6aa2a 100644
--- a/chromium/net/quic/quic_protocol_test.cc
+++ b/chromium/net/quic/quic_protocol_test.cc
@@ -7,6 +7,7 @@
#include <sstream>
#include "base/stl_util.h"
+#include "net/quic/quic_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -14,7 +15,7 @@ namespace test {
namespace {
TEST(QuicProtocolTest, AdjustErrorForVersion) {
- ASSERT_EQ(8, QUIC_STREAM_LAST_ERROR)
+ ASSERT_EQ(9, QUIC_STREAM_LAST_ERROR)
<< "Any additions to QuicRstStreamErrorCode require an addition to "
<< "AdjustErrorForVersion and this associated test.";
@@ -22,7 +23,7 @@ TEST(QuicProtocolTest, AdjustErrorForVersion) {
// following.
// EXPECT_EQ(QUIC_RST_ACKNOWLEDGEMENT, AdjustErrorForVersion(
// QUIC_RST_ACKNOWLEDGEMENT,
- // QUIC_VERSION_24));
+ // QUIC_VERSION_28));
}
TEST(QuicProtocolTest, MakeQuicTag) {
@@ -45,11 +46,25 @@ TEST(QuicProtocolTest, IsAawaitingPacket) {
EXPECT_TRUE(IsAwaitingPacket(ack_frame, 10u));
}
+TEST(QuicProtocolTest, QuicDeprecatedErrorCodeCount) {
+ // If you deprecated any QuicErrorCode, you will need to update the
+ // deprecated QuicErrorCode count. Otherwise this test will fail.
+ int num_deprecated_errors = 0;
+ std::string invalid_error_code = "INVALID_ERROR_CODE";
+ for (int i = 0; i < QUIC_LAST_ERROR; ++i) {
+ if (QuicUtils::ErrorToString(static_cast<QuicErrorCode>(i)) ==
+ invalid_error_code) {
+ ++num_deprecated_errors;
+ }
+ }
+ EXPECT_EQ(kDeprecatedQuicErrorCount, num_deprecated_errors);
+}
+
TEST(QuicProtocolTest, QuicVersionToQuicTag) {
- // If you add a new version to the QuicVersion enum you will need to add a new
- // case to QuicVersionToQuicTag, otherwise this test will fail.
+// If you add a new version to the QuicVersion enum you will need to add a new
+// case to QuicVersionToQuicTag, otherwise this test will fail.
- // TODO(rtenneti): Enable checking of Log(ERROR) messages.
+// TODO(rtenneti): Enable checking of Log(ERROR) messages.
#if 0
// Any logs would indicate an unsupported version which we don't expect.
ScopedMockLog log(kDoNotCaptureLogsYet);
@@ -71,7 +86,7 @@ TEST(QuicProtocolTest, QuicVersionToQuicTag) {
}
TEST(QuicProtocolTest, QuicVersionToQuicTagUnsupported) {
- // TODO(rtenneti): Enable checking of Log(ERROR) messages.
+// TODO(rtenneti): Enable checking of Log(ERROR) messages.
#if 0
// TODO(rjshade): Change to DFATAL once we actually support multiple versions,
// and QuicConnectionTest::SendVersionNegotiationPacket can be changed to use
@@ -85,10 +100,10 @@ TEST(QuicProtocolTest, QuicVersionToQuicTagUnsupported) {
}
TEST(QuicProtocolTest, QuicTagToQuicVersion) {
- // If you add a new version to the QuicVersion enum you will need to add a new
- // case to QuicTagToQuicVersion, otherwise this test will fail.
+// If you add a new version to the QuicVersion enum you will need to add a new
+// case to QuicTagToQuicVersion, otherwise this test will fail.
- // TODO(rtenneti): Enable checking of Log(ERROR) messages.
+// TODO(rtenneti): Enable checking of Log(ERROR) messages.
#if 0
// Any logs would indicate an unsupported version which we don't expect.
ScopedMockLog log(kDoNotCaptureLogsYet);
@@ -115,7 +130,7 @@ TEST(QuicProtocolTest, QuicTagToQuicVersion) {
}
TEST(QuicProtocolTest, QuicTagToQuicVersionUnsupported) {
- // TODO(rtenneti): Enable checking of Log(ERROR) messages.
+// TODO(rtenneti): Enable checking of Log(ERROR) messages.
#if 0
ScopedMockLog log(kDoNotCaptureLogsYet);
#ifndef NDEBUG
diff --git a/chromium/net/quic/quic_received_packet_manager.cc b/chromium/net/quic/quic_received_packet_manager.cc
index 702573e0912..81e94de3be3 100644
--- a/chromium/net/quic/quic_received_packet_manager.cc
+++ b/chromium/net/quic/quic_received_packet_manager.cc
@@ -27,14 +27,10 @@ namespace {
// Set to the number of nacks needed for fast retransmit plus one for protection
// against an ack loss
const size_t kMaxPacketsAfterNewMissing = 4;
-
}
QuicReceivedPacketManager::EntropyTracker::EntropyTracker()
- : packets_entropy_hash_(0),
- first_gap_(1),
- largest_observed_(0) {
-}
+ : packets_entropy_hash_(0), first_gap_(1), largest_observed_(0) {}
QuicReceivedPacketManager::EntropyTracker::~EntropyTracker() {}
@@ -115,7 +111,7 @@ void QuicReceivedPacketManager::EntropyTracker::SetCumulativeEntropyUpTo(
// and since packet_number.
packets_entropy_hash_ = entropy_hash;
for (ReceivedEntropyHashes::const_iterator it = packets_entropy_.begin();
- it != packets_entropy_.end(); ++it) {
+ it != packets_entropy_.end(); ++it) {
packets_entropy_hash_ ^= it->first;
}
@@ -124,7 +120,7 @@ void QuicReceivedPacketManager::EntropyTracker::SetCumulativeEntropyUpTo(
}
void QuicReceivedPacketManager::EntropyTracker::
-AdvanceFirstGapAndGarbageCollectEntropyMap() {
+ AdvanceFirstGapAndGarbageCollectEntropyMap() {
while (!packets_entropy_.empty() && packets_entropy_.front().second) {
++first_gap_;
packets_entropy_.pop_front();
@@ -133,6 +129,7 @@ AdvanceFirstGapAndGarbageCollectEntropyMap() {
QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
: peer_least_packet_awaiting_ack_(0),
+ ack_frame_updated_(false),
time_largest_observed_(QuicTime::Zero()),
stats_(stats) {
ack_frame_.largest_observed = 0;
@@ -145,8 +142,9 @@ void QuicReceivedPacketManager::RecordPacketReceived(
QuicByteCount bytes,
const QuicPacketHeader& header,
QuicTime receipt_time) {
- QuicPacketNumber packet_number = header.packet_packet_number;
+ QuicPacketNumber packet_number = header.packet_number;
DCHECK(IsAwaitingPacket(packet_number));
+ ack_frame_updated_ = true;
// Adds the range of packet numbers from max(largest observed + 1, least
// awaiting ack) up to packet_number not including packet_number.
@@ -165,10 +163,10 @@ void QuicReceivedPacketManager::RecordPacketReceived(
stats_->max_sequence_reordering =
max(stats_->max_sequence_reordering,
ack_frame_.largest_observed - packet_number);
- int64 reordering_time_us =
+ int64_t reordering_time_us =
receipt_time.Subtract(time_largest_observed_).ToMicroseconds();
- stats_->max_time_reordering_us = max(stats_->max_time_reordering_us,
- reordering_time_us);
+ stats_->max_time_reordering_us =
+ max(stats_->max_time_reordering_us, reordering_time_us);
}
if (packet_number > ack_frame_.largest_observed) {
ack_frame_.largest_observed = packet_number;
@@ -176,15 +174,19 @@ void QuicReceivedPacketManager::RecordPacketReceived(
}
entropy_tracker_.RecordPacketEntropyHash(packet_number, header.entropy_hash);
- received_packet_times_.push_back(std::make_pair(packet_number, receipt_time));
+ ack_frame_.received_packet_times.push_back(
+ std::make_pair(packet_number, receipt_time));
- ack_frame_.revived_packets.erase(packet_number);
+ if (ack_frame_.latest_revived_packet == packet_number) {
+ ack_frame_.latest_revived_packet = 0;
+ }
}
void QuicReceivedPacketManager::RecordPacketRevived(
QuicPacketNumber packet_number) {
LOG_IF(DFATAL, !IsAwaitingPacket(packet_number));
- ack_frame_.revived_packets.insert(packet_number);
+ ack_frame_updated_ = true;
+ ack_frame_.latest_revived_packet = packet_number;
}
bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
@@ -204,13 +206,15 @@ struct isTooLarge {
// Return true if the packet in p is too different from largest_observed_
// to express.
bool operator()(const std::pair<QuicPacketNumber, QuicTime>& p) const {
- return largest_observed_ - p.first >= numeric_limits<uint8>::max();
+ return largest_observed_ - p.first >= numeric_limits<uint8_t>::max();
}
};
} // namespace
void QuicReceivedPacketManager::UpdateReceivedPacketInfo(
- QuicAckFrame* ack_frame, QuicTime approximate_now) {
+ QuicAckFrame* ack_frame,
+ QuicTime approximate_now) {
+ ack_frame_updated_ = false;
*ack_frame = ack_frame_;
ack_frame->entropy_hash = EntropyHash(ack_frame_.largest_observed);
@@ -222,15 +226,27 @@ void QuicReceivedPacketManager::UpdateReceivedPacketInfo(
// Ensure the delta is zero if approximate now is "in the past".
ack_frame->delta_time_largest_observed =
- approximate_now < time_largest_observed_ ?
- QuicTime::Delta::Zero() :
- approximate_now.Subtract(time_largest_observed_);
-
- // Remove all packets that are too far from largest_observed to express.
- received_packet_times_.remove_if(isTooLarge(ack_frame_.largest_observed));
+ approximate_now < time_largest_observed_
+ ? QuicTime::Delta::Zero()
+ : approximate_now.Subtract(time_largest_observed_);
+
+ // Clear all packet times if any are too far from largest observed.
+ // It's expected this is extremely rare.
+ for (PacketTimeVector::iterator it = ack_frame_.received_packet_times.begin();
+ it != ack_frame_.received_packet_times.end();) {
+ if (ack_frame_.largest_observed - it->first >=
+ numeric_limits<uint8_t>::max()) {
+ it = ack_frame_.received_packet_times.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ // TODO(ianswett): Instead of transferring all the information over,
+ // consider giving the QuicPacketGenerator a reference to this ack frame
+ // and clear it afterwards.
ack_frame->received_packet_times.clear();
- ack_frame->received_packet_times.swap(received_packet_times_);
+ ack_frame->received_packet_times.swap(ack_frame_.received_packet_times);
}
QuicPacketEntropyHash QuicReceivedPacketManager::EntropyHash(
@@ -240,9 +256,9 @@ QuicPacketEntropyHash QuicReceivedPacketManager::EntropyHash(
bool QuicReceivedPacketManager::DontWaitForPacketsBefore(
QuicPacketNumber least_unacked) {
- ack_frame_.revived_packets.erase(
- ack_frame_.revived_packets.begin(),
- ack_frame_.revived_packets.lower_bound(least_unacked));
+ if (ack_frame_.latest_revived_packet < least_unacked) {
+ ack_frame_.latest_revived_packet = 0;
+ }
return ack_frame_.missing_packets.RemoveUpTo(least_unacked);
}
@@ -258,6 +274,9 @@ void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer(
// the received entropy hash.
entropy_tracker_.SetCumulativeEntropyUpTo(stop_waiting.least_unacked,
stop_waiting.entropy_hash);
+ // Ack frame gets updated because missing packets are updated because of
+ // stop waiting frame.
+ ack_frame_updated_ = true;
}
peer_least_packet_awaiting_ack_ = stop_waiting.least_unacked;
}
@@ -275,4 +294,8 @@ size_t QuicReceivedPacketManager::NumTrackedPackets() const {
return entropy_tracker_.size();
}
+bool QuicReceivedPacketManager::ack_frame_updated() const {
+ return ack_frame_updated_;
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_received_packet_manager.h b/chromium/net/quic/quic_received_packet_manager.h
index 10958083479..c037aed354d 100644
--- a/chromium/net/quic/quic_received_packet_manager.h
+++ b/chromium/net/quic/quic_received_packet_manager.h
@@ -8,8 +8,11 @@
#ifndef NET_QUIC_QUIC_RECEIVED_PACKET_MANAGER_H_
#define NET_QUIC_QUIC_RECEIVED_PACKET_MANAGER_H_
+#include <stddef.h>
+
#include <deque>
+#include "base/macros.h"
#include "net/quic/quic_config.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
@@ -27,8 +30,8 @@ struct QuicConnectionStats;
// Records all received packets by a connection and tracks their entropy.
// Also calculates the correct entropy for the framer when it truncates an ack
// frame being serialized.
-class NET_EXPORT_PRIVATE QuicReceivedPacketManager :
- public QuicReceivedEntropyHashCalculatorInterface {
+class NET_EXPORT_PRIVATE QuicReceivedPacketManager
+ : public QuicReceivedEntropyHashCalculatorInterface {
public:
class NET_EXPORT_PRIVATE EntropyTracker {
public:
@@ -102,17 +105,17 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager :
// bytes: the packet size in bytes including Quic Headers.
// header: the packet header.
// timestamp: the arrival time of the packet.
- void RecordPacketReceived(QuicByteCount bytes,
- const QuicPacketHeader& header,
- QuicTime receipt_time);
+ virtual void RecordPacketReceived(QuicByteCount bytes,
+ const QuicPacketHeader& header,
+ QuicTime receipt_time);
- void RecordPacketRevived(QuicPacketNumber packet_number);
+ virtual void RecordPacketRevived(QuicPacketNumber packet_number);
// Checks whether |packet_number| is missing and less than largest observed.
- bool IsMissing(QuicPacketNumber packet_number);
+ virtual bool IsMissing(QuicPacketNumber packet_number);
// Checks if we're still waiting for the packet with |packet_number|.
- bool IsAwaitingPacket(QuicPacketNumber packet_number);
+ virtual bool IsAwaitingPacket(QuicPacketNumber packet_number);
// Update the |ack_frame| for an outgoing ack.
void UpdateReceivedPacketInfo(QuicAckFrame* ack_frame,
@@ -125,12 +128,12 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager :
QuicPacketNumber packet_number) const override;
// Updates internal state based on |stop_waiting|.
- void UpdatePacketInformationSentByPeer(
+ virtual void UpdatePacketInformationSentByPeer(
const QuicStopWaitingFrame& stop_waiting);
// Returns true when there are new missing packets to be reported within 3
// packets of the largest observed.
- bool HasNewMissingPackets() const;
+ virtual bool HasNewMissingPackets() const;
// Returns the number of packets being tracked in the EntropyTracker.
size_t NumTrackedPackets() const;
@@ -139,6 +142,8 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager :
return peer_least_packet_awaiting_ack_;
}
+ virtual bool ack_frame_updated() const;
+
private:
friend class test::QuicConnectionPeer;
friend class test::QuicReceivedPacketManagerPeer;
@@ -159,6 +164,10 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager :
// Received packet information used to produce acks.
QuicAckFrame ack_frame_;
+ // True if |ack_frame_| has been updated since UpdateReceivedPacketInfo was
+ // last called.
+ bool ack_frame_updated_;
+
// The time we received the largest_observed packet number, or zero if
// no packet numbers have been received since UpdateReceivedPacketInfo.
// Needed for calculating delta_time_largest_observed.
@@ -166,8 +175,6 @@ class NET_EXPORT_PRIVATE QuicReceivedPacketManager :
QuicConnectionStats* stats_;
- PacketTimeList received_packet_times_;
-
DISALLOW_COPY_AND_ASSIGN(QuicReceivedPacketManager);
};
diff --git a/chromium/net/quic/quic_received_packet_manager_test.cc b/chromium/net/quic/quic_received_packet_manager_test.cc
index 4cc61836981..926fcfb5f47 100644
--- a/chromium/net/quic/quic_received_packet_manager_test.cc
+++ b/chromium/net/quic/quic_received_packet_manager_test.cc
@@ -198,7 +198,7 @@ class QuicReceivedPacketManagerTest : public ::testing::Test {
QuicPacketEntropyHash entropy_hash,
QuicTime receipt_time) {
QuicPacketHeader header;
- header.packet_packet_number = packet_number;
+ header.packet_number = packet_number;
header.entropy_hash = entropy_hash;
received_manager_.RecordPacketReceived(0u, header, receipt_time);
}
@@ -232,7 +232,8 @@ TEST_F(QuicReceivedPacketManagerTest, ReceivedPacketEntropyHash) {
hash ^= entropies[index].second;
++index;
}
- if (i < 3) continue;
+ if (i < 3)
+ continue;
EXPECT_EQ(hash, received_manager_.EntropyHash(i));
}
// Reorder by 5 when 2 is received after 7.
@@ -274,12 +275,12 @@ TEST_F(QuicReceivedPacketManagerTest, SetCumulativeEntropyUpTo) {
for (size_t i = 0; i < 4; ++i) {
entropy_hash ^= entropies[i].second;
}
- QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(
- &received_manager_, 5, 100);
+ QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(&received_manager_, 5,
+ 100);
EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7));
- QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(
- &received_manager_, 1, 50);
+ QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(&received_manager_, 1,
+ 50);
EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7));
// No reordering.
@@ -290,9 +291,9 @@ TEST_F(QuicReceivedPacketManagerTest, SetCumulativeEntropyUpTo) {
TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
QuicPacketHeader header;
- header.packet_packet_number = 2u;
+ header.packet_number = 2u;
received_manager_.RecordPacketReceived(0u, header, QuicTime::Zero());
- header.packet_packet_number = 7u;
+ header.packet_number = 7u;
received_manager_.RecordPacketReceived(0u, header, QuicTime::Zero());
EXPECT_TRUE(received_manager_.IsAwaitingPacket(3u));
EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u));
@@ -304,27 +305,47 @@ TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedPacketInfo) {
QuicPacketHeader header;
- header.packet_packet_number = 2u;
+ header.packet_number = 2u;
QuicTime two_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
received_manager_.RecordPacketReceived(0u, header, two_ms);
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
QuicAckFrame ack;
received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
// When UpdateReceivedPacketInfo with a time earlier than the time of the
// largest observed packet, make sure that the delta is 0, not negative.
EXPECT_EQ(QuicTime::Delta::Zero(), ack.delta_time_largest_observed);
- EXPECT_FALSE(ack.received_packet_times.empty());
+ EXPECT_EQ(1ul, ack.received_packet_times.size());
QuicTime four_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(4));
received_manager_.UpdateReceivedPacketInfo(&ack, four_ms);
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
// When UpdateReceivedPacketInfo after not having received a new packet,
// the delta should still be accurate.
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
ack.delta_time_largest_observed);
+ EXPECT_EQ(0ul, ack.received_packet_times.size());
+
+ header.packet_number = 999u;
+ received_manager_.RecordPacketReceived(0u, header, two_ms);
+ header.packet_number = 4u;
+ received_manager_.RecordPacketReceived(0u, header, two_ms);
+ header.packet_number = 1000u;
+ received_manager_.RecordPacketReceived(0u, header, two_ms);
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
+ received_manager_.UpdateReceivedPacketInfo(&ack, two_ms);
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
+ // UpdateReceivedPacketInfo should discard any times which can't be
+ // expressed on the wire.
+ EXPECT_EQ(2ul, ack.received_packet_times.size());
}
TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
RecordPacketReceipt(1, 0);
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
RecordPacketReceipt(6, 0);
RecordPacketReceipt(
2, 0, QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1)));
@@ -335,20 +356,24 @@ TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
}
TEST_F(QuicReceivedPacketManagerTest, RevivedPacket) {
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
RecordPacketReceipt(1, 0);
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
RecordPacketReceipt(3, 0);
RecordPacketRevived(2);
QuicAckFrame ack;
received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
EXPECT_EQ(1u, ack.missing_packets.NumPacketsSlow());
EXPECT_EQ(2u, ack.missing_packets.Min());
- EXPECT_EQ(1u, ack.revived_packets.size());
- EXPECT_EQ(2u, *ack.revived_packets.begin());
+ EXPECT_EQ(2u, ack.latest_revived_packet);
}
TEST_F(QuicReceivedPacketManagerTest, PacketRevivedThenReceived) {
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
RecordPacketReceipt(1, 0);
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
RecordPacketReceipt(3, 0);
RecordPacketRevived(2);
RecordPacketReceipt(2, 0);
@@ -356,9 +381,30 @@ TEST_F(QuicReceivedPacketManagerTest, PacketRevivedThenReceived) {
QuicAckFrame ack;
received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
EXPECT_TRUE(ack.missing_packets.Empty());
- EXPECT_TRUE(ack.revived_packets.empty());
+ EXPECT_EQ(0u, ack.latest_revived_packet);
}
+TEST_F(QuicReceivedPacketManagerTest, RevivedPacketAckFrameUpdated) {
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
+ RecordPacketReceipt(1, 0);
+ RecordPacketReceipt(3, 0);
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
+
+ QuicAckFrame ack;
+ received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
+ EXPECT_EQ(1u, ack.missing_packets.NumPacketsSlow());
+ EXPECT_EQ(2u, ack.missing_packets.Min());
+ EXPECT_EQ(0u, ack.latest_revived_packet);
+
+ RecordPacketRevived(2);
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
+ received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
+ EXPECT_EQ(1u, ack.missing_packets.NumPacketsSlow());
+ EXPECT_EQ(2u, ack.missing_packets.Min());
+ EXPECT_EQ(2u, ack.latest_revived_packet);
+}
} // namespace
} // namespace test
diff --git a/chromium/net/quic/quic_sent_entropy_manager.h b/chromium/net/quic/quic_sent_entropy_manager.h
index cf12c842f1a..9ea900562ea 100644
--- a/chromium/net/quic/quic_sent_entropy_manager.h
+++ b/chromium/net/quic/quic_sent_entropy_manager.h
@@ -10,6 +10,7 @@
#include <deque>
+#include "base/macros.h"
#include "net/base/linked_hash_map.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
diff --git a/chromium/net/quic/quic_sent_entropy_manager_test.cc b/chromium/net/quic/quic_sent_entropy_manager_test.cc
index 167e56b456b..a73185dcb0a 100644
--- a/chromium/net/quic/quic_sent_entropy_manager_test.cc
+++ b/chromium/net/quic/quic_sent_entropy_manager_test.cc
@@ -38,8 +38,8 @@ TEST_F(QuicSentEntropyManagerTest, SentEntropyHash) {
}
TEST_F(QuicSentEntropyManagerTest, IsValidEntropy) {
- QuicPacketEntropyHash entropies[10] =
- {12, 1, 33, 3, 32, 100, 28, 42, 22, 255};
+ QuicPacketEntropyHash entropies[10] = {12, 1, 33, 3, 32,
+ 100, 28, 42, 22, 255};
for (size_t i = 0; i < arraysize(entropies); ++i) {
entropy_manager_.RecordPacketEntropyHash(i + 1, entropies[i]);
}
@@ -56,13 +56,13 @@ TEST_F(QuicSentEntropyManagerTest, IsValidEntropy) {
}
}
- EXPECT_TRUE(entropy_manager_.IsValidEntropy(10, missing_packets,
- entropy_hash));
+ EXPECT_TRUE(
+ entropy_manager_.IsValidEntropy(10, missing_packets, entropy_hash));
}
TEST_F(QuicSentEntropyManagerTest, ClearEntropiesBefore) {
- QuicPacketEntropyHash entropies[10] =
- {12, 1, 33, 3, 32, 100, 28, 42, 22, 255};
+ QuicPacketEntropyHash entropies[10] = {12, 1, 33, 3, 32,
+ 100, 28, 42, 22, 255};
for (size_t i = 0; i < arraysize(entropies); ++i) {
entropy_manager_.RecordPacketEntropyHash(i + 1, entropies[i]);
@@ -81,8 +81,8 @@ TEST_F(QuicSentEntropyManagerTest, ClearEntropiesBefore) {
entropy_hash ^= entropies[i];
}
}
- EXPECT_TRUE(entropy_manager_.IsValidEntropy(10, missing_packets,
- entropy_hash));
+ EXPECT_TRUE(
+ entropy_manager_.IsValidEntropy(10, missing_packets, entropy_hash));
entropy_hash = 0;
for (size_t i = 0; i < arraysize(entropies); ++i) {
diff --git a/chromium/net/quic/quic_sent_packet_manager.cc b/chromium/net/quic/quic_sent_packet_manager.cc
index 4984f7064df..6b71c70f4db 100644
--- a/chromium/net/quic/quic_sent_packet_manager.cc
+++ b/chromium/net/quic/quic_sent_packet_manager.cc
@@ -11,7 +11,7 @@
#include "net/quic/congestion_control/pacing_sender.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/proto/cached_network_parameters.pb.h"
-#include "net/quic/quic_ack_notifier_manager.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_connection_stats.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils_chromium.h"
@@ -23,15 +23,15 @@ namespace net {
// The length of the recent min rtt window in seconds. Windowing is disabled for
// values less than or equal to 0.
-int32 FLAGS_quic_recent_min_rtt_window_s = 60;
+int32_t FLAGS_quic_recent_min_rtt_window_s = 60;
namespace {
-static const int64 kDefaultRetransmissionTimeMs = 500;
+static const int64_t kDefaultRetransmissionTimeMs = 500;
// TCP RFC calls for 1 second RTO however Linux differs from this default and
// define the minimum RTO to 200ms, we will use the same until we have data to
// support a higher or lower value.
-static const int64 kMinRetransmissionTimeMs = 200;
-static const int64 kMaxRetransmissionTimeMs = 60000;
+static const int64_t kMinRetransmissionTimeMs = 200;
+static const int64_t kMaxRetransmissionTimeMs = 60000;
// Maximum number of exponential backoffs used for RTO timeouts.
static const size_t kMaxRetransmissions = 10;
// Maximum number of packets retransmitted upon an RTO.
@@ -39,12 +39,12 @@ static const size_t kMaxRetransmissionsOnTimeout = 2;
// Ensure the handshake timer isnt't faster than 10ms.
// This limits the tenth retransmitted packet to 10s after the initial CHLO.
-static const int64 kMinHandshakeTimeoutMs = 10;
+static const int64_t kMinHandshakeTimeoutMs = 10;
// Sends up to two tail loss probes before firing an RTO,
// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
static const size_t kDefaultMaxTailLossProbes = 2;
-static const int64 kMinTailLossProbeTimeoutMs = 10;
+static const int64_t kMinTailLossProbeTimeoutMs = 10;
// Number of unpaced packets to send after quiescence.
static const size_t kInitialUnpacedBurst = 10;
@@ -54,7 +54,7 @@ bool HasCryptoHandshake(const TransmissionInfo& transmission_info) {
return false;
}
return transmission_info.retransmittable_frames->HasCryptoHandshake() ==
- IS_HANDSHAKE;
+ IS_HANDSHAKE;
}
} // namespace
@@ -64,19 +64,19 @@ bool HasCryptoHandshake(const TransmissionInfo& transmission_info) {
QuicSentPacketManager::QuicSentPacketManager(
Perspective perspective,
+ QuicPathId path_id,
const QuicClock* clock,
QuicConnectionStats* stats,
CongestionControlType congestion_control_type,
- LossDetectionType loss_type,
- bool is_secure)
- : unacked_packets_(&ack_notifier_manager_),
+ LossDetectionType loss_type)
+ : unacked_packets_(),
perspective_(perspective),
+ path_id_(path_id),
clock_(clock),
stats_(stats),
debug_delegate_(nullptr),
network_change_visitor_(nullptr),
- initial_congestion_window_(is_secure ? kInitialCongestionWindowSecure
- : kInitialCongestionWindowInsecure),
+ initial_congestion_window_(kInitialCongestionWindow),
send_algorithm_(
SendAlgorithmInterface::Create(clock,
&rtt_stats_,
@@ -96,10 +96,10 @@ QuicSentPacketManager::QuicSentPacketManager(
enable_half_rtt_tail_loss_probe_(false),
using_pacing_(false),
use_new_rto_(false),
- handshake_confirmed_(false) {}
+ handshake_confirmed_(false),
+ use_general_loss_algorithm_(FLAGS_quic_general_loss_algorithm) {}
-QuicSentPacketManager::~QuicSentPacketManager() {
-}
+QuicSentPacketManager::~QuicSentPacketManager() {}
void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
if (config.HasReceivedInitialRoundTripTimeUs() &&
@@ -120,8 +120,7 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
network_change_visitor_->OnRttChange();
}
// TODO(ianswett): BBR is currently a server only feature.
- if (FLAGS_quic_allow_bbr &&
- config.HasReceivedConnectionOptions() &&
+ if (FLAGS_quic_allow_bbr && config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) {
if (FLAGS_quic_recent_min_rtt_window_s > 0) {
rtt_stats_.set_recent_min_rtt_window(
@@ -144,7 +143,9 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
send_algorithm_.reset(SendAlgorithmInterface::Create(
clock_, &rtt_stats_, kCubicBytes, stats_, initial_congestion_window_));
}
- EnablePacing();
+ if (!FLAGS_quic_disable_pacing) {
+ EnablePacing();
+ }
if (config.HasClientSentConnectionOption(k1CON, perspective_)) {
send_algorithm_->SetNumEmulatedConnections(1);
@@ -188,7 +189,7 @@ void QuicSentPacketManager::ResumeConnectionState(
const CachedNetworkParameters& cached_network_params,
bool max_bandwidth_resumption) {
if (cached_network_params.has_min_rtt_ms()) {
- uint32 initial_rtt_us =
+ uint32_t initial_rtt_us =
kNumMicrosPerMilli * cached_network_params.min_rtt_ms();
rtt_stats_.set_initial_rtt_us(
max(kMinInitialRoundTripTimeUs,
@@ -225,19 +226,10 @@ void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame,
unacked_packets_.RemoveObsoletePackets();
sustained_bandwidth_recorder_.RecordEstimate(
- send_algorithm_->InRecovery(),
- send_algorithm_->InSlowStart(),
- send_algorithm_->BandwidthEstimate(),
- ack_receive_time,
- clock_->WallNow(),
+ send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
+ send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
rtt_stats_.smoothed_rtt());
- // If we have received a truncated ack, then we need to clear out some
- // previous transmissions to allow the peer to actually ACK new packets.
- if (ack_frame.is_truncated && !FLAGS_quic_disable_truncated_ack_handling) {
- unacked_packets_.ClearAllPreviousRetransmissions();
- }
-
// Anytime we are making forward progress and have a new RTT estimate, reset
// the backoff counters.
if (rtt_updated) {
@@ -277,7 +269,8 @@ void QuicSentPacketManager::UpdatePacketInformationReceivedByPeer(
}
void QuicSentPacketManager::MaybeInvokeCongestionEvent(
- bool rtt_updated, QuicByteCount bytes_in_flight) {
+ bool rtt_updated,
+ QuicByteCount bytes_in_flight) {
if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
return;
}
@@ -297,7 +290,7 @@ void QuicSentPacketManager::HandleAckForSentPackets(
QuicTime::Delta delta_largest_observed =
ack_frame.delta_time_largest_observed;
QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
- for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
+ for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin();
it != unacked_packets_.end(); ++it, ++packet_number) {
if (packet_number > ack_frame.largest_observed) {
// These packets are still in flight.
@@ -327,16 +320,14 @@ 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(std::make_pair(packet_number, *it));
+ packets_acked_.push_back(std::make_pair(packet_number, it->bytes_sent));
}
- MarkPacketHandled(packet_number, *it, delta_largest_observed);
+ MarkPacketHandled(packet_number, &(*it), delta_largest_observed);
}
// Discard any retransmittable frames associated with revived packets.
- for (PacketNumberSet::const_iterator revived_it =
- ack_frame.revived_packets.begin();
- revived_it != ack_frame.revived_packets.end(); ++revived_it) {
- MarkPacketRevived(*revived_it, delta_largest_observed);
+ if (ack_frame.latest_revived_packet != 0) {
+ MarkPacketRevived(ack_frame.latest_revived_packet, delta_largest_observed);
}
}
@@ -355,7 +346,7 @@ void QuicSentPacketManager::RetransmitUnackedPackets(
const RetransmittableFrames* frames = it->retransmittable_frames;
if (frames != nullptr &&
(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
- frames->encryption_level() == ENCRYPTION_INITIAL)) {
+ it->encryption_level == ENCRYPTION_INITIAL)) {
MarkForRetransmission(packet_number, retransmission_type);
} else if (it->is_fec_packet) {
// Remove FEC packets from the packet map, since we can't retransmit them.
@@ -368,8 +359,8 @@ void QuicSentPacketManager::NeuterUnencryptedPackets() {
QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
it != unacked_packets_.end(); ++it, ++packet_number) {
- const RetransmittableFrames* frames = it->retransmittable_frames;
- if (frames != nullptr && frames->encryption_level() == ENCRYPTION_NONE) {
+ if (it->retransmittable_frames != nullptr &&
+ it->encryption_level == ENCRYPTION_NONE) {
// Once you're forward secure, no unencrypted packets will be sent, crypto
// or otherwise. Unencrypted packets are neutered and abandoned, to ensure
// they are not retransmitted or considered lost from a congestion control
@@ -402,28 +393,45 @@ void QuicSentPacketManager::MarkForRetransmission(
pending_retransmissions_[packet_number] = transmission_type;
}
+void QuicSentPacketManager::RecordOneSpuriousRetransmission(
+ const TransmissionInfo& info) {
+ stats_->bytes_spuriously_retransmitted += info.bytes_sent;
+ ++stats_->packets_spuriously_retransmitted;
+ if (debug_delegate_ != nullptr) {
+ debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
+ info.bytes_sent);
+ }
+}
+
void QuicSentPacketManager::RecordSpuriousRetransmissions(
- const PacketNumberList& all_transmissions,
+ const TransmissionInfo& info,
QuicPacketNumber acked_packet_number) {
- for (PacketNumberList::const_reverse_iterator it = all_transmissions.rbegin();
- it != all_transmissions.rend() && *it > acked_packet_number; ++it) {
+ if (unacked_packets_.track_single_retransmission()) {
+ QuicPacketNumber retransmission = info.retransmission;
+ while (retransmission != 0) {
+ const TransmissionInfo& retransmit_info =
+ unacked_packets_.GetTransmissionInfo(retransmission);
+ retransmission = retransmit_info.retransmission;
+ RecordOneSpuriousRetransmission(retransmit_info);
+ }
+ return;
+ }
+ const PacketNumberList* all_transmissions = info.all_transmissions;
+ for (PacketNumberList::const_reverse_iterator it =
+ all_transmissions->rbegin();
+ it != all_transmissions->rend() && *it > acked_packet_number; ++it) {
// ianswett: Prevents crash in b/20552846.
if (*it < unacked_packets_.GetLeastUnacked() ||
*it > unacked_packets_.largest_sent_packet()) {
- LOG(DFATAL) << "Retransmission out of range:" << *it
- << " least unacked:" << unacked_packets_.GetLeastUnacked()
- << " largest sent:" << unacked_packets_.largest_sent_packet();
+ QUIC_BUG << "Retransmission out of range:" << *it
+ << " least unacked:" << unacked_packets_.GetLeastUnacked()
+ << " largest sent:" << unacked_packets_.largest_sent_packet();
return;
}
const TransmissionInfo& retransmit_info =
unacked_packets_.GetTransmissionInfo(*it);
- stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent;
- ++stats_->packets_spuriously_retransmitted;
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnSpuriousPacketRetransmission(
- retransmit_info.transmission_type, retransmit_info.bytes_sent);
- }
+ RecordOneSpuriousRetransmission(retransmit_info);
}
}
@@ -432,7 +440,7 @@ bool QuicSentPacketManager::HasPendingRetransmissions() const {
}
QuicSentPacketManager::PendingRetransmission
- QuicSentPacketManager::NextPendingRetransmission() {
+QuicSentPacketManager::NextPendingRetransmission() {
LOG_IF(DFATAL, pending_retransmissions_.empty())
<< "Unexpected call to PendingRetransmissions() with empty pending "
<< "retransmission list. Corrupted memory usage imminent.";
@@ -454,11 +462,30 @@ QuicSentPacketManager::PendingRetransmission
unacked_packets_.GetTransmissionInfo(packet_number);
DCHECK(transmission_info.retransmittable_frames);
- return PendingRetransmission(packet_number, transmission_type,
+ return PendingRetransmission(path_id_, packet_number, transmission_type,
*transmission_info.retransmittable_frames,
+ transmission_info.encryption_level,
transmission_info.packet_number_length);
}
+QuicPacketNumber QuicSentPacketManager::GetNewestRetransmission(
+ QuicPacketNumber packet_number,
+ const TransmissionInfo& transmission_info) const {
+ if (unacked_packets_.track_single_retransmission()) {
+ QuicPacketNumber retransmission = transmission_info.retransmission;
+ while (retransmission != 0) {
+ packet_number = retransmission;
+ retransmission =
+ unacked_packets_.GetTransmissionInfo(retransmission).retransmission;
+ }
+ return packet_number;
+ } else {
+ return transmission_info.all_transmissions == nullptr
+ ? packet_number
+ : *transmission_info.all_transmissions->rbegin();
+ }
+}
+
void QuicSentPacketManager::MarkPacketRevived(
QuicPacketNumber packet_number,
QuicTime::Delta delta_largest_observed) {
@@ -469,51 +496,52 @@ void QuicSentPacketManager::MarkPacketRevived(
const TransmissionInfo& transmission_info =
unacked_packets_.GetTransmissionInfo(packet_number);
QuicPacketNumber newest_transmission =
- transmission_info.all_transmissions == nullptr
- ? packet_number
- : *transmission_info.all_transmissions->rbegin();
+ GetNewestRetransmission(packet_number, transmission_info);
// This packet has been revived at the receiver. If we were going to
// retransmit it, do not retransmit it anymore.
pending_retransmissions_.erase(newest_transmission);
- // The AckNotifierManager needs to be notified for revived packets,
+ // The AckListener needs to be notified for revived packets,
// since it indicates the packet arrived from the appliction's perspective.
- ack_notifier_manager_.OnPacketAcked(newest_transmission,
- delta_largest_observed);
+ unacked_packets_.NotifyAndClearListeners(newest_transmission,
+ delta_largest_observed);
unacked_packets_.RemoveRetransmittability(packet_number);
}
void QuicSentPacketManager::MarkPacketHandled(
QuicPacketNumber packet_number,
- const TransmissionInfo& info,
+ TransmissionInfo* info,
QuicTime::Delta delta_largest_observed) {
QuicPacketNumber newest_transmission =
- info.all_transmissions == nullptr ? packet_number
- : *info.all_transmissions->rbegin();
+ GetNewestRetransmission(packet_number, *info);
// Remove the most recent packet, if it is pending retransmission.
pending_retransmissions_.erase(newest_transmission);
- // The AckNotifierManager needs to be notified about the most recent
+ // The AckListener needs to be notified about the most recent
// transmission, since that's the one only one it tracks.
- ack_notifier_manager_.OnPacketAcked(newest_transmission,
- delta_largest_observed);
- if (newest_transmission != packet_number) {
- RecordSpuriousRetransmissions(*info.all_transmissions, packet_number);
+ if (newest_transmission == packet_number) {
+ unacked_packets_.NotifyAndClearListeners(&info->ack_listeners,
+ delta_largest_observed);
+ } else {
+ unacked_packets_.NotifyAndClearListeners(newest_transmission,
+ delta_largest_observed);
+ RecordSpuriousRetransmissions(*info, packet_number);
// Remove the most recent packet from flight if it's a crypto handshake
// packet, since they won't be acked now that one has been processed.
// Other crypto handshake packets won't be in flight, only the newest
// transmission of a crypto packet is in flight at once.
// TODO(ianswett): Instead of handling all crypto packets special,
// only handle nullptr encrypted packets in a special way.
- if (HasCryptoHandshake(
- unacked_packets_.GetTransmissionInfo(newest_transmission))) {
+ const TransmissionInfo& newest_transmission_info =
+ unacked_packets_.GetTransmissionInfo(newest_transmission);
+ if (HasCryptoHandshake(newest_transmission_info)) {
unacked_packets_.RemoveFromInFlight(newest_transmission);
}
}
- unacked_packets_.RemoveFromInFlight(packet_number);
- unacked_packets_.RemoveRetransmittability(packet_number);
+ unacked_packets_.RemoveFromInFlight(info);
+ unacked_packets_.RemoveRetransmittability(info);
}
bool QuicSentPacketManager::IsUnacked(QuicPacketNumber packet_number) const {
@@ -541,19 +569,11 @@ bool QuicSentPacketManager::OnPacketSent(
LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets.";
if (original_packet_number != 0) {
- PendingRetransmissionMap::iterator it =
- pending_retransmissions_.find(original_packet_number);
- if (it != pending_retransmissions_.end()) {
- pending_retransmissions_.erase(it);
- } else {
- DLOG(DFATAL) << "Expected packet number to be in "
- << "pending_retransmissions_. packet_number: "
- << original_packet_number;
+ if (!pending_retransmissions_.erase(original_packet_number)) {
+ QUIC_BUG << "Expected packet number to be in "
+ << "pending_retransmissions_. packet_number: "
+ << original_packet_number;
}
- // Inform the ack notifier of retransmissions so it can calculate the
- // retransmit rate.
- ack_notifier_manager_.OnPacketRetransmitted(original_packet_number,
- packet_number, bytes);
}
if (pending_timer_transmission_count_ > 0) {
@@ -566,11 +586,12 @@ bool QuicSentPacketManager::OnPacketSent(
HasRetransmittableData has_congestion_controlled_data =
serialized_packet->is_fec_packet ? HAS_RETRANSMITTABLE_DATA
: has_retransmittable_data;
+ // TODO(ianswett): Remove sent_time, because it's unused.
const bool in_flight = send_algorithm_->OnPacketSent(
sent_time, unacked_packets_.bytes_in_flight(), packet_number, bytes,
has_congestion_controlled_data);
- unacked_packets_.AddSentPacket(*serialized_packet, original_packet_number,
+ unacked_packets_.AddSentPacket(serialized_packet, original_packet_number,
transmission_type, sent_time, bytes,
in_flight);
@@ -671,8 +692,12 @@ void QuicSentPacketManager::RetransmitRtoPackets() {
}
// Abandon non-retransmittable data that's in flight to ensure it doesn't
// fill up the congestion window.
+ const bool has_retransmissions =
+ unacked_packets_.track_single_retransmission()
+ ? it->retransmission != 0
+ : it->all_transmissions != nullptr;
if (it->retransmittable_frames == nullptr && it->in_flight &&
- it->all_transmissions == nullptr) {
+ !has_retransmissions) {
unacked_packets_.RemoveFromInFlight(packet_number);
}
}
@@ -685,7 +710,7 @@ void QuicSentPacketManager::RetransmitRtoPackets() {
}
QuicSentPacketManager::RetransmissionTimeoutMode
- QuicSentPacketManager::GetRetransmissionMode() const {
+QuicSentPacketManager::GetRetransmissionMode() const {
DCHECK(unacked_packets_.HasInFlightPackets());
if (!handshake_confirmed_ && unacked_packets_.HasPendingCryptoPackets()) {
return HANDSHAKE_MODE;
@@ -702,6 +727,25 @@ QuicSentPacketManager::RetransmissionTimeoutMode
}
void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
+ if (use_general_loss_algorithm_) {
+ loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
+ &packets_lost_);
+ for (const std::pair<QuicPacketNumber, QuicByteCount>& pair :
+ packets_lost_) {
+ ++stats_->packets_lost;
+ // TODO(ianswett): This could be optimized.
+ if (unacked_packets_.HasRetransmittableFrames(pair.first)) {
+ MarkForRetransmission(pair.first, LOSS_RETRANSMISSION);
+ } else {
+ // Since we will not retransmit this, we need to remove it from
+ // unacked_packets_. This is either the current transmission of
+ // a packet whose previous transmission has been acked, a packet that
+ // has been TLP retransmitted, or an FEC packet.
+ unacked_packets_.RemoveFromInFlight(pair.first);
+ }
+ }
+ return;
+ }
PacketNumberSet lost_packets = loss_algorithm_->DetectLostPackets(
unacked_packets_, time, unacked_packets_.largest_observed(), rtt_stats_);
for (PacketNumberSet::const_iterator it = lost_packets.begin();
@@ -713,7 +757,8 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
// should be recorded as a loss to the send algorithm, but not retransmitted
// until it's known whether the FEC packet arrived.
++stats_->packets_lost;
- packets_lost_.push_back(std::make_pair(packet_number, transmission_info));
+ packets_lost_.push_back(
+ std::make_pair(packet_number, transmission_info.bytes_sent));
DVLOG(1) << ENDPOINT << "Lost packet " << packet_number;
if (transmission_info.retransmittable_frames != nullptr) {
@@ -728,9 +773,8 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
}
}
-bool QuicSentPacketManager::MaybeUpdateRTT(
- const QuicAckFrame& ack_frame,
- const QuicTime& ack_receive_time) {
+bool QuicSentPacketManager::MaybeUpdateRTT(const QuicAckFrame& ack_frame,
+ const QuicTime& ack_receive_time) {
// We rely on delta_time_largest_observed to compute an RTT estimate, so we
// only update rtt when the largest observed gets acked.
// NOTE: If ack is a truncated ack, then the largest observed is in fact
@@ -744,15 +788,15 @@ bool QuicSentPacketManager::MaybeUpdateRTT(
unacked_packets_.GetTransmissionInfo(ack_frame.largest_observed);
// Ensure the packet has a valid sent time.
if (transmission_info.sent_time == QuicTime::Zero()) {
- LOG(DFATAL) << "Acked packet has zero sent time, largest_observed:"
- << ack_frame.largest_observed;
+ QUIC_BUG << "Acked packet has zero sent time, largest_observed:"
+ << ack_frame.largest_observed;
return false;
}
QuicTime::Delta send_delta =
ack_receive_time.Subtract(transmission_info.sent_time);
- rtt_stats_.UpdateRtt(
- send_delta, ack_frame.delta_time_largest_observed, ack_receive_time);
+ rtt_stats_.UpdateRtt(send_delta, ack_frame.delta_time_largest_observed,
+ ack_receive_time);
if (network_change_visitor_ != nullptr) {
network_change_visitor_->OnRttChange();
@@ -769,8 +813,8 @@ QuicTime::Delta QuicSentPacketManager::TimeUntilSend(
if (pending_timer_transmission_count_ > 0) {
return QuicTime::Delta::Zero();
}
- return send_algorithm_->TimeUntilSend(
- now, unacked_packets_.bytes_in_flight(), retransmittable);
+ return send_algorithm_->TimeUntilSend(now, unacked_packets_.bytes_in_flight(),
+ retransmittable);
}
// Uses a 25ms delayed ack timer. Also helps with better signaling
@@ -788,8 +832,8 @@ QuicTime::Delta QuicSentPacketManager::TimeUntilSend(
// any benefits, but if the delayed ack becomes a significant source
// of (likely, tail) latency, then consider such a mechanism.
const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const {
- return QuicTime::Delta::FromMilliseconds(min(kMaxDelayedAckTimeMs,
- kMinRetransmissionTimeMs / 2));
+ return QuicTime::Delta::FromMilliseconds(
+ min(kMaxDelayedAckTimeMs, kMinRetransmissionTimeMs / 2));
}
const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
@@ -835,8 +879,8 @@ const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
if (srtt.IsZero()) {
srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us());
}
- int64 delay_ms = max(kMinHandshakeTimeoutMs,
- static_cast<int64>(1.5 * srtt.ToMilliseconds()));
+ int64_t delay_ms = max(kMinHandshakeTimeoutMs,
+ static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
return QuicTime::Delta::FromMilliseconds(
delay_ms << consecutive_crypto_retransmission_count_);
}
@@ -849,16 +893,17 @@ const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) {
return QuicTime::Delta::FromMilliseconds(
max(kMinTailLossProbeTimeoutMs,
- static_cast<int64>(0.5 * srtt.ToMilliseconds())));
+ static_cast<int64_t>(0.5 * srtt.ToMilliseconds())));
}
if (!unacked_packets_.HasMultipleInFlightPackets()) {
return QuicTime::Delta::Max(
- srtt.Multiply(2), srtt.Multiply(1.5).Add(
+ srtt.Multiply(2),
+ srtt.Multiply(1.5).Add(
QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs / 2)));
}
return QuicTime::Delta::FromMilliseconds(
max(kMinTailLossProbeTimeoutMs,
- static_cast<int64>(2 * srtt.ToMilliseconds())));
+ static_cast<int64_t>(2 * srtt.ToMilliseconds())));
}
const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
@@ -914,11 +959,6 @@ QuicPacketCount QuicSentPacketManager::GetSlowStartThresholdInTcpMss() const {
return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS;
}
-void QuicSentPacketManager::OnSerializedPacket(
- const SerializedPacket& serialized_packet) {
- ack_notifier_manager_.OnSerializedPacket(serialized_packet);
-}
-
void QuicSentPacketManager::CancelRetransmissionsForStream(
QuicStreamId stream_id) {
unacked_packets_.CancelRetransmissionsForStream(stream_id);
@@ -942,10 +982,24 @@ void QuicSentPacketManager::EnablePacing() {
// Set up a pacing sender with a 1 millisecond alarm granularity, the same as
// the default granularity of the Linux kernel's FQ qdisc.
using_pacing_ = true;
- send_algorithm_.reset(
- new PacingSender(send_algorithm_.release(),
- QuicTime::Delta::FromMilliseconds(1),
- kInitialUnpacedBurst));
+ send_algorithm_.reset(new PacingSender(send_algorithm_.release(),
+ QuicTime::Delta::FromMilliseconds(1),
+ kInitialUnpacedBurst));
+}
+
+void QuicSentPacketManager::OnConnectionMigration(PeerAddressChangeType type) {
+ if (type == UNKNOWN) {
+ return;
+ }
+
+ if (type == NAT_PORT_REBINDING || type == IPV4_SUBNET_REBINDING) {
+ // Rtt and cwnd do not need to be reset when the peer address change is
+ // considered to be caused by NATs.
+ return;
+ }
+
+ rtt_stats_.OnConnectionMigration();
+ send_algorithm_->OnConnectionMigration();
}
} // namespace net
diff --git a/chromium/net/quic/quic_sent_packet_manager.h b/chromium/net/quic/quic_sent_packet_manager.h
index d9f46960983..87dedbcad14 100644
--- a/chromium/net/quic/quic_sent_packet_manager.h
+++ b/chromium/net/quic/quic_sent_packet_manager.h
@@ -5,18 +5,20 @@
#ifndef NET_QUIC_QUIC_SENT_PACKET_MANAGER_H_
#define NET_QUIC_QUIC_SENT_PACKET_MANAGER_H_
+#include <stddef.h>
+
#include <map>
#include <set>
#include <utility>
#include <vector>
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/linked_hash_map.h"
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/congestion_control/rtt_stats.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
-#include "net/quic/quic_ack_notifier_manager.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_sustained_bandwidth_recorder.h"
#include "net/quic/quic_unacked_packet_map.h"
@@ -75,27 +77,33 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// Struct to store the pending retransmission information.
struct PendingRetransmission {
- PendingRetransmission(QuicPacketNumber packet_number,
+ PendingRetransmission(QuicPathId path_id,
+ QuicPacketNumber packet_number,
TransmissionType transmission_type,
const RetransmittableFrames& retransmittable_frames,
+ EncryptionLevel encryption_level,
QuicPacketNumberLength packet_number_length)
- : packet_number(packet_number),
+ : path_id(path_id),
+ packet_number(packet_number),
transmission_type(transmission_type),
retransmittable_frames(retransmittable_frames),
+ encryption_level(encryption_level),
packet_number_length(packet_number_length) {}
+ QuicPathId path_id;
QuicPacketNumber packet_number;
TransmissionType transmission_type;
const RetransmittableFrames& retransmittable_frames;
+ EncryptionLevel encryption_level;
QuicPacketNumberLength packet_number_length;
};
QuicSentPacketManager(Perspective perspective,
+ QuicPathId path_id,
const QuicClock* clock,
QuicConnectionStats* stats,
CongestionControlType congestion_control_type,
- LossDetectionType loss_type,
- bool is_secure);
+ LossDetectionType loss_type);
virtual ~QuicSentPacketManager();
virtual void SetFromConfig(const QuicConfig& config);
@@ -110,8 +118,7 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
void SetHandshakeConfirmed() { handshake_confirmed_ = true; }
// Processes the incoming ack.
- void OnIncomingAck(const QuicAckFrame& ack_frame,
- QuicTime ack_receive_time);
+ void OnIncomingAck(const QuicAckFrame& ack_frame, QuicTime ack_receive_time);
// Returns true if the non-FEC packet |packet_number| is unacked.
bool IsUnacked(QuicPacketNumber packet_number) const;
@@ -209,15 +216,15 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// start threshold and will return 0.
QuicPacketCount GetSlowStartThresholdInTcpMss() const;
- // Called by the connection every time it receives a serialized packet.
- void OnSerializedPacket(const SerializedPacket& serialized_packet);
-
// No longer retransmit data for |stream_id|.
void CancelRetransmissionsForStream(QuicStreamId stream_id);
// Enables pacing if it has not already been enabled.
void EnablePacing();
+ // Called when peer address changes and the connection migrates.
+ void OnConnectionMigration(PeerAddressChangeType type);
+
bool using_pacing() const { return using_pacing_; }
void set_debug_delegate(DebugDelegate* debug_delegate) {
@@ -243,14 +250,10 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
}
// Used in Chromium, but not in the server.
- size_t consecutive_rto_count() const {
- return consecutive_rto_count_;
- }
+ size_t consecutive_rto_count() const { return consecutive_rto_count_; }
// Used in Chromium, but not in the server.
- size_t consecutive_tlp_count() const {
- return consecutive_tlp_count_;
- }
+ size_t consecutive_tlp_count() const { return consecutive_tlp_count_; }
private:
friend class test::QuicConnectionPeer;
@@ -298,6 +301,11 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// Returns the retransmission timeout, after which a full RTO occurs.
const QuicTime::Delta GetRetransmissionDelay() const;
+ // Returns the newest transmission associated with a packet.
+ QuicPacketNumber GetNewestRetransmission(
+ QuicPacketNumber packet_number,
+ const TransmissionInfo& transmission_info) const;
+
// 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,
@@ -320,11 +328,10 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
void MarkPacketRevived(QuicPacketNumber packet_number,
QuicTime::Delta delta_largest_observed);
- // Removes the retransmittability and pending properties from the packet at
- // |it| due to receipt by the peer. Returns an iterator to the next remaining
- // unacked packet.
+ // Removes the retransmittability and in flight properties from the packet at
+ // |info| due to receipt by the peer.
void MarkPacketHandled(QuicPacketNumber packet_number,
- const TransmissionInfo& info,
+ TransmissionInfo* info,
QuicTime::Delta delta_largest_observed);
// Request that |packet_number| be retransmitted after the other pending
@@ -333,8 +340,15 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
void MarkForRetransmission(QuicPacketNumber packet_number,
TransmissionType transmission_type);
- // Notify observers about spurious retransmits.
- void RecordSpuriousRetransmissions(const PacketNumberList& all_transmissions,
+ // Notify observers that packet with TransmissionInfo |info| is a spurious
+ // retransmission. It is caller's responsibility to guarantee the packet with
+ // TransmissionInfo |info| is a spurious retransmission before calling this
+ // function.
+ void RecordOneSpuriousRetransmission(const TransmissionInfo& info);
+
+ // Notify observers about spurious retransmits of packet with TransmissionInfo
+ // |info|.
+ void RecordSpuriousRetransmissions(const TransmissionInfo& info,
QuicPacketNumber acked_packet_number);
// Newly serialized retransmittable and fec packets are added to this map,
@@ -353,10 +367,7 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// Tracks if the connection was created by the server or the client.
Perspective perspective_;
- // An AckNotifier can register to be informed when ACKs have been received for
- // all packets that a given block of data was sent in. The AckNotifierManager
- // maintains the currently active notifiers.
- AckNotifierManager ack_notifier_manager_;
+ QuicPathId path_id_;
const QuicClock* clock_;
QuicConnectionStats* stats_;
@@ -404,6 +415,9 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// retransmittable frames.
bool handshake_confirmed_;
+ // Latched value of FLAGS_gfe2_reloadable_flag_quic_general_loss_algorithm.
+ const bool use_general_loss_algorithm_;
+
// Records bandwidth from server to client in normal operation, over periods
// of time with no loss events.
QuicSustainedBandwidthRecorder sustained_bandwidth_recorder_;
diff --git a/chromium/net/quic/quic_sent_packet_manager_test.cc b/chromium/net/quic/quic_sent_packet_manager_test.cc
index b057a1dc079..719137ce4ae 100644
--- a/chromium/net/quic/quic_sent_packet_manager_test.cc
+++ b/chromium/net/quic/quic_sent_packet_manager_test.cc
@@ -28,7 +28,7 @@ namespace test {
namespace {
// Default packet length.
-const uint32 kDefaultLength = 1000;
+const uint32_t kDefaultLength = 1000;
// Stream ID for data sent in CreatePacket().
const QuicStreamId kStreamId = 7;
@@ -49,9 +49,18 @@ class MockDebugDelegate : public QuicSentPacketManager::DebugDelegate {
class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
protected:
QuicSentPacketManagerTest()
- : manager_(Perspective::IS_SERVER, &clock_, &stats_, kCubic, kNack, true),
+ : manager_(Perspective::IS_SERVER,
+ kDefaultPathId,
+ &clock_,
+ &stats_,
+ kCubic,
+ kNack),
send_algorithm_(new StrictMock<MockSendAlgorithm>),
network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
+ // These tests only work with pacing enabled.
+ saved_FLAGS_quic_disable_pacing_ = FLAGS_quic_disable_pacing;
+ FLAGS_quic_disable_pacing = false;
+
QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
// Disable tail loss probes for most tests.
QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
@@ -68,7 +77,10 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
}
- ~QuicSentPacketManagerTest() override { STLDeleteElements(&packets_); }
+ ~QuicSentPacketManagerTest() override {
+ STLDeleteElements(&packets_);
+ FLAGS_quic_disable_pacing = saved_FLAGS_quic_disable_pacing_;
+ }
QuicByteCount BytesInFlight() {
return QuicSentPacketManagerPeer::GetBytesInFlight(&manager_);
@@ -77,7 +89,7 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
if (num_packets == 0) {
EXPECT_FALSE(manager_.HasUnackedPackets());
EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
- &manager_));
+ &manager_));
return;
}
@@ -90,9 +102,9 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
void VerifyRetransmittablePackets(QuicPacketNumber* packets,
size_t num_packets) {
- EXPECT_EQ(num_packets,
- QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
- &manager_));
+ EXPECT_EQ(
+ num_packets,
+ QuicSentPacketManagerPeer::GetNumRetransmittablePackets(&manager_));
for (size_t i = 0; i < num_packets; ++i) {
EXPECT_TRUE(manager_.HasRetransmittableFrames(packets[i]))
<< " packets[" << i << "]:" << packets[i];
@@ -100,8 +112,10 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
}
void ExpectAck(QuicPacketNumber largest_observed) {
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(
- true, _, ElementsAre(Pair(largest_observed, _)), IsEmpty()));
+ EXPECT_CALL(
+ *send_algorithm_,
+ OnCongestionEvent(true, _, ElementsAre(Pair(largest_observed, _)),
+ IsEmpty()));
EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
EXPECT_CALL(*network_change_visitor_, OnRttChange());
}
@@ -116,9 +130,10 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
void ExpectAckAndLoss(bool rtt_updated,
QuicPacketNumber largest_observed,
QuicPacketNumber lost_packet) {
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(
- rtt_updated, _, ElementsAre(Pair(largest_observed, _)),
- ElementsAre(Pair(lost_packet, _))));
+ EXPECT_CALL(*send_algorithm_,
+ OnCongestionEvent(rtt_updated, _,
+ ElementsAre(Pair(largest_observed, _)),
+ ElementsAre(Pair(lost_packet, _))));
EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
EXPECT_CALL(*network_change_visitor_, OnRttChange());
}
@@ -137,12 +152,12 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
for (size_t i = 0; i < num_packets_lost; ++i) {
lost_vector.push_back(packets_lost[i]);
}
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(rtt_updated, _,
- Pointwise(KeyEq(), ack_vector),
- Pointwise(KeyEq(), lost_vector)));
- EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange()).
- Times(AnyNumber());
+ EXPECT_CALL(
+ *send_algorithm_,
+ OnCongestionEvent(rtt_updated, _, Pointwise(KeyEq(), ack_vector),
+ Pointwise(KeyEq(), lost_vector)));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange())
+ .Times(AnyNumber());
EXPECT_CALL(*network_change_visitor_, OnRttChange()).Times(AnyNumber());
}
@@ -154,8 +169,7 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
QuicSentPacketManager::PendingRetransmission next_retransmission =
manager_.NextPendingRetransmission();
EXPECT_EQ(old_packet_number, next_retransmission.packet_number);
- EXPECT_EQ(TLP_RETRANSMISSION,
- next_retransmission.transmission_type);
+ EXPECT_EQ(TLP_RETRANSMISSION, next_retransmission.transmission_type);
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, BytesInFlight(), new_packet_number,
@@ -178,18 +192,20 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
RetransmittableFrames* frames = nullptr;
if (retransmittable) {
- frames = new RetransmittableFrames(ENCRYPTION_NONE);
+ frames = new RetransmittableFrames();
frames->AddFrame(
QuicFrame(new QuicStreamFrame(kStreamId, false, 0, StringPiece())));
}
- return SerializedPacket(packet_number, PACKET_6BYTE_PACKET_NUMBER,
- packets_.back(), 0u, frames, false, false);
+ return SerializedPacket(kDefaultPathId, packet_number,
+ PACKET_6BYTE_PACKET_NUMBER, packets_.back(), 0u,
+ frames, false, false);
}
SerializedPacket CreateFecPacket(QuicPacketNumber packet_number) {
packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
- SerializedPacket serialized(packet_number, PACKET_6BYTE_PACKET_NUMBER,
- packets_.back(), 0u, nullptr, false, false);
+ SerializedPacket serialized(kDefaultPathId, packet_number,
+ PACKET_6BYTE_PACKET_NUMBER, packets_.back(), 0u,
+ nullptr, false, false);
serialized.is_fec_packet = true;
return serialized;
}
@@ -200,9 +216,8 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
.Times(1)
.WillOnce(Return(true));
SerializedPacket packet(CreateDataPacket(packet_number));
- manager_.OnPacketSent(&packet, 0, clock_.Now(),
- packet.packet->length(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA);
+ manager_.OnPacketSent(&packet, 0, clock_.Now(), packet.packet->length(),
+ NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
}
void SendCryptoPacket(QuicPacketNumber packet_number) {
@@ -214,9 +229,8 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
SerializedPacket packet(CreateDataPacket(packet_number));
packet.retransmittable_frames->AddFrame(
QuicFrame(new QuicStreamFrame(1, false, 0, StringPiece())));
- manager_.OnPacketSent(&packet, 0, clock_.Now(),
- packet.packet->length(), NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA);
+ manager_.OnPacketSent(&packet, 0, clock_.Now(), packet.packet->length(),
+ NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
}
void SendFecPacket(QuicPacketNumber packet_number) {
@@ -226,9 +240,8 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
.Times(1)
.WillOnce(Return(true));
SerializedPacket packet(CreateFecPacket(packet_number));
- manager_.OnPacketSent(&packet, 0, clock_.Now(),
- packet.packet->length(), NOT_RETRANSMISSION,
- NO_RETRANSMITTABLE_DATA);
+ manager_.OnPacketSent(&packet, 0, clock_.Now(), packet.packet->length(),
+ NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA);
}
void SendAckPacket(QuicPacketNumber packet_number) {
@@ -238,9 +251,8 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
.Times(1)
.WillOnce(Return(false));
SerializedPacket packet(CreatePacket(packet_number, false));
- manager_.OnPacketSent(&packet, 0, clock_.Now(),
- packet.packet->length(), NOT_RETRANSMISSION,
- NO_RETRANSMITTABLE_DATA);
+ manager_.OnPacketSent(&packet, 0, clock_.Now(), packet.packet->length(),
+ NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA);
}
// Based on QuicConnection's WritePendingRetransmissions.
@@ -265,6 +277,7 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
QuicConnectionStats stats_;
MockSendAlgorithm* send_algorithm_;
scoped_ptr<MockNetworkChangeVisitor> network_change_visitor_;
+ bool saved_FLAGS_quic_disable_pacing_;
};
TEST_F(QuicSentPacketManagerTest, IsUnacked) {
@@ -308,8 +321,8 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
SendDataPacket(1);
- QuicSentPacketManagerPeer::MarkForRetransmission(
- &manager_, 1, TLP_RETRANSMISSION);
+ QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
+ TLP_RETRANSMISSION);
EXPECT_TRUE(manager_.HasPendingRetransmissions());
// Ack 1.
@@ -439,8 +452,9 @@ TEST_F(QuicSentPacketManagerTest,
TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
StrictMock<MockDebugDelegate> debug_delegate;
- EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(
- TLP_RETRANSMISSION, kDefaultLength)).Times(2);
+ EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(TLP_RETRANSMISSION,
+ kDefaultLength))
+ .Times(2);
manager_.set_debug_delegate(&debug_delegate);
SendDataPacket(1);
@@ -493,7 +507,7 @@ TEST_F(QuicSentPacketManagerTest, LoseButDontRetransmitRevivedPacket) {
QuicAckFrame ack_frame;
ack_frame.largest_observed = 3;
ack_frame.missing_packets.Add(1);
- ack_frame.revived_packets.insert(1);
+ ack_frame.latest_revived_packet = 1;
QuicPacketNumber acked[] = {2, 3};
ExpectAcksAndLosses(true, acked, arraysize(acked), nullptr, 0);
manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
@@ -539,7 +553,7 @@ TEST_F(QuicSentPacketManagerTest, MarkLostThenReviveAndDontRetransmitPacket) {
// Ack 5th packet (FEC) and revive 1st packet. 1st packet should now be
// removed from pending retransmissions map.
ack_frame.largest_observed = 5;
- ack_frame.revived_packets.insert(1);
+ ack_frame.latest_revived_packet = 1;
ExpectAck(5);
manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
@@ -547,32 +561,6 @@ TEST_F(QuicSentPacketManagerTest, MarkLostThenReviveAndDontRetransmitPacket) {
VerifyRetransmittablePackets(nullptr, 0);
}
-TEST_F(QuicSentPacketManagerTest, TruncatedAck) {
- ValueRestore<bool> old_flag(&FLAGS_quic_disable_truncated_ack_handling,
- false);
- SendDataPacket(1);
- RetransmitAndSendPacket(1, 2);
- RetransmitAndSendPacket(2, 3);
- RetransmitAndSendPacket(3, 4);
- RetransmitAndSendPacket(4, 5);
-
- // Truncated ack with 4 NACKs, so the first packet is lost.
- QuicAckFrame ack_frame;
- ack_frame.largest_observed = 4;
- ack_frame.missing_packets.Add(1, 5);
- ack_frame.is_truncated = true;
-
- QuicPacketNumber lost[] = {1};
- ExpectAcksAndLosses(true, nullptr, 0, lost, arraysize(lost));
- manager_.OnIncomingAck(ack_frame, clock_.Now());
-
- // High water mark will be raised.
- QuicPacketNumber unacked[] = {2, 3, 4, 5};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- QuicPacketNumber retransmittable[] = {5};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
-}
-
TEST_F(QuicSentPacketManagerTest, AckPreviousTransmissionThenTruncatedAck) {
SendDataPacket(1);
RetransmitAndSendPacket(1, 2);
@@ -674,8 +662,7 @@ TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
// Now ack the ack and expect an RTT update.
QuicAckFrame ack_frame;
ack_frame.largest_observed = 2;
- ack_frame.delta_time_largest_observed =
- QuicTime::Delta::FromMilliseconds(5);
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::FromMilliseconds(5);
ExpectAck(1);
manager_.OnIncomingAck(ack_frame, clock_.Now());
@@ -697,8 +684,7 @@ TEST_F(QuicSentPacketManagerTest, Rtt) {
ExpectAck(packet_number);
QuicAckFrame ack_frame;
ack_frame.largest_observed = packet_number;
- ack_frame.delta_time_largest_observed =
- QuicTime::Delta::FromMilliseconds(5);
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::FromMilliseconds(5);
manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(expected_rtt,
QuicSentPacketManagerPeer::GetRttStats(&manager_)->latest_rtt());
@@ -716,8 +702,7 @@ TEST_F(QuicSentPacketManagerTest, RttWithInvalidDelta) {
ExpectAck(packet_number);
QuicAckFrame ack_frame;
ack_frame.largest_observed = packet_number;
- ack_frame.delta_time_largest_observed =
- QuicTime::Delta::FromMilliseconds(11);
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::FromMilliseconds(11);
manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(expected_rtt,
QuicSentPacketManagerPeer::GetRttStats(&manager_)->latest_rtt());
@@ -782,8 +767,8 @@ TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) {
manager_.MaybeRetransmitTailLossProbe();
EXPECT_TRUE(manager_.HasPendingRetransmissions());
RetransmitNextPacket(3);
- EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Infinite()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Infinite()));
EXPECT_EQ(QuicTime::Delta::Infinite(),
manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -829,8 +814,8 @@ TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
manager_.MaybeRetransmitTailLossProbe();
EXPECT_TRUE(manager_.HasPendingRetransmissions());
RetransmitNextPacket(101);
- EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Infinite()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Infinite()));
EXPECT_EQ(QuicTime::Delta::Infinite(),
manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -844,8 +829,8 @@ TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
EXPECT_TRUE(manager_.HasPendingRetransmissions());
RetransmitNextPacket(102);
- EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Infinite()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Infinite()));
EXPECT_EQ(QuicTime::Delta::Infinite(),
manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
@@ -962,7 +947,22 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutVersionNegotiation) {
RetransmitNextPacket(12);
EXPECT_FALSE(manager_.HasPendingRetransmissions());
- EXPECT_EQ(8u, manager_.GetLeastUnacked());
+ if (!FLAGS_quic_track_single_retransmission) {
+ EXPECT_EQ(8u, manager_.GetLeastUnacked());
+ return;
+ }
+ EXPECT_EQ(1u, manager_.GetLeastUnacked());
+ // Least unacked isn't raised until an ack is received, so ack the
+ // crypto packets.
+ QuicPacketNumber acked[] = {8, 9};
+ ExpectAcksAndLosses(true, acked, arraysize(acked), nullptr, 0);
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 9;
+ for (QuicPacketNumber i = 1; i < 8; ++i) {
+ ack_frame.missing_packets.Add(i);
+ }
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_EQ(10u, manager_.GetLeastUnacked());
}
TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
@@ -1263,8 +1263,8 @@ TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
EXPECT_TRUE(manager_.HasPendingRetransmissions());
RetransmitNextPacket(3);
- EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Infinite()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Infinite()));
EXPECT_EQ(QuicTime::Delta::Infinite(),
manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -1274,10 +1274,9 @@ TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
}
TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
- QuicSentPacketManagerPeer::GetRttStats(&manager_)->UpdateRtt(
- QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(),
- QuicTime::Zero());
+ QuicSentPacketManagerPeer::GetRttStats(&manager_)
+ ->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
SendDataPacket(1);
SendDataPacket(2);
@@ -1383,8 +1382,12 @@ TEST_F(QuicSentPacketManagerTest, GetLossDelay) {
// Handle an ack which causes the loss algorithm to be evaluated and
// set the loss timeout.
ExpectAck(2);
- EXPECT_CALL(*loss_algorithm, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
QuicAckFrame ack_frame;
ack_frame.largest_observed = 2;
ack_frame.missing_packets.Add(1);
@@ -1397,15 +1400,18 @@ TEST_F(QuicSentPacketManagerTest, GetLossDelay) {
// Fire the retransmission timeout and ensure the loss detection algorithm
// is invoked.
- EXPECT_CALL(*loss_algorithm, DetectLostPackets(_, _, _, _))
- .WillOnce(Return(PacketNumberSet()));
+ if (FLAGS_quic_general_loss_algorithm) {
+ EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _));
+ } else {
+ EXPECT_CALL(*loss_algorithm, DetectLostPackets(_, _, _, _))
+ .WillOnce(Return(PacketNumberSet()));
+ }
manager_.OnRetransmissionTimeout();
}
TEST_F(QuicSentPacketManagerTest, NegotiateTimeLossDetectionFromOptions) {
- EXPECT_EQ(kNack,
- QuicSentPacketManagerPeer::GetLossAlgorithm(
- &manager_)->GetLossDetectionType());
+ EXPECT_EQ(kNack, QuicSentPacketManagerPeer::GetLossAlgorithm(&manager_)
+ ->GetLossDetectionType());
QuicConfig config;
QuicTagVector options;
@@ -1416,9 +1422,8 @@ TEST_F(QuicSentPacketManagerTest, NegotiateTimeLossDetectionFromOptions) {
EXPECT_CALL(*network_change_visitor_, OnRttChange());
manager_.SetFromConfig(config);
- EXPECT_EQ(kTime,
- QuicSentPacketManagerPeer::GetLossAlgorithm(
- &manager_)->GetLossDetectionType());
+ EXPECT_EQ(kTime, QuicSentPacketManagerPeer::GetLossAlgorithm(&manager_)
+ ->GetLossDetectionType());
}
TEST_F(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
@@ -1431,10 +1436,10 @@ TEST_F(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
EXPECT_CALL(*network_change_visitor_, OnRttChange());
manager_.SetFromConfig(config);
- EXPECT_EQ(kReno, QuicSentPacketManagerPeer::GetSendAlgorithm(
- manager_)->GetCongestionControlType());
+ EXPECT_EQ(kReno, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+ ->GetCongestionControlType());
- // TODO(rtenneti): Enable the following code after BBR code is checked in.
+// TODO(rtenneti): Enable the following code after BBR code is checked in.
#if 0
options.clear();
options.push_back(kTBBR);
@@ -1638,8 +1643,8 @@ TEST_F(QuicSentPacketManagerTest, ReceiveWindowLimited) {
// Ensure the smaller send window only allows 256 * 0.95 packets to be sent.
for (QuicPacketNumber i = 1; i <= 244; ++i) {
- EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Zero()));
EXPECT_EQ(QuicTime::Delta::Zero(),
manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, BytesInFlight(), i, 1024,
@@ -1656,7 +1661,7 @@ TEST_F(QuicSentPacketManagerTest, ReceiveWindowLimited) {
}
TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {
- uint32 initial_rtt_us = 325000;
+ uint32_t initial_rtt_us = 325000;
EXPECT_NE(initial_rtt_us,
manager_.GetRttStats()->smoothed_rtt().ToMicroseconds());
@@ -1681,7 +1686,7 @@ TEST_F(QuicSentPacketManagerTest, ResumeConnectionState) {
EXPECT_CALL(*send_algorithm_, ResumeConnectionState(_, false));
manager_.ResumeConnectionState(cached_network_params, false);
EXPECT_EQ(kRttMs * kNumMicrosPerMilli,
- static_cast<uint64>(manager_.GetRttStats()->initial_rtt_us()));
+ static_cast<uint64_t>(manager_.GetRttStats()->initial_rtt_us()));
}
} // namespace
diff --git a/chromium/net/quic/quic_server_id.cc b/chromium/net/quic/quic_server_id.cc
index 15c9c5ce067..b810bb3745b 100644
--- a/chromium/net/quic/quic_server_id.cc
+++ b/chromium/net/quic/quic_server_id.cc
@@ -4,57 +4,56 @@
#include "net/quic/quic_server_id.h"
+#include <tuple>
+
+#include "base/logging.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/port_util.h"
+#include "url/gurl.h"
+
using std::string;
namespace net {
-QuicServerId::QuicServerId()
- : is_https_(false), privacy_mode_(PRIVACY_MODE_DISABLED) {
-}
+QuicServerId::QuicServerId() : privacy_mode_(PRIVACY_MODE_DISABLED) {}
QuicServerId::QuicServerId(const HostPortPair& host_port_pair,
- bool is_https,
PrivacyMode privacy_mode)
- : host_port_pair_(host_port_pair),
- is_https_(is_https),
- privacy_mode_(privacy_mode) {}
+ : host_port_pair_(host_port_pair), privacy_mode_(privacy_mode) {}
-QuicServerId::QuicServerId(const string& host,
- uint16 port,
- bool is_https)
- : host_port_pair_(host, port),
- is_https_(is_https),
- privacy_mode_(PRIVACY_MODE_DISABLED) {}
+QuicServerId::QuicServerId(const string& host, uint16_t port)
+ : host_port_pair_(host, port), privacy_mode_(PRIVACY_MODE_DISABLED) {}
QuicServerId::QuicServerId(const string& host,
- uint16 port,
- bool is_https,
+ uint16_t port,
PrivacyMode privacy_mode)
- : host_port_pair_(host, port),
- is_https_(is_https),
- privacy_mode_(privacy_mode) {}
+ : host_port_pair_(host, port), privacy_mode_(privacy_mode) {}
QuicServerId::~QuicServerId() {}
bool QuicServerId::operator<(const QuicServerId& other) const {
- if (!host_port_pair_.Equals(other.host_port_pair_)) {
- return host_port_pair_ < other.host_port_pair_;
- }
- if (is_https_ != other.is_https_) {
- return is_https_ < other.is_https_;
- }
- return privacy_mode_ < other.privacy_mode_;
+ return std::tie(host_port_pair_, privacy_mode_) <
+ std::tie(other.host_port_pair_, other.privacy_mode_);
}
bool QuicServerId::operator==(const QuicServerId& other) const {
- return is_https_ == other.is_https_ &&
- privacy_mode_ == other.privacy_mode_ &&
- host_port_pair_.Equals(other.host_port_pair_);
+ return privacy_mode_ == other.privacy_mode_ &&
+ host_port_pair_.Equals(other.host_port_pair_);
+}
+
+// static
+QuicServerId QuicServerId::FromString(const std::string& str) {
+ GURL url(str);
+ if (!url.is_valid())
+ return QuicServerId();
+ return QuicServerId(HostPortPair::FromURL(url), url.path() == "/private"
+ ? PRIVACY_MODE_ENABLED
+ : PRIVACY_MODE_DISABLED);
}
string QuicServerId::ToString() const {
- return (is_https_ ? "https://" : "http://") + host_port_pair_.ToString() +
- (privacy_mode_ == PRIVACY_MODE_ENABLED ? "/private" : "");
+ return "https://" + host_port_pair_.ToString() +
+ (privacy_mode_ == PRIVACY_MODE_ENABLED ? "/private" : "");
}
} // namespace net
diff --git a/chromium/net/quic/quic_server_id.h b/chromium/net/quic/quic_server_id.h
index 7236bfc88b8..97dbebbb49a 100644
--- a/chromium/net/quic/quic_server_id.h
+++ b/chromium/net/quic/quic_server_id.h
@@ -5,6 +5,8 @@
#ifndef NET_QUIC_QUIC_SERVER_ID_H_
#define NET_QUIC_QUIC_SERVER_ID_H_
+#include <stdint.h>
+
#include <string>
#include "net/base/host_port_pair.h"
@@ -18,15 +20,10 @@ namespace net {
class NET_EXPORT_PRIVATE QuicServerId {
public:
QuicServerId();
- QuicServerId(const HostPortPair& host_port_pair,
- bool is_https,
- PrivacyMode privacy_mode);
- QuicServerId(const std::string& host,
- uint16 port,
- bool is_https);
+ QuicServerId(const HostPortPair& host_port_pair, PrivacyMode privacy_mode);
+ QuicServerId(const std::string& host, uint16_t port);
QuicServerId(const std::string& host,
- uint16 port,
- bool is_https,
+ uint16_t port,
PrivacyMode privacy_mode);
~QuicServerId();
@@ -34,9 +31,12 @@ class NET_EXPORT_PRIVATE QuicServerId {
bool operator<(const QuicServerId& other) const;
bool operator==(const QuicServerId& other) const;
+ // Creates a QuicServerId from a string formatted in same manner as
+ // ToString().
+ static QuicServerId FromString(const std::string& str);
+
// ToString() will convert the QuicServerId to "scheme:hostname:port" or
- // "scheme:hostname:port/private". "scheme" would either be "http" or "https"
- // based on |is_https|.
+ // "scheme:hostname:port/private". "scheme" will be "https".
std::string ToString() const;
// Used in Chromium, but not in the server.
@@ -44,15 +44,12 @@ class NET_EXPORT_PRIVATE QuicServerId {
const std::string& host() const { return host_port_pair_.host(); }
- uint16 port() const { return host_port_pair_.port(); }
-
- bool is_https() const { return is_https_; }
+ uint16_t port() const { return host_port_pair_.port(); }
PrivacyMode privacy_mode() const { return privacy_mode_; }
private:
HostPortPair host_port_pair_;
- bool is_https_;
PrivacyMode privacy_mode_;
};
diff --git a/chromium/net/quic/quic_server_id_test.cc b/chromium/net/quic/quic_server_id_test.cc
index 1e08b30d50f..5c88067cd90 100644
--- a/chromium/net/quic/quic_server_id_test.cc
+++ b/chromium/net/quic/quic_server_id_test.cc
@@ -15,82 +15,35 @@ namespace {
TEST(QuicServerIdTest, ToString) {
HostPortPair google_host_port_pair("google.com", 10);
- QuicServerId google_http_server_id(google_host_port_pair, false,
- PRIVACY_MODE_DISABLED);
- string google_http_server_id_str = google_http_server_id.ToString();
- EXPECT_EQ("http://google.com:10", google_http_server_id_str);
+ QuicServerId google_server_id(google_host_port_pair, PRIVACY_MODE_DISABLED);
+ string google_server_id_str = google_server_id.ToString();
+ EXPECT_EQ("https://google.com:10", google_server_id_str);
- QuicServerId google_https_server_id(google_host_port_pair, true,
- PRIVACY_MODE_DISABLED);
- string google_https_server_id_str = google_https_server_id.ToString();
- EXPECT_EQ("https://google.com:10", google_https_server_id_str);
-
- QuicServerId private_http_server_id(google_host_port_pair, false,
- PRIVACY_MODE_ENABLED);
- string private_http_server_id_str = private_http_server_id.ToString();
- EXPECT_EQ("http://google.com:10/private", private_http_server_id_str);
-
- QuicServerId private_https_server_id(google_host_port_pair, true,
- PRIVACY_MODE_ENABLED);
- string private_https_server_id_str = private_https_server_id.ToString();
- EXPECT_EQ("https://google.com:10/private", private_https_server_id_str);
+ QuicServerId private_server_id(google_host_port_pair, PRIVACY_MODE_ENABLED);
+ string private_server_id_str = private_server_id.ToString();
+ EXPECT_EQ("https://google.com:10/private", private_server_id_str);
}
TEST(QuicServerIdTest, LessThan) {
- QuicServerId a_10_http(HostPortPair("a.com", 10), false,
- PRIVACY_MODE_DISABLED);
- QuicServerId a_10_https(HostPortPair("a.com", 10), true,
- PRIVACY_MODE_DISABLED);
- QuicServerId a_11_http(HostPortPair("a.com", 11), false,
- PRIVACY_MODE_DISABLED);
- QuicServerId a_11_https(HostPortPair("a.com", 11), true,
- PRIVACY_MODE_DISABLED);
- QuicServerId b_10_http(HostPortPair("b.com", 10), false,
- PRIVACY_MODE_DISABLED);
- QuicServerId b_10_https(HostPortPair("b.com", 10), true,
- PRIVACY_MODE_DISABLED);
- QuicServerId b_11_http(HostPortPair("b.com", 11), false,
- PRIVACY_MODE_DISABLED);
- QuicServerId b_11_https(HostPortPair("b.com", 11), true,
- PRIVACY_MODE_DISABLED);
+ QuicServerId a_10_https(HostPortPair("a.com", 10), PRIVACY_MODE_DISABLED);
+ QuicServerId a_11_https(HostPortPair("a.com", 11), PRIVACY_MODE_DISABLED);
+ QuicServerId b_10_https(HostPortPair("b.com", 10), PRIVACY_MODE_DISABLED);
+ QuicServerId b_11_https(HostPortPair("b.com", 11), PRIVACY_MODE_DISABLED);
- QuicServerId a_10_http_private(HostPortPair("a.com", 10), false,
- PRIVACY_MODE_ENABLED);
- QuicServerId a_10_https_private(HostPortPair("a.com", 10), true,
+ QuicServerId a_10_https_private(HostPortPair("a.com", 10),
PRIVACY_MODE_ENABLED);
- QuicServerId a_11_http_private(HostPortPair("a.com", 11), false,
- PRIVACY_MODE_ENABLED);
- QuicServerId a_11_https_private(HostPortPair("a.com", 11), true,
+ QuicServerId a_11_https_private(HostPortPair("a.com", 11),
PRIVACY_MODE_ENABLED);
- QuicServerId b_10_http_private(HostPortPair("b.com", 10), false,
- PRIVACY_MODE_ENABLED);
- QuicServerId b_10_https_private(HostPortPair("b.com", 10), true,
+ QuicServerId b_10_https_private(HostPortPair("b.com", 10),
PRIVACY_MODE_ENABLED);
- QuicServerId b_11_http_private(HostPortPair("b.com", 11), false,
- PRIVACY_MODE_ENABLED);
- QuicServerId b_11_https_private(HostPortPair("b.com", 11), true,
+ QuicServerId b_11_https_private(HostPortPair("b.com", 11),
PRIVACY_MODE_ENABLED);
- // Test combinations of host, port, https and privacy being same on left and
+ // Test combinations of host, port, and privacy being same on left and
// right side of less than.
- EXPECT_FALSE(a_10_http < a_10_http);
- EXPECT_TRUE(a_10_http < a_10_https);
- EXPECT_FALSE(a_10_https < a_10_http);
EXPECT_FALSE(a_10_https < a_10_https);
-
- EXPECT_TRUE(a_10_http < a_10_http_private);
- EXPECT_TRUE(a_10_http < a_10_https_private);
- EXPECT_FALSE(a_10_https < a_10_http_private);
- EXPECT_TRUE(a_10_https < a_10_https_private);
-
- EXPECT_FALSE(a_10_http_private < a_10_http);
- EXPECT_TRUE(a_10_http_private < a_10_https);
- EXPECT_FALSE(a_10_https_private < a_10_http);
+ EXPECT_TRUE(a_10_https < a_10_https_private);
EXPECT_FALSE(a_10_https_private < a_10_https);
-
- EXPECT_FALSE(a_10_http_private < a_10_http_private);
- EXPECT_TRUE(a_10_http_private < a_10_https_private);
- EXPECT_FALSE(a_10_https_private < a_10_http_private);
EXPECT_FALSE(a_10_https_private < a_10_https_private);
// Test with either host, port or https being different on left and right side
@@ -100,98 +53,35 @@ TEST(QuicServerIdTest, LessThan) {
for (int i = 0; i < 4; i++) {
left_privacy = static_cast<PrivacyMode>(i / 2);
right_privacy = static_cast<PrivacyMode>(i % 2);
- QuicServerId a_10_http_left_private(HostPortPair("a.com", 10), false,
- left_privacy);
- QuicServerId a_10_http_right_private(HostPortPair("a.com", 10), false,
- right_privacy);
- QuicServerId a_10_https_left_private(HostPortPair("a.com", 10), true,
+ QuicServerId a_10_https_left_private(HostPortPair("a.com", 10),
left_privacy);
- QuicServerId a_10_https_right_private(HostPortPair("a.com", 10), true,
+ QuicServerId a_10_https_right_private(HostPortPair("a.com", 10),
right_privacy);
- QuicServerId a_11_http_left_private(HostPortPair("a.com", 11), false,
- left_privacy);
- QuicServerId a_11_http_right_private(HostPortPair("a.com", 11), false,
- right_privacy);
- QuicServerId a_11_https_left_private(HostPortPair("a.com", 11), true,
+ QuicServerId a_11_https_left_private(HostPortPair("a.com", 11),
left_privacy);
- QuicServerId a_11_https_right_private(HostPortPair("a.com", 11), true,
+ QuicServerId a_11_https_right_private(HostPortPair("a.com", 11),
right_privacy);
- QuicServerId b_10_http_left_private(HostPortPair("b.com", 10), false,
- left_privacy);
- QuicServerId b_10_http_right_private(HostPortPair("b.com", 10), false,
- right_privacy);
- QuicServerId b_10_https_left_private(HostPortPair("b.com", 10), true,
+ QuicServerId b_10_https_left_private(HostPortPair("b.com", 10),
left_privacy);
- QuicServerId b_10_https_right_private(HostPortPair("b.com", 10), true,
+ QuicServerId b_10_https_right_private(HostPortPair("b.com", 10),
right_privacy);
- QuicServerId b_11_http_left_private(HostPortPair("b.com", 11), false,
- left_privacy);
- QuicServerId b_11_http_right_private(HostPortPair("b.com", 11), false,
- right_privacy);
- QuicServerId b_11_https_left_private(HostPortPair("b.com", 11), true,
+ QuicServerId b_11_https_left_private(HostPortPair("b.com", 11),
left_privacy);
- QuicServerId b_11_https_right_private(HostPortPair("b.com", 11), true,
+ QuicServerId b_11_https_right_private(HostPortPair("b.com", 11),
right_privacy);
- EXPECT_TRUE(a_10_http_left_private < a_11_http_right_private);
- EXPECT_TRUE(a_10_http_left_private < a_11_https_right_private);
- EXPECT_TRUE(a_10_https_left_private < a_11_http_right_private);
EXPECT_TRUE(a_10_https_left_private < a_11_https_right_private);
-
- EXPECT_TRUE(a_10_http_left_private < b_10_http_right_private);
- EXPECT_TRUE(a_10_http_left_private < b_10_https_right_private);
- EXPECT_TRUE(a_10_https_left_private < b_10_http_right_private);
EXPECT_TRUE(a_10_https_left_private < b_10_https_right_private);
-
- EXPECT_TRUE(a_10_http_left_private < b_11_http_right_private);
- EXPECT_TRUE(a_10_http_left_private < b_11_https_right_private);
- EXPECT_TRUE(a_10_https_left_private < b_11_http_right_private);
EXPECT_TRUE(a_10_https_left_private < b_11_https_right_private);
-
- EXPECT_FALSE(a_11_http_left_private < a_10_http_right_private);
- EXPECT_FALSE(a_11_http_left_private < a_10_https_right_private);
- EXPECT_FALSE(a_11_https_left_private < a_10_http_right_private);
EXPECT_FALSE(a_11_https_left_private < a_10_https_right_private);
-
- EXPECT_FALSE(a_11_http_left_private < b_10_http_right_private);
- EXPECT_FALSE(a_11_http_left_private < b_10_https_right_private);
- EXPECT_FALSE(a_11_https_left_private < b_10_http_right_private);
EXPECT_FALSE(a_11_https_left_private < b_10_https_right_private);
-
- EXPECT_TRUE(a_11_http_left_private < b_11_http_right_private);
- EXPECT_TRUE(a_11_http_left_private < b_11_https_right_private);
- EXPECT_TRUE(a_11_https_left_private < b_11_http_right_private);
EXPECT_TRUE(a_11_https_left_private < b_11_https_right_private);
-
- EXPECT_FALSE(b_10_http_left_private < a_10_http_right_private);
- EXPECT_FALSE(b_10_http_left_private < a_10_https_right_private);
- EXPECT_FALSE(b_10_https_left_private < a_10_http_right_private);
EXPECT_FALSE(b_10_https_left_private < a_10_https_right_private);
-
- EXPECT_TRUE(b_10_http_left_private < a_11_http_right_private);
- EXPECT_TRUE(b_10_http_left_private < a_11_https_right_private);
- EXPECT_TRUE(b_10_https_left_private < a_11_http_right_private);
EXPECT_TRUE(b_10_https_left_private < a_11_https_right_private);
-
- EXPECT_TRUE(b_10_http_left_private < b_11_http_right_private);
- EXPECT_TRUE(b_10_http_left_private < b_11_https_right_private);
- EXPECT_TRUE(b_10_https_left_private < b_11_http_right_private);
EXPECT_TRUE(b_10_https_left_private < b_11_https_right_private);
-
- EXPECT_FALSE(b_11_http_left_private < a_10_http_right_private);
- EXPECT_FALSE(b_11_http_left_private < a_10_https_right_private);
- EXPECT_FALSE(b_11_https_left_private < a_10_http_right_private);
EXPECT_FALSE(b_11_https_left_private < a_10_https_right_private);
-
- EXPECT_FALSE(b_11_http_left_private < a_11_http_right_private);
- EXPECT_FALSE(b_11_http_left_private < a_11_https_right_private);
- EXPECT_FALSE(b_11_https_left_private < a_11_http_right_private);
EXPECT_FALSE(b_11_https_left_private < a_11_https_right_private);
-
- EXPECT_FALSE(b_11_http_left_private < b_10_http_right_private);
- EXPECT_FALSE(b_11_http_left_private < b_10_https_right_private);
- EXPECT_FALSE(b_11_https_left_private < b_10_http_right_private);
EXPECT_FALSE(b_11_https_left_private < b_10_https_right_private);
}
}
@@ -201,85 +91,53 @@ TEST(QuicServerIdTest, Equals) {
PrivacyMode right_privacy;
for (int i = 0; i < 2; i++) {
left_privacy = right_privacy = static_cast<PrivacyMode>(i);
- QuicServerId a_10_http_right_private(HostPortPair("a.com", 10), false,
- right_privacy);
- QuicServerId a_10_https_right_private(HostPortPair("a.com", 10), true,
+ QuicServerId a_10_https_right_private(HostPortPair("a.com", 10),
right_privacy);
- QuicServerId a_11_http_right_private(HostPortPair("a.com", 11), false,
- right_privacy);
- QuicServerId a_11_https_right_private(HostPortPair("a.com", 11), true,
+ QuicServerId a_11_https_right_private(HostPortPair("a.com", 11),
right_privacy);
- QuicServerId b_10_http_right_private(HostPortPair("b.com", 10), false,
- right_privacy);
- QuicServerId b_10_https_right_private(HostPortPair("b.com", 10), true,
+ QuicServerId b_10_https_right_private(HostPortPair("b.com", 10),
right_privacy);
- QuicServerId b_11_http_right_private(HostPortPair("b.com", 11), false,
- right_privacy);
- QuicServerId b_11_https_right_private(HostPortPair("b.com", 11), true,
+ QuicServerId b_11_https_right_private(HostPortPair("b.com", 11),
right_privacy);
- QuicServerId new_a_10_http_left_private(HostPortPair("a.com", 10), false,
- left_privacy);
- QuicServerId new_a_10_https_left_private(HostPortPair("a.com", 10), true,
+ QuicServerId new_a_10_https_left_private(HostPortPair("a.com", 10),
left_privacy);
- QuicServerId new_a_11_http_left_private(HostPortPair("a.com", 11), false,
- left_privacy);
- QuicServerId new_a_11_https_left_private(HostPortPair("a.com", 11), true,
+ QuicServerId new_a_11_https_left_private(HostPortPair("a.com", 11),
left_privacy);
- QuicServerId new_b_10_http_left_private(HostPortPair("b.com", 10), false,
- left_privacy);
- QuicServerId new_b_10_https_left_private(HostPortPair("b.com", 10), true,
+ QuicServerId new_b_10_https_left_private(HostPortPair("b.com", 10),
left_privacy);
- QuicServerId new_b_11_http_left_private(HostPortPair("b.com", 11), false,
- left_privacy);
- QuicServerId new_b_11_https_left_private(HostPortPair("b.com", 11), true,
+ QuicServerId new_b_11_https_left_private(HostPortPair("b.com", 11),
left_privacy);
- EXPECT_EQ(new_a_10_http_left_private, a_10_http_right_private);
EXPECT_EQ(new_a_10_https_left_private, a_10_https_right_private);
- EXPECT_EQ(new_a_11_http_left_private, a_11_http_right_private);
EXPECT_EQ(new_a_11_https_left_private, a_11_https_right_private);
- EXPECT_EQ(new_b_10_http_left_private, b_10_http_right_private);
EXPECT_EQ(new_b_10_https_left_private, b_10_https_right_private);
- EXPECT_EQ(new_b_11_http_left_private, b_11_http_right_private);
EXPECT_EQ(new_b_11_https_left_private, b_11_https_right_private);
}
for (int i = 0; i < 2; i++) {
right_privacy = static_cast<PrivacyMode>(i);
- QuicServerId a_10_http_right_private(HostPortPair("a.com", 10), false,
- right_privacy);
- QuicServerId a_10_https_right_private(HostPortPair("a.com", 10), true,
+ QuicServerId a_10_https_right_private(HostPortPair("a.com", 10),
right_privacy);
- QuicServerId a_11_http_right_private(HostPortPair("a.com", 11), false,
- right_privacy);
- QuicServerId a_11_https_right_private(HostPortPair("a.com", 11), true,
+ QuicServerId a_11_https_right_private(HostPortPair("a.com", 11),
right_privacy);
- QuicServerId b_10_http_right_private(HostPortPair("b.com", 10), false,
- right_privacy);
- QuicServerId b_10_https_right_private(HostPortPair("b.com", 10), true,
+ QuicServerId b_10_https_right_private(HostPortPair("b.com", 10),
right_privacy);
- QuicServerId b_11_http_right_private(HostPortPair("b.com", 11), false,
- right_privacy);
- QuicServerId b_11_https_right_private(HostPortPair("b.com", 11), true,
+ QuicServerId b_11_https_right_private(HostPortPair("b.com", 11),
right_privacy);
- QuicServerId new_a_10_http_left_private(HostPortPair("a.com", 10), false,
- PRIVACY_MODE_DISABLED);
+ QuicServerId new_a_10_https_left_private(HostPortPair("a.com", 10),
+ PRIVACY_MODE_DISABLED);
- EXPECT_FALSE(new_a_10_http_left_private == a_10_https_right_private);
- EXPECT_FALSE(new_a_10_http_left_private == a_11_http_right_private);
- EXPECT_FALSE(new_a_10_http_left_private == b_10_http_right_private);
- EXPECT_FALSE(new_a_10_http_left_private == a_11_https_right_private);
- EXPECT_FALSE(new_a_10_http_left_private == b_10_https_right_private);
- EXPECT_FALSE(new_a_10_http_left_private == b_11_http_right_private);
- EXPECT_FALSE(new_a_10_http_left_private == b_11_https_right_private);
+ EXPECT_FALSE(new_a_10_https_left_private == a_11_https_right_private);
+ EXPECT_FALSE(new_a_10_https_left_private == b_10_https_right_private);
+ EXPECT_FALSE(new_a_10_https_left_private == b_11_https_right_private);
}
- QuicServerId a_10_http_private(HostPortPair("a.com", 10), false,
- PRIVACY_MODE_ENABLED);
- QuicServerId new_a_10_http_no_private(HostPortPair("a.com", 10), false,
- PRIVACY_MODE_DISABLED);
- EXPECT_FALSE(new_a_10_http_no_private == a_10_http_private);
+ QuicServerId a_10_https_private(HostPortPair("a.com", 10),
+ PRIVACY_MODE_ENABLED);
+ QuicServerId new_a_10_https_no_private(HostPortPair("a.com", 10),
+ PRIVACY_MODE_DISABLED);
+ EXPECT_FALSE(new_a_10_https_no_private == a_10_https_private);
}
} // namespace
diff --git a/chromium/net/quic/quic_session.cc b/chromium/net/quic/quic_session.cc
index 890f5a25f18..24a6e99d6c2 100644
--- a/chromium/net/quic/quic_session.cc
+++ b/chromium/net/quic/quic_session.cc
@@ -5,7 +5,9 @@
#include "net/quic/quic_session.h"
#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
#include "net/quic/crypto/proof_verifier.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_flow_controller.h"
@@ -19,6 +21,7 @@ using std::map;
using std::max;
using std::string;
using std::vector;
+using net::SpdyPriority;
namespace net {
@@ -103,18 +106,19 @@ QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config)
visitor_shim_(new VisitorShim(this)),
config_(config),
max_open_streams_(config_.MaxStreamsPerConnection()),
- next_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 3),
+ next_outgoing_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 3),
largest_peer_created_stream_id_(
perspective() == Perspective::IS_SERVER ? 1 : 0),
+ num_dynamic_incoming_streams_(0),
+ num_draining_incoming_streams_(0),
+ num_locally_closed_incoming_streams_highest_offset_(0),
error_(QUIC_NO_ERROR),
flow_controller_(connection_.get(),
0,
perspective(),
kMinimumFlowControlSendWindow,
config_.GetInitialSessionFlowControlWindowToSend(),
- false),
- has_pending_handshake_(false) {
-}
+ false) {}
void QuicSession::Initialize() {
connection_->set_visitor(visitor_shim_.get());
@@ -128,10 +132,16 @@ QuicSession::~QuicSession() {
STLDeleteElements(&closed_streams_);
STLDeleteValues(&dynamic_stream_map_);
+ DLOG_IF(WARNING, num_locally_closed_incoming_streams_highest_offset() >
+ max_open_streams_)
+ << "Surprisingly high number of locally closed peer initiated streams"
+ "still waiting for final byte offset: "
+ << num_locally_closed_incoming_streams_highest_offset();
DLOG_IF(WARNING,
- locally_closed_streams_highest_offset_.size() > max_open_streams_)
- << "Surprisingly high number of locally closed streams still waiting for "
- "final byte offset: " << locally_closed_streams_highest_offset_.size();
+ GetNumLocallyClosedOutgoingStreamsHighestOffset() > max_open_streams_)
+ << "Surprisingly high number of locally closed self initiated streams"
+ "still waiting for final byte offset: "
+ << GetNumLocallyClosedOutgoingStreamsHighestOffset();
}
void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
@@ -143,7 +153,7 @@ void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
// final stream byte offset sent by the peer. A frame with a FIN can give
// us this offset.
if (frame.fin) {
- QuicStreamOffset final_byte_offset = frame.offset + frame.data.size();
+ QuicStreamOffset final_byte_offset = frame.offset + frame.frame_length;
UpdateFlowControlOnFinalReceivedByteOffset(stream_id, final_byte_offset);
}
return;
@@ -158,12 +168,9 @@ void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
return;
}
- ReliableQuicStream* stream = GetDynamicStream(frame.stream_id);
+ ReliableQuicStream* stream = GetOrCreateDynamicStream(frame.stream_id);
if (!stream) {
- // The RST frame contains the final byte offset for the stream: we can now
- // update the connection level flow controller if needed.
- UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id,
- frame.byte_offset);
+ HandleRstOnValidNonexistentStream(frame);
return; // Errors are handled by GetStream.
}
@@ -171,7 +178,7 @@ void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
}
void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) {
- DCHECK(frame.last_good_stream_id < next_stream_id_);
+ DCHECK(frame.last_good_stream_id < next_outgoing_stream_id_);
}
void QuicSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) {
@@ -186,15 +193,14 @@ void QuicSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) {
it->second->OnConnectionClosed(error, from_peer);
// The stream should call CloseStream as part of OnConnectionClosed.
if (dynamic_stream_map_.find(id) != dynamic_stream_map_.end()) {
- LOG(DFATAL) << ENDPOINT
- << "Stream failed to close under OnConnectionClosed";
+ QUIC_BUG << ENDPOINT << "Stream failed to close under OnConnectionClosed";
CloseStream(id);
}
}
}
-void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) {
-}
+void QuicSession::OnSuccessfulVersionNegotiation(
+ const QuicVersion& /*version*/) {}
void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
// Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
@@ -245,13 +251,13 @@ void QuicSession::OnCanWrite() {
return;
}
- QuicConnection::ScopedPacketBundler ack_bundler(
- connection_.get(), QuicConnection::NO_ACK);
+ QuicConnection::ScopedPacketBundler ack_bundler(connection_.get(),
+ QuicConnection::NO_ACK);
for (size_t i = 0; i < num_writes; ++i) {
if (!(write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
write_blocked_streams_.HasWriteBlockedDataStreams())) {
// Writing one stream removed another!? Something's broken.
- LOG(DFATAL) << "WriteBlockedStream is missing";
+ QUIC_BUG << "WriteBlockedStream is missing";
connection_->CloseConnection(QUIC_INTERNAL_ERROR, false);
return;
}
@@ -259,12 +265,9 @@ void QuicSession::OnCanWrite() {
return;
}
QuicStreamId stream_id = write_blocked_streams_.PopFront();
- if (stream_id == kCryptoStreamId) {
- has_pending_handshake_ = false; // We just popped it.
- }
ReliableQuicStream* stream = GetStream(stream_id);
if (stream != nullptr && !stream->flow_controller()->IsBlocked()) {
- // If the stream can't write all bytes, it'll re-add itself to the blocked
+ // If the stream can't write all bytes it'll re-add itself to the blocked
// list.
stream->OnCanWrite();
}
@@ -282,35 +285,38 @@ bool QuicSession::WillingAndAbleToWrite() const {
}
bool QuicSession::HasPendingHandshake() const {
- return has_pending_handshake_;
+ return write_blocked_streams_.crypto_stream_blocked();
}
bool QuicSession::HasOpenDynamicStreams() const {
- return GetNumOpenStreams() > 0;
+ return (dynamic_stream_map_.size() - draining_streams_.size() +
+ locally_closed_streams_highest_offset_.size()) > 0;
}
QuicConsumedData QuicSession::WritevData(
QuicStreamId id,
- const QuicIOVector& iov,
+ QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
+ QuicAckListenerInterface* ack_notifier_delegate) {
if (FLAGS_quic_block_unencrypted_writes && !IsEncryptionEstablished() &&
id != kCryptoStreamId) {
// Do not let streams write without encryption. The calling stream will end
// up write blocked until OnCanWrite is next called.
return QuicConsumedData(0, false);
}
- return connection_->SendStreamData(id, iov, offset, fin, fec_protection,
- ack_notifier_delegate);
+ QuicConsumedData data = connection_->SendStreamData(
+ id, iov, offset, fin, fec_protection, ack_notifier_delegate);
+ write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
+ return data;
}
void QuicSession::SendRstStream(QuicStreamId id,
QuicRstStreamErrorCode error,
QuicStreamOffset bytes_written) {
if (ContainsKey(static_stream_map_, id)) {
- LOG(DFATAL) << "Cannot send RST for a static stream with ID " << id;
+ QUIC_BUG << "Cannot send RST for a static stream with ID " << id;
return;
}
@@ -333,8 +339,7 @@ void QuicSession::CloseStream(QuicStreamId stream_id) {
CloseStreamInner(stream_id, false);
}
-void QuicSession::CloseStreamInner(QuicStreamId stream_id,
- bool locally_reset) {
+void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) {
DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
StreamMap::iterator it = dynamic_stream_map_.find(stream_id);
@@ -360,17 +365,30 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id,
if (!stream->HasFinalReceivedByteOffset()) {
locally_closed_streams_highest_offset_[stream_id] =
stream->flow_controller()->highest_received_byte_offset();
+ if (IsIncomingStream(stream_id)) {
+ ++num_locally_closed_incoming_streams_highest_offset_;
+ }
}
dynamic_stream_map_.erase(it);
+ if (IsIncomingStream(stream_id)) {
+ --num_dynamic_incoming_streams_;
+ }
+
+ if (draining_streams_.find(stream_id) != draining_streams_.end() &&
+ IsIncomingStream(stream_id)) {
+ --num_draining_incoming_streams_;
+ }
draining_streams_.erase(stream_id);
+
stream->OnClose();
// Decrease the number of streams being emulated when a new one is opened.
connection_->SetNumOpenStreams(dynamic_stream_map_.size());
}
void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset(
- QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
+ QuicStreamId stream_id,
+ QuicStreamOffset final_byte_offset) {
map<QuicStreamId, QuicStreamOffset>::iterator it =
locally_closed_streams_highest_offset_.find(stream_id);
if (it == locally_closed_streams_highest_offset_.end()) {
@@ -384,14 +402,18 @@ void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset(
flow_controller_.highest_received_byte_offset() + offset_diff)) {
// If the final offset violates flow control, close the connection now.
if (flow_controller_.FlowControlViolation()) {
- connection_->SendConnectionClose(
- QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA);
+ connection_->SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+ "Connection level flow control violation");
return;
}
}
flow_controller_.AddBytesConsumed(offset_diff);
locally_closed_streams_highest_offset_.erase(it);
+ if (IsIncomingStream(stream_id)) {
+ --num_locally_closed_incoming_streams_highest_offset_;
+ }
}
bool QuicSession::IsEncryptionEstablished() {
@@ -405,7 +427,7 @@ bool QuicSession::IsCryptoHandshakeConfirmed() {
void QuicSession::OnConfigNegotiated() {
connection_->SetFromConfig(config_);
- uint32 max_streams = config_.MaxStreamsPerConnection();
+ uint32_t max_streams = config_.MaxStreamsPerConnection();
if (perspective() == Perspective::IS_SERVER) {
// A server should accept a small number of additional streams beyond the
// limit sent to the client. This helps avoid early connection termination
@@ -414,7 +436,7 @@ void QuicSession::OnConfigNegotiated() {
// whichever is larger.
max_streams =
max(max_streams + kMaxStreamsMinimumIncrement,
- static_cast<uint32>(max_streams * kMaxStreamsMultiplier));
+ static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier));
if (config_.HasReceivedConnectionOptions()) {
if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kAFCW)) {
@@ -486,13 +508,36 @@ void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) {
}
}
+void QuicSession::HandleFrameOnNonexistentOutgoingStream(
+ QuicStreamId stream_id) {
+ DCHECK(!IsClosedStream(stream_id));
+ // Received a frame for a locally-created stream that is not currently
+ // active. This is an error.
+ CloseConnectionWithDetails(QUIC_INVALID_STREAM_ID,
+ "Data for nonexistent stream");
+}
+
+void QuicSession::HandleRstOnValidNonexistentStream(
+ const QuicRstStreamFrame& frame) {
+ // If the stream is neither originally in active streams nor created in
+ // GetOrCreateDynamicStream(), it could be a closed stream in which case its
+ // final received byte offset need to be updated.
+ if (IsClosedStream(frame.stream_id)) {
+ // The RST frame contains the final byte offset for the stream: we can now
+ // update the connection level flow controller if needed.
+ UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id,
+ frame.byte_offset);
+ }
+}
+
void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
if (new_window < kMinimumFlowControlSendWindow) {
LOG(ERROR) << "Peer sent us an invalid stream flow control send window: "
<< new_window
<< ", below default: " << kMinimumFlowControlSendWindow;
if (connection_->connected()) {
- connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW);
+ connection_->SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low");
}
return;
}
@@ -512,7 +557,8 @@ void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
<< new_window
<< ", below default: " << kMinimumFlowControlSendWindow;
if (connection_->connected()) {
- connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW);
+ connection_->SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_INVALID_WINDOW, "New connection window too low");
}
return;
}
@@ -542,8 +588,8 @@ void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
break;
case HANDSHAKE_CONFIRMED:
- LOG_IF(DFATAL, !config_.negotiated()) << ENDPOINT
- << "Handshake confirmed without parameter negotiation.";
+ LOG_IF(DFATAL, !config_.negotiated())
+ << ENDPOINT << "Handshake confirmed without parameter negotiation.";
// Discard originally encrypted packets, since they can't be decrypted by
// the peer.
connection_->NeuterUnencryptedPackets();
@@ -555,12 +601,10 @@ void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
}
void QuicSession::OnCryptoHandshakeMessageSent(
- const CryptoHandshakeMessage& message) {
-}
+ const CryptoHandshakeMessage& /*message*/) {}
void QuicSession::OnCryptoHandshakeMessageReceived(
- const CryptoHandshakeMessage& message) {
-}
+ const CryptoHandshakeMessage& /*message*/) {}
QuicConfig* QuicSession::config() {
return &config_;
@@ -572,13 +616,16 @@ void QuicSession::ActivateStream(ReliableQuicStream* stream) {
DCHECK(!ContainsKey(dynamic_stream_map_, stream->id()));
DCHECK(!ContainsKey(static_stream_map_, stream->id()));
dynamic_stream_map_[stream->id()] = stream;
+ if (IsIncomingStream(stream->id())) {
+ ++num_dynamic_incoming_streams_;
+ }
// Increase the number of streams being emulated when a new one is opened.
connection_->SetNumOpenStreams(dynamic_stream_map_.size());
}
-QuicStreamId QuicSession::GetNextStreamId() {
- QuicStreamId id = next_stream_id_;
- next_stream_id_ += 2;
+QuicStreamId QuicSession::GetNextOutgoingStreamId() {
+ QuicStreamId id = next_outgoing_stream_id_;
+ next_outgoing_stream_id_ += 2;
return id;
}
@@ -587,20 +634,31 @@ ReliableQuicStream* QuicSession::GetStream(const QuicStreamId stream_id) {
if (it != static_stream_map_.end()) {
return it->second;
}
- return GetDynamicStream(stream_id);
+ return GetOrCreateDynamicStream(stream_id);
}
void QuicSession::StreamDraining(QuicStreamId stream_id) {
DCHECK(ContainsKey(dynamic_stream_map_, stream_id));
if (!ContainsKey(draining_streams_, stream_id)) {
draining_streams_.insert(stream_id);
+ if (IsIncomingStream(stream_id)) {
+ ++num_draining_incoming_streams_;
+ }
+ }
+}
+
+void QuicSession::CloseConnectionWithDetails(QuicErrorCode error,
+ const char* details) {
+ if (connection()->connected()) {
+ connection()->SendConnectionCloseWithDetails(error, details);
}
}
-ReliableQuicStream* QuicSession::GetDynamicStream(
+ReliableQuicStream* QuicSession::GetOrCreateDynamicStream(
const QuicStreamId stream_id) {
- if (static_stream_map_.find(stream_id) != static_stream_map_.end()) {
- DLOG(FATAL) << "Attempt to call GetDynamicStream for a static stream";
+ if (ContainsKey(static_stream_map_, stream_id)) {
+ DLOG(FATAL)
+ << "Attempt to call GetOrCreateDynamicStream for a static stream";
return nullptr;
}
@@ -613,49 +671,59 @@ ReliableQuicStream* QuicSession::GetDynamicStream(
return nullptr;
}
- if (stream_id % 2 == next_stream_id_ % 2) {
- // We've received a frame for a locally-created stream that is not
- // currently active. This is an error.
- if (connection()->connected()) {
- connection()->SendConnectionClose(QUIC_PACKET_FOR_NONEXISTENT_STREAM);
- }
+ if (!IsIncomingStream(stream_id)) {
+ HandleFrameOnNonexistentOutgoingStream(stream_id);
return nullptr;
}
- return GetIncomingDynamicStream(stream_id);
-}
+ available_streams_.erase(stream_id);
-ReliableQuicStream* QuicSession::GetIncomingDynamicStream(
- QuicStreamId stream_id) {
- if (IsClosedStream(stream_id)) {
- return nullptr;
- }
- implicitly_created_streams_.erase(stream_id);
if (stream_id > largest_peer_created_stream_id_) {
- // Check if the number of streams that will be created (including implicitly
- // open streams) would cause the number of open streams to exceed the limit.
- // Note that the peer can create only alternately-numbered streams.
- if ((stream_id - largest_peer_created_stream_id_) / 2 +
- GetNumOpenStreams() >
- get_max_open_streams()) {
+ // Check if the new number of available streams would cause the number of
+ // available streams to exceed the limit. Note that the peer can create
+ // only alternately-numbered streams.
+ size_t additional_available_streams =
+ (stream_id - largest_peer_created_stream_id_) / 2 - 1;
+ size_t new_num_available_streams =
+ GetNumAvailableStreams() + additional_available_streams;
+ if (new_num_available_streams > get_max_available_streams()) {
DVLOG(1) << "Failed to create a new incoming stream with id:" << stream_id
- << ". Already " << GetNumOpenStreams()
- << " streams open, would exceed max " << get_max_open_streams()
- << ".";
- // We may already have sent a connection close due to multiple reset
- // streams in the same packet.
- if (connection()->connected()) {
- connection()->SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS);
- }
+ << ". There are already " << GetNumAvailableStreams()
+ << " streams available, which would become "
+ << new_num_available_streams << ", which exceeds the limit "
+ << get_max_available_streams() << ".";
+ CloseConnectionWithDetails(
+ QUIC_TOO_MANY_AVAILABLE_STREAMS,
+ base::StringPrintf(
+ "%lu above %lu",
+ static_cast<unsigned long>(new_num_available_streams),
+ static_cast<unsigned long>(get_max_available_streams()))
+ .c_str());
return nullptr;
}
- for (QuicStreamId id = largest_peer_created_stream_id_ + 2;
- id < stream_id;
+ for (QuicStreamId id = largest_peer_created_stream_id_ + 2; id < stream_id;
id += 2) {
- implicitly_created_streams_.insert(id);
+ available_streams_.insert(id);
}
largest_peer_created_stream_id_ = stream_id;
}
+ // Check if the new number of open streams would cause the number of
+ // open streams to exceed the limit.
+ size_t num_current_open_streams =
+ FLAGS_quic_distinguish_incoming_outgoing_streams
+ ? GetNumOpenIncomingStreams()
+ : dynamic_stream_map_.size() - draining_streams_.size() +
+ locally_closed_streams_highest_offset_.size();
+ if (num_current_open_streams >= get_max_open_streams()) {
+ if (connection()->version() <= QUIC_VERSION_27) {
+ CloseConnectionWithDetails(QUIC_TOO_MANY_OPEN_STREAMS,
+ "Old style stream rejection");
+ } else {
+ // Refuse to open the stream.
+ SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0);
+ }
+ return nullptr;
+ }
ReliableQuicStream* stream = CreateIncomingDynamicStream(stream_id);
if (stream == nullptr) {
return nullptr;
@@ -666,6 +734,8 @@ ReliableQuicStream* QuicSession::GetIncomingDynamicStream(
void QuicSession::set_max_open_streams(size_t max_open_streams) {
DVLOG(1) << "Setting max_open_streams_ to " << max_open_streams;
+ DVLOG(1) << "Setting get_max_available_streams() to "
+ << get_max_available_streams();
max_open_streams_ = max_open_streams;
}
@@ -684,45 +754,49 @@ bool QuicSession::IsClosedStream(QuicStreamId id) {
// Stream is active
return false;
}
- if (id % 2 == next_stream_id_ % 2) {
+ if (!IsIncomingStream(id)) {
// Locally created streams are strictly in-order. If the id is in the
// range of created streams and it's not active, it must have been closed.
- return id < next_stream_id_;
+ return id < next_outgoing_stream_id_;
}
- // For peer created streams, we also need to consider implicitly created
- // streams.
+ // For peer created streams, we also need to consider available streams.
return id <= largest_peer_created_stream_id_ &&
- !ContainsKey(implicitly_created_streams_, id);
+ !ContainsKey(available_streams_, id);
+}
+
+size_t QuicSession::GetNumOpenIncomingStreams() const {
+ return num_dynamic_incoming_streams_ - num_draining_incoming_streams_ +
+ num_locally_closed_incoming_streams_highest_offset_;
}
-size_t QuicSession::GetNumOpenStreams() const {
- return dynamic_stream_map_.size() + implicitly_created_streams_.size() -
- draining_streams_.size();
+size_t QuicSession::GetNumOpenOutgoingStreams() const {
+ return GetNumDynamicOutgoingStreams() - GetNumDrainingOutgoingStreams() +
+ GetNumLocallyClosedOutgoingStreamsHighestOffset();
+}
+
+size_t QuicSession::GetNumActiveStreams() const {
+ return dynamic_stream_map_.size() - draining_streams_.size();
+}
+
+size_t QuicSession::GetNumAvailableStreams() const {
+ return available_streams_.size();
}
void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id,
- QuicPriority priority) {
+ SpdyPriority priority) {
#ifndef NDEBUG
ReliableQuicStream* stream = GetStream(id);
if (stream != nullptr) {
- LOG_IF(DFATAL, priority != stream->EffectivePriority())
+ LOG_IF(DFATAL, priority != stream->Priority())
<< ENDPOINT << "Stream " << id
- << "Priorities do not match. Got: " << priority
- << " Expected: " << stream->EffectivePriority();
+ << "Priorities do not match. Got: " << static_cast<int>(priority)
+ << " Expected: " << static_cast<int>(stream->Priority());
} else {
- LOG(DFATAL) << "Marking unknown stream " << id << " blocked.";
+ QUIC_BUG << "Marking unknown stream " << id << " blocked.";
}
#endif
- if (id == kCryptoStreamId) {
- DCHECK(!has_pending_handshake_);
- has_pending_handshake_ = true;
- // TODO(jar): Be sure to use the highest priority for the crypto stream,
- // perhaps by adding a "special" priority for it that is higher than
- // kHighestPriority.
- priority = kHighestPriority;
- }
- write_blocked_streams_.PushBack(id, priority);
+ write_blocked_streams_.AddStream(id, priority);
}
bool QuicSession::HasDataToWrite() const {
@@ -733,12 +807,20 @@ bool QuicSession::HasDataToWrite() const {
void QuicSession::PostProcessAfterData() {
STLDeleteElements(&closed_streams_);
+ closed_streams_.clear();
+}
- if (connection()->connected() &&
- locally_closed_streams_highest_offset_.size() > max_open_streams_) {
- // A buggy client may fail to send FIN/RSTs. Don't tolerate this.
- connection_->SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS);
- }
+size_t QuicSession::GetNumDynamicOutgoingStreams() const {
+ return dynamic_stream_map_.size() - num_dynamic_incoming_streams_;
+}
+
+size_t QuicSession::GetNumDrainingOutgoingStreams() const {
+ return draining_streams_.size() - num_draining_incoming_streams_;
+}
+
+size_t QuicSession::GetNumLocallyClosedOutgoingStreamsHighestOffset() const {
+ return locally_closed_streams_highest_offset_.size() -
+ num_locally_closed_incoming_streams_highest_offset_;
}
bool QuicSession::IsConnectionFlowControlBlocked() const {
@@ -759,4 +841,8 @@ bool QuicSession::IsStreamFlowControlBlocked() {
return false;
}
+bool QuicSession::IsIncomingStream(QuicStreamId id) const {
+ return id % 2 != next_outgoing_stream_id_ % 2;
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_session.h b/chromium/net/quic/quic_session.h
index 37830115674..87fa1083484 100644
--- a/chromium/net/quic/quic_session.h
+++ b/chromium/net/quic/quic_session.h
@@ -7,12 +7,15 @@
#ifndef NET_QUIC_QUIC_SESSION_H_
#define NET_QUIC_QUIC_SESSION_H_
+#include <stddef.h>
+
#include <map>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/ip_endpoint.h"
@@ -53,6 +56,7 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
HANDSHAKE_CONFIRMED,
};
+ // Takes ownership of |connection|.
QuicSession(QuicConnection* connection, const QuicConfig& config);
~QuicSession() override;
@@ -69,7 +73,7 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
void OnWriteBlocked() override {}
void OnSuccessfulVersionNegotiation(const QuicVersion& version) override;
void OnCanWrite() override;
- void OnCongestionWindowChange(QuicTime now) override {}
+ void OnCongestionWindowChange(QuicTime /*now*/) override {}
void OnConnectionMigration() override {}
bool WillingAndAbleToWrite() const override;
bool HasPendingHandshake() const override;
@@ -87,11 +91,11 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
// we have seen ACKs for all packets resulting from this call.
virtual QuicConsumedData WritevData(
QuicStreamId id,
- const QuicIOVector& iov,
+ QuicIOVector iov,
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
+ QuicAckListenerInterface* ack_notifier_delegate);
// Called by streams when they want to close the stream in both directions.
virtual void SendRstStream(QuicStreamId id,
@@ -145,23 +149,32 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
QuicConnection* connection() { return connection_.get(); }
const QuicConnection* connection() const { return connection_.get(); }
size_t num_active_requests() const { return dynamic_stream_map_.size(); }
- const IPEndPoint& peer_address() const {
- return connection_->peer_address();
- }
+ const IPEndPoint& peer_address() const { return connection_->peer_address(); }
QuicConnectionId connection_id() const {
return connection_->connection_id();
}
- // Returns the number of currently open streams, including those which have
- // been implicitly created, but excluding the reserved headers and crypto
- // streams.
- virtual size_t GetNumOpenStreams() const;
+ // Returns the number of currently open streams, excluding the reserved
+ // headers and crypto streams, and never counting unfinished streams.
+ virtual size_t GetNumActiveStreams() const;
+
+ // Returns the number of currently open peer initiated streams, excluding the
+ // reserved headers and crypto streams.
+ virtual size_t GetNumOpenIncomingStreams() const;
+
+ // Returns the number of currently open self initiated streams, excluding the
+ // reserved headers and crypto streams.
+ virtual size_t GetNumOpenOutgoingStreams() const;
+
+ // Returns the number of "available" streams, the stream ids less than
+ // largest_peer_created_stream_id_ that have not yet been opened.
+ virtual size_t GetNumAvailableStreams() const;
// Add the stream to the session's write-blocked list because it is blocked by
// connection-level flow control but not by its own stream-level flow control.
// The stream will be given a chance to write when a connection-level
// WINDOW_UPDATE arrives.
- void MarkConnectionLevelWriteBlocked(QuicStreamId id, QuicPriority priority);
+ void MarkConnectionLevelWriteBlocked(QuicStreamId id, SpdyPriority priority);
// Returns true if the session has data to be sent, either queued in the
// connection, or in a write-blocked stream.
@@ -183,15 +196,19 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
// Returns true if any stream is flow controller blocked.
bool IsStreamFlowControlBlocked();
- // Returns true if this is a secure QUIC session.
- bool IsSecure() const { return connection()->is_secure(); }
-
size_t get_max_open_streams() const { return max_open_streams_; }
+ size_t get_max_available_streams() const {
+ return max_open_streams_ * kMaxAvailableStreamsMultiplier;
+ }
+
ReliableQuicStream* GetStream(const QuicStreamId stream_id);
// Mark a stream as draining.
- void StreamDraining(QuicStreamId id);
+ virtual void StreamDraining(QuicStreamId id);
+
+ // Close the connection, if it is not already closed.
+ void CloseConnectionWithDetails(QuicErrorCode error, const char* details);
protected:
typedef base::hash_map<QuicStreamId, ReliableQuicStream*> StreamMap;
@@ -203,20 +220,25 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
// Create a new stream, owned by the caller, to handle a locally-initiated
// stream. Returns nullptr if max streams have already been opened.
- virtual ReliableQuicStream* CreateOutgoingDynamicStream() = 0;
+ virtual ReliableQuicStream* CreateOutgoingDynamicStream(
+ SpdyPriority priority) = 0;
// Return the reserved crypto stream.
virtual QuicCryptoStream* GetCryptoStream() = 0;
- // Adds 'stream' to the active stream map.
+ // Adds |stream| to the dynamic stream map.
+ // Takes ownership of |stream|.
virtual void ActivateStream(ReliableQuicStream* stream);
- // Returns the stream id for a new stream.
- QuicStreamId GetNextStreamId();
+ // Returns the stream ID for a new outgoing stream, and increments the
+ // underlying counter.
+ QuicStreamId GetNextOutgoingStreamId();
- ReliableQuicStream* GetIncomingDynamicStream(QuicStreamId stream_id);
-
- ReliableQuicStream* GetDynamicStream(const QuicStreamId stream_id);
+ // Returns existing stream with id = |stream_id|. If no such stream exists,
+ // and |stream_id| is a peer-created id, then a new stream is created and
+ // returned. However if |stream_id| is a locally-created id and no such stream
+ // exists, the connection is closed.
+ ReliableQuicStream* GetOrCreateDynamicStream(QuicStreamId stream_id);
// This is called after every call other than OnConnectionClose from the
// QuicConnectionVisitor to allow post-processing once the work has been done.
@@ -224,6 +246,21 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
// operations are being done on the streams at this time)
virtual void PostProcessAfterData();
+ // Performs the work required to close |stream_id|. If |locally_reset|
+ // then the stream has been reset by this endpoint, not by the peer.
+ virtual void CloseStreamInner(QuicStreamId stream_id, bool locally_reset);
+
+ // When a stream is closed locally, it may not yet know how many bytes the
+ // peer sent on that stream.
+ // When this data arrives (via stream frame w. FIN, or RST) this method
+ // is called, and correctly updates the connection level flow controller.
+ void UpdateFlowControlOnFinalReceivedByteOffset(
+ QuicStreamId id,
+ QuicStreamOffset final_byte_offset);
+
+ // Return true if given stream is peer initiated.
+ bool IsIncomingStream(QuicStreamId id) const;
+
StreamMap& static_streams() { return static_stream_map_; }
const StreamMap& static_streams() const { return static_stream_map_; }
@@ -241,22 +278,41 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
largest_peer_created_stream_id_ = largest_peer_created_stream_id;
}
void set_error(QuicErrorCode error) { error_ = error; }
+ QuicWriteBlockedList* write_blocked_streams() {
+ return &write_blocked_streams_;
+ }
+
+ size_t GetNumDynamicOutgoingStreams() const;
+
+ size_t GetNumDrainingOutgoingStreams() const;
+
+ size_t num_locally_closed_incoming_streams_highest_offset() const {
+ return num_locally_closed_incoming_streams_highest_offset_;
+ }
+
+ size_t GetNumLocallyClosedOutgoingStreamsHighestOffset() const;
+
+ QuicStreamId next_outgoing_stream_id() const {
+ return next_outgoing_stream_id_;
+ }
+
+ // Close connection when receive a frame for a locally-created nonexistant
+ // stream.
+ // Prerequisite: IsClosedStream(stream_id) == false
+ // Server session might need to override this method to allow server push
+ // stream to be promised before creating an active stream.
+ virtual void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id);
+
+ // If stream is a locally closed stream, this RST will update FIN offset.
+ // Otherwise stream is a preserved stream and the behavior of it depends on
+ // derived class's own implementation.
+ virtual void HandleRstOnValidNonexistentStream(
+ const QuicRstStreamFrame& frame);
private:
friend class test::QuicSessionPeer;
friend class VisitorShim;
- // Performs the work required to close |stream_id|. If |locally_reset|
- // then the stream has been reset by this endpoint, not by the peer.
- void CloseStreamInner(QuicStreamId stream_id, bool locally_reset);
-
- // When a stream is closed locally, it may not yet know how many bytes the
- // peer sent on that stream.
- // When this data arrives (via stream frame w. FIN, or RST) this method
- // is called, and correctly updates the connection level flow controller.
- void UpdateFlowControlOnFinalReceivedByteOffset(
- QuicStreamId id, QuicStreamOffset final_byte_offset);
-
// Called in OnConfigNegotiated when we receive a new stream level flow
// control window in a negotiated config. Closes the connection if invalid.
void OnNewStreamFlowControlWindow(QuicStreamOffset new_window);
@@ -295,13 +351,15 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
// that create these streams.
StreamMap static_stream_map_;
- // Map from StreamId to pointers to streams that are owned by the caller.
+ // Map from StreamId to pointers to streams. Owns the streams.
StreamMap dynamic_stream_map_;
- QuicStreamId next_stream_id_;
- // Set of stream ids that have been "implicitly created" by receipt
- // of a stream id larger than the next expected stream id.
- base::hash_set<QuicStreamId> implicitly_created_streams_;
+ // The ID to use for the next outgoing stream.
+ QuicStreamId next_outgoing_stream_id_;
+
+ // Set of stream ids that are less than the largest stream id that has been
+ // received, but are nonetheless available to be created.
+ base::hash_set<QuicStreamId> available_streams_;
// Set of stream ids that are "draining" -- a FIN has been sent and received,
// but the stream object still exists because not all the received data has
@@ -313,15 +371,22 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
QuicStreamId largest_peer_created_stream_id_;
+ // A counter for peer initiated streams which are in the dynamic_stream_map_.
+ size_t num_dynamic_incoming_streams_;
+
+ // A counter for peer initiated streams which are in the draining_streams_.
+ size_t num_draining_incoming_streams_;
+
+ // A counter for peer initiated streams which are in the
+ // locally_closed_streams_highest_offset_.
+ size_t num_locally_closed_incoming_streams_highest_offset_;
+
// The latched error with which the connection was closed.
QuicErrorCode error_;
// Used for connection-level flow control.
QuicFlowController flow_controller_;
- // Indicate if there is pending data for the crypto stream.
- bool has_pending_handshake_;
-
DISALLOW_COPY_AND_ASSIGN(QuicSession);
};
diff --git a/chromium/net/quic/quic_session_test.cc b/chromium/net/quic/quic_session_test.cc
index c49936577ae..6d71a77d939 100644
--- a/chromium/net/quic/quic_session_test.cc
+++ b/chromium/net/quic/quic_session_test.cc
@@ -6,11 +6,11 @@
#include <set>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_crypto_stream.h"
#include "net/quic/quic_flags.h"
@@ -19,10 +19,10 @@
#include "net/quic/reliable_quic_stream.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_data_stream_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_spdy_session_peer.h"
+#include "net/quic/test_tools/quic_spdy_stream_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/reliable_quic_stream_peer.h"
#include "net/spdy/spdy_framer.h"
@@ -46,16 +46,13 @@ namespace net {
namespace test {
namespace {
-const QuicPriority kHighestPriority = 0;
-const QuicPriority kSomeMiddlePriority = 3;
+const SpdyPriority kHighestPriority = kV3HighestPriority;
class TestCryptoStream : public QuicCryptoStream {
public:
- explicit TestCryptoStream(QuicSession* session)
- : QuicCryptoStream(session) {
- }
+ explicit TestCryptoStream(QuicSession* session) : QuicCryptoStream(session) {}
- void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+ void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
encryption_established_ = true;
handshake_confirmed_ = true;
CryptoHandshakeMessage msg;
@@ -65,8 +62,8 @@ class TestCryptoStream : public QuicCryptoStream {
session()->config()->SetInitialSessionFlowControlWindowToSend(
kInitialSessionFlowControlWindowForTest);
session()->config()->ToHandshakeMessage(&msg);
- const QuicErrorCode error = session()->config()->ProcessPeerHello(
- msg, CLIENT, &error_details);
+ const QuicErrorCode error =
+ session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
EXPECT_EQ(QUIC_NO_ERROR, error);
session()->OnConfigNegotiated();
session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
@@ -83,10 +80,10 @@ class TestHeadersStream : public QuicHeadersStream {
MOCK_METHOD0(OnCanWrite, void());
};
-class TestStream : public QuicDataStream {
+class TestStream : public QuicSpdyStream {
public:
TestStream(QuicStreamId id, QuicSpdySession* session)
- : QuicDataStream(id, session) {}
+ : QuicSpdyStream(id, session) {}
using ReliableQuicStream::CloseWriteSide;
@@ -103,12 +100,14 @@ class TestStream : public QuicDataStream {
class StreamBlocker {
public:
StreamBlocker(QuicSession* session, QuicStreamId stream_id)
- : session_(session),
- stream_id_(stream_id) {
- }
+ : session_(session), stream_id_(stream_id) {}
void MarkConnectionLevelWriteBlocked() {
- session_->MarkConnectionLevelWriteBlocked(stream_id_, kSomeMiddlePriority);
+ session_->MarkConnectionLevelWriteBlocked(stream_id_, kDefaultPriority);
+ }
+
+ void MarkHighPriorityWriteBlocked() {
+ session_->MarkConnectionLevelWriteBlocked(stream_id_, kHighestPriority);
}
private:
@@ -127,16 +126,18 @@ class TestSession : public QuicSpdySession {
TestCryptoStream* GetCryptoStream() override { return &crypto_stream_; }
- TestStream* CreateOutgoingDynamicStream() override {
- TestStream* stream = new TestStream(GetNextStreamId(), this);
+ TestStream* CreateOutgoingDynamicStream(SpdyPriority priority) override {
+ TestStream* stream = new TestStream(GetNextOutgoingStreamId(), this);
+ stream->SetPriority(priority);
ActivateStream(stream);
return stream;
}
TestStream* CreateIncomingDynamicStream(QuicStreamId id) override {
// Enforce the limit on the number of open streams.
- if (GetNumOpenStreams() + 1 > get_max_open_streams()) {
- connection()->SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS);
+ if (GetNumOpenIncomingStreams() + 1 > get_max_open_streams()) {
+ connection()->SendConnectionCloseWithDetails(QUIC_TOO_MANY_OPEN_STREAMS,
+ "Too many streams!");
return nullptr;
} else {
return new TestStream(id, this);
@@ -147,24 +148,25 @@ class TestSession : public QuicSpdySession {
return QuicSession::IsClosedStream(id);
}
- ReliableQuicStream* GetIncomingDynamicStream(QuicStreamId stream_id) {
- return QuicSpdySession::GetIncomingDynamicStream(stream_id);
+ ReliableQuicStream* GetOrCreateDynamicStream(QuicStreamId stream_id) {
+ return QuicSpdySession::GetOrCreateDynamicStream(stream_id);
}
QuicConsumedData WritevData(
QuicStreamId id,
- const QuicIOVector& data,
+ QuicIOVector data,
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) override {
- // Always consumes everything.
- if (writev_consumes_all_data_) {
- return QuicConsumedData(data.total_length, fin);
- } else {
- return QuicSession::WritevData(id, data, offset, fin, fec_protection,
- ack_notifier_delegate);
+ QuicAckListenerInterface* ack_notifier_delegate) override {
+ QuicConsumedData consumed(data.total_length, fin);
+ if (!writev_consumes_all_data_) {
+ consumed = QuicSession::WritevData(id, data, offset, fin, fec_protection,
+ ack_notifier_delegate);
}
+ QuicSessionPeer::GetWriteBlockedStreams(this)
+ ->UpdateBytesForStream(id, consumed.bytes_consumed);
+ return consumed;
}
void set_writev_consumes_all_data(bool val) {
@@ -177,6 +179,15 @@ class TestSession : public QuicSpdySession {
MAY_FEC_PROTECT, nullptr);
}
+ QuicConsumedData SendLargeFakeData(QuicStreamId id, int bytes) {
+ DCHECK(writev_consumes_all_data_);
+ struct iovec iov;
+ iov.iov_base = nullptr; // should not be read.
+ iov.iov_len = static_cast<size_t>(bytes);
+ return WritevData(id, QuicIOVector(&iov, 1, bytes), 0, true,
+ MAY_FEC_PROTECT, nullptr);
+ }
+
using QuicSession::PostProcessAfterData;
private:
@@ -189,9 +200,11 @@ class QuicSessionTestBase : public ::testing::TestWithParam<QuicVersion> {
protected:
explicit QuicSessionTestBase(Perspective perspective)
: connection_(
- new StrictMock<MockConnection>(perspective,
+ new StrictMock<MockConnection>(&helper_,
+ perspective,
SupportedVersions(GetParam()))),
session_(connection_) {
+ FLAGS_quic_always_log_bugs_for_tests = true;
session_.config()->SetInitialStreamFlowControlWindowToSend(
kInitialStreamFlowControlWindowForTest);
session_.config()->SetInitialSessionFlowControlWindowToSend(
@@ -247,6 +260,7 @@ class QuicSessionTestBase : public ::testing::TestWithParam<QuicVersion> {
QuicVersion version() const { return connection_->version(); }
+ MockConnectionHelper helper_;
StrictMock<MockConnection>* connection_;
TestSession session_;
set<QuicStreamId> closed_streams_;
@@ -280,19 +294,19 @@ TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
}
}
-TEST_P(QuicSessionTestServer, ImplicitlyCreatedStreams) {
- ASSERT_TRUE(session_.GetIncomingDynamicStream(9) != nullptr);
- // Both 5 and 7 should be implicitly created.
- EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 5));
- EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 7));
- ASSERT_TRUE(session_.GetIncomingDynamicStream(7) != nullptr);
- ASSERT_TRUE(session_.GetIncomingDynamicStream(5) != nullptr);
+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();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_EQ(2u, stream2->id());
- TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_EQ(4u, stream4->id());
CheckClosedStreams();
@@ -305,95 +319,190 @@ TEST_P(QuicSessionTestServer, IsClosedStreamLocallyCreated) {
TEST_P(QuicSessionTestServer, IsClosedStreamPeerCreated) {
QuicStreamId stream_id1 = kClientDataStreamId1;
QuicStreamId stream_id2 = kClientDataStreamId2;
- session_.GetIncomingDynamicStream(stream_id1);
- session_.GetIncomingDynamicStream(stream_id2);
+ session_.GetOrCreateDynamicStream(stream_id1);
+ session_.GetOrCreateDynamicStream(stream_id2);
CheckClosedStreams();
CloseStream(stream_id1);
CheckClosedStreams();
CloseStream(stream_id2);
- // Create a stream explicitly, and another implicitly.
+ // Create a stream, and make another available.
ReliableQuicStream* stream3 =
- session_.GetIncomingDynamicStream(stream_id2 + 4);
+ session_.GetOrCreateDynamicStream(stream_id2 + 4);
CheckClosedStreams();
// Close one, but make sure the other is still not closed
CloseStream(stream3->id());
CheckClosedStreams();
}
-TEST_P(QuicSessionTestServer, MaximumImplicitlyOpenedStreams) {
+TEST_P(QuicSessionTestServer, MaximumAvailableOpenedStreams) {
QuicStreamId stream_id = kClientDataStreamId1;
- session_.GetIncomingDynamicStream(stream_id);
- EXPECT_CALL(*connection_, SendConnectionClose(_)).Times(0);
+ session_.GetOrCreateDynamicStream(stream_id);
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
EXPECT_NE(nullptr,
- session_.GetIncomingDynamicStream(
+ session_.GetOrCreateDynamicStream(
stream_id + 2 * (session_.get_max_open_streams() - 1)));
}
-TEST_P(QuicSessionTestServer, TooManyImplicitlyOpenedStreams) {
+TEST_P(QuicSessionTestServer, TooManyAvailableStreams) {
QuicStreamId stream_id1 = kClientDataStreamId1;
+ QuicStreamId stream_id2;
+ EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id1));
// A stream ID which is too large to create.
- QuicStreamId stream_id2 = stream_id1 + 2 * session_.get_max_open_streams();
- EXPECT_NE(nullptr, session_.GetIncomingDynamicStream(stream_id1));
- EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
- EXPECT_EQ(nullptr, session_.GetIncomingDynamicStream(stream_id2));
+ stream_id2 = stream_id1 + 2 * session_.get_max_available_streams() + 4;
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_TOO_MANY_AVAILABLE_STREAMS, _));
+ EXPECT_EQ(nullptr, session_.GetOrCreateDynamicStream(stream_id2));
}
-TEST_P(QuicSessionTestServer, ManyImplicitlyOpenedStreams) {
+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::SetMaxOpenStreams(&session_, 200);
QuicStreamId stream_id = kClientDataStreamId1;
// Create one stream.
- session_.GetIncomingDynamicStream(stream_id);
- EXPECT_CALL(*connection_, SendConnectionClose(_)).Times(0);
+ session_.GetOrCreateDynamicStream(stream_id);
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
// Create the largest stream ID of a threatened total of 200 streams.
- session_.GetIncomingDynamicStream(stream_id + 2 * (200 - 1));
+ session_.GetOrCreateDynamicStream(stream_id + 2 * (200 - 1));
}
TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
QuicStreamId closed_stream_id = stream2->id();
// Close the stream.
EXPECT_CALL(*connection_, SendRstStream(closed_stream_id, _, _));
stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
EXPECT_DEBUG_DFATAL(session_.MarkConnectionLevelWriteBlocked(
- closed_stream_id, kSomeMiddlePriority),
+ closed_stream_id, kDefaultPriority),
"Marking unknown stream 2 blocked.");
}
TEST_P(QuicSessionTestServer,
DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) {
- const QuicPriority kDifferentPriority = 0;
+ const SpdyPriority kDifferentPriority = 0;
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
- EXPECT_NE(kDifferentPriority, stream2->EffectivePriority());
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ EXPECT_NE(kDifferentPriority, stream2->Priority());
EXPECT_DEBUG_DFATAL(session_.MarkConnectionLevelWriteBlocked(
stream2->id(), kDifferentPriority),
"Priorities do not match. Got: 0 Expected: 3");
}
TEST_P(QuicSessionTestServer, OnCanWrite) {
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
- TestStream* stream4 = session_.CreateOutgoingDynamicStream();
- TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
- session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream6->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream4->id(), kSomeMiddlePriority);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream6->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id(), kDefaultPriority);
InSequence s;
StreamBlocker stream2_blocker(&session_, stream2->id());
- // Reregister, to test the loop limit.
- EXPECT_CALL(*stream2, OnCanWrite())
- .WillOnce(Invoke(&stream2_blocker,
- &StreamBlocker::MarkConnectionLevelWriteBlocked));
- EXPECT_CALL(*stream6, OnCanWrite());
- EXPECT_CALL(*stream4, OnCanWrite());
+
+ if (FLAGS_quic_batch_writes) {
+ // Reregister, to test the loop limit.
+ EXPECT_CALL(*stream2, OnCanWrite())
+ .WillOnce(Invoke(&stream2_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked));
+ // 2 will get called a second time as it didn't finish its block
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream6, OnCanWrite());
+ // 4 will not get called, as we exceeded the loop limit.
+ } else {
+ // Reregister, to test the loop limit.
+ EXPECT_CALL(*stream2, OnCanWrite())
+ .WillOnce(Invoke(&stream2_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked));
+ EXPECT_CALL(*stream6, OnCanWrite());
+ EXPECT_CALL(*stream4, OnCanWrite());
+ }
session_.OnCanWrite();
EXPECT_TRUE(session_.WillingAndAbleToWrite());
}
+TEST_P(QuicSessionTestServer, TestBatchedWrites) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_batch_writes, true);
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+
+ session_.set_writev_consumes_all_data(true);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id(), kDefaultPriority);
+
+ StreamBlocker stream2_blocker(&session_, stream2->id());
+ StreamBlocker stream4_blocker(&session_, stream4->id());
+ StreamBlocker stream6_blocker(&session_, stream6->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(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData,
+ stream2->id(), 6000))),
+ Invoke(&stream2_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked)));
+ EXPECT_CALL(*stream2, OnCanWrite())
+ .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData,
+ stream2->id(), 6000))),
+ Invoke(&stream2_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked)));
+ 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(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData,
+ stream2->id(), 6000))),
+ Invoke(&stream2_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked)));
+ EXPECT_CALL(*stream4, OnCanWrite())
+ .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData,
+ stream4->id(), 6000))),
+ Invoke(&stream4_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked)));
+ 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(kHighestPriority);
+ EXPECT_CALL(*stream4, OnCanWrite())
+ .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData,
+ stream4->id(), 6000))),
+ Invoke(&stream4_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked),
+ Invoke(&stream6_blocker,
+ &StreamBlocker::MarkHighPriorityWriteBlocked)));
+ EXPECT_CALL(*stream6, OnCanWrite())
+ .WillOnce(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData, stream4->id(), 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(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData,
+ stream4->id(), 12000))),
+ Invoke(&stream4_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked)));
+ EXPECT_CALL(*stream2, OnCanWrite())
+ .WillOnce(DoAll(testing::IgnoreResult(Invoke(CreateFunctor(
+ &session_, &TestSession::SendLargeFakeData,
+ stream2->id(), 6000))),
+ Invoke(&stream2_blocker,
+ &StreamBlocker::MarkConnectionLevelWriteBlocked)));
+ session_.OnCanWrite();
+}
+
TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
// Encryption needs to be established before data can be sent.
CryptoHandshakeMessage msg;
@@ -403,16 +512,16 @@ TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
- TestStream* stream4 = session_.CreateOutgoingDynamicStream();
- TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
- session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream6->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream4->id(), kSomeMiddlePriority);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream6->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id(), kDefaultPriority);
- EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillRepeatedly(
- Return(QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _))
+ .WillRepeatedly(Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*send_algorithm, GetCongestionWindow())
.WillRepeatedly(Return(kMaxPacketSize * 10));
EXPECT_CALL(*stream2, OnCanWrite())
@@ -427,12 +536,11 @@ TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
// Expect that we only send one packet, the writes from different streams
// should be bundled together.
- MockPacketWriter* writer =
- static_cast<MockPacketWriter*>(
- QuicConnectionPeer::GetWriter(session_.connection()));
- EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce(
- Return(WriteResult(WRITE_STATUS_OK, 0)));
- EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)).Times(1);
+ MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+ QuicConnectionPeer::GetWriter(session_.connection()));
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _))
+ .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+ EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
session_.OnCanWrite();
EXPECT_FALSE(session_.WillingAndAbleToWrite());
}
@@ -444,38 +552,38 @@ TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
- TestStream* stream4 = session_.CreateOutgoingDynamicStream();
- TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
- session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream6->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream4->id(), kSomeMiddlePriority);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream6->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id(), kDefaultPriority);
StreamBlocker stream2_blocker(&session_, stream2->id());
- EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*stream2, OnCanWrite());
- EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*stream6, OnCanWrite());
- EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Infinite()));
+ EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Infinite()));
// stream4->OnCanWrite is not called.
session_.OnCanWrite();
EXPECT_TRUE(session_.WillingAndAbleToWrite());
// Still congestion-control blocked.
- EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Infinite()));
+ EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Infinite()));
session_.OnCanWrite();
EXPECT_TRUE(session_.WillingAndAbleToWrite());
// stream4->OnCanWrite is called once the connection stops being
// congestion-control blocked.
- EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
- QuicTime::Delta::Zero()));
+ EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _))
+ .WillOnce(Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*stream4, OnCanWrite());
session_.OnCanWrite();
EXPECT_FALSE(session_.WillingAndAbleToWrite());
@@ -485,12 +593,12 @@ TEST_P(QuicSessionTestServer, BufferedHandshake) {
EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
// Test that blocking other streams does not change our status.
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
StreamBlocker stream2_blocker(&session_, stream2->id());
stream2_blocker.MarkConnectionLevelWriteBlocked();
EXPECT_FALSE(session_.HasPendingHandshake());
- TestStream* stream3 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream3 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
StreamBlocker stream3_blocker(&session_, stream3->id());
stream3_blocker.MarkConnectionLevelWriteBlocked();
EXPECT_FALSE(session_.HasPendingHandshake());
@@ -499,7 +607,7 @@ TEST_P(QuicSessionTestServer, BufferedHandshake) {
session_.MarkConnectionLevelWriteBlocked(kCryptoStreamId, kHighestPriority);
EXPECT_TRUE(session_.HasPendingHandshake());
- TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
StreamBlocker stream4_blocker(&session_, stream4->id());
stream4_blocker.MarkConnectionLevelWriteBlocked();
EXPECT_TRUE(session_.HasPendingHandshake());
@@ -514,13 +622,8 @@ TEST_P(QuicSessionTestServer, BufferedHandshake) {
TestCryptoStream* crypto_stream = session_.GetCryptoStream();
EXPECT_CALL(*crypto_stream, OnCanWrite());
- // Re-register all other streams, to show they weren't able to proceed.
- EXPECT_CALL(*stream2, OnCanWrite())
- .WillOnce(Invoke(&stream2_blocker,
- &StreamBlocker::MarkConnectionLevelWriteBlocked));
- EXPECT_CALL(*stream3, OnCanWrite())
- .WillOnce(Invoke(&stream3_blocker,
- &StreamBlocker::MarkConnectionLevelWriteBlocked));
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream3, OnCanWrite());
EXPECT_CALL(*stream4, OnCanWrite())
.WillOnce(Invoke(&stream4_blocker,
&StreamBlocker::MarkConnectionLevelWriteBlocked));
@@ -531,13 +634,13 @@ TEST_P(QuicSessionTestServer, BufferedHandshake) {
}
TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
- TestStream* stream4 = session_.CreateOutgoingDynamicStream();
- TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
- session_.MarkConnectionLevelWriteBlocked(stream2->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream6->id(), kSomeMiddlePriority);
- session_.MarkConnectionLevelWriteBlocked(stream4->id(), kSomeMiddlePriority);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream6->id(), kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id(), kDefaultPriority);
CloseStream(stream6->id());
InSequence s;
@@ -561,17 +664,17 @@ TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
// 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(), kSomeMiddlePriority);
+ TestStream* stream = session_.CreateOutgoingDynamicStream(kDefaultPriority);
+ session_.MarkConnectionLevelWriteBlocked(stream->id(), kDefaultPriority);
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_.GetCryptoStream();
- EXPECT_CALL(*crypto_stream, OnCanWrite()).Times(1);
+ EXPECT_CALL(*crypto_stream, OnCanWrite());
TestHeadersStream* headers_stream = new TestHeadersStream(&session_);
QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
- EXPECT_CALL(*headers_stream, OnCanWrite()).Times(1);
+ EXPECT_CALL(*headers_stream, OnCanWrite());
session_.OnCanWrite();
EXPECT_FALSE(session_.WillingAndAbleToWrite());
@@ -591,7 +694,7 @@ TEST_P(QuicSessionTestServer, SendGoAway) {
EXPECT_CALL(*connection_,
SendRstStream(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY, 0))
.Times(0);
- EXPECT_TRUE(session_.GetIncomingDynamicStream(kTestStreamId));
+ EXPECT_TRUE(session_.GetOrCreateDynamicStream(kTestStreamId));
}
TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
@@ -607,12 +710,13 @@ TEST_P(QuicSessionTestServer, RstStreamBeforeHeadersDecompressed) {
// Send two bytes of payload.
QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
session_.OnStreamFrame(data1);
- EXPECT_EQ(1u, session_.GetNumOpenStreams());
+ EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1, _, _));
- QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
+ QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_ERROR_PROCESSING_STREAM,
+ 0);
session_.OnRstStream(rst1);
- EXPECT_EQ(0u, session_.GetNumOpenStreams());
+ EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
// Connection should remain alive.
EXPECT_TRUE(connection_->connected());
}
@@ -625,12 +729,13 @@ TEST_P(QuicSessionTestServer, MultipleRstStreamsCauseSingleConnectionClose) {
// Create valid stream.
QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
session_.OnStreamFrame(data1);
- EXPECT_EQ(1u, session_.GetNumOpenStreams());
+ EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
// Process first invalid stream reset, resulting in the connection being
// closed.
- EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS))
- .Times(1);
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_TOO_MANY_AVAILABLE_STREAMS, _));
+
const QuicStreamId kLargeInvalidStreamId = 99999999;
QuicRstStreamFrame rst1(kLargeInvalidStreamId, QUIC_STREAM_NO_ERROR, 0);
session_.OnRstStream(rst1);
@@ -651,7 +756,7 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
session_.set_writev_consumes_all_data(true);
// Create a stream, and send enough data to make it flow control blocked.
- TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority);
string body(kMinimumFlowControlSendWindow, '.');
EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
@@ -722,6 +827,12 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
}
+#if !defined(OS_IOS)
+// This test is failing flakily for iOS bots.
+// http://crbug.com/425050
+// 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,
HandshakeUnblocksFlowControlBlockedHeadersStream) {
// Test that if the header stream is flow control blocked, then if the SHLO
@@ -744,8 +855,8 @@ TEST_P(QuicSessionTestServer,
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
headers["header"] = base::Uint64ToString(base::RandUint64()) +
- base::Uint64ToString(base::RandUint64()) +
- base::Uint64ToString(base::RandUint64());
+ base::Uint64ToString(base::RandUint64()) +
+ base::Uint64ToString(base::RandUint64());
headers_stream->WriteHeaders(stream_id, headers, true, 0, nullptr);
stream_id += 2;
}
@@ -771,13 +882,14 @@ TEST_P(QuicSessionTestServer,
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
EXPECT_FALSE(headers_stream->HasBufferedData());
}
+#endif // !defined(OS_IOS)
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();
+ TestStream* stream = session_.CreateOutgoingDynamicStream(kDefaultPriority);
const QuicStreamOffset kByteOffset =
1 + kInitialSessionFlowControlWindowForTest / 2;
@@ -786,8 +898,8 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
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)).Times(1);
+ SendWindowUpdate(
+ 0, kInitialSessionFlowControlWindowForTest + kByteOffset));
EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED,
@@ -803,7 +915,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
// 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();
+ TestStream* stream = session_.CreateOutgoingDynamicStream(kDefaultPriority);
const QuicStreamOffset kByteOffset =
kInitialSessionFlowControlWindowForTest / 2;
@@ -829,8 +941,8 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
// Connection starts with some non-zero highest received byte offset,
// due to other active streams.
- const uint64 kInitialConnectionBytesConsumed = 567;
- const uint64 kInitialConnectionHighestReceivedOffset = 1234;
+ const uint64_t kInitialConnectionBytesConsumed = 567;
+ const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
EXPECT_LT(kInitialConnectionBytesConsumed,
kInitialConnectionHighestReceivedOffset);
session_.flow_controller()->UpdateHighestReceivedOffset(
@@ -838,7 +950,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
// Reset our stream: this results in the stream being closed locally.
- TestStream* stream = session_.CreateOutgoingDynamicStream();
+ TestStream* stream = session_.CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
stream->Reset(QUIC_STREAM_CANCELLED);
@@ -866,8 +978,8 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
// Connection starts with some non-zero highest received byte offset,
// due to other active streams.
- const uint64 kInitialConnectionBytesConsumed = 567;
- const uint64 kInitialConnectionHighestReceivedOffset = 1234;
+ const uint64_t kInitialConnectionBytesConsumed = 567;
+ const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
EXPECT_LT(kInitialConnectionBytesConsumed,
kInitialConnectionHighestReceivedOffset);
session_.flow_controller()->UpdateHighestReceivedOffset(
@@ -875,9 +987,10 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
// Reset our stream: this results in the stream being closed locally.
- TestStream* stream = session_.CreateOutgoingDynamicStream();
+ TestStream* stream = session_.CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
stream->Reset(QUIC_STREAM_CANCELLED);
+ EXPECT_TRUE(ReliableQuicStreamPeer::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
@@ -896,37 +1009,37 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
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 kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+ const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
kInvalidWindow);
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW));
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ 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 kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+ const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
kInvalidWindow);
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW));
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_INVALID_WINDOW, _));
session_.OnConfigNegotiated();
}
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 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA))
+ const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _))
.Times(2);
// Check that stream frame + FIN results in connection close.
- TestStream* stream = session_.CreateOutgoingDynamicStream();
+ TestStream* stream = session_.CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
stream->Reset(QUIC_STREAM_CANCELLED);
QuicStreamFrame frame(stream->id(), true, kLargeOffset, StringPiece());
@@ -960,30 +1073,40 @@ TEST_P(QuicSessionTestServer, WindowUpdateUnblocksHeadersStream) {
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
}
-TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseConnectionClose) {
- // If a buggy/malicious peer creates too many streams that are not ended with
- // a FIN or RST then we send a connection close.
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)).Times(1);
-
+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 a connection close or an RST to
+ // refuse streams.
const QuicStreamId kMaxStreams = 5;
QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
+ const QuicStreamId kFirstStreamId = kClientDataStreamId1;
+ const QuicStreamId kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams;
- // Create kMaxStreams + 1 data streams, and close them all without receiving a
+ // Create kMaxStreams data streams, and close them all without receiving a
// FIN or a RST_STREAM from the client.
- const QuicStreamId kFirstStreamId = kClientDataStreamId1;
- const QuicStreamId kFinalStreamId =
- kClientDataStreamId1 + 2 * kMaxStreams + 1;
for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) {
QuicStreamFrame data1(i, false, 0, StringPiece("HT"));
session_.OnStreamFrame(data1);
- EXPECT_EQ(1u, session_.GetNumOpenStreams());
+ // EXPECT_EQ(1u, session_.GetNumOpenStreams());
EXPECT_CALL(*connection_, SendRstStream(i, _, _));
session_.CloseStream(i);
}
- // Called after any new data is received by the session, and triggers the call
- // to close the connection.
+ if (GetParam() <= QUIC_VERSION_27) {
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(QUIC_TOO_MANY_OPEN_STREAMS, _));
+ EXPECT_CALL(*connection_, SendRstStream(kFinalStreamId, _, _)).Times(0);
+ } else {
+ EXPECT_CALL(*connection_,
+ SendRstStream(kFinalStreamId, QUIC_REFUSED_STREAM, _))
+ .Times(1);
+ }
+ // Create one more data streams to exceed limit of open stream.
+ QuicStreamFrame data1(kFinalStreamId, false, 0, StringPiece("HT"));
+ session_.OnStreamFrame(data1);
+
+ // Called after any new data is received by the session, and triggers the
+ // call to close the connection.
session_.PostProcessAfterData();
}
@@ -991,9 +1114,14 @@ 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_,
- SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)).Times(0);
-
+ if (GetParam() <= QUIC_VERSION_27) {
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(QUIC_TOO_MANY_OPEN_STREAMS, _))
+ .Times(0);
+ } else {
+ EXPECT_CALL(*connection_, SendRstStream(_, QUIC_REFUSED_STREAM, _))
+ .Times(0);
+ }
const QuicStreamId kMaxStreams = 5;
QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
@@ -1004,9 +1132,9 @@ TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) {
QuicStreamFrame data1(i, true, 0, StringPiece("HT"));
session_.OnStreamFrame(data1);
- EXPECT_EQ(1u, session_.GetNumOpenStreams());
+ EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
session_.StreamDraining(i);
- EXPECT_EQ(0u, session_.GetNumOpenStreams());
+ EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
}
// Called after any new data is received by the session, and triggers the call
@@ -1023,15 +1151,47 @@ INSTANTIATE_TEST_CASE_P(Tests,
QuicSessionTestClient,
::testing::ValuesIn(QuicSupportedVersions()));
-TEST_P(QuicSessionTestClient, ImplicitlyCreatedStreamsClient) {
- ASSERT_TRUE(session_.GetIncomingDynamicStream(6) != nullptr);
- // Both 2 and 4 should be implicitly created.
- EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 2));
- EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 4));
- ASSERT_TRUE(session_.GetIncomingDynamicStream(2) != nullptr);
- ASSERT_TRUE(session_.GetIncomingDynamicStream(4) != nullptr);
- // And 5 should be not implicitly created.
- EXPECT_FALSE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 5));
+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(kDefaultPriority);
+ QuicStreamId stream_id = stream->id();
+
+ // Close the read side manually.
+ ReliableQuicStreamPeer::CloseReadSide(stream);
+
+ // Receive a stream data frame with FIN.
+ QuicStreamFrame frame(stream_id, true, 0, StringPiece());
+ session_.OnStreamFrame(frame);
+ EXPECT_TRUE(stream->fin_received());
+
+ // Reset stream locally.
+ EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
+ stream->Reset(QUIC_STREAM_CANCELLED);
+ EXPECT_TRUE(ReliableQuicStreamPeer::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_EQ(nullptr, QuicSessionPeer::dynamic_streams(&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());
}
} // namespace
diff --git a/chromium/net/quic/quic_simple_buffer_allocator.cc b/chromium/net/quic/quic_simple_buffer_allocator.cc
new file mode 100644
index 00000000000..5dae280d7e3
--- /dev/null
+++ b/chromium/net/quic/quic_simple_buffer_allocator.cc
@@ -0,0 +1,17 @@
+// 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/quic_simple_buffer_allocator.h"
+
+namespace net {
+
+char* SimpleBufferAllocator::New(size_t size) {
+ return new char[size];
+}
+
+void SimpleBufferAllocator::Delete(char* buffer) {
+ delete[] buffer;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/quic_simple_buffer_allocator.h b/chromium/net/quic/quic_simple_buffer_allocator.h
new file mode 100644
index 00000000000..171f6b0d099
--- /dev/null
+++ b/chromium/net/quic/quic_simple_buffer_allocator.h
@@ -0,0 +1,20 @@
+// 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_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
+#define NET_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
+
+#include "net/quic/quic_protocol.h"
+
+namespace net {
+
+class NET_EXPORT_PRIVATE SimpleBufferAllocator : public QuicBufferAllocator {
+ public:
+ char* New(size_t size) override;
+ void Delete(char* buffer) override;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
diff --git a/chromium/net/quic/quic_simple_buffer_allocator_test.cc b/chromium/net/quic/quic_simple_buffer_allocator_test.cc
new file mode 100644
index 00000000000..3129b9608c8
--- /dev/null
+++ b/chromium/net/quic/quic_simple_buffer_allocator_test.cc
@@ -0,0 +1,35 @@
+// 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/quic_simple_buffer_allocator.h"
+
+#include "net/quic/quic_protocol.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::Eq;
+
+namespace net {
+namespace {
+
+TEST(SimpleBufferAllocatorTest, NewDelete) {
+ SimpleBufferAllocator alloc;
+ char* buf = alloc.New(4);
+ EXPECT_NE(nullptr, buf);
+ alloc.Delete(buf);
+}
+
+TEST(SimpleBufferAllocatorTest, DeleteNull) {
+ SimpleBufferAllocator alloc;
+ alloc.Delete(nullptr);
+}
+
+TEST(SimpleBufferAllocatorTest, StoreInUniqueStreamBuffer) {
+ SimpleBufferAllocator alloc;
+ UniqueStreamBuffer buf = NewStreamBuffer(&alloc, 4);
+ buf.reset();
+}
+
+} // namespace
+} // namespace net
diff --git a/chromium/net/quic/quic_socket_address_coder.cc b/chromium/net/quic/quic_socket_address_coder.cc
index 5dba82107f5..bd28353e864 100644
--- a/chromium/net/quic/quic_socket_address_coder.cc
+++ b/chromium/net/quic/quic_socket_address_coder.cc
@@ -14,24 +14,21 @@ namespace {
// For convenience, the values of these constants match the values of AF_INET
// and AF_INET6 on Linux.
-const uint16 kIPv4 = 2;
-const uint16 kIPv6 = 10;
+const uint16_t kIPv4 = 2;
+const uint16_t kIPv6 = 10;
} // namespace
-QuicSocketAddressCoder::QuicSocketAddressCoder() {
-}
+QuicSocketAddressCoder::QuicSocketAddressCoder() {}
QuicSocketAddressCoder::QuicSocketAddressCoder(const IPEndPoint& address)
- : address_(address) {
-}
+ : address_(address) {}
-QuicSocketAddressCoder::~QuicSocketAddressCoder() {
-}
+QuicSocketAddressCoder::~QuicSocketAddressCoder() {}
string QuicSocketAddressCoder::Encode() const {
string serialized;
- uint16 address_family;
+ uint16_t address_family;
switch (address_.GetSockAddrFamily()) {
case AF_INET:
address_family = kIPv4;
@@ -45,13 +42,13 @@ string QuicSocketAddressCoder::Encode() const {
serialized.append(reinterpret_cast<const char*>(&address_family),
sizeof(address_family));
serialized.append(IPAddressToPackedString(address_.address()));
- uint16 port = address_.port();
+ uint16_t port = address_.port();
serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
return serialized;
}
bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
- uint16 address_family;
+ uint16_t address_family;
if (length < sizeof(address_family)) {
return false;
}
@@ -78,7 +75,7 @@ bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
data += ip_length;
length -= ip_length;
- uint16 port;
+ uint16_t port;
if (length != sizeof(port)) {
return false;
}
diff --git a/chromium/net/quic/quic_socket_address_coder.h b/chromium/net/quic/quic_socket_address_coder.h
index 36ad1d03620..0b620ba9a0a 100644
--- a/chromium/net/quic/quic_socket_address_coder.h
+++ b/chromium/net/quic/quic_socket_address_coder.h
@@ -5,9 +5,12 @@
#ifndef NET_QUIC_QUIC_SOCKET_ADDRESS_CODER_H_
#define NET_QUIC_QUIC_SOCKET_ADDRESS_CODER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
@@ -26,13 +29,9 @@ class NET_EXPORT_PRIVATE QuicSocketAddressCoder {
bool Decode(const char* data, size_t length);
- IPAddressNumber ip() const {
- return address_.address();
- }
+ IPAddressNumber ip() const { return address_.address(); }
- uint16 port() const {
- return address_.port();
- }
+ uint16_t port() const { return address_.port(); }
private:
IPEndPoint address_;
diff --git a/chromium/net/quic/quic_socket_address_coder_test.cc b/chromium/net/quic/quic_socket_address_coder_test.cc
index 6a94550d8e0..79624938df3 100644
--- a/chromium/net/quic/quic_socket_address_coder_test.cc
+++ b/chromium/net/quic/quic_socket_address_coder_test.cc
@@ -4,7 +4,6 @@
#include "net/quic/quic_socket_address_coder.h"
-#include "net/base/net_util.h"
#include "net/base/sys_addrinfo.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,10 +26,12 @@ TEST(QuicSocketAddressCoderTest, EncodeIPv6) {
ASSERT_TRUE(ParseIPLiteralToNumber("2001:700:300:1800::f", &ip));
QuicSocketAddressCoder coder(IPEndPoint(ip, 0x5678));
string serialized = coder.Encode();
- string expected("\x0a\x00"
- "\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f"
- "\x78\x56", 20);
+ string expected(
+ "\x0a\x00"
+ "\x20\x01\x07\x00\x03\x00\x18\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x0f"
+ "\x78\x56",
+ 20);
EXPECT_EQ(expected, serialized);
}
@@ -45,24 +46,30 @@ TEST(QuicSocketAddressCoderTest, DecodeIPv4) {
}
TEST(QuicSocketAddressCoderTest, DecodeIPv6) {
- string serialized("\x0a\x00"
- "\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f"
- "\x78\x56", 20);
+ string serialized(
+ "\x0a\x00"
+ "\x20\x01\x07\x00\x03\x00\x18\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x0f"
+ "\x78\x56",
+ 20);
QuicSocketAddressCoder coder;
ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
EXPECT_EQ(AF_INET6, ConvertAddressFamily(GetAddressFamily(coder.ip())));
- string expected_addr("\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f", 16);
+ string expected_addr(
+ "\x20\x01\x07\x00\x03\x00\x18\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x0f",
+ 16);
EXPECT_EQ(expected_addr, IPAddressToPackedString(coder.ip()));
EXPECT_EQ(0x5678, coder.port());
}
TEST(QuicSocketAddressCoderTest, DecodeBad) {
- string serialized("\x0a\x00"
- "\x20\x01\x07\x00\x03\x00\x18\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x0f"
- "\x78\x56", 20);
+ string serialized(
+ "\x0a\x00"
+ "\x20\x01\x07\x00\x03\x00\x18\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x0f"
+ "\x78\x56",
+ 20);
QuicSocketAddressCoder coder;
EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
// Append junk.
@@ -92,14 +99,14 @@ TEST(QuicSocketAddressCoderTest, DecodeBad) {
TEST(QuicSocketAddressCoderTest, EncodeAndDecode) {
struct {
const char* ip_literal;
- uint16 port;
+ uint16_t port;
} test_case[] = {
- { "93.184.216.119", 0x1234 },
- { "199.204.44.194", 80 },
- { "149.20.4.69", 443 },
- { "127.0.0.1", 8080 },
- { "2001:700:300:1800::", 0x5678 },
- { "::1", 65534 },
+ {"93.184.216.119", 0x1234},
+ {"199.204.44.194", 80},
+ {"149.20.4.69", 443},
+ {"127.0.0.1", 8080},
+ {"2001:700:300:1800::", 0x5678},
+ {"::1", 65534},
};
for (size_t i = 0; i < arraysize(test_case); i++) {
diff --git a/chromium/net/quic/quic_spdy_session.cc b/chromium/net/quic/quic_spdy_session.cc
index 0a8dda6929e..fc420baf555 100644
--- a/chromium/net/quic/quic_spdy_session.cc
+++ b/chromium/net/quic/quic_spdy_session.cc
@@ -4,17 +4,16 @@
#include "net/quic/quic_spdy_session.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_headers_stream.h"
namespace net {
QuicSpdySession::QuicSpdySession(QuicConnection* connection,
const QuicConfig& config)
- : QuicSession(connection, config) {
-}
+ : QuicSession(connection, config) {}
-QuicSpdySession::~QuicSpdySession() {
-}
+QuicSpdySession::~QuicSpdySession() {}
void QuicSpdySession::Initialize() {
QuicSession::Initialize();
@@ -22,7 +21,7 @@ void QuicSpdySession::Initialize() {
if (perspective() == Perspective::IS_SERVER) {
set_largest_peer_created_stream_id(kHeadersStreamId);
} else {
- QuicStreamId headers_stream_id = GetNextStreamId();
+ QuicStreamId headers_stream_id = GetNextOutgoingStreamId();
DCHECK_EQ(headers_stream_id, kHeadersStreamId);
}
@@ -33,7 +32,7 @@ void QuicSpdySession::Initialize() {
void QuicSpdySession::OnStreamHeaders(QuicStreamId stream_id,
StringPiece headers_data) {
- QuicDataStream* stream = GetSpdyDataStream(stream_id);
+ QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
if (!stream) {
// It's quite possible to receive headers after a stream has been reset.
return;
@@ -42,8 +41,8 @@ void QuicSpdySession::OnStreamHeaders(QuicStreamId stream_id,
}
void QuicSpdySession::OnStreamHeadersPriority(QuicStreamId stream_id,
- QuicPriority priority) {
- QuicDataStream* stream = GetSpdyDataStream(stream_id);
+ SpdyPriority priority) {
+ QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
if (!stream) {
// It's quite possible to receive headers after a stream has been reset.
return;
@@ -54,7 +53,7 @@ void QuicSpdySession::OnStreamHeadersPriority(QuicStreamId stream_id,
void QuicSpdySession::OnStreamHeadersComplete(QuicStreamId stream_id,
bool fin,
size_t frame_len) {
- QuicDataStream* stream = GetSpdyDataStream(stream_id);
+ QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
if (!stream) {
// It's quite possible to receive headers after a stream has been reset.
return;
@@ -66,15 +65,46 @@ size_t QuicSpdySession::WriteHeaders(
QuicStreamId id,
const SpdyHeaderBlock& headers,
bool fin,
- QuicPriority priority,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
+ SpdyPriority priority,
+ QuicAckListenerInterface* ack_notifier_delegate) {
return headers_stream_->WriteHeaders(id, headers, fin, priority,
ack_notifier_delegate);
}
-QuicDataStream* QuicSpdySession::GetSpdyDataStream(
+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<QuicDataStream*>(GetDynamicStream(stream_id));
+ return static_cast<QuicSpdyStream*>(GetOrCreateDynamicStream(stream_id));
+}
+
+void QuicSpdySession::OnPromiseHeaders(QuicStreamId stream_id,
+ StringPiece headers_data) {
+ QUIC_BUG << "OnPromiseHeaders should be overriden in client code.";
+ connection()->CloseConnection(QUIC_INTERNAL_ERROR, false);
+}
+
+void QuicSpdySession::OnPromiseHeadersComplete(QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len) {
+ QUIC_BUG << "OnPromiseHeadersComplete shoule be overriden in client code.";
+ connection()->CloseConnection(QUIC_INTERNAL_ERROR, false);
}
} // namespace net
diff --git a/chromium/net/quic/quic_spdy_session.h b/chromium/net/quic/quic_spdy_session.h
index b59eb63aa0e..246a6defb82 100644
--- a/chromium/net/quic/quic_spdy_session.h
+++ b/chromium/net/quic/quic_spdy_session.h
@@ -5,11 +5,12 @@
#ifndef NET_QUIC_QUIC_SPDY_SESSION_H_
#define NET_QUIC_QUIC_SPDY_SESSION_H_
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "net/quic/quic_data_stream.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/quic_headers_stream.h"
#include "net/quic/quic_session.h"
+#include "net/quic/quic_spdy_stream.h"
namespace net {
@@ -33,7 +34,7 @@ class NET_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
// received for this stream. This method will only be called for server
// streams.
virtual void OnStreamHeadersPriority(QuicStreamId stream_id,
- QuicPriority priority);
+ SpdyPriority priority);
// Called by |headers_stream_| when headers have been completely received
// for a stream. |fin| will be true if the fin flag was set in the headers
// frame.
@@ -41,27 +42,52 @@ class NET_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
bool fin,
size_t frame_len);
+ // Called by |headers_stream_| when push promise headers have been
+ // received for a stream.
+ virtual void OnPromiseHeaders(QuicStreamId stream_id,
+ StringPiece headers_data);
+
+ // Called by |headers_stream_| when push promise headers have been
+ // completely received. |fin| will be true if the fin flag was set
+ // in the headers.
+ virtual void OnPromiseHeadersComplete(QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len);
+
// Writes |headers| for the stream |id| to the dedicated headers stream.
// If |fin| is true, then no more data will be sent for the stream |id|.
// If provided, |ack_notifier_delegate| will be registered to be notified when
// we have seen ACKs for all packets resulting from this call.
- size_t WriteHeaders(
- QuicStreamId id,
- const SpdyHeaderBlock& headers,
- bool fin,
- QuicPriority priority,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
+ virtual size_t WriteHeaders(QuicStreamId id,
+ const SpdyHeaderBlock& headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicAckListenerInterface* ack_notifier_delegate);
QuicHeadersStream* headers_stream() { return headers_stream_.get(); }
+ // Called when Head of Line Blocking happens in the headers stream.
+ // |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.
+ void RegisterStreamPriority(QuicStreamId id, SpdyPriority priority);
+ // Called by the stream on deletion to clear priority crom the write blocked
+ // list.
+ void UnregisterStreamPriority(QuicStreamId id);
+ // Called by the stream on SetPriority to update priority on the write blocked
+ // list.
+ void UpdateStreamPriority(QuicStreamId id, SpdyPriority new_priority);
+
protected:
// Override CreateIncomingDynamicStream() and CreateOutgoingDynamicStream()
- // with QuicDataStream return type to make sure that all data streams are
- // QuicDataStreams.
- QuicDataStream* CreateIncomingDynamicStream(QuicStreamId id) override = 0;
- QuicDataStream* CreateOutgoingDynamicStream() override = 0;
+ // with QuicSpdyStream return type to make sure that all data streams are
+ // QuicSpdyStreams.
+ QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override = 0;
+ QuicSpdyStream* CreateOutgoingDynamicStream(SpdyPriority priority) override =
+ 0;
- QuicDataStream* GetSpdyDataStream(const QuicStreamId stream_id);
+ QuicSpdyStream* GetSpdyDataStream(const QuicStreamId stream_id);
private:
friend class test::QuicSpdySessionPeer;
diff --git a/chromium/net/quic/quic_spdy_stream.cc b/chromium/net/quic/quic_spdy_stream.cc
new file mode 100644
index 00000000000..394bea13f88
--- /dev/null
+++ b/chromium/net/quic/quic_spdy_stream.cc
@@ -0,0 +1,264 @@
+// Copyright 2013 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/quic_spdy_stream.h"
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "net/quic/quic_spdy_session.h"
+#include "net/quic/quic_utils.h"
+#include "net/quic/quic_write_blocked_list.h"
+
+using base::StringPiece;
+using std::min;
+using net::SpdyPriority;
+
+namespace net {
+
+#define ENDPOINT \
+ (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client:" \
+ " ")
+
+QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session)
+ : ReliableQuicStream(id, spdy_session),
+ spdy_session_(spdy_session),
+ visitor_(nullptr),
+ headers_decompressed_(false),
+ priority_(kDefaultPriority),
+ trailers_decompressed_(false) {
+ DCHECK_NE(kCryptoStreamId, id);
+ // Don't receive any callbacks from the sequencer until headers
+ // are complete.
+ sequencer()->SetBlockedUntilFlush();
+ spdy_session_->RegisterStreamPriority(id, priority_);
+}
+
+QuicSpdyStream::~QuicSpdyStream() {
+ spdy_session_->UnregisterStreamPriority(id());
+}
+
+void QuicSpdyStream::CloseWriteSide() {
+ if (version() > QUIC_VERSION_28 && !fin_received() && !rst_received() &&
+ sequencer()->ignore_read_data() && !rst_sent()) {
+ DCHECK(fin_sent());
+ // Tell the peer to stop sending further data.
+ DVLOG(1) << ENDPOINT << "Send QUIC_STREAM_NO_ERROR on stream " << id();
+ Reset(QUIC_STREAM_NO_ERROR);
+ }
+
+ ReliableQuicStream::CloseWriteSide();
+}
+
+void QuicSpdyStream::StopReading() {
+ if (version() > QUIC_VERSION_28 && !fin_received() && !rst_received() &&
+ write_side_closed() && !rst_sent()) {
+ DCHECK(fin_sent());
+ // Tell the peer to stop sending further data.
+ DVLOG(1) << ENDPOINT << "Send QUIC_STREAM_NO_ERROR on stream " << id();
+ Reset(QUIC_STREAM_NO_ERROR);
+ }
+ ReliableQuicStream::StopReading();
+}
+
+size_t QuicSpdyStream::WriteHeaders(
+ const SpdyHeaderBlock& header_block,
+ bool fin,
+ QuicAckListenerInterface* ack_notifier_delegate) {
+ size_t bytes_written = spdy_session_->WriteHeaders(
+ id(), header_block, fin, priority_, ack_notifier_delegate);
+ if (fin) {
+ // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
+ set_fin_sent(true);
+ CloseWriteSide();
+ }
+ return bytes_written;
+}
+
+size_t QuicSpdyStream::WriteTrailers(
+ SpdyHeaderBlock trailer_block,
+ QuicAckListenerInterface* ack_notifier_delegate) {
+ if (!FLAGS_quic_supports_trailers) {
+ return 0;
+ }
+ if (fin_sent()) {
+ LOG(DFATAL) << "Trailers cannot be sent after a FIN.";
+ return 0;
+ }
+
+ // The header block must contain the final offset for this stream, as the
+ // trailers may be processed out of order at the peer.
+ trailer_block.insert(std::make_pair(
+ kFinalOffsetHeaderKey,
+ base::IntToString(stream_bytes_written() + queued_data_bytes())));
+
+ // 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(), trailer_block, kFin, priority_, ack_notifier_delegate);
+ set_fin_sent(kFin);
+
+ // Trailers are the last thing to be sent on a stream, but if there is still
+ // queued data then CloseWriteSide() will cause it never to be sent.
+ if (queued_data_bytes() == 0) {
+ CloseWriteSide();
+ }
+
+ return bytes_written;
+}
+
+size_t QuicSpdyStream::Readv(const struct iovec* iov, size_t iov_len) {
+ DCHECK(FinishedReadingHeaders());
+ return sequencer()->Readv(iov, iov_len);
+}
+
+int QuicSpdyStream::GetReadableRegions(iovec* iov, size_t iov_len) const {
+ DCHECK(FinishedReadingHeaders());
+ return sequencer()->GetReadableRegions(iov, iov_len);
+}
+
+void QuicSpdyStream::MarkConsumed(size_t num_bytes) {
+ DCHECK(FinishedReadingHeaders());
+ return sequencer()->MarkConsumed(num_bytes);
+}
+
+bool QuicSpdyStream::IsDoneReading() const {
+ bool done_reading_headers = FinishedReadingHeaders();
+ bool done_reading_body = sequencer()->IsClosed();
+ bool done_reading_trailers = FinishedReadingTrailers();
+ return done_reading_headers && done_reading_body && done_reading_trailers;
+}
+
+bool QuicSpdyStream::HasBytesToRead() const {
+ bool headers_to_read = !decompressed_headers_.empty();
+ bool body_to_read = sequencer()->HasBytesToRead();
+ bool trailers_to_read =
+ (FLAGS_quic_supports_trailers && !decompressed_trailers_.empty());
+ return headers_to_read || body_to_read || trailers_to_read;
+}
+
+void QuicSpdyStream::MarkHeadersConsumed(size_t bytes_consumed) {
+ decompressed_headers_.erase(0, bytes_consumed);
+ if (FinishedReadingHeaders()) {
+ sequencer()->SetUnblocked();
+ }
+}
+
+void QuicSpdyStream::MarkTrailersConsumed(size_t bytes_consumed) {
+ decompressed_trailers_.erase(0, bytes_consumed);
+}
+
+void QuicSpdyStream::SetPriority(SpdyPriority priority) {
+ DCHECK_EQ(0u, stream_bytes_written());
+ spdy_session_->UpdateStreamPriority(id(), priority);
+ priority_ = priority;
+}
+
+SpdyPriority QuicSpdyStream::Priority() const {
+ return priority();
+}
+
+void QuicSpdyStream::OnStreamHeaders(StringPiece headers_data) {
+ if (!FLAGS_quic_supports_trailers || !headers_decompressed_) {
+ headers_data.AppendToString(&decompressed_headers_);
+ } else {
+ DCHECK(!trailers_decompressed_);
+ headers_data.AppendToString(&decompressed_trailers_);
+ }
+}
+
+void QuicSpdyStream::OnStreamHeadersPriority(SpdyPriority priority) {
+ DCHECK_EQ(Perspective::IS_SERVER, session()->connection()->perspective());
+ SetPriority(priority);
+}
+
+void QuicSpdyStream::OnStreamHeadersComplete(bool fin, size_t frame_len) {
+ if (!FLAGS_quic_supports_trailers || !headers_decompressed_) {
+ OnInitialHeadersComplete(fin, frame_len);
+ } else {
+ OnTrailingHeadersComplete(fin, frame_len);
+ }
+}
+
+void QuicSpdyStream::OnInitialHeadersComplete(bool fin, size_t /*frame_len*/) {
+ headers_decompressed_ = true;
+ if (fin) {
+ OnStreamFrame(QuicStreamFrame(id(), fin, 0, StringPiece()));
+ }
+ if (FinishedReadingHeaders()) {
+ sequencer()->SetUnblocked();
+ }
+}
+
+void QuicSpdyStream::OnPromiseHeaders(StringPiece headers_data) {
+ headers_data.AppendToString(&decompressed_headers_);
+}
+
+void QuicSpdyStream::OnPromiseHeadersComplete(
+ QuicStreamId /* promised_stream_id */,
+ size_t /* frame_len */) {
+ // To be overridden in QuicSpdyClientStream. Not supported on
+ // server side.
+ session()->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "Promise headers received by server");
+ return;
+}
+
+void QuicSpdyStream::OnTrailingHeadersComplete(bool fin, size_t /*frame_len*/) {
+ DCHECK(!trailers_decompressed_);
+ if (fin_received()) {
+ DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id();
+ session()->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "Trailers after fin");
+ return;
+ }
+ if (!fin) {
+ DLOG(ERROR) << "Trailers must have FIN set, on stream: " << id();
+ session()->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+ "Fin missing from trailers");
+ return;
+ }
+ trailers_decompressed_ = true;
+}
+
+void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
+ if (frame.error_code != QUIC_STREAM_NO_ERROR ||
+ version() <= QUIC_VERSION_28) {
+ ReliableQuicStream::OnStreamReset(frame);
+ return;
+ }
+ DVLOG(1) << "Received QUIC_STREAM_NO_ERROR, not discarding response";
+ set_rst_received(true);
+ MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+ set_stream_error(frame.error_code);
+ CloseWriteSide();
+}
+
+void QuicSpdyStream::OnClose() {
+ ReliableQuicStream::OnClose();
+
+ if (visitor_) {
+ Visitor* visitor = visitor_;
+ // Calling Visitor::OnClose() may result the destruction of the visitor,
+ // so we need to ensure we don't call it again.
+ visitor_ = nullptr;
+ visitor->OnClose(this);
+ }
+}
+
+bool QuicSpdyStream::FinishedReadingHeaders() const {
+ return headers_decompressed_ && decompressed_headers_.empty();
+}
+
+bool QuicSpdyStream::FinishedReadingTrailers() const {
+ if (!FLAGS_quic_supports_trailers) {
+ return true;
+ }
+ // If no further trailing headers are expected, and the decompressed trailers
+ // (if any) have been consumed, then reading of trailers is finished.
+ bool no_more_trailers = fin_received() || trailers_decompressed_;
+ return no_more_trailers && decompressed_trailers_.empty();
+}
+
+} // namespace net
diff --git a/chromium/net/quic/quic_spdy_stream.h b/chromium/net/quic/quic_spdy_stream.h
new file mode 100644
index 00000000000..d821f77c82e
--- /dev/null
+++ b/chromium/net/quic/quic_spdy_stream.h
@@ -0,0 +1,194 @@
+// Copyright 2013 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.
+//
+// The base class for streams which deliver data to/from an application.
+// In each direction, the data on such a stream first contains compressed
+// headers then body data.
+
+#ifndef NET_QUIC_QUIC_SPDY_STREAM_H_
+#define NET_QUIC_QUIC_SPDY_STREAM_H_
+
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <list>
+#include <string>
+
+#include "base/macros.h"
+#include "base/strings/string_piece.h"
+#include "net/base/iovec.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_export.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_stream_sequencer.h"
+#include "net/quic/reliable_quic_stream.h"
+#include "net/spdy/spdy_framer.h"
+
+namespace net {
+
+namespace test {
+class QuicSpdyStreamPeer;
+class ReliableQuicStreamPeer;
+} // namespace test
+
+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 NET_EXPORT_PRIVATE QuicSpdyStream : public ReliableQuicStream {
+ public:
+ // Visitor receives callbacks from the stream.
+ class NET_EXPORT_PRIVATE Visitor {
+ public:
+ Visitor() {}
+
+ // Called when the stream is closed.
+ virtual void OnClose(QuicSpdyStream* stream) = 0;
+
+ protected:
+ virtual ~Visitor() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Visitor);
+ };
+
+ QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session);
+ ~QuicSpdyStream() override;
+
+ // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
+ // when the stream has not received all the data.
+ void CloseWriteSide() override;
+ void StopReading() override;
+
+ // ReliableQuicStream implementation
+ void OnClose() override;
+
+ // This is the same as priority() and is being deprecated
+ // TODO(alyssar) remove after Priority refactor.
+ SpdyPriority Priority() const override;
+
+ // Called by the session when decompressed headers data is received
+ // for this stream.
+ // May be called multiple times, with each call providing additional headers
+ // data until OnStreamHeadersComplete is called.
+ virtual void OnStreamHeaders(base::StringPiece headers_data);
+
+ // Called by the session when headers with a priority have been received
+ // for this stream. This method will only be called for server streams.
+ virtual void OnStreamHeadersPriority(SpdyPriority priority);
+
+ // Called by the session when decompressed headers have been completely
+ // delivered to this stream. If |fin| is true, then this stream
+ // should be closed; no more data will be sent by the peer.
+ virtual void OnStreamHeadersComplete(bool fin, size_t frame_len);
+
+ // Called by the session when decompressed PUSH_PROMISE headers data
+ // is received for this stream.
+ // May be called multiple times, with each call providing additional headers
+ // data until OnPromiseHeadersComplete is called.
+ virtual void OnPromiseHeaders(StringPiece headers_data);
+
+ // Called by the session when decompressed push promise headers have
+ // been completely delivered to this stream.
+ virtual void OnPromiseHeadersComplete(QuicStreamId promised_id,
+ size_t frame_len);
+
+ // Override the base class to not discard response when receiving
+ // QUIC_STREAM_NO_ERROR on QUIC_VERSION_29 and later versions.
+ void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+ // Writes the headers contained in |header_block| to the dedicated
+ // headers stream.
+ virtual size_t WriteHeaders(const SpdyHeaderBlock& header_block,
+ bool fin,
+ QuicAckListenerInterface* ack_notifier_delegate);
+
+ // Writes the trailers contained in |trailer_block| to the dedicated
+ // headers stream. Trailers will always have the FIN set.
+ virtual size_t WriteTrailers(SpdyHeaderBlock trailer_block,
+ QuicAckListenerInterface* ack_notifier_delegate);
+
+ // Marks |bytes_consumed| of the headers data as consumed.
+ void MarkHeadersConsumed(size_t bytes_consumed);
+
+ // Marks |bytes_consumed| of the trailers data as consumed.
+ void MarkTrailersConsumed(size_t bytes_consumed);
+
+ // This block of functions wraps the sequencer's functions of the same
+ // name. These methods return uncompressed data until that has
+ // been fully processed. Then they simply delegate to the sequencer.
+ virtual size_t Readv(const struct iovec* iov, size_t iov_len);
+ virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
+ void MarkConsumed(size_t num_bytes);
+
+ // Returns true when all data has been read from the peer, including the fin.
+ bool IsDoneReading() const;
+ bool HasBytesToRead() const;
+
+ void set_visitor(Visitor* visitor) { visitor_ = visitor; }
+
+ bool headers_decompressed() const { return headers_decompressed_; }
+
+ const std::string& decompressed_headers() const {
+ return decompressed_headers_;
+ }
+
+ bool trailers_decompressed() const { return trailers_decompressed_; }
+
+ const std::string& decompressed_trailers() const {
+ return decompressed_trailers_;
+ }
+
+ SpdyPriority priority() const { return priority_; }
+
+ // Sets priority_ to priority. This should only be called before bytes are
+ // written to the server.
+ void SetPriority(SpdyPriority priority);
+
+ protected:
+ // Called by OnStreamHeadersComplete depending on which type (initial or
+ // trailing) headers are expected next.
+ virtual void OnInitialHeadersComplete(bool fin, size_t frame_len);
+ virtual void OnTrailingHeadersComplete(bool fin, size_t frame_len);
+ QuicSpdySession* spdy_session() const { return spdy_session_; }
+
+ // Returns true if headers have been fully read and consumed.
+ bool FinishedReadingHeaders() const;
+
+ private:
+ friend class test::QuicSpdyStreamPeer;
+ friend class test::ReliableQuicStreamPeer;
+ friend class QuicStreamUtils;
+
+ // Returns true if trailers have been fully read and consumed.
+ bool FinishedReadingTrailers() const;
+
+ QuicSpdySession* spdy_session_;
+
+ 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 headers until they are consumed
+ // via ProcessData or Readv.
+ std::string decompressed_headers_;
+
+ // True if the trailers have been completely decompressed.
+ bool trailers_decompressed_;
+ // Contains a copy of the decompressed trailers until they are consumed
+ // via ProcessData or Readv.
+ std::string decompressed_trailers_;
+
+ DISALLOW_COPY_AND_ASSIGN(QuicSpdyStream);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_SPDY_STREAM_H_
diff --git a/chromium/net/quic/quic_data_stream_test.cc b/chromium/net/quic/quic_spdy_stream_test.cc
index ab9ac12416e..95d31a8f4c4 100644
--- a/chromium/net/quic/quic_data_stream_test.cc
+++ b/chromium/net/quic/quic_spdy_stream_test.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/quic/quic_data_stream.h"
+#include "net/quic/quic_spdy_stream.h"
+
+#include "base/strings/string_number_conversions.h"
-#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_utils.h"
#include "net/quic/quic_write_blocked_list.h"
@@ -19,6 +20,8 @@
using base::StringPiece;
using std::min;
using std::string;
+using testing::AnyNumber;
+using testing::Invoke;
using testing::Return;
using testing::StrictMock;
using testing::_;
@@ -29,12 +32,12 @@ namespace {
const bool kShouldProcessData = true;
-class TestStream : public QuicDataStream {
+class TestStream : public QuicSpdyStream {
public:
TestStream(QuicStreamId id,
QuicSpdySession* session,
bool should_process_data)
- : QuicDataStream(id, session),
+ : QuicSpdyStream(id, session),
should_process_data_(should_process_data) {}
void OnDataAvailable() override {
@@ -50,7 +53,6 @@ class TestStream : public QuicDataStream {
}
using ReliableQuicStream::WriteOrBufferData;
- using ReliableQuicStream::CloseReadSide;
using ReliableQuicStream::CloseWriteSide;
const string& data() const { return data_; }
@@ -60,9 +62,9 @@ class TestStream : public QuicDataStream {
string data_;
};
-class QuicDataStreamTest : public ::testing::TestWithParam<QuicVersion> {
+class QuicSpdyStreamTest : public ::testing::TestWithParam<QuicVersion> {
public:
- QuicDataStreamTest() {
+ QuicSpdyStreamTest() {
headers_[":host"] = "www.google.com";
headers_[":path"] = "/index.hml";
headers_[":scheme"] = "https";
@@ -94,66 +96,67 @@ class QuicDataStreamTest : public ::testing::TestWithParam<QuicVersion> {
void Initialize(bool stream_should_process_data) {
connection_ = new testing::StrictMock<MockConnection>(
- Perspective::IS_SERVER, SupportedVersions(GetParam()));
+ &helper_, Perspective::IS_SERVER, SupportedVersions(GetParam()));
session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_));
- stream_.reset(new TestStream(kClientDataStreamId1, session_.get(),
- stream_should_process_data));
- stream2_.reset(new TestStream(kClientDataStreamId2, session_.get(),
- stream_should_process_data));
- write_blocked_list_ =
- QuicSessionPeer::GetWriteBlockedStreams(session_.get());
+ stream_ = new TestStream(kClientDataStreamId1, session_.get(),
+ stream_should_process_data);
+ session_->ActivateStream(stream_);
+ stream2_ = new TestStream(kClientDataStreamId2, session_.get(),
+ stream_should_process_data);
+ session_->ActivateStream(stream2_);
}
protected:
+ MockConnectionHelper helper_;
MockConnection* connection_;
scoped_ptr<MockQuicSpdySession> session_;
- scoped_ptr<TestStream> stream_;
- scoped_ptr<TestStream> stream2_;
+
+ // Owned by the |session_|.
+ TestStream* stream_;
+ TestStream* stream2_;
+
SpdyHeaderBlock headers_;
- QuicWriteBlockedList* write_blocked_list_;
};
-INSTANTIATE_TEST_CASE_P(Tests, QuicDataStreamTest,
+INSTANTIATE_TEST_CASE_P(Tests,
+ QuicSpdyStreamTest,
::testing::ValuesIn(QuicSupportedVersions()));
-TEST_P(QuicDataStreamTest, ProcessHeaders) {
+TEST_P(QuicSpdyStreamTest, ProcessHeaders) {
Initialize(kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
- stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeadersPriority(kV3HighestPriority);
stream_->OnStreamHeaders(headers);
EXPECT_EQ("", stream_->data());
EXPECT_EQ(headers, stream_->decompressed_headers());
stream_->OnStreamHeadersComplete(false, headers.size());
- EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority());
+ EXPECT_EQ(kV3HighestPriority, stream_->Priority());
EXPECT_EQ("", stream_->data());
EXPECT_EQ(headers, stream_->decompressed_headers());
EXPECT_FALSE(stream_->IsDoneReading());
}
-TEST_P(QuicDataStreamTest, ProcessHeadersWithFin) {
+TEST_P(QuicSpdyStreamTest, ProcessHeadersWithFin) {
Initialize(kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
- stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeadersPriority(kV3HighestPriority);
stream_->OnStreamHeaders(headers);
EXPECT_EQ("", stream_->data());
EXPECT_EQ(headers, stream_->decompressed_headers());
stream_->OnStreamHeadersComplete(true, headers.size());
- EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority());
+ EXPECT_EQ(kV3HighestPriority, stream_->Priority());
EXPECT_EQ("", stream_->data());
EXPECT_EQ(headers, stream_->decompressed_headers());
EXPECT_FALSE(stream_->IsDoneReading());
EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
}
-TEST_P(QuicDataStreamTest, MarkHeadersConsumed) {
+TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
Initialize(kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
stream_->OnStreamHeaders(headers);
@@ -168,11 +171,10 @@ TEST_P(QuicDataStreamTest, MarkHeadersConsumed) {
EXPECT_EQ("", stream_->decompressed_headers());
}
-TEST_P(QuicDataStreamTest, ProcessHeadersAndBody) {
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
Initialize(kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
stream_->OnStreamHeaders(headers);
@@ -187,24 +189,21 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBody) {
EXPECT_EQ(body, stream_->data());
}
-TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) {
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
- for (size_t fragment_size = 1; fragment_size < body.size();
- ++fragment_size) {
+ for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) {
Initialize(kShouldProcessData);
- for (size_t offset = 0; offset < headers.size();
- offset += fragment_size) {
+ for (size_t offset = 0; offset < headers.size(); offset += fragment_size) {
size_t remaining_data = headers.size() - offset;
StringPiece fragment(headers.data() + offset,
min(fragment_size, remaining_data));
stream_->OnStreamHeaders(fragment);
}
stream_->OnStreamHeadersComplete(false, headers.size());
- ASSERT_EQ(headers, stream_->decompressed_headers())
- << "fragment_size: " << fragment_size;
+ ASSERT_EQ(headers, stream_->decompressed_headers()) << "fragment_size: "
+ << fragment_size;
stream_->MarkHeadersConsumed(headers.length());
for (size_t offset = 0; offset < body.size(); offset += fragment_size) {
size_t remaining_data = body.size() - offset;
@@ -218,9 +217,8 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) {
}
}
-TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) {
@@ -232,8 +230,8 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
headers.size() - split_point);
stream_->OnStreamHeaders(headers2);
stream_->OnStreamHeadersComplete(false, headers.size());
- ASSERT_EQ(headers, stream_->decompressed_headers())
- << "split_point: " << split_point;
+ ASSERT_EQ(headers, stream_->decompressed_headers()) << "split_point: "
+ << split_point;
stream_->MarkHeadersConsumed(headers.length());
StringPiece fragment1(body.data(), split_point);
@@ -241,8 +239,7 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
StringPiece(fragment1));
stream_->OnStreamFrame(frame1);
- StringPiece fragment2(body.data() + split_point,
- body.size() - split_point);
+ StringPiece fragment2(body.data() + split_point, body.size() - split_point);
QuicStreamFrame frame2(kClientDataStreamId1, false, split_point,
StringPiece(fragment2));
stream_->OnStreamFrame(frame2);
@@ -251,11 +248,10 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
}
}
-TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) {
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
Initialize(!kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
stream_->OnStreamHeaders(headers);
@@ -275,11 +271,10 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) {
EXPECT_EQ(body, string(buffer, bytes_read));
}
-TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyMarkConsumed) {
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
Initialize(!kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
stream_->OnStreamHeaders(headers);
@@ -298,11 +293,10 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyMarkConsumed) {
EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed());
}
-TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
Initialize(!kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
stream_->OnStreamHeaders(headers);
stream_->OnStreamHeadersComplete(false, headers.size());
@@ -322,11 +316,10 @@ TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
}
}
-TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
+TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
Initialize(!kShouldProcessData);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body = "this is the body";
stream_->OnStreamHeaders(headers);
stream_->OnStreamHeadersComplete(false, headers.size());
@@ -350,23 +343,22 @@ TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
}
}
-TEST_P(QuicDataStreamTest, StreamFlowControlBlocked) {
+TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
// Tests that we send a BLOCKED frame to the peer when we attempt to write,
// but are flow control blocked.
Initialize(kShouldProcessData);
// Set a small flow control limit.
- const uint64 kWindow = 36;
+ const uint64_t kWindow = 36;
QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(),
kWindow);
EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset(
stream_->flow_controller()));
// Try to send more data than the flow control limit allows.
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body;
- const uint64 kOverflow = 15;
+ const uint64_t kOverflow = 15;
GenerateBody(&body, kWindow + kOverflow);
EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1));
@@ -379,11 +371,10 @@ TEST_P(QuicDataStreamTest, StreamFlowControlBlocked) {
QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller()));
// And we should have queued the overflowed data.
- EXPECT_EQ(kOverflow,
- ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get()));
+ EXPECT_EQ(kOverflow, ReliableQuicStreamPeer::SizeOfQueuedData(stream_));
}
-TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
+TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
// The flow control receive window decreases whenever we add new bytes to the
// sequencer, whether they are consumed immediately or buffered. However we
// only send WINDOW_UPDATE frames based on increasing number of bytes
@@ -396,7 +387,7 @@ TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0);
// Set a small flow control receive window.
- const uint64 kWindow = 36;
+ const uint64_t kWindow = 36;
QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
kWindow);
QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
@@ -405,8 +396,7 @@ TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
stream_->flow_controller()));
// Stream receives enough data to fill a fraction of the receive window.
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body;
GenerateBody(&body, kWindow / 3);
stream_->OnStreamHeaders(headers);
@@ -428,14 +418,14 @@ TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
}
-TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) {
+TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
// Tests that on receipt of data, the stream updates its receive window offset
// appropriately, and sends WINDOW_UPDATE frames when its receive window drops
// too low.
Initialize(kShouldProcessData);
// Set a small flow control limit.
- const uint64 kWindow = 36;
+ const uint64_t kWindow = 36;
QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
kWindow);
QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
@@ -444,8 +434,7 @@ TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) {
stream_->flow_controller()));
// Stream receives enough data to fill a fraction of the receive window.
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
string body;
GenerateBody(&body, kWindow / 3);
stream_->OnStreamHeaders(headers);
@@ -473,14 +462,14 @@ TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) {
stream_->flow_controller()));
}
-TEST_P(QuicDataStreamTest, ConnectionFlowControlWindowUpdate) {
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
// Tests that on receipt of data, the connection updates its receive window
// offset appropriately, and sends WINDOW_UPDATE frames when its receive
// window drops too low.
Initialize(kShouldProcessData);
// Set a small flow control limit for streams and connection.
- const uint64 kWindow = 36;
+ const uint64_t kWindow = 36;
QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
kWindow);
QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
@@ -495,8 +484,7 @@ TEST_P(QuicDataStreamTest, ConnectionFlowControlWindowUpdate) {
kWindow);
// Supply headers to both streams so that they are happy to receive data.
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
stream_->OnStreamHeaders(headers);
stream_->OnStreamHeadersComplete(false, headers.size());
stream_->MarkHeadersConsumed(headers.length());
@@ -527,7 +515,7 @@ TEST_P(QuicDataStreamTest, ConnectionFlowControlWindowUpdate) {
stream_->OnStreamFrame(frame3);
}
-TEST_P(QuicDataStreamTest, StreamFlowControlViolation) {
+TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
// Tests that on if the peer sends too much data (i.e. violates the flow
// control protocol), then we terminate the connection.
@@ -536,12 +524,11 @@ TEST_P(QuicDataStreamTest, StreamFlowControlViolation) {
Initialize(!kShouldProcessData);
// Set a small flow control limit.
- const uint64 kWindow = 50;
+ const uint64_t kWindow = 50;
QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
kWindow);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
stream_->OnStreamHeaders(headers);
stream_->OnStreamHeadersComplete(false, headers.size());
@@ -549,12 +536,31 @@ TEST_P(QuicDataStreamTest, StreamFlowControlViolation) {
string body;
GenerateBody(&body, kWindow + 1);
QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _));
stream_->OnStreamFrame(frame);
}
-TEST_P(QuicDataStreamTest, ConnectionFlowControlViolation) {
+TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
+ Initialize(kShouldProcessData);
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeaders(headers);
+ stream_->OnStreamHeadersComplete(false, headers.size());
+
+ if (GetParam() <= QUIC_VERSION_28) {
+ EXPECT_CALL(*session_, SendRstStream(_, _, _));
+ }
+ stream_->OnStreamReset(
+ QuicRstStreamFrame(stream_->id(), QUIC_STREAM_NO_ERROR, 0));
+ EXPECT_TRUE(stream_->write_side_closed());
+ if (GetParam() > QUIC_VERSION_28) {
+ EXPECT_FALSE(stream_->reading_stopped());
+ } else {
+ EXPECT_TRUE(stream_->reading_stopped());
+ }
+}
+
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
// Tests that on if the peer sends too much data (i.e. violates the flow
// control protocol), at the connection level (rather than the stream level)
// then we terminate the connection.
@@ -564,30 +570,29 @@ TEST_P(QuicDataStreamTest, ConnectionFlowControlViolation) {
Initialize(!kShouldProcessData);
// Set a small flow control window on streams, and connection.
- const uint64 kStreamWindow = 50;
- const uint64 kConnectionWindow = 10;
+ const uint64_t kStreamWindow = 50;
+ const uint64_t kConnectionWindow = 10;
QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
kStreamWindow);
QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
kConnectionWindow);
- string headers =
- SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
stream_->OnStreamHeaders(headers);
stream_->OnStreamHeadersComplete(false, headers.size());
// Send enough data to overflow the connection level flow control window.
string body;
GenerateBody(&body, kConnectionWindow + 1);
- EXPECT_LT(body.size(), kStreamWindow);
+ EXPECT_LT(body.size(), kStreamWindow);
QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _));
stream_->OnStreamFrame(frame);
}
-TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) {
+TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
// An attempt to write a FIN with no data should not be flow control blocked,
// even if the send window is 0.
@@ -609,6 +614,248 @@ TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) {
stream_->WriteOrBufferData(body, fin, nullptr);
}
+TEST_P(QuicSpdyStreamTest, ReceivingTrailers) {
+ // Test that receiving trailing headers from the peer works, and can be read
+ // from the stream and consumed.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+
+ // Receive initial headers.
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeaders(headers);
+ stream_->OnStreamHeadersComplete(false, headers.size());
+ stream_->MarkHeadersConsumed(stream_->decompressed_headers().size());
+
+ // Receive trailing headers.
+ SpdyHeaderBlock trailers_block;
+ trailers_block["key1"] = "value1";
+ trailers_block["key2"] = "value2";
+ trailers_block["key3"] = "value3";
+ string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block);
+ stream_->OnStreamHeaders(trailers);
+ stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size());
+
+ // The trailers should be decompressed, and readable from the stream.
+ EXPECT_TRUE(stream_->trailers_decompressed());
+ const string decompressed_trailers = stream_->decompressed_trailers();
+ EXPECT_EQ(trailers, decompressed_trailers);
+
+ // Consuming the trailers erases them from the stream.
+ stream_->MarkTrailersConsumed(decompressed_trailers.size());
+ EXPECT_EQ("", stream_->decompressed_trailers());
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
+ // Test that received Trailers must always have the FIN set.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+
+ // Receive initial headers.
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeaders(headers);
+ stream_->OnStreamHeadersComplete(false, headers.size());
+
+ // Receive trailing headers with FIN deliberately set to false.
+ SpdyHeaderBlock trailers_block;
+ string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block);
+ stream_->OnStreamHeaders(trailers);
+
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_HEADERS_STREAM_DATA, _))
+ .Times(1);
+ stream_->OnStreamHeadersComplete(/*fin=*/false, trailers.size());
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterFin) {
+ // If Trailers are sent, neither Headers nor Body should contain a FIN.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+
+ // Receive initial headers with FIN set.
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeaders(headers);
+ stream_->OnStreamHeadersComplete(/*fin=*/true, headers.size());
+
+ // Receive trailing headers after FIN already received.
+ SpdyHeaderBlock trailers_block;
+ string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block);
+ stream_->OnStreamHeaders(trailers);
+
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_HEADERS_STREAM_DATA, _))
+ .Times(1);
+ stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size());
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
+ // If body data are received with a FIN, no trailers should then arrive.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+
+ // Receive initial headers without FIN set.
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeaders(headers);
+ stream_->OnStreamHeadersComplete(/*fin=*/false, headers.size());
+
+ // Receive body data, with FIN.
+ QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, "body");
+ stream_->OnStreamFrame(frame);
+
+ // Receive trailing headers after FIN already received.
+ SpdyHeaderBlock trailers_block;
+ string trailers = SpdyUtils::SerializeUncompressedHeaders(trailers_block);
+ stream_->OnStreamHeaders(trailers);
+
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_HEADERS_STREAM_DATA, _))
+ .Times(1);
+ stream_->OnStreamHeadersComplete(/*fin=*/true, trailers.size());
+}
+
+TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
+ // Verify that a stream receiving headers, body, and no trailers is correctly
+ // marked as done reading on consumption of headers and body.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+
+ // Receive and consume initial headers with FIN not set.
+ string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeaders(headers);
+ stream_->OnStreamHeadersComplete(/*fin=*/false, headers.size());
+ stream_->MarkHeadersConsumed(headers.size());
+
+ // Receive and consume body with FIN set, and no trailers.
+ const string kBody = string(1024, 'x');
+ QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, kBody);
+ stream_->OnStreamFrame(frame);
+
+ EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
+ // Test that writing trailers will send a FIN, as Trailers are the last thing
+ // to be sent on a stream.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ // Write the initial headers, without a FIN.
+ EXPECT_CALL(*session_, WriteHeaders(_, _, _, _, _));
+ stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+ // Writing trailers implicitly sends a FIN.
+ SpdyHeaderBlock trailers;
+ trailers["trailer key"] = "trailer value";
+ EXPECT_CALL(*session_, WriteHeaders(_, _,
+ /*fin=*/true, _, _));
+ stream_->WriteTrailers(trailers, nullptr);
+ EXPECT_TRUE(stream_->fin_sent());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
+ // Test that when writing trailers, the trailers that are actually sent to the
+ // peer contain the final offset field indicating last byte of data.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ // Write the initial headers.
+ EXPECT_CALL(*session_, WriteHeaders(_, _, _, _, _));
+ stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+ // Write non-zero body data to force a non-zero final offset.
+ const int kBodySize = 1 * 1024; // 1 MB
+ stream_->WriteOrBufferData(string(kBodySize, 'x'), false, nullptr);
+
+ // The final offset field in the trailing headers is populated with the
+ // number of body bytes written (including queued bytes).
+ SpdyHeaderBlock trailers;
+ trailers["trailer key"] = "trailer value";
+ SpdyHeaderBlock trailers_with_offset = trailers;
+ trailers_with_offset[kFinalOffsetHeaderKey] = base::IntToString(kBodySize);
+ EXPECT_CALL(*session_, WriteHeaders(_, testing::Eq(trailers_with_offset),
+ /*fin=*/true, _, _));
+ stream_->WriteTrailers(trailers, nullptr);
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
+ // Test that if trailers are written after all other data has been written
+ // (headers and body), that this closes the stream for writing.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ // Write the initial headers.
+ EXPECT_CALL(*session_, WriteHeaders(_, _, _, _, _));
+ stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+ // Write non-zero body data.
+ const int kBodySize = 1 * 1024; // 1 MB
+ stream_->WriteOrBufferData(string(kBodySize, 'x'), false, nullptr);
+ EXPECT_EQ(0u, stream_->queued_data_bytes());
+
+ // Headers and body have been fully written, there is no queued data. Writing
+ // trailers marks the end of this stream, and thus the write side is closed.
+ EXPECT_CALL(*session_, WriteHeaders(_, _,
+ /*fin=*/true, _, _));
+ stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
+ // Test that the stream is not closed for writing when trailers are sent
+ // while there are still body bytes queued.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ // Write the initial headers.
+ EXPECT_CALL(*session_, WriteHeaders(_, _, _, _, _));
+ stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+ // Write non-zero body data, but only consume partially, ensuring queueing.
+ const int kBodySize = 1 * 1024; // 1 MB
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
+ stream_->WriteOrBufferData(string(kBodySize, 'x'), false, nullptr);
+ EXPECT_EQ(1u, stream_->queued_data_bytes());
+
+ // Writing trailers will send a FIN, but not close the write side of the
+ // stream as there are queued bytes.
+ EXPECT_CALL(*session_, WriteHeaders(_, _,
+ /*fin=*/true, _, _));
+ stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+ EXPECT_TRUE(stream_->fin_sent());
+ EXPECT_FALSE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
+ // Test that it is not possible to write Trailers after a FIN has been sent.
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ Initialize(kShouldProcessData);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ // Write the initial headers, with a FIN.
+ EXPECT_CALL(*session_, WriteHeaders(_, _, _, _, _));
+ stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
+ EXPECT_TRUE(stream_->fin_sent());
+
+ // Writing Trailers should fail, as the FIN has already been sent.
+ // populated with the number of body bytes written.
+ EXPECT_DFATAL(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
+ "Trailers cannot be sent after a FIN");
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_stream_factory.cc b/chromium/net/quic/quic_stream_factory.cc
index cf32df9ddb3..858f1cb93f0 100644
--- a/chromium/net/quic/quic_stream_factory.cc
+++ b/chromium/net/quic/quic_stream_factory.cc
@@ -6,8 +6,10 @@
#include <algorithm>
#include <set>
+#include <utility>
#include "base/location.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
@@ -22,18 +24,19 @@
#include "net/base/socket_performance_watcher.h"
#include "net/base/socket_performance_watcher_factory.h"
#include "net/cert/cert_verifier.h"
+#include "net/cert/ct_verifier.h"
#include "net/dns/host_resolver.h"
#include "net/dns/single_request_host_resolver.h"
-#include "net/http/http_server_properties.h"
#include "net/quic/crypto/channel_id_chromium.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
+#include "net/quic/crypto/properties_based_quic_server_info.h"
#include "net/quic/crypto/quic_random.h"
#include "net/quic/crypto/quic_server_info.h"
#include "net/quic/port_suggester.h"
#include "net/quic/quic_chromium_client_session.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_clock.h"
#include "net/quic/quic_connection.h"
-#include "net/quic/quic_connection_helper.h"
#include "net/quic/quic_crypto_client_stream_factory.h"
#include "net/quic/quic_default_packet_writer.h"
#include "net/quic/quic_flags.h"
@@ -68,21 +71,32 @@ enum CreateSessionFailure {
CREATION_ERROR_MAX
};
-// 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_MAX
+};
// The maximum receive window sizes for QUIC sessions and streams.
-const int32 kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
-const int32 kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
+const int32_t kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
+const int32_t kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
// Set the maximum number of undecryptable packets the connection will store.
-const int32 kMaxUndecryptablePackets = 100;
+const int32_t kMaxUndecryptablePackets = 100;
void HistogramCreateSessionFailure(enum CreateSessionFailure error) {
UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error,
CREATION_ERROR_MAX);
}
+void HistogramMigrationStatus(enum QuicConnectionMigrationStatus status) {
+ UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration", status,
+ MIGRATION_STATUS_MAX);
+}
+
bool IsEcdsaSupported() {
#if defined(OS_WIN)
if (base::win::GetVersion() < base::win::VERSION_VISTA)
@@ -92,60 +106,19 @@ bool IsEcdsaSupported() {
return true;
}
-QuicConfig InitializeQuicConfig(const QuicTagVector& connection_options) {
+QuicConfig InitializeQuicConfig(const QuicTagVector& connection_options,
+ int idle_connection_timeout_seconds) {
+ DCHECK_GT(idle_connection_timeout_seconds, 0);
QuicConfig config;
config.SetIdleConnectionStateLifetime(
- QuicTime::Delta::FromSeconds(kIdleConnectionTimeoutSeconds),
- QuicTime::Delta::FromSeconds(kIdleConnectionTimeoutSeconds));
+ QuicTime::Delta::FromSeconds(idle_connection_timeout_seconds),
+ QuicTime::Delta::FromSeconds(idle_connection_timeout_seconds));
config.SetConnectionOptionsToSend(connection_options);
return config;
}
-class DefaultPacketWriterFactory : public QuicConnection::PacketWriterFactory {
- public:
- explicit DefaultPacketWriterFactory(DatagramClientSocket* socket)
- : socket_(socket) {}
- ~DefaultPacketWriterFactory() override {}
-
- QuicPacketWriter* Create(QuicConnection* connection) const override;
-
- private:
- DatagramClientSocket* socket_;
-};
-
-QuicPacketWriter* DefaultPacketWriterFactory::Create(
- QuicConnection* connection) const {
- scoped_ptr<QuicDefaultPacketWriter> writer(
- new QuicDefaultPacketWriter(socket_));
- writer->SetConnection(connection);
- return writer.release();
-}
-
} // namespace
-QuicStreamFactory::IpAliasKey::IpAliasKey() {}
-
-QuicStreamFactory::IpAliasKey::IpAliasKey(IPEndPoint ip_endpoint,
- bool is_https)
- : ip_endpoint(ip_endpoint),
- is_https(is_https) {}
-
-QuicStreamFactory::IpAliasKey::~IpAliasKey() {}
-
-bool QuicStreamFactory::IpAliasKey::operator<(
- const QuicStreamFactory::IpAliasKey& other) const {
- if (!(ip_endpoint == other.ip_endpoint)) {
- return ip_endpoint < other.ip_endpoint;
- }
- return is_https < other.is_https;
-}
-
-bool QuicStreamFactory::IpAliasKey::operator==(
- const QuicStreamFactory::IpAliasKey& other) const {
- return is_https == other.is_https &&
- ip_endpoint == other.ip_endpoint;
-};
-
// Responsible for creating a new QUIC session to the specified server, and
// for notifying any associated requests when complete.
class QuicStreamFactory::Job {
@@ -154,7 +127,6 @@ class QuicStreamFactory::Job {
HostResolver* host_resolver,
const HostPortPair& host_port_pair,
bool server_and_origin_have_same_host,
- bool is_https,
bool was_alternative_service_recently_broken,
PrivacyMode privacy_mode,
int cert_verify_flags,
@@ -231,7 +203,6 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
HostResolver* host_resolver,
const HostPortPair& host_port_pair,
bool server_and_origin_have_same_host,
- bool is_https,
bool was_alternative_service_recently_broken,
PrivacyMode privacy_mode,
int cert_verify_flags,
@@ -241,7 +212,7 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
: io_state_(STATE_RESOLVE_HOST),
factory_(factory),
host_resolver_(host_resolver),
- server_id_(host_port_pair, is_https, privacy_mode),
+ server_id_(host_port_pair, privacy_mode),
cert_verify_flags_(cert_verify_flags),
server_and_origin_have_same_host_(server_and_origin_have_same_host),
is_post_(is_post),
@@ -251,8 +222,7 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
started_another_job_(false),
net_log_(net_log),
session_(nullptr),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
HostResolver* host_resolver,
@@ -340,7 +310,8 @@ void QuicStreamFactory::Job::RunAuxilaryJob() {
void QuicStreamFactory::Job::Cancel() {
callback_.Reset();
if (session_)
- session_->connection()->SendConnectionClose(QUIC_CONNECTION_CANCELLED);
+ session_->connection()->SendConnectionCloseWithDetails(
+ QUIC_CONNECTION_CANCELLED, "New job canceled.");
}
void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() {
@@ -398,7 +369,7 @@ int QuicStreamFactory::Job::DoLoadServerInfo() {
if (factory_->load_server_info_timeout_srtt_multiplier_ > 0) {
const int kMaxLoadServerInfoTimeoutMs = 50;
// Wait for DiskCache a maximum of 50ms.
- int64 load_server_info_timeout_ms =
+ int64_t load_server_info_timeout_ms =
min(static_cast<int>(
(factory_->load_server_info_timeout_srtt_multiplier_ *
factory_->GetServerNetworkStatsSmoothedRttInMicroseconds(
@@ -452,7 +423,7 @@ int QuicStreamFactory::Job::DoConnect() {
io_state_ = STATE_CONNECT_COMPLETE;
int rv = factory_->CreateSession(
- server_id_, cert_verify_flags_, server_info_.Pass(), address_list_,
+ server_id_, cert_verify_flags_, std::move(server_info_), address_list_,
dns_resolution_end_time_, net_log_, &session_);
if (rv != OK) {
DCHECK(rv != ERR_IO_PENDING);
@@ -496,7 +467,9 @@ int QuicStreamFactory::Job::DoConnectComplete(int rv) {
// existing session instead.
AddressList address(session_->connection()->peer_address());
if (factory_->OnResolution(server_id_, address)) {
- session_->connection()->SendConnectionClose(QUIC_CONNECTION_IP_POOLED);
+ session_->connection()->SendConnectionCloseWithDetails(
+ QUIC_CONNECTION_IP_POOLED,
+ "An active session exists for the given IP.");
session_ = nullptr;
return OK;
}
@@ -515,7 +488,6 @@ QuicStreamRequest::~QuicStreamRequest() {
}
int QuicStreamRequest::Request(const HostPortPair& host_port_pair,
- bool is_https,
PrivacyMode privacy_mode,
int cert_verify_flags,
base::StringPiece origin_host,
@@ -527,12 +499,10 @@ int QuicStreamRequest::Request(const HostPortPair& host_port_pair,
DCHECK(factory_);
origin_host_ = origin_host.as_string();
privacy_mode_ = privacy_mode;
- int rv =
- factory_->Create(host_port_pair, is_https, privacy_mode,
- cert_verify_flags, origin_host, method, net_log, this);
+ int rv = factory_->Create(host_port_pair, privacy_mode, cert_verify_flags,
+ origin_host, method, net_log, this);
if (rv == ERR_IO_PENDING) {
host_port_pair_ = host_port_pair;
- is_https_ = is_https;
net_log_ = net_log;
callback_ = callback;
} else {
@@ -545,7 +515,7 @@ int QuicStreamRequest::Request(const HostPortPair& host_port_pair,
void QuicStreamRequest::set_stream(scoped_ptr<QuicHttpStream> stream) {
DCHECK(stream);
- stream_ = stream.Pass();
+ stream_ = std::move(stream);
}
void QuicStreamRequest::OnRequestComplete(int rv) {
@@ -557,12 +527,12 @@ base::TimeDelta QuicStreamRequest::GetTimeDelayForWaitingJob() const {
if (!factory_)
return base::TimeDelta();
return factory_->GetTimeDelayForWaitingJob(
- QuicServerId(host_port_pair_, is_https_, privacy_mode_));
+ QuicServerId(host_port_pair_, privacy_mode_));
}
scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() {
DCHECK(stream_);
- return stream_.Pass();
+ return std::move(stream_);
}
QuicStreamFactory::QuicStreamFactory(
@@ -570,10 +540,11 @@ QuicStreamFactory::QuicStreamFactory(
ClientSocketFactory* client_socket_factory,
base::WeakPtr<HttpServerProperties> http_server_properties,
CertVerifier* cert_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
ChannelIDService* channel_id_service,
TransportSecurityState* transport_security_state,
- const SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
+ CTVerifier* cert_transparency_verifier,
+ SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
QuicRandom* random_generator,
QuicClock* clock,
@@ -595,19 +566,28 @@ QuicStreamFactory::QuicStreamFactory(
int threshold_timeouts_with_open_streams,
int socket_receive_buffer_size,
bool delay_tcp_race,
+ int max_server_configs_stored_in_properties,
+ bool close_sessions_on_ip_change,
+ int idle_connection_timeout_seconds,
+ bool migrate_sessions_on_network_change,
const QuicTagVector& connection_options)
: require_confirmation_(true),
host_resolver_(host_resolver),
client_socket_factory_(client_socket_factory),
http_server_properties_(http_server_properties),
transport_security_state_(transport_security_state),
- quic_server_info_factory_(nullptr),
+ cert_transparency_verifier_(cert_transparency_verifier),
quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory),
random_generator_(random_generator),
clock_(clock),
max_packet_length_(max_packet_length),
socket_performance_watcher_factory_(socket_performance_watcher_factory),
- config_(InitializeQuicConfig(connection_options)),
+ config_(InitializeQuicConfig(connection_options,
+ idle_connection_timeout_seconds)),
+ crypto_config_(new ProofVerifierChromium(cert_verifier,
+ ct_policy_enforcer,
+ transport_security_state,
+ cert_transparency_verifier)),
supported_versions_(supported_versions),
enable_port_selection_(enable_port_selection),
always_require_handshake_confirmation_(
@@ -635,18 +615,21 @@ QuicStreamFactory::QuicStreamFactory(
yield_after_packets_(kQuicYieldAfterPacketsRead),
yield_after_duration_(QuicTime::Delta::FromMilliseconds(
kQuicYieldAfterDurationMilliseconds)),
+ close_sessions_on_ip_change_(close_sessions_on_ip_change),
+ migrate_sessions_on_network_change_(
+ migrate_sessions_on_network_change &&
+ NetworkChangeNotifier::AreNetworkHandlesSupported()),
port_seed_(random_generator_->RandUint64()),
check_persisted_supports_quic_(true),
- quic_supported_servers_at_startup_initialzied_(false),
+ has_initialized_data_(false),
task_runner_(nullptr),
weak_factory_(this) {
DCHECK(transport_security_state_);
+ DCHECK(http_server_properties_);
crypto_config_.set_user_agent_id(user_agent_id);
crypto_config_.AddCanonicalSuffix(".c.youtube.com");
crypto_config_.AddCanonicalSuffix(".googlevideo.com");
crypto_config_.AddCanonicalSuffix(".googleusercontent.com");
- crypto_config_.SetProofVerifier(new ProofVerifierChromium(
- cert_verifier, cert_policy_enforcer, transport_security_state));
// TODO(rtenneti): http://crbug.com/487355. Temporary fix for b/20760730 until
// channel_id_service is supported in cronet.
if (channel_id_service) {
@@ -666,10 +649,25 @@ QuicStreamFactory::QuicStreamFactory(
crypto_config_.PreferAesGcm();
if (!IsEcdsaSupported())
crypto_config_.DisableEcdsa();
+ // When disk cache is used to store the server configs, HttpCache code calls
+ // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't
+ // created.
+ if (max_server_configs_stored_in_properties > 0) {
+ quic_server_info_factory_.reset(
+ new PropertiesBasedQuicServerInfoFactory(http_server_properties_));
+ }
+
+ DCHECK(
+ !(close_sessions_on_ip_change_ && migrate_sessions_on_network_change_));
+ if (migrate_sessions_on_network_change_) {
+ NetworkChangeNotifier::AddNetworkObserver(this);
+ } else if (close_sessions_on_ip_change_) {
+ NetworkChangeNotifier::AddIPAddressObserver(this);
+ }
}
QuicStreamFactory::~QuicStreamFactory() {
- CloseAllSessions(ERR_ABORTED);
+ CloseAllSessions(ERR_ABORTED, QUIC_INTERNAL_ERROR);
while (!all_sessions_.empty()) {
delete all_sessions_.begin()->first;
all_sessions_.erase(all_sessions_.begin());
@@ -679,21 +677,31 @@ QuicStreamFactory::~QuicStreamFactory() {
STLDeleteElements(&(active_jobs_[server_id]));
active_jobs_.erase(server_id);
}
+ if (migrate_sessions_on_network_change_) {
+ NetworkChangeNotifier::RemoveNetworkObserver(this);
+ } else if (close_sessions_on_ip_change_) {
+ NetworkChangeNotifier::RemoveIPAddressObserver(this);
+ }
}
void QuicStreamFactory::set_require_confirmation(bool require_confirmation) {
require_confirmation_ = require_confirmation;
- if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) {
+ if (!(local_address_ == IPEndPoint())) {
http_server_properties_->SetSupportsQuic(!require_confirmation,
local_address_.address());
}
}
+bool QuicStreamFactory::ZeroRTTEnabledFor(const QuicServerId& quic_server_id) {
+ return !(require_confirmation_ || CryptoConfigCacheIsEmpty(quic_server_id));
+}
+
base::TimeDelta QuicStreamFactory::GetTimeDelayForWaitingJob(
const QuicServerId& server_id) {
if (!delay_tcp_race_ || require_confirmation_)
return base::TimeDelta();
- int64 srtt = 1.5 * GetServerNetworkStatsSmoothedRttInMicroseconds(server_id);
+ int64_t srtt =
+ 1.5 * GetServerNetworkStatsSmoothedRttInMicroseconds(server_id);
// Picked 300ms based on mean time from
// Net.QuicSession.HostResolution.HandshakeConfirmedTime histogram.
const int kDefaultRTT = 300 * kNumMicrosPerMilli;
@@ -702,15 +710,33 @@ base::TimeDelta QuicStreamFactory::GetTimeDelayForWaitingJob(
return base::TimeDelta::FromMicroseconds(srtt);
}
+void QuicStreamFactory::set_quic_server_info_factory(
+ QuicServerInfoFactory* quic_server_info_factory) {
+ quic_server_info_factory_.reset(quic_server_info_factory);
+}
+
+bool QuicStreamFactory::CanUseExistingSession(QuicServerId server_id,
+ PrivacyMode privacy_mode,
+ StringPiece origin_host) {
+ // TODO(zhongyi): delete active_sessions_.empty() checks once the
+ // android crash issue(crbug.com/498823) is resolved.
+ if (active_sessions_.empty())
+ return false;
+ SessionMap::iterator it = active_sessions_.find(server_id);
+ if (it == active_sessions_.end())
+ return false;
+ QuicChromiumClientSession* session = it->second;
+ return session->CanPool(origin_host.as_string(), privacy_mode);
+}
+
int QuicStreamFactory::Create(const HostPortPair& host_port_pair,
- bool is_https,
PrivacyMode privacy_mode,
int cert_verify_flags,
base::StringPiece origin_host,
base::StringPiece method,
const BoundNetLog& net_log,
QuicStreamRequest* request) {
- QuicServerId server_id(host_port_pair, is_https, privacy_mode);
+ QuicServerId server_id(host_port_pair, privacy_mode);
// TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() checks.
if (!active_sessions_.empty()) {
SessionMap::iterator it = active_sessions_.find(server_id);
@@ -735,17 +761,14 @@ int QuicStreamFactory::Create(const HostPortPair& host_port_pair,
task_runner_ = base::ThreadTaskRunnerHandle::Get().get();
QuicServerInfo* quic_server_info = nullptr;
- if (quic_server_info_factory_) {
+ if (quic_server_info_factory_.get()) {
bool load_from_disk_cache = !disable_disk_cache_;
- if (http_server_properties_) {
- if (!quic_supported_servers_at_startup_initialzied_)
- InitializeQuicSupportedServersAtStartup();
- if (!ContainsKey(quic_supported_servers_at_startup_,
- server_id.host_port_pair())) {
- // If there is no entry for QUIC, consider that as a new server and
- // don't wait for Cache thread to load the data for that server.
- load_from_disk_cache = false;
- }
+ MaybeInitialize();
+ if (!ContainsKey(quic_supported_servers_at_startup_,
+ server_id.host_port_pair())) {
+ // If there is no entry for QUIC, consider that as a new server and
+ // don't wait for Cache thread to load the data for that server.
+ load_from_disk_cache = false;
}
if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) {
quic_server_info = quic_server_info_factory_->GetForServer(server_id);
@@ -753,11 +776,10 @@ int QuicStreamFactory::Create(const HostPortPair& host_port_pair,
}
bool server_and_origin_have_same_host = host_port_pair.host() == origin_host;
- scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair,
- server_and_origin_have_same_host, is_https,
- WasQuicRecentlyBroken(server_id), privacy_mode,
- cert_verify_flags, method == "POST" /* is_post */,
- quic_server_info, net_log));
+ scoped_ptr<Job> job(new Job(
+ this, host_resolver_, host_port_pair, server_and_origin_have_same_host,
+ WasQuicRecentlyBroken(server_id), privacy_mode, cert_verify_flags,
+ method == "POST" /* is_post */, quic_server_info, net_log));
int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete,
base::Unretained(this), job.get()));
if (rv == ERR_IO_PENDING) {
@@ -788,30 +810,27 @@ void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id,
bool server_and_origin_have_same_host,
bool is_post,
const BoundNetLog& net_log) {
- Job* aux_job =
- new Job(this, host_resolver_, server_id.host_port_pair(),
- server_and_origin_have_same_host, server_id.is_https(),
- WasQuicRecentlyBroken(server_id), server_id.privacy_mode(),
- cert_verify_flags, is_post, nullptr, net_log);
+ Job* aux_job = new Job(
+ this, host_resolver_, server_id.host_port_pair(),
+ server_and_origin_have_same_host, WasQuicRecentlyBroken(server_id),
+ server_id.privacy_mode(), cert_verify_flags, is_post, nullptr, net_log);
active_jobs_[server_id].insert(aux_job);
task_runner_->PostTask(FROM_HERE,
base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob,
aux_job->GetWeakPtr()));
}
-bool QuicStreamFactory::OnResolution(
- const QuicServerId& server_id,
- const AddressList& address_list) {
+bool QuicStreamFactory::OnResolution(const QuicServerId& server_id,
+ const AddressList& address_list) {
DCHECK(!HasActiveSession(server_id));
if (disable_connection_pooling_) {
return false;
}
for (const IPEndPoint& address : address_list) {
- const IpAliasKey ip_alias_key(address, server_id.is_https());
- if (!ContainsKey(ip_aliases_, ip_alias_key))
+ if (!ContainsKey(ip_aliases_, address))
continue;
- const SessionSet& sessions = ip_aliases_[ip_alias_key];
+ const SessionSet& sessions = ip_aliases_[address];
for (QuicChromiumClientSession* session : sessions) {
if (!session->CanPool(server_id.host(), server_id.privacy_mode()))
continue;
@@ -891,7 +910,7 @@ scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateFromSession(
}
QuicChromiumClientSession::QuicDisabledReason
-QuicStreamFactory::QuicDisabledReason(uint16 port) const {
+QuicStreamFactory::QuicDisabledReason(uint16_t port) const {
if (max_number_of_lossy_connections_ > 0 &&
number_of_lossy_connections_.find(port) !=
number_of_lossy_connections_.end() &&
@@ -914,7 +933,7 @@ QuicStreamFactory::QuicDisabledReason(uint16 port) const {
const char* QuicStreamFactory::QuicDisabledReasonString() const {
// TODO(ckrasic) - better solution for port/lossy connections?
- const uint16 port = 443;
+ const uint16_t port = 443;
switch (QuicDisabledReason(port)) {
case QuicChromiumClientSession::QUIC_DISABLED_BAD_PACKET_LOSS_RATE:
return "Bad packet loss rate.";
@@ -927,7 +946,7 @@ const char* QuicStreamFactory::QuicDisabledReasonString() const {
}
}
-bool QuicStreamFactory::IsQuicDisabled(uint16 port) {
+bool QuicStreamFactory::IsQuicDisabled(uint16_t port) {
return QuicDisabledReason(port) !=
QuicChromiumClientSession::QUIC_DISABLED_NOT;
}
@@ -935,18 +954,16 @@ bool QuicStreamFactory::IsQuicDisabled(uint16 port) {
bool QuicStreamFactory::OnHandshakeConfirmed(QuicChromiumClientSession* session,
float packet_loss_rate) {
DCHECK(session);
- uint16 port = session->server_id().port();
+ uint16_t port = session->server_id().port();
if (packet_loss_rate < packet_loss_threshold_) {
number_of_lossy_connections_[port] = 0;
return false;
}
- if (http_server_properties_) {
- // We mark it as recently broken, which means that 0-RTT will be disabled
- // but we'll still race.
- http_server_properties_->MarkAlternativeServiceRecentlyBroken(
- AlternativeService(QUIC, session->server_id().host(), port));
- }
+ // We mark it as recently broken, which means that 0-RTT will be disabled
+ // but we'll still race.
+ http_server_properties_->MarkAlternativeServiceRecentlyBroken(
+ AlternativeService(QUIC, session->server_id().host(), port));
bool was_quic_disabled = IsQuicDisabled(port);
++number_of_lossy_connections_[port];
@@ -992,11 +1009,10 @@ void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) {
}
ProcessGoingAwaySession(session, all_sessions_[session], false);
if (!aliases.empty()) {
- const IpAliasKey ip_alias_key(session->connection()->peer_address(),
- aliases.begin()->is_https());
- ip_aliases_[ip_alias_key].erase(session);
- if (ip_aliases_[ip_alias_key].empty()) {
- ip_aliases_.erase(ip_alias_key);
+ const IPEndPoint peer_address = session->connection()->peer_address();
+ ip_aliases_[peer_address].erase(session);
+ if (ip_aliases_[peer_address].empty()) {
+ ip_aliases_.erase(peer_address);
}
}
session_aliases_.erase(session);
@@ -1004,7 +1020,7 @@ void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) {
void QuicStreamFactory::MaybeDisableQuic(QuicChromiumClientSession* session) {
DCHECK(session);
- uint16 port = session->server_id().port();
+ uint16_t port = session->server_id().port();
if (IsQuicDisabled(port))
return;
@@ -1061,7 +1077,7 @@ void QuicStreamFactory::MaybeDisableQuic(QuicChromiumClientSession* session) {
}
void QuicStreamFactory::OnSessionClosed(QuicChromiumClientSession* session) {
- DCHECK_EQ(0u, session->GetNumOpenStreams());
+ DCHECK_EQ(0u, session->GetNumActiveStreams());
MaybeDisableQuic(session);
OnSessionGoingAway(session);
delete session;
@@ -1082,11 +1098,10 @@ void QuicStreamFactory::OnSessionConnectTimeout(
return;
}
- const IpAliasKey ip_alias_key(session->connection()->peer_address(),
- aliases.begin()->is_https());
- ip_aliases_[ip_alias_key].erase(session);
- if (ip_aliases_[ip_alias_key].empty()) {
- ip_aliases_.erase(ip_alias_key);
+ const IPEndPoint peer_address = session->connection()->peer_address();
+ ip_aliases_[peer_address].erase(session);
+ if (ip_aliases_[peer_address].empty()) {
+ ip_aliases_.erase(peer_address);
}
QuicServerId server_id = *aliases.begin();
session_aliases_.erase(session);
@@ -1104,17 +1119,15 @@ void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) {
active_requests_.erase(request);
}
-void QuicStreamFactory::CloseAllSessions(int error) {
+void QuicStreamFactory::CloseAllSessions(int error, QuicErrorCode quic_error) {
while (!active_sessions_.empty()) {
size_t initial_size = active_sessions_.size();
- active_sessions_.begin()->second->CloseSessionOnError(error,
- QUIC_INTERNAL_ERROR);
+ active_sessions_.begin()->second->CloseSessionOnError(error, quic_error);
DCHECK_NE(initial_size, active_sessions_.size());
}
while (!all_sessions_.empty()) {
size_t initial_size = all_sessions_.size();
- all_sessions_.begin()->first->CloseSessionOnError(error,
- QUIC_INTERNAL_ERROR);
+ all_sessions_.begin()->first->CloseSessionOnError(error, quic_error);
DCHECK_NE(initial_size, all_sessions_.size());
}
DCHECK(all_sessions_.empty());
@@ -1139,7 +1152,7 @@ scoped_ptr<base::Value> QuicStreamFactory::QuicStreamFactoryInfoToValue()
list->Append(session->GetInfoAsValue(hosts));
}
}
- return list.Pass();
+ return std::move(list);
}
void QuicStreamFactory::ClearCachedStatesInCryptoConfig() {
@@ -1147,16 +1160,114 @@ void QuicStreamFactory::ClearCachedStatesInCryptoConfig() {
}
void QuicStreamFactory::OnIPAddressChanged() {
- CloseAllSessions(ERR_NETWORK_CHANGED);
+ CloseAllSessions(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED);
+ set_require_confirmation(true);
+}
+
+void QuicStreamFactory::OnNetworkConnected(
+ NetworkChangeNotifier::NetworkHandle network) {}
+
+void QuicStreamFactory::OnNetworkMadeDefault(
+ NetworkChangeNotifier::NetworkHandle network) {}
+
+void QuicStreamFactory::OnNetworkDisconnected(
+ NetworkChangeNotifier::NetworkHandle network) {
+ MaybeMigrateOrCloseSessions(network, /*force_close=*/true);
set_require_confirmation(true);
}
+// This method is expected to only be called when migrating from Cellular to
+// WiFi on Android.
+void QuicStreamFactory::OnNetworkSoonToDisconnect(
+ NetworkChangeNotifier::NetworkHandle network) {
+ MaybeMigrateOrCloseSessions(network, /*force_close=*/false);
+}
+
+void QuicStreamFactory::MaybeMigrateOrCloseSessions(
+ NetworkChangeNotifier::NetworkHandle network,
+ bool force_close) {
+ DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network);
+
+ // Find a new network that sessions bound to |network| can be migrated to.
+ NetworkChangeNotifier::NetworkList network_list;
+ NetworkChangeNotifier::GetConnectedNetworks(&network_list);
+ NetworkChangeNotifier::NetworkHandle new_network =
+ NetworkChangeNotifier::kInvalidNetworkHandle;
+ for (NetworkChangeNotifier::NetworkHandle n : network_list) {
+ if (n != network) {
+ new_network = n;
+ break;
+ }
+ }
+
+ QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin();
+ while (it != all_sessions_.end()) {
+ QuicChromiumClientSession* session = it->first;
+ QuicServerId server_id = it->second;
+ ++it;
+
+ if (session->GetDefaultSocket()->GetBoundNetwork() != network) {
+ // If session is not bound to |network|, move on.
+ HistogramMigrationStatus(MIGRATION_STATUS_ALREADY_MIGRATED);
+ continue;
+ }
+ if (session->GetNumActiveStreams() == 0) {
+ // Close idle sessions.
+ session->CloseSessionOnError(
+ ERR_NETWORK_CHANGED, QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
+ HistogramMigrationStatus(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS);
+ continue;
+ }
+ // If session has active streams, mark it as going away.
+ OnSessionGoingAway(session);
+ if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) {
+ // No new network was found.
+ if (force_close) {
+ session->CloseSessionOnError(ERR_NETWORK_CHANGED,
+ QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
+ }
+ continue;
+ }
+
+ // Use OS-specified port for socket (DEFAULT_BIND) instead of
+ // using the PortSuggester since the connection is being migrated
+ // and not being newly created.
+ scoped_ptr<DatagramClientSocket> socket(
+ client_socket_factory_->CreateDatagramClientSocket(
+ DatagramSocket::DEFAULT_BIND, RandIntCallback(),
+ session->net_log().net_log(), session->net_log().source()));
+
+ QuicConnection* connection = session->connection();
+ if (ConfigureSocket(socket.get(), connection->peer_address(),
+ new_network) != OK) {
+ session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR);
+ HistogramMigrationStatus(MIGRATION_STATUS_INTERNAL_ERROR);
+ continue;
+ }
+
+ scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader(
+ socket.get(), clock_.get(), session, yield_after_packets_,
+ yield_after_duration_, session->net_log()));
+ scoped_ptr<QuicPacketWriter> new_writer(
+ new QuicDefaultPacketWriter(socket.get()));
+
+ if (!session->MigrateToSocket(std::move(socket), std::move(new_reader),
+ std::move(new_writer))) {
+ session->CloseSessionOnError(ERR_NETWORK_CHANGED,
+ QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
+ HistogramMigrationStatus(MIGRATION_STATUS_TOO_MANY_CHANGES);
+ } else {
+ HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS);
+ }
+ }
+}
+
void QuicStreamFactory::OnSSLConfigChanged() {
- CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
+ CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR);
}
void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) {
- CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
+ CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR);
}
void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) {
@@ -1169,11 +1280,10 @@ void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) {
// Since the OnCACertChanged method doesn't tell us what
// kind of change it is, we have to flush the socket
// pools to be safe.
- CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
+ CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR);
}
-bool QuicStreamFactory::HasActiveSession(
- const QuicServerId& server_id) const {
+bool QuicStreamFactory::HasActiveSession(const QuicServerId& server_id) const {
// TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check.
if (active_sessions_.empty())
return false;
@@ -1184,62 +1294,41 @@ bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const {
return ContainsKey(active_jobs_, key);
}
-int QuicStreamFactory::CreateSession(const QuicServerId& server_id,
- int cert_verify_flags,
- scoped_ptr<QuicServerInfo> server_info,
- const AddressList& address_list,
- base::TimeTicks dns_resolution_end_time,
- const BoundNetLog& net_log,
- QuicChromiumClientSession** session) {
- bool enable_port_selection = enable_port_selection_;
- if (enable_port_selection &&
- ContainsKey(gone_away_aliases_, server_id)) {
- // Disable port selection when the server is going away.
- // There is no point in trying to return to the same server, if
- // that server is no longer handling requests.
- enable_port_selection = false;
- gone_away_aliases_.erase(server_id);
- }
-
- QuicConnectionId connection_id = random_generator_->RandUint64();
- IPEndPoint addr = *address_list.begin();
- scoped_refptr<PortSuggester> port_suggester =
- new PortSuggester(server_id.host_port_pair(), port_seed_);
- DatagramSocket::BindType bind_type = enable_port_selection ?
- DatagramSocket::RANDOM_BIND : // Use our callback.
- DatagramSocket::DEFAULT_BIND; // Use OS to randomize.
- scoped_ptr<DatagramClientSocket> socket(
- client_socket_factory_->CreateDatagramClientSocket(
- bind_type,
- base::Bind(&PortSuggester::SuggestPort, port_suggester),
- net_log.net_log(), net_log.source()));
-
+int QuicStreamFactory::ConfigureSocket(
+ DatagramClientSocket* socket,
+ IPEndPoint addr,
+ NetworkChangeNotifier::NetworkHandle network) {
if (enable_non_blocking_io_ &&
client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) {
#if defined(OS_WIN)
- static_cast<UDPClientSocket*>(socket.get())->UseNonBlockingIO();
+ static_cast<UDPClientSocket*>(socket)->UseNonBlockingIO();
#endif
}
- int rv = socket->Connect(addr);
+ // If caller leaves network unspecified, use current default.
+ int rv;
+ if (migrate_sessions_on_network_change_) {
+ if (network == NetworkChangeNotifier::kInvalidNetworkHandle) {
+ rv = socket->BindToDefaultNetwork();
+ } else {
+ rv = socket->BindToNetwork(network);
+ }
+ if (rv != OK)
+ return rv;
+ }
+ rv = socket->Connect(addr);
if (rv != OK) {
HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET);
return rv;
}
- UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested",
- port_suggester->call_count());
- if (enable_port_selection) {
- DCHECK_LE(1u, port_suggester->call_count());
- } else {
- DCHECK_EQ(0u, port_suggester->call_count());
- }
rv = socket->SetReceiveBufferSize(socket_receive_buffer_size_);
if (rv != OK) {
HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER);
return rv;
}
+
// Set a buffer large enough to contain the initial CWND's worth of packet
// to work around the problem with CHLO packets being sent out with the
// wrong encryption level, when the send buffer is full.
@@ -1250,7 +1339,7 @@ int QuicStreamFactory::CreateSession(const QuicServerId& server_id,
}
socket->GetLocalAddress(&local_address_);
- if (check_persisted_supports_quic_ && http_server_properties_) {
+ if (check_persisted_supports_quic_) {
check_persisted_supports_quic_ = false;
IPAddressNumber last_address;
if (http_server_properties_->GetSupportsQuic(&last_address) &&
@@ -1259,18 +1348,64 @@ int QuicStreamFactory::CreateSession(const QuicServerId& server_id,
}
}
- DefaultPacketWriterFactory packet_writer_factory(socket.get());
+ return OK;
+}
+
+int QuicStreamFactory::CreateSession(const QuicServerId& server_id,
+ int cert_verify_flags,
+ scoped_ptr<QuicServerInfo> server_info,
+ const AddressList& address_list,
+ base::TimeTicks dns_resolution_end_time,
+ const BoundNetLog& net_log,
+ QuicChromiumClientSession** session) {
+ IPEndPoint addr = *address_list.begin();
+ bool enable_port_selection = enable_port_selection_;
+ if (enable_port_selection && ContainsKey(gone_away_aliases_, server_id)) {
+ // Disable port selection when the server is going away.
+ // There is no point in trying to return to the same server, if
+ // that server is no longer handling requests.
+ enable_port_selection = false;
+ gone_away_aliases_.erase(server_id);
+ }
+ scoped_refptr<PortSuggester> port_suggester =
+ new PortSuggester(server_id.host_port_pair(), port_seed_);
+ DatagramSocket::BindType bind_type =
+ enable_port_selection ? DatagramSocket::RANDOM_BIND
+ : // Use our callback.
+ DatagramSocket::DEFAULT_BIND; // Use OS to randomize.
+
+ scoped_ptr<DatagramClientSocket> socket(
+ client_socket_factory_->CreateDatagramClientSocket(
+ bind_type, base::Bind(&PortSuggester::SuggestPort, port_suggester),
+ net_log.net_log(), net_log.source()));
+
+ // Passing in kInvalidNetworkHandle binds socket to default network.
+ int rv = ConfigureSocket(socket.get(), addr,
+ NetworkChangeNotifier::kInvalidNetworkHandle);
+ if (rv != OK) {
+ return rv;
+ }
+
+ UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested",
+ port_suggester->call_count());
+ if (enable_port_selection) {
+ DCHECK_LE(1u, port_suggester->call_count());
+ } else {
+ DCHECK_EQ(0u, port_suggester->call_count());
+ }
if (!helper_.get()) {
- helper_.reset(
- new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(),
- clock_.get(), random_generator_));
+ helper_.reset(new QuicChromiumConnectionHelper(
+ base::ThreadTaskRunnerHandle::Get().get(), clock_.get(),
+ random_generator_));
}
+ QuicDefaultPacketWriter* writer = new QuicDefaultPacketWriter(socket.get());
+ QuicConnectionId connection_id = random_generator_->RandUint64();
QuicConnection* connection = new QuicConnection(
- connection_id, addr, helper_.get(), packet_writer_factory,
- true /* owns_writer */, Perspective::IS_CLIENT, server_id.is_https(),
- supported_versions_);
+ connection_id, addr, helper_.get(), writer, true /* owns_writer */,
+ Perspective::IS_CLIENT, supported_versions_);
+ writer->SetConnection(connection);
connection->SetMaxPacketLength(max_packet_length_);
InitializeCachedStateInCryptoConfig(server_id, server_info);
@@ -1281,12 +1416,12 @@ int QuicStreamFactory::CreateSession(const QuicServerId& server_id,
config.SetInitialSessionFlowControlWindowToSend(
kQuicSessionMaxRecvWindowSize);
config.SetInitialStreamFlowControlWindowToSend(kQuicStreamMaxRecvWindowSize);
- int64 srtt = GetServerNetworkStatsSmoothedRttInMicroseconds(server_id);
+ int64_t srtt = GetServerNetworkStatsSmoothedRttInMicroseconds(server_id);
if (srtt > 0)
- config.SetInitialRoundTripTimeUsToSend(static_cast<uint32>(srtt));
+ config.SetInitialRoundTripTimeUsToSend(static_cast<uint32_t>(srtt));
config.SetBytesForConnectionIdToSend(0);
- if (quic_server_info_factory_ && !server_info) {
+ if (quic_server_info_factory_.get() && !server_info) {
// Start the disk cache loading so that we can persist the newer QUIC server
// information and/or inform the disk cache that we have reused
// |server_info|.
@@ -1298,24 +1433,24 @@ int QuicStreamFactory::CreateSession(const QuicServerId& server_id,
// ownership to QuicChromiumClientSession.
scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher;
if (socket_performance_watcher_factory_) {
- socket_performance_watcher = socket_performance_watcher_factory_
- ->CreateUDPSocketPerformanceWatcher();
+ socket_performance_watcher =
+ socket_performance_watcher_factory_->CreateSocketPerformanceWatcher(
+ SocketPerformanceWatcherFactory::PROTOCOL_QUIC);
}
*session = new QuicChromiumClientSession(
- connection, socket.Pass(), this, quic_crypto_client_stream_factory_,
- clock_.get(), transport_security_state_, server_info.Pass(), server_id,
- yield_after_packets_, yield_after_duration_, cert_verify_flags, config,
- &crypto_config_, network_connection_.GetDescription(),
+ connection, std::move(socket), this, quic_crypto_client_stream_factory_,
+ clock_.get(), transport_security_state_, std::move(server_info),
+ server_id, yield_after_packets_, yield_after_duration_, cert_verify_flags,
+ config, &crypto_config_, network_connection_.GetDescription(),
dns_resolution_end_time, base::ThreadTaskRunnerHandle::Get().get(),
- socket_performance_watcher.Pass(), net_log.net_log());
+ std::move(socket_performance_watcher), net_log.net_log());
all_sessions_[*session] = server_id; // owning pointer
(*session)->Initialize();
- bool closed_during_initialize =
- !ContainsKey(all_sessions_, *session) ||
- !(*session)->connection()->connected();
+ bool closed_during_initialize = !ContainsKey(all_sessions_, *session) ||
+ !(*session)->connection()->connected();
UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession",
closed_during_initialize);
if (closed_during_initialize) {
@@ -1332,16 +1467,13 @@ void QuicStreamFactory::ActivateSession(const QuicServerId& server_id,
UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size());
active_sessions_[server_id] = session;
session_aliases_[session].insert(server_id);
- const IpAliasKey ip_alias_key(session->connection()->peer_address(),
- server_id.is_https());
- DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session));
- ip_aliases_[ip_alias_key].insert(session);
+ const IPEndPoint peer_address = session->connection()->peer_address();
+ DCHECK(!ContainsKey(ip_aliases_[peer_address], session));
+ ip_aliases_[peer_address].insert(session);
}
-int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds(
+int64_t QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds(
const QuicServerId& server_id) const {
- if (!http_server_properties_)
- return 0;
const ServerNetworkStats* stats =
http_server_properties_->GetServerNetworkStats(
server_id.host_port_pair());
@@ -1352,8 +1484,6 @@ int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds(
bool QuicStreamFactory::WasQuicRecentlyBroken(
const QuicServerId& server_id) const {
- if (!http_server_properties_)
- return false;
const AlternativeService alternative_service(QUIC,
server_id.host_port_pair());
return http_server_properties_->WasAlternativeServiceRecentlyBroken(
@@ -1380,36 +1510,30 @@ void QuicStreamFactory::InitializeCachedStateInCryptoConfig(
if (!cached->IsEmpty())
return;
- if (http_server_properties_) {
- DCHECK(quic_supported_servers_at_startup_initialzied_);
- // TODO(rtenneti): Delete the following histogram after collecting stats.
- // If the AlternativeServiceMap contained an entry for this host, check if
- // the disk cache contained an entry for it.
- if (ContainsKey(quic_supported_servers_at_startup_,
- server_id.host_port_pair())) {
- UMA_HISTOGRAM_BOOLEAN(
- "Net.QuicServerInfo.ExpectConfigMissingFromDiskCache",
- server_info->state().server_config.empty());
- }
+ // TODO(rtenneti): Delete the following histogram after collecting stats.
+ // If the AlternativeServiceMap contained an entry for this host, check if
+ // the disk cache contained an entry for it.
+ if (ContainsKey(quic_supported_servers_at_startup_,
+ server_id.host_port_pair())) {
+ UMA_HISTOGRAM_BOOLEAN("Net.QuicServerInfo.ExpectConfigMissingFromDiskCache",
+ server_info->state().server_config.empty());
}
- if (!cached->Initialize(server_info->state().server_config,
- server_info->state().source_address_token,
- server_info->state().certs,
- server_info->state().server_config_sig,
- clock_->WallNow()))
- return;
-
- if (!server_id.is_https()) {
- // Don't check the certificates for insecure QUIC.
- cached->SetProofValid();
- }
+ cached->Initialize(server_info->state().server_config,
+ server_info->state().source_address_token,
+ server_info->state().certs, "",
+ server_info->state().server_config_sig, clock_->WallNow());
}
-void QuicStreamFactory::InitializeQuicSupportedServersAtStartup() {
- DCHECK(http_server_properties_);
- DCHECK(!quic_supported_servers_at_startup_initialzied_);
- quic_supported_servers_at_startup_initialzied_ = true;
+void QuicStreamFactory::MaybeInitialize() {
+ // We don't initialize data from HttpServerProperties in the constructor
+ // because HttpServerProperties has not yet initialized. We're guaranteed
+ // HttpServerProperties has been initialized by the first time a request is
+ // made.
+ if (has_initialized_data_)
+ return;
+
+ has_initialized_data_ = true;
for (const std::pair<const HostPortPair, AlternativeServiceInfoVector>&
key_value : http_server_properties_->alternative_service_map()) {
for (const AlternativeServiceInfo& alternative_service_info :
@@ -1420,6 +1544,22 @@ void QuicStreamFactory::InitializeQuicSupportedServersAtStartup() {
}
}
}
+
+ if (http_server_properties_->max_server_configs_stored_in_properties() == 0)
+ return;
+ // Create a temporary QuicServerInfo object to deserialize and to populate the
+ // in-memory crypto server config cache.
+ scoped_ptr<QuicServerInfo> server_info;
+ CompletionCallback callback;
+ for (const auto& key_value :
+ http_server_properties_->quic_server_info_map()) {
+ const QuicServerId& server_id = key_value.first;
+ server_info.reset(quic_server_info_factory_->GetForServer(server_id));
+ if (server_info->WaitForDataReady(callback) == OK) {
+ DVLOG(1) << "Initialized server config for: " << server_id.ToString();
+ InitializeCachedStateInCryptoConfig(server_id, server_info);
+ }
+ }
}
void QuicStreamFactory::ProcessGoingAwaySession(
diff --git a/chromium/net/quic/quic_stream_factory.h b/chromium/net/quic/quic_stream_factory.h
index 162607b5459..9a7cfe5e74e 100644
--- a/chromium/net/quic/quic_stream_factory.h
+++ b/chromium/net/quic/quic_stream_factory.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_QUIC_STREAM_FACTORY_H_
#define NET_QUIC_QUIC_STREAM_FACTORY_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
#include <map>
#include <string>
@@ -12,6 +15,7 @@
#include "base/gtest_prod_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "net/base/address_list.h"
@@ -19,6 +23,7 @@
#include "net/base/host_port_pair.h"
#include "net/base/network_change_notifier.h"
#include "net/cert/cert_database.h"
+#include "net/http/http_server_properties.h"
#include "net/log/net_log.h"
#include "net/proxy/proxy_server.h"
#include "net/quic/network_connection.h"
@@ -31,19 +36,21 @@
namespace net {
-class CertPolicyEnforcer;
+class CTPolicyEnforcer;
class CertVerifier;
class ChannelIDService;
class ClientSocketFactory;
+class CTVerifier;
class HostResolver;
class HttpServerProperties;
class QuicClock;
class QuicChromiumClientSession;
-class QuicConnectionHelper;
+class QuicChromiumConnectionHelper;
class QuicCryptoClientStreamFactory;
class QuicRandom;
-class QuicServerInfoFactory;
class QuicServerId;
+class QuicServerInfo;
+class QuicServerInfoFactory;
class QuicStreamFactory;
class SocketPerformanceWatcherFactory;
class TransportSecurityState;
@@ -52,6 +59,9 @@ namespace test {
class QuicStreamFactoryPeer;
} // namespace test
+// When a connection is idle for 30 seconds it will be closed.
+const int kIdleConnectionTimeoutSeconds = 30;
+
// Encapsulates a pending request for a QuicHttpStream.
// If the request is still pending when it is destroyed, it will
// cancel the request with the factory.
@@ -60,11 +70,9 @@ class NET_EXPORT_PRIVATE QuicStreamRequest {
explicit QuicStreamRequest(QuicStreamFactory* factory);
~QuicStreamRequest();
- // For http, |is_https| is false.
// |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
// passed to CertVerifier::Verify.
int Request(const HostPortPair& host_port_pair,
- bool is_https,
PrivacyMode privacy_mode,
int cert_verify_flags,
base::StringPiece origin_host,
@@ -92,7 +100,6 @@ class NET_EXPORT_PRIVATE QuicStreamRequest {
QuicStreamFactory* factory_;
HostPortPair host_port_pair_;
std::string origin_host_;
- bool is_https_;
PrivacyMode privacy_mode_;
BoundNetLog net_log_;
CompletionCallback callback_;
@@ -105,6 +112,7 @@ class NET_EXPORT_PRIVATE QuicStreamRequest {
// QuicChromiumClientSessions.
class NET_EXPORT_PRIVATE QuicStreamFactory
: public NetworkChangeNotifier::IPAddressObserver,
+ public NetworkChangeNotifier::NetworkObserver,
public SSLConfigService::Observer,
public CertDatabase::Observer {
public:
@@ -113,10 +121,11 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
ClientSocketFactory* client_socket_factory,
base::WeakPtr<HttpServerProperties> http_server_properties,
CertVerifier* cert_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
ChannelIDService* channel_id_service,
TransportSecurityState* transport_security_state,
- const SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
+ CTVerifier* cert_transparency_verifier,
+ SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
QuicRandom* random_generator,
QuicClock* clock,
@@ -138,16 +147,25 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
int threshold_public_resets_post_handshake,
int socket_receive_buffer_size,
bool delay_tcp_race,
+ int max_server_configs_stored_in_properties,
+ bool close_sessions_on_ip_change,
+ int idle_connection_timeout_seconds,
+ bool migrate_sessions_on_network_change,
const QuicTagVector& connection_options);
~QuicStreamFactory() override;
+ // Returns true if there is an existing session to |server_id| which can be
+ // used for request to |origin_host|.
+ bool CanUseExistingSession(QuicServerId server_id,
+ PrivacyMode privacy_mode,
+ StringPiece origin_host);
+
// Creates a new QuicHttpStream to |host_port_pair| which will be
- // owned by |request|. |is_https| specifies if the protocol is https or not.
+ // owned by |request|.
// If a matching session already exists, this method will return OK. If no
// matching session exists, this will return ERR_IO_PENDING and will invoke
// OnRequestComplete asynchronously.
int Create(const HostPortPair& host_port_pair,
- bool is_https,
PrivacyMode privacy_mode,
int cert_verify_flags,
base::StringPiece origin_host,
@@ -166,11 +184,11 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
float packet_loss_rate);
// Returns true if QUIC is disabled for this port.
- bool IsQuicDisabled(uint16 port);
+ bool IsQuicDisabled(uint16_t port);
// Returns reason QUIC is disabled for this port, or QUIC_DISABLED_NOT if not.
QuicChromiumClientSession::QuicDisabledReason QuicDisabledReason(
- uint16 port) const;
+ uint16_t port) const;
// Returns reason QUIC is disabled as string for net-internals, or
// returns empty string if QUIC is not disabled.
@@ -192,20 +210,47 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// Cancels a pending request.
void CancelRequest(QuicStreamRequest* request);
- // Closes all current sessions.
- void CloseAllSessions(int error);
+ // Closes all current sessions with specified network and QUIC error codes.
+ void CloseAllSessions(int error, QuicErrorCode quic_error);
scoped_ptr<base::Value> QuicStreamFactoryInfoToValue() const;
// Delete all cached state objects in |crypto_config_|.
void ClearCachedStatesInCryptoConfig();
+ // Helper method that configures a DatagramClientSocket. Socket is
+ // bound to the default network if the |network| param is
+ // NetworkChangeNotifier::kInvalidNetworkHandle.
+ // Returns net_error code.
+ int ConfigureSocket(DatagramClientSocket* socket,
+ IPEndPoint addr,
+ NetworkChangeNotifier::NetworkHandle network);
+
+ // Helper method that initiates migration of active sessions
+ // currently bound to |network| to an alternate network, if one
+ // exists. Idle sessions bound to |network| are closed. If there is
+ // no alternate network to migrate active sessions onto, active
+ // sessions are closed if |force_close| is true, and continue using
+ // |network| otherwise. Sessions not bound to |network| are left unchanged.
+ void MaybeMigrateOrCloseSessions(NetworkChangeNotifier::NetworkHandle network,
+ bool force_close);
+
// NetworkChangeNotifier::IPAddressObserver methods:
// Until the servers support roaming, close all connections when the local
// IP address changes.
void OnIPAddressChanged() override;
+ // NetworkChangeNotifier::NetworkObserver methods:
+ void OnNetworkConnected(
+ NetworkChangeNotifier::NetworkHandle network) override;
+ void OnNetworkDisconnected(
+ NetworkChangeNotifier::NetworkHandle network) override;
+ void OnNetworkSoonToDisconnect(
+ NetworkChangeNotifier::NetworkHandle network) override;
+ void OnNetworkMadeDefault(
+ NetworkChangeNotifier::NetworkHandle network) override;
+
// SSLConfigService::Observer methods:
// We perform the same flushing as described above when SSL settings change.
@@ -217,28 +262,25 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
void OnCertAdded(const X509Certificate* cert) override;
void OnCACertChanged(const X509Certificate* cert) override;
- bool require_confirmation() const {
- return require_confirmation_;
- }
+ bool require_confirmation() const { return require_confirmation_; }
void set_require_confirmation(bool require_confirmation);
+ bool ZeroRTTEnabledFor(const QuicServerId& server_id);
+
// It returns the amount of time waiting job should be delayed.
base::TimeDelta GetTimeDelayForWaitingJob(const QuicServerId& server_id);
- QuicConnectionHelper* helper() { return helper_.get(); }
+ QuicChromiumConnectionHelper* helper() { return helper_.get(); }
bool enable_port_selection() const { return enable_port_selection_; }
bool has_quic_server_info_factory() {
- return quic_server_info_factory_ != NULL;
+ return quic_server_info_factory_.get() != nullptr;
}
void set_quic_server_info_factory(
- QuicServerInfoFactory* quic_server_info_factory) {
- DCHECK(!quic_server_info_factory_);
- quic_server_info_factory_ = quic_server_info_factory;
- }
+ QuicServerInfoFactory* quic_server_info_factory);
bool enable_connection_racing() const { return enable_connection_racing_; }
void set_enable_connection_racing(bool enable_connection_racing) {
@@ -254,27 +296,12 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
friend class test::QuicStreamFactoryPeer;
FRIEND_TEST_ALL_PREFIXES(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad);
- // The key used to find session by ip. Includes
- // the ip address, port, and scheme.
- struct NET_EXPORT_PRIVATE IpAliasKey {
- IpAliasKey();
- IpAliasKey(IPEndPoint ip_endpoint, bool is_https);
- ~IpAliasKey();
-
- IPEndPoint ip_endpoint;
- bool is_https;
-
- // Needed to be an element of std::set.
- bool operator<(const IpAliasKey &other) const;
- bool operator==(const IpAliasKey &other) const;
- };
-
typedef std::map<QuicServerId, QuicChromiumClientSession*> SessionMap;
typedef std::map<QuicChromiumClientSession*, QuicServerId> SessionIdMap;
typedef std::set<QuicServerId> AliasSet;
typedef std::map<QuicChromiumClientSession*, AliasSet> SessionAliasMap;
typedef std::set<QuicChromiumClientSession*> SessionSet;
- typedef std::map<IpAliasKey, SessionSet> IPAliasMap;
+ typedef std::map<IPEndPoint, SessionSet> IPAliasMap;
typedef std::map<QuicServerId, QuicCryptoClientConfig*> CryptoConfigMap;
typedef std::set<Job*> JobSet;
typedef std::map<QuicServerId, JobSet> JobMap;
@@ -314,7 +341,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// Returns |srtt| in micro seconds from ServerNetworkStats. Returns 0 if there
// is no |http_server_properties_| or if |http_server_properties_| doesn't
// have ServerNetworkStats for the given |server_id|.
- int64 GetServerNetworkStatsSmoothedRttInMicroseconds(
+ int64_t GetServerNetworkStatsSmoothedRttInMicroseconds(
const QuicServerId& server_id) const;
// Helper methods.
@@ -329,8 +356,9 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
const scoped_ptr<QuicServerInfo>& server_info);
// Initialize |quic_supported_servers_at_startup_| with the list of servers
- // that supported QUIC at start up.
- void InitializeQuicSupportedServersAtStartup();
+ // that supported QUIC at start up and also initialize in-memory cache of
+ // QuicServerInfo objects from HttpServerProperties.
+ void MaybeInitialize();
void ProcessGoingAwaySession(QuicChromiumClientSession* session,
const QuicServerId& server_id,
@@ -344,7 +372,8 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
ClientSocketFactory* client_socket_factory_;
base::WeakPtr<HttpServerProperties> http_server_properties_;
TransportSecurityState* transport_security_state_;
- QuicServerInfoFactory* quic_server_info_factory_;
+ CTVerifier* cert_transparency_verifier_;
+ scoped_ptr<QuicServerInfoFactory> quic_server_info_factory_;
QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory_;
QuicRandom* random_generator_;
scoped_ptr<QuicClock> clock_;
@@ -353,10 +382,10 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// Factory which is used to create socket performance watcher. A new watcher
// is created for every QUIC connection.
// |socket_performance_watcher_factory_| may be null.
- const SocketPerformanceWatcherFactory* socket_performance_watcher_factory_;
+ SocketPerformanceWatcherFactory* socket_performance_watcher_factory_;
// The helper used for all connections.
- scoped_ptr<QuicConnectionHelper> helper_;
+ scoped_ptr<QuicChromiumConnectionHelper> helper_;
// Contains owning pointers to all sessions that currently exist.
SessionIdMap all_sessions_;
@@ -420,7 +449,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// and is considered as a lossy connection.
float packet_loss_threshold_;
// Count number of lossy connections by port.
- std::map<uint16, int> number_of_lossy_connections_;
+ std::map<uint16_t, int> number_of_lossy_connections_;
// Keep track of stats for recently closed connections, using a
// bounded queue.
@@ -449,18 +478,25 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
int yield_after_packets_;
QuicTime::Delta yield_after_duration_;
+ // Set if all sessions should be closed when any local IP address changes.
+ const bool close_sessions_on_ip_change_;
+
+ // Set if migration should be attempted on active sessions when primary
+ // interface changes.
+ const bool migrate_sessions_on_network_change_;
+
// Each profile will (probably) have a unique port_seed_ value. This value
// is used to help seed a pseudo-random number generator (PortSuggester) so
// that we consistently (within this profile) suggest the same ephemeral
// port when we re-connect to any given server/port. The differences between
// profiles (probablistically) prevent two profiles from colliding in their
// ephemeral port requests.
- uint64 port_seed_;
+ uint64_t port_seed_;
// Local address of socket that was created in CreateSession.
IPEndPoint local_address_;
bool check_persisted_supports_quic_;
- bool quic_supported_servers_at_startup_initialzied_;
+ bool has_initialized_data_;
std::set<HostPortPair> quic_supported_servers_at_startup_;
NetworkConnection network_connection_;
diff --git a/chromium/net/quic/quic_stream_factory_test.cc b/chromium/net/quic/quic_stream_factory_test.cc
index 4209bc47ecb..8754453ccab 100644
--- a/chromium/net/quic/quic_stream_factory_test.cc
+++ b/chromium/net/quic/quic_stream_factory_test.cc
@@ -9,6 +9,7 @@
#include "base/thread_task_runner_handle.h"
#include "net/base/test_data_directory.h"
#include "net/cert/cert_verifier.h"
+#include "net/cert/multi_log_ct_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
@@ -17,14 +18,18 @@
#include "net/http/transport_security_state.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
+#include "net/quic/crypto/properties_based_quic_server_info.h"
+#include "net/quic/crypto/quic_crypto_client_config.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/crypto/quic_server_info.h"
#include "net/quic/quic_http_stream.h"
+#include "net/quic/quic_http_utils.h"
#include "net/quic/quic_server_id.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
#include "net/quic/test_tools/mock_random.h"
+#include "net/quic/test_tools/quic_stream_factory_peer.h"
#include "net/quic/test_tools/quic_test_packet_maker.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/test_task_runner.h"
@@ -42,10 +47,14 @@ using std::string;
using std::vector;
namespace net {
+
namespace test {
namespace {
-const char kDefaultServerHostName[] = "www.google.com";
+const char kDefaultServerHostName[] = "www.example.org";
+const char kServer2HostName[] = "mail.example.org";
+const char kServer3HostName[] = "docs.example.org";
+const char kServer4HostName[] = "images.example.org";
const int kDefaultServerPort = 443;
// Run all tests with all the combinations of versions and
@@ -77,180 +86,104 @@ vector<TestParams> GetTestParams() {
} // namespace anonymous
-class QuicStreamFactoryPeer {
+class MockQuicServerInfo : public QuicServerInfo {
public:
- static QuicCryptoClientConfig* GetCryptoConfig(QuicStreamFactory* factory) {
- return &factory->crypto_config_;
- }
-
- static bool HasActiveSession(QuicStreamFactory* factory,
- const HostPortPair& host_port_pair,
- bool is_https) {
- QuicServerId server_id(host_port_pair, is_https, PRIVACY_MODE_DISABLED);
- return factory->HasActiveSession(server_id);
- }
-
- static QuicChromiumClientSession* GetActiveSession(
- QuicStreamFactory* factory,
- const HostPortPair& host_port_pair,
- bool is_https) {
- QuicServerId server_id(host_port_pair, is_https, PRIVACY_MODE_DISABLED);
- DCHECK(factory->HasActiveSession(server_id));
- return factory->active_sessions_[server_id];
- }
-
- static scoped_ptr<QuicHttpStream> CreateFromSession(
- QuicStreamFactory* factory,
- QuicChromiumClientSession* session) {
- return factory->CreateFromSession(session);
- }
-
- static bool IsLiveSession(QuicStreamFactory* factory,
- QuicChromiumClientSession* session) {
- for (QuicStreamFactory::SessionIdMap::iterator it =
- factory->all_sessions_.begin();
- it != factory->all_sessions_.end(); ++it) {
- if (it->first == session)
- return true;
- }
- return false;
- }
-
- static void DisableConnectionPooling(QuicStreamFactory* factory) {
- factory->disable_connection_pooling_ = true;
- }
+ MockQuicServerInfo(const QuicServerId& server_id)
+ : QuicServerInfo(server_id) {}
+ ~MockQuicServerInfo() override {}
- static void SetTaskRunner(QuicStreamFactory* factory,
- base::TaskRunner* task_runner) {
- factory->task_runner_ = task_runner;
- }
+ void Start() override {}
- static void SetEnableConnectionRacing(QuicStreamFactory* factory,
- bool enable_connection_racing) {
- factory->enable_connection_racing_ = enable_connection_racing;
+ int WaitForDataReady(const CompletionCallback& callback) override {
+ return ERR_IO_PENDING;
}
- static void SetDisableDiskCache(QuicStreamFactory* factory,
- bool disable_disk_cache) {
- factory->disable_disk_cache_ = disable_disk_cache;
- }
+ void ResetWaitForDataReadyCallback() override {}
- static void SetMaxNumberOfLossyConnections(
- QuicStreamFactory* factory,
- int max_number_of_lossy_connections) {
- factory->max_number_of_lossy_connections_ = max_number_of_lossy_connections;
- }
+ void CancelWaitForDataReadyCallback() override {}
- static int GetNumberOfLossyConnections(QuicStreamFactory* factory,
- uint16 port) {
- return factory->number_of_lossy_connections_[port];
- }
+ bool IsDataReady() override { return false; }
- static bool IsQuicDisabled(QuicStreamFactory* factory, uint16 port) {
- return factory->IsQuicDisabled(port);
- }
+ bool IsReadyToPersist() override { return false; }
- static bool GetDelayTcpRace(QuicStreamFactory* factory) {
- return factory->delay_tcp_race_;
- }
+ void Persist() override {}
- static void SetDelayTcpRace(QuicStreamFactory* factory, bool delay_tcp_race) {
- factory->delay_tcp_race_ = delay_tcp_race;
- }
+ void OnExternalCacheHit() override {}
+};
- static void SetYieldAfterPackets(QuicStreamFactory* factory,
- int yield_after_packets) {
- factory->yield_after_packets_ = yield_after_packets;
- }
+class MockQuicServerInfoFactory : public QuicServerInfoFactory {
+ public:
+ MockQuicServerInfoFactory() {}
+ ~MockQuicServerInfoFactory() override {}
- static void SetYieldAfterDuration(QuicStreamFactory* factory,
- QuicTime::Delta yield_after_duration) {
- factory->yield_after_duration_ = yield_after_duration;
+ QuicServerInfo* GetForServer(const QuicServerId& server_id) override {
+ return new MockQuicServerInfo(server_id);
}
+};
- static void SetHttpServerProperties(
- QuicStreamFactory* factory,
- base::WeakPtr<HttpServerProperties> http_server_properties) {
- factory->http_server_properties_ = http_server_properties;
- }
+class MockNetworkChangeNotifier : public NetworkChangeNotifier {
+ public:
+ MockNetworkChangeNotifier() : force_network_handles_supported_(false) {}
- static size_t GetNumberOfActiveJobs(QuicStreamFactory* factory,
- const QuicServerId& server_id) {
- return (factory->active_jobs_[server_id]).size();
+ ConnectionType GetCurrentConnectionType() const override {
+ return CONNECTION_UNKNOWN;
}
- static void SetThresholdTimeoutsWithOpenStreams(
- QuicStreamFactory* factory,
- int threshold_timeouts_with_open_streams) {
- factory->threshold_timeouts_with_open_streams_ =
- threshold_timeouts_with_open_streams;
+ void ForceNetworkHandlesSupported() {
+ force_network_handles_supported_ = true;
}
- static int GetNumTimeoutsWithOpenStreams(QuicStreamFactory* factory) {
- return factory->num_timeouts_with_open_streams_;
+ bool AreNetworkHandlesCurrentlySupported() const override {
+ return force_network_handles_supported_;
}
- static void SetThresholdPublicResetsPostHandshake(
- QuicStreamFactory* factory,
- int threshold_public_resets_post_handshake) {
- factory->threshold_public_resets_post_handshake_ =
- threshold_public_resets_post_handshake;
+ void SetConnectedNetworksList(const NetworkList& network_list) {
+ connected_networks_ = network_list;
}
- static int GetNumPublicResetsPostHandshake(QuicStreamFactory* factory) {
- return factory->num_public_resets_post_handshake_;
+ void GetCurrentConnectedNetworks(NetworkList* network_list) const override {
+ network_list->clear();
+ *network_list = connected_networks_;
}
- static void InitializeQuicSupportedServersAtStartup(
- QuicStreamFactory* factory) {
- factory->InitializeQuicSupportedServersAtStartup();
+ void NotifyNetworkSoonToDisconnect(
+ NetworkChangeNotifier::NetworkHandle network) {
+ NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
+ NetworkChangeNotifier::SOON_TO_DISCONNECT, network);
+ // Spin the message loop so the notification is delivered.
+ base::MessageLoop::current()->RunUntilIdle();
}
- static bool GetQuicSupportedServersAtStartupInitialzied(
- QuicStreamFactory* factory) {
- return factory->quic_supported_servers_at_startup_initialzied_;
+ void NotifyNetworkDisconnected(NetworkChangeNotifier::NetworkHandle network) {
+ NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
+ NetworkChangeNotifier::DISCONNECTED, network);
+ // Spin the message loop so the notification is delivered.
+ base::MessageLoop::current()->RunUntilIdle();
}
- static bool SupportsQuicAtStartUp(QuicStreamFactory* factory,
- HostPortPair host_port_pair) {
- return ContainsKey(factory->quic_supported_servers_at_startup_,
- host_port_pair);
- }
+ private:
+ bool force_network_handles_supported_;
+ NetworkChangeNotifier::NetworkList connected_networks_;
};
-class MockQuicServerInfo : public QuicServerInfo {
+// Class to replace existing NetworkChangeNotifier singleton with a
+// MockNetworkChangeNotifier for a test. To use, simply create a
+// ScopedMockNetworkChangeNotifier object in the test.
+class ScopedMockNetworkChangeNotifier {
public:
- MockQuicServerInfo(const QuicServerId& server_id)
- : QuicServerInfo(server_id) {}
- ~MockQuicServerInfo() override {}
-
- void Start() override {}
+ ScopedMockNetworkChangeNotifier()
+ : disable_network_change_notifier_for_tests_(
+ new NetworkChangeNotifier::DisableForTest()),
+ mock_network_change_notifier_(new MockNetworkChangeNotifier()) {}
- int WaitForDataReady(const CompletionCallback& callback) override {
- return ERR_IO_PENDING;
+ MockNetworkChangeNotifier* mock_network_change_notifier() {
+ return mock_network_change_notifier_.get();
}
- void ResetWaitForDataReadyCallback() override {}
-
- void CancelWaitForDataReadyCallback() override {}
-
- bool IsDataReady() override { return false; }
-
- bool IsReadyToPersist() override { return false; }
-
- void Persist() override {}
-
- void OnExternalCacheHit() override {}
-};
-
-class MockQuicServerInfoFactory : public QuicServerInfoFactory {
- public:
- MockQuicServerInfoFactory() {}
- ~MockQuicServerInfoFactory() override {}
-
- QuicServerInfo* GetForServer(const QuicServerId& server_id) override {
- return new MockQuicServerInfo(server_id);
- }
+ private:
+ scoped_ptr<NetworkChangeNotifier::DisableForTest>
+ disable_network_change_notifier_for_tests_;
+ scoped_ptr<MockNetworkChangeNotifier> mock_network_change_notifier_;
};
class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> {
@@ -264,64 +197,85 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> {
channel_id_service_(
new ChannelIDService(new DefaultChannelIDStore(nullptr),
base::ThreadTaskRunnerHandle::Get())),
- factory_(&host_resolver_,
- &socket_factory_,
- base::WeakPtr<HttpServerProperties>(),
- cert_verifier_.get(),
- nullptr,
- channel_id_service_.get(),
- &transport_security_state_,
- /*SocketPerformanceWatcherFactory*/ nullptr,
- &crypto_client_stream_factory_,
- &random_generator_,
- clock_,
- kDefaultMaxPacketSize,
- std::string(),
- SupportedVersions(GetParam().version),
- /*enable_port_selection=*/true,
- /*always_require_handshake_confirmation=*/false,
- /*disable_connection_pooling=*/false,
- /*load_server_info_timeout_srtt_multiplier=*/0.0f,
- /*enable_connection_racing=*/false,
- /*enable_non_blocking_io=*/true,
- /*disable_disk_cache=*/false,
- /*prefer_aes=*/false,
- /*max_number_of_lossy_connections=*/0,
- /*packet_loss_threshold=*/1.0f,
- /*max_disabled_reasons=*/3,
- /*threshold_timeouts_with_open_streams=*/2,
- /*threshold_pulic_resets_post_handshake=*/2,
- /*receive_buffer_size=*/0,
- /*delay_tcp_race=*/false,
- QuicTagVector()),
+ cert_transparency_verifier_(new MultiLogCTVerifier()),
+ scoped_mock_network_change_notifier_(nullptr),
+ factory_(nullptr),
host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
- is_https_(false),
- privacy_mode_(PRIVACY_MODE_DISABLED) {
- factory_.set_require_confirmation(false);
+ privacy_mode_(PRIVACY_MODE_DISABLED),
+ enable_port_selection_(true),
+ always_require_handshake_confirmation_(false),
+ disable_connection_pooling_(false),
+ load_server_info_timeout_srtt_multiplier_(0.0f),
+ enable_connection_racing_(true),
+ enable_non_blocking_io_(true),
+ disable_disk_cache_(false),
+ prefer_aes_(false),
+ max_number_of_lossy_connections_(0),
+ packet_loss_threshold_(1.0f),
+ max_disabled_reasons_(3),
+ threshold_timeouts_with_open_streams_(2),
+ threshold_public_resets_post_handshake_(2),
+ receive_buffer_size_(0),
+ delay_tcp_race_(false),
+ close_sessions_on_ip_change_(false),
+ idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds),
+ migrate_sessions_on_network_change_(false) {
clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- QuicStreamFactoryPeer::SetEnableConnectionRacing(
- &factory_, GetParam().enable_connection_racing);
+ }
+
+ void Initialize() {
+ factory_.reset(new QuicStreamFactory(
+ &host_resolver_, &socket_factory_, http_server_properties_.GetWeakPtr(),
+ cert_verifier_.get(), nullptr, channel_id_service_.get(),
+ &transport_security_state_, cert_transparency_verifier_.get(),
+ /*SocketPerformanceWatcherFactory*/ nullptr,
+ &crypto_client_stream_factory_, &random_generator_, clock_,
+ kDefaultMaxPacketSize, std::string(),
+ SupportedVersions(GetParam().version), enable_port_selection_,
+ always_require_handshake_confirmation_, disable_connection_pooling_,
+ load_server_info_timeout_srtt_multiplier_, enable_connection_racing_,
+ enable_non_blocking_io_, disable_disk_cache_, prefer_aes_,
+ max_number_of_lossy_connections_, packet_loss_threshold_,
+ max_disabled_reasons_, threshold_timeouts_with_open_streams_,
+ threshold_public_resets_post_handshake_, receive_buffer_size_,
+ delay_tcp_race_, /*max_server_configs_stored_in_properties*/ 0,
+ close_sessions_on_ip_change_, idle_connection_timeout_seconds_,
+ migrate_sessions_on_network_change_, QuicTagVector()));
+ factory_->set_require_confirmation(false);
+ EXPECT_FALSE(factory_->has_quic_server_info_factory());
+ factory_->set_quic_server_info_factory(new MockQuicServerInfoFactory());
+ EXPECT_TRUE(factory_->has_quic_server_info_factory());
+ }
+
+ void InitializeConnectionMigrationTest(
+ NetworkChangeNotifier::NetworkList connected_networks) {
+ scoped_mock_network_change_notifier_.reset(
+ new ScopedMockNetworkChangeNotifier());
+ MockNetworkChangeNotifier* mock_ncn =
+ scoped_mock_network_change_notifier_->mock_network_change_notifier();
+ mock_ncn->ForceNetworkHandlesSupported();
+ mock_ncn->SetConnectedNetworksList(connected_networks);
+ migrate_sessions_on_network_change_ = true;
+ Initialize();
}
bool HasActiveSession(const HostPortPair& host_port_pair) {
- return QuicStreamFactoryPeer::HasActiveSession(&factory_, host_port_pair,
- /*is_https_=*/false);
+ return QuicStreamFactoryPeer::HasActiveSession(factory_.get(),
+ host_port_pair);
}
scoped_ptr<QuicHttpStream> CreateFromSession(
const HostPortPair& host_port_pair) {
QuicChromiumClientSession* session =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, host_port_pair,
- /*is_https=*/false);
- return QuicStreamFactoryPeer::CreateFromSession(&factory_, session);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair);
+ return QuicStreamFactoryPeer::CreateFromSession(factory_.get(), session);
}
int GetSourcePortForNewSession(const HostPortPair& destination) {
return GetSourcePortForNewSessionInner(destination, false);
}
- int GetSourcePortForNewSessionAndGoAway(
- const HostPortPair& destination) {
+ int GetSourcePortForNewSessionAndGoAway(const HostPortPair& destination) {
return GetSourcePortForNewSessionInner(destination, true);
}
@@ -329,18 +283,15 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> {
bool goaway_received) {
// Should only be called if there is no active session for this destination.
EXPECT_FALSE(HasActiveSession(destination));
- size_t socket_count = socket_factory_.udp_client_sockets().size();
+ size_t socket_count = socket_factory_.udp_client_socket_ports().size();
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
- socket_data.StopAfter(1);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(destination, is_https_, privacy_mode_,
+ request.Request(destination, privacy_mode_,
/*cert_verify_flags=*/0, destination.host(),
"GET", net_log_, callback_.callback()));
@@ -350,28 +301,23 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> {
stream.reset();
QuicChromiumClientSession* session =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, destination,
- is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), destination);
- if (socket_count + 1 != socket_factory_.udp_client_sockets().size()) {
- EXPECT_TRUE(false);
+ if (socket_count + 1 != socket_factory_.udp_client_socket_ports().size()) {
+ ADD_FAILURE();
return 0;
}
- IPEndPoint endpoint;
- socket_factory_.
- udp_client_sockets()[socket_count]->GetLocalAddress(&endpoint);
- int port = endpoint.port();
if (goaway_received) {
QuicGoAwayFrame goaway(QUIC_NO_ERROR, 1, "");
session->connection()->OnGoAwayFrame(goaway);
}
- factory_.OnSessionClosed(session);
+ factory_->OnSessionClosed(session);
EXPECT_FALSE(HasActiveSession(destination));
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
- return port;
+ return socket_factory_.udp_client_socket_ports()[socket_count];
}
scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
@@ -387,10 +333,9 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> {
}
static ProofVerifyDetailsChromium DefaultProofVerifyDetails() {
- // Load a certificate that is valid for www.example.org, mail.example.org,
- // and mail.example.com.
+ // Load a certificate that is valid for *.example.org
scoped_refptr<X509Certificate> test_cert(
- ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
EXPECT_TRUE(test_cert.get());
ProofVerifyDetailsChromium verify_details;
verify_details.cert_verify_result.verified_cert = test_cert;
@@ -398,23 +343,78 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> {
return verify_details;
}
- MockQuicServerInfoFactory quic_server_info_factory_;
+ void NotifyIPAddressChanged() {
+ NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
+ // Spin the message loop so the notification is delivered.
+ base::MessageLoop::current()->RunUntilIdle();
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructGetRequestPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin) {
+ SpdyHeaderBlock headers = maker_.GetRequestHeaders("GET", "https", "/");
+ SpdyPriority priority =
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
+ size_t spdy_headers_frame_len;
+ return maker_.MakeRequestHeadersPacket(
+ packet_number, stream_id, should_include_version, fin, priority,
+ headers, &spdy_headers_frame_len);
+ }
+
+ scoped_ptr<QuicEncryptedPacket> ConstructOkResponsePacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin) {
+ SpdyHeaderBlock headers = maker_.GetResponseHeaders("200 OK");
+ size_t spdy_headers_frame_len;
+ return maker_.MakeResponseHeadersPacket(packet_number, stream_id,
+ should_include_version, fin,
+ headers, &spdy_headers_frame_len);
+ }
+
MockHostResolver host_resolver_;
- DeterministicMockClientSocketFactory socket_factory_;
+ MockClientSocketFactory socket_factory_;
MockCryptoClientStreamFactory crypto_client_stream_factory_;
+ ProofVerifyDetailsChromium verify_details_;
MockRandom random_generator_;
MockClock* clock_; // Owned by factory_.
scoped_refptr<TestTaskRunner> runner_;
QuicTestPacketMaker maker_;
+ HttpServerPropertiesImpl http_server_properties_;
scoped_ptr<CertVerifier> cert_verifier_;
scoped_ptr<ChannelIDService> channel_id_service_;
TransportSecurityState transport_security_state_;
- QuicStreamFactory factory_;
+ scoped_ptr<CTVerifier> cert_transparency_verifier_;
+ scoped_ptr<ScopedMockNetworkChangeNotifier>
+ scoped_mock_network_change_notifier_;
+ scoped_ptr<QuicStreamFactory> factory_;
HostPortPair host_port_pair_;
- bool is_https_;
PrivacyMode privacy_mode_;
BoundNetLog net_log_;
TestCompletionCallback callback_;
+
+ // Variables to configure QuicStreamFactory.
+ bool enable_port_selection_;
+ bool always_require_handshake_confirmation_;
+ bool disable_connection_pooling_;
+ double load_server_info_timeout_srtt_multiplier_;
+ bool enable_connection_racing_;
+ bool enable_non_blocking_io_;
+ bool disable_disk_cache_;
+ bool prefer_aes_;
+ int max_number_of_lossy_connections_;
+ double packet_loss_threshold_;
+ int max_disabled_reasons_;
+ int threshold_timeouts_with_open_streams_;
+ int threshold_public_resets_post_handshake_;
+ int receive_buffer_size_;
+ bool delay_tcp_race_;
+ bool close_sessions_on_ip_change_;
+ int idle_connection_timeout_seconds_;
+ bool migrate_sessions_on_network_change_;
};
INSTANTIATE_TEST_CASE_P(Version,
@@ -422,16 +422,17 @@ INSTANTIATE_TEST_CASE_P(Version,
::testing::ValuesIn(GetTestParams()));
TEST_P(QuicStreamFactoryTest, Create) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -445,25 +446,26 @@ TEST_P(QuicStreamFactoryTest, Create) {
// TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
// in streams on different sessions.
- QuicStreamRequest request2(&factory_);
+ QuicStreamRequest request2(factory_.get());
EXPECT_EQ(OK,
- request2.Request(host_port_pair_, is_https_, privacy_mode_,
+ request2.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
stream = request2.ReleaseStream(); // Will reset stream 5.
- stream.reset(); // Will reset stream 7.
+ stream.reset(); // Will reset stream 7.
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -471,8 +473,8 @@ TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
"192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -483,12 +485,13 @@ TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
}
TEST_P(QuicStreamFactoryTest, CreateZeroRttPost) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -496,10 +499,10 @@ TEST_P(QuicStreamFactoryTest, CreateZeroRttPost) {
host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
"192.168.0.1", "");
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
// Posts require handshake confirmation, so this will return asynchronously.
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"POST", net_log_, callback_.callback()));
@@ -515,12 +518,13 @@ TEST_P(QuicStreamFactoryTest, CreateZeroRttPost) {
}
TEST_P(QuicStreamFactoryTest, NoZeroRttForDifferentHost) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0),
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -528,10 +532,10 @@ TEST_P(QuicStreamFactoryTest, NoZeroRttForDifferentHost) {
host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
"192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- int rv = request.Request(
- host_port_pair_, is_https_, privacy_mode_, /*cert_verify_flags=*/0,
- "different.host.example.com", "GET", net_log_, callback_.callback());
+ QuicStreamRequest request(factory_.get());
+ int rv =
+ request.Request(host_port_pair_, privacy_mode_, /*cert_verify_flags=*/0,
+ kServer2HostName, "GET", net_log_, callback_.callback());
// If server and origin have different hostnames, then handshake confirmation
// should be required, so Request will return asynchronously.
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -546,59 +550,18 @@ TEST_P(QuicStreamFactoryTest, NoZeroRttForDifferentHost) {
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
-TEST_P(QuicStreamFactoryTest, CreateHttpVsHttps) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
- socket_factory_.AddSocketDataProvider(&socket_data1);
- socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data1.StopAfter(1);
- socket_data2.StopAfter(1);
-
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
- /*cert_verify_flags=*/0, host_port_pair_.host(),
- "GET", net_log_, callback_.callback()));
-
- EXPECT_EQ(OK, callback_.WaitForResult());
- scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
- EXPECT_TRUE(stream.get());
-
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(ERR_IO_PENDING,
- request2.Request(host_port_pair_, !is_https_, privacy_mode_,
- /*cert_verify_flags=*/0, host_port_pair_.host(),
- "GET", net_log_, callback_.callback()));
- EXPECT_EQ(OK, callback_.WaitForResult());
- stream = request2.ReleaseStream();
- EXPECT_TRUE(stream.get());
- stream.reset();
-
- EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, !is_https_));
-
- EXPECT_TRUE(socket_data1.AllReadDataConsumed());
- EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
- EXPECT_TRUE(socket_data2.AllReadDataConsumed());
- EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
-}
-
TEST_P(QuicStreamFactoryTest, GoAway) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -606,97 +569,93 @@ TEST_P(QuicStreamFactoryTest, GoAway) {
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
session->OnGoAway(QuicGoAwayFrame());
- EXPECT_FALSE(QuicStreamFactoryPeer::HasActiveSession(
- &factory_, host_port_pair_, is_https_));
+ EXPECT_FALSE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, Pooling) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- HostPortPair server2("mail.google.com", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
host_resolver_.set_synchronous_mode(true);
- host_resolver_.rules()->AddIPLiteralRule(
- kDefaultServerHostName, "192.168.0.1", "");
- host_resolver_.rules()->AddIPLiteralRule(
- "mail.google.com", "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
EXPECT_EQ(
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_));
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_),
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, NoPoolingIfDisabled) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ disable_connection_pooling_ = true;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data1);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data1.StopAfter(1);
- socket_data2.StopAfter(1);
- HostPortPair server2("mail.google.com", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
host_resolver_.set_synchronous_mode(true);
- host_resolver_.rules()->AddIPLiteralRule(
- kDefaultServerHostName, "192.168.0.1", "");
- host_resolver_.rules()->AddIPLiteralRule(
- "mail.google.com", "192.168.0.1", "");
-
- // Disable connection pooling.
- QuicStreamFactoryPeer::DisableConnectionPooling(&factory_);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
EXPECT_NE(
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_));
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_),
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data1.AllReadDataConsumed());
EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
@@ -705,55 +664,54 @@ TEST_P(QuicStreamFactoryTest, NoPoolingIfDisabled) {
}
TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data1);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data1.StopAfter(1);
- socket_data2.StopAfter(1);
- HostPortPair server2("mail.google.com", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
host_resolver_.set_synchronous_mode(true);
- host_resolver_.rules()->AddIPLiteralRule(
- kDefaultServerHostName, "192.168.0.1", "");
- host_resolver_.rules()->AddIPLiteralRule(
- "mail.google.com", "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
- factory_.OnSessionGoingAway(QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_));
- EXPECT_FALSE(QuicStreamFactoryPeer::HasActiveSession(
- &factory_, host_port_pair_, is_https_));
- EXPECT_FALSE(QuicStreamFactoryPeer::HasActiveSession(
- &factory_, server2, is_https_));
+ factory_->OnSessionGoingAway(
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_));
+ EXPECT_FALSE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
+ EXPECT_FALSE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server2));
TestCompletionCallback callback3;
- QuicStreamRequest request3(&factory_);
- EXPECT_EQ(OK, request3.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback3.callback()));
scoped_ptr<QuicHttpStream> stream3 = request3.ReleaseStream();
EXPECT_TRUE(stream3.get());
- EXPECT_TRUE(QuicStreamFactoryPeer::HasActiveSession(
- &factory_, server2, is_https_));
+ EXPECT_TRUE(QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data1.AllReadDataConsumed());
EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
@@ -762,15 +720,14 @@ TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
}
TEST_P(QuicStreamFactoryTest, HttpsPooling) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- HostPortPair server1("www.example.org", 443);
- HostPortPair server2("mail.example.org", 443);
+ HostPortPair server1(kDefaultServerHostName, 443);
+ HostPortPair server2(kServer2HostName, 443);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
@@ -779,75 +736,66 @@ TEST_P(QuicStreamFactoryTest, HttpsPooling) {
host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- is_https_ = true;
- EXPECT_EQ(OK, request.Request(server1, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(server1, privacy_mode_,
/*cert_verify_flags=*/0, server1.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
- EXPECT_EQ(QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server1, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server2, is_https_));
+ EXPECT_EQ(QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server1),
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, NoHttpsPoolingIfDisabled) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ disable_connection_pooling_ = true;
+ Initialize();
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data1);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data1.StopAfter(1);
- socket_data2.StopAfter(1);
- HostPortPair server1("www.example.org", 443);
- HostPortPair server2("mail.example.org", 443);
+ HostPortPair server1(kDefaultServerHostName, 443);
+ HostPortPair server2(kServer2HostName, 443);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
host_resolver_.set_synchronous_mode(true);
host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- // Disable connection pooling.
- QuicStreamFactoryPeer::DisableConnectionPooling(&factory_);
-
- QuicStreamRequest request(&factory_);
- is_https_ = true;
- EXPECT_EQ(OK, request.Request(server1, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(server1, privacy_mode_,
/*cert_verify_flags=*/0, server1.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
- EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server1, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server2, is_https_));
+ EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server1),
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data1.AllReadDataConsumed());
EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
@@ -859,18 +807,15 @@ class QuicAlternativeServiceCertificateValidationPooling
: public QuicStreamFactoryTest {
public:
void Run(bool valid) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data1);
- socket_data1.StopAfter(1);
- HostPortPair server1("www.example.org", 443);
- HostPortPair server2("mail.example.org", 443);
+ HostPortPair server1(kDefaultServerHostName, 443);
+ HostPortPair server2(kServer2HostName, 443);
- std::string origin_host(valid ? "mail.example.org" : "invalid.example.org");
- HostPortPair alternative("www.example.org", 443);
+ std::string origin_host(valid ? kServer2HostName : "invalid.example.com");
+ HostPortPair alternative(kDefaultServerHostName, 443);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bool common_name_fallback_used;
@@ -887,16 +832,15 @@ class QuicAlternativeServiceCertificateValidationPooling
"");
// Open first stream to alternative.
- QuicStreamRequest request1(&factory_);
- is_https_ = true;
- EXPECT_EQ(OK, request1.Request(alternative, is_https_, privacy_mode_,
+ QuicStreamRequest request1(factory_.get());
+ EXPECT_EQ(OK, request1.Request(alternative, privacy_mode_,
/*cert_verify_flags=*/0, alternative.host(),
"GET", net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream1 = request1.ReleaseStream();
EXPECT_TRUE(stream1.get());
- QuicStreamRequest request2(&factory_);
- int rv = request2.Request(alternative, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ int rv = request2.Request(alternative, privacy_mode_,
/*cert_verify_flags=*/0, origin_host, "GET",
net_log_, callback_.callback());
if (valid) {
@@ -921,26 +865,26 @@ INSTANTIATE_TEST_CASE_P(Version,
::testing::ValuesIn(GetTestParams()));
TEST_P(QuicAlternativeServiceCertificateValidationPooling, Valid) {
+ Initialize();
Run(true);
}
TEST_P(QuicAlternativeServiceCertificateValidationPooling, Invalid) {
+ Initialize();
Run(false);
}
TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- HostPortPair server1("www.example.org", 443);
- HostPortPair server2("mail.example.org", 443);
- uint8 primary_pin = 1;
- uint8 backup_pin = 2;
- test::AddPin(&transport_security_state_, "mail.example.org", primary_pin,
+ HostPortPair server1(kDefaultServerHostName, 443);
+ HostPortPair server2(kServer2HostName, 443);
+ uint8_t primary_pin = 1;
+ uint8_t backup_pin = 2;
+ test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
backup_pin);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
@@ -952,81 +896,72 @@ TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- is_https_ = true;
- EXPECT_EQ(OK, request.Request(server1, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(server1, privacy_mode_,
/*cert_verify_flags=*/0, server1.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
- EXPECT_EQ(QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server1, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server2, is_https_));
+ EXPECT_EQ(QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server1),
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithMatchingPinsIfDisabled) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ disable_connection_pooling_ = true;
+ Initialize();
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data1);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data1.StopAfter(1);
- socket_data2.StopAfter(1);
-
- HostPortPair server1("www.example.org", 443);
- HostPortPair server2("mail.example.org", 443);
- uint8 primary_pin = 1;
- uint8 backup_pin = 2;
- test::AddPin(&transport_security_state_, "mail.example.org", primary_pin,
+
+ HostPortPair server1(kDefaultServerHostName, 443);
+ HostPortPair server2(kServer2HostName, 443);
+ uint8_t primary_pin = 1;
+ uint8_t backup_pin = 2;
+ test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
backup_pin);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
verify_details.cert_verify_result.public_key_hashes.push_back(
test::GetTestHashValue(primary_pin));
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
host_resolver_.set_synchronous_mode(true);
host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- // Disable connection pooling.
- QuicStreamFactoryPeer::DisableConnectionPooling(&factory_);
-
- QuicStreamRequest request(&factory_);
- is_https_ = true;
- EXPECT_EQ(OK, request.Request(server1, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(server1, privacy_mode_,
/*cert_verify_flags=*/0, server1.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
- EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server1, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server2, is_https_));
+ EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server1),
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data1.AllReadDataConsumed());
EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
@@ -1035,22 +970,19 @@ TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithMatchingPinsIfDisabled) {
}
TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data1(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data1);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data1.StopAfter(1);
- socket_data2.StopAfter(1);
-
- HostPortPair server1("www.example.org", 443);
- HostPortPair server2("mail.example.org", 443);
- uint8 primary_pin = 1;
- uint8 backup_pin = 2;
- uint8 bad_pin = 3;
- test::AddPin(&transport_security_state_, "mail.example.org", primary_pin,
+
+ HostPortPair server1(kDefaultServerHostName, 443);
+ HostPortPair server2(kServer2HostName, 443);
+ uint8_t primary_pin = 1;
+ uint8_t backup_pin = 2;
+ uint8_t bad_pin = 3;
+ test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
backup_pin);
ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
@@ -1067,26 +999,23 @@ TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- is_https_ = true;
- EXPECT_EQ(OK, request.Request(server1, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(server1, privacy_mode_,
/*cert_verify_flags=*/0, server1.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
TestCompletionCallback callback;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback_.callback()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
- EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server1, is_https_),
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, server2, is_https_));
+ EXPECT_NE(QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server1),
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2));
EXPECT_TRUE(socket_data1.AllReadDataConsumed());
EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
@@ -1095,19 +1024,20 @@ TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
}
TEST_P(QuicStreamFactoryTest, Goaway) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
- socket_data.StopAfter(1);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
- socket_data2.StopAfter(1);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1117,32 +1047,32 @@ TEST_P(QuicStreamFactoryTest, Goaway) {
// Mark the session as going away. Ensure that while it is still alive
// that it is no longer active.
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
- factory_.OnSessionGoingAway(session);
- EXPECT_EQ(true, QuicStreamFactoryPeer::IsLiveSession(&factory_, session));
- EXPECT_FALSE(QuicStreamFactoryPeer::HasActiveSession(
- &factory_, host_port_pair_, is_https_));
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ factory_->OnSessionGoingAway(session);
+ EXPECT_EQ(true,
+ QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
EXPECT_FALSE(HasActiveSession(host_port_pair_));
// Create a new request for the same destination and verify that a
// new session is created.
- QuicStreamRequest request2(&factory_);
+ QuicStreamRequest request2(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request2.Request(host_port_pair_, is_https_, privacy_mode_,
+ request2.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
EXPECT_EQ(OK, callback_.WaitForResult());
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
- EXPECT_TRUE(QuicStreamFactoryPeer::HasActiveSession(&factory_,
- host_port_pair_,
- is_https_));
- EXPECT_NE(session,
- QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_));
- EXPECT_EQ(true, QuicStreamFactoryPeer::IsLiveSession(&factory_, session));
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
+ EXPECT_NE(session, QuicStreamFactoryPeer::GetActiveSession(factory_.get(),
+ host_port_pair_));
+ EXPECT_EQ(true,
+ QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
stream2.reset();
stream.reset();
@@ -1154,27 +1084,32 @@ TEST_P(QuicStreamFactoryTest, Goaway) {
}
TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
QuicStreamId stream_id = kClientDataStreamId1;
- scoped_ptr<QuicEncryptedPacket> rst(
+ scoped_ptr<QuicEncryptedPacket> client_rst(
maker_.MakeRstPacket(1, true, stream_id, QUIC_STREAM_CANCELLED));
MockWrite writes[] = {
- MockWrite(ASYNC, rst->data(), rst->length(), 1),
+ MockWrite(ASYNC, client_rst->data(), client_rst->length(), 0),
};
- DeterministicSocketData socket_data(reads, arraysize(reads),
- writes, arraysize(writes));
+ scoped_ptr<QuicEncryptedPacket> server_rst(
+ maker_.MakeRstPacket(1, false, stream_id, QUIC_STREAM_CANCELLED));
+ MockRead reads[] = {
+ MockRead(ASYNC, server_rst->data(), server_rst->length(), 1),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2)};
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
HttpRequestInfo request_info;
std::vector<QuicHttpStream*> streams;
// The MockCryptoClientStream sets max_open_streams to be
// kDefaultMaxStreamsPerConnection / 2.
for (size_t i = 0; i < kDefaultMaxStreamsPerConnection / 2; i++) {
- QuicStreamRequest request(&factory_);
- int rv = request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ int rv = request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback());
if (i == 0) {
@@ -1185,41 +1120,50 @@ TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
}
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream);
- EXPECT_EQ(OK, stream->InitializeStream(
- &request_info, DEFAULT_PRIORITY, net_log_, CompletionCallback()));
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
streams.push_back(stream.release());
}
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, CompletionCallback()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream);
- EXPECT_EQ(ERR_IO_PENDING, stream->InitializeStream(
- &request_info, DEFAULT_PRIORITY, net_log_, callback_.callback()));
+ EXPECT_EQ(ERR_IO_PENDING,
+ stream->InitializeStream(&request_info, DEFAULT_PRIORITY, net_log_,
+ callback_.callback()));
// Close the first stream.
streams.front()->Close(false);
-
- ASSERT_TRUE(callback_.have_result());
-
+ // Trigger exchange of RSTs that in turn allow progress for the last
+ // stream.
EXPECT_EQ(OK, callback_.WaitForResult());
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+
+ // Force close of the connection to suppress the generation of RST
+ // packets when streams are torn down, which wouldn't be relevant to
+ // this test anyway.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ session->connection()->CloseConnection(QUIC_PUBLIC_RESET, true);
+
STLDeleteElements(&streams);
}
TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
- DeterministicSocketData socket_data(nullptr, 0, nullptr, 0);
+ Initialize();
+ SequencedSocketData socket_data(nullptr, 0, nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
host_resolver_.rules()->AddSimulatedFailure(kDefaultServerHostName);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1230,15 +1174,15 @@ TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
}
TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
+ Initialize();
MockConnect connect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
- DeterministicSocketData socket_data(nullptr, 0, nullptr, 0);
+ SequencedSocketData socket_data(nullptr, 0, nullptr, 0);
socket_data.set_connect_data(connect);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1249,22 +1193,19 @@ TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
}
TEST_P(QuicStreamFactoryTest, CancelCreate) {
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
{
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
}
- socket_data.StopAfter(1);
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
scoped_ptr<QuicHttpStream> stream(CreateFromSession(host_port_pair_));
EXPECT_TRUE(stream.get());
@@ -1275,11 +1216,17 @@ TEST_P(QuicStreamFactoryTest, CancelCreate) {
}
TEST_P(QuicStreamFactoryTest, CreateConsistentEphemeralPort) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
// Sequentially connect to the default host, then another host, and then the
// default host. Verify that the default host gets a consistent ephemeral
// port, that is different from the other host's connection.
- std::string other_server_name = "other.google.com";
+ std::string other_server_name = kServer2HostName;
EXPECT_NE(kDefaultServerHostName, other_server_name);
HostPortPair host_port_pair2(other_server_name, kDefaultServerPort);
@@ -1289,9 +1236,14 @@ TEST_P(QuicStreamFactoryTest, CreateConsistentEphemeralPort) {
}
TEST_P(QuicStreamFactoryTest, GoAwayDisablesConsistentEphemeralPort) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
// Get a session to the host using the port suggester.
- int original_port =
- GetSourcePortForNewSessionAndGoAway(host_port_pair_);
+ int original_port = GetSourcePortForNewSessionAndGoAway(host_port_pair_);
// Verify that the port is different after the goaway.
EXPECT_NE(original_port, GetSourcePortForNewSession(host_port_pair_));
// Since the previous session did not goaway we should see the original port.
@@ -1299,49 +1251,47 @@ TEST_P(QuicStreamFactoryTest, GoAwayDisablesConsistentEphemeralPort) {
}
TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
- MockRead reads[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
scoped_ptr<QuicEncryptedPacket> rst(ConstructRstPacket());
std::vector<MockWrite> writes;
writes.push_back(MockWrite(ASYNC, rst->data(), rst->length(), 1));
- DeterministicSocketData socket_data(reads, arraysize(reads),
- writes.empty() ? nullptr : &writes[0],
- writes.size());
+ SequencedSocketData socket_data(reads, arraysize(reads),
+ writes.empty() ? nullptr : &writes[0],
+ writes.size());
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- MockRead reads2[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
- DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
EXPECT_EQ(OK, callback_.WaitForResult());
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info,
- DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Close the session and verify that stream saw the error.
- factory_.CloseAllSessions(ERR_INTERNET_DISCONNECTED);
+ factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED, QUIC_INTERNAL_ERROR);
EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
stream->ReadResponseHeaders(callback_.callback()));
// Now attempting to request a stream to the same origin should create
// a new session.
- QuicStreamRequest request2(&factory_);
+ QuicStreamRequest request2(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request2.Request(host_port_pair_, is_https_, privacy_mode_,
+ request2.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1356,50 +1306,49 @@ TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
}
TEST_P(QuicStreamFactoryTest, OnIPAddressChanged) {
- MockRead reads[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
+ close_sessions_on_ip_change_ = true;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
scoped_ptr<QuicEncryptedPacket> rst(ConstructRstPacket());
std::vector<MockWrite> writes;
writes.push_back(MockWrite(ASYNC, rst->data(), rst->length(), 1));
- DeterministicSocketData socket_data(reads, arraysize(reads),
- writes.empty() ? nullptr : &writes[0],
- writes.size());
+ SequencedSocketData socket_data(reads, arraysize(reads),
+ writes.empty() ? nullptr : &writes[0],
+ writes.size());
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- MockRead reads2[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
- DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
EXPECT_EQ(OK, callback_.WaitForResult());
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info,
- DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Change the IP address and verify that stream saw the error.
- factory_.OnIPAddressChanged();
+ NotifyIPAddressChanged();
EXPECT_EQ(ERR_NETWORK_CHANGED,
stream->ReadResponseHeaders(callback_.callback()));
- EXPECT_TRUE(factory_.require_confirmation());
+ EXPECT_TRUE(factory_->require_confirmation());
// Now attempting to request a stream to the same origin should create
// a new session.
- QuicStreamRequest request2(&factory_);
+ QuicStreamRequest request2(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request2.Request(host_port_pair_, is_https_, privacy_mode_,
+ request2.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1413,29 +1362,521 @@ TEST_P(QuicStreamFactoryTest, OnIPAddressChanged) {
EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
}
-TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
- MockRead reads[] = {
- MockRead(ASYNC, 0, 0) // EOF
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeSoonToDisconnect) {
+ InitializeConnectionMigrationTest(
+ {kDefaultNetworkForTests, kNewNetworkForTests});
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> request_packet(
+ ConstructGetRequestPacket(1, kClientDataStreamId1, true, true));
+ MockWrite writes[] = {MockWrite(SYNCHRONOUS, request_packet->data(),
+ request_packet->length(), 1)};
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("https://www.example.org/");
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Send GET request on stream.
+ HttpResponseInfo response;
+ HttpRequestHeaders request_headers;
+ EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
+ callback_.callback()));
+
+ // Set up second socket data provider that is used after migration.
+ // The response to the earlier request is read on this new socket.
+ scoped_ptr<QuicEncryptedPacket> ping(
+ maker_.MakePingPacket(2, /*include_version=*/true));
+ MockWrite writes1[] = {
+ MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 0)};
+ scoped_ptr<QuicEncryptedPacket> response_headers_packet(
+ ConstructOkResponsePacket(1, kClientDataStreamId1, false, false));
+ MockRead reads1[] = {MockRead(ASYNC, response_headers_packet->data(),
+ response_headers_packet->length(), 1),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2)};
+ SequencedSocketData socket_data1(reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
+ socket_factory_.AddSocketDataProvider(&socket_data1);
+
+ // Trigger connection migration. This should cause a PING frame
+ // to be emitted.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkSoonToDisconnect(kDefaultNetworkForTests);
+
+ // The session should now be marked as going away. Ensure that
+ // while it is still alive, it is no longer active.
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+
+ // Verify that response headers on the migrated socket were delivered to the
+ // stream.
+ EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
+ EXPECT_EQ(200, response.headers->response_code());
+
+ // Create a new request for the same destination and verify that a
+ // new session is created.
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ socket_factory_.AddSocketDataProvider(&socket_data2);
+
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request2.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
+ EXPECT_TRUE(stream2.get());
+
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
+ EXPECT_NE(session, QuicStreamFactoryPeer::GetActiveSession(factory_.get(),
+ host_port_pair_));
+
+ // On a DISCONNECTED notification, nothing happens to the migrated session.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data1.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeDisconnected) {
+ InitializeConnectionMigrationTest(
+ {kDefaultNetworkForTests, kNewNetworkForTests});
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> request_packet(
+ ConstructGetRequestPacket(1, kClientDataStreamId1, true, true));
+ MockWrite writes[] = {MockWrite(SYNCHRONOUS, request_packet->data(),
+ request_packet->length(), 1)};
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("https://www.example.org/");
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Send GET request on stream.
+ HttpResponseInfo response_info;
+ HttpRequestHeaders request_headers;
+ EXPECT_EQ(OK, stream->SendRequest(request_headers, &response_info,
+ callback_.callback()));
+
+ // Set up second socket data provider that is used after migration.
+ scoped_ptr<QuicEncryptedPacket> ping(
+ maker_.MakePingPacket(2, /*include_version=*/true));
+ scoped_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
+ 3, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED));
+ MockWrite writes1[] = {
+ MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 0)};
+ scoped_ptr<QuicEncryptedPacket> response_packet(
+ ConstructOkResponsePacket(1, kClientDataStreamId1, false, false));
+ MockRead reads1[] = {
+ MockRead(ASYNC, response_packet->data(), response_packet->length(), 1),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2)};
+ SequencedSocketData socket_data1(reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
+ socket_factory_.AddSocketDataProvider(&socket_data1);
+
+ // Trigger connection migration. This should cause a PING frame
+ // to be emitted.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
+
+ // The session should now be marked as going away. Ensure that
+ // while it is still alive, it is no longer active.
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+
+ // Create a new request for the same destination and verify that a
+ // new session is created.
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ socket_factory_.AddSocketDataProvider(&socket_data2);
+
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request2.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
+ EXPECT_TRUE(stream2.get());
+
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
+ EXPECT_NE(session, QuicStreamFactoryPeer::GetActiveSession(factory_.get(),
+ host_port_pair_));
+ EXPECT_EQ(true,
+ QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data1.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeSoonToDisconnectNoNetworks) {
+ NetworkChangeNotifier::NetworkList no_networks(0);
+ InitializeConnectionMigrationTest(no_networks);
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
+ 1, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED));
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, client_rst->data(), client_rst->length(), 1),
+ };
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+
+ // Trigger connection migration. Since there are no networks
+ // to migrate to, this should cause the session to continue on the same
+ // socket, but be marked as going away.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkSoonToDisconnect(kDefaultNetworkForTests);
+
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+
+ stream.reset();
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeDisconnectedNoNetworks) {
+ NetworkChangeNotifier::NetworkList no_networks(0);
+ InitializeConnectionMigrationTest(no_networks);
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
+ 1, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT));
+ MockWrite writes[] = {
+ MockWrite(ASYNC, client_rst->data(), client_rst->length(), 1),
};
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Trigger connection migration. Since there are no networks
+ // to migrate to, this should cause a RST_STREAM frame to be emitted
+ // and the session to be closed.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeSoonToDisconnectNoNewNetwork) {
+ InitializeConnectionMigrationTest({kDefaultNetworkForTests});
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
+ 1, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED));
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, client_rst->data(), client_rst->length(), 1),
+ };
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Trigger connection migration. Since there are no networks
+ // to migrate to, this should cause session to be continue but be marked as
+ // going away.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkSoonToDisconnect(kDefaultNetworkForTests);
+
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+
+ stream.reset();
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeDisconnectedNoNewNetwork) {
+ InitializeConnectionMigrationTest({kDefaultNetworkForTests});
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ scoped_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
+ 1, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT));
+ MockWrite writes[] = {
+ MockWrite(ASYNC, client_rst->data(), client_rst->length(), 1),
+ };
+ SequencedSocketData socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Trigger connection migration. Since there are no networks
+ // to migrate to, this should cause a RST_STREAM frame to be emitted
+ // with QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeSoonToDisconnectNoOpenStreams) {
+ InitializeConnectionMigrationTest(
+ {kDefaultNetworkForTests, kNewNetworkForTests});
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0u);
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Trigger connection migration. Since there are no active streams,
+ // the session will be closed.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnNetworkChangeDisconnectedNoOpenStreams) {
+ InitializeConnectionMigrationTest(
+ {kDefaultNetworkForTests, kNewNetworkForTests});
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0u);
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, host_port_pair_.host(),
+ "GET", net_log_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
+ EXPECT_TRUE(stream.get());
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Trigger connection migration. Since there are no active streams,
+ // the session will be closed.
+ scoped_mock_network_change_notifier_->mock_network_change_notifier()
+ ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
scoped_ptr<QuicEncryptedPacket> rst(ConstructRstPacket());
std::vector<MockWrite> writes;
writes.push_back(MockWrite(ASYNC, rst->data(), rst->length(), 1));
- DeterministicSocketData socket_data(reads, arraysize(reads),
- writes.empty() ? nullptr : &writes[0],
- writes.size());
+ SequencedSocketData socket_data(reads, arraysize(reads),
+ writes.empty() ? nullptr : &writes[0],
+ writes.size());
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- MockRead reads2[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
- DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1445,17 +1886,17 @@ TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
- factory_.OnSSLConfigChanged();
+ factory_->OnSSLConfigChanged();
EXPECT_EQ(ERR_CERT_DATABASE_CHANGED,
stream->ReadResponseHeaders(callback_.callback()));
- EXPECT_FALSE(factory_.require_confirmation());
+ EXPECT_FALSE(factory_->require_confirmation());
// Now attempting to request a stream to the same origin should create
// a new session.
- QuicStreamRequest request2(&factory_);
+ QuicStreamRequest request2(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request2.Request(host_port_pair_, is_https_, privacy_mode_,
+ request2.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1470,50 +1911,48 @@ TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
}
TEST_P(QuicStreamFactoryTest, OnCertAdded) {
- MockRead reads[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
scoped_ptr<QuicEncryptedPacket> rst(ConstructRstPacket());
std::vector<MockWrite> writes;
writes.push_back(MockWrite(ASYNC, rst->data(), rst->length(), 1));
- DeterministicSocketData socket_data(reads, arraysize(reads),
- writes.empty() ? nullptr : &writes[0],
- writes.size());
+ SequencedSocketData socket_data(reads, arraysize(reads),
+ writes.empty() ? nullptr : &writes[0],
+ writes.size());
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- MockRead reads2[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
- DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
EXPECT_EQ(OK, callback_.WaitForResult());
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info,
- DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Add a cert and verify that stream saw the event.
- factory_.OnCertAdded(nullptr);
+ factory_->OnCertAdded(nullptr);
EXPECT_EQ(ERR_CERT_DATABASE_CHANGED,
stream->ReadResponseHeaders(callback_.callback()));
- EXPECT_FALSE(factory_.require_confirmation());
+ EXPECT_FALSE(factory_->require_confirmation());
// Now attempting to request a stream to the same origin should create
// a new session.
- QuicStreamRequest request2(&factory_);
+ QuicStreamRequest request2(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request2.Request(host_port_pair_, is_https_, privacy_mode_,
+ request2.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1528,50 +1967,48 @@ TEST_P(QuicStreamFactoryTest, OnCertAdded) {
}
TEST_P(QuicStreamFactoryTest, OnCACertChanged) {
- MockRead reads[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
scoped_ptr<QuicEncryptedPacket> rst(ConstructRstPacket());
std::vector<MockWrite> writes;
writes.push_back(MockWrite(ASYNC, rst->data(), rst->length(), 1));
- DeterministicSocketData socket_data(reads, arraysize(reads),
- writes.empty() ? nullptr : &writes[0],
- writes.size());
+ SequencedSocketData socket_data(reads, arraysize(reads),
+ writes.empty() ? nullptr : &writes[0],
+ writes.size());
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- MockRead reads2[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
- DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
EXPECT_EQ(OK, callback_.WaitForResult());
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info,
- DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Change the CA cert and verify that stream saw the event.
- factory_.OnCACertChanged(nullptr);
+ factory_->OnCACertChanged(nullptr);
EXPECT_EQ(ERR_CERT_DATABASE_CHANGED,
stream->ReadResponseHeaders(callback_.callback()));
- EXPECT_FALSE(factory_.require_confirmation());
+ EXPECT_FALSE(factory_->require_confirmation());
// Now attempting to request a stream to the same origin should create
// a new session.
- QuicStreamRequest request2(&factory_);
+ QuicStreamRequest request2(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request2.Request(host_port_pair_, is_https_, privacy_mode_,
+ request2.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1586,6 +2023,8 @@ TEST_P(QuicStreamFactoryTest, OnCACertChanged) {
}
TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
+ Initialize();
+
vector<string> cannoncial_suffixes;
cannoncial_suffixes.push_back(string(".c.youtube.com"));
cannoncial_suffixes.push_back(string(".googlevideo.com"));
@@ -1598,8 +2037,8 @@ TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
HostPortPair host_port_pair1(r1_host_name, 80);
QuicCryptoClientConfig* crypto_config =
- QuicStreamFactoryPeer::GetCryptoConfig(&factory_);
- QuicServerId server_id1(host_port_pair1, is_https_, privacy_mode_);
+ QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
+ QuicServerId server_id1(host_port_pair1, privacy_mode_);
QuicCryptoClientConfig::CachedState* cached1 =
crypto_config->LookupOrCreate(server_id1);
EXPECT_FALSE(cached1->proof_valid());
@@ -1611,7 +2050,7 @@ TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
cached1->SetProofValid();
HostPortPair host_port_pair2(r2_host_name, 80);
- QuicServerId server_id2(host_port_pair2, is_https_, privacy_mode_);
+ QuicServerId server_id2(host_port_pair2, privacy_mode_);
QuicCryptoClientConfig::CachedState* cached2 =
crypto_config->LookupOrCreate(server_id2);
EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
@@ -1620,6 +2059,7 @@ TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
}
TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
+ Initialize();
vector<string> cannoncial_suffixes;
cannoncial_suffixes.push_back(string(".c.youtube.com"));
cannoncial_suffixes.push_back(string(".googlevideo.com"));
@@ -1632,8 +2072,8 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
HostPortPair host_port_pair1(r3_host_name, 80);
QuicCryptoClientConfig* crypto_config =
- QuicStreamFactoryPeer::GetCryptoConfig(&factory_);
- QuicServerId server_id1(host_port_pair1, is_https_, privacy_mode_);
+ QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
+ QuicServerId server_id1(host_port_pair1, privacy_mode_);
QuicCryptoClientConfig::CachedState* cached1 =
crypto_config->LookupOrCreate(server_id1);
EXPECT_FALSE(cached1->proof_valid());
@@ -1645,7 +2085,7 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
cached1->SetProofInvalid();
HostPortPair host_port_pair2(r4_host_name, 80);
- QuicServerId server_id2(host_port_pair2, is_https_, privacy_mode_);
+ QuicServerId server_id2(host_port_pair2, privacy_mode_);
QuicCryptoClientConfig::CachedState* cached2 =
crypto_config->LookupOrCreate(server_id2);
EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
@@ -1655,23 +2095,33 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
}
TEST_P(QuicStreamFactoryTest, RacingConnections) {
+ disable_disk_cache_ = false;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
if (!GetParam().enable_connection_racing)
return;
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- MockRead reads2[] = {
- MockRead(ASYNC, 0, 0) // EOF
- };
- DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
+ MockRead reads2[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
+
+ const AlternativeService alternative_service1(QUIC, host_port_pair_.host(),
+ host_port_pair_.port());
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service1, 1.0, expiration));
+
+ http_server_properties_.SetAlternativeServices(
+ host_port_pair_, alternative_service_info_vector);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -1679,14 +2129,14 @@ TEST_P(QuicStreamFactoryTest, RacingConnections) {
host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
"192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- QuicServerId server_id(host_port_pair_, is_https_, privacy_mode_);
+ QuicStreamRequest request(factory_.get());
+ QuicServerId server_id(host_port_pair_, privacy_mode_);
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- EXPECT_EQ(2u,
- QuicStreamFactoryPeer::GetNumberOfActiveJobs(&factory_, server_id));
+ EXPECT_EQ(2u, QuicStreamFactoryPeer::GetNumberOfActiveJobs(factory_.get(),
+ server_id));
runner_->RunNextTask();
@@ -1694,21 +2144,21 @@ TEST_P(QuicStreamFactoryTest, RacingConnections) {
EXPECT_TRUE(stream.get());
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
- EXPECT_EQ(0u,
- QuicStreamFactoryPeer::GetNumberOfActiveJobs(&factory_, server_id));
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumberOfActiveJobs(factory_.get(),
+ server_id));
}
TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
+ disable_disk_cache_ = true;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -1716,8 +2166,8 @@ TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
"192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -1732,37 +2182,38 @@ TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
}
TEST_P(QuicStreamFactoryTest, BadPacketLoss) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
- QuicStreamFactoryPeer::SetMaxNumberOfLossyConnections(&factory_, 2);
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ disable_disk_cache_ = false;
+ max_number_of_lossy_connections_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- DeterministicSocketData socket_data2(nullptr, 0, nullptr, 0);
+ SequencedSocketData socket_data2(nullptr, 0, nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- DeterministicSocketData socket_data3(nullptr, 0, nullptr, 0);
+ SequencedSocketData socket_data3(nullptr, 0, nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data3);
- socket_data3.StopAfter(1);
- DeterministicSocketData socket_data4(nullptr, 0, nullptr, 0);
+ SequencedSocketData socket_data4(nullptr, 0, nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data4);
- socket_data4.StopAfter(1);
- HostPortPair server2("mail.example.org", kDefaultServerPort);
- HostPortPair server3("docs.example.org", kDefaultServerPort);
- HostPortPair server4("images.example.org", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+ HostPortPair server4(kServer4HostName, kDefaultServerPort);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -1773,115 +2224,116 @@ TEST_P(QuicStreamFactoryTest, BadPacketLoss) {
host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
DVLOG(1) << "Create 1st session and test packet loss";
// Set packet_loss_rate to a lower value than packet_loss_threshold.
EXPECT_FALSE(
- factory_.OnHandshakeConfirmed(session, /*packet_loss_rate=*/0.9f));
+ factory_->OnHandshakeConfirmed(session, /*packet_loss_rate=*/0.9f));
EXPECT_TRUE(session->connection()->connected());
- EXPECT_TRUE(QuicStreamFactoryPeer::HasActiveSession(
- &factory_, host_port_pair_, is_https_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
// Set packet_loss_rate to a higher value than packet_loss_threshold only once
// and that shouldn't close the session and it shouldn't disable QUIC.
EXPECT_FALSE(
- factory_.OnHandshakeConfirmed(session, /*packet_loss_rate=*/1.0f));
+ factory_->OnHandshakeConfirmed(session, /*packet_loss_rate=*/1.0f));
EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
EXPECT_TRUE(session->connection()->connected());
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
- EXPECT_TRUE(QuicStreamFactoryPeer::HasActiveSession(
- &factory_, host_port_pair_, is_https_));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
// Test N-in-a-row high packet loss connections.
DVLOG(1) << "Create 2nd session and test packet loss";
TestCompletionCallback callback2;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback2.callback()));
QuicChromiumClientSession* session2 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2);
// If there is no packet loss during handshake confirmation, number of lossy
// connections for the port should be 0.
EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, server2.port()));
+ factory_.get(), server2.port()));
EXPECT_FALSE(
- factory_.OnHandshakeConfirmed(session2, /*packet_loss_rate=*/0.9f));
+ factory_->OnHandshakeConfirmed(session2, /*packet_loss_rate=*/0.9f));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, server2.port()));
+ factory_.get(), server2.port()));
EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, server2.port()));
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server2.port()));
// Set packet_loss_rate to a higher value than packet_loss_threshold only once
// and that shouldn't close the session and it shouldn't disable QUIC.
EXPECT_FALSE(
- factory_.OnHandshakeConfirmed(session2, /*packet_loss_rate=*/1.0f));
+ factory_->OnHandshakeConfirmed(session2, /*packet_loss_rate=*/1.0f));
EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, server2.port()));
+ factory_.get(), server2.port()));
EXPECT_TRUE(session2->connection()->connected());
EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, server2.port()));
- EXPECT_TRUE(
- QuicStreamFactoryPeer::HasActiveSession(&factory_, server2, is_https_));
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server2.port()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server2));
DVLOG(1) << "Create 3rd session which also has packet loss";
TestCompletionCallback callback3;
- QuicStreamRequest request3(&factory_);
- EXPECT_EQ(OK, request3.Request(server3, is_https_, privacy_mode_,
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
/*cert_verify_flags=*/0, server3.host(), "GET",
net_log_, callback3.callback()));
QuicChromiumClientSession* session3 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server3, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server3);
DVLOG(1) << "Create 4th session with packet loss and test IsQuicDisabled()";
TestCompletionCallback callback4;
- QuicStreamRequest request4(&factory_);
- EXPECT_EQ(OK, request4.Request(server4, is_https_, privacy_mode_,
+ QuicStreamRequest request4(factory_.get());
+ EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
/*cert_verify_flags=*/0, server4.host(), "GET",
net_log_, callback4.callback()));
QuicChromiumClientSession* session4 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server4, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server4);
// Set packet_loss_rate to higher value than packet_loss_threshold 2nd time in
// a row and that should close the session and disable QUIC.
EXPECT_TRUE(
- factory_.OnHandshakeConfirmed(session3, /*packet_loss_rate=*/1.0f));
+ factory_->OnHandshakeConfirmed(session3, /*packet_loss_rate=*/1.0f));
EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, server3.port()));
+ factory_.get(), server3.port()));
EXPECT_FALSE(session3->connection()->connected());
- EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(&factory_, server3.port()));
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server3.port()));
EXPECT_FALSE(
- QuicStreamFactoryPeer::HasActiveSession(&factory_, server3, is_https_));
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server3));
EXPECT_FALSE(HasActiveSession(server3));
// Set packet_loss_rate to higher value than packet_loss_threshold 3rd time in
// a row and IsQuicDisabled() should close the session.
EXPECT_TRUE(
- factory_.OnHandshakeConfirmed(session4, /*packet_loss_rate=*/1.0f));
+ factory_->OnHandshakeConfirmed(session4, /*packet_loss_rate=*/1.0f));
EXPECT_EQ(3, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, server4.port()));
+ factory_.get(), server4.port()));
EXPECT_FALSE(session4->connection()->connected());
- EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(&factory_, server4.port()));
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server4.port()));
EXPECT_FALSE(
- QuicStreamFactoryPeer::HasActiveSession(&factory_, server4, is_https_));
+ QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server4));
EXPECT_FALSE(HasActiveSession(server4));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
@@ -1903,27 +2355,27 @@ TEST_P(QuicStreamFactoryTest, BadPacketLoss) {
}
TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfTwo) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
- QuicStreamFactoryPeer::SetThresholdPublicResetsPostHandshake(&factory_, 2);
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ disable_disk_cache_ = false;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- HostPortPair server2("mail.example.org", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::CONFIRM_HANDSHAKE);
@@ -1932,13 +2384,13 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfTwo) {
"192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
session->connection()->CloseConnection(QUIC_PUBLIC_RESET, true);
@@ -1947,33 +2399,33 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfTwo) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_EQ(1,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
// Test two-in-a-row public reset post handshakes..
DVLOG(1) << "Create 2nd session and trigger public reset post handshake";
TestCompletionCallback callback2;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback2.callback()));
QuicChromiumClientSession* session2 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2);
session2->connection()->CloseConnection(QUIC_PUBLIC_RESET, true);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
- EXPECT_EQ(2,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_TRUE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(
QuicChromiumClientSession::QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE,
- factory_.QuicDisabledReason(host_port_pair_.port()));
+ factory_->QuicDisabledReason(host_port_pair_.port()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
@@ -1986,27 +2438,27 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfTwo) {
}
TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfTwo) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
- QuicStreamFactoryPeer::SetThresholdTimeoutsWithOpenStreams(&factory_, 2);
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ disable_disk_cache_ = true;
+ threshold_timeouts_with_open_streams_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- HostPortPair server2("mail.example.org", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::CONFIRM_HANDSHAKE);
@@ -2015,13 +2467,13 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfTwo) {
"192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
@@ -2037,19 +2489,20 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfTwo) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
// Test two-in-a-row timeouts with open streams.
DVLOG(1) << "Create 2nd session and timeout with open stream";
TestCompletionCallback callback2;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback2.callback()));
QuicChromiumClientSession* session2 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2);
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
@@ -2061,11 +2514,12 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfTwo) {
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
- EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_TRUE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
- factory_.QuicDisabledReason(host_port_pair_.port()));
+ factory_->QuicDisabledReason(host_port_pair_.port()));
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
@@ -2074,32 +2528,31 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfTwo) {
}
TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfThree) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
- QuicStreamFactoryPeer::SetThresholdPublicResetsPostHandshake(&factory_, 2);
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- DeterministicSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data3);
- socket_data3.StopAfter(1);
- HostPortPair server2("mail.example.org", kDefaultServerPort);
- HostPortPair server3("docs.example.org", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::CONFIRM_HANDSHAKE);
@@ -2110,13 +2563,13 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfThree) {
host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
// Test first and third out of three public reset post handshakes.
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
session->connection()->CloseConnection(QUIC_PUBLIC_RESET, true);
@@ -2125,52 +2578,52 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfThree) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_EQ(1,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
DVLOG(1) << "Create 2nd session without disable trigger";
TestCompletionCallback callback2;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback2.callback()));
QuicChromiumClientSession* session2 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2);
session2->connection()->CloseConnection(QUIC_NO_ERROR, false);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
- EXPECT_EQ(1,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
DVLOG(1) << "Create 3rd session with public reset post handshake,"
<< " will disable QUIC";
TestCompletionCallback callback3;
- QuicStreamRequest request3(&factory_);
- EXPECT_EQ(OK, request3.Request(server3, is_https_, privacy_mode_,
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
/*cert_verify_flags=*/0, server3.host(), "GET",
net_log_, callback3.callback()));
QuicChromiumClientSession* session3 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server3, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server3);
session3->connection()->CloseConnection(QUIC_PUBLIC_RESET, true);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop3;
run_loop3.RunUntilIdle();
- EXPECT_EQ(2,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_TRUE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(
QuicChromiumClientSession::QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE,
- factory_.QuicDisabledReason(host_port_pair_.port()));
+ factory_->QuicDisabledReason(host_port_pair_.port()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
@@ -2188,33 +2641,33 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfThree) {
}
TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfThree) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
- QuicStreamFactoryPeer::SetThresholdTimeoutsWithOpenStreams(&factory_, 2);
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- // DeterministicSocketData socket_data2(nullptr, 0, nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ // SequencedSocketData socket_data2(nullptr, 0, nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- DeterministicSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data3);
- socket_data3.StopAfter(1);
- HostPortPair server2("mail.example.org", kDefaultServerPort);
- HostPortPair server3("docs.example.org", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::CONFIRM_HANDSHAKE);
@@ -2225,13 +2678,13 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfThree) {
host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
// Test first and third out of three timeouts with open streams.
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
@@ -2247,39 +2700,41 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfThree) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
// Test two-in-a-row timeouts with open streams.
DVLOG(1) << "Create 2nd session without timeout";
TestCompletionCallback callback2;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback2.callback()));
QuicChromiumClientSession* session2 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2);
session2->connection()->CloseConnection(QUIC_NO_ERROR, true);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
- EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
DVLOG(1) << "Create 3rd session with timeout with open streams,"
<< " will disable QUIC";
TestCompletionCallback callback3;
- QuicStreamRequest request3(&factory_);
- EXPECT_EQ(OK, request3.Request(server3, is_https_, privacy_mode_,
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
/*cert_verify_flags=*/0, server3.host(), "GET",
net_log_, callback3.callback()));
QuicChromiumClientSession* session3 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server3, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server3);
scoped_ptr<QuicHttpStream> stream3 = request3.ReleaseStream();
EXPECT_TRUE(stream3.get());
@@ -2290,11 +2745,12 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfThree) {
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop3;
run_loop3.RunUntilIdle();
- EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_TRUE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
- factory_.QuicDisabledReason(host_port_pair_.port()));
+ factory_->QuicDisabledReason(host_port_pair_.port()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
@@ -2307,37 +2763,37 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfThree) {
}
TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfFour) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
- QuicStreamFactoryPeer::SetThresholdPublicResetsPostHandshake(&factory_, 2);
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- DeterministicSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data3);
- socket_data3.StopAfter(1);
- DeterministicSocketData socket_data4(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data4(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data4);
- socket_data4.StopAfter(1);
- HostPortPair server2("mail.example.org", kDefaultServerPort);
- HostPortPair server3("docs.example.org", kDefaultServerPort);
- HostPortPair server4("images.example.org", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+ HostPortPair server4(kServer4HostName, kDefaultServerPort);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::CONFIRM_HANDSHAKE);
@@ -2349,13 +2805,13 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfFour) {
host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
// Test first and fourth out of four public reset post handshakes.
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
session->connection()->CloseConnection(QUIC_PUBLIC_RESET, true);
@@ -2364,67 +2820,67 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfFour) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_EQ(1,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
DVLOG(1) << "Create 2nd and 3rd sessions without disable trigger";
TestCompletionCallback callback2;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback2.callback()));
QuicChromiumClientSession* session2 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2);
session2->connection()->CloseConnection(QUIC_NO_ERROR, false);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
- EXPECT_EQ(1,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
TestCompletionCallback callback3;
- QuicStreamRequest request3(&factory_);
- EXPECT_EQ(OK, request3.Request(server3, is_https_, privacy_mode_,
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
/*cert_verify_flags=*/0, server3.host(), "GET",
net_log_, callback3.callback()));
QuicChromiumClientSession* session3 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server3, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server3);
session3->connection()->CloseConnection(QUIC_NO_ERROR, false);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop3;
run_loop3.RunUntilIdle();
- EXPECT_EQ(1,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
DVLOG(1) << "Create 4rd session with public reset post handshake,"
<< " will not disable QUIC";
TestCompletionCallback callback4;
- QuicStreamRequest request4(&factory_);
- EXPECT_EQ(OK, request4.Request(server4, is_https_, privacy_mode_,
+ QuicStreamRequest request4(factory_.get());
+ EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
/*cert_verify_flags=*/0, server4.host(), "GET",
net_log_, callback4.callback()));
QuicChromiumClientSession* session4 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server4, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server4);
session4->connection()->CloseConnection(QUIC_PUBLIC_RESET, true);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop4;
run_loop4.RunUntilIdle();
- EXPECT_EQ(1,
- QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
@@ -2446,38 +2902,38 @@ TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfFour) {
}
TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfFour) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
- QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true);
- QuicStreamFactoryPeer::SetThresholdTimeoutsWithOpenStreams(&factory_, 2);
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
- &factory_, host_port_pair_.port()));
+ factory_.get(), host_port_pair_.port()));
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0) // EOF
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
- // DeterministicSocketData socket_data2(nullptr, 0, nullptr, 0);
- DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
+ // SequencedSocketData socket_data2(nullptr, 0, nullptr, 0);
+ SequencedSocketData socket_data2(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data2);
- socket_data2.StopAfter(1);
- DeterministicSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data3(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data3);
- socket_data3.StopAfter(1);
- DeterministicSocketData socket_data4(reads, arraysize(reads), nullptr, 0);
+ SequencedSocketData socket_data4(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data4);
- socket_data4.StopAfter(1);
- HostPortPair server2("mail.example.org", kDefaultServerPort);
- HostPortPair server3("docs.example.org", kDefaultServerPort);
- HostPortPair server4("images.example.org", kDefaultServerPort);
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+ HostPortPair server4(kServer4HostName, kDefaultServerPort);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::CONFIRM_HANDSHAKE);
@@ -2489,13 +2945,13 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfFour) {
host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
// Test first and fourth out of three timeouts with open streams.
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
- QuicChromiumClientSession* session = QuicStreamFactoryPeer::GetActiveSession(
- &factory_, host_port_pair_, is_https_);
+ QuicChromiumClientSession* session =
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
EXPECT_TRUE(stream.get());
@@ -2511,55 +2967,58 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfFour) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
DVLOG(1) << "Create 2nd and 3rd sessions without timeout";
TestCompletionCallback callback2;
- QuicStreamRequest request2(&factory_);
- EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_,
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
/*cert_verify_flags=*/0, server2.host(), "GET",
net_log_, callback2.callback()));
QuicChromiumClientSession* session2 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server2);
session2->connection()->CloseConnection(QUIC_NO_ERROR, true);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
- EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
TestCompletionCallback callback3;
- QuicStreamRequest request3(&factory_);
- EXPECT_EQ(OK, request3.Request(server3, is_https_, privacy_mode_,
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
/*cert_verify_flags=*/0, server3.host(), "GET",
net_log_, callback3.callback()));
QuicChromiumClientSession* session3 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server3, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server3);
session3->connection()->CloseConnection(QUIC_NO_ERROR, true);
// Need to spin the loop now to ensure that
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop3;
run_loop3.RunUntilIdle();
- EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
DVLOG(1) << "Create 4th session with timeout with open streams,"
<< " will not disable QUIC";
TestCompletionCallback callback4;
- QuicStreamRequest request4(&factory_);
- EXPECT_EQ(OK, request4.Request(server4, is_https_, privacy_mode_,
+ QuicStreamRequest request4(factory_.get());
+ EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
/*cert_verify_flags=*/0, server4.host(), "GET",
net_log_, callback4.callback()));
QuicChromiumClientSession* session4 =
- QuicStreamFactoryPeer::GetActiveSession(&factory_, server4, is_https_);
+ QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server4);
scoped_ptr<QuicHttpStream> stream4 = request4.ReleaseStream();
EXPECT_TRUE(stream4.get());
@@ -2570,9 +3029,10 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfFour) {
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop4;
run_loop4.RunUntilIdle();
- EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(&factory_));
- EXPECT_FALSE(
- QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
EXPECT_TRUE(stream2.get());
@@ -2589,34 +3049,18 @@ TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfFour) {
}
TEST_P(QuicStreamFactoryTest, EnableDelayTcpRace) {
- bool delay_tcp_race = QuicStreamFactoryPeer::GetDelayTcpRace(&factory_);
- QuicStreamFactoryPeer::SetDelayTcpRace(&factory_, false);
- MockRead reads[] = {
- MockRead(ASYNC, OK, 0),
- };
- DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ bool delay_tcp_race = QuicStreamFactoryPeer::GetDelayTcpRace(factory_.get());
+ QuicStreamFactoryPeer::SetDelayTcpRace(factory_.get(), false);
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
-
- // Set up data in HttpServerProperties.
- scoped_ptr<HttpServerProperties> http_server_properties(
- new HttpServerPropertiesImpl());
- QuicStreamFactoryPeer::SetHttpServerProperties(
- &factory_, http_server_properties->GetWeakPtr());
-
- const AlternativeService alternative_service1(QUIC, host_port_pair_.host(),
- host_port_pair_.port());
- AlternativeServiceInfoVector alternative_service_info_vector;
- base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
- alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service1, 1.0, expiration));
-
- http_server_properties->SetAlternativeServices(
- host_port_pair_, alternative_service_info_vector);
ServerNetworkStats stats1;
stats1.srtt = base::TimeDelta::FromMicroseconds(10);
- http_server_properties->SetServerNetworkStats(host_port_pair_, stats1);
+ http_server_properties_.SetServerNetworkStats(host_port_pair_, stats1);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -2624,20 +3068,20 @@ TEST_P(QuicStreamFactoryTest, EnableDelayTcpRace) {
host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
"192.168.0.1", "");
- QuicStreamRequest request(&factory_);
+ QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
- request.Request(host_port_pair_, is_https_, privacy_mode_,
+ request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"POST", net_log_, callback_.callback()));
// If we don't delay TCP connection, then time delay should be 0.
- EXPECT_FALSE(factory_.delay_tcp_race());
+ EXPECT_FALSE(factory_->delay_tcp_race());
EXPECT_EQ(base::TimeDelta(), request.GetTimeDelayForWaitingJob());
// Enable |delay_tcp_race_| param and verify delay is one RTT and that
// server supports QUIC.
- QuicStreamFactoryPeer::SetDelayTcpRace(&factory_, true);
- EXPECT_TRUE(factory_.delay_tcp_race());
+ QuicStreamFactoryPeer::SetDelayTcpRace(factory_.get(), true);
+ EXPECT_TRUE(factory_->delay_tcp_race());
EXPECT_EQ(base::TimeDelta::FromMicroseconds(15),
request.GetTimeDelayForWaitingJob());
@@ -2651,18 +3095,18 @@ TEST_P(QuicStreamFactoryTest, EnableDelayTcpRace) {
EXPECT_TRUE(stream.get());
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
- QuicStreamFactoryPeer::SetDelayTcpRace(&factory_, delay_tcp_race);
+ QuicStreamFactoryPeer::SetDelayTcpRace(factory_.get(), delay_tcp_race);
}
-TEST_P(QuicStreamFactoryTest, QuicSupportedServersAtStartup) {
- factory_.set_quic_server_info_factory(&quic_server_info_factory_);
- QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get());
+TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
+ idle_connection_timeout_seconds_ = 500;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ const QuicConfig* config = QuicStreamFactoryPeer::GetConfig(factory_.get());
+ EXPECT_EQ(500, config->IdleConnectionStateLifetime().ToSeconds());
- // Set up data in HttpServerProperties.
- scoped_ptr<HttpServerProperties> http_server_properties(
- new HttpServerPropertiesImpl());
- QuicStreamFactoryPeer::SetHttpServerProperties(
- &factory_, http_server_properties->GetWeakPtr());
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
const AlternativeService alternative_service1(QUIC, host_port_pair_.host(),
host_port_pair_.port());
@@ -2671,29 +3115,99 @@ TEST_P(QuicStreamFactoryTest, QuicSupportedServersAtStartup) {
alternative_service_info_vector.push_back(
AlternativeServiceInfo(alternative_service1, 1.0, expiration));
- http_server_properties->SetAlternativeServices(
+ http_server_properties_.SetAlternativeServices(
host_port_pair_, alternative_service_info_vector);
+ http_server_properties_.SetMaxServerConfigsStoredInProperties(
+ kMaxQuicServersToPersist);
+
+ QuicServerId quic_server_id(kDefaultServerHostName, 80,
+ PRIVACY_MODE_DISABLED);
+ QuicServerInfoFactory* quic_server_info_factory =
+ new PropertiesBasedQuicServerInfoFactory(
+ http_server_properties_.GetWeakPtr());
+ factory_->set_quic_server_info_factory(quic_server_info_factory);
+
+ scoped_ptr<QuicServerInfo> quic_server_info(
+ quic_server_info_factory->GetForServer(quic_server_id));
+
+ // Update quic_server_info's server_config and persist it.
+ QuicServerInfo::State* state = quic_server_info->mutable_state();
+ // Minimum SCFG that passes config validation checks.
+ const char scfg[] = {// SCFG
+ 0x53, 0x43, 0x46, 0x47,
+ // num entries
+ 0x01, 0x00,
+ // padding
+ 0x00, 0x00,
+ // EXPY
+ 0x45, 0x58, 0x50, 0x59,
+ // EXPY end offset
+ 0x08, 0x00, 0x00, 0x00,
+ // Value
+ '1', '2', '3', '4', '5', '6', '7', '8'};
+
+ // Create temporary strings becasue Persist() clears string data in |state|.
+ string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
+ string source_address_token("test_source_address_token");
+ string signature("test_signature");
+ string test_cert("test_cert");
+ vector<string> certs;
+ certs.push_back(test_cert);
+ state->server_config = server_config;
+ state->source_address_token = source_address_token;
+ state->server_config_sig = signature;
+ state->certs = certs;
+
+ quic_server_info->Persist();
+
+ QuicStreamFactoryPeer::MaybeInitialize(factory_.get());
+ EXPECT_TRUE(QuicStreamFactoryPeer::HasInitializedData(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::SupportsQuicAtStartUp(factory_.get(),
+ host_port_pair_));
+ EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(factory_.get(),
+ quic_server_id));
+ QuicCryptoClientConfig* crypto_config =
+ QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
+ QuicCryptoClientConfig::CachedState* cached =
+ crypto_config->LookupOrCreate(quic_server_id);
+ EXPECT_FALSE(cached->server_config().empty());
+ EXPECT_TRUE(cached->GetServerConfig());
+ EXPECT_EQ(server_config, cached->server_config());
+ EXPECT_EQ(source_address_token, cached->source_address_token());
+ EXPECT_EQ(signature, cached->signature());
+ ASSERT_EQ(1U, cached->certs().size());
+ EXPECT_EQ(test_cert, cached->certs()[0]);
+}
- QuicStreamFactoryPeer::InitializeQuicSupportedServersAtStartup(&factory_);
- EXPECT_TRUE(
- QuicStreamFactoryPeer::GetQuicSupportedServersAtStartupInitialzied(
- &factory_));
- EXPECT_TRUE(
- QuicStreamFactoryPeer::SupportsQuicAtStartUp(&factory_, host_port_pair_));
+TEST_P(QuicStreamFactoryTest, QuicDoingZeroRTT) {
+ Initialize();
+
+ factory_->set_require_confirmation(true);
+ QuicServerId quic_server_id(host_port_pair_, PRIVACY_MODE_DISABLED);
+ EXPECT_FALSE(factory_->ZeroRTTEnabledFor(quic_server_id));
+
+ factory_->set_require_confirmation(false);
+ EXPECT_FALSE(factory_->ZeroRTTEnabledFor(quic_server_id));
+
+ // Load server config and verify QUIC will do 0RTT.
+ QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
+ EXPECT_TRUE(factory_->ZeroRTTEnabledFor(quic_server_id));
}
TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
- QuicStreamFactoryPeer::SetYieldAfterPackets(&factory_, 0);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
scoped_ptr<QuicEncryptedPacket> close_packet(
ConstructConnectionClosePacket(0));
- std::vector<MockRead> reads;
+ vector<MockRead> reads;
reads.push_back(
MockRead(SYNCHRONOUS, close_packet->data(), close_packet->length(), 0));
reads.push_back(MockRead(ASYNC, OK, 1));
- DeterministicSocketData socket_data(&reads[0], reads.size(), nullptr, 0);
+ SequencedSocketData socket_data(&reads[0], reads.size(), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -2706,8 +3220,8 @@ TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
// TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
SpdySessionTestTaskObserver observer("quic_packet_reader.cc", "StartReading");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
@@ -2727,18 +3241,20 @@ TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
}
TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
QuicStreamFactoryPeer::SetYieldAfterDuration(
- &factory_, QuicTime::Delta::FromMilliseconds(-1));
+ factory_.get(), QuicTime::Delta::FromMilliseconds(-1));
scoped_ptr<QuicEncryptedPacket> close_packet(
ConstructConnectionClosePacket(0));
- std::vector<MockRead> reads;
+ vector<MockRead> reads;
reads.push_back(
MockRead(SYNCHRONOUS, close_packet->data(), close_packet->length(), 0));
reads.push_back(MockRead(ASYNC, OK, 1));
- DeterministicSocketData socket_data(&reads[0], reads.size(), nullptr, 0);
+ SequencedSocketData socket_data(&reads[0], reads.size(), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
- socket_data.StopAfter(1);
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
@@ -2751,8 +3267,8 @@ TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
// TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
SpdySessionTestTaskObserver observer("quic_packet_reader.cc", "StartReading");
- QuicStreamRequest request(&factory_);
- EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_,
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, host_port_pair_.host(),
"GET", net_log_, callback_.callback()));
diff --git a/chromium/net/quic/quic_stream_sequencer.cc b/chromium/net/quic/quic_stream_sequencer.cc
index bd1bc6e4003..1c4f5806f7b 100644
--- a/chromium/net/quic/quic_stream_sequencer.cc
+++ b/chromium/net/quic/quic_stream_sequencer.cc
@@ -9,7 +9,13 @@
#include <utility>
#include "base/logging.h"
+#include "net/quic/quic_bug_tracker.h"
+#include "net/quic/quic_clock.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_frame_list.h"
+#include "net/quic/quic_protocol.h"
#include "net/quic/reliable_quic_stream.h"
+#include "net/quic/stream_sequencer_buffer.h"
using std::min;
using std::numeric_limits;
@@ -17,41 +23,30 @@ using std::string;
namespace net {
-QuicStreamSequencer::FrameData::FrameData(QuicStreamOffset offset,
- const string& segment)
- : offset(offset), segment(segment) {}
-
-QuicStreamSequencer::QuicStreamSequencer(ReliableQuicStream* quic_stream)
+QuicStreamSequencer::QuicStreamSequencer(ReliableQuicStream* quic_stream,
+ const QuicClock* clock)
: stream_(quic_stream),
- num_bytes_consumed_(0),
close_offset_(numeric_limits<QuicStreamOffset>::max()),
blocked_(false),
- num_bytes_buffered_(0),
num_frames_received_(0),
num_duplicate_frames_received_(0),
- num_early_frames_received_(0) {
+ num_early_frames_received_(0),
+ clock_(clock),
+ ignore_read_data_(false) {
+ if (FLAGS_quic_use_stream_sequencer_buffer) {
+ buffered_frames_.reset(
+ new StreamSequencerBuffer(kStreamReceiveWindowLimit));
+ } else {
+ buffered_frames_.reset(new QuicFrameList());
+ }
}
-QuicStreamSequencer::~QuicStreamSequencer() {
-}
+QuicStreamSequencer::~QuicStreamSequencer() {}
void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
++num_frames_received_;
- FrameList::iterator insertion_point = FindInsertionPoint(frame);
- if (IsDuplicate(frame, insertion_point)) {
- ++num_duplicate_frames_received_;
- // Silently ignore duplicates.
- return;
- }
-
- if (FrameOverlapsBufferedData(frame, insertion_point)) {
- stream_->CloseConnectionWithDetails(
- QUIC_INVALID_STREAM_FRAME, "Stream frame overlaps with buffered data.");
- return;
- }
-
const QuicStreamOffset byte_offset = frame.offset;
- const size_t data_len = frame.data.length();
+ const size_t data_len = frame.frame_length;
if (data_len == 0 && !frame.fin) {
// Stream frames must have data or a fin flag.
stream_->CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME,
@@ -65,24 +60,36 @@ void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
return;
}
}
+ size_t bytes_written;
+ QuicErrorCode result = buffered_frames_->OnStreamData(
+ byte_offset, StringPiece(frame.frame_buffer, frame.frame_length),
+ clock_->ApproximateNow(), &bytes_written);
- if (byte_offset > num_bytes_consumed_) {
- ++num_early_frames_received_;
+ if (result == QUIC_INVALID_STREAM_DATA) {
+ stream_->CloseConnectionWithDetails(
+ QUIC_INVALID_STREAM_FRAME, "Stream frame overlaps with buffered data.");
+ return;
+ }
+ if (result == QUIC_NO_ERROR && bytes_written == 0) {
+ ++num_duplicate_frames_received_;
+ // Silently ignore duplicates.
+ return;
}
- DVLOG(1) << "Buffering stream data at offset " << byte_offset;
- // Inserting an empty string and then copying to avoid the extra copy.
- insertion_point =
- buffered_frames_.insert(insertion_point, FrameData(byte_offset, ""));
- frame.data.CopyToString(&insertion_point->segment);
- num_bytes_buffered_ += data_len;
+ if (byte_offset > buffered_frames_->BytesConsumed()) {
+ ++num_early_frames_received_;
+ }
if (blocked_) {
return;
}
- if (byte_offset == num_bytes_consumed_) {
- stream_->OnDataAvailable();
+ if (byte_offset == buffered_frames_->BytesConsumed()) {
+ if (ignore_read_data_) {
+ FlushBufferedFrames();
+ } else {
+ stream_->OnDataAvailable();
+ }
}
}
@@ -101,180 +108,64 @@ void QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) {
}
bool QuicStreamSequencer::MaybeCloseStream() {
- if (!blocked_ && IsClosed()) {
- DVLOG(1) << "Passing up termination, as we've processed "
- << num_bytes_consumed_ << " of " << close_offset_
- << " bytes.";
- // This will cause the stream to consume the fin.
- // Technically it's an error if num_bytes_consumed isn't exactly
- // equal, but error handling seems silly at this point.
+ if (blocked_ || !IsClosed()) {
+ return false;
+ }
+
+ DVLOG(1) << "Passing up termination, as we've processed "
+ << buffered_frames_->BytesConsumed() << " of " << close_offset_
+ << " bytes.";
+ // This will cause the stream to consume the FIN.
+ // Technically it's an error if |num_bytes_consumed| isn't exactly
+ // equal to |close_offset|, but error handling seems silly at this point.
+ if (ignore_read_data_) {
+ // The sequencer is discarding stream data and must notify the stream on
+ // receipt of a FIN because the consumer won't.
+ stream_->OnFinRead();
+ } else {
stream_->OnDataAvailable();
- buffered_frames_.clear();
- num_bytes_buffered_ = 0;
- return true;
}
- return false;
+ buffered_frames_->Clear();
+ return true;
}
int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const {
DCHECK(!blocked_);
- FrameList::const_iterator it = buffered_frames_.begin();
- size_t index = 0;
- QuicStreamOffset offset = num_bytes_consumed_;
- while (it != buffered_frames_.end() && index < iov_len) {
- if (it->offset != offset) {
- return index;
- }
-
- iov[index].iov_base =
- static_cast<void*>(const_cast<char*>(it->segment.data()));
- iov[index].iov_len = it->segment.size();
- offset += it->segment.size();
+ return buffered_frames_->GetReadableRegions(iov, iov_len);
+}
- ++index;
- ++it;
- }
- return index;
+bool QuicStreamSequencer::GetReadableRegion(iovec* iov,
+ QuicTime* timestamp) const {
+ DCHECK(!blocked_);
+ return buffered_frames_->GetReadableRegion(iov, timestamp);
}
int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
DCHECK(!blocked_);
- FrameList::iterator it = buffered_frames_.begin();
- size_t iov_index = 0;
- size_t iov_offset = 0;
- size_t frame_offset = 0;
- QuicStreamOffset initial_bytes_consumed = num_bytes_consumed_;
-
- while (iov_index < iov_len && it != buffered_frames_.end() &&
- it->offset == num_bytes_consumed_) {
- int bytes_to_read = min(iov[iov_index].iov_len - iov_offset,
- it->segment.size() - frame_offset);
-
- char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset;
- memcpy(iov_ptr, it->segment.data() + frame_offset, bytes_to_read);
- frame_offset += bytes_to_read;
- iov_offset += bytes_to_read;
-
- if (iov[iov_index].iov_len == iov_offset) {
- // We've filled this buffer.
- iov_offset = 0;
- ++iov_index;
- }
- if (it->segment.size() == frame_offset) {
- // We've copied this whole frame
- RecordBytesConsumed(it->segment.size());
- buffered_frames_.erase(it);
- it = buffered_frames_.begin();
- frame_offset = 0;
- }
- }
- // Done copying. If there is a partial frame, update it.
- if (frame_offset != 0) {
- buffered_frames_.push_front(
- FrameData(it->offset + frame_offset, it->segment.substr(frame_offset)));
- buffered_frames_.erase(it);
- RecordBytesConsumed(frame_offset);
- }
- return static_cast<int>(num_bytes_consumed_ - initial_bytes_consumed);
+ size_t bytes_read = buffered_frames_->Readv(iov, iov_len);
+ stream_->AddBytesConsumed(bytes_read);
+ return static_cast<int>(bytes_read);
}
bool QuicStreamSequencer::HasBytesToRead() const {
- return !buffered_frames_.empty() &&
- buffered_frames_.begin()->offset == num_bytes_consumed_;
+ return buffered_frames_->HasBytesToRead();
}
bool QuicStreamSequencer::IsClosed() const {
- return num_bytes_consumed_ >= close_offset_;
-}
-
-QuicStreamSequencer::FrameList::iterator
-QuicStreamSequencer::FindInsertionPoint(const QuicStreamFrame& frame) {
- if (buffered_frames_.empty()) {
- return buffered_frames_.begin();
- }
- // If it's after all buffered_frames, return the end.
- if (frame.offset >= (buffered_frames_.rbegin()->offset +
- buffered_frames_.rbegin()->segment.length())) {
- return buffered_frames_.end();
- }
- FrameList::iterator iter = buffered_frames_.begin();
- // Only advance the iterator if the data begins after the already received
- // frame. If the new frame overlaps with an existing frame, the iterator will
- // still point to the frame it overlaps with.
- while (iter != buffered_frames_.end() &&
- frame.offset >= iter->offset + iter->segment.length()) {
- ++iter;
- }
- return iter;
-}
-
-bool QuicStreamSequencer::FrameOverlapsBufferedData(
- const QuicStreamFrame& frame,
- FrameList::const_iterator insertion_point) const {
- if (buffered_frames_.empty() || insertion_point == buffered_frames_.end()) {
- return false;
- }
- // If there is a buffered frame with a higher starting offset, then check to
- // see if the new frame overlaps the beginning of the higher frame.
- if (frame.offset < insertion_point->offset &&
- frame.offset + frame.data.length() > insertion_point->offset) {
- DVLOG(1) << "New frame overlaps next frame: " << frame.offset << " + "
- << frame.data.size() << " > " << insertion_point->offset;
- return true;
- }
- // If there is a buffered frame with a lower starting offset, then check to
- // see if the buffered frame runs into the new frame.
- if (frame.offset >= insertion_point->offset &&
- frame.offset <
- insertion_point->offset + insertion_point->segment.length()) {
- DVLOG(1) << "Preceeding frame overlaps new frame: "
- << insertion_point->offset << " + "
- << insertion_point->segment.length() << " > " << frame.offset;
- return true;
- }
-
- return false;
+ return buffered_frames_->BytesConsumed() >= close_offset_;
}
void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
DCHECK(!blocked_);
- size_t end_offset = num_bytes_consumed_ + num_bytes_consumed;
- while (!buffered_frames_.empty() && end_offset != num_bytes_consumed_) {
- FrameList::iterator it = buffered_frames_.begin();
- if (it->offset != num_bytes_consumed_) {
- LOG(DFATAL) << "Invalid argument to MarkConsumed. "
- << " num_bytes_consumed_: " << num_bytes_consumed_
- << " end_offset: " << end_offset << " offset: " << it->offset
- << " length: " << it->segment.length();
- stream_->Reset(QUIC_ERROR_PROCESSING_STREAM);
- return;
- }
-
- if (it->offset + it->segment.length() <= end_offset) {
- RecordBytesConsumed(it->segment.length());
- // This chunk is entirely consumed.
- buffered_frames_.erase(it);
- continue;
- }
-
- // Partially consume this frame.
- size_t delta = end_offset - it->offset;
- RecordBytesConsumed(delta);
- string new_data = it->segment.substr(delta);
- buffered_frames_.erase(it);
- buffered_frames_.push_front(FrameData(num_bytes_consumed_, new_data));
- break;
+ bool result = buffered_frames_->MarkConsumed(num_bytes_consumed);
+ if (!result) {
+ QUIC_BUG << "Invalid argument to MarkConsumed."
+ << " expect to consume: " << num_bytes_consumed
+ << ", but not enough bytes available.";
+ stream_->Reset(QUIC_ERROR_PROCESSING_STREAM);
+ return;
}
-}
-
-bool QuicStreamSequencer::IsDuplicate(
- const QuicStreamFrame& frame,
- FrameList::const_iterator insertion_point) const {
- // A frame is duplicate if the frame offset is smaller than the bytes consumed
- // or identical to an already received frame.
- return frame.offset < num_bytes_consumed_ ||
- (insertion_point != buffered_frames_.end() &&
- frame.offset == insertion_point->offset);
+ stream_->AddBytesConsumed(num_bytes_consumed);
}
void QuicStreamSequencer::SetBlockedUntilFlush() {
@@ -288,11 +179,30 @@ void QuicStreamSequencer::SetUnblocked() {
}
}
-void QuicStreamSequencer::RecordBytesConsumed(size_t bytes_consumed) {
- num_bytes_consumed_ += bytes_consumed;
- num_bytes_buffered_ -= bytes_consumed;
+void QuicStreamSequencer::StopReading() {
+ if (ignore_read_data_) {
+ return;
+ }
+ ignore_read_data_ = true;
+ FlushBufferedFrames();
+}
+
+void QuicStreamSequencer::FlushBufferedFrames() {
+ DCHECK(ignore_read_data_);
+ size_t bytes_flushed = buffered_frames_->FlushBufferedFrames();
+ DVLOG(1) << "Flushing buffered data at offset "
+ << buffered_frames_->BytesConsumed() << " length " << bytes_flushed
+ << " for stream " << stream_->id();
+ stream_->AddBytesConsumed(bytes_flushed);
+ MaybeCloseStream();
+}
+
+size_t QuicStreamSequencer::NumBytesBuffered() const {
+ return buffered_frames_->BytesBuffered();
+}
- stream_->AddBytesConsumed(bytes_consumed);
+QuicStreamOffset QuicStreamSequencer::NumBytesConsumed() const {
+ return buffered_frames_->BytesConsumed();
}
} // namespace net
diff --git a/chromium/net/quic/quic_stream_sequencer.h b/chromium/net/quic/quic_stream_sequencer.h
index 60a950b3bcd..65d99baaf28 100644
--- a/chromium/net/quic/quic_stream_sequencer.h
+++ b/chromium/net/quic/quic_stream_sequencer.h
@@ -5,11 +5,13 @@
#ifndef NET_QUIC_QUIC_STREAM_SEQUENCER_H_
#define NET_QUIC_QUIC_STREAM_SEQUENCER_H_
+#include <stddef.h>
+
#include <map>
#include <string>
-#include "base/basictypes.h"
-#include "net/base/iovec.h"
+#include "base/macros.h"
+#include "net/quic/quic_frame_list.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -18,6 +20,7 @@ namespace test {
class QuicStreamSequencerPeer;
} // namespace test
+class QuicClock;
class QuicSession;
class ReliableQuicStream;
@@ -25,20 +28,7 @@ class ReliableQuicStream;
// up to the next layer.
class NET_EXPORT_PRIVATE QuicStreamSequencer {
public:
- // A contiguous segment received by a QUIC stream.
- struct FrameData {
- FrameData(QuicStreamOffset offset, const std::string& segment);
-
- const QuicStreamOffset offset;
- std::string segment;
- };
-
- // TODO(alyssar) use something better than strings.
- // Maybe write new frames into a ring buffer, and keep track of consumed
- // bytes, and gaps.
- typedef std::list<FrameData> FrameList;
-
- explicit QuicStreamSequencer(ReliableQuicStream* quic_stream);
+ QuicStreamSequencer(ReliableQuicStream* quic_stream, const QuicClock* clock);
virtual ~QuicStreamSequencer();
// If the frame is the next one we need in order to process in-order data,
@@ -55,6 +45,12 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer {
// number of iovs used. Non-destructive of the underlying data.
int GetReadableRegions(iovec* iov, size_t iov_len) const;
+ // Fills in one iovec with the next readable region. |timestamp| is
+ // data arrived at the sequencer, and is used for measuring head of
+ // line blocking (HOL). Returns false if there is no readable
+ // region available.
+ bool GetReadableRegion(iovec* iov, QuicTime* timestamp) const;
+
// Copies the data into the iov_len buffers provided. Returns the number of
// bytes read. Any buffered data no longer in use will be released.
// TODO(rch): remove this method and instead implement it as a helper method
@@ -79,8 +75,16 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer {
// Blocks processing of frames until |SetUnblocked| is called.
void SetBlockedUntilFlush();
- size_t num_bytes_buffered() const { return num_bytes_buffered_; }
- QuicStreamOffset num_bytes_consumed() const { return num_bytes_consumed_; }
+ // Sets the sequencer to discard all incoming data itself and not call
+ // |stream_->OnDataAvailable()|. |stream_->OnFinRead()| will be called
+ // automatically when the FIN is consumed (which may be immediately).
+ void StopReading();
+
+ // Number of bytes in the buffer right now.
+ size_t NumBytesBuffered() const;
+
+ // Number of bytes has been consumed.
+ QuicStreamOffset NumBytesConsumed() const;
int num_frames_received() const { return num_frames_received_; }
@@ -90,22 +94,14 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer {
int num_early_frames_received() const { return num_early_frames_received_; }
+ bool ignore_read_data() const { return ignore_read_data_; }
+
private:
friend class test::QuicStreamSequencerPeer;
- // Finds the place the frame should be inserted. If an identical frame is
- // present, stops on the identical frame.
- FrameList::iterator FindInsertionPoint(const QuicStreamFrame& frame);
-
- // Returns true if |frame| contains data which overlaps buffered data
- // (indicating an invalid stream frame has been received).
- bool FrameOverlapsBufferedData(
- const QuicStreamFrame& frame,
- FrameList::const_iterator insertion_point) const;
-
- // Returns true if the sequencer has received this frame before.
- bool IsDuplicate(const QuicStreamFrame& frame,
- FrameList::const_iterator insertion_point) const;
+ // Deletes and records as consumed any buffered data that is now in-sequence.
+ // (To be called only after StopReading has been called.)
+ void FlushBufferedFrames();
// Wait until we've seen 'offset' bytes, and then terminate the stream.
void CloseStreamAtOffset(QuicStreamOffset offset);
@@ -114,18 +110,11 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer {
// the stream of FIN, and clear buffers.
bool MaybeCloseStream();
- // Called whenever bytes are consumed by the stream. Updates
- // num_bytes_consumed_ and num_bytes_buffered_.
- void RecordBytesConsumed(size_t bytes_consumed);
-
// The stream which owns this sequencer.
ReliableQuicStream* stream_;
- // The last data consumed by the stream.
- QuicStreamOffset num_bytes_consumed_;
-
- // Stores buffered frames in offset order.
- FrameList buffered_frames_;
+ // Stores received data in offset order.
+ scoped_ptr<QuicStreamSequencerBufferInterface> buffered_frames_;
// The offset, if any, we got a stream termination for. When this many bytes
// have been processed, the sequencer will be closed.
@@ -135,9 +124,6 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer {
// buffer all new incoming data until FlushBufferedFrames is called.
bool blocked_;
- // Tracks how many bytes the sequencer has buffered.
- size_t num_bytes_buffered_;
-
// Count of the number of frames received.
int num_frames_received_;
@@ -148,6 +134,12 @@ class NET_EXPORT_PRIVATE QuicStreamSequencer {
// received.
int num_early_frames_received_;
+ // Not owned.
+ const QuicClock* clock_;
+
+ // If true, all incoming data will be discarded.
+ bool ignore_read_data_;
+
DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencer);
};
diff --git a/chromium/net/quic/quic_stream_sequencer_buffer_interface.h b/chromium/net/quic/quic_stream_sequencer_buffer_interface.h
new file mode 100644
index 00000000000..2fc9e653f6f
--- /dev/null
+++ b/chromium/net/quic/quic_stream_sequencer_buffer_interface.h
@@ -0,0 +1,78 @@
+// 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_QUIC_QUIC_STREAM_SEQUENCER_BUFFER_INTERFACE_H_
+#define NET_QUIC_QUIC_STREAM_SEQUENCER_BUFFER_INTERFACE_H_
+
+#include <stddef.h>
+
+#include "net/quic/quic_protocol.h"
+
+using base::StringPiece;
+
+namespace net {
+
+// The QuicStreamSequencer uses an implementation of this interface to store
+// received data.
+class NET_EXPORT_PRIVATE QuicStreamSequencerBufferInterface {
+ public:
+ virtual ~QuicStreamSequencerBufferInterface() {}
+
+ // Free the space used to buffer data.
+ virtual void Clear() = 0;
+
+ // Returns true if there is nothing to read in this buffer.
+ virtual bool Empty() const = 0;
+
+ // Called to buffer new data received for this stream. If the data was
+ // successfully buffered, returns QUIC_NO_ERROR and stores the number of
+ // bytes buffered in |bytes_buffered|. Returns an error otherwise.
+ // |timestamp| is the time the data arrived.
+ virtual QuicErrorCode OnStreamData(QuicStreamOffset offset,
+ StringPiece data,
+ QuicTime timestamp,
+ size_t* bytes_buffered) = 0;
+
+ // Reads from this buffer into given iovec array, up to number of iov_len
+ // iovec objects and returns the number of bytes read.
+ virtual size_t Readv(const struct iovec* iov, size_t iov_len) = 0;
+
+ // Returns the readable region of valid data in iovec format. The readable
+ // region is the buffer region where there is valid data not yet read by
+ // client.
+ // Returns the number of iovec entries in |iov| which were populated.
+ // If the region is empty, one iovec entry with 0 length
+ // is returned, and the function returns 0. If there are more readable
+ // regions than iov_size, the function only processes the first
+ // iov_size of them.
+ virtual int GetReadableRegions(struct iovec* iov, int iov_len) const = 0;
+
+ // Fills in one iovec with data which all arrived at the same time from the
+ // next readable region.
+ // Populates |timestamp| with the time that this data arrived.
+ // Returns false if there is no readable region available.
+ virtual bool GetReadableRegion(iovec* iov, QuicTime* timestamp) const = 0;
+
+ // Called after GetReadableRegions() to free up |bytes_used| space if these
+ // bytes are processed.
+ // Pre-requisite: bytes_used <= available bytes to read.
+ virtual bool MarkConsumed(size_t bytes_used) = 0;
+
+ // Deletes and records as consumed any buffered data and clear the buffer.
+ // (To be called only after sequencer's StopReading has been called.)
+ virtual size_t FlushBufferedFrames() = 0;
+
+ // Whether there are bytes can be read out.
+ virtual bool HasBytesToRead() const = 0;
+
+ // Count how many bytes have been consumed (read out of buffer).
+ virtual QuicStreamOffset BytesConsumed() const = 0;
+
+ // Count how many bytes are in buffer at this moment.
+ virtual size_t BytesBuffered() const = 0;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_STREAM_SEQUENCER_BUFFER_INTERFACE_H_
diff --git a/chromium/net/quic/quic_stream_sequencer_test.cc b/chromium/net/quic/quic_stream_sequencer_test.cc
index 994ce842acd..3fb6bdacc26 100644
--- a/chromium/net/quic/quic_stream_sequencer_test.cc
+++ b/chromium/net/quic/quic_stream_sequencer_test.cc
@@ -10,8 +10,11 @@
#include "base/logging.h"
#include "base/rand_util.h"
#include "net/base/ip_endpoint.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_frame_list.h"
#include "net/quic/quic_utils.h"
#include "net/quic/reliable_quic_stream.h"
+#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/quic_stream_sequencer_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/test/gtest_util.h"
@@ -38,21 +41,16 @@ namespace test {
class MockStream : public ReliableQuicStream {
public:
MockStream(QuicSession* session, QuicStreamId id)
- : ReliableQuicStream(id, session) {
- }
+ : ReliableQuicStream(id, session) {}
MOCK_METHOD0(OnFinRead, void());
MOCK_METHOD0(OnDataAvailable, void());
- MOCK_METHOD2(CloseConnectionWithDetails, void(QuicErrorCode error,
- const string& details));
+ MOCK_METHOD2(CloseConnectionWithDetails,
+ void(QuicErrorCode error, const string& details));
MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error));
MOCK_METHOD0(OnCanWrite, void());
- QuicPriority EffectivePriority() const override {
- return QuicUtils::HighestPriority();
- }
- virtual bool IsFlowControlEnabled() const {
- return true;
- }
+ SpdyPriority Priority() const override { return kV3HighestPriority; }
+ virtual bool IsFlowControlEnabled() const { return true; }
};
namespace {
@@ -60,8 +58,13 @@ namespace {
static const char kPayload[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-class QuicStreamSequencerTest : public ::testing::Test {
+class QuicStreamSequencerTest : public ::testing::TestWithParam<bool> {
public:
+ void SetUp() override {
+ FLAGS_quic_use_stream_sequencer_buffer = GetParam();
+ sequencer_.reset(new QuicStreamSequencer(&stream_, &clock_));
+ }
+
void ConsumeData(size_t num_bytes) {
char buffer[1024];
ASSERT_GT(arraysize(buffer), num_bytes);
@@ -73,39 +76,61 @@ class QuicStreamSequencerTest : public ::testing::Test {
protected:
QuicStreamSequencerTest()
- : connection_(new MockConnection(Perspective::IS_CLIENT)),
+ : connection_(new MockConnection(&helper_, Perspective::IS_CLIENT)),
session_(connection_),
- stream_(&session_, 1),
- sequencer_(new QuicStreamSequencer(&stream_)) {}
+ stream_(&session_, 1) {}
- bool VerifyReadableRegions(const char** expected, size_t num_expected) {
+ // Verify that the data in first region match with the expected[0].
+ bool VerifyReadableRegion(const vector<string>& expected) {
+ iovec iovecs[1];
+ if (sequencer_->GetReadableRegions(iovecs, 1)) {
+ return (VerifyIovecs(iovecs, 1, vector<string>{expected[0]}));
+ }
+ return false;
+ }
+
+ // Verify that the data in each of currently readable regions match with each
+ // item given in |expected|.
+ bool VerifyReadableRegions(const vector<string>& expected) {
iovec iovecs[5];
size_t num_iovecs =
sequencer_->GetReadableRegions(iovecs, arraysize(iovecs));
- return VerifyIovecs(iovecs, num_iovecs, expected, num_expected);
+ return VerifyReadableRegion(expected) &&
+ VerifyIovecs(iovecs, num_iovecs, expected);
}
bool VerifyIovecs(iovec* iovecs,
size_t num_iovecs,
- const char** expected,
- size_t num_expected) {
- if (num_expected != num_iovecs) {
- LOG(ERROR) << "Incorrect number of iovecs. Expected: " << num_expected
- << " Actual: " << num_iovecs;
- return false;
- }
- for (size_t i = 0; i < num_expected; ++i) {
- if (!VerifyIovec(iovecs[i], expected[i])) {
+ const vector<string>& expected) {
+ if (!FLAGS_quic_use_stream_sequencer_buffer) {
+ if (expected.size() != num_iovecs) {
+ LOG(ERROR) << "Incorrect number of iovecs. Expected: "
+ << expected.size() << " Actual: " << num_iovecs;
return false;
}
+
+ for (size_t i = 0; i < num_iovecs; ++i) {
+ if (!VerifyIovec(iovecs[i], expected[i])) {
+ return false;
+ }
+ }
+ } else {
+ int start_position = 0;
+ for (size_t i = 0; i < num_iovecs; ++i) {
+ if (!VerifyIovec(iovecs[i], expected[0].substr(start_position,
+ iovecs[i].iov_len))) {
+ return false;
+ }
+ start_position += iovecs[i].iov_len;
+ }
}
return true;
}
bool VerifyIovec(const iovec& iovec, StringPiece expected) {
if (iovec.iov_len != expected.length()) {
- LOG(ERROR) << "Invalid length: " << iovec.iov_len
- << " vs " << expected.length();
+ LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs "
+ << expected.length();
return false;
}
if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) {
@@ -120,7 +145,8 @@ class QuicStreamSequencerTest : public ::testing::Test {
QuicStreamFrame frame;
frame.stream_id = 1;
frame.offset = byte_offset;
- frame.data = StringPiece(data);
+ frame.frame_buffer = data;
+ frame.frame_length = strlen(data);
frame.fin = true;
sequencer_->OnStreamFrame(frame);
}
@@ -129,80 +155,82 @@ class QuicStreamSequencerTest : public ::testing::Test {
QuicStreamFrame frame;
frame.stream_id = 1;
frame.offset = byte_offset;
- frame.data = StringPiece(data);
+ frame.frame_buffer = data;
+ frame.frame_length = strlen(data);
frame.fin = false;
sequencer_->OnStreamFrame(frame);
}
- size_t NumBufferedFrames() {
- return QuicStreamSequencerPeer::GetNumBufferedFrames(sequencer_.get());
- }
-
- bool FrameOverlapsBufferedData(const QuicStreamFrame& frame) {
- return QuicStreamSequencerPeer::FrameOverlapsBufferedData(sequencer_.get(),
- frame);
+ size_t NumBufferedBytes() {
+ return QuicStreamSequencerPeer::GetNumBufferedBytes(sequencer_.get());
}
+ MockConnectionHelper helper_;
MockConnection* connection_;
+ MockClock clock_;
MockQuicSpdySession session_;
testing::StrictMock<MockStream> stream_;
scoped_ptr<QuicStreamSequencer> sequencer_;
};
+INSTANTIATE_TEST_CASE_P(QuicStreamSequencerTests,
+ QuicStreamSequencerTest,
+ ::testing::Values(false, true));
+
// TODO(rch): reorder these tests so they build on each other.
-TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
+TEST_P(QuicStreamSequencerTest, RejectOldFrame) {
EXPECT_CALL(stream_, OnDataAvailable())
.WillOnce(testing::Invoke(
CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData, 3)));
OnFrame(0, "abc");
- EXPECT_EQ(0u, NumBufferedFrames());
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
EXPECT_EQ(3u, stream_.flow_controller()->bytes_consumed());
// Ignore this - it matches a past packet number and we should not see it
// again.
OnFrame(0, "def");
- EXPECT_EQ(0u, NumBufferedFrames());
+ EXPECT_EQ(0u, NumBufferedBytes());
}
-TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
+TEST_P(QuicStreamSequencerTest, RejectBufferedFrame) {
EXPECT_CALL(stream_, OnDataAvailable());
OnFrame(0, "abc");
- EXPECT_EQ(1u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
// Ignore this - it matches a buffered frame.
// Right now there's no checking that the payload is consistent.
OnFrame(0, "def");
- EXPECT_EQ(1u, NumBufferedFrames());
+ EXPECT_EQ(3u, NumBufferedBytes());
}
-TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
+TEST_P(QuicStreamSequencerTest, FullFrameConsumed) {
EXPECT_CALL(stream_, OnDataAvailable())
.WillOnce(testing::Invoke(
CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData, 3)));
OnFrame(0, "abc");
- EXPECT_EQ(0u, NumBufferedFrames());
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
}
-TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
+TEST_P(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
sequencer_->SetBlockedUntilFlush();
OnFrame(0, "abc");
- EXPECT_EQ(1u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
EXPECT_CALL(stream_, OnDataAvailable())
.WillOnce(testing::Invoke(
CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData, 3)));
sequencer_->SetUnblocked();
- EXPECT_EQ(0u, NumBufferedFrames());
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
EXPECT_CALL(stream_, OnDataAvailable())
.WillOnce(testing::Invoke(
@@ -212,12 +240,12 @@ TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
EXPECT_TRUE(sequencer_->IsClosed());
}
-TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
+TEST_P(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
sequencer_->SetBlockedUntilFlush();
OnFinFrame(0, "abc");
- EXPECT_EQ(1u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
EXPECT_CALL(stream_, OnDataAvailable())
.WillOnce(testing::Invoke(
@@ -225,62 +253,62 @@ TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
EXPECT_FALSE(sequencer_->IsClosed());
sequencer_->SetUnblocked();
EXPECT_TRUE(sequencer_->IsClosed());
- EXPECT_EQ(0u, NumBufferedFrames());
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
}
-TEST_F(QuicStreamSequencerTest, EmptyFrame) {
+TEST_P(QuicStreamSequencerTest, EmptyFrame) {
EXPECT_CALL(stream_,
CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _));
OnFrame(0, "");
- EXPECT_EQ(0u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
}
-TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
+TEST_P(QuicStreamSequencerTest, EmptyFinFrame) {
EXPECT_CALL(stream_, OnDataAvailable());
OnFinFrame(0, "");
- EXPECT_EQ(0u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
}
-TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
+TEST_P(QuicStreamSequencerTest, PartialFrameConsumed) {
EXPECT_CALL(stream_, OnDataAvailable())
.WillOnce(testing::Invoke(
CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData, 2)));
OnFrame(0, "abc");
- EXPECT_EQ(1u, NumBufferedFrames());
- EXPECT_EQ(2u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(1u, NumBufferedBytes());
+ EXPECT_EQ(2u, sequencer_->NumBytesConsumed());
}
-TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
+TEST_P(QuicStreamSequencerTest, NextxFrameNotConsumed) {
EXPECT_CALL(stream_, OnDataAvailable());
OnFrame(0, "abc");
- EXPECT_EQ(1u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
EXPECT_EQ(0, sequencer_->num_early_frames_received());
}
-TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
+TEST_P(QuicStreamSequencerTest, FutureFrameNotProcessed) {
OnFrame(3, "abc");
- EXPECT_EQ(1u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
EXPECT_EQ(1, sequencer_->num_early_frames_received());
}
-TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
+TEST_P(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
// Buffer the first
OnFrame(6, "ghi");
- EXPECT_EQ(1u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
- EXPECT_EQ(3u, sequencer_->num_bytes_buffered());
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
// Buffer the second
OnFrame(3, "def");
- EXPECT_EQ(2u, NumBufferedFrames());
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
- EXPECT_EQ(6u, sequencer_->num_bytes_buffered());
+ EXPECT_EQ(6u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
EXPECT_CALL(stream_, OnDataAvailable())
.WillOnce(testing::Invoke(
@@ -288,13 +316,13 @@ TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
// Now process all of them at once.
OnFrame(0, "abc");
- EXPECT_EQ(9u, sequencer_->num_bytes_consumed());
- EXPECT_EQ(0u, sequencer_->num_bytes_buffered());
+ EXPECT_EQ(9u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
- EXPECT_EQ(0u, NumBufferedFrames());
+ EXPECT_EQ(0u, NumBufferedBytes());
}
-TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
+TEST_P(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
InSequence s;
EXPECT_CALL(stream_, OnDataAvailable())
@@ -305,7 +333,7 @@ TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
}
-TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
+TEST_P(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
OnFinFrame(6, "");
EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
@@ -318,7 +346,7 @@ TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
EXPECT_TRUE(sequencer_->IsClosed());
}
-TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
+TEST_P(QuicStreamSequencerTest, BasicHalfUnordered) {
OnFinFrame(3, "");
EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
@@ -330,7 +358,7 @@ TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
EXPECT_TRUE(sequencer_->IsClosed());
}
-TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
+TEST_P(QuicStreamSequencerTest, TerminateWithReadv) {
char buffer[3];
OnFinFrame(3, "");
@@ -347,7 +375,7 @@ TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
EXPECT_TRUE(sequencer_->IsClosed());
}
-TEST_F(QuicStreamSequencerTest, MutipleOffsets) {
+TEST_P(QuicStreamSequencerTest, MutipleOffsets) {
OnFinFrame(3, "");
EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
@@ -379,13 +407,9 @@ class QuicSequencerRandomTest : public QuicStreamSequencerTest {
}
}
- QuicSequencerRandomTest() {
- CreateFrames();
- }
+ QuicSequencerRandomTest() { CreateFrames(); }
- int OneToN(int n) {
- return base::RandInt(1, n);
- }
+ int OneToN(int n) { return base::RandInt(1, n); }
void ReadAvailableData() {
// Read all available data
@@ -406,7 +430,7 @@ class QuicSequencerRandomTest : public QuicStreamSequencerTest {
// All frames are processed as soon as we have sequential data.
// Infinite buffering, so all frames are acked right away.
-TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
+TEST_P(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
InSequence s;
EXPECT_CALL(stream_, OnDataAvailable())
.Times(AnyNumber())
@@ -425,7 +449,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
EXPECT_EQ(kPayload, output_);
}
-TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
+TEST_P(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
char buffer[10];
iovec iov[2];
iov[0].iov_base = &buffer[0];
@@ -444,10 +468,13 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
bool has_bytes = sequencer_->HasBytesToRead();
iovec peek_iov[20];
int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20);
+ QuicTime timestamp = clock_.ApproximateNow();
if (has_bytes) {
ASSERT_LT(0, iovs_peeked);
+ ASSERT_TRUE(sequencer_->GetReadableRegion(peek_iov, &timestamp));
} else {
ASSERT_EQ(0, iovs_peeked);
+ ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov, &timestamp));
}
int total_bytes_to_peek = arraysize(buffer);
for (int i = 0; i < iovs_peeked; ++i) {
@@ -468,7 +495,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
}
// Same as above, just using a different method for reading.
-TEST_F(QuicStreamSequencerTest, MarkConsumed) {
+TEST_P(QuicStreamSequencerTest, MarkConsumed) {
InSequence s;
EXPECT_CALL(stream_, OnDataAvailable());
@@ -477,38 +504,53 @@ TEST_F(QuicStreamSequencerTest, MarkConsumed) {
OnFrame(6, "ghi");
// abcdefghi buffered.
- EXPECT_EQ(9u, sequencer_->num_bytes_buffered());
+ EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
// Peek into the data.
- const char* expected[] = {"abc", "def", "ghi"};
- ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected)));
+ vector<string> expected;
+ if (FLAGS_quic_use_stream_sequencer_buffer) {
+ expected = vector<string>{"abcdefghi"};
+ } else {
+ expected = vector<string>{"abc", "def", "ghi"};
+ }
+ ASSERT_TRUE(VerifyReadableRegions(expected));
// Consume 1 byte.
sequencer_->MarkConsumed(1);
EXPECT_EQ(1u, stream_.flow_controller()->bytes_consumed());
// Verify data.
- const char* expected2[] = {"bc", "def", "ghi"};
- ASSERT_TRUE(VerifyReadableRegions(expected2, arraysize(expected2)));
- EXPECT_EQ(8u, sequencer_->num_bytes_buffered());
+ vector<string> expected2;
+ if (FLAGS_quic_use_stream_sequencer_buffer) {
+ expected2 = vector<string>{"bcdefghi"};
+ } else {
+ expected2 = vector<string>{"bc", "def", "ghi"};
+ }
+ ASSERT_TRUE(VerifyReadableRegions(expected2));
+ EXPECT_EQ(8u, sequencer_->NumBytesBuffered());
// Consume 2 bytes.
sequencer_->MarkConsumed(2);
EXPECT_EQ(3u, stream_.flow_controller()->bytes_consumed());
// Verify data.
- const char* expected3[] = {"def", "ghi"};
- ASSERT_TRUE(VerifyReadableRegions(expected3, arraysize(expected3)));
- EXPECT_EQ(6u, sequencer_->num_bytes_buffered());
+ vector<string> expected3;
+ if (FLAGS_quic_use_stream_sequencer_buffer) {
+ expected3 = vector<string>{"defghi"};
+ } else {
+ expected3 = vector<string>{"def", "ghi"};
+ }
+ ASSERT_TRUE(VerifyReadableRegions(expected3));
+ EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
// Consume 5 bytes.
sequencer_->MarkConsumed(5);
EXPECT_EQ(8u, stream_.flow_controller()->bytes_consumed());
// Verify data.
- const char* expected4[] = {"i"};
- ASSERT_TRUE(VerifyReadableRegions(expected4, arraysize(expected4)));
- EXPECT_EQ(1u, sequencer_->num_bytes_buffered());
+ vector<string> expected4{"i"};
+ ASSERT_TRUE(VerifyReadableRegions(expected4));
+ EXPECT_EQ(1u, sequencer_->NumBytesBuffered());
}
-TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
+TEST_P(QuicStreamSequencerTest, MarkConsumedError) {
EXPECT_CALL(stream_, OnDataAvailable());
OnFrame(0, "abc");
@@ -516,18 +558,18 @@ TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
// Peek into the data. Only the first chunk should be readable because of the
// missing data.
- const char* expected[] = {"abc"};
- ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected)));
+ vector<string> expected{"abc"};
+ ASSERT_TRUE(VerifyReadableRegions(expected));
// Now, attempt to mark consumed more data than was readable and expect the
// stream to be closed.
EXPECT_CALL(stream_, Reset(QUIC_ERROR_PROCESSING_STREAM));
EXPECT_DFATAL(sequencer_->MarkConsumed(4),
- "Invalid argument to MarkConsumed. num_bytes_consumed_: 3 "
- "end_offset: 4 offset: 9 length: 17");
+ "Invalid argument to MarkConsumed."
+ " expect to consume: 4, but not enough bytes available.");
}
-TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
+TEST_P(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
InSequence s;
EXPECT_CALL(stream_, OnDataAvailable());
@@ -536,13 +578,20 @@ TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
// Missing packet: 6, ghi.
OnFrame(9, "jkl");
- const char* expected[] = {"abc", "def"};
- ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected)));
+ vector<string> expected;
+ if (FLAGS_quic_use_stream_sequencer_buffer) {
+ expected = vector<string>{"abcdef"};
+ } else {
+ expected = vector<string>{"abc", "def"};
+ }
+ ASSERT_TRUE(VerifyReadableRegions(expected));
sequencer_->MarkConsumed(6);
}
-TEST_F(QuicStreamSequencerTest, FrameOverlapsBufferedData) {
+TEST(QuicFrameListTest, FrameOverlapsBufferedData) {
+ QuicFrameList buffer;
+
// Ensure that FrameOverlapsBufferedData returns appropriate responses when
// there is existing data buffered.
const int kBufferedOffset = 10;
@@ -551,37 +600,44 @@ TEST_F(QuicStreamSequencerTest, FrameOverlapsBufferedData) {
string data(kNewDataLength, '.');
// No overlap if no buffered frames.
- EXPECT_EQ(0u, NumBufferedFrames());
+ EXPECT_EQ(0u, buffer.BytesBuffered());
+ size_t bytes_written;
// Add a buffered frame.
- sequencer_->OnStreamFrame(QuicStreamFrame(1, false, kBufferedOffset,
- string(kBufferedDataLength, '.')));
+ buffer.OnStreamData(
+ kBufferedOffset,
+ StringPiece(string(kBufferedDataLength, '.').data(), kBufferedDataLength),
+ QuicTime::Zero(), &bytes_written);
// New byte range partially overlaps with buffered frame, start offset
// preceding buffered frame.
- EXPECT_TRUE(FrameOverlapsBufferedData(
- QuicStreamFrame(1, false, kBufferedOffset - 1, data)));
- EXPECT_TRUE(FrameOverlapsBufferedData(
+ EXPECT_TRUE(QuicStreamSequencerPeer::FrameOverlapsBufferedData(
+ &buffer, QuicStreamFrame(1, false, kBufferedOffset - 1, data)));
+ EXPECT_TRUE(QuicStreamSequencerPeer::FrameOverlapsBufferedData(
+ &buffer,
QuicStreamFrame(1, false, kBufferedOffset - kNewDataLength + 1, data)));
// New byte range partially overlaps with buffered frame, start offset inside
// existing buffered frame.
- EXPECT_TRUE(FrameOverlapsBufferedData(
- QuicStreamFrame(1, false, kBufferedOffset + 1, data)));
- EXPECT_TRUE(FrameOverlapsBufferedData(QuicStreamFrame(
- 1, false, kBufferedOffset + kBufferedDataLength - 1, data)));
-
- // New byte range entirely outside of buffered frames, start offset preceeding
- // buffered frame.
- EXPECT_FALSE(FrameOverlapsBufferedData(
+ EXPECT_TRUE(QuicStreamSequencerPeer::FrameOverlapsBufferedData(
+ &buffer, QuicStreamFrame(1, false, kBufferedOffset + 1, data)));
+ EXPECT_TRUE(QuicStreamSequencerPeer::FrameOverlapsBufferedData(
+ &buffer, QuicStreamFrame(
+ 1, false, kBufferedOffset + kBufferedDataLength - 1, data)));
+
+ // New byte range entirely outside of buffered frames, start offset
+ // preceeding buffered frame.
+ EXPECT_FALSE(QuicStreamSequencerPeer::FrameOverlapsBufferedData(
+ &buffer,
QuicStreamFrame(1, false, kBufferedOffset - kNewDataLength, data)));
// New byte range entirely outside of buffered frames, start offset later than
// buffered frame.
- EXPECT_FALSE(FrameOverlapsBufferedData(
+ EXPECT_FALSE(QuicStreamSequencerPeer::FrameOverlapsBufferedData(
+ &buffer,
QuicStreamFrame(1, false, kBufferedOffset + kBufferedDataLength, data)));
}
-TEST_F(QuicStreamSequencerTest, DontAcceptOverlappingFrames) {
+TEST_P(QuicStreamSequencerTest, DontAcceptOverlappingFrames) {
// The peer should never send us non-identical stream frames which contain
// overlapping byte ranges - if they do, we close the connection.
@@ -589,12 +645,93 @@ TEST_F(QuicStreamSequencerTest, DontAcceptOverlappingFrames) {
sequencer_->OnStreamFrame(frame1);
QuicStreamFrame frame2(kClientDataStreamId1, false, 2, StringPiece("hello"));
- EXPECT_TRUE(FrameOverlapsBufferedData(frame2));
EXPECT_CALL(stream_, CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _))
.Times(1);
sequencer_->OnStreamFrame(frame2);
}
+TEST_P(QuicStreamSequencerTest, InOrderTimestamps) {
+ // This test verifies that timestamps returned by
+ // GetReadableRegion() are in the correct sequence when frames
+ // arrive at the sequencer in order.
+ EXPECT_CALL(stream_, OnDataAvailable());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+ // Buffer the first frame.
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t1 = clock_.ApproximateNow();
+ OnFrame(0, "abc");
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+ // Buffer the second frame.
+ QuicTime t2 = clock_.ApproximateNow();
+ OnFrame(3, "def");
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ EXPECT_EQ(6u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
+
+ iovec iovecs[1];
+ QuicTime timestamp(QuicTime::Zero());
+
+ EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, &timestamp));
+ EXPECT_EQ(timestamp, t1);
+ QuicStreamSequencerTest::ConsumeData(3);
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+
+ EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, &timestamp));
+ EXPECT_EQ(timestamp, t2);
+ QuicStreamSequencerTest::ConsumeData(3);
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(6u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
+TEST_P(QuicStreamSequencerTest, OutOfOrderTimestamps) {
+ // This test verifies that timestamps returned by
+ // GetReadableRegion() are in the correct sequence when frames
+ // arrive at the sequencer out of order.
+ EXPECT_CALL(stream_, OnDataAvailable());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+ // Buffer the first frame
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t1 = clock_.ApproximateNow();
+ OnFrame(3, "def");
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+ // Buffer the second frame
+ QuicTime t2 = clock_.ApproximateNow();
+ OnFrame(0, "abc");
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ EXPECT_EQ(6u, NumBufferedBytes());
+ EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
+
+ iovec iovecs[1];
+ QuicTime timestamp(QuicTime::Zero());
+
+ EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, &timestamp));
+ EXPECT_EQ(timestamp, t2);
+ QuicStreamSequencerTest::ConsumeData(3);
+ EXPECT_EQ(3u, NumBufferedBytes());
+ EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+
+ EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, &timestamp));
+ EXPECT_EQ(timestamp, t1);
+ QuicStreamSequencerTest::ConsumeData(3);
+ EXPECT_EQ(0u, NumBufferedBytes());
+ EXPECT_EQ(6u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_sustained_bandwidth_recorder.h b/chromium/net/quic/quic_sustained_bandwidth_recorder.h
index 11685d2817e..bc0d1b802ac 100644
--- a/chromium/net/quic/quic_sustained_bandwidth_recorder.h
+++ b/chromium/net/quic/quic_sustained_bandwidth_recorder.h
@@ -5,7 +5,10 @@
#ifndef NET_QUIC_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
#define NET_QUIC_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
+#include <stdint.h>
+
#include "base/logging.h"
+#include "base/macros.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_time.h"
@@ -34,9 +37,7 @@ class NET_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
QuicWallTime wall_time,
QuicTime::Delta srtt);
- bool HasEstimate() const {
- return has_estimate_;
- }
+ bool HasEstimate() const { return has_estimate_; }
QuicBandwidth BandwidthEstimate() const {
DCHECK(has_estimate_);
@@ -48,7 +49,7 @@ class NET_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
return max_bandwidth_estimate_;
}
- int64 MaxBandwidthTimestamp() const {
+ int64_t MaxBandwidthTimestamp() const {
DCHECK(has_estimate_);
return max_bandwidth_timestamp_;
}
@@ -79,7 +80,7 @@ class NET_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
QuicBandwidth max_bandwidth_estimate_;
// Timestamp indicating when the max_bandwidth_estimate_ was seen.
- int64 max_bandwidth_timestamp_;
+ int64_t max_bandwidth_timestamp_;
// Timestamp marking the beginning of the latest recording period.
QuicTime start_time_;
diff --git a/chromium/net/quic/quic_sustained_bandwidth_recorder_test.cc b/chromium/net/quic/quic_sustained_bandwidth_recorder_test.cc
index 6a5fbb25ce2..91cff412927 100644
--- a/chromium/net/quic/quic_sustained_bandwidth_recorder_test.cc
+++ b/chromium/net/quic/quic_sustained_bandwidth_recorder_test.cc
@@ -61,7 +61,7 @@ TEST(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) {
EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
estimate_time = estimate_time.Add(srtt.Multiply(3));
- const int64 kSeconds = 556677;
+ const int64_t kSeconds = 556677;
QuicWallTime second_bandwidth_wall_time =
QuicWallTime::FromUNIXSeconds(kSeconds);
recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth,
diff --git a/chromium/net/quic/quic_time.cc b/chromium/net/quic/quic_time.cc
index 7da849ebc01..2b3684bdca5 100644
--- a/chromium/net/quic/quic_time.cc
+++ b/chromium/net/quic/quic_time.cc
@@ -4,188 +4,62 @@
#include "net/quic/quic_time.h"
-#include <stdint.h>
+#include <limits>
#include "base/logging.h"
namespace net {
-// Highest number of microseconds that DateTimeOffset can hold.
-const int64 kQuicInfiniteTimeUs = INT64_C(0x7fffffffffffffff) / 10;
-
-QuicTime::Delta::Delta(base::TimeDelta delta)
- : delta_(delta) {
-}
-
-// static
-QuicTime::Delta QuicTime::Delta::Zero() {
- return QuicTime::Delta::FromMicroseconds(0);
-}
-
-// static
-QuicTime::Delta QuicTime::Delta::Infinite() {
- return QuicTime::Delta::FromMicroseconds(kQuicInfiniteTimeUs);
-}
-
-// static
-QuicTime::Delta QuicTime::Delta::FromSeconds(int64 seconds) {
- return QuicTime::Delta(base::TimeDelta::FromSeconds(seconds));
-}
-
-// static
-QuicTime::Delta QuicTime::Delta::FromMilliseconds(int64 ms) {
- return QuicTime::Delta(base::TimeDelta::FromMilliseconds(ms));
-}
-
-// static
-QuicTime::Delta QuicTime::Delta::FromMicroseconds(int64 us) {
- return QuicTime::Delta(base::TimeDelta::FromMicroseconds(us));
-}
-
-int64 QuicTime::Delta::ToSeconds() const {
- return delta_.InSeconds();
-}
-
-int64 QuicTime::Delta::ToMilliseconds() const {
- return delta_.InMilliseconds();
-}
-
-int64 QuicTime::Delta::ToMicroseconds() const {
- return delta_.InMicroseconds();
-}
-
-QuicTime::Delta QuicTime::Delta::Add(const Delta& delta) const {
- return QuicTime::Delta::FromMicroseconds(ToMicroseconds() +
- delta.ToMicroseconds());
-}
-
-QuicTime::Delta QuicTime::Delta::Subtract(const Delta& delta) const {
- return QuicTime::Delta::FromMicroseconds(ToMicroseconds() -
- delta.ToMicroseconds());
+uint64_t QuicWallTime::ToUNIXSeconds() const {
+ return microseconds_ / 1000000;
}
-QuicTime::Delta QuicTime::Delta::Multiply(int i) const {
- return QuicTime::Delta::FromMicroseconds(ToMicroseconds() * i);
-}
-
-QuicTime::Delta QuicTime::Delta::Multiply(double d) const {
- return QuicTime::Delta::FromMicroseconds(
- static_cast<int64>(ToMicroseconds() * d));
-}
-
-// static
-QuicTime::Delta QuicTime::Delta::Max(QuicTime::Delta delta1,
- QuicTime::Delta delta2) {
- return delta1 < delta2 ? delta2 : delta1;
-}
-
-bool QuicTime::Delta::IsZero() const {
- return delta_.InMicroseconds() == 0;
-}
-
-bool QuicTime::Delta::IsInfinite() const {
- return delta_.InMicroseconds() == kQuicInfiniteTimeUs;
-}
-
-// static
-QuicTime QuicTime::Zero() {
- return QuicTime(base::TimeTicks());
-}
-
-// static
-QuicTime QuicTime::Infinite() {
- return QuicTime(base::TimeTicks::FromInternalValue(kQuicInfiniteTimeUs));
-}
-
-// static
-QuicTime QuicTime::Max(QuicTime time1, QuicTime time2) {
- return time1 > time2 ? time1 : time2;
-}
-
-QuicTime::QuicTime(base::TimeTicks ticks)
- : ticks_(ticks) {
-}
-
-int64 QuicTime::ToDebuggingValue() const {
- return (ticks_ - base::TimeTicks()).InMicroseconds();
-}
-
-bool QuicTime::IsInitialized() const {
- return ticks_ != base::TimeTicks();
-}
-
-QuicTime QuicTime::Add(const Delta& delta) const {
- return QuicTime(ticks_ + delta.delta_);
-}
-
-QuicTime QuicTime::Subtract(const Delta& delta) const {
- return QuicTime(ticks_ - delta.delta_);
-}
-
-QuicTime::Delta QuicTime::Subtract(const QuicTime& other) const {
- return QuicTime::Delta(ticks_ - other.ticks_);
-}
-
-// static
-QuicWallTime QuicWallTime::FromUNIXSeconds(uint64 seconds) {
- return QuicWallTime(seconds);
-}
-
-// static
-QuicWallTime QuicWallTime::Zero() {
- return QuicWallTime(0);
-}
-
-uint64 QuicWallTime::ToUNIXSeconds() const {
- return seconds_;
+uint64_t QuicWallTime::ToUNIXMicroseconds() const {
+ return microseconds_;
}
bool QuicWallTime::IsAfter(QuicWallTime other) const {
- return seconds_ > other.seconds_;
+ return microseconds_ > other.microseconds_;
}
bool QuicWallTime::IsBefore(QuicWallTime other) const {
- return seconds_ < other.seconds_;
+ return microseconds_ < other.microseconds_;
}
bool QuicWallTime::IsZero() const {
- return seconds_ == 0;
+ return microseconds_ == 0;
}
QuicTime::Delta QuicWallTime::AbsoluteDifference(QuicWallTime other) const {
- uint64 d;
+ uint64_t d;
- if (seconds_ > other.seconds_) {
- d = seconds_ - other.seconds_;
+ if (microseconds_ > other.microseconds_) {
+ d = microseconds_ - other.microseconds_;
} else {
- d = other.seconds_ - seconds_;
+ d = other.microseconds_ - microseconds_;
}
- if (d > static_cast<uint64>(kint64max)) {
- d = kint64max;
+ if (d > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
+ d = std::numeric_limits<int64_t>::max();
}
- return QuicTime::Delta::FromSeconds(d);
+ return QuicTime::Delta::FromMicroseconds(d);
}
QuicWallTime QuicWallTime::Add(QuicTime::Delta delta) const {
- uint64 seconds = seconds_ + delta.ToSeconds();
- if (seconds < seconds_) {
- seconds = kuint64max;
+ uint64_t microseconds = microseconds_ + delta.ToMicroseconds();
+ if (microseconds < microseconds_) {
+ microseconds = std::numeric_limits<uint64_t>::max();
}
- return QuicWallTime(seconds);
+ return QuicWallTime(microseconds);
}
// TODO(ianswett) Test this.
QuicWallTime QuicWallTime::Subtract(QuicTime::Delta delta) const {
- uint64 seconds = seconds_ - delta.ToSeconds();
- if (seconds > seconds_) {
- seconds = 0;
+ uint64_t microseconds = microseconds_ - delta.ToMicroseconds();
+ if (microseconds > microseconds_) {
+ microseconds = 0;
}
- return QuicWallTime(seconds);
-}
-
-QuicWallTime::QuicWallTime(uint64 seconds)
- : seconds_(seconds) {
+ return QuicWallTime(microseconds);
}
} // namespace net
diff --git a/chromium/net/quic/quic_time.h b/chromium/net/quic/quic_time.h
index 62bf582af49..e6db990ecaa 100644
--- a/chromium/net/quic/quic_time.h
+++ b/chromium/net/quic/quic_time.h
@@ -11,16 +11,20 @@
#ifndef NET_QUIC_QUIC_TIME_H_
#define NET_QUIC_QUIC_TIME_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/compiler_specific.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
+#define QUICTIME_CONSTEXPR inline
+
namespace net {
static const int kNumSecondsPerMinute = 60;
static const int kNumSecondsPerHour = kNumSecondsPerMinute * 60;
-static const uint64 kNumMicrosPerSecond = base::Time::kMicrosecondsPerSecond;
-static const uint64 kNumMicrosPerMilli =
+static const uint64_t kNumMicrosPerSecond = base::Time::kMicrosecondsPerSecond;
+static const uint64_t kNumMicrosPerMilli =
base::Time::kMicrosecondsPerMillisecond;
// A QuicTime is a purely relative time. QuicTime values from different clocks
@@ -35,102 +39,156 @@ class NET_EXPORT_PRIVATE QuicTime {
explicit Delta(base::TimeDelta delta);
// Create a object with an offset of 0.
- static Delta Zero();
+ static QUICTIME_CONSTEXPR Delta Zero() { return Delta(0); }
// Create a object with infinite offset time.
- static Delta Infinite();
+ static QUICTIME_CONSTEXPR Delta Infinite() {
+ return Delta(kQuicInfiniteTimeUs);
+ }
// Converts a number of seconds to a time offset.
- static Delta FromSeconds(int64 secs);
+ static QUICTIME_CONSTEXPR Delta FromSeconds(int64_t secs) {
+ return Delta(secs * 1000 * 1000);
+ }
// Converts a number of milliseconds to a time offset.
- static Delta FromMilliseconds(int64 ms);
+ static QUICTIME_CONSTEXPR Delta FromMilliseconds(int64_t ms) {
+ return Delta(ms * 1000);
+ }
// Converts a number of microseconds to a time offset.
- static Delta FromMicroseconds(int64 us);
+ static QUICTIME_CONSTEXPR Delta FromMicroseconds(int64_t us) {
+ return Delta(us);
+ }
// Converts the time offset to a rounded number of seconds.
- int64 ToSeconds() const;
+ inline int64_t ToSeconds() const { return time_offset_ / 1000 / 1000; }
// Converts the time offset to a rounded number of milliseconds.
- int64 ToMilliseconds() const;
+ inline int64_t ToMilliseconds() const { return time_offset_ / 1000; }
// Converts the time offset to a rounded number of microseconds.
- int64 ToMicroseconds() const;
+ inline int64_t ToMicroseconds() const { return time_offset_; }
+
+ inline Delta Add(Delta delta) const WARN_UNUSED_RESULT {
+ return Delta(time_offset_ + delta.time_offset_);
+ }
- Delta Add(const Delta& delta) const;
+ inline Delta Subtract(Delta delta) const WARN_UNUSED_RESULT {
+ return Delta(time_offset_ - delta.time_offset_);
+ }
- Delta Subtract(const Delta& delta) const;
+ inline Delta Multiply(int i) const WARN_UNUSED_RESULT {
+ return Delta(time_offset_ * i);
+ }
- Delta Multiply(int i) const;
- Delta Multiply(double d) const;
+ inline Delta Multiply(double d) const WARN_UNUSED_RESULT {
+ return Delta(time_offset_ * d);
+ }
- // Returns the later delta of time1 and time2.
- static Delta Max(Delta delta1, Delta delta2);
+ // Returns the larger delta of time1 and time2.
+ static inline Delta Max(Delta delta1, Delta delta2) {
+ return delta1 < delta2 ? delta2 : delta1;
+ }
- bool IsZero() const;
+ // Returns the smaller delta of time1 and time2.
+ static inline Delta Min(Delta delta1, Delta delta2) {
+ return delta1 < delta2 ? delta1 : delta2;
+ }
- bool IsInfinite() const;
+ inline bool IsZero() const { return time_offset_ == 0; }
+
+ inline bool IsInfinite() const {
+ return time_offset_ == kQuicInfiniteTimeUs;
+ }
private:
base::TimeDelta delta_;
+ friend inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs);
+ friend inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs);
+
+ // Highest number of microseconds that DateTimeOffset can hold.
+ static const int64_t kQuicInfiniteTimeUs = INT64_C(0x7fffffffffffffff) / 10;
+ explicit QUICTIME_CONSTEXPR Delta(int64_t time_offset)
+ : time_offset_(time_offset) {}
+
+ int64_t time_offset_;
friend class QuicTime;
friend class QuicClock;
};
- explicit QuicTime(base::TimeTicks ticks);
+ explicit QuicTime(base::TimeTicks ticks) : time_(ticks.ToInternalValue()) {}
// Creates a new QuicTime with an internal value of 0. IsInitialized()
// will return false for these times.
- static QuicTime Zero();
+ static QUICTIME_CONSTEXPR QuicTime Zero() { return QuicTime(0); }
// Creates a new QuicTime with an infinite time.
- static QuicTime Infinite();
+ static QUICTIME_CONSTEXPR QuicTime Infinite() {
+ return QuicTime(Delta::kQuicInfiniteTimeUs);
+ }
// Returns the later time of time1 and time2.
- static QuicTime Max(QuicTime time1, QuicTime time2);
+ static inline QuicTime Max(QuicTime time1, QuicTime time2) {
+ return time1 < time2 ? time2 : time1;
+ }
// Produce the internal value to be used when logging. This value
// represents the number of microseconds since some epoch. It may
// be the UNIX epoch on some platforms. On others, it may
// be a CPU ticks based value.
- int64 ToDebuggingValue() const;
+ inline int64_t ToDebuggingValue() const { return time_; }
- bool IsInitialized() const;
+ inline bool IsInitialized() const { return 0 != time_; }
- QuicTime Add(const Delta& delta) const;
+ inline QuicTime Add(Delta delta) const WARN_UNUSED_RESULT {
+ return QuicTime(time_ + delta.time_offset_);
+ }
- QuicTime Subtract(const Delta& delta) const;
+ inline QuicTime Subtract(Delta delta) const WARN_UNUSED_RESULT {
+ return QuicTime(time_ - delta.time_offset_);
+ }
- Delta Subtract(const QuicTime& other) const;
+ inline Delta Subtract(QuicTime other) const WARN_UNUSED_RESULT {
+ return Delta(time_ - other.time_);
+ }
private:
- friend bool operator==(QuicTime lhs, QuicTime rhs);
- friend bool operator<(QuicTime lhs, QuicTime rhs);
-
+ friend inline bool operator==(QuicTime lhs, QuicTime rhs);
+ friend inline bool operator<(QuicTime lhs, QuicTime rhs);
friend class QuicClock;
friend class QuicClockTest;
- base::TimeTicks ticks_;
+ explicit QUICTIME_CONSTEXPR QuicTime(int64_t time) : time_(time) {}
+
+ int64_t time_;
};
-// A QuicWallTime represents an absolute time that is globally consistent. It
-// provides, at most, one second granularity and, in practice, clock-skew means
-// that you shouldn't even depend on that.
+// A QuicWallTime represents an absolute time that is globally consistent. In
+// practice, clock-skew means that comparing values from different machines
+// requires some flexibility in interpretation.
class NET_EXPORT_PRIVATE QuicWallTime {
public:
// FromUNIXSeconds constructs a QuicWallTime from a count of the seconds
// since the UNIX epoch.
- static QuicWallTime FromUNIXSeconds(uint64 seconds);
+ static QUICTIME_CONSTEXPR QuicWallTime FromUNIXSeconds(uint64_t seconds) {
+ return QuicWallTime(seconds * 1000000);
+ }
+
+ static QUICTIME_CONSTEXPR QuicWallTime
+ FromUNIXMicroseconds(uint64_t microseconds) {
+ return QuicWallTime(microseconds);
+ }
// Zero returns a QuicWallTime set to zero. IsZero will return true for this
// value.
- static QuicWallTime Zero();
+ static QUICTIME_CONSTEXPR QuicWallTime Zero() { return QuicWallTime(0); }
- // ToUNIXSeconds converts a QuicWallTime into a count of seconds since the
- // UNIX epoch.
- uint64 ToUNIXSeconds() const;
+ // Returns the number of seconds since the UNIX epoch.
+ uint64_t ToUNIXSeconds() const;
+ // Returns the number of microseconds since the UNIX epoch.
+ uint64_t ToUNIXMicroseconds() const;
bool IsAfter(QuicWallTime other) const;
bool IsBefore(QuicWallTime other) const;
@@ -144,27 +202,28 @@ class NET_EXPORT_PRIVATE QuicWallTime {
// Add returns a new QuicWallTime that represents the time of |this| plus
// |delta|.
- QuicWallTime Add(QuicTime::Delta delta) const;
+ QuicWallTime Add(QuicTime::Delta delta) const WARN_UNUSED_RESULT;
// Subtract returns a new QuicWallTime that represents the time of |this|
// minus |delta|.
- QuicWallTime Subtract(QuicTime::Delta delta) const;
+ QuicWallTime Subtract(QuicTime::Delta delta) const WARN_UNUSED_RESULT;
private:
- explicit QuicWallTime(uint64 seconds);
+ explicit QUICTIME_CONSTEXPR QuicWallTime(uint64_t microseconds)
+ : microseconds_(microseconds) {}
- uint64 seconds_;
+ uint64_t microseconds_;
};
// Non-member relational operators for QuicTime::Delta.
inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return lhs.ToMicroseconds() == rhs.ToMicroseconds();
+ return lhs.time_offset_ == rhs.time_offset_;
}
inline bool operator!=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
return !(lhs == rhs);
}
inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs) {
- return lhs.ToMicroseconds() < rhs.ToMicroseconds();
+ return lhs.time_offset_ < rhs.time_offset_;
}
inline bool operator>(QuicTime::Delta lhs, QuicTime::Delta rhs) {
return rhs < lhs;
@@ -177,13 +236,13 @@ inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
}
// Non-member relational operators for QuicTime.
inline bool operator==(QuicTime lhs, QuicTime rhs) {
- return lhs.ticks_ == rhs.ticks_;
+ return lhs.time_ == rhs.time_;
}
inline bool operator!=(QuicTime lhs, QuicTime rhs) {
return !(lhs == rhs);
}
inline bool operator<(QuicTime lhs, QuicTime rhs) {
- return lhs.ticks_ < rhs.ticks_;
+ return lhs.time_ < rhs.time_;
}
inline bool operator>(QuicTime lhs, QuicTime rhs) {
return rhs < lhs;
diff --git a/chromium/net/quic/quic_time_test.cc b/chromium/net/quic/quic_time_test.cc
index a2e355050c7..602de364583 100644
--- a/chromium/net/quic/quic_time_test.cc
+++ b/chromium/net/quic/quic_time_test.cc
@@ -77,15 +77,14 @@ class QuicTimeTest : public ::testing::Test {
TEST_F(QuicTimeTest, Initialized) {
EXPECT_FALSE(QuicTime::Zero().IsInitialized());
- EXPECT_TRUE(QuicTime::Zero().Add(
- QuicTime::Delta::FromMicroseconds(1)).IsInitialized());
+ EXPECT_TRUE(QuicTime::Zero()
+ .Add(QuicTime::Delta::FromMicroseconds(1))
+ .IsInitialized());
}
TEST_F(QuicTimeTest, Add) {
- QuicTime time_1 = QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(1));
- QuicTime time_2 = QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(2));
+ QuicTime time_1 = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1));
+ QuicTime time_2 = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
QuicTime::Delta diff = time_2.Subtract(time_1);
@@ -95,26 +94,21 @@ TEST_F(QuicTimeTest, Add) {
}
TEST_F(QuicTimeTest, Subtract) {
- QuicTime time_1 = QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(1));
- QuicTime time_2 = QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(2));
+ QuicTime time_1 = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1));
+ QuicTime time_2 = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), time_2.Subtract(time_1));
}
TEST_F(QuicTimeTest, SubtractDelta) {
- QuicTime time = QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(2));
+ QuicTime time = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
EXPECT_EQ(QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1)),
time.Subtract(QuicTime::Delta::FromMilliseconds(1)));
}
TEST_F(QuicTimeTest, Max) {
- QuicTime time_1 = QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(1));
- QuicTime time_2 = QuicTime::Zero().Add(
- QuicTime::Delta::FromMilliseconds(2));
+ QuicTime time_1 = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1));
+ QuicTime time_2 = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
EXPECT_EQ(time_2, QuicTime::Max(time_1, time_2));
}
@@ -138,7 +132,7 @@ TEST_F(QuicTimeTest, MockClock) {
TEST_F(QuicTimeTest, LE) {
const QuicTime zero = QuicTime::Zero();
- const QuicTime one = zero.Add(QuicTime::Delta::FromSeconds(1));
+ const QuicTime one = zero.Add(QuicTime::Delta::FromSeconds(1));
EXPECT_TRUE(zero <= zero);
EXPECT_TRUE(zero <= one);
EXPECT_TRUE(one <= one);
diff --git a/chromium/net/quic/quic_types.cc b/chromium/net/quic/quic_types.cc
index cdfb36dbccb..3b982f1e502 100644
--- a/chromium/net/quic/quic_types.cc
+++ b/chromium/net/quic/quic_types.cc
@@ -8,11 +8,8 @@ using std::ostream;
namespace net {
-QuicConsumedData::QuicConsumedData(size_t bytes_consumed,
- bool fin_consumed)
- : bytes_consumed(bytes_consumed),
- fin_consumed(fin_consumed) {
-}
+QuicConsumedData::QuicConsumedData(size_t bytes_consumed, bool fin_consumed)
+ : bytes_consumed(bytes_consumed), fin_consumed(fin_consumed) {}
ostream& operator<<(ostream& os, const QuicConsumedData& s) {
os << "bytes_consumed: " << s.bytes_consumed
@@ -20,15 +17,9 @@ ostream& operator<<(ostream& os, const QuicConsumedData& s) {
return os;
}
-WriteResult::WriteResult()
- : status(WRITE_STATUS_ERROR),
- bytes_written(0) {
-}
+WriteResult::WriteResult() : status(WRITE_STATUS_ERROR), bytes_written(0) {}
-WriteResult::WriteResult(WriteStatus status,
- int bytes_written_or_error_code)
- : status(status),
- bytes_written(bytes_written_or_error_code) {
-}
+WriteResult::WriteResult(WriteStatus status, int bytes_written_or_error_code)
+ : status(status), bytes_written(bytes_written_or_error_code) {}
} // namespace net
diff --git a/chromium/net/quic/quic_types.h b/chromium/net/quic/quic_types.h
index 01415bc3607..4f24e95f62d 100644
--- a/chromium/net/quic/quic_types.h
+++ b/chromium/net/quic/quic_types.h
@@ -10,6 +10,7 @@
// including quic_protocol.h.
#include <stddef.h>
+
#include <ostream>
#include "net/base/net_export.h"
@@ -24,8 +25,8 @@ struct NET_EXPORT_PRIVATE QuicConsumedData {
// member causes this object to have padding bytes, which causes the
// default gtest object printer to read uninitialize memory. So we need
// to teach gtest how to print this object.
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(
- std::ostream& os, const QuicConsumedData& s);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+ const QuicConsumedData& s);
// How many bytes were consumed.
size_t bytes_consumed;
@@ -60,7 +61,7 @@ struct NET_EXPORT_PRIVATE WriteResult {
WriteStatus status;
union {
int bytes_written; // only valid when status is WRITE_STATUS_OK
- int error_code; // only valid when status is WRITE_STATUS_ERROR
+ int error_code; // only valid when status is WRITE_STATUS_ERROR
};
};
diff --git a/chromium/net/quic/quic_unacked_packet_map.cc b/chromium/net/quic/quic_unacked_packet_map.cc
index 71088ae8869..6beb9bc667f 100644
--- a/chromium/net/quic/quic_unacked_packet_map.cc
+++ b/chromium/net/quic/quic_unacked_packet_map.cc
@@ -5,8 +5,7 @@
#include "net/quic/quic_unacked_packet_map.h"
#include "base/logging.h"
-#include "base/stl_util.h"
-#include "net/quic/quic_ack_notifier_manager.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_connection_stats.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils_chromium.h"
@@ -15,15 +14,13 @@ using std::max;
namespace net {
-QuicUnackedPacketMap::QuicUnackedPacketMap(
- AckNotifierManager* ack_notifier_manager)
+QuicUnackedPacketMap::QuicUnackedPacketMap()
: largest_sent_packet_(0),
largest_observed_(0),
least_unacked_(1),
bytes_in_flight_(0),
pending_crypto_packet_count_(0),
- ack_notifier_manager_(ack_notifier_manager) {
-}
+ track_single_retransmission_(FLAGS_quic_track_single_retransmission) {}
QuicUnackedPacketMap::~QuicUnackedPacketMap() {
QuicPacketNumber index = least_unacked_;
@@ -38,13 +35,13 @@ QuicUnackedPacketMap::~QuicUnackedPacketMap() {
}
}
-void QuicUnackedPacketMap::AddSentPacket(const SerializedPacket& packet,
+void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet,
QuicPacketNumber old_packet_number,
TransmissionType transmission_type,
QuicTime sent_time,
QuicByteCount bytes_sent,
bool set_in_flight) {
- QuicPacketNumber packet_number = packet.packet_number;
+ QuicPacketNumber packet_number = packet->packet_number;
LOG_IF(DFATAL, largest_sent_packet_ >= packet_number) << packet_number;
DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size());
while (least_unacked_ + unacked_packets_.size() < packet_number) {
@@ -52,15 +49,11 @@ void QuicUnackedPacketMap::AddSentPacket(const SerializedPacket& packet,
unacked_packets_.back().is_unackable = true;
}
- TransmissionInfo info(packet.retransmittable_frames,
- packet.packet_number_length, transmission_type,
- sent_time, bytes_sent, packet.is_fec_packet);
- if (old_packet_number == 0) {
- if (packet.retransmittable_frames != nullptr &&
- packet.retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) {
- ++pending_crypto_packet_count_;
- }
- } else {
+ TransmissionInfo info(packet->retransmittable_frames,
+ packet->encryption_level, packet->packet_number_length,
+ transmission_type, sent_time, bytes_sent,
+ packet->is_fec_packet);
+ if (old_packet_number > 0) {
TransferRetransmissionInfo(old_packet_number, packet_number,
transmission_type, &info);
}
@@ -71,6 +64,15 @@ void QuicUnackedPacketMap::AddSentPacket(const SerializedPacket& packet,
info.in_flight = true;
}
unacked_packets_.push_back(info);
+ // Swap the ack listeners after to avoid an extra list allocation.
+ // TODO(ianswett): Could use emplace_back when Chromium can.
+ if (old_packet_number == 0) {
+ if (packet->retransmittable_frames != nullptr &&
+ packet->retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) {
+ ++pending_crypto_packet_count_;
+ }
+ unacked_packets_.back().ack_listeners.swap(packet->listeners);
+ }
}
void QuicUnackedPacketMap::RemoveObsoletePackets() {
@@ -78,7 +80,9 @@ void QuicUnackedPacketMap::RemoveObsoletePackets() {
if (!IsPacketUseless(least_unacked_, unacked_packets_.front())) {
break;
}
- PopLeastUnacked();
+
+ unacked_packets_.pop_front();
+ ++least_unacked_;
}
}
@@ -89,9 +93,9 @@ void QuicUnackedPacketMap::TransferRetransmissionInfo(
TransmissionInfo* info) {
if (old_packet_number < least_unacked_ ||
old_packet_number > largest_sent_packet_) {
- LOG(DFATAL) << "Old TransmissionInfo no longer exists for:"
- << old_packet_number << " least_unacked:" << least_unacked_
- << " largest_sent:" << largest_sent_packet_;
+ QUIC_BUG << "Old TransmissionInfo no longer exists for:"
+ << old_packet_number << " least_unacked:" << least_unacked_
+ << " largest_sent:" << largest_sent_packet_;
return;
}
DCHECK_GE(new_packet_number, least_unacked_ + unacked_packets_.size());
@@ -101,27 +105,34 @@ void QuicUnackedPacketMap::TransferRetransmissionInfo(
&unacked_packets_.at(old_packet_number - least_unacked_);
RetransmittableFrames* frames = transmission_info->retransmittable_frames;
transmission_info->retransmittable_frames = nullptr;
+ for (AckListenerWrapper& wrapper : transmission_info->ack_listeners) {
+ wrapper.ack_listener->OnPacketRetransmitted(wrapper.length);
+ }
+ // Transfer the AckListeners if any are present.
+ info->ack_listeners.swap(transmission_info->ack_listeners);
LOG_IF(DFATAL, frames == nullptr)
<< "Attempt to retransmit packet with no "
<< "retransmittable frames: " << old_packet_number;
// Only keep one transmission older than largest observed, because only the
// most recent is expected to possibly be a spurious retransmission.
- while (transmission_info->all_transmissions != nullptr &&
- transmission_info->all_transmissions->size() > 1 &&
- *(++transmission_info->all_transmissions->begin()) <
- largest_observed_) {
- QuicPacketNumber old_transmission =
- *transmission_info->all_transmissions->begin();
- TransmissionInfo* old_info =
- &unacked_packets_[old_transmission - least_unacked_];
- // Don't remove old packets if they're still in flight.
- if (old_info->in_flight) {
- break;
+ if (!track_single_retransmission_) {
+ while (transmission_info->all_transmissions != nullptr &&
+ transmission_info->all_transmissions->size() > 1 &&
+ *(++transmission_info->all_transmissions->begin()) <
+ largest_observed_) {
+ QuicPacketNumber old_transmission =
+ *transmission_info->all_transmissions->begin();
+ TransmissionInfo* old_info =
+ &unacked_packets_[old_transmission - least_unacked_];
+ // Don't remove old packets if they're still in flight.
+ if (old_info->in_flight) {
+ break;
+ }
+ old_info->all_transmissions->pop_front();
+ // This will cause the packet be removed in RemoveObsoletePackets.
+ old_info->all_transmissions = nullptr;
}
- old_info->all_transmissions->pop_front();
- // This will cause the packet be removed in RemoveObsoletePackets.
- old_info->all_transmissions = nullptr;
}
// Don't link old transmissions to new ones when version or
// encryption changes.
@@ -129,53 +140,24 @@ void QuicUnackedPacketMap::TransferRetransmissionInfo(
transmission_type == ALL_UNACKED_RETRANSMISSION) {
RemoveAckability(transmission_info);
} else {
- if (transmission_info->all_transmissions == nullptr) {
- transmission_info->all_transmissions = new PacketNumberList();
- transmission_info->all_transmissions->push_back(old_packet_number);
+ if (track_single_retransmission_) {
+ transmission_info->retransmission = new_packet_number;
+ } else {
+ if (transmission_info->all_transmissions == nullptr) {
+ transmission_info->all_transmissions = new PacketNumberList();
+ transmission_info->all_transmissions->push_back(old_packet_number);
+ }
+ transmission_info->all_transmissions->push_back(new_packet_number);
}
- transmission_info->all_transmissions->push_back(new_packet_number);
}
info->retransmittable_frames = frames;
- info->all_transmissions = transmission_info->all_transmissions;
+ if (!track_single_retransmission_) {
+ info->all_transmissions = transmission_info->all_transmissions;
+ }
// Proactively remove obsolete packets so the least unacked can be raised.
RemoveObsoletePackets();
}
-void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() {
- while (!unacked_packets_.empty() && least_unacked_ < largest_observed_) {
- // If this packet is in flight, or has retransmittable data, then there is
- // no point in clearing out any further packets, because they would not
- // affect the high water mark.
- TransmissionInfo* info = &unacked_packets_.front();
- if (info->in_flight || info->retransmittable_frames != nullptr) {
- break;
- }
-
- if (info->all_transmissions != nullptr) {
- if (info->all_transmissions->size() < 2) {
- LOG(DFATAL) << "all_transmissions must be nullptr or have multiple "
- << "elements. size:" << info->all_transmissions->size();
- delete info->all_transmissions;
- info->all_transmissions = nullptr;
- } else {
- LOG_IF(DFATAL, info->all_transmissions->front() != least_unacked_)
- << "The first element of all transmissions should be least unacked:"
- << least_unacked_ << " but is:" << info->all_transmissions->front();
- info->all_transmissions->pop_front();
- if (info->all_transmissions->size() == 1) {
- // Set the newer transmission's 'all_transmissions' entry to nullptr.
- QuicPacketNumber new_transmission = info->all_transmissions->front();
- TransmissionInfo* new_info =
- &unacked_packets_.at(new_transmission - least_unacked_);
- delete new_info->all_transmissions;
- new_info->all_transmissions = nullptr;
- }
- }
- }
- PopLeastUnacked();
- }
-}
-
bool QuicUnackedPacketMap::HasRetransmittableFrames(
QuicPacketNumber packet_number) const {
DCHECK_GE(packet_number, least_unacked_);
@@ -185,18 +167,23 @@ bool QuicUnackedPacketMap::HasRetransmittableFrames(
}
void QuicUnackedPacketMap::NackPacket(QuicPacketNumber packet_number,
- QuicPacketCount min_nacks) {
+ uint16_t min_nacks) {
DCHECK_GE(packet_number, least_unacked_);
DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
unacked_packets_[packet_number - least_unacked_].nack_count = max(
min_nacks, unacked_packets_[packet_number - least_unacked_].nack_count);
}
-void QuicUnackedPacketMap::RemoveRetransmittability(
- QuicPacketNumber packet_number) {
- DCHECK_GE(packet_number, least_unacked_);
- DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
- TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_];
+void QuicUnackedPacketMap::RemoveRetransmittability(TransmissionInfo* info) {
+ if (track_single_retransmission_) {
+ while (info->retransmission != 0) {
+ const QuicPacketNumber retransmission = info->retransmission;
+ info->retransmission = 0;
+ info = &unacked_packets_[retransmission - least_unacked_];
+ }
+ MaybeRemoveRetransmittableFrames(info);
+ return;
+ }
PacketNumberList* all_transmissions = info->all_transmissions;
if (all_transmissions == nullptr) {
MaybeRemoveRetransmittableFrames(info);
@@ -213,9 +200,21 @@ void QuicUnackedPacketMap::RemoveRetransmittability(
delete all_transmissions;
}
+void QuicUnackedPacketMap::RemoveRetransmittability(
+ QuicPacketNumber packet_number) {
+ DCHECK_GE(packet_number, least_unacked_);
+ DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+ TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_];
+ RemoveRetransmittability(info);
+}
+
void QuicUnackedPacketMap::RemoveAckability(TransmissionInfo* info) {
DCHECK(info->retransmittable_frames == nullptr);
info->is_unackable = true;
+ if (track_single_retransmission_) {
+ DCHECK_EQ(0u, info->retransmission);
+ return;
+ }
PacketNumberList* all_transmissions = info->all_transmissions;
if (all_transmissions == nullptr) {
return;
@@ -267,7 +266,9 @@ bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
// Packet may have retransmittable frames, or the data may have been
// retransmitted with a new packet number.
return info.retransmittable_frames != nullptr ||
- info.all_transmissions != nullptr;
+ info.all_transmissions != nullptr ||
+ // Allow for an extra 1 RTT before stopping to track old packets.
+ info.retransmission > largest_observed_;
}
bool QuicUnackedPacketMap::IsPacketUseless(QuicPacketNumber packet_number,
@@ -286,10 +287,25 @@ bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const {
unacked_packets_[packet_number - least_unacked_]);
}
-void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
+void QuicUnackedPacketMap::NotifyAndClearListeners(
+ std::list<AckListenerWrapper>* ack_listeners,
+ QuicTime::Delta delta_largest_observed) {
+ for (const AckListenerWrapper& wrapper : *ack_listeners) {
+ wrapper.ack_listener->OnPacketAcked(wrapper.length, delta_largest_observed);
+ }
+ ack_listeners->clear();
+}
+
+void QuicUnackedPacketMap::NotifyAndClearListeners(
+ QuicPacketNumber packet_number,
+ QuicTime::Delta delta_largest_observed) {
DCHECK_GE(packet_number, least_unacked_);
DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_];
+ NotifyAndClearListeners(&info->ack_listeners, delta_largest_observed);
+}
+
+void QuicUnackedPacketMap::RemoveFromInFlight(TransmissionInfo* info) {
if (info->in_flight) {
LOG_IF(DFATAL, bytes_in_flight_ < info->bytes_sent);
bytes_in_flight_ -= info->bytes_sent;
@@ -297,6 +313,13 @@ void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
}
}
+void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
+ DCHECK_GE(packet_number, least_unacked_);
+ DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+ TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_];
+ RemoveFromInFlight(info);
+}
+
void QuicUnackedPacketMap::CancelRetransmissionsForStream(
QuicStreamId stream_id) {
QuicPacketNumber packet_number = least_unacked_;
@@ -336,7 +359,7 @@ QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
}
++it;
}
- LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets.";
+ QUIC_BUG << "GetLastPacketSentTime requires in flight packets.";
return QuicTime::Zero();
}
@@ -353,6 +376,9 @@ size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
}
bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
+ if (bytes_in_flight_ > kDefaultTCPMSS) {
+ return true;
+ }
size_t num_in_flight = 0;
for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
it != unacked_packets_.rend(); ++it) {
@@ -371,8 +397,8 @@ bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
}
bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
- for (UnackedPacketMap::const_reverse_iterator it =
- unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) {
+ for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
+ it != unacked_packets_.rend(); ++it) {
if (it->in_flight && it->retransmittable_frames) {
return true;
}
@@ -384,11 +410,4 @@ QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
return least_unacked_;
}
-void QuicUnackedPacketMap::PopLeastUnacked() {
- ack_notifier_manager_->OnPacketRemoved(least_unacked_);
-
- unacked_packets_.pop_front();
- ++least_unacked_;
-}
-
} // namespace net
diff --git a/chromium/net/quic/quic_unacked_packet_map.h b/chromium/net/quic/quic_unacked_packet_map.h
index 1926d31249d..51cd03e68e0 100644
--- a/chromium/net/quic/quic_unacked_packet_map.h
+++ b/chromium/net/quic/quic_unacked_packet_map.h
@@ -5,8 +5,11 @@
#ifndef NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_
#define NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_
+#include <stddef.h>
+
#include <deque>
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -19,10 +22,7 @@ class AckNotifierManager;
// 3) Track sent time of packets to provide RTT measurements from acks.
class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
public:
- // Initialize an instance of UnackedPacketMap. The AckNotifierManager
- // provided to the constructor will be notified whenever a packet is removed
- // from the map.
- explicit QuicUnackedPacketMap(AckNotifierManager* ack_notifier_manager);
+ QuicUnackedPacketMap();
~QuicUnackedPacketMap();
// Adds |serialized_packet| to the map and marks it as sent at |sent_time|.
@@ -31,7 +31,9 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
// don't arrive, indicating the need for retransmission.
// |old_packet_number| is the packet number of the previous transmission,
// or 0 if there was none.
- void AddSentPacket(const SerializedPacket& serialized_packet,
+ // Any AckNotifierWrappers in |serialized_packet| are swapped from the
+ // serialized packet into the TransmissionInfo.
+ void AddSentPacket(SerializedPacket* serialized_packet,
QuicPacketNumber old_packet_number,
TransmissionType transmission_type,
QuicTime sent_time,
@@ -42,9 +44,22 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
bool IsUnacked(QuicPacketNumber packet_number) const;
// Sets the nack count to the max of the current nack count and |min_nacks|.
- void NackPacket(QuicPacketNumber packet_number, QuicPacketCount min_nacks);
+ void NackPacket(QuicPacketNumber packet_number, uint16_t min_nacks);
+
+ // Notifies all the AckListeners attached to the |info| and
+ // clears them to ensure they're not notified again.
+ void NotifyAndClearListeners(std::list<AckListenerWrapper>* ack_listeners,
+ QuicTime::Delta delta_largest_observed);
+
+ // Notifies all the AckListeners attached to |newest_transmission|.
+ void NotifyAndClearListeners(QuicPacketNumber newest_transmission,
+ QuicTime::Delta delta_largest_observed);
+
+ // Marks |info| as no longer in flight.
+ void RemoveFromInFlight(TransmissionInfo* info);
// Marks |packet_number| as no longer in flight.
+ // TODO(ianswett): Remove this test-only method.
void RemoveFromInFlight(QuicPacketNumber packet_number);
// No longer retransmit data for |stream_id|.
@@ -70,25 +85,26 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
// Returns the largest packet number that has been acked.
QuicPacketNumber largest_observed() const { return largest_observed_; }
- // Returns the sum of bytes from all packets in flight.
- QuicByteCount bytes_in_flight() const {
- return bytes_in_flight_;
+ bool track_single_retransmission() const {
+ return track_single_retransmission_;
}
+ // Returns the sum of bytes from all packets in flight.
+ QuicByteCount bytes_in_flight() const { return bytes_in_flight_; }
+
// Returns the smallest packet number of a serialized packet which has not
// been acked by the peer. If there are no unacked packets, returns 0.
QuicPacketNumber GetLeastUnacked() const;
- // Clears all previous transmissions in order to make room in the ack frame
- // for newly acked packets.
- void ClearAllPreviousRetransmissions();
-
typedef std::deque<TransmissionInfo> UnackedPacketMap;
typedef UnackedPacketMap::const_iterator const_iterator;
+ typedef UnackedPacketMap::iterator iterator;
const_iterator begin() const { return unacked_packets_.begin(); }
const_iterator end() const { return unacked_packets_.end(); }
+ iterator begin() { return unacked_packets_.begin(); }
+ iterator end() { return unacked_packets_.end(); }
// Returns true if there are unacked packets that are in flight.
bool HasInFlightPackets() const;
@@ -113,6 +129,10 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
// Removes any retransmittable frames from this transmission or an associated
// transmission. It removes now useless transmissions, and disconnects any
// other packets from other transmissions.
+ void RemoveRetransmittability(TransmissionInfo* info);
+
+ // Looks up the TransmissionInfo by |packet_number| and calls
+ // RemoveRetransmittability.
void RemoveRetransmittability(QuicPacketNumber packet_number);
// Removes any other retransmissions and marks all transmissions unackable.
@@ -153,9 +173,6 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
bool IsPacketUseless(QuicPacketNumber packet_number,
const TransmissionInfo& info) const;
- // Removes the packet with lowest packet number from the map.
- void PopLeastUnacked();
-
QuicPacketNumber largest_sent_packet_;
QuicPacketNumber largest_observed_;
@@ -175,9 +192,8 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
// Number of retransmittable crypto handshake packets.
size_t pending_crypto_packet_count_;
- // Notifier manager for ACK packets. We notify it every time we abandon a
- // packet.
- AckNotifierManager* ack_notifier_manager_;
+ // Latched copy of gfe2_reloadable_flag_quic_track_single_retransmission.
+ const bool track_single_retransmission_;
DISALLOW_COPY_AND_ASSIGN(QuicUnackedPacketMap);
};
diff --git a/chromium/net/quic/quic_unacked_packet_map_test.cc b/chromium/net/quic/quic_unacked_packet_map_test.cc
index bad705e752f..1adc819e5f6 100644
--- a/chromium/net/quic/quic_unacked_packet_map_test.cc
+++ b/chromium/net/quic/quic_unacked_packet_map_test.cc
@@ -4,7 +4,7 @@
#include "net/quic/quic_unacked_packet_map.h"
-#include "net/quic/quic_ack_notifier_manager.h"
+#include "base/stl_util.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -18,43 +18,41 @@ namespace test {
namespace {
// Default packet length.
-const uint32 kDefaultAckLength = 50;
-const uint32 kDefaultLength = 1000;
+const uint32_t kDefaultAckLength = 50;
+const uint32_t kDefaultLength = 1000;
class QuicUnackedPacketMapTest : public ::testing::Test {
protected:
QuicUnackedPacketMapTest()
- : unacked_packets_(&ack_notifier_manager_),
+ : unacked_packets_(),
now_(QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1000))) {}
- ~QuicUnackedPacketMapTest() override {
- STLDeleteElements(&packets_);
- }
+ ~QuicUnackedPacketMapTest() override { STLDeleteElements(&packets_); }
SerializedPacket CreateRetransmittablePacket(QuicPacketNumber packet_number) {
- packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
- return SerializedPacket(
- packet_number, PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
- new RetransmittableFrames(ENCRYPTION_NONE), false, false);
+ return CreateRetransmittablePacketForStream(packet_number,
+ kHeadersStreamId);
}
SerializedPacket CreateRetransmittablePacketForStream(
QuicPacketNumber packet_number,
QuicStreamId stream_id) {
packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
- RetransmittableFrames* frames = new RetransmittableFrames(ENCRYPTION_NONE);
+ RetransmittableFrames* frames = new RetransmittableFrames();
QuicStreamFrame* frame = new QuicStreamFrame();
frame->stream_id = stream_id;
frames->AddFrame(QuicFrame(frame));
- return SerializedPacket(packet_number, PACKET_1BYTE_PACKET_NUMBER,
- packets_.back(), 0, frames, false, false);
+ return SerializedPacket(kDefaultPathId, packet_number,
+ PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
+ frames, false, false);
}
SerializedPacket CreateNonRetransmittablePacket(
QuicPacketNumber packet_number) {
packets_.push_back(new QuicEncryptedPacket(nullptr, kDefaultLength));
- return SerializedPacket(packet_number, PACKET_1BYTE_PACKET_NUMBER,
- packets_.back(), 0, nullptr, false, false);
+ return SerializedPacket(kDefaultPathId, packet_number,
+ PACKET_1BYTE_PACKET_NUMBER, packets_.back(), 0,
+ nullptr, false, false);
}
void VerifyInFlightPackets(QuicPacketNumber* packets, size_t num_packets) {
@@ -115,16 +113,15 @@ class QuicUnackedPacketMapTest : public ::testing::Test {
}
}
vector<QuicEncryptedPacket*> packets_;
- AckNotifierManager ack_notifier_manager_;
QuicUnackedPacketMap unacked_packets_;
QuicTime now_;
};
TEST_F(QuicUnackedPacketMapTest, RttOnly) {
// Acks are only tracked for RTT measurement purposes.
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(1), 0,
- NOT_RETRANSMISSION, now_, kDefaultAckLength,
- false);
+ SerializedPacket packet(CreateNonRetransmittablePacket(1));
+ unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_,
+ kDefaultAckLength, false);
QuicPacketNumber unacked[] = {1};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -139,9 +136,9 @@ TEST_F(QuicUnackedPacketMapTest, RttOnly) {
TEST_F(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
// Simulate a retransmittable packet being sent and acked.
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(1), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet(CreateRetransmittablePacket(1));
+ unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked[] = {1};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -166,9 +163,9 @@ TEST_F(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
TEST_F(QuicUnackedPacketMapTest, StopRetransmission) {
const QuicStreamId stream_id = 2;
- unacked_packets_.AddSentPacket(
- CreateRetransmittablePacketForStream(1, stream_id), 0, NOT_RETRANSMISSION,
- now_, kDefaultLength, true);
+ SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+ unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked[] = {1};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -184,9 +181,9 @@ TEST_F(QuicUnackedPacketMapTest, StopRetransmission) {
TEST_F(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
const QuicStreamId stream_id = 2;
- unacked_packets_.AddSentPacket(
- CreateRetransmittablePacketForStream(1, stream_id), 0, NOT_RETRANSMISSION,
- now_, kDefaultLength, true);
+ SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+ unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked[] = {1};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -203,12 +200,12 @@ TEST_F(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
TEST_F(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
const QuicStreamId stream_id = 2;
- unacked_packets_.AddSentPacket(
- CreateRetransmittablePacketForStream(1, stream_id), 0, NOT_RETRANSMISSION,
- now_, kDefaultLength, true);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(2), 1,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet1(CreateRetransmittablePacketForStream(1, stream_id));
+ unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet2(CreateNonRetransmittablePacket(2));
+ unacked_packets_.AddSentPacket(&packet2, 1, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked[] = {1, 2};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -225,12 +222,12 @@ TEST_F(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
TEST_F(QuicUnackedPacketMapTest, RetransmittedPacket) {
// Simulate a retransmittable packet being sent, retransmitted, and the first
// transmission being acked.
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(1), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(2), 1,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet1(CreateRetransmittablePacket(1));
+ unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet2(CreateNonRetransmittablePacket(2));
+ unacked_packets_.AddSentPacket(&packet2, 1, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked[] = {1, 2};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -262,12 +259,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmittedPacket) {
TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
// Simulate a retransmittable packet being sent and retransmitted twice.
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(1), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(2), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet1(CreateRetransmittablePacket(1));
+ unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet2(CreateRetransmittablePacket(2));
+ unacked_packets_.AddSentPacket(&packet2, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked[] = {1, 2};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -280,12 +277,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.RemoveFromInFlight(2);
unacked_packets_.RemoveRetransmittability(2);
unacked_packets_.RemoveFromInFlight(1);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(3), 1,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(4), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet3(CreateNonRetransmittablePacket(3));
+ unacked_packets_.AddSentPacket(&packet3, 1, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet4(CreateRetransmittablePacket(4));
+ unacked_packets_.AddSentPacket(&packet4, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked2[] = {1, 3, 4};
VerifyUnackedPackets(unacked2, arraysize(unacked2));
@@ -298,12 +295,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.IncreaseLargestObserved(4);
unacked_packets_.RemoveFromInFlight(4);
unacked_packets_.RemoveRetransmittability(4);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(5), 3,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(6), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet5(CreateNonRetransmittablePacket(5));
+ unacked_packets_.AddSentPacket(&packet5, 3, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet6(CreateRetransmittablePacket(6));
+ unacked_packets_.AddSentPacket(&packet6, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked3[] = {3, 5, 6};
VerifyUnackedPackets(unacked3, arraysize(unacked3));
@@ -316,9 +313,9 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.IncreaseLargestObserved(6);
unacked_packets_.RemoveFromInFlight(6);
unacked_packets_.RemoveRetransmittability(6);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(7), 5,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet7(CreateNonRetransmittablePacket(7));
+ unacked_packets_.AddSentPacket(&packet7, 5, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked4[] = {3, 5, 7};
VerifyUnackedPackets(unacked4, arraysize(unacked4));
@@ -332,23 +329,16 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.RemoveFromInFlight(5);
QuicPacketNumber pending5[] = {7};
VerifyInFlightPackets(pending5, arraysize(pending5));
-
- // Now test ClearAllPreviousTransmissions, leaving one packet.
- unacked_packets_.ClearAllPreviousRetransmissions();
- QuicPacketNumber unacked5[] = {7};
- VerifyUnackedPackets(unacked5, arraysize(unacked5));
- QuicPacketNumber retransmittable5[] = {7};
- VerifyRetransmittablePackets(retransmittable5, arraysize(retransmittable5));
}
TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
// Simulate a retransmittable packet being sent and retransmitted twice.
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(1), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(2), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet1(CreateRetransmittablePacket(1));
+ unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet2(CreateRetransmittablePacket(2));
+ unacked_packets_.AddSentPacket(&packet2, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked[] = {1, 2};
VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -361,9 +351,9 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
unacked_packets_.RemoveFromInFlight(2);
unacked_packets_.RemoveRetransmittability(2);
unacked_packets_.RemoveFromInFlight(1);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(3), 1,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet3(CreateNonRetransmittablePacket(3));
+ unacked_packets_.AddSentPacket(&packet3, 1, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked2[] = {1, 3};
VerifyUnackedPackets(unacked2, arraysize(unacked2));
@@ -373,12 +363,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
VerifyRetransmittablePackets(retransmittable2, arraysize(retransmittable2));
// TLP 3 (formerly 1) as 4, and don't remove 1 from unacked.
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(4), 3,
- TLP_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(5), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet4(CreateNonRetransmittablePacket(4));
+ unacked_packets_.AddSentPacket(&packet4, 3, TLP_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet5(CreateRetransmittablePacket(5));
+ unacked_packets_.AddSentPacket(&packet5, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked3[] = {1, 3, 4, 5};
VerifyUnackedPackets(unacked3, arraysize(unacked3));
@@ -393,9 +383,9 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
unacked_packets_.RemoveRetransmittability(5);
unacked_packets_.RemoveFromInFlight(3);
unacked_packets_.RemoveFromInFlight(4);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(6), 4,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet6(CreateNonRetransmittablePacket(6));
+ unacked_packets_.AddSentPacket(&packet6, 4, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
QuicPacketNumber unacked4[] = {4, 6};
VerifyUnackedPackets(unacked4, arraysize(unacked4));
@@ -408,15 +398,15 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
TEST_F(QuicUnackedPacketMapTest, SendWithGap) {
// Simulate a retransmittable packet being sent, retransmitted, and the first
// transmission being acked.
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(1), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateRetransmittablePacket(3), 0,
- NOT_RETRANSMISSION, now_, kDefaultLength,
- true);
- unacked_packets_.AddSentPacket(CreateNonRetransmittablePacket(5), 3,
- LOSS_RETRANSMISSION, now_, kDefaultLength,
- true);
+ SerializedPacket packet1(CreateRetransmittablePacket(1));
+ unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet3(CreateRetransmittablePacket(3));
+ unacked_packets_.AddSentPacket(&packet3, 0, NOT_RETRANSMISSION, now_,
+ kDefaultLength, true);
+ SerializedPacket packet5(CreateNonRetransmittablePacket(5));
+ unacked_packets_.AddSentPacket(&packet5, 3, LOSS_RETRANSMISSION, now_,
+ kDefaultLength, true);
EXPECT_EQ(1u, unacked_packets_.GetLeastUnacked());
EXPECT_TRUE(unacked_packets_.IsUnacked(1));
diff --git a/chromium/net/quic/quic_utils.cc b/chromium/net/quic/quic_utils.cc
index 32f8c09ce4c..8781afbdcf0 100644
--- a/chromium/net/quic/quic_utils.cc
+++ b/chromium/net/quic/quic_utils.cc
@@ -10,27 +10,82 @@
#include <algorithm>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/adapters.h"
#include "base/logging.h"
-#include "base/strings/stringprintf.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "base/strings/stringprintf.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/quic_write_blocked_list.h"
using base::StringPiece;
using std::string;
namespace net {
+namespace {
+
+// We know that >= GCC 4.8 and Clang have a __uint128_t intrinsic. Other
+// compilers don't necessarily, notably MSVC.
+#if defined(__x86_64__) && \
+ ((defined(__GNUC__) && \
+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
+ defined(__clang__))
+#define QUIC_UTIL_HAS_UINT128 1
+#endif
+
+#ifdef QUIC_UTIL_HAS_UINT128
+uint128 IncrementalHashFast(uint128 uhash, const char* data, size_t len) {
+ // This code ends up faster than the naive implementation for 2 reasons:
+ // 1. uint128 from base/int128.h 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
+ // nicely in the instruction queue of many Intel CPUs.
+ // 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);
+ const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
+ for (size_t i = 0; i < len; ++i) {
+ xhash = (xhash ^ octets[i]) * kPrime;
+ }
+ return uint128(static_cast<uint64_t>(xhash >> 64),
+ static_cast<uint64_t>(xhash & UINT64_C(0xFFFFFFFFFFFFFFFF)));
+}
+#endif
+
+uint128 IncrementalHashSlow(uint128 hash, const char* data, size_t len) {
+ // kPrime = 309485009821345068724781371
+ static const uint128 kPrime(16777216, 315);
+ const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
+ for (size_t i = 0; i < len; ++i) {
+ hash = hash ^ uint128(0, octets[i]);
+ hash = hash * kPrime;
+ }
+ return hash;
+}
+
+uint128 IncrementalHash(uint128 hash, const char* data, size_t len) {
+#ifdef QUIC_UTIL_HAS_UINT128
+ return FLAGS_quic_utils_use_fast_incremental_hash
+ ? IncrementalHashFast(hash, data, len)
+ : IncrementalHashSlow(hash, data, len);
+#else
+ return IncrementalHashSlow(hash, data, len);
+#endif
+}
+
+} // namespace
// static
-uint64 QuicUtils::FNV1a_64_Hash(const char* data, int len) {
- static const uint64 kOffset = UINT64_C(14695981039346656037);
- static const uint64 kPrime = UINT64_C(1099511628211);
+uint64_t QuicUtils::FNV1a_64_Hash(const char* data, int len) {
+ static const uint64_t kOffset = UINT64_C(14695981039346656037);
+ static const uint64_t kPrime = UINT64_C(1099511628211);
- const uint8* octets = reinterpret_cast<const uint8*>(data);
+ const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
- uint64 hash = kOffset;
+ uint64_t hash = kOffset;
for (int i = 0; i < len; ++i) {
hash = hash ^ octets[i];
@@ -52,7 +107,7 @@ uint128 QuicUtils::FNV1a_128_Hash_Two(const char* data1,
int len2) {
// The two constants are defined as part of the hash algorithm.
// see http://www.isthe.com/chongo/tech/comp/fnv/
- // 144066263297769815596495629667062367629
+ // kOffset = 144066263297769815596495629667062367629
const uint128 kOffset(UINT64_C(7809847782465536322),
UINT64_C(7113472399480571277));
@@ -64,18 +119,6 @@ uint128 QuicUtils::FNV1a_128_Hash_Two(const char* data1,
}
// static
-uint128 QuicUtils::IncrementalHash(uint128 hash, const char* data, size_t len) {
- // 309485009821345068724781371
- const uint128 kPrime(16777216, 315);
- const uint8* octets = reinterpret_cast<const uint8*>(data);
- for (size_t i = 0; i < len; ++i) {
- hash = hash ^ uint128(0, octets[i]);
- hash = hash * kPrime;
- }
- return hash;
-}
-
-// static
bool QuicUtils::FindMutualTag(const QuicTagVector& our_tags_vector,
const QuicTag* their_tags,
size_t num_their_tags,
@@ -123,17 +166,17 @@ bool QuicUtils::FindMutualTag(const QuicTagVector& our_tags_vector,
}
// static
-void QuicUtils::SerializeUint128Short(uint128 v, uint8* out) {
- const uint64 lo = Uint128Low64(v);
- const uint64 hi = Uint128High64(v);
+void QuicUtils::SerializeUint128Short(uint128 v, uint8_t* out) {
+ const uint64_t lo = Uint128Low64(v);
+ const uint64_t hi = Uint128High64(v);
// This assumes that the system is little-endian.
memcpy(out, &lo, sizeof(lo));
memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2);
}
#define RETURN_STRING_LITERAL(x) \
-case x: \
-return #x;
+ case x: \
+ return #x;
// static
const char* QuicUtils::StreamErrorToString(QuicRstStreamErrorCode error) {
@@ -146,6 +189,7 @@ const char* QuicUtils::StreamErrorToString(QuicRstStreamErrorCode error) {
RETURN_STRING_LITERAL(QUIC_STREAM_PEER_GOING_AWAY);
RETURN_STRING_LITERAL(QUIC_STREAM_CANCELLED);
RETURN_STRING_LITERAL(QUIC_RST_ACKNOWLEDGEMENT);
+ RETURN_STRING_LITERAL(QUIC_REFUSED_STREAM);
RETURN_STRING_LITERAL(QUIC_STREAM_LAST_ERROR);
}
// Return a default value so that we return this when |error| doesn't match
@@ -178,7 +222,6 @@ const char* QuicUtils::ErrorToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_DECRYPTION_FAILURE);
RETURN_STRING_LITERAL(QUIC_ENCRYPTION_FAILURE);
RETURN_STRING_LITERAL(QUIC_PACKET_TOO_LARGE);
- RETURN_STRING_LITERAL(QUIC_PACKET_FOR_NONEXISTENT_STREAM);
RETURN_STRING_LITERAL(QUIC_PEER_GOING_AWAY);
RETURN_STRING_LITERAL(QUIC_HANDSHAKE_FAILED);
RETURN_STRING_LITERAL(QUIC_CRYPTO_TAGS_OUT_OF_ORDER);
@@ -198,7 +241,6 @@ const char* QuicUtils::ErrorToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_ID);
RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY);
RETURN_STRING_LITERAL(QUIC_TOO_MANY_OPEN_STREAMS);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_UNFINISHED_STREAMS);
RETURN_STRING_LITERAL(QUIC_PUBLIC_RESET);
RETURN_STRING_LITERAL(QUIC_INVALID_VERSION);
RETURN_STRING_LITERAL(QUIC_INVALID_HEADER_ID);
@@ -231,6 +273,12 @@ const char* QuicUtils::ErrorToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_PUBLIC_RESETS_POST_HANDSHAKE);
RETURN_STRING_LITERAL(QUIC_TIMEOUTS_WITH_OPEN_STREAMS);
RETURN_STRING_LITERAL(QUIC_FAILED_TO_SERIALIZE_PACKET);
+ RETURN_STRING_LITERAL(QUIC_TOO_MANY_AVAILABLE_STREAMS);
+ RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_FEC_DATA);
+ RETURN_STRING_LITERAL(QUIC_IP_ADDRESS_CHANGED);
+ RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
+ RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
+ RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
// Intentionally have no default case, so we'll break the build
// if we add errors and don't put them here.
@@ -300,7 +348,7 @@ QuicTagVector QuicUtils::ParseQuicConnectionOptions(
for (const base::StringPiece& token :
base::SplitStringPiece(connection_options, ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL)) {
- uint32 option = 0;
+ uint32_t option = 0;
for (char token_char : base::Reversed(token)) {
option <<= 8;
option |= static_cast<unsigned char>(token_char);
@@ -313,10 +361,10 @@ QuicTagVector QuicUtils::ParseQuicConnectionOptions(
// static
string QuicUtils::StringToHexASCIIDump(StringPiece in_buffer) {
int offset = 0;
- const int kBytesPerLine = 16; // Max bytes dumped per line
+ const int kBytesPerLine = 16; // Max bytes dumped per line
const char* buf = in_buffer.data();
int bytes_remaining = in_buffer.size();
- string s; // our output
+ string s; // our output
const char* p = buf;
while (bytes_remaining > 0) {
const int line_bytes = std::min(bytes_remaining, kBytesPerLine);
@@ -325,13 +373,14 @@ string QuicUtils::StringToHexASCIIDump(StringPiece in_buffer) {
if (i < line_bytes) {
base::StringAppendF(&s, "%02x", static_cast<unsigned char>(p[i]));
} else {
- s += " "; // two-space filler instead of two-space hex digits
+ s += " "; // two-space filler instead of two-space hex digits
}
- if (i % 2) s += ' ';
+ if (i % 2)
+ s += ' ';
}
s += ' ';
for (int i = 0; i < line_bytes; ++i) { // Do the ASCII dump
- s+= (p[i] > 32 && p[i] < 127) ? p[i] : '.';
+ s += (p[i] > 32 && p[i] < 127) ? p[i] : '.';
}
bytes_remaining -= line_bytes;
@@ -342,9 +391,4 @@ string QuicUtils::StringToHexASCIIDump(StringPiece in_buffer) {
return s;
}
-// static
-QuicPriority QuicUtils::HighestPriority() {
- return QuicWriteBlockedList::kHighestPriority;
-}
-
} // namespace net
diff --git a/chromium/net/quic/quic_utils.h b/chromium/net/quic/quic_utils.h
index fb379e66e71..35b675c63ec 100644
--- a/chromium/net/quic/quic_utils.h
+++ b/chromium/net/quic/quic_utils.h
@@ -7,8 +7,12 @@
#ifndef NET_QUIC_QUIC_UTILS_H_
#define NET_QUIC_QUIC_UTILS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/int128.h"
#include "net/base/net_export.h"
@@ -25,7 +29,7 @@ class NET_EXPORT_PRIVATE QuicUtils {
// Returns the 64 bit FNV1a hash of the data. See
// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static uint64 FNV1a_64_Hash(const char* data, int len);
+ static uint64_t FNV1a_64_Hash(const char* data, int len);
// returns the 128 bit FNV1a hash of the data. See
// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
@@ -38,10 +42,6 @@ class NET_EXPORT_PRIVATE QuicUtils {
const char* data2,
int len2);
- // returns the 128 bit FNV1a hash of the |data|, starting with the
- // previous hash.
- static uint128 IncrementalHash(uint128 hash, const char* data, size_t len);
-
// FindMutualTag sets |out_result| to the first tag in the priority list that
// is also in the other list and returns true. If there is no intersection it
// returns false.
@@ -59,7 +59,7 @@ class NET_EXPORT_PRIVATE QuicUtils {
// SerializeUint128 writes the first 96 bits of |v| in little-endian form
// to |out|.
- static void SerializeUint128Short(uint128 v, uint8* out);
+ static void SerializeUint128Short(uint128 v, uint8_t* out);
// Returns the name of the QuicRstStreamErrorCode as a char*
static const char* StreamErrorToString(QuicRstStreamErrorCode error);
@@ -95,8 +95,6 @@ class NET_EXPORT_PRIVATE QuicUtils {
return reinterpret_cast<char*>(data);
}
- static QuicPriority HighestPriority();
-
private:
DISALLOW_COPY_AND_ASSIGN(QuicUtils);
};
diff --git a/chromium/net/quic/quic_utils_chromium.h b/chromium/net/quic/quic_utils_chromium.h
index 0229d1d0400..daa34dd2a1e 100644
--- a/chromium/net/quic/quic_utils_chromium.h
+++ b/chromium/net/quic/quic_utils_chromium.h
@@ -7,7 +7,6 @@
#ifndef NET_QUIC_QUIC_UTILS_CHROMIUM_H_
#define NET_QUIC_QUIC_UTILS_CHROMIUM_H_
-#include "base/basictypes.h"
#include "base/logging.h"
namespace net {
@@ -32,9 +31,9 @@ namespace net {
// This version assumes the key is printable, and includes it in the fatal log
// message.
template <class Collection>
-const typename Collection::value_type::second_type&
-FindOrDie(const Collection& collection,
- const typename Collection::value_type::first_type& key) {
+const typename Collection::value_type::second_type& FindOrDie(
+ const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
CHECK(it != collection.end()) << "Map key not found: " << key;
return it->second;
@@ -42,9 +41,9 @@ FindOrDie(const Collection& collection,
// Same as above, but returns a non-const reference.
template <class Collection>
-typename Collection::value_type::second_type&
-FindOrDie(Collection& collection, // NOLINT
- const typename Collection::value_type::first_type& key) {
+typename Collection::value_type::second_type& FindOrDie(
+ Collection& collection, // NOLINT
+ const typename Collection::value_type::first_type& key) {
typename Collection::iterator it = collection.find(key);
CHECK(it != collection.end()) << "Map key not found: " << key;
return it->second;
@@ -53,9 +52,9 @@ FindOrDie(Collection& collection, // NOLINT
// Returns a pointer to the const value associated with the given key if it
// exists, or NULL otherwise.
template <class Collection>
-const typename Collection::value_type::second_type*
-FindOrNull(const Collection& collection,
- const typename Collection::value_type::first_type& key) {
+const typename Collection::value_type::second_type* FindOrNull(
+ const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return 0;
@@ -65,9 +64,9 @@ FindOrNull(const Collection& collection,
// Same as above but returns a pointer to the non-const value.
template <class Collection>
-typename Collection::value_type::second_type*
-FindOrNull(Collection& collection, // NOLINT
- const typename Collection::value_type::first_type& key) {
+typename Collection::value_type::second_type* FindOrNull(
+ Collection& collection, // NOLINT
+ const typename Collection::value_type::first_type& key) {
typename Collection::iterator it = collection.find(key);
if (it == collection.end()) {
return 0;
diff --git a/chromium/net/quic/quic_utils_test.cc b/chromium/net/quic/quic_utils_test.cc
index 1a3a1e58308..2c4aacb37d7 100644
--- a/chromium/net/quic/quic_utils_test.cc
+++ b/chromium/net/quic/quic_utils_test.cc
@@ -5,6 +5,7 @@
#include "net/quic/quic_utils.h"
#include "net/quic/crypto/crypto_protocol.h"
+#include "net/quic/quic_flags.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::StringPiece;
@@ -16,18 +17,15 @@ namespace {
// A test string and a hex+ASCII dump of the same string.
const unsigned char kString[] = {
- 0x00, 0x90, 0x69, 0xbd, 0x54, 0x00, 0x00, 0x0d,
- 0x61, 0x0f, 0x01, 0x89, 0x08, 0x00, 0x45, 0x00,
- 0x00, 0x1c, 0xfb, 0x98, 0x40, 0x00, 0x40, 0x01,
- 0x7e, 0x18, 0xd8, 0xef, 0x23, 0x01, 0x45, 0x5d,
- 0x7f, 0xe2, 0x08, 0x00, 0x6b, 0xcb, 0x0b, 0xc6,
- 0x80, 0x6e
-};
+ 0x00, 0x90, 0x69, 0xbd, 0x54, 0x00, 0x00, 0x0d, 0x61, 0x0f, 0x01,
+ 0x89, 0x08, 0x00, 0x45, 0x00, 0x00, 0x1c, 0xfb, 0x98, 0x40, 0x00,
+ 0x40, 0x01, 0x7e, 0x18, 0xd8, 0xef, 0x23, 0x01, 0x45, 0x5d, 0x7f,
+ 0xe2, 0x08, 0x00, 0x6b, 0xcb, 0x0b, 0xc6, 0x80, 0x6e};
const unsigned char kHexDump[] =
-"0x0000: 0090 69bd 5400 000d 610f 0189 0800 4500 ..i.T...a.....E.\n"
-"0x0010: 001c fb98 4000 4001 7e18 d8ef 2301 455d ....@.@.~...#.E]\n"
-"0x0020: 7fe2 0800 6bcb 0bc6 806e ....k....n\n";
+ "0x0000: 0090 69bd 5400 000d 610f 0189 0800 4500 ..i.T...a.....E.\n"
+ "0x0010: 001c fb98 4000 4001 7e18 d8ef 2301 455d ....@.@.~...#.E]\n"
+ "0x0020: 7fe2 0800 6bcb 0bc6 806e ....k....n\n";
TEST(QuicUtilsTest, StreamErrorToString) {
EXPECT_STREQ("QUIC_BAD_APPLICATION_PAYLOAD",
@@ -35,8 +33,7 @@ TEST(QuicUtilsTest, StreamErrorToString) {
}
TEST(QuicUtilsTest, ErrorToString) {
- EXPECT_STREQ("QUIC_NO_ERROR",
- QuicUtils::ErrorToString(QUIC_NO_ERROR));
+ EXPECT_STREQ("QUIC_NO_ERROR", QuicUtils::ErrorToString(QUIC_NO_ERROR));
}
TEST(QuicUtilsTest, StringToHexASCIIDumpArgTypes) {
@@ -45,12 +42,22 @@ TEST(QuicUtilsTest, StringToHexASCIIDumpArgTypes) {
const string input;
const string expected;
} tests[] = {
- { "", "", },
- { "A", "0x0000: 41 A\n", },
- { "AB", "0x0000: 4142 AB\n", },
- { "ABC", "0x0000: 4142 43 ABC\n", },
- { "original",
- "0x0000: 6f72 6967 696e 616c original\n", },
+ {
+ "", "",
+ },
+ {
+ "A", "0x0000: 41 A\n",
+ },
+ {
+ "AB", "0x0000: 4142 AB\n",
+ },
+ {
+ "ABC", "0x0000: 4142 43 ABC\n",
+ },
+ {
+ "original",
+ "0x0000: 6f72 6967 696e 616c original\n",
+ },
};
for (size_t i = 0; i < arraysize(tests); ++i) {
@@ -65,19 +72,15 @@ TEST(QuicUtilsTest, StringToHexASCIIDumpArgTypes) {
TEST(QuicUtilsTest, StringToHexASCIIDumpSuccess) {
EXPECT_EQ(string(reinterpret_cast<const char*>(kHexDump)),
- QuicUtils::StringToHexASCIIDump(
- string(reinterpret_cast<const char*>(kString), sizeof(kString))));
+ QuicUtils::StringToHexASCIIDump(string(
+ reinterpret_cast<const char*>(kString), sizeof(kString))));
}
TEST(QuicUtilsTest, TagToString) {
- EXPECT_EQ("SCFG",
- QuicUtils::TagToString(kSCFG));
- EXPECT_EQ("SNO ",
- QuicUtils::TagToString(kServerNonceTag));
- EXPECT_EQ("CRT ",
- QuicUtils::TagToString(kCertificateTag));
- EXPECT_EQ("CHLO",
- QuicUtils::TagToString(MakeQuicTag('C', 'H', 'L', 'O')));
+ EXPECT_EQ("SCFG", QuicUtils::TagToString(kSCFG));
+ EXPECT_EQ("SNO ", QuicUtils::TagToString(kServerNonceTag));
+ EXPECT_EQ("CRT ", QuicUtils::TagToString(kCertificateTag));
+ EXPECT_EQ("CHLO", QuicUtils::TagToString(MakeQuicTag('C', 'H', 'L', 'O')));
// A tag that contains a non-printing character will be printed as a decimal
// number.
EXPECT_EQ("525092931",
@@ -97,6 +100,44 @@ TEST(QuicUtilsTest, ParseQuicConnectionOptions) {
EXPECT_EQ(expected_options, parsed_options);
}
+uint128 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 =
+ uint128(UINT64_C(7809847782465536322), UINT64_C(7113472399480571277));
+ // kPrime = 309485009821345068724781371
+ const uint128 kPrime(16777216, 315);
+ const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
+ for (size_t i = 0; i < len; ++i) {
+ hash = hash ^ uint128(0, octets[i]);
+ hash = hash * kPrime;
+ }
+ return hash;
+}
+
+TEST(QuicUtilsHashTest, ReferenceTestSlow) {
+ FLAGS_quic_utils_use_fast_incremental_hash = false;
+ std::vector<uint8_t> data(32);
+ for (size_t i = 0; i < data.size(); ++i) {
+ data[i] = i % 255;
+ }
+ EXPECT_EQ(IncrementalHashReference(data.data(), data.size()),
+ QuicUtils::FNV1a_128_Hash(
+ reinterpret_cast<const char*>(data.data()), data.size()));
+}
+
+TEST(QuicUtilsHashTest, ReferenceTestFast) {
+ FLAGS_quic_utils_use_fast_incremental_hash = true;
+ std::vector<uint8_t> data(32);
+ for (size_t i = 0; i < data.size(); ++i) {
+ data[i] = i % 255;
+ }
+ EXPECT_EQ(IncrementalHashReference(data.data(), data.size()),
+ QuicUtils::FNV1a_128_Hash(
+ reinterpret_cast<const char*>(data.data()), data.size()));
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_write_blocked_list.cc b/chromium/net/quic/quic_write_blocked_list.cc
index e763d172f26..ebe2ebfeeca 100644
--- a/chromium/net/quic/quic_write_blocked_list.cc
+++ b/chromium/net/quic/quic_write_blocked_list.cc
@@ -6,13 +6,12 @@
namespace net {
-const QuicPriority QuicWriteBlockedList::kHighestPriority =
- static_cast<QuicPriority>(net::kHighestPriority);
-const QuicPriority QuicWriteBlockedList::kLowestPriority =
- static_cast<QuicPriority>(net::kLowestPriority);
-
QuicWriteBlockedList::QuicWriteBlockedList()
- : crypto_stream_blocked_(false), headers_stream_blocked_(false) {
+ : last_priority_popped_(0),
+ crypto_stream_blocked_(false),
+ headers_stream_blocked_(false) {
+ memset(batch_write_stream_id_, 0, sizeof(batch_write_stream_id_));
+ memset(bytes_left_for_batch_write_, 0, sizeof(bytes_left_for_batch_write_));
}
QuicWriteBlockedList::~QuicWriteBlockedList() {}
diff --git a/chromium/net/quic/quic_write_blocked_list.h b/chromium/net/quic/quic_write_blocked_list.h
index 3c08badd616..ad511877a66 100644
--- a/chromium/net/quic/quic_write_blocked_list.h
+++ b/chromium/net/quic/quic_write_blocked_list.h
@@ -5,10 +5,16 @@
#ifndef NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
#define NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <set>
+#include "base/macros.h"
#include "net/base/net_export.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"
+#include "net/spdy/priority_write_scheduler.h"
#include "net/spdy/write_blocked_list.h"
namespace net {
@@ -19,16 +25,18 @@ namespace net {
class NET_EXPORT_PRIVATE QuicWriteBlockedList {
private:
typedef WriteBlockedList<QuicStreamId> QuicWriteBlockedListBase;
+ typedef PriorityWriteScheduler<QuicStreamId> QuicPriorityWriteScheduler;
public:
- static const QuicPriority kHighestPriority;
- static const QuicPriority kLowestPriority;
-
QuicWriteBlockedList();
~QuicWriteBlockedList();
bool HasWriteBlockedDataStreams() const {
- return base_write_blocked_list_.HasWriteBlockedStreams();
+ if (use_new_blocked_list_) {
+ return priority_write_scheduler_.HasReadyStreams();
+ } else {
+ return base_write_blocked_list_.HasWriteBlockedStreams();
+ }
}
bool HasWriteBlockedCryptoOrHeadersStream() const {
@@ -36,7 +44,9 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
}
size_t NumBlockedStreams() const {
- size_t num_blocked = base_write_blocked_list_.NumBlockedStreams();
+ size_t num_blocked = use_new_blocked_list_
+ ? priority_write_scheduler_.NumReadyStreams()
+ : base_write_blocked_list_.NumBlockedStreams();
if (crypto_stream_blocked_) {
++num_blocked;
}
@@ -47,6 +57,8 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
return num_blocked;
}
+ // 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;
@@ -58,29 +70,106 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
return kHeadersStreamId;
}
- SpdyPriority priority =
- base_write_blocked_list_.GetHighestPriorityWriteBlockedList();
- QuicStreamId id = base_write_blocked_list_.PopFront(priority);
+ SpdyPriority priority;
+ QuicStreamId id;
+
+ if (use_new_blocked_list_) {
+ id = priority_write_scheduler_.PopNextReadyStream();
+ priority = priority_write_scheduler_.GetStreamPriority(id);
+ } else {
+ priority = base_write_blocked_list_.GetHighestPriorityWriteBlockedList();
+ id = base_write_blocked_list_.PopFront(priority);
+ }
+
+ size_t num_blocked_for_priority =
+ use_new_blocked_list_
+ ? priority_write_scheduler_.NumReadyStreams(priority)
+ : base_write_blocked_list_.NumBlockedStreams(priority);
+
+ if (num_blocked_for_priority == 0) {
+ // If no streams are blocked, don't bother latching. This stream will be
+ // the first popped for its priority anyway.
+ batch_write_stream_id_[priority] = 0;
+ last_priority_popped_ = priority;
+ } else if (batch_write_stream_id_[priority] != id) {
+ // If newly latching this batch write stream, let it write 16k.
+ batch_write_stream_id_[priority] = id;
+ bytes_left_for_batch_write_[priority] = 16000;
+ last_priority_popped_ = priority;
+ }
+
return id;
}
- void PushBack(QuicStreamId stream_id, QuicPriority priority) {
+ void RegisterStream(QuicStreamId stream_id, SpdyPriority priority) {
+ if (use_new_blocked_list_) {
+ priority_write_scheduler_.RegisterStream(stream_id, priority);
+ }
+ }
+
+ void UnregisterStream(QuicStreamId stream_id) {
+ if (use_new_blocked_list_) {
+ priority_write_scheduler_.UnregisterStream(stream_id);
+ }
+ }
+
+ void UpdateStreamPriority(QuicStreamId stream_id, SpdyPriority new_priority) {
+ if (use_new_blocked_list_) {
+ priority_write_scheduler_.UpdateStreamPriority(stream_id, new_priority);
+ }
+ }
+
+ void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes) {
+ if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
+ // If this was the last data stream popped by PopFront, update the
+ // bytes remaining in its batch write.
+ bytes_left_for_batch_write_[last_priority_popped_] -=
+ static_cast<int32_t>(bytes);
+ } else {
+ // If a batch write stream was set, it should only be preempted by the
+ // crypto or headers streams. Any higher priority data stream would
+ // *become* the new batch write stream.
+ if (FLAGS_quic_respect_send_alarm2 && FLAGS_quic_batch_writes) {
+ DCHECK(stream_id == kCryptoStreamId || stream_id == kHeadersStreamId ||
+ batch_write_stream_id_[last_priority_popped_] == 0 ||
+ bytes == 0);
+ }
+ }
+ }
+
+ // Pushes a stream to the back of the list for this priority level
+ // *unless* it is latched for doing batched writes in which case it goes to
+ // the front of the list for this priority level.
+ // Headers and crypto streams are special cased to always resume first.
+ void AddStream(QuicStreamId stream_id, SpdyPriority priority) {
if (stream_id == kCryptoStreamId) {
- DCHECK_EQ(kHighestPriority, priority);
+ DCHECK_EQ(kV3HighestPriority, priority);
// TODO(avd) Add DCHECK(!crypto_stream_blocked_)
crypto_stream_blocked_ = true;
return;
}
if (stream_id == kHeadersStreamId) {
- DCHECK_EQ(kHighestPriority, priority);
+ DCHECK_EQ(kV3HighestPriority, priority);
// TODO(avd) Add DCHECK(!headers_stream_blocked_);
headers_stream_blocked_ = true;
return;
}
-
- base_write_blocked_list_.PushBack(
- stream_id, static_cast<SpdyPriority>(priority));
+ if (use_new_blocked_list_) {
+ bool push_front =
+ FLAGS_quic_batch_writes &&
+ stream_id == batch_write_stream_id_[last_priority_popped_] &&
+ bytes_left_for_batch_write_[last_priority_popped_] > 0;
+ priority_write_scheduler_.MarkStreamReady(stream_id, push_front);
+ } else if (FLAGS_quic_batch_writes &&
+ stream_id == batch_write_stream_id_[last_priority_popped_] &&
+ bytes_left_for_batch_write_[last_priority_popped_] > 0) {
+ // If the batch write stream has more data to write, push it to the front
+ // for its priority level.
+ base_write_blocked_list_.PushFront(stream_id, priority);
+ } else {
+ base_write_blocked_list_.PushBack(stream_id, priority);
+ }
return;
}
@@ -89,6 +178,21 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
private:
QuicWriteBlockedListBase base_write_blocked_list_;
+ QuicPriorityWriteScheduler priority_write_scheduler_;
+ bool use_new_blocked_list_ = FLAGS_quic_new_blocked_list;
+
+ // If performing batch writes, this will be the stream ID of the stream doing
+ // batch writes for this priority level. We will allow this stream to write
+ // until it has written kBatchWriteSize bytes, it has no more data to write,
+ // or a higher priority stream preempts.
+ QuicStreamId batch_write_stream_id_[kV3LowestPriority + 1];
+ // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
+ // priority. This is decremented with each write the stream does until it is
+ // done with its batch write.
+ int32_t bytes_left_for_batch_write_[kV3LowestPriority + 1];
+ // Tracks the last priority popped for UpdateBytesForStream.
+ SpdyPriority last_priority_popped_;
+
bool crypto_stream_blocked_;
bool headers_stream_blocked_;
@@ -97,5 +201,4 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
} // namespace net
-
#endif // NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
diff --git a/chromium/net/quic/quic_write_blocked_list_test.cc b/chromium/net/quic/quic_write_blocked_list_test.cc
index 0633f633636..bb5ff23b007 100644
--- a/chromium/net/quic/quic_write_blocked_list_test.cc
+++ b/chromium/net/quic/quic_write_blocked_list_test.cc
@@ -7,6 +7,9 @@
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+using net::kV3LowestPriority;
+using net::kV3HighestPriority;
+
namespace net {
namespace test {
namespace {
@@ -16,16 +19,17 @@ TEST(QuicWriteBlockedListTest, PriorityOrder) {
// Mark streams blocked in roughly reverse priority order, and
// verify that streams are sorted.
- write_blocked_list.PushBack(40,
- QuicWriteBlockedList::kLowestPriority);
- write_blocked_list.PushBack(23,
- QuicWriteBlockedList::kHighestPriority);
- write_blocked_list.PushBack(17,
- QuicWriteBlockedList::kHighestPriority);
- write_blocked_list.PushBack(kHeadersStreamId,
- QuicWriteBlockedList::kHighestPriority);
- write_blocked_list.PushBack(kCryptoStreamId,
- QuicWriteBlockedList::kHighestPriority);
+ 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.AddStream(40, kV3LowestPriority);
+ write_blocked_list.AddStream(23, kV3HighestPriority);
+ write_blocked_list.AddStream(17, kV3HighestPriority);
+ write_blocked_list.AddStream(kHeadersStreamId, kV3HighestPriority);
+ write_blocked_list.AddStream(kCryptoStreamId, kV3HighestPriority);
EXPECT_EQ(5u, write_blocked_list.NumBlockedStreams());
EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
@@ -47,8 +51,8 @@ TEST(QuicWriteBlockedListTest, PriorityOrder) {
TEST(QuicWriteBlockedListTest, CryptoStream) {
QuicWriteBlockedList write_blocked_list;
- write_blocked_list.PushBack(kCryptoStreamId,
- QuicWriteBlockedList::kHighestPriority);
+ write_blocked_list.RegisterStream(kCryptoStreamId, kV3HighestPriority);
+ write_blocked_list.AddStream(kCryptoStreamId, kV3HighestPriority);
EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
@@ -59,8 +63,8 @@ TEST(QuicWriteBlockedListTest, CryptoStream) {
TEST(QuicWriteBlockedListTest, HeadersStream) {
QuicWriteBlockedList write_blocked_list;
- write_blocked_list.PushBack(kHeadersStreamId,
- QuicWriteBlockedList::kHighestPriority);
+ write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority);
+ write_blocked_list.AddStream(kHeadersStreamId, kV3HighestPriority);
EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
@@ -71,10 +75,10 @@ TEST(QuicWriteBlockedListTest, HeadersStream) {
TEST(QuicWriteBlockedListTest, VerifyHeadersStream) {
QuicWriteBlockedList write_blocked_list;
- write_blocked_list.PushBack(5,
- QuicWriteBlockedList::kHighestPriority);
- write_blocked_list.PushBack(kHeadersStreamId,
- QuicWriteBlockedList::kHighestPriority);
+ write_blocked_list.RegisterStream(5, kV3HighestPriority);
+ write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority);
+ write_blocked_list.AddStream(5, kV3HighestPriority);
+ write_blocked_list.AddStream(kHeadersStreamId, kV3HighestPriority);
EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
@@ -95,12 +99,10 @@ TEST(QuicWriteBlockedListTest, NoDuplicateEntries) {
// Try to add a stream to the write blocked list multiple times at the same
// priority.
const QuicStreamId kBlockedId = kClientDataStreamId1;
- write_blocked_list.PushBack(kBlockedId,
- QuicWriteBlockedList::kHighestPriority);
- write_blocked_list.PushBack(kBlockedId,
- QuicWriteBlockedList::kHighestPriority);
- write_blocked_list.PushBack(kBlockedId,
- QuicWriteBlockedList::kHighestPriority);
+ write_blocked_list.RegisterStream(kBlockedId, kV3HighestPriority);
+ write_blocked_list.AddStream(kBlockedId, kV3HighestPriority);
+ write_blocked_list.AddStream(kBlockedId, kV3HighestPriority);
+ write_blocked_list.AddStream(kBlockedId, kV3HighestPriority);
// This should only result in one blocked stream being added.
EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
@@ -112,6 +114,60 @@ TEST(QuicWriteBlockedListTest, NoDuplicateEntries) {
EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams());
}
+TEST(QuicWriteBlockedListTest, BatchingWrites) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_batch_writes, true);
+ QuicWriteBlockedList write_blocked_list;
+
+ const QuicStreamId id1 = kClientDataStreamId1;
+ const QuicStreamId id2 = kClientDataStreamId2;
+ const QuicStreamId id3 = kClientDataStreamId2 + 2;
+ write_blocked_list.RegisterStream(id1, kV3LowestPriority);
+ write_blocked_list.RegisterStream(id2, kV3LowestPriority);
+ write_blocked_list.RegisterStream(id3, kV3HighestPriority);
+
+ write_blocked_list.AddStream(id1, kV3LowestPriority);
+ write_blocked_list.AddStream(id2, kV3LowestPriority);
+ EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
+
+ // The first stream we push back should stay at the front until 16k is
+ // written.
+ EXPECT_EQ(id1, write_blocked_list.PopFront());
+ write_blocked_list.UpdateBytesForStream(id1, 15999);
+ write_blocked_list.AddStream(id1, kV3LowestPriority);
+ EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
+ EXPECT_EQ(id1, write_blocked_list.PopFront());
+
+ // Once 16k is written the first stream will cede to the next.
+ write_blocked_list.UpdateBytesForStream(id1, 1);
+ write_blocked_list.AddStream(id1, kV3LowestPriority);
+ EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
+ EXPECT_EQ(id2, write_blocked_list.PopFront());
+
+ // Set the new stream to have written all but one byte.
+ write_blocked_list.UpdateBytesForStream(id2, 15999);
+ write_blocked_list.AddStream(id2, kV3LowestPriority);
+ EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
+
+ // Ensure higher priority streams are popped first.
+ write_blocked_list.AddStream(id3, kV3HighestPriority);
+ EXPECT_EQ(id3, write_blocked_list.PopFront());
+
+ // Higher priority streams will always be popped first, even if using their
+ // byte quota
+ write_blocked_list.UpdateBytesForStream(id3, 20000);
+ write_blocked_list.AddStream(id3, kV3HighestPriority);
+ EXPECT_EQ(id3, write_blocked_list.PopFront());
+
+ // Once the higher priority stream is out of the way, id2 will resume its 16k
+ // write, with only 1 byte remaining of its guaranteed write allocation.
+ EXPECT_EQ(id2, write_blocked_list.PopFront());
+ write_blocked_list.AddStream(id2, net::kV3HighestPriority);
+ write_blocked_list.UpdateBytesForStream(id2, 1);
+ write_blocked_list.AddStream(id2, kV3LowestPriority);
+ EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
+ EXPECT_EQ(id1, write_blocked_list.PopFront());
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/reliable_quic_stream.cc b/chromium/net/quic/reliable_quic_stream.cc
index 7c7b21c4233..f3ff54145f0 100644
--- a/chromium/net/quic/reliable_quic_stream.cc
+++ b/chromium/net/quic/reliable_quic_stream.cc
@@ -6,6 +6,8 @@
#include "base/logging.h"
#include "net/quic/iovector.h"
+#include "net/quic/quic_ack_listener_interface.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_flow_controller.h"
#include "net/quic/quic_session.h"
@@ -42,78 +44,16 @@ size_t GetReceivedFlowControlWindow(QuicSession* session) {
} // namespace
-// Wrapper that aggregates OnAckNotifications for packets sent using
-// WriteOrBufferData and delivers them to the original
-// QuicAckNotifier::DelegateInterface after all bytes written using
-// WriteOrBufferData are acked. This level of indirection is
-// necessary because the delegate interface provides no mechanism that
-// WriteOrBufferData can use to inform it that the write required
-// multiple WritevData calls or that only part of the data has been
-// sent out by the time ACKs start arriving.
-class ReliableQuicStream::ProxyAckNotifierDelegate
- : public QuicAckNotifier::DelegateInterface {
- public:
- explicit ProxyAckNotifierDelegate(DelegateInterface* delegate)
- : delegate_(delegate),
- pending_acks_(0),
- wrote_last_data_(false),
- num_retransmitted_packets_(0),
- num_retransmitted_bytes_(0) {
- }
-
- void OnAckNotification(int num_retransmitted_packets,
- int num_retransmitted_bytes,
- QuicTime::Delta delta_largest_observed) override {
- DCHECK_LT(0, pending_acks_);
- --pending_acks_;
- num_retransmitted_packets_ += num_retransmitted_packets;
- num_retransmitted_bytes_ += num_retransmitted_bytes;
-
- if (wrote_last_data_ && pending_acks_ == 0) {
- delegate_->OnAckNotification(num_retransmitted_packets_,
- num_retransmitted_bytes_,
- delta_largest_observed);
- }
- }
-
- void WroteData(bool last_data) {
- DCHECK(!wrote_last_data_);
- ++pending_acks_;
- wrote_last_data_ = last_data;
- }
-
- protected:
- // Delegates are ref counted.
- ~ProxyAckNotifierDelegate() override {}
-
- private:
- // Original delegate. delegate_->OnAckNotification will be called when:
- // wrote_last_data_ == true and pending_acks_ == 0
- scoped_refptr<DelegateInterface> delegate_;
-
- // Number of outstanding acks.
- int pending_acks_;
-
- // True if no pending writes remain.
- bool wrote_last_data_;
-
- int num_retransmitted_packets_;
- int num_retransmitted_bytes_;
-
- DISALLOW_COPY_AND_ASSIGN(ProxyAckNotifierDelegate);
-};
-
ReliableQuicStream::PendingData::PendingData(
string data_in,
- scoped_refptr<ProxyAckNotifierDelegate> delegate_in)
- : data(data_in), offset(0), delegate(delegate_in) {
-}
+ QuicAckListenerInterface* ack_listener_in)
+ : data(data_in), offset(0), ack_listener(ack_listener_in) {}
-ReliableQuicStream::PendingData::~PendingData() {
-}
+ReliableQuicStream::PendingData::~PendingData() {}
ReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session)
- : sequencer_(this),
+ : queued_data_bytes_(0),
+ sequencer_(this, session->connection()->clock()),
id_(id),
session_(session),
stream_bytes_read_(0),
@@ -140,8 +80,7 @@ ReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session)
SetFromConfig();
}
-ReliableQuicStream::~ReliableQuicStream() {
-}
+ReliableQuicStream::~ReliableQuicStream() {}
void ReliableQuicStream::SetFromConfig() {
if (session_->config()->HasClientSentConnectionOption(kFSTR, perspective_)) {
@@ -150,16 +89,7 @@ void ReliableQuicStream::SetFromConfig() {
}
void ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
- if (read_side_closed_) {
- DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id;
- // The subclass does not want read data: blackhole the data.
- return;
- }
-
- if (frame.stream_id != id_) {
- session_->connection()->SendConnectionClose(QUIC_INTERNAL_ERROR);
- return;
- }
+ DCHECK_EQ(frame.stream_id, id_);
if (frame.fin) {
fin_received_ = true;
@@ -168,8 +98,14 @@ void ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
}
}
+ if (read_side_closed_) {
+ DVLOG(1) << ENDPOINT << "Ignoring data in frame " << frame.stream_id;
+ // The subclass does not want to read data: blackhole the data.
+ return;
+ }
+
// This count includes duplicate data received.
- size_t frame_payload_size = frame.data.size();
+ size_t frame_payload_size = frame.frame_length;
stream_bytes_read_ += frame_payload_size;
// Flow control is interested in tracking highest received offset.
@@ -178,8 +114,9 @@ void ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
// violation of flow control.
if (flow_controller_.FlowControlViolation() ||
connection_flow_controller_->FlowControlViolation()) {
- session_->connection()->SendConnectionClose(
- QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA);
+ session_->connection()->SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+ "Flow control violation after increasing offset");
return;
}
}
@@ -209,7 +146,7 @@ void ReliableQuicStream::OnStreamReset(const QuicRstStreamFrame& frame) {
}
void ReliableQuicStream::OnConnectionClosed(QuicErrorCode error,
- bool from_peer) {
+ bool /*from_peer*/) {
if (read_side_closed_ && write_side_closed_) {
return;
}
@@ -234,17 +171,12 @@ void ReliableQuicStream::OnFinRead() {
}
void ReliableQuicStream::Reset(QuicRstStreamErrorCode error) {
- DCHECK_NE(QUIC_STREAM_NO_ERROR, error);
stream_error_ = error;
// Sending a RstStream results in calling CloseStream.
session()->SendRstStream(id(), error, stream_bytes_written_);
rst_sent_ = true;
}
-void ReliableQuicStream::CloseConnection(QuicErrorCode error) {
- session()->connection()->SendConnectionClose(error);
-}
-
void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error,
const string& details) {
session()->connection()->SendConnectionCloseWithDetails(error, details);
@@ -253,14 +185,14 @@ void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error,
void ReliableQuicStream::WriteOrBufferData(
StringPiece data,
bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
+ QuicAckListenerInterface* ack_listener) {
if (data.empty() && !fin) {
- LOG(DFATAL) << "data.empty() && !fin";
+ QUIC_BUG << "data.empty() && !fin";
return;
}
if (fin_buffered_) {
- LOG(DFATAL) << "Fin already buffered";
+ QUIC_BUG << "Fin already buffered";
return;
}
if (write_side_closed_) {
@@ -268,34 +200,21 @@ void ReliableQuicStream::WriteOrBufferData(
return;
}
- scoped_refptr<ProxyAckNotifierDelegate> proxy_delegate;
- if (ack_notifier_delegate != nullptr) {
- proxy_delegate = new ProxyAckNotifierDelegate(ack_notifier_delegate);
- }
-
QuicConsumedData consumed_data(0, false);
fin_buffered_ = fin;
if (queued_data_.empty()) {
struct iovec iov(MakeIovec(data));
- consumed_data = WritevData(&iov, 1, fin, proxy_delegate.get());
+ consumed_data = WritevData(&iov, 1, fin, ack_listener);
DCHECK_LE(consumed_data.bytes_consumed, data.length());
}
- bool write_completed;
// If there's unconsumed data or an unconsumed fin, queue it.
if (consumed_data.bytes_consumed < data.length() ||
(fin && !consumed_data.fin_consumed)) {
StringPiece remainder(data.substr(consumed_data.bytes_consumed));
- queued_data_.push_back(PendingData(remainder.as_string(), proxy_delegate));
- write_completed = false;
- } else {
- write_completed = true;
- }
-
- if ((proxy_delegate.get() != nullptr) &&
- (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed)) {
- proxy_delegate->WroteData(write_completed);
+ queued_data_bytes_ += remainder.size();
+ queued_data_.push_back(PendingData(remainder.as_string(), ack_listener));
}
}
@@ -303,7 +222,7 @@ void ReliableQuicStream::OnCanWrite() {
bool fin = false;
while (!queued_data_.empty()) {
PendingData* pending_data = &queued_data_.front();
- ProxyAckNotifierDelegate* delegate = pending_data->delegate.get();
+ QuicAckListenerInterface* ack_listener = pending_data->ack_listener.get();
if (queued_data_.size() == 1 && fin_buffered_) {
fin = true;
}
@@ -311,28 +230,22 @@ void ReliableQuicStream::OnCanWrite() {
pending_data->offset >= pending_data->data.size()) {
// This should be impossible because offset tracks the amount of
// pending_data written thus far.
- LOG(DFATAL) << "Pending offset is beyond available data. offset: "
- << pending_data->offset
- << " vs: " << pending_data->data.size();
+ QUIC_BUG << "Pending offset is beyond available data. offset: "
+ << pending_data->offset << " vs: " << pending_data->data.size();
return;
}
size_t remaining_len = pending_data->data.size() - pending_data->offset;
struct iovec iov = {
const_cast<char*>(pending_data->data.data()) + pending_data->offset,
remaining_len};
- QuicConsumedData consumed_data = WritevData(&iov, 1, fin, delegate);
+ QuicConsumedData consumed_data = WritevData(&iov, 1, fin, ack_listener);
+ queued_data_bytes_ -= consumed_data.bytes_consumed;
if (consumed_data.bytes_consumed == remaining_len &&
fin == consumed_data.fin_consumed) {
queued_data_.pop_front();
- if (delegate != nullptr) {
- delegate->WroteData(true);
- }
} else {
if (consumed_data.bytes_consumed > 0) {
pending_data->offset += consumed_data.bytes_consumed;
- if (delegate != nullptr) {
- delegate->WroteData(false);
- }
}
break;
}
@@ -351,7 +264,7 @@ void ReliableQuicStream::MaybeSendBlocked() {
// WINDOW_UPDATE arrives.
if (connection_flow_controller_->IsBlocked() &&
!flow_controller_.IsBlocked()) {
- session_->MarkConnectionLevelWriteBlocked(id(), EffectivePriority());
+ session_->MarkConnectionLevelWriteBlocked(id(), Priority());
}
}
@@ -359,7 +272,7 @@ QuicConsumedData ReliableQuicStream::WritevData(
const struct iovec* iov,
int iov_count,
bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
+ QuicAckListenerInterface* ack_listener) {
if (write_side_closed_) {
DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed";
return QuicConsumedData(0, false);
@@ -394,11 +307,17 @@ QuicConsumedData ReliableQuicStream::WritevData(
QuicConsumedData consumed_data = session()->WritevData(
id(), QuicIOVector(iov, iov_count, write_length), stream_bytes_written_,
- fin, GetFecProtection(), ack_notifier_delegate);
+ fin, GetFecProtection(), ack_listener);
stream_bytes_written_ += consumed_data.bytes_consumed;
AddBytesSent(consumed_data.bytes_consumed);
+ // The write may have generated a write error causing this stream to be
+ // closed. If so, simply return without marking the stream write blocked.
+ if (write_side_closed_) {
+ return consumed_data;
+ }
+
if (consumed_data.bytes_consumed == write_length) {
if (!fin_with_zero_data) {
MaybeSendBlocked();
@@ -410,10 +329,10 @@ QuicConsumedData ReliableQuicStream::WritevData(
}
CloseWriteSide();
} else if (fin && !consumed_data.fin_consumed) {
- session_->MarkConnectionLevelWriteBlocked(id(), EffectivePriority());
+ session_->MarkConnectionLevelWriteBlocked(id(), Priority());
}
} else {
- session_->MarkConnectionLevelWriteBlocked(id(), EffectivePriority());
+ session_->MarkConnectionLevelWriteBlocked(id(), Priority());
}
return consumed_data;
}
@@ -456,6 +375,11 @@ QuicVersion ReliableQuicStream::version() const {
return session_->connection()->version();
}
+void ReliableQuicStream::StopReading() {
+ DVLOG(1) << ENDPOINT << "Stop reading from stream " << id();
+ sequencer_.StopReading();
+}
+
void ReliableQuicStream::OnClose() {
CloseReadSide();
CloseWriteSide();
@@ -494,7 +418,7 @@ void ReliableQuicStream::OnWindowUpdateFrame(
bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset(
QuicStreamOffset new_offset) {
- uint64 increment =
+ uint64_t increment =
new_offset - flow_controller_.highest_received_byte_offset();
if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) {
return false;
diff --git a/chromium/net/quic/reliable_quic_stream.h b/chromium/net/quic/reliable_quic_stream.h
index 7cc26c86d49..22dce1050db 100644
--- a/chromium/net/quic/reliable_quic_stream.h
+++ b/chromium/net/quic/reliable_quic_stream.h
@@ -17,21 +17,26 @@
#ifndef NET_QUIC_RELIABLE_QUIC_STREAM_H_
#define NET_QUIC_RELIABLE_QUIC_STREAM_H_
+#include <stddef.h>
+#include <stdint.h>
#include <sys/types.h>
#include <list>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "net/base/iovec.h"
#include "net/base/net_export.h"
-#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_flow_controller.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_stream_sequencer.h"
#include "net/quic/quic_types.h"
+//#include "std::strings/std::stringpiece.h"
+//#include "util/refcount/reffed_ptr.h"
+// TODO(alyssar) remove this after cleaning Priority logic from this class.
+#include "net/quic/quic_write_blocked_list.h"
namespace net {
@@ -43,8 +48,7 @@ class QuicSession;
class NET_EXPORT_PRIVATE ReliableQuicStream {
public:
- ReliableQuicStream(QuicStreamId id,
- QuicSession* session);
+ ReliableQuicStream(QuicStreamId id, QuicSession* session);
virtual ~ReliableQuicStream();
@@ -88,31 +92,42 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
// Called by the subclass or the sequencer to close the entire connection from
// this end.
- virtual void CloseConnection(QuicErrorCode error);
virtual void CloseConnectionWithDetails(QuicErrorCode error,
const std::string& details);
- // Returns the effective priority for the stream. This value may change
- // during the life of the stream.
- virtual QuicPriority EffectivePriority() const = 0;
+ // Returns the priority for the stream.
+ virtual SpdyPriority Priority() const = 0;
QuicStreamId id() const { return id_; }
QuicRstStreamErrorCode stream_error() const { return stream_error_; }
QuicErrorCode connection_error() const { return connection_error_; }
- bool read_side_closed() const { return read_side_closed_; }
+ bool reading_stopped() const {
+ return sequencer_.ignore_read_data() || read_side_closed_;
+ }
bool write_side_closed() const { return write_side_closed_; }
- uint64 stream_bytes_read() const { return stream_bytes_read_; }
- uint64 stream_bytes_written() const { return stream_bytes_written_; }
+ bool rst_received() { return rst_received_; }
+ bool rst_sent() { return rst_sent_; }
+ bool fin_received() { return fin_received_; }
+ bool fin_sent() { return fin_sent_; }
+
+ uint64_t queued_data_bytes() const { return queued_data_bytes_; }
+
+ uint64_t stream_bytes_read() const { return stream_bytes_read_; }
+ uint64_t stream_bytes_written() const { return stream_bytes_written_; }
void set_fin_sent(bool fin_sent) { fin_sent_ = fin_sent; }
+ void set_fin_received(bool fin_received) { fin_received_ = fin_received; }
void set_rst_sent(bool rst_sent) { rst_sent_ = rst_sent; }
void set_fec_policy(FecPolicy fec_policy) { fec_policy_ = fec_policy; }
FecPolicy fec_policy() const { return fec_policy_; }
+ void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
+ void set_stream_error(QuicRstStreamErrorCode error) { stream_error_ = error; }
+
// Adjust the flow control window according to new offset in |frame|.
virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
@@ -138,7 +153,7 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
// it was blocked before.
void UpdateSendWindowOffset(QuicStreamOffset new_offset);
- // Returns true if the stream have received either a RST_STREAM or a FIN -
+ // Returns true if the stream has received either a RST_STREAM or a FIN -
// either of which gives a definitive number of bytes which the peer has
// sent. If this is not true on deletion of the stream object, the session
// must keep track of the stream's byte offset until a definitive final value
@@ -155,36 +170,37 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
bool fin_received() const { return fin_received_; }
+ // Sets the sequencer to consume all incoming data itself and not call
+ // OnDataAvailable().
+ // When the FIN is received, the stream will be notified automatically (via
+ // OnFinRead()) (which may happen during the call of StopReading()).
+ // TODO(dworley): There should be machinery to send a RST_STREAM/NO_ERROR and
+ // stop sending stream-level flow-control updates when this end sends FIN.
+ virtual void StopReading();
+
protected:
// Sends as much of 'data' to the connection as the connection will consume,
// and then buffers any remaining data in queued_data_.
// If fin is true: if it is immediately passed on to the session,
// write_side_closed() becomes true, otherwise fin_buffered_ becomes true.
- void WriteOrBufferData(
- base::StringPiece data,
- bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
+ void WriteOrBufferData(base::StringPiece data,
+ bool fin,
+ QuicAckListenerInterface* ack_listener);
// Sends as many bytes in the first |count| buffers of |iov| to the connection
// as the connection will consume.
- // If |ack_notifier_delegate| is provided, then it will be notified once all
+ // If |ack_listener| is provided, then it will be notified once all
// the ACKs for this write have been received.
// Returns the number of bytes consumed by the connection.
- QuicConsumedData WritevData(
- const struct iovec* iov,
- int iov_count,
- bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
-
- // Close the read side of the stream. Further incoming stream frames will be
- // discarded. Can be called by the subclass or internally.
- // May cause the stream to be closed.
- virtual void CloseReadSide();
+ QuicConsumedData WritevData(const struct iovec* iov,
+ int iov_count,
+ bool fin,
+ QuicAckListenerInterface* ack_listener);
// Close the write side of the socket. Further writes will fail.
// Can be called by the subclass or internally.
// Does not send a FIN. May cause the stream to be closed.
- void CloseWriteSide();
+ virtual void CloseWriteSide();
// Helper method that returns FecProtection to use when writing.
FecProtection GetFecProtection();
@@ -204,20 +220,25 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
private:
friend class test::ReliableQuicStreamPeer;
friend class QuicStreamUtils;
- class ProxyAckNotifierDelegate;
+
+ // Close the read side of the socket. May cause the stream to be closed.
+ // Subclasses and consumers should use StopReading to terminate reading early.
+ void CloseReadSide();
+
+ // Subclasses and consumers should use reading_stopped.
+ bool read_side_closed() const { return read_side_closed_; }
struct PendingData {
- PendingData(std::string data_in,
- scoped_refptr<ProxyAckNotifierDelegate> delegate_in);
+ PendingData(std::string data_in, QuicAckListenerInterface* ack_listener_in);
~PendingData();
// Pending data to be written.
std::string data;
// Index of the first byte in data still to be written.
size_t offset;
- // Delegate that should be notified when the pending data is acked.
+ // AckListener that should be notified when the pending data is acked.
// Can be nullptr.
- scoped_refptr<ProxyAckNotifierDelegate> delegate;
+ scoped_refptr<QuicAckListenerInterface> ack_listener;
};
// Calls MaybeSendBlocked on the stream's flow controller and the connection
@@ -227,6 +248,8 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
void MaybeSendBlocked();
std::list<PendingData> queued_data_;
+ // How many bytes are queued?
+ uint64_t queued_data_bytes_;
QuicStreamSequencer sequencer_;
QuicStreamId id_;
@@ -234,8 +257,8 @@ class NET_EXPORT_PRIVATE ReliableQuicStream {
QuicSession* session_;
// Bytes read and written refer to payload bytes only: they do not include
// framing, encryption overhead etc.
- uint64 stream_bytes_read_;
- uint64 stream_bytes_written_;
+ uint64_t stream_bytes_read_;
+ uint64_t stream_bytes_written_;
// Stream error code received from a RstStreamFrame or error code sent by the
// visitor or sequencer in the RstStreamFrame.
diff --git a/chromium/net/quic/reliable_quic_stream_test.cc b/chromium/net/quic/reliable_quic_stream_test.cc
index b7d22ed1e0c..10656c722f0 100644
--- a/chromium/net/quic/reliable_quic_stream_test.cc
+++ b/chromium/net/quic/reliable_quic_stream_test.cc
@@ -4,8 +4,8 @@
#include "net/quic/reliable_quic_stream.h"
-#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_connection.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
#include "net/quic/quic_write_blocked_list.h"
#include "net/quic/spdy_utils.h"
@@ -23,9 +23,11 @@ using base::StringPiece;
using std::min;
using std::string;
using testing::AnyNumber;
+using testing::AtLeast;
using testing::CreateFunctor;
using testing::InSequence;
using testing::Invoke;
+using testing::DoAll;
using testing::Return;
using testing::StrictMock;
using testing::WithArgs;
@@ -43,27 +45,22 @@ const bool kShouldNotProcessData = false;
class TestStream : public ReliableQuicStream {
public:
- TestStream(QuicStreamId id,
- QuicSession* session,
- bool should_process_data)
+ TestStream(QuicStreamId id, QuicSession* session, bool should_process_data)
: ReliableQuicStream(id, session),
should_process_data_(should_process_data) {}
void OnDataAvailable() override {}
- uint32 ProcessRawData(const char* data, uint32 data_len) {
+ uint32_t ProcessRawData(const char* data, uint32_t data_len) {
EXPECT_NE(0u, data_len);
DVLOG(1) << "ProcessData data_len: " << data_len;
data_ += string(data, data_len);
return should_process_data_ ? data_len : 0;
}
- QuicPriority EffectivePriority() const override {
- return QuicUtils::HighestPriority();
- }
+ SpdyPriority Priority() const override { return net::kV3HighestPriority; }
using ReliableQuicStream::WriteOrBufferData;
- using ReliableQuicStream::CloseReadSide;
using ReliableQuicStream::CloseWriteSide;
using ReliableQuicStream::OnClose;
@@ -108,8 +105,8 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
}
void Initialize(bool stream_should_process_data) {
- connection_ = new StrictMock<MockConnection>(Perspective::IS_SERVER,
- supported_versions_);
+ connection_ = new StrictMock<MockConnection>(
+ &helper_, Perspective::IS_SERVER, supported_versions_);
session_.reset(new StrictMock<MockQuicSpdySession>(connection_));
// New streams rely on having the peer's flow control receive window
@@ -126,12 +123,13 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
.Times(AnyNumber());
write_blocked_list_ =
QuicSessionPeer::GetWriteBlockedStreams(session_.get());
+ write_blocked_list_->RegisterStream(kTestStreamId, kV3HighestPriority);
}
bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_); }
bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_); }
- void set_initial_flow_control_window_bytes(uint32 val) {
+ void set_initial_flow_control_window_bytes(uint32_t val) {
initial_flow_control_window_bytes_ = val;
}
@@ -140,13 +138,25 @@ class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
write_blocked_list_->HasWriteBlockedDataStreams();
}
+ QuicConsumedData CloseStreamOnWriteError(
+ QuicStreamId id,
+ QuicIOVector /*iov*/,
+ QuicStreamOffset /*offset*/,
+ bool /*fin*/,
+ FecProtection /*fec_protection*/,
+ QuicAckListenerInterface* /*ack_notifier_delegate*/) {
+ session_->CloseStream(id);
+ return QuicConsumedData(1, false);
+ }
+
protected:
+ MockConnectionHelper helper_;
MockConnection* connection_;
scoped_ptr<MockQuicSpdySession> session_;
TestStream* stream_;
SpdyHeaderBlock headers_;
QuicWriteBlockedList* write_blocked_list_;
- uint32 initial_flow_control_window_bytes_;
+ uint32_t initial_flow_control_window_bytes_;
QuicTime::Delta zero_;
QuicVersionVector supported_versions_;
const QuicStreamId kTestStreamId = 5u;
@@ -184,6 +194,7 @@ TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) {
.WillOnce(Return(QuicConsumedData(1, false)));
stream_->WriteOrBufferData(StringPiece(kData1, 2), false, nullptr);
ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
+ EXPECT_EQ(1u, stream_->queued_data_bytes());
}
TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) {
@@ -210,6 +221,18 @@ TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) {
ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
}
+TEST_F(ReliableQuicStreamTest, CloseOnPartialWrite) {
+ Initialize(kShouldProcessData);
+
+ // Write some data and no fin. However, while writing the data
+ // close the stream and verify that MarkConnectionLevelWriteBlocked does not
+ // crash with an unknown stream.
+ EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+ .WillOnce(Invoke(this, &ReliableQuicStreamTest::CloseStreamOnWriteError));
+ stream_->WriteOrBufferData(StringPiece(kData1, 2), false, nullptr);
+ ASSERT_EQ(0u, write_blocked_list_->NumBlockedStreams());
+}
+
TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
Initialize(kShouldProcessData);
@@ -219,8 +242,8 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
PACKET_6BYTE_PACKET_NUMBER, 0u, NOT_IN_FEC_GROUP);
connection_->SetMaxPacketLength(length);
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).WillOnce(
- Return(QuicConsumedData(kDataLen - 1, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
stream_->WriteOrBufferData(kData1, false, nullptr);
EXPECT_TRUE(HasWriteBlockedStreams());
@@ -229,15 +252,15 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
// Make sure we get the tail of the first write followed by the bytes_consumed
InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).
- WillOnce(Return(QuicConsumedData(1, false)));
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).
- WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(1, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
stream_->OnCanWrite();
// And finally the end of the bytes_consumed.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).
- WillOnce(Return(QuicConsumedData(2, true)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(2, true)));
stream_->OnCanWrite();
}
@@ -254,8 +277,8 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectAlways) {
connection_->SetMaxPacketLength(length);
// Write first data onto stream, which will cause one session write.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).WillOnce(
- Return(QuicConsumedData(kDataLen - 1, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
stream_->WriteOrBufferData(kData1, false, nullptr);
EXPECT_TRUE(HasWriteBlockedStreams());
@@ -264,15 +287,15 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectAlways) {
// Make sure we get the tail of the first write followed by the bytes_consumed
InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).
- WillOnce(Return(QuicConsumedData(1, false)));
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).
- WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(1, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
stream_->OnCanWrite();
// And finally the end of the bytes_consumed.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).
- WillOnce(Return(QuicConsumedData(2, true)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(2, true)));
stream_->OnCanWrite();
}
@@ -289,8 +312,8 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectOptional) {
connection_->SetMaxPacketLength(length);
// Write first data onto stream, which will cause one session write.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).WillOnce(
- Return(QuicConsumedData(kDataLen - 1, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
stream_->WriteOrBufferData(kData1, false, nullptr);
EXPECT_TRUE(HasWriteBlockedStreams());
@@ -299,22 +322,22 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectOptional) {
// Make sure we get the tail of the first write followed by the bytes_consumed
InSequence s;
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).
- WillOnce(Return(QuicConsumedData(1, false)));
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).
- WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(1, false)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
stream_->OnCanWrite();
// And finally the end of the bytes_consumed.
- EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).
- WillOnce(Return(QuicConsumedData(2, true)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _))
+ .WillOnce(Return(QuicConsumedData(2, true)));
stream_->OnCanWrite();
}
TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) {
Initialize(kShouldProcessData);
- stream_->CloseReadSide();
+ ReliableQuicStreamPeer::CloseReadSide(stream_);
stream_->CloseWriteSide();
EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
@@ -425,17 +448,17 @@ TEST_F(ReliableQuicStreamTest, StreamFlowControlMultipleWindowUpdates) {
QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller()));
}
-void SaveProxyAckNotifierDelegate(
- scoped_refptr<QuicAckNotifier::DelegateInterface>* delegate_out,
- QuicAckNotifier::DelegateInterface* delegate) {
- *delegate_out = delegate;
+// TODO(ianswett): It's not clear this method is still needed now that
+// ProxyAckNotifierDelegate has been removed.
+void SaveAckListener(scoped_refptr<QuicAckListenerInterface>* listener_out,
+ QuicAckListenerInterface* listener) {
+ *listener_out = (listener);
}
TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) {
Initialize(kShouldProcessData);
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new StrictMock<MockAckNotifierDelegate>);
+ scoped_refptr<MockAckListener> delegate(new StrictMock<MockAckListener>);
const int kDataSize = 16 * 1024;
const string kData(kDataSize, 'a');
@@ -448,40 +471,30 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) {
stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
- scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
+ scoped_refptr<QuicAckListenerInterface> ack_listener;
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
- &SaveProxyAckNotifierDelegate, &proxy_delegate))),
- Return(QuicConsumedData(kFirstWriteSize, false))));
+ .WillOnce(DoAll(
+ WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &ack_listener))),
+ Return(QuicConsumedData(kFirstWriteSize, false))));
stream_->WriteOrBufferData(kData, false, delegate.get());
EXPECT_TRUE(HasWriteBlockedStreams());
EXPECT_CALL(*session_,
- WritevData(kTestStreamId, _, _, _, _, proxy_delegate.get()))
+ WritevData(kTestStreamId, _, _, _, _, ack_listener.get()))
.WillOnce(Return(QuicConsumedData(kSecondWriteSize, false)));
stream_->OnCanWrite();
// No ack expected for an empty write.
EXPECT_CALL(*session_,
- WritevData(kTestStreamId, _, _, _, _, proxy_delegate.get()))
+ WritevData(kTestStreamId, _, _, _, _, ack_listener.get()))
.WillOnce(Return(QuicConsumedData(0, false)));
stream_->OnCanWrite();
EXPECT_CALL(*session_,
- WritevData(kTestStreamId, _, _, _, _, proxy_delegate.get()))
+ WritevData(kTestStreamId, _, _, _, _, ack_listener.get()))
.WillOnce(Return(QuicConsumedData(kLastWriteSize, false)));
stream_->OnCanWrite();
-
- // There were two writes, so OnAckNotification is not propagated until the
- // third Ack arrives.
- proxy_delegate->OnAckNotification(3, 4, zero_);
- proxy_delegate->OnAckNotification(30, 40, zero_);
-
- // The arguments to delegate->OnAckNotification are the sum of the
- // arguments to proxy_delegate OnAckNotification calls.
- EXPECT_CALL(*delegate.get(), OnAckNotification(333, 444, zero_));
- proxy_delegate->OnAckNotification(300, 400, zero_);
}
// Verify delegate behavior when packets are acked before the WritevData call
@@ -489,8 +502,7 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) {
TEST_F(ReliableQuicStreamTest, WriteOrBufferDataAckNotificationBeforeFlush) {
Initialize(kShouldProcessData);
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new StrictMock<MockAckNotifierDelegate>);
+ scoped_refptr<MockAckListener> ack_listener(new StrictMock<MockAckListener>);
const int kDataSize = 16 * 1024;
const string kData(kDataSize, 'a');
@@ -501,60 +513,45 @@ TEST_F(ReliableQuicStreamTest, WriteOrBufferDataAckNotificationBeforeFlush) {
stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
- scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
+ scoped_refptr<QuicAckListenerInterface> proxy_delegate;
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
- &SaveProxyAckNotifierDelegate, &proxy_delegate))),
- Return(QuicConsumedData(kInitialWriteSize, false))));
- stream_->WriteOrBufferData(kData, false, delegate.get());
+ .WillOnce(DoAll(
+ WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ Return(QuicConsumedData(kInitialWriteSize, false))));
+ stream_->WriteOrBufferData(kData, false, ack_listener.get());
EXPECT_TRUE(HasWriteBlockedStreams());
- // Handle the ack of the first write.
- proxy_delegate->OnAckNotification(3, 4, zero_);
- proxy_delegate = nullptr;
-
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(DoAll(
- WithArgs<5>(Invoke(
- CreateFunctor(&SaveProxyAckNotifierDelegate, &proxy_delegate))),
+ WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
Return(QuicConsumedData(kDataSize - kInitialWriteSize, false))));
stream_->OnCanWrite();
-
- // Handle the ack for the second write.
- EXPECT_CALL(*delegate.get(), OnAckNotification(303, 404, zero_));
- proxy_delegate->OnAckNotification(300, 400, zero_);
}
// Verify delegate behavior when WriteOrBufferData does not buffer.
TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) {
Initialize(kShouldProcessData);
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new StrictMock<MockAckNotifierDelegate>);
+ scoped_refptr<MockAckListener> delegate(new StrictMock<MockAckListener>);
- scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
+ scoped_refptr<QuicAckListenerInterface> proxy_delegate;
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
- &SaveProxyAckNotifierDelegate, &proxy_delegate))),
- Return(QuicConsumedData(kDataLen, true))));
+ .WillOnce(DoAll(
+ WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ Return(QuicConsumedData(kDataLen, true))));
stream_->WriteOrBufferData(kData1, true, delegate.get());
EXPECT_FALSE(HasWriteBlockedStreams());
-
- // Handle the ack.
- EXPECT_CALL(*delegate.get(), OnAckNotification(3, 4, zero_));
- proxy_delegate->OnAckNotification(3, 4, zero_);
}
// Verify delegate behavior when WriteOrBufferData buffers all the data.
TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) {
Initialize(kShouldProcessData);
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new StrictMock<MockAckNotifierDelegate>);
+ scoped_refptr<MockAckListener> delegate(new StrictMock<MockAckListener>);
- scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
+ scoped_refptr<QuicAckListenerInterface> proxy_delegate;
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(Return(QuicConsumedData(0, false)));
@@ -562,14 +559,10 @@ TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) {
EXPECT_TRUE(HasWriteBlockedStreams());
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
- &SaveProxyAckNotifierDelegate, &proxy_delegate))),
- Return(QuicConsumedData(kDataLen, true))));
+ .WillOnce(DoAll(
+ WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ Return(QuicConsumedData(kDataLen, true))));
stream_->OnCanWrite();
-
- // Handle the ack.
- EXPECT_CALL(*delegate.get(), OnAckNotification(3, 4, zero_));
- proxy_delegate->OnAckNotification(3, 4, zero_);
}
// Verify delegate behavior when WriteOrBufferData when the FIN is
@@ -577,28 +570,22 @@ TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) {
TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) {
Initialize(kShouldProcessData);
- scoped_refptr<MockAckNotifierDelegate> delegate(
- new StrictMock<MockAckNotifierDelegate>);
+ scoped_refptr<MockAckListener> delegate(new StrictMock<MockAckListener>);
- scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
+ scoped_refptr<QuicAckListenerInterface> proxy_delegate;
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
- &SaveProxyAckNotifierDelegate, &proxy_delegate))),
- Return(QuicConsumedData(kDataLen, false))));
+ .WillOnce(DoAll(
+ WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ Return(QuicConsumedData(kDataLen, false))));
stream_->WriteOrBufferData(kData1, true, delegate.get());
EXPECT_TRUE(HasWriteBlockedStreams());
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
- .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
- &SaveProxyAckNotifierDelegate, &proxy_delegate))),
- Return(QuicConsumedData(0, true))));
+ .WillOnce(DoAll(
+ WithArgs<5>(Invoke(CreateFunctor(SaveAckListener, &proxy_delegate))),
+ Return(QuicConsumedData(0, true))));
stream_->OnCanWrite();
-
- // Handle the acks.
- proxy_delegate->OnAckNotification(3, 4, zero_);
- EXPECT_CALL(*delegate.get(), OnAckNotification(33, 44, zero_));
- proxy_delegate->OnAckNotification(30, 40, zero_);
}
// Verify that when we receive a packet which violates flow control (i.e. sends
@@ -617,11 +604,36 @@ TEST_F(ReliableQuicStreamTest,
stream_->flow_controller()));
// Stream should not accept the frame, and the connection should be closed.
- EXPECT_CALL(*connection_,
- SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _));
stream_->OnStreamFrame(frame);
}
+// Verify that after the consumer calls StopReading(), the stream still sends
+// flow control updates.
+TEST_F(ReliableQuicStreamTest, StopReadingSendsFlowControl) {
+ Initialize(kShouldProcessData);
+
+ stream_->StopReading();
+
+ // Connection should not get terminated due to flow control errors.
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _))
+ .Times(0);
+ EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(AtLeast(1));
+
+ string data(1000, 'x');
+ for (QuicStreamOffset offset = 0;
+ offset < 2 * kInitialStreamFlowControlWindowForTest;
+ offset += data.length()) {
+ QuicStreamFrame frame(stream_->id(), false, offset, data);
+ stream_->OnStreamFrame(frame);
+ }
+ EXPECT_LT(
+ kInitialStreamFlowControlWindowForTest,
+ QuicFlowControllerPeer::ReceiveWindowOffset(stream_->flow_controller()));
+}
+
TEST_F(ReliableQuicStreamTest, FinalByteOffsetFromFin) {
Initialize(kShouldProcessData);
@@ -657,9 +669,10 @@ TEST_F(ReliableQuicStreamTest, SetDrainingIncomingOutgoing) {
stream_->OnStreamFrame(stream_frame_with_fin);
// The FIN has been received but not consumed.
EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
- EXPECT_FALSE(stream_->read_side_closed());
+ EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_FALSE(stream_->reading_stopped());
- EXPECT_EQ(1u, session_->GetNumOpenStreams());
+ EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
// Outgoing data with FIN.
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
@@ -669,7 +682,7 @@ TEST_F(ReliableQuicStreamTest, SetDrainingIncomingOutgoing) {
EXPECT_EQ(1u, QuicSessionPeer::GetDrainingStreams(session_.get())
->count(kTestStreamId));
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
}
TEST_F(ReliableQuicStreamTest, SetDrainingOutgoingIncoming) {
@@ -682,7 +695,7 @@ TEST_F(ReliableQuicStreamTest, SetDrainingOutgoingIncoming) {
stream_->WriteOrBufferData(StringPiece(kData1, 2), true, nullptr);
EXPECT_TRUE(stream_->write_side_closed());
- EXPECT_EQ(1u, session_->GetNumOpenStreams());
+ EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
// Incoming data with FIN.
QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234,
@@ -690,11 +703,12 @@ TEST_F(ReliableQuicStreamTest, SetDrainingOutgoingIncoming) {
stream_->OnStreamFrame(stream_frame_with_fin);
// The FIN has been received but not consumed.
EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
- EXPECT_FALSE(stream_->read_side_closed());
+ EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_FALSE(stream_->reading_stopped());
EXPECT_EQ(1u, QuicSessionPeer::GetDrainingStreams(session_.get())
->count(kTestStreamId));
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
}
TEST_F(ReliableQuicStreamTest, FecSendPolicyReceivedConnectionOption) {
@@ -710,6 +724,31 @@ TEST_F(ReliableQuicStreamTest, FecSendPolicyReceivedConnectionOption) {
EXPECT_EQ(FEC_PROTECT_ALWAYS, stream_->fec_policy());
}
+TEST_F(ReliableQuicStreamTest, EarlyResponseFinHandling) {
+ // Verify that if the server completes the response before reading the end of
+ // the request, the received FIN is recorded.
+
+ Initialize(kShouldProcessData);
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ // Receive data for the request.
+ QuicStreamFrame frame1(stream_->id(), false, 0, StringPiece("Start"));
+ stream_->OnStreamFrame(frame1);
+ // When QuicSimpleServerStream sends the response, it calls
+ // ReliableQuicStream::CloseReadSide() first.
+ ReliableQuicStreamPeer::CloseReadSide(stream_);
+ // Send data and FIN for the response.
+ stream_->WriteOrBufferData(kData1, false, nullptr);
+ EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ // Receive remaining data and FIN for the request.
+ QuicStreamFrame frame2(stream_->id(), true, 0, StringPiece("End"));
+ stream_->OnStreamFrame(frame2);
+ EXPECT_TRUE(stream_->fin_received());
+ EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/spdy_utils.cc b/chromium/net/quic/spdy_utils.cc
index 0ed9e9df90e..6f2d29f423a 100644
--- a/chromium/net/quic/spdy_utils.cc
+++ b/chromium/net/quic/spdy_utils.cc
@@ -4,47 +4,133 @@
#include "net/quic/spdy_utils.h"
+#include <vector>
+
#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_protocol.h"
+#include "url/gurl.h"
using std::string;
+using std::vector;
namespace net {
// static
-SpdyMajorVersion SpdyUtils::GetSpdyVersionForQuicVersion(
- QuicVersion quic_version) {
- if (quic_version > QUIC_VERSION_24) {
- return HTTP2;
+string SpdyUtils::SerializeUncompressedHeaders(const SpdyHeaderBlock& headers) {
+ SpdyMajorVersion spdy_version = HTTP2;
+
+ size_t length = SpdyFramer::GetSerializedLength(spdy_version, &headers);
+ SpdyFrameBuilder builder(length, spdy_version);
+ SpdyFramer::WriteHeaderBlock(&builder, spdy_version, &headers);
+ scoped_ptr<SpdyFrame> block(builder.take());
+ return string(block->data(), length);
+}
+
+// static
+bool SpdyUtils::ParseHeaders(const char* data,
+ uint32_t data_len,
+ int* content_length,
+ SpdyHeaderBlock* headers) {
+ SpdyFramer framer(HTTP2);
+ if (!framer.ParseHeaderBlockInBuffer(data, data_len, headers) ||
+ headers->empty()) {
+ return false; // Headers were invalid.
+ }
+
+ if (ContainsKey(*headers, "content-length")) {
+ // Check whether multiple values are consistent.
+ base::StringPiece content_length_header = (*headers)["content-length"];
+ vector<string> values =
+ base::SplitString(content_length_header, base::StringPiece("\0", 1),
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const string& value : values) {
+ int new_value;
+ if (!base::StringToInt(value, &new_value) || new_value < 0) {
+ return false;
+ }
+ if (*content_length < 0) {
+ *content_length = new_value;
+ continue;
+ }
+ if (new_value != *content_length) {
+ return false;
+ }
+ }
}
- return SPDY3;
+
+ return true;
}
// static
-SpdyHeaderBlock SpdyUtils::ConvertSpdy3ResponseHeadersToSpdy4(
- SpdyHeaderBlock response_headers) {
- // SPDY/4 headers include neither the version field nor the response details.
- response_headers.erase(":version");
- StringPiece status_value = response_headers[":status"];
- size_t end_of_code = status_value.find(' ');
- if (end_of_code != string::npos) {
- response_headers[":status"] = status_value.substr(0, end_of_code);
+bool SpdyUtils::ParseTrailers(const char* data,
+ uint32_t data_len,
+ size_t* final_byte_offset,
+ SpdyHeaderBlock* trailers) {
+ SpdyFramer framer(HTTP2);
+ if (!framer.ParseHeaderBlockInBuffer(data, data_len, trailers) ||
+ trailers->empty()) {
+ DVLOG(1) << "Request Trailers are invalid.";
+ return false; // Trailers were invalid.
+ }
+
+ // Pull out the final offset pseudo header which indicates the number of
+ // response body bytes expected.
+ auto it = trailers->find(kFinalOffsetHeaderKey);
+ if (it == trailers->end() ||
+ !base::StringToSizeT(it->second, final_byte_offset)) {
+ DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey << "' not present";
+ return false;
}
- return response_headers;
+ // The final offset header is no longer needed.
+ trailers->erase(it->first);
+
+ // Trailers must not have empty keys, and must not contain pseudo headers.
+ for (const auto& trailer : *trailers) {
+ base::StringPiece key = trailer.first;
+ base::StringPiece value = trailer.second;
+ if (key.starts_with(":")) {
+ DVLOG(1) << "Trailers must not contain pseudo-header: '" << key << "','"
+ << value << "'.";
+ return false;
+ }
+
+ // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
+ }
+
+ DVLOG(1) << "Successfully parsed Trailers.";
+ return true;
}
// static
-string SpdyUtils::SerializeUncompressedHeaders(const SpdyHeaderBlock& headers,
- QuicVersion quic_version) {
- SpdyMajorVersion spdy_version = GetSpdyVersionForQuicVersion(quic_version);
+string SpdyUtils::GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers) {
+ SpdyHeaderBlock::const_iterator it = headers.find(":scheme");
+ if (it == headers.end())
+ return "";
+ std::string url = it->second.as_string();
- size_t length = SpdyFramer::GetSerializedLength(spdy_version, &headers);
- SpdyFrameBuilder builder(length, spdy_version);
- SpdyFramer::WriteHeaderBlock(&builder, spdy_version, &headers);
- scoped_ptr<SpdyFrame> block(builder.take());
- return string(block->data(), length);
+ url.append("://");
+
+ it = headers.find(":authority");
+ if (it == headers.end())
+ return "";
+ url.append(it->second.as_string());
+
+ it = headers.find(":path");
+ if (it == headers.end())
+ return "";
+ url.append(it->second.as_string());
+ return url;
+}
+
+// static
+bool SpdyUtils::UrlIsValid(const SpdyHeaderBlock& headers) {
+ string url(GetUrlFromHeaderBlock(headers));
+ return url != "" && GURL(url).is_valid();
}
} // namespace net
diff --git a/chromium/net/quic/spdy_utils.h b/chromium/net/quic/spdy_utils.h
index 86f6d3a5c47..2351e57506f 100644
--- a/chromium/net/quic/spdy_utils.h
+++ b/chromium/net/quic/spdy_utils.h
@@ -5,8 +5,13 @@
#ifndef NET_QUIC_SPDY_UTILS_H_
#define NET_QUIC_SPDY_UTILS_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#include <map>
#include <string>
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
#include "net/spdy/spdy_framer.h"
@@ -15,15 +20,36 @@ namespace net {
class NET_EXPORT_PRIVATE SpdyUtils {
public:
- static SpdyMajorVersion GetSpdyVersionForQuicVersion(
- QuicVersion quic_version);
-
- static SpdyHeaderBlock ConvertSpdy3ResponseHeadersToSpdy4(
- SpdyHeaderBlock response_headers);
-
static std::string SerializeUncompressedHeaders(
- const SpdyHeaderBlock& headers,
- QuicVersion version);
+ const SpdyHeaderBlock& headers);
+
+ // Parses |data| as a std::string containing serialized HTTP/2 HEADERS frame,
+ // populating |headers| with the key->value std:pairs found.
+ // |content_length| will be populated with the value of the content-length
+ // header if one or more are present.
+ // Returns true on success, false if parsing fails, or invalid keys are found.
+ static bool ParseHeaders(const char* data,
+ uint32_t data_len,
+ int* content_length,
+ SpdyHeaderBlock* headers);
+
+ // Parses |data| as a std::string containing serialized HTTP/2 HEADERS frame,
+ // populating |trailers| with the key->value std:pairs found.
+ // The final offset header will be excluded from |trailers|, and instead the
+ // value will be copied to |final_byte_offset|.
+ // Returns true on success, false if parsing fails, or invalid keys are found.
+ static bool ParseTrailers(const char* data,
+ uint32_t data_len,
+ size_t* final_byte_offset,
+ SpdyHeaderBlock* trailers);
+
+ // Returns URL composed from scheme, authority, and path header
+ // values, or empty string if any of those fields are missing.
+ static std::string GetUrlFromHeaderBlock(const net::SpdyHeaderBlock& headers);
+
+ // Returns true if result of |GetUrlFromHeaderBlock()| is non-empty
+ // and is a well-formed URL.
+ static bool UrlIsValid(const net::SpdyHeaderBlock& headers);
private:
DISALLOW_COPY_AND_ASSIGN(SpdyUtils);
diff --git a/chromium/net/quic/spdy_utils_test.cc b/chromium/net/quic/spdy_utils_test.cc
new file mode 100644
index 00000000000..b727638caa2
--- /dev/null
+++ b/chromium/net/quic/spdy_utils_test.cc
@@ -0,0 +1,140 @@
+// 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/quic/spdy_utils.h"
+
+#include "base/macros.h"
+#include "base/strings/string_number_conversions.h"
+#include "net/test/gtest_util.h"
+
+using std::string;
+
+namespace net {
+namespace test {
+
+TEST(SpdyUtilsTest, SerializeAndParseHeaders) {
+ // Creates a SpdyHeaderBlock with some key->value pairs, serializes it, then
+ // parses the serialized output and verifies that the end result is the same
+ // as the headers that the test started with.
+
+ SpdyHeaderBlock input_headers;
+ input_headers[":pseudo1"] = "pseudo value1";
+ input_headers[":pseudo2"] = "pseudo value2";
+ input_headers["key1"] = "value1";
+ const int kContentLength = 1234;
+ input_headers["content-length"] = base::IntToString(kContentLength);
+ input_headers["key2"] = "value2";
+
+ // Serialize the header block.
+ string serialized_headers =
+ SpdyUtils::SerializeUncompressedHeaders(input_headers);
+
+ // Take the serialized header block, and parse back into SpdyHeaderBlock.
+ SpdyHeaderBlock output_headers;
+ int content_length = -1;
+ ASSERT_TRUE(SpdyUtils::ParseHeaders(serialized_headers.data(),
+ serialized_headers.size(),
+ &content_length, &output_headers));
+
+ // Should be back to the original headers.
+ EXPECT_EQ(content_length, kContentLength);
+ EXPECT_EQ(output_headers, input_headers);
+}
+
+TEST(SpdyUtilsTest, SerializeAndParseValidTrailers) {
+ // Creates a SpdyHeaderBlock with some valid Trailers key->value pairs,
+ // serializes it, then parses the serialized output and verifies that the end
+ // result is the same as the trailers that the test started with.
+ SpdyHeaderBlock input_trailers;
+ const size_t kFinalOffset = 5678;
+ input_trailers[kFinalOffsetHeaderKey] = base::IntToString(kFinalOffset);
+ input_trailers["key1"] = "value1";
+ input_trailers["key2"] = "value2";
+
+ // Serialize the trailers.
+ string serialized_trailers =
+ SpdyUtils::SerializeUncompressedHeaders(input_trailers);
+
+ // Take the serialized trailers, and parse back into a SpdyHeaderBlock.
+ SpdyHeaderBlock output_trailers;
+ size_t final_byte_offset = 0;
+ EXPECT_TRUE(SpdyUtils::ParseTrailers(serialized_trailers.data(),
+ serialized_trailers.size(),
+ &final_byte_offset, &output_trailers));
+
+ // Should be back to the original trailers, without the final offset header.
+ EXPECT_EQ(final_byte_offset, kFinalOffset);
+ input_trailers.erase(kFinalOffsetHeaderKey);
+ EXPECT_EQ(output_trailers, input_trailers);
+}
+
+TEST(SpdyUtilsTest, SerializeAndParseTrailersWithoutFinalOffset) {
+ // Verifies that parsing fails if Trailers are missing a final offset header.
+
+ SpdyHeaderBlock input_trailers;
+ input_trailers["key1"] = "value1";
+ input_trailers["key2"] = "value2";
+
+ // Serialize the trailers.
+ string serialized_trailers =
+ SpdyUtils::SerializeUncompressedHeaders(input_trailers);
+
+ // Parsing the serialized trailers fails because of the missing final offset.
+ SpdyHeaderBlock output_trailers;
+ size_t final_byte_offset = 0;
+ EXPECT_FALSE(SpdyUtils::ParseTrailers(serialized_trailers.data(),
+ serialized_trailers.size(),
+ &final_byte_offset, &output_trailers));
+ EXPECT_EQ(final_byte_offset, 0u);
+}
+
+TEST(SpdyUtilsTest, SerializeAndParseTrailersWithPseudoHeaders) {
+ // Verifies that parsing fails if Trailers include pseudo-headers.
+
+ SpdyHeaderBlock input_trailers;
+ input_trailers[kFinalOffsetHeaderKey] = "12345";
+ input_trailers[":disallowed-pseudo-header"] = "pseudo value";
+ input_trailers["key1"] = "value1";
+ input_trailers["key2"] = "value2";
+
+ // Serialize the trailers.
+ string serialized_trailers =
+ SpdyUtils::SerializeUncompressedHeaders(input_trailers);
+
+ // Parsing the serialized trailers fails because of the extra pseudo header.
+ SpdyHeaderBlock output_trailers;
+ size_t final_byte_offset = 0;
+ EXPECT_FALSE(SpdyUtils::ParseTrailers(serialized_trailers.data(),
+ serialized_trailers.size(),
+ &final_byte_offset, &output_trailers));
+}
+
+TEST(SpdyUtilsTest, GetUrlFromHeaderBlock) {
+ SpdyHeaderBlock headers;
+ EXPECT_EQ(SpdyUtils::GetUrlFromHeaderBlock(headers), "");
+ headers[":scheme"] = "https";
+ EXPECT_EQ(SpdyUtils::GetUrlFromHeaderBlock(headers), "");
+ headers[":authority"] = "www.google.com";
+ EXPECT_EQ(SpdyUtils::GetUrlFromHeaderBlock(headers), "");
+ headers[":path"] = "/index.html";
+ EXPECT_EQ(SpdyUtils::GetUrlFromHeaderBlock(headers),
+ "https://www.google.com/index.html");
+ headers["key1"] = "value1";
+ headers["key2"] = "value2";
+ EXPECT_EQ(SpdyUtils::GetUrlFromHeaderBlock(headers),
+ "https://www.google.com/index.html");
+}
+
+TEST(SpdyUtilsTest, UrlIsValid) {
+ SpdyHeaderBlock headers;
+ EXPECT_FALSE(SpdyUtils::UrlIsValid(headers));
+ headers[":scheme"] = "https";
+ EXPECT_FALSE(SpdyUtils::UrlIsValid(headers));
+ headers[":authority"] = "www.google.com";
+ EXPECT_FALSE(SpdyUtils::UrlIsValid(headers));
+ headers[":path"] = "/index.html";
+ EXPECT_TRUE(SpdyUtils::UrlIsValid(headers));
+}
+
+} // namespace test
+} // namespace net_quic
diff --git a/chromium/net/quic/stream_sequencer_buffer.cc b/chromium/net/quic/stream_sequencer_buffer.cc
new file mode 100644
index 00000000000..5b98452d03c
--- /dev/null
+++ b/chromium/net/quic/stream_sequencer_buffer.cc
@@ -0,0 +1,453 @@
+// Copyright (c) 2015 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/stream_sequencer_buffer.h"
+
+#include "base/logging.h"
+#include "net/quic/quic_bug_tracker.h"
+
+using std::min;
+
+namespace net {
+
+StreamSequencerBuffer::Gap::Gap(QuicStreamOffset begin_offset,
+ QuicStreamOffset end_offset)
+ : begin_offset(begin_offset), end_offset(end_offset) {}
+
+StreamSequencerBuffer::FrameInfo::FrameInfo()
+ : length(1), timestamp(QuicTime::Zero()) {}
+
+StreamSequencerBuffer::FrameInfo::FrameInfo(size_t length, QuicTime timestamp)
+ : length(length), timestamp(timestamp) {}
+
+StreamSequencerBuffer::StreamSequencerBuffer(size_t max_capacity_bytes)
+ : max_buffer_capacity_bytes_(max_capacity_bytes),
+ blocks_count_(
+ ceil(static_cast<double>(max_capacity_bytes) / kBlockSizeBytes)),
+ total_bytes_read_(0),
+ blocks_(blocks_count_) {
+ Clear();
+}
+
+StreamSequencerBuffer::~StreamSequencerBuffer() {
+ Clear();
+}
+
+void StreamSequencerBuffer::Clear() {
+ for (size_t i = 0; i < blocks_count_; ++i) {
+ if (blocks_[i] != nullptr) {
+ RetireBlock(i);
+ }
+ }
+ num_bytes_buffered_ = 0;
+ // Reset gaps_ so that buffer is in a state as if all data before
+ // total_bytes_read_ has been consumed, and those after total_bytes_read_
+ // has never arrived.
+ gaps_ = std::list<Gap>(
+ 1, Gap(total_bytes_read_, std::numeric_limits<QuicStreamOffset>::max())),
+ frame_arrival_time_map_.clear();
+}
+
+void StreamSequencerBuffer::RetireBlock(size_t idx) {
+ DCHECK(blocks_[idx] != nullptr);
+ delete blocks_[idx];
+ blocks_[idx] = nullptr;
+ DVLOG(1) << "Retired block with index: " << idx;
+}
+
+QuicErrorCode StreamSequencerBuffer::OnStreamData(
+ QuicStreamOffset starting_offset,
+ base::StringPiece data,
+ QuicTime timestamp,
+ size_t* const bytes_buffered) {
+ *bytes_buffered = 0;
+ QuicStreamOffset offset = starting_offset;
+ size_t size = data.size();
+ if (size == 0) {
+ QUIC_BUG << "Attempted to write 0 bytes of data.";
+ return QUIC_INVALID_STREAM_FRAME;
+ }
+
+ // Find the first gap not ending before |offset|. This gap maybe the gap to
+ // fill if the arriving frame doesn't overlaps with previous ones.
+ std::list<Gap>::iterator current_gap = gaps_.begin();
+ while (current_gap != gaps_.end() && current_gap->end_offset <= offset) {
+ ++current_gap;
+ }
+
+ DCHECK(current_gap != gaps_.end());
+
+ // "duplication": might duplicate with data alread filled,but also might
+ // overlap across different base::StringPiece objects already written.
+ // In both cases, don't write the data,
+ // and allow the caller of this method to handle the result.
+ if (offset < current_gap->begin_offset &&
+ offset + size <= current_gap->begin_offset) {
+ DVLOG(1) << "Duplicated data at offset: " << offset << " length: " << size;
+ return QUIC_NO_ERROR;
+ }
+ if (offset < current_gap->begin_offset &&
+ offset + size > current_gap->begin_offset) {
+ // Beginning of new data overlaps data before current gap.
+ return QUIC_INVALID_STREAM_DATA;
+ }
+ if (offset + size > current_gap->end_offset) {
+ // End of new data overlaps with data after current gap.
+ return QUIC_INVALID_STREAM_DATA;
+ }
+
+ // Write beyond the current range this buffer is covering.
+ if (offset + size > total_bytes_read_ + max_buffer_capacity_bytes_) {
+ return QUIC_INTERNAL_ERROR;
+ }
+
+ size_t total_written = 0;
+ size_t source_remaining = size;
+ const char* source = data.data();
+ // Write data block by block. If corresponding block has not created yet,
+ // create it first.
+ // Stop when all data are written or reaches the logical end of the buffer.
+ while (source_remaining > 0) {
+ const size_t write_block_num = GetBlockIndex(offset);
+ const size_t write_block_offset = GetInBlockOffset(offset);
+ DCHECK_GT(blocks_count_, write_block_num);
+
+ size_t block_capacity = GetBlockCapacity(write_block_num);
+ size_t bytes_avail = block_capacity - write_block_offset;
+
+ // If this write meets the upper boundary of the buffer,
+ // reduce the available free bytes.
+ if (offset + bytes_avail > total_bytes_read_ + max_buffer_capacity_bytes_) {
+ bytes_avail = total_bytes_read_ + max_buffer_capacity_bytes_ - offset;
+ }
+
+ if (blocks_[write_block_num] == nullptr) {
+ // TODO(danzh): Investigate if using a freelist would improve performance.
+ // Same as RetireBlock().
+ blocks_[write_block_num] = new BufferBlock();
+ }
+
+ const size_t bytes_to_copy = min<size_t>(bytes_avail, source_remaining);
+ char* dest = blocks_[write_block_num]->buffer + write_block_offset;
+ DVLOG(1) << "Write at offset: " << offset << " length: " << bytes_to_copy;
+ memcpy(dest, source, bytes_to_copy);
+ source += bytes_to_copy;
+ source_remaining -= bytes_to_copy;
+ offset += bytes_to_copy;
+ total_written += bytes_to_copy;
+ }
+
+ DCHECK_GT(total_written, 0u);
+ *bytes_buffered = total_written;
+ UpdateGapList(current_gap, starting_offset, total_written);
+
+ frame_arrival_time_map_.insert(
+ std::make_pair(starting_offset, FrameInfo(size, timestamp)));
+ num_bytes_buffered_ += total_written;
+ return QUIC_NO_ERROR;
+}
+
+inline void StreamSequencerBuffer::UpdateGapList(
+ std::list<Gap>::iterator gap_with_new_data_written,
+ QuicStreamOffset start_offset,
+ size_t bytes_written) {
+ if (gap_with_new_data_written->begin_offset == start_offset &&
+ gap_with_new_data_written->end_offset > start_offset + bytes_written) {
+ // New data has been written into the left part of the buffer.
+ gap_with_new_data_written->begin_offset = start_offset + bytes_written;
+ } else if (gap_with_new_data_written->begin_offset < start_offset &&
+ gap_with_new_data_written->end_offset ==
+ start_offset + bytes_written) {
+ // New data has been written into the right part of the buffer.
+ gap_with_new_data_written->end_offset = start_offset;
+ } else if (gap_with_new_data_written->begin_offset < start_offset &&
+ gap_with_new_data_written->end_offset >
+ start_offset + bytes_written) {
+ // New data has been written into the middle of the buffer.
+ auto current = gap_with_new_data_written++;
+ size_t current_end = current->end_offset;
+ current->end_offset = start_offset;
+ gaps_.insert(gap_with_new_data_written,
+ Gap(start_offset + bytes_written, current_end));
+ } else if (gap_with_new_data_written->begin_offset == start_offset &&
+ gap_with_new_data_written->end_offset ==
+ start_offset + bytes_written) {
+ // This gap has been filled with new data. So it's no longer a gap.
+ gaps_.erase(gap_with_new_data_written);
+ }
+}
+
+size_t StreamSequencerBuffer::Readv(const iovec* dest_iov, size_t dest_count) {
+ size_t bytes_read = 0;
+ for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) {
+ char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base);
+ size_t dest_remaining = dest_iov[i].iov_len;
+ while (dest_remaining > 0 && ReadableBytes() > 0) {
+ size_t block_idx = NextBlockToRead();
+ size_t start_offset_in_block = ReadOffset();
+ size_t block_capacity = GetBlockCapacity(block_idx);
+ size_t bytes_available_in_block =
+ min<size_t>(ReadableBytes(), block_capacity - start_offset_in_block);
+ size_t bytes_to_copy =
+ min<size_t>(bytes_available_in_block, dest_remaining);
+ DCHECK_GT(bytes_to_copy, 0u);
+ DCHECK_NE(static_cast<BufferBlock*>(nullptr), blocks_[block_idx]);
+ memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block,
+ bytes_to_copy);
+ dest += bytes_to_copy;
+ dest_remaining -= bytes_to_copy;
+ num_bytes_buffered_ -= bytes_to_copy;
+ total_bytes_read_ += bytes_to_copy;
+ bytes_read += bytes_to_copy;
+
+ // Retire the block if all the data is read out
+ // and no other data is stored in this block.
+ if (bytes_to_copy == bytes_available_in_block) {
+ RetireBlockIfEmpty(block_idx);
+ }
+ }
+ }
+
+ if (bytes_read > 0) {
+ UpdateFrameArrivalMap(total_bytes_read_);
+ }
+ return bytes_read;
+}
+
+int StreamSequencerBuffer::GetReadableRegions(struct iovec* iov,
+ int iov_count) const {
+ DCHECK(iov != nullptr);
+ DCHECK_GT(iov_count, 0);
+
+ if (ReadableBytes() == 0) {
+ iov[0].iov_base = nullptr;
+ iov[0].iov_len = 0;
+ return 0;
+ }
+
+ size_t start_block_idx = NextBlockToRead();
+ QuicStreamOffset readable_offset_end = gaps_.front().begin_offset - 1;
+ DCHECK_GE(readable_offset_end + 1, total_bytes_read_);
+ size_t end_block_offset = GetInBlockOffset(readable_offset_end);
+ size_t end_block_idx = GetBlockIndex(readable_offset_end);
+
+ // If readable region is within one block, deal with it seperately.
+ if (start_block_idx == end_block_idx && ReadOffset() <= end_block_offset) {
+ iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
+ iov[0].iov_len = ReadableBytes();
+ DVLOG(1) << "Got only a single block with index: " << start_block_idx;
+ return 1;
+ }
+
+ // Get first block
+ iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
+ iov[0].iov_len = GetBlockCapacity(start_block_idx) - ReadOffset();
+ DVLOG(1) << "Got first block " << start_block_idx << " with len "
+ << iov[0].iov_len;
+ DCHECK_GT(readable_offset_end + 1, total_bytes_read_ + iov[0].iov_len)
+ << "there should be more available data";
+
+ // Get readable regions of the rest blocks till either 2nd to last block
+ // before gap is met or |iov| is filled. For these blocks, one whole block is
+ // a region.
+ int iov_used = 1;
+ size_t block_idx = (start_block_idx + iov_used) % blocks_count_;
+ while (block_idx != end_block_idx && iov_used < iov_count) {
+ DCHECK_NE(static_cast<BufferBlock*>(nullptr), blocks_[block_idx]);
+ iov[iov_used].iov_base = blocks_[block_idx]->buffer;
+ iov[iov_used].iov_len = GetBlockCapacity(block_idx);
+ DVLOG(1) << "Got block with index: " << block_idx;
+ ++iov_used;
+ block_idx = (start_block_idx + iov_used) % blocks_count_;
+ }
+
+ // Deal with last block if |iov| can hold more.
+ if (iov_used < iov_count) {
+ DCHECK_NE(static_cast<BufferBlock*>(nullptr), blocks_[block_idx]);
+ iov[iov_used].iov_base = blocks_[end_block_idx]->buffer;
+ iov[iov_used].iov_len = end_block_offset + 1;
+ DVLOG(1) << "Got last block with index: " << end_block_idx;
+ ++iov_used;
+ }
+ return iov_used;
+}
+
+bool StreamSequencerBuffer::GetReadableRegion(iovec* iov,
+ QuicTime* timestamp) const {
+ if (ReadableBytes() == 0) {
+ iov[0].iov_base = nullptr;
+ iov[0].iov_len = 0;
+ return false;
+ }
+
+ size_t start_block_idx = NextBlockToRead();
+ iov->iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
+ size_t readable_bytes_in_block = min<size_t>(
+ GetBlockCapacity(start_block_idx) - ReadOffset(), ReadableBytes());
+ size_t region_len = 0;
+ auto iter = frame_arrival_time_map_.begin();
+ *timestamp = iter->second.timestamp;
+ DVLOG(1) << "Readable bytes in block: " << readable_bytes_in_block;
+ for (; iter != frame_arrival_time_map_.end() &&
+ region_len + iter->second.length <= readable_bytes_in_block;
+ ++iter) {
+ if (iter->second.timestamp != *timestamp) {
+ // If reaches a frame arrive at another timestamp, stop expanding current
+ // region.
+ DVLOG(1) << "Meet frame with different timestamp.";
+ break;
+ }
+ region_len += iter->second.length;
+ DVLOG(1) << "Added bytes to region: " << iter->second.length;
+ }
+ if (iter == frame_arrival_time_map_.end() ||
+ iter->second.timestamp == *timestamp) {
+ // If encountered the end of readable bytes before reaching a different
+ // timestamp.
+ DVLOG(1) << "Got all readable bytes in first block.";
+ region_len = readable_bytes_in_block;
+ }
+ iov->iov_len = region_len;
+ return true;
+}
+
+bool StreamSequencerBuffer::MarkConsumed(size_t bytes_used) {
+ if (bytes_used > ReadableBytes()) {
+ return false;
+ }
+ size_t bytes_to_consume = bytes_used;
+ while (bytes_to_consume > 0) {
+ size_t block_idx = NextBlockToRead();
+ size_t offset_in_block = ReadOffset();
+ size_t bytes_available = min<size_t>(
+ ReadableBytes(), GetBlockCapacity(block_idx) - offset_in_block);
+ size_t bytes_read = min<size_t>(bytes_to_consume, bytes_available);
+ total_bytes_read_ += bytes_read;
+ num_bytes_buffered_ -= bytes_read;
+ bytes_to_consume -= bytes_read;
+ // If advanced to the end of current block and end of buffer hasn't wrapped
+ // to this block yet.
+ if (bytes_available == bytes_read) {
+ RetireBlockIfEmpty(block_idx);
+ }
+ }
+ if (bytes_used > 0) {
+ UpdateFrameArrivalMap(total_bytes_read_);
+ }
+ return true;
+}
+
+size_t StreamSequencerBuffer::FlushBufferedFrames() {
+ size_t prev_total_bytes_read = total_bytes_read_;
+ total_bytes_read_ = gaps_.back().begin_offset;
+ Clear();
+ return total_bytes_read_ - prev_total_bytes_read;
+}
+
+size_t StreamSequencerBuffer::ReadableBytes() const {
+ return gaps_.front().begin_offset - total_bytes_read_;
+}
+
+bool StreamSequencerBuffer::HasBytesToRead() const {
+ return ReadableBytes() > 0;
+}
+
+QuicStreamOffset StreamSequencerBuffer::BytesConsumed() const {
+ return total_bytes_read_;
+}
+
+size_t StreamSequencerBuffer::BytesBuffered() const {
+ return num_bytes_buffered_;
+}
+
+size_t StreamSequencerBuffer::GetBlockIndex(QuicStreamOffset offset) const {
+ return (offset % max_buffer_capacity_bytes_) / kBlockSizeBytes;
+}
+
+size_t StreamSequencerBuffer::GetInBlockOffset(QuicStreamOffset offset) const {
+ return (offset % max_buffer_capacity_bytes_) % kBlockSizeBytes;
+}
+
+size_t StreamSequencerBuffer::ReadOffset() const {
+ return GetInBlockOffset(total_bytes_read_);
+}
+
+size_t StreamSequencerBuffer::NextBlockToRead() const {
+ return GetBlockIndex(total_bytes_read_);
+}
+
+void StreamSequencerBuffer::RetireBlockIfEmpty(size_t block_index) {
+ DCHECK(ReadableBytes() == 0 || GetInBlockOffset(total_bytes_read_) == 0)
+ << "RetireBlockIfEmpty() should only be called when advancing to next "
+ "block"
+ " or a gap has been reached.";
+ // If the whole buffer becomes empty, the last piece of data has been read.
+ if (Empty()) {
+ RetireBlock(block_index);
+ return;
+ }
+
+ // Check where the logical end of this buffer is.
+ // Not empty if the end of circular buffer has been wrapped to this block.
+ if (GetBlockIndex(gaps_.back().begin_offset - 1) == block_index) {
+ return;
+ }
+
+ // Read index remains in this block, which means a gap has been reached.
+ if (NextBlockToRead() == block_index) {
+ Gap first_gap = gaps_.front();
+ DCHECK(first_gap.begin_offset == total_bytes_read_);
+ // Check where the next piece data is.
+ // Not empty if next piece of data is still in this chunk.
+ bool gap_extends_to_infinity =
+ (first_gap.end_offset != std::numeric_limits<QuicStreamOffset>::max());
+ bool gap_ends_in_this_block =
+ (GetBlockIndex(first_gap.end_offset) == block_index);
+ if (gap_extends_to_infinity || gap_ends_in_this_block) {
+ return;
+ }
+ }
+ RetireBlock(block_index);
+}
+
+bool StreamSequencerBuffer::Empty() const {
+ return gaps_.size() == 1 && gaps_.front().begin_offset == total_bytes_read_;
+}
+
+size_t StreamSequencerBuffer::GetBlockCapacity(size_t block_index) const {
+ if ((block_index + 1) == blocks_count_) {
+ size_t result = max_buffer_capacity_bytes_ % kBlockSizeBytes;
+ if (result == 0) { // whole block
+ result = kBlockSizeBytes;
+ }
+ return result;
+ } else {
+ return kBlockSizeBytes;
+ }
+}
+
+void StreamSequencerBuffer::UpdateFrameArrivalMap(QuicStreamOffset offset) {
+ // Get the frame before which all frames should be removed.
+ auto next_frame = frame_arrival_time_map_.upper_bound(offset);
+ DCHECK(next_frame != frame_arrival_time_map_.begin());
+ auto iter = frame_arrival_time_map_.begin();
+ while (iter != next_frame) {
+ auto erased = *iter;
+ iter = frame_arrival_time_map_.erase(iter);
+ DVLOG(1) << "Removed FrameInfo with offset: " << erased.first
+ << " and length: " << erased.second.length;
+ if (erased.first + erased.second.length > offset) {
+ // If last frame is partially read out, update this FrameInfo and insert
+ // it back.
+ auto updated = std::make_pair(
+ offset, FrameInfo(erased.first + erased.second.length - offset,
+ erased.second.timestamp));
+ DVLOG(1) << "Inserted FrameInfo with offset: " << updated.first
+ << " and length: " << updated.second.length;
+ frame_arrival_time_map_.insert(updated);
+ }
+ }
+}
+
+} // namespace net
diff --git a/chromium/net/quic/stream_sequencer_buffer.h b/chromium/net/quic/stream_sequencer_buffer.h
new file mode 100644
index 00000000000..64a7959ccb8
--- /dev/null
+++ b/chromium/net/quic/stream_sequencer_buffer.h
@@ -0,0 +1,203 @@
+// Copyright (c) 2015 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_STREAM_SEQUENCER_BUFFER_H_
+#define NET_QUIC_STREAM_SEQUENCER_BUFFER_H_
+
+// StreamSequencerBuffer implements QuicStreamSequencerBufferInterface.
+// It is a circular stream buffer with random write and
+// in-sequence read. It consists of a vector of pointers pointing
+// to memory blocks created as needed and a list of Gaps to indicate
+// the missing data between the data already written into the buffer.
+// - Data are written in with offset indicating where it should be in the
+// stream, and the buffer grown as needed (up to the maximum buffer capacity),
+// without expensive copying (extra blocks are allocated).
+// - Data can be read from the buffer if there is no gap before it,
+// and the buffer shrinks as the data are consumed.
+// - An upper limit on the number of blocks in the buffer provides an upper
+// bound on memory use.
+//
+// This class is thread-unsafe.
+//
+// StreamSequencerBuffer maintains a concept of the readable region, which
+// contains all written data that has not been read.
+// It promises stability of the underlying memory addresses in the readable
+// region, so pointers into it can be maintained, and the offset of a pointer
+// from the start of the read region can be calculated.
+//
+// Expected Use:
+// StreamSequencerBuffer buffer(2.5 * 8 * 1024);
+// std::string source(1024, 'a');
+// base::StringPiece std::string_piece(source.data(), source.size());
+// size_t written = 0;
+// buffer.OnStreamData(800, std::string_piece, GetEpollClockNow(), &written);
+// source = std::string{800, 'b'};
+// base::StringPiece std::string_piece1(source.data(), 800);
+// // Try to write to [1, 801), but should fail due to overlapping,
+// // res should be QUIC_INVALID_STREAM_DATA
+// auto res = buffer.OnStreamData(1, std::string_piece1, &written));
+// // write to [0, 800), res should be QUIC_NO_ERROR
+// auto res = buffer.OnStreamData(0, std::string_piece1, GetEpollClockNow(),
+// &written);
+//
+// // Read into a iovec array with total capacity of 120 bytes.
+// char dest[120];
+// iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40},
+// iovec{dest + 80, 40}};
+// size_t read = buffer.Readv(iovecs, 3);
+//
+// // Get single readable region with timestamp.
+// QuicTime t;
+// iovec iov;
+// buffer.GetReadableRegion(iov, &t);
+//
+// // Get readable regions from [256, 1024) and consume some of it.
+// iovec iovs[2];
+// int iov_count = buffer.GetReadableRegions(iovs, 2);
+// // Consume some bytes in iovs, returning number of bytes having been
+// consumed.
+// size_t consumed = consume_iovs(iovs, iov_count);
+// buffer.MarkConsumed(consumed);
+
+#include <stddef.h>
+
+#include <functional>
+#include <list>
+#include <memory>
+
+#include "base/macros.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_stream_sequencer_buffer_interface.h"
+
+namespace net {
+
+namespace test {
+class StreamSequencerBufferPeer;
+} // namespace test
+
+class NET_EXPORT_PRIVATE StreamSequencerBuffer
+ : public QuicStreamSequencerBufferInterface {
+ public:
+ // A Gap indicates a missing chunk of bytes between
+ // [begin_offset, end_offset) in the stream
+ struct Gap {
+ Gap(QuicStreamOffset begin_offset, QuicStreamOffset end_offset);
+ QuicStreamOffset begin_offset;
+ QuicStreamOffset end_offset;
+ };
+
+ // A FrameInfo stores the length of a frame and the time it arrived.
+ struct NET_EXPORT_PRIVATE FrameInfo {
+ FrameInfo();
+ FrameInfo(size_t length, QuicTime timestamp);
+
+ size_t length;
+ QuicTime timestamp;
+ };
+
+ // Size of blocks used by this buffer.
+ // Choose 8K to make block large enough to hold multiple frames, each of
+ // which could be up to 1.5 KB.
+ static const size_t kBlockSizeBytes = 8 * 1024; // 8KB
+
+ // The basic storage block used by this buffer.
+ struct BufferBlock {
+ char buffer[kBlockSizeBytes];
+ };
+
+ explicit StreamSequencerBuffer(size_t max_capacity_bytes);
+
+ ~StreamSequencerBuffer() override;
+
+ // QuicStreamSequencerBufferInterface implementation.
+ void Clear() override;
+ bool Empty() const override;
+ QuicErrorCode OnStreamData(QuicStreamOffset offset,
+ base::StringPiece data,
+ QuicTime timestamp,
+ size_t* bytes_buffered) override;
+ size_t Readv(const struct iovec* dest_iov, size_t dest_count) override;
+ int GetReadableRegions(struct iovec* iov, int iov_len) const override;
+ bool GetReadableRegion(iovec* iov, QuicTime* timestamp) const override;
+ bool MarkConsumed(size_t bytes_buffered) override;
+ size_t FlushBufferedFrames() override;
+ bool HasBytesToRead() const override;
+ QuicStreamOffset BytesConsumed() const override;
+ size_t BytesBuffered() const override;
+
+ private:
+ friend class test::StreamSequencerBufferPeer;
+
+ // Dispose the given buffer block.
+ // After calling this method, blocks_[index] is set to nullptr
+ // in order to indicate that no memory set is allocated for that block.
+ void RetireBlock(size_t index);
+
+ // Should only be called after the indexed block is read till the end of the
+ // block or a gap has been reached.
+ // If the block at |block_index| contains no buffered data, then the block is
+ // retired.
+ void RetireBlockIfEmpty(size_t block_index);
+
+ // Called within OnStreamData() to update the gap OnStreamData() writes into
+ // (remove, split or change begin/end offset).
+ void UpdateGapList(std::list<Gap>::iterator gap_with_new_data_written,
+ QuicStreamOffset start_offset,
+ size_t bytes_written);
+
+ // Calculate the capacity of block at specified index.
+ // Return value should be either kBlockSizeBytes for non-trailing blocks and
+ // max_buffer_capacity % kBlockSizeBytes for trailing block.
+ size_t GetBlockCapacity(size_t index) const;
+
+ // Does not check if offset is within reasonable range.
+ size_t GetBlockIndex(QuicStreamOffset offset) const;
+
+ // Given an offset in the stream, return the offset from the beginning of the
+ // block which contains this data.
+ size_t GetInBlockOffset(QuicStreamOffset offset) const;
+
+ // Get offset relative to index 0 in logical 1st block to start next read.
+ size_t ReadOffset() const;
+
+ // Get the index of the logical 1st block to start next read.
+ size_t NextBlockToRead() const;
+
+ // Returns number of bytes available to be read out.
+ size_t ReadableBytes() const;
+
+ // Called after Readv() and MarkConsumed() to keep frame_arrival_time_map_
+ // up to date.
+ // |offset| is the byte next read should start from. All frames before it
+ // should be removed from the map.
+ void UpdateFrameArrivalMap(QuicStreamOffset offset);
+
+ // The maximum total capacity of this buffer in byte, as constructed.
+ const size_t max_buffer_capacity_bytes_;
+
+ // How many blocks this buffer would need when it reaches full capacity.
+ const size_t blocks_count_;
+
+ // Number of bytes read out of buffer.
+ QuicStreamOffset total_bytes_read_;
+
+ // Contains Gaps which represents currently missing data.
+ std::list<Gap> gaps_;
+
+ // An ordered, variable-length list of blocks, with the length limited
+ // such that the number of blocks never exceeds blocks_count_.
+ // Each list entry can hold up to kBlockSizeBytes bytes.
+ std::vector<BufferBlock*> blocks_;
+
+ // Number of bytes in buffer.
+ size_t num_bytes_buffered_;
+
+ // Stores all the buffered frames' start offset, length and arrival time.
+ std::map<QuicStreamOffset, FrameInfo> frame_arrival_time_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(StreamSequencerBuffer);
+};
+} // namespace net
+
+#endif // NET_QUIC_STREAM_SEQUENCER_BUFFER_H_
diff --git a/chromium/net/quic/stream_sequencer_buffer_test.cc b/chromium/net/quic/stream_sequencer_buffer_test.cc
new file mode 100644
index 00000000000..ccebb73539e
--- /dev/null
+++ b/chromium/net/quic/stream_sequencer_buffer_test.cc
@@ -0,0 +1,981 @@
+// Copyright (c) 2015 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/stream_sequencer_buffer.h"
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/rand_util.h"
+#include "net/quic/test_tools/mock_clock.h"
+#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/test/gtest_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gmock_mutant.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using std::min;
+
+namespace net {
+
+namespace test {
+
+char GetCharFromIOVecs(size_t offset, iovec iov[], size_t count) {
+ size_t start_offset = 0;
+ for (size_t i = 0; i < count; i++) {
+ if (iov[i].iov_len == 0) {
+ continue;
+ }
+ size_t end_offset = start_offset + iov[i].iov_len - 1;
+ if (offset >= start_offset && offset <= end_offset) {
+ const char* buf = reinterpret_cast<const char*>(iov[i].iov_base);
+ return buf[offset - start_offset];
+ }
+ start_offset += iov[i].iov_len;
+ }
+ LOG(ERROR) << "Could not locate char at offset " << offset << " in " << count
+ << " iovecs";
+ for (size_t i = 0; i < count; ++i) {
+ LOG(ERROR) << " iov[" << i << "].iov_len = " << iov[i].iov_len;
+ }
+ return '\0';
+}
+
+static const size_t kBlockSizeBytes = StreamSequencerBuffer::kBlockSizeBytes;
+typedef StreamSequencerBuffer::BufferBlock BufferBlock;
+typedef StreamSequencerBuffer::Gap Gap;
+typedef StreamSequencerBuffer::FrameInfo FrameInfo;
+
+class StreamSequencerBufferPeer {
+ public:
+ explicit StreamSequencerBufferPeer(StreamSequencerBuffer* buffer)
+ : buffer_(buffer) {}
+
+ // Read from this buffer_->into the given destination buffer_-> up to the
+ // size of the destination. Returns the number of bytes read. Reading from
+ // an empty buffer_->returns 0.
+ size_t Read(char* dest_buffer, size_t size) {
+ iovec dest;
+ dest.iov_base = dest_buffer, dest.iov_len = size;
+ return buffer_->Readv(&dest, 1);
+ }
+
+ // If buffer is empty, the blocks_ array must be empty, which means all
+ // blocks are deallocated.
+ bool CheckEmptyInvariants() {
+ return !buffer_->Empty() || IsBlockArrayEmpty();
+ }
+
+ bool IsBlockArrayEmpty() {
+ size_t count = buffer_->blocks_count_;
+ for (size_t i = 0; i < count; i++) {
+ if (buffer_->blocks_[i] != nullptr) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool CheckInitialState() {
+ EXPECT_TRUE(buffer_->Empty() && buffer_->total_bytes_read_ == 0 &&
+ buffer_->num_bytes_buffered_ == 0);
+ return CheckBufferInvariants();
+ }
+
+ bool CheckBufferInvariants() {
+ QuicStreamOffset data_span =
+ buffer_->gaps_.back().begin_offset - buffer_->total_bytes_read_;
+ bool capacity_sane = data_span <= buffer_->max_buffer_capacity_bytes_ &&
+ data_span >= buffer_->num_bytes_buffered_;
+ if (!capacity_sane) {
+ LOG(ERROR) << "data span is larger than capacity.";
+ LOG(ERROR) << "total read: " << buffer_->total_bytes_read_
+ << " last byte: " << buffer_->gaps_.back().begin_offset;
+ }
+ bool total_read_sane =
+ buffer_->gaps_.front().begin_offset >= buffer_->total_bytes_read_;
+ if (!total_read_sane) {
+ LOG(ERROR) << "read across 1st gap.";
+ }
+ bool read_offset_sane = buffer_->ReadOffset() < kBlockSizeBytes;
+ if (!capacity_sane) {
+ LOG(ERROR) << "read offset go beyond 1st block";
+ }
+ bool block_match_capacity =
+ (buffer_->max_buffer_capacity_bytes_ <=
+ buffer_->blocks_count_ * kBlockSizeBytes) &&
+ (buffer_->max_buffer_capacity_bytes_ >
+ (buffer_->blocks_count_ - 1) * kBlockSizeBytes);
+ if (!capacity_sane) {
+ LOG(ERROR) << "block number not match capcaity.";
+ }
+ bool block_retired_when_empty = CheckEmptyInvariants();
+ if (!block_retired_when_empty) {
+ LOG(ERROR) << "block is not retired after use.";
+ }
+ return capacity_sane && total_read_sane && read_offset_sane &&
+ block_match_capacity && block_retired_when_empty;
+ }
+
+ size_t GetInBlockOffset(QuicStreamOffset offset) {
+ return buffer_->GetInBlockOffset(offset);
+ }
+
+ BufferBlock* GetBlock(size_t index) { return buffer_->blocks_[index]; }
+
+ int GapSize() { return buffer_->gaps_.size(); }
+
+ std::list<Gap> GetGaps() { return buffer_->gaps_; }
+
+ size_t max_buffer_capacity() { return buffer_->max_buffer_capacity_bytes_; }
+
+ size_t ReadableBytes() { return buffer_->ReadableBytes(); }
+
+ std::map<QuicStreamOffset, FrameInfo>* frame_arrival_time_map() {
+ return &(buffer_->frame_arrival_time_map_);
+ }
+
+ private:
+ StreamSequencerBuffer* buffer_;
+};
+
+namespace {
+
+class StreamSequencerBufferTest : public testing::Test {
+ public:
+ void SetUp() override { Initialize(); }
+
+ void ResetMaxCapacityBytes(size_t max_capacity_bytes) {
+ max_capacity_bytes_ = max_capacity_bytes;
+ Initialize();
+ }
+
+ protected:
+ void Initialize() {
+ buffer_.reset(new StreamSequencerBuffer(max_capacity_bytes_));
+ helper_.reset(new StreamSequencerBufferPeer(buffer_.get()));
+ }
+
+ // Use 2.5 here to make sure the buffer has more than one block and its end
+ // doesn't align with the end of a block in order to test all the offset
+ // calculation.
+ size_t max_capacity_bytes_ = 2.5 * kBlockSizeBytes;
+
+ MockClock clock_;
+ std::unique_ptr<StreamSequencerBuffer> buffer_;
+ std::unique_ptr<StreamSequencerBufferPeer> helper_;
+};
+
+TEST_F(StreamSequencerBufferTest, InitializationWithDifferentSizes) {
+ const size_t kCapacity = 2 * StreamSequencerBuffer::kBlockSizeBytes;
+ ResetMaxCapacityBytes(kCapacity);
+ EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
+ EXPECT_TRUE(helper_->CheckInitialState());
+
+ const size_t kCapacity1 = 8 * StreamSequencerBuffer::kBlockSizeBytes;
+ ResetMaxCapacityBytes(kCapacity1);
+ EXPECT_EQ(kCapacity1, helper_->max_buffer_capacity());
+ EXPECT_TRUE(helper_->CheckInitialState());
+}
+
+TEST_F(StreamSequencerBufferTest, ClearOnEmpty) {
+ buffer_->Clear();
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamData0length) {
+ std::string source;
+ size_t written;
+ EXPECT_DFATAL(
+ buffer_->OnStreamData(800, source, clock_.ApproximateNow(), &written),
+ "Attempted to write 0 bytes of data.");
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataWithinBlock) {
+ std::string source(1024, 'a');
+ size_t written;
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t = clock_.ApproximateNow();
+ EXPECT_EQ(QUIC_NO_ERROR, buffer_->OnStreamData(800, source, t, &written));
+ BufferBlock* block_ptr = helper_->GetBlock(0);
+ for (size_t i = 0; i < source.size(); ++i) {
+ ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
+ }
+ EXPECT_EQ(2, helper_->GapSize());
+ std::list<Gap> gaps = helper_->GetGaps();
+ EXPECT_EQ(800u, gaps.front().end_offset);
+ EXPECT_EQ(1824u, gaps.back().begin_offset);
+ auto frame_map = helper_->frame_arrival_time_map();
+ EXPECT_EQ(1u, frame_map->size());
+ EXPECT_EQ(800u, frame_map->begin()->first);
+ EXPECT_EQ(t, (*frame_map)[800].timestamp);
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataWithOverlap) {
+ std::string source(1024, 'a');
+ // Write something into [800, 1824)
+ size_t written;
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t1 = clock_.ApproximateNow();
+ EXPECT_EQ(QUIC_NO_ERROR, buffer_->OnStreamData(800, source, t1, &written));
+ // Try to write to [0, 1024) and [1024, 2048).
+ // But no byte will be written since overlap.
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t2 = clock_.ApproximateNow();
+ EXPECT_EQ(QUIC_INVALID_STREAM_DATA,
+ buffer_->OnStreamData(0, source, t2, &written));
+ EXPECT_EQ(QUIC_INVALID_STREAM_DATA,
+ buffer_->OnStreamData(1024, source, t2, &written));
+ auto frame_map = helper_->frame_arrival_time_map();
+ EXPECT_EQ(1u, frame_map->size());
+ EXPECT_EQ(t1, (*frame_map)[800].timestamp);
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataOverlapAndDuplicateCornerCases) {
+ std::string source(1024, 'a');
+ // Write something into [800, 1824)
+ size_t written;
+ buffer_->OnStreamData(800, source, clock_.ApproximateNow(), &written);
+ source = std::string(800, 'b');
+ // Try to write to [1, 801), but should fail due to overlapping
+ EXPECT_EQ(
+ QUIC_INVALID_STREAM_DATA,
+ buffer_->OnStreamData(1, source, clock_.ApproximateNow(), &written));
+ // write to [0, 800)
+ EXPECT_EQ(QUIC_NO_ERROR, buffer_->OnStreamData(
+ 0, source, clock_.ApproximateNow(), &written));
+ // Try to write one byte to [1823, 1824), but should count as duplicate
+ std::string one_byte = "c";
+ EXPECT_EQ(
+ QUIC_NO_ERROR,
+ buffer_->OnStreamData(1823, one_byte, clock_.ApproximateNow(), &written));
+ EXPECT_EQ(0u, written);
+ // write one byte to [1824, 1825)
+ EXPECT_EQ(
+ QUIC_NO_ERROR,
+ buffer_->OnStreamData(1824, one_byte, clock_.ApproximateNow(), &written));
+ auto frame_map = helper_->frame_arrival_time_map();
+ EXPECT_EQ(3u, frame_map->size());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataWithoutOverlap) {
+ std::string source(1024, 'a');
+ // Write something into [800, 1824).
+ size_t written;
+ EXPECT_EQ(QUIC_NO_ERROR, buffer_->OnStreamData(
+ 800, source, clock_.ApproximateNow(), &written));
+ source = std::string(100, 'b');
+ // Write something into [kBlockSizeBytes * 2 - 20, kBlockSizeBytes * 2 + 80).
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(kBlockSizeBytes * 2 - 20, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_EQ(3, helper_->GapSize());
+ EXPECT_EQ(1024u + 100u, buffer_->BytesBuffered());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataTillEnd) {
+ // Write 50 bytes to the end.
+ const size_t kBytesToWrite = 50;
+ std::string source(kBytesToWrite, 'a');
+ size_t written;
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_EQ(50u, buffer_->BytesBuffered());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataTillEndCorner) {
+ // Write 1 byte to the end.
+ const size_t kBytesToWrite = 1;
+ std::string source(kBytesToWrite, 'a');
+ size_t written;
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_EQ(1u, buffer_->BytesBuffered());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataBeyondCapacity) {
+ std::string source(60, 'a');
+ size_t written;
+ EXPECT_EQ(QUIC_INTERNAL_ERROR,
+ buffer_->OnStreamData(max_capacity_bytes_ - 50, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+ source = "b";
+ EXPECT_EQ(QUIC_INTERNAL_ERROR,
+ buffer_->OnStreamData(max_capacity_bytes_, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+ EXPECT_EQ(QUIC_INTERNAL_ERROR,
+ buffer_->OnStreamData(max_capacity_bytes_ * 1000, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+ EXPECT_EQ(0u, buffer_->BytesBuffered());
+}
+
+TEST_F(StreamSequencerBufferTest, Readv100Bytes) {
+ std::string source(1024, 'a');
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t1 = clock_.ApproximateNow();
+ // Write something into [kBlockSizeBytes, kBlockSizeBytes + 1024).
+ size_t written;
+ buffer_->OnStreamData(kBlockSizeBytes, source, t1, &written);
+ EXPECT_FALSE(buffer_->HasBytesToRead());
+ source = std::string(100, 'b');
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t2 = clock_.ApproximateNow();
+ // Write something into [0, 100).
+ buffer_->OnStreamData(0, source, t2, &written);
+ EXPECT_TRUE(buffer_->HasBytesToRead());
+ EXPECT_EQ(2u, helper_->frame_arrival_time_map()->size());
+ // Read into a iovec array with total capacity of 120 bytes.
+ char dest[120];
+ iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
+ size_t read = buffer_->Readv(iovecs, 3);
+ EXPECT_EQ(100u, read);
+ EXPECT_EQ(100u, buffer_->BytesConsumed());
+ EXPECT_EQ(source, std::string(dest, read));
+ EXPECT_EQ(1u, helper_->frame_arrival_time_map()->size());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, ReadvAcrossBlocks) {
+ std::string source(kBlockSizeBytes + 50, 'a');
+ // Write 1st block to full and extand 50 bytes to next block.
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ EXPECT_EQ(source.size(), helper_->ReadableBytes());
+ // Iteratively read 512 bytes from buffer_-> Overwrite dest[] each time.
+ char dest[512];
+ while (helper_->ReadableBytes()) {
+ std::fill(dest, dest + 512, 0);
+ iovec iovecs[2]{iovec{dest, 256}, iovec{dest + 256, 256}};
+ buffer_->Readv(iovecs, 2);
+ }
+ // The last read only reads the rest 50 bytes in 2nd block.
+ EXPECT_EQ(std::string(50, 'a'), std::string(dest, 50));
+ EXPECT_EQ(0, dest[50]) << "Dest[50] shouln't be filled.";
+ EXPECT_EQ(source.size(), buffer_->BytesConsumed());
+ EXPECT_TRUE(buffer_->Empty());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, ClearAfterRead) {
+ std::string source(kBlockSizeBytes + 50, 'a');
+ // Write 1st block to full with 'a'.
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ // Read first 512 bytes from buffer to make space at the beginning.
+ char dest[512]{0};
+ const iovec iov{dest, 512};
+ buffer_->Readv(&iov, 1);
+ // Clear() should make buffer empty while preserving BytesConsumed()
+ buffer_->Clear();
+ EXPECT_TRUE(buffer_->Empty());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, OnStreamDataAcrossLastBlockAndFillCapacity) {
+ std::string source(kBlockSizeBytes + 50, 'a');
+ // Write 1st block to full with 'a'.
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ // Read first 512 bytes from buffer to make space at the beginning.
+ char dest[512]{0};
+ const iovec iov{dest, 512};
+ buffer_->Readv(&iov, 1);
+ EXPECT_EQ(source.size(), written);
+
+ // Write more than half block size of bytes in the last block with 'b', which
+ // will wrap to the beginning and reaches the full capacity.
+ source = std::string(0.5 * kBlockSizeBytes + 512, 'b');
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(2 * kBlockSizeBytes, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_EQ(source.size(), written);
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest,
+ OnStreamDataAcrossLastBlockAndExceedCapacity) {
+ std::string source(kBlockSizeBytes + 50, 'a');
+ // Write 1st block to full.
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ // Read first 512 bytes from buffer to make space at the beginning.
+ char dest[512]{0};
+ const iovec iov{dest, 512};
+ buffer_->Readv(&iov, 1);
+
+ // Try to write from [max_capacity_bytes_ - 0.5 * kBlockSizeBytes,
+ // max_capacity_bytes_ + 512 + 1). But last bytes exceeds current capacity.
+ source = std::string(0.5 * kBlockSizeBytes + 512 + 1, 'b');
+ EXPECT_EQ(QUIC_INTERNAL_ERROR,
+ buffer_->OnStreamData(2 * kBlockSizeBytes, source,
+ clock_.ApproximateNow(), &written));
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, ReadvAcrossLastBlock) {
+ // Write to full capacity and read out 512 bytes at beginning and continue
+ // appending 256 bytes.
+ std::string source(max_capacity_bytes_, 'a');
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t = clock_.ApproximateNow();
+ size_t written;
+ buffer_->OnStreamData(0, source, t, &written);
+ char dest[512]{0};
+ const iovec iov{dest, 512};
+ buffer_->Readv(&iov, 1);
+ source = std::string(256, 'b');
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t2 = clock_.ApproximateNow();
+ buffer_->OnStreamData(max_capacity_bytes_, source, t2, &written);
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+ EXPECT_EQ(2u, helper_->frame_arrival_time_map()->size());
+
+ // Read all data out.
+ std::unique_ptr<char[]> dest1{new char[max_capacity_bytes_]{0}};
+ const iovec iov1{dest1.get(), max_capacity_bytes_};
+ EXPECT_EQ(max_capacity_bytes_ - 512 + 256, buffer_->Readv(&iov1, 1));
+ EXPECT_EQ(max_capacity_bytes_ + 256, buffer_->BytesConsumed());
+ EXPECT_TRUE(buffer_->Empty());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+ EXPECT_EQ(0u, helper_->frame_arrival_time_map()->size());
+}
+
+TEST_F(StreamSequencerBufferTest, ReadvEmpty) {
+ char dest[512]{0};
+ iovec iov{dest, 512};
+ size_t read = buffer_->Readv(&iov, 1);
+ EXPECT_EQ(0u, read);
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionsEmpty) {
+ iovec iovs[2];
+ int iov_count = buffer_->GetReadableRegions(iovs, 2);
+ EXPECT_EQ(0, iov_count);
+ EXPECT_EQ(nullptr, iovs[iov_count].iov_base);
+ EXPECT_EQ(0u, iovs[iov_count].iov_len);
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionsBlockedByGap) {
+ // Write into [1, 1024).
+ std::string source(1023, 'a');
+ size_t written;
+ buffer_->OnStreamData(1, source, clock_.ApproximateNow(), &written);
+ // Try to get readable regions, but none is there.
+ iovec iovs[2];
+ int iov_count = buffer_->GetReadableRegions(iovs, 2);
+ EXPECT_EQ(0, iov_count);
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionsTillEndOfBlock) {
+ // Write first block to full with [0, 256) 'a' and the rest 'b' then read out
+ // [0, 256)
+ std::string source(kBlockSizeBytes, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[256];
+ helper_->Read(dest, 256);
+ // Get readable region from [256, 1024)
+ iovec iovs[2];
+ int iov_count = buffer_->GetReadableRegions(iovs, 2);
+ EXPECT_EQ(1, iov_count);
+ EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'),
+ std::string(reinterpret_cast<const char*>(iovs[0].iov_base),
+ iovs[0].iov_len));
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionsWithinOneBlock) {
+ // Write into [0, 1024) and then read out [0, 256)
+ std::string source(1024, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[256];
+ helper_->Read(dest, 256);
+ // Get readable region from [256, 1024)
+ iovec iovs[2];
+ int iov_count = buffer_->GetReadableRegions(iovs, 2);
+ EXPECT_EQ(1, iov_count);
+ EXPECT_EQ(std::string(1024 - 256, 'a'),
+ std::string(reinterpret_cast<const char*>(iovs[0].iov_base),
+ iovs[0].iov_len));
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionsAcrossBlockWithLongIOV) {
+ // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
+ std::string source(2 * kBlockSizeBytes + 1024, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[1024];
+ helper_->Read(dest, 1024);
+
+ iovec iovs[4];
+ int iov_count = buffer_->GetReadableRegions(iovs, 4);
+ EXPECT_EQ(3, iov_count);
+ EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
+ EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
+ EXPECT_EQ(1024u, iovs[2].iov_len);
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionsWithMultipleIOVsAcrossEnd) {
+ // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
+ // and then append 1024 + 512 bytes.
+ std::string source(2.5 * kBlockSizeBytes - 1024, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[1024];
+ helper_->Read(dest, 1024);
+ // Write across the end.
+ source = std::string(1024 + 512, 'b');
+ buffer_->OnStreamData(2.5 * kBlockSizeBytes - 1024, source,
+ clock_.ApproximateNow(), &written);
+ // Use short iovec's.
+ iovec iovs[2];
+ int iov_count = buffer_->GetReadableRegions(iovs, 2);
+ EXPECT_EQ(2, iov_count);
+ EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
+ EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
+ // Use long iovec's and wrap the end of buffer.
+ iovec iovs1[5];
+ EXPECT_EQ(4, buffer_->GetReadableRegions(iovs1, 5));
+ EXPECT_EQ(0.5 * kBlockSizeBytes, iovs1[2].iov_len);
+ EXPECT_EQ(512u, iovs1[3].iov_len);
+ EXPECT_EQ(std::string(512, 'b'),
+ std::string(reinterpret_cast<const char*>(iovs1[3].iov_base),
+ iovs1[3].iov_len));
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionEmpty) {
+ iovec iov;
+ QuicTime t = QuicTime::Zero();
+ EXPECT_FALSE(buffer_->GetReadableRegion(&iov, &t));
+ EXPECT_EQ(nullptr, iov.iov_base);
+ EXPECT_EQ(0u, iov.iov_len);
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionBeforeGap) {
+ // Write into [1, 1024).
+ std::string source(1023, 'a');
+ size_t written;
+ buffer_->OnStreamData(1, source, clock_.ApproximateNow(), &written);
+ // GetReadableRegion should return false because range [0,1) hasn't been
+ // filled yet.
+ iovec iov;
+ QuicTime t = QuicTime::Zero();
+ EXPECT_FALSE(buffer_->GetReadableRegion(&iov, &t));
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionTillEndOfBlock) {
+ // Write into [0, kBlockSizeBytes + 1) and then read out [0, 256)
+ std::string source(kBlockSizeBytes + 1, 'a');
+ size_t written;
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t = clock_.ApproximateNow();
+ buffer_->OnStreamData(0, source, t, &written);
+ char dest[256];
+ helper_->Read(dest, 256);
+ // Get readable region from [256, 1024)
+ iovec iov;
+ QuicTime t2 = QuicTime::Zero();
+ EXPECT_TRUE(buffer_->GetReadableRegion(&iov, &t2));
+ EXPECT_EQ(t, t2);
+ EXPECT_EQ(
+ std::string(kBlockSizeBytes - 256, 'a'),
+ std::string(reinterpret_cast<const char*>(iov.iov_base), iov.iov_len));
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionTillGap) {
+ // Write into [0, kBlockSizeBytes - 1) and then read out [0, 256)
+ std::string source(kBlockSizeBytes - 1, 'a');
+ size_t written;
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t = clock_.ApproximateNow();
+ buffer_->OnStreamData(0, source, t, &written);
+ char dest[256];
+ helper_->Read(dest, 256);
+ // Get readable region from [256, 1023)
+ iovec iov;
+ QuicTime t2 = QuicTime::Zero();
+ EXPECT_TRUE(buffer_->GetReadableRegion(&iov, &t2));
+ EXPECT_EQ(t, t2);
+ EXPECT_EQ(
+ std::string(kBlockSizeBytes - 1 - 256, 'a'),
+ std::string(reinterpret_cast<const char*>(iov.iov_base), iov.iov_len));
+}
+
+TEST_F(StreamSequencerBufferTest, GetReadableRegionByArrivalTime) {
+ // Write into [0, kBlockSizeBytes - 100) and then read out [0, 256)
+ std::string source(kBlockSizeBytes - 100, 'a');
+ size_t written;
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t = clock_.ApproximateNow();
+ buffer_->OnStreamData(0, source, t, &written);
+ char dest[256];
+ helper_->Read(dest, 256);
+ // Write into [kBlockSizeBytes - 100, kBlockSizeBytes - 50)] in same time
+ std::string source2(50, 'b');
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ buffer_->OnStreamData(kBlockSizeBytes - 100, source2, t, &written);
+
+ // Write into [kBlockSizeBytes - 50, kBlockSizeBytes)] in another time
+ std::string source3(50, 'c');
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ QuicTime t3 = clock_.ApproximateNow();
+ buffer_->OnStreamData(kBlockSizeBytes - 50, source3, t3, &written);
+
+ // Get readable region from [256, 1024 - 50)
+ iovec iov;
+ QuicTime t4 = QuicTime::Zero();
+ EXPECT_TRUE(buffer_->GetReadableRegion(&iov, &t4));
+ EXPECT_EQ(t, t4);
+ EXPECT_EQ(
+ std::string(kBlockSizeBytes - 100 - 256, 'a') + source2,
+ std::string(reinterpret_cast<const char*>(iov.iov_base), iov.iov_len));
+}
+
+TEST_F(StreamSequencerBufferTest, MarkConsumedInOneBlock) {
+ // Write into [0, 1024) and then read out [0, 256)
+ std::string source(1024, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[256];
+ helper_->Read(dest, 256);
+
+ EXPECT_TRUE(buffer_->MarkConsumed(512));
+ EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+ EXPECT_EQ(256u, helper_->ReadableBytes());
+ EXPECT_EQ(1u, helper_->frame_arrival_time_map()->size());
+ buffer_->MarkConsumed(256);
+ EXPECT_EQ(0u, helper_->frame_arrival_time_map()->size());
+ EXPECT_TRUE(buffer_->Empty());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, MarkConsumedNotEnoughBytes) {
+ // Write into [0, 1024) and then read out [0, 256)
+ std::string source(1024, 'a');
+ size_t written;
+ QuicTime t = clock_.ApproximateNow();
+ buffer_->OnStreamData(0, source, t, &written);
+ char dest[256];
+ helper_->Read(dest, 256);
+
+ // Consume 1st 512 bytes
+ EXPECT_TRUE(buffer_->MarkConsumed(512));
+ EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+ EXPECT_EQ(256u, helper_->ReadableBytes());
+ // Try to consume one bytes more than available. Should return false.
+ EXPECT_FALSE(buffer_->MarkConsumed(257));
+ EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+ QuicTime t2 = QuicTime::Zero();
+ iovec iov;
+ EXPECT_TRUE(buffer_->GetReadableRegion(&iov, &t2));
+ EXPECT_EQ(t, t2);
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, MarkConsumedAcrossBlock) {
+ // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
+ std::string source(2 * kBlockSizeBytes + 1024, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[1024];
+ helper_->Read(dest, 1024);
+
+ buffer_->MarkConsumed(2 * kBlockSizeBytes);
+ EXPECT_EQ(source.size(), buffer_->BytesConsumed());
+ EXPECT_TRUE(buffer_->Empty());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, MarkConsumedAcrossEnd) {
+ // Write into [0, 2.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
+ // and then append 1024 + 512 bytes.
+ std::string source(2.5 * kBlockSizeBytes - 1024, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[1024];
+ helper_->Read(dest, 1024);
+ source = std::string(1024 + 512, 'b');
+ buffer_->OnStreamData(2.5 * kBlockSizeBytes - 1024, source,
+ clock_.ApproximateNow(), &written);
+ EXPECT_EQ(1024u, buffer_->BytesConsumed());
+
+ // Consume to the end of 2nd block.
+ buffer_->MarkConsumed(2 * kBlockSizeBytes - 1024);
+ EXPECT_EQ(2 * kBlockSizeBytes, buffer_->BytesConsumed());
+ // Consume across the physical end of buffer
+ buffer_->MarkConsumed(0.5 * kBlockSizeBytes + 500);
+ EXPECT_EQ(max_capacity_bytes_ + 500, buffer_->BytesConsumed());
+ EXPECT_EQ(12u, helper_->ReadableBytes());
+ // Consume to the logical end of buffer
+ buffer_->MarkConsumed(12);
+ EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+ EXPECT_TRUE(buffer_->Empty());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(StreamSequencerBufferTest, FlushBufferedFrames) {
+ // Write into [0, 2.5 * kBlockSizeBytes - 1024) and then read out [0, 1024).
+ std::string source(max_capacity_bytes_ - 1024, 'a');
+ size_t written;
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written);
+ char dest[1024];
+ helper_->Read(dest, 1024);
+ EXPECT_EQ(1024u, buffer_->BytesConsumed());
+ // Write [1024, 512) to the physical beginning.
+ source = std::string(512, 'b');
+ buffer_->OnStreamData(max_capacity_bytes_, source, clock_.ApproximateNow(),
+ &written);
+ EXPECT_EQ(512u, written);
+ EXPECT_EQ(max_capacity_bytes_ - 1024 + 512, buffer_->FlushBufferedFrames());
+ EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+ EXPECT_TRUE(buffer_->Empty());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+ // Clear buffer at this point should still preserve BytesConsumed().
+ buffer_->Clear();
+ EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+class StreamSequencerBufferRandomIOTest : public StreamSequencerBufferTest {
+ public:
+ typedef std::pair<QuicStreamOffset, size_t> OffsetSizePair;
+
+ void SetUp() override {
+ // Test against a larger capacity then above tests. Also make sure the last
+ // block is partially available to use.
+ max_capacity_bytes_ = 6.25 * kBlockSizeBytes;
+ // Stream to be buffered should be larger than the capacity to test wrap
+ // around.
+ bytes_to_buffer_ = 2 * max_capacity_bytes_;
+ Initialize();
+
+ uint32_t seed = base::RandInt(0, std::numeric_limits<int32_t>::max());
+ LOG(INFO) << "RandomWriteAndProcessInPlace test seed is " << seed;
+ rng_.set_seed(seed);
+ }
+
+ // Create an out-of-order source stream with given size to populate
+ // shuffled_buf_.
+ void CreateSourceAndShuffle(size_t max_chunk_size_bytes) {
+ max_chunk_size_bytes_ = max_chunk_size_bytes;
+ std::unique_ptr<OffsetSizePair[]> chopped_stream(
+ new OffsetSizePair[bytes_to_buffer_]);
+
+ // Split stream into small chunks with random length. chopped_stream will be
+ // populated with segmented stream chunks.
+ size_t start_chopping_offset = 0;
+ size_t iterations = 0;
+ while (start_chopping_offset < bytes_to_buffer_) {
+ size_t max_chunk = min<size_t>(max_chunk_size_bytes_,
+ bytes_to_buffer_ - start_chopping_offset);
+ size_t chunk_size = rng_.RandUint64() % max_chunk + 1;
+ chopped_stream[iterations] =
+ OffsetSizePair(start_chopping_offset, chunk_size);
+ start_chopping_offset += chunk_size;
+ ++iterations;
+ }
+ DCHECK(start_chopping_offset == bytes_to_buffer_);
+ size_t chunk_num = iterations;
+
+ // Randomly change the sequence of in-ordered OffsetSizePairs to make a
+ // out-of-order array of OffsetSizePairs.
+ for (int i = chunk_num - 1; i >= 0; --i) {
+ size_t random_idx = rng_.RandUint64() % (i + 1);
+ DVLOG(1) << "chunk offset " << chopped_stream[random_idx].first
+ << " size " << chopped_stream[random_idx].second;
+ shuffled_buf_.push_front(chopped_stream[random_idx]);
+ chopped_stream[random_idx] = chopped_stream[i];
+ }
+ }
+
+ // Write the currently first chunk of data in the out-of-order stream into
+ // StreamSequencerBuffer. If current chuck cannot be written into buffer
+ // because it goes beyond current capacity, move it to the end of
+ // shuffled_buf_ and write it later.
+ void WriteNextChunkToBuffer() {
+ OffsetSizePair& chunk = shuffled_buf_.front();
+ QuicStreamOffset offset = chunk.first;
+ const size_t num_to_write = chunk.second;
+ std::unique_ptr<char[]> write_buf{new char[max_chunk_size_bytes_]};
+ for (size_t i = 0; i < num_to_write; ++i) {
+ write_buf[i] = (offset + i) % 256;
+ }
+ base::StringPiece string_piece_w(write_buf.get(), num_to_write);
+ size_t written;
+ auto result = buffer_->OnStreamData(offset, string_piece_w,
+ clock_.ApproximateNow(), &written);
+ if (result == QUIC_NO_ERROR) {
+ shuffled_buf_.pop_front();
+ total_bytes_written_ += num_to_write;
+ } else {
+ // This chunk offset exceeds window size.
+ shuffled_buf_.push_back(chunk);
+ shuffled_buf_.pop_front();
+ }
+ DVLOG(1) << " write at offset: " << offset
+ << " len to write: " << num_to_write << " write result: " << result
+ << " left over: " << shuffled_buf_.size();
+ }
+
+ protected:
+ std::list<OffsetSizePair> shuffled_buf_;
+ size_t max_chunk_size_bytes_;
+ QuicStreamOffset bytes_to_buffer_;
+ size_t total_bytes_written_ = 0;
+ size_t total_bytes_read_ = 0;
+ SimpleRandom rng_;
+};
+
+TEST_F(StreamSequencerBufferRandomIOTest, RandomWriteAndReadv) {
+ // Set kMaxReadSize larger than kBlockSizeBytes to test both small and large
+ // read.
+ const size_t kMaxReadSize = kBlockSizeBytes * 2;
+ // kNumReads is larger than 1 to test how multiple read destinations work.
+ const size_t kNumReads = 2;
+ // Since write and read operation have equal possibility to be called. Bytes
+ // to be written into and read out of should roughly the same.
+ const size_t kMaxWriteSize = kNumReads * kMaxReadSize;
+ size_t iterations = 0;
+
+ CreateSourceAndShuffle(kMaxWriteSize);
+
+ while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
+ iterations <= 2 * bytes_to_buffer_) {
+ uint8_t next_action =
+ shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
+ DVLOG(1) << "iteration: " << iterations;
+ switch (next_action) {
+ case 0: { // write
+ WriteNextChunkToBuffer();
+ ASSERT_TRUE(helper_->CheckBufferInvariants());
+ break;
+ }
+ case 1: { // readv
+ std::unique_ptr<char[][kMaxReadSize]> read_buf{
+ new char[kNumReads][kMaxReadSize]};
+ iovec dest_iov[kNumReads];
+ size_t num_to_read = 0;
+ for (size_t i = 0; i < kNumReads; ++i) {
+ dest_iov[i].iov_base =
+ reinterpret_cast<void*>(const_cast<char*>(read_buf[i]));
+ dest_iov[i].iov_len = rng_.RandUint64() % kMaxReadSize;
+ num_to_read += dest_iov[i].iov_len;
+ }
+ size_t actually_read = buffer_->Readv(dest_iov, kNumReads);
+ ASSERT_LE(actually_read, num_to_read);
+ DVLOG(1) << " read from offset: " << total_bytes_read_
+ << " size: " << num_to_read
+ << " actual read: " << actually_read;
+ for (size_t i = 0; i < actually_read; ++i) {
+ char ch = (i + total_bytes_read_) % 256;
+ ASSERT_EQ(ch, GetCharFromIOVecs(i, dest_iov, kNumReads))
+ << " at iteration " << iterations;
+ }
+ total_bytes_read_ += actually_read;
+ ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
+ ASSERT_TRUE(helper_->CheckBufferInvariants());
+ break;
+ }
+ }
+ ++iterations;
+ ASSERT_LE(total_bytes_read_, total_bytes_written_);
+ }
+ EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
+ EXPECT_LE(bytes_to_buffer_, total_bytes_read_) << "iterations: "
+ << iterations;
+ EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
+}
+
+TEST_F(StreamSequencerBufferRandomIOTest, RandomWriteAndConsumeInPlace) {
+ // The value 4 is chosen such that the max write size is no larger than the
+ // maximum buffer capacity.
+ const size_t kMaxNumReads = 4;
+ // Adjust write amount be roughly equal to that GetReadableRegions() can get.
+ const size_t kMaxWriteSize = kMaxNumReads * kBlockSizeBytes;
+ ASSERT_LE(kMaxWriteSize, max_capacity_bytes_);
+ size_t iterations = 0;
+
+ CreateSourceAndShuffle(kMaxWriteSize);
+
+ while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
+ iterations <= 2 * bytes_to_buffer_) {
+ uint8_t next_action =
+ shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
+ DVLOG(1) << "iteration: " << iterations;
+ switch (next_action) {
+ case 0: { // write
+ WriteNextChunkToBuffer();
+ ASSERT_TRUE(helper_->CheckBufferInvariants());
+ break;
+ }
+ case 1: { // GetReadableRegions and then MarkConsumed
+ size_t num_read = rng_.RandUint64() % kMaxNumReads + 1;
+ iovec dest_iov[kMaxNumReads];
+ ASSERT_TRUE(helper_->CheckBufferInvariants());
+ size_t actually_num_read =
+ buffer_->GetReadableRegions(dest_iov, num_read);
+ ASSERT_LE(actually_num_read, num_read);
+ size_t avail_bytes = 0;
+ for (size_t i = 0; i < actually_num_read; ++i) {
+ avail_bytes += dest_iov[i].iov_len;
+ }
+ // process random number of bytes (check the value of each byte).
+ size_t bytes_to_process = rng_.RandUint64() % (avail_bytes + 1);
+ size_t bytes_processed = 0;
+ for (size_t i = 0; i < actually_num_read; ++i) {
+ size_t bytes_in_block = min<size_t>(
+ bytes_to_process - bytes_processed, dest_iov[i].iov_len);
+ if (bytes_in_block == 0) {
+ break;
+ }
+ for (size_t j = 0; j < bytes_in_block; ++j) {
+ ASSERT_LE(bytes_processed, bytes_to_process);
+ char char_expected =
+ (buffer_->BytesConsumed() + bytes_processed) % 256;
+ ASSERT_EQ(char_expected,
+ reinterpret_cast<const char*>(dest_iov[i].iov_base)[j])
+ << " at iteration " << iterations;
+ ++bytes_processed;
+ }
+ }
+
+ buffer_->MarkConsumed(bytes_processed);
+
+ DVLOG(1) << "iteration " << iterations << ": try to get " << num_read
+ << " readable regions, actually get " << actually_num_read
+ << " from offset: " << total_bytes_read_
+ << "\nprocesse bytes: " << bytes_processed;
+ total_bytes_read_ += bytes_processed;
+ ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
+ ASSERT_TRUE(helper_->CheckBufferInvariants());
+ break;
+ }
+ }
+ ++iterations;
+ ASSERT_LE(total_bytes_read_, total_bytes_written_);
+ }
+ EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
+ EXPECT_LE(bytes_to_buffer_, total_bytes_read_) << "iterations: "
+ << iterations;
+ EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
+}
+
+} // anonymous namespace
+
+} // namespace test
+
+} // namespace net
diff --git a/chromium/net/quic/test_tools/crypto_test_utils.cc b/chromium/net/quic/test_tools/crypto_test_utils.cc
index 0ab55f1f399..8f46d92144f 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils.cc
+++ b/chromium/net/quic/test_tools/crypto_test_utils.cc
@@ -35,9 +35,7 @@ namespace {
// CryptoFramerVisitor is a framer visitor that records handshake messages.
class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
public:
- CryptoFramerVisitor()
- : error_(false) {
- }
+ CryptoFramerVisitor() : error_(false) {}
void OnError(CryptoFramer* framer) override { error_ = true; }
@@ -45,67 +43,18 @@ class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
messages_.push_back(message);
}
- bool error() const {
- return error_;
- }
+ bool error() const { return error_; }
- const vector<CryptoHandshakeMessage>& messages() const {
- return messages_;
- }
+ const vector<CryptoHandshakeMessage>& messages() const { return messages_; }
private:
bool error_;
vector<CryptoHandshakeMessage> messages_;
};
-// MovePackets parses crypto handshake messages from packet number
-// |*inout_packet_index| through to the last packet (or until a packet fails to
-// decrypt) and has |dest_stream| process them. |*inout_packet_index| is updated
-// with an index one greater than the last packet processed.
-void MovePackets(PacketSavingConnection* source_conn,
- size_t *inout_packet_index,
- QuicCryptoStream* dest_stream,
- PacketSavingConnection* dest_conn) {
- SimpleQuicFramer framer(source_conn->supported_versions());
- CryptoFramer crypto_framer;
- CryptoFramerVisitor crypto_visitor;
-
- // In order to properly test the code we need to perform encryption and
- // decryption so that the crypters latch when expected. The crypters are in
- // |dest_conn|, but we don't want to try and use them there. Instead we swap
- // them into |framer|, perform the decryption with them, and then swap them
- // back.
- QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
-
- crypto_framer.set_visitor(&crypto_visitor);
-
- size_t index = *inout_packet_index;
- for (; index < source_conn->encrypted_packets_.size(); index++) {
- if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
- // The framer will be unable to decrypt forward-secure packets sent after
- // the handshake is complete. Don't treat them as handshake packets.
- break;
- }
-
- for (const QuicStreamFrame& stream_frame : framer.stream_frames()) {
- ASSERT_TRUE(crypto_framer.ProcessInput(stream_frame.data));
- ASSERT_FALSE(crypto_visitor.error());
- }
- }
- *inout_packet_index = index;
-
- QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
-
- ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
-
- for (const CryptoHandshakeMessage& message : crypto_visitor.messages()) {
- dest_stream->OnHandshakeMessage(message);
- }
-}
-
// HexChar parses |c| as a hex character. If valid, it sets |*value| to the
// value of the hex character and returns true. Otherwise it returns false.
-bool HexChar(char c, uint8* value) {
+bool HexChar(char c, uint8_t* value) {
if (c >= '0' && c <= '9') {
*value = c - '0';
return true;
@@ -166,25 +115,30 @@ class AsyncTestChannelIDSource : public ChannelIDSource,
} // anonymous namespace
+CryptoTestUtils::FakeServerOptions::FakeServerOptions()
+ : token_binding_enabled(false) {}
+
CryptoTestUtils::FakeClientOptions::FakeClientOptions()
- : dont_verify_certs(false),
- channel_id_enabled(false),
- channel_id_source_async(false) {
-}
+ : channel_id_enabled(false),
+ channel_id_source_async(false),
+ token_binding_enabled(false) {}
// static
int CryptoTestUtils::HandshakeWithFakeServer(
+ MockConnectionHelper* helper,
PacketSavingConnection* client_conn,
- QuicCryptoClientStream* client) {
+ QuicCryptoClientStream* client,
+ const FakeServerOptions& options) {
PacketSavingConnection* server_conn = new PacketSavingConnection(
- Perspective::IS_SERVER, client_conn->supported_versions());
+ helper, Perspective::IS_SERVER, client_conn->supported_versions());
QuicConfig config = DefaultQuicConfig();
QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance());
+ QuicRandom::GetInstance(),
+ ProofSourceForTesting());
SetupCryptoServerConfigForTest(server_conn->clock(),
server_conn->random_generator(), &config,
- &crypto_config);
+ &crypto_config, options);
TestQuicSpdyServerSession server_session(server_conn, config, &crypto_config);
@@ -193,7 +147,6 @@ int CryptoTestUtils::HandshakeWithFakeServer(
CommunicateHandshakeMessages(client_conn, client, server_conn,
server_session.GetCryptoStream());
-
CompareClientAndServerKeys(client, server_session.GetCryptoStream());
return client->num_sent_client_hellos();
@@ -201,19 +154,19 @@ int CryptoTestUtils::HandshakeWithFakeServer(
// static
int CryptoTestUtils::HandshakeWithFakeClient(
+ MockConnectionHelper* helper,
PacketSavingConnection* server_conn,
QuicCryptoServerStream* server,
const QuicServerId& server_id,
const FakeClientOptions& options) {
PacketSavingConnection* client_conn =
- new PacketSavingConnection(Perspective::IS_CLIENT);
+ new PacketSavingConnection(helper, Perspective::IS_CLIENT);
// Advance the time, because timers do not like uninitialized times.
client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- QuicCryptoClientConfig crypto_config;
+ QuicCryptoClientConfig crypto_config(ProofVerifierForTesting());
AsyncTestChannelIDSource* async_channel_id_source = nullptr;
if (options.channel_id_enabled) {
-
ChannelIDSource* source = ChannelIDSourceForTesting();
if (options.channel_id_source_async) {
async_channel_id_source = new AsyncTestChannelIDSource(source);
@@ -221,13 +174,8 @@ int CryptoTestUtils::HandshakeWithFakeClient(
}
crypto_config.SetChannelIDSource(source);
}
- if (!options.dont_verify_certs && server_id.is_https()) {
-#if defined(USE_OPENSSL)
- crypto_config.SetProofVerifier(ProofVerifierForTesting());
-#else
- // TODO(rch): Implement a NSS proof source.
- crypto_config.SetProofVerifier(FakeProofVerifierForTesting());
-#endif
+ if (options.token_binding_enabled) {
+ crypto_config.tb_key_params.push_back(kP256);
}
TestQuicSpdyClientSession client_session(client_conn, DefaultQuicConfig(),
server_id, &crypto_config);
@@ -261,9 +209,11 @@ void CryptoTestUtils::SetupCryptoServerConfigForTest(
const QuicClock* clock,
QuicRandom* rand,
QuicConfig* config,
- QuicCryptoServerConfig* crypto_config) {
+ QuicCryptoServerConfig* crypto_config,
+ const FakeServerOptions& fake_options) {
QuicCryptoServerConfig::ConfigOptions options;
options.channel_id_enabled = true;
+ options.token_binding_enabled = fake_options.token_binding_enabled;
scoped_ptr<CryptoHandshakeMessage> scfg(
crypto_config->AddDefaultConfig(rand, clock, options));
}
@@ -338,18 +288,15 @@ string CryptoTestUtils::GetValueForTag(const CryptoHandshakeMessage& message,
class MockCommonCertSets : public CommonCertSets {
public:
- MockCommonCertSets(StringPiece cert, uint64 hash, uint32 index)
- : cert_(cert.as_string()),
- hash_(hash),
- index_(index) {
- }
+ MockCommonCertSets(StringPiece cert, uint64_t hash, uint32_t index)
+ : cert_(cert.as_string()), hash_(hash), index_(index) {}
StringPiece GetCommonHashes() const override {
CHECK(false) << "not implemented";
return StringPiece();
}
- StringPiece GetCert(uint64 hash, uint32 index) const override {
+ StringPiece GetCert(uint64_t hash, uint32_t index) const override {
if (hash == hash_ && index == index_) {
return cert_;
}
@@ -358,18 +305,18 @@ class MockCommonCertSets : public CommonCertSets {
bool MatchCert(StringPiece cert,
StringPiece common_set_hashes,
- uint64* out_hash,
- uint32* out_index) const override {
+ uint64_t* out_hash,
+ uint32_t* out_index) const override {
if (cert != cert_) {
return false;
}
- if (common_set_hashes.size() % sizeof(uint64) != 0) {
+ if (common_set_hashes.size() % sizeof(uint64_t) != 0) {
return false;
}
bool client_has_set = false;
- for (size_t i = 0; i < common_set_hashes.size(); i += sizeof(uint64)) {
- uint64 hash;
+ for (size_t i = 0; i < common_set_hashes.size(); i += sizeof(uint64_t)) {
+ uint64_t hash;
memcpy(&hash, common_set_hashes.data() + i, sizeof(hash));
if (hash == hash_) {
client_has_set = true;
@@ -388,13 +335,13 @@ class MockCommonCertSets : public CommonCertSets {
private:
const string cert_;
- const uint64 hash_;
- const uint32 index_;
+ const uint64_t hash_;
+ const uint32_t index_;
};
CommonCertSets* CryptoTestUtils::MockCommonCertSets(StringPiece cert,
- uint64 hash,
- uint32 index) {
+ uint64_t hash,
+ uint32_t index) {
return new class MockCommonCertSets(cert, hash, index);
}
@@ -486,38 +433,31 @@ void CryptoTestUtils::CompareClientAndServerKeys(
StringPiece server_subkey_secret =
server->crypto_negotiated_params().subkey_secret;
-
const char kSampleLabel[] = "label";
const char kSampleContext[] = "context";
const size_t kSampleOutputLength = 32;
string client_key_extraction;
string server_key_extraction;
- EXPECT_TRUE(client->ExportKeyingMaterial(kSampleLabel,
- kSampleContext,
+ EXPECT_TRUE(client->ExportKeyingMaterial(kSampleLabel, kSampleContext,
kSampleOutputLength,
&client_key_extraction));
- EXPECT_TRUE(server->ExportKeyingMaterial(kSampleLabel,
- kSampleContext,
+ EXPECT_TRUE(server->ExportKeyingMaterial(kSampleLabel, kSampleContext,
kSampleOutputLength,
&server_key_extraction));
- CompareCharArraysWithHexError("client write key",
- client_encrypter_key.data(),
+ CompareCharArraysWithHexError("client write key", client_encrypter_key.data(),
client_encrypter_key.length(),
server_decrypter_key.data(),
server_decrypter_key.length());
- CompareCharArraysWithHexError("client write IV",
- client_encrypter_iv.data(),
+ CompareCharArraysWithHexError("client write IV", client_encrypter_iv.data(),
client_encrypter_iv.length(),
server_decrypter_iv.data(),
server_decrypter_iv.length());
- CompareCharArraysWithHexError("server write key",
- server_encrypter_key.data(),
+ CompareCharArraysWithHexError("server write key", server_encrypter_key.data(),
server_encrypter_key.length(),
client_decrypter_key.data(),
client_decrypter_key.length());
- CompareCharArraysWithHexError("server write IV",
- server_encrypter_iv.data(),
+ CompareCharArraysWithHexError("server write IV", server_encrypter_iv.data(),
server_encrypter_iv.length(),
client_decrypter_iv.data(),
client_decrypter_iv.length());
@@ -541,16 +481,14 @@ void CryptoTestUtils::CompareClientAndServerKeys(
server_forward_secure_encrypter_iv.length(),
client_forward_secure_decrypter_iv.data(),
client_forward_secure_decrypter_iv.length());
- CompareCharArraysWithHexError("subkey secret",
- client_subkey_secret.data(),
+ CompareCharArraysWithHexError("subkey secret", client_subkey_secret.data(),
client_subkey_secret.length(),
server_subkey_secret.data(),
server_subkey_secret.length());
- CompareCharArraysWithHexError("sample key extraction",
- client_key_extraction.data(),
- client_key_extraction.length(),
- server_key_extraction.data(),
- server_key_extraction.length());
+ CompareCharArraysWithHexError(
+ "sample key extraction", client_key_extraction.data(),
+ client_key_extraction.length(), server_key_extraction.data(),
+ server_key_extraction.length());
}
// static
@@ -561,13 +499,13 @@ QuicTag CryptoTestUtils::ParseTag(const char* tagstr) {
QuicTag tag = 0;
if (tagstr[0] == '#') {
- CHECK_EQ(static_cast<size_t>(1 + 2*4), len);
+ CHECK_EQ(static_cast<size_t>(1 + 2 * 4), len);
tagstr++;
for (size_t i = 0; i < 8; i++) {
tag <<= 4;
- uint8 v = 0;
+ uint8_t v = 0;
CHECK(HexChar(tagstr[i], &v));
tag |= v;
}
@@ -579,7 +517,7 @@ QuicTag CryptoTestUtils::ParseTag(const char* tagstr) {
for (size_t i = 0; i < 4; i++) {
tag >>= 8;
if (i < len) {
- tag |= static_cast<uint32>(tagstr[i]) << 24;
+ tag |= static_cast<uint32_t>(tagstr[i]) << 24;
}
}
@@ -622,18 +560,18 @@ CryptoHandshakeMessage CryptoTestUtils::Message(const char* message_tag, ...) {
len--;
CHECK_EQ(0u, len % 2);
- scoped_ptr<uint8[]> buf(new uint8[len/2]);
+ scoped_ptr<uint8_t[]> buf(new uint8_t[len / 2]);
- for (size_t i = 0; i < len/2; i++) {
- uint8 v = 0;
- CHECK(HexChar(valuestr[i*2], &v));
+ for (size_t i = 0; i < len / 2; i++) {
+ uint8_t v = 0;
+ CHECK(HexChar(valuestr[i * 2], &v));
buf[i] = v << 4;
- CHECK(HexChar(valuestr[i*2 + 1], &v));
+ CHECK(HexChar(valuestr[i * 2 + 1], &v));
buf[i] |= v;
}
msg.SetStringPiece(
- tag, StringPiece(reinterpret_cast<char*>(buf.get()), len/2));
+ tag, StringPiece(reinterpret_cast<char*>(buf.get()), len / 2));
continue;
}
@@ -651,5 +589,48 @@ CryptoHandshakeMessage CryptoTestUtils::Message(const char* message_tag, ...) {
return *parsed;
}
+// static
+void CryptoTestUtils::MovePackets(PacketSavingConnection* source_conn,
+ size_t* inout_packet_index,
+ QuicCryptoStream* dest_stream,
+ PacketSavingConnection* dest_conn) {
+ SimpleQuicFramer framer(source_conn->supported_versions());
+ CryptoFramer crypto_framer;
+ CryptoFramerVisitor crypto_visitor;
+
+ // In order to properly test the code we need to perform encryption and
+ // decryption so that the crypters latch when expected. The crypters are in
+ // |dest_conn|, but we don't want to try and use them there. Instead we swap
+ // them into |framer|, perform the decryption with them, and then swap ther
+ // back.
+ QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
+
+ crypto_framer.set_visitor(&crypto_visitor);
+
+ size_t index = *inout_packet_index;
+ for (; index < source_conn->encrypted_packets_.size(); index++) {
+ if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
+ // The framer will be unable to decrypt forward-secure packets sent after
+ // the handshake is complete. Don't treat them as handshake packets.
+ break;
+ }
+
+ for (const QuicStreamFrame* stream_frame : framer.stream_frames()) {
+ ASSERT_TRUE(crypto_framer.ProcessInput(
+ StringPiece(stream_frame->frame_buffer, stream_frame->frame_length)));
+ ASSERT_FALSE(crypto_visitor.error());
+ }
+ }
+ *inout_packet_index = index;
+
+ QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
+
+ ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
+
+ for (const CryptoHandshakeMessage& message : crypto_visitor.messages()) {
+ dest_stream->OnHandshakeMessage(message);
+ }
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/crypto_test_utils.h b/chromium/net/quic/test_tools/crypto_test_utils.h
index 38fadaea0ce..6d2ad006954 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils.h
+++ b/chromium/net/quic/test_tools/crypto_test_utils.h
@@ -6,16 +6,19 @@
#define NET_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/quic/crypto/crypto_framer.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
+#include "net/quic/test_tools/quic_test_utils.h"
namespace net {
@@ -53,15 +56,21 @@ class CryptoTestUtils {
virtual void RunPendingCallbacks() = 0;
};
+ // FakeServerOptions bundles together a number of options for configuring the
+ // server in HandshakeWithFakeServer.
+ struct FakeServerOptions {
+ FakeServerOptions();
+
+ // If token_binding_enabled is true, then the server will attempt to
+ // negotiate Token Binding.
+ bool token_binding_enabled;
+ };
+
// FakeClientOptions bundles together a number of options for configuring
// HandshakeWithFakeClient.
struct FakeClientOptions {
FakeClientOptions();
- // If dont_verify_certs is true then no ProofVerifier is set on the client.
- // Thus no certificates will be requested or checked.
- bool dont_verify_certs;
-
// If channel_id_enabled is true then the client will attempt to send a
// ChannelID.
bool channel_id_enabled;
@@ -69,14 +78,21 @@ class CryptoTestUtils {
// If channel_id_source_async is true then the client will use an async
// ChannelIDSource for testing. Ignored if channel_id_enabled is false.
bool channel_id_source_async;
+
+ // If token_binding_enabled is true, then the client will attempt to
+ // negotiate Token Binding.
+ bool token_binding_enabled;
};
// returns: the number of client hellos that the client sent.
- static int HandshakeWithFakeServer(PacketSavingConnection* client_conn,
- QuicCryptoClientStream* client);
+ static int HandshakeWithFakeServer(MockConnectionHelper* helper,
+ PacketSavingConnection* client_conn,
+ QuicCryptoClientStream* client,
+ const FakeServerOptions& options);
// returns: the number of client hellos that the client sent.
- static int HandshakeWithFakeClient(PacketSavingConnection* server_conn,
+ static int HandshakeWithFakeClient(MockConnectionHelper* helper,
+ PacketSavingConnection* server_conn,
QuicCryptoServerStream* server,
const QuicServerId& server_id,
const FakeClientOptions& options);
@@ -87,7 +103,8 @@ class CryptoTestUtils {
const QuicClock* clock,
QuicRandom* rand,
QuicConfig* config,
- QuicCryptoServerConfig* crypto_config);
+ QuicCryptoServerConfig* crypto_config,
+ const FakeServerOptions& options);
// CommunicateHandshakeMessages moves messages from |a| to |b| and back until
// |a|'s handshake has completed.
@@ -128,24 +145,18 @@ class CryptoTestUtils {
// Returns a |ProofVerifier| that uses the QUIC testing root CA.
static ProofVerifier* ProofVerifierForTesting();
+ // Returns a real ProofVerifier (not a fake proof verifier) for testing.
+ static ProofVerifier* RealProofVerifierForTesting();
+
// Returns a |ProofVerifyContext| that must be used with the verifier
// returned by |ProofVerifierForTesting|.
static ProofVerifyContext* ProofVerifyContextForTesting();
- // These functions return a fake |ProofSource|, |ProofVerifier|, or
- // |ProofVerifyContext| that works with each other. These are suitable for
- // unit tests that aren't concerned with |ProofSource| and |ProofVerifier|.
- // TODO(wtc): delete these when Chromium has a working
- // ProofSourceForTesting().
- static ProofSource* FakeProofSourceForTesting();
- static ProofVerifier* FakeProofVerifierForTesting();
- static ProofVerifyContext* FakeProofVerifyContextForTesting();
-
// MockCommonCertSets returns a CommonCertSets that contains a single set with
// hash |hash|, consisting of the certificate |cert| at index |index|.
static CommonCertSets* MockCommonCertSets(base::StringPiece cert,
- uint64 hash,
- uint32 index);
+ uint64_t hash,
+ uint32_t index);
// Creates a minimal dummy reject message that will pass the client-config
// validation tests. This will include a server config, but no certs, proof
@@ -178,6 +189,15 @@ class CryptoTestUtils {
// method never returns QUIC_PENDING.
static ChannelIDSource* ChannelIDSourceForTesting();
+ // MovePackets parses crypto handshake messages from packet number
+ // |*inout_packet_index| through to the last packet (or until a packet fails
+ // to decrypt) and has |dest_stream| process them. |*inout_packet_index| is
+ // updated with an index one greater than the last packet processed.
+ static void MovePackets(PacketSavingConnection* source_conn,
+ size_t* inout_packet_index,
+ QuicCryptoStream* dest_stream,
+ PacketSavingConnection* dest_conn);
+
private:
static void CompareClientAndServerKeys(QuicCryptoClientStream* client,
QuicCryptoServerStream* server);
diff --git a/chromium/net/quic/test_tools/crypto_test_utils_chromium.cc b/chromium/net/quic/test_tools/crypto_test_utils_chromium.cc
index 366dd5e2dd0..babaceff3f5 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils_chromium.cc
+++ b/chromium/net/quic/test_tools/crypto_test_utils_chromium.cc
@@ -4,19 +4,40 @@
#include "net/quic/test_tools/crypto_test_utils.h"
+#include <utility>
+
+#include "base/callback_helpers.h"
+#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
#include "net/base/test_data_directory.h"
+#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
+#include "net/cert/cert_verify_result.h"
+#include "net/cert/ct_verifier.h"
#include "net/cert/mock_cert_verifier.h"
+#include "net/cert/multi_log_ct_verifier.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/http/transport_security_state.h"
+#include "net/log/net_log.h"
+#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/crypto/proof_source_chromium.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
+#include "net/ssl/ssl_config_service.h"
#include "net/test/cert_test_util.h"
+using base::StringPiece;
+using base::StringPrintf;
+using std::string;
+using std::vector;
+
namespace net {
namespace test {
@@ -28,63 +49,106 @@ class TestProofVerifierChromium : public ProofVerifierChromium {
TestProofVerifierChromium(
scoped_ptr<CertVerifier> cert_verifier,
scoped_ptr<TransportSecurityState> transport_security_state,
+ scoped_ptr<CTVerifier> cert_transparency_verifier,
const std::string& cert_file)
: ProofVerifierChromium(cert_verifier.get(),
nullptr,
- transport_security_state.get()),
- cert_verifier_(cert_verifier.Pass()),
- transport_security_state_(transport_security_state.Pass()) {
+ transport_security_state.get(),
+ cert_transparency_verifier.get()),
+ cert_verifier_(std::move(cert_verifier)),
+ transport_security_state_(std::move(transport_security_state)),
+ cert_transparency_verifier_(std::move(cert_transparency_verifier)) {
// Load and install the root for the validated chain.
scoped_refptr<X509Certificate> root_cert =
ImportCertFromFile(GetTestCertsDirectory(), cert_file);
scoped_root_.Reset(root_cert.get());
}
+
~TestProofVerifierChromium() override {}
+ CertVerifier* cert_verifier() { return cert_verifier_.get(); }
+
private:
ScopedTestRoot scoped_root_;
scoped_ptr<CertVerifier> cert_verifier_;
scoped_ptr<TransportSecurityState> transport_security_state_;
+ scoped_ptr<CTVerifier> cert_transparency_verifier_;
};
-const char kLeafCert[] = "leaf";
-const char kIntermediateCert[] = "intermediate";
const char kSignature[] = "signature";
+const char kSCT[] = "CryptoServerTests";
class FakeProofSource : public ProofSource {
public:
- FakeProofSource() : certs_(2) {
- certs_[0] = kLeafCert;
- certs_[1] = kIntermediateCert;
- }
+ FakeProofSource() {}
~FakeProofSource() override {}
// ProofSource interface
+ bool Initialize(const base::FilePath& cert_path,
+ const base::FilePath& key_path,
+ const base::FilePath& sct_path) {
+ std::string cert_data;
+ if (!base::ReadFileToString(cert_path, &cert_data)) {
+ DLOG(FATAL) << "Unable to read certificates.";
+ return false;
+ }
+
+ CertificateList certs_in_file =
+ X509Certificate::CreateCertificateListFromBytes(
+ cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
+
+ if (certs_in_file.empty()) {
+ DLOG(FATAL) << "No certificates.";
+ return false;
+ }
+
+ for (const scoped_refptr<X509Certificate>& cert : certs_in_file) {
+ std::string der_encoded_cert;
+ if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(),
+ &der_encoded_cert)) {
+ return false;
+ }
+ certificates_.push_back(der_encoded_cert);
+ }
+ return true;
+ }
+
bool GetProof(const IPAddressNumber& server_ip,
const std::string& hostname,
const std::string& server_config,
bool ecdsa_ok,
const std::vector<std::string>** out_certs,
- std::string* out_signature) override {
- *out_certs = &certs_;
- *out_signature = kSignature;
+ std::string* out_signature,
+ std::string* out_leaf_cert_sct) override {
+ out_signature->assign(kSignature);
+ *out_certs = &certificates_;
+ *out_leaf_cert_sct = kSCT;
return true;
}
private:
- std::vector<std::string> certs_;
+ std::vector<std::string> certificates_;
+
DISALLOW_COPY_AND_ASSIGN(FakeProofSource);
};
-class FakeProofVerifier : public ProofVerifier {
+class FakeProofVerifier : public TestProofVerifierChromium {
public:
- FakeProofVerifier() {}
+ FakeProofVerifier(scoped_ptr<CertVerifier> cert_verifier,
+ scoped_ptr<TransportSecurityState> transport_security_state,
+ scoped_ptr<CTVerifier> cert_transparency_verifier,
+ const std::string& cert_file)
+ : TestProofVerifierChromium(std::move(cert_verifier),
+ std::move(transport_security_state),
+ std::move(cert_transparency_verifier),
+ cert_file) {}
~FakeProofVerifier() override {}
// ProofVerifier interface
QuicAsyncStatus VerifyProof(const std::string& hostname,
const std::string& server_config,
const std::vector<std::string>& certs,
+ const std::string& cert_sct,
const std::string& signature,
const ProofVerifyContext* verify_context,
std::string* error_details,
@@ -93,15 +157,50 @@ class FakeProofVerifier : public ProofVerifier {
error_details->clear();
scoped_ptr<ProofVerifyDetailsChromium> verify_details_chromium(
new ProofVerifyDetailsChromium);
- if (certs.size() != 2 || certs[0] != kLeafCert ||
- certs[1] != kIntermediateCert || signature != kSignature) {
+ DCHECK(!certs.empty());
+ // Convert certs to X509Certificate.
+ vector<StringPiece> cert_pieces(certs.size());
+ for (unsigned i = 0; i < certs.size(); i++) {
+ cert_pieces[i] = base::StringPiece(certs[i]);
+ }
+ scoped_refptr<X509Certificate> x509_cert =
+ X509Certificate::CreateFromDERCertChain(cert_pieces);
+
+ if (!x509_cert.get()) {
+ *error_details = "Failed to create certificate chain";
+ verify_details_chromium->cert_verify_result.cert_status =
+ CERT_STATUS_INVALID;
+ *verify_details = std::move(verify_details_chromium);
+ return QUIC_FAILURE;
+ }
+
+ const ProofVerifyContextChromium* chromium_context =
+ reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
+ scoped_ptr<CertVerifier::Request> cert_verifier_request_;
+ TestCompletionCallback test_callback;
+ int result = cert_verifier()->Verify(
+ x509_cert.get(), hostname, std::string(),
+ chromium_context->cert_verify_flags,
+ SSLConfigService::GetCRLSet().get(),
+ &verify_details_chromium->cert_verify_result, test_callback.callback(),
+ &cert_verifier_request_, chromium_context->net_log);
+ if (result != OK) {
+ std::string error_string = ErrorToString(result);
+ *error_details = StringPrintf("Failed to verify certificate chain: %s",
+ error_string.c_str());
+ verify_details_chromium->cert_verify_result.cert_status =
+ CERT_STATUS_INVALID;
+ *verify_details = std::move(verify_details_chromium);
+ return QUIC_FAILURE;
+ }
+ if (signature != kSignature) {
*error_details = "Invalid proof";
verify_details_chromium->cert_verify_result.cert_status =
CERT_STATUS_INVALID;
- *verify_details = verify_details_chromium.Pass();
+ *verify_details = std::move(verify_details_chromium);
return QUIC_FAILURE;
}
- *verify_details = verify_details_chromium.Pass();
+ *verify_details = std::move(verify_details_chromium);
return QUIC_SUCCESS;
}
@@ -113,16 +212,21 @@ class FakeProofVerifier : public ProofVerifier {
// static
ProofSource* CryptoTestUtils::ProofSourceForTesting() {
+#if defined(USE_OPENSSL)
ProofSourceChromium* source = new ProofSourceChromium();
+#else
+ FakeProofSource* source = new FakeProofSource();
+#endif
base::FilePath certs_dir = GetTestCertsDirectory();
CHECK(source->Initialize(
certs_dir.AppendASCII("quic_chain.crt"),
- certs_dir.AppendASCII("quic_test.example.com.key.pkcs8")));
+ certs_dir.AppendASCII("quic_test.example.com.key.pkcs8"),
+ certs_dir.AppendASCII("quic_test.example.com.key.sct")));
return source;
}
// static
-ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() {
+ProofVerifier* ProofVerifierForTestingInternal(bool use_real_proof_verifier) {
// TODO(rch): use a real cert verifier?
scoped_ptr<MockCertVerifier> cert_verifier(new MockCertVerifier());
net::CertVerifyResult verify_result;
@@ -134,29 +238,35 @@ ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() {
GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(),
"test.example.com", verify_result, OK);
+ if (use_real_proof_verifier) {
+ return new TestProofVerifierChromium(
+ std::move(cert_verifier), make_scoped_ptr(new TransportSecurityState),
+ make_scoped_ptr(new MultiLogCTVerifier), "quic_root.crt");
+ }
+#if defined(USE_OPENSSL)
return new TestProofVerifierChromium(
- cert_verifier.Pass(), make_scoped_ptr(new TransportSecurityState),
- "quic_root.crt");
+ std::move(cert_verifier), make_scoped_ptr(new TransportSecurityState),
+ make_scoped_ptr(new MultiLogCTVerifier), "quic_root.crt");
+#else
+ return new FakeProofVerifier(
+ std::move(cert_verifier), make_scoped_ptr(new TransportSecurityState),
+ make_scoped_ptr(new MultiLogCTVerifier), "quic_root.crt");
+#endif
}
// static
-ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() {
- return new ProofVerifyContextChromium(/*cert_verify_flags=*/0, BoundNetLog());
-}
-
-// static
-ProofSource* CryptoTestUtils::FakeProofSourceForTesting() {
- return new FakeProofSource();
+ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() {
+ return ProofVerifierForTestingInternal(/*use_real_proof_verifier=*/false);
}
// static
-ProofVerifier* CryptoTestUtils::FakeProofVerifierForTesting() {
- return new FakeProofVerifier();
+ProofVerifier* CryptoTestUtils::RealProofVerifierForTesting() {
+ return ProofVerifierForTestingInternal(/*use_real_proof_verifier=*/true);
}
// static
-ProofVerifyContext* CryptoTestUtils::FakeProofVerifyContextForTesting() {
- return nullptr;
+ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() {
+ return new ProofVerifyContextChromium(/*cert_verify_flags=*/0, BoundNetLog());
}
} // namespace test
diff --git a/chromium/net/quic/test_tools/crypto_test_utils_openssl.cc b/chromium/net/quic/test_tools/crypto_test_utils_openssl.cc
index 64d215d82bf..80228ee90ce 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils_openssl.cc
+++ b/chromium/net/quic/test_tools/crypto_test_utils_openssl.cc
@@ -49,28 +49,28 @@ class TestChannelIDKey : public ChannelIDKey {
return false;
}
- scoped_ptr<uint8[]> der_sig(new uint8[sig_len]);
+ scoped_ptr<uint8_t[]> der_sig(new uint8_t[sig_len]);
if (!EVP_DigestSignFinal(md_ctx.get(), der_sig.get(), &sig_len)) {
return false;
}
- uint8* derp = der_sig.get();
+ uint8_t* derp = der_sig.get();
crypto::ScopedECDSA_SIG sig(
- d2i_ECDSA_SIG(nullptr, const_cast<const uint8**>(&derp), sig_len));
+ d2i_ECDSA_SIG(nullptr, const_cast<const uint8_t**>(&derp), sig_len));
if (sig.get() == nullptr) {
return false;
}
// The signature consists of a pair of 32-byte numbers.
static const size_t kSignatureLength = 32 * 2;
- scoped_ptr<uint8[]> signature(new uint8[kSignatureLength]);
+ scoped_ptr<uint8_t[]> signature(new uint8_t[kSignatureLength]);
if (!BN_bn2bin_padded(&signature[0], 32, sig->r) ||
!BN_bn2bin_padded(&signature[32], 32, sig->s)) {
return false;
}
- *out_signature = string(reinterpret_cast<char*>(signature.get()),
- kSignatureLength);
+ *out_signature =
+ string(reinterpret_cast<char*>(signature.get()), kSignatureLength);
return true;
}
@@ -86,8 +86,8 @@ class TestChannelIDKey : public ChannelIDKey {
return "";
}
- uint8 buf[kExpectedKeyLength];
- uint8* derp = buf;
+ uint8_t buf[kExpectedKeyLength];
+ uint8_t* derp = buf;
i2d_PublicKey(ecdsa_key_.get(), &derp);
return string(reinterpret_cast<char*>(buf + 1), kExpectedKeyLength - 1);
diff --git a/chromium/net/quic/test_tools/delayed_verify_strike_register_client.cc b/chromium/net/quic/test_tools/delayed_verify_strike_register_client.cc
index b14a1180296..f65852f1be8 100644
--- a/chromium/net/quic/test_tools/delayed_verify_strike_register_client.cc
+++ b/chromium/net/quic/test_tools/delayed_verify_strike_register_client.cc
@@ -13,14 +13,16 @@ namespace test {
DelayedVerifyStrikeRegisterClient::DelayedVerifyStrikeRegisterClient(
unsigned max_entries,
- uint32 current_time_external,
- uint32 window_secs,
- const uint8 orbit[8],
+ uint32_t current_time_external,
+ uint32_t window_secs,
+ const uint8_t orbit[8],
StrikeRegister::StartupType startup)
- : LocalStrikeRegisterClient(max_entries, current_time_external,
- window_secs, orbit, startup),
- delay_verifications_(false) {
-}
+ : LocalStrikeRegisterClient(max_entries,
+ current_time_external,
+ window_secs,
+ orbit,
+ startup),
+ delay_verifications_(false) {}
DelayedVerifyStrikeRegisterClient::~DelayedVerifyStrikeRegisterClient() {}
@@ -43,9 +45,10 @@ void DelayedVerifyStrikeRegisterClient::RunPendingVerifications() {
vector<VerifyArgs> pending;
pending_verifications_.swap(pending);
for (vector<VerifyArgs>::const_iterator it = pending.begin(),
- end = pending.end(); it != end; ++it) {
- LocalStrikeRegisterClient::VerifyNonceIsValidAndUnique(
- it->nonce, it->now, it->cb);
+ end = pending.end();
+ it != end; ++it) {
+ LocalStrikeRegisterClient::VerifyNonceIsValidAndUnique(it->nonce, it->now,
+ it->cb);
}
}
diff --git a/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h b/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h
index 6d5002b7604..8d14647b6c0 100644
--- a/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h
+++ b/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h
@@ -5,9 +5,12 @@
#ifndef NET_QUIC_TEST_TOOLS_DELAYED_VERIFY_STRIKE_REGISTER_CLIENT_H_
#define NET_QUIC_TEST_TOOLS_DELAYED_VERIFY_STRIKE_REGISTER_CLIENT_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/quic/crypto/local_strike_register_client.h"
@@ -19,9 +22,9 @@ namespace test {
class DelayedVerifyStrikeRegisterClient : public LocalStrikeRegisterClient {
public:
DelayedVerifyStrikeRegisterClient(unsigned max_entries,
- uint32 current_time_external,
- uint32 window_secs,
- const uint8 orbit[8],
+ uint32_t current_time_external,
+ uint32_t window_secs,
+ const uint8_t orbit[8],
StrikeRegister::StartupType startup);
~DelayedVerifyStrikeRegisterClient() override;
@@ -30,9 +33,7 @@ class DelayedVerifyStrikeRegisterClient : public LocalStrikeRegisterClient {
ResultCallback* cb) override;
// Start queueing verifications instead of executing them immediately.
- void StartDelayingVerification() {
- delay_verifications_ = true;
- }
+ void StartDelayingVerification() { delay_verifications_ = true; }
// Number of verifications that are queued.
int PendingVerifications() const;
// Run all pending verifications.
@@ -43,10 +44,7 @@ class DelayedVerifyStrikeRegisterClient : public LocalStrikeRegisterClient {
VerifyArgs(base::StringPiece in_nonce,
QuicWallTime in_now,
ResultCallback* in_cb)
- : nonce(in_nonce.as_string()),
- now(in_now),
- cb(in_cb) {
- }
+ : nonce(in_nonce.as_string()), now(in_now), cb(in_cb) {}
std::string nonce;
QuicWallTime now;
diff --git a/chromium/net/quic/test_tools/mock_clock.cc b/chromium/net/quic/test_tools/mock_clock.cc
index 47f23808877..63e088a0f14 100644
--- a/chromium/net/quic/test_tools/mock_clock.cc
+++ b/chromium/net/quic/test_tools/mock_clock.cc
@@ -6,11 +6,9 @@
namespace net {
-MockClock::MockClock() : now_(QuicTime::Zero()) {
-}
+MockClock::MockClock() : now_(QuicTime::Zero()) {}
-MockClock::~MockClock() {
-}
+MockClock::~MockClock() {}
void MockClock::AdvanceTime(QuicTime::Delta delta) {
now_ = now_.Add(delta);
@@ -32,7 +30,7 @@ QuicWallTime MockClock::WallNow() const {
base::TimeTicks MockClock::NowInTicks() const {
base::TimeTicks ticks;
return ticks + base::TimeDelta::FromMicroseconds(
- now_.Subtract(QuicTime::Zero()).ToMicroseconds());
+ now_.Subtract(QuicTime::Zero()).ToMicroseconds());
}
} // namespace net
diff --git a/chromium/net/quic/test_tools/mock_clock.h b/chromium/net/quic/test_tools/mock_clock.h
index 30c76ddf4b1..93647246837 100644
--- a/chromium/net/quic/test_tools/mock_clock.h
+++ b/chromium/net/quic/test_tools/mock_clock.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/time/time.h"
namespace net {
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 c54ccff7a0c..b0db4dd05d3 100644
--- a/chromium/net/quic/test_tools/mock_crypto_client_stream.cc
+++ b/chromium/net/quic/test_tools/mock_crypto_client_stream.cc
@@ -23,15 +23,14 @@ MockCryptoClientStream::MockCryptoClientStream(
const ProofVerifyDetails* proof_verify_details)
: QuicCryptoClientStream(server_id, session, verify_context, crypto_config),
handshake_mode_(handshake_mode),
- proof_verify_details_(proof_verify_details) {
-}
+ proof_verify_details_(proof_verify_details) {}
-MockCryptoClientStream::~MockCryptoClientStream() {
-}
+MockCryptoClientStream::~MockCryptoClientStream() {}
void MockCryptoClientStream::OnHandshakeMessage(
const CryptoHandshakeMessage& message) {
- CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
+ CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+ "Forced mock failure");
}
void MockCryptoClientStream::CryptoConnect() {
@@ -39,6 +38,11 @@ void MockCryptoClientStream::CryptoConnect() {
case ZERO_RTT: {
encryption_established_ = true;
handshake_confirmed_ = false;
+ crypto_negotiated_params_.key_exchange = kC255;
+ crypto_negotiated_params_.aead = kAESG;
+ if (proof_verify_details_) {
+ client_session()->OnProofVerifyDetailsAvailable(*proof_verify_details_);
+ }
session()->connection()->SetDecrypter(ENCRYPTION_INITIAL,
QuicDecrypter::Create(kNULL));
session()->connection()->SetEncrypter(ENCRYPTION_INITIAL,
@@ -89,7 +93,7 @@ void MockCryptoClientStream::SendOnCryptoHandshakeEvent(
void MockCryptoClientStream::SetConfigNegotiated() {
ASSERT_FALSE(session()->config()->negotiated());
QuicTagVector cgst;
- // TODO(rtenneti): Enable the following code after BBR code is checked in.
+// TODO(rtenneti): Enable the following code after BBR code is checked in.
#if 0
cgst.push_back(kTBBR);
#endif
diff --git a/chromium/net/quic/test_tools/mock_crypto_client_stream.h b/chromium/net/quic/test_tools/mock_crypto_client_stream.h
index d0bda38be17..e9281ab26e4 100644
--- a/chromium/net/quic/test_tools/mock_crypto_client_stream.h
+++ b/chromium/net/quic/test_tools/mock_crypto_client_stream.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_crypto_client_stream.h"
@@ -35,13 +36,12 @@ class MockCryptoClientStream : public QuicCryptoClientStream {
COLD_START,
};
- MockCryptoClientStream(
- const QuicServerId& server_id,
- QuicClientSessionBase* session,
- ProofVerifyContext* verify_context,
- QuicCryptoClientConfig* crypto_config,
- HandshakeMode handshake_mode,
- const ProofVerifyDetails* proof_verify_details_);
+ MockCryptoClientStream(const QuicServerId& server_id,
+ QuicClientSessionBase* session,
+ ProofVerifyContext* verify_context,
+ QuicCryptoClientConfig* crypto_config,
+ HandshakeMode handshake_mode,
+ const ProofVerifyDetails* proof_verify_details_);
~MockCryptoClientStream() override;
// CryptoFramerVisitorInterface implementation.
diff --git a/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.cc b/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.cc
index e341fe8c766..1773059e20e 100644
--- a/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.cc
+++ b/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.cc
@@ -13,18 +13,17 @@ using std::string;
namespace net {
-MockCryptoClientStreamFactory::~MockCryptoClientStreamFactory() {
-}
+MockCryptoClientStreamFactory::~MockCryptoClientStreamFactory() {}
MockCryptoClientStreamFactory::MockCryptoClientStreamFactory()
: handshake_mode_(MockCryptoClientStream::CONFIRM_HANDSHAKE),
- last_stream_(nullptr) {
-}
+ last_stream_(nullptr) {}
QuicCryptoClientStream*
MockCryptoClientStreamFactory::CreateQuicCryptoClientStream(
const QuicServerId& server_id,
QuicChromiumClientSession* session,
+ scoped_ptr<ProofVerifyContext> /*proof_verify_context*/,
QuicCryptoClientConfig* crypto_config) {
const ProofVerifyDetails* proof_verify_details = nullptr;
if (!proof_verify_details_queue_.empty()) {
diff --git a/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.h b/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.h
index 6ccc4208ba0..5ca04bfbaa1 100644
--- a/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.h
+++ b/chromium/net/quic/test_tools/mock_crypto_client_stream_factory.h
@@ -8,6 +8,7 @@
#include <queue>
#include <string>
+#include "base/macros.h"
#include "net/quic/quic_crypto_client_stream.h"
#include "net/quic/quic_crypto_client_stream_factory.h"
#include "net/quic/test_tools/mock_crypto_client_stream.h"
@@ -16,7 +17,7 @@ namespace net {
class QuicServerId;
-class MockCryptoClientStreamFactory : public QuicCryptoClientStreamFactory {
+class MockCryptoClientStreamFactory : public QuicCryptoClientStreamFactory {
public:
MockCryptoClientStreamFactory();
~MockCryptoClientStreamFactory() override;
@@ -24,6 +25,7 @@ class MockCryptoClientStreamFactory : public QuicCryptoClientStreamFactory {
QuicCryptoClientStream* CreateQuicCryptoClientStream(
const QuicServerId& server_id,
QuicChromiumClientSession* session,
+ scoped_ptr<ProofVerifyContext> proof_verify_context,
QuicCryptoClientConfig* crypto_config) override;
void set_handshake_mode(
@@ -36,9 +38,7 @@ class MockCryptoClientStreamFactory : public QuicCryptoClientStreamFactory {
proof_verify_details_queue_.push(proof_verify_details);
}
- MockCryptoClientStream* last_stream() const {
- return last_stream_;
- }
+ MockCryptoClientStream* last_stream() const { return last_stream_; }
private:
MockCryptoClientStream::HandshakeMode handshake_mode_;
diff --git a/chromium/net/quic/test_tools/mock_quic_dispatcher.cc b/chromium/net/quic/test_tools/mock_quic_dispatcher.cc
index ecbdcbd87f5..66b940b8e45 100644
--- a/chromium/net/quic/test_tools/mock_quic_dispatcher.cc
+++ b/chromium/net/quic/test_tools/mock_quic_dispatcher.cc
@@ -12,17 +12,13 @@ namespace test {
MockQuicDispatcher::MockQuicDispatcher(
const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
- QuicDispatcher::PacketWriterFactory* packet_writer_factory,
QuicConnectionHelperInterface* helper)
: QuicDispatcher(config,
crypto_config,
QuicSupportedVersions(),
- packet_writer_factory,
- helper) {
-}
+ helper) {}
-MockQuicDispatcher::~MockQuicDispatcher() {
-}
+MockQuicDispatcher::~MockQuicDispatcher() {}
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/mock_quic_dispatcher.h b/chromium/net/quic/test_tools/mock_quic_dispatcher.h
index e402df22b74..2ef15809703 100644
--- a/chromium/net/quic/test_tools/mock_quic_dispatcher.h
+++ b/chromium/net/quic/test_tools/mock_quic_dispatcher.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
#define NET_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/quic_config.h"
@@ -19,14 +20,14 @@ class MockQuicDispatcher : public tools::QuicDispatcher {
public:
MockQuicDispatcher(const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
- PacketWriterFactory* packet_writer_factory,
QuicConnectionHelperInterface* helper);
~MockQuicDispatcher() override;
- MOCK_METHOD3(ProcessPacket, void(const IPEndPoint& server_address,
- const IPEndPoint& client_address,
- const QuicEncryptedPacket& packet));
+ MOCK_METHOD3(ProcessPacket,
+ void(const IPEndPoint& server_address,
+ const IPEndPoint& client_address,
+ const QuicEncryptedPacket& packet));
private:
DISALLOW_COPY_AND_ASSIGN(MockQuicDispatcher);
diff --git a/chromium/net/quic/test_tools/mock_random.cc b/chromium/net/quic/test_tools/mock_random.cc
index ab71d1634c8..f1bc024ce30 100644
--- a/chromium/net/quic/test_tools/mock_random.cc
+++ b/chromium/net/quic/test_tools/mock_random.cc
@@ -4,31 +4,28 @@
#include "net/quic/test_tools/mock_random.h"
+#include <string.h>
+
namespace net {
+namespace test {
-MockRandom::MockRandom()
- : base_(0xDEADBEEF),
- increment_(0) {
-}
+MockRandom::MockRandom() : base_(0xDEADBEEF), increment_(0) {}
-MockRandom::MockRandom(uint32 base)
- : base_(base),
- increment_(0) {
-}
+MockRandom::MockRandom(uint32_t base) : base_(base), increment_(0) {}
void MockRandom::RandBytes(void* data, size_t len) {
memset(data, 'r' + increment_, len);
}
-uint64 MockRandom::RandUint64() {
+uint64_t MockRandom::RandUint64() {
return base_ + increment_;
}
-void MockRandom::Reseed(const void* additional_entropy, size_t entropy_len) {
-}
+void MockRandom::Reseed(const void* additional_entropy, size_t entropy_len) {}
void MockRandom::ChangeValue() {
increment_++;
}
+} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/mock_random.h b/chromium/net/quic/test_tools/mock_random.h
index 44f94260c2f..0394cb946b8 100644
--- a/chromium/net/quic/test_tools/mock_random.h
+++ b/chromium/net/quic/test_tools/mock_random.h
@@ -5,22 +5,27 @@
#ifndef NET_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
#define NET_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/quic/crypto/quic_random.h"
namespace net {
+namespace test {
class MockRandom : public QuicRandom {
public:
// Initializes base_ to 0xDEADBEEF.
MockRandom();
- explicit MockRandom(uint32 base);
+ explicit MockRandom(uint32_t base);
// QuicRandom:
// Fills the |data| buffer with a repeating byte, initially 'r'.
void RandBytes(void* data, size_t len) override;
// Returns base + the current increment.
- uint64 RandUint64() override;
+ uint64_t RandUint64() override;
// Does nothing.
void Reseed(const void* additional_entropy, size_t entropy_len) override;
@@ -29,12 +34,13 @@ class MockRandom : public QuicRandom {
void ChangeValue();
private:
- uint32 base_;
- uint8 increment_;
+ uint32_t base_;
+ uint8_t increment_;
DISALLOW_COPY_AND_ASSIGN(MockRandom);
};
+} // namespace test
} // namespace net
#endif // NET_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
diff --git a/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.cc b/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.cc
index 3e7f90cb652..5ccaab08398 100644
--- a/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.cc
+++ b/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.cc
@@ -1,18 +1,3 @@
// Copyright (c) 2015 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/test_tools/quic_ack_notifier_manager_peer.h"
-
-#include "net/quic/quic_ack_notifier_manager.h"
-
-namespace net {
-namespace test {
-
-size_t AckNotifierManagerPeer::GetNumberOfRegisteredPackets(
- const AckNotifierManager* manager) {
- return manager->ack_notifier_map_.size();
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.h b/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.h
index ea128d3af24..5ccaab08398 100644
--- a/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.h
+++ b/chromium/net/quic/test_tools/quic_ack_notifier_manager_peer.h
@@ -1,29 +1,3 @@
// Copyright (c) 2015 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_TEST_TOOLS_QUIC_ACK_NOTIFIER_MANAGER_PEER_H_
-#define NET_QUIC_TEST_TOOLS_QUIC_ACK_NOTIFIER_MANAGER_PEER_H_
-
-#include "net/quic/quic_protocol.h"
-
-namespace net {
-
-class AckNotifierManager;
-
-namespace test {
-
-// Exposes the internal fields of AckNotifierManager for tests.
-class AckNotifierManagerPeer {
- public:
- // Returns total number of packets known to the map.
- static size_t GetNumberOfRegisteredPackets(const AckNotifierManager* manager);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AckNotifierManagerPeer);
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_QUIC_TEST_TOOLS_QUIC_ACK_NOTIFIER_MANAGER_PEER_H_
diff --git a/chromium/net/quic/test_tools/quic_chromium_client_session_peer.cc b/chromium/net/quic/test_tools/quic_chromium_client_session_peer.cc
index 94f4b1d4ad9..cf5a27a2a7c 100644
--- a/chromium/net/quic/test_tools/quic_chromium_client_session_peer.cc
+++ b/chromium/net/quic/test_tools/quic_chromium_client_session_peer.cc
@@ -24,5 +24,14 @@ void QuicChromiumClientSessionPeer::SetChannelIDSent(
session->crypto_stream_->channel_id_sent_ = channel_id_sent;
}
+// static
+void QuicChromiumClientSessionPeer::SetHostname(
+ QuicChromiumClientSession* session,
+ const std::string& hostname) {
+ QuicServerId server_id(hostname, session->server_id_.port(),
+ session->server_id_.privacy_mode());
+ session->server_id_ = server_id;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_chromium_client_session_peer.h b/chromium/net/quic/test_tools/quic_chromium_client_session_peer.h
index 9d39741bb21..4000bd7a34d 100644
--- a/chromium/net/quic/test_tools/quic_chromium_client_session_peer.h
+++ b/chromium/net/quic/test_tools/quic_chromium_client_session_peer.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_CHROMIUM_CLIENT_SESSION_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_CHROMIUM_CLIENT_SESSION_PEER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -22,6 +25,9 @@ class QuicChromiumClientSessionPeer {
static void SetChannelIDSent(QuicChromiumClientSession* session,
bool channel_id_sent);
+ static void SetHostname(QuicChromiumClientSession* session,
+ const std::string& hostname);
+
private:
DISALLOW_COPY_AND_ASSIGN(QuicChromiumClientSessionPeer);
};
diff --git a/chromium/net/quic/test_tools/quic_config_peer.cc b/chromium/net/quic/test_tools/quic_config_peer.cc
index 05f75381997..84fa19007ce 100644
--- a/chromium/net/quic/test_tools/quic_config_peer.cc
+++ b/chromium/net/quic/test_tools/quic_config_peer.cc
@@ -12,14 +12,14 @@ namespace test {
// static
void QuicConfigPeer::SetReceivedSocketReceiveBuffer(
QuicConfig* config,
- uint32 receive_buffer_bytes) {
+ uint32_t receive_buffer_bytes) {
config->socket_receive_buffer_.SetReceivedValue(receive_buffer_bytes);
}
// static
void QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
QuicConfig* config,
- uint32 window_bytes) {
+ uint32_t window_bytes) {
config->initial_stream_flow_control_window_bytes_.SetReceivedValue(
window_bytes);
}
@@ -27,7 +27,7 @@ void QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
// static
void QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
QuicConfig* config,
- uint32 window_bytes) {
+ uint32_t window_bytes) {
config->initial_session_flow_control_window_bytes_.SetReceivedValue(
window_bytes);
}
@@ -41,7 +41,7 @@ void QuicConfigPeer::SetReceivedConnectionOptions(
// static
void QuicConfigPeer::SetReceivedBytesForConnectionId(QuicConfig* config,
- uint32 bytes) {
+ uint32_t bytes) {
config->bytes_for_connection_id_.SetReceivedValue(bytes);
}
diff --git a/chromium/net/quic/test_tools/quic_config_peer.h b/chromium/net/quic/test_tools/quic_config_peer.h
index ca2a3391bcc..c212270fafe 100644
--- a/chromium/net/quic/test_tools/quic_config_peer.h
+++ b/chromium/net/quic/test_tools/quic_config_peer.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/quic/quic_config.h"
#include "net/quic/quic_protocol.h"
@@ -17,18 +20,19 @@ namespace test {
class QuicConfigPeer {
public:
static void SetReceivedSocketReceiveBuffer(QuicConfig* config,
- uint32 receive_buffer_bytes);
+ uint32_t receive_buffer_bytes);
static void SetReceivedInitialStreamFlowControlWindow(QuicConfig* config,
- uint32 window_bytes);
+ uint32_t window_bytes);
static void SetReceivedInitialSessionFlowControlWindow(QuicConfig* config,
- uint32 window_bytes);
+ uint32_t window_bytes);
static void SetReceivedConnectionOptions(QuicConfig* config,
const QuicTagVector& options);
- static void SetReceivedBytesForConnectionId(QuicConfig* config, uint32 bytes);
+ static void SetReceivedBytesForConnectionId(QuicConfig* config,
+ uint32_t bytes);
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 5bd6370d977..f171bff8ca6 100644
--- a/chromium/net/quic/test_tools/quic_connection_peer.cc
+++ b/chromium/net/quic/test_tools/quic_connection_peer.cc
@@ -73,6 +73,12 @@ QuicTime::Delta QuicConnectionPeer::GetNetworkTimeout(
}
// static
+QuicSentEntropyManager* QuicConnectionPeer::GetSentEntropyManager(
+ QuicConnection* connection) {
+ return &connection->sent_entropy_manager_;
+}
+
+// static
// TODO(ianswett): Create a GetSentEntropyHash which accepts an AckFrame.
QuicPacketEntropyHash QuicConnectionPeer::GetSentEntropyHash(
QuicConnection* connection,
@@ -123,6 +129,11 @@ bool QuicConnectionPeer::IsSilentCloseEnabled(QuicConnection* connection) {
}
// static
+bool QuicConnectionPeer::IsMultipathEnabled(QuicConnection* connection) {
+ return connection->multipath_enabled_;
+}
+
+// static
void QuicConnectionPeer::SwapCrypters(QuicConnection* connection,
QuicFramer* framer) {
QuicFramerPeer::SwapCrypters(framer, &connection->framer_);
@@ -213,7 +224,11 @@ void QuicConnectionPeer::CloseConnection(QuicConnection* connection) {
// static
QuicEncryptedPacket* QuicConnectionPeer::GetConnectionClosePacket(
QuicConnection* connection) {
- return connection->connection_close_packet_.get();
+ if (connection->termination_packets_ == nullptr ||
+ connection->termination_packets_->empty()) {
+ return nullptr;
+ }
+ return (*connection->termination_packets_)[0];
}
// static
@@ -252,5 +267,10 @@ void QuicConnectionPeer::SetNextMtuProbeAt(QuicConnection* connection,
connection->next_mtu_probe_at_ = number;
}
+// static
+void QuicConnectionPeer::EnableAckDecimation(QuicConnection* connection) {
+ connection->ack_decimation_enabled_ = true;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_connection_peer.h b/chromium/net/quic/test_tools/quic_connection_peer.h
index d7bfe44486a..524eb159ffc 100644
--- a/chromium/net/quic/test_tools/quic_connection_peer.h
+++ b/chromium/net/quic/test_tools/quic_connection_peer.h
@@ -5,7 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_connection_stats.h"
#include "net/quic/quic_protocol.h"
@@ -25,6 +25,7 @@ class QuicPacketCreator;
class QuicPacketGenerator;
class QuicPacketWriter;
class QuicReceivedPacketManager;
+class QuicSentEntropyManager;
class QuicSentPacketManager;
class SendAlgorithmInterface;
@@ -43,8 +44,7 @@ class QuicConnectionPeer {
static void PopulateStopWaitingFrame(QuicConnection* connection,
QuicStopWaitingFrame* stop_waiting);
- static QuicConnectionVisitorInterface* GetVisitor(
- QuicConnection* connection);
+ static QuicConnectionVisitorInterface* GetVisitor(QuicConnection* connection);
static QuicPacketCreator* GetPacketCreator(QuicConnection* connection);
@@ -55,6 +55,9 @@ class QuicConnectionPeer {
static QuicTime::Delta GetNetworkTimeout(QuicConnection* connection);
+ static QuicSentEntropyManager* GetSentEntropyManager(
+ QuicConnection* connection);
+
static QuicPacketEntropyHash GetSentEntropyHash(
QuicConnection* connection,
QuicPacketNumber packet_number);
@@ -77,6 +80,8 @@ class QuicConnectionPeer {
static bool IsSilentCloseEnabled(QuicConnection* connection);
+ static bool IsMultipathEnabled(QuicConnection* connection);
+
static void SwapCrypters(QuicConnection* connection, QuicFramer* framer);
static QuicConnectionHelperInterface* GetHelper(QuicConnection* connection);
@@ -117,6 +122,7 @@ class QuicConnectionPeer {
QuicPacketCount packets);
static void SetNextMtuProbeAt(QuicConnection* connection,
QuicPacketNumber number);
+ static void EnableAckDecimation(QuicConnection* connection);
private:
DISALLOW_COPY_AND_ASSIGN(QuicConnectionPeer);
diff --git a/chromium/net/quic/test_tools/quic_data_stream_peer.h b/chromium/net/quic/test_tools/quic_data_stream_peer.h
deleted file mode 100644
index 914b87d8686..00000000000
--- a/chromium/net/quic/test_tools/quic_data_stream_peer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2013 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_TEST_TOOLS_QUIC_DATA_STREAM_PEER_H_
-#define NET_QUIC_TEST_TOOLS_QUIC_DATA_STREAM_PEER_H_
-
-#include "base/basictypes.h"
-
-namespace net {
-
-class QuicDataStream;
-
-namespace test {
-
-class QuicDataStreamPeer {
- public:
- static void SetHeadersDecompressed(QuicDataStream* stream,
- bool headers_decompressed);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(QuicDataStreamPeer);
-};
-
-} // namespace test
-
-} // namespace net
-
-#endif // NET_QUIC_TEST_TOOLS_QUIC_DATA_STREAM_PEER_H_
diff --git a/chromium/net/quic/test_tools/quic_flow_controller_peer.cc b/chromium/net/quic/test_tools/quic_flow_controller_peer.cc
index 602aaf83808..0e32fed10b0 100644
--- a/chromium/net/quic/test_tools/quic_flow_controller_peer.cc
+++ b/chromium/net/quic/test_tools/quic_flow_controller_peer.cc
@@ -28,8 +28,8 @@ void QuicFlowControllerPeer::SetReceiveWindowOffset(
// static
void QuicFlowControllerPeer::SetMaxReceiveWindow(
- QuicFlowController* flow_controller,
- QuicByteCount window_size) {
+ QuicFlowController* flow_controller,
+ QuicByteCount window_size) {
flow_controller->receive_window_size_ = window_size;
}
diff --git a/chromium/net/quic/test_tools/quic_flow_controller_peer.h b/chromium/net/quic/test_tools/quic_flow_controller_peer.h
index 3d7c9d00d30..59ef7c2c68f 100644
--- a/chromium/net/quic/test_tools/quic_flow_controller_peer.h
+++ b/chromium/net/quic/test_tools/quic_flow_controller_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
diff --git a/chromium/net/quic/test_tools/quic_framer_peer.cc b/chromium/net/quic/test_tools/quic_framer_peer.cc
index a8f43abae92..dd997365b53 100644
--- a/chromium/net/quic/test_tools/quic_framer_peer.cc
+++ b/chromium/net/quic/test_tools/quic_framer_peer.cc
@@ -14,22 +14,23 @@ namespace test {
QuicPacketNumber QuicFramerPeer::CalculatePacketNumberFromWire(
QuicFramer* framer,
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_packet_number) {
- return framer->CalculatePacketNumberFromWire(packet_number_length,
- packet_packet_number);
+ QuicPacketNumber last_packet_number,
+ QuicPacketNumber packet_number) {
+ return framer->CalculatePacketNumberFromWire(
+ packet_number_length, last_packet_number, packet_number);
}
// static
void QuicFramerPeer::SetLastSerializedConnectionId(
- QuicFramer* framer, QuicConnectionId connection_id) {
+ QuicFramer* framer,
+ QuicConnectionId connection_id) {
framer->last_serialized_connection_id_ = connection_id;
}
// static
-void QuicFramerPeer::SetLastPacketNumber(
- QuicFramer* framer,
- QuicPacketNumber packet_packet_number) {
- framer->last_packet_number_ = packet_packet_number;
+void QuicFramerPeer::SetLastPacketNumber(QuicFramer* framer,
+ QuicPacketNumber packet_number) {
+ framer->last_packet_number_ = packet_number;
}
// static
@@ -50,13 +51,11 @@ void QuicFramerPeer::SwapCrypters(QuicFramer* framer1, QuicFramer* framer2) {
framer2->decrypter_level_ = framer1->decrypter_level_;
framer1->decrypter_level_ = framer2_level;
framer2_level = framer2->alternative_decrypter_level_;
- framer2->alternative_decrypter_level_ =
- framer1->alternative_decrypter_level_;
+ framer2->alternative_decrypter_level_ = framer1->alternative_decrypter_level_;
framer1->alternative_decrypter_level_ = framer2_level;
const bool framer2_latch = framer2->alternative_decrypter_latch_;
- framer2->alternative_decrypter_latch_ =
- framer1->alternative_decrypter_latch_;
+ framer2->alternative_decrypter_latch_ = framer1->alternative_decrypter_latch_;
framer1->alternative_decrypter_latch_ = framer2_latch;
}
@@ -66,5 +65,15 @@ QuicEncrypter* QuicFramerPeer::GetEncrypter(QuicFramer* framer,
return framer->encrypter_[level].get();
}
+// static
+QuicPacketNumber QuicFramerPeer::GetLastPacketNumber(QuicFramer* framer) {
+ return framer->last_packet_number_;
+}
+
+// static
+QuicPathId QuicFramerPeer::GetLastPathId(QuicFramer* framer) {
+ return framer->last_path_id_;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_framer_peer.h b/chromium/net/quic/test_tools/quic_framer_peer.h
index e33648ba44b..a31ab265818 100644
--- a/chromium/net/quic/test_tools/quic_framer_peer.h
+++ b/chromium/net/quic/test_tools/quic_framer_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
+#include "base/macros.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
@@ -18,11 +19,12 @@ class QuicFramerPeer {
static QuicPacketNumber CalculatePacketNumberFromWire(
QuicFramer* framer,
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber packet_packet_number);
+ QuicPacketNumber last_packet_number,
+ QuicPacketNumber packet_number);
static void SetLastSerializedConnectionId(QuicFramer* framer,
QuicConnectionId connection_id);
static void SetLastPacketNumber(QuicFramer* framer,
- QuicPacketNumber packet_packet_number);
+ QuicPacketNumber packet_number);
static void SetPerspective(QuicFramer* framer, Perspective perspective);
// SwapCrypters exchanges the state of the crypters of |framer1| with
@@ -31,6 +33,10 @@ class QuicFramerPeer {
static QuicEncrypter* GetEncrypter(QuicFramer* framer, EncryptionLevel level);
+ static QuicPacketNumber GetLastPacketNumber(QuicFramer* framer);
+
+ static QuicPathId GetLastPathId(QuicFramer* framer);
+
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 2437fa0493c..48ad5ca749b 100644
--- a/chromium/net/quic/test_tools/quic_packet_creator_peer.cc
+++ b/chromium/net/quic/test_tools/quic_packet_creator_peer.cc
@@ -53,10 +53,80 @@ void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
}
// static
+void QuicPacketCreatorPeer::FillPacketHeader(QuicPacketCreator* creator,
+ QuicFecGroupNumber fec_group,
+ bool fec_flag,
+ QuicPacketHeader* header) {
+ creator->FillPacketHeader(fec_group, fec_flag, header);
+}
+
+// static
+size_t QuicPacketCreatorPeer::CreateStreamFrame(QuicPacketCreator* creator,
+ QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ QuicFrame* frame) {
+ return creator->CreateStreamFrame(id, iov, iov_offset, offset, fin, frame);
+}
+
+// static
+bool QuicPacketCreatorPeer::IsFecProtected(QuicPacketCreator* creator) {
+ return creator->fec_protect_;
+}
+
+// static
+bool QuicPacketCreatorPeer::IsFecEnabled(QuicPacketCreator* creator) {
+ return creator->max_packets_per_fec_group_ > 0;
+}
+
+// static
+void QuicPacketCreatorPeer::StartFecProtectingPackets(
+ QuicPacketCreator* creator) {
+ creator->StartFecProtectingPackets();
+}
+
+// static
+void QuicPacketCreatorPeer::StopFecProtectingPackets(
+ QuicPacketCreator* creator) {
+ creator->StopFecProtectingPackets();
+}
+
+// static
+SerializedPacket QuicPacketCreatorPeer::SerializeFec(QuicPacketCreator* creator,
+ char* buffer,
+ size_t buffer_len) {
+ return creator->SerializeFec(buffer, buffer_len);
+}
+
+// static
+void QuicPacketCreatorPeer::ResetFecGroup(QuicPacketCreator* creator) {
+ creator->ResetFecGroup();
+}
+
+// static
+QuicTime::Delta QuicPacketCreatorPeer::GetFecTimeout(
+ QuicPacketCreator* creator) {
+ return creator->fec_timeout_;
+}
+
+// static
+float QuicPacketCreatorPeer::GetRttMultiplierForFecTimeout(
+ QuicPacketCreator* creator) {
+ return creator->rtt_multiplier_for_fec_timeout_;
+}
+
+// static
EncryptionLevel QuicPacketCreatorPeer::GetEncryptionLevel(
QuicPacketCreator* creator) {
return creator->encryption_level_;
}
+// static
+QuicPathId QuicPacketCreatorPeer::GetCurrentPath(QuicPacketCreator* creator) {
+ return creator->current_path_;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_packet_creator_peer.h b/chromium/net/quic/test_tools/quic_packet_creator_peer.h
index 05f0d96594b..a5ac0eda086 100644
--- a/chromium/net/quic/test_tools/quic_packet_creator_peer.h
+++ b/chromium/net/quic/test_tools/quic_packet_creator_peer.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -29,7 +32,30 @@ class QuicPacketCreatorPeer {
static QuicPacketNumberLength NextPacketNumberLength(
QuicPacketCreator* creator);
static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber s);
+ static void FillPacketHeader(QuicPacketCreator* creator,
+ QuicFecGroupNumber fec_group,
+ bool fec_flag,
+ QuicPacketHeader* header);
+ static size_t CreateStreamFrame(QuicPacketCreator* creator,
+ QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ QuicFrame* frame);
+ static bool IsFecProtected(QuicPacketCreator* creator);
+ static bool IsFecEnabled(QuicPacketCreator* creator);
+ static void StartFecProtectingPackets(QuicPacketCreator* creator);
+ static void StopFecProtectingPackets(QuicPacketCreator* creator);
+ static SerializedPacket SerializeFec(QuicPacketCreator* creator,
+ char* buffer,
+ size_t buffer_len);
+ static void ResetFecGroup(QuicPacketCreator* creator);
+ static QuicTime::Delta GetFecTimeout(QuicPacketCreator* creator);
+ // TODO(rtenneti): Delete this code after the 0.25 RTT FEC experiment.
+ static float GetRttMultiplierForFecTimeout(QuicPacketCreator* creator);
static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator);
+ static QuicPathId GetCurrentPath(QuicPacketCreator* creator);
private:
DISALLOW_COPY_AND_ASSIGN(QuicPacketCreatorPeer);
diff --git a/chromium/net/quic/test_tools/quic_packet_generator_peer.cc b/chromium/net/quic/test_tools/quic_packet_generator_peer.cc
index c6ef4026186..ad0693a355f 100644
--- a/chromium/net/quic/test_tools/quic_packet_generator_peer.cc
+++ b/chromium/net/quic/test_tools/quic_packet_generator_peer.cc
@@ -16,11 +16,5 @@ QuicPacketCreator* QuicPacketGeneratorPeer::GetPacketCreator(
return &generator->packet_creator_;
}
-// static
-QuicTime::Delta QuicPacketGeneratorPeer::GetFecTimeout(
- QuicPacketGenerator* generator) {
- return generator->fec_timeout_;
-}
-
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_packet_generator_peer.h b/chromium/net/quic/test_tools/quic_packet_generator_peer.h
index fba8dbee70f..246684f732a 100644
--- a/chromium/net/quic/test_tools/quic_packet_generator_peer.h
+++ b/chromium/net/quic/test_tools/quic_packet_generator_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -17,7 +18,6 @@ namespace test {
class QuicPacketGeneratorPeer {
public:
static QuicPacketCreator* GetPacketCreator(QuicPacketGenerator* generator);
- static QuicTime::Delta GetFecTimeout(QuicPacketGenerator* generator);
private:
DISALLOW_COPY_AND_ASSIGN(QuicPacketGeneratorPeer);
diff --git a/chromium/net/quic/test_tools/quic_received_packet_manager_peer.h b/chromium/net/quic/test_tools/quic_received_packet_manager_peer.h
index 957acad472d..10612612270 100644
--- a/chromium/net/quic/test_tools/quic_received_packet_manager_peer.h
+++ b/chromium/net/quic/test_tools/quic_received_packet_manager_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_RECEIVED_PACKET_MANAGER_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_RECEIVED_PACKET_MANAGER_PEER_H_
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
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 229f5287f49..a5f63fcbdd0 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
@@ -7,6 +7,7 @@
#include "base/stl_util.h"
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_sent_packet_manager.h"
@@ -52,8 +53,7 @@ void QuicSentPacketManagerPeer::SetPerspective(
}
// static
-const SendAlgorithmInterface*
- QuicSentPacketManagerPeer::GetSendAlgorithm(
+const SendAlgorithmInterface* QuicSentPacketManagerPeer::GetSendAlgorithm(
const QuicSentPacketManager& sent_packet_manager) {
return sent_packet_manager.send_algorithm_.get();
}
@@ -106,6 +106,17 @@ bool QuicSentPacketManagerPeer::IsRetransmission(
QuicSentPacketManager* sent_packet_manager,
QuicPacketNumber packet_number) {
DCHECK(sent_packet_manager->HasRetransmittableFrames(packet_number));
+ if (FLAGS_quic_track_single_retransmission) {
+ if (!sent_packet_manager->HasRetransmittableFrames(packet_number)) {
+ return false;
+ }
+ for (auto transmission_info : sent_packet_manager->unacked_packets_) {
+ if (transmission_info.retransmission == packet_number) {
+ return true;
+ }
+ }
+ return false;
+ }
return sent_packet_manager->HasRetransmittableFrames(packet_number) &&
sent_packet_manager->unacked_packets_.GetTransmissionInfo(
packet_number)
@@ -154,8 +165,8 @@ QuicByteCount QuicSentPacketManagerPeer::GetBytesInFlight(
// static
QuicSentPacketManager::NetworkChangeVisitor*
- QuicSentPacketManagerPeer::GetNetworkChangeVisitor(
- const QuicSentPacketManager* sent_packet_manager) {
+QuicSentPacketManagerPeer::GetNetworkChangeVisitor(
+ const QuicSentPacketManager* sent_packet_manager) {
return sent_packet_manager->network_change_visitor_;
}
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 10d5ebc5e78..d7f28ebd846 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
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_sent_packet_manager.h"
@@ -19,8 +22,8 @@ class QuicSentPacketManagerPeer {
static size_t GetMaxTailLossProbes(
QuicSentPacketManager* sent_packet_manager);
- static void SetMaxTailLossProbes(
- QuicSentPacketManager* sent_packet_manager, size_t max_tail_loss_probes);
+ static void SetMaxTailLossProbes(QuicSentPacketManager* sent_packet_manager,
+ size_t max_tail_loss_probes);
static bool GetEnableHalfRttTailLossProbe(
QuicSentPacketManager* sent_packet_manager);
diff --git a/chromium/net/quic/test_tools/quic_session_peer.cc b/chromium/net/quic/test_tools/quic_session_peer.cc
index c1f86198c02..64ca722d00a 100644
--- a/chromium/net/quic/test_tools/quic_session_peer.cc
+++ b/chromium/net/quic/test_tools/quic_session_peer.cc
@@ -14,13 +14,19 @@ namespace net {
namespace test {
// static
-void QuicSessionPeer::SetNextStreamId(QuicSession* session, QuicStreamId id) {
- session->next_stream_id_ = id;
+QuicStreamId QuicSessionPeer::GetNextOutgoingStreamId(QuicSession* session) {
+ return session->GetNextOutgoingStreamId();
+}
+
+// static
+void QuicSessionPeer::SetNextOutgoingStreamId(QuicSession* session,
+ QuicStreamId id) {
+ session->next_outgoing_stream_id_ = id;
}
// static
void QuicSessionPeer::SetMaxOpenStreams(QuicSession* session,
- uint32 max_streams) {
+ uint32_t max_streams) {
session->max_open_streams_ = max_streams;
}
@@ -36,10 +42,10 @@ QuicWriteBlockedList* QuicSessionPeer::GetWriteBlockedStreams(
}
// static
-ReliableQuicStream* QuicSessionPeer::GetIncomingDynamicStream(
+ReliableQuicStream* QuicSessionPeer::GetOrCreateDynamicStream(
QuicSession* session,
QuicStreamId stream_id) {
- return session->GetIncomingDynamicStream(stream_id);
+ return session->GetOrCreateDynamicStream(stream_id);
}
// static
@@ -49,6 +55,16 @@ QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(QuicSession* session) {
}
// static
+QuicSession::StreamMap& QuicSessionPeer::static_streams(QuicSession* session) {
+ return session->static_streams();
+}
+
+// static
+QuicSession::StreamMap& QuicSessionPeer::dynamic_streams(QuicSession* session) {
+ return session->dynamic_streams();
+}
+
+// static
base::hash_set<QuicStreamId>* QuicSessionPeer::GetDrainingStreams(
QuicSession* session) {
return &session->draining_streams_;
@@ -67,18 +83,17 @@ bool QuicSessionPeer::IsStreamCreated(QuicSession* session, QuicStreamId id) {
}
// static
-bool QuicSessionPeer::IsStreamImplicitlyCreated(QuicSession* session,
- QuicStreamId id) {
+bool QuicSessionPeer::IsStreamAvailable(QuicSession* session, QuicStreamId id) {
DCHECK_NE(0u, id);
- return ContainsKey(session->implicitly_created_streams_, id);
+ return ContainsKey(session->available_streams_, id);
}
// static
bool QuicSessionPeer::IsStreamUncreated(QuicSession* session, QuicStreamId id) {
DCHECK_NE(0u, id);
- if (id % 2 == session->next_stream_id_ % 2) {
+ if (id % 2 == session->next_outgoing_stream_id_ % 2) {
// locally-created stream.
- return id >= session->next_stream_id_;
+ return id >= session->next_outgoing_stream_id_;
} else {
// peer-created stream.
return id > session->largest_peer_created_stream_id_;
diff --git a/chromium/net/quic/test_tools/quic_session_peer.h b/chromium/net/quic/test_tools/quic_session_peer.h
index 9f4f0110901..bf9af6934f8 100644
--- a/chromium/net/quic/test_tools/quic_session_peer.h
+++ b/chromium/net/quic/test_tools/quic_session_peer.h
@@ -5,39 +5,46 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
+#include <stdint.h>
+
#include <map>
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_session.h"
#include "net/quic/quic_write_blocked_list.h"
namespace net {
class QuicCryptoStream;
-class QuicDataStream;
class QuicHeadersStream;
class QuicSession;
+class QuicSpdyStream;
class ReliableQuicStream;
namespace test {
class QuicSessionPeer {
public:
- static void SetNextStreamId(QuicSession* session, QuicStreamId id);
- static void SetMaxOpenStreams(QuicSession* session, uint32 max_streams);
+ static QuicStreamId GetNextOutgoingStreamId(QuicSession* session);
+ static void SetNextOutgoingStreamId(QuicSession* session, QuicStreamId id);
+ static void SetMaxOpenStreams(QuicSession* session, uint32_t max_streams);
static QuicCryptoStream* GetCryptoStream(QuicSession* session);
static QuicWriteBlockedList* GetWriteBlockedStreams(QuicSession* session);
- static ReliableQuicStream* GetIncomingDynamicStream(QuicSession* session,
+ static ReliableQuicStream* GetOrCreateDynamicStream(QuicSession* session,
QuicStreamId stream_id);
static std::map<QuicStreamId, QuicStreamOffset>&
GetLocallyClosedStreamsHighestOffset(QuicSession* session);
+ static QuicSession::StreamMap& static_streams(QuicSession* session);
+ static QuicSession::StreamMap& dynamic_streams(QuicSession* session);
static base::hash_set<QuicStreamId>* GetDrainingStreams(QuicSession* session);
// Discern the state of a stream. Exactly one of these should be true at a
// time for any stream id > 0 (other than the special streams 1 and 3).
static bool IsStreamClosed(QuicSession* session, QuicStreamId id);
static bool IsStreamCreated(QuicSession* session, QuicStreamId id);
- static bool IsStreamImplicitlyCreated(QuicSession* session, QuicStreamId id);
+ static bool IsStreamAvailable(QuicSession* session, QuicStreamId id);
static bool IsStreamUncreated(QuicSession* session, QuicStreamId id);
private:
diff --git a/chromium/net/quic/test_tools/quic_spdy_session_peer.h b/chromium/net/quic/test_tools/quic_spdy_session_peer.h
index 840f3dcb2c2..d6597c7572d 100644
--- a/chromium/net/quic/test_tools/quic_spdy_session_peer.h
+++ b/chromium/net/quic/test_tools/quic_spdy_session_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_write_blocked_list.h"
diff --git a/chromium/net/quic/test_tools/quic_data_stream_peer.cc b/chromium/net/quic/test_tools/quic_spdy_stream_peer.cc
index 61656753104..953f9111e70 100644
--- a/chromium/net/quic/test_tools/quic_data_stream_peer.cc
+++ b/chromium/net/quic/test_tools/quic_spdy_stream_peer.cc
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/quic/test_tools/quic_data_stream_peer.h"
+#include "net/quic/test_tools/quic_spdy_stream_peer.h"
-#include "net/quic/quic_data_stream.h"
+#include "net/quic/quic_spdy_stream.h"
namespace net {
namespace test {
// static
-void QuicDataStreamPeer::SetHeadersDecompressed(QuicDataStream* stream,
+void QuicSpdyStreamPeer::SetHeadersDecompressed(QuicSpdyStream* stream,
bool headers_decompressed) {
stream->headers_decompressed_ = headers_decompressed;
}
diff --git a/chromium/net/quic/test_tools/quic_spdy_stream_peer.h b/chromium/net/quic/test_tools/quic_spdy_stream_peer.h
new file mode 100644
index 00000000000..49ee55c53aa
--- /dev/null
+++ b/chromium/net/quic/test_tools/quic_spdy_stream_peer.h
@@ -0,0 +1,29 @@
+// Copyright 2013 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_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
+#define NET_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
+
+#include "base/macros.h"
+
+namespace net {
+
+class QuicSpdyStream;
+
+namespace test {
+
+class QuicSpdyStreamPeer {
+ public:
+ static void SetHeadersDecompressed(QuicSpdyStream* stream,
+ bool headers_decompressed);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QuicSpdyStreamPeer);
+};
+
+} // namespace test
+
+} // namespace net
+
+#endif // NET_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
diff --git a/chromium/net/quic/test_tools/quic_stream_factory_peer.cc b/chromium/net/quic/test_tools/quic_stream_factory_peer.cc
new file mode 100644
index 00000000000..99c4ef3feba
--- /dev/null
+++ b/chromium/net/quic/test_tools/quic_stream_factory_peer.cc
@@ -0,0 +1,165 @@
+// Copyright 2015 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/test_tools/quic_stream_factory_peer.h"
+
+#include "net/quic/crypto/quic_crypto_client_config.h"
+#include "net/quic/quic_chromium_client_session.h"
+#include "net/quic/quic_clock.h"
+#include "net/quic/quic_http_stream.h"
+#include "net/quic/quic_stream_factory.h"
+
+using std::string;
+using std::vector;
+
+namespace net {
+namespace test {
+
+const QuicConfig* QuicStreamFactoryPeer::GetConfig(QuicStreamFactory* factory) {
+ return &factory->config_;
+}
+
+QuicCryptoClientConfig* QuicStreamFactoryPeer::GetCryptoConfig(
+ QuicStreamFactory* factory) {
+ return &factory->crypto_config_;
+}
+
+bool QuicStreamFactoryPeer::HasActiveSession(
+ QuicStreamFactory* factory,
+ const HostPortPair& host_port_pair) {
+ QuicServerId server_id(host_port_pair, PRIVACY_MODE_DISABLED);
+ return factory->HasActiveSession(server_id);
+}
+
+QuicChromiumClientSession* QuicStreamFactoryPeer::GetActiveSession(
+ QuicStreamFactory* factory,
+ const HostPortPair& host_port_pair) {
+ QuicServerId server_id(host_port_pair, PRIVACY_MODE_DISABLED);
+ DCHECK(factory->HasActiveSession(server_id));
+ return factory->active_sessions_[server_id];
+}
+
+scoped_ptr<QuicHttpStream> QuicStreamFactoryPeer::CreateFromSession(
+ QuicStreamFactory* factory,
+ QuicChromiumClientSession* session) {
+ return factory->CreateFromSession(session);
+}
+
+bool QuicStreamFactoryPeer::IsLiveSession(QuicStreamFactory* factory,
+ QuicChromiumClientSession* session) {
+ for (QuicStreamFactory::SessionIdMap::iterator it =
+ factory->all_sessions_.begin();
+ it != factory->all_sessions_.end(); ++it) {
+ if (it->first == session)
+ return true;
+ }
+ return false;
+}
+
+void QuicStreamFactoryPeer::SetTaskRunner(QuicStreamFactory* factory,
+ base::TaskRunner* task_runner) {
+ factory->task_runner_ = task_runner;
+}
+
+int QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ QuicStreamFactory* factory,
+ uint16_t port) {
+ return factory->number_of_lossy_connections_[port];
+}
+
+bool QuicStreamFactoryPeer::IsQuicDisabled(QuicStreamFactory* factory,
+ uint16_t port) {
+ return factory->IsQuicDisabled(port);
+}
+
+bool QuicStreamFactoryPeer::GetDelayTcpRace(QuicStreamFactory* factory) {
+ return factory->delay_tcp_race_;
+}
+
+void QuicStreamFactoryPeer::SetDelayTcpRace(QuicStreamFactory* factory,
+ bool delay_tcp_race) {
+ factory->delay_tcp_race_ = delay_tcp_race;
+}
+
+void QuicStreamFactoryPeer::SetYieldAfterPackets(QuicStreamFactory* factory,
+ int yield_after_packets) {
+ factory->yield_after_packets_ = yield_after_packets;
+}
+
+void QuicStreamFactoryPeer::SetYieldAfterDuration(
+ QuicStreamFactory* factory,
+ QuicTime::Delta yield_after_duration) {
+ factory->yield_after_duration_ = yield_after_duration;
+}
+
+size_t QuicStreamFactoryPeer::GetNumberOfActiveJobs(
+ QuicStreamFactory* factory,
+ const QuicServerId& server_id) {
+ return (factory->active_jobs_[server_id]).size();
+}
+
+int QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(
+ QuicStreamFactory* factory) {
+ return factory->num_timeouts_with_open_streams_;
+}
+
+int QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ QuicStreamFactory* factory) {
+ return factory->num_public_resets_post_handshake_;
+}
+
+void QuicStreamFactoryPeer::MaybeInitialize(QuicStreamFactory* factory) {
+ factory->MaybeInitialize();
+}
+
+bool QuicStreamFactoryPeer::HasInitializedData(QuicStreamFactory* factory) {
+ return factory->has_initialized_data_;
+}
+
+bool QuicStreamFactoryPeer::SupportsQuicAtStartUp(QuicStreamFactory* factory,
+ HostPortPair host_port_pair) {
+ return ContainsKey(factory->quic_supported_servers_at_startup_,
+ host_port_pair);
+}
+
+bool QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
+ QuicStreamFactory* factory,
+ QuicServerId& quic_server_id) {
+ return factory->CryptoConfigCacheIsEmpty(quic_server_id);
+}
+
+void QuicStreamFactoryPeer::CacheDummyServerConfig(
+ QuicStreamFactory* factory,
+ const QuicServerId& quic_server_id) {
+ // Minimum SCFG that passes config validation checks.
+ const char scfg[] = {// SCFG
+ 0x53, 0x43, 0x46, 0x47,
+ // num entries
+ 0x01, 0x00,
+ // padding
+ 0x00, 0x00,
+ // EXPY
+ 0x45, 0x58, 0x50, 0x59,
+ // EXPY end offset
+ 0x08, 0x00, 0x00, 0x00,
+ // Value
+ '1', '2', '3', '4', '5', '6', '7', '8'};
+
+ string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
+ string source_address_token("test_source_address_token");
+ string signature("test_signature");
+ string test_cert("test_cert");
+ vector<string> certs;
+ certs.push_back(test_cert);
+
+ QuicCryptoClientConfig* crypto_config = &factory->crypto_config_;
+ QuicCryptoClientConfig::CachedState* cached =
+ crypto_config->LookupOrCreate(quic_server_id);
+ QuicClock clock;
+ cached->Initialize(server_config, source_address_token, certs, "", signature,
+ clock.WallNow());
+}
+
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_stream_factory_peer.h b/chromium/net/quic/test_tools/quic_stream_factory_peer.h
new file mode 100644
index 00000000000..2f731764f45
--- /dev/null
+++ b/chromium/net/quic/test_tools/quic_stream_factory_peer.h
@@ -0,0 +1,95 @@
+// Copyright 2015 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_TEST_TOOLS_QUIC_STREAM_FACTORY_PEER_H_
+#define NET_QUIC_TEST_TOOLS_QUIC_STREAM_FACTORY_PEER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/task_runner.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/privacy_mode.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_server_id.h"
+#include "net/quic/quic_time.h"
+
+namespace net {
+
+class QuicConfig;
+class QuicCryptoClientConfig;
+class QuicHttpStream;
+class QuicStreamFactory;
+class QuicChromiumClientSession;
+
+namespace test {
+
+class QuicStreamFactoryPeer {
+ public:
+ static const QuicConfig* GetConfig(QuicStreamFactory* factory);
+
+ static QuicCryptoClientConfig* GetCryptoConfig(QuicStreamFactory* factory);
+
+ static bool HasActiveSession(QuicStreamFactory* factory,
+ const HostPortPair& host_port_pair);
+
+ static QuicChromiumClientSession* GetActiveSession(
+ QuicStreamFactory* factory,
+ const HostPortPair& host_port_pair);
+
+ static scoped_ptr<QuicHttpStream> CreateFromSession(
+ QuicStreamFactory* factory,
+ QuicChromiumClientSession* session);
+
+ static bool IsLiveSession(QuicStreamFactory* factory,
+ QuicChromiumClientSession* session);
+
+ static void SetTaskRunner(QuicStreamFactory* factory,
+ base::TaskRunner* task_runner);
+
+ static int GetNumberOfLossyConnections(QuicStreamFactory* factory,
+ uint16_t port);
+
+ static bool IsQuicDisabled(QuicStreamFactory* factory, uint16_t port);
+
+ static bool GetDelayTcpRace(QuicStreamFactory* factory);
+
+ static void SetDelayTcpRace(QuicStreamFactory* factory, bool delay_tcp_race);
+
+ static void SetYieldAfterPackets(QuicStreamFactory* factory,
+ int yield_after_packets);
+
+ static void SetYieldAfterDuration(QuicStreamFactory* factory,
+ QuicTime::Delta yield_after_duration);
+
+ static size_t GetNumberOfActiveJobs(QuicStreamFactory* factory,
+ const QuicServerId& server_id);
+
+ static int GetNumTimeoutsWithOpenStreams(QuicStreamFactory* factory);
+
+ static int GetNumPublicResetsPostHandshake(QuicStreamFactory* factory);
+
+ static void MaybeInitialize(QuicStreamFactory* factory);
+
+ static bool HasInitializedData(QuicStreamFactory* factory);
+
+ static bool SupportsQuicAtStartUp(QuicStreamFactory* factory,
+ HostPortPair host_port_pair);
+
+ static bool CryptoConfigCacheIsEmpty(QuicStreamFactory* factory,
+ QuicServerId& quic_server_id);
+
+ // Creates a dummy QUIC server config and caches it.
+ static void CacheDummyServerConfig(QuicStreamFactory* factory,
+ const QuicServerId& quic_server_id);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QuicStreamFactoryPeer);
+};
+
+} // namespace test
+} // namespace net
+
+#endif // NET_QUIC_TEST_TOOLS_QUIC_STREAM_FACTORY_PEER_H_
diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc
index 591a2e9e927..290e2eaa198 100644
--- a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc
+++ b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc
@@ -13,18 +13,19 @@ namespace net {
namespace test {
// static
-size_t QuicStreamSequencerPeer::GetNumBufferedFrames(
+size_t QuicStreamSequencerPeer::GetNumBufferedBytes(
QuicStreamSequencer* sequencer) {
- return sequencer->buffered_frames_.size();
+ return sequencer->buffered_frames_->BytesBuffered();
}
// static
bool QuicStreamSequencerPeer::FrameOverlapsBufferedData(
- QuicStreamSequencer* sequencer,
+ QuicFrameList* buffer,
const QuicStreamFrame& frame) {
- QuicStreamSequencer::FrameList::iterator it =
- sequencer->FindInsertionPoint(frame);
- return sequencer->FrameOverlapsBufferedData(frame, it);
+ list<QuicFrameList::FrameData>::iterator it =
+ buffer->FindInsertionPoint(frame.offset, frame.frame_length);
+ return buffer->FrameOverlapsBufferedData(frame.offset, frame.frame_length,
+ it);
}
// static
diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h
index 22e3a9908b7..f25c8984b69 100644
--- a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h
+++ b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h
@@ -5,7 +5,10 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "net/quic/quic_frame_list.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -16,9 +19,9 @@ namespace test {
class QuicStreamSequencerPeer {
public:
- static size_t GetNumBufferedFrames(QuicStreamSequencer* sequencer);
+ static size_t GetNumBufferedBytes(QuicStreamSequencer* sequencer);
- static bool FrameOverlapsBufferedData(QuicStreamSequencer* sequencer,
+ static bool FrameOverlapsBufferedData(QuicFrameList* buffer,
const QuicStreamFrame& frame);
static QuicStreamOffset GetCloseOffset(QuicStreamSequencer* sequencer);
diff --git a/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc b/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
index fd3678cc8cf..6779aeac434 100644
--- a/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
+++ b/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
@@ -13,7 +13,7 @@ namespace test {
// static
void QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32 bandwidth_estimate_kbytes_per_second) {
+ int32_t bandwidth_estimate_kbytes_per_second) {
bandwidth_recorder->has_estimate_ = true;
bandwidth_recorder->bandwidth_estimate_ =
QuicBandwidth::FromKBytesPerSecond(bandwidth_estimate_kbytes_per_second);
@@ -22,8 +22,8 @@ void QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
// static
void QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32 max_bandwidth_estimate_kbytes_per_second,
- int32 max_bandwidth_timestamp) {
+ int32_t max_bandwidth_estimate_kbytes_per_second,
+ int32_t max_bandwidth_timestamp) {
bandwidth_recorder->max_bandwidth_estimate_ =
QuicBandwidth::FromKBytesPerSecond(
max_bandwidth_estimate_kbytes_per_second);
diff --git a/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h b/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
index 161a94e726f..186dbb65102 100644
--- a/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
+++ b/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -17,12 +20,12 @@ class QuicSustainedBandwidthRecorderPeer {
public:
static void SetBandwidthEstimate(
QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32 bandwidth_estimate_kbytes_per_second);
+ int32_t bandwidth_estimate_kbytes_per_second);
static void SetMaxBandwidthEstimate(
QuicSustainedBandwidthRecorder* bandwidth_recorder,
- int32 max_bandwidth_estimate_kbytes_per_second,
- int32 max_bandwidth_timestamp);
+ int32_t max_bandwidth_estimate_kbytes_per_second,
+ int32_t max_bandwidth_timestamp);
private:
DISALLOW_COPY_AND_ASSIGN(QuicSustainedBandwidthRecorderPeer);
diff --git a/chromium/net/quic/test_tools/quic_test_packet_maker.cc b/chromium/net/quic/test_tools/quic_test_packet_maker.cc
index 46112634463..25f0f4310f3 100644
--- a/chromium/net/quic/test_tools/quic_test_packet_maker.cc
+++ b/chromium/net/quic/test_tools/quic_test_packet_maker.cc
@@ -25,16 +25,31 @@ QuicTestPacketMaker::QuicTestPacketMaker(QuicVersion version,
clock_(clock),
host_(host),
spdy_request_framer_(HTTP2),
- spdy_response_framer_(HTTP2) {
-}
+ spdy_response_framer_(HTTP2) {}
-QuicTestPacketMaker::~QuicTestPacketMaker() {
-}
+QuicTestPacketMaker::~QuicTestPacketMaker() {}
void QuicTestPacketMaker::set_hostname(const std::string& host) {
host_.assign(host);
}
+scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakePingPacket(
+ QuicPacketNumber num,
+ bool include_version) {
+ QuicPacketHeader header;
+ header.public_header.connection_id = connection_id_;
+ header.public_header.reset_flag = false;
+ header.public_header.version_flag = include_version;
+ header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+ header.packet_number = num;
+ header.entropy_flag = false;
+ header.fec_flag = false;
+ header.fec_group = 0;
+
+ QuicPingFrame ping;
+ return scoped_ptr<QuicEncryptedPacket>(MakePacket(header, QuicFrame(ping)));
+}
+
scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRstPacket(
QuicPacketNumber num,
bool include_version,
@@ -45,7 +60,7 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRstPacket(
header.public_header.reset_flag = false;
header.public_header.version_flag = include_version;
header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- header.packet_packet_number = num;
+ header.packet_number = num;
header.entropy_flag = false;
header.fec_flag = false;
header.fec_group = 0;
@@ -67,7 +82,7 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckAndRstPacket(
header.public_header.reset_flag = false;
header.public_header.version_flag = include_version;
header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- header.packet_packet_number = num;
+ header.packet_number = num;
header.entropy_flag = false;
header.fec_flag = false;
header.fec_group = 0;
@@ -92,11 +107,63 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckAndRstPacket(
scoped_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(
- framer.EncryptPayload(ENCRYPTION_NONE, header.packet_packet_number,
- *packet, buffer, kMaxPacketSize));
- EXPECT_TRUE(encrypted != nullptr);
- return scoped_ptr<QuicEncryptedPacket>(encrypted->Clone());
+ size_t encrypted_size = framer.EncryptPayload(
+ ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize);
+ EXPECT_NE(0u, encrypted_size);
+ QuicEncryptedPacket encrypted(buffer, encrypted_size, false);
+ return scoped_ptr<QuicEncryptedPacket>(encrypted.Clone());
+}
+
+scoped_ptr<QuicEncryptedPacket>
+QuicTestPacketMaker::MakeAckAndConnectionClosePacket(
+ QuicPacketNumber num,
+ bool include_version,
+ QuicTime::Delta delta_time_largest_observed,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber least_unacked,
+ QuicErrorCode quic_error,
+ std::string& quic_error_details) {
+ QuicPacketHeader header;
+ header.public_header.connection_id = connection_id_;
+ header.public_header.reset_flag = false;
+ header.public_header.version_flag = include_version;
+ header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+ header.packet_number = num;
+ header.entropy_flag = false;
+ header.fec_flag = false;
+ header.fec_group = 0;
+
+ QuicAckFrame ack(MakeAckFrame(largest_received));
+ ack.delta_time_largest_observed = delta_time_largest_observed;
+ for (QuicPacketNumber i = least_unacked; i <= largest_received; ++i) {
+ ack.received_packet_times.push_back(make_pair(i, clock_->Now()));
+ }
+ QuicFrames frames;
+ frames.push_back(QuicFrame(&ack));
+ DVLOG(1) << "Adding frame: " << frames[0];
+
+ QuicStopWaitingFrame stop_waiting;
+ stop_waiting.least_unacked = least_unacked;
+ frames.push_back(QuicFrame(&stop_waiting));
+ DVLOG(1) << "Adding frame: " << frames[1];
+
+ QuicConnectionCloseFrame close;
+ close.error_code = quic_error;
+ close.error_details = quic_error_details;
+
+ frames.push_back(QuicFrame(&close));
+ DVLOG(1) << "Adding frame: " << frames[2];
+
+ QuicFramer framer(SupportedVersions(version_), clock_->Now(),
+ Perspective::IS_CLIENT);
+ scoped_ptr<QuicPacket> packet(
+ BuildUnsizedDataPacket(&framer, header, frames));
+ char buffer[kMaxPacketSize];
+ size_t encrypted_size = framer.EncryptPayload(
+ ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize);
+ EXPECT_NE(0u, encrypted_size);
+ QuicEncryptedPacket encrypted(buffer, encrypted_size, false);
+ return scoped_ptr<QuicEncryptedPacket>(encrypted.Clone());
}
scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeConnectionClosePacket(
@@ -106,7 +173,7 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeConnectionClosePacket(
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- header.packet_packet_number = num;
+ header.packet_number = num;
header.entropy_flag = false;
header.fec_flag = false;
header.fec_group = 0;
@@ -117,24 +184,36 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeConnectionClosePacket(
return scoped_ptr<QuicEncryptedPacket>(MakePacket(header, QuicFrame(&close)));
}
+// Sets both least_unacked fields in stop waiting frame and ack frame
+// to be |least_unacked|.
scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckPacket(
QuicPacketNumber packet_number,
QuicPacketNumber largest_received,
QuicPacketNumber least_unacked,
bool send_feedback) {
+ return MakeAckPacket(packet_number, largest_received, least_unacked,
+ least_unacked, send_feedback);
+}
+
+scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckPacket(
+ QuicPacketNumber packet_number,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber ack_least_unacked,
+ QuicPacketNumber stop_least_unacked,
+ bool send_feedback) {
QuicPacketHeader header;
header.public_header.connection_id = connection_id_;
header.public_header.reset_flag = false;
header.public_header.version_flag = false;
header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- header.packet_packet_number = packet_number;
+ header.packet_number = packet_number;
header.entropy_flag = false;
header.fec_flag = false;
header.fec_group = 0;
QuicAckFrame ack(MakeAckFrame(largest_received));
ack.delta_time_largest_observed = QuicTime::Delta::Zero();
- for (QuicPacketNumber i = least_unacked; i <= largest_received; ++i) {
+ for (QuicPacketNumber i = ack_least_unacked; i <= largest_received; ++i) {
ack.received_packet_times.push_back(make_pair(i, clock_->Now()));
}
@@ -144,17 +223,17 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckPacket(
frames.push_back(QuicFrame(&ack));
QuicStopWaitingFrame stop_waiting;
- stop_waiting.least_unacked = least_unacked;
+ stop_waiting.least_unacked = stop_least_unacked;
frames.push_back(QuicFrame(&stop_waiting));
scoped_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(
- framer.EncryptPayload(ENCRYPTION_NONE, header.packet_packet_number,
- *packet, buffer, kMaxPacketSize));
- EXPECT_TRUE(encrypted != nullptr);
- return scoped_ptr<QuicEncryptedPacket>(encrypted->Clone());
+ size_t encrypted_size = framer.EncryptPayload(
+ ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize);
+ EXPECT_NE(0u, encrypted_size);
+ QuicEncryptedPacket encrypted(buffer, encrypted_size, false);
+ return scoped_ptr<QuicEncryptedPacket>(encrypted.Clone());
}
// Returns a newly created packet to send kData on stream 1.
@@ -170,14 +249,59 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeDataPacket(
return MakePacket(header_, QuicFrame(&frame));
}
+scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeAckAndDataPacket(
+ QuicPacketNumber packet_number,
+ bool include_version,
+ QuicStreamId stream_id,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber least_unacked,
+ bool fin,
+ QuicStreamOffset offset,
+ base::StringPiece data) {
+ InitializeHeader(packet_number, include_version);
+
+ QuicAckFrame ack(MakeAckFrame(largest_received));
+ ack.delta_time_largest_observed = QuicTime::Delta::Zero();
+ for (QuicPacketNumber i = least_unacked; i <= largest_received; ++i) {
+ ack.received_packet_times.push_back(make_pair(i, clock_->Now()));
+ }
+ QuicFrames frames;
+ frames.push_back(QuicFrame(&ack));
+
+ QuicStopWaitingFrame stop_waiting;
+ stop_waiting.least_unacked = least_unacked;
+ frames.push_back(QuicFrame(&stop_waiting));
+
+ QuicStreamFrame stream_frame(stream_id, fin, offset, data);
+ frames.push_back(QuicFrame(&stream_frame));
+
+ return MakeMultipleFramesPacket(header_, frames);
+}
+
scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRequestHeadersPacket(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- QuicPriority priority,
+ SpdyPriority priority,
const SpdyHeaderBlock& headers,
size_t* spdy_headers_frame_length) {
+ return MakeRequestHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, priority,
+ headers, spdy_headers_frame_length, nullptr);
+}
+
+// If |offset| is provided, will use the value when creating the packet.
+// Will also update the value after packet creation.
+scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ SpdyPriority priority,
+ const SpdyHeaderBlock& headers,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* offset) {
InitializeHeader(packet_number, should_include_version);
scoped_ptr<SpdySerializedFrame> spdy_frame;
if (spdy_request_framer_.protocol_version() == SPDY3) {
@@ -197,34 +321,50 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRequestHeadersPacket(
if (spdy_headers_frame_length) {
*spdy_headers_frame_length = spdy_frame->size();
}
- QuicStreamFrame frame(
- kHeadersStreamId, false, 0,
- base::StringPiece(spdy_frame->data(), spdy_frame->size()));
- return MakePacket(header_, QuicFrame(&frame));
+ if (offset != nullptr) {
+ QuicStreamFrame frame(
+ kHeadersStreamId, false, *offset,
+ base::StringPiece(spdy_frame->data(), spdy_frame->size()));
+ *offset += spdy_frame->size();
+ return MakePacket(header_, QuicFrame(&frame));
+ } else {
+ QuicStreamFrame frame(
+ kHeadersStreamId, false, 0,
+ base::StringPiece(spdy_frame->data(), spdy_frame->size()));
+
+ return MakePacket(header_, QuicFrame(&frame));
+ }
}
-scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeRequestHeadersPacket(
+// Convenience method for calling MakeRequestHeadersPacket with nullptr for
+// |spdy_headers_frame_length|.
+scoped_ptr<QuicEncryptedPacket>
+QuicTestPacketMaker::MakeRequestHeadersPacketWithOffsetTracking(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- QuicPriority priority,
- const SpdyHeaderBlock& headers) {
+ SpdyPriority priority,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset) {
return MakeRequestHeadersPacket(packet_number, stream_id,
should_include_version, fin, priority,
- headers, nullptr);
+ headers, nullptr, offset);
}
+// If |offset| is provided, will use the value when creating the packet.
+// Will also update the value after packet creation.
scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeResponseHeadersPacket(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
bool should_include_version,
bool fin,
const SpdyHeaderBlock& headers,
- size_t* spdy_headers_frame_length) {
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* offset) {
InitializeHeader(packet_number, should_include_version);
scoped_ptr<SpdySerializedFrame> spdy_frame;
- if (spdy_request_framer_.protocol_version() == SPDY3) {
+ if (spdy_response_framer_.protocol_version() == SPDY3) {
SpdySynReplyIR syn_reply(stream_id);
syn_reply.set_header_block(headers);
syn_reply.set_fin(fin);
@@ -233,15 +373,23 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeResponseHeadersPacket(
SpdyHeadersIR headers_frame(stream_id);
headers_frame.set_header_block(headers);
headers_frame.set_fin(fin);
- spdy_frame.reset(spdy_request_framer_.SerializeFrame(headers_frame));
+ spdy_frame.reset(spdy_response_framer_.SerializeFrame(headers_frame));
}
if (spdy_headers_frame_length) {
*spdy_headers_frame_length = spdy_frame->size();
}
- QuicStreamFrame frame(
- kHeadersStreamId, false, 0,
- base::StringPiece(spdy_frame->data(), spdy_frame->size()));
- return MakePacket(header_, QuicFrame(&frame));
+ if (offset != nullptr) {
+ QuicStreamFrame frame(
+ kHeadersStreamId, false, *offset,
+ base::StringPiece(spdy_frame->data(), spdy_frame->size()));
+ *offset += spdy_frame->size();
+ return MakePacket(header_, QuicFrame(&frame));
+ } else {
+ QuicStreamFrame frame(
+ kHeadersStreamId, false, 0,
+ base::StringPiece(spdy_frame->data(), spdy_frame->size()));
+ return MakePacket(header_, QuicFrame(&frame));
+ }
}
scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeResponseHeadersPacket(
@@ -249,9 +397,26 @@ scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeResponseHeadersPacket(
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- const SpdyHeaderBlock& headers) {
- return MakeResponseHeadersPacket(
- packet_number, stream_id, should_include_version, fin, headers, nullptr);
+ const SpdyHeaderBlock& headers,
+ size_t* spdy_headers_frame_length) {
+ return MakeResponseHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ spdy_headers_frame_length, nullptr);
+}
+
+// Convenience method for calling MakeResponseHeadersPacket with nullptr for
+// |spdy_headers_frame_length|.
+scoped_ptr<QuicEncryptedPacket>
+QuicTestPacketMaker::MakeResponseHeadersPacketWithOffsetTracking(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset) {
+ return MakeResponseHeadersPacket(packet_number, stream_id,
+ should_include_version, fin, headers,
+ nullptr, offset);
}
SpdyHeaderBlock QuicTestPacketMaker::GetRequestHeaders(
@@ -259,15 +424,8 @@ SpdyHeaderBlock QuicTestPacketMaker::GetRequestHeaders(
const std::string& scheme,
const std::string& path) {
SpdyHeaderBlock headers;
- if (version_ <= QUIC_VERSION_24) {
- headers[":version"] = "HTTP/1.1";
- }
headers[":method"] = method;
- if (version_ <= QUIC_VERSION_24) {
- headers[":host"] = host_;
- } else {
- headers[":authority"] = host_;
- }
+ headers[":authority"] = host_;
headers[":scheme"] = scheme;
headers[":path"] = path;
return headers;
@@ -277,9 +435,16 @@ SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
const std::string& status) {
SpdyHeaderBlock headers;
headers[":status"] = status;
- if (version_ <= QUIC_VERSION_24) {
- headers[":version"] = "HTTP/1.1";
- }
+ headers["content-type"] = "text/plain";
+ return headers;
+}
+
+SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
+ const std::string& status,
+ const std::string& alt_svc) {
+ SpdyHeaderBlock headers;
+ headers[":status"] = status;
+ headers["Alt-Svc"] = alt_svc;
headers["content-type"] = "text/plain";
return headers;
}
@@ -287,18 +452,24 @@ SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakePacket(
const QuicPacketHeader& header,
const QuicFrame& frame) {
- QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(),
- Perspective::IS_CLIENT);
QuicFrames frames;
frames.push_back(frame);
+ return MakeMultipleFramesPacket(header, frames);
+}
+
+scoped_ptr<QuicEncryptedPacket> QuicTestPacketMaker::MakeMultipleFramesPacket(
+ const QuicPacketHeader& header,
+ const QuicFrames& frames) {
+ QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(),
+ Perspective::IS_CLIENT);
scoped_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(
- framer.EncryptPayload(ENCRYPTION_NONE, header.packet_packet_number,
- *packet, buffer, kMaxPacketSize));
- EXPECT_TRUE(encrypted != nullptr);
- return scoped_ptr<QuicEncryptedPacket>(encrypted->Clone());
+ size_t encrypted_size = framer.EncryptPayload(
+ ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize);
+ EXPECT_NE(0u, encrypted_size);
+ QuicEncryptedPacket encrypted(buffer, encrypted_size, false);
+ return scoped_ptr<QuicEncryptedPacket>(encrypted.Clone());
}
void QuicTestPacketMaker::InitializeHeader(QuicPacketNumber packet_number,
@@ -307,7 +478,7 @@ void QuicTestPacketMaker::InitializeHeader(QuicPacketNumber packet_number,
header_.public_header.reset_flag = false;
header_.public_header.version_flag = should_include_version;
header_.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
- header_.packet_packet_number = packet_number;
+ header_.packet_number = packet_number;
header_.fec_group = 0;
header_.entropy_flag = false;
header_.fec_flag = false;
diff --git a/chromium/net/quic/test_tools/quic_test_packet_maker.h b/chromium/net/quic/test_tools/quic_test_packet_maker.h
index adb2f3be5e7..cad8082bd57 100644
--- a/chromium/net/quic/test_tools/quic_test_packet_maker.h
+++ b/chromium/net/quic/test_tools/quic_test_packet_maker.h
@@ -7,6 +7,9 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_TEST_PACKET_MAKER_H_
#define NET_QUIC_TEST_TOOLS_QUIC_TEST_PACKET_MAKER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/request_priority.h"
#include "net/quic/quic_protocol.h"
@@ -27,6 +30,8 @@ class QuicTestPacketMaker {
~QuicTestPacketMaker();
void set_hostname(const std::string& host);
+ scoped_ptr<QuicEncryptedPacket> MakePingPacket(QuicPacketNumber num,
+ bool include_version);
scoped_ptr<QuicEncryptedPacket> MakeRstPacket(
QuicPacketNumber num,
bool include_version,
@@ -40,6 +45,14 @@ class QuicTestPacketMaker {
QuicPacketNumber largest_received,
QuicPacketNumber least_unacked,
bool send_feedback);
+ scoped_ptr<QuicEncryptedPacket> MakeAckAndConnectionClosePacket(
+ QuicPacketNumber num,
+ bool include_version,
+ QuicTime::Delta delta_time_largest_observed,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber least_unacked,
+ QuicErrorCode quic_error,
+ std::string& quic_error_details);
scoped_ptr<QuicEncryptedPacket> MakeConnectionClosePacket(
QuicPacketNumber num);
scoped_ptr<QuicEncryptedPacket> MakeAckPacket(
@@ -47,12 +60,27 @@ class QuicTestPacketMaker {
QuicPacketNumber largest_received,
QuicPacketNumber least_unacked,
bool send_feedback);
+ scoped_ptr<QuicEncryptedPacket> MakeAckPacket(
+ QuicPacketNumber packet_number,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber ack_least_unacked,
+ QuicPacketNumber stop_least_unacked,
+ bool send_feedback);
scoped_ptr<QuicEncryptedPacket> MakeDataPacket(QuicPacketNumber packet_number,
QuicStreamId stream_id,
bool should_include_version,
bool fin,
QuicStreamOffset offset,
base::StringPiece data);
+ scoped_ptr<QuicEncryptedPacket> MakeAckAndDataPacket(
+ QuicPacketNumber packet_number,
+ bool include_version,
+ QuicStreamId stream_id,
+ QuicPacketNumber largest_received,
+ QuicPacketNumber least_unacked,
+ bool fin,
+ QuicStreamOffset offset,
+ base::StringPiece data);
// If |spdy_headers_frame_length| is non-null, it will be set to the size of
// the SPDY headers frame created for this packet.
@@ -61,19 +89,30 @@ class QuicTestPacketMaker {
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- QuicPriority priority,
+ SpdyPriority priority,
const SpdyHeaderBlock& headers,
size_t* spdy_headers_frame_length);
+ scoped_ptr<QuicEncryptedPacket> MakeRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ SpdyPriority priority,
+ const SpdyHeaderBlock& headers,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* offset);
+
// Convenience method for calling MakeRequestHeadersPacket with nullptr for
// |spdy_headers_frame_length|.
- scoped_ptr<QuicEncryptedPacket> MakeRequestHeadersPacket(
+ scoped_ptr<QuicEncryptedPacket> MakeRequestHeadersPacketWithOffsetTracking(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- QuicPriority priority,
- const SpdyHeaderBlock& headers);
+ SpdyPriority priority,
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset);
// If |spdy_headers_frame_length| is non-null, it will be set to the size of
// the SPDY headers frame created for this packet.
@@ -83,26 +122,41 @@ class QuicTestPacketMaker {
bool should_include_version,
bool fin,
const SpdyHeaderBlock& headers,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* offset);
+
+ scoped_ptr<QuicEncryptedPacket> MakeResponseHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ const SpdyHeaderBlock& headers,
size_t* spdy_headers_frame_length);
// Convenience method for calling MakeResponseHeadersPacket with nullptr for
// |spdy_headers_frame_length|.
- scoped_ptr<QuicEncryptedPacket> MakeResponseHeadersPacket(
+ scoped_ptr<QuicEncryptedPacket> MakeResponseHeadersPacketWithOffsetTracking(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
bool should_include_version,
bool fin,
- const SpdyHeaderBlock& headers);
+ const SpdyHeaderBlock& headers,
+ QuicStreamOffset* offset);
SpdyHeaderBlock GetRequestHeaders(const std::string& method,
const std::string& scheme,
const std::string& path);
SpdyHeaderBlock GetResponseHeaders(const std::string& status);
+ SpdyHeaderBlock GetResponseHeaders(const std::string& status,
+ const std::string& alt_svc);
+
private:
- scoped_ptr<QuicEncryptedPacket> MakePacket(
+ scoped_ptr<QuicEncryptedPacket> MakePacket(const QuicPacketHeader& header,
+ const QuicFrame& frame);
+ scoped_ptr<QuicEncryptedPacket> MakeMultipleFramesPacket(
const QuicPacketHeader& header,
- const QuicFrame& frame);
+ const QuicFrames& frames);
void InitializeHeader(QuicPacketNumber packet_number,
bool should_include_version);
diff --git a/chromium/net/quic/test_tools/quic_test_utils.cc b/chromium/net/quic/test_tools/quic_test_utils.cc
index 7412d30f207..a2ba09f9e04 100644
--- a/chromium/net/quic/test_tools/quic_test_utils.cc
+++ b/chromium/net/quic/test_tools/quic_test_utils.cc
@@ -31,20 +31,6 @@ using testing::_;
namespace net {
namespace test {
-namespace {
-
-// No-op alarm implementation used by MockHelper.
-class TestAlarm : public QuicAlarm {
- public:
- explicit TestAlarm(QuicAlarm::Delegate* delegate)
- : QuicAlarm(delegate) {
- }
-
- void SetImpl() override {}
- void CancelImpl() override {}
-};
-
-} // namespace
QuicAckFrame MakeAckFrame(QuicPacketNumber largest_observed) {
QuicAckFrame ack;
@@ -86,17 +72,16 @@ QuicPacket* BuildUnsizedDataPacket(QuicFramer* framer,
const QuicFrames& frames,
size_t packet_size) {
char* buffer = new char[packet_size];
- scoped_ptr<QuicPacket> packet(
- framer->BuildDataPacket(header, frames, buffer, packet_size));
- DCHECK(packet.get() != nullptr);
- // Now I have to re-construct the data packet with data ownership.
- return new QuicPacket(buffer, packet->length(), true,
+ size_t length = framer->BuildDataPacket(header, frames, buffer, packet_size);
+ DCHECK_NE(0u, length);
+ // Re-construct the data packet with data ownership.
+ return new QuicPacket(buffer, length, /* owns_buffer */ true,
header.public_header.connection_id_length,
header.public_header.version_flag,
header.public_header.packet_number_length);
}
-uint64 SimpleRandom::RandUint64() {
+uint64_t SimpleRandom::RandUint64() {
unsigned char hash[base::kSHA1Length];
base::SHA1HashBytes(reinterpret_cast<unsigned char*>(&seed_), sizeof(seed_),
hash);
@@ -116,33 +101,25 @@ MockFramerVisitor::MockFramerVisitor() {
ON_CALL(*this, OnUnauthenticatedPublicHeader(_))
.WillByDefault(testing::Return(true));
- ON_CALL(*this, OnPacketHeader(_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnPacketHeader(_)).WillByDefault(testing::Return(true));
- ON_CALL(*this, OnStreamFrame(_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnStreamFrame(_)).WillByDefault(testing::Return(true));
- ON_CALL(*this, OnAckFrame(_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnAckFrame(_)).WillByDefault(testing::Return(true));
- ON_CALL(*this, OnStopWaitingFrame(_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnStopWaitingFrame(_)).WillByDefault(testing::Return(true));
- ON_CALL(*this, OnPingFrame(_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnPingFrame(_)).WillByDefault(testing::Return(true));
- ON_CALL(*this, OnRstStreamFrame(_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnRstStreamFrame(_)).WillByDefault(testing::Return(true));
ON_CALL(*this, OnConnectionCloseFrame(_))
.WillByDefault(testing::Return(true));
- ON_CALL(*this, OnGoAwayFrame(_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnGoAwayFrame(_)).WillByDefault(testing::Return(true));
}
-MockFramerVisitor::~MockFramerVisitor() {
-}
+MockFramerVisitor::~MockFramerVisitor() {}
bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersion version) {
return false;
@@ -170,8 +147,7 @@ bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
return true;
}
-bool NoOpFramerVisitor::OnStopWaitingFrame(
- const QuicStopWaitingFrame& frame) {
+bool NoOpFramerVisitor::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
return true;
}
@@ -179,8 +155,7 @@ bool NoOpFramerVisitor::OnPingFrame(const QuicPingFrame& frame) {
return true;
}
-bool NoOpFramerVisitor::OnRstStreamFrame(
- const QuicRstStreamFrame& frame) {
+bool NoOpFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
return true;
}
@@ -202,138 +177,117 @@ bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& frame) {
return true;
}
-MockConnectionVisitor::MockConnectionVisitor() {
-}
+MockConnectionVisitor::MockConnectionVisitor() {}
-MockConnectionVisitor::~MockConnectionVisitor() {
-}
+MockConnectionVisitor::~MockConnectionVisitor() {}
-MockHelper::MockHelper() {
-}
+MockConnectionHelper::MockConnectionHelper() {}
-MockHelper::~MockHelper() {
-}
+MockConnectionHelper::~MockConnectionHelper() {}
-const QuicClock* MockHelper::GetClock() const {
+const QuicClock* MockConnectionHelper::GetClock() const {
return &clock_;
}
-QuicRandom* MockHelper::GetRandomGenerator() {
+QuicRandom* MockConnectionHelper::GetRandomGenerator() {
return &random_generator_;
}
-QuicAlarm* MockHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
- return new TestAlarm(delegate);
+QuicAlarm* MockConnectionHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
+ return new MockConnectionHelper::TestAlarm(delegate);
}
-void MockHelper::AdvanceTime(QuicTime::Delta delta) {
- clock_.AdvanceTime(delta);
-}
-
-QuicPacketWriter* NiceMockPacketWriterFactory::Create(
- QuicConnection* /*connection*/) const {
- return new testing::NiceMock<MockPacketWriter>();
+QuicBufferAllocator* MockConnectionHelper::GetBufferAllocator() {
+ return &buffer_allocator_;
}
-MockConnection::MockConnection(Perspective perspective)
- : MockConnection(perspective,
- /* is_secure= */ false) {
+void MockConnectionHelper::AdvanceTime(QuicTime::Delta delta) {
+ clock_.AdvanceTime(delta);
}
-MockConnection::MockConnection(Perspective perspective, bool is_secure)
+MockConnection::MockConnection(MockConnectionHelper* helper,
+ Perspective perspective)
: MockConnection(kTestConnectionId,
IPEndPoint(TestPeerIPAddress(), kTestPort),
+ helper,
perspective,
- is_secure,
- QuicSupportedVersions()) {
-}
+ QuicSupportedVersions()) {}
-MockConnection::MockConnection(IPEndPoint address, Perspective perspective)
+MockConnection::MockConnection(IPEndPoint address,
+ MockConnectionHelper* helper,
+ Perspective perspective)
: MockConnection(kTestConnectionId,
address,
+ helper,
perspective,
- /* is_secure= */ false,
- QuicSupportedVersions()) {
-}
+ QuicSupportedVersions()) {}
MockConnection::MockConnection(QuicConnectionId connection_id,
+ MockConnectionHelper* helper,
Perspective perspective)
: MockConnection(connection_id,
- perspective,
- /* is_secure= */ false) {
-}
-
-MockConnection::MockConnection(QuicConnectionId connection_id,
- Perspective perspective,
- bool is_secure)
- : MockConnection(connection_id,
IPEndPoint(TestPeerIPAddress(), kTestPort),
+ helper,
perspective,
- is_secure,
- QuicSupportedVersions()) {
-}
+ QuicSupportedVersions()) {}
-MockConnection::MockConnection(Perspective perspective,
+MockConnection::MockConnection(MockConnectionHelper* helper,
+ Perspective perspective,
const QuicVersionVector& supported_versions)
: MockConnection(kTestConnectionId,
IPEndPoint(TestPeerIPAddress(), kTestPort),
+ helper,
perspective,
- /* is_secure= */ false,
- supported_versions) {
-}
+ supported_versions) {}
MockConnection::MockConnection(QuicConnectionId connection_id,
IPEndPoint address,
+ MockConnectionHelper* helper,
Perspective perspective,
- bool is_secure,
const QuicVersionVector& supported_versions)
: QuicConnection(connection_id,
address,
- new testing::NiceMock<MockHelper>(),
- NiceMockPacketWriterFactory(),
+ helper,
+ new testing::NiceMock<MockPacketWriter>(),
/* owns_writer= */ true,
perspective,
- is_secure,
- supported_versions),
- helper_(helper()) {
+ supported_versions) {
ON_CALL(*this, OnError(_))
.WillByDefault(
Invoke(this, &PacketSavingConnection::QuicConnection_OnError));
}
-MockConnection::~MockConnection() {
-}
+MockConnection::~MockConnection() {}
void MockConnection::AdvanceTime(QuicTime::Delta delta) {
- static_cast<MockHelper*>(helper())->AdvanceTime(delta);
+ static_cast<MockConnectionHelper*>(helper())->AdvanceTime(delta);
}
-PacketSavingConnection::PacketSavingConnection(Perspective perspective)
- : MockConnection(perspective) {
-}
+PacketSavingConnection::PacketSavingConnection(MockConnectionHelper* helper,
+ Perspective perspective)
+ : MockConnection(helper, perspective) {}
PacketSavingConnection::PacketSavingConnection(
+ MockConnectionHelper* helper,
Perspective perspective,
const QuicVersionVector& supported_versions)
- : MockConnection(perspective, supported_versions) {
-}
+ : MockConnection(helper, perspective, supported_versions) {}
PacketSavingConnection::~PacketSavingConnection() {
STLDeleteElements(&encrypted_packets_);
}
-void PacketSavingConnection::SendOrQueuePacket(QueuedPacket packet) {
- if (!packet.serialized_packet.packet->owns_buffer()) {
- scoped_ptr<QuicEncryptedPacket> encrypted_deleter(
- packet.serialized_packet.packet);
- packet.serialized_packet.packet = packet.serialized_packet.packet->Clone();
+void PacketSavingConnection::SendOrQueuePacket(SerializedPacket* packet) {
+ if (!packet->packet->owns_buffer()) {
+ scoped_ptr<QuicEncryptedPacket> encrypted_deleter(packet->packet);
+ packet->packet = packet->packet->Clone();
}
- encrypted_packets_.push_back(packet.serialized_packet.packet);
+ encrypted_packets_.push_back(packet->packet);
// Transfer ownership of the packet to the SentPacketManager and the
// ack notifier to the AckNotifierManager.
- sent_packet_manager_.OnPacketSent(
- &packet.serialized_packet, 0, QuicTime::Zero(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ sent_packet_manager_.OnPacketSent(packet, 0, QuicTime::Zero(), 1000,
+ NOT_RETRANSMISSION,
+ HAS_RETRANSMITTABLE_DATA);
}
MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
@@ -344,23 +298,38 @@ MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
.WillByDefault(testing::Return(QuicConsumedData(0, false)));
}
-MockQuicSpdySession::~MockQuicSpdySession() {
+MockQuicSpdySession::~MockQuicSpdySession() {}
+
+// static
+QuicConsumedData MockQuicSpdySession::ConsumeAllData(
+ QuicStreamId /*id*/,
+ const QuicIOVector& data,
+ QuicStreamOffset /*offset*/,
+ bool fin,
+ FecProtection /*fec_protection*/,
+ QuicAckListenerInterface* /*ack_notifier_delegate*/) {
+ return QuicConsumedData(data.total_length, fin);
}
TestQuicSpdyServerSession::TestQuicSpdyServerSession(
QuicConnection* connection,
const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config)
- : QuicSpdySession(connection, config) {
- crypto_stream_.reset(new QuicCryptoServerStream(crypto_config, this));
+ : QuicServerSessionBase(config, connection, &visitor_, crypto_config) {
Initialize();
}
-TestQuicSpdyServerSession::~TestQuicSpdyServerSession() {
+TestQuicSpdyServerSession::~TestQuicSpdyServerSession() {}
+
+QuicCryptoServerStreamBase*
+TestQuicSpdyServerSession::CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) {
+ return new QuicCryptoServerStream(crypto_config, this);
}
QuicCryptoServerStream* TestQuicSpdyServerSession::GetCryptoStream() {
- return crypto_stream_.get();
+ return static_cast<QuicCryptoServerStream*>(
+ QuicServerSessionBase::GetCryptoStream());
}
TestQuicSpdyClientSession::TestQuicSpdyClientSession(
@@ -375,8 +344,7 @@ TestQuicSpdyClientSession::TestQuicSpdyClientSession(
Initialize();
}
-TestQuicSpdyClientSession::~TestQuicSpdyClientSession() {
-}
+TestQuicSpdyClientSession::~TestQuicSpdyClientSession() {}
QuicCryptoClientStream* TestQuicSpdyClientSession::GetCryptoStream() {
return crypto_stream_.get();
@@ -387,37 +355,30 @@ MockPacketWriter::MockPacketWriter() {
.WillByDefault(testing::Return(kMaxPacketSize));
}
-MockPacketWriter::~MockPacketWriter() {
-}
+MockPacketWriter::~MockPacketWriter() {}
-MockSendAlgorithm::MockSendAlgorithm() {
-}
+MockSendAlgorithm::MockSendAlgorithm() {}
-MockSendAlgorithm::~MockSendAlgorithm() {
-}
+MockSendAlgorithm::~MockSendAlgorithm() {}
-MockLossAlgorithm::MockLossAlgorithm() {
-}
+MockLossAlgorithm::MockLossAlgorithm() {}
-MockLossAlgorithm::~MockLossAlgorithm() {
-}
+MockLossAlgorithm::~MockLossAlgorithm() {}
-MockAckNotifierDelegate::MockAckNotifierDelegate() {
-}
+MockAckListener::MockAckListener() {}
-MockAckNotifierDelegate::~MockAckNotifierDelegate() {
-}
+MockAckListener::~MockAckListener() {}
-MockNetworkChangeVisitor::MockNetworkChangeVisitor() {
-}
+MockNetworkChangeVisitor::MockNetworkChangeVisitor() {}
-MockNetworkChangeVisitor::~MockNetworkChangeVisitor() {
-}
+MockNetworkChangeVisitor::~MockNetworkChangeVisitor() {}
namespace {
-string HexDumpWithMarks(const char* data, int length,
- const bool* marks, int mark_length) {
+string HexDumpWithMarks(const char* data,
+ int length,
+ const bool* marks,
+ int mark_length) {
static const char kHexChars[] = "0123456789abcdef";
static const int kColumns = 4;
@@ -429,9 +390,9 @@ string HexDumpWithMarks(const char* data, int length,
}
string hex;
- for (const char* row = data; length > 0;
+ for (const char *row = data; length > 0;
row += kColumns, length -= kColumns) {
- for (const char *p = row; p < row + 4; ++p) {
+ for (const char* p = row; p < row + 4; ++p) {
if (p < row + length) {
const bool mark =
(marks && (p - data) < mark_length && marks[p - data]);
@@ -456,11 +417,17 @@ string HexDumpWithMarks(const char* data, int length,
} // namespace
-IPAddressNumber TestPeerIPAddress() { return Loopback4(); }
+IPAddressNumber TestPeerIPAddress() {
+ return Loopback4();
+}
-QuicVersion QuicVersionMax() { return QuicSupportedVersions().front(); }
+QuicVersion QuicVersionMax() {
+ return QuicSupportedVersions().front();
+}
-QuicVersion QuicVersionMin() { return QuicSupportedVersions().back(); }
+QuicVersion QuicVersionMin() {
+ return QuicSupportedVersions().back();
+}
IPAddressNumber Loopback4() {
IPAddressNumber addr;
@@ -526,7 +493,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
header.public_header.version_flag = version_flag;
header.public_header.reset_flag = reset_flag;
header.public_header.packet_number_length = packet_number_length;
- header.packet_packet_number = packet_number;
+ header.packet_number = packet_number;
header.entropy_flag = false;
header.entropy_hash = 0;
header.fec_flag = false;
@@ -542,11 +509,11 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
scoped_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
EXPECT_TRUE(packet != nullptr);
- char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer.EncryptPayload(
- ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize));
- EXPECT_TRUE(encrypted != nullptr);
- return encrypted->Clone();
+ char* buffer = new char[kMaxPacketSize];
+ size_t encrypted_length = framer.EncryptPayload(
+ ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
+ EXPECT_NE(0u, encrypted_length);
+ return new QuicEncryptedPacket(buffer, encrypted_length, true);
}
QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
@@ -564,7 +531,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
header.public_header.version_flag = version_flag;
header.public_header.reset_flag = reset_flag;
header.public_header.packet_number_length = packet_number_length;
- header.packet_packet_number = packet_number;
+ header.packet_number = packet_number;
header.entropy_flag = false;
header.entropy_hash = 0;
header.fec_flag = false;
@@ -586,19 +553,18 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
packet->mutable_data())[GetStartOfEncryptedData(
connection_id_length, version_flag, packet_number_length)] = 0xFF;
- char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer.EncryptPayload(
- ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize));
- EXPECT_TRUE(encrypted != nullptr);
- return encrypted->Clone();
+ char* buffer = new char[kMaxPacketSize];
+ size_t encrypted_length = framer.EncryptPayload(
+ ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
+ EXPECT_NE(0u, encrypted_length);
+ return new QuicEncryptedPacket(buffer, encrypted_length, true);
}
-void CompareCharArraysWithHexError(
- const string& description,
- const char* actual,
- const int actual_len,
- const char* expected,
- const int expected_len) {
+void CompareCharArraysWithHexError(const string& description,
+ const char* actual,
+ const int actual_len,
+ const char* expected,
+ const int expected_len) {
EXPECT_EQ(actual_len, expected_len);
const int min_len = min(actual_len, expected_len);
const int max_len = max(actual_len, expected_len);
@@ -615,21 +581,20 @@ void CompareCharArraysWithHexError(
for (int i = min_len; i < max_len; ++i) {
marks[i] = true;
}
- if (identical) return;
- ADD_FAILURE()
- << "Description:\n"
- << description
- << "\n\nExpected:\n"
- << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
- << "\nActual:\n"
- << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
+ if (identical)
+ return;
+ ADD_FAILURE() << "Description:\n" << description << "\n\nExpected:\n"
+ << HexDumpWithMarks(expected, expected_len, marks.get(),
+ max_len)
+ << "\nActual:\n"
+ << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
}
bool DecodeHexString(const base::StringPiece& hex, std::string* bytes) {
bytes->clear();
if (hex.empty())
return true;
- std::vector<uint8> v;
+ std::vector<uint8_t> v;
if (!base::HexStringToBytes(hex.as_string(), &v))
return false;
if (!v.empty())
@@ -650,7 +615,7 @@ static QuicPacket* ConstructPacketFromHandshakeMessage(
header.public_header.connection_id = connection_id;
header.public_header.reset_flag = false;
header.public_header.version_flag = should_include_version;
- header.packet_packet_number = 1;
+ header.packet_number = 1;
header.entropy_flag = false;
header.entropy_hash = 0;
header.fec_flag = false;
@@ -688,7 +653,8 @@ size_t GetPacketLengthForOneStream(QuicVersion version,
NullEncrypter().GetCiphertextSize(
QuicFramer::GetMinAckFrameSize(PACKET_1BYTE_PACKET_NUMBER)) +
GetPacketHeaderSize(connection_id_length, include_version,
- packet_number_length, is_in_fec_group);
+ /*include_path_id=*/false, packet_number_length,
+ is_in_fec_group);
if (stream_length < ack_length) {
*payload_length = 1 + ack_length - stream_length;
}
@@ -735,62 +701,20 @@ QuicVersionVector SupportedVersions(QuicVersion version) {
return versions;
}
-TestWriterFactory::TestWriterFactory() : current_writer_(nullptr) {}
-TestWriterFactory::~TestWriterFactory() {}
-
-QuicPacketWriter* TestWriterFactory::Create(QuicPacketWriter* writer,
- QuicConnection* connection) {
- return new PerConnectionPacketWriter(this, writer, connection);
-}
-
-void TestWriterFactory::OnPacketSent(WriteResult result) {
- if (current_writer_ != nullptr && result.status == WRITE_STATUS_ERROR) {
- current_writer_->connection()->OnWriteError(result.error_code);
- current_writer_ = nullptr;
- }
-}
-
-void TestWriterFactory::Unregister(PerConnectionPacketWriter* writer) {
- if (current_writer_ == writer) {
- current_writer_ = nullptr;
- }
-}
-
-TestWriterFactory::PerConnectionPacketWriter::PerConnectionPacketWriter(
- TestWriterFactory* factory,
- QuicPacketWriter* writer,
- QuicConnection* connection)
- : QuicPerConnectionPacketWriter(writer, connection),
- factory_(factory) {
-}
+MockQuicConnectionDebugVisitor::MockQuicConnectionDebugVisitor() {}
-TestWriterFactory::PerConnectionPacketWriter::~PerConnectionPacketWriter() {
- factory_->Unregister(this);
-}
+MockQuicConnectionDebugVisitor::~MockQuicConnectionDebugVisitor() {}
-WriteResult TestWriterFactory::PerConnectionPacketWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const IPAddressNumber& self_address,
- const IPEndPoint& peer_address) {
- // A DCHECK(factory_current_writer_ == nullptr) would be wrong here -- this
- // class may be used in a setting where connection()->OnPacketSent() is called
- // in a different way, so TestWriterFactory::OnPacketSent might never be
- // called.
- factory_->current_writer_ = this;
- return tools::QuicPerConnectionPacketWriter::WritePacket(
- buffer, buf_len, self_address, peer_address);
-}
+MockReceivedPacketManager::MockReceivedPacketManager(QuicConnectionStats* stats)
+ : QuicReceivedPacketManager(stats) {}
-MockQuicConnectionDebugVisitor::MockQuicConnectionDebugVisitor() {
-}
-
-MockQuicConnectionDebugVisitor::~MockQuicConnectionDebugVisitor() {
-}
+MockReceivedPacketManager::~MockReceivedPacketManager() {}
void CreateClientSessionForTest(QuicServerId server_id,
bool supports_stateless_rejects,
QuicTime::Delta connection_start_time,
+ QuicVersionVector supported_versions,
+ MockConnectionHelper* helper,
QuicCryptoClientConfig* crypto_client_config,
PacketSavingConnection** client_connection,
TestQuicSpdyClientSession** client_session) {
@@ -804,7 +728,8 @@ void CreateClientSessionForTest(QuicServerId server_id,
QuicConfig config = supports_stateless_rejects
? DefaultQuicConfigStatelessRejects()
: DefaultQuicConfig();
- *client_connection = new PacketSavingConnection(Perspective::IS_CLIENT);
+ *client_connection = new PacketSavingConnection(
+ helper, Perspective::IS_CLIENT, supported_versions);
*client_session = new TestQuicSpdyClientSession(
*client_connection, config, server_id, crypto_client_config);
(*client_connection)->AdvanceTime(connection_start_time);
@@ -812,6 +737,8 @@ void CreateClientSessionForTest(QuicServerId server_id,
void CreateServerSessionForTest(QuicServerId server_id,
QuicTime::Delta connection_start_time,
+ QuicVersionVector supported_versions,
+ MockConnectionHelper* helper,
QuicCryptoServerConfig* server_crypto_config,
PacketSavingConnection** server_connection,
TestQuicSpdyServerSession** server_session) {
@@ -822,14 +749,19 @@ void CreateServerSessionForTest(QuicServerId server_id,
<< "Connections must start at non-zero times, otherwise the "
<< "strike-register will be unhappy.";
- *server_connection = new PacketSavingConnection(Perspective::IS_SERVER);
+ *server_connection = new PacketSavingConnection(
+ helper, Perspective::IS_SERVER, supported_versions);
*server_session = new TestQuicSpdyServerSession(
*server_connection, DefaultQuicConfig(), server_crypto_config);
// We advance the clock initially because the default time is zero and the
- // strike register worries that we've just overflowed a uint32 time.
+ // strike register worries that we've just overflowed a uint32_t time.
(*server_connection)->AdvanceTime(connection_start_time);
}
+QuicStreamId QuicClientDataStreamId(int i) {
+ return kClientDataStreamId1 + 2 * i;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_test_utils.h b/chromium/net/quic/test_tools/quic_test_utils.h
index d11110d6958..5293e5b1a11 100644
--- a/chromium/net/quic/test_tools/quic_test_utils.h
+++ b/chromium/net/quic/test_tools/quic_test_utils.h
@@ -7,26 +7,30 @@
#ifndef NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
#define NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
-#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_client_session_base.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_sent_packet_manager.h"
#include "net/quic/quic_session.h"
+#include "net/quic/quic_simple_buffer_allocator.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
#include "net/spdy/spdy_framer.h"
#include "net/tools/quic/quic_dispatcher.h"
#include "net/tools/quic/quic_per_connection_packet_writer.h"
-#include "net/tools/quic/quic_server_session.h"
+#include "net/tools/quic/quic_server_session_base.h"
+#include "net/tools/quic/test_tools/mock_quic_server_session_visitor.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace net {
@@ -34,10 +38,10 @@ namespace net {
namespace test {
static const QuicConnectionId kTestConnectionId = 42;
-static const uint16 kTestPort = 123;
-static const uint32 kInitialStreamFlowControlWindowForTest =
+static const uint16_t kTestPort = 123;
+static const uint32_t kInitialStreamFlowControlWindowForTest =
1024 * 1024; // 1 MB
-static const uint32 kInitialSessionFlowControlWindowForTest =
+static const uint32_t kInitialSessionFlowControlWindowForTest =
1536 * 1024; // 1.5 MB
// Data stream IDs start at 5: the crypto stream is 1, headers stream is 3.
static const QuicStreamId kClientDataStreamId1 = 5;
@@ -160,17 +164,13 @@ QuicPacket* BuildUnsizedDataPacket(QuicFramer* framer,
const QuicFrames& frames,
size_t packet_size);
-template<typename SaveType>
+template <typename SaveType>
class ValueRestore {
public:
- ValueRestore(SaveType* name, SaveType value)
- : name_(name),
- value_(*name) {
+ ValueRestore(SaveType* name, SaveType value) : name_(name), value_(*name) {
*name_ = value;
}
- ~ValueRestore() {
- *name_ = value_;
- }
+ ~ValueRestore() { *name_ = value_; }
private:
SaveType* name_;
@@ -188,12 +188,12 @@ class SimpleRandom {
SimpleRandom() : seed_(0) {}
// Returns a random number in the range [0, kuint64max].
- uint64 RandUint64();
+ uint64_t RandUint64();
- void set_seed(uint64 seed) { seed_ = seed; }
+ void set_seed(uint64_t seed) { seed_ = seed; }
private:
- uint64 seed_;
+ uint64_t seed_;
DISALLOW_COPY_AND_ASSIGN(SimpleRandom);
};
@@ -214,8 +214,8 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
// The constructor sets this up to return true by default.
MOCK_METHOD1(OnUnauthenticatedHeader, bool(const QuicPacketHeader& header));
// The constructor sets this up to return true by default.
- MOCK_METHOD1(OnUnauthenticatedPublicHeader, bool(
- const QuicPacketPublicHeader& header));
+ MOCK_METHOD1(OnUnauthenticatedPublicHeader,
+ bool(const QuicPacketPublicHeader& header));
MOCK_METHOD1(OnDecryptedPacket, void(EncryptionLevel level));
MOCK_METHOD1(OnPacketHeader, bool(const QuicPacketHeader& header));
MOCK_METHOD1(OnFecProtectedPayload, void(base::StringPiece payload));
@@ -223,7 +223,7 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
MOCK_METHOD1(OnAckFrame, bool(const QuicAckFrame& frame));
MOCK_METHOD1(OnStopWaitingFrame, bool(const QuicStopWaitingFrame& frame));
MOCK_METHOD1(OnPingFrame, bool(const QuicPingFrame& frame));
- MOCK_METHOD1(OnFecData, void(const QuicFecData& fec));
+ MOCK_METHOD1(OnFecData, void(StringPiece redundancy));
MOCK_METHOD1(OnRstStreamFrame, bool(const QuicRstStreamFrame& frame));
MOCK_METHOD1(OnConnectionCloseFrame,
bool(const QuicConnectionCloseFrame& frame));
@@ -257,7 +257,7 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface {
bool OnAckFrame(const QuicAckFrame& frame) override;
bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
bool OnPingFrame(const QuicPingFrame& frame) override;
- void OnFecData(const QuicFecData& fec) override {}
+ void OnFecData(StringPiece redundancy) override {}
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
@@ -295,86 +295,92 @@ class MockConnectionVisitor : public QuicConnectionVisitorInterface {
DISALLOW_COPY_AND_ASSIGN(MockConnectionVisitor);
};
-class MockHelper : public QuicConnectionHelperInterface {
+class MockConnectionHelper : public QuicConnectionHelperInterface {
public:
- MockHelper();
- ~MockHelper() override;
+ MockConnectionHelper();
+ ~MockConnectionHelper() override;
const QuicClock* GetClock() const override;
QuicRandom* GetRandomGenerator() override;
QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+ QuicBufferAllocator* GetBufferAllocator() override;
void AdvanceTime(QuicTime::Delta delta);
- private:
- MockClock clock_;
- MockRandom random_generator_;
+ // No-op alarm implementation
+ class TestAlarm : public QuicAlarm {
+ public:
+ explicit TestAlarm(QuicAlarm::Delegate* delegate) : QuicAlarm(delegate) {}
- DISALLOW_COPY_AND_ASSIGN(MockHelper);
-};
+ void SetImpl() override {}
+ void CancelImpl() override {}
-class NiceMockPacketWriterFactory : public QuicConnection::PacketWriterFactory {
- public:
- NiceMockPacketWriterFactory() {}
- ~NiceMockPacketWriterFactory() override {}
+ using QuicAlarm::Fire;
+ };
- QuicPacketWriter* Create(QuicConnection* /*connection*/) const override;
+ void FireAlarm(QuicAlarm* alarm) {
+ reinterpret_cast<TestAlarm*>(alarm)->Fire();
+ }
private:
- DISALLOW_COPY_AND_ASSIGN(NiceMockPacketWriterFactory);
+ MockClock clock_;
+ MockRandom random_generator_;
+ SimpleBufferAllocator buffer_allocator_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockConnectionHelper);
};
class MockConnection : public QuicConnection {
public:
- // Uses a MockHelper, ConnectionId of 42, and 127.0.0.1:123.
- explicit MockConnection(Perspective perspective);
-
- // Uses a MockHelper, ConnectionId of 42, and 127.0.0.1:123.
- MockConnection(Perspective perspective, bool is_secure);
-
- // Uses a MockHelper, ConnectionId of 42.
- MockConnection(IPEndPoint address, Perspective perspective);
+ // Uses a ConnectionId of 42 and 127.0.0.1:123.
+ MockConnection(MockConnectionHelper* helper, Perspective perspective);
- // Uses a MockHelper, and 127.0.0.1:123.
- MockConnection(QuicConnectionId connection_id, Perspective perspective);
+ // Uses a ConnectionId of 42.
+ MockConnection(IPEndPoint address,
+ MockConnectionHelper* helper,
+ Perspective perspective);
- // Uses a MockHelper, and 127.0.0.1:123.
+ // Uses 127.0.0.1:123.
MockConnection(QuicConnectionId connection_id,
- Perspective perspective,
- bool is_secure);
+ MockConnectionHelper* helper,
+ Perspective perspective);
- // Uses a Mock helper, ConnectionId of 42, and 127.0.0.1:123.
- MockConnection(Perspective perspective,
+ // Uses a ConnectionId of 42, and 127.0.0.1:123.
+ MockConnection(MockConnectionHelper* helper,
+ Perspective perspective,
const QuicVersionVector& supported_versions);
MockConnection(QuicConnectionId connection_id,
IPEndPoint address,
+ MockConnectionHelper* helper,
Perspective perspective,
- bool is_secure,
const QuicVersionVector& supported_versions);
~MockConnection() override;
- // If the constructor that uses a MockHelper has been used then this method
+ // If the constructor that uses a MockConnectionHelper has been used then
+ // this method
// will advance the time of the MockClock.
void AdvanceTime(QuicTime::Delta delta);
- MOCK_METHOD3(ProcessUdpPacket, void(const IPEndPoint& self_address,
- const IPEndPoint& peer_address,
- const QuicEncryptedPacket& packet));
+ MOCK_METHOD3(ProcessUdpPacket,
+ void(const IPEndPoint& self_address,
+ const IPEndPoint& peer_address,
+ const QuicEncryptedPacket& packet));
MOCK_METHOD1(SendConnectionClose, void(QuicErrorCode error));
MOCK_METHOD2(SendConnectionCloseWithDetails,
void(QuicErrorCode error, const std::string& details));
MOCK_METHOD2(SendConnectionClosePacket,
void(QuicErrorCode error, const std::string& details));
- MOCK_METHOD3(SendRstStream, void(QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written));
+ MOCK_METHOD3(SendRstStream,
+ void(QuicStreamId id,
+ QuicRstStreamErrorCode error,
+ QuicStreamOffset bytes_written));
MOCK_METHOD3(SendGoAway,
void(QuicErrorCode error,
QuicStreamId last_good_stream_id,
const std::string& reason));
MOCK_METHOD1(SendBlocked, void(QuicStreamId id));
- MOCK_METHOD2(SendWindowUpdate, void(QuicStreamId id,
- QuicStreamOffset byte_offset));
+ MOCK_METHOD2(SendWindowUpdate,
+ void(QuicStreamId id, QuicStreamOffset byte_offset));
MOCK_METHOD0(OnCanWrite, void());
MOCK_METHOD1(OnSendConnectionState, void(const CachedNetworkParameters&));
@@ -392,9 +398,7 @@ class MockConnection : public QuicConnection {
QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
}
- bool OnProtocolVersionMismatch(QuicVersion version) override {
- return false;
- }
+ bool OnProtocolVersionMismatch(QuicVersion version) override { return false; }
void ReallySendGoAway(QuicErrorCode error,
QuicStreamId last_good_stream_id,
@@ -403,21 +407,20 @@ class MockConnection : public QuicConnection {
}
private:
- scoped_ptr<QuicConnectionHelperInterface> helper_;
-
DISALLOW_COPY_AND_ASSIGN(MockConnection);
};
class PacketSavingConnection : public MockConnection {
public:
- explicit PacketSavingConnection(Perspective perspective);
+ PacketSavingConnection(MockConnectionHelper* helper, Perspective perspective);
- PacketSavingConnection(Perspective perspective,
+ PacketSavingConnection(MockConnectionHelper* helper,
+ Perspective perspective,
const QuicVersionVector& supported_versions);
~PacketSavingConnection() override;
- void SendOrQueuePacket(QueuedPacket packet) override;
+ void SendOrQueuePacket(SerializedPacket* packet) override;
std::vector<QuicEncryptedPacket*> encrypted_packets_;
@@ -432,50 +435,79 @@ class MockQuicSpdySession : public QuicSpdySession {
QuicCryptoStream* GetCryptoStream() override { return crypto_stream_.get(); }
+ // From QuicSession.
MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer));
- MOCK_METHOD1(CreateIncomingDynamicStream, QuicDataStream*(QuicStreamId id));
- MOCK_METHOD0(CreateOutgoingDynamicStream, QuicDataStream*());
+ MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
+ MOCK_METHOD1(CreateOutgoingDynamicStream,
+ QuicSpdyStream*(SpdyPriority priority));
MOCK_METHOD6(WritevData,
QuicConsumedData(QuicStreamId id,
- const QuicIOVector& data,
+ QuicIOVector data,
QuicStreamOffset offset,
bool fin,
FecProtection fec_protection,
- QuicAckNotifier::DelegateInterface*));
- MOCK_METHOD2(OnStreamHeaders, void(QuicStreamId stream_id,
- base::StringPiece headers_data));
- MOCK_METHOD2(OnStreamHeadersPriority, void(QuicStreamId stream_id,
- QuicPriority priority));
- MOCK_METHOD3(OnStreamHeadersComplete, void(QuicStreamId stream_id,
- bool fin,
- size_t frame_len));
- MOCK_METHOD3(SendRstStream, void(QuicStreamId stream_id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written));
+ QuicAckListenerInterface*));
+ MOCK_METHOD3(SendRstStream,
+ void(QuicStreamId stream_id,
+ QuicRstStreamErrorCode error,
+ QuicStreamOffset bytes_written));
+
+ MOCK_METHOD2(OnStreamHeaders,
+ void(QuicStreamId stream_id, base::StringPiece headers_data));
+ MOCK_METHOD2(OnStreamHeadersPriority,
+ void(QuicStreamId stream_id, SpdyPriority priority));
+ MOCK_METHOD3(OnStreamHeadersComplete,
+ void(QuicStreamId stream_id, bool fin, size_t frame_len));
+ MOCK_METHOD2(OnPromiseHeaders,
+ void(QuicStreamId stream_id, StringPiece headers_data));
+ MOCK_METHOD3(OnPromiseHeadersComplete,
+ void(QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len));
MOCK_METHOD0(IsCryptoHandshakeConfirmed, bool());
+ MOCK_METHOD5(WriteHeaders,
+ size_t(QuicStreamId id,
+ const SpdyHeaderBlock& headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicAckListenerInterface* ack_notifier_delegate));
+ MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta));
using QuicSession::ActivateStream;
+ // Returns a QuicConsumedData that indicates all of |data| (and |fin| if set)
+ // has been consumed.
+ static QuicConsumedData ConsumeAllData(
+ QuicStreamId id,
+ const QuicIOVector& data,
+ QuicStreamOffset offset,
+ bool fin,
+ FecProtection fec_protection,
+ QuicAckListenerInterface* ack_notifier_delegate);
+
private:
scoped_ptr<QuicCryptoStream> crypto_stream_;
DISALLOW_COPY_AND_ASSIGN(MockQuicSpdySession);
};
-class TestQuicSpdyServerSession : public QuicSpdySession {
+class TestQuicSpdyServerSession : public tools::QuicServerSessionBase {
public:
TestQuicSpdyServerSession(QuicConnection* connection,
const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config);
~TestQuicSpdyServerSession() override;
- MOCK_METHOD1(CreateIncomingDynamicStream, QuicDataStream*(QuicStreamId id));
- MOCK_METHOD0(CreateOutgoingDynamicStream, QuicDataStream*());
+ MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
+ MOCK_METHOD1(CreateOutgoingDynamicStream,
+ QuicSpdyStream*(SpdyPriority priority));
+ QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) override;
QuicCryptoServerStream* GetCryptoStream() override;
private:
- scoped_ptr<QuicCryptoServerStream> crypto_stream_;
+ tools::test::MockQuicServerSessionVisitor visitor_;
DISALLOW_COPY_AND_ASSIGN(TestQuicSpdyServerSession);
};
@@ -495,8 +527,9 @@ class TestQuicSpdyClientSession : public QuicClientSessionBase {
void(const ProofVerifyDetails& verify_details));
// TestQuicSpdyClientSession
- MOCK_METHOD1(CreateIncomingDynamicStream, QuicDataStream*(QuicStreamId id));
- MOCK_METHOD0(CreateOutgoingDynamicStream, QuicDataStream*());
+ MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
+ MOCK_METHOD1(CreateOutgoingDynamicStream,
+ QuicSpdyStream*(SpdyPriority priority));
QuicCryptoClientStream* GetCryptoStream() override;
@@ -532,15 +565,15 @@ class MockSendAlgorithm : public SendAlgorithmInterface {
~MockSendAlgorithm() override;
MOCK_METHOD2(SetFromConfig,
- void(const QuicConfig& config,
- Perspective perspective));
+ void(const QuicConfig& config, Perspective perspective));
MOCK_METHOD1(SetNumEmulatedConnections, void(int num_connections));
MOCK_METHOD1(SetMaxCongestionWindow,
void(QuicByteCount max_congestion_window));
- MOCK_METHOD4(OnCongestionEvent, void(bool rtt_updated,
- QuicByteCount bytes_in_flight,
- const CongestionVector& acked_packets,
- const CongestionVector& lost_packets));
+ MOCK_METHOD4(OnCongestionEvent,
+ void(bool rtt_updated,
+ QuicByteCount bytes_in_flight,
+ const CongestionVector& acked_packets,
+ const CongestionVector& lost_packets));
MOCK_METHOD5(OnPacketSent,
bool(QuicTime,
QuicByteCount,
@@ -548,6 +581,7 @@ class MockSendAlgorithm : public SendAlgorithmInterface {
QuicByteCount,
HasRetransmittableData));
MOCK_METHOD1(OnRetransmissionTimeout, void(bool));
+ MOCK_METHOD0(OnConnectionMigration, void());
MOCK_METHOD0(RevertRetransmissionTimeout, void());
MOCK_CONST_METHOD3(TimeUntilSend,
QuicTime::Delta(QuicTime now,
@@ -581,14 +615,19 @@ class MockLossAlgorithm : public LossDetectionInterface {
const QuicTime& time,
QuicPacketNumber largest_observed,
const RttStats& rtt_stats));
+ MOCK_METHOD4(DetectLosses,
+ void(const QuicUnackedPacketMap& unacked_packets,
+ const QuicTime& time,
+ const RttStats& rtt_stats,
+ SendAlgorithmInterface::CongestionVector* packets_lost));
MOCK_CONST_METHOD0(GetLossTimeout, QuicTime());
private:
DISALLOW_COPY_AND_ASSIGN(MockLossAlgorithm);
};
-class TestEntropyCalculator :
- public QuicReceivedEntropyHashCalculatorInterface {
+class TestEntropyCalculator
+ : public QuicReceivedEntropyHashCalculatorInterface {
public:
TestEntropyCalculator();
~TestEntropyCalculator() override;
@@ -612,25 +651,25 @@ class MockEntropyCalculator : public TestEntropyCalculator {
DISALLOW_COPY_AND_ASSIGN(MockEntropyCalculator);
};
-class MockAckNotifierDelegate : public QuicAckNotifier::DelegateInterface {
+class MockAckListener : public QuicAckListenerInterface {
public:
- MockAckNotifierDelegate();
+ MockAckListener();
+
+ MOCK_METHOD2(OnPacketAcked,
+ void(int acked_bytes, QuicTime::Delta delta_largest_observed));
- MOCK_METHOD3(OnAckNotification,
- void(int num_retransmitted_packets,
- int num_retransmitted_bytes,
- QuicTime::Delta delta_largest_observed));
+ MOCK_METHOD1(OnPacketRetransmitted, void(int retransmitted_bytes));
protected:
// Object is ref counted.
- ~MockAckNotifierDelegate() override;
+ ~MockAckListener() override;
private:
- DISALLOW_COPY_AND_ASSIGN(MockAckNotifierDelegate);
+ DISALLOW_COPY_AND_ASSIGN(MockAckListener);
};
-class MockNetworkChangeVisitor :
- public QuicSentPacketManager::NetworkChangeVisitor {
+class MockNetworkChangeVisitor
+ : public QuicSentPacketManager::NetworkChangeVisitor {
public:
MockNetworkChangeVisitor();
~MockNetworkChangeVisitor() override;
@@ -642,46 +681,6 @@ class MockNetworkChangeVisitor :
DISALLOW_COPY_AND_ASSIGN(MockNetworkChangeVisitor);
};
-// Creates per-connection packet writers that register themselves with the
-// TestWriterFactory on each write so that TestWriterFactory::OnPacketSent can
-// be routed to the appropriate QuicConnection.
-class TestWriterFactory : public tools::QuicDispatcher::PacketWriterFactory {
- public:
- TestWriterFactory();
- ~TestWriterFactory() override;
-
- QuicPacketWriter* Create(QuicPacketWriter* writer,
- QuicConnection* connection) override;
-
- // Calls OnPacketSent on the last QuicConnection to write through one of the
- // packet writers created by this factory.
- void OnPacketSent(WriteResult result);
-
- private:
- class PerConnectionPacketWriter
- : public tools::QuicPerConnectionPacketWriter {
- public:
- PerConnectionPacketWriter(TestWriterFactory* factory,
- QuicPacketWriter* writer,
- QuicConnection* connection);
- ~PerConnectionPacketWriter() override;
-
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const IPAddressNumber& self_address,
- const IPEndPoint& peer_address) override;
-
- private:
- TestWriterFactory* factory_;
- };
-
- // If an asynchronous write is happening and |writer| gets deleted, this
- // clears the pointer to it to prevent use-after-free.
- void Unregister(PerConnectionPacketWriter* writer);
-
- PerConnectionPacketWriter* current_writer_;
-};
-
class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
public:
MockQuicConnectionDebugVisitor();
@@ -689,12 +688,11 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&));
- MOCK_METHOD6(OnPacketSent,
+ MOCK_METHOD5(OnPacketSent,
void(const SerializedPacket&,
QuicPacketNumber,
- EncryptionLevel,
TransmissionType,
- const QuicEncryptedPacket&,
+ size_t encrypted_length,
QuicTime));
MOCK_METHOD3(OnPacketReceived,
@@ -708,6 +706,8 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
MOCK_METHOD1(OnPacketHeader, void(const QuicPacketHeader& header));
+ MOCK_METHOD1(OnSuccessfulVersionNegotiation, void(const QuicVersion&));
+
MOCK_METHOD1(OnStreamFrame, void(const QuicStreamFrame&));
MOCK_METHOD1(OnAckFrame, void(const QuicAckFrame& frame));
@@ -727,6 +727,24 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
void(const QuicPacketHeader&, StringPiece payload));
};
+class MockReceivedPacketManager : public QuicReceivedPacketManager {
+ public:
+ explicit MockReceivedPacketManager(QuicConnectionStats* stats);
+ ~MockReceivedPacketManager() override;
+
+ MOCK_METHOD3(RecordPacketReceived,
+ void(QuicByteCount bytes,
+ const QuicPacketHeader& header,
+ QuicTime receipt_time));
+ MOCK_METHOD1(RecordPacketRevived, void(QuicPacketNumber packet_number));
+ MOCK_METHOD1(IsMissing, bool(QuicPacketNumber packet_number));
+ MOCK_METHOD1(IsAwaitingPacket, bool(QuicPacketNumber packet_number));
+ MOCK_METHOD1(UpdatePacketInformationSentByPeer,
+ void(const QuicStopWaitingFrame& stop_waiting));
+ MOCK_CONST_METHOD0(HasNewMissingPackets, bool(void));
+ MOCK_CONST_METHOD0(ack_frame_updated, bool(void));
+};
+
// Creates a client session for testing.
//
// server_id: The server id associated with this stream.
@@ -735,6 +753,8 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
// Needed for strike-register nonce verification. The client
// connection_start_time should be synchronized witht the server
// start time, otherwise nonce verification will fail.
+// supported_versions: Set of QUIC versions this client supports.
+// helper: Pointer to the MockConnectionHelper to use for the session.
// crypto_client_config: Pointer to the crypto client config.
// client_connection: Pointer reference for newly created
// connection. This object will be owned by the
@@ -744,6 +764,8 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
void CreateClientSessionForTest(QuicServerId server_id,
bool supports_stateless_rejects,
QuicTime::Delta connection_start_time,
+ QuicVersionVector supported_versions,
+ MockConnectionHelper* helper,
QuicCryptoClientConfig* crypto_client_config,
PacketSavingConnection** client_connection,
TestQuicSpdyClientSession** client_session);
@@ -755,6 +777,8 @@ void CreateClientSessionForTest(QuicServerId server_id,
// Needed for strike-register nonce verification. The server
// connection_start_time should be synchronized witht the client
// start time, otherwise nonce verification will fail.
+// supported_versions: Set of QUIC versions this server supports.
+// helper: Pointer to the MockConnectionHelper to use for the session.
// crypto_server_config: Pointer to the crypto server config.
// server_connection: Pointer reference for newly created
// connection. This object will be owned by the
@@ -763,10 +787,16 @@ void CreateClientSessionForTest(QuicServerId server_id,
// session. The new object will be owned by the caller.
void CreateServerSessionForTest(QuicServerId server_id,
QuicTime::Delta connection_start_time,
+ QuicVersionVector supported_versions,
+ MockConnectionHelper* helper,
QuicCryptoServerConfig* crypto_server_config,
PacketSavingConnection** server_connection,
TestQuicSpdyServerSession** server_session);
+// Helper to generate client side stream ids, generalizes
+// kClientDataStreamId1 etc. above.
+QuicStreamId QuicClientDataStreamId(int i);
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/reliable_quic_stream_peer.cc b/chromium/net/quic/test_tools/reliable_quic_stream_peer.cc
index a2646b74f7d..97a7278c45c 100644
--- a/chromium/net/quic/test_tools/reliable_quic_stream_peer.cc
+++ b/chromium/net/quic/test_tools/reliable_quic_stream_peer.cc
@@ -27,6 +27,11 @@ void ReliableQuicStreamPeer::SetStreamBytesWritten(
}
// static
+bool ReliableQuicStreamPeer::read_side_closed(ReliableQuicStream* stream) {
+ return stream->read_side_closed();
+}
+
+// static
void ReliableQuicStreamPeer::CloseReadSide(ReliableQuicStream* stream) {
stream->CloseReadSide();
}
@@ -37,13 +42,33 @@ bool ReliableQuicStreamPeer::FinSent(ReliableQuicStream* stream) {
}
// static
+bool ReliableQuicStreamPeer::FinReceived(ReliableQuicStream* stream) {
+ return stream->fin_received_;
+}
+
+// static
bool ReliableQuicStreamPeer::RstSent(ReliableQuicStream* stream) {
return stream->rst_sent_;
}
// static
-uint32 ReliableQuicStreamPeer::SizeOfQueuedData(ReliableQuicStream* stream) {
- uint32 total = 0;
+bool ReliableQuicStreamPeer::RstReceived(ReliableQuicStream* stream) {
+ return stream->rst_received_;
+}
+
+// static
+bool ReliableQuicStreamPeer::ReadSideClosed(ReliableQuicStream* stream) {
+ return stream->read_side_closed_;
+}
+
+// static
+bool ReliableQuicStreamPeer::WriteSideClosed(ReliableQuicStream* stream) {
+ return stream->write_side_closed_;
+}
+
+// static
+uint32_t ReliableQuicStreamPeer::SizeOfQueuedData(ReliableQuicStream* stream) {
+ uint32_t total = 0;
std::list<ReliableQuicStream::PendingData>::iterator it =
stream->queued_data_.begin();
while (it != stream->queued_data_.end()) {
@@ -70,7 +95,7 @@ void ReliableQuicStreamPeer::WriteOrBufferData(
ReliableQuicStream* stream,
StringPiece data,
bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
+ QuicAckListenerInterface* ack_notifier_delegate) {
stream->WriteOrBufferData(data, fin, ack_notifier_delegate);
}
diff --git a/chromium/net/quic/test_tools/reliable_quic_stream_peer.h b/chromium/net/quic/test_tools/reliable_quic_stream_peer.h
index 7ea7ff3e364..db172da1061 100644
--- a/chromium/net/quic/test_tools/reliable_quic_stream_peer.h
+++ b/chromium/net/quic/test_tools/reliable_quic_stream_peer.h
@@ -5,9 +5,10 @@
#ifndef NET_QUIC_TEST_TOOLS_RELIABLE_QUIC_STREAM_PEER_H_
#define NET_QUIC_TEST_TOOLS_RELIABLE_QUIC_STREAM_PEER_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/strings/string_piece.h"
-#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -21,12 +22,18 @@ class ReliableQuicStreamPeer {
static void SetWriteSideClosed(bool value, ReliableQuicStream* stream);
static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written,
ReliableQuicStream* stream);
+ static bool read_side_closed(ReliableQuicStream* stream);
static void CloseReadSide(ReliableQuicStream* stream);
static bool FinSent(ReliableQuicStream* stream);
+ static bool FinReceived(ReliableQuicStream* stream);
static bool RstSent(ReliableQuicStream* stream);
+ static bool RstReceived(ReliableQuicStream* stream);
+
+ static bool ReadSideClosed(ReliableQuicStream* stream);
+ static bool WriteSideClosed(ReliableQuicStream* stream);
- static uint32 SizeOfQueuedData(ReliableQuicStream* stream);
+ static uint32_t SizeOfQueuedData(ReliableQuicStream* stream);
static void SetFecPolicy(ReliableQuicStream* stream, FecPolicy fec_policy);
@@ -37,7 +44,7 @@ class ReliableQuicStreamPeer {
ReliableQuicStream* stream,
base::StringPiece data,
bool fin,
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
+ QuicAckListenerInterface* ack_notifier_delegate);
private:
DISALLOW_COPY_AND_ASSIGN(ReliableQuicStreamPeer);
diff --git a/chromium/net/quic/test_tools/rtt_stats_peer.h b/chromium/net/quic/test_tools/rtt_stats_peer.h
index 640d9b6cc8a..ac528b5ada7 100644
--- a/chromium/net/quic/test_tools/rtt_stats_peer.h
+++ b/chromium/net/quic/test_tools/rtt_stats_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
#define NET_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
+#include "base/macros.h"
#include "net/quic/congestion_control/rtt_stats.h"
#include "net/quic/quic_time.h"
diff --git a/chromium/net/quic/test_tools/simple_quic_framer.cc b/chromium/net/quic/test_tools/simple_quic_framer.cc
index 7784695d035..7b65ca7c41d 100644
--- a/chromium/net/quic/test_tools/simple_quic_framer.cc
+++ b/chromium/net/quic/test_tools/simple_quic_framer.cc
@@ -4,6 +4,7 @@
#include "net/quic/test_tools/simple_quic_framer.h"
+#include "base/macros.h"
#include "base/stl_util.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
@@ -17,11 +18,12 @@ namespace test {
class SimpleFramerVisitor : public QuicFramerVisitorInterface {
public:
- SimpleFramerVisitor()
- : error_(QUIC_NO_ERROR) {
- }
+ SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {}
- ~SimpleFramerVisitor() override { STLDeleteElements(&stream_data_); }
+ ~SimpleFramerVisitor() override {
+ STLDeleteElements(&stream_frames_);
+ STLDeleteElements(&stream_data_);
+ }
void OnError(QuicFramer* framer) override { error_ = framer->error(); }
@@ -33,8 +35,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
}
void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) override {
- version_negotiation_packet_.reset(
- new QuicVersionNegotiationPacket(packet));
+ version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
}
void OnRevivedPacket() override {}
@@ -57,12 +58,12 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
bool OnStreamFrame(const QuicStreamFrame& frame) override {
// Save a copy of the data so it is valid after the packet is processed.
string* string_data = new string();
- frame.data.AppendToString(string_data);
+ StringPiece(frame.frame_buffer, frame.frame_length)
+ .AppendToString(string_data);
stream_data_.push_back(string_data);
- QuicStreamFrame stream_frame(frame);
- // Make sure that the stream frame points to this data.
- stream_frame.data = StringPiece(*string_data);
- stream_frames_.push_back(stream_frame);
+ // TODO(ianswett): A pointer isn't necessary with emplace_back.
+ stream_frames_.push_back(new QuicStreamFrame(
+ frame.stream_id, frame.fin, frame.offset, StringPiece(*string_data)));
return true;
}
@@ -81,10 +82,8 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
return true;
}
- void OnFecData(const QuicFecData& fec) override {
- fec_data_ = fec;
- fec_redundancy_ = fec_data_.redundancy.as_string();
- fec_data_.redundancy = fec_redundancy_;
+ void OnFecData(StringPiece redundancy) override {
+ fec_redundancy_ = redundancy.as_string();
}
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
@@ -125,18 +124,14 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
const vector<QuicRstStreamFrame>& rst_stream_frames() const {
return rst_stream_frames_;
}
- const vector<QuicStreamFrame>& stream_frames() const {
+ const vector<QuicStreamFrame*>& stream_frames() const {
return stream_frames_;
}
const vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
return stop_waiting_frames_;
}
- const vector<QuicPingFrame>& ping_frames() const {
- return ping_frames_;
- }
- const QuicFecData& fec_data() const {
- return fec_data_;
- }
+ const vector<QuicPingFrame>& ping_frames() const { return ping_frames_; }
+ StringPiece fec_data() const { return fec_redundancy_; }
const QuicVersionNegotiationPacket* version_negotiation_packet() const {
return version_negotiation_packet_.get();
}
@@ -145,14 +140,13 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
QuicErrorCode error_;
bool has_header_;
QuicPacketHeader header_;
- QuicFecData fec_data_;
scoped_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
scoped_ptr<QuicPublicResetPacket> public_reset_packet_;
string fec_redundancy_;
vector<QuicAckFrame> ack_frames_;
vector<QuicStopWaitingFrame> stop_waiting_frames_;
vector<QuicPingFrame> ping_frames_;
- vector<QuicStreamFrame> stream_frames_;
+ vector<QuicStreamFrame*> stream_frames_;
vector<QuicRstStreamFrame> rst_stream_frames_;
vector<QuicGoAwayFrame> goaway_frames_;
vector<QuicConnectionCloseFrame> connection_close_frames_;
@@ -166,15 +160,12 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
SimpleQuicFramer::SimpleQuicFramer()
: framer_(QuicSupportedVersions(),
QuicTime::Zero(),
- Perspective::IS_SERVER) {
-}
+ Perspective::IS_SERVER) {}
SimpleQuicFramer::SimpleQuicFramer(const QuicVersionVector& supported_versions)
- : framer_(supported_versions, QuicTime::Zero(), Perspective::IS_SERVER) {
-}
+ : framer_(supported_versions, QuicTime::Zero(), Perspective::IS_SERVER) {}
-SimpleQuicFramer::~SimpleQuicFramer() {
-}
+SimpleQuicFramer::~SimpleQuicFramer() {}
bool SimpleQuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
visitor_.reset(new SimpleFramerVisitor);
@@ -186,12 +177,11 @@ void SimpleQuicFramer::Reset() {
visitor_.reset(new SimpleFramerVisitor);
}
-
const QuicPacketHeader& SimpleQuicFramer::header() const {
return visitor_->header();
}
-const QuicFecData& SimpleQuicFramer::fec_data() const {
+StringPiece SimpleQuicFramer::fec_data() const {
return visitor_->fec_data();
}
@@ -205,21 +195,18 @@ QuicFramer* SimpleQuicFramer::framer() {
}
size_t SimpleQuicFramer::num_frames() const {
- return ack_frames().size() +
- goaway_frames().size() +
- rst_stream_frames().size() +
- stop_waiting_frames().size() +
- stream_frames().size() +
- ping_frames().size() +
- connection_close_frames().size();
+ return ack_frames().size() + goaway_frames().size() +
+ rst_stream_frames().size() + stop_waiting_frames().size() +
+ stream_frames().size() + ping_frames().size() +
+ connection_close_frames().size();
}
const vector<QuicAckFrame>& SimpleQuicFramer::ack_frames() const {
return visitor_->ack_frames();
}
-const vector<QuicStopWaitingFrame>&
-SimpleQuicFramer::stop_waiting_frames() const {
+const vector<QuicStopWaitingFrame>& SimpleQuicFramer::stop_waiting_frames()
+ const {
return visitor_->stop_waiting_frames();
}
@@ -227,7 +214,7 @@ const vector<QuicPingFrame>& SimpleQuicFramer::ping_frames() const {
return visitor_->ping_frames();
}
-const vector<QuicStreamFrame>& SimpleQuicFramer::stream_frames() const {
+const vector<QuicStreamFrame*>& SimpleQuicFramer::stream_frames() const {
return visitor_->stream_frames();
}
@@ -235,8 +222,7 @@ const vector<QuicRstStreamFrame>& SimpleQuicFramer::rst_stream_frames() const {
return visitor_->rst_stream_frames();
}
-const vector<QuicGoAwayFrame>&
-SimpleQuicFramer::goaway_frames() const {
+const vector<QuicGoAwayFrame>& SimpleQuicFramer::goaway_frames() const {
return visitor_->goaway_frames();
}
diff --git a/chromium/net/quic/test_tools/simple_quic_framer.h b/chromium/net/quic/test_tools/simple_quic_framer.h
index 8628a3f2d9f..c476550be8b 100644
--- a/chromium/net/quic/test_tools/simple_quic_framer.h
+++ b/chromium/net/quic/test_tools/simple_quic_framer.h
@@ -5,10 +5,13 @@
#ifndef NET_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
#define NET_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
+#include <stddef.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_piece.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
@@ -42,8 +45,8 @@ class SimpleQuicFramer {
const std::vector<QuicPingFrame>& ping_frames() const;
const std::vector<QuicGoAwayFrame>& goaway_frames() const;
const std::vector<QuicRstStreamFrame>& rst_stream_frames() const;
- const std::vector<QuicStreamFrame>& stream_frames() const;
- const QuicFecData& fec_data() const;
+ const std::vector<QuicStreamFrame*>& stream_frames() const;
+ base::StringPiece fec_data() const;
const QuicVersionNegotiationPacket* version_negotiation_packet() const;
QuicFramer* framer();
diff --git a/chromium/net/quic/test_tools/test_task_runner.cc b/chromium/net/quic/test_tools/test_task_runner.cc
index 385fd5dfa82..5e6e647d9c7 100644
--- a/chromium/net/quic/test_tools/test_task_runner.cc
+++ b/chromium/net/quic/test_tools/test_task_runner.cc
@@ -12,20 +12,16 @@
namespace net {
namespace test {
-TestTaskRunner::TestTaskRunner(MockClock* clock)
- : clock_(clock) {
-}
+TestTaskRunner::TestTaskRunner(MockClock* clock) : clock_(clock) {}
-TestTaskRunner::~TestTaskRunner() {
-}
+TestTaskRunner::~TestTaskRunner() {}
bool TestTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
EXPECT_GE(delay, base::TimeDelta());
- tasks_.push_back(
- PostedTask(from_here, task, clock_->NowInTicks(), delay,
- base::TestPendingTask::NESTABLE));
+ tasks_.push_back(PostedTask(from_here, task, clock_->NowInTicks(), delay,
+ base::TestPendingTask::NESTABLE));
return false;
}
@@ -60,8 +56,8 @@ struct ShouldRunBeforeLessThan {
} // namespace
std::vector<PostedTask>::iterator TestTaskRunner::FindNextTask() {
- return std::min_element(
- tasks_.begin(), tasks_.end(), ShouldRunBeforeLessThan());
+ return std::min_element(tasks_.begin(), tasks_.end(),
+ ShouldRunBeforeLessThan());
}
} // namespace test
diff --git a/chromium/net/quic/test_tools/test_task_runner.h b/chromium/net/quic/test_tools/test_task_runner.h
index 69a1bcbfe9a..258cf736712 100644
--- a/chromium/net/quic/test_tools/test_task_runner.h
+++ b/chromium/net/quic/test_tools/test_task_runner.h
@@ -9,7 +9,7 @@
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/task_runner.h"
#include "base/test/test_pending_task.h"
diff --git a/chromium/net/sdch/README.md b/chromium/net/sdch/README.md
index 8200ee50528..7735197c4e1 100644
--- a/chromium/net/sdch/README.md
+++ b/chromium/net/sdch/README.md
@@ -63,9 +63,8 @@ and guarantee that the SdchManager outlive the SdchOwner.
Note the layering of the above classes:
-1. The SdchManager and SdchOwner classes have no knowledge of
- URLRequests. URLRequest is dependent on those classes, not the
- reverse.
+1. The SdchManager class has no knowledge of URLRequests. URLRequest
+ is dependent on that class, not the reverse.
2. SdchDictionaryFetcher is dependent on URLRequest, but is still a
utility class exported by the net/ library for use by higher levels.
3. SdchOwner manages the entire system on behalf of the embedder. The
diff --git a/chromium/net/sdch/sdch_owner.cc b/chromium/net/sdch/sdch_owner.cc
index ca9b5a77fab..bfb2dd91b65 100644
--- a/chromium/net/sdch/sdch_owner.cc
+++ b/chromium/net/sdch/sdch_owner.cc
@@ -4,9 +4,12 @@
#include "net/sdch/sdch_owner.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/debug/alias.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/prefs/persistent_pref_store.h"
#include "base/prefs/value_map_pref_store.h"
@@ -52,11 +55,12 @@ void RecordPersistenceFailure(PersistenceFailureReason failure_reason) {
// use of it must be namespace restricted.
// Schema:
// pref_store_->GetValue(kPreferenceName) -> Dictionary {
-// 'version' -> 1 [int]
+// 'version' -> 2 [int]
// 'dictionaries' -> Dictionary {
// server_hash -> {
// 'url' -> URL [string]
// 'last_used' -> seconds since unix epoch [double]
+// 'created_time' -> seconds since unix epoch [double]
// 'use_count' -> use count [int]
// 'size' -> size [int]
// }
@@ -66,10 +70,11 @@ const char kVersionKey[] = "version";
const char kDictionariesKey[] = "dictionaries";
const char kDictionaryUrlKey[] = "url";
const char kDictionaryLastUsedKey[] = "last_used";
+const char kDictionaryCreatedTimeKey[] = "created_time";
const char kDictionaryUseCountKey[] = "use_count";
const char kDictionarySizeKey[] = "size";
-const int kVersion = 1;
+const int kVersion = 2;
// This function returns store[kPreferenceName/kDictionariesKey]. The caller
// is responsible for making sure any needed calls to
@@ -102,7 +107,7 @@ void InitializePrefStore(WriteablePrefStore* store) {
empty_store->SetInteger(kVersionKey, kVersion);
empty_store->Set(kDictionariesKey,
make_scoped_ptr(new base::DictionaryValue));
- store->SetValue(kPreferenceName, empty_store.Pass(),
+ store->SetValue(kPreferenceName, std::move(empty_store),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
}
@@ -125,15 +130,21 @@ class DictionaryPreferenceIterator {
const std::string& server_hash() const { return server_hash_; }
const GURL& url() const { return url_; }
base::Time last_used() const { return last_used_; }
+ base::Time created_time() const { return created_time_; }
int use_count() const { return use_count_; }
int size() const { return size_; }
private:
- void LoadDictionaryOrDie();
+ // Load Dictionary silently skipping any that are malformed.
+ void LoadNextDictionary();
+ // Try to load Dictionary from current iterator's position. Returns true if
+ // succeeded.
+ bool TryLoadDictionary();
std::string server_hash_;
GURL url_;
base::Time last_used_;
+ base::Time created_time_;
int use_count_;
int size_;
@@ -142,9 +153,10 @@ class DictionaryPreferenceIterator {
DictionaryPreferenceIterator::DictionaryPreferenceIterator(
WriteablePrefStore* pref_store)
- : dictionary_iterator_(*GetPersistentStoreDictionaryMap(pref_store)) {
- if (!IsAtEnd())
- LoadDictionaryOrDie();
+ : use_count_(0),
+ size_(0),
+ dictionary_iterator_(*GetPersistentStoreDictionaryMap(pref_store)) {
+ LoadNextDictionary();
}
bool DictionaryPreferenceIterator::IsAtEnd() const {
@@ -153,34 +165,54 @@ bool DictionaryPreferenceIterator::IsAtEnd() const {
void DictionaryPreferenceIterator::Advance() {
dictionary_iterator_.Advance();
- if (!IsAtEnd())
- LoadDictionaryOrDie();
+ LoadNextDictionary();
+}
+
+void DictionaryPreferenceIterator::LoadNextDictionary() {
+ while (!IsAtEnd()) {
+ if (TryLoadDictionary())
+ return;
+ dictionary_iterator_.Advance();
+ }
}
-void DictionaryPreferenceIterator::LoadDictionaryOrDie() {
- double last_used_seconds_from_epoch;
+bool DictionaryPreferenceIterator::TryLoadDictionary() {
const base::DictionaryValue* dict = nullptr;
- bool success =
- dictionary_iterator_.value().GetAsDictionary(&dict);
- DCHECK(success);
+
+ bool success = dictionary_iterator_.value().GetAsDictionary(&dict);
+ if (!success)
+ return false;
server_hash_ = dictionary_iterator_.key();
std::string url_spec;
success = dict->GetString(kDictionaryUrlKey, &url_spec);
- DCHECK(success);
+ if (!success)
+ return false;
url_ = GURL(url_spec);
- success = dict->GetDouble(kDictionaryLastUsedKey,
- &last_used_seconds_from_epoch);
- DCHECK(success);
+ double last_used_seconds_from_epoch = 0;
+ success =
+ dict->GetDouble(kDictionaryLastUsedKey, &last_used_seconds_from_epoch);
+ if (!success)
+ return false;
last_used_ = base::Time::FromDoubleT(last_used_seconds_from_epoch);
success = dict->GetInteger(kDictionaryUseCountKey, &use_count_);
- DCHECK(success);
+ if (!success)
+ return false;
success = dict->GetInteger(kDictionarySizeKey, &size_);
- DCHECK(success);
+ if (!success)
+ return false;
+
+ double created_time_seconds = 0;
+ success = dict->GetDouble(kDictionaryCreatedTimeKey, &created_time_seconds);
+ if (!success)
+ return false;
+ created_time_ = base::Time::FromDoubleT(created_time_seconds);
+
+ return true;
}
// Triggers a ReportValueChanged() on the specified WriteablePrefStore
@@ -280,8 +312,7 @@ SdchOwner::~SdchOwner() {
if (external_pref_store_)
external_pref_store_->RemoveObserver(this);
- int64 object_lifetime =
- (clock_->Now() - creation_time_).InMilliseconds();
+ int64_t object_lifetime = (clock_->Now() - creation_time_).InMilliseconds();
for (const auto& val : consumed_byte_seconds_) {
if (object_lifetime > 0) {
// Objects that are created and immediately destroyed don't add any memory
@@ -312,6 +343,7 @@ void SdchOwner::SetMinSpaceForDictionaryFetch(
}
void SdchOwner::OnDictionaryFetched(base::Time last_used,
+ base::Time created_time,
int use_count,
const std::string& dictionary_text,
const GURL& dictionary_url,
@@ -441,10 +473,12 @@ void SdchOwner::OnDictionaryFetched(base::Time last_used,
dictionary_description->SetString(kDictionaryUrlKey, dictionary_url.spec());
dictionary_description->SetDouble(kDictionaryLastUsedKey,
last_used.ToDoubleT());
+ dictionary_description->SetDouble(kDictionaryCreatedTimeKey,
+ created_time.ToDoubleT());
dictionary_description->SetInteger(kDictionaryUseCountKey, use_count);
dictionary_description->SetInteger(kDictionarySizeKey,
dictionary_text.size());
- pref_dictionary_map->Set(server_hash, dictionary_description.Pass());
+ pref_dictionary_map->Set(server_hash, std::move(dictionary_description));
load_times_[server_hash] = clock_->Now();
}
@@ -489,12 +523,21 @@ void SdchOwner::OnDictionaryUsed(const std::string& server_hash) {
base::TimeDelta time_since_last_used(now -
base::Time::FromDoubleT(last_used_seconds_since_epoch));
- // TODO(rdsmith): Distinguish between "Never used" and "Actually not
- // touched for 48 hours".
- UMA_HISTOGRAM_CUSTOM_TIMES(
- "Sdch3.UsageInterval",
- use_count ? time_since_last_used : base::TimeDelta::FromHours(48),
- base::TimeDelta(), base::TimeDelta::FromHours(48), 50);
+ if (use_count) {
+ UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.UsageInterval2", time_since_last_used,
+ base::TimeDelta(), base::TimeDelta::FromDays(7),
+ 50);
+ } else {
+ double created_time = 0;
+ success = specific_dictionary_map->GetDouble(kDictionaryCreatedTimeKey,
+ &created_time);
+ DCHECK(success);
+ base::TimeDelta time_since_created(now -
+ base::Time::FromDoubleT(created_time));
+ UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.FirstUseInterval", time_since_created,
+ base::TimeDelta(), base::TimeDelta::FromDays(7),
+ 50);
+ }
specific_dictionary_map->SetDouble(kDictionaryLastUsedKey, now.ToDoubleT());
specific_dictionary_map->SetInteger(kDictionaryUseCountKey, use_count + 1);
@@ -524,10 +567,11 @@ void SdchOwner::OnGetDictionary(const GURL& request_url,
return;
}
- fetcher_->Schedule(dictionary_url,
- base::Bind(&SdchOwner::OnDictionaryFetched,
- // SdchOwner will outlive its member variables.
- base::Unretained(this), base::Time(), 0));
+ fetcher_->Schedule(
+ dictionary_url,
+ base::Bind(&SdchOwner::OnDictionaryFetched,
+ // SdchOwner will outlive its member variables.
+ base::Unretained(this), base::Time(), base::Time::Now(), 0));
}
void SdchOwner::OnClearDictionaries() {
@@ -621,7 +665,7 @@ void SdchOwner::OnInitializationCompleted(bool succeeded) {
}
void SdchOwner::SetClockForTesting(scoped_ptr<base::Clock> clock) {
- clock_ = clock.Pass();
+ clock_ = std::move(clock);
}
int SdchOwner::GetDictionaryCountForTesting() const {
@@ -644,7 +688,7 @@ bool SdchOwner::HasDictionaryFromURLForTesting(const GURL& url) const {
void SdchOwner::SetFetcherForTesting(
scoped_ptr<SdchDictionaryFetcher> fetcher) {
- fetcher_.reset(fetcher.release());
+ fetcher_ = std::move(fetcher);
}
void SdchOwner::OnMemoryPressure(
@@ -695,20 +739,24 @@ bool SdchOwner::SchedulePersistedDictionaryLoads(
continue;
GURL dict_url(url_string);
- double last_used;
+ double last_used = 0;
if (!dict_info->GetDouble(kDictionaryLastUsedKey, &last_used))
continue;
- int use_count;
+ int use_count = 0;
if (!dict_info->GetInteger(kDictionaryUseCountKey, &use_count))
continue;
+ double created_time = 0;
+ if (!dict_info->GetDouble(kDictionaryCreatedTimeKey, &created_time))
+ continue;
+
fetcher_->ScheduleReload(
- dict_url, base::Bind(&SdchOwner::OnDictionaryFetched,
- // SdchOwner will outlive its member variables.
- base::Unretained(this),
- base::Time::FromDoubleT(last_used),
- use_count));
+ dict_url,
+ base::Bind(&SdchOwner::OnDictionaryFetched,
+ // SdchOwner will outlive its member variables.
+ base::Unretained(this), base::Time::FromDoubleT(last_used),
+ base::Time::FromDoubleT(created_time), use_count));
}
return true;
diff --git a/chromium/net/sdch/sdch_owner.h b/chromium/net/sdch/sdch_owner.h
index 3d6b59b7661..3c965d92a1e 100644
--- a/chromium/net/sdch/sdch_owner.h
+++ b/chromium/net/sdch/sdch_owner.h
@@ -5,9 +5,13 @@
#ifndef NET_SDCH_SDCH_OWNER_H_
#define NET_SDCH_SDCH_OWNER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
+#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h"
#include "base/prefs/pref_store.h"
@@ -72,6 +76,7 @@ class NET_EXPORT SdchOwner : public SdchObserver, public PrefStore::Observer {
// gotten the dictionary. The first two arguments are bound locally.
// Public for testing.
void OnDictionaryFetched(base::Time last_used,
+ base::Time created_time,
int use_count,
const std::string& dictionary_text,
const GURL& dictionary_url,
@@ -203,7 +208,7 @@ class NET_EXPORT SdchOwner : public SdchObserver, public PrefStore::Observer {
// Byte-seconds consumed by dictionaries that have been unloaded. These are
// stored for later uploading in the SdchOwner destructor.
- std::vector<int64> consumed_byte_seconds_;
+ std::vector<int64_t> consumed_byte_seconds_;
// Creation time for this SdchOwner object, used for reporting temporal memory
// pressure.
diff --git a/chromium/net/sdch/sdch_owner_unittest.cc b/chromium/net/sdch/sdch_owner_unittest.cc
index 149041fd359..9ce957928f2 100644
--- a/chromium/net/sdch/sdch_owner_unittest.cc
+++ b/chromium/net/sdch/sdch_owner_unittest.cc
@@ -2,7 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "net/sdch/sdch_owner.h"
+
+#include <utility>
+
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/prefs/testing_pref_store.h"
#include "base/run_loop.h"
@@ -14,7 +19,6 @@
#include "base/values.h"
#include "net/base/sdch_manager.h"
#include "net/log/net_log.h"
-#include "net/sdch/sdch_owner.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_error_job.h"
@@ -311,8 +315,9 @@ class SdchOwnerTest : public testing::Test {
// SdchOwner::OnDictionaryFetched(), and return whether that
// addition was successful or not.
bool CreateAndAddDictionary(size_t size,
- std::string* server_hash_p,
- base::Time last_used_time) {
+ base::Time last_used_time,
+ base::Time created_time,
+ std::string* server_hash_p) {
GURL dictionary_url(
base::StringPrintf("%s/d%d", generic_url, dictionary_creation_index_));
std::string dictionary_text(NewSdchDictionary(size - 4));
@@ -324,13 +329,21 @@ class SdchOwnerTest : public testing::Test {
if (DictionaryPresentInManager(server_hash))
return false;
- sdch_owner().OnDictionaryFetched(last_used_time, 0, dictionary_text,
- dictionary_url, net_log_, false);
+ sdch_owner().OnDictionaryFetched(last_used_time, created_time, 0,
+ dictionary_text, dictionary_url, net_log_,
+ false);
if (server_hash_p)
*server_hash_p = server_hash;
return DictionaryPresentInManager(server_hash);
}
+ bool CreateAndAddDictionary(size_t size,
+ base::Time last_used_time,
+ std::string* server_hash_p) {
+ return CreateAndAddDictionary(size, last_used_time, base::Time(),
+ server_hash_p);
+ }
+
void ResetOwner() {
sdch_owner_.reset(new SdchOwner(&sdch_manager_, &url_request_context_));
}
@@ -366,8 +379,9 @@ TEST_F(SdchOwnerTest, OnGetDictionary_Fetching) {
// Fetch generated when half full.
GURL dict_url2(std::string(generic_url) + "/d2");
std::string dictionary1(NewSdchDictionary(kMaxSizeForTesting / 2));
- sdch_owner().OnDictionaryFetched(base::Time::Now(), 1, dictionary1,
- dict_url1, bound_net_log(), false);
+ sdch_owner().OnDictionaryFetched(base::Time::Now(), base::Time::Now(), 1,
+ dictionary1, dict_url1, bound_net_log(),
+ false);
EXPECT_EQ(0, JobsRecentlyCreated());
SignalGetDictionaryAndClearJobs(request_url, dict_url2);
EXPECT_EQ(1, JobsRecentlyCreated());
@@ -376,8 +390,9 @@ TEST_F(SdchOwnerTest, OnGetDictionary_Fetching) {
GURL dict_url3(std::string(generic_url) + "/d3");
std::string dictionary2(NewSdchDictionary(
(kMaxSizeForTesting / 2 - kMinFetchSpaceForTesting / 2)));
- sdch_owner().OnDictionaryFetched(base::Time::Now(), 1, dictionary2,
- dict_url2, bound_net_log(), false);
+ sdch_owner().OnDictionaryFetched(base::Time::Now(), base::Time::Now(), 1,
+ dictionary2, dict_url2, bound_net_log(),
+ false);
EXPECT_EQ(0, JobsRecentlyCreated());
SignalGetDictionaryAndClearJobs(request_url, dict_url3);
EXPECT_EQ(0, JobsRecentlyCreated());
@@ -394,18 +409,18 @@ TEST_F(SdchOwnerTest, OnDictionaryFetched_Fetching) {
base::TimeDelta::FromMinutes(30));
// Add successful when empty.
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, nullptr,
- dictionary_last_used_time));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2,
+ dictionary_last_used_time, nullptr));
EXPECT_EQ(0, JobsRecentlyCreated());
// Add successful when half full.
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, nullptr,
- dictionary_last_used_time));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2,
+ dictionary_last_used_time, nullptr));
EXPECT_EQ(0, JobsRecentlyCreated());
// Add unsuccessful when full.
- EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting / 2, nullptr,
- dictionary_last_used_time));
+ EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting / 2,
+ dictionary_last_used_time, nullptr));
EXPECT_EQ(0, JobsRecentlyCreated());
}
@@ -425,9 +440,9 @@ TEST_F(SdchOwnerTest, ConfirmAutoEviction) {
base::Time stale(base::Time::Now() - base::TimeDelta::FromHours(25));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d1, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, fresh, &server_hash_d1));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d2, stale));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, stale, &server_hash_d2));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
@@ -438,7 +453,7 @@ TEST_F(SdchOwnerTest, ConfirmAutoEviction) {
test_clock->Advance(synthetic_delta);
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d3, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, fresh, &server_hash_d3));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));
@@ -481,12 +496,12 @@ TEST_F(SdchOwnerTest, ConfirmAutoEviction_2) {
base::Time fresh(base::Time::Now() - base::TimeDelta::FromHours(23));
base::Time stale(base::Time::Now() - base::TimeDelta::FromHours(25));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d1, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, fresh, &server_hash_d1));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2, stale));
+ CreateAndAddDictionary(kMaxSizeForTesting / 4, stale, &server_hash_d2));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3, stale));
+ CreateAndAddDictionary(kMaxSizeForTesting / 4, stale, &server_hash_d3));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
@@ -494,7 +509,7 @@ TEST_F(SdchOwnerTest, ConfirmAutoEviction_2) {
std::string server_hash_d4;
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, fresh, &server_hash_d4));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
EXPECT_FALSE(DictionaryPresentInManager(server_hash_d3));
@@ -514,13 +529,13 @@ TEST_F(SdchOwnerTest, ConfirmAutoEviction_Oldest) {
base::Time stale_older(base::Time::Now() - base::TimeDelta::FromHours(71));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d1, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 4, fresh, &server_hash_d1));
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2,
- stale_newer));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, stale_newer,
+ &server_hash_d2));
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3,
- stale_older));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, stale_older,
+ &server_hash_d3));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
@@ -531,7 +546,7 @@ TEST_F(SdchOwnerTest, ConfirmAutoEviction_Oldest) {
std::string server_hash_d4;
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, fresh, &server_hash_d4));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
EXPECT_FALSE(DictionaryPresentInManager(server_hash_d3));
@@ -551,13 +566,13 @@ TEST_F(SdchOwnerTest, UseChangesEviction) {
base::Time stale_older(base::Time::Now() - base::TimeDelta::FromHours(71));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d1, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 4, fresh, &server_hash_d1));
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2,
- stale_newer));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, stale_newer,
+ &server_hash_d2));
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3,
- stale_older));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, stale_older,
+ &server_hash_d3));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
@@ -570,7 +585,7 @@ TEST_F(SdchOwnerTest, UseChangesEviction) {
// newer stale one.
std::string server_hash_d4;
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, fresh, &server_hash_d4));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));
@@ -590,13 +605,13 @@ TEST_F(SdchOwnerTest, UsePreventsAddition) {
base::Time stale_older(base::Time::Now() - base::TimeDelta::FromHours(71));
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d1, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 4, fresh, &server_hash_d1));
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2,
- stale_newer));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, stale_newer,
+ &server_hash_d2));
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3,
- stale_older));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, stale_older,
+ &server_hash_d3));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
@@ -609,7 +624,7 @@ TEST_F(SdchOwnerTest, UsePreventsAddition) {
// The addition of a new dictionary should fail, not evicting anything.
std::string server_hash_d4;
EXPECT_FALSE(
- CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
+ CreateAndAddDictionary(kMaxSizeForTesting / 2, fresh, &server_hash_d4));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));
@@ -622,11 +637,11 @@ TEST_F(SdchOwnerTest, ClearReturnsSpace) {
std::string server_hash_d2;
// Take up all the space.
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d1,
- base::Time::Now()));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(),
+ &server_hash_d1));
// Addition should fail.
- EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d2,
- base::Time::Now()));
+ EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(),
+ &server_hash_d2));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
sdch_manager().ClearData();
@@ -635,7 +650,7 @@ TEST_F(SdchOwnerTest, ClearReturnsSpace) {
// Addition should now succeed.
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting, nullptr, base::Time::Now()));
+ CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(), nullptr));
}
// Confirm memory pressure gets all the space back.
@@ -644,12 +659,12 @@ TEST_F(SdchOwnerTest, MemoryPressureReturnsSpace) {
std::string server_hash_d2;
// Take up all the space.
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d1,
- base::Time::Now()));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(),
+ &server_hash_d1));
// Addition should fail.
- EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d2,
- base::Time::Now()));
+ EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(),
+ &server_hash_d2));
EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
@@ -666,7 +681,7 @@ TEST_F(SdchOwnerTest, MemoryPressureReturnsSpace) {
// Addition should now succeed.
EXPECT_TRUE(
- CreateAndAddDictionary(kMaxSizeForTesting, nullptr, base::Time::Now()));
+ CreateAndAddDictionary(kMaxSizeForTesting, base::Time::Now(), nullptr));
}
// Confirm that use of a pinned dictionary after its removal works properly.
@@ -675,8 +690,8 @@ TEST_F(SdchOwnerTest, PinRemoveUse) {
sdch_owner().EnablePersistentStorage(&pref_store());
std::string server_hash_d1;
- EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d1,
- base::Time::Now()));
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, base::Time::Now(),
+ &server_hash_d1));
scoped_ptr<SdchManager::DictionarySet> return_set(
sdch_manager().GetDictionarySet(
@@ -711,6 +726,27 @@ TEST_F(SdchOwnerTest, PinRemoveUse) {
EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result));
}
+TEST_F(SdchOwnerTest, UsageIntervalMetrics) {
+ const GURL url("http://www.example.com/dict0");
+
+ std::string server_hash;
+ base::Time last_used_time(base::Time::Now() - base::TimeDelta::FromHours(23));
+ base::Time created_time(base::Time::Now() - base::TimeDelta::FromHours(47));
+
+ EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 3, last_used_time,
+ created_time, &server_hash));
+
+ base::HistogramTester tester;
+
+ sdch_owner().OnDictionaryUsed(server_hash);
+ tester.ExpectTotalCount("Sdch3.FirstUseInterval", 1);
+ tester.ExpectTotalCount("Sdch3.UsageInterval2", 0);
+
+ sdch_owner().OnDictionaryUsed(server_hash);
+ tester.ExpectTotalCount("Sdch3.FirstUseInterval", 1); // count didn't change
+ tester.ExpectTotalCount("Sdch3.UsageInterval2", 1);
+}
+
class SdchOwnerPersistenceTest : public ::testing::Test {
public:
SdchOwnerPersistenceTest() : pref_store_(new TestingPrefStore()) {
@@ -739,9 +775,9 @@ class SdchOwnerPersistenceTest : public ::testing::Test {
}
void InsertDictionaryForURL(const GURL& url, const std::string& nonce) {
- owner_->OnDictionaryFetched(base::Time::Now(), 1,
- CreateDictionary(url, nonce),
- url, net_log_, false);
+ owner_->OnDictionaryFetched(base::Time::Now(), base::Time::Now(), 1,
+ CreateDictionary(url, nonce), url, net_log_,
+ false);
}
bool CompleteLoadFromURL(const GURL& url, const std::string& nonce,
@@ -787,7 +823,7 @@ TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDict) {
TEST_F(SdchOwnerPersistenceTest, Persistent_BadVersion) {
scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue());
sdch_dict->SetInteger("version", 2);
- pref_store_->SetValue("SDCH", sdch_dict.Pass(),
+ pref_store_->SetValue("SDCH", std::move(sdch_dict),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
ResetOwner(false);
@@ -799,8 +835,8 @@ TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDictList) {
scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue());
scoped_ptr<base::DictionaryValue> dicts(new base::DictionaryValue());
sdch_dict->SetInteger("version", 1);
- sdch_dict->Set("dictionaries", dicts.Pass());
- pref_store_->SetValue("SDCH", sdch_dict.Pass(),
+ sdch_dict->Set("dictionaries", std::move(dicts));
+ pref_store_->SetValue("SDCH", std::move(sdch_dict),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
ResetOwner(false);
diff --git a/chromium/net/server/http_connection.cc b/chromium/net/server/http_connection.cc
index 3401f8161d8..d4d16cae191 100644
--- a/chromium/net/server/http_connection.cc
+++ b/chromium/net/server/http_connection.cc
@@ -4,6 +4,8 @@
#include "net/server/http_connection.h"
+#include <utility>
+
#include "base/logging.h"
#include "net/server/web_socket.h"
#include "net/socket/stream_socket.h"
@@ -150,17 +152,16 @@ int HttpConnection::QueuedWriteIOBuffer::GetSizeToWrite() const {
HttpConnection::HttpConnection(int id, scoped_ptr<StreamSocket> socket)
: id_(id),
- socket_(socket.Pass()),
+ socket_(std::move(socket)),
read_buf_(new ReadIOBuffer()),
- write_buf_(new QueuedWriteIOBuffer()) {
-}
+ write_buf_(new QueuedWriteIOBuffer()) {}
HttpConnection::~HttpConnection() {
}
void HttpConnection::SetWebSocket(scoped_ptr<WebSocket> web_socket) {
DCHECK(!web_socket_);
- web_socket_ = web_socket.Pass();
+ web_socket_ = std::move(web_socket);
}
} // namespace net
diff --git a/chromium/net/server/http_connection.h b/chromium/net/server/http_connection.h
index 8163ced6884..8103e4e5072 100644
--- a/chromium/net/server/http_connection.h
+++ b/chromium/net/server/http_connection.h
@@ -8,7 +8,7 @@
#include <queue>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/io_buffer.h"
diff --git a/chromium/net/server/http_server.cc b/chromium/net/server/http_server.cc
index f3560e8cabd..ab05af87ed8 100644
--- a/chromium/net/server/http_server.cc
+++ b/chromium/net/server/http_server.cc
@@ -4,6 +4,8 @@
#include "net/server/http_server.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
@@ -29,7 +31,7 @@ namespace net {
HttpServer::HttpServer(scoped_ptr<ServerSocket> server_socket,
HttpServer::Delegate* delegate)
- : server_socket_(server_socket.Pass()),
+ : server_socket_(std::move(server_socket)),
delegate_(delegate),
last_id_(0),
weak_ptr_factory_(this) {
@@ -123,13 +125,13 @@ int HttpServer::GetLocalAddress(IPEndPoint* address) {
return server_socket_->GetLocalAddress(address);
}
-void HttpServer::SetReceiveBufferSize(int connection_id, int32 size) {
+void HttpServer::SetReceiveBufferSize(int connection_id, int32_t size) {
HttpConnection* connection = FindConnection(connection_id);
if (connection)
connection->read_buf()->set_max_buffer_size(size);
}
-void HttpServer::SetSendBufferSize(int connection_id, int32 size) {
+void HttpServer::SetSendBufferSize(int connection_id, int32_t size) {
HttpConnection* connection = FindConnection(connection_id);
if (connection)
connection->write_buf()->set_max_buffer_size(size);
@@ -159,7 +161,7 @@ int HttpServer::HandleAcceptResult(int rv) {
}
HttpConnection* connection =
- new HttpConnection(++last_id_, accepted_socket_.Pass());
+ new HttpConnection(++last_id_, std::move(accepted_socket_));
id_to_connection_[connection->id()] = connection;
delegate_->OnConnect(connection->id());
if (!HasClosedConnection(connection))
@@ -346,17 +348,16 @@ enum header_parse_states {
};
// State transition table
-int parser_state[MAX_STATES][MAX_INPUTS] = {
-/* METHOD */ { ST_URL, ST_ERR, ST_ERR, ST_ERR, ST_METHOD },
-/* URL */ { ST_PROTO, ST_ERR, ST_ERR, ST_URL, ST_URL },
-/* PROTOCOL */ { ST_ERR, ST_HEADER, ST_NAME, ST_ERR, ST_PROTO },
-/* HEADER */ { ST_ERR, ST_ERR, ST_NAME, ST_ERR, ST_ERR },
-/* NAME */ { ST_SEPARATOR, ST_DONE, ST_ERR, ST_VALUE, ST_NAME },
-/* SEPARATOR */ { ST_SEPARATOR, ST_ERR, ST_ERR, ST_VALUE, ST_ERR },
-/* VALUE */ { ST_VALUE, ST_HEADER, ST_NAME, ST_VALUE, ST_VALUE },
-/* DONE */ { ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE },
-/* ERR */ { ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR }
-};
+const int parser_state[MAX_STATES][MAX_INPUTS] = {
+ /* METHOD */ {ST_URL, ST_ERR, ST_ERR, ST_ERR, ST_METHOD},
+ /* URL */ {ST_PROTO, ST_ERR, ST_ERR, ST_URL, ST_URL},
+ /* PROTOCOL */ {ST_ERR, ST_HEADER, ST_NAME, ST_ERR, ST_PROTO},
+ /* HEADER */ {ST_ERR, ST_ERR, ST_NAME, ST_ERR, ST_ERR},
+ /* NAME */ {ST_SEPARATOR, ST_DONE, ST_ERR, ST_VALUE, ST_NAME},
+ /* SEPARATOR */ {ST_SEPARATOR, ST_ERR, ST_ERR, ST_VALUE, ST_ERR},
+ /* VALUE */ {ST_VALUE, ST_HEADER, ST_NAME, ST_VALUE, ST_VALUE},
+ /* DONE */ {ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE},
+ /* ERR */ {ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR}};
// Convert an input character to the parser's input token.
int charToInput(char ch) {
diff --git a/chromium/net/server/http_server.h b/chromium/net/server/http_server.h
index b8be0ed6ab6..7e103ddb4fc 100644
--- a/chromium/net/server/http_server.h
+++ b/chromium/net/server/http_server.h
@@ -5,10 +5,12 @@
#ifndef NET_SERVER_HTTP_SERVER_H_
#define NET_SERVER_HTTP_SERVER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -71,8 +73,8 @@ class HttpServer {
void Close(int connection_id);
- void SetReceiveBufferSize(int connection_id, int32 size);
- void SetSendBufferSize(int connection_id, int32 size);
+ void SetReceiveBufferSize(int connection_id, int32_t size);
+ void SetSendBufferSize(int connection_id, int32_t size);
// Copies the local address to |address|. Returns a network error code.
int GetLocalAddress(IPEndPoint* address);
diff --git a/chromium/net/server/http_server_response_info.h b/chromium/net/server/http_server_response_info.h
index e583e0ddd2a..fd8dfbc30b7 100644
--- a/chromium/net/server/http_server_response_info.h
+++ b/chromium/net/server/http_server_response_info.h
@@ -5,6 +5,8 @@
#ifndef NET_SERVER_HTTP_SERVER_RESPONSE_INFO_H_
#define NET_SERVER_HTTP_SERVER_RESPONSE_INFO_H_
+#include <stddef.h>
+
#include <string>
#include <utility>
diff --git a/chromium/net/server/http_server_unittest.cc b/chromium/net/server/http_server_unittest.cc
index 170a7203d5e..bda95d1180a 100644
--- a/chromium/net/server/http_server_unittest.cc
+++ b/chromium/net/server/http_server_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <algorithm>
#include <utility>
#include <vector>
@@ -12,6 +14,8 @@
#include "base/compiler_specific.h"
#include "base/format_macros.h"
#include "base/location.h"
+#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -161,7 +165,7 @@ class TestHttpClient {
return false;
// Return true if response has data equal to or more than content length.
- int64 body_size = static_cast<int64>(response.size()) - end_of_headers;
+ int64_t body_size = static_cast<int64_t>(response.size()) - end_of_headers;
DCHECK_LE(0, body_size);
scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(
HttpUtil::AssembleRawHeaders(response.data(), end_of_headers)));
@@ -185,7 +189,7 @@ class HttpServerTest : public testing::Test,
scoped_ptr<ServerSocket> server_socket(
new TCPServerSocket(NULL, NetLog::Source()));
server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1);
- server_.reset(new HttpServer(server_socket.Pass(), this));
+ server_.reset(new HttpServer(std::move(server_socket), this));
ASSERT_EQ(OK, server_->GetLocalAddress(&server_address_));
}
@@ -503,6 +507,10 @@ class MockStreamSocket : public StreamSocket {
}
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
// Socket
int Read(IOBuffer* buf,
@@ -529,8 +537,10 @@ class MockStreamSocket : public StreamSocket {
const CompletionCallback& callback) override {
return ERR_NOT_IMPLEMENTED;
}
- int SetReceiveBufferSize(int32 size) override { return ERR_NOT_IMPLEMENTED; }
- int SetSendBufferSize(int32 size) override { return ERR_NOT_IMPLEMENTED; }
+ int SetReceiveBufferSize(int32_t size) override {
+ return ERR_NOT_IMPLEMENTED;
+ }
+ int SetSendBufferSize(int32_t size) override { return ERR_NOT_IMPLEMENTED; }
void DidRead(const char* data, int data_len) {
if (!read_buf_.get()) {
diff --git a/chromium/net/server/web_socket.h b/chromium/net/server/web_socket.h
index 5309544182a..19e9c71a5dc 100644
--- a/chromium/net/server/web_socket.h
+++ b/chromium/net/server/web_socket.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
diff --git a/chromium/net/server/web_socket_encoder.cc b/chromium/net/server/web_socket_encoder.cc
index b1b93eed064..6d59713d9b3 100644
--- a/chromium/net/server/web_socket_encoder.cc
+++ b/chromium/net/server/web_socket_encoder.cc
@@ -4,6 +4,7 @@
#include "net/server/web_socket_encoder.h"
+#include <utility>
#include <vector>
#include "base/logging.h"
@@ -91,7 +92,7 @@ WebSocket::ParseResult DecodeFrameHybi17(const base::StringPiece& frame,
if (client_frame && !masked) // In Hybi-17 spec client MUST mask its frame.
return WebSocket::FRAME_ERROR;
- uint64 payload_length64 = second_byte & kPayloadLengthMask;
+ uint64_t payload_length64 = second_byte & kPayloadLengthMask;
if (payload_length64 > kMaxSingleBytePayloadLength) {
int extended_payload_length_size;
if (payload_length64 == kTwoBytePayloadLengthField)
@@ -110,7 +111,7 @@ WebSocket::ParseResult DecodeFrameHybi17(const base::StringPiece& frame,
}
size_t actual_masking_key_length = masked ? kMaskingKeyWidthInBytes : 0;
- static const uint64 max_payload_length = 0x7FFFFFFFFFFFFFFFull;
+ static const uint64_t max_payload_length = 0x7FFFFFFFFFFFFFFFull;
static size_t max_length = std::numeric_limits<size_t>::max();
if (payload_length64 > max_payload_length ||
payload_length64 + actual_masking_key_length > max_length) {
@@ -149,9 +150,9 @@ void EncodeFrameHybi17(const std::string& message,
int reserved1 = compressed ? kReserved1Bit : 0;
frame.push_back(kFinalBit | op_code | reserved1);
char mask_key_bit = masking_key != 0 ? kMaskBit : 0;
- if (data_length <= kMaxSingleBytePayloadLength)
- frame.push_back(data_length | mask_key_bit);
- else if (data_length <= 0xFFFF) {
+ if (data_length <= kMaxSingleBytePayloadLength) {
+ frame.push_back(static_cast<char>(data_length) | mask_key_bit);
+ } else if (data_length <= 0xFFFF) {
frame.push_back(kTwoBytePayloadLengthField | mask_key_bit);
frame.push_back((data_length & 0xFF00) >> 8);
frame.push_back(data_length & 0xFF);
@@ -226,8 +227,8 @@ scoped_ptr<WebSocketEncoder> WebSocketEncoder::CreateServer(
continue;
}
*deflate_parameters = response;
- return make_scoped_ptr(
- new WebSocketEncoder(FOR_SERVER, deflater.Pass(), inflater.Pass()));
+ return make_scoped_ptr(new WebSocketEncoder(FOR_SERVER, std::move(deflater),
+ std::move(inflater)));
}
// We cannot find an acceptable offer.
@@ -235,7 +236,7 @@ scoped_ptr<WebSocketEncoder> WebSocketEncoder::CreateServer(
}
// static
-WebSocketEncoder* WebSocketEncoder::CreateClient(
+scoped_ptr<WebSocketEncoder> WebSocketEncoder::CreateClient(
const std::string& response_extensions) {
// TODO(yhirano): Add a way to return an error.
@@ -246,12 +247,12 @@ WebSocketEncoder* WebSocketEncoder::CreateClient(
// 2) There is a malformed Sec-WebSocketExtensions header.
// We should return a deflate-disabled encoder for the former case and
// fail the connection for the latter case.
- return new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr);
+ return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr));
}
if (parser.extensions().size() != 1) {
// Only permessage-deflate extension is supported.
// TODO (yhirano): Fail the connection.
- return new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr);
+ return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr));
}
const auto& extension = parser.extensions()[0];
WebSocketDeflateParameters params;
@@ -259,7 +260,7 @@ WebSocketEncoder* WebSocketEncoder::CreateClient(
if (!params.Initialize(extension, &failure_message) ||
!params.IsValidAsResponse(&failure_message)) {
// TODO (yhirano): Fail the connection.
- return new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr);
+ return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr));
}
auto deflater = make_scoped_ptr(
@@ -269,16 +270,19 @@ WebSocketEncoder* WebSocketEncoder::CreateClient(
if (!deflater->Initialize(params.PermissiveClientMaxWindowBits()) ||
!inflater->Initialize(params.PermissiveServerMaxWindowBits())) {
// TODO (yhirano): Fail the connection.
- return new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr);
+ return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr));
}
- return new WebSocketEncoder(FOR_CLIENT, deflater.Pass(), inflater.Pass());
+ return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, std::move(deflater),
+ std::move(inflater)));
}
WebSocketEncoder::WebSocketEncoder(Type type,
scoped_ptr<WebSocketDeflater> deflater,
scoped_ptr<WebSocketInflater> inflater)
- : type_(type), deflater_(deflater.Pass()), inflater_(inflater.Pass()) {}
+ : type_(type),
+ deflater_(std::move(deflater)),
+ inflater_(std::move(inflater)) {}
WebSocketEncoder::~WebSocketEncoder() {}
diff --git a/chromium/net/server/web_socket_encoder.h b/chromium/net/server/web_socket_encoder.h
index 1eb749f7c81..1e9206fd3c5 100644
--- a/chromium/net/server/web_socket_encoder.h
+++ b/chromium/net/server/web_socket_encoder.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/server/web_socket.h"
@@ -32,8 +32,8 @@ class WebSocketEncoder final {
static scoped_ptr<WebSocketEncoder> CreateServer(
const std::string& extensions,
WebSocketDeflateParameters* params);
- // TODO(yhirano): Return a scoped_ptr instead of a raw pointer.
- static WebSocketEncoder* CreateClient(const std::string& response_extensions);
+ static scoped_ptr<WebSocketEncoder> CreateClient(
+ const std::string& response_extensions);
WebSocket::ParseResult DecodeFrame(const base::StringPiece& frame,
int* bytes_consumed,
diff --git a/chromium/net/server/web_socket_encoder_unittest.cc b/chromium/net/server/web_socket_encoder_unittest.cc
index 9991bd7606d..27babda7fac 100644
--- a/chromium/net/server/web_socket_encoder_unittest.cc
+++ b/chromium/net/server/web_socket_encoder_unittest.cc
@@ -83,7 +83,7 @@ class WebSocketEncoderTest : public testing::Test {
std::string response_extensions;
server_ = WebSocketEncoder::CreateServer();
EXPECT_EQ(std::string(), response_extensions);
- client_.reset(WebSocketEncoder::CreateClient(""));
+ client_ = WebSocketEncoder::CreateClient("");
}
protected:
@@ -103,14 +103,13 @@ class WebSocketEncoderCompressionTest : public WebSocketEncoderTest {
EXPECT_TRUE(server_->deflate_enabled());
EXPECT_EQ("permessage-deflate; client_max_window_bits=15",
params.AsExtension().ToString());
- client_.reset(
- WebSocketEncoder::CreateClient(params.AsExtension().ToString()));
+ client_ = WebSocketEncoder::CreateClient(params.AsExtension().ToString());
}
};
TEST_F(WebSocketEncoderTest, DeflateDisabledEncoder) {
- scoped_ptr<WebSocketEncoder> server(WebSocketEncoder::CreateServer());
- scoped_ptr<WebSocketEncoder> client(WebSocketEncoder::CreateClient(""));
+ scoped_ptr<WebSocketEncoder> server = WebSocketEncoder::CreateServer();
+ scoped_ptr<WebSocketEncoder> client = WebSocketEncoder::CreateClient("");
ASSERT_TRUE(server);
ASSERT_TRUE(client);
@@ -215,7 +214,7 @@ TEST_F(WebSocketEncoderCompressionTest, LongFrame) {
std::string frame;
frame.reserve(length);
for (int i = 0; i < length; ++i) {
- int64 j = i;
+ int64_t j = i;
frame += temp.data()[(j * j) % length];
}
diff --git a/chromium/net/socket/client_socket_factory.cc b/chromium/net/socket/client_socket_factory.cc
index e0bc81d5e34..311f926b59f 100644
--- a/chromium/net/socket/client_socket_factory.cc
+++ b/chromium/net/socket/client_socket_factory.cc
@@ -4,6 +4,8 @@
#include "net/socket/client_socket_factory.h"
+#include <utility>
+
#include "base/lazy_instance.h"
#include "build/build_config.h"
#include "net/cert/cert_database.h"
@@ -70,12 +72,11 @@ class DefaultClientSocketFactory : public ClientSocketFactory,
const SSLConfig& ssl_config,
const SSLClientSocketContext& context) override {
#if defined(USE_OPENSSL)
- return scoped_ptr<SSLClientSocket>(
- new SSLClientSocketOpenSSL(transport_socket.Pass(), host_and_port,
- ssl_config, context));
+ return scoped_ptr<SSLClientSocket>(new SSLClientSocketOpenSSL(
+ std::move(transport_socket), host_and_port, ssl_config, context));
#else
return scoped_ptr<SSLClientSocket>(new SSLClientSocketNSS(
- transport_socket.Pass(), host_and_port, ssl_config, context));
+ std::move(transport_socket), host_and_port, ssl_config, context));
#endif
}
diff --git a/chromium/net/socket/client_socket_factory.h b/chromium/net/socket/client_socket_factory.h
index a1ad503480d..668f39e3032 100644
--- a/chromium/net/socket/client_socket_factory.h
+++ b/chromium/net/socket/client_socket_factory.h
@@ -7,7 +7,6 @@
#include <string>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/base/rand_callback.h"
diff --git a/chromium/net/socket/client_socket_handle.cc b/chromium/net/socket/client_socket_handle.cc
index f38187b3f86..b177fb6f3b2 100644
--- a/chromium/net/socket/client_socket_handle.cc
+++ b/chromium/net/socket/client_socket_handle.cc
@@ -4,6 +4,8 @@
#include "net/socket/client_socket_handle.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
@@ -43,7 +45,7 @@ void ClientSocketHandle::ResetInternal(bool cancel) {
socket_->NetLog().EndEvent(NetLog::TYPE_SOCKET_IN_USE);
// Release the socket back to the ClientSocketPool so it can be
// deleted or reused.
- pool_->ReleaseSocket(group_name_, socket_.Pass(), pool_id_);
+ pool_->ReleaseSocket(group_name_, std::move(socket_), pool_id_);
} else {
// If the handle has been initialized, we should still have a
// socket.
@@ -134,7 +136,7 @@ bool ClientSocketHandle::GetLoadTimingInfo(
}
void ClientSocketHandle::SetSocket(scoped_ptr<StreamSocket> s) {
- socket_ = s.Pass();
+ socket_ = std::move(s);
}
void ClientSocketHandle::OnIOComplete(int result) {
@@ -145,7 +147,7 @@ void ClientSocketHandle::OnIOComplete(int result) {
}
scoped_ptr<StreamSocket> ClientSocketHandle::PassSocket() {
- return socket_.Pass();
+ return std::move(socket_);
}
void ClientSocketHandle::HandleInitCompletion(int result) {
diff --git a/chromium/net/socket/client_socket_handle.h b/chromium/net/socket/client_socket_handle.h
index a4f7befbcac..c5b2720f7d3 100644
--- a/chromium/net/socket/client_socket_handle.h
+++ b/chromium/net/socket/client_socket_handle.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
diff --git a/chromium/net/socket/client_socket_pool.cc b/chromium/net/socket/client_socket_pool.cc
index 261e87fc7fe..5d12324b884 100644
--- a/chromium/net/socket/client_socket_pool.cc
+++ b/chromium/net/socket/client_socket_pool.cc
@@ -12,10 +12,10 @@ namespace {
// alive.
// TODO(ziadh): Change this timeout after getting histogram data on how long it
// should be.
-int64 g_unused_idle_socket_timeout_s = 10;
+int64_t g_unused_idle_socket_timeout_s = 10;
// The maximum duration, in seconds, to keep used idle persistent sockets alive.
-int64 g_used_idle_socket_timeout_s = 300; // 5 minutes
+int64_t g_used_idle_socket_timeout_s = 300; // 5 minutes
} // namespace
diff --git a/chromium/net/socket/client_socket_pool.h b/chromium/net/socket/client_socket_pool.h
index f43792dcb16..e1785a3a7c7 100644
--- a/chromium/net/socket/client_socket_pool.h
+++ b/chromium/net/socket/client_socket_pool.h
@@ -8,7 +8,7 @@
#include <deque>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/template_util.h"
diff --git a/chromium/net/socket/client_socket_pool_base.cc b/chromium/net/socket/client_socket_pool_base.cc
index 29de892a98d..4a76913b7a4 100644
--- a/chromium/net/socket/client_socket_pool_base.cc
+++ b/chromium/net/socket/client_socket_pool_base.cc
@@ -5,6 +5,7 @@
#include "net/socket/client_socket_pool_base.h"
#include <algorithm>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/format_macros.h"
@@ -71,7 +72,7 @@ ConnectJob::~ConnectJob() {
}
scoped_ptr<StreamSocket> ConnectJob::PassSocket() {
- return socket_.Pass();
+ return std::move(socket_);
}
int ConnectJob::Connect() {
@@ -97,7 +98,7 @@ void ConnectJob::SetSocket(scoped_ptr<StreamSocket> socket) {
net_log().AddEvent(NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
socket->NetLog().source().ToEventParametersCallback());
}
- socket_ = socket.Pass();
+ socket_ = std::move(socket);
}
void ConnectJob::NotifyDelegateOfCompletion(int rv) {
@@ -288,7 +289,7 @@ int ClientSocketPoolBaseHelper::RequestSocket(
CHECK(!request->handle()->is_initialized());
request.reset();
} else {
- group->InsertPendingRequest(request.Pass());
+ group->InsertPendingRequest(std::move(request));
// Have to do this asynchronously, as closing sockets in higher level pools
// call back in to |this|, which will cause all sorts of fun and exciting
// re-entrancy issues if the socket pool is doing something else at the
@@ -319,9 +320,8 @@ void ClientSocketPoolBaseHelper::RequestSockets(
num_sockets = max_sockets_per_group_;
}
- request.net_log().BeginEvent(
- NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS,
- NetLog::IntegerCallback("num_sockets", num_sockets));
+ request.net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS,
+ NetLog::IntCallback("num_sockets", num_sockets));
Group* group = GetOrCreateGroup(group_name);
@@ -431,7 +431,7 @@ int ClientSocketPoolBaseHelper::RequestSocketInternal(
connecting_socket_count_++;
- group->AddJob(connect_job.Pass(), preconnecting);
+ group->AddJob(std::move(connect_job), preconnecting);
} else {
LogBoundConnectJobToRequest(connect_job->net_log().source(), request);
scoped_ptr<StreamSocket> error_socket;
@@ -441,7 +441,7 @@ int ClientSocketPoolBaseHelper::RequestSocketInternal(
error_socket = connect_job->PassSocket();
}
if (error_socket) {
- HandOutSocket(error_socket.Pass(), ClientSocketHandle::UNUSED,
+ HandOutSocket(std::move(error_socket), ClientSocketHandle::UNUSED,
connect_job->connect_timing(), handle, base::TimeDelta(),
group, request.net_log());
} else if (group->IsEmpty()) {
@@ -534,7 +534,7 @@ void ClientSocketPoolBaseHelper::CancelRequest(
if (socket) {
if (result != OK)
socket->Disconnect();
- ReleaseSocket(handle->group_name(), socket.Pass(), handle->id());
+ ReleaseSocket(handle->group_name(), std::move(socket), handle->id());
}
return;
}
@@ -616,7 +616,7 @@ scoped_ptr<base::DictionaryValue> ClientSocketPoolBaseHelper::GetInfoAsValue(
dict->SetInteger("pool_generation_number", pool_generation_number_);
if (group_map_.empty())
- return dict.Pass();
+ return dict;
base::DictionaryValue* all_groups_dict = new base::DictionaryValue();
for (GroupMap::const_iterator it = group_map_.begin();
@@ -660,7 +660,7 @@ scoped_ptr<base::DictionaryValue> ClientSocketPoolBaseHelper::GetInfoAsValue(
all_groups_dict->SetWithoutPathExpansion(it->first, group_dict);
}
dict->Set("groups", all_groups_dict);
- return dict.Pass();
+ return dict;
}
bool ClientSocketPoolBaseHelper::IdleSocket::IsUsable() const {
@@ -796,7 +796,7 @@ void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name,
id == pool_generation_number_;
if (can_reuse) {
// Add it to the idle list.
- AddIdleSocket(socket.Pass(), group);
+ AddIdleSocket(std::move(socket), group);
OnAvailableSocketSlot(group_name, group);
} else {
socket.reset();
@@ -902,13 +902,13 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete(
scoped_ptr<const Request> request = group->PopNextPendingRequest();
if (request) {
LogBoundConnectJobToRequest(job_log.source(), *request);
- HandOutSocket(
- socket.Pass(), ClientSocketHandle::UNUSED, connect_timing,
- request->handle(), base::TimeDelta(), group, request->net_log());
+ HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED,
+ connect_timing, request->handle(), base::TimeDelta(), group,
+ request->net_log());
request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL);
InvokeUserCallbackLater(request->handle(), request->callback(), result);
} else {
- AddIdleSocket(socket.Pass(), group);
+ AddIdleSocket(std::move(socket), group);
OnAvailableSocketSlot(group_name, group);
CheckForStalledSocketGroups();
}
@@ -923,7 +923,7 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete(
RemoveConnectJob(job, group);
if (socket.get()) {
handed_out_socket = true;
- HandOutSocket(socket.Pass(), ClientSocketHandle::UNUSED,
+ HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED,
connect_timing, request->handle(), base::TimeDelta(),
group, request->net_log());
}
@@ -1004,7 +1004,7 @@ void ClientSocketPoolBaseHelper::HandOutSocket(
Group* group,
const BoundNetLog& net_log) {
DCHECK(socket);
- handle->SetSocket(socket.Pass());
+ handle->SetSocket(std::move(socket));
handle->set_reuse_type(reuse_type);
handle->set_idle_time(idle_time);
handle->set_pool_id(pool_generation_number_);
@@ -1013,8 +1013,8 @@ void ClientSocketPoolBaseHelper::HandOutSocket(
if (handle->is_reused()) {
net_log.AddEvent(
NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET,
- NetLog::IntegerCallback(
- "idle_ms", static_cast<int>(idle_time.InMilliseconds())));
+ NetLog::IntCallback("idle_ms",
+ static_cast<int>(idle_time.InMilliseconds())));
}
net_log.AddEvent(
@@ -1257,7 +1257,7 @@ void ClientSocketPoolBaseHelper::Group::OnBackupJobTimerFired(
int rv = backup_job->Connect();
pool->connecting_socket_count_++;
ConnectJob* raw_backup_job = backup_job.get();
- AddJob(backup_job.Pass(), false);
+ AddJob(std::move(backup_job), false);
if (rv != ERR_IO_PENDING)
pool->OnConnectJobComplete(rv, raw_backup_job);
}
@@ -1328,7 +1328,7 @@ ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest(
pointer = pending_requests_.GetNextTowardsLastMin(pointer)) {
if (pointer.value()->handle() == handle) {
scoped_ptr<const Request> request = RemovePendingRequest(pointer);
- return request.Pass();
+ return request;
}
}
return scoped_ptr<const ClientSocketPoolBaseHelper::Request>();
@@ -1345,7 +1345,7 @@ ClientSocketPoolBaseHelper::Group::RemovePendingRequest(
if (pending_requests_.empty())
backup_job_timer_.Stop();
request->CrashIfInvalid();
- return request.Pass();
+ return request;
}
} // namespace internal
diff --git a/chromium/net/socket/client_socket_pool_base.h b/chromium/net/socket/client_socket_pool_base.h
index 2f21981969d..cd13ce0dbdd 100644
--- a/chromium/net/socket/client_socket_pool_base.h
+++ b/chromium/net/socket/client_socket_pool_base.h
@@ -22,15 +22,18 @@
#ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
#define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
+#include <stddef.h>
+#include <stdint.h>
#include <cstddef>
#include <deque>
#include <list>
#include <map>
#include <set>
#include <string>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -157,7 +160,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
: public ConnectJob::Delegate,
public NetworkChangeNotifier::IPAddressObserver {
public:
- typedef uint32 Flags;
+ typedef uint32_t Flags;
// Used to specify specific behavior for the ClientSocketPool.
enum Flag {
@@ -754,7 +757,7 @@ class ClientSocketPoolBase {
internal::ClientSocketPoolBaseHelper::NORMAL,
params->ignore_limits(),
params, net_log));
- return helper_.RequestSocket(group_name, request.Pass());
+ return helper_.RequestSocket(group_name, std::move(request));
}
// RequestSockets bundles up the parameters into a Request and then forwards
@@ -778,7 +781,7 @@ class ClientSocketPoolBase {
void ReleaseSocket(const std::string& group_name,
scoped_ptr<StreamSocket> socket,
int id) {
- return helper_.ReleaseSocket(group_name, socket.Pass(), id);
+ return helper_.ReleaseSocket(group_name, std::move(socket), id);
}
void FlushWithError(int error) { helper_.FlushWithError(error); }
diff --git a/chromium/net/socket/client_socket_pool_base_unittest.cc b/chromium/net/socket/client_socket_pool_base_unittest.cc
index 2ac188159a7..a467f49e601 100644
--- a/chromium/net/socket/client_socket_pool_base_unittest.cc
+++ b/chromium/net/socket/client_socket_pool_base_unittest.cc
@@ -4,6 +4,8 @@
#include "net/socket/client_socket_pool_base.h"
+#include <stdint.h>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -11,6 +13,7 @@
#include "base/callback.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
@@ -149,8 +152,8 @@ class MockClientSocket : public StreamSocket {
was_used_to_convey_data_ = true;
return len;
}
- int SetReceiveBufferSize(int32 size) override { return OK; }
- int SetSendBufferSize(int32 size) override { return OK; }
+ int SetReceiveBufferSize(int32_t size) override { return OK; }
+ int SetSendBufferSize(int32_t size) override { return OK; }
// StreamSocket implementation.
int Connect(const CompletionCallback& callback) override {
@@ -186,6 +189,10 @@ class MockClientSocket : public StreamSocket {
}
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
private:
bool connected_;
@@ -525,7 +532,7 @@ class TestClientSocketPool : public ClientSocketPool {
void ReleaseSocket(const std::string& group_name,
scoped_ptr<StreamSocket> socket,
int id) override {
- base_.ReleaseSocket(group_name, socket.Pass(), id);
+ base_.ReleaseSocket(group_name, std::move(socket), id);
}
void FlushWithError(int error) override { base_.FlushWithError(error); }
@@ -634,7 +641,7 @@ class TestConnectJobDelegate : public ConnectJob::Delegate {
EXPECT_EQ(socket == NULL, result != OK);
have_result_ = true;
if (waiting_for_result_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
int WaitForResult() {
@@ -720,7 +727,9 @@ class ClientSocketPoolBaseTest : public testing::Test {
TestSocketRequest* request(int i) { return test_base_.request(i); }
size_t requests_size() const { return test_base_.requests_size(); }
- ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
+ std::vector<scoped_ptr<TestSocketRequest>>* requests() {
+ return test_base_.requests();
+ }
size_t completion_count() const { return test_base_.completion_count(); }
TestNetLog net_log_;
@@ -2205,8 +2214,14 @@ TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
}
+#if defined(OS_IOS)
+// TODO(droger): Enable this test (crbug.com/512595).
+#define MAYBE_DisableCleanupTimerNoReuse DISABLED_DisableCleanupTimerNoReuse
+#else
+#define MAYBE_DisableCleanupTimerNoReuse DisableCleanupTimerNoReuse
+#endif
// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
-TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
+TEST_F(ClientSocketPoolBaseTest, MAYBE_DisableCleanupTimerNoReuse) {
// Disable cleanup timer.
internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
@@ -3651,7 +3666,7 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
// *would* complete if it were created.
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromSeconds(1));
base::MessageLoop::current()->Run();
EXPECT_FALSE(pool_->HasGroup("a"));
diff --git a/chromium/net/socket/client_socket_pool_manager.cc b/chromium/net/socket/client_socket_pool_manager.cc
index 3066171fc4a..c053b1f4c04 100644
--- a/chromium/net/socket/client_socket_pool_manager.cc
+++ b/chromium/net/socket/client_socket_pool_manager.cc
@@ -6,7 +6,6 @@
#include <string>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "net/base/load_flags.h"
@@ -39,14 +38,12 @@ static_assert(arraysize(g_max_sockets_per_pool) ==
// as home routers blocking the connections!?!? See http://crbug.com/12066.
//
// WebSocket connections are long-lived, and should be treated differently
-// than normal other connections. 6 connections per group sounded too small
-// for such use, thus we use a larger limit which was determined somewhat
-// arbitrarily.
-// TODO(yutak): Look at the usage and determine the right value after
-// WebSocket protocol stack starts to work.
+// than normal other connections. Use a limit of 255, so the limit for wss will
+// 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
- 30 // WEBSOCKET_SOCKET_POOL
+ 255 // WEBSOCKET_SOCKET_POOL
};
static_assert(arraysize(g_max_sockets_per_group) ==
@@ -146,7 +143,7 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
}
// Place sockets with and without deprecated ciphers into separate
// connection groups.
- if (ssl_config_for_origin.enable_deprecated_cipher_suites)
+ if (ssl_config_for_origin.deprecated_cipher_suites_enabled)
prefix += "deprecatedciphers/";
connection_group = prefix + connection_group;
}
diff --git a/chromium/net/socket/client_socket_pool_manager_impl.cc b/chromium/net/socket/client_socket_pool_manager_impl.cc
index 9dbb19e9c62..f2d512c2a91 100644
--- a/chromium/net/socket/client_socket_pool_manager_impl.cc
+++ b/chromium/net/socket/client_socket_pool_manager_impl.cc
@@ -4,6 +4,9 @@
#include "net/socket/client_socket_pool_manager_impl.h"
+#include <algorithm>
+#include <utility>
+
#include "base/logging.h"
#include "base/values.h"
#include "net/http/http_network_session.h"
@@ -42,7 +45,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
ChannelIDService* channel_id_service,
TransportSecurityState* transport_security_state,
CTVerifier* cert_transparency_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
const std::string& ssl_session_cache_shard,
SSLConfigService* ssl_config_service,
HttpNetworkSession::SocketPoolType pool_type)
@@ -53,7 +56,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
channel_id_service_(channel_id_service),
transport_security_state_(transport_security_state),
cert_transparency_verifier_(cert_transparency_verifier),
- cert_policy_enforcer_(cert_policy_enforcer),
+ ct_policy_enforcer_(ct_policy_enforcer),
ssl_session_cache_shard_(ssl_session_cache_shard),
ssl_config_service_(ssl_config_service),
pool_type_(pool_type),
@@ -76,7 +79,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
channel_id_service,
transport_security_state,
cert_transparency_verifier,
- cert_policy_enforcer,
+ ct_policy_enforcer,
ssl_session_cache_shard,
socket_factory,
transport_socket_pool_.get(),
@@ -208,14 +211,17 @@ SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
}
DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
+ int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
+ int sockets_per_group = std::min(sockets_per_proxy_server,
+ max_sockets_per_group(pool_type_));
std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
transport_socket_pools_for_socks_proxies_.insert(
std::make_pair(
socks_proxy,
new TransportClientSocketPool(
- max_sockets_per_proxy_server(pool_type_),
- max_sockets_per_group(pool_type_),
+ sockets_per_proxy_server,
+ sockets_per_group,
host_resolver_,
socket_factory_,
net_log_)));
@@ -224,8 +230,8 @@ SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
socks_socket_pools_.insert(
std::make_pair(socks_proxy, new SOCKSClientSocketPool(
- max_sockets_per_proxy_server(pool_type_),
- max_sockets_per_group(pool_type_),
+ sockets_per_proxy_server,
+ sockets_per_group,
host_resolver_,
tcp_ret.first->second,
net_log_)));
@@ -249,13 +255,17 @@ ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
+ int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
+ int sockets_per_group = std::min(sockets_per_proxy_server,
+ max_sockets_per_group(pool_type_));
+
std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
transport_socket_pools_for_http_proxies_.insert(
std::make_pair(
http_proxy,
new TransportClientSocketPool(
- max_sockets_per_proxy_server(pool_type_),
- max_sockets_per_group(pool_type_),
+ sockets_per_proxy_server,
+ sockets_per_group,
host_resolver_,
socket_factory_,
net_log_)));
@@ -266,8 +276,8 @@ ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
std::make_pair(
http_proxy,
new TransportClientSocketPool(
- max_sockets_per_proxy_server(pool_type_),
- max_sockets_per_group(pool_type_),
+ sockets_per_proxy_server,
+ sockets_per_group,
host_resolver_,
socket_factory_,
net_log_)));
@@ -275,15 +285,15 @@ ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
- http_proxy, new SSLClientSocketPool(
- max_sockets_per_proxy_server(pool_type_),
- max_sockets_per_group(pool_type_), cert_verifier_,
- channel_id_service_, transport_security_state_,
- cert_transparency_verifier_, cert_policy_enforcer_,
- ssl_session_cache_shard_, socket_factory_,
- tcp_https_ret.first->second /* https proxy */,
- NULL /* no socks proxy */, NULL /* no http proxy */,
- ssl_config_service_.get(), net_log_)));
+ http_proxy,
+ new SSLClientSocketPool(
+ sockets_per_proxy_server, sockets_per_group, cert_verifier_,
+ channel_id_service_, transport_security_state_,
+ cert_transparency_verifier_, ct_policy_enforcer_,
+ ssl_session_cache_shard_, socket_factory_,
+ tcp_https_ret.first->second /* https proxy */,
+ NULL /* no socks proxy */, NULL /* no http proxy */,
+ ssl_config_service_.get(), net_log_)));
DCHECK(tcp_https_ret.second);
std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
@@ -291,8 +301,8 @@ ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
std::make_pair(
http_proxy,
new HttpProxyClientSocketPool(
- max_sockets_per_proxy_server(pool_type_),
- max_sockets_per_group(pool_type_),
+ sockets_per_proxy_server,
+ sockets_per_group,
tcp_http_ret.first->second,
ssl_https_ret.first->second,
net_log_)));
@@ -307,11 +317,15 @@ SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
if (it != ssl_socket_pools_for_proxies_.end())
return it->second;
+ int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
+ int sockets_per_group = std::min(sockets_per_proxy_server,
+ max_sockets_per_group(pool_type_));
+
SSLClientSocketPool* new_pool = new SSLClientSocketPool(
- max_sockets_per_proxy_server(pool_type_),
- max_sockets_per_group(pool_type_), cert_verifier_, channel_id_service_,
- transport_security_state_, cert_transparency_verifier_,
- cert_policy_enforcer_, ssl_session_cache_shard_, socket_factory_,
+ sockets_per_proxy_server, sockets_per_group, cert_verifier_,
+ channel_id_service_, transport_security_state_,
+ cert_transparency_verifier_, ct_policy_enforcer_,
+ ssl_session_cache_shard_, socket_factory_,
NULL, /* no tcp pool, we always go through a proxy */
GetSocketPoolForSOCKSProxy(proxy_server),
GetSocketPoolForHTTPProxy(proxy_server), ssl_config_service_.get(),
@@ -345,7 +359,7 @@ scoped_ptr<base::Value> ClientSocketPoolManagerImpl::SocketPoolInfoToValue()
// socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
AddSocketPoolsToList(list.get(), ssl_socket_pools_for_proxies_,
"ssl_socket_pool_for_proxies", false);
- return list.Pass();
+ return std::move(list);
}
void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
diff --git a/chromium/net/socket/client_socket_pool_manager_impl.h b/chromium/net/socket/client_socket_pool_manager_impl.h
index 2038220a3e2..538e507fe6e 100644
--- a/chromium/net/socket/client_socket_pool_manager_impl.h
+++ b/chromium/net/socket/client_socket_pool_manager_impl.h
@@ -6,8 +6,8 @@
#define NET_SOCKET_CLIENT_SOCKET_POOL_MANAGER_IMPL_H_
#include <map>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
@@ -60,7 +60,7 @@ class ClientSocketPoolManagerImpl : public base::NonThreadSafe,
ChannelIDService* channel_id_service,
TransportSecurityState* transport_security_state,
CTVerifier* cert_transparency_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
const std::string& ssl_session_cache_shard,
SSLConfigService* ssl_config_service,
HttpNetworkSession::SocketPoolType pool_type);
@@ -106,7 +106,7 @@ class ClientSocketPoolManagerImpl : public base::NonThreadSafe,
ChannelIDService* const channel_id_service_;
TransportSecurityState* const transport_security_state_;
CTVerifier* const cert_transparency_verifier_;
- CertPolicyEnforcer* const cert_policy_enforcer_;
+ CTPolicyEnforcer* const ct_policy_enforcer_;
const std::string ssl_session_cache_shard_;
const scoped_refptr<SSLConfigService> ssl_config_service_;
const HttpNetworkSession::SocketPoolType pool_type_;
diff --git a/chromium/net/socket/deterministic_socket_data_unittest.cc b/chromium/net/socket/deterministic_socket_data_unittest.cc
deleted file mode 100644
index 9a95e1e17b0..00000000000
--- a/chromium/net/socket/deterministic_socket_data_unittest.cc
+++ /dev/null
@@ -1,621 +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/socket/socket_test_util.h"
-
-#include <string.h>
-
-#include "base/memory/ref_counted.h"
-#include "testing/platform_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-static const char kMsg1[] = "\0hello!\xff";
-static const int kLen1 = arraysize(kMsg1);
-static const char kMsg2[] = "\0a2345678\0";
-static const int kLen2 = arraysize(kMsg2);
-static const char kMsg3[] = "bye!";
-static const int kLen3 = arraysize(kMsg3);
-
-} // anonymous namespace
-
-namespace net {
-
-class DeterministicSocketDataTest : public PlatformTest {
- public:
- DeterministicSocketDataTest();
-
- void TearDown() override;
-
- void ReentrantReadCallback(int len, int rv);
- void ReentrantWriteCallback(const char* data, int len, int rv);
-
- protected:
- void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
- size_t writes_count);
-
- void AssertSyncReadEquals(const char* data, int len);
- void AssertAsyncReadEquals(const char* data, int len);
- void AssertReadReturns(const char* data, int len, int rv);
- void AssertReadBufferEquals(const char* data, int len);
-
- void AssertSyncWriteEquals(const char* data, int len);
- void AssertAsyncWriteEquals(const char* data, int len);
- void AssertWriteReturns(const char* data, int len, int rv);
-
- TestCompletionCallback read_callback_;
- TestCompletionCallback write_callback_;
- StreamSocket* sock_;
- scoped_ptr<DeterministicSocketData> data_;
-
- private:
- scoped_refptr<IOBuffer> read_buf_;
- MockConnect connect_data_;
-
- HostPortPair endpoint_;
- scoped_refptr<TransportSocketParams> tcp_params_;
- DeterministicMockClientSocketFactory socket_factory_;
- MockTransportClientSocketPool socket_pool_;
- ClientSocketHandle connection_;
-
- DISALLOW_COPY_AND_ASSIGN(DeterministicSocketDataTest);
-};
-
-DeterministicSocketDataTest::DeterministicSocketDataTest()
- : sock_(NULL),
- read_buf_(NULL),
- connect_data_(SYNCHRONOUS, OK),
- endpoint_("www.google.com", 443),
- tcp_params_(new TransportSocketParams(
- endpoint_,
- false,
- false,
- OnHostResolutionCallback(),
- TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
- socket_pool_(10, 10, &socket_factory_) {
-}
-
-void DeterministicSocketDataTest::TearDown() {
- // Empty the current queue.
- base::MessageLoop::current()->RunUntilIdle();
- PlatformTest::TearDown();
-}
-
-void DeterministicSocketDataTest::Initialize(MockRead* reads,
- size_t reads_count,
- MockWrite* writes,
- size_t writes_count) {
- data_.reset(new DeterministicSocketData(reads, reads_count,
- writes, writes_count));
- data_->set_connect_data(connect_data_);
- socket_factory_.AddSocketDataProvider(data_.get());
-
- // Perform the TCP connect
- EXPECT_EQ(OK,
- connection_.Init(endpoint_.ToString(),
- tcp_params_,
- LOWEST,
- CompletionCallback(),
- reinterpret_cast<TransportClientSocketPool*>(&socket_pool_),
- BoundNetLog()));
- sock_ = connection_.socket();
-}
-
-void DeterministicSocketDataTest::AssertSyncReadEquals(const char* data,
- int len) {
- // Issue the read, which will complete immediately
- AssertReadReturns(data, len, len);
- AssertReadBufferEquals(data, len);
-}
-
-void DeterministicSocketDataTest::AssertAsyncReadEquals(const char* data,
- int len) {
- // Issue the read, which will be completed asynchronously
- AssertReadReturns(data, len, ERR_IO_PENDING);
-
- EXPECT_FALSE(read_callback_.have_result());
- EXPECT_TRUE(sock_->IsConnected());
- data_->RunFor(1); // Runs 1 step, to cause the callbacks to be invoked
-
- // Now the read should complete
- ASSERT_EQ(len, read_callback_.WaitForResult());
- AssertReadBufferEquals(data, len);
-}
-
-void DeterministicSocketDataTest::AssertReadReturns(const char* data,
- int len, int rv) {
- read_buf_ = new IOBuffer(len);
- ASSERT_EQ(rv, sock_->Read(read_buf_.get(), len, read_callback_.callback()));
-}
-
-void DeterministicSocketDataTest::AssertReadBufferEquals(const char* data,
- int len) {
- ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
-}
-
-void DeterministicSocketDataTest::AssertSyncWriteEquals(const char* data,
- int len) {
- scoped_refptr<IOBuffer> buf(new IOBuffer(len));
- memcpy(buf->data(), data, len);
-
- // Issue the write, which will complete immediately
- ASSERT_EQ(len, sock_->Write(buf.get(), len, write_callback_.callback()));
-}
-
-void DeterministicSocketDataTest::AssertAsyncWriteEquals(const char* data,
- int len) {
- // Issue the read, which will be completed asynchronously
- AssertWriteReturns(data, len, ERR_IO_PENDING);
-
- EXPECT_FALSE(read_callback_.have_result());
- EXPECT_TRUE(sock_->IsConnected());
- data_->RunFor(1); // Runs 1 step, to cause the callbacks to be invoked
-
- ASSERT_EQ(len, write_callback_.WaitForResult());
-}
-
-void DeterministicSocketDataTest::AssertWriteReturns(const char* data,
- int len, int rv) {
- scoped_refptr<IOBuffer> buf(new IOBuffer(len));
- memcpy(buf->data(), data, len);
-
- // Issue the read, which will complete asynchronously
- ASSERT_EQ(rv, sock_->Write(buf.get(), len, write_callback_.callback()));
-}
-
-void DeterministicSocketDataTest::ReentrantReadCallback(int len, int rv) {
- scoped_refptr<IOBuffer> read_buf(new IOBuffer(len));
- EXPECT_EQ(len,
- sock_->Read(
- read_buf.get(),
- len,
- base::Bind(&DeterministicSocketDataTest::ReentrantReadCallback,
- base::Unretained(this),
- len)));
-}
-
-void DeterministicSocketDataTest::ReentrantWriteCallback(
- const char* data, int len, int rv) {
- scoped_refptr<IOBuffer> write_buf(new IOBuffer(len));
- memcpy(write_buf->data(), data, len);
- EXPECT_EQ(len,
- sock_->Write(
- write_buf.get(),
- len,
- base::Bind(&DeterministicSocketDataTest::ReentrantWriteCallback,
- base::Unretained(this),
- data,
- len)));
-}
-
-// ----------- Read
-
-TEST_F(DeterministicSocketDataTest, SingleSyncReadWhileStopped) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Read
- MockRead(SYNCHRONOUS, 0, 1), // EOF
- };
-
- Initialize(reads, arraysize(reads), NULL, 0);
-
- data_->SetStopped(true);
- AssertReadReturns(kMsg1, kLen1, ERR_UNEXPECTED);
-}
-
-TEST_F(DeterministicSocketDataTest, SingleSyncReadTooEarly) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 1), // Sync Read
- MockRead(SYNCHRONOUS, 0, 2), // EOF
- };
-
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, 0, 0)
- };
-
- Initialize(reads, arraysize(reads), writes, arraysize(writes));
-
- data_->StopAfter(2);
- ASSERT_FALSE(data_->stopped());
- AssertReadReturns(kMsg1, kLen1, ERR_UNEXPECTED);
-}
-
-TEST_F(DeterministicSocketDataTest, SingleSyncRead) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Read
- MockRead(SYNCHRONOUS, 0, 1), // EOF
- };
-
- Initialize(reads, arraysize(reads), NULL, 0);
- // Make sure we don't stop before we've read all the data
- data_->StopAfter(1);
- AssertSyncReadEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, MultipleSyncReads) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Read
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 1), // Sync Read
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 2), // Sync Read
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 3), // Sync Read
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 4), // Sync Read
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 5), // Sync Read
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 6), // Sync Read
- MockRead(SYNCHRONOUS, 0, 7), // EOF
- };
-
- Initialize(reads, arraysize(reads), NULL, 0);
-
- // Make sure we don't stop before we've read all the data
- data_->StopAfter(10);
- AssertSyncReadEquals(kMsg1, kLen1);
- AssertSyncReadEquals(kMsg2, kLen2);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg2, kLen2);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, SingleAsyncRead) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), // Async Read
- MockRead(SYNCHRONOUS, 0, 1), // EOF
- };
-
- Initialize(reads, arraysize(reads), NULL, 0);
-
- AssertAsyncReadEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, MultipleAsyncReads) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), // Async Read
- MockRead(ASYNC, kMsg2, kLen2, 1), // Async Read
- MockRead(ASYNC, kMsg3, kLen3, 2), // Async Read
- MockRead(ASYNC, kMsg3, kLen3, 3), // Async Read
- MockRead(ASYNC, kMsg2, kLen2, 4), // Async Read
- MockRead(ASYNC, kMsg3, kLen3, 5), // Async Read
- MockRead(ASYNC, kMsg1, kLen1, 6), // Async Read
- MockRead(SYNCHRONOUS, 0, 7), // EOF
- };
-
- Initialize(reads, arraysize(reads), NULL, 0);
-
- AssertAsyncReadEquals(kMsg1, kLen1);
- AssertAsyncReadEquals(kMsg2, kLen2);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg2, kLen2);
- AssertAsyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, MixedReads) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Read
- MockRead(ASYNC, kMsg2, kLen2, 1), // Async Read
- MockRead(SYNCHRONOUS, kMsg3, kLen3, 2), // Sync Read
- MockRead(ASYNC, kMsg3, kLen3, 3), // Async Read
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 4), // Sync Read
- MockRead(ASYNC, kMsg3, kLen3, 5), // Async Read
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 6), // Sync Read
- MockRead(SYNCHRONOUS, 0, 7), // EOF
- };
-
- Initialize(reads, arraysize(reads), NULL, 0);
-
- data_->StopAfter(1);
- AssertSyncReadEquals(kMsg1, kLen1);
- AssertAsyncReadEquals(kMsg2, kLen2);
- data_->StopAfter(1);
- AssertSyncReadEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg3, kLen3);
- data_->StopAfter(1);
- AssertSyncReadEquals(kMsg2, kLen2);
- AssertAsyncReadEquals(kMsg3, kLen3);
- data_->StopAfter(1);
- AssertSyncReadEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, SyncReadFromCompletionCallback) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), // Async Read
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 1), // Sync Read
- };
-
- Initialize(reads, arraysize(reads), NULL, 0);
-
- data_->StopAfter(2);
-
- scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Read(
- read_buf.get(),
- kLen1,
- base::Bind(&DeterministicSocketDataTest::ReentrantReadCallback,
- base::Unretained(this),
- kLen2)));
- data_->Run();
-}
-
-// ----------- Write
-
-TEST_F(DeterministicSocketDataTest, SingleSyncWriteWhileStopped) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Read
- };
-
- Initialize(NULL, 0, writes, arraysize(writes));
-
- data_->SetStopped(true);
- AssertWriteReturns(kMsg1, kLen1, ERR_UNEXPECTED);
-}
-
-TEST_F(DeterministicSocketDataTest, SingleSyncWriteTooEarly) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 1), // Sync Write
- };
-
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, 0, 0)
- };
-
- Initialize(reads, arraysize(reads), writes, arraysize(writes));
-
- data_->StopAfter(2);
- ASSERT_FALSE(data_->stopped());
- AssertWriteReturns(kMsg1, kLen1, ERR_UNEXPECTED);
-}
-
-TEST_F(DeterministicSocketDataTest, SingleSyncWrite) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Write
- };
-
- Initialize(NULL, 0, writes, arraysize(writes));
-
- // Make sure we don't stop before we've read all the data
- data_->StopAfter(1);
- AssertSyncWriteEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, MultipleSyncWrites) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Write
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1), // Sync Write
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2), // Sync Write
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 3), // Sync Write
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 4), // Sync Write
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 5), // Sync Write
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 6), // Sync Write
- };
-
- Initialize(NULL, 0, writes, arraysize(writes));
-
- // Make sure we don't stop before we've read all the data
- data_->StopAfter(10);
- AssertSyncWriteEquals(kMsg1, kLen1);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncWriteEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, SingleAsyncWrite) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0), // Async Write
- };
-
- Initialize(NULL, 0, writes, arraysize(writes));
-
- AssertAsyncWriteEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, MultipleAsyncWrites) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0), // Async Write
- MockWrite(ASYNC, kMsg2, kLen2, 1), // Async Write
- MockWrite(ASYNC, kMsg3, kLen3, 2), // Async Write
- MockWrite(ASYNC, kMsg3, kLen3, 3), // Async Write
- MockWrite(ASYNC, kMsg2, kLen2, 4), // Async Write
- MockWrite(ASYNC, kMsg3, kLen3, 5), // Async Write
- MockWrite(ASYNC, kMsg1, kLen1, 6), // Async Write
- };
-
- Initialize(NULL, 0, writes, arraysize(writes));
-
- AssertAsyncWriteEquals(kMsg1, kLen1);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, MixedWrites) {
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Write
- MockWrite(ASYNC, kMsg2, kLen2, 1), // Async Write
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2), // Sync Write
- MockWrite(ASYNC, kMsg3, kLen3, 3), // Async Write
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 4), // Sync Write
- MockWrite(ASYNC, kMsg3, kLen3, 5), // Async Write
- MockWrite(SYNCHRONOUS, kMsg1, kLen1, 6), // Sync Write
- };
-
- Initialize(NULL, 0, writes, arraysize(writes));
-
- data_->StopAfter(1);
- AssertSyncWriteEquals(kMsg1, kLen1);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- data_->StopAfter(1);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- data_->StopAfter(1);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- data_->StopAfter(1);
- AssertSyncWriteEquals(kMsg1, kLen1);
-}
-
-TEST_F(DeterministicSocketDataTest, SyncWriteFromCompletionCallback) {
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg1, kLen1, 0), // Async Write
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1), // Sync Write
- };
-
- Initialize(NULL, 0, writes, arraysize(writes));
-
- data_->StopAfter(2);
-
- scoped_refptr<IOBuffer> write_buf(new IOBuffer(kLen1));
- memcpy(write_buf->data(), kMsg1, kLen1);
- ASSERT_EQ(ERR_IO_PENDING,
- sock_->Write(
- write_buf.get(),
- kLen1,
- base::Bind(&DeterministicSocketDataTest::ReentrantWriteCallback,
- base::Unretained(this),
- kMsg2,
- kLen2)));
- data_->Run();
-}
-
-// ----------- Mixed Reads and Writes
-
-TEST_F(DeterministicSocketDataTest, MixedSyncOperations) {
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Read
- MockRead(SYNCHRONOUS, kMsg2, kLen2, 3), // Sync Read
- MockRead(SYNCHRONOUS, 0, 4), // EOF
- };
-
- MockWrite writes[] = {
- MockWrite(SYNCHRONOUS, kMsg2, kLen2, 1), // Sync Write
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2), // Sync Write
- };
-
- Initialize(reads, arraysize(reads), writes, arraysize(writes));
-
- // Make sure we don't stop before we've read/written everything
- data_->StopAfter(10);
- AssertSyncReadEquals(kMsg1, kLen1);
- AssertSyncWriteEquals(kMsg2, kLen2);
- AssertSyncWriteEquals(kMsg3, kLen3);
- AssertSyncReadEquals(kMsg2, kLen2);
-}
-
-TEST_F(DeterministicSocketDataTest, MixedAsyncOperations) {
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), // Sync Read
- MockRead(ASYNC, kMsg2, kLen2, 3), // Sync Read
- MockRead(ASYNC, 0, 4), // EOF
- };
-
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1), // Sync Write
- MockWrite(ASYNC, kMsg3, kLen3, 2), // Sync Write
- };
-
- Initialize(reads, arraysize(reads), writes, arraysize(writes));
-
- AssertAsyncReadEquals(kMsg1, kLen1);
- AssertAsyncWriteEquals(kMsg2, kLen2);
- AssertAsyncWriteEquals(kMsg3, kLen3);
- AssertAsyncReadEquals(kMsg2, kLen2);
-}
-
-TEST_F(DeterministicSocketDataTest, InterleavedAsyncOperations) {
- // Order of completion is read, write, write, read
- MockRead reads[] = {
- MockRead(ASYNC, kMsg1, kLen1, 0), // Async Read
- MockRead(ASYNC, kMsg2, kLen2, 3), // Async Read
- MockRead(ASYNC, 0, 4), // EOF
- };
-
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1), // Async Write
- MockWrite(ASYNC, kMsg3, kLen3, 2), // Async Write
- };
-
- Initialize(reads, arraysize(reads), writes, arraysize(writes));
-
- // Issue the write, which will block until the read completes
- AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
-
- // Issue the read which will return first
- AssertReadReturns(kMsg1, kLen1, ERR_IO_PENDING);
-
- data_->RunFor(1);
- ASSERT_TRUE(read_callback_.have_result());
- ASSERT_EQ(kLen1, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg1, kLen1);
-
- data_->RunFor(1);
- ASSERT_TRUE(write_callback_.have_result());
- ASSERT_EQ(kLen2, write_callback_.WaitForResult());
-
- data_->StopAfter(1);
- // Issue the read, which will block until the write completes
- AssertReadReturns(kMsg2, kLen2, ERR_IO_PENDING);
-
- // Issue the writes which will return first
- AssertWriteReturns(kMsg3, kLen3, ERR_IO_PENDING);
-
- data_->RunFor(1);
- ASSERT_TRUE(write_callback_.have_result());
- ASSERT_EQ(kLen3, write_callback_.WaitForResult());
-
- data_->RunFor(1);
- ASSERT_TRUE(read_callback_.have_result());
- ASSERT_EQ(kLen2, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg2, kLen2);
-}
-
-TEST_F(DeterministicSocketDataTest, InterleavedMixedOperations) {
- // Order of completion is read, write, write, read
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, kMsg1, kLen1, 0), // Sync Read
- MockRead(ASYNC, kMsg2, kLen2, 3), // Async Read
- MockRead(SYNCHRONOUS, 0, 4), // EOF
- };
-
- MockWrite writes[] = {
- MockWrite(ASYNC, kMsg2, kLen2, 1), // Async Write
- MockWrite(SYNCHRONOUS, kMsg3, kLen3, 2), // Sync Write
- };
-
- Initialize(reads, arraysize(reads), writes, arraysize(writes));
-
- // Issue the write, which will block until the read completes
- AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
-
- // Issue the writes which will complete immediately
- data_->StopAfter(1);
- AssertSyncReadEquals(kMsg1, kLen1);
-
- data_->RunFor(1);
- ASSERT_TRUE(write_callback_.have_result());
- ASSERT_EQ(kLen2, write_callback_.WaitForResult());
-
- // Issue the read, which will block until the write completes
- AssertReadReturns(kMsg2, kLen2, ERR_IO_PENDING);
-
- // Issue the writes which will complete immediately
- data_->StopAfter(1);
- AssertSyncWriteEquals(kMsg3, kLen3);
-
- data_->RunFor(1);
- ASSERT_TRUE(read_callback_.have_result());
- ASSERT_EQ(kLen2, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg2, kLen2);
-}
-
-} // namespace net
diff --git a/chromium/net/socket/mock_client_socket_pool_manager.h b/chromium/net/socket/mock_client_socket_pool_manager.h
index 80327665cc6..e24b2fb3ae6 100644
--- a/chromium/net/socket/mock_client_socket_pool_manager.h
+++ b/chromium/net/socket/mock_client_socket_pool_manager.h
@@ -5,7 +5,7 @@
#ifndef NET_SOCKET_MOCK_CLIENT_SOCKET_POOL_MANAGER_H_
#define NET_SOCKET_MOCK_CLIENT_SOCKET_POOL_MANAGER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/client_socket_pool_manager_impl.h"
diff --git a/chromium/net/socket/next_proto.cc b/chromium/net/socket/next_proto.cc
index 0285044c21f..a22418c542e 100644
--- a/chromium/net/socket/next_proto.cc
+++ b/chromium/net/socket/next_proto.cc
@@ -8,30 +8,30 @@ namespace net {
NextProtoVector NextProtosDefaults() {
NextProtoVector next_protos;
- next_protos.push_back(kProtoHTTP11);
- next_protos.push_back(kProtoSPDY31);
next_protos.push_back(kProtoHTTP2);
+ next_protos.push_back(kProtoSPDY31);
+ next_protos.push_back(kProtoHTTP11);
return next_protos;
}
NextProtoVector NextProtosWithSpdyAndQuic(bool spdy_enabled,
bool quic_enabled) {
NextProtoVector next_protos;
- next_protos.push_back(kProtoHTTP11);
if (quic_enabled)
next_protos.push_back(kProtoQUIC1SPDY3);
if (spdy_enabled) {
- next_protos.push_back(kProtoSPDY31);
next_protos.push_back(kProtoHTTP2);
+ next_protos.push_back(kProtoSPDY31);
}
+ next_protos.push_back(kProtoHTTP11);
return next_protos;
}
NextProtoVector NextProtosSpdy31() {
NextProtoVector next_protos;
- next_protos.push_back(kProtoHTTP11);
next_protos.push_back(kProtoQUIC1SPDY3);
next_protos.push_back(kProtoSPDY31);
+ next_protos.push_back(kProtoHTTP11);
return next_protos;
}
diff --git a/chromium/net/socket/next_proto.h b/chromium/net/socket/next_proto.h
index 06f31ba749e..3938d4424ad 100644
--- a/chromium/net/socket/next_proto.h
+++ b/chromium/net/socket/next_proto.h
@@ -18,16 +18,14 @@ namespace net {
// are used to collect statistics on UMA. Also, values must be in [0,499),
// because of the way TLS protocol negotiation extension information is added to
// UMA histogram.
+const int kProtoSPDYHistogramOffset = 100;
enum NextProto {
kProtoUnknown = 0,
kProtoHTTP11 = 1,
kProtoMinimumVersion = kProtoHTTP11,
- kProtoDeprecatedSPDY2 = 100,
- kProtoSPDYMinimumVersion = kProtoDeprecatedSPDY2,
- kProtoSPDYHistogramOffset = kProtoDeprecatedSPDY2,
- kProtoSPDY3 = 101,
kProtoSPDY31 = 102,
+ kProtoSPDYMinimumVersion = kProtoSPDY31,
// kProtoHTTP2_14 = 103, // HTTP/2 draft-14
// kProtoHTTP2_15 = 104, // HTTP/2 draft-15
// kProtoHTTP2_16 = 105, // HTTP/2 draft-16
diff --git a/chromium/net/socket/nss_ssl_util.cc b/chromium/net/socket/nss_ssl_util.cc
index 554bd273c77..ee587571639 100644
--- a/chromium/net/socket/nss_ssl_util.cc
+++ b/chromium/net/socket/nss_ssl_util.cc
@@ -11,6 +11,7 @@
#include <sslproto.h>
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/cpu.h"
@@ -37,7 +38,7 @@ namespace {
// |to_remove| and sets every instance of them in |ciphers| to zero. It returns
// true if it found and removed every element of |to_remove|. It assumes that
// there are no duplicates in |ciphers| nor in |to_remove|.
-bool CiphersRemove(const uint16* to_remove, uint16* ciphers, size_t num) {
+bool CiphersRemove(const uint16_t* to_remove, uint16_t* ciphers, size_t num) {
size_t i, found = 0;
for (i = 0; ; i++) {
@@ -59,7 +60,7 @@ bool CiphersRemove(const uint16* to_remove, uint16* ciphers, size_t num) {
// CiphersCompact takes an array of cipher suite ids in |ciphers|, where some
// entries are zero, and moves the entries so that all the non-zero elements
// are compacted at the end of the array.
-void CiphersCompact(uint16* ciphers, size_t num) {
+void CiphersCompact(uint16_t* ciphers, size_t num) {
size_t j = num - 1;
for (size_t i = num - 1; i < num; i--) {
@@ -71,7 +72,7 @@ void CiphersCompact(uint16* ciphers, size_t num) {
// CiphersCopy copies the zero-terminated array |in| to |out|. It returns the
// number of cipher suite ids copied.
-size_t CiphersCopy(const uint16* in, uint16* out) {
+size_t CiphersCopy(const uint16_t* in, uint16_t* out) {
for (size_t i = 0; ; i++) {
if (in[i] == 0)
return i;
@@ -87,7 +88,7 @@ scoped_ptr<base::Value> NetLogSSLErrorCallback(
dict->SetInteger("net_error", net_error);
if (ssl_lib_error)
dict->SetInteger("ssl_lib_error", ssl_lib_error);
- return dict.Pass();
+ return std::move(dict);
}
class NSSSSLInitSingleton {
@@ -146,26 +147,24 @@ class NSSSSLInitSingleton {
// forward-secret ChaCha20-Poly1305. If the local machine has AES-NI then
// we prefer AES-GCM, otherwise ChaCha20. The remainder of the cipher suite
// preference is inheriented from NSS. */
- static const uint16 chacha_ciphers[] = {
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
- 0,
+ static const uint16_t chacha_ciphers[] = {
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 0,
};
- static const uint16 aes_gcm_ciphers[] = {
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
- 0,
+ static const uint16_t aes_gcm_ciphers[] = {
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0,
};
- scoped_ptr<uint16[]> ciphers(new uint16[num_ciphers]);
- memcpy(ciphers.get(), ssl_ciphers, sizeof(uint16)*num_ciphers);
+ scoped_ptr<uint16_t[]> ciphers(new uint16_t[num_ciphers]);
+ memcpy(ciphers.get(), ssl_ciphers, sizeof(uint16_t) * num_ciphers);
if (CiphersRemove(chacha_ciphers, ciphers.get(), num_ciphers) &&
CiphersRemove(aes_gcm_ciphers, ciphers.get(), num_ciphers)) {
CiphersCompact(ciphers.get(), num_ciphers);
- const uint16* preference_ciphers = chacha_ciphers;
- const uint16* other_ciphers = aes_gcm_ciphers;
+ const uint16_t* preference_ciphers = chacha_ciphers;
+ const uint16_t* other_ciphers = aes_gcm_ciphers;
base::CPU cpu;
if (cpu.has_aesni() && cpu.has_avx()) {
@@ -390,7 +389,7 @@ scoped_ptr<base::Value> NetLogSSLFailedNSSFunctionCallback(
if (param[0] != '\0')
dict->SetString("param", param);
dict->SetInteger("ssl_lib_error", ssl_lib_error);
- return dict.Pass();
+ return std::move(dict);
}
void LogFailedNSSFunction(const BoundNetLog& net_log,
diff --git a/chromium/net/socket/sequenced_socket_data_unittest.cc b/chromium/net/socket/sequenced_socket_data_unittest.cc
index 41e7b91932b..e8df5546e74 100644
--- a/chromium/net/socket/sequenced_socket_data_unittest.cc
+++ b/chromium/net/socket/sequenced_socket_data_unittest.cc
@@ -194,7 +194,10 @@ class SequencedSocketDataTest : public testing::Test {
void AssertSyncWriteEquals(const char* data, int len);
void AssertAsyncWriteEquals(const char* data, int len);
void AssertWriteReturns(const char* data, int len, int rv);
- void CompleteRead();
+
+ bool IsPaused() const;
+ void Resume();
+ void RunUntilPaused();
// When a given test completes, data_.at_eof() is expected to
// match the value specified here. Most test should consume all
@@ -314,8 +317,16 @@ void SequencedSocketDataTest::AssertAsyncWriteEquals(const char* data,
ASSERT_EQ(len, write_callback_.WaitForResult());
}
-void SequencedSocketDataTest::CompleteRead() {
- data_->CompleteRead();
+bool SequencedSocketDataTest::IsPaused() const {
+ return data_->IsPaused();
+}
+
+void SequencedSocketDataTest::Resume() {
+ data_->Resume();
+}
+
+void SequencedSocketDataTest::RunUntilPaused() {
+ data_->RunUntilPaused();
}
void SequencedSocketDataTest::AssertWriteReturns(const char* data,
@@ -592,7 +603,7 @@ TEST_F(SequencedSocketDataTest, SingleAsyncReadLargeBuffer) {
TEST_F(SequencedSocketDataTest, HangingRead) {
MockRead reads[] = {
- MockRead(ASYNC, ERR_IO_PENDING, 0),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
};
Initialize(reads, arraysize(reads), nullptr, 0);
@@ -608,28 +619,6 @@ TEST_F(SequencedSocketDataTest, HangingRead) {
ASSERT_FALSE(read_callback_.have_result());
}
-TEST_F(SequencedSocketDataTest, CompleteRead) {
- MockRead reads[] = {
- MockRead(ASYNC, ERR_IO_PENDING, 0), MockRead(ASYNC, kMsg1, kLen1, 1),
- };
-
- Initialize(reads, arraysize(reads), nullptr, 0);
-
- AssertReadReturns(kLen1, ERR_IO_PENDING);
- ASSERT_FALSE(read_callback_.have_result());
-
- // Even though the read is scheduled to complete at sequence number 0,
- // verify that the read callback in not called, until CompleteRead() is.
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_FALSE(read_callback_.have_result());
-
- CompleteRead();
-
- ASSERT_TRUE(read_callback_.have_result());
- ASSERT_EQ(kLen1, read_callback_.WaitForResult());
- AssertReadBufferEquals(kMsg1, kLen1);
-}
-
// ----------- Write
TEST_F(SequencedSocketDataTest, SingleSyncWriteTooEarly) {
@@ -1128,6 +1117,134 @@ TEST_F(SequencedSocketDataTest, MixedReentrantOperationsThenSynchronousWrite) {
base::MessageLoop::current()->RunUntilIdle();
}
+// Test the basic case where a read is paused.
+TEST_F(SequencedSocketDataTest, PauseAndResume_PauseRead) {
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 0), MockRead(ASYNC, kMsg1, kLen1, 1),
+ };
+
+ Initialize(reads, arraysize(reads), nullptr, 0);
+
+ AssertReadReturns(kLen1, ERR_IO_PENDING);
+ ASSERT_FALSE(read_callback_.have_result());
+
+ RunUntilPaused();
+ ASSERT_TRUE(IsPaused());
+
+ // Spinning the message loop should do nothing.
+ base::MessageLoop::current()->RunUntilIdle();
+ ASSERT_FALSE(read_callback_.have_result());
+ ASSERT_TRUE(IsPaused());
+
+ Resume();
+ ASSERT_FALSE(IsPaused());
+ ASSERT_TRUE(read_callback_.have_result());
+ ASSERT_EQ(kLen1, read_callback_.WaitForResult());
+ AssertReadBufferEquals(kMsg1, kLen1);
+}
+
+// Test the case where a read that will be paused is started before write that
+// completes before the pause.
+TEST_F(SequencedSocketDataTest, PauseAndResume_WritePauseRead) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, kMsg1, kLen1, 0),
+ };
+
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, kMsg2, kLen2, 2),
+ };
+
+ Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+ AssertReadReturns(kLen2, ERR_IO_PENDING);
+ ASSERT_FALSE(read_callback_.have_result());
+
+ // Nothing should happen until the write starts.
+ base::MessageLoop::current()->RunUntilIdle();
+ ASSERT_FALSE(read_callback_.have_result());
+ ASSERT_FALSE(IsPaused());
+
+ AssertSyncWriteEquals(kMsg1, kLen1);
+
+ RunUntilPaused();
+ ASSERT_FALSE(read_callback_.have_result());
+ ASSERT_TRUE(IsPaused());
+
+ // Spinning the message loop should do nothing.
+ base::MessageLoop::current()->RunUntilIdle();
+ ASSERT_FALSE(read_callback_.have_result());
+ ASSERT_TRUE(IsPaused());
+
+ Resume();
+ ASSERT_FALSE(IsPaused());
+ ASSERT_TRUE(read_callback_.have_result());
+ ASSERT_EQ(kLen2, read_callback_.WaitForResult());
+ AssertReadBufferEquals(kMsg2, kLen2);
+}
+
+// Test the basic case where a write is paused.
+TEST_F(SequencedSocketDataTest, PauseAndResume_PauseWrite) {
+ MockWrite writes[] = {
+ MockWrite(ASYNC, ERR_IO_PENDING, 0), MockWrite(ASYNC, kMsg1, kLen1, 1),
+ };
+
+ Initialize(nullptr, 0, writes, arraysize(writes));
+
+ AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
+ ASSERT_FALSE(write_callback_.have_result());
+
+ RunUntilPaused();
+ ASSERT_TRUE(IsPaused());
+
+ // Spinning the message loop should do nothing.
+ base::MessageLoop::current()->RunUntilIdle();
+ ASSERT_FALSE(write_callback_.have_result());
+ ASSERT_TRUE(IsPaused());
+
+ Resume();
+ ASSERT_FALSE(IsPaused());
+ ASSERT_TRUE(write_callback_.have_result());
+ ASSERT_EQ(kLen1, write_callback_.WaitForResult());
+}
+
+// Test the case where a write that will be paused is started before read that
+// completes before the pause.
+TEST_F(SequencedSocketDataTest, PauseAndResume_ReadPauseWrite) {
+ MockWrite writes[] = {
+ MockWrite(ASYNC, ERR_IO_PENDING, 1), MockWrite(ASYNC, kMsg2, kLen2, 2),
+ };
+
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, kMsg1, kLen1, 0),
+ };
+
+ Initialize(reads, arraysize(reads), writes, arraysize(writes));
+
+ AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
+ ASSERT_FALSE(write_callback_.have_result());
+
+ // Nothing should happen until the write starts.
+ base::MessageLoop::current()->RunUntilIdle();
+ ASSERT_FALSE(write_callback_.have_result());
+ ASSERT_FALSE(IsPaused());
+
+ AssertSyncReadEquals(kMsg1, kLen1);
+
+ RunUntilPaused();
+ ASSERT_FALSE(write_callback_.have_result());
+ ASSERT_TRUE(IsPaused());
+
+ // Spinning the message loop should do nothing.
+ base::MessageLoop::current()->RunUntilIdle();
+ ASSERT_FALSE(write_callback_.have_result());
+ ASSERT_TRUE(IsPaused());
+
+ Resume();
+ ASSERT_FALSE(IsPaused());
+ ASSERT_TRUE(write_callback_.have_result());
+ ASSERT_EQ(kLen2, write_callback_.WaitForResult());
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/socket/server_socket.cc b/chromium/net/socket/server_socket.cc
index 7cf6c64133c..50722a91f32 100644
--- a/chromium/net/socket/server_socket.cc
+++ b/chromium/net/socket/server_socket.cc
@@ -17,7 +17,7 @@ ServerSocket::~ServerSocket() {
}
int ServerSocket::ListenWithAddressAndPort(const std::string& address_string,
- uint16 port,
+ uint16_t port,
int backlog) {
IPAddressNumber address_number;
if (!ParseIPLiteralToNumber(address_string, &address_number)) {
diff --git a/chromium/net/socket/server_socket.h b/chromium/net/socket/server_socket.h
index 828b399c7a8..41894338e8a 100644
--- a/chromium/net/socket/server_socket.h
+++ b/chromium/net/socket/server_socket.h
@@ -5,9 +5,11 @@
#ifndef NET_SOCKET_SERVER_SOCKET_H_
#define NET_SOCKET_SERVER_SOCKET_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -31,7 +33,7 @@ class NET_EXPORT ServerSocket {
// Subclasses may override this function if |address_string| is in a different
// format, for example, unix domain socket path.
virtual int ListenWithAddressAndPort(const std::string& address_string,
- uint16 port,
+ uint16_t port,
int backlog);
// Gets current address the socket is bound to.
diff --git a/chromium/net/socket/socket.h b/chromium/net/socket/socket.h
index 5d9af81f205..cda54063f30 100644
--- a/chromium/net/socket/socket.h
+++ b/chromium/net/socket/socket.h
@@ -5,6 +5,8 @@
#ifndef NET_SOCKET_SOCKET_H_
#define NET_SOCKET_SOCKET_H_
+#include <stdint.h>
+
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -49,12 +51,12 @@ class NET_EXPORT Socket {
// Set the receive buffer size (in bytes) for the socket.
// Note: changing this value can affect the TCP window size on some platforms.
// Returns a net error code.
- virtual int SetReceiveBufferSize(int32 size) = 0;
+ virtual int SetReceiveBufferSize(int32_t size) = 0;
// Set the send buffer size (in bytes) for the socket.
// Note: changing this value can affect the TCP window size on some platforms.
// Returns a net error code.
- virtual int SetSendBufferSize(int32 size) = 0;
+ virtual int SetSendBufferSize(int32_t size) = 0;
};
} // namespace net
diff --git a/chromium/net/socket/socket_descriptor.cc b/chromium/net/socket/socket_descriptor.cc
index 81787a29d25..0822d2d9983 100644
--- a/chromium/net/socket/socket_descriptor.cc
+++ b/chromium/net/socket/socket_descriptor.cc
@@ -9,8 +9,6 @@
#include <sys/socket.h>
#endif
-#include "base/basictypes.h"
-
#if defined(OS_WIN)
#include <ws2tcpip.h>
#include "base/win/windows_version.h"
@@ -19,22 +17,10 @@
namespace net {
-PlatformSocketFactory* g_socket_factory = NULL;
-
-PlatformSocketFactory::PlatformSocketFactory() {
-}
-
-PlatformSocketFactory::~PlatformSocketFactory() {
-}
-
-void PlatformSocketFactory::SetInstance(PlatformSocketFactory* factory) {
- g_socket_factory = factory;
-}
-
-SocketDescriptor CreateSocketDefault(int family, int type, int protocol) {
+SocketDescriptor CreatePlatformSocket(int family, int type, int protocol) {
#if defined(OS_WIN)
EnsureWinsockInit();
- SocketDescriptor result = ::WSASocket(family, type, protocol, NULL, 0,
+ SocketDescriptor result = ::WSASocket(family, type, protocol, nullptr, 0,
WSA_FLAG_OVERLAPPED);
if (result != kInvalidSocket && family == AF_INET6 &&
base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) {
@@ -49,13 +35,7 @@ SocketDescriptor CreateSocketDefault(int family, int type, int protocol) {
#else // OS_WIN
return ::socket(family, type, protocol);
#endif // OS_WIN
-}
-SocketDescriptor CreatePlatformSocket(int family, int type, int protocol) {
- if (g_socket_factory)
- return g_socket_factory->CreateSocket(family, type, protocol);
- else
- return CreateSocketDefault(family, type, protocol);
}
} // namespace net
diff --git a/chromium/net/socket/socket_descriptor.h b/chromium/net/socket/socket_descriptor.h
index b2a22234b80..e58e1407be0 100644
--- a/chromium/net/socket/socket_descriptor.h
+++ b/chromium/net/socket/socket_descriptor.h
@@ -22,23 +22,6 @@ typedef SOCKET SocketDescriptor;
const SocketDescriptor kInvalidSocket = INVALID_SOCKET;
#endif
-// Interface to create native socket.
-// Usually such factories are used for testing purposes, which is not true in
-// this case. This interface is used to substitute WSASocket/socket to make
-// possible execution of some network code in sandbox.
-class NET_EXPORT PlatformSocketFactory {
- public:
- PlatformSocketFactory();
- virtual ~PlatformSocketFactory();
-
- // Replace WSASocket/socket with given factory. The factory will be used by
- // CreatePlatformSocket.
- static void SetInstance(PlatformSocketFactory* factory);
-
- // Creates socket. See WSASocket/socket documentation of parameters.
- virtual SocketDescriptor CreateSocket(int family, int type, int protocol) = 0;
-};
-
// Creates socket. See WSASocket/socket documentation of parameters.
SocketDescriptor NET_EXPORT CreatePlatformSocket(int family,
int type,
diff --git a/chromium/net/socket/socket_net_log_params.cc b/chromium/net/socket/socket_net_log_params.cc
index 64012f4264c..37be0a6a34b 100644
--- a/chromium/net/socket/socket_net_log_params.cc
+++ b/chromium/net/socket/socket_net_log_params.cc
@@ -4,6 +4,8 @@
#include "net/socket/socket_net_log_params.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
@@ -21,7 +23,7 @@ scoped_ptr<base::Value> NetLogSocketErrorCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("net_error", net_error);
dict->SetInteger("os_error", os_error);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogHostPortPairCallback(
@@ -29,7 +31,7 @@ scoped_ptr<base::Value> NetLogHostPortPairCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host_and_port", host_and_port->ToString());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogIPEndPointCallback(
@@ -37,7 +39,7 @@ scoped_ptr<base::Value> NetLogIPEndPointCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("address", address->ToString());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSourceAddressCallback(
@@ -45,9 +47,11 @@ scoped_ptr<base::Value> NetLogSourceAddressCallback(
socklen_t address_len,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetString("source_address",
- NetAddressToStringWithPort(net_address, address_len));
- return dict.Pass();
+ IPEndPoint ipe;
+ bool result = ipe.FromSockAddr(net_address, address_len);
+ DCHECK(result);
+ dict->SetString("source_address", ipe.ToString());
+ return std::move(dict);
}
} // namespace
diff --git a/chromium/net/socket/socket_posix.cc b/chromium/net/socket/socket_posix.cc
index 657774a0b71..96892891d09 100644
--- a/chromium/net/socket/socket_posix.cc
+++ b/chromium/net/socket/socket_posix.cc
@@ -7,14 +7,16 @@
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
+#include <utility>
#include "base/callback_helpers.h"
+#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
+#include "net/base/sockaddr_storage.h"
namespace net {
@@ -79,7 +81,7 @@ int SocketPosix::Open(int address_family) {
return MapSystemError(errno);
}
- if (SetNonBlocking(socket_fd_)) {
+ if (!base::SetNonBlocking(socket_fd_)) {
int rv = MapSystemError(errno);
Close();
return rv;
@@ -95,7 +97,7 @@ int SocketPosix::AdoptConnectedSocket(SocketDescriptor socket,
socket_fd_ = socket;
- if (SetNonBlocking(socket_fd_)) {
+ if (!base::SetNonBlocking(socket_fd_)) {
int rv = MapSystemError(errno);
Close();
return rv;
@@ -341,6 +343,10 @@ void SocketPosix::Close() {
}
}
+void SocketPosix::DetachFromThread() {
+ thread_checker_.DetachFromThread();
+}
+
void SocketPosix::OnFileCanReadWithoutBlocking(int fd) {
DCHECK(!accept_callback_.is_null() || !read_callback_.is_null());
if (!accept_callback_.is_null()) {
@@ -372,7 +378,7 @@ int SocketPosix::DoAccept(scoped_ptr<SocketPosix>* socket) {
if (rv != OK)
return rv;
- *socket = accepted_socket.Pass();
+ *socket = std::move(accepted_socket);
return OK;
}
diff --git a/chromium/net/socket/socket_posix.h b/chromium/net/socket/socket_posix.h
index 6ded624579c..f6df5292bf6 100644
--- a/chromium/net/socket/socket_posix.h
+++ b/chromium/net/socket/socket_posix.h
@@ -5,7 +5,6 @@
#ifndef NET_SOCKET_SOCKET_POSIX_H_
#define NET_SOCKET_SOCKET_POSIX_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -13,13 +12,13 @@
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_checker.h"
#include "net/base/completion_callback.h"
-#include "net/base/net_util.h"
#include "net/socket/socket_descriptor.h"
namespace net {
class IOBuffer;
class IPEndPoint;
+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.
@@ -76,6 +75,11 @@ class NET_EXPORT_PRIVATE SocketPosix : public base::MessageLoopForIO::Watcher {
void Close();
+ // Detachs from the current thread, to allow the socket to be transferred to
+ // a new thread. Should only be called when the object is no longer used by
+ // the old thread.
+ void DetachFromThread();
+
SocketDescriptor socket_fd() const { return socket_fd_; }
private:
diff --git a/chromium/net/socket/socket_test_util.cc b/chromium/net/socket/socket_test_util.cc
index 1436b14a17e..04f5151d4fe 100644
--- a/chromium/net/socket/socket_test_util.cc
+++ b/chromium/net/socket/socket_test_util.cc
@@ -5,9 +5,9 @@
#include "net/socket/socket_test_util.h"
#include <algorithm>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
@@ -35,7 +35,6 @@
#define NET_TRACE(level, s) VLOG(level) << s << __FUNCTION__ << "() "
namespace net {
-
namespace {
inline char AsciifyHigh(char x) {
@@ -143,6 +142,29 @@ MockConnect::MockConnect(IoMode io_mode, int r, IPEndPoint addr) :
MockConnect::~MockConnect() {}
+bool SocketDataProvider::IsIdle() const {
+ return true;
+}
+
+void SocketDataProvider::Initialize(AsyncSocket* socket) {
+ CHECK(!socket_);
+ CHECK(socket);
+ socket_ = socket;
+ Reset();
+}
+
+void SocketDataProvider::DetachSocket() {
+ CHECK(socket_);
+ socket_ = nullptr;
+}
+
+SocketDataProvider::SocketDataProvider() : socket_(nullptr) {}
+
+SocketDataProvider::~SocketDataProvider() {
+ if (socket_)
+ socket_->OnDataProviderDestroyed();
+}
+
StaticSocketDataHelper::StaticSocketDataHelper(MockRead* reads,
size_t reads_count,
MockWrite* writes,
@@ -247,10 +269,6 @@ MockWriteResult StaticSocketDataProvider::OnWrite(const std::string& data) {
return MockWriteResult(next_write.mode, result);
}
-void StaticSocketDataProvider::Reset() {
- helper_.Reset();
-}
-
bool StaticSocketDataProvider::AllReadDataConsumed() const {
return helper_.AllReadDataConsumed();
}
@@ -259,6 +277,10 @@ bool StaticSocketDataProvider::AllWriteDataConsumed() const {
return helper_.AllWriteDataConsumed();
}
+void StaticSocketDataProvider::Reset() {
+ helper_.Reset();
+}
+
SSLSocketDataProvider::SSLSocketDataProvider(IoMode mode, int result)
: connect(mode, result),
next_proto_status(SSLClientSocket::kNextProtoUnsupported),
@@ -288,6 +310,7 @@ SequencedSocketData::SequencedSocketData(MockRead* reads,
sequence_number_(0),
read_state_(IDLE),
write_state_(IDLE),
+ busy_before_sync_reads_(false),
weak_factory_(this) {
// Check that reads and writes have a contiguous set of sequence numbers
// starting from 0 and working their way up, with no repeats and skipping
@@ -295,15 +318,48 @@ SequencedSocketData::SequencedSocketData(MockRead* reads,
size_t next_read = 0;
size_t next_write = 0;
int next_sequence_number = 0;
+ bool last_event_was_pause = false;
while (next_read < reads_count || next_write < writes_count) {
if (next_read < reads_count &&
reads[next_read].sequence_number == next_sequence_number) {
+ // Check if this is a pause.
+ if (reads[next_read].mode == ASYNC &&
+ reads[next_read].result == ERR_IO_PENDING) {
+ CHECK(!last_event_was_pause) << "Two pauses in a row are not allowed: "
+ << next_sequence_number;
+ last_event_was_pause = true;
+ } else if (last_event_was_pause) {
+ CHECK_EQ(ASYNC, reads[next_read].mode)
+ << "A sync event after a pause makes no sense: "
+ << next_sequence_number;
+ CHECK_NE(ERR_IO_PENDING, reads[next_read].result)
+ << "A pause event after a pause makes no sense: "
+ << next_sequence_number;
+ last_event_was_pause = false;
+ }
+
++next_read;
++next_sequence_number;
continue;
}
if (next_write < writes_count &&
writes[next_write].sequence_number == next_sequence_number) {
+ // Check if this is a pause.
+ if (writes[next_write].mode == ASYNC &&
+ writes[next_write].result == ERR_IO_PENDING) {
+ CHECK(!last_event_was_pause) << "Two pauses in a row are not allowed: "
+ << next_sequence_number;
+ last_event_was_pause = true;
+ } else if (last_event_was_pause) {
+ CHECK_EQ(ASYNC, writes[next_write].mode)
+ << "A sync event after a pause makes no sense: "
+ << next_sequence_number;
+ CHECK_NE(ERR_IO_PENDING, writes[next_write].result)
+ << "A pause event after a pause makes no sense: "
+ << next_sequence_number;
+ last_event_was_pause = false;
+ }
+
++next_write;
++next_sequence_number;
continue;
@@ -312,6 +368,12 @@ SequencedSocketData::SequencedSocketData(MockRead* reads,
<< next_sequence_number;
return;
}
+
+ // Last event must not be a pause. For the final event to indicate the
+ // operation never completes, it should be SYNCHRONOUS and return
+ // ERR_IO_PENDING.
+ CHECK(!last_event_was_pause);
+
CHECK_EQ(next_read, reads_count);
CHECK_EQ(next_write, writes_count);
}
@@ -344,13 +406,12 @@ MockRead SequencedSocketData::OnRead() {
return next_read;
}
- // If the result is ERR_IO_PENDING, then advance to the next state
- // and pause reads.
+ // If the result is ERR_IO_PENDING, then pause.
if (next_read.result == ERR_IO_PENDING) {
- NET_TRACE(1, " *** ") << "Pausing at: " << sequence_number_;
- ++sequence_number_;
- helper_.AdvanceRead();
+ NET_TRACE(1, " *** ") << "Pausing read at: " << sequence_number_;
read_state_ = PAUSED;
+ if (run_until_paused_run_loop_)
+ run_until_paused_run_loop_->Quit();
return MockRead(SYNCHRONOUS, ERR_IO_PENDING);
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -394,6 +455,15 @@ MockWriteResult SequencedSocketData::OnWrite(const std::string& data) {
return MockWriteResult(SYNCHRONOUS, rv);
}
+ // If the result is ERR_IO_PENDING, then pause.
+ if (next_write.result == ERR_IO_PENDING) {
+ NET_TRACE(1, " *** ") << "Pausing write at: " << sequence_number_;
+ write_state_ = PAUSED;
+ if (run_until_paused_run_loop_)
+ run_until_paused_run_loop_->Quit();
+ return MockWriteResult(SYNCHRONOUS, ERR_IO_PENDING);
+ }
+
NET_TRACE(1, " *** ") << "Posting task to complete write";
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&SequencedSocketData::OnWriteComplete,
@@ -411,14 +481,6 @@ MockWriteResult SequencedSocketData::OnWrite(const std::string& data) {
return MockWriteResult(SYNCHRONOUS, ERR_IO_PENDING);
}
-void SequencedSocketData::Reset() {
- helper_.Reset();
- sequence_number_ = 0;
- read_state_ = IDLE;
- write_state_ = IDLE;
- weak_factory_.InvalidateWeakPtrs();
-}
-
bool SequencedSocketData::AllReadDataConsumed() const {
return helper_.AllReadDataConsumed();
}
@@ -427,19 +489,74 @@ bool SequencedSocketData::AllWriteDataConsumed() const {
return helper_.AllWriteDataConsumed();
}
-bool SequencedSocketData::IsReadPaused() {
- return read_state_ == PAUSED;
+bool SequencedSocketData::IsIdle() const {
+ // If |busy_before_sync_reads_| is not set, always considered idle. If
+ // no reads left, or the next operation is a write, also consider it idle.
+ if (!busy_before_sync_reads_ || helper_.AllReadDataConsumed() ||
+ helper_.PeekRead().sequence_number != sequence_number_) {
+ return true;
+ }
+
+ // If the next operation is synchronous read, treat the socket as not idle.
+ if (helper_.PeekRead().mode == SYNCHRONOUS)
+ return false;
+ return true;
+}
+
+bool SequencedSocketData::IsPaused() const {
+ // Both states should not be paused.
+ DCHECK(read_state_ != PAUSED || write_state_ != PAUSED);
+ return write_state_ == PAUSED || read_state_ == PAUSED;
}
-void SequencedSocketData::CompleteRead() {
- if (read_state_ != PAUSED) {
- ADD_FAILURE() << "Unable to CompleteRead when not paused.";
+void SequencedSocketData::Resume() {
+ if (!IsPaused()) {
+ ADD_FAILURE() << "Unable to Resume when not paused.";
return;
}
+
+ sequence_number_++;
+ if (read_state_ == PAUSED) {
+ read_state_ = PENDING;
+ helper_.AdvanceRead();
+ } else { // write_state_ == PAUSED
+ write_state_ = PENDING;
+ helper_.AdvanceWrite();
+ }
+
+ if (!helper_.AllWriteDataConsumed() &&
+ helper_.PeekWrite().sequence_number == sequence_number_) {
+ // The next event hasn't even started yet. Pausing isn't really needed in
+ // that case, but may as well support it.
+ if (write_state_ != PENDING)
+ return;
+ write_state_ = COMPLETING;
+ OnWriteComplete();
+ return;
+ }
+
+ CHECK(!helper_.AllReadDataConsumed());
+
+ // The next event hasn't even started yet. Pausing isn't really needed in
+ // that case, but may as well support it.
+ if (read_state_ != PENDING)
+ return;
read_state_ = COMPLETING;
OnReadComplete();
}
+void SequencedSocketData::RunUntilPaused() {
+ CHECK(!run_until_paused_run_loop_);
+
+ if (IsPaused())
+ return;
+
+ run_until_paused_run_loop_.reset(new base::RunLoop());
+ run_until_paused_run_loop_->Run();
+ run_until_paused_run_loop_.reset();
+ DCHECK(IsPaused());
+}
+
void SequencedSocketData::MaybePostReadCompleteTask() {
NET_TRACE(1, " ****** ") << " current: " << sequence_number_;
// Only trigger the next read to complete if there is already a read pending
@@ -449,13 +566,12 @@ void SequencedSocketData::MaybePostReadCompleteTask() {
return;
}
- // If the result is ERR_IO_PENDING, then advance to the next state
- // and pause reads.
+ // If the result is ERR_IO_PENDING, then pause.
if (helper_.PeekRead().result == ERR_IO_PENDING) {
NET_TRACE(1, " *** ") << "Pausing read at: " << sequence_number_;
- ++sequence_number_;
- helper_.AdvanceRead();
read_state_ = PAUSED;
+ if (run_until_paused_run_loop_)
+ run_until_paused_run_loop_->Quit();
return;
}
@@ -477,6 +593,15 @@ void SequencedSocketData::MaybePostWriteCompleteTask() {
return;
}
+ // If the result is ERR_IO_PENDING, then pause.
+ if (helper_.PeekWrite().result == ERR_IO_PENDING) {
+ NET_TRACE(1, " *** ") << "Pausing write at: " << sequence_number_;
+ write_state_ = PAUSED;
+ if (run_until_paused_run_loop_)
+ run_until_paused_run_loop_->Quit();
+ return;
+ }
+
NET_TRACE(1, " ****** ") << "Posting task to complete write: "
<< sequence_number_;
base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -486,6 +611,14 @@ void SequencedSocketData::MaybePostWriteCompleteTask() {
write_state_ = COMPLETING;
}
+void SequencedSocketData::Reset() {
+ helper_.Reset();
+ sequence_number_ = 0;
+ read_state_ = IDLE;
+ write_state_ = IDLE;
+ weak_factory_.InvalidateWeakPtrs();
+}
+
void SequencedSocketData::OnReadComplete() {
CHECK_EQ(COMPLETING, read_state_);
NET_TRACE(1, " *** ") << "Completing read for: " << sequence_number_;
@@ -545,210 +678,6 @@ void SequencedSocketData::OnWriteComplete() {
SequencedSocketData::~SequencedSocketData() {
}
-DeterministicSocketData::DeterministicSocketData(MockRead* reads,
- size_t reads_count,
- MockWrite* writes,
- size_t writes_count)
- : helper_(reads, reads_count, writes, writes_count),
- sequence_number_(0),
- current_read_(),
- current_write_(),
- stopping_sequence_number_(0),
- stopped_(false),
- print_debug_(false),
- is_running_(false) {
- VerifyCorrectSequenceNumbers(reads, reads_count, writes, writes_count);
-}
-
-DeterministicSocketData::~DeterministicSocketData() {}
-
-void DeterministicSocketData::Run() {
- DCHECK(!is_running_);
- is_running_ = true;
-
- SetStopped(false);
- int counter = 0;
- // Continue to consume data until all data has run out, or the stopped_ flag
- // has been set. Consuming data requires two separate operations -- running
- // the tasks in the message loop, and explicitly invoking the read/write
- // callbacks (simulating network I/O). We check our conditions between each,
- // since they can change in either.
- while ((!AllWriteDataConsumed() || !AllReadDataConsumed()) && !stopped()) {
- if (counter % 2 == 0)
- base::RunLoop().RunUntilIdle();
- if (counter % 2 == 1) {
- InvokeCallbacks();
- }
- counter++;
- }
- // We're done consuming new data, but it is possible there are still some
- // pending callbacks which we expect to complete before returning.
- while (delegate_.get() &&
- (delegate_->WritePending() || delegate_->ReadPending()) &&
- !stopped()) {
- InvokeCallbacks();
- base::RunLoop().RunUntilIdle();
- }
- SetStopped(false);
- is_running_ = false;
-}
-
-void DeterministicSocketData::RunFor(int steps) {
- StopAfter(steps);
- Run();
-}
-
-void DeterministicSocketData::SetStop(int seq) {
- DCHECK_LT(sequence_number_, seq);
- stopping_sequence_number_ = seq;
- stopped_ = false;
-}
-
-void DeterministicSocketData::StopAfter(int seq) {
- SetStop(sequence_number_ + seq);
-}
-
-MockRead DeterministicSocketData::OnRead() {
- current_read_ = helper_.PeekRead();
-
- // Synchronous read while stopped is an error
- if (stopped() && current_read_.mode == SYNCHRONOUS) {
- LOG(ERROR) << "Unable to perform synchronous IO while stopped";
- return MockRead(SYNCHRONOUS, ERR_UNEXPECTED);
- }
-
- // Async read which will be called back in a future step.
- if (sequence_number_ < current_read_.sequence_number) {
- NET_TRACE(1, " *** ") << "Stage " << sequence_number_ << ": I/O Pending";
- MockRead result = MockRead(SYNCHRONOUS, ERR_IO_PENDING);
- if (current_read_.mode == SYNCHRONOUS) {
- LOG(ERROR) << "Unable to perform synchronous read: "
- << current_read_.sequence_number
- << " at stage: " << sequence_number_;
- result = MockRead(SYNCHRONOUS, ERR_UNEXPECTED);
- }
- if (print_debug_)
- DumpMockReadWrite(result);
- return result;
- }
-
- NET_TRACE(1, " *** ") << "Stage " << sequence_number_ << ": Read "
- << helper_.read_index();
- if (print_debug_)
- DumpMockReadWrite(current_read_);
-
- // Increment the sequence number if IO is complete
- if (current_read_.mode == SYNCHRONOUS)
- NextStep();
-
- DCHECK_NE(ERR_IO_PENDING, current_read_.result);
-
- helper_.AdvanceRead();
- return current_read_;
-}
-
-MockWriteResult DeterministicSocketData::OnWrite(const std::string& data) {
- const MockWrite& next_write = helper_.PeekWrite();
- current_write_ = next_write;
-
- // Synchronous write while stopped is an error
- if (stopped() && next_write.mode == SYNCHRONOUS) {
- LOG(ERROR) << "Unable to perform synchronous IO while stopped";
- return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
- }
-
- // Async write which will be called back in a future step.
- if (sequence_number_ < next_write.sequence_number) {
- NET_TRACE(1, " *** ") << "Stage " << sequence_number_ << ": I/O Pending";
- if (next_write.mode == SYNCHRONOUS) {
- LOG(ERROR) << "Unable to perform synchronous write: "
- << next_write.sequence_number << " at stage: " << sequence_number_;
- return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
- }
- } else {
- NET_TRACE(1, " *** ") << "Stage " << sequence_number_ << ": Write "
- << helper_.write_index();
- }
-
- if (print_debug_)
- DumpMockReadWrite(next_write);
-
- // Move to the next step if I/O is synchronous, since the operation will
- // complete when this method returns.
- if (next_write.mode == SYNCHRONOUS)
- NextStep();
-
- // Check that what we are writing matches the expectation.
- // Then give the mocked return value.
- if (!helper_.VerifyWriteData(data))
- return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
-
- helper_.AdvanceWrite();
-
- // In the case that the write was successful, return the number of bytes
- // written. Otherwise return the error code.
- int result =
- next_write.result == OK ? next_write.data_len : next_write.result;
- return MockWriteResult(next_write.mode, result);
-}
-
-bool DeterministicSocketData::AllReadDataConsumed() const {
- return helper_.AllReadDataConsumed();
-}
-
-bool DeterministicSocketData::AllWriteDataConsumed() const {
- return helper_.AllWriteDataConsumed();
-}
-
-void DeterministicSocketData::InvokeCallbacks() {
- if (delegate_.get() && delegate_->WritePending() &&
- (current_write().sequence_number == sequence_number())) {
- NextStep();
- delegate_->CompleteWrite();
- return;
- }
- if (delegate_.get() && delegate_->ReadPending() &&
- (current_read().sequence_number == sequence_number())) {
- NextStep();
- delegate_->CompleteRead();
- return;
- }
-}
-
-void DeterministicSocketData::NextStep() {
- // Invariant: Can never move *past* the stopping step.
- DCHECK_LT(sequence_number_, stopping_sequence_number_);
- sequence_number_++;
- if (sequence_number_ == stopping_sequence_number_)
- SetStopped(true);
-}
-
-void DeterministicSocketData::VerifyCorrectSequenceNumbers(
- MockRead* reads, size_t reads_count,
- MockWrite* writes, size_t writes_count) {
- size_t read = 0;
- size_t write = 0;
- int expected = 0;
- while (read < reads_count || write < writes_count) {
- // Check to see that we have a read or write at the expected
- // state.
- if (read < reads_count && reads[read].sequence_number == expected) {
- ++read;
- ++expected;
- continue;
- }
- if (write < writes_count && writes[write].sequence_number == expected) {
- ++write;
- ++expected;
- continue;
- }
- NOTREACHED() << "Missing sequence number: " << expected;
- return;
- }
- DCHECK_EQ(read, reads_count);
- DCHECK_EQ(write, writes_count);
-}
-
MockClientSocketFactory::MockClientSocketFactory() {}
MockClientSocketFactory::~MockClientSocketFactory() {}
@@ -777,10 +706,11 @@ MockClientSocketFactory::CreateDatagramClientSocket(
SocketDataProvider* data_provider = mock_data_.GetNext();
scoped_ptr<MockUDPClientSocket> socket(
new MockUDPClientSocket(data_provider, net_log));
- data_provider->set_socket(socket.get());
if (bind_type == DatagramSocket::RANDOM_BIND)
- socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535)));
- return socket.Pass();
+ socket->set_source_port(
+ static_cast<uint16_t>(rand_int_cb.Run(1025, 65535)));
+ udp_client_socket_ports_.push_back(socket->source_port());
+ return std::move(socket);
}
scoped_ptr<StreamSocket> MockClientSocketFactory::CreateTransportClientSocket(
@@ -790,8 +720,7 @@ scoped_ptr<StreamSocket> MockClientSocketFactory::CreateTransportClientSocket(
SocketDataProvider* data_provider = mock_data_.GetNext();
scoped_ptr<MockTCPClientSocket> socket(
new MockTCPClientSocket(addresses, net_log, data_provider));
- data_provider->set_socket(socket.get());
- return socket.Pass();
+ return std::move(socket);
}
scoped_ptr<SSLClientSocket> MockClientSocketFactory::CreateSSLClientSocket(
@@ -802,14 +731,14 @@ scoped_ptr<SSLClientSocket> MockClientSocketFactory::CreateSSLClientSocket(
SSLSocketDataProvider* next_ssl_data = mock_ssl_data_.GetNext();
if (!next_ssl_data->next_protos_expected_in_ssl_config.empty()) {
EXPECT_EQ(next_ssl_data->next_protos_expected_in_ssl_config.size(),
- ssl_config.next_protos.size());
+ ssl_config.alpn_protos.size());
EXPECT_TRUE(
std::equal(next_ssl_data->next_protos_expected_in_ssl_config.begin(),
next_ssl_data->next_protos_expected_in_ssl_config.end(),
- ssl_config.next_protos.begin()));
+ ssl_config.alpn_protos.begin()));
}
return scoped_ptr<SSLClientSocket>(new MockSSLClientSocket(
- transport_socket.Pass(), host_and_port, ssl_config, next_ssl_data));
+ std::move(transport_socket), host_and_port, ssl_config, next_ssl_data));
}
void MockClientSocketFactory::ClearSSLSessionCache() {
@@ -826,11 +755,11 @@ MockClientSocket::MockClientSocket(const BoundNetLog& net_log)
peer_addr_ = IPEndPoint(ip, 0);
}
-int MockClientSocket::SetReceiveBufferSize(int32 size) {
+int MockClientSocket::SetReceiveBufferSize(int32_t size) {
return OK;
}
-int MockClientSocket::SetSendBufferSize(int32 size) {
+int MockClientSocket::SetSendBufferSize(int32_t size) {
return OK;
}
@@ -869,6 +798,11 @@ void MockClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
out->clear();
}
+int64_t MockClientSocket::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
void MockClientSocket::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
}
@@ -932,14 +866,17 @@ MockTCPClientSocket::MockTCPClientSocket(const AddressList& addresses,
was_used_to_convey_data_(false) {
DCHECK(data_);
peer_addr_ = data->connect_data().peer_addr;
- data_->Reset();
+ data_->Initialize(this);
}
-MockTCPClientSocket::~MockTCPClientSocket() {}
+MockTCPClientSocket::~MockTCPClientSocket() {
+ if (data_)
+ data_->DetachSocket();
+}
int MockTCPClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
// If the buffer is already in use, a read is already in progress!
@@ -981,7 +918,7 @@ int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len,
DCHECK(buf);
DCHECK_GT(buf_len, 0);
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
std::string data(buf->data(), buf_len);
@@ -996,8 +933,6 @@ int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len,
return ERR_IO_PENDING;
}
- // TODO(rch): remove this once OrderedSocketData and DelayedSocketData
- // have been removed.
if (write_result.mode == ASYNC) {
RunCallbackAsync(callback, write_result.result);
return ERR_IO_PENDING;
@@ -1021,6 +956,9 @@ void MockTCPClientSocket::AddConnectionAttempts(
}
int MockTCPClientSocket::Connect(const CompletionCallback& callback) {
+ if (!data_)
+ return ERR_UNEXPECTED;
+
if (connected_)
return OK;
connected_ = true;
@@ -1052,11 +990,15 @@ void MockTCPClientSocket::Disconnect() {
}
bool MockTCPClientSocket::IsConnected() const {
+ if (!data_)
+ return false;
return connected_ && !peer_closed_connection_;
}
bool MockTCPClientSocket::IsConnectedAndIdle() const {
- return IsConnected();
+ if (!data_)
+ return false;
+ return IsConnected() && data_->IsIdle();
}
int MockTCPClientSocket::GetPeerAddress(IPEndPoint* address) const {
@@ -1084,6 +1026,10 @@ bool MockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
}
void MockTCPClientSocket::OnReadComplete(const MockRead& data) {
+ // If |data_| has been destroyed, safest to just do nothing.
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(pending_read_buf_.get());
// You can't complete a read with another ERR_IO_PENDING status code.
@@ -1104,6 +1050,10 @@ void MockTCPClientSocket::OnReadComplete(const MockRead& data) {
}
void MockTCPClientSocket::OnWriteComplete(int rv) {
+ // If |data_| has been destroyed, safest to just do nothing.
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(!pending_write_callback_.is_null());
CompletionCallback callback = pending_write_callback_;
@@ -1111,10 +1061,18 @@ void MockTCPClientSocket::OnWriteComplete(int rv) {
}
void MockTCPClientSocket::OnConnectComplete(const MockConnect& data) {
+ // If |data_| has been destroyed, safest to just do nothing.
+ if (!data_)
+ return;
+
CompletionCallback callback = pending_connect_callback_;
RunCallback(callback, data.result);
}
+void MockTCPClientSocket::OnDataProviderDestroyed() {
+ data_ = nullptr;
+}
+
int MockTCPClientSocket::CompleteRead() {
DCHECK(pending_read_buf_.get());
DCHECK(pending_read_buf_len_ > 0);
@@ -1154,283 +1112,6 @@ int MockTCPClientSocket::CompleteRead() {
return result;
}
-DeterministicSocketHelper::DeterministicSocketHelper(
- NetLog* net_log,
- DeterministicSocketData* data)
- : write_pending_(false),
- write_result_(0),
- read_data_(),
- read_buf_(NULL),
- read_buf_len_(0),
- read_pending_(false),
- data_(data),
- was_used_to_convey_data_(false),
- peer_closed_connection_(false),
- net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_NONE)) {
-}
-
-DeterministicSocketHelper::~DeterministicSocketHelper() {}
-
-void DeterministicSocketHelper::CompleteWrite() {
- was_used_to_convey_data_ = true;
- write_pending_ = false;
- write_callback_.Run(write_result_);
-}
-
-int DeterministicSocketHelper::CompleteRead() {
- DCHECK_GT(read_buf_len_, 0);
- DCHECK_LE(read_data_.data_len, read_buf_len_);
- DCHECK(read_buf_);
-
- was_used_to_convey_data_ = true;
-
- if (read_data_.result == ERR_IO_PENDING)
- read_data_ = data_->OnRead();
- DCHECK_NE(ERR_IO_PENDING, read_data_.result);
- // If read_data_.mode is ASYNC, we do not need to wait, since this is already
- // the callback. Therefore we don't even bother to check it.
- int result = read_data_.result;
-
- if (read_data_.data_len > 0) {
- DCHECK(read_data_.data);
- result = std::min(read_buf_len_, read_data_.data_len);
- memcpy(read_buf_->data(), read_data_.data, result);
- }
-
- if (read_pending_) {
- read_pending_ = false;
- read_callback_.Run(result);
- }
-
- return result;
-}
-
-int DeterministicSocketHelper::Write(
- IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
- DCHECK(buf);
- DCHECK_GT(buf_len, 0);
-
- std::string data(buf->data(), buf_len);
- MockWriteResult write_result = data_->OnWrite(data);
-
- if (write_result.mode == ASYNC) {
- write_callback_ = callback;
- write_result_ = write_result.result;
- DCHECK(!write_callback_.is_null());
- write_pending_ = true;
- return ERR_IO_PENDING;
- }
-
- was_used_to_convey_data_ = true;
- write_pending_ = false;
- return write_result.result;
-}
-
-int DeterministicSocketHelper::Read(
- IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
- read_data_ = data_->OnRead();
- // The buffer should always be big enough to contain all the MockRead data. To
- // use small buffers, split the data into multiple MockReads.
- DCHECK_LE(read_data_.data_len, buf_len);
-
- if (read_data_.result == ERR_CONNECTION_CLOSED) {
- // This MockRead is just a marker to instruct us to set
- // peer_closed_connection_.
- peer_closed_connection_ = true;
- }
- if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) {
- // This MockRead is just a marker to instruct us to set
- // peer_closed_connection_. Skip it and get the next one.
- read_data_ = data_->OnRead();
- peer_closed_connection_ = true;
- }
-
- read_buf_ = buf;
- read_buf_len_ = buf_len;
- read_callback_ = callback;
-
- if (read_data_.mode == ASYNC || (read_data_.result == ERR_IO_PENDING)) {
- read_pending_ = true;
- DCHECK(!read_callback_.is_null());
- return ERR_IO_PENDING;
- }
-
- was_used_to_convey_data_ = true;
- return CompleteRead();
-}
-
-DeterministicMockUDPClientSocket::DeterministicMockUDPClientSocket(
- net::NetLog* net_log,
- DeterministicSocketData* data)
- : connected_(false),
- helper_(net_log, data),
- source_port_(123) {
-}
-
-DeterministicMockUDPClientSocket::~DeterministicMockUDPClientSocket() {}
-
-bool DeterministicMockUDPClientSocket::WritePending() const {
- return helper_.write_pending();
-}
-
-bool DeterministicMockUDPClientSocket::ReadPending() const {
- return helper_.read_pending();
-}
-
-void DeterministicMockUDPClientSocket::CompleteWrite() {
- helper_.CompleteWrite();
-}
-
-int DeterministicMockUDPClientSocket::CompleteRead() {
- return helper_.CompleteRead();
-}
-
-int DeterministicMockUDPClientSocket::Connect(const IPEndPoint& address) {
- if (connected_)
- return OK;
- connected_ = true;
- peer_address_ = address;
- return helper_.data()->connect_data().result;
-};
-
-int DeterministicMockUDPClientSocket::Write(
- IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
- if (!connected_)
- return ERR_UNEXPECTED;
-
- return helper_.Write(buf, buf_len, callback);
-}
-
-int DeterministicMockUDPClientSocket::Read(
- IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
- if (!connected_)
- return ERR_UNEXPECTED;
-
- return helper_.Read(buf, buf_len, callback);
-}
-
-int DeterministicMockUDPClientSocket::SetReceiveBufferSize(int32 size) {
- return OK;
-}
-
-int DeterministicMockUDPClientSocket::SetSendBufferSize(int32 size) {
- return OK;
-}
-
-void DeterministicMockUDPClientSocket::Close() {
- connected_ = false;
-}
-
-int DeterministicMockUDPClientSocket::GetPeerAddress(
- IPEndPoint* address) const {
- *address = peer_address_;
- return OK;
-}
-
-int DeterministicMockUDPClientSocket::GetLocalAddress(
- IPEndPoint* address) const {
- IPAddressNumber ip;
- bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip);
- CHECK(rv);
- *address = IPEndPoint(ip, source_port_);
- return OK;
-}
-
-const BoundNetLog& DeterministicMockUDPClientSocket::NetLog() const {
- return helper_.net_log();
-}
-
-DeterministicMockTCPClientSocket::DeterministicMockTCPClientSocket(
- net::NetLog* net_log,
- DeterministicSocketData* data)
- : MockClientSocket(BoundNetLog::Make(net_log, NetLog::SOURCE_NONE)),
- helper_(net_log, data) {
- peer_addr_ = data->connect_data().peer_addr;
-}
-
-DeterministicMockTCPClientSocket::~DeterministicMockTCPClientSocket() {}
-
-bool DeterministicMockTCPClientSocket::WritePending() const {
- return helper_.write_pending();
-}
-
-bool DeterministicMockTCPClientSocket::ReadPending() const {
- return helper_.read_pending();
-}
-
-void DeterministicMockTCPClientSocket::CompleteWrite() {
- helper_.CompleteWrite();
-}
-
-int DeterministicMockTCPClientSocket::CompleteRead() {
- return helper_.CompleteRead();
-}
-
-int DeterministicMockTCPClientSocket::Write(
- IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
- if (!connected_)
- return ERR_UNEXPECTED;
-
- return helper_.Write(buf, buf_len, callback);
-}
-
-int DeterministicMockTCPClientSocket::Read(
- IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
- if (!connected_)
- return ERR_UNEXPECTED;
-
- return helper_.Read(buf, buf_len, callback);
-}
-
-// TODO(erikchen): Support connect sequencing.
-int DeterministicMockTCPClientSocket::Connect(
- const CompletionCallback& callback) {
- if (connected_)
- return OK;
- connected_ = true;
- if (helper_.data()->connect_data().mode == ASYNC) {
- RunCallbackAsync(callback, helper_.data()->connect_data().result);
- return ERR_IO_PENDING;
- }
- return helper_.data()->connect_data().result;
-}
-
-void DeterministicMockTCPClientSocket::Disconnect() {
- MockClientSocket::Disconnect();
-}
-
-bool DeterministicMockTCPClientSocket::IsConnected() const {
- return connected_ && !helper_.peer_closed_connection();
-}
-
-bool DeterministicMockTCPClientSocket::IsConnectedAndIdle() const {
- return IsConnected();
-}
-
-bool DeterministicMockTCPClientSocket::WasEverUsed() const {
- return helper_.was_used_to_convey_data();
-}
-
-bool DeterministicMockTCPClientSocket::UsingTCPFastOpen() const {
- return false;
-}
-
-bool DeterministicMockTCPClientSocket::WasNpnNegotiated() const {
- return false;
-}
-
-bool DeterministicMockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
- return false;
-}
-
// static
void MockSSLClientSocket::ConnectCallback(
MockSSLClientSocket* ssl_client_socket,
@@ -1449,8 +1130,9 @@ MockSSLClientSocket::MockSSLClientSocket(
: MockClientSocket(
// Have to use the right BoundNetLog for LoadTimingInfo regression
// tests.
- transport_socket->socket()->NetLog()),
- transport_(transport_socket.Pass()),
+ transport_socket->socket()
+ ->NetLog()),
+ transport_(std::move(transport_socket)),
data_(data) {
DCHECK(data_);
peer_addr_ = data->connect.peer_addr;
@@ -1495,6 +1177,10 @@ bool MockSSLClientSocket::IsConnected() const {
return transport_->socket()->IsConnected();
}
+bool MockSSLClientSocket::IsConnectedAndIdle() const {
+ return transport_->socket()->IsConnectedAndIdle();
+}
+
bool MockSSLClientSocket::WasEverUsed() const {
return transport_->socket()->WasEverUsed();
}
@@ -1558,21 +1244,25 @@ MockUDPClientSocket::MockUDPClientSocket(SocketDataProvider* data,
read_data_(SYNCHRONOUS, ERR_UNEXPECTED),
need_read_data_(true),
source_port_(123),
+ network_(NetworkChangeNotifier::kInvalidNetworkHandle),
pending_read_buf_(NULL),
pending_read_buf_len_(0),
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_NONE)),
weak_factory_(this) {
DCHECK(data_);
- data_->Reset();
+ data_->Initialize(this);
peer_addr_ = data->connect_data().peer_addr;
}
-MockUDPClientSocket::~MockUDPClientSocket() {}
+MockUDPClientSocket::~MockUDPClientSocket() {
+ if (data_)
+ data_->DetachSocket();
+}
int MockUDPClientSocket::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
// If the buffer is already in use, a read is already in progress!
@@ -1603,7 +1293,7 @@ int MockUDPClientSocket::Write(IOBuffer* buf, int buf_len,
DCHECK(buf);
DCHECK_GT(buf_len, 0);
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
std::string data(buf->data(), buf_len);
@@ -1622,11 +1312,11 @@ int MockUDPClientSocket::Write(IOBuffer* buf, int buf_len,
return write_result.result;
}
-int MockUDPClientSocket::SetReceiveBufferSize(int32 size) {
+int MockUDPClientSocket::SetReceiveBufferSize(int32_t size) {
return OK;
}
-int MockUDPClientSocket::SetSendBufferSize(int32 size) {
+int MockUDPClientSocket::SetSendBufferSize(int32_t size) {
return OK;
}
@@ -1651,13 +1341,34 @@ const BoundNetLog& MockUDPClientSocket::NetLog() const {
return net_log_;
}
+int MockUDPClientSocket::BindToNetwork(
+ NetworkChangeNotifier::NetworkHandle network) {
+ network_ = network;
+ return OK;
+}
+
+int MockUDPClientSocket::BindToDefaultNetwork() {
+ network_ = kDefaultNetworkForTests;
+ return OK;
+}
+
+NetworkChangeNotifier::NetworkHandle MockUDPClientSocket::GetBoundNetwork()
+ const {
+ return network_;
+}
+
int MockUDPClientSocket::Connect(const IPEndPoint& address) {
+ if (!data_)
+ return ERR_UNEXPECTED;
connected_ = true;
peer_addr_ = address;
return data_->connect_data().result;
}
void MockUDPClientSocket::OnReadComplete(const MockRead& data) {
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(pending_read_buf_.get());
// You can't complete a read with another ERR_IO_PENDING status code.
@@ -1678,6 +1389,9 @@ void MockUDPClientSocket::OnReadComplete(const MockRead& data) {
}
void MockUDPClientSocket::OnWriteComplete(int rv) {
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(!pending_write_callback_.is_null());
CompletionCallback callback = pending_write_callback_;
@@ -1688,6 +1402,10 @@ void MockUDPClientSocket::OnConnectComplete(const MockConnect& data) {
NOTIMPLEMENTED();
}
+void MockUDPClientSocket::OnDataProviderDestroyed() {
+ data_ = nullptr;
+}
+
int MockUDPClientSocket::CompleteRead() {
DCHECK(pending_read_buf_.get());
DCHECK(pending_read_buf_len_ > 0);
@@ -1772,19 +1490,18 @@ int ClientSocketPoolTest::GetOrderOfRequest(size_t index) const {
return kIndexOutOfBounds;
for (size_t i = 0; i < request_order_.size(); i++)
- if (requests_[index] == request_order_[i])
+ if (requests_[index].get() == request_order_[i])
return i + 1;
return kRequestNotFound;
}
bool ClientSocketPoolTest::ReleaseOneConnection(KeepAlive keep_alive) {
- ScopedVector<TestSocketRequest>::iterator i;
- for (i = requests_.begin(); i != requests_.end(); ++i) {
- if ((*i)->handle()->is_initialized()) {
+ for (scoped_ptr<TestSocketRequest>& it : requests_) {
+ if (it->handle()->is_initialized()) {
if (keep_alive == NO_KEEP_ALIVE)
- (*i)->handle()->socket()->Disconnect();
- (*i)->handle()->Reset();
+ it->handle()->socket()->Disconnect();
+ it->handle()->Reset();
base::RunLoop().RunUntilIdle();
return true;
}
@@ -1803,10 +1520,7 @@ MockTransportClientSocketPool::MockConnectJob::MockConnectJob(
scoped_ptr<StreamSocket> socket,
ClientSocketHandle* handle,
const CompletionCallback& callback)
- : socket_(socket.Pass()),
- handle_(handle),
- user_callback_(callback) {
-}
+ : socket_(std::move(socket)), handle_(handle), user_callback_(callback) {}
MockTransportClientSocketPool::MockConnectJob::~MockConnectJob() {}
@@ -1834,7 +1548,7 @@ void MockTransportClientSocketPool::MockConnectJob::OnConnect(int rv) {
if (!socket_.get())
return;
if (rv == OK) {
- handle_->SetSocket(socket_.Pass());
+ handle_->SetSocket(std::move(socket_));
// Needed for socket pool tests that layer other sockets on top of mock
// sockets.
@@ -1888,17 +1602,16 @@ int MockTransportClientSocketPool::RequestSocket(
scoped_ptr<StreamSocket> socket =
client_socket_factory_->CreateTransportClientSocket(
AddressList(), net_log.net_log(), NetLog::Source());
- MockConnectJob* job = new MockConnectJob(socket.Pass(), handle, callback);
- job_list_.push_back(job);
+ MockConnectJob* job = new MockConnectJob(std::move(socket), handle, callback);
+ job_list_.push_back(make_scoped_ptr(job));
handle->set_pool_id(1);
return job->Connect();
}
void MockTransportClientSocketPool::CancelRequest(const std::string& group_name,
ClientSocketHandle* handle) {
- std::vector<MockConnectJob*>::iterator i;
- for (i = job_list_.begin(); i != job_list_.end(); ++i) {
- if ((*i)->CancelHandle(handle)) {
+ for (scoped_ptr<MockConnectJob>& it : job_list_) {
+ if (it->CancelHandle(handle)) {
cancel_count_++;
break;
}
@@ -1913,77 +1626,6 @@ void MockTransportClientSocketPool::ReleaseSocket(
release_count_++;
}
-DeterministicMockClientSocketFactory::DeterministicMockClientSocketFactory() {}
-
-DeterministicMockClientSocketFactory::~DeterministicMockClientSocketFactory() {}
-
-void DeterministicMockClientSocketFactory::AddSocketDataProvider(
- DeterministicSocketData* data) {
- mock_data_.Add(data);
-}
-
-void DeterministicMockClientSocketFactory::AddSSLSocketDataProvider(
- SSLSocketDataProvider* data) {
- mock_ssl_data_.Add(data);
-}
-
-void DeterministicMockClientSocketFactory::ResetNextMockIndexes() {
- mock_data_.ResetNextIndex();
- mock_ssl_data_.ResetNextIndex();
-}
-
-MockSSLClientSocket* DeterministicMockClientSocketFactory::
- GetMockSSLClientSocket(size_t index) const {
- DCHECK_LT(index, ssl_client_sockets_.size());
- return ssl_client_sockets_[index];
-}
-
-scoped_ptr<DatagramClientSocket>
-DeterministicMockClientSocketFactory::CreateDatagramClientSocket(
- DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
- NetLog* net_log,
- const NetLog::Source& source) {
- DeterministicSocketData* data_provider = mock_data().GetNext();
- scoped_ptr<DeterministicMockUDPClientSocket> socket(
- new DeterministicMockUDPClientSocket(net_log, data_provider));
- data_provider->set_delegate(socket->AsWeakPtr());
- udp_client_sockets().push_back(socket.get());
- if (bind_type == DatagramSocket::RANDOM_BIND)
- socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535)));
- return socket.Pass();
-}
-
-scoped_ptr<StreamSocket>
-DeterministicMockClientSocketFactory::CreateTransportClientSocket(
- const AddressList& addresses,
- NetLog* net_log,
- const NetLog::Source& source) {
- DeterministicSocketData* data_provider = mock_data().GetNext();
- scoped_ptr<DeterministicMockTCPClientSocket> socket(
- new DeterministicMockTCPClientSocket(net_log, data_provider));
- data_provider->set_delegate(socket->AsWeakPtr());
- tcp_client_sockets().push_back(socket.get());
- return socket.Pass();
-}
-
-scoped_ptr<SSLClientSocket>
-DeterministicMockClientSocketFactory::CreateSSLClientSocket(
- scoped_ptr<ClientSocketHandle> transport_socket,
- const HostPortPair& host_and_port,
- const SSLConfig& ssl_config,
- const SSLClientSocketContext& context) {
- scoped_ptr<MockSSLClientSocket> socket(
- new MockSSLClientSocket(transport_socket.Pass(),
- host_and_port, ssl_config,
- mock_ssl_data_.GetNext()));
- ssl_client_sockets_.push_back(socket.get());
- return socket.Pass();
-}
-
-void DeterministicMockClientSocketFactory::ClearSSLSessionCache() {
-}
-
MockSOCKSClientSocketPool::MockSOCKSClientSocketPool(
int max_sockets,
int max_sockets_per_group,
@@ -2015,7 +1657,7 @@ void MockSOCKSClientSocketPool::CancelRequest(
void MockSOCKSClientSocketPool::ReleaseSocket(const std::string& group_name,
scoped_ptr<StreamSocket> socket,
int id) {
- return transport_pool_->ReleaseSocket(group_name, socket.Pass(), id);
+ return transport_pool_->ReleaseSocket(group_name, std::move(socket), id);
}
ScopedWebSocketEndpointZeroUnlockDelay::
diff --git a/chromium/net/socket/socket_test_util.h b/chromium/net/socket/socket_test_util.h
index 6b966dff560..a3c6df42149 100644
--- a/chromium/net/socket/socket_test_util.h
+++ b/chromium/net/socket/socket_test_util.h
@@ -5,6 +5,7 @@
#ifndef NET_SOCKET_SOCKET_TEST_UTIL_H_
#define NET_SOCKET_SOCKET_TEST_UTIL_H_
+#include <stddef.h>
#include <stdint.h>
#include <cstring>
@@ -12,9 +13,9 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
@@ -39,8 +40,15 @@
#include "net/udp/datagram_client_socket.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace base {
+class RunLoop;
+}
+
namespace net {
+const NetworkChangeNotifier::NetworkHandle kDefaultNetworkForTests = 1;
+const NetworkChangeNotifier::NetworkHandle kNewNetworkForTests = 2;
+
enum {
// A private network error code used by the socket test utility classes.
// If the |result| member of a MockRead is
@@ -187,12 +195,13 @@ struct MockWriteResult {
};
// The SocketDataProvider is an interface used by the MockClientSocket
-// for getting data about individual reads and writes on the socket.
+// for getting data about individual reads and writes on the socket. Can be
+// used with at most one socket at a time.
+// TODO(mmenke): Do these really need to be re-useable?
class SocketDataProvider {
public:
- SocketDataProvider() : socket_(NULL) {}
-
- virtual ~SocketDataProvider() {}
+ SocketDataProvider();
+ virtual ~SocketDataProvider();
// Returns the buffer and result code for the next simulated read.
// If the |MockRead.result| is ERR_IO_PENDING, it informs the caller
@@ -200,18 +209,32 @@ class SocketDataProvider {
// function at a later time.
virtual MockRead OnRead() = 0;
virtual MockWriteResult OnWrite(const std::string& data) = 0;
- virtual void Reset() = 0;
virtual bool AllReadDataConsumed() const = 0;
virtual bool AllWriteDataConsumed() const = 0;
+ // Returns true if the request should be considered idle, for the purposes of
+ // IsConnectedAndIdle.
+ virtual bool IsIdle() const;
+
+ // Initializes the SocketDataProvider for use with |socket|. Must be called
+ // before use
+ void Initialize(AsyncSocket* socket);
+ // Detaches the socket associated with a SocketDataProvider. Must be called
+ // before |socket_| is destroyed, unless the SocketDataProvider has informed
+ // |socket_| it was destroyed. Must also be called before Initialize() may
+ // be called again with a new socket.
+ void DetachSocket();
+
// Accessor for the socket which is using the SocketDataProvider.
AsyncSocket* socket() { return socket_; }
- void set_socket(AsyncSocket* socket) { socket_ = socket; }
MockConnect connect_data() const { return connect_; }
void set_connect_data(const MockConnect& connect) { connect_ = connect; }
private:
+ // Called to inform subclasses of initialization.
+ virtual void Reset() = 0;
+
MockConnect connect_;
AsyncSocket* socket_;
@@ -235,6 +258,11 @@ class AsyncSocket {
// is called to complete the asynchronous read operation.
virtual void OnWriteComplete(int rv) = 0;
virtual void OnConnectComplete(const MockConnect& data) = 0;
+
+ // Called when the SocketDataProvider associated with the socket is destroyed.
+ // The socket may continue to be used after the data provider is destroyed,
+ // so it should be sure not to dereference the provider after this is called.
+ virtual void OnDataProviderDestroyed() = 0;
};
// StaticSocketDataHelper manages a list of reads and writes.
@@ -295,10 +323,9 @@ class StaticSocketDataProvider : public SocketDataProvider {
virtual void CompleteRead() {}
- // SocketDataProvider implementation.
+ // From SocketDataProvider:
MockRead OnRead() override;
MockWriteResult OnWrite(const std::string& data) override;
- void Reset() override;
bool AllReadDataConsumed() const override;
bool AllWriteDataConsumed() const override;
@@ -307,10 +334,10 @@ class StaticSocketDataProvider : public SocketDataProvider {
size_t read_count() const { return helper_.read_count(); }
size_t write_count() const { return helper_.write_count(); }
- protected:
- StaticSocketDataHelper* helper() { return &helper_; }
-
private:
+ // From SocketDataProvider:
+ void Reset() override;
+
StaticSocketDataHelper helper_;
DISALLOW_COPY_AND_ASSIGN(StaticSocketDataProvider);
@@ -358,15 +385,37 @@ class SequencedSocketData : public SocketDataProvider {
~SequencedSocketData() override;
- // SocketDataProviderBase implementation.
+ // From SocketDataProvider:
MockRead OnRead() override;
MockWriteResult OnWrite(const std::string& data) override;
- void Reset() override;
bool AllReadDataConsumed() const override;
bool AllWriteDataConsumed() const override;
-
- bool IsReadPaused();
- void CompleteRead();
+ bool IsIdle() const override;
+
+ // An ASYNC read event with a return value of ERR_IO_PENDING will cause the
+ // socket data to pause at that event, and advance no further, until Resume is
+ // invoked. At that point, the socket will continue at the next event in the
+ // sequence.
+ //
+ // If a request just wants to simulate a connection that stays open and never
+ // receives any more data, instead of pausing and then resuming a request, it
+ // should use a SYNCHRONOUS event with a return value of ERR_IO_PENDING
+ // instead.
+ bool IsPaused() const;
+ // Resumes events once |this| is in the paused state. The next even will
+ // occur synchronously with the call if it can.
+ void Resume();
+ void RunUntilPaused();
+
+ // When true, IsConnectedAndIdle() will return false if the next event in the
+ // sequence is a synchronous. Otherwise, the socket claims to be idle as
+ // long as it's connected. Defaults to false.
+ // TODO(mmenke): See if this can be made the default behavior, and consider
+ // removing this mehtod. Need to make sure it doesn't change what code any
+ // tests are targetted at testing.
+ void set_busy_before_sync_reads(bool busy_before_sync_reads) {
+ busy_before_sync_reads_ = busy_before_sync_reads;
+ }
private:
// Defines the state for the read or write path.
@@ -375,9 +424,12 @@ class SequencedSocketData : public SocketDataProvider {
PENDING, // An async operation in waiting for another opteration to
// complete.
COMPLETING, // A task has been posted to complet an async operation.
- PAUSED, // IO is paused until CompleteRead() is called.
+ PAUSED, // IO is paused until Resume() is called.
};
+ // From SocketDataProvider:
+ void Reset() override;
+
void OnReadComplete();
void OnWriteComplete();
@@ -389,157 +441,14 @@ class SequencedSocketData : public SocketDataProvider {
IoState read_state_;
IoState write_state_;
- base::WeakPtrFactory<SequencedSocketData> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(SequencedSocketData);
-};
-
-class DeterministicMockTCPClientSocket;
-
-// This class gives the user full control over the network activity,
-// specifically the timing of the COMPLETION of I/O operations. Regardless of
-// the order in which I/O operations are initiated, this class ensures that they
-// complete in the correct order.
-//
-// Network activity is modeled as a sequence of numbered steps which is
-// incremented whenever an I/O operation completes. This can happen under two
-// different circumstances:
-//
-// 1) Performing a synchronous I/O operation. (Invoking Read() or Write()
-// when the corresponding MockRead or MockWrite is marked !async).
-// 2) Running the Run() method of this class. The run method will invoke
-// the current MessageLoop, running all pending events, and will then
-// invoke any pending IO callbacks.
-//
-// In addition, this class allows for I/O processing to "stop" at a specified
-// step, by calling SetStop(int) or StopAfter(int). Initiating an I/O operation
-// by calling Read() or Write() while stopped is permitted if the operation is
-// asynchronous. It is an error to perform synchronous I/O while stopped.
-//
-// When creating the MockReads and MockWrites, note that the sequence number
-// refers to the number of the step in which the I/O will complete. In the
-// case of synchronous I/O, this will be the same step as the I/O is initiated.
-// However, in the case of asynchronous I/O, this I/O may be initiated in
-// a much earlier step. Furthermore, when the a Read() or Write() is separated
-// from its completion by other Read() or Writes()'s, it can not be marked
-// synchronous. If it is, ERR_UNUEXPECTED will be returned indicating that a
-// synchronous Read() or Write() could not be completed synchronously because of
-// the specific ordering constraints.
-//
-// Sequence numbers are preserved across both reads and writes. There should be
-// no gaps in sequence numbers, and no repeated sequence numbers. i.e.
-// MockRead reads[] = {
-// MockRead(false, "first read", length, 0) // sync
-// MockRead(true, "second read", length, 2) // async
-// };
-// MockWrite writes[] = {
-// MockWrite(true, "first write", length, 1), // async
-// MockWrite(false, "second write", length, 3), // sync
-// };
-//
-// Example control flow:
-// Read() is called. The current step is 0. The first available read is
-// synchronous, so the call to Read() returns length. The current step is
-// now 1. Next, Read() is called again. The next available read can
-// not be completed until step 2, so Read() returns ERR_IO_PENDING. The current
-// step is still 1. Write is called(). The first available write is able to
-// complete in this step, but is marked asynchronous. Write() returns
-// ERR_IO_PENDING. The current step is still 1. At this point RunFor(1) is
-// called which will cause the write callback to be invoked, and will then
-// stop. The current state is now 2. RunFor(1) is called again, which
-// causes the read callback to be invoked, and will then stop. Then current
-// step is 2. Write() is called again. Then next available write is
-// synchronous so the call to Write() returns length.
-//
-// For examples of how to use this class, see:
-// deterministic_socket_data_unittests.cc
-class DeterministicSocketData {
- public:
- // The Delegate is an abstract interface which handles the communication from
- // the DeterministicSocketData to the Deterministic MockSocket. The
- // MockSockets directly store a pointer to the DeterministicSocketData,
- // whereas the DeterministicSocketData only stores a pointer to the
- // abstract Delegate interface.
- class Delegate {
- public:
- // Returns true if there is currently a write pending. That is to say, if
- // an asynchronous write has been started but the callback has not been
- // invoked.
- virtual bool WritePending() const = 0;
- // Returns true if there is currently a read pending. That is to say, if
- // an asynchronous read has been started but the callback has not been
- // invoked.
- virtual bool ReadPending() const = 0;
- // Called to complete an asynchronous write to execute the write callback.
- virtual void CompleteWrite() = 0;
- // Called to complete an asynchronous read to execute the read callback.
- virtual int CompleteRead() = 0;
-
- protected:
- virtual ~Delegate() {}
- };
-
- // |reads| the list of MockRead completions.
- // |writes| the list of MockWrite completions.
- DeterministicSocketData(MockRead* reads,
- size_t reads_count,
- MockWrite* writes,
- size_t writes_count);
- ~DeterministicSocketData();
-
- // Consume all the data up to the give stop point (via SetStop()).
- void Run();
-
- // Set the stop point to be |steps| from now, and then invoke Run().
- void RunFor(int steps);
-
- // Stop at step |seq|, which must be in the future.
- void SetStop(int seq);
-
- // Stop |seq| steps after the current step.
- void StopAfter(int seq);
+ bool busy_before_sync_reads_;
- bool stopped() const { return stopped_; }
- void SetStopped(bool val) { stopped_ = val; }
- MockRead& current_read() { return current_read_; }
- MockWrite& current_write() { return current_write_; }
- int sequence_number() const { return sequence_number_; }
- void set_delegate(base::WeakPtr<Delegate> delegate) { delegate_ = delegate; }
- MockConnect connect_data() const { return connect_; }
- void set_connect_data(const MockConnect& connect) { connect_ = connect; }
-
- // When the socket calls Read(), that calls OnRead(), and expects either
- // ERR_IO_PENDING or data.
- MockRead OnRead();
-
- // When the socket calls Write(), it always completes synchronously. OnWrite()
- // checks to make sure the written data matches the expected data. The
- // callback will not be invoked until its sequence number is reached.
- MockWriteResult OnWrite(const std::string& data);
-
- bool AllReadDataConsumed() const;
- bool AllWriteDataConsumed() const;
+ // Used by RunUntilPaused. NULL at all other times.
+ scoped_ptr<base::RunLoop> run_until_paused_run_loop_;
- private:
- // Invoke the read and write callbacks, if the timing is appropriate.
- void InvokeCallbacks();
-
- void NextStep();
+ base::WeakPtrFactory<SequencedSocketData> weak_factory_;
- void VerifyCorrectSequenceNumbers(MockRead* reads,
- size_t reads_count,
- MockWrite* writes,
- size_t writes_count);
- StaticSocketDataHelper helper_;
- MockConnect connect_;
- int sequence_number_;
- MockRead current_read_;
- MockWrite current_write_;
- int stopping_sequence_number_;
- bool stopped_;
- base::WeakPtr<Delegate> delegate_;
- bool print_debug_;
- bool is_running_;
+ DISALLOW_COPY_AND_ASSIGN(SequencedSocketData);
};
// Holds an array of SocketDataProvider elements. As Mock{TCP,SSL}StreamSocket
@@ -612,9 +521,16 @@ class MockClientSocketFactory : public ClientSocketFactory {
const SSLClientSocketContext& context) override;
void ClearSSLSessionCache() override;
+ const std::vector<uint16_t>& udp_client_socket_ports() const {
+ return udp_client_socket_ports_;
+ }
+
private:
SocketDataProviderArray<SocketDataProvider> mock_data_;
SocketDataProviderArray<SSLSocketDataProvider> mock_ssl_data_;
+ std::vector<uint16_t> udp_client_socket_ports_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockClientSocketFactory);
};
class MockClientSocket : public SSLClientSocket {
@@ -633,8 +549,8 @@ class MockClientSocket : public SSLClientSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override = 0;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
// StreamSocket implementation.
int Connect(const CompletionCallback& callback) override = 0;
@@ -649,6 +565,7 @@ class MockClientSocket : public SSLClientSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// SSLClientSocket implementation.
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
@@ -716,6 +633,7 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket {
void OnReadComplete(const MockRead& data) override;
void OnWriteComplete(int rv) override;
void OnConnectComplete(const MockConnect& data) override;
+ void OnDataProviderDestroyed() override;
private:
int CompleteRead();
@@ -745,137 +663,6 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket {
DISALLOW_COPY_AND_ASSIGN(MockTCPClientSocket);
};
-// DeterministicSocketHelper is a helper class that can be used
-// to simulate Socket::Read() and Socket::Write()
-// using deterministic |data|.
-// Note: This is provided as a common helper class because
-// of the inheritance hierarchy of DeterministicMock[UDP,TCP]ClientSocket and a
-// desire not to introduce an additional common base class.
-class DeterministicSocketHelper {
- public:
- DeterministicSocketHelper(NetLog* net_log, DeterministicSocketData* data);
- virtual ~DeterministicSocketHelper();
-
- bool write_pending() const { return write_pending_; }
- bool read_pending() const { return read_pending_; }
-
- void CompleteWrite();
- int CompleteRead();
-
- int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
- int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
-
- const BoundNetLog& net_log() const { return net_log_; }
-
- bool was_used_to_convey_data() const { return was_used_to_convey_data_; }
-
- bool peer_closed_connection() const { return peer_closed_connection_; }
-
- DeterministicSocketData* data() const { return data_; }
-
- private:
- bool write_pending_;
- CompletionCallback write_callback_;
- int write_result_;
-
- MockRead read_data_;
-
- IOBuffer* read_buf_;
- int read_buf_len_;
- bool read_pending_;
- CompletionCallback read_callback_;
- DeterministicSocketData* data_;
- bool was_used_to_convey_data_;
- bool peer_closed_connection_;
- BoundNetLog net_log_;
-};
-
-// Mock UDP socket to be used in conjunction with DeterministicSocketData.
-class DeterministicMockUDPClientSocket
- : public DatagramClientSocket,
- public DeterministicSocketData::Delegate,
- public base::SupportsWeakPtr<DeterministicMockUDPClientSocket> {
- public:
- DeterministicMockUDPClientSocket(net::NetLog* net_log,
- DeterministicSocketData* data);
- ~DeterministicMockUDPClientSocket() override;
-
- // DeterministicSocketData::Delegate:
- bool WritePending() const override;
- bool ReadPending() const override;
- void CompleteWrite() override;
- int CompleteRead() override;
-
- // Socket implementation.
- int Read(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) override;
- int Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
-
- // DatagramSocket implementation.
- void Close() override;
- int GetPeerAddress(IPEndPoint* address) const override;
- int GetLocalAddress(IPEndPoint* address) const override;
- const BoundNetLog& NetLog() const override;
-
- // DatagramClientSocket implementation.
- int Connect(const IPEndPoint& address) override;
-
- void set_source_port(uint16 port) { source_port_ = port; }
-
- private:
- bool connected_;
- IPEndPoint peer_address_;
- DeterministicSocketHelper helper_;
- uint16 source_port_; // Ephemeral source port.
-
- DISALLOW_COPY_AND_ASSIGN(DeterministicMockUDPClientSocket);
-};
-
-// Mock TCP socket to be used in conjunction with DeterministicSocketData.
-class DeterministicMockTCPClientSocket
- : public MockClientSocket,
- public DeterministicSocketData::Delegate,
- public base::SupportsWeakPtr<DeterministicMockTCPClientSocket> {
- public:
- DeterministicMockTCPClientSocket(net::NetLog* net_log,
- DeterministicSocketData* data);
- ~DeterministicMockTCPClientSocket() override;
-
- // DeterministicSocketData::Delegate:
- bool WritePending() const override;
- bool ReadPending() const override;
- void CompleteWrite() override;
- int CompleteRead() override;
-
- // Socket:
- int Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) override;
- int Read(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) override;
-
- // StreamSocket:
- int Connect(const CompletionCallback& callback) override;
- void Disconnect() override;
- bool IsConnected() const override;
- bool IsConnectedAndIdle() const override;
- bool WasEverUsed() const override;
- bool UsingTCPFastOpen() const override;
- bool WasNpnNegotiated() const override;
- bool GetSSLInfo(SSLInfo* ssl_info) override;
-
- private:
- DeterministicSocketHelper helper_;
-
- DISALLOW_COPY_AND_ASSIGN(DeterministicMockTCPClientSocket);
-};
-
class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
public:
MockSSLClientSocket(scoped_ptr<ClientSocketHandle> transport_socket,
@@ -896,6 +683,7 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
int Connect(const CompletionCallback& callback) override;
void Disconnect() override;
bool IsConnected() const override;
+ bool IsConnectedAndIdle() const override;
bool WasEverUsed() const override;
bool UsingTCPFastOpen() const override;
int GetPeerAddress(IPEndPoint* address) const override;
@@ -909,6 +697,10 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
void OnReadComplete(const MockRead& data) override;
void OnWriteComplete(int rv) override;
void OnConnectComplete(const MockConnect& data) override;
+ // SSL sockets don't need magic to deal with destruction of their data
+ // provider.
+ // TODO(mmenke): Probably a good idea to support it, anyways.
+ void OnDataProviderDestroyed() override {}
ChannelIDService* GetChannelIDService() const override;
@@ -935,8 +727,8 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
// DatagramSocket implementation.
void Close() override;
@@ -945,14 +737,19 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
const BoundNetLog& NetLog() const override;
// DatagramClientSocket implementation.
+ int BindToNetwork(NetworkChangeNotifier::NetworkHandle network) override;
+ int BindToDefaultNetwork() override;
+ NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override;
int Connect(const IPEndPoint& address) override;
// AsyncSocket implementation.
void OnReadComplete(const MockRead& data) override;
void OnWriteComplete(int rv) override;
void OnConnectComplete(const MockConnect& data) override;
+ void OnDataProviderDestroyed() override;
- void set_source_port(uint16 port) { source_port_ = port;}
+ void set_source_port(uint16_t port) { source_port_ = port; }
+ uint16_t source_port() const { return source_port_; }
private:
int CompleteRead();
@@ -965,11 +762,14 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
int read_offset_;
MockRead read_data_;
bool need_read_data_;
- uint16 source_port_; // Ephemeral source port.
+ uint16_t source_port_; // Ephemeral source port.
// Address of the "remote" peer we're connected to.
IPEndPoint peer_addr_;
+ // Network that the socket is bound to.
+ NetworkChangeNotifier::NetworkHandle network_;
+
// While an asynchronous IO is pending, we save our user-buffer state.
scoped_refptr<IOBuffer> pending_read_buf_;
int pending_read_buf_len_;
@@ -1026,9 +826,9 @@ class ClientSocketPoolTest {
RequestPriority priority,
const scoped_refptr<typename PoolType::SocketParams>& socket_params) {
DCHECK(socket_pool);
- TestSocketRequest* request =
- new TestSocketRequest(&request_order_, &completion_count_);
- requests_.push_back(request);
+ TestSocketRequest* request(
+ new TestSocketRequest(&request_order_, &completion_count_));
+ requests_.push_back(make_scoped_ptr(request));
int rv = request->handle()->Init(group_name,
socket_params,
priority,
@@ -1055,14 +855,14 @@ class ClientSocketPoolTest {
// Note that this uses 0-based indices, while GetOrderOfRequest takes and
// returns 0-based indices.
- TestSocketRequest* request(int i) { return requests_[i]; }
+ TestSocketRequest* request(int i) { return requests_[i].get(); }
size_t requests_size() const { return requests_.size(); }
- ScopedVector<TestSocketRequest>* requests() { return &requests_; }
+ std::vector<scoped_ptr<TestSocketRequest>>* requests() { return &requests_; }
size_t completion_count() const { return completion_count_; }
private:
- ScopedVector<TestSocketRequest> requests_;
+ std::vector<scoped_ptr<TestSocketRequest>> requests_;
std::vector<TestSocketRequest*> request_order_;
size_t completion_count_;
@@ -1130,7 +930,7 @@ class MockTransportClientSocketPool : public TransportClientSocketPool {
private:
ClientSocketFactory* client_socket_factory_;
- ScopedVector<MockConnectJob> job_list_;
+ std::vector<scoped_ptr<MockConnectJob>> job_list_;
RequestPriority last_request_priority_;
int release_count_;
int cancel_count_;
@@ -1138,58 +938,6 @@ class MockTransportClientSocketPool : public TransportClientSocketPool {
DISALLOW_COPY_AND_ASSIGN(MockTransportClientSocketPool);
};
-class DeterministicMockClientSocketFactory : public ClientSocketFactory {
- public:
- DeterministicMockClientSocketFactory();
- ~DeterministicMockClientSocketFactory() override;
-
- void AddSocketDataProvider(DeterministicSocketData* socket);
- void AddSSLSocketDataProvider(SSLSocketDataProvider* socket);
- void ResetNextMockIndexes();
-
- // Return |index|-th MockSSLClientSocket (starting from 0) that the factory
- // created.
- MockSSLClientSocket* GetMockSSLClientSocket(size_t index) const;
-
- SocketDataProviderArray<DeterministicSocketData>& mock_data() {
- return mock_data_;
- }
- std::vector<DeterministicMockTCPClientSocket*>& tcp_client_sockets() {
- return tcp_client_sockets_;
- }
- std::vector<DeterministicMockUDPClientSocket*>& udp_client_sockets() {
- return udp_client_sockets_;
- }
-
- // ClientSocketFactory
- scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
- DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
- NetLog* net_log,
- const NetLog::Source& source) override;
- scoped_ptr<StreamSocket> CreateTransportClientSocket(
- const AddressList& addresses,
- NetLog* net_log,
- const NetLog::Source& source) override;
- scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
- scoped_ptr<ClientSocketHandle> transport_socket,
- const HostPortPair& host_and_port,
- const SSLConfig& ssl_config,
- const SSLClientSocketContext& context) override;
- void ClearSSLSessionCache() override;
-
- private:
- SocketDataProviderArray<DeterministicSocketData> mock_data_;
- SocketDataProviderArray<SSLSocketDataProvider> mock_ssl_data_;
-
- // Store pointers to handed out sockets in case the test wants to get them.
- std::vector<DeterministicMockTCPClientSocket*> tcp_client_sockets_;
- std::vector<DeterministicMockUDPClientSocket*> udp_client_sockets_;
- std::vector<MockSSLClientSocket*> ssl_client_sockets_;
-
- DISALLOW_COPY_AND_ASSIGN(DeterministicMockClientSocketFactory);
-};
-
class MockSOCKSClientSocketPool : public SOCKSClientSocketPool {
public:
MockSOCKSClientSocketPool(int max_sockets,
diff --git a/chromium/net/socket/socks5_client_socket.cc b/chromium/net/socket/socks5_client_socket.cc
index 4ac9ca59656..20baaf2cbe4 100644
--- a/chromium/net/socket/socks5_client_socket.cc
+++ b/chromium/net/socket/socks5_client_socket.cc
@@ -4,7 +4,8 @@
#include "net/socket/socks5_client_socket.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
#include "base/format_macros.h"
@@ -21,9 +22,9 @@ namespace net {
const unsigned int SOCKS5ClientSocket::kGreetReadHeaderSize = 2;
const unsigned int SOCKS5ClientSocket::kWriteHeaderSize = 10;
const unsigned int SOCKS5ClientSocket::kReadHeaderSize = 5;
-const uint8 SOCKS5ClientSocket::kSOCKS5Version = 0x05;
-const uint8 SOCKS5ClientSocket::kTunnelCommand = 0x01;
-const uint8 SOCKS5ClientSocket::kNullByte = 0x00;
+const uint8_t SOCKS5ClientSocket::kSOCKS5Version = 0x05;
+const uint8_t SOCKS5ClientSocket::kTunnelCommand = 0x01;
+const uint8_t SOCKS5ClientSocket::kNullByte = 0x00;
static_assert(sizeof(struct in_addr) == 4, "incorrect system size of IPv4");
static_assert(sizeof(struct in6_addr) == 16, "incorrect system size of IPv6");
@@ -33,7 +34,7 @@ SOCKS5ClientSocket::SOCKS5ClientSocket(
const HostResolver::RequestInfo& req_info)
: io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete,
base::Unretained(this))),
- transport_(transport_socket.Pass()),
+ transport_(std::move(transport_socket)),
next_state_(STATE_NONE),
completed_handshake_(false),
bytes_sent_(0),
@@ -41,8 +42,7 @@ SOCKS5ClientSocket::SOCKS5ClientSocket(
read_header_size(kReadHeaderSize),
was_ever_used_(false),
host_request_info_(req_info),
- net_log_(transport_->socket()->NetLog()) {
-}
+ net_log_(transport_->socket()->NetLog()) {}
SOCKS5ClientSocket::~SOCKS5ClientSocket() {
Disconnect();
@@ -150,6 +150,10 @@ void SOCKS5ClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
out->clear();
}
+int64_t SOCKS5ClientSocket::GetTotalReceivedBytes() const {
+ return transport_->socket()->GetTotalReceivedBytes();
+}
+
// Read is called by the transport layer above to read. This can only be done
// if the SOCKS handshake is complete.
int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len,
@@ -186,11 +190,11 @@ int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len,
return rv;
}
-int SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) {
+int SOCKS5ClientSocket::SetReceiveBufferSize(int32_t size) {
return transport_->socket()->SetReceiveBufferSize(size);
}
-int SOCKS5ClientSocket::SetSendBufferSize(int32 size) {
+int SOCKS5ClientSocket::SetSendBufferSize(int32_t size) {
return transport_->socket()->SetSendBufferSize(size);
}
@@ -343,12 +347,12 @@ int SOCKS5ClientSocket::DoGreetReadComplete(int result) {
// Got the greet data.
if (buffer_[0] != kSOCKS5Version) {
net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTED_VERSION,
- NetLog::IntegerCallback("version", buffer_[0]));
+ NetLog::IntCallback("version", buffer_[0]));
return ERR_SOCKS_CONNECTION_FAILED;
}
if (buffer_[1] != 0x00) {
net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTED_AUTH,
- NetLog::IntegerCallback("method", buffer_[1]));
+ NetLog::IntCallback("method", buffer_[1]));
return ERR_SOCKS_CONNECTION_FAILED;
}
@@ -374,7 +378,7 @@ int SOCKS5ClientSocket::BuildHandshakeWriteBuffer(std::string* handshake)
host_request_info_.hostname().size()));
handshake->append(host_request_info_.hostname());
- uint16 nw_port = base::HostToNet16(host_request_info_.port());
+ uint16_t nw_port = base::HostToNet16(host_request_info_.port());
handshake->append(reinterpret_cast<char*>(&nw_port), sizeof(nw_port));
return OK;
}
@@ -451,12 +455,12 @@ int SOCKS5ClientSocket::DoHandshakeReadComplete(int result) {
if (bytes_received_ == kReadHeaderSize) {
if (buffer_[0] != kSOCKS5Version || buffer_[2] != kNullByte) {
net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTED_VERSION,
- NetLog::IntegerCallback("version", buffer_[0]));
+ NetLog::IntCallback("version", buffer_[0]));
return ERR_SOCKS_CONNECTION_FAILED;
}
if (buffer_[1] != 0x00) {
net_log_.AddEvent(NetLog::TYPE_SOCKS_SERVER_ERROR,
- NetLog::IntegerCallback("error_code", buffer_[1]));
+ NetLog::IntCallback("error_code", buffer_[1]));
return ERR_SOCKS_CONNECTION_FAILED;
}
@@ -468,14 +472,14 @@ int SOCKS5ClientSocket::DoHandshakeReadComplete(int result) {
SocksEndPointAddressType address_type =
static_cast<SocksEndPointAddressType>(buffer_[3]);
if (address_type == kEndPointDomain)
- read_header_size += static_cast<uint8>(buffer_[4]);
+ read_header_size += static_cast<uint8_t>(buffer_[4]);
else if (address_type == kEndPointResolvedIPv4)
read_header_size += sizeof(struct in_addr) - 1;
else if (address_type == kEndPointResolvedIPv6)
read_header_size += sizeof(struct in6_addr) - 1;
else {
net_log_.AddEvent(NetLog::TYPE_SOCKS_UNKNOWN_ADDRESS_TYPE,
- NetLog::IntegerCallback("address_type", buffer_[3]));
+ NetLog::IntCallback("address_type", buffer_[3]));
return ERR_SOCKS_CONNECTION_FAILED;
}
diff --git a/chromium/net/socket/socks5_client_socket.h b/chromium/net/socket/socks5_client_socket.h
index bd9b5b48703..a5438b643ad 100644
--- a/chromium/net/socket/socks5_client_socket.h
+++ b/chromium/net/socket/socks5_client_socket.h
@@ -5,9 +5,12 @@
#ifndef NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_
#define NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
@@ -57,6 +60,7 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -66,8 +70,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket {
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
@@ -95,9 +99,9 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket {
static const unsigned int kGreetReadHeaderSize;
static const unsigned int kWriteHeaderSize;
static const unsigned int kReadHeaderSize;
- static const uint8 kSOCKS5Version;
- static const uint8 kTunnelCommand;
- static const uint8 kNullByte;
+ static const uint8_t kSOCKS5Version;
+ static const uint8_t kTunnelCommand;
+ static const uint8_t kNullByte;
void DoCallback(int result);
void OnIOComplete(int result);
diff --git a/chromium/net/socket/socks5_client_socket_unittest.cc b/chromium/net/socket/socks5_client_socket_unittest.cc
index 76146c7ab83..c41c6b94ada 100644
--- a/chromium/net/socket/socks5_client_socket_unittest.cc
+++ b/chromium/net/socket/socks5_client_socket_unittest.cc
@@ -7,7 +7,9 @@
#include <algorithm>
#include <iterator>
#include <map>
+#include <utility>
+#include "base/macros.h"
#include "base/sys_byteorder.h"
#include "net/base/address_list.h"
#include "net/base/test_completion_callback.h"
@@ -45,7 +47,7 @@ class SOCKS5ClientSocketTest : public PlatformTest {
void SetUp() override;
protected:
- const uint16 kNwPort;
+ const uint16_t kNwPort;
TestNetLog net_log_;
scoped_ptr<SOCKS5ClientSocket> user_sock_;
AddressList address_list_;
@@ -107,7 +109,7 @@ scoped_ptr<SOCKS5ClientSocket> SOCKS5ClientSocketTest::BuildMockSocket(
// non-owning pointer to it.
connection->SetSocket(scoped_ptr<StreamSocket>(tcp_sock_));
return scoped_ptr<SOCKS5ClientSocket>(new SOCKS5ClientSocket(
- connection.Pass(),
+ std::move(connection),
HostResolver::RequestInfo(HostPortPair(hostname, port))));
}
@@ -194,7 +196,7 @@ TEST_F(SOCKS5ClientSocketTest, ConnectAndDisconnectTwice) {
};
std::string request(kSOCKS5DomainRequest, arraysize(kSOCKS5DomainRequest));
- request.push_back(hostname.size());
+ request.push_back(static_cast<char>(hostname.size()));
request.append(hostname);
request.append(reinterpret_cast<const char*>(&kNwPort), sizeof(kNwPort));
diff --git a/chromium/net/socket/socks_client_socket.cc b/chromium/net/socket/socks_client_socket.cc
index dbdc0251768..69805bb6f3a 100644
--- a/chromium/net/socket/socks_client_socket.cc
+++ b/chromium/net/socket/socks_client_socket.cc
@@ -4,7 +4,8 @@
#include "net/socket/socks_client_socket.h"
-#include "base/basictypes.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
@@ -27,31 +28,31 @@ static const unsigned int kWriteHeaderSize = 8;
static const unsigned int kReadHeaderSize = 8;
// Server Response codes for SOCKS.
-static const uint8 kServerResponseOk = 0x5A;
-static const uint8 kServerResponseRejected = 0x5B;
-static const uint8 kServerResponseNotReachable = 0x5C;
-static const uint8 kServerResponseMismatchedUserId = 0x5D;
+static const uint8_t kServerResponseOk = 0x5A;
+static const uint8_t kServerResponseRejected = 0x5B;
+static const uint8_t kServerResponseNotReachable = 0x5C;
+static const uint8_t kServerResponseMismatchedUserId = 0x5D;
-static const uint8 kSOCKSVersion4 = 0x04;
-static const uint8 kSOCKSStreamRequest = 0x01;
+static const uint8_t kSOCKSVersion4 = 0x04;
+static const uint8_t kSOCKSStreamRequest = 0x01;
// A struct holding the essential details of the SOCKS4 Server Request.
// The port in the header is stored in network byte order.
struct SOCKS4ServerRequest {
- uint8 version;
- uint8 command;
- uint16 nw_port;
- uint8 ip[4];
+ uint8_t version;
+ uint8_t command;
+ uint16_t nw_port;
+ uint8_t ip[4];
};
static_assert(sizeof(SOCKS4ServerRequest) == kWriteHeaderSize,
"socks4 server request struct has incorrect size");
// A struct holding details of the SOCKS4 Server Response.
struct SOCKS4ServerResponse {
- uint8 reserved_null;
- uint8 code;
- uint16 port;
- uint8 ip[4];
+ uint8_t reserved_null;
+ uint8_t code;
+ uint16_t port;
+ uint8_t ip[4];
};
static_assert(sizeof(SOCKS4ServerResponse) == kReadHeaderSize,
"socks4 server response struct has incorrect size");
@@ -61,7 +62,7 @@ SOCKSClientSocket::SOCKSClientSocket(
const HostResolver::RequestInfo& req_info,
RequestPriority priority,
HostResolver* host_resolver)
- : transport_(transport_socket.Pass()),
+ : transport_(std::move(transport_socket)),
next_state_(STATE_NONE),
completed_handshake_(false),
bytes_sent_(0),
@@ -178,6 +179,10 @@ void SOCKSClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
out->clear();
}
+int64_t SOCKSClientSocket::GetTotalReceivedBytes() const {
+ return transport_->socket()->GetTotalReceivedBytes();
+}
+
// Read is called by the transport layer above to read. This can only be done
// if the SOCKS handshake is complete.
int SOCKSClientSocket::Read(IOBuffer* buf, int buf_len,
@@ -214,11 +219,11 @@ int SOCKSClientSocket::Write(IOBuffer* buf, int buf_len,
return rv;
}
-int SOCKSClientSocket::SetReceiveBufferSize(int32 size) {
+int SOCKSClientSocket::SetReceiveBufferSize(int32_t size) {
return transport_->socket()->SetReceiveBufferSize(size);
}
-int SOCKSClientSocket::SetSendBufferSize(int32 size) {
+int SOCKSClientSocket::SetSendBufferSize(int32_t size) {
return transport_->socket()->SetSendBufferSize(size);
}
diff --git a/chromium/net/socket/socks_client_socket.h b/chromium/net/socket/socks_client_socket.h
index ee2918a6094..8d5accd4200 100644
--- a/chromium/net/socket/socks_client_socket.h
+++ b/chromium/net/socket/socks_client_socket.h
@@ -5,10 +5,13 @@
#ifndef NET_SOCKET_SOCKS_CLIENT_SOCKET_H_
#define NET_SOCKET_SOCKS_CLIENT_SOCKET_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
@@ -55,6 +58,7 @@ class NET_EXPORT_PRIVATE SOCKSClientSocket : public StreamSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -64,8 +68,8 @@ class NET_EXPORT_PRIVATE SOCKSClientSocket : public StreamSocket {
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
diff --git a/chromium/net/socket/socks_client_socket_pool.cc b/chromium/net/socket/socks_client_socket_pool.cc
index dda4aec060f..543c2c4ad72 100644
--- a/chromium/net/socket/socks_client_socket_pool.cc
+++ b/chromium/net/socket/socks_client_socket_pool.cc
@@ -4,6 +4,8 @@
#include "net/socket/socks_client_socket_pool.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/time/time.h"
@@ -141,13 +143,12 @@ int SOCKSConnectJob::DoSOCKSConnect() {
// Add a SOCKS connection on top of the tcp socket.
if (socks_params_->is_socks_v5()) {
- socket_.reset(new SOCKS5ClientSocket(transport_socket_handle_.Pass(),
+ socket_.reset(new SOCKS5ClientSocket(std::move(transport_socket_handle_),
socks_params_->destination()));
} else {
- socket_.reset(new SOCKSClientSocket(transport_socket_handle_.Pass(),
+ socket_.reset(new SOCKSClientSocket(std::move(transport_socket_handle_),
socks_params_->destination(),
- priority(),
- resolver_));
+ priority(), resolver_));
}
return socket_->Connect(
base::Bind(&SOCKSConnectJob::OnIOComplete, base::Unretained(this)));
@@ -159,7 +160,7 @@ int SOCKSConnectJob::DoSOCKSConnectComplete(int result) {
return result;
}
- SetSocket(socket_.Pass());
+ SetSocket(std::move(socket_));
return result;
}
@@ -241,7 +242,7 @@ void SOCKSClientSocketPool::CancelRequest(const std::string& group_name,
void SOCKSClientSocketPool::ReleaseSocket(const std::string& group_name,
scoped_ptr<StreamSocket> socket,
int id) {
- base_.ReleaseSocket(group_name, socket.Pass(), id);
+ base_.ReleaseSocket(group_name, std::move(socket), id);
}
void SOCKSClientSocketPool::FlushWithError(int error) {
@@ -276,9 +277,9 @@ scoped_ptr<base::DictionaryValue> SOCKSClientSocketPool::GetInfoAsValue(
list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool",
"transport_socket_pool",
false));
- dict->Set("nested_pools", list.Pass());
+ dict->Set("nested_pools", std::move(list));
}
- return dict.Pass();
+ return dict;
}
base::TimeDelta SOCKSClientSocketPool::ConnectionTimeout() const {
diff --git a/chromium/net/socket/socks_client_socket_pool.h b/chromium/net/socket/socks_client_socket_pool.h
index 77dbb4988a8..8aaf726c353 100644
--- a/chromium/net/socket/socks_client_socket_pool.h
+++ b/chromium/net/socket/socks_client_socket_pool.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
diff --git a/chromium/net/socket/socks_client_socket_pool_unittest.cc b/chromium/net/socket/socks_client_socket_pool_unittest.cc
index e841c83635d..587f1fa5fa5 100644
--- a/chromium/net/socket/socks_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/socks_client_socket_pool_unittest.cc
@@ -109,7 +109,9 @@ class SOCKSClientSocketPoolTest : public testing::Test {
return test_base_.GetOrderOfRequest(index);
}
- ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
+ std::vector<scoped_ptr<TestSocketRequest>>* requests() {
+ return test_base_.requests();
+ }
MockClientSocketFactory transport_client_socket_factory_;
MockTransportClientSocketPool transport_socket_pool_;
diff --git a/chromium/net/socket/socks_client_socket_unittest.cc b/chromium/net/socket/socks_client_socket_unittest.cc
index 27b4c70aa95..bff76c109c6 100644
--- a/chromium/net/socket/socks_client_socket_unittest.cc
+++ b/chromium/net/socket/socks_client_socket_unittest.cc
@@ -4,6 +4,9 @@
#include "net/socket/socks_client_socket.h"
+#include <utility>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
#include "net/base/test_completion_callback.h"
@@ -85,9 +88,8 @@ scoped_ptr<SOCKSClientSocket> SOCKSClientSocketTest::BuildMockSocket(
// non-owning pointer to it.
connection->SetSocket(scoped_ptr<StreamSocket>(tcp_sock_));
return scoped_ptr<SOCKSClientSocket>(new SOCKSClientSocket(
- connection.Pass(),
- HostResolver::RequestInfo(HostPortPair(hostname, port)),
- DEFAULT_PRIORITY,
+ std::move(connection),
+ HostResolver::RequestInfo(HostPortPair(hostname, port)), DEFAULT_PRIORITY,
host_resolver));
}
diff --git a/chromium/net/socket/ssl_client_socket.cc b/chromium/net/socket/ssl_client_socket.cc
index 3472fd023f2..a7c0dd420ad 100644
--- a/chromium/net/socket/ssl_client_socket.cc
+++ b/chromium/net/socket/ssl_client_socket.cc
@@ -15,6 +15,10 @@
#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_connection_status_flags.h"
+#if defined(USE_OPENSSL)
+#include "net/socket/ssl_client_socket_openssl.h"
+#endif
+
namespace net {
SSLClientSocket::SSLClientSocket()
@@ -28,10 +32,6 @@ NextProto SSLClientSocket::NextProtoFromString(
const std::string& proto_string) {
if (proto_string == "http1.1" || proto_string == "http/1.1") {
return kProtoHTTP11;
- } else if (proto_string == "spdy/2") {
- return kProtoDeprecatedSPDY2;
- } else if (proto_string == "spdy/3") {
- return kProtoSPDY3;
} else if (proto_string == "spdy/3.1") {
return kProtoSPDY31;
} else if (proto_string == "h2") {
@@ -48,10 +48,6 @@ const char* SSLClientSocket::NextProtoToString(NextProto next_proto) {
switch (next_proto) {
case kProtoHTTP11:
return "http/1.1";
- case kProtoDeprecatedSPDY2:
- return "spdy/2";
- case kProtoSPDY3:
- return "spdy/3";
case kProtoSPDY31:
return "spdy/3.1";
case kProtoHTTP2:
@@ -78,6 +74,17 @@ const char* SSLClientSocket::NextProtoStatusToString(
return NULL;
}
+// static
+void SSLClientSocket::SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
+#if defined(USE_OPENSSL) && !defined(OS_NACL)
+ SSLClientSocketOpenSSL::SetSSLKeyLogFile(path, task_runner);
+#else
+ NOTIMPLEMENTED();
+#endif
+}
+
bool SSLClientSocket::WasNpnNegotiated() const {
std::string unused_proto;
return GetNextProto(&unused_proto) == kNextProtoNegotiated;
@@ -127,14 +134,13 @@ void SSLClientSocket::RecordNegotiationExtension() {
void SSLClientSocket::RecordChannelIDSupport(
ChannelIDService* channel_id_service,
bool negotiated_channel_id,
- bool channel_id_enabled,
- bool supports_ecc) {
+ bool channel_id_enabled) {
// Since this enum is used for a histogram, do not change or re-use values.
enum {
DISABLED = 0,
CLIENT_ONLY = 1,
CLIENT_AND_SERVER = 2,
- CLIENT_NO_ECC = 3,
+ // CLIENT_NO_ECC is unused now.
// CLIENT_BAD_SYSTEM_TIME is unused now.
CLIENT_BAD_SYSTEM_TIME = 4,
CLIENT_NO_CHANNEL_ID_SERVICE = 5,
@@ -145,8 +151,6 @@ void SSLClientSocket::RecordChannelIDSupport(
} else if (channel_id_enabled) {
if (!channel_id_service)
supported = CLIENT_NO_CHANNEL_ID_SERVICE;
- else if (!supports_ecc)
- supported = CLIENT_NO_ECC;
else
supported = CLIENT_ONLY;
}
@@ -164,18 +168,14 @@ bool SSLClientSocket::IsChannelIDEnabled(
DVLOG(1) << "NULL channel_id_service_, not enabling channel ID.";
return false;
}
- if (!crypto::ECPrivateKey::IsSupported()) {
- DVLOG(1) << "Elliptic Curve not supported, not enabling channel ID.";
- return false;
- }
return true;
}
// static
bool SSLClientSocket::HasCipherAdequateForHTTP2(
- const std::vector<uint16>& cipher_suites) {
- for (uint16 cipher : cipher_suites) {
- if (IsSecureTLSCipherSuite(cipher))
+ const std::vector<uint16_t>& cipher_suites) {
+ for (uint16_t cipher : cipher_suites) {
+ if (IsTLSCipherSuiteAllowedByHTTP2(cipher))
return true;
}
return false;
diff --git a/chromium/net/socket/ssl_client_socket.h b/chromium/net/socket/ssl_client_socket.h
index 1d38048d0c6..3a6aa94258f 100644
--- a/chromium/net/socket/ssl_client_socket.h
+++ b/chromium/net/socket/ssl_client_socket.h
@@ -5,6 +5,8 @@
#ifndef NET_SOCKET_SSL_CLIENT_SOCKET_H_
#define NET_SOCKET_SSL_CLIENT_SOCKET_H_
+#include <stdint.h>
+
#include <string>
#include "base/gtest_prod_util.h"
@@ -15,9 +17,14 @@
#include "net/socket/stream_socket.h"
#include "net/ssl/ssl_failure_state.h"
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
namespace net {
-class CertPolicyEnforcer;
+class CTPolicyEnforcer;
class CertVerifier;
class ChannelIDService;
class CTVerifier;
@@ -35,26 +42,26 @@ struct SSLClientSocketContext {
channel_id_service(NULL),
transport_security_state(NULL),
cert_transparency_verifier(NULL),
- cert_policy_enforcer(NULL) {}
+ ct_policy_enforcer(NULL) {}
SSLClientSocketContext(CertVerifier* cert_verifier_arg,
ChannelIDService* channel_id_service_arg,
TransportSecurityState* transport_security_state_arg,
CTVerifier* cert_transparency_verifier_arg,
- CertPolicyEnforcer* cert_policy_enforcer_arg,
+ CTPolicyEnforcer* ct_policy_enforcer_arg,
const std::string& ssl_session_cache_shard_arg)
: cert_verifier(cert_verifier_arg),
channel_id_service(channel_id_service_arg),
transport_security_state(transport_security_state_arg),
cert_transparency_verifier(cert_transparency_verifier_arg),
- cert_policy_enforcer(cert_policy_enforcer_arg),
+ ct_policy_enforcer(ct_policy_enforcer_arg),
ssl_session_cache_shard(ssl_session_cache_shard_arg) {}
CertVerifier* cert_verifier;
ChannelIDService* channel_id_service;
TransportSecurityState* transport_security_state;
CTVerifier* cert_transparency_verifier;
- CertPolicyEnforcer* cert_policy_enforcer;
+ CTPolicyEnforcer* ct_policy_enforcer;
// ssl_session_cache_shard is an opaque string that identifies a shard of the
// SSL session cache. SSL sockets with the same ssl_session_cache_shard may
// resume each other's SSL sessions but we'll never sessions between shards.
@@ -114,6 +121,17 @@ class NET_EXPORT SSLClientSocket : public SSLSocket {
static const char* NextProtoStatusToString(const NextProtoStatus status);
+ // Log SSL key material to |path| on |task_runner|. Must be called before any
+ // SSLClientSockets are created.
+ //
+ // TODO(davidben): Switch this to a parameter on the SSLClientSocketContext
+ // once https://crbug.com/458365 is resolved. This will require splitting
+ // SSLKeyLogger into an interface, built with OS_NACL and a non-NaCl
+ // SSLKeyLoggerImpl.
+ static void SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner);
+
// Returns true if |error| is OK or |load_flags| ignores certificate errors
// and |error| is a certificate error.
static bool IgnoreCertError(int error, int load_flags);
@@ -152,11 +170,9 @@ class NET_EXPORT SSLClientSocket : public SSLSocket {
// Records histograms for channel id support during full handshakes - resumed
// handshakes are ignored.
- static void RecordChannelIDSupport(
- ChannelIDService* channel_id_service,
- bool negotiated_channel_id,
- bool channel_id_enabled,
- bool supports_ecc);
+ static void RecordChannelIDSupport(ChannelIDService* channel_id_service,
+ bool negotiated_channel_id,
+ bool channel_id_enabled);
// Returns whether TLS channel ID is enabled.
static bool IsChannelIDEnabled(
@@ -167,7 +183,7 @@ class NET_EXPORT SSLClientSocket : public SSLSocket {
// Section 9.2 of the HTTP/2 specification. Note that the server might still
// pick an inadequate cipher suite.
static bool HasCipherAdequateForHTTP2(
- const std::vector<uint16>& cipher_suites);
+ const std::vector<uint16_t>& cipher_suites);
// Determine if the TLS version required by Section 9.2 of the HTTP/2
// specification is enabled. Note that the server might still pick an
diff --git a/chromium/net/socket/ssl_client_socket_nss.cc b/chromium/net/socket/ssl_client_socket_nss.cc
index ecff0e5a6bf..b15d76174aa 100644
--- a/chromium/net/socket/ssl_client_socket_nss.cc
+++ b/chromium/net/socket/ssl_client_socket_nss.cc
@@ -63,6 +63,7 @@
#include <algorithm>
#include <limits>
#include <map>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -70,6 +71,7 @@
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -85,15 +87,14 @@
#include "crypto/rsa_private_key.h"
#include "crypto/scoped_nss_types.h"
#include "net/base/address_list.h"
-#include "net/base/dns_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
+#include "net/base/sockaddr_storage.h"
#include "net/cert/asn1_util.h"
-#include "net/cert/cert_policy_enforcer.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_ev_whitelist.h"
+#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_verifier.h"
#include "net/cert/ct_verify_result.h"
#include "net/cert/scoped_nss_types.h"
@@ -101,6 +102,7 @@
#include "net/cert/x509_certificate_net_log_param.h"
#include "net/cert/x509_util.h"
#include "net/cert_net/nss_ocsp.h"
+#include "net/dns/dns_util.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
#include "net/socket/client_socket_handle.h"
@@ -648,10 +650,8 @@ class SSLClientSocketNSS::Core : public base::RefCountedThreadSafe<Core> {
void OnNSSBufferUpdated(int amount_in_read_buffer);
void DidNSSRead(int result);
void DidNSSWrite(int result);
- void RecordChannelIDSupportOnNetworkTaskRunner(
- bool negotiated_channel_id,
- bool channel_id_enabled,
- bool supports_ecc) const;
+ void RecordChannelIDSupportOnNetworkTaskRunner(bool negotiated_channel_id,
+ bool channel_id_enabled) const;
////////////////////////////////////////////////////////////////////////////
// Methods that are called on both the network task runner and the NSS
@@ -843,12 +843,18 @@ bool SSLClientSocketNSS::Core::Init(PRFileDesc* socket,
SECStatus rv = SECSuccess;
- if (!ssl_config_.next_protos.empty()) {
- NextProtoVector next_protos = ssl_config_.next_protos;
+ if (!ssl_config_.alpn_protos.empty()) {
+ NextProtoVector alpn_protos = ssl_config_.alpn_protos;
// TODO(bnc): Check ssl_config_.disabled_cipher_suites.
if (!IsTLSVersionAdequateForHTTP2(ssl_config_))
- DisableHTTP2(&next_protos);
- std::vector<uint8_t> wire_protos = SerializeNextProtos(next_protos);
+ DisableHTTP2(&alpn_protos);
+ // |ssl_config_| has fallback protocol at the end of the list, but NSS
+ // expects fallback at the first place, thus protocols need to be reordered.
+ ReorderNextProtos(&alpn_protos);
+ // NSS only supports a single protocol vector to be used with ALPN and NPN.
+ // Because of this limitation, |alpn_prototos| will be used for both.
+ // However, it is possible to enable ALPN and NPN separately.
+ std::vector<uint8_t> wire_protos = SerializeNextProtos(alpn_protos);
rv = SSL_SetNextProtoNego(
nss_fd_, wire_protos.empty() ? NULL : &wire_protos[0],
wire_protos.size());
@@ -857,9 +863,11 @@ bool SSLClientSocketNSS::Core::Init(PRFileDesc* socket,
rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_ALPN, PR_TRUE);
if (rv != SECSuccess)
LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_ALPN");
- rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_NPN, PR_TRUE);
- if (rv != SECSuccess)
- LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_NPN");
+ if (!ssl_config_.npn_protos.empty()) {
+ rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_NPN, PR_TRUE);
+ if (rv != SECSuccess)
+ LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_NPN");
+ }
}
rv = SSL_AuthCertificateHook(
@@ -1259,7 +1267,7 @@ SECStatus SSLClientSocketNSS::Core::CanFalseStartCallback(
SSL_GetChannelInfo(socket, &channel_info, sizeof(channel_info));
if (ok != SECSuccess || channel_info.length != sizeof(channel_info) ||
channel_info.protocolVersion < SSL_LIBRARY_VERSION_TLS_1_2 ||
- !IsFalseStartableTLSCipherSuite(channel_info.cipherSuite)) {
+ !IsSecureTLSCipherSuite(channel_info.cipherSuite)) {
*can_false_start = PR_FALSE;
return SECSuccess;
}
@@ -2060,7 +2068,7 @@ void SSLClientSocketNSS::Core::UpdateConnectionStatus() {
}
void SSLClientSocketNSS::Core::UpdateNextProto() {
- uint8 buf[256];
+ uint8_t buf[256];
SSLNextProtoState state;
unsigned buf_len;
@@ -2128,23 +2136,17 @@ void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNSSTaskRunner() {
// network task runner state.
PostOrRunCallback(
FROM_HERE,
- base::Bind(&Core::RecordChannelIDSupportOnNetworkTaskRunner,
- this,
- channel_id_xtn_negotiated_,
- ssl_config_.channel_id_enabled,
- crypto::ECPrivateKey::IsSupported()));
+ base::Bind(&Core::RecordChannelIDSupportOnNetworkTaskRunner, this,
+ channel_id_xtn_negotiated_, ssl_config_.channel_id_enabled));
}
void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNetworkTaskRunner(
bool negotiated_channel_id,
- bool channel_id_enabled,
- bool supports_ecc) const {
+ bool channel_id_enabled) const {
DCHECK(OnNetworkTaskRunner());
- RecordChannelIDSupport(channel_id_service_,
- negotiated_channel_id,
- channel_id_enabled,
- supports_ecc);
+ RecordChannelIDSupport(channel_id_service_, negotiated_channel_id,
+ channel_id_enabled);
}
int SSLClientSocketNSS::Core::DoBufferRecv(IOBuffer* read_buffer, int len) {
@@ -2335,11 +2337,10 @@ void SSLClientSocketNSS::Core::PostOrRunCallback(
}
void SSLClientSocketNSS::Core::AddCertProvidedEvent(int cert_count) {
- PostOrRunCallback(
- FROM_HERE,
- base::Bind(&AddLogEventWithCallback, weak_net_log_,
- NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED,
- NetLog::IntegerCallback("cert_count", cert_count)));
+ PostOrRunCallback(FROM_HERE,
+ base::Bind(&AddLogEventWithCallback, weak_net_log_,
+ NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED,
+ NetLog::IntCallback("cert_count", cert_count)));
}
void SSLClientSocketNSS::Core::SetChannelIDProvided() {
@@ -2359,7 +2360,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(
const HostPortPair& host_and_port,
const SSLConfig& ssl_config,
const SSLClientSocketContext& context)
- : transport_(transport_socket.Pass()),
+ : transport_(std::move(transport_socket)),
host_and_port_(host_and_port),
ssl_config_(ssl_config),
cert_verifier_(context.cert_verifier),
@@ -2372,7 +2373,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(
nss_fd_(NULL),
net_log_(transport_->socket()->NetLog()),
transport_security_state_(context.transport_security_state),
- policy_enforcer_(context.cert_policy_enforcer),
+ policy_enforcer_(context.ct_policy_enforcer),
valid_thread_id_(base::kInvalidThreadId) {
DCHECK(cert_verifier_);
@@ -2445,6 +2446,11 @@ void SSLClientSocketNSS::GetConnectionAttempts(ConnectionAttempts* out) const {
out->clear();
}
+int64_t SSLClientSocketNSS::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
void SSLClientSocketNSS::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
EnterFunction("");
@@ -2657,11 +2663,11 @@ int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
return rv;
}
-int SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
+int SSLClientSocketNSS::SetReceiveBufferSize(int32_t size) {
return transport_->socket()->SetReceiveBufferSize(size);
}
-int SSLClientSocketNSS::SetSendBufferSize(int32 size) {
+int SSLClientSocketNSS::SetSendBufferSize(int32_t size) {
return transport_->socket()->SetSendBufferSize(size);
}
@@ -2768,7 +2774,7 @@ int SSLClientSocketNSS::InitializeSSLOptions() {
}
}
- for (std::vector<uint16>::const_iterator it =
+ for (std::vector<uint16_t>::const_iterator it =
ssl_config_.disabled_cipher_suites.begin();
it != ssl_config_.disabled_cipher_suites.end(); ++it) {
// This will fail if the specified cipher is not implemented by NSS, but
@@ -2776,17 +2782,23 @@ int SSLClientSocketNSS::InitializeSSLOptions() {
SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
}
- if (!ssl_config_.enable_deprecated_cipher_suites) {
- const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers();
- const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers();
- for (int i = 0; i < num_ciphers; i++) {
- SSLCipherSuiteInfo info;
- if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) !=
- SECSuccess) {
- continue;
- }
- if (info.symCipher == ssl_calg_rc4)
- SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE);
+ const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers();
+ const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers();
+ for (int i = 0; i < num_ciphers; i++) {
+ SSLCipherSuiteInfo info;
+ if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) !=
+ SECSuccess) {
+ continue;
+ }
+ if (info.symCipher == ssl_calg_rc4 &&
+ !(ssl_config_.rc4_enabled &&
+ ssl_config_.deprecated_cipher_suites_enabled)) {
+ SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE);
+ }
+ if (info.keaType == ssl_kea_dh &&
+ !ssl_config_.deprecated_cipher_suites_enabled) {
+ // Only offer DHE on the second handshake. https://crbug.com/538690
+ SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE);
}
}
@@ -2902,9 +2914,13 @@ int SSLClientSocketNSS::InitializeSSLPeerName() {
NOTREACHED();
}
peer_id += "/";
- if (ssl_config_.enable_deprecated_cipher_suites)
+ if (ssl_config_.deprecated_cipher_suites_enabled)
peer_id += "deprecated";
+ peer_id += "/";
+ if (ssl_config_.channel_id_enabled)
+ peer_id += "channelid";
+
SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str()));
if (rv != SECSuccess)
LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str());
@@ -3143,25 +3159,20 @@ bool SSLClientSocketNSS::CalledOnValidThread() const {
}
void SSLClientSocketNSS::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const {
- for (ct::SCTList::const_iterator iter =
- ct_verify_result_.verified_scts.begin();
- iter != ct_verify_result_.verified_scts.end(); ++iter) {
- ssl_info->signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK));
- }
- for (ct::SCTList::const_iterator iter =
- ct_verify_result_.invalid_scts.begin();
- iter != ct_verify_result_.invalid_scts.end(); ++iter) {
- ssl_info->signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_INVALID));
- }
- for (ct::SCTList::const_iterator iter =
- ct_verify_result_.unknown_logs_scts.begin();
- iter != ct_verify_result_.unknown_logs_scts.end(); ++iter) {
- ssl_info->signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(*iter,
- ct::SCT_STATUS_LOG_UNKNOWN));
+ ssl_info->UpdateSignedCertificateTimestamps(ct_verify_result_);
+}
+
+// static
+void SSLClientSocketNSS::ReorderNextProtos(NextProtoVector* next_protos) {
+ if (next_protos->size() < 2) {
+ return;
+ }
+
+ NextProto fallback_proto = next_protos->back();
+ for (size_t i = next_protos->size() - 1; i > 0; --i) {
+ (*next_protos)[i] = (*next_protos)[i - 1];
}
+ (*next_protos)[0] = fallback_proto;
}
ChannelIDService* SSLClientSocketNSS::GetChannelIDService() const {
diff --git a/chromium/net/socket/ssl_client_socket_nss.h b/chromium/net/socket/ssl_client_socket_nss.h
index 0cec7eb22c0..366df1c4ee7 100644
--- a/chromium/net/socket/ssl_client_socket_nss.h
+++ b/chromium/net/socket/ssl_client_socket_nss.h
@@ -9,6 +9,7 @@
#include <keyt.h>
#include <nspr.h>
#include <nss.h>
+#include <stdint.h>
#include <string>
#include <vector>
@@ -33,7 +34,7 @@
namespace net {
class BoundNetLog;
-class CertPolicyEnforcer;
+class CTPolicyEnforcer;
class CertVerifier;
class ChannelIDService;
class CTVerifier;
@@ -84,6 +85,7 @@ class SSLClientSocketNSS : public SSLClientSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -92,8 +94,8 @@ class SSLClientSocketNSS : public SSLClientSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
// SSLClientSocket implementation.
ChannelIDService* GetChannelIDService() const override;
@@ -144,6 +146,12 @@ class SSLClientSocketNSS : public SSLClientSocket {
// the |ssl_info|.signed_certificate_timestamps list.
void AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const;
+ // Move last protocol to first place: SSLConfig::next_protos has protocols in
+ // decreasing order of preference with NPN fallback protocol at the end, but
+ // NSS moves the first one to the last place before sending them in ALPN, and
+ // uses the first one as a fallback for NPN.
+ static void ReorderNextProtos(NextProtoVector* next_protos);
+
scoped_ptr<ClientSocketHandle> transport_;
HostPortPair host_and_port_;
SSLConfig ssl_config_;
@@ -188,7 +196,7 @@ class SSLClientSocketNSS : public SSLClientSocket {
TransportSecurityState* transport_security_state_;
- CertPolicyEnforcer* const policy_enforcer_;
+ CTPolicyEnforcer* const policy_enforcer_;
// pinning_failure_log contains a message produced by
// TransportSecurityState::CheckPublicKeyPins in the event of a
diff --git a/chromium/net/socket/ssl_client_socket_openssl.cc b/chromium/net/socket/ssl_client_socket_openssl.cc
index b242388b52f..82ced7cbfea 100644
--- a/chromium/net/socket/ssl_client_socket_openssl.cc
+++ b/chromium/net/socket/ssl_client_socket_openssl.cc
@@ -9,22 +9,25 @@
#include <errno.h>
#include <openssl/bio.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/ssl.h>
#include <string.h>
+#include <utility>
+
#include "base/bind.h"
#include "base/callback_helpers.h"
-#include "base/environment.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/profiler/scoped_tracker.h"
-#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_local.h"
#include "base/values.h"
#include "crypto/ec_private_key.h"
@@ -32,9 +35,9 @@
#include "crypto/scoped_openssl_types.h"
#include "net/base/ip_address_number.h"
#include "net/base/net_errors.h"
-#include "net/cert/cert_policy_enforcer.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_ev_whitelist.h"
+#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_verifier.h"
#include "net/cert/x509_certificate_net_log_param.h"
#include "net/cert/x509_util_openssl.h"
@@ -52,7 +55,7 @@
#endif
#if !defined(OS_NACL)
-#include "net/ssl/ssl_platform_key.h"
+#include "net/ssl/ssl_key_logger.h"
#endif
#if defined(USE_NSS_CERTS) || defined(OS_IOS)
@@ -83,6 +86,15 @@ const char kDefaultSupportedNPNProtocol[] = "http/1.1";
// Default size of the internal BoringSSL buffers.
const int KDefaultOpenSSLBufferSize = 17 * 1024;
+// TLS extension number use for Token Binding.
+const unsigned int kTbExtNum = 30033;
+
+// Token Binding ProtocolVersions supported.
+const uint8_t kTbProtocolVersionMajor = 0;
+const uint8_t kTbProtocolVersionMinor = 3;
+const uint8_t kTbMinProtocolVersionMajor = 0;
+const uint8_t kTbMinProtocolVersionMinor = 2;
+
void FreeX509Stack(STACK_OF(X509)* ptr) {
sk_X509_pop_free(ptr, X509_free);
}
@@ -90,7 +102,7 @@ void FreeX509Stack(STACK_OF(X509)* ptr) {
using ScopedX509Stack = crypto::ScopedOpenSSL<STACK_OF(X509), FreeX509Stack>;
// Used for encoding the |connection_status| field of an SSLInfo object.
-int EncodeSSLConnectionStatus(uint16 cipher_suite,
+int EncodeSSLConnectionStatus(uint16_t cipher_suite,
int compression,
int version) {
return cipher_suite |
@@ -138,12 +150,7 @@ ScopedX509Stack OSCertHandlesToOpenSSL(
return ScopedX509Stack();
sk_X509_push(stack.get(), x509.release());
}
- return stack.Pass();
-}
-
-int LogErrorCallback(const char* str, size_t len, void* context) {
- LOG(ERROR) << base::StringPiece(str, len);
- return 1;
+ return stack;
}
bool EVP_MDToPrivateKeyHash(const EVP_MD* md, SSLPrivateKey::Hash* hash) {
@@ -168,32 +175,56 @@ bool EVP_MDToPrivateKeyHash(const EVP_MD* md, SSLPrivateKey::Hash* hash) {
}
}
-#if !defined(OS_NACL)
-class PlatformKeyTaskRunner {
+class ScopedCBB {
public:
- PlatformKeyTaskRunner() {
- // Serialize all the private key operations on a single background
- // thread to avoid problems with buggy smartcards.
- worker_pool_ = new base::SequencedWorkerPool(1, "Platform Key Thread");
- task_runner_ = worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
- worker_pool_->GetSequenceToken(),
- base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
- }
+ ScopedCBB() { CBB_zero(&cbb_); }
+ ~ScopedCBB() { CBB_cleanup(&cbb_); }
- scoped_refptr<base::SequencedTaskRunner> task_runner() {
- return task_runner_;
- }
+ CBB* get() { return &cbb_; }
private:
- scoped_refptr<base::SequencedWorkerPool> worker_pool_;
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(PlatformKeyTaskRunner);
+ CBB cbb_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedCBB);
};
-base::LazyInstance<PlatformKeyTaskRunner>::Leaky g_platform_key_task_runner =
- LAZY_INSTANCE_INITIALIZER;
-#endif
+scoped_ptr<base::Value> NetLogPrivateKeyOperationCallback(
+ SSLPrivateKey::Type type,
+ SSLPrivateKey::Hash hash,
+ NetLogCaptureMode mode) {
+ std::string type_str;
+ switch (type) {
+ case SSLPrivateKey::Type::RSA:
+ type_str = "RSA";
+ break;
+ case SSLPrivateKey::Type::ECDSA:
+ type_str = "ECDSA";
+ break;
+ }
+
+ std::string hash_str;
+ switch (hash) {
+ case SSLPrivateKey::Hash::MD5_SHA1:
+ hash_str = "MD5_SHA1";
+ break;
+ case SSLPrivateKey::Hash::SHA1:
+ hash_str = "SHA1";
+ break;
+ case SSLPrivateKey::Hash::SHA256:
+ hash_str = "SHA256";
+ break;
+ case SSLPrivateKey::Hash::SHA384:
+ hash_str = "SHA384";
+ break;
+ case SSLPrivateKey::Hash::SHA512:
+ hash_str = "SHA512";
+ break;
+ }
+
+ scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue);
+ value->SetString("type", type_str);
+ value->SetString("hash", hash_str);
+ return std::move(value);
+}
} // namespace
@@ -217,6 +248,16 @@ class SSLClientSocketOpenSSL::SSLContext {
return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0;
}
+#if !defined(OS_NACL)
+ void SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
+ DCHECK(!ssl_key_logger_);
+ ssl_key_logger_.reset(new SSLKeyLogger(path, task_runner));
+ SSL_CTX_set_keylog_callback(ssl_ctx_.get(), KeyLogCallback);
+ }
+#endif
+
static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
private:
@@ -234,9 +275,8 @@ class SSLClientSocketOpenSSL::SSLContext {
// is currently not sent on the network.
// TODO(haavardm): Remove setting quiet shutdown once 118366 is fixed.
SSL_CTX_set_quiet_shutdown(ssl_ctx_.get(), 1);
- // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty.
- // It would be better if the callback were not a global setting,
- // but that is an OpenSSL issue.
+ // Note that SSL_OP_DISABLE_NPN is used to disable NPN if
+ // ssl_config_.next_proto is empty.
SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback,
NULL);
@@ -246,21 +286,48 @@ class SSLClientSocketOpenSSL::SSLContext {
ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallback);
- scoped_ptr<base::Environment> env(base::Environment::Create());
- std::string ssl_keylog_file;
- if (env->GetVar("SSLKEYLOGFILE", &ssl_keylog_file) &&
- !ssl_keylog_file.empty()) {
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- BIO* bio = BIO_new_file(ssl_keylog_file.c_str(), "a");
- if (!bio) {
- LOG(ERROR) << "Failed to open " << ssl_keylog_file;
- ERR_print_errors_cb(&LogErrorCallback, NULL);
- } else {
- SSL_CTX_set_keylog_bio(ssl_ctx_.get(), bio);
- }
+ if (!SSL_CTX_add_client_custom_ext(ssl_ctx_.get(), kTbExtNum,
+ &TokenBindingAddCallback,
+ &TokenBindingFreeCallback, nullptr,
+ &TokenBindingParseCallback, nullptr)) {
+ NOTREACHED();
}
}
+ static int TokenBindingAddCallback(SSL* ssl,
+ unsigned int extension_value,
+ const uint8_t** out,
+ size_t* out_len,
+ int* out_alert_value,
+ void* add_arg) {
+ DCHECK_EQ(extension_value, kTbExtNum);
+ SSLClientSocketOpenSSL* socket =
+ SSLClientSocketOpenSSL::SSLContext::GetInstance()
+ ->GetClientSocketFromSSL(ssl);
+ return socket->TokenBindingAdd(out, out_len, out_alert_value);
+ }
+
+ static void TokenBindingFreeCallback(SSL* ssl,
+ unsigned extension_value,
+ const uint8_t* out,
+ void* add_arg) {
+ DCHECK_EQ(extension_value, kTbExtNum);
+ OPENSSL_free(const_cast<unsigned char*>(out));
+ }
+
+ static int TokenBindingParseCallback(SSL* ssl,
+ unsigned int extension_value,
+ const uint8_t* contents,
+ size_t contents_len,
+ int* out_alert_value,
+ void* parse_arg) {
+ DCHECK_EQ(extension_value, kTbExtNum);
+ SSLClientSocketOpenSSL* socket =
+ SSLClientSocketOpenSSL::SSLContext::GetInstance()
+ ->GetClientSocketFromSSL(ssl);
+ return socket->TokenBindingParse(contents, contents_len, out_alert_value);
+ }
+
static int ClientCertRequestCallback(SSL* ssl, void* arg) {
SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl);
DCHECK(socket);
@@ -320,12 +387,22 @@ class SSLClientSocketOpenSSL::SSLContext {
return socket->PrivateKeySignCompleteCallback(out, out_len, max_out);
}
+#if !defined(OS_NACL)
+ static void KeyLogCallback(const SSL* ssl, const char* line) {
+ GetInstance()->ssl_key_logger_->WriteLine(line);
+ }
+#endif
+
// This is the index used with SSL_get_ex_data to retrieve the owner
// SSLClientSocketOpenSSL object from an SSL instance.
int ssl_socket_data_index_;
ScopedSSL_CTX ssl_ctx_;
+#if !defined(OS_NACL)
+ scoped_ptr<SSLKeyLogger> ssl_key_logger_;
+#endif
+
// TODO(davidben): Use a separate cache per URLRequestContext.
// https://crbug.com/458365
//
@@ -447,9 +524,11 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
cert_verifier_(context.cert_verifier),
cert_transparency_verifier_(context.cert_transparency_verifier),
channel_id_service_(context.channel_id_service),
+ tb_was_negotiated_(false),
+ tb_negotiated_param_(TB_PARAM_ECDSAP256),
ssl_(NULL),
transport_bio_(NULL),
- transport_(transport_socket.Pass()),
+ transport_(std::move(transport_socket)),
host_and_port_(host_and_port),
ssl_config_(ssl_config),
ssl_session_cache_shard_(context.ssl_session_cache_shard),
@@ -462,7 +541,7 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
ssl_failure_state_(SSL_FAILURE_NONE),
signature_result_(kNoPendingResult),
transport_security_state_(context.transport_security_state),
- policy_enforcer_(context.cert_policy_enforcer),
+ policy_enforcer_(context.ct_policy_enforcer),
net_log_(transport_->socket()->NetLog()),
weak_factory_(this) {
DCHECK(cert_verifier_);
@@ -472,6 +551,14 @@ SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
Disconnect();
}
+#if !defined(OS_NACL)
+void SSLClientSocketOpenSSL::SetSSLKeyLogFile(
+ const base::FilePath& ssl_keylog_file,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
+ SSLContext::GetInstance()->SetSSLKeyLogFile(ssl_keylog_file, task_runner);
+}
+#endif
+
void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
cert_request_info->host_and_port = host_and_port_;
@@ -611,12 +698,12 @@ void SSLClientSocketOpenSSL::Disconnect() {
npn_proto_.clear();
channel_id_sent_ = false;
+ tb_was_negotiated_ = false;
session_pending_ = false;
certificate_verified_ = false;
channel_id_request_.Cancel();
ssl_failure_state_ = SSL_FAILURE_NONE;
- private_key_.reset();
signature_result_ = kNoPendingResult;
signature_.clear();
}
@@ -708,6 +795,8 @@ bool SSLClientSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
ssl_info->client_cert_sent =
ssl_config_.send_client_cert && ssl_config_.client_cert.get();
ssl_info->channel_id_sent = channel_id_sent_;
+ ssl_info->token_binding_negotiated = tb_was_negotiated_;
+ ssl_info->token_binding_key_param = tb_negotiated_param_;
ssl_info->pinning_failure_log = pinning_failure_log_;
AddSCTInfoToSSLInfo(ssl_info);
@@ -719,7 +808,7 @@ bool SSLClientSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl_));
ssl_info->connection_status = EncodeSSLConnectionStatus(
- static_cast<uint16>(SSL_CIPHER_get_id(cipher)), 0 /* no compression */,
+ static_cast<uint16_t>(SSL_CIPHER_get_id(cipher)), 0 /* no compression */,
GetNetSSLVersion(ssl_));
if (!SSL_get_secure_renegotiation_support(ssl_))
@@ -743,6 +832,10 @@ void SSLClientSocketOpenSSL::GetConnectionAttempts(
out->clear();
}
+int64_t SSLClientSocketOpenSSL::GetTotalReceivedBytes() const {
+ return transport_->socket()->GetTotalReceivedBytes();
+}
+
int SSLClientSocketOpenSSL::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
@@ -783,11 +876,11 @@ int SSLClientSocketOpenSSL::Write(IOBuffer* buf,
return rv;
}
-int SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) {
+int SSLClientSocketOpenSSL::SetReceiveBufferSize(int32_t size) {
return transport_->socket()->SetReceiveBufferSize(size);
}
-int SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) {
+int SSLClientSocketOpenSSL::SetSendBufferSize(int32_t size) {
return transport_->socket()->SetSendBufferSize(size);
}
@@ -821,9 +914,10 @@ int SSLClientSocketOpenSSL::Init() {
return ERR_UNEXPECTED;
}
- SSL_SESSION* session = context->session_cache()->Lookup(GetSessionCacheKey());
- if (session != nullptr)
- SSL_set_session(ssl_, session);
+ ScopedSSL_SESSION session =
+ context->session_cache()->Lookup(GetSessionCacheKey());
+ if (session)
+ SSL_set_session(ssl_, session.get());
send_buffer_ = new GrowableIOBuffer();
send_buffer_->SetCapacity(KDefaultOpenSSLBufferSize);
@@ -887,14 +981,14 @@ int SSLClientSocketOpenSSL::Init() {
if (ssl_config_.require_ecdhe)
command.append(":!kRSA:!kDHE");
- if (!ssl_config_.enable_deprecated_cipher_suites) {
+ if (!(ssl_config_.rc4_enabled &&
+ ssl_config_.deprecated_cipher_suites_enabled)) {
command.append(":!RC4");
- } else {
- // Add TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 under a fallback. This is
- // believed to work around a bug in some out-of-date Microsoft IIS servers
- // which cause them to require the version downgrade
- // (https://crbug.com/433406).
- command.append(":ECDHE-RSA-AES256-SHA384");
+ }
+
+ if (!ssl_config_.deprecated_cipher_suites_enabled) {
+ // Only offer DHE on the second handshake. https://crbug.com/538690
+ command.append(":!kDHE");
}
// Remove any disabled ciphers.
@@ -926,27 +1020,30 @@ int SSLClientSocketOpenSSL::Init() {
SSL_enable_tls_channel_id(ssl_);
}
- if (!ssl_config_.next_protos.empty()) {
+ if (!ssl_config_.alpn_protos.empty()) {
// Get list of ciphers that are enabled.
STACK_OF(SSL_CIPHER)* enabled_ciphers = SSL_get_ciphers(ssl_);
DCHECK(enabled_ciphers);
- std::vector<uint16> enabled_ciphers_vector;
+ std::vector<uint16_t> enabled_ciphers_vector;
for (size_t i = 0; i < sk_SSL_CIPHER_num(enabled_ciphers); ++i) {
const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(enabled_ciphers, i);
- const uint16 id = static_cast<uint16>(SSL_CIPHER_get_id(cipher));
+ const uint16_t id = static_cast<uint16_t>(SSL_CIPHER_get_id(cipher));
enabled_ciphers_vector.push_back(id);
}
- NextProtoVector next_protos = ssl_config_.next_protos;
+ NextProtoVector alpn_protos = ssl_config_.alpn_protos;
if (!HasCipherAdequateForHTTP2(enabled_ciphers_vector) ||
!IsTLSVersionAdequateForHTTP2(ssl_config_)) {
- DisableHTTP2(&next_protos);
+ DisableHTTP2(&alpn_protos);
}
- std::vector<uint8_t> wire_protos = SerializeNextProtos(next_protos);
+ std::vector<uint8_t> wire_protos = SerializeNextProtos(alpn_protos);
SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0],
wire_protos.size());
}
+ if (ssl_config_.npn_protos.empty())
+ SSL_set_options(ssl_, SSL_OP_DISABLE_NPN);
+
if (ssl_config_.signed_cert_timestamps_enabled) {
SSL_enable_signed_cert_timestamps(ssl_);
SSL_enable_ocsp_stapling(ssl_);
@@ -955,10 +1052,6 @@ int SSLClientSocketOpenSSL::Init() {
if (cert_verifier_->SupportsOCSPStapling())
SSL_enable_ocsp_stapling(ssl_);
- // By default, renegotiations are rejected. After the initial handshake
- // completes, some application protocols may re-enable it.
- SSL_set_reject_peer_renegotiations(ssl_, 1);
-
return OK;
}
@@ -1039,7 +1132,7 @@ int SSLClientSocketOpenSSL::DoHandshake() {
return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
}
if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
- DCHECK(private_key_);
+ DCHECK(ssl_config_.client_private_key);
DCHECK_NE(kNoPendingResult, signature_result_);
GotoState(STATE_HANDSHAKE);
return ERR_IO_PENDING;
@@ -1098,6 +1191,11 @@ int SSLClientSocketOpenSSL::DoHandshakeComplete(int result) {
return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION;
}
+ // Check that if token binding was negotiated, then extended master secret
+ // must also be negotiated.
+ if (tb_was_negotiated_ && !SSL_get_extms_support(ssl_))
+ return ERR_SSL_PROTOCOL_ERROR;
+
// SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was.
if (npn_status_ == kNextProtoUnsupported) {
const uint8_t* alpn_proto = NULL;
@@ -1112,8 +1210,7 @@ int SSLClientSocketOpenSSL::DoHandshakeComplete(int result) {
RecordNegotiationExtension();
RecordChannelIDSupport(channel_id_service_, channel_id_sent_,
- ssl_config_.channel_id_enabled,
- crypto::ECPrivateKey::IsSupported());
+ ssl_config_.channel_id_enabled);
// Only record OCSP histograms if OCSP was requested.
if (ssl_config_.signed_cert_timestamps_enabled ||
@@ -1132,7 +1229,13 @@ int SSLClientSocketOpenSSL::DoHandshakeComplete(int result) {
set_signed_cert_timestamps_received(sct_list_len != 0);
if (IsRenegotiationAllowed())
- SSL_set_reject_peer_renegotiations(ssl_, 0);
+ SSL_set_renegotiate_mode(ssl_, ssl_renegotiate_freely);
+
+ uint8_t server_key_exchange_hash = SSL_get_server_key_exchange_hash(ssl_);
+ if (server_key_exchange_hash != TLSEXT_hash_none) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLServerKeyExchangeHash",
+ server_key_exchange_hash);
+ }
// Verify the certificate.
UpdateServerCert();
@@ -1239,16 +1342,6 @@ int SSLClientSocketOpenSSL::DoVerifyCertComplete(int result) {
}
}
- if (result == OK) {
- if (SSL_session_reused(ssl_)) {
- // Record whether or not the server tried to resume a session for a
- // different version. See https://crbug.com/441456.
- UMA_HISTOGRAM_BOOLEAN(
- "Net.SSLSessionVersionMatch",
- SSL_version(ssl_) == SSL_get_session(ssl_)->ssl_version);
- }
- }
-
const CertStatus cert_status = server_cert_verify_result_.cert_status;
if (transport_security_state_ &&
(result == OK ||
@@ -1506,7 +1599,7 @@ int SSLClientSocketOpenSSL::DoPayloadRead() {
pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
} else if (pending_read_ssl_error_ ==
SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
- DCHECK(private_key_);
+ DCHECK(ssl_config_.client_private_key);
DCHECK_NE(kNoPendingResult, signature_result_);
pending_read_error_ = ERR_IO_PENDING;
} else {
@@ -1796,18 +1889,9 @@ int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) {
return -1;
}
-#if defined(OS_NACL)
- OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY);
- return -1;
-#else
- // TODO(davidben): Lift this call up to the embedder so we can actually test
- // this code. https://crbug.com/394131
- private_key_ = FetchClientCertPrivateKey(
- ssl_config_.client_cert.get(),
- g_platform_key_task_runner.Get().task_runner());
- if (!private_key_) {
- // Could not find the private key. Fail the handshake and surface an
- // appropriate error to the caller.
+ if (!ssl_config_.client_private_key) {
+ // The caller supplied a null private key. Fail the handshake and surface
+ // an appropriate error to the caller.
LOG(WARNING) << "Client cert found without private key";
OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY);
return -1;
@@ -1816,7 +1900,7 @@ int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) {
SSL_set_private_key_method(ssl_, &SSLContext::kPrivateKeyMethod);
std::vector<SSLPrivateKey::Hash> digest_prefs =
- private_key_->GetDigestPreferences();
+ ssl_config_.client_private_key->GetDigestPreferences();
size_t digests_len = digest_prefs.size();
std::vector<int> digests;
@@ -1840,20 +1924,18 @@ int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) {
}
}
- SSL_set_private_key_digest_prefs(ssl_, vector_as_array(&digests),
- digests.size());
-#endif // !OS_NACL
+ SSL_set_private_key_digest_prefs(ssl_, digests.data(), digests.size());
int cert_count = 1 + sk_X509_num(chain.get());
net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED,
- NetLog::IntegerCallback("cert_count", cert_count));
+ NetLog::IntCallback("cert_count", cert_count));
return 1;
}
#endif // defined(OS_IOS)
// Send no client certificate.
net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED,
- NetLog::IntegerCallback("cert_count", 0));
+ NetLog::IntCallback("cert_count", 0));
return 1;
}
@@ -1886,14 +1968,14 @@ int SSLClientSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx) {
// SelectNextProtoCallback is called by OpenSSL during the handshake. If the
// server supports NPN, selects a protocol from the list that the server
-// provides. According to third_party/openssl/openssl/ssl/ssl_lib.c, the
+// provides. According to third_party/boringssl/src/ssl/ssl_lib.c, the
// callback can assume that |in| is syntactically valid.
int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out,
unsigned char* outlen,
const unsigned char* in,
unsigned int inlen) {
- if (ssl_config_.next_protos.empty()) {
- *out = reinterpret_cast<uint8*>(
+ if (ssl_config_.npn_protos.empty()) {
+ *out = reinterpret_cast<uint8_t*>(
const_cast<char*>(kDefaultSupportedNPNProtocol));
*outlen = arraysize(kDefaultSupportedNPNProtocol) - 1;
npn_status_ = kNextProtoUnsupported;
@@ -1905,7 +1987,7 @@ int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out,
// For each protocol in server preference order, see if we support it.
for (unsigned int i = 0; i < inlen; i += in[i] + 1) {
- for (NextProto next_proto : ssl_config_.next_protos) {
+ for (NextProto next_proto : ssl_config_.npn_protos) {
const std::string proto = NextProtoToString(next_proto);
if (in[i] == proto.size() &&
memcmp(&in[i + 1], proto.data(), in[i]) == 0) {
@@ -1920,10 +2002,10 @@ int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out,
break;
}
- // If we didn't find a protocol, we select the first one from our list.
+ // If we didn't find a protocol, we select the last one from our list.
if (npn_status_ == kNextProtoNoOverlap) {
// NextProtoToString returns a pointer to a static string.
- const char* proto = NextProtoToString(ssl_config_.next_protos[0]);
+ const char* proto = NextProtoToString(ssl_config_.npn_protos.back());
*out = reinterpret_cast<unsigned char*>(const_cast<char*>(proto));
*outlen = strlen(proto);
}
@@ -2006,25 +2088,7 @@ int SSLClientSocketOpenSSL::NewSessionCallback(SSL_SESSION* session) {
}
void SSLClientSocketOpenSSL::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const {
- for (ct::SCTList::const_iterator iter =
- ct_verify_result_.verified_scts.begin();
- iter != ct_verify_result_.verified_scts.end(); ++iter) {
- ssl_info->signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK));
- }
- for (ct::SCTList::const_iterator iter =
- ct_verify_result_.invalid_scts.begin();
- iter != ct_verify_result_.invalid_scts.end(); ++iter) {
- ssl_info->signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_INVALID));
- }
- for (ct::SCTList::const_iterator iter =
- ct_verify_result_.unknown_logs_scts.begin();
- iter != ct_verify_result_.unknown_logs_scts.end(); ++iter) {
- ssl_info->signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(*iter,
- ct::SCT_STATUS_LOG_UNKNOWN));
- }
+ ssl_info->UpdateSignedCertificateTimestamps(ct_verify_result_);
}
std::string SSLClientSocketOpenSSL::GetSessionCacheKey() const {
@@ -2050,13 +2114,20 @@ std::string SSLClientSocketOpenSSL::GetSessionCacheKey() const {
}
result.append("/");
- if (ssl_config_.enable_deprecated_cipher_suites)
+ if (ssl_config_.deprecated_cipher_suites_enabled)
result.append("deprecated");
+ result.append("/");
+ if (ssl_config_.channel_id_enabled)
+ result.append("channelid");
+
return result;
}
bool SSLClientSocketOpenSSL::IsRenegotiationAllowed() const {
+ if (tb_was_negotiated_)
+ return false;
+
if (npn_status_ == kNextProtoUnsupported)
return ssl_config_.renego_allowed_default;
@@ -2069,7 +2140,7 @@ bool SSLClientSocketOpenSSL::IsRenegotiationAllowed() const {
}
int SSLClientSocketOpenSSL::PrivateKeyTypeCallback() {
- switch (private_key_->GetType()) {
+ switch (ssl_config_.client_private_key->GetType()) {
case SSLPrivateKey::Type::RSA:
return EVP_PKEY_RSA;
case SSLPrivateKey::Type::ECDSA:
@@ -2080,7 +2151,7 @@ int SSLClientSocketOpenSSL::PrivateKeyTypeCallback() {
}
size_t SSLClientSocketOpenSSL::PrivateKeyMaxSignatureLenCallback() {
- return private_key_->GetMaxSignatureLengthInBytes();
+ return ssl_config_.client_private_key->GetMaxSignatureLengthInBytes();
}
ssl_private_key_result_t SSLClientSocketOpenSSL::PrivateKeySignCallback(
@@ -2092,9 +2163,7 @@ ssl_private_key_result_t SSLClientSocketOpenSSL::PrivateKeySignCallback(
size_t in_len) {
DCHECK_EQ(kNoPendingResult, signature_result_);
DCHECK(signature_.empty());
- DCHECK(private_key_);
-
- net_log_.BeginEvent(NetLog::TYPE_SSL_PRIVATE_KEY_OPERATION);
+ DCHECK(ssl_config_.client_private_key);
SSLPrivateKey::Hash hash;
if (!EVP_MDToPrivateKeyHash(md, &hash)) {
@@ -2102,8 +2171,13 @@ ssl_private_key_result_t SSLClientSocketOpenSSL::PrivateKeySignCallback(
return ssl_private_key_failure;
}
+ net_log_.BeginEvent(
+ NetLog::TYPE_SSL_PRIVATE_KEY_OPERATION,
+ base::Bind(&NetLogPrivateKeyOperationCallback,
+ ssl_config_.client_private_key->GetType(), hash));
+
signature_result_ = ERR_IO_PENDING;
- private_key_->SignDigest(
+ ssl_config_.client_private_key->SignDigest(
hash, base::StringPiece(reinterpret_cast<const char*>(in), in_len),
base::Bind(&SSLClientSocketOpenSSL::OnPrivateKeySignComplete,
weak_factory_.GetWeakPtr()));
@@ -2115,7 +2189,7 @@ ssl_private_key_result_t SSLClientSocketOpenSSL::PrivateKeySignCompleteCallback(
size_t* out_len,
size_t max_out) {
DCHECK_NE(kNoPendingResult, signature_result_);
- DCHECK(private_key_);
+ DCHECK(ssl_config_.client_private_key);
if (signature_result_ == ERR_IO_PENDING)
return ssl_private_key_retry;
@@ -2127,7 +2201,7 @@ ssl_private_key_result_t SSLClientSocketOpenSSL::PrivateKeySignCompleteCallback(
OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
return ssl_private_key_failure;
}
- memcpy(out, vector_as_array(&signature_), signature_.size());
+ memcpy(out, signature_.data(), signature_.size());
*out_len = signature_.size();
signature_.clear();
return ssl_private_key_success;
@@ -2138,7 +2212,7 @@ void SSLClientSocketOpenSSL::OnPrivateKeySignComplete(
const std::vector<uint8_t>& signature) {
DCHECK_EQ(ERR_IO_PENDING, signature_result_);
DCHECK(signature_.empty());
- DCHECK(private_key_);
+ DCHECK(ssl_config_.client_private_key);
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_PRIVATE_KEY_OPERATION,
error);
@@ -2157,4 +2231,83 @@ void SSLClientSocketOpenSSL::OnPrivateKeySignComplete(
PumpReadWriteEvents();
}
+int SSLClientSocketOpenSSL::TokenBindingAdd(const uint8_t** out,
+ size_t* out_len,
+ int* out_alert_value) {
+ if (ssl_config_.token_binding_params.empty()) {
+ return 0;
+ }
+ ScopedCBB output;
+ CBB parameters_list;
+ if (!CBB_init(output.get(), 7) ||
+ !CBB_add_u8(output.get(), kTbProtocolVersionMajor) ||
+ !CBB_add_u8(output.get(), kTbProtocolVersionMinor) ||
+ !CBB_add_u8_length_prefixed(output.get(), &parameters_list)) {
+ *out_alert_value = SSL_AD_INTERNAL_ERROR;
+ return -1;
+ }
+ for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
+ if (!CBB_add_u8(&parameters_list, ssl_config_.token_binding_params[i])) {
+ *out_alert_value = SSL_AD_INTERNAL_ERROR;
+ return -1;
+ }
+ }
+ // |*out| will be freed by TokenBindingFreeCallback.
+ if (!CBB_finish(output.get(), const_cast<uint8_t**>(out), out_len)) {
+ *out_alert_value = SSL_AD_INTERNAL_ERROR;
+ return -1;
+ }
+
+ return 1;
+}
+
+int SSLClientSocketOpenSSL::TokenBindingParse(const uint8_t* contents,
+ size_t contents_len,
+ int* out_alert_value) {
+ if (completed_connect_) {
+ // Token Binding may only be negotiated on the initial handshake.
+ *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+
+ CBS extension;
+ CBS_init(&extension, contents, contents_len);
+
+ CBS parameters_list;
+ uint8_t version_major, version_minor, param;
+ if (!CBS_get_u8(&extension, &version_major) ||
+ !CBS_get_u8(&extension, &version_minor) ||
+ !CBS_get_u8_length_prefixed(&extension, &parameters_list) ||
+ !CBS_get_u8(&parameters_list, &param) || CBS_len(&parameters_list) > 0 ||
+ CBS_len(&extension) > 0) {
+ *out_alert_value = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ // The server-negotiated version must be less than or equal to our version.
+ if (version_major > kTbProtocolVersionMajor ||
+ (version_minor > kTbProtocolVersionMinor &&
+ version_major == kTbProtocolVersionMajor)) {
+ *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+ // If the version the server negotiated is older than we support, don't fail
+ // parsing the extension, but also don't set |negotiated_|.
+ if (version_major < kTbMinProtocolVersionMajor ||
+ (version_minor < kTbMinProtocolVersionMinor &&
+ version_major == kTbMinProtocolVersionMajor)) {
+ return 1;
+ }
+
+ for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
+ if (param == ssl_config_.token_binding_params[i]) {
+ tb_negotiated_param_ = ssl_config_.token_binding_params[i];
+ tb_was_negotiated_ = true;
+ return 1;
+ }
+ }
+
+ *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+}
+
} // namespace net
diff --git a/chromium/net/socket/ssl_client_socket_openssl.h b/chromium/net/socket/ssl_client_socket_openssl.h
index 228214b42d6..178daeb3273 100644
--- a/chromium/net/socket/ssl_client_socket_openssl.h
+++ b/chromium/net/socket/ssl_client_socket_openssl.h
@@ -7,13 +7,16 @@
#include <openssl/base.h>
#include <openssl/ssl.h>
+#include <stddef.h>
+#include <stdint.h>
#include <string>
#include <vector>
-#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/cert/cert_verifier.h"
@@ -27,13 +30,17 @@
#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_failure_state.h"
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
namespace net {
class CertVerifier;
class CTVerifier;
class SSLCertRequestInfo;
class SSLInfo;
-class SSLPrivateKey;
// An SSL client socket implemented with OpenSSL.
class SSLClientSocketOpenSSL : public SSLClientSocket {
@@ -53,6 +60,14 @@ class SSLClientSocketOpenSSL : public SSLClientSocket {
return ssl_session_cache_shard_;
}
+#if !defined(OS_NACL)
+ // Log SSL key material to |path| on |task_runner|. Must be called before any
+ // SSLClientSockets are created.
+ static void SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner);
+#endif
+
// SSLClientSocket implementation.
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
NextProtoStatus GetNextProto(std::string* proto) const override;
@@ -83,6 +98,7 @@ class SSLClientSocketOpenSSL : public SSLClientSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -91,8 +107,8 @@ class SSLClientSocketOpenSSL : public SSLClientSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
private:
class PeerCertificateChain;
@@ -205,6 +221,13 @@ class SSLClientSocketOpenSSL : public SSLClientSocket {
void OnPrivateKeySignComplete(Error error,
const std::vector<uint8_t>& signature);
+ int TokenBindingAdd(const uint8_t** out,
+ size_t* out_len,
+ int* out_alert_value);
+ int TokenBindingParse(const uint8_t* contents,
+ size_t contents_len,
+ int* out_alert_value);
+
bool transport_send_busy_;
bool transport_recv_busy_;
@@ -276,6 +299,8 @@ class SSLClientSocketOpenSSL : public SSLClientSocket {
// The service for retrieving Channel ID keys. May be NULL.
ChannelIDService* channel_id_service_;
+ bool tb_was_negotiated_;
+ TokenBindingParam tb_negotiated_param_;
// OpenSSL stuff
SSL* ssl_;
@@ -319,13 +344,12 @@ class SSLClientSocketOpenSSL : public SSLClientSocket {
ChannelIDService::Request channel_id_request_;
SSLFailureState ssl_failure_state_;
- scoped_ptr<SSLPrivateKey> private_key_;
int signature_result_;
std::vector<uint8_t> signature_;
TransportSecurityState* transport_security_state_;
- CertPolicyEnforcer* const policy_enforcer_;
+ CTPolicyEnforcer* const policy_enforcer_;
// pinning_failure_log contains a message produced by
// TransportSecurityState::CheckPublicKeyPins in the event of a
diff --git a/chromium/net/socket/ssl_client_socket_openssl_unittest.cc b/chromium/net/socket/ssl_client_socket_openssl_unittest.cc
index 3a8b52ce6aa..a1ab91a4754 100644
--- a/chromium/net/socket/ssl_client_socket_openssl_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_openssl_unittest.cc
@@ -5,13 +5,13 @@
#include "net/socket/ssl_client_socket.h"
#include <errno.h>
-#include <string.h>
-
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
+#include <string.h>
+#include <utility>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -36,6 +36,7 @@
#include "net/ssl/openssl_client_key_store.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_config_service.h"
+#include "net/ssl/ssl_platform_key.h"
#include "net/test/cert_test_util.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -98,11 +99,9 @@ class SSLClientSocketOpenSSLClientAuthTest : public PlatformTest {
const HostPortPair& host_and_port,
const SSLConfig& ssl_config) {
scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
- connection->SetSocket(transport_socket.Pass());
- return socket_factory_->CreateSSLClientSocket(connection.Pass(),
- host_and_port,
- ssl_config,
- context_);
+ connection->SetSocket(std::move(transport_socket));
+ return socket_factory_->CreateSSLClientSocket(
+ std::move(connection), host_and_port, ssl_config, context_);
}
// Connect to a HTTPS test server.
@@ -152,9 +151,8 @@ class SSLClientSocketOpenSSLClientAuthTest : public PlatformTest {
// itself was a success.
bool CreateAndConnectSSLClientSocket(const SSLConfig& ssl_config,
int* result) {
- sock_ = CreateSSLClientSocket(transport_.Pass(),
- test_server_->host_port_pair(),
- ssl_config);
+ sock_ = CreateSSLClientSocket(std::move(transport_),
+ test_server_->host_port_pair(), ssl_config);
if (sock_->IsConnected()) {
LOG(ERROR) << "SSL Socket prematurely connected";
@@ -218,6 +216,7 @@ TEST_F(SSLClientSocketOpenSSLClientAuthTest, SendEmptyCert) {
SSLConfig ssl_config;
ssl_config.send_client_cert = true;
ssl_config.client_cert = NULL;
+ ssl_config.client_private_key = NULL;
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
@@ -248,6 +247,9 @@ TEST_F(SSLClientSocketOpenSSLClientAuthTest, SendGoodCert) {
&client_private_key));
EXPECT_TRUE(RecordPrivateKey(ssl_config, client_private_key.get()));
+ ssl_config.client_private_key =
+ FetchClientCertPrivateKey(ssl_config.client_cert.get());
+
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
diff --git a/chromium/net/socket/ssl_client_socket_pool.cc b/chromium/net/socket/ssl_client_socket_pool.cc
index b16eeedd2f8..f9a405854b3 100644
--- a/chromium/net/socket/ssl_client_socket_pool.cc
+++ b/chromium/net/socket/ssl_client_socket_pool.cc
@@ -4,6 +4,8 @@
#include "net/socket/ssl_client_socket_pool.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/metrics/field_trial.h"
@@ -122,7 +124,7 @@ SSLConnectJob::SSLConnectJob(const std::string& group_name,
context.channel_id_service,
context.transport_security_state,
context.cert_transparency_verifier,
- context.cert_policy_enforcer,
+ context.ct_policy_enforcer,
(params->privacy_mode() == PRIVACY_MODE_ENABLED
? "pm/" + context.ssl_session_cache_shard
: context.ssl_session_cache_shard)),
@@ -319,10 +321,8 @@ int SSLConnectJob::DoSSLConnect() {
connect_timing_.ssl_start = base::TimeTicks::Now();
ssl_socket_ = client_socket_factory_->CreateSSLClientSocket(
- transport_socket_handle_.Pass(),
- params_->host_and_port(),
- params_->ssl_config(),
- context_);
+ std::move(transport_socket_handle_), params_->host_and_port(),
+ params_->ssl_config(), context_);
return ssl_socket_->Connect(callback_);
}
@@ -372,7 +372,7 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
ssl_info.connection_status),
SSL_CONNECTION_VERSION_MAX);
- uint16 cipher_suite =
+ uint16_t cipher_suite =
SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_CipherSuite", cipher_suite);
@@ -440,7 +440,7 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error", std::abs(result));
if (result == OK || IsCertificateError(result)) {
- SetSocket(ssl_socket_.Pass());
+ SetSocket(std::move(ssl_socket_));
} else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
error_response_info_.cert_request_info = new SSLCertRequestInfo;
ssl_socket_->GetSSLCertRequestInfo(
@@ -510,7 +510,7 @@ SSLClientSocketPool::SSLClientSocketPool(
ChannelIDService* channel_id_service,
TransportSecurityState* transport_security_state,
CTVerifier* cert_transparency_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
const std::string& ssl_session_cache_shard,
ClientSocketFactory* client_socket_factory,
TransportClientSocketPool* transport_pool,
@@ -535,7 +535,7 @@ SSLClientSocketPool::SSLClientSocketPool(
channel_id_service,
transport_security_state,
cert_transparency_verifier,
- cert_policy_enforcer,
+ ct_policy_enforcer,
ssl_session_cache_shard),
net_log)),
ssl_config_service_(ssl_config_service) {
@@ -608,7 +608,7 @@ void SSLClientSocketPool::CancelRequest(const std::string& group_name,
void SSLClientSocketPool::ReleaseSocket(const std::string& group_name,
scoped_ptr<StreamSocket> socket,
int id) {
- base_.ReleaseSocket(group_name, socket.Pass(), id);
+ base_.ReleaseSocket(group_name, std::move(socket), id);
}
void SSLClientSocketPool::FlushWithError(int error) {
@@ -657,7 +657,7 @@ scoped_ptr<base::DictionaryValue> SSLClientSocketPool::GetInfoAsValue(
}
dict->Set("nested_pools", list);
}
- return dict.Pass();
+ return dict;
}
base::TimeDelta SSLClientSocketPool::ConnectionTimeout() const {
diff --git a/chromium/net/socket/ssl_client_socket_pool.h b/chromium/net/socket/ssl_client_socket_pool.h
index 2e4b20c51ab..b015baeb797 100644
--- a/chromium/net/socket/ssl_client_socket_pool.h
+++ b/chromium/net/socket/ssl_client_socket_pool.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
@@ -20,7 +21,7 @@
namespace net {
-class CertPolicyEnforcer;
+class CTPolicyEnforcer;
class CertVerifier;
class ClientSocketFactory;
class ConnectJobFactory;
@@ -189,7 +190,7 @@ class NET_EXPORT_PRIVATE SSLClientSocketPool
ChannelIDService* channel_id_service,
TransportSecurityState* transport_security_state,
CTVerifier* cert_transparency_verifier,
- CertPolicyEnforcer* cert_policy_enforcer,
+ CTPolicyEnforcer* ct_policy_enforcer,
const std::string& ssl_session_cache_shard,
ClientSocketFactory* client_socket_factory,
TransportClientSocketPool* transport_pool,
diff --git a/chromium/net/socket/ssl_client_socket_pool_unittest.cc b/chromium/net/socket/ssl_client_socket_pool_unittest.cc
index 48d667025b5..2baae896fb0 100644
--- a/chromium/net/socket/ssl_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_pool_unittest.cc
@@ -130,7 +130,7 @@ class SSLClientSocketPoolTest
pool_.reset(new SSLClientSocketPool(
kMaxSockets, kMaxSocketsPerGroup, NULL /* cert_verifier */,
NULL /* channel_id_service */, NULL /* transport_security_state */,
- NULL /* cert_transparency_verifier */, NULL /* cert_policy_enforcer */,
+ NULL /* cert_transparency_verifier */, NULL /* ct_policy_enforcer */,
std::string() /* ssl_session_cache_shard */, &socket_factory_,
transport_pool ? &transport_socket_pool_ : NULL,
socks_pool ? &socks_socket_pool_ : NULL,
@@ -185,7 +185,7 @@ class SSLClientSocketPoolTest
const scoped_refptr<SSLConfigService> ssl_config_service_;
const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
HttpServerPropertiesImpl http_server_properties_;
- const scoped_refptr<HttpNetworkSession> session_;
+ const scoped_ptr<HttpNetworkSession> session_;
scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
MockTransportClientSocketPool transport_socket_pool_;
@@ -828,7 +828,7 @@ TEST_P(SSLClientSocketPoolTest, IPPooling) {
CreatePool(true /* tcp pool */, false, false);
base::WeakPtr<SpdySession> spdy_session =
- CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());
+ CreateSecureSpdySession(session_.get(), test_hosts[0].key, BoundNetLog());
EXPECT_TRUE(
HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
@@ -885,7 +885,7 @@ void SSLClientSocketPoolTest::TestIPPoolingDisabled(
CreatePool(true /* tcp pool */, false, false);
base::WeakPtr<SpdySession> spdy_session =
- CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());
+ CreateSecureSpdySession(session_.get(), test_hosts[0].key, BoundNetLog());
EXPECT_TRUE(
HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
diff --git a/chromium/net/socket/ssl_client_socket_unittest.cc b/chromium/net/socket/ssl_client_socket_unittest.cc
index f27151c24e1..6a9d4654bdf 100644
--- a/chromium/net/socket/ssl_client_socket_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_unittest.cc
@@ -4,8 +4,11 @@
#include "net/socket/ssl_client_socket.h"
+#include <utility>
+
#include "base/callback_helpers.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -17,9 +20,13 @@
#include "net/base/test_completion_callback.h"
#include "net/base/test_data_directory.h"
#include "net/cert/asn1_util.h"
+#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_verifier.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/test_root_certs.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
+#include "net/der/tag.h"
#include "net/dns/host_resolver.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
@@ -59,7 +66,7 @@ namespace {
class WrappedStreamSocket : public StreamSocket {
public:
explicit WrappedStreamSocket(scoped_ptr<StreamSocket> transport)
- : transport_(transport.Pass()) {}
+ : transport_(std::move(transport)) {}
~WrappedStreamSocket() override {}
// StreamSocket implementation:
@@ -104,6 +111,9 @@ class WrappedStreamSocket : public StreamSocket {
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {
transport_->AddConnectionAttempts(attempts);
}
+ int64_t GetTotalReceivedBytes() const override {
+ return transport_->GetTotalReceivedBytes();
+ }
// Socket implementation:
int Read(IOBuffer* buf,
@@ -116,10 +126,10 @@ class WrappedStreamSocket : public StreamSocket {
const CompletionCallback& callback) override {
return transport_->Write(buf, buf_len, callback);
}
- int SetReceiveBufferSize(int32 size) override {
+ int SetReceiveBufferSize(int32_t size) override {
return transport_->SetReceiveBufferSize(size);
}
- int SetSendBufferSize(int32 size) override {
+ int SetSendBufferSize(int32_t size) override {
return transport_->SetSendBufferSize(size);
}
@@ -174,7 +184,7 @@ class ReadBufferingStreamSocket : public WrappedStreamSocket {
ReadBufferingStreamSocket::ReadBufferingStreamSocket(
scoped_ptr<StreamSocket> transport)
- : WrappedStreamSocket(transport.Pass()),
+ : WrappedStreamSocket(std::move(transport)),
read_buffer_(new GrowableIOBuffer()),
buffer_size_(0) {}
@@ -308,7 +318,7 @@ class SynchronousErrorStreamSocket : public WrappedStreamSocket {
SynchronousErrorStreamSocket::SynchronousErrorStreamSocket(
scoped_ptr<StreamSocket> transport)
- : WrappedStreamSocket(transport.Pass()),
+ : WrappedStreamSocket(std::move(transport)),
have_read_error_(false),
pending_read_error_(OK),
have_write_error_(false),
@@ -410,7 +420,7 @@ class FakeBlockingStreamSocket : public WrappedStreamSocket {
FakeBlockingStreamSocket::FakeBlockingStreamSocket(
scoped_ptr<StreamSocket> transport)
- : WrappedStreamSocket(transport.Pass()),
+ : WrappedStreamSocket(std::move(transport)),
should_block_read_(false),
pending_read_result_(ERR_IO_PENDING),
should_block_write_(false),
@@ -558,7 +568,7 @@ void FakeBlockingStreamSocket::OnReadCompleted(int result) {
class CountingStreamSocket : public WrappedStreamSocket {
public:
explicit CountingStreamSocket(scoped_ptr<StreamSocket> transport)
- : WrappedStreamSocket(transport.Pass()),
+ : WrappedStreamSocket(std::move(transport)),
read_count_(0),
write_count_(0) {}
~CountingStreamSocket() override {}
@@ -671,6 +681,16 @@ class MockCTVerifier : public CTVerifier {
MOCK_METHOD1(SetObserver, void(CTVerifier::Observer*));
};
+// A mock CTPolicyEnforcer that returns a custom verification result.
+class MockCTPolicyEnforcer : public CTPolicyEnforcer {
+ public:
+ MOCK_METHOD4(DoesConformToCTEVPolicy,
+ bool(X509Certificate* cert,
+ const ct::EVCertsWhitelist*,
+ const ct::CTVerifyResult&,
+ const BoundNetLog&));
+};
+
class SSLClientSocketTest : public PlatformTest {
public:
SSLClientSocketTest()
@@ -687,75 +707,87 @@ class SSLClientSocketTest : public PlatformTest {
const AddressList& addr() const { return addr_; }
// The SpawnedTestServer object, after calling StartTestServer().
- const SpawnedTestServer* test_server() const { return test_server_.get(); }
+ const SpawnedTestServer* spawned_test_server() const {
+ return spawned_test_server_.get();
+ }
void SetCTVerifier(CTVerifier* ct_verifier) {
context_.cert_transparency_verifier = ct_verifier;
}
+ void SetCTPolicyEnforcer(CTPolicyEnforcer* policy_enforcer) {
+ context_.ct_policy_enforcer = policy_enforcer;
+ }
+
// Starts the test server with SSL configuration |ssl_options|. Returns true
// on success.
bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) {
- test_server_.reset(new SpawnedTestServer(
+ spawned_test_server_.reset(new SpawnedTestServer(
SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()));
- if (!test_server_->Start()) {
+ if (!spawned_test_server_->Start()) {
LOG(ERROR) << "Could not start SpawnedTestServer";
return false;
}
- if (!test_server_->GetAddressList(&addr_)) {
+ if (!spawned_test_server_->GetAddressList(&addr_)) {
LOG(ERROR) << "Could not get SpawnedTestServer address list";
return false;
}
return true;
}
- // Sets up a TCP connection to a HTTPS server. To actually do the SSL
- // handshake, follow up with call to CreateAndConnectSSLClientSocket() below.
- bool ConnectToTestServer(const SpawnedTestServer::SSLOptions& ssl_options) {
- if (!StartTestServer(ssl_options))
- return false;
-
- transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source()));
- int rv = callback_.GetResult(transport_->Connect(callback_.callback()));
- if (rv != OK) {
- LOG(ERROR) << "Could not connect to SpawnedTestServer";
- return false;
- }
- return true;
- }
-
scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
scoped_ptr<StreamSocket> transport_socket,
const HostPortPair& host_and_port,
const SSLConfig& ssl_config) {
scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
- connection->SetSocket(transport_socket.Pass());
+ connection->SetSocket(std::move(transport_socket));
return socket_factory_->CreateSSLClientSocket(
- connection.Pass(), host_and_port, ssl_config, context_);
+ std::move(connection), host_and_port, ssl_config, context_);
}
// Create an SSLClientSocket object and use it to connect to a test
// server, then wait for connection results. This must be called after
- // a successful ConnectToTestServer() call.
+ // a successful StartTestServer() call.
// |ssl_config| the SSL configuration to use.
// |result| will retrieve the ::Connect() result value.
- // Returns true on success, false otherwise. Success means that the socket
+ // Returns true on success, false otherwise. Success means that the SSL socket
// could be created and its Connect() was called, not that the connection
// itself was a success.
- bool CreateAndConnectSSLClientSocket(SSLConfig& ssl_config, int* result) {
- sock_ = CreateSSLClientSocket(
- transport_.Pass(), test_server_->host_port_pair(), ssl_config);
-
- if (sock_->IsConnected()) {
- LOG(ERROR) << "SSL Socket prematurely connected";
+ bool CreateAndConnectSSLClientSocket(const SSLConfig& ssl_config,
+ int* result) {
+ scoped_ptr<StreamSocket> transport(
+ new TCPClientSocket(addr_, &log_, NetLog::Source()));
+ int rv = callback_.GetResult(transport->Connect(callback_.callback()));
+ if (rv != OK) {
+ LOG(ERROR) << "Could not connect to SpawnedTestServer";
return false;
}
+ sock_ = CreateSSLClientSocket(std::move(transport),
+ spawned_test_server_->host_port_pair(),
+ ssl_config);
+ EXPECT_FALSE(sock_->IsConnected());
+
*result = callback_.GetResult(sock_->Connect(callback_.callback()));
return true;
}
+ // Adds the server certificate with provided cert status.
+ // Must be called after StartTestServer has been called.
+ void AddServerCertStatusToSSLConfig(CertStatus status,
+ SSLConfig* ssl_config) {
+ ASSERT_TRUE(spawned_test_server());
+ // Find out the certificate the server is using.
+ scoped_refptr<X509Certificate> server_cert =
+ spawned_test_server()->GetCertificate();
+ // Get the MockCertVerifier to verify it as an EV cert.
+ CertVerifyResult verify_result;
+ verify_result.cert_status = status;
+ verify_result.verified_cert = server_cert;
+ cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
+ }
+
ClientSocketFactory* socket_factory_;
scoped_ptr<MockCertVerifier> cert_verifier_;
scoped_ptr<TransportSecurityState> transport_security_state_;
@@ -764,8 +796,7 @@ class SSLClientSocketTest : public PlatformTest {
TestNetLog log_;
private:
- scoped_ptr<StreamSocket> transport_;
- scoped_ptr<SpawnedTestServer> test_server_;
+ scoped_ptr<SpawnedTestServer> spawned_test_server_;
TestCompletionCallback callback_;
AddressList addr_;
};
@@ -777,37 +808,36 @@ class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest {
// the SSLCertRequestInfo reported by the socket.
scoped_refptr<SSLCertRequestInfo> GetCertRequest(
SpawnedTestServer::SSLOptions ssl_options) {
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
- if (!test_server.Start())
+ SpawnedTestServer spawned_test_server(SpawnedTestServer::TYPE_HTTPS,
+ ssl_options, base::FilePath());
+ if (!spawned_test_server.Start())
return NULL;
AddressList addr;
- if (!test_server.GetAddressList(&addr))
+ if (!spawned_test_server.GetAddressList(&addr))
return NULL;
TestCompletionCallback callback;
TestNetLog log;
scoped_ptr<StreamSocket> transport(
new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server.host_port_pair(),
+ SSLConfig()));
EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(sock->Connect(callback.callback()));
+ EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
+
scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo();
sock->GetSSLCertRequestInfo(request_info.get());
sock->Disconnect();
EXPECT_FALSE(sock->IsConnected());
- EXPECT_TRUE(
- test_server.host_port_pair().Equals(request_info->host_and_port));
+ EXPECT_TRUE(spawned_test_server.host_port_pair().Equals(
+ request_info->host_and_port));
return request_info;
}
@@ -833,18 +863,19 @@ class SSLClientSocketFalseStartTest : public SSLClientSocketTest {
TestCompletionCallback* callback,
FakeBlockingStreamSocket** out_raw_transport,
scoped_ptr<SSLClientSocket>* out_sock) {
- CHECK(test_server());
+ CHECK(spawned_test_server());
scoped_ptr<StreamSocket> real_transport(
new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<FakeBlockingStreamSocket> transport(
- new FakeBlockingStreamSocket(real_transport.Pass()));
+ new FakeBlockingStreamSocket(std::move(real_transport)));
int rv = callback->GetResult(transport->Connect(callback->callback()));
EXPECT_EQ(OK, rv);
FakeBlockingStreamSocket* raw_transport = transport.get();
scoped_ptr<SSLClientSocket> sock = CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), client_config);
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ client_config);
// Connect. Stop before the client processes the first server leg
// (ServerHello, etc.)
@@ -867,7 +898,7 @@ class SSLClientSocketFalseStartTest : public SSLClientSocketTest {
raw_transport->UnblockWrite();
*out_raw_transport = raw_transport;
- *out_sock = sock.Pass();
+ *out_sock = std::move(sock);
}
void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options,
@@ -949,25 +980,18 @@ class SSLClientSocketChannelIDTest : public SSLClientSocketTest {
} // namespace
TEST_F(SSLClientSocketTest, Connect) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
TestNetLog log;
scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ new TCPClientSocket(addr(), &log, NetLog::Source()));
+ int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ SSLConfig()));
EXPECT_FALSE(sock->IsConnected());
@@ -990,88 +1014,40 @@ TEST_F(SSLClientSocketTest, Connect) {
TEST_F(SSLClientSocketTest, ConnectExpired) {
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_EXPIRED);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
- ASSERT_TRUE(test_server.Start());
+ ASSERT_TRUE(StartTestServer(ssl_options));
cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- TestNetLog log;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
-
- EXPECT_FALSE(sock->IsConnected());
-
- rv = sock->Connect(callback.callback());
-
- TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(ERR_CERT_DATE_INVALID, rv);
// Rather than testing whether or not the underlying socket is connected,
// test that the handshake has finished. This is because it may be
// desirable to disconnect the socket before showing a user prompt, since
// the user may take indefinitely long to respond.
- log.GetEntries(&entries);
+ TestNetLogEntry::List entries;
+ log_.GetEntries(&entries);
EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SSL_CONNECT));
}
TEST_F(SSLClientSocketTest, ConnectMismatched) {
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
- ASSERT_TRUE(test_server.Start());
+ ASSERT_TRUE(StartTestServer(ssl_options));
cert_verifier_->set_default_result(ERR_CERT_COMMON_NAME_INVALID);
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- TestNetLog log;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
-
- EXPECT_FALSE(sock->IsConnected());
-
- rv = sock->Connect(callback.callback());
-
- TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, rv);
// Rather than testing whether or not the underlying socket is connected,
// test that the handshake has finished. This is because it may be
// desirable to disconnect the socket before showing a user prompt, since
// the user may take indefinitely long to respond.
- log.GetEntries(&entries);
+ TestNetLogEntry::List entries;
+ log_.GetEntries(&entries);
EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SSL_CONNECT));
}
@@ -1082,7 +1058,7 @@ TEST_F(SSLClientSocketTest, ConnectMismatched) {
TEST_F(SSLClientSocketTest, ConnectBadValidity) {
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_BAD_VALIDITY);
- ASSERT_TRUE(ConnectToTestServer(ssl_options));
+ ASSERT_TRUE(StartTestServer(ssl_options));
SSLConfig ssl_config;
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
@@ -1101,39 +1077,16 @@ TEST_F(SSLClientSocketTest, ConnectBadValidity) {
TEST_F(SSLClientSocketTest, ConnectClientAuthCertRequested) {
SpawnedTestServer::SSLOptions ssl_options;
ssl_options.request_client_certificate = true;
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- TestNetLog log;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
-
- EXPECT_FALSE(sock->IsConnected());
+ ASSERT_TRUE(StartTestServer(ssl_options));
- rv = sock->Connect(callback.callback());
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
+ EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
- log.GetEntries(&entries);
+ log_.GetEntries(&entries);
EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SSL_CONNECT));
- EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
- EXPECT_FALSE(sock->IsConnected());
+ EXPECT_FALSE(sock_->IsConnected());
}
// Connect to a server requesting optional client authentication. Send it a
@@ -1143,55 +1096,27 @@ TEST_F(SSLClientSocketTest, ConnectClientAuthCertRequested) {
TEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) {
SpawnedTestServer::SSLOptions ssl_options;
ssl_options.request_client_certificate = true;
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- TestNetLog log;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ ASSERT_TRUE(StartTestServer(ssl_options));
+ // Our test server accepts certificate-less connections.
+ // TODO(davidben): Add a test which requires them and verify the error.
SSLConfig ssl_config;
ssl_config.send_client_cert = true;
ssl_config.client_cert = NULL;
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
-
- EXPECT_FALSE(sock->IsConnected());
-
- // Our test server accepts certificate-less connections.
- // TODO(davidben): Add a test which requires them and verify the error.
- rv = sock->Connect(callback.callback());
-
- TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
EXPECT_EQ(OK, rv);
- EXPECT_TRUE(sock->IsConnected());
- log.GetEntries(&entries);
- EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SSL_CONNECT));
// We responded to the server's certificate request with a Certificate
// message with no client certificate in it. ssl_info.client_cert_sent
// should be false in this case.
SSLInfo ssl_info;
- sock->GetSSLInfo(&ssl_info);
+ sock_->GetSSLInfo(&ssl_info);
EXPECT_FALSE(ssl_info.client_cert_sent);
- sock->Disconnect();
- EXPECT_FALSE(sock->IsConnected());
+ sock_->Disconnect();
+ EXPECT_FALSE(sock_->IsConnected());
}
// TODO(wtc): Add unit tests for IsConnectedAndIdle:
@@ -1202,56 +1127,54 @@ TEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) {
// Tests that the socket can be read from successfully. Also test that a peer's
// close_notify alert is successfully processed without error.
TEST_F(SSLClientSocketTest, Read) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
+ EXPECT_EQ(0, transport->GetTotalReceivedBytes());
+
+ int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ SSLConfig()));
+ EXPECT_EQ(0, sock->GetTotalReceivedBytes());
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
- EXPECT_TRUE(sock->IsConnected());
+
+ // Number of network bytes received should increase because of SSL socket
+ // establishment.
+ EXPECT_GT(sock->GetTotalReceivedBytes(), 0);
const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
scoped_refptr<IOBuffer> request_buffer(
new IOBuffer(arraysize(request_text) - 1));
memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
- rv = sock->Write(
- request_buffer.get(), arraysize(request_text) - 1, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(sock->Write(
+ request_buffer.get(), arraysize(request_text) - 1, callback.callback()));
EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
- for (;;) {
- rv = sock->Read(buf.get(), 4096, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
+ int64_t unencrypted_bytes_read = 0;
+ int64_t network_bytes_read_during_handshake = sock->GetTotalReceivedBytes();
+ do {
+ rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback()));
EXPECT_GE(rv, 0);
- if (rv <= 0)
- break;
- }
+ if (rv >= 0) {
+ unencrypted_bytes_read += rv;
+ }
+ } while (rv > 0);
+ EXPECT_GT(unencrypted_bytes_read, 0);
+ // Reading the payload should increase the number of bytes on network layer.
+ EXPECT_GT(sock->GetTotalReceivedBytes(), network_bytes_read_during_handshake);
+ // Number of bytes received on the network after the handshake should be
+ // higher than the number of encrypted bytes read.
+ EXPECT_GE(sock->GetTotalReceivedBytes() - network_bytes_read_during_handshake,
+ unencrypted_bytes_read);
// The peer should have cleanly closed the connection with a close_notify.
EXPECT_EQ(0, rv);
@@ -1261,19 +1184,13 @@ TEST_F(SSLClientSocketTest, Read) {
// synchronously fails a transport read in during the handshake. The error code
// should be preserved so SSLv3 fallback logic can condition on it.
TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<SynchronousErrorStreamSocket> transport(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1283,7 +1200,8 @@ TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) {
SynchronousErrorStreamSocket* raw_transport = transport.get();
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ ssl_config));
raw_transport->SetNextWriteError(ERR_CONNECTION_RESET);
@@ -1297,19 +1215,13 @@ TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) {
// the socket connection uncleanly.
// This is a regression test for http://crbug.com/238536
TEST_F(SSLClientSocketTest, Read_WithSynchronousError) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<SynchronousErrorStreamSocket> transport(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1319,7 +1231,8 @@ TEST_F(SSLClientSocketTest, Read_WithSynchronousError) {
SynchronousErrorStreamSocket* raw_transport = transport.get();
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ ssl_config));
rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1352,24 +1265,18 @@ TEST_F(SSLClientSocketTest, Read_WithSynchronousError) {
// intermediary terminates the socket connection uncleanly.
// This is a regression test for http://crbug.com/249848
TEST_F(SSLClientSocketTest, Write_WithSynchronousError) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
// Note: |error_socket|'s ownership is handed to |transport|, but a pointer
// is retained in order to configure additional errors.
scoped_ptr<SynchronousErrorStreamSocket> error_socket(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
scoped_ptr<FakeBlockingStreamSocket> transport(
- new FakeBlockingStreamSocket(error_socket.Pass()));
+ new FakeBlockingStreamSocket(std::move(error_socket)));
FakeBlockingStreamSocket* raw_transport = transport.get();
int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1379,7 +1286,8 @@ TEST_F(SSLClientSocketTest, Write_WithSynchronousError) {
ssl_config.false_start_enabled = false;
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ ssl_config));
rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1424,24 +1332,18 @@ TEST_F(SSLClientSocketTest, Write_WithSynchronousError) {
// Write operation, SSLClientSocket should not spin attempting to re-write on
// the socket. This is a regression test for part of https://crbug.com/381160.
TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
// Note: intermediate sockets' ownership are handed to |sock|, but a pointer
// is retained in order to query them.
scoped_ptr<SynchronousErrorStreamSocket> error_socket(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
scoped_ptr<CountingStreamSocket> counting_socket(
- new CountingStreamSocket(error_socket.Pass()));
+ new CountingStreamSocket(std::move(error_socket)));
CountingStreamSocket* raw_counting_socket = counting_socket.get();
int rv = callback.GetResult(counting_socket->Connect(callback.callback()));
ASSERT_EQ(OK, rv);
@@ -1451,7 +1353,8 @@ TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) {
ssl_config.false_start_enabled = false;
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- counting_socket.Pass(), test_server.host_port_pair(), ssl_config));
+ std::move(counting_socket), spawned_test_server()->host_port_pair(),
+ ssl_config));
rv = callback.GetResult(sock->Connect(callback.callback()));
ASSERT_EQ(OK, rv);
@@ -1489,35 +1392,16 @@ TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) {
// Test the full duplex mode, with Read and Write pending at the same time.
// This test also serves as a regression test for http://crbug.com/29815.
TEST_F(SSLClientSocketTest, Read_FullDuplex) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback; // Used for everything except Write.
-
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
-
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(OK, rv);
- EXPECT_TRUE(sock->IsConnected());
// Issue a "hanging" Read first.
+ TestCompletionCallback callback;
scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
- rv = sock->Read(buf.get(), 4096, callback.callback());
+ rv = sock_->Read(buf.get(), 4096, callback.callback());
// We haven't written the request, so there should be no response yet.
ASSERT_EQ(ERR_IO_PENDING, rv);
@@ -1532,12 +1416,8 @@ TEST_F(SSLClientSocketTest, Read_FullDuplex) {
scoped_refptr<IOBuffer> request_buffer(new StringIOBuffer(request_text));
TestCompletionCallback callback2; // Used for Write only.
- rv = sock->Write(
- request_buffer.get(), request_text.size(), callback2.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback2.WaitForResult();
+ rv = callback2.GetResult(sock_->Write(
+ request_buffer.get(), request_text.size(), callback2.callback()));
EXPECT_EQ(static_cast<int>(request_text.size()), rv);
// Now get the Read result.
@@ -1552,24 +1432,18 @@ TEST_F(SSLClientSocketTest, Read_FullDuplex) {
// callback, the Write() callback should not be invoked.
// Regression test for http://crbug.com/232633
TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
// Note: |error_socket|'s ownership is handed to |transport|, but a pointer
// is retained in order to configure additional errors.
scoped_ptr<SynchronousErrorStreamSocket> error_socket(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
scoped_ptr<FakeBlockingStreamSocket> transport(
- new FakeBlockingStreamSocket(error_socket.Pass()));
+ new FakeBlockingStreamSocket(std::move(error_socket)));
FakeBlockingStreamSocket* raw_transport = transport.get();
int rv = callback.GetResult(transport->Connect(callback.callback()));
@@ -1580,7 +1454,8 @@ TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) {
ssl_config.false_start_enabled = false;
scoped_ptr<SSLClientSocket> sock = CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config);
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ ssl_config);
rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1666,24 +1541,18 @@ TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) {
// error in a SPDY socket.
// Regression test for http://crbug.com/335557
TEST_F(SSLClientSocketTest, Read_WithWriteError) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
// Note: |error_socket|'s ownership is handed to |transport|, but a pointer
// is retained in order to configure additional errors.
scoped_ptr<SynchronousErrorStreamSocket> error_socket(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
scoped_ptr<FakeBlockingStreamSocket> transport(
- new FakeBlockingStreamSocket(error_socket.Pass()));
+ new FakeBlockingStreamSocket(std::move(error_socket)));
FakeBlockingStreamSocket* raw_transport = transport.get();
int rv = callback.GetResult(transport->Connect(callback.callback()));
@@ -1694,7 +1563,8 @@ TEST_F(SSLClientSocketTest, Read_WithWriteError) {
ssl_config.false_start_enabled = false;
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ ssl_config));
rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1768,25 +1638,20 @@ TEST_F(SSLClientSocketTest, Read_WithWriteError) {
// Tests that SSLClientSocket fails the handshake if the underlying
// transport is cleanly closed.
TEST_F(SSLClientSocketTest, Connect_WithZeroReturn) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<SynchronousErrorStreamSocket> transport(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
SynchronousErrorStreamSocket* raw_transport = transport.get();
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ SSLConfig()));
raw_transport->SetNextReadError(0);
@@ -1799,19 +1664,13 @@ TEST_F(SSLClientSocketTest, Connect_WithZeroReturn) {
// is cleanly closed, but the peer does not send close_notify.
// This is a regression test for https://crbug.com/422246
TEST_F(SSLClientSocketTest, Read_WithZeroReturn) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<SynchronousErrorStreamSocket> transport(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1820,10 +1679,9 @@ TEST_F(SSLClientSocketTest, Read_WithZeroReturn) {
ssl_config.false_start_enabled = false;
SynchronousErrorStreamSocket* raw_transport = transport.get();
- scoped_ptr<SSLClientSocket> sock(
- CreateSSLClientSocket(transport.Pass(),
- test_server.host_port_pair(),
- ssl_config));
+ scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ ssl_config));
rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1839,22 +1697,16 @@ TEST_F(SSLClientSocketTest, Read_WithZeroReturn) {
// underlying socket is cleanly closed asynchronously.
// This is a regression test for https://crbug.com/422246
TEST_F(SSLClientSocketTest, Read_WithAsyncZeroReturn) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<SynchronousErrorStreamSocket> error_socket(
- new SynchronousErrorStreamSocket(real_transport.Pass()));
+ new SynchronousErrorStreamSocket(std::move(real_transport)));
SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
scoped_ptr<FakeBlockingStreamSocket> transport(
- new FakeBlockingStreamSocket(error_socket.Pass()));
+ new FakeBlockingStreamSocket(std::move(error_socket)));
FakeBlockingStreamSocket* raw_transport = transport.get();
int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1863,10 +1715,9 @@ TEST_F(SSLClientSocketTest, Read_WithAsyncZeroReturn) {
SSLConfig ssl_config;
ssl_config.false_start_enabled = false;
- scoped_ptr<SSLClientSocket> sock(
- CreateSSLClientSocket(transport.Pass(),
- test_server.host_port_pair(),
- ssl_config));
+ scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ ssl_config));
rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
@@ -1890,44 +1741,22 @@ TEST_F(SSLClientSocketTest, Read_WithFatalAlert) {
ssl_options.alert_after_handshake = true;
ASSERT_TRUE(StartTestServer(ssl_options));
- SSLConfig ssl_config;
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), ssl_config));
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
+ EXPECT_EQ(OK, rv);
// Receive the fatal alert.
+ TestCompletionCallback callback;
scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
- EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.GetResult(sock->Read(
+ EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.GetResult(sock_->Read(
buf.get(), 4096, callback.callback())));
}
TEST_F(SSLClientSocketTest, Read_SmallChunks) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(OK, rv);
const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
@@ -1935,49 +1764,34 @@ TEST_F(SSLClientSocketTest, Read_SmallChunks) {
new IOBuffer(arraysize(request_text) - 1));
memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
- rv = sock->Write(
- request_buffer.get(), arraysize(request_text) - 1, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ TestCompletionCallback callback;
+ rv = callback.GetResult(sock_->Write(
+ request_buffer.get(), arraysize(request_text) - 1, callback.callback()));
EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
scoped_refptr<IOBuffer> buf(new IOBuffer(1));
- for (;;) {
- rv = sock->Read(buf.get(), 1, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
+ do {
+ rv = callback.GetResult(sock_->Read(buf.get(), 1, callback.callback()));
EXPECT_GE(rv, 0);
- if (rv <= 0)
- break;
- }
+ } while (rv > 0);
}
TEST_F(SSLClientSocketTest, Read_ManySmallRecords) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<ReadBufferingStreamSocket> transport(
- new ReadBufferingStreamSocket(real_transport.Pass()));
+ new ReadBufferingStreamSocket(std::move(real_transport)));
ReadBufferingStreamSocket* raw_transport = transport.get();
int rv = callback.GetResult(transport->Connect(callback.callback()));
ASSERT_EQ(OK, rv);
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ SSLConfig()));
rv = callback.GetResult(sock->Connect(callback.callback()));
ASSERT_EQ(OK, rv);
@@ -2010,28 +1824,10 @@ TEST_F(SSLClientSocketTest, Read_ManySmallRecords) {
}
TEST_F(SSLClientSocketTest, Read_Interrupted) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(OK, rv);
const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
@@ -2039,50 +1835,33 @@ TEST_F(SSLClientSocketTest, Read_Interrupted) {
new IOBuffer(arraysize(request_text) - 1));
memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
- rv = sock->Write(
- request_buffer.get(), arraysize(request_text) - 1, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ TestCompletionCallback callback;
+ rv = callback.GetResult(sock_->Write(
+ request_buffer.get(), arraysize(request_text) - 1, callback.callback()));
EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
// Do a partial read and then exit. This test should not crash!
scoped_refptr<IOBuffer> buf(new IOBuffer(512));
- rv = sock->Read(buf.get(), 512, callback.callback());
- EXPECT_TRUE(rv > 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
+ rv = callback.GetResult(sock_->Read(buf.get(), 512, callback.callback()));
EXPECT_GT(rv, 0);
}
TEST_F(SSLClientSocketTest, Read_FullLogging) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
TestNetLog log;
log.SetCaptureMode(NetLogCaptureMode::IncludeSocketBytes());
scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ new TCPClientSocket(addr(), &log, NetLog::Source()));
+ int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ SSLConfig()));
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
EXPECT_TRUE(sock->IsConnected());
@@ -2091,12 +1870,8 @@ TEST_F(SSLClientSocketTest, Read_FullLogging) {
new IOBuffer(arraysize(request_text) - 1));
memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
- rv = sock->Write(
- request_buffer.get(), arraysize(request_text) - 1, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(sock->Write(
+ request_buffer.get(), arraysize(request_text) - 1, callback.callback()));
EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
TestNetLogEntry::List entries;
@@ -2106,12 +1881,7 @@ TEST_F(SSLClientSocketTest, Read_FullLogging) {
scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
for (;;) {
- rv = sock->Read(buf.get(), 4096, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
+ rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback()));
EXPECT_GE(rv, 0);
if (rv <= 0)
break;
@@ -2127,13 +1897,7 @@ TEST_F(SSLClientSocketTest, Read_FullLogging) {
// Regression test for http://crbug.com/42538
TEST_F(SSLClientSocketTest, PrematureApplicationData) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- TestCompletionCallback callback;
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
static const unsigned char application_data[] = {
0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b,
@@ -2156,19 +1920,17 @@ TEST_F(SSLClientSocketTest, PrematureApplicationData) {
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
+ TestCompletionCallback callback;
scoped_ptr<StreamSocket> transport(
- new MockTCPClientSocket(addr, NULL, &data));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ new MockTCPClientSocket(addr(), NULL, &data));
+ int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ SSLConfig()));
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
}
@@ -2176,7 +1938,7 @@ TEST_F(SSLClientSocketTest, CipherSuiteDisables) {
// Rather than exhaustively disabling every AES_128_CBC ciphersuite defined at
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml, only
// disabling those cipher suites that the test server actually implements.
- const uint16 kCiphersToDisable[] = {
+ const uint16_t kCiphersToDisable[] = {
0x002f, // TLS_RSA_WITH_AES_128_CBC_SHA
0x0033, // TLS_DHE_RSA_WITH_AES_128_CBC_SHA
0xc013, // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
@@ -2185,58 +1947,15 @@ TEST_F(SSLClientSocketTest, CipherSuiteDisables) {
SpawnedTestServer::SSLOptions ssl_options;
// Enable only AES_128_CBC on the test server.
ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128;
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- TestNetLog log;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ ASSERT_TRUE(StartTestServer(ssl_options));
SSLConfig ssl_config;
for (size_t i = 0; i < arraysize(kCiphersToDisable); ++i)
ssl_config.disabled_cipher_suites.push_back(kCiphersToDisable[i]);
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
-
- EXPECT_FALSE(sock->IsConnected());
-
- rv = sock->Connect(callback.callback());
- TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
- // The exact ordering depends no whether an extra read is issued. Just check
- // the error is somewhere in the log.
- log.GetEntries(&entries);
- ExpectLogContainsSomewhere(
- entries, 0, NetLog::TYPE_SSL_HANDSHAKE_ERROR, NetLog::PHASE_NONE);
-
- // We cannot test sock->IsConnected(), as the NSS implementation disconnects
- // the socket when it encounters an error, whereas other implementations
- // leave it connected.
- // Because this an error that the test server is mutually aware of, as opposed
- // to being an error such as a certificate name mismatch, which is
- // client-only, the exact index of the SSL connect end depends on how
- // quickly the test server closes the underlying socket. If the test server
- // closes before the IO message loop pumps messages, there may be a 0-byte
- // Read event in the NetLog due to TCPClientSocket picking up the EOF. As a
- // result, the SSL connect end event will be the second-to-last entry,
- // rather than the last entry.
- EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SSL_CONNECT) ||
- LogContainsEndEvent(entries, -2, NetLog::TYPE_SSL_CONNECT));
}
// When creating an SSLClientSocket, it is allowed to pass in a
@@ -2244,93 +1963,64 @@ TEST_F(SSLClientSocketTest, CipherSuiteDisables) {
// Here we verify that such a simple ClientSocketHandle, not associated with any
// client socket pool, can be destroyed safely.
TEST_F(SSLClientSocketTest, ClientSocketHandleNotFromPool) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
+ int rv = callback.GetResult(transport->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle());
- socket_handle->SetSocket(transport.Pass());
+ socket_handle->SetSocket(std::move(transport));
scoped_ptr<SSLClientSocket> sock(socket_factory_->CreateSSLClientSocket(
- socket_handle.Pass(), test_server.host_port_pair(), SSLConfig(),
- context_));
+ std::move(socket_handle), spawned_test_server()->host_port_pair(),
+ SSLConfig(), context_));
EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(sock->Connect(callback.callback()));
EXPECT_EQ(OK, rv);
}
// Verifies that SSLClientSocket::ExportKeyingMaterial return a success
// code and different keying label results in different keying material.
TEST_F(SSLClientSocketTest, ExportKeyingMaterial) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
-
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
-
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(OK, rv);
- EXPECT_TRUE(sock->IsConnected());
+ EXPECT_TRUE(sock_->IsConnected());
const int kKeyingMaterialSize = 32;
const char kKeyingLabel1[] = "client-socket-test-1";
const char kKeyingContext1[] = "";
unsigned char client_out1[kKeyingMaterialSize];
memset(client_out1, 0, sizeof(client_out1));
- rv = sock->ExportKeyingMaterial(kKeyingLabel1, false, kKeyingContext1,
- client_out1, sizeof(client_out1));
+ rv = sock_->ExportKeyingMaterial(kKeyingLabel1, false, kKeyingContext1,
+ client_out1, sizeof(client_out1));
EXPECT_EQ(rv, OK);
const char kKeyingLabel2[] = "client-socket-test-2";
unsigned char client_out2[kKeyingMaterialSize];
memset(client_out2, 0, sizeof(client_out2));
- rv = sock->ExportKeyingMaterial(kKeyingLabel2, false, kKeyingContext1,
- client_out2, sizeof(client_out2));
+ rv = sock_->ExportKeyingMaterial(kKeyingLabel2, false, kKeyingContext1,
+ client_out2, sizeof(client_out2));
EXPECT_EQ(rv, OK);
EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
const char kKeyingContext2[] = "context";
- rv = sock->ExportKeyingMaterial(kKeyingLabel1, true, kKeyingContext2,
- client_out2, sizeof(client_out2));
+ rv = sock_->ExportKeyingMaterial(kKeyingLabel1, true, kKeyingContext2,
+ client_out2, sizeof(client_out2));
EXPECT_EQ(rv, OK);
EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
// Using an empty context should give different key material from not using a
// context at all.
memset(client_out2, 0, sizeof(client_out2));
- rv = sock->ExportKeyingMaterial(kKeyingLabel1, true, kKeyingContext1,
- client_out2, sizeof(client_out2));
+ rv = sock_->ExportKeyingMaterial(kKeyingLabel1, true, kKeyingContext1,
+ client_out2, sizeof(client_out2));
EXPECT_EQ(rv, OK);
EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
}
@@ -2379,28 +2069,12 @@ TEST_F(SSLClientSocketTest, VerifyServerChainProperlyOrdered) {
// intermediate certificates.
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- rv = callback.GetResult(rv);
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
- EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(callback.callback());
- rv = callback.GetResult(rv);
+ ASSERT_TRUE(StartTestServer(ssl_options));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(ERR_CERT_INVALID, rv);
- EXPECT_TRUE(sock->IsConnected());
+ EXPECT_TRUE(sock_->IsConnected());
// When given option CERT_CHAIN_WRONG_ROOT, SpawnedTestServer will present
// certs from redundant-server-chain.pem.
@@ -2411,7 +2085,7 @@ TEST_F(SSLClientSocketTest, VerifyServerChainProperlyOrdered) {
// Get the server certificate as received client side.
SSLInfo ssl_info;
- ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
scoped_refptr<X509Certificate> server_certificate = ssl_info.unverified_cert;
// Get the intermediates as received client side.
@@ -2434,8 +2108,8 @@ TEST_F(SSLClientSocketTest, VerifyServerChainProperlyOrdered) {
EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[2],
server_certs[3]->os_cert_handle()));
- sock->Disconnect();
- EXPECT_FALSE(sock->IsConnected());
+ sock_->Disconnect();
+ EXPECT_FALSE(sock_->IsConnected());
}
// This tests that SSLInfo contains a properly re-constructed certificate
@@ -2488,42 +2162,19 @@ TEST_F(SSLClientSocketTest, VerifyReturnChainProperlyOrdered) {
// Set up a test server with CERT_CHAIN_WRONG_ROOT.
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(ssl_options));
- TestCompletionCallback callback;
- TestNetLog log;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
- EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(callback.callback());
+ EXPECT_TRUE(sock_->IsConnected());
TestNetLogEntry::List entries;
- log.GetEntries(&entries);
- EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
-
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(sock->IsConnected());
- log.GetEntries(&entries);
+ log_.GetEntries(&entries);
EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SSL_CONNECT));
SSLInfo ssl_info;
- sock->GetSSLInfo(&ssl_info);
+ sock_->GetSSLInfo(&ssl_info);
// Verify that SSLInfo contains the corrected re-constructed chain A -> B
// -> C2.
@@ -2550,8 +2201,8 @@ TEST_F(SSLClientSocketTest, VerifyReturnChainProperlyOrdered) {
EXPECT_TRUE(X509Certificate::IsSameOSCert(
served_intermediates[2], unverified_certs[3]->os_cert_handle()));
- sock->Disconnect();
- EXPECT_FALSE(sock->IsConnected());
+ sock_->Disconnect();
+ EXPECT_FALSE(sock_->IsConnected());
}
TEST_F(SSLClientSocketCertRequestInfoTest, NoAuthorities) {
@@ -2624,19 +2275,7 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) {
SpawnedTestServer::SSLOptions ssl_options;
ssl_options.signed_cert_timestamps_tls_ext = "test";
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log_, NetLog::Source()));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_EQ(OK, rv);
+ ASSERT_TRUE(StartTestServer(ssl_options));
SSLConfig ssl_config;
ssl_config.signed_cert_timestamps_enabled = true;
@@ -2648,26 +2287,109 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) {
EXPECT_CALL(ct_verifier, Verify(_, "", "test", _, _)).WillRepeatedly(
Return(ERR_CT_NO_SCTS_VERIFIED_OK));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
- rv = callback.GetResult(sock->Connect(callback.callback()));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+
+ EXPECT_TRUE(sock_->signed_cert_timestamps_received_);
+}
+
+// Test that when an EV certificate is received, but no CT verifier
+// or certificate policy enforcer are defined, then the EV status
+// of the certificate is maintained.
+TEST_F(SSLClientSocketTest, EVCertStatusMaintainedNoCTVerifier) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ASSERT_TRUE(StartTestServer(ssl_options));
+
+ SSLConfig ssl_config;
+ AddServerCertStatusToSSLConfig(CERT_STATUS_IS_EV, &ssl_config);
+
+ // No verifier to skip CT and policy checks.
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+
+ SSLInfo result;
+ ASSERT_TRUE(sock_->GetSSLInfo(&result));
+
+ EXPECT_TRUE(result.cert_status & CERT_STATUS_IS_EV);
+}
+
+// Test that when a CT verifier and a CTPolicyEnforcer are defined, and
+// the EV certificate used conforms to the CT/EV policy, its EV status
+// is maintained.
+TEST_F(SSLClientSocketTest, EVCertStatusMaintainedForCompliantCert) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ASSERT_TRUE(StartTestServer(ssl_options));
+
+ SSLConfig ssl_config;
+ AddServerCertStatusToSSLConfig(CERT_STATUS_IS_EV, &ssl_config);
+
+ // To activate the CT/EV policy enforcement non-null CTVerifier and
+ // CTPolicyEnforcer are needed.
+ MockCTVerifier ct_verifier;
+ SetCTVerifier(&ct_verifier);
+ EXPECT_CALL(ct_verifier, Verify(_, "", "", _, _)).WillRepeatedly(Return(OK));
+
+ // Emulate compliance of the certificate to the policy.
+ MockCTPolicyEnforcer policy_enforcer;
+ SetCTPolicyEnforcer(&policy_enforcer);
+ EXPECT_CALL(policy_enforcer, DoesConformToCTEVPolicy(_, _, _, _))
+ .WillRepeatedly(Return(true));
+
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
EXPECT_EQ(OK, rv);
- EXPECT_TRUE(sock->signed_cert_timestamps_received_);
+ SSLInfo result;
+ ASSERT_TRUE(sock_->GetSSLInfo(&result));
+
+ EXPECT_TRUE(result.cert_status & CERT_STATUS_IS_EV);
+}
+
+// Test that when a CT verifier and a CTPolicyEnforcer are defined, but
+// the EV certificate used does not conform to the CT/EV policy, its EV status
+// is removed.
+TEST_F(SSLClientSocketTest, EVCertStatusRemovedForNonCompliantCert) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ASSERT_TRUE(StartTestServer(ssl_options));
+
+ SSLConfig ssl_config;
+ AddServerCertStatusToSSLConfig(CERT_STATUS_IS_EV, &ssl_config);
+
+ // To activate the CT/EV policy enforcement non-null CTVerifier and
+ // CTPolicyEnforcer are needed.
+ MockCTVerifier ct_verifier;
+ SetCTVerifier(&ct_verifier);
+ EXPECT_CALL(ct_verifier, Verify(_, "", "", _, _)).WillRepeatedly(Return(OK));
+
+ // Emulate non-compliance of the certificate to the policy.
+ MockCTPolicyEnforcer policy_enforcer;
+ SetCTPolicyEnforcer(&policy_enforcer);
+ EXPECT_CALL(policy_enforcer, DoesConformToCTEVPolicy(_, _, _, _))
+ .WillRepeatedly(Return(false));
+
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+
+ SSLInfo result;
+ ASSERT_TRUE(sock_->GetSSLInfo(&result));
+
+ EXPECT_FALSE(result.cert_status & CERT_STATUS_IS_EV);
+ EXPECT_TRUE(result.cert_status & CERT_STATUS_CT_COMPLIANCE_FAILED);
}
namespace {
bool IsValidOCSPResponse(const base::StringPiece& input) {
- base::StringPiece ocsp_response = input;
- base::StringPiece sequence, response_status, response_bytes;
- return asn1::GetElement(&ocsp_response, asn1::kSEQUENCE, &sequence) &&
- ocsp_response.empty() &&
- asn1::GetElement(&sequence, asn1::kENUMERATED, &response_status) &&
- asn1::GetElement(&sequence,
- asn1::kContextSpecific | asn1::kConstructed | 0,
- &response_status) &&
- sequence.empty();
+ der::Parser parser((der::Input(input)));
+ der::Parser sequence;
+ return parser.ReadSequence(&sequence) && !parser.HasMore() &&
+ sequence.SkipTag(der::kEnumerated) &&
+ sequence.SkipTag(der::kTagContextSpecific | der::kTagConstructed |
+ 0) &&
+ !sequence.HasMore();
}
} // namespace
@@ -2680,19 +2402,7 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) {
// for a freshly minted certificate.
ssl_options.server_certificate = SpawnedTestServer::SSLOptions::CERT_AUTO;
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log_, NetLog::Source()));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_EQ(OK, rv);
+ ASSERT_TRUE(StartTestServer(ssl_options));
SSLConfig ssl_config;
// Enabling Signed Cert Timestamps ensures we request OCSP stapling for
@@ -2712,90 +2422,55 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) {
Verify(_, Truly(IsValidOCSPResponse), "", _, _)).WillRepeatedly(
Return(ERR_CT_NO_SCTS_VERIFIED_OK));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
- rv = callback.GetResult(sock->Connect(callback.callback()));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
EXPECT_EQ(OK, rv);
- EXPECT_TRUE(sock->stapled_ocsp_response_received_);
+ EXPECT_TRUE(sock_->stapled_ocsp_response_received_);
}
TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsDisabled) {
SpawnedTestServer::SSLOptions ssl_options;
ssl_options.signed_cert_timestamps_tls_ext = "test";
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
-
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log_, NetLog::Source()));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_EQ(OK, rv);
+ ASSERT_TRUE(StartTestServer(ssl_options));
SSLConfig ssl_config;
ssl_config.signed_cert_timestamps_enabled = false;
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), ssl_config));
- rv = callback.GetResult(sock->Connect(callback.callback()));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
EXPECT_EQ(OK, rv);
- EXPECT_FALSE(sock->signed_cert_timestamps_received_);
+ EXPECT_FALSE(sock_->signed_cert_timestamps_received_);
}
// Tests that IsConnectedAndIdle and WasEverUsed behave as expected.
TEST_F(SSLClientSocketTest, ReuseStates) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
-
- rv = sock->Connect(callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
// The socket was just connected. It should be idle because it is speaking
// HTTP. Although the transport has been used for the handshake, WasEverUsed()
// returns false.
- EXPECT_TRUE(sock->IsConnected());
- EXPECT_TRUE(sock->IsConnectedAndIdle());
- EXPECT_FALSE(sock->WasEverUsed());
+ EXPECT_TRUE(sock_->IsConnected());
+ EXPECT_TRUE(sock_->IsConnectedAndIdle());
+ EXPECT_FALSE(sock_->WasEverUsed());
const char kRequestText[] = "GET / HTTP/1.0\r\n\r\n";
const size_t kRequestLen = arraysize(kRequestText) - 1;
scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestLen));
memcpy(request_buffer->data(), kRequestText, kRequestLen);
- rv = sock->Write(request_buffer.get(), kRequestLen, callback.callback());
- EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
-
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ TestCompletionCallback callback;
+ rv = callback.GetResult(
+ sock_->Write(request_buffer.get(), kRequestLen, callback.callback()));
EXPECT_EQ(static_cast<int>(kRequestLen), rv);
// The socket has now been used.
- EXPECT_TRUE(sock->WasEverUsed());
+ EXPECT_TRUE(sock_->WasEverUsed());
// TODO(davidben): Read one byte to ensure the test server has responded and
// then assert IsConnectedAndIdle is false. This currently doesn't work
@@ -2809,24 +2484,19 @@ TEST_F(SSLClientSocketTest, ReuseStates) {
// been flushed completely out of SSLClientSocket's internal buffers. This is a
// regression test for https://crbug.com/466147.
TEST_F(SSLClientSocketTest, ReusableAfterWrite) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
-
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
TestCompletionCallback callback;
scoped_ptr<StreamSocket> real_transport(
- new TCPClientSocket(addr, NULL, NetLog::Source()));
+ new TCPClientSocket(addr(), NULL, NetLog::Source()));
scoped_ptr<FakeBlockingStreamSocket> transport(
- new FakeBlockingStreamSocket(real_transport.Pass()));
+ new FakeBlockingStreamSocket(std::move(real_transport)));
FakeBlockingStreamSocket* raw_transport = transport.get();
ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), SSLConfig()));
+ std::move(transport), spawned_test_server()->host_port_pair(),
+ SSLConfig()));
ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
// Block any application data from reaching the network.
@@ -2858,44 +2528,38 @@ TEST_F(SSLClientSocketTest, SessionResumption) {
// First, perform a full handshake.
SSLConfig ssl_config;
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), ssl_config));
- ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ ASSERT_EQ(OK, rv);
SSLInfo ssl_info;
- ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
// The next connection should resume.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ ASSERT_EQ(OK, rv);
+ ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
+ sock_.reset();
// Using a different HostPortPair uses a different session cache key.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
+ scoped_ptr<StreamSocket> transport(
+ new TCPClientSocket(addr(), &log_, NetLog::Source()));
+ TestCompletionCallback callback;
ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- HostPortPair("example.com", 443), ssl_config);
+ scoped_ptr<SSLClientSocket> sock = CreateSSLClientSocket(
+ std::move(transport), HostPortPair("example.com", 443), ssl_config);
ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
+ sock.reset();
SSLClientSocket::ClearSessionCache();
// After clearing the session cache, the next handshake doesn't resume.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ ASSERT_EQ(OK, rv);
+ ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
}
@@ -2908,32 +2572,23 @@ TEST_F(SSLClientSocketTest, CertificateErrorNoResume) {
cert_verifier_->set_default_result(ERR_CERT_COMMON_NAME_INVALID);
SSLConfig ssl_config;
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), ssl_config));
- EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID,
- callback.GetResult(sock->Connect(callback.callback())));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ ASSERT_EQ(ERR_CERT_COMMON_NAME_INVALID, rv);
cert_verifier_->set_default_result(OK);
// The next connection should perform a full handshake.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ ASSERT_EQ(OK, rv);
SSLInfo ssl_info;
- ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
}
// Tests that session caches are sharded by max_version.
TEST_F(SSLClientSocketTest, FallbackShardSessionCache) {
- SpawnedTestServer::SSLOptions ssl_options;
- ASSERT_TRUE(StartTestServer(ssl_options));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
// Prepare a normal and fallback SSL config.
SSLConfig ssl_config;
@@ -2944,30 +2599,21 @@ TEST_F(SSLClientSocketTest, FallbackShardSessionCache) {
// Connect with a fallback config from the test server to add an entry to the
// session cache.
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), fallback_ssl_config));
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(fallback_ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
SSLInfo ssl_info;
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1,
SSLConnectionStatusToVersion(ssl_info.connection_status));
// A non-fallback connection needs a full handshake.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- // This does not check for equality because TLS 1.2 support is conditional on
- // system NSS features.
- EXPECT_LT(SSL_CONNECTION_VERSION_TLS1,
+ EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_2,
SSLConnectionStatusToVersion(ssl_info.connection_status));
// Note: if the server (correctly) declines to resume a TLS 1.0 session at TLS
@@ -2976,12 +2622,9 @@ TEST_F(SSLClientSocketTest, FallbackShardSessionCache) {
// attempt to resume with two more connections.
// The non-fallback connection added a > TLS 1.0 entry to the session cache.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
// This does not check for equality because TLS 1.2 support is conditional on
// system NSS features.
@@ -2991,112 +2634,111 @@ TEST_F(SSLClientSocketTest, FallbackShardSessionCache) {
// The fallback connection still resumes from its session cache. It cannot
// offer the > TLS 1.0 session, so this must have been the session from the
// first fallback connection.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), fallback_ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(fallback_ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1,
SSLConnectionStatusToVersion(ssl_info.connection_status));
}
-// Test that RC4 is only enabled if enable_deprecated_cipher_suites is set.
-TEST_F(SSLClientSocketTest, DeprecatedRC4) {
+// Test that RC4 is only enabled if rc4_enabled and
+// deprecated_cipher_suites_enabled are both set.
+TEST_F(SSLClientSocketTest, RC4Enabled) {
SpawnedTestServer::SSLOptions ssl_options;
ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_RC4;
ASSERT_TRUE(StartTestServer(ssl_options));
// Normal handshakes with RC4 do not work.
SSLConfig ssl_config;
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), ssl_config));
- ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH,
- callback.GetResult(sock->Connect(callback.callback())));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
+
+ // RC4 is also not enabled in the fallback handshake.
+ ssl_config.deprecated_cipher_suites_enabled = true;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
+
+ // Even if RC4 is enabled, it is not sent in the initial handshake.
+ ssl_config.deprecated_cipher_suites_enabled = false;
+ ssl_config.rc4_enabled = true;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
+
+ // If enabled, RC4 works in the fallback handshake.
+ ssl_config.deprecated_cipher_suites_enabled = true;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+}
+
+// Test that DHE is only enabled if deprecated_cipher_suites_enabled is set.
+TEST_F(SSLClientSocketTest, DHEDeprecated) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ssl_options.key_exchanges =
+ SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
+ ASSERT_TRUE(StartTestServer(ssl_options));
+
+ // Normal handshakes with DHE do not work.
+ SSLConfig ssl_config;
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
// Enabling deprecated ciphers works fine.
- ssl_config.enable_deprecated_cipher_suites = true;
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- ASSERT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- ASSERT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
+ ssl_config.deprecated_cipher_suites_enabled = true;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
}
// Tests that enabling deprecated ciphers shards the session cache.
TEST_F(SSLClientSocketTest, DeprecatedShardSessionCache) {
- SpawnedTestServer::SSLOptions ssl_options;
- ASSERT_TRUE(StartTestServer(ssl_options));
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
// Prepare a normal and deprecated SSL config.
SSLConfig ssl_config;
SSLConfig deprecated_ssl_config;
- deprecated_ssl_config.enable_deprecated_cipher_suites = true;
+ deprecated_ssl_config.deprecated_cipher_suites_enabled = true;
// Connect with deprecated ciphers enabled to warm the session cache cache.
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock(
- CreateSSLClientSocket(transport.Pass(), test_server()->host_port_pair(),
- deprecated_ssl_config));
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(deprecated_ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
SSLInfo ssl_info;
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
// Test that re-connecting with deprecated ciphers enabled still resumes.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), deprecated_ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(deprecated_ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
// However, a normal connection needs a full handshake.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
// Clear the session cache for the inverse test.
SSLClientSocket::ClearSessionCache();
// Now make a normal connection to prime the session cache.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
// A normal connection should be able to resume.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(transport.Pass(),
- test_server()->host_port_pair(), ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
// However, enabling deprecated ciphers connects fresh.
- transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback())));
- sock = CreateSSLClientSocket(
- transport.Pass(), test_server()->host_port_pair(), deprecated_ssl_config);
- EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback())));
- EXPECT_TRUE(sock->GetSSLInfo(&ssl_info));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(deprecated_ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
}
@@ -3104,33 +2746,65 @@ TEST_F(SSLClientSocketTest, RequireECDHE) {
// Run test server without ECDHE.
SpawnedTestServer::SSLOptions ssl_options;
ssl_options.key_exchanges = SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA;
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, ssl_options,
- base::FilePath());
- ASSERT_TRUE(test_server.Start());
+ ASSERT_TRUE(StartTestServer(ssl_options));
+
+ SSLConfig config;
+ config.require_ecdhe = true;
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
+ EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
+}
- AddressList addr;
- ASSERT_TRUE(test_server.GetAddressList(&addr));
+TEST_F(SSLClientSocketTest, TokenBindingEnabled) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ssl_options.supported_token_binding_params.push_back(TB_PARAM_ECDSAP256);
+ ASSERT_TRUE(StartTestServer(ssl_options));
- TestCompletionCallback callback;
- TestNetLog log;
- scoped_ptr<StreamSocket> transport(
- new TCPClientSocket(addr, &log, NetLog::Source()));
- int rv = transport->Connect(callback.callback());
- rv = callback.GetResult(rv);
+ SSLConfig ssl_config;
+ ssl_config.token_binding_params.push_back(TB_PARAM_ECDSAP256);
+
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
EXPECT_EQ(OK, rv);
+ SSLInfo info;
+ EXPECT_TRUE(sock_->GetSSLInfo(&info));
+ EXPECT_TRUE(info.token_binding_negotiated);
+ EXPECT_EQ(TB_PARAM_ECDSAP256, info.token_binding_key_param);
+}
- SSLConfig config;
- config.require_ecdhe = true;
+TEST_F(SSLClientSocketTest, TokenBindingFailsWithEmsDisabled) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ssl_options.supported_token_binding_params.push_back(TB_PARAM_ECDSAP256);
+ ssl_options.disable_extended_master_secret = true;
+ ASSERT_TRUE(StartTestServer(ssl_options));
- scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- transport.Pass(), test_server.host_port_pair(), config));
+ SSLConfig ssl_config;
+ ssl_config.token_binding_params.push_back(TB_PARAM_ECDSAP256);
- rv = sock->Connect(callback.callback());
- rv = callback.GetResult(rv);
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
+}
- EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv);
+TEST_F(SSLClientSocketTest, TokenBindingEnabledWithoutServerSupport) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ASSERT_TRUE(StartTestServer(ssl_options));
+
+ SSLConfig ssl_config;
+ ssl_config.token_binding_params.push_back(TB_PARAM_ECDSAP256);
+
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_EQ(OK, rv);
+ SSLInfo info;
+ EXPECT_TRUE(sock_->GetSSLInfo(&info));
+ EXPECT_FALSE(info.token_binding_negotiated);
}
+// In tests requiring NPN, client_config.alpn_protos and
+// client_config.npn_protos both need to be set when using NSS, otherwise NPN is
+// disabled due to quirks of the implementation.
+
TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) {
// False Start requires NPN/ALPN, ECDHE, and an AEAD.
SpawnedTestServer::SSLOptions server_options;
@@ -3140,7 +2814,10 @@ TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) {
SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM;
server_options.npn_protocols.push_back(std::string("http/1.1"));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
ASSERT_NO_FATAL_FAILURE(
TestFalseStart(server_options, client_config, true));
}
@@ -3153,7 +2830,8 @@ TEST_F(SSLClientSocketFalseStartTest, NoNPN) {
server_options.bulk_ciphers =
SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM;
SSLConfig client_config;
- client_config.next_protos.clear();
+ client_config.alpn_protos.clear();
+ client_config.npn_protos.clear();
ASSERT_NO_FATAL_FAILURE(
TestFalseStart(server_options, client_config, false));
}
@@ -3167,7 +2845,10 @@ TEST_F(SSLClientSocketFalseStartTest, RSA) {
SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM;
server_options.npn_protocols.push_back(std::string("http/1.1"));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
ASSERT_NO_FATAL_FAILURE(
TestFalseStart(server_options, client_config, false));
}
@@ -3181,7 +2862,12 @@ TEST_F(SSLClientSocketFalseStartTest, DHE_RSA) {
SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM;
server_options.npn_protocols.push_back(std::string("http/1.1"));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
+ // DHE is only advertised when deprecated ciphers are enabled.
+ client_config.deprecated_cipher_suites_enabled = true;
ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, false));
}
@@ -3194,7 +2880,10 @@ TEST_F(SSLClientSocketFalseStartTest, NoAEAD) {
SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128;
server_options.npn_protocols.push_back(std::string("http/1.1"));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, false));
}
@@ -3208,25 +2897,23 @@ TEST_F(SSLClientSocketFalseStartTest, SessionResumption) {
SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM;
server_options.npn_protocols.push_back(std::string("http/1.1"));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
// Let a full handshake complete with False Start.
ASSERT_NO_FATAL_FAILURE(
TestFalseStart(server_options, client_config, true));
// Make a second connection.
- TestCompletionCallback callback;
- scoped_ptr<StreamSocket> transport2(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
- transport2.Pass(), test_server()->host_port_pair(), client_config);
- ASSERT_TRUE(sock2.get());
- EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
+ EXPECT_EQ(OK, rv);
// It should resume the session.
SSLInfo ssl_info;
- EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
}
@@ -3243,7 +2930,10 @@ TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinished) {
ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
// Start a handshake up to the server Finished message.
TestCompletionCallback callback;
@@ -3274,17 +2964,13 @@ TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinished) {
sock1.reset();
// Start a second connection.
- scoped_ptr<StreamSocket> transport2(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
- transport2.Pass(), test_server()->host_port_pair(), client_config);
- EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
+ EXPECT_EQ(OK, rv);
// No session resumption because the first connection never received a server
// Finished message.
SSLInfo ssl_info;
- EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
}
@@ -3301,7 +2987,10 @@ TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBadFinished) {
ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
// Start a handshake up to the server Finished message.
TestCompletionCallback callback;
@@ -3341,17 +3030,13 @@ TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBadFinished) {
sock1.reset();
// Start a second connection.
- scoped_ptr<StreamSocket> transport2(
- new TCPClientSocket(addr(), &log_, NetLog::Source()));
- EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback())));
- scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket(
- transport2.Pass(), test_server()->host_port_pair(), client_config);
- EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback())));
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
+ EXPECT_EQ(OK, rv);
// No session resumption because the first connection never received a server
// Finished message.
SSLInfo ssl_info;
- EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
}
@@ -3359,7 +3044,7 @@ TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBadFinished) {
TEST_F(SSLClientSocketChannelIDTest, SendChannelID) {
SpawnedTestServer::SSLOptions ssl_options;
- ASSERT_TRUE(ConnectToTestServer(ssl_options));
+ ASSERT_TRUE(StartTestServer(ssl_options));
EnableChannelID();
SSLConfig ssl_config;
@@ -3383,7 +3068,7 @@ TEST_F(SSLClientSocketChannelIDTest, SendChannelID) {
TEST_F(SSLClientSocketChannelIDTest, FailingChannelID) {
SpawnedTestServer::SSLOptions ssl_options;
- ASSERT_TRUE(ConnectToTestServer(ssl_options));
+ ASSERT_TRUE(StartTestServer(ssl_options));
EnableFailingChannelID();
SSLConfig ssl_config;
@@ -3405,7 +3090,7 @@ TEST_F(SSLClientSocketChannelIDTest, FailingChannelID) {
TEST_F(SSLClientSocketChannelIDTest, FailingChannelIDAsync) {
SpawnedTestServer::SSLOptions ssl_options;
- ASSERT_TRUE(ConnectToTestServer(ssl_options));
+ ASSERT_TRUE(StartTestServer(ssl_options));
EnableAsyncFailingChannelID();
SSLConfig ssl_config;
@@ -3418,15 +3103,45 @@ TEST_F(SSLClientSocketChannelIDTest, FailingChannelIDAsync) {
EXPECT_FALSE(sock_->IsConnected());
}
+// Tests that session caches are sharded by whether Channel ID is enabled.
+TEST_F(SSLClientSocketChannelIDTest, ChannelIDShardSessionCache) {
+ SpawnedTestServer::SSLOptions ssl_options;
+ ASSERT_TRUE(StartTestServer(ssl_options));
+
+ EnableChannelID();
+
+ // Connect without Channel ID.
+ SSLConfig ssl_config;
+ ssl_config.channel_id_enabled = false;
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ SSLInfo ssl_info;
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
+ EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
+ EXPECT_FALSE(ssl_info.channel_id_sent);
+
+ // Enable Channel ID and connect again. This needs a full handshake to assert
+ // Channel ID.
+ ssl_config.channel_id_enabled = true;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
+ EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
+ EXPECT_TRUE(ssl_info.channel_id_sent);
+}
+
TEST_F(SSLClientSocketTest, NPN) {
SpawnedTestServer::SSLOptions server_options;
server_options.npn_protocols.push_back(std::string("spdy/3.1"));
server_options.npn_protocols.push_back(std::string("h2"));
- ASSERT_TRUE(ConnectToTestServer(server_options));
+ ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP2);
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP2);
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP2);
+ client_config.npn_protos.push_back(kProtoHTTP11);
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
@@ -3438,15 +3153,19 @@ TEST_F(SSLClientSocketTest, NPN) {
}
// In case of no overlap between client and server list, SSLClientSocket should
-// fall back to first one on the client list.
+// fall back to last one on the client list.
TEST_F(SSLClientSocketTest, NPNNoOverlap) {
SpawnedTestServer::SSLOptions server_options;
server_options.npn_protocols.push_back(std::string("http/1.1"));
- ASSERT_TRUE(ConnectToTestServer(server_options));
+ ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP2);
- client_config.next_protos.push_back(kProtoSPDY31);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoSPDY31);
+ client_config.alpn_protos.push_back(kProtoHTTP2);
+#endif
+ client_config.npn_protos.push_back(kProtoSPDY31);
+ client_config.npn_protos.push_back(kProtoHTTP2);
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
@@ -3463,11 +3182,15 @@ TEST_F(SSLClientSocketTest, NPNServerPreference) {
SpawnedTestServer::SSLOptions server_options;
server_options.npn_protocols.push_back(std::string("spdy/3.1"));
server_options.npn_protocols.push_back(std::string("h2"));
- ASSERT_TRUE(ConnectToTestServer(server_options));
+ ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP2);
- client_config.next_protos.push_back(kProtoSPDY31);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP2);
+ client_config.alpn_protos.push_back(kProtoSPDY31);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP2);
+ client_config.npn_protos.push_back(kProtoSPDY31);
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
@@ -3478,12 +3201,16 @@ TEST_F(SSLClientSocketTest, NPNServerPreference) {
EXPECT_EQ("spdy/3.1", proto);
}
+// If npn_protos.empty(), then NPN should be disabled, even if
+// !alpn_protos.empty(). Tlslite does not support ALPN, therefore if NPN is
+// disabled in the client, no protocol should be negotiated.
TEST_F(SSLClientSocketTest, NPNClientDisabled) {
SpawnedTestServer::SSLOptions server_options;
server_options.npn_protocols.push_back(std::string("http/1.1"));
- ASSERT_TRUE(ConnectToTestServer(server_options));
+ ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
+ client_config.alpn_protos.push_back(kProtoHTTP11);
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
@@ -3496,10 +3223,13 @@ TEST_F(SSLClientSocketTest, NPNClientDisabled) {
TEST_F(SSLClientSocketTest, NPNServerDisabled) {
SpawnedTestServer::SSLOptions server_options;
- ASSERT_TRUE(ConnectToTestServer(server_options));
+ ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
- client_config.next_protos.push_back(kProtoHTTP11);
+#if !defined(USE_OPENSSL)
+ client_config.alpn_protos.push_back(kProtoHTTP11);
+#endif
+ client_config.npn_protos.push_back(kProtoHTTP11);
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
diff --git a/chromium/net/socket/ssl_server_socket.h b/chromium/net/socket/ssl_server_socket.h
index 88f7f941439..bfbe7de9110 100644
--- a/chromium/net/socket/ssl_server_socket.h
+++ b/chromium/net/socket/ssl_server_socket.h
@@ -5,7 +5,6 @@
#ifndef NET_SOCKET_SSL_SERVER_SOCKET_H_
#define NET_SOCKET_SSL_SERVER_SOCKET_H_
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -18,7 +17,7 @@ class RSAPrivateKey;
namespace net {
-struct SSLConfig;
+struct SSLServerConfig;
class X509Certificate;
class SSLServerSocket : public SSLSocket {
@@ -48,16 +47,15 @@ NET_EXPORT void EnableSSLServerSockets();
// The returned SSLServerSocket takes ownership of |socket|. Stubbed versions
// of CreateSSLServerSocket will delete |socket| and return NULL.
// It takes a reference to |certificate|.
-// The |key| and |ssl_config| parameters are copied. |key| cannot be const
-// because the methods used to copy its contents are non-const.
+// The |key| and |ssl_config| parameters are copied.
//
// The caller starts the SSL server handshake by calling Handshake on the
// returned socket.
NET_EXPORT scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
scoped_ptr<StreamSocket> socket,
X509Certificate* certificate,
- crypto::RSAPrivateKey* key,
- const SSLConfig& ssl_config);
+ const crypto::RSAPrivateKey& key,
+ const SSLServerConfig& ssl_config);
} // namespace net
diff --git a/chromium/net/socket/ssl_server_socket_nss.cc b/chromium/net/socket/ssl_server_socket_nss.cc
index 614265e45ee..80450fe65fa 100644
--- a/chromium/net/socket/ssl_server_socket_nss.cc
+++ b/chromium/net/socket/ssl_server_socket_nss.cc
@@ -4,6 +4,8 @@
#include "net/socket/ssl_server_socket_nss.h"
+#include <utility>
+
#if defined(OS_WIN)
#include <winsock2.h>
#endif
@@ -31,6 +33,7 @@
#include "base/callback_helpers.h"
#include "base/lazy_instance.h"
+#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "crypto/nss_util_internal.h"
#include "crypto/rsa_private_key.h"
@@ -81,36 +84,33 @@ void EnableSSLServerSockets() {
scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
scoped_ptr<StreamSocket> socket,
X509Certificate* cert,
- crypto::RSAPrivateKey* key,
- const SSLConfig& ssl_config) {
+ const crypto::RSAPrivateKey& key,
+ const SSLServerConfig& ssl_config) {
DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been"
<< " called yet!";
return scoped_ptr<SSLServerSocket>(
- new SSLServerSocketNSS(socket.Pass(), cert, key, ssl_config));
+ new SSLServerSocketNSS(std::move(socket), cert, key, ssl_config));
}
SSLServerSocketNSS::SSLServerSocketNSS(
scoped_ptr<StreamSocket> transport_socket,
scoped_refptr<X509Certificate> cert,
- crypto::RSAPrivateKey* key,
- const SSLConfig& ssl_config)
+ const crypto::RSAPrivateKey& key,
+ const SSLServerConfig& ssl_config)
: transport_send_busy_(false),
transport_recv_busy_(false),
user_read_buf_len_(0),
user_write_buf_len_(0),
nss_fd_(NULL),
nss_bufs_(NULL),
- transport_socket_(transport_socket.Pass()),
+ transport_socket_(std::move(transport_socket)),
ssl_config_(ssl_config),
cert_(cert),
+ key_(key.Copy()),
next_handshake_state_(STATE_NONE),
completed_handshake_(false) {
- // TODO(hclam): Need a better way to clone a key.
- std::vector<uint8> key_bytes;
- CHECK(key->ExportPrivateKey(&key_bytes));
- key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
- CHECK(key_.get());
+ CHECK(key_);
}
SSLServerSocketNSS::~SSLServerSocketNSS() {
@@ -197,7 +197,7 @@ int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(user_read_callback_.is_null());
DCHECK(user_handshake_callback_.is_null());
- DCHECK(!user_read_buf_.get());
+ DCHECK(!user_read_buf_);
DCHECK(nss_bufs_);
DCHECK(!callback.is_null());
@@ -220,7 +220,7 @@ int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len,
int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(user_write_callback_.is_null());
- DCHECK(!user_write_buf_.get());
+ DCHECK(!user_write_buf_);
DCHECK(nss_bufs_);
DCHECK(!callback.is_null());
@@ -238,11 +238,11 @@ int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len,
return rv;
}
-int SSLServerSocketNSS::SetReceiveBufferSize(int32 size) {
+int SSLServerSocketNSS::SetReceiveBufferSize(int32_t size) {
return transport_socket_->SetReceiveBufferSize(size);
}
-int SSLServerSocketNSS::SetSendBufferSize(int32 size) {
+int SSLServerSocketNSS::SetSendBufferSize(int32_t size) {
return transport_socket_->SetSendBufferSize(size);
}
@@ -311,6 +311,11 @@ void SSLServerSocketNSS::GetConnectionAttempts(ConnectionAttempts* out) const {
out->clear();
}
+int64_t SSLServerSocketNSS::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
int SSLServerSocketNSS::InitializeSSLOptions() {
// Transport connected, now hook it up to nss
nss_fd_ = memio_CreateIOLayer(kRecvBufferSize, kSendBufferSize);
@@ -332,6 +337,15 @@ int SSLServerSocketNSS::InitializeSSLOptions() {
int rv;
+ if (ssl_config_.require_client_cert) {
+ rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE);
+ if (rv != SECSuccess) {
+ LogFailedNSSFunction(net_log_, "SSL_OptionSet",
+ "SSL_REQUEST_CERTIFICATE");
+ return ERR_UNEXPECTED;
+ }
+ }
+
rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
if (rv != SECSuccess) {
LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
@@ -369,7 +383,7 @@ int SSLServerSocketNSS::InitializeSSLOptions() {
}
}
- for (std::vector<uint16>::const_iterator it =
+ for (std::vector<uint16_t>::const_iterator it =
ssl_config_.disabled_cipher_suites.begin();
it != ssl_config_.disabled_cipher_suites.end(); ++it) {
// This will fail if the specified cipher is not implemented by NSS, but
@@ -441,7 +455,7 @@ int SSLServerSocketNSS::InitializeSSLOptions() {
}
// Get a key of SECKEYPrivateKey* structure.
- std::vector<uint8> key_vector;
+ std::vector<uint8_t> key_vector;
if (!key_->ExportPrivateKey(&key_vector)) {
CERT_DestroyCertificate(cert);
return ERR_UNEXPECTED;
@@ -508,7 +522,7 @@ void SSLServerSocketNSS::OnSendComplete(int result) {
if (!completed_handshake_)
return;
- if (user_write_buf_.get()) {
+ if (user_write_buf_) {
int rv = DoWriteLoop(result);
if (rv != ERR_IO_PENDING)
DoWriteCallback(rv);
@@ -527,7 +541,7 @@ void SSLServerSocketNSS::OnRecvComplete(int result) {
// Network layer received some data, check if client requested to read
// decrypted data.
- if (!user_read_buf_.get() || !completed_handshake_)
+ if (!user_read_buf_ || !completed_handshake_)
return;
int rv = DoReadLoop(result);
@@ -648,7 +662,7 @@ bool SSLServerSocketNSS::DoTransportIO() {
}
int SSLServerSocketNSS::DoPayloadRead() {
- DCHECK(user_read_buf_.get());
+ DCHECK(user_read_buf_);
DCHECK_GT(user_read_buf_len_, 0);
int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
if (rv >= 0)
@@ -664,7 +678,7 @@ int SSLServerSocketNSS::DoPayloadRead() {
}
int SSLServerSocketNSS::DoPayloadWrite() {
- DCHECK(user_write_buf_.get());
+ DCHECK(user_write_buf_);
int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
if (rv >= 0)
return rv;
diff --git a/chromium/net/socket/ssl_server_socket_nss.h b/chromium/net/socket/ssl_server_socket_nss.h
index d1bcec69067..6bdcf112f76 100644
--- a/chromium/net/socket/ssl_server_socket_nss.h
+++ b/chromium/net/socket/ssl_server_socket_nss.h
@@ -9,14 +9,16 @@
#include <keyt.h>
#include <nspr.h>
#include <nss.h>
+#include <stdint.h>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/host_port_pair.h"
#include "net/base/nss_memio.h"
#include "net/log/net_log.h"
#include "net/socket/ssl_server_socket.h"
-#include "net/ssl/ssl_config_service.h"
+#include "net/ssl/ssl_server_config.h"
namespace net {
@@ -26,8 +28,8 @@ class SSLServerSocketNSS : public SSLServerSocket {
// parameters are used.
SSLServerSocketNSS(scoped_ptr<StreamSocket> socket,
scoped_refptr<X509Certificate> certificate,
- crypto::RSAPrivateKey* key,
- const SSLConfig& ssl_config);
+ const crypto::RSAPrivateKey& key,
+ const SSLServerConfig& ssl_config);
~SSLServerSocketNSS() override;
// SSLServerSocket interface.
@@ -48,8 +50,8 @@ class SSLServerSocketNSS : public SSLServerSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
// StreamSocket implementation.
int Connect(const CompletionCallback& callback) override;
@@ -69,6 +71,7 @@ class SSLServerSocketNSS : public SSLServerSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
private:
enum State {
@@ -136,7 +139,7 @@ class SSLServerSocketNSS : public SSLServerSocket {
scoped_ptr<StreamSocket> transport_socket_;
// Options for the SSL socket.
- SSLConfig ssl_config_;
+ SSLServerConfig ssl_config_;
// Certificate for the server.
scoped_refptr<X509Certificate> cert_;
diff --git a/chromium/net/socket/ssl_server_socket_openssl.cc b/chromium/net/socket/ssl_server_socket_openssl.cc
index e8cbf5bddf4..c3869cd865d 100644
--- a/chromium/net/socket/ssl_server_socket_openssl.cc
+++ b/chromium/net/socket/ssl_server_socket_openssl.cc
@@ -6,6 +6,7 @@
#include <openssl/err.h>
#include <openssl/ssl.h>
+#include <utility>
#include "base/callback_helpers.h"
#include "base/logging.h"
@@ -28,18 +29,18 @@ void EnableSSLServerSockets() {
scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
scoped_ptr<StreamSocket> socket,
X509Certificate* certificate,
- crypto::RSAPrivateKey* key,
- const SSLConfig& ssl_config) {
+ const crypto::RSAPrivateKey& key,
+ const SSLServerConfig& ssl_config) {
crypto::EnsureOpenSSLInit();
- return scoped_ptr<SSLServerSocket>(
- new SSLServerSocketOpenSSL(socket.Pass(), certificate, key, ssl_config));
+ return scoped_ptr<SSLServerSocket>(new SSLServerSocketOpenSSL(
+ std::move(socket), certificate, key, ssl_config));
}
SSLServerSocketOpenSSL::SSLServerSocketOpenSSL(
scoped_ptr<StreamSocket> transport_socket,
scoped_refptr<X509Certificate> certificate,
- crypto::RSAPrivateKey* key,
- const SSLConfig& ssl_config)
+ const crypto::RSAPrivateKey& key,
+ const SSLServerConfig& ssl_config)
: transport_send_busy_(false),
transport_recv_busy_(false),
transport_recv_eof_(false),
@@ -48,16 +49,13 @@ SSLServerSocketOpenSSL::SSLServerSocketOpenSSL(
transport_write_error_(OK),
ssl_(NULL),
transport_bio_(NULL),
- transport_socket_(transport_socket.Pass()),
+ transport_socket_(std::move(transport_socket)),
ssl_config_(ssl_config),
cert_(certificate),
+ key_(key.Copy()),
next_handshake_state_(STATE_NONE),
completed_handshake_(false) {
- // TODO(byungchul): Need a better way to clone a key.
- std::vector<uint8> key_bytes;
- CHECK(key->ExportPrivateKey(&key_bytes));
- key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
- CHECK(key_.get());
+ CHECK(key_);
}
SSLServerSocketOpenSSL::~SSLServerSocketOpenSSL() {
@@ -134,7 +132,7 @@ int SSLServerSocketOpenSSL::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(user_read_callback_.is_null());
DCHECK(user_handshake_callback_.is_null());
- DCHECK(!user_read_buf_.get());
+ DCHECK(!user_read_buf_);
DCHECK(!callback.is_null());
user_read_buf_ = buf;
@@ -157,7 +155,7 @@ int SSLServerSocketOpenSSL::Read(IOBuffer* buf, int buf_len,
int SSLServerSocketOpenSSL::Write(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(user_write_callback_.is_null());
- DCHECK(!user_write_buf_.get());
+ DCHECK(!user_write_buf_);
DCHECK(!callback.is_null());
user_write_buf_ = buf;
@@ -174,11 +172,11 @@ int SSLServerSocketOpenSSL::Write(IOBuffer* buf, int buf_len,
return rv;
}
-int SSLServerSocketOpenSSL::SetReceiveBufferSize(int32 size) {
+int SSLServerSocketOpenSSL::SetReceiveBufferSize(int32_t size) {
return transport_socket_->SetReceiveBufferSize(size);
}
-int SSLServerSocketOpenSSL::SetSendBufferSize(int32 size) {
+int SSLServerSocketOpenSSL::SetSendBufferSize(int32_t size) {
return transport_socket_->SetSendBufferSize(size);
}
@@ -253,6 +251,10 @@ void SSLServerSocketOpenSSL::GetConnectionAttempts(
out->clear();
}
+int64_t SSLServerSocketOpenSSL::GetTotalReceivedBytes() const {
+ return transport_socket_->GetTotalReceivedBytes();
+}
+
void SSLServerSocketOpenSSL::OnSendComplete(int result) {
if (next_handshake_state_ == STATE_HANDSHAKE) {
// In handshake phase.
@@ -265,7 +267,7 @@ void SSLServerSocketOpenSSL::OnSendComplete(int result) {
if (!completed_handshake_)
return;
- if (user_write_buf_.get()) {
+ if (user_write_buf_) {
int rv = DoWriteLoop(result);
if (rv != ERR_IO_PENDING)
DoWriteCallback(rv);
@@ -284,7 +286,7 @@ void SSLServerSocketOpenSSL::OnRecvComplete(int result) {
// Network layer received some data, check if client requested to read
// decrypted data.
- if (!user_read_buf_.get() || !completed_handshake_)
+ if (!user_read_buf_ || !completed_handshake_)
return;
int rv = DoReadLoop(result);
@@ -309,7 +311,7 @@ int SSLServerSocketOpenSSL::BufferSend() {
if (transport_send_busy_)
return ERR_IO_PENDING;
- if (!send_buffer_.get()) {
+ if (!send_buffer_) {
// Get a fresh send buffer out of the send BIO.
size_t max_read = BIO_pending(transport_bio_);
if (!max_read)
@@ -358,7 +360,7 @@ void SSLServerSocketOpenSSL::TransportWriteComplete(int result) {
(void)BIO_shutdown_wr(transport_bio_);
send_buffer_ = NULL;
} else {
- DCHECK(send_buffer_.get());
+ DCHECK(send_buffer_);
send_buffer_->DidConsume(result);
DCHECK_GE(send_buffer_->BytesRemaining(), 0);
if (send_buffer_->BytesRemaining() <= 0)
@@ -427,7 +429,7 @@ int SSLServerSocketOpenSSL::TransportReadComplete(int result) {
// the CHECK. http://crbug.com/335557.
result = transport_write_error_;
} else {
- DCHECK(recv_buffer_.get());
+ DCHECK(recv_buffer_);
int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
// A write into a memory BIO should always succeed.
DCHECK_EQ(result, ret);
@@ -456,7 +458,7 @@ bool SSLServerSocketOpenSSL::DoTransportIO() {
}
int SSLServerSocketOpenSSL::DoPayloadRead() {
- DCHECK(user_read_buf_.get());
+ DCHECK(user_read_buf_);
DCHECK_GT(user_read_buf_len_, 0);
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_);
@@ -475,7 +477,7 @@ int SSLServerSocketOpenSSL::DoPayloadRead() {
}
int SSLServerSocketOpenSSL::DoPayloadWrite() {
- DCHECK(user_write_buf_.get());
+ DCHECK(user_write_buf_);
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
if (rv >= 0)
@@ -614,6 +616,10 @@ int SSLServerSocketOpenSSL::Init() {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method()));
+
+ if (ssl_config_.require_client_cert)
+ SSL_CTX_set_verify(ssl_ctx.get(), SSL_VERIFY_PEER, NULL);
+
ssl_ = SSL_new(ssl_ctx.get());
if (!ssl_)
return ERR_UNEXPECTED;
@@ -644,7 +650,7 @@ int SSLServerSocketOpenSSL::Init() {
reinterpret_cast<const unsigned char*>(der_string.data());
ScopedX509 x509(d2i_X509(NULL, &der_string_array, der_string.length()));
- if (!x509.get())
+ if (!x509)
return ERR_UNEXPECTED;
// On success, SSL_use_certificate acquires a reference to |x509|.
@@ -681,7 +687,7 @@ int SSLServerSocketOpenSSL::Init() {
SSL_set_mode(ssl_, mode.set_mask);
SSL_clear_mode(ssl_, mode.clear_mask);
- // See SSLConfig::disabled_cipher_suites for description of the suites
+ // See SSLServerConfig::disabled_cipher_suites for description of the suites
// disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256
// and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384
// as the handshake hash.
diff --git a/chromium/net/socket/ssl_server_socket_openssl.h b/chromium/net/socket/ssl_server_socket_openssl.h
index 34e8bb001fc..fd7824970fc 100644
--- a/chromium/net/socket/ssl_server_socket_openssl.h
+++ b/chromium/net/socket/ssl_server_socket_openssl.h
@@ -5,12 +5,15 @@
#ifndef NET_SOCKET_SSL_SERVER_SOCKET_OPENSSL_H_
#define NET_SOCKET_SSL_SERVER_SOCKET_OPENSSL_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/log/net_log.h"
#include "net/socket/ssl_server_socket.h"
-#include "net/ssl/ssl_config_service.h"
+#include "net/ssl/ssl_server_config.h"
// Avoid including misc OpenSSL headers, i.e.:
// <openssl/bio.h>
@@ -28,8 +31,8 @@ class SSLServerSocketOpenSSL : public SSLServerSocket {
// parameters are used.
SSLServerSocketOpenSSL(scoped_ptr<StreamSocket> socket,
scoped_refptr<X509Certificate> certificate,
- crypto::RSAPrivateKey* key,
- const SSLConfig& ssl_config);
+ const crypto::RSAPrivateKey& key,
+ const SSLServerConfig& ssl_config);
~SSLServerSocketOpenSSL() override;
// SSLServerSocket interface.
@@ -50,8 +53,8 @@ class SSLServerSocketOpenSSL : public SSLServerSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
// StreamSocket implementation.
int Connect(const CompletionCallback& callback) override;
@@ -71,6 +74,7 @@ class SSLServerSocketOpenSSL : public SSLServerSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
private:
enum State {
@@ -136,7 +140,7 @@ class SSLServerSocketOpenSSL : public SSLServerSocket {
scoped_ptr<StreamSocket> transport_socket_;
// Options for the SSL socket.
- SSLConfig ssl_config_;
+ SSLServerConfig ssl_config_;
// Certificate for the server.
scoped_refptr<X509Certificate> cert_;
diff --git a/chromium/net/socket/ssl_server_socket_unittest.cc b/chromium/net/socket/ssl_server_socket_unittest.cc
index 24b30905be5..ac2d44ec413 100644
--- a/chromium/net/socket/ssl_server_socket_unittest.cc
+++ b/chromium/net/socket/ssl_server_socket_unittest.cc
@@ -15,14 +15,17 @@
#include "net/socket/ssl_server_socket.h"
+#include <stdint.h>
#include <stdlib.h>
-
#include <queue>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
+#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -45,9 +48,9 @@
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
#include "net/ssl/ssl_cipher_suite_names.h"
-#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "net/ssl/ssl_info.h"
+#include "net/ssl/ssl_server_config.h"
#include "net/test/cert_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -76,7 +79,7 @@ class FakeDataChannel {
read_buf_len_ = buf_len;
return ERR_IO_PENDING;
}
- return PropogateData(buf, buf_len);
+ return PropagateData(buf, buf_len);
}
int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
@@ -114,7 +117,7 @@ class FakeDataChannel {
if (read_callback_.is_null() || data_.empty())
return;
- int copied = PropogateData(read_buf_, read_buf_len_);
+ int copied = PropagateData(read_buf_, read_buf_len_);
CompletionCallback callback = read_callback_;
read_callback_.Reset();
read_buf_ = NULL;
@@ -131,7 +134,7 @@ class FakeDataChannel {
callback.Run(ERR_CONNECTION_RESET);
}
- int PropogateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) {
+ int PropagateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) {
scoped_refptr<DrainableIOBuffer> buf = data_.front();
int copied = std::min(buf->BytesRemaining(), read_buf_len);
memcpy(read_buf->data(), buf->data(), copied);
@@ -189,9 +192,9 @@ class FakeSocket : public StreamSocket {
return outgoing_->Write(buf, buf_len, callback);
}
- int SetReceiveBufferSize(int32 size) override { return OK; }
+ int SetReceiveBufferSize(int32_t size) override { return OK; }
- int SetSendBufferSize(int32 size) override { return OK; }
+ int SetSendBufferSize(int32_t size) override { return OK; }
int Connect(const CompletionCallback& callback) override { return OK; }
@@ -239,6 +242,11 @@ class FakeSocket : public StreamSocket {
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+
private:
BoundNetLog net_log_;
FakeDataChannel* incoming_;
@@ -318,10 +326,10 @@ class SSLServerSocketTest : public PlatformTest {
base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin");
std::string key_string;
ASSERT_TRUE(base::ReadFileToString(key_path, &key_string));
- std::vector<uint8> key_vector(
- reinterpret_cast<const uint8*>(key_string.data()),
- reinterpret_cast<const uint8*>(key_string.data() +
- key_string.length()));
+ std::vector<uint8_t> key_vector(
+ reinterpret_cast<const uint8_t*>(key_string.data()),
+ reinterpret_cast<const uint8_t*>(key_string.data() +
+ key_string.length()));
scoped_ptr<crypto::RSAPrivateKey> private_key(
crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
@@ -340,16 +348,16 @@ class SSLServerSocketTest : public PlatformTest {
context.cert_verifier = cert_verifier_.get();
context.transport_security_state = transport_security_state_.get();
client_socket_ = socket_factory_->CreateSSLClientSocket(
- client_connection.Pass(), host_and_pair, client_ssl_config_, context);
- server_socket_ =
- CreateSSLServerSocket(server_socket.Pass(), cert.get(),
- private_key.get(), server_ssl_config_);
+ std::move(client_connection), host_and_pair, client_ssl_config_,
+ context);
+ server_socket_ = CreateSSLServerSocket(std::move(server_socket), cert.get(),
+ *private_key, server_ssl_config_);
}
FakeDataChannel channel_1_;
FakeDataChannel channel_2_;
SSLConfig client_ssl_config_;
- SSLConfig server_ssl_config_;
+ SSLServerConfig server_ssl_config_;
scoped_ptr<SSLClientSocket> client_socket_;
scoped_ptr<SSLServerSocket> server_socket_;
ClientSocketFactory* socket_factory_;
@@ -532,7 +540,7 @@ TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) {
EXPECT_GT(client_ret, 0);
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitClosure(),
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(10));
base::MessageLoop::current()->Run();
}
diff --git a/chromium/net/socket/ssl_socket.h b/chromium/net/socket/ssl_socket.h
index 0dc817becdd..5f60e800b5b 100644
--- a/chromium/net/socket/ssl_socket.h
+++ b/chromium/net/socket/ssl_socket.h
@@ -5,7 +5,6 @@
#ifndef NET_SOCKET_SSL_SOCKET_H_
#define NET_SOCKET_SSL_SOCKET_H_
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/socket/stream_socket.h"
diff --git a/chromium/net/socket/stream_socket.h b/chromium/net/socket/stream_socket.h
index 5669ea3e9a0..e2f9d3cd790 100644
--- a/chromium/net/socket/stream_socket.h
+++ b/chromium/net/socket/stream_socket.h
@@ -5,6 +5,9 @@
#ifndef NET_SOCKET_STREAM_SOCKET_H_
#define NET_SOCKET_STREAM_SOCKET_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/log/net_log.h"
#include "net/socket/connection_attempts.h"
#include "net/socket/next_proto.h"
@@ -106,6 +109,12 @@ class NET_EXPORT_PRIVATE StreamSocket : public Socket {
// Adds |attempts| to the socket's list of connection attempts.
virtual void AddConnectionAttempts(const ConnectionAttempts& attempts) = 0;
+ // Returns the total number of number bytes read by the socket. This only
+ // counts the payload bytes. Transport headers are not counted. Returns
+ // 0 if the socket does not implement the function. The count is reset when
+ // Disconnect() is called.
+ virtual int64_t GetTotalReceivedBytes() const = 0;
+
protected:
// The following class is only used to gather statistics about the history of
// a socket. It is only instantiated and used in basic sockets, such as
diff --git a/chromium/net/socket/tcp_client_socket.cc b/chromium/net/socket/tcp_client_socket.cc
index 78b24de7b15..700fa1c1655 100644
--- a/chromium/net/socket/tcp_client_socket.cc
+++ b/chromium/net/socket/tcp_client_socket.cc
@@ -4,6 +4,8 @@
#include "net/socket/tcp_client_socket.h"
+#include <utility>
+
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
@@ -23,16 +25,17 @@ TCPClientSocket::TCPClientSocket(const AddressList& addresses,
addresses_(addresses),
current_address_index_(-1),
next_connect_state_(CONNECT_STATE_NONE),
- previously_disconnected_(false) {
-}
+ previously_disconnected_(false),
+ total_received_bytes_(0) {}
TCPClientSocket::TCPClientSocket(scoped_ptr<TCPSocket> connected_socket,
const IPEndPoint& peer_address)
- : socket_(connected_socket.Pass()),
+ : socket_(std::move(connected_socket)),
addresses_(AddressList(peer_address)),
current_address_index_(0),
next_connect_state_(CONNECT_STATE_NONE),
- previously_disconnected_(false) {
+ previously_disconnected_(false),
+ total_received_bytes_(0) {
DCHECK(socket_);
socket_->SetDefaultOptionsForClient();
@@ -187,6 +190,7 @@ void TCPClientSocket::Disconnect() {
}
void TCPClientSocket::DoDisconnect() {
+ total_received_bytes_ = 0;
EmitTCPMetricsHistogramsOnDisconnect();
// If connecting or already connected, record that the socket has been
// disconnected.
@@ -264,10 +268,12 @@ int TCPClientSocket::Read(IOBuffer* buf,
// |socket_| is owned by this class and the callback won't be run once
// |socket_| is gone. Therefore, it is safe to use base::Unretained() here.
CompletionCallback read_callback = base::Bind(
- &TCPClientSocket::DidCompleteReadWrite, base::Unretained(this), callback);
+ &TCPClientSocket::DidCompleteRead, base::Unretained(this), callback);
int result = socket_->Read(buf, buf_len, read_callback);
- if (result > 0)
+ if (result > 0) {
use_history_.set_was_used_to_convey_data();
+ total_received_bytes_ += result;
+ }
return result;
}
@@ -280,7 +286,7 @@ int TCPClientSocket::Write(IOBuffer* buf,
// |socket_| is owned by this class and the callback won't be run once
// |socket_| is gone. Therefore, it is safe to use base::Unretained() here.
CompletionCallback write_callback = base::Bind(
- &TCPClientSocket::DidCompleteReadWrite, base::Unretained(this), callback);
+ &TCPClientSocket::DidCompleteWrite, base::Unretained(this), callback);
int result = socket_->Write(buf, buf_len, write_callback);
if (result > 0)
use_history_.set_was_used_to_convey_data();
@@ -288,11 +294,11 @@ int TCPClientSocket::Write(IOBuffer* buf,
return result;
}
-int TCPClientSocket::SetReceiveBufferSize(int32 size) {
+int TCPClientSocket::SetReceiveBufferSize(int32_t size) {
return socket_->SetReceiveBufferSize(size);
}
-int TCPClientSocket::SetSendBufferSize(int32 size) {
+int TCPClientSocket::SetSendBufferSize(int32_t size) {
return socket_->SetSendBufferSize(size);
}
@@ -318,6 +324,10 @@ void TCPClientSocket::AddConnectionAttempts(
attempts.end());
}
+int64_t TCPClientSocket::GetTotalReceivedBytes() const {
+ return total_received_bytes_;
+}
+
void TCPClientSocket::DidCompleteConnect(int result) {
DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE);
DCHECK_NE(result, ERR_IO_PENDING);
@@ -330,6 +340,19 @@ void TCPClientSocket::DidCompleteConnect(int result) {
}
}
+void TCPClientSocket::DidCompleteRead(const CompletionCallback& callback,
+ int result) {
+ if (result > 0)
+ total_received_bytes_ += result;
+
+ DidCompleteReadWrite(callback, result);
+}
+
+void TCPClientSocket::DidCompleteWrite(const CompletionCallback& callback,
+ int result) {
+ DidCompleteReadWrite(callback, result);
+}
+
void TCPClientSocket::DidCompleteReadWrite(const CompletionCallback& callback,
int result) {
if (result > 0)
diff --git a/chromium/net/socket/tcp_client_socket.h b/chromium/net/socket/tcp_client_socket.h
index 064b5eb53ee..73ee62bfeb2 100644
--- a/chromium/net/socket/tcp_client_socket.h
+++ b/chromium/net/socket/tcp_client_socket.h
@@ -5,8 +5,10 @@
#ifndef NET_SOCKET_TCP_CLIENT_SOCKET_H_
#define NET_SOCKET_TCP_CLIENT_SOCKET_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
@@ -64,8 +66,8 @@ class NET_EXPORT TCPClientSocket : public StreamSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
virtual bool SetKeepAlive(bool enable, int delay);
virtual bool SetNoDelay(bool no_delay);
@@ -73,6 +75,7 @@ class NET_EXPORT TCPClientSocket : public StreamSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override;
void AddConnectionAttempts(const ConnectionAttempts& attempts) override;
+ int64_t GetTotalReceivedBytes() const override;
private:
// State machine for connecting the socket.
@@ -92,6 +95,8 @@ class NET_EXPORT TCPClientSocket : public StreamSocket {
void DoDisconnect();
void DidCompleteConnect(int result);
+ void DidCompleteRead(const CompletionCallback& callback, int result);
+ void DidCompleteWrite(const CompletionCallback& callback, int result);
void DidCompleteReadWrite(const CompletionCallback& callback, int result);
int OpenSocket(AddressFamily family);
@@ -128,6 +133,9 @@ class NET_EXPORT TCPClientSocket : public StreamSocket {
// Failed connection attempts made while trying to connect this socket.
ConnectionAttempts connection_attempts_;
+ // Total number of bytes received by the socket.
+ int64_t total_received_bytes_;
+
DISALLOW_COPY_AND_ASSIGN(TCPClientSocket);
};
diff --git a/chromium/net/socket/tcp_server_socket.cc b/chromium/net/socket/tcp_server_socket.cc
index a25f73f6c6f..06f75122033 100644
--- a/chromium/net/socket/tcp_server_socket.cc
+++ b/chromium/net/socket/tcp_server_socket.cc
@@ -4,6 +4,8 @@
#include "net/socket/tcp_server_socket.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
@@ -79,16 +81,20 @@ int TCPServerSocket::Accept(scoped_ptr<StreamSocket>* socket,
return result;
}
+void TCPServerSocket::DetachFromThread() {
+ socket_.DetachFromThread();
+}
+
int TCPServerSocket::ConvertAcceptedSocket(
int result,
scoped_ptr<StreamSocket>* output_accepted_socket) {
// Make sure the TCPSocket object is destroyed in any case.
- scoped_ptr<TCPSocket> temp_accepted_socket(accepted_socket_.Pass());
+ scoped_ptr<TCPSocket> temp_accepted_socket(std::move(accepted_socket_));
if (result != OK)
return result;
- output_accepted_socket->reset(new TCPClientSocket(
- temp_accepted_socket.Pass(), accepted_address_));
+ output_accepted_socket->reset(
+ new TCPClientSocket(std::move(temp_accepted_socket), accepted_address_));
return OK;
}
diff --git a/chromium/net/socket/tcp_server_socket.h b/chromium/net/socket/tcp_server_socket.h
index b161be65723..ea2021c921e 100644
--- a/chromium/net/socket/tcp_server_socket.h
+++ b/chromium/net/socket/tcp_server_socket.h
@@ -5,8 +5,8 @@
#ifndef NET_SOCKET_TCP_SERVER_SOCKET_H_
#define NET_SOCKET_TCP_SERVER_SOCKET_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
@@ -27,6 +27,11 @@ class NET_EXPORT_PRIVATE TCPServerSocket : public ServerSocket {
int Accept(scoped_ptr<StreamSocket>* socket,
const CompletionCallback& callback) override;
+ // Detachs from the current thread, to allow the socket to be transferred to
+ // a new thread. Should only be called when the object is no longer used by
+ // the old thread.
+ void DetachFromThread();
+
private:
// Converts |accepted_socket_| and stores the result in
// |output_accepted_socket|.
diff --git a/chromium/net/socket/tcp_server_socket_unittest.cc b/chromium/net/socket/tcp_server_socket_unittest.cc
index 19c715bfc91..133c8073188 100644
--- a/chromium/net/socket/tcp_server_socket_unittest.cc
+++ b/chromium/net/socket/tcp_server_socket_unittest.cc
@@ -51,7 +51,7 @@ class TCPServerSocketTest : public PlatformTest {
}
void ParseAddress(const std::string& ip_str,
- uint16 port,
+ uint16_t port,
IPEndPoint* address) {
IPAddressNumber ip_number;
bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
diff --git a/chromium/net/socket/tcp_socket_posix.cc b/chromium/net/socket/tcp_socket_posix.cc
index 653eb82445d..0546e6075a5 100644
--- a/chromium/net/socket/tcp_socket_posix.cc
+++ b/chromium/net/socket/tcp_socket_posix.cc
@@ -21,9 +21,9 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "net/base/network_activity_monitor.h"
#include "net/base/network_change_notifier.h"
+#include "net/base/sockaddr_storage.h"
#include "net/socket/socket_net_log_params.h"
#include "net/socket/socket_posix.h"
@@ -404,14 +404,14 @@ int TCPSocketPosix::SetAddressReuse(bool allow) {
return OK;
}
-int TCPSocketPosix::SetReceiveBufferSize(int32 size) {
+int TCPSocketPosix::SetReceiveBufferSize(int32_t size) {
DCHECK(socket_);
int rv = setsockopt(socket_->socket_fd(), SOL_SOCKET, SO_RCVBUF,
reinterpret_cast<const char*>(&size), sizeof(size));
return (rv == 0) ? OK : MapSystemError(errno);
}
-int TCPSocketPosix::SetSendBufferSize(int32 size) {
+int TCPSocketPosix::SetSendBufferSize(int32_t size) {
DCHECK(socket_);
int rv = setsockopt(socket_->socket_fd(), SOL_SOCKET, SO_SNDBUF,
reinterpret_cast<const char*>(&size), sizeof(size));
@@ -465,6 +465,10 @@ bool TCPSocketPosix::IsValid() const {
return socket_ != NULL && socket_->socket_fd() != kInvalidSocket;
}
+void TCPSocketPosix::DetachFromThread() {
+ socket_->DetachFromThread();
+}
+
void TCPSocketPosix::StartLoggingMultipleConnectAttempts(
const AddressList& addresses) {
if (!logging_multiple_connect_attempts_) {
@@ -535,7 +539,7 @@ int TCPSocketPosix::HandleConnectCompleted(int rv) const {
// Log the end of this attempt (and any OS error it threw).
if (rv != OK) {
net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT,
- NetLog::IntegerCallback("os_error", errno));
+ NetLog::IntCallback("os_error", errno));
} else {
net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT);
}
diff --git a/chromium/net/socket/tcp_socket_posix.h b/chromium/net/socket/tcp_socket_posix.h
index de9487c35f7..8d53caf567f 100644
--- a/chromium/net/socket/tcp_socket_posix.h
+++ b/chromium/net/socket/tcp_socket_posix.h
@@ -5,9 +5,11 @@
#ifndef NET_SOCKET_TCP_SOCKET_POSIX_H_
#define NET_SOCKET_TCP_SOCKET_POSIX_H_
-#include "base/basictypes.h"
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "net/base/address_family.h"
@@ -59,8 +61,8 @@ class NET_EXPORT TCPSocketPosix {
// - SetKeepAlive(true, 45).
void SetDefaultOptionsForClient();
int SetAddressReuse(bool allow);
- int SetReceiveBufferSize(int32 size);
- int SetSendBufferSize(int32 size);
+ int SetReceiveBufferSize(int32_t size);
+ int SetSendBufferSize(int32_t size);
bool SetKeepAlive(bool enable, int delay);
bool SetNoDelay(bool no_delay);
@@ -77,6 +79,11 @@ class NET_EXPORT TCPSocketPosix {
bool IsValid() const;
+ // Detachs from the current thread, to allow the socket to be transferred to
+ // a new thread. Should only be called when the object is no longer used by
+ // the old thread.
+ void DetachFromThread();
+
// Marks the start/end of a series of connect attempts for logging purpose.
//
// TCPClientSocket may attempt to connect to multiple addresses until it
diff --git a/chromium/net/socket/tcp_socket_unittest.cc b/chromium/net/socket/tcp_socket_unittest.cc
index 374621e8020..ade3ee7fd8d 100644
--- a/chromium/net/socket/tcp_socket_unittest.cc
+++ b/chromium/net/socket/tcp_socket_unittest.cc
@@ -9,14 +9,13 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
+#include "net/base/sockaddr_storage.h"
#include "net/base/test_completion_callback.h"
#include "net/socket/tcp_client_socket.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -59,7 +58,7 @@ class TCPSocketTest : public PlatformTest {
}
void ParseAddress(const std::string& ip_str,
- uint16 port,
+ uint16_t port,
IPEndPoint* address) {
IPAddressNumber ip_number;
bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
diff --git a/chromium/net/socket/tcp_socket_win.cc b/chromium/net/socket/tcp_socket_win.cc
index b14475cd4e6..a9998e2c0c6 100644
--- a/chromium/net/socket/tcp_socket_win.cc
+++ b/chromium/net/socket/tcp_socket_win.cc
@@ -5,10 +5,13 @@
#include "net/socket/tcp_socket.h"
#include "net/socket/tcp_socket_win.h"
+#include <errno.h>
#include <mstcpip.h>
#include "base/callback_helpers.h"
+#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/win/windows_version.h"
#include "net/base/address_list.h"
@@ -16,9 +19,9 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "net/base/network_activity_monitor.h"
#include "net/base/network_change_notifier.h"
+#include "net/base/sockaddr_storage.h"
#include "net/base/winsock_init.h"
#include "net/base/winsock_util.h"
#include "net/socket/socket_descriptor.h"
@@ -30,7 +33,7 @@ namespace {
const int kTCPKeepAliveSeconds = 45;
-int SetSocketReceiveBufferSize(SOCKET socket, int32 size) {
+int SetSocketReceiveBufferSize(SOCKET socket, int32_t size) {
int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
reinterpret_cast<const char*>(&size), sizeof(size));
int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError());
@@ -38,7 +41,7 @@ int SetSocketReceiveBufferSize(SOCKET socket, int32 size) {
return net_error;
}
-int SetSocketSendBufferSize(SOCKET socket, int32 size) {
+int SetSocketSendBufferSize(SOCKET socket, int32_t size) {
int rv = setsockopt(socket, SOL_SOCKET, SO_SNDBUF,
reinterpret_cast<const char*>(&size), sizeof(size));
int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError());
@@ -301,7 +304,7 @@ int TCPSocketWin::Open(AddressFamily family) {
return MapSystemError(WSAGetLastError());
}
- if (SetNonBlocking(socket_)) {
+ if (!base::SetNonBlocking(socket_)) {
int result = MapSystemError(WSAGetLastError());
Close();
return result;
@@ -318,7 +321,7 @@ int TCPSocketWin::AdoptConnectedSocket(SOCKET socket,
socket_ = socket;
- if (SetNonBlocking(socket_)) {
+ if (!base::SetNonBlocking(socket_)) {
int result = MapSystemError(WSAGetLastError());
Close();
return result;
@@ -336,7 +339,7 @@ int TCPSocketWin::AdoptListenSocket(SOCKET socket) {
socket_ = socket;
- if (SetNonBlocking(socket_)) {
+ if (!base::SetNonBlocking(socket_)) {
int result = MapSystemError(WSAGetLastError());
Close();
return result;
@@ -588,7 +591,7 @@ void TCPSocketWin::SetDefaultOptionsForClient() {
// Since Vista's auto-tune is better than any static value we can could set,
// only change these on pre-vista machines.
if (base::win::GetVersion() < base::win::VERSION_VISTA) {
- const int32 kSocketBufferSize = 64 * 1024;
+ const int32_t kSocketBufferSize = 64 * 1024;
SetSocketReceiveBufferSize(socket_, kSocketBufferSize);
SetSocketSendBufferSize(socket_, kSocketBufferSize);
}
@@ -623,12 +626,12 @@ int TCPSocketWin::SetExclusiveAddrUse() {
return OK;
}
-int TCPSocketWin::SetReceiveBufferSize(int32 size) {
+int TCPSocketWin::SetReceiveBufferSize(int32_t size) {
DCHECK(CalledOnValidThread());
return SetSocketReceiveBufferSize(socket_, size);
}
-int TCPSocketWin::SetSendBufferSize(int32 size) {
+int TCPSocketWin::SetSendBufferSize(int32_t size) {
DCHECK(CalledOnValidThread());
return SetSocketSendBufferSize(socket_, size);
}
@@ -698,6 +701,10 @@ void TCPSocketWin::Close() {
connect_os_error_ = 0;
}
+void TCPSocketWin::DetachFromThread() {
+ base::NonThreadSafe::DetachFromThread();
+}
+
void TCPSocketWin::StartLoggingMultipleConnectAttempts(
const AddressList& addresses) {
if (!logging_multiple_connect_attempts_) {
@@ -841,7 +848,7 @@ void TCPSocketWin::DoConnectComplete(int result) {
connect_os_error_ = 0;
if (result != OK) {
net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT,
- NetLog::IntegerCallback("os_error", os_error));
+ NetLog::IntCallback("os_error", os_error));
} else {
net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT);
}
diff --git a/chromium/net/socket/tcp_socket_win.h b/chromium/net/socket/tcp_socket_win.h
index cc969d4d9cd..f24ffb801b7 100644
--- a/chromium/net/socket/tcp_socket_win.h
+++ b/chromium/net/socket/tcp_socket_win.h
@@ -5,10 +5,11 @@
#ifndef NET_SOCKET_TCP_SOCKET_WIN_H_
#define NET_SOCKET_TCP_SOCKET_WIN_H_
+#include <stdint.h>
#include <winsock2.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
@@ -68,8 +69,8 @@ class NET_EXPORT TCPSocketWin : NON_EXPORTED_BASE(public base::NonThreadSafe),
// - SetKeepAlive(true, 45).
void SetDefaultOptionsForClient();
int SetExclusiveAddrUse();
- int SetReceiveBufferSize(int32 size);
- int SetSendBufferSize(int32 size);
+ int SetReceiveBufferSize(int32_t size);
+ int SetSendBufferSize(int32_t size);
bool SetKeepAlive(bool enable, int delay);
bool SetNoDelay(bool no_delay);
@@ -87,6 +88,11 @@ class NET_EXPORT TCPSocketWin : NON_EXPORTED_BASE(public base::NonThreadSafe),
bool IsValid() const { return socket_ != INVALID_SOCKET; }
+ // Detachs from the current thread, to allow the socket to be transferred to
+ // a new thread. Should only be called when the object is no longer used by
+ // the old thread.
+ void DetachFromThread();
+
// Marks the start/end of a series of connect attempts for logging purpose.
//
// TCPClientSocket may attempt to connect to multiple addresses until it
diff --git a/chromium/net/socket/transport_client_socket_pool.cc b/chromium/net/socket/transport_client_socket_pool.cc
index aaf54c5f33e..0949193ff2e 100644
--- a/chromium/net/socket/transport_client_socket_pool.cc
+++ b/chromium/net/socket/transport_client_socket_pool.cc
@@ -5,6 +5,7 @@
#include "net/socket/transport_client_socket_pool.h"
#include <algorithm>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
@@ -282,7 +283,7 @@ int TransportConnectJob::DoTransportConnect() {
if (last_connect_time.is_null()) {
interval_between_connects_ = CONNECT_INTERVAL_GT_20MS;
} else {
- int64 interval = (now - last_connect_time).InMilliseconds();
+ int64_t interval = (now - last_connect_time).InMilliseconds();
if (interval <= 10)
interval_between_connects_ = CONNECT_INTERVAL_LE_10MS;
else if (interval <= 20)
@@ -382,7 +383,7 @@ int TransportConnectJob::DoTransportConnectComplete(int result) {
break;
}
- SetSocket(transport_socket_.Pass());
+ SetSocket(std::move(transport_socket_));
} else {
// Failure will be returned via |GetAdditionalErrorState|, so save
// connection attempts from both sockets for use there.
@@ -452,7 +453,7 @@ void TransportConnectJob::DoIPv6FallbackTransportConnectComplete(int result) {
connect_timing_.connect_start = fallback_connect_start_time_;
helper_.HistogramDuration(
TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_WINS_RACE);
- SetSocket(fallback_transport_socket_.Pass());
+ SetSocket(std::move(fallback_transport_socket_));
helper_.set_next_state(TransportConnectJobHelper::STATE_NONE);
} else {
// Failure will be returned via |GetAdditionalErrorState|, so save
@@ -579,7 +580,7 @@ void TransportClientSocketPool::ReleaseSocket(
const std::string& group_name,
scoped_ptr<StreamSocket> socket,
int id) {
- base_.ReleaseSocket(group_name, socket.Pass(), id);
+ base_.ReleaseSocket(group_name, std::move(socket), id);
}
void TransportClientSocketPool::FlushWithError(int error) {
diff --git a/chromium/net/socket/transport_client_socket_pool.h b/chromium/net/socket/transport_client_socket_pool.h
index 036fd9fcddd..07a67b515a5 100644
--- a/chromium/net/socket/transport_client_socket_pool.h
+++ b/chromium/net/socket/transport_client_socket_pool.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.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 c13ffdd14b0..0140c255e18 100644
--- a/chromium/net/socket/transport_client_socket_pool_test_util.cc
+++ b/chromium/net/socket/transport_client_socket_pool_test_util.cc
@@ -4,10 +4,13 @@
#include "net/socket/transport_client_socket_pool_test_util.h"
+#include <stdint.h>
#include <string>
+#include <utility>
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -77,6 +80,10 @@ class MockConnectClientSocket : public StreamSocket {
}
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
// Socket implementation.
int Read(IOBuffer* buf,
@@ -89,8 +96,8 @@ class MockConnectClientSocket : public StreamSocket {
const CompletionCallback& callback) override {
return ERR_FAILED;
}
- int SetReceiveBufferSize(int32 size) override { return OK; }
- int SetSendBufferSize(int32 size) override { return OK; }
+ int SetReceiveBufferSize(int32_t size) override { return OK; }
+ int SetSendBufferSize(int32_t size) override { return OK; }
private:
bool connected_;
@@ -140,6 +147,10 @@ class MockFailingClientSocket : public StreamSocket {
}
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
// Socket implementation.
int Read(IOBuffer* buf,
@@ -153,8 +164,8 @@ class MockFailingClientSocket : public StreamSocket {
const CompletionCallback& callback) override {
return ERR_FAILED;
}
- int SetReceiveBufferSize(int32 size) override { return OK; }
- int SetSendBufferSize(int32 size) override { return OK; }
+ int SetReceiveBufferSize(int32_t size) override { return OK; }
+ int SetSendBufferSize(int32_t size) override { return OK; }
private:
const AddressList addrlist_;
@@ -194,7 +205,7 @@ class MockTriggerableClientSocket : public StreamSocket {
new MockTriggerableClientSocket(addrlist, should_connect, net_log));
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
socket->GetConnectCallback());
- return socket.Pass();
+ return std::move(socket);
}
static scoped_ptr<StreamSocket> MakeMockDelayedClientSocket(
@@ -206,7 +217,7 @@ class MockTriggerableClientSocket : public StreamSocket {
new MockTriggerableClientSocket(addrlist, should_connect, net_log));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, socket->GetConnectCallback(), delay);
- return socket.Pass();
+ return std::move(socket);
}
static scoped_ptr<StreamSocket> MakeMockStalledClientSocket(
@@ -221,7 +232,7 @@ class MockTriggerableClientSocket : public StreamSocket {
attempts.push_back(ConnectionAttempt(addrlist[0], ERR_CONNECTION_FAILED));
socket->AddConnectionAttempts(attempts);
}
- return socket.Pass();
+ return std::move(socket);
}
// StreamSocket implementation.
@@ -266,6 +277,10 @@ class MockTriggerableClientSocket : public StreamSocket {
connection_attempts_.insert(connection_attempts_.begin(), attempts.begin(),
attempts.end());
}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
// Socket implementation.
int Read(IOBuffer* buf,
@@ -279,8 +294,8 @@ class MockTriggerableClientSocket : public StreamSocket {
const CompletionCallback& callback) override {
return ERR_FAILED;
}
- int SetReceiveBufferSize(int32 size) override { return OK; }
- int SetSendBufferSize(int32 size) override { return OK; }
+ int SetReceiveBufferSize(int32_t size) override { return OK; }
+ int SetSendBufferSize(int32_t size) override { return OK; }
private:
void DoCallback() {
@@ -410,7 +425,7 @@ MockTransportClientSocketFactory::CreateTransportClientSocket(
// single-threaded.
if (!run_loop_quit_closure_.is_null())
run_loop_quit_closure_.Run();
- return rv.Pass();
+ return std::move(rv);
}
default:
NOTREACHED();
diff --git a/chromium/net/socket/transport_client_socket_pool_unittest.cc b/chromium/net/socket/transport_client_socket_pool_unittest.cc
index 1a00d46a47a..dab0d076398 100644
--- a/chromium/net/socket/transport_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/transport_client_socket_pool_unittest.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/platform_thread.h"
#include "net/base/ip_endpoint.h"
@@ -86,7 +87,9 @@ class TransportClientSocketPoolTest : public testing::Test {
test_base_.ReleaseAllConnections(keep_alive);
}
- ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
+ std::vector<scoped_ptr<TestSocketRequest>>* requests() {
+ return test_base_.requests();
+ }
size_t completion_count() const { return test_base_.completion_count(); }
bool connect_backup_jobs_enabled_;
diff --git a/chromium/net/socket/transport_client_socket_unittest.cc b/chromium/net/socket/transport_client_socket_unittest.cc
index 9ab358cb891..ef5291d52d5 100644
--- a/chromium/net/socket/transport_client_socket_unittest.cc
+++ b/chromium/net/socket/transport_client_socket_unittest.cc
@@ -4,7 +4,6 @@
#include <string>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -58,8 +57,8 @@ class TransportClientSocketTest
}
int DrainClientSocket(IOBuffer* buf,
- uint32 buf_len,
- uint32 bytes_to_read,
+ uint32_t buf_len,
+ uint32_t bytes_to_read,
TestCompletionCallback* callback);
// Establishes a connection to the server.
@@ -82,7 +81,7 @@ class TransportClientSocketTest
protected:
base::RunLoop connect_loop_;
- uint16 listen_port_;
+ uint16_t listen_port_;
TestNetLog net_log_;
ClientSocketFactory* const socket_factory_;
scoped_ptr<StreamSocket> sock_;
@@ -125,11 +124,11 @@ void TransportClientSocketTest::SetUp() {
int TransportClientSocketTest::DrainClientSocket(
IOBuffer* buf,
- uint32 buf_len,
- uint32 bytes_to_read,
+ uint32_t buf_len,
+ uint32_t bytes_to_read,
TestCompletionCallback* callback) {
int rv = OK;
- uint32 bytes_read = 0;
+ uint32_t bytes_read = 0;
while (bytes_read < bytes_to_read) {
rv = sock_->Read(buf, buf_len, callback->callback());
@@ -260,7 +259,7 @@ TEST_P(TransportClientSocketTest, Connect) {
TEST_P(TransportClientSocketTest, IsConnected) {
scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
TestCompletionCallback callback;
- uint32 bytes_read;
+ uint32_t bytes_read;
EXPECT_FALSE(sock_->IsConnected());
EXPECT_FALSE(sock_->IsConnectedAndIdle());
@@ -325,7 +324,7 @@ TEST_P(TransportClientSocketTest, Read) {
SendRequestAndResponse();
scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
- uint32 bytes_read =
+ uint32_t bytes_read =
DrainClientSocket(buf.get(), 4096, strlen(kServerReply), &callback);
ASSERT_EQ(bytes_read, strlen(kServerReply));
ASSERT_EQ(std::string(kServerReply), std::string(buf->data(), bytes_read));
@@ -346,7 +345,7 @@ TEST_P(TransportClientSocketTest, Read_SmallChunks) {
SendRequestAndResponse();
scoped_refptr<IOBuffer> buf(new IOBuffer(1));
- uint32 bytes_read = 0;
+ uint32_t bytes_read = 0;
while (bytes_read < strlen(kServerReply)) {
int rv = sock_->Read(buf.get(), 1, callback.callback());
EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
diff --git a/chromium/net/socket/unix_domain_client_socket_posix.cc b/chromium/net/socket/unix_domain_client_socket_posix.cc
index 5e55a92db2c..564bef80d71 100644
--- a/chromium/net/socket/unix_domain_client_socket_posix.cc
+++ b/chromium/net/socket/unix_domain_client_socket_posix.cc
@@ -6,12 +6,13 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <utility>
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
+#include "net/base/sockaddr_storage.h"
#include "net/socket/socket_posix.h"
namespace net {
@@ -23,7 +24,7 @@ UnixDomainClientSocket::UnixDomainClientSocket(const std::string& socket_path,
}
UnixDomainClientSocket::UnixDomainClientSocket(scoped_ptr<SocketPosix> socket)
- : use_abstract_namespace_(false), socket_(socket.Pass()) {}
+ : use_abstract_namespace_(false), socket_(std::move(socket)) {}
UnixDomainClientSocket::~UnixDomainClientSocket() {
Disconnect();
@@ -152,6 +153,11 @@ void UnixDomainClientSocket::GetConnectionAttempts(
out->clear();
}
+int64_t UnixDomainClientSocket::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
int UnixDomainClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(socket_);
@@ -164,12 +170,12 @@ int UnixDomainClientSocket::Write(IOBuffer* buf, int buf_len,
return socket_->Write(buf, buf_len, callback);
}
-int UnixDomainClientSocket::SetReceiveBufferSize(int32 size) {
+int UnixDomainClientSocket::SetReceiveBufferSize(int32_t size) {
NOTIMPLEMENTED();
return ERR_NOT_IMPLEMENTED;
}
-int UnixDomainClientSocket::SetSendBufferSize(int32 size) {
+int UnixDomainClientSocket::SetSendBufferSize(int32_t size) {
NOTIMPLEMENTED();
return ERR_NOT_IMPLEMENTED;
}
diff --git a/chromium/net/socket/unix_domain_client_socket_posix.h b/chromium/net/socket/unix_domain_client_socket_posix.h
index 4e2c17d5db6..260b3b9be42 100644
--- a/chromium/net/socket/unix_domain_client_socket_posix.h
+++ b/chromium/net/socket/unix_domain_client_socket_posix.h
@@ -5,9 +5,10 @@
#ifndef NET_SOCKET_UNIX_DOMAIN_CLIENT_SOCKET_POSIX_H_
#define NET_SOCKET_UNIX_DOMAIN_CLIENT_SOCKET_POSIX_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
@@ -58,6 +59,7 @@ class NET_EXPORT UnixDomainClientSocket : public StreamSocket {
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -66,8 +68,8 @@ class NET_EXPORT UnixDomainClientSocket : public StreamSocket {
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
// Releases ownership of underlying SocketDescriptor to caller.
// Internal state is reset so that this object can be used again.
diff --git a/chromium/net/socket/unix_domain_client_socket_posix_unittest.cc b/chromium/net/socket/unix_domain_client_socket_posix_unittest.cc
index fca4ad1d3cc..35830759630 100644
--- a/chromium/net/socket/unix_domain_client_socket_posix_unittest.cc
+++ b/chromium/net/socket/unix_domain_client_socket_posix_unittest.cc
@@ -5,6 +5,7 @@
#include "net/socket/unix_domain_client_socket_posix.h"
#include <unistd.h>
+#include <utility>
#include "base/bind.h"
#include "base/files/file_path.h"
@@ -13,6 +14,7 @@
#include "base/posix/eintr_wrapper.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
+#include "net/base/sockaddr_storage.h"
#include "net/base/test_completion_callback.h"
#include "net/socket/socket_posix.h"
#include "net/socket/unix_domain_server_socket_posix.h"
@@ -184,7 +186,7 @@ TEST_F(UnixDomainClientSocketTest, ConnectWithSocketDescriptor) {
ASSERT_TRUE(UnixDomainClientSocket::FillAddress(socket_path_, false, &addr));
scoped_ptr<SocketPosix> adopter(new SocketPosix);
adopter->AdoptConnectedSocket(client_socket_fd, addr);
- UnixDomainClientSocket rewrapped_socket(adopter.Pass());
+ UnixDomainClientSocket rewrapped_socket(std::move(adopter));
EXPECT_TRUE(rewrapped_socket.IsConnected());
// Try to read data.
diff --git a/chromium/net/socket/unix_domain_server_socket_posix.cc b/chromium/net/socket/unix_domain_server_socket_posix.cc
index 6b3cc9407e9..161893a4324 100644
--- a/chromium/net/socket/unix_domain_server_socket_posix.cc
+++ b/chromium/net/socket/unix_domain_server_socket_posix.cc
@@ -8,9 +8,11 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
+#include <utility>
#include "base/logging.h"
#include "net/base/net_errors.h"
+#include "net/base/sockaddr_storage.h"
#include "net/socket/socket_posix.h"
#include "net/socket/unix_domain_client_socket_posix.h"
@@ -21,7 +23,7 @@ namespace {
// Intended for use as SetterCallbacks in Accept() helper methods.
void SetStreamSocket(scoped_ptr<StreamSocket>* socket,
scoped_ptr<SocketPosix> accepted_socket) {
- socket->reset(new UnixDomainClientSocket(accepted_socket.Pass()));
+ socket->reset(new UnixDomainClientSocket(std::move(accepted_socket)));
}
void SetSocketDescriptor(SocketDescriptor* socket,
@@ -67,7 +69,7 @@ int UnixDomainServerSocket::Listen(const IPEndPoint& address, int backlog) {
int UnixDomainServerSocket::ListenWithAddressAndPort(
const std::string& unix_domain_path,
- uint16 port_unused,
+ uint16_t port_unused,
int backlog) {
DCHECK(!listen_socket_);
@@ -182,7 +184,7 @@ bool UnixDomainServerSocket::AuthenticateAndGetStreamSocket(
return false;
}
- setter_callback.Run(accept_socket_.Pass());
+ setter_callback.Run(std::move(accept_socket_));
return true;
}
diff --git a/chromium/net/socket/unix_domain_server_socket_posix.h b/chromium/net/socket/unix_domain_server_socket_posix.h
index 7dd5c1a82b1..55d2708b323 100644
--- a/chromium/net/socket/unix_domain_server_socket_posix.h
+++ b/chromium/net/socket/unix_domain_server_socket_posix.h
@@ -5,11 +5,11 @@
#ifndef NET_SOCKET_UNIX_DOMAIN_SERVER_SOCKET_POSIX_H_
#define NET_SOCKET_UNIX_DOMAIN_SERVER_SOCKET_POSIX_H_
+#include <stdint.h>
#include <sys/types.h>
#include <string>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
@@ -53,7 +53,7 @@ class NET_EXPORT UnixDomainServerSocket : public ServerSocket {
// ServerSocket implementation.
int Listen(const IPEndPoint& address, int backlog) override;
int ListenWithAddressAndPort(const std::string& unix_domain_path,
- uint16 port_unused,
+ uint16_t port_unused,
int backlog) override;
int GetLocalAddress(IPEndPoint* address) const override;
int Accept(scoped_ptr<StreamSocket>* socket,
diff --git a/chromium/net/socket/websocket_endpoint_lock_manager.h b/chromium/net/socket/websocket_endpoint_lock_manager.h
index f3887b8cd89..dfbc30897ab 100644
--- a/chromium/net/socket/websocket_endpoint_lock_manager.h
+++ b/chromium/net/socket/websocket_endpoint_lock_manager.h
@@ -5,6 +5,8 @@
#ifndef NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_
#define NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_
+#include <stddef.h>
+
#include <map>
#include "base/containers/linked_list.h"
diff --git a/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc b/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
index 29fc067b733..6808d3733fc 100644
--- a/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
+++ b/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
@@ -4,6 +4,8 @@
#include "net/socket/websocket_endpoint_lock_manager.h"
+#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/time/time.h"
@@ -62,6 +64,11 @@ class FakeStreamSocket : public StreamSocket {
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+
// Socket implementation
int Read(IOBuffer* buf,
int buf_len,
@@ -75,9 +82,9 @@ class FakeStreamSocket : public StreamSocket {
return ERR_FAILED;
}
- int SetReceiveBufferSize(int32 size) override { return ERR_FAILED; }
+ int SetReceiveBufferSize(int32_t size) override { return ERR_FAILED; }
- int SetSendBufferSize(int32 size) override { return ERR_FAILED; }
+ int SetSendBufferSize(int32_t size) override { return ERR_FAILED; }
private:
BoundNetLog bound_net_log_;
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.cc b/chromium/net/socket/websocket_transport_client_socket_pool.cc
index 4a7da5ca12f..73d8599b0e9 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool.cc
+++ b/chromium/net/socket/websocket_transport_client_socket_pool.cc
@@ -5,6 +5,7 @@
#include "net/socket/websocket_transport_client_socket_pool.h"
#include <algorithm>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/location.h"
@@ -332,16 +333,14 @@ int WebSocketTransportClientSocketPool::RequestSocket(
request_net_log.EndEvent(NetLog::TYPE_SOCKET_POOL);
} else if (rv == ERR_IO_PENDING) {
// TODO(ricea): Implement backup job timer?
- AddJob(handle, connect_job.Pass());
+ AddJob(handle, std::move(connect_job));
} else {
scoped_ptr<StreamSocket> error_socket;
connect_job->GetAdditionalErrorState(handle);
error_socket = connect_job->PassSocket();
if (error_socket) {
- HandOutSocket(error_socket.Pass(),
- connect_job->connect_timing(),
- handle,
- request_net_log);
+ HandOutSocket(std::move(error_socket), connect_job->connect_timing(),
+ handle, request_net_log);
}
}
@@ -368,7 +367,7 @@ void WebSocketTransportClientSocketPool::CancelRequest(
return;
scoped_ptr<StreamSocket> socket = handle->PassSocket();
if (socket)
- ReleaseSocket(handle->group_name(), socket.Pass(), handle->id());
+ ReleaseSocket(handle->group_name(), std::move(socket), handle->id());
if (!DeleteJob(handle))
pending_callbacks_.erase(handle);
if (!ReachedMaxSocketsLimit() && !stalled_request_queue_.empty())
@@ -449,7 +448,7 @@ scoped_ptr<base::DictionaryValue>
dict->SetInteger("max_socket_count", max_sockets_);
dict->SetInteger("max_sockets_per_group", max_sockets_);
dict->SetInteger("pool_generation_number", 0);
- return dict.Pass();
+ return dict;
}
TimeDelta WebSocketTransportClientSocketPool::ConnectionTimeout() const {
@@ -483,7 +482,7 @@ void WebSocketTransportClientSocketPool::OnConnectJobComplete(
if (result == OK) {
DCHECK(socket.get());
handed_out_socket = true;
- HandOutSocket(socket.Pass(), connect_timing, handle, request_net_log);
+ HandOutSocket(std::move(socket), connect_timing, handle, request_net_log);
request_net_log.EndEvent(NetLog::TYPE_SOCKET_POOL);
} else {
// If we got a socket, it must contain error information so pass that
@@ -491,7 +490,7 @@ void WebSocketTransportClientSocketPool::OnConnectJobComplete(
job->GetAdditionalErrorState(handle);
if (socket.get()) {
handed_out_socket = true;
- HandOutSocket(socket.Pass(), connect_timing, handle, request_net_log);
+ HandOutSocket(std::move(socket), connect_timing, handle, request_net_log);
}
request_net_log.EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, result);
}
@@ -535,7 +534,7 @@ void WebSocketTransportClientSocketPool::HandOutSocket(
ClientSocketHandle* handle,
const BoundNetLog& net_log) {
DCHECK(socket);
- handle->SetSocket(socket.Pass());
+ handle->SetSocket(std::move(socket));
DCHECK_EQ(ClientSocketHandle::UNUSED, handle->reuse_type());
DCHECK_EQ(0, handle->idle_time().InMicroseconds());
handle->set_pool_id(0);
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.h b/chromium/net/socket/websocket_transport_client_socket_pool.h
index 4eed5981c83..c0f1351dfe8 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool.h
+++ b/chromium/net/socket/websocket_transport_client_socket_pool.h
@@ -10,7 +10,7 @@
#include <set>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
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 477fdb33d47..96aa84a9921 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -102,7 +102,9 @@ class WebSocketTransportClientSocketPoolTest : public ::testing::Test {
TestSocketRequest* request(int i) { return test_base_.request(i); }
- ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
+ std::vector<scoped_ptr<TestSocketRequest>>* requests() {
+ return test_base_.requests();
+ }
size_t completion_count() const { return test_base_.completion_count(); }
TestNetLog net_log_;
diff --git a/chromium/net/socket/websocket_transport_connect_sub_job.h b/chromium/net/socket/websocket_transport_connect_sub_job.h
index 5709a461caf..36a4e943eb0 100644
--- a/chromium/net/socket/websocket_transport_connect_sub_job.h
+++ b/chromium/net/socket/websocket_transport_connect_sub_job.h
@@ -5,6 +5,9 @@
#ifndef NET_SOCKET_WEBSOCKET_TRANSPORT_CONNECT_SUB_JOB_H_
#define NET_SOCKET_WEBSOCKET_TRANSPORT_CONNECT_SUB_JOB_H_
+#include <stddef.h>
+#include <utility>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
@@ -44,7 +47,7 @@ class WebSocketTransportConnectSubJob
SubJobType type() const { return type_; }
- scoped_ptr<StreamSocket> PassSocket() { return transport_socket_.Pass(); }
+ scoped_ptr<StreamSocket> PassSocket() { return std::move(transport_socket_); }
// Implementation of WebSocketEndpointLockManager::EndpointWaiter.
void GotEndpointLock() override;
diff --git a/chromium/net/spdy/bidirectional_stream_spdy_job.cc b/chromium/net/spdy/bidirectional_stream_spdy_job.cc
new file mode 100644
index 00000000000..553d191c63d
--- /dev/null
+++ b/chromium/net/spdy/bidirectional_stream_spdy_job.cc
@@ -0,0 +1,280 @@
+// Copyright 2015 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/spdy/bidirectional_stream_spdy_job.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "net/http/bidirectional_stream_request_info.h"
+#include "net/spdy/spdy_buffer.h"
+#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_http_utils.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace net {
+
+namespace {
+
+// Time to wait in millisecond to notify |delegate_| of data received.
+// Handing small chunks of data to the caller creates measurable overhead.
+// So buffer data in short time-spans and send a single read notification.
+const int kBufferTimeMs = 1;
+
+} // namespace
+
+BidirectionalStreamSpdyJob::BidirectionalStreamSpdyJob(
+ const base::WeakPtr<SpdySession>& spdy_session)
+ : spdy_session_(spdy_session),
+ request_info_(nullptr),
+ delegate_(nullptr),
+ negotiated_protocol_(kProtoUnknown),
+ more_read_data_pending_(false),
+ read_buffer_len_(0),
+ stream_closed_(false),
+ closed_stream_status_(ERR_FAILED),
+ closed_stream_received_bytes_(0),
+ closed_stream_sent_bytes_(0),
+ weak_factory_(this) {}
+
+BidirectionalStreamSpdyJob::~BidirectionalStreamSpdyJob() {
+ if (stream_) {
+ stream_->DetachDelegate();
+ DCHECK(!stream_);
+ }
+}
+
+void BidirectionalStreamSpdyJob::Start(
+ const BidirectionalStreamRequestInfo* request_info,
+ const BoundNetLog& net_log,
+ BidirectionalStreamJob::Delegate* delegate,
+ scoped_ptr<base::Timer> timer) {
+ DCHECK(!stream_);
+ DCHECK(timer);
+
+ delegate_ = delegate;
+ timer_ = std::move(timer);
+
+ if (!spdy_session_) {
+ delegate_->OnFailed(ERR_CONNECTION_CLOSED);
+ return;
+ }
+
+ request_info_ = request_info;
+
+ int rv = stream_request_.StartRequest(
+ SPDY_BIDIRECTIONAL_STREAM, spdy_session_, request_info_->url,
+ request_info_->priority, net_log,
+ base::Bind(&BidirectionalStreamSpdyJob::OnStreamInitialized,
+ weak_factory_.GetWeakPtr()));
+ if (rv != ERR_IO_PENDING)
+ OnStreamInitialized(rv);
+}
+
+int BidirectionalStreamSpdyJob::ReadData(IOBuffer* buf, int buf_len) {
+ if (stream_)
+ DCHECK(!stream_->IsIdle());
+
+ DCHECK(buf);
+ DCHECK(buf_len);
+ DCHECK(!timer_->IsRunning()) << "There should be only one ReadData in flight";
+
+ // If there is data buffered, complete the IO immediately.
+ if (!read_data_queue_.IsEmpty()) {
+ return read_data_queue_.Dequeue(buf->data(), buf_len);
+ } else if (stream_closed_) {
+ return closed_stream_status_;
+ }
+ // Read will complete asynchronously and Delegate::OnReadCompleted will be
+ // called upon completion.
+ read_buffer_ = buf;
+ read_buffer_len_ = buf_len;
+ return ERR_IO_PENDING;
+}
+
+void BidirectionalStreamSpdyJob::SendData(IOBuffer* data,
+ int length,
+ bool end_stream) {
+ DCHECK(!stream_closed_);
+ DCHECK(stream_);
+
+ stream_->SendData(data, length,
+ end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND);
+}
+
+void BidirectionalStreamSpdyJob::Cancel() {
+ if (!stream_)
+ return;
+ // Cancels the stream and detaches the delegate so it doesn't get called back.
+ stream_->DetachDelegate();
+ DCHECK(!stream_);
+}
+
+NextProto BidirectionalStreamSpdyJob::GetProtocol() const {
+ return negotiated_protocol_;
+}
+
+int64_t BidirectionalStreamSpdyJob::GetTotalReceivedBytes() const {
+ if (stream_closed_)
+ return closed_stream_received_bytes_;
+
+ if (!stream_)
+ return 0;
+
+ return stream_->raw_received_bytes();
+}
+
+int64_t BidirectionalStreamSpdyJob::GetTotalSentBytes() const {
+ if (stream_closed_)
+ return closed_stream_sent_bytes_;
+
+ if (!stream_)
+ return 0;
+
+ return stream_->raw_sent_bytes();
+}
+
+void BidirectionalStreamSpdyJob::OnRequestHeadersSent() {
+ DCHECK(stream_);
+
+ negotiated_protocol_ = stream_->GetProtocol();
+ delegate_->OnHeadersSent();
+}
+
+SpdyResponseHeadersStatus BidirectionalStreamSpdyJob::OnResponseHeadersUpdated(
+ const SpdyHeaderBlock& response_headers) {
+ DCHECK(stream_);
+
+ delegate_->OnHeadersReceived(response_headers);
+ return RESPONSE_HEADERS_ARE_COMPLETE;
+}
+
+void BidirectionalStreamSpdyJob::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
+ DCHECK(stream_);
+ DCHECK(!stream_closed_);
+
+ // If |buffer| is null, BidirectionalStreamSpdyJob::OnClose will be invoked by
+ // SpdyStream to indicate the end of stream.
+ if (!buffer)
+ return;
+
+ // When buffer is consumed, SpdyStream::OnReadBufferConsumed will adjust
+ // recv window size accordingly.
+ read_data_queue_.Enqueue(std::move(buffer));
+ if (read_buffer_) {
+ // Handing small chunks of data to the caller creates measurable overhead.
+ // So buffer data in short time-spans and send a single read notification.
+ ScheduleBufferedRead();
+ }
+}
+
+void BidirectionalStreamSpdyJob::OnDataSent() {
+ DCHECK(stream_);
+ DCHECK(!stream_closed_);
+
+ delegate_->OnDataSent();
+}
+
+void BidirectionalStreamSpdyJob::OnTrailers(const SpdyHeaderBlock& trailers) {
+ DCHECK(stream_);
+ DCHECK(!stream_closed_);
+
+ delegate_->OnTrailersReceived(trailers);
+}
+
+void BidirectionalStreamSpdyJob::OnClose(int status) {
+ DCHECK(stream_);
+
+ stream_closed_ = true;
+ closed_stream_status_ = status;
+ closed_stream_received_bytes_ = stream_->raw_received_bytes();
+ closed_stream_sent_bytes_ = stream_->raw_sent_bytes();
+ stream_.reset();
+
+ if (status != OK) {
+ delegate_->OnFailed(status);
+ return;
+ }
+ // Complete any remaining read, as all data has been buffered.
+ // If user has not called ReadData (i.e |read_buffer_| is nullptr), this will
+ // do nothing.
+ timer_->Stop();
+ DoBufferedRead();
+}
+
+void BidirectionalStreamSpdyJob::SendRequestHeaders() {
+ scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+ 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;
+
+ CreateSpdyHeadersFromHttpRequest(
+ http_request_info, http_request_info.extra_headers,
+ stream_->GetProtocolVersion(), true, headers.get());
+ stream_->SendRequestHeaders(std::move(headers),
+ request_info_->end_stream_on_headers
+ ? NO_MORE_DATA_TO_SEND
+ : MORE_DATA_TO_SEND);
+}
+
+void BidirectionalStreamSpdyJob::OnStreamInitialized(int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ if (rv == OK) {
+ stream_ = stream_request_.ReleaseStream();
+ stream_->SetDelegate(this);
+ SendRequestHeaders();
+ return;
+ }
+ delegate_->OnFailed(rv);
+}
+
+void BidirectionalStreamSpdyJob::ScheduleBufferedRead() {
+ // If there is already a scheduled DoBufferedRead, don't issue
+ // another one. Mark that we have received more data and return.
+ if (timer_->IsRunning()) {
+ more_read_data_pending_ = true;
+ return;
+ }
+
+ more_read_data_pending_ = false;
+ timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kBufferTimeMs),
+ base::Bind(&BidirectionalStreamSpdyJob::DoBufferedRead,
+ weak_factory_.GetWeakPtr()));
+}
+
+void BidirectionalStreamSpdyJob::DoBufferedRead() {
+ DCHECK(!timer_->IsRunning());
+ // Check to see that the stream has not errored out.
+ DCHECK(stream_ || stream_closed_);
+ DCHECK(!stream_closed_ || closed_stream_status_ == OK);
+
+ // When |more_read_data_pending_| is true, it means that more data has arrived
+ // since started waiting. Wait a little longer and continue to buffer.
+ if (more_read_data_pending_ && ShouldWaitForMoreBufferedData()) {
+ ScheduleBufferedRead();
+ return;
+ }
+
+ int rv = 0;
+ if (read_buffer_) {
+ rv = ReadData(read_buffer_.get(), read_buffer_len_);
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ read_buffer_ = nullptr;
+ read_buffer_len_ = 0;
+ delegate_->OnDataRead(rv);
+ }
+}
+
+bool BidirectionalStreamSpdyJob::ShouldWaitForMoreBufferedData() const {
+ if (stream_closed_)
+ return false;
+ DCHECK_GT(read_buffer_len_, 0);
+ return read_data_queue_.GetTotalSize() <
+ static_cast<size_t>(read_buffer_len_);
+}
+
+} // namespace net
diff --git a/chromium/net/spdy/bidirectional_stream_spdy_job.h b/chromium/net/spdy/bidirectional_stream_spdy_job.h
new file mode 100644
index 00000000000..7dda52f4759
--- /dev/null
+++ b/chromium/net/spdy/bidirectional_stream_spdy_job.h
@@ -0,0 +1,102 @@
+// Copyright 2015 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_SPDY_BIDIRECTIONAL_STREAM_SPDY_JOB_H_
+#define NET_SPDY_BIDIRECTIONAL_STREAM_SPDY_JOB_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "net/http/bidirectional_stream_job.h"
+#include "net/http/bidirectional_stream_request_info.h"
+#include "net/http/http_request_info.h"
+#include "net/spdy/spdy_read_queue.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_stream.h"
+
+namespace base {
+class Timer;
+} // namespace base
+
+namespace net {
+
+class BoundNetLog;
+class IOBuffer;
+class SpdyHeaderBlock;
+
+class NET_EXPORT_PRIVATE BidirectionalStreamSpdyJob
+ : public BidirectionalStreamJob,
+ public SpdyStream::Delegate {
+ public:
+ explicit BidirectionalStreamSpdyJob(
+ const base::WeakPtr<SpdySession>& spdy_session);
+
+ ~BidirectionalStreamSpdyJob() override;
+
+ // BidirectionalStreamJob implementation:
+ void Start(const BidirectionalStreamRequestInfo* request_info,
+ const BoundNetLog& net_log,
+ BidirectionalStreamJob::Delegate* delegate,
+ scoped_ptr<base::Timer> timer) override;
+ int ReadData(IOBuffer* buf, int buf_len) override;
+ void SendData(IOBuffer* data, int length, bool end_stream) override;
+ void Cancel() override;
+ NextProto GetProtocol() const override;
+ int64_t GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
+
+ // SpdyStream::Delegate implementation:
+ void OnRequestHeadersSent() override;
+ SpdyResponseHeadersStatus OnResponseHeadersUpdated(
+ const SpdyHeaderBlock& response_headers) override;
+ void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override;
+ void OnDataSent() override;
+ void OnTrailers(const SpdyHeaderBlock& trailers) override;
+ void OnClose(int status) override;
+
+ private:
+ void SendRequestHeaders();
+ void OnStreamInitialized(int rv);
+ void ScheduleBufferedRead();
+ void DoBufferedRead();
+ bool ShouldWaitForMoreBufferedData() const;
+
+ const base::WeakPtr<SpdySession> spdy_session_;
+ const BidirectionalStreamRequestInfo* request_info_;
+ BidirectionalStreamJob::Delegate* delegate_;
+ scoped_ptr<base::Timer> timer_;
+ SpdyStreamRequest stream_request_;
+ base::WeakPtr<SpdyStream> stream_;
+
+ NextProto negotiated_protocol_;
+
+ // Buffers the data as it arrives asynchronously from the stream.
+ SpdyReadQueue read_data_queue_;
+ // Whether received more data has arrived since started waiting.
+ bool more_read_data_pending_;
+ // User provided read buffer for ReadData() response.
+ scoped_refptr<IOBuffer> read_buffer_;
+ int read_buffer_len_;
+
+ // Whether OnClose has been invoked.
+ bool stream_closed_;
+ // Status reported in OnClose.
+ int closed_stream_status_;
+ // After |stream_| has been closed, this keeps track of the total number of
+ // bytes received over the network for |stream_| while it was open.
+ int64_t closed_stream_received_bytes_;
+ // After |stream_| has been closed, this keeps track of the total number of
+ // bytes sent over the network for |stream_| while it was open.
+ int64_t closed_stream_sent_bytes_;
+
+ base::WeakPtrFactory<BidirectionalStreamSpdyJob> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(BidirectionalStreamSpdyJob);
+};
+
+} // namespace net
+
+#endif // NET_SPDY_BIDIRECTIONAL_STREAM_SPDY_JOB_H_
diff --git a/chromium/net/spdy/buffered_spdy_framer.cc b/chromium/net/spdy/buffered_spdy_framer.cc
index 2fa15b8b9b8..d68dea78f01 100644
--- a/chromium/net/spdy/buffered_spdy_framer.cc
+++ b/chromium/net/spdy/buffered_spdy_framer.cc
@@ -8,11 +8,19 @@
namespace net {
+namespace {
+
+// GOAWAY frame debug data is only buffered up to this many bytes.
+size_t kGoAwayDebugDataMaxSize = 1024;
+
+// Initial and maximum sizes for header block buffer.
+size_t kHeaderBufferInitialSize = 8 * 1024;
+size_t kHeaderBufferMaxSize = 256 * 1024;
+
+} // namespace
+
SpdyMajorVersion NextProtoToSpdyMajorVersion(NextProto next_proto) {
switch (next_proto) {
- case kProtoDeprecatedSPDY2:
- return SPDY2;
- case kProtoSPDY3:
case kProtoSPDY31:
return SPDY3;
case kProtoHTTP2:
@@ -23,19 +31,17 @@ SpdyMajorVersion NextProtoToSpdyMajorVersion(NextProto next_proto) {
break;
}
NOTREACHED();
- return SPDY2;
+ return HTTP2;
}
BufferedSpdyFramer::BufferedSpdyFramer(SpdyMajorVersion version,
bool enable_compression)
: spdy_framer_(version),
visitor_(NULL),
- header_buffer_used_(0),
header_buffer_valid_(false),
header_stream_id_(SpdyFramer::kInvalidStream),
frames_received_(0) {
spdy_framer_.set_enable_compression(enable_compression);
- memset(header_buffer_, 0, sizeof(header_buffer_));
}
BufferedSpdyFramer::~BufferedSpdyFramer() {
@@ -120,11 +126,8 @@ bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
CHECK(header_buffer_valid_);
SpdyHeaderBlock headers;
- size_t parsed_len = spdy_framer_.ParseHeaderBlockInBuffer(
- header_buffer_, header_buffer_used_, &headers);
- // TODO(rch): this really should be checking parsed_len != len,
- // but a bunch of tests fail. Need to figure out why.
- if (parsed_len == 0) {
+ if (!spdy_framer_.ParseHeaderBlockInBuffer(
+ header_buffer_.data(), header_buffer_.size(), &headers)) {
visitor_->OnStreamError(
stream_id, "Could not parse Spdy Control Frame Header.");
return false;
@@ -167,15 +170,22 @@ bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
return true;
}
- const size_t available = kHeaderBufferSize - header_buffer_used_;
- if (len > available) {
+ const size_t new_size = header_buffer_.size() + len;
+ if (new_size > kHeaderBufferMaxSize) {
header_buffer_valid_ = false;
- visitor_->OnStreamError(
- stream_id, "Received more data than the allocated size.");
+ visitor_->OnStreamError(stream_id, "Received too much header data.");
return false;
}
- memcpy(header_buffer_ + header_buffer_used_, header_data, len);
- header_buffer_used_ += len;
+
+ if (new_size > header_buffer_.capacity()) {
+ // Grow |header_buffer_| exponentially to reduce memory allocations and
+ // copies.
+ size_t new_capacity = std::max(new_size, kHeaderBufferInitialSize);
+ new_capacity = std::max(new_capacity, 2 * header_buffer_.capacity());
+ new_capacity = std::min(new_capacity, kHeaderBufferMaxSize);
+ header_buffer_.reserve(new_capacity);
+ }
+ header_buffer_.append(header_data, len);
return true;
}
@@ -198,13 +208,23 @@ void BufferedSpdyFramer::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
visitor_->OnStreamPadding(stream_id, len);
}
+SpdyHeadersHandlerInterface* BufferedSpdyFramer::OnHeaderFrameStart(
+ SpdyStreamId stream_id) {
+ return visitor_->OnHeaderFrameStart(stream_id);
+}
+
+void BufferedSpdyFramer::OnHeaderFrameEnd(SpdyStreamId stream_id,
+ bool end_headers) {
+ visitor_->OnHeaderFrameEnd(stream_id, end_headers);
+}
+
void BufferedSpdyFramer::OnSettings(bool clear_persisted) {
visitor_->OnSettings(clear_persisted);
}
void BufferedSpdyFramer::OnSetting(SpdySettingsIds id,
- uint8 flags,
- uint32 value) {
+ uint8_t flags,
+ uint32_t value) {
visitor_->OnSetting(id, flags, value);
}
@@ -226,7 +246,26 @@ void BufferedSpdyFramer::OnRstStream(SpdyStreamId stream_id,
}
void BufferedSpdyFramer::OnGoAway(SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status) {
- visitor_->OnGoAway(last_accepted_stream_id, status);
+ DCHECK(!goaway_fields_);
+ goaway_fields_.reset(new GoAwayFields());
+ goaway_fields_->last_accepted_stream_id = last_accepted_stream_id;
+ goaway_fields_->status = status;
+}
+
+bool BufferedSpdyFramer::OnGoAwayFrameData(const char* goaway_data,
+ size_t len) {
+ if (len > 0) {
+ if (goaway_fields_->debug_data.size() < kGoAwayDebugDataMaxSize) {
+ goaway_fields_->debug_data.append(
+ goaway_data, std::min(len, kGoAwayDebugDataMaxSize -
+ goaway_fields_->debug_data.size()));
+ }
+ return true;
+ }
+ visitor_->OnGoAway(goaway_fields_->last_accepted_stream_id,
+ goaway_fields_->status, goaway_fields_->debug_data);
+ goaway_fields_.reset();
+ return true;
}
void BufferedSpdyFramer::OnWindowUpdate(SpdyStreamId stream_id,
@@ -320,9 +359,7 @@ SpdyFrame* BufferedSpdyFramer::CreateSynReply(
SpdyFrame* BufferedSpdyFramer::CreateRstStream(
SpdyStreamId stream_id,
SpdyRstStreamStatus status) const {
- // RST_STREAM payloads are not part of any SPDY spec.
- // SpdyFramer will accept them, but don't create them.
- SpdyRstStreamIR rst_ir(stream_id, status, "");
+ SpdyRstStreamIR rst_ir(stream_id, status);
return spdy_framer_.SerializeRstStream(rst_ir);
}
@@ -354,8 +391,9 @@ SpdyFrame* BufferedSpdyFramer::CreatePingFrame(SpdyPingId unique_id,
// TODO(jgraettinger): Eliminate uses of this method (prefer SpdyGoAwayIR).
SpdyFrame* BufferedSpdyFramer::CreateGoAway(
SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) const {
- SpdyGoAwayIR go_ir(last_accepted_stream_id, status, "");
+ SpdyGoAwayStatus status,
+ base::StringPiece debug_data) const {
+ SpdyGoAwayIR go_ir(last_accepted_stream_id, status, debug_data);
return spdy_framer_.SerializeGoAway(go_ir);
}
@@ -379,7 +417,7 @@ SpdyFrame* BufferedSpdyFramer::CreateHeaders(
// SpdyWindowUpdateIR).
SpdyFrame* BufferedSpdyFramer::CreateWindowUpdate(
SpdyStreamId stream_id,
- uint32 delta_window_size) const {
+ uint32_t delta_window_size) const {
SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
return spdy_framer_.SerializeWindowUpdate(update_ir);
}
@@ -387,7 +425,7 @@ SpdyFrame* BufferedSpdyFramer::CreateWindowUpdate(
// TODO(jgraettinger): Eliminate uses of this method (prefer SpdyDataIR).
SpdyFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
const char* data,
- uint32 len,
+ uint32_t len,
SpdyDataFlags flags) {
SpdyDataIR data_ir(stream_id,
base::StringPiece(data, len));
@@ -410,8 +448,7 @@ SpdyPriority BufferedSpdyFramer::GetHighestPriority() const {
}
void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) {
- memset(header_buffer_, 0, kHeaderBufferSize);
- header_buffer_used_ = 0;
+ header_buffer_.clear();
header_buffer_valid_ = true;
header_stream_id_ = stream_id;
DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
diff --git a/chromium/net/spdy/buffered_spdy_framer.h b/chromium/net/spdy/buffered_spdy_framer.h
index ee73f0893cb..5f893ad44d8 100644
--- a/chromium/net/spdy/buffered_spdy_framer.h
+++ b/chromium/net/spdy/buffered_spdy_framer.h
@@ -5,9 +5,12 @@
#ifndef NET_SPDY_BUFFERED_SPDY_FRAMER_H_
#define NET_SPDY_BUFFERED_SPDY_FRAMER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/socket/next_proto.h"
@@ -77,13 +80,27 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
// |len| The number of padding octets.
virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0;
+ // Called just before processing the payload of a frame containing header
+ // data. Should return an implementation of SpdyHeadersHandlerInterface that
+ // will receive headers for stream |stream_id|. The caller will not take
+ // ownership of the headers handler. The same instance should be returned
+ // for all header frames comprising a logical header block (i.e. until
+ // OnHeaderFrameEnd() is called with end_headers == true).
+ virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) = 0;
+
+ // Called after processing the payload of a frame containing header data.
+ // |end_headers| is true if there will not be any subsequent CONTINUATION
+ // frames.
+ virtual void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) = 0;
+
// Called when a SETTINGS frame is received.
// |clear_persisted| True if the respective flag is set on the SETTINGS frame.
virtual void OnSettings(bool clear_persisted) = 0;
// Called when an individual setting within a SETTINGS frame has been parsed
// and validated.
- virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
+ virtual void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) = 0;
// Called when a SETTINGS frame is received with the ACK flag set.
virtual void OnSettingsAck() {}
@@ -100,7 +117,8 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
// Called when a GOAWAY frame has been parsed.
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) = 0;
+ SpdyGoAwayStatus status,
+ base::StringPiece debug_data) = 0;
// Called when a WINDOW_UPDATE frame has been parsed.
virtual void OnWindowUpdate(SpdyStreamId stream_id,
@@ -165,14 +183,18 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
size_t len,
bool fin) override;
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override;
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override;
void OnSettings(bool clear_persisted) override;
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override;
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override;
void OnSettingsAck() override;
void OnSettingsEnd() override;
void OnPing(SpdyPingId unique_id, bool is_ack) override;
void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override;
void OnGoAway(SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status) override;
+ bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
void OnPushPromise(SpdyStreamId stream_id,
SpdyStreamId promised_stream_id,
@@ -203,19 +225,18 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
SpdyRstStreamStatus status) const;
SpdyFrame* CreateSettings(const SettingsMap& values) const;
SpdyFrame* CreatePingFrame(SpdyPingId unique_id, bool is_ack) const;
- SpdyFrame* CreateGoAway(
- SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) const;
+ SpdyFrame* CreateGoAway(SpdyStreamId last_accepted_stream_id,
+ SpdyGoAwayStatus status,
+ base::StringPiece debug_data) const;
SpdyFrame* CreateHeaders(SpdyStreamId stream_id,
SpdyControlFlags flags,
SpdyPriority priority,
const SpdyHeaderBlock* headers);
- SpdyFrame* CreateWindowUpdate(
- SpdyStreamId stream_id,
- uint32 delta_window_size) const;
+ SpdyFrame* CreateWindowUpdate(SpdyStreamId stream_id,
+ uint32_t delta_window_size) const;
SpdyFrame* CreateDataFrame(SpdyStreamId stream_id,
const char* data,
- uint32 len,
+ uint32_t len,
SpdyDataFlags flags);
SpdyFrame* CreatePushPromise(SpdyStreamId stream_id,
SpdyStreamId promised_stream_id,
@@ -255,17 +276,13 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
int frames_received() const { return frames_received_; }
private:
- // The size of the header_buffer_.
- enum { kHeaderBufferSize = 32 * 1024 };
-
void InitHeaderStreaming(SpdyStreamId stream_id);
SpdyFramer spdy_framer_;
BufferedSpdyFramerVisitorInterface* visitor_;
// Header block streaming state:
- char header_buffer_[kHeaderBufferSize];
- size_t header_buffer_used_;
+ std::string header_buffer_;
bool header_buffer_valid_;
SpdyStreamId header_stream_id_;
int frames_received_;
@@ -281,12 +298,19 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
SpdyPriority priority;
SpdyStreamId parent_stream_id;
bool exclusive;
- uint8 credential_slot;
bool fin;
bool unidirectional;
};
scoped_ptr<ControlFrameFields> control_frame_fields_;
+ // Collection of fields of a GOAWAY frame that this class needs to buffer.
+ struct GoAwayFields {
+ SpdyStreamId last_accepted_stream_id;
+ SpdyGoAwayStatus status;
+ std::string debug_data;
+ };
+ scoped_ptr<GoAwayFields> goaway_fields_;
+
DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
};
diff --git a/chromium/net/spdy/buffered_spdy_framer_unittest.cc b/chromium/net/spdy/buffered_spdy_framer_unittest.cc
index 5f05fa1d208..fd61298e7a0 100644
--- a/chromium/net/spdy/buffered_spdy_framer_unittest.cc
+++ b/chromium/net/spdy/buffered_spdy_framer_unittest.cc
@@ -21,9 +21,9 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
syn_reply_frame_count_(0),
headers_frame_count_(0),
push_promise_frame_count_(0),
+ goaway_count_(0),
header_stream_id_(static_cast<SpdyStreamId>(-1)),
- promised_stream_id_(static_cast<SpdyStreamId>(-1)) {
- }
+ promised_stream_id_(static_cast<SpdyStreamId>(-1)) {}
void OnError(SpdyFramer::SpdyError error_code) override {
LOG(INFO) << "SpdyFramer Error: " << error_code;
@@ -88,9 +88,19 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
LOG(FATAL) << "Unexpected OnStreamPadding call.";
}
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override {
+ LOG(FATAL) << "Unexpected OnHeaderFrameStart call.";
+ return nullptr;
+ }
+
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override {
+ LOG(FATAL) << "Unexpected OnHeaderFrameEnd call.";
+ }
+
void OnSettings(bool clear_persisted) override {}
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override {
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {
setting_count_++;
}
@@ -100,11 +110,12 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
SpdyRstStreamStatus status) override {}
void OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) override {}
-
- bool OnCredentialFrameData(const char*, size_t) {
- LOG(FATAL) << "Unexpected OnCredentialFrameData call.";
- return false;
+ SpdyGoAwayStatus status,
+ StringPiece debug_data) override {
+ goaway_count_++;
+ goaway_last_accepted_stream_id_ = last_accepted_stream_id;
+ goaway_status_ = status;
+ goaway_debug_data_.assign(debug_data.data(), debug_data.size());
}
void OnDataFrameHeader(const SpdyFrame* frame) {
@@ -131,8 +142,6 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
return true;
}
- void OnCredential(const SpdyFrame& frame) {}
-
// Convenience function which runs a framer simulation with particular input.
void SimulateInFramer(const unsigned char* input, size_t size) {
buffered_spdy_framer_.set_visitor(this);
@@ -162,6 +171,7 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
int syn_reply_frame_count_;
int headers_frame_count_;
int push_promise_frame_count_;
+ int goaway_count_;
// Header block streaming state:
SpdyStreamId header_stream_id_;
@@ -170,6 +180,11 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
// Headers from OnSyn, OnSynReply, OnHeaders and OnPushPromise for
// verification.
SpdyHeaderBlock headers_;
+
+ // OnGoAway parameters.
+ SpdyStreamId goaway_last_accepted_stream_id_;
+ SpdyGoAwayStatus goaway_status_;
+ std::string goaway_debug_data_;
};
} // namespace
@@ -178,33 +193,6 @@ class BufferedSpdyFramerTest
: public PlatformTest,
public ::testing::WithParamInterface<NextProto> {
protected:
- // Returns true if the two header blocks have equivalent content.
- bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
- const SpdyHeaderBlock* actual) {
- if (expected->size() != actual->size()) {
- LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
- << actual->size() << ".";
- return false;
- }
- for (SpdyHeaderBlock::const_iterator it = expected->begin();
- it != expected->end();
- ++it) {
- SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
- if (it2 == actual->end()) {
- LOG(ERROR) << "Expected header name '" << it->first << "'.";
- return false;
- }
- if (it->second.compare(it2->second) != 0) {
- LOG(ERROR) << "Expected header named '" << it->first
- << "' to have a value of '" << it->second
- << "'. The actual value received was '" << it2->second
- << "'.";
- return false;
- }
- }
- return true;
- }
-
SpdyMajorVersion spdy_version() {
return NextProtoToSpdyMajorVersion(GetParam());
}
@@ -256,7 +244,7 @@ TEST_P(BufferedSpdyFramerTest, ReadSynStreamHeaderBlock) {
EXPECT_EQ(0, visitor.syn_reply_frame_count_);
EXPECT_EQ(0, visitor.headers_frame_count_);
EXPECT_EQ(0, visitor.push_promise_frame_count_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(BufferedSpdyFramerTest, ReadSynReplyHeaderBlock) {
@@ -288,7 +276,7 @@ TEST_P(BufferedSpdyFramerTest, ReadSynReplyHeaderBlock) {
EXPECT_EQ(0, visitor.syn_reply_frame_count_);
EXPECT_EQ(1, visitor.headers_frame_count_);
}
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(BufferedSpdyFramerTest, ReadHeadersHeaderBlock) {
@@ -312,7 +300,7 @@ TEST_P(BufferedSpdyFramerTest, ReadHeadersHeaderBlock) {
EXPECT_EQ(0, visitor.syn_reply_frame_count_);
EXPECT_EQ(1, visitor.headers_frame_count_);
EXPECT_EQ(0, visitor.push_promise_frame_count_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(BufferedSpdyFramerTest, ReadPushPromiseHeaderBlock) {
@@ -335,9 +323,27 @@ TEST_P(BufferedSpdyFramerTest, ReadPushPromiseHeaderBlock) {
EXPECT_EQ(0, visitor.syn_reply_frame_count_);
EXPECT_EQ(0, visitor.headers_frame_count_);
EXPECT_EQ(1, visitor.push_promise_frame_count_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
EXPECT_EQ(1u, visitor.header_stream_id_);
EXPECT_EQ(2u, visitor.promised_stream_id_);
}
+TEST_P(BufferedSpdyFramerTest, GoAwayDebugData) {
+ if (spdy_version() < HTTP2)
+ return;
+ BufferedSpdyFramer framer(spdy_version(), true);
+ scoped_ptr<SpdyFrame> goaway_frame(
+ framer.CreateGoAway(2u, GOAWAY_FRAME_SIZE_ERROR, "foo"));
+
+ TestBufferedSpdyVisitor visitor(spdy_version());
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(goaway_frame.get()->data()),
+ goaway_frame.get()->size());
+ EXPECT_EQ(0, visitor.error_count_);
+ EXPECT_EQ(1, visitor.goaway_count_);
+ EXPECT_EQ(2u, visitor.goaway_last_accepted_stream_id_);
+ EXPECT_EQ(GOAWAY_FRAME_SIZE_ERROR, visitor.goaway_status_);
+ EXPECT_EQ("foo", visitor.goaway_debug_data_);
+}
+
} // namespace net
diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_mutator.cc b/chromium/net/spdy/fuzzing/hpack_fuzz_mutator.cc
index 6301070e3c1..c0e76d25ffc 100644
--- a/chromium/net/spdy/fuzzing/hpack_fuzz_mutator.cc
+++ b/chromium/net/spdy/fuzzing/hpack_fuzz_mutator.cc
@@ -65,9 +65,8 @@ int main(int argc, char** argv) {
StringPiece block;
while (HpackFuzzUtil::NextHeaderBlock(&input, &block)) {
HpackFuzzUtil::FlipBits(
- reinterpret_cast<uint8*>(const_cast<char*>(block.data())),
- block.size(),
- flip_ratio);
+ reinterpret_cast<uint8_t*>(const_cast<char*>(block.data())),
+ block.size(), flip_ratio);
string prefix = HpackFuzzUtil::HeaderBlockPrefix(block.size());
diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_util.cc b/chromium/net/spdy/fuzzing/hpack_fuzz_util.cc
index 6a7caf7502b..d82e34c52a3 100644
--- a/chromium/net/spdy/fuzzing/hpack_fuzz_util.cc
+++ b/chromium/net/spdy/fuzzing/hpack_fuzz_util.cc
@@ -117,12 +117,13 @@ bool HpackFuzzUtil::NextHeaderBlock(Input* input,
// ClusterFuzz may truncate input files if the fuzzer ran out of allocated
// disk space. Be tolerant of these.
CHECK_LE(input->offset, input->input.size());
- if (input->remaining() < sizeof(uint32)) {
+ if (input->remaining() < sizeof(uint32_t)) {
return false;
}
- size_t length = ntohl(*reinterpret_cast<const uint32*>(input->ptr()));
- input->offset += sizeof(uint32);
+ size_t length =
+ base::NetToHost32(*reinterpret_cast<const uint32_t*>(input->ptr()));
+ input->offset += sizeof(uint32_t);
if (input->remaining() < length) {
return false;
@@ -134,15 +135,15 @@ bool HpackFuzzUtil::NextHeaderBlock(Input* input,
// static
string HpackFuzzUtil::HeaderBlockPrefix(size_t block_size) {
- uint32 length = htonl(block_size);
- return string(reinterpret_cast<char*>(&length), sizeof(uint32));
+ uint32_t length = base::HostToNet32(static_cast<uint32_t>(block_size));
+ return string(reinterpret_cast<char*>(&length), sizeof(uint32_t));
}
// static
void HpackFuzzUtil::InitializeFuzzerContext(FuzzerContext* context) {
- context->first_stage.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
+ context->first_stage.reset(new HpackDecoder());
context->second_stage.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
- context->third_stage.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
+ context->third_stage.reset(new HpackDecoder());
}
// static
@@ -150,10 +151,10 @@ bool HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages(FuzzerContext* context,
StringPiece input_block) {
// First stage: Decode the input header block. This may fail on invalid input.
if (!context->first_stage->HandleControlFrameHeadersData(
- 1, input_block.data(), input_block.size())) {
+ input_block.data(), input_block.size())) {
return false;
}
- if (!context->first_stage->HandleControlFrameHeadersComplete(1, nullptr)) {
+ if (!context->first_stage->HandleControlFrameHeadersComplete(nullptr)) {
return false;
}
// Second stage: Re-encode the decoded header block. This must succeed.
@@ -165,24 +166,25 @@ bool HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages(FuzzerContext* context,
// don't require it. It's possible for the stage-two encoder to produce an
// output which violates decoder size tolerances.
if (!context->third_stage->HandleControlFrameHeadersData(
- 1, second_stage_out.data(), second_stage_out.length())) {
+ second_stage_out.data(), second_stage_out.length())) {
return false;
}
- if (!context->third_stage->HandleControlFrameHeadersComplete(1, nullptr)) {
+ if (!context->third_stage->HandleControlFrameHeadersComplete(nullptr)) {
return false;
}
return true;
}
// static
-void HpackFuzzUtil::FlipBits(uint8* buffer, size_t buffer_length,
+void HpackFuzzUtil::FlipBits(uint8_t* buffer,
+ size_t buffer_length,
size_t flip_per_thousand) {
- uint64 buffer_bit_length = buffer_length * 8u;
- uint64 bits_to_flip = flip_per_thousand * (1 + buffer_bit_length / 1024);
+ uint64_t buffer_bit_length = buffer_length * 8u;
+ uint64_t bits_to_flip = flip_per_thousand * (1 + buffer_bit_length / 1024);
// Iteratively identify & flip offsets in the buffer bit-sequence.
- for (uint64 i = 0; i != bits_to_flip; ++i) {
- uint64 bit_offset = base::RandUint64() % buffer_bit_length;
+ for (uint64_t i = 0; i != bits_to_flip; ++i) {
+ uint64_t bit_offset = base::RandUint64() % buffer_bit_length;
buffer[bit_offset / 8u] ^= (1 << (bit_offset % 8u));
}
}
diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_util.h b/chromium/net/spdy/fuzzing/hpack_fuzz_util.h
index a15a3fd2995..3ee64e6b3fe 100644
--- a/chromium/net/spdy/fuzzing/hpack_fuzz_util.h
+++ b/chromium/net/spdy/fuzzing/hpack_fuzz_util.h
@@ -5,6 +5,9 @@
#ifndef NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_
#define NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -82,7 +85,7 @@ class NET_EXPORT_PRIVATE HpackFuzzUtil {
// Flips random bits within |buffer|. The total number of flips is
// |flip_per_thousand| bits for every 1,024 bytes of |buffer_length|,
// rounding up.
- static void FlipBits(uint8* buffer,
+ static void FlipBits(uint8_t* buffer,
size_t buffer_length,
size_t flip_per_thousand);
};
diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc b/chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc
index 732b90d4869..ecbcb6b2a7a 100644
--- a/chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc
+++ b/chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc
@@ -108,8 +108,7 @@ TEST(HpackFuzzUtilTest, PassValidInputThroughAllStages) {
expect[":scheme"] = "http";
expect[":path"] = "/";
expect[":authority"] = "www.example.com";
- EXPECT_TRUE(
- CompareSpdyHeaderBlocks(expect, context.third_stage->decoded_block()));
+ EXPECT_EQ(expect, context.third_stage->decoded_block());
}
TEST(HpackFuzzUtilTest, ValidFuzzExamplesRegressionTest) {
@@ -141,9 +140,8 @@ TEST(HpackFuzzUtilTest, FlipBitsMutatesBuffer) {
string unmodified(buffer, arraysize(buffer) - 1);
EXPECT_EQ(unmodified, buffer);
- HpackFuzzUtil::FlipBits(reinterpret_cast<uint8*>(buffer),
- arraysize(buffer) - 1,
- 1);
+ HpackFuzzUtil::FlipBits(reinterpret_cast<uint8_t*>(buffer),
+ arraysize(buffer) - 1, 1);
EXPECT_NE(unmodified, buffer);
}
diff --git a/chromium/net/spdy/hpack/hpack_constants.h b/chromium/net/spdy/hpack/hpack_constants.h
index 4110260cc1d..a247e405dcc 100644
--- a/chromium/net/spdy/hpack/hpack_constants.h
+++ b/chromium/net/spdy/hpack/hpack_constants.h
@@ -5,9 +5,11 @@
#ifndef NET_SPDY_HPACK_CONSTANTS_H_
#define NET_SPDY_HPACK_CONSTANTS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
// All section references below are to
@@ -18,15 +20,15 @@ namespace net {
// An HpackPrefix signifies |bits| stored in the top |bit_size| bits
// of an octet.
struct HpackPrefix {
- uint8 bits;
+ uint8_t bits;
size_t bit_size;
};
// Represents a symbol and its Huffman code (stored in most-significant bits).
struct HpackHuffmanSymbol {
- uint32 code;
- uint8 length;
- uint16 id;
+ uint32_t code;
+ uint8_t length;
+ uint16_t id;
};
// An entry in the static table. Must be a POD in order to avoid static
@@ -41,16 +43,17 @@ struct HpackStaticEntry {
class HpackHuffmanTable;
class HpackStaticTable;
-const uint32 kDefaultHeaderTableSizeSetting = 4096;
+// Defined in RFC 7540 section 6.5.2.
+const uint32_t kDefaultHeaderTableSizeSetting = 4096;
// Largest string literal an HpackDecoder/HpackEncoder will attempt to process
// before returning an error.
-const uint32 kDefaultMaxStringLiteralSize = 16 * 1024;
+const uint32_t kDefaultMaxStringLiteralSize = 256 * 1024;
// Maximum amount of encoded header buffer HpackDecoder will retain before
// returning an error.
// TODO(jgraettinger): Remove with SpdyHeadersHandlerInterface switch.
-const uint32 kMaxDecodeBufferSize = 32 * 1024;
+const uint32_t kMaxDecodeBufferSize = 256 * 1024;
// 6.2: Flag for a string literal that is stored unmodified (i.e.,
// without Huffman encoding).
diff --git a/chromium/net/spdy/hpack/hpack_decoder.cc b/chromium/net/spdy/hpack/hpack_decoder.cc
index d729919e492..13654dd3f5c 100644
--- a/chromium/net/spdy/hpack/hpack_decoder.cc
+++ b/chromium/net/spdy/hpack/hpack_decoder.cc
@@ -6,7 +6,6 @@
#include <utility>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/hpack/hpack_output_stream.h"
@@ -22,18 +21,23 @@ const char kCookieKey[] = "cookie";
} // namespace
-HpackDecoder::HpackDecoder(const HpackHuffmanTable& table)
+HpackDecoder::HpackDecoder()
: max_string_literal_size_(kDefaultMaxStringLiteralSize),
+ handler_(nullptr),
regular_header_seen_(false),
- huffman_table_(table) {}
+ header_block_started_(false) {}
HpackDecoder::~HpackDecoder() {}
-bool HpackDecoder::HandleControlFrameHeadersData(SpdyStreamId id,
- const char* headers_data,
+bool HpackDecoder::HandleControlFrameHeadersData(const char* headers_data,
size_t headers_data_length) {
decoded_block_.clear();
-
+ if (!header_block_started_) {
+ header_block_started_ = true;
+ if (handler_ != nullptr) {
+ handler_->OnHeaderBlockStart();
+ }
+ }
size_t new_size = headers_block_buffer_.size() + headers_data_length;
if (new_size > kMaxDecodeBufferSize) {
return false;
@@ -43,8 +47,7 @@ bool HpackDecoder::HandleControlFrameHeadersData(SpdyStreamId id,
return true;
}
-bool HpackDecoder::HandleControlFrameHeadersComplete(SpdyStreamId id,
- size_t* compressed_len) {
+bool HpackDecoder::HandleControlFrameHeadersComplete(size_t* compressed_len) {
HpackInputStream input_stream(max_string_literal_size_,
headers_block_buffer_);
regular_header_seen_ = false;
@@ -57,8 +60,12 @@ bool HpackDecoder::HandleControlFrameHeadersComplete(SpdyStreamId id,
return false;
}
}
+ if (handler_ != nullptr) {
+ handler_->OnHeaderBlockEnd(headers_block_buffer_.size());
+ }
headers_block_buffer_.clear();
-
+ header_block_started_ = false;
+ handler_ = nullptr;
return true;
}
@@ -75,16 +82,21 @@ bool HpackDecoder::HandleHeaderRepresentation(StringPiece name,
}
}
- auto it = decoded_block_.find(name);
- if (it == decoded_block_.end()) {
- // This is a new key.
- decoded_block_[name] = value;
+ if (handler_ == nullptr) {
+ auto it = decoded_block_.find(name);
+ if (it == decoded_block_.end()) {
+ // This is a new key.
+ decoded_block_[name] = value;
+ } else {
+ // The key already exists, append |value| with appropriate delimiter.
+ string new_value = it->second.as_string();
+ new_value.append((name == kCookieKey) ? "; " : string(1, '\0'));
+ value.AppendToString(&new_value);
+ decoded_block_.ReplaceOrAppendHeader(name, new_value);
+ }
} else {
- // The key already exists, append |value| with appropriate delimiter.
- string new_value = it->second.as_string();
- new_value.append((name == kCookieKey) ? "; " : string(1, '\0'));
- value.AppendToString(&new_value);
- decoded_block_.ReplaceOrAppendHeader(name, new_value);
+ DCHECK(decoded_block_.empty());
+ handler_->OnHeader(name, value);
}
return true;
}
@@ -117,7 +129,7 @@ bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) {
bool HpackDecoder::DecodeNextHeaderTableSizeUpdate(
HpackInputStream* input_stream) {
- uint32 size = 0;
+ uint32_t size = 0;
if (!input_stream->DecodeNextUint32(&size)) {
return false;
}
@@ -129,7 +141,7 @@ bool HpackDecoder::DecodeNextHeaderTableSizeUpdate(
}
bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) {
- uint32 index = 0;
+ uint32_t index = 0;
if (!input_stream->DecodeNextUint32(&index)) {
return false;
}
@@ -168,7 +180,7 @@ bool HpackDecoder::DecodeNextLiteralHeader(HpackInputStream* input_stream,
bool HpackDecoder::DecodeNextName(HpackInputStream* input_stream,
StringPiece* next_name) {
- uint32 index_or_zero = 0;
+ uint32_t index_or_zero = 0;
if (!input_stream->DecodeNextUint32(&index_or_zero)) {
return false;
}
@@ -196,7 +208,7 @@ bool HpackDecoder::DecodeNextStringLiteral(HpackInputStream* input_stream,
StringPiece* output) {
if (input_stream->MatchPrefixAndConsume(kStringLiteralHuffmanEncoded)) {
string* buffer = is_key ? &key_buffer_ : &value_buffer_;
- bool result = input_stream->DecodeNextHuffmanString(huffman_table_, buffer);
+ bool result = input_stream->DecodeNextHuffmanString(buffer);
*output = StringPiece(*buffer);
return result;
}
diff --git a/chromium/net/spdy/hpack/hpack_decoder.h b/chromium/net/spdy/hpack/hpack_decoder.h
index 93ffae00ea7..da6162d7f37 100644
--- a/chromium/net/spdy/hpack/hpack_decoder.h
+++ b/chromium/net/spdy/hpack/hpack_decoder.h
@@ -5,16 +5,19 @@
#ifndef NET_SPDY_HPACK_DECODER_H_
#define NET_SPDY_HPACK_DECODER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/spdy/hpack/hpack_header_table.h"
#include "net/spdy/hpack/hpack_input_stream.h"
+#include "net/spdy/spdy_headers_handler_interface.h"
#include "net/spdy/spdy_protocol.h"
// An HpackDecoder decodes header sets as outlined in
@@ -22,8 +25,6 @@
namespace net {
-class HpackHuffmanTable;
-
namespace test {
class HpackDecoderPeer;
} // namespace test
@@ -32,9 +33,7 @@ class NET_EXPORT_PRIVATE HpackDecoder {
public:
friend class test::HpackDecoderPeer;
- // |table| is an initialized HPACK Huffman table, having an
- // externally-managed lifetime which spans beyond HpackDecoder.
- explicit HpackDecoder(const HpackHuffmanTable& table);
+ HpackDecoder();
~HpackDecoder();
// Called upon acknowledgement of SETTINGS_HEADER_TABLE_SIZE.
@@ -42,12 +41,17 @@ class NET_EXPORT_PRIVATE HpackDecoder {
header_table_.SetSettingsHeaderTableSize(size_setting);
}
+ // If a SpdyHeadersHandlerInterface is provided, HpackDecoder will emit
+ // headers to it rather than accumulating them in a SpdyHeaderBlock.
+ void HandleControlFrameHeadersStart(SpdyHeadersHandlerInterface* handler) {
+ handler_ = handler;
+ }
+
// Called as headers data arrives. Returns false if an error occurred.
// TODO(jgraettinger): A future version of this method will incrementally
// parse and deliver headers via SpdyHeadersHandlerInterface. For now,
// header data is buffered until HandleControlFrameHeadersComplete().
- bool HandleControlFrameHeadersData(SpdyStreamId stream_id,
- const char* headers_data,
+ bool HandleControlFrameHeadersData(const char* headers_data,
size_t headers_data_length);
// Called after a headers block has been completely delivered via
@@ -55,20 +59,17 @@ class NET_EXPORT_PRIVATE HpackDecoder {
// occurred. |compressed_len| if non-null will be set to the size
// of the encoded buffered block that was accumulated in
// HandleControlFrameHeadersData(), to support subsequent
- // calculation of compression percentage. TODO(jgraettinger): A
+ // calculation of compression percentage. Clears |handler_|.
+ // TODO(jgraettinger): A
// future version of this method will simply deliver the Cookie
// header (which has been incrementally reconstructed) and notify
- // the visitor that the block is finished. For now, this method
- // decodes the complete buffered block, and stores results to
- // |decoded_block_|.
- bool HandleControlFrameHeadersComplete(SpdyStreamId stream_id,
- size_t* compressed_len);
+ // the visitor that the block is finished.
+ bool HandleControlFrameHeadersComplete(size_t* compressed_len);
// Accessor for the most recently decoded headers block. Valid until the next
// call to HandleControlFrameHeadersData().
- // TODO(jgraettinger): This was added to facilitate re-encoding the block in
- // SPDY3 format for delivery to the SpdyFramer visitor, and will be removed
- // with the migration to SpdyHeadersHandlerInterface.
+ // TODO(birenroy): Remove this method when all users of HpackDecoder specify
+ // a SpdyHeadersHandlerInterface.
const SpdyHeaderBlock& decoded_block() { return decoded_block_; }
private:
@@ -85,12 +86,10 @@ class NET_EXPORT_PRIVATE HpackDecoder {
// MUST be treated as malformed, as per sections 8.1.2.3. of the HTTP2
// specification (RFC 7540).
//
- // TODO(jgraettinger): This method will eventually emit to the
- // SpdyHeadersHandlerInterface visitor.
bool HandleHeaderRepresentation(base::StringPiece name,
base::StringPiece value);
- const uint32 max_string_literal_size_;
+ const uint32_t max_string_literal_size_;
HpackHeaderTable header_table_;
// TODO(jgraettinger): Buffer for headers data, and storage for the last-
@@ -99,13 +98,17 @@ class NET_EXPORT_PRIVATE HpackDecoder {
std::string headers_block_buffer_;
SpdyHeaderBlock decoded_block_;
+ // Scratch space for storing decoded literals.
+ std::string key_buffer_, value_buffer_;
+
+ // If non-NULL, handles decoded headers.
+ SpdyHeadersHandlerInterface* handler_;
+
// Flag to keep track of having seen a regular header field.
bool regular_header_seen_;
- // Huffman table to be applied to decoded Huffman literals,
- // and scratch space for storing those decoded literals.
- const HpackHuffmanTable& huffman_table_;
- std::string key_buffer_, value_buffer_;
+ // Flag to keep track of having seen the header block start.
+ bool header_block_started_;
// Handlers for decoding HPACK opcodes and header representations
// (or parts thereof). These methods return true on success and
diff --git a/chromium/net/spdy/hpack/hpack_decoder_test.cc b/chromium/net/spdy/hpack/hpack_decoder_test.cc
index 948aae244b5..7c3b7d6753a 100644
--- a/chromium/net/spdy/hpack/hpack_decoder_test.cc
+++ b/chromium/net/spdy/hpack/hpack_decoder_test.cc
@@ -7,12 +7,13 @@
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "net/spdy/hpack/hpack_encoder.h"
#include "net/spdy/hpack/hpack_input_stream.h"
#include "net/spdy/hpack/hpack_output_stream.h"
+#include "net/spdy/spdy_headers_handler_interface.h"
+#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,6 +24,37 @@ namespace test {
using base::StringPiece;
using std::string;
+// A test implementation of SpdyHeadersHandlerInterface.
+class TestHeadersHandler : public SpdyHeadersHandlerInterface {
+ public:
+ TestHeadersHandler() : header_bytes_parsed_(0) {}
+
+ void OnHeaderBlockStart() override { block_.clear(); }
+
+ void OnHeader(StringPiece key, StringPiece value) override {
+ auto it = block_.find(key);
+ if (it == block_.end()) {
+ block_[key] = value;
+ } else {
+ string new_value = it->second.as_string();
+ new_value.append((key == "cookie") ? "; " : string(1, '\0'));
+ value.AppendToString(&new_value);
+ block_.ReplaceOrAppendHeader(key, new_value);
+ }
+ }
+
+ void OnHeaderBlockEnd(size_t header_bytes_parsed) override {
+ header_bytes_parsed_ = header_bytes_parsed;
+ }
+
+ const SpdyHeaderBlock& decoded_block() const { return block_; }
+ size_t header_bytes_parsed() { return header_bytes_parsed_; }
+
+ private:
+ SpdyHeaderBlock block_;
+ size_t header_bytes_parsed_;
+};
+
class HpackDecoderPeer {
public:
explicit HpackDecoderPeer(HpackDecoder* decoder) : decoder_(decoder) {}
@@ -56,20 +88,24 @@ using testing::Pair;
const size_t kLiteralBound = 1024;
-class HpackDecoderTest : public ::testing::Test {
+class HpackDecoderTest : public ::testing::TestWithParam<bool> {
protected:
- HpackDecoderTest()
- : decoder_(ObtainHpackHuffmanTable()), decoder_peer_(&decoder_) {}
+ HpackDecoderTest() : decoder_(), decoder_peer_(&decoder_) {}
bool DecodeHeaderBlock(StringPiece str) {
- return decoder_.HandleControlFrameHeadersData(0, str.data(), str.size()) &&
- decoder_.HandleControlFrameHeadersComplete(0, nullptr);
+ if (GetParam()) {
+ decoder_.HandleControlFrameHeadersStart(&handler_);
+ }
+ return decoder_.HandleControlFrameHeadersData(str.data(), str.size()) &&
+ decoder_.HandleControlFrameHeadersComplete(nullptr);
}
const SpdyHeaderBlock& decoded_block() const {
- // TODO(jgraettinger): HpackDecoderTest should implement
- // SpdyHeadersHandlerInterface, and collect headers for examination.
- return decoder_peer_.decoded_block();
+ if (GetParam()) {
+ return handler_.decoded_block();
+ } else {
+ return decoder_peer_.decoded_block();
+ }
}
const SpdyHeaderBlock& DecodeBlockExpectingSuccess(StringPiece str) {
@@ -90,23 +126,30 @@ class HpackDecoderTest : public ::testing::Test {
HpackDecoder decoder_;
test::HpackDecoderPeer decoder_peer_;
+ TestHeadersHandler handler_;
};
-TEST_F(HpackDecoderTest, HandleControlFrameHeadersData) {
+INSTANTIATE_TEST_CASE_P(WithAndWithoutHeadersHandler,
+ HpackDecoderTest,
+ ::testing::Bool());
+
+TEST_P(HpackDecoderTest, HandleControlFrameHeadersData) {
// Strings under threshold are concatenated in the buffer.
- EXPECT_TRUE(
- decoder_.HandleControlFrameHeadersData(0, "small string one", 16));
- EXPECT_TRUE(
- decoder_.HandleControlFrameHeadersData(0, "small string two", 16));
+ EXPECT_TRUE(decoder_.HandleControlFrameHeadersData("small string one", 16));
+ EXPECT_TRUE(decoder_.HandleControlFrameHeadersData("small string two", 16));
// A string which would push the buffer over the threshold is refused.
EXPECT_FALSE(decoder_.HandleControlFrameHeadersData(
- 0, "fails", kMaxDecodeBufferSize - 32 + 1));
+ "fails", kMaxDecodeBufferSize - 32 + 1));
EXPECT_EQ(decoder_peer_.headers_block_buffer(),
"small string onesmall string two");
}
-TEST_F(HpackDecoderTest, HandleHeaderRepresentation) {
+TEST_P(HpackDecoderTest, HandleHeaderRepresentation) {
+ if (GetParam()) {
+ decoder_.HandleControlFrameHeadersStart(&handler_);
+ }
+
// All cookie crumbs are joined.
decoder_peer_.HandleHeaderRepresentation("cookie", " part 1");
decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 ");
@@ -134,7 +177,7 @@ TEST_F(HpackDecoderTest, HandleHeaderRepresentation) {
decoder_peer_.HandleHeaderRepresentation("cookie", " fin!");
// Finish and emit all headers.
- decoder_.HandleControlFrameHeadersComplete(0, nullptr);
+ decoder_.HandleControlFrameHeadersComplete(nullptr);
// Resulting decoded headers are in the same order as input.
EXPECT_THAT(decoded_block(),
@@ -147,7 +190,7 @@ TEST_F(HpackDecoderTest, HandleHeaderRepresentation) {
}
// Decoding an encoded name with a valid string literal should work.
-TEST_F(HpackDecoderTest, DecodeNextNameLiteral) {
+TEST_P(HpackDecoderTest, DecodeNextNameLiteral) {
HpackInputStream input_stream(kLiteralBound, StringPiece("\x00\x04name", 6));
StringPiece string_piece;
@@ -156,7 +199,7 @@ TEST_F(HpackDecoderTest, DecodeNextNameLiteral) {
EXPECT_FALSE(input_stream.HasMoreData());
}
-TEST_F(HpackDecoderTest, DecodeNextNameLiteralWithHuffmanEncoding) {
+TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithHuffmanEncoding) {
string input = a2b_hex("008825a849e95ba97d7f");
HpackInputStream input_stream(kLiteralBound, input);
@@ -167,7 +210,7 @@ TEST_F(HpackDecoderTest, DecodeNextNameLiteralWithHuffmanEncoding) {
}
// Decoding an encoded name with a valid index should work.
-TEST_F(HpackDecoderTest, DecodeNextNameIndexed) {
+TEST_P(HpackDecoderTest, DecodeNextNameIndexed) {
HpackInputStream input_stream(kLiteralBound, "\x01");
StringPiece string_piece;
@@ -177,7 +220,7 @@ TEST_F(HpackDecoderTest, DecodeNextNameIndexed) {
}
// Decoding an encoded name with an invalid index should fail.
-TEST_F(HpackDecoderTest, DecodeNextNameInvalidIndex) {
+TEST_P(HpackDecoderTest, DecodeNextNameInvalidIndex) {
// One more than the number of static table entries.
HpackInputStream input_stream(kLiteralBound, "\x3e");
@@ -186,22 +229,22 @@ TEST_F(HpackDecoderTest, DecodeNextNameInvalidIndex) {
}
// Decoding indexed static table field should work.
-TEST_F(HpackDecoderTest, IndexedHeaderStatic) {
+TEST_P(HpackDecoderTest, IndexedHeaderStatic) {
// Reference static table entries #2 and #5.
SpdyHeaderBlock header_set1 = DecodeBlockExpectingSuccess("\x82\x85");
SpdyHeaderBlock expected_header_set1;
expected_header_set1[":method"] = "GET";
expected_header_set1[":path"] = "/index.html";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set1, header_set1));
+ EXPECT_EQ(expected_header_set1, header_set1);
// Reference static table entry #2.
SpdyHeaderBlock header_set2 = DecodeBlockExpectingSuccess("\x82");
SpdyHeaderBlock expected_header_set2;
expected_header_set2[":method"] = "GET";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set2, header_set2));
+ EXPECT_EQ(expected_header_set2, header_set2);
}
-TEST_F(HpackDecoderTest, IndexedHeaderDynamic) {
+TEST_P(HpackDecoderTest, IndexedHeaderDynamic) {
// First header block: add an entry to header table.
SpdyHeaderBlock header_set1 = DecodeBlockExpectingSuccess(
"\x40\x03"
@@ -210,7 +253,7 @@ TEST_F(HpackDecoderTest, IndexedHeaderDynamic) {
"bar");
SpdyHeaderBlock expected_header_set1;
expected_header_set1["foo"] = "bar";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set1, header_set1));
+ EXPECT_EQ(expected_header_set1, header_set1);
// Second header block: add another entry to header table.
SpdyHeaderBlock header_set2 = DecodeBlockExpectingSuccess(
@@ -221,17 +264,17 @@ TEST_F(HpackDecoderTest, IndexedHeaderDynamic) {
SpdyHeaderBlock expected_header_set2;
expected_header_set2["foo"] = "bar";
expected_header_set2["spam"] = "eggs";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set2, header_set2));
+ EXPECT_EQ(expected_header_set2, header_set2);
// Third header block: refer to most recently added entry.
SpdyHeaderBlock header_set3 = DecodeBlockExpectingSuccess("\xbe");
SpdyHeaderBlock expected_header_set3;
expected_header_set3["spam"] = "eggs";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set3, header_set3));
+ EXPECT_EQ(expected_header_set3, header_set3);
}
// Test a too-large indexed header.
-TEST_F(HpackDecoderTest, InvalidIndexedHeader) {
+TEST_P(HpackDecoderTest, InvalidIndexedHeader) {
// High-bit set, and a prefix of one more than the number of static entries.
EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\xbe", 1)));
}
@@ -239,21 +282,21 @@ TEST_F(HpackDecoderTest, InvalidIndexedHeader) {
// Test that a header block with a pseudo-header field following a regular one
// is treated as malformed. (HTTP2 draft-14 8.1.2.1., HPACK draft-09 3.1.)
-TEST_F(HpackDecoderTest, InvalidPseudoHeaderPositionStatic) {
+TEST_P(HpackDecoderTest, InvalidPseudoHeaderPositionStatic) {
// Okay: ":path" (static entry 4) followed by "allow" (static entry 20).
EXPECT_TRUE(DecodeHeaderBlock(a2b_hex("8494")));
// Malformed: "allow" (static entry 20) followed by ":path" (static entry 4).
EXPECT_FALSE(DecodeHeaderBlock(a2b_hex("9484")));
}
-TEST_F(HpackDecoderTest, InvalidPseudoHeaderPositionLiteral) {
+TEST_P(HpackDecoderTest, InvalidPseudoHeaderPositionLiteral) {
// Okay: literal ":bar" followed by literal "foo".
EXPECT_TRUE(DecodeHeaderBlock(a2b_hex("40043a626172004003666f6f00")));
// Malformed: literal "foo" followed by literal ":bar".
EXPECT_FALSE(DecodeHeaderBlock(a2b_hex("4003666f6f0040043a62617200")));
}
-TEST_F(HpackDecoderTest, ContextUpdateMaximumSize) {
+TEST_P(HpackDecoderTest, ContextUpdateMaximumSize) {
EXPECT_EQ(kDefaultHeaderTableSizeSetting,
decoder_peer_.header_table()->max_size());
string input;
@@ -293,7 +336,7 @@ TEST_F(HpackDecoderTest, ContextUpdateMaximumSize) {
// Decoding two valid encoded literal headers with no indexing should
// work.
-TEST_F(HpackDecoderTest, LiteralHeaderNoIndexing) {
+TEST_P(HpackDecoderTest, LiteralHeaderNoIndexing) {
// First header with indexed name, second header with string literal
// name.
const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2";
@@ -303,12 +346,12 @@ TEST_F(HpackDecoderTest, LiteralHeaderNoIndexing) {
SpdyHeaderBlock expected_header_set;
expected_header_set[":path"] = "/sample/path";
expected_header_set[":path2"] = "/sample/path/2";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set, header_set));
+ EXPECT_EQ(expected_header_set, header_set);
}
// Decoding two valid encoded literal headers with incremental
// indexing and string literal names should work.
-TEST_F(HpackDecoderTest, LiteralHeaderIncrementalIndexing) {
+TEST_P(HpackDecoderTest, LiteralHeaderIncrementalIndexing) {
const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2";
SpdyHeaderBlock header_set =
DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1));
@@ -316,10 +359,10 @@ TEST_F(HpackDecoderTest, LiteralHeaderIncrementalIndexing) {
SpdyHeaderBlock expected_header_set;
expected_header_set[":path"] = "/sample/path";
expected_header_set[":path2"] = "/sample/path/2";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set, header_set));
+ EXPECT_EQ(expected_header_set, header_set);
}
-TEST_F(HpackDecoderTest, LiteralHeaderWithIndexingInvalidNameIndex) {
+TEST_P(HpackDecoderTest, LiteralHeaderWithIndexingInvalidNameIndex) {
decoder_.ApplyHeaderTableSizeSetting(0);
// Name is the last static index. Works.
@@ -328,14 +371,14 @@ TEST_F(HpackDecoderTest, LiteralHeaderWithIndexingInvalidNameIndex) {
EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x7e\x03ooo")));
}
-TEST_F(HpackDecoderTest, LiteralHeaderNoIndexingInvalidNameIndex) {
+TEST_P(HpackDecoderTest, LiteralHeaderNoIndexingInvalidNameIndex) {
// Name is the last static index. Works.
EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x0f\x2e\x03ooo")));
// Name is one beyond the last static index. Fails.
EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x0f\x2f\x03ooo")));
}
-TEST_F(HpackDecoderTest, LiteralHeaderNeverIndexedInvalidNameIndex) {
+TEST_P(HpackDecoderTest, LiteralHeaderNeverIndexedInvalidNameIndex) {
// Name is the last static index. Works.
EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x1f\x2e\x03ooo")));
// Name is one beyond the last static index. Fails.
@@ -343,7 +386,7 @@ TEST_F(HpackDecoderTest, LiteralHeaderNeverIndexedInvalidNameIndex) {
}
// Round-tripping the header set from E.2.1 should work.
-TEST_F(HpackDecoderTest, BasicE21) {
+TEST_P(HpackDecoderTest, BasicE21) {
HpackEncoder encoder(ObtainHpackHuffmanTable());
SpdyHeaderBlock expected_header_set;
@@ -357,10 +400,10 @@ TEST_F(HpackDecoderTest, BasicE21) {
encoder.EncodeHeaderSet(expected_header_set, &encoded_header_set));
EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set));
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_header_set, decoded_block()));
+ EXPECT_EQ(expected_header_set, decoded_block());
}
-TEST_F(HpackDecoderTest, SectionD4RequestHuffmanExamples) {
+TEST_P(HpackDecoderTest, SectionD4RequestHuffmanExamples) {
SpdyHeaderBlock header_set;
// 82 | == Indexed - Add ==
@@ -470,7 +513,7 @@ TEST_F(HpackDecoderTest, SectionD4RequestHuffmanExamples) {
EXPECT_EQ(164u, decoder_peer_.header_table()->size());
}
-TEST_F(HpackDecoderTest, SectionD6ResponseHuffmanExamples) {
+TEST_P(HpackDecoderTest, SectionD6ResponseHuffmanExamples) {
SpdyHeaderBlock header_set;
decoder_.ApplyHeaderTableSizeSetting(256);
diff --git a/chromium/net/spdy/hpack/hpack_encoder.cc b/chromium/net/spdy/hpack/hpack_encoder.cc
index cb02285e3bb..59198a7c5e9 100644
--- a/chromium/net/spdy/hpack/hpack_encoder.cc
+++ b/chromium/net/spdy/hpack/hpack_encoder.cc
@@ -5,8 +5,10 @@
#include "net/spdy/hpack/hpack_encoder.h"
#include <algorithm>
+#include <limits>
#include "base/logging.h"
+#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/hpack/hpack_header_table.h"
#include "net/spdy/hpack/hpack_huffman_table.h"
#include "net/spdy/hpack/hpack_output_stream.h"
@@ -18,15 +20,16 @@ using std::string;
HpackEncoder::HpackEncoder(const HpackHuffmanTable& table)
: output_stream_(),
- allow_huffman_compression_(true),
huffman_table_(table),
- char_counts_(NULL),
- total_char_counts_(NULL) {}
+ min_table_size_setting_received_(std::numeric_limits<size_t>::max()),
+ allow_huffman_compression_(true),
+ should_emit_table_size_(false) {}
HpackEncoder::~HpackEncoder() {}
bool HpackEncoder::EncodeHeaderSet(const SpdyHeaderBlock& header_set,
string* output) {
+ MaybeEmitTableSize();
// Separate header set into pseudo-headers and regular headers.
Representations pseudo_headers;
Representations regular_headers;
@@ -37,7 +40,8 @@ bool HpackEncoder::EncodeHeaderSet(const SpdyHeaderBlock& header_set,
// a map.
found_cookie = true;
CookieToCrumbs(header, &regular_headers);
- } else if (header.first[0] == kPseudoHeaderPrefix) {
+ } else if (!header.first.empty() &&
+ header.first[0] == kPseudoHeaderPrefix) {
DecomposeRepresentation(header, &pseudo_headers);
} else {
DecomposeRepresentation(header, &regular_headers);
@@ -87,6 +91,7 @@ bool HpackEncoder::EncodeHeaderSetWithoutCompression(
const SpdyHeaderBlock& header_set,
string* output) {
allow_huffman_compression_ = false;
+ MaybeEmitTableSize();
for (const auto& header : header_set) {
// Note that cookies are not crumbled in this case.
EmitNonIndexedLiteral(header);
@@ -96,6 +101,18 @@ bool HpackEncoder::EncodeHeaderSetWithoutCompression(
return true;
}
+void HpackEncoder::ApplyHeaderTableSizeSetting(size_t size_setting) {
+ if (size_setting == header_table_.settings_size_bound()) {
+ return;
+ }
+ if (size_setting < header_table_.settings_size_bound()) {
+ min_table_size_setting_received_ =
+ std::min(size_setting, min_table_size_setting_received_);
+ }
+ header_table_.SetSettingsHeaderTableSize(size_setting);
+ should_emit_table_size_ = true;
+}
+
void HpackEncoder::EmitIndex(const HpackEntry* entry) {
output_stream_.AppendPrefix(kIndexedOpcode);
output_stream_.AppendUint32(header_table_.IndexOf(entry));
@@ -138,24 +155,21 @@ void HpackEncoder::EmitString(StringPiece str) {
output_stream_.AppendUint32(str.size());
output_stream_.AppendBytes(str);
}
- UpdateCharacterCounts(str);
}
-void HpackEncoder::SetCharCountsStorage(std::vector<size_t>* char_counts,
- size_t* total_char_counts) {
- CHECK_LE(256u, char_counts->size());
- char_counts_ = char_counts;
- total_char_counts_ = total_char_counts;
-}
-
-void HpackEncoder::UpdateCharacterCounts(base::StringPiece str) {
- if (char_counts_ == NULL || total_char_counts_ == NULL) {
+void HpackEncoder::MaybeEmitTableSize() {
+ if (!should_emit_table_size_) {
return;
}
- for (StringPiece::const_iterator it = str.begin(); it != str.end(); ++it) {
- ++(*char_counts_)[static_cast<uint8>(*it)];
+ const size_t current_size = CurrentHeaderTableSizeSetting();
+ if (min_table_size_setting_received_ < current_size) {
+ output_stream_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+ output_stream_.AppendUint32(min_table_size_setting_received_);
}
- (*total_char_counts_) += str.size();
+ output_stream_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+ output_stream_.AppendUint32(current_size);
+ min_table_size_setting_received_ = std::numeric_limits<size_t>::max();
+ should_emit_table_size_ = false;
}
// static
@@ -198,8 +212,10 @@ void HpackEncoder::DecomposeRepresentation(const Representation& header_field,
size_t end = 0;
while (end != StringPiece::npos) {
end = header_field.second.find('\0', pos);
- out->push_back(std::make_pair(header_field.first,
- header_field.second.substr(pos, end - pos)));
+ out->push_back(
+ std::make_pair(header_field.first,
+ header_field.second.substr(
+ pos, end == StringPiece::npos ? end : end - pos)));
pos = end + 1;
}
}
diff --git a/chromium/net/spdy/hpack/hpack_encoder.h b/chromium/net/spdy/hpack/hpack_encoder.h
index d95ea11845f..cd6558bb1e7 100644
--- a/chromium/net/spdy/hpack/hpack_encoder.h
+++ b/chromium/net/spdy/hpack/hpack_encoder.h
@@ -5,12 +5,13 @@
#ifndef NET_SPDY_HPACK_ENCODER_H_
#define NET_SPDY_HPACK_ENCODER_H_
+#include <stddef.h>
+
#include <map>
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -51,14 +52,11 @@ class NET_EXPORT_PRIVATE HpackEncoder {
// Called upon a change to SETTINGS_HEADER_TABLE_SIZE. Specifically, this
// is to be called after receiving (and sending an acknowledgement for) a
// SETTINGS_HEADER_TABLE_SIZE update from the remote decoding endpoint.
- void ApplyHeaderTableSizeSetting(size_t size_setting) {
- header_table_.SetSettingsHeaderTableSize(size_setting);
- }
+ void ApplyHeaderTableSizeSetting(size_t size_setting);
- // Sets externally-owned storage for aggregating character counts of emitted
- // literal representations.
- void SetCharCountsStorage(std::vector<size_t>* char_counts,
- size_t* total_char_counts);
+ size_t CurrentHeaderTableSizeSetting() const {
+ return header_table_.settings_size_bound();
+ }
private:
typedef std::pair<base::StringPiece, base::StringPiece> Representation;
@@ -75,7 +73,9 @@ class NET_EXPORT_PRIVATE HpackEncoder {
// Emits a Huffman or identity string (whichever is smaller).
void EmitString(base::StringPiece str);
- void UpdateCharacterCounts(base::StringPiece str);
+ // Emits the current dynamic table size if the table size was recently
+ // updated and we have not yet emitted it (Section 6.3).
+ void MaybeEmitTableSize();
// Crumbles a cookie header into ";" delimited crumbs.
static void CookieToCrumbs(const Representation& cookie,
@@ -88,12 +88,10 @@ class NET_EXPORT_PRIVATE HpackEncoder {
HpackHeaderTable header_table_;
HpackOutputStream output_stream_;
- bool allow_huffman_compression_;
const HpackHuffmanTable& huffman_table_;
-
- // Externally-owned, nullable storage for character counts of literals.
- std::vector<size_t>* char_counts_;
- size_t* total_char_counts_;
+ size_t min_table_size_setting_received_;
+ bool allow_huffman_compression_;
+ bool should_emit_table_size_;
DISALLOW_COPY_AND_ASSIGN(HpackEncoder);
};
diff --git a/chromium/net/spdy/hpack/hpack_encoder_test.cc b/chromium/net/spdy/hpack/hpack_encoder_test.cc
index 07b2752772f..10fd6087da0 100644
--- a/chromium/net/spdy/hpack/hpack_encoder_test.cc
+++ b/chromium/net/spdy/hpack/hpack_encoder_test.cc
@@ -44,9 +44,6 @@ class HpackEncoderPeer {
}
void EmitString(StringPiece str) { encoder_->EmitString(str); }
void TakeString(string* out) { encoder_->output_stream_.TakeString(out); }
- void UpdateCharacterCounts(StringPiece str) {
- encoder_->UpdateCharacterCounts(str);
- }
static void CookieToCrumbs(StringPiece cookie,
std::vector<StringPiece>* out) {
Representations tmp;
@@ -135,6 +132,10 @@ class HpackEncoderTest : public ::testing::Test {
expected_.AppendUint32(value.size());
expected_.AppendBytes(value);
}
+ void ExpectHeaderTableSizeUpdate(uint32_t size) {
+ expected_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+ expected_.AppendUint32(size);
+ }
void CompareWithExpectedEncoding(const SpdyHeaderBlock& header_set) {
string expected_out, actual_out;
expected_.TakeString(&expected_out);
@@ -397,29 +398,6 @@ TEST_F(HpackEncoderTest, CookieToCrumbs) {
EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3"));
}
-TEST_F(HpackEncoderTest, UpdateCharacterCounts) {
- std::vector<size_t> counts(256, 0);
- size_t total_counts = 0;
- encoder_.SetCharCountsStorage(&counts, &total_counts);
-
- char kTestString[] =
- "foo\0\1\xff"
- "boo";
- peer_.UpdateCharacterCounts(
- StringPiece(kTestString, arraysize(kTestString) - 1));
-
- std::vector<size_t> expect(256, 0);
- expect[static_cast<uint8>('f')] = 1;
- expect[static_cast<uint8>('o')] = 4;
- expect[static_cast<uint8>('\0')] = 1;
- expect[static_cast<uint8>('\1')] = 1;
- expect[static_cast<uint8>('\xff')] = 1;
- expect[static_cast<uint8>('b')] = 1;
-
- EXPECT_EQ(expect, counts);
- EXPECT_EQ(9u, total_counts);
-}
-
TEST_F(HpackEncoderTest, DecomposeRepresentation) {
test::HpackEncoderPeer peer(NULL);
std::vector<StringPiece> out;
@@ -459,6 +437,70 @@ TEST_F(HpackEncoderTest, CrumbleNullByteDelimitedValue) {
CompareWithExpectedEncoding(headers);
}
+TEST_F(HpackEncoderTest, HeaderTableSizeUpdate) {
+ encoder_.ApplyHeaderTableSizeSetting(1024);
+ ExpectHeaderTableSizeUpdate(1024);
+ ExpectIndexedLiteral("key3", "value3");
+
+ SpdyHeaderBlock headers;
+ headers["key3"] = "value3";
+ CompareWithExpectedEncoding(headers);
+
+ HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+ EXPECT_EQ(new_entry->name(), "key3");
+ EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_F(HpackEncoderTest, HeaderTableSizeUpdateWithMin) {
+ const size_t starting_size = peer_.table()->settings_size_bound();
+ encoder_.ApplyHeaderTableSizeSetting(starting_size - 2);
+ encoder_.ApplyHeaderTableSizeSetting(starting_size - 1);
+ // We must encode the low watermark, so the peer knows to evict entries
+ // if necessary.
+ ExpectHeaderTableSizeUpdate(starting_size - 2);
+ ExpectHeaderTableSizeUpdate(starting_size - 1);
+ ExpectIndexedLiteral("key3", "value3");
+
+ SpdyHeaderBlock headers;
+ headers["key3"] = "value3";
+ CompareWithExpectedEncoding(headers);
+
+ HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+ EXPECT_EQ(new_entry->name(), "key3");
+ EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_F(HpackEncoderTest, HeaderTableSizeUpdateWithExistingSize) {
+ encoder_.ApplyHeaderTableSizeSetting(peer_.table()->settings_size_bound());
+ // No encoded size update.
+ ExpectIndexedLiteral("key3", "value3");
+
+ SpdyHeaderBlock headers;
+ headers["key3"] = "value3";
+ CompareWithExpectedEncoding(headers);
+
+ HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+ EXPECT_EQ(new_entry->name(), "key3");
+ EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_F(HpackEncoderTest, HeaderTableSizeUpdatesWithGreaterSize) {
+ const size_t starting_size = peer_.table()->settings_size_bound();
+ encoder_.ApplyHeaderTableSizeSetting(starting_size + 1);
+ encoder_.ApplyHeaderTableSizeSetting(starting_size + 2);
+ // Only a single size update to the final size.
+ ExpectHeaderTableSizeUpdate(starting_size + 2);
+ ExpectIndexedLiteral("key3", "value3");
+
+ SpdyHeaderBlock headers;
+ headers["key3"] = "value3";
+ CompareWithExpectedEncoding(headers);
+
+ HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+ EXPECT_EQ(new_entry->name(), "key3");
+ EXPECT_EQ(new_entry->value(), "value3");
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/spdy/hpack/hpack_entry.h b/chromium/net/spdy/hpack/hpack_entry.h
index d3d2c618d09..b0948102f9d 100644
--- a/chromium/net/spdy/hpack/hpack_entry.h
+++ b/chromium/net/spdy/hpack/hpack_entry.h
@@ -5,9 +5,10 @@
#ifndef NET_SPDY_HPACK_ENTRY_H_
#define NET_SPDY_HPACK_ENTRY_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/spdy/hpack/hpack_header_table.h b/chromium/net/spdy/hpack/hpack_header_table.h
index 50a7acdb054..be0ac0b7b6a 100644
--- a/chromium/net/spdy/hpack/hpack_header_table.h
+++ b/chromium/net/spdy/hpack/hpack_header_table.h
@@ -9,7 +9,6 @@
#include <deque>
#include <set>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/spdy/hpack/hpack_entry.h"
@@ -18,8 +17,6 @@
namespace net {
-using base::StringPiece;
-
namespace test {
class HpackHeaderTablePeer;
} // namespace test
@@ -51,7 +48,7 @@ class NET_EXPORT_PRIVATE HpackHeaderTable {
~HpackHeaderTable();
// Last-acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
- size_t settings_size_bound() { return settings_size_bound_; }
+ size_t settings_size_bound() const { return settings_size_bound_; }
// Current and maximum estimated byte size of the table, as described in
// 4.1. Notably, this is /not/ the number of entries in the table.
@@ -62,10 +59,11 @@ class NET_EXPORT_PRIVATE HpackHeaderTable {
const HpackEntry* GetByIndex(size_t index);
// Returns the lowest-value entry having |name|, or NULL.
- const HpackEntry* GetByName(StringPiece name);
+ const HpackEntry* GetByName(base::StringPiece name);
// Returns the lowest-index matching entry, or NULL.
- const HpackEntry* GetByNameAndValue(StringPiece name, StringPiece value);
+ const HpackEntry* GetByNameAndValue(base::StringPiece name,
+ base::StringPiece value);
// Returns the index of an entry within this header table.
size_t IndexOf(const HpackEntry* entry) const;
@@ -81,8 +79,8 @@ class NET_EXPORT_PRIVATE HpackHeaderTable {
// Determine the set of entries which would be evicted by the insertion
// of |name| & |value| into the table, as per section 4.4. No eviction
// actually occurs. The set is returned via range [begin_out, end_out).
- void EvictionSet(StringPiece name,
- StringPiece value,
+ void EvictionSet(base::StringPiece name,
+ base::StringPiece value,
EntryTable::iterator* begin_out,
EntryTable::iterator* end_out);
@@ -90,13 +88,15 @@ class NET_EXPORT_PRIVATE HpackHeaderTable {
// and |value| must not be owned by an entry which could be evicted. The
// added HpackEntry is returned, or NULL is returned if all entries were
// evicted and the empty table is of insufficent size for the representation.
- const HpackEntry* TryAddEntry(StringPiece name, StringPiece value);
+ const HpackEntry* TryAddEntry(base::StringPiece name,
+ base::StringPiece value);
void DebugLogTableState() const;
private:
// Returns number of evictions required to enter |name| & |value|.
- size_t EvictionCountForEntry(StringPiece name, StringPiece value) const;
+ size_t EvictionCountForEntry(base::StringPiece name,
+ base::StringPiece value) const;
// Returns number of evictions required to reclaim |reclaim_size| table size.
size_t EvictionCountToReclaim(size_t reclaim_size) const;
diff --git a/chromium/net/spdy/hpack/hpack_header_table_test.cc b/chromium/net/spdy/hpack/hpack_header_table_test.cc
index 86b688b3aad..1d9071d2ccf 100644
--- a/chromium/net/spdy/hpack/hpack_header_table_test.cc
+++ b/chromium/net/spdy/hpack/hpack_header_table_test.cc
@@ -9,7 +9,6 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/hpack/hpack_entry.h"
@@ -75,7 +74,7 @@ class HpackHeaderTableTest : public ::testing::Test {
HpackHeaderTableTest() : table_(), peer_(&table_) {}
// Returns an entry whose Size() is equal to the given one.
- static HpackEntry MakeEntryOfSize(uint32 size) {
+ static HpackEntry MakeEntryOfSize(uint32_t size) {
EXPECT_GE(size, HpackEntry::kSizeOverhead);
string name((size - HpackEntry::kSizeOverhead) / 2, 'n');
string value(size - HpackEntry::kSizeOverhead - name.size(), 'v');
@@ -86,10 +85,10 @@ class HpackHeaderTableTest : public ::testing::Test {
// Returns a vector of entries whose total size is equal to the given
// one.
- static HpackEntryVector MakeEntriesOfTotalSize(uint32 total_size) {
+ static HpackEntryVector MakeEntriesOfTotalSize(uint32_t total_size) {
EXPECT_GE(total_size, HpackEntry::kSizeOverhead);
- uint32 entry_size = HpackEntry::kSizeOverhead;
- uint32 remaining_size = total_size;
+ uint32_t entry_size = HpackEntry::kSizeOverhead;
+ uint32_t remaining_size = total_size;
HpackEntryVector entries;
while (remaining_size > 0) {
EXPECT_LE(entry_size, remaining_size);
diff --git a/chromium/net/spdy/hpack/hpack_huffman_decoder.cc b/chromium/net/spdy/hpack/hpack_huffman_decoder.cc
new file mode 100644
index 00000000000..3573744c052
--- /dev/null
+++ b/chromium/net/spdy/hpack/hpack_huffman_decoder.cc
@@ -0,0 +1,410 @@
+// 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.
+//
+// Decoder for strings encoded using the HPACK Huffman Code (see
+// https://httpwg.github.io/specs/rfc7541.html#huffman.code).
+//
+// This implementation is inspired by the One-Shift algorithm described in
+// "On the Implementation of Minimum Redundancy Prefix Codes", by Alistair
+// Moffat and Andrew Turpin, 1997.
+// See also https://en.wikipedia.org/wiki/Canonical_Huffman_code for background
+// on canonical Huffman codes.
+//
+// This decoder differs from that in .../spdy/hpack/hpack_huffman_table.cc
+// as follows:
+// 1) It decodes only the code described in RFC7541, where as the older
+// implementation supported any canonical Huffman code provided at run
+// time.
+// 2) It uses a fixed amount of memory allocated at build time; it doesn't
+// construct a tree of of decoding tables based on an encoding
+// table provided at run time.
+// 3) In benchmarks it runs from 10% to 70% faster, based on the length
+// of the strings (faster for longer strings). Some of the improvements
+// could be back ported, but others are fundamental to the approach.
+
+#include "net/spdy/hpack/hpack_huffman_decoder.h"
+
+#include <bitset>
+#include <limits>
+#include <utility>
+
+#include "base/logging.h"
+#include "net/spdy/hpack/hpack_input_stream.h"
+
+namespace net {
+namespace {
+
+typedef HpackHuffmanDecoder::HuffmanWord HuffmanWord;
+typedef HpackHuffmanDecoder::HuffmanCodeLength HuffmanCodeLength;
+
+const HuffmanCodeLength kHuffmanWordLength =
+ std::numeric_limits<HuffmanWord>::digits;
+
+const HuffmanCodeLength kMinCodeLength = 5;
+const HuffmanCodeLength kMaxCodeLength = 30;
+
+const HuffmanWord kInvalidLJCode = ~static_cast<HuffmanWord>(0);
+// Length of a code in bits to the first code with that length, left-justified.
+// Note that this can be computed from kLengthToFirstCanonical.
+const HuffmanWord kLengthToFirstLJCode[] = {
+ kInvalidLJCode, // There are no codes of length 0.
+ kInvalidLJCode, // There are no codes of length 1.
+ kInvalidLJCode, // There are no codes of length 2.
+ kInvalidLJCode, // There are no codes of length 3.
+ kInvalidLJCode, // There are no codes of length 4.
+ 0x00000000, // Length 5.
+ 0x50000000, // Length 6.
+ 0xb8000000, // Length 7.
+ 0xf8000000, // Length 8.
+ kInvalidLJCode, // There are no codes of length 9.
+ 0xfe000000, // Length 10.
+ 0xff400000, // Length 11.
+ 0xffa00000, // Length 12.
+ 0xffc00000, // Length 13.
+ 0xfff00000, // Length 14.
+ 0xfff80000, // Length 15.
+ kInvalidLJCode, // There are no codes of length 16.
+ kInvalidLJCode, // There are no codes of length 17.
+ kInvalidLJCode, // There are no codes of length 18.
+ 0xfffe0000, // Length 19.
+ 0xfffe6000, // Length 20.
+ 0xfffee000, // Length 21.
+ 0xffff4800, // Length 22.
+ 0xffffb000, // Length 23.
+ 0xffffea00, // Length 24.
+ 0xfffff600, // Length 25.
+ 0xfffff800, // Length 26.
+ 0xfffffbc0, // Length 27.
+ 0xfffffe20, // Length 28.
+ kInvalidLJCode, // There are no codes of length 29.
+ 0xfffffff0, // Length 30.
+};
+
+// TODO(jamessynge): Determine the performance impact of different types for
+// the elements of this array (i.e. a larger type uses more cache, yet might
+// better on some architectures).
+const uint8_t kInvalidCanonical = 255;
+// Maps from length of a code to the first 'canonical symbol' with that length.
+const uint8_t kLengthToFirstCanonical[] = {
+ kInvalidCanonical, // Length 0, 0 codes.
+ kInvalidCanonical, // Length 1, 0 codes.
+ kInvalidCanonical, // Length 2, 0 codes.
+ kInvalidCanonical, // Length 3, 0 codes.
+ kInvalidCanonical, // Length 4, 0 codes.
+ 0, // Length 5, 10 codes.
+ 10, // Length 6, 26 codes.
+ 36, // Length 7, 32 codes.
+ 68, // Length 8, 6 codes.
+ kInvalidCanonical, // Length 9, 0 codes.
+ 74, // Length 10, 5 codes.
+ 79, // Length 11, 3 codes.
+ 82, // Length 12, 2 codes.
+ 84, // Length 13, 6 codes.
+ 90, // Length 14, 2 codes.
+ 92, // Length 15, 3 codes.
+ kInvalidCanonical, // Length 16, 0 codes.
+ kInvalidCanonical, // Length 17, 0 codes.
+ kInvalidCanonical, // Length 18, 0 codes.
+ 95, // Length 19, 3 codes.
+ 98, // Length 20, 8 codes.
+ 106, // Length 21, 13 codes.
+ 119, // Length 22, 26 codes.
+ 145, // Length 23, 29 codes.
+ 174, // Length 24, 12 codes.
+ 186, // Length 25, 4 codes.
+ 190, // Length 26, 15 codes.
+ 205, // Length 27, 19 codes.
+ 224, // Length 28, 29 codes.
+ kInvalidCanonical, // Length 29, 0 codes.
+ 253, // Length 30, 4 codes.
+};
+
+// Mapping from canonical symbol (0 to 255) to actual symbol.
+// clang-format off
+const uint8_t kCanonicalToSymbol[] = {
+ '0', '1', '2', 'a', 'c', 'e', 'i', 'o',
+ 's', 't', 0x20, '%', '-', '.', '/', '3',
+ '4', '5', '6', '7', '8', '9', '=', 'A',
+ '_', 'b', 'd', 'f', 'g', 'h', 'l', 'm',
+ 'n', 'p', 'r', 'u', ':', 'B', 'C', 'D',
+ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'Y', 'j', 'k', 'q', 'v',
+ 'w', 'x', 'y', 'z', '&', '*', ',', ';',
+ 'X', 'Z', '!', '\"', '(', ')', '?', '\'',
+ '+', '|', '#', '>', 0x00, '$', '@', '[',
+ ']', '~', '^', '}', '<', '`', '{', '\\',
+ 0xc3, 0xd0, 0x80, 0x82, 0x83, 0xa2, 0xb8, 0xc2,
+ 0xe0, 0xe2, 0x99, 0xa1, 0xa7, 0xac, 0xb0, 0xb1,
+ 0xb3, 0xd1, 0xd8, 0xd9, 0xe3, 0xe5, 0xe6, 0x81,
+ 0x84, 0x85, 0x86, 0x88, 0x92, 0x9a, 0x9c, 0xa0,
+ 0xa3, 0xa4, 0xa9, 0xaa, 0xad, 0xb2, 0xb5, 0xb9,
+ 0xba, 0xbb, 0xbd, 0xbe, 0xc4, 0xc6, 0xe4, 0xe8,
+ 0xe9, 0x01, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
+ 0x8f, 0x93, 0x95, 0x96, 0x97, 0x98, 0x9b, 0x9d,
+ 0x9e, 0xa5, 0xa6, 0xa8, 0xae, 0xaf, 0xb4, 0xb6,
+ 0xb7, 0xbc, 0xbf, 0xc5, 0xe7, 0xef, 0x09, 0x8e,
+ 0x90, 0x91, 0x94, 0x9f, 0xab, 0xce, 0xd7, 0xe1,
+ 0xec, 0xed, 0xc7, 0xcf, 0xea, 0xeb, 0xc0, 0xc1,
+ 0xc8, 0xc9, 0xca, 0xcd, 0xd2, 0xd5, 0xda, 0xdb,
+ 0xee, 0xf0, 0xf2, 0xf3, 0xff, 0xcb, 0xcc, 0xd3,
+ 0xd4, 0xd6, 0xdd, 0xde, 0xdf, 0xf1, 0xf4, 0xf5,
+ 0xf6, 0xf7, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0b,
+ 0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f, 0x7f, 0xdc, 0xf9, 0x0a, 0x0d, 0x16,
+};
+// clang-format on
+
+#ifndef NDEBUG
+
+// Only used in DLOG.
+bool IsEOSPrefix(HuffmanWord bits, HuffmanCodeLength bits_available) {
+ if (bits_available == 0) {
+ return true;
+ }
+ // We expect all the bits below the high order |bits_available| bits
+ // to be cleared.
+ HuffmanWord expected = HuffmanWord(0xffffffff) << (32 - bits_available);
+ return bits == expected;
+}
+
+#endif // NDEBUG
+
+} // namespace
+
+// TODO(jamessynge): Should we read these magic numbers from
+// kLengthToFirstLJCode? Would that reduce cache consumption? Slow decoding?
+// TODO(jamessynge): Is this being inlined by the compiler? Should we inline
+// into DecodeString the tests for code lengths 5 through 8 (> 99% of codes
+// according to the HPACK spec)?
+HpackHuffmanDecoder::HuffmanCodeLength HpackHuffmanDecoder::CodeLengthOfPrefix(
+ HpackHuffmanDecoder::HuffmanWord value) {
+ HuffmanCodeLength length;
+ if (value < 0xb8000000) {
+ if (value < 0x50000000) {
+ length = 5;
+ } else {
+ length = 6;
+ }
+ } else {
+ if (value < 0xfe000000) {
+ if (value < 0xf8000000) {
+ length = 7;
+ } else {
+ length = 8;
+ }
+ } else {
+ if (value < 0xffc00000) {
+ if (value < 0xffa00000) {
+ if (value < 0xff400000) {
+ length = 10;
+ } else {
+ length = 11;
+ }
+ } else {
+ length = 12;
+ }
+ } else {
+ if (value < 0xfffe0000) {
+ if (value < 0xfff80000) {
+ if (value < 0xfff00000) {
+ length = 13;
+ } else {
+ length = 14;
+ }
+ } else {
+ length = 15;
+ }
+ } else {
+ if (value < 0xffff4800) {
+ if (value < 0xfffee000) {
+ if (value < 0xfffe6000) {
+ length = 19;
+ } else {
+ length = 20;
+ }
+ } else {
+ length = 21;
+ }
+ } else {
+ if (value < 0xffffea00) {
+ if (value < 0xffffb000) {
+ length = 22;
+ } else {
+ length = 23;
+ }
+ } else {
+ if (value < 0xfffffbc0) {
+ if (value < 0xfffff800) {
+ if (value < 0xfffff600) {
+ length = 24;
+ } else {
+ length = 25;
+ }
+ } else {
+ length = 26;
+ }
+ } else {
+ if (value < 0xfffffff0) {
+ if (value < 0xfffffe20) {
+ length = 27;
+ } else {
+ length = 28;
+ }
+ } else {
+ length = 30;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return length;
+}
+
+HuffmanWord HpackHuffmanDecoder::DecodeToCanonical(
+ HuffmanCodeLength code_length,
+ HuffmanWord bits) {
+ DCHECK_LE(kMinCodeLength, code_length);
+ DCHECK_LE(code_length, kMaxCodeLength);
+
+ // What is the first left-justified code of length |code_length|?
+ HuffmanWord first_lj_code = kLengthToFirstLJCode[code_length];
+ DCHECK_NE(kInvalidLJCode, first_lj_code);
+
+ // Which canonical symbol corresponds to the high order |code_length|
+ // bits of |first_lj_code|?
+ HuffmanWord first_canonical = kLengthToFirstCanonical[code_length];
+ DCHECK_NE(kInvalidCanonical, first_canonical);
+
+ // What is the position of the canonical symbol being decoded within
+ // the canonical symbols of length |code_length|?
+ HuffmanWord ordinal_in_length =
+ ((bits - first_lj_code) >> (kHuffmanWordLength - code_length));
+
+ // Combined these two to produce the position of the canonical symbol
+ // being decoded within all of the canonical symbols.
+ return first_canonical + ordinal_in_length;
+}
+
+char HpackHuffmanDecoder::CanonicalToSource(HuffmanWord canonical) {
+ DCHECK_LT(canonical, 256u);
+ return static_cast<char>(kCanonicalToSymbol[canonical]);
+}
+
+// TODO(jamessynge): Maybe further refactorings, including just passing in a
+// StringPiece instead of an HpackInputStream, thus avoiding the PeekBits calls,
+// and also allowing us to separate the code into portions dealing with long
+// strings, and a later portion dealing with the last few bytes of strings.
+// TODO(jamessynge): Determine if that is worth it by adding some counters to
+// measure the distribution of string sizes seen in practice.
+bool HpackHuffmanDecoder::DecodeString(HpackInputStream* in,
+ size_t out_capacity,
+ std::string* out) {
+ out->clear();
+
+ // Load |bits| with the leading bits of the input stream, left justified
+ // (i.e. the bits of the first byte are the high-order bits of |bits|,
+ // and the bits of the fourth byte are the low-order bits of |bits|).
+ // |peeked_success| if there are more bits in |*in| (i.e. the encoding
+ // of the string to be decoded is more than 4 bytes).
+
+ auto bits_available_and_bits = in->InitializePeekBits();
+ HuffmanCodeLength bits_available = bits_available_and_bits.first;
+ HuffmanWord bits = bits_available_and_bits.second;
+
+ // |peeked_success| tracks whether the previous PeekBits call was able to
+ // store any new bits into |bits|. For the first pass through the loop below
+ // the value false is appropriate:
+ // If we have 32 bits (i.e. the input has at least 4 bytes), then:
+ // |peeked_sucess| is not examined because |code_length| is
+ // at most 30 in the HPACK Huffman Code.
+ // If we have at most 24 bits (i.e. the input has at most 3 bytes), then:
+ // It is possible that the very first |code_length| is greater than
+ // |bits_available|, in which case we need to read peeked_success to
+ // determine whether we should try to read more input, or have already
+ // loaded |bits| with the final bits of the input.
+ // After the first loop |peeked_success| has been set by a call to PeekBits.
+ bool peeked_success = false;
+
+ while (true) {
+ const HuffmanCodeLength code_length = CodeLengthOfPrefix(bits);
+ DCHECK_LE(kMinCodeLength, code_length);
+ DCHECK_LE(code_length, kMaxCodeLength);
+ DVLOG(1) << "bits: 0b" << std::bitset<32>(bits)
+ << " (avail=" << bits_available << ")"
+ << " prefix length: " << code_length
+ << (code_length > bits_available ? " *****" : "");
+ if (code_length > bits_available) {
+ if (!peeked_success) {
+ // Unable to read enough input for a match. If only a portion of
+ // the last byte remains, this is a successful EOS condition.
+ // Note that this does NOT check whether the available bits are all
+ // set to 1, which the encoder is required to set at EOS, and the
+ // decoder is required to check.
+ // TODO(jamessynge): Discuss whether we should enforce this check,
+ // as required by the RFC, presumably flag guarded so that we can
+ // disable it should it occur a lot. From my testing it appears that
+ // our encoder may be doing this wrong. Sigh.
+ // TODO(jamessynge): Add a counter for how often the remaining bits
+ // are non-zero.
+ in->ConsumeByteRemainder();
+ DLOG_IF(WARNING,
+ (in->HasMoreData() || !IsEOSPrefix(bits, bits_available)))
+ << "bits: 0b" << std::bitset<32>(bits)
+ << " (avail=" << bits_available << ")"
+ << " prefix length: " << code_length
+ << " HasMoreData: " << in->HasMoreData();
+ return !in->HasMoreData();
+ }
+ // We're dealing with a long code. It *might* be useful to add a special
+ // method to HpackInputStream for getting more than "at most 8" bits
+ // at a time.
+ do {
+ peeked_success = in->PeekBits(&bits_available, &bits);
+ } while (peeked_success && bits_available < 32);
+ } else {
+ if (out->size() == out_capacity) {
+ // This code would cause us to overflow |out_capacity|.
+ // TODO(jamessynge) Avoid this case by pre-allocating out based on
+ // scaling up the encoded size by 8/5 (shortest codes are 5 bits).
+ DLOG(WARNING) << "Output size too large: " << out_capacity;
+ return false;
+ }
+
+ // Convert from the prefix code of length |code_length| to the
+ // canonical symbol (i.e. where the input symbols (bytes) are ordered by
+ // increasing code length and then by their increasing uint8 value).
+ HuffmanWord canonical = DecodeToCanonical(code_length, bits);
+
+ bits = bits << code_length;
+ bits_available -= code_length;
+ in->ConsumeBits(code_length);
+
+ if (canonical < 256) {
+ out->push_back(CanonicalToSource(canonical));
+ } else {
+ // Encoder is not supposed to explicity encode the EOS symbol (30
+ // 1-bits).
+ // TODO(jamessynge): Discuss returning false here, as required by HPACK.
+ DCHECK(false) << "EOS explicitly encoded!\n"
+ << "bits: 0b" << std::bitset<32>(bits)
+ << " (avail=" << bits_available << ")"
+ << " prefix length: " << code_length
+ << " canonical: " << canonical;
+ }
+ // Get some more bits for decoding (up to 8). |peeked_success| is true
+ // if we got any bits.
+ peeked_success = in->PeekBits(&bits_available, &bits);
+ }
+ DLOG_IF(WARNING, (VLOG_IS_ON(1) && bits_available < 32 && !peeked_success))
+ << "no more peeking possible";
+ }
+}
+
+} // namespace net
diff --git a/chromium/net/spdy/hpack/hpack_huffman_decoder.h b/chromium/net/spdy/hpack/hpack_huffman_decoder.h
new file mode 100644
index 00000000000..d63aa048522
--- /dev/null
+++ b/chromium/net/spdy/hpack/hpack_huffman_decoder.h
@@ -0,0 +1,70 @@
+// 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_SPDY_HPACK_HPACK_HUFFMAN_DECODER_H_
+#define NET_SPDY_HPACK_HPACK_HUFFMAN_DECODER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+
+#include "net/base/net_export.h"
+#include "net/spdy/hpack/hpack_input_stream.h"
+
+namespace net {
+namespace test {
+class HpackHuffmanDecoderPeer;
+} // namespace test
+
+// Declared as a class to simplify testing.
+// No instances are actually allocated.
+class NET_EXPORT_PRIVATE HpackHuffmanDecoder {
+ public:
+ typedef uint32_t HuffmanWord;
+ typedef size_t HuffmanCodeLength;
+
+ HpackHuffmanDecoder() = delete;
+
+ // Decodes a string that has been encoded using the HPACK Huffman Code (see
+ // https://httpwg.github.io/specs/rfc7541.html#huffman.code), reading the
+ // encoded bitstream from |*in|, appending each decoded char to |*out|.
+ // To avoid repeatedly growing the |*out| string, the caller should reserve
+ // sufficient space in |*out| to hold decoded output.
+ // DecodeString() halts when |in| runs out of input, in which case true is
+ // returned. It also halts (returning false) if an invalid Huffman code
+ // prefix is read, or if |out_capacity| would otherwise be overflowed.
+ static bool DecodeString(HpackInputStream* in,
+ size_t out_capacity,
+ std::string* out);
+
+ private:
+ friend class test::HpackHuffmanDecoderPeer;
+
+ // The following private methods are declared here rather than simply
+ // inlined into DecodeString so that they can be tested directly.
+
+ // Returns the length (in bits) of the HPACK Huffman code that starts with
+ // the high bits of |value|.
+ static HuffmanCodeLength CodeLengthOfPrefix(HuffmanWord value);
+
+ // Decodes the code in the high |code_length| bits of |bits| to the
+ // corresponding canonical symbol.
+ // Returns a value in the range [0, 256] (257 values). 256 is the EOS symbol,
+ // which must not be explicitly encoded; the HPACK spec says that a decoder
+ // must treat EOS as a decoding error.
+ // Note that the canonical symbol is not the final value to be output because
+ // the source symbols are not in descending probability order, so another
+ // translation is required (see CanonicalToSource below).
+ static HuffmanWord DecodeToCanonical(HuffmanCodeLength code_length,
+ HuffmanWord bits);
+
+ // Converts a canonical symbol to the source symbol (the char in the original
+ // string that was encoded).
+ static char CanonicalToSource(HuffmanWord canonical);
+};
+
+} // namespace net
+
+#endif // NET_SPDY_HPACK_HPACK_HUFFMAN_DECODER_H_
diff --git a/chromium/net/spdy/hpack/hpack_huffman_decoder_test.cc b/chromium/net/spdy/hpack/hpack_huffman_decoder_test.cc
new file mode 100644
index 00000000000..5b7b16cc072
--- /dev/null
+++ b/chromium/net/spdy/hpack/hpack_huffman_decoder_test.cc
@@ -0,0 +1,292 @@
+// 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/spdy/hpack/hpack_huffman_decoder.h"
+
+#include <bitset>
+#include <limits>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/rand_util.h"
+#include "base/strings/string_piece.h"
+#include "net/spdy/hpack/hpack_constants.h"
+#include "net/spdy/hpack/hpack_huffman_table.h"
+#include "net/spdy/hpack/hpack_input_stream.h"
+#include "net/spdy/hpack/hpack_output_stream.h"
+#include "net/spdy/spdy_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::StringPiece;
+
+namespace net {
+namespace test {
+
+namespace {
+
+uint32_t RandUint32() {
+ return static_cast<uint32_t>(base::RandUint64() & 0xffffffff);
+}
+
+} // anonymous namespace
+
+// Bits(HuffmanWord) constructs a bitset<32>, which produces nicely formatted
+// binary numbers when LOG'd.
+typedef std::bitset<32> Bits;
+
+typedef HpackHuffmanDecoder::HuffmanWord HuffmanWord;
+typedef HpackHuffmanDecoder::HuffmanCodeLength HuffmanCodeLength;
+
+class HpackHuffmanDecoderPeer {
+ public:
+ static HuffmanCodeLength CodeLengthOfPrefix(HuffmanWord value) {
+ return HpackHuffmanDecoder::CodeLengthOfPrefix(value);
+ }
+
+ static HuffmanWord DecodeToCanonical(HuffmanCodeLength code_length,
+ HuffmanWord bits) {
+ return HpackHuffmanDecoder::DecodeToCanonical(code_length, bits);
+ }
+
+ static char CanonicalToSource(HuffmanWord canonical) {
+ return HpackHuffmanDecoder::CanonicalToSource(canonical);
+ }
+};
+
+// Tests of the ability to decode the HPACK Huffman Code, defined in:
+// https://httpwg.github.io/specs/rfc7541.html#huffman.code
+class HpackHuffmanDecoderTest : public ::testing::Test {
+ protected:
+ HpackHuffmanDecoderTest() : table_(ObtainHpackHuffmanTable()) {}
+
+ // Since kHpackHuffmanCode doesn't include the canonical symbol value,
+ // this helper helps us to decode directly to the source symbol, allowing
+ // for EOS.
+ uint16_t DecodeToSource(HuffmanCodeLength code_length, HuffmanWord bits) {
+ HuffmanWord canonical =
+ HpackHuffmanDecoderPeer::DecodeToCanonical(code_length, bits);
+ EXPECT_LE(canonical, 256u);
+ if (canonical == 256u) {
+ return canonical;
+ }
+ return static_cast<unsigned char>(
+ HpackHuffmanDecoderPeer::CanonicalToSource(canonical));
+ }
+
+ void EncodeString(StringPiece input, std::string* encoded) {
+ HpackOutputStream output_stream;
+ table_.EncodeString(input, &output_stream);
+ encoded->clear();
+ output_stream.TakeString(encoded);
+ // Verify EncodedSize() agrees with EncodeString().
+ EXPECT_EQ(encoded->size(), table_.EncodedSize(input));
+ }
+
+ std::string EncodeString(StringPiece input) {
+ std::string result;
+ EncodeString(input, &result);
+ return result;
+ }
+
+ const HpackHuffmanTable& table_;
+};
+
+TEST_F(HpackHuffmanDecoderTest, CodeLengthOfPrefix) {
+ for (const HpackHuffmanSymbol& entry : HpackHuffmanCode()) {
+ // First confirm our assumption that the low order bits of entry.code
+ // (those not part of the high order entry.length bits) are zero.
+ uint32_t non_code_bits = 0xffffffff >> entry.length;
+ EXPECT_EQ(0u, entry.code & non_code_bits);
+
+ // entry.code has a code length of entry.length.
+ EXPECT_EQ(entry.length,
+ HpackHuffmanDecoderPeer::CodeLengthOfPrefix(entry.code))
+ << "Full code: " << Bits(entry.code) << "\n"
+ << " ID: " << entry.id;
+
+ // Let's try again with all the low order bits set to 1.
+ uint32_t bits = entry.code | (0xffffffff >> entry.length);
+ EXPECT_EQ(entry.length, HpackHuffmanDecoderPeer::CodeLengthOfPrefix(bits))
+ << "Full code: " << Bits(entry.code) << "\n"
+ << " bits: " << Bits(bits) << "\n"
+ << " ID: " << entry.id;
+
+ // Let's try again with random low order bits.
+ uint32_t rand = RandUint32() & (0xffffffff >> entry.length);
+ bits = entry.code | rand;
+ EXPECT_EQ(entry.length, HpackHuffmanDecoderPeer::CodeLengthOfPrefix(bits))
+ << "Full code: " << Bits(entry.code) << "\n"
+ << " rand: " << Bits(rand) << "\n"
+ << " bits: " << Bits(bits) << "\n"
+ << " ID: " << entry.id;
+
+ // If fewer bits are available and low order bits are zero after left
+ // shifting (should be true), CodeLengthOfPrefix should never return
+ // a value that is <= the number of available bits.
+ for (uint8_t available = entry.length - 1; available > 0; --available) {
+ uint32_t mask = 0xffffffff;
+ uint32_t avail_mask = mask << (32 - available);
+ bits = entry.code & avail_mask;
+ EXPECT_LT(available, HpackHuffmanDecoderPeer::CodeLengthOfPrefix(bits))
+ << "Full code: " << Bits(entry.code) << "\n"
+ << "availMask: " << Bits(avail_mask) << "\n"
+ << " bits: " << Bits(bits) << "\n"
+ << " ID: " << entry.id;
+ }
+ }
+}
+
+TEST_F(HpackHuffmanDecoderTest, DecodeToSource) {
+ for (const HpackHuffmanSymbol& entry : HpackHuffmanCode()) {
+ // Check that entry.code, which has all the low order bits set to 0,
+ // decodes to entry.id.
+ EXPECT_EQ(entry.id, DecodeToSource(entry.length, entry.code))
+ << " Length: " << entry.length << "\n"
+ << "Full code: " << Bits(entry.code);
+
+ // Let's try again with all the low order bits set to 1.
+ uint32_t bits = entry.code | (0xffffffff >> entry.length);
+ EXPECT_EQ(entry.id, DecodeToSource(entry.length, bits))
+ << " Length: " << entry.length << "\n"
+ << "Full code: " << Bits(entry.code) << "\n"
+ << " bits: " << Bits(bits);
+
+ // Let's try again with random low order bits.
+ uint32_t rand = RandUint32() & (0xffffffff >> entry.length);
+ bits = entry.code | rand;
+ EXPECT_EQ(entry.id, DecodeToSource(entry.length, bits))
+ << " Length: " << entry.length << "\n"
+ << "Full code: " << Bits(entry.code) << "\n"
+ << " rand: " << Bits(rand) << "\n"
+ << " bits: " << Bits(bits);
+ }
+}
+
+TEST_F(HpackHuffmanDecoderTest, SpecRequestExamples) {
+ std::string buffer;
+ std::string test_table[] = {
+ a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"),
+ "www.example.com",
+ a2b_hex("a8eb10649cbf"),
+ "no-cache",
+ a2b_hex("25a849e95ba97d7f"),
+ "custom-key",
+ a2b_hex("25a849e95bb8e8b4bf"),
+ "custom-value",
+ };
+ // Round-trip each test example.
+ for (size_t i = 0; i != arraysize(test_table); i += 2) {
+ const std::string& encodedFixture(test_table[i]);
+ const std::string& decodedFixture(test_table[i + 1]);
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
+ encodedFixture);
+ EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(
+ &input_stream, decodedFixture.size(), &buffer));
+ EXPECT_EQ(decodedFixture, buffer);
+ buffer = EncodeString(decodedFixture);
+ EXPECT_EQ(encodedFixture, buffer);
+ }
+}
+
+TEST_F(HpackHuffmanDecoderTest, TooLong) {
+ std::string buffer;
+ std::string test_table[] = {
+ a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"),
+ "www.example.com",
+ a2b_hex("a8eb10649cbf"),
+ "no-cache",
+ a2b_hex("25a849e95ba97d7f"),
+ "custom-key",
+ a2b_hex("25a849e95bb8e8b4bf"),
+ "custom-value",
+ };
+ // Round-trip each test example, but with too small an output buffer.
+ for (size_t i = 0; i != arraysize(test_table); i += 2) {
+ const std::string& encodedFixture(test_table[i]);
+ const std::string& decodedFixture(test_table[i + 1]);
+ uint32_t limit = base::RandInt(0, decodedFixture.size() - 1);
+ HpackInputStream strm(std::numeric_limits<uint32_t>::max(), encodedFixture);
+ EXPECT_FALSE(HpackHuffmanDecoder::DecodeString(&strm, limit, &buffer));
+
+ // This is NOT a required test as it really tests an implementation detail,
+ // i.e. the fact that it writes the first |limit| values into |buffer|,
+ // then returns false leaving those chars in the buffer.
+ EXPECT_EQ(decodedFixture.substr(0, limit), buffer);
+ }
+}
+
+TEST_F(HpackHuffmanDecoderTest, SpecResponseExamples) {
+ std::string buffer;
+ // clang-format off
+ std::string test_table[] = {
+ a2b_hex("6402"),
+ "302",
+ a2b_hex("aec3771a4b"),
+ "private",
+ a2b_hex("d07abe941054d444a8200595040b8166"
+ "e082a62d1bff"),
+ "Mon, 21 Oct 2013 20:13:21 GMT",
+ a2b_hex("9d29ad171863c78f0b97c8e9ae82ae43"
+ "d3"),
+ "https://www.example.com",
+ a2b_hex("94e7821dd7f2e6c7b335dfdfcd5b3960"
+ "d5af27087f3672c1ab270fb5291f9587"
+ "316065c003ed4ee5b1063d5007"),
+ "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
+ };
+ // clang-format on
+ // Round-trip each test example.
+ for (size_t i = 0; i != arraysize(test_table); i += 2) {
+ const std::string& encodedFixture(test_table[i]);
+ const std::string& decodedFixture(test_table[i + 1]);
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
+ encodedFixture);
+ EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(
+ &input_stream, decodedFixture.size(), &buffer));
+ EXPECT_EQ(decodedFixture, buffer);
+ buffer = EncodeString(decodedFixture);
+ EXPECT_EQ(encodedFixture, buffer);
+ }
+}
+
+TEST_F(HpackHuffmanDecoderTest, RoundTripIndividualSymbols) {
+ for (size_t i = 0; i != 256; i++) {
+ char c = static_cast<char>(i);
+ char storage[3] = {c, c, c};
+ StringPiece input(storage, arraysize(storage));
+ std::string buffer_in = EncodeString(input);
+ std::string buffer_out;
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
+ buffer_in);
+ EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, input.size(),
+ &buffer_out));
+ EXPECT_EQ(input, buffer_out);
+ }
+}
+
+// Creates 256 input strings, each with a unique byte value i used to sandwich
+// all the other higher byte values.
+TEST_F(HpackHuffmanDecoderTest, RoundTripSymbolSequences) {
+ std::string input;
+ std::string encoded;
+ std::string decoded;
+ for (size_t i = 0; i != 256; i++) {
+ input.clear();
+ auto ic = static_cast<char>(i);
+ input.push_back(ic);
+ for (size_t j = i; j != 256; j++) {
+ input.push_back(static_cast<char>(j));
+ input.push_back(ic);
+ }
+ EncodeString(input, &encoded);
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
+ encoded);
+ EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, input.size(),
+ &decoded));
+ EXPECT_EQ(input, decoded);
+ }
+}
+
+} // namespace test
+} // namespace net
diff --git a/chromium/net/spdy/hpack/hpack_huffman_table.cc b/chromium/net/spdy/hpack/hpack_huffman_table.cc
index 8815e608fdf..e29e1c4debd 100644
--- a/chromium/net/spdy/hpack/hpack_huffman_table.cc
+++ b/chromium/net/spdy/hpack/hpack_huffman_table.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <cmath>
+#include <memory>
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
@@ -20,9 +21,9 @@ using std::string;
namespace {
// How many bits to index in the root decode table.
-const uint8 kDecodeTableRootBits = 9;
+const uint8_t kDecodeTableRootBits = 9;
// Maximum number of bits to index in successive decode tables.
-const uint8 kDecodeTableBranchBits = 6;
+const uint8_t kDecodeTableBranchBits = 6;
bool SymbolLengthAndIdCompare(const HpackHuffmanSymbol& a,
const HpackHuffmanSymbol& b) {
@@ -39,9 +40,9 @@ bool SymbolIdCompare(const HpackHuffmanSymbol& a, const HpackHuffmanSymbol& b) {
HpackHuffmanTable::DecodeEntry::DecodeEntry()
: next_table_index(0), length(0), symbol_id(0) {}
-HpackHuffmanTable::DecodeEntry::DecodeEntry(uint8 next_table_index,
- uint8 length,
- uint16 symbol_id)
+HpackHuffmanTable::DecodeEntry::DecodeEntry(uint8_t next_table_index,
+ uint8_t length,
+ uint16_t symbol_id)
: next_table_index(next_table_index),
length(length),
symbol_id(symbol_id) {}
@@ -56,11 +57,11 @@ HpackHuffmanTable::~HpackHuffmanTable() {}
bool HpackHuffmanTable::Initialize(const HpackHuffmanSymbol* input_symbols,
size_t symbol_count) {
CHECK(!IsInitialized());
- DCHECK(base::IsValueInRangeForNumericType<uint16>(symbol_count));
+ DCHECK(base::IsValueInRangeForNumericType<uint16_t>(symbol_count));
std::vector<Symbol> symbols(symbol_count);
// Validate symbol id sequence, and copy into |symbols|.
- for (uint16 i = 0; i < symbol_count; i++) {
+ for (uint16_t i = 0; i < symbol_count; i++) {
if (i != input_symbols[i].id) {
failed_symbol_id_ = i;
return false;
@@ -75,7 +76,7 @@ bool HpackHuffmanTable::Initialize(const HpackHuffmanSymbol* input_symbols,
}
for (size_t i = 1; i != symbols.size(); i++) {
unsigned code_shift = 32 - symbols[i - 1].length;
- uint32 code = symbols[i - 1].code + (1 << code_shift);
+ uint32_t code = symbols[i - 1].code + (1 << code_shift);
if (code != symbols[i].code) {
failed_symbol_id_ = symbols[i].id;
@@ -94,7 +95,7 @@ bool HpackHuffmanTable::Initialize(const HpackHuffmanSymbol* input_symbols,
// of bytes.
return false;
}
- pad_bits_ = static_cast<uint8>(symbols.back().code >> 24);
+ pad_bits_ = static_cast<uint8_t>(symbols.back().code >> 24);
BuildDecodeTables(symbols);
// Order on symbol ID ascending.
@@ -122,18 +123,18 @@ void HpackHuffmanTable::BuildDecodeTables(const std::vector<Symbol>& symbols) {
// that entry without fear of introducing unneccesary branches later.
for (std::vector<Symbol>::const_reverse_iterator it = symbols.rbegin();
it != symbols.rend(); ++it) {
- uint8 table_index = 0;
+ uint8_t table_index = 0;
while (true) {
const DecodeTable table = decode_tables_[table_index];
// Mask and shift the portion of the code being indexed into low bits.
- uint32 index = (it->code << table.prefix_length);
+ uint32_t index = (it->code << table.prefix_length);
index = index >> (32 - table.indexed_length);
CHECK_LT(index, table.size());
DecodeEntry entry = Entry(table, index);
- uint8 total_indexed = table.prefix_length + table.indexed_length;
+ uint8_t total_indexed = table.prefix_length + table.indexed_length;
if (total_indexed >= it->length) {
// We're writing a terminal entry.
entry.length = it->length;
@@ -149,8 +150,8 @@ void HpackHuffmanTable::BuildDecodeTables(const std::vector<Symbol>& symbols) {
entry.length = it->length;
entry.next_table_index =
AddDecodeTable(total_indexed, // Becomes the new table prefix.
- std::min<uint8>(kDecodeTableBranchBits,
- entry.length - total_indexed));
+ std::min<uint8_t>(kDecodeTableBranchBits,
+ entry.length - total_indexed));
SetEntry(table, index, entry);
}
CHECK_NE(entry.next_table_index, table_index);
@@ -160,7 +161,7 @@ void HpackHuffmanTable::BuildDecodeTables(const std::vector<Symbol>& symbols) {
// Fill shorter table entries into the additional entry spots they map to.
for (size_t i = 0; i != decode_tables_.size(); i++) {
const DecodeTable& table = decode_tables_[i];
- uint8 total_indexed = table.prefix_length + table.indexed_length;
+ uint8_t total_indexed = table.prefix_length + table.indexed_length;
size_t j = 0;
while (j != table.size()) {
@@ -183,7 +184,7 @@ void HpackHuffmanTable::BuildDecodeTables(const std::vector<Symbol>& symbols) {
}
}
-uint8 HpackHuffmanTable::AddDecodeTable(uint8 prefix, uint8 indexed) {
+uint8_t HpackHuffmanTable::AddDecodeTable(uint8_t prefix, uint8_t indexed) {
CHECK_LT(decode_tables_.size(), 255u);
{
DecodeTable table;
@@ -193,19 +194,19 @@ uint8 HpackHuffmanTable::AddDecodeTable(uint8 prefix, uint8 indexed) {
decode_tables_.push_back(table);
}
decode_entries_.resize(decode_entries_.size() + (size_t(1) << indexed));
- return static_cast<uint8>(decode_tables_.size() - 1);
+ return static_cast<uint8_t>(decode_tables_.size() - 1);
}
const HpackHuffmanTable::DecodeEntry& HpackHuffmanTable::Entry(
const DecodeTable& table,
- uint32 index) const {
+ uint32_t index) const {
DCHECK_LT(index, table.size());
DCHECK_LT(table.entries_offset + index, decode_entries_.size());
return decode_entries_[table.entries_offset + index];
}
void HpackHuffmanTable::SetEntry(const DecodeTable& table,
- uint32 index,
+ uint32_t index,
const DecodeEntry& entry) {
CHECK_LT(index, table.size());
CHECK_LT(table.entries_offset + index, decode_entries_.size());
@@ -220,28 +221,28 @@ void HpackHuffmanTable::EncodeString(StringPiece in,
HpackOutputStream* out) const {
size_t bit_remnant = 0;
for (size_t i = 0; i != in.size(); i++) {
- uint16 symbol_id = static_cast<uint8>(in[i]);
+ uint16_t symbol_id = static_cast<uint8_t>(in[i]);
CHECK_GT(code_by_id_.size(), symbol_id);
// Load, and shift code to low bits.
unsigned length = length_by_id_[symbol_id];
- uint32 code = code_by_id_[symbol_id] >> (32 - length);
+ uint32_t code = code_by_id_[symbol_id] >> (32 - length);
bit_remnant = (bit_remnant + length) % 8;
if (length > 24) {
- out->AppendBits(static_cast<uint8>(code >> 24), length - 24);
+ out->AppendBits(static_cast<uint8_t>(code >> 24), length - 24);
length = 24;
}
if (length > 16) {
- out->AppendBits(static_cast<uint8>(code >> 16), length - 16);
+ out->AppendBits(static_cast<uint8_t>(code >> 16), length - 16);
length = 16;
}
if (length > 8) {
- out->AppendBits(static_cast<uint8>(code >> 8), length - 8);
+ out->AppendBits(static_cast<uint8_t>(code >> 8), length - 8);
length = 8;
}
- out->AppendBits(static_cast<uint8>(code), length);
+ out->AppendBits(static_cast<uint8_t>(code), length);
}
if (bit_remnant != 0) {
// Pad current byte as required.
@@ -252,7 +253,7 @@ void HpackHuffmanTable::EncodeString(StringPiece in,
size_t HpackHuffmanTable::EncodedSize(StringPiece in) const {
size_t bit_count = 0;
for (size_t i = 0; i != in.size(); i++) {
- uint16 symbol_id = static_cast<uint8>(in[i]);
+ uint16_t symbol_id = static_cast<uint8_t>(in[i]);
CHECK_GT(code_by_id_.size(), symbol_id);
bit_count += length_by_id_[symbol_id];
@@ -263,9 +264,9 @@ size_t HpackHuffmanTable::EncodedSize(StringPiece in) const {
return bit_count / 8;
}
-bool HpackHuffmanTable::DecodeString(HpackInputStream* in,
- size_t out_capacity,
- string* out) const {
+bool HpackHuffmanTable::GenericDecodeString(HpackInputStream* in,
+ size_t out_capacity,
+ string* out) const {
// Number of decode iterations required for a 32-bit code.
const int kDecodeIterations = static_cast<int>(
std::ceil((32.f - kDecodeTableRootBits) / kDecodeTableBranchBits));
@@ -273,13 +274,13 @@ bool HpackHuffmanTable::DecodeString(HpackInputStream* in,
out->clear();
// Current input, stored in the high |bits_available| bits of |bits|.
- uint32 bits = 0;
+ uint32_t bits = 0;
size_t bits_available = 0;
bool peeked_success = in->PeekBits(&bits_available, &bits);
while (true) {
const DecodeTable* table = &decode_tables_[0];
- uint32 index = bits >> (32 - kDecodeTableRootBits);
+ uint32_t index = bits >> (32 - kDecodeTableRootBits);
for (int i = 0; i != kDecodeIterations; i++) {
DCHECK_LT(index, table->size());
diff --git a/chromium/net/spdy/hpack/hpack_huffman_table.h b/chromium/net/spdy/hpack/hpack_huffman_table.h
index 1904a7b7022..6fd60e43d39 100644
--- a/chromium/net/spdy/hpack/hpack_huffman_table.h
+++ b/chromium/net/spdy/hpack/hpack_huffman_table.h
@@ -5,11 +5,12 @@
#ifndef NET_SPDY_HPACK_HUFFMAN_TABLE_H_
#define NET_SPDY_HPACK_HUFFMAN_TABLE_H_
+#include <stdint.h>
+
#include <cstddef>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/spdy/hpack/hpack_constants.h"
@@ -38,22 +39,22 @@ class NET_EXPORT_PRIVATE HpackHuffmanTable {
// with successive portions of the prefix.
struct NET_EXPORT_PRIVATE DecodeEntry {
DecodeEntry();
- DecodeEntry(uint8 next_table_index, uint8 length, uint16 symbol_id);
+ DecodeEntry(uint8_t next_table_index, uint8_t length, uint16_t symbol_id);
// The next table to consult. If this is a terminal,
// |next_table_index| will be self-referential.
- uint8 next_table_index;
+ uint8_t next_table_index;
// Bit-length of terminal code, if this is a terminal. Length of the
// longest code having this prefix, if non-terminal.
- uint8 length;
+ uint8_t length;
// Set only for terminal entries.
- uint16 symbol_id;
+ uint16_t symbol_id;
};
struct NET_EXPORT_PRIVATE DecodeTable {
// Number of bits indexed by the chain leading to this table.
- uint8 prefix_length;
+ uint8_t prefix_length;
// Number of additional prefix bits this table indexes.
- uint8 indexed_length;
+ uint8_t indexed_length;
// Entries are represented as a length |size()| slice into
// |decode_entries_| beginning at |entries_offset|.
size_t entries_offset;
@@ -68,7 +69,7 @@ class NET_EXPORT_PRIVATE HpackHuffmanTable {
// code as determined by the given symbols. Must be called exactly once.
// Returns false if the input symbols define an invalid coding, and true
// otherwise. Symbols must be presented in ascending ID order with no gaps,
- // and |symbol_count| must fit in a uint16.
+ // and |symbol_count| must fit in a uint16_t.
bool Initialize(const Symbol* input_symbols, size_t symbol_count);
// Returns whether Initialize() has been successfully called.
@@ -81,14 +82,18 @@ class NET_EXPORT_PRIVATE HpackHuffmanTable {
// Returns the encoded size of the input string.
size_t EncodedSize(base::StringPiece in) const;
- // Decodes symbols from |in| into |out|. It is the caller's responsibility
- // to ensure |out| has a reserved a sufficient buffer to hold decoded output.
- // DecodeString() halts when |in| runs out of input, in which case true is
- // returned. It also halts (returning false) if an invalid Huffman code
- // prefix is read, or if |out_capacity| would otherwise be overflowed.
- bool DecodeString(HpackInputStream* in,
- size_t out_capacity,
- std::string* out) const;
+ // Decodes symbols from |in| into |out|, using the support for generic (any)
+ // huffman tables, not just those defined in the HPACK spec. It is the
+ // caller's responsibility to ensure |out| has reserved a sufficient buffer to
+ // hold decoded output. GenericDecodeString() halts when |in| runs out of
+ // input, in which case true is returned. It also halts (returning false) if
+ // an invalid Huffman code prefix is read, or if |out_capacity| would
+ // otherwise be overflowed.
+ // DEPRECATED: HpackHuffmanDecoder is now used for decoding strings encoded
+ // according to the Huffman Table in the HPACK spec.
+ bool GenericDecodeString(HpackInputStream* in,
+ size_t out_capacity,
+ std::string* out) const;
private:
// Expects symbols ordered on length & ID ascending.
@@ -99,12 +104,12 @@ class NET_EXPORT_PRIVATE HpackHuffmanTable {
// Adds a new DecodeTable with the argument prefix & indexed length.
// Returns the new table index.
- uint8 AddDecodeTable(uint8 prefix, uint8 indexed);
+ uint8_t AddDecodeTable(uint8_t prefix, uint8_t indexed);
- const DecodeEntry& Entry(const DecodeTable& table, uint32 index) const;
+ const DecodeEntry& Entry(const DecodeTable& table, uint32_t index) const;
void SetEntry(const DecodeTable& table,
- uint32 index,
+ uint32_t index,
const DecodeEntry& entry);
std::vector<DecodeTable> decode_tables_;
@@ -112,15 +117,15 @@ class NET_EXPORT_PRIVATE HpackHuffmanTable {
// Symbol code and code length, in ascending symbol ID order.
// Codes are stored in the most-significant bits of the word.
- std::vector<uint32> code_by_id_;
- std::vector<uint8> length_by_id_;
+ std::vector<uint32_t> code_by_id_;
+ std::vector<uint8_t> length_by_id_;
// The first 8 bits of the longest code. Applied when generating padding bits.
- uint8 pad_bits_;
+ uint8_t pad_bits_;
// If initialization fails, preserve the symbol ID which failed validation
// for examination in tests.
- uint16 failed_symbol_id_;
+ uint16_t failed_symbol_id_;
};
} // namespace net
diff --git a/chromium/net/spdy/hpack/hpack_huffman_table_test.cc b/chromium/net/spdy/hpack/hpack_huffman_table_test.cc
index a48ccb42450..95ae765d8f8 100644
--- a/chromium/net/spdy/hpack/hpack_huffman_table_test.cc
+++ b/chromium/net/spdy/hpack/hpack_huffman_table_test.cc
@@ -4,11 +4,17 @@
#include "net/spdy/hpack/hpack_huffman_table.h"
+#include <stdint.h>
+
#include <bitset>
+#include <limits>
#include <string>
+#include <utility>
#include "base/logging.h"
+#include "base/macros.h"
#include "net/spdy/hpack/hpack_constants.h"
+#include "net/spdy/hpack/hpack_huffman_decoder.h"
#include "net/spdy/hpack/hpack_input_stream.h"
#include "net/spdy/hpack/hpack_output_stream.h"
#include "net/spdy/spdy_test_utils.h"
@@ -32,8 +38,8 @@ class HpackHuffmanTablePeer {
explicit HpackHuffmanTablePeer(const HpackHuffmanTable& table)
: table_(table) {}
- const std::vector<uint32>& code_by_id() const { return table_.code_by_id_; }
- const std::vector<uint8>& length_by_id() const {
+ const std::vector<uint32_t>& code_by_id() const { return table_.code_by_id_; }
+ const std::vector<uint8_t>& length_by_id() const {
return table_.length_by_id_;
}
const std::vector<DecodeTable>& decode_tables() const {
@@ -43,7 +49,7 @@ class HpackHuffmanTablePeer {
// Cast to match signed-ness of bits8().
return static_cast<char>(table_.pad_bits_);
}
- uint16 failed_symbol_id() const { return table_.failed_symbol_id_; }
+ uint16_t failed_symbol_id() const { return table_.failed_symbol_id_; }
std::vector<DecodeEntry> decode_entries(const DecodeTable& decode_table) {
std::vector<DecodeEntry>::const_iterator begin =
table_.decode_entries_.begin() + decode_table.entries_offset;
@@ -56,9 +62,11 @@ class HpackHuffmanTablePeer {
namespace {
-class HpackHuffmanTableTest : public ::testing::Test {
+// Tests of the ability to decode some canonical Huffman code,
+// not just the one defined in the RFC 7541.
+class GenericHuffmanTableTest : public ::testing::TestWithParam<bool> {
protected:
- HpackHuffmanTableTest() : table_(), peer_(table_) {}
+ GenericHuffmanTableTest() : table_(), peer_(table_) {}
string EncodeString(StringPiece input) {
string result;
@@ -82,21 +90,14 @@ MATCHER(DecodeEntryEq, "") {
lhs.length == rhs.length && lhs.symbol_id == rhs.symbol_id;
}
-uint32 bits32(const string& bitstring) {
+uint32_t bits32(const string& bitstring) {
return std::bitset<32>(bitstring).to_ulong();
}
char bits8(const string& bitstring) {
return static_cast<char>(std::bitset<8>(bitstring).to_ulong());
}
-TEST_F(HpackHuffmanTableTest, InitializeHpackCode) {
- std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
- EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
- EXPECT_TRUE(table_.IsInitialized());
- EXPECT_EQ(peer_.pad_bits(), bits8("11111111")); // First 8 bits of EOS.
-}
-
-TEST_F(HpackHuffmanTableTest, InitializeEdgeCases) {
+TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) {
{
// Verify eight symbols can be encoded with 3 bits per symbol.
HpackHuffmanSymbol code[] = {
@@ -192,7 +193,7 @@ TEST_F(HpackHuffmanTableTest, InitializeEdgeCases) {
}
}
-TEST_F(HpackHuffmanTableTest, ValidateInternalsWithSmallCode) {
+TEST_F(GenericHuffmanTableTest, ValidateInternalsWithSmallCode) {
HpackHuffmanSymbol code[] = {
{bits32("01100000000000000000000000000000"), 4, 0}, // 3rd.
{bits32("01110000000000000000000000000000"), 4, 1}, // 4th.
@@ -239,12 +240,14 @@ TEST_F(HpackHuffmanTableTest, ValidateInternalsWithSmallCode) {
EXPECT_EQ(expect, buffer_in);
string buffer_out;
- HpackInputStream input_stream(kuint32max, buffer_in);
- EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
+ buffer_in);
+ EXPECT_TRUE(
+ table_.GenericDecodeString(&input_stream, input.size(), &buffer_out));
EXPECT_EQ(buffer_out, input);
}
-TEST_F(HpackHuffmanTableTest, ValidateMultiLevelDecodeTables) {
+TEST_F(GenericHuffmanTableTest, ValidateMultiLevelDecodeTables) {
HpackHuffmanSymbol code[] = {
{bits32("00000000000000000000000000000000"), 6, 0},
{bits32("00000100000000000000000000000000"), 6, 1},
@@ -284,7 +287,7 @@ TEST_F(HpackHuffmanTableTest, ValidateMultiLevelDecodeTables) {
EXPECT_EQ(bits8("00001000"), peer_.pad_bits());
}
-TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
+TEST_F(GenericHuffmanTableTest, DecodeWithBadInput) {
HpackHuffmanSymbol code[] = {
{bits32("01100000000000000000000000000000"), 4, 0},
{bits32("01110000000000000000000000000000"), 4, 1},
@@ -304,8 +307,8 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
char input_storage[] = {bits8("00010001"), bits8("00110100")};
StringPiece input(input_storage, arraysize(input_storage));
- HpackInputStream input_stream(kuint32max, input);
- EXPECT_TRUE(table_.DecodeString(&input_stream, capacity, &buffer));
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
+ EXPECT_TRUE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
EXPECT_EQ(buffer, "\x02\x03\x02\x06");
}
{
@@ -314,8 +317,8 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
char input_storage[] = {bits8("00010001"), bits8("01000111")};
StringPiece input(input_storage, arraysize(input_storage));
- HpackInputStream input_stream(kuint32max, input);
- EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer));
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
+ EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
EXPECT_EQ(buffer, "\x02\x03\x02");
}
{
@@ -323,8 +326,8 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
std::vector<char> input_storage(1 + capacity / 4, '\0');
StringPiece input(&input_storage[0], input_storage.size());
- HpackInputStream input_stream(kuint32max, input);
- EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer));
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
+ EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
std::vector<char> expected(capacity, '\x02');
EXPECT_THAT(buffer, ElementsAreArray(expected));
@@ -336,16 +339,49 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
char input_storage[] = {bits8("10011010"), bits8("01110000")};
StringPiece input(input_storage, arraysize(input_storage));
- HpackInputStream input_stream(kuint32max, input);
- EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer));
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
+ EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
EXPECT_EQ(buffer, "\x06");
}
}
-TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
- std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
- EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
+// Tests of the ability to decode the HPACK Huffman Code, defined in:
+// https://httpwg.github.io/specs/rfc7541.html#huffman.code
+class HpackHuffmanTableTest : public GenericHuffmanTableTest {
+ protected:
+ void SetUp() override {
+ std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
+ EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
+ EXPECT_TRUE(table_.IsInitialized());
+ }
+
+ void DecodeStringTwice(const string& encoded,
+ size_t out_capacity,
+ string* out) {
+ // First decode with HpackHuffmanTable.
+ {
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
+ encoded);
+ EXPECT_TRUE(table_.GenericDecodeString(&input_stream, out_capacity, out));
+ }
+ // And decode again with the fixed decoder, confirming that the result is
+ // the same.
+ {
+ HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
+ encoded);
+ string buf;
+ EXPECT_TRUE(
+ HpackHuffmanDecoder::DecodeString(&input_stream, out_capacity, &buf));
+ EXPECT_EQ(*out, buf);
+ }
+ }
+};
+
+TEST_F(HpackHuffmanTableTest, InitializeHpackCode) {
+ EXPECT_EQ(peer_.pad_bits(), '\xFF'); // First 8 bits of EOS.
+}
+TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
string buffer;
string test_table[] = {
a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"),
@@ -361,10 +397,7 @@ TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
for (size_t i = 0; i != arraysize(test_table); i += 2) {
const string& encodedFixture(test_table[i]);
const string& decodedFixture(test_table[i + 1]);
- HpackInputStream input_stream(kuint32max, encodedFixture);
-
- EXPECT_TRUE(
- table_.DecodeString(&input_stream, decodedFixture.size(), &buffer));
+ DecodeStringTwice(encodedFixture, decodedFixture.size(), &buffer);
EXPECT_EQ(decodedFixture, buffer);
buffer = EncodeString(decodedFixture);
EXPECT_EQ(encodedFixture, buffer);
@@ -372,9 +405,6 @@ TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
}
TEST_F(HpackHuffmanTableTest, SpecResponseExamples) {
- std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
- EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
-
string buffer;
string test_table[] = {
a2b_hex("6402"), "302", a2b_hex("aec3771a4b"), "private",
@@ -392,38 +422,27 @@ TEST_F(HpackHuffmanTableTest, SpecResponseExamples) {
for (size_t i = 0; i != arraysize(test_table); i += 2) {
const string& encodedFixture(test_table[i]);
const string& decodedFixture(test_table[i + 1]);
- HpackInputStream input_stream(kuint32max, encodedFixture);
-
- EXPECT_TRUE(
- table_.DecodeString(&input_stream, decodedFixture.size(), &buffer));
+ DecodeStringTwice(encodedFixture, decodedFixture.size(), &buffer);
EXPECT_EQ(decodedFixture, buffer);
buffer = EncodeString(decodedFixture);
EXPECT_EQ(encodedFixture, buffer);
}
}
-TEST_F(HpackHuffmanTableTest, RoundTripIndvidualSymbols) {
- std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
- EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
-
+TEST_F(HpackHuffmanTableTest, RoundTripIndividualSymbols) {
for (size_t i = 0; i != 256; i++) {
char c = static_cast<char>(i);
char storage[3] = {c, c, c};
StringPiece input(storage, arraysize(storage));
-
string buffer_in = EncodeString(input);
string buffer_out;
- HpackInputStream input_stream(kuint32max, buffer_in);
- EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
+ DecodeStringTwice(buffer_in, input.size(), &buffer_out);
EXPECT_EQ(input, buffer_out);
}
}
TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) {
- std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
- EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
-
char storage[512];
for (size_t i = 0; i != 256; i++) {
storage[i] = static_cast<char>(i);
@@ -433,16 +452,11 @@ TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) {
string buffer_in = EncodeString(input);
string buffer_out;
-
- HpackInputStream input_stream(kuint32max, buffer_in);
- EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
+ DecodeStringTwice(buffer_in, input.size(), &buffer_out);
EXPECT_EQ(input, buffer_out);
}
TEST_F(HpackHuffmanTableTest, EncodedSizeAgreesWithEncodeString) {
- std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
- EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
-
string test_table[] = {
"",
"Mon, 21 Oct 2013 20:13:21 GMT",
diff --git a/chromium/net/spdy/hpack/hpack_input_stream.cc b/chromium/net/spdy/hpack/hpack_input_stream.cc
index fe6b19c7b55..e9e9540e0ca 100644
--- a/chromium/net/spdy/hpack/hpack_input_stream.cc
+++ b/chromium/net/spdy/hpack/hpack_input_stream.cc
@@ -6,15 +6,15 @@
#include <algorithm>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "net/spdy/hpack/hpack_huffman_decoder.h"
namespace net {
using base::StringPiece;
using std::string;
-HpackInputStream::HpackInputStream(uint32 max_string_literal_size,
+HpackInputStream::HpackInputStream(uint32_t max_string_literal_size,
StringPiece buffer)
: max_string_literal_size_(max_string_literal_size),
buffer_(buffer),
@@ -30,7 +30,7 @@ bool HpackInputStream::MatchPrefixAndConsume(HpackPrefix prefix) {
DCHECK_GT(prefix.bit_size, 0u);
DCHECK_LE(prefix.bit_size, 8u);
- uint32 peeked = 0;
+ uint32_t peeked = 0;
size_t peeked_count = 0;
if (!PeekBits(&peeked_count, &peeked)) {
@@ -44,8 +44,9 @@ bool HpackInputStream::MatchPrefixAndConsume(HpackPrefix prefix) {
return false;
}
-bool HpackInputStream::PeekNextOctet(uint8* next_octet) {
+bool HpackInputStream::PeekNextOctet(uint8_t* next_octet) {
if ((bit_offset_ > 0) || buffer_.empty()) {
+ DVLOG(1) << "HpackInputStream::PeekNextOctet bit_offset_=" << bit_offset_;
return false;
}
@@ -53,7 +54,7 @@ bool HpackInputStream::PeekNextOctet(uint8* next_octet) {
return true;
}
-bool HpackInputStream::DecodeNextOctet(uint8* next_octet) {
+bool HpackInputStream::DecodeNextOctet(uint8_t* next_octet) {
if (!PeekNextOctet(next_octet)) {
return false;
}
@@ -62,7 +63,7 @@ bool HpackInputStream::DecodeNextOctet(uint8* next_octet) {
return true;
}
-bool HpackInputStream::DecodeNextUint32(uint32* I) {
+bool HpackInputStream::DecodeNextUint32(uint32_t* I) {
size_t N = 8 - bit_offset_;
DCHECK_GT(N, 0u);
DCHECK_LE(N, 8u);
@@ -71,9 +72,10 @@ bool HpackInputStream::DecodeNextUint32(uint32* I) {
*I = 0;
- uint8 next_marker = (1 << N) - 1;
- uint8 next_octet = 0;
+ uint8_t next_marker = (1 << N) - 1;
+ uint8_t next_octet = 0;
if (!DecodeNextOctet(&next_octet)) {
+ DVLOG(1) << "HpackInputStream::DecodeNextUint32 initial octet error";
return false;
}
*I = next_octet & next_marker;
@@ -81,15 +83,17 @@ bool HpackInputStream::DecodeNextUint32(uint32* I) {
bool has_more = (*I == next_marker);
size_t shift = 0;
while (has_more && (shift < 32)) {
- uint8 next_octet = 0;
+ uint8_t next_octet = 0;
if (!DecodeNextOctet(&next_octet)) {
+ DVLOG(1) << "HpackInputStream::DecodeNextUint32 shift=" << shift;
return false;
}
has_more = (next_octet & 0x80) != 0;
next_octet &= 0x7f;
- uint32 addend = next_octet << shift;
+ uint32_t addend = next_octet << shift;
// Check for overflow.
if ((addend >> shift) != next_octet) {
+ DVLOG(1) << "HpackInputStream::DecodeNextUint32 overflow";
return false;
}
*I += addend;
@@ -100,7 +104,7 @@ bool HpackInputStream::DecodeNextUint32(uint32* I) {
}
bool HpackInputStream::DecodeNextIdentityString(StringPiece* str) {
- uint32 size = 0;
+ uint32_t size = 0;
if (!DecodeNextUint32(&size)) {
return false;
}
@@ -118,14 +122,17 @@ bool HpackInputStream::DecodeNextIdentityString(StringPiece* str) {
return true;
}
-bool HpackInputStream::DecodeNextHuffmanString(const HpackHuffmanTable& table,
- string* str) {
- uint32 encoded_size = 0;
+bool HpackInputStream::DecodeNextHuffmanString(string* str) {
+ uint32_t encoded_size = 0;
if (!DecodeNextUint32(&encoded_size)) {
+ DVLOG(1) << "HpackInputStream::DecodeNextHuffmanString "
+ << "unable to decode size";
return false;
}
if (encoded_size > buffer_.size()) {
+ DVLOG(1) << "HpackInputStream::DecodeNextHuffmanString " << encoded_size
+ << " > " << buffer_.size();
return false;
}
@@ -133,11 +140,13 @@ bool HpackInputStream::DecodeNextHuffmanString(const HpackHuffmanTable& table,
StringPiece(buffer_.data(), encoded_size));
buffer_.remove_prefix(encoded_size);
- // HpackHuffmanTable will not decode beyond |max_string_literal_size_|.
- return table.DecodeString(&bounded_reader, max_string_literal_size_, str);
+ // DecodeString will not append more than |max_string_literal_size_| chars
+ // to |str|.
+ return HpackHuffmanDecoder::DecodeString(&bounded_reader,
+ max_string_literal_size_, str);
}
-bool HpackInputStream::PeekBits(size_t* peeked_count, uint32* out) {
+bool HpackInputStream::PeekBits(size_t* peeked_count, uint32_t* out) const {
size_t byte_offset = (bit_offset_ + *peeked_count) / 8;
size_t bit_offset = (bit_offset_ + *peeked_count) % 8;
@@ -148,7 +157,7 @@ bool HpackInputStream::PeekBits(size_t* peeked_count, uint32* out) {
// and the remaining unfilled bits of |out|.
size_t bits_to_read = std::min(32 - *peeked_count, 8 - bit_offset);
- uint32 new_bits = static_cast<uint32>(buffer_[byte_offset]);
+ uint32_t new_bits = static_cast<uint32_t>(buffer_[byte_offset]);
// Shift byte remainder to most-signifcant bits of |new_bits|.
// This drops the leading |bit_offset| bits of the byte.
new_bits = new_bits << (24 + bit_offset);
@@ -162,6 +171,41 @@ bool HpackInputStream::PeekBits(size_t* peeked_count, uint32* out) {
return true;
}
+std::pair<size_t, uint32_t> HpackInputStream::InitializePeekBits() {
+ size_t peeked_count = 0;
+ uint32_t bits = 0;
+ if (bit_offset_ == 0) {
+ switch (buffer_.size()) {
+ default:
+ DCHECK_LE(4u, buffer_.size());
+ bits = static_cast<uint32_t>(static_cast<unsigned char>(buffer_[3]));
+ peeked_count += 8;
+ /* FALLTHROUGH */
+ case 3:
+ bits |= (static_cast<uint32_t>(static_cast<unsigned char>(buffer_[2]))
+ << 8);
+ peeked_count += 8;
+ /* FALLTHROUGH */
+ case 2:
+ bits |= (static_cast<uint32_t>(static_cast<unsigned char>(buffer_[1]))
+ << 16);
+ peeked_count += 8;
+ /* FALLTHROUGH */
+ case 1:
+ bits |= (static_cast<uint32_t>(static_cast<unsigned char>(buffer_[0]))
+ << 24);
+ peeked_count += 8;
+ break;
+ case 0:
+ break;
+ }
+ } else {
+ LOG(DFATAL) << "InitializePeekBits called with non-zero bit_offset_: "
+ << bit_offset_;
+ }
+ return std::make_pair(peeked_count, bits);
+}
+
void HpackInputStream::ConsumeBits(size_t bit_count) {
size_t byte_count = (bit_offset_ + bit_count) / 8;
bit_offset_ = (bit_offset_ + bit_count) % 8;
diff --git a/chromium/net/spdy/hpack/hpack_input_stream.h b/chromium/net/spdy/hpack/hpack_input_stream.h
index c64022319a6..ab716d0eff4 100644
--- a/chromium/net/spdy/hpack/hpack_input_stream.h
+++ b/chromium/net/spdy/hpack/hpack_input_stream.h
@@ -5,9 +5,12 @@
#ifndef NET_SPDY_HPACK_INPUT_STREAM_H_
#define NET_SPDY_HPACK_INPUT_STREAM_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
+#include <utility>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -19,13 +22,15 @@
namespace net {
+typedef std::pair<size_t, uint32_t> InitialPeekResult;
+
// An HpackInputStream handles all the low-level details of decoding
// header fields.
class NET_EXPORT_PRIVATE HpackInputStream {
public:
// |max_string_literal_size| is the largest that any one string
// literal (header name or header value) can be.
- HpackInputStream(uint32 max_string_literal_size, base::StringPiece buffer);
+ HpackInputStream(uint32_t max_string_literal_size, base::StringPiece buffer);
~HpackInputStream();
// Returns whether or not there is more data to process.
@@ -38,17 +43,27 @@ class NET_EXPORT_PRIVATE HpackInputStream {
// The Decode* functions return true and fill in their arguments if
// decoding was successful, or false if an error was encountered.
- bool DecodeNextUint32(uint32* I);
+ bool DecodeNextUint32(uint32_t* I);
bool DecodeNextIdentityString(base::StringPiece* str);
- bool DecodeNextHuffmanString(const HpackHuffmanTable& table,
- std::string* str);
+ bool DecodeNextHuffmanString(std::string* str);
// Stores input bits into the most-significant, unfilled bits of |out|.
// |peeked_count| is the number of filled bits in |out| which have been
// previously peeked. PeekBits() will fill some number of remaining bits,
// returning the new total number via |peeked_count|. Returns true if one
- // or more additional bits could be peeked, and false otherwise.
- bool PeekBits(size_t* peeked_count, uint32* out);
+ // or more additional bits were added to |out|, and false otherwise.
+ bool PeekBits(size_t* peeked_count, uint32_t* out) const;
+
+ // Similar to PeekBits, but intended to be used when starting to decode a
+ // Huffman encoded string. Returns a pair containing the peeked_count and
+ // out values as described for PeekBits, with the bits from the first N bytes
+ // of buffer_, where N == min(4, buffer_.size()), starting with the high
+ // order bits.
+ // Should only be called when first peeking at bits from the input stream as
+ // it does not take peeked_count as an input, so doesn't know how many bits
+ // have already been returned by previous calls to InitializePeekBits and
+ // PeekBits.
+ InitialPeekResult InitializePeekBits();
// Consumes |count| bits of input. Generally paired with PeekBits().
void ConsumeBits(size_t count);
@@ -62,13 +77,13 @@ class NET_EXPORT_PRIVATE HpackInputStream {
void SetBitOffsetForTest(size_t bit_offset) { bit_offset_ = bit_offset; }
private:
- const uint32 max_string_literal_size_;
+ const uint32_t max_string_literal_size_;
base::StringPiece buffer_;
size_t bit_offset_;
- bool PeekNextOctet(uint8* next_octet);
+ bool PeekNextOctet(uint8_t* next_octet);
- bool DecodeNextOctet(uint8* next_octet);
+ bool DecodeNextOctet(uint8_t* next_octet);
DISALLOW_COPY_AND_ASSIGN(HpackInputStream);
};
diff --git a/chromium/net/spdy/hpack/hpack_input_stream_test.cc b/chromium/net/spdy/hpack/hpack_input_stream_test.cc
index 3468516aded..1b68754080e 100644
--- a/chromium/net/spdy/hpack/hpack_input_stream_test.cc
+++ b/chromium/net/spdy/hpack/hpack_input_stream_test.cc
@@ -12,6 +12,7 @@
#include "base/strings/string_piece.h"
#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/spdy_test_utils.h"
+#include "net/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -24,17 +25,6 @@ using test::a2b_hex;
const size_t kLiteralBound = 1024;
-class HpackInputStreamTest : public ::testing::Test {
- public:
- void SetUp() override {
- std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
- EXPECT_TRUE(huffman_table_.Initialize(&code[0], code.size()));
- }
-
- protected:
- HpackHuffmanTable huffman_table_;
-};
-
// Hex representation of encoded length and Huffman string.
const char kEncodedHuffmanFixture[] =
"2d" // Length prefix.
@@ -45,30 +35,30 @@ const char kEncodedHuffmanFixture[] =
const char kDecodedHuffmanFixture[] =
"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1";
-// Utility function to decode an assumed-valid uint32 with an N-bit
+// Utility function to decode an assumed-valid uint32_t with an N-bit
// prefix.
-uint32 DecodeValidUint32(uint8 N, StringPiece str) {
+uint32_t DecodeValidUint32(uint8_t N, StringPiece str) {
EXPECT_GT(N, 0);
EXPECT_LE(N, 8);
HpackInputStream input_stream(kLiteralBound, str);
input_stream.SetBitOffsetForTest(8 - N);
- uint32 I;
+ uint32_t I;
EXPECT_TRUE(input_stream.DecodeNextUint32(&I));
return I;
}
-// Utility function to decode an assumed-invalid uint32 with an N-bit
+// Utility function to decode an assumed-invalid uint32_t with an N-bit
// prefix.
-void ExpectDecodeUint32Invalid(uint8 N, StringPiece str) {
+void ExpectDecodeUint32Invalid(uint8_t N, StringPiece str) {
EXPECT_GT(N, 0);
EXPECT_LE(N, 8);
HpackInputStream input_stream(kLiteralBound, str);
input_stream.SetBitOffsetForTest(8 - N);
- uint32 I;
+ uint32_t I;
EXPECT_FALSE(input_stream.DecodeNextUint32(&I));
}
-uint32 bits32(const string& bitstring) {
+uint32_t bits32(const string& bitstring) {
return std::bitset<32>(bitstring).to_ulong();
}
@@ -76,7 +66,7 @@ uint32 bits32(const string& bitstring) {
// certain integers are decoded correctly with an 8-bit prefix in
// exactly {Number} bytes.
-TEST_F(HpackInputStreamTest, OneByteIntegersEightBitPrefix) {
+TEST(HpackInputStreamTest, OneByteIntegersEightBitPrefix) {
// Minimum.
EXPECT_EQ(0x00u, DecodeValidUint32(8, string("\x00", 1)));
EXPECT_EQ(0x7fu, DecodeValidUint32(8, "\x7f"));
@@ -86,7 +76,7 @@ TEST_F(HpackInputStreamTest, OneByteIntegersEightBitPrefix) {
ExpectDecodeUint32Invalid(8, "\xff");
}
-TEST_F(HpackInputStreamTest, TwoByteIntegersEightBitPrefix) {
+TEST(HpackInputStreamTest, TwoByteIntegersEightBitPrefix) {
// Minimum.
EXPECT_EQ(0xffu, DecodeValidUint32(8, string("\xff\x00", 2)));
EXPECT_EQ(0x0100u, DecodeValidUint32(8, "\xff\x01"));
@@ -97,7 +87,7 @@ TEST_F(HpackInputStreamTest, TwoByteIntegersEightBitPrefix) {
ExpectDecodeUint32Invalid(8, "\xff\xff");
}
-TEST_F(HpackInputStreamTest, ThreeByteIntegersEightBitPrefix) {
+TEST(HpackInputStreamTest, ThreeByteIntegersEightBitPrefix) {
// Minimum.
EXPECT_EQ(0x017fu, DecodeValidUint32(8, "\xff\x80\x01"));
EXPECT_EQ(0x0fffu, DecodeValidUint32(8, "\xff\x80\x1e"));
@@ -110,7 +100,7 @@ TEST_F(HpackInputStreamTest, ThreeByteIntegersEightBitPrefix) {
ExpectDecodeUint32Invalid(8, "\xff\xff\xff");
}
-TEST_F(HpackInputStreamTest, FourByteIntegersEightBitPrefix) {
+TEST(HpackInputStreamTest, FourByteIntegersEightBitPrefix) {
// Minimum.
EXPECT_EQ(0x40ffu, DecodeValidUint32(8, "\xff\x80\x80\x01"));
EXPECT_EQ(0xffffu, DecodeValidUint32(8, "\xff\x80\xfe\x03"));
@@ -123,7 +113,7 @@ TEST_F(HpackInputStreamTest, FourByteIntegersEightBitPrefix) {
ExpectDecodeUint32Invalid(8, "\xff\xff\xff\xff");
}
-TEST_F(HpackInputStreamTest, FiveByteIntegersEightBitPrefix) {
+TEST(HpackInputStreamTest, FiveByteIntegersEightBitPrefix) {
// Minimum.
EXPECT_EQ(0x002000ffu, DecodeValidUint32(8, "\xff\x80\x80\x80\x01"));
EXPECT_EQ(0x00ffffffu, DecodeValidUint32(8, "\xff\x80\xfe\xff\x07"));
@@ -136,7 +126,7 @@ TEST_F(HpackInputStreamTest, FiveByteIntegersEightBitPrefix) {
ExpectDecodeUint32Invalid(8, "\xff\xff\xff\xff\xff");
}
-TEST_F(HpackInputStreamTest, SixByteIntegersEightBitPrefix) {
+TEST(HpackInputStreamTest, SixByteIntegersEightBitPrefix) {
// Minimum.
EXPECT_EQ(0x100000ffu, DecodeValidUint32(8, "\xff\x80\x80\x80\x80\x01"));
// Maximum.
@@ -147,9 +137,9 @@ TEST_F(HpackInputStreamTest, SixByteIntegersEightBitPrefix) {
ExpectDecodeUint32Invalid(8, "\xff\xff\xff\xff\xff\xff");
}
-// There are no valid uint32 encodings that are greater than six
+// There are no valid uint32_t encodings that are greater than six
// bytes.
-TEST_F(HpackInputStreamTest, SevenByteIntegersEightBitPrefix) {
+TEST(HpackInputStreamTest, SevenByteIntegersEightBitPrefix) {
ExpectDecodeUint32Invalid(8, "\xff\x80\x80\x80\x80\x80\x00");
ExpectDecodeUint32Invalid(8, "\xff\x80\x80\x80\x80\x80\x01");
ExpectDecodeUint32Invalid(8, "\xff\xff\xff\xff\xff\xff\xff");
@@ -159,7 +149,7 @@ TEST_F(HpackInputStreamTest, SevenByteIntegersEightBitPrefix) {
// certain integers are encoded correctly with an N-bit prefix in
// exactly {Number} bytes for N in {1, 2, ..., 7}.
-TEST_F(HpackInputStreamTest, OneByteIntegersOneToSevenBitPrefixes) {
+TEST(HpackInputStreamTest, OneByteIntegersOneToSevenBitPrefixes) {
// Minimums.
EXPECT_EQ(0x00u, DecodeValidUint32(7, string("\x00", 1)));
EXPECT_EQ(0x00u, DecodeValidUint32(7, "\x80"));
@@ -209,7 +199,7 @@ TEST_F(HpackInputStreamTest, OneByteIntegersOneToSevenBitPrefixes) {
ExpectDecodeUint32Invalid(1, "\xff");
}
-TEST_F(HpackInputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) {
+TEST(HpackInputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) {
// Minimums.
EXPECT_EQ(0x7fu, DecodeValidUint32(7, string("\x7f\x00", 2)));
EXPECT_EQ(0x7fu, DecodeValidUint32(7, string("\xff\x00", 2)));
@@ -259,7 +249,7 @@ TEST_F(HpackInputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) {
ExpectDecodeUint32Invalid(1, "\xff\xff");
}
-TEST_F(HpackInputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) {
+TEST(HpackInputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) {
// Minimums.
EXPECT_EQ(0xffu, DecodeValidUint32(7, "\x7f\x80\x01"));
EXPECT_EQ(0xffu, DecodeValidUint32(7, "\xff\x80\x01"));
@@ -309,7 +299,7 @@ TEST_F(HpackInputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) {
ExpectDecodeUint32Invalid(1, "\xff\xff\xff");
}
-TEST_F(HpackInputStreamTest, FourByteIntegersOneToSevenBitPrefixes) {
+TEST(HpackInputStreamTest, FourByteIntegersOneToSevenBitPrefixes) {
// Minimums.
EXPECT_EQ(0x407fu, DecodeValidUint32(7, "\x7f\x80\x80\x01"));
EXPECT_EQ(0x407fu, DecodeValidUint32(7, "\xff\x80\x80\x01"));
@@ -359,7 +349,7 @@ TEST_F(HpackInputStreamTest, FourByteIntegersOneToSevenBitPrefixes) {
ExpectDecodeUint32Invalid(1, "\xff\xff\xff\xff");
}
-TEST_F(HpackInputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) {
+TEST(HpackInputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) {
// Minimums.
EXPECT_EQ(0x20007fu, DecodeValidUint32(7, "\x7f\x80\x80\x80\x01"));
EXPECT_EQ(0x20007fu, DecodeValidUint32(7, "\xff\x80\x80\x80\x01"));
@@ -409,7 +399,7 @@ TEST_F(HpackInputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) {
ExpectDecodeUint32Invalid(1, "\xff\xff\xff\xff\xff");
}
-TEST_F(HpackInputStreamTest, SixByteIntegersOneToSevenBitPrefixes) {
+TEST(HpackInputStreamTest, SixByteIntegersOneToSevenBitPrefixes) {
// Minimums.
EXPECT_EQ(0x1000007fu, DecodeValidUint32(7, "\x7f\x80\x80\x80\x80\x01"));
EXPECT_EQ(0x1000007fu, DecodeValidUint32(7, "\xff\x80\x80\x80\x80\x01"));
@@ -459,9 +449,9 @@ TEST_F(HpackInputStreamTest, SixByteIntegersOneToSevenBitPrefixes) {
ExpectDecodeUint32Invalid(1, "\xff\xfe\xff\xff\xff\xff");
}
-// There are no valid uint32 encodings that are greater than six
+// There are no valid uint32_t encodings that are greater than six
// bytes.
-TEST_F(HpackInputStreamTest, SevenByteIntegersOneToSevenBitPrefixes) {
+TEST(HpackInputStreamTest, SevenByteIntegersOneToSevenBitPrefixes) {
ExpectDecodeUint32Invalid(7, "\x7f\x80\x80\x80\x80\x80\x00");
ExpectDecodeUint32Invalid(7, "\x7f\x80\x80\x80\x80\x80\x01");
ExpectDecodeUint32Invalid(7, "\xff\xff\xff\xff\xff\xff\xff");
@@ -486,7 +476,7 @@ TEST_F(HpackInputStreamTest, SevenByteIntegersOneToSevenBitPrefixes) {
}
// Decoding a valid encoded string literal should work.
-TEST_F(HpackInputStreamTest, DecodeNextIdentityString) {
+TEST(HpackInputStreamTest, DecodeNextIdentityString) {
HpackInputStream input_stream(kLiteralBound, "\x0estring literal");
EXPECT_TRUE(input_stream.HasMoreData());
@@ -498,7 +488,7 @@ TEST_F(HpackInputStreamTest, DecodeNextIdentityString) {
// Decoding an encoded string literal with size larger than
// |max_string_literal_size_| should fail.
-TEST_F(HpackInputStreamTest, DecodeNextIdentityStringSizeLimit) {
+TEST(HpackInputStreamTest, DecodeNextIdentityStringSizeLimit) {
HpackInputStream input_stream(13, "\x0estring literal");
EXPECT_TRUE(input_stream.HasMoreData());
@@ -508,7 +498,7 @@ TEST_F(HpackInputStreamTest, DecodeNextIdentityStringSizeLimit) {
// Decoding an encoded string literal with size larger than the
// remainder of the buffer should fail.
-TEST_F(HpackInputStreamTest, DecodeNextIdentityStringNotEnoughInput) {
+TEST(HpackInputStreamTest, DecodeNextIdentityStringNotEnoughInput) {
// Set the length to be one more than it should be.
HpackInputStream input_stream(kLiteralBound, "\x0fstring literal");
@@ -517,40 +507,40 @@ TEST_F(HpackInputStreamTest, DecodeNextIdentityStringNotEnoughInput) {
EXPECT_FALSE(input_stream.DecodeNextIdentityString(&string_piece));
}
-TEST_F(HpackInputStreamTest, DecodeNextHuffmanString) {
+TEST(HpackInputStreamTest, DecodeNextHuffmanString) {
string output, input(a2b_hex(kEncodedHuffmanFixture));
HpackInputStream input_stream(arraysize(kDecodedHuffmanFixture) - 1, input);
EXPECT_TRUE(input_stream.HasMoreData());
- EXPECT_TRUE(input_stream.DecodeNextHuffmanString(huffman_table_, &output));
+ EXPECT_TRUE(input_stream.DecodeNextHuffmanString(&output));
EXPECT_EQ(kDecodedHuffmanFixture, output);
EXPECT_FALSE(input_stream.HasMoreData());
}
-TEST_F(HpackInputStreamTest, DecodeNextHuffmanStringSizeLimit) {
+TEST(HpackInputStreamTest, DecodeNextHuffmanStringSizeLimit) {
string output, input(a2b_hex(kEncodedHuffmanFixture));
// Max string literal is one byte shorter than the decoded fixture.
HpackInputStream input_stream(arraysize(kDecodedHuffmanFixture) - 2, input);
// Decoded string overflows the max string literal.
EXPECT_TRUE(input_stream.HasMoreData());
- EXPECT_FALSE(input_stream.DecodeNextHuffmanString(huffman_table_, &output));
+ EXPECT_FALSE(input_stream.DecodeNextHuffmanString(&output));
}
-TEST_F(HpackInputStreamTest, DecodeNextHuffmanStringNotEnoughInput) {
+TEST(HpackInputStreamTest, DecodeNextHuffmanStringNotEnoughInput) {
string output, input(a2b_hex(kEncodedHuffmanFixture));
input[0]++; // Input prefix is one byte larger than available input.
HpackInputStream input_stream(arraysize(kDecodedHuffmanFixture) - 1, input);
// Not enough buffer for declared encoded length.
EXPECT_TRUE(input_stream.HasMoreData());
- EXPECT_FALSE(input_stream.DecodeNextHuffmanString(huffman_table_, &output));
+ EXPECT_FALSE(input_stream.DecodeNextHuffmanString(&output));
}
-TEST_F(HpackInputStreamTest, PeekBitsAndConsume) {
+TEST(HpackInputStreamTest, PeekBitsAndConsume) {
HpackInputStream input_stream(kLiteralBound, "\xad\xab\xad\xab\xad");
- uint32 bits = 0;
+ uint32_t bits = 0;
size_t peeked_count = 0;
// Read 0xad.
@@ -609,7 +599,97 @@ TEST_F(HpackInputStreamTest, PeekBitsAndConsume) {
EXPECT_FALSE(input_stream.HasMoreData());
}
-TEST_F(HpackInputStreamTest, ConsumeByteRemainder) {
+TEST(HpackInputStreamTest, InitializePeekBits) {
+ {
+ // Empty input, peeked_count == 0 and bits == 0.
+ HpackInputStream input_stream(kLiteralBound, "");
+ auto peeked_count_and_bits = input_stream.InitializePeekBits();
+ size_t peeked_count = peeked_count_and_bits.first;
+ uint32_t bits = peeked_count_and_bits.second;
+ EXPECT_EQ(0u, peeked_count);
+ EXPECT_EQ(0u, bits);
+ }
+ {
+ // One input byte, returns peeked_count == 8 and bits
+ // has the input byte in its high order bits.
+ HpackInputStream input_stream(kLiteralBound, "\xfe");
+ auto peeked_count_and_bits = input_stream.InitializePeekBits();
+ size_t peeked_count = peeked_count_and_bits.first;
+ uint32_t bits = peeked_count_and_bits.second;
+ EXPECT_EQ(8u, peeked_count);
+ EXPECT_EQ(0xfe000000, bits);
+ input_stream.ConsumeBits(8);
+ EXPECT_FALSE(input_stream.HasMoreData());
+ }
+ {
+ // Two input bytes, returns peeked_count == 16 and bits
+ // has the two input bytes in its high order bits.
+ HpackInputStream input_stream(kLiteralBound, "\xfe\xdc");
+ auto peeked_count_and_bits = input_stream.InitializePeekBits();
+ size_t peeked_count = peeked_count_and_bits.first;
+ uint32_t bits = peeked_count_and_bits.second;
+ EXPECT_EQ(16u, peeked_count);
+ EXPECT_EQ(0xfedc0000, bits);
+ input_stream.ConsumeBits(16);
+ EXPECT_FALSE(input_stream.HasMoreData());
+ }
+ {
+ // Three input bytes, returns peeked_count == 24 and bits
+ // has the three input bytes in its high order bits.
+ HpackInputStream input_stream(kLiteralBound, "\xab\xcd\xef");
+ auto peeked_count_and_bits = input_stream.InitializePeekBits();
+ size_t peeked_count = peeked_count_and_bits.first;
+ uint32_t bits = peeked_count_and_bits.second;
+ EXPECT_EQ(24u, peeked_count);
+ EXPECT_EQ(0xabcdef00, bits);
+ input_stream.ConsumeBits(24);
+ EXPECT_FALSE(input_stream.HasMoreData());
+ }
+ {
+ // Four input bytes, returns peeked_count == 32 and bits
+ // contains the four input bytes.
+ HpackInputStream input_stream(kLiteralBound, "\xfe\xed\xdc\xcb");
+ auto peeked_count_and_bits = input_stream.InitializePeekBits();
+ size_t peeked_count = peeked_count_and_bits.first;
+ uint32_t bits = peeked_count_and_bits.second;
+ EXPECT_EQ(32u, peeked_count);
+ EXPECT_EQ(0xfeeddccb, bits);
+ input_stream.ConsumeBits(32);
+ EXPECT_FALSE(input_stream.HasMoreData());
+ }
+ {
+ // Five input bytes, returns peeked_count == 32 and bits
+ // contains the first four input bytes.
+ HpackInputStream input_stream(kLiteralBound, "\xfe\xed\xdc\xcb\xba");
+ auto peeked_count_and_bits = input_stream.InitializePeekBits();
+ size_t peeked_count = peeked_count_and_bits.first;
+ uint32_t bits = peeked_count_and_bits.second;
+ EXPECT_EQ(32u, peeked_count);
+ EXPECT_EQ(0xfeeddccb, bits);
+ EXPECT_TRUE(input_stream.HasMoreData());
+
+ // If we consume some bits, then InitializePeekBits will return no bits.
+ input_stream.ConsumeBits(28);
+ peeked_count -= 28;
+ bits <<= 28;
+ EXPECT_EQ(0xb0000000, bits);
+
+ EXPECT_DFATAL(peeked_count_and_bits = input_stream.InitializePeekBits(),
+ "bit_offset_");
+ EXPECT_EQ(0u, peeked_count_and_bits.first);
+ EXPECT_EQ(0u, peeked_count_and_bits.second);
+ EXPECT_TRUE(input_stream.HasMoreData());
+
+ // Can PeekBits, which will get us the last byte's bits.
+ EXPECT_TRUE(input_stream.PeekBits(&peeked_count, &bits));
+ EXPECT_EQ(12u, peeked_count);
+ EXPECT_EQ(0xbba00000, bits);
+ input_stream.ConsumeBits(12);
+ EXPECT_FALSE(input_stream.HasMoreData());
+ }
+}
+
+TEST(HpackInputStreamTest, ConsumeByteRemainder) {
HpackInputStream input_stream(kLiteralBound, "\xad\xab");
// Does nothing.
input_stream.ConsumeByteRemainder();
diff --git a/chromium/net/spdy/hpack/hpack_output_stream.cc b/chromium/net/spdy/hpack/hpack_output_stream.cc
index d2342b19483..18aa4e6fb00 100644
--- a/chromium/net/spdy/hpack/hpack_output_stream.cc
+++ b/chromium/net/spdy/hpack/hpack_output_stream.cc
@@ -15,7 +15,7 @@ HpackOutputStream::HpackOutputStream() : bit_offset_(0) {}
HpackOutputStream::~HpackOutputStream() {}
-void HpackOutputStream::AppendBits(uint8 bits, size_t bit_size) {
+void HpackOutputStream::AppendBits(uint8_t bits, size_t bit_size) {
DCHECK_GT(bit_size, 0u);
DCHECK_LE(bit_size, 8u);
DCHECK_EQ(bits >> bit_size, 0);
@@ -46,12 +46,12 @@ void HpackOutputStream::AppendBytes(StringPiece buffer) {
buffer_.append(buffer.data(), buffer.size());
}
-void HpackOutputStream::AppendUint32(uint32 I) {
+void HpackOutputStream::AppendUint32(uint32_t I) {
// The algorithm below is adapted from the pseudocode in 6.1.
size_t N = 8 - bit_offset_;
- uint8 max_first_byte = static_cast<uint8>((1 << N) - 1);
+ uint8_t max_first_byte = static_cast<uint8_t>((1 << N) - 1);
if (I < max_first_byte) {
- AppendBits(static_cast<uint8>(I), N);
+ AppendBits(static_cast<uint8_t>(I), N);
} else {
AppendBits(max_first_byte, N);
I -= max_first_byte;
@@ -59,7 +59,7 @@ void HpackOutputStream::AppendUint32(uint32 I) {
buffer_.append(1, (I & 0x7f) | 0x80);
I >>= 7;
}
- AppendBits(static_cast<uint8>(I), 8);
+ AppendBits(static_cast<uint8_t>(I), 8);
}
}
diff --git a/chromium/net/spdy/hpack/hpack_output_stream.h b/chromium/net/spdy/hpack/hpack_output_stream.h
index 5063900a5ae..0c5a013a950 100644
--- a/chromium/net/spdy/hpack/hpack_output_stream.h
+++ b/chromium/net/spdy/hpack/hpack_output_stream.h
@@ -5,10 +5,12 @@
#ifndef NET_SPDY_HPACK_OUTPUT_STREAM_H_
#define NET_SPDY_HPACK_OUTPUT_STREAM_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -30,7 +32,7 @@ class NET_EXPORT_PRIVATE HpackOutputStream {
//
// |bit_size| must be > 0 and <= 8. |bits| must not have any bits
// set other than the lower |bit_size| bits.
- void AppendBits(uint8 bits, size_t bit_size);
+ void AppendBits(uint8_t bits, size_t bit_size);
// Simply forwards to AppendBits(prefix.bits, prefix.bit-size).
void AppendPrefix(HpackPrefix prefix);
@@ -45,7 +47,7 @@ class NET_EXPORT_PRIVATE HpackOutputStream {
//
// It is guaranteed that the internal buffer will end on a byte
// boundary after this function is called.
- void AppendUint32(uint32 I);
+ void AppendUint32(uint32_t I);
// Swaps the interal buffer with |output|.
void TakeString(std::string* output);
diff --git a/chromium/net/spdy/hpack/hpack_output_stream_test.cc b/chromium/net/spdy/hpack/hpack_output_stream_test.cc
index 48b5dcc0593..939dd9d8d03 100644
--- a/chromium/net/spdy/hpack/hpack_output_stream_test.cc
+++ b/chromium/net/spdy/hpack/hpack_output_stream_test.cc
@@ -6,7 +6,6 @@
#include <cstddef>
-#include "base/basictypes.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -47,7 +46,7 @@ TEST(HpackOutputStreamTest, AppendBits) {
// Utility function to return I as a string encoded with an N-bit
// prefix.
-string EncodeUint32(uint8 N, uint32 I) {
+string EncodeUint32(uint8_t N, uint32_t I) {
HpackOutputStream output_stream;
if (N < 8) {
output_stream.AppendBits(0x00, 8 - N);
diff --git a/chromium/net/spdy/hpack/hpack_round_trip_test.cc b/chromium/net/spdy/hpack/hpack_round_trip_test.cc
index bc703674c1d..07ab6990c9d 100644
--- a/chromium/net/spdy/hpack/hpack_round_trip_test.cc
+++ b/chromium/net/spdy/hpack/hpack_round_trip_test.cc
@@ -26,9 +26,7 @@ namespace {
class HpackRoundTripTest : public ::testing::Test {
protected:
- HpackRoundTripTest()
- : encoder_(ObtainHpackHuffmanTable()),
- decoder_(ObtainHpackHuffmanTable()) {}
+ HpackRoundTripTest() : encoder_(ObtainHpackHuffmanTable()), decoder_() {}
void SetUp() override {
// Use a small table size to tickle eviction handling.
@@ -40,11 +38,11 @@ class HpackRoundTripTest : public ::testing::Test {
string encoded;
encoder_.EncodeHeaderSet(header_set, &encoded);
- bool success = decoder_.HandleControlFrameHeadersData(1, encoded.data(),
- encoded.size());
- success &= decoder_.HandleControlFrameHeadersComplete(1, nullptr);
+ bool success =
+ decoder_.HandleControlFrameHeadersData(encoded.data(), encoded.size());
+ success &= decoder_.HandleControlFrameHeadersComplete(nullptr);
- EXPECT_TRUE(CompareSpdyHeaderBlocks(header_set, decoder_.decoded_block()));
+ EXPECT_EQ(header_set, decoder_.decoded_block());
return success;
}
diff --git a/chromium/net/spdy/hpack/hpack_static_table.cc b/chromium/net/spdy/hpack/hpack_static_table.cc
index 8ee1d0bdd9c..b954c3482d7 100644
--- a/chromium/net/spdy/hpack/hpack_static_table.cc
+++ b/chromium/net/spdy/hpack/hpack_static_table.cc
@@ -21,10 +21,11 @@ void HpackStaticTable::Initialize(const HpackStaticEntry* static_entry_table,
int total_insertions = 0;
for (const HpackStaticEntry* it = static_entry_table;
it != static_entry_table + static_entry_count; ++it) {
- static_entries_.push_back(HpackEntry(StringPiece(it->name, it->name_len),
- StringPiece(it->value, it->value_len),
- true, // is_static
- total_insertions));
+ static_entries_.push_back(
+ HpackEntry(base::StringPiece(it->name, it->name_len),
+ base::StringPiece(it->value, it->value_len),
+ true, // is_static
+ total_insertions));
CHECK(static_index_.insert(&static_entries_.back()).second);
++total_insertions;
diff --git a/chromium/net/spdy/hpack/hpack_static_table.h b/chromium/net/spdy/hpack/hpack_static_table.h
index e7e0fd4a554..e7616b33843 100644
--- a/chromium/net/spdy/hpack/hpack_static_table.h
+++ b/chromium/net/spdy/hpack/hpack_static_table.h
@@ -5,6 +5,8 @@
#ifndef NET_SPDY_HPACK_STATIC_TABLE_H_
#define NET_SPDY_HPACK_STATIC_TABLE_H_
+#include <stddef.h>
+
#include "net/spdy/hpack/hpack_header_table.h"
namespace net {
diff --git a/chromium/net/spdy/mock_spdy_framer_visitor.h b/chromium/net/spdy/mock_spdy_framer_visitor.h
index 83eacc5edab..85bf5ba068c 100644
--- a/chromium/net/spdy/mock_spdy_framer_visitor.h
+++ b/chromium/net/spdy/mock_spdy_framer_visitor.h
@@ -5,6 +5,9 @@
#ifndef NET_SPDY_MOCK_SPDY_FRAMER_VISITOR_H_
#define NET_SPDY_MOCK_SPDY_FRAMER_VISITOR_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/strings/string_piece.h"
#include "net/spdy/spdy_framer.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -26,6 +29,9 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface {
size_t len,
bool fin));
MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId stream_id, size_t len));
+ MOCK_METHOD1(OnHeaderFrameStart,
+ SpdyHeadersHandlerInterface*(SpdyStreamId stream_id));
+ MOCK_METHOD2(OnHeaderFrameEnd, void(SpdyStreamId stream_id, bool end));
MOCK_METHOD3(OnControlFrameHeaderData, bool(SpdyStreamId stream_id,
const char* header_data,
size_t len));
@@ -38,7 +44,8 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface {
MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id,
SpdyRstStreamStatus status));
MOCK_METHOD1(OnSettings, void(bool clear_persisted));
- MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
+ MOCK_METHOD3(OnSetting,
+ void(SpdySettingsIds id, uint8_t flags, uint32_t value));
MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
MOCK_METHOD0(OnSettingsEnd, void());
MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
@@ -66,7 +73,7 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface {
MOCK_METHOD4(OnPriority,
void(SpdyStreamId stream_id,
SpdyStreamId parent_stream_id,
- uint8 weight,
+ uint8_t weight,
bool exclusive));
MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type));
};
diff --git a/chromium/net/spdy/priority_write_scheduler.h b/chromium/net/spdy/priority_write_scheduler.h
new file mode 100644
index 00000000000..dd16b41cb8c
--- /dev/null
+++ b/chromium/net/spdy/priority_write_scheduler.h
@@ -0,0 +1,261 @@
+// Copyright (c) 2015 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_SPDY_PRIORITY_WRITE_SCHEDULER_H_
+#define NET_SPDY_PRIORITY_WRITE_SCHEDULER_H_
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <deque>
+#include <unordered_map>
+#include <utility>
+
+#include "base/logging.h"
+#include "net/spdy/spdy_protocol.h"
+
+namespace net {
+
+// Class that manages the order in which streams are written using the SPDY
+// priority scheme described at:
+// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
+//
+// Callers must first register a stream with the PriorityWriteScheduler (by
+// calling RegisterStream(), which informs the PriorityWriteScheduler of the
+// stream's priority) before calling other methods referencing that stream,
+// which may implicitly use the stream's priority. When the stream is
+// eventually closed, the caller should unregister it from the
+// PriorityWriteScheduler (by calling UnregisterStream()), to free data
+// structures associated with it.
+//
+// Each stream can be in one of two states: ready or not ready (for writing).
+// Ready state is changed by calling the MarkStreamReady() and
+// MarkStreamNotReady() methods. Only streams in the ready state can be
+// returned by PopNextReadyStream(); when returned by that method, the stream's
+// state changes to not ready.
+//
+// Internally, PriorityWriteScheduler consists of 8 per-priority sublists, one
+// for each priority value. The elements (if any) of each sublist are streams
+// that are ready to write and have that priority.
+template <typename StreamIdType>
+class PriorityWriteScheduler {
+ public:
+ // Creates scheduler with no streams.
+ PriorityWriteScheduler() = default;
+
+ // Registers the given stream with the scheduler, which will now track its
+ // priority and ready state. If the stream was already registered, logs
+ // DFATAL and does nothing.
+ void RegisterStream(StreamIdType stream_id, SpdyPriority priority) {
+ priority = ClampPriority(priority);
+ StreamInfo stream_info = {priority, false};
+ bool inserted =
+ stream_infos_.insert(std::make_pair(stream_id, stream_info)).second;
+ if (!inserted) {
+ LOG(DFATAL) << "Stream " << stream_id << " already registered";
+ }
+ }
+
+ // Unregisters the given stream from the scheduler, which will no
+ // longer keep track of its priority and ready state. If the stream
+ // was not previously registered, logs DFATAL and does nothing.
+ void UnregisterStream(StreamIdType stream_id) {
+ auto it = stream_infos_.find(stream_id);
+ if (it == stream_infos_.end()) {
+ LOG(DFATAL) << "Stream " << stream_id << " not registered";
+ return;
+ }
+ StreamInfo& stream_info = it->second;
+ if (stream_info.ready) {
+ bool erased = Erase(&ready_lists_[stream_info.priority], stream_id);
+ DCHECK(erased);
+ }
+ stream_infos_.erase(it);
+ }
+
+ // Returns the priority value for the specified stream. If the stream is not
+ // registered, logs DFATAL and returns the lowest priority.
+ SpdyPriority GetStreamPriority(StreamIdType stream_id) const {
+ auto it = stream_infos_.find(stream_id);
+ if (it == stream_infos_.end()) {
+ LOG(DFATAL) << "Stream " << stream_id << " not registered";
+ return kV3LowestPriority;
+ }
+ return it->second.priority;
+ }
+
+ // Updates the priority of the given stream. If the stream is not registered,
+ // logs DFATAL and does nothing.
+ void UpdateStreamPriority(StreamIdType stream_id, SpdyPriority priority) {
+ auto it = stream_infos_.find(stream_id);
+ if (it == stream_infos_.end()) {
+ LOG(DFATAL) << "Stream " << stream_id << " not registered";
+ return;
+ }
+ StreamInfo& stream_info = it->second;
+ if (stream_info.priority == priority) {
+ return;
+ }
+ if (stream_info.ready) {
+ bool erased = Erase(&ready_lists_[stream_info.priority], stream_id);
+ DCHECK(erased);
+ ready_lists_[priority].push_back(stream_id);
+ }
+ stream_info.priority = priority;
+ }
+
+ // If the scheduler has any ready streams, pops the next stream ID from the
+ // highest priority non-empty ready list and returns it, transitioning the
+ // stream from ready to not ready. If the scheduler doesn't have any ready
+ // streams, logs DFATAL and returns 0.
+ StreamIdType PopNextReadyStream() {
+ StreamIdType stream_id = 0;
+ for (SpdyPriority p = kV3HighestPriority; p <= kV3LowestPriority; ++p) {
+ StreamIdList& ready_list = ready_lists_[p];
+ if (!ready_list.empty()) {
+ stream_id = ready_list.front();
+ ready_list.pop_front();
+
+ auto it = stream_infos_.find(stream_id);
+ if (it == stream_infos_.end()) {
+ LOG(DFATAL) << "Missing StreamInfo for stream " << stream_id;
+ } else {
+ it->second.ready = false;
+ }
+ return stream_id;
+ }
+ }
+ LOG(DFATAL) << "No ready streams available";
+ return stream_id;
+ }
+
+ // Returns true if the scheduler has any ready streams with a higher priority
+ // than that of the specified stream. If the stream is not registered, logs
+ // DFATAL and returns false.
+ bool HasHigherPriorityReadyStream(StreamIdType stream_id) {
+ auto it = stream_infos_.find(stream_id);
+ if (it == stream_infos_.end()) {
+ LOG(DFATAL) << "Stream " << stream_id << " not registered";
+ return false;
+ }
+ StreamInfo& stream_info = it->second;
+ for (SpdyPriority p = kV3HighestPriority; p < stream_info.priority; ++p) {
+ if (!ready_lists_[p].empty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Marks the given stream as ready to write. If stream was already ready,
+ // does nothing. If stream was not registered, logs DFATAL and does
+ // nothing. If |add_to_front| is true, adds stream to the front of its
+ // per-priority ready list, otherwise adds it to the back.
+ void MarkStreamReady(StreamIdType stream_id, bool add_to_front) {
+ auto it = stream_infos_.find(stream_id);
+ if (it == stream_infos_.end()) {
+ LOG(DFATAL) << "Stream " << stream_id << " not registered";
+ return;
+ }
+ StreamInfo& stream_info = it->second;
+ if (stream_info.ready) {
+ return;
+ }
+ StreamIdList& ready_list = ready_lists_[stream_info.priority];
+ if (add_to_front) {
+ ready_list.push_front(stream_id);
+ } else {
+ ready_list.push_back(stream_id);
+ }
+ stream_info.ready = true;
+ }
+
+ // Marks the given stream as not ready to write, removing it from the ready
+ // list for its priority. If stream was already not ready, does nothing. If
+ // stream was not registered, logs DFATAL and does nothing.
+ void MarkStreamNotReady(StreamIdType stream_id) {
+ auto it = stream_infos_.find(stream_id);
+ if (it == stream_infos_.end()) {
+ LOG(DFATAL) << "Stream " << stream_id << " not registered";
+ return;
+ }
+ StreamInfo& stream_info = it->second;
+ if (!stream_info.ready) {
+ return;
+ }
+ bool erased = Erase(&ready_lists_[stream_info.priority], stream_id);
+ DCHECK(erased);
+ stream_info.ready = false;
+ }
+
+ // Returns true iff the number of ready streams is non-zero.
+ bool HasReadyStreams() const {
+ for (SpdyPriority i = kV3HighestPriority; i <= kV3LowestPriority; ++i) {
+ if (!ready_lists_[i].empty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Returns the number of ready streams.
+ size_t NumReadyStreams() const {
+ size_t n = 0;
+ for (SpdyPriority i = kV3HighestPriority; i <= kV3LowestPriority; ++i) {
+ n += ready_lists_[i].size();
+ }
+ return n;
+ }
+
+ // Returns the number of ready streams with the given priority.
+ size_t NumReadyStreams(SpdyPriority priority) const {
+ priority = ClampPriority(priority);
+ return ready_lists_[priority].size();
+ }
+
+ private:
+ // 0(1) size lookup, 0(1) insert at front or back.
+ typedef std::deque<StreamIdType> StreamIdList;
+
+ // State kept for all registered streams. All ready streams have ready = true
+ // and should be present in ready_lists_[priority].
+ struct StreamInfo {
+ SpdyPriority priority;
+ bool ready;
+ };
+
+ typedef std::unordered_map<StreamIdType, StreamInfo> StreamInfoMap;
+
+ static SpdyPriority ClampPriority(SpdyPriority priority) {
+ if (priority < kV3HighestPriority) {
+ LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority);
+ return kV3HighestPriority;
+ }
+ if (priority > kV3LowestPriority) {
+ LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority);
+ return kV3LowestPriority;
+ }
+ return priority;
+ }
+
+ // Erases first occurrence (which should be the only one) of |stream_id| in
+ // |ready_list|, returning true if found (and erased), or false otherwise.
+ bool Erase(StreamIdList* ready_list, StreamIdType stream_id) {
+ auto it = std::find(ready_list->begin(), ready_list->end(), stream_id);
+ if (it == ready_list->end()) {
+ return false;
+ }
+ ready_list->erase(it);
+ return true;
+ }
+
+ // IDs of streams that are ready to write, grouped by priority.
+ StreamIdList ready_lists_[kV3LowestPriority + 1];
+ // StreamInfos for all registered streams.
+ StreamInfoMap stream_infos_;
+};
+
+} // namespace net
+
+#endif // NET_SPDY_PRIORITY_WRITE_SCHEDULER_H_
diff --git a/chromium/net/spdy/priority_write_scheduler_test.cc b/chromium/net/spdy/priority_write_scheduler_test.cc
new file mode 100644
index 00000000000..c503f5e243e
--- /dev/null
+++ b/chromium/net/spdy/priority_write_scheduler_test.cc
@@ -0,0 +1,262 @@
+// Copyright (c) 2015 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/spdy/priority_write_scheduler.h"
+
+#include "net/test/gtest_util.h"
+
+namespace net {
+namespace test {
+namespace {
+
+class PriorityWriteSchedulerTest : public ::testing::Test {
+ public:
+ PriorityWriteScheduler<int> scheduler_;
+};
+
+TEST_F(PriorityWriteSchedulerTest, RegisterUnregisterStreams) {
+ EXPECT_FALSE(scheduler_.HasReadyStreams());
+ scheduler_.RegisterStream(1, 1);
+
+ // Try redundant registrations.
+ EXPECT_DFATAL(scheduler_.RegisterStream(1, 1), "Stream 1 already registered");
+ EXPECT_DFATAL(scheduler_.RegisterStream(1, 2), "Stream 1 already registered");
+
+ scheduler_.RegisterStream(2, 3);
+
+ // Verify registration != ready.
+ EXPECT_FALSE(scheduler_.HasReadyStreams());
+
+ scheduler_.UnregisterStream(1);
+ scheduler_.UnregisterStream(2);
+
+ // Try redundant unregistration.
+ EXPECT_DFATAL(scheduler_.UnregisterStream(1), "Stream 1 not registered");
+ EXPECT_DFATAL(scheduler_.UnregisterStream(2), "Stream 2 not registered");
+}
+
+TEST_F(PriorityWriteSchedulerTest, GetStreamPriority) {
+ EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(1)),
+ "Stream 1 not registered");
+
+ scheduler_.RegisterStream(1, 3);
+ EXPECT_EQ(3, scheduler_.GetStreamPriority(1));
+
+ // Redundant registration shouldn't change stream priority.
+ EXPECT_DFATAL(scheduler_.RegisterStream(1, 4), "Stream 1 already registered");
+ EXPECT_EQ(3, scheduler_.GetStreamPriority(1));
+
+ scheduler_.UpdateStreamPriority(1, 5);
+ EXPECT_EQ(5, scheduler_.GetStreamPriority(1));
+
+ // Toggling ready state shouldn't change stream priority.
+ scheduler_.MarkStreamReady(1, true);
+ EXPECT_EQ(5, scheduler_.GetStreamPriority(1));
+
+ // Test changing priority of ready stream.
+ EXPECT_EQ(1u, scheduler_.NumReadyStreams(5));
+ scheduler_.UpdateStreamPriority(1, 6);
+ EXPECT_EQ(6, scheduler_.GetStreamPriority(1));
+ EXPECT_EQ(0u, scheduler_.NumReadyStreams(5));
+ EXPECT_EQ(1u, scheduler_.NumReadyStreams(6));
+
+ EXPECT_EQ(1, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(6, scheduler_.GetStreamPriority(1));
+
+ scheduler_.UnregisterStream(1);
+ EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(1)),
+ "Stream 1 not registered");
+}
+
+TEST_F(PriorityWriteSchedulerTest, UpdateStreamPriority) {
+ // Updating priority of unregistered stream should have no effect.
+ EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)),
+ "Stream 3 not registered");
+ EXPECT_DFATAL(scheduler_.UpdateStreamPriority(3, 1),
+ "Stream 3 not registered");
+ EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)),
+ "Stream 3 not registered");
+
+ scheduler_.RegisterStream(3, 1);
+ EXPECT_EQ(1, scheduler_.GetStreamPriority(3));
+ scheduler_.UpdateStreamPriority(3, 2);
+ EXPECT_EQ(2, scheduler_.GetStreamPriority(3));
+
+ // Updating priority of stream to current priority value is valid, but has no
+ // effect.
+ scheduler_.UpdateStreamPriority(3, 2);
+ EXPECT_EQ(2, scheduler_.GetStreamPriority(3));
+
+ // Even though stream 4 is marked ready after stream 5, it should be returned
+ // first by PopNextReadyStream() since it has higher priority.
+ scheduler_.RegisterStream(4, 1);
+ scheduler_.MarkStreamReady(3, false); // priority 2
+ scheduler_.MarkStreamReady(4, false); // priority 1
+ EXPECT_EQ(4, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(3, scheduler_.PopNextReadyStream());
+
+ // Verify that lowering priority of stream 4 causes it to be returned later
+ // by PopNextReadyStream().
+ scheduler_.MarkStreamReady(3, false); // priority 2
+ scheduler_.MarkStreamReady(4, false); // priority 1
+ scheduler_.UpdateStreamPriority(4, 3);
+ EXPECT_EQ(3, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(4, scheduler_.PopNextReadyStream());
+
+ scheduler_.UnregisterStream(3);
+ EXPECT_DFATAL(scheduler_.UpdateStreamPriority(3, 1),
+ "Stream 3 not registered");
+}
+
+TEST_F(PriorityWriteSchedulerTest, HasHigherPriorityReadyStream) {
+ EXPECT_DFATAL(EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1)),
+ "Stream 1 not registered");
+
+ // Add ready streams of lower and equal priority.
+ scheduler_.RegisterStream(1, 4);
+ EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1));
+ scheduler_.RegisterStream(2, 5);
+ scheduler_.MarkStreamReady(2, false);
+ EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1));
+ scheduler_.RegisterStream(3, 4);
+ scheduler_.MarkStreamReady(3, false);
+ EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1));
+
+ // Verify that registration of a stream with higher priority isn't
+ // sufficient--it needs to be marked ready.
+ scheduler_.RegisterStream(4, 3);
+ EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1));
+ scheduler_.MarkStreamReady(4, false);
+ EXPECT_TRUE(scheduler_.HasHigherPriorityReadyStream(1));
+
+ // Verify method is responsive to changes in priority.
+ scheduler_.UpdateStreamPriority(1, 2);
+ EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1));
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBack) {
+ EXPECT_FALSE(scheduler_.HasReadyStreams());
+ EXPECT_DFATAL(scheduler_.MarkStreamReady(1, false),
+ "Stream 1 not registered");
+ EXPECT_FALSE(scheduler_.HasReadyStreams());
+ EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()),
+ "No ready streams available");
+
+ // Add a bunch of ready streams to tail of per-priority lists.
+ // Expected order: (P2) 4, (P3) 1, 2, 3, (P5) 5.
+ scheduler_.RegisterStream(1, 3);
+ scheduler_.MarkStreamReady(1, false);
+ EXPECT_TRUE(scheduler_.HasReadyStreams());
+ scheduler_.RegisterStream(2, 3);
+ scheduler_.MarkStreamReady(2, false);
+ scheduler_.RegisterStream(3, 3);
+ scheduler_.MarkStreamReady(3, false);
+ scheduler_.RegisterStream(4, 2);
+ scheduler_.MarkStreamReady(4, false);
+ scheduler_.RegisterStream(5, 5);
+ scheduler_.MarkStreamReady(5, false);
+
+ EXPECT_EQ(4, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(1, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(2, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(3, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(5, scheduler_.PopNextReadyStream());
+ EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()),
+ "No ready streams available");
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyFront) {
+ EXPECT_FALSE(scheduler_.HasReadyStreams());
+ EXPECT_DFATAL(scheduler_.MarkStreamReady(1, true), "Stream 1 not registered");
+ EXPECT_FALSE(scheduler_.HasReadyStreams());
+ EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()),
+ "No ready streams available");
+
+ // Add a bunch of ready streams to head of per-priority lists.
+ // Expected order: (P2) 4, (P3) 3, 2, 1, (P5) 5
+ scheduler_.RegisterStream(1, 3);
+ scheduler_.MarkStreamReady(1, true);
+ EXPECT_TRUE(scheduler_.HasReadyStreams());
+ scheduler_.RegisterStream(2, 3);
+ scheduler_.MarkStreamReady(2, true);
+ scheduler_.RegisterStream(3, 3);
+ scheduler_.MarkStreamReady(3, true);
+ scheduler_.RegisterStream(4, 2);
+ scheduler_.MarkStreamReady(4, true);
+ scheduler_.RegisterStream(5, 5);
+ scheduler_.MarkStreamReady(5, true);
+
+ EXPECT_EQ(4, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(3, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(2, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(1, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(5, scheduler_.PopNextReadyStream());
+ EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()),
+ "No ready streams available");
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBackAndFront) {
+ scheduler_.RegisterStream(1, 4);
+ scheduler_.RegisterStream(2, 3);
+ scheduler_.RegisterStream(3, 3);
+ scheduler_.RegisterStream(4, 3);
+ scheduler_.RegisterStream(5, 4);
+ scheduler_.RegisterStream(6, 1);
+
+ // Add a bunch of ready streams to per-priority lists, with variety of adding
+ // at head and tail.
+ // Expected order: (P1) 6, (P3) 4, 2, 3, (P4) 1, 5
+ scheduler_.MarkStreamReady(1, true);
+ scheduler_.MarkStreamReady(2, true);
+ scheduler_.MarkStreamReady(3, false);
+ scheduler_.MarkStreamReady(4, true);
+ scheduler_.MarkStreamReady(5, false);
+ scheduler_.MarkStreamReady(6, true);
+
+ EXPECT_EQ(6, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(4, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(2, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(3, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(1, scheduler_.PopNextReadyStream());
+ EXPECT_EQ(5, scheduler_.PopNextReadyStream());
+ EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()),
+ "No ready streams available");
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamNotReady) {
+ // Verify ready state reflected in NumReadyStreams().
+ scheduler_.RegisterStream(1, 1);
+ EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+ scheduler_.MarkStreamReady(1, false);
+ EXPECT_EQ(1u, scheduler_.NumReadyStreams());
+ scheduler_.MarkStreamNotReady(1);
+ EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+
+ // Empty pop should fail.
+ EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()),
+ "No ready streams available");
+
+ // Tolerate redundant marking of a stream as not ready.
+ scheduler_.MarkStreamNotReady(1);
+ EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+
+ // Should only be able to mark registered streams.
+ EXPECT_DFATAL(scheduler_.MarkStreamNotReady(3), "Stream 3 not registered");
+}
+
+TEST_F(PriorityWriteSchedulerTest, UnregisterRemovesStream) {
+ scheduler_.RegisterStream(3, 4);
+ scheduler_.MarkStreamReady(3, false);
+ EXPECT_EQ(1u, scheduler_.NumReadyStreams());
+
+ // Unregistering a stream should remove it from set of ready streams.
+ scheduler_.UnregisterStream(3);
+ EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+ EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()),
+ "No ready streams available");
+}
+
+} // namespace
+} // namespace test
+} // namespace net
diff --git a/chromium/net/spdy/spdy_alt_svc_wire_format.cc b/chromium/net/spdy/spdy_alt_svc_wire_format.cc
index 45047e079e2..ba32160e6f9 100644
--- a/chromium/net/spdy/spdy_alt_svc_wire_format.cc
+++ b/chromium/net/spdy/spdy_alt_svc_wire_format.cc
@@ -12,6 +12,8 @@
namespace net {
+using base::StringPiece;
+
namespace {
template <class T>
@@ -34,6 +36,24 @@ bool ParsePositiveIntegerImpl(StringPiece::const_iterator c,
} // namespace
+SpdyAltSvcWireFormat::AlternativeService::AlternativeService() {}
+
+SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
+ const std::string& protocol_id,
+ const std::string& host,
+ uint16_t port,
+ uint32_t max_age,
+ double probability,
+ VersionVector version)
+ : protocol_id(protocol_id),
+ host(host),
+ port(port),
+ max_age(max_age),
+ probability(probability),
+ version(version) {}
+
+SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() {}
+
// static
bool SpdyAltSvcWireFormat::ParseHeaderFieldValue(
StringPiece value,
@@ -83,14 +103,15 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue(
}
DCHECK_EQ('"', *c);
std::string host;
- uint16 port;
+ uint16_t port;
if (!ParseAltAuthority(alt_authority_begin, c, &host, &port)) {
return false;
}
++c;
// Parse parameters.
- uint32 max_age = 86400;
- double p = 1.0;
+ uint32_t max_age = 86400;
+ double probability = 1.0;
+ VersionVector version;
StringPiece::const_iterator parameters_end = std::find(c, value.end(), ',');
while (c != parameters_end) {
SkipWhiteSpace(&c, parameters_end);
@@ -130,13 +151,44 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue(
if (*parameter_value_begin != '"' || *(c - 1) != '"') {
return false;
}
- if (!ParseProbability(parameter_value_begin + 1, c - 1, &p)) {
+ if (!ParseProbability(parameter_value_begin + 1, c - 1, &probability)) {
+ return false;
+ }
+ } else if (parameter_name.compare("v") == 0) {
+ // Version is a comma separated list of positive integers enclosed in
+ // quotation marks. Since it can contain commas, which are not
+ // delineating alternative service entries, |parameters_end| and |c| can
+ // be invalid.
+ if (*parameter_value_begin != '"') {
return false;
}
+ c = std::find(parameter_value_begin + 1, value.end(), '"');
+ if (c == value.end()) {
+ return false;
+ }
+ ++c;
+ parameters_end = std::find(c, value.end(), ',');
+ StringPiece::const_iterator v_begin = parameter_value_begin + 1;
+ while (v_begin < c) {
+ StringPiece::const_iterator v_end = v_begin;
+ while (v_end < c - 1 && *v_end != ',') {
+ ++v_end;
+ }
+ uint16_t v;
+ if (!ParsePositiveInteger16(v_begin, v_end, &v)) {
+ return false;
+ }
+ version.push_back(v);
+ v_begin = v_end + 1;
+ if (v_begin == c - 1) {
+ // List ends in comma.
+ return false;
+ }
+ }
}
}
- altsvc_vector->push_back(
- AlternativeService(protocol_id, host, port, max_age, p));
+ altsvc_vector->push_back(AlternativeService(protocol_id, host, port,
+ max_age, probability, version));
for (; c != value.end() && (*c == ' ' || *c == '\t' || *c == ','); ++c) {
}
}
@@ -199,8 +251,19 @@ std::string SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
if (altsvc.max_age != 86400) {
base::StringAppendF(&value, "; ma=%d", altsvc.max_age);
}
- if (altsvc.p != 1.0) {
- base::StringAppendF(&value, "; p=\"%.2f\"", altsvc.p);
+ if (altsvc.probability != 1.0) {
+ base::StringAppendF(&value, "; p=\"%.2f\"", altsvc.probability);
+ }
+ if (!altsvc.version.empty()) {
+ value.append("; v=\"");
+ for (VersionVector::const_iterator it = altsvc.version.begin();
+ it != altsvc.version.end(); ++it) {
+ if (it != altsvc.version.begin()) {
+ value.append(",");
+ }
+ base::StringAppendF(&value, "%d", *it);
+ }
+ value.append("\"");
}
}
return value;
@@ -249,7 +312,7 @@ bool SpdyAltSvcWireFormat::PercentDecode(StringPiece::const_iterator c,
bool SpdyAltSvcWireFormat::ParseAltAuthority(StringPiece::const_iterator c,
StringPiece::const_iterator end,
std::string* host,
- uint16* port) {
+ uint16_t* port) {
host->clear();
for (; c != end && *c != ':'; ++c) {
if (*c == '"') {
@@ -276,16 +339,16 @@ bool SpdyAltSvcWireFormat::ParseAltAuthority(StringPiece::const_iterator c,
bool SpdyAltSvcWireFormat::ParsePositiveInteger16(
StringPiece::const_iterator c,
StringPiece::const_iterator end,
- uint16* value) {
- return ParsePositiveIntegerImpl<uint16>(c, end, value);
+ uint16_t* value) {
+ return ParsePositiveIntegerImpl<uint16_t>(c, end, value);
}
// static
bool SpdyAltSvcWireFormat::ParsePositiveInteger32(
StringPiece::const_iterator c,
StringPiece::const_iterator end,
- uint32* value) {
- return ParsePositiveIntegerImpl<uint32>(c, end, value);
+ uint32_t* value) {
+ return ParsePositiveIntegerImpl<uint32_t>(c, end, value);
}
// Probability is a decimal fraction between 0.0 and 1.0, inclusive, with
@@ -295,7 +358,7 @@ bool SpdyAltSvcWireFormat::ParsePositiveInteger32(
// static
bool SpdyAltSvcWireFormat::ParseProbability(StringPiece::const_iterator c,
StringPiece::const_iterator end,
- double* p) {
+ double* probability) {
// "" is invalid.
if (c == end) {
return false;
@@ -305,10 +368,10 @@ bool SpdyAltSvcWireFormat::ParseProbability(StringPiece::const_iterator c,
return false;
}
if (*c == '1') {
- *p = 1.0;
+ *probability = 1.0;
++c;
} else {
- *p = 0.0;
+ *probability = 0.0;
if (*c == '0') {
++c;
}
@@ -323,10 +386,10 @@ bool SpdyAltSvcWireFormat::ParseProbability(StringPiece::const_iterator c,
++c;
double place_value = 0.1;
for (; c != end && isdigit(*c); ++c) {
- *p += place_value * (*c - '0');
+ *probability += place_value * (*c - '0');
place_value *= 0.1;
}
- return (c == end && *p <= 1.0);
+ return (c == end && *probability <= 1.0);
}
} // namespace net
diff --git a/chromium/net/spdy/spdy_alt_svc_wire_format.h b/chromium/net/spdy/spdy_alt_svc_wire_format.h
index df4a8ef6948..28b45723684 100644
--- a/chromium/net/spdy/spdy_alt_svc_wire_format.h
+++ b/chromium/net/spdy/spdy_alt_svc_wire_format.h
@@ -10,14 +10,13 @@
#ifndef NET_SPDY_SPDY_ALT_SVC_WIRE_FORMAT_H_
#define NET_SPDY_SPDY_ALT_SVC_WIRE_FORMAT_H_
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
-using base::StringPiece;
-
namespace net {
namespace test {
@@ -26,28 +25,34 @@ class SpdyAltSvcWireFormatPeer;
class NET_EXPORT_PRIVATE SpdyAltSvcWireFormat {
public:
- struct AlternativeService {
+ using VersionVector = std::vector<uint16_t>;
+
+ struct NET_EXPORT_PRIVATE AlternativeService {
std::string protocol_id;
std::string host;
- uint16 port;
- uint32 max_age;
- double p;
- AlternativeService() = default;
+ // Default is 0: invalid port.
+ uint16_t port = 0;
+ // Default is one day.
+ uint32_t max_age = 86400;
+ // Default is always use.
+ double probability = 1.0;
+ // Default is empty: unspecified version.
+ VersionVector version;
+
+ AlternativeService();
AlternativeService(const std::string& protocol_id,
const std::string& host,
- uint16 port,
- uint32 max_age,
- double p)
- : protocol_id(protocol_id),
- host(host),
- port(port),
- max_age(max_age),
- p(p) {}
+ uint16_t port,
+ uint32_t max_age,
+ double probability,
+ VersionVector version);
+ ~AlternativeService();
bool operator==(const AlternativeService& other) const {
return protocol_id == other.protocol_id && host == other.host &&
- port == other.port && max_age == other.max_age && p == other.p;
+ port == other.port && version == other.version &&
+ max_age == other.max_age && probability == other.probability;
}
};
// An empty vector means alternative services should be cleared for given
@@ -56,30 +61,30 @@ class NET_EXPORT_PRIVATE SpdyAltSvcWireFormat {
typedef std::vector<AlternativeService> AlternativeServiceVector;
friend class test::SpdyAltSvcWireFormatPeer;
- static bool ParseHeaderFieldValue(StringPiece value,
+ static bool ParseHeaderFieldValue(base::StringPiece value,
AlternativeServiceVector* altsvc_vector);
static std::string SerializeHeaderFieldValue(
const AlternativeServiceVector& altsvc_vector);
private:
- static void SkipWhiteSpace(StringPiece::const_iterator* c,
- StringPiece::const_iterator end);
- static bool PercentDecode(StringPiece::const_iterator c,
- StringPiece::const_iterator end,
+ static void SkipWhiteSpace(base::StringPiece::const_iterator* c,
+ base::StringPiece::const_iterator end);
+ static bool PercentDecode(base::StringPiece::const_iterator c,
+ base::StringPiece::const_iterator end,
std::string* output);
- static bool ParseAltAuthority(StringPiece::const_iterator c,
- StringPiece::const_iterator end,
+ static bool ParseAltAuthority(base::StringPiece::const_iterator c,
+ base::StringPiece::const_iterator end,
std::string* host,
- uint16* port);
- static bool ParsePositiveInteger16(StringPiece::const_iterator c,
- StringPiece::const_iterator end,
- uint16* value);
- static bool ParsePositiveInteger32(StringPiece::const_iterator c,
- StringPiece::const_iterator end,
- uint32* value);
- static bool ParseProbability(StringPiece::const_iterator c,
- StringPiece::const_iterator end,
- double* p);
+ uint16_t* port);
+ static bool ParsePositiveInteger16(base::StringPiece::const_iterator c,
+ base::StringPiece::const_iterator end,
+ uint16_t* value);
+ static bool ParsePositiveInteger32(base::StringPiece::const_iterator c,
+ base::StringPiece::const_iterator end,
+ uint32_t* value);
+ static bool ParseProbability(base::StringPiece::const_iterator c,
+ base::StringPiece::const_iterator end,
+ double* probability);
};
} // namespace net
diff --git a/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc b/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc
index 12094a2b88e..565194f4222 100644
--- a/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc
+++ b/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc
@@ -9,6 +9,7 @@
#include "testing/platform_test.h"
using ::testing::_;
+using base::StringPiece;
namespace net {
@@ -29,23 +30,23 @@ class SpdyAltSvcWireFormatPeer {
static bool ParseAltAuthority(StringPiece::const_iterator c,
StringPiece::const_iterator end,
std::string* host,
- uint16* port) {
+ uint16_t* port) {
return SpdyAltSvcWireFormat::ParseAltAuthority(c, end, host, port);
}
static bool ParsePositiveInteger16(StringPiece::const_iterator c,
StringPiece::const_iterator end,
- uint16* max_age) {
+ uint16_t* max_age) {
return SpdyAltSvcWireFormat::ParsePositiveInteger16(c, end, max_age);
}
static bool ParsePositiveInteger32(StringPiece::const_iterator c,
StringPiece::const_iterator end,
- uint32* max_age) {
+ uint32_t* max_age) {
return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end, max_age);
}
static bool ParseProbability(StringPiece::const_iterator c,
StringPiece::const_iterator end,
- double* p) {
- return SpdyAltSvcWireFormat::ParseProbability(c, end, p);
+ double* probability) {
+ return SpdyAltSvcWireFormat::ParseProbability(c, end, probability);
}
};
@@ -53,6 +54,8 @@ class SpdyAltSvcWireFormatPeer {
namespace {
+// Generate header field values, possibly with multiply defined parameters and
+// random case, and corresponding AlternativeService entries.
void FuzzHeaderFieldValue(
int i,
std::string* header_field_value,
@@ -72,7 +75,6 @@ void FuzzHeaderFieldValue(
if (i & 1 << 1) {
header_field_value->append(" ");
}
- expected_altsvc->max_age = 86400;
if (i & 3 << 2) {
expected_altsvc->max_age = 1111;
header_field_value->append(";");
@@ -87,22 +89,22 @@ void FuzzHeaderFieldValue(
if (i & 1 << 4) {
header_field_value->append("; J=s");
}
- expected_altsvc->p = 1.0;
if (i & 1 << 5) {
- expected_altsvc->p = 0.33;
+ expected_altsvc->probability = 0.33;
header_field_value->append("; P=\".33\"");
}
if (i & 1 << 6) {
- expected_altsvc->p = 0.0;
- header_field_value->append("; p=\"0\"");
+ expected_altsvc->probability = 0.0;
+ expected_altsvc->version.push_back(24);
+ header_field_value->append("; p=\"0\";v=\"24\"");
}
if (i & 1 << 7) {
expected_altsvc->max_age = 999999999;
header_field_value->append("; Ma=999999999");
}
if (i & 1 << 8) {
- expected_altsvc->p = 0.0;
- header_field_value->append("; P=\"0.\"");
+ expected_altsvc->probability = 0.1;
+ header_field_value->append("; P=\"0.1\"");
}
if (i & 1 << 9) {
header_field_value->append(";");
@@ -118,6 +120,8 @@ void FuzzHeaderFieldValue(
}
}
+// Generate AlternativeService entries and corresponding header field values in
+// canonical form, that is, what SerializeHeaderFieldValue() should output.
void FuzzAlternativeService(int i,
SpdyAltSvcWireFormat::AlternativeService* altsvc,
std::string* expected_header_field_value) {
@@ -132,22 +136,35 @@ void FuzzAlternativeService(int i,
expected_header_field_value->append("foo\\\"bar\\\\baz");
}
expected_header_field_value->append(":42\"");
- altsvc->max_age = 86400;
if (i & 1 << 1) {
altsvc->max_age = 1111;
expected_header_field_value->append("; ma=1111");
}
- altsvc->p = 1.0;
if (i & 1 << 2) {
- altsvc->p = 0.33;
+ altsvc->probability = 0.33;
expected_header_field_value->append("; p=\"0.33\"");
}
+ if (i & 1 << 3) {
+ altsvc->version.push_back(24);
+ altsvc->version.push_back(25);
+ expected_header_field_value->append("; v=\"24,25\"");
+ }
}
class SpdyAltSvcWireFormatTest : public ::testing::Test {};
// Tests of public API.
+TEST(SpdyAltSvcWireFormatTest, DefaultValues) {
+ SpdyAltSvcWireFormat::AlternativeService altsvc;
+ EXPECT_EQ("", altsvc.protocol_id);
+ EXPECT_EQ("", altsvc.host);
+ EXPECT_EQ(0u, altsvc.port);
+ EXPECT_EQ(86400u, altsvc.max_age);
+ EXPECT_DOUBLE_EQ(1.0, altsvc.probability);
+ EXPECT_TRUE(altsvc.version.empty());
+}
+
TEST(SpdyAltSvcWireFormatTest, ParseInvalidEmptyHeaderFieldValue) {
SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
ASSERT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue("", &altsvc_vector));
@@ -176,7 +193,24 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValue) {
EXPECT_EQ(expected_altsvc.host, altsvc_vector[0].host);
EXPECT_EQ(expected_altsvc.port, altsvc_vector[0].port);
EXPECT_EQ(expected_altsvc.max_age, altsvc_vector[0].max_age);
- EXPECT_DOUBLE_EQ(expected_altsvc.p, altsvc_vector[0].p);
+ EXPECT_DOUBLE_EQ(expected_altsvc.probability, altsvc_vector[0].probability);
+ EXPECT_EQ(expected_altsvc.version, altsvc_vector[0].version);
+
+ // Roundtrip test starting with |altsvc_vector|.
+ std::string reserialized_header_field_value =
+ SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector);
+ SpdyAltSvcWireFormat::AlternativeServiceVector roundtrip_altsvc_vector;
+ ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ reserialized_header_field_value, &roundtrip_altsvc_vector));
+ ASSERT_EQ(1u, roundtrip_altsvc_vector.size());
+ EXPECT_EQ(expected_altsvc.protocol_id,
+ roundtrip_altsvc_vector[0].protocol_id);
+ EXPECT_EQ(expected_altsvc.host, roundtrip_altsvc_vector[0].host);
+ EXPECT_EQ(expected_altsvc.port, roundtrip_altsvc_vector[0].port);
+ EXPECT_EQ(expected_altsvc.max_age, roundtrip_altsvc_vector[0].max_age);
+ EXPECT_DOUBLE_EQ(expected_altsvc.probability,
+ roundtrip_altsvc_vector[0].probability);
+ EXPECT_EQ(expected_altsvc.version, roundtrip_altsvc_vector[0].version);
}
}
@@ -206,7 +240,31 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueMultiple) {
EXPECT_EQ(expected_altsvc_vector[j].host, altsvc_vector[j].host);
EXPECT_EQ(expected_altsvc_vector[j].port, altsvc_vector[j].port);
EXPECT_EQ(expected_altsvc_vector[j].max_age, altsvc_vector[j].max_age);
- EXPECT_DOUBLE_EQ(expected_altsvc_vector[j].p, altsvc_vector[j].p);
+ EXPECT_DOUBLE_EQ(expected_altsvc_vector[j].probability,
+ altsvc_vector[j].probability);
+ EXPECT_EQ(expected_altsvc_vector[j].version, altsvc_vector[j].version);
+ }
+
+ // Roundtrip test starting with |altsvc_vector|.
+ std::string reserialized_header_field_value =
+ SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector);
+ SpdyAltSvcWireFormat::AlternativeServiceVector roundtrip_altsvc_vector;
+ ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ reserialized_header_field_value, &roundtrip_altsvc_vector));
+ ASSERT_EQ(expected_altsvc_vector.size(), roundtrip_altsvc_vector.size());
+ for (unsigned int j = 0; j < roundtrip_altsvc_vector.size(); ++j) {
+ EXPECT_EQ(expected_altsvc_vector[j].protocol_id,
+ roundtrip_altsvc_vector[j].protocol_id);
+ EXPECT_EQ(expected_altsvc_vector[j].host,
+ roundtrip_altsvc_vector[j].host);
+ EXPECT_EQ(expected_altsvc_vector[j].port,
+ roundtrip_altsvc_vector[j].port);
+ EXPECT_EQ(expected_altsvc_vector[j].max_age,
+ roundtrip_altsvc_vector[j].max_age);
+ EXPECT_DOUBLE_EQ(expected_altsvc_vector[j].probability,
+ roundtrip_altsvc_vector[j].probability);
+ EXPECT_EQ(expected_altsvc_vector[j].version,
+ roundtrip_altsvc_vector[j].version);
}
}
}
@@ -217,13 +275,29 @@ TEST(SpdyAltSvcWireFormatTest, SerializeEmptyHeaderFieldValue) {
SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
}
-// Test SerializeHeaderFieldValue() with and without hostname and each
+// Test ParseHeaderFieldValue() and SerializeHeaderFieldValue() on the same pair
+// of |expected_header_field_value| and |altsvc|, with and without hostname and
+// each
// parameter. Single alternative service at a time.
-TEST(SpdyAltSvcWireFormatTest, SerializeHeaderFieldValue) {
- for (int i = 0; i < 1 << 3; ++i) {
+TEST(SpdyAltSvcWireFormatTest, RoundTrip) {
+ for (int i = 0; i < 1 << 4; ++i) {
SpdyAltSvcWireFormat::AlternativeService altsvc;
std::string expected_header_field_value;
FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
+
+ // Test ParseHeaderFieldValue().
+ SpdyAltSvcWireFormat::AlternativeServiceVector parsed_altsvc_vector;
+ ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ expected_header_field_value, &parsed_altsvc_vector));
+ ASSERT_EQ(1u, parsed_altsvc_vector.size());
+ EXPECT_EQ(altsvc.protocol_id, parsed_altsvc_vector[0].protocol_id);
+ EXPECT_EQ(altsvc.host, parsed_altsvc_vector[0].host);
+ EXPECT_EQ(altsvc.port, parsed_altsvc_vector[0].port);
+ EXPECT_EQ(altsvc.max_age, parsed_altsvc_vector[0].max_age);
+ EXPECT_DOUBLE_EQ(altsvc.probability, parsed_altsvc_vector[0].probability);
+ EXPECT_EQ(altsvc.version, parsed_altsvc_vector[0].version);
+
+ // Test SerializeHeaderFieldValue().
SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
altsvc_vector.push_back(altsvc);
EXPECT_EQ(expected_header_field_value,
@@ -231,16 +305,38 @@ TEST(SpdyAltSvcWireFormatTest, SerializeHeaderFieldValue) {
}
}
-// Test SerializeHeaderFieldValue() with and without hostname and each
+// Test ParseHeaderFieldValue() and SerializeHeaderFieldValue() on the same pair
+// of |expected_header_field_value| and |altsvc|, with and without hostname and
+// each
// parameter. Multiple alternative services at a time.
-TEST(SpdyAltSvcWireFormatTest, SerializeHeaderFieldValueMultiple) {
+TEST(SpdyAltSvcWireFormatTest, RoundTripMultiple) {
SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
std::string expected_header_field_value;
- for (int i = 0; i < 1 << 3; ++i) {
+ for (int i = 0; i < 1 << 4; ++i) {
SpdyAltSvcWireFormat::AlternativeService altsvc;
FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
altsvc_vector.push_back(altsvc);
}
+
+ // Test ParseHeaderFieldValue().
+ SpdyAltSvcWireFormat::AlternativeServiceVector parsed_altsvc_vector;
+ ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ expected_header_field_value, &parsed_altsvc_vector));
+ ASSERT_EQ(altsvc_vector.size(), parsed_altsvc_vector.size());
+ SpdyAltSvcWireFormat::AlternativeServiceVector::iterator expected_it =
+ altsvc_vector.begin();
+ SpdyAltSvcWireFormat::AlternativeServiceVector::iterator parsed_it =
+ parsed_altsvc_vector.begin();
+ for (; expected_it != altsvc_vector.end(); ++expected_it, ++parsed_it) {
+ EXPECT_EQ(expected_it->protocol_id, parsed_it->protocol_id);
+ EXPECT_EQ(expected_it->host, parsed_it->host);
+ EXPECT_EQ(expected_it->port, parsed_it->port);
+ EXPECT_EQ(expected_it->max_age, parsed_it->max_age);
+ EXPECT_DOUBLE_EQ(expected_it->probability, parsed_it->probability);
+ EXPECT_EQ(expected_it->version, parsed_it->version);
+ }
+
+ // Test SerializeHeaderFieldValue().
EXPECT_EQ(expected_header_field_value,
SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
}
@@ -256,7 +352,9 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueInvalid) {
"a=\"b:42\" ; min-age", "a=\"b:42\" ; ma", "a=\"b:42\" ; ma=",
"a=\"b:42\" ; ma=ma", "a=\"b:42\" ; ma=123bar", "a=\"b:42\" ; p=\"-2\"",
"a=\"b:42\" ; p=\"..\"", "a=\"b:42\" ; p=\"1.05\"", "a=\"b:42\" ; p=0.4",
- "a=\"b:42\" ; p=\" 1.0\""};
+ "a=\"b:42\" ; p=\" 1.0\"", "a=\"b:42\" ; v=24", "a=\"b:42\" ; v=24,25",
+ "a=\"b:42\" ; v=\"-3\"", "a=\"b:42\" ; v=\"1.2\"",
+ "a=\"b:42\" ; v=\"24,\""};
for (const char* invalid_field_value : invalid_field_value_array) {
EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
invalid_field_value, &altsvc_vector))
@@ -333,7 +431,7 @@ TEST(SpdyAltSvcWireFormatTest, PercentDecodeInvalid) {
TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) {
StringPiece input(":42");
std::string host;
- uint16 port;
+ uint16_t port;
ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
input.begin(), input.end(), &host, &port));
EXPECT_TRUE(host.empty());
@@ -354,7 +452,7 @@ TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) {
for (const char* invalid_input : invalid_input_array) {
StringPiece input(invalid_input);
std::string host;
- uint16 port;
+ uint16_t port;
EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
input.begin(), input.end(), &host, &port))
<< input;
@@ -364,7 +462,7 @@ TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) {
// Test ParseInteger() on valid input.
TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) {
StringPiece input("3");
- uint16 value;
+ uint16_t value;
ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value));
EXPECT_EQ(3, value);
@@ -381,7 +479,7 @@ TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) {
const char* invalid_input_array[] = {"", " ", "a", "0", "00", "1 ", "12b"};
for (const char* invalid_input : invalid_input_array) {
StringPiece input(invalid_input);
- uint16 value;
+ uint16_t value;
EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value))
<< input;
@@ -390,14 +488,14 @@ TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) {
// Test ParseIntegerValid() around overflow limit.
TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) {
- // Largest possible uint16 value.
+ // Largest possible uint16_t value.
StringPiece input("65535");
- uint16 value16;
+ uint16_t value16;
ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value16));
EXPECT_EQ(65535, value16);
- // Overflow uint16, ParsePositiveInteger16() should return false.
+ // Overflow uint16_t, ParsePositiveInteger16() should return false.
input = StringPiece("65536");
ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value16));
@@ -408,14 +506,14 @@ TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) {
ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value16));
- // Largest possible uint32 value.
+ // Largest possible uint32_t value.
input = StringPiece("4294967295");
- uint32 value32;
+ uint32_t value32;
ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
input.begin(), input.end(), &value32));
EXPECT_EQ(4294967295, value32);
- // Overflow uint32, ParsePositiveInteger32() should return false.
+ // Overflow uint32_t, ParsePositiveInteger32() should return false.
input = StringPiece("4294967296");
ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
input.begin(), input.end(), &value32));
diff --git a/chromium/net/spdy/spdy_buffer.cc b/chromium/net/spdy/spdy_buffer.cc
index f7cd3786e2b..fad3305d894 100644
--- a/chromium/net/spdy/spdy_buffer.cc
+++ b/chromium/net/spdy/spdy_buffer.cc
@@ -5,9 +5,11 @@
#include "net/spdy/spdy_buffer.h"
#include <cstring>
+#include <utility>
#include "base/callback.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "net/base/io_buffer.h"
#include "net/spdy/spdy_protocol.h"
@@ -28,7 +30,7 @@ scoped_ptr<SpdyFrame> MakeSpdyFrame(const char* data, size_t size) {
std::memcpy(frame_data.get(), data, size);
scoped_ptr<SpdyFrame> frame(
new SpdyFrame(frame_data.release(), size, true /* owns_buffer */));
- return frame.Pass();
+ return frame;
}
} // namespace
@@ -57,7 +59,7 @@ class SpdyBuffer::SharedFrameIOBuffer : public IOBuffer {
SpdyBuffer::SpdyBuffer(scoped_ptr<SpdyFrame> frame)
: shared_frame_(new SharedFrame()),
offset_(0) {
- shared_frame_->data = frame.Pass();
+ shared_frame_->data = std::move(frame);
}
// The given data may not be strictly a SPDY frame; we (ab)use
diff --git a/chromium/net/spdy/spdy_buffer.h b/chromium/net/spdy/spdy_buffer.h
index 60bdab7465d..94ee97fe6d5 100644
--- a/chromium/net/spdy/spdy_buffer.h
+++ b/chromium/net/spdy/spdy_buffer.h
@@ -8,8 +8,8 @@
#include <cstddef>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/spdy/spdy_buffer_producer.cc b/chromium/net/spdy/spdy_buffer_producer.cc
index 3a9598c859f..8f18d19f24f 100644
--- a/chromium/net/spdy/spdy_buffer_producer.cc
+++ b/chromium/net/spdy/spdy_buffer_producer.cc
@@ -4,6 +4,8 @@
#include "net/spdy/spdy_buffer_producer.h"
+#include <utility>
+
#include "base/logging.h"
#include "net/spdy/spdy_buffer.h"
#include "net/spdy/spdy_protocol.h"
@@ -15,13 +17,13 @@ SpdyBufferProducer::SpdyBufferProducer() {}
SpdyBufferProducer::~SpdyBufferProducer() {}
SimpleBufferProducer::SimpleBufferProducer(scoped_ptr<SpdyBuffer> buffer)
- : buffer_(buffer.Pass()) {}
+ : buffer_(std::move(buffer)) {}
SimpleBufferProducer::~SimpleBufferProducer() {}
scoped_ptr<SpdyBuffer> SimpleBufferProducer::ProduceBuffer() {
DCHECK(buffer_);
- return buffer_.Pass();
+ return std::move(buffer_);
}
} // namespace net
diff --git a/chromium/net/spdy/spdy_buffer_producer.h b/chromium/net/spdy/spdy_buffer_producer.h
index d098bb9a36e..849ecd24dfe 100644
--- a/chromium/net/spdy/spdy_buffer_producer.h
+++ b/chromium/net/spdy/spdy_buffer_producer.h
@@ -5,8 +5,8 @@
#ifndef NET_SPDY_SPDY_BUFFER_PRODUCER_H_
#define NET_SPDY_SPDY_BUFFER_PRODUCER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/spdy/spdy_buffer_unittest.cc b/chromium/net/spdy/spdy_buffer_unittest.cc
index 7c14ee9d8f1..4200916c426 100644
--- a/chromium/net/spdy/spdy_buffer_unittest.cc
+++ b/chromium/net/spdy/spdy_buffer_unittest.cc
@@ -8,7 +8,6 @@
#include <cstring>
#include <string>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
diff --git a/chromium/net/spdy/spdy_frame_builder.cc b/chromium/net/spdy/spdy_frame_builder.cc
index 5015c9a49a6..fb8cdccb45b 100644
--- a/chromium/net/spdy/spdy_frame_builder.cc
+++ b/chromium/net/spdy/spdy_frame_builder.cc
@@ -16,15 +16,15 @@ namespace {
// A special structure for the 8 bit flags and 24 bit length fields.
union FlagsAndLength {
- uint8 flags[4]; // 8 bits
- uint32 length; // 24 bits
+ uint8_t flags[4]; // 8 bits
+ uint32_t length; // 24 bits
};
// Creates a FlagsAndLength.
-FlagsAndLength CreateFlagsAndLength(uint8 flags, size_t length) {
+FlagsAndLength CreateFlagsAndLength(uint8_t flags, size_t length) {
DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
FlagsAndLength flags_length;
- flags_length.length = htonl(static_cast<uint32>(length));
+ flags_length.length = base::HostToNet32(static_cast<uint32_t>(length));
DCHECK_EQ(0, flags & ~kControlFlagsMask);
flags_length.flags[0] = flags;
return flags_length;
@@ -61,7 +61,7 @@ bool SpdyFrameBuilder::Seek(size_t length) {
bool SpdyFrameBuilder::WriteControlFrameHeader(const SpdyFramer& framer,
SpdyFrameType type,
- uint8 flags) {
+ uint8_t flags) {
DCHECK_GE(SPDY3, version_);
DCHECK(SpdyConstants::IsValidFrameType(
version_, SpdyConstants::SerializeFrameType(version_, type)));
@@ -79,7 +79,7 @@ bool SpdyFrameBuilder::WriteControlFrameHeader(const SpdyFramer& framer,
bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
SpdyStreamId stream_id,
- uint8 flags) {
+ uint8_t flags) {
if (version_ > SPDY3) {
return BeginNewFrame(framer, DATA, flags, stream_id);
}
@@ -89,7 +89,7 @@ bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
size_t length_field = capacity_ - framer.GetDataFrameMinimumSize();
DCHECK_EQ(0u, length_field & ~static_cast<size_t>(kLengthMask));
FlagsAndLength flags_length;
- flags_length.length = htonl(length_field);
+ flags_length.length = base::HostToNet32(static_cast<uint32_t>(length_field));
DCHECK_EQ(0, flags & ~kDataFlagsMask);
flags_length.flags[0] = flags;
success &= WriteBytes(&flags_length, sizeof(flags_length));
@@ -99,7 +99,7 @@ bool SpdyFrameBuilder::WriteDataFrameHeader(const SpdyFramer& framer,
bool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer,
SpdyFrameType type,
- uint8 flags,
+ uint8_t flags,
SpdyStreamId stream_id) {
DCHECK(SpdyConstants::IsValidFrameType(
version_, SpdyConstants::SerializeFrameType(version_, type)));
@@ -136,11 +136,11 @@ bool SpdyFrameBuilder::WriteStringPiece16(const base::StringPiece& value) {
return false;
}
- if (!WriteUInt16(static_cast<uint16>(value.size()))) {
+ if (!WriteUInt16(static_cast<uint16_t>(value.size()))) {
return false;
}
- return WriteBytes(value.data(), static_cast<uint16>(value.size()));
+ return WriteBytes(value.data(), static_cast<uint16_t>(value.size()));
}
bool SpdyFrameBuilder::WriteStringPiece32(const base::StringPiece& value) {
@@ -151,7 +151,7 @@ bool SpdyFrameBuilder::WriteStringPiece32(const base::StringPiece& value) {
return WriteBytes(value.data(), value.size());
}
-bool SpdyFrameBuilder::WriteBytes(const void* data, uint32 data_len) {
+bool SpdyFrameBuilder::WriteBytes(const void* data, uint32_t data_len) {
if (!CanWrite(data_len)) {
return false;
}
@@ -197,8 +197,7 @@ bool SpdyFrameBuilder::OverwriteLength(const SpdyFramer& framer,
return success;
}
-bool SpdyFrameBuilder::OverwriteFlags(const SpdyFramer& framer,
- uint8 flags) {
+bool SpdyFrameBuilder::OverwriteFlags(const SpdyFramer& framer, uint8_t flags) {
DCHECK_GT(framer.protocol_version(), SPDY3);
bool success = false;
const size_t old_length = length_;
diff --git a/chromium/net/spdy/spdy_frame_builder.h b/chromium/net/spdy/spdy_frame_builder.h
index 2cecd65b50e..8d75aef760f 100644
--- a/chromium/net/spdy/spdy_frame_builder.h
+++ b/chromium/net/spdy/spdy_frame_builder.h
@@ -5,9 +5,11 @@
#ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_
#define NET_SPDY_SPDY_FRAME_BUILDER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "base/sys_byteorder.h"
@@ -54,13 +56,13 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder {
// Used only for SPDY versions <4.
bool WriteControlFrameHeader(const SpdyFramer& framer,
SpdyFrameType type,
- uint8 flags);
+ uint8_t flags);
// Populates this frame with a SPDY data frame header using version-specific
// information from the |framer| and length information from capacity_.
bool WriteDataFrameHeader(const SpdyFramer& framer,
SpdyStreamId stream_id,
- uint8 flags);
+ uint8_t flags);
// Populates this frame with a SPDY4/HTTP2 frame prefix using
// version-specific information from the |framer| and length information from
@@ -68,7 +70,7 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder {
// Used only for SPDY versions >=4.
bool BeginNewFrame(const SpdyFramer& framer,
SpdyFrameType type,
- uint8 flags,
+ uint8_t flags,
SpdyStreamId stream_id);
// Takes the buffer from the SpdyFrameBuilder.
@@ -88,31 +90,29 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder {
// Methods for adding to the payload. These values are appended to the end
// of the SpdyFrameBuilder payload. Note - binary integers are converted from
// host to network form.
- bool WriteUInt8(uint8 value) {
- return WriteBytes(&value, sizeof(value));
- }
- bool WriteUInt16(uint16 value) {
- value = htons(value);
+ bool WriteUInt8(uint8_t value) { return WriteBytes(&value, sizeof(value)); }
+ bool WriteUInt16(uint16_t value) {
+ value = base::HostToNet16(value);
return WriteBytes(&value, sizeof(value));
}
- bool WriteUInt24(uint32 value) {
- value = htonl(value);
+ bool WriteUInt24(uint32_t value) {
+ value = base::HostToNet32(value);
return WriteBytes(reinterpret_cast<char*>(&value) + 1,
sizeof(value) - 1);
}
- bool WriteUInt32(uint32 value) {
- value = htonl(value);
+ bool WriteUInt32(uint32_t value) {
+ value = base::HostToNet32(value);
return WriteBytes(&value, sizeof(value));
}
- bool WriteUInt64(uint64 value) {
- uint32 upper = htonl(value >> 32);
- uint32 lower = htonl(static_cast<uint32>(value));
+ bool WriteUInt64(uint64_t value) {
+ uint32_t upper = base::HostToNet32(static_cast<uint32_t>(value >> 32));
+ uint32_t lower = base::HostToNet32(static_cast<uint32_t>(value));
return (WriteBytes(&upper, sizeof(upper)) &&
WriteBytes(&lower, sizeof(lower)));
}
bool WriteStringPiece16(const base::StringPiece& value);
bool WriteStringPiece32(const base::StringPiece& value);
- bool WriteBytes(const void* data, uint32 data_len);
+ bool WriteBytes(const void* data, uint32_t data_len);
// Update (in-place) the length field in the frame being built to reflect the
// current actual length of bytes written to said frame through this builder.
@@ -131,7 +131,7 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder {
// Update (in-place) the flags field in the frame being built to reflect the
// given flags value.
// Used only for SPDY versions >=4.
- bool OverwriteFlags(const SpdyFramer& framer, uint8 flags);
+ bool OverwriteFlags(const SpdyFramer& framer, uint8_t flags);
private:
// Checks to make sure that there is an appropriate amount of space for a
diff --git a/chromium/net/spdy/spdy_frame_builder_test.cc b/chromium/net/spdy/spdy_frame_builder_test.cc
index e352303bf36..70b9374d8b8 100644
--- a/chromium/net/spdy/spdy_frame_builder_test.cc
+++ b/chromium/net/spdy/spdy_frame_builder_test.cc
@@ -18,11 +18,10 @@ class SpdyFrameBuilderTest : public ::testing::TestWithParam<SpdyMajorVersion> {
SpdyMajorVersion spdy_version_;
};
-// All tests are run with three different SPDY versions: SPDY/2, SPDY/3 and
-// HTTP/2.
+// All tests are run with SPDY/3 and HTTP/2.
INSTANTIATE_TEST_CASE_P(SpdyFrameBuilderTests,
SpdyFrameBuilderTest,
- ::testing::Values(SPDY2, SPDY3, HTTP2));
+ ::testing::Values(SPDY3, HTTP2));
TEST_P(SpdyFrameBuilderTest, GetWritableBuffer) {
const size_t builder_size = 10;
diff --git a/chromium/net/spdy/spdy_frame_reader.cc b/chromium/net/spdy/spdy_frame_reader.cc
index 3ecce43e17e..4727caaa2ec 100644
--- a/chromium/net/spdy/spdy_frame_reader.cc
+++ b/chromium/net/spdy/spdy_frame_reader.cc
@@ -16,15 +16,15 @@ SpdyFrameReader::SpdyFrameReader(const char* data, const size_t len)
ofs_(0) {
}
-bool SpdyFrameReader::ReadUInt8(uint8* result) {
- // Make sure that we have the whole uint8.
+bool SpdyFrameReader::ReadUInt8(uint8_t* result) {
+ // Make sure that we have the whole uint8_t.
if (!CanRead(1)) {
OnFailure();
return false;
}
// Read into result.
- *result = *reinterpret_cast<const uint8*>(data_ + ofs_);
+ *result = *reinterpret_cast<const uint8_t*>(data_ + ofs_);
// Iterate.
ofs_ += 1;
@@ -32,15 +32,16 @@ bool SpdyFrameReader::ReadUInt8(uint8* result) {
return true;
}
-bool SpdyFrameReader::ReadUInt16(uint16* result) {
- // Make sure that we have the whole uint16.
+bool SpdyFrameReader::ReadUInt16(uint16_t* result) {
+ // Make sure that we have the whole uint16_t.
if (!CanRead(2)) {
OnFailure();
return false;
}
// Read into result.
- *result = ntohs(*(reinterpret_cast<const uint16*>(data_ + ofs_)));
+ *result =
+ base::NetToHost16(*(reinterpret_cast<const uint16_t*>(data_ + ofs_)));
// Iterate.
ofs_ += 2;
@@ -48,15 +49,16 @@ bool SpdyFrameReader::ReadUInt16(uint16* result) {
return true;
}
-bool SpdyFrameReader::ReadUInt32(uint32* result) {
- // Make sure that we have the whole uint32.
+bool SpdyFrameReader::ReadUInt32(uint32_t* result) {
+ // Make sure that we have the whole uint32_t.
if (!CanRead(4)) {
OnFailure();
return false;
}
// Read into result.
- *result = ntohl(*(reinterpret_cast<const uint32*>(data_ + ofs_)));
+ *result =
+ base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data_ + ofs_)));
// Iterate.
ofs_ += 4;
@@ -64,16 +66,18 @@ bool SpdyFrameReader::ReadUInt32(uint32* result) {
return true;
}
-bool SpdyFrameReader::ReadUInt64(uint64* result) {
- // Make sure that we have the whole uint64.
+bool SpdyFrameReader::ReadUInt64(uint64_t* result) {
+ // Make sure that we have the whole uint64_t.
if (!CanRead(8)) {
OnFailure();
return false;
}
// Read into result. Network byte order is big-endian.
- uint64 upper = ntohl(*(reinterpret_cast<const uint32*>(data_ + ofs_)));
- uint64 lower = ntohl(*(reinterpret_cast<const uint32*>(data_ + ofs_ + 4)));
+ uint64_t upper =
+ base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data_ + ofs_)));
+ uint64_t lower =
+ base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data_ + ofs_ + 4)));
*result = (upper << 32) + lower;
// Iterate.
@@ -82,7 +86,7 @@ bool SpdyFrameReader::ReadUInt64(uint64* result) {
return true;
}
-bool SpdyFrameReader::ReadUInt31(uint32* result) {
+bool SpdyFrameReader::ReadUInt31(uint32_t* result) {
bool success = ReadUInt32(result);
// Zero out highest-order bit.
@@ -93,7 +97,7 @@ bool SpdyFrameReader::ReadUInt31(uint32* result) {
return success;
}
-bool SpdyFrameReader::ReadUInt24(uint32* result) {
+bool SpdyFrameReader::ReadUInt24(uint32_t* result) {
// Make sure that we have the whole uint24.
if (!CanRead(3)) {
OnFailure();
@@ -103,7 +107,7 @@ bool SpdyFrameReader::ReadUInt24(uint32* result) {
// Read into result.
*result = 0;
memcpy(reinterpret_cast<char*>(result) + 1, data_ + ofs_, 3);
- *result = ntohl(*result);
+ *result = base::NetToHost32(*result);
// Iterate.
ofs_ += 3;
@@ -113,7 +117,7 @@ bool SpdyFrameReader::ReadUInt24(uint32* result) {
bool SpdyFrameReader::ReadStringPiece16(base::StringPiece* result) {
// Read resultant length.
- uint16 result_len;
+ uint16_t result_len;
if (!ReadUInt16(&result_len)) {
// OnFailure() already called.
return false;
@@ -136,7 +140,7 @@ bool SpdyFrameReader::ReadStringPiece16(base::StringPiece* result) {
bool SpdyFrameReader::ReadStringPiece32(base::StringPiece* result) {
// Read resultant length.
- uint32 result_len;
+ uint32_t result_len;
if (!ReadUInt32(&result_len)) {
// OnFailure() already called.
return false;
diff --git a/chromium/net/spdy/spdy_frame_reader.h b/chromium/net/spdy/spdy_frame_reader.h
index d30ae93c1ba..c1752180ca2 100644
--- a/chromium/net/spdy/spdy_frame_reader.h
+++ b/chromium/net/spdy/spdy_frame_reader.h
@@ -5,7 +5,9 @@
#ifndef NET_SPDY_SPDY_FRAME_READER_H_
#define NET_SPDY_SPDY_FRAME_READER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
@@ -36,34 +38,34 @@ class NET_EXPORT_PRIVATE SpdyFrameReader {
// Reads an 8-bit unsigned integer into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUInt8(uint8* result);
+ bool ReadUInt8(uint8_t* result);
// Reads a 16-bit unsigned integer into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUInt16(uint16* result);
+ bool ReadUInt16(uint16_t* result);
// Reads a 32-bit unsigned integer into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUInt32(uint32* result);
+ bool ReadUInt32(uint32_t* result);
// Reads a 64-bit unsigned integer into the given output parameter.
// Forwards the internal iterator on success.
// Returns true on success, false otherwise.
- bool ReadUInt64(uint64* result);
+ bool ReadUInt64(uint64_t* result);
// Reads a 31-bit unsigned integer into the given output parameter. This is
// equivalent to ReadUInt32() above except that the highest-order bit is
// discarded.
// Forwards the internal iterator (by 4B) on success.
// Returns true on success, false otherwise.
- bool ReadUInt31(uint32* result);
+ bool ReadUInt31(uint32_t* result);
// Reads a 24-bit unsigned integer into the given output parameter.
// Forwards the internal iterator (by 3B) on success.
// Returns true on success, false otherwise.
- bool ReadUInt24(uint32* result);
+ bool ReadUInt24(uint32_t* result);
// Reads a string prefixed with 16-bit length into the given output parameter.
//
diff --git a/chromium/net/spdy/spdy_frame_reader_test.cc b/chromium/net/spdy/spdy_frame_reader_test.cc
index 8db2d992e70..ca178de33f5 100644
--- a/chromium/net/spdy/spdy_frame_reader_test.cc
+++ b/chromium/net/spdy/spdy_frame_reader_test.cc
@@ -14,15 +14,15 @@ namespace net {
TEST(SpdyFrameReaderTest, ReadUInt16) {
// Frame data in network byte order.
- const uint16 kFrameData[] = {
- htons(1), htons(1<<15),
+ const uint16_t kFrameData[] = {
+ base::HostToNet16(1), base::HostToNet16(1 << 15),
};
SpdyFrameReader frame_reader(reinterpret_cast<const char*>(kFrameData),
sizeof(kFrameData));
EXPECT_FALSE(frame_reader.IsDoneReading());
- uint16 uint16_val;
+ uint16_t uint16_val;
EXPECT_TRUE(frame_reader.ReadUInt16(&uint16_val));
EXPECT_FALSE(frame_reader.IsDoneReading());
EXPECT_EQ(1, uint16_val);
@@ -34,15 +34,15 @@ TEST(SpdyFrameReaderTest, ReadUInt16) {
TEST(SpdyFrameReaderTest, ReadUInt32) {
// Frame data in network byte order.
- const uint32 kFrameData[] = {
- htonl(1), htonl(0x80000000),
+ const uint32_t kFrameData[] = {
+ base::HostToNet32(1), base::HostToNet32(0x80000000),
};
- SpdyFrameReader frame_reader(reinterpret_cast<const char *>(kFrameData),
- arraysize(kFrameData) * sizeof(uint32));
+ SpdyFrameReader frame_reader(reinterpret_cast<const char*>(kFrameData),
+ arraysize(kFrameData) * sizeof(uint32_t));
EXPECT_FALSE(frame_reader.IsDoneReading());
- uint32 uint32_val;
+ uint32_t uint32_val;
EXPECT_TRUE(frame_reader.ReadUInt32(&uint32_val));
EXPECT_FALSE(frame_reader.IsDoneReading());
EXPECT_EQ(1u, uint32_val);
@@ -55,13 +55,11 @@ TEST(SpdyFrameReaderTest, ReadUInt32) {
TEST(SpdyFrameReaderTest, ReadStringPiece16) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, 0x02, // uint16(2)
- 0x48, 0x69, // "Hi"
- 0x00, 0x10, // uint16(16)
- 0x54, 0x65, 0x73, 0x74,
- 0x69, 0x6e, 0x67, 0x2c,
- 0x20, 0x31, 0x2c, 0x20,
- 0x32, 0x2c, 0x20, 0x33, // "Testing, 1, 2, 3"
+ 0x00, 0x02, // uint16_t(2)
+ 0x48, 0x69, // "Hi"
+ 0x00, 0x10, // uint16_t(16)
+ 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2c,
+ 0x20, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33, // "Testing, 1, 2, 3"
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
@@ -80,13 +78,11 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16) {
TEST(SpdyFrameReaderTest, ReadStringPiece32) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, 0x00, 0x00, 0x03, // uint32(3)
- 0x66, 0x6f, 0x6f, // "foo"
- 0x00, 0x00, 0x00, 0x10, // uint32(16)
- 0x54, 0x65, 0x73, 0x74,
- 0x69, 0x6e, 0x67, 0x2c,
- 0x20, 0x34, 0x2c, 0x20,
- 0x35, 0x2c, 0x20, 0x36, // "Testing, 4, 5, 6"
+ 0x00, 0x00, 0x00, 0x03, // uint32_t(3)
+ 0x66, 0x6f, 0x6f, // "foo"
+ 0x00, 0x00, 0x00, 0x10, // uint32_t(16)
+ 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2c,
+ 0x20, 0x34, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x36, // "Testing, 4, 5, 6"
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
@@ -105,31 +101,32 @@ TEST(SpdyFrameReaderTest, ReadStringPiece32) {
TEST(SpdyFrameReaderTest, ReadUInt16WithBufferTooSmall) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, // part of a uint16
+ 0x00, // part of a uint16_t
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
EXPECT_FALSE(frame_reader.IsDoneReading());
- uint16 uint16_val;
+ uint16_t uint16_val;
EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
}
TEST(SpdyFrameReaderTest, ReadUInt32WithBufferTooSmall) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, 0x00, 0x00, // part of a uint32
+ 0x00, 0x00, 0x00, // part of a uint32_t
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
EXPECT_FALSE(frame_reader.IsDoneReading());
- uint32 uint32_val;
+ uint32_t uint32_val;
EXPECT_FALSE(frame_reader.ReadUInt32(&uint32_val));
- // Also make sure that trying to read a uint16, which technically could work,
+ // Also make sure that trying to read a uint16_t, which technically could
+ // work,
// fails immediately due to previously encountered failed read.
- uint16 uint16_val;
+ uint16_t uint16_val;
EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
}
@@ -137,8 +134,8 @@ TEST(SpdyFrameReaderTest, ReadUInt32WithBufferTooSmall) {
TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferTooSmall) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, 0x03, // uint16(3)
- 0x48, 0x69, // "Hi"
+ 0x00, 0x03, // uint16_t(3)
+ 0x48, 0x69, // "Hi"
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
@@ -147,9 +144,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferTooSmall) {
base::StringPiece stringpiece_val;
EXPECT_FALSE(frame_reader.ReadStringPiece16(&stringpiece_val));
- // Also make sure that trying to read a uint16, which technically could work,
+ // Also make sure that trying to read a uint16_t, which technically could
+ // work,
// fails immediately due to previously encountered failed read.
- uint16 uint16_val;
+ uint16_t uint16_val;
EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
}
@@ -157,7 +155,7 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferTooSmall) {
TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferWayTooSmall) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, // part of a uint16
+ 0x00, // part of a uint16_t
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
@@ -166,9 +164,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferWayTooSmall) {
base::StringPiece stringpiece_val;
EXPECT_FALSE(frame_reader.ReadStringPiece16(&stringpiece_val));
- // Also make sure that trying to read a uint16, which technically could work,
+ // Also make sure that trying to read a uint16_t, which technically could
+ // work,
// fails immediately due to previously encountered failed read.
- uint16 uint16_val;
+ uint16_t uint16_val;
EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
}
@@ -176,8 +175,8 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferWayTooSmall) {
TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferTooSmall) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, 0x00, 0x00, 0x03, // uint32(3)
- 0x48, 0x69, // "Hi"
+ 0x00, 0x00, 0x00, 0x03, // uint32_t(3)
+ 0x48, 0x69, // "Hi"
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
@@ -186,9 +185,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferTooSmall) {
base::StringPiece stringpiece_val;
EXPECT_FALSE(frame_reader.ReadStringPiece32(&stringpiece_val));
- // Also make sure that trying to read a uint16, which technically could work,
+ // Also make sure that trying to read a uint16_t, which technically could
+ // work,
// fails immediately due to previously encountered failed read.
- uint16 uint16_val;
+ uint16_t uint16_val;
EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
}
@@ -196,7 +196,7 @@ TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferTooSmall) {
TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferWayTooSmall) {
// Frame data in network byte order.
const char kFrameData[] = {
- 0x00, 0x00, 0x00, // part of a uint32
+ 0x00, 0x00, 0x00, // part of a uint32_t
};
SpdyFrameReader frame_reader(kFrameData, arraysize(kFrameData));
@@ -205,9 +205,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferWayTooSmall) {
base::StringPiece stringpiece_val;
EXPECT_FALSE(frame_reader.ReadStringPiece32(&stringpiece_val));
- // Also make sure that trying to read a uint16, which technically could work,
+ // Also make sure that trying to read a uint16_t, which technically could
+ // work,
// fails immediately due to previously encountered failed read.
- uint16 uint16_val;
+ uint16_t uint16_val;
EXPECT_FALSE(frame_reader.ReadUInt16(&uint16_val));
}
diff --git a/chromium/net/spdy/spdy_framer.cc b/chromium/net/spdy/spdy_framer.cc
index ad9fb975284..6568b281d2c 100644
--- a/chromium/net/spdy/spdy_framer.cc
+++ b/chromium/net/spdy/spdy_framer.cc
@@ -14,7 +14,6 @@
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
-#include "base/third_party/valgrind/memcheck.h"
#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_frame_reader.h"
@@ -39,6 +38,7 @@ uLong CalculateDictionaryId(const char* dictionary,
dictionary_size);
}
+#if !defined(USE_SYSTEM_ZLIB)
// Check to see if the name and value of a cookie are both empty.
bool IsCookieEmpty(const base::StringPiece& cookie) {
if (cookie.size() == 0) {
@@ -57,21 +57,22 @@ bool IsCookieEmpty(const base::StringPiece& cookie) {
}
return (pos == 0) && ((cookie.size() - value_start) == 0);
}
+#endif // !defined(USE_SYSTEM_ZLIB)
// Pack parent stream ID and exclusive flag into the format used by HTTP/2
// headers and priority frames.
-uint32 PackStreamDependencyValues(bool exclusive,
- SpdyStreamId parent_stream_id) {
+uint32_t PackStreamDependencyValues(bool exclusive,
+ SpdyStreamId parent_stream_id) {
// Make sure the highest-order bit in the parent stream id is zeroed out.
- uint32 parent = parent_stream_id & 0x7fffffff;
+ uint32_t parent = parent_stream_id & 0x7fffffff;
// Set the one-bit exclusivity flag.
- uint32 e_bit = exclusive ? 0x80000000 : 0;
+ uint32_t e_bit = exclusive ? 0x80000000 : 0;
return parent | e_bit;
}
// Unpack parent stream ID and exclusive flag from the format used by HTTP/2
// headers and priority frames.
-void UnpackStreamDependencyValues(uint32 packed,
+void UnpackStreamDependencyValues(uint32_t packed,
bool* exclusive,
SpdyStreamId* parent_stream_id) {
*exclusive = (packed >> 31) != 0;
@@ -81,10 +82,8 @@ void UnpackStreamDependencyValues(uint32 packed,
struct DictionaryIds {
DictionaryIds()
- : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)),
- v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize))
- {}
- const uLong v2_dictionary_id;
+ : v3_dictionary_id(
+ CalculateDictionaryId(kV3Dictionary, kV3DictionarySize)) {}
const uLong v3_dictionary_id;
};
@@ -93,7 +92,7 @@ struct DictionaryIds {
base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
// Used to indicate no flags in a SPDY flags field.
-const uint8 kNoFlags = 0;
+const uint8_t kNoFlags = 0;
// Wire sizes of priority payloads.
const size_t kPriorityDependencyPayloadSize = 4;
@@ -134,37 +133,19 @@ const size_t SpdyFramer::kControlFrameBufferSize = 19;
} while (false)
#endif
-SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(
- SpdyMajorVersion version, uint32 wire) {
- if (version < SPDY3) {
- ConvertFlagsAndIdForSpdy2(&wire);
- }
- return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
+SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(SpdyMajorVersion version,
+ uint32_t wire) {
+ return SettingsFlagsAndId(base::NetToHost32(wire) >> 24,
+ base::NetToHost32(wire) & 0x00ffffff);
}
-SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
+SettingsFlagsAndId::SettingsFlagsAndId(uint8_t flags, uint32_t id)
: flags_(flags), id_(id & 0x00ffffff) {
LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id;
}
-uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version)
- const {
- uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
- if (version < SPDY3) {
- ConvertFlagsAndIdForSpdy2(&wire);
- }
- return wire;
-}
-
-// SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
-// This method is used to preserve buggy behavior and works on both
-// little-endian and big-endian hosts.
-// This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
-// as well as vice versa).
-void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
- uint8* wire_array = reinterpret_cast<uint8*>(val);
- std::swap(wire_array[0], wire_array[3]);
- std::swap(wire_array[1], wire_array[2]);
+uint32_t SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version) const {
+ return base::HostToNet32(id_ & 0x00ffffff) | base::HostToNet32(flags_ << 24);
}
bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data,
@@ -188,8 +169,7 @@ SpdyFramer::SpdyFramer(SpdyMajorVersion version)
enable_compression_(true),
syn_frame_processed_(false),
probable_http_response_(false),
- end_stream_when_done_(false),
- header_table_size_bound_(4096) {
+ end_stream_when_done_(false) {
DCHECK_GE(protocol_version_, SPDY_MIN_VERSION);
DCHECK_LE(protocol_version_, SPDY_MAX_VERSION);
DCHECK_LE(kMaxControlFrameSize,
@@ -238,7 +218,7 @@ size_t SpdyFramer::GetSynStreamMinimumSize() const {
if (protocol_version() <= SPDY3) {
// Calculated as:
// control frame header + 2 * 4 (stream IDs) + 1 (priority)
- // + 1 (unused, was credential slot)
+ // + 1 (unused)
return GetControlFrameHeaderSize() + 10;
} else {
return GetControlFrameHeaderSize() +
@@ -257,11 +237,6 @@ size_t SpdyFramer::GetSynReplyMinimumSize() const {
size += 4;
}
- // In SPDY 2, there were 2 unused bytes before payload.
- if (protocol_version() < SPDY3) {
- size += 2;
- }
-
return size;
}
@@ -310,10 +285,8 @@ size_t SpdyFramer::GetGoAwayMinimumSize() const {
// 2. Last good stream id (4 bytes)
size += 4;
- // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes)
- if (protocol_version() >= SPDY3) {
- size += 4;
- }
+ // 3. GOAWAY frames also contain a status (4 bytes)
+ size += 4;
return size;
}
@@ -328,11 +301,6 @@ size_t SpdyFramer::GetHeadersMinimumSize() const {
size += 4;
}
- // In SPDY 2, there were 2 unused bytes before payload.
- if (protocol_version() <= SPDY2) {
- size += 2;
- }
-
return size;
}
@@ -498,8 +466,6 @@ const char* SpdyFramer::StatusCodeToString(int status_code) {
return "STREAM_IN_USE";
case RST_STREAM_STREAM_ALREADY_CLOSED:
return "STREAM_ALREADY_CLOSED";
- case RST_STREAM_INVALID_CREDENTIALS:
- return "INVALID_CREDENTIALS";
case RST_STREAM_FRAME_TOO_LARGE:
return "FRAME_TOO_LARGE";
case RST_STREAM_CONNECT_ERROR:
@@ -534,8 +500,6 @@ const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) {
return "HEADERS";
case WINDOW_UPDATE:
return "WINDOW_UPDATE";
- case CREDENTIAL:
- return "CREDENTIAL";
case PUSH_PROMISE:
return "PUSH_PROMISE";
case CONTINUATION:
@@ -745,7 +709,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
// correct value if this is a valid control frame.
current_frame_type_ = DATA;
if (protocol_version() <= SPDY3) {
- uint16 version = 0;
+ uint16_t version = 0;
bool successful_read = reader.ReadUInt16(&version);
DCHECK(successful_read);
is_control_frame = (version & kControlFlagMask) != 0;
@@ -765,7 +729,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
}
// We check control_frame_type_field's validity in
// ProcessControlFrameHeader().
- uint16 control_frame_type_field_uint16;
+ uint16_t control_frame_type_field_uint16;
successful_read = reader.ReadUInt16(&control_frame_type_field_uint16);
control_frame_type_field = control_frame_type_field_uint16;
} else {
@@ -777,17 +741,17 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
successful_read = reader.ReadUInt8(&current_frame_flags_);
DCHECK(successful_read);
- uint32 length_field = 0;
+ uint32_t length_field = 0;
successful_read = reader.ReadUInt24(&length_field);
DCHECK(successful_read);
remaining_data_length_ = length_field;
current_frame_length_ = remaining_data_length_ + reader.GetBytesConsumed();
} else {
- uint32 length_field = 0;
+ uint32_t length_field = 0;
bool successful_read = reader.ReadUInt24(&length_field);
DCHECK(successful_read);
- uint8 control_frame_type_field_uint8;
+ uint8_t control_frame_type_field_uint8;
successful_read = reader.ReadUInt8(&control_frame_type_field_uint8);
DCHECK(successful_read);
// We check control_frame_type_field's validity in
@@ -855,7 +819,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
<< "DATA frame too large for SPDY >= 4.";
}
- uint8 valid_data_flags = 0;
+ uint8_t valid_data_flags = 0;
if (protocol_version() > SPDY3) {
valid_data_flags =
DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED;
@@ -891,19 +855,6 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) {
DCHECK_EQ(SPDY_NO_ERROR, error_code_);
DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_.len());
- // TODO(mlavan): Either remove credential frames from the code entirely,
- // or add them to parsing + serialization methods for SPDY3.
- // Early detection of deprecated frames that we ignore.
- if (protocol_version() <= SPDY3) {
- if (control_frame_type_field == CREDENTIAL) {
- current_frame_type_ = CREDENTIAL;
- DCHECK_EQ(SPDY3, protocol_version());
- DVLOG(1) << "CREDENTIAL control frame found. Ignoring.";
- CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
- return;
- }
- }
-
if (!SpdyConstants::IsValidFrameType(protocol_version(),
control_frame_type_field)) {
if (protocol_version() <= SPDY3) {
@@ -954,9 +905,8 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) {
}
break;
case RST_STREAM:
- // For SPDY versions < 4, the header has a fixed length.
- // For SPDY version 4 and up, the RST_STREAM frame may include optional
- // opaque data, so we only have a lower limit on the frame size.
+ // TODO(bnc): Enforce the length of the header, and change error to
+ // FRAME_SIZE_ERROR.
if ((current_frame_length_ != GetRstStreamMinimumSize() &&
protocol_version() <= SPDY3) ||
(current_frame_length_ < GetRstStreamMinimumSize() &&
@@ -1132,7 +1082,7 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) {
return;
}
// Determine the frame size without variable-length data.
- int32 frame_size_without_variable_data;
+ int32_t frame_size_without_variable_data;
switch (current_frame_type_) {
case SYN_STREAM:
syn_frame_processed_ = true;
@@ -1190,7 +1140,7 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) {
// remainder of the control frame's header before we can parse the header
// block. The start of the header block varies with the control type.
DCHECK_GE(frame_size_without_variable_data,
- static_cast<int32>(current_frame_buffer_.len()));
+ static_cast<int32_t>(current_frame_buffer_.len()));
remaining_control_header_ =
frame_size_without_variable_data - current_frame_buffer_.len();
@@ -1215,8 +1165,7 @@ size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
size_t SpdyFramer::GetSerializedLength(
const SpdyMajorVersion spdy_version,
const SpdyHeaderBlock* headers) {
- const size_t num_name_value_pairs_size
- = (spdy_version < SPDY3) ? sizeof(uint16) : sizeof(uint32);
+ const size_t num_name_value_pairs_size = sizeof(uint32_t);
const size_t length_of_name_size = num_name_value_pairs_size;
const size_t length_of_value_size = num_name_value_pairs_size;
@@ -1233,20 +1182,11 @@ size_t SpdyFramer::GetSerializedLength(
void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
const SpdyMajorVersion spdy_version,
const SpdyHeaderBlock* headers) {
- if (spdy_version < SPDY3) {
- frame->WriteUInt16(static_cast<uint16>(headers->size()));
- } else {
- frame->WriteUInt32(headers->size());
- }
+ frame->WriteUInt32(headers->size());
SpdyHeaderBlock::const_iterator it;
for (it = headers->begin(); it != headers->end(); ++it) {
- if (spdy_version < SPDY3) {
- frame->WriteStringPiece16(it->first);
- frame->WriteStringPiece16(it->second);
- } else {
- frame->WriteStringPiece32(it->first);
- frame->WriteStringPiece32(it->second);
- }
+ frame->WriteStringPiece32(it->first);
+ frame->WriteStringPiece32(it->second);
}
}
@@ -1324,10 +1264,7 @@ static void WriteLengthZ(size_t n,
// cookie data.
void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
z_stream* z) const {
- unsigned length_length = 4;
- if (protocol_version() < 3)
- length_length = 2;
-
+ const size_t length_length = 4;
WriteLengthZ(headers->size(), length_length, kZStandardData, z);
SpdyHeaderBlock::const_iterator it;
@@ -1460,13 +1397,9 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
SpdyPriority priority = 0;
successful_read = reader.ReadUInt8(&priority);
DCHECK(successful_read);
- if (protocol_version() <= SPDY2) {
- priority = priority >> 6;
- } else {
- priority = priority >> 5;
- }
+ priority = priority >> 5;
- // Seek past unused byte; used to be credential slot in SPDY 3.
+ // Seek past unused byte.
reader.Seek(1);
DCHECK(reader.IsDoneReading());
@@ -1512,10 +1445,6 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
set_error(SPDY_INVALID_CONTROL_FRAME);
break;
}
- if (protocol_version() <= SPDY2) {
- // SPDY 2 had two unused bytes here. Seek past them.
- reader.Seek(2);
- }
if (protocol_version() > SPDY3 &&
!(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) &&
current_frame_type_ == HEADERS) {
@@ -1524,7 +1453,7 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
}
if (protocol_version() > SPDY3 &&
current_frame_flags_ & HEADERS_FLAG_PADDED) {
- uint8 pad_payload_len = 0;
+ uint8_t pad_payload_len = 0;
DCHECK_EQ(remaining_padding_payload_length_, 0u);
successful_read = reader.ReadUInt8(&pad_payload_len);
DCHECK(successful_read);
@@ -1533,16 +1462,16 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
const bool has_priority =
(current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
SpdyPriority priority = 0;
- uint32 parent_stream_id = 0;
+ uint32_t parent_stream_id = 0;
bool exclusive = false;
if (protocol_version() > SPDY3 && has_priority) {
- uint32 stream_dependency;
+ uint32_t stream_dependency;
successful_read = reader.ReadUInt32(&stream_dependency);
DCHECK(successful_read);
UnpackStreamDependencyValues(stream_dependency, &exclusive,
&parent_stream_id);
- uint8 weight = 0;
+ uint8_t weight = 0;
successful_read = reader.ReadUInt8(&weight);
if (successful_read) {
priority = MapWeightToPriority(weight);
@@ -1581,7 +1510,7 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
if (protocol_version() > SPDY3 &&
current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) {
DCHECK_EQ(remaining_padding_payload_length_, 0u);
- uint8 pad_payload_len = 0;
+ uint8_t pad_payload_len = 0;
successful_read = reader.ReadUInt8(&pad_payload_len);
DCHECK(successful_read);
remaining_padding_payload_length_ = pad_payload_len;
@@ -1665,8 +1594,8 @@ size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
size_t process_bytes = std::min(
data_len, remaining_data_length_ - remaining_padding_payload_length_);
if (is_hpack_header_block) {
- if (!GetHpackDecoder()->HandleControlFrameHeadersData(
- current_frame_stream_id_, data, process_bytes)) {
+ if (!GetHpackDecoder()->HandleControlFrameHeadersData(data,
+ process_bytes)) {
// TODO(jgraettinger): Finer-grained HPACK error codes.
set_error(SPDY_DECOMPRESS_FAILURE);
processed_successfully = false;
@@ -1689,7 +1618,7 @@ size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
if (is_hpack_header_block) {
size_t compressed_len = 0;
if (GetHpackDecoder()->HandleControlFrameHeadersComplete(
- current_frame_stream_id_, &compressed_len)) {
+ &compressed_len)) {
// TODO(jgraettinger): To be removed with migration to
// SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
// block, delivered via reentrant call to
@@ -1809,21 +1738,22 @@ void SpdyFramer::DeliverHpackBlockAsSpdy3Block(size_t compressed_len) {
bool SpdyFramer::ProcessSetting(const char* data) {
int id_field;
SpdySettingsIds id;
- uint8 flags = 0;
- uint32 value;
+ uint8_t flags = 0;
+ uint32_t value;
// Extract fields.
// Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
if (protocol_version() <= SPDY3) {
- const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
+ const uint32_t id_and_flags_wire =
+ *(reinterpret_cast<const uint32_t*>(data));
SettingsFlagsAndId id_and_flags =
SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire);
id_field = id_and_flags.id();
flags = id_and_flags.flags();
- value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
+ value = base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data + 4)));
} else {
- id_field = ntohs(*(reinterpret_cast<const uint16*>(data)));
- value = ntohl(*(reinterpret_cast<const uint32*>(data + 2)));
+ id_field = base::NetToHost16(*(reinterpret_cast<const uint16_t*>(data)));
+ value = base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data + 2)));
}
// Validate id.
@@ -1850,7 +1780,7 @@ bool SpdyFramer::ProcessSetting(const char* data) {
settings_scratch_.last_setting_id = id;
// Validate flags.
- uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
+ uint8_t kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
if ((flags & ~(kFlagsMask)) != 0) {
DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
<< flags;
@@ -1881,7 +1811,7 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
(current_frame_flags_ & PING_FLAG_ACK);
bool successful_read = true;
if (protocol_version() <= SPDY3) {
- uint32 id32 = 0;
+ uint32_t id32 = 0;
successful_read = reader.ReadUInt32(&id32);
id = id32;
} else {
@@ -1893,7 +1823,7 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
}
break;
case WINDOW_UPDATE: {
- uint32 delta_window_size = 0;
+ uint32_t delta_window_size = 0;
bool successful_read = true;
if (protocol_version() <= SPDY3) {
successful_read = reader.ReadUInt31(&current_frame_stream_id_);
@@ -1914,10 +1844,10 @@ size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
break;
case PRIORITY: {
DCHECK_LT(SPDY3, protocol_version());
- uint32 stream_dependency;
- uint32 parent_stream_id;
+ uint32_t stream_dependency;
+ uint32_t parent_stream_id;
bool exclusive;
- uint8 weight;
+ uint8_t weight;
bool successful_read = reader.ReadUInt32(&stream_dependency);
DCHECK(successful_read);
UnpackStreamDependencyValues(stream_dependency, &exclusive,
@@ -1970,7 +1900,7 @@ size_t SpdyFramer::ProcessGoAwayFramePayload(const char* data, size_t len) {
// In SPDYv3 and up, frames also specify a status code - parse it out.
SpdyGoAwayStatus status = GOAWAY_OK;
if (protocol_version() >= SPDY3) {
- uint32 status_raw = GOAWAY_OK;
+ uint32_t status_raw = GOAWAY_OK;
successful_read = reader.ReadUInt32(&status_raw);
DCHECK(successful_read);
if (SpdyConstants::IsValidGoAwayStatus(protocol_version(),
@@ -2037,7 +1967,7 @@ size_t SpdyFramer::ProcessRstStreamFramePayload(const char* data, size_t len) {
}
SpdyRstStreamStatus status = RST_STREAM_INVALID;
- uint32 status_raw = status;
+ uint32_t status_raw = status;
bool successful_read = reader.ReadUInt32(&status_raw);
DCHECK(successful_read);
if (SpdyConstants::IsValidRstStreamStatus(protocol_version(),
@@ -2128,7 +2058,8 @@ size_t SpdyFramer::ProcessDataFramePaddingLength(const char* data, size_t len) {
static_assert(kPadLengthFieldSize == 1,
"Unexpected pad length field size.");
- remaining_padding_payload_length_ = *reinterpret_cast<const uint8*>(data);
+ remaining_padding_payload_length_ =
+ *reinterpret_cast<const uint8_t*>(data);
++data;
--len;
--remaining_data_length_;
@@ -2217,46 +2148,35 @@ size_t SpdyFramer::ProcessIgnoredControlFramePayload(/*const char* data,*/
return original_len - len;
}
-size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
+bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
size_t header_length,
SpdyHeaderBlock* block) const {
SpdyFrameReader reader(header_data, header_length);
// Read number of headers.
- uint32 num_headers;
- if (protocol_version() <= SPDY2) {
- uint16 temp;
- if (!reader.ReadUInt16(&temp)) {
- DVLOG(1) << "Unable to read number of headers.";
- return 0;
- }
- num_headers = temp;
- } else {
- if (!reader.ReadUInt32(&num_headers)) {
- DVLOG(1) << "Unable to read number of headers.";
- return 0;
- }
+ uint32_t num_headers;
+ if (!reader.ReadUInt32(&num_headers)) {
+ DVLOG(1) << "Unable to read number of headers.";
+ return false;
}
// Read each header.
- for (uint32 index = 0; index < num_headers; ++index) {
+ for (uint32_t index = 0; index < num_headers; ++index) {
base::StringPiece temp;
// Read header name.
- if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
- : !reader.ReadStringPiece32(&temp)) {
+ if (!reader.ReadStringPiece32(&temp)) {
DVLOG(1) << "Unable to read header name (" << index + 1 << " of "
<< num_headers << ").";
- return 0;
+ return false;
}
std::string name = temp.as_string();
// Read header value.
- if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
- : !reader.ReadStringPiece32(&temp)) {
+ if (!reader.ReadStringPiece32(&temp)) {
DVLOG(1) << "Unable to read header value (" << index + 1 << " of "
<< num_headers << ").";
- return 0;
+ return false;
}
std::string value = temp.as_string();
@@ -2264,18 +2184,25 @@ size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
if (block->find(name) != block->end()) {
DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of "
<< num_headers << ").";
- return 0;
+ return false;
}
// Store header.
(*block)[name] = value;
}
- return reader.GetBytesConsumed();
+ if (reader.GetBytesConsumed() != header_length) {
+ LOG(DFATAL) << "Buffer expected to consist entirely of headers, but only "
+ << reader.GetBytesConsumed() << " bytes consumed, from "
+ << header_length;
+ return false;
+ }
+
+ return true;
}
SpdySerializedFrame* SpdyFramer::SerializeData(
const SpdyDataIR& data_ir) const {
- uint8 flags = DATA_FLAG_NONE;
+ uint8_t flags = DATA_FLAG_NONE;
if (data_ir.fin()) {
flags = DATA_FLAG_FIN;
}
@@ -2314,7 +2241,7 @@ SpdySerializedFrame* SpdyFramer::SerializeData(
SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
const SpdyDataIR& data_ir) const {
- uint8 flags = DATA_FLAG_NONE;
+ uint8_t flags = DATA_FLAG_NONE;
if (data_ir.fin()) {
flags = DATA_FLAG_FIN;
}
@@ -2347,7 +2274,7 @@ SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
SpdySerializedFrame* SpdyFramer::SerializeSynStream(
const SpdySynStreamIR& syn_stream) {
DCHECK_GE(SPDY3, protocol_version());
- uint8 flags = 0;
+ uint8_t flags = 0;
if (syn_stream.fin()) {
flags |= CONTROL_FLAG_FIN;
}
@@ -2357,7 +2284,7 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream(
}
// Sanitize priority.
- uint8 priority = syn_stream.priority();
+ uint8_t priority = syn_stream.priority();
if (priority > GetLowestPriority()) {
DLOG(DFATAL) << "Priority out-of-bounds.";
priority = GetLowestPriority();
@@ -2371,8 +2298,8 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream(
builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
builder.WriteUInt32(syn_stream.stream_id());
builder.WriteUInt32(syn_stream.associated_to_stream_id());
- builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5));
- builder.WriteUInt8(0); // Unused byte where credential slot used to be.
+ builder.WriteUInt8(priority << 5);
+ builder.WriteUInt8(0); // Unused byte.
DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
SerializeHeaderBlock(&builder, syn_stream);
@@ -2391,7 +2318,7 @@ SpdySerializedFrame* SpdyFramer::SerializeSynStream(
SpdySerializedFrame* SpdyFramer::SerializeSynReply(
const SpdySynReplyIR& syn_reply) {
DCHECK_GE(SPDY3, protocol_version());
- uint8 flags = 0;
+ uint8_t flags = 0;
if (syn_reply.fin()) {
flags |= CONTROL_FLAG_FIN;
}
@@ -2410,9 +2337,6 @@ SpdySerializedFrame* SpdyFramer::SerializeSynReply(
flags,
syn_reply.stream_id());
}
- if (protocol_version() < SPDY3) {
- builder.WriteUInt16(0); // Unused.
- }
DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
SerializeHeaderBlock(&builder, syn_reply);
@@ -2436,9 +2360,6 @@ SpdySerializedFrame* SpdyFramer::SerializeRstStream(
// commented but left in place to simplify future patching.
// Compute the output buffer size, taking opaque data into account.
size_t expected_length = GetRstStreamMinimumSize();
- if (protocol_version() > SPDY3) {
- expected_length += rst_stream.description().size();
- }
SpdyFrameBuilder builder(expected_length, protocol_version());
// Serialize the RST_STREAM frame.
@@ -2452,19 +2373,13 @@ SpdySerializedFrame* SpdyFramer::SerializeRstStream(
builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus(
protocol_version(), rst_stream.status()));
- // In HTTP2 and up, RST_STREAM frames may also specify opaque data.
- if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
- builder.WriteBytes(rst_stream.description().data(),
- rst_stream.description().size());
- }
-
DCHECK_EQ(expected_length, builder.length());
return builder.take();
}
SpdySerializedFrame* SpdyFramer::SerializeSettings(
const SpdySettingsIR& settings) const {
- uint8 flags = 0;
+ uint8_t flags = 0;
if (protocol_version() <= SPDY3) {
if (settings.clear_settings()) {
@@ -2504,7 +2419,7 @@ SpdySerializedFrame* SpdyFramer::SerializeSettings(
SpdyConstants::SerializeSettingId(protocol_version(), it->first);
DCHECK_GE(setting_id, 0);
if (protocol_version() <= SPDY3) {
- uint8 setting_flags = 0;
+ uint8_t setting_flags = 0;
if (it->second.persist_value) {
setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST;
}
@@ -2512,10 +2427,11 @@ SpdySerializedFrame* SpdyFramer::SerializeSettings(
setting_flags |= SETTINGS_FLAG_PERSISTED;
}
SettingsFlagsAndId flags_and_id(setting_flags, setting_id);
- uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version());
+ uint32_t id_and_flags_wire =
+ flags_and_id.GetWireFormat(protocol_version());
builder.WriteBytes(&id_and_flags_wire, 4);
} else {
- builder.WriteUInt16(static_cast<uint16>(setting_id));
+ builder.WriteUInt16(static_cast<uint16_t>(setting_id));
}
builder.WriteUInt32(it->second.value);
}
@@ -2527,9 +2443,9 @@ SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
SpdyFrameBuilder builder(GetPingSize(), protocol_version());
if (protocol_version() <= SPDY3) {
builder.WriteControlFrameHeader(*this, PING, kNoFlags);
- builder.WriteUInt32(static_cast<uint32>(ping.id()));
+ builder.WriteUInt32(static_cast<uint32_t>(ping.id()));
} else {
- uint8 flags = 0;
+ uint8_t flags = 0;
if (ping.is_ack()) {
flags |= PING_FLAG_ACK;
}
@@ -2560,7 +2476,7 @@ SpdySerializedFrame* SpdyFramer::SerializeGoAway(
// GOAWAY frames specify the last good stream id for all SPDY versions.
builder.WriteUInt32(goaway.last_good_stream_id());
- // In SPDY3 and up, GOAWAY frames also specify the error status code.
+ // GOAWAY frames also specify the error status code.
if (protocol_version() >= SPDY3) {
// TODO(jgraettinger): Merge back to server-side.
builder.WriteUInt32(SpdyConstants::SerializeGoAwayStatus(protocol_version(),
@@ -2579,7 +2495,7 @@ SpdySerializedFrame* SpdyFramer::SerializeGoAway(
SpdySerializedFrame* SpdyFramer::SerializeHeaders(
const SpdyHeadersIR& headers) {
- uint8 flags = 0;
+ uint8_t flags = 0;
if (headers.fin()) {
flags |= CONTROL_FLAG_FIN;
}
@@ -2641,9 +2557,6 @@ SpdySerializedFrame* SpdyFramer::SerializeHeaders(
flags,
headers.stream_id());
}
- if (protocol_version() <= SPDY2) {
- builder.WriteUInt16(0); // Unused.
- }
DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
if (protocol_version() > SPDY3) {
@@ -2708,7 +2621,7 @@ SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
SpdyFrame* SpdyFramer::SerializePushPromise(
const SpdyPushPromiseIR& push_promise) {
DCHECK_LT(SPDY3, protocol_version());
- uint8 flags = 0;
+ uint8_t flags = 0;
// This will get overwritten if we overflow into a CONTINUATION frame.
flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
// The size of this frame, including variable-length name-value block.
@@ -2780,7 +2693,7 @@ SpdyFrame* SpdyFramer::SerializePushPromise(
SpdyFrame* SpdyFramer::SerializeContinuation(
const SpdyContinuationIR& continuation) {
CHECK_LT(SPDY3, protocol_version());
- uint8 flags = 0;
+ uint8_t flags = 0;
if (continuation.end_headers()) {
flags |= HEADERS_FLAG_END_HEADERS;
}
@@ -2931,8 +2844,8 @@ void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
SpdyStreamId stream_id,
SpdyFrameType type,
int padding_payload_len) {
- uint8 end_flag = 0;
- uint8 flags = 0;
+ uint8_t end_flag = 0;
+ uint8_t flags = 0;
if (type == HEADERS) {
end_flag = HEADERS_FLAG_END_HEADERS;
} else if (type == PUSH_PROMISE) {
@@ -3006,10 +2919,8 @@ z_stream* SpdyFramer::GetHeaderCompressor() {
kCompressorMemLevel,
Z_DEFAULT_STRATEGY);
if (success == Z_OK) {
- const char* dictionary = (protocol_version() <= SPDY2) ?
- kV2Dictionary : kV3Dictionary;
- const int dictionary_size = (protocol_version() <= SPDY2) ?
- kV2DictionarySize : kV3DictionarySize;
+ const char* dictionary = kV3Dictionary;
+ const int dictionary_size = kV3DictionarySize;
success = deflateSetDictionary(header_compressor_.get(),
reinterpret_cast<const Bytef*>(dictionary),
dictionary_size);
@@ -3050,17 +2961,17 @@ HpackEncoder* SpdyFramer::GetHpackEncoder() {
HpackDecoder* SpdyFramer::GetHpackDecoder() {
DCHECK_LT(SPDY3, protocol_version());
if (hpack_decoder_.get() == nullptr) {
- hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
+ hpack_decoder_.reset(new HpackDecoder());
}
return hpack_decoder_.get();
}
-uint8 SpdyFramer::MapPriorityToWeight(SpdyPriority priority) {
+uint8_t SpdyFramer::MapPriorityToWeight(SpdyPriority priority) {
const float kSteps = 255.9f / 7.f;
- return static_cast<uint8>(kSteps * (7.f - priority));
+ return static_cast<uint8_t>(kSteps * (7.f - priority));
}
-SpdyPriority SpdyFramer::MapWeightToPriority(uint8 weight) {
+SpdyPriority SpdyFramer::MapWeightToPriority(uint8_t weight) {
const float kSteps = 255.9f / 7.f;
return static_cast<SpdyPriority>(7.f - weight / kSteps);
}
@@ -3096,13 +3007,10 @@ bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
int rv = inflate(decomp, Z_SYNC_FLUSH);
if (rv == Z_NEED_DICT) {
- const char* dictionary = (protocol_version() <= SPDY2) ? kV2Dictionary
- : kV3Dictionary;
- const int dictionary_size = (protocol_version() <= SPDY2) ?
- kV2DictionarySize : kV3DictionarySize;
+ const char* dictionary = kV3Dictionary;
+ const int dictionary_size = kV3DictionarySize;
const DictionaryIds& ids = g_dictionary_ids.Get();
- const uLong dictionary_id = (protocol_version() <= SPDY2) ?
- ids.v2_dictionary_id : ids.v3_dictionary_id;
+ const uLong dictionary_id = ids.v3_dictionary_id;
// Need to try again with the right dictionary.
if (decomp->adler == dictionary_id) {
rv = inflateSetDictionary(decomp,
@@ -3157,36 +3065,28 @@ bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
return read_successfully;
}
-void SpdyFramer::UpdateHeaderTableSizeSetting(uint32 value) {
- header_table_size_bound_ = value;
+void SpdyFramer::UpdateHeaderEncoderTableSize(uint32_t value) {
GetHpackEncoder()->ApplyHeaderTableSizeSetting(value);
- GetHpackDecoder()->ApplyHeaderTableSizeSetting(value);
}
-// Return size bound of the header compression table.
-size_t SpdyFramer::header_table_size_bound() const {
- return header_table_size_bound_;
+size_t SpdyFramer::header_encoder_table_size() const {
+ if (hpack_encoder_ == nullptr) {
+ return kDefaultHeaderTableSizeSetting;
+ } else {
+ return hpack_encoder_->CurrentHeaderTableSizeSetting();
+ }
}
void SpdyFramer::SerializeHeaderBlockWithoutCompression(
SpdyFrameBuilder* builder,
const SpdyHeaderBlock& header_block) const {
// Serialize number of headers.
- if (protocol_version() <= SPDY2) {
- builder->WriteUInt16(static_cast<uint16>(header_block.size()));
- } else {
- builder->WriteUInt32(header_block.size());
- }
+ builder->WriteUInt32(header_block.size());
// Serialize each header.
for (const auto& header : header_block) {
- if (protocol_version() <= SPDY2) {
- builder->WriteStringPiece16(header.first);
- builder->WriteStringPiece16(header.second);
- } else {
- builder->WriteStringPiece32(header.first);
- builder->WriteStringPiece32(header.second);
- }
+ builder->WriteStringPiece32(header.first);
+ builder->WriteStringPiece32(header.second);
}
}
diff --git a/chromium/net/spdy/spdy_framer.h b/chromium/net/spdy/spdy_framer.h
index e3cabbce114..5f3ff2a2cc3 100644
--- a/chromium/net/spdy/spdy_framer.h
+++ b/chromium/net/spdy/spdy_framer.h
@@ -5,6 +5,9 @@
#ifndef NET_SPDY_SPDY_FRAMER_H_
#define NET_SPDY_SPDY_FRAMER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <memory>
#include <string>
@@ -20,8 +23,6 @@
#include "net/spdy/spdy_header_block.h"
#include "net/spdy/spdy_protocol.h"
-// TODO(akalin): Remove support for CREDENTIAL frames.
-
typedef struct z_stream_s z_stream; // Forward declaration for zlib.
namespace net {
@@ -50,27 +51,25 @@ class SpdyFramerPeer;
class NET_EXPORT_PRIVATE SettingsFlagsAndId {
public:
static SettingsFlagsAndId FromWireFormat(SpdyMajorVersion version,
- uint32 wire);
+ uint32_t wire);
SettingsFlagsAndId() : flags_(0), id_(0) {}
// TODO(hkhalil): restrict to enums instead of free-form ints.
- SettingsFlagsAndId(uint8 flags, uint32 id);
+ SettingsFlagsAndId(uint8_t flags, uint32_t id);
- uint32 GetWireFormat(SpdyMajorVersion version) const;
+ uint32_t GetWireFormat(SpdyMajorVersion version) const;
- uint32 id() const { return id_; }
- uint8 flags() const { return flags_; }
+ uint32_t id() const { return id_; }
+ uint8_t flags() const { return flags_; }
private:
- static void ConvertFlagsAndIdForSpdy2(uint32* val);
-
- uint8 flags_;
- uint32 id_;
+ uint8_t flags_;
+ uint32_t id_;
};
// SettingsMap has unique (flags, value) pair for given SpdySettingsIds ID.
-typedef std::pair<SpdySettingsFlags, uint32> SettingsFlagsAndValue;
+typedef std::pair<SpdySettingsFlags, uint32_t> SettingsFlagsAndValue;
typedef std::map<SpdySettingsIds, SettingsFlagsAndValue> SettingsMap;
// SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer.
@@ -125,6 +124,20 @@ class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface {
// |len| The number of padding octets.
virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0;
+ // Called just before processing the payload of a frame containing header
+ // data. Should return an implementation of SpdyHeadersHandlerInterface that
+ // will receive headers for stream |stream_id|. The caller will not take
+ // ownership of the headers handler. The same instance should be returned
+ // for all header frames comprising a logical header block (i.e. until
+ // OnHeaderFrameEnd() is called with end_headers == true).
+ virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) = 0;
+
+ // Called after processing the payload of a frame containing header data.
+ // |end_headers| is true if there will not be any subsequent CONTINUATION
+ // frames.
+ virtual void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) = 0;
+
// Called when a chunk of header data is available. This is called
// after OnSynStream, OnSynReply, OnHeaders(), or OnPushPromise.
// |stream_id| The stream receiving the header data.
@@ -162,7 +175,7 @@ class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface {
// Called when a complete setting within a SETTINGS frame has been parsed and
// validated.
- virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
+ virtual void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) = 0;
// Called when a SETTINGS frame is received with the ACK flag set.
virtual void OnSettingsAck() {}
@@ -248,7 +261,7 @@ class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface {
// Called when a PRIORITY frame is received.
virtual void OnPriority(SpdyStreamId stream_id,
SpdyStreamId parent_stream_id,
- uint8 weight,
+ uint8_t weight,
bool exclusive) {}
// Called when a frame type we don't recognize is received.
@@ -390,8 +403,8 @@ class NET_EXPORT_PRIVATE SpdyFramer {
// Given a buffer containing a decompressed header block in SPDY
// serialized format, parse out a SpdyHeaderBlock, putting the results
// in the given header block.
- // Returns number of bytes consumed if successfully parsed, 0 otherwise.
- size_t ParseHeaderBlockInBuffer(const char* header_data,
+ // Returns true if successfully parsed, false otherwise.
+ bool ParseHeaderBlockInBuffer(const char* header_data,
size_t header_length,
SpdyHeaderBlock* block) const;
@@ -533,16 +546,14 @@ class NET_EXPORT_PRIVATE SpdyFramer {
bool probable_http_response() const { return probable_http_response_; }
- SpdyPriority GetLowestPriority() const {
- return protocol_version_ < SPDY3 ? 3 : 7;
- }
+ SpdyPriority GetLowestPriority() const { return 7; }
SpdyPriority GetHighestPriority() const { return 0; }
// Interpolates SpdyPriority values into SPDY4/HTTP2 priority weights,
// and vice versa.
- static uint8 MapPriorityToWeight(SpdyPriority priority);
- static SpdyPriority MapWeightToPriority(uint8 weight);
+ static uint8_t MapPriorityToWeight(SpdyPriority priority);
+ static SpdyPriority MapWeightToPriority(uint8_t weight);
// Deliver the given control frame's compressed headers block to the visitor
// in decompressed form, in chunks. Returns true if the visitor has
@@ -552,11 +563,11 @@ class NET_EXPORT_PRIVATE SpdyFramer {
const char* data,
size_t len);
- // Updates the maximum size of header compression table.
- void UpdateHeaderTableSizeSetting(uint32 value);
+ // Updates the maximum size of the header encoder compression table.
+ void UpdateHeaderEncoderTableSize(uint32_t value);
- // Returns bound of header compression table size.
- size_t header_table_size_bound() const;
+ // Returns the maximum size of the header encoder compression table.
+ size_t header_encoder_table_size() const;
protected:
friend class HttpNetworkLayer; // This is temporary for the server.
@@ -720,7 +731,7 @@ class NET_EXPORT_PRIVATE SpdyFramer {
SpdyFrameType current_frame_type_;
// The total length of the frame currently being read, including frame header.
- uint32 current_frame_length_;
+ uint32_t current_frame_length_;
// The stream ID field of the frame currently being read, if applicable.
SpdyStreamId current_frame_stream_id_;
@@ -754,7 +765,7 @@ class NET_EXPORT_PRIVATE SpdyFramer {
const SpdyMajorVersion protocol_version_;
// The flags field of the frame currently being read.
- uint8 current_frame_flags_;
+ uint8_t current_frame_flags_;
// Determines whether HPACK or gzip compression is used.
bool enable_compression_;
@@ -783,9 +794,6 @@ class NET_EXPORT_PRIVATE SpdyFramer {
// If true, then ProcessInput returns after processing a full frame,
// rather than reading all available input.
bool process_single_input_frame_ = false;
-
- // Last acknowledged value for SETTINGS_HEADER_TABLE_SIZE.
- size_t header_table_size_bound_;
};
} // namespace net
diff --git a/chromium/net/spdy/spdy_framer_test.cc b/chromium/net/spdy/spdy_framer_test.cc
index c7785e7bd3d..ac971373de9 100644
--- a/chromium/net/spdy/spdy_framer_test.cc
+++ b/chromium/net/spdy/spdy_framer_test.cc
@@ -14,6 +14,7 @@
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/spdy/hpack/hpack_constants.h"
#include "net/spdy/mock_spdy_framer_visitor.h"
@@ -24,6 +25,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/platform_test.h"
+using base::StringPiece;
using std::string;
using testing::_;
@@ -99,6 +101,16 @@ class SpdyFramerTestUtil {
LOG(FATAL);
}
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override {
+ LOG(FATAL);
+ return nullptr;
+ }
+
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override {
+ LOG(FATAL);
+ }
+
bool OnControlFrameHeaderData(SpdyStreamId stream_id,
const char* header_data,
size_t len) override {
@@ -148,7 +160,7 @@ class SpdyFramerTestUtil {
SpdyRstStreamStatus status) override {
LOG(FATAL);
}
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override {
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {
LOG(FATAL);
}
void OnPing(SpdyPingId unique_id, bool is_ack) override { LOG(FATAL); }
@@ -202,7 +214,7 @@ class SpdyFramerTestUtil {
void OnPriority(SpdyStreamId stream_id,
SpdyStreamId parent_stream_id,
- uint8 weight,
+ uint8_t weight,
bool exclusive) override {
// Do nothing.
}
@@ -319,6 +331,16 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
LOG(INFO) << "OnStreamPadding(" << stream_id << ", " << len << ")\n";
}
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override {
+ LOG(FATAL);
+ return nullptr;
+ }
+
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override {
+ LOG(FATAL);
+ }
+
bool OnControlFrameHeaderData(SpdyStreamId stream_id,
const char* header_data,
size_t len) override {
@@ -329,12 +351,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
// Indicates end-of-header-block.
headers_.clear();
CHECK(header_buffer_valid_);
- size_t parsed_length = framer_.ParseHeaderBlockInBuffer(
- header_buffer_.get(), header_buffer_length_, &headers_);
- LOG_IF(DFATAL, header_buffer_length_ != parsed_length)
- << "Check failed: header_buffer_length_ == parsed_length "
- << "(" << header_buffer_length_ << " vs. " << parsed_length << ")";
- return true;
+ return framer_.ParseHeaderBlockInBuffer(header_buffer_.get(),
+ header_buffer_length_, &headers_);
}
const size_t available = header_buffer_size_ - header_buffer_length_;
if (len > available) {
@@ -386,7 +404,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
return true;
}
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override {
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {
++setting_count_;
}
@@ -459,7 +477,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
void OnPriority(SpdyStreamId stream_id,
SpdyStreamId parent_stream_id,
- uint8 weight,
+ uint8_t weight,
bool exclusive) override {
++priority_count_;
}
@@ -595,8 +613,8 @@ class SpdyFramerPeer {
};
// Retrieves serialized headers from a HEADERS or SYN_STREAM frame.
-base::StringPiece GetSerializedHeaders(const SpdyFrame* frame,
- const SpdyFramer& framer) {
+StringPiece GetSerializedHeaders(const SpdyFrame* frame,
+ const SpdyFramer& framer) {
SpdyFrameReader reader(frame->data(), frame->size());
if (framer.protocol_version() > SPDY3) {
reader.Seek(3); // Seek past the frame length.
@@ -605,18 +623,18 @@ base::StringPiece GetSerializedHeaders(const SpdyFrame* frame,
}
SpdyFrameType frame_type;
if (framer.protocol_version() > SPDY3) {
- uint8 serialized_type;
+ uint8_t serialized_type;
reader.ReadUInt8(&serialized_type);
frame_type = SpdyConstants::ParseFrameType(framer.protocol_version(),
serialized_type);
DCHECK_EQ(HEADERS, frame_type);
- uint8 flags;
+ uint8_t flags;
reader.ReadUInt8(&flags);
if (flags & HEADERS_FLAG_PRIORITY) {
frame_type = SYN_STREAM;
}
} else {
- uint16 serialized_type;
+ uint16_t serialized_type;
reader.ReadUInt16(&serialized_type);
frame_type = SpdyConstants::ParseFrameType(framer.protocol_version(),
serialized_type);
@@ -662,34 +680,6 @@ class SpdyFramerTest : public ::testing::TestWithParam<SpdyMajorVersion> {
actual_frame.size());
}
- // Returns true if the two header blocks have equivalent content.
- bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
- const SpdyHeaderBlock* actual) {
- if (expected->size() != actual->size()) {
- LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
- << actual->size() << ".";
- return false;
- }
- for (SpdyHeaderBlock::const_iterator it = expected->begin();
- it != expected->end();
- ++it) {
- SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
- if (it2 == actual->end()) {
- LOG(ERROR) << "Expected header name '" << it->first << "'.";
- return false;
- }
- if (it->second.compare(it2->second) != 0) {
- LOG(ERROR) << "Expected header named '" << it->first
- << "' to have a value of '" << it->second
- << "'. The actual value received was '" << it2->second
- << "'.";
- return false;
- }
- }
- return true;
- }
-
- bool IsSpdy2() { return spdy_version_ == SPDY2; }
bool IsSpdy3() { return spdy_version_ == SPDY3; }
bool IsHttp2() { return spdy_version_ == HTTP2; }
@@ -698,10 +688,10 @@ class SpdyFramerTest : public ::testing::TestWithParam<SpdyMajorVersion> {
unsigned char spdy_version_ch_;
};
-// All tests are run with 3 different SPDY versions: SPDY/2, SPDY/3, HTTP/2.
+// All tests are run with SPDY/3 and HTTP/2.
INSTANTIATE_TEST_CASE_P(SpdyFramerTests,
SpdyFramerTest,
- ::testing::Values(SPDY2, SPDY3, HTTP2));
+ ::testing::Values(SPDY3, HTTP2));
// Test that we ignore cookie where both name and value are empty.
TEST_P(SpdyFramerTest, HeaderBlockWithEmptyCookie) {
@@ -726,7 +716,7 @@ TEST_P(SpdyFramerTest, HeaderBlockWithEmptyCookie) {
frame->size());
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
- EXPECT_FALSE(CompareHeaderBlocks(&headers.header_block(), &visitor.headers_));
+ EXPECT_NE(headers.header_block(), visitor.headers_);
EXPECT_EQ(1u, visitor.headers_.size());
EXPECT_EQ("key=value; foo; bar=; k2=v2 ", visitor.headers_["cookie"]);
}
@@ -752,7 +742,7 @@ TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
frame->size());
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers.header_block(), &visitor.headers_));
+ EXPECT_EQ(headers.header_block(), visitor.headers_);
}
// Test that if there's not a full frame, we fail to parse it.
@@ -923,26 +913,18 @@ TEST_P(SpdyFramerTest, DuplicateHeader) {
frame.WriteUInt32(framer.GetHighestPriority());
}
- if (IsSpdy2()) {
- frame.WriteUInt16(2); // Number of headers.
- frame.WriteStringPiece16("name");
- frame.WriteStringPiece16("value1");
- frame.WriteStringPiece16("name");
- frame.WriteStringPiece16("value2");
- } else {
- frame.WriteUInt32(2); // Number of headers.
- frame.WriteStringPiece32("name");
- frame.WriteStringPiece32("value1");
- frame.WriteStringPiece32("name");
- frame.WriteStringPiece32("value2");
- }
+ frame.WriteUInt32(2); // Number of headers.
+ frame.WriteStringPiece32("name");
+ frame.WriteStringPiece32("value1");
+ frame.WriteStringPiece32("name");
+ frame.WriteStringPiece32("value2");
// write the length
frame.RewriteLength(framer);
SpdyHeaderBlock new_headers;
framer.set_enable_compression(false);
scoped_ptr<SpdyFrame> control_frame(frame.take());
- base::StringPiece serialized_headers =
+ StringPiece serialized_headers =
GetSerializedHeaders(control_frame.get(), framer);
// This should fail because duplicate headers are verboten by the spec.
EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
@@ -969,11 +951,7 @@ TEST_P(SpdyFramerTest, MultiValueHeader) {
}
string value("value1\0value2", 13);
- if (IsSpdy2()) {
- frame.WriteUInt16(1); // Number of headers.
- frame.WriteStringPiece16("name");
- frame.WriteStringPiece16(value);
- } else if (spdy_version_ > SPDY3) {
+ if (spdy_version_ > SPDY3) {
// TODO(jgraettinger): If this pattern appears again, move to test class.
SpdyHeaderBlock header_set;
header_set["name"] = value;
@@ -1022,21 +1000,12 @@ TEST_P(SpdyFramerTest, BasicCompression) {
size_t uncompressed_size1 = visitor->last_payload_len_;
size_t compressed_size1 =
visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
- if (IsSpdy2()) {
- EXPECT_EQ(139u, uncompressed_size1);
+ EXPECT_EQ(165u, uncompressed_size1);
#if defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(155u, compressed_size1);
+ EXPECT_EQ(181u, compressed_size1);
#else // !defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(135u, compressed_size1);
+ EXPECT_EQ(117u, compressed_size1);
#endif // !defined(USE_SYSTEM_ZLIB)
- } else {
- EXPECT_EQ(165u, uncompressed_size1);
-#if defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(181u, compressed_size1);
-#else // !defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(117u, compressed_size1);
-#endif // !defined(USE_SYSTEM_ZLIB)
- }
scoped_ptr<SpdyFrame> frame2(framer.SerializeSynStream(syn_stream));
size_t uncompressed_size2 = visitor->last_payload_len_;
size_t compressed_size2 =
@@ -1058,21 +1027,12 @@ TEST_P(SpdyFramerTest, BasicCompression) {
frame4->size() - framer.GetSynStreamMinimumSize();
size_t compressed_size4 =
visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
- if (IsSpdy2()) {
- EXPECT_EQ(139u, uncompressed_size4);
+ EXPECT_EQ(165u, uncompressed_size4);
#if defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(149u, compressed_size4);
+ EXPECT_EQ(175u, compressed_size4);
#else // !defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(99u, compressed_size4);
+ EXPECT_EQ(99u, compressed_size4);
#endif // !defined(USE_SYSTEM_ZLIB)
- } else {
- EXPECT_EQ(165u, uncompressed_size4);
-#if defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(175u, compressed_size4);
-#else // !defined(USE_SYSTEM_ZLIB)
- EXPECT_EQ(99u, compressed_size4);
-#endif // !defined(USE_SYSTEM_ZLIB)
- }
EXPECT_EQ(uncompressed_size1, uncompressed_size2);
EXPECT_EQ(uncompressed_size1, uncompressed_size4);
@@ -1106,59 +1066,6 @@ TEST_P(SpdyFramerTest, CompressEmptyHeaders) {
}
TEST_P(SpdyFramerTest, Basic) {
- const unsigned char kV2Input[] = {
- 0x80, spdy_version_ch_, 0x00, 0x01, // SYN Stream #1
- 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x02, 'h', 'h',
- 0x00, 0x02, 'v', 'v',
-
- 0x80, spdy_version_ch_, 0x00, 0x08, // HEADERS on Stream #1
- 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x02, 'h', '2',
- 0x00, 0x02, 'v', '2',
- 0x00, 0x02, 'h', '3',
- 0x00, 0x02, 'v', '3',
-
- 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
- 0x00, 0x00, 0x00, 0x0c,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
-
- 0x80, spdy_version_ch_, 0x00, 0x01, // SYN Stream #3
- 0x00, 0x00, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
-
- 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
- 0x00, 0x00, 0x00, 0x08,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
-
- 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
- 0x00, 0x00, 0x00, 0x04,
- 0xde, 0xad, 0xbe, 0xef,
-
- 0x80, spdy_version_ch_, 0x00, 0x03, // RST_STREAM on Stream #1
- 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x05, // RST_STREAM_CANCEL
-
- 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
- 0x00, 0x00, 0x00, 0x00,
-
- 0x80, spdy_version_ch_, 0x00, 0x03, // RST_STREAM on Stream #3
- 0x00, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x05, // RST_STREAM_CANCEL
- };
-
const unsigned char kV3Input[] = {
0x80, spdy_version_ch_, 0x00, 0x01, // SYN Stream #1
0x00, 0x00, 0x00, 0x1a,
@@ -1271,9 +1178,7 @@ TEST_P(SpdyFramerTest, Basic) {
};
TestSpdyVisitor visitor(spdy_version_);
- if (IsSpdy2()) {
- visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
} else {
visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
@@ -1287,7 +1192,7 @@ TEST_P(SpdyFramerTest, Basic) {
if (IsHttp2()) {
EXPECT_EQ(3, visitor.headers_frame_count_);
EXPECT_EQ(0, visitor.syn_frame_count_);
- base::StringPiece reset_stream = "RESETSTREAM";
+ StringPiece reset_stream = "RESETSTREAM";
EXPECT_EQ(reset_stream, visitor.fin_opaque_data_);
} else {
EXPECT_EQ(1, visitor.headers_frame_count_);
@@ -1303,32 +1208,6 @@ TEST_P(SpdyFramerTest, Basic) {
// Test that the FIN flag on a data frame signifies EOF.
TEST_P(SpdyFramerTest, FinOnDataFrame) {
- const unsigned char kV2Input[] = {
- 0x80, spdy_version_ch_, 0x00, 0x01, // SYN Stream #1
- 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x02, 'h', 'h',
- 0x00, 0x02, 'v', 'v',
-
- 0x80, spdy_version_ch_, 0x00, 0x02, // SYN REPLY Stream #1
- 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x02, 'a', 'a',
- 0x00, 0x02, 'b', 'b',
-
- 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
- 0x00, 0x00, 0x00, 0x0c,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
-
- 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1, with EOF
- 0x01, 0x00, 0x00, 0x04,
- 0xde, 0xad, 0xbe, 0xef,
- };
const unsigned char kV3Input[] = {
0x80, spdy_version_ch_, 0x00, 0x01, // SYN Stream #1
0x00, 0x00, 0x00, 0x1a,
@@ -1385,9 +1264,7 @@ TEST_P(SpdyFramerTest, FinOnDataFrame) {
};
TestSpdyVisitor visitor(spdy_version_);
- if (IsSpdy2()) {
- visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
} else {
visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
@@ -1412,24 +1289,6 @@ TEST_P(SpdyFramerTest, FinOnDataFrame) {
// Test that the FIN flag on a SYN reply frame signifies EOF.
TEST_P(SpdyFramerTest, FinOnSynReplyFrame) {
- const unsigned char kV2Input[] = {
- 0x80, spdy_version_ch_, 0x00, // SYN Stream #1
- 0x01, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x02, 'h',
- 'h', 0x00, 0x02, 'v',
- 'v',
-
- 0x80, spdy_version_ch_, 0x00, // SYN REPLY Stream #1
- 0x02, 0x01, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x02, 'a',
- 'a', 0x00, 0x02, 'b',
- 'b',
- };
const unsigned char kV3Input[] = {
0x80, spdy_version_ch_, 0x00, // SYN Stream #1
0x01, 0x00, 0x00, 0x00,
@@ -1465,9 +1324,7 @@ TEST_P(SpdyFramerTest, FinOnSynReplyFrame) {
};
TestSpdyVisitor visitor(spdy_version_);
- if (IsSpdy2()) {
- visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
} else {
visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
@@ -1527,7 +1384,7 @@ TEST_P(SpdyFramerTest, HeaderCompression) {
// Now start decompressing
scoped_ptr<SpdyFrame> decompressed;
scoped_ptr<SpdyFrame> uncompressed;
- base::StringPiece serialized_headers;
+ StringPiece serialized_headers;
SpdyHeaderBlock decompressed_headers;
// Decompress SYN_STREAM #1
@@ -1613,7 +1470,7 @@ TEST_P(SpdyFramerTest, WindowUpdateFrame) {
SpdyWindowUpdateIR(1, 0x12345678)));
const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
@@ -1638,7 +1495,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] = "'hello' data frame, no FIN";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x05,
'h', 'e', 'l', 'l',
@@ -1682,7 +1539,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] = "'hello' data frame with more padding, no FIN";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x05,
'h', 'e', 'l', 'l',
@@ -1742,7 +1599,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] = "'hello' data frame with few padding, no FIN";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x05,
'h', 'e', 'l', 'l',
@@ -1775,7 +1632,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] =
"'hello' data frame with 1 byte padding, no FIN";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x05,
'h', 'e', 'l', 'l',
@@ -1813,7 +1670,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] = "Data frame with negative data byte, no FIN";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0xff
@@ -1832,7 +1689,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] = "'hello' data frame, with FIN";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x00, 0x05,
'h', 'e', 'l', 'l',
@@ -1857,9 +1714,8 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] = "Empty data frame";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
+ const unsigned char kV3FrameData[] = {
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
};
const unsigned char kH2FrameData[] = {
0x00, 0x00, 0x00, 0x00,
@@ -1885,7 +1741,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
{
const char kDescription[] = "Data frame with max stream ID";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x7f, 0xff, 0xff, 0xff,
0x01, 0x00, 0x00, 0x05,
'h', 'e', 'l', 'l',
@@ -1933,7 +1789,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
}
TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
- if (!IsSpdy2() && !IsSpdy3()) {
+ if (!IsSpdy3()) {
// SYN_STREAM unsupported in SPDY>3
return;
}
@@ -1943,25 +1799,12 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
{
const char kDescription[] = "SYN_STREAM frame, lowest pri, no FIN";
- const unsigned char kPri = IsSpdy2() ? 0xC0 : 0xE0;
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x20,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
- kPri, 0x00, 0x00, 0x02,
- 0x00, 0x03, 'b', 'a',
- 'r', 0x00, 0x03, 'f',
- 'o', 'o', 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x03, 'b', 'a', 'r'
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x01,
0x00, 0x00, 0x00, 0x2a,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
- kPri, 0x00, 0x00, 0x00,
+ 0xE0, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00,
0x00, 0x03, 'b', 'a',
'r', 0x00, 0x00, 0x00,
@@ -1976,9 +1819,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
syn_stream.SetHeader("bar", "foo");
syn_stream.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
LOG(FATAL) << "Unsupported version in test.";
@@ -1990,18 +1831,6 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
"SYN_STREAM frame with a 0-length header name, highest pri, FIN, "
"max stream ID";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x01,
- 0x01, 0x00, 0x00, 0x1D,
- 0x7f, 0xff, 0xff, 0xff,
- 0x7f, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x03, 'f', 'o', 'o',
- 0x00, 0x03, 'b', 'a',
- 'r'
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x01,
0x01, 0x00, 0x00, 0x27,
@@ -2023,9 +1852,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
syn_stream.SetHeader("", "foo");
syn_stream.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
LOG(FATAL) << "Unsupported version in test.";
@@ -2037,25 +1864,12 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
"SYN_STREAM frame with a 0-length header val, high pri, FIN, "
"max stream ID";
- const unsigned char kPri = IsSpdy2() ? 0x40 : 0x20;
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x01,
- 0x01, 0x00, 0x00, 0x1D,
- 0x7f, 0xff, 0xff, 0xff,
- 0x7f, 0xff, 0xff, 0xff,
- kPri, 0x00, 0x00, 0x02,
- 0x00, 0x03, 'b', 'a',
- 'r', 0x00, 0x03, 'f',
- 'o', 'o', 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x00
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x01,
0x01, 0x00, 0x00, 0x27,
0x7f, 0xff, 0xff, 0xff,
0x7f, 0xff, 0xff, 0xff,
- kPri, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00,
0x00, 0x03, 'b', 'a',
'r', 0x00, 0x00, 0x00,
@@ -2071,9 +1885,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
syn_stream.SetHeader("bar", "foo");
syn_stream.SetHeader("foo", "");
scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
LOG(FATAL) << "Unsupported version in test.";
@@ -2085,7 +1897,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
// to workaround http://crbug.com/139744.
#if !defined(USE_SYSTEM_ZLIB)
TEST_P(SpdyFramerTest, CreateSynStreamCompressed) {
- if (!IsSpdy2() && !IsSpdy3()) {
+ if (!IsSpdy3()) {
// SYN_STREAM not supported for SPDY>3
return;
}
@@ -2095,26 +1907,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamCompressed) {
{
const char kDescription[] =
"SYN_STREAM frame, low pri, no FIN";
- const SpdyPriority priority = IsSpdy2() ? 2 : 4;
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x36,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x38, 0xea,
- 0xdf, 0xa2, 0x51, 0xb2,
- 0x62, 0x60, 0x62, 0x60,
- 0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x4e,
- 0xcb, 0xcf, 0x67, 0x60,
- 0x06, 0x08, 0xa0, 0xa4,
- 0xc4, 0x22, 0x80, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xff, 0xff,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x01,
0x00, 0x00, 0x00, 0x37,
@@ -2133,23 +1926,6 @@ TEST_P(SpdyFramerTest, CreateSynStreamCompressed) {
0x80, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF,
};
- const unsigned char kV2SIMDFrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x33,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x38, 0xea,
- 0xdf, 0xa2, 0x51, 0xb2,
- 0x62, 0x60, 0x62, 0x60,
- 0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x06,
- 0x13, 0x00, 0x01, 0x94,
- 0x94, 0x58, 0x04, 0x10,
- 0x40, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff,
- };
const unsigned char kV3SIMDFrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x01,
0x00, 0x00, 0x00, 0x32,
@@ -2169,25 +1945,13 @@ TEST_P(SpdyFramerTest, CreateSynStreamCompressed) {
};
SpdySynStreamIR syn_stream(1);
- syn_stream.set_priority(priority);
+ syn_stream.set_priority(4);
syn_stream.SetHeader("bar", "foo");
syn_stream.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
const unsigned char* frame_data =
reinterpret_cast<const unsigned char*>(frame->data());
- if (IsSpdy2()) {
- // Try comparing with SIMD version, if that fails, do a failing check
- // with pretty printing against non-SIMD version
- if (memcmp(frame_data,
- kV2SIMDFrameData,
- std::min(arraysize(kV2SIMDFrameData), frame->size())) != 0) {
- CompareCharArraysWithHexError(kDescription,
- frame_data,
- frame->size(),
- kV2FrameData,
- arraysize(kV2FrameData));
- }
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
if (memcmp(frame_data,
kV3SIMDFrameData,
std::min(arraysize(kV3SIMDFrameData), frame->size())) != 0) {
@@ -2215,17 +1979,6 @@ TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
{
const char kDescription[] = "SYN_REPLY frame, no FIN";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x1C,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x03, 'b', 'a',
- 'r', 0x00, 0x03, 'f',
- 'o', 'o', 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x03, 'b', 'a', 'r'
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x02,
0x00, 0x00, 0x00, 0x24,
@@ -2243,9 +1996,7 @@ TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
syn_reply.SetHeader("bar", "foo");
syn_reply.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
LOG(FATAL) << "Unsupported version in test.";
@@ -2256,17 +2007,6 @@ TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
const char kDescription[] =
"SYN_REPLY frame with a 0-length header name, FIN, max stream ID";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x02,
- 0x01, 0x00, 0x00, 0x19,
- 0x7f, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x03, 'f', 'o', 'o',
- 0x00, 0x03, 'b', 'a',
- 'r'
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x02,
0x01, 0x00, 0x00, 0x21,
@@ -2285,9 +2025,7 @@ TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
syn_reply.SetHeader("", "foo");
syn_reply.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
LOG(FATAL) << "Unsupported version in test.";
@@ -2298,17 +2036,6 @@ TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
const char kDescription[] =
"SYN_REPLY frame with a 0-length header val, FIN, max stream ID";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x02,
- 0x01, 0x00, 0x00, 0x19,
- 0x7f, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x03, 'b', 'a',
- 'r', 0x00, 0x03, 'f',
- 'o', 'o', 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x00
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x02,
0x01, 0x00, 0x00, 0x21,
@@ -2327,9 +2054,7 @@ TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
syn_reply.SetHeader("bar", "foo");
syn_reply.SetHeader("foo", "");
scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
LOG(FATAL) << "Unsupported version in test.";
@@ -2351,23 +2076,6 @@ TEST_P(SpdyFramerTest, CreateSynReplyCompressed) {
{
const char kDescription[] = "SYN_REPLY frame, no FIN";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x38, 0xea,
- 0xdf, 0xa2, 0x51, 0xb2,
- 0x62, 0x60, 0x62, 0x60,
- 0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x4e,
- 0xcb, 0xcf, 0x67, 0x60,
- 0x06, 0x08, 0xa0, 0xa4,
- 0xc4, 0x22, 0x80, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xff, 0xff,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x02,
0x00, 0x00, 0x00, 0x31,
@@ -2385,22 +2093,6 @@ TEST_P(SpdyFramerTest, CreateSynReplyCompressed) {
0x00, 0x00, 0x00, 0xff,
0xff,
};
- const unsigned char kV2SIMDFrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x2f,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x38, 0xea,
- 0xdf, 0xa2, 0x51, 0xb2,
- 0x62, 0x60, 0x62, 0x60,
- 0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x06,
- 0x13, 0x00, 0x01, 0x94,
- 0x94, 0x58, 0x04, 0x10,
- 0x40, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff,
- };
const unsigned char kV3SIMDFrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x02,
0x00, 0x00, 0x00, 0x2c,
@@ -2423,19 +2115,7 @@ TEST_P(SpdyFramerTest, CreateSynReplyCompressed) {
scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
const unsigned char* frame_data =
reinterpret_cast<const unsigned char*>(frame->data());
- if (IsSpdy2()) {
- // Try comparing with SIMD version, if that fails, do a failing check
- // with pretty printing against non-SIMD version
- if (memcmp(frame_data,
- kV2SIMDFrameData,
- std::min(arraysize(kV2SIMDFrameData), frame->size())) != 0) {
- CompareCharArraysWithHexError(kDescription,
- frame_data,
- frame->size(),
- kV2FrameData,
- arraysize(kV2FrameData));
- }
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
if (memcmp(frame_data,
kV3SIMDFrameData,
std::min(arraysize(kV3SIMDFrameData), frame->size())) != 0) {
@@ -2457,19 +2137,17 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
{
const char kDescription[] = "RST_STREAM frame";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
};
const unsigned char kH2FrameData[] = {
- 0x00, 0x00, 0x07, 0x03,
- 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x52, 0x53, 0x54
+ 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
};
- SpdyRstStreamIR rst_stream(1, RST_STREAM_PROTOCOL_ERROR, "RST");
+ SpdyRstStreamIR rst_stream(1, RST_STREAM_PROTOCOL_ERROR);
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
if (IsHttp2()) {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2480,7 +2158,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
{
const char kDescription[] = "RST_STREAM frame with max stream ID";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x7f, 0xff, 0xff, 0xff,
@@ -2492,9 +2170,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
0xff, 0x00, 0x00, 0x00,
0x01,
};
- SpdyRstStreamIR rst_stream(0x7FFFFFFF,
- RST_STREAM_PROTOCOL_ERROR,
- "");
+ SpdyRstStreamIR rst_stream(0x7FFFFFFF, RST_STREAM_PROTOCOL_ERROR);
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
if (IsHttp2()) {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2505,7 +2181,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
{
const char kDescription[] = "RST_STREAM frame with max status code";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x7f, 0xff, 0xff, 0xff,
@@ -2517,9 +2193,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
0xff, 0x00, 0x00, 0x00,
0x02,
};
- SpdyRstStreamIR rst_stream(0x7FFFFFFF,
- RST_STREAM_INTERNAL_ERROR,
- "");
+ SpdyRstStreamIR rst_stream(0x7FFFFFFF, RST_STREAM_INTERNAL_ERROR);
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
if (IsHttp2()) {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2535,13 +2209,6 @@ TEST_P(SpdyFramerTest, CreateSettings) {
{
const char kDescription[] = "Network byte order SETTINGS frame";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x01,
- 0x07, 0x00, 0x00, 0x01,
- 0x0a, 0x0b, 0x0c, 0x0d,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x04,
0x00, 0x00, 0x00, 0x0c,
@@ -2556,7 +2223,7 @@ TEST_P(SpdyFramerTest, CreateSettings) {
0x0b, 0x0c, 0x0d,
};
- uint32 kValue = 0x0a0b0c0d;
+ uint32_t kValue = 0x0a0b0c0d;
SpdySettingsIR settings_ir;
SpdySettingsFlags kFlags = static_cast<SpdySettingsFlags>(0x01);
@@ -2567,9 +2234,7 @@ TEST_P(SpdyFramerTest, CreateSettings) {
kValue);
scoped_ptr<SpdyFrame> frame(framer.SerializeSettings(settings_ir));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2579,19 +2244,6 @@ TEST_P(SpdyFramerTest, CreateSettings) {
{
const char kDescription[] = "Basic SETTINGS frame";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x24,
- 0x00, 0x00, 0x00, 0x04,
- 0x01, 0x00, 0x00, 0x00, // 1st Setting
- 0x00, 0x00, 0x00, 0x05,
- 0x02, 0x00, 0x00, 0x00, // 2nd Setting
- 0x00, 0x00, 0x00, 0x06,
- 0x03, 0x00, 0x00, 0x00, // 3rd Setting
- 0x00, 0x00, 0x00, 0x07,
- 0x04, 0x00, 0x00, 0x00, // 4th Setting
- 0x00, 0x00, 0x00, 0x08,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x04,
0x00, 0x00, 0x00, 0x24,
@@ -2640,9 +2292,7 @@ TEST_P(SpdyFramerTest, CreateSettings) {
8);
scoped_ptr<SpdyFrame> frame(framer.SerializeSettings(settings_ir));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2652,7 +2302,7 @@ TEST_P(SpdyFramerTest, CreateSettings) {
{
const char kDescription[] = "Empty SETTINGS frame";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x04,
0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00,
@@ -2677,7 +2327,7 @@ TEST_P(SpdyFramerTest, CreatePingFrame) {
{
const char kDescription[] = "PING frame";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x06,
0x00, 0x00, 0x00, 0x04,
0x12, 0x34, 0x56, 0x78,
@@ -2723,11 +2373,6 @@ TEST_P(SpdyFramerTest, CreateGoAway) {
{
const char kDescription[] = "GOAWAY frame";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, // Stream Id
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x07,
0x00, 0x00, 0x00, 0x08,
@@ -2743,9 +2388,7 @@ TEST_P(SpdyFramerTest, CreateGoAway) {
};
SpdyGoAwayIR goaway_ir(0, GOAWAY_OK, "GA");
scoped_ptr<SpdyFrame> frame(framer.SerializeGoAway(goaway_ir));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2754,11 +2397,6 @@ TEST_P(SpdyFramerTest, CreateGoAway) {
{
const char kDescription[] = "GOAWAY frame with max stream ID, status";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x04,
- 0x7f, 0xff, 0xff, 0xff, // Stream Id
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x07,
0x00, 0x00, 0x00, 0x08,
@@ -2774,9 +2412,7 @@ TEST_P(SpdyFramerTest, CreateGoAway) {
};
SpdyGoAwayIR goaway_ir(0x7FFFFFFF, GOAWAY_INTERNAL_ERROR, "GA");
scoped_ptr<SpdyFrame> frame(framer.SerializeGoAway(goaway_ir));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2791,17 +2427,6 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
{
const char kDescription[] = "HEADERS frame, no FIN";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x1C,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x03, 'b', 'a',
- 'r', 0x00, 0x03, 'f',
- 'o', 'o', 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x03, 'b', 'a', 'r'
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x08,
0x00, 0x00, 0x00, 0x24,
@@ -2828,9 +2453,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
headers_ir.SetHeader("bar", "foo");
headers_ir.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2841,17 +2464,6 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
const char kDescription[] =
"HEADERS frame with a 0-length header name, FIN, max stream ID";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x08,
- 0x01, 0x00, 0x00, 0x19,
- 0x7f, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x03, 'f', 'o', 'o',
- 0x00, 0x03, 'b', 'a',
- 'r'
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x08,
0x01, 0x00, 0x00, 0x21,
@@ -2878,9 +2490,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
headers_ir.SetHeader("", "foo");
headers_ir.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2891,17 +2501,6 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
const char kDescription[] =
"HEADERS frame with a 0-length header val, FIN, max stream ID";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x08,
- 0x01, 0x00, 0x00, 0x19,
- 0x7f, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x03, 'b', 'a',
- 'r', 0x00, 0x03, 'f',
- 'o', 'o', 0x00, 0x03,
- 'f', 'o', 'o', 0x00,
- 0x00
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x08,
0x01, 0x00, 0x00, 0x21,
@@ -2928,9 +2527,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
headers_ir.SetHeader("bar", "foo");
headers_ir.SetHeader("foo", "");
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- if (IsSpdy2()) {
- CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2958,7 +2555,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
headers_ir.SetHeader("bar", "foo");
headers_ir.SetHeader("foo", "");
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- if (IsSpdy2() || IsSpdy3()) {
+ if (IsSpdy3()) {
// HEADERS with priority not supported.
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -2989,7 +2586,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
headers_ir.SetHeader("bar", "foo");
headers_ir.SetHeader("foo", "");
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- if (IsSpdy2() || IsSpdy3()) {
+ if (IsSpdy3()) {
// HEADERS with priority not supported.
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -3020,7 +2617,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
headers_ir.SetHeader("bar", "foo");
headers_ir.SetHeader("foo", "");
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- if (IsSpdy2() || IsSpdy3()) {
+ if (IsSpdy3()) {
// HEADERS with priority not supported.
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -3049,7 +2646,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
headers_ir.SetHeader("foo", "bar");
headers_ir.set_padding_len(6);
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- if (IsSpdy2() || IsSpdy3()) {
+ if (IsSpdy3()) {
// Padding is not supported.
} else {
CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
@@ -3067,23 +2664,6 @@ TEST_P(SpdyFramerTest, CreateHeadersCompressed) {
{
const char kDescription[] = "HEADERS frame, no FIN";
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x38, 0xea,
- 0xdf, 0xa2, 0x51, 0xb2,
- 0x62, 0x60, 0x62, 0x60,
- 0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x4e,
- 0xcb, 0xcf, 0x67, 0x60,
- 0x06, 0x08, 0xa0, 0xa4,
- 0xc4, 0x22, 0x80, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xff, 0xff,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x08,
0x00, 0x00, 0x00, 0x31,
@@ -3101,22 +2681,6 @@ TEST_P(SpdyFramerTest, CreateHeadersCompressed) {
0x00, 0x00, 0x00, 0xff,
0xff,
};
- const unsigned char kV2SIMDFrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x2f,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x38, 0xea,
- 0xdf, 0xa2, 0x51, 0xb2,
- 0x62, 0x60, 0x62, 0x60,
- 0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x06,
- 0x13, 0x00, 0x01, 0x94,
- 0x94, 0x58, 0x04, 0x10,
- 0x40, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff,
- };
const unsigned char kV3SIMDFrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x08,
0x00, 0x00, 0x00, 0x2c,
@@ -3139,19 +2703,7 @@ TEST_P(SpdyFramerTest, CreateHeadersCompressed) {
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
const unsigned char* frame_data =
reinterpret_cast<const unsigned char*>(frame->data());
- if (IsSpdy2()) {
- // Try comparing with SIMD version, if that fails, do a failing check
- // with pretty printing against non-SIMD version
- if (memcmp(frame_data,
- kV2SIMDFrameData,
- std::min(arraysize(kV2SIMDFrameData), frame->size())) != 0) {
- CompareCharArraysWithHexError(kDescription,
- frame_data,
- frame->size(),
- kV2FrameData,
- arraysize(kV2FrameData));
- }
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
if (memcmp(frame_data,
kV3SIMDFrameData,
std::min(arraysize(kV3SIMDFrameData), frame->size())) != 0) {
@@ -3173,7 +2725,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) {
{
const char kDescription[] = "WINDOW_UPDATE frame";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
@@ -3196,7 +2748,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) {
{
const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x7f, 0xff, 0xff, 0xff,
@@ -3219,7 +2771,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) {
{
const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
@@ -3532,20 +3084,21 @@ TEST_P(SpdyFramerTest, CreateAltSvc) {
const char kType = static_cast<unsigned char>(
SpdyConstants::SerializeFrameType(spdy_version_, ALTSVC));
const unsigned char kFrameData[] = {
- 0x00, 0x00, 0x4b, kType, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 'o',
+ 0x00, 0x00, 0x53, kType, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 'o',
'r', 'i', 'g', 'i', 'n', 'p', 'i', 'd', '1', '=', '"', 'h',
'o', 's', 't', ':', '4', '4', '3', '"', ';', ' ', 'm', 'a',
'=', '5', ',', 'p', '%', '2', '2', '%', '3', 'D', 'i', '%',
'3', 'A', 'd', '=', '"', 'h', '_', '\\', '\\', 'o', '\\', '"',
's', 't', ':', '1', '2', '3', '"', ';', ' ', 'm', 'a', '=',
'4', '2', ';', ' ', 'p', '=', '"', '0', '.', '2', '0', '"',
- };
+ ';', ' ', 'v', '=', '"', '2', '4', '"'};
SpdyAltSvcIR altsvc_ir(3);
altsvc_ir.set_origin("origin");
- altsvc_ir.add_altsvc(
- SpdyAltSvcWireFormat::AlternativeService("pid1", "host", 443, 5, 1.0));
altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
- "p\"=i:d", "h_\\o\"st", 123, 42, 0.2));
+ "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector{}));
+ altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+ "p\"=i:d", "h_\\o\"st", 123, 42, 0.2,
+ SpdyAltSvcWireFormat::VersionVector{24}));
scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
}
@@ -3596,7 +3149,7 @@ TEST_P(SpdyFramerTest, ReadCompressedSynStreamHeaderBlock) {
reinterpret_cast<unsigned char*>(control_frame->data()),
control_frame->size());
EXPECT_EQ(1, visitor.syn_frame_count_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(SpdyFramerTest, ReadCompressedSynReplyHeaderBlock) {
@@ -3622,7 +3175,7 @@ TEST_P(SpdyFramerTest, ReadCompressedSynReplyHeaderBlock) {
EXPECT_EQ(1, visitor.syn_reply_frame_count_);
EXPECT_EQ(0, visitor.headers_frame_count_);
}
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
@@ -3646,7 +3199,7 @@ TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
EXPECT_LE(2, visitor.control_frame_header_data_count_);
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
@@ -3671,7 +3224,7 @@ TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
EXPECT_LE(2, visitor.control_frame_header_data_count_);
EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) {
@@ -3887,7 +3440,7 @@ TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) {
// We create enough overhead to overflow the framer's control frame buffer.
ASSERT_LE(SpdyFramerPeer::ControlFrameBufferSize(), 250u);
const size_t length = SpdyFramerPeer::ControlFrameBufferSize() + 1;
- const unsigned char kV3FrameData[] = { // Also applies for V2.
+ const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x07,
0x00, 0x00, 0x00, static_cast<unsigned char>(length),
0x00, 0x00, 0x00, 0x00, // Stream ID
@@ -4027,17 +3580,6 @@ TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
SpdyFramer framer(spdy_version_);
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x1C,
- 0x00, 0x00, 0x00, 0x03,
- 0x01, 0x00, 0x00, 0x00, // 1st Setting
- 0x00, 0x00, 0x00, 0x02,
- 0x01, 0x00, 0x00, 0x00, // 2nd (duplicate) Setting
- 0x00, 0x00, 0x00, 0x03,
- 0x03, 0x00, 0x00, 0x00, // 3rd (unprocessed) Setting
- 0x00, 0x00, 0x00, 0x03,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x04,
0x00, 0x00, 0x00, 0x1C,
@@ -4062,9 +3604,7 @@ TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
TestSpdyVisitor visitor(spdy_version_);
visitor.use_compression_ = false;
- if (IsSpdy2()) {
- visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
} else {
visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
@@ -4086,13 +3626,6 @@ TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
SpdyFramer framer(spdy_version_);
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x1C,
- 0x00, 0x00, 0x00, 0x01,
- 0x10, 0x00, 0x00, 0x00, // 1st Setting
- 0x00, 0x00, 0x00, 0x02,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x04,
0x00, 0x00, 0x00, 0x1C,
@@ -4109,9 +3642,7 @@ TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
TestSpdyVisitor visitor(spdy_version_);
visitor.use_compression_ = false;
- if (IsSpdy2()) {
- visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
} else {
visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
@@ -4131,17 +3662,6 @@ TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
SpdyFramer framer(spdy_version_);
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x1C,
- 0x00, 0x00, 0x00, 0x03,
- 0x02, 0x00, 0x00, 0x00, // 1st Setting
- 0x00, 0x00, 0x00, 0x02,
- 0x01, 0x00, 0x00, 0x00, // 2nd (out of order) Setting
- 0x00, 0x00, 0x00, 0x03,
- 0x03, 0x00, 0x00, 0x00, // 3rd (unprocessed) Setting
- 0x00, 0x00, 0x00, 0x03,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x04,
0x00, 0x00, 0x00, 0x1C,
@@ -4166,9 +3686,7 @@ TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
TestSpdyVisitor visitor(spdy_version_);
visitor.use_compression_ = false;
- if (IsSpdy2()) {
- visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
} else {
visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
@@ -4281,72 +3799,6 @@ TEST_P(SpdyFramerTest, ReadWindowUpdate) {
EXPECT_EQ(2, visitor.last_window_update_delta_);
}
-TEST_P(SpdyFramerTest, ReceiveCredentialFrame) {
- if (!IsSpdy3()) {
- return;
- }
- SpdyFramer framer(spdy_version_);
- const unsigned char kV3FrameData[] = { // Also applies for V2.
- 0x80, spdy_version_ch_, 0x00, 0x0A,
- 0x00, 0x00, 0x00, 0x33,
- 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x05, 'p', 'r',
- 'o', 'o', 'f', 0x00,
- 0x00, 0x00, 0x06, 'a',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0C, 'a', 'n', 'o',
- 't', 'h', 'e', 'r',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0A, 'f', 'i', 'n',
- 'a', 'l', ' ', 'c',
- 'e', 'r', 't',
- };
- TestSpdyVisitor visitor(spdy_version_);
- visitor.use_compression_ = false;
- visitor.SimulateInFramer(kV3FrameData, arraysize(kV3FrameData));
- EXPECT_EQ(0, visitor.error_count_);
-}
-
-TEST_P(SpdyFramerTest, ReadCredentialFrameFollowedByAnotherFrame) {
- if (!IsSpdy3()) {
- return;
- }
- SpdyFramer framer(spdy_version_);
- const unsigned char kV3FrameData[] = { // Also applies for V2.
- 0x80, spdy_version_ch_, 0x00, 0x0A,
- 0x00, 0x00, 0x00, 0x33,
- 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x05, 'p', 'r',
- 'o', 'o', 'f', 0x00,
- 0x00, 0x00, 0x06, 'a',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0C, 'a', 'n', 'o',
- 't', 'h', 'e', 'r',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0A, 'f', 'i', 'n',
- 'a', 'l', ' ', 'c',
- 'e', 'r', 't',
- };
- TestSpdyVisitor visitor(spdy_version_);
- visitor.use_compression_ = false;
- string multiple_frame_data(reinterpret_cast<const char*>(kV3FrameData),
- arraysize(kV3FrameData));
- scoped_ptr<SpdyFrame> control_frame(
- framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 2)));
- multiple_frame_data.append(string(control_frame->data(),
- control_frame->size()));
- visitor.SimulateInFramer(
- reinterpret_cast<unsigned const char*>(multiple_frame_data.data()),
- multiple_frame_data.length());
- EXPECT_EQ(0, visitor.error_count_);
- EXPECT_EQ(1u, visitor.last_window_update_stream_);
- EXPECT_EQ(2, visitor.last_window_update_delta_);
-}
-
TEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
if (spdy_version_ <= SPDY3) {
return;
@@ -4367,7 +3819,7 @@ TEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
frame->size());
EXPECT_EQ(42u, visitor.last_push_promise_stream_);
EXPECT_EQ(57u, visitor.last_push_promise_promised_stream_);
- EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
+ EXPECT_EQ(headers, visitor.headers_);
}
TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) {
@@ -4816,12 +4268,12 @@ TEST_P(SpdyFramerTest, SizesTest) {
EXPECT_EQ(8u, framer.GetDataFrameMinimumSize());
EXPECT_EQ(8u, framer.GetControlFrameHeaderSize());
EXPECT_EQ(18u, framer.GetSynStreamMinimumSize());
- EXPECT_EQ(IsSpdy2() ? 14u : 12u, framer.GetSynReplyMinimumSize());
+ EXPECT_EQ(12u, framer.GetSynReplyMinimumSize());
EXPECT_EQ(16u, framer.GetRstStreamMinimumSize());
EXPECT_EQ(12u, framer.GetSettingsMinimumSize());
EXPECT_EQ(12u, framer.GetPingSize());
- EXPECT_EQ(IsSpdy2() ? 12u : 16u, framer.GetGoAwayMinimumSize());
- EXPECT_EQ(IsSpdy2() ? 14u : 12u, framer.GetHeadersMinimumSize());
+ EXPECT_EQ(16u, framer.GetGoAwayMinimumSize());
+ EXPECT_EQ(12u, framer.GetHeadersMinimumSize());
EXPECT_EQ(16u, framer.GetWindowUpdateSize());
EXPECT_EQ(8u, framer.GetFrameMinimumSize());
EXPECT_EQ(16777223u, framer.GetFrameMaximumSize());
@@ -4938,8 +4390,6 @@ TEST_P(SpdyFramerTest, FrameTypeToStringTest) {
SpdyFramer::FrameTypeToString(WINDOW_UPDATE));
EXPECT_STREQ("PUSH_PROMISE",
SpdyFramer::FrameTypeToString(PUSH_PROMISE));
- EXPECT_STREQ("CREDENTIAL",
- SpdyFramer::FrameTypeToString(CREDENTIAL));
EXPECT_STREQ("CONTINUATION",
SpdyFramer::FrameTypeToString(CONTINUATION));
}
@@ -4980,7 +4430,7 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) {
return;
}
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5021,10 +4471,10 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
return;
}
- uint8 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT |
- DATA_FLAG_PADDED;
+ uint8_t valid_data_flags =
+ DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED;
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5067,11 +4517,11 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
}
TEST_P(SpdyFramerTest, SynStreamFrameFlags) {
- if (!IsSpdy2() && !IsSpdy3()) {
+ if (!IsSpdy3()) {
// SYN_STREAM not supported in SPDY>3
return;
}
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5121,11 +4571,11 @@ TEST_P(SpdyFramerTest, SynStreamFrameFlags) {
}
TEST_P(SpdyFramerTest, SynReplyFrameFlags) {
- if (!IsSpdy2() && !IsSpdy3()) {
+ if (!IsSpdy3()) {
// SYN_REPLY not supported in SPDY>3
return;
}
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5164,7 +4614,7 @@ TEST_P(SpdyFramerTest, SynReplyFrameFlags) {
}
TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5172,7 +4622,7 @@ TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- SpdyRstStreamIR rst_stream(13, RST_STREAM_CANCEL, "");
+ SpdyRstStreamIR rst_stream(13, RST_STREAM_CANCEL);
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
SetFrameFlags(frame.get(), flags, spdy_version_);
@@ -5198,7 +4648,7 @@ TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
TEST_P(SpdyFramerTest, SettingsFrameFlagsOldFormat) {
if (spdy_version_ > SPDY3) { return; }
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5240,7 +4690,7 @@ TEST_P(SpdyFramerTest, SettingsFrameFlagsOldFormat) {
TEST_P(SpdyFramerTest, SettingsFrameFlags) {
if (spdy_version_ <= SPDY3) { return; }
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5282,7 +4732,7 @@ TEST_P(SpdyFramerTest, SettingsFrameFlags) {
}
TEST_P(SpdyFramerTest, GoawayFrameFlags) {
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5315,7 +4765,7 @@ TEST_P(SpdyFramerTest, GoawayFrameFlags) {
}
TEST_P(SpdyFramerTest, HeadersFrameFlags) {
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5332,7 +4782,7 @@ TEST_P(SpdyFramerTest, HeadersFrameFlags) {
}
headers_ir.SetHeader("foo", "bar");
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
- uint8 set_flags = flags;
+ uint8_t set_flags = flags;
if (IsHttp2()) {
// TODO(jgraettinger): Add padding to SpdyHeadersIR,
// and implement framing.
@@ -5404,7 +4854,7 @@ TEST_P(SpdyFramerTest, HeadersFrameFlags) {
}
TEST_P(SpdyFramerTest, PingFrameFlags) {
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5440,7 +4890,7 @@ TEST_P(SpdyFramerTest, PingFrameFlags) {
}
TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) {
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5477,7 +4927,7 @@ TEST_P(SpdyFramerTest, PushPromiseFrameFlags) {
return;
}
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5526,7 +4976,7 @@ TEST_P(SpdyFramerTest, ContinuationFrameFlags) {
return;
}
- uint8 flags = 0;
+ uint8_t flags = 0;
do {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -5583,7 +5033,7 @@ TEST_P(SpdyFramerTest, ContinuationFrameFlags) {
// TODO(hkhalil): Add TEST_P(SpdyFramerTest, BlockedFrameFlags)
TEST_P(SpdyFramerTest, EmptySynStream) {
- if (!IsSpdy2() && !IsSpdy3()) {
+ if (!IsSpdy3()) {
// SYN_STREAM not supported in SPDY>3.
return;
}
@@ -5615,9 +5065,9 @@ TEST_P(SpdyFramerTest, EmptySynStream) {
}
TEST_P(SpdyFramerTest, SettingsFlagsAndId) {
- const uint32 kId = 0x020304;
- const uint32 kFlags = 0x01;
- const uint32 kWireFormat = htonl(IsSpdy2() ? 0x04030201 : 0x01020304);
+ const uint32_t kId = 0x020304;
+ const uint32_t kFlags = 0x01;
+ const uint32_t kWireFormat = base::HostToNet32(0x01020304);
SettingsFlagsAndId id_and_flags =
SettingsFlagsAndId::FromWireFormat(spdy_version_, kWireFormat);
@@ -5694,9 +5144,6 @@ TEST_P(SpdyFramerTest, RstStreamStatusBounds) {
// Test handling of GOAWAY frames with out-of-bounds status code.
TEST_P(SpdyFramerTest, GoAwayStatusBounds) {
- if (spdy_version_ <= SPDY2) {
- return;
- }
SpdyFramer framer(spdy_version_);
const unsigned char kV3FrameData[] = {
@@ -5731,11 +5178,6 @@ TEST_P(SpdyFramerTest, GoAwayStatusBounds) {
// Tests handling of a GOAWAY frame with out-of-bounds stream ID.
TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) {
- const unsigned char kV2FrameData[] = {
- 0x80, spdy_version_ch_, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x04,
- 0xff, 0xff, 0xff, 0xff,
- };
const unsigned char kV3FrameData[] = {
0x80, spdy_version_ch_, 0x00, 0x07,
0x00, 0x00, 0x00, 0x08,
@@ -5755,10 +5197,7 @@ TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) {
framer.set_visitor(&visitor);
EXPECT_CALL(visitor, OnGoAway(0x7fffffff, GOAWAY_OK));
- if (IsSpdy2()) {
- framer.ProcessInput(reinterpret_cast<const char*>(kV2FrameData),
- arraysize(kV2FrameData));
- } else if (IsSpdy3()) {
+ if (IsSpdy3()) {
framer.ProcessInput(reinterpret_cast<const char*>(kV3FrameData),
arraysize(kV3FrameData));
} else {
@@ -5803,9 +5242,11 @@ TEST_P(SpdyFramerTest, OnAltSvc) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- SpdyAltSvcWireFormat::AlternativeService altsvc1("pid1", "host", 443, 5, 1.0);
- SpdyAltSvcWireFormat::AlternativeService altsvc2("p\"=i:d", "h_\\o\"st", 123,
- 42, 0.2);
+ SpdyAltSvcWireFormat::AlternativeService altsvc1(
+ "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector());
+ SpdyAltSvcWireFormat::AlternativeService altsvc2(
+ "p\"=i:d", "h_\\o\"st", 123, 42, 0.2,
+ SpdyAltSvcWireFormat::VersionVector{24});
SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
altsvc_vector.push_back(altsvc1);
altsvc_vector.push_back(altsvc2);
@@ -5835,9 +5276,11 @@ TEST_P(SpdyFramerTest, OnAltSvcNoOrigin) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- SpdyAltSvcWireFormat::AlternativeService altsvc1("pid1", "host", 443, 5, 1.0);
- SpdyAltSvcWireFormat::AlternativeService altsvc2("p\"=i:d", "h_\\o\"st", 123,
- 42, 0.2);
+ SpdyAltSvcWireFormat::AlternativeService altsvc1(
+ "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector());
+ SpdyAltSvcWireFormat::AlternativeService altsvc2(
+ "p\"=i:d", "h_\\o\"st", 123, 42, 0.2,
+ SpdyAltSvcWireFormat::VersionVector{24});
SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
altsvc_vector.push_back(altsvc1);
altsvc_vector.push_back(altsvc2);
@@ -5867,10 +5310,10 @@ TEST_P(SpdyFramerTest, OnAltSvcEmptyProtocolId) {
SpdyAltSvcIR altsvc_ir(1);
altsvc_ir.set_origin("o1");
- altsvc_ir.add_altsvc(
- SpdyAltSvcWireFormat::AlternativeService("pid1", "host", 443, 5, 1.0));
- altsvc_ir.add_altsvc(
- SpdyAltSvcWireFormat::AlternativeService("", "h1", 443, 10, 1.0));
+ altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+ "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector()));
+ altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+ "", "h1", 443, 10, 1.0, SpdyAltSvcWireFormat::VersionVector()));
scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
framer.ProcessInput(frame->data(), frame->size());
@@ -5890,7 +5333,8 @@ TEST_P(SpdyFramerTest, OnAltSvcBadLengths) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- SpdyAltSvcWireFormat::AlternativeService altsvc("pid", "h1", 443, 10, 1.0);
+ SpdyAltSvcWireFormat::AlternativeService altsvc(
+ "pid", "h1", 443, 10, 1.0, SpdyAltSvcWireFormat::VersionVector());
SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
altsvc_vector.push_back(altsvc);
EXPECT_CALL(visitor, OnAltSvc(kStreamId, StringPiece("o1"), altsvc_vector));
@@ -5914,9 +5358,11 @@ TEST_P(SpdyFramerTest, ReadChunkedAltSvcFrame) {
SpdyFramer framer(spdy_version_);
SpdyAltSvcIR altsvc_ir(1);
- SpdyAltSvcWireFormat::AlternativeService altsvc1("pid1", "host", 443, 5, 1.0);
- SpdyAltSvcWireFormat::AlternativeService altsvc2("p\"=i:d", "h_\\o\"st", 123,
- 42, 0.2);
+ SpdyAltSvcWireFormat::AlternativeService altsvc1(
+ "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector());
+ SpdyAltSvcWireFormat::AlternativeService altsvc2(
+ "p\"=i:d", "h_\\o\"st", 123, 42, 0.2,
+ SpdyAltSvcWireFormat::VersionVector{24});
altsvc_ir.add_altsvc(altsvc1);
altsvc_ir.add_altsvc(altsvc2);
diff --git a/chromium/net/spdy/spdy_header_block.cc b/chromium/net/spdy/spdy_header_block.cc
index d12ab70cb90..49243a7a341 100644
--- a/chromium/net/spdy/spdy_header_block.cc
+++ b/chromium/net/spdy/spdy_header_block.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/values.h"
#include "net/http/http_log_util.h"
@@ -18,6 +19,7 @@ using std::dec;
using std::hex;
using std::max;
using std::min;
+using std::string;
namespace net {
namespace {
@@ -157,6 +159,27 @@ SpdyHeaderBlock& SpdyHeaderBlock::operator=(const SpdyHeaderBlock& other) {
return *this;
}
+bool SpdyHeaderBlock::operator==(const SpdyHeaderBlock& other) const {
+ return std::equal(begin(), end(), other.begin());
+}
+
+bool SpdyHeaderBlock::operator!=(const SpdyHeaderBlock& other) const {
+ return !(operator==(other));
+}
+
+string SpdyHeaderBlock::DebugString() const {
+ if (empty()) {
+ return "{}";
+ }
+ string output = "\n{\n";
+ for (auto it = begin(); it != end(); ++it) {
+ output +=
+ " " + it->first.as_string() + ":" + it->second.as_string() + "\n";
+ }
+ output.append("}\n");
+ return output;
+}
+
void SpdyHeaderBlock::clear() {
block_.clear();
storage_->Clear();
@@ -184,10 +207,6 @@ SpdyHeaderBlock::StringPieceProxy SpdyHeaderBlock::operator[](
return StringPieceProxy(&block_, storage_.get(), iter, out_key);
}
-bool SpdyHeaderBlock::operator==(const SpdyHeaderBlock& other) const {
- return size() == other.size() && std::equal(begin(), end(), other.begin());
-}
-
void SpdyHeaderBlock::ReplaceOrAppendHeader(const StringPiece key,
const StringPiece value) {
// TODO(birenroy): Write new value in place of old value, if it fits.
@@ -219,7 +238,7 @@ scoped_ptr<base::Value> SpdyHeaderBlockNetLogCallback(
capture_mode, it->first.as_string(), it->second.as_string())));
}
dict->Set("headers", headers_dict);
- return dict.Pass();
+ return std::move(dict);
}
bool SpdyHeaderBlockFromNetLogParam(
@@ -238,7 +257,7 @@ bool SpdyHeaderBlockFromNetLogParam(
for (base::DictionaryValue::Iterator it(*header_dict); !it.IsAtEnd();
it.Advance()) {
- std::string value;
+ string value;
if (!it.value().GetAsString(&value)) {
headers->clear();
return false;
diff --git a/chromium/net/spdy/spdy_header_block.h b/chromium/net/spdy/spdy_header_block.h
index 7ca62f9b07e..2c57d413fd4 100644
--- a/chromium/net/spdy/spdy_header_block.h
+++ b/chromium/net/spdy/spdy_header_block.h
@@ -5,6 +5,8 @@
#ifndef NET_SPDY_SPDY_HEADER_BLOCK_H_
#define NET_SPDY_SPDY_HEADER_BLOCK_H_
+#include <stddef.h>
+
#include <map>
#include <memory>
#include <string>
@@ -49,6 +51,12 @@ class NET_EXPORT SpdyHeaderBlock {
~SpdyHeaderBlock();
SpdyHeaderBlock& operator=(const SpdyHeaderBlock& other);
+ bool operator==(const SpdyHeaderBlock& other) const;
+ bool operator!=(const SpdyHeaderBlock& other) const;
+
+ // Provides a human readable multi-line representation of the stored header
+ // keys and values.
+ std::string DebugString() const;
// These methods delegate to our MapType member.
iterator begin() { return block_.begin(); }
@@ -73,8 +81,6 @@ class NET_EXPORT SpdyHeaderBlock {
// Allows either lookup or mutation of the value associated with a key.
StringPieceProxy operator[](const base::StringPiece key);
- bool operator==(const SpdyHeaderBlock& other) const;
-
// This object provides automatic conversions that allow SpdyHeaderBlock to be
// nearly a drop-in replacement for linked_hash_map<string, string>. It reads
// data from or writes data to a SpdyHeaderBlock::Storage.
diff --git a/chromium/net/spdy/spdy_header_block_test.cc b/chromium/net/spdy/spdy_header_block_test.cc
index c2568aaa608..ec2b665106c 100644
--- a/chromium/net/spdy/spdy_header_block_test.cc
+++ b/chromium/net/spdy/spdy_header_block_test.cc
@@ -19,7 +19,8 @@ using ::testing::ElementsAre;
namespace net {
-std::pair<StringPiece, StringPiece> Pair(StringPiece k, StringPiece v) {
+std::pair<base::StringPiece, base::StringPiece> Pair(base::StringPiece k,
+ base::StringPiece v) {
return make_pair(k, v);
}
@@ -66,12 +67,8 @@ TEST(SpdyHeaderBlockTest, CopyBlocks) {
SpdyHeaderBlock block3(block1);
- EXPECT_THAT(block1, ElementsAre(Pair("foo", string(300, 'x')),
- Pair("bar", "baz"), Pair("qux", "qux1")));
- EXPECT_THAT(block2, ElementsAre(Pair("foo", string(300, 'x')),
- Pair("bar", "baz"), Pair("qux", "qux1")));
- EXPECT_THAT(block3, ElementsAre(Pair("foo", string(300, 'x')),
- Pair("bar", "baz"), Pair("qux", "qux1")));
+ EXPECT_EQ(block1, block2);
+ EXPECT_EQ(block1, block3);
}
TEST(SpdyHeaderBlockTest, ToNetLogParamAndBackAgain) {
@@ -87,4 +84,19 @@ TEST(SpdyHeaderBlockTest, ToNetLogParamAndBackAgain) {
EXPECT_EQ(headers, headers2);
}
+TEST(SpdyHeaderBlockTest, Equality) {
+ // Test equality and inequality operators.
+ SpdyHeaderBlock block1;
+ block1["foo"] = "bar";
+
+ SpdyHeaderBlock block2;
+ block2["foo"] = "bar";
+
+ SpdyHeaderBlock block3;
+ block3["baz"] = "qux";
+
+ EXPECT_EQ(block1, block2);
+ EXPECT_NE(block1, block3);
+}
+
} // namespace net
diff --git a/chromium/net/spdy/spdy_headers_block_parser.cc b/chromium/net/spdy/spdy_headers_block_parser.cc
index 10057dda770..83a216028d8 100644
--- a/chromium/net/spdy/spdy_headers_block_parser.cc
+++ b/chromium/net/spdy/spdy_headers_block_parser.cc
@@ -14,14 +14,17 @@ const SpdyStreamId kInvalidStreamId = 0;
} // anonymous namespace
+namespace {
+const size_t kLengthFieldSize = sizeof(uint32_t);
+} // anonymous namespace
+
const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024;
SpdyHeadersBlockParser::SpdyHeadersBlockParser(
SpdyMajorVersion spdy_version,
SpdyHeadersHandlerInterface* handler)
: state_(READING_HEADER_BLOCK_LEN),
- length_field_size_(LengthFieldSizeForVersion(spdy_version)),
- max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)),
+ max_headers_in_block_(MaxNumberOfHeaders()),
total_bytes_received_(0),
remaining_key_value_pairs_for_frame_(0),
handler_(handler),
@@ -162,35 +165,22 @@ void SpdyHeadersBlockParser::ParseFieldLength(Reader* reader) {
void SpdyHeadersBlockParser::ParseLength(Reader* reader,
uint32_t* parsed_length) {
char buffer[] = {0, 0, 0, 0};
- if (!reader->ReadN(length_field_size_, buffer)) {
+ if (!reader->ReadN(kLengthFieldSize, buffer)) {
error_ = NEED_MORE_DATA;
return;
}
// Convert from network to host order and return the parsed out integer.
- if (length_field_size_ == sizeof(uint32_t)) {
- *parsed_length = ntohl(*reinterpret_cast<const uint32_t *>(buffer));
- } else {
- *parsed_length = ntohs(*reinterpret_cast<const uint16_t *>(buffer));
- }
-}
-
-size_t SpdyHeadersBlockParser::LengthFieldSizeForVersion(
- SpdyMajorVersion spdy_version) {
- if (spdy_version < SPDY3) {
- return sizeof(uint16_t);
- }
- return sizeof(uint32_t);
+ *parsed_length =
+ base::NetToHost32(*reinterpret_cast<const uint32_t*>(buffer));
}
-size_t SpdyHeadersBlockParser::MaxNumberOfHeadersForVersion(
- SpdyMajorVersion spdy_version) {
+size_t SpdyHeadersBlockParser::MaxNumberOfHeaders() {
// Account for the length of the header block field.
- size_t max_bytes_for_headers =
- kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version);
+ size_t max_bytes_for_headers = kMaximumFieldLength - kLengthFieldSize;
// A minimal size header is twice the length field size (and has a
// zero-lengthed key and a zero-lengthed value).
- return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version));
+ return max_bytes_for_headers / (2 * kLengthFieldSize);
}
} // namespace net
diff --git a/chromium/net/spdy/spdy_headers_block_parser.h b/chromium/net/spdy/spdy_headers_block_parser.h
index 66a6b810c15..4ee8760dc7d 100644
--- a/chromium/net/spdy/spdy_headers_block_parser.h
+++ b/chromium/net/spdy/spdy_headers_block_parser.h
@@ -5,6 +5,9 @@
#ifndef NET_SPDY_SPDY_HEADERS_BLOCK_PARSER_H_
#define NET_SPDY_SPDY_HEADERS_BLOCK_PARSER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
@@ -61,11 +64,8 @@ class NET_EXPORT_PRIVATE SpdyHeadersBlockParser {
SpdyMajorVersion spdy_version() const { return spdy_version_; }
- // Returns the size in bytes of a length field in a SPDY header.
- static size_t LengthFieldSizeForVersion(SpdyMajorVersion spdy_version);
-
// Returns the maximal number of headers in a SPDY headers block.
- static size_t MaxNumberOfHeadersForVersion(SpdyMajorVersion spdy_version);
+ static size_t MaxNumberOfHeaders();
private:
typedef SpdyPrefixedBufferReader Reader;
@@ -90,9 +90,6 @@ class NET_EXPORT_PRIVATE SpdyHeadersBlockParser {
};
ParserState state_;
- // Size in bytes of a length field in the spdy header.
- const size_t length_field_size_;
-
// The maximal number of headers in a SPDY headers block.
const size_t max_headers_in_block_;
diff --git a/chromium/net/spdy/spdy_headers_block_parser_test.cc b/chromium/net/spdy/spdy_headers_block_parser_test.cc
index 324a1e51747..85beb6cd7b4 100644
--- a/chromium/net/spdy/spdy_headers_block_parser_test.cc
+++ b/chromium/net/spdy/spdy_headers_block_parser_test.cc
@@ -40,8 +40,6 @@ class SpdyHeadersBlockParserTest :
spdy_version_ = GetParam();
parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_));
- length_field_size_ =
- SpdyHeadersBlockParser::LengthFieldSizeForVersion(spdy_version_);
}
// Create a header block with a specified number of headers.
@@ -80,19 +78,11 @@ class SpdyHeadersBlockParserTest :
string EncodeLength(uint32_t len) {
char buffer[4];
- if (length_field_size_ == sizeof(uint32_t)) {
- uint32_t net_order_len = htonl(len);
- memcpy(buffer, &net_order_len, length_field_size_);
- } else if (length_field_size_ == sizeof(uint16_t)) {
- uint16_t net_order_len = htons(len);
- memcpy(buffer, &net_order_len, length_field_size_);
- } else {
- CHECK(false) << "Invalid length field size";
- }
- return string(buffer, length_field_size_);
+ uint32_t net_order_len = base::HostToNet32(len);
+ memcpy(buffer, &net_order_len, sizeof(uint32_t));
+ return string(buffer, sizeof(uint32_t));
}
- size_t length_field_size_;
SpdyMajorVersion spdy_version_;
MockSpdyHeadersHandler handler_;
@@ -109,10 +99,10 @@ class SpdyHeadersBlockParserTest :
const char *const SpdyHeadersBlockParserTest::kBaseKey = "test_key";
const char *const SpdyHeadersBlockParserTest::kBaseValue = "test_value";
-// All tests are run with 3 different SPDY versions: SPDY/2, SPDY/3, HTTP/2.
+// All tests are run with SPDY/3 and HTTP/2.
INSTANTIATE_TEST_CASE_P(SpdyHeadersBlockParserTests,
SpdyHeadersBlockParserTest,
- ::testing::Values(SPDY2, SPDY3, HTTP2));
+ ::testing::Values(SPDY3, HTTP2));
TEST_P(SpdyHeadersBlockParserTest, BasicTest) {
// Sanity test, verify that we parse out correctly a block with
@@ -218,8 +208,7 @@ TEST_P(SpdyHeadersBlockParserTest, HandlesEmptyCallsTest) {
TEST_P(SpdyHeadersBlockParserTest, LargeBlocksDiscardedTest) {
// Header block with too many headers.
{
- string headers = EncodeLength(
- parser_->MaxNumberOfHeadersForVersion(spdy_version_) + 1);
+ string headers = EncodeLength(parser_->MaxNumberOfHeaders() + 1);
EXPECT_FALSE(parser_->
HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE,
diff --git a/chromium/net/spdy/spdy_headers_handler_interface.h b/chromium/net/spdy/spdy_headers_handler_interface.h
index ff5648adde1..5543194752e 100644
--- a/chromium/net/spdy/spdy_headers_handler_interface.h
+++ b/chromium/net/spdy/spdy_headers_handler_interface.h
@@ -5,6 +5,8 @@
#ifndef NET_SPDY_SPDY_HEADERS_HANDLER_INTERFACE_H_
#define NET_SPDY_SPDY_HEADERS_HANDLER_INTERFACE_H_
+#include <stddef.h>
+
#include "base/strings/string_piece.h"
namespace net {
diff --git a/chromium/net/spdy/spdy_http_stream.cc b/chromium/net/spdy/spdy_http_stream.cc
index 6cf1d737c10..16e19b209ab 100644
--- a/chromium/net/spdy/spdy_http_stream.cc
+++ b/chromium/net/spdy/spdy_http_stream.cc
@@ -6,8 +6,10 @@
#include <algorithm>
#include <list>
+#include <utility>
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
@@ -115,8 +117,8 @@ int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
}
// Still waiting for the response, return IO_PENDING.
- CHECK(callback_.is_null());
- callback_ = callback;
+ CHECK(response_callback_.is_null());
+ response_callback_ = callback;
return ERR_IO_PENDING;
}
@@ -136,11 +138,11 @@ int SpdyHttpStream::ReadResponseBody(
return closed_stream_status_;
}
- CHECK(callback_.is_null());
+ CHECK(response_callback_.is_null());
CHECK(!user_buffer_.get());
CHECK_EQ(0, user_buffer_len_);
- callback_ = callback;
+ response_callback_ = callback;
user_buffer_ = buf;
user_buffer_len_ = buf_len;
return ERR_IO_PENDING;
@@ -268,31 +270,32 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
// idle. However, we still want to return ERR_IO_PENDING to mimic
// non-push behavior. The callback will be called when the
// response is received.
- result = ERR_IO_PENDING;
- } else {
- scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
- CreateSpdyHeadersFromHttpRequest(
- *request_info_, request_headers,
- stream_->GetProtocolVersion(), direct_,
- headers.get());
- stream_->net_log().AddEvent(
- NetLog::TYPE_HTTP_TRANSACTION_HTTP2_SEND_REQUEST_HEADERS,
- base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get()));
- result =
- stream_->SendRequestHeaders(
- headers.Pass(),
- HasUploadData() ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND);
+ CHECK(response_callback_.is_null());
+ response_callback_ = callback;
+ return ERR_IO_PENDING;
}
+ scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
+ CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
+ stream_->GetProtocolVersion(), direct_,
+ headers.get());
+ stream_->net_log().AddEvent(
+ NetLog::TYPE_HTTP_TRANSACTION_HTTP2_SEND_REQUEST_HEADERS,
+ base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get()));
+ result = stream_->SendRequestHeaders(
+ std::move(headers),
+ HasUploadData() ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND);
+
if (result == ERR_IO_PENDING) {
- CHECK(callback_.is_null());
- callback_ = callback;
+ CHECK(request_callback_.is_null());
+ request_callback_ = callback;
}
return result;
}
void SpdyHttpStream::Cancel() {
- callback_.Reset();
+ request_callback_.Reset();
+ response_callback_.Reset();
if (stream_.get()) {
stream_->Cancel();
DCHECK(!stream_.get());
@@ -300,8 +303,8 @@ void SpdyHttpStream::Cancel() {
}
void SpdyHttpStream::OnRequestHeadersSent() {
- if (!callback_.is_null())
- DoCallback(OK);
+ if (!request_callback_.is_null())
+ DoRequestCallback(OK);
// TODO(akalin): Do this immediately after sending the request
// headers.
@@ -342,8 +345,9 @@ SpdyResponseHeadersStatus SpdyHttpStream::OnResponseHeadersUpdated(
response_info_->vary_data
.Init(*request_info_, *response_info_->headers.get());
- if (!callback_.is_null())
- DoCallback(OK);
+ if (!response_callback_.is_null()) {
+ DoResponseCallback(OK);
+ }
return RESPONSE_HEADERS_ARE_COMPLETE;
}
@@ -357,7 +361,7 @@ void SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
DCHECK(stream_.get());
DCHECK(!stream_->IsClosed() || stream_->type() == SPDY_PUSH_STREAM);
if (buffer) {
- response_body_queue_.Enqueue(buffer.Pass());
+ response_body_queue_.Enqueue(std::move(buffer));
if (user_buffer_.get()) {
// Handing small chunks of data to the caller creates measurable overhead.
@@ -391,13 +395,25 @@ void SpdyHttpStream::OnClose(int status) {
}
stream_.reset();
- bool invoked_callback = false;
+ // Callbacks might destroy |this|.
+ base::WeakPtr<SpdyHttpStream> self = weak_factory_.GetWeakPtr();
+
+ if (!request_callback_.is_null()) {
+ DoRequestCallback(status);
+ if (!self)
+ return;
+ }
+
if (status == OK) {
// We need to complete any pending buffered read now.
- invoked_callback = DoBufferedReadCallback();
+ DoBufferedReadCallback();
+ if (!self)
+ return;
+ }
+
+ if (!response_callback_.is_null()) {
+ DoResponseCallback(status);
}
- if (!invoked_callback && !callback_.is_null())
- DoCallback(status);
}
bool SpdyHttpStream::HasUploadData() const {
@@ -466,9 +482,8 @@ void SpdyHttpStream::ScheduleBufferedReadCallback() {
buffered_read_callback_pending_ = true;
const base::TimeDelta kBufferTime = base::TimeDelta::FromMilliseconds(1);
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(&SpdyHttpStream::DoBufferedReadCallback),
- weak_factory_.GetWeakPtr()),
+ FROM_HERE, base::Bind(&SpdyHttpStream::DoBufferedReadCallback,
+ weak_factory_.GetWeakPtr()),
kBufferTime);
}
@@ -484,47 +499,54 @@ bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const {
static_cast<size_t>(user_buffer_len_);
}
-bool SpdyHttpStream::DoBufferedReadCallback() {
+void SpdyHttpStream::DoBufferedReadCallback() {
buffered_read_callback_pending_ = false;
// If the transaction is cancelled or errored out, we don't need to complete
// the read.
if (!stream_.get() && !stream_closed_)
- return false;
+ return;
int stream_status =
stream_closed_ ? closed_stream_status_ : stream_->response_status();
if (stream_status != OK)
- return false;
+ return;
// When more_read_data_pending_ is true, it means that more data has
// arrived since we started waiting. Wait a little longer and continue
// to buffer.
if (more_read_data_pending_ && ShouldWaitForMoreBufferedData()) {
ScheduleBufferedReadCallback();
- return false;
+ return;
}
int rv = 0;
if (user_buffer_.get()) {
- rv = ReadResponseBody(user_buffer_.get(), user_buffer_len_, callback_);
+ rv = ReadResponseBody(user_buffer_.get(), user_buffer_len_,
+ response_callback_);
CHECK_NE(rv, ERR_IO_PENDING);
user_buffer_ = NULL;
user_buffer_len_ = 0;
- DoCallback(rv);
- return true;
+ DoResponseCallback(rv);
}
- return false;
}
-void SpdyHttpStream::DoCallback(int rv) {
+void SpdyHttpStream::DoRequestCallback(int rv) {
CHECK_NE(rv, ERR_IO_PENDING);
- CHECK(!callback_.is_null());
+ CHECK(!request_callback_.is_null());
- // Since Run may result in being called back, clear user_callback_ in advance.
- CompletionCallback c = callback_;
- callback_.Reset();
- c.Run(rv);
+ // Since Run may result in being called back, reset request_callback_ in
+ // advance.
+ ResetAndReturn(&request_callback_).Run(rv);
+}
+
+void SpdyHttpStream::DoResponseCallback(int rv) {
+ CHECK_NE(rv, ERR_IO_PENDING);
+ CHECK(!response_callback_.is_null());
+
+ // Since Run may result in being called back, reset response_callback_ in
+ // advance.
+ ResetAndReturn(&response_callback_).Run(rv);
}
void SpdyHttpStream::GetSSLInfo(SSLInfo* ssl_info) {
@@ -554,6 +576,10 @@ void SpdyHttpStream::Drain(HttpNetworkSession* session) {
delete this;
}
+void SpdyHttpStream::PopulateNetErrorDetails(NetErrorDetails* /*details*/) {
+ return;
+}
+
void SpdyHttpStream::SetPriority(RequestPriority priority) {
// TODO(akalin): Plumb this through to |stream_request_| and
// |stream_|.
diff --git a/chromium/net/spdy/spdy_http_stream.h b/chromium/net/spdy/spdy_http_stream.h
index b51869c257a..a79569a33f0 100644
--- a/chromium/net/spdy/spdy_http_stream.h
+++ b/chromium/net/spdy/spdy_http_stream.h
@@ -9,7 +9,7 @@
#include <list>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/base/completion_callback.h"
@@ -80,6 +80,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
bool GetRemoteEndpoint(IPEndPoint* endpoint) override;
void Drain(HttpNetworkSession* session) override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) override;
void SetPriority(RequestPriority priority) override;
// SpdyStream::Delegate implementation.
@@ -107,13 +108,14 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
// does the actual sending of data.
void OnRequestBodyReadCompleted(int status);
- // Call the user callback.
- void DoCallback(int rv);
+ // Call the user callback associated with sending the request.
+ void DoRequestCallback(int rv);
- void ScheduleBufferedReadCallback();
+ // Call the user callback associated with reading the response.
+ void DoResponseCallback(int rv);
- // Returns true if the callback is invoked.
- bool DoBufferedReadCallback();
+ void ScheduleBufferedReadCallback();
+ void DoBufferedReadCallback();
bool ShouldWaitForMoreBufferedData() const;
const base::WeakPtr<SpdySession> spdy_session_;
@@ -152,7 +154,8 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
// We buffer the response body as it arrives asynchronously from the stream.
SpdyReadQueue response_body_queue_;
- CompletionCallback callback_;
+ CompletionCallback request_callback_;
+ CompletionCallback response_callback_;
// User provided buffer for the ReadResponseBody() response.
scoped_refptr<IOBuffer> user_buffer_;
diff --git a/chromium/net/spdy/spdy_http_stream_unittest.cc b/chromium/net/spdy/spdy_http_stream_unittest.cc
index 69ad12c8474..9aff81b57b5 100644
--- a/chromium/net/spdy/spdy_http_stream_unittest.cc
+++ b/chromium/net/spdy/spdy_http_stream_unittest.cc
@@ -34,6 +34,19 @@ namespace net {
namespace {
+enum TestCase {
+ // Test using the SPDY/3.1 protocol.
+ kTestCaseSPDY31,
+
+ // Test using the HTTP/2 protocol, without specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2NoPriorityDependencies,
+
+ // Test using the HTTP/2 protocol, specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2PriorityDependencies
+};
+
// Tests the load timing of a stream that's connected and is not the first
// request sent on a connection.
void TestLoadTimingReused(const HttpStream& stream) {
@@ -64,15 +77,29 @@ void TestLoadTimingNotReused(const HttpStream& stream) {
} // namespace
class SpdyHttpStreamTest : public testing::Test,
- public testing::WithParamInterface<NextProto> {
+ public testing::WithParamInterface<TestCase> {
public:
SpdyHttpStreamTest()
- : spdy_util_(GetParam()),
- session_deps_(GetParam()) {
+ : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
+ session_deps_(GetProtocol()) {
+ SpdySession::SetPriorityDependencyDefaultForTesting(
+ GetDependenciesFromPriority());
session_deps_.net_log = &net_log_;
}
+ ~SpdyHttpStreamTest() {
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
+ }
+
protected:
+ NextProto GetProtocol() const {
+ return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
+ }
+
+ bool GetDependenciesFromPriority() const {
+ return GetParam() == kTestCaseHTTP2PriorityDependencies;
+ }
+
void TearDown() override {
crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
base::MessageLoop::current()->RunUntilIdle();
@@ -90,7 +117,8 @@ class SpdyHttpStreamTest : public testing::Test,
new SequencedSocketData(reads, reads_count, writes, writes_count));
session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get());
http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
- session_ = CreateInsecureSpdySession(http_session_, key, BoundNetLog());
+ session_ =
+ CreateInsecureSpdySession(http_session_.get(), key, BoundNetLog());
}
void TestSendCredentials(
@@ -102,17 +130,18 @@ class SpdyHttpStreamTest : public testing::Test,
TestNetLog net_log_;
SpdySessionDependencies session_deps_;
scoped_ptr<SequencedSocketData> sequenced_data_;
- scoped_refptr<HttpNetworkSession> http_session_;
+ scoped_ptr<HttpNetworkSession> http_session_;
base::WeakPtr<SpdySession> session_;
private:
MockECSignatureCreatorFactory ec_signature_creator_factory_;
};
-INSTANTIATE_TEST_CASE_P(NextProto,
+INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
SpdyHttpStreamTest,
- testing::Values(kProtoSPDY31,
- kProtoHTTP2));
+ testing::Values(kTestCaseSPDY31,
+ kTestCaseHTTP2NoPriorityDependencies,
+ kTestCaseHTTP2PriorityDependencies));
// SpdyHttpStream::GetUploadProgress() should still work even before the
// stream is initialized.
@@ -815,7 +844,7 @@ TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) {
http_stream->stream()->send_window_size());
// Read rest of data.
- sequenced_data_->CompleteRead();
+ sequenced_data_->Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(static_cast<int64_t>(req->size() + chunk1->size()),
diff --git a/chromium/net/spdy/spdy_http_utils.cc b/chromium/net/spdy/spdy_http_utils.cc
index 7162d96f3a1..8692305bf56 100644
--- a/chromium/net/spdy/spdy_http_utils.cc
+++ b/chromium/net/spdy/spdy_http_utils.cc
@@ -84,7 +84,7 @@ bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers,
tval = value.substr(start, (end - start));
else
tval = value.substr(start);
- if (protocol_version >= 3 && it->first[0] == ':')
+ if (it->first[0] == ':')
raw_headers.append(it->first.as_string().substr(1));
else
raw_headers.append(it->first.as_string());
@@ -107,19 +107,6 @@ void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info,
SpdyHeaderBlock* headers) {
static const char kHttpProtocolVersion[] = "HTTP/1.1";
switch (protocol_version) {
- case SPDY2:
- // TODO(bnc): Remove this code now that SPDY/2 is deprecated.
- (*headers)["version"] = kHttpProtocolVersion;
- (*headers)["method"] = info.method;
- (*headers)["host"] = GetHostAndOptionalPort(info.url);
- if (info.method == "CONNECT") {
- (*headers)["url"] = GetHostAndPort(info.url);
- } else {
- (*headers)["scheme"] = info.url.scheme();
- (*headers)["url"] = direct ? info.url.PathForRequest()
- : HttpUtil::SpecForRequest(info.url);
- }
- break;
case SPDY3:
(*headers)[":version"] = kHttpProtocolVersion;
(*headers)[":method"] = info.method;
@@ -171,7 +158,11 @@ void CreateSpdyHeadersFromHttpResponse(
if (protocol_version < HTTP2) {
(*headers)[version_key] = std::string(status_line.begin(), after_version);
}
- (*headers)[status_key] = std::string(after_version + 1, status_line.end());
+
+ // Get status code only.
+ std::string::const_iterator after_status =
+ std::find(after_version + 1, status_line.end(), ' ');
+ (*headers)[status_key] = std::string(after_version + 1, after_status);
void* iter = NULL;
std::string raw_name, value;
diff --git a/chromium/net/spdy/spdy_http_utils_unittest.cc b/chromium/net/spdy/spdy_http_utils_unittest.cc
index 7a94ecabd52..a53e33145d2 100644
--- a/chromium/net/spdy/spdy_http_utils_unittest.cc
+++ b/chromium/net/spdy/spdy_http_utils_unittest.cc
@@ -4,7 +4,10 @@
#include "net/spdy/spdy_http_utils.h"
-#include "base/basictypes.h"
+#include <stdint.h>
+
+#include <limits>
+
#include "net/http/http_request_info.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_test_utils.h"
@@ -34,28 +37,11 @@ TEST(SpdyHttpUtilsTest, ConvertSpdy3PriorityToRequestPriority) {
EXPECT_EQ(IDLE, ConvertSpdyPriorityToRequestPriority(4, SPDY3));
// These are invalid values, but we should still handle them
// gracefully.
- for (int i = 5; i < kuint8max; ++i) {
+ for (int i = 5; i < std::numeric_limits<uint8_t>::max(); ++i) {
EXPECT_EQ(IDLE, ConvertSpdyPriorityToRequestPriority(i, SPDY3));
}
}
-TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestSPDY2) {
- GURL url("https://www.google.com/index.html");
- HttpRequestInfo request;
- request.method = "GET";
- request.url = url;
- request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, "Chrome/1.1");
- SpdyHeaderBlock headers;
- CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, SPDY2,
- kDirect, &headers);
- EXPECT_EQ("GET", headers["method"]);
- EXPECT_EQ("https", headers["scheme"]);
- EXPECT_EQ("www.google.com", headers["host"]);
- EXPECT_EQ("/index.html", headers["url"]);
- EXPECT_EQ("HTTP/1.1", headers["version"]);
- EXPECT_EQ("Chrome/1.1", headers["user-agent"]);
-}
-
TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestSPDY3) {
GURL url("https://www.google.com/index.html");
HttpRequestInfo request;
@@ -90,23 +76,6 @@ TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestHTTP2) {
EXPECT_EQ("Chrome/1.1", headers["user-agent"]);
}
-TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestProxySPDY2) {
- GURL url("https://www.google.com/index.html");
- HttpRequestInfo request;
- request.method = "GET";
- request.url = url;
- request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, "Chrome/1.1");
- SpdyHeaderBlock headers;
- CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, SPDY2,
- !kDirect, &headers);
- EXPECT_EQ("GET", headers["method"]);
- EXPECT_EQ("https", headers["scheme"]);
- EXPECT_EQ("www.google.com", headers["host"]);
- EXPECT_EQ("https://www.google.com/index.html", headers["url"]);
- EXPECT_EQ("HTTP/1.1", headers["version"]);
- EXPECT_EQ("Chrome/1.1", headers["user-agent"]);
-}
-
TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestProxySPDY3) {
GURL url("https://www.google.com/index.html");
HttpRequestInfo request;
@@ -141,23 +110,6 @@ TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestProxyHTTP2) {
EXPECT_EQ("Chrome/1.1", headers["user-agent"]);
}
-TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestConnectSPDY2) {
- GURL url("https://www.google.com/index.html");
- HttpRequestInfo request;
- request.method = "CONNECT";
- request.url = url;
- request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, "Chrome/1.1");
- SpdyHeaderBlock headers;
- CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, SPDY2,
- kDirect, &headers);
- EXPECT_EQ("CONNECT", headers["method"]);
- EXPECT_TRUE(headers.end() == headers.find("scheme"));
- EXPECT_EQ("www.google.com", headers["host"]);
- EXPECT_EQ("www.google.com:443", headers["url"]);
- EXPECT_EQ("HTTP/1.1", headers["version"]);
- EXPECT_EQ("Chrome/1.1", headers["user-agent"]);
-}
-
TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestConnectSPDY3) {
GURL url("https://www.google.com/index.html");
HttpRequestInfo request;
diff --git a/chromium/net/spdy/spdy_network_transaction_unittest.cc b/chromium/net/spdy/spdy_network_transaction_unittest.cc
index fa6294ad000..59951ae8f7b 100644
--- a/chromium/net/spdy/spdy_network_transaction_unittest.cc
+++ b/chromium/net/spdy/spdy_network_transaction_unittest.cc
@@ -3,15 +3,15 @@
// found in the LICENSE file.
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
-#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/test/test_file_util.h"
#include "base/thread_task_runner_handle.h"
@@ -22,6 +22,7 @@
#include "net/base/test_data_directory.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_file_element_reader.h"
+#include "net/http/http_auth_scheme.h"
#include "net/http/http_network_session_peer.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_server_properties.h"
@@ -65,11 +66,16 @@ enum SpdyNetworkTransactionTestSSLType {
struct SpdyNetworkTransactionTestParams {
SpdyNetworkTransactionTestParams()
- : protocol(kProtoSPDY31), ssl_type(HTTPS_SPDY_VIA_NPN) {}
+ : protocol(kProtoSPDY31),
+ ssl_type(HTTPS_SPDY_VIA_NPN),
+ priority_to_dependency(false) {}
SpdyNetworkTransactionTestParams(NextProto protocol,
- SpdyNetworkTransactionTestSSLType ssl_type)
- : protocol(protocol), ssl_type(ssl_type) {}
+ SpdyNetworkTransactionTestSSLType ssl_type,
+ bool priority_to_dependency)
+ : protocol(protocol),
+ ssl_type(ssl_type),
+ priority_to_dependency(priority_to_dependency) {}
friend std::ostream& operator<<(std::ostream& os,
const SpdyNetworkTransactionTestParams& p) {
@@ -83,12 +89,14 @@ struct SpdyNetworkTransactionTestParams {
break;
}
os << "{ protocol: " << SSLClientSocket::NextProtoToString(p.protocol)
- << ", ssl_type: " << type_str << " }";
+ << ", ssl_type: " << type_str
+ << ", priority_to_dependency: " << p.priority_to_dependency << " }";
return os;
}
NextProto protocol;
SpdyNetworkTransactionTestSSLType ssl_type;
+ bool priority_to_dependency;
};
void UpdateSpdySessionDependencies(SpdyNetworkTransactionTestParams test_params,
@@ -116,8 +124,8 @@ scoped_ptr<SpdySessionDependencies> CreateSpdySessionDependencies(
scoped_ptr<SpdySessionDependencies> CreateSpdySessionDependencies(
SpdyNetworkTransactionTestParams test_params,
scoped_ptr<ProxyService> proxy_service) {
- scoped_ptr<SpdySessionDependencies> session_deps(
- new SpdySessionDependencies(test_params.protocol, proxy_service.Pass()));
+ scoped_ptr<SpdySessionDependencies> session_deps(new SpdySessionDependencies(
+ test_params.protocol, std::move(proxy_service)));
UpdateSpdySessionDependencies(test_params, session_deps.get());
return session_deps;
}
@@ -127,7 +135,10 @@ scoped_ptr<SpdySessionDependencies> CreateSpdySessionDependencies(
class SpdyNetworkTransactionTest
: public ::testing::TestWithParam<SpdyNetworkTransactionTestParams> {
protected:
- SpdyNetworkTransactionTest() : spdy_util_(GetParam().protocol) {
+ SpdyNetworkTransactionTest()
+ : spdy_util_(GetParam().protocol, GetParam().priority_to_dependency) {
+ SpdySession::SetPriorityDependencyDefaultForTesting(
+ GetParam().priority_to_dependency);
spdy_util_.set_default_url(GURL(GetDefaultUrl()));
}
@@ -136,6 +147,7 @@ class SpdyNetworkTransactionTest
// destruction.
upload_data_stream_.reset();
base::RunLoop().RunUntilIdle();
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
}
void SetUp() override {
@@ -165,13 +177,12 @@ class SpdyNetworkTransactionTest
priority_(priority),
session_deps_(session_deps.get() == NULL
? CreateSpdySessionDependencies(test_params)
- : session_deps.Pass()),
+ : std::move(session_deps)),
session_(
SpdySessionDependencies::SpdyCreateSession(session_deps_.get())),
log_(log),
test_params_(test_params),
port_(443),
- deterministic_(false),
spdy_enabled_(true) {}
~NormalSpdyTransactionHelper() {
@@ -186,12 +197,6 @@ class SpdyNetworkTransactionTest
session()->spdy_session_pool()->CloseAllSessions();
}
- void SetDeterministic() {
- session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
- session_deps_.get());
- deterministic_ = true;
- }
-
void SetSpdyDisabled() {
spdy_enabled_ = false;
port_ = test_params_.ssl_type == HTTP_SPDY_VIA_ALT_SVC ? 80 : 443;
@@ -235,8 +240,6 @@ class SpdyNetworkTransactionTest
const HttpResponseInfo* response = trans_->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
- EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy);
if (HttpStreamFactory::spdy_enabled()) {
EXPECT_EQ(
HttpResponseInfo::ConnectionInfoFromNextProto(
@@ -247,8 +250,12 @@ class SpdyNetworkTransactionTest
response->connection_info);
}
if (spdy_enabled_) {
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
} else {
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
// If SPDY is disabled, an HTTP request should not be diverted
// over an SSL session.
EXPECT_EQ(request_.url.SchemeIs("https"),
@@ -267,6 +274,8 @@ class SpdyNetworkTransactionTest
session_->spdy_session_pool()->CloseCurrentSessions(ERR_ABORTED);
}
+ void WaitForHeaders() { output_.rv = callback_.WaitForResult(); }
+
// Most tests will want to call this function. In particular, the MockReads
// should end with an empty read, and that read needs to be processed to
// ensure proper deletion of the spdy_session_pool.
@@ -275,11 +284,6 @@ class SpdyNetworkTransactionTest
EXPECT_TRUE(provider->AllReadDataConsumed());
EXPECT_TRUE(provider->AllWriteDataConsumed());
}
- for (const DeterministicSocketData* provider :
- deterministic_data_vector_) {
- EXPECT_TRUE(provider->AllReadDataConsumed());
- EXPECT_TRUE(provider->AllWriteDataConsumed());
- }
}
// Occasionally a test will expect to error out before certain reads are
@@ -290,11 +294,6 @@ class SpdyNetworkTransactionTest
EXPECT_FALSE(provider->AllReadDataConsumed());
EXPECT_FALSE(provider->AllWriteDataConsumed());
}
- for (const DeterministicSocketData* provider :
- deterministic_data_vector_) {
- EXPECT_FALSE(provider->AllReadDataConsumed());
- EXPECT_FALSE(provider->AllWriteDataConsumed());
- }
}
void RunToCompletion(SocketDataProvider* data) {
@@ -308,7 +307,7 @@ class SpdyNetworkTransactionTest
SocketDataProvider* data,
scoped_ptr<SSLSocketDataProvider> ssl_provider) {
RunPreTestSetup();
- AddDataWithSSLSocketDataProvider(data, ssl_provider.Pass());
+ AddDataWithSSLSocketDataProvider(data, std::move(ssl_provider));
RunDefaultTest();
VerifyDataConsumed();
}
@@ -318,13 +317,12 @@ class SpdyNetworkTransactionTest
new SSLSocketDataProvider(ASYNC, OK));
ssl_provider->cert =
ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
- AddDataWithSSLSocketDataProvider(data, ssl_provider.Pass());
+ AddDataWithSSLSocketDataProvider(data, std::move(ssl_provider));
}
void AddDataWithSSLSocketDataProvider(
SocketDataProvider* data,
scoped_ptr<SSLSocketDataProvider> ssl_provider) {
- DCHECK(!deterministic_);
data_vector_.push_back(data);
if (ssl_provider->next_proto_status ==
SSLClientSocket::kNextProtoUnsupported) {
@@ -333,54 +331,28 @@ class SpdyNetworkTransactionTest
session_deps_->socket_factory->AddSSLSocketDataProvider(
ssl_provider.get());
- ssl_vector_.push_back(ssl_provider.release());
+ ssl_vector_.push_back(std::move(ssl_provider));
session_deps_->socket_factory->AddSocketDataProvider(data);
if (test_params_.ssl_type == HTTP_SPDY_VIA_ALT_SVC) {
MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
- StaticSocketDataProvider* hanging_non_alt_svc_socket =
- new StaticSocketDataProvider(NULL, 0, NULL, 0);
+ scoped_ptr<StaticSocketDataProvider> hanging_non_alt_svc_socket(
+ make_scoped_ptr(new StaticSocketDataProvider(NULL, 0, NULL, 0)));
hanging_non_alt_svc_socket->set_connect_data(hanging_connect);
session_deps_->socket_factory->AddSocketDataProvider(
- hanging_non_alt_svc_socket);
- alternate_vector_.push_back(hanging_non_alt_svc_socket);
- }
- }
-
- void AddDeterministicData(DeterministicSocketData* data) {
- DCHECK(deterministic_);
- deterministic_data_vector_.push_back(data);
- SSLSocketDataProvider* ssl_provider =
- new SSLSocketDataProvider(ASYNC, OK);
- ssl_provider->SetNextProto(test_params_.protocol);
- ssl_provider->cert =
- ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
- ssl_vector_.push_back(ssl_provider);
- session_deps_->deterministic_socket_factory->AddSSLSocketDataProvider(
- ssl_provider);
-
- session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
- if (test_params_.ssl_type == HTTP_SPDY_VIA_ALT_SVC) {
- MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
- DeterministicSocketData* hanging_non_alt_svc_socket =
- new DeterministicSocketData(NULL, 0, NULL, 0);
- hanging_non_alt_svc_socket->set_connect_data(hanging_connect);
- session_deps_->deterministic_socket_factory->AddSocketDataProvider(
- hanging_non_alt_svc_socket);
- alternate_deterministic_vector_.push_back(hanging_non_alt_svc_socket);
+ hanging_non_alt_svc_socket.get());
+ alternate_vector_.push_back(std::move(hanging_non_alt_svc_socket));
}
}
- void SetSession(const scoped_refptr<HttpNetworkSession>& session) {
- session_ = session;
+ void SetSession(scoped_ptr<HttpNetworkSession> session) {
+ session_ = std::move(session);
}
HttpNetworkTransaction* trans() { return trans_.get(); }
void ResetTrans() { trans_.reset(); }
TransactionHelperResult& output() { return output_; }
const HttpRequestInfo& request() const { return request_; }
- const scoped_refptr<HttpNetworkSession>& session() const {
- return session_;
- }
+ HttpNetworkSession* session() const { return session_.get(); }
scoped_ptr<SpdySessionDependencies>& session_deps() {
return session_deps_;
}
@@ -391,14 +363,12 @@ class SpdyNetworkTransactionTest
private:
typedef std::vector<SocketDataProvider*> DataVector;
- typedef std::vector<DeterministicSocketData*> DeterministicDataVector;
- typedef ScopedVector<SSLSocketDataProvider> SSLVector;
- typedef ScopedVector<SocketDataProvider> AlternateVector;
- typedef ScopedVector<DeterministicSocketData> AlternateDeterministicVector;
+ typedef std::vector<scoped_ptr<SSLSocketDataProvider>> SSLVector;
+ typedef std::vector<scoped_ptr<SocketDataProvider>> AlternateVector;
HttpRequestInfo request_;
RequestPriority priority_;
scoped_ptr<SpdySessionDependencies> session_deps_;
- scoped_refptr<HttpNetworkSession> session_;
+ scoped_ptr<HttpNetworkSession> session_;
TransactionHelperResult output_;
scoped_ptr<SocketDataProvider> first_transaction_;
SSLVector ssl_vector_;
@@ -406,13 +376,10 @@ class SpdyNetworkTransactionTest
scoped_ptr<HttpNetworkTransaction> trans_;
scoped_ptr<HttpNetworkTransaction> trans_http_;
DataVector data_vector_;
- DeterministicDataVector deterministic_data_vector_;
AlternateVector alternate_vector_;
- AlternateDeterministicVector alternate_deterministic_vector_;
const BoundNetLog log_;
SpdyNetworkTransactionTestParams test_params_;
int port_;
- bool deterministic_;
bool spdy_enabled_;
};
@@ -451,11 +418,11 @@ class SpdyNetworkTransactionTest
const HttpRequestInfo& CreatePostRequest() {
if (!post_request_initialized_) {
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(
- new UploadBytesElementReader(kUploadData, kUploadDataSize));
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(
+ new UploadBytesElementReader(kUploadData, kUploadDataSize)));
upload_data_stream_.reset(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
post_request_.method = "POST";
post_request_.url = GURL(GetDefaultUrl());
@@ -472,12 +439,12 @@ class SpdyNetworkTransactionTest
CHECK_EQ(static_cast<int>(kUploadDataSize),
base::WriteFile(file_path, kUploadData, kUploadDataSize));
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadFileElementReader(
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
base::ThreadTaskRunnerHandle::Get().get(), file_path, 0,
- kUploadDataSize, base::Time()));
+ kUploadDataSize, base::Time())));
upload_data_stream_.reset(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
post_request_.method = "POST";
post_request_.url = GURL(GetDefaultUrl());
@@ -497,12 +464,12 @@ class SpdyNetworkTransactionTest
base::WriteFile(file_path, kUploadData, kUploadDataSize));
CHECK(base::MakeFileUnreadable(file_path));
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(new UploadFileElementReader(
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
base::ThreadTaskRunnerHandle::Get().get(), file_path, 0,
- kUploadDataSize, base::Time()));
+ kUploadDataSize, base::Time())));
upload_data_stream_.reset(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
post_request_.method = "POST";
post_request_.url = GURL(GetDefaultUrl());
@@ -522,17 +489,17 @@ class SpdyNetworkTransactionTest
CHECK_EQ(static_cast<int>(kUploadDataSize),
base::WriteFile(file_path, kUploadData, kUploadDataSize));
- ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(
- new UploadBytesElementReader(kUploadData, kFileRangeOffset));
- element_readers.push_back(new UploadFileElementReader(
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ element_readers.push_back(make_scoped_ptr(
+ new UploadBytesElementReader(kUploadData, kFileRangeOffset)));
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
base::ThreadTaskRunnerHandle::Get().get(), file_path,
- kFileRangeOffset, kFileRangeLength, base::Time()));
- element_readers.push_back(new UploadBytesElementReader(
+ kFileRangeOffset, kFileRangeLength, base::Time())));
+ element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
kUploadData + kFileRangeOffset + kFileRangeLength,
- kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
+ kUploadDataSize - (kFileRangeOffset + kFileRangeLength))));
upload_data_stream_.reset(
- new ElementsUploadDataStream(element_readers.Pass(), 0));
+ new ElementsUploadDataStream(std::move(element_readers), 0));
post_request_.method = "POST";
post_request_.url = GURL(GetDefaultUrl());
@@ -587,7 +554,7 @@ class SpdyNetworkTransactionTest
SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
BoundNetLog log;
- const scoped_refptr<HttpNetworkSession>& session = helper.session();
+ HttpNetworkSession* session = helper.session();
base::WeakPtr<SpdySession> spdy_session =
session->spdy_session_pool()->FindAvailableSession(key, log);
ASSERT_TRUE(spdy_session != NULL);
@@ -615,7 +582,7 @@ class SpdyNetworkTransactionTest
// Request the pushed path.
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
rv = trans2->Start(
&CreateGetPushRequest(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -654,12 +621,11 @@ class SpdyNetworkTransactionTest
helper->ResetTrans();
}
- static void StartTransactionCallback(
- const scoped_refptr<HttpNetworkSession>& session,
- GURL url,
- int result) {
+ static void StartTransactionCallback(HttpNetworkSession* session,
+ GURL url,
+ int result) {
scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
TestCompletionCallback callback;
HttpRequestInfo request;
request.method = "GET";
@@ -715,16 +681,28 @@ INSTANTIATE_TEST_CASE_P(
Spdy,
SpdyNetworkTransactionTest,
::testing::Values(
- SpdyNetworkTransactionTestParams(kProtoSPDY31, HTTPS_SPDY_VIA_NPN),
- SpdyNetworkTransactionTestParams(kProtoSPDY31, HTTP_SPDY_VIA_ALT_SVC),
- SpdyNetworkTransactionTestParams(kProtoHTTP2, HTTPS_SPDY_VIA_NPN),
- SpdyNetworkTransactionTestParams(kProtoHTTP2, HTTP_SPDY_VIA_ALT_SVC)));
+ SpdyNetworkTransactionTestParams(kProtoSPDY31,
+ HTTPS_SPDY_VIA_NPN,
+ false),
+ SpdyNetworkTransactionTestParams(kProtoSPDY31,
+ HTTP_SPDY_VIA_ALT_SVC,
+ false),
+ SpdyNetworkTransactionTestParams(kProtoHTTP2,
+ HTTPS_SPDY_VIA_NPN,
+ false),
+ SpdyNetworkTransactionTestParams(kProtoHTTP2, HTTPS_SPDY_VIA_NPN, true),
+ SpdyNetworkTransactionTestParams(kProtoHTTP2,
+ HTTP_SPDY_VIA_ALT_SVC,
+ false),
+ SpdyNetworkTransactionTestParams(kProtoHTTP2,
+ HTTP_SPDY_VIA_ALT_SVC,
+ true)));
// Verify HttpNetworkTransaction constructor.
TEST_P(SpdyNetworkTransactionTest, Constructor) {
scoped_ptr<SpdySessionDependencies> session_deps(
CreateSpdySessionDependencies(GetParam()));
- scoped_refptr<HttpNetworkSession> session(
+ scoped_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -750,7 +728,7 @@ TEST_P(SpdyNetworkTransactionTest, Get) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
@@ -760,6 +738,7 @@ TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) {
// Construct the request.
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, p, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
MockWrite writes[] = {CreateMockWrite(*req, 0)};
SpdyPriority spdy_prio = 0;
@@ -767,44 +746,24 @@ TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) {
// this repeats the RequestPriority-->SpdyPriority mapping from
// SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
// sure it's being done right.
- if (spdy_util_.spdy_version() < SPDY3) {
- switch (p) {
- case HIGHEST:
- EXPECT_EQ(0, spdy_prio);
- break;
- case MEDIUM:
- EXPECT_EQ(1, spdy_prio);
- break;
- case LOW:
- case LOWEST:
- EXPECT_EQ(2, spdy_prio);
- break;
- case IDLE:
- EXPECT_EQ(3, spdy_prio);
- break;
- default:
- FAIL();
- }
- } else {
- switch (p) {
- case HIGHEST:
- EXPECT_EQ(0, spdy_prio);
- break;
- case MEDIUM:
- EXPECT_EQ(1, spdy_prio);
- break;
- case LOW:
- EXPECT_EQ(2, spdy_prio);
- break;
- case LOWEST:
- EXPECT_EQ(3, spdy_prio);
- break;
- case IDLE:
- EXPECT_EQ(4, spdy_prio);
- break;
- default:
- FAIL();
- }
+ switch (p) {
+ case HIGHEST:
+ EXPECT_EQ(0, spdy_prio);
+ break;
+ case MEDIUM:
+ EXPECT_EQ(1, spdy_prio);
+ break;
+ case LOW:
+ EXPECT_EQ(2, spdy_prio);
+ break;
+ case LOWEST:
+ EXPECT_EQ(3, spdy_prio);
+ break;
+ case IDLE:
+ EXPECT_EQ(4, spdy_prio);
+ break;
+ default:
+ FAIL();
}
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -824,7 +783,7 @@ TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
}
@@ -878,7 +837,8 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
MockRead(ASYNC, 0, 12), // EOF
};
SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
- SequencedSocketData data_placeholder(NULL, 0, NULL, 0);
+ SequencedSocketData data_placeholder1(NULL, 0, NULL, 0);
+ SequencedSocketData data_placeholder2(NULL, 0, NULL, 0);
BoundNetLog log;
TransactionHelperResult out;
@@ -889,14 +849,14 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
// We require placeholder data because three get requests are sent out at
// the same time which results in three sockets being connected. The first
// on will negotiate SPDY and will be used for all requests.
- helper.AddData(&data_placeholder);
- helper.AddData(&data_placeholder);
+ helper.AddData(&data_placeholder1);
+ helper.AddData(&data_placeholder2);
scoped_ptr<HttpNetworkTransaction> trans1(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans3(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
TestCompletionCallback callback1;
TestCompletionCallback callback2;
@@ -931,7 +891,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
}
@@ -977,9 +937,9 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
// on will negotiate SPDY and will be used for all requests.
helper.AddData(&data_placeholder);
scoped_ptr<HttpNetworkTransaction> trans1(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
TestCompletionCallback callback1;
TestCompletionCallback callback2;
@@ -1004,7 +964,7 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
out.response_info = *response1;
out.rv = ReadTransaction(trans1.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
const HttpResponseInfo* response2 = trans2->GetResponseInfo();
@@ -1014,7 +974,7 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
out.response_info = *response2;
out.rv = ReadTransaction(trans2.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
helper.VerifyDataConsumed();
@@ -1065,9 +1025,9 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
helper.AddData(&data_placeholder);
scoped_ptr<HttpNetworkTransaction> trans1(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
TestCompletionCallback callback1;
TestCompletionCallback callback2;
@@ -1079,7 +1039,8 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config);
HttpStreamFactory* http_stream_factory =
helper.session()->http_stream_factory();
- helper.session()->GetNextProtos(&preconnect_ssl_config.next_protos);
+ helper.session()->GetAlpnProtos(&preconnect_ssl_config.alpn_protos);
+ helper.session()->GetNpnProtos(&preconnect_ssl_config.npn_protos);
http_stream_factory->PreconnectStreams(1, httpreq, preconnect_ssl_config,
preconnect_ssl_config);
@@ -1101,7 +1062,7 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
out.response_info = *response1;
out.rv = ReadTransaction(trans1.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
const HttpResponseInfo* response2 = trans2->GetResponseInfo();
@@ -1111,7 +1072,7 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
out.response_info = *response2;
out.rv = ReadTransaction(trans2.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
helper.VerifyDataConsumed();
@@ -1124,17 +1085,20 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
// second transaction completes, so we can assert on read_index().
TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
// Construct the request.
+ // Each request fully completes before the next starts.
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+ spdy_util_.UpdateWithStreamDestruction(3);
scoped_ptr<SpdyFrame> req3(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
@@ -1143,7 +1107,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true));
SettingsMap settings;
- const uint32 max_concurrent_streams = 1;
+ const uint32_t max_concurrent_streams = 1;
settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
scoped_ptr<SpdyFrame> settings_frame(
@@ -1182,11 +1146,11 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
helper.RunPreTestSetup();
helper.AddData(&data);
scoped_ptr<HttpNetworkTransaction> trans1(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans3(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
TestCompletionCallback callback1;
TestCompletionCallback callback2;
@@ -1221,7 +1185,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
out.response_info = *response1;
out.rv = ReadTransaction(trans1.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
const HttpResponseInfo* response2 = trans2->GetResponseInfo();
@@ -1229,7 +1193,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
out.response_info = *response2;
out.rv = ReadTransaction(trans2.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
const HttpResponseInfo* response3 = trans3->GetResponseInfo();
@@ -1237,7 +1201,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
out.response_info = *response3;
out.rv = ReadTransaction(trans3.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
helper.VerifyDataConsumed();
@@ -1257,17 +1221,20 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+ spdy_util_.UpdateWithStreamDestruction(3);
scoped_ptr<SpdyFrame> req4(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, HIGHEST, true));
scoped_ptr<SpdyFrame> resp4(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
scoped_ptr<SpdyFrame> fbody4(spdy_util_.ConstructSpdyBodyFrame(5, true));
+ spdy_util_.UpdateWithStreamDestruction(5);
scoped_ptr<SpdyFrame> req3(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 7, LOWEST, true));
@@ -1276,7 +1243,7 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(7, true));
SettingsMap settings;
- const uint32 max_concurrent_streams = 1;
+ const uint32_t max_concurrent_streams = 1;
settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
scoped_ptr<SpdyFrame> settings_frame(
@@ -1317,13 +1284,13 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
helper.AddData(&data);
scoped_ptr<HttpNetworkTransaction> trans1(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans3(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans4(
- new HttpNetworkTransaction(HIGHEST, helper.session().get()));
+ new HttpNetworkTransaction(HIGHEST, helper.session()));
TestCompletionCallback callback1;
TestCompletionCallback callback2;
@@ -1361,7 +1328,7 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
out.response_info = *response1;
out.rv = ReadTransaction(trans1.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
const HttpResponseInfo* response2 = trans2->GetResponseInfo();
@@ -1369,7 +1336,7 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
out.response_info = *response2;
out.rv = ReadTransaction(trans2.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
// notice: response3 gets two hellos, response4 gets one
@@ -1379,7 +1346,7 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
out.response_info = *response3;
out.rv = ReadTransaction(trans3.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
out.rv = callback4.WaitForResult();
@@ -1389,7 +1356,7 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
out.response_info = *response4;
out.rv = ReadTransaction(trans4.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
helper.VerifyDataConsumed();
EXPECT_EQ(OK, out.rv);
@@ -1406,6 +1373,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
@@ -1414,7 +1382,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
SettingsMap settings;
- const uint32 max_concurrent_streams = 1;
+ const uint32_t max_concurrent_streams = 1;
settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
scoped_ptr<SpdyFrame> settings_frame(
@@ -1446,11 +1414,11 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
helper.RunPreTestSetup();
helper.AddData(&data);
scoped_ptr<HttpNetworkTransaction> trans1(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans3(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
TestCompletionCallback callback1;
TestCompletionCallback callback2;
@@ -1469,7 +1437,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
ASSERT_EQ(out.rv, ERR_IO_PENDING);
out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
- delete trans3.release();
+ trans3.reset();
ASSERT_EQ(out.rv, ERR_IO_PENDING);
out.rv = callback2.WaitForResult();
ASSERT_EQ(OK, out.rv);
@@ -1482,7 +1450,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
out.response_info = *response1;
out.rv = ReadTransaction(trans1.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
const HttpResponseInfo* response2 = trans2->GetResponseInfo();
@@ -1491,7 +1459,7 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
out.response_info = *response2;
out.rv = ReadTransaction(trans2.get(), &out.response_data);
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!hello!", out.response_data);
helper.VerifyDataConsumed();
EXPECT_EQ(OK, out.rv);
@@ -1537,13 +1505,14 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
scoped_ptr<SpdyFrame> fin_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
SettingsMap settings;
- const uint32 max_concurrent_streams = 1;
+ const uint32_t max_concurrent_streams = 1;
settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
scoped_ptr<SpdyFrame> settings_frame(
@@ -1577,10 +1546,10 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
// there needs to be three sets of SSL connection data.
helper.AddData(&data_placeholder);
helper.AddData(&data_placeholder);
- HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session().get());
- HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session().get());
+ HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
+ HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
HttpNetworkTransaction* trans3(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
TestCompletionCallback callback1;
TestCompletionCallback callback2;
@@ -1652,7 +1621,7 @@ TEST_P(SpdyNetworkTransactionTest, Put) {
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
}
// Test that a simple HEAD request works.
@@ -1685,7 +1654,7 @@ TEST_P(SpdyNetworkTransactionTest, Head) {
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
}
// Test that a simple POST works.
@@ -1710,7 +1679,7 @@ TEST_P(SpdyNetworkTransactionTest, Post) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
@@ -1736,7 +1705,7 @@ TEST_P(SpdyNetworkTransactionTest, FilePost) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
@@ -1785,7 +1754,7 @@ TEST_P(SpdyNetworkTransactionTest, ComplexPost) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
@@ -1818,7 +1787,7 @@ TEST_P(SpdyNetworkTransactionTest, ChunkedPost) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ(kUploadData, out.response_data);
}
@@ -1870,7 +1839,7 @@ TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) {
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ(expected_response, out.response_data);
}
@@ -1910,7 +1879,7 @@ TEST_P(SpdyNetworkTransactionTest, NullPost) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
@@ -1918,8 +1887,8 @@ TEST_P(SpdyNetworkTransactionTest, NullPost) {
TEST_P(SpdyNetworkTransactionTest, EmptyPost) {
BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
// Create an empty UploadDataStream.
- ScopedVector<UploadElementReader> element_readers;
- ElementsUploadDataStream stream(element_readers.Pass(), 0);
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
+ ElementsUploadDataStream stream(std::move(element_readers), 0);
// Setup the request
HttpRequestInfo request;
@@ -1927,7 +1896,7 @@ TEST_P(SpdyNetworkTransactionTest, EmptyPost) {
request.url = GURL(GetDefaultUrl());
request.upload_data_stream = &stream;
- const uint64 kContentLength = 0;
+ const uint64_t kContentLength = 0;
scoped_ptr<SpdyHeaderBlock> req_block(
spdy_util_.ConstructPostHeaderBlock(GetDefaultUrl(), kContentLength));
@@ -1953,7 +1922,7 @@ TEST_P(SpdyNetworkTransactionTest, EmptyPost) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
@@ -1974,27 +1943,25 @@ TEST_P(SpdyNetworkTransactionTest, ResponseBeforePostCompletes) {
// Write the request headers, and read the complete response
// while still waiting for chunked request data.
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateChunkedPostRequest(),
DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
ASSERT_TRUE(helper.StartDefaultTest());
+ helper.WaitForHeaders();
+ EXPECT_EQ(OK, helper.output().rv);
+
// Process the request headers, SYN_REPLY, and response body.
// The request body is still in flight.
- data.RunFor(3);
-
const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
// Finish sending the request body.
upload_chunked_data_stream()->AppendData(kUploadData, kUploadDataSize, true);
- data.RunFor(2);
std::string response_body;
EXPECT_EQ(OK, ReadTransaction(helper.trans(), &response_body));
@@ -2022,25 +1989,20 @@ TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
MockRead(ASYNC, 0, 0, 4) // EOF
};
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
HttpNetworkTransaction* trans = helper.trans();
TestCompletionCallback callback;
int rv = trans->Start(
&CreateGetRequest(), callback.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.GetResult(rv));
- data.SetStop(2);
- data.Run();
helper.ResetTrans();
- data.SetStop(20);
- data.Run();
+ base::RunLoop().RunUntilIdle();
helper.VerifyDataConsumed();
}
@@ -2178,7 +2140,7 @@ TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
helper.session()->spdy_session_pool()->CloseAllSessions();
@@ -2241,28 +2203,23 @@ TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
MockRead(ASYNC, 0, 0, 3) // EOF
};
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(),
GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
HttpNetworkTransaction* trans = helper.trans();
TestCompletionCallback callback;
int rv = trans->Start(
&CreateGetRequest(), callback.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.GetResult(rv));
- data.SetStop(2);
- data.Run();
helper.ResetTrans();
- data.SetStop(20);
- data.Run();
+ base::RunLoop().RunUntilIdle();
helper.VerifyDataConsumed();
}
@@ -2279,10 +2236,9 @@ TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
// The indicated length of this frame is longer than its actual length. When
// the session receives an empty frame after this one, it shuts down the
// session, and calls the read callback with the incomplete data.
- const uint8 kGetBodyFrame2[] = {
- 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x00, 0x00, 0x07,
- 'h', 'e', 'l', 'l', 'o', '!',
+ const uint8_t kGetBodyFrame2[] = {
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+ 0x07, 'h', 'e', 'l', 'l', 'o', '!',
};
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -2323,9 +2279,12 @@ TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
helper.session(), GURL(GetDefaultUrl())));
ASSERT_EQ(ERR_IO_PENDING, rv);
// This forces an err_IO_pending, which sets the callback.
- data.CompleteRead();
+ data.Resume();
+ data.RunUntilPaused();
+
// This finishes the read.
- data.CompleteRead();
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
helper.VerifyDataConsumed();
}
@@ -2370,7 +2329,7 @@ TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
base::Bind(&SpdyNetworkTransactionTest::DeleteSessionCallback,
base::Unretained(&helper)));
ASSERT_EQ(ERR_IO_PENDING, rv);
- data.CompleteRead();
+ data.Resume();
// Finish running rest of tasks.
base::RunLoop().RunUntilIdle();
@@ -2576,7 +2535,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
@@ -2619,7 +2578,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
@@ -2662,7 +2621,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
@@ -2716,7 +2675,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) {
// Verify the SYN_REPLY.
HttpResponseInfo response = *trans->GetResponseInfo();
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
}
// Verify that we don't leak streams and that we properly send a reset
@@ -2762,7 +2721,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
@@ -2816,7 +2775,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
@@ -2869,7 +2828,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
@@ -2928,7 +2887,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
// Verify the SYN_REPLY.
HttpResponseInfo response = *trans->GetResponseInfo();
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
}
TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
@@ -2977,7 +2936,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
// Verify the SYN_REPLY.
HttpResponseInfo response = *trans->GetResponseInfo();
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
}
TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
@@ -2998,7 +2957,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
(*incomplete_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
(*incomplete_headers)["hello"] = "bye";
scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
- incomplete_headers.Pass(), 2, 1));
+ std::move(incomplete_headers), 2, 1));
MockRead reads[] = {
CreateMockRead(*stream1_reply, 1),
CreateMockRead(*stream2_syn, 2),
@@ -3030,7 +2989,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
// Verify the SYN_REPLY.
HttpResponseInfo response = *trans->GetResponseInfo();
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
}
// Verify that various SynReply headers parse correctly through the
@@ -3088,6 +3047,7 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) {
test_cases[i].num_headers,
1));
scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
MockRead reads[] = {
CreateMockRead(*resp, 1),
CreateMockRead(*body, 2),
@@ -3102,7 +3062,7 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) {
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
scoped_refptr<HttpResponseHeaders> headers = out.response_info.headers;
@@ -3185,6 +3145,7 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
spdy_util_.ConstructSpdyReply(1, reply_headers));
scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
MockRead reads[] = {
CreateMockRead(*frame_reply, 1),
CreateMockRead(*body, 2),
@@ -3209,7 +3170,7 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv) << i;
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i;
+ EXPECT_EQ("HTTP/1.1 200", out.status_line) << i;
EXPECT_EQ("hello!", out.response_data) << i;
// Test the response information.
@@ -3262,6 +3223,7 @@ TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) {
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
+ spdy_util_.UpdateWithStreamDestruction(1);
MockWrite writes[] = {
CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
};
@@ -3428,30 +3390,25 @@ TEST_P(SpdyNetworkTransactionTest, WriteError) {
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
MockWrite writes[] = {
// We'll write 10 bytes successfully
- MockWrite(ASYNC, req->data(), 10, 0),
+ MockWrite(ASYNC, req->data(), 10, 1),
// Followed by ERROR!
- MockWrite(ASYNC, ERR_FAILED, 1),
- // Session drains and attempts to write a GOAWAY: Another ERROR!
MockWrite(ASYNC, ERR_FAILED, 2),
+ // Session drains and attempts to write a GOAWAY: Another ERROR!
+ MockWrite(ASYNC, ERR_FAILED, 3),
};
- MockRead reads[] = {
- MockRead(ASYNC, 0, 3) // EOF
- };
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
EXPECT_TRUE(helper.StartDefaultTest());
- data.RunFor(2);
helper.FinishDefaultTest();
EXPECT_TRUE(data.AllWriteDataConsumed());
- EXPECT_TRUE(!data.AllReadDataConsumed());
+ EXPECT_TRUE(data.AllReadDataConsumed());
TransactionHelperResult out = helper.output();
EXPECT_EQ(ERR_FAILED, out.rv);
}
@@ -3481,7 +3438,7 @@ TEST_P(SpdyNetworkTransactionTest, PartialWrite) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
@@ -3511,11 +3468,10 @@ TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) {
session_deps->enable_compression = true;
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(), GetParam(),
- session_deps.Pass());
+ std::move(session_deps));
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(ERR_SPDY_COMPRESSION_ERROR, out.rv);
- data.Reset();
}
// Test that the NetLog contains good data for a simple GET request.
@@ -3544,7 +3500,7 @@ TEST_P(SpdyNetworkTransactionTest, NetLog) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
// Check that the NetLog was filled reasonably.
@@ -3576,7 +3532,7 @@ TEST_P(SpdyNetworkTransactionTest, NetLog) {
NetLog::PHASE_END);
// Check that we logged all the headers correctly
- const NetLog::EventType type = (GetParam().protocol <= kProtoSPDY31)
+ const NetLog::EventType type = (GetParam().protocol == kProtoSPDY31)
? NetLog::TYPE_HTTP2_SESSION_SYN_STREAM
: NetLog::TYPE_HTTP2_SESSION_SEND_HEADERS;
pos = ExpectLogContainsSomewhere(entries, 0, type, NetLog::PHASE_NONE);
@@ -3677,7 +3633,7 @@ TEST_P(SpdyNetworkTransactionTest, BufferFull) {
scoped_refptr<IOBuffer> buf(new IOBuffer(kSmallReadSize));
rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
if (rv == ERR_IO_PENDING) {
- data.CompleteRead();
+ data.Resume();
rv = read_callback.WaitForResult();
}
if (rv > 0) {
@@ -3697,7 +3653,7 @@ TEST_P(SpdyNetworkTransactionTest, BufferFull) {
helper.VerifyDataConsumed();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("goodbye world", out.response_data);
}
@@ -3769,7 +3725,7 @@ TEST_P(SpdyNetworkTransactionTest, Buffering) {
scoped_refptr<IOBuffer> buf(new IOBuffer(kSmallReadSize));
rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
if (rv == ERR_IO_PENDING) {
- data.CompleteRead();
+ data.Resume();
rv = read_callback.WaitForResult();
}
if (rv > 0) {
@@ -3793,7 +3749,7 @@ TEST_P(SpdyNetworkTransactionTest, Buffering) {
helper.VerifyDataConsumed();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("messagemessagemessagemessage", out.response_data);
}
@@ -3877,7 +3833,7 @@ TEST_P(SpdyNetworkTransactionTest, BufferedAll) {
helper.VerifyDataConsumed();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("messagemessagemessagemessage", out.response_data);
}
@@ -3946,7 +3902,7 @@ TEST_P(SpdyNetworkTransactionTest, BufferedClosed) {
scoped_refptr<IOBuffer> buf(new IOBuffer(kSmallReadSize));
rv = trans->Read(buf.get(), kSmallReadSize, read_callback.callback());
if (rv == ERR_IO_PENDING) {
- data.CompleteRead();
+ data.Resume();
rv = read_callback.WaitForResult();
}
if (rv > 0) {
@@ -4025,7 +3981,8 @@ TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) {
ASSERT_EQ(ERR_IO_PENDING, rv) << "Unexpected read: " << rv;
// Complete the read now, which causes buffering to start.
- data.CompleteRead();
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
// Destroy the transaction, causing the stream to get cancelled
// and orphaning the buffered IO task.
helper.ResetTrans();
@@ -4051,7 +4008,6 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
0, // Associated Stream ID
ConvertRequestPriorityToSpdyPriority(
LOWEST, spdy_util_.spdy_version()),
- kSpdyCredentialSlotUnused,
CONTROL_FLAG_NONE, // Control Flags
false, // Compressed
RST_STREAM_INVALID, // Status
@@ -4081,7 +4037,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
(*reply_headers)[spdy_util_.GetStatusKey()] = "200";
(*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
scoped_ptr<SpdyFrame> reply(
- spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass()));
+ spdy_util_.ConstructSpdyFrame(kSynReplyInfo, std::move(reply_headers)));
const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
unsigned int kSampleValue1 = 0x0a0a0a0a;
@@ -4119,7 +4075,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
helper.VerifyDataConsumed();
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
{
@@ -4158,7 +4114,6 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
0, // Associated Stream ID
ConvertRequestPriorityToSpdyPriority(
LOWEST, spdy_util_.spdy_version()),
- kSpdyCredentialSlotUnused,
CONTROL_FLAG_NONE, // Control Flags
false, // Compressed
RST_STREAM_INVALID, // Status
@@ -4233,7 +4188,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
(*reply_headers)[spdy_util_.GetStatusKey()] = "200";
(*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
scoped_ptr<SpdyFrame> reply(
- spdy_util_.ConstructSpdyFrame(kSynReplyInfo, reply_headers.Pass()));
+ spdy_util_.ConstructSpdyFrame(kSynReplyInfo, std::move(reply_headers)));
scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockRead reads[] = {
@@ -4248,7 +4203,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
helper.VerifyDataConsumed();
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
{
@@ -4370,7 +4325,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
// Do not force SPDY so that second socket can negotiate HTTP/1.1.
session_deps->next_protos = SpdyNextProtos();
NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(),
- GetParam(), session_deps.Pass());
+ GetParam(), std::move(session_deps));
// First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED.
const char* url = request.url.spec().c_str();
@@ -4392,7 +4347,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2);
// Force SPDY.
ssl_provider0->SetNextProto(GetParam().protocol);
- helper.AddDataWithSSLSocketDataProvider(&data0, ssl_provider0.Pass());
+ helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
// Second socket: falling back to HTTP/1.1.
MockWrite writes1[] = {MockWrite(ASYNC, 0,
@@ -4412,7 +4367,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11);
// Force HTTP/1.1.
ssl_provider1->SetNextProto(kProtoHTTP11);
- helper.AddDataWithSSLSocketDataProvider(&data1, ssl_provider1.Pass());
+ helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
base::WeakPtr<HttpServerProperties> http_server_properties =
helper.session()->spdy_session_pool()->http_server_properties();
@@ -4462,7 +4417,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
// Do not force SPDY so that second socket can negotiate HTTP/1.1.
session_deps->next_protos = SpdyNextProtos();
NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(),
- GetParam(), session_deps.Pass());
+ GetParam(), std::move(session_deps));
// First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
@@ -4482,13 +4437,13 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2);
// Force SPDY.
ssl_provider0->SetNextProto(GetParam().protocol);
- helper.AddDataWithSSLSocketDataProvider(&data0, ssl_provider0.Pass());
+ helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0));
// Second socket: retry using HTTP/1.1.
MockWrite writes1[] = {
MockWrite(ASYNC, 0,
"CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
+ "Host: www.example.org:443\r\n"
"Proxy-Connection: keep-alive\r\n\r\n"),
MockWrite(ASYNC, 2,
"GET / HTTP/1.1\r\n"
@@ -4512,7 +4467,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11);
// Force HTTP/1.1.
ssl_provider1->SetNextProto(kProtoHTTP11);
- helper.AddDataWithSSLSocketDataProvider(&data1, ssl_provider1.Pass());
+ helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1));
// A third socket is needed for the tunnelled connection.
scoped_ptr<SSLSocketDataProvider> ssl_provider2(
@@ -4552,14 +4507,14 @@ TEST_P(SpdyNetworkTransactionTest, ProxyConnect) {
BoundNetLog(), GetParam(), NULL);
helper.session_deps() = CreateSpdySessionDependencies(
GetParam(), ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
- helper.SetSession(make_scoped_refptr(
- SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
+ helper.SetSession(
+ SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()));
helper.RunPreTestSetup();
HttpNetworkTransaction* trans = helper.trans();
const char kConnect443[] = {
"CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
+ "Host: www.example.org:443\r\n"
"Proxy-Connection: keep-alive\r\n\r\n"};
const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
scoped_ptr<SpdyFrame> req(
@@ -4592,8 +4547,8 @@ TEST_P(SpdyNetworkTransactionTest, ProxyConnect) {
// Verify the SYN_REPLY.
HttpResponseInfo response = *trans->GetResponseInfo();
- EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ ASSERT_TRUE(response.headers.get() != NULL);
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
@@ -4617,8 +4572,8 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
helper.session_deps() = CreateSpdySessionDependencies(
GetParam(),
ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70"));
- helper.SetSession(make_scoped_refptr(
- SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
+ helper.SetSession(
+ SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()));
SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
helper.RunPreTestSetup();
@@ -4656,7 +4611,7 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
out.rv = ReadTransaction(trans, &out.response_data);
EXPECT_EQ(OK, out.rv);
out.status_line = response->headers->GetStatusLine();
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
// Check that the SpdySession is still in the SpdySessionPool.
@@ -4670,16 +4625,21 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
PRIVACY_MODE_DISABLED);
EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy));
+ // New SpdyTestUtil instance for the session that will be used for the
+ // proxy connection.
+ SpdyTestUtil spdy_util_2(GetParam().protocol,
+ GetParam().priority_to_dependency);
+
// Set up data for the proxy connection.
const char kConnect443[] = {
"CONNECT www.example.org:443 HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
+ "Host: www.example.org:443\r\n"
"Proxy-Connection: keep-alive\r\n\r\n"};
const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
- scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyGet(
+ scoped_ptr<SpdyFrame> req2(spdy_util_2.ConstructSpdyGet(
GetDefaultUrlWithPath("/foo.dat").c_str(), false, 1, LOWEST));
- scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ scoped_ptr<SpdyFrame> resp2(spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> body2(spdy_util_2.ConstructSpdyBodyFrame(1, true));
MockWrite writes2[] = {
MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
@@ -4703,16 +4663,16 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
scoped_ptr<SpdySessionDependencies> ssd_proxy(
CreateSpdySessionDependencies(GetParam()));
// Ensure that this transaction uses the same SpdySessionPool.
- scoped_refptr<HttpNetworkSession> session_proxy(
+ scoped_ptr<HttpNetworkSession> session_proxy(
SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get()));
NormalSpdyTransactionHelper helper_proxy(request_proxy, DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- HttpNetworkSessionPeer session_peer(session_proxy);
+ HttpNetworkSessionPeer session_peer(session_proxy.get());
scoped_ptr<ProxyService> proxy_service(
ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
session_peer.SetProxyService(proxy_service.get());
helper_proxy.session_deps().swap(ssd_proxy);
- helper_proxy.SetSession(session_proxy);
+ helper_proxy.SetSession(std::move(session_proxy));
helper_proxy.RunPreTestSetup();
helper_proxy.AddData(data_proxy.get());
@@ -4725,8 +4685,8 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
EXPECT_EQ(0, rv);
HttpResponseInfo response_proxy = *trans_proxy->GetResponseInfo();
- EXPECT_TRUE(response_proxy.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response_proxy.headers->GetStatusLine());
+ ASSERT_TRUE(response_proxy.headers.get() != NULL);
+ EXPECT_EQ("HTTP/1.1 200", response_proxy.headers->GetStatusLine());
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(trans_proxy, &response_data));
@@ -4757,6 +4717,9 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
+ // In all cases the connection will be reset before req3 can be
+ // dispatched, destroying both streams.
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req3(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
MockWrite writes1[] = {CreateMockWrite(*req, 0), CreateMockWrite(*req3, 5)};
@@ -4787,7 +4750,7 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
for (int i = 0; i < 2; ++i) {
scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
TestCompletionCallback callback;
int rv = trans->Start(
@@ -4802,7 +4765,7 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
}
// Now schedule the ERR_CONNECTION_RESET.
- data1.CompleteRead();
+ data1.Resume();
}
rv = callback.WaitForResult();
EXPECT_EQ(OK, rv);
@@ -4814,7 +4777,7 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
EXPECT_EQ(OK, rv);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_EQ("hello!", response_data);
base::RunLoop().RunUntilIdle();
}
@@ -4846,7 +4809,7 @@ TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
HttpStreamFactory::set_spdy_enabled(false);
@@ -4884,6 +4847,8 @@ TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) {
// GET with an Authorization header.
scoped_ptr<SpdyFrame> req_get(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
+ // Will be refused for lack of auth.
+ spdy_util_.UpdateWithStreamDestruction(1);
const char* const kExtraAuthorizationHeaders[] = {
"authorization", "Basic Zm9vOmJhcg=="
};
@@ -4946,7 +4911,7 @@ TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) {
AuthChallengeInfo* auth_challenge = response_start->auth_challenge.get();
ASSERT_TRUE(auth_challenge != NULL);
EXPECT_FALSE(auth_challenge->is_proxy);
- EXPECT_EQ("basic", auth_challenge->scheme);
+ EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
EXPECT_EQ("MyRealm", auth_challenge->realm);
// Restart with a username/password.
@@ -4979,21 +4944,16 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
initial_headers.get());
- scoped_ptr<SpdyFrame> stream2_syn(
- spdy_util_.ConstructInitialSpdyPushFrame(initial_headers.Pass(), 2, 1));
+ scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
+ std::move(initial_headers), 2, 1));
scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
(*late_headers)[spdy_util_.GetStatusKey()] = "200";
(*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
(*late_headers)["hello"] = "bye";
- scoped_ptr<SpdyFrame> stream2_headers(
- spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
- false,
- 2,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> stream2_headers(spdy_util_.ConstructSpdyControlFrame(
+ std::move(late_headers), false, 2, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
scoped_ptr<SpdyFrame>
stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -5021,11 +4981,11 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
}
TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
@@ -5041,21 +5001,16 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
initial_headers.get());
- scoped_ptr<SpdyFrame> stream2_syn(
- spdy_util_.ConstructInitialSpdyPushFrame(initial_headers.Pass(), 2, 1));
+ scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
+ std::move(initial_headers), 2, 1));
scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
(*late_headers)[spdy_util_.GetStatusKey()] = "200";
(*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
(*late_headers)["hello"] = "bye";
- scoped_ptr<SpdyFrame> stream2_headers(
- spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
- false,
- 2,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> stream2_headers(spdy_util_.ConstructSpdyControlFrame(
+ std::move(late_headers), false, 2, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
scoped_ptr<SpdyFrame>
stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -5064,50 +5019,44 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
spdy_util_.ConstructSpdyBodyFrame(
2, kPushedData, strlen(kPushedData), true));
MockRead reads[] = {
- CreateMockRead(*stream1_reply, 1),
- CreateMockRead(*stream2_syn, 2),
- CreateMockRead(*stream1_body, 3),
- CreateMockRead(*stream2_headers, 4),
- CreateMockRead(*stream2_body, 5),
- MockRead(ASYNC, 0, 6), // EOF
+ CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream2_syn, 2),
+ CreateMockRead(*stream1_body, 3), MockRead(ASYNC, ERR_IO_PENDING, 4),
+ CreateMockRead(*stream2_headers, 5), CreateMockRead(*stream2_body, 6),
+ MockRead(ASYNC, ERR_IO_PENDING, 7), MockRead(ASYNC, 0, 8), // EOF
};
HttpResponseInfo response;
HttpResponseInfo response2;
std::string expected_push_result("pushed");
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
helper.RunPreTestSetup();
HttpNetworkTransaction* trans = helper.trans();
- // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
- // and the body of the primary stream, but before we've received the HEADERS
- // for the pushed stream.
- data.SetStop(3);
-
// Start the transaction.
TestCompletionCallback callback;
int rv = trans->Start(
&CreateGetRequest(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.Run();
- rv = callback.WaitForResult();
- EXPECT_EQ(0, rv);
+ // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+ // and the body of the primary stream, but before we've received the HEADERS
+ // for the pushed stream.
+ data.RunUntilPaused();
+ EXPECT_EQ(OK, callback.WaitForResult());
// Request the pushed path. At this point, we've received the push, but the
// headers are not yet complete.
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
rv = trans2->Start(
&CreateGetPushRequest(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.RunFor(3);
+ data.Resume();
+ data.RunUntilPaused();
base::RunLoop().RunUntilIdle();
// Read the server push body.
@@ -5133,14 +5082,15 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
// Read the final EOF (which will close the session)
- data.RunFor(1);
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
// Verify that we consumed all test data.
EXPECT_TRUE(data.AllReadDataConsumed());
@@ -5165,19 +5115,14 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
}
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
initial_headers.get());
- scoped_ptr<SpdyFrame> stream2_syn(
- spdy_util_.ConstructInitialSpdyPushFrame(initial_headers.Pass(), 2, 1));
+ scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
+ std::move(initial_headers), 2, 1));
scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
(*middle_headers)["hello"] = "bye";
- scoped_ptr<SpdyFrame> stream2_headers1(
- spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
- false,
- 2,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> stream2_headers1(spdy_util_.ConstructSpdyControlFrame(
+ std::move(middle_headers), false, 2, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
(*late_headers)[spdy_util_.GetStatusKey()] = "200";
@@ -5185,14 +5130,9 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
// HTTP/2 eliminates use of the :version header.
(*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
}
- scoped_ptr<SpdyFrame> stream2_headers2(
- spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
- false,
- 2,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> stream2_headers2(spdy_util_.ConstructSpdyControlFrame(
+ std::move(late_headers), false, 2, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
scoped_ptr<SpdyFrame>
stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -5201,51 +5141,51 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
spdy_util_.ConstructSpdyBodyFrame(
2, kPushedData, strlen(kPushedData), true));
MockRead reads[] = {
- CreateMockRead(*stream1_reply, 1),
- CreateMockRead(*stream2_syn, 2),
- CreateMockRead(*stream1_body, 3),
- CreateMockRead(*stream2_headers1, 4),
- CreateMockRead(*stream2_headers2, 5),
- CreateMockRead(*stream2_body, 6),
- MockRead(ASYNC, 0, 7), // EOF
+ CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream2_syn, 2),
+ CreateMockRead(*stream1_body, 3), MockRead(ASYNC, ERR_IO_PENDING, 4),
+ CreateMockRead(*stream2_headers1, 5),
+ // This is needed to work around https://crbug.com/571102.
+ MockRead(ASYNC, ERR_IO_PENDING, 6), CreateMockRead(*stream2_headers2, 7),
+ CreateMockRead(*stream2_body, 8), MockRead(ASYNC, ERR_IO_PENDING, 9),
+ MockRead(ASYNC, 0, 10), // EOF
};
HttpResponseInfo response;
HttpResponseInfo response2;
std::string expected_push_result("pushed");
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
helper.RunPreTestSetup();
HttpNetworkTransaction* trans = helper.trans();
- // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
- // the first HEADERS frame, and the body of the primary stream, but before
- // we've received the final HEADERS for the pushed stream.
- data.SetStop(4);
-
// Start the transaction.
TestCompletionCallback callback;
int rv = trans->Start(
&CreateGetRequest(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.Run();
- rv = callback.WaitForResult();
- EXPECT_EQ(0, rv);
+ // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+ // the first HEADERS frame, and the body of the primary stream, but before
+ // we've received the final HEADERS for the pushed stream.
+ data.RunUntilPaused();
+ EXPECT_EQ(0, callback.WaitForResult());
// Request the pushed path. At this point, we've received the push, but the
// headers are not yet complete.
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
rv = trans2->Start(
&CreateGetPushRequest(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.RunFor(3);
+ data.Resume();
+ data.RunUntilPaused();
+ base::RunLoop().RunUntilIdle();
+ // This is needed to work around https://crbug.com/571102.
+ data.Resume();
+ data.RunUntilPaused();
base::RunLoop().RunUntilIdle();
// Read the server push body.
@@ -5267,11 +5207,11 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Verify the pushed stream.
EXPECT_TRUE(response2.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
// Verify we got all the headers from all header blocks.
if (spdy_util_.spdy_version() < HTTP2)
@@ -5280,7 +5220,8 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
// Read the final EOF (which will close the session)
- data.RunFor(1);
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
// Verify that we consumed all test data.
EXPECT_TRUE(data.AllReadDataConsumed());
@@ -5300,19 +5241,14 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
initial_headers.get());
- scoped_ptr<SpdyFrame> stream2_syn(
- spdy_util_.ConstructInitialSpdyPushFrame(initial_headers.Pass(), 2, 1));
+ scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
+ std::move(initial_headers), 2, 1));
scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
(*middle_headers)["hello"] = "bye";
- scoped_ptr<SpdyFrame> stream2_headers1(
- spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
- false,
- 2,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> stream2_headers1(spdy_util_.ConstructSpdyControlFrame(
+ std::move(middle_headers), false, 2, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
scoped_ptr<SpdyFrame>
stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -5321,47 +5257,41 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
spdy_util_.ConstructSpdyBodyFrame(
2, kPushedData, strlen(kPushedData), true));
MockRead reads[] = {
- CreateMockRead(*stream1_reply, 1),
- CreateMockRead(*stream2_syn, 2),
- CreateMockRead(*stream1_body, 3),
- CreateMockRead(*stream2_headers1, 4),
- CreateMockRead(*stream2_body, 5),
- MockRead(ASYNC, 0, 6), // EOF
+ CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream2_syn, 2),
+ CreateMockRead(*stream1_body, 3), MockRead(ASYNC, ERR_IO_PENDING, 4),
+ CreateMockRead(*stream2_headers1, 5), CreateMockRead(*stream2_body, 6),
+ MockRead(ASYNC, ERR_IO_PENDING, 7), MockRead(ASYNC, 0, 8), // EOF
};
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
helper.RunPreTestSetup();
HttpNetworkTransaction* trans = helper.trans();
- // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
- // the first HEADERS frame, and the body of the primary stream, but before
- // we've received the final HEADERS for the pushed stream.
- data.SetStop(4);
-
// Start the transaction.
TestCompletionCallback callback;
int rv = trans->Start(
&CreateGetRequest(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.Run();
- rv = callback.WaitForResult();
- EXPECT_EQ(0, rv);
+ // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
+ // the first HEADERS frame, and the body of the primary stream, but before
+ // we've received the final HEADERS for the pushed stream.
+ data.RunUntilPaused();
+ EXPECT_EQ(0, callback.WaitForResult());
// Request the pushed path. At this point, we've received the push, but the
// headers are not yet complete.
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
rv = trans2->Start(
&CreateGetPushRequest(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.RunFor(2);
+ data.Resume();
+ data.RunUntilPaused();
base::RunLoop().RunUntilIdle();
// Read the server push body.
@@ -5383,10 +5313,11 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
// Read the final EOF (which will close the session).
- data.RunFor(1);
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
// Verify that we consumed all test data.
EXPECT_TRUE(data.AllReadDataConsumed());
@@ -5407,14 +5338,9 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) {
scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
(*late_headers)["hello"] = "bye";
- scoped_ptr<SpdyFrame> stream1_headers(
- spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
- false,
- 1,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> stream1_headers(spdy_util_.ConstructSpdyControlFrame(
+ std::move(late_headers), false, 1, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
scoped_ptr<SpdyFrame> stream1_body(
spdy_util_.ConstructSpdyBodyFrame(1, true));
MockRead reads[] = {
@@ -5449,14 +5375,9 @@ TEST_P(SpdyNetworkTransactionTest, SyncReplyDataAfterTrailers) {
scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
(*late_headers)["hello"] = "bye";
- scoped_ptr<SpdyFrame> stream1_headers(
- spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
- false,
- 1,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> stream1_headers(spdy_util_.ConstructSpdyControlFrame(
+ std::move(late_headers), false, 1, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
scoped_ptr<SpdyFrame> stream1_body(
spdy_util_.ConstructSpdyBodyFrame(1, false));
scoped_ptr<SpdyFrame> stream1_body2(
@@ -5512,6 +5433,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
spdy_util_.ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
scoped_ptr<SpdyFrame> stream1_body(
spdy_util_.ConstructSpdyBodyFrame(1, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> push_rst(
spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
MockWrite writes[] = {
@@ -5556,7 +5478,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
CreateSpdySessionDependencies(GetParam()));
session_deps->trusted_spdy_proxy = "123.45.67.89:8080";
NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(),
- GetParam(), session_deps.Pass());
+ GetParam(), std::move(session_deps));
helper.RunPreTestSetup();
helper.AddData(&data);
@@ -5585,7 +5507,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
// Verify the SYN_REPLY.
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
}
}
@@ -5593,6 +5515,8 @@ TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) {
// Construct the request.
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
+ // Will be destroyed by the RST before stream 3 starts.
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
MockWrite writes[] = {
@@ -5634,7 +5558,7 @@ TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) {
// Verify the SYN_REPLY.
HttpResponseInfo response = *trans->GetResponseInfo();
EXPECT_TRUE(response.headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine());
}
TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
@@ -5643,16 +5567,27 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
// (HIGHEST priority) request in such a way that the third will actually
// start before the second, causing the second to be numbered differently
// than the order they were created.
+ //
+ // Note that the requests and responses created below are expectations
+ // of what the above will produce on the wire, and hence are in the
+ // initial->HIGHEST->LOWEST priority.
+ //
+ // Frames are created by SpdySession just before the write associated
+ // with the frame is attempted, so stream dependencies will be based
+ // on the streams alive at the point of the request write attempt. Thus
+ // req1 is alive when req2 is attempted (during but not after the
+ // |data.RunFor(2);| statement below) but not when req3 is attempted.
+ // The call to spdy_util_.UpdateWithStreamDestruction() reflects this.
scoped_ptr<SpdyFrame> req1(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, HIGHEST, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req3(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, MEDIUM, true));
MockWrite writes[] = {
- CreateMockWrite(*req1, 0),
- CreateMockWrite(*req2, 3),
- CreateMockWrite(*req3, 4),
+ MockWrite(ASYNC, ERR_IO_PENDING, 0), CreateMockWrite(*req1, 1),
+ CreateMockWrite(*req2, 5), CreateMockWrite(*req3, 6),
};
scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
@@ -5662,22 +5597,17 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
MockRead reads[] = {
- CreateMockRead(*resp1, 1),
- CreateMockRead(*body1, 2),
- CreateMockRead(*resp2, 5),
- CreateMockRead(*body2, 6),
- CreateMockRead(*resp3, 7),
- CreateMockRead(*body3, 8),
- MockRead(ASYNC, 0, 9) // EOF
+ CreateMockRead(*resp1, 2), MockRead(ASYNC, ERR_IO_PENDING, 3),
+ CreateMockRead(*body1, 4), CreateMockRead(*resp2, 7),
+ CreateMockRead(*body2, 8), CreateMockRead(*resp3, 9),
+ CreateMockRead(*body3, 10), MockRead(ASYNC, 0, 11) // EOF
};
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(CreateGetRequest(), LOWEST,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
// Start the first transaction to set up the SpdySession
HttpNetworkTransaction* trans = helper.trans();
@@ -5695,7 +5625,7 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
HttpRequestInfo info2 = CreateGetRequest();
TestCompletionCallback callback2;
scoped_ptr<HttpNetworkTransaction> trans2(
- new HttpNetworkTransaction(MEDIUM, helper.session().get()));
+ new HttpNetworkTransaction(MEDIUM, helper.session()));
rv = trans2->Start(&info2, callback2.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
base::RunLoop().RunUntilIdle();
@@ -5703,7 +5633,7 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
HttpRequestInfo info3 = CreateGetRequest();
TestCompletionCallback callback3;
scoped_ptr<HttpNetworkTransaction> trans3(
- new HttpNetworkTransaction(HIGHEST, helper.session().get()));
+ new HttpNetworkTransaction(HIGHEST, helper.session()));
rv = trans3->Start(&info3, callback3.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
base::RunLoop().RunUntilIdle();
@@ -5711,12 +5641,13 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
// We now have two SYN_STREAM frames queued up which will be
// dequeued only once the first write completes, which we
// now allow to happen.
- data.RunFor(2);
+ ASSERT_TRUE(data.IsPaused());
+ data.Resume();
EXPECT_EQ(OK, callback.WaitForResult());
// And now we can allow everything else to run to completion.
- data.SetStop(10);
- data.Run();
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(OK, callback2.WaitForResult());
EXPECT_EQ(OK, callback3.WaitForResult());
@@ -5766,7 +5697,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
CreateMockWrite(*body_end, 2),
};
- static const int32 kDeltaWindowSize = 0xff;
+ static const int32_t kDeltaWindowSize = 0xff;
static const int kDeltaCount = 4;
scoped_ptr<SpdyFrame> window_update(
spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
@@ -5774,27 +5705,25 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
MockRead reads[] = {
- CreateMockRead(*window_update_dummy, 3),
- CreateMockRead(*window_update_dummy, 4),
- CreateMockRead(*window_update_dummy, 5),
- CreateMockRead(*window_update, 6), // Four updates, therefore window
- CreateMockRead(*window_update, 7), // size should increase by
- CreateMockRead(*window_update, 8), // kDeltaWindowSize * 4
- CreateMockRead(*window_update, 9),
- CreateMockRead(*resp, 10),
- CreateMockRead(*body_end, 11),
- MockRead(ASYNC, 0, 0, 12) // EOF
- };
-
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
-
- ScopedVector<UploadElementReader> element_readers;
+ CreateMockRead(*window_update_dummy, 3),
+ CreateMockRead(*window_update_dummy, 4),
+ CreateMockRead(*window_update_dummy, 5),
+ CreateMockRead(*window_update, 6), // Four updates, therefore window
+ CreateMockRead(*window_update, 7), // size should increase by
+ CreateMockRead(*window_update, 8), // kDeltaWindowSize * 4
+ CreateMockRead(*window_update, 9), CreateMockRead(*resp, 10),
+ MockRead(ASYNC, ERR_IO_PENDING, 11), CreateMockRead(*body_end, 12),
+ MockRead(ASYNC, 0, 13) // EOF
+ };
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
for (int i = 0; i < kFrameCount; ++i) {
- element_readers.push_back(
- new UploadBytesElementReader(content->c_str(), content->size()));
+ element_readers.push_back(make_scoped_ptr(
+ new UploadBytesElementReader(content->c_str(), content->size())));
}
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
// Setup the request
HttpRequestInfo request;
@@ -5804,8 +5733,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
helper.RunPreTestSetup();
HttpNetworkTransaction* trans = helper.trans();
@@ -5815,7 +5743,8 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.RunFor(11);
+ data.RunUntilPaused();
+ base::RunLoop().RunUntilIdle();
SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
ASSERT_TRUE(stream != NULL);
@@ -5826,7 +5755,8 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
kMaxSpdyFrameChunkSize * kFrameCount,
stream->stream()->send_window_size());
- data.RunFor(1);
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
rv = callback.WaitForResult();
EXPECT_EQ(OK, rv);
@@ -5837,33 +5767,33 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
// Test that received data frames and sent WINDOW_UPDATE frames change
// the recv_window_size_ correctly.
TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
- const int32 default_initial_window_size =
+ const int32_t default_initial_window_size =
SpdySession::GetDefaultInitialWindowSize(GetParam().protocol);
// Session level maximum window size that is more than twice the default
// initial window size so that an initial window update is sent.
- const int32 session_max_recv_window_size = 5 * 64 * 1024;
+ const int32_t session_max_recv_window_size = 5 * 64 * 1024;
ASSERT_LT(2 * default_initial_window_size, session_max_recv_window_size);
// Stream level maximum window size that is less than the session level
// maximum window size so that we test for confusion between the two.
- const int32 stream_max_recv_window_size = 4 * 64 * 1024;
+ const int32_t stream_max_recv_window_size = 4 * 64 * 1024;
ASSERT_GT(session_max_recv_window_size, stream_max_recv_window_size);
// Size of body to be sent. Has to be less than or equal to both window sizes
// so that we do not run out of receiving window. Also has to be greater than
// half of them so that it triggers both a session level and a stream level
// window update frame.
- const int32 kTargetSize = 3 * 64 * 1024;
+ const int32_t kTargetSize = 3 * 64 * 1024;
ASSERT_GE(session_max_recv_window_size, kTargetSize);
ASSERT_GE(stream_max_recv_window_size, kTargetSize);
ASSERT_LT(session_max_recv_window_size / 2, kTargetSize);
ASSERT_LT(stream_max_recv_window_size / 2, kTargetSize);
// Size of each DATA frame.
- const int32 kChunkSize = 4096;
+ const int32_t kChunkSize = 4096;
// Size of window updates.
ASSERT_EQ(0, session_max_recv_window_size / 2 % kChunkSize);
- const int32 session_window_update_delta =
+ const int32_t session_window_update_delta =
session_max_recv_window_size / 2 + kChunkSize;
ASSERT_EQ(0, stream_max_recv_window_size / 2 % kChunkSize);
- const int32 stream_window_update_delta =
+ const int32_t stream_window_update_delta =
stream_max_recv_window_size / 2 + kChunkSize;
SettingsMap initial_settings;
@@ -5898,26 +5828,27 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
reads.push_back(CreateMockRead(*resp, writes.size() + reads.size()));
- ScopedVector<SpdyFrame> body_frames;
+ std::vector<scoped_ptr<SpdyFrame>> body_frames;
const std::string body_data(kChunkSize, 'x');
for (size_t remaining = kTargetSize; remaining != 0;) {
size_t frame_size = std::min(remaining, body_data.size());
- body_frames.push_back(spdy_util_.ConstructSpdyBodyFrame(
- 1, body_data.data(), frame_size, false));
+ body_frames.push_back(make_scoped_ptr(spdy_util_.ConstructSpdyBodyFrame(
+ 1, body_data.data(), frame_size, false)));
reads.push_back(
CreateMockRead(*body_frames.back(), writes.size() + reads.size()));
remaining -= frame_size;
}
+ // Yield.
reads.push_back(
- MockRead(ASYNC, ERR_IO_PENDING, writes.size() + reads.size())); // Yield.
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, writes.size() + reads.size()));
writes.push_back(
CreateMockWrite(*session_window_update, writes.size() + reads.size()));
writes.push_back(
CreateMockWrite(*stream_window_update, writes.size() + reads.size()));
- SequencedSocketData data(vector_as_array(&reads), reads.size(),
- vector_as_array(&writes), writes.size());
+ SequencedSocketData data(reads.data(), reads.size(), writes.data(),
+ writes.size());
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
@@ -5950,7 +5881,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
// Issue a read which will cause a WINDOW_UPDATE to be sent and window
@@ -5992,7 +5923,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
CreateMockWrite(*rst, 3),
};
- static const int32 kDeltaWindowSize = 0x7fffffff; // cause an overflow
+ static const int32_t kDeltaWindowSize = 0x7fffffff; // cause an overflow
scoped_ptr<SpdyFrame> window_update(
spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
MockRead reads[] = {
@@ -6000,15 +5931,14 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
MockRead(ASYNC, 0, 4) // EOF
};
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
for (int i = 0; i < kFrameCount; ++i) {
- element_readers.push_back(
- new UploadBytesElementReader(content->c_str(), content->size()));
+ element_readers.push_back(make_scoped_ptr(
+ new UploadBytesElementReader(content->c_str(), content->size())));
}
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
// Setup the request
HttpRequestInfo request;
@@ -6018,16 +5948,15 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
HttpNetworkTransaction* trans = helper.trans();
TestCompletionCallback callback;
int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
ASSERT_EQ(ERR_IO_PENDING, rv);
- data.RunFor(5);
+ base::RunLoop().RunUntilIdle();
ASSERT_TRUE(callback.have_result());
EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, callback.WaitForResult());
helper.VerifyDataConsumed();
@@ -6049,7 +5978,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
// After that, next read is artifically enforced, which causes a
// WINDOW_UPDATE to be read and I/O process resumes.
TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
- const int32 initial_window_size =
+ const int32_t initial_window_size =
SpdySession::GetDefaultInitialWindowSize(GetParam().protocol);
// Number of frames we need to send to zero out the window size: data
// frames plus SYN_STREAM plus the last data frame; also we need another
@@ -6111,12 +6040,12 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
SequencedSocketData data(reads, arraysize(reads), writes.get(), num_writes);
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
std::string upload_data_string(initial_window_size, 'a');
upload_data_string.append(kUploadData, kUploadDataSize);
- element_readers.push_back(new UploadBytesElementReader(
- upload_data_string.c_str(), upload_data_string.size()));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+ upload_data_string.c_str(), upload_data_string.size())));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -6147,7 +6076,7 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
// since we're send-stalled.
EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
- data.CompleteRead(); // Read in WINDOW_UPDATE frame.
+ data.Resume(); // Read in WINDOW_UPDATE frame.
rv = callback.WaitForResult();
helper.VerifyDataConsumed();
}
@@ -6155,7 +6084,7 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
// Test we correctly handle the case where the SETTINGS frame results in
// unstalling the send window.
TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
- const int32 initial_window_size =
+ const int32_t initial_window_size =
SpdySession::GetDefaultInitialWindowSize(GetParam().protocol);
// Number of frames we need to send to zero out the window size: data
@@ -6195,6 +6124,8 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
writes.push_back(CreateMockWrite(*body1, i++));
writes.push_back(CreateMockWrite(*body2, i++));
+ reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++));
+
// Construct read frame for SETTINGS that gives enough space to upload the
// rest of the data.
SettingsMap settings;
@@ -6207,8 +6138,7 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
scoped_ptr<SpdyFrame> session_window_update(
spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
- if (GetParam().protocol >= kProtoSPDY31)
- reads.push_back(CreateMockRead(*session_window_update, i++));
+ reads.push_back(CreateMockRead(*session_window_update, i++));
scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
writes.push_back(CreateMockWrite(*settings_ack, i++));
@@ -6223,15 +6153,15 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
// Force all writes to happen before any read, last write will not
// actually queue a frame, due to window size being 0.
- DeterministicSocketData data(vector_as_array(&reads), reads.size(),
- vector_as_array(&writes), writes.size());
+ SequencedSocketData data(reads.data(), reads.size(), writes.data(),
+ writes.size());
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
std::string upload_data_string(initial_window_size, 'a');
upload_data_string.append(kUploadData, kUploadDataSize);
- element_readers.push_back(new UploadBytesElementReader(
- upload_data_string.c_str(), upload_data_string.size()));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+ upload_data_string.c_str(), upload_data_string.size())));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -6239,9 +6169,8 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
request.upload_data_stream = &upload_data_stream;
NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
HttpNetworkTransaction* trans = helper.trans();
@@ -6249,7 +6178,8 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.RunFor(num_writes - 1); // Write as much as we can.
+ data.RunUntilPaused(); // Write as much as we can.
+ base::RunLoop().RunUntilIdle();
SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
ASSERT_TRUE(stream != NULL);
@@ -6264,7 +6194,10 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
// since we're send-stalled.
EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
- data.RunFor(7); // Read in SETTINGS frame to unstall.
+ // Read in SETTINGS frame to unstall.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+
rv = callback.WaitForResult();
helper.VerifyDataConsumed();
// If stream is NULL, that means it was unstalled and closed.
@@ -6274,7 +6207,7 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
// Test we correctly handle the case where the SETTINGS frame results in a
// negative send window size.
TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
- const int32 initial_window_size =
+ const int32_t initial_window_size =
SpdySession::GetDefaultInitialWindowSize(GetParam().protocol);
// Number of frames we need to send to zero out the window size: data
// frames plus SYN_STREAM plus the last data frame; also we need another
@@ -6313,6 +6246,8 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
writes.push_back(CreateMockWrite(*body1, i++));
writes.push_back(CreateMockWrite(*body2, i++));
+ reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++));
+
// Construct read frame for SETTINGS that makes the send_window_size
// negative.
SettingsMap new_settings;
@@ -6344,15 +6279,15 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
// Force all writes to happen before any read, last write will not
// actually queue a frame, due to window size being 0.
- DeterministicSocketData data(vector_as_array(&reads), reads.size(),
- vector_as_array(&writes), writes.size());
+ SequencedSocketData data(reads.data(), reads.size(), writes.data(),
+ writes.size());
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
std::string upload_data_string(initial_window_size, 'a');
upload_data_string.append(kUploadData, kUploadDataSize);
- element_readers.push_back(new UploadBytesElementReader(
- upload_data_string.c_str(), upload_data_string.size()));
- ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+ upload_data_string.c_str(), upload_data_string.size())));
+ ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -6360,9 +6295,8 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
request.upload_data_stream = &upload_data_stream;
NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
BoundNetLog(), GetParam(), NULL);
- helper.SetDeterministic();
helper.RunPreTestSetup();
- helper.AddDeterministicData(&data);
+ helper.AddData(&data);
HttpNetworkTransaction* trans = helper.trans();
@@ -6370,7 +6304,8 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
- data.RunFor(num_writes - 1); // Write as much as we can.
+ data.RunUntilPaused(); // Write as much as we can.
+ base::RunLoop().RunUntilIdle();
SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
ASSERT_TRUE(stream != NULL);
@@ -6386,20 +6321,18 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
// Read in WINDOW_UPDATE or SETTINGS frame.
- data.RunFor((GetParam().protocol >= kProtoSPDY31) ? 9 : 8);
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
rv = callback.WaitForResult();
helper.VerifyDataConsumed();
}
TEST_P(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) {
- if (spdy_util_.spdy_version() < SPDY3)
- return;
-
scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat",
push_headers.get());
scoped_ptr<SpdyFrame> push(
- spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 3, 1));
+ spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 3, 1));
MockRead reads[] = {CreateMockRead(*push, 1)};
scoped_ptr<SpdyFrame> req(
@@ -6420,16 +6353,13 @@ TEST_P(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) {
TEST_P(SpdyNetworkTransactionTest,
GoAwayOnPushStreamIdLesserOrEqualThanLastAccepted) {
- if (spdy_util_.spdy_version() < SPDY3)
- return;
-
scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
NULL, 0, 4, 1, GetDefaultUrlWithPath("/a.dat").c_str()));
scoped_ptr<SpdyHeaderBlock> push_b_headers(new SpdyHeaderBlock);
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/b.dat"),
push_b_headers.get());
- scoped_ptr<SpdyFrame> push_b(
- spdy_util_.ConstructInitialSpdyPushFrame(push_b_headers.Pass(), 2, 1));
+ scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructInitialSpdyPushFrame(
+ std::move(push_b_headers), 2, 1));
MockRead reads[] = {
CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2),
};
@@ -6488,8 +6418,49 @@ TEST_P(SpdyNetworkTransactionTest, LargeRequest) {
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
+ EXPECT_EQ("hello!", out.response_data);
+}
+
+// Regression test for https://crbug.com/535629: response header exceeds 16 kB.
+TEST_P(SpdyNetworkTransactionTest, LargeResponseHeader) {
+ scoped_ptr<SpdyHeaderBlock> headers(
+ spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl()));
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0),
+ };
+
+ // HPACK decoder implementation limits string literal length to 16 kB.
+ const char* response_headers[2];
+ const std::string kKey(16 * 1024, 'a');
+ response_headers[0] = kKey.data();
+ const std::string kValue(16 * 1024, 'b');
+ response_headers[1] = kValue.data();
+
+ scoped_ptr<SpdyFrame> resp(
+ spdy_util_.ConstructSpdyGetSynReply(response_headers, 1, 1));
+ scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ MockRead reads[] = {
+ CreateMockRead(*resp, 1), CreateMockRead(*body, 2),
+ MockRead(ASYNC, 0, 3) // EOF
+ };
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL(GetDefaultUrl());
+ NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(),
+ GetParam(), nullptr);
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+ helper.RunToCompletion(&data);
+ TransactionHelperResult out = helper.output();
+
+ EXPECT_EQ(OK, out.rv);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
+ ASSERT_TRUE(out.response_info.headers->HasHeaderValue(kKey, kValue));
}
class SpdyNetworkTransactionNoTLSUsageCheckTest
@@ -6516,10 +6487,10 @@ class SpdyNetworkTransactionNoTLSUsageCheckTest
request.url = GURL("https://www.example.org/");
NormalSpdyTransactionHelper helper(
request, DEFAULT_PRIORITY, BoundNetLog(), GetParam(), NULL);
- helper.RunToCompletionWithSSLData(&data, ssl_provider.Pass());
+ helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
TransactionHelperResult out = helper.output();
EXPECT_EQ(OK, out.rv);
- EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
EXPECT_EQ("hello!", out.response_data);
}
};
@@ -6534,7 +6505,8 @@ INSTANTIATE_TEST_CASE_P(
Spdy,
SpdyNetworkTransactionNoTLSUsageCheckTest,
::testing::Values(SpdyNetworkTransactionTestParams(kProtoSPDY31,
- HTTPS_SPDY_VIA_NPN)));
+ HTTPS_SPDY_VIA_NPN,
+ false)));
TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSVersionTooOld) {
scoped_ptr<SSLSocketDataProvider> ssl_provider(
@@ -6542,7 +6514,7 @@ TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSVersionTooOld) {
SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3,
&ssl_provider->connection_status);
- RunNoTLSUsageCheckTest(ssl_provider.Pass());
+ RunNoTLSUsageCheckTest(std::move(ssl_provider));
}
TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSCipherSuiteSucky) {
@@ -6551,7 +6523,7 @@ TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSCipherSuiteSucky) {
// Set to TLS_RSA_WITH_NULL_MD5
SSLConnectionStatusSetCipherSuite(0x1, &ssl_provider->connection_status);
- RunNoTLSUsageCheckTest(ssl_provider.Pass());
+ RunNoTLSUsageCheckTest(std::move(ssl_provider));
}
class SpdyNetworkTransactionTLSUsageCheckTest
@@ -6568,7 +6540,7 @@ class SpdyNetworkTransactionTLSUsageCheckTest
request.url = GURL("https://www.example.org/");
NormalSpdyTransactionHelper helper(
request, DEFAULT_PRIORITY, BoundNetLog(), GetParam(), NULL);
- helper.RunToCompletionWithSSLData(&data, ssl_provider.Pass());
+ helper.RunToCompletionWithSSLData(&data, std::move(ssl_provider));
TransactionHelperResult out = helper.output();
EXPECT_EQ(ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, out.rv);
}
@@ -6577,8 +6549,12 @@ class SpdyNetworkTransactionTLSUsageCheckTest
INSTANTIATE_TEST_CASE_P(
Spdy,
SpdyNetworkTransactionTLSUsageCheckTest,
- ::testing::Values(
- SpdyNetworkTransactionTestParams(kProtoHTTP2, HTTPS_SPDY_VIA_NPN)));
+ ::testing::Values(SpdyNetworkTransactionTestParams(kProtoHTTP2,
+ HTTPS_SPDY_VIA_NPN,
+ false),
+ SpdyNetworkTransactionTestParams(kProtoHTTP2,
+ HTTPS_SPDY_VIA_NPN,
+ true)));
TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSVersionTooOld) {
scoped_ptr<SSLSocketDataProvider> ssl_provider(
@@ -6586,7 +6562,7 @@ TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSVersionTooOld) {
SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3,
&ssl_provider->connection_status);
- RunTLSUsageCheckTest(ssl_provider.Pass());
+ RunTLSUsageCheckTest(std::move(ssl_provider));
}
TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSCipherSuiteSucky) {
@@ -6595,7 +6571,7 @@ TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSCipherSuiteSucky) {
// Set to TLS_RSA_WITH_NULL_MD5
SSLConnectionStatusSetCipherSuite(0x1, &ssl_provider->connection_status);
- RunTLSUsageCheckTest(ssl_provider.Pass());
+ RunTLSUsageCheckTest(std::move(ssl_provider));
}
} // namespace net
diff --git a/chromium/net/spdy/spdy_pinnable_buffer_piece.h b/chromium/net/spdy/spdy_pinnable_buffer_piece.h
index 42bae12a50b..d0fe866c8ed 100644
--- a/chromium/net/spdy/spdy_pinnable_buffer_piece.h
+++ b/chromium/net/spdy/spdy_pinnable_buffer_piece.h
@@ -5,6 +5,8 @@
#ifndef NET_SPDY_SPDY_PINNABLE_BUFFER_PIECE_H_
#define NET_SPDY_SPDY_PINNABLE_BUFFER_PIECE_H_
+#include <stddef.h>
+
#include <memory>
#include "base/memory/scoped_ptr.h"
diff --git a/chromium/net/spdy/spdy_prefixed_buffer_reader.h b/chromium/net/spdy/spdy_prefixed_buffer_reader.h
index 6d277179712..9e5fc914580 100644
--- a/chromium/net/spdy/spdy_prefixed_buffer_reader.h
+++ b/chromium/net/spdy/spdy_prefixed_buffer_reader.h
@@ -5,6 +5,8 @@
#ifndef NET_SPDY_SPDY_PREFIXED_BUFFER_READER_H_
#define NET_SPDY_SPDY_PREFIXED_BUFFER_READER_H_
+#include <stddef.h>
+
#include "net/base/net_export.h"
#include "net/spdy/spdy_pinnable_buffer_piece.h"
diff --git a/chromium/net/spdy/spdy_priority_tree.h b/chromium/net/spdy/spdy_priority_tree.h
index 1652f77efe8..ea09c2a592b 100644
--- a/chromium/net/spdy/spdy_priority_tree.h
+++ b/chromium/net/spdy/spdy_priority_tree.h
@@ -13,9 +13,9 @@
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
diff --git a/chromium/net/spdy/spdy_priority_tree_test.cc b/chromium/net/spdy/spdy_priority_tree_test.cc
index f9991b82284..b953c01c696 100644
--- a/chromium/net/spdy/spdy_priority_tree_test.cc
+++ b/chromium/net/spdy/spdy_priority_tree_test.cc
@@ -4,7 +4,6 @@
#include "net/spdy/spdy_priority_tree.h"
-#include "base/basictypes.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -44,7 +43,7 @@ class SpdyPriorityTreePeer {
class SpdyPriorityTreeTest : public ::testing::Test {
protected:
- typedef uint32 SpdyStreamId;
+ typedef uint32_t SpdyStreamId;
typedef std::pair<SpdyStreamId, float> PriorityNode;
typedef std::vector<PriorityNode> PriorityList;
diff --git a/chromium/net/spdy/spdy_protocol.cc b/chromium/net/spdy/spdy_protocol.cc
index 46b080f940a..ca48c5470ae 100644
--- a/chromium/net/spdy/spdy_protocol.cc
+++ b/chromium/net/spdy/spdy_protocol.cc
@@ -6,27 +6,9 @@
namespace net {
-SpdyFrameWithHeaderBlockIR::SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id)
- : SpdyFrameWithFinIR(stream_id) {}
-
-SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() {}
-
-SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, base::StringPiece data)
- : SpdyFrameWithFinIR(stream_id), padded_(false), padding_payload_len_(0) {
- SetDataDeep(data);
-}
-
-SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
- : SpdyFrameWithFinIR(stream_id),
- padded_(false),
- padding_payload_len_(0) {}
-
-SpdyDataIR::~SpdyDataIR() {}
-
bool SpdyConstants::IsValidFrameType(SpdyMajorVersion version,
int frame_type_field) {
switch (version) {
- case SPDY2:
case SPDY3:
// SYN_STREAM is the first valid frame.
if (frame_type_field < SerializeFrameType(version, SYN_STREAM)) {
@@ -66,7 +48,6 @@ bool SpdyConstants::IsValidFrameType(SpdyMajorVersion version,
SpdyFrameType SpdyConstants::ParseFrameType(SpdyMajorVersion version,
int frame_type_field) {
switch (version) {
- case SPDY2:
case SPDY3:
switch (frame_type_field) {
case 1:
@@ -124,7 +105,6 @@ SpdyFrameType SpdyConstants::ParseFrameType(SpdyMajorVersion version,
int SpdyConstants::SerializeFrameType(SpdyMajorVersion version,
SpdyFrameType frame_type) {
switch (version) {
- case SPDY2:
case SPDY3:
switch (frame_type) {
case SYN_STREAM:
@@ -186,7 +166,6 @@ int SpdyConstants::SerializeFrameType(SpdyMajorVersion version,
int SpdyConstants::DataFrameType(SpdyMajorVersion version) {
switch (version) {
- case SPDY2:
case SPDY3:
return 0;
case HTTP2:
@@ -200,7 +179,6 @@ int SpdyConstants::DataFrameType(SpdyMajorVersion version) {
bool SpdyConstants::IsValidSettingId(SpdyMajorVersion version,
int setting_id_field) {
switch (version) {
- case SPDY2:
case SPDY3:
// UPLOAD_BANDWIDTH is the first valid setting id.
if (setting_id_field <
@@ -238,7 +216,6 @@ bool SpdyConstants::IsValidSettingId(SpdyMajorVersion version,
SpdySettingsIds SpdyConstants::ParseSettingId(SpdyMajorVersion version,
int setting_id_field) {
switch (version) {
- case SPDY2:
case SPDY3:
switch (setting_id_field) {
case 1:
@@ -282,7 +259,6 @@ SpdySettingsIds SpdyConstants::ParseSettingId(SpdyMajorVersion version,
int SpdyConstants::SerializeSettingId(SpdyMajorVersion version,
SpdySettingsIds id) {
switch (version) {
- case SPDY2:
case SPDY3:
switch (id) {
case SETTINGS_UPLOAD_BANDWIDTH:
@@ -329,7 +305,6 @@ int SpdyConstants::SerializeSettingId(SpdyMajorVersion version,
bool SpdyConstants::IsValidRstStreamStatus(SpdyMajorVersion version,
int rst_stream_status_field) {
switch (version) {
- case SPDY2:
case SPDY3:
// PROTOCOL_ERROR is the valid first status code.
if (rst_stream_status_field <
@@ -378,7 +353,6 @@ SpdyRstStreamStatus SpdyConstants::ParseRstStreamStatus(
SpdyMajorVersion version,
int rst_stream_status_field) {
switch (version) {
- case SPDY2:
case SPDY3:
switch (rst_stream_status_field) {
case 1:
@@ -399,8 +373,6 @@ SpdyRstStreamStatus SpdyConstants::ParseRstStreamStatus(
return RST_STREAM_STREAM_IN_USE;
case 9:
return RST_STREAM_STREAM_ALREADY_CLOSED;
- case 10:
- return RST_STREAM_INVALID_CREDENTIALS;
case 11:
return RST_STREAM_FRAME_TOO_LARGE;
}
@@ -441,7 +413,6 @@ int SpdyConstants::SerializeRstStreamStatus(
SpdyMajorVersion version,
SpdyRstStreamStatus rst_stream_status) {
switch (version) {
- case SPDY2:
case SPDY3:
switch (rst_stream_status) {
case RST_STREAM_PROTOCOL_ERROR:
@@ -462,8 +433,6 @@ int SpdyConstants::SerializeRstStreamStatus(
return 8;
case RST_STREAM_STREAM_ALREADY_CLOSED:
return 9;
- case RST_STREAM_INVALID_CREDENTIALS:
- return 10;
case RST_STREAM_FRAME_TOO_LARGE:
return 11;
default:
@@ -508,7 +477,6 @@ int SpdyConstants::SerializeRstStreamStatus(
bool SpdyConstants::IsValidGoAwayStatus(SpdyMajorVersion version,
int goaway_status_field) {
switch (version) {
- case SPDY2:
case SPDY3:
// GOAWAY_OK is the first valid status.
if (goaway_status_field < SerializeGoAwayStatus(version, GOAWAY_OK)) {
@@ -544,7 +512,6 @@ bool SpdyConstants::IsValidGoAwayStatus(SpdyMajorVersion version,
SpdyGoAwayStatus SpdyConstants::ParseGoAwayStatus(SpdyMajorVersion version,
int goaway_status_field) {
switch (version) {
- case SPDY2:
case SPDY3:
switch (goaway_status_field) {
case 0:
@@ -593,52 +560,9 @@ SpdyGoAwayStatus SpdyConstants::ParseGoAwayStatus(SpdyMajorVersion version,
return GOAWAY_PROTOCOL_ERROR;
}
-SpdyMajorVersion SpdyConstants::ParseMajorVersion(int version_number) {
- switch (version_number) {
- case 2:
- return SPDY2;
- case 3:
- return SPDY3;
- case 4:
- return HTTP2;
- default:
- LOG(DFATAL) << "Unsupported SPDY version number: " << version_number;
- return SPDY3;
- }
-}
-
-int SpdyConstants::SerializeMajorVersion(SpdyMajorVersion version) {
- switch (version) {
- case SPDY2:
- return 2;
- case SPDY3:
- return 3;
- case HTTP2:
- return 4;
- default:
- LOG(DFATAL) << "Unsupported SPDY major version: " << version;
- return -1;
- }
-}
-
-std::string SpdyConstants::GetVersionString(SpdyMajorVersion version) {
- switch (version) {
- case SPDY2:
- return "spdy/2";
- case SPDY3:
- return "spdy/3";
- case HTTP2:
- return "h2";
- default:
- LOG(DFATAL) << "Unsupported SPDY major version: " << version;
- return "spdy/3";
- }
-}
-
int SpdyConstants::SerializeGoAwayStatus(SpdyMajorVersion version,
SpdyGoAwayStatus status) {
switch (version) {
- case SPDY2:
case SPDY3:
// TODO(jgraettinger): Merge this back to server-side.
switch (status) {
@@ -703,7 +627,6 @@ int SpdyConstants::SerializeGoAwayStatus(SpdyMajorVersion version,
size_t SpdyConstants::GetDataFrameMinimumSize(SpdyMajorVersion version) {
switch (version) {
- case SPDY2:
case SPDY3:
return 8;
case HTTP2:
@@ -715,7 +638,6 @@ size_t SpdyConstants::GetDataFrameMinimumSize(SpdyMajorVersion version) {
size_t SpdyConstants::GetControlFrameHeaderSize(SpdyMajorVersion version) {
switch (version) {
- case SPDY2:
case SPDY3:
return 8;
case HTTP2:
@@ -747,22 +669,73 @@ size_t SpdyConstants::GetFrameMaximumSize(SpdyMajorVersion version) {
}
}
-size_t SpdyConstants::GetSizeOfSizeField(SpdyMajorVersion version) {
- return (version < SPDY3) ? sizeof(uint16) : sizeof(uint32);
+size_t SpdyConstants::GetSizeOfSizeField() {
+ return sizeof(uint32_t);
}
size_t SpdyConstants::GetSettingSize(SpdyMajorVersion version) {
return version <= SPDY3 ? 8 : 6;
}
-int32 SpdyConstants::GetInitialStreamWindowSize(SpdyMajorVersion version) {
+int32_t SpdyConstants::GetInitialStreamWindowSize(SpdyMajorVersion version) {
return (version <= SPDY3) ? (64 * 1024) : (64 * 1024 - 1);
}
-int32 SpdyConstants::GetInitialSessionWindowSize(SpdyMajorVersion version) {
+int32_t SpdyConstants::GetInitialSessionWindowSize(SpdyMajorVersion version) {
return (version <= SPDY3) ? (64 * 1024) : (64 * 1024 - 1);
}
+SpdyMajorVersion SpdyConstants::ParseMajorVersion(int version_number) {
+ switch (version_number) {
+ case 3:
+ return SPDY3;
+ case 4:
+ return HTTP2;
+ default:
+ LOG(DFATAL) << "Unsupported SPDY version number: " << version_number;
+ return SPDY3;
+ }
+}
+
+int SpdyConstants::SerializeMajorVersion(SpdyMajorVersion version) {
+ switch (version) {
+ case SPDY3:
+ return 3;
+ case HTTP2:
+ return 4;
+ default:
+ LOG(DFATAL) << "Unsupported SPDY major version: " << version;
+ return -1;
+ }
+}
+
+std::string SpdyConstants::GetVersionString(SpdyMajorVersion version) {
+ switch (version) {
+ case SPDY3:
+ return "spdy/3";
+ case HTTP2:
+ return "h2";
+ default:
+ LOG(DFATAL) << "Unsupported SPDY major version: " << version;
+ return "spdy/3";
+ }
+}
+
+SpdyFrameWithHeaderBlockIR::SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id)
+ : SpdyFrameWithFinIR(stream_id) {}
+
+SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() {}
+
+SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, base::StringPiece data)
+ : SpdyFrameWithFinIR(stream_id), padded_(false), padding_payload_len_(0) {
+ SetDataDeep(data);
+}
+
+SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
+ : SpdyFrameWithFinIR(stream_id), padded_(false), padding_payload_len_(0) {}
+
+SpdyDataIR::~SpdyDataIR() {}
+
void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitData(*this);
}
@@ -776,10 +749,8 @@ void SpdySynReplyIR::Visit(SpdyFrameVisitor* visitor) const {
}
SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
- SpdyRstStreamStatus status,
- base::StringPiece description)
- : SpdyFrameWithStreamIdIR(stream_id),
- description_(description) {
+ SpdyRstStreamStatus status)
+ : SpdyFrameWithStreamIdIR(stream_id) {
set_status(status);
}
@@ -813,10 +784,6 @@ SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
SpdyGoAwayIR::~SpdyGoAwayIR() {}
-const base::StringPiece& SpdyGoAwayIR::description() const {
- return description_;
-}
-
void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitGoAway(*this);
}
diff --git a/chromium/net/spdy/spdy_protocol.h b/chromium/net/spdy/spdy_protocol.h
index c5d66c917d1..86eb9b1a400 100644
--- a/chromium/net/spdy/spdy_protocol.h
+++ b/chromium/net/spdy/spdy_protocol.h
@@ -2,22 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This file contains some protocol structures for use with SPDY 2 and 3
-// The SPDY 2 spec can be found at:
-// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2
+// This file contains some protocol structures for use with SPDY 3 and HTTP 2
// The SPDY 3 spec can be found at:
// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3
#ifndef NET_SPDY_SPDY_PROTOCOL_H_
#define NET_SPDY_SPDY_PROTOCOL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <limits>
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "base/sys_byteorder.h"
@@ -30,52 +31,33 @@ namespace net {
// The major versions of SPDY. Major version differences indicate
// framer-layer incompatibility, as opposed to minor version numbers
-// which indicate application-layer incompatibility. Do not rely on
-// the mapping from enum value SPDYn to the integer n.
+// which indicate application-layer incompatibility. It is NOT guaranteed
+// that the enum value SPDYn maps to the integer n.
enum SpdyMajorVersion {
- SPDY2 = 2,
- SPDY_MIN_VERSION = SPDY2,
- SPDY3 = 3,
- HTTP2 = 4,
+ SPDY3 = 1,
+ SPDY_MIN_VERSION = SPDY3,
+ HTTP2,
SPDY_MAX_VERSION = HTTP2
};
// A SPDY stream id is a 31 bit entity.
-typedef uint32 SpdyStreamId;
+typedef uint32_t SpdyStreamId;
// Specifies the stream ID used to denote the current session (for
// flow control).
const SpdyStreamId kSessionFlowControlStreamId = 0;
// The maxmium possible control frame size allowed by the spec.
-const int32 kSpdyMaxControlFrameSize = (1 << 24) - 1;
+const int32_t kSpdyMaxControlFrameSize = (1 << 24) - 1;
// The maximum control frame size we accept.
-const int32 kControlFrameSizeLimit = 1 << 14;
+const int32_t kControlFrameSizeLimit = 1 << 14;
// Maximum window size for a Spdy stream or session.
-const int32 kSpdyMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int
+const int32_t kSpdyMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int
// Maximum padding size in octets for one DATA or HEADERS or PUSH_PROMISE frame.
-const int32 kPaddingSizePerFrame = 256;
-
-// SPDY 2 dictionary.
-// This is just a hacked dictionary to use for shrinking HTTP-like headers.
-const char kV2Dictionary[] =
- "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
- "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
- "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
- "-agent10010120020120220320420520630030130230330430530630740040140240340440"
- "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
- "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
- "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
- "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
- "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
- "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
- "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
- "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
- ".1statusversionurl";
-const int kV2DictionarySize = arraysize(kV2Dictionary);
+const int32_t kPaddingSizePerFrame = 256;
// SPDY 3 dictionary.
const char kV3Dictionary[] = {
@@ -287,7 +269,6 @@ enum SpdyFrameType {
GOAWAY,
HEADERS,
WINDOW_UPDATE,
- CREDENTIAL = 10, // No longer valid. Kept for identifiability.
PUSH_PROMISE,
CONTINUATION,
PRIORITY,
@@ -383,7 +364,6 @@ enum SpdyRstStreamStatus {
RST_STREAM_FLOW_CONTROL_ERROR = 7,
RST_STREAM_STREAM_IN_USE = 8,
RST_STREAM_STREAM_ALREADY_CLOSED = 9,
- RST_STREAM_INVALID_CREDENTIALS = 10,
// FRAME_TOO_LARGE (defined by SPDY versions 3.1 and below), and
// FRAME_SIZE_ERROR (defined by HTTP/2) are mapped to the same internal
// reset status.
@@ -417,11 +397,15 @@ enum SpdyGoAwayStatus {
};
// A SPDY priority is a number between 0 and 7 (inclusive).
-// SPDY priority range is version-dependent. For SPDY 2 and below, priority is a
-// number between 0 and 3.
-typedef uint8 SpdyPriority;
+typedef uint8_t SpdyPriority;
+
+// Lowest and Highest here refer to SPDY priorities as described in
-typedef uint64 SpdyPingId;
+// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
+const SpdyPriority kV3HighestPriority = 0;
+const SpdyPriority kV3LowestPriority = 7;
+
+typedef uint64_t SpdyPingId;
typedef std::string SpdyProtocolId;
@@ -522,18 +506,17 @@ class NET_EXPORT_PRIVATE SpdyConstants {
static size_t GetFrameMaximumSize(SpdyMajorVersion version);
- // Returns the size of a header block size field. Valid only for SPDY
- // versions <= 3.
- static size_t GetSizeOfSizeField(SpdyMajorVersion version);
+ // Returns the size of a header block size field. Valid only for SPDY 3.
+ static size_t GetSizeOfSizeField();
// Returns the size (in bytes) of a wire setting ID and value.
static size_t GetSettingSize(SpdyMajorVersion version);
// Initial window size for a stream in bytes.
- static int32 GetInitialStreamWindowSize(SpdyMajorVersion version);
+ static int32_t GetInitialStreamWindowSize(SpdyMajorVersion version);
// Initial window size for a session in bytes.
- static int32 GetInitialSessionWindowSize(SpdyMajorVersion version);
+ static int32_t GetInitialSessionWindowSize(SpdyMajorVersion version);
static SpdyMajorVersion ParseMajorVersion(int version_number);
@@ -609,6 +592,8 @@ class NET_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR {
class NET_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR
: public NON_EXPORTED_BASE(SpdyFrameWithFinIR) {
public:
+ ~SpdyFrameWithHeaderBlockIR() override;
+
const SpdyHeaderBlock& header_block() const { return header_block_; }
void set_header_block(const SpdyHeaderBlock& header_block) {
// Deep copy.
@@ -621,7 +606,6 @@ class NET_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR
protected:
explicit SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id);
- ~SpdyFrameWithHeaderBlockIR() override;
private:
SpdyHeaderBlock header_block_;
@@ -723,8 +707,7 @@ class NET_EXPORT_PRIVATE SpdySynReplyIR : public SpdyFrameWithHeaderBlockIR {
class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
public:
- SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status,
- base::StringPiece description);
+ SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status);
~SpdyRstStreamIR() override;
@@ -735,13 +718,10 @@ class NET_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
status_ = status;
}
- base::StringPiece description() const { return description_; }
-
void Visit(SpdyFrameVisitor* visitor) const override;
private:
SpdyRstStreamStatus status_;
- base::StringPiece description_;
DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR);
};
@@ -755,7 +735,7 @@ class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
value(0) {}
bool persist_value;
bool persisted;
- int32 value;
+ int32_t value;
};
typedef std::map<SpdySettingsIds, Value> ValueMap;
@@ -768,7 +748,7 @@ class NET_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
void AddSetting(SpdySettingsIds id,
bool persist_value,
bool persisted,
- int32 value) {
+ int32_t value) {
values_[id].persist_value = persist_value;
values_[id].persisted = persisted;
values_[id].value = value;
@@ -826,7 +806,7 @@ class NET_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
status_ = status;
}
- const base::StringPiece& description() const;
+ const base::StringPiece& description() const { return description_; }
void Visit(SpdyFrameVisitor* visitor) const override;
@@ -847,7 +827,7 @@ class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
bool has_priority() const { return has_priority_; }
void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
- uint32 priority() const { return priority_; }
+ uint32_t priority() const { return priority_; }
void set_priority(SpdyPriority priority) { priority_ = priority; }
SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
void set_parent_stream_id(SpdyStreamId id) { parent_stream_id_ = id; }
@@ -866,7 +846,7 @@ class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
private:
bool has_priority_ = false;
// 31-bit priority.
- uint32 priority_ = 0;
+ uint32_t priority_ = 0;
SpdyStreamId parent_stream_id_ = 0;
bool exclusive_ = false;
bool padded_ = false;
@@ -877,12 +857,12 @@ class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
public:
- SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta)
+ SpdyWindowUpdateIR(SpdyStreamId stream_id, int32_t delta)
: SpdyFrameWithStreamIdIR(stream_id) {
set_delta(delta);
}
- int32 delta() const { return delta_; }
- void set_delta(int32 delta) {
+ int32_t delta() const { return delta_; }
+ void set_delta(int32_t delta) {
DCHECK_LT(0, delta);
DCHECK_LE(delta, kSpdyMaximumWindowSize);
delta_ = delta;
@@ -891,7 +871,7 @@ class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
void Visit(SpdyFrameVisitor* visitor) const override;
private:
- int32 delta_;
+ int32_t delta_;
DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR);
};
@@ -988,7 +968,7 @@ class NET_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameWithStreamIdIR {
exclusive_(false) {}
SpdyPriorityIR(SpdyStreamId stream_id,
SpdyStreamId parent_stream_id,
- uint8 weight,
+ uint8_t weight,
bool exclusive)
: SpdyFrameWithStreamIdIR(stream_id),
parent_stream_id_(parent_stream_id),
@@ -996,8 +976,8 @@ class NET_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameWithStreamIdIR {
exclusive_(exclusive) {}
SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
void set_parent_stream_id(SpdyStreamId id) { parent_stream_id_ = id; }
- uint8 weight() const { return weight_; }
- void set_weight(uint8 weight) { weight_ = weight; }
+ uint8_t weight() const { return weight_; }
+ void set_weight(uint8_t weight) { weight_ = weight; }
bool exclusive() const { return exclusive_; }
void set_exclusive(bool exclusive) { exclusive_ = exclusive; }
@@ -1005,7 +985,7 @@ class NET_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameWithStreamIdIR {
private:
SpdyStreamId parent_stream_id_;
- uint8 weight_;
+ uint8_t weight_;
bool exclusive_;
DISALLOW_COPY_AND_ASSIGN(SpdyPriorityIR);
};
diff --git a/chromium/net/spdy/spdy_protocol_test.cc b/chromium/net/spdy/spdy_protocol_test.cc
index 486a7722fda..c224818447a 100644
--- a/chromium/net/spdy/spdy_protocol_test.cc
+++ b/chromium/net/spdy/spdy_protocol_test.cc
@@ -6,7 +6,6 @@
#include <limits>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/spdy/spdy_bitmasks.h"
#include "net/spdy/spdy_framer.h"
@@ -15,47 +14,19 @@
namespace {
-enum SpdyProtocolTestTypes {
- SPDY2 = net::SPDY2,
- SPDY3 = net::SPDY3,
-};
-
} // namespace
namespace net {
-class SpdyProtocolTest
- : public ::testing::TestWithParam<SpdyProtocolTestTypes> {
- protected:
- void SetUp() override {
- spdy_version_ = static_cast<SpdyMajorVersion>(GetParam());
- }
-
- // Version of SPDY protocol to be used.
- SpdyMajorVersion spdy_version_;
-};
-
-// All tests are run with two different SPDY versions: SPDY/2 and SPDY/3.
-INSTANTIATE_TEST_CASE_P(SpdyProtocolTests,
- SpdyProtocolTest,
- ::testing::Values(SPDY2, SPDY3));
-
-class SpdyProtocolDeathTest : public SpdyProtocolTest {};
-
-// All tests are run with two different SPDY versions: SPDY/2 and SPDY/3.
-INSTANTIATE_TEST_CASE_P(SpdyProtocolDeathTests,
- SpdyProtocolDeathTest,
- ::testing::Values(SPDY2, SPDY3));
-
-TEST_P(SpdyProtocolDeathTest, TestSpdySettingsAndIdOutOfBounds) {
+TEST(SpdyProtocolDeathTest, TestSpdySettingsAndIdOutOfBounds) {
scoped_ptr<SettingsFlagsAndId> flags_and_id;
- EXPECT_DFATAL(flags_and_id.reset(new SettingsFlagsAndId(1, 0xFFFFFFFF)),
+ EXPECT_DFATAL(flags_and_id.reset(new SettingsFlagsAndId(1, 0xffffffff)),
"SPDY setting ID too large.");
// Make sure that we get expected values in opt mode.
- if (flags_and_id.get() != NULL) {
+ if (flags_and_id.get() != nullptr) {
EXPECT_EQ(1, flags_and_id->flags());
- EXPECT_EQ(static_cast<SpdyPingId>(0xffffff), flags_and_id->id());
+ EXPECT_EQ(0xffffffu, flags_and_id->id());
}
}
diff --git a/chromium/net/spdy/spdy_proxy_client_socket.cc b/chromium/net/spdy/spdy_proxy_client_socket.cc
index e6d521e1356..df2530b19dc 100644
--- a/chromium/net/spdy/spdy_proxy_client_socket.cc
+++ b/chromium/net/spdy/spdy_proxy_client_socket.cc
@@ -5,6 +5,7 @@
#include "net/spdy/spdy_proxy_client_socket.h"
#include <algorithm> // min
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -34,15 +35,11 @@ SpdyProxyClientSocket::SpdyProxyClientSocket(
const HostPortPair& endpoint,
const HostPortPair& proxy_server,
const BoundNetLog& source_net_log,
- HttpAuthCache* auth_cache,
- HttpAuthHandlerFactory* auth_handler_factory)
+ HttpAuthController* auth_controller)
: next_state_(STATE_DISCONNECTED),
spdy_stream_(spdy_stream),
endpoint_(endpoint),
- auth_(new HttpAuthController(HttpAuth::AUTH_PROXY,
- GURL("https://" + proxy_server.ToString()),
- auth_cache,
- auth_handler_factory)),
+ auth_(auth_controller),
user_agent_(user_agent),
user_buffer_len_(0),
write_buffer_len_(0),
@@ -198,6 +195,11 @@ void SpdyProxyClientSocket::GetConnectionAttempts(
out->clear();
}
+int64_t SpdyProxyClientSocket::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(read_callback_.is_null());
@@ -243,13 +245,13 @@ int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len,
return ERR_IO_PENDING;
}
-int SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) {
+int SpdyProxyClientSocket::SetReceiveBufferSize(int32_t size) {
// Since this StreamSocket sits on top of a shared SpdySession, it
// is not safe for callers to change this underlying socket.
return ERR_NOT_IMPLEMENTED;
}
-int SpdyProxyClientSocket::SetSendBufferSize(int32 size) {
+int SpdyProxyClientSocket::SetSendBufferSize(int32_t size) {
// Since this StreamSocket sits on top of a shared SpdySession, it
// is not safe for callers to change this underlying socket.
return ERR_NOT_IMPLEMENTED;
@@ -372,7 +374,8 @@ int SpdyProxyClientSocket::DoSendRequest() {
spdy_stream_->GetProtocolVersion(), true,
headers.get());
- return spdy_stream_->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND);
+ return spdy_stream_->SendRequestHeaders(std::move(headers),
+ MORE_DATA_TO_SEND);
}
int SpdyProxyClientSocket::DoSendRequestComplete(int result) {
@@ -392,7 +395,7 @@ int SpdyProxyClientSocket::DoReadReplyComplete(int result) {
return result;
// Require the "HTTP/1.x" status line for SSL CONNECT.
- if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0))
+ if (response_.headers->GetHttpVersion() < HttpVersion(1, 0))
return ERR_TUNNEL_CONNECTION_FAILED;
net_log_.AddEvent(
@@ -467,7 +470,7 @@ void SpdyProxyClientSocket::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED,
buffer->GetRemainingSize(),
buffer->GetRemainingData());
- read_buffer_queue_.Enqueue(buffer.Pass());
+ read_buffer_queue_.Enqueue(std::move(buffer));
} else {
net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, 0, NULL);
}
diff --git a/chromium/net/spdy/spdy_proxy_client_socket.h b/chromium/net/spdy/spdy_proxy_client_socket.h
index af38767eab9..9dc9cff15be 100644
--- a/chromium/net/spdy/spdy_proxy_client_socket.h
+++ b/chromium/net/spdy/spdy_proxy_client_socket.h
@@ -5,10 +5,13 @@
#ifndef NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
#define NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/base/completion_callback.h"
@@ -45,9 +48,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
const HostPortPair& endpoint,
const HostPortPair& proxy_server,
const BoundNetLog& source_net_log,
- HttpAuthCache* auth_cache,
- HttpAuthHandlerFactory* auth_handler_factory);
-
+ HttpAuthController* auth_controller);
// On destruction Disconnect() is called.
~SpdyProxyClientSocket() override;
@@ -76,6 +77,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
void GetConnectionAttempts(ConnectionAttempts* out) const override;
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -84,8 +86,8 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
int Write(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
diff --git a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc
index b8f62cfb094..2fcf3f431f8 100644
--- a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -6,6 +6,8 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/macros.h"
+#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/address_list.h"
#include "net/base/test_completion_callback.h"
@@ -33,6 +35,19 @@
namespace {
+enum TestCase {
+ // Test using the SPDY/3.1 protocol.
+ kTestCaseSPDY31,
+
+ // Test using the HTTP/2 protocol, without specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2NoPriorityDependencies,
+
+ // Test using the HTTP/2 protocol, specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2PriorityDependencies
+};
+
static const char kRequestUrl[] = "https://www.google.com/";
static const char kOriginHost[] = "www.google.com";
static const int kOriginPort = 443;
@@ -61,15 +76,18 @@ static const char kRedirectUrl[] = "https://example.com/";
namespace net {
-class SpdyProxyClientSocketTest
- : public PlatformTest,
- public testing::WithParamInterface<NextProto> {
+class SpdyProxyClientSocketTest : public PlatformTest,
+ public testing::WithParamInterface<TestCase> {
public:
SpdyProxyClientSocketTest();
+ ~SpdyProxyClientSocketTest();
void TearDown() override;
protected:
+ NextProto GetProtocol() const;
+ bool GetDependenciesFromPriority() const;
+
void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
size_t writes_count);
void PopulateConnectRequestIR(SpdyHeaderBlock* syn_ir);
@@ -92,8 +110,6 @@ class SpdyProxyClientSocketTest
void AssertAsyncWriteSucceeds(const char* data, int len);
void AssertWriteReturns(const char* data, int len, int rv);
void AssertWriteLength(int len);
- void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
- int num_reads);
void AddAuthToCache() {
const base::string16 kFoo(base::ASCIIToUTF16("foo"));
@@ -106,9 +122,11 @@ class SpdyProxyClientSocketTest
"/");
}
- void Run(int steps) {
- data_->StopAfter(steps);
- data_->Run();
+ void ResumeAndRun() {
+ // Run until the pause, if the provider isn't paused yet.
+ data_->RunUntilPaused();
+ data_->Resume();
+ base::RunLoop().RunUntilIdle();
}
void CloseSpdySession(Error error, const std::string& description) {
@@ -119,11 +137,11 @@ class SpdyProxyClientSocketTest
scoped_ptr<SpdyProxyClientSocket> sock_;
TestCompletionCallback read_callback_;
TestCompletionCallback write_callback_;
- scoped_ptr<DeterministicSocketData> data_;
+ scoped_ptr<SequencedSocketData> data_;
BoundTestNetLog net_log_;
private:
- scoped_refptr<HttpNetworkSession> session_;
+ scoped_ptr<HttpNetworkSession> session_;
scoped_refptr<IOBuffer> read_buf_;
SpdySessionDependencies session_deps_;
MockConnect connect_data_;
@@ -140,16 +158,16 @@ class SpdyProxyClientSocketTest
DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
};
-INSTANTIATE_TEST_CASE_P(NextProto,
+INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
SpdyProxyClientSocketTest,
- testing::Values(kProtoSPDY31,
- kProtoHTTP2));
+ testing::Values(kTestCaseSPDY31,
+ kTestCaseHTTP2NoPriorityDependencies,
+ kTestCaseHTTP2PriorityDependencies));
SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
- : spdy_util_(GetParam()),
- session_(NULL),
+ : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
read_buf_(NULL),
- session_deps_(GetParam()),
+ session_deps_(GetProtocol()),
connect_data_(SYNCHRONOUS, OK),
framer_(spdy_util_.spdy_version(), false),
user_agent_(kUserAgent),
@@ -161,6 +179,14 @@ SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
proxy_,
PRIVACY_MODE_DISABLED) {
session_deps_.net_log = net_log_.bound().net_log();
+ SpdySession::SetPriorityDependencyDefaultForTesting(
+ GetDependenciesFromPriority());
+}
+
+SpdyProxyClientSocketTest::~SpdyProxyClientSocketTest() {
+ EXPECT_TRUE(data_->AllWriteDataConsumed());
+ EXPECT_TRUE(data_->AllReadDataConsumed());
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
}
void SpdyProxyClientSocketTest::TearDown() {
@@ -172,26 +198,30 @@ void SpdyProxyClientSocketTest::TearDown() {
PlatformTest::TearDown();
}
+NextProto SpdyProxyClientSocketTest::GetProtocol() const {
+ return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
+}
+
+bool SpdyProxyClientSocketTest::GetDependenciesFromPriority() const {
+ return GetParam() == kTestCaseHTTP2PriorityDependencies;
+}
+
void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
- size_t reads_count,
- MockWrite* writes,
- size_t writes_count) {
- data_.reset(new DeterministicSocketData(reads, reads_count,
- writes, writes_count));
+ size_t reads_count,
+ MockWrite* writes,
+ size_t writes_count) {
+ data_.reset(
+ new SequencedSocketData(reads, reads_count, writes, writes_count));
data_->set_connect_data(connect_data_);
- data_->SetStop(2);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(
- data_.get());
+ session_deps_.socket_factory->AddSocketDataProvider(data_.get());
session_deps_.host_resolver->set_synchronous_mode(true);
- session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
- &session_deps_);
+ session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
// Creates the SPDY session and stream.
- spdy_session_ =
- CreateInsecureSpdySession(
- session_, endpoint_spdy_session_key_, BoundNetLog());
+ spdy_session_ = CreateInsecureSpdySession(
+ session_.get(), endpoint_spdy_session_key_, BoundNetLog());
base::WeakPtr<SpdyStream> spdy_stream(
CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_, LOWEST,
@@ -201,8 +231,10 @@ void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
// Create the SpdyProxyClientSocket.
sock_.reset(new SpdyProxyClientSocket(
spdy_stream, user_agent_, endpoint_host_port_pair_, proxy_host_port_,
- net_log_.bound(), session_->http_auth_cache(),
- session_->http_auth_handler_factory()));
+ net_log_.bound(),
+ new HttpAuthController(
+ HttpAuth::AUTH_PROXY, GURL("https://" + proxy_host_port_.ToString()),
+ session_->http_auth_cache(), session_->http_auth_handler_factory())));
}
scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
@@ -214,13 +246,11 @@ scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
- data_->Run();
ASSERT_EQ(OK, read_callback_.WaitForResult());
}
void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
- data_->Run();
ASSERT_EQ(result, read_callback_.WaitForResult());
}
@@ -239,34 +269,29 @@ void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
}
void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
- int len) {
- data_->StopAfter(1);
+ int len) {
// Issue the read, which will be completed asynchronously
scoped_refptr<IOBuffer> buf(new IOBuffer(len));
ASSERT_EQ(ERR_IO_PENDING,
sock_->Read(buf.get(), len, read_callback_.callback()));
EXPECT_TRUE(sock_->IsConnected());
- data_->Run();
- EXPECT_TRUE(sock_->IsConnected());
+ ResumeAndRun();
- // Now the read will return
EXPECT_EQ(len, read_callback_.WaitForResult());
+ EXPECT_TRUE(sock_->IsConnected());
ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
}
-void SpdyProxyClientSocketTest::AssertReadStarts(const char* data,
- int len) {
- data_->StopAfter(1);
- // Issue the read, which will be completed asynchronously
+void SpdyProxyClientSocketTest::AssertReadStarts(const char* data, int len) {
+ // Issue the read, which will be completed asynchronously.
read_buf_ = new IOBuffer(len);
ASSERT_EQ(ERR_IO_PENDING,
sock_->Read(read_buf_.get(), len, read_callback_.callback()));
EXPECT_TRUE(sock_->IsConnected());
}
-void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
- int len) {
+void SpdyProxyClientSocketTest::AssertReadReturns(const char* data, int len) {
EXPECT_TRUE(sock_->IsConnected());
// Now the read will return
@@ -277,13 +302,12 @@ void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
int len) {
AssertWriteReturns(data, len, ERR_IO_PENDING);
- data_->RunFor(1);
AssertWriteLength(len);
}
void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
- int len,
- int rv) {
+ int len,
+ int rv) {
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
EXPECT_EQ(rv,
sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
@@ -293,21 +317,6 @@ void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
EXPECT_EQ(len, write_callback_.WaitForResult());
}
-void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
- const char* data, int len, int num_reads) {
- scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
-
- EXPECT_EQ(ERR_IO_PENDING,
- sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
-
- for (int i = 0; i < num_reads; i++) {
- Run(1);
- AssertSyncReadEquals(kMsg2, kLen2);
- }
-
- write_callback_.WaitForResult();
-}
-
void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
SpdyHeaderBlock* block) {
spdy_util_.MaybeAddVersionHeader(block);
@@ -393,8 +402,7 @@ TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -414,8 +422,7 @@ TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -435,8 +442,7 @@ TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -452,12 +458,12 @@ TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -507,12 +513,12 @@ TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -537,8 +543,8 @@ TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -550,7 +556,7 @@ TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
EXPECT_TRUE(sock_->IsConnected());
EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
- Run(1);
+ ResumeAndRun();
EXPECT_FALSE(sock_->IsConnected());
EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
@@ -567,15 +573,14 @@ TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
- CreateMockWrite(*msg1, 2, SYNCHRONOUS),
- CreateMockWrite(*msg2, 3, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*msg1, 3, SYNCHRONOUS),
+ CreateMockWrite(*msg2, 4, SYNCHRONOUS),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -591,17 +596,14 @@ TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
chunk_data.length()));
- MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
- CreateMockWrite(*chunk, 2, SYNCHRONOUS),
- CreateMockWrite(*chunk, 3, SYNCHRONOUS),
- CreateMockWrite(*chunk, 4, SYNCHRONOUS)
- };
+ MockWrite writes[] = {CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*chunk, 3, SYNCHRONOUS),
+ CreateMockWrite(*chunk, 4, SYNCHRONOUS),
+ CreateMockWrite(*chunk, 5, SYNCHRONOUS)};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 5), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -614,8 +616,6 @@ TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
EXPECT_EQ(ERR_IO_PENDING,
sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
- data_->RunFor(3);
-
EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
}
@@ -630,17 +630,16 @@ TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1); // SpdySession consumes the next read and sends it to
- // sock_ to be buffered.
+ // SpdySession consumes the next read and sends it to sock_ to be buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
}
@@ -654,21 +653,20 @@ TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- CreateMockRead(*msg2, 3, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4),
+ CreateMockRead(*msg2, 5, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1); // SpdySession consumes the next read and sends it to
- // sock_ to be buffered.
+ // SpdySession consumes the next read and sends it to sock_ to be buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
- Run(1); // SpdySession consumes the next read and sends it to
- // sock_ to be buffered.
+ // SpdySession consumes the next read and sends it to sock_ to be buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg2, kLen2);
}
@@ -682,18 +680,20 @@ TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- CreateMockRead(*msg2, 3, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC),
+ MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC),
+ CreateMockRead(*msg2, 4, ASYNC),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(2); // SpdySession consumes the next two reads and sends then to
- // sock_ to be buffered.
+ // SpdySession consumes the next two reads and sends then to sock_ to be
+ // buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
AssertSyncReadEquals(kMsg2, kLen2);
}
@@ -709,18 +709,20 @@ TEST_P(SpdyProxyClientSocketTest,
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg3, 2, ASYNC),
- CreateMockRead(*msg3, 3, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC),
+ MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg3, 3, ASYNC),
+ CreateMockRead(*msg3, 4, ASYNC),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(2); // SpdySession consumes the next two reads and sends then to
- // sock_ to be buffered.
+ // SpdySession consumes the next two reads and sends then to sock_ to be
+ // buffered.
+ ResumeAndRun();
// The payload from two data frames, each with kMsg3 will be combined
// together into a single read().
AssertSyncReadEquals(kMsg33, kLen33);
@@ -737,20 +739,22 @@ TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- CreateMockRead(*msg3, 3, ASYNC),
- CreateMockRead(*msg3, 4, ASYNC),
- CreateMockRead(*msg2, 5, ASYNC),
- MockRead(ASYNC, 0, 6), // EOF
+ CreateMockRead(*resp, 1, ASYNC),
+ MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC),
+ CreateMockRead(*msg3, 4, ASYNC),
+ CreateMockRead(*msg3, 5, ASYNC),
+ CreateMockRead(*msg2, 6, ASYNC),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 7),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(4); // SpdySession consumes the next four reads and sends then to
- // sock_ to be buffered.
+ // SpdySession consumes the next four reads and sends then to sock_ to be
+ // buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
// The payload from two data frames, each with kMsg3 will be combined
// together into a single read().
@@ -769,18 +773,20 @@ TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- CreateMockRead(*msg33, 3, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC),
+ MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC),
+ CreateMockRead(*msg33, 4, ASYNC),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(2); // SpdySession consumes the next two reads and sends then to
- // sock_ to be buffered.
+ // SpdySession consumes the next two reads and sends then to sock_ to be
+ // buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
// The payload from the single large data frame will be read across
// two different reads.
@@ -797,17 +803,17 @@ TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg333, 2, ASYNC),
- MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg333, 3, ASYNC),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1); // SpdySession consumes the next read and sends it to
- // sock_ to be buffered.
+ // SpdySession consumes the next read and sends it to sock_ to be buffered.
+ ResumeAndRun();
// The payload from the single large data frame will be read across
// two different reads.
AssertSyncReadEquals(kMsg33, kLen33);
@@ -829,18 +835,20 @@ TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- CreateMockRead(*msg2, 3, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC),
+ MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC),
+ CreateMockRead(*msg2, 4, ASYNC),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
- Run(2); // SpdySession consumes the next two reads and sends then to
- // sock_ to be buffered.
+ // SpdySession consumes the next two reads and sends then to sock_ to be
+ // buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
AssertSyncReadEquals(kMsg2, kLen2);
}
@@ -872,35 +880,37 @@ TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
- CreateMockWrite(*msg2, 3, SYNCHRONOUS),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ CreateMockWrite(*msg2, 4, SYNCHRONOUS),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC), // sync read
- CreateMockRead(*msg3, 4, ASYNC), // async read
- MockRead(ASYNC, 0, 5), // EOF
+ CreateMockRead(*resp, 1, ASYNC),
+ MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC), // sync read
+ MockRead(ASYNC, ERR_IO_PENDING, 5),
+ CreateMockRead(*msg3, 6, ASYNC), // async read
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 7),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1);
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
AssertReadStarts(kMsg3, kLen3);
- // Read should block until after the write succeeds
+ // Read should block until after the write succeeds.
- AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
+ AssertAsyncWriteSucceeds(kMsg2, kLen2); // Advances past paused read.
ASSERT_FALSE(read_callback_.have_result());
- Run(1);
- // Now the read will return
+ ResumeAndRun();
+ // Now the read will return.
AssertReadReturns(kMsg3, kLen3);
}
@@ -908,25 +918,24 @@ TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
- CreateMockWrite(*msg2, 4, ASYNC),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ MockWrite(ASYNC, ERR_IO_PENDING, 7), CreateMockWrite(*msg2, 8, ASYNC),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- CreateMockRead(*msg3, 3, ASYNC),
- MockRead(ASYNC, 0, 5), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4),
+ CreateMockRead(*msg3, 5, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1);
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
// Write should block until the read completes
AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
@@ -936,7 +945,7 @@ TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
ASSERT_FALSE(write_callback_.have_result());
// Now the write will complete
- Run(1);
+ ResumeAndRun();
AssertWriteLength(kLen2);
}
@@ -951,15 +960,15 @@ TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1);
+ ResumeAndRun();
ASSERT_FALSE(sock_->IsConnected());
ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
@@ -977,8 +986,8 @@ TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -987,7 +996,7 @@ TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
AssertReadStarts(kMsg1, kLen1);
- Run(1);
+ ResumeAndRun();
ASSERT_EQ(0, read_callback_.WaitForResult());
}
@@ -999,12 +1008,12 @@ TEST_P(SpdyProxyClientSocketTest,
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -1031,16 +1040,15 @@ TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*msg1, 2, ASYNC),
- MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, 0, 4), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(2);
+ ResumeAndRun();
ASSERT_FALSE(sock_->IsConnected());
scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
@@ -1064,33 +1072,34 @@ TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 2), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ MockRead(ASYNC, 0, 3), // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1); // Read EOF which will close the stream
+ // Read EOF which will close the stream.
+ ResumeAndRun();
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
sock_->Write(buf.get(), buf->size(), CompletionCallback()));
}
-// Calling Write() on a disconnected socket is an error
+// Calling Write() on a disconnected socket is an error.
TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -1112,14 +1121,13 @@ TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS),
- MockWrite(ASYNC, ERR_ABORTED, 2),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS),
+ MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -1131,6 +1139,8 @@ TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_IO_PENDING,
sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
+ // Make sure the write actually starts.
+ base::RunLoop().RunUntilIdle();
CloseSpdySession(ERR_ABORTED, std::string());
@@ -1144,13 +1154,12 @@ TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
- MockWrite(SYNCHRONOUS, 0, 3), // EOF
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -1179,12 +1188,12 @@ TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -1212,16 +1221,14 @@ TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
MockWrite writes[] = {
CreateMockWrite(*conn, 0, SYNCHRONOUS),
- MockWrite(ASYNC, ERR_ABORTED, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*rst, 2, ASYNC),
- MockRead(ASYNC, 0, 4) // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*rst, 3, ASYNC), MockRead(ASYNC, 0, 4) // EOF
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -1240,7 +1247,7 @@ TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
sock_->Write(
write_buf.get(), write_buf->size(), write_callback_.callback()));
- Run(2);
+ ResumeAndRun();
EXPECT_TRUE(sock_.get());
EXPECT_TRUE(read_callback_.have_result());
@@ -1257,22 +1264,22 @@ TEST_P(SpdyProxyClientSocketTest, NetLog) {
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockWrite writes[] = {
- CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
+ CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 5),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
AssertConnectSucceeds();
- Run(1); // SpdySession consumes the next read and sends it to
- // sock_ to be buffered.
+ // SpdySession consumes the next read and sends it to sock_ to be buffered.
+ ResumeAndRun();
AssertSyncReadEquals(kMsg1, kLen1);
NetLog::Source sock_source = sock_->NetLog().source();
@@ -1342,16 +1349,14 @@ TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
MockWrite writes[] = {
CreateMockWrite(*conn, 0, SYNCHRONOUS),
- MockWrite(ASYNC, ERR_ABORTED, 3),
};
scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
MockRead reads[] = {
- CreateMockRead(*resp, 1, ASYNC),
- CreateMockRead(*rst, 2, ASYNC),
- MockRead(ASYNC, 0, 4), // EOF
+ CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(*rst, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
};
Initialize(reads, arraysize(reads), writes, arraysize(writes));
@@ -1372,7 +1377,7 @@ TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
sock_->Write(
write_buf.get(), write_buf->size(), write_callback_.callback()));
- Run(1);
+ ResumeAndRun();
EXPECT_FALSE(sock_.get());
EXPECT_TRUE(read_callback.have_result());
diff --git a/chromium/net/spdy/spdy_read_queue.h b/chromium/net/spdy/spdy_read_queue.h
index 65f3dafc93f..7c4172cecfb 100644
--- a/chromium/net/spdy/spdy_read_queue.h
+++ b/chromium/net/spdy/spdy_read_queue.h
@@ -8,7 +8,7 @@
#include <cstddef>
#include <deque>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/spdy/spdy_session.cc b/chromium/net/spdy/spdy_session.cc
index 4055422f313..0e4a3e8c3a0 100644
--- a/chromium/net/spdy/spdy_session.cc
+++ b/chromium/net/spdy/spdy_session.cc
@@ -5,9 +5,10 @@
#include "net/spdy/spdy_session.h"
#include <algorithm>
+#include <limits>
#include <map>
+#include <utility>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
@@ -59,6 +60,14 @@ const int kHungIntervalSeconds = 10;
// Minimum seconds that unclaimed pushed streams will be kept in memory.
const int kMinPushedStreamLifetimeSeconds = 300;
+// Field trial constants
+const char kSpdyDependenciesFieldTrial[] = "SpdyEnableDependencies";
+const char kSpdyDepencenciesFieldTrialEnable[] = "Enable";
+
+// Whether the creation of SPDY dependencies based on priority is
+// enabled by default.
+static bool priority_dependency_enabled_default = false;
+
scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue(
const SpdyHeaderBlock& headers,
NetLogCaptureMode capture_mode) {
@@ -70,7 +79,7 @@ scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue(
ElideHeaderValueForNetLog(capture_mode, it->first.as_string(),
it->second.as_string()));
}
- return headers_list.Pass();
+ return headers_list;
}
scoped_ptr<base::Value> NetLogSpdySynStreamSentCallback(
@@ -86,7 +95,7 @@ scoped_ptr<base::Value> NetLogSpdySynStreamSentCallback(
dict->SetBoolean("unidirectional", unidirectional);
dict->SetInteger("priority", static_cast<int>(spdy_priority));
dict->SetInteger("stream_id", stream_id);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySynStreamReceivedCallback(
@@ -104,7 +113,7 @@ scoped_ptr<base::Value> NetLogSpdySynStreamReceivedCallback(
dict->SetInteger("priority", static_cast<int>(spdy_priority));
dict->SetInteger("stream_id", stream_id);
dict->SetInteger("associated_stream", associated_stream);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySynReplyOrHeadersReceivedCallback(
@@ -116,7 +125,7 @@ scoped_ptr<base::Value> NetLogSpdySynReplyOrHeadersReceivedCallback(
dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
dict->SetBoolean("fin", fin);
dict->SetInteger("stream_id", stream_id);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySessionCloseCallback(
@@ -126,7 +135,7 @@ scoped_ptr<base::Value> NetLogSpdySessionCloseCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("net_error", net_error);
dict->SetString("description", *description);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySessionCallback(
@@ -135,7 +144,7 @@ scoped_ptr<base::Value> NetLogSpdySessionCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host", host_pair->first.ToString());
dict->SetString("proxy", host_pair->second.ToPacString());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyInitializedCallback(
@@ -148,7 +157,7 @@ scoped_ptr<base::Value> NetLogSpdyInitializedCallback(
}
dict->SetString("protocol",
SSLClientSocket::NextProtoToString(protocol_version));
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySettingsCallback(
@@ -158,21 +167,21 @@ scoped_ptr<base::Value> NetLogSpdySettingsCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host", host_port_pair.ToString());
dict->SetBoolean("clear_persisted", clear_persisted);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySettingCallback(
SpdySettingsIds id,
const SpdyMajorVersion protocol_version,
SpdySettingsFlags flags,
- uint32 value,
+ uint32_t value,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("id",
SpdyConstants::SerializeSettingId(protocol_version, id));
dict->SetInteger("flags", flags);
dict->SetInteger("value", value);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySendSettingsCallback(
@@ -185,35 +194,35 @@ scoped_ptr<base::Value> NetLogSpdySendSettingsCallback(
it != settings->end(); ++it) {
const SpdySettingsIds id = it->first;
const SpdySettingsFlags flags = it->second.first;
- const uint32 value = it->second.second;
+ const uint32_t value = it->second.second;
settings_list->Append(new base::StringValue(base::StringPrintf(
"[id:%u flags:%u value:%u]",
SpdyConstants::SerializeSettingId(protocol_version, id),
flags,
value)));
}
- dict->Set("settings", settings_list.Pass());
- return dict.Pass();
+ dict->Set("settings", std::move(settings_list));
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback(
SpdyStreamId stream_id,
- uint32 delta,
+ uint32_t delta,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", static_cast<int>(stream_id));
dict->SetInteger("delta", delta);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback(
- int32 delta,
- int32 window_size,
+ int32_t delta,
+ int32_t window_size,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("delta", delta);
dict->SetInteger("window_size", window_size);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyDataCallback(
@@ -225,7 +234,7 @@ scoped_ptr<base::Value> NetLogSpdyDataCallback(
dict->SetInteger("stream_id", static_cast<int>(stream_id));
dict->SetInteger("size", size);
dict->SetBoolean("fin", fin);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyRstCallback(
@@ -237,7 +246,7 @@ scoped_ptr<base::Value> NetLogSpdyRstCallback(
dict->SetInteger("stream_id", static_cast<int>(stream_id));
dict->SetInteger("status", status);
dict->SetString("description", *description);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyPingCallback(
@@ -249,7 +258,7 @@ scoped_ptr<base::Value> NetLogSpdyPingCallback(
dict->SetInteger("unique_id", static_cast<int>(unique_id));
dict->SetString("type", type);
dict->SetBoolean("is_ack", is_ack);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyGoAwayCallback(
@@ -257,14 +266,17 @@ scoped_ptr<base::Value> NetLogSpdyGoAwayCallback(
int active_streams,
int unclaimed_streams,
SpdyGoAwayStatus status,
- NetLogCaptureMode /* capture_mode */) {
+ StringPiece debug_data,
+ NetLogCaptureMode capture_mode) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("last_accepted_stream_id",
static_cast<int>(last_stream_id));
dict->SetInteger("active_streams", active_streams);
dict->SetInteger("unclaimed_streams", unclaimed_streams);
dict->SetInteger("status", static_cast<int>(status));
- return dict.Pass();
+ dict->SetString("debug_data",
+ ElideGoAwayDebugDataForNetLog(capture_mode, debug_data));
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback(
@@ -276,7 +288,7 @@ scoped_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback(
dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
dict->SetInteger("id", stream_id);
dict->SetInteger("promised_stream_id", promised_stream_id);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback(
@@ -286,7 +298,7 @@ scoped_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback(
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", stream_id);
dict->SetString("url", url->spec());
- return dict.Pass();
+ return std::move(dict);
}
// Helper function to return the total size of an array of objects
@@ -406,8 +418,6 @@ SpdyProtocolErrorDetails MapRstStreamStatusToProtocolError(
return STATUS_CODE_STREAM_IN_USE;
case RST_STREAM_STREAM_ALREADY_CLOSED:
return STATUS_CODE_STREAM_ALREADY_CLOSED;
- case RST_STREAM_INVALID_CREDENTIALS:
- return STATUS_CODE_INVALID_CREDENTIALS;
case RST_STREAM_FRAME_SIZE_ERROR:
return STATUS_CODE_FRAME_SIZE_ERROR;
case RST_STREAM_SETTINGS_TIMEOUT:
@@ -455,15 +465,11 @@ void SplitPushedHeadersToRequestAndResponse(const SpdyHeaderBlock& headers,
it != headers.end();
++it) {
SpdyHeaderBlock* to_insert = response_headers;
- if (protocol_version == SPDY2) {
- if (it->first == "url")
- to_insert = request_headers;
- } else {
- const char* host = protocol_version >= HTTP2 ? ":authority" : ":host";
- static const char scheme[] = ":scheme";
- static const char path[] = ":path";
- if (it->first == host || it->first == scheme || it->first == path)
- to_insert = request_headers;
+ const char* host = protocol_version >= HTTP2 ? ":authority" : ":host";
+ static const char scheme[] = ":scheme";
+ static const char path[] = ":path";
+ if (it->first == host || it->first == scheme || it->first == path) {
+ to_insert = request_headers;
}
to_insert->insert(*it);
}
@@ -668,7 +674,6 @@ SpdySession::SpdySession(
last_compressed_frame_len_(0),
check_ping_status_pending_(false),
send_connection_header_prefix_(false),
- flow_control_state_(FLOW_CONTROL_NONE),
session_send_window_size_(0),
session_max_recv_window_size_(session_max_recv_window_size),
session_recv_window_size_(0),
@@ -688,6 +693,7 @@ SpdySession::SpdySession(
hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
trusted_spdy_proxy_(trusted_spdy_proxy),
time_func_(time_func),
+ send_priority_dependency_(priority_dependency_enabled_default),
weak_factory_(this) {
DCHECK_GE(protocol_, kProtoSPDYMinimumVersion);
DCHECK_LE(protocol_, kProtoSPDYMaximumVersion);
@@ -697,6 +703,10 @@ SpdySession::SpdySession(
base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair()));
next_unclaimed_push_stream_sweep_time_ = time_func_() +
base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
+ if (base::FieldTrialList::FindFullName(kSpdyDependenciesFieldTrial) ==
+ kSpdyDepencenciesFieldTrialEnable) {
+ send_priority_dependency_ = true;
+ }
// TODO(mbelshe): consider randomization of the stream_hi_water_mark.
}
@@ -732,7 +742,7 @@ void SpdySession::InitializeWithSocket(
// requires re-working CreateFakeSpdySession(), though.
DCHECK(connection->socket());
- connection_ = connection.Pass();
+ connection_ = std::move(connection);
is_secure_ = is_secure;
certificate_error_code_ = certificate_error_code;
@@ -748,15 +758,8 @@ void SpdySession::InitializeWithSocket(
if (protocol_ == kProtoHTTP2)
send_connection_header_prefix_ = true;
- if (protocol_ >= kProtoSPDY31) {
- flow_control_state_ = FLOW_CONTROL_STREAM_AND_SESSION;
- session_send_window_size_ = GetDefaultInitialWindowSize(protocol_);
- session_recv_window_size_ = GetDefaultInitialWindowSize(protocol_);
- } else if (protocol_ >= kProtoSPDY3) {
- flow_control_state_ = FLOW_CONTROL_STREAM;
- } else {
- flow_control_state_ = FLOW_CONTROL_NONE;
- }
+ session_send_window_size_ = GetDefaultInitialWindowSize(protocol_);
+ session_recv_window_size_ = GetDefaultInitialWindowSize(protocol_);
buffered_spdy_framer_.reset(
new BufferedSpdyFramer(NextProtoToSpdyMajorVersion(protocol_),
@@ -907,7 +910,7 @@ int SpdySession::CreateStream(const SpdyStreamRequest& request,
request.priority(), stream_initial_send_window_size_,
stream_max_recv_window_size_, request.net_log()));
*stream = new_stream->GetWeakPtr();
- InsertCreatedStream(new_stream.Pass());
+ InsertCreatedStream(std::move(new_stream));
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Net.SpdyPriorityCount",
@@ -1020,7 +1023,7 @@ bool SpdySession::HasAcceptableTransportSecurity() const {
return false;
}
- if (!IsSecureTLSCipherSuite(
+ if (!IsTLSCipherSuiteAllowedByHTTP2(
SSLConnectionStatusToCipherSuite(ssl_info.connection_status))) {
return false;
}
@@ -1042,15 +1045,19 @@ bool SpdySession::CloseOneIdleConnection() {
return false;
}
+// static
+void SpdySession::SetPriorityDependencyDefaultForTesting(bool enable) {
+ priority_dependency_enabled_default = enable;
+}
+
void SpdySession::EnqueueStreamWrite(
const base::WeakPtr<SpdyStream>& stream,
SpdyFrameType frame_type,
scoped_ptr<SpdyBufferProducer> producer) {
DCHECK(frame_type == HEADERS ||
frame_type == DATA ||
- frame_type == CREDENTIAL ||
frame_type == SYN_STREAM);
- EnqueueWrite(stream->priority(), frame_type, producer.Pass(), stream);
+ EnqueueWrite(stream->priority(), frame_type, std::move(producer), stream);
}
scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
@@ -1082,6 +1089,41 @@ scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
SpdyHeadersIR headers(stream_id);
headers.set_priority(spdy_priority);
headers.set_has_priority(true);
+
+ if (send_priority_dependency_) {
+ // Set dependencies to reflect request priority. A newly created
+ // stream should be dependent on the most recent previously created
+ // stream of the same priority level. The newly created stream
+ // should also have all streams of a lower priority level dependent
+ // on it, which is guaranteed by setting the exclusive bit.
+ //
+ // Note that this depends on stream ids being allocated in a monotonically
+ // increasing fashion, and on all streams in
+ // active_streams_{,by_priority_} having stream ids set.
+ for (int i = priority; i >= IDLE; --i) {
+ if (active_streams_by_priority_[i].empty())
+ continue;
+
+ auto candidate_it = active_streams_by_priority_[i].rbegin();
+
+ // |active_streams_by_priority_| is updated before the
+ // SYN stream frame is created, so the current streams
+ // id is already on the list. Skip over it, skipping this
+ // priority level if it's singular.
+ if (candidate_it->second->stream_id() == stream_id)
+ ++candidate_it;
+ if (candidate_it == active_streams_by_priority_[i].rend())
+ continue;
+
+ headers.set_parent_stream_id(candidate_it->second->stream_id());
+ break;
+ }
+
+ // If there are no streams of priority <= the current stream, the
+ // current stream will default to a child of the idle node (0).
+ headers.set_exclusive(true);
+ }
+
headers.set_fin((flags & CONTROL_FLAG_FIN) != 0);
headers.set_header_block(block);
syn_frame.reset(buffered_spdy_framer_->SerializeFrame(headers));
@@ -1101,7 +1143,7 @@ scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
spdy_priority, stream_id));
}
- return syn_frame.Pass();
+ return syn_frame;
}
scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
@@ -1124,9 +1166,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
int effective_len = std::min(len, kMaxSpdyFrameChunkSize);
- bool send_stalled_by_stream =
- (flow_control_state_ >= FLOW_CONTROL_STREAM) &&
- (stream->send_window_size() <= 0);
+ bool send_stalled_by_stream = (stream->send_window_size() <= 0);
bool send_stalled_by_session = IsSendStalled();
// NOTE: There's an enum of the same name in histograms.xml.
@@ -1148,50 +1188,36 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
frame_flow_control_state = SEND_STALLED_BY_SESSION;
}
- if (flow_control_state_ == FLOW_CONTROL_STREAM) {
- UMA_HISTOGRAM_ENUMERATION(
- "Net.SpdyFrameStreamFlowControlState",
- frame_flow_control_state,
- SEND_STALLED_BY_STREAM + 1);
- } else if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
- UMA_HISTOGRAM_ENUMERATION(
- "Net.SpdyFrameStreamAndSessionFlowControlState",
- frame_flow_control_state,
- SEND_STALLED_BY_STREAM_AND_SESSION + 1);
- }
-
- // Obey send window size of the stream if stream flow control is
- // enabled.
- if (flow_control_state_ >= FLOW_CONTROL_STREAM) {
- if (send_stalled_by_stream) {
- stream->set_send_stalled_by_flow_control(true);
- // Even though we're currently stalled only by the stream, we
- // might end up being stalled by the session also.
- QueueSendStalledStream(*stream);
- net_log().AddEvent(
- NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW,
- NetLog::IntegerCallback("stream_id", stream_id));
- return scoped_ptr<SpdyBuffer>();
- }
+ UMA_HISTOGRAM_ENUMERATION("Net.SpdyFrameStreamAndSessionFlowControlState",
+ frame_flow_control_state,
+ SEND_STALLED_BY_STREAM_AND_SESSION + 1);
- effective_len = std::min(effective_len, stream->send_window_size());
+ // Obey send window size of the stream.
+ if (send_stalled_by_stream) {
+ stream->set_send_stalled_by_flow_control(true);
+ // Even though we're currently stalled only by the stream, we
+ // might end up being stalled by the session also.
+ QueueSendStalledStream(*stream);
+ net_log().AddEvent(
+ NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW,
+ NetLog::IntCallback("stream_id", stream_id));
+ return scoped_ptr<SpdyBuffer>();
}
- // Obey send window size of the session if session flow control is
- // enabled.
- if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
- if (send_stalled_by_session) {
- stream->set_send_stalled_by_flow_control(true);
- QueueSendStalledStream(*stream);
- net_log().AddEvent(
- NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW,
- NetLog::IntegerCallback("stream_id", stream_id));
- return scoped_ptr<SpdyBuffer>();
- }
+ effective_len = std::min(effective_len, stream->send_window_size());
- effective_len = std::min(effective_len, session_send_window_size_);
+ // Obey send window size of the session.
+ if (send_stalled_by_session) {
+ stream->set_send_stalled_by_flow_control(true);
+ QueueSendStalledStream(*stream);
+ net_log().AddEvent(
+ NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW,
+ NetLog::IntCallback("stream_id", stream_id));
+ return scoped_ptr<SpdyBuffer>();
}
+ effective_len = std::min(effective_len, session_send_window_size_);
+
DCHECK_GE(effective_len, 0);
// Clear FIN flag if only some of the data will be in the data
@@ -1211,25 +1237,22 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
// TODO(mbelshe): reduce memory copies here.
DCHECK(buffered_spdy_framer_.get());
- scoped_ptr<SpdyFrame> frame(
- buffered_spdy_framer_->CreateDataFrame(
- stream_id, data->data(),
- static_cast<uint32>(effective_len), flags));
+ scoped_ptr<SpdyFrame> frame(buffered_spdy_framer_->CreateDataFrame(
+ stream_id, data->data(), static_cast<uint32_t>(effective_len), flags));
- scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass()));
+ scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(std::move(frame)));
// Send window size is based on payload size, so nothing to do if this is
// just a FIN with no payload.
- if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION &&
- effective_len != 0) {
- DecreaseSendWindowSize(static_cast<int32>(effective_len));
+ if (effective_len != 0) {
+ DecreaseSendWindowSize(static_cast<int32_t>(effective_len));
data_buffer->AddConsumeCallback(
base::Bind(&SpdySession::OnWriteBufferConsumed,
weak_factory_.GetWeakPtr(),
static_cast<size_t>(effective_len)));
}
- return data_buffer.Pass();
+ return data_buffer;
}
void SpdySession::CloseActiveStream(SpdyStreamId stream_id, int status) {
@@ -1288,6 +1311,8 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it,
scoped_ptr<SpdyStream> owned_stream(it->second.stream);
active_streams_.erase(it);
+ active_streams_by_priority_[owned_stream->priority()].erase(
+ owned_stream->stream_id());
// TODO(akalin): When SpdyStream was ref-counted (and
// |unclaimed_pushed_streams_| held scoped_refptr<SpdyStream>), this
@@ -1303,12 +1328,12 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it,
num_active_pushed_streams_--;
}
- DeleteStream(owned_stream.Pass(), status);
- MaybeFinishGoingAway();
+ DeleteStream(std::move(owned_stream), status);
// If there are no active streams and the socket pool is stalled, close the
// session to free up a socket slot.
- if (active_streams_.empty() && connection_->IsPoolStalled()) {
+ if (active_streams_.empty() && created_streams_.empty() &&
+ connection_->IsPoolStalled()) {
DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
}
}
@@ -1317,7 +1342,7 @@ void SpdySession::CloseCreatedStreamIterator(CreatedStreamSet::iterator it,
int status) {
scoped_ptr<SpdyStream> owned_stream(*it);
created_streams_.erase(it);
- DeleteStream(owned_stream.Pass(), status);
+ DeleteStream(std::move(owned_stream), status);
}
void SpdySession::ResetStreamIterator(ActiveStreamMap::iterator it,
@@ -1348,7 +1373,7 @@ void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id,
scoped_ptr<SpdyFrame> rst_frame(
buffered_spdy_framer_->CreateRstStream(stream_id, status));
- EnqueueSessionWrite(priority, RST_STREAM, rst_frame.Pass());
+ EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame));
RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status));
}
@@ -1457,7 +1482,8 @@ int SpdySession::DoReadComplete(int result) {
DCHECK(buffered_spdy_framer_.get());
char* data = read_buffer_->data();
while (result > 0) {
- uint32 bytes_processed = buffered_spdy_framer_->ProcessInput(data, result);
+ uint32_t bytes_processed =
+ buffered_spdy_framer_->ProcessInput(data, result);
result -= bytes_processed;
data += bytes_processed;
@@ -1549,7 +1575,7 @@ int SpdySession::DoWrite() {
CHECK_EQ(stream->stream_id(), 0u);
scoped_ptr<SpdyStream> owned_stream =
ActivateCreatedStream(stream.get());
- InsertActivatedStream(owned_stream.Pass());
+ InsertActivatedStream(std::move(owned_stream));
if (stream_hi_water_mark_ > kLastStreamId) {
CHECK_EQ(stream->stream_id(), kLastStreamId);
@@ -1705,10 +1731,12 @@ void SpdySession::StartGoingAway(SpdyStreamId last_good_stream_id,
write_queue_.RemovePendingWritesForStreamsAfter(last_good_stream_id);
DcheckGoingAway();
+ MaybeFinishGoingAway();
}
void SpdySession::MaybeFinishGoingAway() {
- if (active_streams_.empty() && availability_state_ == STATE_GOING_AWAY) {
+ if (active_streams_.empty() && created_streams_.empty() &&
+ availability_state_ == STATE_GOING_AWAY) {
DoDrainSession(OK, "Finished going away");
}
}
@@ -1819,7 +1847,7 @@ scoped_ptr<base::Value> SpdySession::GetInfoAsValue() const {
for (const auto& alias : pooled_aliases_) {
alias_list->AppendString(alias.host_port_pair().ToString());
}
- dict->Set("aliases", alias_list.Pass());
+ dict->Set("aliases", std::move(alias_list));
}
dict->SetString("proxy", host_port_proxy_pair().second.ToURI());
@@ -1852,7 +1880,7 @@ scoped_ptr<base::Value> SpdySession::GetInfoAsValue() const {
dict->SetInteger("recv_window_size", session_recv_window_size_);
dict->SetInteger("unacked_recv_window_bytes",
session_unacked_recv_window_bytes_);
- return dict.Pass();
+ return std::move(dict);
}
bool SpdySession::IsReused() const {
@@ -1896,12 +1924,10 @@ void SpdySession::EnqueueSessionWrite(RequestPriority priority,
DCHECK(frame_type == RST_STREAM || frame_type == SETTINGS ||
frame_type == WINDOW_UPDATE || frame_type == PING ||
frame_type == GOAWAY);
- EnqueueWrite(
- priority, frame_type,
- scoped_ptr<SpdyBufferProducer>(
- new SimpleBufferProducer(
- scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass())))),
- base::WeakPtr<SpdyStream>());
+ EnqueueWrite(priority, frame_type,
+ scoped_ptr<SpdyBufferProducer>(new SimpleBufferProducer(
+ scoped_ptr<SpdyBuffer>(new SpdyBuffer(std::move(frame))))),
+ base::WeakPtr<SpdyStream>());
}
void SpdySession::EnqueueWrite(RequestPriority priority,
@@ -1911,7 +1937,7 @@ void SpdySession::EnqueueWrite(RequestPriority priority,
if (availability_state_ == STATE_DRAINING)
return;
- write_queue_.Enqueue(priority, frame_type, producer.Pass(), stream);
+ write_queue_.Enqueue(priority, frame_type, std::move(producer), stream);
MaybePostWriteLoop();
}
@@ -1938,7 +1964,7 @@ scoped_ptr<SpdyStream> SpdySession::ActivateCreatedStream(SpdyStream* stream) {
stream->set_stream_id(GetNewStreamId());
scoped_ptr<SpdyStream> owned_stream(stream);
created_streams_.erase(stream);
- return owned_stream.Pass();
+ return owned_stream;
}
void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) {
@@ -1947,6 +1973,8 @@ void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) {
std::pair<ActiveStreamMap::iterator, bool> result =
active_streams_.insert(
std::make_pair(stream_id, ActiveStreamInfo(stream.get())));
+ active_streams_by_priority_[stream->priority()].insert(
+ std::make_pair(stream_id, stream.get()));
CHECK(result.second);
ignore_result(stream.release());
}
@@ -2065,12 +2093,9 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
CHECK_LE(len, static_cast<size_t>(kReadBufferSize));
buffer.reset(new SpdyBuffer(data, len));
- if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
- DecreaseRecvWindowSize(static_cast<int32>(len));
- buffer->AddConsumeCallback(
- base::Bind(&SpdySession::OnReadBufferConsumed,
- weak_factory_.GetWeakPtr()));
- }
+ DecreaseRecvWindowSize(static_cast<int32_t>(len));
+ buffer->AddConsumeCallback(base::Bind(&SpdySession::OnReadBufferConsumed,
+ weak_factory_.GetWeakPtr()));
} else {
DCHECK_EQ(len, 0u);
}
@@ -2093,21 +2118,18 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
return;
}
- stream->OnDataReceived(buffer.Pass());
+ stream->OnDataReceived(std::move(buffer));
}
void SpdySession::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
CHECK(in_io_loop_);
- if (flow_control_state_ != FLOW_CONTROL_STREAM_AND_SESSION)
- return;
-
// Decrease window size because padding bytes are received.
// Increase window size because padding bytes are consumed (by discarding).
// Net result: |session_unacked_recv_window_bytes_| increases by |len|,
// |session_recv_window_size_| does not change.
- DecreaseRecvWindowSize(static_cast<int32>(len));
- IncreaseRecvWindowSize(static_cast<int32>(len));
+ DecreaseRecvWindowSize(static_cast<int32_t>(len));
+ IncreaseRecvWindowSize(static_cast<int32_t>(len));
ActiveStreamMap::iterator it = active_streams_.find(stream_id);
if (it == active_streams_.end())
@@ -2115,6 +2137,16 @@ void SpdySession::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
it->second.stream->OnPaddingConsumed(len);
}
+SpdyHeadersHandlerInterface* SpdySession::OnHeaderFrameStart(
+ SpdyStreamId stream_id) {
+ LOG(FATAL);
+ return nullptr;
+}
+
+void SpdySession::OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) {
+ LOG(FATAL);
+}
+
void SpdySession::OnSettings(bool clear_persisted) {
CHECK(in_io_loop_);
@@ -2139,9 +2171,7 @@ void SpdySession::OnSettings(bool clear_persisted) {
}
}
-void SpdySession::OnSetting(SpdySettingsIds id,
- uint8 flags,
- uint32 value) {
+void SpdySession::OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) {
CHECK(in_io_loop_);
HandleSetting(id, value);
@@ -2452,15 +2482,17 @@ void SpdySession::OnRstStream(SpdyStreamId stream_id,
}
void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) {
+ SpdyGoAwayStatus status,
+ StringPiece debug_data) {
CHECK(in_io_loop_);
// TODO(jgraettinger): UMA histogram on |status|.
- net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_GOAWAY,
- base::Bind(&NetLogSpdyGoAwayCallback,
- last_accepted_stream_id, active_streams_.size(),
- unclaimed_pushed_streams_.size(), status));
+ net_log_.AddEvent(
+ NetLog::TYPE_HTTP2_SESSION_GOAWAY,
+ base::Bind(&NetLogSpdyGoAwayCallback, last_accepted_stream_id,
+ active_streams_.size(), unclaimed_pushed_streams_.size(),
+ status, debug_data));
MakeUnavailable();
if (status == GOAWAY_HTTP_1_1_REQUIRED) {
// TODO(bnc): Record histogram with number of open streams capped at 50.
@@ -2515,13 +2547,6 @@ void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
if (stream_id == kSessionFlowControlStreamId) {
// WINDOW_UPDATE for the session.
- if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) {
- LOG(WARNING) << "Received WINDOW_UPDATE for session when "
- << "session flow control is not turned on";
- // TODO(akalin): Record an error and close the session.
- return;
- }
-
if (delta_window_size < 1) {
RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
DoDrainSession(
@@ -2534,13 +2559,6 @@ void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
IncreaseSendWindowSize(delta_window_size);
} else {
// WINDOW_UPDATE for a stream.
- if (flow_control_state_ < FLOW_CONTROL_STREAM) {
- // TODO(akalin): Record an error and close the session.
- LOG(WARNING) << "Received WINDOW_UPDATE for stream " << stream_id
- << " when flow control is not turned on";
- return;
- }
-
ActiveStreamMap::iterator it = active_streams_.find(stream_id);
if (it == active_streams_.end()) {
@@ -2573,20 +2591,17 @@ bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
// Server-initiated streams should have even sequence numbers.
if ((stream_id & 0x1) != 0) {
LOG(WARNING) << "Received invalid push stream id " << stream_id;
- if (GetProtocolVersion() > SPDY2)
- CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Odd push stream id.");
+ CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Odd push stream id.");
return false;
}
- if (GetProtocolVersion() > SPDY2) {
- if (stream_id <= last_accepted_push_stream_id_) {
- LOG(WARNING) << "Received push stream id lesser or equal to the last "
- << "accepted before " << stream_id;
- CloseSessionOnError(
- ERR_SPDY_PROTOCOL_ERROR,
- "New push stream id must be greater than the last accepted.");
- return false;
- }
+ if (stream_id <= last_accepted_push_stream_id_) {
+ LOG(WARNING) << "Received push stream id lesser or equal to the last "
+ << "accepted before " << stream_id;
+ CloseSessionOnError(
+ ERR_SPDY_PROTOCOL_ERROR,
+ "New push stream id must be greater than the last accepted.");
+ return false;
}
if (IsStreamActive(stream_id)) {
@@ -2664,6 +2679,7 @@ bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
RST_STREAM_REFUSED_STREAM,
base::StringPrintf("Rejected push of Cross Origin HTTPS content %d",
associated_stream_id));
+ return false;
}
} else {
GURL associated_url(associated_it->second.stream->GetUrlFromHeaders());
@@ -2714,7 +2730,7 @@ bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
DCHECK(inserted_pushed_it != pushed_it);
DeleteExpiredPushedStreams();
- InsertActivatedStream(stream.Pass());
+ InsertActivatedStream(std::move(stream));
ActiveStreamMap::iterator active_it = active_streams_.find(stream_id);
if (active_it == active_streams_.end()) {
@@ -2746,8 +2762,7 @@ void SpdySession::OnPushPromise(SpdyStreamId stream_id,
}
void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id,
- uint32 delta_window_size) {
- CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM);
+ uint32_t delta_window_size) {
ActiveStreamMap::const_iterator it = active_streams_.find(stream_id);
CHECK(it != active_streams_.end());
CHECK_EQ(it->second.stream->stream_id(), stream_id);
@@ -2766,7 +2781,7 @@ void SpdySession::SendInitialData() {
false /* take_ownership */));
// Count the prefix as part of the subsequent SETTINGS frame.
EnqueueSessionWrite(HIGHEST, SETTINGS,
- connection_header_prefix_frame.Pass());
+ std::move(connection_header_prefix_frame));
}
// First, notify the server about the settings they should use when
@@ -2776,29 +2791,26 @@ void SpdySession::SendInitialData() {
// max concurrent streams and initial window size.
settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
- if (flow_control_state_ >= FLOW_CONTROL_STREAM &&
- stream_max_recv_window_size_ != GetDefaultInitialWindowSize(protocol_)) {
+ if (stream_max_recv_window_size_ != GetDefaultInitialWindowSize(protocol_)) {
settings_map[SETTINGS_INITIAL_WINDOW_SIZE] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, stream_max_recv_window_size_);
}
SendSettings(settings_map);
// Next, notify the server about our initial recv window size.
- if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
- // Bump up the receive window size to the real initial value. This
- // has to go here since the WINDOW_UPDATE frame sent by
- // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|.
- // This condition implies that |session_max_recv_window_size_| -
- // |session_recv_window_size_| doesn't overflow.
- DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_);
- DCHECK_GE(session_recv_window_size_, 0);
- if (session_max_recv_window_size_ > session_recv_window_size_) {
- IncreaseRecvWindowSize(session_max_recv_window_size_ -
- session_recv_window_size_);
- }
- }
-
- if (protocol_ <= kProtoSPDY31) {
+ // Bump up the receive window size to the real initial value. This
+ // has to go here since the WINDOW_UPDATE frame sent by
+ // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|.
+ // This condition implies that |session_max_recv_window_size_| -
+ // |session_recv_window_size_| doesn't overflow.
+ DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_);
+ DCHECK_GE(session_recv_window_size_, 0);
+ if (session_max_recv_window_size_ > session_recv_window_size_) {
+ IncreaseRecvWindowSize(session_max_recv_window_size_ -
+ session_recv_window_size_);
+ }
+
+ if (protocol_ == kProtoSPDY31) {
// Finally, notify the server about the settings they have
// previously told us to use when communicating with them (after
// applying them).
@@ -2809,13 +2821,13 @@ void SpdySession::SendInitialData() {
SettingsMap::const_iterator it =
server_settings_map.find(SETTINGS_CURRENT_CWND);
- uint32 cwnd = (it != server_settings_map.end()) ? it->second.second : 0;
+ uint32_t cwnd = (it != server_settings_map.end()) ? it->second.second : 0;
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100);
for (SettingsMap::const_iterator it = server_settings_map.begin();
it != server_settings_map.end(); ++it) {
const SpdySettingsIds new_id = it->first;
- const uint32 new_val = it->second.second;
+ const uint32_t new_val = it->second.second;
HandleSetting(new_id, new_val);
}
@@ -2834,10 +2846,10 @@ void SpdySession::SendSettings(const SettingsMap& settings) {
scoped_ptr<SpdyFrame> settings_frame(
buffered_spdy_framer_->CreateSettings(settings));
sent_settings_ = true;
- EnqueueSessionWrite(HIGHEST, SETTINGS, settings_frame.Pass());
+ EnqueueSessionWrite(HIGHEST, SETTINGS, std::move(settings_frame));
}
-void SpdySession::HandleSetting(uint32 id, uint32 value) {
+void SpdySession::HandleSetting(uint32_t id, uint32_t value) {
switch (id) {
case SETTINGS_MAX_CONCURRENT_STREAMS:
max_concurrent_streams_ = std::min(static_cast<size_t>(value),
@@ -2845,34 +2857,27 @@ void SpdySession::HandleSetting(uint32 id, uint32 value) {
ProcessPendingStreamRequests();
break;
case SETTINGS_INITIAL_WINDOW_SIZE: {
- if (flow_control_state_ < FLOW_CONTROL_STREAM) {
- net_log().AddEvent(
- NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL);
- return;
- }
-
- if (value > static_cast<uint32>(kint32max)) {
+ if (value > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
net_log().AddEvent(
NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE,
- NetLog::IntegerCallback("initial_window_size", value));
+ NetLog::IntCallback("initial_window_size", value));
return;
}
// SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only.
- int32 delta_window_size =
- static_cast<int32>(value) - stream_initial_send_window_size_;
- stream_initial_send_window_size_ = static_cast<int32>(value);
+ int32_t delta_window_size =
+ static_cast<int32_t>(value) - stream_initial_send_window_size_;
+ stream_initial_send_window_size_ = static_cast<int32_t>(value);
UpdateStreamsSendWindowSize(delta_window_size);
net_log().AddEvent(
NetLog::TYPE_HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE,
- NetLog::IntegerCallback("delta_window_size", delta_window_size));
+ NetLog::IntCallback("delta_window_size", delta_window_size));
break;
}
}
}
-void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) {
- DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM);
+void SpdySession::UpdateStreamsSendWindowSize(int32_t delta_window_size) {
for (ActiveStreamMap::iterator it = active_streams_.begin();
it != active_streams_.end(); ++it) {
it->second.stream->AdjustSendWindowSize(delta_window_size);
@@ -2899,14 +2904,12 @@ void SpdySession::SendPrefacePing() {
}
void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id,
- uint32 delta_window_size,
+ uint32_t delta_window_size,
RequestPriority priority) {
- CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM);
ActiveStreamMap::const_iterator it = active_streams_.find(stream_id);
if (it != active_streams_.end()) {
CHECK_EQ(it->second.stream->stream_id(), stream_id);
} else {
- CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
CHECK_EQ(stream_id, kSessionFlowControlStreamId);
}
@@ -2917,14 +2920,14 @@ void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id,
DCHECK(buffered_spdy_framer_.get());
scoped_ptr<SpdyFrame> window_update_frame(
buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size));
- EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass());
+ EnqueueSessionWrite(priority, WINDOW_UPDATE, std::move(window_update_frame));
}
void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) {
DCHECK(buffered_spdy_framer_.get());
scoped_ptr<SpdyFrame> ping_frame(
buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack));
- EnqueueSessionWrite(HIGHEST, PING, ping_frame.Pass());
+ EnqueueSessionWrite(HIGHEST, PING, std::move(ping_frame));
if (net_log().IsCapturing()) {
net_log().AddEvent(
@@ -3024,7 +3027,7 @@ void SpdySession::RecordHistograms() {
SettingsMap::const_iterator it;
for (it = settings_map.begin(); it != settings_map.end(); ++it) {
const SpdySettingsIds id = it->first;
- const uint32 val = it->second.second;
+ const uint32_t val = it->second.second;
switch (id) {
case SETTINGS_CURRENT_CWND:
// Record several different histograms to see if cwnd converges
@@ -3090,9 +3093,6 @@ void SpdySession::OnWriteBufferConsumed(
SpdyBuffer::ConsumeSource consume_source) {
// We can be called with |in_io_loop_| set if a write SpdyBuffer is
// deleted (e.g., a stream is closed due to incoming data).
-
- DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
-
if (consume_source == SpdyBuffer::DISCARD) {
// If we're discarding a frame or part of it, increase the send
// window by the number of discarded bytes. (Although if we're
@@ -3109,12 +3109,11 @@ void SpdySession::OnWriteBufferConsumed(
void SpdySession::IncreaseSendWindowSize(int delta_window_size) {
// We can be called with |in_io_loop_| set if a SpdyBuffer is
// deleted (e.g., a stream is closed due to incoming data).
-
- DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
DCHECK_GE(delta_window_size, 1);
// Check for overflow.
- int32 max_delta_window_size = kint32max - session_send_window_size_;
+ int32_t max_delta_window_size =
+ std::numeric_limits<int32_t>::max() - session_send_window_size_;
if (delta_window_size > max_delta_window_size) {
RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
DoDrainSession(
@@ -3136,9 +3135,7 @@ void SpdySession::IncreaseSendWindowSize(int delta_window_size) {
ResumeSendStalledStreams();
}
-void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) {
- DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
-
+void SpdySession::DecreaseSendWindowSize(int32_t delta_window_size) {
// We only call this method when sending a frame. Therefore,
// |delta_window_size| should be within the valid frame size range.
DCHECK_GE(delta_window_size, 1);
@@ -3160,21 +3157,20 @@ void SpdySession::OnReadBufferConsumed(
SpdyBuffer::ConsumeSource consume_source) {
// We can be called with |in_io_loop_| set if a read SpdyBuffer is
// deleted (e.g., discarded by a SpdyReadQueue).
-
- DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
DCHECK_GE(consume_size, 1u);
- DCHECK_LE(consume_size, static_cast<size_t>(kint32max));
+ DCHECK_LE(consume_size,
+ static_cast<size_t>(std::numeric_limits<int32_t>::max()));
- IncreaseRecvWindowSize(static_cast<int32>(consume_size));
+ IncreaseRecvWindowSize(static_cast<int32_t>(consume_size));
}
-void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) {
- DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
+void SpdySession::IncreaseRecvWindowSize(int32_t delta_window_size) {
DCHECK_GE(session_unacked_recv_window_bytes_, 0);
DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_);
DCHECK_GE(delta_window_size, 1);
// Check for overflow.
- DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_);
+ DCHECK_LE(delta_window_size,
+ std::numeric_limits<int32_t>::max() - session_recv_window_size_);
session_recv_window_size_ += delta_window_size;
net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW,
@@ -3190,9 +3186,8 @@ void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) {
}
}
-void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) {
+void SpdySession::DecreaseRecvWindowSize(int32_t delta_window_size) {
CHECK(in_io_loop_);
- DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
DCHECK_GE(delta_window_size, 1);
// The receiving window size as the peer knows it is
@@ -3225,8 +3220,6 @@ void SpdySession::QueueSendStalledStream(const SpdyStream& stream) {
}
void SpdySession::ResumeSendStalledStreams() {
- DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
-
// We don't have to worry about new streams being queued, since
// doing so would cause IsSendStalled() to return true. But we do
// have to worry about streams being closed, as well as ourselves
diff --git a/chromium/net/spdy/spdy_session.h b/chromium/net/spdy/spdy_session.h
index f6475bc08fb..5d72161b592 100644
--- a/chromium/net/spdy/spdy_session.h
+++ b/chromium/net/spdy/spdy_session.h
@@ -5,13 +5,16 @@
#ifndef NET_SPDY_SPDY_SESSION_H_
#define NET_SPDY_SPDY_SESSION_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <deque>
#include <map>
#include <set>
#include <string>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -39,6 +42,10 @@
namespace net {
+namespace test {
+class SpdyStreamTest;
+}
+
// This is somewhat arbitrary and not really fixed, but it will always work
// reasonably with ethernet. Chop the world into 2-packet chunks. This is
// somewhat arbitrary, but is reasonably small and ensures that we elicit
@@ -81,7 +88,6 @@ enum SpdyProtocolErrorDetails {
SPDY_ERROR_UNSUPPORTED_VERSION = 4,
SPDY_ERROR_DECOMPRESS_FAILURE = 5,
SPDY_ERROR_COMPRESS_FAILURE = 6,
- // SPDY_ERROR_CREDENTIAL_FRAME_CORRUPT = 7, (removed).
SPDY_ERROR_GOAWAY_FRAME_CORRUPT = 29,
SPDY_ERROR_RST_STREAM_FRAME_CORRUPT = 30,
SPDY_ERROR_INVALID_DATA_FRAME_FLAGS = 8,
@@ -98,7 +104,6 @@ enum SpdyProtocolErrorDetails {
STATUS_CODE_FLOW_CONTROL_ERROR = 17,
STATUS_CODE_STREAM_IN_USE = 18,
STATUS_CODE_STREAM_ALREADY_CLOSED = 19,
- STATUS_CODE_INVALID_CREDENTIALS = 20,
STATUS_CODE_FRAME_SIZE_ERROR = 21,
STATUS_CODE_SETTINGS_TIMEOUT = 32,
STATUS_CODE_CONNECT_ERROR = 33,
@@ -216,13 +221,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// TODO(akalin): Use base::TickClock when it becomes available.
typedef base::TimeTicks (*TimeFunc)(void);
- // How we handle flow control (version-dependent).
- enum FlowControlState {
- FLOW_CONTROL_NONE,
- FLOW_CONTROL_STREAM,
- FLOW_CONTROL_STREAM_AND_SESSION
- };
-
// Returns true if |hostname| can be pooled into an existing connection
// associated with |ssl_info|.
static bool CanPool(TransportSecurityState* transport_security_state,
@@ -362,7 +360,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// Send a WINDOW_UPDATE frame for a stream. Called by a stream
// whenever receive window size is increased.
void SendStreamWindowUpdate(SpdyStreamId stream_id,
- uint32 delta_window_size);
+ uint32_t delta_window_size);
// Accessors for the session's availability state.
bool IsAvailable() const { return availability_state_ == STATE_AVAILABLE; }
@@ -447,23 +445,14 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
return pending_create_stream_queues_[priority].size();
}
- // Returns the (version-dependent) flow control state.
- FlowControlState flow_control_state() const {
- return flow_control_state_;
- }
-
// Returns the current |stream_initial_send_window_size_|.
- int32 stream_initial_send_window_size() const {
+ int32_t stream_initial_send_window_size() const {
return stream_initial_send_window_size_;
}
// Returns true if no stream in the session can send data due to
// session flow control.
- bool IsSendStalled() const {
- return
- flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION &&
- session_send_window_size_ == 0;
- }
+ bool IsSendStalled() const { return session_send_window_size_ == 0; }
const BoundNetLog& net_log() const { return net_log_; }
@@ -502,7 +491,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// Default value of SETTINGS_INITIAL_WINDOW_SIZE per protocol specification.
// A session is always created with this initial window size.
- static int32 GetDefaultInitialWindowSize(NextProto protocol) {
+ static int32_t GetDefaultInitialWindowSize(NextProto protocol) {
return protocol < kProtoHTTP2 ? 65536 : 65535;
}
@@ -517,9 +506,15 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
bool CloseOneIdleConnection() override;
private:
+ friend class test::SpdyStreamTest;
friend class base::RefCounted<SpdySession>;
- friend class SpdyStreamRequest;
+ friend class HttpNetworkTransactionTest;
+ friend class HttpProxyClientSocketPoolTest;
+ friend class SpdyHttpStreamTest;
+ friend class SpdyNetworkTransactionTest;
+ friend class SpdyProxyClientSocketTest;
friend class SpdySessionTest;
+ friend class SpdyStreamRequest;
// Allow tests to access our innards for testing purposes.
FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, ClientPing);
@@ -548,6 +543,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
FRIEND_TEST_ALL_PREFIXES(SpdySessionTest,
CancelReservedStreamOnHeadersReceived);
FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, RejectInvalidUnknownFrames);
+ FRIEND_TEST_ALL_PREFIXES(SpdySessionPoolTest, IPAddressChanged);
typedef std::deque<base::WeakPtr<SpdyStreamRequest> >
PendingStreamRequestQueue;
@@ -709,10 +705,10 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// Handle SETTING. Either when we send settings, or when we receive a
// SETTINGS control frame, update our SpdySession accordingly.
- void HandleSetting(uint32 id, uint32 value);
+ void HandleSetting(uint32_t id, uint32_t value);
// Adjust the send window size of all ActiveStreams and PendingStreamRequests.
- void UpdateStreamsSendWindowSize(int32 delta_window_size);
+ void UpdateStreamsSendWindowSize(int32_t delta_window_size);
// Send the PING (preface-PING) frame.
void SendPrefacePingIfNoneInFlight();
@@ -721,7 +717,8 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
void SendPrefacePing();
// Send a single WINDOW_UPDATE frame.
- void SendWindowUpdateFrame(SpdyStreamId stream_id, uint32 delta_window_size,
+ void SendWindowUpdateFrame(SpdyStreamId stream_id,
+ uint32_t delta_window_size,
RequestPriority priority);
// Send the PING frame.
@@ -821,7 +818,8 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
void OnPing(SpdyPingId unique_id, bool is_ack) override;
void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override;
void OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) override;
+ SpdyGoAwayStatus status,
+ base::StringPiece debug_data) override;
void OnDataFrameHeader(SpdyStreamId stream_id,
size_t length,
bool fin) override;
@@ -830,8 +828,11 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
size_t len,
bool fin) override;
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override;
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override;
void OnSettings(bool clear_persisted) override;
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override;
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override;
void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
void OnPushPromise(SpdyStreamId stream_id,
SpdyStreamId promised_stream_id,
@@ -889,7 +890,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// cause this session's send window size to go negative.
//
// If session flow control is turned off, this must not be called.
- void DecreaseSendWindowSize(int32 delta_window_size);
+ void DecreaseSendWindowSize(int32_t delta_window_size);
// Called when bytes are consumed by the delegate from a SpdyBuffer
// containing received data. Increases the receive window size
@@ -906,7 +907,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// initialization to set the initial receive window size.
//
// If session flow control is turned off, this must not be called.
- void IncreaseRecvWindowSize(int32 delta_window_size);
+ void IncreaseRecvWindowSize(int32_t delta_window_size);
// Called by OnStreamFrameData (which is in turn called by the
// framer) to decrease this session's receive window size by
@@ -914,7 +915,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// this session's receive window size to go negative.
//
// If session flow control is turned off, this must not be called.
- void DecreaseRecvWindowSize(int32 delta_window_size);
+ void DecreaseRecvWindowSize(int32_t delta_window_size);
// Queue a send-stalled stream for possibly resuming once we're not
// send-stalled anymore.
@@ -944,7 +945,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
max_concurrent_pushed_streams_ = value;
}
- int64 pings_in_flight() const { return pings_in_flight_; }
+ int64_t pings_in_flight() const { return pings_in_flight_; }
SpdyPingId next_ping_id() const { return next_ping_id_; }
@@ -954,6 +955,10 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
size_t max_concurrent_streams() const { return max_concurrent_streams_; }
+ // Set whether priority->dependency conversion is enabled
+ // by default for all future SpdySessions.
+ static void SetPriorityDependencyDefaultForTesting(bool enable);
+
// Whether Do{Read,Write}Loop() is in the call stack. Useful for
// making sure we don't destroy ourselves prematurely in that case.
bool in_io_loop_;
@@ -1000,6 +1005,14 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// them?
ActiveStreamMap active_streams_;
+ // Per-priority map from stream id to all active streams. This map will
+ // contain the same set of streams as |active_streams_|. It is used for
+ // setting dependencies to match incoming requests RequestPriority.
+ //
+ // |active_streams_by_priority_| does *not* own its SpdyStream objects.
+ std::map<SpdyStreamId, SpdyStream*>
+ active_streams_by_priority_[NUM_PRIORITIES];
+
// (Bijective) map from the URL to the ID of the streams that have
// already started to be pushed by the server, but do not have
// consumers yet. Contains a subset of |active_streams_|.
@@ -1075,7 +1088,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
int stalled_streams_; // Count of streams that were ever stalled.
// Count of all pings on the wire, for which we have not gotten a response.
- int64 pings_in_flight_;
+ int64_t pings_in_flight_;
// This is the next ping_id (unique_id) to be sent in PING frame.
SpdyPingId next_ping_id_;
@@ -1100,39 +1113,36 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// Whether to send the (HTTP/2) connection header prefix.
bool send_connection_header_prefix_;
- // The (version-dependent) flow control state.
- FlowControlState flow_control_state_;
-
// Current send window size. Zero unless session flow control is turned on.
- int32 session_send_window_size_;
+ int32_t session_send_window_size_;
// Maximum receive window size. Each time a WINDOW_UPDATE is sent, it
// restores the receive window size to this value. Zero unless session flow
// control is turned on.
- int32 session_max_recv_window_size_;
+ int32_t session_max_recv_window_size_;
// Sum of |session_unacked_recv_window_bytes_| and current receive window
// size. Zero unless session flow control is turned on.
// TODO(bnc): Rename or change semantics so that |window_size_| is actual
// window size.
- int32 session_recv_window_size_;
+ int32_t session_recv_window_size_;
// When bytes are consumed, SpdyIOBuffer destructor calls back to SpdySession,
// and this member keeps count of them until the corresponding WINDOW_UPDATEs
// are sent. Zero unless session flow control is turned on.
- int32 session_unacked_recv_window_bytes_;
+ int32_t session_unacked_recv_window_bytes_;
// Initial send window size for this session's streams. Can be
// changed by an arriving SETTINGS frame. Newly created streams use
// this value for the initial send window size.
- int32 stream_initial_send_window_size_;
+ int32_t stream_initial_send_window_size_;
// Initial receive window size for this session's streams. There are
// plans to add a command line switch that would cause a SETTINGS
// frame with window size announcement to be sent on startup. Newly
// created streams will use this value for the initial receive
// window size.
- int32 stream_max_recv_window_size_;
+ int32_t stream_max_recv_window_size_;
// A queue of stream IDs that have been send-stalled at some point
// in the past.
@@ -1178,6 +1188,10 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
TimeFunc time_func_;
+ // Should priority-based dependency information be sent in stream header
+ // frames.
+ bool send_priority_dependency_;
+
// Used for posting asynchronous IO tasks. We use this even though
// SpdySession is refcounted because we don't need to keep the SpdySession
// alive if the last reference is within a RunnableMethod. Just revoke the
diff --git a/chromium/net/spdy/spdy_session_key.cc b/chromium/net/spdy/spdy_session_key.cc
index 3ef95de5c3a..59f36df7703 100644
--- a/chromium/net/spdy/spdy_session_key.cc
+++ b/chromium/net/spdy/spdy_session_key.cc
@@ -4,6 +4,8 @@
#include "net/spdy/spdy_session_key.h"
+#include <tuple>
+
#include "base/logging.h"
namespace net {
@@ -33,11 +35,10 @@ SpdySessionKey::SpdySessionKey(const HostPortProxyPair& host_port_proxy_pair,
SpdySessionKey::~SpdySessionKey() {}
bool SpdySessionKey::operator<(const SpdySessionKey& other) const {
- if (privacy_mode_ != other.privacy_mode_)
- return privacy_mode_ < other.privacy_mode_;
- if (!host_port_proxy_pair_.first.Equals(other.host_port_proxy_pair_.first))
- return host_port_proxy_pair_.first < other.host_port_proxy_pair_.first;
- return host_port_proxy_pair_.second < other.host_port_proxy_pair_.second;
+ return std::tie(privacy_mode_, host_port_proxy_pair_.first,
+ host_port_proxy_pair_.second) <
+ std::tie(other.privacy_mode_, other.host_port_proxy_pair_.first,
+ other.host_port_proxy_pair_.second);
}
bool SpdySessionKey::Equals(const SpdySessionKey& other) const {
@@ -47,4 +48,3 @@ bool SpdySessionKey::Equals(const SpdySessionKey& other) const {
}
} // namespace net
-
diff --git a/chromium/net/spdy/spdy_session_pool.cc b/chromium/net/spdy/spdy_session_pool.cc
index eef0f9bfc48..120887859ea 100644
--- a/chromium/net/spdy/spdy_session_pool.cc
+++ b/chromium/net/spdy/spdy_session_pool.cc
@@ -4,6 +4,8 @@
#include "net/spdy/spdy_session_pool.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/profiler/scoped_tracker.h"
@@ -13,7 +15,6 @@
#include "net/http/http_server_properties.h"
#include "net/spdy/spdy_session.h"
-
namespace net {
namespace {
@@ -102,8 +103,8 @@ base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket(
stream_max_recv_window_size_, initial_max_concurrent_streams_, time_func_,
trusted_spdy_proxy_, net_log.net_log()));
- new_session->InitializeWithSocket(
- connection.Pass(), this, is_secure, certificate_error_code);
+ new_session->InitializeWithSocket(std::move(connection), this, is_secure,
+ certificate_error_code);
base::WeakPtr<SpdySession> available_session = new_session->GetWeakPtr();
sessions_.insert(new_session.release());
@@ -260,7 +261,7 @@ scoped_ptr<base::Value> SpdySessionPool::SpdySessionPoolInfoToValue() const {
if (key.Equals(session_key))
list->Append(it->second->GetInfoAsValue());
}
- return list.Pass();
+ return std::move(list);
}
void SpdySessionPool::OnIPAddressChanged() {
diff --git a/chromium/net/spdy/spdy_session_pool.h b/chromium/net/spdy/spdy_session_pool.h
index 740bd5a9746..0b0f97edb81 100644
--- a/chromium/net/spdy/spdy_session_pool.h
+++ b/chromium/net/spdy/spdy_session_pool.h
@@ -5,12 +5,14 @@
#ifndef NET_SPDY_SPDY_SESSION_POOL_H_
#define NET_SPDY_SPDY_SESSION_POOL_H_
+#include <stddef.h>
+
#include <map>
#include <set>
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/base/host_port_pair.h"
diff --git a/chromium/net/spdy/spdy_session_pool_unittest.cc b/chromium/net/spdy/spdy_session_pool_unittest.cc
index fccfadd5874..3791c7f88ae 100644
--- a/chromium/net/spdy/spdy_session_pool_unittest.cc
+++ b/chromium/net/spdy/spdy_session_pool_unittest.cc
@@ -6,6 +6,7 @@
#include <cstddef>
#include <string>
+#include <utility>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -20,8 +21,6 @@
namespace net {
-namespace {
-
class SpdySessionPoolTest : public ::testing::Test,
public ::testing::WithParamInterface<NextProto> {
protected:
@@ -44,7 +43,7 @@ class SpdySessionPoolTest : public ::testing::Test,
void RunIPPoolingTest(SpdyPoolCloseSessionsType close_sessions_type);
SpdySessionDependencies session_deps_;
- scoped_refptr<HttpNetworkSession> http_session_;
+ scoped_ptr<HttpNetworkSession> http_session_;
SpdySessionPool* spdy_session_pool_;
};
@@ -115,7 +114,7 @@ TEST_P(SpdySessionPoolTest, CloseCurrentSessions) {
// Setup the first session to the first host.
base::WeakPtr<SpdySession> session =
- CreateInsecureSpdySession(http_session_, test_key, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), test_key, BoundNetLog());
// Flush the SpdySession::OnReadComplete() task.
base::MessageLoop::current()->RunUntilIdle();
@@ -145,9 +144,9 @@ TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
session_deps_.host_resolver->set_synchronous_mode(true);
- StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data1(reads, arraysize(reads), nullptr, 0);
+ data1.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -160,7 +159,7 @@ TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
SpdySessionKey key1(test_host_port_pair1, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session1 =
- CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), key1, BoundNetLog());
GURL url1(kTestHost1);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
@@ -168,13 +167,15 @@ TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
ASSERT_TRUE(spdy_stream1.get() != NULL);
// Set up session 2
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data2(reads, arraysize(reads), nullptr, 0);
+ data2.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
const std::string kTestHost2("http://www.b.com");
HostPortPair test_host_port_pair2(kTestHost2, 80);
SpdySessionKey key2(test_host_port_pair2, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session2 =
- CreateInsecureSpdySession(http_session_, key2, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), key2, BoundNetLog());
GURL url2(kTestHost2);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
@@ -182,13 +183,15 @@ TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
ASSERT_TRUE(spdy_stream2.get() != NULL);
// Set up session 3
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data3(reads, arraysize(reads), nullptr, 0);
+ data3.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data3);
const std::string kTestHost3("http://www.c.com");
HostPortPair test_host_port_pair3(kTestHost3, 80);
SpdySessionKey key3(test_host_port_pair3, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session3 =
- CreateInsecureSpdySession(http_session_, key3, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), key3, BoundNetLog());
GURL url3(kTestHost3);
base::WeakPtr<SpdyStream> spdy_stream3 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
@@ -286,7 +289,7 @@ TEST_P(SpdySessionPoolTest, CloseAllSessions) {
// Setup the first session to the first host.
base::WeakPtr<SpdySession> session =
- CreateInsecureSpdySession(http_session_, test_key, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), test_key, BoundNetLog());
// Flush the SpdySession::OnReadComplete() task.
base::MessageLoop::current()->RunUntilIdle();
@@ -365,9 +368,9 @@ void SpdySessionPoolTest::RunIPPoolingTest(
MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
};
- StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data1(reads, arraysize(reads), NULL, 0);
+ data1.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -375,9 +378,8 @@ void SpdySessionPoolTest::RunIPPoolingTest(
CreateNetworkSession();
// Setup the first session to the first host.
- base::WeakPtr<SpdySession> session =
- CreateInsecureSpdySession(
- http_session_, test_hosts[0].key, BoundNetLog());
+ base::WeakPtr<SpdySession> session = CreateInsecureSpdySession(
+ http_session_.get(), test_hosts[0].key, BoundNetLog());
// Flush the SpdySession::OnReadComplete() task.
base::MessageLoop::current()->RunUntilIdle();
@@ -398,10 +400,11 @@ void SpdySessionPoolTest::RunIPPoolingTest(
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
// Create a new session to host 2.
- session_deps_.socket_factory->AddSocketDataProvider(&data);
- base::WeakPtr<SpdySession> session2 =
- CreateInsecureSpdySession(
- http_session_, test_hosts[2].key, BoundNetLog());
+ StaticSocketDataProvider data2(reads, arraysize(reads), NULL, 0);
+ data2.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ base::WeakPtr<SpdySession> session2 = CreateInsecureSpdySession(
+ http_session_.get(), test_hosts[2].key, BoundNetLog());
// Verify that we have sessions for everything.
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[0].key));
@@ -512,7 +515,13 @@ TEST_P(SpdySessionPoolTest, IPPoolingCloseIdleSessions) {
TEST_P(SpdySessionPoolTest, IPAddressChanged) {
MockConnect connect_data(SYNCHRONOUS, OK);
session_deps_.host_resolver->set_synchronous_mode(true);
- SpdyTestUtil spdy_util(GetParam());
+
+ // This isn't testing anything having to do with SPDY frames; we
+ // can ignore issues of how dependencies are set. We default to
+ // setting them (when doing the appropriate protocol) since that's
+ // where we're eventually headed for all HTTP/2 connections.
+ SpdyTestUtil spdy_util(GetParam(), true);
+ SpdySession::SetPriorityDependencyDefaultForTesting(true);
MockRead reads[] = {
MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
@@ -521,10 +530,10 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
spdy_util.ConstructSpdyGet("http://www.a.com", false, 1, MEDIUM));
MockWrite writes[] = {CreateMockWrite(*req, 1)};
- StaticSocketDataProvider data(reads, arraysize(reads), writes,
- arraysize(writes));
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider dataA(reads, arraysize(reads), writes,
+ arraysize(writes));
+ dataA.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&dataA);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -532,13 +541,12 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
CreateNetworkSession();
// Set up session A: Going away, but with an active stream.
- session_deps_.socket_factory->AddSocketDataProvider(&data);
const std::string kTestHostA("http://www.a.com");
HostPortPair test_host_port_pairA(kTestHostA, 80);
SpdySessionKey keyA(
test_host_port_pairA, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> sessionA =
- CreateInsecureSpdySession(http_session_, keyA, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), keyA, BoundNetLog());
GURL urlA(kTestHostA);
base::WeakPtr<SpdyStream> spdy_streamA = CreateStreamSynchronously(
@@ -548,7 +556,7 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util.ConstructGetHeaderBlock(urlA.spec()));
- spdy_streamA->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_streamA->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_streamA->HasUrlFromHeaders());
base::MessageLoop::current()->RunUntilIdle(); // Allow headers to write.
@@ -559,12 +567,16 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
EXPECT_FALSE(delegateA.StreamIsClosed());
// Set up session B: Available, with a created stream.
+ StaticSocketDataProvider dataB(reads, arraysize(reads), writes,
+ arraysize(writes));
+ dataB.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&dataB);
const std::string kTestHostB("http://www.b.com");
HostPortPair test_host_port_pairB(kTestHostB, 80);
SpdySessionKey keyB(
test_host_port_pairB, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> sessionB =
- CreateInsecureSpdySession(http_session_, keyB, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), keyB, BoundNetLog());
EXPECT_TRUE(sessionB->IsAvailable());
GURL urlB(kTestHostB);
@@ -574,13 +586,16 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
spdy_streamB->SetDelegate(&delegateB);
// Set up session C: Draining.
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider dataC(reads, arraysize(reads), writes,
+ arraysize(writes));
+ dataC.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&dataC);
const std::string kTestHostC("http://www.c.com");
HostPortPair test_host_port_pairC(kTestHostC, 80);
SpdySessionKey keyC(
test_host_port_pairC, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> sessionC =
- CreateInsecureSpdySession(http_session_, keyC, BoundNetLog());
+ CreateInsecureSpdySession(http_session_.get(), keyC, BoundNetLog());
sessionC->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error!");
EXPECT_TRUE(sessionC->IsDraining());
@@ -615,8 +630,7 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
EXPECT_TRUE(delegateB.StreamIsClosed());
EXPECT_EQ(ERR_NETWORK_CHANGED, delegateB.WaitForClose());
#endif // defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
}
-} // namespace
-
} // namespace net
diff --git a/chromium/net/spdy/spdy_session_test_util.h b/chromium/net/spdy/spdy_session_test_util.h
index dcb17339632..819b15c8da0 100644
--- a/chromium/net/spdy/spdy_session_test_util.h
+++ b/chromium/net/spdy/spdy_session_test_util.h
@@ -5,9 +5,10 @@
#ifndef NET_SPDY_SPDY_SESSION_TEST_UTIL_H_
#define NET_SPDY_SPDY_SESSION_TEST_UTIL_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/message_loop/message_loop.h"
#include "base/pending_task.h"
@@ -33,10 +34,10 @@ class SpdySessionTestTaskObserver : public base::MessageLoop::TaskObserver {
void DidProcessTask(const base::PendingTask& pending_task) override;
// Returns the number of tasks posted by the given function and file.
- uint16 executed_count() const { return executed_count_; }
+ uint16_t executed_count() const { return executed_count_; }
private:
- uint16 executed_count_;
+ uint16_t executed_count_;
std::string file_name_;
std::string function_name_;
};
diff --git a/chromium/net/spdy/spdy_session_unittest.cc b/chromium/net/spdy/spdy_session_unittest.cc
index 0f89c4f0c19..ee19f03ac0d 100644
--- a/chromium/net/spdy/spdy_session_unittest.cc
+++ b/chromium/net/spdy/spdy_session_unittest.cc
@@ -4,6 +4,8 @@
#include "net/spdy/spdy_session.h"
+#include <utility>
+
#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
@@ -35,6 +37,22 @@ namespace net {
namespace {
+enum TestCase {
+ // Test using the SPDY/3.1 protocol.
+ kTestCaseSPDY31,
+
+ // Test using the HTTP/2 protocol, without specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2NoPriorityDependencies,
+
+ // Test using the HTTP/2 protocol, specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2PriorityDependencies
+};
+
+const char kHttpURLFromAnotherOrigin[] = "http://www.example2.org/a.dat";
+const char kHttpsURLFromAnotherOrigin[] = "https://www.example2.org/b.dat";
+
const char kBodyData[] = "Body data";
const size_t kBodyDataSize = arraysize(kBodyData);
const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize);
@@ -59,7 +77,7 @@ base::TimeTicks InstantaneousReads() {
} // namespace
class SpdySessionTest : public PlatformTest,
- public ::testing::WithParamInterface<NextProto> {
+ public ::testing::WithParamInterface<TestCase> {
public:
// Functions used with RunResumeAfterUnstallTest().
@@ -77,38 +95,49 @@ class SpdySessionTest : public PlatformTest,
StallSessionSend();
}
- void UnstallSessionOnly(SpdyStream* stream, int32 delta_window_size) {
+ void UnstallSessionOnly(SpdyStream* stream, int32_t delta_window_size) {
UnstallSessionSend(delta_window_size);
}
- void UnstallStreamOnly(SpdyStream* stream, int32 delta_window_size) {
+ void UnstallStreamOnly(SpdyStream* stream, int32_t delta_window_size) {
UnstallStreamSend(stream, delta_window_size);
}
- void UnstallSessionStream(SpdyStream* stream, int32 delta_window_size) {
+ void UnstallSessionStream(SpdyStream* stream, int32_t delta_window_size) {
UnstallSessionSend(delta_window_size);
UnstallStreamSend(stream, delta_window_size);
}
- void UnstallStreamSession(SpdyStream* stream, int32 delta_window_size) {
+ void UnstallStreamSession(SpdyStream* stream, int32_t delta_window_size) {
UnstallStreamSend(stream, delta_window_size);
UnstallSessionSend(delta_window_size);
}
protected:
+ NextProto GetProtocol() const {
+ return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
+ }
+
+ bool GetDependenciesFromPriority() const {
+ return GetParam() == kTestCaseHTTP2PriorityDependencies;
+ }
+
SpdySessionTest()
: old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
HttpNetworkSession::NORMAL_SOCKET_POOL)),
old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
HttpNetworkSession::NORMAL_SOCKET_POOL)),
- spdy_util_(GetParam()),
- session_deps_(GetParam()),
+ spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
+ session_deps_(GetProtocol()),
spdy_session_pool_(nullptr),
test_url_(kDefaultURL),
test_host_port_pair_(HostPortPair::FromURL(test_url_)),
key_(test_host_port_pair_,
ProxyServer::Direct(),
- PRIVACY_MODE_DISABLED) {}
+ PRIVACY_MODE_DISABLED) {
+ SpdySession::SetPriorityDependencyDefaultForTesting(
+ GetDependenciesFromPriority());
+ }
virtual ~SpdySessionTest() {
// Important to restore the per-pool limit first, since the pool limit must
@@ -117,6 +146,7 @@ class SpdySessionTest : public PlatformTest,
HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
ClientSocketPoolManager::set_max_sockets_per_group(
HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
}
void SetUp() override {
@@ -135,8 +165,8 @@ class SpdySessionTest : public PlatformTest,
void CreateInsecureSpdySession() {
DCHECK(!session_);
- session_ =
- ::net::CreateInsecureSpdySession(http_session_, key_, log_.bound());
+ session_ = ::net::CreateInsecureSpdySession(http_session_.get(), key_,
+ log_.bound());
}
void StallSessionSend() {
@@ -147,7 +177,7 @@ class SpdySessionTest : public PlatformTest,
}
}
- void UnstallSessionSend(int32 delta_window_size) {
+ void UnstallSessionSend(int32_t delta_window_size) {
session_->IncreaseSendWindowSize(delta_window_size);
}
@@ -159,13 +189,13 @@ class SpdySessionTest : public PlatformTest,
}
}
- void UnstallStreamSend(SpdyStream* stream, int32 delta_window_size) {
+ void UnstallStreamSend(SpdyStream* stream, int32_t delta_window_size) {
stream->IncreaseSendWindowSize(delta_window_size);
}
void RunResumeAfterUnstallTest(
const base::Callback<void(SpdyStream*)>& stall_function,
- const base::Callback<void(SpdyStream*, int32)>& unstall_function);
+ const base::Callback<void(SpdyStream*, int32_t)>& unstall_function);
// Original socket limits. Some tests set these. Safest to always restore
// them once each test has been run.
@@ -174,7 +204,7 @@ class SpdySessionTest : public PlatformTest,
SpdyTestUtil spdy_util_;
SpdySessionDependencies session_deps_;
- scoped_refptr<HttpNetworkSession> http_session_;
+ scoped_ptr<HttpNetworkSession> http_session_;
base::WeakPtr<SpdySession> session_;
SpdySessionPool* spdy_session_pool_;
GURL test_url_;
@@ -183,10 +213,11 @@ class SpdySessionTest : public PlatformTest,
BoundTestNetLog log_;
};
-INSTANTIATE_TEST_CASE_P(NextProto,
+INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
SpdySessionTest,
- testing::Values(kProtoSPDY31,
- kProtoHTTP2));
+ testing::Values(kTestCaseSPDY31,
+ kTestCaseHTTP2NoPriorityDependencies,
+ kTestCaseHTTP2PriorityDependencies));
// Try to create a SPDY session that will fail during
// initialization. Nothing should blow up.
@@ -212,7 +243,7 @@ class StreamRequestDestroyingCallback : public TestCompletionCallbackBase {
~StreamRequestDestroyingCallback() override {}
void SetRequestToDestroy(scoped_ptr<SpdyStreamRequest> request) {
- request_ = request.Pass();
+ request_ = std::move(request);
}
CompletionCallback MakeCallback() {
@@ -268,7 +299,7 @@ TEST_P(SpdySessionTest, PendingStreamCancellingAnother) {
SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
MEDIUM, BoundNetLog(), callback2.callback()));
- callback1.SetRequestToDestroy(request2.Pass());
+ callback1.SetRequestToDestroy(std::move(request2));
session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");
@@ -314,7 +345,7 @@ TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
CreateNetworkSession();
session_ = TryCreateInsecureSpdySessionExpectingFailure(
- http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog());
+ http_session_.get(), key_, ERR_CONNECTION_CLOSED, BoundNetLog());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
@@ -364,9 +395,9 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -377,7 +408,7 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
// Read and process the GOAWAY frame.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
@@ -393,11 +424,67 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
EXPECT_FALSE(spdy_stream1);
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
+// Regression test for https://crbug.com/547130.
+TEST_P(SpdySessionTest, GoAwayWithActiveAndCreatedStream) {
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(0));
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*goaway, 2),
+ };
+
+ // No |req2|, because the second stream will never get activated.
+ scoped_ptr<SpdyFrame> req1(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true));
+ MockWrite writes[] = {
+ CreateMockWrite(*req1, 0),
+ };
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ CreateNetworkSession();
+ CreateInsecureSpdySession();
+
+ EXPECT_EQ(spdy_util_.spdy_version(), session_->GetProtocolVersion());
+
+ base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM, BoundNetLog());
+ test::StreamDelegateDoNothing delegate1(spdy_stream1);
+ spdy_stream1->SetDelegate(&delegate1);
+ scoped_ptr<SpdyHeaderBlock> headers1(
+ spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
+ spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
+ EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
+
+ EXPECT_EQ(0u, spdy_stream1->stream_id());
+
+ // Active stream 1.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, spdy_stream1->stream_id());
+ EXPECT_TRUE(session_->IsStreamActive(1));
+
+ // Create stream corresponding to the next request.
+ base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM, BoundNetLog());
+
+ EXPECT_EQ(0u, spdy_stream2->stream_id());
+
+ // Read and process the GOAWAY frame before the second stream could be
+ // activated.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(session_);
+
+ EXPECT_TRUE(data.AllWriteDataConsumed());
+ EXPECT_TRUE(data.AllReadDataConsumed());
+}
+
// Have a session receive two GOAWAY frames, with the last one causing
// the last active stream to be closed. The session should then be
// closed after the second GOAWAY frame.
@@ -444,9 +531,9 @@ TEST_P(SpdySessionTest, GoAwayTwice) {
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -457,7 +544,7 @@ TEST_P(SpdySessionTest, GoAwayTwice) {
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
// Read and process the first GOAWAY frame.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
@@ -469,7 +556,7 @@ TEST_P(SpdySessionTest, GoAwayTwice) {
// Read and process the second GOAWAY frame, which should close the
// session.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -517,9 +604,9 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -530,7 +617,7 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
// Read and process the GOAWAY frame.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
@@ -543,7 +630,7 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");
EXPECT_FALSE(spdy_stream1);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -598,7 +685,7 @@ TEST_P(SpdySessionTest, GoAwayWhileDraining) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -642,7 +729,7 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -652,7 +739,7 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
// Read and process the GOAWAY frame.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
@@ -665,7 +752,7 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
EXPECT_EQ(ERR_FAILED, rv);
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -705,7 +792,7 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -715,7 +802,7 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
// Read and process the GOAWAY frame.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
@@ -723,7 +810,7 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
// Read and process the SYN_STREAM frame, the subsequent RST_STREAM,
// and EOF.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -757,7 +844,7 @@ TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -786,7 +873,7 @@ TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) {
#endif
EXPECT_FALSE(spdy_stream);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -834,7 +921,7 @@ TEST_P(SpdySessionTest, ClientPing) {
EXPECT_FALSE(session_->check_ping_status_pending());
EXPECT_GE(session_->last_activity_time(), before_ping_time);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
@@ -912,7 +999,7 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
// Shift time so that a ping will be sent out.
g_time_delta = base::TimeDelta::FromSeconds(11);
@@ -920,7 +1007,7 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) {
base::RunLoop().RunUntilIdle();
session_->CloseSessionOnError(ERR_ABORTED, "Aborting");
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -1034,7 +1121,7 @@ TEST_P(SpdySessionTest, StreamIdSpaceExhausted) {
EXPECT_EQ(0u, session_->pending_create_stream_queue_size(MEDIUM));
// Read responses on remaining active streams.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(OK, delegate1.WaitForClose());
EXPECT_EQ(kUploadData, delegate1.TakeReceivedData());
@@ -1148,7 +1235,7 @@ TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
base::RunLoop().RunUntilIdle();
@@ -1159,19 +1246,16 @@ TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
GURL("http://www.example.org/a.dat"));
EXPECT_TRUE(session_->unclaimed_pushed_streams_.end() != iter);
- if (session_->flow_control_state_ ==
- SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) {
- // Unclaimed push body consumed bytes from the session window.
- EXPECT_EQ(
- SpdySession::GetDefaultInitialWindowSize(GetParam()) - kUploadDataSize,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
- }
+ // Unclaimed push body consumed bytes from the session window.
+ EXPECT_EQ(
+ SpdySession::GetDefaultInitialWindowSize(GetProtocol()) - kUploadDataSize,
+ session_->session_recv_window_size_);
+ EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
// Shift time to expire the push stream. Read the second SYN_STREAM,
// and verify a RST_STREAM was written.
g_time_delta = base::TimeDelta::FromSeconds(301);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
// Verify that the second pushed stream evicted the first pushed stream.
@@ -1180,17 +1264,14 @@ TEST_P(SpdySessionTest, DeleteExpiredPushStreams) {
GURL("http://www.example.org/0.dat"));
EXPECT_TRUE(session_->unclaimed_pushed_streams_.end() != iter);
- if (session_->flow_control_state_ ==
- SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) {
- // Verify that the session window reclaimed the evicted stream body.
- EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()),
- session_->session_recv_window_size_);
- EXPECT_EQ(kUploadDataSize, session_->session_unacked_recv_window_bytes_);
- }
+ // Verify that the session window reclaimed the evicted stream body.
+ EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetProtocol()),
+ session_->session_recv_window_size_);
+ EXPECT_EQ(kUploadDataSize, session_->session_unacked_recv_window_bytes_);
// Read and process EOF.
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -1259,12 +1340,12 @@ TEST_P(SpdySessionTest, OnSettings) {
int seq = 0;
std::vector<MockWrite> writes;
scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
- if (GetParam() == kProtoHTTP2) {
+ if (GetProtocol() == kProtoHTTP2) {
writes.push_back(CreateMockWrite(*settings_ack, ++seq));
}
SettingsMap new_settings;
- const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
+ const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
new_settings[kSpdySettingsIds] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
scoped_ptr<SpdyFrame> settings_frame(
@@ -1275,7 +1356,7 @@ TEST_P(SpdySessionTest, OnSettings) {
MockRead(ASYNC, 0, ++seq),
};
- SequencedSocketData data(reads, arraysize(reads), vector_as_array(&writes),
+ SequencedSocketData data(reads, arraysize(reads), writes.data(),
writes.size());
session_deps_.socket_factory->AddSocketDataProvider(&data);
@@ -1300,7 +1381,7 @@ TEST_P(SpdySessionTest, OnSettings) {
EXPECT_EQ(OK, stream_releaser.WaitForResult());
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
@@ -1321,12 +1402,12 @@ TEST_P(SpdySessionTest, ClearSettings) {
session_deps_.host_resolver->set_synchronous_mode(true);
SettingsMap new_settings;
- const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
+ const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
scoped_ptr<SpdyFrame> settings_frame(
spdy_util_.ConstructSpdySettings(new_settings));
- uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
+ uint8_t flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version());
MockRead reads[] = {
CreateMockRead(*settings_frame, 0),
@@ -1380,7 +1461,7 @@ TEST_P(SpdySessionTest, ClearSettings) {
EXPECT_EQ(kInitialMaxConcurrentStreams + 1,
session_->max_concurrent_streams());
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -1456,7 +1537,7 @@ TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
scoped_ptr<SpdyFrame> settings_frame(
spdy_util_.ConstructSpdySettings(settings));
std::vector<MockWrite> writes;
- if (GetParam() == kProtoHTTP2) {
+ if (GetProtocol() == kProtoHTTP2) {
writes.push_back(
MockWrite(ASYNC,
kHttp2ConnectionHeaderPrefix,
@@ -1465,18 +1546,18 @@ TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
writes.push_back(CreateMockWrite(*settings_frame));
SettingsMap server_settings;
- const uint32 initial_max_concurrent_streams = 1;
+ const uint32_t initial_max_concurrent_streams = 1;
server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
initial_max_concurrent_streams);
scoped_ptr<SpdyFrame> server_settings_frame(
spdy_util_.ConstructSpdySettings(server_settings));
- if (GetParam() <= kProtoSPDY31) {
+ if (GetProtocol() == kProtoSPDY31) {
writes.push_back(CreateMockWrite(*server_settings_frame));
}
- StaticSocketDataProvider data(reads, arraysize(reads),
- vector_as_array(&writes), writes.size());
+ StaticSocketDataProvider data(reads, arraysize(reads), writes.data(),
+ writes.size());
session_deps_.socket_factory->AddSocketDataProvider(&data);
CreateNetworkSession();
@@ -1551,7 +1632,8 @@ TEST_P(SpdySessionTest, Initialize) {
TEST_P(SpdySessionTest, NetLogOnSessionGoaway) {
session_deps_.host_resolver->set_synchronous_mode(true);
- scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
+ scoped_ptr<SpdyFrame> goaway(
+ spdy_util_.ConstructSpdyGoAway(42, GOAWAY_ENHANCE_YOUR_CALM, "foo"));
MockRead reads[] = {
CreateMockRead(*goaway),
MockRead(SYNCHRONOUS, 0, 0) // EOF
@@ -1575,18 +1657,35 @@ TEST_P(SpdySessionTest, NetLogOnSessionGoaway) {
log_.GetEntries(&entries);
EXPECT_LT(0u, entries.size());
+ if (GetProtocol() == kProtoHTTP2) {
+ int pos = ExpectLogContainsSomewhere(
+ entries, 0, NetLog::TYPE_HTTP2_SESSION_GOAWAY, NetLog::PHASE_NONE);
+ TestNetLogEntry entry = entries[pos];
+ int last_accepted_stream_id;
+ ASSERT_TRUE(entry.GetIntegerValue("last_accepted_stream_id",
+ &last_accepted_stream_id));
+ EXPECT_EQ(42, last_accepted_stream_id);
+ int active_streams;
+ ASSERT_TRUE(entry.GetIntegerValue("active_streams", &active_streams));
+ EXPECT_EQ(0, active_streams);
+ int unclaimed_streams;
+ ASSERT_TRUE(entry.GetIntegerValue("unclaimed_streams", &unclaimed_streams));
+ EXPECT_EQ(0, unclaimed_streams);
+ int status;
+ ASSERT_TRUE(entry.GetIntegerValue("status", &status));
+ EXPECT_EQ(GOAWAY_ENHANCE_YOUR_CALM, status);
+ std::string debug_data;
+ ASSERT_TRUE(entry.GetStringValue("debug_data", &debug_data));
+ EXPECT_EQ("foo", debug_data);
+ }
+
// Check that we logged SPDY_SESSION_CLOSE correctly.
int pos = ExpectLogContainsSomewhere(
entries, 0, NetLog::TYPE_HTTP2_SESSION_CLOSE, NetLog::PHASE_NONE);
-
- if (pos < static_cast<int>(entries.size())) {
- TestNetLogEntry entry = entries[pos];
- int error_code = 0;
- ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
- EXPECT_EQ(OK, error_code);
- } else {
- ADD_FAILURE();
- }
+ TestNetLogEntry entry = entries[pos];
+ int error_code = 0;
+ ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
+ EXPECT_EQ(OK, error_code);
}
TEST_P(SpdySessionTest, NetLogOnSessionEOF) {
@@ -1652,7 +1751,7 @@ TEST_P(SpdySessionTest, SynCompressionHistograms) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
// Write request headers & capture resulting histogram update.
@@ -1675,7 +1774,7 @@ TEST_P(SpdySessionTest, SynCompressionHistograms) {
// Read and process EOF.
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -1737,14 +1836,14 @@ TEST_P(SpdySessionTest, OutOfOrderSynStreams) {
scoped_ptr<SpdyHeaderBlock> headers_lowest(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream_lowest->SendRequestHeaders(
- headers_lowest.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream_lowest->SendRequestHeaders(std::move(headers_lowest),
+ NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders());
scoped_ptr<SpdyHeaderBlock> headers_highest(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream_highest->SendRequestHeaders(
- headers_highest.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream_highest->SendRequestHeaders(std::move(headers_highest),
+ NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -1799,12 +1898,12 @@ TEST_P(SpdySessionTest, CancelStream) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
EXPECT_EQ(0u, spdy_stream1->stream_id());
@@ -1862,12 +1961,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
// Ensure that the streams have not yet been activated and assigned an id.
@@ -1918,12 +2017,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
// Ensure that the streams have not yet been activated and assigned an id.
@@ -1985,12 +2084,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
// Ensure that the streams have not yet been activated and assigned an id.
@@ -2012,7 +2111,7 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
EXPECT_TRUE(delegate2.StreamIsClosed());
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -2061,12 +2160,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders());
// Ensure that the streams have not yet been activated and assigned an id.
@@ -2088,7 +2187,7 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
EXPECT_TRUE(delegate2.StreamIsClosed());
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -2149,7 +2248,7 @@ TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
EXPECT_EQ(0u, spdy_stream->stream_id());
@@ -2192,7 +2291,7 @@ TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
CreateNetworkSession();
- session_ = CreateSecureSpdySession(http_session_, key_, BoundNetLog());
+ session_ = CreateSecureSpdySession(http_session_.get(), key_, BoundNetLog());
EXPECT_TRUE(session_->VerifyDomainAuthentication("www.example.org"));
EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.org"));
@@ -2222,7 +2321,7 @@ TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) {
CreateNetworkSession();
- session_ = CreateSecureSpdySession(http_session_, key_, BoundNetLog());
+ session_ = CreateSecureSpdySession(http_session_.get(), key_, BoundNetLog());
EXPECT_TRUE(session_->VerifyDomainAuthentication("www.example.org"));
EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.org"));
@@ -2235,15 +2334,17 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
// this file.
SettingsMap new_settings;
const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
- const uint32 max_concurrent_streams = 1;
+ const uint32_t max_concurrent_streams = 1;
new_settings[kSpdySettingsIds1] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
scoped_ptr<SpdyFrame> req1(
spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, LOWEST, true));
+ spdy_util_.UpdateWithStreamDestruction(3);
scoped_ptr<SpdyFrame> req3(
spdy_util_.ConstructSpdyGet(nullptr, 0, false, 5, LOWEST, true));
MockWrite writes[] = {
@@ -2318,7 +2419,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Run until 1st stream is activated and then closed.
@@ -2343,7 +2444,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
stream2->SetDelegate(&delegate2);
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
+ stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(stream2->HasUrlFromHeaders());
// Run until 2nd stream is activated and then closed.
@@ -2368,7 +2469,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
stream3->SetDelegate(&delegate3);
scoped_ptr<SpdyHeaderBlock> headers3(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND);
+ stream3->SendRequestHeaders(std::move(headers3), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(stream3->HasUrlFromHeaders());
// Run until 2nd stream is activated and then closed.
@@ -2381,7 +2482,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
EXPECT_EQ(0u, session_->num_created_streams());
EXPECT_EQ(0u, session_->pending_create_stream_queue_size(LOWEST));
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
}
@@ -2517,7 +2618,7 @@ TEST_P(SpdySessionTest, ReadDataWithoutYielding) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't
@@ -2532,7 +2633,7 @@ TEST_P(SpdySessionTest, ReadDataWithoutYielding) {
// Read all the data and verify SpdySession::DoReadLoop has not
// posted a task.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(spdy_stream1);
@@ -2581,7 +2682,7 @@ TEST_P(SpdySessionTest, TestYieldingSlowReads) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Set up the TaskObserver to verify that SpdySession::DoReadLoop posts a
@@ -2629,7 +2730,7 @@ TEST_P(SpdySessionTest, TestYieldingSlowSynchronousReads) {
MockRead reads[] = {
CreateMockRead(*resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
- CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
+ CreateMockRead(*partial_data_frame, 3, ASYNC),
CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS),
CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS),
@@ -2652,7 +2753,7 @@ TEST_P(SpdySessionTest, TestYieldingSlowSynchronousReads) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Run until 1st read.
@@ -2661,7 +2762,7 @@ TEST_P(SpdySessionTest, TestYieldingSlowSynchronousReads) {
EXPECT_EQ(1u, delegate1.stream_id());
// Read all the data and verify SpdySession::DoReadLoop has posted a task.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ("foo foo foo bar", delegate1.TakeReceivedData());
EXPECT_FALSE(spdy_stream1);
@@ -2733,7 +2834,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringReadData) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Set up the TaskObserver to verify SpdySession::DoReadLoop posts a task.
@@ -2746,7 +2847,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringReadData) {
EXPECT_EQ(0u, observer.executed_count());
// Read all the data and verify SpdySession::DoReadLoop has posted a task.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(spdy_stream1);
@@ -2840,7 +2941,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Set up the TaskObserver to monitor SpdySession::DoReadLoop
@@ -2855,7 +2956,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) {
// Read all the data and verify SpdySession::DoReadLoop has posted a
// task.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(spdy_stream1);
@@ -2908,7 +3009,7 @@ TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Run until 1st read.
@@ -2917,7 +3018,7 @@ TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) {
EXPECT_EQ(1u, spdy_stream1->stream_id());
// Run until GoAway.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(spdy_stream1);
EXPECT_TRUE(data.AllWriteDataConsumed());
@@ -2943,11 +3044,9 @@ TEST_P(SpdySessionTest, ProtocolNegotiation) {
EXPECT_EQ(spdy_util_.spdy_version(),
session_->buffered_spdy_framer_->protocol_version());
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
- EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()),
+ EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetProtocol()),
session_->session_send_window_size_);
- EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()),
+ EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetProtocol()),
session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
}
@@ -3032,8 +3131,8 @@ TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
// Create an idle SPDY session.
SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
- base::WeakPtr<SpdySession> session1 =
- ::net::CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
+ base::WeakPtr<SpdySession> session1 = ::net::CreateInsecureSpdySession(
+ http_session_.get(), key1, BoundNetLog());
EXPECT_FALSE(pool->IsStalled());
// Set up an alias for the idle SPDY session, increasing its ref count to 2.
@@ -3127,9 +3226,8 @@ TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- EXPECT_EQ(ERR_IO_PENDING,
- spdy_stream1->SendRequestHeaders(
- headers1.Pass(), NO_MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, spdy_stream1->SendRequestHeaders(
+ std::move(headers1), NO_MORE_DATA_TO_SEND));
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
base::RunLoop().RunUntilIdle();
@@ -3258,7 +3356,7 @@ TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
EXPECT_EQ(0u, spdy_stream->stream_id());
@@ -3269,7 +3367,7 @@ TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
// Cause the stream to be reset, which should cause another stream
// to be created.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(spdy_stream);
@@ -3277,7 +3375,7 @@ TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
EXPECT_EQ(0u, session_->num_active_streams());
EXPECT_EQ(1u, session_->num_created_streams());
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -3286,7 +3384,7 @@ TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
// Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
// gets sent.
SettingsMap new_settings;
- int32 window_size = 1;
+ int32_t window_size = 1;
new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
@@ -3335,7 +3433,7 @@ TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
EXPECT_FALSE(spdy_stream2);
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -3347,9 +3445,9 @@ TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
session_deps_.host_resolver->set_synchronous_mode(true);
- const int32 initial_window_size =
- SpdySession::GetDefaultInitialWindowSize(GetParam());
- const int32 delta_window_size = 100;
+ const int32_t initial_window_size =
+ SpdySession::GetDefaultInitialWindowSize(GetProtocol());
+ const int32_t delta_window_size = 100;
MockRead reads[] = {
MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF
@@ -3364,8 +3462,6 @@ TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
@@ -3392,7 +3488,7 @@ TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -3411,12 +3507,10 @@ TEST_P(SpdySessionTest, AdjustSendWindowSize) {
CreateNetworkSession();
session_ = CreateFakeSpdySession(spdy_session_pool_, key_);
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
- const int32 initial_window_size =
- SpdySession::GetDefaultInitialWindowSize(GetParam());
- const int32 delta_window_size = 100;
+ const int32_t initial_window_size =
+ SpdySession::GetDefaultInitialWindowSize(GetProtocol());
+ const int32_t delta_window_size = 100;
EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
@@ -3445,21 +3539,19 @@ TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) {
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
- EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()),
+ EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetProtocol()),
session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()),
+ EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetProtocol()),
session_->session_recv_window_size_);
EXPECT_EQ(kUploadDataSize, session_->session_unacked_recv_window_bytes_);
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -3468,7 +3560,7 @@ TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) {
// (including optional pad length and padding) is.
TEST_P(SpdySessionTest, SessionFlowControlPadding) {
// Padding only exists in HTTP/2.
- if (GetParam() < kProtoHTTP2)
+ if (GetProtocol() < kProtoHTTP2)
return;
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -3486,29 +3578,27 @@ TEST_P(SpdySessionTest, SessionFlowControlPadding) {
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
- EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()),
+ EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetProtocol()),
session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()),
+ EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetProtocol()),
session_->session_recv_window_size_);
EXPECT_EQ(kUploadDataSize + padding_length,
session_->session_unacked_recv_window_bytes_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
// Peer sends more data than stream level receiving flow control window.
TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) {
- const int32 stream_max_recv_window_size = 1024;
- const int32 data_frame_size = 2 * stream_max_recv_window_size;
+ const int32_t stream_max_recv_window_size = 1024;
+ const int32_t data_frame_size = 2 * stream_max_recv_window_size;
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true));
@@ -3538,7 +3628,6 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) {
SpdySessionPoolPeer pool_peer(spdy_session_pool_);
pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size);
CreateInsecureSpdySession();
- EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session_->flow_control_state());
base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
@@ -3550,19 +3639,19 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
- headers.Pass(), NO_MORE_DATA_TO_SEND));
+ std::move(headers), NO_MORE_DATA_TO_SEND));
// Request and response.
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, spdy_stream->stream_id());
// Too large data frame causes flow control error, should close stream.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(spdy_stream);
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -3571,9 +3660,9 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) {
// deltas in the receiving window size when checking incoming frames for flow
// control errors at session level.
TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
- const int32 session_max_recv_window_size = 500;
- const int32 first_data_frame_size = 200;
- const int32 second_data_frame_size = 400;
+ const int32_t session_max_recv_window_size = 500;
+ const int32_t first_data_frame_size = 200;
+ const int32_t second_data_frame_size = 400;
// First data frame should not trigger a WINDOW_UPDATE.
ASSERT_GT(session_max_recv_window_size / 2, first_data_frame_size);
@@ -3611,8 +3700,6 @@ TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
// Setting session level receiving window size to smaller than initial is not
// possible via SpdySessionPoolPeer.
session_->session_recv_window_size_ = session_max_recv_window_size;
@@ -3626,7 +3713,7 @@ TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
EXPECT_EQ(SpdySession::STATE_AVAILABLE, session_->availability_state_);
// Second data frame overflows receiving window, causes session to close.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SpdySession::STATE_DRAINING, session_->availability_state_);
}
@@ -3635,9 +3722,9 @@ TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
// deltas in the receiving window size when checking incoming data frames for
// flow control errors at stream level.
TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
- const int32 stream_max_recv_window_size = 500;
- const int32 first_data_frame_size = 200;
- const int32 second_data_frame_size = 400;
+ const int32_t stream_max_recv_window_size = 500;
+ const int32_t first_data_frame_size = 200;
+ const int32_t second_data_frame_size = 400;
// First data frame should not trigger a WINDOW_UPDATE.
ASSERT_GT(stream_max_recv_window_size / 2, first_data_frame_size);
@@ -3681,7 +3768,6 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size);
CreateInsecureSpdySession();
- EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session_->flow_control_state());
base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
@@ -3691,7 +3777,7 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
- headers.Pass(), NO_MORE_DATA_TO_SEND));
+ std::move(headers), NO_MORE_DATA_TO_SEND));
// Request and response.
base::RunLoop().RunUntilIdle();
@@ -3699,7 +3785,7 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
// First data frame.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(spdy_stream->IsLocallyClosed());
EXPECT_EQ(stream_max_recv_window_size - first_data_frame_size,
@@ -3711,13 +3797,13 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
// Second data frame overflows receiving window, causes the stream to close.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(spdy_stream.get());
// RST_STREAM
EXPECT_TRUE(session_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -3739,14 +3825,13 @@ class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
// data. The receive window should still increase to its original
// value, i.e. we shouldn't "leak" receive window bytes.
TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
- const int32 msg_data_size = 100;
- const std::string msg_data(msg_data_size, 'a');
+ const int32_t kMsgDataSize = 100;
+ const std::string msg_data(kMsgDataSize, 'a');
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
- kDefaultURL, 1, msg_data_size, MEDIUM, nullptr, 0));
- scoped_ptr<SpdyFrame> msg(
- spdy_util_.ConstructSpdyBodyFrame(
- 1, msg_data.data(), msg_data_size, false));
+ kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0));
+ scoped_ptr<SpdyFrame> msg(spdy_util_.ConstructSpdyBodyFrame(
+ 1, msg_data.data(), kMsgDataSize, false));
MockWrite writes[] = {
CreateMockWrite(*req, 0),
CreateMockWrite(*msg, 2),
@@ -3754,12 +3839,10 @@ TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
scoped_ptr<SpdyFrame> resp(
spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
- scoped_ptr<SpdyFrame> echo(
- spdy_util_.ConstructSpdyBodyFrame(
- 1, msg_data.data(), msg_data_size, false));
- scoped_ptr<SpdyFrame> window_update(
- spdy_util_.ConstructSpdyWindowUpdate(
- kSessionFlowControlStreamId, msg_data_size));
+ scoped_ptr<SpdyFrame> echo(spdy_util_.ConstructSpdyBodyFrame(
+ 1, msg_data.data(), kMsgDataSize, false));
+ scoped_ptr<SpdyFrame> window_update(spdy_util_.ConstructSpdyWindowUpdate(
+ kSessionFlowControlStreamId, kMsgDataSize));
MockRead reads[] = {
CreateMockRead(*resp, 1),
CreateMockRead(*echo, 3),
@@ -3784,20 +3867,20 @@ TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
stream->SetDelegate(&delegate);
scoped_ptr<SpdyHeaderBlock> headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultURL, msg_data_size));
+ spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kMsgDataSize));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
- const int32 initial_window_size =
- SpdySession::GetDefaultInitialWindowSize(GetParam());
+ const int32_t initial_window_size =
+ SpdySession::GetDefaultInitialWindowSize(GetProtocol());
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(msg_data_size, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
stream->Close();
EXPECT_FALSE(stream);
@@ -3805,9 +3888,9 @@ TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
EXPECT_EQ(OK, delegate.WaitForClose());
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(msg_data_size, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -3816,11 +3899,11 @@ TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
// can be written to the socket. The send window should then increase
// to its original value, i.e. we shouldn't "leak" send window bytes.
TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
- const int32 msg_data_size = 100;
- const std::string msg_data(msg_data_size, 'a');
+ const int32_t kMsgDataSize = 100;
+ const std::string msg_data(kMsgDataSize, 'a');
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
- kDefaultURL, 1, msg_data_size, MEDIUM, nullptr, 0));
+ kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0));
MockWrite writes[] = {
CreateMockWrite(*req, 0),
};
@@ -3850,13 +3933,13 @@ TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
stream->SetDelegate(&delegate);
scoped_ptr<SpdyHeaderBlock> headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultURL, msg_data_size));
+ spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kMsgDataSize));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
- const int32 initial_window_size =
- SpdySession::GetDefaultInitialWindowSize(GetParam());
+ const int32_t initial_window_size =
+ SpdySession::GetDefaultInitialWindowSize(GetProtocol());
EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
// Write request.
@@ -3866,9 +3949,9 @@ TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
// Read response, but do not run the message loop, so that the body is not
// written to the socket.
- data.CompleteRead();
+ data.Resume();
- EXPECT_EQ(initial_window_size - msg_data_size,
+ EXPECT_EQ(initial_window_size - kMsgDataSize,
session_->session_send_window_size_);
// Closing the stream should increase the session's send window.
@@ -3889,14 +3972,13 @@ TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) {
// Send data back and forth; the send and receive windows should
// change appropriately.
TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
- const int32 msg_data_size = 100;
- const std::string msg_data(msg_data_size, 'a');
+ const int32_t kMsgDataSize = 100;
+ const std::string msg_data(kMsgDataSize, 'a');
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
- kDefaultURL, 1, msg_data_size, MEDIUM, nullptr, 0));
- scoped_ptr<SpdyFrame> msg(
- spdy_util_.ConstructSpdyBodyFrame(
- 1, msg_data.data(), msg_data_size, false));
+ kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0));
+ scoped_ptr<SpdyFrame> msg(spdy_util_.ConstructSpdyBodyFrame(
+ 1, msg_data.data(), kMsgDataSize, false));
MockWrite writes[] = {
CreateMockWrite(*req, 0),
CreateMockWrite(*msg, 2),
@@ -3904,12 +3986,10 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
scoped_ptr<SpdyFrame> resp(
spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
- scoped_ptr<SpdyFrame> echo(
- spdy_util_.ConstructSpdyBodyFrame(
- 1, msg_data.data(), msg_data_size, false));
- scoped_ptr<SpdyFrame> window_update(
- spdy_util_.ConstructSpdyWindowUpdate(
- kSessionFlowControlStreamId, msg_data_size));
+ scoped_ptr<SpdyFrame> echo(spdy_util_.ConstructSpdyBodyFrame(
+ 1, msg_data.data(), kMsgDataSize, false));
+ scoped_ptr<SpdyFrame> window_update(spdy_util_.ConstructSpdyWindowUpdate(
+ kSessionFlowControlStreamId, kMsgDataSize));
MockRead reads[] = {
CreateMockRead(*resp, 1),
MockRead(ASYNC, ERR_IO_PENDING, 3),
@@ -3937,13 +4017,13 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
stream->SetDelegate(&delegate);
scoped_ptr<SpdyHeaderBlock> headers(
- spdy_util_.ConstructPostHeaderBlock(kDefaultURL, msg_data_size));
+ spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kMsgDataSize));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
- const int32 initial_window_size =
- SpdySession::GetDefaultInitialWindowSize(GetParam());
+ const int32_t initial_window_size =
+ SpdySession::GetDefaultInitialWindowSize(GetProtocol());
EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
@@ -3951,27 +4031,27 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
// Send request and message.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(initial_window_size - msg_data_size,
+ EXPECT_EQ(initial_window_size - kMsgDataSize,
session_->session_send_window_size_);
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
// Read echo.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(initial_window_size - msg_data_size,
+ EXPECT_EQ(initial_window_size - kMsgDataSize,
session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size - msg_data_size,
+ EXPECT_EQ(initial_window_size - kMsgDataSize,
session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
// Read window update.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size - msg_data_size,
+ EXPECT_EQ(initial_window_size - kMsgDataSize,
session_->session_recv_window_size_);
EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
@@ -3981,7 +4061,7 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
// receive window.
EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(msg_data_size, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
stream->Close();
EXPECT_FALSE(stream);
@@ -3990,9 +4070,9 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(msg_data_size, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -4001,8 +4081,7 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) {
// sure that a stream resumes after unstall.
void SpdySessionTest::RunResumeAfterUnstallTest(
const base::Callback<void(SpdyStream*)>& stall_function,
- const base::Callback<void(SpdyStream*, int32)>& unstall_function) {
-
+ const base::Callback<void(SpdyStream*, int32_t)>& unstall_function) {
session_deps_.host_resolver->set_synchronous_mode(true);
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
@@ -4027,8 +4106,6 @@ void SpdySessionTest::RunResumeAfterUnstallTest(
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
@@ -4043,7 +4120,7 @@ void SpdySessionTest::RunResumeAfterUnstallTest(
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream->GetUrlFromHeaders().spec());
@@ -4155,8 +4232,6 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
@@ -4183,8 +4258,8 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
+ MORE_DATA_TO_SEND));
EXPECT_TRUE(stream1->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream1->GetUrlFromHeaders().spec());
@@ -4194,8 +4269,8 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
+ MORE_DATA_TO_SEND));
EXPECT_TRUE(stream2->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream2->GetUrlFromHeaders().spec());
@@ -4296,8 +4371,6 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
@@ -4334,8 +4407,8 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
+ MORE_DATA_TO_SEND));
EXPECT_TRUE(stream1->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream1->GetUrlFromHeaders().spec());
@@ -4345,8 +4418,8 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
+ MORE_DATA_TO_SEND));
EXPECT_TRUE(stream2->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream2->GetUrlFromHeaders().spec());
@@ -4356,8 +4429,8 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
scoped_ptr<SpdyHeaderBlock> headers3(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream3->SendRequestHeaders(std::move(headers3),
+ MORE_DATA_TO_SEND));
EXPECT_TRUE(stream3->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream3->GetUrlFromHeaders().spec());
@@ -4389,7 +4462,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
EXPECT_TRUE(session_->IsStreamActive(stream_id2));
EXPECT_FALSE(session_->IsStreamActive(stream_id3));
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(stream2);
EXPECT_FALSE(session_);
@@ -4437,8 +4510,6 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
CreateNetworkSession();
CreateInsecureSpdySession();
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session_->flow_control_state());
base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
@@ -4465,8 +4536,8 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
scoped_ptr<SpdyHeaderBlock> headers1(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
+ MORE_DATA_TO_SEND));
EXPECT_TRUE(stream1->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream1->GetUrlFromHeaders().spec());
@@ -4476,8 +4547,8 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
scoped_ptr<SpdyHeaderBlock> headers2(
spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
+ MORE_DATA_TO_SEND));
EXPECT_TRUE(stream2->HasUrlFromHeaders());
EXPECT_EQ(kDefaultURL, stream2->GetUrlFromHeaders().spec());
@@ -4493,7 +4564,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
// Close the session (since we can't do it from within the delegate
// method, since it's in the stream's loop).
session_->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
@@ -4545,7 +4616,7 @@ TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
// Write request.
base::RunLoop().RunUntilIdle();
@@ -4555,7 +4626,7 @@ TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) {
// Read response headers & body. Body overflows the session window, and a
// goaway is written.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(ERR_SPDY_FLOW_CONTROL_ERROR, delegate.WaitForClose());
@@ -4632,7 +4703,7 @@ TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Run until 1st stream is activated.
@@ -4645,7 +4716,7 @@ TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
EXPECT_EQ(0u, session_->num_active_pushed_streams());
// Run until pushed stream is created.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4664,7 +4735,7 @@ TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
EXPECT_EQ(1u, session_->num_active_pushed_streams());
// Read EOF.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -4712,7 +4783,7 @@ TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Run until 1st stream is activated.
@@ -4725,7 +4796,7 @@ TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
EXPECT_EQ(0u, session_->num_active_pushed_streams());
// Run until pushed stream is created.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4733,7 +4804,7 @@ TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
EXPECT_EQ(1u, session_->num_active_pushed_streams());
// Reset incoming pushed stream.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4741,7 +4812,157 @@ TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
EXPECT_EQ(1u, session_->num_active_pushed_streams());
// Read EOF.
- data.CompleteRead();
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(session_);
+}
+
+// Tests that HTTP SPDY push streams that advertise an origin different from the
+// associated stream are accepted from a trusted SPDY proxy.
+TEST_P(SpdySessionTest, TrustedSpdyProxy) {
+ // Origin of kDefaultURL should be different from the origin of
+ // kHttpURLFromAnotherOrigin and kHttpsURLFromAnotherOrigin.
+ ASSERT_NE(GURL(kDefaultURL).host(), GURL(kHttpURLFromAnotherOrigin).host());
+ ASSERT_NE(GURL(kDefaultURL).host(), GURL(kHttpsURLFromAnotherOrigin).host());
+
+ // cross_origin_push contains HTTP resource for an origin different from the
+ // origin of kDefaultURL, and should be accepted.
+ scoped_ptr<SpdyFrame> cross_origin_push(spdy_util_.ConstructSpdyPush(
+ nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin));
+ // cross_origin_https_push contains HTTPS resource, and should be refused.
+ scoped_ptr<SpdyFrame> cross_origin_https_push(spdy_util_.ConstructSpdyPush(
+ nullptr, 0, 4, 1, kHttpsURLFromAnotherOrigin));
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 1),
+ CreateMockRead(*cross_origin_push, 2),
+ MockRead(ASYNC, ERR_IO_PENDING, 3),
+ CreateMockRead(*cross_origin_https_push, 4),
+ MockRead(ASYNC, ERR_IO_PENDING, 6),
+ MockRead(ASYNC, 0, 7),
+ };
+
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true));
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5),
+ };
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ session_deps_.trusted_spdy_proxy =
+ HostPortPair::FromURL(GURL(kDefaultURL)).ToString();
+
+ CreateNetworkSession();
+ CreateInsecureSpdySession();
+
+ base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream.get() != nullptr);
+ EXPECT_EQ(0u, spdy_stream->stream_id());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ EXPECT_EQ(0u, session_->num_active_streams());
+ EXPECT_EQ(1u, session_->num_created_streams());
+ EXPECT_EQ(0u, session_->num_pushed_streams());
+ EXPECT_EQ(0u, session_->num_active_pushed_streams());
+
+ scoped_ptr<SpdyHeaderBlock> headers(
+ spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
+ EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
+
+ // Run until 1st stream is activated.
+ EXPECT_EQ(0u, delegate.stream_id());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, delegate.stream_id());
+ EXPECT_EQ(1u, session_->num_active_streams());
+ EXPECT_EQ(0u, session_->num_created_streams());
+ EXPECT_EQ(0u, session_->num_pushed_streams());
+ EXPECT_EQ(0u, session_->num_active_pushed_streams());
+
+ // Run until pushed stream is created.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(2u, session_->num_active_streams());
+ EXPECT_EQ(0u, session_->num_created_streams());
+ EXPECT_EQ(1u, session_->num_pushed_streams());
+ EXPECT_EQ(1u, session_->num_active_pushed_streams());
+
+ // Reset incoming pushed stream.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(2u, session_->num_active_streams());
+ EXPECT_EQ(0u, session_->num_created_streams());
+ EXPECT_EQ(1u, session_->num_pushed_streams());
+ EXPECT_EQ(1u, session_->num_active_pushed_streams());
+
+ // Read EOF.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(session_);
+}
+
+// Tests that if the SPDY trusted proxy is not set, then push streams that
+// advertise an origin different from the associated stream are refused.
+TEST_P(SpdySessionTest, TrustedSpdyProxyNotSet) {
+ // Origin of kDefaultURL should be different from the origin of
+ // kHttpURLFromAnotherOrigin.
+ ASSERT_NE(GURL(kDefaultURL).host(), GURL(kHttpURLFromAnotherOrigin).host());
+
+ // cross_origin_push contains resource for an origin different from the
+ // origin of kDefaultURL, and should be refused.
+ scoped_ptr<SpdyFrame> cross_origin_push(spdy_util_.ConstructSpdyPush(
+ nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin));
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*cross_origin_push, 2),
+ MockRead(ASYNC, 0, 4),
+ };
+
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true));
+ scoped_ptr<SpdyFrame> rst(
+ spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
+ MockWrite writes[] = {
+ CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3),
+ };
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ CreateNetworkSession();
+ CreateInsecureSpdySession();
+
+ base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream.get() != nullptr);
+ EXPECT_EQ(0u, spdy_stream->stream_id());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ EXPECT_EQ(0u, session_->num_active_streams());
+ EXPECT_EQ(1u, session_->num_created_streams());
+ EXPECT_EQ(0u, session_->num_pushed_streams());
+ EXPECT_EQ(0u, session_->num_active_pushed_streams());
+
+ scoped_ptr<SpdyHeaderBlock> headers(
+ spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
+ EXPECT_TRUE(spdy_stream->HasUrlFromHeaders());
+
+ // Run until 1st stream is activated.
+ EXPECT_EQ(0u, delegate.stream_id());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, delegate.stream_id());
+ EXPECT_EQ(1u, session_->num_active_streams());
+ EXPECT_EQ(0u, session_->num_created_streams());
+ EXPECT_EQ(0u, session_->num_pushed_streams());
+ EXPECT_EQ(0u, session_->num_active_pushed_streams());
+
+ // Read EOF.
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -4757,7 +4978,7 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
spdy_util_.AddUrlToHeaderBlock("http://www.example.org/b.dat",
push_headers.get());
scoped_ptr<SpdyFrame> push_b(
- spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 4, 1));
+ spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 4, 1));
scoped_ptr<SpdyFrame> headers_b(
spdy_util_.ConstructSpdyPushHeaders(4, nullptr, 0));
MockRead reads[] = {
@@ -4800,7 +5021,7 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Run until 1st stream is activated.
@@ -4813,7 +5034,7 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
EXPECT_EQ(0u, session_->num_active_pushed_streams());
// Run until pushed stream is created.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4821,7 +5042,7 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
EXPECT_EQ(1u, session_->num_active_pushed_streams());
// Accept promised stream. It should not count towards pushed stream limit.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4830,7 +5051,7 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
// Reset last pushed stream upon headers reception as it is going to be 2nd,
// while we accept only one.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4838,7 +5059,7 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
EXPECT_EQ(1u, session_->num_active_pushed_streams());
// Read EOF.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
}
@@ -4852,7 +5073,7 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get());
scoped_ptr<SpdyFrame> push_promise(
- spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 2, 1));
+ spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 2, 1));
scoped_ptr<SpdyFrame> headers_frame(
spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));
MockRead reads[] = {
@@ -4892,7 +5113,7 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
- spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
// Run until 1st stream is activated.
@@ -4905,7 +5126,7 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
EXPECT_EQ(0u, session_->num_active_pushed_streams());
// Run until pushed stream is created.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4922,7 +5143,7 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
// Receive headers for pushed stream. Delegate will cancel the stream, ensure
// that all our counters are in consistent state.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, session_->num_active_streams());
EXPECT_EQ(0u, session_->num_created_streams());
@@ -4930,7 +5151,7 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
EXPECT_EQ(0u, session_->num_active_pushed_streams());
// Read EOF.
- data.CompleteRead();
+ data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(data.AllWriteDataConsumed());
EXPECT_TRUE(data.AllReadDataConsumed());
@@ -5087,9 +5308,9 @@ TEST(CanPoolTest, CanNotPoolAcrossETLDsWithChannelID) {
}
TEST(CanPoolTest, CanNotPoolWithBadPins) {
- uint8 primary_pin = 1;
- uint8 backup_pin = 2;
- uint8 bad_pin = 3;
+ uint8_t primary_pin = 1;
+ uint8_t backup_pin = 2;
+ uint8_t bad_pin = 3;
TransportSecurityState tss;
test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin);
@@ -5104,8 +5325,8 @@ TEST(CanPoolTest, CanNotPoolWithBadPins) {
}
TEST(CanPoolTest, CanPoolWithAcceptablePins) {
- uint8 primary_pin = 1;
- uint8 backup_pin = 2;
+ uint8_t primary_pin = 1;
+ uint8_t backup_pin = 2;
TransportSecurityState tss;
test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin);
diff --git a/chromium/net/spdy/spdy_stream.cc b/chromium/net/spdy/spdy_stream.cc
index 18f5fafcc00..4fedae416cb 100644
--- a/chromium/net/spdy/spdy_stream.cc
+++ b/chromium/net/spdy/spdy_stream.cc
@@ -4,6 +4,9 @@
#include "net/spdy/spdy_stream.h"
+#include <limits>
+#include <utility>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
@@ -31,19 +34,19 @@ scoped_ptr<base::Value> NetLogSpdyStreamErrorCallback(
dict->SetInteger("stream_id", static_cast<int>(stream_id));
dict->SetInteger("status", status);
dict->SetString("description", *description);
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogSpdyStreamWindowUpdateCallback(
SpdyStreamId stream_id,
- int32 delta,
- int32 window_size,
+ int32_t delta,
+ int32_t window_size,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", stream_id);
dict->SetInteger("delta", delta);
dict->SetInteger("window_size", window_size);
- return dict.Pass();
+ return std::move(dict);
}
bool ContainsUppercaseAscii(const std::string& str) {
@@ -87,8 +90,8 @@ SpdyStream::SpdyStream(SpdyStreamType type,
const base::WeakPtr<SpdySession>& session,
const GURL& url,
RequestPriority priority,
- int32 initial_send_window_size,
- int32 max_recv_window_size,
+ int32_t initial_send_window_size,
+ int32_t max_recv_window_size,
const BoundNetLog& net_log)
: type_(type),
stream_id_(0),
@@ -178,13 +181,13 @@ void SpdyStream::PushedStreamReplay() {
while (!pending_recv_data_.empty()) {
// Take ownership of the first element of |pending_recv_data_|.
- scoped_ptr<SpdyBuffer> buffer(pending_recv_data_.front());
- pending_recv_data_.weak_erase(pending_recv_data_.begin());
+ scoped_ptr<SpdyBuffer> buffer = std::move(pending_recv_data_.at(0));
+ pending_recv_data_.erase(pending_recv_data_.begin());
bool eof = (buffer == NULL);
CHECK(delegate_);
- delegate_->OnDataReceived(buffer.Pass());
+ delegate_->OnDataReceived(std::move(buffer));
// OnDataReceived() may have closed |this|.
if (!weak_this)
@@ -211,7 +214,7 @@ scoped_ptr<SpdyFrame> SpdyStream::ProduceSynStreamFrame() {
scoped_ptr<SpdyFrame> frame(session_->CreateSynStream(
stream_id_, priority_, flags, *request_headers_));
send_time_ = base::TimeTicks::Now();
- return frame.Pass();
+ return frame;
}
void SpdyStream::DetachDelegate() {
@@ -220,18 +223,18 @@ void SpdyStream::DetachDelegate() {
Cancel();
}
-void SpdyStream::AdjustSendWindowSize(int32 delta_window_size) {
- DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM);
-
+void SpdyStream::AdjustSendWindowSize(int32_t delta_window_size) {
if (IsClosed())
return;
// Check for wraparound.
if (send_window_size_ > 0) {
- DCHECK_LE(delta_window_size, kint32max - send_window_size_);
+ DCHECK_LE(delta_window_size,
+ std::numeric_limits<int32_t>::max() - send_window_size_);
}
if (send_window_size_ < 0) {
- DCHECK_GE(delta_window_size, kint32min - send_window_size_);
+ DCHECK_GE(delta_window_size,
+ std::numeric_limits<int32_t>::min() - send_window_size_);
}
send_window_size_ += delta_window_size;
PossiblyResumeIfSendStalled();
@@ -241,7 +244,6 @@ void SpdyStream::OnWriteBufferConsumed(
size_t frame_payload_size,
size_t consume_size,
SpdyBuffer::ConsumeSource consume_source) {
- DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM);
if (consume_source == SpdyBuffer::DISCARD) {
// If we're discarding a frame or part of it, increase the send
// window by the number of discarded bytes. (Although if we're
@@ -249,14 +251,13 @@ void SpdyStream::OnWriteBufferConsumed(
// error and we'll be tearing down the stream soon.)
size_t remaining_payload_bytes = std::min(consume_size, frame_payload_size);
DCHECK_GT(remaining_payload_bytes, 0u);
- IncreaseSendWindowSize(static_cast<int32>(remaining_payload_bytes));
+ IncreaseSendWindowSize(static_cast<int32_t>(remaining_payload_bytes));
}
// For consumed bytes, the send window is increased when we receive
// a WINDOW_UPDATE frame.
}
-void SpdyStream::IncreaseSendWindowSize(int32 delta_window_size) {
- DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM);
+void SpdyStream::IncreaseSendWindowSize(int32_t delta_window_size) {
DCHECK_GE(delta_window_size, 1);
// Ignore late WINDOW_UPDATEs.
@@ -265,7 +266,8 @@ void SpdyStream::IncreaseSendWindowSize(int32 delta_window_size) {
if (send_window_size_ > 0) {
// Check for overflow.
- int32 max_delta_window_size = kint32max - send_window_size_;
+ int32_t max_delta_window_size =
+ std::numeric_limits<int32_t>::max() - send_window_size_;
if (delta_window_size > max_delta_window_size) {
std::string desc = base::StringPrintf(
"Received WINDOW_UPDATE [delta: %d] for stream %d overflows "
@@ -286,9 +288,7 @@ void SpdyStream::IncreaseSendWindowSize(int32 delta_window_size) {
PossiblyResumeIfSendStalled();
}
-void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) {
- DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM);
-
+void SpdyStream::DecreaseSendWindowSize(int32_t delta_window_size) {
if (IsClosed())
return;
@@ -312,15 +312,13 @@ void SpdyStream::DecreaseSendWindowSize(int32 delta_window_size) {
void SpdyStream::OnReadBufferConsumed(
size_t consume_size,
SpdyBuffer::ConsumeSource consume_source) {
- DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM);
DCHECK_GE(consume_size, 1u);
- DCHECK_LE(consume_size, static_cast<size_t>(kint32max));
- IncreaseRecvWindowSize(static_cast<int32>(consume_size));
+ DCHECK_LE(consume_size,
+ static_cast<size_t>(std::numeric_limits<int32_t>::max()));
+ IncreaseRecvWindowSize(static_cast<int32_t>(consume_size));
}
-void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) {
- DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM);
-
+void SpdyStream::IncreaseRecvWindowSize(int32_t delta_window_size) {
// By the time a read is processed by the delegate, this stream may
// already be inactive.
if (!session_->IsStreamActive(stream_id_))
@@ -330,7 +328,8 @@ void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) {
DCHECK_GE(recv_window_size_, unacked_recv_window_bytes_);
DCHECK_GE(delta_window_size, 1);
// Check for overflow.
- DCHECK_LE(delta_window_size, kint32max - recv_window_size_);
+ DCHECK_LE(delta_window_size,
+ std::numeric_limits<int32_t>::max() - recv_window_size_);
recv_window_size_ += delta_window_size;
net_log_.AddEvent(
@@ -341,14 +340,13 @@ void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) {
unacked_recv_window_bytes_ += delta_window_size;
if (unacked_recv_window_bytes_ > max_recv_window_size_ / 2) {
session_->SendStreamWindowUpdate(
- stream_id_, static_cast<uint32>(unacked_recv_window_bytes_));
+ stream_id_, static_cast<uint32_t>(unacked_recv_window_bytes_));
unacked_recv_window_bytes_ = 0;
}
}
-void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) {
+void SpdyStream::DecreaseRecvWindowSize(int32_t delta_window_size) {
DCHECK(session_->IsStreamActive(stream_id_));
- DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM);
DCHECK_GE(delta_window_size, 1);
// The receiving window size as the peer knows it is
@@ -453,6 +451,12 @@ int SpdyStream::OnAdditionalResponseHeadersReceived(
delegate_->OnTrailers(additional_response_headers);
return OK;
}
+ if (type_ == SPDY_BIDIRECTIONAL_STREAM) {
+ DCHECK_EQ(RESPONSE_HEADERS_ARE_COMPLETE, response_headers_status_);
+ response_headers_status_ = TRAILERS_RECEIVED;
+ delegate_->OnTrailers(additional_response_headers);
+ return OK;
+ }
if (type_ == SPDY_PUSH_STREAM &&
response_headers_status_ == RESPONSE_HEADERS_ARE_COMPLETE) {
session_->ResetStream(
@@ -484,7 +488,7 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
// It should be valid for this to happen in the server push case.
// We'll return received data when delegate gets attached to the stream.
if (buffer) {
- pending_recv_data_.push_back(buffer.Pass());
+ pending_recv_data_.push_back(std::move(buffer));
} else {
pending_recv_data_.push_back(NULL);
// Note: we leave the stream open in the session until the stream
@@ -494,8 +498,10 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
}
if (response_headers_status_ == TRAILERS_RECEIVED && buffer) {
- // TRAILERS_RECEIVED is only used in SPDY_REQUEST_RESPONSE_STREAM.
- DCHECK_EQ(type_, SPDY_REQUEST_RESPONSE_STREAM);
+ // TRAILERS_RECEIVED is only used in SPDY_REQUEST_RESPONSE_STREAM and
+ // SPDY_BIDIRECTIONAL_STREAM.
+ DCHECK(type_ == SPDY_REQUEST_RESPONSE_STREAM ||
+ type_ == SPDY_BIDIRECTIONAL_STREAM);
session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR,
"Data received after trailers");
return;
@@ -527,37 +533,33 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
size_t length = buffer->GetRemainingSize();
DCHECK_LE(length, session_->GetDataFrameMaximumPayload());
- if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) {
- base::WeakPtr<SpdyStream> weak_this = GetWeakPtr();
- // May close the stream.
- DecreaseRecvWindowSize(static_cast<int32>(length));
- if (!weak_this)
- return;
- buffer->AddConsumeCallback(
- base::Bind(&SpdyStream::OnReadBufferConsumed, GetWeakPtr()));
- }
+ base::WeakPtr<SpdyStream> weak_this = GetWeakPtr();
+ // May close the stream.
+ DecreaseRecvWindowSize(static_cast<int32_t>(length));
+ if (!weak_this)
+ return;
+ buffer->AddConsumeCallback(
+ base::Bind(&SpdyStream::OnReadBufferConsumed, GetWeakPtr()));
// Track our bandwidth.
recv_bytes_ += length;
recv_last_byte_time_ = base::TimeTicks::Now();
// May close |this|.
- delegate_->OnDataReceived(buffer.Pass());
+ delegate_->OnDataReceived(std::move(buffer));
}
void SpdyStream::OnPaddingConsumed(size_t len) {
- if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) {
- // Decrease window size because padding bytes are received.
- // Increase window size because padding bytes are consumed (by discarding).
- // Net result: |unacked_recv_window_bytes_| increases by |len|,
- // |recv_window_size_| does not change.
- base::WeakPtr<SpdyStream> weak_this = GetWeakPtr();
- // May close the stream.
- DecreaseRecvWindowSize(static_cast<int32>(len));
- if (!weak_this)
- return;
- IncreaseRecvWindowSize(static_cast<int32>(len));
- }
+ // Decrease window size because padding bytes are received.
+ // Increase window size because padding bytes are consumed (by discarding).
+ // Net result: |unacked_recv_window_bytes_| increases by |len|,
+ // |recv_window_size_| does not change.
+ base::WeakPtr<SpdyStream> weak_this = GetWeakPtr();
+ // May close the stream.
+ DecreaseRecvWindowSize(static_cast<int32_t>(len));
+ if (!weak_this)
+ return;
+ IncreaseRecvWindowSize(static_cast<int32_t>(len));
}
void SpdyStream::OnFrameWriteComplete(SpdyFrameType frame_type,
@@ -693,7 +695,7 @@ int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers,
CHECK(!request_headers_);
CHECK(!pending_send_data_.get());
CHECK_EQ(io_state_, STATE_IDLE);
- request_headers_ = request_headers.Pass();
+ request_headers_ = std::move(request_headers);
pending_send_status_ = send_status;
session_->EnqueueStreamWrite(
GetWeakPtr(), SYN_STREAM,
@@ -729,7 +731,7 @@ void SpdyStream::PossiblyResumeIfSendStalled() {
if (send_stalled_by_flow_control_ && !session_->IsSendStalled() &&
send_window_size_ > 0) {
net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_FLOW_CONTROL_UNSTALLED,
- NetLog::IntegerCallback("stream_id", stream_id_));
+ NetLog::IntCallback("stream_id", stream_id_));
send_stalled_by_flow_control_ = false;
QueueNextDataFrame();
}
@@ -844,30 +846,27 @@ void SpdyStream::QueueNextDataFrame() {
if (!data_buffer)
return;
- if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) {
- DCHECK_GE(data_buffer->GetRemainingSize(),
- session_->GetDataFrameMinimumSize());
- size_t payload_size =
- data_buffer->GetRemainingSize() - session_->GetDataFrameMinimumSize();
- DCHECK_LE(payload_size, session_->GetDataFrameMaximumPayload());
-
- // Send window size is based on payload size, so nothing to do if this is
- // just a FIN with no payload.
- if (payload_size != 0) {
- DecreaseSendWindowSize(static_cast<int32>(payload_size));
- // This currently isn't strictly needed, since write frames are
- // discarded only if the stream is about to be closed. But have it
- // here anyway just in case this changes.
- data_buffer->AddConsumeCallback(
- base::Bind(&SpdyStream::OnWriteBufferConsumed,
- GetWeakPtr(), payload_size));
- }
+ DCHECK_GE(data_buffer->GetRemainingSize(),
+ session_->GetDataFrameMinimumSize());
+ size_t payload_size =
+ data_buffer->GetRemainingSize() - session_->GetDataFrameMinimumSize();
+ DCHECK_LE(payload_size, session_->GetDataFrameMaximumPayload());
+
+ // Send window size is based on payload size, so nothing to do if this is
+ // just a FIN with no payload.
+ if (payload_size != 0) {
+ DecreaseSendWindowSize(static_cast<int32_t>(payload_size));
+ // This currently isn't strictly needed, since write frames are
+ // discarded only if the stream is about to be closed. But have it
+ // here anyway just in case this changes.
+ data_buffer->AddConsumeCallback(base::Bind(
+ &SpdyStream::OnWriteBufferConsumed, GetWeakPtr(), payload_size));
}
session_->EnqueueStreamWrite(
GetWeakPtr(), DATA,
scoped_ptr<SpdyBufferProducer>(
- new SimpleBufferProducer(data_buffer.Pass())));
+ new SimpleBufferProducer(std::move(data_buffer))));
}
int SpdyStream::MergeWithResponseHeaders(
diff --git a/chromium/net/spdy/spdy_stream.h b/chromium/net/spdy/spdy_stream.h
index 011363ab5fe..43629957cb0 100644
--- a/chromium/net/spdy/spdy_stream.h
+++ b/chromium/net/spdy/spdy_stream.h
@@ -5,16 +5,16 @@
#ifndef NET_SPDY_SPDY_STREAM_H_
#define NET_SPDY_SPDY_STREAM_H_
+#include <stddef.h>
#include <stdint.h>
#include <deque>
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "net/base/io_buffer.h"
#include "net/base/net_export.h"
@@ -170,8 +170,8 @@ class NET_EXPORT_PRIVATE SpdyStream {
const base::WeakPtr<SpdySession>& session,
const GURL& url,
RequestPriority priority,
- int32 initial_send_window_size,
- int32 max_recv_window_size,
+ int32_t initial_send_window_size,
+ int32_t max_recv_window_size,
const BoundNetLog& net_log);
~SpdyStream();
@@ -199,9 +199,9 @@ class NET_EXPORT_PRIVATE SpdyStream {
RequestPriority priority() const { return priority_; }
- int32 send_window_size() const { return send_window_size_; }
+ int32_t send_window_size() const { return send_window_size_; }
- int32 recv_window_size() const { return recv_window_size_; }
+ int32_t recv_window_size() const { return recv_window_size_; }
bool send_stalled_by_flow_control() const {
return send_stalled_by_flow_control_;
@@ -221,7 +221,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
// closed.
//
// If stream flow control is turned off, this must not be called.
- void AdjustSendWindowSize(int32 delta_window_size);
+ void AdjustSendWindowSize(int32_t delta_window_size);
// Called when bytes are consumed from a SpdyBuffer for a DATA frame
// that is to be written or is being written. Increases the send
@@ -242,7 +242,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
// nothing if the stream is already closed.
//
// If stream flow control is turned off, this must not be called.
- void IncreaseSendWindowSize(int32 delta_window_size);
+ void IncreaseSendWindowSize(int32_t delta_window_size);
// If stream flow control is turned on, called by the session to
// decrease this stream's send window size by |delta_window_size|,
@@ -251,7 +251,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
// to go negative. Does nothing if the stream is already closed.
//
// If stream flow control is turned off, this must not be called.
- void DecreaseSendWindowSize(int32 delta_window_size);
+ void DecreaseSendWindowSize(int32_t delta_window_size);
// Called when bytes are consumed by the delegate from a SpdyBuffer
// containing received data. Increases the receive window size
@@ -268,7 +268,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
// stream is not active.
//
// If stream flow control is turned off, this must not be called.
- void IncreaseRecvWindowSize(int32 delta_window_size);
+ void IncreaseRecvWindowSize(int32_t delta_window_size);
// Called by OnDataReceived or OnPaddingConsumed (which are in turn called by
// the session) to decrease this stream's receive window size by
@@ -277,7 +277,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
//
// If stream flow control is turned off or the stream is not active,
// this must not be called.
- void DecreaseRecvWindowSize(int32 delta_window_size);
+ void DecreaseRecvWindowSize(int32_t delta_window_size);
int GetPeerAddress(IPEndPoint* address) const;
int GetLocalAddress(IPEndPoint* address) const;
@@ -426,7 +426,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
void AddRawReceivedBytes(size_t received_bytes);
void AddRawSentBytes(size_t sent_bytes);
- int64 raw_received_bytes() const { return raw_received_bytes_; }
+ int64_t raw_received_bytes() const { return raw_received_bytes_; }
int64_t raw_sent_bytes() const { return raw_sent_bytes_; }
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
@@ -510,22 +510,22 @@ class NET_EXPORT_PRIVATE SpdyStream {
bool send_stalled_by_flow_control_;
// Current send window size.
- int32 send_window_size_;
+ int32_t send_window_size_;
// Maximum receive window size. Each time a WINDOW_UPDATE is sent, it
// restores the receive window size to this value.
- int32 max_recv_window_size_;
+ int32_t max_recv_window_size_;
// Sum of |session_unacked_recv_window_bytes_| and current receive window
// size.
// TODO(bnc): Rename or change semantics so that |window_size_| is actual
// window size.
- int32 recv_window_size_;
+ int32_t recv_window_size_;
// When bytes are consumed, SpdyIOBuffer destructor calls back to SpdySession,
// and this member keeps count of them until the corresponding WINDOW_UPDATEs
// are sent.
- int32 unacked_recv_window_bytes_;
+ int32_t unacked_recv_window_bytes_;
const base::WeakPtr<SpdySession> session_;
@@ -547,7 +547,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
// after the data is fully read. Specifically, data received before the
// delegate is attached must be buffered and later replayed. A remote FIN
// is represented by a final, zero-length buffer.
- ScopedVector<SpdyBuffer> pending_recv_data_;
+ std::vector<scoped_ptr<SpdyBuffer>> pending_recv_data_;
// The time at which the request was made that resulted in this response.
// For cached responses, this time could be "far" in the past.
@@ -571,7 +571,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
// Number of bytes that have been received on this stream, including frame
// overhead and headers.
- int64 raw_received_bytes_;
+ int64_t raw_received_bytes_;
// Number of bytes that have been sent on this stream, including frame
// overhead and headers.
int64_t raw_sent_bytes_;
diff --git a/chromium/net/spdy/spdy_stream_test_util.cc b/chromium/net/spdy/spdy_stream_test_util.cc
index 4ea4f4b9148..e0d8e69ada0 100644
--- a/chromium/net/spdy/spdy_stream_test_util.cc
+++ b/chromium/net/spdy/spdy_stream_test_util.cc
@@ -5,6 +5,7 @@
#include "net/spdy/spdy_stream_test_util.h"
#include <cstddef>
+#include <utility>
#include "base/stl_util.h"
#include "net/base/completion_callback.h"
@@ -66,7 +67,7 @@ SpdyResponseHeadersStatus StreamDelegateBase::OnResponseHeadersUpdated(
void StreamDelegateBase::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
if (buffer)
- received_data_queue_.Enqueue(buffer.Pass());
+ received_data_queue_.Enqueue(std::move(buffer));
}
void StreamDelegateBase::OnDataSent() {}
diff --git a/chromium/net/spdy/spdy_stream_unittest.cc b/chromium/net/spdy/spdy_stream_unittest.cc
index 044be4bd238..7177651411e 100644
--- a/chromium/net/spdy/spdy_stream_unittest.cc
+++ b/chromium/net/spdy/spdy_stream_unittest.cc
@@ -2,13 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "net/spdy/spdy_stream.h"
+
+#include <stdint.h>
#include <cstddef>
+#include <limits>
#include <string>
+#include <utility>
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/stl_util.h"
+#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "net/base/completion_callback.h"
#include "net/base/request_priority.h"
@@ -21,7 +26,6 @@
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_session.h"
-#include "net/spdy/spdy_stream.h"
#include "net/spdy/spdy_stream_test_util.h"
#include "net/spdy/spdy_test_util_common.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -34,32 +38,63 @@ namespace test {
namespace {
+enum TestCase {
+ // Test using the SPDY/3.1 protocol.
+ kTestCaseSPDY31,
+
+ // Test using the HTTP/2 protocol, without specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2NoPriorityDependencies,
+
+ // Test using the HTTP/2 protocol, specifying a stream
+ // dependency based on the RequestPriority.
+ kTestCaseHTTP2PriorityDependencies
+};
+
const char kStreamUrl[] = "http://www.example.org/";
const char kPostBody[] = "\0hello!\xff";
const size_t kPostBodyLength = arraysize(kPostBody);
const base::StringPiece kPostBodyStringPiece(kPostBody, kPostBodyLength);
+} // namespace
+
class SpdyStreamTest : public ::testing::Test,
- public ::testing::WithParamInterface<NextProto> {
+ public ::testing::WithParamInterface<TestCase> {
protected:
// A function that takes a SpdyStream and the number of bytes which
// will unstall the next frame completely.
- typedef base::Callback<void(const base::WeakPtr<SpdyStream>&, int32)>
+ typedef base::Callback<void(const base::WeakPtr<SpdyStream>&, int32_t)>
UnstallFunction;
SpdyStreamTest()
- : spdy_util_(GetParam()),
- session_deps_(GetParam()),
- offset_(0) {}
+ : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
+ session_deps_(GetProtocol()),
+ session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
+ offset_(0) {
+ SpdySession::SetPriorityDependencyDefaultForTesting(
+ GetDependenciesFromPriority());
+ }
+
+ ~SpdyStreamTest() {
+ SpdySession::SetPriorityDependencyDefaultForTesting(false);
+ }
base::WeakPtr<SpdySession> CreateDefaultSpdySession() {
SpdySessionKey key(HostPortPair("www.example.org", 80),
ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
- return CreateInsecureSpdySession(session_, key, BoundNetLog());
+ return CreateInsecureSpdySession(session_.get(), key, BoundNetLog());
}
void TearDown() override { base::MessageLoop::current()->RunUntilIdle(); }
+ NextProto GetProtocol() const {
+ return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
+ }
+
+ bool GetDependenciesFromPriority() const {
+ return GetParam() == kTestCaseHTTP2PriorityDependencies;
+ }
+
void RunResumeAfterUnstallRequestResponseTest(
const UnstallFunction& unstall_function);
@@ -81,17 +116,21 @@ class SpdyStreamTest : public ::testing::Test,
reads_.push_back(MockRead(ASYNC, 0, offset_++));
}
- MockRead* GetReads() {
- return vector_as_array(&reads_);
+ void AddWritePause() {
+ writes_.push_back(MockWrite(ASYNC, ERR_IO_PENDING, offset_++));
+ }
+
+ void AddReadPause() {
+ reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING, offset_++));
}
+ MockRead* GetReads() { return reads_.data(); }
+
size_t GetNumReads() const {
return reads_.size();
}
- MockWrite* GetWrites() {
- return vector_as_array(&writes_);
- }
+ MockWrite* GetWrites() { return writes_.data(); }
int GetNumWrites() const {
return writes_.size();
@@ -99,7 +138,7 @@ class SpdyStreamTest : public ::testing::Test,
SpdyTestUtil spdy_util_;
SpdySessionDependencies session_deps_;
- scoped_refptr<HttpNetworkSession> session_;
+ scoped_ptr<HttpNetworkSession> session_;
private:
// Used by Add{Read,Write}() above.
@@ -108,17 +147,15 @@ class SpdyStreamTest : public ::testing::Test,
int offset_;
};
-INSTANTIATE_TEST_CASE_P(NextProto,
+INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
SpdyStreamTest,
- testing::Values(kProtoSPDY31,
- kProtoHTTP2));
+ testing::Values(kTestCaseSPDY31,
+ kTestCaseHTTP2NoPriorityDependencies,
+ kTestCaseHTTP2PriorityDependencies));
TEST_P(SpdyStreamTest, SendDataAfterOpen) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
@@ -138,12 +175,12 @@ TEST_P(SpdyStreamTest, SendDataAfterOpen) {
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -160,11 +197,10 @@ TEST_P(SpdyStreamTest, SendDataAfterOpen) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(GetNumReads() + GetNumWrites());
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
EXPECT_TRUE(delegate.send_headers_completed());
@@ -197,9 +233,6 @@ class StreamDelegateWithTrailers : public test::StreamDelegateWithBody {
TEST_P(SpdyStreamTest, Trailers) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
AddWrite(*req);
@@ -222,12 +255,12 @@ TEST_P(SpdyStreamTest, Trailers) {
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -243,11 +276,10 @@ TEST_P(SpdyStreamTest, Trailers) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(GetNumReads() + GetNumWrites());
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
EXPECT_TRUE(delegate.send_headers_completed());
@@ -261,17 +293,14 @@ TEST_P(SpdyStreamTest, Trailers) {
}
TEST_P(SpdyStreamTest, PushedStream) {
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> spdy_session(CreateDefaultSpdySession());
@@ -307,7 +336,7 @@ TEST_P(SpdyStreamTest, PushedStream) {
StreamDelegateDoNothing delegate(stream.GetWeakPtr());
stream.SetDelegate(&delegate);
- data.RunFor(GetNumReads() + GetNumWrites());
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy_util_.GetStatusKey()));
EXPECT_EQ("beta", delegate.GetResponseHeaderValue("alpha"));
@@ -318,9 +347,6 @@ TEST_P(SpdyStreamTest, PushedStream) {
TEST_P(SpdyStreamTest, StreamError) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
@@ -342,12 +368,12 @@ TEST_P(SpdyStreamTest, StreamError) {
BoundTestNetLog log;
- DeterministicSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -364,11 +390,10 @@ TEST_P(SpdyStreamTest, StreamError) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(GetNumReads() + GetNumWrites());
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
const SpdyStreamId stream_id = delegate.stream_id();
@@ -399,9 +424,6 @@ TEST_P(SpdyStreamTest, StreamError) {
TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
@@ -424,12 +446,12 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -447,11 +469,10 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(GetNumReads() + GetNumWrites());
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
EXPECT_TRUE(delegate.send_headers_completed());
@@ -466,9 +487,6 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
@@ -487,12 +505,12 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(), GetWrites(),
- GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -510,11 +528,10 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(GetNumReads() + GetNumWrites());
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
EXPECT_TRUE(delegate.send_headers_completed());
@@ -528,9 +545,6 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
TEST_P(SpdyStreamTest, UpperCaseHeaders) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> syn(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
AddWrite(*syn);
@@ -546,12 +560,12 @@ TEST_P(SpdyStreamTest, UpperCaseHeaders) {
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -567,13 +581,11 @@ TEST_P(SpdyStreamTest, UpperCaseHeaders) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kStreamUrl));
- EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
+ NO_MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(4);
-
EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, delegate.WaitForClose());
}
@@ -582,9 +594,6 @@ TEST_P(SpdyStreamTest, UpperCaseHeaders) {
TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> syn(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
AddWrite(*syn);
@@ -602,14 +611,16 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) {
spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
AddWrite(*rst);
+ AddReadPause();
+
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -625,18 +636,18 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kStreamUrl));
- EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
+ NO_MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(4);
+ data.RunUntilPaused();
base::WeakPtr<SpdyStream> push_stream;
EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog()));
EXPECT_FALSE(push_stream);
- data.RunFor(1);
+ data.Resume();
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
}
@@ -646,9 +657,6 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) {
TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> syn(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
AddWrite(*syn);
@@ -661,30 +669,29 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) {
push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
AddRead(*push);
+ AddReadPause();
+
scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
(*late_headers)["X-UpperCase"] = "yes";
- scoped_ptr<SpdyFrame> headers_frame(
- spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
- false,
- 2,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> headers_frame(spdy_util_.ConstructSpdyControlFrame(
+ std::move(late_headers), false, 2, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
AddRead(*headers_frame);
+ AddWritePause();
+
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
AddWrite(*rst);
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -700,23 +707,24 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kStreamUrl));
- EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
+ NO_MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(3);
+ data.RunUntilPaused();
base::WeakPtr<SpdyStream> push_stream;
EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog()));
EXPECT_TRUE(push_stream);
- data.RunFor(1);
+ data.Resume();
+ data.RunUntilPaused();
EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog()));
EXPECT_FALSE(push_stream);
- data.RunFor(2);
+ data.Resume();
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
}
@@ -726,9 +734,6 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) {
TEST_P(SpdyStreamTest, DuplicateHeaders) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> syn(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
AddWrite(*syn);
@@ -741,30 +746,29 @@ TEST_P(SpdyStreamTest, DuplicateHeaders) {
push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
AddRead(*push);
+ AddReadPause();
+
scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
(*late_headers)[spdy_util_.GetStatusKey()] = "500 Server Error";
- scoped_ptr<SpdyFrame> headers_frame(
- spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
- false,
- 2,
- LOWEST,
- HEADERS,
- CONTROL_FLAG_NONE,
- 0));
+ scoped_ptr<SpdyFrame> headers_frame(spdy_util_.ConstructSpdyControlFrame(
+ std::move(late_headers), false, 2, LOWEST, HEADERS, CONTROL_FLAG_NONE,
+ 0));
AddRead(*headers_frame);
+ AddReadPause();
+
scoped_ptr<SpdyFrame> rst(
spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
AddWrite(*rst);
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -780,41 +784,39 @@ TEST_P(SpdyStreamTest, DuplicateHeaders) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kStreamUrl));
- EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
+ NO_MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(3);
+ data.RunUntilPaused();
base::WeakPtr<SpdyStream> push_stream;
EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog()));
EXPECT_TRUE(push_stream);
- data.RunFor(1);
+ data.Resume();
+ data.RunUntilPaused();
EXPECT_EQ(OK, session->GetPushStream(url, &push_stream, BoundNetLog()));
EXPECT_FALSE(push_stream);
- data.RunFor(2);
+ data.Resume();
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
}
-// The tests below are only for SPDY/3 and above.
-
// Call IncreaseSendWindowSize on a stream with a large enough delta
-// to overflow an int32. The SpdyStream should handle that case
+// to overflow an int32_t. The SpdyStream should handle that case
// gracefully.
TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
AddWrite(*req);
+ AddReadPause();
+
// Triggered by the overflowing call to IncreaseSendWindowSize
// below.
scoped_ptr<SpdyFrame> rst(
@@ -825,12 +827,12 @@ TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
BoundTestNetLog log;
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
GURL url(kStreamUrl);
@@ -845,19 +847,21 @@ TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(1);
+ data.RunUntilPaused();
- int32 old_send_window_size = stream->send_window_size();
+ int32_t old_send_window_size = stream->send_window_size();
ASSERT_GT(old_send_window_size, 0);
- int32 delta_window_size = kint32max - old_send_window_size + 1;
+ int32_t delta_window_size =
+ std::numeric_limits<int32_t>::max() - old_send_window_size + 1;
stream->IncreaseSendWindowSize(delta_window_size);
EXPECT_EQ(NULL, stream.get());
- data.RunFor(2);
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, delegate.WaitForClose());
}
@@ -874,14 +878,14 @@ void StallStream(const base::WeakPtr<SpdyStream>& stream) {
}
void IncreaseStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
- int32 delta_window_size) {
+ int32_t delta_window_size) {
EXPECT_TRUE(stream->send_stalled_by_flow_control());
stream->IncreaseSendWindowSize(delta_window_size);
EXPECT_FALSE(stream->send_stalled_by_flow_control());
}
void AdjustStreamSendWindowSize(const base::WeakPtr<SpdyStream>& stream,
- int32 delta_window_size) {
+ int32_t delta_window_size) {
// Make sure that negative adjustments are handled properly.
EXPECT_TRUE(stream->send_stalled_by_flow_control());
stream->AdjustSendWindowSize(-delta_window_size);
@@ -899,9 +903,6 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
const UnstallFunction& unstall_function) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
@@ -916,12 +917,12 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -939,13 +940,13 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
StallStream(stream);
- data.RunFor(1);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(stream->send_stalled_by_flow_control());
@@ -953,8 +954,6 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
EXPECT_FALSE(stream->send_stalled_by_flow_control());
- data.RunFor(3);
-
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
EXPECT_TRUE(delegate.send_headers_completed());
@@ -980,14 +979,13 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
const UnstallFunction& unstall_function) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
AddWrite(*req);
+ AddReadPause();
+
scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
AddRead(*resp);
@@ -1001,12 +999,12 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -1023,17 +1021,18 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength));
EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND));
+ stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- data.RunFor(1);
+ data.RunUntilPaused();
EXPECT_FALSE(stream->send_stalled_by_flow_control());
StallStream(stream);
- data.RunFor(1);
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(stream->send_stalled_by_flow_control());
@@ -1041,8 +1040,6 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
EXPECT_FALSE(stream->send_stalled_by_flow_control());
- data.RunFor(3);
-
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
EXPECT_TRUE(delegate.send_headers_completed());
@@ -1066,29 +1063,32 @@ TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) {
TEST_P(SpdyStreamTest, ReceivedBytes) {
GURL url(kStreamUrl);
- session_ =
- SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
-
scoped_ptr<SpdyFrame> syn(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
AddWrite(*syn);
+ AddReadPause();
+
scoped_ptr<SpdyFrame>
reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
AddRead(*reply);
+ AddReadPause();
+
scoped_ptr<SpdyFrame> msg(
spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
AddRead(*msg);
+ AddReadPause();
+
AddReadEOF();
- DeterministicSocketData data(GetReads(), GetNumReads(),
- GetWrites(), GetNumWrites());
+ SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(),
+ GetNumWrites());
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
@@ -1104,31 +1104,38 @@ TEST_P(SpdyStreamTest, ReceivedBytes) {
scoped_ptr<SpdyHeaderBlock> headers(
spdy_util_.ConstructGetHeaderBlock(kStreamUrl));
- EXPECT_EQ(ERR_IO_PENDING,
- stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND));
+ EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
+ NO_MORE_DATA_TO_SEND));
EXPECT_TRUE(stream->HasUrlFromHeaders());
EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec());
- int64 reply_frame_len = reply->size();
- int64 data_header_len = spdy_util_.CreateFramer(false)
- ->GetDataFrameMinimumSize();
- int64 data_frame_len = data_header_len + kPostBodyLength;
- int64 response_len = reply_frame_len + data_frame_len;
+ int64_t reply_frame_len = reply->size();
+ int64_t data_header_len =
+ spdy_util_.CreateFramer(false)->GetDataFrameMinimumSize();
+ int64_t data_frame_len = data_header_len + kPostBodyLength;
+ int64_t response_len = reply_frame_len + data_frame_len;
EXPECT_EQ(0, stream->raw_received_bytes());
- data.RunFor(1); // SYN
+
+ // SYN
+ data.RunUntilPaused();
EXPECT_EQ(0, stream->raw_received_bytes());
- data.RunFor(1); // REPLY
+
+ // REPLY
+ data.Resume();
+ data.RunUntilPaused();
EXPECT_EQ(reply_frame_len, stream->raw_received_bytes());
- data.RunFor(1); // DATA
+
+ // DATA
+ data.Resume();
+ data.RunUntilPaused();
EXPECT_EQ(response_len, stream->raw_received_bytes());
- data.RunFor(1); // FIN
+ // FIN
+ data.Resume();
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
}
-} // namespace
-
} // namespace test
} // namespace net
diff --git a/chromium/net/spdy/spdy_test_util_common.cc b/chromium/net/spdy/spdy_test_util_common.cc
index 8755cc06c70..6a287948021 100644
--- a/chromium/net/spdy/spdy_test_util_common.cc
+++ b/chromium/net/spdy/spdy_test_util_common.cc
@@ -4,9 +4,12 @@
#include "net/spdy/spdy_test_util_common.h"
+#include <stdint.h>
#include <cstddef>
+#include <utility>
#include "base/compiler_specific.h"
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -61,51 +64,21 @@ NextProtoVector SpdyNextProtos() {
}
// Chop a frame into an array of MockWrites.
-// |data| is the frame to chop.
-// |length| is the length of the frame to chop.
-// |num_chunks| is the number of chunks to create.
-MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks) {
- MockWrite* chunks = new MockWrite[num_chunks];
- int chunk_size = length / num_chunks;
- for (int index = 0; index < num_chunks; index++) {
- const char* ptr = data + (index * chunk_size);
- if (index == num_chunks - 1)
- chunk_size += length % chunk_size; // The last chunk takes the remainder.
- chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
- }
- return chunks;
-}
-
-// Chop a SpdyFrame into an array of MockWrites.
// |frame| is the frame to chop.
// |num_chunks| is the number of chunks to create.
MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks) {
- return ChopWriteFrame(frame.data(), frame.size(), num_chunks);
-}
-
-// Chop a frame into an array of MockReads.
-// |data| is the frame to chop.
-// |length| is the length of the frame to chop.
-// |num_chunks| is the number of chunks to create.
-MockRead* ChopReadFrame(const char* data, int length, int num_chunks) {
- MockRead* chunks = new MockRead[num_chunks];
- int chunk_size = length / num_chunks;
+ MockWrite* chunks = new MockWrite[num_chunks];
+ int chunk_size = frame.size() / num_chunks;
for (int index = 0; index < num_chunks; index++) {
- const char* ptr = data + (index * chunk_size);
+ const char* ptr = frame.data() + (index * chunk_size);
if (index == num_chunks - 1)
- chunk_size += length % chunk_size; // The last chunk takes the remainder.
- chunks[index] = MockRead(ASYNC, ptr, chunk_size);
+ chunk_size +=
+ frame.size() % chunk_size; // The last chunk takes the remainder.
+ chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
}
return chunks;
}
-// Chop a SpdyFrame into an array of MockReads.
-// |frame| is the frame to chop.
-// |num_chunks| is the number of chunks to create.
-MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks) {
- return ChopReadFrame(frame.data(), frame.size(), num_chunks);
-}
-
// Adds headers and values to a map.
// |extra_headers| is an array of { name, value } pairs, arranged as strings
// where the even entries are the header names, and the odd entries are the
@@ -185,14 +158,16 @@ MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode) {
// Combines the given SpdyFrames into the given char array and returns
// the total length.
-int CombineFrames(const SpdyFrame** frames, int num_frames,
- char* buff, int buff_len) {
+int CombineFrames(const SpdyFrame** frames,
+ int num_frames,
+ char* buf,
+ int buf_len) {
int total_len = 0;
for (int i = 0; i < num_frames; ++i) {
total_len += frames[i]->size();
}
- DCHECK_LE(total_len, buff_len);
- char* ptr = buff;
+ DCHECK_LE(total_len, buf_len);
+ char* ptr = buf;
for (int i = 0; i < num_frames; ++i) {
int len = frames[i]->size();
memcpy(ptr, frames[i]->data(), len);
@@ -245,13 +220,19 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
size_t len,
bool fin) override {}
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {}
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override {
+ return nullptr;
+ }
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override {}
void OnSettings(bool clear_persisted) override {}
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override {}
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {}
void OnPing(SpdyPingId unique_id, bool is_ack) override {}
void OnRstStream(SpdyStreamId stream_id,
SpdyRstStreamStatus status) override {}
void OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) override {}
+ SpdyGoAwayStatus status,
+ StringPiece debug_data) override {}
void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {}
void OnPushPromise(SpdyStreamId stream_id,
SpdyStreamId promised_stream_id,
@@ -315,10 +296,10 @@ MockECSignatureCreator::MockECSignatureCreator(crypto::ECPrivateKey* key)
: key_(key) {
}
-bool MockECSignatureCreator::Sign(const uint8* data,
+bool MockECSignatureCreator::Sign(const uint8_t* data,
int data_len,
- std::vector<uint8>* signature) {
- std::vector<uint8> private_key_value;
+ std::vector<uint8_t>* signature) {
+ std::vector<uint8_t> private_key_value;
key_->ExportValue(&private_key_value);
std::string head = "fakesignature";
std::string tail = "/fakesignature";
@@ -334,8 +315,8 @@ bool MockECSignatureCreator::Sign(const uint8* data,
}
bool MockECSignatureCreator::DecodeSignature(
- const std::vector<uint8>& signature,
- std::vector<uint8>* out_raw_sig) {
+ const std::vector<uint8_t>& signature,
+ std::vector<uint8_t>* out_raw_sig) {
*out_raw_sig = signature;
return true;
}
@@ -360,13 +341,13 @@ SpdySessionDependencies::SpdySessionDependencies(NextProto protocol)
proxy_service(ProxyService::CreateDirect()),
ssl_config_service(new SSLConfigServiceDefaults),
socket_factory(new MockClientSocketFactory),
- deterministic_socket_factory(new DeterministicMockClientSocketFactory),
http_auth_handler_factory(
HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
enable_ip_pooling(true),
enable_compression(false),
enable_ping(false),
enable_user_alternate_protocol_ports(false),
+ enable_npn(true),
protocol(protocol),
session_max_recv_window_size(
SpdySession::GetDefaultInitialWindowSize(protocol)),
@@ -392,16 +373,16 @@ SpdySessionDependencies::SpdySessionDependencies(
: host_resolver(new MockHostResolver),
cert_verifier(new MockCertVerifier),
transport_security_state(new TransportSecurityState),
- proxy_service(proxy_service.Pass()),
+ proxy_service(std::move(proxy_service)),
ssl_config_service(new SSLConfigServiceDefaults),
socket_factory(new MockClientSocketFactory),
- deterministic_socket_factory(new DeterministicMockClientSocketFactory),
http_auth_handler_factory(
HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
enable_ip_pooling(true),
enable_compression(false),
enable_ping(false),
enable_user_alternate_protocol_ports(false),
+ enable_npn(true),
protocol(protocol),
session_max_recv_window_size(
SpdySession::GetDefaultInitialWindowSize(protocol)),
@@ -416,23 +397,11 @@ SpdySessionDependencies::SpdySessionDependencies(
SpdySessionDependencies::~SpdySessionDependencies() {}
// static
-HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession(
+scoped_ptr<HttpNetworkSession> SpdySessionDependencies::SpdyCreateSession(
SpdySessionDependencies* session_deps) {
HttpNetworkSession::Params params = CreateSessionParams(session_deps);
params.client_socket_factory = session_deps->socket_factory.get();
- HttpNetworkSession* http_session = new HttpNetworkSession(params);
- SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
- pool_peer.SetEnableSendingInitialData(false);
- return http_session;
-}
-
-// static
-HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic(
- SpdySessionDependencies* session_deps) {
- HttpNetworkSession::Params params = CreateSessionParams(session_deps);
- params.client_socket_factory =
- session_deps->deterministic_socket_factory.get();
- HttpNetworkSession* http_session = new HttpNetworkSession(params);
+ scoped_ptr<HttpNetworkSession> http_session(new HttpNetworkSession(params));
SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
pool_peer.SetEnableSendingInitialData(false);
return http_session;
@@ -459,6 +428,7 @@ HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
params.enable_spdy_ping_based_connection_checking = session_deps->enable_ping;
params.enable_user_alternate_protocol_ports =
session_deps->enable_user_alternate_protocol_ports;
+ params.enable_npn = session_deps->enable_npn;
params.spdy_default_protocol = session_deps->protocol;
params.spdy_session_max_recv_window_size =
session_deps->session_max_recv_window_size;
@@ -500,12 +470,14 @@ SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol)
params.enable_spdy_ping_based_connection_checking = false;
params.spdy_default_protocol = protocol;
params.http_server_properties = http_server_properties();
- scoped_refptr<HttpNetworkSession> network_session(
- new HttpNetworkSession(params));
- SpdySessionPoolPeer pool_peer(network_session->spdy_session_pool());
+ storage_.set_http_network_session(
+ make_scoped_ptr(new HttpNetworkSession(params)));
+ SpdySessionPoolPeer pool_peer(
+ storage_.http_network_session()->spdy_session_pool());
pool_peer.SetEnableSendingInitialData(false);
- storage_.set_http_transaction_factory(make_scoped_ptr(new HttpCache(
- network_session.get(), HttpCache::DefaultBackend::InMemory(0))));
+ storage_.set_http_transaction_factory(make_scoped_ptr(
+ new HttpCache(storage_.http_network_session(),
+ HttpCache::DefaultBackend::InMemory(0), false)));
}
SpdyURLRequestContext::~SpdyURLRequestContext() {
@@ -519,7 +491,7 @@ bool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key) {
namespace {
base::WeakPtr<SpdySession> CreateSpdySessionHelper(
- const scoped_refptr<HttpNetworkSession>& http_session,
+ HttpNetworkSession* http_session,
const SpdySessionKey& key,
const BoundNetLog& net_log,
Error expected_status,
@@ -570,7 +542,7 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper(
base::WeakPtr<SpdySession> spdy_session =
http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
- key, connection.Pass(), net_log, OK, is_secure);
+ key, std::move(connection), net_log, OK, is_secure);
// Failure is reported asynchronously.
EXPECT_TRUE(spdy_session != NULL);
EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
@@ -580,7 +552,7 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper(
} // namespace
base::WeakPtr<SpdySession> CreateInsecureSpdySession(
- const scoped_refptr<HttpNetworkSession>& http_session,
+ HttpNetworkSession* http_session,
const SpdySessionKey& key,
const BoundNetLog& net_log) {
return CreateSpdySessionHelper(http_session, key, net_log,
@@ -588,7 +560,7 @@ base::WeakPtr<SpdySession> CreateInsecureSpdySession(
}
base::WeakPtr<SpdySession> TryCreateInsecureSpdySessionExpectingFailure(
- const scoped_refptr<HttpNetworkSession>& http_session,
+ HttpNetworkSession* http_session,
const SpdySessionKey& key,
Error expected_error,
const BoundNetLog& net_log) {
@@ -598,7 +570,7 @@ base::WeakPtr<SpdySession> TryCreateInsecureSpdySessionExpectingFailure(
}
base::WeakPtr<SpdySession> CreateSecureSpdySession(
- const scoped_refptr<HttpNetworkSession>& http_session,
+ HttpNetworkSession* http_session,
const SpdySessionKey& key,
const BoundNetLog& net_log) {
return CreateSpdySessionHelper(http_session, key, net_log,
@@ -657,6 +629,11 @@ class FakeSpdySessionClientSocket : public MockClientSocket {
return false;
}
+ int64_t GetTotalReceivedBytes() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+
private:
int read_result_;
};
@@ -672,7 +649,7 @@ base::WeakPtr<SpdySession> CreateFakeSpdySessionHelper(
expected_status == OK ? ERR_IO_PENDING : expected_status)));
base::WeakPtr<SpdySession> spdy_session =
pool->CreateAvailableSessionFromSocket(
- key, handle.Pass(), BoundNetLog(), OK, true /* is_secure */);
+ key, std::move(handle), BoundNetLog(), OK, true /* is_secure */);
// Failure is reported asynchronously.
EXPECT_TRUE(spdy_session != NULL);
EXPECT_TRUE(HasSpdySession(pool, key));
@@ -717,13 +694,16 @@ void SpdySessionPoolPeer::SetStreamInitialRecvWindowSize(size_t window) {
pool_->stream_max_recv_window_size_ = window;
}
-SpdyTestUtil::SpdyTestUtil(NextProto protocol)
+SpdyTestUtil::SpdyTestUtil(NextProto protocol, bool dependency_priorities)
: protocol_(protocol),
spdy_version_(NextProtoToSpdyMajorVersion(protocol)),
- default_url_(GURL(kDefaultURL)) {
+ default_url_(GURL(kDefaultURL)),
+ dependency_priorities_(dependency_priorities) {
DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol;
}
+SpdyTestUtil::~SpdyTestUtil() {}
+
void SpdyTestUtil::AddUrlToHeaderBlock(base::StringPiece url,
SpdyHeaderBlock* headers) const {
std::string scheme, host, path;
@@ -741,24 +721,24 @@ scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlock(
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlockForProxy(
base::StringPiece url) const {
scoped_ptr<SpdyHeaderBlock> headers(ConstructGetHeaderBlock(url));
- return headers.Pass();
+ return headers;
}
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeadHeaderBlock(
base::StringPiece url,
- int64 content_length) const {
+ int64_t content_length) const {
return ConstructHeaderBlock("HEAD", url, nullptr);
}
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPostHeaderBlock(
base::StringPiece url,
- int64 content_length) const {
+ int64_t content_length) const {
return ConstructHeaderBlock("POST", url, &content_length);
}
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPutHeaderBlock(
base::StringPiece url,
- int64 content_length) const {
+ int64_t content_length) const {
return ConstructHeaderBlock("PUT", url, &content_length);
}
@@ -809,7 +789,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(const SpdyHeaderInfo& header_info,
AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
if (tail_headers && tail_header_count)
AppendToHeaderBlock(tail_headers, tail_header_count, headers.get());
- return ConstructSpdyFrame(header_info, headers.Pass());
+ return ConstructSpdyFrame(header_info, std::move(headers));
}
SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
@@ -827,7 +807,6 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
stream_id,
associated_stream_id,
ConvertRequestPriorityToSpdyPriority(request_priority, spdy_version_),
- 0, // credential slot
flags,
compressed,
RST_STREAM_INVALID, // status
@@ -835,7 +814,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
0, // length
DATA_FLAG_NONE
};
- return ConstructSpdyFrame(header_info, headers.Pass());
+ return ConstructSpdyFrame(header_info, std::move(headers));
}
SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
@@ -853,9 +832,9 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyControlFrame(
AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
if (tail_headers && tail_header_size)
AppendToHeaderBlock(tail_headers, tail_header_size / 2, headers.get());
- return ConstructSpdyControlFrame(
- headers.Pass(), compressed, stream_id,
- request_priority, type, flags, associated_stream_id);
+ return ConstructSpdyControlFrame(std::move(headers), compressed, stream_id,
+ request_priority, type, flags,
+ associated_stream_id);
}
std::string SpdyTestUtil::ConstructSpdyReplyString(
@@ -906,7 +885,8 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySettingsAck() const {
return new SpdyFrame(kEmptyWrite, 0, false);
}
-SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32 ping_id, bool is_ack) const {
+SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32_t ping_id,
+ bool is_ack) const {
SpdyPingIR ping_ir(ping_id);
ping_ir.set_is_ack(is_ack);
return CreateFramer(false)->SerializeFrame(ping_ir);
@@ -930,7 +910,8 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway(SpdyStreamId last_good_stream_id,
}
SpdyFrame* SpdyTestUtil::ConstructSpdyWindowUpdate(
- const SpdyStreamId stream_id, uint32 delta_window_size) const {
+ const SpdyStreamId stream_id,
+ uint32_t delta_window_size) const {
SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
return CreateFramer(false)->SerializeFrame(update_ir);
}
@@ -940,15 +921,14 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyWindowUpdate(
SpdyFrame* SpdyTestUtil::ConstructSpdyRstStream(
SpdyStreamId stream_id,
SpdyRstStreamStatus status) const {
- SpdyRstStreamIR rst_ir(stream_id, status, "");
+ SpdyRstStreamIR rst_ir(stream_id, status);
return CreateFramer(false)->SerializeRstStream(rst_ir);
}
-SpdyFrame* SpdyTestUtil::ConstructSpdyGet(
- const char* const url,
- bool compressed,
- SpdyStreamId stream_id,
- RequestPriority request_priority) const {
+SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const url,
+ bool compressed,
+ SpdyStreamId stream_id,
+ RequestPriority request_priority) {
scoped_ptr<SpdyHeaderBlock> block(ConstructGetHeaderBlock(url));
return ConstructSpdySyn(
stream_id, *block, request_priority, compressed, true);
@@ -959,7 +939,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const extra_headers[],
bool compressed,
int stream_id,
RequestPriority request_priority,
- bool direct) const {
+ bool direct) {
SpdyHeaderBlock block;
MaybeAddVersionHeader(&block);
block[GetMethodKey()] = "GET";
@@ -973,7 +953,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyConnect(
int extra_header_count,
int stream_id,
RequestPriority priority,
- const HostPortPair& host_port_pair) const {
+ const HostPortPair& host_port_pair) {
SpdyHeaderBlock block;
MaybeAddVersionHeader(&block);
block[GetMethodKey()] = "CONNECT";
@@ -1107,7 +1087,15 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPushHeaders(
SpdyFrame* SpdyTestUtil::ConstructSpdyHeaderFrame(int stream_id,
const char* const headers[],
int header_count) {
+ return ConstructSpdyHeaderFrame(stream_id, headers, header_count, false);
+}
+
+SpdyFrame* SpdyTestUtil::ConstructSpdyHeaderFrame(int stream_id,
+ const char* const headers[],
+ int header_count,
+ bool fin) {
SpdyHeadersIR spdy_headers(stream_id);
+ spdy_headers.set_fin(fin);
AppendToHeaderBlock(headers, header_count,
spdy_headers.mutable_header_block());
return CreateFramer(false)->SerializeFrame(spdy_headers);
@@ -1117,7 +1105,20 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySyn(int stream_id,
const SpdyHeaderBlock& block,
RequestPriority priority,
bool compressed,
- bool fin) const {
+ bool fin) {
+ // Get the stream id of the next highest priority request
+ // (most recent request of the same priority, or last request of
+ // an earlier priority).
+ int parent_stream_id = 0;
+ for (int q = priority; q >= IDLE; --q) {
+ if (!priority_to_stream_id_list_[q].empty()) {
+ parent_stream_id = priority_to_stream_id_list_[q].back();
+ break;
+ }
+ }
+
+ priority_to_stream_id_list_[priority].push_back(stream_id);
+
if (protocol_ < kProtoHTTP2) {
SpdySynStreamIR syn_stream(stream_id);
syn_stream.set_header_block(block);
@@ -1131,6 +1132,10 @@ SpdyFrame* SpdyTestUtil::ConstructSpdySyn(int stream_id,
headers.set_has_priority(true);
headers.set_priority(
ConvertRequestPriorityToSpdyPriority(priority, spdy_version()));
+ if (dependency_priorities_) {
+ headers.set_parent_stream_id(parent_stream_id);
+ headers.set_exclusive(true);
+ }
headers.set_fin(fin);
return CreateFramer(compressed)->SerializeFrame(headers);
}
@@ -1190,7 +1195,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReply(
SpdyFrame* SpdyTestUtil::ConstructSpdyPost(const char* url,
SpdyStreamId stream_id,
- int64 content_length,
+ int64_t content_length,
RequestPriority priority,
const char* const extra_headers[],
int extra_header_count) {
@@ -1215,7 +1220,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyPostSynReply(
const char* const extra_headers[],
int extra_header_count) {
// TODO(jgraettinger): Remove this method.
- return ConstructSpdyGetSynReply(NULL, 0, 1);
+ return ConstructSpdyGetSynReply(extra_headers, extra_header_count, 1);
}
SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id, bool fin) {
@@ -1228,7 +1233,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id, bool fin) {
SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
const char* data,
- uint32 len,
+ uint32_t len,
bool fin) {
SpdyFramer framer(spdy_version_);
SpdyDataIR data_ir(stream_id, base::StringPiece(data, len));
@@ -1238,7 +1243,7 @@ SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
const char* data,
- uint32 len,
+ uint32_t len,
bool fin,
int padding_length) {
SpdyFramer framer(spdy_version_);
@@ -1255,27 +1260,24 @@ SpdyFrame* SpdyTestUtil::ConstructWrappedSpdyFrame(
frame->size(), false);
}
-const SpdyHeaderInfo SpdyTestUtil::MakeSpdyHeader(SpdyFrameType type) {
- const SpdyHeaderInfo kHeader = {
- type,
- 1, // Stream ID
- 0, // Associated stream ID
- ConvertRequestPriorityToSpdyPriority(LOWEST, spdy_version_),
- kSpdyCredentialSlotUnused,
- CONTROL_FLAG_FIN, // Control Flags
- false, // Compressed
- RST_STREAM_INVALID,
- NULL, // Data
- 0, // Length
- DATA_FLAG_NONE
- };
- return kHeader;
+void SpdyTestUtil::UpdateWithStreamDestruction(int stream_id) {
+ for (auto priority_it = priority_to_stream_id_list_.begin();
+ priority_it != priority_to_stream_id_list_.end(); ++priority_it) {
+ for (auto stream_it = priority_it->second.begin();
+ stream_it != priority_it->second.end(); ++stream_it) {
+ if (*stream_it == stream_id) {
+ priority_it->second.erase(stream_it);
+ return;
+ }
+ }
+ }
+ NOTREACHED();
}
scoped_ptr<SpdyFramer> SpdyTestUtil::CreateFramer(bool compressed) const {
scoped_ptr<SpdyFramer> framer(new SpdyFramer(spdy_version_));
framer->set_enable_compression(compressed);
- return framer.Pass();
+ return framer;
}
const char* SpdyTestUtil::GetMethodKey() const {
@@ -1308,7 +1310,7 @@ const char* SpdyTestUtil::GetPathKey() const {
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock(
base::StringPiece method,
base::StringPiece url,
- int64* content_length) const {
+ int64_t* content_length) const {
std::string scheme, host, path;
ParseUrl(url.data(), &scheme, &host, &path);
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
@@ -1323,7 +1325,7 @@ scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock(
std::string length_str = base::Int64ToString(*content_length);
(*headers)["content-length"] = length_str;
}
- return headers.Pass();
+ return headers;
}
void SpdyTestUtil::MaybeAddVersionHeader(
diff --git a/chromium/net/spdy/spdy_test_util_common.h b/chromium/net/spdy/spdy_test_util_common.h
index 68bdfdf3296..9ef8df53876 100644
--- a/chromium/net/spdy/spdy_test_util_common.h
+++ b/chromium/net/spdy/spdy_test_util_common.h
@@ -5,9 +5,13 @@
#ifndef NET_SPDY_SPDY_TEST_UTIL_COMMON_H_
#define NET_SPDY_SPDY_TEST_UTIL_COMMON_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "crypto/ec_private_key.h"
@@ -52,28 +56,11 @@ const int kUploadDataSize = arraysize(kUploadData)-1;
// SPDY.
NextProtoVector SpdyNextProtos();
-// Chop a frame into an array of MockWrites.
-// |data| is the frame to chop.
-// |length| is the length of the frame to chop.
-// |num_chunks| is the number of chunks to create.
-MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks);
-
// Chop a SpdyFrame into an array of MockWrites.
// |frame| is the frame to chop.
// |num_chunks| is the number of chunks to create.
MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks);
-// Chop a frame into an array of MockReads.
-// |data| is the frame to chop.
-// |length| is the length of the frame to chop.
-// |num_chunks| is the number of chunks to create.
-MockRead* ChopReadFrame(const char* data, int length, int num_chunks);
-
-// Chop a SpdyFrame into an array of MockReads.
-// |frame| is the frame to chop.
-// |num_chunks| is the number of chunks to create.
-MockRead* ChopReadFrame(const SpdyFrame& frame, int num_chunks);
-
// Adds headers and values to a map.
// |extra_headers| is an array of { name, value } pairs, arranged as strings
// where the even entries are the header names, and the odd entries are the
@@ -101,8 +88,10 @@ MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode);
// Combines the given SpdyFrames into the given char array and returns
// the total length.
-int CombineFrames(const SpdyFrame** frames, int num_frames,
- char* buff, int buff_len);
+int CombineFrames(const SpdyFrame** frames,
+ int num_frames,
+ char* buf,
+ int buf_len);
// Returns the SpdyPriority embedded in the given frame. Returns true
// and fills in |priority| on success.
@@ -134,20 +123,17 @@ class StreamReleaserCallback : public TestCompletionCallbackBase {
void OnComplete(SpdyStreamRequest* request, int result);
};
-const size_t kSpdyCredentialSlotUnused = 0;
-
// This struct holds information used to construct spdy control and data frames.
struct SpdyHeaderInfo {
SpdyFrameType kind;
SpdyStreamId id;
SpdyStreamId assoc_id;
SpdyPriority priority;
- size_t credential_slot; // SPDY3 only
SpdyControlFlags control_flags;
bool compressed;
SpdyRstStreamStatus status;
const char* data;
- uint32 data_length;
+ uint32_t data_length;
SpdyDataFlags data_flags;
};
@@ -157,11 +143,11 @@ class MockECSignatureCreator : public crypto::ECSignatureCreator {
explicit MockECSignatureCreator(crypto::ECPrivateKey* key);
// crypto::ECSignatureCreator
- bool Sign(const uint8* data,
+ bool Sign(const uint8_t* data,
int data_len,
- std::vector<uint8>* signature) override;
- bool DecodeSignature(const std::vector<uint8>& signature,
- std::vector<uint8>* out_raw_sig) override;
+ std::vector<uint8_t>* signature) override;
+ bool DecodeSignature(const std::vector<uint8_t>& signature,
+ std::vector<uint8_t>* out_raw_sig) override;
private:
crypto::ECPrivateKey* key_;
@@ -194,9 +180,7 @@ struct SpdySessionDependencies {
~SpdySessionDependencies();
- static HttpNetworkSession* SpdyCreateSession(
- SpdySessionDependencies* session_deps);
- static HttpNetworkSession* SpdyCreateSessionDeterministic(
+ static scoped_ptr<HttpNetworkSession> SpdyCreateSession(
SpdySessionDependencies* session_deps);
static HttpNetworkSession::Params CreateSessionParams(
SpdySessionDependencies* session_deps);
@@ -208,13 +192,13 @@ struct SpdySessionDependencies {
scoped_ptr<ProxyService> proxy_service;
scoped_refptr<SSLConfigService> ssl_config_service;
scoped_ptr<MockClientSocketFactory> socket_factory;
- scoped_ptr<DeterministicMockClientSocketFactory> deterministic_socket_factory;
scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
HttpServerPropertiesImpl http_server_properties;
bool enable_ip_pooling;
bool enable_compression;
bool enable_ping;
bool enable_user_alternate_protocol_ports;
+ bool enable_npn;
NextProto protocol;
size_t session_max_recv_window_size;
size_t stream_max_recv_window_size;
@@ -244,7 +228,7 @@ bool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key);
// session pool in |http_session|. A SPDY session for |key| must not
// already exist.
base::WeakPtr<SpdySession> CreateInsecureSpdySession(
- const scoped_refptr<HttpNetworkSession>& http_session,
+ HttpNetworkSession* http_session,
const SpdySessionKey& key,
const BoundNetLog& net_log);
@@ -253,14 +237,14 @@ base::WeakPtr<SpdySession> CreateInsecureSpdySession(
// not already exist. The session will be created but close in the
// next event loop iteration.
base::WeakPtr<SpdySession> TryCreateInsecureSpdySessionExpectingFailure(
- const scoped_refptr<HttpNetworkSession>& http_session,
+ HttpNetworkSession* http_session,
const SpdySessionKey& key,
Error expected_error,
const BoundNetLog& net_log);
// Like CreateInsecureSpdySession(), but uses TLS.
base::WeakPtr<SpdySession> CreateSecureSpdySession(
- const scoped_refptr<HttpNetworkSession>& http_session,
+ HttpNetworkSession* http_session,
const SpdySessionKey& key,
const BoundNetLog& net_log);
@@ -298,7 +282,8 @@ class SpdySessionPoolPeer {
class SpdyTestUtil {
public:
- explicit SpdyTestUtil(NextProto protocol);
+ explicit SpdyTestUtil(NextProto protocol, bool dependency_priorities);
+ ~SpdyTestUtil();
// Add the appropriate headers to put |url| into |block|.
void AddUrlToHeaderBlock(base::StringPiece url,
@@ -310,13 +295,13 @@ class SpdyTestUtil {
base::StringPiece url) const;
scoped_ptr<SpdyHeaderBlock> ConstructHeadHeaderBlock(
base::StringPiece url,
- int64 content_length) const;
+ int64_t content_length) const;
scoped_ptr<SpdyHeaderBlock> ConstructPostHeaderBlock(
base::StringPiece url,
- int64 content_length) const;
+ int64_t content_length) const;
scoped_ptr<SpdyHeaderBlock> ConstructPutHeaderBlock(
base::StringPiece url,
- int64 content_length) const;
+ int64_t content_length) const;
// Construct a SPDY frame. If it is a SYN_STREAM or SYN_REPLY frame (as
// specified in header_info.kind), the provided headers are included in the
@@ -377,7 +362,7 @@ class SpdyTestUtil {
// Construct a SPDY PING frame.
// Returns the constructed frame. The caller takes ownership of the frame.
- SpdyFrame* ConstructSpdyPing(uint32 ping_id, bool is_ack) const;
+ SpdyFrame* ConstructSpdyPing(uint32_t ping_id, bool is_ack) const;
// Construct a SPDY GOAWAY frame with last_good_stream_id = 0.
// Returns the constructed frame. The caller takes ownership of the frame.
@@ -396,9 +381,8 @@ class SpdyTestUtil {
// Construct a SPDY WINDOW_UPDATE frame.
// Returns the constructed frame. The caller takes ownership of the frame.
- SpdyFrame* ConstructSpdyWindowUpdate(
- SpdyStreamId stream_id,
- uint32 delta_window_size) const;
+ SpdyFrame* ConstructSpdyWindowUpdate(SpdyStreamId stream_id,
+ uint32_t delta_window_size) const;
// Construct a SPDY RST_STREAM frame.
// Returns the constructed frame. The caller takes ownership of the frame.
@@ -413,12 +397,7 @@ class SpdyTestUtil {
SpdyFrame* ConstructSpdyGet(const char* const url,
bool compressed,
SpdyStreamId stream_id,
- RequestPriority request_priority) const;
-
- SpdyFrame* ConstructSpdyGetForProxy(const char* const url,
- bool compressed,
- SpdyStreamId stream_id,
- RequestPriority request_priority) const;
+ RequestPriority request_priority);
// Constructs a standard SPDY GET SYN frame, optionally compressed.
// |extra_headers| are the extra header-value pairs, which typically
@@ -430,14 +409,14 @@ class SpdyTestUtil {
bool compressed,
int stream_id,
RequestPriority request_priority,
- bool direct) const;
+ bool direct);
// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
int extra_header_count,
int stream_id,
RequestPriority priority,
- const HostPortPair& host_port_pair) const;
+ const HostPortPair& host_port_pair);
// Constructs a standard SPDY push SYN frame.
// |extra_headers| are the extra header-value pairs, which typically
@@ -468,13 +447,19 @@ class SpdyTestUtil {
const char* const headers[],
int header_count);
+ // Constructs a SPDY header frame with END_STREAM flag set to |fin|.
+ SpdyFrame* ConstructSpdyHeaderFrame(int stream_id,
+ const char* const headers[],
+ int header_count,
+ bool fin);
+
// Construct a SPDY syn (HEADERS or SYN_STREAM, depending on protocol
// version) carrying exactly the given headers and priority.
SpdyFrame* ConstructSpdySyn(int stream_id,
const SpdyHeaderBlock& headers,
RequestPriority priority,
bool compressed,
- bool fin) const;
+ bool fin);
// Construct a SPDY reply (HEADERS or SYN_REPLY, depending on protocol
// version) carrying exactly the given headers, and the default priority
@@ -514,7 +499,7 @@ class SpdyTestUtil {
// Returns a SpdyFrame.
SpdyFrame* ConstructSpdyPost(const char* url,
SpdyStreamId stream_id,
- int64 content_length,
+ int64_t content_length,
RequestPriority priority,
const char* const extra_headers[],
int extra_header_count);
@@ -538,13 +523,15 @@ class SpdyTestUtil {
bool fin);
// Constructs a single SPDY data frame with the given content.
- SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
- uint32 len, bool fin);
+ SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
+ const char* data,
+ uint32_t len,
+ bool fin);
// Constructs a single SPDY data frame with the given content and padding.
SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
const char* data,
- uint32 len,
+ uint32_t len,
bool fin,
int padding_length);
@@ -552,7 +539,10 @@ class SpdyTestUtil {
SpdyFrame* ConstructWrappedSpdyFrame(const scoped_ptr<SpdyFrame>& frame,
int stream_id);
- const SpdyHeaderInfo MakeSpdyHeader(SpdyFrameType type);
+ // Called when necessary (when it will affect stream dependency specification
+ // when setting dependencies based on priorioties) to notify the utility
+ // class of stream destruction.
+ void UpdateWithStreamDestruction(int stream_id);
// For versions below SPDY4, adds the version HTTP/1.1 header.
void MaybeAddVersionHeader(SpdyFrameWithHeaderBlockIR* frame_ir) const;
@@ -582,11 +572,15 @@ class SpdyTestUtil {
scoped_ptr<SpdyHeaderBlock> ConstructHeaderBlock(
base::StringPiece method,
base::StringPiece url,
- int64* content_length) const;
+ int64_t* content_length) const;
const NextProto protocol_;
const SpdyMajorVersion spdy_version_;
GURL default_url_;
+ bool dependency_priorities_;
+
+ // Track a FIFO list of the stream_id of all created requests by priority.
+ std::map<int, std::vector<int>> priority_to_stream_id_list_;
};
} // namespace net
diff --git a/chromium/net/spdy/spdy_test_utils.cc b/chromium/net/spdy/spdy_test_utils.cc
index 1b2e178d622..668a9028f87 100644
--- a/chromium/net/spdy/spdy_test_utils.cc
+++ b/chromium/net/spdy/spdy_test_utils.cc
@@ -89,10 +89,9 @@ void CompareCharArraysWithHexError(
}
void SetFrameFlags(SpdyFrame* frame,
- uint8 flags,
+ uint8_t flags,
SpdyMajorVersion spdy_version) {
switch (spdy_version) {
- case SPDY2:
case SPDY3:
case HTTP2:
frame->data()[4] = flags;
@@ -106,12 +105,11 @@ void SetFrameLength(SpdyFrame* frame,
size_t length,
SpdyMajorVersion spdy_version) {
switch (spdy_version) {
- case SPDY2:
case SPDY3:
CHECK_EQ(0u, length & ~kLengthMask);
{
- int32 wire_length = base::HostToNet32(length);
- // The length field in SPDY 2 and 3 is a 24-bit (3B) integer starting at
+ int32_t wire_length = base::HostToNet32(length);
+ // The length field in SPDY 3 is a 24-bit (3B) integer starting at
// offset 5.
memcpy(frame->data() + 5, reinterpret_cast<char*>(&wire_length) + 1, 3);
}
@@ -119,7 +117,7 @@ void SetFrameLength(SpdyFrame* frame,
case HTTP2:
CHECK_GT(1u<<14, length);
{
- int32 wire_length = base::HostToNet32(length);
+ int32_t wire_length = base::HostToNet32(length);
memcpy(frame->data(),
reinterpret_cast<char*>(&wire_length) + 1,
3);
@@ -130,13 +128,8 @@ void SetFrameLength(SpdyFrame* frame,
}
}
-bool CompareSpdyHeaderBlocks(const SpdyHeaderBlock& a,
- const SpdyHeaderBlock& b) {
- return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
-}
-
std::string a2b_hex(const char* hex_data) {
- std::vector<uint8> output;
+ std::vector<uint8_t> output;
std::string result;
if (base::HexStringToBytes(hex_data, &output))
result.assign(reinterpret_cast<const char*>(&output[0]), output.size());
diff --git a/chromium/net/spdy/spdy_test_utils.h b/chromium/net/spdy/spdy_test_utils.h
index e052a3f0dc3..de4212f6b09 100644
--- a/chromium/net/spdy/spdy_test_utils.h
+++ b/chromium/net/spdy/spdy_test_utils.h
@@ -5,6 +5,7 @@
#ifndef NET_SPDY_TEST_UTILS_H_
#define NET_SPDY_TEST_UTILS_H_
+#include <stddef.h>
#include <stdint.h>
#include <string>
@@ -17,9 +18,9 @@ namespace net {
class HashValue;
class TransportSecurityState;
-inline bool operator==(StringPiece x,
+inline bool operator==(base::StringPiece x,
const SpdyHeaderBlock::StringPieceProxy& y) {
- return x == y.operator StringPiece();
+ return x == y.operator base::StringPiece();
}
namespace test {
@@ -35,18 +36,13 @@ void CompareCharArraysWithHexError(
const int expected_len);
void SetFrameFlags(SpdyFrame* frame,
- uint8 flags,
+ uint8_t flags,
SpdyMajorVersion spdy_version);
void SetFrameLength(SpdyFrame* frame,
size_t length,
SpdyMajorVersion spdy_version);
-// Returns true if |a| and |b| are the same size, and contain the same
-// entries in the same positions.
-bool CompareSpdyHeaderBlocks(const SpdyHeaderBlock& a,
- const SpdyHeaderBlock& b);
-
std::string a2b_hex(const char* hex_data);
// Returns a SHA1 HashValue in which each byte has the value |label|.
diff --git a/chromium/net/spdy/spdy_write_queue.h b/chromium/net/spdy/spdy_write_queue.h
index bd67f6ba38b..c19b3f206c6 100644
--- a/chromium/net/spdy/spdy_write_queue.h
+++ b/chromium/net/spdy/spdy_write_queue.h
@@ -7,7 +7,7 @@
#include <deque>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/spdy/spdy_write_queue_unittest.cc b/chromium/net/spdy/spdy_write_queue_unittest.cc
index 2fdcf5ea31a..1c7bc0a8805 100644
--- a/chromium/net/spdy/spdy_write_queue_unittest.cc
+++ b/chromium/net/spdy/spdy_write_queue_unittest.cc
@@ -7,8 +7,8 @@
#include <cstddef>
#include <cstring>
#include <string>
+#include <utility>
-#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
@@ -59,7 +59,7 @@ class RequeingBufferProducer : public SpdyBufferProducer {
base::Bind(RequeingBufferProducer::ConsumeCallback, queue));
}
- scoped_ptr<SpdyBuffer> ProduceBuffer() override { return buffer_.Pass(); }
+ scoped_ptr<SpdyBuffer> ProduceBuffer() override { return std::move(buffer_); }
static void ConsumeCallback(SpdyWriteQueue* queue,
size_t size,
@@ -68,8 +68,8 @@ class RequeingBufferProducer : public SpdyBufferProducer {
new SimpleBufferProducer(scoped_ptr<SpdyBuffer>(
new SpdyBuffer(kRequeued, arraysize(kRequeued)))));
- queue->Enqueue(
- MEDIUM, RST_STREAM, producer.Pass(), base::WeakPtr<SpdyStream>());
+ queue->Enqueue(MEDIUM, RST_STREAM, std::move(producer),
+ base::WeakPtr<SpdyStream>());
}
private:
@@ -87,7 +87,7 @@ std::string ProducerToString(scoped_ptr<SpdyBufferProducer> producer) {
// data as an int (converted from a string).
int ProducerToInt(scoped_ptr<SpdyBufferProducer> producer) {
int i = 0;
- EXPECT_TRUE(base::StringToInt(ProducerToString(producer.Pass()), &i));
+ EXPECT_TRUE(base::StringToInt(ProducerToString(std::move(producer)), &i));
return i;
}
@@ -113,31 +113,30 @@ TEST_F(SpdyWriteQueueTest, DequeuesByPriority) {
scoped_ptr<SpdyStream> stream_highest(MakeTestStream(HIGHEST));
// A NULL stream should still work.
- write_queue.Enqueue(
- LOW, SYN_STREAM, producer_low.Pass(), base::WeakPtr<SpdyStream>());
- write_queue.Enqueue(
- MEDIUM, SYN_REPLY, producer_medium.Pass(), stream_medium->GetWeakPtr());
- write_queue.Enqueue(
- HIGHEST, RST_STREAM, producer_highest.Pass(),
- stream_highest->GetWeakPtr());
+ write_queue.Enqueue(LOW, SYN_STREAM, std::move(producer_low),
+ base::WeakPtr<SpdyStream>());
+ write_queue.Enqueue(MEDIUM, SYN_REPLY, std::move(producer_medium),
+ stream_medium->GetWeakPtr());
+ write_queue.Enqueue(HIGHEST, RST_STREAM, std::move(producer_highest),
+ stream_highest->GetWeakPtr());
SpdyFrameType frame_type = DATA;
scoped_ptr<SpdyBufferProducer> frame_producer;
base::WeakPtr<SpdyStream> stream;
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
EXPECT_EQ(RST_STREAM, frame_type);
- EXPECT_EQ("HIGHEST", ProducerToString(frame_producer.Pass()));
- EXPECT_EQ(stream_highest, stream.get());
+ EXPECT_EQ("HIGHEST", ProducerToString(std::move(frame_producer)));
+ EXPECT_EQ(stream_highest.get(), stream.get());
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
EXPECT_EQ(SYN_REPLY, frame_type);
- EXPECT_EQ("MEDIUM", ProducerToString(frame_producer.Pass()));
- EXPECT_EQ(stream_medium, stream.get());
+ EXPECT_EQ("MEDIUM", ProducerToString(std::move(frame_producer)));
+ EXPECT_EQ(stream_medium.get(), stream.get());
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
EXPECT_EQ(SYN_STREAM, frame_type);
- EXPECT_EQ("LOW", ProducerToString(frame_producer.Pass()));
- EXPECT_EQ(NULL, stream.get());
+ EXPECT_EQ("LOW", ProducerToString(std::move(frame_producer)));
+ EXPECT_EQ(nullptr, stream.get());
EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
}
@@ -155,11 +154,11 @@ TEST_F(SpdyWriteQueueTest, DequeuesFIFO) {
scoped_ptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY));
scoped_ptr<SpdyStream> stream3(MakeTestStream(DEFAULT_PRIORITY));
- write_queue.Enqueue(DEFAULT_PRIORITY, SYN_STREAM, producer1.Pass(),
+ write_queue.Enqueue(DEFAULT_PRIORITY, SYN_STREAM, std::move(producer1),
stream1->GetWeakPtr());
- write_queue.Enqueue(DEFAULT_PRIORITY, SYN_REPLY, producer2.Pass(),
+ write_queue.Enqueue(DEFAULT_PRIORITY, SYN_REPLY, std::move(producer2),
stream2->GetWeakPtr());
- write_queue.Enqueue(DEFAULT_PRIORITY, RST_STREAM, producer3.Pass(),
+ write_queue.Enqueue(DEFAULT_PRIORITY, RST_STREAM, std::move(producer3),
stream3->GetWeakPtr());
SpdyFrameType frame_type = DATA;
@@ -167,18 +166,18 @@ TEST_F(SpdyWriteQueueTest, DequeuesFIFO) {
base::WeakPtr<SpdyStream> stream;
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
EXPECT_EQ(SYN_STREAM, frame_type);
- EXPECT_EQ(1, ProducerToInt(frame_producer.Pass()));
- EXPECT_EQ(stream1, stream.get());
+ EXPECT_EQ(1, ProducerToInt(std::move(frame_producer)));
+ EXPECT_EQ(stream1.get(), stream.get());
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
EXPECT_EQ(SYN_REPLY, frame_type);
- EXPECT_EQ(2, ProducerToInt(frame_producer.Pass()));
- EXPECT_EQ(stream2, stream.get());
+ EXPECT_EQ(2, ProducerToInt(std::move(frame_producer)));
+ EXPECT_EQ(stream2.get(), stream.get());
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
EXPECT_EQ(RST_STREAM, frame_type);
- EXPECT_EQ(3, ProducerToInt(frame_producer.Pass()));
- EXPECT_EQ(stream3, stream.get());
+ EXPECT_EQ(3, ProducerToInt(std::move(frame_producer)));
+ EXPECT_EQ(stream3.get(), stream.get());
EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
}
@@ -206,8 +205,8 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) {
base::WeakPtr<SpdyStream> stream;
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
EXPECT_EQ(SYN_STREAM, frame_type);
- EXPECT_EQ(i, ProducerToInt(frame_producer.Pass()));
- EXPECT_EQ(stream1, stream.get());
+ EXPECT_EQ(i, ProducerToInt(std::move(frame_producer)));
+ EXPECT_EQ(stream1.get(), stream.get());
}
SpdyFrameType frame_type = DATA;
@@ -250,8 +249,8 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStreamsAfter) {
ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream))
<< "Unable to Dequeue i: " << i;
EXPECT_EQ(SYN_STREAM, frame_type);
- EXPECT_EQ(i, ProducerToInt(frame_producer.Pass()));
- EXPECT_EQ(stream1, stream.get());
+ EXPECT_EQ(i, ProducerToInt(std::move(frame_producer)));
+ EXPECT_EQ(stream1.get(), stream.get());
}
SpdyFrameType frame_type = DATA;
diff --git a/chromium/net/spdy/write_blocked_list.h b/chromium/net/spdy/write_blocked_list.h
index 32ed19c98d8..76d22da257a 100644
--- a/chromium/net/spdy/write_blocked_list.h
+++ b/chromium/net/spdy/write_blocked_list.h
@@ -5,6 +5,8 @@
#ifndef NET_SPDY_WRITE_BLOCKED_LIST_H_
#define NET_SPDY_WRITE_BLOCKED_LIST_H_
+#include <stddef.h>
+
#include <algorithm>
#include <deque>
@@ -18,9 +20,6 @@ namespace test {
class WriteBlockedListPeer;
} // namespace test
-const int kHighestPriority = 0;
-const int kLowestPriority = 7;
-
template <typename IdType>
class WriteBlockedList {
public:
@@ -31,26 +30,26 @@ class WriteBlockedList {
WriteBlockedList() {}
static SpdyPriority ClampPriority(SpdyPriority priority) {
- if (priority < kHighestPriority) {
+ if (priority < kV3HighestPriority) {
LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority);
- return kHighestPriority;
+ return kV3HighestPriority;
}
- if (priority > kLowestPriority) {
+ if (priority > kV3LowestPriority) {
LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority);
- return kLowestPriority;
+ return kV3LowestPriority;
}
return priority;
}
// Returns the priority of the highest priority list with sessions on it.
SpdyPriority GetHighestPriorityWriteBlockedList() const {
- for (SpdyPriority i = 0; i <= kLowestPriority; ++i) {
+ for (SpdyPriority i = 0; i <= kV3LowestPriority; ++i) {
if (write_blocked_lists_[i].size() > 0) {
return i;
}
}
LOG(DFATAL) << "No blocked streams";
- return kHighestPriority;
+ return kV3HighestPriority;
}
IdType PopFront(SpdyPriority priority) {
@@ -64,7 +63,7 @@ class WriteBlockedList {
bool HasWriteBlockedStreamsGreaterThanPriority(SpdyPriority priority) const {
priority = ClampPriority(priority);
- for (SpdyPriority i = kHighestPriority; i < priority; ++i) {
+ for (SpdyPriority i = kV3HighestPriority; i < priority; ++i) {
if (!write_blocked_lists_[i].empty()) {
return true;
}
@@ -73,7 +72,7 @@ class WriteBlockedList {
}
bool HasWriteBlockedStreams() const {
- for (SpdyPriority i = kHighestPriority; i <= kLowestPriority; ++i) {
+ for (SpdyPriority i = kV3HighestPriority; i <= kV3LowestPriority; ++i) {
if (!write_blocked_lists_[i].empty()) {
return true;
}
@@ -81,29 +80,20 @@ class WriteBlockedList {
return false;
}
+ // Add this stream to the back of the write blocked list for this priority
+ // level. If the stream is already on that write blocked list this is a
+ // no-op. If the stream is on a write blocked list for a different priority
+ // it will be removed from that list.
void PushBack(IdType stream_id, SpdyPriority priority) {
- priority = ClampPriority(priority);
- DVLOG(2) << "Adding stream " << stream_id << " at priority "
- << static_cast<int>(priority);
- bool should_insert_stream = true;
- typename StreamToPriorityMap::iterator iter =
- stream_to_priority_.find(stream_id);
- if (iter != stream_to_priority_.end()) {
- DVLOG(1) << "Stream " << stream_id << " already in write blocked list.";
- if (iter->second == priority) {
- // The stream is already in the write blocked list for the priority.
- should_insert_stream = false;
- } else {
- // The stream is in a write blocked list for a different priority.
- bool removed =
- RemoveStreamFromWriteBlockedList(stream_id, iter->second);
- DCHECK(removed);
- }
- }
- if (should_insert_stream) {
- stream_to_priority_[stream_id] = priority;
- write_blocked_lists_[priority].push_back(stream_id);
- }
+ AddStream(stream_id, priority, true);
+ }
+
+ // Add this stream to the front of the write blocked list for this priority
+ // level. If the stream is already on that write blocked list this is a
+ // no-op. If the stream is on a write blocked list for a different priority
+ // it will be removed from that list.
+ void PushFront(IdType stream_id, SpdyPriority priority) {
+ AddStream(stream_id, priority, false);
}
bool RemoveStreamFromWriteBlockedList(IdType stream_id,
@@ -147,18 +137,55 @@ class WriteBlockedList {
size_t NumBlockedStreams() const {
size_t num_blocked_streams = 0;
- for (SpdyPriority i = kHighestPriority; i <= kLowestPriority; ++i) {
+ for (SpdyPriority i = kV3HighestPriority; i <= kV3LowestPriority; ++i) {
num_blocked_streams += write_blocked_lists_[i].size();
}
return num_blocked_streams;
}
+ size_t NumBlockedStreams(SpdyPriority priority) const {
+ priority = ClampPriority(priority);
+ return write_blocked_lists_[priority].size();
+ }
+
private:
friend class net::test::WriteBlockedListPeer;
typedef base::hash_map<IdType, SpdyPriority> StreamToPriorityMap;
- BlockedList write_blocked_lists_[kLowestPriority + 1];
+ void AddStream(IdType stream_id, SpdyPriority priority, bool push_back) {
+ priority = ClampPriority(priority);
+ DVLOG(2) << "Adding stream " << stream_id << " at priority "
+ << static_cast<int>(priority);
+ bool should_insert_stream = true;
+ typename StreamToPriorityMap::iterator iter =
+ stream_to_priority_.find(stream_id);
+ // Ensure the stream is not in the write blocked list multiple times.
+ if (iter != stream_to_priority_.end()) {
+ DVLOG(1) << "Stream " << stream_id << " already in write blocked list.";
+ if (iter->second == priority) {
+ // The stream is already in the write blocked list for the priority.
+ // It will not be inserted again but will retain its place in the list.
+ should_insert_stream = false;
+ } else {
+ // The stream is in a write blocked list for a different priority.
+ // Remove it from that list and allow it to be added to the list for
+ // this priority.
+ bool removed =
+ RemoveStreamFromWriteBlockedList(stream_id, iter->second);
+ DCHECK(removed);
+ }
+ }
+ if (should_insert_stream) {
+ stream_to_priority_[stream_id] = priority;
+ if (push_back) {
+ write_blocked_lists_[priority].push_back(stream_id);
+ } else {
+ write_blocked_lists_[priority].push_front(stream_id);
+ }
+ }
+ }
+ BlockedList write_blocked_lists_[kV3LowestPriority + 1];
StreamToPriorityMap stream_to_priority_;
};
diff --git a/chromium/net/spdy/write_blocked_list_test.cc b/chromium/net/spdy/write_blocked_list_test.cc
index 20a1b7e43d0..933dc715b8f 100644
--- a/chromium/net/spdy/write_blocked_list_test.cc
+++ b/chromium/net/spdy/write_blocked_list_test.cc
@@ -78,6 +78,34 @@ TEST_F(WriteBlockedListTest, PopFront) {
EXPECT_EQ(3, list.PopFront(4));
}
+TEST_F(WriteBlockedListTest, PushFront) {
+ list.PushFront(1, 4);
+ EXPECT_EQ(1u, list.NumBlockedStreams());
+ list.PushFront(2, 4);
+ list.PushFront(1, 4);
+ list.PushFront(3, 4);
+ EXPECT_EQ(3u, list.NumBlockedStreams());
+
+ EXPECT_EQ(3, list.PopFront(4));
+ EXPECT_EQ(2, list.PopFront(4));
+ EXPECT_EQ(1u, list.NumBlockedStreams());
+ EXPECT_EQ(1, list.PopFront(4));
+}
+
+TEST_F(WriteBlockedListTest, PushFrontAndBack) {
+ list.PushFront(1, 4);
+ list.PushBack(5, 4);
+ list.PushFront(2, 4);
+ list.PushBack(3, 4);
+ list.PushFront(4, 4);
+
+ EXPECT_EQ(4, list.PopFront(4));
+ EXPECT_EQ(2, list.PopFront(4));
+ EXPECT_EQ(1, list.PopFront(4));
+ EXPECT_EQ(5, list.PopFront(4));
+ EXPECT_EQ(3, list.PopFront(4));
+}
+
TEST_F(WriteBlockedListTest, UpdateStreamPriorityInWriteBlockedList) {
list.PushBack(1, 1);
list.PushBack(2, 2);
diff --git a/chromium/net/ssl/channel_id_service.cc b/chromium/net/ssl/channel_id_service.cc
index cfa61ccdde7..e17b813cd73 100644
--- a/chromium/net/ssl/channel_id_service.cc
+++ b/chromium/net/ssl/channel_id_service.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <limits>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -13,6 +14,7 @@
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
@@ -93,18 +95,18 @@ scoped_ptr<ChannelIDStore::ChannelID> GenerateChannelID(
if (!key) {
DLOG(ERROR) << "Unable to create channel ID key pair";
*error = ERR_KEY_GENERATION_FAILED;
- return result.Pass();
+ return result;
}
result.reset(new ChannelIDStore::ChannelID(server_identifier, creation_time,
- key.Pass()));
+ std::move(key)));
UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.GenerateCertTime",
base::TimeTicks::Now() - start,
base::TimeDelta::FromMilliseconds(1),
base::TimeDelta::FromMinutes(5),
50);
*error = OK;
- return result.Pass();
+ return result;
}
} // namespace
@@ -182,7 +184,7 @@ class ChannelIDServiceJob {
}
void HandleResult(int error, scoped_ptr<crypto::ECPrivateKey> key) {
- PostAll(error, key.Pass());
+ PostAll(error, std::move(key));
}
bool CreateIfMissing() const { return create_if_missing_; }
@@ -203,7 +205,7 @@ class ChannelIDServiceJob {
scoped_ptr<crypto::ECPrivateKey> key_copy;
if (key)
key_copy.reset(key->Copy());
- (*i)->Post(error, key_copy.Pass());
+ (*i)->Post(error, std::move(key_copy));
}
}
@@ -274,7 +276,7 @@ void ChannelIDService::Request::Post(int error,
service_ = NULL;
DCHECK(!callback_.is_null());
if (key)
- *key_ = key.Pass();
+ *key_ = std::move(key);
// Running the callback might delete |this| (e.g. the callback cleans up
// resources created for the request), so we can't touch any of our
// members afterwards. Reset callback_ first.
@@ -412,14 +414,14 @@ void ChannelIDService::GotChannelID(int err,
// Async DB lookup found a valid channel ID.
key_store_hits_++;
// ChannelIDService::Request::Post will do the histograms and stuff.
- HandleResult(OK, server_identifier, key.Pass());
+ HandleResult(OK, server_identifier, std::move(key));
return;
}
// Async lookup failed or the channel ID was missing. Return the error
// directly, unless the channel ID was missing and a request asked to create
// one.
if (err != ERR_FILE_NOT_FOUND || !j->second->CreateIfMissing()) {
- HandleResult(err, server_identifier, key.Pass());
+ HandleResult(err, server_identifier, std::move(key));
return;
}
// At least one request asked to create a channel ID => start generating a new
@@ -449,9 +451,9 @@ void ChannelIDService::GeneratedChannelID(
scoped_ptr<crypto::ECPrivateKey> key;
if (error == OK) {
key.reset(channel_id->key()->Copy());
- channel_id_store_->SetChannelID(channel_id.Pass());
+ channel_id_store_->SetChannelID(std::move(channel_id));
}
- HandleResult(error, server_identifier, key.Pass());
+ HandleResult(error, server_identifier, std::move(key));
}
void ChannelIDService::HandleResult(int error,
@@ -468,7 +470,7 @@ void ChannelIDService::HandleResult(int error,
ChannelIDServiceJob* job = j->second;
inflight_.erase(j);
- job->HandleResult(error, key.Pass());
+ job->HandleResult(error, std::move(key));
delete job;
}
diff --git a/chromium/net/ssl/channel_id_service.h b/chromium/net/ssl/channel_id_service.h
index abb22fa6862..eb4a92ae6f5 100644
--- a/chromium/net/ssl/channel_id_service.h
+++ b/chromium/net/ssl/channel_id_service.h
@@ -5,11 +5,13 @@
#ifndef NET_SSL_CHANNEL_ID_SERVICE_H_
#define NET_SSL_CHANNEL_ID_SERVICE_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
@@ -129,10 +131,10 @@ class NET_EXPORT ChannelIDService
// Public only for unit testing.
int channel_id_count();
- uint64 requests() const { return requests_; }
- uint64 key_store_hits() const { return key_store_hits_; }
- uint64 inflight_joins() const { return inflight_joins_; }
- uint64 workers_created() const { return workers_created_; }
+ uint64_t requests() const { return requests_; }
+ uint64_t key_store_hits() const { return key_store_hits_; }
+ uint64_t inflight_joins() const { return inflight_joins_; }
+ uint64_t workers_created() const { return workers_created_; }
private:
void GotChannelID(int err,
@@ -174,10 +176,10 @@ class NET_EXPORT ChannelIDService
// place.
std::map<std::string, ChannelIDServiceJob*> inflight_;
- uint64 requests_;
- uint64 key_store_hits_;
- uint64 inflight_joins_;
- uint64 workers_created_;
+ uint64_t requests_;
+ uint64_t key_store_hits_;
+ uint64_t inflight_joins_;
+ uint64_t workers_created_;
base::WeakPtrFactory<ChannelIDService> weak_ptr_factory_;
diff --git a/chromium/net/ssl/channel_id_service_unittest.cc b/chromium/net/ssl/channel_id_service_unittest.cc
index 2a2ec962d50..1e98b61a674 100644
--- a/chromium/net/ssl/channel_id_service_unittest.cc
+++ b/chromium/net/ssl/channel_id_service_unittest.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/net/ssl/channel_id_store.cc b/chromium/net/ssl/channel_id_store.cc
index e1835ff1546..1345da13cbb 100644
--- a/chromium/net/ssl/channel_id_store.cc
+++ b/chromium/net/ssl/channel_id_store.cc
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "crypto/ec_private_key.h"
#include "net/ssl/channel_id_store.h"
+#include <utility>
+
+#include "crypto/ec_private_key.h"
+
namespace net {
ChannelIDStore::ChannelID::ChannelID() {
@@ -15,8 +18,7 @@ ChannelIDStore::ChannelID::ChannelID(const std::string& server_identifier,
scoped_ptr<crypto::ECPrivateKey> key)
: server_identifier_(server_identifier),
creation_time_(creation_time),
- key_(key.Pass()) {
-}
+ key_(std::move(key)) {}
ChannelIDStore::ChannelID::ChannelID(const ChannelID& other)
: server_identifier_(other.server_identifier_),
diff --git a/chromium/net/ssl/client_cert_store.h b/chromium/net/ssl/client_cert_store.h
index b1172deb7d9..f87c22ee47f 100644
--- a/chromium/net/ssl/client_cert_store.h
+++ b/chromium/net/ssl/client_cert_store.h
@@ -5,8 +5,8 @@
#ifndef NET_SSL_CLIENT_CERT_STORE_H_
#define NET_SSL_CLIENT_CERT_STORE_H_
-#include "base/basictypes.h"
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
diff --git a/chromium/net/ssl/client_cert_store_mac.h b/chromium/net/ssl/client_cert_store_mac.h
index bca35b31eda..aade83ce595 100644
--- a/chromium/net/ssl/client_cert_store_mac.h
+++ b/chromium/net/ssl/client_cert_store_mac.h
@@ -5,8 +5,8 @@
#ifndef NET_SSL_CLIENT_CERT_STORE_MAC_H_
#define NET_SSL_CLIENT_CERT_STORE_MAC_H_
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/ssl/client_cert_store.h"
#include "net/ssl/ssl_cert_request_info.h"
diff --git a/chromium/net/ssl/client_cert_store_nss.cc b/chromium/net/ssl/client_cert_store_nss.cc
index 169351710b5..8a6c329b58f 100644
--- a/chromium/net/ssl/client_cert_store_nss.cc
+++ b/chromium/net/ssl/client_cert_store_nss.cc
@@ -6,6 +6,7 @@
#include <nss.h>
#include <ssl.h>
+#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -117,7 +118,7 @@ void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread(
const SSLCertRequestInfo* request,
CertificateList* selected_certs) {
CertificateList platform_certs;
- GetPlatformCertsOnWorkerThread(password_delegate.Pass(), &platform_certs);
+ GetPlatformCertsOnWorkerThread(std::move(password_delegate), &platform_certs);
FilterCertsOnWorkerThread(platform_certs, *request, true, selected_certs);
}
diff --git a/chromium/net/ssl/client_cert_store_win.cc b/chromium/net/ssl/client_cert_store_win.cc
index 2e9763ffdb2..1ebf02d79ef 100644
--- a/chromium/net/ssl/client_cert_store_win.cc
+++ b/chromium/net/ssl/client_cert_store_win.cc
@@ -13,7 +13,6 @@
#include "base/callback.h"
#include "base/logging.h"
-#include "crypto/scoped_capi_types.h"
#include "crypto/wincrypt_shim.h"
#include "net/cert/x509_util.h"
@@ -99,7 +98,7 @@ void GetClientCertsImpl(HCERTSTORE cert_store,
&find_by_issuer_para,
chain_context);
if (!chain_context) {
- if (GetLastError() != CRYPT_E_NOT_FOUND)
+ if (GetLastError() != static_cast<DWORD>(CRYPT_E_NOT_FOUND))
DPLOG(ERROR) << "CertFindChainInStore failed: ";
break;
}
@@ -129,6 +128,11 @@ void GetClientCertsImpl(HCERTSTORE cert_store,
if (ok)
intermediates.push_back(copied_intermediate);
}
+ // TODO(svaldez): cert currently wraps cert_context2 which may be backed
+ // by a smartcard with threading difficulties. Instead, create a fresh
+ // X509Certificate with CreateFromBytes and route cert_context2 into the
+ // SSLPrivateKey. Probably changing CertificateList to be a
+ // pair<X509Certificate, SSLPrivateKeyCallback>.
scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
cert_context2, intermediates);
selected_certs->push_back(cert);
@@ -145,13 +149,30 @@ void GetClientCertsImpl(HCERTSTORE cert_store,
ClientCertStoreWin::ClientCertStoreWin() {}
+ClientCertStoreWin::ClientCertStoreWin(HCERTSTORE cert_store) {
+ DCHECK(cert_store);
+ cert_store_.reset(cert_store);
+}
+
ClientCertStoreWin::~ClientCertStoreWin() {}
void ClientCertStoreWin::GetClientCerts(const SSLCertRequestInfo& request,
- CertificateList* selected_certs,
- const base::Closure& callback) {
- // Client certificates of the user are in the "MY" system certificate store.
- HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
+ CertificateList* selected_certs,
+ const base::Closure& callback) {
+ if (cert_store_) {
+ // Use the existing client cert store. Note: Under some situations,
+ // it's possible for this to return certificates that aren't usable
+ // (see below).
+ GetClientCertsImpl(cert_store_, request, selected_certs);
+ callback.Run();
+ return;
+ }
+
+ // Always open a new instance of the "MY" store, to ensure that there
+ // are no previously cached certificates being reused after they're
+ // no longer available (some smartcard providers fail to update the "MY"
+ // store handles and instead interpose CertOpenSystemStore).
+ ScopedHCERTSTORE my_cert_store(CertOpenSystemStore(NULL, L"MY"));
if (!my_cert_store) {
PLOG(ERROR) << "Could not open the \"MY\" system certificate store: ";
selected_certs->clear();
@@ -160,8 +181,7 @@ void ClientCertStoreWin::GetClientCerts(const SSLCertRequestInfo& request,
}
GetClientCertsImpl(my_cert_store, request, selected_certs);
- if (!CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG))
- PLOG(ERROR) << "Could not close the \"MY\" system certificate store: ";
+
callback.Run();
}
@@ -169,11 +189,6 @@ bool ClientCertStoreWin::SelectClientCertsForTesting(
const CertificateList& input_certs,
const SSLCertRequestInfo& request,
CertificateList* selected_certs) {
- typedef crypto::ScopedCAPIHandle<
- HCERTSTORE,
- crypto::CAPIDestroyerWithFlags<HCERTSTORE,
- CertCloseStore, 0> > ScopedHCERTSTORE;
-
ScopedHCERTSTORE test_store(CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0,
NULL));
if (!test_store)
diff --git a/chromium/net/ssl/client_cert_store_win.h b/chromium/net/ssl/client_cert_store_win.h
index 48500fa6d1e..ffbb301bd20 100644
--- a/chromium/net/ssl/client_cert_store_win.h
+++ b/chromium/net/ssl/client_cert_store_win.h
@@ -5,8 +5,9 @@
#ifndef NET_SSL_CLIENT_CERT_STORE_WIN_H_
#define NET_SSL_CLIENT_CERT_STORE_WIN_H_
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
+#include "crypto/scoped_capi_types.h"
#include "net/base/net_export.h"
#include "net/ssl/client_cert_store.h"
#include "net/ssl/ssl_cert_request_info.h"
@@ -15,15 +16,28 @@ namespace net {
class NET_EXPORT ClientCertStoreWin : public ClientCertStore {
public:
+ // Uses the "MY" current user system certificate store.
ClientCertStoreWin();
+
+ // Takes ownership of |cert_store| and closes it at destruction time.
+ explicit ClientCertStoreWin(HCERTSTORE cert_store);
+
~ClientCertStoreWin() override;
- // ClientCertStore:
+ // If a cert store has been provided at construction time GetClientCerts
+ // will use that. Otherwise it will use the current user's "MY" cert store
+ // instead.
void GetClientCerts(const SSLCertRequestInfo& cert_request_info,
CertificateList* selected_certs,
const base::Closure& callback) override;
private:
+ using ScopedHCERTSTORE = crypto::ScopedCAPIHandle<
+ HCERTSTORE,
+ crypto::CAPIDestroyerWithFlags<HCERTSTORE,
+ CertCloseStore,
+ CERT_CLOSE_STORE_CHECK_FLAG>>;
+
friend class ClientCertStoreWinTestDelegate;
// A hook for testing. Filters |input_certs| using the logic being used to
@@ -34,6 +48,8 @@ class NET_EXPORT ClientCertStoreWin : public ClientCertStore {
const SSLCertRequestInfo& cert_request_info,
CertificateList* selected_certs);
+ ScopedHCERTSTORE cert_store_;
+
DISALLOW_COPY_AND_ASSIGN(ClientCertStoreWin);
};
diff --git a/chromium/net/ssl/client_key_store.cc b/chromium/net/ssl/client_key_store.cc
index 358bc8e2f57..87dafec16b0 100644
--- a/chromium/net/ssl/client_key_store.cc
+++ b/chromium/net/ssl/client_key_store.cc
@@ -5,6 +5,7 @@
#include "net/ssl/client_key_store.h"
#include <algorithm>
+#include <utility>
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_private_key.h"
@@ -38,14 +39,14 @@ void ClientKeyStore::RemoveProvider(const CertKeyProvider* provider) {
providers_.erase(it);
}
-scoped_ptr<SSLPrivateKey> ClientKeyStore::FetchClientCertPrivateKey(
+scoped_refptr<SSLPrivateKey> ClientKeyStore::FetchClientCertPrivateKey(
const X509Certificate& certificate) {
base::AutoLock auto_lock(lock_);
for (const auto& provider : providers_) {
- scoped_ptr<SSLPrivateKey> key;
+ scoped_refptr<SSLPrivateKey> key;
if (provider->GetCertificateKey(certificate, &key))
- return key.Pass();
+ return key;
}
return nullptr;
}
diff --git a/chromium/net/ssl/client_key_store.h b/chromium/net/ssl/client_key_store.h
index 51eba4caad9..bab45f3267d 100644
--- a/chromium/net/ssl/client_key_store.h
+++ b/chromium/net/ssl/client_key_store.h
@@ -37,8 +37,9 @@ class NET_EXPORT ClientKeyStore {
// it knows about the certificate, but is unable to return the private key,
// returns true and sets |*private_key| to nullptr.
// This can be called from any thread.
- virtual bool GetCertificateKey(const X509Certificate& cert,
- scoped_ptr<SSLPrivateKey>* private_key) = 0;
+ virtual bool GetCertificateKey(
+ const X509Certificate& cert,
+ scoped_refptr<SSLPrivateKey>* private_key) = 0;
};
static ClientKeyStore* GetInstance();
@@ -53,7 +54,7 @@ class NET_EXPORT ClientKeyStore {
// Given a |certificate|'s public key, return the corresponding private
// key if any of the registered providers has a matching key.
// Returns its matching private key on success, nullptr otherwise.
- scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
+ scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
const X509Certificate& certificate);
private:
diff --git a/chromium/net/ssl/default_channel_id_store.cc b/chromium/net/ssl/default_channel_id_store.cc
index b0497e1f631..8fff6f04132 100644
--- a/chromium/net/ssl/default_channel_id_store.cc
+++ b/chromium/net/ssl/default_channel_id_store.cc
@@ -4,6 +4,8 @@
#include "net/ssl/default_channel_id_store.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
@@ -68,7 +70,7 @@ void DefaultChannelIDStore::GetChannelIDTask::Run(
DCHECK(err != ERR_IO_PENDING);
InvokeCallback(base::Bind(callback_, err, server_identifier_,
- base::Passed(key_result.Pass())));
+ base::Passed(std::move(key_result))));
}
// --------------------------------------------------------------------------
@@ -86,15 +88,14 @@ class DefaultChannelIDStore::SetChannelIDTask
DefaultChannelIDStore::SetChannelIDTask::SetChannelIDTask(
scoped_ptr<ChannelID> channel_id)
- : channel_id_(channel_id.Pass()) {
-}
+ : channel_id_(std::move(channel_id)) {}
DefaultChannelIDStore::SetChannelIDTask::~SetChannelIDTask() {
}
void DefaultChannelIDStore::SetChannelIDTask::Run(
DefaultChannelIDStore* store) {
- store->SyncSetChannelID(channel_id_.Pass());
+ store->SyncSetChannelID(std::move(channel_id_));
}
// --------------------------------------------------------------------------
@@ -235,7 +236,7 @@ int DefaultChannelIDStore::GetChannelID(
}
void DefaultChannelIDStore::SetChannelID(scoped_ptr<ChannelID> channel_id) {
- auto task = new SetChannelIDTask(channel_id.Pass());
+ auto task = new SetChannelIDTask(std::move(channel_id));
RunOrEnqueueTask(scoped_ptr<Task>(task));
}
@@ -302,16 +303,16 @@ void DefaultChannelIDStore::InitStore() {
}
void DefaultChannelIDStore::OnLoaded(
- scoped_ptr<ScopedVector<ChannelID> > channel_ids) {
+ scoped_ptr<std::vector<scoped_ptr<ChannelID>>> channel_ids) {
DCHECK(CalledOnValidThread());
-
- for (std::vector<ChannelID*>::const_iterator it = channel_ids->begin();
+ for (std::vector<scoped_ptr<ChannelID>>::iterator it = channel_ids->begin();
it != channel_ids->end(); ++it) {
DCHECK(channel_ids_.find((*it)->server_identifier()) ==
channel_ids_.end());
- channel_ids_[(*it)->server_identifier()] = *it;
+ std::string ident = (*it)->server_identifier();
+ channel_ids_[ident] = it->release();
}
- channel_ids->weak_clear();
+ channel_ids->clear();
loaded_ = true;
@@ -327,10 +328,8 @@ void DefaultChannelIDStore::OnLoaded(
UMA_HISTOGRAM_COUNTS_100("DomainBoundCerts.TaskWaitCount",
waiting_tasks_.size());
-
- for (ScopedVector<Task>::iterator i = waiting_tasks_.begin();
- i != waiting_tasks_.end(); ++i)
- (*i)->Run(this);
+ for (scoped_ptr<Task>& i : waiting_tasks_)
+ i->Run(this);
waiting_tasks_.clear();
}
@@ -339,7 +338,7 @@ void DefaultChannelIDStore::SyncSetChannelID(scoped_ptr<ChannelID> channel_id) {
DCHECK(loaded_);
InternalDeleteChannelID(channel_id->server_identifier());
- InternalInsertChannelID(channel_id.Pass());
+ InternalInsertChannelID(std::move(channel_id));
}
void DefaultChannelIDStore::SyncDeleteChannelID(
@@ -384,7 +383,7 @@ void DefaultChannelIDStore::EnqueueTask(scoped_ptr<Task> task) {
DCHECK(!loaded_);
if (waiting_tasks_.empty())
waiting_tasks_start_time_ = base::TimeTicks::Now();
- waiting_tasks_.push_back(task.Pass());
+ waiting_tasks_.push_back(std::move(task));
}
void DefaultChannelIDStore::RunOrEnqueueTask(scoped_ptr<Task> task) {
@@ -392,7 +391,7 @@ void DefaultChannelIDStore::RunOrEnqueueTask(scoped_ptr<Task> task) {
InitIfNecessary();
if (!loaded_) {
- EnqueueTask(task.Pass());
+ EnqueueTask(std::move(task));
return;
}
diff --git a/chromium/net/ssl/default_channel_id_store.h b/chromium/net/ssl/default_channel_id_store.h
index db6ee97641a..52eb1d01947 100644
--- a/chromium/net/ssl/default_channel_id_store.h
+++ b/chromium/net/ssl/default_channel_id_store.h
@@ -11,6 +11,7 @@
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
@@ -93,7 +94,7 @@ class NET_EXPORT DefaultChannelIDStore : public ChannelIDStore {
void InitStore();
// Callback for backing store loading completion.
- void OnLoaded(scoped_ptr<ScopedVector<ChannelID> > certs);
+ void OnLoaded(scoped_ptr<std::vector<scoped_ptr<ChannelID>>> certs);
// Syncronous methods which do the actual work. Can only be called after
// initialization is complete.
@@ -127,7 +128,7 @@ class NET_EXPORT DefaultChannelIDStore : public ChannelIDStore {
bool loaded_;
// Tasks that are waiting to be run once we finish loading.
- ScopedVector<Task> waiting_tasks_;
+ std::vector<scoped_ptr<Task>> waiting_tasks_;
base::TimeTicks waiting_tasks_start_time_;
scoped_refptr<PersistentStore> store_;
@@ -145,7 +146,7 @@ typedef base::RefCountedThreadSafe<DefaultChannelIDStore::PersistentStore>
class NET_EXPORT DefaultChannelIDStore::PersistentStore
: public RefcountedPersistentStore {
public:
- typedef base::Callback<void(scoped_ptr<ScopedVector<ChannelID> >)>
+ typedef base::Callback<void(scoped_ptr<std::vector<scoped_ptr<ChannelID>>>)>
LoadedCallback;
// Initializes the store and retrieves the existing channel_ids. This will be
diff --git a/chromium/net/ssl/default_channel_id_store_unittest.cc b/chromium/net/ssl/default_channel_id_store_unittest.cc
index fce807f0f6c..80f0657c086 100644
--- a/chromium/net/ssl/default_channel_id_store_unittest.cc
+++ b/chromium/net/ssl/default_channel_id_store_unittest.cc
@@ -6,6 +6,7 @@
#include <map>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -45,7 +46,7 @@ class AsyncGetChannelIDHelper {
scoped_ptr<crypto::ECPrivateKey> key_result) {
err_ = err;
server_identifier_ = server_identifier;
- key_ = key_result.Pass();
+ key_ = std::move(key_result);
called_ = true;
}
@@ -87,13 +88,14 @@ class MockPersistentStore
MockPersistentStore::MockPersistentStore() {}
void MockPersistentStore::Load(const LoadedCallback& loaded_callback) {
- scoped_ptr<ScopedVector<DefaultChannelIDStore::ChannelID> >
- channel_ids(new ScopedVector<DefaultChannelIDStore::ChannelID>());
+ scoped_ptr<std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>>
+ channel_ids(
+ new std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>());
ChannelIDMap::iterator it;
for (it = channel_ids_.begin(); it != channel_ids_.end(); ++it) {
channel_ids->push_back(
- new DefaultChannelIDStore::ChannelID(it->second));
+ make_scoped_ptr(new DefaultChannelIDStore::ChannelID(it->second)));
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chromium/net/ssl/openssl_client_key_store.h b/chromium/net/ssl/openssl_client_key_store.h
index 16904ef3031..269565bfd36 100644
--- a/chromium/net/ssl/openssl_client_key_store.h
+++ b/chromium/net/ssl/openssl_client_key_store.h
@@ -9,7 +9,7 @@
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "crypto/openssl_util.h"
diff --git a/chromium/net/ssl/openssl_ssl_util.cc b/chromium/net/ssl/openssl_ssl_util.cc
index b6d48c75d57..b91acdd97a2 100644
--- a/chromium/net/ssl/openssl_ssl_util.cc
+++ b/chromium/net/ssl/openssl_ssl_util.cc
@@ -5,9 +5,9 @@
#include "net/ssl/openssl_ssl_util.h"
#include <errno.h>
-
#include <openssl/err.h>
#include <openssl/ssl.h>
+#include <utility>
#include "base/bind.h"
#include "base/lazy_instance.h"
@@ -69,7 +69,6 @@ int MapOpenSSLErrorSSL(uint32_t error_code) {
case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE:
case SSL_R_UNKNOWN_SSL_VERSION:
return ERR_NOT_IMPLEMENTED;
- case SSL_R_UNSUPPORTED_SSL_VERSION:
case SSL_R_NO_CIPHER_MATCH:
case SSL_R_NO_SHARED_CIPHER:
case SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY:
@@ -94,38 +93,6 @@ int MapOpenSSLErrorSSL(uint32_t error_code) {
return ERR_SSL_UNRECOGNIZED_NAME_ALERT;
case SSL_R_BAD_DH_P_LENGTH:
return ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY;
- // SSL_R_UNKNOWN_PROTOCOL is reported if premature application data is
- // received (see http://crbug.com/42538), and also if all the protocol
- // versions supported by the server were disabled in this socket instance.
- // Mapped to ERR_SSL_PROTOCOL_ERROR for compatibility with other SSL sockets
- // in the former scenario.
- case SSL_R_UNKNOWN_PROTOCOL:
- case SSL_R_SSL_HANDSHAKE_FAILURE:
- case SSL_R_DECRYPTION_FAILED:
- case SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC:
- case SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG:
- case SSL_R_DIGEST_CHECK_FAILED:
- case SSL_R_ENCRYPTED_LENGTH_TOO_LONG:
- case SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST:
- case SSL_R_EXCESSIVE_MESSAGE_SIZE:
- case SSL_R_EXTRA_DATA_IN_MESSAGE:
- case SSL_R_GOT_A_FIN_BEFORE_A_CCS:
- case SSL_R_INVALID_COMMAND:
- case SSL_R_INVALID_TICKET_KEYS_LENGTH:
- // SSL_do_handshake reports this error when the server responds to a
- // ClientHello with a fatal close_notify alert.
- case SSL_R_SSLV3_ALERT_CLOSE_NOTIFY:
- case SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE:
- case SSL_R_SSLV3_ALERT_NO_CERTIFICATE:
- case SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER:
- case SSL_R_TLSV1_ALERT_DECODE_ERROR:
- case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:
- case SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION:
- case SSL_R_TLSV1_ALERT_INTERNAL_ERROR:
- case SSL_R_TLSV1_ALERT_NO_RENEGOTIATION:
- case SSL_R_TLSV1_ALERT_RECORD_OVERFLOW:
- case SSL_R_TLSV1_ALERT_USER_CANCELLED:
- return ERR_SSL_PROTOCOL_ERROR;
case SSL_R_CERTIFICATE_VERIFY_FAILED:
// The only way that the certificate verify callback can fail is if
// the leaf certificate changed during a renegotiation.
@@ -145,7 +112,6 @@ int MapOpenSSLErrorSSL(uint32_t error_code) {
return ERR_SSL_PROTOCOL_ERROR;
}
default:
- LOG(WARNING) << "Unmapped error reason: " << ERR_GET_REASON(error_code);
return ERR_SSL_PROTOCOL_ERROR;
}
}
@@ -166,7 +132,7 @@ scoped_ptr<base::Value> NetLogOpenSSLErrorCallback(
dict->SetString("file", error_info.file);
if (error_info.line != 0)
dict->SetInteger("line", error_info.line);
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
@@ -179,8 +145,8 @@ void OpenSSLPutNetError(const tracked_objects::Location& location, int err) {
NOTREACHED();
err = ERR_INVALID_ARGUMENT;
}
- ERR_put_error(OpenSSLNetErrorLib(), err, location.function_name(),
- location.file_name(), location.line_number());
+ ERR_put_error(OpenSSLNetErrorLib(), 0 /* unused */, err, location.file_name(),
+ location.line_number());
}
int MapOpenSSLError(int err, const crypto::OpenSSLErrStackTracer& tracer) {
diff --git a/chromium/net/ssl/openssl_ssl_util.h b/chromium/net/ssl/openssl_ssl_util.h
index 6c886cc1c9c..af8b9abb15b 100644
--- a/chromium/net/ssl/openssl_ssl_util.h
+++ b/chromium/net/ssl/openssl_ssl_util.h
@@ -5,6 +5,8 @@
#ifndef NET_SSL_OPENSSL_SSL_UTIL_H_
#define NET_SSL_OPENSSL_SSL_UTIL_H_
+#include <stdint.h>
+
#include "net/log/net_log.h"
namespace crypto {
diff --git a/chromium/net/ssl/ssl_cipher_suite_names.cc b/chromium/net/ssl/ssl_cipher_suite_names.cc
index 0b21edb5217..2bfe72ac93f 100644
--- a/chromium/net/ssl/ssl_cipher_suite_names.cc
+++ b/chromium/net/ssl/ssl_cipher_suite_names.cc
@@ -31,7 +31,7 @@
namespace {
struct CipherSuite {
- uint16 cipher_suite, encoded;
+ uint16_t cipher_suite, encoded;
};
const struct CipherSuite kCipherSuites[] = {
@@ -199,9 +199,10 @@ const struct CipherSuite kCipherSuites[] = {
{0xc08b, 0x1087}, // TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
{0xc08c, 0xf7f}, // TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
{0xc08d, 0xf87}, // TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
- {0xcc13, 0x108f}, // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- {0xcc14, 0x0e8f}, // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- {0xcc15, 0x0a8f}, // TLS_DHE_RSA_WITH_CHACHA20_POLY1305
+ {0xcc13, 0x108f}, // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 (non-standard)
+ {0xcc14, 0x0e8f}, // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 (non-standard)
+ {0xcca8, 0x108f}, // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+ {0xcca9, 0x0e8f}, // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
};
const struct {
@@ -276,7 +277,7 @@ int CipherSuiteCmp(const void* ia, const void* ib) {
}
}
-bool GetCipherProperties(uint16 cipher_suite,
+bool GetCipherProperties(uint16_t cipher_suite,
int* out_key_exchange,
int* out_cipher,
int* out_mac) {
@@ -302,8 +303,8 @@ namespace net {
void SSLCipherSuiteToStrings(const char** key_exchange_str,
const char** cipher_str,
const char** mac_str,
- bool *is_aead,
- uint16 cipher_suite) {
+ bool* is_aead,
+ uint16_t cipher_suite) {
*key_exchange_str = *cipher_str = *mac_str = "???";
*is_aead = false;
@@ -349,26 +350,25 @@ void SSLVersionToString(const char** name, int ssl_version) {
}
bool ParseSSLCipherString(const std::string& cipher_string,
- uint16* cipher_suite) {
+ uint16_t* cipher_suite) {
int value = 0;
if (cipher_string.size() == 6 &&
base::StartsWith(cipher_string, "0x",
base::CompareCase::INSENSITIVE_ASCII) &&
base::HexStringToInt(cipher_string, &value)) {
- *cipher_suite = static_cast<uint16>(value);
+ *cipher_suite = static_cast<uint16_t>(value);
return true;
}
return false;
}
-bool IsSecureTLSCipherSuite(uint16 cipher_suite) {
+bool IsSecureTLSCipherSuite(uint16_t cipher_suite) {
int key_exchange, cipher, mac;
if (!GetCipherProperties(cipher_suite, &key_exchange, &cipher, &mac))
return false;
- // Only allow forward secure key exchanges.
+ // Only allow ECDHE key exchanges.
switch (key_exchange) {
- case 10: // DHE_RSA
case 14: // ECDHE_ECDSA
case 16: // ECDHE_RSA
break;
@@ -392,13 +392,14 @@ bool IsSecureTLSCipherSuite(uint16 cipher_suite) {
return true;
}
-bool IsFalseStartableTLSCipherSuite(uint16 cipher_suite) {
+bool IsTLSCipherSuiteAllowedByHTTP2(uint16_t cipher_suite) {
int key_exchange, cipher, mac;
if (!GetCipherProperties(cipher_suite, &key_exchange, &cipher, &mac))
return false;
- // Only allow ECDHE key exchanges.
+ // Only allow forward secure key exchanges.
switch (key_exchange) {
+ case 10: // DHE_RSA
case 14: // ECDHE_ECDSA
case 16: // ECDHE_RSA
break;
@@ -422,7 +423,7 @@ bool IsFalseStartableTLSCipherSuite(uint16 cipher_suite) {
return true;
}
-const char* ECCurveName(uint16 cipher_suite, int key_exchange_info) {
+const char* ECCurveName(uint16_t cipher_suite, int key_exchange_info) {
#if defined(USE_OPENSSL)
int key_exchange, cipher, mac;
if (!GetCipherProperties(cipher_suite, &key_exchange, &cipher, &mac))
diff --git a/chromium/net/ssl/ssl_cipher_suite_names.h b/chromium/net/ssl/ssl_cipher_suite_names.h
index 207dbfbb8ed..4651eb188a7 100644
--- a/chromium/net/ssl/ssl_cipher_suite_names.h
+++ b/chromium/net/ssl/ssl_cipher_suite_names.h
@@ -5,9 +5,10 @@
#ifndef NET_SSL_SSL_CIPHER_SUITE_NAMES_H_
#define NET_SSL_SSL_CIPHER_SUITE_NAMES_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "net/base/net_export.h"
namespace net {
@@ -23,7 +24,7 @@ NET_EXPORT void SSLCipherSuiteToStrings(const char** key_exchange_str,
const char** cipher_str,
const char** mac_str,
bool* is_aead,
- uint16 cipher_suite);
+ uint16_t cipher_suite);
// SSLVersionToString returns the name of the SSL protocol version
// specified by |ssl_version|, which is defined in
@@ -44,26 +45,27 @@ NET_EXPORT void SSLVersionToString(const char** name, int ssl_version);
// TODO(rsleevi): Support the full strings defined in the IANA TLS parameters
// list.
NET_EXPORT bool ParseSSLCipherString(const std::string& cipher_string,
- uint16* cipher_suite);
+ uint16_t* cipher_suite);
// |cipher_suite| is the IANA id for the cipher suite. What a "secure"
// cipher suite is arbitrarily determined here. The intent is to indicate what
// cipher suites meet modern security standards when backwards compatibility can
-// be ignored. Notably, HTTP/2 requires/encourages this sort of validation of
-// cipher suites: https://http2.github.io/http2-spec/#TLSUsage.
+// be ignored.
//
// Currently, this function follows these criteria:
-// 1) Only uses forward secure key exchanges
+// 1) Only uses ECDHE-based key exchanges authenticated by a certificate
// 2) Only uses AEADs
-NET_EXPORT bool IsSecureTLSCipherSuite(uint16 cipher_suite);
+NET_EXPORT bool IsSecureTLSCipherSuite(uint16_t cipher_suite);
-// Returns true if |cipher_suite| is suitable for use with False Start.
-NET_EXPORT bool IsFalseStartableTLSCipherSuite(uint16 cipher_suite);
+// Returns true if |cipher_suite| is suitable for use with HTTP/2. See
+// https://http2.github.io/http2-spec/#rfc.section.9.2.2.
+NET_EXPORT bool IsTLSCipherSuiteAllowedByHTTP2(uint16_t cipher_suite);
// Returns the static curve name of |key_exchange_info| if the |cipher_suite|
// is an elliptic curve, and a name is known. Returns nullptr otherwise.
// Only defined for OpenSSL, returns nullptr otherwise.
-NET_EXPORT const char* ECCurveName(uint16 cipher_suite, int key_exchange_info);
+NET_EXPORT const char* ECCurveName(uint16_t cipher_suite,
+ int key_exchange_info);
} // namespace net
diff --git a/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc b/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc
index 6334c30d686..cfa26e0a6b2 100644
--- a/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc
+++ b/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc
@@ -4,7 +4,7 @@
#include "net/ssl/ssl_cipher_suite_names.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -27,8 +27,15 @@ TEST(CipherSuiteNamesTest, Basic) {
EXPECT_TRUE(is_aead);
EXPECT_EQ(NULL, mac);
- SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, 0xcc15);
- EXPECT_STREQ("DHE_RSA", key_exchange);
+ SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, 0xcca9);
+ EXPECT_STREQ("ECDHE_ECDSA", key_exchange);
+ EXPECT_STREQ("CHACHA20_POLY1305", cipher);
+ EXPECT_TRUE(is_aead);
+ EXPECT_EQ(NULL, mac);
+
+ // Non-standard variant.
+ SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, 0xcc14);
+ EXPECT_STREQ("ECDHE_ECDSA", key_exchange);
EXPECT_STREQ("CHACHA20_POLY1305", cipher);
EXPECT_TRUE(is_aead);
EXPECT_EQ(NULL, mac);
@@ -41,7 +48,7 @@ TEST(CipherSuiteNamesTest, Basic) {
}
TEST(CipherSuiteNamesTest, ParseSSLCipherString) {
- uint16 cipher_suite = 0;
+ uint16_t cipher_suite = 0;
EXPECT_TRUE(ParseSSLCipherString("0x0004", &cipher_suite));
EXPECT_EQ(0x00004u, cipher_suite);
@@ -57,26 +64,78 @@ TEST(CipherSuiteNamesTest, ParseSSLCipherStringFails) {
};
for (size_t i = 0; i < arraysize(cipher_strings); ++i) {
- uint16 cipher_suite = 0;
+ uint16_t cipher_suite = 0;
EXPECT_FALSE(ParseSSLCipherString(cipher_strings[i], &cipher_suite));
}
}
TEST(CipherSuiteNamesTest, SecureCipherSuites) {
// Picked some random cipher suites.
- EXPECT_FALSE(IsSecureTLSCipherSuite(0x0));
- EXPECT_FALSE(IsSecureTLSCipherSuite(0x39));
- EXPECT_FALSE(IsSecureTLSCipherSuite(0xc5));
- EXPECT_FALSE(IsSecureTLSCipherSuite(0xc00f));
- EXPECT_FALSE(IsSecureTLSCipherSuite(0xc083));
+ EXPECT_FALSE(IsSecureTLSCipherSuite(0x0 /* TLS_NULL_WITH_NULL_NULL */));
+ EXPECT_FALSE(
+ IsSecureTLSCipherSuite(0x39 /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */));
+ EXPECT_FALSE(IsSecureTLSCipherSuite(
+ 0xc5 /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */));
+ EXPECT_FALSE(
+ IsSecureTLSCipherSuite(0xc00f /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */));
+ EXPECT_FALSE(IsSecureTLSCipherSuite(
+ 0xc083 /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */));
+ EXPECT_FALSE(
+ IsSecureTLSCipherSuite(0x9e /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */));
+ EXPECT_FALSE(
+ IsSecureTLSCipherSuite(0xc014 /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */));
+ EXPECT_FALSE(
+ IsSecureTLSCipherSuite(0x9c /* TLS_RSA_WITH_AES_128_GCM_SHA256 */));
// Non-existent cipher suite.
EXPECT_FALSE(IsSecureTLSCipherSuite(0xffff)) << "Doesn't exist!";
// Secure ones.
- EXPECT_TRUE(IsSecureTLSCipherSuite(0xcc13));
- EXPECT_TRUE(IsSecureTLSCipherSuite(0xcc14));
- EXPECT_TRUE(IsSecureTLSCipherSuite(0xcc15));
+ EXPECT_TRUE(IsSecureTLSCipherSuite(
+ 0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */));
+ EXPECT_TRUE(IsSecureTLSCipherSuite(
+ 0xcc13 /* ECDHE_RSA_WITH_CHACHA20_POLY1305 (non-standard) */));
+ EXPECT_TRUE(IsSecureTLSCipherSuite(
+ 0xcc14 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305 (non-standard) */));
+ EXPECT_TRUE(IsSecureTLSCipherSuite(
+ 0xcca8 /* ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */));
+ EXPECT_TRUE(IsSecureTLSCipherSuite(
+ 0xcca9 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */));
+}
+
+TEST(CipherSuiteNamesTest, HTTP2CipherSuites) {
+ // Picked some random cipher suites.
+ EXPECT_FALSE(
+ IsTLSCipherSuiteAllowedByHTTP2(0x0 /* TLS_NULL_WITH_NULL_NULL */));
+ EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0x39 /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */));
+ EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xc5 /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */));
+ EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xc00f /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */));
+ EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xc083 /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */));
+ EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xc014 /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */));
+ EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0x9c /* TLS_RSA_WITH_AES_128_GCM_SHA256 */));
+
+ // Non-existent cipher suite.
+ EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(0xffff)) << "Doesn't exist!";
+
+ // HTTP/2-compatible ones.
+ EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0x9e /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */));
+ EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */));
+ EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xcc13 /* ECDHE_RSA_WITH_CHACHA20_POLY1305 (non-standard) */));
+ EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xcc14 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305 (non-standard) */));
+ EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xcca8 /* ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */));
+ EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(
+ 0xcca9 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */));
}
} // anonymous namespace
diff --git a/chromium/net/ssl/ssl_client_auth_cache.cc b/chromium/net/ssl/ssl_client_auth_cache.cc
index 4c6b0d82f15..ba60c1bc5fe 100644
--- a/chromium/net/ssl/ssl_client_auth_cache.cc
+++ b/chromium/net/ssl/ssl_client_auth_cache.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "net/cert/x509_certificate.h"
+#include "net/ssl/ssl_private_key.h"
namespace net {
@@ -17,22 +18,24 @@ SSLClientAuthCache::~SSLClientAuthCache() {
CertDatabase::GetInstance()->RemoveObserver(this);
}
-bool SSLClientAuthCache::Lookup(
- const HostPortPair& server,
- scoped_refptr<X509Certificate>* certificate) {
+bool SSLClientAuthCache::Lookup(const HostPortPair& server,
+ scoped_refptr<X509Certificate>* certificate,
+ scoped_refptr<SSLPrivateKey>* private_key) {
DCHECK(certificate);
AuthCacheMap::iterator iter = cache_.find(server);
if (iter == cache_.end())
return false;
- *certificate = iter->second;
+ *certificate = iter->second.first;
+ *private_key = iter->second.second;
return true;
}
void SSLClientAuthCache::Add(const HostPortPair& server,
- X509Certificate* value) {
- cache_[server] = value;
+ X509Certificate* certificate,
+ SSLPrivateKey* private_key) {
+ cache_[server] = std::make_pair(certificate, private_key);
// TODO(wtc): enforce a maximum number of entries.
}
diff --git a/chromium/net/ssl/ssl_client_auth_cache.h b/chromium/net/ssl/ssl_client_auth_cache.h
index 53d5312a9ee..276fd37757f 100644
--- a/chromium/net/ssl/ssl_client_auth_cache.h
+++ b/chromium/net/ssl/ssl_client_auth_cache.h
@@ -7,12 +7,14 @@
#include <map>
#include <string>
+#include <utility>
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_export.h"
#include "net/cert/cert_database.h"
+#include "net/ssl/ssl_private_key.h"
namespace net {
@@ -36,13 +38,16 @@ class NET_EXPORT_PRIVATE SSLClientAuthCache : public CertDatabase::Observer {
// indicates a preference to not send any certificate to |server|.
// If a certificate preference is not found, returns false.
bool Lookup(const HostPortPair& server,
- scoped_refptr<X509Certificate>* certificate);
+ scoped_refptr<X509Certificate>* certificate,
+ scoped_refptr<SSLPrivateKey>* private_key);
- // Add a client certificate for |server| to the cache. If there is already
- // a client certificate for |server|, it will be overwritten. A NULL
- // |client_cert| indicates a preference that no client certificate should
- // be sent to |server|.
- void Add(const HostPortPair& server, X509Certificate* client_cert);
+ // Add a client certificate and private key for |server| to the cache. If
+ // there is already a client certificate for |server|, it will be
+ // overwritten. A NULL |client_cert| indicates a preference that no client
+ // certificate should be sent to |server|.
+ void Add(const HostPortPair& server,
+ X509Certificate* client_cert,
+ SSLPrivateKey* private_key);
// Remove the client certificate for |server| from the cache, if one exists.
void Remove(const HostPortPair& server);
@@ -52,7 +57,8 @@ class NET_EXPORT_PRIVATE SSLClientAuthCache : public CertDatabase::Observer {
private:
typedef HostPortPair AuthCacheKey;
- typedef scoped_refptr<X509Certificate> AuthCacheValue;
+ typedef std::pair<scoped_refptr<X509Certificate>,
+ scoped_refptr<SSLPrivateKey>> AuthCacheValue;
typedef std::map<AuthCacheKey, AuthCacheValue> AuthCacheMap;
// internal representation of cache, an STL map.
diff --git a/chromium/net/ssl/ssl_client_auth_cache_unittest.cc b/chromium/net/ssl/ssl_client_auth_cache_unittest.cc
index 567418a3fb4..3107ab8a605 100644
--- a/chromium/net/ssl/ssl_client_auth_cache_unittest.cc
+++ b/chromium/net/ssl/ssl_client_auth_cache_unittest.cc
@@ -4,12 +4,42 @@
#include "net/ssl/ssl_client_auth_cache.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "net/cert/x509_certificate.h"
+#include "net/ssl/ssl_private_key.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
+class MockSSLPrivateKey : public SSLPrivateKey {
+ public:
+ MockSSLPrivateKey() {}
+
+ Type GetType() override { return Type::RSA; }
+
+ std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
+ NOTIMPLEMENTED();
+ return std::vector<SSLPrivateKey::Hash>();
+ }
+
+ size_t GetMaxSignatureLengthInBytes() override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+
+ void SignDigest(Hash hash,
+ const base::StringPiece& input,
+ const SignCallback& callback) override {
+ NOTIMPLEMENTED();
+ }
+
+ private:
+ ~MockSSLPrivateKey() override {}
+
+ DISALLOW_COPY_AND_ASSIGN(MockSSLPrivateKey);
+};
+
TEST(SSLClientAuthCacheTest, LookupAddRemove) {
SSLClientAuthCache cache;
@@ -29,48 +59,49 @@ TEST(SSLClientAuthCacheTest, LookupAddRemove) {
new X509Certificate("foo3", "CA", start_date, expiration_date));
scoped_refptr<X509Certificate> cached_cert;
+ scoped_refptr<SSLPrivateKey> cached_pkey;
// Lookup non-existent client certificate.
cached_cert = NULL;
- EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
+ EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
// Add client certificate for server1.
- cache.Add(server1, cert1.get());
+ cache.Add(server1, cert1.get(), new MockSSLPrivateKey);
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(cert1, cached_cert);
// Add client certificate for server2.
- cache.Add(server2, cert2.get());
+ cache.Add(server2, cert2.get(), new MockSSLPrivateKey);
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(cert1.get(), cached_cert.get());
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
EXPECT_EQ(cert2, cached_cert);
// Overwrite the client certificate for server1.
- cache.Add(server1, cert3.get());
+ cache.Add(server1, cert3.get(), new MockSSLPrivateKey);
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(cert3, cached_cert);
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
EXPECT_EQ(cert2, cached_cert);
// Remove client certificate of server1.
cache.Remove(server1);
cached_cert = NULL;
- EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
+ EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
EXPECT_EQ(cert2, cached_cert);
// Remove non-existent client certificate.
cache.Remove(server1);
cached_cert = NULL;
- EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
+ EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
EXPECT_EQ(cert2, cached_cert);
}
@@ -90,13 +121,14 @@ TEST(SSLClientAuthCacheTest, LookupWithPort) {
scoped_refptr<X509Certificate> cert2(
new X509Certificate("foo", "CA", start_date, expiration_date));
- cache.Add(server1, cert1.get());
- cache.Add(server2, cert2.get());
+ cache.Add(server1, cert1.get(), new MockSSLPrivateKey);
+ cache.Add(server2, cert2.get(), new MockSSLPrivateKey);
scoped_refptr<X509Certificate> cached_cert;
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ scoped_refptr<SSLPrivateKey> cached_pkey;
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(cert1.get(), cached_cert.get());
- EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
EXPECT_EQ(cert2.get(), cached_cert.get());
}
@@ -111,29 +143,30 @@ TEST(SSLClientAuthCacheTest, LookupNullPreference) {
scoped_refptr<X509Certificate> cert1(
new X509Certificate("foo", "CA", start_date, expiration_date));
- cache.Add(server1, NULL);
+ cache.Add(server1, NULL, new MockSSLPrivateKey);
scoped_refptr<X509Certificate> cached_cert(cert1);
+ scoped_refptr<SSLPrivateKey> cached_pkey;
// Make sure that |cached_cert| is updated to NULL, indicating the user
// declined to send a certificate to |server1|.
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(NULL, cached_cert.get());
// Remove the existing cached certificate.
cache.Remove(server1);
cached_cert = NULL;
- EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
+ EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
// Add a new preference for a specific certificate.
- cache.Add(server1, cert1.get());
+ cache.Add(server1, cert1.get(), new MockSSLPrivateKey);
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(cert1, cached_cert);
// Replace the specific preference with a NULL certificate.
- cache.Add(server1, NULL);
+ cache.Add(server1, NULL, new MockSSLPrivateKey);
cached_cert = NULL;
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(NULL, cached_cert.get());
}
@@ -147,25 +180,26 @@ TEST(SSLClientAuthCacheTest, OnCertAdded) {
scoped_refptr<X509Certificate> cert1(
new X509Certificate("foo", "CA", start_date, expiration_date));
- cache.Add(server1, cert1.get());
+ cache.Add(server1, cert1.get(), new MockSSLPrivateKey);
HostPortPair server2("foo2", 443);
- cache.Add(server2, NULL);
+ cache.Add(server2, NULL, new MockSSLPrivateKey);
scoped_refptr<X509Certificate> cached_cert;
+ scoped_refptr<SSLPrivateKey> cached_pkey;
// Demonstrate the set up is correct.
- EXPECT_TRUE(cache.Lookup(server1, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey));
EXPECT_EQ(cert1, cached_cert);
- EXPECT_TRUE(cache.Lookup(server2, &cached_cert));
+ EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey));
EXPECT_EQ(NULL, cached_cert.get());
cache.OnCertAdded(NULL);
// Check that we no longer have entries for either server.
- EXPECT_FALSE(cache.Lookup(server1, &cached_cert));
- EXPECT_FALSE(cache.Lookup(server2, &cached_cert));
+ EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey));
+ EXPECT_FALSE(cache.Lookup(server2, &cached_cert, &cached_pkey));
}
} // namespace net
diff --git a/chromium/net/ssl/ssl_client_session_cache_openssl.cc b/chromium/net/ssl/ssl_client_session_cache_openssl.cc
index a0f03247a7a..6246bd54365 100644
--- a/chromium/net/ssl/ssl_client_session_cache_openssl.cc
+++ b/chromium/net/ssl/ssl_client_session_cache_openssl.cc
@@ -26,7 +26,7 @@ size_t SSLClientSessionCacheOpenSSL::size() const {
return cache_.size();
}
-SSL_SESSION* SSLClientSessionCacheOpenSSL::Lookup(
+ScopedSSL_SESSION SSLClientSessionCacheOpenSSL::Lookup(
const std::string& cache_key) {
base::AutoLock lock(lock_);
@@ -44,7 +44,7 @@ SSL_SESSION* SSLClientSessionCacheOpenSSL::Lookup(
cache_.Erase(iter);
return nullptr;
}
- return iter->second->session.get();
+ return ScopedSSL_SESSION(SSL_SESSION_up_ref(iter->second->session.get()));
}
void SSLClientSessionCacheOpenSSL::Insert(const std::string& cache_key,
@@ -68,7 +68,7 @@ void SSLClientSessionCacheOpenSSL::Flush() {
void SSLClientSessionCacheOpenSSL::SetClockForTesting(
scoped_ptr<base::Clock> clock) {
- clock_ = clock.Pass();
+ clock_ = std::move(clock);
}
SSLClientSessionCacheOpenSSL::CacheEntry::CacheEntry() {
diff --git a/chromium/net/ssl/ssl_client_session_cache_openssl.h b/chromium/net/ssl/ssl_client_session_cache_openssl.h
index 9d2f4b57b9b..b74042ed4ff 100644
--- a/chromium/net/ssl/ssl_client_session_cache_openssl.h
+++ b/chromium/net/ssl/ssl_client_session_cache_openssl.h
@@ -6,6 +6,7 @@
#define NET_SSL_SSL_CLIENT_SESSION_CACHE_OPENSSL_H
#include <openssl/ssl.h>
+#include <stddef.h>
#include <string>
@@ -41,10 +42,8 @@ class NET_EXPORT SSLClientSessionCacheOpenSSL {
size_t size() const;
// Returns the session associated with |cache_key| and moves it to the front
- // of the MRU list. Returns null if there is none. The caller is responsible
- // for taking a reference to the pointer if the cache is destroyed or a call
- // to Insert is made.
- SSL_SESSION* Lookup(const std::string& cache_key);
+ // of the MRU list. Returns nullptr if there is none.
+ ScopedSSL_SESSION Lookup(const std::string& cache_key);
// Inserts |session| into the cache at |cache_key|. If there is an existing
// one, it is released. Every |expiration_check_count| calls, the cache is
diff --git a/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc b/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc
index 7d8799ae999..ee579f00ee5 100644
--- a/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc
+++ b/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc
@@ -25,26 +25,26 @@ TEST(SSLClientSessionCacheOpenSSLTest, Basic) {
EXPECT_EQ(1u, session2->references);
EXPECT_EQ(1u, session3->references);
- EXPECT_EQ(nullptr, cache.Lookup("key1"));
- EXPECT_EQ(nullptr, cache.Lookup("key2"));
+ EXPECT_EQ(nullptr, cache.Lookup("key1").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key2").get());
EXPECT_EQ(0u, cache.size());
cache.Insert("key1", session1.get());
- EXPECT_EQ(session1.get(), cache.Lookup("key1"));
- EXPECT_EQ(nullptr, cache.Lookup("key2"));
+ EXPECT_EQ(session1.get(), cache.Lookup("key1").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key2").get());
EXPECT_EQ(1u, cache.size());
cache.Insert("key2", session2.get());
- EXPECT_EQ(session1.get(), cache.Lookup("key1"));
- EXPECT_EQ(session2.get(), cache.Lookup("key2"));
+ EXPECT_EQ(session1.get(), cache.Lookup("key1").get());
+ EXPECT_EQ(session2.get(), cache.Lookup("key2").get());
EXPECT_EQ(2u, cache.size());
EXPECT_EQ(2u, session1->references);
EXPECT_EQ(2u, session2->references);
cache.Insert("key1", session3.get());
- EXPECT_EQ(session3.get(), cache.Lookup("key1"));
- EXPECT_EQ(session2.get(), cache.Lookup("key2"));
+ EXPECT_EQ(session3.get(), cache.Lookup("key1").get());
+ EXPECT_EQ(session2.get(), cache.Lookup("key2").get());
EXPECT_EQ(2u, cache.size());
EXPECT_EQ(1u, session1->references);
@@ -52,9 +52,9 @@ TEST(SSLClientSessionCacheOpenSSLTest, Basic) {
EXPECT_EQ(2u, session3->references);
cache.Flush();
- EXPECT_EQ(nullptr, cache.Lookup("key1"));
- EXPECT_EQ(nullptr, cache.Lookup("key2"));
- EXPECT_EQ(nullptr, cache.Lookup("key3"));
+ EXPECT_EQ(nullptr, cache.Lookup("key1").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key2").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key3").get());
EXPECT_EQ(0u, cache.size());
EXPECT_EQ(1u, session1->references);
@@ -71,27 +71,27 @@ TEST(SSLClientSessionCacheOpenSSLTest, DoubleInsert) {
ScopedSSL_SESSION session(SSL_SESSION_new());
EXPECT_EQ(1u, session->references);
- EXPECT_EQ(nullptr, cache.Lookup("key1"));
- EXPECT_EQ(nullptr, cache.Lookup("key2"));
+ EXPECT_EQ(nullptr, cache.Lookup("key1").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key2").get());
EXPECT_EQ(0u, cache.size());
cache.Insert("key1", session.get());
- EXPECT_EQ(session.get(), cache.Lookup("key1"));
- EXPECT_EQ(nullptr, cache.Lookup("key2"));
+ EXPECT_EQ(session.get(), cache.Lookup("key1").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key2").get());
EXPECT_EQ(1u, cache.size());
EXPECT_EQ(2u, session->references);
cache.Insert("key2", session.get());
- EXPECT_EQ(session.get(), cache.Lookup("key1"));
- EXPECT_EQ(session.get(), cache.Lookup("key2"));
+ EXPECT_EQ(session.get(), cache.Lookup("key1").get());
+ EXPECT_EQ(session.get(), cache.Lookup("key2").get());
EXPECT_EQ(2u, cache.size());
EXPECT_EQ(3u, session->references);
cache.Flush();
- EXPECT_EQ(nullptr, cache.Lookup("key1"));
- EXPECT_EQ(nullptr, cache.Lookup("key2"));
+ EXPECT_EQ(nullptr, cache.Lookup("key1").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key2").get());
EXPECT_EQ(0u, cache.size());
EXPECT_EQ(1u, session->references);
@@ -112,26 +112,26 @@ TEST(SSLClientSessionCacheOpenSSLTest, MaxEntries) {
cache.Insert("key1", session1.get());
cache.Insert("key2", session2.get());
cache.Insert("key3", session3.get());
- EXPECT_EQ(session1.get(), cache.Lookup("key1"));
- EXPECT_EQ(session2.get(), cache.Lookup("key2"));
- EXPECT_EQ(session3.get(), cache.Lookup("key3"));
+ EXPECT_EQ(session1.get(), cache.Lookup("key1").get());
+ EXPECT_EQ(session2.get(), cache.Lookup("key2").get());
+ EXPECT_EQ(session3.get(), cache.Lookup("key3").get());
EXPECT_EQ(3u, cache.size());
// On insertion of a fourth, the first is removed.
cache.Insert("key4", session4.get());
- EXPECT_EQ(nullptr, cache.Lookup("key1"));
- EXPECT_EQ(session4.get(), cache.Lookup("key4"));
- EXPECT_EQ(session3.get(), cache.Lookup("key3"));
- EXPECT_EQ(session2.get(), cache.Lookup("key2"));
+ EXPECT_EQ(nullptr, cache.Lookup("key1").get());
+ EXPECT_EQ(session4.get(), cache.Lookup("key4").get());
+ EXPECT_EQ(session3.get(), cache.Lookup("key3").get());
+ EXPECT_EQ(session2.get(), cache.Lookup("key2").get());
EXPECT_EQ(3u, cache.size());
// Despite being newest, the next to be removed is session4 as it was accessed
// least. recently.
cache.Insert("key1", session1.get());
- EXPECT_EQ(session1.get(), cache.Lookup("key1"));
- EXPECT_EQ(session2.get(), cache.Lookup("key2"));
- EXPECT_EQ(session3.get(), cache.Lookup("key3"));
- EXPECT_EQ(nullptr, cache.Lookup("key4"));
+ EXPECT_EQ(session1.get(), cache.Lookup("key1").get());
+ EXPECT_EQ(session2.get(), cache.Lookup("key2").get());
+ EXPECT_EQ(session3.get(), cache.Lookup("key3").get());
+ EXPECT_EQ(nullptr, cache.Lookup("key4").get());
EXPECT_EQ(3u, cache.size());
}
@@ -174,7 +174,7 @@ TEST(SSLClientSessionCacheOpenSSLTest, Expiration) {
// Perform one more lookup. This will expire all sessions but the last one.
cache.Lookup("key");
EXPECT_EQ(1u, cache.size());
- EXPECT_EQ(session.get(), cache.Lookup("key"));
+ EXPECT_EQ(session.get(), cache.Lookup("key").get());
for (size_t i = 0; i < kNumEntries - 1; i++) {
SCOPED_TRACE(i);
EXPECT_EQ(nullptr, cache.Lookup(base::SizeTToString(i)));
@@ -199,7 +199,7 @@ TEST(SSLClientSessionCacheOpenSSLTest, LookupExpirationCheck) {
// Insert an entry into the session cache.
ScopedSSL_SESSION session(SSL_SESSION_new());
cache.Insert("key", session.get());
- EXPECT_EQ(session.get(), cache.Lookup("key"));
+ EXPECT_EQ(session.get(), cache.Lookup("key").get());
EXPECT_EQ(1u, cache.size());
// Expire the session.
@@ -209,17 +209,17 @@ TEST(SSLClientSessionCacheOpenSSLTest, LookupExpirationCheck) {
EXPECT_EQ(1u, cache.size());
// But it will not be returned on lookup and gets pruned at that point.
- EXPECT_EQ(nullptr, cache.Lookup("key"));
+ EXPECT_EQ(nullptr, cache.Lookup("key").get());
EXPECT_EQ(0u, cache.size());
// Sessions also are treated as expired if the clock rewinds.
cache.Insert("key", session.get());
- EXPECT_EQ(session.get(), cache.Lookup("key"));
+ EXPECT_EQ(session.get(), cache.Lookup("key").get());
EXPECT_EQ(1u, cache.size());
clock->Advance(-kTimeout * 2);
- EXPECT_EQ(nullptr, cache.Lookup("key"));
+ EXPECT_EQ(nullptr, cache.Lookup("key").get());
EXPECT_EQ(0u, cache.size());
}
diff --git a/chromium/net/ssl/ssl_config.cc b/chromium/net/ssl/ssl_config.cc
index 412bf0068ae..e3ced671925 100644
--- a/chromium/net/ssl/ssl_config.cc
+++ b/chromium/net/ssl/ssl_config.cc
@@ -24,7 +24,8 @@ SSLConfig::SSLConfig()
version_min(kDefaultSSLVersionMin),
version_max(kDefaultSSLVersionMax),
version_fallback_min(kDefaultSSLVersionFallbackMin),
- enable_deprecated_cipher_suites(false),
+ deprecated_cipher_suites_enabled(false),
+ rc4_enabled(false),
channel_id_enabled(true),
false_start_enabled(true),
signed_cert_timestamps_enabled(true),
diff --git a/chromium/net/ssl/ssl_config.h b/chromium/net/ssl/ssl_config.h
index f1c70bb0dc4..5460f6640ef 100644
--- a/chromium/net/ssl/ssl_config.h
+++ b/chromium/net/ssl/ssl_config.h
@@ -11,13 +11,14 @@
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
#include "net/socket/next_proto.h"
+#include "net/ssl/ssl_private_key.h"
namespace net {
-// Various TLS/SSL ProtocolVersion values encoded as uint16
+// Various TLS/SSL ProtocolVersion values encoded as uint16_t
// struct {
-// uint8 major;
-// uint8 minor;
+// uint8_t major;
+// uint8_t minor;
// } ProtocolVersion;
// The most significant byte is |major|, and the least significant byte
// is |minor|.
@@ -27,6 +28,12 @@ enum {
SSL_PROTOCOL_VERSION_TLS1_2 = 0x0303,
};
+enum TokenBindingParam {
+ TB_PARAM_RSA2048_PKCS15 = 0,
+ TB_PARAM_RSA2048_PSS = 1,
+ TB_PARAM_ECDSAP256 = 2,
+};
+
// Default minimum protocol version.
NET_EXPORT extern const uint16_t kDefaultSSLVersionMin;
@@ -77,14 +84,14 @@ struct NET_EXPORT SSLConfig {
// (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined above.)
// SSL 2.0 and SSL 3.0 are not supported. If version_max < version_min, it
// means no protocol versions are enabled.
- uint16 version_min;
- uint16 version_max;
+ uint16_t version_min;
+ uint16_t version_max;
// version_fallback_min contains the minimum version that is acceptable to
// fallback to. Versions before this may be tried to see whether they would
// have succeeded and thus to give a better message to the user, but the
// resulting connection won't be used in these cases.
- uint16 version_fallback_min;
+ uint16_t version_fallback_min;
// Presorted list of cipher suites which should be explicitly prevented from
// being used in addition to those disabled by the net built-in policy.
@@ -102,17 +109,32 @@ struct NET_EXPORT SSLConfig {
// The ciphers listed in |disabled_cipher_suites| will be removed in addition
// to the above list.
//
- // Though cipher suites are sent in TLS as "uint8 CipherSuite[2]", in
+ // Though cipher suites are sent in TLS as "uint8_t CipherSuite[2]", in
// big-endian form, they should be declared in host byte order, with the
- // first uint8 occupying the most significant byte.
+ // first uint8_t occupying the most significant byte.
// Ex: To disable TLS_RSA_WITH_RC4_128_MD5, specify 0x0004, while to
// disable TLS_ECDH_ECDSA_WITH_RC4_128_SHA, specify 0xC002.
- std::vector<uint16> disabled_cipher_suites;
+ std::vector<uint16_t> disabled_cipher_suites;
+
+ // Enables deprecated cipher suites. These cipher suites are selected under a
+ // fallback to distinguish servers which require them from servers which
+ // merely prefer them.
+ //
+ // NOTE: because they are under a fallback, connections are still vulnerable
+ // to them as far as downgrades are concerned, so this should only be used for
+ // measurement of ciphers not to be carried long-term. It is no fix for
+ // servers with bad configurations without full removal.
+ bool deprecated_cipher_suites_enabled;
- // Enables deprecated cipher suites. Currently, RC4 is deprecated.
- bool enable_deprecated_cipher_suites;
+ // Enables RC4 cipher suites.
+ bool rc4_enabled;
bool channel_id_enabled; // True if TLS channel ID extension is enabled.
+
+ // List of Token Binding key parameters supported by the client. If empty,
+ // Token Binding will be disabled, even if token_binding_enabled is true.
+ 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.
@@ -154,13 +176,20 @@ struct NET_EXPORT SSLConfig {
// NOTE: Only used by NSS.
bool cert_io_enabled;
- // The list of application level protocols supported. If set, this will
- // enable Next Protocol Negotiation (if supported). The order of the
- // protocols doesn't matter expect for one case: if the server supports Next
- // Protocol Negotiation, but there is no overlap between the server's and
- // client's protocol sets, then the first protocol in this list will be
- // requested by the client.
- NextProtoVector next_protos;
+ // 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.
+ NextProtoVector alpn_protos;
+
+ // The list of application level protocols supported with NPN (Next Protocol
+ // Negotiation). The last item on the list is selected if there is no overlap
+ // between |npn_protos| and the protocols supported by the server, otherwise
+ // server preference is observed and the order of |npn_protos| is irrelevant.
+ // Note that due to NSS limitations, ports which use NSS will use
+ // |alpn_protos| for both ALPN and NPN. However, if |npn_protos| is empty, NPN
+ // will still be disabled.
+ // TODO(bnc): Deprecate NPN, see https://crbug.com/526713.
+ NextProtoVector npn_protos;
// True if renegotiation should be allowed for the default application-level
// protocol when the peer negotiates neither ALPN nor NPN.
@@ -170,6 +199,7 @@ struct NET_EXPORT SSLConfig {
NextProtoVector renego_allowed_for_protos;
scoped_refptr<X509Certificate> client_cert;
+ scoped_refptr<SSLPrivateKey> client_private_key;
};
} // namespace net
diff --git a/chromium/net/ssl/ssl_config_service_defaults.h b/chromium/net/ssl/ssl_config_service_defaults.h
index de867da13ac..bec5b7a9ac6 100644
--- a/chromium/net/ssl/ssl_config_service_defaults.h
+++ b/chromium/net/ssl/ssl_config_service_defaults.h
@@ -5,6 +5,7 @@
#ifndef NET_SSL_SSL_CONFIG_SERVICE_DEFAULTS_H_
#define NET_SSL_SSL_CONFIG_SERVICE_DEFAULTS_H_
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/ssl/ssl_config_service.h"
diff --git a/chromium/net/ssl/ssl_config_service_unittest.cc b/chromium/net/ssl/ssl_config_service_unittest.cc
index 7428dd00eb9..11f59cd8241 100644
--- a/chromium/net/ssl/ssl_config_service_unittest.cc
+++ b/chromium/net/ssl/ssl_config_service_unittest.cc
@@ -6,7 +6,6 @@
#include <vector>
-#include "base/basictypes.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -94,7 +93,7 @@ TEST(SSLConfigServiceTest, ConfigUpdatesNotifyObservers) {
mock_service->SetSSLConfig(initial_config);
// Test that disabling certain cipher suites triggers an update.
- std::vector<uint16> disabled_ciphers;
+ std::vector<uint16_t> disabled_ciphers;
disabled_ciphers.push_back(0x0004u);
disabled_ciphers.push_back(0xBEEFu);
disabled_ciphers.push_back(0xDEADu);
diff --git a/chromium/net/ssl/ssl_connection_status_flags.h b/chromium/net/ssl/ssl_connection_status_flags.h
index 5d806ae7d72..c6c03059764 100644
--- a/chromium/net/ssl/ssl_connection_status_flags.h
+++ b/chromium/net/ssl/ssl_connection_status_flags.h
@@ -5,6 +5,8 @@
#ifndef NET_SSL_SSL_CONNECTION_STATUS_FLAGS_H_
#define NET_SSL_SSL_CONNECTION_STATUS_FLAGS_H_
+#include <stdint.h>
+
#include "base/logging.h"
#include "base/macros.h"
@@ -53,8 +55,8 @@ enum {
static_assert(SSL_CONNECTION_VERSION_MAX - 1 <= SSL_CONNECTION_VERSION_MASK,
"SSL_CONNECTION_VERSION_MASK too small");
-inline uint16 SSLConnectionStatusToCipherSuite(int connection_status) {
- return static_cast<uint16>(connection_status);
+inline uint16_t SSLConnectionStatusToCipherSuite(int connection_status) {
+ return static_cast<uint16_t>(connection_status);
}
inline int SSLConnectionStatusToVersion(int connection_status) {
@@ -62,7 +64,7 @@ inline int SSLConnectionStatusToVersion(int connection_status) {
SSL_CONNECTION_VERSION_MASK;
}
-inline void SSLConnectionStatusSetCipherSuite(uint16 cipher_suite,
+inline void SSLConnectionStatusSetCipherSuite(uint16_t cipher_suite,
int* connection_status) {
// Clear out the old ciphersuite.
*connection_status &= ~SSL_CONNECTION_CIPHERSUITE_MASK;
diff --git a/chromium/net/ssl/ssl_connection_status_flags_unittest.cc b/chromium/net/ssl/ssl_connection_status_flags_unittest.cc
index 98e4f53b3fd..9827605557e 100644
--- a/chromium/net/ssl/ssl_connection_status_flags_unittest.cc
+++ b/chromium/net/ssl/ssl_connection_status_flags_unittest.cc
@@ -21,7 +21,7 @@ TEST(SSLConnectionStatusTest, SetCipherSuite) {
TEST(SSLConnectionStatusTest, SetVersion) {
int connection_status = 0xDEADBEEF;
- uint16 expected_cipher_suite =
+ uint16_t expected_cipher_suite =
SSLConnectionStatusToCipherSuite(connection_status);
SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
diff --git a/chromium/net/ssl/ssl_info.cc b/chromium/net/ssl/ssl_info.cc
index d3aae9d8f54..545bf7ec6df 100644
--- a/chromium/net/ssl/ssl_info.cc
+++ b/chromium/net/ssl/ssl_info.cc
@@ -32,6 +32,8 @@ SSLInfo& SSLInfo::operator=(const SSLInfo& info) {
is_issued_by_known_root = info.is_issued_by_known_root;
client_cert_sent = info.client_cert_sent;
channel_id_sent = info.channel_id_sent;
+ token_binding_negotiated = info.token_binding_negotiated;
+ token_binding_key_param = info.token_binding_key_param;
handshake_type = info.handshake_type;
public_key_hashes = info.public_key_hashes;
signed_certificate_timestamps = info.signed_certificate_timestamps;
@@ -50,6 +52,8 @@ void SSLInfo::Reset() {
is_issued_by_known_root = false;
client_cert_sent = false;
channel_id_sent = false;
+ token_binding_negotiated = false;
+ token_binding_key_param = TB_PARAM_ECDSAP256;
handshake_type = HANDSHAKE_UNKNOWN;
public_key_hashes.clear();
signed_certificate_timestamps.clear();
@@ -60,4 +64,20 @@ void SSLInfo::SetCertError(int error) {
cert_status |= MapNetErrorToCertStatus(error);
}
+void SSLInfo::UpdateSignedCertificateTimestamps(
+ const ct::CTVerifyResult& ct_verify_result) {
+ for (const auto& sct : ct_verify_result.verified_scts) {
+ signed_certificate_timestamps.push_back(
+ SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_OK));
+ }
+ for (const auto& sct : ct_verify_result.invalid_scts) {
+ signed_certificate_timestamps.push_back(
+ SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_INVALID));
+ }
+ for (const auto& sct : ct_verify_result.unknown_logs_scts) {
+ signed_certificate_timestamps.push_back(
+ SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN));
+ }
+}
+
} // namespace net
diff --git a/chromium/net/ssl/ssl_info.h b/chromium/net/ssl/ssl_info.h
index 28ce82d0ae6..40dec286572 100644
--- a/chromium/net/ssl/ssl_info.h
+++ b/chromium/net/ssl/ssl_info.h
@@ -10,9 +10,11 @@
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/cert_status_flags.h"
+#include "net/cert/ct_verify_result.h"
#include "net/cert/sct_status_flags.h"
#include "net/cert/x509_cert_types.h"
#include "net/ssl/signed_certificate_timestamp_and_status.h"
+#include "net/ssl/ssl_config.h"
namespace net {
@@ -42,6 +44,14 @@ class NET_EXPORT SSLInfo {
// Adds the specified |error| to the cert status.
void SetCertError(int error);
+ // Adds the SignedCertificateTimestamps from ct_verify_result to
+ // |signed_certificate_timestamps|. SCTs are held in three separate vectors
+ // in ct_verify_result, each vetor representing a particular verification
+ // state, this method associates each of the SCTs with the corresponding
+ // SCTVerifyStatus as it adds it to the |signed_certificate_timestamps| list.
+ void UpdateSignedCertificateTimestamps(
+ const ct::CTVerifyResult& ct_verify_result);
+
// The SSL certificate.
scoped_refptr<X509Certificate> cert;
@@ -82,6 +92,15 @@ class NET_EXPORT SSLInfo {
// True if a channel ID was sent to the server.
bool channel_id_sent;
+ // True if Token Binding was negotiated with the server and we agreed on a
+ // version and key params.
+ bool token_binding_negotiated;
+
+ // 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;
+
HandshakeType handshake_type;
// The hashes, in several algorithms, of the SubjectPublicKeyInfos from
diff --git a/chromium/net/ssl/ssl_key_logger.cc b/chromium/net/ssl/ssl_key_logger.cc
new file mode 100644
index 00000000000..42984dfaf37
--- /dev/null
+++ b/chromium/net/ssl/ssl_key_logger.cc
@@ -0,0 +1,69 @@
+// Copyright 2015 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/ssl/ssl_key_logger.h"
+
+#include <stdio.h>
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/sequence_checker.h"
+#include "base/sequenced_task_runner.h"
+
+namespace net {
+
+// An object which lives on the background SequencedTaskRunner and performs the
+// blocking file operations.
+class SSLKeyLogger::Core {
+ public:
+ Core() { sequence_checker_.DetachFromSequence(); }
+ ~Core() { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); }
+
+ void OpenFile(const base::FilePath& path) {
+ DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+ DCHECK(!file_);
+ file_.reset(base::OpenFile(path, "a"));
+ if (!file_)
+ LOG(WARNING) << "Could not open " << path.value();
+ }
+
+ void WriteLine(const std::string& line) {
+ DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+ if (!file_)
+ return;
+ fprintf(file_.get(), "%s\n", line.c_str());
+ fflush(file_.get());
+ }
+
+ private:
+ base::ScopedFILE file_;
+ base::SequenceChecker sequence_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+};
+
+SSLKeyLogger::SSLKeyLogger(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner)
+ : task_runner_(task_runner), core_(new Core) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Core::OpenFile, base::Unretained(core_.get()), path));
+}
+
+SSLKeyLogger::~SSLKeyLogger() {
+ task_runner_->DeleteSoon(FROM_HERE, core_.release());
+}
+
+void SSLKeyLogger::WriteLine(const std::string& line) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Core::WriteLine, base::Unretained(core_.get()), line));
+}
+
+} // namespace net
diff --git a/chromium/net/ssl/ssl_key_logger.h b/chromium/net/ssl/ssl_key_logger.h
new file mode 100644
index 00000000000..dcaf6c6a89b
--- /dev/null
+++ b/chromium/net/ssl/ssl_key_logger.h
@@ -0,0 +1,50 @@
+// Copyright 2015 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_SSL_SSL_KEY_LOGGER_H_
+#define NET_SSL_SSL_KEY_LOGGER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
+namespace net {
+
+// SSLKeyLogger logs SSL key material for debugging purposes. This should only
+// be used when requested by the user, typically via the SSLKEYLOGFILE
+// environment variable. See also
+// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
+class SSLKeyLogger {
+ public:
+ // Creates a new SSLKeyLogger which writes to |path|, scheduling write
+ // operations on |task_runner|.
+ SSLKeyLogger(const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner);
+ ~SSLKeyLogger();
+
+ // Writes |line| followed by a newline. This may be called by multiple threads
+ // simultaneously. If two calls race, the order of the lines is undefined, but
+ // each line will be written atomically.
+ void WriteLine(const std::string& line);
+
+ private:
+ class Core;
+
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ // Destroyed on |task_runner_|.
+ scoped_ptr<Core> core_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSLKeyLogger);
+};
+
+} // namespace net
+
+#endif // NET_SSL_SSL_KEY_LOGGER_H_
diff --git a/chromium/net/ssl/ssl_platform_key.h b/chromium/net/ssl/ssl_platform_key.h
index bcab6a4c32d..a6d53138cbd 100644
--- a/chromium/net/ssl/ssl_platform_key.h
+++ b/chromium/net/ssl/ssl_platform_key.h
@@ -5,8 +5,10 @@
#ifndef NET_SSL_SSL_PLATFORM_KEY_H_
#define NET_SSL_SSL_PLATFORM_KEY_H_
+#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
namespace base {
class SequencedTaskRunner;
@@ -18,12 +20,10 @@ class SSLPrivateKey;
class X509Certificate;
// Looks up the private key from the platform key store corresponding to
-// |certificate|'s public key and returns an SSLPrivateKey which offloads
-// signing operations to |task_runner|. |task_runner| is a SequencedTaskRunner
-// to allow for buggy third-party smartcard drivers.
-scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
- X509Certificate* certificate,
- scoped_refptr<base::SequencedTaskRunner> task_runner);
+// |certificate|'s public key and returns an SSLPrivateKey backed by the
+// playform key.
+NET_EXPORT scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
+ X509Certificate* certificate);
} // namespace net
diff --git a/chromium/net/ssl/ssl_platform_key_android.cc b/chromium/net/ssl/ssl_platform_key_android.cc
index 773844a08fa..6a6595cc0e6 100644
--- a/chromium/net/ssl/ssl_platform_key_android.cc
+++ b/chromium/net/ssl/ssl_platform_key_android.cc
@@ -6,13 +6,14 @@
#include <openssl/digest.h>
#include <openssl/evp.h>
+#include <utility>
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "net/base/net_errors.h"
#include "net/ssl/openssl_client_key_store.h"
+#include "net/ssl/ssl_platform_key_task_runner.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/threaded_ssl_private_key.h"
@@ -23,7 +24,7 @@ namespace {
class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate {
public:
SSLPlatformKeyAndroid(crypto::ScopedEVP_PKEY key, SSLPrivateKey::Type type)
- : key_(key.Pass()), type_(type) {}
+ : key_(std::move(key)), type_(type) {}
~SSLPlatformKeyAndroid() override {}
@@ -79,19 +80,16 @@ class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate {
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
}
- uint8_t* input_ptr =
- const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(input.data()));
+ const uint8_t* input_ptr = reinterpret_cast<const uint8_t*>(input.data());
size_t input_len = input.size();
size_t sig_len = 0;
if (!EVP_PKEY_sign(ctx.get(), NULL, &sig_len, input_ptr, input_len))
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
signature->resize(sig_len);
- uint8_t* sig = const_cast<uint8_t*>(
- reinterpret_cast<const uint8_t*>(vector_as_array(signature)));
- if (!sig)
- return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
- if (!EVP_PKEY_sign(ctx.get(), sig, &sig_len, input_ptr, input_len))
+ if (!EVP_PKEY_sign(ctx.get(), signature->data(), &sig_len, input_ptr,
+ input_len)) {
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ }
signature->resize(sig_len);
@@ -105,14 +103,7 @@ class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate {
DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyAndroid);
};
-} // namespace
-
-scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
- X509Certificate* certificate,
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
- crypto::ScopedEVP_PKEY key =
- OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey(
- certificate);
+scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey(crypto::ScopedEVP_PKEY key) {
if (!key)
return nullptr;
@@ -128,9 +119,19 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
LOG(ERROR) << "Unknown key type: " << EVP_PKEY_id(key.get());
return nullptr;
}
- return make_scoped_ptr(new ThreadedSSLPrivateKey(
- make_scoped_ptr(new SSLPlatformKeyAndroid(key.Pass(), type)),
- task_runner.Pass()));
+ return make_scoped_refptr(new ThreadedSSLPrivateKey(
+ make_scoped_ptr(new SSLPlatformKeyAndroid(std::move(key), type)),
+ GetSSLPlatformKeyTaskRunner()));
+}
+
+} // namespace
+
+scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
+ X509Certificate* certificate) {
+ crypto::ScopedEVP_PKEY key =
+ OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey(
+ certificate);
+ return WrapOpenSSLPrivateKey(std::move(key));
}
} // namespace net
diff --git a/chromium/net/ssl/ssl_platform_key_mac.cc b/chromium/net/ssl/ssl_platform_key_mac.cc
index 0eb787a03eb..ec7cb42f0db 100644
--- a/chromium/net/ssl/ssl_platform_key_mac.cc
+++ b/chromium/net/ssl/ssl_platform_key_mac.cc
@@ -14,21 +14,21 @@
#include <Security/SecIdentity.h>
#include <Security/SecKey.h>
-#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/mac/scoped_cftyperef.h"
+#include "base/macros.h"
#include "base/memory/scoped_policy.h"
#include "base/memory/scoped_ptr.h"
#include "base/sequenced_task_runner.h"
-#include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "crypto/mac_security_services_lock.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
+#include "net/ssl/ssl_platform_key_task_runner.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/threaded_ssl_private_key.h"
@@ -199,7 +199,7 @@ class SSLPlatformKeyMac : public ThreadedSSLPrivateKey::Delegate {
signature->resize(GetMaxSignatureLengthInBytes());
CSSM_DATA signature_data;
signature_data.Length = signature->size();
- signature_data.Data = vector_as_array(signature);
+ signature_data.Data = signature->data();
if (CSSM_SignData(cssm_signature.get(), &hash_data, 1, CSSM_ALGID_NONE,
&signature_data) != CSSM_OK) {
@@ -218,9 +218,8 @@ class SSLPlatformKeyMac : public ThreadedSSLPrivateKey::Delegate {
} // namespace
-scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
- X509Certificate* certificate,
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
+scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
+ X509Certificate* certificate) {
// Look up the private key.
base::ScopedCFTypeRef<SecKeyRef> private_key(
FetchSecKeyRefForCertificate(certificate));
@@ -237,9 +236,9 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
LOG(ERROR) << "Unknown key type: " << cssm_key->KeyHeader.AlgorithmId;
return nullptr;
}
- return make_scoped_ptr(new ThreadedSSLPrivateKey(
+ return make_scoped_refptr(new ThreadedSSLPrivateKey(
make_scoped_ptr(new SSLPlatformKeyMac(private_key.get(), cssm_key)),
- task_runner.Pass()));
+ GetSSLPlatformKeyTaskRunner()));
}
} // namespace net
diff --git a/chromium/net/ssl/ssl_platform_key_nss.cc b/chromium/net/ssl/ssl_platform_key_nss.cc
index 25332104c9e..858ffb9db7f 100644
--- a/chromium/net/ssl/ssl_platform_key_nss.cc
+++ b/chromium/net/ssl/ssl_platform_key_nss.cc
@@ -5,21 +5,21 @@
#include "net/ssl/ssl_platform_key.h"
#include <keyhi.h>
-#include <pk11pub.h>
-#include <prerror.h>
-
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/rsa.h>
+#include <pk11pub.h>
+#include <prerror.h>
+#include <utility>
#include "base/logging.h"
#include "base/macros.h"
#include "base/sequenced_task_runner.h"
-#include "base/stl_util.h"
#include "crypto/scoped_nss_types.h"
#include "crypto/scoped_openssl_types.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/client_key_store.h"
+#include "net/ssl/ssl_platform_key_task_runner.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/threaded_ssl_private_key.h"
@@ -39,7 +39,7 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
public:
SSLPlatformKeyNSS(SSLPrivateKey::Type type,
crypto::ScopedSECKEYPrivateKey key)
- : type_(type), key_(key.Pass()) {}
+ : type_(type), key_(std::move(key)) {}
~SSLPlatformKeyNSS() override {}
SSLPrivateKey::Type GetType() override { return type_; }
@@ -110,7 +110,7 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
}
signature->resize(len);
SECItem signature_item;
- signature_item.data = vector_as_array(signature);
+ signature_item.data = signature->data();
signature_item.len = signature->size();
SECStatus rv = PK11_Sign(key_.get(), &signature_item, &digest_item);
@@ -131,9 +131,8 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
// Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value.
crypto::ScopedECDSA_SIG sig(ECDSA_SIG_new());
- if (!sig || !BN_bin2bn(vector_as_array(signature), order_len, sig->r) ||
- !BN_bin2bn(vector_as_array(signature) + order_len, order_len,
- sig->s)) {
+ if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) ||
+ !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) {
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
}
@@ -141,7 +140,7 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
if (len <= 0)
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
signature->resize(len);
- uint8_t* ptr = vector_as_array(signature);
+ uint8_t* ptr = signature->data();
len = i2d_ECDSA_SIG(sig.get(), &ptr);
if (len <= 0)
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
@@ -160,9 +159,8 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
} // namespace
-scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
- X509Certificate* certificate,
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
+scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
+ X509Certificate* certificate) {
crypto::ScopedSECKEYPrivateKey key(
PK11_FindKeyByAnyCert(certificate->os_cert_handle(), nullptr));
if (!key) {
@@ -183,9 +181,9 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
LOG(ERROR) << "Unknown key type: " << nss_type;
return nullptr;
}
- return make_scoped_ptr(new ThreadedSSLPrivateKey(
- make_scoped_ptr(new SSLPlatformKeyNSS(type, key.Pass())),
- task_runner.Pass()));
+ return make_scoped_refptr(new ThreadedSSLPrivateKey(
+ make_scoped_ptr(new SSLPlatformKeyNSS(type, std::move(key))),
+ GetSSLPlatformKeyTaskRunner()));
}
} // namespace net
diff --git a/chromium/net/ssl/ssl_platform_key_task_runner.cc b/chromium/net/ssl/ssl_platform_key_task_runner.cc
new file mode 100644
index 00000000000..7611d60454d
--- /dev/null
+++ b/chromium/net/ssl/ssl_platform_key_task_runner.cc
@@ -0,0 +1,31 @@
+// Copyright 2015 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 "base/lazy_instance.h"
+#include "net/ssl/ssl_platform_key_task_runner.h"
+
+namespace net {
+
+SSLPlatformKeyTaskRunner::SSLPlatformKeyTaskRunner() {
+ worker_pool_ = new base::SequencedWorkerPool(1, "Platform Key Thread");
+ task_runner_ = worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
+ worker_pool_->GetSequenceToken(),
+ base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
+}
+
+SSLPlatformKeyTaskRunner::~SSLPlatformKeyTaskRunner() {}
+
+scoped_refptr<base::SequencedTaskRunner>
+SSLPlatformKeyTaskRunner::task_runner() {
+ return task_runner_;
+}
+
+base::LazyInstance<SSLPlatformKeyTaskRunner>::Leaky g_platform_key_task_runner =
+ LAZY_INSTANCE_INITIALIZER;
+
+scoped_refptr<base::SequencedTaskRunner> GetSSLPlatformKeyTaskRunner() {
+ return g_platform_key_task_runner.Get().task_runner();
+}
+
+} // namespace net
diff --git a/chromium/net/ssl/ssl_platform_key_task_runner.h b/chromium/net/ssl/ssl_platform_key_task_runner.h
new file mode 100644
index 00000000000..0c9b124f1fa
--- /dev/null
+++ b/chromium/net/ssl/ssl_platform_key_task_runner.h
@@ -0,0 +1,33 @@
+// Copyright 2015 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_SSL_SSL_PLATFORM_KEY_TASK_RUNNER_H_
+#define NET_SSL_SSL_PLATFORM_KEY_TASK_RUNNER_H_
+
+#include "base/macros.h"
+#include "base/threading/sequenced_worker_pool.h"
+
+namespace net {
+
+// Serialize all the private key operations on a single background
+// thread to avoid problems with buggy smartcards.
+class SSLPlatformKeyTaskRunner {
+ public:
+ SSLPlatformKeyTaskRunner();
+ ~SSLPlatformKeyTaskRunner();
+
+ scoped_refptr<base::SequencedTaskRunner> task_runner();
+
+ private:
+ scoped_refptr<base::SequencedWorkerPool> worker_pool_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyTaskRunner);
+};
+
+scoped_refptr<base::SequencedTaskRunner> GetSSLPlatformKeyTaskRunner();
+
+} // namespace net
+
+#endif // NET_SSL_SSL_PLATFORM_KEY_TASK_RUNNER_H_
diff --git a/chromium/net/ssl/ssl_platform_key_win.cc b/chromium/net/ssl/ssl_platform_key_win.cc
index 1cb846b8534..2f3e7c6764c 100644
--- a/chromium/net/ssl/ssl_platform_key_win.cc
+++ b/chromium/net/ssl/ssl_platform_key_win.cc
@@ -20,7 +20,6 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/sequenced_task_runner.h"
-#include "base/stl_util.h"
#include "base/win/windows_version.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_capi_types.h"
@@ -28,6 +27,7 @@
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/scoped_openssl_types.h"
+#include "net/ssl/ssl_platform_key_task_runner.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/threaded_ssl_private_key.h"
@@ -145,7 +145,7 @@ class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate {
}
signature->resize(signature_len);
if (!CryptSignHash(hash_handle.get(), key_spec_, nullptr, 0,
- vector_as_array(signature), &signature_len)) {
+ signature->data(), &signature_len)) {
PLOG(ERROR) << "CryptSignHash failed";
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
}
@@ -242,8 +242,7 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
status = g_cng_functions.Get().ncrypt_sign_hash()(
key_, padding_info,
const_cast<BYTE*>(reinterpret_cast<const BYTE*>(input.data())),
- input.size(), vector_as_array(signature), signature_len, &signature_len,
- flags);
+ input.size(), signature->data(), signature_len, &signature_len, flags);
if (FAILED(status)) {
LOG(ERROR) << "NCryptSignHash failed: " << status;
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
@@ -261,9 +260,8 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
// Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value.
crypto::ScopedECDSA_SIG sig(ECDSA_SIG_new());
- if (!sig || !BN_bin2bn(vector_as_array(signature), order_len, sig->r) ||
- !BN_bin2bn(vector_as_array(signature) + order_len, order_len,
- sig->s)) {
+ if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) ||
+ !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) {
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
}
@@ -271,7 +269,7 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
if (len <= 0)
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
signature->resize(len);
- uint8_t* ptr = vector_as_array(signature);
+ uint8_t* ptr = signature->data();
len = i2d_ECDSA_SIG(sig.get(), &ptr);
if (len <= 0)
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
@@ -323,9 +321,8 @@ bool GetKeyInfo(const X509Certificate* certificate,
} // namespace
-scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
- X509Certificate* certificate,
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
+scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
+ X509Certificate* certificate) {
// Rather than query the private key for metadata, extract the public key from
// the certificate without using Windows APIs. CAPI and CNG do not
// consistently work depending on the system. See https://crbug.com/468345.
@@ -360,8 +357,8 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey(
DCHECK(SSLPrivateKey::Type::RSA == key_type);
delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec, max_length));
}
- return make_scoped_ptr(
- new ThreadedSSLPrivateKey(delegate.Pass(), task_runner.Pass()));
+ return make_scoped_refptr(new ThreadedSSLPrivateKey(
+ delegate.Pass(), GetSSLPlatformKeyTaskRunner()));
}
} // namespace net
diff --git a/chromium/net/ssl/ssl_private_key.h b/chromium/net/ssl/ssl_private_key.h
index d1aa09951d7..2e382fbf3b2 100644
--- a/chromium/net/ssl/ssl_private_key.h
+++ b/chromium/net/ssl/ssl_private_key.h
@@ -5,20 +5,21 @@
#ifndef NET_SSL_SSL_PRIVATE_KEY_H_
#define NET_SSL_SSL_PRIVATE_KEY_H_
+#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "base/callback_forward.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "net/base/net_errors.h"
namespace net {
// An interface for a private key for use with SSL client authentication.
-class SSLPrivateKey {
+class SSLPrivateKey : public base::RefCountedThreadSafe<SSLPrivateKey> {
public:
using SignCallback = base::Callback<void(Error, const std::vector<uint8_t>&)>;
@@ -36,7 +37,6 @@ class SSLPrivateKey {
};
SSLPrivateKey() {}
- virtual ~SSLPrivateKey() {}
// Returns whether the key is an RSA key or an ECDSA key. Although the signing
// interface is type-agnositic and type tags in interfaces are discouraged,
@@ -62,7 +62,11 @@ class SSLPrivateKey {
const base::StringPiece& input,
const SignCallback& callback) = 0;
+ protected:
+ virtual ~SSLPrivateKey() {}
+
private:
+ friend class base::RefCountedThreadSafe<SSLPrivateKey>;
DISALLOW_COPY_AND_ASSIGN(SSLPrivateKey);
};
diff --git a/chromium/net/ssl/ssl_server_config.cc b/chromium/net/ssl/ssl_server_config.cc
new file mode 100644
index 00000000000..8b3e67f7f21
--- /dev/null
+++ b/chromium/net/ssl/ssl_server_config.cc
@@ -0,0 +1,20 @@
+// Copyright 2015 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/ssl/ssl_server_config.h"
+
+#include "net/socket/ssl_client_socket.h"
+#include "net/ssl/ssl_config.h"
+
+namespace net {
+
+SSLServerConfig::SSLServerConfig()
+ : version_min(kDefaultSSLVersionMin),
+ version_max(SSL_PROTOCOL_VERSION_TLS1_2),
+ require_ecdhe(false),
+ require_client_cert(false) {}
+
+SSLServerConfig::~SSLServerConfig() {}
+
+} // namespace net
diff --git a/chromium/net/ssl/ssl_server_config.h b/chromium/net/ssl/ssl_server_config.h
new file mode 100644
index 00000000000..36d1286b225
--- /dev/null
+++ b/chromium/net/ssl/ssl_server_config.h
@@ -0,0 +1,63 @@
+// Copyright 2015 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_SSL_SSL_SERVER_CONFIG_H_
+#define NET_SSL_SSL_SERVER_CONFIG_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "net/base/net_export.h"
+#include "net/ssl/ssl_config.h"
+
+namespace net {
+
+// A collection of server-side SSL-related configuration settings.
+struct NET_EXPORT SSLServerConfig {
+ // Defaults
+ SSLServerConfig();
+ ~SSLServerConfig();
+
+ // The minimum and maximum protocol versions that are enabled.
+ // (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined in ssl_config.h)
+ // SSL 2.0 and SSL 3.0 are not supported. If version_max < version_min, it
+ // means no protocol versions are enabled.
+ uint16_t version_min;
+ uint16_t version_max;
+
+ // Presorted list of cipher suites which should be explicitly prevented from
+ // being used in addition to those disabled by the net built-in policy.
+ //
+ // By default, all cipher suites supported by the underlying SSL
+ // implementation will be enabled except for:
+ // - Null encryption cipher suites.
+ // - Weak cipher suites: < 80 bits of security strength.
+ // - FORTEZZA cipher suites (obsolete).
+ // - IDEA cipher suites (RFC 5469 explains why).
+ // - Anonymous cipher suites.
+ // - ECDSA cipher suites on platforms that do not support ECDSA signed
+ // certificates, as servers may use the presence of such ciphersuites as a
+ // hint to send an ECDSA certificate.
+ // The ciphers listed in |disabled_cipher_suites| will be removed in addition
+ // to the above list.
+ //
+ // Though cipher suites are sent in TLS as "uint8_t CipherSuite[2]", in
+ // big-endian form, they should be declared in host byte order, with the
+ // first uint8_t occupying the most significant byte.
+ // Ex: To disable TLS_RSA_WITH_RC4_128_MD5, specify 0x0004, while to
+ // disable TLS_ECDH_ECDSA_WITH_RC4_128_SHA, specify 0xC002.
+ std::vector<uint16_t> disabled_cipher_suites;
+
+ // If true, causes only ECDHE cipher suites to be enabled.
+ bool require_ecdhe;
+
+ // Requires a client certificate for client authentication from the client.
+ // This doesn't currently enforce certificate validity.
+ bool require_client_cert;
+};
+
+} // namespace net
+
+#endif // NET_SSL_SSL_SERVER_CONFIG_H_
diff --git a/chromium/net/ssl/threaded_ssl_private_key.cc b/chromium/net/ssl/threaded_ssl_private_key.cc
index f395518e680..d2f1d95ea43 100644
--- a/chromium/net/ssl/threaded_ssl_private_key.cc
+++ b/chromium/net/ssl/threaded_ssl_private_key.cc
@@ -5,6 +5,7 @@
#include "net/ssl/threaded_ssl_private_key.h"
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/location.h"
@@ -30,7 +31,7 @@ class ThreadedSSLPrivateKey::Core
: public base::RefCountedThreadSafe<ThreadedSSLPrivateKey::Core> {
public:
Core(scoped_ptr<ThreadedSSLPrivateKey::Delegate> delegate)
- : delegate_(delegate.Pass()) {}
+ : delegate_(std::move(delegate)) {}
ThreadedSSLPrivateKey::Delegate* delegate() { return delegate_.get(); }
@@ -50,13 +51,9 @@ class ThreadedSSLPrivateKey::Core
ThreadedSSLPrivateKey::ThreadedSSLPrivateKey(
scoped_ptr<ThreadedSSLPrivateKey::Delegate> delegate,
scoped_refptr<base::TaskRunner> task_runner)
- : core_(new Core(delegate.Pass())),
- task_runner_(task_runner.Pass()),
- weak_factory_(this) {
-}
-
-ThreadedSSLPrivateKey::~ThreadedSSLPrivateKey() {
-}
+ : core_(new Core(std::move(delegate))),
+ task_runner_(std::move(task_runner)),
+ weak_factory_(this) {}
SSLPrivateKey::Type ThreadedSSLPrivateKey::GetType() {
return core_->delegate()->GetType();
@@ -83,4 +80,6 @@ void ThreadedSSLPrivateKey::SignDigest(
base::Owned(signature)));
}
+ThreadedSSLPrivateKey::~ThreadedSSLPrivateKey() {}
+
} // namespace net
diff --git a/chromium/net/ssl/threaded_ssl_private_key.h b/chromium/net/ssl/threaded_ssl_private_key.h
index afee1034727..629ce3b9160 100644
--- a/chromium/net/ssl/threaded_ssl_private_key.h
+++ b/chromium/net/ssl/threaded_ssl_private_key.h
@@ -5,6 +5,7 @@
#ifndef NET_SSL_THREADED_SSL_PRIVATE_KEY_H_
#define NET_SSL_THREADED_SSL_PRIVATE_KEY_H_
+#include <stddef.h>
#include <stdint.h>
#include <vector>
@@ -38,7 +39,7 @@ class ThreadedSSLPrivateKey : public SSLPrivateKey {
virtual std::vector<SSLPrivateKey::Hash> GetDigestPreferences() = 0;
virtual size_t GetMaxSignatureLengthInBytes() = 0;
- // Signs |input| as a digest of type |hash|. On sucess it returns OK and
+ // Signs |input| as a digest of type |hash|. On success it returns OK and
// sets |signature| to the resulting signature. Otherwise it returns a net
// error code. It will only be called on the task runner passed to the
// owning ThreadedSSLPrivateKey.
@@ -52,7 +53,6 @@ class ThreadedSSLPrivateKey : public SSLPrivateKey {
ThreadedSSLPrivateKey(scoped_ptr<Delegate> delegate,
scoped_refptr<base::TaskRunner> task_runner);
- ~ThreadedSSLPrivateKey() override;
// SSLPrivateKey implementation.
Type GetType() override;
@@ -63,6 +63,7 @@ class ThreadedSSLPrivateKey : public SSLPrivateKey {
const SignCallback& callback) override;
private:
+ ~ThreadedSSLPrivateKey() override;
class Core;
scoped_refptr<Core> core_;
diff --git a/chromium/net/test/android/javatests/AndroidManifest.xml b/chromium/net/test/android/javatests/AndroidManifest.xml
new file mode 100644
index 00000000000..c2a2652743c
--- /dev/null
+++ b/chromium/net/test/android/javatests/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2015 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. -->
+
+<!-- package name must be unique. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="org.chromium.net.test.support">
+
+ <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <application android:label="ChromiumNetTestSupport">
+
+ <uses-library android:name="android.test.runner" />
+
+ <service android:name="org.chromium.net.test.EmbeddedTestServerService"
+ android:exported="true"
+ tools:ignore="ExportedService">
+ <intent-filter android:action="org.chromium.net.test.EMBEDDED_TEST_SERVER_SERVICE" />
+ </service>
+
+ </application>
+
+</manifest>
diff --git a/chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl b/chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl
new file mode 100644
index 00000000000..898b7f582e1
--- /dev/null
+++ b/chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerImpl.aidl
@@ -0,0 +1,41 @@
+// Copyright 2015 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.
+
+package org.chromium.net.test;
+
+interface IEmbeddedTestServerImpl {
+
+ /** Initialize the native object. */
+ boolean initializeNative();
+
+ /** Start the server.
+ *
+ * @return Whether the server was successfully started.
+ */
+ boolean start();
+
+ /** Serve files from the provided directory.
+ *
+ * @param directoryPath The path of the directory from which files should be served.
+ */
+ void serveFilesFromDirectory(String directoryPath);
+
+ /** Get the full URL for the given relative URL.
+ *
+ * @param relativeUrl The relative URL for which a full URL should be returned.
+ * @return The URL as a String.
+ */
+ String getURL(String relativeUrl);
+
+ /** Shut down the server.
+ *
+ * @return Whether the server was successfully shut down.
+ */
+ boolean shutdownAndWaitUntilComplete();
+
+ /** Destroy the native object. */
+ void destroy();
+
+}
+
diff --git a/chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerInterface.aidl b/chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerInterface.aidl
new file mode 100644
index 00000000000..df0c3d18cca
--- /dev/null
+++ b/chromium/net/test/android/javatests/src/org/chromium/net/test/IEmbeddedTestServerInterface.aidl
@@ -0,0 +1,5 @@
+// Copyright 2015 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.
+
+interface org.chromium.net.test.IEmbedddedTestServerImpl;
diff --git a/chromium/net/test/android/net_test_entry_point.cc b/chromium/net/test/android/net_test_entry_point.cc
new file mode 100644
index 00000000000..c7a2dde0545
--- /dev/null
+++ b/chromium/net/test/android/net_test_entry_point.cc
@@ -0,0 +1,14 @@
+// Copyright 2015 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 "base/android/jni_android.h"
+#include "net/test/android/net_test_jni_onload.h"
+
+// This is called by the VM when the shared library is first loaded.
+JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ if (!net::test::OnJNIOnLoadRegisterJNI(vm) || !net::test::OnJNIOnLoadInit()) {
+ return -1;
+ }
+ return JNI_VERSION_1_4;
+}
diff --git a/chromium/net/test/cert_test_util_nss.cc b/chromium/net/test/cert_test_util_nss.cc
index 4427cebe117..4cd435bc3ac 100644
--- a/chromium/net/test/cert_test_util_nss.cc
+++ b/chromium/net/test/cert_test_util_nss.cc
@@ -27,10 +27,10 @@ bool ImportSensitiveKeyFromFile(const base::FilePath& dir,
return false;
}
- const uint8* key_pkcs8_begin =
- reinterpret_cast<const uint8*>(key_pkcs8.data());
- std::vector<uint8> key_vector(key_pkcs8_begin,
- key_pkcs8_begin + key_pkcs8.length());
+ const uint8_t* key_pkcs8_begin =
+ reinterpret_cast<const uint8_t*>(key_pkcs8.data());
+ std::vector<uint8_t> key_vector(key_pkcs8_begin,
+ key_pkcs8_begin + key_pkcs8.length());
crypto::ScopedSECKEYPrivateKey private_key(
crypto::ImportNSSKeyFromPrivateKeyInfo(slot, key_vector,
diff --git a/chromium/net/test/ct_test_util.cc b/chromium/net/test/ct_test_util.cc
index 65a8122e39b..b36c13ded8a 100644
--- a/chromium/net/test/ct_test_util.cc
+++ b/chromium/net/test/ct_test_util.cc
@@ -5,7 +5,7 @@
#include "net/test/ct_test_util.h"
#include <stdint.h>
-#include <string>
+#include <string.h>
#include <vector>
#include "base/base64.h"
@@ -25,7 +25,7 @@ namespace ct {
namespace {
std::string HexToBytes(const char* hex_data) {
- std::vector<uint8> output;
+ std::vector<uint8_t> output;
std::string result;
if (base::HexStringToBytes(hex_data, &output))
result.assign(reinterpret_cast<const char*>(&output[0]), output.size());
@@ -166,7 +166,7 @@ const char kSampleSTHTreeHeadSignature[] =
"6c7a20022100e38464f3c0fd066257b982074f7ac87655e0c8f714768a050b4be9a7b441cb"
"d3";
size_t kSampleSTHTreeSize = 21u;
-int64_t kSampleSTHTimestamp = 1396877277237u;
+int64_t kSampleSTHTimestamp = INT64_C(1396877277237);
} // namespace
@@ -255,7 +255,7 @@ std::string GetDerEncodedFakeOCSPResponseIssuerCert() {
}
// A sample, valid STH
-void GetSampleSignedTreeHead(SignedTreeHead* sth) {
+bool GetSampleSignedTreeHead(SignedTreeHead* sth) {
sth->version = SignedTreeHead::V1;
sth->timestamp = base::Time::UnixEpoch() +
base::TimeDelta::FromMilliseconds(kSampleSTHTimestamp);
@@ -263,7 +263,39 @@ void GetSampleSignedTreeHead(SignedTreeHead* sth) {
std::string sha256_root_hash = GetSampleSTHSHA256RootHash();
memcpy(sth->sha256_root_hash, sha256_root_hash.c_str(), kSthRootHashLength);
- GetSampleSTHTreeHeadDecodedSignature(&(sth->signature));
+ return GetSampleSTHTreeHeadDecodedSignature(&(sth->signature));
+}
+
+bool GetSampleEmptySignedTreeHead(SignedTreeHead* sth) {
+ sth->version = SignedTreeHead::V1;
+ sth->timestamp = base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(INT64_C(1450443594920));
+ sth->tree_size = 0;
+ std::string empty_root_hash = HexToBytes(
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+ memcpy(sth->sha256_root_hash, empty_root_hash.c_str(), kSthRootHashLength);
+
+ std::string tree_head_signature = HexToBytes(
+ "040300463044022046c26401de9416403da54762dc1f1687c38eafd791b15e484ab4c5f7"
+ "f52721fe02201bf537a3bbea47109fc76c2273fe0f3349f493a07de9335c266330105fb0"
+ "2a4a");
+ base::StringPiece sp(tree_head_signature);
+ return DecodeDigitallySigned(&sp, &(sth->signature)) && sp.empty();
+}
+
+bool GetBadEmptySignedTreeHead(SignedTreeHead* sth) {
+ sth->version = SignedTreeHead::V1;
+ sth->timestamp = base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(INT64_C(1450870952897));
+ sth->tree_size = 0;
+ memset(sth->sha256_root_hash, 'f', kSthRootHashLength);
+
+ std::string tree_head_signature = HexToBytes(
+ "04030046304402207cab04c62dee5d1cbc95fec30cd8417313f71587b75f133ad2e6f324"
+ "74f164d702205e2f3a9bce46f87d7e20e951a4e955da3cb502f8717a22fabd7c5d7e1bef"
+ "46ea");
+ base::StringPiece sp(tree_head_signature);
+ return DecodeDigitallySigned(&sp, &(sth->signature)) && sp.empty();
}
std::string GetSampleSTHSHA256RootHash() {
@@ -274,11 +306,10 @@ std::string GetSampleSTHTreeHeadSignature() {
return HexToBytes(kSampleSTHTreeHeadSignature);
}
-void GetSampleSTHTreeHeadDecodedSignature(DigitallySigned* signature) {
+bool GetSampleSTHTreeHeadDecodedSignature(DigitallySigned* signature) {
std::string tree_head_signature = HexToBytes(kSampleSTHTreeHeadSignature);
base::StringPiece sp(tree_head_signature);
- CHECK(DecodeDigitallySigned(&sp, signature));
- CHECK(sp.empty());
+ return DecodeDigitallySigned(&sp, signature) && sp.empty();
}
std::string GetSampleSTHAsJson() {
@@ -312,6 +343,23 @@ std::string CreateSignedTreeHeadJsonString(size_t tree_size,
return sth_json;
}
+std::string CreateConsistencyProofJsonString(
+ const std::vector<std::string>& raw_nodes) {
+ std::string consistency_proof_json = std::string("{\"consistency\":[");
+
+ for (auto it = raw_nodes.begin(); it != raw_nodes.end(); ++it) {
+ std::string proof_node_b64;
+ base::Base64Encode(*it, &proof_node_b64);
+ consistency_proof_json +=
+ base::StringPrintf("\"%s\"", proof_node_b64.c_str());
+ if (it + 1 != raw_nodes.end())
+ consistency_proof_json += std::string(",");
+ }
+ consistency_proof_json += std::string("]}");
+
+ return consistency_proof_json;
+}
+
} // namespace ct
} // namespace net
diff --git a/chromium/net/test/ct_test_util.h b/chromium/net/test/ct_test_util.h
index 5701a288272..e1d6cff6f09 100644
--- a/chromium/net/test/ct_test_util.h
+++ b/chromium/net/test/ct_test_util.h
@@ -5,7 +5,11 @@
#ifndef NET_CERT_CT_TEST_UTIL_H_
#define NET_CERT_CT_TEST_UTIL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
+#include <vector>
#include "base/memory/ref_counted.h"
@@ -65,7 +69,15 @@ std::string GetDerEncodedFakeOCSPResponseCert();
std::string GetDerEncodedFakeOCSPResponseIssuerCert();
// A sample, valid STH.
-void GetSampleSignedTreeHead(SignedTreeHead* sth);
+bool GetSampleSignedTreeHead(SignedTreeHead* sth);
+
+// A valid STH for the empty tree.
+bool GetSampleEmptySignedTreeHead(SignedTreeHead* sth);
+
+// An STH for an empty tree where the root hash is not the hash of the empty
+// string, but the signature over the STH is valid. Such an STH is not valid
+// according to RFC6962.
+bool GetBadEmptySignedTreeHead(SignedTreeHead* sth);
// The SHA256 root hash for the sample STH.
std::string GetSampleSTHSHA256RootHash();
@@ -74,7 +86,7 @@ std::string GetSampleSTHSHA256RootHash();
std::string GetSampleSTHTreeHeadSignature();
// The same signature as GetSampleSTHTreeHeadSignature, decoded.
-void GetSampleSTHTreeHeadDecodedSignature(DigitallySigned* signature);
+bool GetSampleSTHTreeHeadDecodedSignature(DigitallySigned* signature);
// The sample STH in JSON form.
std::string GetSampleSTHAsJson();
@@ -86,6 +98,10 @@ std::string CreateSignedTreeHeadJsonString(size_t tree_size,
std::string sha256_root_hash,
std::string tree_head_signature);
+// Assembles, and returns, a sample consistency proof in JSON format using
+// the provided raw nodes (i.e. the raw nodes will be base64-encoded).
+std::string CreateConsistencyProofJsonString(
+ const std::vector<std::string>& raw_nodes);
} // namespace ct
} // namespace net
diff --git a/chromium/net/test/embedded_test_server/OWNERS b/chromium/net/test/embedded_test_server/OWNERS
deleted file mode 100644
index 4eab6e490b7..00000000000
--- a/chromium/net/test/embedded_test_server/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-mtomasz@chromium.org
diff --git a/chromium/net/test/embedded_test_server/android/embedded_test_server_android.cc b/chromium/net/test/embedded_test_server/android/embedded_test_server_android.cc
index 9ba38862e8e..0f53545b5bf 100644
--- a/chromium/net/test/embedded_test_server/android/embedded_test_server_android.cc
+++ b/chromium/net/test/embedded_test_server/android/embedded_test_server_android.cc
@@ -9,36 +9,38 @@
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/trace_event/trace_event.h"
-#include "net/test/jni/EmbeddedTestServer_jni.h"
+#include "net/test/jni/EmbeddedTestServerImpl_jni.h"
namespace net {
namespace test_server {
EmbeddedTestServerAndroid::EmbeddedTestServerAndroid(JNIEnv* env, jobject jobj)
: weak_java_server_(env, jobj), test_server_() {
- Java_EmbeddedTestServer_setNativePtr(env, jobj,
- reinterpret_cast<intptr_t>(this));
+ Java_EmbeddedTestServerImpl_setNativePtr(env, jobj,
+ reinterpret_cast<intptr_t>(this));
}
EmbeddedTestServerAndroid::~EmbeddedTestServerAndroid() {
JNIEnv* env = base::android::AttachCurrentThread();
- Java_EmbeddedTestServer_clearNativePtr(env, weak_java_server_.get(env).obj());
+ Java_EmbeddedTestServerImpl_clearNativePtr(env,
+ weak_java_server_.get(env).obj());
}
-jboolean EmbeddedTestServerAndroid::InitializeAndWaitUntilReady(JNIEnv* env,
- jobject jobj) {
- return test_server_.InitializeAndWaitUntilReady();
+jboolean EmbeddedTestServerAndroid::Start(JNIEnv* env,
+ const JavaParamRef<jobject>& jobj) {
+ return test_server_.Start();
}
-jboolean EmbeddedTestServerAndroid::ShutdownAndWaitUntilComplete(JNIEnv* env,
- jobject jobj) {
+jboolean EmbeddedTestServerAndroid::ShutdownAndWaitUntilComplete(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& jobj) {
return test_server_.ShutdownAndWaitUntilComplete();
}
base::android::ScopedJavaLocalRef<jstring> EmbeddedTestServerAndroid::GetURL(
JNIEnv* env,
- jobject jobj,
- jstring jrelative_url) const {
+ const JavaParamRef<jobject>& jobj,
+ const JavaParamRef<jstring>& jrelative_url) const {
const GURL gurl(test_server_.GetURL(
base::android::ConvertJavaStringToUTF8(env, jrelative_url)));
return base::android::ConvertUTF8ToJavaString(env, gurl.spec());
@@ -46,14 +48,15 @@ base::android::ScopedJavaLocalRef<jstring> EmbeddedTestServerAndroid::GetURL(
void EmbeddedTestServerAndroid::ServeFilesFromDirectory(
JNIEnv* env,
- jobject jobj,
- jstring jdirectory_path) {
+ const JavaParamRef<jobject>& jobj,
+ const JavaParamRef<jstring>& jdirectory_path) {
const base::FilePath directory(
base::android::ConvertJavaStringToUTF8(env, jdirectory_path));
test_server_.ServeFilesFromDirectory(directory);
}
-void EmbeddedTestServerAndroid::Destroy(JNIEnv* env, jobject jobj) {
+void EmbeddedTestServerAndroid::Destroy(JNIEnv* env,
+ const JavaParamRef<jobject>& jobj) {
delete this;
}
diff --git a/chromium/net/test/embedded_test_server/android/embedded_test_server_android.h b/chromium/net/test/embedded_test_server/android/embedded_test_server_android.h
index fb03e37a252..a3876f71836 100644
--- a/chromium/net/test/embedded_test_server/android/embedded_test_server_android.h
+++ b/chromium/net/test/embedded_test_server/android/embedded_test_server_android.h
@@ -9,6 +9,7 @@
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
@@ -22,18 +23,23 @@ class EmbeddedTestServerAndroid {
EmbeddedTestServerAndroid(JNIEnv* env, jobject obj);
~EmbeddedTestServerAndroid();
- void Destroy(JNIEnv* env, jobject obj);
+ void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
- jboolean InitializeAndWaitUntilReady(JNIEnv* env, jobject jobj);
+ jboolean Start(JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj);
- jboolean ShutdownAndWaitUntilComplete(JNIEnv* env, jobject jobj);
+ jboolean ShutdownAndWaitUntilComplete(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj);
- base::android::ScopedJavaLocalRef<jstring>
- GetURL(JNIEnv* jenv, jobject jobj, jstring jrelative_url) const;
+ base::android::ScopedJavaLocalRef<jstring> GetURL(
+ JNIEnv* jenv,
+ const base::android::JavaParamRef<jobject>& jobj,
+ const base::android::JavaParamRef<jstring>& jrelative_url) const;
- void ServeFilesFromDirectory(JNIEnv* env,
- jobject jobj,
- jstring jdirectory_path);
+ void ServeFilesFromDirectory(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj,
+ const base::android::JavaParamRef<jstring>& jdirectory_path);
static bool RegisterEmbeddedTestServerAndroid(JNIEnv* env);
diff --git a/chromium/net/test/embedded_test_server/default_handlers.cc b/chromium/net/test/embedded_test_server/default_handlers.cc
new file mode 100644
index 00000000000..039ac3c8665
--- /dev/null
+++ b/chromium/net/test/embedded_test_server/default_handlers.cc
@@ -0,0 +1,639 @@
+// Copyright 2015 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/embedded_test_server/default_handlers.h"
+
+#include <stdlib.h>
+#include <ctime>
+#include <map>
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "base/base64.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/format_macros.h"
+#include "base/macros.h"
+#include "base/md5.h"
+#include "base/path_service.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "net/base/escape.h"
+#include "net/base/url_util.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
+
+namespace net {
+namespace test_server {
+namespace {
+
+const UnescapeRule::Type kUnescapeAll =
+ UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS |
+ UnescapeRule::SPOOFING_AND_CONTROL_CHARS |
+ UnescapeRule::REPLACE_PLUS_WITH_SPACE;
+
+const char kDefaultRealm[] = "testrealm";
+const char kDefaultPassword[] = "secret";
+const char kEtag[] = "abc";
+const char kLogoPath[] = "chrome/test/data/google/logo.gif";
+
+// method: CONNECT
+// Responses with a BAD_REQUEST to any CONNECT requests.
+scoped_ptr<HttpResponse> HandleDefaultConnect(const HttpRequest& request) {
+ if (request.method != METHOD_CONNECT)
+ return nullptr;
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_code(HTTP_BAD_REQUEST);
+ http_response->set_content(
+ "Your client has issued a malformed or illegal request.");
+ http_response->set_content_type("text/html");
+ return std::move(http_response);
+}
+
+// /cachetime
+// Returns a cacheable response.
+scoped_ptr<HttpResponse> HandleCacheTime(const HttpRequest& request) {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content(
+ "<html><head><title>Cache: max-age=60</title></head></html>");
+ http_response->set_content_type("text/html");
+ http_response->AddCustomHeader("Cache-Control", "max-age=60");
+ return std::move(http_response);
+}
+
+// /echoheader | /echoheadercache
+// Responds with the headers echoed in the message body.
+// echoheader does not cache the results, while echoheadercache does.
+scoped_ptr<HttpResponse> HandleEchoHeader(const std::string& url,
+ const std::string& cache_control,
+ const HttpRequest& request) {
+ if (!ShouldHandle(request, url))
+ return nullptr;
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+
+ GURL request_url = request.GetURL();
+ if (request_url.has_query()) {
+ std::string header_name = request_url.query();
+ http_response->AddCustomHeader("Vary", header_name);
+ if (request.headers.find(header_name) != request.headers.end())
+ http_response->set_content(request.headers.at(header_name));
+ else
+ http_response->set_content("None");
+ }
+
+ http_response->set_content_type("text/plain");
+ http_response->AddCustomHeader("Cache-Control", cache_control);
+ return std::move(http_response);
+}
+
+// /echo?status=STATUS
+// Responds with the request body as the response body and
+// a status code of STATUS.
+scoped_ptr<HttpResponse> HandleEcho(const HttpRequest& request) {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+
+ GURL request_url = request.GetURL();
+ if (request_url.has_query()) {
+ RequestQuery query = ParseQuery(request_url);
+ if (query.find("status") != query.end())
+ http_response->set_code(static_cast<HttpStatusCode>(
+ std::atoi(query["status"].front().c_str())));
+ }
+
+ http_response->set_content_type("text/html");
+ if (request.method != METHOD_POST && request.method != METHOD_PUT)
+ http_response->set_content("Echo");
+ else
+ http_response->set_content(request.content);
+ return std::move(http_response);
+}
+
+// /echotitle
+// Responds with the request body as the title.
+scoped_ptr<HttpResponse> HandleEchoTitle(const HttpRequest& request) {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content_type("text/html");
+ http_response->set_content("<html><head><title>" + request.content +
+ "</title></head></html>");
+ return std::move(http_response);
+}
+
+// /echoall?QUERY
+// Responds with the list of QUERY and the request headers.
+scoped_ptr<HttpResponse> HandleEchoAll(const HttpRequest& request) {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+
+ std::string body =
+ "<html><head><style>"
+ "pre { border: 1px solid black; margin: 5px; padding: 5px }"
+ "</style></head><body>"
+ "<div style=\"float: right\">"
+ "<a href=\"/echo\">back to referring page</a></div>"
+ "<h1>Request Body:</h1><pre>";
+
+ if (request.has_content) {
+ std::vector<std::string> query_list = base::SplitString(
+ request.content, "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const auto& query : query_list)
+ body += query + "\n";
+ }
+
+ body +=
+ "</pre>"
+ "<h1>Request Headers:</h1><pre>" +
+ request.all_headers +
+ "</pre>"
+ "</body></html>";
+
+ http_response->set_content_type("text/html");
+ http_response->set_content(body);
+ return std::move(http_response);
+}
+
+// /set-cookie?COOKIES
+// Sets response cookies to be COOKIES.
+scoped_ptr<HttpResponse> HandleSetCookie(const HttpRequest& request) {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content_type("text/html");
+ std::string content;
+ GURL request_url = request.GetURL();
+ if (request_url.has_query()) {
+ std::vector<std::string> cookies = base::SplitString(
+ request_url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const auto& cookie : cookies) {
+ http_response->AddCustomHeader("Set-Cookie", cookie);
+ content += cookie;
+ }
+ }
+
+ http_response->set_content(content);
+ return std::move(http_response);
+}
+
+// /set-many-cookies?N
+// Sets N cookies in the response.
+scoped_ptr<HttpResponse> HandleSetManyCookies(const HttpRequest& request) {
+ std::string content;
+
+ GURL request_url = request.GetURL();
+ size_t num = 0;
+ if (request_url.has_query())
+ num = std::atoi(request_url.query().c_str());
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content_type("text/html");
+ for (size_t i = 0; i < num; ++i) {
+ http_response->AddCustomHeader("Set-Cookie", "a=");
+ }
+
+ http_response->set_content(
+ base::StringPrintf("%" PRIuS " cookies were sent", num));
+ return std::move(http_response);
+}
+
+// /expect-and-set-cookie?expect=EXPECTED&set=SET&data=DATA
+// Verifies that the request cookies match EXPECTED and then returns cookies
+// that match SET and a content that matches DATA.
+scoped_ptr<HttpResponse> HandleExpectAndSetCookie(const HttpRequest& request) {
+ std::vector<std::string> received_cookies;
+ if (request.headers.find("Cookie") != request.headers.end()) {
+ received_cookies =
+ base::SplitString(request.headers.at("Cookie"), ";",
+ base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ }
+
+ bool got_all_expected = true;
+ GURL request_url = request.GetURL();
+ RequestQuery query_list = ParseQuery(request_url);
+ if (query_list.find("expect") != query_list.end()) {
+ for (const auto& expected_cookie : query_list.at("expect")) {
+ bool found = false;
+ for (const auto& received_cookie : received_cookies) {
+ if (expected_cookie == received_cookie)
+ found = true;
+ }
+ got_all_expected &= found;
+ }
+ }
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content_type("text/html");
+ if (got_all_expected) {
+ for (const auto& cookie : query_list.at("set")) {
+ http_response->AddCustomHeader(
+ "Set-Cookie", net::UnescapeURLComponent(cookie, kUnescapeAll));
+ }
+ }
+
+ std::string content;
+ if (query_list.find("data") != query_list.end()) {
+ for (const auto& item : query_list.at("data"))
+ content += item;
+ }
+
+ http_response->set_content(content);
+ return std::move(http_response);
+}
+
+// /set-header?HEADERS
+// Returns a response with HEADERS set as the response headers.
+scoped_ptr<HttpResponse> HandleSetHeader(const HttpRequest& request) {
+ std::string content;
+
+ GURL request_url = request.GetURL();
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content_type("text/html");
+ if (request_url.has_query()) {
+ RequestQuery headers = ParseQuery(request_url);
+ for (const auto& header : headers) {
+ size_t delimiter = header.first.find(": ");
+ if (delimiter == std::string::npos)
+ continue;
+ std::string key = header.first.substr(0, delimiter);
+ std::string value = header.first.substr(delimiter + 2);
+ http_response->AddCustomHeader(key, value);
+ content += header.first;
+ }
+ }
+
+ http_response->set_content(content);
+ return std::move(http_response);
+}
+
+// /nocontent
+// Returns a NO_CONTENT response.
+scoped_ptr<HttpResponse> HandleNoContent(const HttpRequest& request) {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_code(HTTP_NO_CONTENT);
+ return std::move(http_response);
+}
+
+// /close-socket
+// Immediately closes the connection.
+scoped_ptr<HttpResponse> HandleCloseSocket(const HttpRequest& request) {
+ scoped_ptr<RawHttpResponse> http_response(new RawHttpResponse("", ""));
+ return std::move(http_response);
+}
+
+// /auth-basic?password=PASS&realm=REALM
+// Performs "Basic" HTTP authentication using expected password PASS and
+// realm REALM.
+scoped_ptr<HttpResponse> HandleAuthBasic(const HttpRequest& request) {
+ GURL request_url = request.GetURL();
+ RequestQuery query = ParseQuery(request_url);
+
+ std::string expected_password = kDefaultPassword;
+ if (query.find("password") != query.end())
+ expected_password = query.at("password").front();
+ std::string realm = kDefaultRealm;
+ if (query.find("realm") != query.end())
+ realm = query.at("realm").front();
+
+ bool authed = false;
+ std::string error;
+ std::string auth;
+ std::string username;
+ std::string userpass;
+ std::string password;
+ std::string b64str;
+ if (request.headers.find("Authorization") == request.headers.end()) {
+ error = "Missing Authorization Header";
+ } else {
+ auth = request.headers.at("Authorization");
+ if (auth.find("Basic ") == std::string::npos) {
+ error = "Invalid Authorization Header";
+ } else {
+ b64str = auth.substr(std::string("Basic ").size());
+ base::Base64Decode(b64str, &userpass);
+ size_t delimiter = userpass.find(":");
+ if (delimiter != std::string::npos) {
+ username = userpass.substr(0, delimiter);
+ password = userpass.substr(delimiter + 1);
+ if (password == expected_password)
+ authed = true;
+ else
+ error = "Invalid Credentials";
+ } else {
+ error = "Invalid Credentials";
+ }
+ }
+ }
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ if (!authed) {
+ http_response->set_code(HTTP_UNAUTHORIZED);
+ http_response->set_content_type("text/html");
+ http_response->AddCustomHeader("WWW-Authenticate",
+ "Basic realm=\"" + realm + "\"");
+ if (query.find("set-cookie-if-challenged") != query.end())
+ http_response->AddCustomHeader("Set-Cookie", "got_challenged=true");
+ http_response->set_content(base::StringPrintf(
+ "<html><head><title>Denied: %s</title></head>"
+ "<body>auth=%s<p>b64str=%s<p>username: %s<p>userpass: %s<p>"
+ "password: %s<p>You sent:<br>%s<p></body></html>",
+ error.c_str(), auth.c_str(), b64str.c_str(), username.c_str(),
+ userpass.c_str(), password.c_str(), request.all_headers.c_str()));
+ return std::move(http_response);
+ }
+
+ if (request.headers.find("If-None-Match") != request.headers.end() &&
+ request.headers.at("If-None-Match") == kEtag) {
+ http_response->set_code(HTTP_NOT_MODIFIED);
+ return std::move(http_response);
+ }
+
+ base::FilePath file_path =
+ base::FilePath().AppendASCII(request.relative_url.substr(1));
+ if (file_path.FinalExtension() == FILE_PATH_LITERAL("gif")) {
+ base::FilePath server_root;
+ PathService::Get(base::DIR_SOURCE_ROOT, &server_root);
+ base::FilePath gif_path = server_root.AppendASCII(kLogoPath);
+ std::string gif_data;
+ base::ReadFileToString(gif_path, &gif_data);
+ http_response->set_content_type("image/gif");
+ http_response->set_content(gif_data);
+ } else {
+ http_response->set_content_type("text/html");
+ http_response->set_content(
+ base::StringPrintf("<html><head><title>%s/%s</title></head>"
+ "<body>auth=%s<p>You sent:<br>%s<p></body></html>",
+ username.c_str(), password.c_str(), auth.c_str(),
+ request.all_headers.c_str()));
+ }
+
+ http_response->AddCustomHeader("Cache-Control", "max-age=60000");
+ http_response->AddCustomHeader("Etag", kEtag);
+ return std::move(http_response);
+}
+
+// /auth-digest
+// Performs "Digest" HTTP authentication.
+scoped_ptr<HttpResponse> HandleAuthDigest(const HttpRequest& request) {
+ std::string nonce = base::MD5String(
+ base::StringPrintf("privatekey%s", request.relative_url.c_str()));
+ std::string opaque = base::MD5String("opaque");
+ std::string password = kDefaultPassword;
+ std::string realm = kDefaultRealm;
+
+ bool authed = false;
+ std::string error;
+ std::string auth;
+ std::string digest_str = "Digest";
+ std::string username;
+ if (request.headers.find("Authorization") == request.headers.end()) {
+ error = "no auth";
+ } else if (request.headers.at("Authorization").substr(0, digest_str.size()) !=
+ digest_str) {
+ error = "not digest";
+ } else {
+ auth = request.headers.at("Authorization").substr(digest_str.size() + 1);
+
+ std::map<std::string, std::string> auth_pairs;
+ base::StringPairs auth_vector;
+ base::SplitStringIntoKeyValuePairs(auth, '=', ',', &auth_vector);
+ for (const auto& auth_pair : auth_vector) {
+ std::string key;
+ std::string value;
+ base::TrimWhitespaceASCII(auth_pair.first, base::TRIM_ALL, &key);
+ base::TrimWhitespaceASCII(auth_pair.second, base::TRIM_ALL, &value);
+ if (value.size() > 2 && value.at(0) == '"' &&
+ value.at(value.size() - 1) == '"') {
+ value = value.substr(1, value.size() - 2);
+ }
+ auth_pairs[key] = value;
+ }
+
+ if (auth_pairs["nonce"] != nonce) {
+ error = "wrong nonce";
+ } else if (auth_pairs["opaque"] != opaque) {
+ error = "wrong opaque";
+ } else {
+ username = auth_pairs["username"];
+
+ std::string hash1 = base::MD5String(
+ base::StringPrintf("%s:%s:%s", auth_pairs["username"].c_str(),
+ realm.c_str(), password.c_str()));
+ std::string hash2 = base::MD5String(base::StringPrintf(
+ "%s:%s", request.method_string.c_str(), auth_pairs["uri"].c_str()));
+
+ std::string response;
+ if (auth_pairs.find("qop") != auth_pairs.end() &&
+ auth_pairs.find("nc") != auth_pairs.end() &&
+ auth_pairs.find("cnonce") != auth_pairs.end()) {
+ response = base::MD5String(base::StringPrintf(
+ "%s:%s:%s:%s:%s:%s", hash1.c_str(), nonce.c_str(),
+ auth_pairs["nc"].c_str(), auth_pairs["cnonce"].c_str(),
+ auth_pairs["qop"].c_str(), hash2.c_str()));
+ } else {
+ response = base::MD5String(base::StringPrintf(
+ "%s:%s:%s", hash1.c_str(), nonce.c_str(), hash2.c_str()));
+ }
+
+ if (auth_pairs["response"] == response)
+ authed = true;
+ else
+ error = "wrong password";
+ }
+ }
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ if (!authed) {
+ http_response->set_code(HTTP_UNAUTHORIZED);
+ http_response->set_content_type("text/html");
+ std::string auth_header = base::StringPrintf(
+ "Digest realm=\"%s\", "
+ "domain=\"/\", qop=\"auth\", algorithm=MD5, nonce=\"%s\", "
+ "opaque=\"%s\"",
+ realm.c_str(), nonce.c_str(), opaque.c_str());
+ http_response->AddCustomHeader("WWW-Authenticate", auth_header);
+ http_response->set_content(base::StringPrintf(
+ "<html><head><title>Denied: %s</title></head>"
+ "<body>auth=%s<p>"
+ "You sent:<br>%s<p>We are replying:<br>%s<p></body></html>",
+ error.c_str(), auth.c_str(), request.all_headers.c_str(),
+ auth_header.c_str()));
+ return std::move(http_response);
+ }
+
+ http_response->set_content_type("text/html");
+ http_response->set_content(
+ base::StringPrintf("<html><head><title>%s/%s</title></head>"
+ "<body>auth=%s<p></body></html>",
+ username.c_str(), password.c_str(), auth.c_str()));
+
+ return std::move(http_response);
+}
+
+// /server-redirect?URL
+// Returns a server-redirect (301) to URL.
+scoped_ptr<HttpResponse> HandleServerRedirect(const HttpRequest& request) {
+ GURL request_url = request.GetURL();
+ std::string dest =
+ net::UnescapeURLComponent(request_url.query(), kUnescapeAll);
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_code(HTTP_MOVED_PERMANENTLY);
+ http_response->AddCustomHeader("Location", dest);
+ http_response->set_content_type("text/html");
+ http_response->set_content(base::StringPrintf(
+ "<html><head></head><body>Redirecting to %s</body></html>",
+ dest.c_str()));
+ return std::move(http_response);
+}
+
+// /cross-site?URL
+// Returns a cross-site redirect to URL.
+scoped_ptr<HttpResponse> HandleCrossSiteRedirect(EmbeddedTestServer* server,
+ const HttpRequest& request) {
+ if (!ShouldHandle(request, "/cross-site"))
+ return nullptr;
+
+ std::string dest_all = net::UnescapeURLComponent(
+ request.relative_url.substr(std::string("/cross-site").size() + 1),
+ kUnescapeAll);
+
+ std::string dest;
+ size_t delimiter = dest_all.find("/");
+ if (delimiter != std::string::npos) {
+ dest = base::StringPrintf(
+ "//%s:%hu/%s", dest_all.substr(0, delimiter).c_str(), server->port(),
+ dest_all.substr(delimiter + 1).c_str());
+ }
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_code(HTTP_MOVED_PERMANENTLY);
+ http_response->AddCustomHeader("Location", dest);
+ http_response->set_content_type("text/html");
+ http_response->set_content(base::StringPrintf(
+ "<html><head></head><body>Redirecting to %s</body></html>",
+ dest.c_str()));
+ return std::move(http_response);
+}
+
+// /client-redirect?URL
+// Returns a meta redirect to URL.
+scoped_ptr<HttpResponse> HandleClientRedirect(const HttpRequest& request) {
+ GURL request_url = request.GetURL();
+ std::string dest =
+ net::UnescapeURLComponent(request_url.query(), kUnescapeAll);
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content_type("text/html");
+ http_response->set_content(base::StringPrintf(
+ "<html><head><meta http-equiv=\"refresh\" content=\"0;url=%s\"></head>"
+ "<body>Redirecting to %s</body></html>",
+ dest.c_str(), dest.c_str()));
+ return std::move(http_response);
+}
+
+// /defaultresponse
+// Returns a valid 200 response.
+scoped_ptr<HttpResponse> HandleDefaultResponse(const HttpRequest& request) {
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_content_type("text/html");
+ http_response->set_content("Default response given for path: " +
+ request.relative_url);
+ return std::move(http_response);
+}
+
+// Delays |delay| seconds before sending a response to the client.
+class DelayedHttpResponse : public BasicHttpResponse {
+ public:
+ explicit DelayedHttpResponse(double delay) : delay_(delay) {}
+
+ void SendResponse(const SendBytesCallback& send,
+ const SendCompleteCallback& done) override {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, base::Bind(send, ToResponseString(), done),
+ base::TimeDelta::FromSecondsD(delay_));
+ }
+
+ private:
+ const double delay_;
+
+ DISALLOW_COPY_AND_ASSIGN(DelayedHttpResponse);
+};
+
+// /slow?N
+// Returns a response to the server delayed by N seconds.
+scoped_ptr<HttpResponse> HandleSlowServer(const HttpRequest& request) {
+ double delay = 1.0f;
+
+ GURL request_url = request.GetURL();
+ if (request_url.has_query())
+ delay = std::atof(request_url.query().c_str());
+
+ scoped_ptr<BasicHttpResponse> http_response(new DelayedHttpResponse(delay));
+ http_response->set_content_type("text/plain");
+ http_response->set_content(base::StringPrintf("waited %.1f seconds", delay));
+ return std::move(http_response);
+}
+
+} // namespace anonymous
+
+#define PREFIXED_HANDLER(prefix, handler) \
+ base::Bind(&HandlePrefixedRequest, prefix, base::Bind(handler))
+
+void RegisterDefaultHandlers(EmbeddedTestServer* server) {
+ server->RegisterDefaultHandler(base::Bind(&HandleDefaultConnect));
+
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/cachetime", &HandleCacheTime));
+ server->RegisterDefaultHandler(
+ base::Bind(&HandleEchoHeader, "/echoheader", "no-cache"));
+ server->RegisterDefaultHandler(
+ base::Bind(&HandleEchoHeader, "/echoheadercache", "max-age=60000"));
+ server->RegisterDefaultHandler(PREFIXED_HANDLER("/echo", &HandleEcho));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/echotitle", &HandleEchoTitle));
+ server->RegisterDefaultHandler(PREFIXED_HANDLER("/echoall", &HandleEchoAll));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/set-cookie", &HandleSetCookie));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/set-many-cookies", &HandleSetManyCookies));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/expect-and-set-cookie", &HandleExpectAndSetCookie));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/set-header", &HandleSetHeader));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/nocontent", &HandleNoContent));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/close-socket", &HandleCloseSocket));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/auth-basic", &HandleAuthBasic));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/auth-digest", &HandleAuthDigest));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/server-redirect", &HandleServerRedirect));
+ server->RegisterDefaultHandler(base::Bind(&HandleCrossSiteRedirect, server));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/client-redirect", &HandleClientRedirect));
+ server->RegisterDefaultHandler(
+ PREFIXED_HANDLER("/defaultresponse", &HandleDefaultResponse));
+ server->RegisterDefaultHandler(PREFIXED_HANDLER("/slow", &HandleSlowServer));
+
+ // TODO(svaldez): HandleDownload
+ // TODO(svaldez): HandleDownloadFinish
+ // TODO(svaldez): HandleZipFile
+ // TODO(svaldez): HandleSSLManySmallRecords
+ // TODO(svaldez): HandleChunkedServer
+ // TODO(svaldez): HandleGetSSLSessionCache
+ // TODO(svaldez): HandleGetChannelID
+ // TODO(svaldez): HandleGetClientCert
+ // TODO(svaldez): HandleClientCipherList
+ // TODO(svaldez): HandleEchoMultipartPost
+}
+
+#undef PREFIXED_HANDLER
+
+} // namespace test_server
+} // namespace net
diff --git a/chromium/net/test/embedded_test_server/default_handlers.h b/chromium/net/test/embedded_test_server/default_handlers.h
new file mode 100644
index 00000000000..90e6f1e8a5d
--- /dev/null
+++ b/chromium/net/test/embedded_test_server/default_handlers.h
@@ -0,0 +1,23 @@
+// Copyright 2015 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_EMBEDDED_TEST_SERVER_DEFAULT_HANDLERS_H_
+#define NET_TEST_EMBEDDED_TEST_SERVER_DEFAULT_HANDLERS_H_
+
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace net {
+namespace test_server {
+
+// This file is only meant for compatibility with testserver.py. No
+// additional handlers should be added here that don't affect multiple
+// distinct tests.
+
+// Registers default handlers for use in tests.
+void RegisterDefaultHandlers(EmbeddedTestServer* server);
+
+} // namespace test_server
+} // namespace net
+
+#endif // NET_TEST_EMBEDDED_TEST_SERVER_DEFAULT_HANDLERS_H_
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.cc b/chromium/net/test/embedded_test_server/embedded_test_server.cc
index 5b0079c8472..8f10e1ca301 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.cc
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.cc
@@ -4,12 +4,15 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
#include "base/process/process_metrics.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
@@ -17,117 +20,42 @@
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
+#include "crypto/rsa_private_key.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
+#include "net/base/test_data_directory.h"
+#include "net/cert/pem_tokenizer.h"
+#include "net/cert/test_root_certs.h"
+#include "net/socket/ssl_server_socket.h"
+#include "net/socket/stream_socket.h"
+#include "net/socket/tcp_server_socket.h"
+#include "net/ssl/ssl_server_config.h"
+#include "net/test/cert_test_util.h"
+#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
#include "net/test/embedded_test_server/http_connection.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
namespace net {
namespace test_server {
-namespace {
-
-class CustomHttpResponse : public HttpResponse {
- public:
- CustomHttpResponse(const std::string& headers, const std::string& contents)
- : headers_(headers), contents_(contents) {
- }
-
- std::string ToResponseString() const override {
- return headers_ + "\r\n" + contents_;
- }
-
- private:
- std::string headers_;
- std::string contents_;
-
- DISALLOW_COPY_AND_ASSIGN(CustomHttpResponse);
-};
-
-// Handles |request| by serving a file from under |server_root|.
-scoped_ptr<HttpResponse> HandleFileRequest(
- const base::FilePath& server_root,
- const HttpRequest& request) {
- // This is a test-only server. Ignore I/O thread restrictions.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
-
- std::string relative_url(request.relative_url);
- // A proxy request will have an absolute path. Simulate the proxy by stripping
- // the scheme, host, and port.
- GURL relative_gurl(relative_url);
- if (relative_gurl.is_valid())
- relative_url = relative_gurl.PathForRequest();
-
- // Trim the first byte ('/').
- std::string request_path = relative_url.substr(1);
-
- // Remove the query string if present.
- size_t query_pos = request_path.find('?');
- if (query_pos != std::string::npos)
- request_path = request_path.substr(0, query_pos);
-
- base::FilePath file_path(server_root.AppendASCII(request_path));
- std::string file_contents;
- if (!base::ReadFileToString(file_path, &file_contents))
- return scoped_ptr<HttpResponse>();
-
- base::FilePath headers_path(
- file_path.AddExtension(FILE_PATH_LITERAL("mock-http-headers")));
-
- if (base::PathExists(headers_path)) {
- std::string headers_contents;
- if (!base::ReadFileToString(headers_path, &headers_contents))
- return scoped_ptr<HttpResponse>();
-
- scoped_ptr<CustomHttpResponse> http_response(
- new CustomHttpResponse(headers_contents, file_contents));
- return http_response.Pass();
- }
-
- scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
- http_response->set_code(HTTP_OK);
- http_response->set_content(file_contents);
- return http_response.Pass();
-}
-
-} // namespace
-
-HttpListenSocket::HttpListenSocket(const SocketDescriptor socket_descriptor,
- StreamListenSocket::Delegate* delegate)
- : TCPListenSocket(socket_descriptor, delegate) {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void HttpListenSocket::Listen() {
- DCHECK(thread_checker_.CalledOnValidThread());
- TCPListenSocket::Listen();
-}
-
-void HttpListenSocket::ListenOnIOThread() {
- DCHECK(thread_checker_.CalledOnValidThread());
-#if !defined(OS_POSIX)
- // This method may be called after the IO thread is changed, thus we need to
- // call |WatchSocket| again to make sure it listens on the current IO thread.
- // Only needed for non POSIX platforms, since on POSIX platforms
- // StreamListenSocket::Listen already calls WatchSocket inside the function.
- WatchSocket(WAITING_ACCEPT);
-#endif
- Listen();
-}
+EmbeddedTestServer::EmbeddedTestServer() : EmbeddedTestServer(TYPE_HTTP) {}
-HttpListenSocket::~HttpListenSocket() {
+EmbeddedTestServer::EmbeddedTestServer(Type type)
+ : is_using_ssl_(type == TYPE_HTTPS),
+ connection_listener_(nullptr),
+ port_(0),
+ cert_(CERT_OK),
+ weak_factory_(this) {
DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void HttpListenSocket::DetachFromThread() {
- thread_checker_.DetachFromThread();
-}
-EmbeddedTestServer::EmbeddedTestServer()
- : connection_listener_(nullptr), port_(0), weak_factory_(this) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ if (is_using_ssl_) {
+ TestRootCerts* root_certs = TestRootCerts::GetInstance();
+ base::FilePath certs_dir(GetTestCertsDirectory());
+ root_certs->AddFromFile(certs_dir.AppendASCII("root_ca_cert.pem"));
+ }
}
EmbeddedTestServer::~EmbeddedTestServer() {
@@ -144,94 +72,71 @@ void EmbeddedTestServer::SetConnectionListener(
connection_listener_ = listener;
}
-bool EmbeddedTestServer::InitializeAndWaitUntilReady() {
- StartThread();
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!PostTaskToIOThreadAndWait(base::Bind(
- &EmbeddedTestServer::InitializeOnIOThread, base::Unretained(this)))) {
+bool EmbeddedTestServer::Start() {
+ bool success = InitializeAndListen();
+ if (!success)
return false;
- }
- return Started() && base_url_.is_valid();
+ StartAcceptingConnections();
+ return true;
}
-void EmbeddedTestServer::StopThread() {
- DCHECK(io_thread_ && io_thread_->IsRunning());
-
-#if defined(OS_LINUX)
- const int thread_count =
- base::GetNumberOfThreads(base::GetCurrentProcessHandle());
-#endif
+bool EmbeddedTestServer::InitializeAndListen() {
+ DCHECK(!Started());
- io_thread_->Stop();
- io_thread_.reset();
- thread_checker_.DetachFromThread();
- listen_socket_->DetachFromThread();
+ listen_socket_.reset(new TCPServerSocket(nullptr, NetLog::Source()));
-#if defined(OS_LINUX)
- // Busy loop to wait for thread count to decrease. This is needed because
- // pthread_join does not guarantee that kernel stat is updated when it
- // returns. Thus, GetNumberOfThreads does not immediately reflect the stopped
- // thread and hits the thread number DCHECK in render_sandbox_host_linux.cc
- // in browser_tests.
- while (thread_count ==
- base::GetNumberOfThreads(base::GetCurrentProcessHandle())) {
- base::PlatformThread::YieldCurrentThread();
+ int result = listen_socket_->ListenWithAddressAndPort("127.0.0.1", 0, 10);
+ if (result) {
+ LOG(ERROR) << "Listen failed: " << ErrorToString(result);
+ listen_socket_.reset();
+ return false;
}
-#endif
-}
-void EmbeddedTestServer::RestartThreadAndListen() {
- StartThread();
- CHECK(PostTaskToIOThreadAndWait(base::Bind(
- &EmbeddedTestServer::ListenOnIOThread, base::Unretained(this))));
-}
+ result = listen_socket_->GetLocalAddress(&local_endpoint_);
+ if (result != OK) {
+ LOG(ERROR) << "GetLocalAddress failed: " << ErrorToString(result);
+ listen_socket_.reset();
+ return false;
+ }
-bool EmbeddedTestServer::ShutdownAndWaitUntilComplete() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ if (is_using_ssl_) {
+ base_url_ = GURL("https://" + local_endpoint_.ToString());
+ if (cert_ == CERT_MISMATCHED_NAME || cert_ == CERT_COMMON_NAME_IS_DOMAIN) {
+ base_url_ = GURL(
+ base::StringPrintf("https://localhost:%d", local_endpoint_.port()));
+ }
+ } else {
+ base_url_ = GURL("http://" + local_endpoint_.ToString());
+ }
+ port_ = local_endpoint_.port();
- return PostTaskToIOThreadAndWait(base::Bind(
- &EmbeddedTestServer::ShutdownOnIOThread, base::Unretained(this)));
+ listen_socket_->DetachFromThread();
+ return true;
}
-void EmbeddedTestServer::StartThread() {
+void EmbeddedTestServer::StartAcceptingConnections() {
DCHECK(!io_thread_.get());
base::Thread::Options thread_options;
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
- io_thread_.reset(new base::Thread("EmbeddedTestServer io thread"));
+ io_thread_.reset(new base::Thread("EmbeddedTestServer IO Thread"));
CHECK(io_thread_->StartWithOptions(thread_options));
CHECK(io_thread_->WaitUntilThreadStarted());
-}
-
-void EmbeddedTestServer::InitializeOnIOThread() {
- DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
- DCHECK(!Started());
- SocketDescriptor socket_descriptor =
- TCPListenSocket::CreateAndBindAnyPort("127.0.0.1", &port_);
- if (socket_descriptor == kInvalidSocket)
- return;
-
- listen_socket_.reset(new HttpListenSocket(socket_descriptor, this));
- listen_socket_->Listen();
-
- IPEndPoint address;
- int result = listen_socket_->GetLocalAddress(&address);
- if (result == OK) {
- base_url_ = GURL(std::string("http://") + address.ToString());
- } else {
- LOG(ERROR) << "GetLocalAddress failed: " << ErrorToString(result);
- }
+ io_thread_->task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&EmbeddedTestServer::DoAcceptLoop, base::Unretained(this)));
}
-void EmbeddedTestServer::ListenOnIOThread() {
- DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
- DCHECK(Started());
- listen_socket_->ListenOnIOThread();
+bool EmbeddedTestServer::ShutdownAndWaitUntilComplete() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ return PostTaskToIOThreadAndWait(base::Bind(
+ &EmbeddedTestServer::ShutdownOnIOThread, base::Unretained(this)));
}
void EmbeddedTestServer::ShutdownOnIOThread() {
DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
-
+ weak_factory_.InvalidateWeakPtrs();
listen_socket_.reset();
STLDeleteContainerPairSecondPointers(connections_.begin(),
connections_.end());
@@ -239,33 +144,37 @@ void EmbeddedTestServer::ShutdownOnIOThread() {
}
void EmbeddedTestServer::HandleRequest(HttpConnection* connection,
- scoped_ptr<HttpRequest> request) {
+ scoped_ptr<HttpRequest> request) {
DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
- bool request_handled = false;
+ scoped_ptr<HttpResponse> response;
- for (size_t i = 0; i < request_handlers_.size(); ++i) {
- scoped_ptr<HttpResponse> response =
- request_handlers_[i].Run(*request.get());
- if (response.get()) {
- connection->SendResponse(response.Pass());
- request_handled = true;
+ for (const auto& handler : request_handlers_) {
+ response = handler.Run(*request);
+ if (response)
break;
+ }
+
+ if (!response) {
+ for (const auto& handler : default_request_handlers_) {
+ response = handler.Run(*request);
+ if (response)
+ break;
}
}
- if (!request_handled) {
+ if (!response) {
LOG(WARNING) << "Request not handled. Returning 404: "
<< request->relative_url;
scoped_ptr<BasicHttpResponse> not_found_response(new BasicHttpResponse);
not_found_response->set_code(HTTP_NOT_FOUND);
- connection->SendResponse(not_found_response.Pass());
+ response = std::move(not_found_response);
}
- // Drop the connection, since we do not support multiple requests per
- // connection.
- connections_.erase(connection->socket_.get());
- delete connection;
+ response->SendResponse(
+ base::Bind(&HttpConnection::SendResponseBytes, connection->GetWeakPtr()),
+ base::Bind(&EmbeddedTestServer::DidClose, weak_factory_.GetWeakPtr(),
+ connection));
}
GURL EmbeddedTestServer::GetURL(const std::string& relative_url) const {
@@ -284,73 +193,208 @@ GURL EmbeddedTestServer::GetURL(
return local_url.ReplaceComponents(replace_host);
}
-bool EmbeddedTestServer::GetAddressList(net::AddressList* address_list) const {
- if (!listen_socket_)
- return false;
- IPEndPoint endpoint;
- int result = listen_socket_->GetLocalAddress(&endpoint);
- if (result != OK)
- return false;
-
- *address_list = net::AddressList(endpoint);
+bool EmbeddedTestServer::GetAddressList(AddressList* address_list) const {
+ *address_list = AddressList(local_endpoint_);
return true;
}
+void EmbeddedTestServer::SetSSLConfig(ServerCertificate cert,
+ const SSLServerConfig& ssl_config) {
+ DCHECK(!Started());
+ cert_ = cert;
+ ssl_config_ = ssl_config;
+}
+
+void EmbeddedTestServer::SetSSLConfig(ServerCertificate cert) {
+ SetSSLConfig(cert, SSLServerConfig());
+}
+
+std::string EmbeddedTestServer::GetCertificateName() const {
+ DCHECK(is_using_ssl_);
+ switch (cert_) {
+ case CERT_OK:
+ case CERT_MISMATCHED_NAME:
+ return "ok_cert.pem";
+ case CERT_COMMON_NAME_IS_DOMAIN:
+ return "localhost_cert.pem";
+ case CERT_EXPIRED:
+ return "expired_cert.pem";
+ case CERT_CHAIN_WRONG_ROOT:
+ return "redundant-server-chain.pem";
+ case CERT_BAD_VALIDITY:
+ return "bad_validity.pem";
+ }
+
+ return "ok_cert.pem";
+}
+
+scoped_refptr<X509Certificate> EmbeddedTestServer::GetCertificate() const {
+ DCHECK(is_using_ssl_);
+ base::FilePath certs_dir(GetTestCertsDirectory());
+ return ImportCertFromFile(certs_dir, GetCertificateName());
+}
+
void EmbeddedTestServer::ServeFilesFromDirectory(
const base::FilePath& directory) {
RegisterRequestHandler(base::Bind(&HandleFileRequest, directory));
}
+void EmbeddedTestServer::ServeFilesFromSourceDirectory(
+ const std::string& relative) {
+ base::FilePath test_data_dir;
+ CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
+ ServeFilesFromDirectory(test_data_dir.AppendASCII(relative));
+}
+
+void EmbeddedTestServer::ServeFilesFromSourceDirectory(
+ const base::FilePath& relative) {
+ base::FilePath test_data_dir;
+ CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
+ ServeFilesFromDirectory(test_data_dir.Append(relative));
+}
+
+void EmbeddedTestServer::AddDefaultHandlers(const base::FilePath& directory) {
+ RegisterDefaultHandlers(this);
+ ServeFilesFromSourceDirectory(directory);
+}
+
void EmbeddedTestServer::RegisterRequestHandler(
const HandleRequestCallback& callback) {
+ // TODO(svaldez): Add check to prevent RegisterHandler from being called
+ // after the server has started. https://crbug.com/546060
request_handlers_.push_back(callback);
}
-void EmbeddedTestServer::DidAccept(StreamListenSocket* server,
- scoped_ptr<StreamListenSocket> connection) {
+void EmbeddedTestServer::RegisterDefaultHandler(
+ const HandleRequestCallback& callback) {
+ // TODO(svaldez): Add check to prevent RegisterHandler from being called
+ // after the server has started. https://crbug.com/546060
+ default_request_handlers_.push_back(callback);
+}
+
+scoped_ptr<StreamSocket> EmbeddedTestServer::DoSSLUpgrade(
+ scoped_ptr<StreamSocket> connection) {
+ DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
+
+ base::FilePath certs_dir(GetTestCertsDirectory());
+ std::string cert_name = GetCertificateName();
+
+ base::FilePath key_path = certs_dir.AppendASCII(cert_name);
+ std::string key_string;
+ CHECK(base::ReadFileToString(key_path, &key_string));
+ std::vector<std::string> headers;
+ headers.push_back("PRIVATE KEY");
+ PEMTokenizer pem_tokenizer(key_string, headers);
+ pem_tokenizer.GetNext();
+ std::vector<uint8_t> key_vector;
+ key_vector.assign(pem_tokenizer.data().begin(), pem_tokenizer.data().end());
+
+ scoped_ptr<crypto::RSAPrivateKey> server_key(
+ crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
+
+ return CreateSSLServerSocket(std::move(connection), GetCertificate().get(),
+ *server_key, ssl_config_);
+}
+
+void EmbeddedTestServer::DoAcceptLoop() {
+ int rv = OK;
+ while (rv == OK) {
+ rv = listen_socket_->Accept(
+ &accepted_socket_, base::Bind(&EmbeddedTestServer::OnAcceptCompleted,
+ base::Unretained(this)));
+ if (rv == ERR_IO_PENDING)
+ return;
+ HandleAcceptResult(std::move(accepted_socket_));
+ }
+}
+
+void EmbeddedTestServer::OnAcceptCompleted(int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ HandleAcceptResult(std::move(accepted_socket_));
+ DoAcceptLoop();
+}
+
+void EmbeddedTestServer::OnHandshakeDone(HttpConnection* connection, int rv) {
+ if (connection->socket_->IsConnected())
+ ReadData(connection);
+ else
+ DidClose(connection);
+}
+
+void EmbeddedTestServer::HandleAcceptResult(scoped_ptr<StreamSocket> socket) {
DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
if (connection_listener_)
- connection_listener_->AcceptedSocket(*connection);
+ connection_listener_->AcceptedSocket(*socket);
+
+ if (is_using_ssl_)
+ socket = DoSSLUpgrade(std::move(socket));
HttpConnection* http_connection = new HttpConnection(
- connection.Pass(), base::Bind(&EmbeddedTestServer::HandleRequest,
- weak_factory_.GetWeakPtr()));
- // TODO(szym): Make HttpConnection the StreamListenSocket delegate.
+ std::move(socket),
+ base::Bind(&EmbeddedTestServer::HandleRequest, base::Unretained(this)));
connections_[http_connection->socket_.get()] = http_connection;
+
+ if (is_using_ssl_) {
+ SSLServerSocket* ssl_socket =
+ static_cast<SSLServerSocket*>(http_connection->socket_.get());
+ int rv = ssl_socket->Handshake(
+ base::Bind(&EmbeddedTestServer::OnHandshakeDone, base::Unretained(this),
+ http_connection));
+ if (rv != ERR_IO_PENDING)
+ OnHandshakeDone(http_connection, rv);
+ } else {
+ ReadData(http_connection);
+ }
+}
+
+void EmbeddedTestServer::ReadData(HttpConnection* connection) {
+ while (true) {
+ int rv =
+ connection->ReadData(base::Bind(&EmbeddedTestServer::OnReadCompleted,
+ base::Unretained(this), connection));
+ if (rv == ERR_IO_PENDING)
+ return;
+ if (!HandleReadResult(connection, rv))
+ return;
+ }
}
-void EmbeddedTestServer::DidRead(StreamListenSocket* connection,
- const char* data,
- int length) {
+void EmbeddedTestServer::OnReadCompleted(HttpConnection* connection, int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ if (HandleReadResult(connection, rv))
+ ReadData(connection);
+}
+
+bool EmbeddedTestServer::HandleReadResult(HttpConnection* connection, int rv) {
DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
if (connection_listener_)
- connection_listener_->ReadFromSocket(*connection);
-
- HttpConnection* http_connection = FindConnection(connection);
- if (http_connection == NULL) {
- LOG(WARNING) << "Unknown connection.";
- return;
+ connection_listener_->ReadFromSocket(*connection->socket_);
+ if (rv <= 0) {
+ DidClose(connection);
+ return false;
}
- http_connection->ReceiveData(std::string(data, length));
+
+ // Once a single complete request has been received, there is no further need
+ // for the connection and it may be destroyed once the response has been sent.
+ if (connection->ConsumeData(rv))
+ return false;
+
+ return true;
}
-void EmbeddedTestServer::DidClose(StreamListenSocket* connection) {
+void EmbeddedTestServer::DidClose(HttpConnection* connection) {
DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
+ DCHECK(connection);
+ DCHECK_EQ(1u, connections_.count(connection->socket_.get()));
- HttpConnection* http_connection = FindConnection(connection);
- if (http_connection == NULL) {
- LOG(WARNING) << "Unknown connection.";
- return;
- }
- delete http_connection;
- connections_.erase(connection);
+ connections_.erase(connection->socket_.get());
+ delete connection;
}
-HttpConnection* EmbeddedTestServer::FindConnection(
- StreamListenSocket* socket) {
+HttpConnection* EmbeddedTestServer::FindConnection(StreamSocket* socket) {
DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
- std::map<StreamListenSocket*, HttpConnection*>::iterator it =
+ std::map<StreamSocket*, HttpConnection*>::iterator it =
connections_.find(socket);
if (it == connections_.end()) {
return NULL;
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.h b/chromium/net/test/embedded_test_server/embedded_test_server.h
index 01148a5df3d..ad69a141843 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.h
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.h
@@ -5,26 +5,36 @@
#ifndef NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
+#include "crypto/rsa_private_key.h"
#include "net/base/address_list.h"
-#include "net/test/embedded_test_server/tcp_listen_socket.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/ip_endpoint.h"
+#include "net/cert/x509_certificate.h"
+#include "net/socket/stream_socket.h"
+#include "net/socket/tcp_server_socket.h"
+#include "net/ssl/ssl_server_config.h"
#include "url/gurl.h"
-namespace base {
-class FilePath;
-}
-
namespace net {
+
+class StreamSocket;
+class TCPServerSocket;
+
namespace test_server {
class EmbeddedTestServerConnectionListener;
@@ -32,28 +42,6 @@ class HttpConnection;
class HttpResponse;
struct HttpRequest;
-// This class is required to be able to have composition instead of inheritance,
-class HttpListenSocket : public TCPListenSocket {
- public:
- HttpListenSocket(const SocketDescriptor socket_descriptor,
- StreamListenSocket::Delegate* delegate);
- ~HttpListenSocket() override;
- virtual void Listen();
-
- // Listen on the current IO thread. If the IO thread has changed since this
- // object is constructed, call |ListenOnIOThread| to make sure it listens on
- // the right thread. Otherwise must call |Listen| instead.
- void ListenOnIOThread();
-
- private:
- friend class EmbeddedTestServer;
-
- // Detaches the current from |thread_checker_|.
- void DetachFromThread();
-
- base::ThreadChecker thread_checker_;
-};
-
// Class providing an HTTP server for testing purpose. This is a basic server
// providing only an essential subset of HTTP/1.1 protocol. Especially,
// it assumes that the request syntax is correct. It *does not* support
@@ -63,7 +51,7 @@ class HttpListenSocket : public TCPListenSocket {
//
// void SetUp() {
// test_server_.reset(new EmbeddedTestServer());
-// ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
+// ASSERT_TRUE(test_server_.Start());
// test_server_->RegisterRequestHandler(
// base::Bind(&FooTest::HandleRequest, base::Unretained(this)));
// }
@@ -81,34 +69,58 @@ class HttpListenSocket : public TCPListenSocket {
// }
//
// For a test that spawns another process such as browser_tests, it is
-// suggested to call InitializeAndWaitUntilReady in SetUpOnMainThread after
-// the process is spawned. If you have to do it before the process spawns,
-// you need to stop the server's thread so that there is no no other
-// threads running while spawning the process. To do so, please follow
-// the following example:
+// suggested to call Start in SetUpOnMainThread after the process is spawned.
+// If you have to do it before the process spawns, you need to first setup the
+// listen socket so that there is no no other threads running while spawning
+// the process. To do so, please follow the following example:
//
// void SetUp() {
-// ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-// // EmbeddedTestServer spawns a thread to initialize socket.
-// // Stop the thread in preparation for fork and exec.
-// embedded_test_server()->StopThread();
+// ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
// ...
// InProcessBrowserTest::SetUp();
// }
//
// void SetUpOnMainThread() {
-// embedded_test_server()->RestartThreadAndListen();
+// // Starts the accept IO thread.
+// embedded_test_server()->StartAcceptingConnections();
// }
//
-class EmbeddedTestServer : public StreamListenSocket::Delegate {
+class EmbeddedTestServer {
public:
+ enum Type {
+ TYPE_HTTP,
+ TYPE_HTTPS,
+ };
+
+ enum ServerCertificate {
+ CERT_OK,
+
+ CERT_MISMATCHED_NAME,
+ CERT_EXPIRED,
+
+ // A certificate with invalid notBefore and notAfter times. Windows'
+ // certificate library will not parse this certificate.
+ CERT_BAD_VALIDITY,
+
+ // Cross-signed certificate to test PKIX path building. Contains an
+ // intermediate cross-signed by an unknown root, while the client (via
+ // TestRootStore) is expected to have a self-signed version of the
+ // intermediate.
+ CERT_CHAIN_WRONG_ROOT,
+
+ // Causes the testserver to use a hostname that is a domain
+ // instead of an IP.
+ CERT_COMMON_NAME_IS_DOMAIN,
+ };
+
typedef base::Callback<scoped_ptr<HttpResponse>(
const HttpRequest& request)> HandleRequestCallback;
- // Creates a http test server. InitializeAndWaitUntilReady() must be called
- // to start the server.
+ // Creates a http test server. Start() must be called to start the server.
+ // |type| indicates the protocol type of the server (HTTP/HTTPS).
EmbeddedTestServer();
- ~EmbeddedTestServer() override;
+ explicit EmbeddedTestServer(Type type);
+ ~EmbeddedTestServer();
// Sets a connection listener, that would be notified when various connection
// events happen. May only be called before the server is started. Caller
@@ -116,16 +128,30 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate {
void SetConnectionListener(EmbeddedTestServerConnectionListener* listener);
// Initializes and waits until the server is ready to accept requests.
- bool InitializeAndWaitUntilReady() WARN_UNUSED_RESULT;
+ // This is the equivalent of calling InitializeAndListen() followed by
+ // StartAcceptingConnections().
+ // Returns whether a listening socket has been successfully created.
+ bool Start();
+
+ // Starts listening for incoming connections but will not yet accept them.
+ // Returns whether a listening socket has been succesfully created.
+ bool InitializeAndListen() WARN_UNUSED_RESULT;
+
+ // Starts the Accept IO Thread and begins accepting connections.
+ void StartAcceptingConnections();
// Shuts down the http server and waits until the shutdown is complete.
bool ShutdownAndWaitUntilComplete() WARN_UNUSED_RESULT;
- // Checks if the server is started.
+ // Checks if the server has started listening for incoming connections.
bool Started() const {
return listen_socket_.get() != NULL;
}
+ HostPortPair host_port_pair() const {
+ return HostPortPair::FromURL(base_url_);
+ }
+
// Returns the base URL to the server, which looks like
// http://127.0.0.1:<port>/, where <port> is the actual port number used by
// the server.
@@ -143,81 +169,120 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate {
const std::string& relative_url) const;
// Returns the address list needed to connect to the server.
- bool GetAddressList(net::AddressList* address_list) const WARN_UNUSED_RESULT;
+ bool GetAddressList(AddressList* address_list) const WARN_UNUSED_RESULT;
// Returns the port number used by the server.
- uint16 port() const { return port_; }
+ uint16_t port() const { return port_; }
+
+ void SetSSLConfig(ServerCertificate cert, const SSLServerConfig& ssl_config);
+ void SetSSLConfig(ServerCertificate cert);
+
+ // Returns the file name of the certificate the server is using. The test
+ // certificates can be found in net/data/ssl/certificates/.
+ std::string GetCertificateName() const;
+
+ // Returns the certificate that the server is using.
+ scoped_refptr<X509Certificate> GetCertificate() const;
// Registers request handler which serves files from |directory|.
// For instance, a request to "/foo.html" is served by "foo.html" under
// |directory|. Files under sub directories are also handled in the same way
// (i.e. "/foo/bar.html" is served by "foo/bar.html" under |directory|).
+ // TODO(svaldez): Merge ServeFilesFromDirectory and
+ // ServeFilesFromSourceDirectory.
void ServeFilesFromDirectory(const base::FilePath& directory);
+ // Serves files relative to DIR_SOURCE_ROOT.
+ void ServeFilesFromSourceDirectory(const std::string& relative);
+ void ServeFilesFromSourceDirectory(const base::FilePath& relative);
+
+ // Registers the default handlers and serve additional files from the
+ // |directory| directory, relative to DIR_SOURCE_ROOT.
+ void AddDefaultHandlers(const base::FilePath& directory);
+
// The most general purpose method. Any request processing can be added using
// this method. Takes ownership of the object. The |callback| is called
// on UI thread.
void RegisterRequestHandler(const HandleRequestCallback& callback);
- // Stops IO thread that handles http requests.
- void StopThread();
-
- // Restarts IO thread and listen on the socket.
- void RestartThreadAndListen();
+ // Adds default handlers, including those added by AddDefaultHandlers, to be
+ // tried after all other user-specified handlers have been tried.
+ void RegisterDefaultHandler(const HandleRequestCallback& callback);
private:
- void StartThread();
-
- // Initializes and starts the server. If initialization succeeds, Starts()
- // will return true.
- void InitializeOnIOThread();
- void ListenOnIOThread();
-
// Shuts down the server.
void ShutdownOnIOThread();
- // Handles a request when it is parsed. It passes the request to registed
+ // Upgrade the TCP connection to one over SSL.
+ scoped_ptr<StreamSocket> DoSSLUpgrade(scoped_ptr<StreamSocket> connection);
+ // Handles async callback when the SSL handshake has been completed.
+ void OnHandshakeDone(HttpConnection* connection, int rv);
+
+ // Begins accepting new client connections.
+ void DoAcceptLoop();
+ // Handles async callback when there is a new client socket. |rv| is the
+ // return value of the socket Accept.
+ void OnAcceptCompleted(int rv);
+ // Adds the new |socket| to the list of clients and begins the reading
+ // data.
+ void HandleAcceptResult(scoped_ptr<StreamSocket> socket);
+
+ // Attempts to read data from the |connection|'s socket.
+ void ReadData(HttpConnection* connection);
+ // Handles async callback when new data has been read from the |connection|.
+ void OnReadCompleted(HttpConnection* connection, int rv);
+ // Parses the data read from the |connection| and returns true if the entire
+ // request has been received.
+ bool HandleReadResult(HttpConnection* connection, int rv);
+
+ // Closes and removes the connection upon error or completion.
+ void DidClose(HttpConnection* connection);
+
+ // Handles a request when it is parsed. It passes the request to registered
// request handlers and sends a http response.
void HandleRequest(HttpConnection* connection,
scoped_ptr<HttpRequest> request);
- // StreamListenSocket::Delegate overrides:
- void DidAccept(StreamListenSocket* server,
- scoped_ptr<StreamListenSocket> connection) override;
- void DidRead(StreamListenSocket* connection,
- const char* data,
- int length) override;
- void DidClose(StreamListenSocket* connection) override;
-
- HttpConnection* FindConnection(StreamListenSocket* socket);
+ HttpConnection* FindConnection(StreamSocket* socket);
// Posts a task to the |io_thread_| and waits for a reply.
bool PostTaskToIOThreadAndWait(
const base::Closure& closure) WARN_UNUSED_RESULT;
+ const bool is_using_ssl_;
+
scoped_ptr<base::Thread> io_thread_;
- scoped_ptr<HttpListenSocket> listen_socket_;
+ scoped_ptr<TCPServerSocket> listen_socket_;
+ scoped_ptr<StreamSocket> accepted_socket_;
+
EmbeddedTestServerConnectionListener* connection_listener_;
- uint16 port_;
+ uint16_t port_;
GURL base_url_;
+ IPEndPoint local_endpoint_;
// Owns the HttpConnection objects.
- std::map<StreamListenSocket*, HttpConnection*> connections_;
+ std::map<StreamSocket*, HttpConnection*> connections_;
- // Vector of registered request handlers.
+ // Vector of registered and default request handlers.
std::vector<HandleRequestCallback> request_handlers_;
+ std::vector<HandleRequestCallback> default_request_handlers_;
base::ThreadChecker thread_checker_;
- // Note: This should remain the last member so it'll be destroyed and
- // invalidate its weak pointers before any other members are destroyed.
+ net::SSLServerConfig ssl_config_;
+ ServerCertificate cert_;
+
base::WeakPtrFactory<EmbeddedTestServer> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServer);
};
} // namespace test_server
+
+// TODO(svaldez): Refactor EmbeddedTestServer to be in the net namespace.
+using test_server::EmbeddedTestServer;
+
} // namespace net
#endif // NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server_connection_listener.h b/chromium/net/test/embedded_test_server/embedded_test_server_connection_listener.h
index 5ebef3c9b18..01d5415220d 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server_connection_listener.h
+++ b/chromium/net/test/embedded_test_server/embedded_test_server_connection_listener.h
@@ -6,18 +6,19 @@
#define NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_CONNECTION_LISTENER_H_
namespace net {
-namespace test_server {
-class StreamListenSocket;
+class StreamSocket;
+
+namespace test_server {
// An interface for connection event notifications.
class EmbeddedTestServerConnectionListener {
public:
// Notified when a socket was accepted by the EmbeddedTestServer.
- virtual void AcceptedSocket(const StreamListenSocket& socket) = 0;
+ virtual void AcceptedSocket(const StreamSocket& socket) = 0;
// Notified when a socket was read from by the EmbeddedTestServer.
- virtual void ReadFromSocket(const StreamListenSocket& socket) = 0;
+ virtual void ReadFromSocket(const StreamSocket& socket) = 0;
protected:
EmbeddedTestServerConnectionListener() {}
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 4ff1afc38a1..a08d3b7e254 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,12 +4,17 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include <utility>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
+#include "crypto/nss_util.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_response_headers.h"
#include "net/log/test_net_log.h"
@@ -18,12 +23,17 @@
#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
-#include "net/test/spawned_test_server/base_test_server.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+#include "net/cert_net/nss_ocsp.h"
+#endif
+
namespace net {
namespace test_server {
@@ -64,8 +74,7 @@ class TestConnectionListener
// Get called from the EmbeddedTestServer thread to be notified that
// a connection was accepted.
- void AcceptedSocket(
- const net::test_server::StreamListenSocket& connection) override {
+ void AcceptedSocket(const net::StreamSocket& connection) override {
base::AutoLock lock(lock_);
++socket_accepted_count_;
task_runner_->PostTask(FROM_HERE, accept_loop_.QuitClosure());
@@ -73,8 +82,7 @@ class TestConnectionListener
// Get called from the EmbeddedTestServer thread to be notified that
// a connection was read from.
- void ReadFromSocket(
- const net::test_server::StreamListenSocket& connection) override {
+ void ReadFromSocket(const net::StreamSocket& connection) override {
base::AutoLock lock(lock_);
did_read_from_socket_ = true;
}
@@ -103,8 +111,9 @@ class TestConnectionListener
DISALLOW_COPY_AND_ASSIGN(TestConnectionListener);
};
-class EmbeddedTestServerTest: public testing::Test,
- public URLFetcherDelegate {
+class EmbeddedTestServerTest
+ : public testing::TestWithParam<EmbeddedTestServer::Type>,
+ public URLFetcherDelegate {
public:
EmbeddedTestServerTest()
: num_responses_received_(0),
@@ -113,6 +122,15 @@ class EmbeddedTestServerTest: public testing::Test,
}
void SetUp() override {
+#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+ // 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));
@@ -120,20 +138,23 @@ class EmbeddedTestServerTest: public testing::Test,
request_context_getter_ =
new TestURLRequestContextGetter(io_thread_.task_runner());
- server_.reset(new EmbeddedTestServer);
+ server_.reset(new EmbeddedTestServer(GetParam()));
server_->SetConnectionListener(&connection_listener_);
- ASSERT_TRUE(server_->InitializeAndWaitUntilReady());
}
void TearDown() override {
- ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete());
+ if (server_->Started())
+ ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete());
+#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+ ShutdownNSSHttpIO();
+#endif
}
// URLFetcherDelegate override.
void OnURLFetchComplete(const URLFetcher* source) override {
++num_responses_received_;
if (num_responses_received_ == num_responses_expected_)
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
// Waits until the specified number of responses are received.
@@ -159,7 +180,7 @@ class EmbeddedTestServerTest: public testing::Test,
http_response->set_code(code);
http_response->set_content(content);
http_response->set_content_type(content_type);
- return http_response.Pass();
+ return std::move(http_response);
}
return nullptr;
@@ -175,24 +196,44 @@ class EmbeddedTestServerTest: public testing::Test,
scoped_ptr<EmbeddedTestServer> server_;
};
-TEST_F(EmbeddedTestServerTest, GetBaseURL) {
- EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/", server_->port()),
- server_->base_url().spec());
+TEST_P(EmbeddedTestServerTest, GetBaseURL) {
+ ASSERT_TRUE(server_->Start());
+ if (GetParam() == EmbeddedTestServer::TYPE_HTTPS) {
+ EXPECT_EQ(base::StringPrintf("https://127.0.0.1:%u/", server_->port()),
+ server_->base_url().spec());
+ } else {
+ EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/", server_->port()),
+ server_->base_url().spec());
+ }
}
-TEST_F(EmbeddedTestServerTest, GetURL) {
- EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/path?query=foo",
- server_->port()),
- server_->GetURL("/path?query=foo").spec());
+TEST_P(EmbeddedTestServerTest, GetURL) {
+ ASSERT_TRUE(server_->Start());
+ if (GetParam() == EmbeddedTestServer::TYPE_HTTPS) {
+ EXPECT_EQ(base::StringPrintf("https://127.0.0.1:%u/path?query=foo",
+ server_->port()),
+ server_->GetURL("/path?query=foo").spec());
+ } else {
+ EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/path?query=foo",
+ server_->port()),
+ server_->GetURL("/path?query=foo").spec());
+ }
}
-TEST_F(EmbeddedTestServerTest, GetURLWithHostname) {
- EXPECT_EQ(base::StringPrintf("http://foo.com:%d/path?query=foo",
- server_->port()),
- server_->GetURL("foo.com", "/path?query=foo").spec());
+TEST_P(EmbeddedTestServerTest, GetURLWithHostname) {
+ ASSERT_TRUE(server_->Start());
+ if (GetParam() == EmbeddedTestServer::TYPE_HTTPS) {
+ EXPECT_EQ(base::StringPrintf("https://foo.com:%d/path?query=foo",
+ server_->port()),
+ server_->GetURL("foo.com", "/path?query=foo").spec());
+ } else {
+ EXPECT_EQ(
+ base::StringPrintf("http://foo.com:%d/path?query=foo", server_->port()),
+ server_->GetURL("foo.com", "/path?query=foo").spec());
+ }
}
-TEST_F(EmbeddedTestServerTest, RegisterRequestHandler) {
+TEST_P(EmbeddedTestServerTest, RegisterRequestHandler) {
server_->RegisterRequestHandler(
base::Bind(&EmbeddedTestServerTest::HandleRequest,
base::Unretained(this),
@@ -200,6 +241,7 @@ TEST_F(EmbeddedTestServerTest, RegisterRequestHandler) {
"<b>Worked!</b>",
"text/html",
HTTP_OK));
+ ASSERT_TRUE(server_->Start());
scoped_ptr<URLFetcher> fetcher =
URLFetcher::Create(server_->GetURL("/test?q=foo"), URLFetcher::GET, this);
@@ -215,11 +257,12 @@ TEST_F(EmbeddedTestServerTest, RegisterRequestHandler) {
EXPECT_EQ("/test?q=foo", request_relative_url_);
}
-TEST_F(EmbeddedTestServerTest, ServeFilesFromDirectory) {
+TEST_P(EmbeddedTestServerTest, ServeFilesFromDirectory) {
base::FilePath src_dir;
ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
server_->ServeFilesFromDirectory(
src_dir.AppendASCII("net").AppendASCII("data"));
+ ASSERT_TRUE(server_->Start());
scoped_ptr<URLFetcher> fetcher =
URLFetcher::Create(server_->GetURL("/test.html"), URLFetcher::GET, this);
@@ -230,10 +273,12 @@ TEST_F(EmbeddedTestServerTest, ServeFilesFromDirectory) {
EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
EXPECT_EQ(HTTP_OK, fetcher->GetResponseCode());
EXPECT_EQ("<p>Hello World!</p>", GetContentFromFetcher(*fetcher));
- EXPECT_EQ("", GetContentTypeFromFetcher(*fetcher));
+ EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher));
}
-TEST_F(EmbeddedTestServerTest, DefaultNotFoundResponse) {
+TEST_P(EmbeddedTestServerTest, DefaultNotFoundResponse) {
+ ASSERT_TRUE(server_->Start());
+
scoped_ptr<URLFetcher> fetcher = URLFetcher::Create(
server_->GetURL("/non-existent"), URLFetcher::GET, this);
fetcher->SetRequestContext(request_context_getter_.get());
@@ -244,7 +289,9 @@ TEST_F(EmbeddedTestServerTest, DefaultNotFoundResponse) {
EXPECT_EQ(HTTP_NOT_FOUND, fetcher->GetResponseCode());
}
-TEST_F(EmbeddedTestServerTest, ConnectionListenerAccept) {
+TEST_P(EmbeddedTestServerTest, ConnectionListenerAccept) {
+ ASSERT_TRUE(server_->Start());
+
TestNetLog net_log;
net::AddressList address_list;
EXPECT_TRUE(server_->GetAddressList(&address_list));
@@ -261,7 +308,9 @@ TEST_F(EmbeddedTestServerTest, ConnectionListenerAccept) {
EXPECT_FALSE(connection_listener_.DidReadFromSocket());
}
-TEST_F(EmbeddedTestServerTest, ConnectionListenerRead) {
+TEST_P(EmbeddedTestServerTest, ConnectionListenerRead) {
+ ASSERT_TRUE(server_->Start());
+
scoped_ptr<URLFetcher> fetcher = URLFetcher::Create(
server_->GetURL("/non-existent"), URLFetcher::GET, this);
fetcher->SetRequestContext(request_context_getter_.get());
@@ -272,7 +321,7 @@ TEST_F(EmbeddedTestServerTest, ConnectionListenerRead) {
EXPECT_TRUE(connection_listener_.DidReadFromSocket());
}
-TEST_F(EmbeddedTestServerTest, ConcurrentFetches) {
+TEST_P(EmbeddedTestServerTest, ConcurrentFetches) {
server_->RegisterRequestHandler(
base::Bind(&EmbeddedTestServerTest::HandleRequest,
base::Unretained(this),
@@ -294,6 +343,7 @@ TEST_F(EmbeddedTestServerTest, ConcurrentFetches) {
"No chocolates",
"text/plain",
HTTP_NOT_FOUND));
+ ASSERT_TRUE(server_->Start());
scoped_ptr<URLFetcher> fetcher1 =
URLFetcher::Create(server_->GetURL("/test1"), URLFetcher::GET, this);
@@ -327,14 +377,141 @@ TEST_F(EmbeddedTestServerTest, ConcurrentFetches) {
EXPECT_EQ("text/plain", GetContentTypeFromFetcher(*fetcher3));
}
+namespace {
+
+class CancelRequestDelegate : public TestDelegate {
+ public:
+ CancelRequestDelegate() {}
+ ~CancelRequestDelegate() override {}
+
+ void OnResponseStarted(URLRequest* request) override {
+ TestDelegate::OnResponseStarted(request);
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop_.QuitClosure(), base::TimeDelta::FromSeconds(1));
+ }
+
+ void WaitUntilDone() { run_loop_.Run(); }
+
+ private:
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(CancelRequestDelegate);
+};
+
+class InfiniteResponse : public BasicHttpResponse {
+ public:
+ InfiniteResponse() : weak_ptr_factory_(this) {}
+
+ void SendResponse(const SendBytesCallback& send,
+ const SendCompleteCallback& done) override {
+ send.Run(ToResponseString(),
+ base::Bind(&InfiniteResponse::SendInfinite,
+ weak_ptr_factory_.GetWeakPtr(), send));
+ }
+
+ private:
+ void SendInfinite(const SendBytesCallback& send) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(send, "echo",
+ base::Bind(&InfiniteResponse::SendInfinite,
+ weak_ptr_factory_.GetWeakPtr(), send)));
+ }
+
+ base::WeakPtrFactory<InfiniteResponse> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(InfiniteResponse);
+};
+
+scoped_ptr<HttpResponse> HandleInfiniteRequest(const HttpRequest& request) {
+ return make_scoped_ptr(new InfiniteResponse);
+}
+}
+
+// Tests the case the connection is closed while the server is sending a
+// response. May non-deterministically end up at one of three paths
+// (Discover the close event synchronously, asynchronously, or server
+// shutting down before it is discovered).
+TEST_P(EmbeddedTestServerTest, CloseDuringWrite) {
+ CancelRequestDelegate cancel_delegate;
+ TestURLRequestContext context;
+ cancel_delegate.set_cancel_in_response_started(true);
+ server_->RegisterRequestHandler(base::Bind(
+ &HandlePrefixedRequest, "/infinite", base::Bind(&HandleInfiniteRequest)));
+ ASSERT_TRUE(server_->Start());
+
+ scoped_ptr<URLRequest> request = context.CreateRequest(
+ server_->GetURL("/infinite"), DEFAULT_PRIORITY, &cancel_delegate);
+ request->Start();
+ cancel_delegate.WaitUntilDone();
+}
+
+struct CertificateValuesEntry {
+ const EmbeddedTestServer::ServerCertificate server_cert;
+ const bool is_expired;
+ const char* common_name;
+ const char* root;
+};
+
+const CertificateValuesEntry kCertificateValuesEntry[] = {
+ {EmbeddedTestServer::CERT_OK, false, "127.0.0.1", "Test Root CA"},
+ {EmbeddedTestServer::CERT_MISMATCHED_NAME, false, "127.0.0.1",
+ "Test Root CA"},
+ {EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN, false, "localhost",
+ "Test Root CA"},
+ {EmbeddedTestServer::CERT_EXPIRED, true, "127.0.0.1", "Test Root CA"},
+ {EmbeddedTestServer::CERT_CHAIN_WRONG_ROOT, false, "127.0.0.1", "B CA"},
+#if !defined(OS_WIN)
+ {EmbeddedTestServer::CERT_BAD_VALIDITY, true, "Leaf Certificate",
+ "Test Root CA"},
+#endif
+};
+
+TEST_P(EmbeddedTestServerTest, GetCertificate) {
+ if (GetParam() != EmbeddedTestServer::TYPE_HTTPS)
+ return;
+
+ for (const auto& certEntry : kCertificateValuesEntry) {
+ server_->SetSSLConfig(certEntry.server_cert);
+ scoped_refptr<X509Certificate> cert = server_->GetCertificate();
+ DCHECK(cert.get());
+ EXPECT_EQ(cert->HasExpired(), certEntry.is_expired);
+ EXPECT_EQ(cert->subject().common_name, certEntry.common_name);
+ EXPECT_EQ(cert->issuer().common_name, certEntry.root);
+ }
+}
+
+INSTANTIATE_TEST_CASE_P(EmbeddedTestServerTestInstantiation,
+ EmbeddedTestServerTest,
+ testing::Values(EmbeddedTestServer::TYPE_HTTP,
+ EmbeddedTestServer::TYPE_HTTPS));
+
// Below test exercises EmbeddedTestServer's ability to cope with the situation
// where there is no MessageLoop available on the thread at EmbeddedTestServer
// initialization and/or destruction.
-typedef std::tr1::tuple<bool, bool> ThreadingTestParams;
+typedef std::tr1::tuple<bool, bool, EmbeddedTestServer::Type>
+ ThreadingTestParams;
class EmbeddedTestServerThreadingTest
- : public testing::TestWithParam<ThreadingTestParams> {};
+ : public testing::TestWithParam<ThreadingTestParams> {
+ void SetUp() override {
+#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+ // 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) || defined(OS_IOS)
+ ShutdownNSSHttpIO();
+#endif
+ }
+};
class EmbeddedTestServerThreadingTestDelegate
: public base::PlatformThread::Delegate,
@@ -342,9 +519,11 @@ class EmbeddedTestServerThreadingTestDelegate
public:
EmbeddedTestServerThreadingTestDelegate(
bool message_loop_present_on_initialize,
- bool message_loop_present_on_shutdown)
+ bool message_loop_present_on_shutdown,
+ EmbeddedTestServer::Type type)
: message_loop_present_on_initialize_(message_loop_present_on_initialize),
- message_loop_present_on_shutdown_(message_loop_present_on_shutdown) {}
+ message_loop_present_on_shutdown_(message_loop_present_on_shutdown),
+ type_(type) {}
// base::PlatformThread::Delegate:
void ThreadMain() override {
@@ -360,10 +539,10 @@ class EmbeddedTestServerThreadingTestDelegate
loop.reset(new base::MessageLoopForIO);
// Create the test server instance.
- EmbeddedTestServer server;
+ EmbeddedTestServer server(type_);
base::FilePath src_dir;
ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
- ASSERT_TRUE(server.InitializeAndWaitUntilReady());
+ ASSERT_TRUE(server.Start());
// Make a request and wait for the reply.
if (!loop)
@@ -386,12 +565,13 @@ class EmbeddedTestServerThreadingTestDelegate
// URLFetcherDelegate override.
void OnURLFetchComplete(const URLFetcher* source) override {
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
private:
- bool message_loop_present_on_initialize_;
- bool message_loop_present_on_shutdown_;
+ const bool message_loop_present_on_initialize_;
+ const bool message_loop_present_on_shutdown_;
+ const EmbeddedTestServer::Type type_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServerThreadingTestDelegate);
};
@@ -402,15 +582,19 @@ TEST_P(EmbeddedTestServerThreadingTest, RunTest) {
// main test thread.
base::PlatformThreadHandle thread_handle;
EmbeddedTestServerThreadingTestDelegate delegate(
- std::tr1::get<0>(GetParam()),
- std::tr1::get<1>(GetParam()));
+ std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()),
+ std::tr1::get<2>(GetParam()));
ASSERT_TRUE(base::PlatformThread::Create(0, &delegate, &thread_handle));
base::PlatformThread::Join(thread_handle);
}
-INSTANTIATE_TEST_CASE_P(EmbeddedTestServerThreadingTestInstantiation,
- EmbeddedTestServerThreadingTest,
- testing::Combine(testing::Bool(), testing::Bool()));
+INSTANTIATE_TEST_CASE_P(
+ EmbeddedTestServerThreadingTestInstantiation,
+ EmbeddedTestServerThreadingTest,
+ testing::Combine(testing::Bool(),
+ testing::Bool(),
+ testing::Values(EmbeddedTestServer::TYPE_HTTP,
+ EmbeddedTestServer::TYPE_HTTPS)));
} // namespace test_server
} // namespace net
diff --git a/chromium/net/test/embedded_test_server/http_connection.cc b/chromium/net/test/embedded_test_server/http_connection.cc
index 0e94756301d..ce95f4362d2 100644
--- a/chromium/net/test/embedded_test_server/http_connection.cc
+++ b/chromium/net/test/embedded_test_server/http_connection.cc
@@ -4,31 +4,82 @@
#include "net/test/embedded_test_server/http_connection.h"
-#include "net/test/embedded_test_server/http_response.h"
-#include "net/test/embedded_test_server/stream_listen_socket.h"
+#include <utility>
+
+#include "net/base/net_errors.h"
+#include "net/socket/stream_socket.h"
namespace net {
namespace test_server {
-HttpConnection::HttpConnection(scoped_ptr<StreamListenSocket> socket,
+HttpConnection::HttpConnection(scoped_ptr<StreamSocket> socket,
const HandleRequestCallback& callback)
- : socket_(socket.Pass()),
- callback_(callback) {
-}
+ : socket_(std::move(socket)),
+ callback_(callback),
+ read_buf_(new IOBufferWithSize(4096)),
+ weak_factory_(this) {}
HttpConnection::~HttpConnection() {
+ weak_factory_.InvalidateWeakPtrs();
+}
+
+void HttpConnection::SendResponseBytes(const std::string& response_string,
+ const SendCompleteCallback& callback) {
+ if (response_string.length() > 0) {
+ scoped_refptr<DrainableIOBuffer> write_buf(new DrainableIOBuffer(
+ new StringIOBuffer(response_string), response_string.length()));
+
+ SendInternal(callback, write_buf);
+ } else {
+ callback.Run();
+ }
}
-void HttpConnection::SendResponse(scoped_ptr<HttpResponse> response) const {
- const std::string response_string = response->ToResponseString();
- socket_->Send(response_string.c_str(), response_string.length());
+int HttpConnection::ReadData(const CompletionCallback& callback) {
+ return socket_->Read(read_buf_.get(), read_buf_->size(), callback);
}
-void HttpConnection::ReceiveData(const base::StringPiece& data) {
- request_parser_.ProcessChunk(data);
+bool HttpConnection::ConsumeData(int size) {
+ request_parser_.ProcessChunk(base::StringPiece(read_buf_->data(), size));
if (request_parser_.ParseRequest() == HttpRequestParser::ACCEPTED) {
callback_.Run(this, request_parser_.GetRequest());
+ return true;
+ }
+ return false;
+}
+
+void HttpConnection::SendInternal(const base::Closure& callback,
+ scoped_refptr<DrainableIOBuffer> buf) {
+ while (buf->BytesRemaining() > 0) {
+ int rv = socket_->Write(buf.get(), buf->BytesRemaining(),
+ base::Bind(&HttpConnection::OnSendInternalDone,
+ base::Unretained(this), callback, buf));
+ if (rv == ERR_IO_PENDING)
+ return;
+
+ if (rv < 0)
+ break;
+ buf->DidConsume(rv);
+ }
+
+ // The HttpConnection will be deleted by the callback since we only need to
+ // serve a single request.
+ callback.Run();
+}
+
+void HttpConnection::OnSendInternalDone(const base::Closure& callback,
+ scoped_refptr<DrainableIOBuffer> buf,
+ int rv) {
+ if (rv < 0) {
+ callback.Run();
+ return;
}
+ buf->DidConsume(rv);
+ SendInternal(callback, buf);
+}
+
+base::WeakPtr<HttpConnection> HttpConnection::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
}
} // namespace test_server
diff --git a/chromium/net/test/embedded_test_server/http_connection.h b/chromium/net/test/embedded_test_server/http_connection.h
index 121f8bef369..4f4e555f959 100644
--- a/chromium/net/test/embedded_test_server/http_connection.h
+++ b/chromium/net/test/embedded_test_server/http_connection.h
@@ -5,18 +5,25 @@
#ifndef NET_TEST_EMBEDDED_TEST_SERVER_HTTP_CONNECTION_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_HTTP_CONNECTION_H_
-#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece.h"
+#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
namespace net {
+class StreamSocket;
+
namespace test_server {
class HttpConnection;
class HttpResponse;
-class StreamListenSocket;
// Calblack called when a request is parsed. Response should be sent
// using HttpConnection::SendResponse() on the |connection| argument.
@@ -28,24 +35,38 @@ typedef base::Callback<void(HttpConnection* connection,
// If a valid request is parsed, then |callback_| is invoked.
class HttpConnection {
public:
- HttpConnection(scoped_ptr<StreamListenSocket> socket,
+ HttpConnection(scoped_ptr<StreamSocket> socket,
const HandleRequestCallback& callback);
~HttpConnection();
- // Sends the HTTP response to the client.
- void SendResponse(scoped_ptr<HttpResponse> response) const;
-
- private:
- friend class EmbeddedTestServer;
+ // Sends the |response_string| to the client and calls |callback| once done.
+ void SendResponseBytes(const std::string& response_string,
+ const SendCompleteCallback& callback);
// Accepts raw chunk of data from the client. Internally, passes it to the
// HttpRequestParser class. If a request is parsed, then |callback_| is
// called.
- void ReceiveData(const base::StringPiece& data);
+ int ReadData(const CompletionCallback& callback);
+
+ bool ConsumeData(int size);
- scoped_ptr<StreamListenSocket> socket_;
+ private:
+ friend class EmbeddedTestServer;
+
+ void SendInternal(const base::Closure& callback,
+ scoped_refptr<DrainableIOBuffer> buffer);
+ void OnSendInternalDone(const base::Closure& callback,
+ scoped_refptr<DrainableIOBuffer> buffer,
+ int rv);
+
+ base::WeakPtr<HttpConnection> GetWeakPtr();
+
+ scoped_ptr<StreamSocket> socket_;
const HandleRequestCallback callback_;
HttpRequestParser request_parser_;
+ scoped_refptr<IOBufferWithSize> read_buf_;
+
+ base::WeakPtrFactory<HttpConnection> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(HttpConnection);
};
diff --git a/chromium/net/test/embedded_test_server/http_request.cc b/chromium/net/test/embedded_test_server/http_request.cc
index 9e0c80f96fa..b5b2e4f372d 100644
--- a/chromium/net/test/embedded_test_server/http_request.cc
+++ b/chromium/net/test/embedded_test_server/http_request.cc
@@ -5,12 +5,14 @@
#include "net/test/embedded_test_server/http_request.h"
#include <algorithm>
+#include <utility>
#include "base/logging.h"
-#include "base/strings/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "net/http/http_chunked_decoder.h"
+#include "url/gurl.h"
namespace net {
namespace test_server {
@@ -35,6 +37,11 @@ HttpRequest::HttpRequest() : method(METHOD_UNKNOWN),
HttpRequest::~HttpRequest() {
}
+GURL HttpRequest::GetURL() const {
+ // TODO(svaldez): Use real URL from the EmbeddedTestServer.
+ return GURL("http://localhost" + relative_url);
+}
+
HttpRequestParser::HttpRequestParser()
: http_request_(new HttpRequest()),
buffer_position_(0),
@@ -98,7 +105,15 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() {
// Address.
// Don't build an absolute URL as the parser does not know (should not
// know) anything about the server address.
- http_request_->relative_url = header_line_tokens[1];
+ GURL url(header_line_tokens[1]);
+ if (url.is_valid()) {
+ http_request_->relative_url = url.path();
+ } else if (header_line_tokens[1][0] == '/') {
+ http_request_->relative_url = header_line_tokens[1];
+ } else {
+ http_request_->relative_url = "/" + header_line_tokens[1];
+ }
+
// Protocol.
const std::string protocol = base::ToLowerASCII(header_line_tokens[2]);
CHECK(protocol == "http/1.0" || protocol == "http/1.1") <<
@@ -139,7 +154,10 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() {
const bool success = base::StringToSizeT(
http_request_->headers["Content-Length"],
&declared_content_length_);
- DCHECK(success) << "Malformed Content-Length header's value.";
+ if (!success) {
+ declared_content_length_ = 0;
+ LOG(WARNING) << "Malformed Content-Length header's value.";
+ }
} else if (http_request_->headers.count("Transfer-Encoding") > 0) {
if (http_request_->headers["Transfer-Encoding"] == "chunked") {
http_request_->has_content = true;
@@ -199,7 +217,7 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseContent() {
scoped_ptr<HttpRequest> HttpRequestParser::GetRequest() {
DCHECK_EQ(STATE_ACCEPTED, state_);
- scoped_ptr<HttpRequest> result = http_request_.Pass();
+ scoped_ptr<HttpRequest> result = std::move(http_request_);
// Prepare for parsing a new request.
state_ = STATE_HEADERS;
@@ -208,7 +226,7 @@ scoped_ptr<HttpRequest> HttpRequestParser::GetRequest() {
buffer_position_ = 0;
declared_content_length_ = 0;
- return result.Pass();
+ return result;
}
HttpMethod HttpRequestParser::GetMethodType(const std::string& token) const {
@@ -224,9 +242,11 @@ HttpMethod HttpRequestParser::GetMethodType(const std::string& token) const {
return METHOD_DELETE;
} else if (token == "patch") {
return METHOD_PATCH;
+ } else if (token == "connect") {
+ return METHOD_CONNECT;
}
- NOTREACHED() << "Method not implemented: " << token;
- return METHOD_UNKNOWN;
+ LOG(WARNING) << "Method not implemented: " << token;
+ return METHOD_GET;
}
} // namespace test_server
diff --git a/chromium/net/test/embedded_test_server/http_request.h b/chromium/net/test/embedded_test_server/http_request.h
index c2993785664..d99c0500267 100644
--- a/chromium/net/test/embedded_test_server/http_request.h
+++ b/chromium/net/test/embedded_test_server/http_request.h
@@ -5,12 +5,16 @@
#ifndef NET_TEST_EMBEDDED_TEST_SERVER_HTTP_REQUEST_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_HTTP_REQUEST_H_
+#include <stddef.h>
+
#include <map>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "url/gurl.h"
namespace net {
@@ -27,20 +31,34 @@ enum HttpMethod {
METHOD_PUT,
METHOD_DELETE,
METHOD_PATCH,
+ METHOD_CONNECT,
};
// Represents a HTTP request. Since it can be big, use scoped_ptr to pass it
// instead of copying. However, the struct is copyable so tests can save and
// examine a HTTP request.
struct HttpRequest {
+ struct CaseInsensitiveStringComparator {
+ bool operator()(const std::string& left, const std::string& right) const {
+ return base::CompareCaseInsensitiveASCII(left, right) < 0;
+ }
+ };
+
+ using HeaderMap =
+ std::map<std::string, std::string, CaseInsensitiveStringComparator>;
+
HttpRequest();
~HttpRequest();
+ // Returns a GURL as a convenience to extract the path and query strings.
+ // TODO(svaldez): Use provided URL if available.
+ GURL GetURL() const;
+
std::string relative_url; // Starts with '/'. Example: "/test?query=foo"
HttpMethod method;
std::string method_string;
std::string all_headers;
- std::map<std::string, std::string> headers;
+ HeaderMap headers;
std::string content;
bool has_content;
};
diff --git a/chromium/net/test/embedded_test_server/http_response.cc b/chromium/net/test/embedded_test_server/http_response.cc
index 04155b5ffa5..51e75610a9d 100644
--- a/chromium/net/test/embedded_test_server/http_response.cc
+++ b/chromium/net/test/embedded_test_server/http_response.cc
@@ -15,6 +15,26 @@ namespace test_server {
HttpResponse::~HttpResponse() {
}
+RawHttpResponse::RawHttpResponse(const std::string& headers,
+ const std::string& contents)
+ : headers_(headers), contents_(contents) {}
+
+RawHttpResponse::~RawHttpResponse() {}
+
+void RawHttpResponse::SendResponse(const SendBytesCallback& send,
+ const SendCompleteCallback& done) {
+ std::string response;
+ if (!headers_.empty())
+ response = headers_ + "\r\n" + contents_;
+ else
+ response = contents_;
+ send.Run(response, done);
+}
+
+void RawHttpResponse::AddHeader(const std::string& key_value_pair) {
+ headers_.append(base::StringPrintf("%s\r\n", key_value_pair.c_str()));
+}
+
BasicHttpResponse::BasicHttpResponse() : code_(HTTP_OK) {
}
@@ -33,11 +53,10 @@ std::string BasicHttpResponse::ToResponseString() const {
code_,
http_reason_phrase.c_str());
base::StringAppendF(&response_builder, "Connection: close\r\n");
- base::StringAppendF(&response_builder,
- "Content-Length: %" PRIuS "\r\n",
+
+ base::StringAppendF(&response_builder, "Content-Length: %" PRIuS "\r\n",
content_.size());
- base::StringAppendF(&response_builder,
- "Content-Type: %s\r\n",
+ base::StringAppendF(&response_builder, "Content-Type: %s\r\n",
content_type_.c_str());
for (size_t i = 0; i < custom_headers_.size(); ++i) {
const std::string& header_name = custom_headers_[i].first;
@@ -54,5 +73,10 @@ std::string BasicHttpResponse::ToResponseString() const {
return response_builder + content_;
}
+void BasicHttpResponse::SendResponse(const SendBytesCallback& send,
+ const SendCompleteCallback& done) {
+ send.Run(ToResponseString(), done);
+}
+
} // namespace test_server
} // namespace net
diff --git a/chromium/net/test/embedded_test_server/http_response.h b/chromium/net/test/embedded_test_server/http_response.h
index d4df75b5b85..caca4bf1fcb 100644
--- a/chromium/net/test/embedded_test_server/http_response.h
+++ b/chromium/net/test/embedded_test_server/http_response.h
@@ -5,30 +5,41 @@
#ifndef NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
-#include <map>
#include <string>
-#include "base/basictypes.h"
+#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/strings/string_split.h"
#include "net/http/http_status_code.h"
namespace net {
namespace test_server {
+// Callback called when the response is done being sent.
+using SendCompleteCallback = base::Callback<void(void)>;
+
+// Callback called when the response is ready to be sent that takes the
+// |response| that is being sent along with the callback |write_done| that is
+// called when the response has been fully written.
+using SendBytesCallback =
+ base::Callback<void(const std::string& response,
+ const SendCompleteCallback& write_done)>;
+
// Interface for HTTP response implementations.
class HttpResponse{
public:
virtual ~HttpResponse();
- // Returns raw contents to be written to the network socket
- // in response. If you intend to make this a valid HTTP response,
- // it should start with "HTTP/x.x" line, followed by response headers.
- virtual std::string ToResponseString() const = 0;
+ // |send| will send the specified data to the network socket, and invoke
+ // |write_done| when complete. When the entire response has been sent,
+ // |done| must be called.
+ virtual void SendResponse(const SendBytesCallback& send,
+ const SendCompleteCallback& done) = 0;
};
// This class is used to handle basic HTTP responses with commonly used
-// response headers such as "Content-Type".
+// response headers such as "Content-Type". Sends the response immediately.
class BasicHttpResponse : public HttpResponse {
public:
BasicHttpResponse();
@@ -54,7 +65,10 @@ class BasicHttpResponse : public HttpResponse {
}
// Generates and returns a http response string.
- std::string ToResponseString() const override;
+ std::string ToResponseString() const;
+
+ void SendResponse(const SendBytesCallback& send,
+ const SendCompleteCallback& done) override;
private:
HttpStatusCode code_;
@@ -65,6 +79,23 @@ class BasicHttpResponse : public HttpResponse {
DISALLOW_COPY_AND_ASSIGN(BasicHttpResponse);
};
+class RawHttpResponse : public HttpResponse {
+ public:
+ RawHttpResponse(const std::string& headers, const std::string& contents);
+ ~RawHttpResponse() override;
+
+ void SendResponse(const SendBytesCallback& send,
+ const SendCompleteCallback& done) override;
+
+ void AddHeader(const std::string& key_value_pair);
+
+ private:
+ std::string headers_;
+ const std::string contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(RawHttpResponse);
+};
+
} // namespace test_server
} // namespace net
diff --git a/chromium/net/test/embedded_test_server/request_handler_util.cc b/chromium/net/test/embedded_test_server/request_handler_util.cc
new file mode 100644
index 00000000000..ab3e975e2e4
--- /dev/null
+++ b/chromium/net/test/embedded_test_server/request_handler_util.cc
@@ -0,0 +1,229 @@
+// Copyright 2015 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/embedded_test_server/request_handler_util.h"
+
+#include <stdlib.h>
+#include <ctime>
+#include <sstream>
+#include <utility>
+
+#include "base/base64.h"
+#include "base/files/file_util.h"
+#include "base/format_macros.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/threading/thread_restrictions.h"
+#include "net/base/escape.h"
+#include "net/base/url_util.h"
+#include "net/http/http_byte_range.h"
+#include "net/http/http_util.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "url/gurl.h"
+
+namespace net {
+namespace test_server {
+namespace {
+
+const UnescapeRule::Type kUnescapeAll =
+ UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS |
+ UnescapeRule::SPOOFING_AND_CONTROL_CHARS |
+ UnescapeRule::REPLACE_PLUS_WITH_SPACE;
+
+std::string GetContentType(const base::FilePath& path) {
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".crx")))
+ return "application/x-chrome-extension";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".exe")))
+ return "application/octet-stream";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".gif")))
+ return "image/gif";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".jpeg")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".jpg"))) {
+ return "image/jpeg";
+ }
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".js")))
+ return "application/javascript";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".json")))
+ return "application/json";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")))
+ return "application/pdf";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".txt")))
+ return "text/plain";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".wav")))
+ return "audio/wav";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".xml")))
+ return "text/xml";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".html")) ||
+ path.MatchesExtension(FILE_PATH_LITERAL(".htm"))) {
+ return "text/html";
+ }
+ return "";
+}
+
+} // namespace
+
+bool ShouldHandle(const HttpRequest& request, const std::string& path_prefix) {
+ GURL url = request.GetURL();
+ return url.path() == path_prefix ||
+ base::StartsWith(url.path(), path_prefix + "/",
+ base::CompareCase::SENSITIVE);
+}
+
+scoped_ptr<HttpResponse> HandlePrefixedRequest(
+ const std::string& prefix,
+ const EmbeddedTestServer::HandleRequestCallback& handler,
+ const HttpRequest& request) {
+ if (ShouldHandle(request, prefix))
+ return handler.Run(request);
+ return nullptr;
+}
+
+RequestQuery ParseQuery(const GURL& url) {
+ RequestQuery queries;
+ for (QueryIterator it(url); !it.IsAtEnd(); it.Advance()) {
+ queries[net::UnescapeURLComponent(it.GetKey(), kUnescapeAll)].push_back(
+ it.GetUnescapedValue());
+ }
+ return queries;
+}
+
+void GetFilePathWithReplacements(const std::string& original_file_path,
+ const base::StringPairs& text_to_replace,
+ std::string* replacement_path) {
+ std::string new_file_path = original_file_path;
+ for (const auto& replacement : text_to_replace) {
+ const std::string& old_text = replacement.first;
+ const std::string& new_text = replacement.second;
+ std::string base64_old;
+ std::string base64_new;
+ base::Base64Encode(old_text, &base64_old);
+ base::Base64Encode(new_text, &base64_new);
+ if (new_file_path == original_file_path)
+ new_file_path += "?";
+ else
+ new_file_path += "&";
+ new_file_path += "replace_text=";
+ new_file_path += base64_old;
+ new_file_path += ":";
+ new_file_path += base64_new;
+ }
+
+ *replacement_path = new_file_path;
+}
+
+// Handles |request| by serving a file from under |server_root|.
+scoped_ptr<HttpResponse> HandleFileRequest(const base::FilePath& server_root,
+ const HttpRequest& request) {
+ // This is a test-only server. Ignore I/O thread restrictions.
+ // TODO(svaldez): Figure out why thread is I/O restricted in the first place.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+ // A proxy request will have an absolute path. Simulate the proxy by stripping
+ // the scheme, host, and port.
+ GURL request_url = request.GetURL();
+ std::string relative_path(request_url.path());
+
+ std::string post_prefix("/post/");
+ if (base::StartsWith(relative_path, post_prefix,
+ base::CompareCase::SENSITIVE)) {
+ if (request.method != METHOD_POST)
+ return nullptr;
+ relative_path = relative_path.substr(post_prefix.size() - 1);
+ }
+
+ RequestQuery query = ParseQuery(request_url);
+
+ scoped_ptr<BasicHttpResponse> failed_response(new BasicHttpResponse);
+ failed_response->set_code(HTTP_NOT_FOUND);
+
+ if (query.find("expected_body") != query.end()) {
+ if (request.content.find(query["expected_body"].front()) ==
+ std::string::npos) {
+ return std::move(failed_response);
+ }
+ }
+
+ if (query.find("expected_headers") != query.end()) {
+ for (const auto& header : query["expected_headers"]) {
+ if (header.find(":") == std::string::npos)
+ return std::move(failed_response);
+ std::string key = header.substr(0, header.find(":"));
+ std::string value = header.substr(header.find(":") + 1);
+ if (request.headers.find(key) == request.headers.end() ||
+ request.headers.at(key) != value) {
+ return std::move(failed_response);
+ }
+ }
+ }
+
+ // Trim the first byte ('/').
+ DCHECK(base::StartsWith(relative_path, "/", base::CompareCase::SENSITIVE));
+ std::string request_path = relative_path.substr(1);
+ base::FilePath file_path(server_root.AppendASCII(request_path));
+ std::string file_contents;
+ if (!base::ReadFileToString(file_path, &file_contents)) {
+ file_path = file_path.AppendASCII("index.html");
+ if (!base::ReadFileToString(file_path, &file_contents))
+ return nullptr;
+ }
+
+ if (request.method == METHOD_HEAD)
+ file_contents = "";
+
+ if (query.find("replace_text") != query.end()) {
+ for (const auto& replacement : query["replace_text"]) {
+ if (replacement.find(":") == std::string::npos)
+ return std::move(failed_response);
+ std::string find;
+ std::string with;
+ base::Base64Decode(replacement.substr(0, replacement.find(":")), &find);
+ base::Base64Decode(replacement.substr(replacement.find(":") + 1), &with);
+ base::ReplaceSubstringsAfterOffset(&file_contents, 0, find, with);
+ }
+ }
+
+ base::FilePath headers_path(
+ file_path.AddExtension(FILE_PATH_LITERAL("mock-http-headers")));
+
+ if (base::PathExists(headers_path)) {
+ std::string headers_contents;
+
+ if (!base::ReadFileToString(headers_path, &headers_contents))
+ return nullptr;
+
+ return make_scoped_ptr(
+ new RawHttpResponse(headers_contents, file_contents));
+ }
+
+ scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
+ http_response->set_code(HTTP_OK);
+
+ if (request.headers.find("Range") != request.headers.end()) {
+ std::vector<HttpByteRange> ranges;
+
+ if (HttpUtil::ParseRangeHeader(request.headers.at("Range"), &ranges) &&
+ ranges.size() == 1) {
+ ranges[0].ComputeBounds(file_contents.size());
+ size_t start = ranges[0].first_byte_position();
+ size_t end = ranges[0].last_byte_position();
+
+ http_response->set_code(HTTP_PARTIAL_CONTENT);
+ http_response->AddCustomHeader(
+ "Content-Range",
+ base::StringPrintf("bytes %" PRIuS "-%" PRIuS "/%" PRIuS, start, end,
+ file_contents.size()));
+
+ file_contents = file_contents.substr(start, end - start + 1);
+ }
+ }
+
+ http_response->set_content_type(GetContentType(file_path));
+ http_response->AddCustomHeader("Accept-Ranges", "bytes");
+ http_response->AddCustomHeader("ETag", "'" + file_path.MaybeAsASCII() + "'");
+ http_response->set_content(file_contents);
+ return std::move(http_response);
+}
+
+} // namespace test_server
+} // namespace net
diff --git a/chromium/net/test/embedded_test_server/request_handler_util.h b/chromium/net/test/embedded_test_server/request_handler_util.h
new file mode 100644
index 00000000000..2ed8d1383b4
--- /dev/null
+++ b/chromium/net/test/embedded_test_server/request_handler_util.h
@@ -0,0 +1,63 @@
+// Copyright 2015 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_EMBEDDED_TEST_SERVER_REQUEST_HANDLER_UTIL_H_
+#define NET_TEST_EMBEDDED_TEST_SERVER_REQUEST_HANDLER_UTIL_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_split.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_response.h"
+
+namespace url {
+class GURL;
+}
+
+namespace net {
+namespace test_server {
+struct HttpRequest;
+
+// This file is only meant for compatibility with testserver.py. No
+// additional handlers should be added here that don't affect multiple
+// distinct tests.
+
+using RequestQuery = std::map<std::string, std::vector<std::string>>;
+
+// Return whether |request| starts with a URL path of |url|.
+bool ShouldHandle(const HttpRequest& request, const std::string& prefix_path);
+
+// Calls |handler| if the |request| URL starts with |prefix|.
+scoped_ptr<HttpResponse> HandlePrefixedRequest(
+ const std::string& prefix,
+ const EmbeddedTestServer::HandleRequestCallback& handler,
+ const HttpRequest& request);
+
+// Parses |url| to get the query and places it into a map.
+RequestQuery ParseQuery(const GURL& url);
+
+// Returns a path that serves the contents of the file at |original_path|
+// with all the text matching the elements of |text_to_replace| replaced
+// with the corresponding values. The path is returned in |replacement_path|.
+// The result path is only usable by HandleFileRequest which will perform the
+// actual replacements of the file contents.
+// TODO(svaldez): Modify to return |replacement_path| instead of passing by
+// reference.
+void GetFilePathWithReplacements(const std::string& original_path,
+ const base::StringPairs& text_to_replace,
+ std::string* replacement_path);
+
+// Handles |request| by serving a file from under |server_root|.
+scoped_ptr<HttpResponse> HandleFileRequest(const base::FilePath& server_root,
+ const HttpRequest& request);
+
+} // namespace test_server
+} // namespace net
+
+#endif // NET_TEST_EMBEDDED_TEST_SERVER_REQUEST_HANDLER_UTIL_H_
diff --git a/chromium/net/test/embedded_test_server/stream_listen_socket.cc b/chromium/net/test/embedded_test_server/stream_listen_socket.cc
deleted file mode 100644
index 897b23bbd56..00000000000
--- a/chromium/net/test/embedded_test_server/stream_listen_socket.cc
+++ /dev/null
@@ -1,330 +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/test/embedded_test_server/stream_listen_socket.h"
-
-#if defined(OS_WIN)
-// winsock2.h must be included first in order to ensure it is included before
-// windows.h.
-#include <winsock2.h>
-#elif defined(OS_POSIX)
-#include <arpa/inet.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include "net/base/net_errors.h"
-#endif
-
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/sys_byteorder.h"
-#include "base/threading/platform_thread.h"
-#include "build/build_config.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
-#include "net/socket/socket_descriptor.h"
-
-using std::string;
-
-#if defined(OS_WIN)
-typedef int socklen_t;
-#endif // defined(OS_WIN)
-
-namespace net {
-
-namespace test_server {
-
-namespace {
-
-const int kReadBufSize = 4096;
-
-} // namespace
-
-#if defined(OS_WIN)
-const int StreamListenSocket::kSocketError = SOCKET_ERROR;
-#elif defined(OS_POSIX)
-const int StreamListenSocket::kSocketError = -1;
-#endif
-
-StreamListenSocket::StreamListenSocket(SocketDescriptor s,
- StreamListenSocket::Delegate* del)
- : socket_delegate_(del),
- socket_(s),
- reads_paused_(false),
- has_pending_reads_(false) {
-#if defined(OS_WIN)
- socket_event_ = WSACreateEvent();
- // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT.
- WatchSocket(NOT_WAITING);
-#elif defined(OS_POSIX)
- wait_state_ = NOT_WAITING;
-#endif
-}
-
-StreamListenSocket::~StreamListenSocket() {
- CloseSocket();
-#if defined(OS_WIN)
- if (socket_event_) {
- WSACloseEvent(socket_event_);
- socket_event_ = WSA_INVALID_EVENT;
- }
-#endif
-}
-
-void StreamListenSocket::Send(const char* bytes,
- int len,
- bool append_linefeed) {
- SendInternal(bytes, len);
- if (append_linefeed)
- SendInternal("\r\n", 2);
-}
-
-void StreamListenSocket::Send(const string& str, bool append_linefeed) {
- Send(str.data(), static_cast<int>(str.length()), append_linefeed);
-}
-
-int StreamListenSocket::GetLocalAddress(IPEndPoint* address) const {
- SockaddrStorage storage;
- if (getsockname(socket_, storage.addr, &storage.addr_len)) {
-#if defined(OS_WIN)
- int err = WSAGetLastError();
-#else
- int err = errno;
-#endif
- return MapSystemError(err);
- }
- if (!address->FromSockAddr(storage.addr, storage.addr_len))
- return ERR_ADDRESS_INVALID;
- return OK;
-}
-
-int StreamListenSocket::GetPeerAddress(IPEndPoint* address) const {
- SockaddrStorage storage;
- if (getpeername(socket_, storage.addr, &storage.addr_len)) {
-#if defined(OS_WIN)
- int err = WSAGetLastError();
-#else
- int err = errno;
-#endif
- return MapSystemError(err);
- }
-
- if (!address->FromSockAddr(storage.addr, storage.addr_len))
- return ERR_ADDRESS_INVALID;
-
- return OK;
-}
-
-SocketDescriptor StreamListenSocket::AcceptSocket() {
- SocketDescriptor conn = HANDLE_EINTR(accept(socket_, NULL, NULL));
- if (conn == kInvalidSocket)
- LOG(ERROR) << "Error accepting connection.";
- else
- SetNonBlocking(conn);
- return conn;
-}
-
-void StreamListenSocket::SendInternal(const char* bytes, int len) {
- char* send_buf = const_cast<char*>(bytes);
- int len_left = len;
- while (true) {
- int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0));
- if (sent == len_left) { // A shortcut to avoid extraneous checks.
- break;
- }
- if (sent == kSocketError) {
-#if defined(OS_WIN)
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError();
-#elif defined(OS_POSIX)
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- LOG(ERROR) << "send failed: errno==" << errno;
-#endif
- break;
- }
- // Otherwise we would block, and now we have to wait for a retry.
- // Fall through to PlatformThread::YieldCurrentThread()
- } else {
- // sent != len_left according to the shortcut above.
- // Shift the buffer start and send the remainder after a short while.
- send_buf += sent;
- len_left -= sent;
- }
- base::PlatformThread::YieldCurrentThread();
- }
-}
-
-void StreamListenSocket::Listen() {
- int backlog = 10; // TODO(erikkay): maybe don't allow any backlog?
- if (listen(socket_, backlog) == -1) {
- // TODO(erikkay): error handling.
- LOG(ERROR) << "Could not listen on socket.";
- return;
- }
-#if defined(OS_POSIX)
- WatchSocket(WAITING_ACCEPT);
-#endif
-}
-
-void StreamListenSocket::Read() {
- char buf[kReadBufSize + 1]; // +1 for null termination.
- int len;
- do {
- len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0));
- if (len == kSocketError) {
-#if defined(OS_WIN)
- int err = WSAGetLastError();
- if (err == WSAEWOULDBLOCK) {
-#elif defined(OS_POSIX)
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
-#endif
- break;
- } else {
- // TODO(ibrar): some error handling required here.
- break;
- }
- } else if (len == 0) {
-#if defined(OS_POSIX)
- // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need
- // to call it here.
- Close();
-#endif
- } else {
- // TODO(ibrar): maybe change DidRead to take a length instead.
- DCHECK_GT(len, 0);
- DCHECK_LE(len, kReadBufSize);
- buf[len] = 0; // Already create a buffer with +1 length.
- socket_delegate_->DidRead(this, buf, len);
- }
- } while (len == kReadBufSize);
-}
-
-void StreamListenSocket::Close() {
-#if defined(OS_POSIX)
- if (wait_state_ == NOT_WAITING)
- return;
- wait_state_ = NOT_WAITING;
-#endif
- UnwatchSocket();
- socket_delegate_->DidClose(this);
-}
-
-void StreamListenSocket::CloseSocket() {
- if (socket_ != kInvalidSocket) {
- UnwatchSocket();
-#if defined(OS_WIN)
- closesocket(socket_);
-#elif defined(OS_POSIX)
- close(socket_);
-#endif
- }
-}
-
-void StreamListenSocket::WatchSocket(WaitState state) {
-#if defined(OS_WIN)
- WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ);
- watcher_.StartWatchingOnce(socket_event_, this);
-#elif defined(OS_POSIX)
- // Implicitly calls StartWatchingFileDescriptor().
- base::MessageLoopForIO::current()->WatchFileDescriptor(
- socket_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
- wait_state_ = state;
-#endif
-}
-
-void StreamListenSocket::UnwatchSocket() {
-#if defined(OS_WIN)
- watcher_.StopWatching();
-#elif defined(OS_POSIX)
- watcher_.StopWatchingFileDescriptor();
-#endif
-}
-
-// TODO(ibrar): We can add these functions into OS dependent files.
-#if defined(OS_WIN)
-// MessageLoop watcher callback.
-void StreamListenSocket::OnObjectSignaled(HANDLE object) {
- WSANETWORKEVENTS ev;
- if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) {
- // TODO
- return;
- }
-
- // If both FD_CLOSE and FD_READ are set we only call Read().
- // This will cause OnObjectSignaled to be called immediately again
- // unless this socket is destroyed in Read().
- if ((ev.lNetworkEvents & (FD_CLOSE | FD_READ)) == FD_CLOSE) {
- Close();
- // Close might have deleted this object. We should return immediately.
- return;
- }
- // The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
- watcher_.StartWatchingOnce(object, this);
-
- if (ev.lNetworkEvents == 0) {
- // Occasionally the event is set even though there is no new data.
- // The net seems to think that this is ignorable.
- return;
- }
- if (ev.lNetworkEvents & FD_ACCEPT) {
- Accept();
- }
- if (ev.lNetworkEvents & FD_READ) {
- if (reads_paused_) {
- has_pending_reads_ = true;
- } else {
- Read();
- // Read might have deleted this object. We should return immediately.
- }
- }
-}
-#elif defined(OS_POSIX)
-void StreamListenSocket::OnFileCanReadWithoutBlocking(int fd) {
- switch (wait_state_) {
- case WAITING_ACCEPT:
- Accept();
- break;
- case WAITING_READ:
- if (reads_paused_) {
- has_pending_reads_ = true;
- } else {
- Read();
- }
- break;
- default:
- // Close() is called by Read() in the Linux case.
- NOTREACHED();
- break;
- }
-}
-
-void StreamListenSocket::OnFileCanWriteWithoutBlocking(int fd) {
- // MessagePumpLibevent callback, we don't listen for write events
- // so we shouldn't ever reach here.
- NOTREACHED();
-}
-
-#endif
-
-void StreamListenSocket::PauseReads() {
- DCHECK(!reads_paused_);
- reads_paused_ = true;
-}
-
-void StreamListenSocket::ResumeReads() {
- DCHECK(reads_paused_);
- reads_paused_ = false;
- if (has_pending_reads_) {
- has_pending_reads_ = false;
- Read();
- }
-}
-
-} // namespace test_server
-
-} // namespace net
diff --git a/chromium/net/test/embedded_test_server/stream_listen_socket.h b/chromium/net/test/embedded_test_server/stream_listen_socket.h
deleted file mode 100644
index efa8b2e4d48..00000000000
--- a/chromium/net/test/embedded_test_server/stream_listen_socket.h
+++ /dev/null
@@ -1,151 +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.
-
-// Stream-based listen socket implementation that handles reading and writing
-// to the socket, but does not handle creating the socket nor connecting
-// sockets, which are handled by subclasses on creation and in Accept,
-// respectively.
-
-// StreamListenSocket handles IO asynchronously in the specified MessageLoop.
-// This class is NOT thread safe. It uses WSAEVENT handles to monitor activity
-// in a given MessageLoop. This means that callbacks will happen in that loop's
-// thread always and that all other methods (including constructor and
-// destructor) should also be called from the same thread.
-
-#ifndef NET_TEST_EMBEDDED_TEST_SERVER_STREAM_LISTEN_SOCKET_H_
-#define NET_TEST_EMBEDDED_TEST_SERVER_STREAM_LISTEN_SOCKET_H_
-
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <winsock2.h>
-#endif
-#include <string>
-#if defined(OS_WIN)
-#include "base/win/object_watcher.h"
-#elif defined(OS_POSIX)
-#include "base/message_loop/message_loop.h"
-#endif
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "net/base/net_export.h"
-#include "net/socket/socket_descriptor.h"
-
-namespace net {
-
-class IPEndPoint;
-
-namespace test_server {
-
-class StreamListenSocket :
-#if defined(OS_WIN)
- public base::win::ObjectWatcher::Delegate {
-#elif defined(OS_POSIX)
- public base::MessageLoopForIO::Watcher {
-#endif
-
- public:
- ~StreamListenSocket() override;
-
- // TODO(erikkay): this delegate should really be split into two parts
- // to split up the listener from the connected socket. Perhaps this class
- // should be split up similarly.
- class Delegate {
- public:
- // |server| is the original listening Socket, connection is the new
- // Socket that was created.
- virtual void DidAccept(StreamListenSocket* server,
- scoped_ptr<StreamListenSocket> connection) = 0;
- virtual void DidRead(StreamListenSocket* connection,
- const char* data,
- int len) = 0;
- virtual void DidClose(StreamListenSocket* sock) = 0;
-
- protected:
- virtual ~Delegate() {}
- };
-
- // Send data to the socket.
- void Send(const char* bytes, int len, bool append_linefeed = false);
- void Send(const std::string& str, bool append_linefeed = false);
-
- // Copies the local address to |address|. Returns a network error code.
- // This method is virtual to support unit testing.
- virtual int GetLocalAddress(IPEndPoint* address) const;
- // Copies the peer address to |address|. Returns a network error code.
- // This method is virtual to support unit testing.
- virtual int GetPeerAddress(IPEndPoint* address) const;
-
- static const int kSocketError;
-
- protected:
- enum WaitState { NOT_WAITING = 0, WAITING_ACCEPT = 1, WAITING_READ = 2 };
-
- StreamListenSocket(SocketDescriptor s, Delegate* del);
-
- SocketDescriptor AcceptSocket();
- virtual void Accept() = 0;
-
- void Listen();
- void Read();
- void Close();
- void CloseSocket();
-
- // Pass any value in case of Windows, because in Windows
- // we are not using state.
- void WatchSocket(WaitState state);
- void UnwatchSocket();
-
- Delegate* const socket_delegate_;
-
- private:
- friend class TransportClientSocketTest;
-
- void SendInternal(const char* bytes, int len);
-
-#if defined(OS_WIN)
- // ObjectWatcher delegate.
- void OnObjectSignaled(HANDLE object) override;
- base::win::ObjectWatcher watcher_;
- HANDLE socket_event_;
-#elif defined(OS_POSIX)
- // Called by MessagePumpLibevent when the socket is ready to do I/O.
- void OnFileCanReadWithoutBlocking(int fd) override;
- void OnFileCanWriteWithoutBlocking(int fd) override;
- WaitState wait_state_;
- // The socket's posix wrapper.
- base::MessageLoopForIO::FileDescriptorWatcher watcher_;
-#endif
-
- // NOTE: This is for unit test use only!
- // Pause/Resume calling Read(). Note that ResumeReads() will also call
- // Read() if there is anything to read.
- void PauseReads();
- void ResumeReads();
-
- const SocketDescriptor socket_;
- bool reads_paused_;
- bool has_pending_reads_;
-
- DISALLOW_COPY_AND_ASSIGN(StreamListenSocket);
-};
-
-// Abstract factory that must be subclassed for each subclass of
-// StreamListenSocket.
-class StreamListenSocketFactory {
- public:
- virtual ~StreamListenSocketFactory() {}
-
- // Returns a new instance of StreamListenSocket or NULL if an error occurred.
- virtual scoped_ptr<StreamListenSocket> CreateAndListen(
- StreamListenSocket::Delegate* delegate) const = 0;
-};
-
-} // namespace test_server
-
-} // namespace net
-
-#endif // NET_TEST_EMBEDDED_TEST_SERVER_STREAM_LISTEN_SOCKET_H_
diff --git a/chromium/net/test/embedded_test_server/tcp_listen_socket.cc b/chromium/net/test/embedded_test_server/tcp_listen_socket.cc
deleted file mode 100644
index 418f3459212..00000000000
--- a/chromium/net/test/embedded_test_server/tcp_listen_socket.cc
+++ /dev/null
@@ -1,118 +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/test/embedded_test_server/tcp_listen_socket.h"
-
-#if defined(OS_WIN)
-// winsock2.h must be included first in order to ensure it is included before
-// windows.h.
-#include <winsock2.h>
-#elif defined(OS_POSIX)
-#include <arpa/inet.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include "net/base/net_errors.h"
-#endif
-
-#include "base/logging.h"
-#include "base/sys_byteorder.h"
-#include "base/threading/platform_thread.h"
-#include "build/build_config.h"
-#include "net/base/net_util.h"
-#include "net/base/winsock_init.h"
-#include "net/socket/socket_descriptor.h"
-
-using std::string;
-
-namespace net {
-
-namespace test_server {
-
-// static
-scoped_ptr<TCPListenSocket> TCPListenSocket::CreateAndListen(
- const string& ip,
- uint16 port,
- StreamListenSocket::Delegate* del) {
- SocketDescriptor s = CreateAndBind(ip, port);
- if (s == kInvalidSocket)
- return scoped_ptr<TCPListenSocket>();
- scoped_ptr<TCPListenSocket> sock(new TCPListenSocket(s, del));
- sock->Listen();
- return sock.Pass();
-}
-
-TCPListenSocket::TCPListenSocket(SocketDescriptor s,
- StreamListenSocket::Delegate* del)
- : StreamListenSocket(s, del) {
-}
-
-TCPListenSocket::~TCPListenSocket() {
-}
-
-SocketDescriptor TCPListenSocket::CreateAndBind(const string& ip, uint16 port) {
- SocketDescriptor s = CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (s != kInvalidSocket) {
-#if defined(OS_POSIX)
- // Allow rapid reuse.
- static const int kOn = 1;
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
-#endif
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr(ip.c_str());
- addr.sin_port = base::HostToNet16(port);
- if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) {
-#if defined(OS_WIN)
- closesocket(s);
-#elif defined(OS_POSIX)
- close(s);
-#endif
- LOG(ERROR) << "Could not bind socket to " << ip << ":" << port;
- s = kInvalidSocket;
- }
- }
- return s;
-}
-
-SocketDescriptor TCPListenSocket::CreateAndBindAnyPort(const string& ip,
- uint16* port) {
- SocketDescriptor s = CreateAndBind(ip, 0);
- if (s == kInvalidSocket)
- return kInvalidSocket;
- sockaddr_in addr;
- socklen_t addr_size = sizeof(addr);
- bool failed = getsockname(s, reinterpret_cast<struct sockaddr*>(&addr),
- &addr_size) != 0;
- if (addr_size != sizeof(addr))
- failed = true;
- if (failed) {
- LOG(ERROR) << "Could not determine bound port, getsockname() failed";
-#if defined(OS_WIN)
- closesocket(s);
-#elif defined(OS_POSIX)
- close(s);
-#endif
- return kInvalidSocket;
- }
- *port = base::NetToHost16(addr.sin_port);
- return s;
-}
-
-void TCPListenSocket::Accept() {
- SocketDescriptor conn = AcceptSocket();
- if (conn == kInvalidSocket)
- return;
- scoped_ptr<TCPListenSocket> sock(new TCPListenSocket(conn, socket_delegate_));
-#if defined(OS_POSIX)
- sock->WatchSocket(WAITING_READ);
-#endif
- socket_delegate_->DidAccept(this, sock.Pass());
-}
-
-} // namespace test_server
-
-} // namespace net
diff --git a/chromium/net/test/embedded_test_server/tcp_listen_socket.h b/chromium/net/test/embedded_test_server/tcp_listen_socket.h
deleted file mode 100644
index 1de0d50ab34..00000000000
--- a/chromium/net/test/embedded_test_server/tcp_listen_socket.h
+++ /dev/null
@@ -1,57 +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_TEST_EMBEDDED_TEST_SERVER_TCP_LISTEN_SOCKET_H_
-#define NET_TEST_EMBEDDED_TEST_SERVER_TCP_LISTEN_SOCKET_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "net/base/net_export.h"
-#include "net/socket/socket_descriptor.h"
-#include "net/test/embedded_test_server/stream_listen_socket.h"
-
-namespace net {
-
-namespace test_server {
-
-// Implements a TCP socket.
-// TODO(xunjieli): Consider making embedded_test_server use HttpServer instead
-// of having its own socket class.
-class TCPListenSocket : public StreamListenSocket {
- public:
- ~TCPListenSocket() override;
-
- protected:
- TCPListenSocket(SocketDescriptor s, StreamListenSocket::Delegate* del);
-
- // Implements StreamListenSocket::Accept.
- void Accept() override;
-
- private:
- friend class EmbeddedTestServer;
- friend class TCPListenSocketTester;
-
- // Listen on port for the specified IP address. Use 127.0.0.1 to only
- // accept local connections.
- static scoped_ptr<TCPListenSocket> CreateAndListen(
- const std::string& ip,
- uint16 port,
- StreamListenSocket::Delegate* del);
-
- // Get raw TCP socket descriptor bound to ip:port.
- static SocketDescriptor CreateAndBind(const std::string& ip, uint16 port);
-
- // Get raw TCP socket descriptor bound to ip and return port it is bound to.
- static SocketDescriptor CreateAndBindAnyPort(const std::string& ip,
- uint16* port);
-
- DISALLOW_COPY_AND_ASSIGN(TCPListenSocket);
-};
-
-} // namespace test_server
-
-} // namespace net
-
-#endif // NET_TEST_EMBEDDED_TEST_SERVER_TCP_LISTEN_SOCKET_H_
diff --git a/chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.cc b/chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.cc
deleted file mode 100644
index 662d465148e..00000000000
--- a/chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.cc
+++ /dev/null
@@ -1,312 +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/test/embedded_test_server/tcp_listen_socket_unittest.h"
-
-#include <fcntl.h>
-#include <sys/types.h>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/single_thread_task_runner.h"
-#include "base/sys_byteorder.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
-#include "net/socket/socket_descriptor.h"
-#include "testing/platform_test.h"
-
-namespace net {
-
-namespace test_server {
-
-const int kReadBufSize = 1024;
-const char kHelloWorld[] = "HELLO, WORLD";
-const char kLoopback[] = "127.0.0.1";
-
-TCPListenSocketTester::TCPListenSocketTester()
- : loop_(NULL), cv_(&lock_), server_port_(0) {
-}
-
-void TCPListenSocketTester::SetUp() {
- base::Thread::Options options;
- options.message_loop_type = base::MessageLoop::TYPE_IO;
- thread_.reset(new base::Thread("socketio_test"));
- thread_->StartWithOptions(options);
- loop_ = reinterpret_cast<base::MessageLoopForIO*>(thread_->message_loop());
-
- loop_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&TCPListenSocketTester::Listen, this));
-
- // verify Listen succeeded
- NextAction();
- ASSERT_FALSE(server_.get() == NULL);
- ASSERT_EQ(ACTION_LISTEN, last_action_.type());
-
- int server_port = GetServerPort();
- ASSERT_GT(server_port, 0);
-
- // verify the connect/accept and setup test_socket_
- test_socket_ = CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- ASSERT_NE(kInvalidSocket, test_socket_);
- struct sockaddr_in client;
- client.sin_family = AF_INET;
- client.sin_addr.s_addr = inet_addr(kLoopback);
- client.sin_port = base::HostToNet16(server_port);
- int ret = HANDLE_EINTR(connect(
- test_socket_, reinterpret_cast<sockaddr*>(&client), sizeof(client)));
-#if defined(OS_POSIX)
- // The connect() call may be interrupted by a signal. When connect()
- // is retried on EINTR, it fails with EISCONN.
- if (ret == StreamListenSocket::kSocketError)
- ASSERT_EQ(EISCONN, errno);
-#else
- // Don't have signals.
- ASSERT_NE(StreamListenSocket::kSocketError, ret);
-#endif
-
- NextAction();
- ASSERT_EQ(ACTION_ACCEPT, last_action_.type());
-}
-
-void TCPListenSocketTester::TearDown() {
-#if defined(OS_WIN)
- ASSERT_EQ(0, closesocket(test_socket_));
-#elif defined(OS_POSIX)
- ASSERT_EQ(0, IGNORE_EINTR(close(test_socket_)));
-#endif
- NextAction();
- ASSERT_EQ(ACTION_CLOSE, last_action_.type());
-
- loop_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&TCPListenSocketTester::Shutdown, this));
- NextAction();
- ASSERT_EQ(ACTION_SHUTDOWN, last_action_.type());
-
- thread_.reset();
- loop_ = NULL;
-}
-
-void TCPListenSocketTester::ReportAction(
- const TCPListenSocketTestAction& action) {
- base::AutoLock locked(lock_);
- queue_.push_back(action);
- cv_.Broadcast();
-}
-
-void TCPListenSocketTester::NextAction() {
- base::AutoLock locked(lock_);
- while (queue_.empty())
- cv_.Wait();
- last_action_ = queue_.front();
- queue_.pop_front();
-}
-
-int TCPListenSocketTester::ClearTestSocket() {
- char buf[kReadBufSize];
- int len_ret = 0;
- do {
- int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0));
- if (len == StreamListenSocket::kSocketError || len == 0) {
- break;
- } else {
- len_ret += len;
- }
- } while (true);
- return len_ret;
-}
-
-void TCPListenSocketTester::Shutdown() {
- connection_.reset();
- server_.reset();
- ReportAction(TCPListenSocketTestAction(ACTION_SHUTDOWN));
-}
-
-void TCPListenSocketTester::Listen() {
- server_ = DoListen();
- ASSERT_TRUE(server_.get());
-
- // The server's port will be needed to open the client socket.
- IPEndPoint local_address;
- ASSERT_EQ(OK, server_->GetLocalAddress(&local_address));
- SetServerPort(local_address.port());
-
- ReportAction(TCPListenSocketTestAction(ACTION_LISTEN));
-}
-
-void TCPListenSocketTester::SendFromTester() {
- connection_->Send(kHelloWorld);
- ReportAction(TCPListenSocketTestAction(ACTION_SEND));
-}
-
-void TCPListenSocketTester::TestClientSend() {
- ASSERT_TRUE(Send(test_socket_, kHelloWorld));
- NextAction();
- ASSERT_EQ(ACTION_READ, last_action_.type());
- ASSERT_EQ(last_action_.data(), kHelloWorld);
-}
-
-void TCPListenSocketTester::TestClientSendLong() {
- size_t hello_len = strlen(kHelloWorld);
- std::string long_string;
- size_t long_len = 0;
- for (int i = 0; i < 200; i++) {
- long_string += kHelloWorld;
- long_len += hello_len;
- }
- ASSERT_TRUE(Send(test_socket_, long_string));
- size_t read_len = 0;
- while (read_len < long_len) {
- NextAction();
- ASSERT_EQ(ACTION_READ, last_action_.type());
- std::string last_data = last_action_.data();
- size_t len = last_data.length();
- if (long_string.compare(read_len, len, last_data)) {
- ASSERT_EQ(long_string.compare(read_len, len, last_data), 0);
- }
- read_len += last_data.length();
- }
- ASSERT_EQ(read_len, long_len);
-}
-
-void TCPListenSocketTester::TestServerSend() {
- loop_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&TCPListenSocketTester::SendFromTester, this));
- NextAction();
- ASSERT_EQ(ACTION_SEND, last_action_.type());
- const int buf_len = 200;
- char buf[buf_len + 1];
- unsigned recv_len = 0;
- while (recv_len < strlen(kHelloWorld)) {
- int r =
- HANDLE_EINTR(recv(test_socket_, buf + recv_len, buf_len - recv_len, 0));
- ASSERT_GE(r, 0);
- recv_len += static_cast<unsigned>(r);
- if (!r)
- break;
- }
- buf[recv_len] = 0;
- ASSERT_STREQ(kHelloWorld, buf);
-}
-
-void TCPListenSocketTester::TestServerSendMultiple() {
- // Send enough data to exceed the socket receive window. 20kb is probably a
- // safe bet.
- int send_count = (1024 * 20) / (sizeof(kHelloWorld) - 1);
-
- // Send multiple writes. Since no reading is occurring the data should be
- // buffered in TCPListenSocket.
- for (int i = 0; i < send_count; ++i) {
- loop_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&TCPListenSocketTester::SendFromTester, this));
- NextAction();
- ASSERT_EQ(ACTION_SEND, last_action_.type());
- }
-
- // Make multiple reads. All of the data should eventually be returned.
- char buf[sizeof(kHelloWorld)];
- const int buf_len = sizeof(kHelloWorld);
- for (int i = 0; i < send_count; ++i) {
- unsigned recv_len = 0;
- while (recv_len < buf_len - 1) {
- int r = HANDLE_EINTR(
- recv(test_socket_, buf + recv_len, buf_len - 1 - recv_len, 0));
- ASSERT_GE(r, 0);
- recv_len += static_cast<unsigned>(r);
- if (!r)
- break;
- }
- buf[recv_len] = 0;
- ASSERT_STREQ(kHelloWorld, buf);
- }
-}
-
-bool TCPListenSocketTester::Send(SocketDescriptor sock,
- const std::string& str) {
- int len = static_cast<int>(str.length());
- int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0));
- if (send_len == StreamListenSocket::kSocketError) {
- LOG(ERROR) << "send failed: " << errno;
- return false;
- } else if (send_len != len) {
- return false;
- }
- return true;
-}
-
-void TCPListenSocketTester::DidAccept(
- StreamListenSocket* server,
- scoped_ptr<StreamListenSocket> connection) {
- connection_ = connection.Pass();
- ReportAction(TCPListenSocketTestAction(ACTION_ACCEPT));
-}
-
-void TCPListenSocketTester::DidRead(StreamListenSocket* connection,
- const char* data,
- int len) {
- std::string str(data, len);
- ReportAction(TCPListenSocketTestAction(ACTION_READ, str));
-}
-
-void TCPListenSocketTester::DidClose(StreamListenSocket* sock) {
- ReportAction(TCPListenSocketTestAction(ACTION_CLOSE));
-}
-
-TCPListenSocketTester::~TCPListenSocketTester() {
-}
-
-scoped_ptr<TCPListenSocket> TCPListenSocketTester::DoListen() {
- // Let the OS pick a free port.
- return TCPListenSocket::CreateAndListen(kLoopback, 0, this);
-}
-
-int TCPListenSocketTester::GetServerPort() {
- base::AutoLock locked(lock_);
- return server_port_;
-}
-
-void TCPListenSocketTester::SetServerPort(int server_port) {
- base::AutoLock locked(lock_);
- server_port_ = server_port;
-}
-
-class TCPListenSocketTest : public PlatformTest {
- public:
- TCPListenSocketTest() { tester_ = NULL; }
-
- void SetUp() override {
- PlatformTest::SetUp();
- tester_ = new TCPListenSocketTester();
- tester_->SetUp();
- }
-
- void TearDown() override {
- PlatformTest::TearDown();
- tester_->TearDown();
- tester_ = NULL;
- }
-
- scoped_refptr<TCPListenSocketTester> tester_;
-};
-
-TEST_F(TCPListenSocketTest, ClientSend) {
- tester_->TestClientSend();
-}
-
-TEST_F(TCPListenSocketTest, ClientSendLong) {
- tester_->TestClientSendLong();
-}
-
-TEST_F(TCPListenSocketTest, ServerSend) {
- tester_->TestServerSend();
-}
-
-TEST_F(TCPListenSocketTest, ServerSendMultiple) {
- tester_->TestServerSendMultiple();
-}
-
-} // namespace test_server
-
-} // namespace net
diff --git a/chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.h b/chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.h
deleted file mode 100644
index 949e6311363..00000000000
--- a/chromium/net/test/embedded_test_server/tcp_listen_socket_unittest.h
+++ /dev/null
@@ -1,131 +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_TEST_EMBEDDED_TEST_SERVER_LISTEN_SOCKET_UNITTEST_H_
-#define NET_TEST_EMBEDDED_TEST_SERVER_LISTEN_SOCKET_UNITTEST_H_
-
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <winsock2.h>
-#elif defined(OS_POSIX)
-#include <arpa/inet.h>
-#include <errno.h>
-#include <sys/socket.h>
-#endif
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_util.h"
-#include "base/synchronization/condition_variable.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/thread.h"
-#include "net/base/net_util.h"
-#include "net/base/winsock_init.h"
-#include "net/test/embedded_test_server/tcp_listen_socket.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-namespace test_server {
-
-enum ActionType {
- ACTION_NONE = 0,
- ACTION_LISTEN = 1,
- ACTION_ACCEPT = 2,
- ACTION_READ = 3,
- ACTION_SEND = 4,
- ACTION_CLOSE = 5,
- ACTION_SHUTDOWN = 6
-};
-
-class TCPListenSocketTestAction {
- public:
- TCPListenSocketTestAction() : action_(ACTION_NONE) {}
- explicit TCPListenSocketTestAction(ActionType action) : action_(action) {}
- TCPListenSocketTestAction(ActionType action, const std::string& data)
- : action_(action), data_(data) {}
-
- const std::string& data() const { return data_; }
- ActionType type() const { return action_; }
-
- private:
- ActionType action_;
- std::string data_;
-};
-
-// This had to be split out into a separate class because I couldn't
-// make the testing::Test class refcounted.
-class TCPListenSocketTester
- : public StreamListenSocket::Delegate,
- public base::RefCountedThreadSafe<TCPListenSocketTester> {
- public:
- TCPListenSocketTester();
-
- void SetUp();
- void TearDown();
-
- void ReportAction(const TCPListenSocketTestAction& action);
- void NextAction();
-
- // read all pending data from the test socket
- int ClearTestSocket();
- // Release the connection and server sockets
- void Shutdown();
- void Listen();
- void SendFromTester();
- // verify the send/read from client to server
- void TestClientSend();
- // verify send/read of a longer string
- void TestClientSendLong();
- // verify a send/read from server to client
- void TestServerSend();
- // verify multiple sends and reads from server to client.
- void TestServerSendMultiple();
-
- virtual bool Send(SocketDescriptor sock, const std::string& str);
-
- // StreamListenSocket::Delegate:
- void DidAccept(StreamListenSocket* server,
- scoped_ptr<StreamListenSocket> connection) override;
- void DidRead(StreamListenSocket* connection,
- const char* data,
- int len) override;
- void DidClose(StreamListenSocket* sock) override;
-
- scoped_ptr<base::Thread> thread_;
- base::MessageLoopForIO* loop_;
- scoped_ptr<TCPListenSocket> server_;
- scoped_ptr<StreamListenSocket> connection_;
- TCPListenSocketTestAction last_action_;
-
- SocketDescriptor test_socket_;
-
- base::Lock lock_; // Protects |queue_| and |server_port_|. Wraps |cv_|.
- base::ConditionVariable cv_;
- std::deque<TCPListenSocketTestAction> queue_;
-
- private:
- friend class base::RefCountedThreadSafe<TCPListenSocketTester>;
-
- ~TCPListenSocketTester() override;
-
- virtual scoped_ptr<TCPListenSocket> DoListen();
-
- // Getters/setters for |server_port_|. They use |lock_| for thread safety.
- int GetServerPort();
- void SetServerPort(int server_port);
-
- // Port the server is using. Must have |lock_| to access. Set by Listen() on
- // the server's thread.
- int server_port_;
-};
-
-} // namespace test_server
-
-} // namespace net
-
-#endif // NET_TEST_EMBEDDED_TEST_SERVER_LISTEN_SOCKET_UNITTEST_H_
diff --git a/chromium/net/test/net_test_suite.cc b/chromium/net/test/net_test_suite.cc
index b14e3fea536..a657d26df6b 100644
--- a/chromium/net/test/net_test_suite.cc
+++ b/chromium/net/test/net_test_suite.cc
@@ -24,11 +24,6 @@ NetTestSuite::NetTestSuite(int argc, char** argv)
: TestSuite(argc, argv) {
}
-NetTestSuite::NetTestSuite(int argc, char** argv,
- bool create_at_exit_manager)
- : TestSuite(argc, argv, create_at_exit_manager) {
-}
-
NetTestSuite::~NetTestSuite() {}
void NetTestSuite::Initialize() {
diff --git a/chromium/net/test/net_test_suite.h b/chromium/net/test/net_test_suite.h
index e0f601eb887..92f079cde7f 100644
--- a/chromium/net/test/net_test_suite.h
+++ b/chromium/net/test/net_test_suite.h
@@ -28,11 +28,6 @@ class NetTestSuite : public base::TestSuite {
void Shutdown() override;
protected:
- // This constructor is only accessible to specialized net test
- // implementations which need to control the creation of an AtExitManager
- // instance for the duration of the test.
- NetTestSuite(int argc, char** argv, bool create_at_exit_manager);
-
// Called from within Initialize(), but separate so that derived classes
// can initialize the NetTestSuite instance only and not
// TestSuite::Initialize(). TestSuite::Initialize() performs some global
diff --git a/chromium/net/test/python_utils_unittest.cc b/chromium/net/test/python_utils_unittest.cc
index 57b7f476d47..a713e72ff33 100644
--- a/chromium/net/test/python_utils_unittest.cc
+++ b/chromium/net/test/python_utils_unittest.cc
@@ -61,6 +61,6 @@ TEST(PythonUtils, MAYBE_PythonRunTime) {
cmd_line.AppendArg(python_cmd);
std::string output;
EXPECT_TRUE(base::GetAppOutput(cmd_line, &output));
- base::TrimWhitespace(output, base::TRIM_TRAILING, &output);
+ base::TrimWhitespaceASCII(output, base::TRIM_TRAILING, &output);
EXPECT_EQ(input, output);
}
diff --git a/chromium/net/test/scoped_disable_exit_on_dfatal.h b/chromium/net/test/scoped_disable_exit_on_dfatal.h
index d536fbcce63..33f06e3bc59 100644
--- a/chromium/net/test/scoped_disable_exit_on_dfatal.h
+++ b/chromium/net/test/scoped_disable_exit_on_dfatal.h
@@ -6,13 +6,13 @@
#define NET_TEST_SCOPED_DISABLE_EXIT_ON_DFATAL_H_
#include "base/logging.h"
+#include "base/macros.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace test {
-
// The ScopedDisableExitOnDFatal class is used to disable exiting the
// program when we encounter a LOG(DFATAL) within the current block.
// After we leave the current block, the default behavior is
diff --git a/chromium/net/test/spawned_test_server/base_test_server.cc b/chromium/net/test/spawned_test_server/base_test_server.cc
index d245cc2e218..e69233e5a61 100644
--- a/chromium/net/test/spawned_test_server/base_test_server.cc
+++ b/chromium/net/test/spawned_test_server/base_test_server.cc
@@ -4,7 +4,10 @@
#include "net/test/spawned_test_server/base_test_server.h"
+#include <stdint.h>
+#include <limits>
#include <string>
+#include <utility>
#include <vector>
#include "base/base64.h"
@@ -285,11 +288,11 @@ bool BaseTestServer::GetAddressList(AddressList* address_list) const {
return true;
}
-uint16 BaseTestServer::GetPort() {
+uint16_t BaseTestServer::GetPort() {
return host_port_pair_.port();
}
-void BaseTestServer::SetPort(uint16 port) {
+void BaseTestServer::SetPort(uint16_t port) {
host_port_pair_.set_port(port);
}
@@ -414,7 +417,7 @@ bool BaseTestServer::ParseServerData(const std::string& server_data) {
LOG(ERROR) << "Could not find port value";
return false;
}
- if ((port <= 0) || (port > kuint16max)) {
+ if ((port <= 0) || (port > std::numeric_limits<uint16_t>::max())) {
LOG(ERROR) << "Invalid port value: " << port;
return false;
}
@@ -557,7 +560,7 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const {
for (const std::string& proto : ssl_options_.npn_protocols) {
npn_protocols->Append(new base::StringValue(proto));
}
- arguments->Set("npn-protocols", npn_protocols.Pass());
+ arguments->Set("npn-protocols", std::move(npn_protocols));
}
if (ssl_options_.alert_after_handshake)
arguments->Set("alert-after-handshake", base::Value::CreateNullValue());
diff --git a/chromium/net/test/spawned_test_server/base_test_server.h b/chromium/net/test/spawned_test_server/base_test_server.h
index 3ea2506d432..7df24163713 100644
--- a/chromium/net/test/spawned_test_server/base_test_server.h
+++ b/chromium/net/test/spawned_test_server/base_test_server.h
@@ -5,12 +5,15 @@
#ifndef NET_TEST_SPAWNED_TEST_SERVER_BASE_TEST_SERVER_H_
#define NET_TEST_SPAWNED_TEST_SERVER_BASE_TEST_SERVER_H_
+#include <stdint.h>
+
#include <string>
#include <utility>
#include <vector>
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/host_port_pair.h"
@@ -156,7 +159,7 @@ class BaseTestServer {
// If not zero, |cert_serial| will be the serial number of the
// auto-generated leaf certificate when |server_certificate==CERT_AUTO|.
- uint64 cert_serial;
+ uint64_t cert_serial;
// True if a CertificateRequest should be sent to the client during
// handshaking.
@@ -297,10 +300,10 @@ class BaseTestServer {
// Gets port currently assigned to host_port_pair_ without checking
// whether it's available (server started) or not.
- uint16 GetPort();
+ uint16_t GetPort();
// Sets |port| as the actual port used by Python based test server.
- void SetPort(uint16 port);
+ void SetPort(uint16_t port);
// Set up internal status when the server is started.
bool SetupWhenServerStarted() WARN_UNUSED_RESULT;
diff --git a/chromium/net/test/spawned_test_server/local_test_server.h b/chromium/net/test/spawned_test_server/local_test_server.h
index 785d7267056..98152a162f7 100644
--- a/chromium/net/test/spawned_test_server/local_test_server.h
+++ b/chromium/net/test/spawned_test_server/local_test_server.h
@@ -9,6 +9,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
+#include "base/macros.h"
#include "base/process/process.h"
#include "net/test/spawned_test_server/base_test_server.h"
diff --git a/chromium/net/test/spawned_test_server/local_test_server_posix.cc b/chromium/net/test/spawned_test_server/local_test_server_posix.cc
index 2899c9030de..e5db9c010dd 100644
--- a/chromium/net/test/spawned_test_server/local_test_server_posix.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server_posix.cc
@@ -12,6 +12,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/process/process_iterator.h"
@@ -60,7 +61,9 @@ class OrphanedTestServerFilter : public base::ProcessFilter {
// Given a file descriptor, reads into |buffer| until |bytes_max|
// bytes has been read or an error has been encountered. Returns true
// if the read was successful. |remaining_time| is used as a timeout.
-bool ReadData(int fd, ssize_t bytes_max, uint8* buffer,
+bool ReadData(int fd,
+ ssize_t bytes_max,
+ uint8_t* buffer,
base::TimeDelta* remaining_time) {
ssize_t bytes_read = 0;
base::TimeTicks previous_time = base::TimeTicks::Now();
@@ -153,17 +156,16 @@ bool LocalTestServer::WaitToStart() {
base::TimeDelta remaining_time = TestTimeouts::action_timeout();
- uint32 server_data_len = 0;
+ uint32_t server_data_len = 0;
if (!ReadData(our_fd.get(), sizeof(server_data_len),
- reinterpret_cast<uint8*>(&server_data_len),
+ reinterpret_cast<uint8_t*>(&server_data_len),
&remaining_time)) {
LOG(ERROR) << "Could not read server_data_len";
return false;
}
std::string server_data(server_data_len, '\0');
if (!ReadData(our_fd.get(), server_data_len,
- reinterpret_cast<uint8*>(&server_data[0]),
- &remaining_time)) {
+ reinterpret_cast<uint8_t*>(&server_data[0]), &remaining_time)) {
LOG(ERROR) << "Could not read server_data (" << server_data_len
<< " bytes)";
return false;
diff --git a/chromium/net/test/spawned_test_server/local_test_server_win.cc b/chromium/net/test/spawned_test_server/local_test_server_win.cc
index 0476b907caf..3e87e997b84 100644
--- a/chromium/net/test/spawned_test_server/local_test_server_win.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server_win.cc
@@ -41,8 +41,10 @@ void UnblockPipe(HANDLE handle, DWORD size, bool* unblocked) {
// Given a file handle, reads into |buffer| until |bytes_max| bytes
// has been read or an error has been encountered. Returns
// true if the read was successful.
-bool ReadData(HANDLE read_fd, HANDLE write_fd,
- DWORD bytes_max, uint8* buffer) {
+bool ReadData(HANDLE read_fd,
+ HANDLE write_fd,
+ DWORD bytes_max,
+ uint8_t* buffer) {
base::Thread thread("test_server_watcher");
if (!thread.Start())
return false;
@@ -138,15 +140,15 @@ bool LocalTestServer::WaitToStart() {
base::win::ScopedHandle read_fd(child_read_fd_.Take());
base::win::ScopedHandle write_fd(child_write_fd_.Take());
- uint32 server_data_len = 0;
+ uint32_t server_data_len = 0;
if (!ReadData(read_fd.Get(), write_fd.Get(), sizeof(server_data_len),
- reinterpret_cast<uint8*>(&server_data_len))) {
+ reinterpret_cast<uint8_t*>(&server_data_len))) {
LOG(ERROR) << "Could not read server_data_len";
return false;
}
std::string server_data(server_data_len, '\0');
if (!ReadData(read_fd.Get(), write_fd.Get(), server_data_len,
- reinterpret_cast<uint8*>(&server_data[0]))) {
+ reinterpret_cast<uint8_t*>(&server_data[0]))) {
LOG(ERROR) << "Could not read server_data (" << server_data_len
<< " bytes)";
return false;
diff --git a/chromium/net/test/spawned_test_server/remote_test_server.cc b/chromium/net/test/spawned_test_server/remote_test_server.cc
index 0e1303e066c..c563242bb3c 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server.cc
+++ b/chromium/net/test/spawned_test_server/remote_test_server.cc
@@ -4,6 +4,9 @@
#include "net/test/spawned_test_server/remote_test_server.h"
+#include <stdint.h>
+
+#include <limits>
#include <vector>
#include "base/base_paths.h"
@@ -108,7 +111,7 @@ bool RemoteTestServer::Start() {
return false;
// Start the Python test server on the remote machine.
- uint16 test_server_port;
+ uint16_t test_server_port;
if (!spawner_communicator_->StartServer(arguments_string,
&test_server_port)) {
return false;
@@ -184,13 +187,15 @@ bool RemoteTestServer::Init(const base::FilePath& document_root) {
// Verify the ports information.
base::StringToInt(ports[0], &spawner_server_port_);
if (!spawner_server_port_ ||
- static_cast<uint32>(spawner_server_port_) >= kuint16max)
+ static_cast<uint32_t>(spawner_server_port_) >=
+ std::numeric_limits<uint16_t>::max())
return false;
// Allow the test_server_port to be 0, which means the test server spawner
// will pick up a random port to run the test server.
base::StringToInt(ports[1], &test_server_port);
- if (static_cast<uint32>(test_server_port) >= kuint16max)
+ if (static_cast<uint32_t>(test_server_port) >=
+ std::numeric_limits<uint16_t>::max())
return false;
SetPort(test_server_port);
diff --git a/chromium/net/test/spawned_test_server/remote_test_server.h b/chromium/net/test/spawned_test_server/remote_test_server.h
index a8b8bb2c235..0de5c7f63b4 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server.h
+++ b/chromium/net/test/spawned_test_server/remote_test_server.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "net/test/spawned_test_server/base_test_server.h"
namespace net {
diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.cc b/chromium/net/test/spawned_test_server/spawner_communicator.cc
index 9a96d3c78ab..8851f9f8bec 100644
--- a/chromium/net/test/spawned_test_server/spawner_communicator.cc
+++ b/chromium/net/test/spawned_test_server/spawner_communicator.cc
@@ -4,8 +4,12 @@
#include "net/test/spawned_test_server/spawner_communicator.h"
+#include <limits>
+#include <utility>
+
#include "base/json/json_reader.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/supports_user_data.h"
#include "base/test/test_timeouts.h"
@@ -24,7 +28,7 @@ namespace net {
namespace {
-GURL GenerateSpawnerCommandURL(const std::string& command, uint16 port) {
+GURL GenerateSpawnerCommandURL(const std::string& command, uint16_t port) {
// Always performs HTTP request for sending command to the spawner server.
return GURL(base::StringPrintf("%s:%u/%s", "http://127.0.0.1", port,
command.c_str()));
@@ -98,7 +102,7 @@ class SpawnerRequestData : public base::SupportsUserData::Data {
} // namespace
-SpawnerCommunicator::SpawnerCommunicator(uint16 port)
+SpawnerCommunicator::SpawnerCommunicator(uint16_t port)
: io_thread_("spawner_communicator"),
event_(false, false),
port_(port),
@@ -189,7 +193,7 @@ void SpawnerCommunicator::SendCommandAndWaitForResultOnIOThread(
scoped_ptr<UploadElementReader> reader(
UploadOwnedBytesElementReader::CreateWithString(post_data));
cur_request_->set_upload(
- ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
HttpRequestHeaders headers;
headers.SetHeader(HttpRequestHeaders::kContentType,
"application/json");
@@ -324,7 +328,7 @@ void SpawnerCommunicator::OnReadCompleted(URLRequest* request, int num_bytes) {
}
bool SpawnerCommunicator::StartServer(const std::string& arguments,
- uint16* port) {
+ uint16_t* port) {
*port = 0;
// Send the start command to spawner server to start the Python test server
// on remote machine.
@@ -352,11 +356,11 @@ bool SpawnerCommunicator::StartServer(const std::string& arguments,
}
int int_port;
if (!server_data->GetInteger("port", &int_port) || int_port <= 0 ||
- int_port > kuint16max) {
+ int_port > std::numeric_limits<uint16_t>::max()) {
LOG(ERROR) << "Invalid port value: " << int_port;
return false;
}
- *port = static_cast<uint16>(int_port);
+ *port = static_cast<uint16_t>(int_port);
return true;
}
diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.h b/chromium/net/test/spawned_test_server/spawner_communicator.h
index 15ae0c5e1c3..c066016ab13 100644
--- a/chromium/net/test/spawned_test_server/spawner_communicator.h
+++ b/chromium/net/test/spawned_test_server/spawner_communicator.h
@@ -5,9 +5,11 @@
#ifndef NET_TEST_SPAWNED_TEST_SERVER_SPAWNER_COMMUNICATOR_H_
#define NET_TEST_SPAWNED_TEST_SERVER_SPAWNER_COMMUNICATOR_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h"
@@ -60,7 +62,7 @@ class ScopedPortException;
// fetched from spawner server or timed-out.
class SpawnerCommunicator : public URLRequest::Delegate {
public:
- explicit SpawnerCommunicator(uint16 port);
+ explicit SpawnerCommunicator(uint16_t port);
~SpawnerCommunicator() override;
// Starts an instance of the Python test server on the host/ machine.
@@ -68,7 +70,7 @@ class SpawnerCommunicator : public URLRequest::Delegate {
// on the local machine that can be used to communicate with the remote
// test server.
bool StartServer(const std::string& arguments,
- uint16* port) WARN_UNUSED_RESULT;
+ uint16_t* port) WARN_UNUSED_RESULT;
bool StopServer() WARN_UNUSED_RESULT;
@@ -122,7 +124,7 @@ class SpawnerCommunicator : public URLRequest::Delegate {
// used to control the startup and shutdown of the Python TestServer running
// on the remote machine. On Android, this port will be redirected to the
// same port on the host machine.
- const uint16 port_;
+ const uint16_t port_;
// Helper to add |port_| to the list of the globally explicitly allowed ports.
scoped_ptr<ScopedPortException> allowed_port_;
diff --git a/chromium/net/test/test_certificate_data.h b/chromium/net/test/test_certificate_data.h
index b5346b4d9d1..a2e26a56e11 100644
--- a/chromium/net/test/test_certificate_data.h
+++ b/chromium/net/test/test_certificate_data.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
namespace {
// This is the SHA1 hash of the SubjectPublicKeyInfo of nist.der.
@@ -524,17 +526,16 @@ unsigned char VARIABLE_IS_NOT_USED paypal_null_der[] = {
// 44:d=3 hl=2 l= 3 prim: OBJECT :organizationalUnitName
// 49:d=3 hl=2 l= 46 prim: PRINTABLESTRING :
// Class 1 Public Primary Certification Authority
-const uint8 VARIABLE_IS_NOT_USED VerisignDN[] = {
- 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
- 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04,
- 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20, 0x50,
- 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72,
- 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
- 0x79
-};
+const uint8_t VARIABLE_IS_NOT_USED VerisignDN[] = {
+ 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
+ 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+ 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35,
+ 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x20, 0x31, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+ 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+ 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79};
// 0:d=0 hl=2 l= 125 cons: SEQUENCE
// 2:d=1 hl=2 l= 11 cons: SET
@@ -555,19 +556,18 @@ const uint8 VARIABLE_IS_NOT_USED VerisignDN[] = {
// 88:d=3 hl=2 l= 3 prim: OBJECT :commonName
// 93:d=3 hl=2 l= 32 prim: PRINTABLESTRING :
// StartCom Certification Authority
-const uint8 VARIABLE_IS_NOT_USED StartComDN[] = {
- 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c,
- 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67,
- 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67,
- 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x53,
- 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79
-};
+const uint8_t VARIABLE_IS_NOT_USED StartComDN[] = {
+ 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c,
+ 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b,
+ 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67,
+ 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67,
+ 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79};
// 0:d=0 hl=3 l= 174 cons: SEQUENCE
// 3:d=1 hl=2 l= 11 cons: SET
@@ -595,23 +595,22 @@ const uint8 VARIABLE_IS_NOT_USED StartComDN[] = {
//125:d=3 hl=2 l= 3 prim: OBJECT :commonName
//130:d=3 hl=2 l= 45 prim: PRINTABLESTRING :
// UTN-USERFirst-Client Authentication and Email
-const uint8 VARIABLE_IS_NOT_USED UserTrustDN[] = {
- 0x30, 0x81, 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
- 0x08, 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
- 0x04, 0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b,
- 0x65, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45,
- 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
- 0x6d, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d,
- 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
- 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75, 0x74,
- 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x61, 0x6e, 0x64, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c
-};
+const uint8_t VARIABLE_IS_NOT_USED UserTrustDN[] = {
+ 0x30, 0x81, 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+ 0x08, 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b,
+ 0x65, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03,
+ 0x55, 0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45,
+ 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+ 0x72, 0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+ 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d,
+ 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
+ 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75, 0x74,
+ 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+ 0x61, 0x6e, 0x64, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c};
// 0:d=0 hl=3 l= 190 cons: SEQUENCE
// 3:d=1 hl=2 l= 63 cons: SET
@@ -633,26 +632,25 @@ const uint8 VARIABLE_IS_NOT_USED UserTrustDN[] = {
//107:d=3 hl=2 l= 84 prim: UTF8STRING :
// TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
// (c) Kasım 2005
-const uint8 VARIABLE_IS_NOT_USED TurkTrustDN[] = {
- 0x30, 0x81, 0xbe, 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03,
- 0x0c, 0x36, 0x54, 0xc3, 0x9c, 0x52, 0x4b, 0x54, 0x52, 0x55, 0x53, 0x54,
- 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x6b, 0x20,
- 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x69,
- 0x7a, 0x6d, 0x65, 0x74, 0x20, 0x53, 0x61, 0xc4, 0x9f, 0x6c, 0x61, 0x79,
- 0xc4, 0xb1, 0x63, 0xc4, 0xb1, 0x73, 0xc4, 0xb1, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x52, 0x31, 0x0f, 0x30,
- 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x41, 0x6e, 0x6b, 0x61,
- 0x72, 0x61, 0x31, 0x5d, 0x30, 0x5b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
- 0x54, 0x54, 0xc3, 0x9c, 0x52, 0x4b, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20,
- 0x42, 0x69, 0x6c, 0x67, 0x69, 0x20, 0xc4, 0xb0, 0x6c, 0x65, 0x74, 0x69,
- 0xc5, 0x9f, 0x69, 0x6d, 0x20, 0x76, 0x65, 0x20, 0x42, 0x69, 0x6c, 0x69,
- 0xc5, 0x9f, 0x69, 0x6d, 0x20, 0x47, 0xc3, 0xbc, 0x76, 0x65, 0x6e, 0x6c,
- 0x69, 0xc4, 0x9f, 0x69, 0x20, 0x48, 0x69, 0x7a, 0x6d, 0x65, 0x74, 0x6c,
- 0x65, 0x72, 0x69, 0x20, 0x41, 0x2e, 0xc5, 0x9e, 0x2e, 0x20, 0x28, 0x63,
- 0x29, 0x20, 0x4b, 0x61, 0x73, 0xc4, 0xb1, 0x6d, 0x20, 0x32, 0x30, 0x30,
- 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31, 0x31, 0x30, 0x37, 0x31,
- 0x30, 0x30, 0x37, 0x35, 0x37
-};
+const uint8_t VARIABLE_IS_NOT_USED TurkTrustDN[] = {
+ 0x30, 0x81, 0xbe, 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x36, 0x54, 0xc3, 0x9c, 0x52, 0x4b, 0x54, 0x52, 0x55, 0x53, 0x54,
+ 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x6b, 0x20,
+ 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x69,
+ 0x7a, 0x6d, 0x65, 0x74, 0x20, 0x53, 0x61, 0xc4, 0x9f, 0x6c, 0x61, 0x79,
+ 0xc4, 0xb1, 0x63, 0xc4, 0xb1, 0x73, 0xc4, 0xb1, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x52, 0x31, 0x0f, 0x30,
+ 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x41, 0x6e, 0x6b, 0x61,
+ 0x72, 0x61, 0x31, 0x5d, 0x30, 0x5b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
+ 0x54, 0x54, 0xc3, 0x9c, 0x52, 0x4b, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20,
+ 0x42, 0x69, 0x6c, 0x67, 0x69, 0x20, 0xc4, 0xb0, 0x6c, 0x65, 0x74, 0x69,
+ 0xc5, 0x9f, 0x69, 0x6d, 0x20, 0x76, 0x65, 0x20, 0x42, 0x69, 0x6c, 0x69,
+ 0xc5, 0x9f, 0x69, 0x6d, 0x20, 0x47, 0xc3, 0xbc, 0x76, 0x65, 0x6e, 0x6c,
+ 0x69, 0xc4, 0x9f, 0x69, 0x20, 0x48, 0x69, 0x7a, 0x6d, 0x65, 0x74, 0x6c,
+ 0x65, 0x72, 0x69, 0x20, 0x41, 0x2e, 0xc5, 0x9e, 0x2e, 0x20, 0x28, 0x63,
+ 0x29, 0x20, 0x4b, 0x61, 0x73, 0xc4, 0xb1, 0x6d, 0x20, 0x32, 0x30, 0x30,
+ 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31, 0x31, 0x30, 0x37, 0x31,
+ 0x30, 0x30, 0x37, 0x35, 0x37};
// 33:d=2 hl=3 l= 207 cons: SEQUENCE
// 36:d=3 hl=2 l= 11 cons: SET
@@ -672,26 +670,25 @@ const uint8 VARIABLE_IS_NOT_USED TurkTrustDN[] = {
//219:d=4 hl=2 l= 22 cons: SEQUENCE
//221:d=5 hl=2 l= 3 prim: OBJECT :commonName
//226:d=5 hl=2 l= 15 prim: PRINTABLESTRING :A-Trust-Qual-01
-const uint8 VARIABLE_IS_NOT_USED ATrustQual01DN[] = {
- 0x30, 0x81, 0xcf, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
- 0x13, 0x02, 0x41, 0x54, 0x31, 0x81, 0x8b, 0x30, 0x81, 0x88, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x1e, 0x81, 0x80, 0x00, 0x41, 0x00, 0x2d, 0x00, 0x54,
- 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x20, 0x00, 0x47,
- 0x00, 0x65, 0x00, 0x73, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x66, 0x00, 0xfc,
- 0x00, 0x72, 0x00, 0x20, 0x00, 0x53, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68,
- 0x00, 0x65, 0x00, 0x72, 0x00, 0x68, 0x00, 0x65, 0x00, 0x69, 0x00, 0x74,
- 0x00, 0x73, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65,
- 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x20,
- 0x00, 0x65, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x6b, 0x00, 0x74, 0x00, 0x72,
- 0x00, 0x2e, 0x00, 0x20, 0x00, 0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65,
- 0x00, 0x6e, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x65,
- 0x00, 0x68, 0x00, 0x72, 0x00, 0x20, 0x00, 0x47, 0x00, 0x6d, 0x00, 0x62,
- 0x00, 0x48, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
- 0x0f, 0x41, 0x2d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x51, 0x75, 0x61,
- 0x6c, 0x2d, 0x30, 0x31, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04,
- 0x03, 0x13, 0x0f, 0x41, 0x2d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x51,
- 0x75, 0x61, 0x6c, 0x2d, 0x30, 0x31, 0x30, 0x1e, 0x17
-};
+const uint8_t VARIABLE_IS_NOT_USED ATrustQual01DN[] = {
+ 0x30, 0x81, 0xcf, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x41, 0x54, 0x31, 0x81, 0x8b, 0x30, 0x81, 0x88, 0x06, 0x03,
+ 0x55, 0x04, 0x0a, 0x1e, 0x81, 0x80, 0x00, 0x41, 0x00, 0x2d, 0x00, 0x54,
+ 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x20, 0x00, 0x47,
+ 0x00, 0x65, 0x00, 0x73, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x66, 0x00, 0xfc,
+ 0x00, 0x72, 0x00, 0x20, 0x00, 0x53, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68,
+ 0x00, 0x65, 0x00, 0x72, 0x00, 0x68, 0x00, 0x65, 0x00, 0x69, 0x00, 0x74,
+ 0x00, 0x73, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65,
+ 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x20,
+ 0x00, 0x65, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x6b, 0x00, 0x74, 0x00, 0x72,
+ 0x00, 0x2e, 0x00, 0x20, 0x00, 0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65,
+ 0x00, 0x6e, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x65,
+ 0x00, 0x68, 0x00, 0x72, 0x00, 0x20, 0x00, 0x47, 0x00, 0x6d, 0x00, 0x62,
+ 0x00, 0x48, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
+ 0x0f, 0x41, 0x2d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x51, 0x75, 0x61,
+ 0x6c, 0x2d, 0x30, 0x31, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x0f, 0x41, 0x2d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x51,
+ 0x75, 0x61, 0x6c, 0x2d, 0x30, 0x31, 0x30, 0x1e, 0x17};
// 34:d=2 hl=3 l= 180 cons: SEQUENCE
// 37:d=3 hl=2 l= 20 cons: SET
@@ -713,24 +710,23 @@ const uint8 VARIABLE_IS_NOT_USED ATrustQual01DN[] = {
//168:d=5 hl=2 l= 3 prim: OBJECT :commonName
//173:d=5 hl=2 l= 42 prim: PRINTABLESTRING :
// Entrust.net Certification Authority (2048)
-const uint8 VARIABLE_IS_NOT_USED EntrustDN[] = {
- 0x30, 0x81, 0xb4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x0b, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
- 0x74, 0x31, 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x37,
- 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
- 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38,
- 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20,
- 0x72, 0x65, 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73,
- 0x20, 0x6c, 0x69, 0x61, 0x62, 0x2e, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06,
- 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1c, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39,
- 0x39, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e,
- 0x65, 0x74, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33,
- 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x45, 0x6e, 0x74,
- 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72,
- 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30,
- 0x34, 0x38, 0x29
-};
+const uint8_t VARIABLE_IS_NOT_USED EntrustDN[] = {
+ 0x30, 0x81, 0xb4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0b, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
+ 0x74, 0x31, 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x37,
+ 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+ 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38,
+ 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20,
+ 0x72, 0x65, 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73,
+ 0x20, 0x6c, 0x69, 0x61, 0x62, 0x2e, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1c, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39,
+ 0x39, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e,
+ 0x65, 0x74, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33,
+ 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x45, 0x6e, 0x74,
+ 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+ 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30,
+ 0x34, 0x38, 0x29};
// 46:d=2 hl=2 l= 76 cons: SEQUENCE
// 48:d=3 hl=2 l= 11 cons: SET
@@ -746,15 +742,14 @@ const uint8 VARIABLE_IS_NOT_USED EntrustDN[] = {
// 102:d=4 hl=2 l= 20 cons: SEQUENCE
// 104:d=5 hl=2 l= 3 prim: OBJECT :commonName
// 109:d=5 hl=2 l= 13 prim: PRINTABLESTRING :Thawte SGC CA
-const uint8 VARIABLE_IS_NOT_USED ThawteDN[] = {
- 0x30, 0x4C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x5A, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A,
- 0x13, 0x1C, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6F, 0x6E,
- 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79,
- 0x29, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x0D, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
- 0x53, 0x47, 0x43, 0x20, 0x43, 0x41
-};
+const uint8_t VARIABLE_IS_NOT_USED ThawteDN[] = {
+ 0x30, 0x4C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+ 0x02, 0x5A, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A,
+ 0x13, 0x1C, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6F, 0x6E,
+ 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79,
+ 0x29, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x13, 0x0D, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+ 0x53, 0x47, 0x43, 0x20, 0x43, 0x41};
// 47:d=2 hl=2 l= 108 cons: SEQUENCE
// 49:d=3 hl=2 l= 11 cons: SET
@@ -774,17 +769,16 @@ const uint8 VARIABLE_IS_NOT_USED ThawteDN[] = {
// 136:d=4 hl=2 l= 19 cons: SEQUENCE
// 138:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
// 143:d=5 hl=2 l= 12 prim: PRINTABLESTRING :Client CA v1
-const uint8 VARIABLE_IS_NOT_USED MITDN[] = {
- 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x08,
- 0x13, 0x0D, 0x4D, 0x61, 0x73, 0x73, 0x61, 0x63, 0x68, 0x75, 0x73, 0x65,
- 0x74, 0x74, 0x73, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x0A,
- 0x13, 0x25, 0x4D, 0x61, 0x73, 0x73, 0x61, 0x63, 0x68, 0x75, 0x73, 0x65,
- 0x74, 0x74, 0x73, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74,
- 0x65, 0x20, 0x6F, 0x66, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C,
- 0x6F, 0x67, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0B,
- 0x13, 0x0C, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x43, 0x41, 0x20,
- 0x76, 0x31
-};
+const uint8_t VARIABLE_IS_NOT_USED MITDN[] = {
+ 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55,
+ 0x04, 0x08, 0x13, 0x0D, 0x4D, 0x61, 0x73, 0x73, 0x61, 0x63, 0x68,
+ 0x75, 0x73, 0x65, 0x74, 0x74, 0x73, 0x31, 0x2E, 0x30, 0x2C, 0x06,
+ 0x03, 0x55, 0x04, 0x0A, 0x13, 0x25, 0x4D, 0x61, 0x73, 0x73, 0x61,
+ 0x63, 0x68, 0x75, 0x73, 0x65, 0x74, 0x74, 0x73, 0x20, 0x49, 0x6E,
+ 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x20, 0x6F, 0x66, 0x20,
+ 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x79, 0x31,
+ 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0C, 0x43,
+ 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31};
} // namespace
diff --git a/chromium/net/test/url_request/ssl_certificate_error_job.cc b/chromium/net/test/url_request/ssl_certificate_error_job.cc
index 8f2a12bef10..83e7fd0c0a7 100644
--- a/chromium/net/test/url_request/ssl_certificate_error_job.cc
+++ b/chromium/net/test/url_request/ssl_certificate_error_job.cc
@@ -7,6 +7,7 @@
#include <string>
#include "base/bind.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "net/ssl/ssl_info.h"
diff --git a/chromium/net/test/url_request/url_request_failed_job.cc b/chromium/net/test/url_request/url_request_failed_job.cc
index e4ac6a675d0..d7c479b14f7 100644
--- a/chromium/net/test/url_request/url_request_failed_job.cc
+++ b/chromium/net/test/url_request/url_request_failed_job.cc
@@ -97,40 +97,20 @@ URLRequestFailedJob::URLRequestFailedJob(URLRequest* request,
}
void URLRequestFailedJob::Start() {
- if (phase_ == START) {
- if (net_error_ != ERR_IO_PENDING) {
- NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, net_error_));
- return;
- }
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- return;
- }
- response_info_.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
- NotifyHeadersComplete();
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&URLRequestFailedJob::StartAsync, weak_factory_.GetWeakPtr()));
}
-bool URLRequestFailedJob::ReadRawData(IOBuffer* buf,
- int buf_size,
- int* bytes_read) {
+int URLRequestFailedJob::ReadRawData(IOBuffer* buf, int buf_size) {
CHECK(phase_ == READ_SYNC || phase_ == READ_ASYNC);
- if (net_error_ != ERR_IO_PENDING && phase_ == READ_SYNC) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, net_error_));
- return false;
- }
-
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
-
- if (net_error_ == ERR_IO_PENDING)
- return false;
-
- DCHECK_EQ(READ_ASYNC, phase_);
- DCHECK_NE(ERR_IO_PENDING, net_error_);
+ if (net_error_ == ERR_IO_PENDING || phase_ == READ_SYNC)
+ return net_error_;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&URLRequestFailedJob::NotifyDone, weak_factory_.GetWeakPtr(),
- URLRequestStatus(URLRequestStatus::FAILED, net_error_)));
- return false;
+ FROM_HERE, base::Bind(&URLRequestFailedJob::ReadRawDataComplete,
+ weak_factory_.GetWeakPtr(), net_error_));
+ return ERR_IO_PENDING;
}
int URLRequestFailedJob::GetResponseCode() const {
@@ -195,4 +175,17 @@ GURL URLRequestFailedJob::GetMockHttpsUrlForHostname(
URLRequestFailedJob::~URLRequestFailedJob() {
}
+void URLRequestFailedJob::StartAsync() {
+ if (phase_ == START) {
+ if (net_error_ != ERR_IO_PENDING) {
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, net_error_));
+ return;
+ }
+ SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
+ return;
+ }
+ response_info_.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
+ NotifyHeadersComplete();
+}
+
} // namespace net
diff --git a/chromium/net/test/url_request/url_request_failed_job.h b/chromium/net/test/url_request/url_request_failed_job.h
index 0413111c87c..72518f78576 100644
--- a/chromium/net/test/url_request/url_request_failed_job.h
+++ b/chromium/net/test/url_request/url_request_failed_job.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/url_request/url_request_job.h"
#include "url/gurl.h"
@@ -39,7 +40,7 @@ class URLRequestFailedJob : public URLRequestJob {
// URLRequestJob implementation:
void Start() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
int GetResponseCode() const override;
void GetResponseInfo(HttpResponseInfo* info) override;
@@ -71,6 +72,7 @@ class URLRequestFailedJob : public URLRequestJob {
protected:
~URLRequestFailedJob() override;
+ void StartAsync();
private:
HttpResponseInfo response_info_;
diff --git a/chromium/net/test/url_request/url_request_mock_data_job.cc b/chromium/net/test/url_request/url_request_mock_data_job.cc
index 95492421a82..8c67dc5cf53 100644
--- a/chromium/net/test/url_request/url_request_mock_data_job.cc
+++ b/chromium/net/test/url_request/url_request_mock_data_job.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@@ -15,6 +16,7 @@
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
+#include "net/ssl/ssl_cert_request_info.h"
#include "net/url_request/url_request_filter.h"
namespace net {
@@ -47,16 +49,25 @@ int GetRepeatCountFromRequest(const URLRequest& request) {
return repeat_count;
}
+// Gets the requestcert flag from URL.
+bool GetRequestClientCertificate(const URLRequest& request) {
+ std::string ignored_value;
+ return GetValueForKeyInQuery(request.url(), "requestcert", &ignored_value);
+}
+
GURL GetMockUrl(const std::string& scheme,
const std::string& hostname,
const std::string& data,
- int data_repeat_count) {
+ int data_repeat_count,
+ bool request_client_certificate) {
DCHECK_GT(data_repeat_count, 0);
std::string url(scheme + "://" + hostname + "/");
url.append("?data=");
url.append(data);
url.append("&repeat=");
url.append(base::IntToString(data_repeat_count));
+ if (request_client_certificate)
+ url += "&requestcert=1";
return GURL(url);
}
@@ -71,7 +82,8 @@ class MockJobInterceptor : public URLRequestInterceptor {
NetworkDelegate* network_delegate) const override {
return new URLRequestMockDataJob(request, network_delegate,
GetDataFromRequest(*request),
- GetRepeatCountFromRequest(*request));
+ GetRepeatCountFromRequest(*request),
+ GetRequestClientCertificate(*request));
}
private:
@@ -83,9 +95,11 @@ class MockJobInterceptor : public URLRequestInterceptor {
URLRequestMockDataJob::URLRequestMockDataJob(URLRequest* request,
NetworkDelegate* network_delegate,
const std::string& data,
- int data_repeat_count)
+ int data_repeat_count,
+ bool request_client_certificate)
: URLRequestJob(request, network_delegate),
data_offset_(0),
+ request_client_certificate_(request_client_certificate),
weak_factory_(this) {
DCHECK_GT(data_repeat_count, 0);
for (int i = 0; i < data_repeat_count; ++i) {
@@ -104,15 +118,12 @@ void URLRequestMockDataJob::Start() {
URLRequestMockDataJob::~URLRequestMockDataJob() {
}
-bool URLRequestMockDataJob::ReadRawData(IOBuffer* buf,
- int buf_size,
- int* bytes_read) {
- DCHECK(bytes_read);
- *bytes_read = static_cast<int>(
- std::min(static_cast<size_t>(buf_size), data_.length() - data_offset_));
- memcpy(buf->data(), data_.c_str() + data_offset_, *bytes_read);
- data_offset_ += *bytes_read;
- return true;
+int URLRequestMockDataJob::ReadRawData(IOBuffer* buf, int buf_size) {
+ int bytes_read =
+ std::min(static_cast<size_t>(buf_size), data_.length() - data_offset_);
+ memcpy(buf->data(), data_.c_str() + data_offset_, bytes_read);
+ data_offset_ += bytes_read;
+ return bytes_read;
}
int URLRequestMockDataJob::GetResponseCode() const {
@@ -121,6 +132,13 @@ int URLRequestMockDataJob::GetResponseCode() const {
return info.headers->response_code();
}
+void URLRequestMockDataJob::ContinueWithCertificate(
+ X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key) {
+ DCHECK(request_client_certificate_);
+ NotifyHeadersComplete();
+}
+
// Public virtual version.
void URLRequestMockDataJob::GetResponseInfo(HttpResponseInfo* info) {
// Forward to private const version.
@@ -145,6 +163,11 @@ void URLRequestMockDataJob::StartAsync() {
return;
set_expected_content_size(data_.length());
+ if (request_client_certificate_) {
+ scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo());
+ NotifyCertificateRequested(request_all.get());
+ return;
+ }
NotifyHeadersComplete();
}
@@ -176,12 +199,16 @@ GURL URLRequestMockDataJob::GetMockHttpsUrl(const std::string& data,
return GetMockHttpsUrlForHostname(kMockHostname, data, repeat_count);
}
+GURL URLRequestMockDataJob::GetMockUrlForClientCertificateRequest() {
+ return GetMockUrl("https", kMockHostname, "data", 1, true);
+}
+
// static
GURL URLRequestMockDataJob::GetMockHttpUrlForHostname(
const std::string& hostname,
const std::string& data,
int repeat_count) {
- return GetMockUrl("http", hostname, data, repeat_count);
+ return GetMockUrl("http", hostname, data, repeat_count, false);
}
// static
@@ -189,7 +216,7 @@ GURL URLRequestMockDataJob::GetMockHttpsUrlForHostname(
const std::string& hostname,
const std::string& data,
int repeat_count) {
- return GetMockUrl("https", hostname, data, repeat_count);
+ return GetMockUrl("https", hostname, data, repeat_count, false);
}
} // namespace net
diff --git a/chromium/net/test/url_request/url_request_mock_data_job.h b/chromium/net/test/url_request/url_request_mock_data_job.h
index 3d84e371c35..ae33dd7dadb 100644
--- a/chromium/net/test/url_request/url_request_mock_data_job.h
+++ b/chromium/net/test/url_request/url_request_mock_data_job.h
@@ -5,6 +5,8 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_MOCK_DATA_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_MOCK_DATA_JOB_H_
+#include <stddef.h>
+
#include <string>
#include "base/memory/weak_ptr.h"
@@ -15,18 +17,23 @@ namespace net {
class URLRequest;
-// Mock data job, which synchronously returns data repeated multiple times.
+// Mock data job, which synchronously returns data repeated multiple times. If
+// |request_client_certificate| is true, then this job will request client
+// certificate before proceeding.
class URLRequestMockDataJob : public URLRequestJob {
public:
URLRequestMockDataJob(URLRequest* request,
NetworkDelegate* network_delegate,
const std::string& data,
- int data_repeat_count);
+ int data_repeat_count,
+ bool request_client_certificate);
void Start() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
int GetResponseCode() const override;
void GetResponseInfo(HttpResponseInfo* info) override;
+ void ContinueWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key) override;
// Adds the testing URLs to the URLRequestFilter.
static void AddUrlHandler();
@@ -38,6 +45,10 @@ class URLRequestMockDataJob : public URLRequestJob {
static GURL GetMockHttpUrl(const std::string& data, int repeat_count);
static GURL GetMockHttpsUrl(const std::string& data, int repeat_count);
+ // Constructs Mock URL which will request client certificate and return the
+ // word "data" as the response.
+ static GURL GetMockUrlForClientCertificateRequest();
+
// URLRequestFailedJob must be added as a handler for |hostname| for
// the returned URL to return |net_error|.
static GURL GetMockHttpUrlForHostname(const std::string& hostname,
@@ -55,6 +66,7 @@ class URLRequestMockDataJob : public URLRequestJob {
std::string data_;
size_t data_offset_;
+ bool request_client_certificate_;
base::WeakPtrFactory<URLRequestMockDataJob> weak_factory_;
};
diff --git a/chromium/net/test/url_request/url_request_mock_http_job.cc b/chromium/net/test/url_request/url_request_mock_http_job.cc
index c4efa6aa025..cf2cc6c8d8f 100644
--- a/chromium/net/test/url_request/url_request_mock_http_job.cc
+++ b/chromium/net/test/url_request/url_request_mock_http_job.cc
@@ -120,20 +120,6 @@ GURL URLRequestMockHTTPJob::GetMockHttpsUrl(const std::string& path) {
}
// static
-GURL URLRequestMockHTTPJob::GetMockUrl(const base::FilePath& path) {
- std::string path_str = path.MaybeAsASCII();
- DCHECK(!path_str.empty()); // We only expect ASCII paths in tests.
- return GetMockUrlForScheme(path_str, "http");
-}
-
-// static
-GURL URLRequestMockHTTPJob::GetMockHttpsUrl(const base::FilePath& path) {
- std::string path_str = path.MaybeAsASCII();
- DCHECK(!path_str.empty()); // We only expect ASCII paths in tests.
- return GetMockUrlForScheme(path_str, "https");
-}
-
-// static
scoped_ptr<URLRequestInterceptor> URLRequestMockHTTPJob::CreateInterceptor(
const base::FilePath& base_path,
const scoped_refptr<base::SequencedWorkerPool>& worker_pool) {
diff --git a/chromium/net/test/url_request/url_request_mock_http_job.h b/chromium/net/test/url_request/url_request_mock_http_job.h
index 70839f5292f..7a931fec5ca 100644
--- a/chromium/net/test/url_request/url_request_mock_http_job.h
+++ b/chromium/net/test/url_request/url_request_mock_http_job.h
@@ -51,11 +51,6 @@ class URLRequestMockHTTPJob : public URLRequestFileJob {
static GURL GetMockUrl(const std::string& path);
static GURL GetMockHttpsUrl(const std::string& path);
- // Like above, but takes a FilePath. These methods are deprecated. Prefer the
- // std::string versions. See http://crbug.com/496936.
- static GURL GetMockUrl(const base::FilePath& path);
- static GURL GetMockHttpsUrl(const base::FilePath& path);
-
// Returns a URLRequestJobFactory::ProtocolHandler that serves
// URLRequestMockHTTPJob's responding like an HTTP server. |base_path| is the
// file path leading to the root of the directory to use as the root of the
diff --git a/chromium/net/test/url_request/url_request_slow_download_job.cc b/chromium/net/test/url_request/url_request_slow_download_job.cc
index f344feb1c4d..ac4beb07530 100644
--- a/chromium/net/test/url_request/url_request_slow_download_job.cc
+++ b/chromium/net/test/url_request/url_request_slow_download_job.cc
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -179,39 +180,34 @@ URLRequestSlowDownloadJob::FillBufferHelper(IOBuffer* buf,
return REQUEST_COMPLETE;
}
-bool URLRequestSlowDownloadJob::ReadRawData(IOBuffer* buf,
- int buf_size,
- int* bytes_read) {
+int URLRequestSlowDownloadJob::ReadRawData(IOBuffer* buf, int buf_size) {
if (base::LowerCaseEqualsASCII(kFinishDownloadUrl,
request_->url().spec().c_str()) ||
base::LowerCaseEqualsASCII(kErrorDownloadUrl,
request_->url().spec().c_str())) {
VLOG(10) << __FUNCTION__ << " called w/ kFinish/ErrorDownloadUrl.";
- *bytes_read = 0;
- return true;
+ return 0;
}
VLOG(10) << __FUNCTION__ << " called at position " << bytes_already_sent_
<< " in the stream.";
- ReadStatus status = FillBufferHelper(buf, buf_size, bytes_read);
+ int bytes_read = 0;
+ ReadStatus status = FillBufferHelper(buf, buf_size, &bytes_read);
switch (status) {
case BUFFER_FILLED:
- return true;
+ case REQUEST_COMPLETE:
+ return bytes_read;
case REQUEST_BLOCKED:
buffer_ = buf;
buffer_size_ = buf_size;
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::Bind(&URLRequestSlowDownloadJob::CheckDoneStatus,
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(100));
- return false;
- case REQUEST_COMPLETE:
- *bytes_read = 0;
- return true;
+ return ERR_IO_PENDING;
}
NOTREACHED();
- return true;
+ return OK;
}
void URLRequestSlowDownloadJob::CheckDoneStatus() {
@@ -223,12 +219,10 @@ void URLRequestSlowDownloadJob::CheckDoneStatus() {
FillBufferHelper(buffer_.get(), buffer_size_, &bytes_written);
DCHECK_EQ(BUFFER_FILLED, status);
buffer_ = NULL; // Release the reference.
- SetStatus(URLRequestStatus());
- NotifyReadComplete(bytes_written);
+ ReadRawDataComplete(bytes_written);
} else if (should_error_download_) {
VLOG(10) << __FUNCTION__ << " called w/ should_finish_ownload_ set.";
- NotifyDone(
- URLRequestStatus(URLRequestStatus::FAILED, ERR_CONNECTION_RESET));
+ ReadRawDataComplete(ERR_CONNECTION_RESET);
} else {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::Bind(&URLRequestSlowDownloadJob::CheckDoneStatus,
diff --git a/chromium/net/test/url_request/url_request_slow_download_job.h b/chromium/net/test/url_request/url_request_slow_download_job.h
index 115a6ac7e7d..5ab4ccd8353 100644
--- a/chromium/net/test/url_request/url_request_slow_download_job.h
+++ b/chromium/net/test/url_request/url_request_slow_download_job.h
@@ -8,6 +8,8 @@
#ifndef NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_
#define NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_
+#include <stddef.h>
+
#include <set>
#include <string>
@@ -37,7 +39,7 @@ class URLRequestSlowDownloadJob : public URLRequestJob {
void Start() override;
bool GetMimeType(std::string* mime_type) const override;
void GetResponseInfo(HttpResponseInfo* info) override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
// Returns the current number of URLRequestSlowDownloadJobs that have
// not yet completed.
diff --git a/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp b/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
index bfbeae6a299..a79d52eac5a 100644
--- a/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
+++ b/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
@@ -44,6 +44,7 @@
#include <secerr.h>
#include "base/logging.h"
+#include "crypto/scoped_nss_types.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_nss.h"
@@ -206,6 +207,37 @@ bool ImportServerCert(
return true;
}
+// Based on nsNSSCertificateDB::ImportUserCertificate.
+int ImportUserCert(const net::CertificateList& certificates) {
+ if (certificates.empty())
+ return net::ERR_CERT_INVALID;
+
+ const scoped_refptr<net::X509Certificate>& cert = certificates[0];
+ CK_OBJECT_HANDLE key;
+ crypto::ScopedPK11Slot slot(
+ PK11_KeyForCertExists(cert->os_cert_handle(), &key, NULL));
+
+ if (!slot.get())
+ return net::ERR_NO_PRIVATE_KEY_FOR_CERT;
+
+ // Mozilla uses CERT_ImportCerts, which doesn't take a slot arg. We use
+ // PK11_ImportCert instead.
+ SECStatus srv =
+ PK11_ImportCert(slot.get(), cert->os_cert_handle(), key,
+ net::x509_util::GetUniqueNicknameForSlot(
+ cert->GetDefaultNickname(net::USER_CERT),
+ &cert->os_cert_handle()->derSubject, slot.get())
+ .c_str(),
+ PR_FALSE /* includeTrust (unused) */);
+
+ if (srv != SECSuccess) {
+ LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError();
+ return net::ERR_ADD_USER_CERT_FAILED;
+ }
+
+ return net::OK;
+}
+
// Based on nsNSSCertificateDB::SetCertTrust.
bool
SetCertTrust(const net::X509Certificate* cert,
diff --git a/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h b/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h
index 990fdbc4cff..285474bb909 100644
--- a/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h
+++ b/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h
@@ -65,6 +65,8 @@ bool ImportServerCert(
net::NSSCertDatabase::TrustBits trustBits,
net::NSSCertDatabase::ImportCertFailureList* not_imported);
+int ImportUserCert(const net::CertificateList& certificates);
+
bool SetCertTrust(const net::X509Certificate* cert,
net::CertType type,
net::NSSCertDatabase::TrustBits trustBits);
diff --git a/chromium/net/third_party/mozilla_security_manager/nsPKCS12Blob.h b/chromium/net/third_party/mozilla_security_manager/nsPKCS12Blob.h
index a2f2a490ab6..1a87c060dce 100644
--- a/chromium/net/third_party/mozilla_security_manager/nsPKCS12Blob.h
+++ b/chromium/net/third_party/mozilla_security_manager/nsPKCS12Blob.h
@@ -38,6 +38,8 @@
#ifndef NET_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSPKCS12BLOB_H_
#define NET_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSPKCS12BLOB_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
diff --git a/chromium/net/third_party/nss/README.chromium b/chromium/net/third_party/nss/README.chromium
index f47896df4dc..02700b86409 100644
--- a/chromium/net/third_party/nss/README.chromium
+++ b/chromium/net/third_party/nss/README.chromium
@@ -1,6 +1,6 @@
Name: Network Security Services (NSS)
URL: http://www.mozilla.org/projects/security/pki/nss/
-Version: 3.19 RTM
+Version: 3.21 RTM
Security Critical: Yes
License: MPL 2
License File: NOT_SHIPPED
@@ -11,7 +11,7 @@ This directory includes a copy of NSS's libssl from the hg repo at:
The same module appears in crypto/third_party/nss (and third_party/nss on some
platforms), so we don't repeat the license file here.
-The snapshot was updated to the hg tag: NSS_3_19_RTM
+The snapshot was updated to the hg tag: NSS_3_21_RTM
Patches:
@@ -100,16 +100,6 @@ Patches:
length.
patches/reorderextensions.patch
- * Make the build metadata deterministic
- patches/removebuildmetadata.patch
-
- * Fix locking bug in ssl3_HandleHelloRequest when rejecting a renegotiation.
- patches/norenegotiatelock.patch
- https://bugzilla.mozilla.org/show_bug.cgi?id=1162521
-
- * Increase the minimum DH group size to 1024
- patches/dh1024.patch
-
Apply the patches to NSS by running the patches/applypatches.sh script. Read
the comments at the top of patches/applypatches.sh for instructions.
diff --git a/chromium/net/third_party/nss/patches/aesgcmchromium.patch b/chromium/net/third_party/nss/patches/aesgcmchromium.patch
index 6172a0928a4..b144e9494fa 100644
--- a/chromium/net/third_party/nss/patches/aesgcmchromium.patch
+++ b/chromium/net/third_party/nss/patches/aesgcmchromium.patch
@@ -1,7 +1,7 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 1167d6d..dabe333 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index c5cb1eb..299e414 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
@@ -8,6 +8,7 @@
/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
@@ -10,7 +10,7 @@ index 1167d6d..dabe333 100644
#include "cert.h"
#include "ssl.h"
#include "cryptohi.h" /* for DSAU_ stuff */
-@@ -44,6 +45,9 @@
+@@ -46,6 +47,9 @@
#ifdef NSS_ENABLE_ZLIB
#include "zlib.h"
#endif
@@ -20,7 +20,7 @@ index 1167d6d..dabe333 100644
#ifndef PK11_SETATTRS
#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
-@@ -1874,6 +1878,63 @@ ssl3_BuildRecordPseudoHeader(unsigned char *out,
+@@ -1897,6 +1901,63 @@ ssl3_BuildRecordPseudoHeader(unsigned char *out,
return 13;
}
@@ -84,7 +84,7 @@ index 1167d6d..dabe333 100644
static SECStatus
ssl3_AESGCM(ssl3KeyMaterial *keys,
PRBool doDecrypt,
-@@ -1925,10 +1986,10 @@ ssl3_AESGCM(ssl3KeyMaterial *keys,
+@@ -1948,10 +2009,10 @@ ssl3_AESGCM(ssl3KeyMaterial *keys,
gcmParams.ulTagBits = tagSize * 8;
if (doDecrypt) {
@@ -97,7 +97,7 @@ index 1167d6d..dabe333 100644
maxout, in, inlen);
}
*outlen += (int) uOutLen;
-@@ -5162,6 +5223,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5337,6 +5398,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
ssl3_DisableNonDTLSSuites(ss);
}
@@ -108,7 +108,7 @@ index 1167d6d..dabe333 100644
/* how many suites are permitted by policy and user preference? */
num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
if (!num_suites) {
-@@ -8172,6 +8237,10 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -8400,6 +8465,10 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ssl3_DisableNonDTLSSuites(ss);
}
diff --git a/chromium/net/third_party/nss/patches/applypatches.sh b/chromium/net/third_party/nss/patches/applypatches.sh
index 90634e904d2..faf850a444d 100755
--- a/chromium/net/third_party/nss/patches/applypatches.sh
+++ b/chromium/net/third_party/nss/patches/applypatches.sh
@@ -46,9 +46,3 @@ patch -p2 < $patches_dir/sessioncache.patch
patch -p2 < $patches_dir/nssrwlock.patch
patch -p2 < $patches_dir/reorderextensions.patch
-
-patch -p2 < $patches_dir/removebuildmetadata.patch
-
-patch -p2 < $patches_dir/norenegotiatelock.patch
-
-patch -p2 < $patches_dir/dh1024.patch
diff --git a/chromium/net/third_party/nss/patches/cachecerts.patch b/chromium/net/third_party/nss/patches/cachecerts.patch
index 18fcc242962..1e0e3135c8c 100644
--- a/chromium/net/third_party/nss/patches/cachecerts.patch
+++ b/chromium/net/third_party/nss/patches/cachecerts.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 163572c..60af5b0 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -43,6 +43,7 @@
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 8f1c547..9aaf601 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -45,6 +45,7 @@
static SECStatus ssl3_AuthCertificate(sslSocket *ss);
static void ssl3_CleanupPeerCerts(sslSocket *ss);
@@ -10,15 +10,15 @@ index 163572c..60af5b0 100644
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PK11SlotInfo * serverKeySlot);
static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
-@@ -6549,6 +6550,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -6751,6 +6752,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* copy the peer cert from the SID */
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
+ ssl3_CopyPeerCertsFromSID(ss, sid);
}
- /* NULL value for PMS signifies re-use of the old MS */
-@@ -8140,6 +8142,7 @@ compression_found:
+ /* NULL value for PMS because we are reusing the old MS */
+@@ -8405,6 +8407,7 @@ compression_found:
ss->sec.ci.sid = sid;
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
@@ -26,7 +26,7 @@ index 163572c..60af5b0 100644
}
/*
-@@ -9763,6 +9766,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
+@@ -10389,6 +10392,44 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
ss->ssl3.peerCertChain = NULL;
}
@@ -71,7 +71,7 @@ index 163572c..60af5b0 100644
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 CertificateStatus message.
* Caller must hold Handshake and RecvBuf locks.
-@@ -10041,6 +10082,7 @@ ssl3_AuthCertificate(sslSocket *ss)
+@@ -10669,6 +10710,7 @@ ssl3_AuthCertificate(sslSocket *ss)
}
ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
@@ -79,11 +79,11 @@ index 163572c..60af5b0 100644
if (!ss->sec.isServer) {
CERTCertificate *cert = ss->sec.peerCert;
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index 1b38a52..086f6d2 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -597,6 +597,8 @@ typedef enum { never_cached,
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index ad31aae..9dcc29e 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -608,6 +608,8 @@ typedef enum { never_cached,
invalid_cache /* no longer in any cache. */
} Cached;
@@ -92,7 +92,7 @@ index 1b38a52..086f6d2 100644
struct sslSessionIDStr {
/* The global cache lock must be held when accessing these members when the
* sid is in any cache.
-@@ -611,6 +613,7 @@ struct sslSessionIDStr {
+@@ -622,6 +624,7 @@ struct sslSessionIDStr {
*/
CERTCertificate * peerCert;
@@ -100,10 +100,10 @@ index 1b38a52..086f6d2 100644
SECItemArray peerCertStatus; /* client only */
const char * peerID; /* client only */
const char * urlSvrName; /* client only */
-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c
+diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c
index 2e861f1..be11008 100644
---- a/ssl/sslnonce.c
-+++ b/ssl/sslnonce.c
+--- a/lib/ssl/sslnonce.c
++++ b/lib/ssl/sslnonce.c
@@ -164,6 +164,7 @@ lock_cache(void)
static void
ssl_DestroySID(sslSessionID *sid)
diff --git a/chromium/net/third_party/nss/patches/cachelocks.patch b/chromium/net/third_party/nss/patches/cachelocks.patch
index 66a539b3476..d2bde5f8093 100644
--- a/chromium/net/third_party/nss/patches/cachelocks.patch
+++ b/chromium/net/third_party/nss/patches/cachelocks.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 6819b03..6a4a443 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -5748,7 +5748,6 @@ SSL3_ShutdownServerCache(void)
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 2533679..ba3d012 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -5921,7 +5921,6 @@ SSL3_ShutdownServerCache(void)
}
PZ_Unlock(symWrapKeysLock);
@@ -10,7 +10,7 @@ index 6819b03..6a4a443 100644
return SECSuccess;
}
-@@ -5800,7 +5799,7 @@ getWrappingKey( sslSocket * ss,
+@@ -5973,7 +5972,7 @@ getWrappingKey( sslSocket * ss,
pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType];
@@ -19,11 +19,11 @@ index 6819b03..6a4a443 100644
PZ_Lock(symWrapKeysLock);
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index 88b2eba..c4c87b4 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -1924,9 +1924,7 @@ extern SECStatus ssl_InitSymWrapKeysLock(void);
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index d5f326f..d53c446 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -1957,9 +1957,7 @@ extern SECStatus ssl_InitSymWrapKeysLock(void);
extern SECStatus ssl_FreeSymWrapKeysLock(void);
@@ -34,10 +34,10 @@ index 88b2eba..c4c87b4 100644
/***************** platform client auth ****************/
-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c
+diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c
index 1326a8b..c45849d 100644
---- a/ssl/sslnonce.c
-+++ b/ssl/sslnonce.c
+--- a/lib/ssl/sslnonce.c
++++ b/lib/ssl/sslnonce.c
@@ -35,91 +35,55 @@ static PZLock * cacheLock = NULL;
#define LOCK_CACHE lock_cache()
#define UNLOCK_CACHE PZ_Unlock(cacheLock)
@@ -204,11 +204,11 @@ index 1326a8b..c45849d 100644
PZ_Lock(cacheLock);
}
-diff --git a/ssl/sslsnce.c b/ssl/sslsnce.c
-index 4d9ef38..3279200 100644
---- a/ssl/sslsnce.c
-+++ b/ssl/sslsnce.c
-@@ -1352,7 +1352,7 @@ SSL_ConfigServerSessionIDCache( int maxCacheEntries,
+diff --git a/lib/ssl/sslsnce.c b/lib/ssl/sslsnce.c
+index f31b2e9..3856c13 100644
+--- a/lib/ssl/sslsnce.c
++++ b/lib/ssl/sslsnce.c
+@@ -1363,7 +1363,7 @@ SSL_ConfigServerSessionIDCache( int maxCacheEntries,
PRUint32 ssl3_timeout,
const char * directory)
{
@@ -217,7 +217,7 @@ index 4d9ef38..3279200 100644
return SSL_ConfigServerSessionIDCacheInstance(&globalCache,
maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE);
}
-@@ -1466,7 +1466,7 @@ SSL_ConfigServerSessionIDCacheWithOpt(
+@@ -1477,7 +1477,7 @@ SSL_ConfigServerSessionIDCacheWithOpt(
PRBool enableMPCache)
{
if (!enableMPCache) {
@@ -226,7 +226,7 @@ index 4d9ef38..3279200 100644
return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache,
ssl2_timeout, ssl3_timeout, directory, PR_FALSE,
maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
-@@ -1511,7 +1511,7 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
+@@ -1521,7 +1521,7 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
return SECSuccess; /* already done. */
}
diff --git a/chromium/net/third_party/nss/patches/chacha20poly1305.patch b/chromium/net/third_party/nss/patches/chacha20poly1305.patch
index a9017f12504..e4c78017d9a 100644
--- a/chromium/net/third_party/nss/patches/chacha20poly1305.patch
+++ b/chromium/net/third_party/nss/patches/chacha20poly1305.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index dabe333..6819b03 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -41,6 +41,21 @@
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 299e414..2533679 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -43,6 +43,21 @@
#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
#endif
@@ -24,16 +24,16 @@ index dabe333..6819b03 100644
#include <stdio.h>
#ifdef NSS_ENABLE_ZLIB
#include "zlib.h"
-@@ -105,6 +120,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
+@@ -110,6 +125,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
/* cipher_suite policy enabled isPresent */
#ifndef NSS_DISABLE_ECC
+ { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around
-@@ -296,6 +313,7 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = {
+@@ -307,6 +324,7 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = {
{cipher_camellia_256, calg_camellia, 32,32, type_block, 16,16, 0, 0},
{cipher_seed, calg_seed, 16,16, type_block, 16,16, 0, 0},
{cipher_aes_128_gcm, calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8},
@@ -41,16 +41,16 @@ index dabe333..6819b03 100644
{cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0},
};
-@@ -422,6 +440,8 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] =
+@@ -433,6 +451,8 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] =
{TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa},
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa},
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa},
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_rsa},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa},
- #ifndef NSS_DISABLE_ECC
- {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa},
-@@ -487,6 +507,7 @@ static const SSLCipher2Mech alg2Mech[] = {
+ {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss},
+ {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss},
+@@ -502,6 +522,7 @@ static const SSLCipher2Mech alg2Mech[] = {
{ calg_camellia , CKM_CAMELLIA_CBC },
{ calg_seed , CKM_SEED_CBC },
{ calg_aes_gcm , CKM_AES_GCM },
@@ -58,7 +58,7 @@ index dabe333..6819b03 100644
/* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */
};
-@@ -662,6 +683,8 @@ ssl3_CipherSuiteAllowedForVersionRange(
+@@ -679,6 +700,8 @@ ssl3_CipherSuiteAllowedForVersionRange(
case TLS_RSA_WITH_NULL_SHA256:
return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2;
@@ -67,7 +67,7 @@ index dabe333..6819b03 100644
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
-@@ -2070,6 +2093,46 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys,
+@@ -2093,6 +2116,46 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys,
}
#endif
@@ -114,7 +114,7 @@ index dabe333..6819b03 100644
/* Initialize encryption and MAC contexts for pending spec.
* Master Secret already is derived.
* Caller holds Spec write lock.
-@@ -2103,13 +2166,17 @@ ssl3_InitPendingContextsPKCS11(sslSocket *ss)
+@@ -2126,13 +2189,17 @@ ssl3_InitPendingContextsPKCS11(sslSocket *ss)
pwSpec->client.write_mac_context = NULL;
pwSpec->server.write_mac_context = NULL;
@@ -134,11 +134,11 @@ index dabe333..6819b03 100644
return SECSuccess;
}
-diff --git a/ssl/ssl3ecc.c b/ssl/ssl3ecc.c
-index 9b91270..31e0774 100644
---- a/ssl/ssl3ecc.c
-+++ b/ssl/ssl3ecc.c
-@@ -921,6 +921,7 @@ static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
+diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c
+index cf8e741..ab5ab14 100644
+--- a/lib/ssl/ssl3ecc.c
++++ b/lib/ssl/ssl3ecc.c
+@@ -926,6 +926,7 @@ static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
@@ -146,7 +146,7 @@ index 9b91270..31e0774 100644
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
0 /* end of list marker */
-@@ -932,6 +933,7 @@ static const ssl3CipherSuite ecdhe_rsa_suites[] = {
+@@ -937,6 +938,7 @@ static const ssl3CipherSuite ecdhe_rsa_suites[] = {
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
@@ -154,7 +154,7 @@ index 9b91270..31e0774 100644
TLS_ECDHE_RSA_WITH_NULL_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
0 /* end of list marker */
-@@ -944,6 +946,7 @@ static const ssl3CipherSuite ecSuites[] = {
+@@ -949,6 +951,7 @@ static const ssl3CipherSuite ecSuites[] = {
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
@@ -162,7 +162,7 @@ index 9b91270..31e0774 100644
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-@@ -951,6 +954,7 @@ static const ssl3CipherSuite ecSuites[] = {
+@@ -956,6 +959,7 @@ static const ssl3CipherSuite ecSuites[] = {
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
@@ -170,10 +170,10 @@ index 9b91270..31e0774 100644
TLS_ECDHE_RSA_WITH_NULL_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
-diff --git a/ssl/sslenum.c b/ssl/sslenum.c
-index 09ce43f..a036627 100644
---- a/ssl/sslenum.c
-+++ b/ssl/sslenum.c
+diff --git a/lib/ssl/sslenum.c b/lib/ssl/sslenum.c
+index f69aed2..b4a8844 100644
+--- a/lib/ssl/sslenum.c
++++ b/lib/ssl/sslenum.c
@@ -37,17 +37,21 @@
*
* Exception: Because some servers ignore the high-order byte of the cipher
@@ -199,11 +199,11 @@ index 09ce43f..a036627 100644
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA must appear before
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index ea71975..88b2eba 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -65,6 +65,7 @@ typedef SSLSignType SSL3SignType;
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index 60dd243..d5f326f 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -66,6 +66,7 @@ typedef SSLSignType SSL3SignType;
#define calg_camellia ssl_calg_camellia
#define calg_seed ssl_calg_seed
#define calg_aes_gcm ssl_calg_aes_gcm
@@ -211,16 +211,16 @@ index ea71975..88b2eba 100644
#define mac_null ssl_mac_null
#define mac_md5 ssl_mac_md5
-@@ -299,7 +300,7 @@ typedef struct {
+@@ -301,7 +302,7 @@ typedef struct {
} ssl3CipherSuiteCfg;
#ifndef NSS_DISABLE_ECC
--#define ssl_V3_SUITES_IMPLEMENTED 61
-+#define ssl_V3_SUITES_IMPLEMENTED 63
+-#define ssl_V3_SUITES_IMPLEMENTED 64
++#define ssl_V3_SUITES_IMPLEMENTED 66
#else
- #define ssl_V3_SUITES_IMPLEMENTED 37
+ #define ssl_V3_SUITES_IMPLEMENTED 40
#endif /* NSS_DISABLE_ECC */
-@@ -485,6 +486,7 @@ typedef enum {
+@@ -495,6 +496,7 @@ typedef enum {
cipher_camellia_256,
cipher_seed,
cipher_aes_128_gcm,
@@ -228,11 +228,11 @@ index ea71975..88b2eba 100644
cipher_missing /* reserved for no such supported cipher */
/* This enum must match ssl3_cipherName[] in ssl3con.c. */
} SSL3BulkCipher;
-diff --git a/ssl/sslinfo.c b/ssl/sslinfo.c
-index ba230d2..845d9f0 100644
---- a/ssl/sslinfo.c
-+++ b/ssl/sslinfo.c
-@@ -110,6 +110,7 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
+diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c
+index 7048eb8..bef3190 100644
+--- a/lib/ssl/sslinfo.c
++++ b/lib/ssl/sslinfo.c
+@@ -148,6 +148,7 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
#define C_NULL "NULL", calg_null
#define C_SJ "SKIPJACK", calg_sj
#define C_AESGCM "AES-GCM", calg_aes_gcm
@@ -240,7 +240,7 @@ index ba230d2..845d9f0 100644
#define B_256 256, 256, 256
#define B_128 128, 128, 128
-@@ -188,12 +189,14 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
+@@ -229,12 +230,14 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
@@ -255,11 +255,11 @@ index ba230d2..845d9f0 100644
{0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
-diff --git a/ssl/sslproto.h b/ssl/sslproto.h
-index e02442c..dc653c9 100644
---- a/ssl/sslproto.h
-+++ b/ssl/sslproto.h
-@@ -258,6 +258,9 @@
+diff --git a/lib/ssl/sslproto.h b/lib/ssl/sslproto.h
+index 2db47a5..36ae6c9 100644
+--- a/lib/ssl/sslproto.h
++++ b/lib/ssl/sslproto.h
+@@ -260,6 +260,9 @@
#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F
#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031
@@ -269,11 +269,11 @@ index e02442c..dc653c9 100644
/* Netscape "experimental" cipher suites. */
#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
-diff --git a/ssl/sslt.h b/ssl/sslt.h
-index 430d216..fe0ad07 100644
---- a/ssl/sslt.h
-+++ b/ssl/sslt.h
-@@ -94,7 +94,8 @@ typedef enum {
+diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
+index 5593579..a2eff62 100644
+--- a/lib/ssl/sslt.h
++++ b/lib/ssl/sslt.h
+@@ -117,7 +117,8 @@ typedef enum {
ssl_calg_aes = 7,
ssl_calg_camellia = 8,
ssl_calg_seed = 9,
diff --git a/chromium/net/third_party/nss/patches/channelid.patch b/chromium/net/third_party/nss/patches/channelid.patch
index e2b985470cf..58b0ae7d1ae 100644
--- a/chromium/net/third_party/nss/patches/channelid.patch
+++ b/chromium/net/third_party/nss/patches/channelid.patch
@@ -1,25 +1,25 @@
-diff --git a/ssl/SSLerrs.h b/ssl/SSLerrs.h
-index 174037b..81da41c 100644
---- a/ssl/SSLerrs.h
-+++ b/ssl/SSLerrs.h
-@@ -422,3 +422,12 @@ ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130),
- ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131),
- "The server rejected the handshake because the client downgraded to a lower "
- "TLS version than the server supports.")
-+
-+ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 132),
+diff --git a/lib/ssl/SSLerrs.h b/lib/ssl/SSLerrs.h
+index 6028396..3d21ab8 100644
+--- a/lib/ssl/SSLerrs.h
++++ b/lib/ssl/SSLerrs.h
+@@ -440,3 +440,12 @@ ER3(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 136),
+
+ ER3(SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 137),
+ "The peer tried to resume with an unexpected extended_master_secret extension")
++
++ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 138),
+"SSL received a malformed TLS Channel ID extension.")
+
-+ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 133),
++ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 139),
+"The application provided an invalid TLS Channel ID key.")
+
-+ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 134),
++ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 140),
+"The application could not get a TLS Channel ID.")
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 593dd00..716537d 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -1025,6 +1025,34 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index 85ced8a..120c257 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -1135,6 +1135,34 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
SSL_IMPORT SECStatus SSL_HandshakeResumedSession(PRFileDesc *fd,
PRBool *last_handshake_resumed);
@@ -54,11 +54,11 @@ index 593dd00..716537d 100644
/*
** How long should we wait before retransmitting the next flight of
** the DTLS handshake? Returns SECFailure if not DTLS or not in a
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 29e8f1c..c0e8e79 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -55,6 +55,7 @@ static SECStatus ssl3_SendCertificateStatus( sslSocket *ss);
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 304e03b..2ae8ce9 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -57,6 +57,7 @@ static SECStatus ssl3_SendCertificateStatus( sslSocket *ss);
static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
static SECStatus ssl3_SendNextProto( sslSocket *ss);
@@ -66,7 +66,7 @@ index 29e8f1c..c0e8e79 100644
static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
static SECStatus ssl3_SendServerHello( sslSocket *ss);
static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
-@@ -6296,6 +6297,15 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -6470,6 +6471,15 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
#endif /* NSS_PLATFORM_CLIENT_AUTH */
@@ -82,7 +82,7 @@ index 29e8f1c..c0e8e79 100644
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (temp < 0) {
goto loser; /* alert has been sent */
-@@ -6578,7 +6588,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -6780,7 +6790,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) {
goto alert_loser; /* err code was set */
}
@@ -91,9 +91,9 @@ index 29e8f1c..c0e8e79 100644
} while (0);
if (sid_match)
-@@ -6613,6 +6623,27 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- } else {
- ss->ssl3.hs.ws = wait_cert_request;
+@@ -6819,6 +6829,27 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ PORT_Assert(ss->ssl3.hs.kea_def->ephemeral);
+ ss->ssl3.hs.ws = wait_server_key;
}
+
+winner:
@@ -119,7 +119,7 @@ index 29e8f1c..c0e8e79 100644
return SECSuccess;
alert_loser:
-@@ -7565,7 +7596,14 @@ ssl3_SendClientSecondRound(sslSocket *ss)
+@@ -7774,7 +7805,14 @@ ssl3_SendClientSecondRound(sslSocket *ss)
if (rv != SECSuccess) {
goto loser; /* err code was set. */
}
@@ -134,7 +134,7 @@ index 29e8f1c..c0e8e79 100644
if (ss->opt.enableFalseStart) {
if (!ss->ssl3.hs.authCertificatePending) {
/* When we fix bug 589047, we will need to know whether we are
-@@ -7602,6 +7640,33 @@ ssl3_SendClientSecondRound(sslSocket *ss)
+@@ -7811,6 +7849,33 @@ ssl3_SendClientSecondRound(sslSocket *ss)
ssl_ReleaseXmitBufLock(ss); /*******************************/
@@ -168,7 +168,7 @@ index 29e8f1c..c0e8e79 100644
if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
ss->ssl3.hs.ws = wait_new_session_ticket;
else
-@@ -10590,6 +10655,184 @@ ssl3_RecordKeyLog(sslSocket *ss)
+@@ -11264,6 +11329,184 @@ ssl3_RecordKeyLog(sslSocket *ss)
}
/* called from ssl3_SendClientSecondRound
@@ -353,7 +353,7 @@ index 29e8f1c..c0e8e79 100644
* ssl3_HandleClientHello
* ssl3_HandleFinished
*/
-@@ -10849,11 +11092,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+@@ -11531,11 +11774,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
}
@@ -374,7 +374,7 @@ index 29e8f1c..c0e8e79 100644
}
if (IS_DTLS(ss)) {
-@@ -12333,6 +12581,11 @@ ssl3_DestroySSL3Info(sslSocket *ss)
+@@ -13095,6 +13343,11 @@ ssl3_DestroySSL3Info(sslSocket *ss)
ssl_FreePlatformKey(ss->ssl3.platformClientKey);
#endif /* NSS_PLATFORM_CLIENT_AUTH */
@@ -386,10 +386,10 @@ index 29e8f1c..c0e8e79 100644
if (ss->ssl3.peerCertArena != NULL)
ssl3_CleanupPeerCerts(ss);
-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c
-index 0a2288a..4d17587 100644
---- a/ssl/ssl3ext.c
-+++ b/ssl/ssl3ext.c
+diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c
+index 5661a5c..78825cb 100644
+--- a/lib/ssl/ssl3ext.c
++++ b/lib/ssl/ssl3ext.c
@@ -73,6 +73,10 @@ static SECStatus ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
SECItem *data);
static SECStatus ssl3_ServerHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
@@ -401,15 +401,15 @@ index 0a2288a..4d17587 100644
static PRInt32 ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
PRBool append, PRUint32 maxBytes);
static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
-@@ -269,6 +273,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
+@@ -276,6 +280,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
{ ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
{ ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
{ ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
+ { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
{ -1, NULL }
- };
-@@ -296,6 +301,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
+@@ -304,6 +309,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
{ ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
{ ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
{ ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
@@ -417,7 +417,7 @@ index 0a2288a..4d17587 100644
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
{ ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
-@@ -930,6 +936,61 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
+@@ -945,6 +951,61 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
}
static SECStatus
@@ -479,10 +479,10 @@ index 0a2288a..4d17587 100644
ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data)
{
-diff --git a/ssl/ssl3prot.h b/ssl/ssl3prot.h
-index 485d7dd..78fbcaa 100644
---- a/ssl/ssl3prot.h
-+++ b/ssl/ssl3prot.h
+diff --git a/lib/ssl/ssl3prot.h b/lib/ssl/ssl3prot.h
+index a93bef1..848bdee 100644
+--- a/lib/ssl/ssl3prot.h
++++ b/lib/ssl/ssl3prot.h
@@ -136,7 +136,8 @@ typedef enum {
client_key_exchange = 16,
finished = 20,
@@ -493,10 +493,10 @@ index 485d7dd..78fbcaa 100644
} SSL3HandshakeType;
typedef struct {
-diff --git a/ssl/sslauth.c b/ssl/sslauth.c
-index 7f9c43b..c2d9201 100644
---- a/ssl/sslauth.c
-+++ b/ssl/sslauth.c
+diff --git a/lib/ssl/sslauth.c b/lib/ssl/sslauth.c
+index e6981f0..03b23b4 100644
+--- a/lib/ssl/sslauth.c
++++ b/lib/ssl/sslauth.c
@@ -216,6 +216,24 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
return SECSuccess;
}
@@ -522,26 +522,26 @@ index 7f9c43b..c2d9201 100644
#ifdef NSS_PLATFORM_CLIENT_AUTH
/* NEED LOCKS IN HERE. */
SECStatus
-diff --git a/ssl/sslerr.h b/ssl/sslerr.h
-index 12dbb1d..24bf893 100644
---- a/ssl/sslerr.h
-+++ b/ssl/sslerr.h
-@@ -198,6 +198,10 @@ SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
-
- SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131),
+diff --git a/lib/ssl/sslerr.h b/lib/ssl/sslerr.h
+index 192a107..835b812 100644
+--- a/lib/ssl/sslerr.h
++++ b/lib/ssl/sslerr.h
+@@ -208,6 +208,10 @@ SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135),
+ SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136),
+ SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137),
-+SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 132),
-+SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 133),
-+SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 134),
++SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 138),
++SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 139),
++SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 140),
+
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index 2cf0b3a..e11860e 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -711,6 +711,14 @@ struct sslSessionIDStr {
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index c089889..c286518 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -722,6 +722,14 @@ struct sslSessionIDStr {
SECItem srvName;
@@ -556,7 +556,7 @@ index 2cf0b3a..e11860e 100644
/* This lock is lazily initialized by CacheSID when a sid is first
* cached. Before then, there is no need to lock anything because
* the sid isn't being shared by anything.
-@@ -986,6 +994,9 @@ struct ssl3StateStr {
+@@ -999,6 +1007,9 @@ struct ssl3StateStr {
CERTCertificateList *clientCertChain; /* used by client */
PRBool sendEmptyCert; /* used by client */
@@ -566,7 +566,7 @@ index 2cf0b3a..e11860e 100644
int policy;
/* This says what cipher suites we can do, and should
* be either SSL_ALLOWED or SSL_RESTRICTED
-@@ -1264,6 +1275,8 @@ const unsigned char * preferredCipher;
+@@ -1294,6 +1305,8 @@ const unsigned char * preferredCipher;
void *pkcs11PinArg;
SSLNextProtoCallback nextProtoCallback;
void *nextProtoArg;
@@ -575,7 +575,7 @@ index 2cf0b3a..e11860e 100644
PRIntervalTime rTimeout; /* timeout for NSPR I/O */
PRIntervalTime wTimeout; /* timeout for NSPR I/O */
-@@ -1610,6 +1623,11 @@ extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
+@@ -1640,6 +1653,11 @@ extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
SECKEYPrivateKey * key,
CERTCertificateList *certChain);
@@ -587,10 +587,10 @@ index 2cf0b3a..e11860e 100644
extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
/*
-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c
+diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c
index be11008..1326a8b 100644
---- a/ssl/sslnonce.c
-+++ b/ssl/sslnonce.c
+--- a/lib/ssl/sslnonce.c
++++ b/lib/ssl/sslnonce.c
@@ -180,6 +180,9 @@ ssl_DestroySID(sslSessionID *sid)
if (sid->u.ssl3.srvName.data) {
SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
@@ -601,11 +601,11 @@ index be11008..1326a8b 100644
if (sid->u.ssl3.lock) {
PR_DestroyRWLock(sid->u.ssl3.lock);
-diff --git a/ssl/sslsecur.c b/ssl/sslsecur.c
-index d44336e..5c6751a 100644
---- a/ssl/sslsecur.c
-+++ b/ssl/sslsecur.c
-@@ -1582,6 +1582,42 @@ SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd,
+diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c
+index f77d6fa..cca55bb 100644
+--- a/lib/ssl/sslsecur.c
++++ b/lib/ssl/sslsecur.c
+@@ -1598,6 +1598,42 @@ SSL_RestartHandshakeAfterCertReq(PRFileDesc * fd,
return ret;
}
@@ -648,11 +648,11 @@ index d44336e..5c6751a 100644
/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
* this implementation exists to maintain link-time compatibility.
*/
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 9431fe4..042f24f 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -288,6 +288,8 @@ ssl_DupSocket(sslSocket *os)
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index 11e66f2..efba686 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -313,6 +313,8 @@ ssl_DupSocket(sslSocket *os)
ss->canFalseStartCallback = os->canFalseStartCallback;
ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
ss->pkcs11PinArg = os->pkcs11PinArg;
@@ -661,7 +661,7 @@ index 9431fe4..042f24f 100644
/* Create security data */
rv = ssl_CopySecurityInfo(ss, os);
-@@ -1733,6 +1735,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
+@@ -1987,6 +1989,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
ss->handshakeCallbackData = sm->handshakeCallbackData;
if (sm->pkcs11PinArg)
ss->pkcs11PinArg = sm->pkcs11PinArg;
@@ -672,7 +672,7 @@ index 9431fe4..042f24f 100644
return fd;
loser:
return NULL;
-@@ -3021,6 +3027,8 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
+@@ -3279,6 +3285,8 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
ss->badCertArg = NULL;
ss->pkcs11PinArg = NULL;
ss->ephemeralECDHKeyPair = NULL;
@@ -681,12 +681,12 @@ index 9431fe4..042f24f 100644
ssl_ChooseOps(ss);
ssl2_InitSocketPolicy(ss);
-diff --git a/ssl/sslt.h b/ssl/sslt.h
-index 1d28feb..0900f28 100644
---- a/ssl/sslt.h
-+++ b/ssl/sslt.h
-@@ -191,10 +191,11 @@ typedef enum {
- ssl_padding_xtn = 21,
+diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
+index cd742bb..b6616e2 100644
+--- a/lib/ssl/sslt.h
++++ b/lib/ssl/sslt.h
+@@ -238,11 +238,12 @@ typedef enum {
+ ssl_extended_master_secret_xtn = 23,
ssl_session_ticket_xtn = 35,
ssl_next_proto_nego_xtn = 13172,
+ ssl_channel_id_xtn = 30032,
@@ -694,7 +694,8 @@ index 1d28feb..0900f28 100644
ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
} SSLExtensionType;
--#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */
-+#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */
+-#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */
++#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */
- #endif /* __sslt_h_ */
+ typedef enum {
+ ssl_dhe_group_none = 0,
diff --git a/chromium/net/third_party/nss/patches/cipherorder.patch b/chromium/net/third_party/nss/patches/cipherorder.patch
index 2cbf2f79f19..eb15be7b735 100644
--- a/chromium/net/third_party/nss/patches/cipherorder.patch
+++ b/chromium/net/third_party/nss/patches/cipherorder.patch
@@ -1,10 +1,10 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index e9f5fb0..be6d88e 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -295,6 +295,13 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled);
- SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
- SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index db09425..437a822 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -387,6 +387,13 @@ SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd,
+ */
+ SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled);
+/* SSL_CipherOrderSet sets the cipher suite preference order from |ciphers|,
+ * which must be an array of cipher suite ids of length |len|. All the given
@@ -16,12 +16,12 @@ index e9f5fb0..be6d88e 100644
/* SSLChannelBindingType enumerates the types of supported channel binding
* values. See RFC 5929. */
typedef enum SSLChannelBindingType {
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 54c5b80..26b87c6 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -12631,6 +12631,46 @@ ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
- return rv;
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 5c09f25..572bba9 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -13390,6 +13390,46 @@ SSL_SignatureMaxCount() {
+ return MAX_SIGNATURE_ALGORITHMS;
}
+SECStatus
@@ -67,11 +67,11 @@ index 54c5b80..26b87c6 100644
/* copy global default policy into socket. */
void
ssl3_InitSocketPolicy(sslSocket *ss)
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index 0fd0a89..d12228e 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -1754,6 +1754,8 @@ extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index 080debe..3403091 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -1786,6 +1786,8 @@ extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool
extern SECStatus ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *on);
extern SECStatus ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled);
extern SECStatus ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled);
@@ -80,11 +80,11 @@ index 0fd0a89..d12228e 100644
extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy);
extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy);
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 72058f5..09a0fb5 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -1316,6 +1316,19 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index 28e3543..8ad1517 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -1369,6 +1369,19 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
}
SECStatus
diff --git a/chromium/net/third_party/nss/patches/clientauth.patch b/chromium/net/third_party/nss/patches/clientauth.patch
index 83206b064e0..17539d16322 100644
--- a/chromium/net/third_party/nss/patches/clientauth.patch
+++ b/chromium/net/third_party/nss/patches/clientauth.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 91a47a6..4e7d52e 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -543,6 +543,48 @@ typedef SECStatus (PR_CALLBACK *SSLGetClientAuthData)(void *arg,
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index 2a52769..48fa018 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -636,6 +636,48 @@ typedef SECStatus (PR_CALLBACK *SSLGetClientAuthData)(void *arg,
SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
SSLGetClientAuthData f, void *a);
@@ -51,11 +51,11 @@ index 91a47a6..4e7d52e 100644
/*
** SNI extension processing callback function.
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 60af5b0..b9014ef 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -2503,6 +2503,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 9aaf601..cc193cd 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -2530,6 +2530,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
PRBool isPresent = PR_TRUE;
/* we only care if we are doing client auth */
@@ -65,7 +65,7 @@ index 60af5b0..b9014ef 100644
if (!sid || !sid->u.ssl3.clAuthValid) {
return PR_TRUE;
}
-@@ -6178,25 +6181,36 @@ ssl3_SendCertificateVerify(sslSocket *ss)
+@@ -6352,25 +6355,36 @@ ssl3_SendCertificateVerify(sslSocket *ss)
isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
@@ -119,7 +119,7 @@ index 60af5b0..b9014ef 100644
if (rv != SECSuccess) {
goto done; /* err code was set by ssl3_SignHashes */
}
-@@ -6275,6 +6289,12 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -6449,6 +6463,12 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
ss->ssl3.clientPrivateKey = NULL;
}
@@ -132,7 +132,7 @@ index 60af5b0..b9014ef 100644
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (temp < 0) {
-@@ -6904,6 +6924,18 @@ ssl3_ExtractClientKeyInfo(sslSocket *ss,
+@@ -7109,6 +7129,18 @@ ssl3_ExtractClientKeyInfo(sslSocket *ss,
goto done;
}
@@ -151,7 +151,7 @@ index 60af5b0..b9014ef 100644
/* If the key is a 1024-bit RSA or DSA key, assume conservatively that
* it may be unable to sign SHA-256 hashes. This is the case for older
* Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
-@@ -7002,6 +7034,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -7207,6 +7239,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECItem cert_types = {siBuffer, NULL, 0};
SECItem algorithms = {siBuffer, NULL, 0};
CERTDistNames ca_list;
@@ -162,7 +162,7 @@ index 60af5b0..b9014ef 100644
SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
SSL_GETPID(), ss->fd));
-@@ -7017,6 +7053,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -7222,6 +7258,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
PORT_Assert(ss->ssl3.clientCertChain == NULL);
PORT_Assert(ss->ssl3.clientCertificate == NULL);
PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
@@ -170,7 +170,7 @@ index 60af5b0..b9014ef 100644
isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
-@@ -7096,6 +7133,18 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -7301,6 +7338,18 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
desc = no_certificate;
ss->ssl3.hs.ws = wait_hello_done;
@@ -187,9 +187,9 @@ index 60af5b0..b9014ef 100644
+ } else
+#endif
if (ss->getClientAuthData != NULL) {
- /* XXX Should pass cert_types and algorithms in this call!! */
- rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
-@@ -7105,12 +7154,55 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
+@@ -7312,12 +7361,55 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
} else {
rv = SECFailure; /* force it to send a no_certificate alert */
}
@@ -245,7 +245,7 @@ index 60af5b0..b9014ef 100644
/* check what the callback function returned */
if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
/* we are missing either the key or cert */
-@@ -7172,6 +7264,10 @@ loser:
+@@ -7379,6 +7471,10 @@ loser:
done:
if (arena != NULL)
PORT_FreeArena(arena, PR_FALSE);
@@ -256,7 +256,7 @@ index 60af5b0..b9014ef 100644
return rv;
}
-@@ -7288,7 +7384,8 @@ ssl3_SendClientSecondRound(sslSocket *ss)
+@@ -7497,7 +7593,8 @@ ssl3_SendClientSecondRound(sslSocket *ss)
sendClientCert = !ss->ssl3.sendEmptyCert &&
ss->ssl3.clientCertChain != NULL &&
@@ -266,7 +266,7 @@ index 60af5b0..b9014ef 100644
if (!sendClientCert &&
ss->ssl3.hs.hashType == handshake_hash_single &&
-@@ -12148,6 +12245,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
+@@ -12910,6 +13007,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
if (ss->ssl3.clientPrivateKey != NULL)
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
@@ -277,10 +277,10 @@ index 60af5b0..b9014ef 100644
if (ss->ssl3.peerCertArena != NULL)
ssl3_CleanupPeerCerts(ss);
-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c
-index 28d21c4..0a2288a 100644
---- a/ssl/ssl3ext.c
-+++ b/ssl/ssl3ext.c
+diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c
+index cf04aba..5661a5c 100644
+--- a/lib/ssl/ssl3ext.c
++++ b/lib/ssl/ssl3ext.c
@@ -11,8 +11,8 @@
#include "nssrenam.h"
#include "nss.h"
@@ -291,10 +291,10 @@ index 28d21c4..0a2288a 100644
#include "pk11pub.h"
#ifdef NO_PKCS11_BYPASS
#include "blapit.h"
-diff --git a/ssl/sslauth.c b/ssl/sslauth.c
-index ed74d94..7f9c43b 100644
---- a/ssl/sslauth.c
-+++ b/ssl/sslauth.c
+diff --git a/lib/ssl/sslauth.c b/lib/ssl/sslauth.c
+index b144336..e6981f0 100644
+--- a/lib/ssl/sslauth.c
++++ b/lib/ssl/sslauth.c
@@ -216,6 +216,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
return SECSuccess;
}
@@ -324,11 +324,11 @@ index ed74d94..7f9c43b 100644
/* NEED LOCKS IN HERE. */
SECStatus
SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index 086f6d2..bbc9bd2 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -20,6 +20,7 @@
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index 9dcc29e..94bb9f4 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -21,6 +21,7 @@
#include "sslerr.h"
#include "ssl3prot.h"
#include "hasht.h"
@@ -336,7 +336,7 @@ index 086f6d2..bbc9bd2 100644
#include "nssilock.h"
#include "pkcs11t.h"
#if defined(XP_UNIX) || defined(XP_BEOS)
-@@ -31,6 +32,15 @@
+@@ -32,6 +33,15 @@
#include "sslt.h" /* for some formerly private types, now public */
@@ -352,7 +352,7 @@ index 086f6d2..bbc9bd2 100644
/* to make some of these old enums public without namespace pollution,
** it was necessary to prepend ssl_ to the names.
** These #defines preserve compatibility with the old code here in libssl.
-@@ -443,6 +453,14 @@ struct sslGatherStr {
+@@ -453,6 +463,14 @@ struct sslGatherStr {
#define GS_DATA 3
#define GS_PAD 4
@@ -367,7 +367,7 @@ index 086f6d2..bbc9bd2 100644
/*
-@@ -961,6 +979,10 @@ struct ssl3StateStr {
+@@ -974,6 +992,10 @@ struct ssl3StateStr {
CERTCertificate * clientCertificate; /* used by client */
SECKEYPrivateKey * clientPrivateKey; /* used by client */
@@ -378,7 +378,7 @@ index 086f6d2..bbc9bd2 100644
CERTCertificateList *clientCertChain; /* used by client */
PRBool sendEmptyCert; /* used by client */
-@@ -1223,6 +1245,10 @@ const unsigned char * preferredCipher;
+@@ -1253,6 +1275,10 @@ const unsigned char * preferredCipher;
void *authCertificateArg;
SSLGetClientAuthData getClientAuthData;
void *getClientAuthDataArg;
@@ -389,7 +389,7 @@ index 086f6d2..bbc9bd2 100644
SSLSNISocketConfig sniSocketConfig;
void *sniSocketConfigArg;
SSLBadCertHandler handleBadCert;
-@@ -1863,6 +1889,26 @@ extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit);
+@@ -1896,6 +1922,26 @@ extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit);
extern SECStatus ssl_FreeSessionCacheLocks(void);
@@ -416,11 +416,11 @@ index 086f6d2..bbc9bd2 100644
/**************** DTLS-specific functions **************/
extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg);
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 282bb85..6c09992 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -275,6 +275,10 @@ ssl_DupSocket(sslSocket *os)
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index f735009..21754d6 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -300,6 +300,10 @@ ssl_DupSocket(sslSocket *os)
ss->authCertificateArg = os->authCertificateArg;
ss->getClientAuthData = os->getClientAuthData;
ss->getClientAuthDataArg = os->getClientAuthDataArg;
@@ -431,7 +431,7 @@ index 282bb85..6c09992 100644
ss->sniSocketConfig = os->sniSocketConfig;
ss->sniSocketConfigArg = os->sniSocketConfigArg;
ss->handleBadCert = os->handleBadCert;
-@@ -1709,6 +1713,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
+@@ -1963,6 +1967,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
ss->getClientAuthData = sm->getClientAuthData;
if (sm->getClientAuthDataArg)
ss->getClientAuthDataArg = sm->getClientAuthDataArg;
@@ -444,7 +444,7 @@ index 282bb85..6c09992 100644
if (sm->sniSocketConfig)
ss->sniSocketConfig = sm->sniSocketConfig;
if (sm->sniSocketConfigArg)
-@@ -2974,6 +2984,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
+@@ -3232,6 +3242,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
ss->sniSocketConfig = NULL;
ss->sniSocketConfigArg = NULL;
ss->getClientAuthData = NULL;
diff --git a/chromium/net/third_party/nss/patches/dh1024.patch b/chromium/net/third_party/nss/patches/dh1024.patch
deleted file mode 100644
index 3b76da0600b..00000000000
--- a/chromium/net/third_party/nss/patches/dh1024.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index a67a9d1..02b0dda 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -6964,7 +6964,8 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-- if (dh_p.len < 512/8) {
-+ if (dh_p.len < 1024/8 ||
-+ (dh_p.len == 1024/8 && (dh_p.data[0] & 0x80) == 0)) {
- errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
- goto alert_loser;
- }
diff --git a/chromium/net/third_party/nss/patches/didhandshakeresume.patch b/chromium/net/third_party/nss/patches/didhandshakeresume.patch
index 06f024ce2df..bceeae1d8e6 100644
--- a/chromium/net/third_party/nss/patches/didhandshakeresume.patch
+++ b/chromium/net/third_party/nss/patches/didhandshakeresume.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 4e7d52e..34142fc 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -1007,6 +1007,9 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index 48fa018..0983b5f 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -1117,6 +1117,9 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
SSLExtensionType extId,
PRBool *yes);
@@ -12,11 +12,11 @@ index 4e7d52e..34142fc 100644
/*
** How long should we wait before retransmitting the next flight of
** the DTLS handshake? Returns SECFailure if not DTLS or not in a
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 6c09992..1a9c584 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -1897,6 +1897,20 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index 21754d6..b73f8f6 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -2151,6 +2151,20 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
return &ss->sec.ci.sid->peerCertStatus;
}
diff --git a/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch b/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch
index dbd6a15e414..e58cb58a612 100644
--- a/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch
+++ b/chromium/net/third_party/nss/patches/getrequestedclientcerttypes.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 34142fc..e2d1b09 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -803,6 +803,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index 0983b5f..cf9f6db 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -896,6 +896,16 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
PRBool flushCache,
PRIntervalTime timeout);
@@ -19,11 +19,11 @@ index 34142fc..e2d1b09 100644
#ifdef SSL_DEPRECATED_FUNCTION
/* deprecated!
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index b9014ef..800c28e 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -7061,6 +7061,9 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index cc193cd..27038f3 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -7266,6 +7266,9 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess)
goto loser; /* malformed, alert has been sent */
@@ -33,7 +33,7 @@ index b9014ef..800c28e 100644
if (isTLS12) {
rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &b, &length);
if (rv != SECSuccess)
-@@ -7262,6 +7265,7 @@ loser:
+@@ -7469,6 +7472,7 @@ loser:
PORT_SetError(errCode);
rv = SECFailure;
done:
@@ -41,11 +41,11 @@ index b9014ef..800c28e 100644
if (arena != NULL)
PORT_FreeArena(arena, PR_FALSE);
#ifdef NSS_PLATFORM_CLIENT_AUTH
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index bbc9bd2..46e618a 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -1238,6 +1238,10 @@ struct sslSocketStr {
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index 94bb9f4..c7231a7 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -1265,6 +1265,10 @@ struct sslSocketStr {
unsigned int sizeCipherSpecs;
const unsigned char * preferredCipher;
@@ -55,12 +55,12 @@ index bbc9bd2..46e618a 100644
+
ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */
- /* Callbacks */
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 1a9c584..9431fe4 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -1911,6 +1911,20 @@ SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
+ const ssl3DHParams *dheParams; /* DHE param */
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index b73f8f6..11e66f2 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -2165,6 +2165,20 @@ SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
return SECSuccess;
}
@@ -81,11 +81,11 @@ index 1a9c584..9431fe4 100644
/************************************************************************/
/* The following functions are the TOP LEVEL SSL functions.
** They all get called through the NSPRIOMethods table below.
-@@ -2989,6 +3003,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
+@@ -3243,6 +3257,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
sc->serverKeyBits = 0;
ss->certStatusArray[i] = NULL;
}
+ ss->requestedCertTypes = NULL;
ss->stepDownKeyPair = NULL;
- ss->dbHandle = CERT_GetDefaultCertDB();
+ ss->dheParams = NULL;
diff --git a/chromium/net/third_party/nss/patches/norenegotiatelock.patch b/chromium/net/third_party/nss/patches/norenegotiatelock.patch
deleted file mode 100644
index 4d512e4f719..00000000000
--- a/chromium/net/third_party/nss/patches/norenegotiatelock.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index f5afab7..a67a9d1 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -5547,9 +5547,7 @@ ssl3_HandleHelloRequest(sslSocket *ss)
- return SECFailure;
- }
- if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
-- ssl_GetXmitBufLock(ss);
-- rv = SSL3_SendAlert(ss, alert_warning, no_renegotiation);
-- ssl_ReleaseXmitBufLock(ss);
-+ (void)SSL3_SendAlert(ss, alert_warning, no_renegotiation);
- PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
- return SECFailure;
- }
diff --git a/chromium/net/third_party/nss/patches/nssrwlock.patch b/chromium/net/third_party/nss/patches/nssrwlock.patch
index d56dbfbf757..ed0e9109ef4 100644
--- a/chromium/net/third_party/nss/patches/nssrwlock.patch
+++ b/chromium/net/third_party/nss/patches/nssrwlock.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 0ac85da..f5afab7 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -5261,7 +5261,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index afab931..e5e620f 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -5436,7 +5436,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
* the lock across the calls to ssl3_CallHelloExtensionSenders.
*/
if (sid->u.ssl3.lock) {
@@ -11,7 +11,7 @@ index 0ac85da..f5afab7 100644
}
if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) {
-@@ -5270,7 +5270,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5445,7 +5445,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL);
if (extLen < 0) {
@@ -20,7 +20,7 @@ index 0ac85da..f5afab7 100644
return SECFailure;
}
total_exten_len += extLen;
-@@ -5297,7 +5297,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5472,7 +5472,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
/* how many suites are permitted by policy and user preference? */
num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
if (!num_suites) {
@@ -29,7 +29,7 @@ index 0ac85da..f5afab7 100644
return SECFailure; /* count_cipher_suites has set error code. */
}
-@@ -5342,7 +5342,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5517,7 +5517,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
if (rv != SECSuccess) {
@@ -38,7 +38,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
-@@ -5361,21 +5361,21 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5536,21 +5536,21 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
}
if (rv != SECSuccess) {
@@ -63,7 +63,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
-@@ -5385,7 +5385,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5560,7 +5560,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
else
rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
if (rv != SECSuccess) {
@@ -72,7 +72,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
-@@ -5393,14 +5393,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5568,14 +5568,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeVariable(
ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1);
if (rv != SECSuccess) {
@@ -89,7 +89,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
-@@ -5409,7 +5409,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5584,7 +5584,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
sizeof(ssl3CipherSuite));
if (rv != SECSuccess) {
@@ -98,7 +98,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
actual_count++;
-@@ -5418,7 +5418,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5593,7 +5593,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV,
sizeof(ssl3CipherSuite));
if (rv != SECSuccess) {
@@ -107,8 +107,8 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
actual_count++;
-@@ -5428,7 +5428,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
- if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) {
+@@ -5603,7 +5603,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+ if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange, ss)) {
actual_count++;
if (actual_count > num_suites) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
@@ -116,7 +116,7 @@ index 0ac85da..f5afab7 100644
/* set error card removal/insertion error */
PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
return SECFailure;
-@@ -5436,7 +5436,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5611,7 +5611,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite,
sizeof(ssl3CipherSuite));
if (rv != SECSuccess) {
@@ -125,7 +125,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
}
-@@ -5447,14 +5447,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5622,14 +5622,14 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
* the server.. */
if (actual_count != num_suites) {
/* Card removal/insertion error */
@@ -142,7 +142,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
for (i = 0; i < compressionMethodsCount; i++) {
-@@ -5462,7 +5462,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5637,7 +5637,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
continue;
rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1);
if (rv != SECSuccess) {
@@ -151,7 +151,7 @@ index 0ac85da..f5afab7 100644
return rv; /* err set by ssl3_AppendHandshake* */
}
}
-@@ -5473,20 +5473,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5648,20 +5648,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2);
if (rv != SECSuccess) {
@@ -175,7 +175,7 @@ index 0ac85da..f5afab7 100644
return SECFailure;
}
maxBytes -= extLen;
-@@ -5495,7 +5495,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
+@@ -5670,7 +5670,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
}
if (sid->u.ssl3.lock) {
@@ -184,11 +184,11 @@ index 0ac85da..f5afab7 100644
}
if (ss->xtnData.sentSessionTicketInClientHello) {
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index d12228e..efcbf9f 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -731,7 +731,7 @@ struct sslSessionIDStr {
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index 3403091..874e59c 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -742,7 +742,7 @@ struct sslSessionIDStr {
* cached. Before then, there is no need to lock anything because
* the sid isn't being shared by anything.
*/
@@ -197,10 +197,10 @@ index d12228e..efcbf9f 100644
/* The lock must be held while reading or writing these members
* because they change while the sid is cached.
-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c
+diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c
index cefdda6..28ad364 100644
---- a/ssl/sslnonce.c
-+++ b/ssl/sslnonce.c
+--- a/lib/ssl/sslnonce.c
++++ b/lib/ssl/sslnonce.c
@@ -136,7 +136,7 @@ ssl_DestroySID(sslSessionID *sid)
}
diff --git a/chromium/net/third_party/nss/patches/removebuildmetadata.patch b/chromium/net/third_party/nss/patches/removebuildmetadata.patch
deleted file mode 100644
index cd25f09ee87..00000000000
--- a/chromium/net/third_party/nss/patches/removebuildmetadata.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-diff --git a/ssl/sslver.c b/ssl/sslver.c
-index 35e0317..ea60888 100644
---- a/ssl/sslver.c
-+++ b/ssl/sslver.c
-@@ -12,6 +12,13 @@
- #define _DEBUG_STRING ""
- #endif
-
-+#if defined(DONT_EMBED_BUILD_METADATA) && !defined(OFFICIAL_BUILD)
-+#define _DATE_AND_TIME "Sep 02 2008 08:00:00"
-+#else
-+#define _DATE_AND_TIME __DATE__ " " __TIME__
-+#endif
-+
-+
- /*
- * Version information for the 'ident' and 'what commands
- *
-@@ -19,6 +26,6 @@
- * must not end in a '$' to prevent rcs keyword substitution.
- */
- const char __nss_ssl_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
-- " " __DATE__ " " __TIME__ " $";
-+ " " _DATE_AND_TIME " $";
- const char __nss_ssl_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
-- " " __DATE__ " " __TIME__;
-+ " " _DATE_AND_TIME;
diff --git a/chromium/net/third_party/nss/patches/reorderextensions.patch b/chromium/net/third_party/nss/patches/reorderextensions.patch
index 66e9a67aba8..c522822506e 100644
--- a/chromium/net/third_party/nss/patches/reorderextensions.patch
+++ b/chromium/net/third_party/nss/patches/reorderextensions.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c
-index c18d6f6..9214a2e 100644
---- a/ssl/ssl3ext.c
-+++ b/ssl/ssl3ext.c
-@@ -313,6 +313,10 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
+diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c
+index 9cfd541..eb3fb70 100644
+--- a/lib/ssl/ssl3ext.c
++++ b/lib/ssl/ssl3ext.c
+@@ -321,6 +321,10 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
{ ssl_signed_certificate_timestamp_xtn,
&ssl3_ClientSendSignedCertTimestampXtn },
@@ -12,8 +12,8 @@ index c18d6f6..9214a2e 100644
+ * extension. */
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
{ ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
- /* any extra entries will appear as { 0, NULL } */
-@@ -2507,9 +2511,11 @@ ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
+ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn},
+@@ -2546,9 +2550,11 @@ ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
}
extensionLength = 512 - recordLength;
diff --git a/chromium/net/third_party/nss/patches/restartclientauth.patch b/chromium/net/third_party/nss/patches/restartclientauth.patch
index d4ca3f7534e..6e3a0b9ed9b 100644
--- a/chromium/net/third_party/nss/patches/restartclientauth.patch
+++ b/chromium/net/third_party/nss/patches/restartclientauth.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index e2d1b09..593dd00 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -409,6 +409,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd);
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index cf9f6db..85ced8a 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -502,6 +502,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd);
SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
PRIntervalTime timeout);
@@ -14,11 +14,11 @@ index e2d1b09..593dd00 100644
/*
** Query security status of socket. *on is set to one if security is
** enabled. *keySize will contain the stream key size used. *issuer will
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 800c28e..29e8f1c 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -7275,6 +7275,85 @@ done:
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 27038f3..304e03b 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -7482,6 +7482,85 @@ done:
return rv;
}
@@ -104,11 +104,11 @@ index 800c28e..29e8f1c 100644
static SECStatus
ssl3_CheckFalseStart(sslSocket *ss)
{
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index 46e618a..2cf0b3a 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -1599,16 +1599,17 @@ extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec,
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index c7231a7..c089889 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -1629,16 +1629,17 @@ extern SECStatus ssl3_MasterSecretDeriveBypass( ssl3CipherSpec * pwSpec,
/* These functions are called from secnav, even though they're "private". */
extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error);
@@ -130,11 +130,11 @@ index 46e618a..2cf0b3a 100644
extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
/*
-diff --git a/ssl/sslsecur.c b/ssl/sslsecur.c
-index ea2d408..d44336e 100644
---- a/ssl/sslsecur.c
-+++ b/ssl/sslsecur.c
-@@ -1516,17 +1516,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
+diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c
+index 53b4885..f77d6fa 100644
+--- a/lib/ssl/sslsecur.c
++++ b/lib/ssl/sslsecur.c
+@@ -1532,17 +1532,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
return SECSuccess;
}
diff --git a/chromium/net/third_party/nss/patches/secitemarray.patch b/chromium/net/third_party/nss/patches/secitemarray.patch
index 136f3e44563..d40e7ca3407 100644
--- a/chromium/net/third_party/nss/patches/secitemarray.patch
+++ b/chromium/net/third_party/nss/patches/secitemarray.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index 0ece0ed..ea71975 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -1373,6 +1373,15 @@ extern sslSessionIDUncacheFunc ssl_sid_uncache;
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index 976330e..60dd243 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -1403,6 +1403,15 @@ extern sslSessionIDUncacheFunc ssl_sid_uncache;
SEC_BEGIN_PROTOS
@@ -18,11 +18,11 @@ index 0ece0ed..ea71975 100644
/* Internal initialization and installation of the SSL error tables */
extern SECStatus ssl_Init(void);
extern SECStatus ssl_InitializePRErrorTable(void);
-diff --git a/ssl/sslt.h b/ssl/sslt.h
-index 0900f28..430d216 100644
---- a/ssl/sslt.h
-+++ b/ssl/sslt.h
-@@ -10,6 +10,19 @@
+diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
+index b6616e2..5593579 100644
+--- a/lib/ssl/sslt.h
++++ b/lib/ssl/sslt.h
+@@ -11,6 +11,19 @@
#include "prtypes.h"
diff --git a/chromium/net/third_party/nss/patches/secretexporterlocks.patch b/chromium/net/third_party/nss/patches/secretexporterlocks.patch
index 7716f938dc2..232b93237fb 100644
--- a/chromium/net/third_party/nss/patches/secretexporterlocks.patch
+++ b/chromium/net/third_party/nss/patches/secretexporterlocks.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/sslinfo.c b/ssl/sslinfo.c
-index 00f2f38..ba230d2 100644
---- a/ssl/sslinfo.c
-+++ b/ssl/sslinfo.c
-@@ -350,8 +350,13 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
+diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c
+index 216ab0f..7048eb8 100644
+--- a/lib/ssl/sslinfo.c
++++ b/lib/ssl/sslinfo.c
+@@ -387,8 +387,13 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
return SECFailure;
}
@@ -16,7 +16,7 @@ index 00f2f38..ba230d2 100644
return SECFailure;
}
-@@ -362,13 +367,17 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
+@@ -399,13 +404,17 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
}
val = PORT_Alloc(valLen);
if (!val) {
@@ -34,7 +34,7 @@ index 00f2f38..ba230d2 100644
if (hasContext) {
val[i++] = contextLen >> 8;
val[i++] = contextLen;
-@@ -389,6 +398,8 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
+@@ -426,6 +435,8 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
valLen, out, outLen);
}
ssl_ReleaseSpecReadLock(ss);
diff --git a/chromium/net/third_party/nss/patches/sessioncache.patch b/chromium/net/third_party/nss/patches/sessioncache.patch
index e8180e1ecc3..07e762fc02a 100644
--- a/chromium/net/third_party/nss/patches/sessioncache.patch
+++ b/chromium/net/third_party/nss/patches/sessioncache.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index be6d88e..57771cd 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -900,6 +900,18 @@ SSL_IMPORT int SSL_DataPending(PRFileDesc *fd);
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index 437a822..bc417a5 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -992,6 +992,18 @@ SSL_IMPORT int SSL_DataPending(PRFileDesc *fd);
SSL_IMPORT SECStatus SSL_InvalidateSession(PRFileDesc *fd);
/*
@@ -21,11 +21,11 @@ index be6d88e..57771cd 100644
** Return a SECItem containing the SSL session ID associated with the fd.
*/
SSL_IMPORT SECItem *SSL_GetSessionID(PRFileDesc *fd);
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 26b87c6..0ac85da 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -11375,7 +11375,7 @@ ssl3_FinishHandshake(sslSocket * ss)
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 572bba9..afab931 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -12058,7 +12058,7 @@ ssl3_FinishHandshake(sslSocket * ss)
ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
}
@@ -34,11 +34,11 @@ index 26b87c6..0ac85da 100644
PORT_Assert(ss->sec.ci.sid->cached == never_cached);
(*ss->sec.cache)(ss->sec.ci.sid);
ss->ssl3.hs.cacheSID = PR_FALSE;
-diff --git a/ssl/sslsecur.c b/ssl/sslsecur.c
-index 5c6751a..00ab455 100644
---- a/ssl/sslsecur.c
-+++ b/ssl/sslsecur.c
-@@ -1467,6 +1467,49 @@ SSL_InvalidateSession(PRFileDesc *fd)
+diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c
+index cca55bb..b4b8e95 100644
+--- a/lib/ssl/sslsecur.c
++++ b/lib/ssl/sslsecur.c
+@@ -1483,6 +1483,49 @@ SSL_InvalidateSession(PRFileDesc *fd)
return rv;
}
diff --git a/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch b/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch
index a0c5d2c21a9..e6af84fcb10 100644
--- a/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch
+++ b/chromium/net/third_party/nss/patches/signedcertificatetimestamps.patch
@@ -1,18 +1,17 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 80717db..e9f5fb0 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -191,6 +191,9 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
- #define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in
- * handshakes. */
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index eb7f7ec..db09425 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -203,6 +203,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
+ */
+ #define SSL_ENABLE_EXTENDED_MASTER_SECRET 30
+/* Request Signed Certificate Timestamps via TLS extension (client) */
-+#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 29
-+
++#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 31
+
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
- SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
-@@ -493,6 +496,23 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
+@@ -586,6 +588,23 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
*/
SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
@@ -36,13 +35,13 @@ index 80717db..e9f5fb0 100644
/* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses
* in the fd's data, which may be sent as part of a server side cert_status
* handshake message. Parameter |responses| is for the server certificate of
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 6a4a443..54c5b80 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -6752,6 +6752,14 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
- sid->u.ssl3.sessionIDLength = sidBytes.len;
- PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index ba3d012..5c09f25 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -6957,6 +6957,14 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ sid->u.ssl3.keys.extendedMasterSecretUsed =
+ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
+ /* Copy Signed Certificate Timestamps, if any. */
+ if (ss->xtnData.signedCertTimestamps.data) {
@@ -55,7 +54,7 @@ index 6a4a443..54c5b80 100644
ss->ssl3.hs.isResuming = PR_FALSE;
if (ss->ssl3.hs.kea_def->signKeyType != sign_null) {
/* All current cipher suites other than those with sign_null (i.e.,
-@@ -6765,6 +6773,10 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+@@ -6971,6 +6979,10 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
winner:
@@ -66,7 +65,7 @@ index 6a4a443..54c5b80 100644
/* If we will need a ChannelID key then we make the callback now. This
* allows the handshake to be restarted cleanly if the callback returns
* SECWouldBlock. */
-@@ -6790,6 +6802,9 @@ alert_loser:
+@@ -6996,6 +7008,9 @@ alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
@@ -76,10 +75,10 @@ index 6a4a443..54c5b80 100644
errCode = ssl_MapLowLevelError(errCode);
return SECFailure;
}
-diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c
-index 4d17587..c18d6f6 100644
---- a/ssl/ssl3ext.c
-+++ b/ssl/ssl3ext.c
+diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c
+index 78825cb..9cfd541 100644
+--- a/lib/ssl/ssl3ext.c
++++ b/lib/ssl/ssl3ext.c
@@ -90,6 +90,12 @@ static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes);
static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
@@ -93,16 +92,16 @@ index 4d17587..c18d6f6 100644
static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes);
-@@ -275,6 +281,8 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
- { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
+@@ -283,6 +289,8 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
{ ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
+ { ssl_signed_certificate_timestamp_xtn,
+ &ssl3_ClientHandleSignedCertTimestampXtn },
{ -1, NULL }
};
-@@ -303,6 +311,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
+@@ -311,6 +319,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
{ ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
{ ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
@@ -110,12 +109,16 @@ index 4d17587..c18d6f6 100644
+ &ssl3_ClientSendSignedCertTimestampXtn },
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
{ ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
- /* any extra entries will appear as { 0, NULL } */
-@@ -2616,3 +2626,65 @@ ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
+ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn},
+@@ -2698,11 +2708,48 @@ ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
+ }
- return SECSuccess;
+ return extension_length;
+-
+ loser:
+ return -1;
}
-+
+
+/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
+ * extension for TLS ClientHellos. */
+static PRInt32
@@ -129,7 +132,12 @@ index 4d17587..c18d6f6 100644
+ if (!ss->opt.enableSignedCertTimestamps)
+ return 0;
+
-+ if (append && maxBytes >= extension_length) {
++ if (maxBytes < extension_length) {
++ PORT_Assert(0);
++ return 0;
++ }
++
++ if (append) {
+ SECStatus rv;
+ /* extension_type */
+ rv = ssl3_AppendHandshakeNumber(ss,
@@ -143,15 +151,19 @@ index 4d17587..c18d6f6 100644
+ goto loser;
+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
+ ssl_signed_certificate_timestamp_xtn;
-+ } else if (maxBytes < extension_length) {
-+ PORT_Assert(0);
-+ return 0;
+ }
+
+ return extension_length;
+loser:
+ return -1;
+}
+
+ static SECStatus
+ ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
+@@ -2743,3 +2790,28 @@ ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
+ }
+ return SECSuccess;
+ }
+
+static SECStatus
+ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
@@ -177,19 +189,19 @@ index 4d17587..c18d6f6 100644
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+ return SECSuccess;
+}
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index c4c87b4..0fd0a89 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -339,6 +339,7 @@ typedef struct sslOptionsStr {
- unsigned int enableALPN : 1; /* 27 */
- unsigned int reuseServerECDHEKey : 1; /* 28 */
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index d53c446..080debe 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -349,6 +349,7 @@ typedef struct sslOptionsStr {
unsigned int enableFallbackSCSV : 1; /* 29 */
-+ unsigned int enableSignedCertTimestamps : 1; /* 30 */
+ unsigned int enableServerDhe : 1; /* 30 */
+ unsigned int enableExtendedMS : 1; /* 31 */
++ unsigned int enableSignedCertTimestamps : 1; /* 32 */
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
-@@ -721,6 +722,11 @@ struct sslSessionIDStr {
+@@ -732,6 +733,11 @@ struct sslSessionIDStr {
* resumption handshake to the original handshake. */
SECItem originalHandshakeHash;
@@ -201,7 +213,7 @@ index c4c87b4..0fd0a89 100644
/* This lock is lazily initialized by CacheSID when a sid is first
* cached. Before then, there is no need to lock anything because
* the sid isn't being shared by anything.
-@@ -835,6 +841,18 @@ struct TLSExtensionDataStr {
+@@ -846,6 +852,18 @@ struct TLSExtensionDataStr {
* is beyond ssl3_HandleClientHello function. */
SECItem *sniNameArr;
PRUint32 sniNameArrSize;
@@ -220,10 +232,10 @@ index c4c87b4..0fd0a89 100644
};
typedef SECStatus (*sslRestartTarget)(sslSocket *);
-diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c
+diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c
index c45849d..cefdda6 100644
---- a/ssl/sslnonce.c
-+++ b/ssl/sslnonce.c
+--- a/lib/ssl/sslnonce.c
++++ b/lib/ssl/sslnonce.c
@@ -131,6 +131,9 @@ ssl_DestroySID(sslSessionID *sid)
if (sid->u.ssl3.originalHandshakeHash.data) {
SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
@@ -234,22 +246,22 @@ index c45849d..cefdda6 100644
if (sid->u.ssl3.lock) {
PR_DestroyRWLock(sid->u.ssl3.lock);
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 6a6c8d1..72058f5 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -89,7 +89,8 @@ static sslOptions ssl_defaults = {
- PR_TRUE, /* enableNPN */
- PR_FALSE, /* enableALPN */
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index 6d700a7..28e3543 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -92,7 +92,8 @@ static sslOptions ssl_defaults = {
PR_TRUE, /* reuseServerECDHEKey */
-- PR_FALSE /* enableFallbackSCSV */
-+ PR_FALSE, /* enableFallbackSCSV */
+ PR_FALSE, /* enableFallbackSCSV */
+ PR_TRUE, /* enableServerDhe */
+- PR_FALSE /* enableExtendedMS */
++ PR_FALSE, /* enableExtendedMS */
+ PR_FALSE, /* enableSignedCertTimestamps */
};
/*
-@@ -807,6 +808,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
- ss->opt.enableFallbackSCSV = on;
+@@ -843,6 +844,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
+ ss->opt.enableExtendedMS = on;
break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
@@ -259,19 +271,19 @@ index 6a6c8d1..72058f5 100644
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
-@@ -882,6 +887,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
- case SSL_REUSE_SERVER_ECDHE_KEY:
- on = ss->opt.reuseServerECDHEKey; break;
- case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
+@@ -921,6 +926,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
+ case SSL_ENABLE_SERVER_DHE: on = ss->opt.enableServerDhe; break;
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ on = ss->opt.enableExtendedMS; break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
+ on = ss->opt.enableSignedCertTimestamps;
+ break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
-@@ -951,6 +959,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
- case SSL_ENABLE_FALLBACK_SCSV:
- on = ssl_defaults.enableFallbackSCSV;
+@@ -996,6 +1004,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ on = ssl_defaults.enableExtendedMS;
break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
+ on = ssl_defaults.enableSignedCertTimestamps;
@@ -279,8 +291,8 @@ index 6a6c8d1..72058f5 100644
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
-@@ -1134,6 +1145,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
- ssl_defaults.enableFallbackSCSV = on;
+@@ -1187,6 +1198,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
+ ssl_defaults.enableExtendedMS = on;
break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
@@ -290,7 +302,7 @@ index 6a6c8d1..72058f5 100644
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
-@@ -1963,6 +1978,29 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
+@@ -2218,6 +2233,29 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
return &ss->sec.ci.sid->peerCertStatus;
}
@@ -320,23 +332,24 @@ index 6a6c8d1..72058f5 100644
SECStatus
SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
sslSocket *ss = ssl_FindSocket(fd);
-diff --git a/ssl/sslt.h b/ssl/sslt.h
-index fe0ad07..c36b8c7 100644
---- a/ssl/sslt.h
-+++ b/ssl/sslt.h
-@@ -202,6 +202,7 @@ typedef enum {
+diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
+index a2eff62..36e34df 100644
+--- a/lib/ssl/sslt.h
++++ b/lib/ssl/sslt.h
+@@ -248,6 +248,7 @@ typedef enum {
ssl_signature_algorithms_xtn = 13,
ssl_use_srtp_xtn = 14,
ssl_app_layer_protocol_xtn = 16,
+ ssl_signed_certificate_timestamp_xtn = 18, /* RFC 6962 */
ssl_padding_xtn = 21,
+ ssl_extended_master_secret_xtn = 23,
ssl_session_ticket_xtn = 35,
- ssl_next_proto_nego_xtn = 13172,
-@@ -210,6 +211,6 @@ typedef enum {
+@@ -257,7 +258,7 @@ typedef enum {
ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
} SSLExtensionType;
--#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */
-+#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */
+-#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */
++#define SSL_MAX_EXTENSIONS 14 /* doesn't include ssl_padding_xtn. */
- #endif /* __sslt_h_ */
+ typedef enum {
+ ssl_dhe_group_none = 0,
diff --git a/chromium/net/third_party/nss/patches/suitebonly.patch b/chromium/net/third_party/nss/patches/suitebonly.patch
index 24df8145093..32f0f7e25e2 100644
--- a/chromium/net/third_party/nss/patches/suitebonly.patch
+++ b/chromium/net/third_party/nss/patches/suitebonly.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl3ecc.c b/ssl/ssl3ecc.c
-index aca2b74..dac7a9e 100644
---- a/ssl/ssl3ecc.c
-+++ b/ssl/ssl3ecc.c
-@@ -1090,6 +1090,7 @@ static const PRUint8 ecPtFmt[6] = {
+diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c
+index 94008a0..6d89bbe 100644
+--- a/lib/ssl/ssl3ecc.c
++++ b/lib/ssl/ssl3ecc.c
+@@ -1093,6 +1093,7 @@ static const PRUint8 ecPtFmt[6] = {
static PRBool
ssl3_SuiteBOnly(sslSocket *ss)
{
@@ -10,7 +10,7 @@ index aca2b74..dac7a9e 100644
/* See if we can support small curves (like 163). If not, assume we can
* only support Suite-B curves (P-256, P-384, P-521). */
PK11SlotInfo *slot =
-@@ -1103,6 +1104,9 @@ ssl3_SuiteBOnly(sslSocket *ss)
+@@ -1106,6 +1107,9 @@ ssl3_SuiteBOnly(sslSocket *ss)
/* we can, presume we can do all curves */
PK11_FreeSlot(slot);
return PR_FALSE;
diff --git a/chromium/net/third_party/nss/patches/tls12chromium.patch b/chromium/net/third_party/nss/patches/tls12chromium.patch
index 14e8bd317ee..b6e168b53cc 100644
--- a/chromium/net/third_party/nss/patches/tls12chromium.patch
+++ b/chromium/net/third_party/nss/patches/tls12chromium.patch
@@ -1,8 +1,8 @@
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index 7c06815..1167d6d 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -31,6 +31,15 @@
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index ce92cf1..c5cb1eb 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -33,6 +33,15 @@
#include "blapi.h"
#endif
@@ -18,10 +18,10 @@ index 7c06815..1167d6d 100644
#include <stdio.h>
#ifdef NSS_ENABLE_ZLIB
#include "zlib.h"
-diff --git a/ssl/ssl3ecc.c b/ssl/ssl3ecc.c
-index dac7a9e..9b91270 100644
---- a/ssl/ssl3ecc.c
-+++ b/ssl/ssl3ecc.c
+diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c
+index 6d89bbe..cf8e741 100644
+--- a/lib/ssl/ssl3ecc.c
++++ b/lib/ssl/ssl3ecc.c
@@ -31,6 +31,12 @@
#include <stdio.h>
@@ -35,16 +35,17 @@ index dac7a9e..9b91270 100644
#ifndef NSS_DISABLE_ECC
#ifndef PK11_SETATTRS
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 14ff328..6a6c8d1 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -17,8 +17,15 @@
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index c9a4493..6d700a7 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -17,9 +17,16 @@
#ifndef NO_PKCS11_BYPASS
#include "blapi.h"
#endif
+#include "pk11pub.h"
#include "nss.h"
+ #include "pk11pqg.h"
+/* This is a bodge to allow this code to be compiled against older NSS headers
+ * that don't contain the TLS 1.2 changes. */
@@ -55,7 +56,7 @@ index 14ff328..6a6c8d1 100644
#define SET_ERROR_CODE /* reminder */
static const sslSocketOps ssl_default_ops = { /* No SSL. */
-@@ -1878,6 +1885,24 @@ SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
+@@ -2133,6 +2140,24 @@ SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
return SECSuccess;
}
@@ -80,7 +81,7 @@ index 14ff328..6a6c8d1 100644
SECStatus
SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
{
-@@ -1898,6 +1923,20 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
+@@ -2153,6 +2178,20 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
ssl_GetSSL3HandshakeLock(ss);
ss->vrange = *vrange;
diff --git a/chromium/net/third_party/nss/patches/tlsunique.patch b/chromium/net/third_party/nss/patches/tlsunique.patch
index f2b2c50c05a..a31049aec75 100644
--- a/chromium/net/third_party/nss/patches/tlsunique.patch
+++ b/chromium/net/third_party/nss/patches/tlsunique.patch
@@ -1,10 +1,10 @@
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 716537d..80717db 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -292,6 +292,27 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled);
- SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
- SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
+diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h
+index 120c257..eb7f7ec 100644
+--- a/lib/ssl/ssl.h
++++ b/lib/ssl/ssl.h
+@@ -385,6 +385,27 @@ SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd,
+ */
+ SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled);
+/* SSLChannelBindingType enumerates the types of supported channel binding
+ * values. See RFC 5929. */
@@ -30,12 +30,12 @@ index 716537d..80717db 100644
/* SSL Version Range API
**
** This API should be used to control SSL 3.0 & TLS support instead of the
-diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
-index c0e8e79..7c06815 100644
---- a/ssl/ssl3con.c
-+++ b/ssl/ssl3con.c
-@@ -12479,6 +12479,68 @@ ssl3_InitSocketPolicy(sslSocket *ss)
- PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
+diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
+index 2ae8ce9..ce92cf1 100644
+--- a/lib/ssl/ssl3con.c
++++ b/lib/ssl/ssl3con.c
+@@ -13241,6 +13241,68 @@ ssl3_InitSocketPolicy(sslSocket *ss)
+ ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms);
}
+SECStatus
@@ -103,11 +103,11 @@ index c0e8e79..7c06815 100644
/* ssl3_config_match_init must have already been called by
* the caller of this function.
*/
-diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
-index e11860e..0ece0ed 100644
---- a/ssl/sslimpl.h
-+++ b/ssl/sslimpl.h
-@@ -1864,6 +1864,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
+diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
+index c286518..976330e 100644
+--- a/lib/ssl/sslimpl.h
++++ b/lib/ssl/sslimpl.h
+@@ -1897,6 +1897,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
unsigned int length);
@@ -119,12 +119,12 @@ index e11860e..0ece0ed 100644
/* Construct a new NSPR socket for the app to use */
extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd);
extern void ssl_FreePRSocket(PRFileDesc *fd);
-diff --git a/ssl/sslsock.c b/ssl/sslsock.c
-index 042f24f..14ff328 100644
---- a/ssl/sslsock.c
-+++ b/ssl/sslsock.c
-@@ -1345,6 +1345,27 @@ NSS_SetFrancePolicy(void)
- return NSS_SetDomesticPolicy();
+diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
+index efba686..c9a4493 100644
+--- a/lib/ssl/sslsock.c
++++ b/lib/ssl/sslsock.c
+@@ -1540,6 +1540,28 @@ SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled)
+ return SECSuccess;
}
+SECStatus
@@ -148,6 +148,7 @@ index 042f24f..14ff328 100644
+
+ return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax);
+}
++
+ #include "dhe-param.c"
-
- /* LOCKS ??? XXX */
+ static const SSLDHEGroupType ssl_default_dhe_groups[] = {
diff --git a/chromium/net/third_party/nss/ssl/SSLerrs.h b/chromium/net/third_party/nss/ssl/SSLerrs.h
index 81da41c0254..3d21ab805d5 100644
--- a/chromium/net/third_party/nss/ssl/SSLerrs.h
+++ b/chromium/net/third_party/nss/ssl/SSLerrs.h
@@ -423,11 +423,29 @@ ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131),
"The server rejected the handshake because the client downgraded to a lower "
"TLS version than the server supports.")
-ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 132),
+ER3(SSL_ERROR_WEAK_SERVER_CERT_KEY, (SSL_ERROR_BASE + 132),
+"The server certificate included a public key that was too weak.")
+
+ER3(SSL_ERROR_RX_SHORT_DTLS_READ, (SSL_ERROR_BASE + 133),
+"Not enough room in buffer for DTLS record.")
+
+ER3(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 134),
+"No supported TLS signature algorithm was configured.")
+
+ER3(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 135),
+"The peer used an unsupported combination of signature and hash algorithm.")
+
+ER3(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 136),
+"The peer tried to resume without a correct extended_master_secret extension")
+
+ER3(SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 137),
+"The peer tried to resume with an unexpected extended_master_secret extension")
+
+ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 138),
"SSL received a malformed TLS Channel ID extension.")
-ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 133),
+ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 139),
"The application provided an invalid TLS Channel ID key.")
-ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 134),
+ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 140),
"The application could not get a TLS Channel ID.")
diff --git a/chromium/net/third_party/nss/ssl/derive.c b/chromium/net/third_party/nss/ssl/derive.c
index b7c38c30ba3..8b58b800d71 100644
--- a/chromium/net/third_party/nss/ssl/derive.c
+++ b/chromium/net/third_party/nss/ssl/derive.c
@@ -431,7 +431,7 @@ key_and_mac_derive_fail:
* so isRSA is always true.
*/
SECStatus
-ssl3_MasterKeyDeriveBypass(
+ssl3_MasterSecretDeriveBypass(
ssl3CipherSpec * pwSpec,
const unsigned char * cr,
const unsigned char * sr,
diff --git a/chromium/net/third_party/nss/ssl/dhe-param.c b/chromium/net/third_party/nss/ssl/dhe-param.c
new file mode 100644
index 00000000000..ac0942e290a
--- /dev/null
+++ b/chromium/net/third_party/nss/ssl/dhe-param.c
@@ -0,0 +1,413 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+static const unsigned char ff_dhe_g2[] = { 2 };
+
+static const unsigned char ff_dhe_2048_p[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+ 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+ 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+ 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+ 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+ 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+ 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+ 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+ 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+ 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+ 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+ 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+ 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+ 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+ 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+ 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+ 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+ 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+ 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+ 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+ 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+ 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+ 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+ 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+ 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+ 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+ 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+ 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+ 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+ 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static const ssl3DHParams ff_dhe_2048 = {
+ { siBuffer, (unsigned char *)ff_dhe_2048_p, sizeof(ff_dhe_2048_p) },
+ { siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
+};
+
+static const unsigned char ff_dhe_3072_p[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+ 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+ 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+ 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+ 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+ 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+ 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+ 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+ 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+ 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+ 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+ 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+ 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+ 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+ 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+ 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+ 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+ 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+ 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+ 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+ 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+ 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+ 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+ 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+ 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+ 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+ 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+ 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+ 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+ 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+ 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+ 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+ 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+ 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+ 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+ 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+ 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+ 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+ 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+ 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+ 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+ 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+ 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+ 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+ 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+ 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static const ssl3DHParams ff_dhe_3072 = {
+ { siBuffer, (unsigned char *)ff_dhe_3072_p, sizeof(ff_dhe_3072_p) },
+ { siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
+};
+
+static const unsigned char ff_dhe_4096_p[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+ 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+ 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+ 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+ 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+ 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+ 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+ 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+ 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+ 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+ 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+ 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+ 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+ 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+ 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+ 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+ 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+ 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+ 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+ 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+ 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+ 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+ 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+ 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+ 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+ 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+ 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+ 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+ 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+ 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+ 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+ 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+ 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+ 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+ 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+ 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+ 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+ 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+ 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+ 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+ 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+ 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+ 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+ 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+ 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+ 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
+ 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
+ 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
+ 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
+ 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
+ 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
+ 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
+ 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
+ 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
+ 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
+ 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
+ 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
+ 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
+ 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
+ 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
+ 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
+ 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static const ssl3DHParams ff_dhe_4096 = {
+ { siBuffer, (unsigned char *)ff_dhe_4096_p, sizeof(ff_dhe_4096_p) },
+ { siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
+};
+
+static const unsigned char ff_dhe_6144_p[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+ 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+ 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+ 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+ 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+ 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+ 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+ 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+ 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+ 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+ 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+ 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+ 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+ 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+ 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+ 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+ 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+ 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+ 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+ 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+ 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+ 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+ 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+ 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+ 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+ 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+ 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+ 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+ 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+ 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+ 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+ 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+ 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+ 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+ 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+ 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+ 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+ 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+ 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+ 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+ 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+ 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+ 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+ 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+ 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+ 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
+ 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
+ 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
+ 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
+ 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
+ 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
+ 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
+ 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
+ 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
+ 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
+ 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
+ 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
+ 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
+ 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
+ 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
+ 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
+ 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
+ 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
+ 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
+ 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
+ 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
+ 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
+ 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
+ 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
+ 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
+ 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
+ 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
+ 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
+ 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
+ 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
+ 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
+ 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
+ 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
+ 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
+ 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
+ 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
+ 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
+ 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
+ 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
+ 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
+ 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
+ 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
+ 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
+ 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
+ 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
+ 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
+ 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
+ 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
+ 0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static const ssl3DHParams ff_dhe_6144 = {
+ { siBuffer, (unsigned char *)ff_dhe_6144_p, sizeof(ff_dhe_6144_p) },
+ { siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
+};
+
+static const unsigned char ff_dhe_8192_p[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
+ 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
+ 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
+ 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
+ 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
+ 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
+ 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
+ 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
+ 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
+ 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
+ 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
+ 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
+ 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
+ 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
+ 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
+ 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
+ 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
+ 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
+ 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
+ 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
+ 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
+ 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
+ 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
+ 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
+ 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
+ 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
+ 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
+ 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
+ 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
+ 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
+ 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
+ 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
+ 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
+ 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
+ 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
+ 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
+ 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
+ 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
+ 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
+ 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
+ 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
+ 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
+ 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
+ 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
+ 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
+ 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
+ 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
+ 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
+ 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
+ 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
+ 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
+ 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
+ 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
+ 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
+ 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
+ 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
+ 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
+ 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
+ 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
+ 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
+ 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
+ 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
+ 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
+ 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
+ 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
+ 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
+ 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
+ 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
+ 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
+ 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
+ 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
+ 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
+ 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
+ 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
+ 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
+ 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
+ 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
+ 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
+ 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
+ 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
+ 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
+ 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
+ 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
+ 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
+ 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
+ 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
+ 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
+ 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
+ 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
+ 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
+ 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
+ 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
+ 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
+ 0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA,
+ 0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38,
+ 0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64,
+ 0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43,
+ 0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E,
+ 0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF,
+ 0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29,
+ 0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65,
+ 0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02,
+ 0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4,
+ 0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82,
+ 0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C,
+ 0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51,
+ 0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22,
+ 0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74,
+ 0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE,
+ 0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C,
+ 0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC,
+ 0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B,
+ 0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9,
+ 0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0,
+ 0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31,
+ 0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57,
+ 0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8,
+ 0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E,
+ 0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30,
+ 0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E,
+ 0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE,
+ 0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D,
+ 0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D,
+ 0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E,
+ 0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C,
+ 0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static const ssl3DHParams ff_dhe_8192 = {
+ { siBuffer, (unsigned char *)ff_dhe_8192_p, sizeof(ff_dhe_8192_p) },
+ { siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
+};
diff --git a/chromium/net/third_party/nss/ssl/dtlscon.c b/chromium/net/third_party/nss/ssl/dtlscon.c
index 89315eee041..1b21107094e 100644
--- a/chromium/net/third_party/nss/ssl/dtlscon.c
+++ b/chromium/net/third_party/nss/ssl/dtlscon.c
@@ -104,9 +104,7 @@ ssl3_DisableNonDTLSSuites(sslSocket * ss)
const ssl3CipherSuite * suite;
for (suite = nonDTLSSuites; *suite; ++suite) {
- SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
-
- PORT_Assert(rv == SECSuccess); /* else is coding error */
+ PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE));
}
return SECSuccess;
}
@@ -229,7 +227,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
if (message_length > MAX_HANDSHAKE_MSG_LEN) {
(void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
return SECFailure;
}
#undef MAX_HANDSHAKE_MSG_LEN
@@ -396,7 +394,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
* This avoids having to fill in the bitmask in the common
* case of adjacent fragments received in sequence
*/
- if (fragment_offset <= ss->ssl3.hs.recvdHighWater) {
+ if (fragment_offset <= (unsigned int)ss->ssl3.hs.recvdHighWater) {
/* Either this is the adjacent fragment or an overlapping
* fragment */
ss->ssl3.hs.recvdHighWater = fragment_offset +
@@ -676,7 +674,7 @@ dtls_TransmitMessageFlight(sslSocket *ss)
/* The reason we use 8 here is that that's the length of
* the new DTLS data that we add to the header */
- fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
+ fragment_len = PR_MIN((PRUint32)room_left - (SSL3_BUFFER_FUDGE + 8),
content_len - fragment_offset);
PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
/* Make totally sure that we are within the buffer.
diff --git a/chromium/net/third_party/nss/ssl/ssl.h b/chromium/net/third_party/nss/ssl/ssl.h
index 57771cd5b98..bc417a5e4be 100644
--- a/chromium/net/third_party/nss/ssl/ssl.h
+++ b/chromium/net/third_party/nss/ssl/ssl.h
@@ -185,14 +185,26 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
/* SSL_REUSE_SERVER_ECDHE_KEY controls whether the ECDHE server key is
* reused for multiple handshakes or generated each time.
* SSL_REUSE_SERVER_ECDHE_KEY is currently enabled by default.
+ * This socket option is for ECDHE, only. It is unrelated to DHE.
*/
#define SSL_REUSE_SERVER_ECDHE_KEY 27
#define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in
* handshakes. */
+/* SSL_ENABLE_SERVER_DHE controls whether DHE is enabled for the server socket.
+ */
+#define SSL_ENABLE_SERVER_DHE 29
+
+/* Use draft-ietf-tls-session-hash. Controls whether we offer the
+ * extended_master_secret extension which, when accepted, hashes
+ * the handshake transcript into the master secret. This option is
+ * disabled by default.
+ */
+#define SSL_ENABLE_EXTENDED_MASTER_SECRET 30
+
/* Request Signed Certificate Timestamps via TLS extension (client) */
-#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 29
+#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 31
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
@@ -295,6 +307,86 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled);
SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
+/*
+** Control for TLS signature algorithms for TLS 1.2 only.
+**
+** This governs what signature algorithms are sent by a client in the
+** signature_algorithms extension. A client will not accept a signature from a
+** server unless it uses an enabled algorithm.
+**
+** This also governs what the server sends in the supported_signature_algorithms
+** field of a CertificateRequest. It also changes what the server uses to sign
+** ServerKeyExchange: a server uses the first entry from this list that is
+** compatible with the client's advertised signature_algorithms extension and
+** the selected server certificate.
+**
+** Omitting SHA-256 from this list might be foolish. Support is mandatory in
+** TLS 1.2 and there might be interoperability issues. For a server, NSS only
+** supports SHA-256 for verifying a TLS 1.2 CertificateVerify. This list needs
+** to include SHA-256 if client authentication is requested or required, or
+** creating a CertificateRequest will fail.
+*/
+SSL_IMPORT SECStatus SSL_SignaturePrefSet(
+ PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms,
+ unsigned int count);
+
+/*
+** Get the currently configured signature algorithms.
+**
+** The algorithms are written to |algorithms| but not if there are more than
+** |maxCount| values configured. The number of algorithms that are in use are
+** written to |count|. This fails if |maxCount| is insufficiently large.
+*/
+SSL_IMPORT SECStatus SSL_SignaturePrefGet(
+ PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms, unsigned int *count,
+ unsigned int maxCount);
+
+/*
+** Returns the maximum number of signature algorithms that are supported and
+** can be set or retrieved using SSL_SignaturePrefSet or SSL_SignaturePrefGet.
+*/
+SSL_IMPORT unsigned int SSL_SignatureMaxCount();
+
+/* SSL_DHEGroupPrefSet is used to configure the set of allowed/enabled DHE group
+** parameters that can be used by NSS for the given server socket.
+** The first item in the array is used as the default group, if no other
+** selection criteria can be used by NSS.
+** The set is provided as an array of identifiers as defined by SSLDHEGroupType.
+** If more than one group identifier is provided, NSS will select the one to use.
+** For example, a TLS extension sent by the client might indicate a preference.
+*/
+SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd,
+ SSLDHEGroupType *groups,
+ PRUint16 num_groups);
+
+/* Enable the use of a DHE group that's smaller than the library default,
+** for backwards compatibility reasons. The DH parameters will be created
+** at the time this function is called, which might take a very long time.
+** The function will block until generation is completed.
+** The intention is to enforce that fresh and safe parameters are generated
+** each time a process is started.
+** At the time this API was initially implemented, the API will enable the
+** use of 1024 bit DHE parameters. This value might get increased in future
+** versions of NSS.
+**
+** It is allowed to call this API will a NULL value for parameter fd,
+** which will prepare the global parameters that NSS will reuse for the remainder
+** of the process lifetime. This can be used early after startup of a process,
+** to avoid a delay when handling incoming client connections.
+** This preparation with a NULL for parameter fd will NOT enable the weak group
+** on sockets. The function needs to be called again for every socket that
+** should use the weak group.
+**
+** It is allowed to use this API in combination with the SSL_DHEGroupPrefSet API.
+** If both APIs have been called, the weakest group will be used,
+** unless it is certain that the client supports larger group parameters.
+** The weak group will be used as the default group, overriding the preference
+** for the first group potentially set with a call to SSL_DHEGroupPrefSet
+** (The first group set using SSL_DHEGroupPrefSet will still be enabled, but
+** it's no longer the default group.)
+*/
+SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled);
+
/* SSL_CipherOrderSet sets the cipher suite preference order from |ciphers|,
* which must be an array of cipher suite ids of length |len|. All the given
* cipher suite ids must appear in the array that is returned by
@@ -1012,10 +1104,27 @@ SSL_IMPORT SECStatus NSS_SetFrancePolicy(void);
SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void);
/* Report more information than SSL_SecurityStatus.
-** Caller supplies the info struct. Function fills it in.
-*/
+ * Caller supplies the info struct. This function fills it in.
+ * The information here will be zeroed prior to details being confirmed. The
+ * details are confirmed either when a Finished message is received, or - for a
+ * client - when the second flight of messages have been sent. This function
+ * therefore produces unreliable results prior to receiving the
+ * SSLHandshakeCallback or the SSLCanFalseStartCallback.
+ */
SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info,
PRUintn len);
+/* Get preliminary information about a channel.
+ * This function can be called prior to handshake details being confirmed (see
+ * SSL_GetChannelInfo above for what that means). Thus, information provided by
+ * this function is available to SSLAuthCertificate, SSLGetClientAuthData,
+ * SSLSNISocketConfig, and other callbacks that might be called during the
+ * processing of the first flight of client of server handshake messages.
+ * Values are marked as being unavailable when renegotiation is initiated.
+ */
+SSL_IMPORT SECStatus
+SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
+ SSLPreliminaryChannelInfo *info,
+ PRUintn len);
SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
SSLCipherSuiteInfo *info, PRUintn len);
diff --git a/chromium/net/third_party/nss/ssl/ssl3con.c b/chromium/net/third_party/nss/ssl/ssl3con.c
index 02b0ddaf9f1..e5e620fd34c 100644
--- a/chromium/net/third_party/nss/ssl/ssl3con.c
+++ b/chromium/net/third_party/nss/ssl/ssl3con.c
@@ -25,6 +25,8 @@
#include "prerror.h"
#include "pratom.h"
#include "prthread.h"
+#include "nss.h"
+#include "nssoptions.h"
#include "pk11func.h"
#include "secmod.h"
@@ -91,8 +93,11 @@ static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss,
const unsigned char *b,
unsigned int l);
+static SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss,
+ ssl3CipherSpec *spec,
+ SSL3Hashes *hashes,
+ PRUint32 sender);
static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
-static int ssl3_OIDToTLSHashAlgorithm(SECOidTag oid);
static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
int maxOutputLen, const unsigned char *input,
@@ -122,17 +127,17 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
#ifndef NSS_DISABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around
* bug 946147.
*/
- { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
@@ -140,14 +145,17 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
#endif /* NSS_DISABLE_ECC */
{ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
@@ -205,6 +213,23 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ TLS_RSA_WITH_NULL_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE},
};
+static const SSLSignatureAndHashAlg defaultSignatureAlgorithms[] = {
+ {ssl_hash_sha256, ssl_sign_rsa},
+ {ssl_hash_sha384, ssl_sign_rsa},
+ {ssl_hash_sha512, ssl_sign_rsa},
+ {ssl_hash_sha1, ssl_sign_rsa},
+#ifndef NSS_DISABLE_ECC
+ {ssl_hash_sha256, ssl_sign_ecdsa},
+ {ssl_hash_sha384, ssl_sign_ecdsa},
+ {ssl_hash_sha512, ssl_sign_ecdsa},
+ {ssl_hash_sha1, ssl_sign_ecdsa},
+#endif
+ {ssl_hash_sha256, ssl_sign_dsa},
+ {ssl_hash_sha1, ssl_sign_dsa}
+};
+PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureAlgorithms) <=
+ MAX_SIGNATURE_ALGORITHMS);
+
/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
*/
#ifdef DEBUG
@@ -265,20 +290,6 @@ static const /*SSL3ClientCertificateType */ PRUint8 certificate_types [] = {
ct_DSS_sign,
};
-/* This block is the contents of the supported_signature_algorithms field of
- * our TLS 1.2 CertificateRequest message, in wire format. See
- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
- *
- * This block contains only sha256 entries because we only support TLS 1.2
- * CertificateVerify messages that use the handshake hash. */
-static const PRUint8 supported_signature_algorithms[] = {
- tls_hash_sha256, tls_sig_rsa,
-#ifndef NSS_DISABLE_ECC
- tls_hash_sha256, tls_sig_ecdsa,
-#endif
- tls_hash_sha256, tls_sig_dsa,
-};
-
#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
@@ -322,8 +333,8 @@ static const ssl3KEADef kea_defs[] =
/* kea exchKeyType signKeyType is_limited limit tls_keygen ephemeral */
{kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE, PR_FALSE},
{kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
- {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_TRUE},
- {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE, PR_TRUE},
+ {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_FALSE},
+ {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE, PR_FALSE},
{kea_dh_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
{kea_dh_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE, PR_FALSE},
{kea_dh_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
@@ -443,6 +454,10 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] =
{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_rsa},
{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa},
+ {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss},
+ {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss},
+ {TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_dss},
+
#ifndef NSS_DISABLE_ECC
{TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa},
{TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa},
@@ -680,6 +695,8 @@ ssl3_CipherSuiteAllowedForVersionRange(
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
case TLS_RSA_WITH_AES_128_CBC_SHA256:
case TLS_RSA_WITH_AES_128_GCM_SHA256:
+ case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+ case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
case TLS_RSA_WITH_NULL_SHA256:
return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2;
@@ -688,6 +705,7 @@ ssl3_CipherSuiteAllowedForVersionRange(
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+ case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2;
/* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and
@@ -810,16 +828,11 @@ ssl3_config_match_init(sslSocket *ss)
* that the server uses an RSA cert for (EC)DHE-RSA.
*/
switch (cipher_def->key_exchange_alg) {
+ case kea_dhe_dss:
+ svrAuth = ss->serverCerts + ssl_kea_dh;
+ break;
case kea_ecdhe_rsa:
-#if NSS_SERVER_DHE_IMPLEMENTED
- /* XXX NSS does not yet implement the server side of _DHE_
- * cipher suites. Correcting the computation for svrAuth,
- * as the case below does, causes NSS SSL servers to begin to
- * negotiate cipher suites they do not implement. So, until
- * server side _DHE_ is implemented, keep this disabled.
- */
case kea_dhe_rsa:
-#endif
svrAuth = ss->serverCerts + kt_rsa;
break;
case kea_ecdh_ecdsa:
@@ -831,6 +844,8 @@ ssl3_config_match_init(sslSocket *ss)
* simultaneously. For now, both of them use
* whatever is in the certificate slot for kt_ecdh
*/
+ case kea_dhe_dss_export:
+ case kea_dhe_rsa_export:
default:
svrAuth = ss->serverCerts + exchKeyType;
break;
@@ -867,11 +882,22 @@ ssl3_config_match_init(sslSocket *ss)
* cipher suite. */
static PRBool
config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled,
- const SSLVersionRange *vrange)
+ const SSLVersionRange *vrange, const sslSocket *ss)
{
+ const ssl3CipherSuiteDef *cipher_def;
+
PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE);
if (policy == SSL_NOT_ALLOWED || !enabled)
- return PR_FALSE;
+ return PR_FALSE;
+
+ cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite);
+ PORT_Assert(cipher_def != NULL);
+
+ PORT_Assert(ss != NULL);
+ if (ss->sec.isServer && !ss->opt.enableServerDhe &&
+ kea_defs[cipher_def->key_exchange_alg].exchKeyType == ssl_kea_dh)
+ return PR_FALSE;
+
return (PRBool)(suite->enabled &&
suite->isPresent &&
suite->policy != SSL_NOT_ALLOWED &&
@@ -892,7 +918,7 @@ count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
return 0;
}
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange))
+ if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange, ss))
count++;
}
if (count <= 0) {
@@ -984,9 +1010,9 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
break;
case dsaKey:
doDerEncode = isTLS;
- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
* In that case, we use just the SHA1 part. */
- if (hash->hashAlg == SEC_OID_UNKNOWN) {
+ if (hash->hashAlg == ssl_hash_none) {
hashItem.data = hash->u.s.sha;
hashItem.len = sizeof(hash->u.s.sha);
} else {
@@ -997,9 +1023,9 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
#ifndef NSS_DISABLE_ECC
case ecKey:
doDerEncode = PR_TRUE;
- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
* In that case, we use just the SHA1 part. */
- if (hash->hashAlg == SEC_OID_UNKNOWN) {
+ if (hash->hashAlg == ssl_hash_none) {
hashItem.data = hash->u.s.sha;
hashItem.len = sizeof(hash->u.s.sha);
} else {
@@ -1014,7 +1040,7 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
}
PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));
- if (hash->hashAlg == SEC_OID_UNKNOWN) {
+ if (hash->hashAlg == ssl_hash_none) {
signatureLen = PK11_SignatureLen(key);
if (signatureLen <= 0) {
PORT_SetError(SEC_ERROR_INVALID_KEY);
@@ -1028,7 +1054,8 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
rv = PK11_Sign(key, buf, &hashItem);
} else {
- rv = SGN_Digest(key, hash->hashAlg, buf, &hashItem);
+ SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(hash->hashAlg);
+ rv = SGN_Digest(key, hashOID, buf, &hashItem);
}
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);
@@ -1076,7 +1103,7 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
return SECFailure;
}
- hashAlg = hash->hashAlg;
+ hashAlg = ssl3_TLSHashAlgorithmToOID(hash->hashAlg);
switch (key->keyType) {
case rsaKey:
encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
@@ -1085,9 +1112,9 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
break;
case dsaKey:
encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
* In that case, we use just the SHA1 part. */
- if (hash->hashAlg == SEC_OID_UNKNOWN) {
+ if (hash->hashAlg == ssl_hash_none) {
hashItem.data = hash->u.s.sha;
hashItem.len = sizeof(hash->u.s.sha);
} else {
@@ -1108,13 +1135,13 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
#ifndef NSS_DISABLE_ECC
case ecKey:
encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
- /* SEC_OID_UNKNOWN is used to specify the MD5/SHA1 concatenated hash.
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
* In that case, we use just the SHA1 part.
* ECDSA signatures always encode the integers r and s using ASN.1
* (unlike DSA where ASN.1 encoding is used with TLS but not with
* SSL3). So we can use VFY_VerifyDigestDirect for ECDSA.
*/
- if (hash->hashAlg == SEC_OID_UNKNOWN) {
+ if (hash->hashAlg == ssl_hash_none) {
hashAlg = SEC_OID_SHA1;
hashItem.data = hash->u.s.sha;
hashItem.len = sizeof(hash->u.s.sha);
@@ -1142,8 +1169,8 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
*/
rv = PK11_Verify(key, buf, &hashItem, pwArg);
} else {
- rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg,
- pwArg);
+ rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg,
+ pwArg);
}
SECKEY_DestroyPublicKey(key);
if (signature) {
@@ -1159,75 +1186,71 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
/* Caller must set hiLevel error code. */
/* Called from ssl3_ComputeExportRSAKeyHash
* ssl3_ComputeDHKeyHash
- * which are called from ssl3_HandleServerKeyExchange.
+ * which are called from ssl3_HandleServerKeyExchange.
*
- * hashAlg: either the OID for a hash algorithm or SEC_OID_UNKNOWN to specify
- * the pre-1.2, MD5/SHA1 combination hash.
+ * hashAlg: ssl_hash_none indicates the pre-1.2, MD5/SHA1 combination hash.
*/
SECStatus
-ssl3_ComputeCommonKeyHash(SECOidTag hashAlg,
- PRUint8 * hashBuf, unsigned int bufLen,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
+ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
+ PRUint8 * hashBuf, unsigned int bufLen,
+ SSL3Hashes *hashes, PRBool bypassPKCS11)
{
- SECStatus rv = SECSuccess;
+ SECStatus rv;
+ SECOidTag hashOID;
#ifndef NO_PKCS11_BYPASS
if (bypassPKCS11) {
- if (hashAlg == SEC_OID_UNKNOWN) {
- MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen);
- SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen);
- hashes->len = MD5_LENGTH + SHA1_LENGTH;
- } else if (hashAlg == SEC_OID_SHA1) {
- SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA1_LENGTH;
- } else if (hashAlg == SEC_OID_SHA256) {
- SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA256_LENGTH;
- } else if (hashAlg == SEC_OID_SHA384) {
- SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA384_LENGTH;
- } else if (hashAlg == SEC_OID_SHA512) {
- SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA512_LENGTH;
- } else {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
- return SECFailure;
- }
- } else
+ if (hashAlg == ssl_hash_none) {
+ MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen);
+ SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen);
+ hashes->len = MD5_LENGTH + SHA1_LENGTH;
+ } else if (hashAlg == ssl_hash_sha1) {
+ SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen);
+ hashes->len = SHA1_LENGTH;
+ } else if (hashAlg == ssl_hash_sha256) {
+ SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen);
+ hashes->len = SHA256_LENGTH;
+ } else if (hashAlg == ssl_hash_sha384) {
+ SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen);
+ hashes->len = SHA384_LENGTH;
+ } else if (hashAlg == ssl_hash_sha512) {
+ SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen);
+ hashes->len = SHA512_LENGTH;
+ } else {
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
+ return SECFailure;
+ }
+ } else
#endif
{
- if (hashAlg == SEC_OID_UNKNOWN) {
- rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- }
- hashes->len = MD5_LENGTH + SHA1_LENGTH;
- } else {
- hashes->len = HASH_ResultLenByOidTag(hashAlg);
- if (hashes->len > sizeof(hashes->u.raw)) {
- ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
- rv = SECFailure;
- goto done;
- }
- rv = PK11_HashBuf(hashAlg, hashes->u.raw, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- rv = SECFailure;
- }
- }
+ if (hashAlg == ssl_hash_none) {
+ rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ return rv;
+ }
+ rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return rv;
+ }
+ hashes->len = MD5_LENGTH + SHA1_LENGTH;
+ } else {
+ hashOID = ssl3_TLSHashAlgorithmToOID(hashAlg);
+ hashes->len = HASH_ResultLenByOidTag(hashOID);
+ if (hashes->len == 0 || hashes->len > sizeof(hashes->u.raw)) {
+ ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
+ return SECFailure;
+ }
+ rv = PK11_HashBuf(hashOID, hashes->u.raw, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ return rv;
+ }
+ }
}
hashes->hashAlg = hashAlg;
-
-done:
- return rv;
+ return SECSuccess;
}
/* Caller must set hiLevel error code.
@@ -1235,10 +1258,10 @@ done:
** ssl3_HandleServerKeyExchange.
*/
static SECStatus
-ssl3_ComputeExportRSAKeyHash(SECOidTag hashAlg,
- SECItem modulus, SECItem publicExponent,
- SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
+ssl3_ComputeExportRSAKeyHash(SSLHashType hashAlg,
+ SECItem modulus, SECItem publicExponent,
+ SSL3Random *client_rand, SSL3Random *server_rand,
+ SSL3Hashes *hashes, PRBool bypassPKCS11)
{
PRUint8 * hashBuf;
PRUint8 * pBuf;
@@ -1276,7 +1299,7 @@ ssl3_ComputeExportRSAKeyHash(SECOidTag hashAlg,
bypassPKCS11);
PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));
- if (hashAlg == SEC_OID_UNKNOWN) {
+ if (hashAlg == ssl_hash_none) {
PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result",
hashes->u.s.md5, MD5_LENGTH));
PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result",
@@ -1294,10 +1317,10 @@ ssl3_ComputeExportRSAKeyHash(SECOidTag hashAlg,
/* Caller must set hiLevel error code. */
/* Called from ssl3_HandleServerKeyExchange. */
static SECStatus
-ssl3_ComputeDHKeyHash(SECOidTag hashAlg,
- SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
- SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
+ssl3_ComputeDHKeyHash(SSLHashType hashAlg,
+ SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
+ SSL3Random *client_rand, SSL3Random *server_rand,
+ SSL3Hashes *hashes, PRBool bypassPKCS11)
{
PRUint8 * hashBuf;
PRUint8 * pBuf;
@@ -1340,7 +1363,7 @@ ssl3_ComputeDHKeyHash(SECOidTag hashAlg,
bypassPKCS11);
PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen));
- if (hashAlg == SEC_OID_UNKNOWN) {
+ if (hashAlg == ssl_hash_none) {
PRINT_BUF(95, (NULL, "DHkey hash: MD5 result",
hashes->u.s.md5, MD5_LENGTH));
PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result",
@@ -2298,7 +2321,11 @@ fail:
* Sets error code, but caller probably should override to disambiguate.
* NULL pms means re-use old master_secret.
*
- * This code is common to the bypass and PKCS11 execution paths.
+ * This code is common to the bypass and PKCS11 execution paths. For
+ * the bypass case, pms is NULL. If the old master secret is reused,
+ * pms is NULL and the master secret is already in either
+ * pwSpec->msItem.len (the bypass case) or pwSpec->master_secret.
+ *
* For the bypass case, pms is NULL.
*/
SECStatus
@@ -2682,7 +2709,7 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
PRUint32 fragLen;
PRUint32 p1Len, p2Len, oddLen = 0;
PRUint16 headerLen;
- int ivLen = 0;
+ unsigned int ivLen = 0;
int cipherBytes = 0;
unsigned char pseudoHeader[13];
unsigned int pseudoHeaderLen;
@@ -3244,7 +3271,8 @@ ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
{
static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
ssl_SEND_FLAG_CAP_RECORD_VERSION;
- PRInt32 rv = SECSuccess;
+ PRInt32 count = -1;
+ SECStatus rv = SECSuccess;
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
@@ -3258,18 +3286,19 @@ ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
} else {
- rv = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf,
+ count = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf,
ss->sec.ci.sendBuf.len, flags);
}
- if (rv < 0) {
+ if (count < 0) {
int err = PORT_GetError();
PORT_Assert(err != PR_WOULD_BLOCK_ERROR);
if (err == PR_WOULD_BLOCK_ERROR) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
}
- } else if (rv < ss->sec.ci.sendBuf.len) {
+ rv = SECFailure;
+ } else if ((unsigned int)count < ss->sec.ci.sendBuf.len) {
/* short write should never happen */
- PORT_Assert(rv >= ss->sec.ci.sendBuf.len);
+ PORT_Assert((unsigned int)count >= ss->sec.ci.sendBuf.len);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
} else {
@@ -3705,13 +3734,70 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
return SECSuccess;
}
-/* This method uses PKCS11 to derive the MS from the PMS, where PMS
-** is a PKCS11 symkey. This is used in all cases except the
-** "triple bypass" with RSA key exchange.
-** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec.
+/* This method completes the derivation of the MS from the PMS.
+**
+** 1. Derive the MS, if possible, else return an error.
+**
+** 2. Check the version if |pms_version| is non-zero and if wrong,
+** return an error.
+**
+** 3. If |msp| is nonzero, return MS in |*msp|.
+
+** Called from:
+** ssl3_ComputeMasterSecretInt
+** tls_ComputeExtendedMasterSecretInt
*/
static SECStatus
-ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
+ssl3_ComputeMasterSecretFinish(sslSocket *ss,
+ CK_MECHANISM_TYPE master_derive,
+ CK_MECHANISM_TYPE key_derive,
+ CK_VERSION *pms_version,
+ SECItem *params, CK_FLAGS keyFlags,
+ PK11SymKey *pms, PK11SymKey **msp)
+{
+ PK11SymKey *ms = NULL;
+
+ ms = PK11_DeriveWithFlags(pms, master_derive,
+ params, key_derive,
+ CKA_DERIVE, 0, keyFlags);
+ if (!ms) {
+ ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ return SECFailure;
+ }
+
+ if (pms_version && ss->opt.detectRollBack) {
+ SSL3ProtocolVersion client_version;
+ client_version = pms_version->major << 8 | pms_version->minor;
+
+ if (IS_DTLS(ss)) {
+ client_version = dtls_DTLSVersionToTLSVersion(client_version);
+ }
+
+ if (client_version != ss->clientHelloVersion) {
+ /* Destroy MS. Version roll-back detected. */
+ PK11_FreeSymKey(ms);
+ ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ return SECFailure;
+ }
+ }
+
+ if (msp) {
+ *msp = ms;
+ } else {
+ PK11_FreeSymKey(ms);
+ }
+
+ return SECSuccess;
+}
+
+/* Compute the ordinary (pre draft-ietf-tls-session-hash) master
+ ** secret and return it in |*msp|.
+ **
+ ** Called from: ssl3_ComputeMasterSecret
+ */
+static SECStatus
+ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
+ PK11SymKey **msp)
{
ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def;
@@ -3721,28 +3807,27 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
(pwSpec->version > SSL_LIBRARY_VERSION_3_0));
PRBool isTLS12=
(PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
- /*
+ /*
* Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
* which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
- * data into a 48-byte value.
+ * data into a 48-byte value, and does not expect to return the version.
*/
PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
(ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
- SECStatus rv = SECFailure;
CK_MECHANISM_TYPE master_derive;
CK_MECHANISM_TYPE key_derive;
SECItem params;
CK_FLAGS keyFlags;
CK_VERSION pms_version;
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
+ CK_VERSION *pms_version_ptr = NULL;
+ /* master_params may be used as a CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params;
+ unsigned int master_params_len;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
if (isTLS12) {
- if(isDH) master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
- else master_derive = CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256;
- key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
+ if(isDH) master_derive = CKM_TLS12_MASTER_KEY_DERIVE_DH;
+ else master_derive = CKM_TLS12_MASTER_KEY_DERIVE;
+ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
keyFlags = CKF_SIGN | CKF_VERIFY;
} else if (isTLS) {
if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH;
@@ -3756,87 +3841,142 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
keyFlags = 0;
}
- if (pms || !pwSpec->master_secret) {
- if (isDH) {
- master_params.pVersion = NULL;
- } else {
- master_params.pVersion = &pms_version;
- }
- master_params.RandomInfo.pClientRandom = cr;
- master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
- master_params.RandomInfo.pServerRandom = sr;
- master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
+ if (!isDH) {
+ pms_version_ptr = &pms_version;
+ }
- params.data = (unsigned char *) &master_params;
- params.len = sizeof master_params;
+ master_params.pVersion = pms_version_ptr;
+ master_params.RandomInfo.pClientRandom = cr;
+ master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
+ master_params.RandomInfo.pServerRandom = sr;
+ master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
+ if (isTLS12) {
+ master_params.prfHashMechanism = CKM_SHA256;
+ master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
+ } else {
+ /* prfHashMechanism is not relevant with this PRF */
+ master_params_len = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
}
- if (pms != NULL) {
-#if defined(TRACE)
- if (ssl_trace >= 100) {
- SECStatus extractRV = PK11_ExtractKeyValue(pms);
- if (extractRV == SECSuccess) {
- SECItem * keyData = PK11_GetKeyData(pms);
- if (keyData && keyData->data && keyData->len) {
- ssl_PrintBuf(ss, "Pre-Master Secret",
- keyData->data, keyData->len);
- }
- }
- }
-#endif
- pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive,
- &params, key_derive, CKA_DERIVE, 0, keyFlags);
- if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
- SSL3ProtocolVersion client_version;
- client_version = pms_version.major << 8 | pms_version.minor;
+ params.data = (unsigned char *) &master_params;
+ params.len = master_params_len;
- if (IS_DTLS(ss)) {
- client_version = dtls_DTLSVersionToTLSVersion(client_version);
- }
+ return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive,
+ pms_version_ptr, &params,
+ keyFlags, pms, msp);
+}
- if (client_version != ss->clientHelloVersion) {
- /* Destroy it. Version roll-back detected. */
- PK11_FreeSymKey(pwSpec->master_secret);
- pwSpec->master_secret = NULL;
- }
- }
- if (pwSpec->master_secret == NULL) {
- /* Generate a faux master secret in the same slot as the old one. */
- PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms);
- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
+/* Compute the draft-ietf-tls-session-hash master
+** secret and return it in |*msp|.
+**
+** Called from: ssl3_ComputeMasterSecret
+*/
+static SECStatus
+tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
+ PK11SymKey **msp)
+{
+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
+ CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS extended_master_params;
+ SSL3Hashes hashes;
+ /*
+ * Determine whether to use the DH/ECDH or RSA derivation modes.
+ */
+ /*
+ * TODO(ekr@rtfm.com): Verify that the slot can handle this key expansion
+ * mode. Bug 1198298 */
+ PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
+ (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
+ CK_MECHANISM_TYPE master_derive;
+ CK_MECHANISM_TYPE key_derive;
+ SECItem params;
+ const CK_FLAGS keyFlags = CKF_SIGN | CKF_VERIFY;
+ CK_VERSION pms_version;
+ CK_VERSION *pms_version_ptr = NULL;
+ SECStatus rv;
- PK11_FreeSlot(slot);
- if (fpms != NULL) {
- pwSpec->master_secret = PK11_DeriveWithFlags(fpms,
- master_derive, &params, key_derive,
- CKA_DERIVE, 0, keyFlags);
- PK11_FreeSymKey(fpms);
- }
- }
+ rv = ssl3_ComputeHandshakeHashes(ss, pwSpec, &hashes, 0);
+ if (rv != SECSuccess) {
+ PORT_Assert(0); /* Should never fail */
+ ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ return SECFailure;
}
- if (pwSpec->master_secret == NULL) {
- /* Generate a faux master secret from the internal slot. */
- PK11SlotInfo * slot = PK11_GetInternalSlot();
- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
- PK11_FreeSlot(slot);
- if (fpms != NULL) {
- pwSpec->master_secret = PK11_DeriveWithFlags(fpms,
- master_derive, &params, key_derive,
- CKA_DERIVE, 0, keyFlags);
- if (pwSpec->master_secret == NULL) {
- pwSpec->master_secret = fpms; /* use the fpms as the master. */
- fpms = NULL;
- }
- }
- if (fpms) {
- PK11_FreeSymKey(fpms);
- }
+ if (isDH) {
+ master_derive = CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH;
+ } else {
+ master_derive = CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE;
+ pms_version_ptr = &pms_version;
}
- if (pwSpec->master_secret == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return rv;
+
+ if (pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
+ /* TLS 1.2 */
+ extended_master_params.prfHashMechanism = CKM_SHA256;
+ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
+ } else {
+ /* TLS < 1.2 */
+ extended_master_params.prfHashMechanism = CKM_TLS_PRF;
+ key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
}
+
+ extended_master_params.pVersion = pms_version_ptr;
+ extended_master_params.pSessionHash = hashes.u.raw;
+ extended_master_params.ulSessionHashLen = hashes.len;
+
+ params.data = (unsigned char *) &extended_master_params;
+ params.len = sizeof extended_master_params;
+
+ return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive,
+ pms_version_ptr, &params,
+ keyFlags, pms, msp);
+}
+
+
+/* Wrapper method to compute the master secret and return it in |*msp|.
+**
+** Called from ssl3_ComputeMasterSecret
+*/
+static SECStatus
+ssl3_ComputeMasterSecret(sslSocket *ss, PK11SymKey *pms,
+ PK11SymKey **msp)
+{
+ PORT_Assert(pms != NULL);
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
+
+ if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
+ return tls_ComputeExtendedMasterSecretInt(ss, pms, msp);
+ } else {
+ return ssl3_ComputeMasterSecretInt(ss, pms, msp);
+ }
+}
+
+/* This method uses PKCS11 to derive the MS from the PMS, where PMS
+** is a PKCS11 symkey. We call ssl3_ComputeMasterSecret to do the
+** computations and then modify the pwSpec->state as a side effect.
+**
+** This is used in all cases except the "triple bypass" with RSA key
+** exchange.
+**
+** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec.
+*/
+static SECStatus
+ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
+{
+ SECStatus rv;
+ PK11SymKey* ms = NULL;
+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
+
+ if (pms) {
+ rv = ssl3_ComputeMasterSecret(ss, pms, &ms);
+ pwSpec->master_secret = ms;
+ if (rv != SECSuccess)
+ return rv;
+ }
+
#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
SECItem * keydata;
@@ -3847,7 +3987,7 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
rv = PK11_ExtractKeyValue(pwSpec->master_secret);
if (rv != SECSuccess) {
return rv;
- }
+ }
/* This returns the address of the secItem inside the key struct,
* not a copy or a reference. So, there's no need to free it.
*/
@@ -3862,10 +4002,10 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
}
}
#endif
+
return SECSuccess;
}
-
/*
* Derive encryption and MAC Keys (and IVs) from master secret
* Sets a useful error code when returning SECFailure.
@@ -3898,7 +4038,9 @@ ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss)
PK11SymKey * symKey = NULL;
void * pwArg = ss->pkcs11PinArg;
int keySize;
- CK_SSL3_KEY_MAT_PARAMS key_material_params;
+ CK_TLS12_KEY_MAT_PARAMS key_material_params; /* may be used as a
+ * CK_SSL3_KEY_MAT_PARAMS */
+ unsigned int key_material_params_len;
CK_SSL3_KEY_MAT_OUT returnedKeys;
CK_MECHANISM_TYPE key_derive;
CK_MECHANISM_TYPE bulk_mechanism;
@@ -3952,17 +4094,21 @@ ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss)
PORT_Assert( alg2Mech[calg].calg == calg);
bulk_mechanism = alg2Mech[calg].cmech;
- params.data = (unsigned char *)&key_material_params;
- params.len = sizeof(key_material_params);
-
if (isTLS12) {
- key_derive = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
+ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
+ key_material_params.prfHashMechanism = CKM_SHA256;
+ key_material_params_len = sizeof(CK_TLS12_KEY_MAT_PARAMS);
} else if (isTLS) {
key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
+ key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS);
} else {
key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
+ key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS);
}
+ params.data = (unsigned char *)&key_material_params;
+ params.len = key_material_params_len;
+
/* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and
* DERIVE by DEFAULT */
symKey = PK11_Derive(pwSpec->master_secret, key_derive, &params,
@@ -4273,6 +4419,12 @@ ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
PRUint8 b[4];
PRUint8 * p = b;
+ PORT_Assert(lenSize <= 4 && lenSize > 0);
+ if (lenSize < 4 && num >= (1L << (lenSize * 8))) {
+ PORT_SetError(SSL_ERROR_TX_RECORD_TOO_LONG);
+ return SECFailure;
+ }
+
switch (lenSize) {
case 4:
*p++ = (num >> 24) & 0xff;
@@ -4365,17 +4517,12 @@ ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
* |sigAndHash| to the current handshake message. */
SECStatus
ssl3_AppendSignatureAndHashAlgorithm(
- sslSocket *ss, const SSL3SignatureAndHashAlgorithm* sigAndHash)
+ sslSocket *ss, const SSLSignatureAndHashAlg* sigAndHash)
{
- unsigned char serialized[2];
+ PRUint8 serialized[2];
- serialized[0] = ssl3_OIDToTLSHashAlgorithm(sigAndHash->hashAlg);
- if (serialized[0] == 0) {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
- return SECFailure;
- }
-
- serialized[1] = sigAndHash->sigAlg;
+ serialized[0] = (PRUint8)sigAndHash->hashAlg;
+ serialized[1] = (PRUint8)sigAndHash->sigAlg;
return ssl3_AppendHandshake(ss, serialized, sizeof(serialized));
}
@@ -4470,6 +4617,7 @@ ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
PORT_Assert(bytes <= 3);
i->len = 0;
i->data = NULL;
+ i->type = siBuffer;
count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length);
if (count < 0) { /* Can't test for SECSuccess here. */
return SECFailure;
@@ -4489,15 +4637,13 @@ ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
/* tlsHashOIDMap contains the mapping between TLS hash identifiers and the
* SECOidTag used internally by NSS. */
static const struct {
- int tlsHash;
+ SSLHashType tlsHash;
SECOidTag oid;
} tlsHashOIDMap[] = {
- { tls_hash_md5, SEC_OID_MD5 },
- { tls_hash_sha1, SEC_OID_SHA1 },
- { tls_hash_sha224, SEC_OID_SHA224 },
- { tls_hash_sha256, SEC_OID_SHA256 },
- { tls_hash_sha384, SEC_OID_SHA384 },
- { tls_hash_sha512, SEC_OID_SHA512 }
+ { ssl_hash_sha1, SEC_OID_SHA1 },
+ { ssl_hash_sha256, SEC_OID_SHA256 },
+ { ssl_hash_sha384, SEC_OID_SHA384 },
+ { ssl_hash_sha512, SEC_OID_SHA512 }
};
/* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value.
@@ -4505,7 +4651,7 @@ static const struct {
*
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECOidTag
-ssl3_TLSHashAlgorithmToOID(int hashFunc)
+ssl3_TLSHashAlgorithmToOID(SSLHashType hashFunc)
{
unsigned int i;
@@ -4517,42 +4663,24 @@ ssl3_TLSHashAlgorithmToOID(int hashFunc)
return SEC_OID_UNKNOWN;
}
-/* ssl3_OIDToTLSHashAlgorithm converts an OID to a TLS hash algorithm
- * identifier. If the hash is not recognised, zero is returned.
- *
- * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
-static int
-ssl3_OIDToTLSHashAlgorithm(SECOidTag oid)
-{
- unsigned int i;
-
- for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap); i++) {
- if (oid == tlsHashOIDMap[i].oid) {
- return tlsHashOIDMap[i].tlsHash;
- }
- }
- return 0;
-}
-
/* ssl3_TLSSignatureAlgorithmForKeyType returns the TLS 1.2 signature algorithm
* identifier for a given KeyType. */
static SECStatus
-ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType,
- TLSSignatureAlgorithm *out)
+ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType, SSLSignType *out)
{
switch (keyType) {
case rsaKey:
- *out = tls_sig_rsa;
- return SECSuccess;
+ *out = ssl_sign_rsa;
+ return SECSuccess;
case dsaKey:
- *out = tls_sig_dsa;
- return SECSuccess;
+ *out = ssl_sign_dsa;
+ return SECSuccess;
case ecKey:
- *out = tls_sig_ecdsa;
- return SECSuccess;
+ *out = ssl_sign_ecdsa;
+ return SECSuccess;
default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ return SECFailure;
}
}
@@ -4560,15 +4688,15 @@ ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType,
* algorithm identifier for the given certificate. */
static SECStatus
ssl3_TLSSignatureAlgorithmForCertificate(CERTCertificate *cert,
- TLSSignatureAlgorithm *out)
+ SSLSignType *out)
{
SECKEYPublicKey *key;
KeyType keyType;
key = CERT_ExtractPublicKey(cert);
if (key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
+ ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ return SECFailure;
}
keyType = key->keyType;
@@ -4578,24 +4706,75 @@ ssl3_TLSSignatureAlgorithmForCertificate(CERTCertificate *cert,
/* ssl3_CheckSignatureAndHashAlgorithmConsistency checks that the signature
* algorithm identifier in |sigAndHash| is consistent with the public key in
- * |cert|. If so, SECSuccess is returned. Otherwise, PORT_SetError is called
- * and SECFailure is returned. */
+ * |cert|. It also checks the hash algorithm against the configured signature
+ * algorithms. If all the tests pass, SECSuccess is returned. Otherwise,
+ * PORT_SetError is called and SECFailure is returned. */
SECStatus
ssl3_CheckSignatureAndHashAlgorithmConsistency(
- const SSL3SignatureAndHashAlgorithm *sigAndHash, CERTCertificate* cert)
+ sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash,
+ CERTCertificate* cert)
{
SECStatus rv;
- TLSSignatureAlgorithm sigAlg;
+ SSLSignType sigAlg;
+ unsigned int i;
rv = ssl3_TLSSignatureAlgorithmForCertificate(cert, &sigAlg);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
if (sigAlg != sigAndHash->sigAlg) {
- PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
- return SECFailure;
+ PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
+ return SECFailure;
}
- return SECSuccess;
+
+ for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) {
+ const SSLSignatureAndHashAlg *alg = &ss->ssl3.signatureAlgorithms[i];
+ if (sigAndHash->sigAlg == alg->sigAlg &&
+ sigAndHash->hashAlg == alg->hashAlg) {
+ return SECSuccess;
+ }
+ }
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
+ return SECFailure;
+}
+
+PRBool
+ssl3_IsSupportedSignatureAlgorithm(const SSLSignatureAndHashAlg *alg)
+{
+ static const SSLHashType supportedHashes[] = {
+ ssl_hash_sha1,
+ ssl_hash_sha256,
+ ssl_hash_sha384,
+ ssl_hash_sha512
+ };
+
+ static const SSLSignType supportedSigAlgs[] = {
+ ssl_sign_rsa,
+#ifndef NSS_DISABLE_ECC
+ ssl_sign_ecdsa,
+#endif
+ ssl_sign_dsa
+ };
+
+ unsigned int i;
+ PRBool hashOK = PR_FALSE;
+ PRBool signOK = PR_FALSE;
+
+ for (i = 0; i < PR_ARRAY_SIZE(supportedHashes); ++i) {
+ if (alg->hashAlg == supportedHashes[i]) {
+ hashOK = PR_TRUE;
+ break;
+ }
+ }
+
+ for (i = 0; i < PR_ARRAY_SIZE(supportedSigAlgs); ++i) {
+ if (alg->sigAlg == supportedSigAlgs[i]) {
+ signOK = PR_TRUE;
+ break;
+ }
+ }
+
+ return hashOK && signOK;
}
/* ssl3_ConsumeSignatureAndHashAlgorithm reads a SignatureAndHashAlgorithm
@@ -4605,25 +4784,24 @@ ssl3_CheckSignatureAndHashAlgorithmConsistency(
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECStatus
ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss,
- SSL3Opaque **b,
- PRUint32 *length,
- SSL3SignatureAndHashAlgorithm *out)
+ SSL3Opaque **b,
+ PRUint32 *length,
+ SSLSignatureAndHashAlg *out)
{
- unsigned char bytes[2];
+ PRUint8 bytes[2];
SECStatus rv;
rv = ssl3_ConsumeHandshake(ss, bytes, sizeof(bytes), b, length);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
- out->hashAlg = ssl3_TLSHashAlgorithmToOID(bytes[0]);
- if (out->hashAlg == SEC_OID_UNKNOWN) {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
- return SECFailure;
+ out->hashAlg = (SSLHashType)bytes[0];
+ out->sigAlg = (SSLSignType)bytes[1];
+ if (!ssl3_IsSupportedSignatureAlgorithm(out)) {
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
+ return SECFailure;
}
-
- out->sigAlg = bytes[1];
return SECSuccess;
}
@@ -4653,7 +4831,12 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
SSL3Opaque sha_inner[MAX_MAC_LENGTH];
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- hashes->hashAlg = SEC_OID_UNKNOWN;
+ if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ hashes->hashAlg = ssl_hash_none;
#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11 &&
@@ -4661,11 +4844,6 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
/* compute them without PKCS11 */
PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
- if (!spec->msItem.data) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
ss->ssl3.hs.sha_clone(sha_cx, ss->ssl3.hs.sha_cx);
ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len,
sizeof(hashes->u.raw));
@@ -4674,7 +4852,7 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
/* If we ever support ciphersuites where the PRF hash isn't SHA-256
* then this will need to be updated. */
- hashes->hashAlg = SEC_OID_SHA256;
+ hashes->hashAlg = ssl_hash_sha256;
rv = SECSuccess;
} else if (ss->opt.bypassPKCS11) {
/* compute them without PKCS11 */
@@ -4684,11 +4862,6 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
#define md5cx ((MD5Context *)md5_cx)
#define shacx ((SHA1Context *)sha_cx)
- if (!spec->msItem.data) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
MD5_Clone (md5cx, (MD5Context *)ss->ssl3.hs.md5_cx);
SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx);
@@ -4696,6 +4869,11 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
/* compute hashes for SSL3. */
unsigned char s[4];
+ if (!spec->msItem.data) {
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
+ return SECFailure;
+ }
+
s[0] = (unsigned char)(sender >> 24);
s[1] = (unsigned char)(sender >> 16);
s[2] = (unsigned char)(sender >> 8);
@@ -4768,11 +4946,6 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
unsigned char stackBuf[1024];
unsigned char *stateBuf = NULL;
- if (!spec->master_secret) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
h = ss->ssl3.hs.sha;
stateBuf = PK11_SaveContextAlloc(h, stackBuf,
sizeof(stackBuf), &stateLen);
@@ -4789,7 +4962,7 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
}
/* If we ever support ciphersuites where the PRF hash isn't SHA-256
* then this will need to be updated. */
- hashes->hashAlg = SEC_OID_SHA256;
+ hashes->hashAlg = ssl_hash_sha256;
rv = SECSuccess;
tls12_loser:
@@ -4812,11 +4985,6 @@ tls12_loser:
unsigned char md5StackBuf[256];
unsigned char shaStackBuf[512];
- if (!spec->master_secret) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf,
sizeof md5StackBuf, &md5StateLen);
if (md5StateBuf == NULL) {
@@ -4837,6 +5005,11 @@ tls12_loser:
/* compute hashes for SSL3. */
unsigned char s[4];
+ if (!spec->master_secret) {
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
+ return SECFailure;
+ }
+
s[0] = (unsigned char)(sender >> 24);
s[1] = (unsigned char)(sender >> 16);
s[2] = (unsigned char)(sender >> 8);
@@ -4968,7 +5141,7 @@ ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
rv = SECFailure;
goto loser;
}
- hashes->hashAlg = SEC_OID_SHA1;
+ hashes->hashAlg = ssl_hash_sha1;
loser:
PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
@@ -5049,7 +5222,9 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
if (rv != SECSuccess) {
return rv; /* ssl3_InitState has set the error code. */
}
- ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */
+ /* These must be reset every handshake. */
+ ss->ssl3.hs.sendingSCSV = PR_FALSE;
+ ss->ssl3.hs.preliminaryInfo = 0;
PORT_Assert(IS_DTLS(ss) || !resending);
SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
@@ -5425,7 +5600,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
}
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) {
+ if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange, ss)) {
actual_count++;
if (actual_count > num_suites) {
if (sid->u.ssl3.lock) { NSSRWLock_UnlockRead(sid->u.ssl3.lock); }
@@ -6083,14 +6258,6 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
}
}
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
isTLS ? enc_pms.len + 2 : enc_pms.len);
if (rv != SECSuccess) {
@@ -6105,6 +6272,15 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
goto loser; /* err set by ssl3_AppendHandshake* */
}
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms);
+ pms = NULL;
+
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
rv = SECSuccess;
loser:
@@ -6174,14 +6350,6 @@ sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
SECKEY_DestroyPrivateKey(privKey);
privKey = NULL;
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
pubKey->u.dh.publicValue.len + 2);
if (rv != SECSuccess) {
@@ -6197,8 +6365,16 @@ sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
goto loser; /* err set by ssl3_AppendHandshake* */
}
- rv = SECSuccess;
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms);
+ pms = NULL;
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ rv = SECSuccess;
loser:
@@ -6240,9 +6416,9 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
/* enforce limits on kea key sizes. */
if (ss->ssl3.hs.kea_def->is_limited) {
- int keyLen = SECKEY_PublicKeyStrength(serverKey); /* bytes */
+ unsigned int keyLen = SECKEY_PublicKeyStrengthInBits(serverKey);
- if (keyLen * BPB > ss->ssl3.hs.kea_def->key_size_limit) {
+ if (keyLen > ss->ssl3.hs.kea_def->key_size_limit) {
if (isTLS)
(void)SSL3_SendAlert(ss, alert_fatal, export_restriction);
else
@@ -6297,7 +6473,7 @@ ssl3_SendCertificateVerify(sslSocket *ss)
SSL3Hashes hashes;
KeyType keyType;
unsigned int len;
- SSL3SignatureAndHashAlgorithm sigAndHash;
+ SSLSignatureAndHashAlg sigAndHash;
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
@@ -6362,11 +6538,11 @@ ssl3_SendCertificateVerify(sslSocket *ss)
}
if (isTLS12) {
rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType,
- &sigAndHash.sigAlg);
+ &sigAndHash.sigAlg);
if (rv != SECSuccess) {
goto done;
}
- sigAndHash.hashAlg = hashes.hashAlg;
+ sigAndHash.hashAlg = hashes.hashAlg;
rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
if (rv != SECSuccess) {
@@ -6474,6 +6650,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
errCode = SSL_ERROR_UNSUPPORTED_VERSION;
goto alert_loser;
}
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
rv = ssl3_InitHandshakeHashes(ss);
@@ -6509,7 +6686,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
if (temp == suite->cipher_suite) {
SSLVersionRange vrange = {ss->version, ss->version};
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) {
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) {
/* config_match already checks whether the cipher suite is
* acceptable for the version, but the check is repeated here
* in order to give a more precise error code. */
@@ -6533,6 +6710,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp;
ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp);
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
PORT_Assert(ss->ssl3.hs.suite_def);
if (!ss->ssl3.hs.suite_def) {
PORT_SetError(errCode = SEC_ERROR_LIBRARY_FAILURE);
@@ -6619,6 +6797,32 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECItem wrappedMS; /* wrapped master secret. */
+ /* [draft-ietf-tls-session-hash-06; Section 5.3]
+ *
+ * o If the original session did not use the "extended_master_secret"
+ * extension but the new ServerHello contains the extension, the
+ * client MUST abort the handshake.
+ */
+ if (!sid->u.ssl3.keys.extendedMasterSecretUsed &&
+ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
+ errCode = SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET;
+ goto alert_loser;
+ }
+
+ /*
+ * o If the original session used an extended master secret but the new
+ * ServerHello does not contain the "extended_master_secret"
+ * extension, the client SHOULD abort the handshake.
+ *
+ * TODO(ekr@rtfm.com): Add option to refuse to resume when EMS is not
+ * used at all (bug 1176526).
+ */
+ if (sid->u.ssl3.keys.extendedMasterSecretUsed &&
+ !ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
+ errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
+ goto alert_loser;
+ }
+
ss->sec.authAlgorithm = sid->authAlgorithm;
ss->sec.authKeyBits = sid->authKeyBits;
ss->sec.keaType = sid->keaType;
@@ -6721,7 +6925,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ssl3_CopyPeerCertsFromSID(ss, sid);
}
- /* NULL value for PMS signifies re-use of the old MS */
+ /* NULL value for PMS because we are reusing the old MS */
rv = ssl3_InitPendingCipherSpec(ss, NULL);
if (rv != SECSuccess) {
goto alert_loser; /* err code was set */
@@ -6750,6 +6954,9 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
sid->u.ssl3.sessionIDLength = sidBytes.len;
PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
+ sid->u.ssl3.keys.extendedMasterSecretUsed =
+ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
+
/* Copy Signed Certificate Timestamps, if any. */
if (ss->xtnData.signedCertTimestamps.data) {
rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
@@ -6761,13 +6968,14 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ss->ssl3.hs.isResuming = PR_FALSE;
if (ss->ssl3.hs.kea_def->signKeyType != sign_null) {
/* All current cipher suites other than those with sign_null (i.e.,
- * DH_anon_* suites) require a certificate, so use that signal. */
+ * (EC)DH_anon_* suites) require a certificate, so use that signal. */
ss->ssl3.hs.ws = wait_server_cert;
- } else if (ss->ssl3.hs.kea_def->ephemeral) {
- /* Only ephemeral cipher suites use ServerKeyExchange. */
- ss->ssl3.hs.ws = wait_server_key;
} else {
- ss->ssl3.hs.ws = wait_cert_request;
+ /* All the remaining cipher suites must be (EC)DH_anon_* and so
+ * must be ephemeral. Note, if we ever add PSK this might
+ * change. */
+ PORT_Assert(ss->ssl3.hs.kea_def->ephemeral);
+ ss->ssl3.hs.ws = wait_server_key;
}
winner:
@@ -6807,29 +7015,6 @@ loser:
return SECFailure;
}
-/* ssl3_BigIntGreaterThanOne returns true iff |mpint|, taken as an unsigned,
- * big-endian integer is > 1 */
-static PRBool
-ssl3_BigIntGreaterThanOne(const SECItem* mpint) {
- unsigned char firstNonZeroByte = 0;
- unsigned int i;
-
- for (i = 0; i < mpint->len; i++) {
- if (mpint->data[i]) {
- firstNonZeroByte = mpint->data[i];
- break;
- }
- }
-
- if (firstNonZeroByte == 0)
- return PR_FALSE;
- if (firstNonZeroByte > 1)
- return PR_TRUE;
-
- /* firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte
- * is followed by another byte. */
- return (i < mpint->len - 1);
-}
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 ServerKeyExchange message.
@@ -6846,9 +7031,9 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SSL3AlertDescription desc = illegal_parameter;
SSL3Hashes hashes;
SECItem signature = {siBuffer, NULL, 0};
- SSL3SignatureAndHashAlgorithm sigAndHash;
+ SSLSignatureAndHashAlg sigAndHash;
- sigAndHash.hashAlg = SEC_OID_UNKNOWN;
+ sigAndHash.hashAlg = ssl_hash_none;
SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake",
SSL_GETPID(), ss->fd));
@@ -6874,6 +7059,12 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) {
goto loser; /* malformed. */
}
+ /* This exchange method is only used by export cipher suites.
+ * Those are broken and so this code will eventually be removed. */
+ if (SECKEY_BigIntegerBitLength(&modulus) < 512) {
+ desc = isTLS ? insufficient_security : illegal_parameter;
+ goto alert_loser;
+ }
rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed. */
@@ -6884,7 +7075,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) {
goto loser; /* malformed or unsupported. */
}
- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
+ rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(ss,
&sigAndHash, ss->sec.peerCert);
if (rv != SECSuccess) {
goto loser;
@@ -6907,10 +7098,10 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/*
* check to make sure the hash is signed by right guy
*/
- rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, modulus, exponent,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
+ rv = ssl3_ComputeExportRSAKeyHash(sigAndHash.hashAlg, modulus, exponent,
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
if (rv != SECSuccess) {
errCode =
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
@@ -6936,7 +7127,6 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
if (peerKey == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
goto no_memory;
}
@@ -6947,7 +7137,6 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus, &modulus) ||
SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent))
{
- PORT_FreeArena(arena, PR_FALSE);
goto no_memory;
}
ss->sec.peerKey = peerKey;
@@ -6959,13 +7148,22 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECItem dh_p = {siBuffer, NULL, 0};
SECItem dh_g = {siBuffer, NULL, 0};
SECItem dh_Ys = {siBuffer, NULL, 0};
+ unsigned dh_p_bits;
+ unsigned dh_g_bits;
+ unsigned dh_Ys_bits;
+ PRInt32 minDH;
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed. */
}
- if (dh_p.len < 1024/8 ||
- (dh_p.len == 1024/8 && (dh_p.data[0] & 0x80) == 0)) {
+
+ rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH);
+ if (rv != SECSuccess) {
+ minDH = SSL_DH_MIN_P_BITS;
+ }
+ dh_p_bits = SECKEY_BigIntegerBitLength(&dh_p);
+ if (dh_p_bits < minDH) {
errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
goto alert_loser;
}
@@ -6973,13 +7171,16 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) {
goto loser; /* malformed. */
}
- if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_g))
+ /* Abort if dh_g is 0, 1, or obviously too big. */
+ dh_g_bits = SECKEY_BigIntegerBitLength(&dh_g);
+ if (dh_g_bits > dh_p_bits || dh_g_bits <= 1)
goto alert_loser;
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed. */
}
- if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys))
+ dh_Ys_bits = SECKEY_BigIntegerBitLength(&dh_Ys);
+ if (dh_Ys_bits > dh_p_bits || dh_Ys_bits <= 1)
goto alert_loser;
if (isTLS12) {
rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
@@ -6987,7 +7188,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) {
goto loser; /* malformed or unsupported. */
}
- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
+ rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(ss,
&sigAndHash, ss->sec.peerCert);
if (rv != SECSuccess) {
goto loser;
@@ -7014,10 +7215,10 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/*
* check to make sure the hash is signed by right guy
*/
- rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
+ rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys,
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
if (rv != SECSuccess) {
errCode =
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
@@ -7041,7 +7242,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto no_memory;
}
- ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
+ peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
if (peerKey == NULL) {
goto no_memory;
}
@@ -7055,7 +7256,6 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECITEM_CopyItem(arena, &peerKey->u.dh.base, &dh_g) ||
SECITEM_CopyItem(arena, &peerKey->u.dh.publicValue, &dh_Ys))
{
- PORT_FreeArena(arena, PR_FALSE);
goto no_memory;
}
ss->sec.peerKey = peerKey;
@@ -7078,10 +7278,16 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
PORT_SetError( errCode );
return SECFailure;
no_memory: /* no-memory error has already been set. */
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
return SECFailure;
}
@@ -7092,7 +7298,7 @@ no_memory: /* no-memory error has already been set. */
*/
static SECStatus
ssl3_ExtractClientKeyInfo(sslSocket *ss,
- TLSSignatureAlgorithm *sigAlg,
+ SSLSignType *sigAlg,
PRBool *preferSha1)
{
SECStatus rv = SECSuccess;
@@ -7148,7 +7354,7 @@ ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
const SECItem *algorithms)
{
SECStatus rv;
- TLSSignatureAlgorithm sigAlg;
+ SSLSignType sigAlg;
PRBool preferSha1;
PRBool supportsSha1 = PR_FALSE;
PRBool supportsSha256 = PR_FALSE;
@@ -7173,9 +7379,9 @@ ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
/* Determine the server's hash support for that signature algorithm. */
for (i = 0; i < algorithms->len; i += 2) {
if (algorithms->data[i+1] == sigAlg) {
- if (algorithms->data[i] == tls_hash_sha1) {
+ if (algorithms->data[i] == ssl_hash_sha1) {
supportsSha1 = PR_TRUE;
- } else if (algorithms->data[i] == tls_hash_sha256) {
+ } else if (algorithms->data[i] == ssl_hash_sha256) {
supportsSha256 = PR_TRUE;
}
}
@@ -7334,6 +7540,8 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
} else
#endif
if (ss->getClientAuthData != NULL) {
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
/* XXX Should pass cert_types and algorithms in this call!! */
rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
ss->fd, &ca_list,
@@ -7565,6 +7773,8 @@ ssl3_CheckFalseStart(sslSocket *ss)
SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
SSL_GETPID(), ss->fd));
} else {
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
rv = (ss->canFalseStartCallback)(ss->fd,
ss->canFalseStartCallbackData,
&ss->ssl3.hs.canFalseStart);
@@ -7923,6 +8133,7 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
sid->u.ssl3.policy = SSL_ALLOWED;
sid->u.ssl3.clientWriteKey = NULL;
sid->u.ssl3.serverWriteKey = NULL;
+ sid->u.ssl3.keys.extendedMasterSecretUsed = PR_FALSE;
if (is_server) {
SECStatus rv;
@@ -7975,7 +8186,7 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
/* see if we can legally use the key in the cert. */
- int keyLen; /* bytes */
+ unsigned int keyLen; /* bytes */
keyLen = PK11_GetPrivateModulusLen(
ss->serverCerts[kea_def->exchKeyType].SERVERKEY);
@@ -8022,6 +8233,22 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
/* An empty TLS Renegotiation Info (RI) extension */
static const PRUint8 emptyRIext[5] = {0xff, 0x01, 0x00, 0x01, 0x00};
+static PRBool
+ssl3_KEAAllowsSessionTicket(SSL3KeyExchangeAlgorithm kea)
+{
+ switch (kea) {
+ case kea_dhe_dss:
+ case kea_dhe_dss_export:
+ case kea_dh_dss_export:
+ case kea_dh_dss:
+ /* TODO: Fix session tickets for DSS. The server code rejects the
+ * session ticket received from the client. Bug 1174677 */
+ return PR_FALSE;
+ default:
+ return PR_TRUE;
+ };
+}
+
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 Client Hello message.
* Caller must hold Handshake and RecvBuf locks.
@@ -8044,6 +8271,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECItem comps = {siBuffer, NULL, 0};
PRBool haveSpecWriteLock = PR_FALSE;
PRBool haveXmitBufLock = PR_FALSE;
+ PRBool canOfferSessionTicket = PR_FALSE;
SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",
SSL_GETPID(), ss->fd));
@@ -8051,6 +8279,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert( ss->ssl3.initialized );
+ ss->ssl3.hs.preliminaryInfo = 0;
if (!ss->sec.isServer ||
(ss->ssl3.hs.ws != wait_client_hello &&
@@ -8116,6 +8345,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
errCode = SSL_ERROR_UNSUPPORTED_VERSION;
goto alert_loser;
}
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
rv = ssl3_InitHandshakeHashes(ss);
if (rv != SECSuccess) {
@@ -8283,8 +8513,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* resuming.)
*/
if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && sid == NULL) {
- ssl3_RegisterServerHelloExtensionSender(ss,
- ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn);
+ canOfferSessionTicket = PR_TRUE;
}
if (sid != NULL) {
@@ -8367,7 +8596,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* The product policy won't change during the process lifetime.
* Implemented ("isPresent") shouldn't change for servers.
*/
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange))
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss))
break;
#else
if (!suite->enabled)
@@ -8380,6 +8609,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ss->ssl3.hs.cipher_suite = suite->cipher_suite;
ss->ssl3.hs.suite_def =
ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
/* Use the cached compression method. */
ss->ssl3.hs.compression = sid->u.ssl3.compression;
@@ -8416,7 +8646,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
SSLVersionRange vrange = {ss->version, ss->version};
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) {
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) {
continue;
}
for (i = 0; i + 1 < suites.len; i += 2) {
@@ -8425,6 +8655,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ss->ssl3.hs.cipher_suite = suite->cipher_suite;
ss->ssl3.hs.suite_def =
ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
goto suite_found;
}
}
@@ -8433,6 +8664,15 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto alert_loser;
suite_found:
+ if (canOfferSessionTicket)
+ canOfferSessionTicket = ssl3_KEAAllowsSessionTicket(
+ ss->ssl3.hs.suite_def->key_exchange_alg);
+
+ if (canOfferSessionTicket) {
+ ssl3_RegisterServerHelloExtensionSender(ss,
+ ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn);
+ }
+
/* Select a compression algorithm. */
for (i = 0; i < comps.len; i++) {
if (!compressionEnabled(ss, comps.data[i]))
@@ -8458,6 +8698,8 @@ compression_found:
/* If there are any failures while processing the old sid,
* we don't consider them to be errors. Instead, We just behave
* as if the client had sent us no sid to begin with, and make a new one.
+ * The exception here is attempts to resume extended_master_secret
+ * sessions without the extension, which causes an alert.
*/
if (sid != NULL) do {
ssl3CipherSpec *pwSpec;
@@ -8469,6 +8711,30 @@ compression_found:
break; /* not an error */
}
+ /* [draft-ietf-tls-session-hash-06; Section 5.3]
+ * o If the original session did not use the "extended_master_secret"
+ * extension but the new ClientHello contains the extension, then the
+ * server MUST NOT perform the abbreviated handshake. Instead, it
+ * SHOULD continue with a full handshake (as described in
+ * Section 5.2) to negotiate a new session.
+ *
+ * o If the original session used the "extended_master_secret"
+ * extension but the new ClientHello does not contain the extension,
+ * the server MUST abort the abbreviated handshake.
+ */
+ if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
+ if (!sid->u.ssl3.keys.extendedMasterSecretUsed) {
+ break; /* not an error */
+ }
+ } else {
+ if (sid->u.ssl3.keys.extendedMasterSecretUsed) {
+ /* Note: we do not destroy the session */
+ desc = handshake_failure;
+ errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
+ goto alert_loser;
+ }
+ }
+
if (ss->sec.ci.sid) {
if (ss->sec.uncache)
ss->sec.uncache(ss->sec.ci.sid);
@@ -8610,7 +8876,7 @@ compression_found:
haveSpecWriteLock = PR_FALSE;
}
- /* NULL value for PMS signifies re-use of the old MS */
+ /* NULL value for PMS because we are re-using the old MS */
rv = ssl3_InitPendingCipherSpec(ss, NULL);
if (rv != SECSuccess) {
errCode = PORT_GetError();
@@ -8654,6 +8920,9 @@ compression_found:
if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
int ret = 0;
if (ss->sniSocketConfig) do { /* not a loop */
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
+
ret = SSL_SNI_SEND_ALERT;
/* If extension is negotiated, the len of names should > 0. */
if (ss->xtnData.sniNameArrSize) {
@@ -8701,7 +8970,7 @@ compression_found:
ret = SSL_SNI_SEND_ALERT;
break;
}
- } else if (ret < ss->xtnData.sniNameArrSize) {
+ } else if ((unsigned int)ret < ss->xtnData.sniNameArrSize) {
/* Application has configured new socket info. Lets check it
* and save the name. */
SECStatus rv;
@@ -8752,7 +9021,7 @@ compression_found:
ssl3_SendServerNameXtn);
} else {
/* Callback returned index outside of the boundary. */
- PORT_Assert(ret < ss->xtnData.sniNameArrSize);
+ PORT_Assert((unsigned int)ret < ss->xtnData.sniNameArrSize);
errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
desc = internal_error;
ret = SSL_SNI_SEND_ALERT;
@@ -8798,13 +9067,16 @@ compression_found:
}
ss->sec.ci.sid = sid;
+ sid->u.ssl3.keys.extendedMasterSecretUsed =
+ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
ss->ssl3.hs.isResuming = PR_FALSE;
ssl_GetXmitBufLock(ss);
rv = ssl3_SendServerHelloSequence(ss);
ssl_ReleaseXmitBufLock(ss);
if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
+ errCode = PORT_GetError();
+ desc = handshake_failure;
+ goto alert_loser;
}
if (haveXmitBufLock) {
@@ -8896,6 +9168,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
errCode = SSL_ERROR_UNSUPPORTED_VERSION;
goto alert_loser;
}
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
rv = ssl3_InitHandshakeHashes(ss);
if (rv != SECSuccess) {
@@ -8951,7 +9224,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
SSLVersionRange vrange = {ss->version, ss->version};
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange)) {
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) {
continue;
}
for (i = 0; i+2 < suite_length; i += 3) {
@@ -8960,6 +9233,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
ss->ssl3.hs.cipher_suite = suite->cipher_suite;
ss->ssl3.hs.suite_def =
ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
goto suite_found;
}
}
@@ -9150,6 +9424,154 @@ ssl3_SendServerHello(sslSocket *ss)
return SECSuccess;
}
+static SECStatus
+ssl3_PickSignatureHashAlgorithm(sslSocket *ss,
+ SSLSignatureAndHashAlg* out);
+
+static SECStatus
+ssl3_SendDHServerKeyExchange(sslSocket *ss)
+{
+ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
+ SECStatus rv = SECFailure;
+ int length;
+ PRBool isTLS;
+ SECItem signed_hash = {siBuffer, NULL, 0};
+ SSL3Hashes hashes;
+ SSLSignatureAndHashAlg sigAndHash;
+ SECKEYDHParams dhParam;
+
+ ssl3KeyPair *keyPair = NULL;
+ SECKEYPublicKey *pubKey = NULL; /* Ephemeral DH key */
+ SECKEYPrivateKey *privKey = NULL; /* Ephemeral DH key */
+ int certIndex = -1;
+
+ if (kea_def->kea != kea_dhe_dss && kea_def->kea != kea_dhe_rsa) {
+ /* TODO: Support DH_anon. It might be sufficient to drop the signature.
+ See bug 1170510. */
+ PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
+ }
+
+ dhParam.prime.data = ss->dheParams->prime.data;
+ dhParam.prime.len = ss->dheParams->prime.len;
+ dhParam.base.data = ss->dheParams->base.data;
+ dhParam.base.len = ss->dheParams->base.len;
+
+ PRINT_BUF(60, (NULL, "Server DH p", dhParam.prime.data,
+ dhParam.prime.len));
+ PRINT_BUF(60, (NULL, "Server DH g", dhParam.base.data,
+ dhParam.base.len));
+
+ /* Generate ephemeral DH keypair */
+ privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL);
+ if (!privKey || !pubKey) {
+ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
+ rv = SECFailure;
+ goto loser;
+ }
+
+ keyPair = ssl3_NewKeyPair(privKey, pubKey);
+ if (!keyPair) {
+ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
+ goto loser;
+ }
+
+ PRINT_BUF(50, (ss, "DH public value:",
+ pubKey->u.dh.publicValue.data,
+ pubKey->u.dh.publicValue.len));
+
+ if (ssl3_PickSignatureHashAlgorithm(ss, &sigAndHash) != SECSuccess) {
+ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
+ goto loser;
+ }
+
+ rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg,
+ pubKey->u.dh.prime,
+ pubKey->u.dh.base,
+ pubKey->u.dh.publicValue,
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ /* It has been suggested to test kea_def->signKeyType instead, and to use
+ * ssl_auth_* instead. Investigate what to do. See bug 102794. */
+ if (kea_def->kea == kea_dhe_rsa)
+ certIndex = ssl_kea_rsa;
+ else
+ certIndex = ssl_kea_dh;
+
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
+ &signed_hash, isTLS);
+ if (rv != SECSuccess) {
+ goto loser; /* ssl3_SignHashes has set err. */
+ }
+ if (signed_hash.data == NULL) {
+ PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+ length = 2 + pubKey->u.dh.prime.len +
+ 2 + pubKey->u.dh.base.len +
+ 2 + pubKey->u.dh.publicValue.len +
+ 2 + signed_hash.len;
+
+ if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
+ length += 2;
+ }
+
+ rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.prime.data,
+ pubKey->u.dh.prime.len, 2);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.base.data,
+ pubKey->u.dh.base.len, 2);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.publicValue.data,
+ pubKey->u.dh.publicValue.len, 2);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
+ rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
+ signed_hash.len, 2);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+ PORT_Free(signed_hash.data);
+ ss->dheKeyPair = keyPair;
+ return SECSuccess;
+
+loser:
+ if (signed_hash.data)
+ PORT_Free(signed_hash.data);
+ if (privKey)
+ SECKEY_DestroyPrivateKey(privKey);
+ if (pubKey)
+ SECKEY_DestroyPublicKey(pubKey);
+ return SECFailure;
+}
+
/* ssl3_PickSignatureHashAlgorithm selects a hash algorithm to use when signing
* elements of the handshake. (The negotiated cipher suite determines the
* signature algorithm.) Prior to TLS 1.2, the MD5/SHA1 combination is always
@@ -9157,18 +9579,11 @@ ssl3_SendServerHello(sslSocket *ss)
* hash combinations. */
static SECStatus
ssl3_PickSignatureHashAlgorithm(sslSocket *ss,
- SSL3SignatureAndHashAlgorithm* out)
+ SSLSignatureAndHashAlg* out)
{
- TLSSignatureAlgorithm sigAlg;
+ SSLSignType sigAlg;
+ PRUint32 policy;
unsigned int i, j;
- /* hashPreference expresses our preferences for hash algorithms, most
- * preferable first. */
- static const SECOidTag hashPreference[] = {
- SEC_OID_SHA256,
- SEC_OID_SHA384,
- SEC_OID_SHA512,
- SEC_OID_SHA1,
- };
switch (ss->ssl3.hs.kea_def->kea) {
case kea_rsa:
@@ -9181,48 +9596,63 @@ ssl3_PickSignatureHashAlgorithm(sslSocket *ss,
case kea_rsa_fips:
case kea_ecdh_rsa:
case kea_ecdhe_rsa:
- sigAlg = tls_sig_rsa;
- break;
+ sigAlg = ssl_sign_rsa;
+ break;
case kea_dh_dss:
case kea_dh_dss_export:
case kea_dhe_dss:
case kea_dhe_dss_export:
- sigAlg = tls_sig_dsa;
- break;
+ sigAlg = ssl_sign_dsa;
+ break;
case kea_ecdh_ecdsa:
case kea_ecdhe_ecdsa:
- sigAlg = tls_sig_ecdsa;
- break;
+ sigAlg = ssl_sign_ecdsa;
+ break;
default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+ return SECFailure;
}
out->sigAlg = sigAlg;
if (ss->version <= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and
- * prior. */
- out->hashAlg = SEC_OID_UNKNOWN;
- return SECSuccess;
+ /* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and
+ * prior. */
+ out->hashAlg = ssl_hash_none;
+ return SECSuccess;
}
if (ss->ssl3.hs.numClientSigAndHash == 0) {
- /* If the client didn't provide any signature_algorithms extension then
- * we can assume that they support SHA-1:
- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
- out->hashAlg = SEC_OID_SHA1;
- return SECSuccess;
+ /* If the client didn't provide any signature_algorithms extension then
+ * we can assume that they support SHA-1:
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
+ out->hashAlg = ssl_hash_sha1;
+ return SECSuccess;
}
- for (i = 0; i < PR_ARRAY_SIZE(hashPreference); i++) {
- for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) {
- const SSL3SignatureAndHashAlgorithm* sh =
- &ss->ssl3.hs.clientSigAndHash[j];
- if (sh->sigAlg == sigAlg && sh->hashAlg == hashPreference[i]) {
- out->hashAlg = sh->hashAlg;
- return SECSuccess;
- }
+ /* Here we look for the first server preference that the client has
+ * indicated support for in their signature_algorithms extension. */
+ for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) {
+ const SSLSignatureAndHashAlg *serverPref =
+ &ss->ssl3.signatureAlgorithms[i];
+ SECOidTag hashOID;
+ if (serverPref->sigAlg != sigAlg) {
+ continue;
+ }
+ hashOID = ssl3_TLSHashAlgorithmToOID(serverPref->hashAlg);
+ if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess)
+ || !(policy & NSS_USE_ALG_IN_SSL_KX)) {
+ /* we ignore hashes we don't support */
+ continue;
}
+ for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) {
+ const SSLSignatureAndHashAlg *clientPref =
+ &ss->ssl3.hs.clientSigAndHash[j];
+ if (clientPref->hashAlg == serverPref->hashAlg &&
+ clientPref->sigAlg == sigAlg) {
+ out->hashAlg = serverPref->hashAlg;
+ return SECSuccess;
+ }
+ }
}
PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
@@ -9240,7 +9670,7 @@ ssl3_SendServerKeyExchange(sslSocket *ss)
SECItem signed_hash = {siBuffer, NULL, 0};
SSL3Hashes hashes;
SECKEYPublicKey * sdPub; /* public key for step-down */
- SSL3SignatureAndHashAlgorithm sigAndHash;
+ SSLSignatureAndHashAlg sigAndHash;
SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
SSL_GETPID(), ss->fd));
@@ -9287,6 +9717,10 @@ ssl3_SendServerKeyExchange(sslSocket *ss)
2 + sdPub->u.rsa.publicExponent.len +
2 + signed_hash.len;
+ if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
+ length += 2;
+ }
+
rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
if (rv != SECSuccess) {
goto loser; /* err set by AppendHandshake. */
@@ -9320,6 +9754,11 @@ ssl3_SendServerKeyExchange(sslSocket *ss)
PORT_Free(signed_hash.data);
return SECSuccess;
+ case ssl_kea_dh: {
+ rv = ssl3_SendDHServerKeyExchange(ss);
+ return rv;
+ }
+
#ifndef NSS_DISABLE_ECC
case kt_ecdh: {
rv = ssl3_SendECDHServerKeyExchange(ss, &sigAndHash);
@@ -9327,7 +9766,6 @@ ssl3_SendServerKeyExchange(sslSocket *ss)
}
#endif /* NSS_DISABLE_ECC */
- case kt_dh:
case kt_null:
default:
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
@@ -9339,6 +9777,36 @@ loser:
return SECFailure;
}
+static SECStatus
+ssl3_EncodeCertificateRequestSigAlgs(sslSocket *ss, PRUint8 *buf,
+ unsigned maxLen, PRUint32 *len)
+{
+ unsigned int i;
+
+ PORT_Assert(maxLen >= ss->ssl3.signatureAlgorithmCount * 2);
+ if (maxLen < ss->ssl3.signatureAlgorithmCount * 2) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ *len = 0;
+ for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) {
+ const SSLSignatureAndHashAlg *alg = &ss->ssl3.signatureAlgorithms[i];
+ /* Note that we don't support a handshake hash with anything other than
+ * SHA-256, so asking for a signature from clients for something else
+ * would be inviting disaster. */
+ if (alg->hashAlg == ssl_hash_sha256) {
+ buf[(*len)++] = (PRUint8)alg->hashAlg;
+ buf[(*len)++] = (PRUint8)alg->sigAlg;
+ }
+ }
+
+ if (*len == 0) {
+ PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
static SECStatus
ssl3_SendCertificateRequest(sslSocket *ss)
@@ -9347,7 +9815,6 @@ ssl3_SendCertificateRequest(sslSocket *ss)
SECItem * name;
CERTDistNames *ca_list;
const PRUint8 *certTypes;
- const PRUint8 *sigAlgs;
SECItem * names = NULL;
SECStatus rv;
int length;
@@ -9355,7 +9822,8 @@ ssl3_SendCertificateRequest(sslSocket *ss)
int calen = 0;
int nnames = 0;
int certTypesLength;
- int sigAlgsLength;
+ PRUint8 sigAlgs[MAX_SIGNATURE_ALGORITHMS * 2];
+ unsigned int sigAlgsLength = 0;
SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
SSL_GETPID(), ss->fd));
@@ -9382,12 +9850,15 @@ ssl3_SendCertificateRequest(sslSocket *ss)
certTypes = certificate_types;
certTypesLength = sizeof certificate_types;
- sigAlgs = supported_signature_algorithms;
- sigAlgsLength = sizeof supported_signature_algorithms;
length = 1 + certTypesLength + 2 + calen;
if (isTLS12) {
- length += 2 + sigAlgsLength;
+ rv = ssl3_EncodeCertificateRequestSigAlgs(ss, sigAlgs, sizeof(sigAlgs),
+ &sigAlgsLength);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ length += 2 + sigAlgsLength;
}
rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
@@ -9453,7 +9924,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY;
SSL3AlertDescription desc = handshake_failure;
PRBool isTLS, isTLS12;
- SSL3SignatureAndHashAlgorithm sigAndHash;
+ SSLSignatureAndHashAlg sigAndHash;
SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake",
SSL_GETPID(), ss->fd));
@@ -9469,6 +9940,13 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
goto alert_loser;
}
+ if (!hashes) {
+ PORT_Assert(0);
+ desc = internal_error;
+ errCode = SEC_ERROR_LIBRARY_FAILURE;
+ goto alert_loser;
+ }
+
if (isTLS12) {
rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
&sigAndHash);
@@ -9476,7 +9954,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
goto loser; /* malformed or unsupported. */
}
rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
- &sigAndHash, ss->sec.peerCert);
+ ss, &sigAndHash, ss->sec.peerCert);
if (rv != SECSuccess) {
errCode = PORT_GetError();
desc = decrypt_error;
@@ -9485,7 +9963,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
/* We only support CertificateVerify messages that use the handshake
* hash. */
- if (sigAndHash.hashAlg != hashes->hashAlg) {
+ if (sigAndHash.hashAlg != hashes->hashAlg) {
errCode = SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM;
desc = decrypt_error;
goto alert_loser;
@@ -9616,18 +10094,17 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
PRUint32 length,
SECKEYPrivateKey *serverKey)
{
- PK11SymKey * pms;
#ifndef NO_PKCS11_BYPASS
unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
unsigned int outLen = 0;
-#endif
PRBool isTLS = PR_FALSE;
+ SECItem pmsItem = {siBuffer, NULL, 0};
+ unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
+#endif
SECStatus rv;
SECItem enc_pms;
- unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
- SECItem pmsItem = {siBuffer, NULL, 0};
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
@@ -9635,8 +10112,10 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
enc_pms.data = b;
enc_pms.len = length;
+#ifndef NO_PKCS11_BYPASS
pmsItem.data = rsaPmsBuf;
pmsItem.len = sizeof rsaPmsBuf;
+#endif
if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
PRInt32 kLen;
@@ -9648,13 +10127,24 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
if ((unsigned)kLen < enc_pms.len) {
enc_pms.len = kLen;
}
+#ifndef NO_PKCS11_BYPASS
isTLS = PR_TRUE;
+#endif
} else {
+#ifndef NO_PKCS11_BYPASS
isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
+#endif
}
#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
+ /* We have not implemented a tls_ExtendedMasterKeyDeriveBypass
+ * and will not negotiate this extension in bypass mode. This
+ * assert just double-checks that.
+ */
+ PORT_Assert(
+ !ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn));
+
/* TRIPLE BYPASS, get PMS directly from RSA decryption.
* Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer,
* then, check for version rollback attack, then
@@ -9682,8 +10172,8 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
}
}
/* have PMS, build MS without PKCS11 */
- rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS,
- PR_TRUE);
+ rv = ssl3_MasterSecretDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS,
+ PR_TRUE);
if (rv != SECSuccess) {
pwSpec->msItem.data = pwSpec->raw_master_secret;
pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
@@ -9693,49 +10183,163 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
} else
#endif
{
+ PK11SymKey *tmpPms[2] = {NULL, NULL};
+ PK11SlotInfo *slot;
+ int useFauxPms = 0;
+#define currentPms tmpPms[!useFauxPms]
+#define unusedPms tmpPms[useFauxPms]
+#define realPms tmpPms[1]
+#define fauxPms tmpPms[0]
+
#ifndef NO_PKCS11_BYPASS
double_bypass:
#endif
- /*
- * unwrap pms out of the incoming buffer
- * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do
- * the unwrap. Rather, it is the mechanism with which the
- * unwrapped pms will be used.
- */
- pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
- CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
- if (pms != NULL) {
- PRINT_BUF(60, (ss, "decrypted premaster secret:",
- PK11_GetKeyData(pms)->data,
- PK11_GetKeyData(pms)->len));
- } else {
- /* unwrap failed. Generate a bogus PMS and carry on. */
- PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey);
- ssl_GetSpecWriteLock(ss);
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
- ssl_ReleaseSpecWriteLock(ss);
- PK11_FreeSlot(slot);
- }
+ /*
+ * Get as close to algorithm 2 from RFC 5246; Section 7.4.7.1
+ * as we can within the constraints of the PKCS#11 interface.
+ *
+ * 1. Unconditionally generate a bogus PMS (what RFC 5246
+ * calls R).
+ * 2. Attempt the RSA decryption to recover the PMS (what
+ * RFC 5246 calls M).
+ * 3. Set PMS = (M == NULL) ? R : M
+ * 4. Use ssl3_ComputeMasterSecret(PMS) to attempt to derive
+ * the MS from PMS. This includes performing the version
+ * check and length check.
+ * 5. If either the initial RSA decryption failed or
+ * ssl3_ComputeMasterSecret(PMS) failed, then discard
+ * M and set PMS = R. Else, discard R and set PMS = M.
+ *
+ * We do two derivations here because we can't rely on having
+ * a function that only performs the PMS version and length
+ * check. The only redundant cost is that this runs the PRF,
+ * which isn't necessary here.
+ */
- if (pms == NULL) {
- /* last gasp. */
+ /* Generate the bogus PMS (R) */
+ slot = PK11_GetSlotFromPrivateKey(serverKey);
+ if (!slot) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ if (!PK11_DoesMechanism(slot, CKM_SSL3_MASTER_KEY_DERIVE)) {
+ PK11_FreeSlot(slot);
+ slot = PK11_GetBestSlot(CKM_SSL3_MASTER_KEY_DERIVE, NULL);
+ if (!slot) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ }
+
+ ssl_GetSpecWriteLock(ss);
+ fauxPms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
+ ssl_ReleaseSpecWriteLock(ss);
+ PK11_FreeSlot(slot);
+
+ if (fauxPms == NULL) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
return SECFailure;
}
+ /*
+ * unwrap pms out of the incoming buffer
+ * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do
+ * the unwrap. Rather, it is the mechanism with which the
+ * unwrapped pms will be used.
+ */
+ realPms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
+ CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
+ /* Temporarily use the PMS if unwrapping the real PMS fails. */
+ useFauxPms |= (realPms == NULL);
+
+ /* Attempt to derive the MS from the PMS. This is the only way to
+ * check the version field in the RSA PMS. If this fails, we
+ * then use the faux PMS in place of the PMS. Note that this
+ * operation should never fail if we are using the faux PMS
+ * since it is correctly formatted. */
+ rv = ssl3_ComputeMasterSecret(ss, currentPms, NULL);
+
+ /* If we succeeded, then select the true PMS and discard the
+ * FPMS. Else, select the FPMS and select the true PMS */
+ useFauxPms |= (rv != SECSuccess);
+
+ if (unusedPms) {
+ PK11_FreeSymKey(unusedPms);
+ }
+
/* This step will derive the MS from the PMS, among other things. */
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
+ rv = ssl3_InitPendingCipherSpec(ss, currentPms);
+ PK11_FreeSymKey(currentPms);
}
if (rv != SECSuccess) {
SEND_ALERT
return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
}
+
+#undef currentPms
+#undef unusedPms
+#undef realPms
+#undef fauxPms
+
return SECSuccess;
}
+static SECStatus
+ssl3_HandleDHClientKeyExchange(sslSocket *ss,
+ SSL3Opaque *b,
+ PRUint32 length,
+ SECKEYPublicKey *srvrPubKey,
+ SECKEYPrivateKey *serverKey)
+{
+ PK11SymKey *pms;
+ SECStatus rv;
+ SECKEYPublicKey clntPubKey;
+ CK_MECHANISM_TYPE target;
+ PRBool isTLS;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( srvrPubKey );
+
+ clntPubKey.keyType = dhKey;
+ clntPubKey.u.dh.prime.len = srvrPubKey->u.dh.prime.len;
+ clntPubKey.u.dh.prime.data = srvrPubKey->u.dh.prime.data;
+ clntPubKey.u.dh.base.len = srvrPubKey->u.dh.base.len;
+ clntPubKey.u.dh.base.data = srvrPubKey->u.dh.base.data;
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.dh.publicValue,
+ 2, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
+
+ if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
+ else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
+
+ /* Determine the PMS */
+ pms = PK11_PubDerive(serverKey, &clntPubKey, PR_FALSE, NULL, NULL,
+ CKM_DH_PKCS_DERIVE, target, CKA_DERIVE, 0, NULL);
+ if (pms == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms); pms = NULL;
+
+loser:
+ if (ss->dheKeyPair) {
+ ssl3_FreeKeyPair(ss->dheKeyPair);
+ ss->dheKeyPair = NULL;
+ }
+ return rv;
+}
+
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 ClientKeyExchange message from the remote client
@@ -9748,9 +10352,7 @@ ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECStatus rv;
const ssl3KEADef *kea_def;
ssl3KeyPair *serverKeyPair = NULL;
-#ifndef NSS_DISABLE_ECC
SECKEYPublicKey *serverPubKey = NULL;
-#endif /* NSS_DISABLE_ECC */
SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
SSL_GETPID(), ss->fd));
@@ -9780,6 +10382,16 @@ ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB;
} else
skip:
+ if (kea_def->kea == kea_dhe_dss ||
+ kea_def->kea == kea_dhe_rsa) {
+ if (ss->dheKeyPair) {
+ serverKeyPair = ss->dheKeyPair;
+ if (serverKeyPair->pubKey) {
+ ss->sec.keaKeyBits =
+ SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey);
+ }
+ }
+ } else
#ifndef NSS_DISABLE_ECC
/* XXX Using SSLKEAType to index server certifiates
* does not work for (EC)DHE ciphers. Until we have
@@ -9825,6 +10437,21 @@ skip:
}
break;
+ case ssl_kea_dh:
+ if (ss->dheKeyPair && ss->dheKeyPair->pubKey) {
+ serverPubKey = ss->dheKeyPair->pubKey;
+ }
+ if (!serverPubKey) {
+ PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ return SECFailure;
+ }
+ rv = ssl3_HandleDHClientKeyExchange(ss, b, length,
+ serverPubKey, serverKey);
+ if (rv != SECSuccess) {
+ SSL3_SendAlert(ss, alert_fatal, handshake_failure);
+ return SECFailure; /* error code set */
+ }
+ break;
#ifndef NSS_DISABLE_ECC
case kt_ecdh:
@@ -10454,6 +11081,8 @@ ssl3_AuthCertificate(sslSocket *ss)
ss->ssl3.hs.authCertificatePending = PR_FALSE;
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
/*
* Ask caller-supplied callback function to validate cert chain.
*/
@@ -10498,40 +11127,60 @@ ssl3_AuthCertificate(sslSocket *ss)
ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType;
if (pubKey) {
+ KeyType pubKeyType;
+ PRInt32 minKey;
ss->sec.keaKeyBits = ss->sec.authKeyBits =
SECKEY_PublicKeyStrengthInBits(pubKey);
-#ifndef NSS_DISABLE_ECC
- if (ss->sec.keaType == kt_ecdh) {
- /* Get authKeyBits from signing key.
- * XXX The code below uses a quick approximation of
- * key size based on cert->signatureWrap.signature.data
- * (which contains the DER encoded signature). The field
- * cert->signatureWrap.signature.len contains the
- * length of the encoded signature in bits.
- */
- if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) {
- ss->sec.authKeyBits =
- cert->signatureWrap.signature.data[3]*8;
- if (cert->signatureWrap.signature.data[4] == 0x00)
- ss->sec.authKeyBits -= 8;
- /*
- * XXX: if cert is not signed by ecdsa we should
- * destroy pubKey and goto bad_cert
- */
- } else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) {
- ss->sec.authKeyBits = cert->signatureWrap.signature.len;
- /*
- * XXX: if cert is not signed by rsa we should
- * destroy pubKey and goto bad_cert
- */
+ pubKeyType = SECKEY_GetPublicKeyType(pubKey);
+ minKey = ss->sec.authKeyBits;
+ switch (pubKeyType) {
+ case rsaKey:
+ case rsaPssKey:
+ case rsaOaepKey:
+ rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minKey);
+ if (rv != SECSuccess) {
+ minKey = SSL_RSA_MIN_MODULUS_BITS;
}
+ break;
+ case dsaKey:
+ rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minKey);
+ if (rv != SECSuccess) {
+ minKey = SSL_DSA_MIN_P_BITS;
+ }
+ break;
+ case dhKey:
+ rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minKey);
+ if (rv != SECSuccess) {
+ minKey = SSL_DH_MIN_P_BITS;
+ }
+ break;
+ default:
+ break;
}
-#endif /* NSS_DISABLE_ECC */
+
+ /* Too small: not good enough. Send a fatal alert. */
+ /* We aren't checking EC here on the understanding that we only
+ * support curves we like, a decision that might need revisiting. */
+ if ( ss->sec.authKeyBits < minKey) {
+ PORT_SetError(SSL_ERROR_WEAK_SERVER_CERT_KEY);
+ (void)SSL3_SendAlert(ss, alert_fatal,
+ ss->version >= SSL_LIBRARY_VERSION_TLS_1_0
+ ? insufficient_security
+ : illegal_parameter);
+ SECKEY_DestroyPublicKey(pubKey);
+ return SECFailure;
+ }
SECKEY_DestroyPublicKey(pubKey);
pubKey = NULL;
}
- if (ss->ssl3.hs.kea_def->ephemeral) {
+ /* Ephemeral suites require ServerKeyExchange. Export cipher suites
+ * with RSA key exchange also require ServerKeyExchange if the
+ * authentication key exceeds the key size limit. */
+ if (ss->ssl3.hs.kea_def->ephemeral ||
+ (ss->ssl3.hs.kea_def->is_limited &&
+ ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa &&
+ ss->sec.authKeyBits > ss->ssl3.hs.kea_def->key_size_limit)) {
ss->ssl3.hs.ws = wait_server_key; /* require server_key_exchange */
} else {
ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */
@@ -10643,16 +11292,42 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
const SSL3Hashes * hashes,
TLSFinished * tlsFinished)
{
- const char * label;
- unsigned int len;
- SECStatus rv;
+ SECStatus rv;
+ CK_TLS_MAC_PARAMS tls_mac_params;
+ SECItem param = {siBuffer, NULL, 0};
+ PK11Context *prf_context;
+ unsigned int retLen;
+
+ if (!spec->master_secret || spec->bypassCiphers) {
+ const char *label = isServer ? "server finished" : "client finished";
+ unsigned int len = 15;
- label = isServer ? "server finished" : "client finished";
- len = 15;
+ return ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw,
+ hashes->len, tlsFinished->verify_data,
+ sizeof tlsFinished->verify_data);
+ }
- rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw,
- hashes->len, tlsFinished->verify_data,
- sizeof tlsFinished->verify_data);
+ if (spec->version < SSL_LIBRARY_VERSION_TLS_1_2) {
+ tls_mac_params.prfMechanism = CKM_TLS_PRF;
+ } else {
+ tls_mac_params.prfMechanism = CKM_SHA256;
+ }
+ tls_mac_params.ulMacLength = 12;
+ tls_mac_params.ulServerOrClient = isServer ? 1 : 2;
+ param.data = (unsigned char *)&tls_mac_params;
+ param.len = sizeof(tls_mac_params);
+ prf_context = PK11_CreateContextBySymKey(CKM_TLS_MAC, CKA_SIGN,
+ spec->master_secret, &param);
+ if (!prf_context)
+ return SECFailure;
+
+ rv = PK11_DigestBegin(prf_context);
+ rv |= PK11_DigestOp(prf_context, hashes->u.raw, hashes->len);
+ rv |= PK11_DigestFinal(prf_context, tlsFinished->verify_data, &retLen,
+ sizeof tlsFinished->verify_data);
+ PORT_Assert(rv != SECSuccess || retLen == sizeof tlsFinished->verify_data);
+
+ PK11_DestroyContext(prf_context, PR_TRUE);
return rv;
}
@@ -11170,6 +11845,13 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
return SECFailure;
}
+ if (!hashes) {
+ PORT_Assert(0);
+ SSL3_SendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0);
if (isTLS) {
TLSFinished tlsFinished;
@@ -11225,7 +11907,8 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
* ServerHello message.)
*/
if (isServer && !ss->ssl3.hs.isResuming &&
- ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) {
+ ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) &&
+ ssl3_KEAAllowsSessionTicket(ss->ssl3.hs.suite_def->key_exchange_alg)) {
/* RFC 5077 Section 3.3: "In the case of a full handshake, the
* server MUST verify the client's Finished message before sending
* the ticket." Presumably, this also means that the client's
@@ -11278,7 +11961,8 @@ xmit_loser:
return rv;
}
- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
+ if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
+ ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) {
effectiveExchKeyType = kt_rsa;
} else {
effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
@@ -11398,6 +12082,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECStatus rv = SECSuccess;
SSL3HandshakeType type = ss->ssl3.hs.msg_type;
SSL3Hashes hashes; /* computed hashes are put here. */
+ SSL3Hashes *hashesPtr = NULL; /* Set when hashes are computed */
PRUint8 hdr[4];
PRUint8 dtlsData[8];
@@ -11408,7 +12093,8 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* current message.
*/
ssl_GetSpecReadLock(ss); /************************************/
- if((type == finished) || (type == certificate_verify)) {
+ if(((type == finished) && (ss->ssl3.hs.ws == wait_finished)) ||
+ ((type == certificate_verify) && (ss->ssl3.hs.ws == wait_cert_verify))) {
SSL3Sender sender = (SSL3Sender)0;
ssl3CipherSpec *rSpec = ss->ssl3.prSpec;
@@ -11417,6 +12103,9 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
rSpec = ss->ssl3.crSpec;
}
rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender);
+ if (rv == SECSuccess) {
+ hashesPtr = &hashes;
+ }
}
ssl_ReleaseSpecReadLock(ss); /************************************/
if (rv != SECSuccess) {
@@ -11567,7 +12256,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
return SECFailure;
}
- rv = ssl3_HandleCertificateVerify(ss, b, length, &hashes);
+ rv = ssl3_HandleCertificateVerify(ss, b, length, hashesPtr);
break;
case client_key_exchange:
if (!ss->sec.isServer) {
@@ -11586,7 +12275,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
rv = ssl3_HandleNewSessionTicket(ss, b, length);
break;
case finished:
- rv = ssl3_HandleFinished(ss, b, length, &hashes);
+ rv = ssl3_HandleFinished(ss, b, length, hashesPtr);
break;
default:
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
@@ -11641,7 +12330,7 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
if (ss->ssl3.hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {
(void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
return SECFailure;
}
#undef MAX_HANDSHAKE_MSG_LEN
@@ -11942,7 +12631,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
SSL3Opaque *givenHash;
sslBuffer *plaintext;
sslBuffer temp_buf;
- PRUint64 dtls_seq_num;
+ PRUint64 dtls_seq_num = 0;
unsigned int ivLen = 0;
unsigned int originalLen = 0;
unsigned int good;
@@ -12423,6 +13112,7 @@ ssl3_InitState(sslSocket *ss)
ss->ssl3.hs.sendingSCSV = PR_FALSE;
ssl3_InitCipherSpec(ss, ss->ssl3.crSpec);
ssl3_InitCipherSpec(ss, ss->ssl3.prSpec);
+ ss->ssl3.hs.preliminaryInfo = 0;
ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
#ifndef NSS_DISABLE_ECC
@@ -12496,8 +13186,6 @@ ssl3_FreeKeyPair(ssl3KeyPair * keyPair)
}
}
-
-
/*
* Creates the public and private RSA keys for SSL Step down.
* Called from SSL_ConfigSecureServer in sslsecur.c
@@ -12529,7 +13217,6 @@ ssl3_CreateRSAStepDownKeys(sslSocket *ss)
return rv;
}
-
/* record the export policy for this cipher suite */
SECStatus
ssl3_SetPolicy(ssl3CipherSuite which, int policy)
@@ -12631,6 +13318,79 @@ ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
}
SECStatus
+SSL_SignaturePrefSet(PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms,
+ unsigned int count)
+{
+ sslSocket *ss;
+ unsigned int i;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignaturePrefSet",
+ SSL_GETPID(), fd));
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (!count || count > MAX_SIGNATURE_ALGORITHMS) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ ss->ssl3.signatureAlgorithmCount = 0;
+ for (i = 0; i < count; ++i) {
+ if (!ssl3_IsSupportedSignatureAlgorithm(&algorithms[i])) {
+ SSL_DBG(("%d: SSL[%d]: invalid signature algorithm set %d/%d",
+ SSL_GETPID(), fd, algorithms[i].sigAlg,
+ algorithms[i].hashAlg));
+ continue;
+ }
+
+ ss->ssl3.signatureAlgorithms[ss->ssl3.signatureAlgorithmCount++] =
+ algorithms[i];
+ }
+
+ if (ss->ssl3.signatureAlgorithmCount == 0) {
+ PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+SSL_SignaturePrefGet(PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms,
+ unsigned int *count, unsigned int maxCount)
+{
+ sslSocket *ss;
+ unsigned int requiredSpace;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignaturePrefGet",
+ SSL_GETPID(), fd));
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (!algorithms || !count ||
+ maxCount < ss->ssl3.signatureAlgorithmCount) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ requiredSpace =
+ ss->ssl3.signatureAlgorithmCount * sizeof(SSLSignatureAndHashAlg);
+ PORT_Memcpy(algorithms, ss->ssl3.signatureAlgorithms, requiredSpace);
+ *count = ss->ssl3.signatureAlgorithmCount;
+ return SECSuccess;
+}
+
+unsigned int
+SSL_SignatureMaxCount() {
+ return MAX_SIGNATURE_ALGORITHMS;
+}
+
+SECStatus
ssl3_CipherOrderSet(sslSocket *ss, const ssl3CipherSuite *ciphers, unsigned int len)
{
/* |i| iterates over |ciphers| while |done| and |j| iterate over
@@ -12675,6 +13435,9 @@ void
ssl3_InitSocketPolicy(sslSocket *ss)
{
PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
+ PORT_Memcpy(ss->ssl3.signatureAlgorithms, defaultSignatureAlgorithms,
+ sizeof(defaultSignatureAlgorithms));
+ ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms);
}
SECStatus
@@ -12764,7 +13527,7 @@ ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size)
/* ssl3_config_match_init was called by the caller of this function. */
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (config_match(suite, SSL_ALLOWED, PR_TRUE, &ss->vrange)) {
+ if (config_match(suite, SSL_ALLOWED, PR_TRUE, &ss->vrange, ss)) {
if (cs != NULL) {
*cs++ = 0x00;
*cs++ = (suite->cipher_suite >> 8) & 0xFF;
@@ -12898,6 +13661,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
}
}
+ if (ss->ssl3.dheGroups) {
+ PORT_Free(ss->ssl3.dheGroups);
+ }
+
ss->ssl3.initialized = PR_FALSE;
SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
diff --git a/chromium/net/third_party/nss/ssl/ssl3ecc.c b/chromium/net/third_party/nss/ssl/ssl3ecc.c
index 31e07744bb9..ab5ab14d41d 100644
--- a/chromium/net/third_party/nss/ssl/ssl3ecc.c
+++ b/chromium/net/third_party/nss/ssl/ssl3ecc.c
@@ -214,7 +214,7 @@ params2ecName(SECKEYECParams * params)
/* Caller must set hiLevel error code. */
static SECStatus
-ssl3_ComputeECDHKeyHash(SECOidTag hashAlg,
+ssl3_ComputeECDHKeyHash(SSLHashType hashAlg,
SECItem ec_params, SECItem server_ecpoint,
SSL3Random *client_rand, SSL3Random *server_rand,
SSL3Hashes *hashes, PRBool bypassPKCS11)
@@ -303,7 +303,7 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
pubKey->u.ec.publicValue.len));
if (isTLS12) {
- target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
+ target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
} else if (isTLS) {
target = CKM_TLS_MASTER_KEY_DERIVE_DH;
} else {
@@ -325,14 +325,6 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
SECKEY_DestroyPrivateKey(privKey);
privKey = NULL;
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
pubKey->u.ec.publicValue.len + 1);
if (rv != SECSuccess) {
@@ -349,6 +341,14 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
goto loser; /* err set by ssl3_AppendHandshake* */
}
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms); pms = NULL;
+
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
rv = SECSuccess;
loser:
@@ -394,7 +394,7 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
if (isTLS12) {
- target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
+ target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
} else if (isTLS) {
target = CKM_TLS_MASTER_KEY_DERIVE_DH;
} else {
@@ -615,9 +615,9 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECItem ec_params = {siBuffer, NULL, 0};
SECItem ec_point = {siBuffer, NULL, 0};
unsigned char paramBuf[3]; /* only for curve_type == named_curve */
- SSL3SignatureAndHashAlgorithm sigAndHash;
+ SSLSignatureAndHashAlg sigAndHash;
- sigAndHash.hashAlg = SEC_OID_UNKNOWN;
+ sigAndHash.hashAlg = ssl_hash_none;
isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
@@ -659,7 +659,7 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto loser; /* malformed or unsupported. */
}
rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
- &sigAndHash, ss->sec.peerCert);
+ ss, &sigAndHash, ss->sec.peerCert);
if (rv != SECSuccess) {
goto loser;
}
@@ -710,7 +710,7 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto no_memory;
}
- ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
+ peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
if (peerKey == NULL) {
goto no_memory;
}
@@ -731,7 +731,6 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* copy publicValue in peerKey */
if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point))
{
- PORT_FreeArena(arena, PR_FALSE);
goto no_memory;
}
peerKey->pkcs11Slot = NULL;
@@ -745,10 +744,16 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
PORT_SetError( errCode );
return SECFailure;
no_memory: /* no-memory error has already been set. */
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
return SECFailure;
}
@@ -756,7 +761,7 @@ no_memory: /* no-memory error has already been set. */
SECStatus
ssl3_SendECDHServerKeyExchange(
sslSocket *ss,
- const SSL3SignatureAndHashAlgorithm *sigAndHash)
+ const SSLSignatureAndHashAlg *sigAndHash)
{
const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
SECStatus rv = SECFailure;
@@ -977,9 +982,7 @@ ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
if (!suite)
suite = ecSuites;
for (; *suite; ++suite) {
- SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
-
- PORT_Assert(rv == SECSuccess); /* else is coding error */
+ PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE));
}
return SECSuccess;
}
@@ -1142,7 +1145,10 @@ ssl3_SendSupportedCurvesXtn(
ecList = tlsECList;
}
- if (append && maxBytes >= ecListSize) {
+ if (maxBytes < (PRUint32)ecListSize) {
+ return 0;
+ }
+ if (append) {
SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize);
if (rv != SECSuccess)
return -1;
diff --git a/chromium/net/third_party/nss/ssl/ssl3ext.c b/chromium/net/third_party/nss/ssl/ssl3ext.c
index 9214a2e6b3b..eb3fb70f280 100644
--- a/chromium/net/third_party/nss/ssl/ssl3ext.c
+++ b/chromium/net/third_party/nss/ssl/ssl3ext.c
@@ -101,6 +101,12 @@ static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes);
static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data);
+static PRInt32 ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append,
+ PRUint32 maxBytes);
+static SECStatus ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss,
+ PRUint16 ex_type,
+ SECItem *data);
+
/*
* Write bytes. Using this function means the SECItem structure
@@ -266,6 +272,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
{ ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
{ ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
{ -1, NULL }
};
@@ -281,6 +288,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
{ ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
{ ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
{ ssl_signed_certificate_timestamp_xtn,
&ssl3_ClientHandleSignedCertTimestampXtn },
{ -1, NULL }
@@ -319,6 +327,7 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
* extension. */
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
{ ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn},
/* any extra entries will appear as { 0, NULL } */
};
@@ -331,7 +340,7 @@ ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
static PRBool
arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
{
- int i;
+ unsigned int i;
for (i = 0; i < len; i++) {
if (ex_type == array[i])
return PR_TRUE;
@@ -433,12 +442,12 @@ ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
/* length of server_name_list */
listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- if (listLenBytes < 0 || listLenBytes != data->len) {
- (void)ssl3_DecodeError(ss);
+ if (listLenBytes < 0) {
return SECFailure;
}
- if (listLenBytes == 0) {
- return SECSuccess; /* ignore an empty extension */
+ if (listLenBytes == 0 || listLenBytes != data->len) {
+ (void)ssl3_DecodeError(ss);
+ return SECFailure;
}
ldata = *data;
/* Calculate the size of the array.*/
@@ -463,15 +472,12 @@ ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
listCount += 1;
}
- if (!listCount) {
- return SECFailure; /* nothing we can act on */
- }
names = PORT_ZNewArray(SECItem, listCount);
if (!names) {
return SECFailure;
}
for (i = 0;i < listCount;i++) {
- int j;
+ unsigned int j;
PRInt32 type;
SECStatus rv;
PRBool nametypePresent = PR_FALSE;
@@ -559,7 +565,11 @@ ssl3_SendSessionTicketXtn(
}
}
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
SECStatus rv;
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
@@ -582,9 +592,6 @@ ssl3_SendSessionTicketXtn(
xtnData->advertised[xtnData->numAdvertised++] =
ssl_session_ticket_xtn;
}
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
@@ -645,12 +652,17 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
rv = ssl3_ValidateNextProtoNego(data->data, data->len);
if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return rv;
}
PORT_Assert(ss->nextProtoCallback);
+ /* For ALPN, the cipher suite isn't selected yet. Note that extensions
+ * sometimes affect what cipher suite is selected, e.g., for ECC. */
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo &
+ ssl_preinfo_all & ~ssl_preinfo_cipher_suite) ==
+ (ssl_preinfo_all & ~ssl_preinfo_cipher_suite));
rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
result.data, &result.len, sizeof(resultBuffer));
if (rv != SECSuccess) {
@@ -673,8 +685,8 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
/* The callback might say OK, but then it picks a default value - one
* that was not listed. That's OK for NPN, but not ALPN. */
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
(void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
return SECFailure;
}
@@ -693,8 +705,8 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
* despite it being permitted by the spec. */
if (ss->firstHsDone || data->len == 0) {
/* Clients MUST send a non-empty ALPN extension. */
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
@@ -721,8 +733,8 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
rv = ssl3_RegisterServerHelloExtensionSender(
ss, ex_type, ssl3_ServerSendAppProtoXtn);
if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return rv;
}
}
@@ -742,8 +754,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
* we've negotiated NPN then we're required to send the NPN handshake
* message. Thus, these two extensions cannot both be negotiated on the
* same connection. */
- PORT_SetError(SSL_ERROR_BAD_SERVER);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_BAD_SERVER);
return SECFailure;
}
@@ -753,8 +765,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
* we sent the ClientHello and now. */
if (!ss->nextProtoCallback) {
PORT_Assert(0);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
return SECFailure;
}
@@ -778,16 +790,16 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
* uint8 len; // where len >= 1
* uint8 protocol_name[len]; */
if (data->len < 4 || data->len > 2 + 1 + 255) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
/* The list has to be the entire extension. */
if (list_len != data->len) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
@@ -795,8 +807,8 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
&data->data, &data->len);
/* The list must have exactly one value. */
if (rv != SECSuccess || data->len != 0) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
@@ -819,7 +831,10 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
extension_length = 4;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
if (rv != SECSuccess)
@@ -829,8 +844,6 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_next_proto_nego_xtn;
- } else if (maxBytes < extension_length) {
- return 0;
}
return extension_length;
@@ -854,7 +867,10 @@ ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
2 /* protocol name list length */ +
ss->opt.nextProtoNego.len;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
/* NPN requires that the client's fallback protocol is first in the
* list. However, ALPN sends protocols in preference order. So we
* allocate a buffer and move the first protocol to the end of the
@@ -894,8 +910,6 @@ ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
}
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_app_layer_protocol_xtn;
- } else if (maxBytes < extension_length) {
- return 0;
}
return extension_length;
@@ -923,7 +937,10 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
2 /* protocol name list */ + 1 /* name length */ +
ss->ssl3.nextProto.len;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
if (rv != SECSuccess) {
@@ -942,8 +959,6 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
if (rv != SECSuccess) {
return -1;
}
- } else if (maxBytes < extension_length) {
- return 0;
}
return extension_length;
@@ -1045,7 +1060,10 @@ ssl3_ServerSendStatusRequestXtn(
return 0;
extension_length = 2 + 2;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
if (rv != SECSuccess)
@@ -1078,7 +1096,11 @@ ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
*/
extension_length = 9;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
SECStatus rv;
TLSExtensionData *xtnData;
@@ -1106,9 +1128,6 @@ ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
xtnData = &ss->xtnData;
xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
}
@@ -1120,7 +1139,7 @@ ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
SECStatus
ssl3_SendNewSessionTicket(sslSocket *ss)
{
- int i;
+ PRUint32 i;
SECStatus rv;
NewSessionTicket ticket;
SECItem plaintext;
@@ -1152,7 +1171,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
PK11Context *aes_ctx_pkcs11;
CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
- PK11Context *hmac_ctx_pkcs11;
+ PK11Context *hmac_ctx_pkcs11 = NULL;
unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
unsigned int computed_mac_length;
unsigned char iv[AES_BLOCK_SIZE];
@@ -1200,7 +1219,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
sslSessionID sid;
PORT_Memset(&sid, 0, sizeof(sslSessionID));
- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
+ if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
+ ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) {
effectiveExchKeyType = kt_rsa;
} else {
effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
@@ -1243,6 +1263,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
+ cert_length /* cert */
+ 1 /* server name type */
+ srvNameLen /* name len + length field */
+ + 1 /* extendedMasterSecretUsed */
+ sizeof(ticket.ticket_lifetime_hint);
padding_length = AES_BLOCK_SIZE -
(ciphertext_length % AES_BLOCK_SIZE);
@@ -1341,6 +1362,11 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
if (rv != SECSuccess) goto loser;
}
+ /* extendedMasterSecretUsed */
+ rv = ssl3_AppendNumberToItem(
+ &plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 1);
+ if (rv != SECSuccess) goto loser;
+
PORT_Assert(plaintext.len == padding_length);
for (i = 0; i < padding_length; i++)
plaintext.data[i] = (unsigned char)padding_length;
@@ -1410,14 +1436,18 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
goto loser;
rv = PK11_DigestBegin(hmac_ctx_pkcs11);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
SESS_TICKET_KEY_NAME_LEN);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
+ if (rv != SECSuccess) goto loser;
rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
&computed_mac_length, sizeof(computed_mac));
- PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
if (rv != SECSuccess) goto loser;
}
@@ -1446,6 +1476,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
if (rv != SECSuccess) goto loser;
loser:
+ if (hmac_ctx_pkcs11)
+ PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
if (plaintext_item.data)
SECITEM_FreeItem(&plaintext_item, PR_FALSE);
if (ciphertext.data)
@@ -1495,7 +1527,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
if (data->len == 0) {
ss->xtnData.emptySessionTicket = PR_TRUE;
} else {
- int i;
+ PRUint32 i;
SECItem extension_data;
EncryptedSessionTicket enc_session_ticket;
unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
@@ -1698,9 +1730,10 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
goto loser;
}
- /* Read ticket_version (which is ignored for now.) */
+ /* Read ticket_version and reject if the version is wrong */
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
+ if (temp != TLS_EX_SESS_TICKET_VERSION) goto no_ticket;
+
parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
/* Read SSLVersion. */
@@ -1801,6 +1834,13 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
parsed_session_ticket->srvName.type = nameType;
}
+ /* Read extendedMasterSecretUsed */
+ temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ PORT_Assert(temp == PR_TRUE || temp == PR_FALSE);
+ parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp;
+
/* Done parsing. Check that all bytes have been consumed. */
if (buffer_len != padding_length)
goto no_ticket;
@@ -1847,6 +1887,8 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
parsed_session_ticket->ms_is_wrapped;
sid->u.ssl3.masterValid = PR_TRUE;
sid->u.ssl3.keys.resumable = PR_TRUE;
+ sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->
+ extendedMasterSecretUsed;
/* Copy over client cert from session ticket if there is one. */
if (parsed_session_ticket->peer_cert.data != NULL) {
@@ -2085,7 +2127,10 @@ ssl3_SendRenegotiationInfoXtn(
(ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
: ss->ssl3.hs.finishedBytes);
needed = 5 + len;
- if (append && maxBytes >= needed) {
+ if (maxBytes < (PRUint32)needed) {
+ return 0;
+ }
+ if (append) {
SECStatus rv;
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
@@ -2138,8 +2183,8 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
}
if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
data->data + 1, len)) {
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
+ PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
return SECFailure;
}
/* remember that we got this extension and it was correct. */
@@ -2263,8 +2308,8 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
if (!found) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
return SECFailure;
}
@@ -2277,8 +2322,8 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
/* We didn't offer an MKI, so this must be 0 length */
if (litem.len != 0) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
return SECFailure;
}
@@ -2374,7 +2419,7 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
SECStatus rv;
SECItem algorithms;
const unsigned char *b;
- unsigned int numAlgorithms, i, j;
+ unsigned int numAlgorithms, i;
/* Ignore this extension if we aren't doing TLS 1.2 or greater. */
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
@@ -2388,8 +2433,8 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
/* Trailing data, empty value, or odd-length value is invalid. */
if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure;
}
@@ -2401,30 +2446,24 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
}
ss->ssl3.hs.clientSigAndHash =
- PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
+ PORT_NewArray(SSLSignatureAndHashAlg, numAlgorithms);
if (!ss->ssl3.hs.clientSigAndHash) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure;
}
ss->ssl3.hs.numClientSigAndHash = 0;
b = algorithms.data;
- for (i = j = 0; i < numAlgorithms; i++) {
- unsigned char tls_hash = *(b++);
- unsigned char tls_sig = *(b++);
- SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash);
-
- if (hash == SEC_OID_UNKNOWN) {
- /* We ignore formats that we don't understand. */
- continue;
+ ss->ssl3.hs.numClientSigAndHash = 0;
+ for (i = 0; i < numAlgorithms; i++) {
+ SSLSignatureAndHashAlg *sigAndHash =
+ &ss->ssl3.hs.clientSigAndHash[ss->ssl3.hs.numClientSigAndHash];
+ sigAndHash->hashAlg = (SSLHashType)*(b++);
+ sigAndHash->sigAlg = (SSLSignType)*(b++);
+ if (ssl3_IsSupportedSignatureAlgorithm(sigAndHash)) {
+ ++ss->ssl3.hs.numClientSigAndHash;
}
- /* tls_sig support will be checked later in
- * ssl3_PickSignatureHashAlgorithm. */
- ss->ssl3.hs.clientSigAndHash[j].hashAlg = hash;
- ss->ssl3.hs.clientSigAndHash[j].sigAlg = tls_sig;
- ++j;
- ++ss->ssl3.hs.numClientSigAndHash;
}
if (!ss->ssl3.hs.numClientSigAndHash) {
@@ -2442,60 +2481,60 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
* 1.2 ClientHellos. */
static PRInt32
-ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
+ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
{
- static const unsigned char signatureAlgorithms[] = {
- /* This block is the contents of our signature_algorithms extension, in
- * wire format. See
- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
- tls_hash_sha256, tls_sig_rsa,
- tls_hash_sha384, tls_sig_rsa,
- tls_hash_sha512, tls_sig_rsa,
- tls_hash_sha1, tls_sig_rsa,
-#ifndef NSS_DISABLE_ECC
- tls_hash_sha256, tls_sig_ecdsa,
- tls_hash_sha384, tls_sig_ecdsa,
- tls_hash_sha512, tls_sig_ecdsa,
- tls_hash_sha1, tls_sig_ecdsa,
-#endif
- tls_hash_sha256, tls_sig_dsa,
- tls_hash_sha1, tls_sig_dsa,
- };
PRInt32 extension_length;
+ unsigned int i;
+ PRInt32 pos=0;
+ PRUint32 policy;
+ PRUint8 buf[MAX_SIGNATURE_ALGORITHMS * 2];
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
return 0;
}
+ for (i=0; i < ss->ssl3.signatureAlgorithmCount; i++) {
+ SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(
+ ss->ssl3.signatureAlgorithms[i].hashAlg);
+ if ((NSS_GetAlgorithmPolicy(hashOID, & policy) != SECSuccess) ||
+ (policy & NSS_USE_ALG_IN_SSL_KX)) {
+ buf[pos++] = ss->ssl3.signatureAlgorithms[i].hashAlg;
+ buf[pos++] = ss->ssl3.signatureAlgorithms[i].sigAlg;
+ }
+ }
+
extension_length =
2 /* extension type */ +
2 /* extension length */ +
2 /* supported_signature_algorithms length */ +
- sizeof(signatureAlgorithms);
+ pos;
+
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
- if (append && maxBytes >= extension_length) {
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
- if (rv != SECSuccess)
- goto loser;
+ if (rv != SECSuccess) {
+ return -1;
+ }
rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess)
- goto loser;
- rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms,
- sizeof(signatureAlgorithms), 2);
- if (rv != SECSuccess)
- goto loser;
+ if (rv != SECSuccess) {
+ return -1;
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, buf, extension_length - 6, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_signature_algorithms_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
-
-loser:
- return -1;
}
unsigned int
@@ -2565,7 +2604,11 @@ ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
}
extension_length = 6; /* Type + length + number */
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_draft_version_xtn, 2);
if (rv != SECSuccess)
@@ -2578,9 +2621,6 @@ ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_tls13_draft_version_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
@@ -2633,6 +2673,51 @@ ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
return SECSuccess;
}
+static PRInt32
+ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+
+ if (!ss->opt.enableExtendedMS) {
+ return 0;
+ }
+
+#ifndef NO_PKCS11_BYPASS
+ /* Extended MS can only be used w/o bypass mode */
+ if (ss->opt.bypassPKCS11) {
+ PORT_Assert(0);
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return -1;
+ }
+#endif
+
+ /* Always send the extension in this function, since the
+ * client always sends it and this function is only called on
+ * the server if we negotiated the extension. */
+ extension_length = 4; /* Type + length (0) */
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
+ ssl_extended_master_secret_xtn;
+ }
+
+ return extension_length;
+loser:
+ return -1;
+}
+
/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
* extension for TLS ClientHellos. */
static PRInt32
@@ -2646,7 +2731,12 @@ ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
if (!ss->opt.enableSignedCertTimestamps)
return 0;
- if (append && maxBytes >= extension_length) {
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
SECStatus rv;
/* extension_type */
rv = ssl3_AppendHandshakeNumber(ss,
@@ -2660,9 +2750,6 @@ ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_signed_certificate_timestamp_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
}
return extension_length;
@@ -2671,6 +2758,46 @@ loser:
}
static SECStatus
+ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
+ SECItem *data)
+{
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) {
+ return SECSuccess;
+ }
+
+ if (!ss->opt.enableExtendedMS) {
+ return SECSuccess;
+ }
+
+#ifndef NO_PKCS11_BYPASS
+ /* Extended MS can only be used w/o bypass mode */
+ if (ss->opt.bypassPKCS11) {
+ PORT_Assert(0);
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return SECFailure;
+ }
+#endif
+
+ if (data->len != 0) {
+ SSL_TRC(30, ("%d: SSL3[%d]: Bogus extended master secret extension",
+ SSL_GETPID(), ss->fd));
+ return SECFailure;
+ }
+
+ SSL_DBG(("%d: SSL[%d]: Negotiated extended master secret extension.",
+ SSL_GETPID(), ss->fd));
+
+ /* Keep track of negotiated extensions. */
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+
+ if (ss->sec.isServer) {
+ return ssl3_RegisterServerHelloExtensionSender(
+ ss, ex_type, ssl3_SendExtendedMasterSecretXtn);
+ }
+ return SECSuccess;
+}
+
+static SECStatus
ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data)
{
diff --git a/chromium/net/third_party/nss/ssl/ssl3gthr.c b/chromium/net/third_party/nss/ssl/ssl3gthr.c
index cd487c6670a..23b9755b600 100644
--- a/chromium/net/third_party/nss/ssl/ssl3gthr.c
+++ b/chromium/net/third_party/nss/ssl/ssl3gthr.c
@@ -71,8 +71,8 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
break;
}
- PORT_Assert( nb <= gs->remainder );
- if (nb > gs->remainder) {
+ PORT_Assert( (unsigned int)nb <= gs->remainder );
+ if ((unsigned int)nb > gs->remainder) {
/* ssl_DefRecv is misbehaving! this error is fatal to SSL. */
gs->state = GS_INIT; /* so we don't crash next time */
rv = SECFailure;
diff --git a/chromium/net/third_party/nss/ssl/ssl3prot.h b/chromium/net/third_party/nss/ssl/ssl3prot.h
index 78fbcaa02db..848bdee7a20 100644
--- a/chromium/net/third_party/nss/ssl/ssl3prot.h
+++ b/chromium/net/third_party/nss/ssl/ssl3prot.h
@@ -218,32 +218,6 @@ typedef struct {
} u;
} SSL3ServerParams;
-/* This enum reflects HashAlgorithm enum from
- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
- *
- * When updating, be sure to also update ssl3_TLSHashAlgorithmToOID. */
-enum {
- tls_hash_md5 = 1,
- tls_hash_sha1 = 2,
- tls_hash_sha224 = 3,
- tls_hash_sha256 = 4,
- tls_hash_sha384 = 5,
- tls_hash_sha512 = 6
-};
-
-/* This enum reflects SignatureAlgorithm enum from
- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
-typedef enum {
- tls_sig_rsa = 1,
- tls_sig_dsa = 2,
- tls_sig_ecdsa = 3
-} TLSSignatureAlgorithm;
-
-typedef struct {
- SECOidTag hashAlg;
- TLSSignatureAlgorithm sigAlg;
-} SSL3SignatureAndHashAlgorithm;
-
/* SSL3HashesIndividually contains a combination MD5/SHA1 hash, as used in TLS
* prior to 1.2. */
typedef struct {
@@ -252,11 +226,11 @@ typedef struct {
} SSL3HashesIndividually;
/* SSL3Hashes contains an SSL hash value. The digest is contained in |u.raw|
- * which, if |hashAlg==SEC_OID_UNKNOWN| is also a SSL3HashesIndividually
+ * which, if |hashAlg==ssl_hash_none| is also a SSL3HashesIndividually
* struct. */
typedef struct {
unsigned int len;
- SECOidTag hashAlg;
+ SSLHashType hashAlg;
union {
PRUint8 raw[64];
SSL3HashesIndividually s;
diff --git a/chromium/net/third_party/nss/ssl/sslauth.c b/chromium/net/third_party/nss/ssl/sslauth.c
index c2d920120bb..03b23b48d12 100644
--- a/chromium/net/third_party/nss/ssl/sslauth.c
+++ b/chromium/net/third_party/nss/ssl/sslauth.c
@@ -304,8 +304,7 @@ SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
&certStatusArray->items[0],
ss->pkcs11PinArg)
!= SECSuccess) {
- PRErrorCode error = PR_GetError();
- PORT_Assert(error != 0);
+ PORT_Assert(PR_GetError() != 0);
}
}
diff --git a/chromium/net/third_party/nss/ssl/sslcon.c b/chromium/net/third_party/nss/ssl/sslcon.c
index 8c5a5ad3dea..ccd00260ec2 100644
--- a/chromium/net/third_party/nss/ssl/sslcon.c
+++ b/chromium/net/third_party/nss/ssl/sslcon.c
@@ -22,20 +22,6 @@
static PRBool policyWasSet;
-/* This ordered list is indexed by (SSL_CK_xx * 3) */
-/* Second and third bytes are MSB and LSB of master key length. */
-static const PRUint8 allCipherSuites[] = {
- 0, 0, 0,
- SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_IDEA_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40,
- SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0,
- 0, 0, 0
-};
-
#define ssl2_NUM_SUITES_IMPLEMENTED 6
/* This list is sent back to the client when the client-hello message
@@ -851,7 +837,7 @@ ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
{
PRUint8 * out;
int rv;
- int amount;
+ unsigned int amount;
int count = 0;
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
@@ -927,7 +913,7 @@ ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
int amount;
PRUint8 macLen;
int nout;
- int buflen;
+ unsigned int buflen;
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
@@ -1031,7 +1017,7 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
int amount; /* of plaintext to go in record. */
unsigned int padding; /* add this many padding byte. */
int nout; /* ciphertext size after header. */
- int buflen; /* size of generated record. */
+ unsigned int buflen; /* size of generated record. */
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
@@ -1555,7 +1541,7 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
unsigned int ddLen; /* length of RSA decrypted data in kbuf */
unsigned int keySize;
unsigned int dkLen; /* decrypted key length in bytes */
- int modulusLen;
+ int modulusLen;
SECStatus rv;
PRUint16 allowed; /* cipher kinds enabled and allowed by policy */
PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES];
@@ -1617,11 +1603,11 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
}
modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
- if (modulusLen == -1) {
+ if (modulusLen < 0) {
/* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */
modulusLen = ekLen;
}
- if (ekLen > modulusLen || ekLen + ckLen < keySize) {
+ if (ekLen > (unsigned int)modulusLen || ekLen + ckLen < keySize) {
SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!",
SSL_GETPID(), ss->fd, ekLen));
PORT_SetError(SSL_ERROR_BAD_CLIENT);
@@ -2495,7 +2481,6 @@ ssl2_HandleMessage(sslSocket *ss)
PRUint8 * cid;
unsigned len, certType, certLen, responseLen;
int rv;
- int rv2;
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
@@ -2613,7 +2598,7 @@ ssl2_HandleMessage(sslSocket *ss)
data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
responseLen);
if (rv) {
- rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
+ (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
SET_ERROR_CODE
goto loser;
}
@@ -2741,7 +2726,7 @@ ssl2_HandleServerHelloMessage(sslSocket *ss)
PRUint8 * cs;
PRUint8 * data;
SECStatus rv;
- int needed, sidHit, certLen, csLen, cidLen, certType, err;
+ unsigned int needed, sidHit, certLen, csLen, cidLen, certType, err;
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
@@ -3669,12 +3654,14 @@ loser:
*/
#include "nss.h"
-extern const char __nss_ssl_rcsid[];
-extern const char __nss_ssl_sccsid[];
+extern const char __nss_ssl_version[];
PRBool
NSSSSL_VersionCheck(const char *importedVersion)
{
+#define NSS_VERSION_VARIABLE __nss_ssl_version
+#include "verref.h"
+
/*
* This is the secret handshake algorithm.
*
@@ -3684,9 +3671,6 @@ NSSSSL_VersionCheck(const char *importedVersion)
* not compatible with future major, minor, or
* patch releases.
*/
- volatile char c; /* force a reference that won't get optimized away */
-
- c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0];
return NSS_VersionCheck(importedVersion);
}
diff --git a/chromium/net/third_party/nss/ssl/sslenum.c b/chromium/net/third_party/nss/ssl/sslenum.c
index a036627f9ed..b4a8844470b 100644
--- a/chromium/net/third_party/nss/ssl/sslenum.c
+++ b/chromium/net/third_party/nss/ssl/sslenum.c
@@ -70,14 +70,17 @@ const PRUint16 SSL_ImplementedCiphers[] = {
#endif /* NSS_DISABLE_ECC */
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
diff --git a/chromium/net/third_party/nss/ssl/sslerr.h b/chromium/net/third_party/nss/ssl/sslerr.h
index 24bf89318cb..835b8125121 100644
--- a/chromium/net/third_party/nss/ssl/sslerr.h
+++ b/chromium/net/third_party/nss/ssl/sslerr.h
@@ -198,9 +198,19 @@ SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131),
-SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 132),
-SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 133),
-SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 134),
+SSL_ERROR_WEAK_SERVER_CERT_KEY = (SSL_ERROR_BASE + 132),
+
+SSL_ERROR_RX_SHORT_DTLS_READ = (SSL_ERROR_BASE + 133),
+
+SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 134),
+SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135),
+
+SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136),
+SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137),
+
+SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 138),
+SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 139),
+SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 140),
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
diff --git a/chromium/net/third_party/nss/ssl/sslimpl.h b/chromium/net/third_party/nss/ssl/sslimpl.h
index efcbf9faddc..874e59c6223 100644
--- a/chromium/net/third_party/nss/ssl/sslimpl.h
+++ b/chromium/net/third_party/nss/ssl/sslimpl.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is PRIVATE to SSL and should be the first thing included by
* any SSL implementation file.
@@ -181,6 +182,7 @@ typedef struct ssl3CertNodeStr ssl3CertNode;
typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef;
typedef struct ssl3MACDefStr ssl3MACDef;
typedef struct ssl3KeyPairStr ssl3KeyPair;
+typedef struct ssl3DHParamsStr ssl3DHParams;
struct ssl3CertNodeStr {
struct ssl3CertNodeStr *next;
@@ -300,13 +302,19 @@ typedef struct {
} ssl3CipherSuiteCfg;
#ifndef NSS_DISABLE_ECC
-#define ssl_V3_SUITES_IMPLEMENTED 63
+#define ssl_V3_SUITES_IMPLEMENTED 66
#else
-#define ssl_V3_SUITES_IMPLEMENTED 37
+#define ssl_V3_SUITES_IMPLEMENTED 40
#endif /* NSS_DISABLE_ECC */
#define MAX_DTLS_SRTP_CIPHER_SUITES 4
+/* MAX_SIGNATURE_ALGORITHMS allows for a large number of combinations of
+ * SSLSignType and SSLHashType, but not all combinations (specifically, this
+ * doesn't allow space for combinations with MD5). */
+#define MAX_SIGNATURE_ALGORITHMS 15
+
+
typedef struct sslOptionsStr {
/* If SSL_SetNextProtoNego has been called, then this contains the
* list of supported protocols. */
@@ -339,7 +347,9 @@ typedef struct sslOptionsStr {
unsigned int enableALPN : 1; /* 27 */
unsigned int reuseServerECDHEKey : 1; /* 28 */
unsigned int enableFallbackSCSV : 1; /* 29 */
- unsigned int enableSignedCertTimestamps : 1; /* 30 */
+ unsigned int enableServerDhe : 1; /* 30 */
+ unsigned int enableExtendedMS : 1; /* 31 */
+ unsigned int enableSignedCertTimestamps : 1; /* 32 */
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
@@ -521,6 +531,7 @@ typedef struct {
PRUint16 wrapped_master_secret_len;
PRUint8 msIsWrapped;
PRUint8 resumable;
+ PRUint8 extendedMasterSecretUsed;
} ssl3SidKeys; /* 52 bytes */
typedef struct {
@@ -766,10 +777,10 @@ typedef struct {
* is_limited identifies a suite as having a limit on the key size.
* key_size_limit provides the corresponding limit. */
PRBool is_limited;
- int key_size_limit;
+ unsigned int key_size_limit;
PRBool tls_keygen;
- /* True if the key exchange for the suite can be ephemeral. Or to be more
- * precise: true if the ServerKeyExchange message is required. */
+ /* True if the key exchange for the suite is ephemeral. Or to be more
+ * precise: true if the ServerKeyExchange message is always required. */
PRBool ephemeral;
} ssl3KEADef;
@@ -955,12 +966,14 @@ const ssl3CipherSuiteDef *suite_def;
PRBool cacheSID;
PRBool canFalseStart; /* Can/did we False Start */
+ /* Which preliminaryinfo values have been set. */
+ PRUint32 preliminaryInfo;
/* clientSigAndHash contains the contents of the signature_algorithms
* extension (if any) from the client. This is only valid for TLS 1.2
* or later. */
- SSL3SignatureAndHashAlgorithm *clientSigAndHash;
- unsigned int numClientSigAndHash;
+ SSLSignatureAndHashAlg *clientSigAndHash;
+ unsigned int numClientSigAndHash;
/* This group of values is used for DTLS */
PRUint16 sendMessageSeq; /* The sending message sequence
@@ -1044,9 +1057,17 @@ struct ssl3StateStr {
PRUint16 dtlsSRTPCipherCount;
PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */
PRBool fatalAlertSent;
+ PRUint16 numDHEGroups; /* used by server */
+ SSLDHEGroupType * dheGroups; /* used by server */
+ PRBool dheWeakGroupEnabled; /* used by server */
+
+ /* TLS 1.2 introduces separate signature algorithm negotiation.
+ * This is our preference order. */
+ SSLSignatureAndHashAlg signatureAlgorithms[MAX_SIGNATURE_ALGORITHMS];
+ unsigned int signatureAlgorithmCount;
};
-#define DTLS_MAX_MTU 1500 /* Ethernet MTU but without subtracting the
+#define DTLS_MAX_MTU 1500U /* Ethernet MTU but without subtracting the
* headers, so slightly larger than expected */
#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram)
@@ -1063,6 +1084,11 @@ struct ssl3KeyPairStr {
PRInt32 refCount; /* use PR_Atomic calls for this. */
};
+struct ssl3DHParamsStr {
+ SECItem prime; /* p */
+ SECItem base; /* g */
+};
+
typedef struct SSLWrappedSymWrappingKeyStr {
SSL3Opaque wrappedSymmetricWrappingkey[512];
CK_MECHANISM_TYPE symWrapMechanism;
@@ -1093,6 +1119,7 @@ typedef struct SessionTicketStr {
CK_MECHANISM_TYPE msWrapMech;
PRUint16 ms_length;
SSL3Opaque master_secret[48];
+ PRBool extendedMasterSecretUsed;
ClientIdentity client_identity;
SECItem peer_cert;
PRUint32 timestamp;
@@ -1275,6 +1302,9 @@ const unsigned char * preferredCipher;
ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */
+ const ssl3DHParams *dheParams; /* DHE param */
+ ssl3KeyPair * dheKeyPair; /* DHE keys */
+
/* Callbacks */
SSLAuthCertificate authCertificate;
void *authCertificateArg;
@@ -1634,7 +1664,7 @@ extern PRBool ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
extern SECStatus ssl3_KeyAndMacDeriveBypass(ssl3CipherSpec * pwSpec,
const unsigned char * cr, const unsigned char * sr,
PRBool isTLS, PRBool isExport);
-extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec,
+extern SECStatus ssl3_MasterSecretDeriveBypass( ssl3CipherSpec * pwSpec,
const unsigned char * cr, const unsigned char * sr,
const SECItem * pms, PRBool isTLS, PRBool isRSA);
@@ -1688,6 +1718,8 @@ int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags);
*/
extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss);
+extern SECStatus ssl3_SelectDHParams(sslSocket *ss);
+
#ifndef NSS_DISABLE_ECC
extern void ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss);
extern PRBool ssl3_IsECCEnabled(sslSocket *ss);
@@ -1790,11 +1822,11 @@ extern SECStatus ssl3_HandleECDHClientKeyExchange(sslSocket *ss,
SSL3Opaque *b, PRUint32 length,
SECKEYPublicKey *srvrPubKey,
SECKEYPrivateKey *srvrPrivKey);
-extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss,
- const SSL3SignatureAndHashAlgorithm *sigAndHash);
+extern SECStatus ssl3_SendECDHServerKeyExchange(
+ sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash);
#endif
-extern SECStatus ssl3_ComputeCommonKeyHash(SECOidTag hashAlg,
+extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
PRUint8 * hashBuf,
unsigned int bufLen, SSL3Hashes *hashes,
PRBool bypassPKCS11);
@@ -1808,21 +1840,22 @@ extern SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num,
PRInt32 lenSize);
extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss,
const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize);
-extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(sslSocket *ss,
- const SSL3SignatureAndHashAlgorithm* sigAndHash);
+extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(
+ sslSocket *ss, const SSLSignatureAndHashAlg* sigAndHash);
extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes,
SSL3Opaque **b, PRUint32 *length);
extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes,
SSL3Opaque **b, PRUint32 *length);
extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i,
PRInt32 bytes, SSL3Opaque **b, PRUint32 *length);
-extern SECOidTag ssl3_TLSHashAlgorithmToOID(int hashFunc);
+extern PRBool ssl3_IsSupportedSignatureAlgorithm(
+ const SSLSignatureAndHashAlg *alg);
extern SECStatus ssl3_CheckSignatureAndHashAlgorithmConsistency(
- const SSL3SignatureAndHashAlgorithm *sigAndHash,
- CERTCertificate* cert);
-extern SECStatus ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss,
- SSL3Opaque **b, PRUint32 *length,
- SSL3SignatureAndHashAlgorithm *out);
+ sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash,
+ CERTCertificate* cert);
+extern SECStatus ssl3_ConsumeSignatureAndHashAlgorithm(
+ sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
+ SSLSignatureAndHashAlg *out);
extern SECStatus ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key,
SECItem *buf, PRBool isTLS);
extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash,
@@ -1890,7 +1923,7 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
/* Tell clients to consider tickets valid for this long. */
#define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */
-#define TLS_EX_SESS_TICKET_VERSION (0x0100)
+#define TLS_EX_SESS_TICKET_VERSION (0x0101)
extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
unsigned int length);
@@ -2024,6 +2057,8 @@ ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec,
const char *label, unsigned int labelLen,
const unsigned char *val, unsigned int valLen,
unsigned char *out, unsigned int outLen);
+extern SECOidTag
+ssl3_TLSHashAlgorithmToOID(SSLHashType hashFunc);
#ifdef TRACE
#define SSL_TRACE(msg) ssl_Trace msg
diff --git a/chromium/net/third_party/nss/ssl/sslinfo.c b/chromium/net/third_party/nss/ssl/sslinfo.c
index 845d9f02cf9..bef3190f367 100644
--- a/chromium/net/third_party/nss/ssl/sslinfo.c
+++ b/chromium/net/third_party/nss/ssl/sslinfo.c
@@ -67,6 +67,8 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
inf.creationTime = sid->creationTime;
inf.lastAccessTime = sid->lastAccessTime;
inf.expirationTime = sid->expirationTime;
+ inf.extendedMasterSecretUsed = sid->u.ssl3.keys.extendedMasterSecretUsed;
+
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
inf.sessionIDLength = SSL2_SESSIONID_BYTES;
memcpy(inf.sessionID, sid->u.ssl2.sessionID,
@@ -85,6 +87,42 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
return SECSuccess;
}
+SECStatus
+SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
+ SSLPreliminaryChannelInfo *info,
+ PRUintn len)
+{
+ sslSocket *ss;
+ SSLPreliminaryChannelInfo inf;
+
+ if (!info || len < sizeof inf.length) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPreliminaryChannelInfo",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (ss->version < SSL_LIBRARY_VERSION_3_0) {
+ PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
+ return SECFailure;
+ }
+
+ memset(&inf, 0, sizeof(inf));
+ inf.length = PR_MIN(sizeof(inf), len);
+
+ inf.valuesSet = ss->ssl3.hs.preliminaryInfo;
+ inf.protocolVersion = ss->version;
+ inf.cipherSuite = ss->ssl3.hs.cipher_suite;
+
+ memcpy(info, &inf, inf.length);
+ return SECSuccess;
+}
+
#define CS(x) x, #x
#define CK(x) x | 0xff00, #x
@@ -136,6 +174,7 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0, },
{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
+{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0, },
{0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, 1, 0, 0, },
{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, },
@@ -146,7 +185,9 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
{0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
+{0,CS(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
+{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
{0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, },
{0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
@@ -247,12 +288,10 @@ SSL_DisableDefaultExportCipherSuites(void)
{
const SSLCipherSuiteInfo * pInfo = suiteInfo;
unsigned int i;
- SECStatus rv;
for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
if (pInfo->isExportable) {
- rv = SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE);
- PORT_Assert(rv == SECSuccess);
+ PORT_CheckSuccess(SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE));
}
}
return SECSuccess;
@@ -268,12 +307,10 @@ SSL_DisableExportCipherSuites(PRFileDesc * fd)
{
const SSLCipherSuiteInfo * pInfo = suiteInfo;
unsigned int i;
- SECStatus rv;
for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
if (pInfo->isExportable) {
- rv = SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE);
- PORT_Assert(rv == SECSuccess);
+ PORT_CheckSuccess(SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE));
}
}
return SECSuccess;
diff --git a/chromium/net/third_party/nss/ssl/sslmutex.c b/chromium/net/third_party/nss/ssl/sslmutex.c
index ff6368069df..af683daf561 100644
--- a/chromium/net/third_party/nss/ssl/sslmutex.c
+++ b/chromium/net/third_party/nss/ssl/sslmutex.c
@@ -504,7 +504,7 @@ sslMutex_Lock(sslMutex *pMutex)
return SECSuccess;
}
-#elif defined(XP_UNIX)
+#elif defined(XP_UNIX) && !defined(DARWIN)
#include <errno.h>
#include "unix_err.h"
diff --git a/chromium/net/third_party/nss/ssl/sslmutex.h b/chromium/net/third_party/nss/ssl/sslmutex.h
index b784baf665b..d374a883b73 100644
--- a/chromium/net/third_party/nss/ssl/sslmutex.h
+++ b/chromium/net/third_party/nss/ssl/sslmutex.h
@@ -67,7 +67,8 @@ typedef struct {
} sslMutex;
typedef pid_t sslPID;
-#elif defined(XP_UNIX) /* other types of Unix */
+/* other types of unix, except OS X */
+#elif defined(XP_UNIX) && !defined(DARWIN)
#include <sys/types.h> /* for pid_t */
#include <semaphore.h> /* for sem_t, and sem_* functions */
@@ -83,7 +84,7 @@ typedef struct
typedef pid_t sslPID;
-#else
+#else /* no support for cross-process locking */
/* what platform is this ?? */
@@ -95,7 +96,11 @@ typedef struct {
} u;
} sslMutex;
+#ifdef DARWIN
+typedef pid_t sslPID;
+#else
typedef int sslPID;
+#endif
#endif
diff --git a/chromium/net/third_party/nss/ssl/sslproto.h b/chromium/net/third_party/nss/ssl/sslproto.h
index dc653c91f73..36ae6c9c200 100644
--- a/chromium/net/third_party/nss/ssl/sslproto.h
+++ b/chromium/net/third_party/nss/ssl/sslproto.h
@@ -177,6 +177,7 @@
#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C
#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D
+#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 0x0040
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0041
#define TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0042
#define TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0043
@@ -191,6 +192,7 @@
#define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065
#define TLS_DHE_DSS_WITH_RC4_128_SHA 0x0066
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067
+#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0084
diff --git a/chromium/net/third_party/nss/ssl/sslsecur.c b/chromium/net/third_party/nss/ssl/sslsecur.c
index 00ab455b56c..b4b8e9558b1 100644
--- a/chromium/net/third_party/nss/ssl/sslsecur.c
+++ b/chromium/net/third_party/nss/ssl/sslsecur.c
@@ -138,6 +138,9 @@ ssl_FinishHandshake(sslSocket *ss)
ss->gs.readOffset = 0;
if (ss->handshakeCallback) {
+ PORT_Assert(ss->version < SSL_LIBRARY_VERSION_3_0 ||
+ (ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
}
}
@@ -654,6 +657,16 @@ DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
SSL_GETPID(), ss->fd, available));
}
+ if (IS_DTLS(ss) && (len < available)) {
+ /* DTLS does not allow you to do partial reads */
+ SSL_TRC(30, ("%d: SSL[%d]: DTLS short read. len=%d available=%d",
+ SSL_GETPID(), ss->fd, len, available));
+ ss->gs.readOffset += available;
+ PORT_SetError(SSL_ERROR_RX_SHORT_DTLS_READ);
+ rv = SECFailure;
+ goto done;
+ }
+
/* Dole out clear data to reader */
amount = PR_MIN(len, available);
PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount);
@@ -693,6 +706,7 @@ NSS_FindCertKEAType(CERTCertificate * cert)
case SEC_OID_PKCS1_RSA_ENCRYPTION:
keaType = kt_rsa;
break;
+ case SEC_OID_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
keaType = kt_dh;
break;
@@ -789,6 +803,11 @@ ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert,
goto loser;
}
}
+ if (kea == ssl_kea_dh || kea == ssl_kea_rsa) {
+ if (ssl3_SelectDHParams(ss) != SECSuccess) {
+ goto loser;
+ }
+ }
return SECSuccess;
loser:
@@ -1177,11 +1196,8 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow)
int
ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
{
- sslSecurityInfo *sec;
int rv = 0;
- sec = &ss->sec;
-
if (ss->shutdownHow & ssl_SHUTDOWN_RCV) {
PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
return PR_FAILURE;
diff --git a/chromium/net/third_party/nss/ssl/sslsnce.c b/chromium/net/third_party/nss/ssl/sslsnce.c
index 327920080c5..3856c13166f 100644
--- a/chromium/net/third_party/nss/ssl/sslsnce.c
+++ b/chromium/net/third_party/nss/ssl/sslsnce.c
@@ -120,14 +120,14 @@ struct sidCacheEntryStr {
/* 2 */ ssl3CipherSuite cipherSuite;
/* 2 */ PRUint16 compression; /* SSLCompressionMethod */
-/* 52 */ ssl3SidKeys keys; /* keys, wrapped as needed. */
+/* 54 */ ssl3SidKeys keys; /* keys, wrapped as needed. */
/* 4 */ PRUint32 masterWrapMech;
/* 4 */ SSL3KEAType exchKeyType;
/* 4 */ PRInt32 certIndex;
/* 4 */ PRInt32 srvNameIndex;
/* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
-/*104 */} ssl3;
+/*108 */} ssl3;
/* force sizeof(sidCacheEntry) to be a multiple of cache line size */
struct {
/*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */
@@ -507,7 +507,6 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
to->sessionIDLength = from->u.ssl3.sessionIDLength;
to->u.ssl3.certIndex = -1;
to->u.ssl3.srvNameIndex = -1;
-
PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
to->sessionIDLength);
@@ -637,7 +636,7 @@ ConvertToSID(sidCacheEntry * from,
to->authKeyBits = from->authKeyBits;
to->keaType = from->keaType;
to->keaKeyBits = from->keaKeyBits;
-
+
return to;
loser:
@@ -1228,20 +1227,32 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
/* Fix pointers in our private copy of cache descriptor to point to
** spaces in shared memory
*/
- ptr = (ptrdiff_t)cache->cacheMem;
- *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheData) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
- *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
+ cache->sidCacheLocks = (sidCacheLock *)
+ (cache->cacheMem + (ptrdiff_t)cache->sidCacheLocks);
+ cache->keyCacheLock = (sidCacheLock *)
+ (cache->cacheMem + (ptrdiff_t)cache->keyCacheLock);
+ cache->certCacheLock = (sidCacheLock *)
+ (cache->cacheMem + (ptrdiff_t)cache->certCacheLock);
+ cache->srvNameCacheLock = (sidCacheLock *)
+ (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
+ cache->sidCacheSets = (sidCacheSet *)
+ (cache->cacheMem + (ptrdiff_t)cache->sidCacheSets);
+ cache->sidCacheData = (sidCacheEntry *)
+ (cache->cacheMem + (ptrdiff_t)cache->sidCacheData);
+ cache->certCacheData = (certCacheEntry *)
+ (cache->cacheMem + (ptrdiff_t)cache->certCacheData);
+ cache->keyCacheData = (SSLWrappedSymWrappingKey *)
+ (cache->cacheMem + (ptrdiff_t)cache->keyCacheData);
+ cache->ticketKeyNameSuffix = (PRUint8 *)
+ (cache->cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
+ cache->ticketEncKey = (encKeyCacheEntry *)
+ (cache->cacheMem + (ptrdiff_t)cache->ticketEncKey);
+ cache->ticketMacKey = (encKeyCacheEntry *)
+ (cache->cacheMem + (ptrdiff_t)cache->ticketMacKey);
+ cache->ticketKeysValid = (PRUint32 *)
+ (cache->cacheMem + (ptrdiff_t)cache->ticketKeysValid);
+ cache->srvNameCacheData = (srvNameCacheEntry *)
+ (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData);
/* initialize the locks */
init_time = ssl_Time();
@@ -1484,7 +1495,6 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
char * fmString = NULL;
char * myEnvString = NULL;
unsigned int decoLen;
- ptrdiff_t ptr;
inheritance inherit;
cacheDesc my;
#ifdef WINNT
@@ -1580,20 +1590,32 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
/* Fix pointers in our private copy of cache descriptor to point to
** spaces in shared memory, whose address is now in "my".
*/
- ptr = (ptrdiff_t)my.cacheMem;
- *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheData) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
- *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
+ cache->sidCacheLocks = (sidCacheLock *)
+ (my.cacheMem + (ptrdiff_t)cache->sidCacheLocks);
+ cache->keyCacheLock = (sidCacheLock *)
+ (my.cacheMem + (ptrdiff_t)cache->keyCacheLock);
+ cache->certCacheLock = (sidCacheLock *)
+ (my.cacheMem + (ptrdiff_t)cache->certCacheLock);
+ cache->srvNameCacheLock = (sidCacheLock *)
+ (my.cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
+ cache->sidCacheSets = (sidCacheSet *)
+ (my.cacheMem + (ptrdiff_t)cache->sidCacheSets);
+ cache->sidCacheData = (sidCacheEntry *)
+ (my.cacheMem + (ptrdiff_t)cache->sidCacheData);
+ cache->certCacheData = (certCacheEntry *)
+ (my.cacheMem + (ptrdiff_t)cache->certCacheData);
+ cache->keyCacheData = (SSLWrappedSymWrappingKey *)
+ (my.cacheMem + (ptrdiff_t)cache->keyCacheData);
+ cache->ticketKeyNameSuffix = (PRUint8 *)
+ (my.cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
+ cache->ticketEncKey = (encKeyCacheEntry *)
+ (my.cacheMem + (ptrdiff_t)cache->ticketEncKey);
+ cache->ticketMacKey = (encKeyCacheEntry *)
+ (my.cacheMem + (ptrdiff_t)cache->ticketMacKey);
+ cache->ticketKeysValid = (PRUint32 *)
+ (my.cacheMem + (ptrdiff_t)cache->ticketKeysValid);
+ cache->srvNameCacheData = (srvNameCacheEntry *)
+ (my.cacheMem + (ptrdiff_t)cache->srvNameCacheData);
cache->cacheMemMap = my.cacheMemMap;
cache->cacheMem = my.cacheMem;
diff --git a/chromium/net/third_party/nss/ssl/sslsock.c b/chromium/net/third_party/nss/ssl/sslsock.c
index 09a0fb514b2..0a8fbf0fdcd 100644
--- a/chromium/net/third_party/nss/ssl/sslsock.c
+++ b/chromium/net/third_party/nss/ssl/sslsock.c
@@ -19,6 +19,7 @@
#endif
#include "pk11pub.h"
#include "nss.h"
+#include "pk11pqg.h"
/* This is a bodge to allow this code to be compiled against older NSS headers
* that don't contain the TLS 1.2 changes. */
@@ -90,6 +91,8 @@ static sslOptions ssl_defaults = {
PR_FALSE, /* enableALPN */
PR_TRUE, /* reuseServerECDHEKey */
PR_FALSE, /* enableFallbackSCSV */
+ PR_TRUE, /* enableServerDhe */
+ PR_FALSE, /* enableExtendedMS */
PR_FALSE, /* enableSignedCertTimestamps */
};
@@ -232,6 +235,24 @@ ssl_DupSocket(sslSocket *os)
PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
+ PORT_Memcpy(ss->ssl3.signatureAlgorithms, os->ssl3.signatureAlgorithms,
+ sizeof(ss->ssl3.signatureAlgorithms[0]) *
+ os->ssl3.signatureAlgorithmCount);
+ ss->ssl3.signatureAlgorithmCount = os->ssl3.signatureAlgorithmCount;
+
+ ss->ssl3.dheWeakGroupEnabled = os->ssl3.dheWeakGroupEnabled;
+ ss->ssl3.numDHEGroups = os->ssl3.numDHEGroups;
+ if (os->ssl3.dheGroups) {
+ ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType,
+ os->ssl3.numDHEGroups);
+ if (!ss->ssl3.dheGroups) {
+ goto loser;
+ }
+ PORT_Memcpy(ss->ssl3.dheGroups, os->ssl3.dheGroups,
+ sizeof(SSLDHEGroupType) * os->ssl3.numDHEGroups);
+ } else {
+ ss->ssl3.dheGroups = NULL;
+ }
if (os->cipherSpecs) {
ss->cipherSpecs = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
@@ -275,6 +296,10 @@ ssl_DupSocket(sslSocket *os)
ssl3_GetKeyPairRef(os->stepDownKeyPair);
ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
+ ss->dheKeyPair = !os->dheKeyPair ? NULL :
+ ssl3_GetKeyPairRef(os->dheKeyPair);
+ ss->dheParams = os->dheParams;
+
/*
* XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
* XXX We should detect this, and not just march on with NULL pointers.
@@ -398,8 +423,11 @@ ssl_DestroySocketContents(sslSocket *ss)
ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
ss->ephemeralECDHKeyPair = NULL;
}
+ if (ss->dheKeyPair) {
+ ssl3_FreeKeyPair(ss->dheKeyPair);
+ ss->dheKeyPair = NULL;
+ }
SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
- PORT_Assert(!ss->xtnData.sniNameArr);
if (ss->xtnData.sniNameArr) {
PORT_Free(ss->xtnData.sniNameArr);
ss->xtnData.sniNameArr = NULL;
@@ -808,6 +836,14 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
ss->opt.enableFallbackSCSV = on;
break;
+ case SSL_ENABLE_SERVER_DHE:
+ ss->opt.enableServerDhe = on;
+ break;
+
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ ss->opt.enableExtendedMS = on;
+ break;
+
case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
ss->opt.enableSignedCertTimestamps = on;
break;
@@ -887,6 +923,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
case SSL_REUSE_SERVER_ECDHE_KEY:
on = ss->opt.reuseServerECDHEKey; break;
case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
+ case SSL_ENABLE_SERVER_DHE: on = ss->opt.enableServerDhe; break;
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ on = ss->opt.enableExtendedMS; break;
case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
on = ss->opt.enableSignedCertTimestamps;
break;
@@ -959,6 +998,12 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
case SSL_ENABLE_FALLBACK_SCSV:
on = ssl_defaults.enableFallbackSCSV;
break;
+ case SSL_ENABLE_SERVER_DHE:
+ on = ssl_defaults.enableServerDhe;
+ break;
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ on = ssl_defaults.enableExtendedMS;
+ break;
case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
on = ssl_defaults.enableSignedCertTimestamps;
break;
@@ -1145,6 +1190,14 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
ssl_defaults.enableFallbackSCSV = on;
break;
+ case SSL_ENABLE_SERVER_DHE:
+ ssl_defaults.enableServerDhe = on;
+ break;
+
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ ssl_defaults.enableExtendedMS = on;
+ break;
+
case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
ssl_defaults.enableSignedCertTimestamps = on;
break;
@@ -1381,6 +1434,148 @@ NSS_SetFrancePolicy(void)
}
SECStatus
+SSL_DHEGroupPrefSet(PRFileDesc *fd,
+ SSLDHEGroupType *groups,
+ PRUint16 num_groups)
+{
+ sslSocket *ss;
+
+ if ((num_groups && !groups) || (!num_groups && groups)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DHEGroupPrefSet", SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (ss->ssl3.dheGroups) {
+ PORT_Free(ss->ssl3.dheGroups);
+ ss->ssl3.dheGroups = NULL;
+ ss->ssl3.numDHEGroups = 0;
+ }
+
+ if (groups) {
+ ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType, num_groups);
+ if (!ss->ssl3.dheGroups) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ PORT_Memcpy(ss->ssl3.dheGroups, groups,
+ sizeof(SSLDHEGroupType) * num_groups);
+ }
+ return SECSuccess;
+}
+
+
+PRCallOnceType gWeakDHParamsRegisterOnce;
+int gWeakDHParamsRegisterError;
+
+PRCallOnceType gWeakDHParamsOnce;
+int gWeakDHParamsError;
+/* As our code allocates type PQGParams, we'll keep it around,
+ * even though we only make use of it's parameters through gWeakDHParam. */
+static PQGParams *gWeakParamsPQG;
+static ssl3DHParams *gWeakDHParams;
+
+static PRStatus
+ssl3_CreateWeakDHParams(void)
+{
+ PQGVerify *vfy;
+ SECStatus rv, passed;
+
+ PORT_Assert(!gWeakDHParams && !gWeakParamsPQG);
+
+ rv = PK11_PQG_ParamGenV2(1024, 160, 64 /*maximum seed that will work*/,
+ &gWeakParamsPQG, &vfy);
+ if (rv != SECSuccess) {
+ gWeakDHParamsError = PORT_GetError();
+ return PR_FAILURE;
+ }
+
+ rv = PK11_PQG_VerifyParams(gWeakParamsPQG, vfy, &passed);
+ if (rv != SECSuccess || passed != SECSuccess) {
+ SSL_DBG(("%d: PK11_PQG_VerifyParams failed in ssl3_CreateWeakDHParams",
+ SSL_GETPID()));
+ gWeakDHParamsError = PORT_GetError();
+ return PR_FAILURE;
+ }
+
+ gWeakDHParams = PORT_ArenaNew(gWeakParamsPQG->arena, ssl3DHParams);
+ if (!gWeakDHParams) {
+ gWeakDHParamsError = PORT_GetError();
+ return PR_FAILURE;
+ }
+
+ gWeakDHParams->prime.data = gWeakParamsPQG->prime.data;
+ gWeakDHParams->prime.len = gWeakParamsPQG->prime.len;
+ gWeakDHParams->base.data = gWeakParamsPQG->base.data;
+ gWeakDHParams->base.len = gWeakParamsPQG->base.len;
+
+ PK11_PQG_DestroyVerify(vfy);
+ return PR_SUCCESS;
+}
+
+static SECStatus
+ssl3_WeakDHParamsShutdown(void *appData, void *nssData)
+{
+ if (gWeakParamsPQG) {
+ PK11_PQG_DestroyParams(gWeakParamsPQG);
+ gWeakParamsPQG = NULL;
+ gWeakDHParams = NULL;
+ }
+ return SECSuccess;
+}
+
+static PRStatus
+ssl3_WeakDHParamsRegisterShutdown(void)
+{
+ SECStatus rv;
+ rv = NSS_RegisterShutdown(ssl3_WeakDHParamsShutdown, NULL);
+ if (rv != SECSuccess) {
+ gWeakDHParamsRegisterError = PORT_GetError();
+ }
+ return (PRStatus)rv;
+}
+
+/* global init strategy inspired by ssl3_CreateECDHEphemeralKeys */
+SECStatus
+SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled)
+{
+ sslSocket *ss;
+ PRStatus status;
+
+ if (enabled) {
+ status = PR_CallOnce(&gWeakDHParamsRegisterOnce,
+ ssl3_WeakDHParamsRegisterShutdown);
+ if (status != PR_SUCCESS) {
+ PORT_SetError(gWeakDHParamsRegisterError);
+ return SECFailure;
+ }
+
+ status = PR_CallOnce(&gWeakDHParamsOnce, ssl3_CreateWeakDHParams);
+ if (status != PR_SUCCESS) {
+ PORT_SetError(gWeakDHParamsError);
+ return SECFailure;
+ }
+ }
+
+ if (!fd)
+ return SECSuccess;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DHEGroupPrefSet", SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ ss->ssl3.dheWeakGroupEnabled = enabled;
+ return SECSuccess;
+}
+
+SECStatus
SSL_GetChannelBinding(PRFileDesc *fd,
SSLChannelBindingType binding_type,
unsigned char *out,
@@ -1402,6 +1597,62 @@ SSL_GetChannelBinding(PRFileDesc *fd,
return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax);
}
+#include "dhe-param.c"
+
+static const SSLDHEGroupType ssl_default_dhe_groups[] = {
+ ssl_ff_dhe_2048_group
+};
+
+/* Keep this array synchronized with the index definitions in SSLDHEGroupType */
+static const ssl3DHParams *all_ssl3DHParams[] = {
+ NULL, /* ssl_dhe_group_none */
+ &ff_dhe_2048,
+ &ff_dhe_3072,
+ &ff_dhe_4096,
+ &ff_dhe_6144,
+ &ff_dhe_8192,
+};
+
+static SSLDHEGroupType
+selectDHEGroup(sslSocket *ss, const SSLDHEGroupType *groups, PRUint16 num_groups)
+{
+ if (!groups || !num_groups)
+ return ssl_dhe_group_none;
+
+ /* We don't have automatic group parameter selection yet
+ * (potentially) based on socket parameters, e.g. key sizes.
+ * For now, we return the first available group from the allowed list. */
+ return groups[0];
+}
+
+/* Ensure DH parameters have been selected */
+SECStatus
+ssl3_SelectDHParams(sslSocket *ss)
+{
+ SSLDHEGroupType selectedGroup = ssl_dhe_group_none;
+
+ if (ss->ssl3.dheWeakGroupEnabled) {
+ ss->dheParams = gWeakDHParams;
+ } else {
+ if (ss->ssl3.dheGroups) {
+ selectedGroup = selectDHEGroup(ss, ss->ssl3.dheGroups,
+ ss->ssl3.numDHEGroups);
+ } else {
+ size_t number_of_default_groups = PR_ARRAY_SIZE(ssl_default_dhe_groups);
+ selectedGroup = selectDHEGroup(ss, ssl_default_dhe_groups,
+ number_of_default_groups);
+ }
+
+ if (selectedGroup == ssl_dhe_group_none ||
+ selectedGroup >= ssl_dhe_group_max) {
+ return SECFailure;
+ }
+
+ ss->dheParams = all_ssl3DHParams[selectedGroup];
+ }
+
+ return SECSuccess;
+}
/* LOCKS ??? XXX */
static PRFileDesc *
@@ -1699,6 +1950,10 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;
+ PORT_Memcpy(ss->ssl3.signatureAlgorithms, sm->ssl3.signatureAlgorithms,
+ sizeof(ss->ssl3.signatureAlgorithms[0]) *
+ sm->ssl3.signatureAlgorithmCount);
+ ss->ssl3.signatureAlgorithmCount = sm->ssl3.signatureAlgorithmCount;
if (!ss->opt.useSecurity) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -3122,6 +3377,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
}
ss->requestedCertTypes = NULL;
ss->stepDownKeyPair = NULL;
+
+ ss->dheParams = NULL;
+ ss->dheKeyPair = NULL;
+
ss->dbHandle = CERT_GetDefaultCertDB();
/* Provide default implementation of hooks */
diff --git a/chromium/net/third_party/nss/ssl/sslt.h b/chromium/net/third_party/nss/ssl/sslt.h
index c36b8c73fd9..36e34dfb8d0 100644
--- a/chromium/net/third_party/nss/ssl/sslt.h
+++ b/chromium/net/third_party/nss/ssl/sslt.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file contains prototypes for the public SSL functions.
*
@@ -68,13 +69,35 @@ typedef enum {
#define kt_ecdh ssl_kea_ecdh
#define kt_kea_size ssl_kea_size
+
+/* Values of this enum match the SignatureAlgorithm enum from
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
typedef enum {
- ssl_sign_null = 0,
+ ssl_sign_null = 0, /* "anonymous" in TLS */
ssl_sign_rsa = 1,
ssl_sign_dsa = 2,
ssl_sign_ecdsa = 3
} SSLSignType;
+/* Values of this enum match the HashAlgorithm enum from
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
+typedef enum {
+ /* ssl_hash_none is used internally to mean the pre-1.2 combination of MD5
+ * and SHA1. The other values are only used in TLS 1.2. */
+ ssl_hash_none = 0,
+ ssl_hash_md5 = 1,
+ ssl_hash_sha1 = 2,
+ ssl_hash_sha224 = 3,
+ ssl_hash_sha256 = 4,
+ ssl_hash_sha384 = 5,
+ ssl_hash_sha512 = 6
+} SSLHashType;
+
+typedef struct SSLSignatureAndHashAlgStr {
+ SSLHashType hashAlg;
+ SSLSignType sigAlg;
+} SSLSignatureAndHashAlg;
+
typedef enum {
ssl_auth_null = 0,
ssl_auth_rsa = 1,
@@ -136,8 +159,31 @@ typedef struct SSLChannelInfoStr {
/* compression method info */
const char * compressionMethodName;
SSLCompressionMethod compressionMethod;
+
+ /* The following fields are added in NSS 3.21.
+ * This field only has meaning in TLS < 1.3 and will be set to
+ * PR_FALSE in TLS 1.3.
+ */
+ PRBool extendedMasterSecretUsed;
} SSLChannelInfo;
+/* Preliminary channel info */
+#define ssl_preinfo_version (1U << 0)
+#define ssl_preinfo_cipher_suite (1U << 1)
+#define ssl_preinfo_all (ssl_preinfo_version|ssl_preinfo_cipher_suite)
+
+typedef struct SSLPreliminaryChannelInfoStr {
+ /* This is set to the length of the struct. */
+ PRUint32 length;
+ /* A bitfield over SSLPreliminaryValueSet that describes which
+ * preliminary values are set (see ssl_preinfo_*). */
+ PRUint32 valuesSet;
+ /* Protocol version: test (valuesSet & ssl_preinfo_version) */
+ PRUint16 protocolVersion;
+ /* Cipher suite: test (valuesSet & ssl_preinfo_cipher_suite) */
+ PRUint16 cipherSuite;
+} SSLPreliminaryChannelInfo;
+
typedef struct SSLCipherSuiteInfoStr {
PRUint16 length;
PRUint16 cipherSuite;
@@ -204,6 +250,7 @@ typedef enum {
ssl_app_layer_protocol_xtn = 16,
ssl_signed_certificate_timestamp_xtn = 18, /* RFC 6962 */
ssl_padding_xtn = 21,
+ ssl_extended_master_secret_xtn = 23,
ssl_session_ticket_xtn = 35,
ssl_next_proto_nego_xtn = 13172,
ssl_channel_id_xtn = 30032,
@@ -211,6 +258,16 @@ typedef enum {
ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
} SSLExtensionType;
-#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */
+#define SSL_MAX_EXTENSIONS 14 /* doesn't include ssl_padding_xtn. */
+
+typedef enum {
+ ssl_dhe_group_none = 0,
+ ssl_ff_dhe_2048_group = 1,
+ ssl_ff_dhe_3072_group = 2,
+ ssl_ff_dhe_4096_group = 3,
+ ssl_ff_dhe_6144_group = 4,
+ ssl_ff_dhe_8192_group = 5,
+ ssl_dhe_group_max
+} SSLDHEGroupType;
#endif /* __sslt_h_ */
diff --git a/chromium/net/third_party/nss/ssl/sslver.c b/chromium/net/third_party/nss/ssl/sslver.c
index ea60888f233..666e2592243 100644
--- a/chromium/net/third_party/nss/ssl/sslver.c
+++ b/chromium/net/third_party/nss/ssl/sslver.c
@@ -12,20 +12,7 @@
#define _DEBUG_STRING ""
#endif
-#if defined(DONT_EMBED_BUILD_METADATA) && !defined(OFFICIAL_BUILD)
-#define _DATE_AND_TIME "Sep 02 2008 08:00:00"
-#else
-#define _DATE_AND_TIME __DATE__ " " __TIME__
-#endif
-
-
/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
+ * Version information
*/
-const char __nss_ssl_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
- " " _DATE_AND_TIME " $";
-const char __nss_ssl_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
- " " _DATE_AND_TIME;
+const char __nss_ssl_version[] = "Version: NSS " NSS_VERSION _DEBUG_STRING;
diff --git a/chromium/net/tools/balsa/balsa_frame.cc b/chromium/net/tools/balsa/balsa_frame.cc
index cbd11baeab0..8505ac16a0c 100644
--- a/chromium/net/tools/balsa/balsa_frame.cc
+++ b/chromium/net/tools/balsa/balsa_frame.cc
@@ -405,7 +405,7 @@ bool ParseHTTPFirstLine(const char* begin,
return false;
}
size_t status_code_x_10 = headers->parsed_response_code_ * 10;
- uint8 c = *parsed_response_code_current - '0';
+ uint8_t c = *parsed_response_code_current - '0';
if ((headers->parsed_response_code_ > kMaxDiv10) ||
(std::numeric_limits<size_t>::max() - status_code_x_10) < c) {
// overflow.
diff --git a/chromium/net/tools/balsa/balsa_frame.h b/chromium/net/tools/balsa/balsa_frame.h
index 27f27ea53d2..97025ddba44 100644
--- a/chromium/net/tools/balsa/balsa_frame.h
+++ b/chromium/net/tools/balsa/balsa_frame.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_BALSA_BALSA_FRAME_H_
#define NET_TOOLS_BALSA_BALSA_FRAME_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <utility>
#include <vector>
@@ -34,16 +37,10 @@ class BalsaFrame {
// TODO(fenix): get rid of the 'kValidTerm*' stuff by using the 'since last
// index' strategy. Note that this implies getting rid of the HeaderFramed()
- static const uint32 kValidTerm1 = '\n' << 16 |
- '\r' << 8 |
- '\n';
- static const uint32 kValidTerm1Mask = 0xFF << 16 |
- 0xFF << 8 |
- 0xFF;
- static const uint32 kValidTerm2 = '\n' << 8 |
- '\n';
- static const uint32 kValidTerm2Mask = 0xFF << 8 |
- 0xFF;
+ static const uint32_t kValidTerm1 = '\n' << 16 | '\r' << 8 | '\n';
+ static const uint32_t kValidTerm1Mask = 0xFF << 16 | 0xFF << 8 | 0xFF;
+ static const uint32_t kValidTerm2 = '\n' << 8 | '\n';
+ static const uint32_t kValidTerm2Mask = 0xFF << 8 | 0xFF;
BalsaFrame();
~BalsaFrame();
@@ -245,7 +242,7 @@ class BalsaFrame {
const char* last_slash_n_loc_;
const char* last_recorded_slash_n_loc_;
size_t last_slash_n_idx_;
- uint32 term_chars_;
+ uint32_t term_chars_;
BalsaFrameEnums::ParseState parse_state_;
BalsaFrameEnums::ErrorCode last_error_;
diff --git a/chromium/net/tools/balsa/balsa_headers.h b/chromium/net/tools/balsa/balsa_headers.h
index 3fc01c4c157..a67e7435133 100644
--- a/chromium/net/tools/balsa/balsa_headers.h
+++ b/chromium/net/tools/balsa/balsa_headers.h
@@ -5,6 +5,8 @@
#ifndef NET_TOOLS_BALSA_BALSA_HEADERS_H_
#define NET_TOOLS_BALSA_BALSA_HEADERS_H_
+#include <stddef.h>
+
#include <algorithm>
#include <iosfwd>
#include <iterator>
diff --git a/chromium/net/tools/balsa/noop_balsa_visitor.h b/chromium/net/tools/balsa/noop_balsa_visitor.h
index 89e97194664..0e0c04acb00 100644
--- a/chromium/net/tools/balsa/noop_balsa_visitor.h
+++ b/chromium/net/tools/balsa/noop_balsa_visitor.h
@@ -9,6 +9,9 @@
#ifndef NET_TOOLS_BALSA_NOOP_BALSA_VISITOR_H_
#define NET_TOOLS_BALSA_NOOP_BALSA_VISITOR_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/tools/balsa/balsa_visitor_interface.h"
namespace net {
diff --git a/chromium/net/tools/balsa/simple_buffer.h b/chromium/net/tools/balsa/simple_buffer.h
index d914ec58074..7cc1e16ad3b 100644
--- a/chromium/net/tools/balsa/simple_buffer.h
+++ b/chromium/net/tools/balsa/simple_buffer.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/tools/balsa/buffer_interface.h"
namespace net {
diff --git a/chromium/net/tools/balsa/string_piece_utils.h b/chromium/net/tools/balsa/string_piece_utils.h
index 6d8967a0142..ccc9d52729f 100644
--- a/chromium/net/tools/balsa/string_piece_utils.h
+++ b/chromium/net/tools/balsa/string_piece_utils.h
@@ -5,6 +5,8 @@
#ifndef NET_TOOLS_BALSA_STRING_PIECE_UTILS_H_
#define NET_TOOLS_BALSA_STRING_PIECE_UTILS_H_
+#include <stddef.h>
+
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
diff --git a/chromium/net/tools/tld_cleanup/PRESUBMIT.py b/chromium/net/tools/dafsa/PRESUBMIT.py
index 8391e0e61a1..253fcbbf248 100644
--- a/chromium/net/tools/tld_cleanup/PRESUBMIT.py
+++ b/chromium/net/tools/dafsa/PRESUBMIT.py
@@ -3,13 +3,13 @@
# found in the LICENSE file.
-"""Chromium presubmit script for src/net/tools/tld_cleanup."""
+"""Chromium presubmit script for src/net/tools/dafsa."""
def _RunMakeDafsaTests(input_api, output_api):
"""Runs unittest for make_dafsa if any related file has been modified."""
- files = ('net/tools/tld_cleanup/make_dafsa.py',
- 'net/tools/tld_cleanup/make_dafsa_unittest.py')
+ files = ('net/tools/dafsa/make_dafsa.py',
+ 'net/tools/dafsa/make_dafsa_unittest.py')
if not any(f in input_api.LocalPaths() for f in files):
return []
test_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
diff --git a/chromium/net/tools/tld_cleanup/make_dafsa.py b/chromium/net/tools/dafsa/make_dafsa.py
index 78358effa84..78358effa84 100755
--- a/chromium/net/tools/tld_cleanup/make_dafsa.py
+++ b/chromium/net/tools/dafsa/make_dafsa.py
diff --git a/chromium/net/tools/tld_cleanup/make_dafsa_unittest.py b/chromium/net/tools/dafsa/make_dafsa_unittest.py
index 5ff92e62292..5ff92e62292 100755
--- a/chromium/net/tools/tld_cleanup/make_dafsa_unittest.py
+++ b/chromium/net/tools/dafsa/make_dafsa_unittest.py
diff --git a/chromium/net/tools/disk_cache_memory_test/disk_cache_memory_test.cc b/chromium/net/tools/disk_cache_memory_test/disk_cache_memory_test.cc
index cf1864225a0..bcf5412fa74 100644
--- a/chromium/net/tools/disk_cache_memory_test/disk_cache_memory_test.cc
+++ b/chromium/net/tools/disk_cache_memory_test/disk_cache_memory_test.cc
@@ -15,7 +15,6 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -105,7 +104,7 @@ scoped_ptr<Backend> CreateAndInitBackend(const CacheSpec& spec) {
if (!succeeded) {
LOG(ERROR) << "Could not initialize backend in "
<< spec.path.LossyDisplayName();
- return result.Pass();
+ return result;
}
// For the simple cache, the index may not be initialized yet.
if (spec.backend_type == net::CACHE_BACKEND_SIMPLE) {
@@ -125,12 +124,12 @@ scoped_ptr<Backend> CreateAndInitBackend(const CacheSpec& spec) {
if (!succeeded) {
LOG(ERROR) << "Could not initialize Simple Cache in "
<< spec.path.LossyDisplayName();
- return result.Pass();
+ return result;
}
}
DCHECK(backend);
result.swap(backend);
- return result.Pass();
+ return result;
}
// Parses range lines from /proc/<PID>/smaps, e.g. (anonymous read write):
@@ -162,7 +161,7 @@ bool ParseRangeLine(const std::string& line,
// only if parsing succeeded.
bool ParseRangeProperty(const std::string& line,
std::vector<std::string>* tokens,
- uint64* size,
+ uint64_t* size,
bool* is_private_dirty) {
*tokens = base::SplitString(line, base::kWhitespaceASCII,
base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
@@ -183,7 +182,7 @@ bool ParseRangeProperty(const std::string& line,
return true;
}
const std::string& size_str = (*tokens)[1];
- uint64 map_size = 0;
+ uint64_t map_size = 0;
if (!base::StringToUint64(size_str, &map_size))
return true;
*is_private_dirty = true;
@@ -191,7 +190,7 @@ bool ParseRangeProperty(const std::string& line,
return true;
}
-uint64 GetMemoryConsumption() {
+uint64_t GetMemoryConsumption() {
std::ifstream maps_file(
base::StringPrintf("/proc/%d/smaps", getpid()).c_str());
if (!maps_file.good()) {
@@ -200,7 +199,7 @@ uint64 GetMemoryConsumption() {
}
std::string line;
std::vector<std::string> tokens;
- uint64 total_size = 0;
+ uint64_t total_size = 0;
if (!std::getline(maps_file, line) || line.empty())
return total_size;
while (true) {
@@ -211,7 +210,7 @@ uint64 GetMemoryConsumption() {
if (!std::getline(maps_file, line) || line.empty())
return total_size;
bool is_private_dirty = false;
- uint64 size = 0;
+ uint64_t size = 0;
while (ParseRangeProperty(line, &tokens, &size, &is_private_dirty)) {
if (is_anonymous_read_write && is_private_dirty) {
total_size += size;
@@ -224,18 +223,17 @@ uint64 GetMemoryConsumption() {
return total_size;
}
-bool CacheMemTest(const ScopedVector<CacheSpec>& specs) {
- ScopedVector<Backend> backends;
- ScopedVector<CacheSpec>::const_iterator it;
- for (it = specs.begin(); it != specs.end(); ++it) {
- scoped_ptr<Backend> backend = CreateAndInitBackend(**it);
+bool CacheMemTest(const std::vector<scoped_ptr<CacheSpec>>& specs) {
+ std::vector<scoped_ptr<Backend>> backends;
+ for (const auto& it : specs) {
+ scoped_ptr<Backend> backend = CreateAndInitBackend(*it);
if (!backend)
return false;
- std::cout << "Number of entries in " << (*it)->path.LossyDisplayName()
- << " : " << backend->GetEntryCount() << std::endl;
- backends.push_back(backend.release());
+ std::cout << "Number of entries in " << it->path.LossyDisplayName() << " : "
+ << backend->GetEntryCount() << std::endl;
+ backends.push_back(std::move(backend));
}
- const uint64 memory_consumption = GetMemoryConsumption();
+ const uint64_t memory_consumption = GetMemoryConsumption();
std::cout << "Private dirty memory: " << memory_consumption << " kB"
<< std::endl;
return true;
@@ -254,13 +252,13 @@ void PrintUsage(std::ostream* stream) {
}
bool ParseAndStoreSpec(const std::string& spec_str,
- ScopedVector<CacheSpec>* specs) {
+ std::vector<scoped_ptr<CacheSpec>>* specs) {
scoped_ptr<CacheSpec> spec = CacheSpec::Parse(spec_str);
if (!spec) {
PrintUsage(&std::cerr);
return false;
}
- specs->push_back(spec.release());
+ specs->push_back(std::move(spec));
return true;
}
@@ -282,7 +280,7 @@ bool Main(int argc, char** argv) {
PrintUsage(&std::cerr);
return false;
}
- ScopedVector<CacheSpec> specs;
+ std::vector<scoped_ptr<CacheSpec>> specs;
const std::string spec_str_1 = command_line.GetSwitchValueASCII("spec-1");
if (!ParseAndStoreSpec(spec_str_1, &specs))
return false;
diff --git a/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc b/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc
index 549d11c2445..2a2c88e9e58 100644
--- a/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc
+++ b/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
#include <algorithm>
+#include <limits>
#include <sstream>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
@@ -15,12 +17,12 @@
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/address_list.h"
-#include "net/base/dns_util.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
+#include "net/dns/dns_util.h"
namespace {
@@ -39,15 +41,17 @@ void CrashNullPointerDereference(void) {
}
bool FitsUint8(int num) {
- return (num >= 0) && (num <= kuint8max);
+ return (num >= 0) && (num <= std::numeric_limits<uint8_t>::max());
}
bool FitsUint16(int num) {
- return (num >= 0) && (num <= kuint16max);
+ return (num >= 0) && (num <= std::numeric_limits<uint16_t>::max());
}
bool ReadTestCase(const char* filename,
- uint16* id, std::string* qname, uint16* qtype,
+ uint16_t* id,
+ std::string* qname,
+ uint16_t* qtype,
std::vector<char>* resp_buf,
bool* crash_test) {
base::FilePath filepath = base::FilePath::FromUTF8Unsafe(filename);
@@ -85,7 +89,7 @@ bool ReadTestCase(const char* filename,
LOG(ERROR) << filename << ": id is out of range.";
return false;
}
- *id = static_cast<uint16>(id_int);
+ *id = static_cast<uint16_t>(id_int);
if (!dict->GetStringASCII("qname", qname)) {
LOG(ERROR) << filename << ": qname is missing or not a string.";
@@ -101,7 +105,7 @@ bool ReadTestCase(const char* filename,
LOG(ERROR) << filename << ": qtype is out of range.";
return false;
}
- *qtype = static_cast<uint16>(qtype_int);
+ *qtype = static_cast<uint16_t>(qtype_int);
base::ListValue* resp_list;
if (!dict->GetList("response", &resp_list)) {
@@ -134,7 +138,9 @@ bool ReadTestCase(const char* filename,
return true;
}
-void RunTestCase(uint16 id, std::string& qname, uint16 qtype,
+void RunTestCase(uint16_t id,
+ std::string& qname,
+ uint16_t qtype,
std::vector<char>& resp_buf) {
net::DnsQuery query(id, qname, qtype);
net::DnsResponse response;
@@ -165,9 +171,9 @@ void RunTestCase(uint16 id, std::string& qname, uint16 qtype,
}
bool ReadAndRunTestCase(const char* filename) {
- uint16 id = 0;
+ uint16_t id = 0;
std::string qname;
- uint16 qtype = 0;
+ uint16_t qtype = 0;
std::vector<char> resp_buf;
bool crash_test = false;
diff --git a/chromium/net/tools/dump_cache/dump_files.cc b/chromium/net/tools/dump_cache/dump_files.cc
index 8c7434e971f..691c08540a6 100644
--- a/chromium/net/tools/dump_cache/dump_files.cc
+++ b/chromium/net/tools/dump_cache/dump_files.cc
@@ -18,6 +18,7 @@
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@@ -73,13 +74,13 @@ void DumpStats(const base::FilePath& path, disk_cache::CacheAddr addr) {
if (!file)
return;
- size_t length = (2 + disk_cache::Stats::kDataSizesLength) * sizeof(int32) +
- disk_cache::Stats::MAX_COUNTER * sizeof(int64);
+ size_t length = (2 + disk_cache::Stats::kDataSizesLength) * sizeof(int32_t) +
+ disk_cache::Stats::MAX_COUNTER * sizeof(int64_t);
size_t offset = address.start_block() * address.BlockSize() +
disk_cache::kBlockHeaderSize;
- scoped_ptr<int32[]> buffer(new int32[length]);
+ scoped_ptr<int32_t[]> buffer(new int32_t[length]);
if (!file->Read(buffer.get(), length, offset))
return;
@@ -88,8 +89,8 @@ void DumpStats(const base::FilePath& path, disk_cache::CacheAddr addr) {
for (int i = 0; i < disk_cache::Stats::kDataSizesLength; i++)
printf("Size(%d): %d\n", i, buffer[i + 2]);
- int64* counters = reinterpret_cast<int64*>(
- buffer.get() + 2 + disk_cache::Stats::kDataSizesLength);
+ int64_t* counters = reinterpret_cast<int64_t*>(
+ buffer.get() + 2 + disk_cache::Stats::kDataSizesLength);
for (int i = 0; i < disk_cache::Stats::MAX_COUNTER; i++)
printf("Count(%d): %" PRId64 "\n", i, *counters++);
printf("-------------------------\n\n");
@@ -306,7 +307,7 @@ bool CacheDumper::HexDump(disk_cache::CacheAddr addr, std::string* out) {
return true;
}
-std::string ToLocalTime(int64 time_us) {
+std::string ToLocalTime(int64_t time_us) {
base::Time time = base::Time::FromInternalValue(time_us);
base::Time::Exploded e;
time.LocalExplode(&e);
@@ -490,7 +491,7 @@ int DumpLists(const base::FilePath& input_path) {
const int kMaxLength = 1 * 1000 * 1000;
for (int i = 0; i < 5; i++) {
- int32 size = header.lru.sizes[i];
+ int32_t size = header.lru.sizes[i];
if (size < 0 || size > kMaxLength) {
printf("Wrong size %d\n", size);
size = kMaxLength;
diff --git a/chromium/net/tools/epoll_server/epoll_server.cc b/chromium/net/tools/epoll_server/epoll_server.cc
index 7b60ce2ae0d..7aec1138b41 100644
--- a/chromium/net/tools/epoll_server/epoll_server.cc
+++ b/chromium/net/tools/epoll_server/epoll_server.cc
@@ -9,9 +9,10 @@
#include <errno.h> // for errno and strerror_r
#include <algorithm>
#include <utility>
-#include <vector>
+#include "base/auto_reset.h"
#include "base/logging.h"
+#include "base/stl_util.h"
#include "base/time/time.h"
// Design notes: An efficient implementation of ready list has the following
@@ -221,12 +222,8 @@ void EpollServer::RegisterFD(int fd, CB* cb, int event_mask) {
cb->OnRegistration(this, fd, event_mask);
}
-int EpollServer::GetFlags(int fd) {
- return fcntl(fd, F_GETFL, 0);
-}
-
void EpollServer::SetNonblocking(int fd) {
- int flags = GetFlags(fd);
+ int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
int saved_errno = errno;
char buf[kErrorBufferSize];
@@ -236,7 +233,7 @@ void EpollServer::SetNonblocking(int fd) {
}
if (!(flags & O_NONBLOCK)) {
int saved_flags = flags;
- flags = SetFlags(fd, flags | O_NONBLOCK);
+ flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if (flags == -1) {
// bad.
int saved_errno = errno;
@@ -338,20 +335,6 @@ void EpollServer::HandleEvent(int fd, int event_mask) {
AddToReadyList(cb_and_mask);
}
-class TrueFalseGuard {
- public:
- explicit TrueFalseGuard(bool* guarded_bool) : guarded_bool_(guarded_bool) {
- DCHECK(guarded_bool_ != NULL);
- DCHECK(*guarded_bool_ == false);
- *guarded_bool_ = true;
- }
- ~TrueFalseGuard() {
- *guarded_bool_ = false;
- }
- private:
- bool* guarded_bool_;
-};
-
void EpollServer::WaitForEventsAndExecuteCallbacks() {
if (in_wait_for_events_and_execute_callbacks_) {
LOG(DFATAL) <<
@@ -362,7 +345,8 @@ void EpollServer::WaitForEventsAndExecuteCallbacks() {
// we never see it.
return; // COV_NF_LINE
}
- TrueFalseGuard recursion_guard(&in_wait_for_events_and_execute_callbacks_);
+ base::AutoReset<bool> recursion_guard(
+ &in_wait_for_events_and_execute_callbacks_, true);
if (alarm_map_.empty()) {
// no alarms, this is business as usual.
WaitForEventsAndCallHandleEvents(timeout_in_us_,
@@ -377,23 +361,23 @@ void EpollServer::WaitForEventsAndExecuteCallbacks() {
// long-running alarms might install other long-running
// alarms, etc. By storing it here now, we ensure that
// a more reasonable amount of work is done here.
- int64 now_in_us = NowInUsec();
+ int64_t now_in_us = NowInUsec();
// Get the first timeout from the alarm_map where it is
// stored in absolute time.
- int64 next_alarm_time_in_us = alarm_map_.begin()->first;
+ int64_t next_alarm_time_in_us = alarm_map_.begin()->first;
VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us
<< " now = " << now_in_us
<< " timeout_in_us = " << timeout_in_us_;
- int64 wait_time_in_us;
- int64 alarm_timeout_in_us = next_alarm_time_in_us - now_in_us;
+ int64_t wait_time_in_us;
+ int64_t alarm_timeout_in_us = next_alarm_time_in_us - now_in_us;
// If the next alarm is sooner than the default timeout, or if there is no
// timeout (timeout_in_us_ == -1), wake up when the alarm should fire.
// Otherwise use the default timeout.
if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) {
- wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64>(0));
+ wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64_t>(0));
} else {
wait_time_in_us = timeout_in_us_;
}
@@ -456,9 +440,9 @@ void EpollServer::VerifyReadyList() const {
CHECK_EQ(ready_list_size_, count) << "Ready list size does not match count";
}
-void EpollServer::RegisterAlarm(int64 timeout_time_in_us, AlarmCB* ac) {
+void EpollServer::RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac) {
CHECK(ac);
- if (ContainsAlarm(ac)) {
+ if (ContainsKey(all_alarms_, ac)) {
LOG(FATAL) << "Alarm already exists " << ac;
}
VLOG(4) << "RegisteringAlarm at : " << timeout_time_in_us;
@@ -492,11 +476,11 @@ void EpollServer::Wake() {
DCHECK_EQ(rv, 1);
}
-int64 EpollServer::NowInUsec() const {
- return base::Time::Now().ToInternalValue();
+int64_t EpollServer::NowInUsec() const {
+ return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
}
-int64 EpollServer::ApproximateNowInUsec() const {
+int64_t EpollServer::ApproximateNowInUsec() const {
if (recorded_now_in_us_ != 0) {
return recorded_now_in_us_;
}
@@ -628,7 +612,7 @@ void EpollServer::ModifyFD(int fd, int remove_event, int add_event) {
}
}
-void EpollServer::WaitForEventsAndCallHandleEvents(int64 timeout_in_us,
+void EpollServer::WaitForEventsAndCallHandleEvents(int64_t timeout_in_us,
struct epoll_event events[],
int events_size) {
if (timeout_in_us == 0 || ready_list_.lh_first != NULL) {
@@ -713,7 +697,7 @@ void EpollServer::CallReadyListCallbacks() {
// UnRegister call will now simply set the cb to NULL instead of
// invalidating the cb_and_mask object (by deleting the object in the
// map to which cb_and_mask refers)
- TrueFalseGuard in_use_guard(&(cb_and_mask->in_use));
+ base::AutoReset<bool> in_use_guard(&(cb_and_mask->in_use), true);
cb_and_mask->cb->OnEvent(cb_and_mask->fd, &event);
}
@@ -732,7 +716,7 @@ void EpollServer::CallReadyListCallbacks() {
}
void EpollServer::CallAndReregisterAlarmEvents() {
- int64 now_in_us = recorded_now_in_us_;
+ int64_t now_in_us = recorded_now_in_us_;
DCHECK_NE(0, recorded_now_in_us_);
TimeToAlarmCBMap::iterator erase_it;
@@ -755,7 +739,7 @@ void EpollServer::CallAndReregisterAlarmEvents() {
continue;
}
all_alarms_.erase(cb);
- const int64 new_timeout_time_in_us = cb->OnAlarm();
+ const int64_t new_timeout_time_in_us = cb->OnAlarm();
erase_it = i;
++i;
@@ -786,7 +770,7 @@ EpollAlarm::~EpollAlarm() {
UnregisterIfRegistered();
}
-int64 EpollAlarm::OnAlarm() {
+int64_t EpollAlarm::OnAlarm() {
registered_ = false;
return 0;
}
diff --git a/chromium/net/tools/epoll_server/epoll_server.h b/chromium/net/tools/epoll_server/epoll_server.h
index 139ae270b54..460db3d3a4a 100644
--- a/chromium/net/tools/epoll_server/epoll_server.h
+++ b/chromium/net/tools/epoll_server/epoll_server.h
@@ -6,11 +6,12 @@
#define NET_TOOLS_EPOLL_SERVER_EPOLL_SERVER_H_
#include <fcntl.h>
+#include <stddef.h>
+#include <stdint.h>
#include <sys/queue.h>
+
#include <map>
-#include <set>
#include <string>
-#include <utility>
#include <vector>
// #define EPOLL_SERVER_EVENT_TRACING 1
@@ -32,9 +33,9 @@
#include "base/logging.h"
#endif
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include <sys/epoll.h>
@@ -122,7 +123,7 @@ class EpollServer {
typedef EpollAlarmCallbackInterface AlarmCB;
typedef EpollCallbackInterface CB;
- typedef std::multimap<int64, AlarmCB*> TimeToAlarmCBMap;
+ typedef std::multimap<int64_t, AlarmCB*> TimeToAlarmCBMap;
typedef TimeToAlarmCBMap::iterator AlarmRegToken;
// Summary:
@@ -361,7 +362,7 @@ class EpollServer {
// Args:
// timeout_time_in_us - the absolute time at which the alarm should go off
// ac - the alarm which will be called.
- virtual void RegisterAlarm(int64 timeout_time_in_us, AlarmCB* ac);
+ virtual void RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac);
// Summary:
// Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() +
@@ -383,7 +384,7 @@ class EpollServer {
// delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at
// which point the alarm should go off.
// ac - the alarm which will be called.
- void RegisterAlarmApproximateDelta(int64 delta_in_us, AlarmCB* ac) {
+ void RegisterAlarmApproximateDelta(int64_t delta_in_us, AlarmCB* ac) {
RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac);
}
@@ -416,7 +417,7 @@ class EpollServer {
// that would ensue)
// Returns:
// the current time as number of microseconds since the Unix epoch.
- virtual int64 NowInUsec() const;
+ virtual int64_t NowInUsec() const;
// Summary:
// Since calling NowInUsec() many thousands of times per
@@ -439,7 +440,7 @@ class EpollServer {
// Returns:
// the "approximate" current time as number of microseconds since the Unix
// epoch.
- virtual int64 ApproximateNowInUsec() const;
+ virtual int64_t ApproximateNowInUsec() const;
static std::string EventMaskToString(int event_mask);
@@ -461,7 +462,7 @@ class EpollServer {
// Args:
// timeout_in_us - value specified depending on behaviour desired.
// See above.
- void set_timeout_in_us(int64 timeout_in_us) {
+ void set_timeout_in_us(int64_t timeout_in_us) {
timeout_in_us_ = timeout_in_us;
}
@@ -475,10 +476,6 @@ class EpollServer {
// Returns true when the EpollServer() is being destroyed.
bool in_shutdown() const { return in_shutdown_; }
- bool ContainsAlarm(EpollAlarmCallbackInterface* alarm) const {
- return all_alarms_.find(alarm) != all_alarms_.end();
- }
-
// Summary:
// A function for implementing the ready list. It invokes OnEvent for each
// of the fd in the ready list, and takes care of adding them back to the
@@ -487,11 +484,6 @@ class EpollServer {
void CallReadyListCallbacks();
protected:
- virtual int GetFlags(int fd);
- inline int SetFlags(int fd, int flags) {
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
- }
-
virtual void SetNonblocking(int fd);
// This exists here so that we can override this function in unittests
@@ -633,12 +625,10 @@ class EpollServer {
// another callback (A) has closed a file-descriptor N, and
// the callback (B) has a newly opened file-descriptor, which
// also happens to be N.
- virtual void WaitForEventsAndCallHandleEvents(int64 timeout_in_us,
+ virtual void WaitForEventsAndCallHandleEvents(int64_t timeout_in_us,
struct epoll_event events[],
int events_size);
-
-
// Summary:
// An internal function for implementing the ready list. It adds a fd's
// CBAndEventMask to the ready list. If the fd is already on the ready
@@ -684,14 +674,14 @@ class EpollServer {
// If this is positive, wait that many microseconds.
// If this is negative, wait forever, or for the first event that occurs
// If this is zero, never wait for an event.
- int64 timeout_in_us_;
+ int64_t timeout_in_us_;
// This is nonzero only after the invocation of epoll_wait_impl within
// WaitForEventsAndCallHandleEvents and before the function
// WaitForEventsAndExecuteCallbacks returns. At all other times, this is
// zero. This enables us to have relatively accurate time returned from the
// ApproximateNowInUs() function. See that function for more details.
- int64 recorded_now_in_us_;
+ int64_t recorded_now_in_us_;
// This is used to implement CallAndReregisterAlarmEvents. This stores
// all alarms that were reregistered because OnAlarm() returned a
@@ -728,7 +718,7 @@ class EpollServer {
// Note that the definition of an 'event' is a bit 'hazy',
// as it includes the 'Unregistration' event, and perhaps
// others.
- void set_record_threshold(int64 new_threshold) {
+ void set_record_threshold(int64_t new_threshold) {
record_threshold_ = new_threshold;
}
@@ -927,8 +917,8 @@ class EpollServer {
std::vector<Events> unregistered_fds_;
typedef base::hash_map<int, Events> EventCountsMap;
EventCountsMap event_counts_;
- int64 num_records_;
- int64 record_threshold_;
+ int64_t num_records_;
+ int64_t record_threshold_;
};
void ClearEventRecords() {
@@ -979,7 +969,7 @@ class EpollAlarmCallbackInterface {
// Returns:
// the unix time (in microseconds) at which this alarm should be signaled
// again, or 0 if the alarm should be removed.
- virtual int64 OnAlarm() = 0;
+ virtual int64_t OnAlarm() = 0;
// Summary:
// Called when the an alarm is registered. Invalidates an AlarmRegToken.
@@ -1023,7 +1013,7 @@ class EpollAlarm : public EpollAlarmCallbackInterface {
// Marks the alarm as unregistered and returns 0. The return value may be
// safely ignored by subclasses.
- int64 OnAlarm() override;
+ int64_t OnAlarm() override;
// Marks the alarm as registered, and stores the token.
void OnRegistration(const EpollServer::AlarmRegToken& token,
diff --git a/chromium/net/tools/flip_server/acceptor_thread.cc b/chromium/net/tools/flip_server/acceptor_thread.cc
index 2b65e5d43af..4e7866344c2 100644
--- a/chromium/net/tools/flip_server/acceptor_thread.cc
+++ b/chromium/net/tools/flip_server/acceptor_thread.cc
@@ -7,6 +7,7 @@
#include <errno.h>
#include <netinet/in.h>
#include <netinet/tcp.h> // For TCP_NODELAY
+#include <string.h> // For strerror
#include <sys/socket.h>
#include <sys/types.h>
diff --git a/chromium/net/tools/flip_server/create_listener.cc b/chromium/net/tools/flip_server/create_listener.cc
index 1fc5a7e8c79..3e976036cb3 100644
--- a/chromium/net/tools/flip_server/create_listener.cc
+++ b/chromium/net/tools/flip_server/create_listener.cc
@@ -11,6 +11,7 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
diff --git a/chromium/net/tools/flip_server/flip_in_mem_edsm_server.cc b/chromium/net/tools/flip_server/flip_in_mem_edsm_server.cc
index 1e6a8cef361..8473560534d 100644
--- a/chromium/net/tools/flip_server/flip_in_mem_edsm_server.cc
+++ b/chromium/net/tools/flip_server/flip_in_mem_edsm_server.cc
@@ -5,6 +5,7 @@
#include <errno.h>
#include <signal.h>
#include <stdio.h>
+#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
@@ -32,10 +33,10 @@ bool FLAGS_disable_nagle = true;
// alarm goes off when the accept_using_alarm flag is set to true.
// If set to 0, accept() will be performed until the accept queue
// is completely drained and the accept() call returns an error);
-int32 FLAGS_accepts_per_wake = 0;
+int32_t FLAGS_accepts_per_wake = 0;
// The size of the TCP accept backlog);
-int32 FLAGS_accept_backlog_size = 1024;
+int32_t FLAGS_accept_backlog_size = 1024;
// If set to false a single socket will be used. If set to true
// then a new socket will be created for each accept thread.
diff --git a/chromium/net/tools/flip_server/flip_test_utils.h b/chromium/net/tools/flip_server/flip_test_utils.h
index 0a61a60f771..a4eab1bb7c0 100644
--- a/chromium/net/tools/flip_server/flip_test_utils.h
+++ b/chromium/net/tools/flip_server/flip_test_utils.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_FLIP_SERVER_FLIP_TEST_UTILS_H_
#define NET_TOOLS_FLIP_SERVER_FLIP_TEST_UTILS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "net/tools/flip_server/sm_interface.h"
@@ -18,7 +21,7 @@ class MockSMInterface : public SMInterface {
MockSMInterface();
virtual ~MockSMInterface();
- MOCK_METHOD2(InitSMInterface, void(SMInterface*, int32));
+ MOCK_METHOD2(InitSMInterface, void(SMInterface*, int32_t));
MOCK_METHOD8(InitSMConnection,
void(SMConnectionPoolInterface*,
SMInterface*,
@@ -30,21 +33,22 @@ class MockSMInterface : public SMInterface {
bool));
MOCK_METHOD2(ProcessReadInput, size_t(const char*, size_t));
MOCK_METHOD2(ProcessWriteInput, size_t(const char*, size_t));
- MOCK_METHOD1(SetStreamID, void(uint32 stream_id));
+ MOCK_METHOD1(SetStreamID, void(uint32_t stream_id));
MOCK_CONST_METHOD0(MessageFullyRead, bool());
MOCK_CONST_METHOD0(Error, bool());
MOCK_CONST_METHOD0(ErrorAsString, const char*());
MOCK_METHOD0(Reset, void());
- MOCK_METHOD1(ResetForNewInterface, void(int32 server_idx));
+ MOCK_METHOD1(ResetForNewInterface, void(int32_t server_idx));
MOCK_METHOD0(ResetForNewConnection, void());
MOCK_METHOD0(Cleanup, void());
MOCK_METHOD0(PostAcceptHook, int());
- MOCK_METHOD3(NewStream, void(uint32, uint32, const std::string&));
- MOCK_METHOD1(SendEOF, void(uint32 stream_id));
- MOCK_METHOD1(SendErrorNotFound, void(uint32 stream_id));
- MOCK_METHOD2(SendSynStream, size_t(uint32, const BalsaHeaders&));
- MOCK_METHOD2(SendSynReply, size_t(uint32, const BalsaHeaders&));
- MOCK_METHOD5(SendDataFrame, void(uint32, const char*, int64, uint32, bool));
+ MOCK_METHOD3(NewStream, void(uint32_t, uint32_t, const std::string&));
+ MOCK_METHOD1(SendEOF, void(uint32_t stream_id));
+ MOCK_METHOD1(SendErrorNotFound, void(uint32_t stream_id));
+ MOCK_METHOD2(SendSynStream, size_t(uint32_t, const BalsaHeaders&));
+ MOCK_METHOD2(SendSynReply, size_t(uint32_t, const BalsaHeaders&));
+ MOCK_METHOD5(SendDataFrame,
+ void(uint32_t, const char*, int64_t, uint32_t, bool));
MOCK_METHOD0(GetOutput, void());
MOCK_METHOD0(set_is_request, void());
};
diff --git a/chromium/net/tools/flip_server/http_interface.cc b/chromium/net/tools/flip_server/http_interface.cc
index 576e912ba7c..8d5e1738788 100644
--- a/chromium/net/tools/flip_server/http_interface.cc
+++ b/chromium/net/tools/flip_server/http_interface.cc
@@ -32,7 +32,6 @@ HttpSM::HttpSM(SMConnection* connection,
}
HttpSM::~HttpSM() {
Reset();
- delete http_framer_;
}
void HttpSM::ProcessBodyData(const char* input, size_t size) {
@@ -87,7 +86,8 @@ void HttpSM::AddToOutputOrder(const MemCacheIter& mci) {
output_ordering_.AddToOutputOrder(mci);
}
-void HttpSM::InitSMInterface(SMInterface* sm_spdy_interface, int32 server_idx) {
+void HttpSM::InitSMInterface(SMInterface* sm_spdy_interface,
+ int32_t server_idx) {
sm_spdy_interface_ = sm_spdy_interface;
server_idx_ = server_idx;
}
@@ -135,7 +135,9 @@ bool HttpSM::MessageFullyRead() const {
return http_framer_->MessageFullyRead();
}
-void HttpSM::SetStreamID(uint32 stream_id) { stream_id_ = stream_id; }
+void HttpSM::SetStreamID(uint32_t stream_id) {
+ stream_id_ = stream_id;
+}
bool HttpSM::Error() const { return http_framer_->Error(); }
@@ -177,8 +179,8 @@ void HttpSM::Cleanup() {
int HttpSM::PostAcceptHook() { return 1; }
-void HttpSM::NewStream(uint32 stream_id,
- uint32 priority,
+void HttpSM::NewStream(uint32_t stream_id,
+ uint32_t priority,
const std::string& filename) {
MemCacheIter mci;
mci.stream_id = stream_id;
@@ -192,34 +194,34 @@ void HttpSM::NewStream(uint32 stream_id,
}
}
-void HttpSM::SendEOF(uint32 stream_id) {
+void HttpSM::SendEOF(uint32_t stream_id) {
SendEOFImpl(stream_id);
if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
sm_spdy_interface_->ResetForNewInterface(server_idx_);
}
}
-void HttpSM::SendErrorNotFound(uint32 stream_id) {
+void HttpSM::SendErrorNotFound(uint32_t stream_id) {
SendErrorNotFoundImpl(stream_id);
}
-size_t HttpSM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) {
+size_t HttpSM::SendSynStream(uint32_t stream_id, const BalsaHeaders& headers) {
return 0;
}
-size_t HttpSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) {
+size_t HttpSM::SendSynReply(uint32_t stream_id, const BalsaHeaders& headers) {
return SendSynReplyImpl(stream_id, headers);
}
-void HttpSM::SendDataFrame(uint32 stream_id,
+void HttpSM::SendDataFrame(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) {
SendDataFrameImpl(stream_id, data, len, flags, compress);
}
-void HttpSM::SendEOFImpl(uint32 stream_id) {
+void HttpSM::SendEOFImpl(uint32_t stream_id) {
DataFrame* df = new DataFrame;
df->data = "0\r\n\r\n";
df->size = 5;
@@ -230,7 +232,7 @@ void HttpSM::SendEOFImpl(uint32 stream_id) {
}
}
-void HttpSM::SendErrorNotFoundImpl(uint32 stream_id) {
+void HttpSM::SendErrorNotFoundImpl(uint32_t stream_id) {
BalsaHeaders my_headers;
my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found");
my_headers.RemoveAllOfHeader("content-length");
@@ -241,7 +243,8 @@ void HttpSM::SendErrorNotFoundImpl(uint32 stream_id) {
output_ordering_.RemoveStreamId(stream_id);
}
-size_t HttpSM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) {
+size_t HttpSM::SendSynReplyImpl(uint32_t stream_id,
+ const BalsaHeaders& headers) {
SimpleBuffer sb;
headers.WriteHeaderAndEndingToBuffer(&sb);
DataFrame* df = new DataFrame;
@@ -257,7 +260,7 @@ size_t HttpSM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) {
return df_size;
}
-size_t HttpSM::SendSynStreamImpl(uint32 stream_id,
+size_t HttpSM::SendSynStreamImpl(uint32_t stream_id,
const BalsaHeaders& headers) {
SimpleBuffer sb;
headers.WriteHeaderAndEndingToBuffer(&sb);
@@ -274,10 +277,10 @@ size_t HttpSM::SendSynStreamImpl(uint32 stream_id,
return df_size;
}
-void HttpSM::SendDataFrameImpl(uint32 stream_id,
+void HttpSM::SendDataFrameImpl(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) {
char chunk_buf[128];
snprintf(chunk_buf, sizeof(chunk_buf), "%x\r\n", (unsigned int)len);
diff --git a/chromium/net/tools/flip_server/http_interface.h b/chromium/net/tools/flip_server/http_interface.h
index c6dc978b086..73618bc7974 100644
--- a/chromium/net/tools/flip_server/http_interface.h
+++ b/chromium/net/tools/flip_server/http_interface.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_FLIP_SERVER_HTTP_INTERFACE_H_
#define NET_TOOLS_FLIP_SERVER_HTTP_INTERFACE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/compiler_specific.h"
@@ -66,13 +69,13 @@ class HttpSM : public BalsaVisitorInterface, public SMInterface {
public:
void AddToOutputOrder(const MemCacheIter& mci);
- BalsaFrame* spdy_framer() { return http_framer_; }
+ BalsaFrame* spdy_framer() { return http_framer_.get(); }
void set_is_request() override {}
const OutputOrdering& output_ordering() const { return output_ordering_; }
// SMInterface:
void InitSMInterface(SMInterface* sm_spdy_interface,
- int32 server_idx) override;
+ int32_t server_idx) override;
void InitSMConnection(SMConnectionPoolInterface* connection_pool,
SMInterface* sm_interface,
EpollServer* epoll_server,
@@ -84,47 +87,48 @@ class HttpSM : public BalsaVisitorInterface, public SMInterface {
size_t ProcessReadInput(const char* data, size_t len) override;
size_t ProcessWriteInput(const char* data, size_t len) override;
bool MessageFullyRead() const override;
- void SetStreamID(uint32 stream_id) override;
+ void SetStreamID(uint32_t stream_id) override;
bool Error() const override;
const char* ErrorAsString() const override;
void Reset() override;
- void ResetForNewInterface(int32 server_idx) override {}
+ void ResetForNewInterface(int32_t server_idx) override {}
void ResetForNewConnection() override;
void Cleanup() override;
int PostAcceptHook() override;
- void NewStream(uint32 stream_id,
- uint32 priority,
+ void NewStream(uint32_t stream_id,
+ uint32_t priority,
const std::string& filename) override;
- void SendEOF(uint32 stream_id) override;
- void SendErrorNotFound(uint32 stream_id) override;
- size_t SendSynStream(uint32 stream_id, const BalsaHeaders& headers) override;
- size_t SendSynReply(uint32 stream_id, const BalsaHeaders& headers) override;
- void SendDataFrame(uint32 stream_id,
+ void SendEOF(uint32_t stream_id) override;
+ void SendErrorNotFound(uint32_t stream_id) override;
+ size_t SendSynStream(uint32_t stream_id,
+ const BalsaHeaders& headers) override;
+ size_t SendSynReply(uint32_t stream_id, const BalsaHeaders& headers) override;
+ void SendDataFrame(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) override;
private:
- void SendEOFImpl(uint32 stream_id);
- void SendErrorNotFoundImpl(uint32 stream_id);
- void SendOKResponseImpl(uint32 stream_id, const std::string& output);
- size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers);
- size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers);
- void SendDataFrameImpl(uint32 stream_id,
+ void SendEOFImpl(uint32_t stream_id);
+ void SendErrorNotFoundImpl(uint32_t stream_id);
+ void SendOKResponseImpl(uint32_t stream_id, const std::string& output);
+ size_t SendSynReplyImpl(uint32_t stream_id, const BalsaHeaders& headers);
+ size_t SendSynStreamImpl(uint32_t stream_id, const BalsaHeaders& headers);
+ void SendDataFrameImpl(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress);
void EnqueueDataFrame(DataFrame* df);
void GetOutput() override;
private:
- BalsaFrame* http_framer_;
+ scoped_ptr<BalsaFrame> http_framer_;
BalsaHeaders headers_;
- uint32 stream_id_;
- int32 server_idx_;
+ uint32_t stream_id_;
+ int32_t server_idx_;
SMConnection* connection_;
SMInterface* sm_spdy_interface_;
diff --git a/chromium/net/tools/flip_server/http_interface_test.cc b/chromium/net/tools/flip_server/http_interface_test.cc
index 6d07840becf..34b2390b33d 100644
--- a/chromium/net/tools/flip_server/http_interface_test.cc
+++ b/chromium/net/tools/flip_server/http_interface_test.cc
@@ -95,7 +95,7 @@ class FlipHttpSMTest : public ::testing::Test {
STLDeleteElements(connection_->output_list());
}
- bool HasStream(uint32 stream_id) {
+ bool HasStream(uint32_t stream_id) {
return interface_->output_ordering().ExistsInPriorityMaps(stream_id);
}
@@ -131,7 +131,7 @@ TEST_F(FlipHttpSMTest, Construct) {
}
TEST_F(FlipHttpSMTest, AddToOutputOrder) {
- uint32 stream_id = 13;
+ uint32_t stream_id = 13;
MemCacheIter mci;
mci.stream_id = stream_id;
@@ -254,7 +254,7 @@ TEST_F(FlipHttpSMTest, ResetForNewConnection) {
}
TEST_F(FlipHttpSMTest, NewStream) {
- uint32 stream_id = 4;
+ uint32_t stream_id = 4;
{
BalsaHeaders headers;
std::string filename = "foobar";
@@ -270,7 +270,7 @@ TEST_F(FlipHttpSMTest, NewStreamError) {
"HTTP/1.1 404 Not Found\r\n"
"transfer-encoding: chunked\r\n\r\n";
std::string body = "e\r\npage not found\r\n";
- uint32 stream_id = 4;
+ uint32_t stream_id = 4;
ASSERT_FALSE(HasStream(stream_id));
interface_->NewStream(stream_id, 1, "foobar");
@@ -291,7 +291,7 @@ TEST_F(FlipHttpSMTest, SendErrorNotFound) {
"HTTP/1.1 404 Not Found\r\n"
"transfer-encoding: chunked\r\n\r\n";
std::string body = "e\r\npage not found\r\n";
- uint32 stream_id = 13;
+ uint32_t stream_id = 13;
MemCacheIter mci;
mci.stream_id = stream_id;
@@ -416,7 +416,7 @@ TEST_F(FlipHttpSMHttpTest, ProcessHeaders) {
BalsaHeaders headers;
headers.AppendHeader("Host", "example.com");
headers.SetRequestFirstlineFromStringPieces("GET", "/path/file", "HTTP/1.0");
- uint32 stream_id = 133;
+ uint32_t stream_id = 133;
interface_->SetStreamID(stream_id);
ASSERT_FALSE(HasStream(stream_id));
visitor->ProcessHeaders(headers);
diff --git a/chromium/net/tools/flip_server/loadtime_measurement.h b/chromium/net/tools/flip_server/loadtime_measurement.h
deleted file mode 100644
index d1a8e07fdb2..00000000000
--- a/chromium/net/tools/flip_server/loadtime_measurement.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2009 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_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H_
-#define NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H_
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/files/file_util.h"
-#include "base/strings/string_split.h"
-
-// Class to handle loadtime measure related urls, which all start with testing
-// The in memory server has a singleton object of this class. It includes a
-// html file containing javascript to go through a list of urls and upload the
-// loadtime. The users can modify urls.txt to define the urls they want to
-// measure and start with downloading the html file from browser.
-class LoadtimeMeasurement {
- public:
- LoadtimeMeasurement(const std::string& urls_file,
- const std::string& pageload_html_file)
- : num_urls_(0), pageload_html_file_(pageload_html_file) {
- std::string urls_string;
- base::ReadFileToString(urls_file, &urls_string);
- urls_ = base::SplitString(urls_string, "\n", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_ALL);
- num_urls_ = urls_.size();
- }
-
- // This is the entry function for all the loadtime measure related urls
- // It handles the request to html file, get_total_iteration to get number
- // of urls in the urls file, get each url, report the loadtime for
- // each url, and the test is completed.
- void ProcessRequest(const std::string& uri, std::string& output) {
- // remove "/testing/" from uri to get the action
- std::string action = uri.substr(9);
- if (pageload_html_file_.find(action) != std::string::npos) {
- base::ReadFileToString(pageload_html_file_, &output);
- return;
- }
- if (action.find("get_total_iteration") == 0) {
- char buffer[16];
- snprintf(buffer, sizeof(buffer), "%d", num_urls_);
- output.append(buffer, strlen(buffer));
- return;
- }
- if (action.find("geturl") == 0) {
- size_t b = action.find_first_of('=');
- if (b != std::string::npos) {
- int num = atoi(action.substr(b + 1).c_str());
- if (num < num_urls_) {
- output.append(urls_[num]);
- }
- }
- return;
- }
- if (action.find("test_complete") == 0) {
- for (std::map<std::string, int>::const_iterator it = loadtimes_.begin();
- it != loadtimes_.end();
- ++it) {
- LOG(INFO) << it->first << " " << it->second;
- }
- loadtimes_.clear();
- output.append("OK");
- return;
- }
- if (action.find("record_page_load") == 0) {
- std::vector<std::string> query = base::SplitString(
- action, "?", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- std::vector<std::string> params = base::SplitString(
- query[1], "&", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- std::vector<std::string> url = base::SplitString(
- params[1], "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- std::vector<std::string> loadtime = base::SplitString(
- params[2], "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- loadtimes_[url[1]] = atoi(loadtime[1].c_str());
- output.append("OK");
- return;
- }
- }
-
- private:
- int num_urls_;
- std::vector<std::string> urls_;
- std::map<std::string, int> loadtimes_;
- const std::string pageload_html_file_;
-};
-
-#endif // NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H_
diff --git a/chromium/net/tools/flip_server/mem_cache.cc b/chromium/net/tools/flip_server/mem_cache.cc
index 950a1a6056e..15c4f79aea9 100644
--- a/chromium/net/tools/flip_server/mem_cache.cc
+++ b/chromium/net/tools/flip_server/mem_cache.cc
@@ -65,15 +65,7 @@ FileData::FileData() {}
FileData::~FileData() {}
MemoryCache::MemoryCache() : cwd_(FLAGS_cache_base_dir) {}
-
-MemoryCache::~MemoryCache() { ClearFiles(); }
-
-void MemoryCache::CloneFrom(const MemoryCache& mc) {
- DCHECK_NE(this, &mc);
- ClearFiles();
- files_ = mc.files_;
- cwd_ = mc.cwd_;
-}
+MemoryCache::~MemoryCache() {}
void MemoryCache::AddFiles() {
std::deque<std::string> paths;
@@ -213,7 +205,7 @@ FileData* MemoryCache::GetFileData(const std::string& filename) {
if (fi == files_.end()) {
return NULL;
}
- return fi->second;
+ return fi->second.get();
}
bool MemoryCache::AssignFileData(const std::string& filename,
@@ -235,18 +227,11 @@ void MemoryCache::InsertFile(const BalsaHeaders* headers,
void MemoryCache::InsertFile(FileData* file_data) {
Files::iterator it = files_.find(file_data->filename());
if (it != files_.end()) {
- delete it->second;
- it->second = file_data;
+ it->second.reset(file_data);
} else {
- files_.insert(std::make_pair(file_data->filename(), file_data));
- }
-}
-
-void MemoryCache::ClearFiles() {
- for (Files::const_iterator i = files_.begin(); i != files_.end(); ++i) {
- delete i->second;
+ files_.insert(
+ std::make_pair(file_data->filename(), make_scoped_ptr(file_data)));
}
- files_.clear();
}
} // namespace net
diff --git a/chromium/net/tools/flip_server/mem_cache.h b/chromium/net/tools/flip_server/mem_cache.h
index 6d311b2bdc8..6b85149eca0 100644
--- a/chromium/net/tools/flip_server/mem_cache.h
+++ b/chromium/net/tools/flip_server/mem_cache.h
@@ -5,10 +5,14 @@
#ifndef NET_TOOLS_FLIP_SERVER_MEM_CACHE_H_
#define NET_TOOLS_FLIP_SERVER_MEM_CACHE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/tools/balsa/balsa_headers.h"
#include "net/tools/balsa/balsa_visitor_interface.h"
@@ -103,21 +107,19 @@ class MemCacheIter {
int priority;
bool transformed_header;
size_t body_bytes_consumed;
- uint32 stream_id;
- uint32 max_segment_size;
+ uint32_t stream_id;
+ uint32_t max_segment_size;
size_t bytes_sent;
};
class MemoryCache {
public:
- typedef std::map<std::string, FileData*> Files;
+ using Files = std::map<std::string, scoped_ptr<FileData>>;
public:
MemoryCache();
virtual ~MemoryCache();
- void CloneFrom(const MemoryCache& mc);
-
void AddFiles();
// virtual for unittests
@@ -136,7 +138,6 @@ class MemoryCache {
private:
void InsertFile(FileData* file_data);
- void ClearFiles();
Files files_;
std::string cwd_;
diff --git a/chromium/net/tools/flip_server/output_ordering.cc b/chromium/net/tools/flip_server/output_ordering.cc
index 9659954f48b..f378a8742cf 100644
--- a/chromium/net/tools/flip_server/output_ordering.cc
+++ b/chromium/net/tools/flip_server/output_ordering.cc
@@ -41,7 +41,7 @@ void OutputOrdering::Reset() {
first_data_senders_.clear();
}
-bool OutputOrdering::ExistsInPriorityMaps(uint32 stream_id) const {
+bool OutputOrdering::ExistsInPriorityMaps(uint32_t stream_id) const {
StreamIdToPriorityMap::const_iterator sitpmi = stream_ids_.find(stream_id);
return sitpmi != stream_ids_.end();
}
@@ -57,7 +57,7 @@ OutputOrdering::BeginOutputtingAlarm::~BeginOutputtingAlarm() {
epoll_server_->UnregisterAlarm(pmp_->alarm_token);
}
-int64 OutputOrdering::BeginOutputtingAlarm::OnAlarm() {
+int64_t OutputOrdering::BeginOutputtingAlarm::OnAlarm() {
OnUnregistration();
output_ordering_->MoveToActive(pmp_, mci_);
VLOG(2) << "ON ALARM! Should now start to output...";
@@ -110,8 +110,9 @@ void OutputOrdering::AddToOutputOrder(const MemCacheIter& mci) {
}
}
StreamIdToPriorityMap::iterator sitpmi;
- sitpmi = stream_ids_.insert(std::pair<uint32, PriorityMapPointer>(
- mci.stream_id, PriorityMapPointer())).first;
+ sitpmi = stream_ids_.insert(std::pair<uint32_t, PriorityMapPointer>(
+ mci.stream_id, PriorityMapPointer()))
+ .first;
PriorityMapPointer& pmp = sitpmi->second;
BeginOutputtingAlarm* boa = new BeginOutputtingAlarm(this, &pmp, mci);
@@ -123,8 +124,9 @@ void OutputOrdering::SpliceToPriorityRing(PriorityRing::iterator pri) {
MemCacheIter& mci = *pri;
PriorityMap::iterator pmi = priority_map_.find(mci.priority);
if (pmi == priority_map_.end()) {
- pmi = priority_map_.insert(std::pair<uint32, PriorityRing>(
- mci.priority, PriorityRing())).first;
+ pmi = priority_map_.insert(std::pair<uint32_t, PriorityRing>(
+ mci.priority, PriorityRing()))
+ .first;
}
pmi->second.splice(pmi->second.end(), first_data_senders_, pri);
@@ -159,7 +161,7 @@ MemCacheIter* OutputOrdering::GetIter() {
return NULL;
}
-void OutputOrdering::RemoveStreamId(uint32 stream_id) {
+void OutputOrdering::RemoveStreamId(uint32_t stream_id) {
StreamIdToPriorityMap::iterator sitpmi = stream_ids_.find(stream_id);
if (sitpmi == stream_ids_.end())
return;
diff --git a/chromium/net/tools/flip_server/output_ordering.h b/chromium/net/tools/flip_server/output_ordering.h
index 82cbfd24c94..364146037d5 100644
--- a/chromium/net/tools/flip_server/output_ordering.h
+++ b/chromium/net/tools/flip_server/output_ordering.h
@@ -5,11 +5,12 @@
#ifndef NET_TOOLS_FLIP_SERVER_OUTPUT_ORDERING_H_
#define NET_TOOLS_FLIP_SERVER_OUTPUT_ORDERING_H_
+#include <stdint.h>
+
#include <list>
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/flip_server/constants.h"
@@ -22,7 +23,7 @@ class SMConnectionInterface;
class OutputOrdering {
public:
typedef std::list<MemCacheIter> PriorityRing;
- typedef std::map<uint32, PriorityRing> PriorityMap;
+ typedef std::map<uint32_t, PriorityRing> PriorityMap;
struct PriorityMapPointer {
PriorityMapPointer();
@@ -33,20 +34,20 @@ class OutputOrdering {
EpollServer::AlarmRegToken alarm_token;
};
- typedef std::map<uint32, PriorityMapPointer> StreamIdToPriorityMap;
+ typedef std::map<uint32_t, PriorityMapPointer> StreamIdToPriorityMap;
StreamIdToPriorityMap stream_ids_;
PriorityMap priority_map_;
PriorityRing first_data_senders_;
- uint32 first_data_senders_threshold_; // when you've passed this, you're no
- // longer a first_data_sender...
+ uint32_t first_data_senders_threshold_; // when you've passed this, you're no
+ // longer a first_data_sender...
SMConnectionInterface* connection_;
EpollServer* epoll_server_;
explicit OutputOrdering(SMConnectionInterface* connection);
~OutputOrdering();
void Reset();
- bool ExistsInPriorityMaps(uint32 stream_id) const;
+ bool ExistsInPriorityMaps(uint32_t stream_id) const;
struct BeginOutputtingAlarm : public EpollAlarmCallbackInterface {
public:
@@ -56,7 +57,7 @@ class OutputOrdering {
~BeginOutputtingAlarm() override;
// EpollAlarmCallbackInterface:
- int64 OnAlarm() override;
+ int64_t OnAlarm() override;
void OnRegistration(const EpollServer::AlarmRegToken& tok,
EpollServer* eps) override;
void OnUnregistration() override;
@@ -73,7 +74,7 @@ class OutputOrdering {
void AddToOutputOrder(const MemCacheIter& mci);
void SpliceToPriorityRing(PriorityRing::iterator pri);
MemCacheIter* GetIter();
- void RemoveStreamId(uint32 stream_id);
+ void RemoveStreamId(uint32_t stream_id);
static double server_think_time_in_s() { return server_think_time_in_s_; }
static void set_server_think_time_in_s(double value) {
diff --git a/chromium/net/tools/flip_server/sm_connection.cc b/chromium/net/tools/flip_server/sm_connection.cc
index eb6a9eecfe2..ea874e26b47 100644
--- a/chromium/net/tools/flip_server/sm_connection.cc
+++ b/chromium/net/tools/flip_server/sm_connection.cc
@@ -319,12 +319,6 @@ bool SMConnection::WasSpdyNegotiated(SpdyMajorVersion* version_negotiated) {
VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT
<< "NPN protocol detected: " << npn_proto_str;
if (!strncmp(reinterpret_cast<const char*>(npn_proto),
- "spdy/2",
- npn_proto_len)) {
- *version_negotiated = SPDY2;
- return true;
- }
- if (!strncmp(reinterpret_cast<const char*>(npn_proto),
"spdy/3",
npn_proto_len)) {
*version_negotiated = SPDY3;
diff --git a/chromium/net/tools/flip_server/sm_connection.h b/chromium/net/tools/flip_server/sm_connection.h
index af94d6d1ed0..b586a18b34b 100644
--- a/chromium/net/tools/flip_server/sm_connection.h
+++ b/chromium/net/tools/flip_server/sm_connection.h
@@ -6,6 +6,7 @@
#define NET_TOOLS_FLIP_SERVER_SM_CONNECTION_H_
#include <arpa/inet.h> // in_addr_t
+#include <stddef.h>
#include <time.h>
#include <list>
diff --git a/chromium/net/tools/flip_server/sm_interface.h b/chromium/net/tools/flip_server/sm_interface.h
index 389c683602c..bf2bc5ed06c 100644
--- a/chromium/net/tools/flip_server/sm_interface.h
+++ b/chromium/net/tools/flip_server/sm_interface.h
@@ -7,6 +7,9 @@
// State Machine Interfaces
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "net/tools/balsa/balsa_headers.h"
@@ -20,7 +23,7 @@ class SMConnection;
class SMInterface {
public:
virtual void InitSMInterface(SMInterface* sm_other_interface,
- int32 server_idx) = 0;
+ int32_t server_idx) = 0;
virtual void InitSMConnection(SMConnectionPoolInterface* connection_pool,
SMInterface* sm_interface,
EpollServer* epoll_server,
@@ -31,12 +34,12 @@ class SMInterface {
bool use_ssl) = 0;
virtual size_t ProcessReadInput(const char* data, size_t len) = 0;
virtual size_t ProcessWriteInput(const char* data, size_t len) = 0;
- virtual void SetStreamID(uint32 stream_id) = 0;
+ virtual void SetStreamID(uint32_t stream_id) = 0;
virtual bool MessageFullyRead() const = 0;
virtual bool Error() const = 0;
virtual const char* ErrorAsString() const = 0;
virtual void Reset() = 0;
- virtual void ResetForNewInterface(int32 server_idx) = 0;
+ virtual void ResetForNewInterface(int32_t server_idx) = 0;
// ResetForNewConnection is used for interfaces which control SMConnection
// objects. When called an interface may put its connection object into
// a reusable instance pool. Currently this is what the HttpSM interface
@@ -46,19 +49,19 @@ class SMInterface {
virtual int PostAcceptHook() = 0;
- virtual void NewStream(uint32 stream_id,
- uint32 priority,
+ virtual void NewStream(uint32_t stream_id,
+ uint32_t priority,
const std::string& filename) = 0;
- virtual void SendEOF(uint32 stream_id) = 0;
- virtual void SendErrorNotFound(uint32 stream_id) = 0;
- virtual size_t SendSynStream(uint32 stream_id,
+ virtual void SendEOF(uint32_t stream_id) = 0;
+ virtual void SendErrorNotFound(uint32_t stream_id) = 0;
+ virtual size_t SendSynStream(uint32_t stream_id,
const BalsaHeaders& headers) = 0;
- virtual size_t SendSynReply(uint32 stream_id,
+ virtual size_t SendSynReply(uint32_t stream_id,
const BalsaHeaders& headers) = 0;
- virtual void SendDataFrame(uint32 stream_id,
+ virtual void SendDataFrame(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) = 0;
virtual void GetOutput() = 0;
virtual void set_is_request() = 0;
diff --git a/chromium/net/tools/flip_server/spdy_interface.cc b/chromium/net/tools/flip_server/spdy_interface.cc
index fb5d29075c7..d08394041ad 100644
--- a/chromium/net/tools/flip_server/spdy_interface.cc
+++ b/chromium/net/tools/flip_server/spdy_interface.cc
@@ -93,7 +93,7 @@ SMInterface* SpdySM::FindOrMakeNewSMConnectionInterface(
const std::string& server_ip,
const std::string& server_port) {
SMInterface* sm_http_interface;
- int32 server_idx;
+ int32_t server_idx;
if (unused_server_interface_list.empty()) {
sm_http_interface = NewConnectionInterface();
server_idx = server_interface_list.size();
@@ -139,39 +139,19 @@ int SpdySM::SpdyHandleNewStream(SpdyStreamId stream_id,
std::string path_string, host_string, version_string;
- if (spdy_version() == SPDY2) {
- url = headers.find("url");
- method = headers.find("method");
- version = headers.find("version");
- scheme = headers.find("scheme");
- if (url == headers.end() || method == headers.end() ||
- version == headers.end() || scheme == headers.end()) {
- VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: A mandatory header is "
- << "missing. Not creating stream";
- return 0;
- }
- // url->second here only ever seems to contain just the path. When this
- // path contains a query string with a http:// in one of its values,
- // UrlUtilities::GetUrlPath will fail and always return a / breaking
- // the request. GetUrlPath assumes the absolute URL is being passed in.
- path_string = UrlUtilities::GetUrlPath(url->second.as_string());
- host_string = UrlUtilities::GetUrlHost(url->second.as_string());
- version_string = version->second.as_string();
- } else {
- method = headers.find(":method");
- host = headers.find(":host");
- path = headers.find(":path");
- scheme = headers.find(":scheme");
- if (method == headers.end() || host == headers.end() ||
- path == headers.end() || scheme == headers.end()) {
- VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: A mandatory header is "
- << "missing. Not creating stream";
- return 0;
- }
- host_string = host->second.as_string();
- path_string = path->second.as_string();
- version_string = "HTTP/1.1";
+ method = headers.find(":method");
+ host = headers.find(":host");
+ path = headers.find(":path");
+ scheme = headers.find(":scheme");
+ if (method == headers.end() || host == headers.end() ||
+ path == headers.end() || scheme == headers.end()) {
+ VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: A mandatory header is "
+ << "missing. Not creating stream";
+ return 0;
}
+ host_string = host->second.as_string();
+ path_string = path->second.as_string();
+ version_string = "HTTP/1.1";
if (scheme->second.compare("https") == 0) {
*is_https_scheme = true;
@@ -244,6 +224,18 @@ void SpdySM::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
<< ", [" << len << "])";
}
+SpdyHeadersHandlerInterface* SpdySM::OnHeaderFrameStart(
+ SpdyStreamId stream_id) {
+ LOG(FATAL) << ACCEPTOR_CLIENT_IDENT
+ << "SpdySM::OnHeaderFrameStart() not implemented.";
+ return nullptr;
+}
+
+void SpdySM::OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) {
+ LOG(FATAL) << ACCEPTOR_CLIENT_IDENT
+ << "SpdySM::OnHeaderFrameEnd() not implemented.";
+}
+
void SpdySM::OnSynStream(SpdyStreamId stream_id,
SpdyStreamId associated_stream_id,
SpdyPriority priority,
@@ -331,7 +323,7 @@ const char* SpdySM::ErrorAsString() const {
return SpdyFramer::ErrorCodeToString(buffered_spdy_framer_->error_code());
}
-void SpdySM::ResetForNewInterface(int32 server_idx) {
+void SpdySM::ResetForNewInterface(int32_t server_idx) {
VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reset for new interface: "
<< "server_idx: " << server_idx;
unused_server_interface_list.push_back(server_idx);
@@ -359,8 +351,8 @@ int SpdySM::PostAcceptHook() {
return 1;
}
-void SpdySM::NewStream(uint32 stream_id,
- uint32 priority,
+void SpdySM::NewStream(uint32_t stream_id,
+ uint32_t priority,
const std::string& filename) {
MemCacheIter mci;
mci.stream_id = stream_id;
@@ -385,37 +377,39 @@ void SpdySM::AddToOutputOrder(const MemCacheIter& mci) {
client_output_ordering_.AddToOutputOrder(mci);
}
-void SpdySM::SendEOF(uint32 stream_id) { SendEOFImpl(stream_id); }
+void SpdySM::SendEOF(uint32_t stream_id) {
+ SendEOFImpl(stream_id);
+}
-void SpdySM::SendErrorNotFound(uint32 stream_id) {
+void SpdySM::SendErrorNotFound(uint32_t stream_id) {
SendErrorNotFoundImpl(stream_id);
}
-size_t SpdySM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) {
+size_t SpdySM::SendSynStream(uint32_t stream_id, const BalsaHeaders& headers) {
return SendSynStreamImpl(stream_id, headers);
}
-size_t SpdySM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) {
+size_t SpdySM::SendSynReply(uint32_t stream_id, const BalsaHeaders& headers) {
return SendSynReplyImpl(stream_id, headers);
}
-void SpdySM::SendDataFrame(uint32 stream_id,
+void SpdySM::SendDataFrame(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) {
SpdyDataFlags spdy_flags = static_cast<SpdyDataFlags>(flags);
SendDataFrameImpl(stream_id, data, len, spdy_flags, compress);
}
-void SpdySM::SendEOFImpl(uint32 stream_id) {
+void SpdySM::SendEOFImpl(uint32_t stream_id) {
SendDataFrame(stream_id, NULL, 0, DATA_FLAG_FIN, false);
VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending EOF: " << stream_id;
KillStream(stream_id);
stream_to_smif_.erase(stream_id);
}
-void SpdySM::SendErrorNotFoundImpl(uint32 stream_id) {
+void SpdySM::SendErrorNotFoundImpl(uint32_t stream_id) {
BalsaHeaders my_headers;
my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found");
SendSynReplyImpl(stream_id, my_headers);
@@ -423,7 +417,7 @@ void SpdySM::SendErrorNotFoundImpl(uint32 stream_id) {
client_output_ordering_.RemoveStreamId(stream_id);
}
-void SpdySM::KillStream(uint32 stream_id) {
+void SpdySM::KillStream(uint32_t stream_id) {
client_output_ordering_.RemoveStreamId(stream_id);
}
@@ -454,35 +448,21 @@ void SpdySM::CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers) {
dest.erase("X-Original-Url"); // TODO(mbelshe): case-sensitive
}
-size_t SpdySM::SendSynStreamImpl(uint32 stream_id,
+size_t SpdySM::SendSynStreamImpl(uint32_t stream_id,
const BalsaHeaders& headers) {
SpdyHeaderBlock block;
CopyHeaders(block, headers);
- if (spdy_version() == SPDY2) {
- block["method"] = headers.request_method().as_string();
- if (!headers.HasHeader("version"))
- block["version"] = headers.request_version().as_string();
- if (headers.HasHeader("X-Original-Url")) {
- std::string original_url =
- headers.GetHeader("X-Original-Url").as_string();
- block["url"] = UrlUtilities::GetUrlPath(original_url);
- } else {
- block["url"] = headers.request_uri().as_string();
- }
+ block[":method"] = headers.request_method().as_string();
+ block[":version"] = headers.request_version().as_string();
+ if (headers.HasHeader("X-Original-Url")) {
+ std::string original_url = headers.GetHeader("X-Original-Url").as_string();
+ block[":path"] = UrlUtilities::GetUrlPath(original_url);
+ block[":host"] = UrlUtilities::GetUrlPath(original_url);
} else {
- block[":method"] = headers.request_method().as_string();
- block[":version"] = headers.request_version().as_string();
- if (headers.HasHeader("X-Original-Url")) {
- std::string original_url =
- headers.GetHeader("X-Original-Url").as_string();
- block[":path"] = UrlUtilities::GetUrlPath(original_url);
- block[":host"] = UrlUtilities::GetUrlPath(original_url);
- } else {
- block[":path"] = headers.request_uri().as_string();
- if (block.find("host") != block.end()) {
- block[":host"] = headers.GetHeader("Host").as_string();
- block.erase("host");
- }
+ block[":path"] = headers.request_uri().as_string();
+ if (block.find("host") != block.end()) {
+ block[":host"] = headers.GetHeader("Host").as_string();
+ block.erase("host");
}
}
@@ -497,18 +477,13 @@ size_t SpdySM::SendSynStreamImpl(uint32 stream_id,
return df_size;
}
-size_t SpdySM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) {
+size_t SpdySM::SendSynReplyImpl(uint32_t stream_id,
+ const BalsaHeaders& headers) {
SpdyHeaderBlock block;
CopyHeaders(block, headers);
- if (spdy_version() == SPDY2) {
- block["status"] = headers.response_code().as_string() + " " +
- headers.response_reason_phrase().as_string();
- block["version"] = headers.response_version().as_string();
- } else {
- block[":status"] = headers.response_code().as_string() + " " +
- headers.response_reason_phrase().as_string();
- block[":version"] = headers.response_version().as_string();
- }
+ block[":status"] = headers.response_code().as_string() + " " +
+ headers.response_reason_phrase().as_string();
+ block[":version"] = headers.response_version().as_string();
DCHECK(buffered_spdy_framer_);
SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynReply(
@@ -521,9 +496,9 @@ size_t SpdySM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) {
return df_size;
}
-void SpdySM::SendDataFrameImpl(uint32 stream_id,
+void SpdySM::SendDataFrameImpl(uint32_t stream_id,
const char* data,
- int64 len,
+ int64_t len,
SpdyDataFlags flags,
bool compress) {
DCHECK(buffered_spdy_framer_);
@@ -540,7 +515,7 @@ void SpdySM::SendDataFrameImpl(uint32 stream_id,
// Chop data frames into chunks so that one stream can't monopolize the
// output channel.
while (len > 0) {
- int64 size = std::min(len, static_cast<int64>(kSpdySegmentSize));
+ int64_t size = std::min(len, static_cast<int64_t>(kSpdySegmentSize));
SpdyDataFlags chunk_flags = flags;
// If we chunked this block, and the FIN flag was set, there is more
diff --git a/chromium/net/tools/flip_server/spdy_interface.h b/chromium/net/tools/flip_server/spdy_interface.h
index cbaeab1894a..3d1cfa0a63f 100644
--- a/chromium/net/tools/flip_server/spdy_interface.h
+++ b/chromium/net/tools/flip_server/spdy_interface.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_
#define NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <map>
#include <string>
#include <vector>
@@ -35,7 +38,7 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
~SpdySM() override;
void InitSMInterface(SMInterface* sm_http_interface,
- int32 server_idx) override {}
+ int32_t server_idx) override {}
void InitSMConnection(SMConnectionPoolInterface* connection_pool,
SMInterface* sm_interface,
@@ -109,13 +112,27 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
// |len| The number of padding octets.
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
+ // Called just before processing the payload of a frame containing header
+ // data. Should return an implementation of SpdyHeadersHandlerInterface that
+ // will receive headers for stream |stream_id|. The caller will not take
+ // ownership of the headers handler. The same instance should be returned
+ // for all header frames comprising a logical header block (i.e. until
+ // OnHeaderFrameEnd() is called with end_headers == true).
+ SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+ SpdyStreamId stream_id) override;
+
+ // Called after processing the payload of a frame containing header data.
+ // |end_headers| is true if there will not be any subsequent CONTINUATION
+ // frames.
+ void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override;
+
// Called when a SETTINGS frame is received.
// |clear_persisted| True if the respective flag is set on the SETTINGS frame.
void OnSettings(bool clear_persisted) override {}
// Called when an individual setting within a SETTINGS frame has been parsed
// and validated.
- void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override {}
+ void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {}
// Called when a PING frame has been parsed.
void OnPing(SpdyPingId unique_id, bool is_ack) override {}
@@ -125,7 +142,8 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
// Called when a GOAWAY frame has been parsed.
void OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status) override {}
+ SpdyGoAwayStatus status,
+ base::StringPiece debug_data) override {}
// Called when a WINDOW_UPDATE frame has been parsed.
void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {}
@@ -141,11 +159,11 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
size_t ProcessReadInput(const char* data, size_t len) override;
size_t ProcessWriteInput(const char* data, size_t len) override;
bool MessageFullyRead() const override;
- void SetStreamID(uint32 stream_id) override {}
+ void SetStreamID(uint32_t stream_id) override {}
bool Error() const override;
const char* ErrorAsString() const override;
void Reset() override {}
- void ResetForNewInterface(int32 server_idx) override;
+ void ResetForNewInterface(int32_t server_idx) override;
void ResetForNewConnection() override;
// SMInterface's Cleanup is currently only called by SMConnection after a
// protocol message as been fully read. Spdy's SMInterface does not need
@@ -155,18 +173,19 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
void Cleanup() override {}
// Send a settings frame
int PostAcceptHook() override;
- void NewStream(uint32 stream_id,
- uint32 priority,
+ void NewStream(uint32_t stream_id,
+ uint32_t priority,
const std::string& filename) override;
void AddToOutputOrder(const MemCacheIter& mci);
- void SendEOF(uint32 stream_id) override;
- void SendErrorNotFound(uint32 stream_id) override;
- size_t SendSynStream(uint32 stream_id, const BalsaHeaders& headers) override;
- size_t SendSynReply(uint32 stream_id, const BalsaHeaders& headers) override;
- void SendDataFrame(uint32 stream_id,
+ void SendEOF(uint32_t stream_id) override;
+ void SendErrorNotFound(uint32_t stream_id) override;
+ size_t SendSynStream(uint32_t stream_id,
+ const BalsaHeaders& headers) override;
+ size_t SendSynReply(uint32_t stream_id, const BalsaHeaders& headers) override;
+ void SendDataFrame(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) override;
BufferedSpdyFramer* spdy_framer() { return buffered_spdy_framer_.get(); }
@@ -184,15 +203,15 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
}
private:
- void SendEOFImpl(uint32 stream_id);
- void SendErrorNotFoundImpl(uint32 stream_id);
- void KillStream(uint32 stream_id);
+ void SendEOFImpl(uint32_t stream_id);
+ void SendErrorNotFoundImpl(uint32_t stream_id);
+ void KillStream(uint32_t stream_id);
void CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers);
- size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers);
- size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers);
- void SendDataFrameImpl(uint32 stream_id,
+ size_t SendSynStreamImpl(uint32_t stream_id, const BalsaHeaders& headers);
+ size_t SendSynReplyImpl(uint32_t stream_id, const BalsaHeaders& headers);
+ void SendDataFrameImpl(uint32_t stream_id,
const char* data,
- int64 len,
+ int64_t len,
SpdyDataFlags flags,
bool compress);
void EnqueueDataFrame(DataFrame* df);
@@ -207,13 +226,13 @@ class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
SMConnection* connection_;
OutputList* client_output_list_;
OutputOrdering client_output_ordering_;
- uint32 next_outgoing_stream_id_;
+ uint32_t next_outgoing_stream_id_;
EpollServer* epoll_server_;
FlipAcceptor* acceptor_;
MemoryCache* memory_cache_;
std::vector<SMInterface*> server_interface_list;
- std::vector<int32> unused_server_interface_list;
- typedef std::map<uint32, SMInterface*> StreamToSmif;
+ std::vector<int32_t> unused_server_interface_list;
+ typedef std::map<uint32_t, SMInterface*> StreamToSmif;
StreamToSmif stream_to_smif_;
bool close_on_error_;
diff --git a/chromium/net/tools/flip_server/spdy_interface_test.cc b/chromium/net/tools/flip_server/spdy_interface_test.cc
index 23c7a9d00e0..1d4c09ac16e 100644
--- a/chromium/net/tools/flip_server/spdy_interface_test.cc
+++ b/chromium/net/tools/flip_server/spdy_interface_test.cc
@@ -9,7 +9,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/spdy/buffered_spdy_framer.h"
-#include "net/spdy/spdy_test_utils.h"
#include "net/tools/balsa/balsa_enums.h"
#include "net/tools/balsa/balsa_headers.h"
#include "net/tools/flip_server/flip_config.h"
@@ -28,6 +27,11 @@ using ::testing::Return;
using ::testing::SaveArg;
using ::testing::Values;
+inline bool operator==(StringPiece x,
+ const SpdyHeaderBlock::StringPieceProxy& y) {
+ return x == y.operator StringPiece();
+}
+
namespace {
struct StringSaver {
@@ -67,11 +71,15 @@ class SpdyFramerVisitor : public BufferedSpdyFramerVisitorInterface {
size_t,
bool));
MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId, size_t));
+ MOCK_METHOD1(OnHeaderFrameStart,
+ SpdyHeadersHandlerInterface*(SpdyStreamId stream_id));
+ MOCK_METHOD2(OnHeaderFrameEnd,
+ void(SpdyStreamId stream_id, bool end_headers));
MOCK_METHOD1(OnSettings, void(bool clear_persisted));
- MOCK_METHOD3(OnSetting, void(SpdySettingsIds, uint8, uint32));
+ MOCK_METHOD3(OnSetting, void(SpdySettingsIds, uint8_t, uint32_t));
MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
MOCK_METHOD2(OnRstStream, void(SpdyStreamId, SpdyRstStreamStatus));
- MOCK_METHOD2(OnGoAway, void(SpdyStreamId, SpdyGoAwayStatus));
+ MOCK_METHOD3(OnGoAway, void(SpdyStreamId, SpdyGoAwayStatus, StringPiece));
MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId, int));
MOCK_METHOD3(OnPushPromise,
void(SpdyStreamId, SpdyStreamId, const SpdyHeaderBlock&));
@@ -181,7 +189,7 @@ class SpdySMTestBase : public ::testing::TestWithParam<SpdyMajorVersion> {
output_list.clear();
}
- bool HasStream(uint32 stream_id) {
+ bool HasStream(uint32_t stream_id) {
return interface_->output_ordering().ExistsInPriorityMaps(stream_id);
}
@@ -223,8 +231,8 @@ TEST_P(SpdySMProxyTest, InitSMConnection) {
TEST_P(SpdySMProxyTest, OnStreamFrameData) {
BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
- uint32 stream_id = 92;
- uint32 associated_id = 43;
+ uint32_t stream_id = 92;
+ uint32_t associated_id = 43;
SpdyHeaderBlock block;
testing::MockFunction<void(int)> checkpoint; // NOLINT
@@ -253,7 +261,7 @@ TEST_P(SpdySMProxyTest, OnStreamFrameData) {
TEST_P(SpdySMProxyTest, OnRstStream) {
BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
- uint32 stream_id = 82;
+ uint32_t stream_id = 82;
MemCacheIter mci;
mci.stream_id = stream_id;
@@ -279,7 +287,7 @@ TEST_P(SpdySMProxyTest, ProcessReadInput) {
}
TEST_P(SpdySMProxyTest, ResetForNewConnection) {
- uint32 stream_id = 13;
+ uint32_t stream_id = 13;
MemCacheIter mci;
mci.stream_id = stream_id;
// incomplete input
@@ -338,7 +346,7 @@ TEST_P(SpdySMProxyTest, NewStream) {
}
TEST_P(SpdySMProxyTest, AddToOutputOrder) {
- uint32 stream_id = 13;
+ uint32_t stream_id = 13;
MemCacheIter mci;
mci.stream_id = stream_id;
@@ -354,7 +362,7 @@ TEST_P(SpdySMProxyTest, AddToOutputOrder) {
}
TEST_P(SpdySMProxyTest, SendErrorNotFound) {
- uint32 stream_id = 82;
+ uint32_t stream_id = 82;
SpdyHeaderBlock actual_header_block;
const char* actual_data;
size_t actual_size;
@@ -402,7 +410,7 @@ TEST_P(SpdySMProxyTest, SendErrorNotFound) {
}
TEST_P(SpdySMProxyTest, SendSynStream) {
- uint32 stream_id = 82;
+ uint32_t stream_id = 82;
BalsaHeaders headers;
SpdyHeaderBlock actual_header_block;
headers.AppendHeader("key1", "value1");
@@ -433,7 +441,7 @@ TEST_P(SpdySMProxyTest, SendSynStream) {
}
TEST_P(SpdySMProxyTest, SendSynReply) {
- uint32 stream_id = 82;
+ uint32_t stream_id = 82;
BalsaHeaders headers;
SpdyHeaderBlock actual_header_block;
headers.AppendHeader("key1", "value1");
@@ -467,7 +475,7 @@ TEST_P(SpdySMProxyTest, SendSynReply) {
}
TEST_P(SpdySMProxyTest, SendDataFrame) {
- uint32 stream_id = 133;
+ uint32_t stream_id = 133;
SpdyDataFlags flags = DATA_FLAG_NONE;
const char* actual_data;
size_t actual_size;
@@ -493,7 +501,7 @@ TEST_P(SpdySMProxyTest, SendDataFrame) {
}
TEST_P(SpdySMProxyTest, SendLongDataFrame) {
- uint32 stream_id = 133;
+ uint32_t stream_id = 133;
SpdyDataFlags flags = DATA_FLAG_NONE;
const char* actual_data;
size_t actual_size;
@@ -533,7 +541,7 @@ TEST_P(SpdySMProxyTest, SendLongDataFrame) {
TEST_P(SpdySMServerTest, OnSynStream) {
BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
- uint32 stream_id = 82;
+ uint32_t stream_id = 82;
SpdyHeaderBlock spdy_headers;
spdy_headers["url"] = "http://www.example.com/path";
spdy_headers["method"] = "GET";
@@ -549,7 +557,7 @@ TEST_P(SpdySMServerTest, OnSynStream) {
}
TEST_P(SpdySMServerTest, NewStream) {
- uint32 stream_id = 13;
+ uint32_t stream_id = 13;
std::string filename = "foobar";
{
@@ -562,7 +570,7 @@ TEST_P(SpdySMServerTest, NewStream) {
}
TEST_P(SpdySMServerTest, NewStreamError) {
- uint32 stream_id = 82;
+ uint32_t stream_id = 82;
SpdyHeaderBlock actual_header_block;
const char* actual_data;
size_t actual_size;
diff --git a/chromium/net/tools/flip_server/streamer_interface.cc b/chromium/net/tools/flip_server/streamer_interface.cc
index 25a496497ba..5f3d479ce04 100644
--- a/chromium/net/tools/flip_server/streamer_interface.cc
+++ b/chromium/net/tools/flip_server/streamer_interface.cc
@@ -43,7 +43,7 @@ void StreamerSM::set_is_request() {
}
void StreamerSM::InitSMInterface(SMInterface* sm_other_interface,
- int32 server_idx) {
+ int32_t server_idx) {
sm_other_interface_ = sm_other_interface;
}
@@ -143,12 +143,13 @@ int StreamerSM::PostAcceptHook() {
return 1;
}
-size_t StreamerSM::SendSynStream(uint32 stream_id,
+size_t StreamerSM::SendSynStream(uint32_t stream_id,
const BalsaHeaders& headers) {
return 0;
}
-size_t StreamerSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) {
+size_t StreamerSM::SendSynReply(uint32_t stream_id,
+ const BalsaHeaders& headers) {
return 0;
}
diff --git a/chromium/net/tools/flip_server/streamer_interface.h b/chromium/net/tools/flip_server/streamer_interface.h
index ef666695ec3..f255427c053 100644
--- a/chromium/net/tools/flip_server/streamer_interface.h
+++ b/chromium/net/tools/flip_server/streamer_interface.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_FLIP_SERVER_STREAMER_INTERFACE_H_
#define NET_TOOLS_FLIP_SERVER_STREAMER_INTERFACE_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/compiler_specific.h"
@@ -31,7 +34,7 @@ class StreamerSM : public BalsaVisitorInterface, public SMInterface {
void AddToOutputOrder(const MemCacheIter& mci) {}
void InitSMInterface(SMInterface* sm_other_interface,
- int32 server_idx) override;
+ int32_t server_idx) override;
void InitSMConnection(SMConnectionPoolInterface* connection_pool,
SMInterface* sm_interface,
EpollServer* epoll_server,
@@ -44,26 +47,27 @@ class StreamerSM : public BalsaVisitorInterface, public SMInterface {
size_t ProcessReadInput(const char* data, size_t len) override;
size_t ProcessWriteInput(const char* data, size_t len) override;
bool MessageFullyRead() const override;
- void SetStreamID(uint32 stream_id) override {}
+ void SetStreamID(uint32_t stream_id) override {}
bool Error() const override;
const char* ErrorAsString() const override;
void Reset() override;
- void ResetForNewInterface(int32 server_idx) override {}
+ void ResetForNewInterface(int32_t server_idx) override {}
void ResetForNewConnection() override;
void Cleanup() override;
int PostAcceptHook() override;
- void NewStream(uint32 stream_id,
- uint32 priority,
+ void NewStream(uint32_t stream_id,
+ uint32_t priority,
const std::string& filename) override {}
- void SendEOF(uint32 stream_id) override {}
- void SendErrorNotFound(uint32 stream_id) override {}
- virtual void SendOKResponse(uint32 stream_id, const std::string& output) {}
- size_t SendSynStream(uint32 stream_id, const BalsaHeaders& headers) override;
- size_t SendSynReply(uint32 stream_id, const BalsaHeaders& headers) override;
- void SendDataFrame(uint32 stream_id,
+ void SendEOF(uint32_t stream_id) override {}
+ void SendErrorNotFound(uint32_t stream_id) override {}
+ virtual void SendOKResponse(uint32_t stream_id, const std::string& output) {}
+ size_t SendSynStream(uint32_t stream_id,
+ const BalsaHeaders& headers) override;
+ size_t SendSynReply(uint32_t stream_id, const BalsaHeaders& headers) override;
+ void SendDataFrame(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) override {}
void set_is_request() override;
static std::string forward_ip_header() { return forward_ip_header_; }
@@ -72,19 +76,19 @@ class StreamerSM : public BalsaVisitorInterface, public SMInterface {
}
private:
- void SendEOFImpl(uint32 stream_id) {}
- void SendErrorNotFoundImpl(uint32 stream_id) {}
- void SendOKResponseImpl(uint32 stream_id, std::string* output) {}
- size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) {
+ void SendEOFImpl(uint32_t stream_id) {}
+ void SendErrorNotFoundImpl(uint32_t stream_id) {}
+ void SendOKResponseImpl(uint32_t stream_id, std::string* output) {}
+ size_t SendSynReplyImpl(uint32_t stream_id, const BalsaHeaders& headers) {
return 0;
}
- size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers) {
+ size_t SendSynStreamImpl(uint32_t stream_id, const BalsaHeaders& headers) {
return 0;
}
- void SendDataFrameImpl(uint32 stream_id,
+ void SendDataFrameImpl(uint32_t stream_id,
const char* data,
- int64 len,
- uint32 flags,
+ int64_t len,
+ uint32_t flags,
bool compress) {}
void GetOutput() override {}
diff --git a/chromium/net/tools/flip_server/url_to_filename_encoder.cc b/chromium/net/tools/flip_server/url_to_filename_encoder.cc
index 5383cc88d5b..b3d80e4b5a1 100644
--- a/chromium/net/tools/flip_server/url_to_filename_encoder.cc
+++ b/chromium/net/tools/flip_server/url_to_filename_encoder.cc
@@ -2,28 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "net/tools/flip_server/url_to_filename_encoder.h"
+
#include <stdlib.h>
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "net/base/net_util.h"
-#include "net/tools/flip_server/url_to_filename_encoder.h"
using std::string;
namespace {
-// Returns 1 if buf is prefixed by "num_digits" of hex digits
-// Teturns 0 otherwise.
-// The function checks for '\0' for string termination.
-int HexDigitsPrefix(const char* buf, int num_digits) {
- for (int i = 0; i < num_digits; i++) {
- if (!base::IsHexDigit(buf[i]))
- return 0; // This also detects end of string as '\0' is not xdigit.
- }
- return 1;
-}
-
#ifdef WIN32
#define strtoull _strtoui64
#endif
@@ -31,12 +21,13 @@ int HexDigitsPrefix(const char* buf, int num_digits) {
// A simple parser for long long values. Returns the parsed value if a
// valid integer is found; else returns deflt
// UInt64 and Int64 cannot handle decimal numbers with leading 0s.
-uint64 ParseLeadingHex64Value(const char* str, uint64 deflt) {
+uint64_t ParseLeadingHex64Value(const char* str, uint64_t deflt) {
char* error = NULL;
- const uint64 value = strtoull(str, &error, 16);
+ const uint64_t value = strtoull(str, &error, 16);
return (error == str) ? deflt : value;
}
-}
+
+} // namespace
namespace net {
@@ -185,7 +176,7 @@ bool UrlToFilenameEncoder::Decode(const string& encoded_filename,
}
break;
case kEscape:
- if (HexDigitsPrefix(&ch, 1) == 1) {
+ if (base::IsHexDigit(ch)) {
hex_buffer[0] = ch;
state = kFirstDigit;
} else if (ch == kTruncationChar) {
@@ -203,9 +194,9 @@ bool UrlToFilenameEncoder::Decode(const string& encoded_filename,
}
break;
case kFirstDigit:
- if (HexDigitsPrefix(&ch, 1) == 1) {
+ if (base::IsHexDigit(ch)) {
hex_buffer[1] = ch;
- uint64 hex_value = ParseLeadingHex64Value(hex_buffer, 0);
+ uint64_t hex_value = ParseLeadingHex64Value(hex_buffer, 0);
decoded_url->append(1, static_cast<char>(hex_value));
state = kStart;
} else {
diff --git a/chromium/net/tools/flip_server/url_to_filename_encoder.h b/chromium/net/tools/flip_server/url_to_filename_encoder.h
index d07c12910c4..583e2fbb341 100644
--- a/chromium/net/tools/flip_server/url_to_filename_encoder.h
+++ b/chromium/net/tools/flip_server/url_to_filename_encoder.h
@@ -79,6 +79,8 @@
#ifndef NET_TOOLS_FLIP_SERVER_URL_TO_FILENAME_ENCODER_H_
#define NET_TOOLS_FLIP_SERVER_URL_TO_FILENAME_ENCODER_H_
+#include <stddef.h>
+
#include <string>
#include "base/strings/string_util.h"
diff --git a/chromium/net/tools/gdig/file_net_log.h b/chromium/net/tools/gdig/file_net_log.h
index aca1d57ce61..b39111d7d46 100644
--- a/chromium/net/tools/gdig/file_net_log.h
+++ b/chromium/net/tools/gdig/file_net_log.h
@@ -7,7 +7,6 @@
#include <string>
-#include "base/basictypes.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "net/log/net_log.h"
diff --git a/chromium/net/tools/gdig/gdig.cc b/chromium/net/tools/gdig/gdig.cc
index cc490cd945d..9a0176b140d 100644
--- a/chromium/net/tools/gdig/gdig.cc
+++ b/chromium/net/tools/gdig/gdig.cc
@@ -4,9 +4,9 @@
#include <stdio.h>
#include <string>
+#include <utility>
#include "base/at_exit.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/cancelable_callback.h"
#include "base/command_line.h"
@@ -57,7 +57,7 @@ bool StringToIPEndPoint(const std::string& ip_address_and_port,
if (!net::ParseIPLiteralToNumber(ip, &ip_number))
return false;
- *ip_end_point = net::IPEndPoint(ip_number, static_cast<uint16>(port));
+ *ip_end_point = net::IPEndPoint(ip_number, static_cast<uint16_t>(port));
return true;
}
@@ -152,7 +152,7 @@ bool LoadReplayLog(const base::FilePath& file_path, ReplayLog* replay_log) {
continue;
}
- int64 delta_in_milliseconds;
+ int64_t delta_in_milliseconds;
if (!base::StringToInt64(time_and_name[0], &delta_in_milliseconds)) {
fprintf(
stderr,
@@ -401,7 +401,7 @@ void GDig::Finish(Result result) {
DCHECK_NE(RESULT_PENDING, result);
result_ = result;
if (base::MessageLoop::current())
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
void GDig::OnDnsConfig(const DnsConfig& dns_config_const) {
@@ -432,8 +432,8 @@ void GDig::OnDnsConfig(const DnsConfig& dns_config_const) {
options.max_retry_attempts = 1u;
scoped_ptr<HostResolverImpl> resolver(
new HostResolverImpl(options, log_.get()));
- resolver->SetDnsClient(dns_client.Pass());
- resolver_ = resolver.Pass();
+ resolver->SetDnsClient(std::move(dns_client));
+ resolver_ = std::move(resolver);
start_time_ = base::Time::Now();
diff --git a/chromium/net/tools/get_server_time/get_server_time.cc b/chromium/net/tools/get_server_time/get_server_time.cc
index 4bfc12f1944..3363bb08391 100644
--- a/chromium/net/tools/get_server_time/get_server_time.cc
+++ b/chromium/net/tools/get_server_time/get_server_time.cc
@@ -14,13 +14,13 @@
#include <string>
#include "base/at_exit.h"
-#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/format_macros.h"
#include "base/i18n/time_formatting.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -54,17 +54,17 @@ namespace {
// base::TimeTicks::Now() is documented to have a resolution of
// ~1-15ms.
-const int64 kTicksResolutionMs = 15;
+const int64_t kTicksResolutionMs = 15;
// For the sources that are supported (HTTP date headers, TLS
// handshake), the resolution of the server time is 1 second.
-const int64 kServerTimeResolutionMs = 1000;
+const int64_t kServerTimeResolutionMs = 1000;
// Assume base::Time::Now() has the same resolution as
// base::TimeTicks::Now().
//
// TODO(akalin): Figure out the real resolution.
-const int64 kTimeResolutionMs = kTicksResolutionMs;
+const int64_t kTimeResolutionMs = kTicksResolutionMs;
// Simply quits the current message loop when finished. Used to make
// URLFetcher synchronous.
@@ -76,18 +76,18 @@ class QuitDelegate : public net::URLFetcherDelegate {
// net::URLFetcherDelegate implementation.
void OnURLFetchComplete(const net::URLFetcher* source) override {
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
void OnURLFetchDownloadProgress(const net::URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
NOTREACHED();
}
void OnURLFetchUploadProgress(const net::URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
NOTREACHED();
}
@@ -148,7 +148,7 @@ BuildURLRequestContext(net::NetLog* net_log) {
#endif
scoped_ptr<net::URLRequestContext> context(builder.Build());
context->set_net_log(net_log);
- return context.Pass();
+ return context;
}
// Assuming that the time |server_time| was received from a server,
@@ -261,7 +261,7 @@ int main(int argc, char* argv[]) {
UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(end_time)).c_str(),
end_ticks.ToInternalValue());
- const int64 delta_ticks_internal =
+ const int64_t delta_ticks_internal =
end_ticks.ToInternalValue() - start_ticks.ToInternalValue();
const base::TimeDelta delta_ticks = end_ticks - start_ticks;
diff --git a/chromium/net/tools/net_docs/net_docs.py b/chromium/net/tools/net_docs/net_docs.py
index e694214941d..a433a201e5a 100755
--- a/chromium/net/tools/net_docs/net_docs.py
+++ b/chromium/net/tools/net_docs/net_docs.py
@@ -113,7 +113,8 @@ def main():
parser.add_argument('filenames', nargs=argparse.REMAINDER)
args = parser.parse_args()
- ProcessDocs(args.filenames, args.input_path, args.output_path)
+ extensions = ['markdown.extensions.def_list']
+ ProcessDocs(args.filenames, args.input_path, args.output_path, extensions)
return 0
diff --git a/chromium/net/tools/net_watcher/net_watcher.cc b/chromium/net/tools/net_watcher/net_watcher.cc
index ca25040748d..9f07513c655 100644
--- a/chromium/net/tools/net_watcher/net_watcher.cc
+++ b/chromium/net/tools/net_watcher/net_watcher.cc
@@ -7,11 +7,11 @@
#include <string>
#include "base/at_exit.h"
-#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_split.h"
@@ -199,7 +199,7 @@ int main(int argc, char* argv[]) {
LOG(INFO) << "Initial connection type: "
<< ConnectionTypeToString(
- network_change_notifier->GetCurrentConnectionType());
+ net::NetworkChangeNotifier::GetConnectionType());
{
net::ProxyConfig config;
diff --git a/chromium/net/tools/quic/end_to_end_test.cc b/chromium/net/tools/quic/end_to_end_test.cc
index fa671a2cf63..b1cee41f65b 100644
--- a/chromium/net/tools/quic/end_to_end_test.cc
+++ b/chromium/net/tools/quic/end_to_end_test.cc
@@ -3,11 +3,10 @@
// found in the LICENSE file.
#include <stddef.h>
-#include <string>
#include <sys/epoll.h>
+#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/strings/string_number_conversions.h"
@@ -23,7 +22,9 @@
#include "net/quic/quic_packet_creator.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_server_id.h"
+#include "net/quic/quic_session.h"
#include "net/quic/quic_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.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_sent_packet_manager_peer.h"
@@ -37,6 +38,7 @@
#include "net/tools/quic/quic_in_memory_cache.h"
#include "net/tools/quic/quic_packet_writer_wrapper.h"
#include "net/tools/quic/quic_server.h"
+#include "net/tools/quic/quic_simple_server_stream.h"
#include "net/tools/quic/quic_socket_utils.h"
#include "net/tools/quic/quic_spdy_client_stream.h"
#include "net/tools/quic/test_tools/http_message.h"
@@ -46,14 +48,17 @@
#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
#include "net/tools/quic/test_tools/quic_server_peer.h"
#include "net/tools/quic/test_tools/quic_test_client.h"
+#include "net/tools/quic/test_tools/quic_test_server.h"
#include "net/tools/quic/test_tools/server_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
+using base::IntToString;
using base::StringPiece;
using base::WaitableEvent;
using net::EpollServer;
using net::IPAddressNumber;
using net::test::ConstructEncryptedPacket;
+using net::test::CryptoTestUtils;
using net::test::GenerateBody;
using net::test::Loopback4;
using net::test::MockQuicConnectionDebugVisitor;
@@ -63,7 +68,6 @@ using net::test::QuicSentPacketManagerPeer;
using net::test::QuicSessionPeer;
using net::test::QuicSpdySessionPeer;
using net::test::ReliableQuicStreamPeer;
-using net::test::TestWriterFactory;
using net::test::ValueRestore;
using net::test::kClientDataStreamId1;
using net::test::kInitialSessionFlowControlWindowForTest;
@@ -82,6 +86,7 @@ namespace {
const char kFooResponseBody[] = "Artichoke hearts make me happy.";
const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
+const float kSessionToStreamRatio = 1.5;
// Run all tests with the cross products of all versions.
struct TestParams {
@@ -142,34 +147,51 @@ vector<TestParams> GetTestParams() {
// to do 0-RTT across incompatible versions. Chromium only supports
// a single version at a time anyway. :)
QuicVersionVector all_supported_versions = QuicSupportedVersions();
- QuicVersionVector client_version_buckets[3];
+ QuicVersionVector version_buckets[2];
for (const QuicVersion version : all_supported_versions) {
- if (version <= QUIC_VERSION_24) {
- // SPDY/4 compression but SPDY/3 headers
- client_version_buckets[0].push_back(version);
- } else if (version <= QUIC_VERSION_25) {
+ if (version <= QUIC_VERSION_25) {
// SPDY/4
- client_version_buckets[1].push_back(version);
+ version_buckets[0].push_back(version);
} else {
// QUIC_VERSION_26 changes the kdf in a way that is incompatible with
// version negotiation across the version 26 boundary.
- client_version_buckets[2].push_back(version);
+ version_buckets[1].push_back(version);
}
}
vector<TestParams> params;
- // TODO(rtenneti): Add kTBBR after BBR code is checked in.
- // for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC}) {
- for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) {
- for (const bool use_fec : {false, true}) {
- for (const QuicVersionVector& client_versions : client_version_buckets) {
- // A number of end to end tests fail when stateless rejects are enabled
- // *and* there are more than two QUIC versions.
- // TODO(b/23745998) Re-enable client stateless reject support.
- for (bool client_supports_stateless_rejects : {false}) {
- // TODO(b/23745998) Re-enable server stateless reject support.
- for (bool server_uses_stateless_rejects_if_peer_supported : {false}) {
- for (bool auto_tune_flow_control_window : {true, false}) {
+ for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) {
+ for (bool client_supports_stateless_rejects : {true, false}) {
+ // TODO(rtenneti): Add kTBBR after BBR code is checked in.
+ for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) {
+ for (bool auto_tune_flow_control_window : {true, false}) {
+ for (const bool use_fec : {false, true}) {
+ const int kMaxEnabledOptions = 5;
+ int enabled_options = 0;
+ if (congestion_control_tag != kQBIC) {
+ ++enabled_options;
+ }
+ if (use_fec) {
+ ++enabled_options;
+ }
+ if (auto_tune_flow_control_window) {
+ ++enabled_options;
+ }
+ if (client_supports_stateless_rejects) {
+ ++enabled_options;
+ }
+ if (server_uses_stateless_rejects_if_peer_supported) {
+ ++enabled_options;
+ }
+ CHECK_GE(kMaxEnabledOptions, enabled_options);
+
+ // Run tests with no options, a single option, or all the options
+ // enabled to avoid a combinatorial explosion.
+ if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) {
+ continue;
+ }
+
+ for (const QuicVersionVector& client_versions : version_buckets) {
CHECK(!client_versions.empty());
// Add an entry for server and client supporting all versions.
params.push_back(TestParams(
@@ -179,13 +201,19 @@ vector<TestParams> GetTestParams() {
server_uses_stateless_rejects_if_peer_supported,
congestion_control_tag, auto_tune_flow_control_window));
+ // Run version negotiation tests tests with no options, or all
+ // the options enabled to avoid a combinatorial explosion.
+ if (enabled_options > 0 && enabled_options < kMaxEnabledOptions) {
+ continue;
+ }
+
// Test client supporting all versions and server supporting 1
// version. Simulate an old server and exercise version downgrade
// in the client. Protocol negotiation should occur. Skip the i =
// 0 case because it is essentially the same as the default case.
- for (const QuicVersion version : client_versions) {
+ for (size_t i = 1; i < client_versions.size(); ++i) {
QuicVersionVector server_supported_versions;
- server_supported_versions.push_back(version);
+ server_supported_versions.push_back(client_versions[i]);
params.push_back(TestParams(
client_versions, server_supported_versions,
server_supported_versions.front(), use_fec,
@@ -204,18 +232,12 @@ vector<TestParams> GetTestParams() {
class ServerDelegate : public PacketDroppingTestWriter::Delegate {
public:
- ServerDelegate(TestWriterFactory* writer_factory,
- QuicDispatcher* dispatcher)
- : writer_factory_(writer_factory),
- dispatcher_(dispatcher) {}
+ explicit ServerDelegate(QuicDispatcher* dispatcher)
+ : dispatcher_(dispatcher) {}
~ServerDelegate() override {}
- void OnPacketSent(WriteResult result) override {
- writer_factory_->OnPacketSent(result);
- }
void OnCanWrite() override { dispatcher_->OnCanWrite(); }
private:
- TestWriterFactory* writer_factory_;
QuicDispatcher* dispatcher_;
};
@@ -223,7 +245,6 @@ class ClientDelegate : public PacketDroppingTestWriter::Delegate {
public:
explicit ClientDelegate(QuicClient* client) : client_(client) {}
~ClientDelegate() override {}
- void OnPacketSent(WriteResult result) override {}
void OnCanWrite() override {
EpollEvent event(EPOLLOUT, false);
client_->OnEvent(client_->fd(), &event);
@@ -240,7 +261,9 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
server_address_(IPEndPoint(Loopback4(), 0)),
server_hostname_("example.com"),
server_started_(false),
- strike_register_no_startup_period_(false) {
+ strike_register_no_startup_period_(false),
+ chlo_multiplier_(0),
+ stream_factory_(nullptr) {
client_supported_versions_ = GetParam().client_supported_versions;
server_supported_versions_ = GetParam().server_supported_versions;
negotiated_version_ = GetParam().negotiated_version;
@@ -259,8 +282,8 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
3 * kInitialSessionFlowControlWindowForTest);
QuicInMemoryCachePeer::ResetForTests();
- AddToCache("/foo", 200, "OK", kFooResponseBody);
- AddToCache("/bar", 200, "OK", kBarResponseBody);
+ AddToCache("/foo", 200, kFooResponseBody);
+ AddToCache("/bar", 200, kBarResponseBody);
}
~EndToEndTest() override {
@@ -270,43 +293,53 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
}
QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
- QuicTestClient* client = new QuicTestClient(
- server_address_, server_hostname_,
- /*secure=*/true, client_config_, client_supported_versions_);
+ QuicTestClient* client =
+ new QuicTestClient(server_address_, server_hostname_, client_config_,
+ client_supported_versions_);
client->UseWriter(writer);
client->Connect();
return client;
}
- void set_client_initial_stream_flow_control_receive_window(uint32 window) {
+ void set_smaller_flow_control_receive_window() {
+ const uint32_t kClientIFCW = 64 * 1024;
+ const uint32_t kServerIFCW = 1024 * 1024;
+ set_client_initial_stream_flow_control_receive_window(kClientIFCW);
+ set_client_initial_session_flow_control_receive_window(
+ kSessionToStreamRatio * kClientIFCW);
+ set_server_initial_stream_flow_control_receive_window(kServerIFCW);
+ set_server_initial_session_flow_control_receive_window(
+ kSessionToStreamRatio * kServerIFCW);
+ }
+
+ void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
CHECK(client_.get() == nullptr);
DVLOG(1) << "Setting client initial stream flow control window: " << window;
client_config_.SetInitialStreamFlowControlWindowToSend(window);
}
- void set_client_initial_session_flow_control_receive_window(uint32 window) {
+ void set_client_initial_session_flow_control_receive_window(uint32_t window) {
CHECK(client_.get() == nullptr);
DVLOG(1) << "Setting client initial session flow control window: "
<< window;
client_config_.SetInitialSessionFlowControlWindowToSend(window);
}
- void set_server_initial_stream_flow_control_receive_window(uint32 window) {
+ void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
CHECK(server_thread_.get() == nullptr);
- DVLOG(1) << "Setting server initial stream flow control window: "
- << window;
+ DVLOG(1) << "Setting server initial stream flow control window: " << window;
server_config_.SetInitialStreamFlowControlWindowToSend(window);
}
- void set_server_initial_session_flow_control_receive_window(uint32 window) {
+ void set_server_initial_session_flow_control_receive_window(uint32_t window) {
CHECK(server_thread_.get() == nullptr);
DVLOG(1) << "Setting server initial session flow control window: "
<< window;
server_config_.SetInitialSessionFlowControlWindowToSend(window);
}
- const QuicSentPacketManager *
- GetSentPacketManagerFromFirstServerSession() const {
+ const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession()
+ const {
QuicDispatcher* dispatcher =
QuicServerPeer::GetDispatcher(server_thread_->server());
QuicSession* session = dispatcher->session_map().begin()->second;
@@ -337,6 +370,7 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
// Start the server first, because CreateQuicClient() attempts
// to connect to the server.
StartServer();
+
client_.reset(CreateQuicClient(client_writer_));
if (GetParam().use_fec) {
// Set FecPolicy to always protect data on all streams.
@@ -354,7 +388,7 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
void SetUp() override {
// The ownership of these gets transferred to the QuicPacketWriterWrapper
- // and TestWriterFactory when Initialize() is executed.
+ // when Initialize() is executed.
client_writer_ = new PacketDroppingTestWriter();
server_writer_ = new PacketDroppingTestWriter();
}
@@ -367,32 +401,29 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
void StartServer() {
server_thread_.reset(new ServerThread(
- new QuicServer(server_config_, server_supported_versions_),
- /*is_secure=*/true, server_address_,
- strike_register_no_startup_period_));
+ new QuicTestServer(CryptoTestUtils::ProofSourceForTesting(),
+ server_config_, server_supported_versions_),
+ server_address_, strike_register_no_startup_period_));
+ if (chlo_multiplier_ != 0) {
+ server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
+ }
server_thread_->Initialize();
- server_address_ = IPEndPoint(server_address_.address(),
- server_thread_->GetPort());
+ server_address_ =
+ IPEndPoint(server_address_.address(), server_thread_->GetPort());
QuicDispatcher* dispatcher =
QuicServerPeer::GetDispatcher(server_thread_->server());
- TestWriterFactory* packet_writer_factory = new TestWriterFactory();
- QuicDispatcherPeer::SetPacketWriterFactory(dispatcher,
- packet_writer_factory);
QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
- if (GetParam().server_uses_stateless_rejects_if_peer_supported) {
- // Enable stateless rejects and force the server to always send
- // them.
- FLAGS_enable_quic_stateless_reject_support = true;
- FLAGS_quic_session_map_threshold_for_stateless_rejects = 0;
- } else {
- FLAGS_enable_quic_stateless_reject_support = false;
- FLAGS_quic_session_map_threshold_for_stateless_rejects = -1;
+ FLAGS_enable_quic_stateless_reject_support =
+ GetParam().server_uses_stateless_rejects_if_peer_supported;
+
+ server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
+ new ServerDelegate(dispatcher));
+ if (stream_factory_ != nullptr) {
+ static_cast<QuicTestServer*>(server_thread_->server())
+ ->SetSpdyStreamFactory(stream_factory_);
}
- server_writer_->Initialize(
- QuicDispatcherPeer::GetHelper(dispatcher),
- new ServerDelegate(packet_writer_factory, dispatcher));
server_thread_->Start();
server_started_ = true;
}
@@ -406,15 +437,12 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
}
}
- void AddToCache(StringPiece path,
- int response_code,
- StringPiece response_detail,
- StringPiece body) {
- QuicInMemoryCache::GetInstance()->AddSimpleResponse(
- "www.google.com", path, response_code, response_detail, body);
+ void AddToCache(StringPiece path, int response_code, StringPiece body) {
+ QuicInMemoryCache::GetInstance()->AddSimpleResponse("www.google.com", path,
+ response_code, body);
}
- void SetPacketLossPercentage(int32 loss) {
+ void SetPacketLossPercentage(int32_t loss) {
// TODO(rtenneti): enable when we can do random packet loss tests in
// chrome's tree.
if (loss != 0 && loss != 100)
@@ -430,7 +458,7 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
// server_writer_->set_fake_packet_delay(delay);
}
- void SetReorderPercentage(int32 reorder) {
+ void SetReorderPercentage(int32_t reorder) {
// TODO(rtenneti): enable when we can do random packet reorder tests in
// chrome's tree.
// client_writer_->set_fake_reorder_percentage(reorder);
@@ -441,7 +469,7 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
// being discarded, based on connection stats.
// Calls server_thread_ Pause() and Resume(), which may only be called once
// per test.
- void VerifyCleanConnection(bool had_packet_loss) {
+ void VerifyCleanConnection(bool /*had_packet_loss*/) {
QuicConnectionStats client_stats =
client_->client()->session()->connection()->GetStats();
// TODO(ianswett): Re-enable this check once b/19572432 is fixed.
@@ -449,7 +477,11 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
// EXPECT_EQ(0u, client_stats.packets_lost);
// }
EXPECT_EQ(0u, client_stats.packets_discarded);
- EXPECT_EQ(0u, client_stats.packets_dropped);
+ // When doing 0-RTT with stateless rejects, the encrypted requests cause
+ // a retranmission of the SREJ packets which are dropped by the client.
+ if (!BothSidesSupportStatelessRejects()) {
+ EXPECT_EQ(0u, client_stats.packets_dropped);
+ }
EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
const int num_expected_stateless_rejects =
@@ -490,6 +522,11 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
QuicFlowControllerPeer::SendWindowSize(server));
}
+ // Must be called before Initialize to have effect.
+ void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
+ stream_factory_ = factory;
+ }
+
bool initialized_;
IPEndPoint server_address_;
string server_hostname_;
@@ -504,6 +541,8 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
QuicVersionVector server_supported_versions_;
QuicVersion negotiated_version_;
bool strike_register_no_startup_period_;
+ size_t chlo_multiplier_;
+ QuicTestServer::StreamFactory* stream_factory_;
};
// Run all end to end tests with all supported versions.
@@ -516,6 +555,16 @@ TEST_P(EndToEndTest, SimpleRequestResponse) {
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
+ EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
+ chlo_multiplier_ = 1;
+ ASSERT_TRUE(Initialize());
+
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
+ EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
}
// TODO(rch): figure out how to detect missing v6 supprt (like on the linux
@@ -586,7 +635,7 @@ TEST_P(EndToEndTest, MultipleClients) {
TEST_P(EndToEndTest, RequestOverMultiplePackets) {
// Send a large enough request to guarantee fragmentation.
string huge_request = "/some/path?query=" + string(kMaxPacketSize, '.');
- AddToCache(huge_request, 200, "OK", kBarResponseBody);
+ AddToCache(huge_request, 200, kBarResponseBody);
ASSERT_TRUE(Initialize());
@@ -597,7 +646,7 @@ TEST_P(EndToEndTest, RequestOverMultiplePackets) {
TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
// Send a large enough request to guarantee fragmentation.
string huge_request = "/some/path?query=" + string(kMaxPacketSize, '.');
- AddToCache(huge_request, 200, "OK", kBarResponseBody);
+ AddToCache(huge_request, 200, kBarResponseBody);
ASSERT_TRUE(Initialize());
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
@@ -618,13 +667,12 @@ TEST_P(EndToEndTest, PostMissingBytes) {
// This should be detected as stream fin without complete request,
// triggering an error response.
client_->SendCustomSynchronousRequest(request);
- EXPECT_EQ("bad", client_->response_body());
+ EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
+ client_->response_body());
EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
}
-// TODO(rtenneti): DISABLED_LargePostNoPacketLoss seems to be flaky.
-// http://crbug.com/297040.
-TEST_P(EndToEndTest, DISABLED_LargePostNoPacketLoss) {
+TEST_P(EndToEndTest, LargePostNoPacketLoss) {
ASSERT_TRUE(Initialize());
client_->client()->WaitForCryptoHandshakeConfirmed();
@@ -759,8 +807,14 @@ TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
client_->WaitForResponseForMs(-1);
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
- EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+ if (FLAGS_require_strike_register_or_server_nonce) {
+ EXPECT_EQ(expected_num_hellos_latest_session,
+ client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+ } else {
+ EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+ }
client_->Disconnect();
@@ -811,8 +865,14 @@ TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
client_->WaitForInitialResponse();
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
- EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+ if (FLAGS_require_strike_register_or_server_nonce) {
+ EXPECT_EQ(expected_num_hellos_latest_session,
+ client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+ } else {
+ EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+ }
client_->Disconnect();
@@ -869,8 +929,14 @@ TEST_P(EndToEndTest, LargePostSynchronousRequest) {
client_->WaitForInitialResponse();
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
- EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
- EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+ if (FLAGS_require_strike_register_or_server_nonce) {
+ EXPECT_EQ(expected_num_hellos_latest_session,
+ client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
+ } else {
+ EXPECT_EQ(1, client_->client()->session()->GetNumSentClientHellos());
+ EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
+ }
client_->Disconnect();
@@ -897,15 +963,9 @@ TEST_P(EndToEndTest, LargePostSynchronousRequest) {
TEST_P(EndToEndTest, StatelessRejectWithPacketLoss) {
// In this test, we intentionally drop the first packet from the
// server, which corresponds with the initial REJ/SREJ response from
- // the server. The REJ case will succeed, due to redundancy in the
- // stateful handshake. The SREJ will fail, because there is
- // (currently) no way to recover from a loss of the first SREJ, and
- // all remaining state for the first handshake is black-holed on the
- // time-wait list.
- // TODO(jokulik): Once redundant SREJ support is added, this test
- // should succeed.
+ // the server.
server_writer_->set_fake_drop_first_n_packets(1);
- ASSERT_EQ(!BothSidesSupportStatelessRejects(), Initialize());
+ ASSERT_TRUE(Initialize());
}
TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
@@ -953,10 +1013,10 @@ TEST_P(EndToEndTest, CorrectlyConfiguredFec) {
server_thread_->Resume();
// Verify that client's FEC configuration is correct.
- EXPECT_EQ(expected_policy, QuicSpdySessionPeer::GetHeadersStream(
- client_->client()->session())->fec_policy());
EXPECT_EQ(expected_policy,
- client_->GetOrCreateStream()->fec_policy());
+ QuicSpdySessionPeer::GetHeadersStream(client_->client()->session())
+ ->fec_policy());
+ EXPECT_EQ(expected_policy, client_->GetOrCreateStream()->fec_policy());
}
TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
@@ -993,7 +1053,7 @@ TEST_P(EndToEndTest, DoNotSetResumeWriteAlarmIfConnectionFlowControlBlocked) {
// Ensure both stream and connection level are flow control blocked by setting
// the send window offset to 0.
- const uint64 flow_control_window =
+ const uint64_t flow_control_window =
server_config_.GetInitialStreamFlowControlWindowToSend();
QuicSpdyClientStream* stream = client_->GetOrCreateStream();
QuicSession* session = client_->client()->session();
@@ -1033,11 +1093,34 @@ TEST_P(EndToEndTest, InvalidStream) {
request.AddBody(body, true);
// Force the client to write with a stream ID belonging to a nonexistent
// server-side stream.
- QuicSessionPeer::SetNextStreamId(client_->client()->session(), 2);
+ QuicSessionPeer::SetNextOutgoingStreamId(client_->client()->session(), 2);
client_->SendCustomSynchronousRequest(request);
// EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
- EXPECT_EQ(QUIC_PACKET_FOR_NONEXISTENT_STREAM, client_->connection_error());
+ EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
+ EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
+}
+
+TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
+ ASSERT_TRUE(Initialize());
+ client_->client()->WaitForCryptoHandshakeConfirmed();
+
+ string large_body;
+ GenerateBody(&large_body, 1024 * 1024);
+
+ HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/foo");
+ request.AddBody(large_body, false);
+
+ // Insert an invalid content_length field in request to trigger an early
+ // response from server.
+ request.AddHeader("content-length", "-3");
+
+ request.set_skip_message_validation(true);
+ client_->SendCustomSynchronousRequest(request);
+ EXPECT_EQ("bad", client_->response_body());
+ EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
+ EXPECT_EQ(QUIC_STREAM_NO_ERROR, client_->stream_error());
+ EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
}
// TODO(rch): this test seems to cause net_unittests timeouts :|
@@ -1060,8 +1143,8 @@ TEST_P(EndToEndTest, DISABLED_MultipleTermination) {
// By default the stream protects itself from writes after terminte is set.
// Override this to test the server handling buggy clients.
- ReliableQuicStreamPeer::SetWriteSideClosed(
- false, client_->GetOrCreateStream());
+ ReliableQuicStreamPeer::SetWriteSideClosed(false,
+ client_->GetOrCreateStream());
EXPECT_DFATAL(client_->SendData("eep", true), "Fin already buffered");
}
@@ -1100,9 +1183,15 @@ TEST_P(EndToEndTest, NegotiateMaxOpenStreams) {
}
client_->WaitForResponse();
- EXPECT_FALSE(client_->connected());
- EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
- EXPECT_EQ(QUIC_TOO_MANY_OPEN_STREAMS, client_->connection_error());
+ if (negotiated_version_ <= QUIC_VERSION_27) {
+ EXPECT_FALSE(client_->connected());
+ EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
+ EXPECT_EQ(QUIC_TOO_MANY_OPEN_STREAMS, client_->connection_error());
+ } else {
+ EXPECT_TRUE(client_->connected());
+ EXPECT_EQ(QUIC_REFUSED_STREAM, client_->stream_error());
+ EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
+ }
}
TEST_P(EndToEndTest, NegotiateCongestionControl) {
@@ -1128,7 +1217,7 @@ TEST_P(EndToEndTest, NegotiateCongestionControl) {
EXPECT_EQ(expected_congestion_control_type,
QuicSentPacketManagerPeer::GetSendAlgorithm(
*GetSentPacketManagerFromFirstServerSession())
- ->GetCongestionControlType());
+ ->GetCongestionControlType());
}
TEST_P(EndToEndTest, LimitMaxOpenStreams) {
@@ -1145,7 +1234,7 @@ TEST_P(EndToEndTest, LimitMaxOpenStreams) {
TEST_P(EndToEndTest, ClientSuggestsRTT) {
// Client suggests initial RTT, verify it is used.
- const uint32 kInitialRTT = 20000;
+ const uint32_t kInitialRTT = 20000;
client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT);
ASSERT_TRUE(Initialize());
@@ -1172,8 +1261,8 @@ TEST_P(EndToEndTest, ClientSuggestsRTT) {
TEST_P(EndToEndTest, MaxInitialRTT) {
// Client tries to suggest twice the server's max initial rtt and the server
// uses the max.
- client_config_.SetInitialRoundTripTimeUsToSend(
- 2 * kMaxInitialRoundTripTimeUs);
+ client_config_.SetInitialRoundTripTimeUsToSend(2 *
+ kMaxInitialRoundTripTimeUs);
ASSERT_TRUE(Initialize());
client_->client()->WaitForCryptoHandshakeConfirmed();
@@ -1194,9 +1283,9 @@ TEST_P(EndToEndTest, MaxInitialRTT) {
client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
const RttStats& server_rtt_stats =
*session->connection()->sent_packet_manager().GetRttStats();
- EXPECT_EQ(static_cast<int64>(kMaxInitialRoundTripTimeUs),
+ EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
server_rtt_stats.initial_rtt_us());
- EXPECT_GE(static_cast<int64>(kMaxInitialRoundTripTimeUs),
+ EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
server_rtt_stats.smoothed_rtt().ToMicroseconds());
server_thread_->Resume();
}
@@ -1225,7 +1314,7 @@ TEST_P(EndToEndTest, MinInitialRTT) {
EXPECT_FALSE(
client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
// Expect the default rtt of 100ms.
- EXPECT_EQ(static_cast<int64>(100 * kNumMicrosPerMilli),
+ EXPECT_EQ(static_cast<int64_t>(100 * kNumMicrosPerMilli),
server_sent_packet_manager.GetRttStats()->initial_rtt_us());
// Ensure the bandwidth is valid.
client_sent_packet_manager.BandwidthEstimate();
@@ -1319,7 +1408,7 @@ TEST_P(EndToEndTest, MaxStreamsUberTest) {
GenerateBody(&large_body, 10240);
int max_streams = 100;
- AddToCache("/large_response", 200, "OK", large_body);;
+ AddToCache("/large_response", 200, large_body);
client_->client()->WaitForCryptoHandshakeConfirmed();
SetPacketLossPercentage(10);
@@ -1339,7 +1428,7 @@ TEST_P(EndToEndTest, StreamCancelErrorTest) {
string small_body;
GenerateBody(&small_body, 256);
- AddToCache("/small_response", 200, "OK", small_body);
+ AddToCache("/small_response", 200, small_body);
client_->client()->WaitForCryptoHandshakeConfirmed();
@@ -1372,7 +1461,7 @@ class WrongAddressWriter : public QuicPacketWriterWrapper {
WriteResult WritePacket(const char* buffer,
size_t buf_len,
- const IPAddressNumber& real_self_address,
+ const IPAddressNumber& /*real_self_address*/,
const IPEndPoint& peer_address) override {
// Use wrong address!
return QuicPacketWriterWrapper::WritePacket(
@@ -1459,14 +1548,14 @@ 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
// in the crypto handshake.
- const uint32 kClientStreamIFCW = 123456;
- const uint32 kClientSessionIFCW = 234567;
+ const uint32_t kClientStreamIFCW = 123456;
+ const uint32_t kClientSessionIFCW = 234567;
set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
- uint32 kServerStreamIFCW =
+ uint32_t kServerStreamIFCW =
GetParam().auto_tune_flow_control_window ? 32 * 1024 : 654321;
- uint32 kServerSessionIFCW =
+ uint32_t kServerSessionIFCW =
GetParam().auto_tune_flow_control_window ? 48 * 1024 : 765432;
set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
@@ -1515,9 +1604,9 @@ TEST_P(EndToEndTest, DifferentFlowControlWindows) {
TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
// The special headers and crypto streams should be subject to per-stream flow
// control limits, but should not be subject to connection level flow control.
- const uint32 kStreamIFCW =
+ const uint32_t kStreamIFCW =
GetParam().auto_tune_flow_control_window ? 32 * 1024 : 123456;
- const uint32 kSessionIFCW =
+ const uint32_t kSessionIFCW =
GetParam().auto_tune_flow_control_window ? 48 * 1024 : 234567;
set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
set_client_initial_session_flow_control_receive_window(kSessionIFCW);
@@ -1561,20 +1650,12 @@ TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
QuicFlowController* server_connection_flow_controller =
session->flow_controller();
EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
- server_connection_flow_controller));
+ server_connection_flow_controller));
server_thread_->Resume();
}
TEST_P(EndToEndTest, FlowControlsSynced) {
- const uint32 kClientIFCW = 64 * 1024;
- const uint32 kServerIFCW = 1024 * 1024;
- const float kSessionToStreamRatio = 1.5;
- set_client_initial_stream_flow_control_receive_window(kClientIFCW);
- set_client_initial_session_flow_control_receive_window(kSessionToStreamRatio *
- kClientIFCW);
- set_server_initial_stream_flow_control_receive_window(kServerIFCW);
- set_server_initial_session_flow_control_receive_window(kSessionToStreamRatio *
- kServerIFCW);
+ set_smaller_flow_control_receive_window();
ASSERT_TRUE(Initialize());
@@ -1621,32 +1702,33 @@ TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
QuicDispatcher* dispatcher =
QuicServerPeer::GetDispatcher(server_thread_->server());
QuicSession* session = dispatcher->session_map().begin()->second;
- EXPECT_EQ(0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(
- session).size());
+ EXPECT_EQ(0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(session)
+ .size());
server_thread_->Resume();
}
-// A TestAckNotifierDelegate verifies that its OnAckNotification method has been
+// A TestAckListener verifies that its OnAckNotification method has been
// called exactly once on destruction.
-class TestAckNotifierDelegate : public QuicAckNotifier::DelegateInterface {
+class TestAckListener : public QuicAckListenerInterface {
public:
- TestAckNotifierDelegate() {}
+ explicit TestAckListener(int num_packets) : num_notifications_(num_packets) {}
- void OnAckNotification(int /*num_retransmitted_packets*/,
- int /*num_retransmitted_bytes*/,
- QuicTime::Delta /*delta_largest_observed*/) override {
- ASSERT_FALSE(has_been_notified_);
- has_been_notified_ = true;
+ void OnPacketAcked(int /*acked_bytes*/,
+ QuicTime::Delta /*delta_largest_observed*/) override {
+ ASSERT_LT(0, num_notifications_);
+ num_notifications_--;
}
- bool has_been_notified() const { return has_been_notified_; }
+ void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
+
+ bool has_been_notified() const { return num_notifications_ == 0; }
protected:
// Object is ref counted.
- ~TestAckNotifierDelegate() override { EXPECT_TRUE(has_been_notified_); }
+ ~TestAckListener() override { EXPECT_EQ(0, num_notifications_); }
private:
- bool has_been_notified_ = false;
+ int num_notifications_;
};
TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
@@ -1671,8 +1753,8 @@ TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
request.set_has_complete_message(false);
client_->SendMessage(request);
- // The TestAckNotifierDelegate will cause a failure if not notified.
- scoped_refptr<TestAckNotifierDelegate> delegate(new TestAckNotifierDelegate);
+ // The TestAckListener will cause a failure if not notified.
+ scoped_refptr<TestAckListener> delegate(new TestAckListener(2));
// Test the AckNotifier's ability to track multiple packets by making the
// request body exceed the size of a single packet.
@@ -1686,7 +1768,7 @@ TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
// Send another request to flush out any pending ACKs on the server.
- client_->SendSynchronousRequest(request_string);
+ client_->SendSynchronousRequest("/bar");
// Pause the server to avoid races.
server_thread_->Pause();
@@ -1766,14 +1848,9 @@ TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
// Send the version negotiation packet.
QuicConnectionId incorrect_connection_id =
client_->client()->session()->connection()->connection_id() + 1;
- QuicVersionNegotiationPacket header;
- header.connection_id = incorrect_connection_id;
- header.reset_flag = true;
- header.version_flag = true;
- QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
- Perspective::IS_SERVER);
scoped_ptr<QuicEncryptedPacket> packet(
- framer.BuildVersionNegotiationPacket(header, server_supported_versions_));
+ QuicFramer::BuildVersionNegotiationPacket(incorrect_connection_id,
+ server_supported_versions_));
testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
client_->client()->session()->connection()->set_debug_visitor(&visitor);
EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
@@ -1839,21 +1916,9 @@ TEST_P(EndToEndTest, BadPacketHeaderFlags) {
// invalid public flags
0xFF,
// connection_id
- 0x10,
- 0x32,
- 0x54,
- 0x76,
- 0x98,
- 0xBA,
- 0xDC,
- 0xFE,
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// packet sequence number
- 0xBC,
- 0x9A,
- 0x78,
- 0x56,
- 0x34,
- 0x12,
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
// private flags
0x00,
};
@@ -1912,6 +1977,195 @@ TEST_P(EndToEndTest, BadEncryptedData) {
EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
}
+// A test stream that gives |response_body_| as an error response body.
+class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
+ public:
+ ServerStreamWithErrorResponseBody(QuicStreamId id,
+ QuicSpdySession* session,
+ string response_body)
+ : QuicSimpleServerStream(id, session), response_body_(response_body) {}
+
+ ~ServerStreamWithErrorResponseBody() override {}
+
+ protected:
+ void SendErrorResponse() override {
+ DVLOG(1) << "Sending error response for stream " << id();
+ SpdyHeaderBlock headers;
+ headers[":status"] = "500";
+ headers["content-length"] = base::UintToString(response_body_.size());
+ // This method must call CloseReadSide to cause the test case, StopReading
+ // is not sufficient.
+ ReliableQuicStreamPeer::CloseReadSide(this);
+ SendHeadersAndBody(headers, response_body_);
+ }
+
+ string response_body_;
+};
+
+class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
+ public:
+ explicit StreamWithErrorFactory(string response_body)
+ : response_body_(response_body) {}
+
+ ~StreamWithErrorFactory() override {}
+
+ QuicSimpleServerStream* CreateStream(QuicStreamId id,
+ QuicSpdySession* session) override {
+ return new ServerStreamWithErrorResponseBody(id, session, response_body_);
+ }
+
+ private:
+ string response_body_;
+};
+
+TEST_P(EndToEndTest, EarlyResponseFinRecording) {
+ set_smaller_flow_control_receive_window();
+
+ // 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_close_streams_highest_offset_ (which will never be deleted).
+ // To set up the test condition, the server must do the following in order:
+ // start sending the response and call CloseReadSide
+ // receive the FIN of the request
+ // send the FIN of the response
+
+ string response_body;
+ // The response body must be larger than the flow control window so the server
+ // must receive a window update from the client before it can finish sending
+ // it.
+ uint32_t response_body_size =
+ 2 * client_config_.GetInitialStreamFlowControlWindowToSend();
+ GenerateBody(&response_body, response_body_size);
+
+ StreamWithErrorFactory stream_factory(response_body);
+ SetSpdyStreamFactory(&stream_factory);
+
+ ASSERT_TRUE(Initialize());
+
+ client_->client()->WaitForCryptoHandshakeConfirmed();
+
+ // A POST that gets an early error response, after the headers are received
+ // and before the body is received, due to invalid content-length.
+ HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/garbage");
+ // The body must be large enough that the FIN will be in a different packet
+ // than the end of the headers, but short enough to not require a flow control
+ // update. This allows headers processing to trigger the error response
+ // before the request FIN is processed but receive the request FIN before the
+ // response is sent completely.
+ const uint32_t kRequestBodySize = kMaxPacketSize + 10;
+ string request_body;
+ GenerateBody(&request_body, kRequestBodySize);
+ request.AddBody(request_body, false);
+ // Set an invalid content-length, so the request will receive an early 500
+ // response. Must be done after AddBody, which also sets content-length.
+ request.AddHeader("content-length", "-1");
+ request.set_skip_message_validation(true);
+
+ // Send the request.
+ client_->SendMessage(request);
+ client_->WaitForResponse();
+ EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
+
+ // Pause the server so we can access the server's internals without races.
+ server_thread_->Pause();
+
+ QuicDispatcher* dispatcher =
+ QuicServerPeer::GetDispatcher(server_thread_->server());
+ QuicDispatcher::SessionMap const& map =
+ QuicDispatcherPeer::session_map(dispatcher);
+ QuicDispatcher::SessionMap::const_iterator it = map.begin();
+ EXPECT_TRUE(it != map.end());
+ QuicServerSessionBase* server_session = it->second;
+
+ // The stream is not waiting for the arrival of the peer's final offset.
+ EXPECT_EQ(
+ 0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
+ .size());
+
+ server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, LargePostEarlyResponse) {
+ const uint32_t kWindowSize = 65536;
+ set_client_initial_stream_flow_control_receive_window(kWindowSize);
+ set_client_initial_session_flow_control_receive_window(kWindowSize);
+ set_server_initial_stream_flow_control_receive_window(kWindowSize);
+ set_server_initial_session_flow_control_receive_window(kWindowSize);
+
+ ASSERT_TRUE(Initialize());
+
+ client_->client()->WaitForCryptoHandshakeConfirmed();
+
+ // POST to a URL that gets an early error response, after the headers are
+ // received and before the body is received.
+ HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/garbage");
+ const uint32_t kBodySize = 2 * kWindowSize;
+ // Invalid content-length so the request will receive an early 500 response.
+ request.AddHeader("content-length", "-1");
+ request.set_skip_message_validation(true);
+ request.set_has_complete_message(false);
+
+ // Tell the client to not close the stream if it receives an early response.
+ client_->set_allow_bidirectional_data(true);
+ // Send the headers.
+ client_->SendMessage(request);
+ // Receive the response and let the server close writing.
+ client_->WaitForInitialResponse();
+ EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
+
+ if (negotiated_version_ > QUIC_VERSION_28) {
+ // Receive the reset stream from server on early response.
+ client_->WaitForResponseForMs(100);
+ ReliableQuicStream* stream =
+ client_->client()->session()->GetStream(kClientDataStreamId1);
+ // The stream is reset by server's reset stream.
+ EXPECT_EQ(stream, nullptr);
+ return;
+ }
+
+ // Send a body larger than the stream flow control window.
+ string body;
+ GenerateBody(&body, kBodySize);
+ client_->SendData(body, true);
+
+ // Run the client to let any buffered data be sent.
+ // (This is OK despite already waiting for a response.)
+ client_->WaitForResponse();
+ // There should be no buffered data to write in the client's stream.
+ ReliableQuicStream* stream =
+ client_->client()->session()->GetStream(kClientDataStreamId1);
+ EXPECT_FALSE(stream != nullptr && stream->HasBufferedData());
+}
+
+TEST_P(EndToEndTest, Trailers) {
+ // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
+ ValueRestore<bool> old_flag(&FLAGS_quic_supports_trailers, true);
+ ASSERT_TRUE(Initialize());
+ client_->client()->WaitForCryptoHandshakeConfirmed();
+
+ // Set reordering to ensure that Trailers arriving before body is ok.
+ SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+ SetReorderPercentage(30);
+
+ // Add a response with headers, body, and trailers.
+ const string kBody = "body content";
+
+ SpdyHeaderBlock headers;
+ headers[":status"] = "200";
+ headers[":version"] = "HTTP/1.1";
+ headers["content-length"] = IntToString(kBody.size());
+
+ SpdyHeaderBlock trailers;
+ trailers["some-trailing-header"] = "trailing-header-value";
+
+ QuicInMemoryCache::GetInstance()->AddResponse(
+ "www.google.com", "/trailer_url", headers, kBody, trailers);
+
+ EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url"));
+ EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
+ EXPECT_EQ(trailers, client_->response_trailers());
+}
+
} // namespace
} // namespace test
} // namespace tools
diff --git a/chromium/net/tools/quic/quic_client.cc b/chromium/net/tools/quic/quic_client.cc
index ed3585020a3..2ecfe6d73a9 100644
--- a/chromium/net/tools/quic/quic_client.cc
+++ b/chromium/net/tools/quic/quic_client.cc
@@ -12,7 +12,8 @@
#include <unistd.h>
#include "base/logging.h"
-#include "net/base/net_util.h"
+#include "base/run_loop.h"
+#include "net/base/sockaddr_storage.h"
#include "net/quic/crypto/quic_random.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_data_reader.h"
@@ -44,24 +45,30 @@ void QuicClient::ClientQuicDataToResend::Resend() {
QuicClient::QuicClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
- EpollServer* epoll_server)
+ EpollServer* epoll_server,
+ ProofVerifier* proof_verifier)
: QuicClient(server_address,
server_id,
supported_versions,
QuicConfig(),
- epoll_server) {}
+ epoll_server,
+ proof_verifier) {}
QuicClient::QuicClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
const QuicConfig& config,
- EpollServer* epoll_server)
- : QuicClientBase(server_id, supported_versions, config),
+ EpollServer* epoll_server,
+ ProofVerifier* proof_verifier)
+ : QuicClientBase(server_id,
+ supported_versions,
+ config,
+ new QuicEpollConnectionHelper(epoll_server),
+ proof_verifier),
server_address_(server_address),
local_port_(0),
epoll_server_(epoll_server),
fd_(-1),
- helper_(CreateQuicConnectionHelper()),
initialized_(false),
packets_dropped_(0),
overflow_supported_(false),
@@ -70,7 +77,8 @@ QuicClient::QuicClient(IPEndPoint server_address,
QuicClient::~QuicClient() {
if (connected()) {
- session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY);
+ session()->connection()->SendConnectionCloseWithDetails(
+ QUIC_PEER_GOING_AWAY, "Client being torn down");
}
STLDeleteElements(&data_to_resend_on_connect_);
@@ -84,8 +92,8 @@ bool QuicClient::Initialize() {
// If an initial flow control window has not explicitly been set, then use the
// same values that Chrome uses.
- const uint32 kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
- const uint32 kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
+ const uint32_t kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
+ const uint32_t kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
if (config()->GetInitialStreamFlowControlWindowToSend() ==
kMinimumFlowControlSendWindow) {
config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize);
@@ -165,10 +173,9 @@ bool QuicClient::CreateUDPSocket() {
sockaddr_storage raw_addr;
socklen_t raw_addr_len = sizeof(raw_addr);
CHECK(client_address_.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr),
- &raw_addr_len));
- rc = bind(fd_,
- reinterpret_cast<const sockaddr*>(&raw_addr),
- sizeof(raw_addr));
+ &raw_addr_len));
+ rc =
+ bind(fd_, reinterpret_cast<const sockaddr*>(&raw_addr), sizeof(raw_addr));
if (rc < 0) {
LOG(ERROR) << "Bind failed: " << strerror(errno);
return false;
@@ -224,8 +231,6 @@ void QuicClient::StartConnect() {
QuicPacketWriter* writer = CreateQuicPacketWriter();
- DummyPacketWriterFactory factory(writer);
-
if (connected_or_attempting_connect()) {
// Before we destroy the last session and create a new one, gather its stats
// and update the stats for the overall connection.
@@ -241,9 +246,8 @@ void QuicClient::StartConnect() {
}
CreateQuicClientSession(new QuicConnection(
- GetNextConnectionId(), server_address_, helper_.get(), factory,
- /* owns_writer= */ false, Perspective::IS_CLIENT, server_id().is_https(),
- supported_versions()));
+ GetNextConnectionId(), server_address_, helper(), writer,
+ /* owns_writer= */ false, Perspective::IS_CLIENT, supported_versions()));
// Reset |writer_| after |session()| so that the old writer outlives the old
// session.
@@ -257,7 +261,8 @@ void QuicClient::Disconnect() {
DCHECK(initialized_);
if (connected()) {
- session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY);
+ session()->connection()->SendConnectionCloseWithDetails(
+ QUIC_PEER_GOING_AWAY, "Client disconnecting");
}
STLDeleteElements(&data_to_resend_on_connect_);
STLDeleteElements(&data_sent_before_handshake_);
@@ -289,9 +294,8 @@ void QuicClient::SendRequest(const BalsaHeaders& headers,
return;
}
stream->set_visitor(this);
- stream->SendRequest(
- SpdyBalsaUtils::RequestHeadersToSpdyHeaders(headers, stream->version()),
- body, fin);
+ stream->SendRequest(SpdyBalsaUtils::RequestHeadersToSpdyHeaders(headers),
+ body, fin);
if (FLAGS_enable_quic_stateless_reject_support) {
// Record this in case we need to resend.
auto new_headers = new BalsaHeaders;
@@ -317,12 +321,12 @@ void QuicClient::MaybeAddQuicDataToResend(QuicDataToResend* data_to_resend) {
data_sent_before_handshake_.push_back(data_to_resend);
}
-void QuicClient::SendRequestAndWaitForResponse(
- const BalsaHeaders& headers,
- StringPiece body,
- bool fin) {
+void QuicClient::SendRequestAndWaitForResponse(const BalsaHeaders& headers,
+ StringPiece body,
+ bool fin) {
SendRequest(headers, body, fin);
- while (WaitForEvents()) {}
+ while (WaitForEvents()) {
+ }
}
void QuicClient::SendRequestsAndWaitForResponse(
@@ -332,13 +336,15 @@ void QuicClient::SendRequestsAndWaitForResponse(
headers.SetRequestFirstlineFromStringPieces("GET", url_list[i], "HTTP/1.1");
SendRequest(headers, "", true);
}
- while (WaitForEvents()) {}
+ while (WaitForEvents()) {
+ }
}
bool QuicClient::WaitForEvents() {
DCHECK(connected());
epoll_server_->WaitForEventsAndExecuteCallbacks();
+ base::RunLoop().RunUntilIdle();
DCHECK(session() != nullptr);
if (!connected() &&
@@ -368,7 +374,6 @@ bool QuicClient::MigrateSocket(const IPAddressNumber& new_host) {
session()->connection()->SetSelfAddress(client_address_);
QuicPacketWriter* writer = CreateQuicPacketWriter();
- DummyPacketWriterFactory factory(writer);
set_writer(writer);
session()->connection()->SetQuicPacketWriter(writer, false);
@@ -391,17 +396,17 @@ void QuicClient::OnEvent(int fd, EpollEvent* event) {
}
}
-void QuicClient::OnClose(QuicDataStream* stream) {
+void QuicClient::OnClose(QuicSpdyStream* stream) {
DCHECK(stream != nullptr);
QuicSpdyClientStream* client_stream =
static_cast<QuicSpdyClientStream*>(stream);
BalsaHeaders headers;
SpdyBalsaUtils::SpdyHeadersToResponseHeaders(client_stream->headers(),
- &headers, stream->version());
+ &headers);
if (response_listener_.get() != nullptr) {
- response_listener_->OnCompleteResponse(
- stream->id(), headers, client_stream->data());
+ response_listener_->OnCompleteResponse(stream->id(), headers,
+ client_stream->data());
}
// Store response headers and body.
@@ -409,6 +414,7 @@ void QuicClient::OnClose(QuicDataStream* stream) {
latest_response_code_ = headers.parsed_response_code();
headers.DumpHeadersToString(&latest_response_headers_);
latest_response_body_ = client_stream->data();
+ latest_response_trailers_ = client_stream->trailers().DebugString();
}
}
@@ -427,8 +433,9 @@ const string& QuicClient::latest_response_body() const {
return latest_response_body_;
}
-QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() {
- return new QuicEpollConnectionHelper(epoll_server_);
+const string& QuicClient::latest_response_trailers() const {
+ LOG_IF(DFATAL, !store_response_) << "Response not stored!";
+ return latest_response_trailers_;
}
QuicPacketWriter* QuicClient::CreateQuicPacketWriter() {
diff --git a/chromium/net/tools/quic/quic_client.h b/chromium/net/tools/quic/quic_client.h
index d2fdd21cdce..29febd7675d 100644
--- a/chromium/net/tools/quic/quic_client.h
+++ b/chromium/net/tools/quic/quic_client.h
@@ -8,15 +8,17 @@
#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_
#define NET_TOOLS_QUIC_QUIC_CLIENT_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_config.h"
-#include "net/quic/quic_data_stream.h"
+#include "net/quic/quic_spdy_stream.h"
#include "net/tools/balsa/balsa_headers.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/quic/quic_client_base.h"
@@ -35,7 +37,7 @@ class QuicClientPeer;
class QuicClient : public QuicClientBase,
public EpollCallbackInterface,
- public QuicDataStream::Visitor {
+ public QuicSpdyStream::Visitor {
public:
class ResponseListener {
public:
@@ -79,12 +81,14 @@ class QuicClient : public QuicClientBase,
QuicClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
- EpollServer* epoll_server);
+ EpollServer* epoll_server,
+ ProofVerifier* proof_verifier);
QuicClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
const QuicConfig& config,
- EpollServer* epoll_server);
+ EpollServer* epoll_server,
+ ProofVerifier* proof_verifier);
~QuicClient() override;
@@ -116,8 +120,7 @@ class QuicClient : public QuicClientBase,
// Sends a request simple GET for each URL in |args|, and then waits for
// each to complete.
- void SendRequestsAndWaitForResponse(
- const std::vector<std::string>& url_list);
+ void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list);
// Migrate to a new socket during an active connection.
bool MigrateSocket(const IPAddressNumber& new_host);
@@ -132,8 +135,8 @@ class QuicClient : public QuicClientBase,
void OnUnregistration(int fd, bool replaced) override {}
void OnShutdown(EpollServer* eps, int fd) override {}
- // QuicDataStream::Visitor
- void OnClose(QuicDataStream* stream) override;
+ // QuicSpdyStream::Visitor
+ void OnClose(QuicSpdyStream* stream) override;
// If the crypto handshake has not yet been confirmed, adds the data to the
// queue of data to resend if the client receives a stateless reject.
@@ -164,9 +167,9 @@ class QuicClient : public QuicClientBase,
size_t latest_response_code() const;
const std::string& latest_response_headers() const;
const std::string& latest_response_body() const;
+ const std::string& latest_response_trailers() const;
protected:
- virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper();
virtual QuicPacketWriter* CreateQuicPacketWriter();
virtual int ReadPacket(char* buffer,
@@ -231,9 +234,6 @@ class QuicClient : public QuicClientBase,
// UDP socket.
int fd_;
- // Helper to be used by created connections.
- scoped_ptr<QuicEpollConnectionHelper> helper_;
-
// Listens for full responses.
scoped_ptr<ResponseListener> response_listener_;
@@ -252,10 +252,12 @@ class QuicClient : public QuicClientBase,
bool store_response_;
// HTTP response code from most recent response.
size_t latest_response_code_;
- // HTTP headers from most recent response.
+ // HTTP/2 headers from most recent response.
std::string latest_response_headers_;
// Body of most recent response.
std::string latest_response_body_;
+ // HTTP/2 trailers from most recent response.
+ std::string latest_response_trailers_;
// Keeps track of any data sent before the handshake.
std::vector<QuicDataToResend*> data_sent_before_handshake_;
diff --git a/chromium/net/tools/quic/quic_client_base.cc b/chromium/net/tools/quic/quic_client_base.cc
index b40afe16b4f..5c8daa26af3 100644
--- a/chromium/net/tools/quic/quic_client_base.cc
+++ b/chromium/net/tools/quic/quic_client_base.cc
@@ -12,9 +12,13 @@ namespace tools {
QuicClientBase::QuicClientBase(const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
- const QuicConfig& config)
+ const QuicConfig& config,
+ QuicConnectionHelperInterface* helper,
+ ProofVerifier* proof_verifier)
: server_id_(server_id),
config_(config),
+ crypto_config_(proof_verifier),
+ helper_(helper),
supported_versions_(supported_versions),
initial_max_packet_length_(0),
num_stateless_rejects_received_(0),
@@ -32,15 +36,8 @@ bool QuicClientBase::Initialize() {
return true;
}
-QuicClientBase::DummyPacketWriterFactory::DummyPacketWriterFactory(
- QuicPacketWriter* writer)
- : writer_(writer) {}
-
-QuicClientBase::DummyPacketWriterFactory::~DummyPacketWriterFactory() {}
-
-QuicPacketWriter* QuicClientBase::DummyPacketWriterFactory::Create(
- QuicConnection* /*connection*/) const {
- return writer_;
+ProofVerifier* QuicClientBase::proof_verifier() const {
+ return crypto_config_.proof_verifier();
}
QuicClientSession* QuicClientBase::CreateQuicClientSession(
@@ -63,7 +60,7 @@ QuicSpdyClientStream* QuicClientBase::CreateReliableClientStream() {
return nullptr;
}
- return session_->CreateOutgoingDynamicStream();
+ return session_->CreateOutgoingDynamicStream(kDefaultPriority);
}
void QuicClientBase::WaitForStreamToClose(QuicStreamId id) {
diff --git a/chromium/net/tools/quic/quic_client_base.h b/chromium/net/tools/quic/quic_client_base.h
index 50582c33572..2ca8acac3ee 100644
--- a/chromium/net/tools/quic/quic_client_base.h
+++ b/chromium/net/tools/quic/quic_client_base.h
@@ -10,7 +10,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/log/net_log.h"
@@ -33,21 +33,11 @@ namespace tools {
class QuicClientBase {
public:
- // A packet writer factory that always returns the same writer.
- class DummyPacketWriterFactory : public QuicConnection::PacketWriterFactory {
- public:
- explicit DummyPacketWriterFactory(QuicPacketWriter* writer);
- ~DummyPacketWriterFactory() override;
-
- QuicPacketWriter* Create(QuicConnection* connection) const override;
-
- private:
- QuicPacketWriter* writer_;
- };
-
QuicClientBase(const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
- const QuicConfig& config);
+ const QuicConfig& config,
+ QuicConnectionHelperInterface* helper,
+ ProofVerifier* proof_verifier);
~QuicClientBase();
@@ -89,13 +79,6 @@ class QuicClientBase {
crypto_config_.set_user_agent_id(user_agent_id);
}
- // SetProofVerifier sets the ProofVerifier that will be used to verify the
- // server's certificate and takes ownership of |verifier|.
- void SetProofVerifier(ProofVerifier* verifier) {
- // TODO(rtenneti): We should set ProofVerifier in QuicClientSession.
- crypto_config_.SetProofVerifier(verifier);
- }
-
// SetChannelIDSource sets a ChannelIDSource that will be called, when the
// server supports channel IDs, to obtain a channel ID for signing a message
// proving possession of the channel ID. This object takes ownership of
@@ -167,6 +150,8 @@ class QuicClientBase {
return initial_max_packet_length_;
}
+ ProofVerifier* proof_verifier() const;
+
protected:
virtual QuicClientSession* CreateQuicClientSession(
QuicConnection* connection);
@@ -184,6 +169,8 @@ class QuicClientBase {
// connection ID).
virtual QuicConnectionId GenerateNewConnectionId();
+ QuicConnectionHelperInterface* helper() { return helper_.get(); }
+
private:
// |server_id_| is a tuple (hostname, port, is_https) of the server.
QuicServerId server_id_;
@@ -193,6 +180,9 @@ class QuicClientBase {
QuicConfig config_;
QuicCryptoClientConfig crypto_config_;
+ // Helper to be used by created connections. Needs to outlive |session_|.
+ scoped_ptr<QuicConnectionHelperInterface> helper_;
+
// Writer used to actually send packets to the wire. Needs to outlive
// |session_|.
scoped_ptr<QuicPacketWriter> writer_;
diff --git a/chromium/net/tools/quic/quic_client_bin.cc b/chromium/net/tools/quic/quic_client_bin.cc
index 7fb9dc49298..41f75cbc994 100644
--- a/chromium/net/tools/quic/quic_client_bin.cc
+++ b/chromium/net/tools/quic/quic_client_bin.cc
@@ -19,7 +19,7 @@
// quic_client https://www.google.com --port=443 --host=${IP}
//
// Use a specific version:
-// quic_client http://www.google.com --version=23 --host=${IP}
+// quic_client http://www.google.com --quic_version=23 --host=${IP}
//
// Send a POST instead of a GET:
// quic_client http://www.google.com --body="this is a POST body" --host=${IP}
@@ -43,16 +43,20 @@
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/privacy_mode.h"
#include "net/cert/cert_verifier.h"
+#include "net/cert/multi_log_ct_verifier.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_server_id.h"
#include "net/quic/quic_utils.h"
@@ -65,6 +69,8 @@
using base::StringPiece;
using net::CertVerifier;
+using net::CTVerifier;
+using net::MultiLogCTVerifier;
using net::ProofVerifierChromium;
using net::TransportSecurityState;
using std::cout;
@@ -76,16 +82,19 @@ using std::endl;
// The IP or hostname the quic client will connect to.
string FLAGS_host = "";
// The port to connect to.
-int32 FLAGS_port = 80;
+int32_t FLAGS_port = 0;
// If set, send a POST with this body.
string FLAGS_body = "";
+// If set, contents are converted from hex to ascii, before sending as body of
+// a POST. e.g. --body_hex=\"68656c6c6f\"
+string FLAGS_body_hex = "";
// A semicolon separated list of key:value pairs to add to request headers.
string FLAGS_headers = "";
// Set to true for a quieter output experience.
bool FLAGS_quiet = false;
// QUIC version to speak, e.g. 21. If not set, then all available versions are
// offered in the handshake.
-int32 FLAGS_quic_version = -1;
+int32_t FLAGS_quic_version = -1;
// If true, a version mismatch in the handshake is not considered a failure.
// Useful for probing a server to determine if it speaks any version of QUIC.
bool FLAGS_version_mismatch_ok = false;
@@ -93,9 +102,55 @@ bool FLAGS_version_mismatch_ok = false;
// response, otherwise a failure.
bool FLAGS_redirect_is_success = true;
// Initial MTU of the connection.
-int32 FLAGS_initial_mtu = 0;
+int32_t FLAGS_initial_mtu = 0;
-int main(int argc, char *argv[]) {
+class FakeCertVerifier : public net::CertVerifier {
+ public:
+ int Verify(net::X509Certificate* cert,
+ const std::string& hostname,
+ const std::string& ocsp_response,
+ int flags,
+ net::CRLSet* crl_set,
+ net::CertVerifyResult* verify_result,
+ const net::CompletionCallback& callback,
+ scoped_ptr<net::CertVerifier::Request>* out_req,
+ const net::BoundNetLog& net_log) override {
+ return net::OK;
+ }
+
+ // Returns true if this CertVerifier supports stapled OCSP responses.
+ bool SupportsOCSPStapling() override { return false; }
+};
+
+static bool DecodeHexString(const base::StringPiece& hex, std::string* bytes) {
+ bytes->clear();
+ if (hex.empty())
+ return true;
+ std::vector<uint8_t> v;
+ if (!base::HexStringToBytes(hex.as_string(), &v))
+ return false;
+ if (!v.empty())
+ bytes->assign(reinterpret_cast<const char*>(&v[0]), v.size());
+ return true;
+};
+
+// Converts binary data into an ASCII string. Each character in the resulting
+// string is preceeded by a space, and replaced with a '.' if not printable.
+string BinaryToAscii(const string& binary) {
+ string out = "";
+ for (const unsigned char c : binary) {
+ // Leading space.
+ out += " ";
+ if (isprint(c)) {
+ out += c;
+ } else {
+ out += '.';
+ }
+ }
+ return out;
+}
+
+int main(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv);
base::CommandLine* line = base::CommandLine::ForCurrentProcess();
const base::CommandLine::StringVector& urls = line->GetArgs();
@@ -104,6 +159,8 @@ int main(int argc, char *argv[]) {
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
CHECK(logging::InitLogging(settings));
+ FLAGS_quic_supports_trailers = true;
+
if (line->HasSwitch("h") || line->HasSwitch("help") || urls.empty()) {
const char* help_str =
"Usage: quic_client [options] <url>\n"
@@ -115,6 +172,7 @@ int main(int argc, char *argv[]) {
"connect to\n"
"--port=<port> specify the port to connect to\n"
"--body=<body> specify the body to post\n"
+ "--body_hex=<body_hex> specify the body_hex to be printed out\n"
"--headers=<headers> specify a semicolon separated list of "
"key:value pairs to add to request headers\n"
"--quiet specify for a quieter output experience\n"
@@ -124,7 +182,8 @@ int main(int argc, char *argv[]) {
"--redirect_is_success if specified an HTTP response code of 3xx "
"is considered to be a successful response, otherwise a failure\n"
"--initial_mtu=<initial_mtu> specify the initial MTU of the connection"
- "\n";
+ "\n"
+ "--disable-certificate-verification do not verify certificates\n";
cout << help_str;
exit(0);
}
@@ -140,6 +199,9 @@ int main(int argc, char *argv[]) {
if (line->HasSwitch("body")) {
FLAGS_body = line->GetSwitchValueASCII("body");
}
+ if (line->HasSwitch("body_hex")) {
+ FLAGS_body_hex = line->GetSwitchValueASCII("body_hex");
+ }
if (line->HasSwitch("headers")) {
FLAGS_headers = line->GetSwitchValueASCII("headers");
}
@@ -176,51 +238,59 @@ int main(int argc, char *argv[]) {
<< " initial_mtu: " << FLAGS_initial_mtu;
base::AtExitManager exit_manager;
+ base::MessageLoopForIO message_loop;
// Determine IP address to connect to from supplied hostname.
net::IPAddressNumber ip_addr;
- // TODO(rtenneti): GURL's doesn't support default_protocol argument, thus
- // protocol is required in the URL.
GURL url(urls[0]);
string host = FLAGS_host;
if (host.empty()) {
host = url.host();
}
+ int port = FLAGS_port;
+ if (port == 0) {
+ port = url.EffectiveIntPort();
+ }
if (!net::ParseIPLiteralToNumber(host, &ip_addr)) {
net::AddressList addresses;
int rv = net::tools::SynchronousHostResolver::Resolve(host, &addresses);
if (rv != net::OK) {
- LOG(ERROR) << "Unable to resolve '" << host << "' : "
- << net::ErrorToShortString(rv);
+ LOG(ERROR) << "Unable to resolve '" << host
+ << "' : " << net::ErrorToShortString(rv);
return 1;
}
ip_addr = addresses[0].address();
}
- string host_port = net::IPAddressToStringWithPort(ip_addr, FLAGS_port);
+ string host_port = net::IPAddressToStringWithPort(ip_addr, port);
VLOG(1) << "Resolved " << host << " to " << host_port << endl;
// Build the client, and try to connect.
net::EpollServer epoll_server;
- net::QuicServerId server_id(url.host(), FLAGS_port, /*is_https=*/true,
+ net::QuicServerId server_id(url.host(), url.EffectiveIntPort(),
net::PRIVACY_MODE_DISABLED);
net::QuicVersionVector versions = net::QuicSupportedVersions();
if (FLAGS_quic_version != -1) {
versions.clear();
versions.push_back(static_cast<net::QuicVersion>(FLAGS_quic_version));
}
+ // For secure QUIC we need to verify the cert chain.
+ scoped_ptr<CertVerifier> cert_verifier(CertVerifier::CreateDefault());
+ if (line->HasSwitch("disable-certificate-verification")) {
+ cert_verifier.reset(new FakeCertVerifier());
+ }
+ scoped_ptr<TransportSecurityState> transport_security_state(
+ new TransportSecurityState);
+ transport_security_state.reset(new TransportSecurityState);
+ scoped_ptr<CTVerifier> ct_verifier(new MultiLogCTVerifier());
+ ProofVerifierChromium* proof_verifier = new ProofVerifierChromium(
+ cert_verifier.get(), nullptr, transport_security_state.get(),
+ ct_verifier.get());
net::tools::QuicClient client(net::IPEndPoint(ip_addr, FLAGS_port), server_id,
- versions, &epoll_server);
- scoped_ptr<CertVerifier> cert_verifier;
- scoped_ptr<TransportSecurityState> transport_security_state;
+ versions, &epoll_server, proof_verifier);
client.set_initial_max_packet_length(
FLAGS_initial_mtu != 0 ? FLAGS_initial_mtu : net::kDefaultMaxPacketSize);
- // For secure QUIC we need to verify the cert chain.
- cert_verifier = CertVerifier::CreateDefault();
- transport_security_state.reset(new TransportSecurityState);
- client.SetProofVerifier(new ProofVerifierChromium(
- cert_verifier.get(), nullptr, transport_security_state.get()));
if (!client.Initialize()) {
cerr << "Failed to initialize client." << endl;
return 1;
@@ -239,10 +309,17 @@ int main(int argc, char *argv[]) {
}
cout << "Connected to " << host_port << endl;
+ // Construct the string body from flags, if provided.
+ string body = FLAGS_body;
+ if (!FLAGS_body_hex.empty()) {
+ DCHECK(FLAGS_body.empty()) << "Only set one of --body and --body_hex.";
+ DecodeHexString(FLAGS_body_hex, &body);
+ }
+
// Construct a GET or POST request for supplied URL.
net::BalsaHeaders headers;
- headers.SetRequestFirstlineFromStringPieces(
- FLAGS_body.empty() ? "GET" : "POST", url.spec(), "HTTP/1.1");
+ headers.SetRequestFirstlineFromStringPieces(body.empty() ? "GET" : "POST",
+ url.spec(), "HTTP/1.1");
// Append any additional headers supplied on the command line.
for (const std::string& header :
@@ -268,22 +345,36 @@ int main(int argc, char *argv[]) {
// Send the request.
net::SpdyHeaderBlock header_block =
- net::tools::SpdyBalsaUtils::RequestHeadersToSpdyHeaders(
- headers, client.session()->connection()->version());
- client.SendRequestAndWaitForResponse(headers, FLAGS_body, /*fin=*/true);
+ net::tools::SpdyBalsaUtils::RequestHeadersToSpdyHeaders(headers);
+ client.SendRequestAndWaitForResponse(headers, body, /*fin=*/true);
// Print request and response details.
if (!FLAGS_quiet) {
cout << "Request:" << endl;
- cout << "headers:" << endl;
- for (const auto& kv : header_block) {
- cout << " " << kv.first << ": " << kv.second << endl;
+ cout << "headers:" << header_block.DebugString();
+ if (!FLAGS_body_hex.empty()) {
+ // Print the user provided hex, rather than binary body.
+ cout << "body hex: " << FLAGS_body_hex << endl;
+ string bytes;
+ DecodeHexString(FLAGS_body_hex, &bytes);
+ cout << "body ascii: " << BinaryToAscii(bytes) << endl;
+ } else {
+ cout << "body: " << body << endl;
}
- cout << "body: " << FLAGS_body << endl;
cout << endl;
cout << "Response:" << endl;
cout << "headers: " << client.latest_response_headers() << endl;
- cout << "body: " << client.latest_response_body() << endl;
+ string response_body = client.latest_response_body();
+ if (!FLAGS_body_hex.empty()) {
+ // Assume response is binary data.
+ string bytes;
+ DecodeHexString(response_body, &bytes);
+ cout << "body hex: " << bytes << endl;
+ cout << "body ascii: " << BinaryToAscii(response_body) << endl;
+ } else {
+ cout << "body: " << response_body << endl;
+ }
+ cout << "trailers: " << client.latest_response_trailers() << endl;
}
size_t response_code = client.latest_response_code();
diff --git a/chromium/net/tools/quic/quic_client_session.cc b/chromium/net/tools/quic/quic_client_session.cc
index 99371b261fc..4ae4851af8a 100644
--- a/chromium/net/tools/quic/quic_client_session.cc
+++ b/chromium/net/tools/quic/quic_client_session.cc
@@ -20,15 +20,15 @@ QuicClientSession::QuicClientSession(const QuicConfig& config,
const QuicServerId& server_id,
QuicCryptoClientConfig* crypto_config)
: QuicClientSessionBase(connection, config),
- crypto_stream_(new QuicCryptoClientStream(
- server_id,
- this,
- new ProofVerifyContextChromium(0, BoundNetLog()),
- crypto_config)),
- respect_goaway_(true) {
-}
+ server_id_(server_id),
+ crypto_config_(crypto_config),
+ respect_goaway_(true) {}
+
+QuicClientSession::~QuicClientSession() {}
-QuicClientSession::~QuicClientSession() {
+void QuicClientSession::Initialize() {
+ crypto_stream_.reset(CreateQuicCryptoStream());
+ QuicClientSessionBase::Initialize();
}
void QuicClientSession::OnProofValid(
@@ -37,14 +37,15 @@ void QuicClientSession::OnProofValid(
void QuicClientSession::OnProofVerifyDetailsAvailable(
const ProofVerifyDetails& /*verify_details*/) {}
-QuicSpdyClientStream* QuicClientSession::CreateOutgoingDynamicStream() {
+QuicSpdyClientStream* QuicClientSession::CreateOutgoingDynamicStream(
+ SpdyPriority priority) {
if (!crypto_stream_->encryption_established()) {
DVLOG(1) << "Encryption not active so no outgoing stream created.";
return nullptr;
}
- if (GetNumOpenStreams() >= get_max_open_streams()) {
+ if (GetNumOpenOutgoingStreams() >= get_max_open_streams()) {
DVLOG(1) << "Failed to create a new outgoing stream. "
- << "Already " << GetNumOpenStreams() << " open.";
+ << "Already " << GetNumOpenOutgoingStreams() << " open.";
return nullptr;
}
if (goaway_received() && respect_goaway_) {
@@ -53,15 +54,16 @@ QuicSpdyClientStream* QuicClientSession::CreateOutgoingDynamicStream() {
return nullptr;
}
QuicSpdyClientStream* stream = CreateClientStream();
+ stream->SetPriority(priority);
ActivateStream(stream);
return stream;
}
QuicSpdyClientStream* QuicClientSession::CreateClientStream() {
- return new QuicSpdyClientStream(GetNextStreamId(), this);
+ return new QuicSpdyClientStream(GetNextOutgoingStreamId(), this);
}
-QuicCryptoClientStream* QuicClientSession::GetCryptoStream() {
+QuicCryptoClientStreamBase* QuicClientSession::GetCryptoStream() {
return crypto_stream_.get();
}
@@ -74,11 +76,18 @@ int QuicClientSession::GetNumSentClientHellos() const {
return crypto_stream_->num_sent_client_hellos();
}
-QuicDataStream* QuicClientSession::CreateIncomingDynamicStream(
+QuicSpdyStream* QuicClientSession::CreateIncomingDynamicStream(
QuicStreamId id) {
DLOG(ERROR) << "Server push not supported";
return nullptr;
}
+QuicCryptoClientStreamBase* QuicClientSession::CreateQuicCryptoStream() {
+ return new QuicCryptoClientStream(
+ server_id_, this, new ProofVerifyContextChromium(0, BoundNetLog()),
+ crypto_config_);
+}
+
} // namespace tools
+
} // namespace net
diff --git a/chromium/net/tools/quic/quic_client_session.h b/chromium/net/tools/quic/quic_client_session.h
index 93187d06c5f..6d25b592cb1 100644
--- a/chromium/net/tools/quic/quic_client_session.h
+++ b/chromium/net/tools/quic/quic_client_session.h
@@ -9,7 +9,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/quic/quic_client_session_base.h"
#include "net/quic/quic_crypto_client_stream.h"
#include "net/quic/quic_protocol.h"
@@ -23,6 +23,10 @@ class ReliableQuicStream;
namespace tools {
+// The maximum time a promises stream can be reserved without being
+// claimed by a client request.
+const int64_t kPushPromiseTimeoutSecs = 60;
+
class QuicClientSession : public QuicClientSessionBase {
public:
QuicClientSession(const QuicConfig& config,
@@ -30,10 +34,13 @@ class QuicClientSession : public QuicClientSessionBase {
const QuicServerId& server_id,
QuicCryptoClientConfig* crypto_config);
~QuicClientSession() override;
+ // Set up the QuicClientSession. Must be called prior to use.
+ void Initialize() override;
// QuicSession methods:
- QuicSpdyClientStream* CreateOutgoingDynamicStream() override;
- QuicCryptoClientStream* GetCryptoStream() override;
+ QuicSpdyClientStream* CreateOutgoingDynamicStream(
+ SpdyPriority priority) override;
+ QuicCryptoClientStreamBase* GetCryptoStream() override;
// QuicClientSessionBase methods:
void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
@@ -54,7 +61,10 @@ class QuicClientSession : public QuicClientSessionBase {
protected:
// QuicSession methods:
- QuicDataStream* CreateIncomingDynamicStream(QuicStreamId id) override;
+ QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override;
+
+ // Create the crypto stream. Called by Initialize()
+ virtual QuicCryptoClientStreamBase* CreateQuicCryptoStream();
// Unlike CreateOutgoingDynamicStream, which applies a bunch of sanity checks,
// this simply returns a new QuicSpdyClientStream. This may be used by
@@ -62,8 +72,14 @@ class QuicClientSession : public QuicClientSessionBase {
// but wish to use the sanity checks in CreateOutgoingDynamicStream.
virtual QuicSpdyClientStream* CreateClientStream();
+ const QuicServerId& server_id() { return server_id_; }
+ QuicCryptoClientConfig* crypto_config() { return crypto_config_; }
+
private:
- scoped_ptr<QuicCryptoClientStream> crypto_stream_;
+ bool ShouldCreateIncomingDynamicStream(QuicStreamId id);
+ scoped_ptr<QuicCryptoClientStreamBase> crypto_stream_;
+ QuicServerId server_id_;
+ QuicCryptoClientConfig* crypto_config_;
// If this is set to false, the client will ignore server GOAWAYs and allow
// the creation of streams regardless of the high chance they will fail.
diff --git a/chromium/net/tools/quic/quic_client_session_test.cc b/chromium/net/tools/quic/quic_client_session_test.cc
index 0c6ab8736a2..7b43f963e35 100644
--- a/chromium/net/tools/quic/quic_client_session_test.cc
+++ b/chromium/net/tools/quic/quic_client_session_test.cc
@@ -22,6 +22,7 @@ using net::test::ConstructMisFramedEncryptedPacket;
using net::test::CryptoTestUtils;
using net::test::DefaultQuicConfig;
using net::test::MockConnection;
+using net::test::MockConnectionHelper;
using net::test::PacketSavingConnection;
using net::test::QuicConnectionPeer;
using net::test::QuicPacketCreatorPeer;
@@ -40,13 +41,14 @@ namespace tools {
namespace test {
namespace {
-const char kServerHostname[] = "www.example.org";
-const uint16 kPort = 80;
+const char kServerHostname[] = "test.example.com";
+const uint16_t kPort = 80;
class ToolsQuicClientSessionTest
: public ::testing::TestWithParam<QuicVersion> {
protected:
- ToolsQuicClientSessionTest() {
+ ToolsQuicClientSessionTest()
+ : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) {
Initialize();
// Advance the time, because timers do not like uninitialized times.
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -54,27 +56,32 @@ class ToolsQuicClientSessionTest
void Initialize() {
session_.reset();
- connection_ = new PacketSavingConnection(Perspective::IS_CLIENT,
+ connection_ = new PacketSavingConnection(&helper_, Perspective::IS_CLIENT,
SupportedVersions(GetParam()));
session_.reset(new QuicClientSession(
DefaultQuicConfig(), connection_,
- QuicServerId(kServerHostname, kPort, false, PRIVACY_MODE_DISABLED),
+ QuicServerId(kServerHostname, kPort, PRIVACY_MODE_DISABLED),
&crypto_config_));
session_->Initialize();
}
void CompleteCryptoHandshake() {
session_->CryptoConnect();
- CryptoTestUtils::HandshakeWithFakeServer(
- connection_, session_->GetCryptoStream());
+ QuicCryptoClientStream* stream =
+ static_cast<QuicCryptoClientStream*>(session_->GetCryptoStream());
+ CryptoTestUtils::FakeServerOptions options;
+ CryptoTestUtils::HandshakeWithFakeServer(&helper_, connection_, stream,
+ options);
}
+ QuicCryptoClientConfig crypto_config_;
+ MockConnectionHelper helper_;
PacketSavingConnection* connection_;
scoped_ptr<QuicClientSession> session_;
- QuicCryptoClientConfig crypto_config_;
};
-INSTANTIATE_TEST_CASE_P(Tests, ToolsQuicClientSessionTest,
+INSTANTIATE_TEST_CASE_P(Tests,
+ ToolsQuicClientSessionTest,
::testing::ValuesIn(QuicSupportedVersions()));
TEST_P(ToolsQuicClientSessionTest, CryptoConnect) {
@@ -93,7 +100,8 @@ TEST_P(ToolsQuicClientSessionTest, NoEncryptionAfterInitialEncryption) {
// established and will allow streams to be created.
session_->CryptoConnect();
EXPECT_TRUE(session_->IsEncryptionEstablished());
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
+ QuicSpdyClientStream* stream =
+ session_->CreateOutgoingDynamicStream(kDefaultPriority);
DCHECK_NE(kCryptoStreamId, stream->id());
EXPECT_TRUE(stream != nullptr);
@@ -109,7 +117,8 @@ TEST_P(ToolsQuicClientSessionTest, NoEncryptionAfterInitialEncryption) {
QuicPacketCreatorPeer::GetEncryptionLevel(
QuicConnectionPeer::GetPacketCreator(connection_)));
// Verify that no new streams may be created.
- EXPECT_TRUE(session_->CreateOutgoingDynamicStream() == nullptr);
+ EXPECT_TRUE(session_->CreateOutgoingDynamicStream(kDefaultPriority) ==
+ nullptr);
// Verify that no data may be send on existing streams.
char data[] = "hello world";
struct iovec iov = {data, arraysize(data)};
@@ -120,7 +129,29 @@ TEST_P(ToolsQuicClientSessionTest, NoEncryptionAfterInitialEncryption) {
EXPECT_EQ(0u, consumed.bytes_consumed);
}
-TEST_P(ToolsQuicClientSessionTest, MaxNumStreams) {
+TEST_P(ToolsQuicClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
+ EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber());
+
+ session_->config()->SetMaxStreamsPerConnection(1, 1);
+
+ // Initialize crypto before the client session will create a stream.
+ CompleteCryptoHandshake();
+
+ QuicSpdyClientStream* stream =
+ session_->CreateOutgoingDynamicStream(kDefaultPriority);
+ ASSERT_TRUE(stream);
+ EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
+
+ // Close the stream, but without having received a FIN or a RST_STREAM
+ // and check that a new one can not be created.
+ session_->CloseStream(stream->id());
+ EXPECT_EQ(1u, session_->GetNumOpenOutgoingStreams());
+
+ stream = session_->CreateOutgoingDynamicStream(kDefaultPriority);
+ EXPECT_FALSE(stream);
+}
+
+TEST_P(ToolsQuicClientSessionTest, MaxNumStreamsWithRst) {
EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber());
session_->config()->SetMaxStreamsPerConnection(1, 1);
@@ -128,13 +159,19 @@ TEST_P(ToolsQuicClientSessionTest, MaxNumStreams) {
// Initialize crypto before the client session will create a stream.
CompleteCryptoHandshake();
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
+ QuicSpdyClientStream* stream =
+ session_->CreateOutgoingDynamicStream(kDefaultPriority);
ASSERT_TRUE(stream);
- EXPECT_FALSE(session_->CreateOutgoingDynamicStream());
+ EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
- // Close a stream and ensure I can now open a new one.
+ // Close the stream and receive an RST frame to remove the unfinished stream
session_->CloseStream(stream->id());
- stream = session_->CreateOutgoingDynamicStream();
+ session_->OnRstStream(QuicRstStreamFrame(
+ stream->id(), AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()),
+ 0));
+ // Check that a new one can be created.
+ EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
+ stream = session_->CreateOutgoingDynamicStream(kDefaultPriority);
EXPECT_TRUE(stream);
}
@@ -145,7 +182,7 @@ TEST_P(ToolsQuicClientSessionTest, GoAwayReceived) {
// streams.
session_->connection()->OnGoAwayFrame(
QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
- EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream());
+ EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream(kDefaultPriority));
}
TEST_P(ToolsQuicClientSessionTest, SetFecProtectionFromConfig) {
@@ -161,9 +198,11 @@ TEST_P(ToolsQuicClientSessionTest, SetFecProtectionFromConfig) {
// Verify that headers stream is always protected and data streams are
// optionally protected.
- EXPECT_EQ(FEC_PROTECT_ALWAYS, QuicSpdySessionPeer::GetHeadersStream(
- session_.get())->fec_policy());
- QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
+ EXPECT_EQ(
+ FEC_PROTECT_ALWAYS,
+ QuicSpdySessionPeer::GetHeadersStream(session_.get())->fec_policy());
+ QuicSpdyClientStream* stream =
+ session_->CreateOutgoingDynamicStream(kDefaultPriority);
ASSERT_TRUE(stream);
EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy());
}
diff --git a/chromium/net/tools/quic/quic_client_test.cc b/chromium/net/tools/quic/quic_client_test.cc
index e3a7270536f..8ab4a65e05e 100644
--- a/chromium/net/tools/quic/quic_client_test.cc
+++ b/chromium/net/tools/quic/quic_client_test.cc
@@ -7,13 +7,14 @@
#include <dirent.h>
#include <stdio.h>
-#include "base/basictypes.h"
#include "base/strings/string_util.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "testing/gtest/include/gtest/gtest.h"
using net::EpollServer;
+using net::test::CryptoTestUtils;
namespace net {
namespace tools {
@@ -36,17 +37,23 @@ int NumOpenFDs() {
// Creates a new QuicClient and Initializes it. Caller is responsible for
// deletion.
-QuicClient* CreateAndInitializeQuicClient(EpollServer* eps, uint16 port) {
+QuicClient* CreateAndInitializeQuicClient(EpollServer* eps, uint16_t port) {
IPEndPoint server_address(IPEndPoint(net::test::Loopback4(), port));
- QuicServerId server_id("hostname", server_address.port(), false,
+ QuicServerId server_id("hostname", server_address.port(),
PRIVACY_MODE_DISABLED);
QuicVersionVector versions = QuicSupportedVersions();
- QuicClient* client = new QuicClient(server_address, server_id, versions, eps);
+ QuicClient* client =
+ new QuicClient(server_address, server_id, versions, eps,
+ CryptoTestUtils::ProofVerifierForTesting());
EXPECT_TRUE(client->Initialize());
return client;
}
TEST(QuicClientTest, DoNotLeakFDs) {
+ // Create a ProofVerifier before counting the number of open FDs to work
+ // around some ASAN weirdness.
+ delete CryptoTestUtils::ProofVerifierForTesting();
+
// Make sure that the QuicClient doesn't leak FDs. Doing so could cause port
// exhaustion in long running processes which repeatedly create clients.
@@ -56,7 +63,7 @@ TEST(QuicClientTest, DoNotLeakFDs) {
// Create a number of clients, initialize them, and verify this has resulted
// in additional FDs being opened.
- const int kNumClients = 5;
+ const int kNumClients = 50;
for (int i = 0; i < kNumClients; ++i) {
scoped_ptr<QuicClient> client(
CreateAndInitializeQuicClient(&eps, net::test::kTestPort + i));
diff --git a/chromium/net/tools/quic/quic_default_packet_writer.cc b/chromium/net/tools/quic/quic_default_packet_writer.cc
index e7b50880cdc..c5e48750c69 100644
--- a/chromium/net/tools/quic/quic_default_packet_writer.cc
+++ b/chromium/net/tools/quic/quic_default_packet_writer.cc
@@ -10,8 +10,7 @@ namespace net {
namespace tools {
QuicDefaultPacketWriter::QuicDefaultPacketWriter(int fd)
- : fd_(fd),
- write_blocked_(false) {}
+ : fd_(fd), write_blocked_(false) {}
QuicDefaultPacketWriter::~QuicDefaultPacketWriter() {}
@@ -21,8 +20,8 @@ WriteResult QuicDefaultPacketWriter::WritePacket(
const IPAddressNumber& self_address,
const IPEndPoint& peer_address) {
DCHECK(!IsWriteBlocked());
- WriteResult result = QuicSocketUtils::WritePacket(
- fd_, buffer, buf_len, self_address, peer_address);
+ WriteResult result = QuicSocketUtils::WritePacket(fd_, buffer, buf_len,
+ self_address, peer_address);
if (result.status == WRITE_STATUS_BLOCKED) {
write_blocked_ = true;
}
diff --git a/chromium/net/tools/quic/quic_default_packet_writer.h b/chromium/net/tools/quic/quic_default_packet_writer.h
index f231dea4a68..f423ff0c834 100644
--- a/chromium/net/tools/quic/quic_default_packet_writer.h
+++ b/chromium/net/tools/quic/quic_default_packet_writer.h
@@ -5,7 +5,9 @@
#ifndef NET_TOOLS_QUIC_QUIC_DEFAULT_PACKET_WRITER_H_
#define NET_TOOLS_QUIC_QUIC_DEFAULT_PACKET_WRITER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_packet_writer.h"
@@ -34,9 +36,7 @@ class QuicDefaultPacketWriter : public QuicPacketWriter {
void set_fd(int fd) { fd_ = fd; }
protected:
- void set_write_blocked(bool is_blocked) {
- write_blocked_ = is_blocked;
- }
+ void set_write_blocked(bool is_blocked) { write_blocked_ = is_blocked; }
int fd() { return fd_; }
private:
diff --git a/chromium/net/tools/quic/quic_dispatcher.cc b/chromium/net/tools/quic/quic_dispatcher.cc
index a4efa69f730..a02955b469e 100644
--- a/chromium/net/tools/quic/quic_dispatcher.cc
+++ b/chromium/net/tools/quic/quic_dispatcher.cc
@@ -8,10 +8,13 @@
#include "base/debug/stack_trace.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/stl_util.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
#include "net/tools/quic/quic_per_connection_packet_writer.h"
+#include "net/tools/quic/quic_simple_server_session.h"
#include "net/tools/quic/quic_time_wait_list_manager.h"
namespace net {
@@ -21,20 +24,13 @@ namespace tools {
using std::make_pair;
using base::StringPiece;
-// The threshold size for the session map, over which the dispatcher will start
-// sending stateless rejects (SREJ), rather than stateful rejects (REJ) to
-// clients who support them. If -1, stateless rejects will not be sent. If 0,
-// the server will only send stateless rejects to clients who support them.
-int32 FLAGS_quic_session_map_threshold_for_stateless_rejects = -1;
-
namespace {
// An alarm that informs the QuicDispatcher to delete old sessions.
class DeleteSessionsAlarm : public QuicAlarm::Delegate {
public:
explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher) {
- }
+ : dispatcher_(dispatcher) {}
QuicTime OnAlarm() override {
dispatcher_->DeleteSessions();
@@ -54,8 +50,7 @@ class DeleteSessionsAlarm : public QuicAlarm::Delegate {
class QuicDispatcher::QuicFramerVisitor : public QuicFramerVisitorInterface {
public:
explicit QuicFramerVisitor(QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher),
- connection_id_(0) {}
+ : dispatcher_(dispatcher), connection_id_(0) {}
// QuicFramerVisitorInterface implementation
void OnPacket() override {}
@@ -139,7 +134,7 @@ class QuicDispatcher::QuicFramerVisitor : public QuicFramerVisitorInterface {
DCHECK(false);
return false;
}
- void OnFecData(const QuicFecData& /*fec*/) override { DCHECK(false); }
+ void OnFecData(StringPiece /*redundancy*/) override { DCHECK(false); }
void OnPacketComplete() override { DCHECK(false); }
private:
@@ -149,37 +144,15 @@ class QuicDispatcher::QuicFramerVisitor : public QuicFramerVisitorInterface {
QuicConnectionId connection_id_;
};
-QuicPacketWriter* QuicDispatcher::DefaultPacketWriterFactory::Create(
- QuicPacketWriter* writer,
- QuicConnection* connection) {
- return new QuicPerConnectionPacketWriter(writer, connection);
-}
-
-QuicDispatcher::PacketWriterFactoryAdapter::PacketWriterFactoryAdapter(
- QuicDispatcher* dispatcher)
- : dispatcher_(dispatcher) {}
-
-QuicDispatcher::PacketWriterFactoryAdapter::~PacketWriterFactoryAdapter() {}
-
-QuicPacketWriter* QuicDispatcher::PacketWriterFactoryAdapter::Create(
- QuicConnection* connection) const {
- return dispatcher_->packet_writer_factory_->Create(
- dispatcher_->writer_.get(),
- connection);
-}
-
QuicDispatcher::QuicDispatcher(const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
const QuicVersionVector& supported_versions,
- PacketWriterFactory* packet_writer_factory,
QuicConnectionHelperInterface* helper)
: config_(config),
crypto_config_(crypto_config),
helper_(helper),
delete_sessions_alarm_(
helper_->CreateAlarm(new DeleteSessionsAlarm(this))),
- packet_writer_factory_(packet_writer_factory),
- connection_writer_factory_(this),
supported_versions_(supported_versions),
current_packet_(nullptr),
framer_(supported_versions,
@@ -209,7 +182,7 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
current_packet_ = &packet;
// ProcessPacket will cause the packet to be dispatched in
// OnUnauthenticatedPublicHeader, or sent to the time wait list manager
- // in OnAuthenticatedHeader.
+ // in OnUnauthenticatedHeader.
framer_.ProcessPacket(packet);
// TODO(rjshade): Return a status describing if/why a packet was dropped,
// and log somehow. Maybe expose as a varz.
@@ -285,7 +258,7 @@ void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
// This connection ID is already in time-wait state.
time_wait_list_manager_->ProcessPacket(
current_server_address_, current_client_address_,
- header.public_header.connection_id, header.packet_packet_number,
+ header.public_header.connection_id, header.packet_number,
*current_packet_);
return;
}
@@ -296,23 +269,12 @@ void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
switch (fate) {
case kFateProcess: {
// Create a session and process the packet.
- QuicServerSession* session = CreateQuicSession(
- connection_id, current_server_address_, current_client_address_);
+ QuicServerSessionBase* session =
+ CreateQuicSession(connection_id, current_client_address_);
DVLOG(1) << "Created new session for " << connection_id;
- session_map_.insert(make_pair(connection_id, session));
+ session_map_.insert(std::make_pair(connection_id, session));
session->connection()->ProcessUdpPacket(
current_server_address_, current_client_address_, *current_packet_);
-
- if (FLAGS_enable_quic_stateless_reject_support &&
- session->UsingStatelessRejectsIfPeerSupported() &&
- session->PeerSupportsStatelessRejects() &&
- !session->IsCryptoHandshakeConfirmed()) {
- DVLOG(1) << "Removing new session for " << connection_id
- << " because the session is in stateless reject mode and"
- << " encryption has not been established.";
- session->connection()->CloseConnection(
- QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, /* from_peer */ false);
- }
break;
}
case kFateTimeWait:
@@ -327,7 +289,7 @@ void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
header.public_header.connection_id));
time_wait_list_manager_->ProcessPacket(
current_server_address_, current_client_address_,
- header.public_header.connection_id, header.packet_packet_number,
+ header.public_header.connection_id, header.packet_number,
*current_packet_);
break;
case kFateDrop:
@@ -359,8 +321,8 @@ QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
// Check that the sequence numer is within the range that the client is
// expected to send before receiving a response from the server.
- if (header.packet_packet_number == kInvalidPacketNumber ||
- header.packet_packet_number > kMaxReasonableInitialPacketNumber) {
+ if (header.packet_number == kInvalidPacketNumber ||
+ header.packet_number > kMaxReasonableInitialPacketNumber) {
return kFateTimeWait;
}
@@ -370,13 +332,15 @@ QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
void QuicDispatcher::CleanUpSession(SessionMap::iterator it,
bool should_close_statelessly) {
QuicConnection* connection = it->second->connection();
- QuicEncryptedPacket* connection_close_packet =
- connection->ReleaseConnectionClosePacket();
+
write_blocked_list_.erase(connection);
- DCHECK(!should_close_statelessly || !connection_close_packet);
+ if (should_close_statelessly) {
+ DCHECK(connection->termination_packets() != nullptr &&
+ !connection->termination_packets()->empty());
+ }
time_wait_list_manager_->AddConnectionIdToTimeWait(
it->first, connection->version(), should_close_statelessly,
- connection_close_packet);
+ connection->termination_packets());
session_map_.erase(it);
}
@@ -404,8 +368,9 @@ bool QuicDispatcher::HasPendingWrites() const {
void QuicDispatcher::Shutdown() {
while (!session_map_.empty()) {
- QuicServerSession* session = session_map_.begin()->second;
- session->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY);
+ QuicServerSessionBase* session = session_map_.begin()->second;
+ session->connection()->SendConnectionCloseWithDetails(
+ QUIC_PEER_GOING_AWAY, "Server shutdown imminent");
// Validate that the session removes itself from the session map on close.
DCHECK(session_map_.empty() || session_map_.begin()->second != session);
}
@@ -416,17 +381,16 @@ void QuicDispatcher::OnConnectionClosed(QuicConnectionId connection_id,
QuicErrorCode error) {
SessionMap::iterator it = session_map_.find(connection_id);
if (it == session_map_.end()) {
- LOG(DFATAL) << "ConnectionId " << connection_id
- << " does not exist in the session map. "
- << "Error: " << QuicUtils::ErrorToString(error);
- LOG(DFATAL) << base::debug::StackTrace().ToString();
+ QUIC_BUG << "ConnectionId " << connection_id
+ << " does not exist in the session map. Error: "
+ << QuicUtils::ErrorToString(error);
+ QUIC_BUG << base::debug::StackTrace().ToString();
return;
}
- DVLOG_IF(1, error != QUIC_NO_ERROR) << "Closing connection ("
- << connection_id
- << ") due to error: "
- << QuicUtils::ErrorToString(error);
+ DVLOG_IF(1, error != QUIC_NO_ERROR)
+ << "Closing connection (" << connection_id
+ << ") due to error: " << QuicUtils::ErrorToString(error);
if (closed_session_list_.empty()) {
delete_sessions_alarm_->Cancel();
@@ -441,8 +405,8 @@ void QuicDispatcher::OnConnectionClosed(QuicConnectionId connection_id,
void QuicDispatcher::OnWriteBlocked(
QuicBlockedWriterInterface* blocked_writer) {
if (!writer_->IsWriteBlocked()) {
- LOG(DFATAL) <<
- "QuicDispatcher::OnWriteBlocked called when the writer is not blocked.";
+ LOG(DFATAL) << "QuicDispatcher::OnWriteBlocked called when the writer is "
+ "not blocked.";
// Return without adding the connection to the blocked list, to avoid
// infinite loops in OnCanWrite.
return;
@@ -460,35 +424,26 @@ void QuicDispatcher::OnConnectionRemovedFromTimeWaitList(
DVLOG(1) << "Connection " << connection_id << " removed from time wait list.";
}
-QuicServerSession* QuicDispatcher::CreateQuicSession(
+QuicServerSessionBase* QuicDispatcher::CreateQuicSession(
QuicConnectionId connection_id,
- const IPEndPoint& server_address,
const IPEndPoint& client_address) {
- // The QuicServerSession takes ownership of |connection| below.
+ // The QuicServerSessionBase takes ownership of |connection| below.
QuicConnection* connection = new QuicConnection(
- connection_id, client_address, helper_.get(), connection_writer_factory_,
- /* owns_writer= */ true, Perspective::IS_SERVER,
- crypto_config_->HasProofSource(), supported_versions_);
+ connection_id, client_address, helper_.get(), CreatePerConnectionWriter(),
+ /* owns_writer= */ true, Perspective::IS_SERVER, supported_versions_);
- QuicServerSession* session =
- new QuicServerSession(config_, connection, this, crypto_config_);
+ QuicServerSessionBase* session =
+ new QuicSimpleServerSession(config_, connection, this, crypto_config_);
session->Initialize();
- if (FLAGS_quic_session_map_threshold_for_stateless_rejects != -1 &&
- session_map_.size() >=
- static_cast<size_t>(
- FLAGS_quic_session_map_threshold_for_stateless_rejects)) {
- session->set_use_stateless_rejects_if_peer_supported(true);
- }
return session;
}
QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
// TODO(rjshade): The QuicTimeWaitListManager should take ownership of the
// per-connection packet writer.
- time_wait_list_writer_.reset(
- packet_writer_factory_->Create(writer_.get(), nullptr));
+ time_wait_list_writer_.reset(CreatePerConnectionWriter());
return new QuicTimeWaitListManager(time_wait_list_writer_.get(), this,
- helper_.get(), supported_versions());
+ helper_.get());
}
bool QuicDispatcher::HandlePacketForTimeWait(
@@ -508,6 +463,10 @@ bool QuicDispatcher::HandlePacketForTimeWait(
return true;
}
+QuicPacketWriter* QuicDispatcher::CreatePerConnectionWriter() {
+ return new QuicPerConnectionPacketWriter(writer_.get());
+}
+
void QuicDispatcher::SetLastError(QuicErrorCode error) {
last_error_ = error;
}
diff --git a/chromium/net/tools/quic/quic_dispatcher.h b/chromium/net/tools/quic/quic_dispatcher.h
index 1fec49427cb..3c5b9c90307 100644
--- a/chromium/net/tools/quic/quic_dispatcher.h
+++ b/chromium/net/tools/quic/quic_dispatcher.h
@@ -10,22 +10,22 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/base/linked_hash_map.h"
#include "net/quic/quic_blocked_writer_interface.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_protocol.h"
-#include "net/tools/quic/quic_server_session.h"
+#include "net/tools/quic/quic_server_session_base.h"
#include "net/tools/quic/quic_time_wait_list_manager.h"
namespace net {
class QuicConfig;
class QuicCryptoServerConfig;
-class QuicServerSession;
+class QuicServerSessionBase;
namespace tools {
@@ -33,8 +33,6 @@ namespace test {
class QuicDispatcherPeer;
} // namespace test
-extern int32 FLAGS_quic_session_map_threshold_for_stateless_rejects;
-
class ProcessPacketInterface {
public:
virtual ~ProcessPacketInterface() {}
@@ -47,28 +45,6 @@ class QuicDispatcher : public QuicServerSessionVisitor,
public ProcessPacketInterface,
public QuicBlockedWriterInterface {
public:
- // Creates per-connection packet writers out of the QuicDispatcher's shared
- // QuicPacketWriter. The per-connection writers' IsWriteBlocked() state must
- // always be the same as the shared writer's IsWriteBlocked(), or else the
- // QuicDispatcher::OnCanWrite logic will not work. (This will hopefully be
- // cleaned up for bug 16950226.)
- class PacketWriterFactory {
- public:
- virtual ~PacketWriterFactory() {}
-
- virtual QuicPacketWriter* Create(QuicPacketWriter* writer,
- QuicConnection* connection) = 0;
- };
-
- // Creates ordinary QuicPerConnectionPacketWriter instances.
- class DefaultPacketWriterFactory : public PacketWriterFactory {
- public:
- ~DefaultPacketWriterFactory() override {}
-
- QuicPacketWriter* Create(QuicPacketWriter* writer,
- QuicConnection* connection) override;
- };
-
// Ideally we'd have a linked_hash_set: the boolean is unused.
typedef linked_hash_map<QuicBlockedWriterInterface*, bool> WriteBlockedList;
@@ -79,7 +55,6 @@ class QuicDispatcher : public QuicServerSessionVisitor,
QuicDispatcher(const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
const QuicVersionVector& supported_versions,
- PacketWriterFactory* packet_writer_factory,
QuicConnectionHelperInterface* helper);
~QuicDispatcher() override;
@@ -119,7 +94,7 @@ class QuicDispatcher : public QuicServerSessionVisitor,
void OnConnectionRemovedFromTimeWaitList(
QuicConnectionId connection_id) override;
- typedef base::hash_map<QuicConnectionId, QuicServerSession*> SessionMap;
+ typedef base::hash_map<QuicConnectionId, QuicServerSessionBase*> SessionMap;
const SessionMap& session_map() const { return session_map_; }
@@ -133,18 +108,13 @@ class QuicDispatcher : public QuicServerSessionVisitor,
// sent with unique packet numbers.)
static const QuicPacketNumber kMaxReasonableInitialPacketNumber = 100;
static_assert(kMaxReasonableInitialPacketNumber >=
- kInitialCongestionWindowSecure + 10,
+ kInitialCongestionWindow + 10,
"kMaxReasonableInitialPacketNumber is unreasonably small "
- "relative to kInitialCongestionWindowSecure.");
- static_assert(kMaxReasonableInitialPacketNumber >=
- kInitialCongestionWindowInsecure + 10,
- "kMaxReasonableInitialPacketNumber is unreasonably small "
- "relative to kInitialCongestionWindowInsecure.");
+ "relative to kInitialCongestionWindow.");
protected:
- virtual QuicServerSession* CreateQuicSession(
+ virtual QuicServerSessionBase* CreateQuicSession(
QuicConnectionId connection_id,
- const IPEndPoint& server_address,
const IPEndPoint& client_address);
// Called by |framer_visitor_| when the public header has been parsed.
@@ -182,15 +152,9 @@ class QuicDispatcher : public QuicServerSessionVisitor,
return supported_versions_;
}
- const IPEndPoint& current_server_address() {
- return current_server_address_;
- }
- const IPEndPoint& current_client_address() {
- return current_client_address_;
- }
- const QuicEncryptedPacket& current_packet() {
- return *current_packet_;
- }
+ const IPEndPoint& current_server_address() { return current_server_address_; }
+ const IPEndPoint& current_client_address() { return current_client_address_; }
+ const QuicEncryptedPacket& current_packet() { return *current_packet_; }
const QuicConfig& config() const { return config_; }
@@ -202,9 +166,12 @@ class QuicDispatcher : public QuicServerSessionVisitor,
QuicPacketWriter* writer() { return writer_.get(); }
- const QuicConnection::PacketWriterFactory& connection_writer_factory() {
- return connection_writer_factory_;
- }
+ // Creates per-connection packet writers out of the QuicDispatcher's shared
+ // QuicPacketWriter. The per-connection writers' IsWriteBlocked() state must
+ // always be the same as the shared writer's IsWriteBlocked(), or else the
+ // QuicDispatcher::OnCanWrite logic will not work. (This will hopefully be
+ // cleaned up for bug 16950226.)
+ virtual QuicPacketWriter* CreatePerConnectionWriter();
void SetLastError(QuicErrorCode error);
@@ -212,21 +179,6 @@ class QuicDispatcher : public QuicServerSessionVisitor,
class QuicFramerVisitor;
friend class net::tools::test::QuicDispatcherPeer;
- // An adapter that creates packet writers using the dispatcher's
- // PacketWriterFactory and shared writer. Essentially, it just curries the
- // writer argument away from QuicDispatcher::PacketWriterFactory.
- class PacketWriterFactoryAdapter :
- public QuicConnection::PacketWriterFactory {
- public:
- explicit PacketWriterFactoryAdapter(QuicDispatcher* dispatcher);
- ~PacketWriterFactoryAdapter() override;
-
- QuicPacketWriter* Create(QuicConnection* connection) const override;
-
- private:
- QuicDispatcher* dispatcher_;
- };
-
// Called by |framer_visitor_| when the private header has been parsed
// of a data packet that is destined for the time wait manager.
void OnUnauthenticatedHeader(const QuicPacketHeader& header);
@@ -251,7 +203,7 @@ class QuicDispatcher : public QuicServerSessionVisitor,
scoped_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
// The list of closed but not-yet-deleted sessions.
- std::vector<QuicServerSession*> closed_session_list_;
+ std::vector<QuicServerSessionBase*> closed_session_list_;
// The helper used for all connections.
scoped_ptr<QuicConnectionHelperInterface> helper_;
@@ -265,12 +217,6 @@ class QuicDispatcher : public QuicServerSessionVisitor,
// A per-connection writer that is passed to the time wait list manager.
scoped_ptr<QuicPacketWriter> time_wait_list_writer_;
- // Used to create per-connection packet writers, not |writer_| itself.
- scoped_ptr<PacketWriterFactory> packet_writer_factory_;
-
- // Passed in to QuicConnection for it to create the per-connection writers
- PacketWriterFactoryAdapter connection_writer_factory_;
-
// This vector contains QUIC versions which we currently support.
// This should be ordered such that the highest supported version is the first
// element, with subsequent elements in descending order (versions can be
diff --git a/chromium/net/tools/quic/quic_dispatcher_test.cc b/chromium/net/tools/quic/quic_dispatcher_test.cc
index c45fe3a8b59..bbf797eeefc 100644
--- a/chromium/net/tools/quic/quic_dispatcher_test.cc
+++ b/chromium/net/tools/quic/quic_dispatcher_test.cc
@@ -7,14 +7,16 @@
#include <ostream>
#include <string>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/crypto/quic_random.h"
-#include "net/quic/quic_connection_helper.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_crypto_stream.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/quic/quic_epoll_connection_helper.h"
@@ -28,9 +30,10 @@
using base::StringPiece;
using net::EpollServer;
using net::test::ConstructEncryptedPacket;
+using net::test::CryptoTestUtils;
using net::test::MockConnection;
+using net::test::MockConnectionHelper;
using net::test::ValueRestore;
-using net::test::TestWriterFactory;
using std::string;
using std::vector;
using testing::DoAll;
@@ -44,27 +47,35 @@ namespace tools {
namespace test {
namespace {
-class TestQuicSpdyServerSession : public QuicServerSession {
+class TestQuicSpdyServerSession : public QuicServerSessionBase {
public:
TestQuicSpdyServerSession(const QuicConfig& config,
QuicConnection* connection,
const QuicCryptoServerConfig* crypto_config)
- : QuicServerSession(config, connection, nullptr, crypto_config),
- crypto_stream_(QuicServerSession::GetCryptoStream()) {}
+ : QuicServerSessionBase(config, connection, nullptr, crypto_config),
+ crypto_stream_(QuicServerSessionBase::GetCryptoStream()) {}
~TestQuicSpdyServerSession() override{};
MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer));
- MOCK_METHOD1(CreateIncomingDynamicStream, QuicDataStream*(QuicStreamId id));
- MOCK_METHOD0(CreateOutgoingDynamicStream, QuicDataStream*());
+ MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
+ MOCK_METHOD1(CreateOutgoingDynamicStream,
+ QuicSpdyStream*(SpdyPriority priority));
+
+ QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) override {
+ return new QuicCryptoServerStream(crypto_config, this);
+ }
void SetCryptoStream(QuicCryptoServerStream* crypto_stream) {
crypto_stream_ = crypto_stream;
}
- QuicCryptoServerStream* GetCryptoStream() override { return crypto_stream_; }
+ QuicCryptoServerStreamBase* GetCryptoStream() override {
+ return crypto_stream_;
+ }
private:
- QuicCryptoServerStream* crypto_stream_;
+ QuicCryptoServerStreamBase* crypto_stream_;
DISALLOW_COPY_AND_ASSIGN(TestQuicSpdyServerSession);
};
@@ -77,13 +88,11 @@ class TestDispatcher : public QuicDispatcher {
: QuicDispatcher(config,
crypto_config,
QuicSupportedVersions(),
- new QuicDispatcher::DefaultPacketWriterFactory(),
new QuicEpollConnectionHelper(eps)) {}
- MOCK_METHOD3(CreateQuicSession,
- QuicServerSession*(QuicConnectionId connection_id,
- const IPEndPoint& server_address,
- const IPEndPoint& client_address));
+ MOCK_METHOD2(CreateQuicSession,
+ QuicServerSessionBase*(QuicConnectionId connection_id,
+ const IPEndPoint& client_address));
using QuicDispatcher::current_server_address;
using QuicDispatcher::current_client_address;
@@ -96,8 +105,9 @@ class TestDispatcher : public QuicDispatcher {
class MockServerConnection : public MockConnection {
public:
MockServerConnection(QuicConnectionId connection_id,
+ MockConnectionHelper* helper,
QuicDispatcher* dispatcher)
- : MockConnection(connection_id, Perspective::IS_SERVER),
+ : MockConnection(connection_id, helper, Perspective::IS_SERVER),
dispatcher_(dispatcher) {}
void UnregisterOnConnectionClosed() {
@@ -109,18 +119,20 @@ class MockServerConnection : public MockConnection {
QuicDispatcher* dispatcher_;
};
-QuicServerSession* CreateSession(QuicDispatcher* dispatcher,
- const QuicConfig& config,
- QuicConnectionId connection_id,
- const IPEndPoint& client_address,
- const QuicCryptoServerConfig* crypto_config,
- TestQuicSpdyServerSession** session) {
+QuicServerSessionBase* CreateSession(
+ QuicDispatcher* dispatcher,
+ const QuicConfig& config,
+ QuicConnectionId connection_id,
+ const IPEndPoint& client_address,
+ MockConnectionHelper* helper,
+ const QuicCryptoServerConfig* crypto_config,
+ TestQuicSpdyServerSession** session) {
MockServerConnection* connection =
- new MockServerConnection(connection_id, dispatcher);
+ new MockServerConnection(connection_id, helper, dispatcher);
*session = new TestQuicSpdyServerSession(config, connection, crypto_config);
connection->set_visitor(*session);
- ON_CALL(*connection, SendConnectionClose(_)).WillByDefault(
- WithoutArgs(Invoke(
+ ON_CALL(*connection, SendConnectionCloseWithDetails(_, _))
+ .WillByDefault(WithoutArgs(Invoke(
connection, &MockServerConnection::UnregisterOnConnectionClosed)));
EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()),
ProcessUdpPacket(_, client_address, _));
@@ -133,7 +145,8 @@ class QuicDispatcherTest : public ::testing::Test {
QuicDispatcherTest()
: helper_(&eps_),
crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance()),
+ QuicRandom::GetInstance(),
+ CryptoTestUtils::ProofSourceForTesting()),
dispatcher_(config_, &crypto_config_, &eps_),
time_wait_list_manager_(nullptr),
session1_(nullptr),
@@ -198,6 +211,7 @@ class QuicDispatcherTest : public ::testing::Test {
EpollServer eps_;
QuicEpollConnectionHelper helper_;
+ MockConnectionHelper mock_helper_;
QuicConfig config_;
QuicCryptoServerConfig crypto_config_;
IPEndPoint server_address_;
@@ -212,39 +226,40 @@ TEST_F(QuicDispatcherTest, ProcessPackets) {
IPEndPoint client_address(net::test::Loopback4(), 1);
server_address_ = IPEndPoint(net::test::Any4(), 5);
- EXPECT_CALL(dispatcher_, CreateQuicSession(1, _, client_address))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(1, client_address))
.WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &crypto_config_,
- &session1_)));
+ client_address, &mock_helper_,
+ &crypto_config_, &session1_)));
ProcessPacket(client_address, 1, true, "foo");
EXPECT_EQ(client_address, dispatcher_.current_client_address());
EXPECT_EQ(server_address_, dispatcher_.current_server_address());
- EXPECT_CALL(dispatcher_, CreateQuicSession(2, _, client_address))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(2, client_address))
.WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 2,
- client_address, &crypto_config_,
- &session2_)));
+ client_address, &mock_helper_,
+ &crypto_config_, &session2_)));
ProcessPacket(client_address, 2, true, "bar");
EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _)).Times(1).
- WillOnce(testing::WithArgs<2>(Invoke(
- this, &QuicDispatcherTest::ValidatePacket)));
+ ProcessUdpPacket(_, _, _))
+ .Times(1)
+ .WillOnce(testing::WithArgs<2>(
+ Invoke(this, &QuicDispatcherTest::ValidatePacket)));
ProcessPacket(client_address, 1, false, "eep");
}
TEST_F(QuicDispatcherTest, Shutdown) {
IPEndPoint client_address(net::test::Loopback4(), 1);
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, client_address))
.WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &crypto_config_,
- &session1_)));
+ client_address, &mock_helper_,
+ &crypto_config_, &session1_)));
ProcessPacket(client_address, 1, true, "foo");
EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()),
- SendConnectionClose(QUIC_PEER_GOING_AWAY));
+ SendConnectionCloseWithDetails(QUIC_PEER_GOING_AWAY, _));
dispatcher_.Shutdown();
}
@@ -255,10 +270,10 @@ TEST_F(QuicDispatcherTest, TimeWaitListManager) {
// Create a new session.
IPEndPoint client_address(net::test::Loopback4(), 1);
QuicConnectionId connection_id = 1;
- EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, _, client_address))
- .WillOnce(testing::Return(CreateSession(&dispatcher_, config_,
- connection_id, client_address,
- &crypto_config_, &session1_)));
+ EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, client_address))
+ .WillOnce(testing::Return(
+ CreateSession(&dispatcher_, config_, connection_id, client_address,
+ &mock_helper_, &crypto_config_, &session1_)));
ProcessPacket(client_address, connection_id, true, "foo");
// Close the connection by sending public reset packet.
@@ -270,22 +285,24 @@ TEST_F(QuicDispatcherTest, TimeWaitListManager) {
packet.nonce_proof = 132232;
scoped_ptr<QuicEncryptedPacket> encrypted(
QuicFramer::BuildPublicResetPacket(packet));
- EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, true)).Times(1)
+ EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, true))
+ .Times(1)
.WillOnce(WithoutArgs(Invoke(
reinterpret_cast<MockServerConnection*>(session1_->connection()),
&MockServerConnection::UnregisterOnConnectionClosed)));
EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()),
ProcessUdpPacket(_, _, _))
- .WillOnce(Invoke(
- reinterpret_cast<MockConnection*>(session1_->connection()),
- &MockConnection::ReallyProcessUdpPacket));
+ .WillOnce(
+ Invoke(reinterpret_cast<MockConnection*>(session1_->connection()),
+ &MockConnection::ReallyProcessUdpPacket));
dispatcher_.ProcessPacket(IPEndPoint(), client_address, *encrypted);
EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
// Dispatcher forwards subsequent packets for this connection_id to the time
// wait list manager.
EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _)).Times(1);
+ ProcessPacket(_, _, connection_id, _, _))
+ .Times(1);
EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
.Times(0);
ProcessPacket(client_address, connection_id, true, "foo");
@@ -298,9 +315,10 @@ TEST_F(QuicDispatcherTest, NoVersionPacketToTimeWaitListManager) {
QuicConnectionId connection_id = 1;
// Dispatcher forwards all packets for this connection_id to the time wait
// list manager.
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0);
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, _)).Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _)).Times(1);
+ ProcessPacket(_, _, connection_id, _, _))
+ .Times(1);
EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
.Times(1);
ProcessPacket(client_address, connection_id, false, "data");
@@ -322,12 +340,9 @@ class MockQuicCryptoServerStream : public QuicCryptoServerStream {
struct StatelessRejectTestParams {
StatelessRejectTestParams(bool enable_stateless_rejects_via_flag,
- bool use_stateless_rejects_if_peer_supported,
bool client_supports_statelesss_rejects,
bool crypto_handshake_successful)
: enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
- use_stateless_rejects_if_peer_supported(
- use_stateless_rejects_if_peer_supported),
client_supports_statelesss_rejects(client_supports_statelesss_rejects),
crypto_handshake_successful(crypto_handshake_successful) {}
@@ -335,8 +350,6 @@ struct StatelessRejectTestParams {
const StatelessRejectTestParams& p) {
os << " enable_stateless_rejects_via_flag: "
<< p.enable_stateless_rejects_via_flag << std::endl;
- os << "{ use_stateless_rejects_if_peer_supported: "
- << p.use_stateless_rejects_if_peer_supported << std::endl;
os << "{ client_supports_statelesss_rejects: "
<< p.client_supports_statelesss_rejects << std::endl;
os << " crypto_handshake_successful: " << p.crypto_handshake_successful
@@ -345,12 +358,8 @@ struct StatelessRejectTestParams {
}
// This only enables the stateless reject feature via the feature-flag.
- // It does not force the crypto server to emit stateless rejects.
+ // This should be a no-op if the peer does not support them.
bool enable_stateless_rejects_via_flag;
- // If true, this forces the server to send a stateless reject when rejecting
- // messages. This should be a no-op if enable_stateless_rejects_via_flag is
- // false or the peer does not support them.
- bool use_stateless_rejects_if_peer_supported;
// Whether or not the client supports stateless rejects.
bool client_supports_statelesss_rejects;
// Should the initial crypto handshake succeed or not.
@@ -361,14 +370,11 @@ struct StatelessRejectTestParams {
vector<StatelessRejectTestParams> GetStatelessRejectTestParams() {
vector<StatelessRejectTestParams> params;
for (bool enable_stateless_rejects_via_flag : {true, false}) {
- for (bool use_stateless_rejects_if_peer_supported : {true, false}) {
- for (bool client_supports_statelesss_rejects : {true, false}) {
- for (bool crypto_handshake_successful : {true, false}) {
- params.push_back(StatelessRejectTestParams(
- enable_stateless_rejects_via_flag,
- use_stateless_rejects_if_peer_supported,
- client_supports_statelesss_rejects, crypto_handshake_successful));
- }
+ for (bool client_supports_statelesss_rejects : {true, false}) {
+ for (bool crypto_handshake_successful : {true, false}) {
+ params.push_back(StatelessRejectTestParams(
+ enable_stateless_rejects_via_flag,
+ client_supports_statelesss_rejects, crypto_handshake_successful));
}
}
}
@@ -398,26 +404,23 @@ class QuicDispatcherStatelessRejectTest
// a stateless reject, depending upon the parameters of the test.
bool ExpectStatelessReject() {
return GetParam().enable_stateless_rejects_via_flag &&
- GetParam().use_stateless_rejects_if_peer_supported &&
!GetParam().crypto_handshake_successful &&
GetParam().client_supports_statelesss_rejects;
}
// Sets up dispatcher_, sesession1_, and crypto_stream1_ based on
// the test parameters.
- QuicServerSession* CreateSessionBasedOnTestParams(
+ QuicServerSessionBase* CreateSessionBasedOnTestParams(
QuicConnectionId connection_id,
const IPEndPoint& client_address) {
CreateSession(&dispatcher_, config_, connection_id, client_address,
- &crypto_config_, &session1_);
+ &mock_helper_, &crypto_config_, &session1_);
crypto_stream1_ = new MockQuicCryptoServerStream(crypto_config_, session1_);
session1_->SetCryptoStream(crypto_stream1_);
- crypto_stream1_->set_use_stateless_rejects_if_peer_supported(
- GetParam().use_stateless_rejects_if_peer_supported);
crypto_stream1_->set_handshake_confirmed_for_testing(
GetParam().crypto_handshake_successful);
- crypto_stream1_->set_peer_supports_stateless_rejects(
+ crypto_stream1_->SetPeerSupportsStatelessRejects(
GetParam().client_supports_statelesss_rejects);
return session1_;
}
@@ -432,7 +435,7 @@ TEST_F(QuicDispatcherTest, ProcessPacketWithZeroPort) {
server_address_ = IPEndPoint(net::test::Any4(), 5);
// dispatcher_ should drop this packet.
- EXPECT_CALL(dispatcher_, CreateQuicSession(1, _, client_address)).Times(0);
+ EXPECT_CALL(dispatcher_, CreateQuicSession(1, client_address)).Times(0);
EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
.Times(0);
@@ -444,10 +447,10 @@ TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
QuicConnectionId connection_id = 1;
server_address_ = IPEndPoint(net::test::Any4(), 5);
- EXPECT_CALL(dispatcher_, CreateQuicSession(1, _, client_address))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(1, client_address))
.WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &crypto_config_,
- &session1_)));
+ client_address, &mock_helper_,
+ &crypto_config_, &session1_)));
// A packet whose packet number is the largest that is allowed to start a
// connection.
ProcessPacket(client_address, connection_id, true, "data",
@@ -464,9 +467,10 @@ TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
QuicConnectionId connection_id = 1;
// Dispatcher forwards this packet for this connection_id to the time wait
// list manager.
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0);
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, _)).Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _)).Times(1);
+ ProcessPacket(_, _, connection_id, _, _))
+ .Times(1);
EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
.Times(1);
// A packet whose packet number is one to large to be allowed to start a
@@ -488,20 +492,23 @@ TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
IPEndPoint client_address(net::test::Loopback4(), 1);
QuicConnectionId connection_id = 1;
- EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, _, client_address))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, client_address))
.WillOnce(testing::Return(
CreateSessionBasedOnTestParams(connection_id, client_address)));
// Process the first packet for the connection.
+ ProcessPacket(client_address, connection_id, true, "foo");
if (ExpectStatelessReject()) {
- // If this is a stateless reject, we expect the connection to close.
+ // If this is a stateless reject, the crypto stream will close the
+ // connection.
EXPECT_CALL(*session1_, OnConnectionClosed(_, _))
.Times(1)
.WillOnce(WithoutArgs(Invoke(
reinterpret_cast<MockServerConnection*>(session1_->connection()),
&MockServerConnection::UnregisterOnConnectionClosed)));
+ session1_->connection()->CloseConnection(
+ QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, /* from_peer */ false);
}
- ProcessPacket(client_address, connection_id, true, "foo");
// Send a second packet and check the results. If this is a stateless reject,
// the existing connection_id will go on the time-wait list.
@@ -510,7 +517,8 @@ TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
if (ExpectStatelessReject()) {
// The second packet will be processed on the time-wait list.
EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _)).Times(1);
+ ProcessPacket(_, _, connection_id, _, _))
+ .Times(1);
} else {
// The second packet will trigger a packet-validation
EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()),
@@ -538,9 +546,10 @@ TEST_P(QuicDispatcherTestStrayPacketConnectionId,
IPEndPoint client_address(net::test::Loopback4(), 1);
QuicConnectionId connection_id = 1;
// Dispatcher drops this packet.
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0);
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, _)).Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- ProcessPacket(_, _, connection_id, _, _)).Times(0);
+ ProcessPacket(_, _, connection_id, _, _))
+ .Times(0);
EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
.Times(0);
ProcessPacket(client_address, connection_id, true, "data",
@@ -578,36 +587,34 @@ class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
public:
void SetUp() override {
writer_ = new BlockingWriter;
- QuicDispatcherPeer::SetPacketWriterFactory(&dispatcher_,
- new TestWriterFactory());
QuicDispatcherPeer::UseWriter(&dispatcher_, writer_);
IPEndPoint client_address(net::test::Loopback4(), 1);
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, client_address))
.WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 1,
- client_address, &crypto_config_,
- &session1_)));
+ client_address, &helper_,
+ &crypto_config_, &session1_)));
ProcessPacket(client_address, 1, true, "foo");
- EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address))
+ EXPECT_CALL(dispatcher_, CreateQuicSession(_, client_address))
.WillOnce(testing::Return(CreateSession(&dispatcher_, config_, 2,
- client_address, &crypto_config_,
- &session2_)));
+ client_address, &helper_,
+ &crypto_config_, &session2_)));
ProcessPacket(client_address, 2, true, "bar");
blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(&dispatcher_);
}
void TearDown() override {
- EXPECT_CALL(*connection1(), SendConnectionClose(QUIC_PEER_GOING_AWAY));
- EXPECT_CALL(*connection2(), SendConnectionClose(QUIC_PEER_GOING_AWAY));
+ EXPECT_CALL(*connection1(),
+ SendConnectionCloseWithDetails(QUIC_PEER_GOING_AWAY, _));
+ EXPECT_CALL(*connection2(),
+ SendConnectionCloseWithDetails(QUIC_PEER_GOING_AWAY, _));
dispatcher_.Shutdown();
}
- void SetBlocked() {
- writer_->write_blocked_ = true;
- }
+ void SetBlocked() { writer_->write_blocked_ = true; }
void BlockConnection2() {
writer_->write_blocked_ = true;
@@ -615,6 +622,7 @@ class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
}
protected:
+ MockConnectionHelper helper_;
BlockingWriter* writer_;
QuicDispatcher::WriteBlockedList* blocked_list_;
};
@@ -702,8 +710,8 @@ TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlock) {
SetBlocked();
dispatcher_.OnWriteBlocked(connection1());
dispatcher_.OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked));
+ EXPECT_CALL(*connection1(), OnCanWrite())
+ .WillOnce(Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked));
EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
dispatcher_.OnCanWrite();
@@ -720,8 +728,9 @@ TEST_F(QuicDispatcherWriteBlockedListTest, LimitedWrites) {
dispatcher_.OnWriteBlocked(connection1());
dispatcher_.OnWriteBlocked(connection2());
EXPECT_CALL(*connection1(), OnCanWrite());
- EXPECT_CALL(*connection2(), OnCanWrite()).WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
+ EXPECT_CALL(*connection2(), OnCanWrite())
+ .WillOnce(
+ Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
dispatcher_.OnCanWrite();
EXPECT_TRUE(dispatcher_.HasPendingWrites());
@@ -737,8 +746,8 @@ TEST_F(QuicDispatcherWriteBlockedListTest, TestWriteLimits) {
SetBlocked();
dispatcher_.OnWriteBlocked(connection1());
dispatcher_.OnWriteBlocked(connection2());
- EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(
- Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked));
+ EXPECT_CALL(*connection1(), OnCanWrite())
+ .WillOnce(Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked));
EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
dispatcher_.OnCanWrite();
EXPECT_TRUE(dispatcher_.HasPendingWrites());
diff --git a/chromium/net/tools/quic/quic_epoll_clock.cc b/chromium/net/tools/quic/quic_epoll_clock.cc
index 450afb8c524..bb607257743 100644
--- a/chromium/net/tools/quic/quic_epoll_clock.cc
+++ b/chromium/net/tools/quic/quic_epoll_clock.cc
@@ -10,8 +10,7 @@ namespace net {
namespace tools {
QuicEpollClock::QuicEpollClock(EpollServer* epoll_server)
- : epoll_server_(epoll_server) {
-}
+ : epoll_server_(epoll_server) {}
QuicEpollClock::~QuicEpollClock() {}
@@ -25,5 +24,10 @@ QuicTime QuicEpollClock::Now() const {
QuicTime::Delta::FromMicroseconds(epoll_server_->NowInUsec()));
}
+QuicWallTime QuicEpollClock::WallNow() const {
+ return QuicWallTime::FromUNIXMicroseconds(
+ epoll_server_->ApproximateNowInUsec());
+}
+
} // namespace tools
} // namespace net
diff --git a/chromium/net/tools/quic/quic_epoll_clock.h b/chromium/net/tools/quic/quic_epoll_clock.h
index c5a1390bd24..05b2b9fda86 100644
--- a/chromium/net/tools/quic/quic_epoll_clock.h
+++ b/chromium/net/tools/quic/quic_epoll_clock.h
@@ -5,8 +5,8 @@
#ifndef NET_TOOLS_QUIC_QUIC_EPOLL_CLOCK_H_
#define NET_TOOLS_QUIC_QUIC_EPOLL_CLOCK_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/quic/quic_clock.h"
#include "net/quic/quic_time.h"
@@ -27,9 +27,13 @@ class QuicEpollClock : public QuicClock {
QuicTime ApproximateNow() const override;
// Returns the current time as a QuicTime object.
- // Note: this use significant resources please use only if needed.
+ // Note: this uses significant resources, please use only if needed.
QuicTime Now() const override;
+ // Returns the current time as a QuicWallTime object.
+ // Note: this uses significant resources, please use only if needed.
+ QuicWallTime WallNow() const override;
+
protected:
EpollServer* epoll_server_;
diff --git a/chromium/net/tools/quic/quic_epoll_clock_test.cc b/chromium/net/tools/quic/quic_epoll_clock_test.cc
index 1ed1d15c1d7..05b2d7a388e 100644
--- a/chromium/net/tools/quic/quic_epoll_clock_test.cc
+++ b/chromium/net/tools/quic/quic_epoll_clock_test.cc
@@ -18,10 +18,18 @@ TEST(QuicEpollClockTest, ApproximateNowInUsec) {
epoll_server.set_now_in_usec(1000000);
EXPECT_EQ(1000000,
clock.ApproximateNow().Subtract(QuicTime::Zero()).ToMicroseconds());
+ EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+ EXPECT_EQ(1000000u, clock.WallNow().ToUNIXMicroseconds());
epoll_server.AdvanceBy(5);
EXPECT_EQ(1000005,
clock.ApproximateNow().Subtract(QuicTime::Zero()).ToMicroseconds());
+ EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+ EXPECT_EQ(1000005u, clock.WallNow().ToUNIXMicroseconds());
+
+ epoll_server.AdvanceBy(10 * 1000000);
+ EXPECT_EQ(11u, clock.WallNow().ToUNIXSeconds());
+ EXPECT_EQ(11000005u, clock.WallNow().ToUNIXMicroseconds());
}
TEST(QuicEpollClockTest, NowInUsec) {
@@ -29,27 +37,10 @@ TEST(QuicEpollClockTest, NowInUsec) {
QuicEpollClock clock(&epoll_server);
epoll_server.set_now_in_usec(1000000);
- EXPECT_EQ(1000000,
- clock.Now().Subtract(QuicTime::Zero()).ToMicroseconds());
+ EXPECT_EQ(1000000, clock.Now().Subtract(QuicTime::Zero()).ToMicroseconds());
epoll_server.AdvanceBy(5);
- EXPECT_EQ(1000005,
- clock.Now().Subtract(QuicTime::Zero()).ToMicroseconds());
-}
-
-TEST(QuicEpollClockTest, WallNow) {
- MockEpollServer epoll_server;
- QuicEpollClock clock(&epoll_server);
-
- base::Time start = base::Time::Now();
- QuicWallTime now = clock.WallNow();
- base::Time end = base::Time::Now();
-
- // If end > start, then we can check now is between start and end.
- if (end > start) {
- EXPECT_LE(static_cast<uint64>(start.ToTimeT()), now.ToUNIXSeconds());
- EXPECT_LE(now.ToUNIXSeconds(), static_cast<uint64>(end.ToTimeT()));
- }
+ EXPECT_EQ(1000005, clock.Now().Subtract(QuicTime::Zero()).ToMicroseconds());
}
} // namespace test
diff --git a/chromium/net/tools/quic/quic_epoll_connection_helper.cc b/chromium/net/tools/quic/quic_epoll_connection_helper.cc
index b763d822c7c..853f0d02571 100644
--- a/chromium/net/tools/quic/quic_epoll_connection_helper.cc
+++ b/chromium/net/tools/quic/quic_epoll_connection_helper.cc
@@ -21,8 +21,7 @@ namespace {
class QuicEpollAlarm : public QuicAlarm {
public:
- QuicEpollAlarm(EpollServer* epoll_server,
- QuicAlarm::Delegate* delegate)
+ QuicEpollAlarm(EpollServer* epoll_server, QuicAlarm::Delegate* delegate)
: QuicAlarm(delegate),
epoll_server_(epoll_server),
epoll_alarm_impl_(this) {}
@@ -45,7 +44,7 @@ class QuicEpollAlarm : public QuicAlarm {
public:
explicit EpollAlarmImpl(QuicEpollAlarm* alarm) : alarm_(alarm) {}
- int64 OnAlarm() override {
+ int64_t OnAlarm() override {
EpollAlarm::OnAlarm();
alarm_->Fire();
// Fire will take care of registering the alarm, if needed.
@@ -65,11 +64,9 @@ class QuicEpollAlarm : public QuicAlarm {
QuicEpollConnectionHelper::QuicEpollConnectionHelper(EpollServer* epoll_server)
: epoll_server_(epoll_server),
clock_(epoll_server),
- random_generator_(QuicRandom::GetInstance()) {
-}
+ random_generator_(QuicRandom::GetInstance()) {}
-QuicEpollConnectionHelper::~QuicEpollConnectionHelper() {
-}
+QuicEpollConnectionHelper::~QuicEpollConnectionHelper() {}
const QuicClock* QuicEpollConnectionHelper::GetClock() const {
return &clock_;
@@ -84,5 +81,9 @@ QuicAlarm* QuicEpollConnectionHelper::CreateAlarm(
return new QuicEpollAlarm(epoll_server_, delegate);
}
+QuicBufferAllocator* QuicEpollConnectionHelper::GetBufferAllocator() {
+ return &buffer_allocator_;
+}
+
} // namespace tools
} // namespace net
diff --git a/chromium/net/tools/quic/quic_epoll_connection_helper.h b/chromium/net/tools/quic/quic_epoll_connection_helper.h
index 66a27bb5e96..b3cc28ee22d 100644
--- a/chromium/net/tools/quic/quic_epoll_connection_helper.h
+++ b/chromium/net/tools/quic/quic_epoll_connection_helper.h
@@ -11,9 +11,11 @@
#include <sys/types.h>
#include <set>
+#include "base/macros.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_packet_writer.h"
#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_simple_buffer_allocator.h"
#include "net/quic/quic_time.h"
#include "net/tools/quic/quic_default_packet_writer.h"
#include "net/tools/quic/quic_epoll_clock.h"
@@ -39,6 +41,7 @@ class QuicEpollConnectionHelper : public QuicConnectionHelperInterface {
const QuicClock* GetClock() const override;
QuicRandom* GetRandomGenerator() override;
QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+ QuicBufferAllocator* GetBufferAllocator() override;
EpollServer* epoll_server() { return epoll_server_; }
@@ -49,6 +52,7 @@ class QuicEpollConnectionHelper : public QuicConnectionHelperInterface {
const QuicEpollClock clock_;
QuicRandom* random_generator_;
+ SimpleBufferAllocator buffer_allocator_;
DISALLOW_COPY_AND_ASSIGN(QuicEpollConnectionHelper);
};
diff --git a/chromium/net/tools/quic/quic_in_memory_cache.cc b/chromium/net/tools/quic/quic_in_memory_cache.cc
index 2ae5c49d9e8..9c248414d5f 100644
--- a/chromium/net/tools/quic/quic_in_memory_cache.cc
+++ b/chromium/net/tools/quic/quic_in_memory_cache.cc
@@ -9,8 +9,10 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
+#include "net/quic/quic_bug_tracker.h"
#include "net/spdy/spdy_http_utils.h"
using base::FilePath;
@@ -21,6 +23,16 @@ using std::string;
namespace net {
namespace tools {
+QuicInMemoryCache::ServerPushInfo::ServerPushInfo(
+ GURL request_url,
+ const SpdyHeaderBlock& headers,
+ net::SpdyPriority priority,
+ string body)
+ : request_url(request_url),
+ headers(headers),
+ priority(priority),
+ body(body) {}
+
QuicInMemoryCache::Response::Response() : response_type_(REGULAR_RESPONSE) {}
QuicInMemoryCache::Response::~Response() {}
@@ -43,21 +55,29 @@ const QuicInMemoryCache::Response* QuicInMemoryCache::GetResponse(
return it->second;
}
+typedef QuicInMemoryCache::ServerPushInfo ServerPushInfo;
+
void QuicInMemoryCache::AddSimpleResponse(StringPiece host,
StringPiece path,
int response_code,
- StringPiece response_detail,
StringPiece body) {
SpdyHeaderBlock response_headers;
- response_headers[":version"] = "HTTP/1.1";
- string status = IntToString(response_code) + " ";
- response_detail.AppendToString(&status);
- response_headers[":status"] = status;
+ response_headers[":status"] = IntToString(response_code);
response_headers["content-length"] =
IntToString(static_cast<int>(body.length()));
AddResponse(host, path, response_headers, body);
}
+void QuicInMemoryCache::AddSimpleResponseWithServerPushResources(
+ StringPiece host,
+ StringPiece path,
+ int response_code,
+ StringPiece body,
+ list<ServerPushInfo> push_resources) {
+ AddSimpleResponse(host, path, response_code, body);
+ MaybeAddServerPushResources(host, path, push_resources);
+}
+
void QuicInMemoryCache::AddDefaultResponse(Response* response) {
default_response_.reset(response);
}
@@ -66,33 +86,42 @@ void QuicInMemoryCache::AddResponse(StringPiece host,
StringPiece path,
const SpdyHeaderBlock& response_headers,
StringPiece response_body) {
- AddResponseImpl(host, path, REGULAR_RESPONSE, response_headers,
- response_body);
+ AddResponseImpl(host, path, REGULAR_RESPONSE, response_headers, response_body,
+ SpdyHeaderBlock());
+}
+
+void QuicInMemoryCache::AddResponse(StringPiece host,
+ StringPiece path,
+ const SpdyHeaderBlock& response_headers,
+ StringPiece response_body,
+ const SpdyHeaderBlock& response_trailers) {
+ AddResponseImpl(host, path, REGULAR_RESPONSE, response_headers, response_body,
+ response_trailers);
}
void QuicInMemoryCache::AddSpecialResponse(StringPiece host,
StringPiece path,
SpecialResponseType response_type) {
- AddResponseImpl(host, path, response_type, SpdyHeaderBlock(), "");
+ AddResponseImpl(host, path, response_type, SpdyHeaderBlock(), "",
+ SpdyHeaderBlock());
}
QuicInMemoryCache::QuicInMemoryCache() {}
void QuicInMemoryCache::ResetForTests() {
STLDeleteValues(&responses_);
+ server_push_resources_.clear();
}
void QuicInMemoryCache::InitializeFromDirectory(const string& cache_directory) {
if (cache_directory.empty()) {
- LOG(DFATAL) << "cache_directory must not be empty.";
+ QUIC_BUG << "cache_directory must not be empty.";
return;
}
VLOG(1) << "Attempting to initialize QuicInMemoryCache from directory: "
<< cache_directory;
FilePath directory(FilePath::FromUTF8Unsafe(cache_directory));
- base::FileEnumerator file_list(directory,
- true,
- base::FileEnumerator::FILES);
+ base::FileEnumerator file_list(directory, true, base::FileEnumerator::FILES);
for (FilePath file_iter = file_list.Next(); !file_iter.empty();
file_iter = file_list.Next()) {
@@ -111,8 +140,8 @@ void QuicInMemoryCache::InitializeFromDirectory(const string& cache_directory) {
string file_contents;
base::ReadFileToString(file_iter, &file_contents);
int file_len = static_cast<int>(file_contents.length());
- int headers_end = HttpUtil::LocateEndOfHeaders(file_contents.data(),
- file_len);
+ int headers_end =
+ HttpUtil::LocateEndOfHeaders(file_contents.data(), file_len);
if (headers_end < 1) {
LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file;
continue;
@@ -145,20 +174,24 @@ void QuicInMemoryCache::InitializeFromDirectory(const string& cache_directory) {
if (path[path.length() - 1] == ',') {
path.remove_suffix(1);
}
-
StringPiece body(file_contents.data() + headers_end,
file_contents.size() - headers_end);
- // QUIC_VERSION_24 and below use SPDY/3 headers, which includes the
- // status reason in :status, and "HTTP/1.1" in :version. Since this
- // format is a strict superset of SPDY/4 headers, the cache uses this
- // format to store response. Once SPDY/3 responses are no longer
- // required, the cache can store SPDY/4 headers.
SpdyHeaderBlock header_block;
CreateSpdyHeadersFromHttpResponse(*response_headers, HTTP2, &header_block);
AddResponse(host, path, header_block, body);
}
}
+list<ServerPushInfo> QuicInMemoryCache::GetServerPushResources(
+ string request_url) {
+ list<ServerPushInfo> resources;
+ auto resource_range = server_push_resources_.equal_range(request_url);
+ for (auto it = resource_range.first; it != resource_range.second; ++it) {
+ resources.push_back(it->second);
+ }
+ return resources;
+}
+
QuicInMemoryCache::~QuicInMemoryCache() {
STLDeleteValues(&responses_);
}
@@ -168,17 +201,19 @@ void QuicInMemoryCache::AddResponseImpl(
StringPiece path,
SpecialResponseType response_type,
const SpdyHeaderBlock& response_headers,
- StringPiece response_body) {
+ StringPiece response_body,
+ const SpdyHeaderBlock& response_trailers) {
+ DCHECK(!host.empty()) << "Host must be populated, e.g. \"www.google.com\"";
string key = GetKey(host, path);
- VLOG(1) << "Adding response for: " << key;
if (ContainsKey(responses_, key)) {
- LOG(DFATAL) << "Response for '" << key << "' already exists!";
+ QUIC_BUG << "Response for '" << key << "' already exists!";
return;
}
Response* new_response = new Response();
new_response->set_response_type(response_type);
new_response->set_headers(response_headers);
new_response->set_body(response_body);
+ new_response->set_trailers(response_trailers);
responses_[key] = new_response;
}
@@ -186,5 +221,42 @@ string QuicInMemoryCache::GetKey(StringPiece host, StringPiece path) const {
return host.as_string() + path.as_string();
}
+void QuicInMemoryCache::MaybeAddServerPushResources(
+ StringPiece request_host,
+ StringPiece request_path,
+ list<ServerPushInfo> push_resources) {
+ string request_url = request_host.as_string() + request_path.as_string();
+
+ for (const auto& push_resource : push_resources) {
+ if (PushResourceExistsInCache(request_url, push_resource)) {
+ continue;
+ }
+
+ DVLOG(1) << "Add request-resource association.";
+ server_push_resources_.insert(std::make_pair(request_url, push_resource));
+ string path = push_resource.request_url.path();
+ if (responses_.find(GetKey(request_host, path)) == responses_.end()) {
+ // Add a server push response to responses map, if it is not in the map.
+ SpdyHeaderBlock headers = push_resource.headers;
+ StringPiece body = push_resource.body;
+ DVLOG(1) << "Add response for push resource " << body;
+ AddResponse(request_host, path, headers, body);
+ }
+ }
+}
+
+bool QuicInMemoryCache::PushResourceExistsInCache(string original_request_url,
+ ServerPushInfo resource) {
+ auto resource_range =
+ server_push_resources_.equal_range(original_request_url);
+ for (auto it = resource_range.first; it != resource_range.second; ++it) {
+ ServerPushInfo push_resource = it->second;
+ if (push_resource.request_url.spec() == resource.request_url.spec()) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace tools
} // namespace net
diff --git a/chromium/net/tools/quic/quic_in_memory_cache.h b/chromium/net/tools/quic/quic_in_memory_cache.h
index e96ad0107ab..e6ebada8740 100644
--- a/chromium/net/tools/quic/quic_in_memory_cache.h
+++ b/chromium/net/tools/quic/quic_in_memory_cache.h
@@ -5,16 +5,25 @@
#ifndef NET_TOOLS_QUIC_QUIC_IN_MEMORY_CACHE_H_
#define NET_TOOLS_QUIC_QUIC_IN_MEMORY_CACHE_H_
+#include <map>
#include <string>
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/string_piece.h"
+#include "net/quic/spdy_utils.h"
#include "net/spdy/spdy_framer.h"
+#include "url/gurl.h"
+
+using base::StringPiece;
+using std::string;
+using std::list;
namespace base {
-template <typename Type> struct DefaultSingletonTraits;
+template <typename Type>
+struct DefaultSingletonTraits;
} // namespace base
@@ -32,10 +41,23 @@ class QuicServer;
// `wget -p --save_headers <url>`
class QuicInMemoryCache {
public:
+ // A ServerPushInfo contains path of the push request and everything needed in
+ // comprising a response for the push request.
+ struct ServerPushInfo {
+ ServerPushInfo(GURL request_url,
+ const net::SpdyHeaderBlock& headers,
+ net::SpdyPriority priority,
+ string body);
+ GURL request_url;
+ net::SpdyHeaderBlock headers;
+ net::SpdyPriority priority;
+ string body;
+ };
+
enum SpecialResponseType {
REGULAR_RESPONSE, // Send the headers and body like a server should.
CLOSE_CONNECTION, // Close the connection (sending the close packet).
- IGNORE_REQUEST, // Do nothing, expect the client to time out.
+ IGNORE_REQUEST, // Do nothing, expect the client to time out.
};
// Container for response header/body pairs.
@@ -46,21 +68,20 @@ class QuicInMemoryCache {
SpecialResponseType response_type() const { return response_type_; }
const SpdyHeaderBlock& headers() const { return headers_; }
- const StringPiece body() const { return StringPiece(body_); }
+ const SpdyHeaderBlock& trailers() const { return trailers_; }
+ const base::StringPiece body() const { return base::StringPiece(body_); }
void set_response_type(SpecialResponseType response_type) {
response_type_ = response_type;
}
- void set_headers(const SpdyHeaderBlock& headers) {
- headers_ = headers;
- }
- void set_body(base::StringPiece body) {
- body.CopyToString(&body_);
- }
+ void set_headers(const SpdyHeaderBlock& headers) { headers_ = headers; }
+ void set_trailers(const SpdyHeaderBlock& trailers) { trailers_ = trailers; }
+ void set_body(base::StringPiece body) { body.CopyToString(&body_); }
private:
SpecialResponseType response_type_;
SpdyHeaderBlock headers_;
+ SpdyHeaderBlock trailers_;
std::string body_;
DISALLOW_COPY_AND_ASSIGN(Response);
@@ -79,15 +100,32 @@ class QuicInMemoryCache {
void AddSimpleResponse(base::StringPiece host,
base::StringPiece path,
int response_code,
- base::StringPiece response_detail,
base::StringPiece body);
+ // Add a simple response to the cache as AddSimpleResponse() does, and add
+ // some server push resources(resource path, corresponding response status and
+ // path) associated with it.
+ // Push resource implicitly come from the same host.
+ void AddSimpleResponseWithServerPushResources(
+ StringPiece host,
+ StringPiece path,
+ int response_code,
+ StringPiece body,
+ list<ServerPushInfo> push_resources);
+
// Add a response to the cache.
void AddResponse(base::StringPiece host,
base::StringPiece path,
const SpdyHeaderBlock& response_headers,
base::StringPiece response_body);
+ // Add a response, with trailers, to the cache.
+ void AddResponse(base::StringPiece host,
+ base::StringPiece path,
+ const SpdyHeaderBlock& response_headers,
+ base::StringPiece response_body,
+ const SpdyHeaderBlock& response_trailers);
+
// Simulate a special behavior at a particular path.
void AddSpecialResponse(base::StringPiece host,
base::StringPiece path,
@@ -98,10 +136,13 @@ class QuicInMemoryCache {
void AddDefaultResponse(Response* response);
// |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
- void InitializeFromDirectory(const std::string& cache_directory);
+ void InitializeFromDirectory(const string& cache_directory);
+
+ // Find all the server push resources associated with |request_url|.
+ list<ServerPushInfo> GetServerPushResources(string request_url);
private:
- typedef base::hash_map<std::string, Response*> ResponseMap;
+ typedef base::hash_map<string, Response*> ResponseMap;
friend struct base::DefaultSingletonTraits<QuicInMemoryCache>;
friend class test::QuicInMemoryCachePeer;
@@ -115,9 +156,21 @@ class QuicInMemoryCache {
base::StringPiece path,
SpecialResponseType response_type,
const SpdyHeaderBlock& response_headers,
- base::StringPiece response_body);
+ base::StringPiece response_body,
+ const SpdyHeaderBlock& response_trailers);
- std::string GetKey(base::StringPiece host, base::StringPiece path) const;
+ string GetKey(base::StringPiece host, base::StringPiece path) const;
+
+ // Add some server push urls with given responses for specified
+ // request if these push resources are not associated with this request yet.
+ void MaybeAddServerPushResources(StringPiece request_host,
+ StringPiece request_path,
+ list<ServerPushInfo> push_resources);
+
+ // Check if push resource(push_host/push_path) associated with given request
+ // url already exists in server push map.
+ bool PushResourceExistsInCache(string original_request_url,
+ ServerPushInfo resource);
// Cached responses.
ResponseMap responses_;
@@ -125,6 +178,9 @@ class QuicInMemoryCache {
// The default response for cache misses, if set.
scoped_ptr<Response> default_response_;
+ // A map from request URL to associated server push responses (if any).
+ std::multimap<string, ServerPushInfo> server_push_resources_;
+
DISALLOW_COPY_AND_ASSIGN(QuicInMemoryCache);
};
diff --git a/chromium/net/tools/quic/quic_in_memory_cache_test.cc b/chromium/net/tools/quic/quic_in_memory_cache_test.cc
index 534edfff27e..227d615d20a 100644
--- a/chromium/net/tools/quic/quic_in_memory_cache_test.cc
+++ b/chromium/net/tools/quic/quic_in_memory_cache_test.cc
@@ -10,6 +10,7 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
#include "net/spdy/spdy_framer.h"
#include "net/tools/balsa/balsa_headers.h"
#include "net/tools/quic/quic_in_memory_cache.h"
@@ -18,17 +19,21 @@
using base::IntToString;
using base::StringPiece;
+using net::SpdyHeaderBlock;
using std::string;
namespace net {
namespace tools {
namespace test {
+namespace {
+typedef QuicInMemoryCache::Response Response;
+typedef QuicInMemoryCache::ServerPushInfo ServerPushInfo;
+}; // namespace
+
class QuicInMemoryCacheTest : public ::testing::Test {
protected:
- QuicInMemoryCacheTest() {
- QuicInMemoryCachePeer::ResetForTests();
- }
+ QuicInMemoryCacheTest() { QuicInMemoryCachePeer::ResetForTests(); }
~QuicInMemoryCacheTest() override { QuicInMemoryCachePeer::ResetForTests(); }
@@ -40,8 +45,8 @@ class QuicInMemoryCacheTest : public ::testing::Test {
string CacheDirectory() {
base::FilePath path;
PathService::Get(base::DIR_SOURCE_ROOT, &path);
- path = path.AppendASCII("net").AppendASCII("data")
- .AppendASCII("quic_in_memory_cache_data");
+ path = path.AppendASCII("net").AppendASCII("data").AppendASCII(
+ "quic_in_memory_cache_data");
// The file path is known to be an ascii string.
return path.MaybeAsASCII();
}
@@ -57,7 +62,7 @@ TEST_F(QuicInMemoryCacheTest, GetResponseNoMatch) {
TEST_F(QuicInMemoryCacheTest, AddSimpleResponseGetResponse) {
string response_body("hello response");
QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance();
- cache->AddSimpleResponse("www.google.com", "/", 200, "OK", response_body);
+ cache->AddSimpleResponse("www.google.com", "/", 200, response_body);
BalsaHeaders request_headers;
CreateRequest("www.google.com", "/", &request_headers);
@@ -65,10 +70,36 @@ TEST_F(QuicInMemoryCacheTest, AddSimpleResponseGetResponse) {
cache->GetResponse("www.google.com", "/");
ASSERT_TRUE(response);
ASSERT_TRUE(ContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200 OK", response->headers().find(":status")->second);
+ EXPECT_EQ("200", response->headers().find(":status")->second);
EXPECT_EQ(response_body.size(), response->body().length());
}
+TEST_F(QuicInMemoryCacheTest, AddResponse) {
+ const string kRequestHost = "www.foo.com";
+ const string kRequestPath = "/";
+ const string kResponseBody("hello response");
+
+ SpdyHeaderBlock response_headers;
+ response_headers[":version"] = "HTTP/1.1";
+ response_headers[":status"] = "200";
+ response_headers["content-length"] = IntToString(kResponseBody.size());
+
+ SpdyHeaderBlock response_trailers;
+ response_trailers["key-1"] = "value-1";
+ response_trailers["key-2"] = "value-2";
+ response_trailers["key-3"] = "value-3";
+
+ QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance();
+ cache->AddResponse(kRequestHost, "/", response_headers, kResponseBody,
+ response_trailers);
+
+ const QuicInMemoryCache::Response* response =
+ cache->GetResponse(kRequestHost, kRequestPath);
+ EXPECT_EQ(response->headers(), response_headers);
+ EXPECT_EQ(response->body(), kResponseBody);
+ EXPECT_EQ(response->trailers(), response_trailers);
+}
+
TEST_F(QuicInMemoryCacheTest, ReadsCacheDir) {
QuicInMemoryCache::GetInstance()->InitializeFromDirectory(CacheDirectory());
const QuicInMemoryCache::Response* response =
@@ -76,7 +107,7 @@ TEST_F(QuicInMemoryCacheTest, ReadsCacheDir) {
"/index.html");
ASSERT_TRUE(response);
ASSERT_TRUE(ContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200 OK", response->headers().find(":status")->second);
+ EXPECT_EQ("200", response->headers().find(":status")->second);
ASSERT_TRUE(ContainsKey(response->headers(), "connection"));
EXPECT_EQ("close", response->headers().find("connection")->second);
EXPECT_LT(0U, response->body().length());
@@ -89,7 +120,7 @@ TEST_F(QuicInMemoryCacheTest, UsesOriginalUrl) {
"/index.html");
ASSERT_TRUE(response);
ASSERT_TRUE(ContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200 OK", response->headers().find(":status")->second);
+ EXPECT_EQ("200", response->headers().find(":status")->second);
ASSERT_TRUE(ContainsKey(response->headers(), "connection"));
EXPECT_EQ("close", response->headers().find("connection")->second);
EXPECT_LT(0U, response->body().length());
@@ -105,7 +136,7 @@ TEST_F(QuicInMemoryCacheTest, DefaultResponse) {
// Add a default response.
SpdyHeaderBlock response_headers;
response_headers[":version"] = "HTTP/1.1";
- response_headers[":status"] = "200 OK";
+ response_headers[":status"] = "200";
response_headers["content-length"] = "0";
QuicInMemoryCache::Response* default_response =
new QuicInMemoryCache::Response;
@@ -116,20 +147,98 @@ TEST_F(QuicInMemoryCacheTest, DefaultResponse) {
response = cache->GetResponse("www.google.com", "/");
ASSERT_TRUE(response);
ASSERT_TRUE(ContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200 OK", response->headers().find(":status")->second);
+ EXPECT_EQ("200", response->headers().find(":status")->second);
// Now add a set response for / and make sure it is returned
- cache->AddSimpleResponse("www.google.com", "/", 302, "foo", "");
+ cache->AddSimpleResponse("www.google.com", "/", 302, "");
response = cache->GetResponse("www.google.com", "/");
ASSERT_TRUE(response);
ASSERT_TRUE(ContainsKey(response->headers(), ":status"));
- EXPECT_EQ("302 foo", response->headers().find(":status")->second);
+ EXPECT_EQ("302", response->headers().find(":status")->second);
// We should get the default response for other requests.
response = cache->GetResponse("www.google.com", "/asd");
ASSERT_TRUE(response);
ASSERT_TRUE(ContainsKey(response->headers(), ":status"));
- EXPECT_EQ("200 OK", response->headers().find(":status")->second);
+ EXPECT_EQ("200", response->headers().find(":status")->second);
+}
+
+TEST_F(QuicInMemoryCacheTest, AddSimpleResponseWithServerPushResources) {
+ string request_host = "www.foo.com";
+ string response_body("hello response");
+ const size_t kNumResources = 5;
+ int NumResources = 5;
+ list<QuicInMemoryCache::ServerPushInfo> push_resources;
+ string scheme = "http";
+ for (int i = 0; i < NumResources; ++i) {
+ string path = "/server_push_src" + base::IntToString(i);
+ string url = scheme + "://" + request_host + path;
+ GURL resource_url(url);
+ string body = "This is server push response body for " + path;
+ SpdyHeaderBlock response_headers;
+ response_headers[":version"] = "HTTP/1.1";
+ response_headers[":status"] = "200";
+ response_headers["content-length"] = base::UintToString(body.size());
+ push_resources.push_back(
+ ServerPushInfo(resource_url, response_headers, i, body));
+ }
+
+ QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance();
+ cache->AddSimpleResponseWithServerPushResources(
+ request_host, "/", 200, response_body, push_resources);
+ string request_url = request_host + "/";
+ std::list<ServerPushInfo> resources =
+ cache->GetServerPushResources(request_url);
+ ASSERT_EQ(kNumResources, resources.size());
+ for (const auto& push_resource : push_resources) {
+ ServerPushInfo resource = resources.front();
+ EXPECT_EQ(resource.request_url.spec(), push_resource.request_url.spec());
+ EXPECT_EQ(resource.priority, push_resource.priority);
+ resources.pop_front();
+ }
+}
+
+TEST_F(QuicInMemoryCacheTest, GetServerPushResourcesAndPushResponses) {
+ string request_host = "www.foo.com";
+ string response_body("hello response");
+ const size_t kNumResources = 4;
+ int NumResources = 4;
+ string scheme = "http";
+ string push_response_status[kNumResources] = {"200", "200", "301", "404"};
+ list<QuicInMemoryCache::ServerPushInfo> push_resources;
+ for (int i = 0; i < NumResources; ++i) {
+ string path = "/server_push_src" + base::IntToString(i);
+ string url = scheme + "://" + request_host + path;
+ GURL resource_url(url);
+ string body = "This is server push response body for " + path;
+ SpdyHeaderBlock response_headers;
+ response_headers[":version"] = "HTTP/1.1";
+ response_headers[":status"] = push_response_status[i];
+ response_headers["content-length"] = base::UintToString(body.size());
+ push_resources.push_back(
+ ServerPushInfo(resource_url, response_headers, i, body));
+ }
+ QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance();
+ cache->AddSimpleResponseWithServerPushResources(
+ request_host, "/", 200, response_body, push_resources);
+ string request_url = request_host + "/";
+ std::list<ServerPushInfo> resources =
+ cache->GetServerPushResources(request_url);
+ ASSERT_EQ(kNumResources, resources.size());
+ int i = 0;
+ for (const auto& push_resource : push_resources) {
+ GURL url = resources.front().request_url;
+ string host = url.host();
+ string path = url.path();
+ const QuicInMemoryCache::Response* response =
+ cache->GetResponse(host, path);
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(ContainsKey(response->headers(), ":status"));
+ EXPECT_EQ(push_response_status[i++],
+ response->headers().find(":status")->second);
+ EXPECT_EQ(push_resource.body, response->body());
+ resources.pop_front();
+ }
}
} // namespace test
diff --git a/chromium/net/tools/quic/quic_packet_reader.cc b/chromium/net/tools/quic/quic_packet_reader.cc
index 1982269f30b..a6d325e5737 100644
--- a/chromium/net/tools/quic/quic_packet_reader.cc
+++ b/chromium/net/tools/quic/quic_packet_reader.cc
@@ -14,6 +14,8 @@
#include "base/logging.h"
#include "net/base/ip_endpoint.h"
+#include "net/quic/quic_bug_tracker.h"
+#include "net/quic/quic_flags.h"
#include "net/tools/quic/quic_dispatcher.h"
#include "net/tools/quic/quic_socket_utils.h"
@@ -39,8 +41,8 @@ void QuicPacketReader::Initialize() {
memset(mmsg_hdr_, 0, sizeof(mmsg_hdr_));
for (int i = 0; i < kNumPacketsPerReadMmsgCall; ++i) {
- iov_[i].iov_base = buf_ + (2 * kMaxPacketSize * i);
- iov_[i].iov_len = 2 * kMaxPacketSize;
+ iov_[i].iov_base = buf_ + (kMaxPacketSize * i);
+ iov_[i].iov_len = kMaxPacketSize;
msghdr* hdr = &mmsg_hdr_[i].msg_hdr;
hdr->msg_name = &raw_address_[i];
@@ -53,8 +55,7 @@ void QuicPacketReader::Initialize() {
}
}
-QuicPacketReader::~QuicPacketReader() {
-}
+QuicPacketReader::~QuicPacketReader() {}
bool QuicPacketReader::ReadAndDispatchPackets(
int fd,
@@ -64,7 +65,7 @@ bool QuicPacketReader::ReadAndDispatchPackets(
#if MMSG_MORE
// Re-set the length fields in case recvmmsg has changed them.
for (int i = 0; i < kNumPacketsPerReadMmsgCall; ++i) {
- iov_[i].iov_len = 2 * kMaxPacketSize;
+ iov_[i].iov_len = kMaxPacketSize;
mmsg_hdr_[i].msg_len = 0;
msghdr* hdr = &mmsg_hdr_[i].msg_hdr;
hdr->msg_namelen = sizeof(sockaddr_storage);
@@ -88,7 +89,7 @@ bool QuicPacketReader::ReadAndDispatchPackets(
IPAddressNumber server_ip =
QuicSocketUtils::GetAddressFromMsghdr(&mmsg_hdr_[i].msg_hdr);
if (!IsInitializedAddress(server_ip)) {
- LOG(DFATAL) << "Unable to get server address.";
+ QUIC_BUG << "Unable to get server address.";
continue;
}
@@ -103,7 +104,8 @@ bool QuicPacketReader::ReadAndDispatchPackets(
packets_dropped);
}
- return true;
+ // We may not have read all of the packets available on the socket.
+ return packets_read == kNumPacketsPerReadMmsgCall;
#else
LOG(FATAL) << "Unsupported";
return false;
@@ -116,9 +118,7 @@ bool QuicPacketReader::ReadAndDispatchSinglePacket(
int port,
ProcessPacketInterface* processor,
QuicPacketCount* packets_dropped) {
- // Allocate some extra space so we can send an error if the packet is larger
- // than kMaxPacketSize.
- char buf[2 * kMaxPacketSize];
+ char buf[kMaxPacketSize];
IPEndPoint client_address;
IPAddressNumber server_ip;
diff --git a/chromium/net/tools/quic/quic_packet_reader.h b/chromium/net/tools/quic/quic_packet_reader.h
index 479fc6d9097..0d99afbc745 100644
--- a/chromium/net/tools/quic/quic_packet_reader.h
+++ b/chromium/net/tools/quic/quic_packet_reader.h
@@ -10,7 +10,7 @@
#include <netinet/in.h>
#include <sys/socket.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
namespace net {
@@ -37,8 +37,8 @@ class QuicPacketReader {
virtual ~QuicPacketReader();
// Reads a number of packets from the given fd, and then passes them off to
- // the PacketProcessInterface. Returns true if at least 1 packet is read,
- // false otherwise.
+ // the PacketProcessInterface. Returns true if there may be additional
+ // packets available on the socket.
// Populates |packets_dropped| if it is non-null and the socket is configured
// to track dropped packets and some packets are read.
virtual bool ReadAndDispatchPackets(int fd,
@@ -61,7 +61,9 @@ class QuicPacketReader {
// cbuf_ is used for ancillary data from the kernel on recvmmsg.
char cbuf_[kSpaceForOverflowAndIp * kNumPacketsPerReadMmsgCall];
// buf_ is used for the data read from the kernel on recvmmsg.
- char buf_[2 * kMaxPacketSize * kNumPacketsPerReadMmsgCall];
+ // TODO(danzh): change it to be a pointer to avoid the allocation on the stack
+ // from exceeding maximum allowed frame size.
+ char buf_[kMaxPacketSize * kNumPacketsPerReadMmsgCall];
// iov_ and mmsg_hdr_ are used to supply cbuf and buf to the recvmmsg call.
iovec iov_[kNumPacketsPerReadMmsgCall];
mmsghdr mmsg_hdr_[kNumPacketsPerReadMmsgCall];
diff --git a/chromium/net/tools/quic/quic_packet_writer_wrapper.h b/chromium/net/tools/quic/quic_packet_writer_wrapper.h
index 1ab474a145a..f425b5c3b77 100644
--- a/chromium/net/tools/quic/quic_packet_writer_wrapper.h
+++ b/chromium/net/tools/quic/quic_packet_writer_wrapper.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_QUIC_QUIC_PACKET_WRITER_WRAPPER_H_
#define NET_TOOLS_QUIC_QUIC_PACKET_WRITER_WRAPPER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/quic_packet_writer.h"
diff --git a/chromium/net/tools/quic/quic_per_connection_packet_writer.cc b/chromium/net/tools/quic/quic_per_connection_packet_writer.cc
index 0a7d77a6837..f95e0169104 100644
--- a/chromium/net/tools/quic/quic_per_connection_packet_writer.cc
+++ b/chromium/net/tools/quic/quic_per_connection_packet_writer.cc
@@ -9,23 +9,17 @@ namespace net {
namespace tools {
QuicPerConnectionPacketWriter::QuicPerConnectionPacketWriter(
- QuicPacketWriter* shared_writer,
- QuicConnection* connection)
- : shared_writer_(shared_writer),
- connection_(connection) {
-}
+ QuicPacketWriter* shared_writer)
+ : shared_writer_(shared_writer) {}
-QuicPerConnectionPacketWriter::~QuicPerConnectionPacketWriter() {
-}
+QuicPerConnectionPacketWriter::~QuicPerConnectionPacketWriter() {}
WriteResult QuicPerConnectionPacketWriter::WritePacket(
const char* buffer,
size_t buf_len,
const IPAddressNumber& self_address,
const IPEndPoint& peer_address) {
- return shared_writer_->WritePacket(buffer,
- buf_len,
- self_address,
+ return shared_writer_->WritePacket(buffer, buf_len, self_address,
peer_address);
}
diff --git a/chromium/net/tools/quic/quic_per_connection_packet_writer.h b/chromium/net/tools/quic/quic_per_connection_packet_writer.h
index ae3175f4e83..e4c20450605 100644
--- a/chromium/net/tools/quic/quic_per_connection_packet_writer.h
+++ b/chromium/net/tools/quic/quic_per_connection_packet_writer.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_QUIC_QUIC_PER_CONNECTION_PACKET_WRITER_H_
#define NET_TOOLS_QUIC_QUIC_PER_CONNECTION_PACKET_WRITER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_packet_writer.h"
@@ -12,17 +15,14 @@ namespace net {
namespace tools {
-// A connection-specific packet writer that wraps a shared writer and keeps a
-// reference to the connection.
+// A connection-specific packet writer that wraps a shared writer.
class QuicPerConnectionPacketWriter : public QuicPacketWriter {
public:
- // Does not take ownership of |shared_writer| or |connection|.
- QuicPerConnectionPacketWriter(QuicPacketWriter* shared_writer,
- QuicConnection* connection);
+ // Does not take ownership of |shared_writer|.
+ QuicPerConnectionPacketWriter(QuicPacketWriter* shared_writer);
~QuicPerConnectionPacketWriter() override;
QuicPacketWriter* shared_writer() const { return shared_writer_; }
- QuicConnection* connection() const { return connection_; }
// Default implementation of the QuicPacketWriter interface: Passes everything
// to |shared_writer_|.
@@ -37,7 +37,6 @@ class QuicPerConnectionPacketWriter : public QuicPacketWriter {
private:
QuicPacketWriter* shared_writer_; // Not owned.
- QuicConnection* connection_; // Not owned.
DISALLOW_COPY_AND_ASSIGN(QuicPerConnectionPacketWriter);
};
diff --git a/chromium/net/tools/quic/quic_server.cc b/chromium/net/tools/quic/quic_server.cc
index 5d551e68762..743060033f6 100644
--- a/chromium/net/tools/quic/quic_server.cc
+++ b/chromium/net/tools/quic/quic_server.cc
@@ -12,6 +12,7 @@
#include <sys/socket.h>
#include "net/base/ip_endpoint.h"
+#include "net/base/sockaddr_storage.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/quic_random.h"
#include "net/quic/quic_clock.h"
@@ -46,19 +47,11 @@ const char kSourceAddressTokenSecret[] = "secret";
} // namespace
-QuicServer::QuicServer()
- : port_(0),
- fd_(-1),
- packets_dropped_(0),
- overflow_supported_(false),
- use_recvmmsg_(false),
- crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
- supported_versions_(QuicSupportedVersions()),
- packet_reader_(new QuicPacketReader()) {
- Initialize();
-}
+QuicServer::QuicServer(ProofSource* proof_source)
+ : QuicServer(proof_source, QuicConfig(), QuicSupportedVersions()) {}
-QuicServer::QuicServer(const QuicConfig& config,
+QuicServer::QuicServer(ProofSource* proof_source,
+ const QuicConfig& config,
const QuicVersionVector& supported_versions)
: port_(0),
fd_(-1),
@@ -66,7 +59,9 @@ QuicServer::QuicServer(const QuicConfig& config,
overflow_supported_(false),
use_recvmmsg_(false),
config_(config),
- crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
+ crypto_config_(kSourceAddressTokenSecret,
+ QuicRandom::GetInstance(),
+ proof_source),
supported_versions_(supported_versions),
packet_reader_(new QuicPacketReader()) {
Initialize();
@@ -79,8 +74,8 @@ void QuicServer::Initialize() {
// If an initial flow control window has not explicitly been set, then use a
// sensible value for a server: 1 MB for session, 64 KB for each stream.
- const uint32 kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
- const uint32 kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
+ const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
+ const uint32_t kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
if (config_.GetInitialStreamFlowControlWindowToSend() ==
kMinimumFlowControlSendWindow) {
config_.SetInitialStreamFlowControlWindowToSend(
@@ -102,13 +97,11 @@ void QuicServer::Initialize() {
QuicEpollClock clock(&epoll_server_);
scoped_ptr<CryptoHandshakeMessage> scfg(
- crypto_config_.AddDefaultConfig(
- QuicRandom::GetInstance(), &clock,
- QuicCryptoServerConfig::ConfigOptions()));
+ crypto_config_.AddDefaultConfig(QuicRandom::GetInstance(), &clock,
+ QuicCryptoServerConfig::ConfigOptions()));
}
-QuicServer::~QuicServer() {
-}
+QuicServer::~QuicServer() {}
bool QuicServer::Listen(const IPEndPoint& address) {
port_ = address.port();
@@ -129,8 +122,8 @@ bool QuicServer::Listen(const IPEndPoint& address) {
}
int get_overflow = 1;
- rc = setsockopt(
- fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, sizeof(get_overflow));
+ rc = setsockopt(fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
+ sizeof(get_overflow));
if (rc < 0) {
DLOG(WARNING) << "Socket overflow detection not supported";
@@ -154,9 +147,8 @@ bool QuicServer::Listen(const IPEndPoint& address) {
socklen_t raw_addr_len = sizeof(raw_addr);
CHECK(address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr),
&raw_addr_len));
- rc = bind(fd_,
- reinterpret_cast<const sockaddr*>(&raw_addr),
- sizeof(raw_addr));
+ rc =
+ bind(fd_, reinterpret_cast<const sockaddr*>(&raw_addr), sizeof(raw_addr));
if (rc < 0) {
LOG(ERROR) << "Bind failed: " << strerror(errno);
return false;
@@ -187,12 +179,8 @@ QuicDefaultPacketWriter* QuicServer::CreateWriter(int fd) {
}
QuicDispatcher* QuicServer::CreateQuicDispatcher() {
- return new QuicDispatcher(
- config_,
- &crypto_config_,
- supported_versions_,
- new QuicDispatcher::DefaultPacketWriterFactory(),
- new QuicEpollConnectionHelper(&epoll_server_));
+ return new QuicDispatcher(config_, &crypto_config_, supported_versions_,
+ new QuicEpollConnectionHelper(&epoll_server_));
}
void QuicServer::WaitForEvents() {
@@ -214,14 +202,14 @@ void QuicServer::OnEvent(int fd, EpollEvent* event) {
if (event->in_events & EPOLLIN) {
DVLOG(1) << "EPOLLIN";
- bool read = true;
- while (read) {
+ bool more_to_read = true;
+ while (more_to_read) {
if (use_recvmmsg_) {
- read = packet_reader_->ReadAndDispatchPackets(
+ more_to_read = packet_reader_->ReadAndDispatchPackets(
fd_, port_, dispatcher_.get(),
overflow_supported_ ? &packets_dropped_ : nullptr);
} else {
- read = QuicPacketReader::ReadAndDispatchSinglePacket(
+ more_to_read = QuicPacketReader::ReadAndDispatchSinglePacket(
fd_, port_, dispatcher_.get(),
overflow_supported_ ? &packets_dropped_ : nullptr);
}
diff --git a/chromium/net/tools/quic/quic_server.h b/chromium/net/tools/quic/quic_server.h
index 56b9e4da850..b2023e3c8c5 100644
--- a/chromium/net/tools/quic/quic_server.h
+++ b/chromium/net/tools/quic/quic_server.h
@@ -11,12 +11,14 @@
#ifndef NET_TOOLS_QUIC_QUIC_SERVER_H_
#define NET_TOOLS_QUIC_QUIC_SERVER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_config.h"
-#include "net/quic/quic_connection_helper.h"
#include "net/quic/quic_framer.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "net/tools/quic/quic_default_packet_writer.h"
@@ -34,8 +36,9 @@ class QuicPacketReader;
class QuicServer : public EpollCallbackInterface {
public:
- QuicServer();
- QuicServer(const QuicConfig& config,
+ explicit QuicServer(ProofSource* proof_source);
+ QuicServer(ProofSource* proof_source,
+ const QuicConfig& config,
const QuicVersionVector& supported_versions);
~QuicServer() override;
@@ -61,10 +64,8 @@ class QuicServer : public EpollCallbackInterface {
crypto_config_.set_strike_register_no_startup_period();
}
- // SetProofSource sets the ProofSource that will be used to verify the
- // server's certificate, and takes ownership of |source|.
- void SetProofSource(ProofSource* source) {
- crypto_config_.SetProofSource(source);
+ void SetChloMultiplier(size_t multiplier) {
+ crypto_config_.set_chlo_multiplier(multiplier);
}
bool overflow_supported() { return overflow_supported_; }
@@ -79,9 +80,7 @@ class QuicServer : public EpollCallbackInterface {
virtual QuicDispatcher* CreateQuicDispatcher();
const QuicConfig& config() const { return config_; }
- const QuicCryptoServerConfig& crypto_config() const {
- return crypto_config_;
- }
+ const QuicCryptoServerConfig& crypto_config() const { return crypto_config_; }
const QuicVersionVector& supported_versions() const {
return supported_versions_;
}
diff --git a/chromium/net/tools/quic/quic_server_bin.cc b/chromium/net/tools/quic/quic_server_bin.cc
index e5e212e00ca..5e04ccbaab0 100644
--- a/chromium/net/tools/quic/quic_server_bin.cc
+++ b/chromium/net/tools/quic/quic_server_bin.cc
@@ -8,7 +8,6 @@
#include <iostream>
#include "base/at_exit.h"
-#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/run_loop.h"
@@ -20,16 +19,16 @@
#include "net/tools/quic/quic_server.h"
// The port the quic server will listen on.
-int32 FLAGS_port = 6121;
+int32_t FLAGS_port = 6121;
net::ProofSource* CreateProofSource(const base::FilePath& cert_path,
const base::FilePath& key_path) {
net::ProofSourceChromium* proof_source = new net::ProofSourceChromium();
- CHECK(proof_source->Initialize(cert_path, key_path));
+ CHECK(proof_source->Initialize(cert_path, key_path, base::FilePath()));
return proof_source;
}
-int main(int argc, char *argv[]) {
+int main(int argc, char* argv[]) {
base::AtExitManager exit_manager;
base::MessageLoopForIO message_loop;
@@ -67,23 +66,25 @@ int main(int argc, char *argv[]) {
}
}
- net::IPAddressNumber ip;
- CHECK(net::ParseIPLiteralToNumber("::", &ip));
-
- net::QuicConfig config;
- net::tools::QuicServer server(config, net::QuicSupportedVersions());
- server.SetStrikeRegisterNoStartupPeriod();
if (!line->HasSwitch("certificate_file")) {
LOG(ERROR) << "missing --certificate_file";
return 1;
}
+
if (!line->HasSwitch("key_file")) {
LOG(ERROR) << "missing --key_file";
return 1;
}
- server.SetProofSource(
+
+ net::IPAddressNumber ip;
+ CHECK(net::ParseIPLiteralToNumber("::", &ip));
+
+ net::QuicConfig config;
+ net::tools::QuicServer server(
CreateProofSource(line->GetSwitchValuePath("certificate_file"),
- line->GetSwitchValuePath("key_file")));
+ line->GetSwitchValuePath("key_file")),
+ config, net::QuicSupportedVersions());
+ server.SetStrikeRegisterNoStartupPeriod();
int rc = server.Listen(net::IPEndPoint(ip, FLAGS_port));
if (rc < 0) {
diff --git a/chromium/net/tools/quic/quic_server_session.cc b/chromium/net/tools/quic/quic_server_session_base.cc
index cca2bb8d9ca..835df612ffb 100644
--- a/chromium/net/tools/quic/quic_server_session.cc
+++ b/chromium/net/tools/quic/quic_server_session_base.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/tools/quic/quic_server_session.h"
+#include "net/tools/quic/quic_server_session_base.h"
#include "base/logging.h"
#include "net/quic/proto/cached_network_parameters.pb.h"
@@ -10,12 +10,11 @@
#include "net/quic/quic_flags.h"
#include "net/quic/quic_spdy_session.h"
#include "net/quic/reliable_quic_stream.h"
-#include "net/tools/quic/quic_spdy_server_stream.h"
namespace net {
namespace tools {
-QuicServerSession::QuicServerSession(
+QuicServerSessionBase::QuicServerSessionBase(
const QuicConfig& config,
QuicConnection* connection,
QuicServerSessionVisitor* visitor,
@@ -28,19 +27,14 @@ QuicServerSession::QuicServerSession(
last_scup_time_(QuicTime::Zero()),
last_scup_packet_number_(0) {}
-QuicServerSession::~QuicServerSession() {}
+QuicServerSessionBase::~QuicServerSessionBase() {}
-void QuicServerSession::Initialize() {
+void QuicServerSessionBase::Initialize() {
crypto_stream_.reset(CreateQuicCryptoServerStream(crypto_config_));
QuicSpdySession::Initialize();
}
-QuicCryptoServerStream* QuicServerSession::CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config) {
- return new QuicCryptoServerStream(crypto_config, this);
-}
-
-void QuicServerSession::OnConfigNegotiated() {
+void QuicServerSessionBase::OnConfigNegotiated() {
QuicSession::OnConfigNegotiated();
if (!config()->HasReceivedConnectionOptions()) {
@@ -51,7 +45,7 @@ void QuicServerSession::OnConfigNegotiated() {
// region, then pass it to the sent packet manager in preparation for possible
// bandwidth resumption.
const CachedNetworkParameters* cached_network_params =
- crypto_stream_->previous_cached_network_params();
+ crypto_stream_->PreviousCachedNetworkParams();
const bool last_bandwidth_resumption =
ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE);
const bool max_bandwidth_resumption =
@@ -60,7 +54,7 @@ void QuicServerSession::OnConfigNegotiated() {
last_bandwidth_resumption || max_bandwidth_resumption;
if (cached_network_params != nullptr && bandwidth_resumption_enabled_ &&
cached_network_params->serving_region() == serving_region_) {
- int64 seconds_since_estimate =
+ int64_t seconds_since_estimate =
connection()->clock()->WallNow().ToUNIXSeconds() -
cached_network_params->timestamp();
bool estimate_within_last_hour =
@@ -79,8 +73,8 @@ void QuicServerSession::OnConfigNegotiated() {
}
}
-void QuicServerSession::OnConnectionClosed(QuicErrorCode error,
- bool from_peer) {
+void QuicServerSessionBase::OnConnectionClosed(QuicErrorCode error,
+ bool from_peer) {
QuicSession::OnConnectionClosed(error, from_peer);
// In the unlikely event we get a connection close while doing an asynchronous
// crypto event, make sure we cancel the callback.
@@ -90,12 +84,12 @@ void QuicServerSession::OnConnectionClosed(QuicErrorCode error,
visitor_->OnConnectionClosed(connection()->connection_id(), error);
}
-void QuicServerSession::OnWriteBlocked() {
+void QuicServerSessionBase::OnWriteBlocked() {
QuicSession::OnWriteBlocked();
visitor_->OnWriteBlocked(connection());
}
-void QuicServerSession::OnCongestionWindowChange(QuicTime now) {
+void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) {
if (!bandwidth_resumption_enabled_) {
return;
}
@@ -108,10 +102,10 @@ void QuicServerSession::OnCongestionWindowChange(QuicTime now) {
// client, or not enough packets have been sent, then return early.
const QuicSentPacketManager& sent_packet_manager =
connection()->sent_packet_manager();
- int64 srtt_ms =
+ int64_t srtt_ms =
sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds();
- int64 now_ms = now.Subtract(last_scup_time_).ToMilliseconds();
- int64 packets_since_last_scup =
+ int64_t now_ms = now.Subtract(last_scup_time_).ToMilliseconds();
+ int64_t packets_since_last_scup =
connection()->packet_number_of_last_sent_packet() -
last_scup_packet_number_;
if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) ||
@@ -132,7 +126,7 @@ void QuicServerSession::OnCongestionWindowChange(QuicTime now) {
// we sent to the client, and if so, send the new one.
QuicBandwidth new_bandwidth_estimate = bandwidth_recorder.BandwidthEstimate();
- int64 bandwidth_delta =
+ int64_t bandwidth_delta =
std::abs(new_bandwidth_estimate.ToBitsPerSecond() -
bandwidth_estimate_sent_to_client_.ToBitsPerSecond());
@@ -152,7 +146,7 @@ void QuicServerSession::OnCongestionWindowChange(QuicTime now) {
// Include max bandwidth in the update.
QuicBandwidth max_bandwidth_estimate =
bandwidth_recorder.MaxBandwidthEstimate();
- int32 max_bandwidth_timestamp = bandwidth_recorder.MaxBandwidthTimestamp();
+ int32_t max_bandwidth_timestamp = bandwidth_recorder.MaxBandwidthTimestamp();
// Fill the proto before passing it to the crypto stream to send.
CachedNetworkParameters cached_network_params;
@@ -182,7 +176,7 @@ void QuicServerSession::OnCongestionWindowChange(QuicTime now) {
last_scup_packet_number_ = connection()->packet_number_of_last_sent_packet();
}
-bool QuicServerSession::ShouldCreateIncomingDynamicStream(QuicStreamId id) {
+bool QuicServerSessionBase::ShouldCreateIncomingDynamicStream(QuicStreamId id) {
if (!connection()->connected()) {
LOG(DFATAL) << "ShouldCreateIncomingDynamicStream called when disconnected";
return false;
@@ -190,27 +184,31 @@ bool QuicServerSession::ShouldCreateIncomingDynamicStream(QuicStreamId id) {
if (id % 2 == 0) {
DVLOG(1) << "Invalid incoming even stream_id:" << id;
- connection()->SendConnectionClose(QUIC_INVALID_STREAM_ID);
+ connection()->SendConnectionCloseWithDetails(
+ QUIC_INVALID_STREAM_ID, "Client created even numbered stream");
return false;
}
return true;
}
-QuicDataStream* QuicServerSession::CreateIncomingDynamicStream(
- QuicStreamId id) {
- if (!ShouldCreateIncomingDynamicStream(id)) {
- return nullptr;
+bool QuicServerSessionBase::ShouldCreateOutgoingDynamicStream() {
+ if (!connection()->connected()) {
+ LOG(DFATAL) << "ShouldCreateOutgoingDynamicStream called when disconnected";
+ return false;
}
-
- return new QuicSpdyServerStream(id, this);
-}
-
-QuicDataStream* QuicServerSession::CreateOutgoingDynamicStream() {
- DLOG(ERROR) << "Server push not yet supported";
- return nullptr;
+ if (!crypto_stream_->encryption_established()) {
+ LOG(DFATAL) << "Encryption not established so no outgoing stream created.";
+ return false;
+ }
+ if (GetNumOpenOutgoingStreams() >= get_max_open_streams()) {
+ VLOG(1) << "No more streams should be created. "
+ << "Already " << GetNumOpenOutgoingStreams() << " open.";
+ return false;
+ }
+ return true;
}
-QuicCryptoServerStream* QuicServerSession::GetCryptoStream() {
+QuicCryptoServerStreamBase* QuicServerSessionBase::GetCryptoStream() {
return crypto_stream_.get();
}
diff --git a/chromium/net/tools/quic/quic_server_session.h b/chromium/net/tools/quic/quic_server_session_base.h
index 14d7b29f8a7..a68d52bd293 100644
--- a/chromium/net/tools/quic/quic_server_session.h
+++ b/chromium/net/tools/quic/quic_server_session_base.h
@@ -4,15 +4,17 @@
//
// A server specific QuicSession subclass.
-#ifndef NET_TOOLS_QUIC_QUIC_SERVER_SESSION_H_
-#define NET_TOOLS_QUIC_QUIC_SERVER_SESSION_H_
+#ifndef NET_TOOLS_QUIC_QUIC_SERVER_SESSION_BASE_H_
+#define NET_TOOLS_QUIC_QUIC_SERVER_SESSION_BASE_H_
+
+#include <stdint.h>
#include <set>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/quic_crypto_server_stream.h"
#include "net/quic/quic_protocol.h"
@@ -29,7 +31,8 @@ class ReliableQuicStream;
namespace tools {
namespace test {
-class QuicServerSessionPeer;
+class QuicServerSessionBasePeer;
+class QuicSimpleServerSessionPeer;
} // namespace test
// An interface from the session to the entity owning the session.
@@ -50,13 +53,13 @@ class QuicServerSessionVisitor {
QuicConnectionId connection_id) {}
};
-class QuicServerSession : public QuicSpdySession {
+class QuicServerSessionBase : public QuicSpdySession {
public:
// |crypto_config| must outlive the session.
- QuicServerSession(const QuicConfig& config,
- QuicConnection* connection,
- QuicServerSessionVisitor* visitor,
- const QuicCryptoServerConfig* crypto_config);
+ QuicServerSessionBase(const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config);
// Override the base class to notify the owner of the connection close.
void OnConnectionClosed(QuicErrorCode error, bool from_peer) override;
@@ -66,61 +69,47 @@ class QuicServerSession : public QuicSpdySession {
// estimate.
void OnCongestionWindowChange(QuicTime now) override;
- ~QuicServerSession() override;
+ ~QuicServerSessionBase() override;
void Initialize() override;
- const QuicCryptoServerStream* crypto_stream() const {
+ const QuicCryptoServerStreamBase* crypto_stream() const {
return crypto_stream_.get();
}
// Override base class to process FEC config received from client.
void OnConfigNegotiated() override;
- bool UsingStatelessRejectsIfPeerSupported() {
- if (GetCryptoStream() == nullptr) {
- return false;
- }
- return GetCryptoStream()->use_stateless_rejects_if_peer_supported();
- }
-
- bool PeerSupportsStatelessRejects() {
- if (GetCryptoStream() == nullptr) {
- return false;
- }
- return GetCryptoStream()->peer_supports_stateless_rejects();
- }
-
void set_serving_region(const std::string& serving_region) {
serving_region_ = serving_region;
}
- void set_use_stateless_rejects_if_peer_supported(
- bool use_stateless_rejects_if_peer_supported) {
- DCHECK(GetCryptoStream() != nullptr);
- GetCryptoStream()->set_use_stateless_rejects_if_peer_supported(
- use_stateless_rejects_if_peer_supported);
- }
-
protected:
- // QuicSession methods:
- QuicDataStream* CreateIncomingDynamicStream(QuicStreamId id) override;
- QuicDataStream* CreateOutgoingDynamicStream() override;
- QuicCryptoServerStream* GetCryptoStream() override;
+ // QuicSession methods(override them with return type of QuicSpdyStream*):
+ QuicCryptoServerStreamBase* GetCryptoStream() override;
+
+ // If an outgoing stream can be created, return true.
+ // Return false when connection is closed or forward secure encryption hasn't
+ // established yet or number of server initiated streams already reaches the
+ // upper limit.
+ bool ShouldCreateOutgoingDynamicStream();
// If we should create an incoming stream, returns true. Otherwise
// does error handling, including communicating the error to the client and
// possibly closing the connection, and returns false.
virtual bool ShouldCreateIncomingDynamicStream(QuicStreamId id);
- virtual QuicCryptoServerStream* CreateQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config);
+ virtual QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) = 0;
+
+ const QuicCryptoServerConfig* crypto_config() { return crypto_config_; }
private:
- friend class test::QuicServerSessionPeer;
+ friend class test::QuicServerSessionBasePeer;
+ friend class test::QuicSimpleServerSessionPeer;
const QuicCryptoServerConfig* crypto_config_;
- scoped_ptr<QuicCryptoServerStream> crypto_stream_;
+ scoped_ptr<QuicCryptoServerStreamBase> crypto_stream_;
QuicServerSessionVisitor* visitor_;
// Whether bandwidth resumption is enabled for this connection.
@@ -137,12 +126,12 @@ class QuicServerSession : public QuicSpdySession {
QuicTime last_scup_time_;
// Number of packets sent to the peer, at the time we last sent a SCUP.
- int64 last_scup_packet_number_;
+ int64_t last_scup_packet_number_;
- DISALLOW_COPY_AND_ASSIGN(QuicServerSession);
+ DISALLOW_COPY_AND_ASSIGN(QuicServerSessionBase);
};
} // namespace tools
} // namespace net
-#endif // NET_TOOLS_QUIC_QUIC_SERVER_SESSION_H_
+#endif // NET_TOOLS_QUIC_QUIC_SERVER_SESSION_BASE_H_
diff --git a/chromium/net/tools/quic/quic_server_session_test.cc b/chromium/net/tools/quic/quic_server_session_base_test.cc
index 62cb49110b4..36432aa5749 100644
--- a/chromium/net/tools/quic/quic_server_session_test.cc
+++ b/chromium/net/tools/quic/quic_server_session_base_test.cc
@@ -2,34 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/tools/quic/quic_server_session.h"
+#include "net/tools/quic/quic_server_session_base.h"
+#include "base/macros.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/crypto/quic_random.h"
#include "net/quic/proto/cached_network_parameters.pb.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_crypto_server_stream.h"
-#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.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_data_stream_peer.h"
#include "net/quic/test_tools/quic_sent_packet_manager_peer.h"
#include "net/quic/test_tools/quic_session_peer.h"
#include "net/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/quic/test_tools/quic_spdy_stream_peer.h"
#include "net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/test/gtest_util.h"
-#include "net/tools/quic/quic_spdy_server_stream.h"
+#include "net/tools/quic/quic_simple_server_stream.h"
#include "net/tools/quic/test_tools/mock_quic_server_session_visitor.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using __gnu_cxx::vector;
+using net::test::CryptoTestUtils;
using net::test::MockConnection;
+using net::test::MockConnectionHelper;
using net::test::QuicConfigPeer;
using net::test::QuicConnectionPeer;
-using net::test::QuicDataStreamPeer;
+using net::test::QuicSpdyStreamPeer;
using net::test::QuicSentPacketManagerPeer;
using net::test::QuicSessionPeer;
using net::test::QuicSpdySessionPeer;
@@ -49,42 +52,78 @@ namespace net {
namespace tools {
namespace test {
-class QuicServerSessionPeer {
+class QuicServerSessionBasePeer {
public:
- static ReliableQuicStream* GetIncomingDynamicStream(QuicServerSession* s,
+ static ReliableQuicStream* GetOrCreateDynamicStream(QuicServerSessionBase* s,
QuicStreamId id) {
- return s->GetIncomingDynamicStream(id);
+ return s->GetOrCreateDynamicStream(id);
}
- static void SetCryptoStream(QuicServerSession* s,
+ static void SetCryptoStream(QuicServerSessionBase* s,
QuicCryptoServerStream* crypto_stream) {
s->crypto_stream_.reset(crypto_stream);
s->static_streams()[kCryptoStreamId] = crypto_stream;
}
- static bool IsBandwidthResumptionEnabled(QuicServerSession* s) {
+ static bool IsBandwidthResumptionEnabled(QuicServerSessionBase* s) {
return s->bandwidth_resumption_enabled_;
}
};
namespace {
+class TestServerSession : public QuicServerSessionBase {
+ public:
+ TestServerSession(const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config)
+ : QuicServerSessionBase(config, connection, visitor, crypto_config) {}
+
+ ~TestServerSession() override{};
+
+ protected:
+ QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override {
+ if (!ShouldCreateIncomingDynamicStream(id)) {
+ return nullptr;
+ }
+ return new QuicSimpleServerStream(id, this);
+ }
+
+ QuicSpdyStream* CreateOutgoingDynamicStream(SpdyPriority priority) override {
+ if (!ShouldCreateOutgoingDynamicStream()) {
+ return nullptr;
+ }
+
+ QuicSpdyStream* stream =
+ new QuicSimpleServerStream(GetNextOutgoingStreamId(), this);
+ stream->SetPriority(priority);
+ ActivateStream(stream);
+ return stream;
+ }
+
+ QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) override {
+ return new QuicCryptoServerStream(crypto_config, this);
+ }
+};
+
const size_t kMaxStreamsForTest = 10;
-class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> {
+class QuicServerSessionBaseTest : public ::testing::TestWithParam<QuicVersion> {
protected:
- QuicServerSessionTest()
+ QuicServerSessionBaseTest()
: crypto_config_(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance()) {
- config_.SetMaxStreamsPerConnection(kMaxStreamsForTest,
- kMaxStreamsForTest);
+ QuicRandom::GetInstance(),
+ CryptoTestUtils::ProofSourceForTesting()) {
+ config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
config_.SetInitialStreamFlowControlWindowToSend(
kInitialStreamFlowControlWindowForTest);
config_.SetInitialSessionFlowControlWindowToSend(
kInitialSessionFlowControlWindowForTest);
- connection_ = new StrictMock<MockConnection>(Perspective::IS_SERVER,
- SupportedVersions(GetParam()));
+ connection_ = new StrictMock<MockConnection>(
+ &helper_, Perspective::IS_SERVER, SupportedVersions(GetParam()));
session_.reset(
- new QuicServerSession(config_, connection_, &owner_, &crypto_config_));
+ new TestServerSession(config_, connection_, &owner_, &crypto_config_));
MockClock clock;
handshake_message_.reset(crypto_config_.AddDefaultConfig(
QuicRandom::GetInstance(), &clock,
@@ -94,10 +133,11 @@ class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> {
}
StrictMock<MockQuicServerSessionVisitor> owner_;
+ MockConnectionHelper helper_;
StrictMock<MockConnection>* connection_;
QuicConfig config_;
QuicCryptoServerConfig crypto_config_;
- scoped_ptr<QuicServerSession> session_;
+ scoped_ptr<TestServerSession> session_;
scoped_ptr<CryptoHandshakeMessage> handshake_message_;
QuicConnectionVisitorInterface* visitor_;
};
@@ -106,61 +146,64 @@ class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> {
MATCHER_P(EqualsProto, network_params, "") {
CachedNetworkParameters reference(network_params);
return (arg->bandwidth_estimate_bytes_per_second() ==
- reference.bandwidth_estimate_bytes_per_second() &&
+ reference.bandwidth_estimate_bytes_per_second() &&
arg->bandwidth_estimate_bytes_per_second() ==
- reference.bandwidth_estimate_bytes_per_second() &&
+ reference.bandwidth_estimate_bytes_per_second() &&
arg->max_bandwidth_estimate_bytes_per_second() ==
- reference.max_bandwidth_estimate_bytes_per_second() &&
+ reference.max_bandwidth_estimate_bytes_per_second() &&
arg->max_bandwidth_timestamp_seconds() ==
- reference.max_bandwidth_timestamp_seconds() &&
+ reference.max_bandwidth_timestamp_seconds() &&
arg->min_rtt_ms() == reference.min_rtt_ms() &&
arg->previous_connection_state() ==
- reference.previous_connection_state());
+ reference.previous_connection_state());
}
-INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest,
+INSTANTIATE_TEST_CASE_P(Tests,
+ QuicServerSessionBaseTest,
::testing::ValuesIn(QuicSupportedVersions()));
-TEST_P(QuicServerSessionTest, CloseStreamDueToReset) {
+TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
// Open a stream, then reset it.
// Send two bytes of payload to open it.
QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
session_->OnStreamFrame(data1);
- EXPECT_EQ(1u, session_->GetNumOpenStreams());
+ EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
// Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
+ QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_ERROR_PROCESSING_STREAM,
+ 0);
EXPECT_CALL(*connection_,
SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
visitor_->OnRstStream(rst1);
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
// Send the same two bytes of payload in a new packet.
visitor_->OnStreamFrame(data1);
// The stream should not be re-opened.
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
EXPECT_TRUE(connection_->connected());
}
-TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) {
+TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
// Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
+ QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_ERROR_PROCESSING_STREAM,
+ 0);
EXPECT_CALL(*connection_,
SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
visitor_->OnRstStream(rst1);
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
// Send two bytes of payload.
QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
visitor_->OnStreamFrame(data1);
// The stream should never be opened, now that the reset is received.
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
EXPECT_TRUE(connection_->connected());
}
-TEST_P(QuicServerSessionTest, AcceptClosedStream) {
+TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
// Send (empty) compressed headers followed by two bytes of data.
QuicStreamFrame frame1(kClientDataStreamId1, false, 0,
StringPiece("\1\0\0\0\0\0\0\0HT"));
@@ -168,10 +211,10 @@ TEST_P(QuicServerSessionTest, AcceptClosedStream) {
StringPiece("\2\0\0\0\0\0\0\0HT"));
visitor_->OnStreamFrame(frame1);
visitor_->OnStreamFrame(frame2);
- EXPECT_EQ(2u, session_->GetNumOpenStreams());
+ EXPECT_EQ(2u, session_->GetNumOpenIncomingStreams());
// Send a reset (and expect the peer to send a RST in response).
- QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
+ QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(*connection_,
SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
visitor_->OnRstStream(rst);
@@ -184,94 +227,106 @@ TEST_P(QuicServerSessionTest, AcceptClosedStream) {
visitor_->OnStreamFrame(frame3);
visitor_->OnStreamFrame(frame4);
// The stream should never be opened, now that the reset is received.
- EXPECT_EQ(1u, session_->GetNumOpenStreams());
+ EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
EXPECT_TRUE(connection_->connected());
}
-TEST_P(QuicServerSessionTest, MaxOpenStreams) {
- // Test that the server closes the connection if a client attempts to open too
- // many data streams. The server accepts slightly more than the negotiated
- // stream limit to deal with rare cases where a client FIN/RST is lost.
+TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
+ // Test that the server refuses if a client attempts to open too many data
+ // streams. The server accepts slightly more than the negotiated stream limit
+ // to deal with rare cases where a client FIN/RST is lost.
- // The slightly increased stream limit is set during config negotiation. It
- // should be either an increase of 10 over negotiated limit, or a fixed
- // percentage scaling, whichever is larger. Test both before continuing.
+ // The slightly increased stream limit is set during config negotiation. It
+ // is either an increase of 10 over negotiated limit, or a fixed percentage
+ // scaling, whichever is larger. Test both before continuing.
EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
session_->OnConfigNegotiated();
EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
session_->get_max_open_streams());
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
QuicStreamId stream_id = kClientDataStreamId1;
// Open the max configured number of streams, should be no problem.
for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
- EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(),
- stream_id));
+ EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+ session_.get(), stream_id));
stream_id += 2;
}
// Open more streams: server should accept slightly more than the limit.
for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
- EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(),
- stream_id));
+ EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+ session_.get(), stream_id));
stream_id += 2;
}
// Now violate the server's internal stream limit.
- EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
stream_id += 2;
- EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(),
- stream_id));
+ if (connection_->version() <= QUIC_VERSION_27) {
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(QUIC_TOO_MANY_OPEN_STREAMS, _));
+ EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(0);
+ } else {
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
+ EXPECT_CALL(*connection_, SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0));
+ }
+ // Even if the connection remains open, the stream creation should fail.
+ EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+ session_.get(), stream_id));
}
-TEST_P(QuicServerSessionTest, MaxOpenStreamsImplicit) {
- // Test that the server closes the connection if a client attempts to open too
- // many data streams implicitly. The server accepts slightly more than the
- // negotiated stream limit to deal with rare cases where a client FIN/RST is
- // lost.
+TEST_P(QuicServerSessionBaseTest, MaxAvailableStreams) {
+ // Test that the server closes the connection if a client makes too many data
+ // streams available. The server accepts slightly more than the negotiated
+ // stream limit to deal with rare cases where a client FIN/RST is lost.
// The slightly increased stream limit is set during config negotiation.
EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
session_->OnConfigNegotiated();
- EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
- kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
- EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
- session_->get_max_open_streams());
-
- EXPECT_EQ(0u, session_->GetNumOpenStreams());
- EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream(
+ const size_t kAvailableStreamLimit = session_->get_max_available_streams();
+ EXPECT_EQ(session_->get_max_open_streams() * kMaxAvailableStreamsMultiplier,
+ session_->get_max_available_streams());
+ // The protocol specification requires that there can be at least 10 times
+ // as many available streams as the connection's maximum open streams.
+ EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit);
+
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+ EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
session_.get(), kClientDataStreamId1));
- // Implicitly open streams up to the server's limit.
- const int kActualMaxStreams =
- kMaxStreamsForTest + kMaxStreamsMinimumIncrement;
- const int kMaxValidStreamId =
- kClientDataStreamId1 + (kActualMaxStreams - 1) * 2;
- EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream(
- session_.get(), kMaxValidStreamId));
-
- // Opening a further stream will result in connection close.
- EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
- EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDynamicStream(
- session_.get(), kMaxValidStreamId + 2));
+
+ // Establish available streams up to the server's limit.
+ const int kLimitingStreamId =
+ kClientDataStreamId1 + (kAvailableStreamLimit)*2 + 2;
+ EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+ session_.get(), kLimitingStreamId));
+
+ // A further available stream will result in connection close.
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_TOO_MANY_AVAILABLE_STREAMS, _));
+ // This forces stream kLimitingStreamId + 2 to become available, which
+ // violates the quota.
+ EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+ session_.get(), kLimitingStreamId + 4));
}
-TEST_P(QuicServerSessionTest, GetEvenIncomingError) {
+TEST_P(QuicServerSessionBaseTest, GetEvenIncomingError) {
// Incoming streams on the server session must be odd.
- EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID));
- EXPECT_EQ(nullptr,
- QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), 4));
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(QUIC_INVALID_STREAM_ID, _));
+ EXPECT_EQ(nullptr, QuicServerSessionBasePeer::GetOrCreateDynamicStream(
+ session_.get(), 4));
}
-TEST_P(QuicServerSessionTest, GetStreamDisconnected) {
+TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) {
// Don't create new streams if the connection is disconnected.
QuicConnectionPeer::CloseConnection(connection_);
EXPECT_DFATAL(
- QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), 5),
+ QuicServerSessionBasePeer::GetOrCreateDynamicStream(session_.get(), 5),
"ShouldCreateIncomingDynamicStream called when disconnected");
}
-TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) {
+TEST_P(QuicServerSessionBaseTest, SetFecProtectionFromConfig) {
ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true);
// Set received config to have FEC connection option.
@@ -282,10 +337,12 @@ TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) {
// Verify that headers stream is always protected and data streams are
// optionally protected.
- EXPECT_EQ(FEC_PROTECT_ALWAYS, QuicSpdySessionPeer::GetHeadersStream(
- session_.get())->fec_policy());
- ReliableQuicStream* stream = QuicServerSessionPeer::GetIncomingDynamicStream(
- session_.get(), kClientDataStreamId1);
+ EXPECT_EQ(
+ FEC_PROTECT_ALWAYS,
+ QuicSpdySessionPeer::GetHeadersStream(session_.get())->fec_policy());
+ ReliableQuicStream* stream =
+ QuicServerSessionBasePeer::GetOrCreateDynamicStream(session_.get(),
+ kClientDataStreamId1);
ASSERT_TRUE(stream);
EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy());
}
@@ -293,18 +350,23 @@ TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) {
class MockQuicCryptoServerStream : public QuicCryptoServerStream {
public:
explicit MockQuicCryptoServerStream(
- const QuicCryptoServerConfig* crypto_config, QuicSession* session)
+ const QuicCryptoServerConfig* crypto_config,
+ QuicSession* session)
: QuicCryptoServerStream(crypto_config, session) {}
~MockQuicCryptoServerStream() override {}
MOCK_METHOD1(SendServerConfigUpdate,
void(const CachedNetworkParameters* cached_network_parameters));
+ void set_encryption_established(bool has_established) {
+ encryption_established_ = has_established;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
};
-TEST_P(QuicServerSessionTest, BandwidthEstimates) {
+TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
// Test that bandwidth estimate updates are sent to the client, only when
// bandwidth resumption is enabled, the bandwidth estimate has changed
// sufficiently, enough time has passed,
@@ -316,17 +378,17 @@ TEST_P(QuicServerSessionTest, BandwidthEstimates) {
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
session_->OnConfigNegotiated();
EXPECT_TRUE(
- QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
+ QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
- int32 bandwidth_estimate_kbytes_per_second = 123;
- int32 max_bandwidth_estimate_kbytes_per_second = 134;
- int32 max_bandwidth_estimate_timestamp = 1122334455;
+ int32_t bandwidth_estimate_kbytes_per_second = 123;
+ int32_t max_bandwidth_estimate_kbytes_per_second = 134;
+ int32_t max_bandwidth_estimate_timestamp = 1122334455;
const string serving_region = "not a real region";
session_->set_serving_region(serving_region);
MockQuicCryptoServerStream* crypto_stream =
new MockQuicCryptoServerStream(&crypto_config_, session_.get());
- QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
+ QuicServerSessionBasePeer::SetCryptoStream(session_.get(), crypto_stream);
// Set some initial bandwidth values.
QuicSentPacketManager* sent_packet_manager =
@@ -336,16 +398,17 @@ TEST_P(QuicServerSessionTest, BandwidthEstimates) {
// Seed an rtt measurement equal to the initial default rtt.
RttStats* rtt_stats =
QuicSentPacketManagerPeer::GetRttStats(sent_packet_manager);
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(
- rtt_stats->initial_rtt_us()), QuicTime::Delta::Zero(), QuicTime::Zero());
+ rtt_stats->UpdateRtt(
+ QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us()),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
&bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
&bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
max_bandwidth_estimate_timestamp);
// Queue up some pending data.
- session_->MarkConnectionLevelWriteBlocked(
- kCryptoStreamId, QuicWriteBlockedList::kHighestPriority);
+ session_->MarkConnectionLevelWriteBlocked(kCryptoStreamId,
+ net::kV3HighestPriority);
EXPECT_TRUE(session_->HasDataToWrite());
// There will be no update sent yet - not enough time has passed.
@@ -360,7 +423,7 @@ TEST_P(QuicServerSessionTest, BandwidthEstimates) {
// Bandwidth estimate has now changed sufficiently and enough time has passed,
// but not enough packets have been sent.
- int64 srtt_ms =
+ int64_t srtt_ms =
sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
now = now.Add(QuicTime::Delta::FromMilliseconds(
kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms));
@@ -402,7 +465,7 @@ TEST_P(QuicServerSessionTest, BandwidthEstimates) {
session_->OnCongestionWindowChange(now);
}
-TEST_P(QuicServerSessionTest, BandwidthResumptionExperiment) {
+TEST_P(QuicServerSessionBaseTest, BandwidthResumptionExperiment) {
// Test that if a client provides a CachedNetworkParameters with the same
// serving region as the current server, and which was made within an hour of
// now, that this data is passed down to the send algorithm.
@@ -419,9 +482,8 @@ TEST_P(QuicServerSessionTest, BandwidthResumptionExperiment) {
connection_->AdvanceTime(
QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
- QuicCryptoServerStream* crypto_stream =
- static_cast<QuicCryptoServerStream*>(
- QuicSessionPeer::GetCryptoStream(session_.get()));
+ QuicCryptoServerStream* crypto_stream = static_cast<QuicCryptoServerStream*>(
+ QuicSessionPeer::GetCryptoStream(session_.get()));
// No effect if no CachedNetworkParameters provided.
EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
@@ -432,28 +494,28 @@ TEST_P(QuicServerSessionTest, BandwidthResumptionExperiment) {
CachedNetworkParameters cached_network_params;
cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
cached_network_params.set_serving_region("different serving region");
- crypto_stream->set_previous_cached_network_params(cached_network_params);
+ crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
session_->OnConfigNegotiated();
// Same serving region, but timestamp is too old, should have no effect.
cached_network_params.set_serving_region(kTestServingRegion);
cached_network_params.set_timestamp(0);
- crypto_stream->set_previous_cached_network_params(cached_network_params);
+ crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
session_->OnConfigNegotiated();
// Same serving region, and timestamp is recent: estimate is stored.
cached_network_params.set_timestamp(
connection_->clock()->WallNow().ToUNIXSeconds());
- crypto_stream->set_previous_cached_network_params(cached_network_params);
+ crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
session_->OnConfigNegotiated();
}
-TEST_P(QuicServerSessionTest, BandwidthMaxEnablesResumption) {
+TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
EXPECT_FALSE(
- QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
+ QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
// Client has sent kBWMX connection option to trigger bandwidth resumption.
QuicTagVector copt;
@@ -461,15 +523,15 @@ TEST_P(QuicServerSessionTest, BandwidthMaxEnablesResumption) {
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
session_->OnConfigNegotiated();
EXPECT_TRUE(
- QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
+ QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
}
-TEST_P(QuicServerSessionTest, NoBandwidthResumptionByDefault) {
+TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
EXPECT_FALSE(
- QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
+ QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
session_->OnConfigNegotiated();
EXPECT_FALSE(
- QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
+ QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
}
} // namespace
diff --git a/chromium/net/tools/quic/quic_server_test.cc b/chromium/net/tools/quic/quic_server_test.cc
index 7ed7774b6c7..60b2a695629 100644
--- a/chromium/net/tools/quic/quic_server_test.cc
+++ b/chromium/net/tools/quic/quic_server_test.cc
@@ -6,11 +6,13 @@
#include "net/quic/crypto/quic_random.h"
#include "net/quic/quic_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_quic_dispatcher.h"
#include "net/tools/quic/quic_epoll_connection_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
+using net::test::CryptoTestUtils;
using net::test::MockQuicDispatcher;
namespace net {
@@ -22,10 +24,11 @@ namespace {
class QuicServerDispatchPacketTest : public ::testing::Test {
public:
QuicServerDispatchPacketTest()
- : crypto_config_("blah", QuicRandom::GetInstance()),
+ : crypto_config_("blah",
+ QuicRandom::GetInstance(),
+ CryptoTestUtils::ProofSourceForTesting()),
dispatcher_(config_,
&crypto_config_,
- new QuicDispatcher::DefaultPacketWriterFactory(),
new QuicEpollConnectionHelper(&eps_)) {
dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
}
diff --git a/chromium/net/tools/quic/quic_simple_client.cc b/chromium/net/tools/quic/quic_simple_client.cc
index 0361df6277d..4c05b6710df 100644
--- a/chromium/net/tools/quic/quic_simple_client.cc
+++ b/chromium/net/tools/quic/quic_simple_client.cc
@@ -11,8 +11,8 @@
#include "net/http/http_request_info.h"
#include "net/http/http_response_info.h"
#include "net/quic/crypto/quic_random.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_connection.h"
-#include "net/quic/quic_connection_helper.h"
#include "net/quic/quic_default_packet_writer.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_packet_reader.h"
@@ -37,11 +37,15 @@ void QuicSimpleClient::ClientQuicDataToResend::Resend() {
QuicSimpleClient::QuicSimpleClient(IPEndPoint server_address,
const QuicServerId& server_id,
- const QuicVersionVector& supported_versions)
- : QuicClientBase(server_id, supported_versions, QuicConfig()),
+ const QuicVersionVector& supported_versions,
+ ProofVerifier* proof_verifier)
+ : QuicClientBase(server_id,
+ supported_versions,
+ QuicConfig(),
+ CreateQuicConnectionHelper(),
+ proof_verifier),
server_address_(server_address),
local_port_(0),
- helper_(CreateQuicConnectionHelper()),
initialized_(false),
packet_reader_started_(false),
weak_factory_(this) {}
@@ -49,19 +53,23 @@ QuicSimpleClient::QuicSimpleClient(IPEndPoint server_address,
QuicSimpleClient::QuicSimpleClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
- const QuicConfig& config)
- : QuicClientBase(server_id, supported_versions, config),
+ const QuicConfig& config,
+ ProofVerifier* proof_verifier)
+ : QuicClientBase(server_id,
+ supported_versions,
+ config,
+ CreateQuicConnectionHelper(),
+ proof_verifier),
server_address_(server_address),
local_port_(0),
- helper_(CreateQuicConnectionHelper()),
initialized_(false),
packet_reader_started_(false),
weak_factory_(this) {}
QuicSimpleClient::~QuicSimpleClient() {
if (connected()) {
- session()->connection()->SendConnectionClosePacket(
- QUIC_PEER_GOING_AWAY, "");
+ session()->connection()->SendConnectionClosePacket(QUIC_PEER_GOING_AWAY,
+ "");
}
STLDeleteElements(&data_to_resend_on_connect_);
STLDeleteElements(&data_sent_before_handshake_);
@@ -93,10 +101,8 @@ QuicSimpleClient::QuicDataToResend::~QuicDataToResend() {
bool QuicSimpleClient::CreateUDPSocket() {
scoped_ptr<UDPClientSocket> socket(
- new UDPClientSocket(DatagramSocket::DEFAULT_BIND,
- RandIntCallback(),
- &net_log_,
- NetLog::Source()));
+ new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
+ &net_log_, NetLog::Source()));
int address_family = server_address_.GetSockAddrFamily();
if (bind_to_address_.size() != 0) {
@@ -197,8 +203,6 @@ void QuicSimpleClient::StartConnect() {
set_writer(CreateQuicPacketWriter());
- DummyPacketWriterFactory factory(writer());
-
if (connected_or_attempting_connect()) {
// Before we destroy the last session and create a new one, gather its stats
// and update the stats for the overall connection.
@@ -214,9 +218,8 @@ void QuicSimpleClient::StartConnect() {
}
CreateQuicClientSession(new QuicConnection(
- GetNextConnectionId(), server_address_, helper_.get(), factory,
- /* owns_writer= */ false, Perspective::IS_CLIENT, server_id().is_https(),
- supported_versions()));
+ GetNextConnectionId(), server_address_, helper(), writer(),
+ /* owns_writer= */ false, Perspective::IS_CLIENT, supported_versions()));
session()->Initialize();
session()->CryptoConnect();
@@ -227,7 +230,8 @@ void QuicSimpleClient::Disconnect() {
DCHECK(initialized_);
if (connected()) {
- session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY);
+ session()->connection()->SendConnectionCloseWithDetails(
+ QUIC_PEER_GOING_AWAY, "Client disconnecting");
}
STLDeleteElements(&data_to_resend_on_connect_);
STLDeleteElements(&data_sent_before_handshake_);
@@ -247,9 +251,7 @@ void QuicSimpleClient::SendRequest(const HttpRequestInfo& headers,
return;
}
SpdyHeaderBlock header_block;
- SpdyMajorVersion spdy_version =
- SpdyUtils::GetSpdyVersionForQuicVersion(stream->version());
- CreateSpdyHeadersFromHttpRequest(headers, headers.extra_headers, spdy_version,
+ CreateSpdyHeadersFromHttpRequest(headers, headers.extra_headers, net::HTTP2,
true, &header_block);
stream->set_visitor(this);
stream->SendRequest(header_block, body, fin);
@@ -284,7 +286,8 @@ void QuicSimpleClient::SendRequestAndWaitForResponse(
StringPiece body,
bool fin) {
SendRequest(request, body, fin);
- while (WaitForEvents()) {}
+ while (WaitForEvents()) {
+ }
}
void QuicSimpleClient::SendRequestsAndWaitForResponse(
@@ -296,7 +299,8 @@ void QuicSimpleClient::SendRequestsAndWaitForResponse(
SendRequest(request, "", true);
}
- while (WaitForEvents()) {}
+ while (WaitForEvents()) {
+ }
}
bool QuicSimpleClient::WaitForEvents() {
@@ -329,24 +333,21 @@ bool QuicSimpleClient::MigrateSocket(const IPAddressNumber& new_host) {
session()->connection()->SetSelfAddress(client_address_);
QuicPacketWriter* writer = CreateQuicPacketWriter();
- DummyPacketWriterFactory factory(writer);
set_writer(writer);
session()->connection()->SetQuicPacketWriter(writer, false);
return true;
}
-void QuicSimpleClient::OnClose(QuicDataStream* stream) {
+void QuicSimpleClient::OnClose(QuicSpdyStream* stream) {
DCHECK(stream != nullptr);
QuicSpdyClientStream* client_stream =
static_cast<QuicSpdyClientStream*>(stream);
HttpResponseInfo response;
- SpdyMajorVersion spdy_version =
- SpdyUtils::GetSpdyVersionForQuicVersion(client_stream->version());
- SpdyHeadersToHttpResponse(client_stream->headers(), spdy_version, &response);
+ SpdyHeadersToHttpResponse(client_stream->headers(), net::HTTP2, &response);
if (response_listener_.get() != nullptr) {
- response_listener_->OnCompleteResponse(
- stream->id(), *response.headers, client_stream->data());
+ response_listener_->OnCompleteResponse(stream->id(), *response.headers,
+ client_stream->data());
}
// Store response headers and body.
@@ -373,19 +374,21 @@ const string& QuicSimpleClient::latest_response_body() const {
}
QuicConnectionId QuicSimpleClient::GenerateNewConnectionId() {
- return helper_->GetRandomGenerator()->RandUint64();
+ return helper()->GetRandomGenerator()->RandUint64();
}
-QuicConnectionHelper* QuicSimpleClient::CreateQuicConnectionHelper() {
- return new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(),
- &clock_, QuicRandom::GetInstance());
+QuicChromiumConnectionHelper* QuicSimpleClient::CreateQuicConnectionHelper() {
+ return new QuicChromiumConnectionHelper(
+ base::ThreadTaskRunnerHandle::Get().get(), &clock_,
+ QuicRandom::GetInstance());
}
QuicPacketWriter* QuicSimpleClient::CreateQuicPacketWriter() {
return new QuicDefaultPacketWriter(socket_.get());
}
-void QuicSimpleClient::OnReadError(int result) {
+void QuicSimpleClient::OnReadError(int result,
+ const DatagramClientSocket* socket) {
LOG(ERROR) << "QuicSimpleClient read failed: " << ErrorToShortString(result);
Disconnect();
}
diff --git a/chromium/net/tools/quic/quic_simple_client.h b/chromium/net/tools/quic/quic_simple_client.h
index 88a0032189c..ce6e42555f0 100644
--- a/chromium/net/tools/quic/quic_simple_client.h
+++ b/chromium/net/tools/quic/quic_simple_client.h
@@ -8,24 +8,26 @@
#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_
#define NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_
+#include <stddef.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/ip_endpoint.h"
#include "net/http/http_response_headers.h"
#include "net/log/net_log.h"
#include "net/quic/quic_config.h"
-#include "net/quic/quic_data_stream.h"
#include "net/quic/quic_packet_reader.h"
+#include "net/quic/quic_spdy_stream.h"
#include "net/tools/quic/quic_client_base.h"
namespace net {
struct HttpRequestInfo;
-class QuicConnectionHelper;
+class QuicChromiumConnectionHelper;
class UDPClientSocket;
namespace tools {
@@ -35,7 +37,7 @@ class QuicClientPeer;
} // namespace test
class QuicSimpleClient : public QuicClientBase,
- public QuicDataStream::Visitor,
+ public QuicSpdyStream::Visitor,
public QuicPacketReader::Visitor {
public:
class ResponseListener {
@@ -81,11 +83,13 @@ class QuicSimpleClient : public QuicClientBase,
// EpollServer.
QuicSimpleClient(IPEndPoint server_address,
const QuicServerId& server_id,
- const QuicVersionVector& supported_versions);
+ const QuicVersionVector& supported_versions,
+ ProofVerifier* proof_verifier);
QuicSimpleClient(IPEndPoint server_address,
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
- const QuicConfig& config);
+ const QuicConfig& config,
+ ProofVerifier* proof_verifier);
~QuicSimpleClient() override;
@@ -125,13 +129,13 @@ class QuicSimpleClient : public QuicClientBase,
bool MigrateSocket(const IPAddressNumber& new_host);
// QuicPacketReader::Visitor
- void OnReadError(int result) override;
+ void OnReadError(int result, const DatagramClientSocket* socket) override;
bool OnPacket(const QuicEncryptedPacket& packet,
IPEndPoint local_address,
IPEndPoint peer_address) override;
- // QuicDataStream::Visitor
- void OnClose(QuicDataStream* stream) override;
+ // QuicSpdyStream::Visitor
+ void OnClose(QuicSpdyStream* stream) override;
// If the crypto handshake has not yet been confirmed, adds the data to the
// queue of data to resend if the client receives a stateless reject.
@@ -162,7 +166,7 @@ class QuicSimpleClient : public QuicClientBase,
const std::string& latest_response_body() const;
protected:
- virtual QuicConnectionHelper* CreateQuicConnectionHelper();
+ virtual QuicChromiumConnectionHelper* CreateQuicConnectionHelper();
virtual QuicPacketWriter* CreateQuicPacketWriter();
private:
@@ -217,9 +221,6 @@ class QuicSimpleClient : public QuicClientBase,
// UDP socket connected to the server.
scoped_ptr<UDPClientSocket> socket_;
- // Helper to be used by created connections.
- scoped_ptr<QuicConnectionHelper> helper_;
-
// Listens for full responses.
scoped_ptr<ResponseListener> response_listener_;
diff --git a/chromium/net/tools/quic/quic_simple_client_bin.cc b/chromium/net/tools/quic/quic_simple_client_bin.cc
index 4cc3f32557b..cf261fbcf8e 100644
--- a/chromium/net/tools/quic/quic_simple_client_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_client_bin.cc
@@ -19,7 +19,7 @@
// quic_client https://www.google.com --port=443 --host=${IP}
//
// Use a specific version:
-// quic_client http://www.google.com --version=23 --host=${IP}
+// quic_client http://www.google.com --quic_version=23 --host=${IP}
//
// Send a POST instead of a GET:
// quic_client http://www.google.com --body="this is a POST body" --host=${IP}
@@ -47,10 +47,12 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/privacy_mode.h"
#include "net/cert/cert_verifier.h"
+#include "net/cert/multi_log_ct_verifier.h"
#include "net/http/http_request_info.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
@@ -66,6 +68,8 @@
using base::StringPiece;
using net::CertVerifier;
+using net::CTVerifier;
+using net::MultiLogCTVerifier;
using net::ProofVerifierChromium;
using net::TransportSecurityState;
using std::cout;
@@ -78,16 +82,19 @@ using std::endl;
// The IP or hostname the quic client will connect to.
string FLAGS_host = "";
// The port to connect to.
-int32 FLAGS_port = 80;
+int32_t FLAGS_port = 0;
// If set, send a POST with this body.
string FLAGS_body = "";
+// If set, contents are converted from hex to ascii, before sending as body of
+// a POST. e.g. --body_hex=\"68656c6c6f\"
+string FLAGS_body_hex = "";
// A semicolon separated list of key:value pairs to add to request headers.
string FLAGS_headers = "";
// Set to true for a quieter output experience.
bool FLAGS_quiet = false;
// QUIC version to speak, e.g. 21. If not set, then all available versions are
// offered in the handshake.
-int32 FLAGS_quic_version = -1;
+int32_t FLAGS_quic_version = -1;
// If true, a version mismatch in the handshake is not considered a failure.
// Useful for probing a server to determine if it speaks any version of QUIC.
bool FLAGS_version_mismatch_ok = false;
@@ -95,9 +102,55 @@ bool FLAGS_version_mismatch_ok = false;
// response, otherwise a failure.
bool FLAGS_redirect_is_success = true;
// Initial MTU of the connection.
-int32 FLAGS_initial_mtu = 0;
+int32_t FLAGS_initial_mtu = 0;
-int main(int argc, char *argv[]) {
+class FakeCertVerifier : public net::CertVerifier {
+ public:
+ int Verify(net::X509Certificate* cert,
+ const std::string& hostname,
+ const std::string& ocsp_response,
+ int flags,
+ net::CRLSet* crl_set,
+ net::CertVerifyResult* verify_result,
+ const net::CompletionCallback& callback,
+ scoped_ptr<net::CertVerifier::Request>* out_req,
+ const net::BoundNetLog& net_log) override {
+ return net::OK;
+ }
+
+ // Returns true if this CertVerifier supports stapled OCSP responses.
+ bool SupportsOCSPStapling() override { return false; }
+};
+
+static bool DecodeHexString(const base::StringPiece& hex, std::string* bytes) {
+ bytes->clear();
+ if (hex.empty())
+ return true;
+ std::vector<uint8_t> v;
+ if (!base::HexStringToBytes(hex.as_string(), &v))
+ return false;
+ if (!v.empty())
+ bytes->assign(reinterpret_cast<const char*>(&v[0]), v.size());
+ return true;
+};
+
+// Converts binary data into an ASCII string. Each character in the resulting
+// string is preceeded by a space, and replaced with a '.' if not printable.
+string BinaryToAscii(const string& binary) {
+ string out = "";
+ for (const unsigned char c : binary) {
+ // Leading space.
+ out += " ";
+ if (isprint(c)) {
+ out += c;
+ } else {
+ out += '.';
+ }
+ }
+ return out;
+}
+
+int main(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv);
base::CommandLine* line = base::CommandLine::ForCurrentProcess();
const base::CommandLine::StringVector& urls = line->GetArgs();
@@ -106,6 +159,8 @@ int main(int argc, char *argv[]) {
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
CHECK(logging::InitLogging(settings));
+ FLAGS_quic_supports_trailers = true;
+
if (line->HasSwitch("h") || line->HasSwitch("help") || urls.empty()) {
const char* help_str =
"Usage: quic_client [options] <url>\n"
@@ -117,6 +172,7 @@ int main(int argc, char *argv[]) {
"connect to\n"
"--port=<port> specify the port to connect to\n"
"--body=<body> specify the body to post\n"
+ "--body_hex=<body_hex> specify the body_hex to be printed out\n"
"--headers=<headers> specify a semicolon separated list of "
"key:value pairs to add to request headers\n"
"--quiet specify for a quieter output experience\n"
@@ -126,7 +182,8 @@ int main(int argc, char *argv[]) {
"--redirect_is_success if specified an HTTP response code of 3xx "
"is considered to be a successful response, otherwise a failure\n"
"--initial_mtu=<initial_mtu> specify the initial MTU of the connection"
- "\n";
+ "\n"
+ "--disable-certificate-verification do not verify certificates\n";
cout << help_str;
exit(0);
}
@@ -142,6 +199,9 @@ int main(int argc, char *argv[]) {
if (line->HasSwitch("body")) {
FLAGS_body = line->GetSwitchValueASCII("body");
}
+ if (line->HasSwitch("body_hex")) {
+ FLAGS_body_hex = line->GetSwitchValueASCII("body_hex");
+ }
if (line->HasSwitch("headers")) {
FLAGS_headers = line->GetSwitchValueASCII("headers");
}
@@ -190,12 +250,16 @@ int main(int argc, char *argv[]) {
if (host.empty()) {
host = url.host();
}
+ int port = FLAGS_port;
+ if (port == 0) {
+ port = url.EffectiveIntPort();
+ }
if (!net::ParseIPLiteralToNumber(host, &ip_addr)) {
net::AddressList addresses;
int rv = net::tools::SynchronousHostResolver::Resolve(host, &addresses);
if (rv != net::OK) {
- LOG(ERROR) << "Unable to resolve '" << host << "' : "
- << net::ErrorToShortString(rv);
+ LOG(ERROR) << "Unable to resolve '" << host
+ << "' : " << net::ErrorToShortString(rv);
return 1;
}
ip_addr = addresses[0].address();
@@ -205,24 +269,28 @@ int main(int argc, char *argv[]) {
VLOG(1) << "Resolved " << host << " to " << host_port << endl;
// Build the client, and try to connect.
- net::QuicServerId server_id(host, FLAGS_port, /*is_https=*/true,
+ net::QuicServerId server_id(url.host(), url.EffectiveIntPort(),
net::PRIVACY_MODE_DISABLED);
net::QuicVersionVector versions = net::QuicSupportedVersions();
if (FLAGS_quic_version != -1) {
versions.clear();
versions.push_back(static_cast<net::QuicVersion>(FLAGS_quic_version));
}
- net::tools::QuicSimpleClient client(net::IPEndPoint(ip_addr, FLAGS_port),
- server_id, versions);
- scoped_ptr<CertVerifier> cert_verifier;
- scoped_ptr<TransportSecurityState> transport_security_state;
+ // For secure QUIC we need to verify the cert chain.
+ scoped_ptr<CertVerifier> cert_verifier(CertVerifier::CreateDefault());
+ if (line->HasSwitch("disable-certificate-verification")) {
+ cert_verifier.reset(new FakeCertVerifier());
+ }
+ scoped_ptr<TransportSecurityState> transport_security_state(
+ new TransportSecurityState);
+ scoped_ptr<CTVerifier> ct_verifier(new MultiLogCTVerifier());
+ ProofVerifierChromium* proof_verifier = new ProofVerifierChromium(
+ cert_verifier.get(), nullptr, transport_security_state.get(),
+ ct_verifier.get());
+ net::tools::QuicSimpleClient client(net::IPEndPoint(ip_addr, port), server_id,
+ versions, proof_verifier);
client.set_initial_max_packet_length(
FLAGS_initial_mtu != 0 ? FLAGS_initial_mtu : net::kDefaultMaxPacketSize);
- // For secure QUIC we need to verify the cert chain.
- cert_verifier = CertVerifier::CreateDefault();
- transport_security_state.reset(new TransportSecurityState);
- client.SetProofVerifier(new ProofVerifierChromium(
- cert_verifier.get(), nullptr, transport_security_state.get()));
if (!client.Initialize()) {
cerr << "Failed to initialize client." << endl;
return 1;
@@ -241,9 +309,16 @@ int main(int argc, char *argv[]) {
}
cout << "Connected to " << host_port << endl;
+ // Construct the string body from flags, if provided.
+ string body = FLAGS_body;
+ if (!FLAGS_body_hex.empty()) {
+ DCHECK(FLAGS_body.empty()) << "Only set one of --body and --body_hex.";
+ DecodeHexString(FLAGS_body_hex, &body);
+ }
+
// Construct a GET or POST request for supplied URL.
net::HttpRequestInfo request;
- request.method = FLAGS_body.empty() ? "GET" : "POST";
+ request.method = body.empty() ? "GET" : "POST";
request.url = url;
// Append any additional headers supplied on the command line.
@@ -273,20 +348,34 @@ int main(int argc, char *argv[]) {
net::CreateSpdyHeadersFromHttpRequest(request, request.extra_headers,
net::HTTP2, /*direct=*/true,
&header_block);
- client.SendRequestAndWaitForResponse(request, FLAGS_body, /*fin=*/true);
+ client.SendRequestAndWaitForResponse(request, body, /*fin=*/true);
// Print request and response details.
if (!FLAGS_quiet) {
cout << "Request:" << endl;
- cout << "headers:" << endl;
- for (const auto& kv : header_block) {
- cout << " " << kv.first << ": " << kv.second << endl;
+ cout << "headers:" << header_block.DebugString();
+ if (!FLAGS_body_hex.empty()) {
+ // Print the user provided hex, rather than binary body.
+ cout << "body hex: " << FLAGS_body_hex << endl;
+ string bytes;
+ DecodeHexString(FLAGS_body_hex, &bytes);
+ cout << "body ascii: " << BinaryToAscii(bytes) << endl;
+ } else {
+ cout << "body: " << body << endl;
}
- cout << "body: " << FLAGS_body << endl;
cout << endl;
cout << "Response:" << endl;
cout << "headers: " << client.latest_response_headers() << endl;
- cout << "body: " << client.latest_response_body() << endl;
+ string response_body = client.latest_response_body();
+ if (!FLAGS_body_hex.empty()) {
+ // Assume response is binary data.
+ string bytes;
+ DecodeHexString(response_body, &bytes);
+ cout << "body hex: " << bytes << endl;
+ cout << "body ascii: " << BinaryToAscii(response_body) << endl;
+ } else {
+ cout << "body: " << response_body << endl;
+ }
}
size_t response_code = client.latest_response_code();
diff --git a/chromium/net/tools/quic/quic_simple_client_test.cc b/chromium/net/tools/quic/quic_simple_client_test.cc
index e57cebb9077..096ff0f59be 100644
--- a/chromium/net/tools/quic/quic_simple_client_test.cc
+++ b/chromium/net/tools/quic/quic_simple_client_test.cc
@@ -4,21 +4,24 @@
#include "net/tools/quic/quic_simple_client.h"
-#include "base/basictypes.h"
#include "base/strings/string_util.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+using net::test::CryptoTestUtils;
+
namespace net {
namespace tools {
namespace test {
TEST(QuicSimpleClientTest, Initialize) {
IPEndPoint server_address(IPEndPoint(net::test::Loopback4(), 80));
- QuicServerId server_id("hostname", server_address.port(), false,
+ QuicServerId server_id("hostname", server_address.port(),
PRIVACY_MODE_DISABLED);
QuicVersionVector versions = QuicSupportedVersions();
- QuicSimpleClient client(server_address, server_id, versions);
+ QuicSimpleClient client(server_address, server_id, versions,
+ CryptoTestUtils::ProofVerifierForTesting());
EXPECT_TRUE(client.Initialize());
}
diff --git a/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.cc b/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.cc
index 2bcaf4b6c95..9020a2ffabe 100644
--- a/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.cc
+++ b/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.cc
@@ -11,15 +11,12 @@ namespace net {
namespace tools {
QuicSimplePerConnectionPacketWriter::QuicSimplePerConnectionPacketWriter(
- QuicSimpleServerPacketWriter* shared_writer,
- QuicConnection* connection)
+ QuicSimpleServerPacketWriter* shared_writer)
: shared_writer_(shared_writer),
- connection_(connection),
- weak_factory_(this){
-}
+ connection_(nullptr),
+ weak_factory_(this) {}
-QuicSimplePerConnectionPacketWriter::~QuicSimplePerConnectionPacketWriter() {
-}
+QuicSimplePerConnectionPacketWriter::~QuicSimplePerConnectionPacketWriter() {}
QuicPacketWriter* QuicSimplePerConnectionPacketWriter::shared_writer() const {
return shared_writer_;
@@ -31,10 +28,7 @@ WriteResult QuicSimplePerConnectionPacketWriter::WritePacket(
const IPAddressNumber& self_address,
const IPEndPoint& peer_address) {
return shared_writer_->WritePacketWithCallback(
- buffer,
- buf_len,
- self_address,
- peer_address,
+ buffer, buf_len, self_address, peer_address,
base::Bind(&QuicSimplePerConnectionPacketWriter::OnWriteComplete,
weak_factory_.GetWeakPtr()));
}
diff --git a/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h b/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h
index 1634e6b4a75..b3fd647a0e6 100644
--- a/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h
+++ b/chromium/net/tools/quic/quic_simple_per_connection_packet_writer.h
@@ -5,6 +5,9 @@
#ifndef NET_QUIC_TOOLS_QUIC_SIMPLE_PER_CONNECTION_PACKET_WRITER_H_
#define NET_QUIC_TOOLS_QUIC_SIMPLE_PER_CONNECTION_PACKET_WRITER_H_
+#include <stddef.h>
+
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_packet_writer.h"
@@ -22,11 +25,11 @@ class QuicSimplePerConnectionPacketWriter : public QuicPacketWriter {
public:
// Does not take ownership of |shared_writer| or |connection|.
QuicSimplePerConnectionPacketWriter(
- QuicSimpleServerPacketWriter* shared_writer,
- QuicConnection* connection);
+ QuicSimpleServerPacketWriter* shared_writer);
~QuicSimplePerConnectionPacketWriter() override;
QuicPacketWriter* shared_writer() const;
+ void set_connection(QuicConnection* connection) { connection_ = connection; }
QuicConnection* connection() const { return connection_; }
// Default implementation of the QuicPacketWriter interface: Passes everything
@@ -44,7 +47,7 @@ class QuicSimplePerConnectionPacketWriter : public QuicPacketWriter {
void OnWriteComplete(WriteResult result);
QuicSimpleServerPacketWriter* shared_writer_; // Not owned.
- QuicConnection* connection_; // Not owned.
+ QuicConnection* connection_; // Not owned.
base::WeakPtrFactory<QuicSimplePerConnectionPacketWriter> weak_factory_;
diff --git a/chromium/net/tools/quic/quic_simple_server.cc b/chromium/net/tools/quic/quic_simple_server.cc
index f7fc9427d10..755ab06bdd5 100644
--- a/chromium/net/tools/quic/quic_simple_server.cc
+++ b/chromium/net/tools/quic/quic_simple_server.cc
@@ -32,44 +32,46 @@ const char kSourceAddressTokenSecret[] = "secret";
// the limit.
const int kReadBufferSize = 2 * kMaxPacketSize;
-// A packet writer factory which wraps a shared QuicSimpleServerPacketWriter
-// inside of a QuicPerConnectionPacketWriter. Instead of checking that
-// the shared_writer is the expected writer, this could instead cast
-// from QuicPacketWriter to QuicSimpleServerPacketWriter.
-class CustomPacketWriterFactory : public QuicDispatcher::PacketWriterFactory {
+class SimpleQuicDispatcher : public QuicDispatcher {
public:
- ~CustomPacketWriterFactory() override {}
-
- QuicPacketWriter* Create(QuicPacketWriter* writer,
- QuicConnection* connection) override {
- if (writer == nullptr) {
- LOG(DFATAL) << "shared_writer not initialized";
- return nullptr;
- }
- if (writer != shared_writer_) {
- LOG(DFATAL) << "writer mismatch";
- return nullptr;
- }
- return new QuicSimplePerConnectionPacketWriter(shared_writer_, connection);
+ SimpleQuicDispatcher(const QuicConfig& config,
+ const QuicCryptoServerConfig* crypto_config,
+ const QuicVersionVector& supported_versions,
+ QuicConnectionHelperInterface* helper)
+ : QuicDispatcher(config, crypto_config, supported_versions, helper) {}
+
+ protected:
+ QuicServerSessionBase* CreateQuicSession(
+ QuicConnectionId connection_id,
+ const IPEndPoint& client_address) override {
+ QuicServerSessionBase* session =
+ QuicDispatcher::CreateQuicSession(connection_id, client_address);
+ static_cast<QuicSimplePerConnectionPacketWriter*>(
+ session->connection()->writer())
+ ->set_connection(session->connection());
+ return session;
}
- void set_shared_writer(QuicSimpleServerPacketWriter* shared_writer) {
- shared_writer_ = shared_writer;
+ QuicPacketWriter* CreatePerConnectionWriter() override {
+ return new QuicSimplePerConnectionPacketWriter(
+ static_cast<QuicSimpleServerPacketWriter*>(writer()));
}
-
- private:
- QuicSimpleServerPacketWriter* shared_writer_; // Not owned.
};
-} // namespace
+} // namespace
-QuicSimpleServer::QuicSimpleServer(const QuicConfig& config,
+QuicSimpleServer::QuicSimpleServer(ProofSource* proof_source,
+ const QuicConfig& config,
const QuicVersionVector& supported_versions)
- : helper_(base::ThreadTaskRunnerHandle::Get().get(),
- &clock_,
- QuicRandom::GetInstance()),
+ : helper_(
+ new QuicChromiumConnectionHelper(base::ThreadTaskRunnerHandle::Get()
+ .get(),
+ &clock_,
+ QuicRandom::GetInstance())),
config_(config),
- crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
+ crypto_config_(kSourceAddressTokenSecret,
+ QuicRandom::GetInstance(),
+ proof_source),
supported_versions_(supported_versions),
read_pending_(false),
synchronous_read_count_(0),
@@ -85,8 +87,8 @@ void QuicSimpleServer::Initialize() {
// If an initial flow control window has not explicitly been set, then use a
// sensible value for a server: 1 MB for session, 64 KB for each stream.
- const uint32 kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
- const uint32 kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
+ const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
+ const uint32_t kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
if (config_.GetInitialStreamFlowControlWindowToSend() ==
kMinimumFlowControlSendWindow) {
config_.SetInitialStreamFlowControlWindowToSend(
@@ -98,14 +100,12 @@ void QuicSimpleServer::Initialize() {
kInitialSessionFlowControlWindow);
}
- scoped_ptr<CryptoHandshakeMessage> scfg(
- crypto_config_.AddDefaultConfig(
- helper_.GetRandomGenerator(), helper_.GetClock(),
- QuicCryptoServerConfig::ConfigOptions()));
+ scoped_ptr<CryptoHandshakeMessage> scfg(crypto_config_.AddDefaultConfig(
+ helper_->GetRandomGenerator(), helper_->GetClock(),
+ QuicCryptoServerConfig::ConfigOptions()));
}
-QuicSimpleServer::~QuicSimpleServer() {
-}
+QuicSimpleServer::~QuicSimpleServer() {}
int QuicSimpleServer::Listen(const IPEndPoint& address) {
scoped_ptr<UDPServerSocket> socket(
@@ -123,7 +123,7 @@ int QuicSimpleServer::Listen(const IPEndPoint& address) {
// because the default usage of QuicSimpleServer is as a test server with
// one or two clients. Adjust higher for use with many clients.
rc = socket->SetReceiveBufferSize(
- static_cast<int32>(kDefaultSocketReceiveBuffer));
+ static_cast<int32_t>(kDefaultSocketReceiveBuffer));
if (rc < 0) {
LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc);
return rc;
@@ -145,17 +145,10 @@ int QuicSimpleServer::Listen(const IPEndPoint& address) {
socket_.swap(socket);
- CustomPacketWriterFactory* factory = new CustomPacketWriterFactory();
- dispatcher_.reset(
- new QuicDispatcher(config_,
- &crypto_config_,
- supported_versions_,
- factory,
- &helper_));
- QuicSimpleServerPacketWriter* writer = new QuicSimpleServerPacketWriter(
- socket_.get(),
- dispatcher_.get());
- factory->set_shared_writer(writer);
+ dispatcher_.reset(new SimpleQuicDispatcher(config_, &crypto_config_,
+ supported_versions_, helper_));
+ QuicSimpleServerPacketWriter* writer =
+ new QuicSimpleServerPacketWriter(socket_.get(), dispatcher_.get());
dispatcher_->InitializeWithWriter(writer);
StartReading();
@@ -179,9 +172,7 @@ void QuicSimpleServer::StartReading() {
read_pending_ = true;
int result = socket_->RecvFrom(
- read_buffer_.get(),
- read_buffer_->size(),
- &client_address_,
+ read_buffer_.get(), read_buffer_->size(), &client_address_,
base::Bind(&QuicSimpleServer::OnReadComplete, base::Unretained(this)));
if (result == ERR_IO_PENDING) {
diff --git a/chromium/net/tools/quic/quic_simple_server.h b/chromium/net/tools/quic/quic_simple_server.h
index b8dba27f942..ba4575e9c6b 100644
--- a/chromium/net/tools/quic/quic_simple_server.h
+++ b/chromium/net/tools/quic/quic_simple_server.h
@@ -8,15 +8,15 @@
#ifndef NET_QUIC_TOOLS_QUIC_SIMPLE_SERVER_H_
#define NET_QUIC_TOOLS_QUIC_SIMPLE_SERVER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/log/net_log.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_clock.h"
#include "net/quic/quic_config.h"
-#include "net/quic/quic_connection_helper.h"
namespace net {
@@ -32,7 +32,8 @@ class QuicSimpleServerPeer;
class QuicSimpleServer {
public:
- QuicSimpleServer(const QuicConfig& config,
+ QuicSimpleServer(ProofSource* proof_source,
+ const QuicConfig& config,
const QuicVersionVector& supported_versions);
virtual ~QuicSimpleServer();
@@ -55,12 +56,6 @@ class QuicSimpleServer {
crypto_config_.set_strike_register_no_startup_period();
}
- // SetProofSource sets the ProofSource that will be used to verify the
- // server's certificate, and takes ownership of |source|.
- void SetProofSource(ProofSource* source) {
- crypto_config_.SetProofSource(source);
- }
-
QuicDispatcher* dispatcher() { return dispatcher_.get(); }
private:
@@ -75,8 +70,8 @@ class QuicSimpleServer {
// Used by the helper_ to time alarms.
QuicClock clock_;
- // Used to manage the message loop.
- QuicConnectionHelper helper_;
+ // Used to manage the message loop. Owned by dispatcher_.
+ QuicChromiumConnectionHelper* helper_;
// Listening socket. Also used for outbound client communication.
scoped_ptr<UDPServerSocket> socket_;
diff --git a/chromium/net/tools/quic/quic_simple_server_bin.cc b/chromium/net/tools/quic/quic_simple_server_bin.cc
index b1f6a6ab1bb..e7ec276e652 100644
--- a/chromium/net/tools/quic/quic_simple_server_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_server_bin.cc
@@ -8,7 +8,6 @@
#include <iostream>
#include "base/at_exit.h"
-#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/run_loop.h"
@@ -20,16 +19,16 @@
#include "net/tools/quic/quic_simple_server.h"
// The port the quic server will listen on.
-int32 FLAGS_port = 6121;
+int32_t FLAGS_port = 6121;
net::ProofSource* CreateProofSource(const base::FilePath& cert_path,
const base::FilePath& key_path) {
net::ProofSourceChromium* proof_source = new net::ProofSourceChromium();
- CHECK(proof_source->Initialize(cert_path, key_path));
+ CHECK(proof_source->Initialize(cert_path, key_path, base::FilePath()));
return proof_source;
}
-int main(int argc, char *argv[]) {
+int main(int argc, char* argv[]) {
base::AtExitManager exit_manager;
base::MessageLoopForIO message_loop;
@@ -67,23 +66,25 @@ int main(int argc, char *argv[]) {
}
}
- net::IPAddressNumber ip;
- CHECK(net::ParseIPLiteralToNumber("::", &ip));
-
- net::QuicConfig config;
- net::tools::QuicSimpleServer server(config, net::QuicSupportedVersions());
- server.SetStrikeRegisterNoStartupPeriod();
if (!line->HasSwitch("certificate_file")) {
LOG(ERROR) << "missing --certificate_file";
return 1;
}
+
if (!line->HasSwitch("key_file")) {
LOG(ERROR) << "missing --key_file";
return 1;
}
- server.SetProofSource(
+
+ net::IPAddressNumber ip;
+ CHECK(net::ParseIPLiteralToNumber("::", &ip));
+
+ net::QuicConfig config;
+ net::tools::QuicSimpleServer server(
CreateProofSource(line->GetSwitchValuePath("certificate_file"),
- line->GetSwitchValuePath("key_file")));
+ line->GetSwitchValuePath("key_file")),
+ config, net::QuicSupportedVersions());
+ server.SetStrikeRegisterNoStartupPeriod();
int rc = server.Listen(net::IPEndPoint(ip, FLAGS_port));
if (rc < 0) {
diff --git a/chromium/net/tools/quic/quic_simple_server_packet_writer.cc b/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
index 78ac16f3a8a..5754875e2a5 100644
--- a/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
+++ b/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
@@ -21,11 +21,9 @@ QuicSimpleServerPacketWriter::QuicSimpleServerPacketWriter(
: socket_(socket),
blocked_writer_(blocked_writer),
write_blocked_(false),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
-QuicSimpleServerPacketWriter::~QuicSimpleServerPacketWriter() {
-}
+QuicSimpleServerPacketWriter::~QuicSimpleServerPacketWriter() {}
WriteResult QuicSimpleServerPacketWriter::WritePacketWithCallback(
const char* buffer,
@@ -75,12 +73,9 @@ WriteResult QuicSimpleServerPacketWriter::WritePacket(
int rv;
if (buf_len <= static_cast<size_t>(std::numeric_limits<int>::max())) {
rv = socket_->SendTo(
- buf.get(),
- static_cast<int>(buf_len),
- peer_address,
- base::Bind(
- &QuicSimpleServerPacketWriter::OnWriteComplete,
- weak_factory_.GetWeakPtr()));
+ buf.get(), static_cast<int>(buf_len), peer_address,
+ base::Bind(&QuicSimpleServerPacketWriter::OnWriteComplete,
+ weak_factory_.GetWeakPtr()));
} else {
rv = ERR_MSG_TOO_BIG;
}
diff --git a/chromium/net/tools/quic/quic_simple_server_packet_writer.h b/chromium/net/tools/quic/quic_simple_server_packet_writer.h
index 613c11b9851..6e4cf8a81a6 100644
--- a/chromium/net/tools/quic/quic_simple_server_packet_writer.h
+++ b/chromium/net/tools/quic/quic_simple_server_packet_writer.h
@@ -5,8 +5,10 @@
#ifndef NET_QUIC_TOOLS_QUIC_SIMPLE_SERVER_PACKET_WRITER_H_
#define NET_QUIC_TOOLS_QUIC_SIMPLE_SERVER_PACKET_WRITER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_connection.h"
@@ -28,7 +30,7 @@ class QuicSimpleServerPacketWriter : public QuicPacketWriter {
typedef base::Callback<void(WriteResult)> WriteCallback;
QuicSimpleServerPacketWriter(UDPServerSocket* socket,
- QuicBlockedWriterInterface* blocked_writer);
+ QuicBlockedWriterInterface* blocked_writer);
~QuicSimpleServerPacketWriter() override;
// Use this method to write packets rather than WritePacket:
diff --git a/chromium/net/tools/quic/quic_simple_server_session.cc b/chromium/net/tools/quic/quic_simple_server_session.cc
new file mode 100644
index 00000000000..fea72a3a0d3
--- /dev/null
+++ b/chromium/net/tools/quic/quic_simple_server_session.cc
@@ -0,0 +1,186 @@
+// 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/tools/quic/quic_simple_server_session.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "net/quic/proto/cached_network_parameters.pb.h"
+#include "net/quic/quic_connection.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_spdy_session.h"
+#include "net/quic/reliable_quic_stream.h"
+#include "net/tools/quic/quic_simple_server_stream.h"
+#include "url/gurl.h"
+
+namespace net {
+namespace tools {
+
+QuicSimpleServerSession::QuicSimpleServerSession(
+ const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config)
+ : QuicServerSessionBase(config, connection, visitor, crypto_config),
+ highest_promised_stream_id_(0) {}
+
+QuicSimpleServerSession::~QuicSimpleServerSession() {}
+
+QuicCryptoServerStreamBase*
+QuicSimpleServerSession::CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) {
+ return new QuicCryptoServerStream(crypto_config, this);
+}
+
+void QuicSimpleServerSession::StreamDraining(QuicStreamId id) {
+ QuicSpdySession::StreamDraining(id);
+ if (!IsIncomingStream(id)) {
+ HandlePromisedPushRequests();
+ }
+}
+
+void QuicSimpleServerSession::OnStreamFrame(const QuicStreamFrame& frame) {
+ if (!IsIncomingStream(frame.stream_id)) {
+ LOG(WARNING) << "Client shouldn't send data on server push stream";
+ connection()->SendConnectionCloseWithDetails(
+ QUIC_INVALID_STREAM_ID, "Client sent data on server push stream");
+ return;
+ }
+ QuicSpdySession::OnStreamFrame(frame);
+}
+
+void QuicSimpleServerSession::PromisePushResources(
+ const string& request_url,
+ const list<QuicInMemoryCache::ServerPushInfo>& resources,
+ QuicStreamId original_stream_id,
+ const SpdyHeaderBlock& original_request_headers) {
+ for (QuicInMemoryCache::ServerPushInfo resource : resources) {
+ SpdyHeaderBlock headers = SynthesizePushRequestHeaders(
+ request_url, resource, original_request_headers);
+ highest_promised_stream_id_ += 2;
+ SendPushPromise(original_stream_id, highest_promised_stream_id_, headers);
+ promised_streams_.push_back(PromisedStreamInfo(
+ headers, highest_promised_stream_id_, resource.priority));
+ }
+
+ // Procese promised push request as many as possible.
+ HandlePromisedPushRequests();
+}
+
+QuicSpdyStream* QuicSimpleServerSession::CreateIncomingDynamicStream(
+ QuicStreamId id) {
+ if (!ShouldCreateIncomingDynamicStream(id)) {
+ return nullptr;
+ }
+
+ return new QuicSimpleServerStream(id, this);
+}
+
+QuicSimpleServerStream* QuicSimpleServerSession::CreateOutgoingDynamicStream(
+ SpdyPriority priority) {
+ if (!ShouldCreateOutgoingDynamicStream()) {
+ return nullptr;
+ }
+
+ QuicSimpleServerStream* stream =
+ new QuicSimpleServerStream(GetNextOutgoingStreamId(), this);
+ stream->SetPriority(priority);
+ ActivateStream(stream);
+ return stream;
+}
+
+void QuicSimpleServerSession::CloseStreamInner(QuicStreamId stream_id,
+ bool locally_reset) {
+ QuicSpdySession::CloseStreamInner(stream_id, locally_reset);
+ HandlePromisedPushRequests();
+}
+
+void QuicSimpleServerSession::HandleFrameOnNonexistentOutgoingStream(
+ QuicStreamId stream_id) {
+ // If this stream is a promised but not created stream (stream_id within the
+ // range of next_outgoing_stream_id_ and highes_promised_stream_id_),
+ // connection shouldn't be closed.
+ // Otherwise behave in the same way as base class.
+ if (stream_id > highest_promised_stream_id_) {
+ QuicSession::HandleFrameOnNonexistentOutgoingStream(stream_id);
+ }
+}
+
+void QuicSimpleServerSession::HandleRstOnValidNonexistentStream(
+ const QuicRstStreamFrame& frame) {
+ QuicSession::HandleRstOnValidNonexistentStream(frame);
+ if (!IsClosedStream(frame.stream_id)) {
+ // If a nonexistent stream is not a closed stream and still valid, it must
+ // be a locally preserved stream. Resetting this kind of stream means
+ // cancelling the promised server push.
+ // Since PromisedStreamInfo are queued in sequence, the corresponding
+ // index for it in promised_streams_ can be calculated.
+ DCHECK(frame.stream_id >= next_outgoing_stream_id());
+ size_t index = (frame.stream_id - next_outgoing_stream_id()) / 2;
+ DCHECK(index <= promised_streams_.size());
+ promised_streams_[index].is_cancelled = true;
+ connection()->SendRstStream(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT, 0);
+ }
+}
+
+SpdyHeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders(
+ string request_url,
+ QuicInMemoryCache::ServerPushInfo resource,
+ const SpdyHeaderBlock& original_request_headers) {
+ GURL push_request_url = resource.request_url;
+ string path = push_request_url.path();
+
+ SpdyHeaderBlock spdy_headers = original_request_headers;
+ // :authority could be different from original request.
+ spdy_headers.ReplaceOrAppendHeader(":authority", push_request_url.host());
+ spdy_headers.ReplaceOrAppendHeader(":path", path);
+ // Push request always use GET.
+ spdy_headers.ReplaceOrAppendHeader(":method", "GET");
+ spdy_headers.ReplaceOrAppendHeader("referer", request_url);
+ spdy_headers.ReplaceOrAppendHeader(":scheme", push_request_url.scheme());
+ // It is not possible to push a response to a request that includes a request
+ // body.
+ spdy_headers.ReplaceOrAppendHeader("content-length", "0");
+ // Remove "host" field as push request is a directly generated HTTP2 request
+ // which should use ":authority" instead of "host".
+ spdy_headers.erase("host");
+ return spdy_headers;
+}
+
+void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id,
+ QuicStreamId promised_stream_id,
+ const SpdyHeaderBlock& headers) {
+ DVLOG(1) << "stream " << original_stream_id
+ << " send PUSH_PROMISE for promised stream " << promised_stream_id;
+ headers_stream()->WritePushPromise(original_stream_id, promised_stream_id,
+ headers, nullptr);
+}
+
+void QuicSimpleServerSession::HandlePromisedPushRequests() {
+ while (!promised_streams_.empty() && ShouldCreateOutgoingDynamicStream()) {
+ const PromisedStreamInfo& promised_info = promised_streams_.front();
+ DCHECK_EQ(next_outgoing_stream_id(), promised_info.stream_id);
+
+ if (promised_info.is_cancelled) {
+ // This stream has been reset by client. Skip this stream id.
+ promised_streams_.pop_front();
+ GetNextOutgoingStreamId();
+ return;
+ }
+
+ QuicSimpleServerStream* promised_stream =
+ static_cast<QuicSimpleServerStream*>(
+ CreateOutgoingDynamicStream(promised_info.priority));
+ DCHECK(promised_stream != nullptr);
+ DCHECK_EQ(promised_info.stream_id, promised_stream->id());
+ DVLOG(1) << "created server push stream " << promised_stream->id();
+
+ promised_stream->PushResponse(promised_info.request_headers);
+
+ promised_streams_.pop_front();
+ }
+}
+
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_session.h b/chromium/net/tools/quic/quic_simple_server_session.h
new file mode 100644
index 00000000000..d9b2901c4bc
--- /dev/null
+++ b/chromium/net/tools/quic/quic_simple_server_session.h
@@ -0,0 +1,154 @@
+// 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.
+//
+// A toy server specific QuicSession subclass.
+
+#ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_
+#define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_SESSION_H_
+
+#include <stdint.h>
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/containers/hash_tables.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/quic/quic_crypto_server_stream.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_spdy_session.h"
+#include "net/tools/quic/quic_in_memory_cache.h"
+#include "net/tools/quic/quic_server_session_base.h"
+#include "net/tools/quic/quic_simple_server_stream.h"
+
+namespace net {
+
+class QuicBlockedWriterInterface;
+class QuicConfig;
+class QuicConnection;
+class QuicCryptoServerConfig;
+class ReliableQuicStream;
+
+namespace tools {
+
+namespace test {
+class QuicSimpleServerSessionPeer;
+} // namespace test
+
+class QuicSimpleServerSession : public QuicServerSessionBase {
+ public:
+ // A PromisedStreamInfo is an element of the queue to store promised
+ // stream which hasn't been created yet. It keeps a mapping between promised
+ // stream id with its priority and the headers sent out in PUSH_PROMISE.
+ struct PromisedStreamInfo {
+ public:
+ PromisedStreamInfo(SpdyHeaderBlock request_headers,
+ QuicStreamId stream_id,
+ SpdyPriority priority)
+ : request_headers(request_headers),
+ stream_id(stream_id),
+ priority(priority),
+ is_cancelled(false) {}
+ SpdyHeaderBlock request_headers;
+ QuicStreamId stream_id;
+ SpdyPriority priority;
+ bool is_cancelled;
+ };
+
+ QuicSimpleServerSession(const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config);
+
+ ~QuicSimpleServerSession() override;
+
+ // When a stream is marked draining, it will decrease the number of open
+ // streams. If it is an outgoing stream, try to open a new stream to send
+ // remaing push responses.
+ void StreamDraining(QuicStreamId id) override;
+
+ // Override base class to detact client sending data on server push stream.
+ void OnStreamFrame(const QuicStreamFrame& frame) override;
+
+ // Send out PUSH_PROMISE for all |resources| promised stream id in each frame
+ // will increase by 2 for each item in |resources|.
+ // And enqueue HEADERS block in those PUSH_PROMISED for sending push response
+ // later.
+ virtual void PromisePushResources(
+ const string& request_url,
+ const list<QuicInMemoryCache::ServerPushInfo>& resources,
+ QuicStreamId original_stream_id,
+ const SpdyHeaderBlock& original_request_headers);
+
+ protected:
+ // QuicSession methods:
+ QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override;
+ QuicSimpleServerStream* CreateOutgoingDynamicStream(
+ SpdyPriority priority) override;
+ // Closing an outgoing stream can reduce open outgoing stream count, try
+ // to handle queued promised streams right now.
+ void CloseStreamInner(QuicStreamId stream_id, bool locally_reset) override;
+ // Override to return true for locally preserved server push stream.
+ void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
+ // Override to handle reseting locally preserved streams.
+ void HandleRstOnValidNonexistentStream(
+ const QuicRstStreamFrame& frame) override;
+
+ // QuicServerSessionBaseMethod:
+ QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) override;
+
+ private:
+ friend class test::QuicSimpleServerSessionPeer;
+
+ // Create a server push headers block by copying request's headers block.
+ // But replace or add these pseudo-headers as they are specific to each
+ // request:
+ // :authority, :path, :method, :scheme, referer.
+ // Copying the rest headers ensures they are the same as the original
+ // request, especially cookies.
+ SpdyHeaderBlock SynthesizePushRequestHeaders(
+ string request_url,
+ QuicInMemoryCache::ServerPushInfo resource,
+ const SpdyHeaderBlock& original_request_headers);
+
+ // Send PUSH_PROMISE frame on headers stream.
+ void SendPushPromise(QuicStreamId original_stream_id,
+ QuicStreamId promised_stream_id,
+ const SpdyHeaderBlock& headers);
+
+ // Fetch response from cache for request headers enqueued into
+ // promised_headers_and_streams_ and send them on dedicated stream until
+ // reaches max_open_stream_ limit.
+ // Called when return value of GetNumOpenOutgoingStreams() changes:
+ // CloseStreamInner();
+ // StreamDraining();
+ // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
+ // return value becasue all push streams are impossible to become locally
+ // closed. Since a locally preserved stream becomes remotely closed after
+ // HandlePromisedPushRequests() starts to process it, and if it is reset
+ // locally afterwards, it will be immediately become closed and never get into
+ // locally_closed_stream_highest_offset_. So all the streams in this map
+ // are not outgoing streams.
+ void HandlePromisedPushRequests();
+
+ // Keep track of the highest stream id which has been sent in PUSH_PROMISE.
+ QuicStreamId highest_promised_stream_id_;
+
+ // Promised streams which hasn't been created yet because of max_open_stream_
+ // limit. New element is added to the end of the queue.
+ // Since outgoing stream is created in sequence, stream_id of each element in
+ // the queue also increases by 2 from previous one's. The front element's
+ // stream_id is always next_outgoing_stream_id_, and the last one is always
+ // highest_promised_stream_id_.
+ std::deque<PromisedStreamInfo> promised_streams_;
+
+ DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerSession);
+};
+
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_QUIC_SERVER_SESSION_H_
diff --git a/chromium/net/tools/quic/quic_simple_server_session_test.cc b/chromium/net/tools/quic/quic_simple_server_session_test.cc
new file mode 100644
index 00000000000..e3ed3c9e601
--- /dev/null
+++ b/chromium/net/tools/quic/quic_simple_server_session_test.cc
@@ -0,0 +1,504 @@
+// Copyright 2013 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/tools/quic/quic_simple_server_session.h"
+
+#include <algorithm>
+
+#include "base/macros.h"
+#include "base/strings/string_number_conversions.h"
+#include "net/quic/crypto/quic_crypto_server_config.h"
+#include "net/quic/crypto/quic_random.h"
+#include "net/quic/proto/cached_network_parameters.pb.h"
+#include "net/quic/quic_connection.h"
+#include "net/quic/quic_crypto_server_stream.h"
+#include "net/quic/quic_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.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_sent_packet_manager_peer.h"
+#include "net/quic/test_tools/quic_session_peer.h"
+#include "net/quic/test_tools/quic_spdy_session_peer.h"
+#include "net/quic/test_tools/quic_spdy_stream_peer.h"
+#include "net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
+#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/test/gtest_util.h"
+#include "net/tools/quic/quic_simple_server_stream.h"
+#include "net/tools/quic/test_tools/mock_quic_server_session_visitor.h"
+#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using __gnu_cxx::vector;
+using net::test::CryptoTestUtils;
+using net::test::MockConnection;
+using net::test::MockConnectionHelper;
+using net::test::QuicConfigPeer;
+using net::test::QuicConnectionPeer;
+using net::test::QuicSpdyStreamPeer;
+using net::test::QuicSentPacketManagerPeer;
+using net::test::QuicSessionPeer;
+using net::test::QuicSpdySessionPeer;
+using net::test::QuicSustainedBandwidthRecorderPeer;
+using net::test::SupportedVersions;
+using net::test::ValueRestore;
+using net::test::kClientDataStreamId1;
+using net::test::kClientDataStreamId2;
+using net::test::kClientDataStreamId3;
+using net::test::kInitialSessionFlowControlWindowForTest;
+using net::test::kInitialStreamFlowControlWindowForTest;
+using std::string;
+using testing::StrictMock;
+using testing::_;
+using testing::InSequence;
+using testing::Return;
+
+namespace net {
+namespace tools {
+namespace test {
+namespace {
+typedef QuicSimpleServerSession::PromisedStreamInfo PromisedStreamInfo;
+} // namespace
+
+class MockQuicHeadersStream : public QuicHeadersStream {
+ public:
+ explicit MockQuicHeadersStream(QuicSpdySession* session)
+ : QuicHeadersStream(session) {}
+
+ MOCK_METHOD4(WritePushPromise,
+ size_t(QuicStreamId original_stream_id,
+ QuicStreamId promised_stream_id,
+ const SpdyHeaderBlock& headers,
+ QuicAckListenerInterface* ack_listener));
+
+ MOCK_METHOD5(WriteHeaders,
+ size_t(QuicStreamId stream_id,
+ const SpdyHeaderBlock& headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicAckListenerInterface* ack_listener));
+};
+
+class MockQuicCryptoServerStream : public QuicCryptoServerStream {
+ public:
+ explicit MockQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config,
+ QuicSession* session)
+ : QuicCryptoServerStream(crypto_config, session) {}
+ ~MockQuicCryptoServerStream() override {}
+
+ MOCK_METHOD1(SendServerConfigUpdate,
+ void(const CachedNetworkParameters* cached_network_parameters));
+
+ void set_encryption_established(bool has_established) {
+ encryption_established_ = has_established;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
+};
+
+class MockConnectionWithSendStreamData : public MockConnection {
+ public:
+ MockConnectionWithSendStreamData(MockConnectionHelper* helper,
+ Perspective perspective,
+ const QuicVersionVector& supported_versions)
+ : MockConnection(helper, perspective, supported_versions) {}
+
+ MOCK_METHOD6(SendStreamData,
+ QuicConsumedData(QuicStreamId id,
+ QuicIOVector iov,
+ QuicStreamOffset offset,
+ bool fin,
+ FecProtection fec_protection,
+ QuicAckListenerInterface* listern));
+};
+
+class QuicSimpleServerSessionPeer {
+ public:
+ static void SetCryptoStream(QuicSimpleServerSession* s,
+ QuicCryptoServerStream* crypto_stream) {
+ s->crypto_stream_.reset(crypto_stream);
+ s->static_streams()[kCryptoStreamId] = crypto_stream;
+ }
+
+ static QuicSpdyStream* CreateIncomingDynamicStream(QuicSimpleServerSession* s,
+ QuicStreamId id) {
+ return s->CreateIncomingDynamicStream(id);
+ }
+
+ static QuicSimpleServerStream* CreateOutgoingDynamicStream(
+ QuicSimpleServerSession* s,
+ SpdyPriority priority) {
+ return s->CreateOutgoingDynamicStream(priority);
+ }
+
+ static std::deque<PromisedStreamInfo>* promised_streams(
+ QuicSimpleServerSession* s) {
+ return &(s->promised_streams_);
+ }
+
+ static QuicStreamId hightest_promised_stream_id(QuicSimpleServerSession* s) {
+ return s->highest_promised_stream_id_;
+ }
+};
+
+namespace {
+
+const size_t kMaxStreamsForTest = 10;
+
+class QuicSimpleServerSessionTest
+ : public ::testing::TestWithParam<QuicVersion> {
+ protected:
+ QuicSimpleServerSessionTest()
+ : crypto_config_(QuicCryptoServerConfig::TESTING,
+ QuicRandom::GetInstance(),
+ CryptoTestUtils::ProofSourceForTesting()) {
+ config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
+ config_.SetInitialStreamFlowControlWindowToSend(
+ kInitialStreamFlowControlWindowForTest);
+ config_.SetInitialSessionFlowControlWindowToSend(
+ kInitialSessionFlowControlWindowForTest);
+
+ connection_ = new StrictMock<MockConnectionWithSendStreamData>(
+ &helper_, Perspective::IS_SERVER, SupportedVersions(GetParam()));
+ session_.reset(new QuicSimpleServerSession(config_, connection_, &owner_,
+ &crypto_config_));
+ MockClock clock;
+ handshake_message_.reset(crypto_config_.AddDefaultConfig(
+ QuicRandom::GetInstance(), &clock,
+ QuicCryptoServerConfig::ConfigOptions()));
+ session_->Initialize();
+ visitor_ = QuicConnectionPeer::GetVisitor(connection_);
+ headers_stream_ = new MockQuicHeadersStream(session_.get());
+ QuicSpdySessionPeer::SetHeadersStream(session_.get(), headers_stream_);
+ }
+
+ // Given |num_resources|, create this number of fake push resources and push
+ // them by sending PUSH_PROMISE for all and sending push responses for as much
+ // as possible(limited by kMaxStreamsForTest).
+ // If |num_resources| > kMaxStreamsForTest, the left over will be queued.
+ void PromisePushResources(size_t num_resources) {
+ // Assume encryption already established.
+ MockQuicCryptoServerStream* crypto_stream =
+ new MockQuicCryptoServerStream(&crypto_config_, session_.get());
+ crypto_stream->set_encryption_established(true);
+ QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
+
+ QuicInMemoryCachePeer::ResetForTests();
+
+ string request_url = "mail.google.com/";
+ SpdyHeaderBlock request_headers;
+ string resource_host = "www.google.com";
+ string partial_push_resource_path = "/server_push_src";
+ string partial_push_response_body =
+ "Push resource body " + partial_push_resource_path;
+ list<QuicInMemoryCache::ServerPushInfo> push_resources;
+ string scheme = "http";
+ for (unsigned int i = 1; i <= num_resources; ++i) {
+ string path = partial_push_resource_path + base::UintToString(i);
+ string url = scheme + "://" + resource_host + path;
+ GURL resource_url = GURL(url);
+ string body = partial_push_response_body + base::UintToString(i);
+ SpdyHeaderBlock response_headers;
+ QuicInMemoryCache::GetInstance()->AddSimpleResponse(resource_host, path,
+ 200, body);
+ push_resources.push_back(QuicInMemoryCache::ServerPushInfo(
+ resource_url, response_headers, kDefaultPriority, body));
+ // PUSH_PROMISED are sent for all the resources.
+ EXPECT_CALL(*headers_stream_,
+ WritePushPromise(kClientDataStreamId1, i * 2, _, nullptr));
+ if (i <= kMaxStreamsForTest) {
+ // |kMaxStreamsForTest| promised responses should be sent.
+ EXPECT_CALL(*headers_stream_,
+ WriteHeaders(i * 2, _, false, kDefaultPriority, nullptr));
+ // Mock that SendStreamData() returns less than supposed to send to keep
+ // the stream open.
+ EXPECT_CALL(*connection_, SendStreamData(i * 2, _, 0, true, _, nullptr))
+ .WillOnce(Return(QuicConsumedData(0, false)));
+ }
+ }
+ session_->PromisePushResources(request_url, push_resources,
+ kClientDataStreamId1, request_headers);
+ }
+
+ StrictMock<MockQuicServerSessionVisitor> owner_;
+ MockConnectionHelper helper_;
+ StrictMock<MockConnectionWithSendStreamData>* connection_;
+ QuicConfig config_;
+ QuicCryptoServerConfig crypto_config_;
+ scoped_ptr<QuicSimpleServerSession> session_;
+ scoped_ptr<CryptoHandshakeMessage> handshake_message_;
+ QuicConnectionVisitorInterface* visitor_;
+ MockQuicHeadersStream* headers_stream_;
+};
+
+INSTANTIATE_TEST_CASE_P(Tests,
+ QuicSimpleServerSessionTest,
+ ::testing::ValuesIn(QuicSupportedVersions()));
+
+TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) {
+ // Open a stream, then reset it.
+ // Send two bytes of payload to open it.
+ QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
+ session_->OnStreamFrame(data1);
+ EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
+
+ // Receive a reset (and send a RST in response).
+ QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_ERROR_PROCESSING_STREAM,
+ 0);
+ EXPECT_CALL(*connection_,
+ SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
+ visitor_->OnRstStream(rst1);
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+
+ // Send the same two bytes of payload in a new packet.
+ visitor_->OnStreamFrame(data1);
+
+ // The stream should not be re-opened.
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+ EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) {
+ // Send a reset (and expect the peer to send a RST in response).
+ QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_ERROR_PROCESSING_STREAM,
+ 0);
+ EXPECT_CALL(*connection_,
+ SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
+ visitor_->OnRstStream(rst1);
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+
+ // Send two bytes of payload.
+ QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
+ visitor_->OnStreamFrame(data1);
+
+ // The stream should never be opened, now that the reset is received.
+ EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
+ EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) {
+ // Send (empty) compressed headers followed by two bytes of data.
+ QuicStreamFrame frame1(kClientDataStreamId1, false, 0,
+ StringPiece("\1\0\0\0\0\0\0\0HT"));
+ QuicStreamFrame frame2(kClientDataStreamId2, false, 0,
+ StringPiece("\2\0\0\0\0\0\0\0HT"));
+ visitor_->OnStreamFrame(frame1);
+ visitor_->OnStreamFrame(frame2);
+ EXPECT_EQ(2u, session_->GetNumOpenIncomingStreams());
+
+ // Send a reset (and expect the peer to send a RST in response).
+ QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_ERROR_PROCESSING_STREAM, 0);
+ EXPECT_CALL(*connection_,
+ SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
+ visitor_->OnRstStream(rst);
+
+ // If we were tracking, we'd probably want to reject this because it's data
+ // past the reset point of stream 3. As it's a closed stream we just drop the
+ // data on the floor, but accept the packet because it has data for stream 5.
+ QuicStreamFrame frame3(kClientDataStreamId1, false, 2, StringPiece("TP"));
+ QuicStreamFrame frame4(kClientDataStreamId2, false, 2, StringPiece("TP"));
+ visitor_->OnStreamFrame(frame3);
+ visitor_->OnStreamFrame(frame4);
+ // The stream should never be opened, now that the reset is received.
+ EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
+ EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateIncomingDynamicStreamDisconnected) {
+ // Tests that incoming stream creation fails when connection is not connected.
+ size_t initial_num_open_stream = session_->GetNumOpenIncomingStreams();
+ QuicConnectionPeer::CloseConnection(connection_);
+ EXPECT_DFATAL(QuicSimpleServerSessionPeer::CreateIncomingDynamicStream(
+ session_.get(), kClientDataStreamId1),
+ "ShouldCreateIncomingDynamicStream called when disconnected");
+ EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenIncomingStreams());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateEvenIncomingDynamicStream) {
+ // Tests that incoming stream creation fails when given stream id is even.
+ size_t initial_num_open_stream = session_->GetNumOpenIncomingStreams();
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_STREAM_ID,
+ "Client created even numbered stream"));
+ QuicSimpleServerSessionPeer::CreateIncomingDynamicStream(session_.get(), 2);
+ EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenIncomingStreams());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateIncomingDynamicStream) {
+ std::unique_ptr<QuicSpdyStream> stream(
+ QuicSimpleServerSessionPeer::CreateIncomingDynamicStream(
+ session_.get(), kClientDataStreamId1));
+ EXPECT_NE(nullptr, stream);
+ EXPECT_EQ(kClientDataStreamId1, stream->id());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamDisconnected) {
+ // Tests that outgoing stream creation fails when connection is not connected.
+ size_t initial_num_open_stream = session_->GetNumOpenOutgoingStreams();
+ QuicConnectionPeer::CloseConnection(connection_);
+ EXPECT_DFATAL(QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(
+ session_.get(), kDefaultPriority),
+ "ShouldCreateOutgoingDynamicStream called when disconnected");
+
+ EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenOutgoingStreams());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUnencrypted) {
+ // Tests that outgoing stream creation fails when encryption has not yet been
+ // established.
+ size_t initial_num_open_stream = session_->GetNumOpenOutgoingStreams();
+ EXPECT_DFATAL(QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(
+ session_.get(), kDefaultPriority),
+ "Encryption not established so no outgoing stream created.");
+ EXPECT_EQ(initial_num_open_stream, session_->GetNumOpenOutgoingStreams());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) {
+ // Tests that outgoing stream creation should not be affected by existing
+ // incoming stream and vice-versa. But when reaching the limit of max outgoing
+ // stream allowed, creation should fail.
+
+ // Receive some data to initiate a incoming stream which should not effect
+ // creating outgoing streams.
+ QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
+ session_->OnStreamFrame(data1);
+ EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
+ EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
+
+ // Assume encryption already established.
+ MockQuicCryptoServerStream* crypto_stream =
+ new MockQuicCryptoServerStream(&crypto_config_, session_.get());
+ crypto_stream->set_encryption_established(true);
+ QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
+
+ // Create push streams till reaching the upper limit of allowed open streams.
+ for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
+ QuicSpdyStream* created_stream =
+ QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(
+ session_.get(), kDefaultPriority);
+ EXPECT_EQ(2 * (i + 1), created_stream->id());
+ EXPECT_EQ(i + 1, session_->GetNumOpenOutgoingStreams());
+ }
+
+ // Continuing creating push stream would fail.
+ EXPECT_EQ(nullptr, QuicSimpleServerSessionPeer::CreateOutgoingDynamicStream(
+ session_.get(), kDefaultPriority));
+ EXPECT_EQ(kMaxStreamsForTest, session_->GetNumOpenOutgoingStreams());
+
+ // Create peer initiated stream should have no problem.
+ QuicStreamFrame data2(kClientDataStreamId2, false, 0, StringPiece("HT"));
+ session_->OnStreamFrame(data2);
+ EXPECT_EQ(2u, session_->GetNumOpenIncomingStreams());
+}
+
+TEST_P(QuicSimpleServerSessionTest, OnStreamFrameWithEvenStreamId) {
+ QuicStreamFrame frame(2, false, 0, StringPiece());
+ EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
+ QUIC_INVALID_STREAM_ID,
+ "Client sent data on server push stream"));
+ session_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSimpleServerSessionTest, TestPromisePushResources) {
+ // Tests that given more than kMaxOpenStreamForTest resources, all their
+ // PUSH_PROMISE's will be sent out and only |kMaxOpenStreamForTest| streams
+ // will be opened and send push response.
+ size_t num_resources = kMaxStreamsForTest + 5;
+ PromisePushResources(num_resources);
+ EXPECT_EQ(kMaxStreamsForTest, session_->GetNumOpenOutgoingStreams());
+}
+
+TEST_P(QuicSimpleServerSessionTest,
+ HandlePromisedPushRequestsAfterStreamDraining) {
+ // Tests that after promised stream queued up, when an opened stream is marked
+ // draining, a queued promised stream will become open and send push response.
+ size_t num_resources = kMaxStreamsForTest + 1;
+ PromisePushResources(num_resources);
+ QuicStreamId next_out_going_stream_id = num_resources * 2;
+
+ // After an open stream is marked draining, a new stream is expected to be
+ // created and a response sent on the stream.
+ EXPECT_CALL(*headers_stream_, WriteHeaders(next_out_going_stream_id, _, false,
+ kDefaultPriority, nullptr));
+ EXPECT_CALL(*connection_,
+ SendStreamData(next_out_going_stream_id, _, 0, true, _, nullptr))
+ .WillOnce(Return(QuicConsumedData(0, false)));
+ 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.
+ EXPECT_EQ(kMaxStreamsForTest, session_->GetNumOpenOutgoingStreams());
+}
+
+TEST_P(QuicSimpleServerSessionTest, GetEvenIncomingError) {
+ // Tests that calling GetOrCreateDynamicStream() on an outgoing stream not
+ // promised yet should result close connection.
+ EXPECT_CALL(*connection_,
+ SendConnectionCloseWithDetails(QUIC_INVALID_STREAM_ID,
+ "Data for nonexistent stream"));
+ EXPECT_EQ(nullptr,
+ QuicSessionPeer::GetOrCreateDynamicStream(session_.get(), 4));
+}
+
+TEST_P(QuicSimpleServerSessionTest, ResetPromisedStreamToCancelServerPush) {
+ // Tests that after all resources are promised, a RST frame from client can
+ // prevent a promised resource to be send out.
+
+ // Having two extra resources to be send later. One of them will be reset, so
+ // when opened stream become close, only one will become open.
+ size_t num_resources = kMaxStreamsForTest + 2;
+ PromisePushResources(num_resources);
+
+ // Reset the last stream in the queue. It should be marked cancelled.
+ QuicStreamId stream_got_reset = num_resources * 2;
+ QuicRstStreamFrame rst(stream_got_reset, QUIC_STREAM_CANCELLED, 0);
+ EXPECT_CALL(*connection_,
+ SendRstStream(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT, 0));
+ visitor_->OnRstStream(rst);
+
+ // When the first 2 streams becomes draining, the two queued up stream could
+ // be created. But since one of them was marked cancelled due to RST frame,
+ // only one queued resource will be sent out.
+ QuicStreamId stream_not_reset = (kMaxStreamsForTest + 1) * 2;
+ InSequence s;
+ EXPECT_CALL(*headers_stream_, WriteHeaders(stream_not_reset, _, false,
+ kDefaultPriority, nullptr));
+ EXPECT_CALL(*connection_,
+ SendStreamData(stream_not_reset, _, 0, true, _, nullptr))
+ .WillOnce(Return(QuicConsumedData(0, false)));
+ EXPECT_CALL(*headers_stream_, WriteHeaders(stream_got_reset, _, false,
+ kDefaultPriority, nullptr))
+ .Times(0);
+
+ session_->StreamDraining(2);
+ session_->StreamDraining(4);
+}
+
+TEST_P(QuicSimpleServerSessionTest, CloseStreamToHandleMorePromisedStream) {
+ // Tests that closing a open outgoing stream can trigger a promised resource
+ // in the queue to be send out.
+ size_t num_resources = kMaxStreamsForTest + 1;
+ PromisePushResources(num_resources);
+ QuicStreamId stream_to_open = num_resources * 2;
+
+ // Resetting 1st open stream will close the stream and give space for extra
+ // stream to be opened.
+ QuicStreamId stream_got_reset = 2;
+ EXPECT_CALL(*connection_,
+ SendRstStream(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT, _));
+ EXPECT_CALL(*headers_stream_, WriteHeaders(stream_to_open, _, false,
+ kDefaultPriority, nullptr));
+ EXPECT_CALL(*connection_,
+ SendStreamData(stream_to_open, _, 0, true, _, nullptr))
+ .WillOnce(Return(QuicConsumedData(0, false)));
+
+ QuicRstStreamFrame rst(stream_got_reset, QUIC_STREAM_CANCELLED, 0);
+ visitor_->OnRstStream(rst);
+}
+
+} // namespace
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_stream.cc b/chromium/net/tools/quic/quic_simple_server_stream.cc
new file mode 100644
index 00000000000..6a34fc6b75a
--- /dev/null
+++ b/chromium/net/tools/quic/quic_simple_server_stream.cc
@@ -0,0 +1,247 @@
+// 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/tools/quic/quic_simple_server_stream.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_spdy_stream.h"
+#include "net/quic/spdy_utils.h"
+#include "net/spdy/spdy_protocol.h"
+#include "net/tools/quic/quic_in_memory_cache.h"
+#include "net/tools/quic/quic_simple_server_session.h"
+
+using base::StringPiece;
+using base::StringToInt;
+using std::string;
+
+namespace net {
+namespace tools {
+
+QuicSimpleServerStream::QuicSimpleServerStream(QuicStreamId id,
+ QuicSpdySession* session)
+ : QuicSpdyStream(id, session), content_length_(-1) {}
+
+QuicSimpleServerStream::~QuicSimpleServerStream() {}
+
+void QuicSimpleServerStream::OnInitialHeadersComplete(bool fin,
+ size_t frame_len) {
+ QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len);
+ if (!SpdyUtils::ParseHeaders(decompressed_headers().data(),
+ decompressed_headers().length(),
+ &content_length_, &request_headers_)) {
+ DVLOG(1) << "Invalid headers";
+ SendErrorResponse();
+ }
+ MarkHeadersConsumed(decompressed_headers().length());
+}
+
+void QuicSimpleServerStream::OnTrailingHeadersComplete(bool fin,
+ size_t frame_len) {
+ LOG(DFATAL) << "Server does not support receiving Trailers.";
+ SendErrorResponse();
+}
+
+void QuicSimpleServerStream::OnDataAvailable() {
+ while (HasBytesToRead()) {
+ struct iovec iov;
+ if (GetReadableRegions(&iov, 1) == 0) {
+ // No more data to read.
+ break;
+ }
+ DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream " << id();
+ body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
+
+ if (content_length_ >= 0 &&
+ static_cast<int>(body_.size()) > content_length_) {
+ DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
+ << content_length_ << ").";
+ SendErrorResponse();
+ return;
+ }
+ MarkConsumed(iov.iov_len);
+ }
+ if (!sequencer()->IsClosed()) {
+ sequencer()->SetUnblocked();
+ return;
+ }
+
+ // If the sequencer is closed, then all the body, including the fin, has been
+ // consumed.
+ OnFinRead();
+
+ if (write_side_closed() || fin_buffered()) {
+ return;
+ }
+
+ if (request_headers_.empty()) {
+ DVLOG(1) << "Request headers empty.";
+ SendErrorResponse();
+ return;
+ }
+
+ if (content_length_ > 0 &&
+ content_length_ != static_cast<int>(body_.size())) {
+ DVLOG(1) << "Content length (" << content_length_ << ") != body size ("
+ << body_.size() << ").";
+ SendErrorResponse();
+ return;
+ }
+
+ SendResponse();
+}
+
+void QuicSimpleServerStream::PushResponse(
+ SpdyHeaderBlock push_request_headers) {
+ if (id() % 2 != 0) {
+ LOG(DFATAL) << "Client initiated stream shouldn't be used "
+ << "as promised stream.";
+ return;
+ }
+ // Change the stream state to emulate a client request.
+ request_headers_ = push_request_headers;
+ content_length_ = 0;
+ DVLOG(1) << "Stream " << id() << ": Ready to receive server push response.";
+
+ // Set as if stream decompresed the headers and received fin.
+ QuicSpdyStream::OnInitialHeadersComplete(/*fin=*/true, 0);
+}
+
+void QuicSimpleServerStream::SendResponse() {
+ if (!ContainsKey(request_headers_, ":authority") ||
+ !ContainsKey(request_headers_, ":path")) {
+ DVLOG(1) << "Request headers do not contain :authority or :path.";
+ SendErrorResponse();
+ return;
+ }
+
+ // Find response in cache. If not found, send error response.
+ const QuicInMemoryCache::Response* response =
+ QuicInMemoryCache::GetInstance()->GetResponse(
+ request_headers_[":authority"], request_headers_[":path"]);
+ if (response == nullptr) {
+ DVLOG(1) << "Response not found in cache.";
+ SendErrorResponse();
+ return;
+ }
+
+ if (response->response_type() == QuicInMemoryCache::CLOSE_CONNECTION) {
+ DVLOG(1) << "Special response: closing connection.";
+ CloseConnectionWithDetails(QUIC_NO_ERROR, "Toy server forcing close");
+ return;
+ }
+
+ if (response->response_type() == QuicInMemoryCache::IGNORE_REQUEST) {
+ DVLOG(1) << "Special response: ignoring request.";
+ return;
+ }
+
+ // Examing response status, if it was not pure integer as typical h2 response
+ // status, send error response.
+ string request_url;
+ if (!request_headers_[":scheme"].as_string().empty()) {
+ request_url = request_headers_[":scheme"].as_string() + "://" +
+ request_headers_[":authority"].as_string() +
+ request_headers_[":path"].as_string();
+ } else {
+ request_url = request_headers_[":authority"].as_string() +
+ request_headers_[":path"].as_string();
+ }
+ int response_code;
+ SpdyHeaderBlock response_headers = response->headers();
+ if (!base::StringToInt(response_headers[":status"], &response_code)) {
+ DVLOG(1) << "Illegal (non-integer) response :status from cache: "
+ << response_headers[":status"].as_string() << " for request "
+ << request_url;
+ SendErrorResponse();
+ return;
+ }
+
+ if (id() % 2 == 0) {
+ // A server initiated stream is only used for a server push response,
+ // and only 200 and 30X response codes are supported for server push.
+ // This behavior mirrors the HTTP/2 implementation.
+ bool is_redirection = response_code / 100 == 3;
+ if (response_code != 200 && !is_redirection) {
+ LOG(WARNING) << "Response to server push request " << request_url
+ << " result in response code " << response_code;
+ Reset(QUIC_STREAM_CANCELLED);
+ return;
+ }
+ }
+ list<QuicInMemoryCache::ServerPushInfo> resources =
+ QuicInMemoryCache::GetInstance()->GetServerPushResources(request_url);
+ DVLOG(1) << "Found " << resources.size() << " push resources for stream "
+ << id();
+
+ if (!resources.empty()) {
+ QuicSimpleServerSession* session =
+ static_cast<QuicSimpleServerSession*>(spdy_session());
+ session->PromisePushResources(request_url, resources, id(),
+ request_headers_);
+ }
+
+ DVLOG(1) << "Sending response for stream " << id();
+ SendHeadersAndBodyAndTrailers(response->headers(), response->body(),
+ response->trailers());
+}
+
+void QuicSimpleServerStream::SendErrorResponse() {
+ DVLOG(1) << "Sending error response for stream " << id();
+ SpdyHeaderBlock headers;
+ headers[":status"] = "500";
+ headers["content-length"] = base::UintToString(strlen(kErrorResponseBody));
+ SendHeadersAndBody(headers, kErrorResponseBody);
+}
+
+void QuicSimpleServerStream::SendHeadersAndBody(
+ const SpdyHeaderBlock& response_headers,
+ StringPiece body) {
+ SendHeadersAndBodyAndTrailers(response_headers, body, SpdyHeaderBlock());
+}
+
+void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
+ const SpdyHeaderBlock& response_headers,
+ StringPiece body,
+ const SpdyHeaderBlock& response_trailers) {
+ // This server only supports SPDY and HTTP, and neither handles bidirectional
+ // streaming.
+ if (!reading_stopped()) {
+ StopReading();
+ }
+
+ // Send the headers, with a FIN if there's nothing else to send.
+ bool send_fin = (body.empty() && response_trailers.empty());
+ DVLOG(1) << "Writing headers (fin = " << send_fin
+ << ") : " << response_headers.DebugString();
+ WriteHeaders(response_headers, send_fin, nullptr);
+ if (send_fin) {
+ // Nothing else to send.
+ return;
+ }
+
+ // Send the body, with a FIN if there's nothing else to send.
+ send_fin = response_trailers.empty();
+ DVLOG(1) << "Writing body (fin = " << send_fin
+ << ") with size: " << body.size();
+ WriteOrBufferData(body, send_fin, nullptr);
+ if (send_fin) {
+ // Nothing else to send.
+ return;
+ }
+
+ // Send the trailers. A FIN is always sent with trailers.
+ DVLOG(1) << "Writing trailers (fin = true): "
+ << response_trailers.DebugString();
+ WriteTrailers(response_trailers, nullptr);
+}
+
+const char* const QuicSimpleServerStream::kErrorResponseBody = "bad";
+
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_stream.h b/chromium/net/tools/quic/quic_simple_server_stream.h
new file mode 100644
index 00000000000..015a96a28ac
--- /dev/null
+++ b/chromium/net/tools/quic/quic_simple_server_stream.h
@@ -0,0 +1,81 @@
+// 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_TOOLS_QUIC_QUIC_SIMPLE_SERVER_STREAM_H_
+#define NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_STREAM_H_
+
+#include <stddef.h>
+
+#include <string>
+
+#include "base/macros.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_spdy_stream.h"
+#include "net/spdy/spdy_framer.h"
+
+namespace net {
+
+namespace tools {
+
+namespace test {
+class QuicSimpleServerStreamPeer;
+} // namespace test
+
+// All this does right now is aggregate data, and on fin, send an HTTP
+// response.
+class QuicSimpleServerStream : public QuicSpdyStream {
+ public:
+ QuicSimpleServerStream(QuicStreamId id, QuicSpdySession* session);
+ ~QuicSimpleServerStream() override;
+
+ // QuicSpdyStream
+ void OnInitialHeadersComplete(bool fin, size_t frame_len) override;
+ void OnTrailingHeadersComplete(bool fin, size_t frame_len) override;
+
+ // ReliableQuicStream implementation called by the sequencer when there is
+ // data (or a FIN) to be read.
+ void OnDataAvailable() override;
+
+ // Make this stream start from as if it just finished parsing an incoming
+ // request whose headers are equivalent to |push_request_headers|.
+ // Doing so will trigger this toy stream to fetch response and send it back.
+ virtual void PushResponse(SpdyHeaderBlock push_request_headers);
+
+ // The response body of error responses.
+ static const char* const kErrorResponseBody;
+
+ protected:
+ // Sends a basic 200 response using SendHeaders for the headers and WriteData
+ // for the body.
+ virtual void SendResponse();
+
+ // Sends a basic 500 response using SendHeaders for the headers and WriteData
+ // for the body
+ virtual void SendErrorResponse();
+
+ void SendHeadersAndBody(const SpdyHeaderBlock& response_headers,
+ base::StringPiece body);
+ void SendHeadersAndBodyAndTrailers(const SpdyHeaderBlock& response_headers,
+ base::StringPiece body,
+ const SpdyHeaderBlock& response_trailers);
+
+ SpdyHeaderBlock* request_headers() { return &request_headers_; }
+
+ const std::string& body() { return body_; }
+
+ private:
+ friend class test::QuicSimpleServerStreamPeer;
+
+ // The parsed headers received from the client.
+ SpdyHeaderBlock request_headers_;
+ int content_length_;
+ std::string body_;
+
+ DISALLOW_COPY_AND_ASSIGN(QuicSimpleServerStream);
+};
+
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_QUIC_SIMPLE_SERVER_STREAM_H_
diff --git a/chromium/net/tools/quic/quic_simple_server_stream_test.cc b/chromium/net/tools/quic/quic_simple_server_stream_test.cc
new file mode 100644
index 00000000000..5c28df03596
--- /dev/null
+++ b/chromium/net/tools/quic/quic_simple_server_stream_test.cc
@@ -0,0 +1,601 @@
+// Copyright (c) 2013 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/tools/quic/quic_simple_server_stream.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "net/quic/quic_connection.h"
+#include "net/quic/quic_flags.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_utils.h"
+#include "net/quic/spdy_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
+#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/quic/test_tools/reliable_quic_stream_peer.h"
+#include "net/test/gtest_util.h"
+#include "net/tools/epoll_server/epoll_server.h"
+#include "net/tools/quic/quic_in_memory_cache.h"
+#include "net/tools/quic/quic_simple_server_session.h"
+#include "net/tools/quic/spdy_balsa_utils.h"
+#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+using base::StringPiece;
+using net::test::MockConnection;
+using net::test::MockConnectionHelper;
+using net::test::MockQuicSpdySession;
+using net::test::ReliableQuicStreamPeer;
+using net::test::SupportedVersions;
+using net::test::kInitialSessionFlowControlWindowForTest;
+using net::test::kInitialStreamFlowControlWindowForTest;
+using std::string;
+using testing::_;
+using testing::AnyNumber;
+using testing::Invoke;
+using testing::InvokeArgument;
+using testing::InSequence;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace net {
+namespace tools {
+namespace test {
+
+class QuicSimpleServerStreamPeer : public QuicSimpleServerStream {
+ public:
+ QuicSimpleServerStreamPeer(QuicStreamId stream_id, QuicSpdySession* session)
+ : QuicSimpleServerStream(stream_id, session) {}
+
+ ~QuicSimpleServerStreamPeer() override{};
+
+ using QuicSimpleServerStream::SendResponse;
+ using QuicSimpleServerStream::SendErrorResponse;
+
+ SpdyHeaderBlock* mutable_headers() { return &request_headers_; }
+
+ static void SendResponse(QuicSimpleServerStream* stream) {
+ stream->SendResponse();
+ }
+
+ static void SendErrorResponse(QuicSimpleServerStream* stream) {
+ stream->SendErrorResponse();
+ }
+
+ static const string& body(QuicSimpleServerStream* stream) {
+ return stream->body_;
+ }
+
+ static int content_length(QuicSimpleServerStream* stream) {
+ return stream->content_length_;
+ }
+
+ static SpdyHeaderBlock& headers(QuicSimpleServerStream* stream) {
+ return stream->request_headers_;
+ }
+};
+
+class MockQuicSimpleServerSession : public QuicSimpleServerSession {
+ public:
+ const size_t kMaxStreamsForTest = 100;
+
+ explicit MockQuicSimpleServerSession(QuicConnection* connection,
+ MockQuicServerSessionVisitor* owner,
+ QuicCryptoServerConfig* crypto_config)
+ : QuicSimpleServerSession(::net::test::DefaultQuicConfig(),
+ connection,
+ owner,
+ crypto_config) {
+ set_max_open_streams(kMaxStreamsForTest);
+ ON_CALL(*this, WritevData(_, _, _, _, _, _))
+ .WillByDefault(testing::Return(QuicConsumedData(0, false)));
+ }
+
+ ~MockQuicSimpleServerSession() override {}
+
+ MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer));
+ MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id));
+ MOCK_METHOD6(WritevData,
+ QuicConsumedData(QuicStreamId id,
+ QuicIOVector data,
+ QuicStreamOffset offset,
+ bool fin,
+ FecProtection fec_protection,
+ QuicAckListenerInterface*));
+ MOCK_METHOD2(OnStreamHeaders,
+ void(QuicStreamId stream_id, StringPiece headers_data));
+ MOCK_METHOD2(OnStreamHeadersPriority,
+ void(QuicStreamId stream_id, SpdyPriority priority));
+ MOCK_METHOD3(OnStreamHeadersComplete,
+ void(QuicStreamId stream_id, bool fin, size_t frame_len));
+ MOCK_METHOD5(WriteHeaders,
+ size_t(QuicStreamId id,
+ const SpdyHeaderBlock& headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicAckListenerInterface* ack_notifier_delegate));
+ MOCK_METHOD3(SendRstStream,
+ void(QuicStreamId stream_id,
+ QuicRstStreamErrorCode error,
+ QuicStreamOffset bytes_written));
+ MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta));
+ MOCK_METHOD4(PromisePushResources,
+ void(const string&,
+ const list<QuicInMemoryCache::ServerPushInfo>&,
+ QuicStreamId,
+ const SpdyHeaderBlock&));
+
+ using QuicSession::ActivateStream;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockQuicSimpleServerSession);
+};
+
+namespace {
+
+class QuicSimpleServerStreamTest
+ : public ::testing::TestWithParam<QuicVersion> {
+ public:
+ QuicSimpleServerStreamTest()
+ : connection_(
+ new StrictMock<MockConnection>(&helper_,
+ Perspective::IS_SERVER,
+ SupportedVersions(GetParam()))),
+ session_owner_(new StrictMock<MockQuicServerSessionVisitor>()),
+ crypto_config_(new QuicCryptoServerConfig(
+ QuicCryptoServerConfig::TESTING,
+ QuicRandom::GetInstance(),
+ ::net::test::CryptoTestUtils::ProofSourceForTesting())),
+ session_(connection_, session_owner_, crypto_config_.get()),
+ body_("hello world") {
+ SpdyHeaderBlock request_headers;
+ request_headers[":host"] = "";
+ request_headers[":authority"] = "www.google.com";
+ request_headers[":path"] = "/";
+ request_headers[":method"] = "POST";
+ request_headers[":version"] = "HTTP/1.1";
+ request_headers["content-length"] = "11";
+
+ headers_string_ =
+ net::SpdyUtils::SerializeUncompressedHeaders(request_headers);
+
+ // New streams rely on having the peer's flow control receive window
+ // negotiated in the config.
+ session_.config()->SetInitialStreamFlowControlWindowToSend(
+ kInitialStreamFlowControlWindowForTest);
+ session_.config()->SetInitialSessionFlowControlWindowToSend(
+ kInitialSessionFlowControlWindowForTest);
+ stream_ = new QuicSimpleServerStreamPeer(::net::test::kClientDataStreamId1,
+ &session_);
+ // Register stream_ in dynamic_stream_map_ and pass ownership to session_.
+ session_.ActivateStream(stream_);
+
+ QuicInMemoryCachePeer::ResetForTests();
+ }
+
+ ~QuicSimpleServerStreamTest() override {
+ QuicInMemoryCachePeer::ResetForTests();
+ }
+
+ const string& StreamBody() {
+ return QuicSimpleServerStreamPeer::body(stream_);
+ }
+
+ StringPiece StreamHeadersValue(const string& key) {
+ return (*stream_->mutable_headers())[key];
+ }
+
+ SpdyHeaderBlock response_headers_;
+ MockConnectionHelper helper_;
+ StrictMock<MockConnection>* connection_;
+ StrictMock<MockQuicServerSessionVisitor>* session_owner_;
+ std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
+ StrictMock<MockQuicSimpleServerSession> session_;
+ QuicSimpleServerStreamPeer* stream_; // Owned by session_.
+ string headers_string_;
+ string body_;
+};
+
+INSTANTIATE_TEST_CASE_P(Tests,
+ QuicSimpleServerStreamTest,
+ ::testing::ValuesIn(QuicSupportedVersions()));
+
+TEST_P(QuicSimpleServerStreamTest, TestFraming) {
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+ stream_->OnStreamHeaders(headers_string_);
+ stream_->OnStreamHeadersComplete(false, headers_string_.size());
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
+ EXPECT_EQ("11", StreamHeadersValue("content-length"));
+ EXPECT_EQ("/", StreamHeadersValue(":path"));
+ EXPECT_EQ("POST", StreamHeadersValue(":method"));
+ EXPECT_EQ(body_, StreamBody());
+}
+
+TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ stream_->OnStreamHeaders(headers_string_);
+ stream_->OnStreamHeadersComplete(false, headers_string_.size());
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
+ EXPECT_EQ("11", StreamHeadersValue("content-length"));
+ EXPECT_EQ("/", StreamHeadersValue(":path"));
+ EXPECT_EQ("POST", StreamHeadersValue(":method"));
+ EXPECT_EQ(body_, StreamBody());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+
+ EXPECT_FALSE(stream_->fin_received());
+ EXPECT_FALSE(stream_->rst_received());
+
+ stream_->set_fin_sent(true);
+ stream_->CloseWriteSide();
+
+ if (GetParam() > QUIC_VERSION_28) {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1);
+ } else {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+ }
+ stream_->StopReading();
+}
+
+TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
+ string large_body = "hello world!!!!!!";
+
+ // We'll automatically write out an error (headers + body)
+ EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .WillOnce(Invoke(MockQuicSpdySession::ConsumeAllData));
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+
+ stream_->OnStreamHeaders(headers_string_);
+ stream_->OnStreamHeadersComplete(false, headers_string_.size());
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
+ // Content length is still 11. This will register as an error and we won't
+ // accept the bytes.
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/true, body_.size(), large_body));
+ EXPECT_EQ("11", StreamHeadersValue("content-length"));
+ EXPECT_EQ("/", StreamHeadersValue(":path"));
+ EXPECT_EQ("POST", StreamHeadersValue(":method"));
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
+ // Send a illegal response with response status not supported by HTTP/2.
+ SpdyHeaderBlock* request_headers = stream_->mutable_headers();
+ (*request_headers)[":path"] = "/bar";
+ (*request_headers)[":authority"] = "www.google.com";
+ (*request_headers)[":version"] = "HTTP/1.1";
+ (*request_headers)[":method"] = "GET";
+
+ response_headers_[":version"] = "HTTP/1.1";
+ // HTTP/2 only supports integer responsecode, so "200 OK" is illegal.
+ response_headers_[":status"] = "200 OK";
+ response_headers_["content-length"] = "5";
+ string body = "Yummm";
+ QuicInMemoryCache::GetInstance()->AddResponse("www.google.com", "/bar",
+ response_headers_, body);
+
+ stream_->set_fin_received(true);
+
+ InSequence s;
+ EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(1)
+ .WillOnce(Return(QuicConsumedData(
+ strlen(QuicSimpleServerStream::kErrorResponseBody), true)));
+
+ QuicSimpleServerStreamPeer::SendResponse(stream_);
+ EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_TRUE(stream_->reading_stopped());
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) {
+ // Create a new promised stream with even id().
+ QuicSimpleServerStreamPeer* promised_stream =
+ new QuicSimpleServerStreamPeer(2, &session_);
+ session_.ActivateStream(promised_stream);
+
+ // Send a push response with response status 404, which will be regarded as
+ // invalid server push response.
+ SpdyHeaderBlock* request_headers = promised_stream->mutable_headers();
+ (*request_headers)[":path"] = "/bar";
+ (*request_headers)[":authority"] = "www.google.com";
+ (*request_headers)[":version"] = "HTTP/1.1";
+ (*request_headers)[":method"] = "GET";
+
+ response_headers_[":version"] = "HTTP/1.1";
+ response_headers_[":status"] = "404";
+ response_headers_["content-length"] = "8";
+ string body = "NotFound";
+ QuicInMemoryCache::GetInstance()->AddResponse("www.google.com", "/bar",
+ response_headers_, body);
+
+ InSequence s;
+ EXPECT_CALL(session_,
+ SendRstStream(promised_stream->id(), QUIC_STREAM_CANCELLED, 0));
+
+ QuicSimpleServerStreamPeer::SendResponse(promised_stream);
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
+ // Add a request and response with valid headers.
+ SpdyHeaderBlock* request_headers = stream_->mutable_headers();
+ (*request_headers)[":path"] = "/bar";
+ (*request_headers)[":authority"] = "www.google.com";
+ (*request_headers)[":version"] = "HTTP/1.1";
+ (*request_headers)[":method"] = "GET";
+
+ response_headers_[":version"] = "HTTP/1.1";
+ response_headers_[":status"] = "200";
+ response_headers_["content-length"] = "5";
+ string body = "Yummm";
+ QuicInMemoryCache::GetInstance()->AddResponse("www.google.com", "/bar",
+ response_headers_, body);
+ stream_->set_fin_received(true);
+
+ InSequence s;
+ EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(1)
+ .WillOnce(Return(QuicConsumedData(body.length(), true)));
+
+ QuicSimpleServerStreamPeer::SendResponse(stream_);
+ EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_TRUE(stream_->reading_stopped());
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendReponseWithPushResources) {
+ // Tests that if a reponse has push resources to be send, SendResponse() will
+ // call PromisePushResources() to handle these resources.
+
+ // Add a request and response with valid headers into cache.
+ string host = "www.google.com";
+ string request_path = "/foo";
+ string body = "Yummm";
+ SpdyHeaderBlock response_headers;
+ string url = host + "/bar";
+ QuicInMemoryCache::ServerPushInfo push_info(GURL(url), response_headers,
+ kDefaultPriority, "Push body");
+ list<QuicInMemoryCache::ServerPushInfo> push_resources;
+ push_resources.push_back(push_info);
+ QuicInMemoryCache::GetInstance()->AddSimpleResponseWithServerPushResources(
+ host, request_path, 200, body, push_resources);
+
+ SpdyHeaderBlock* request_headers = stream_->mutable_headers();
+ (*request_headers)[":path"] = request_path;
+ (*request_headers)[":authority"] = host;
+ (*request_headers)[":version"] = "HTTP/1.1";
+ (*request_headers)[":method"] = "GET";
+
+ stream_->set_fin_received(true);
+ InSequence s;
+ EXPECT_CALL(session_, PromisePushResources(host + request_path, _,
+ ::net::test::kClientDataStreamId1,
+ *request_headers));
+ EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, false, _, nullptr));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(1)
+ .WillOnce(Return(QuicConsumedData(body.length(), true)));
+ QuicSimpleServerStreamPeer::SendResponse(stream_);
+}
+
+TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) {
+ // Calling PushResponse() on a client initialted stream is never supposed to
+ // happen.
+ SpdyHeaderBlock headers;
+ EXPECT_DFATAL(stream_->PushResponse(headers),
+ "Client initiated stream"
+ " shouldn't be used as promised stream.");
+}
+
+TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) {
+ // Tests that PushResponse() should take the given headers as request headers
+ // and fetch response from cache, and send it out.
+
+ // Create a stream with even stream id and test against this stream.
+ const QuicStreamId kServerInitiatedStreamId = 2;
+ // Create a server initiated stream and pass it to session_.
+ QuicSimpleServerStreamPeer* server_initiated_stream =
+ new QuicSimpleServerStreamPeer(kServerInitiatedStreamId, &session_);
+ session_.ActivateStream(server_initiated_stream);
+
+ const string kHost = "www.foo.com";
+ const string kPath = "/bar";
+ SpdyHeaderBlock headers;
+ headers[":path"] = kPath;
+ headers[":authority"] = kHost;
+ headers[":version"] = "HTTP/1.1";
+ headers[":method"] = "GET";
+
+ response_headers_[":version"] = "HTTP/1.1";
+ response_headers_[":status"] = "200";
+ response_headers_["content-length"] = "5";
+ const string kBody = "Hello";
+ QuicInMemoryCache::GetInstance()->AddResponse(kHost, kPath, response_headers_,
+ kBody);
+
+ // Call PushResponse() should trigger stream to fetch response from cache
+ // and send it back.
+ EXPECT_CALL(session_,
+ WriteHeaders(kServerInitiatedStreamId, _, false,
+ server_initiated_stream->Priority(), nullptr));
+ EXPECT_CALL(session_, WritevData(kServerInitiatedStreamId, _, _, _, _, _))
+ .Times(1)
+ .WillOnce(Return(QuicConsumedData(kBody.size(), true)));
+ server_initiated_stream->PushResponse(headers);
+ EXPECT_EQ(kPath, QuicSimpleServerStreamPeer::headers(
+ server_initiated_stream)[":path"]
+ .as_string());
+ EXPECT_EQ("GET", QuicSimpleServerStreamPeer::headers(
+ server_initiated_stream)[":method"]
+ .as_string());
+}
+
+TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+
+ response_headers_[":version"] = "HTTP/1.1";
+ response_headers_[":status"] = "500 Server Error";
+ response_headers_["content-length"] = "3";
+ stream_->set_fin_received(true);
+
+ InSequence s;
+ EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(1)
+ .WillOnce(Return(QuicConsumedData(3, true)));
+
+ QuicSimpleServerStreamPeer::SendErrorResponse(stream_);
+ EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_TRUE(stream_->reading_stopped());
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+
+ SpdyHeaderBlock request_headers;
+ // \000 is a way to write the null byte when followed by a literal digit.
+ request_headers["content-length"] = StringPiece("11\00012", 5);
+
+ headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers);
+
+ EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+ stream_->OnStreamHeaders(headers_string_);
+ stream_->OnStreamHeadersComplete(true, headers_string_.size());
+
+ EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_TRUE(stream_->reading_stopped());
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+
+ SpdyHeaderBlock request_headers;
+ // \000 is a way to write the null byte when followed by a literal digit.
+ request_headers["content-length"] = StringPiece("\00012", 3);
+
+ headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers);
+
+ EXPECT_CALL(session_, WriteHeaders(_, _, _, _, _));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+ stream_->OnStreamHeaders(headers_string_);
+ stream_->OnStreamHeadersComplete(true, headers_string_.size());
+
+ EXPECT_TRUE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_TRUE(stream_->reading_stopped());
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) {
+ SpdyHeaderBlock request_headers;
+ // \000 is a way to write the null byte when followed by a literal digit.
+ request_headers["content-length"] = StringPiece("11\00011", 5);
+
+ headers_string_ = SpdyUtils::SerializeUncompressedHeaders(request_headers);
+
+ stream_->OnStreamHeaders(headers_string_);
+ stream_->OnStreamHeadersComplete(false, headers_string_.size());
+
+ EXPECT_EQ(11, QuicSimpleServerStreamPeer::content_length(stream_));
+ EXPECT_FALSE(ReliableQuicStreamPeer::read_side_closed(stream_));
+ EXPECT_FALSE(stream_->reading_stopped());
+ EXPECT_FALSE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorWithEarlyResponse) {
+ response_headers_[":version"] = "HTTP/1.1";
+ response_headers_[":status"] = "500 Server Error";
+ response_headers_["content-length"] = "3";
+
+ InSequence s;
+ EXPECT_CALL(session_, WriteHeaders(stream_->id(), _, _, _, _));
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .Times(1)
+ .WillOnce(Return(QuicConsumedData(3, true)));
+ if (GetParam() > QUIC_VERSION_28) {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(1);
+ } else {
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+ }
+ EXPECT_FALSE(stream_->fin_received());
+ QuicSimpleServerStreamPeer::SendErrorResponse(stream_);
+ EXPECT_TRUE(stream_->reading_stopped());
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest,
+ DoNotSendQuicRstStreamNoErrorWithRstReceived) {
+ response_headers_[":version"] = "HTTP/1.1";
+ response_headers_[":status"] = "500 Server Error";
+ response_headers_["content-length"] = "3";
+
+ InSequence s;
+ EXPECT_FALSE(stream_->reading_stopped());
+
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
+ EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _)).Times(1);
+ QuicRstStreamFrame rst_frame(stream_->id(), QUIC_STREAM_CANCELLED, 1234);
+ stream_->OnStreamReset(rst_frame);
+
+ EXPECT_TRUE(stream_->reading_stopped());
+ EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
+ char arr[] = {
+ 0x3a, 0x68, 0x6f, 0x73, // :hos
+ 0x74, 0x00, 0x00, 0x00, // t...
+ 0x00, 0x00, 0x00, 0x00, // ....
+ 0x07, 0x3a, 0x6d, 0x65, // .:me
+ 0x74, 0x68, 0x6f, 0x64, // thod
+ 0x00, 0x00, 0x00, 0x03, // ....
+ 0x47, 0x45, 0x54, 0x00, // GET.
+ 0x00, 0x00, 0x05, 0x3a, // ...:
+ 0x70, 0x61, 0x74, 0x68, // path
+ 0x00, 0x00, 0x00, 0x04, // ....
+ 0x2f, 0x66, 0x6f, 0x6f, // /foo
+ 0x00, 0x00, 0x00, 0x07, // ....
+ 0x3a, 0x73, 0x63, 0x68, // :sch
+ 0x65, 0x6d, 0x65, 0x00, // eme.
+ 0x00, 0x00, 0x00, 0x00, // ....
+ 0x00, 0x00, 0x08, 0x3a, // ...:
+ 0x76, 0x65, 0x72, 0x73, // vers
+ '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on.
+ 0x00, 0x00, 0x08, 0x48, // ...H
+ 0x54, 0x54, 0x50, 0x2f, // TTP/
+ 0x31, 0x2e, 0x31, // 1.1
+ };
+ StringPiece data(arr, arraysize(arr));
+ QuicStreamFrame frame(stream_->id(), true, 0, data);
+ // Verify that we don't crash when we get a invalid headers in stream frame.
+ stream_->OnStreamFrame(frame);
+}
+
+} // namespace
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/quic_simple_server_test.cc b/chromium/net/tools/quic/quic_simple_server_test.cc
index ddb6318a223..d98069c5c3c 100644
--- a/chromium/net/tools/quic/quic_simple_server_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_test.cc
@@ -6,11 +6,13 @@
#include "net/quic/crypto/quic_random.h"
#include "net/quic/quic_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_quic_dispatcher.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
+using net::test::CryptoTestUtils;
namespace net {
namespace tools {
@@ -20,11 +22,12 @@ namespace test {
class QuicChromeServerDispatchPacketTest : public ::testing::Test {
public:
QuicChromeServerDispatchPacketTest()
- : crypto_config_("blah", QuicRandom::GetInstance()),
+ : crypto_config_("blah",
+ QuicRandom::GetInstance(),
+ CryptoTestUtils::ProofSourceForTesting()),
dispatcher_(config_,
&crypto_config_,
- new tools::QuicDispatcher::DefaultPacketWriterFactory(),
- new net::test::MockHelper) {
+ new net::test::MockConnectionHelper) {
dispatcher_.InitializeWithWriter(nullptr);
}
@@ -40,17 +43,15 @@ class QuicChromeServerDispatchPacketTest : public ::testing::Test {
};
TEST_F(QuicChromeServerDispatchPacketTest, DispatchPacket) {
- unsigned char valid_packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00 };
+ unsigned char valid_packet[] = {// public flags (8 byte connection_id)
+ 0x3C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC,
+ 0xFE,
+ // packet sequence number
+ 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ // private flags
+ 0x00};
QuicEncryptedPacket encrypted_valid_packet(QuicUtils::AsChars(valid_packet),
arraysize(valid_packet), false);
diff --git a/chromium/net/tools/quic/quic_socket_utils.cc b/chromium/net/tools/quic/quic_socket_utils.cc
index ae557327b75..1853a6bf568 100644
--- a/chromium/net/tools/quic/quic_socket_utils.cc
+++ b/chromium/net/tools/quic/quic_socket_utils.cc
@@ -6,13 +6,12 @@
#include <errno.h>
#include <netinet/in.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <string>
-#include "base/basictypes.h"
#include "base/logging.h"
-#include "net/base/net_util.h"
#include "net/quic/quic_protocol.h"
#ifndef SO_RXQ_OVFL
@@ -25,18 +24,17 @@ namespace tools {
// static
IPAddressNumber QuicSocketUtils::GetAddressFromMsghdr(struct msghdr* hdr) {
if (hdr->msg_controllen > 0) {
- for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
- cmsg != nullptr;
+ for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
cmsg = CMSG_NXTHDR(hdr, cmsg)) {
- const uint8* addr_data = nullptr;
+ const uint8_t* addr_data = nullptr;
int len = 0;
if (cmsg->cmsg_type == IPV6_PKTINFO) {
- in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>CMSG_DATA(cmsg);
- addr_data = reinterpret_cast<const uint8*>(&info->ipi6_addr);
+ in6_pktinfo* info = reinterpret_cast<in6_pktinfo*> CMSG_DATA(cmsg);
+ addr_data = reinterpret_cast<const uint8_t*>(&info->ipi6_addr);
len = sizeof(in6_addr);
} else if (cmsg->cmsg_type == IP_PKTINFO) {
- in_pktinfo* info = reinterpret_cast<in_pktinfo*>CMSG_DATA(cmsg);
- addr_data = reinterpret_cast<const uint8*>(&info->ipi_addr);
+ in_pktinfo* info = reinterpret_cast<in_pktinfo*> CMSG_DATA(cmsg);
+ addr_data = reinterpret_cast<const uint8_t*>(&info->ipi_addr);
len = sizeof(in_addr);
} else {
continue;
@@ -53,11 +51,10 @@ bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr* hdr,
QuicPacketCount* dropped_packets) {
if (hdr->msg_controllen > 0) {
struct cmsghdr* cmsg;
- for (cmsg = CMSG_FIRSTHDR(hdr);
- cmsg != nullptr;
+ for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
cmsg = CMSG_NXTHDR(hdr, cmsg)) {
if (cmsg->cmsg_type == SO_RXQ_OVFL) {
- *dropped_packets = *(reinterpret_cast<int*>CMSG_DATA(cmsg));
+ *dropped_packets = *(reinterpret_cast<int*> CMSG_DATA(cmsg));
return true;
}
}
@@ -68,11 +65,11 @@ bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr* hdr,
// static
int QuicSocketUtils::SetGetAddressInfo(int fd, int address_family) {
int get_local_ip = 1;
- int rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO,
- &get_local_ip, sizeof(get_local_ip));
+ int rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip,
+ sizeof(get_local_ip));
if (rc == 0 && address_family == AF_INET6) {
- rc = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
- &get_local_ip, sizeof(get_local_ip));
+ rc = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip,
+ sizeof(get_local_ip));
}
return rc;
}
@@ -96,7 +93,9 @@ bool QuicSocketUtils::SetReceiveBufferSize(int fd, size_t size) {
}
// static
-int QuicSocketUtils::ReadPacket(int fd, char* buffer, size_t buf_len,
+int QuicSocketUtils::ReadPacket(int fd,
+ char* buffer,
+ size_t buf_len,
QuicPacketCount* dropped_packets,
IPAddressNumber* self_address,
IPEndPoint* peer_address) {
@@ -183,8 +182,7 @@ WriteResult QuicSocketUtils::WritePacket(int fd,
sockaddr_storage raw_address;
socklen_t address_len = sizeof(raw_address);
CHECK(peer_address.ToSockAddr(
- reinterpret_cast<struct sockaddr*>(&raw_address),
- &address_len));
+ reinterpret_cast<struct sockaddr*>(&raw_address), &address_len));
iovec iov = {const_cast<char*>(buffer), buf_len};
msghdr hdr;
@@ -215,8 +213,10 @@ WriteResult QuicSocketUtils::WritePacket(int fd,
if (rc >= 0) {
return WriteResult(WRITE_STATUS_OK, rc);
}
- return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK) ?
- WRITE_STATUS_BLOCKED : WRITE_STATUS_ERROR, errno);
+ return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+ ? WRITE_STATUS_BLOCKED
+ : WRITE_STATUS_ERROR,
+ errno);
}
} // namespace tools
diff --git a/chromium/net/tools/quic/quic_socket_utils.h b/chromium/net/tools/quic/quic_socket_utils.h
index 2c8fe437349..2d152f9a36e 100644
--- a/chromium/net/tools/quic/quic_socket_utils.h
+++ b/chromium/net/tools/quic/quic_socket_utils.h
@@ -9,9 +9,10 @@
#include <stddef.h>
#include <sys/socket.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_types.h"
diff --git a/chromium/net/tools/quic/quic_spdy_client_stream.cc b/chromium/net/tools/quic/quic_spdy_client_stream.cc
index b8cb73b9c54..a77cab7fbac 100644
--- a/chromium/net/tools/quic/quic_spdy_client_stream.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_stream.cc
@@ -21,37 +21,71 @@ namespace tools {
QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
QuicClientSession* session)
- : QuicDataStream(id, session),
+ : QuicSpdyStream(id, session),
content_length_(-1),
response_code_(0),
header_bytes_read_(0),
- header_bytes_written_(0) {
-}
+ header_bytes_written_(0),
+ allow_bidirectional_data_(false) {}
-QuicSpdyClientStream::~QuicSpdyClientStream() {
-}
+QuicSpdyClientStream::~QuicSpdyClientStream() {}
void QuicSpdyClientStream::OnStreamFrame(const QuicStreamFrame& frame) {
- if (!write_side_closed()) {
+ if (!allow_bidirectional_data_ && !write_side_closed()) {
DVLOG(1) << "Got a response before the request was complete. "
<< "Aborting request.";
CloseWriteSide();
}
- QuicDataStream::OnStreamFrame(frame);
+ QuicSpdyStream::OnStreamFrame(frame);
}
-void QuicSpdyClientStream::OnStreamHeadersComplete(bool fin,
- size_t frame_len) {
+void QuicSpdyClientStream::OnInitialHeadersComplete(bool fin,
+ size_t frame_len) {
+ QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len);
+
+ DCHECK(headers_decompressed());
header_bytes_read_ = frame_len;
- QuicDataStream::OnStreamHeadersComplete(fin, frame_len);
- if (!ParseResponseHeaders(decompressed_headers().data(),
- decompressed_headers().length())) {
+ if (!SpdyUtils::ParseHeaders(decompressed_headers().data(),
+ decompressed_headers().length(),
+ &content_length_, &response_headers_)) {
+ Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+ return;
+ }
+
+ string status = response_headers_[":status"].as_string();
+ size_t end = status.find(" ");
+ if (end != string::npos) {
+ status.erase(end);
+ }
+ if (!StringToInt(status, &response_code_)) {
+ // Invalid response code.
Reset(QUIC_BAD_APPLICATION_PAYLOAD);
return;
}
+
MarkHeadersConsumed(decompressed_headers().length());
}
+void QuicSpdyClientStream::OnTrailingHeadersComplete(bool fin,
+ size_t frame_len) {
+ QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len);
+
+ size_t final_byte_offset = 0;
+ if (!SpdyUtils::ParseTrailers(decompressed_trailers().data(),
+ decompressed_trailers().length(),
+ &final_byte_offset, &response_trailers_)) {
+ Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+ return;
+ }
+ MarkTrailersConsumed(decompressed_trailers().length());
+
+ // The data on this stream ends at |final_byte_offset|.
+ DVLOG(1) << "Stream ends at byte offset: " << final_byte_offset
+ << " currently read: " << stream_bytes_read();
+ OnStreamFrame(
+ QuicStreamFrame(id(), /*fin=*/true, final_byte_offset, StringPiece()));
+}
+
void QuicSpdyClientStream::OnDataAvailable() {
while (HasBytesToRead()) {
struct iovec iov;
@@ -77,44 +111,12 @@ void QuicSpdyClientStream::OnDataAvailable() {
}
}
-bool QuicSpdyClientStream::ParseResponseHeaders(const char* data,
- uint32 data_len) {
- DCHECK(headers_decompressed());
- SpdyFramer framer(HTTP2);
- size_t len = framer.ParseHeaderBlockInBuffer(data,
- data_len,
- &response_headers_);
- DCHECK_LE(len, data_len);
- if (len == 0 || response_headers_.empty()) {
- return false; // Headers were invalid.
- }
-
- if (data_len > len) {
- data_.append(data + len, data_len - len);
- }
- if (ContainsKey(response_headers_, "content-length") &&
- !StringToInt(StringPiece(response_headers_["content-length"]),
- &content_length_)) {
- return false; // Invalid content-length.
- }
- string status = response_headers_[":status"].as_string();
- size_t end = status.find(" ");
- if (end != string::npos) {
- status.erase(end);
- }
- if (!StringToInt(status, &response_code_)) {
- return false; // Invalid response code.
- }
- return true;
-}
-
size_t QuicSpdyClientStream::SendRequest(const SpdyHeaderBlock& headers,
StringPiece body,
bool fin) {
bool send_fin_with_headers = fin && body.empty();
size_t bytes_sent = body.size();
- header_bytes_written_ =
- WriteHeaders(headers, send_fin_with_headers, nullptr);
+ header_bytes_written_ = WriteHeaders(headers, send_fin_with_headers, nullptr);
bytes_sent += header_bytes_written_;
if (!body.empty()) {
@@ -128,10 +130,10 @@ void QuicSpdyClientStream::SendBody(const string& data, bool fin) {
SendBody(data, fin, nullptr);
}
-void QuicSpdyClientStream::SendBody(
- const string& data, bool fin,
- QuicAckNotifier::DelegateInterface* delegate) {
- WriteOrBufferData(data, fin, delegate);
+void QuicSpdyClientStream::SendBody(const string& data,
+ bool fin,
+ QuicAckListenerInterface* listener) {
+ WriteOrBufferData(data, fin, listener);
}
} // namespace tools
diff --git a/chromium/net/tools/quic/quic_spdy_client_stream.h b/chromium/net/tools/quic/quic_spdy_client_stream.h
index 9c351637e9e..d56eb554b6d 100644
--- a/chromium/net/tools/quic/quic_spdy_client_stream.h
+++ b/chromium/net/tools/quic/quic_spdy_client_stream.h
@@ -5,13 +5,15 @@
#ifndef NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
#define NET_TOOLS_QUIC_QUIC_SPDY_CLIENT_STREAM_H_
+#include <stddef.h>
#include <sys/types.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
-#include "net/quic/quic_data_stream.h"
#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_spdy_stream.h"
#include "net/spdy/spdy_framer.h"
namespace net {
@@ -21,7 +23,7 @@ class QuicClientSession;
// All this does right now is send an SPDY request, and aggregate the
// SPDY response.
-class QuicSpdyClientStream : public QuicDataStream {
+class QuicSpdyClientStream : public QuicSpdyStream {
public:
QuicSpdyClientStream(QuicStreamId id, QuicClientSession* session);
~QuicSpdyClientStream() override;
@@ -31,8 +33,11 @@ class QuicSpdyClientStream : public QuicDataStream {
// SPDY/HTTP does not support bidirectional streaming.
void OnStreamFrame(const QuicStreamFrame& frame) override;
- // Override the base class to store the size of the headers.
- void OnStreamHeadersComplete(bool fin, size_t frame_len) override;
+ // Override the base class to parse and store headers.
+ void OnInitialHeadersComplete(bool fin, size_t frame_len) override;
+
+ // Override the base class to parse and store trailers.
+ void OnTrailingHeadersComplete(bool fin, size_t frame_len) override;
// ReliableQuicStream implementation called by the session when there's
// data for us.
@@ -49,7 +54,7 @@ class QuicSpdyClientStream : public QuicDataStream {
// As above, but |delegate| will be notified once |data| is ACKed.
void SendBody(const std::string& data,
bool fin,
- QuicAckNotifier::DelegateInterface* delegate);
+ QuicAckListenerInterface* listener);
// Returns the response data.
const std::string& data() { return data_; }
@@ -57,27 +62,43 @@ class QuicSpdyClientStream : public QuicDataStream {
// Returns whatever headers have been received for this stream.
const SpdyHeaderBlock& headers() { return response_headers_; }
+ // Returns whatever trailers have been received for this stream.
+ const SpdyHeaderBlock& trailers() { return response_trailers_; }
+
size_t header_bytes_read() const { return header_bytes_read_; }
size_t header_bytes_written() const { return header_bytes_written_; }
+ size_t trailer_bytes_read() const { return header_bytes_read_; }
+
int response_code() const { return response_code_; }
- // While the server's set_priority shouldn't be called externally, the creator
+ // While the server's SetPriority shouldn't be called externally, the creator
// of client-side streams should be able to set the priority.
- using QuicDataStream::set_priority;
+ using QuicSpdyStream::SetPriority;
- private:
- bool ParseResponseHeaders(const char* data, uint32 data_len);
+ void set_allow_bidirectional_data(bool value) {
+ allow_bidirectional_data_ = value;
+ }
+ bool allow_bidirectional_data() const { return allow_bidirectional_data_; }
+
+ private:
// The parsed headers received from the server.
SpdyHeaderBlock response_headers_;
+
+ // The parsed trailers received from the server.
+ SpdyHeaderBlock response_trailers_;
+
// The parsed content-length, or -1 if none is specified.
int content_length_;
int response_code_;
std::string data_;
size_t header_bytes_read_;
size_t header_bytes_written_;
+ // When true allows the sending of a request to continue while the response is
+ // arriving.
+ bool allow_bidirectional_data_;
DISALLOW_COPY_AND_ASSIGN(QuicSpdyClientStream);
};
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 03f8cc29e60..eaefac5843f 100644
--- a/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
@@ -4,8 +4,11 @@
#include "net/tools/quic/quic_spdy_client_stream.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "net/quic/quic_utils.h"
+#include "net/quic/spdy_utils.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/tools/quic/quic_client_session.h"
#include "net/tools/quic/quic_spdy_client_stream.h"
@@ -13,8 +16,10 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using net::test::CryptoTestUtils;
using net::test::DefaultQuicConfig;
using net::test::MockConnection;
+using net::test::MockConnectionHelper;
using net::test::SupportedVersions;
using net::test::kClientDataStreamId1;
using net::test::kInitialSessionFlowControlWindowForTest;
@@ -29,86 +34,80 @@ namespace tools {
namespace test {
namespace {
-class QuicSpdyClientStreamTest : public TestWithParam<QuicVersion> {
+class MockQuicClientSession : public QuicClientSession {
+ public:
+ explicit MockQuicClientSession(QuicConnection* connection)
+ : QuicClientSession(
+ DefaultQuicConfig(),
+ connection,
+ QuicServerId("example.com", 80, PRIVACY_MODE_DISABLED),
+ &crypto_config_),
+ crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) {}
+ ~MockQuicClientSession() override {}
+
+ MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id));
+
+ private:
+ QuicCryptoClientConfig crypto_config_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockQuicClientSession);
+};
+
+class QuicSpdyClientStreamTest : public ::testing::Test {
public:
QuicSpdyClientStreamTest()
: connection_(
- new StrictMock<MockConnection>(Perspective::IS_CLIENT,
- SupportedVersions(GetParam()))),
- session_(DefaultQuicConfig(),
- connection_,
- QuicServerId("example.com", 80, false, PRIVACY_MODE_DISABLED),
- &crypto_config_),
+ new StrictMock<MockConnection>(&helper_, Perspective::IS_CLIENT)),
+ session_(connection_),
body_("hello world") {
session_.Initialize();
headers_.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200", "Ok");
headers_.ReplaceOrAppendHeader("content-length", "11");
- headers_string_ = net::tools::SpdyBalsaUtils::SerializeResponseHeaders(
- headers_, GetParam());
+ headers_string_ =
+ net::tools::SpdyBalsaUtils::SerializeResponseHeaders(headers_);
- // New streams rely on having the peer's flow control receive window
- // negotiated in the config.
- session_.config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session_.config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
stream_.reset(new QuicSpdyClientStream(kClientDataStreamId1, &session_));
}
+ MockConnectionHelper helper_;
StrictMock<MockConnection>* connection_;
- QuicCryptoClientConfig crypto_config_;
- QuicClientSession session_;
+ MockQuicClientSession session_;
scoped_ptr<QuicSpdyClientStream> stream_;
BalsaHeaders headers_;
string headers_string_;
string body_;
};
-INSTANTIATE_TEST_CASE_P(Tests, QuicSpdyClientStreamTest,
- ::testing::ValuesIn(QuicSupportedVersions()));
-
-TEST_P(QuicSpdyClientStreamTest, TestFraming) {
+TEST_F(QuicSpdyClientStreamTest, TestFraming) {
stream_->OnStreamHeaders(headers_string_);
stream_->OnStreamHeadersComplete(false, headers_string_.size());
stream_->OnStreamFrame(
QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- if (GetParam() > QUIC_VERSION_24) {
- EXPECT_EQ("200", stream_->headers().find(":status")->second);
- } else {
- EXPECT_EQ("200 Ok", stream_->headers().find(":status")->second);
- }
+ EXPECT_EQ("200", stream_->headers().find(":status")->second);
EXPECT_EQ(200, stream_->response_code());
EXPECT_EQ(body_, stream_->data());
}
-TEST_P(QuicSpdyClientStreamTest, TestFramingOnePacket) {
+TEST_F(QuicSpdyClientStreamTest, TestFramingOnePacket) {
stream_->OnStreamHeaders(headers_string_);
stream_->OnStreamHeadersComplete(false, headers_string_.size());
stream_->OnStreamFrame(
QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- if (GetParam() > QUIC_VERSION_24) {
- EXPECT_EQ("200", stream_->headers().find(":status")->second);
- } else {
- EXPECT_EQ("200 Ok", stream_->headers().find(":status")->second);
- }
+ EXPECT_EQ("200", stream_->headers().find(":status")->second);
EXPECT_EQ(200, stream_->response_code());
EXPECT_EQ(body_, stream_->data());
}
-TEST_P(QuicSpdyClientStreamTest, DISABLED_TestFramingExtraData) {
+TEST_F(QuicSpdyClientStreamTest, DISABLED_TestFramingExtraData) {
string large_body = "hello world!!!!!!";
stream_->OnStreamHeaders(headers_string_);
stream_->OnStreamHeadersComplete(false, headers_string_.size());
// The headers should parse successfully.
EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
- if (GetParam() > QUIC_VERSION_24) {
- EXPECT_EQ("200", stream_->headers().find(":status")->second);
- } else {
- EXPECT_EQ("200 Ok", stream_->headers().find(":status")->second);
- }
+ EXPECT_EQ("200", stream_->headers().find(":status")->second);
EXPECT_EQ(200, stream_->response_code());
EXPECT_CALL(*connection_,
@@ -119,7 +118,7 @@ TEST_P(QuicSpdyClientStreamTest, DISABLED_TestFramingExtraData) {
EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error());
}
-TEST_P(QuicSpdyClientStreamTest, TestNoBidirectionalStreaming) {
+TEST_F(QuicSpdyClientStreamTest, TestNoBidirectionalStreaming) {
QuicStreamFrame frame(kClientDataStreamId1, false, 3, StringPiece("asd"));
EXPECT_FALSE(stream_->write_side_closed());
@@ -127,6 +126,32 @@ TEST_P(QuicSpdyClientStreamTest, TestNoBidirectionalStreaming) {
EXPECT_TRUE(stream_->write_side_closed());
}
+TEST_F(QuicSpdyClientStreamTest, ReceivingTrailers) {
+ // Test that receiving trailing headers, containing a final offset, results in
+ // the stream being closed at that byte offset.
+ FLAGS_quic_supports_trailers = true;
+
+ // Send headers as usual.
+ stream_->OnStreamHeaders(headers_string_);
+ stream_->OnStreamHeadersComplete(false, headers_string_.size());
+
+ // Send trailers before sending the body. Even though a FIN has been received
+ // the stream should not be closed, as it does not yet have all the data bytes
+ // promised by the final offset field.
+ SpdyHeaderBlock trailers;
+ trailers["trailer key"] = "trailer value";
+ trailers[kFinalOffsetHeaderKey] = base::IntToString(body_.size());
+ string trailers_string = SpdyUtils::SerializeUncompressedHeaders(trailers);
+ stream_->OnStreamHeaders(trailers_string);
+ stream_->OnStreamHeadersComplete(true, trailers_string.size());
+
+ // Now send the body, which should close the stream as the FIN has been
+ // received, as well as all data.
+ EXPECT_CALL(session_, CloseStream(stream_->id()));
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
+}
+
} // namespace
} // namespace test
} // namespace tools
diff --git a/chromium/net/tools/quic/quic_spdy_server_stream.cc b/chromium/net/tools/quic/quic_spdy_server_stream.cc
deleted file mode 100644
index 06d065c2227..00000000000
--- a/chromium/net/tools/quic/quic_spdy_server_stream.cc
+++ /dev/null
@@ -1,199 +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/tools/quic/quic_spdy_server_stream.h"
-
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
-#include "net/quic/quic_data_stream.h"
-#include "net/quic/quic_spdy_session.h"
-#include "net/quic/spdy_utils.h"
-#include "net/spdy/spdy_protocol.h"
-#include "net/tools/quic/quic_in_memory_cache.h"
-
-using base::StringPiece;
-using base::StringToInt;
-using std::string;
-
-namespace net {
-namespace tools {
-
-QuicSpdyServerStream::QuicSpdyServerStream(QuicStreamId id,
- QuicSpdySession* session)
- : QuicDataStream(id, session), content_length_(-1) {
-}
-
-QuicSpdyServerStream::~QuicSpdyServerStream() {
-}
-
-void QuicSpdyServerStream::OnStreamHeadersComplete(bool fin, size_t frame_len) {
- QuicDataStream::OnStreamHeadersComplete(fin, frame_len);
- if (!ParseRequestHeaders(decompressed_headers().data(),
- decompressed_headers().length())) {
- // Headers were invalid.
- SendErrorResponse();
- }
- MarkHeadersConsumed(decompressed_headers().length());
-}
-
-void QuicSpdyServerStream::OnDataAvailable() {
- while (HasBytesToRead()) {
- struct iovec iov;
- if (GetReadableRegions(&iov, 1) == 0) {
- // No more data to read.
- break;
- }
- DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream " << id();
- body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
-
- if (content_length_ >= 0 &&
- static_cast<int>(body_.size()) > content_length_) {
- SendErrorResponse();
- return;
- }
- MarkConsumed(iov.iov_len);
- }
- if (!sequencer()->IsClosed()) {
- sequencer()->SetUnblocked();
- return;
- }
-
- // If the sequencer is closed, then the all the body, including the fin,
- // has been consumed.
- OnFinRead();
-
- if (write_side_closed() || fin_buffered()) {
- return;
- }
-
- if (request_headers_.empty()) {
- SendErrorResponse();
- return;
- }
-
- if (content_length_ > 0 &&
- content_length_ != static_cast<int>(body_.size())) {
- SendErrorResponse();
- return;
- }
-
- SendResponse();
-}
-
-bool QuicSpdyServerStream::ParseRequestHeaders(const char* data,
- uint32 data_len) {
- DCHECK(headers_decompressed());
- SpdyFramer framer(HTTP2);
- size_t len = framer.ParseHeaderBlockInBuffer(data,
- data_len,
- &request_headers_);
- DCHECK_LE(len, data_len);
- if (len == 0 || request_headers_.empty()) {
- return false; // Headers were invalid.
- }
-
- if (data_len > len) {
- body_.append(data + len, data_len - len);
- }
- if (ContainsKey(request_headers_, "content-length")) {
- string delimiter;
- delimiter.push_back('\0');
- std::vector<string> values =
- base::SplitString(request_headers_["content-length"], delimiter,
- base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
-
- for (const string& value : values) {
- int new_value;
- if (!StringToInt(value, &new_value) || new_value < 0) {
- return false;
- }
- if (content_length_ < 0) {
- content_length_ = new_value;
- continue;
- }
- if (new_value != content_length_) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-void QuicSpdyServerStream::SendResponse() {
- if (!ContainsKey(request_headers_, GetHostKey()) ||
- !ContainsKey(request_headers_, ":path")) {
- SendErrorResponse();
- return;
- }
-
- // Find response in cache. If not found, send error response.
- const QuicInMemoryCache::Response* response =
- QuicInMemoryCache::GetInstance()->GetResponse(
- request_headers_[GetHostKey()], request_headers_[":path"]);
- if (response == nullptr) {
- SendErrorResponse();
- return;
- }
-
- if (response->response_type() == QuicInMemoryCache::CLOSE_CONNECTION) {
- DVLOG(1) << "Special response: closing connection.";
- CloseConnection(QUIC_NO_ERROR);
- return;
- }
-
- if (response->response_type() == QuicInMemoryCache::IGNORE_REQUEST) {
- DVLOG(1) << "Special response: ignoring request.";
- return;
- }
-
- DVLOG(1) << "Sending response for stream " << id();
- if (version() > QUIC_VERSION_24) {
- SendHeadersAndBody(
- SpdyUtils::ConvertSpdy3ResponseHeadersToSpdy4(response->headers()),
- response->body());
- return;
- }
-
- SendHeadersAndBody(response->headers(), response->body());
-}
-
-void QuicSpdyServerStream::SendErrorResponse() {
- DVLOG(1) << "Sending error response for stream " << id();
- SpdyHeaderBlock headers;
- if (version() <= QUIC_VERSION_24) {
- headers[":version"] = "HTTP/1.1";
- headers[":status"] = "500 Server Error";
- } else {
- headers[":status"] = "500";
- }
- headers["content-length"] = "3";
- SendHeadersAndBody(headers, "bad");
-}
-
-void QuicSpdyServerStream::SendHeadersAndBody(
- const SpdyHeaderBlock& response_headers,
- StringPiece body) {
- // We only support SPDY and HTTP, and neither handles bidirectional streaming.
- if (!read_side_closed()) {
- CloseReadSide();
- }
-
- WriteHeaders(response_headers, body.empty(), nullptr);
-
- if (!body.empty()) {
- WriteOrBufferData(body, true, nullptr);
- }
-}
-
-const string QuicSpdyServerStream::GetHostKey() {
- // SPDY/4 uses ":authority" instead of ":host".
- return version() > QUIC_VERSION_24 ? ":authority" : ":host";
-}
-
-} // namespace tools
-} // namespace net
diff --git a/chromium/net/tools/quic/quic_spdy_server_stream.h b/chromium/net/tools/quic/quic_spdy_server_stream.h
deleted file mode 100644
index d266a6aac2e..00000000000
--- a/chromium/net/tools/quic/quic_spdy_server_stream.h
+++ /dev/null
@@ -1,76 +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_TOOLS_QUIC_QUIC_SPDY_SERVER_STREAM_H_
-#define NET_TOOLS_QUIC_QUIC_SPDY_SERVER_STREAM_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "net/quic/quic_data_stream.h"
-#include "net/quic/quic_protocol.h"
-#include "net/spdy/spdy_framer.h"
-
-namespace net {
-
-class QuicSpdySession;
-
-namespace tools {
-
-namespace test {
-class QuicSpdyServerStreamPeer;
-} // namespace test
-
-// All this does right now is aggregate data, and on fin, send an HTTP
-// response.
-class QuicSpdyServerStream : public QuicDataStream {
- public:
- QuicSpdyServerStream(QuicStreamId id, QuicSpdySession* session);
- ~QuicSpdyServerStream() override;
-
- // QuicDataStream
- void OnStreamHeadersComplete(bool fin, size_t frame_len) override;
-
- // ReliableQuicStream implementation called by the sequencer when there is
- // data (or a FIN) to be read.
- void OnDataAvailable() override;
-
- protected:
- // Sends a basic 200 response using SendHeaders for the headers and WriteData
- // for the body.
- virtual void SendResponse();
-
- void SendHeadersAndBody(const SpdyHeaderBlock& response_headers,
- base::StringPiece body);
-
- SpdyHeaderBlock* request_headers() { return &request_headers_; }
-
- const std::string& body() { return body_; }
-
- private:
- friend class test::QuicSpdyServerStreamPeer;
-
- // Parses the request headers from |data| to |request_headers_|.
- // Returns false if there was an error parsing the headers.
- bool ParseRequestHeaders(const char* data, uint32 data_len);
-
- // Sends a basic 500 response using SendHeaders for the headers and WriteData
- // for the body
- void SendErrorResponse();
-
- // Returns the key for |request_headers_| which identifies the host.
- const std::string GetHostKey();
-
- // The parsed headers received from the client.
- SpdyHeaderBlock request_headers_;
- int content_length_;
- std::string body_;
-
- DISALLOW_COPY_AND_ASSIGN(QuicSpdyServerStream);
-};
-
-} // namespace tools
-} // namespace net
-
-#endif // NET_TOOLS_QUIC_QUIC_SPDY_SERVER_STREAM_H_
diff --git a/chromium/net/tools/quic/quic_spdy_server_stream_test.cc b/chromium/net/tools/quic/quic_spdy_server_stream_test.cc
deleted file mode 100644
index 0a128e18042..00000000000
--- a/chromium/net/tools/quic/quic_spdy_server_stream_test.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright (c) 2013 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/tools/quic/quic_spdy_server_stream.h"
-
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "net/quic/quic_connection.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_utils.h"
-#include "net/quic/spdy_utils.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/tools/epoll_server/epoll_server.h"
-#include "net/tools/quic/quic_in_memory_cache.h"
-#include "net/tools/quic/spdy_balsa_utils.h"
-#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::StringPiece;
-using net::test::MockConnection;
-using net::test::MockQuicSpdySession;
-using net::test::SupportedVersions;
-using net::test::kInitialSessionFlowControlWindowForTest;
-using net::test::kInitialStreamFlowControlWindowForTest;
-using std::string;
-using testing::_;
-using testing::AnyNumber;
-using testing::Invoke;
-using testing::InvokeArgument;
-using testing::InSequence;
-using testing::Return;
-using testing::StrictMock;
-using testing::WithArgs;
-
-namespace net {
-namespace tools {
-namespace test {
-
-class QuicSpdyServerStreamPeer : public QuicSpdyServerStream {
- public:
- QuicSpdyServerStreamPeer(QuicStreamId stream_id, QuicSpdySession* session)
- : QuicSpdyServerStream(stream_id, session) {}
-
- using QuicSpdyServerStream::SendResponse;
- using QuicSpdyServerStream::SendErrorResponse;
-
- SpdyHeaderBlock* mutable_headers() {
- return &request_headers_;
- }
-
- static void SendResponse(QuicSpdyServerStream* stream) {
- stream->SendResponse();
- }
-
- static void SendErrorResponse(QuicSpdyServerStream* stream) {
- stream->SendResponse();
- }
-
- static const string& body(QuicSpdyServerStream* stream) {
- return stream->body_;
- }
-
- static const int content_length(QuicSpdyServerStream* stream) {
- return stream->content_length_;
- }
-
- static const SpdyHeaderBlock& headers(QuicSpdyServerStream* stream) {
- return stream->request_headers_;
- }
-};
-
-namespace {
-
-class QuicSpdyServerStreamTest : public ::testing::TestWithParam<QuicVersion> {
- public:
- QuicSpdyServerStreamTest()
- : connection_(
- new StrictMock<MockConnection>(Perspective::IS_SERVER,
- SupportedVersions(GetParam()))),
- session_(connection_),
- body_("hello world") {
- SpdyHeaderBlock request_headers;
- request_headers[":host"] = "";
- request_headers[":path"] = "/";
- request_headers[":method"] = "POST";
- request_headers[":version"] = "HTTP/1.1";
- request_headers["content-length"] = "11";
-
- headers_string_ = net::SpdyUtils::SerializeUncompressedHeaders(
- request_headers, GetParam());
-
- // New streams rely on having the peer's flow control receive window
- // negotiated in the config.
- session_.config()->SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- session_.config()->SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- stream_.reset(new QuicSpdyServerStreamPeer(3, &session_));
-
- QuicInMemoryCachePeer::ResetForTests();
-
- string host = "";
- string path = "/foo";
- SpdyHeaderBlock response_headers;
- StringPiece body("Yum");
- QuicInMemoryCache::GetInstance()->AddResponse(host, path, response_headers,
- body);
- }
-
- ~QuicSpdyServerStreamTest() override {
- QuicInMemoryCachePeer::ResetForTests();
- }
-
- const string& StreamBody() {
- return QuicSpdyServerStreamPeer::body(stream_.get());
- }
-
- StringPiece StreamHeadersValue(const string& key) {
- return (*stream_->mutable_headers())[key];
- }
-
- SpdyHeaderBlock response_headers_;
- StrictMock<MockConnection>* connection_;
- StrictMock<MockQuicSpdySession> session_;
- scoped_ptr<QuicSpdyServerStreamPeer> stream_;
- string headers_string_;
- string body_;
-};
-
-QuicConsumedData ConsumeAllData(
- QuicStreamId id,
- const QuicIOVector& data,
- QuicStreamOffset offset,
- bool fin,
- FecProtection /*fec_protection_*/,
- QuicAckNotifier::DelegateInterface* /*ack_notifier_delegate*/) {
- return QuicConsumedData(data.total_length, fin);
-}
-
-INSTANTIATE_TEST_CASE_P(Tests, QuicSpdyServerStreamTest,
- ::testing::ValuesIn(QuicSupportedVersions()));
-
-TEST_P(QuicSpdyServerStreamTest, TestFraming) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber()).
- WillRepeatedly(Invoke(ConsumeAllData));
- stream_->OnStreamHeaders(headers_string_);
- stream_->OnStreamHeadersComplete(false, headers_string_.size());
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
- EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSpdyServerStreamTest, TestFramingOnePacket) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber()).
- WillRepeatedly(Invoke(ConsumeAllData));
-
- stream_->OnStreamHeaders(headers_string_);
- stream_->OnStreamHeadersComplete(false, headers_string_.size());
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
- EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSpdyServerStreamTest, TestFramingExtraData) {
- string large_body = "hello world!!!!!!";
-
- // We'll automatically write out an error (headers + body)
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber()).
- WillRepeatedly(Invoke(ConsumeAllData));
-
- stream_->OnStreamHeaders(headers_string_);
- stream_->OnStreamHeadersComplete(false, headers_string_.size());
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
- // Content length is still 11. This will register as an error and we won't
- // accept the bytes.
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, body_.size(), large_body));
- EXPECT_EQ("11", StreamHeadersValue("content-length"));
- EXPECT_EQ("/", StreamHeadersValue(":path"));
- EXPECT_EQ("POST", StreamHeadersValue(":method"));
-}
-
-TEST_P(QuicSpdyServerStreamTest, TestSendResponse) {
- SpdyHeaderBlock* request_headers = stream_->mutable_headers();
- (*request_headers)[":path"] = "/foo";
- (*request_headers)[":host"] = "";
- (*request_headers)[":version"] = "HTTP/1.1";
- (*request_headers)[":method"] = "GET";
-
- response_headers_[":version"] = "HTTP/1.1";
- response_headers_[":status"] = "200 OK";
- response_headers_["content-length"] = "3";
-
- InSequence s;
- EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, 0, false, _, nullptr));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(1).
- WillOnce(Return(QuicConsumedData(3, true)));
-
- QuicSpdyServerStreamPeer::SendResponse(stream_.get());
- EXPECT_TRUE(stream_->read_side_closed());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSpdyServerStreamTest, TestSendErrorResponse) {
- response_headers_[":version"] = "HTTP/1.1";
- response_headers_[":status"] = "500 Server Error";
- response_headers_["content-length"] = "3";
-
- InSequence s;
- EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, 0, false, _, nullptr));
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(1).
- WillOnce(Return(QuicConsumedData(3, true)));
-
- QuicSpdyServerStreamPeer::SendErrorResponse(stream_.get());
- EXPECT_TRUE(stream_->read_side_closed());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSpdyServerStreamTest, InvalidMultipleContentLength) {
- SpdyHeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- request_headers["content-length"] = StringPiece("11\00012", 5);
-
- headers_string_ =
- SpdyUtils::SerializeUncompressedHeaders(request_headers, GetParam());
-
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(ConsumeAllData));
-
- stream_->OnStreamHeaders(headers_string_);
- stream_->OnStreamHeadersComplete(false, headers_string_.size());
-
- EXPECT_TRUE(stream_->read_side_closed());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSpdyServerStreamTest, InvalidLeadingNullContentLength) {
- SpdyHeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- request_headers["content-length"] = StringPiece("\00012", 3);
-
- headers_string_ =
- SpdyUtils::SerializeUncompressedHeaders(request_headers, GetParam());
-
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .Times(AnyNumber())
- .WillRepeatedly(Invoke(ConsumeAllData));
-
- stream_->OnStreamHeaders(headers_string_);
- stream_->OnStreamHeadersComplete(false, headers_string_.size());
-
- EXPECT_TRUE(stream_->read_side_closed());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSpdyServerStreamTest, ValidMultipleContentLength) {
- SpdyHeaderBlock request_headers;
- // \000 is a way to write the null byte when followed by a literal digit.
- request_headers["content-length"] = StringPiece("11\00011", 5);
-
- headers_string_ =
- SpdyUtils::SerializeUncompressedHeaders(request_headers, GetParam());
-
- stream_->OnStreamHeaders(headers_string_);
- stream_->OnStreamHeadersComplete(false, headers_string_.size());
-
- EXPECT_EQ(11, QuicSpdyServerStreamPeer::content_length(stream_.get()));
- EXPECT_FALSE(stream_->read_side_closed());
- EXPECT_FALSE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSpdyServerStreamTest, InvalidHeadersWithFin) {
- char arr[] = {
- 0x3a, 0x68, 0x6f, 0x73, // :hos
- 0x74, 0x00, 0x00, 0x00, // t...
- 0x00, 0x00, 0x00, 0x00, // ....
- 0x07, 0x3a, 0x6d, 0x65, // .:me
- 0x74, 0x68, 0x6f, 0x64, // thod
- 0x00, 0x00, 0x00, 0x03, // ....
- 0x47, 0x45, 0x54, 0x00, // GET.
- 0x00, 0x00, 0x05, 0x3a, // ...:
- 0x70, 0x61, 0x74, 0x68, // path
- 0x00, 0x00, 0x00, 0x04, // ....
- 0x2f, 0x66, 0x6f, 0x6f, // /foo
- 0x00, 0x00, 0x00, 0x07, // ....
- 0x3a, 0x73, 0x63, 0x68, // :sch
- 0x65, 0x6d, 0x65, 0x00, // eme.
- 0x00, 0x00, 0x00, 0x00, // ....
- 0x00, 0x00, 0x08, 0x3a, // ...:
- 0x76, 0x65, 0x72, 0x73, // vers
- '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on.
- 0x00, 0x00, 0x08, 0x48, // ...H
- 0x54, 0x54, 0x50, 0x2f, // TTP/
- 0x31, 0x2e, 0x31, // 1.1
- };
- StringPiece data(arr, arraysize(arr));
- QuicStreamFrame frame(stream_->id(), true, 0, data);
- // Verify that we don't crash when we get a invalid headers in stream frame.
- stream_->OnStreamFrame(frame);
-}
-
-} // namespace
-} // namespace test
-} // namespace tools
-} // namespace net
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 68d1b9ec394..9472e736aaa 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.cc
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager.cc
@@ -7,6 +7,7 @@
#include <errno.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "net/base/ip_endpoint.h"
@@ -18,7 +19,7 @@
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_utils.h"
-#include "net/tools/quic/quic_server_session.h"
+#include "net/tools/quic/quic_server_session_base.h"
using base::StringPiece;
@@ -32,8 +33,7 @@ class ConnectionIdCleanUpAlarm : public QuicAlarm::Delegate {
public:
explicit ConnectionIdCleanUpAlarm(
QuicTimeWaitListManager* time_wait_list_manager)
- : time_wait_list_manager_(time_wait_list_manager) {
- }
+ : time_wait_list_manager_(time_wait_list_manager) {}
QuicTime OnAlarm() override {
time_wait_list_manager_->CleanUpOldConnectionIds();
@@ -62,8 +62,7 @@ class QuicTimeWaitListManager::QueuedPacket {
QuicEncryptedPacket* packet)
: server_address_(server_address),
client_address_(client_address),
- packet_(packet) {
- }
+ packet_(packet) {}
const IPEndPoint& server_address() const { return server_address_; }
const IPEndPoint& client_address() const { return client_address_; }
@@ -80,8 +79,7 @@ class QuicTimeWaitListManager::QueuedPacket {
QuicTimeWaitListManager::QuicTimeWaitListManager(
QuicPacketWriter* writer,
QuicServerSessionVisitor* visitor,
- QuicConnectionHelperInterface* helper,
- const QuicVersionVector& supported_versions)
+ QuicConnectionHelperInterface* helper)
: time_wait_period_(
QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)),
connection_id_clean_up_alarm_(
@@ -96,9 +94,8 @@ QuicTimeWaitListManager::~QuicTimeWaitListManager() {
connection_id_clean_up_alarm_->Cancel();
STLDeleteElements(&pending_packets_queue_);
for (ConnectionIdMap::iterator it = connection_id_map_.begin();
- it != connection_id_map_.end();
- ++it) {
- delete it->second.close_packet;
+ it != connection_id_map_.end(); ++it) {
+ STLDeleteElements(&it->second.termination_packets);
}
}
@@ -106,23 +103,28 @@ void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
QuicVersion version,
bool connection_rejected_statelessly,
- QuicEncryptedPacket* close_packet) {
- DCHECK(!connection_rejected_statelessly || !close_packet)
- << "Connections that were rejected statelessly should not "
- << "have a close packet. connection_id = " << connection_id;
+ std::vector<QuicEncryptedPacket*>* termination_packets) {
+ if (connection_rejected_statelessly) {
+ DCHECK(termination_packets != nullptr && !termination_packets->empty())
+ << "Connections that were rejected statelessly must "
+ << "have a close packet. connection_id = " << connection_id;
+ }
int num_packets = 0;
ConnectionIdMap::iterator it = connection_id_map_.find(connection_id);
const bool new_connection_id = it == connection_id_map_.end();
if (!new_connection_id) { // Replace record if it is reinserted.
num_packets = it->second.num_packets;
- delete it->second.close_packet;
+ STLDeleteElements(&it->second.termination_packets);
connection_id_map_.erase(it);
}
TrimTimeWaitListIfNeeded();
DCHECK_LT(num_connections(),
static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections));
ConnectionIdData data(num_packets, version, clock_->ApproximateNow(),
- close_packet, connection_rejected_statelessly);
+ connection_rejected_statelessly);
+ if (termination_packets != nullptr) {
+ data.termination_packets.swap(*termination_packets);
+ }
connection_id_map_.insert(std::make_pair(connection_id, data));
if (new_connection_id) {
visitor_->OnConnectionAddedToTimeWaitList(connection_id);
@@ -167,21 +169,26 @@ void QuicTimeWaitListManager::ProcessPacket(
// Increment the received packet count.
ConnectionIdData* connection_data = &it->second;
++(connection_data->num_packets);
+
if (!ShouldSendResponse(connection_data->num_packets)) {
return;
}
- if (connection_data->close_packet) {
- QueuedPacket* queued_packet = new QueuedPacket(
- server_address, client_address, connection_data->close_packet->Clone());
- // Takes ownership of the packet.
- SendOrQueuePacket(queued_packet);
- } else if (!connection_data->connection_rejected_statelessly) {
- SendPublicReset(server_address, client_address, connection_id,
- packet_number);
- } else {
- DVLOG(3) << "Time wait list not sending response for connection "
- << connection_id << " due to previous stateless reject.";
+
+ if (!connection_data->termination_packets.empty()) {
+ if (connection_data->connection_rejected_statelessly) {
+ DVLOG(3) << "Time wait list sending previous stateless reject response "
+ << "for connection " << connection_id;
+ }
+ for (QuicEncryptedPacket* packet : connection_data->termination_packets) {
+ QueuedPacket* queued_packet =
+ new QueuedPacket(server_address, client_address, packet->Clone());
+ // Takes ownership of the packet.
+ SendOrQueuePacket(queued_packet);
+ }
+ return;
}
+
+ SendPublicReset(server_address, client_address, connection_id, packet_number);
}
// Returns true if the number of packets received for this connection_id is a
@@ -204,10 +211,8 @@ void QuicTimeWaitListManager::SendPublicReset(
// TODO(satyamshekhar): generate a valid nonce for this connection_id.
packet.nonce_proof = 1010101;
packet.client_address = client_address;
- QueuedPacket* queued_packet = new QueuedPacket(
- server_address,
- client_address,
- BuildPublicReset(packet));
+ QueuedPacket* queued_packet = new QueuedPacket(server_address, client_address,
+ BuildPublicReset(packet));
// Takes ownership of the packet.
SendOrQueuePacket(queued_packet);
}
@@ -234,8 +239,7 @@ bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) {
return false;
}
WriteResult result = writer_->WritePacket(
- queued_packet->packet()->data(),
- queued_packet->packet()->length(),
+ queued_packet->packet()->data(), queued_packet->packet()->length(),
queued_packet->server_address().address(),
queued_packet->client_address());
if (result.status == WRITE_STATUS_BLOCKED) {
@@ -286,7 +290,7 @@ bool QuicTimeWaitListManager::MaybeExpireOldestConnection(
}
// This connection_id has lived its age, retire it now.
const QuicConnectionId connection_id = it->first;
- delete it->second.close_packet;
+ STLDeleteElements(&it->second.termination_packets);
connection_id_map_.erase(it);
visitor_->OnConnectionRemovedFromTimeWaitList(connection_id);
return true;
@@ -312,5 +316,17 @@ void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
}
}
+QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
+ int num_packets_,
+ QuicVersion version_,
+ QuicTime time_added_,
+ bool connection_rejected_statelessly)
+ : num_packets(num_packets_),
+ version(version_),
+ time_added(time_added_),
+ connection_rejected_statelessly(connection_rejected_statelessly) {}
+
+QuicTimeWaitListManager::ConnectionIdData::~ConnectionIdData() {}
+
} // namespace tools
} // namespace net
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 9a9eccd5e78..777ab0eb691 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.h
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager.h
@@ -9,9 +9,11 @@
#ifndef NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_
#define NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_
+#include <stddef.h>
+
#include <deque>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/linked_hash_map.h"
#include "net/quic/quic_blocked_writer_interface.h"
#include "net/quic/quic_connection.h"
@@ -44,28 +46,22 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
// helper - used to run clean up alarms. (Owned by the dispatcher)
QuicTimeWaitListManager(QuicPacketWriter* writer,
QuicServerSessionVisitor* visitor,
- QuicConnectionHelperInterface* helper,
- const QuicVersionVector& supported_versions);
+ QuicConnectionHelperInterface* helper);
~QuicTimeWaitListManager() override;
// Adds the given connection_id to time wait state for time_wait_period_.
- // Henceforth, any packet bearing this connection_id should not be processed
- // while the connection_id remains in this list. If a non-nullptr
- // |close_packet| is provided, the TimeWaitListManager takes ownership of it
- // and sends it again when packets are received for added connection_ids. If
- // nullptr, a public reset packet is sent with the specified |version|.
- // DCHECKs that connection_id is not already on the list. "virtual" to
- // override in tests. If "connection_rejected_statelessly" is true, it means
- // that the connection was closed due to a stateless reject, and no close
- // packet is expected. Any packets that are received for connection_id will
- // be black-holed.
- // TODO(jokulik): In the future, we plan send (redundant) SREJ packets back to
- // the client in response to stray data-packets that arrive after the first
- // SREJ. This requires some new plumbing, so we black-hole for now.
- virtual void AddConnectionIdToTimeWait(QuicConnectionId connection_id,
- QuicVersion version,
- bool connection_rejected_statelessly,
- QuicEncryptedPacket* close_packet);
+ // If |termination_packets| are provided, copies of these packets will be sent
+ // when a packet with this connection ID is processed. If no termination
+ // packets are provided, then a PUBLIC_RESET will be sent with the specified
+ // |version|. Any termination packets will be move from |termination_packets|
+ // and will become owned by the manager. If |connection_rejected_statelessly|
+ // is true, it means that the connection was closed due to a stateless reject,
+ // and termination packets are expected.
+ virtual void AddConnectionIdToTimeWait(
+ QuicConnectionId connection_id,
+ QuicVersion version,
+ bool connection_rejected_statelessly,
+ std::vector<QuicEncryptedPacket*>* termination_packets);
// Returns true if the connection_id is in time wait state, false otherwise.
// Packets received for this connection_id should not lead to creation of new
@@ -152,17 +148,15 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
ConnectionIdData(int num_packets_,
QuicVersion version_,
QuicTime time_added_,
- QuicEncryptedPacket* close_packet,
- bool connection_rejected_statelessly)
- : num_packets(num_packets_),
- version(version_),
- time_added(time_added_),
- close_packet(close_packet),
- connection_rejected_statelessly(connection_rejected_statelessly) {}
+ bool connection_rejected_statelessly);
+
+ ~ConnectionIdData();
+
int num_packets;
QuicVersion version;
QuicTime time_added;
- QuicEncryptedPacket* close_packet;
+ // These packets may contain CONNECTION_CLOSE frames, or SREJ messages.
+ std::vector<QuicEncryptedPacket*> termination_packets;
bool connection_rejected_statelessly;
};
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 e6baf7dbc22..a1c7b6008aa 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
@@ -10,7 +10,7 @@
#include "net/quic/crypto/null_encrypter.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
-#include "net/quic/quic_connection_helper.h"
+#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_data_reader.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_framer.h"
@@ -88,21 +88,15 @@ namespace {
class MockFakeTimeEpollServer : public FakeTimeEpollServer {
public:
- MOCK_METHOD2(RegisterAlarm, void(int64 timeout_in_us,
- EpollAlarmCallbackInterface* alarm));
+ MOCK_METHOD2(RegisterAlarm,
+ void(int64_t timeout_in_us, EpollAlarmCallbackInterface* alarm));
};
class QuicTimeWaitListManagerTest : public ::testing::Test {
protected:
QuicTimeWaitListManagerTest()
: helper_(&epoll_server_),
- time_wait_list_manager_(&writer_,
- &visitor_,
- &helper_,
- QuicSupportedVersions()),
- framer_(QuicSupportedVersions(),
- QuicTime::Zero(),
- Perspective::IS_SERVER),
+ time_wait_list_manager_(&writer_, &visitor_, &helper_),
connection_id_(45),
client_address_(net::test::TestPeerIPAddress(), kTestPort),
writer_is_blocked_(false) {}
@@ -122,17 +116,19 @@ class QuicTimeWaitListManagerTest : public ::testing::Test {
}
void AddStatelessConnectionId(QuicConnectionId connection_id) {
+ std::vector<QuicEncryptedPacket*> termination_packets;
+ termination_packets.push_back(new QuicEncryptedPacket(nullptr, 0, false));
time_wait_list_manager_.AddConnectionIdToTimeWait(
connection_id, QuicVersionMax(),
- /*connection_rejected_statelessly=*/true, nullptr);
+ /*connection_rejected_statelessly=*/true, &termination_packets);
}
void AddConnectionId(QuicConnectionId connection_id,
QuicVersion version,
bool connection_rejected_statelessly,
- QuicEncryptedPacket* packet) {
+ std::vector<QuicEncryptedPacket*>* packets) {
time_wait_list_manager_.AddConnectionIdToTimeWait(
- connection_id, version, connection_rejected_statelessly, packet);
+ connection_id, version, connection_rejected_statelessly, packets);
}
bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
@@ -147,33 +143,10 @@ class QuicTimeWaitListManagerTest : public ::testing::Test {
}
QuicEncryptedPacket* ConstructEncryptedPacket(
- EncryptionLevel level,
QuicConnectionId connection_id,
QuicPacketNumber packet_number) {
- QuicPacketHeader header;
- header.public_header.connection_id = connection_id;
- header.public_header.connection_id_length = PACKET_8BYTE_CONNECTION_ID;
- header.public_header.version_flag = false;
- header.public_header.reset_flag = false;
- header.public_header.packet_number_length = PACKET_6BYTE_PACKET_NUMBER;
- header.packet_packet_number = packet_number;
- header.entropy_flag = false;
- header.entropy_hash = 0;
- header.fec_flag = false;
- header.is_in_fec_group = NOT_IN_FEC_GROUP;
- header.fec_group = 0;
- QuicStreamFrame stream_frame(1, false, 0, StringPiece("data"));
- QuicFrame frame(&stream_frame);
- QuicFrames frames;
- frames.push_back(frame);
- scoped_ptr<QuicPacket> packet(
- BuildUnsizedDataPacket(&framer_, header, frames));
- EXPECT_TRUE(packet != nullptr);
- char buffer[kMaxPacketSize];
- scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
- ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize));
- EXPECT_TRUE(encrypted != nullptr);
- return encrypted->Clone();
+ return net::test::ConstructEncryptedPacket(connection_id, false, false,
+ packet_number, "data");
}
NiceMock<MockFakeTimeEpollServer> epoll_server_;
@@ -181,7 +154,6 @@ class QuicTimeWaitListManagerTest : public ::testing::Test {
StrictMock<MockPacketWriter> writer_;
StrictMock<MockQuicServerSessionVisitor> visitor_;
QuicTimeWaitListManager time_wait_list_manager_;
- QuicFramer framer_;
QuicConnectionId connection_id_;
IPEndPoint server_address_;
IPEndPoint client_address_;
@@ -189,7 +161,7 @@ class QuicTimeWaitListManagerTest : public ::testing::Test {
};
class ValidatePublicResetPacketPredicate
- : public MatcherInterface<const std::tr1::tuple<const char*, int> > {
+ : public MatcherInterface<const std::tr1::tuple<const char*, int>> {
public:
explicit ValidatePublicResetPacketPredicate(QuicConnectionId connection_id,
QuicPacketNumber number)
@@ -249,28 +221,48 @@ TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
const size_t kConnectionCloseLength = 100;
EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+ std::vector<QuicEncryptedPacket*> termination_packets;
+ termination_packets.push_back(new QuicEncryptedPacket(
+ new char[kConnectionCloseLength], kConnectionCloseLength, true));
AddConnectionId(connection_id_, QuicVersionMax(),
/*connection_rejected_statelessly=*/false,
- new QuicEncryptedPacket(new char[kConnectionCloseLength],
- kConnectionCloseLength, true));
+ &termination_packets);
const int kRandomSequenceNumber = 1;
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- server_address_.address(),
- client_address_))
+ server_address_.address(), client_address_))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
ProcessPacket(connection_id_, kRandomSequenceNumber);
}
+TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) {
+ const size_t kConnectionCloseLength = 100;
+ EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+ std::vector<QuicEncryptedPacket*> termination_packets;
+ termination_packets.push_back(new QuicEncryptedPacket(
+ new char[kConnectionCloseLength], kConnectionCloseLength, true));
+ termination_packets.push_back(new QuicEncryptedPacket(
+ new char[kConnectionCloseLength], kConnectionCloseLength, true));
+ AddConnectionId(connection_id_, QuicVersionMax(),
+ /*connection_rejected_statelessly=*/false,
+ &termination_packets);
+ const int kRandomSequenceNumber = 1;
+ EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+ server_address_.address(), client_address_))
+ .Times(2)
+ .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+ ProcessPacket(connection_id_, kRandomSequenceNumber);
+}
+
TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
AddConnectionId(connection_id_);
const int kRandomSequenceNumber = 1;
- EXPECT_CALL(writer_, WritePacket(_, _,
- server_address_.address(),
- client_address_))
- .With(Args<0, 1>(PublicResetPacketEq(connection_id_,
- kRandomSequenceNumber)))
+ EXPECT_CALL(writer_,
+ WritePacket(_, _, server_address_.address(), client_address_))
+ .With(Args<0, 1>(
+ PublicResetPacketEq(connection_id_, kRandomSequenceNumber)))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
ProcessPacket(connection_id_, kRandomSequenceNumber);
@@ -301,6 +293,11 @@ TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
AddStatelessConnectionId(connection_id_);
const int kRandomSequenceNumber = 1;
+
+ EXPECT_CALL(writer_,
+ WritePacket(_, _, server_address_.address(), client_address_))
+ .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
ProcessPacket(connection_id_, kRandomSequenceNumber);
}
@@ -334,8 +331,8 @@ TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
epoll_server_.set_now_in_usec(time_wait_period.Add(offset).ToMicroseconds());
// After all the old connection_ids are cleaned up, check the next alarm
// interval.
- int64 next_alarm_time = epoll_server_.ApproximateNowInUsec() +
- time_wait_period.Subtract(offset).ToMicroseconds();
+ int64_t next_alarm_time = epoll_server_.ApproximateNowInUsec() +
+ time_wait_period.Subtract(offset).ToMicroseconds();
EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _));
for (size_t connection_id = 1; connection_id <= kConnectionIdCount;
@@ -350,7 +347,7 @@ TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
EXPECT_EQ(connection_id > kOldConnectionIdCount,
IsConnectionIdInTimeWait(connection_id))
<< "kOldConnectionIdCount: " << kOldConnectionIdCount
- << " connection_id: " << connection_id;
+ << " connection_id: " << connection_id;
}
EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
time_wait_list_manager_.num_connections());
@@ -362,7 +359,7 @@ TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
AddConnectionId(connection_id);
QuicPacketNumber packet_number = 234;
scoped_ptr<QuicEncryptedPacket> packet(
- ConstructEncryptedPacket(ENCRYPTION_NONE, connection_id, packet_number));
+ ConstructEncryptedPacket(connection_id, packet_number));
// Let first write through.
EXPECT_CALL(writer_,
WritePacket(_, _, server_address_.address(), client_address_))
@@ -387,10 +384,9 @@ TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
AddConnectionId(other_connection_id);
QuicPacketNumber other_packet_number = 23423;
- scoped_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
- ENCRYPTION_NONE, other_connection_id, other_packet_number));
- EXPECT_CALL(writer_, WritePacket(_, _, _, _))
- .Times(0);
+ scoped_ptr<QuicEncryptedPacket> other_packet(
+ ConstructEncryptedPacket(other_connection_id, other_packet_number));
+ EXPECT_CALL(writer_, WritePacket(_, _, _, _)).Times(0);
EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
ProcessPacket(other_connection_id, other_packet_number);
EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
@@ -442,17 +438,17 @@ TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
AddConnectionId(connection_id_);
EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
const size_t kConnectionCloseLength = 100;
+ std::vector<QuicEncryptedPacket*> termination_packets;
+ termination_packets.push_back(new QuicEncryptedPacket(
+ new char[kConnectionCloseLength], kConnectionCloseLength, true));
AddConnectionId(connection_id_, QuicVersionMax(),
/*connection_rejected_statelessly=*/false,
- new QuicEncryptedPacket(new char[kConnectionCloseLength],
- kConnectionCloseLength, true));
+ &termination_packets);
EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
- EXPECT_CALL(writer_, WritePacket(_,
- kConnectionCloseLength,
- server_address_.address(),
- client_address_))
+ EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+ server_address_.address(), client_address_))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
const int kRandomSequenceNumber = 1;
@@ -465,8 +461,8 @@ TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
// Now set the current time as time_wait_period + offset usecs.
epoll_server_.set_now_in_usec(time_wait_period.Add(offset).ToMicroseconds());
// After the connection_ids are cleaned up, check the next alarm interval.
- int64 next_alarm_time = epoll_server_.ApproximateNowInUsec() +
- time_wait_period.ToMicroseconds();
+ int64_t next_alarm_time =
+ epoll_server_.ApproximateNowInUsec() + time_wait_period.ToMicroseconds();
EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _));
EXPECT_CALL(visitor_, OnConnectionRemovedFromTimeWaitList(connection_id_));
@@ -514,7 +510,7 @@ TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
QuicConnectionId current_connection_id = 0;
// Add exactly the maximum number of connections
- for (int64 i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
+ for (int64_t i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
++current_connection_id;
EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
EXPECT_CALL(visitor_,
@@ -526,7 +522,7 @@ TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
// Now keep adding. Since we're already at the max, every new connection-id
// will evict the oldest one.
- for (int64 i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
+ for (int64_t i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
++current_connection_id;
const QuicConnectionId id_to_evict =
current_connection_id - FLAGS_quic_time_wait_list_max_connections;
diff --git a/chromium/net/tools/quic/spdy_balsa_utils.cc b/chromium/net/tools/quic/spdy_balsa_utils.cc
index fd72a06230a..b298e38c79d 100644
--- a/chromium/net/tools/quic/spdy_balsa_utils.cc
+++ b/chromium/net/tools/quic/spdy_balsa_utils.cc
@@ -76,31 +76,6 @@ void PopulateSpdyHeaderBlock(const BalsaHeaders& headers,
}
}
-void PopulateSpdy3RequestHeaderBlock(const BalsaHeaders& headers,
- const string& scheme,
- const string& host_and_port,
- const string& path,
- SpdyHeaderBlock* block) {
- PopulateSpdyHeaderBlock(headers, block, true);
- StringPiece host_header = headers.GetHeader("Host");
- if (!host_header.empty()) {
- DCHECK(host_and_port.empty() || host_header == host_and_port);
- block->insert(make_pair(kV3Host, host_header));
- } else {
- block->insert(make_pair(kV3Host, host_and_port));
- }
- block->insert(make_pair(kV3Path, path));
- block->insert(make_pair(kV3Scheme, scheme));
-
- if (!headers.request_method().empty()) {
- block->insert(make_pair(kV3Method, headers.request_method()));
- }
-
- if (!headers.request_version().empty()) {
- (*block)[kV3Version] = headers.request_version();
- }
-}
-
void PopulateSpdy4RequestHeaderBlock(const BalsaHeaders& headers,
const string& scheme,
const string& host_and_port,
@@ -150,67 +125,32 @@ bool IsSpecialSpdyHeader(SpdyHeaderBlock::const_iterator header,
// The reason phrase should match regexp [\d\d\d [^\r\n]+]. If not, we will
// fail to parse it.
bool ParseReasonAndStatus(StringPiece status_and_reason,
- BalsaHeaders* headers,
- QuicVersion quic_version) {
- if (quic_version > QUIC_VERSION_24) {
- int status;
- if (!base::StringToInt(status_and_reason, &status)) {
- return false;
- }
- headers->SetResponseCode(status_and_reason);
- headers->SetResponseCode(status_and_reason);
- headers->set_parsed_response_code(status);
- return true;
- }
-
- if (status_and_reason.size() < 5)
- return false;
-
- if (status_and_reason[3] != ' ')
- return false;
-
- const StringPiece status_str = StringPiece(status_and_reason.data(), 3);
+ BalsaHeaders* headers) {
int status;
- if (!base::StringToInt(status_str, &status)) {
+ if (!base::StringToInt(status_and_reason, &status)) {
return false;
}
-
- headers->SetResponseCode(status_str);
+ headers->SetResponseCode(status_and_reason);
+ headers->SetResponseCode(status_and_reason);
headers->set_parsed_response_code(status);
-
- StringPiece reason(status_and_reason.data() + 4,
- status_and_reason.length() - 4);
-
- headers->SetResponseReasonPhrase(reason);
return true;
}
// static
void SpdyHeadersToResponseHeaders(const SpdyHeaderBlock& header_block,
- BalsaHeaders* request_headers,
- QuicVersion quic_version) {
+ BalsaHeaders* request_headers) {
typedef SpdyHeaderBlock::const_iterator BlockIt;
BlockIt status_it = header_block.find(kV3Status);
- BlockIt version_it = header_block.find(kV3Version);
BlockIt end_it = header_block.end();
- if (quic_version > QUIC_VERSION_24) {
- if (status_it == end_it) {
- return;
- }
- } else {
- if (status_it == end_it || version_it == end_it) {
- return;
- }
+ if (status_it == end_it) {
+ return;
}
- if (!ParseReasonAndStatus(status_it->second, request_headers, quic_version)) {
+ if (!ParseReasonAndStatus(status_it->second, request_headers)) {
return;
}
- if (quic_version <= QUIC_VERSION_24) {
- request_headers->SetResponseVersion(version_it->second);
- }
for (BlockIt it = header_block.begin(); it != header_block.end(); ++it) {
if (!IsSpecialSpdyHeader(it, request_headers)) {
request_headers->AppendHeader(it->first, it->second);
@@ -220,8 +160,7 @@ void SpdyHeadersToResponseHeaders(const SpdyHeaderBlock& header_block,
// static
void SpdyHeadersToRequestHeaders(const SpdyHeaderBlock& header_block,
- BalsaHeaders* request_headers,
- QuicVersion quic_version) {
+ BalsaHeaders* request_headers) {
typedef SpdyHeaderBlock::const_iterator BlockIt;
BlockIt authority_it = header_block.find(kV4Host);
@@ -267,21 +206,19 @@ void SpdyHeadersToRequestHeaders(const SpdyHeaderBlock& header_block,
// static
void SpdyHeadersToBalsaHeaders(const SpdyHeaderBlock& block,
BalsaHeaders* headers,
- QuicVersion quic_version,
SpdyHeaderValidatorType type) {
if (type == SpdyHeaderValidatorType::RESPONSE_HEADER) {
- SpdyHeadersToResponseHeaders(block, headers, quic_version);
+ SpdyHeadersToResponseHeaders(block, headers);
return;
}
- SpdyHeadersToRequestHeaders(block, headers, quic_version);
+ SpdyHeadersToRequestHeaders(block, headers);
}
} // namespace
// static
SpdyHeaderBlock SpdyBalsaUtils::RequestHeadersToSpdyHeaders(
- const BalsaHeaders& request_headers,
- QuicVersion quic_version) {
+ const BalsaHeaders& request_headers) {
string scheme;
string host_and_port;
string path;
@@ -308,51 +245,38 @@ SpdyHeaderBlock SpdyBalsaUtils::RequestHeadersToSpdyHeaders(
DCHECK(!path.empty());
SpdyHeaderBlock block;
- if (net::SpdyUtils::GetSpdyVersionForQuicVersion(quic_version) == SPDY3) {
- PopulateSpdy3RequestHeaderBlock(request_headers, scheme, host_and_port,
- path, &block);
- } else {
- PopulateSpdy4RequestHeaderBlock(request_headers, scheme, host_and_port,
- path, &block);
- }
+ PopulateSpdy4RequestHeaderBlock(request_headers, scheme, host_and_port, path,
+ &block);
return block;
}
// static
SpdyHeaderBlock SpdyBalsaUtils::ResponseHeadersToSpdyHeaders(
- const BalsaHeaders& response_headers,
- QuicVersion quic_version) {
+ const BalsaHeaders& response_headers) {
SpdyHeaderBlock block;
- PopulateSpdyResponseHeaderBlock(
- net::SpdyUtils::GetSpdyVersionForQuicVersion(quic_version),
- response_headers, &block);
+ PopulateSpdyResponseHeaderBlock(HTTP2, response_headers, &block);
return block;
}
// static
string SpdyBalsaUtils::SerializeResponseHeaders(
- const BalsaHeaders& response_headers,
- QuicVersion quic_version) {
- SpdyHeaderBlock block =
- ResponseHeadersToSpdyHeaders(response_headers, quic_version);
+ const BalsaHeaders& response_headers) {
+ SpdyHeaderBlock block = ResponseHeadersToSpdyHeaders(response_headers);
- return net::SpdyUtils::SerializeUncompressedHeaders(block, quic_version);
+ return net::SpdyUtils::SerializeUncompressedHeaders(block);
}
// static
void SpdyBalsaUtils::SpdyHeadersToResponseHeaders(const SpdyHeaderBlock& block,
- BalsaHeaders* headers,
- QuicVersion quic_version) {
- SpdyHeadersToBalsaHeaders(block, headers, quic_version,
+ BalsaHeaders* headers) {
+ SpdyHeadersToBalsaHeaders(block, headers,
SpdyHeaderValidatorType::RESPONSE_HEADER);
}
// static
void SpdyBalsaUtils::SpdyHeadersToRequestHeaders(const SpdyHeaderBlock& block,
- BalsaHeaders* headers,
- QuicVersion quic_version) {
- SpdyHeadersToBalsaHeaders(block, headers, quic_version,
- SpdyHeaderValidatorType::REQUEST);
+ BalsaHeaders* headers) {
+ SpdyHeadersToBalsaHeaders(block, headers, SpdyHeaderValidatorType::REQUEST);
}
} // namespace tools
diff --git a/chromium/net/tools/quic/spdy_balsa_utils.h b/chromium/net/tools/quic/spdy_balsa_utils.h
index 55389b6619d..6cbdffa2db2 100644
--- a/chromium/net/tools/quic/spdy_balsa_utils.h
+++ b/chromium/net/tools/quic/spdy_balsa_utils.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_header_block.h"
@@ -19,24 +20,19 @@ namespace tools {
class SpdyBalsaUtils {
public:
static std::string SerializeResponseHeaders(
- const BalsaHeaders& response_headers,
- QuicVersion quic_version);
+ const BalsaHeaders& response_headers);
static SpdyHeaderBlock RequestHeadersToSpdyHeaders(
- const BalsaHeaders& request_headers,
- QuicVersion quic_version);
+ const BalsaHeaders& request_headers);
static SpdyHeaderBlock ResponseHeadersToSpdyHeaders(
- const BalsaHeaders& response_headers,
- QuicVersion quic_version);
+ const BalsaHeaders& response_headers);
static void SpdyHeadersToResponseHeaders(const SpdyHeaderBlock& block,
- BalsaHeaders* headers,
- QuicVersion quic_version);
+ BalsaHeaders* headers);
static void SpdyHeadersToRequestHeaders(const SpdyHeaderBlock& block,
- BalsaHeaders* headers,
- QuicVersion quic_version);
+ BalsaHeaders* headers);
private:
DISALLOW_COPY_AND_ASSIGN(SpdyBalsaUtils);
diff --git a/chromium/net/tools/quic/spdy_balsa_utils_test.cc b/chromium/net/tools/quic/spdy_balsa_utils_test.cc
index 823a4a6788f..0bceda367ad 100644
--- a/chromium/net/tools/quic/spdy_balsa_utils_test.cc
+++ b/chromium/net/tools/quic/spdy_balsa_utils_test.cc
@@ -7,8 +7,6 @@
#include "net/spdy/spdy_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
-using net::test::CompareSpdyHeaderBlocks;
-
namespace net {
namespace tools {
namespace test {
@@ -18,8 +16,8 @@ TEST(SpdyBalsaUtilsTest, RequestHeadersToSpdyHeaders) {
BalsaHeaders request_headers;
request_headers.SetRequestFirstlineFromStringPieces(
"GET", "https://www.google.com/foo", "HTTP/1.1");
- SpdyHeaderBlock spdy_headers = SpdyBalsaUtils::RequestHeadersToSpdyHeaders(
- request_headers, kSupportedQuicVersions[0]);
+ SpdyHeaderBlock spdy_headers =
+ SpdyBalsaUtils::RequestHeadersToSpdyHeaders(request_headers);
SpdyHeaderBlock expected_headers;
expected_headers[":authority"] = "www.google.com";
@@ -27,20 +25,20 @@ TEST(SpdyBalsaUtilsTest, RequestHeadersToSpdyHeaders) {
expected_headers[":scheme"] = "https";
expected_headers[":method"] = "GET";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_headers, spdy_headers));
+ EXPECT_EQ(expected_headers, spdy_headers);
}
TEST(SpdyBalsaUtilsTest, ResponseHeadersToSpdyHeaders) {
BalsaHeaders response_headers;
response_headers.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200",
"OK");
- SpdyHeaderBlock spdy_headers = SpdyBalsaUtils::ResponseHeadersToSpdyHeaders(
- response_headers, kSupportedQuicVersions[0]);
+ SpdyHeaderBlock spdy_headers =
+ SpdyBalsaUtils::ResponseHeadersToSpdyHeaders(response_headers);
SpdyHeaderBlock expected_headers;
expected_headers[":status"] = "200";
- EXPECT_TRUE(CompareSpdyHeaderBlocks(expected_headers, spdy_headers));
+ EXPECT_EQ(expected_headers, spdy_headers);
}
TEST(SpdyBalsaUtilsTest, SpdyHeadersToRequestHeaders) {
@@ -52,8 +50,7 @@ TEST(SpdyBalsaUtilsTest, SpdyHeadersToRequestHeaders) {
spdy_headers[":method"] = "GET";
BalsaHeaders request_headers;
- SpdyBalsaUtils::SpdyHeadersToRequestHeaders(spdy_headers, &request_headers,
- kSupportedQuicVersions[0]);
+ SpdyBalsaUtils::SpdyHeadersToRequestHeaders(spdy_headers, &request_headers);
EXPECT_EQ("GET", request_headers.request_method());
EXPECT_EQ("HTTP/1.1", request_headers.request_version());
EXPECT_EQ("/foo", request_headers.request_uri());
@@ -66,8 +63,7 @@ TEST(SpdyBalsaUtilsTest, SpdyHeadersToRequestHeaders) {
spdy_headers1[":scheme"] = "http";
BalsaHeaders request_headers1;
- SpdyBalsaUtils::SpdyHeadersToRequestHeaders(spdy_headers1, &request_headers1,
- kSupportedQuicVersions[0]);
+ SpdyBalsaUtils::SpdyHeadersToRequestHeaders(spdy_headers1, &request_headers1);
EXPECT_EQ("GET", request_headers1.request_method());
EXPECT_EQ("HTTP/1.1", request_headers1.request_version());
EXPECT_EQ("/foo", request_headers1.request_uri());
@@ -79,8 +75,7 @@ TEST(SpdyBalsaUtilsTest, SpdyHeadersToResponseHeaders) {
spdy_headers[":status"] = "200";
BalsaHeaders response_headers;
- SpdyBalsaUtils::SpdyHeadersToResponseHeaders(spdy_headers, &response_headers,
- kSupportedQuicVersions[0]);
+ SpdyBalsaUtils::SpdyHeadersToResponseHeaders(spdy_headers, &response_headers);
EXPECT_EQ("200", response_headers.response_code());
}
diff --git a/chromium/net/tools/quic/synchronous_host_resolver.cc b/chromium/net/tools/quic/synchronous_host_resolver.cc
index 4c0cb3f216b..b0ec18ed18c 100644
--- a/chromium/net/tools/quic/synchronous_host_resolver.cc
+++ b/chromium/net/tools/quic/synchronous_host_resolver.cc
@@ -6,6 +6,7 @@
#include "base/at_exit.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -64,12 +65,11 @@ void ResolverThread::Run() {
SingleRequestHostResolver resolver(resolver_impl.get());
HostPortPair host_port_pair(host_, 80);
- rv_ = resolver.Resolve(
- HostResolver::RequestInfo(host_port_pair), DEFAULT_PRIORITY,
- addresses_,
- base::Bind(&ResolverThread::OnResolutionComplete,
- weak_factory_.GetWeakPtr()),
- BoundNetLog());
+ rv_ = resolver.Resolve(HostResolver::RequestInfo(host_port_pair),
+ DEFAULT_PRIORITY, addresses_,
+ base::Bind(&ResolverThread::OnResolutionComplete,
+ weak_factory_.GetWeakPtr()),
+ BoundNetLog());
if (rv_ != ERR_IO_PENDING)
return;
@@ -89,7 +89,7 @@ int ResolverThread::Resolve(const std::string& host, AddressList* addresses) {
void ResolverThread::OnResolutionComplete(int rv) {
rv_ = rv;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
} // namespace
diff --git a/chromium/net/tools/quic/test_tools/http_message.cc b/chromium/net/tools/quic/test_tools/http_message.cc
index b1520917b43..1ea56382c73 100644
--- a/chromium/net/tools/quic/test_tools/http_message.cc
+++ b/chromium/net/tools/quic/test_tools/http_message.cc
@@ -6,7 +6,6 @@
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
@@ -20,31 +19,18 @@ namespace test {
namespace {
-//const char kContentEncoding[] = "content-encoding";
+// const char kContentEncoding[] = "content-encoding";
const char kContentLength[] = "content-length";
const char kTransferCoding[] = "transfer-encoding";
// Both kHTTPVersionString and kMethodString arrays are constructed to match
// the enum values defined in Version and Method of HTTPMessage.
-const char* const kHTTPVersionString[] = {
- "",
- "HTTP/0.9",
- "HTTP/1.0",
- "HTTP/1.1"
-};
+const char* const kHTTPVersionString[] = {"", "HTTP/0.9", "HTTP/1.0",
+ "HTTP/1.1"};
const char* const kMethodString[] = {
- "",
- "OPTIONS",
- "GET",
- "HEAD",
- "POST",
- "PUT",
- "DELETE",
- "TRACE",
- "CONNECT",
- "MKCOL",
- "UNLOCK",
+ "", "OPTIONS", "GET", "HEAD", "POST", "PUT",
+ "DELETE", "TRACE", "CONNECT", "MKCOL", "UNLOCK",
};
// Returns true if the message represents a complete request or response.
@@ -101,8 +87,7 @@ const char* HTTPMessage::VersionToString(Version version) {
return kHTTPVersionString[version];
}
-HTTPMessage::HTTPMessage()
- : is_request_(true) {
+HTTPMessage::HTTPMessage() : is_request_(true) {
InitializeFields();
}
@@ -116,8 +101,7 @@ HTTPMessage::HTTPMessage(Version ver, Method request, const string& path)
headers()->SetRequestUri(path);
}
-HTTPMessage::~HTTPMessage() {
-}
+HTTPMessage::~HTTPMessage() {}
void HTTPMessage::InitializeFields() {
has_complete_message_ = true;
@@ -156,10 +140,10 @@ void HTTPMessage::ValidateMessage() const {
headers()->GetAllOfHeader(kTransferCoding, &transfer_encodings);
CHECK_GE(1ul, transfer_encodings.size());
for (vector<StringPiece>::iterator it = transfer_encodings.begin();
- it != transfer_encodings.end();
- ++it) {
+ it != transfer_encodings.end(); ++it) {
CHECK(base::EqualsCaseInsensitiveASCII("identity", *it) ||
- base::EqualsCaseInsensitiveASCII("chunked", *it)) << *it;
+ base::EqualsCaseInsensitiveASCII("chunked", *it))
+ << *it;
}
vector<StringPiece> content_lengths;
diff --git a/chromium/net/tools/quic/test_tools/http_message.h b/chromium/net/tools/quic/test_tools/http_message.h
index 6b63dafd76c..de0ee3a5314 100644
--- a/chromium/net/tools/quic/test_tools/http_message.h
+++ b/chromium/net/tools/quic/test_tools/http_message.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/tools/balsa/balsa_enums.h"
#include "net/tools/balsa/balsa_headers.h"
@@ -18,12 +19,7 @@ namespace test {
class HttpConstants {
public:
- enum Version {
- HTTP_UNKNOWN = 0,
- HTTP_0_9,
- HTTP_1_0,
- HTTP_1_1
- };
+ enum Version { HTTP_UNKNOWN = 0, HTTP_0_9, HTTP_1_0, HTTP_1_1 };
enum Method {
UNKNOWN_METHOD = 0,
diff --git a/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h b/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h
index f3021651bc1..31040828b8f 100644
--- a/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h
+++ b/chromium/net/tools/quic/test_tools/limited_mtu_test_writer.h
@@ -5,7 +5,9 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
+#include "base/macros.h"
#include "net/quic/quic_protocol.h"
#include "net/tools/quic/quic_packet_writer_wrapper.h"
diff --git a/chromium/net/tools/quic/test_tools/mock_epoll_server.cc b/chromium/net/tools/quic/test_tools/mock_epoll_server.cc
index 4101c5e9ab0..b5cd974681e 100644
--- a/chromium/net/tools/quic/test_tools/mock_epoll_server.cc
+++ b/chromium/net/tools/quic/test_tools/mock_epoll_server.cc
@@ -8,34 +8,28 @@ namespace net {
namespace tools {
namespace test {
-FakeTimeEpollServer::FakeTimeEpollServer(): now_in_usec_(0) {
-}
+FakeTimeEpollServer::FakeTimeEpollServer() : now_in_usec_(0) {}
-FakeTimeEpollServer::~FakeTimeEpollServer() {
-}
+FakeTimeEpollServer::~FakeTimeEpollServer() {}
-int64 FakeTimeEpollServer::NowInUsec() const {
+int64_t FakeTimeEpollServer::NowInUsec() const {
return now_in_usec_;
}
-MockEpollServer::MockEpollServer() : until_in_usec_(-1) {
-}
+MockEpollServer::MockEpollServer() : until_in_usec_(-1) {}
-MockEpollServer::~MockEpollServer() {
-}
+MockEpollServer::~MockEpollServer() {}
int MockEpollServer::epoll_wait_impl(int epfd,
struct epoll_event* events,
int max_events,
int timeout_in_ms) {
int num_events = 0;
- while (!event_queue_.empty() &&
- num_events < max_events &&
+ while (!event_queue_.empty() && num_events < max_events &&
event_queue_.begin()->first <= NowInUsec() &&
((until_in_usec_ == -1) ||
- (event_queue_.begin()->first < until_in_usec_))
- ) {
- int64 event_time_in_usec = event_queue_.begin()->first;
+ (event_queue_.begin()->first < until_in_usec_))) {
+ int64_t event_time_in_usec = event_queue_.begin()->first;
events[num_events] = event_queue_.begin()->second;
if (event_time_in_usec > NowInUsec()) {
set_now_in_usec(event_time_in_usec);
@@ -43,7 +37,7 @@ int MockEpollServer::epoll_wait_impl(int epfd,
event_queue_.erase(event_queue_.begin());
++num_events;
}
- if (num_events == 0) { // then we'd have waited 'till the timeout.
+ if (num_events == 0) { // then we'd have waited 'till the timeout.
if (until_in_usec_ < 0) { // then we don't care what the final time is.
if (timeout_in_ms > 0) {
AdvanceBy(timeout_in_ms * 1000);
diff --git a/chromium/net/tools/quic/test_tools/mock_epoll_server.h b/chromium/net/tools/quic/test_tools/mock_epoll_server.h
index 38c8be5b335..e10fc498697 100644
--- a/chromium/net/tools/quic/test_tools/mock_epoll_server.h
+++ b/chromium/net/tools/quic/test_tools/mock_epoll_server.h
@@ -5,7 +5,11 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/logging.h"
+#include "base/macros.h"
#include "net/tools/epoll_server/epoll_server.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -22,12 +26,12 @@ class FakeTimeEpollServer : public EpollServer {
~FakeTimeEpollServer() override;
// Replaces the EpollServer NowInUsec.
- int64 NowInUsec() const override;
+ int64_t NowInUsec() const override;
- void set_now_in_usec(int64 nius) { now_in_usec_ = nius; }
+ void set_now_in_usec(int64_t nius) { now_in_usec_ = nius; }
// Advances the virtual 'now' by advancement_usec.
- void AdvanceBy(int64 advancement_usec) {
+ void AdvanceBy(int64_t advancement_usec) {
set_now_in_usec(NowInUsec() + advancement_usec);
}
@@ -36,20 +40,20 @@ class FakeTimeEpollServer : public EpollServer {
// Note that the WaitForEventsAndExecuteCallbacks invocation
// may cause NowInUs to advance beyond what was specified here.
// If that is not desired, use the AdvanceByExactly calls.
- void AdvanceByAndWaitForEventsAndExecuteCallbacks(int64 advancement_usec) {
+ void AdvanceByAndWaitForEventsAndExecuteCallbacks(int64_t advancement_usec) {
AdvanceBy(advancement_usec);
WaitForEventsAndExecuteCallbacks();
}
private:
- int64 now_in_usec_;
+ int64_t now_in_usec_;
DISALLOW_COPY_AND_ASSIGN(FakeTimeEpollServer);
};
class MockEpollServer : public FakeTimeEpollServer {
public: // type definitions
- typedef base::hash_multimap<int64, struct epoll_event> EventQueue;
+ typedef base::hash_multimap<int64_t, struct epoll_event> EventQueue;
MockEpollServer();
~MockEpollServer() override;
@@ -59,7 +63,7 @@ class MockEpollServer : public FakeTimeEpollServer {
// to add an event for a time which has already been passed..
// .. upon the next time that the callbacks are invoked,
// all events which are in the 'past' will be delivered.
- void AddEvent(int64 time_in_usec, const struct epoll_event& ee) {
+ void AddEvent(int64_t time_in_usec, const struct epoll_event& ee) {
event_queue_.insert(std::make_pair(time_in_usec, ee));
}
@@ -67,13 +71,13 @@ class MockEpollServer : public FakeTimeEpollServer {
// and ensure that the next invocation of
// WaitForEventsAndExecuteCallbacks goes no farther than
// advancement_usec from the current time.
- void AdvanceByExactly(int64 advancement_usec) {
+ void AdvanceByExactly(int64_t advancement_usec) {
until_in_usec_ = NowInUsec() + advancement_usec;
set_now_in_usec(NowInUsec() + advancement_usec);
}
// As above, except calls WaitForEventsAndExecuteCallbacks.
- void AdvanceByExactlyAndCallCallbacks(int64 advancement_usec) {
+ void AdvanceByExactlyAndCallCallbacks(int64_t advancement_usec) {
AdvanceByExactly(advancement_usec);
WaitForEventsAndExecuteCallbacks();
}
@@ -98,7 +102,7 @@ class MockEpollServer : public FakeTimeEpollServer {
private: // members
EventQueue event_queue_;
- int64 until_in_usec_;
+ int64_t until_in_usec_;
DISALLOW_COPY_AND_ASSIGN(MockEpollServer);
};
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_server_session_visitor.h b/chromium/net/tools/quic/test_tools/mock_quic_server_session_visitor.h
index 38d437110ee..15fba1d62a5 100644
--- a/chromium/net/tools/quic/test_tools/mock_quic_server_session_visitor.h
+++ b/chromium/net/tools/quic/test_tools/mock_quic_server_session_visitor.h
@@ -5,7 +5,8 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_SERVER_SESSION_VISITOR_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_SERVER_SESSION_VISITOR_H_
-#include "net/tools/quic/quic_server_session.h"
+#include "base/macros.h"
+#include "net/tools/quic/quic_server_session_base.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace net {
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 7801db5f561..8e972f3b7c8 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
@@ -16,10 +16,7 @@ MockTimeWaitListManager::MockTimeWaitListManager(
QuicPacketWriter* writer,
QuicServerSessionVisitor* visitor,
QuicConnectionHelperInterface* helper)
- : QuicTimeWaitListManager(writer,
- visitor,
- helper,
- QuicSupportedVersions()) {
+ : QuicTimeWaitListManager(writer, visitor, helper) {
// Though AddConnectionIdToTimeWait is mocked, we want to retain its
// functionality.
EXPECT_CALL(*this, 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 56b2880eba4..116fd7e30c9 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
@@ -25,15 +25,16 @@ class MockTimeWaitListManager : public QuicTimeWaitListManager {
void(QuicConnectionId connection_id,
QuicVersion version,
bool connection_rejected_statelessly,
- QuicEncryptedPacket* close_packet));
+ std::vector<QuicEncryptedPacket*>* termination_packets));
void QuicTimeWaitListManager_AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
QuicVersion version,
bool connection_rejected_statelessly,
- QuicEncryptedPacket* close_packet) {
+ std::vector<QuicEncryptedPacket*>* termination_packets) {
QuicTimeWaitListManager::AddConnectionIdToTimeWait(
- connection_id, version, connection_rejected_statelessly, close_packet);
+ connection_id, version, connection_rejected_statelessly,
+ termination_packets);
}
MOCK_METHOD5(ProcessPacket,
diff --git a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc b/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc
index 79573803cbe..5e1bfb81063 100644
--- a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc
+++ b/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.cc
@@ -55,21 +55,19 @@ PacketDroppingTestWriter::PacketDroppingTestWriter()
fake_packet_delay_(QuicTime::Delta::Zero()),
fake_bandwidth_(QuicBandwidth::Zero()),
buffer_size_(0) {
- uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
+ uint32_t seed = base::RandInt(0, std::numeric_limits<int32_t>::max());
VLOG(1) << "Seeding packet loss with " << seed;
simple_random_.set_seed(seed);
}
PacketDroppingTestWriter::~PacketDroppingTestWriter() {}
-void PacketDroppingTestWriter::Initialize(
- QuicConnectionHelperInterface* helper,
- Delegate* on_can_write) {
+void PacketDroppingTestWriter::Initialize(QuicConnectionHelperInterface* helper,
+ Delegate* on_can_write) {
clock_ = helper->GetClock();
write_unblocked_alarm_.reset(
helper->CreateAlarm(new WriteUnblockedAlarm(this)));
- delay_alarm_.reset(
- helper->CreateAlarm(new DelayAlarm(this)));
+ delay_alarm_.reset(helper->CreateAlarm(new DelayAlarm(this)));
on_can_write_.reset(on_can_write);
}
@@ -83,20 +81,21 @@ WriteResult PacketDroppingTestWriter::WritePacket(
base::AutoLock locked(config_mutex_);
if (fake_drop_first_n_packets_ > 0 &&
- num_calls_to_write_ <= static_cast<uint64>(fake_drop_first_n_packets_)) {
+ num_calls_to_write_ <=
+ static_cast<uint64_t>(fake_drop_first_n_packets_)) {
DVLOG(1) << "Dropping first " << fake_drop_first_n_packets_
<< " packets (packet number " << num_calls_to_write_ << ")";
return WriteResult(WRITE_STATUS_OK, buf_len);
}
if (fake_packet_loss_percentage_ > 0 &&
simple_random_.RandUint64() % 100 <
- static_cast<uint64>(fake_packet_loss_percentage_)) {
+ static_cast<uint64_t>(fake_packet_loss_percentage_)) {
DVLOG(1) << "Dropping packet.";
return WriteResult(WRITE_STATUS_OK, buf_len);
}
if (fake_blocked_socket_percentage_ > 0 &&
simple_random_.RandUint64() % 100 <
- static_cast<uint64>(fake_blocked_socket_percentage_)) {
+ static_cast<uint64_t>(fake_blocked_socket_percentage_)) {
CHECK(on_can_write_.get() != nullptr);
DVLOG(1) << "Blocking socket.";
if (!write_unblocked_alarm_->IsSet()) {
@@ -118,14 +117,13 @@ WriteResult PacketDroppingTestWriter::WritePacket(
if (!fake_bandwidth_.IsZero()) {
// Calculate a time the bandwidth limit would impose.
QuicTime::Delta bandwidth_delay = QuicTime::Delta::FromMicroseconds(
- (buf_len * kNumMicrosPerSecond) /
- fake_bandwidth_.ToBytesPerSecond());
- send_time = delayed_packets_.empty() ?
- send_time.Add(bandwidth_delay) :
- delayed_packets_.back().send_time.Add(bandwidth_delay);
+ (buf_len * kNumMicrosPerSecond) / fake_bandwidth_.ToBytesPerSecond());
+ send_time = delayed_packets_.empty()
+ ? send_time.Add(bandwidth_delay)
+ : delayed_packets_.back().send_time.Add(bandwidth_delay);
}
- delayed_packets_.push_back(DelayedWrite(buffer, buf_len, self_address,
- peer_address, send_time));
+ delayed_packets_.push_back(
+ DelayedWrite(buffer, buf_len, self_address, peer_address, send_time));
cur_buffer_size_ += buf_len;
// Set the alarm if it's not yet set.
@@ -136,8 +134,8 @@ WriteResult PacketDroppingTestWriter::WritePacket(
return WriteResult(WRITE_STATUS_OK, buf_len);
}
- return QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address, peer_address);
+ return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+ peer_address);
}
bool PacketDroppingTestWriter::IsWriteBlocked() const {
@@ -165,7 +163,7 @@ QuicTime PacketDroppingTestWriter::ReleaseNextPacket() {
// Determine if we should re-order.
if (delayed_packets_.size() > 1 && fake_packet_reorder_percentage_ > 0 &&
simple_random_.RandUint64() % 100 <
- static_cast<uint64>(fake_packet_reorder_percentage_)) {
+ static_cast<uint64_t>(fake_packet_reorder_percentage_)) {
DVLOG(1) << "Reordering packets.";
++iter;
// Swap the send times when re-ordering packets.
@@ -175,9 +173,9 @@ QuicTime PacketDroppingTestWriter::ReleaseNextPacket() {
DVLOG(1) << "Releasing packet. " << (delayed_packets_.size() - 1)
<< " remaining.";
// Grab the next one off the queue and send it.
- QuicPacketWriterWrapper::WritePacket(
- iter->buffer.data(), iter->buffer.length(),
- iter->self_address, iter->peer_address);
+ QuicPacketWriterWrapper::WritePacket(iter->buffer.data(),
+ iter->buffer.length(),
+ iter->self_address, iter->peer_address);
DCHECK_GE(cur_buffer_size_, iter->buffer.length());
cur_buffer_size_ -= iter->buffer.length();
delayed_packets_.erase(iter);
diff --git a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h b/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h
index 0082f8e2d87..ed5dc82f5f8 100644
--- a/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h
+++ b/chromium/net/tools/quic/test_tools/packet_dropping_test_writer.h
@@ -5,11 +5,14 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <list>
#include <string>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "net/quic/quic_alarm.h"
@@ -30,7 +33,6 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
class Delegate {
public:
virtual ~Delegate() {}
- virtual void OnPacketSent(WriteResult result) = 0;
virtual void OnCanWrite() = 0;
};
@@ -63,14 +65,14 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
void OnCanWrite();
// The percent of time a packet is simulated as being lost.
- void set_fake_packet_loss_percentage(int32 fake_packet_loss_percentage) {
+ void set_fake_packet_loss_percentage(int32_t fake_packet_loss_percentage) {
base::AutoLock locked(config_mutex_);
fake_packet_loss_percentage_ = fake_packet_loss_percentage;
}
// Simulate dropping the first n packets unconditionally.
// Subsequent packets will be lost at fake_packet_loss_percentage_ if set.
- void set_fake_drop_first_n_packets(int32 fake_drop_first_n_packets) {
+ void set_fake_drop_first_n_packets(int32_t fake_drop_first_n_packets) {
base::AutoLock locked(config_mutex_);
fake_drop_first_n_packets_ = fake_drop_first_n_packets;
}
@@ -78,14 +80,14 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
// The percent of time WritePacket will block and set WriteResult's status
// to WRITE_STATUS_BLOCKED.
void set_fake_blocked_socket_percentage(
- int32 fake_blocked_socket_percentage) {
+ int32_t fake_blocked_socket_percentage) {
DCHECK(clock_);
base::AutoLock locked(config_mutex_);
- fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
+ fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
}
// The percent of time a packet is simulated as being reordered.
- void set_fake_reorder_percentage(int32 fake_packet_reorder_percentage) {
+ void set_fake_reorder_percentage(int32_t fake_packet_reorder_percentage) {
DCHECK(clock_);
base::AutoLock locked(config_mutex_);
DCHECK(!fake_packet_delay_.IsZero());
@@ -96,7 +98,7 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
DCHECK(clock_);
base::AutoLock locked(config_mutex_);
- fake_packet_delay_ = fake_packet_delay;
+ fake_packet_delay_ = fake_packet_delay;
}
// The maximum bandwidth and buffer size of the connection. When these are
@@ -112,9 +114,7 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
}
// Useful for reproducing very flaky issues.
- void set_seed(uint64 seed) {
- simple_random_.set_seed(seed);
- }
+ void set_seed(uint64_t seed) { simple_random_.set_seed(seed); }
private:
// Writes out the next packet to the contained writer and returns the time
@@ -147,13 +147,13 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
// Stored packets delayed by fake packet delay or bandwidth restrictions.
DelayedPacketList delayed_packets_;
QuicByteCount cur_buffer_size_;
- uint64 num_calls_to_write_;
+ uint64_t num_calls_to_write_;
base::Lock config_mutex_;
- int32 fake_packet_loss_percentage_;
- int32 fake_drop_first_n_packets_;
- int32 fake_blocked_socket_percentage_;
- int32 fake_packet_reorder_percentage_;
+ int32_t fake_packet_loss_percentage_;
+ int32_t fake_drop_first_n_packets_;
+ int32_t fake_blocked_socket_percentage_;
+ int32_t fake_packet_reorder_percentage_;
QuicTime::Delta fake_packet_delay_;
QuicBandwidth fake_bandwidth_;
QuicByteCount buffer_size_;
diff --git a/chromium/net/tools/quic/test_tools/quic_client_peer.h b/chromium/net/tools/quic/test_tools/quic_client_peer.h
index 32f96a78173..9d9d1034122 100644
--- a/chromium/net/tools/quic/test_tools/quic_client_peer.h
+++ b/chromium/net/tools/quic/test_tools/quic_client_peer.h
@@ -5,7 +5,7 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
namespace net {
diff --git a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc b/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc
index 02ca0bff55c..ab8f28119b5 100644
--- a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc
+++ b/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.cc
@@ -31,13 +31,6 @@ QuicPacketWriter* QuicDispatcherPeer::GetWriter(QuicDispatcher* dispatcher) {
}
// static
-void QuicDispatcherPeer::SetPacketWriterFactory(
- QuicDispatcher* dispatcher,
- QuicDispatcher::PacketWriterFactory* packet_writer_factory) {
- dispatcher->packet_writer_factory_.reset(packet_writer_factory);
-}
-
-// static
QuicConnectionHelperInterface* QuicDispatcherPeer::GetHelper(
QuicDispatcher* dispatcher) {
return dispatcher->helper_.get();
@@ -57,6 +50,12 @@ QuicErrorCode QuicDispatcherPeer::GetAndClearLastError(
return ret;
}
+// static
+const QuicDispatcher::SessionMap& QuicDispatcherPeer::session_map(
+ QuicDispatcher* dispatcher) {
+ return dispatcher->session_map();
+}
+
} // namespace test
} // namespace tools
} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h b/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h
index b2b945160d1..19311bd4915 100644
--- a/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h
+++ b/chromium/net/tools/quic/test_tools/quic_dispatcher_peer.h
@@ -7,6 +7,7 @@
#include "net/tools/quic/quic_dispatcher.h"
+#include "base/macros.h"
#include "net/base/ip_endpoint.h"
namespace net {
@@ -28,10 +29,6 @@ class QuicDispatcherPeer {
static QuicPacketWriter* GetWriter(QuicDispatcher* dispatcher);
- static void SetPacketWriterFactory(
- QuicDispatcher* dispatcher,
- QuicDispatcher::PacketWriterFactory* packet_writer_factory);
-
static QuicConnectionHelperInterface* GetHelper(QuicDispatcher* dispatcher);
static QuicDispatcher::WriteBlockedList* GetWriteBlockedList(
@@ -41,6 +38,9 @@ class QuicDispatcherPeer {
// visitor's OnError() method. Then set that record to QUIC_NO_ERROR.
static QuicErrorCode GetAndClearLastError(QuicDispatcher* dispatcher);
+ static const QuicDispatcher::SessionMap& session_map(
+ QuicDispatcher* dispatcher);
+
private:
DISALLOW_COPY_AND_ASSIGN(QuicDispatcherPeer);
};
diff --git a/chromium/net/tools/quic/test_tools/quic_in_memory_cache_peer.h b/chromium/net/tools/quic/test_tools/quic_in_memory_cache_peer.h
index b5996bd7505..e7241099412 100644
--- a/chromium/net/tools/quic/test_tools/quic_in_memory_cache_peer.h
+++ b/chromium/net/tools/quic/test_tools/quic_in_memory_cache_peer.h
@@ -5,6 +5,7 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_QUIC_IN_MEMORY_CACHE_PEER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_IN_MEMORY_CACHE_PEER_H_
+#include "base/macros.h"
#include "net/tools/quic/quic_in_memory_cache.h"
namespace net {
diff --git a/chromium/net/tools/quic/test_tools/quic_server_peer.cc b/chromium/net/tools/quic/test_tools/quic_server_peer.cc
index 293c788b81e..eabebf86541 100644
--- a/chromium/net/tools/quic/test_tools/quic_server_peer.cc
+++ b/chromium/net/tools/quic/test_tools/quic_server_peer.cc
@@ -15,8 +15,8 @@ namespace test {
// static
bool QuicServerPeer::SetSmallSocket(QuicServer* server) {
int size = 1024 * 10;
- return setsockopt(
- server->fd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) != -1;
+ return setsockopt(server->fd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) !=
+ -1;
}
// static
diff --git a/chromium/net/tools/quic/test_tools/quic_server_peer.h b/chromium/net/tools/quic/test_tools/quic_server_peer.h
index a9d4f56d512..ae3c1498dd9 100644
--- a/chromium/net/tools/quic/test_tools/quic_server_peer.h
+++ b/chromium/net/tools/quic/test_tools/quic_server_peer.h
@@ -5,7 +5,7 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_SERVER_PEER_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
namespace net {
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 eff3160539f..4deec5688df 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_client.cc
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.cc
@@ -46,6 +46,7 @@ class RecordingProofVerifier : public ProofVerifier {
QuicAsyncStatus VerifyProof(const string& hostname,
const string& server_config,
const vector<string>& certs,
+ const string& cert_sct,
const string& signature,
const ProofVerifyContext* context,
string* error_details,
@@ -71,19 +72,23 @@ class RecordingProofVerifier : public ProofVerifier {
// }
//
// common_name_ = cert->subject().GetDisplayName();
+ cert_sct_ = cert_sct;
+
return QUIC_SUCCESS;
}
const string& common_name() const { return common_name_; }
+ const string& cert_sct() const { return cert_sct_; }
+
private:
string common_name_;
+ string cert_sct_;
};
} // anonymous namespace
-BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers,
- bool secure) {
+BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers) {
StringPiece uri = const_headers->request_uri();
if (uri.empty()) {
return nullptr;
@@ -93,11 +98,9 @@ BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers,
}
BalsaHeaders* headers = new BalsaHeaders;
headers->CopyFrom(*const_headers);
- if (!uri.starts_with("https://") &&
- !uri.starts_with("http://")) {
+ if (!uri.starts_with("https://") && !uri.starts_with("http://")) {
// If we have a relative URL, set some defaults.
- string full_uri = secure ? "https://www.google.com" :
- "http://www.google.com";
+ string full_uri = "https://www.google.com";
full_uri.append(uri.as_string());
headers->SetRequestUri(full_uri);
}
@@ -109,12 +112,11 @@ MockableQuicClient::MockableQuicClient(
const QuicServerId& server_id,
const QuicVersionVector& supported_versions,
EpollServer* epoll_server)
- : QuicClient(server_address,
- server_id,
- supported_versions,
- epoll_server),
- override_connection_id_(0),
- test_writer_(nullptr) {}
+ : MockableQuicClient(server_address,
+ server_id,
+ QuicConfig(),
+ supported_versions,
+ epoll_server) {}
MockableQuicClient::MockableQuicClient(
IPEndPoint server_address,
@@ -126,7 +128,8 @@ MockableQuicClient::MockableQuicClient(
server_id,
supported_versions,
config,
- epoll_server),
+ epoll_server,
+ new RecordingProofVerifier()),
override_connection_id_(0),
test_writer_(nullptr) {}
@@ -162,55 +165,43 @@ void MockableQuicClient::UseConnectionId(QuicConnectionId connection_id) {
QuicTestClient::QuicTestClient(IPEndPoint server_address,
const string& server_hostname,
- bool secure,
+ const QuicVersionVector& supported_versions)
+ : QuicTestClient(server_address,
+ server_hostname,
+ QuicConfig(),
+ supported_versions) {}
+
+QuicTestClient::QuicTestClient(IPEndPoint server_address,
+ const string& server_hostname,
+ const QuicConfig& config,
const QuicVersionVector& supported_versions)
: client_(new MockableQuicClient(server_address,
QuicServerId(server_hostname,
server_address.port(),
- secure,
PRIVACY_MODE_DISABLED),
+ config,
supported_versions,
- &epoll_server_)) {
- Initialize(secure);
-}
-
-QuicTestClient::QuicTestClient(
- IPEndPoint server_address,
- const string& server_hostname,
- bool secure,
- const QuicConfig& config,
- const QuicVersionVector& supported_versions)
- : client_(
- new MockableQuicClient(server_address,
- QuicServerId(server_hostname,
- server_address.port(),
- secure,
- PRIVACY_MODE_DISABLED),
- config,
- supported_versions,
- &epoll_server_)) {
- Initialize(secure);
+ &epoll_server_)),
+ allow_bidirectional_data_(false) {
+ Initialize();
}
-QuicTestClient::QuicTestClient() {
-}
+QuicTestClient::QuicTestClient() : allow_bidirectional_data_(false) {}
QuicTestClient::~QuicTestClient() {
if (stream_) {
stream_->set_visitor(nullptr);
}
+ client_->Disconnect();
}
-void QuicTestClient::Initialize(bool secure) {
+void QuicTestClient::Initialize() {
priority_ = 3;
connect_attempted_ = false;
- secure_ = secure;
auto_reconnect_ = false;
buffer_body_ = true;
fec_policy_ = FEC_PROTECT_OPTIONAL;
- proof_verifier_ = nullptr;
ClearPerRequestState();
- ExpectCertificates(secure_);
// As chrome will generally do this, we want it to be the default when it's
// not overridden.
if (!client_->config()->HasSetBytesForConnectionIdToSend()) {
@@ -218,16 +209,6 @@ void QuicTestClient::Initialize(bool secure) {
}
}
-void QuicTestClient::ExpectCertificates(bool on) {
- if (on) {
- proof_verifier_ = new RecordingProofVerifier;
- client_->SetProofVerifier(proof_verifier_);
- } else {
- proof_verifier_ = nullptr;
- client_->SetProofVerifier(nullptr);
- }
-}
-
void QuicTestClient::SetUserAgentID(const string& user_agent_id) {
client_->SetUserAgentID(user_agent_id);
}
@@ -252,7 +233,7 @@ ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
const BalsaHeaders* headers,
StringPiece body,
bool fin,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* delegate) {
// Maybe it's better just to overload this. it's just that we need
// for the GetOrCreateStream function to call something else...which
// is icky and complicated, but maybe not worse than this.
@@ -263,8 +244,8 @@ ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
ssize_t ret = 0;
if (headers != nullptr) {
- SpdyHeaderBlock spdy_headers = SpdyBalsaUtils::RequestHeadersToSpdyHeaders(
- *headers, stream->version());
+ SpdyHeaderBlock spdy_headers =
+ SpdyBalsaUtils::RequestHeadersToSpdyHeaders(*headers);
if (headers->HasHeader("transfer-encoding")) {
// We have tests which rely on sending a non-standards-compliant
// T-E header.
@@ -272,9 +253,13 @@ ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
headers->GetAllOfHeaderAsString("transfer-encoding", &encoding);
spdy_headers.insert(std::make_pair("transfer-encoding", encoding));
}
+ if (static_cast<StringPiece>(spdy_headers[":authority"]).empty()) {
+ // HTTP/2 requests should include the :authority pseudo hader.
+ spdy_headers[":authority"] = client_->server_id().host();
+ }
ret = stream->SendRequest(spdy_headers, body, fin);
} else {
- stream->SendBody(body.data(), fin, delegate);
+ stream->SendBody(body.as_string(), fin, delegate);
ret = body.length();
}
if (FLAGS_enable_quic_stateless_reject_support) {
@@ -297,11 +282,8 @@ ssize_t QuicTestClient::SendMessage(const HTTPMessage& message) {
if (!connected()) {
GURL url(message.headers()->request_uri().as_string());
if (!url.host().empty()) {
- client_->set_server_id(
- QuicServerId(url.host(),
- url.EffectiveIntPort(),
- url.SchemeIs("https"),
- PRIVACY_MODE_DISABLED));
+ client_->set_server_id(QuicServerId(url.host(), url.EffectiveIntPort(),
+ PRIVACY_MODE_DISABLED));
}
}
@@ -309,8 +291,7 @@ ssize_t QuicTestClient::SendMessage(const HTTPMessage& message) {
// CHECK(message.body_chunks().empty())
// << "HTTPMessage::body_chunks not supported";
- scoped_ptr<BalsaHeaders> munged_headers(MungeHeaders(message.headers(),
- secure_));
+ scoped_ptr<BalsaHeaders> munged_headers(MungeHeaders(message.headers()));
ssize_t ret = GetOrCreateStreamAndSendRequest(
(munged_headers.get() ? munged_headers.get() : message.headers()),
message.body(), message.has_complete_message(), nullptr);
@@ -324,7 +305,7 @@ ssize_t QuicTestClient::SendData(const string& data, bool last_data) {
ssize_t QuicTestClient::SendData(const string& data,
bool last_data,
- QuicAckNotifier::DelegateInterface* delegate) {
+ QuicAckListenerInterface* delegate) {
return GetOrCreateStreamAndSendRequest(nullptr, StringPiece(data), last_data,
delegate);
}
@@ -337,7 +318,7 @@ int QuicTestClient::response_header_size() const {
return response_header_size_;
}
-int64 QuicTestClient::response_body_size() const {
+int64_t QuicTestClient::response_body_size() const {
return response_body_size_;
}
@@ -392,7 +373,9 @@ QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
return nullptr;
}
stream_->set_visitor(this);
- reinterpret_cast<QuicSpdyClientStream*>(stream_)->set_priority(priority_);
+ QuicSpdyClientStream* cs = reinterpret_cast<QuicSpdyClientStream*>(stream_);
+ cs->SetPriority(priority_);
+ cs->set_allow_bidirectional_data(allow_bidirectional_data_);
// Set FEC policy on stream.
ReliableQuicStreamPeer::SetFecPolicy(stream_, fec_policy_);
}
@@ -404,13 +387,20 @@ QuicErrorCode QuicTestClient::connection_error() {
return client()->connection_error();
}
-MockableQuicClient* QuicTestClient::client() { return client_.get(); }
+MockableQuicClient* QuicTestClient::client() {
+ return client_.get();
+}
const string& QuicTestClient::cert_common_name() const {
- return reinterpret_cast<RecordingProofVerifier*>(proof_verifier_)
+ return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
->common_name();
}
+const string& QuicTestClient::cert_sct() const {
+ return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
+ ->cert_sct();
+}
+
QuicTagValueMap QuicTestClient::GetServerConfig() const {
QuicCryptoClientConfig* config = client_->crypto_config();
QuicCryptoClientConfig::CachedState* state =
@@ -464,16 +454,16 @@ void QuicTestClient::ClearPerRequestState() {
}
void QuicTestClient::WaitForResponseForMs(int timeout_ms) {
- int64 timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
- int64 old_timeout_us = epoll_server()->timeout_in_us();
+ int64_t timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
+ int64_t old_timeout_us = epoll_server()->timeout_in_us();
if (timeout_us > 0) {
epoll_server()->set_timeout_in_us(timeout_us);
}
const QuicClock* clock =
- QuicConnectionPeer::GetHelper(client()->session()->connection())->
- GetClock();
- QuicTime end_waiting_time = clock->Now().Add(
- QuicTime::Delta::FromMicroseconds(timeout_us));
+ QuicConnectionPeer::GetHelper(client()->session()->connection())
+ ->GetClock();
+ QuicTime end_waiting_time =
+ clock->Now().Add(QuicTime::Delta::FromMicroseconds(timeout_us));
while (stream_ != nullptr &&
!client_->session()->IsClosedStream(stream_->id()) &&
(timeout_us < 0 || clock->Now() < end_waiting_time)) {
@@ -485,16 +475,16 @@ void QuicTestClient::WaitForResponseForMs(int timeout_ms) {
}
void QuicTestClient::WaitForInitialResponseForMs(int timeout_ms) {
- int64 timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
- int64 old_timeout_us = epoll_server()->timeout_in_us();
+ int64_t timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
+ int64_t old_timeout_us = epoll_server()->timeout_in_us();
if (timeout_us > 0) {
epoll_server()->set_timeout_in_us(timeout_us);
}
const QuicClock* clock =
- QuicConnectionPeer::GetHelper(client()->session()->connection())->
- GetClock();
- QuicTime end_waiting_time = clock->Now().Add(
- QuicTime::Delta::FromMicroseconds(timeout_us));
+ QuicConnectionPeer::GetHelper(client()->session()->connection())
+ ->GetClock();
+ QuicTime end_waiting_time =
+ clock->Now().Add(QuicTime::Delta::FromMicroseconds(timeout_us));
while (stream_ != nullptr &&
!client_->session()->IsClosedStream(stream_->id()) &&
stream_->stream_bytes_read() == 0 &&
@@ -506,7 +496,7 @@ void QuicTestClient::WaitForInitialResponseForMs(int timeout_ms) {
}
}
-ssize_t QuicTestClient::Send(const void *buffer, size_t size) {
+ssize_t QuicTestClient::Send(const void* buffer, size_t size) {
return SendData(string(static_cast<const char*>(buffer), size), false);
}
@@ -519,15 +509,18 @@ bool QuicTestClient::response_headers_complete() const {
const BalsaHeaders* QuicTestClient::response_headers() const {
if (stream_ != nullptr) {
- SpdyBalsaUtils::SpdyHeadersToResponseHeaders(stream_->headers(), &headers_,
- stream_->version());
+ SpdyBalsaUtils::SpdyHeadersToResponseHeaders(stream_->headers(), &headers_);
return &headers_;
} else {
return &headers_;
}
}
-int64 QuicTestClient::response_size() const {
+const SpdyHeaderBlock& QuicTestClient::response_trailers() const {
+ return response_trailers_;
+}
+
+int64_t QuicTestClient::response_size() const {
return bytes_read_;
}
@@ -539,7 +532,7 @@ size_t QuicTestClient::bytes_written() const {
return bytes_written_;
}
-void QuicTestClient::OnClose(QuicDataStream* stream) {
+void QuicTestClient::OnClose(QuicSpdyStream* stream) {
if (stream != nullptr) {
// Always close the stream, regardless of whether it was the last stream
// written.
@@ -554,8 +547,8 @@ void QuicTestClient::OnClose(QuicDataStream* stream) {
}
response_complete_ = true;
response_headers_complete_ = stream_->headers_decompressed();
- SpdyBalsaUtils::SpdyHeadersToResponseHeaders(stream_->headers(), &headers_,
- stream_->version());
+ SpdyBalsaUtils::SpdyHeadersToResponseHeaders(stream_->headers(), &headers_);
+ response_trailers_ = stream_->trailers();
stream_error_ = stream_->stream_error();
bytes_read_ = stream_->stream_bytes_read() + stream_->header_bytes_read();
bytes_written_ =
@@ -574,7 +567,7 @@ void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) {
client_->UseConnectionId(connection_id);
}
-ssize_t QuicTestClient::SendAndWaitForResponse(const void *buffer,
+ssize_t QuicTestClient::SendAndWaitForResponse(const void* buffer,
size_t size) {
LOG(DFATAL) << "Not implemented";
return 0;
@@ -602,7 +595,6 @@ void QuicTestClient::set_bind_to_address(IPAddressNumber address) {
}
const IPEndPoint& QuicTestClient::address() const {
- LOG(DFATAL) << "Not implemented";
return client_->server_address();
}
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 a354b2f4c11..d4f27e90f79 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_client.h
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.h
@@ -5,9 +5,12 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/proto/cached_network_parameters.pb.h"
@@ -65,26 +68,18 @@ class MockableQuicClient : public QuicClient {
};
// A toy QUIC client used for testing, mostly following the SimpleClient APIs.
-class QuicTestClient : public SimpleClient,
- public QuicDataStream::Visitor {
+class QuicTestClient : public SimpleClient, public QuicSpdyStream::Visitor {
public:
QuicTestClient(IPEndPoint server_address,
const std::string& server_hostname,
- bool secure,
const QuicVersionVector& supported_versions);
QuicTestClient(IPEndPoint server_address,
const std::string& server_hostname,
- bool secure,
const QuicConfig& config,
const QuicVersionVector& supported_versions);
~QuicTestClient() override;
- // ExpectCertificates controls whether the server is expected to provide
- // certificates. The certificates, if any, are not verified, but the common
- // name is recorded and available with |cert_common_name()|.
- void ExpectCertificates(bool on);
-
// Sets the |user_agent_id| of the |client_|.
void SetUserAgentID(const std::string& user_agent_id);
@@ -93,7 +88,7 @@ class QuicTestClient : public SimpleClient,
// As above, but |delegate| will be notified when |data| is ACKed.
ssize_t SendData(const std::string& data,
bool last_data,
- QuicAckNotifier::DelegateInterface* delegate);
+ QuicAckListenerInterface* delegate);
// From SimpleClient
// Clears any outstanding state and sends a simple GET of 'uri' to the
@@ -118,9 +113,9 @@ class QuicTestClient : public SimpleClient,
bool response_complete() const override;
bool response_headers_complete() const override;
const BalsaHeaders* response_headers() const override;
- int64 response_size() const override;
+ int64_t response_size() const override;
int response_header_size() const override;
- int64 response_body_size() const override;
+ int64_t response_body_size() const override;
size_t bytes_read() const override;
size_t bytes_written() const override;
bool buffer_body() const override;
@@ -139,8 +134,11 @@ class QuicTestClient : public SimpleClient,
const IPEndPoint& address() const override;
size_t requests_sent() const override;
- // From QuicDataStream::Visitor
- void OnClose(QuicDataStream* stream) override;
+ // Returns the response trailers as received by the |stream_|.
+ const SpdyHeaderBlock& response_trailers() const;
+
+ // From QuicSpdyStream::Visitor
+ void OnClose(QuicSpdyStream* stream) override;
// Configures client_ to take ownership of and use the writer.
// Must be called before initial connect.
@@ -155,11 +153,10 @@ class QuicTestClient : public SimpleClient,
// Calls GetorCreateStream(), sends the request on the stream, and
// stores the reuest in case it needs to be resent. If |headers| is
// null, only the body will be sent on the stream.
- ssize_t GetOrCreateStreamAndSendRequest(
- const BalsaHeaders* headers,
- StringPiece body,
- bool fin,
- QuicAckNotifier::DelegateInterface* delegate);
+ ssize_t GetOrCreateStreamAndSendRequest(const BalsaHeaders* headers,
+ StringPiece body,
+ bool fin,
+ QuicAckListenerInterface* delegate);
QuicRstStreamErrorCode stream_error() { return stream_error_; }
QuicErrorCode connection_error();
@@ -170,12 +167,16 @@ class QuicTestClient : public SimpleClient,
// or the empty string if no certificate was presented.
const std::string& cert_common_name() const;
+ // cert_sct returns the signed timestamp of the server's certificate,
+ // or the empty string if no signed timestamp was presented.
+ const std::string& cert_sct() const;
+
// Get the server config map.
QuicTagValueMap GetServerConfig() const;
void set_auto_reconnect(bool reconnect) { auto_reconnect_ = reconnect; }
- void set_priority(QuicPriority priority) { priority_ = priority; }
+ void set_priority(SpdyPriority priority) { priority_ = priority; }
// Sets client's FEC policy. This policy applies to the data stream(s), and
// also to the headers and crypto streams.
@@ -185,10 +186,16 @@ class QuicTestClient : public SimpleClient,
EpollServer* epoll_server() { return &epoll_server_; }
+ void set_allow_bidirectional_data(bool value) {
+ allow_bidirectional_data_ = value;
+ }
+
+ bool allow_bidirectional_data() const { return allow_bidirectional_data_; }
+
protected:
QuicTestClient();
- void Initialize(bool secure);
+ void Initialize();
void set_client(MockableQuicClient* client) { client_.reset(client); }
@@ -199,7 +206,7 @@ class QuicTestClient : public SimpleClient,
StringPiece body,
bool fin,
QuicTestClient* test_client,
- QuicAckNotifier::DelegateInterface* delegate)
+ QuicAckListenerInterface* delegate)
: QuicClient::QuicDataToResend(headers, body, fin),
test_client_(test_client),
delegate_(delegate) {}
@@ -210,7 +217,7 @@ class QuicTestClient : public SimpleClient,
protected:
QuicTestClient* test_client_;
- QuicAckNotifier::DelegateInterface* delegate_;
+ QuicAckListenerInterface* delegate_;
};
// Given a uri, creates a simple HTTPMessage request message for testing.
@@ -225,17 +232,20 @@ class QuicTestClient : public SimpleClient,
bool response_complete_;
bool response_headers_complete_;
mutable BalsaHeaders headers_;
- QuicPriority priority_;
+
+ // Parsed response trailers (if present), copied from the stream in OnClose.
+ SpdyHeaderBlock response_trailers_;
+
+ SpdyPriority priority_;
std::string response_;
- uint64 bytes_read_;
- uint64 bytes_written_;
+ uint64_t bytes_read_;
+ uint64_t bytes_written_;
// The number of uncompressed HTTP header bytes received.
int response_header_size_;
// The number of HTTP body bytes received.
- int64 response_body_size_;
+ int64_t response_body_size_;
// True if we tried to connect already since the last call to Disconnect().
bool connect_attempted_;
- bool secure_;
// The client will auto-connect exactly once before sending data. If
// something causes a connection reset, it will not automatically reconnect
// unless auto_reconnect_ is true.
@@ -244,9 +254,9 @@ class QuicTestClient : public SimpleClient,
bool buffer_body_;
// FEC policy for data sent by this client.
FecPolicy fec_policy_;
- // proof_verifier_ points to a RecordingProofVerifier that is owned by
- // client_.
- ProofVerifier* proof_verifier_;
+ // When true allows the sending of a request to continue while the response is
+ // arriving.
+ bool allow_bidirectional_data_;
DISALLOW_COPY_AND_ASSIGN(QuicTestClient);
};
diff --git a/chromium/net/tools/quic/test_tools/quic_test_server.cc b/chromium/net/tools/quic/test_tools/quic_test_server.cc
new file mode 100644
index 00000000000..421952bc910
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_test_server.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2015 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/tools/quic/test_tools/quic_test_server.h"
+
+#include "base/logging.h"
+#include "base/run_loop.h"
+#include "base/synchronization/lock.h"
+#include "base/thread_task_runner_handle.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/quic/crypto/crypto_handshake.h"
+#include "net/quic/crypto/quic_crypto_server_config.h"
+#include "net/quic/crypto/quic_random.h"
+#include "net/quic/quic_chromium_connection_helper.h"
+#include "net/quic/quic_config.h"
+#include "net/quic/quic_connection.h"
+#include "net/quic/quic_packet_writer.h"
+#include "net/quic/quic_protocol.h"
+#include "net/tools/quic/quic_dispatcher.h"
+#include "net/tools/quic/quic_epoll_connection_helper.h"
+#include "net/tools/quic/quic_simple_server_session.h"
+#include "net/tools/quic/quic_simple_server_stream.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+class CustomStreamSession : public QuicSimpleServerSession {
+ public:
+ CustomStreamSession(
+ const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config,
+ QuicTestServer::StreamFactory* factory,
+ QuicTestServer::CryptoStreamFactory* crypto_stream_factory)
+ : QuicSimpleServerSession(config, connection, visitor, crypto_config),
+ stream_factory_(factory),
+ crypto_stream_factory_(crypto_stream_factory) {}
+
+ QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override {
+ if (!ShouldCreateIncomingDynamicStream(id)) {
+ return nullptr;
+ }
+ if (stream_factory_) {
+ return stream_factory_->CreateStream(id, this);
+ }
+ return QuicSimpleServerSession::CreateIncomingDynamicStream(id);
+ }
+
+ QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
+ const QuicCryptoServerConfig* crypto_config) override {
+ if (crypto_stream_factory_) {
+ return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
+ }
+ return QuicSimpleServerSession::CreateQuicCryptoServerStream(crypto_config);
+ }
+
+ private:
+ QuicTestServer::StreamFactory* stream_factory_; // Not owned.
+ QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
+};
+
+class QuicTestDispatcher : public QuicDispatcher {
+ public:
+ QuicTestDispatcher(const QuicConfig& config,
+ const QuicCryptoServerConfig* crypto_config,
+ const QuicVersionVector& versions,
+ QuicConnectionHelperInterface* helper)
+ : QuicDispatcher(config, crypto_config, versions, helper),
+ session_factory_(nullptr),
+ stream_factory_(nullptr),
+ crypto_stream_factory_(nullptr) {}
+
+ QuicServerSessionBase* CreateQuicSession(QuicConnectionId id,
+ const IPEndPoint& client) override {
+ base::AutoLock lock(factory_lock_);
+ if (session_factory_ == nullptr && stream_factory_ == nullptr &&
+ crypto_stream_factory_ == nullptr) {
+ return QuicDispatcher::CreateQuicSession(id, client);
+ }
+ QuicConnection* connection = new QuicConnection(
+ id, client, helper(), CreatePerConnectionWriter(),
+ /* owns_writer= */ true, Perspective::IS_SERVER, supported_versions());
+
+ QuicServerSessionBase* session = nullptr;
+ if (stream_factory_ != nullptr || crypto_stream_factory_ != nullptr) {
+ session =
+ new CustomStreamSession(config(), connection, this, crypto_config(),
+ stream_factory_, crypto_stream_factory_);
+ } else {
+ session = session_factory_->CreateSession(config(), connection, this,
+ crypto_config());
+ }
+ session->Initialize();
+ return session;
+ }
+
+ void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
+ base::AutoLock lock(factory_lock_);
+ DCHECK(session_factory_ == nullptr);
+ DCHECK(stream_factory_ == nullptr);
+ DCHECK(crypto_stream_factory_ == nullptr);
+ session_factory_ = factory;
+ }
+
+ void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
+ base::AutoLock lock(factory_lock_);
+ DCHECK(session_factory_ == nullptr);
+ DCHECK(stream_factory_ == nullptr);
+ stream_factory_ = factory;
+ }
+
+ void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
+ base::AutoLock lock(factory_lock_);
+ DCHECK(session_factory_ == nullptr);
+ DCHECK(crypto_stream_factory_ == nullptr);
+ crypto_stream_factory_ = factory;
+ }
+
+ private:
+ base::Lock factory_lock_;
+ QuicTestServer::SessionFactory* session_factory_; // Not owned.
+ QuicTestServer::StreamFactory* stream_factory_; // Not owned.
+ QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
+};
+
+QuicTestServer::QuicTestServer(ProofSource* proof_source)
+ : QuicServer(proof_source) {}
+
+QuicTestServer::QuicTestServer(ProofSource* proof_source,
+ const QuicConfig& config,
+ const QuicVersionVector& supported_versions)
+ : QuicServer(proof_source, config, supported_versions) {}
+
+QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
+ return new QuicTestDispatcher(config(), &crypto_config(),
+ supported_versions(),
+ new QuicEpollConnectionHelper(epoll_server()));
+}
+
+void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
+ DCHECK(dispatcher());
+ static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
+}
+
+void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
+ static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
+}
+
+void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
+ static_cast<QuicTestDispatcher*>(dispatcher())
+ ->SetCryptoStreamFactory(factory);
+}
+
+/////////////////////////// TEST SESSIONS ///////////////////////////////
+
+ImmediateGoAwaySession::ImmediateGoAwaySession(
+ const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config)
+ : QuicSimpleServerSession(config, connection, visitor, crypto_config) {
+ SendGoAway(QUIC_PEER_GOING_AWAY, "");
+}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_test_server.h b/chromium/net/tools/quic/test_tools/quic_test_server.h
new file mode 100644
index 00000000000..a38923ccbbb
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_test_server.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2015 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_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "net/base/ip_endpoint.h"
+#include "net/quic/quic_session.h"
+#include "net/tools/quic/quic_dispatcher.h"
+#include "net/tools/quic/quic_server.h"
+#include "net/tools/quic/quic_simple_server_session.h"
+#include "net/tools/quic/quic_simple_server_stream.h"
+
+namespace net {
+
+namespace tools {
+
+namespace test {
+
+// A test server which enables easy creation of custom QuicServerSessions
+//
+// Eventually this may be extended to allow custom QuicConnections etc.
+class QuicTestServer : public QuicServer {
+ public:
+ // Factory for creating QuicServerSessions.
+ class SessionFactory {
+ public:
+ virtual ~SessionFactory() {}
+
+ // Returns a new session owned by the caller.
+ virtual QuicServerSessionBase* CreateSession(
+ const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config) = 0;
+ };
+
+ // Factory for creating QuicSimpleServerStreams.
+ class StreamFactory {
+ public:
+ virtual ~StreamFactory() {}
+
+ // Returns a new stream owned by the caller.
+ virtual QuicSimpleServerStream* CreateStream(QuicStreamId id,
+ QuicSpdySession* session) = 0;
+ };
+
+ class CryptoStreamFactory {
+ public:
+ virtual ~CryptoStreamFactory() {}
+
+ // Returns a new QuicCryptoServerStreamBase owned by the caller
+ virtual QuicCryptoServerStreamBase* CreateCryptoStream(
+ const QuicCryptoServerConfig* crypto_config,
+ QuicSpdySession* session) = 0;
+ };
+
+ explicit QuicTestServer(ProofSource* proof_source);
+ QuicTestServer(ProofSource* proof_source,
+ const QuicConfig& config,
+ const QuicVersionVector& supported_versions);
+
+ // Create a custom dispatcher which creates custom sessions.
+ QuicDispatcher* CreateQuicDispatcher() override;
+
+ // Sets a custom session factory, owned by the caller, for easy custom
+ // session logic. This is incompatible with setting a stream factory or a
+ // crypto stream factory.
+ void SetSessionFactory(SessionFactory* factory);
+
+ // Sets a custom stream factory, owned by the caller, for easy custom
+ // stream logic. This is incompatible with setting a session factory.
+ void SetSpdyStreamFactory(StreamFactory* factory);
+
+ // Sets a custom crypto stream factory, owned by the caller, for easy custom
+ // crypto logic. This is incompatible with setting a session factory.
+ void SetCryptoStreamFactory(CryptoStreamFactory* factory);
+};
+
+// Useful test sessions for the QuicTestServer.
+
+// Test session which sends a GOAWAY immedaitely on creation, before crypto
+// credentials have even been established.
+class ImmediateGoAwaySession : public QuicSimpleServerSession {
+ public:
+ ImmediateGoAwaySession(const QuicConfig& config,
+ QuicConnection* connection,
+ QuicServerSessionVisitor* visitor,
+ const QuicCryptoServerConfig* crypto_config);
+};
+
+} // namespace test
+
+} // namespace tools
+
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
diff --git a/chromium/net/tools/quic/test_tools/server_thread.cc b/chromium/net/tools/quic/test_tools/server_thread.cc
index 09cba688edc..4ca948980d5 100644
--- a/chromium/net/tools/quic/test_tools/server_thread.cc
+++ b/chromium/net/tools/quic/test_tools/server_thread.cc
@@ -13,7 +13,6 @@ namespace tools {
namespace test {
ServerThread::ServerThread(QuicServer* server,
- bool is_secure,
const IPEndPoint& address,
bool strike_register_no_startup_period)
: SimpleThread("server_thread"),
@@ -29,12 +28,6 @@ ServerThread::ServerThread(QuicServer* server,
if (strike_register_no_startup_period) {
server_->SetStrikeRegisterNoStartupPeriod();
}
- if (is_secure) {
- // TODO(rtenneti): replace this with ProofSourceForTesting() when Chromium
- // has a working ProofSourceForTesting().
- server_->SetProofSource(
- net::test::CryptoTestUtils::FakeProofSourceForTesting());
- }
}
ServerThread::~ServerThread() {}
diff --git a/chromium/net/tools/quic/test_tools/server_thread.h b/chromium/net/tools/quic/test_tools/server_thread.h
index b017440506a..e6cb97d24ac 100644
--- a/chromium/net/tools/quic/test_tools/server_thread.h
+++ b/chromium/net/tools/quic/test_tools/server_thread.h
@@ -5,6 +5,7 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_SERVER_THREAD_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_SERVER_THREAD_H_
+#include "base/macros.h"
#include "base/threading/simple_thread.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_config.h"
@@ -18,7 +19,6 @@ namespace test {
class ServerThread : public base::SimpleThread {
public:
ServerThread(QuicServer* server,
- bool is_secure,
const IPEndPoint& address,
bool strike_register_no_startup_period);
diff --git a/chromium/net/tools/quic/test_tools/simple_client.cc b/chromium/net/tools/quic/test_tools/simple_client.cc
index 46f5b9d6877..8d3d51b3139 100644
--- a/chromium/net/tools/quic/test_tools/simple_client.cc
+++ b/chromium/net/tools/quic/test_tools/simple_client.cc
@@ -27,9 +27,13 @@ int SimpleClient::HalfClose() {
return 0;
}
-int SimpleClient::response_header_size() const { return 0; }
+int SimpleClient::response_header_size() const {
+ return 0;
+}
-int64 SimpleClient::response_body_size() const { return 0; }
+int64_t SimpleClient::response_body_size() const {
+ return 0;
+}
} // namespace net
} // namespace tools
diff --git a/chromium/net/tools/quic/test_tools/simple_client.h b/chromium/net/tools/quic/test_tools/simple_client.h
index b483491387f..322210129db 100644
--- a/chromium/net/tools/quic/test_tools/simple_client.h
+++ b/chromium/net/tools/quic/test_tools/simple_client.h
@@ -5,6 +5,9 @@
#ifndef NET_TOOLS_QUIC_TEST_TOOLS_SIMPLE_CLIENT_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_SIMPLE_CLIENT_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -25,14 +28,14 @@ class SimpleClient {
// server, possibly with multiple send operations. Returns 'size' on success
// and -1 on error. Callers should assume that any return value other than
// 'size' indicates failure.
- virtual ssize_t Send(const void *buffer, size_t size) = 0;
+ virtual ssize_t Send(const void* buffer, size_t size) = 0;
// Serialize and send an HTTP request.
virtual ssize_t SendMessage(const HTTPMessage& message) = 0;
// Clears any outstanding state, sends 'size' bytes from 'buffer' and waits
// for a response or an error.
- virtual ssize_t SendAndWaitForResponse(const void *buffer, size_t size) = 0;
+ virtual ssize_t SendAndWaitForResponse(const void* buffer, size_t size) = 0;
// Clears any outstanding state and sends a simple GET of 'uri' to the
// server.
@@ -115,7 +118,7 @@ class SimpleClient {
virtual bool response_complete() const = 0;
// Returns the number of bytes read from the server during this request.
- virtual int64 response_size() const = 0;
+ virtual int64_t response_size() const = 0;
// Returns the number of header bytes received during this request, if
// meaningful for the protocol.
@@ -123,7 +126,7 @@ class SimpleClient {
// Returns the number of body bytes received during this request, if
// meaningful for the protocol.
- virtual int64 response_body_size() const;
+ virtual int64_t response_body_size() const;
// Returns the response body, if there was one. If there was no response, or
// if buffer_body() is false, returns an empty string.
diff --git a/chromium/net/tools/stress_cache/stress_cache.cc b/chromium/net/tools/stress_cache/stress_cache.cc
index 29ddff29a38..0ba3ff75eb2 100644
--- a/chromium/net/tools/stress_cache/stress_cache.cc
+++ b/chromium/net/tools/stress_cache/stress_cache.cc
@@ -296,7 +296,7 @@ void LoopTask() {
// to know which instance of the application wrote them.
void StressTheCache(int iteration) {
int cache_size = 0x2000000; // 32MB.
- uint32 mask = 0xfff; // 4096 entries.
+ uint32_t mask = 0xfff; // 4096 entries.
base::FilePath path;
PathService::Get(base::DIR_TEMP, &path);
diff --git a/chromium/net/tools/testserver/testserver.isolate b/chromium/net/tools/testserver/testserver.isolate
new file mode 100644
index 00000000000..edece5e2d0f
--- /dev/null
+++ b/chromium/net/tools/testserver/testserver.isolate
@@ -0,0 +1,15 @@
+# Copyright 2015 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.
+{
+ 'variables': {
+ 'files': [
+ './',
+ '../../../testing/test_env.py',
+ '../../../third_party/pyftpdlib/',
+ '../../../third_party/pywebsocket/',
+ '../../../third_party/tlslite/',
+ '<(PRODUCT_DIR)/pyproto/google/',
+ ]
+ }
+}
diff --git a/chromium/net/tools/testserver/testserver.py b/chromium/net/tools/testserver/testserver.py
index 7919f87b8f0..15317657d08 100755
--- a/chromium/net/tools/testserver/testserver.py
+++ b/chromium/net/tools/testserver/testserver.py
@@ -343,7 +343,6 @@ class TestPageHandler(testserver_base.BasePageHandler):
self.GetClientCert,
self.ClientCipherListHandler,
self.CloseSocketHandler,
- self.RangeResetHandler,
self.DefaultResponseHandler]
post_handlers = [
self.EchoTitleHandler,
@@ -1560,154 +1559,6 @@ class TestPageHandler(testserver_base.BasePageHandler):
self.wfile.close()
return True
- def RangeResetHandler(self):
- """Send data broken up by connection resets every N (default 4K) bytes.
- Support range requests. If the data requested doesn't straddle a reset
- boundary, it will all be sent. Used for testing resuming downloads."""
-
- def DataForRange(start, end):
- """Data to be provided for a particular range of bytes."""
- # Offset and scale to avoid too obvious (and hence potentially
- # collidable) data.
- return ''.join([chr(y % 256)
- for y in range(start * 2 + 15, end * 2 + 15, 2)])
-
- if not self._ShouldHandleRequest('/rangereset'):
- return False
-
- # HTTP/1.1 is required for ETag and range support.
- self.protocol_version = 'HTTP/1.1'
- _, _, url_path, _, query, _ = urlparse.urlparse(self.path)
-
- # Defaults
- size = 8000
- # Note that the rst is sent just before sending the rst_boundary byte.
- rst_boundary = 4000
- respond_to_range = True
- hold_for_signal = False
- rst_limit = -1
- token = 'DEFAULT'
- fail_precondition = 0
- send_verifiers = True
-
- # Parse the query
- qdict = urlparse.parse_qs(query, True)
- if 'size' in qdict:
- size = int(qdict['size'][0])
- if 'rst_boundary' in qdict:
- rst_boundary = int(qdict['rst_boundary'][0])
- if 'token' in qdict:
- # Identifying token for stateful tests.
- token = qdict['token'][0]
- if 'rst_limit' in qdict:
- # Max number of rsts for a given token.
- rst_limit = int(qdict['rst_limit'][0])
- if 'bounce_range' in qdict:
- respond_to_range = False
- if 'hold' in qdict:
- # Note that hold_for_signal will not work with null range requests;
- # see TODO below.
- hold_for_signal = True
- if 'no_verifiers' in qdict:
- send_verifiers = False
- if 'fail_precondition' in qdict:
- fail_precondition = int(qdict['fail_precondition'][0])
-
- # Record already set information, or set it.
- rst_limit = TestPageHandler.rst_limits.setdefault(token, rst_limit)
- if rst_limit != 0:
- TestPageHandler.rst_limits[token] -= 1
- fail_precondition = TestPageHandler.fail_precondition.setdefault(
- token, fail_precondition)
- if fail_precondition != 0:
- TestPageHandler.fail_precondition[token] -= 1
-
- first_byte = 0
- last_byte = size - 1
-
- # Does that define what we want to return, or do we need to apply
- # a range?
- range_response = False
- range_header = self.headers.getheader('range')
- if range_header and respond_to_range:
- mo = re.match("bytes=(\d*)-(\d*)", range_header)
- if mo.group(1):
- first_byte = int(mo.group(1))
- if mo.group(2):
- last_byte = int(mo.group(2))
- if last_byte > size - 1:
- last_byte = size - 1
- range_response = True
- if last_byte < first_byte:
- return False
-
- if (fail_precondition and
- (self.headers.getheader('If-Modified-Since') or
- self.headers.getheader('If-Match'))):
- self.send_response(412)
- self.end_headers()
- return True
-
- if range_response:
- self.send_response(206)
- self.send_header('Content-Range',
- 'bytes %d-%d/%d' % (first_byte, last_byte, size))
- else:
- self.send_response(200)
- self.send_header('Content-Type', 'application/octet-stream')
- self.send_header('Content-Length', last_byte - first_byte + 1)
- if send_verifiers:
- # If fail_precondition is non-zero, then the ETag for each request will be
- # different.
- etag = "%s%d" % (token, fail_precondition)
- self.send_header('ETag', etag)
- self.send_header('Last-Modified', 'Tue, 19 Feb 2013 14:32 EST')
- self.end_headers()
-
- if hold_for_signal:
- # TODO(rdsmith/phajdan.jr): http://crbug.com/169519: Without writing
- # a single byte, the self.server.handle_request() below hangs
- # without processing new incoming requests.
- self.wfile.write(DataForRange(first_byte, first_byte + 1))
- first_byte = first_byte + 1
- # handle requests until one of them clears this flag.
- self.server.wait_for_download = True
- while self.server.wait_for_download:
- self.server.handle_request()
-
- possible_rst = ((first_byte / rst_boundary) + 1) * rst_boundary
- if possible_rst >= last_byte or rst_limit == 0:
- # No RST has been requested in this range, so we don't need to
- # do anything fancy; just write the data and let the python
- # infrastructure close the connection.
- self.wfile.write(DataForRange(first_byte, last_byte + 1))
- self.wfile.flush()
- return True
-
- # We're resetting the connection part way in; go to the RST
- # boundary and then send an RST.
- # Because socket semantics do not guarantee that all the data will be
- # sent when using the linger semantics to hard close a socket,
- # we send the data and then wait for our peer to release us
- # before sending the reset.
- data = DataForRange(first_byte, possible_rst)
- self.wfile.write(data)
- self.wfile.flush()
- self.server.wait_for_download = True
- while self.server.wait_for_download:
- self.server.handle_request()
- l_onoff = 1 # Linger is active.
- l_linger = 0 # Seconds to linger for.
- self.connection.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
- struct.pack('ii', l_onoff, l_linger))
-
- # Close all duplicates of the underlying socket to force the RST.
- self.wfile.close()
- self.rfile.close()
- self.connection.close()
-
- return True
-
def DefaultResponseHandler(self):
"""This is the catch-all response handler for requests that aren't handled
by one of the special handlers above.
diff --git a/chromium/net/udp/datagram_client_socket.h b/chromium/net/udp/datagram_client_socket.h
index c2c2cba4d07..e8d54c18d51 100644
--- a/chromium/net/udp/datagram_client_socket.h
+++ b/chromium/net/udp/datagram_client_socket.h
@@ -5,6 +5,7 @@
#ifndef NET_UDP_DATAGRAM_CLIENT_SOCKET_H_
#define NET_UDP_DATAGRAM_CLIENT_SOCKET_H_
+#include "net/base/network_change_notifier.h"
#include "net/socket/socket.h"
#include "net/udp/datagram_socket.h"
@@ -17,6 +18,22 @@ class NET_EXPORT_PRIVATE DatagramClientSocket : public DatagramSocket,
public:
~DatagramClientSocket() override {}
+ // Binds this socket to |network|. All data traffic on the socket will be sent
+ // and received via |network|. Must be called before Connect(). This call will
+ // fail if |network| has disconnected. Communication using this socket will
+ // fail if |network| disconnects.
+ // Returns a net error code.
+ virtual int BindToNetwork(NetworkChangeNotifier::NetworkHandle network) = 0;
+
+ // Same as BindToNetwork, except that the current default network is used.
+ // Returns a net error code.
+ virtual int BindToDefaultNetwork() = 0;
+
+ // Returns the network that either BindToNetwork() or BindToDefaultNetwork()
+ // bound this socket to. Returns NetworkChangeNotifier::kInvalidNetworkHandle
+ // if not explicitly bound via BindToNetwork() or BindToDefaultNetwork().
+ virtual NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const = 0;
+
// Initialize this socket as a client socket to server at |address|.
// Returns a network error code.
virtual int Connect(const IPEndPoint& address) = 0;
diff --git a/chromium/net/udp/datagram_server_socket.h b/chromium/net/udp/datagram_server_socket.h
index d3796c36328..1dd444f444c 100644
--- a/chromium/net/udp/datagram_server_socket.h
+++ b/chromium/net/udp/datagram_server_socket.h
@@ -5,9 +5,11 @@
#ifndef NET_UDP_DATAGRAM_SERVER_SOCKET_H_
#define NET_UDP_DATAGRAM_SERVER_SOCKET_H_
+#include <stdint.h>
+
#include "net/base/completion_callback.h"
-#include "net/base/net_util.h"
#include "net/udp/datagram_socket.h"
+#include "net/udp/diff_serv_code_point.h"
namespace net {
@@ -57,11 +59,11 @@ class NET_EXPORT DatagramServerSocket : public DatagramSocket {
// Set the receive buffer size (in bytes) for the socket.
// Returns a net error code.
- virtual int SetReceiveBufferSize(int32 size) = 0;
+ virtual int SetReceiveBufferSize(int32_t size) = 0;
// Set the send buffer size (in bytes) for the socket.
// Returns a net error code.
- virtual int SetSendBufferSize(int32 size) = 0;
+ virtual int SetSendBufferSize(int32_t size) = 0;
// Allow the socket to share the local address to which the socket will
// be bound with other processes. Should be called before Listen().
@@ -86,7 +88,7 @@ class NET_EXPORT DatagramServerSocket : public DatagramSocket {
// interface is used.
// Should be called before Bind().
// Returns a network error code.
- virtual int SetMulticastInterface(uint32 interface_index) = 0;
+ virtual int SetMulticastInterface(uint32_t interface_index) = 0;
// Set the time-to-live option for UDP packets sent to the multicast
// group address. The default value of this option is 1.
diff --git a/chromium/net/udp/diff_serv_code_point.h b/chromium/net/udp/diff_serv_code_point.h
new file mode 100644
index 00000000000..f4a878635f2
--- /dev/null
+++ b/chromium/net/udp/diff_serv_code_point.h
@@ -0,0 +1,42 @@
+// Copyright 2015 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_UDP_DIFF_SERV_CODE_POINT_H_
+#define NET_UDP_DIFF_SERV_CODE_POINT_H_
+
+namespace net {
+
+// Differentiated Services Code Point.
+// See http://tools.ietf.org/html/rfc2474 for details.
+enum DiffServCodePoint {
+ DSCP_NO_CHANGE = -1,
+ DSCP_FIRST = DSCP_NO_CHANGE,
+ DSCP_DEFAULT = 0, // Same as DSCP_CS0
+ DSCP_CS0 = 0, // The default
+ DSCP_CS1 = 8, // Bulk/background traffic
+ DSCP_AF11 = 10,
+ DSCP_AF12 = 12,
+ DSCP_AF13 = 14,
+ DSCP_CS2 = 16,
+ DSCP_AF21 = 18,
+ DSCP_AF22 = 20,
+ DSCP_AF23 = 22,
+ DSCP_CS3 = 24,
+ DSCP_AF31 = 26,
+ DSCP_AF32 = 28,
+ DSCP_AF33 = 30,
+ DSCP_CS4 = 32,
+ DSCP_AF41 = 34, // Video
+ DSCP_AF42 = 36, // Video
+ DSCP_AF43 = 38, // Video
+ DSCP_CS5 = 40, // Video
+ DSCP_EF = 46, // Voice
+ DSCP_CS6 = 48, // Voice
+ DSCP_CS7 = 56, // Control messages
+ DSCP_LAST = DSCP_CS7
+};
+
+} // namespace net
+
+#endif // NET_UDP_DIFF_SERV_CODE_POINT_H_
diff --git a/chromium/net/udp/udp_client_socket.cc b/chromium/net/udp/udp_client_socket.cc
index 5b7639f0b82..7559c77f9ee 100644
--- a/chromium/net/udp/udp_client_socket.cc
+++ b/chromium/net/udp/udp_client_socket.cc
@@ -13,12 +13,50 @@ UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type,
const RandIntCallback& rand_int_cb,
net::NetLog* net_log,
const net::NetLog::Source& source)
- : socket_(bind_type, rand_int_cb, net_log, source) {
-}
+ : socket_(bind_type, rand_int_cb, net_log, source),
+ network_(NetworkChangeNotifier::kInvalidNetworkHandle) {}
UDPClientSocket::~UDPClientSocket() {
}
+int UDPClientSocket::BindToNetwork(
+ NetworkChangeNotifier::NetworkHandle network) {
+ int rv = socket_.BindToNetwork(network);
+ if (rv == OK)
+ network_ = network;
+ return rv;
+}
+
+int UDPClientSocket::BindToDefaultNetwork() {
+ if (!NetworkChangeNotifier::AreNetworkHandlesSupported())
+ return ERR_NOT_IMPLEMENTED;
+ int rv;
+ // Calling connect() will bind a socket to the default network, however there
+ // is no way to determine what network the socket got bound to. The
+ // alternative is to query what the default network is and bind the socket to
+ // that network explicitly, however this is racy because the default network
+ // can change in between when we query it and when we bind to it. This is
+ // rare but should be accounted for. Since changes of the default network
+ // should not come in quick succession, we can simply try again.
+ for (int attempt = 0; attempt < 2; attempt++) {
+ NetworkChangeNotifier::NetworkHandle network =
+ NetworkChangeNotifier::GetDefaultNetwork();
+ if (network == NetworkChangeNotifier::kInvalidNetworkHandle)
+ return ERR_INTERNET_DISCONNECTED;
+ rv = BindToNetwork(network);
+ // |network| may have disconnected between the call to GetDefaultNetwork()
+ // and the call to BindToNetwork(). Loop if this is the case (|rv| will be
+ // ERR_NETWORK_CHANGED).
+ if (rv != ERR_NETWORK_CHANGED)
+ return rv;
+ }
+ return rv;
+}
+
+NetworkChangeNotifier::NetworkHandle UDPClientSocket::GetBoundNetwork() const {
+ return network_;
+}
+
int UDPClientSocket::Connect(const IPEndPoint& address) {
int rv = socket_.Open(address.GetFamily());
if (rv != OK)
@@ -50,11 +88,11 @@ int UDPClientSocket::GetLocalAddress(IPEndPoint* address) const {
return socket_.GetLocalAddress(address);
}
-int UDPClientSocket::SetReceiveBufferSize(int32 size) {
+int UDPClientSocket::SetReceiveBufferSize(int32_t size) {
return socket_.SetReceiveBufferSize(size);
}
-int UDPClientSocket::SetSendBufferSize(int32 size) {
+int UDPClientSocket::SetSendBufferSize(int32_t size) {
return socket_.SetSendBufferSize(size);
}
diff --git a/chromium/net/udp/udp_client_socket.h b/chromium/net/udp/udp_client_socket.h
index 50a1b29d709..99b9fe601af 100644
--- a/chromium/net/udp/udp_client_socket.h
+++ b/chromium/net/udp/udp_client_socket.h
@@ -5,6 +5,9 @@
#ifndef NET_SOCKET_UDP_CLIENT_SOCKET_H_
#define NET_SOCKET_UDP_CLIENT_SOCKET_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/base/rand_callback.h"
#include "net/log/net_log.h"
#include "net/udp/datagram_client_socket.h"
@@ -24,6 +27,9 @@ class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
~UDPClientSocket() override;
// DatagramClientSocket implementation.
+ int BindToNetwork(NetworkChangeNotifier::NetworkHandle network) override;
+ int BindToDefaultNetwork() override;
+ NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override;
int Connect(const IPEndPoint& address) override;
int Read(IOBuffer* buf,
int buf_len,
@@ -34,8 +40,8 @@ class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
void Close() override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
const BoundNetLog& NetLog() const override;
#if defined(OS_WIN)
@@ -46,6 +52,7 @@ class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
private:
UDPSocket socket_;
+ NetworkChangeNotifier::NetworkHandle network_;
DISALLOW_COPY_AND_ASSIGN(UDPClientSocket);
};
diff --git a/chromium/net/udp/udp_net_log_parameters.cc b/chromium/net/udp/udp_net_log_parameters.cc
index 423f074605c..d157fe83667 100644
--- a/chromium/net/udp/udp_net_log_parameters.cc
+++ b/chromium/net/udp/udp_net_log_parameters.cc
@@ -4,6 +4,8 @@
#include "net/udp/udp_net_log_parameters.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
@@ -24,7 +26,7 @@ scoped_ptr<base::Value> NetLogUDPDataTranferCallback(
dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, byte_count));
if (address)
dict->SetString("address", address->ToString());
- return dict.Pass();
+ return std::move(dict);
}
scoped_ptr<base::Value> NetLogUDPConnectCallback(
@@ -32,7 +34,7 @@ scoped_ptr<base::Value> NetLogUDPConnectCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("address", address->ToString());
- return dict.Pass();
+ return std::move(dict);
}
} // namespace
diff --git a/chromium/net/udp/udp_server_socket.cc b/chromium/net/udp/udp_server_socket.cc
index 9fc92df0659..8cda8d40017 100644
--- a/chromium/net/udp/udp_server_socket.cc
+++ b/chromium/net/udp/udp_server_socket.cc
@@ -60,11 +60,11 @@ int UDPServerSocket::SendTo(IOBuffer* buf,
return socket_.SendTo(buf, buf_len, address, callback);
}
-int UDPServerSocket::SetReceiveBufferSize(int32 size) {
+int UDPServerSocket::SetReceiveBufferSize(int32_t size) {
return socket_.SetReceiveBufferSize(size);
}
-int UDPServerSocket::SetSendBufferSize(int32 size) {
+int UDPServerSocket::SetSendBufferSize(int32_t size) {
return socket_.SetSendBufferSize(size);
}
@@ -100,7 +100,7 @@ int UDPServerSocket::LeaveGroup(const IPAddressNumber& group_address) const {
return socket_.LeaveGroup(group_address);
}
-int UDPServerSocket::SetMulticastInterface(uint32 interface_index) {
+int UDPServerSocket::SetMulticastInterface(uint32_t interface_index) {
return socket_.SetMulticastInterface(interface_index);
}
diff --git a/chromium/net/udp/udp_server_socket.h b/chromium/net/udp/udp_server_socket.h
index dabb8f0b100..668ebcc4b2d 100644
--- a/chromium/net/udp/udp_server_socket.h
+++ b/chromium/net/udp/udp_server_socket.h
@@ -5,8 +5,11 @@
#ifndef NET_SOCKET_UDP_SERVER_SOCKET_H_
#define NET_SOCKET_UDP_SERVER_SOCKET_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "net/base/completion_callback.h"
-#include "net/base/net_util.h"
+#include "net/base/ip_address_number.h"
#include "net/udp/datagram_server_socket.h"
#include "net/udp/udp_socket.h"
@@ -31,8 +34,8 @@ class NET_EXPORT UDPServerSocket : public DatagramServerSocket {
int buf_len,
const IPEndPoint& address,
const CompletionCallback& callback) override;
- int SetReceiveBufferSize(int32 size) override;
- int SetSendBufferSize(int32 size) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
void Close() override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
@@ -41,7 +44,7 @@ class NET_EXPORT UDPServerSocket : public DatagramServerSocket {
void AllowBroadcast() override;
int JoinGroup(const IPAddressNumber& group_address) const override;
int LeaveGroup(const IPAddressNumber& group_address) const override;
- int SetMulticastInterface(uint32 interface_index) override;
+ int SetMulticastInterface(uint32_t interface_index) override;
int SetMulticastTimeToLive(int time_to_live) override;
int SetMulticastLoopbackMode(bool loopback) override;
int SetDiffServCodePoint(DiffServCodePoint dscp) override;
diff --git a/chromium/net/udp/udp_socket_perftest.cc b/chromium/net/udp/udp_socket_perftest.cc
index 6816c57cecb..066ec28bb06 100644
--- a/chromium/net/udp/udp_socket_perftest.cc
+++ b/chromium/net/udp/udp_socket_perftest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -53,7 +52,7 @@ class UDPSocketPerfTest : public PlatformTest {
// Creates and address from an ip/port and returns it in |address|.
void CreateUDPAddress(const std::string& ip_str,
- uint16 port,
+ uint16_t port,
IPEndPoint* address) {
IPAddressNumber ip_number;
bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
@@ -86,7 +85,7 @@ void UDPSocketPerfTest::WritePacketsToSocket(UDPClientSocket* socket,
void UDPSocketPerfTest::WriteBenchmark(bool use_nonblocking_io) {
base::MessageLoopForIO message_loop;
- const uint16 kPort = 9999;
+ const uint16_t kPort = 9999;
// Setup the server to listen.
IPEndPoint bind_address;
diff --git a/chromium/net/udp/udp_socket_posix.cc b/chromium/net/udp/udp_socket_posix.cc
index 3b60bf214cc..ea1a560289e 100644
--- a/chromium/net/udp/udp_socket_posix.cc
+++ b/chromium/net/udp/udp_socket_posix.cc
@@ -14,6 +14,7 @@
#include "base/callback.h"
#include "base/debug/alias.h"
+#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/sparse_histogram.h"
@@ -22,12 +23,17 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "net/base/network_activity_monitor.h"
+#include "net/base/sockaddr_storage.h"
#include "net/log/net_log.h"
#include "net/socket/socket_descriptor.h"
#include "net/udp/udp_net_log_parameters.h"
+#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
+#include "base/native_library.h"
+#include "base/strings/utf_string_conversions.h"
+#endif
namespace net {
@@ -40,7 +46,7 @@ const int kPortEnd = 65535;
#if defined(OS_MACOSX)
// Returns IPv4 address in network order.
-int GetIPv4AddressFromIndex(int socket, uint32 index, uint32* address){
+int GetIPv4AddressFromIndex(int socket, uint32_t index, uint32_t* address) {
if (!index) {
*address = htonl(INADDR_ANY);
return OK;
@@ -97,7 +103,7 @@ int UDPSocketPosix::Open(AddressFamily address_family) {
socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0);
if (socket_ == kInvalidSocket)
return MapSystemError(errno);
- if (SetNonBlocking(socket_)) {
+ if (!base::SetNonBlocking(socket_)) {
const int err = MapSystemError(errno);
Close();
return err;
@@ -319,7 +325,51 @@ int UDPSocketPosix::Bind(const IPEndPoint& address) {
return rv;
}
-int UDPSocketPosix::SetReceiveBufferSize(int32 size) {
+int UDPSocketPosix::BindToNetwork(
+ NetworkChangeNotifier::NetworkHandle network) {
+ DCHECK_NE(socket_, kInvalidSocket);
+ DCHECK(CalledOnValidThread());
+ DCHECK(!is_connected());
+ if (network == NetworkChangeNotifier::kInvalidNetworkHandle)
+ return ERR_INVALID_ARGUMENT;
+#if defined(OS_ANDROID)
+ // Android prior to Lollipop didn't have support for binding sockets to
+ // networks.
+ if (base::android::BuildInfo::GetInstance()->sdk_int() <
+ base::android::SDK_VERSION_LOLLIPOP) {
+ return ERR_NOT_IMPLEMENTED;
+ }
+ // NOTE(pauljensen): This does rely on Android implementation details, but
+ // these details are unlikely to change.
+ typedef int (*SetNetworkForSocket)(unsigned netId, int socketFd);
+ static SetNetworkForSocket setNetworkForSocket;
+ // This is racy, but all racers should come out with the same answer so it
+ // shouldn't matter.
+ if (setNetworkForSocket == nullptr) {
+ // Android's netd client library should always be loaded in our address
+ // space as it shims libc functions like connect().
+ base::FilePath file(base::FilePath::FromUTF16Unsafe(
+ base::GetNativeLibraryName(base::ASCIIToUTF16("netd_client"))));
+ base::NativeLibrary lib = base::LoadNativeLibrary(file, nullptr);
+ setNetworkForSocket = reinterpret_cast<SetNetworkForSocket>(
+ base::GetFunctionPointerFromNativeLibrary(lib, "setNetworkForSocket"));
+ }
+ if (setNetworkForSocket == nullptr)
+ return ERR_NOT_IMPLEMENTED;
+ int rv = setNetworkForSocket(network, socket_);
+ // If |network| has since disconnected, |rv| will be ENONET. Surface this as
+ // ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
+ // the less descriptive ERR_FAILED.
+ if (rv == ENONET)
+ return ERR_NETWORK_CHANGED;
+ return MapSystemError(rv);
+#else
+ NOTIMPLEMENTED();
+ return ERR_NOT_IMPLEMENTED;
+#endif
+}
+
+int UDPSocketPosix::SetReceiveBufferSize(int32_t size) {
DCHECK_NE(socket_, kInvalidSocket);
DCHECK(CalledOnValidThread());
int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
@@ -327,7 +377,7 @@ int UDPSocketPosix::SetReceiveBufferSize(int32 size) {
return rv == 0 ? OK : MapSystemError(errno);
}
-int UDPSocketPosix::SetSendBufferSize(int32 size) {
+int UDPSocketPosix::SetSendBufferSize(int32_t size) {
DCHECK_NE(socket_, kInvalidSocket);
DCHECK(CalledOnValidThread());
int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
@@ -567,7 +617,7 @@ int UDPSocketPosix::SetMulticastOptions() {
break;
}
case AF_INET6: {
- uint32 interface_index = multicast_interface_;
+ uint32_t interface_index = multicast_interface_;
int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF,
reinterpret_cast<const char*>(&interface_index),
sizeof(interface_index));
@@ -697,7 +747,7 @@ int UDPSocketPosix::LeaveGroup(const IPAddressNumber& group_address) const {
}
}
-int UDPSocketPosix::SetMulticastInterface(uint32 interface_index) {
+int UDPSocketPosix::SetMulticastInterface(uint32_t interface_index) {
DCHECK(CalledOnValidThread());
if (is_connected())
return ERR_SOCKET_IS_CONNECTED;
diff --git a/chromium/net/udp/udp_socket_posix.h b/chromium/net/udp/udp_socket_posix.h
index e27c2f4703a..2219f2e6aa5 100644
--- a/chromium/net/udp/udp_socket_posix.h
+++ b/chromium/net/udp/udp_socket_posix.h
@@ -5,6 +5,9 @@
#ifndef NET_UDP_UDP_SOCKET_POSIX_H_
#define NET_UDP_UDP_SOCKET_POSIX_H_
+#include <stdint.h>
+
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -14,11 +17,12 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
-#include "net/base/net_util.h"
+#include "net/base/network_change_notifier.h"
#include "net/base/rand_callback.h"
#include "net/log/net_log.h"
#include "net/socket/socket_descriptor.h"
#include "net/udp/datagram_socket.h"
+#include "net/udp/diff_serv_code_point.h"
namespace net {
@@ -34,6 +38,13 @@ class NET_EXPORT UDPSocketPosix : public base::NonThreadSafe {
// Returns a net error code.
int Open(AddressFamily address_family);
+ // Binds this socket to |network|. All data traffic on the socket will be sent
+ // and received via |network|. Must be called before Connect(). This call will
+ // fail if |network| has disconnected. Communication using this socket will
+ // fail if |network| disconnects.
+ // Returns a net error code.
+ int BindToNetwork(NetworkChangeNotifier::NetworkHandle network);
+
// Connects the socket to connect with a certain |address|.
// Should be called after Open().
// Returns a net error code.
@@ -103,11 +114,11 @@ class NET_EXPORT UDPSocketPosix : public base::NonThreadSafe {
// Sets the receive buffer size (in bytes) for the socket.
// Returns a net error code.
- int SetReceiveBufferSize(int32 size);
+ int SetReceiveBufferSize(int32_t size);
// Sets the send buffer size (in bytes) for the socket.
// Returns a net error code.
- int SetSendBufferSize(int32 size);
+ int SetSendBufferSize(int32_t size);
// Returns true if the socket is already connected or bound.
bool is_connected() const { return is_connected_; }
@@ -144,7 +155,7 @@ class NET_EXPORT UDPSocketPosix : public base::NonThreadSafe {
// default interface is used.
// Should be called before Bind().
// Returns a net error code.
- int SetMulticastInterface(uint32 interface_index);
+ int SetMulticastInterface(uint32_t interface_index);
// Sets the time-to-live option for UDP packets sent to the multicast
// group address. The default value of this option is 1.
@@ -256,7 +267,7 @@ class NET_EXPORT UDPSocketPosix : public base::NonThreadSafe {
int socket_options_;
// Multicast interface.
- uint32 multicast_interface_;
+ uint32_t multicast_interface_;
// Multicast socket options cached for SetMulticastOption.
// Cannot be used after Bind().
diff --git a/chromium/net/udp/udp_socket_unittest.cc b/chromium/net/udp/udp_socket_unittest.cc
index 0a0a855425c..4bd8a9ece0d 100644
--- a/chromium/net/udp/udp_socket_unittest.cc
+++ b/chromium/net/udp/udp_socket_unittest.cc
@@ -7,9 +7,9 @@
#include "net/udp/udp_client_socket.h"
#include "net/udp/udp_server_socket.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -27,6 +27,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
+#if defined(OS_IOS)
+#include <TargetConditionals.h>
+#endif
+
namespace net {
namespace {
@@ -123,7 +127,7 @@ class UDPSocketTest : public PlatformTest {
// Creates an address from ip address and port and writes it to |*address|.
void CreateUDPAddress(const std::string& ip_str,
- uint16 port,
+ uint16_t port,
IPEndPoint* address) {
IPAddressNumber ip_number;
bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
@@ -149,7 +153,7 @@ void ReadCompleteCallback(int* result_out, base::Closure callback, int result) {
}
void UDPSocketTest::ConnectTest(bool use_nonblocking_io) {
- const uint16 kPort = 9999;
+ const uint16_t kPort = 9999;
std::string simple_message("hello world!");
// Setup the server to listen.
@@ -275,7 +279,7 @@ TEST_F(UDPSocketTest, DISABLED_Broadcast) {
#else
TEST_F(UDPSocketTest, Broadcast) {
#endif
- const uint16 kPort = 9999;
+ const uint16_t kPort = 9999;
std::string first_message("first message"), second_message("second message");
IPEndPoint broadcast_address;
@@ -398,7 +402,14 @@ int PrivilegedRand(int min, int max) {
return 4;
}
-TEST_F(UDPSocketTest, ConnectFail) {
+#if defined(OS_IOS) && !TARGET_IPHONE_SIMULATOR
+// TODO(droger): On iOS this test fails on device (but passes on simulator).
+// See http://crbug.com/227760.
+#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);
@@ -425,8 +436,8 @@ TEST_F(UDPSocketTest, ConnectFail) {
// not bind the client's reads to only be from that endpoint, and that we need
// to always use recvfrom() to disambiguate.
TEST_F(UDPSocketTest, VerifyConnectBindsAddr) {
- const uint16 kPort1 = 9999;
- const uint16 kPort2 = 10000;
+ const uint16_t kPort1 = 9999;
+ const uint16_t kPort2 = 10000;
std::string simple_message("hello world!");
std::string foreign_message("BAD MESSAGE TO GET!!");
@@ -595,7 +606,7 @@ TEST_F(UDPSocketTest, CloseWithPendingRead) {
#endif // defined(OS_ANDROID)
TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) {
- const uint16 kPort = 9999;
+ const uint16_t kPort = 9999;
const char kGroup[] = "237.132.100.17";
IPEndPoint bind_address;
@@ -620,7 +631,7 @@ TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) {
}
TEST_F(UDPSocketTest, MulticastOptions) {
- const uint16 kPort = 9999;
+ const uint16_t kPort = 9999;
IPEndPoint bind_address;
CreateUDPAddress("0.0.0.0", kPort, &bind_address);
@@ -715,8 +726,8 @@ BOOL WINAPI FakeQOSAddSocketToFlow(HANDLE handle,
PQOS_FLOWID flow_id) {
EXPECT_EQ(kFakeHandle, handle);
EXPECT_EQ(NULL, addr);
- EXPECT_EQ(QOS_NON_ADAPTIVE_FLOW, flags);
- EXPECT_EQ(0, *flow_id);
+ EXPECT_EQ(static_cast<DWORD>(QOS_NON_ADAPTIVE_FLOW), flags);
+ EXPECT_EQ(0u, *flow_id);
*flow_id = kFakeFlowId;
return true;
}
@@ -726,9 +737,9 @@ BOOL WINAPI FakeQOSRemoveSocketFromFlow(HANDLE handle,
QOS_FLOWID flowid,
DWORD reserved) {
EXPECT_EQ(kFakeHandle, handle);
- EXPECT_EQ(NULL, socket);
+ EXPECT_EQ(0u, socket);
EXPECT_EQ(kFakeFlowId, flowid);
- EXPECT_EQ(0, reserved);
+ EXPECT_EQ(0u, reserved);
return true;
}
@@ -746,7 +757,7 @@ BOOL WINAPI FakeQOSSetFlow(HANDLE handle,
EXPECT_EQ(sizeof(DWORD), size);
EXPECT_EQ(g_expected_dscp, *reinterpret_cast<DWORD*>(data));
EXPECT_EQ(kFakeFlowId, flow_id);
- EXPECT_EQ(0, reserved);
+ EXPECT_EQ(0u, reserved);
EXPECT_EQ(NULL, overlapped);
return true;
}
diff --git a/chromium/net/udp/udp_socket_win.cc b/chromium/net/udp/udp_socket_win.cc
index f9c1d20e4b3..27e2750e40e 100644
--- a/chromium/net/udp/udp_socket_win.cc
+++ b/chromium/net/udp/udp_socket_win.cc
@@ -6,10 +6,10 @@
#include <mstcpip.h>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
@@ -17,8 +17,8 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "net/base/network_activity_monitor.h"
+#include "net/base/sockaddr_storage.h"
#include "net/base/winsock_init.h"
#include "net/base/winsock_util.h"
#include "net/log/net_log.h"
@@ -482,7 +482,12 @@ int UDPSocketWin::Bind(const IPEndPoint& address) {
return rv;
}
-int UDPSocketWin::SetReceiveBufferSize(int32 size) {
+int UDPSocketWin::BindToNetwork(NetworkChangeNotifier::NetworkHandle network) {
+ NOTIMPLEMENTED();
+ return ERR_NOT_IMPLEMENTED;
+}
+
+int UDPSocketWin::SetReceiveBufferSize(int32_t size) {
DCHECK_NE(socket_, INVALID_SOCKET);
DCHECK(CalledOnValidThread());
int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
@@ -492,7 +497,7 @@ int UDPSocketWin::SetReceiveBufferSize(int32 size) {
// According to documentation, setsockopt may succeed, but we need to check
// the results via getsockopt to be sure it works on Windows.
- int32 actual_size = 0;
+ int32_t actual_size = 0;
int option_size = sizeof(actual_size);
rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
reinterpret_cast<char*>(&actual_size), &option_size);
@@ -505,7 +510,7 @@ int UDPSocketWin::SetReceiveBufferSize(int32 size) {
return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
}
-int UDPSocketWin::SetSendBufferSize(int32 size) {
+int UDPSocketWin::SetSendBufferSize(int32_t size) {
DCHECK_NE(socket_, INVALID_SOCKET);
DCHECK(CalledOnValidThread());
int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
@@ -514,7 +519,7 @@ int UDPSocketWin::SetSendBufferSize(int32 size) {
return MapSystemError(WSAGetLastError());
// According to documentation, setsockopt may succeed, but we need to check
// the results via getsockopt to be sure it works on Windows.
- int32 actual_size = 0;
+ int32_t actual_size = 0;
int option_size = sizeof(actual_size);
rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
reinterpret_cast<char*>(&actual_size), &option_size);
@@ -911,7 +916,7 @@ int UDPSocketWin::SetMulticastOptions() {
break;
}
case AF_INET6: {
- uint32 interface_index = multicast_interface_;
+ uint32_t interface_index = multicast_interface_;
int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF,
reinterpret_cast<const char*>(&interface_index),
sizeof(interface_index));
@@ -951,8 +956,8 @@ int UDPSocketWin::RandomBind(const IPAddressNumber& address) {
DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
for (int i = 0; i < kBindRetries; ++i) {
- int rv = DoBind(IPEndPoint(
- address, static_cast<uint16>(rand_int_cb_.Run(kPortStart, kPortEnd))));
+ int rv = DoBind(IPEndPoint(address, static_cast<uint16_t>(rand_int_cb_.Run(
+ kPortStart, kPortEnd))));
if (rv == OK || rv != ERR_ADDRESS_IN_USE)
return rv;
}
@@ -1035,7 +1040,7 @@ int UDPSocketWin::LeaveGroup(
}
}
-int UDPSocketWin::SetMulticastInterface(uint32 interface_index) {
+int UDPSocketWin::SetMulticastInterface(uint32_t interface_index) {
DCHECK(CalledOnValidThread());
if (is_connected())
return ERR_SOCKET_IS_CONNECTED;
diff --git a/chromium/net/udp/udp_socket_win.h b/chromium/net/udp/udp_socket_win.h
index 24e1bad0cb1..ea72e28b84c 100644
--- a/chromium/net/udp/udp_socket_win.h
+++ b/chromium/net/udp/udp_socket_win.h
@@ -6,9 +6,11 @@
#define NET_UDP_UDP_SOCKET_WIN_H_
#include <qos2.h>
+#include <stdint.h>
#include <winsock2.h>
#include "base/gtest_prod_util.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
@@ -19,10 +21,11 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
-#include "net/base/net_util.h"
+#include "net/base/network_change_notifier.h"
#include "net/base/rand_callback.h"
#include "net/log/net_log.h"
#include "net/udp/datagram_socket.h"
+#include "net/udp/diff_serv_code_point.h"
namespace net {
@@ -40,6 +43,13 @@ class NET_EXPORT UDPSocketWin
// Returns a net error code.
int Open(AddressFamily address_family);
+ // Binds this socket to |network|. All data traffic on the socket will be sent
+ // and received via |network|. Must be called before Connect(). This call will
+ // fail if |network| has disconnected. Communication using this socket will
+ // fail if |network| disconnects.
+ // Returns a net error code.
+ int BindToNetwork(NetworkChangeNotifier::NetworkHandle network);
+
// Connects the socket to connect with a certain |address|.
// Should be called after Open().
// Returns a net error code.
@@ -109,11 +119,11 @@ class NET_EXPORT UDPSocketWin
// Sets the receive buffer size (in bytes) for the socket.
// Returns a net error code.
- int SetReceiveBufferSize(int32 size);
+ int SetReceiveBufferSize(int32_t size);
// Sets the send buffer size (in bytes) for the socket.
// Returns a net error code.
- int SetSendBufferSize(int32 size);
+ int SetSendBufferSize(int32_t size);
// Returns true if the socket is already connected or bound.
bool is_connected() const { return is_connected_; }
@@ -149,7 +159,7 @@ class NET_EXPORT UDPSocketWin
// default interface is used.
// Should be called before Bind().
// Returns a net error code.
- int SetMulticastInterface(uint32 interface_index);
+ int SetMulticastInterface(uint32_t interface_index);
// Sets the time-to-live option for UDP packets sent to the multicast
// group address. The default value of this option is 1.
@@ -250,7 +260,7 @@ class NET_EXPORT UDPSocketWin
int socket_options_;
// Multicast interface.
- uint32 multicast_interface_;
+ uint32_t multicast_interface_;
// Multicast socket options cached for SetMulticastOption.
// Cannot be used after Bind().
diff --git a/chromium/net/url_request/certificate_report_sender.cc b/chromium/net/url_request/certificate_report_sender.cc
index 0ff637bc472..55b27a59275 100644
--- a/chromium/net/url_request/certificate_report_sender.cc
+++ b/chromium/net/url_request/certificate_report_sender.cc
@@ -4,6 +4,8 @@
#include "net/url_request/certificate_report_sender.h"
+#include <utility>
+
#include "base/stl_util.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/load_flags.h"
@@ -42,7 +44,7 @@ void CertificateReportSender::Send(const GURL& report_uri,
scoped_ptr<UploadElementReader> reader(
UploadOwnedBytesElementReader::CreateWithString(report));
url_request->set_upload(
- ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
URLRequest* raw_url_request = url_request.get();
inflight_requests_.insert(url_request.release());
diff --git a/chromium/net/url_request/data_protocol_handler.h b/chromium/net/url_request/data_protocol_handler.h
index cc0f7b854b9..bb4e093703d 100644
--- a/chromium/net/url_request/data_protocol_handler.h
+++ b/chromium/net/url_request/data_protocol_handler.h
@@ -5,8 +5,8 @@
#ifndef NET_URL_REQUEST_DATA_PROTOCOL_HANDLER_H_
#define NET_URL_REQUEST_DATA_PROTOCOL_HANDLER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/url_request/url_request_job_factory.h"
namespace net {
diff --git a/chromium/net/url_request/file_protocol_handler.h b/chromium/net/url_request/file_protocol_handler.h
index 4ac81d35e5d..4a66df15058 100644
--- a/chromium/net/url_request/file_protocol_handler.h
+++ b/chromium/net/url_request/file_protocol_handler.h
@@ -5,8 +5,8 @@
#ifndef NET_URL_REQUEST_FILE_PROTOCOL_HANDLER_H_
#define NET_URL_REQUEST_FILE_PROTOCOL_HANDLER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "net/url_request/url_request_job_factory.h"
diff --git a/chromium/net/url_request/ftp_protocol_handler.h b/chromium/net/url_request/ftp_protocol_handler.h
index a951e0539f7..d13bf0b0a6c 100644
--- a/chromium/net/url_request/ftp_protocol_handler.h
+++ b/chromium/net/url_request/ftp_protocol_handler.h
@@ -5,8 +5,8 @@
#ifndef NET_URL_REQUEST_FTP_PROTOCOL_HANDLER_H_
#define NET_URL_REQUEST_FTP_PROTOCOL_HANDLER_H_
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/url_request/url_request_job_factory.h"
diff --git a/chromium/net/url_request/http_user_agent_settings.h b/chromium/net/url_request/http_user_agent_settings.h
index 40eb1a6739c..54bdfaccbc6 100644
--- a/chromium/net/url_request/http_user_agent_settings.h
+++ b/chromium/net/url_request/http_user_agent_settings.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
class GURL;
diff --git a/chromium/net/url_request/sdch_dictionary_fetcher.cc b/chromium/net/url_request/sdch_dictionary_fetcher.cc
index 25ae1f21a83..1141aab8024 100644
--- a/chromium/net/url_request/sdch_dictionary_fetcher.cc
+++ b/chromium/net/url_request/sdch_dictionary_fetcher.cc
@@ -11,6 +11,7 @@
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
diff --git a/chromium/net/url_request/sdch_dictionary_fetcher_unittest.cc b/chromium/net/url_request/sdch_dictionary_fetcher_unittest.cc
index 98eecaa4c08..e676a2510e1 100644
--- a/chromium/net/url_request/sdch_dictionary_fetcher_unittest.cc
+++ b/chromium/net/url_request/sdch_dictionary_fetcher_unittest.cc
@@ -5,6 +5,7 @@
#include "net/url_request/sdch_dictionary_fetcher.h"
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -124,8 +125,8 @@ class SpecifiedResponseJobInterceptor : public URLRequestInterceptor {
new SpecifiedResponseJobInterceptor(http_response_info,
lifecycle_callback));
- URLRequestFilter::GetInstance()->AddHostnameInterceptor("http", kTestDomain,
- interceptor.Pass());
+ URLRequestFilter::GetInstance()->AddHostnameInterceptor(
+ "http", kTestDomain, std::move(interceptor));
}
static void Unregister() {
@@ -221,12 +222,14 @@ class SdchDictionaryFetcherTest : public ::testing::Test {
// Block until there are no outstanding URLRequestSpecifiedResponseJobs.
void WaitForNoJobs() {
- if (jobs_outstanding_ == 0)
- return;
-
- run_loop_.reset(new base::RunLoop);
- run_loop_->Run();
- run_loop_.reset();
+ // A job may be started after the previous one was destroyed, with a brief
+ // period of 0 jobs in between, so may have to start the run loop multiple
+ // times.
+ while (jobs_outstanding_ != 0) {
+ run_loop_.reset(new base::RunLoop);
+ run_loop_->Run();
+ run_loop_.reset();
+ }
}
HttpResponseInfo* response_info_to_return() {
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 57bbd07b4c7..991af6af688 100644
--- a/chromium/net/url_request/static_http_user_agent_settings.h
+++ b/chromium/net/url_request/static_http_user_agent_settings.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/url_request/http_user_agent_settings.h"
diff --git a/chromium/net/url_request/test_url_fetcher_factory.cc b/chromium/net/url_request/test_url_fetcher_factory.cc
index 6f9344b556e..a22c13a5d1a 100644
--- a/chromium/net/url_request/test_url_fetcher_factory.cc
+++ b/chromium/net/url_request/test_url_fetcher_factory.cc
@@ -5,11 +5,13 @@
#include "net/url_request/test_url_fetcher_factory.h"
#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/location.h"
+#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
@@ -47,6 +49,7 @@ TestURLFetcher::TestURLFetcher(int id, const GURL& url, URLFetcherDelegate* d)
fake_load_flags_(0),
fake_response_code_(-1),
fake_response_destination_(STRING),
+ write_response_file_(false),
fake_was_fetched_via_proxy_(false),
fake_was_cached_(false),
fake_response_bytes_(0),
@@ -70,8 +73,8 @@ void TestURLFetcher::SetUploadData(const std::string& upload_content_type,
void TestURLFetcher::SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
scoped_refptr<base::TaskRunner> file_task_runner) {
upload_file_path_ = file_path;
}
@@ -122,9 +125,7 @@ void TestURLFetcher::SetRequestContext(
URLRequestContextGetter* request_context_getter) {
}
-void TestURLFetcher::SetFirstPartyForCookies(
- const GURL& first_party_for_cookies) {
-}
+void TestURLFetcher::SetInitiatorURL(const GURL& initiator) {}
void TestURLFetcher::SetURLRequestUserData(
const void* key,
@@ -155,16 +156,17 @@ void TestURLFetcher::SetAutomaticallyRetryOnNetworkChanges(int max_retries) {
void TestURLFetcher::SaveResponseToFileAtPath(
const base::FilePath& file_path,
scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
+ write_response_file_ = true;
SetResponseFilePath(file_path);
// Asynchronous IO is not supported, so file_task_runner is ignored.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- const size_t written_bytes = base::WriteFile(
- file_path, fake_response_string_.c_str(), fake_response_string_.size());
- DCHECK_EQ(written_bytes, fake_response_string_.size());
}
void TestURLFetcher::SaveResponseToTemporaryFile(
scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
+ base::FilePath path;
+ if (!base::CreateTemporaryFile(&path))
+ DLOG(ERROR) << "SaveResponseToTemporaryFile failed creating temp file";
+ SaveResponseToFileAtPath(path, file_task_runner);
}
void TestURLFetcher::SaveResponseWithWriter(
@@ -176,7 +178,7 @@ void TestURLFetcher::SaveResponseWithWriter(
// to be done in SaveResponseToFileAtPath(), and this method supports only
// URLFetcherStringWriter (for testing of this method only).
if (fake_response_destination_ == STRING) {
- response_writer_ = response_writer.Pass();
+ response_writer_ = std::move(response_writer);
int response = response_writer_->Initialize(CompletionCallback());
// The TestURLFetcher doesn't handle asynchronous writes.
DCHECK_EQ(OK, response);
@@ -227,6 +229,16 @@ void TestURLFetcher::Start() {
// Overriden to do nothing. It is assumed the caller will notify the delegate.
if (delegate_for_tests_)
delegate_for_tests_->OnRequestStart(id_);
+
+ // If the response should go into a file, write it out now.
+ if (fake_status_.is_success() && fake_response_code_ == net::HTTP_OK &&
+ write_response_file_ && !fake_response_file_path_.empty()) {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ size_t written_bytes =
+ base::WriteFile(fake_response_file_path_, fake_response_string_.c_str(),
+ fake_response_string_.size());
+ DCHECK_EQ(fake_response_string_.size(), written_bytes);
+ }
}
const GURL& TestURLFetcher::GetOriginalURL() const {
@@ -379,6 +391,7 @@ FakeURLFetcher::FakeURLFetcher(const GURL& url,
FakeURLFetcher::~FakeURLFetcher() {}
void FakeURLFetcher::Start() {
+ TestURLFetcher::Start();
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&FakeURLFetcher::RunDelegate, weak_factory_.GetWeakPtr()));
diff --git a/chromium/net/url_request/test_url_fetcher_factory.h b/chromium/net/url_request/test_url_fetcher_factory.h
index 18360bda671..c8d78675936 100644
--- a/chromium/net/url_request/test_url_fetcher_factory.h
+++ b/chromium/net/url_request/test_url_fetcher_factory.h
@@ -12,10 +12,10 @@
#include <string>
#include <utility>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
@@ -94,8 +94,8 @@ class TestURLFetcher : public URLFetcher {
void SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
scoped_refptr<base::TaskRunner> file_task_runner) override;
void SetUploadStreamFactory(
const std::string& upload_content_type,
@@ -114,7 +114,7 @@ class TestURLFetcher : public URLFetcher {
void AddExtraRequestHeader(const std::string& header_line) override;
void SetRequestContext(
URLRequestContextGetter* request_context_getter) override;
- void SetFirstPartyForCookies(const GURL& first_party_for_cookies) override;
+ void SetInitiatorURL(const GURL& initiator) override;
void SetURLRequestUserData(
const void* key,
const CreateDataCallback& create_data_callback) override;
@@ -229,9 +229,10 @@ class TestURLFetcher : public URLFetcher {
ResponseDestinationType fake_response_destination_;
std::string fake_response_string_;
base::FilePath fake_response_file_path_;
+ bool write_response_file_;
bool fake_was_fetched_via_proxy_;
bool fake_was_cached_;
- int64 fake_response_bytes_;
+ int64_t fake_response_bytes_;
scoped_refptr<HttpResponseHeaders> fake_response_headers_;
HttpRequestHeaders fake_extra_request_headers_;
int fake_max_retries_;
diff --git a/chromium/net/url_request/test_url_request_interceptor.cc b/chromium/net/url_request/test_url_request_interceptor.cc
index 72aeea26c9e..7b098f6ba85 100644
--- a/chromium/net/url_request/test_url_request_interceptor.cc
+++ b/chromium/net/url_request/test_url_request_interceptor.cc
@@ -5,6 +5,7 @@
#include "net/url_request/test_url_request_interceptor.h"
#include "base/files/file_util.h"
+#include "base/macros.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
#include "net/url_request/url_request.h"
diff --git a/chromium/net/url_request/test_url_request_interceptor.h b/chromium/net/url_request/test_url_request_interceptor.h
index 4b084c59f15..c2ec40fc367 100644
--- a/chromium/net/url_request/test_url_request_interceptor.h
+++ b/chromium/net/url_request/test_url_request_interceptor.h
@@ -7,7 +7,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
class GURL;
diff --git a/chromium/net/url_request/url_fetcher.h b/chromium/net/url_request/url_fetcher.h
index f13b40310c2..b8642405986 100644
--- a/chromium/net/url_request/url_fetcher.h
+++ b/chromium/net/url_request/url_fetcher.h
@@ -150,8 +150,8 @@ class NET_EXPORT URLFetcher {
virtual void SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
scoped_refptr<base::TaskRunner> file_task_runner) = 0;
// Sets data only needed by POSTs. All callers making POST requests should
@@ -207,10 +207,12 @@ class NET_EXPORT URLFetcher {
virtual void SetRequestContext(
URLRequestContextGetter* request_context_getter) = 0;
- // Set the URL that should be consulted for the third-party cookie
- // blocking policy.
- virtual void SetFirstPartyForCookies(
- const GURL& first_party_for_cookies) = 0;
+ // Set the URL that should be considered as "initiating" the fetch. This URL
+ // will be considered the "first-party" when applying cookie blocking policy
+ // to requests, and treated as the request's initiator.
+ //
+ // TODO(mkwst): Convert this to take a 'url::Origin': https://crbug.com/577565
+ virtual void SetInitiatorURL(const GURL& initiator) = 0;
// Set the key and data callback that is used when setting the user
// data on any URLRequest objects this object creates.
diff --git a/chromium/net/url_request/url_fetcher_core.cc b/chromium/net/url_request/url_fetcher_core.cc
index 1ecf9e5401e..ee1a3d8c830 100644
--- a/chromium/net/url_request/url_fetcher_core.cc
+++ b/chromium/net/url_request/url_fetcher_core.cc
@@ -5,6 +5,7 @@
#include "net/url_request/url_fetcher_core.h"
#include <stdint.h>
+#include <utility>
#include "base/bind.h"
#include "base/logging.h"
@@ -155,8 +156,8 @@ void URLFetcherCore::SetUploadData(const std::string& upload_content_type,
void URLFetcherCore::SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
scoped_refptr<base::TaskRunner> file_task_runner) {
AssertHasNoUploadData();
DCHECK(!is_chunked_upload_);
@@ -244,10 +245,9 @@ void URLFetcherCore::SetRequestContext(
request_context_getter_ = request_context_getter;
}
-void URLFetcherCore::SetFirstPartyForCookies(
- const GURL& first_party_for_cookies) {
- DCHECK(first_party_for_cookies_.is_empty());
- first_party_for_cookies_ = first_party_for_cookies;
+void URLFetcherCore::SetInitiatorURL(const GURL& initiator) {
+ DCHECK(initiator_.is_empty());
+ initiator_ = initiator;
}
void URLFetcherCore::SetURLRequestUserData(
@@ -301,7 +301,7 @@ void URLFetcherCore::SaveResponseToTemporaryFile(
void URLFetcherCore::SaveResponseWithWriter(
scoped_ptr<URLFetcherResponseWriter> response_writer) {
DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- response_writer_ = response_writer.Pass();
+ response_writer_ = std::move(response_writer);
}
HttpResponseHeaders* URLFetcherCore::GetResponseHeaders() const {
@@ -437,7 +437,7 @@ void URLFetcherCore::OnCertificateRequested(
DCHECK(network_task_runner_->BelongsToCurrentThread());
if (g_ignore_certificate_requests) {
- request->ContinueWithCertificate(NULL);
+ request->ContinueWithCertificate(nullptr, nullptr);
} else {
request->Cancel();
}
@@ -445,7 +445,7 @@ void URLFetcherCore::OnCertificateRequested(
void URLFetcherCore::OnReadCompleted(URLRequest* request,
int bytes_read) {
- DCHECK(request == request_);
+ DCHECK_EQ(request, request_.get());
DCHECK(network_task_runner_->BelongsToCurrentThread());
if (!stopped_on_redirect_)
@@ -555,8 +555,10 @@ void URLFetcherCore::StartURLRequest() {
request_->SetLoadFlags(flags);
request_->SetReferrer(referrer_);
request_->set_referrer_policy(referrer_policy_);
- request_->set_first_party_for_cookies(first_party_for_cookies_.is_empty() ?
- original_url_ : first_party_for_cookies_);
+ request_->set_first_party_for_cookies(initiator_.is_empty() ? original_url_
+ : initiator_);
+ request_->set_initiator(initiator_.is_empty() ? url::Origin(original_url_)
+ : url::Origin(initiator_));
if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) {
request_->SetUserData(url_request_data_key_,
url_request_create_data_callback_.Run());
@@ -583,7 +585,7 @@ void URLFetcherCore::StartURLRequest() {
scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader(
upload_content_.data(), upload_content_.size()));
request_->set_upload(
- ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
} else if (!upload_file_path_.empty()) {
scoped_ptr<UploadElementReader> reader(
new UploadFileElementReader(upload_file_task_runner_.get(),
@@ -592,11 +594,11 @@ void URLFetcherCore::StartURLRequest() {
upload_range_length_,
base::Time()));
request_->set_upload(
- ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
} else if (!upload_stream_factory_.is_null()) {
scoped_ptr<UploadDataStream> stream = upload_stream_factory_.Run();
DCHECK(stream);
- request_->set_upload(stream.Pass());
+ request_->set_upload(std::move(stream));
}
current_upload_bytes_ = -1;
@@ -659,7 +661,7 @@ void URLFetcherCore::StartURLRequestWhenAppropriate() {
}
if (original_url_throttler_entry_.get()) {
- int64 delay =
+ int64_t delay =
original_url_throttler_entry_->ReserveSendingTimeForNextRequest(
GetBackoffReleaseTime());
if (delay != 0) {
@@ -695,7 +697,7 @@ void URLFetcherCore::CancelURLRequest(int error) {
// delete the object, but we cannot delay the destruction of the request
// context.
request_context_getter_ = NULL;
- first_party_for_cookies_ = GURL();
+ initiator_ = GURL();
url_request_data_key_ = NULL;
url_request_create_data_callback_.Reset();
was_cancelled_ = true;
@@ -786,7 +788,7 @@ void URLFetcherCore::RetryOrCompleteUrlFetch() {
}
request_context_getter_ = NULL;
- first_party_for_cookies_ = GURL();
+ initiator_ = GURL();
url_request_data_key_ = NULL;
url_request_create_data_callback_.Reset();
bool posted = delegate_task_runner_->PostTask(
@@ -899,12 +901,12 @@ void URLFetcherCore::ReadResponse() {
void URLFetcherCore::InformDelegateUploadProgress() {
DCHECK(network_task_runner_->BelongsToCurrentThread());
if (request_.get()) {
- int64 current = request_->GetUploadProgress().position();
+ int64_t current = request_->GetUploadProgress().position();
if (current_upload_bytes_ != current) {
current_upload_bytes_ = current;
- int64 total = -1;
+ int64_t total = -1;
if (!is_chunked_upload_) {
- total = static_cast<int64>(request_->GetUploadProgress().size());
+ total = static_cast<int64_t>(request_->GetUploadProgress().size());
// Total may be zero if the UploadDataStream::Init has not been called
// yet. Don't send the upload progress until the size is initialized.
if (!total)
@@ -920,7 +922,8 @@ void URLFetcherCore::InformDelegateUploadProgress() {
}
void URLFetcherCore::InformDelegateUploadProgressInDelegateThread(
- int64 current, int64 total) {
+ int64_t current,
+ int64_t total) {
DCHECK(delegate_task_runner_->BelongsToCurrentThread());
if (delegate_)
delegate_->OnURLFetchUploadProgress(fetcher_, current, total);
@@ -942,7 +945,8 @@ void URLFetcherCore::InformDelegateDownloadProgress() {
}
void URLFetcherCore::InformDelegateDownloadProgressInDelegateThread(
- int64 current, int64 total) {
+ int64_t current,
+ int64_t total) {
DCHECK(delegate_task_runner_->BelongsToCurrentThread());
if (delegate_)
delegate_->OnURLFetchDownloadProgress(fetcher_, current, total);
diff --git a/chromium/net/url_request/url_fetcher_core.h b/chromium/net/url_request/url_fetcher_core.h
index 0af6d147df6..9b4bba2c53b 100644
--- a/chromium/net/url_request/url_fetcher_core.h
+++ b/chromium/net/url_request/url_fetcher_core.h
@@ -10,11 +10,11 @@
#include <set>
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/debug/stack_trace.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
@@ -68,8 +68,8 @@ class URLFetcherCore : public base::RefCountedThreadSafe<URLFetcherCore>,
const std::string& upload_content);
void SetUploadFilePath(const std::string& upload_content_type,
const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
scoped_refptr<base::TaskRunner> file_task_runner);
void SetUploadStreamFactory(
const std::string& upload_content_type,
@@ -87,9 +87,12 @@ class URLFetcherCore : public base::RefCountedThreadSafe<URLFetcherCore>,
void SetExtraRequestHeaders(const std::string& extra_request_headers);
void AddExtraRequestHeader(const std::string& header_line);
void SetRequestContext(URLRequestContextGetter* request_context_getter);
- // Set the URL that should be consulted for the third-party cookie
- // blocking policy.
- void SetFirstPartyForCookies(const GURL& first_party_for_cookies);
+ // Set the URL that should be considered as "initiating" the fetch. This URL
+ // will be considered the "first-party" when applying cookie blocking policy
+ // to requests, and treated as the request's initiator.
+ //
+ // TODO(mkwst): Convert this to a url::Origin. https://crbug.com/577565
+ void SetInitiatorURL(const GURL& initiator);
// Set the key and data callback that is used when setting the user
// data on any URLRequest objects this object creates.
void SetURLRequestUserData(
@@ -215,10 +218,11 @@ class URLFetcherCore : public base::RefCountedThreadSafe<URLFetcherCore>,
// Notify Delegate about the progress of upload/download.
void InformDelegateUploadProgress();
- void InformDelegateUploadProgressInDelegateThread(int64 current, int64 total);
+ void InformDelegateUploadProgressInDelegateThread(int64_t current,
+ int64_t total);
void InformDelegateDownloadProgress();
- void InformDelegateDownloadProgressInDelegateThread(int64 current,
- int64 total);
+ void InformDelegateDownloadProgressInDelegateThread(int64_t current,
+ int64_t total);
// Check if any upload data is set or not.
void AssertHasNoUploadData() const;
@@ -242,7 +246,7 @@ class URLFetcherCore : public base::RefCountedThreadSafe<URLFetcherCore>,
// Read buffer
scoped_refptr<URLRequestContextGetter> request_context_getter_;
// Cookie/cache info for the request
- GURL first_party_for_cookies_; // The first party URL for the request
+ GURL initiator_; // The request's initiator
// The user data to add to each newly-created URLRequest.
const void* url_request_data_key_;
URLFetcher::CreateDataCallback url_request_create_data_callback_;
@@ -258,9 +262,9 @@ class URLFetcherCore : public base::RefCountedThreadSafe<URLFetcherCore>,
bool upload_content_set_; // SetUploadData has been called
std::string upload_content_; // HTTP POST payload
base::FilePath upload_file_path_; // Path to file containing POST payload
- uint64 upload_range_offset_; // Offset from the beginning of the file
+ uint64_t upload_range_offset_; // Offset from the beginning of the file
// to be uploaded.
- uint64 upload_range_length_; // The length of the part of file to be
+ uint64_t upload_range_length_; // The length of the part of file to be
// uploaded.
URLFetcher::CreateUploadStreamCallback
upload_stream_factory_; // Callback to create HTTP POST payload.
@@ -328,11 +332,11 @@ class URLFetcherCore : public base::RefCountedThreadSafe<URLFetcherCore>,
// When crbug.com/119629 is fixed, scoped_ptr is not necessary here.
scoped_ptr<base::RepeatingTimer> upload_progress_checker_timer_;
// Number of bytes sent so far.
- int64 current_upload_bytes_;
+ int64_t current_upload_bytes_;
// Number of bytes received so far.
- int64 current_response_bytes_;
+ int64_t current_response_bytes_;
// Total expected bytes to receive (-1 if it cannot be determined).
- int64 total_response_bytes_;
+ int64_t total_response_bytes_;
// TODO(willchan): Get rid of this after debugging crbug.com/90971.
base::debug::StackTrace stack_trace_;
diff --git a/chromium/net/url_request/url_fetcher_delegate.cc b/chromium/net/url_request/url_fetcher_delegate.cc
index 4f7cd653bff..0d2edd961e9 100644
--- a/chromium/net/url_request/url_fetcher_delegate.cc
+++ b/chromium/net/url_request/url_fetcher_delegate.cc
@@ -6,11 +6,13 @@
namespace net {
-void URLFetcherDelegate::OnURLFetchDownloadProgress(
- const URLFetcher* source, int64 current, int64 total) {}
+void URLFetcherDelegate::OnURLFetchDownloadProgress(const URLFetcher* source,
+ int64_t current,
+ int64_t total) {}
-void URLFetcherDelegate::OnURLFetchUploadProgress(
- const URLFetcher* source, int64 current, int64 total) {}
+void URLFetcherDelegate::OnURLFetchUploadProgress(const URLFetcher* source,
+ int64_t current,
+ int64_t total) {}
URLFetcherDelegate::~URLFetcherDelegate() {}
diff --git a/chromium/net/url_request/url_fetcher_delegate.h b/chromium/net/url_request/url_fetcher_delegate.h
index e1b1352fb50..1f5eb5dbeab 100644
--- a/chromium/net/url_request/url_fetcher_delegate.h
+++ b/chromium/net/url_request/url_fetcher_delegate.h
@@ -5,9 +5,10 @@
#ifndef NET_URL_REQUEST_URL_FETCHER_DELEGATE_H_
#define NET_URL_REQUEST_URL_FETCHER_DELEGATE_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -26,13 +27,15 @@ class NET_EXPORT URLFetcherDelegate {
// denotes the number of bytes received up to the call, and |total| is the
// expected total size of the response (or -1 if not determined).
virtual void OnURLFetchDownloadProgress(const URLFetcher* source,
- int64 current, int64 total);
+ int64_t current,
+ int64_t total);
// This will be called when uploading of POST or PUT requests proceeded.
// |current| denotes the number of bytes sent so far, and |total| is the
// total size of uploading data (or -1 if chunked upload is enabled).
virtual void OnURLFetchUploadProgress(const URLFetcher* source,
- int64 current, int64 total);
+ int64_t current,
+ int64_t total);
protected:
virtual ~URLFetcherDelegate();
diff --git a/chromium/net/url_request/url_fetcher_impl.cc b/chromium/net/url_request/url_fetcher_impl.cc
index ab14571b3fa..37a77ffda32 100644
--- a/chromium/net/url_request/url_fetcher_impl.cc
+++ b/chromium/net/url_request/url_fetcher_impl.cc
@@ -4,6 +4,8 @@
#include "net/url_request/url_fetcher_impl.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/sequenced_task_runner.h"
#include "net/base/upload_data_stream.h"
@@ -33,8 +35,8 @@ void URLFetcherImpl::SetUploadData(const std::string& upload_content_type,
void URLFetcherImpl::SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
scoped_refptr<base::TaskRunner> file_task_runner) {
core_->SetUploadFilePath(upload_content_type,
file_path,
@@ -90,9 +92,8 @@ void URLFetcherImpl::SetRequestContext(
core_->SetRequestContext(request_context_getter);
}
-void URLFetcherImpl::SetFirstPartyForCookies(
- const GURL& first_party_for_cookies) {
- core_->SetFirstPartyForCookies(first_party_for_cookies);
+void URLFetcherImpl::SetInitiatorURL(const GURL& initiator) {
+ core_->SetInitiatorURL(initiator);
}
void URLFetcherImpl::SetURLRequestUserData(
@@ -139,7 +140,7 @@ void URLFetcherImpl::SaveResponseToTemporaryFile(
void URLFetcherImpl::SaveResponseWithWriter(
scoped_ptr<URLFetcherResponseWriter> response_writer) {
- core_->SaveResponseWithWriter(response_writer.Pass());
+ core_->SaveResponseWithWriter(std::move(response_writer));
}
HttpResponseHeaders* URLFetcherImpl::GetResponseHeaders() const {
diff --git a/chromium/net/url_request/url_fetcher_impl.h b/chromium/net/url_request/url_fetcher_impl.h
index 0878469cb76..107982a87eb 100644
--- a/chromium/net/url_request/url_fetcher_impl.h
+++ b/chromium/net/url_request/url_fetcher_impl.h
@@ -18,8 +18,7 @@
#include <string>
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "net/base/net_export.h"
#include "net/url_request/url_fetcher.h"
@@ -44,8 +43,8 @@ class NET_EXPORT_PRIVATE URLFetcherImpl : public URLFetcher {
void SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
- uint64 range_offset,
- uint64 range_length,
+ uint64_t range_offset,
+ uint64_t range_length,
scoped_refptr<base::TaskRunner> file_task_runner) override;
void SetUploadStreamFactory(
const std::string& upload_content_type,
@@ -62,7 +61,7 @@ class NET_EXPORT_PRIVATE URLFetcherImpl : public URLFetcher {
void AddExtraRequestHeader(const std::string& header_line) override;
void SetRequestContext(
URLRequestContextGetter* request_context_getter) override;
- void SetFirstPartyForCookies(const GURL& first_party_for_cookies) override;
+ void SetInitiatorURL(const GURL& initiator) override;
void SetURLRequestUserData(
const void* key,
const CreateDataCallback& create_data_callback) override;
diff --git a/chromium/net/url_request/url_fetcher_impl_unittest.cc b/chromium/net/url_request/url_fetcher_impl_unittest.cc
index 37e690244cf..9b0c5621a9c 100644
--- a/chromium/net/url_request/url_fetcher_impl_unittest.cc
+++ b/chromium/net/url_request/url_fetcher_impl_unittest.cc
@@ -8,9 +8,11 @@
#include <string.h>
#include <algorithm>
+#include <limits>
#include <string>
#include "base/bind.h"
+#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
@@ -33,7 +35,7 @@
#include "net/base/upload_file_element_reader.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_response_headers.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_test_util.h"
@@ -56,11 +58,11 @@ namespace {
// TODO(akalin): Move all the test data to somewhere under net/.
const base::FilePath::CharType kDocRoot[] =
FILE_PATH_LITERAL("net/data/url_fetcher_impl_unittest");
-const char kTestServerFilePrefix[] = "files/";
+const char kTestServerFilePrefix[] = "/";
// Test server path and response body for the default URL used by many of the
// tests.
-const char kDefaultResponsePath[] = "defaultresponse";
+const char kDefaultResponsePath[] = "/defaultresponse";
const char kDefaultResponseBody[] =
"Default response given for path: /defaultresponse";
@@ -117,8 +119,8 @@ class WaitingURLFetcherDelegate : public URLFetcherDelegate {
}
void OnURLFetchDownloadProgress(const URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
// Note that the current progress may be greater than the previous progress,
// in the case of retrying the request.
EXPECT_FALSE(did_complete_);
@@ -132,8 +134,8 @@ class WaitingURLFetcherDelegate : public URLFetcherDelegate {
}
void OnURLFetchUploadProgress(const URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
// Note that the current progress may be greater than the previous progress,
// in the case of retrying the request.
EXPECT_FALSE(did_complete_);
@@ -386,8 +388,11 @@ class URLFetcherTest : public testing::Test {
EXPECT_EQ(requested_out_path, out_path);
}
+ base::FilePath server_root;
+ PathService::Get(base::DIR_SOURCE_ROOT, &server_root);
+
EXPECT_TRUE(base::ContentsEqual(
- test_server_->GetDocumentRoot().AppendASCII(file_to_fetch), out_path));
+ server_root.Append(kDocRoot).AppendASCII(file_to_fetch), out_path));
// Delete the delegate and run the message loop to give the fetcher's
// destructor a chance to delete the file.
@@ -413,7 +418,7 @@ class URLFetcherTest : public testing::Test {
// URL that will hang when lookups reach the host resolver.
hanging_url_ = GURL(base::StringPrintf(
- "http://example.com:%d/%s", test_server_->host_port_pair().port(),
+ "http://example.com:%d%s", test_server_->host_port_pair().port(),
kDefaultResponsePath));
ASSERT_TRUE(hanging_url_.is_valid());
@@ -432,16 +437,15 @@ class URLFetcherTest : public testing::Test {
// Initializes |test_server_| without starting it. Allows subclasses to use
// their own server configuration.
virtual void SetUpServer() {
- test_server_.reset(new SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath(kDocRoot)));
+ test_server_.reset(new EmbeddedTestServer);
+ test_server_->AddDefaultHandlers(base::FilePath(kDocRoot));
}
// Network thread for cross-thread tests. Most threads just use the main
// thread for network activity.
scoped_ptr<base::Thread> network_thread_;
- scoped_ptr<SpawnedTestServer> test_server_;
+ scoped_ptr<EmbeddedTestServer> test_server_;
GURL hanging_url_;
size_t num_upload_streams_created_;
@@ -456,10 +460,10 @@ class URLFetcherBadHTTPSTest : public URLFetcherTest {
// URLFetcherTest:
void SetUpServer() override {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_EXPIRED);
- test_server_.reset(new SpawnedTestServer(
- SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath(kDocRoot)));
+ test_server_.reset(
+ new EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
+ test_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
+ test_server_->ServeFilesFromSourceDirectory("net/data/ssl");
}
};
@@ -660,7 +664,7 @@ TEST_F(URLFetcherTest, PostString) {
const char kUploadData[] = "bobsyeruncle";
WaitingURLFetcherDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
+ delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST,
CreateSameThreadContextGetter());
delegate.fetcher()->SetUploadData("application/x-www-form-urlencoded",
kUploadData);
@@ -677,7 +681,7 @@ TEST_F(URLFetcherTest, PostEmptyString) {
const char kUploadData[] = "";
WaitingURLFetcherDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
+ delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST,
CreateSameThreadContextGetter());
delegate.fetcher()->SetUploadData("application/x-www-form-urlencoded",
kUploadData);
@@ -694,10 +698,11 @@ TEST_F(URLFetcherTest, PostEntireFile) {
base::FilePath upload_path = GetUploadFileTestPath();
WaitingURLFetcherDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
+ delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST,
CreateSameThreadContextGetter());
delegate.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded",
- upload_path, 0, kuint64max,
+ upload_path, 0,
+ std::numeric_limits<uint64_t>::max(),
base::ThreadTaskRunnerHandle::Get());
delegate.StartFetcherAndWait();
@@ -717,7 +722,7 @@ TEST_F(URLFetcherTest, PostFileRange) {
base::FilePath upload_path = GetUploadFileTestPath();
WaitingURLFetcherDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
+ delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST,
CreateSameThreadContextGetter());
delegate.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded",
upload_path, kRangeStart, kRangeLength,
@@ -736,7 +741,7 @@ TEST_F(URLFetcherTest, PostFileRange) {
TEST_F(URLFetcherTest, PostWithUploadStreamFactory) {
WaitingURLFetcherDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
+ delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST,
CreateSameThreadContextGetter());
delegate.fetcher()->SetUploadStreamFactory(
"text/plain",
@@ -753,7 +758,7 @@ TEST_F(URLFetcherTest, PostWithUploadStreamFactory) {
TEST_F(URLFetcherTest, PostWithUploadStreamFactoryAndRetries) {
WaitingURLFetcherDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo?status=500"),
+ delegate.CreateFetcher(test_server_->GetURL("/echo?status=500"),
URLFetcher::POST, CreateSameThreadContextGetter());
delegate.fetcher()->SetAutomaticallyRetryOn5xx(true);
delegate.fetcher()->SetMaxRetriesOn5xx(1);
@@ -780,8 +785,8 @@ class CheckUploadProgressDelegate : public WaitingURLFetcherDelegate {
~CheckUploadProgressDelegate() override {}
void OnURLFetchUploadProgress(const URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
// Run default checks.
WaitingURLFetcherDelegate::OnURLFetchUploadProgress(source, current, total);
@@ -803,19 +808,21 @@ class CheckUploadProgressDelegate : public WaitingURLFetcherDelegate {
}
private:
- int64 bytes_appended() const { return num_chunks_appended_ * chunk_.size(); }
+ int64_t bytes_appended() const {
+ return num_chunks_appended_ * chunk_.size();
+ }
const std::string chunk_;
- int64 num_chunks_appended_;
- int64 last_seen_progress_;
+ int64_t num_chunks_appended_;
+ int64_t last_seen_progress_;
DISALLOW_COPY_AND_ASSIGN(CheckUploadProgressDelegate);
};
TEST_F(URLFetcherTest, UploadProgress) {
CheckUploadProgressDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
+ delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST,
CreateSameThreadContextGetter());
// Use a chunked upload so that the upload can be paused after uploading data.
// Since upload progress uses a timer, the delegate may not receive any
@@ -840,13 +847,13 @@ TEST_F(URLFetcherTest, UploadProgress) {
// that file size is correctly reported.
class CheckDownloadProgressDelegate : public WaitingURLFetcherDelegate {
public:
- CheckDownloadProgressDelegate(int64 file_size)
+ CheckDownloadProgressDelegate(int64_t file_size)
: file_size_(file_size), last_seen_progress_(0) {}
~CheckDownloadProgressDelegate() override {}
void OnURLFetchDownloadProgress(const URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
// Run default checks.
WaitingURLFetcherDelegate::OnURLFetchDownloadProgress(source, current,
total);
@@ -857,8 +864,8 @@ class CheckDownloadProgressDelegate : public WaitingURLFetcherDelegate {
}
private:
- int64 file_size_;
- int64 last_seen_progress_;
+ int64_t file_size_;
+ int64_t last_seen_progress_;
DISALLOW_COPY_AND_ASSIGN(CheckDownloadProgressDelegate);
};
@@ -869,9 +876,12 @@ TEST_F(URLFetcherTest, DownloadProgress) {
const char kFileToFetch[] = "animate1.gif";
std::string file_contents;
+
+ base::FilePath server_root;
+ PathService::Get(base::DIR_SOURCE_ROOT, &server_root);
+
ASSERT_TRUE(base::ReadFileToString(
- test_server_->GetDocumentRoot().AppendASCII(kFileToFetch),
- &file_contents));
+ server_root.Append(kDocRoot).AppendASCII(kFileToFetch), &file_contents));
CheckDownloadProgressDelegate delegate(file_contents.size());
delegate.CreateFetcher(
@@ -892,8 +902,8 @@ class CancelOnUploadProgressDelegate : public WaitingURLFetcherDelegate {
~CancelOnUploadProgressDelegate() override {}
void OnURLFetchUploadProgress(const URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
CancelFetch();
}
@@ -905,7 +915,7 @@ class CancelOnUploadProgressDelegate : public WaitingURLFetcherDelegate {
// callback.
TEST_F(URLFetcherTest, CancelInUploadProgressCallback) {
CancelOnUploadProgressDelegate delegate;
- delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
+ delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST,
CreateSameThreadContextGetter());
delegate.fetcher()->SetChunkedUpload("application/x-www-form-urlencoded");
delegate.fetcher()->Start();
@@ -929,8 +939,8 @@ class CancelOnDownloadProgressDelegate : public WaitingURLFetcherDelegate {
~CancelOnDownloadProgressDelegate() override {}
void OnURLFetchDownloadProgress(const URLFetcher* source,
- int64 current,
- int64 total) override {
+ int64_t current,
+ int64_t total) override {
CancelFetch();
}
@@ -960,7 +970,7 @@ TEST_F(URLFetcherTest, CancelInDownloadProgressCallback) {
TEST_F(URLFetcherTest, Headers) {
WaitingURLFetcherDelegate delegate;
delegate.CreateFetcher(
- test_server_->GetURL("set-header?cache-control: private"),
+ test_server_->GetURL("/set-header?cache-control: private"),
URLFetcher::GET, CreateSameThreadContextGetter());
delegate.StartFetcherAndWait();
@@ -991,7 +1001,7 @@ TEST_F(URLFetcherTest, StopOnRedirect) {
WaitingURLFetcherDelegate delegate;
delegate.CreateFetcher(
- test_server_->GetURL(std::string("server-redirect?") + kRedirectTarget),
+ test_server_->GetURL(std::string("/server-redirect?") + kRedirectTarget),
URLFetcher::GET, CreateSameThreadContextGetter());
delegate.fetcher()->SetStopOnRedirect(true);
delegate.StartFetcherAndWait();
@@ -1035,7 +1045,7 @@ TEST_F(URLFetcherTest, ThrottleOnRepeatedFetches) {
TEST_F(URLFetcherTest, ThrottleOn5xxRetries) {
base::Time start_time = Time::Now();
- GURL url(test_server_->GetURL("files/server-unavailable.html"));
+ GURL url(test_server_->GetURL("/server-unavailable.html"));
scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
CreateSameThreadContextGetter());
@@ -1072,7 +1082,7 @@ TEST_F(URLFetcherTest, ThrottleOn5xxRetries) {
// Tests overload protection, when responses passed through.
TEST_F(URLFetcherTest, ProtectTestPassedThrough) {
base::Time start_time = Time::Now();
- GURL url(test_server_->GetURL("files/server-unavailable.html"));
+ GURL url(test_server_->GetURL("/server-unavailable.html"));
scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
CreateSameThreadContextGetter());
@@ -1241,7 +1251,7 @@ TEST_F(URLFetcherTest, ReuseFetcherForSameURL) {
scoped_refptr<URLRequestContextGetter> context_getter(
CreateSameThreadContextGetter());
ReuseFetcherDelegate delegate(context_getter);
- delegate.CreateFetcher(test_server_->GetURL("echoheader?test"),
+ delegate.CreateFetcher(test_server_->GetURL("/echoheader?test"),
URLFetcher::GET, context_getter);
delegate.fetcher()->SetExtraRequestHeaders("test: request1");
delegate.StartFetcherAndWait();
diff --git a/chromium/net/url_request/url_fetcher_response_writer.h b/chromium/net/url_request/url_fetcher_response_writer.h
index fb9952226fb..891123a6433 100644
--- a/chromium/net/url_request/url_fetcher_response_writer.h
+++ b/chromium/net/url_request/url_fetcher_response_writer.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/net/url_request/url_request.cc b/chromium/net/url_request/url_request.cc
index 03f3f02c89a..7bd01e0a6c2 100644
--- a/chromium/net/url_request/url_request.cc
+++ b/chromium/net/url_request/url_request.cc
@@ -4,15 +4,20 @@
#include "net/url_request/url_request.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/debug/alias.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/debug/stack_trace.h"
#include "base/lazy_instance.h"
#include "base/memory/singleton.h"
#include "base/message_loop/message_loop.h"
#include "base/profiler/scoped_tracker.h"
+#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
@@ -50,28 +55,17 @@ namespace {
// Max number of http redirects to follow. Same number as gecko.
const int kMaxRedirects = 20;
-// Discard headers which have meaning in POST (Content-Length, Content-Type,
-// Origin).
-void StripPostSpecificHeaders(HttpRequestHeaders* headers) {
- // These are headers that may be attached to a POST.
- headers->RemoveHeader(HttpRequestHeaders::kContentLength);
- headers->RemoveHeader(HttpRequestHeaders::kContentType);
- // TODO(jww): This is Origin header removal is probably layering violation and
- // should be refactored into //content. See https://crbug.com/471397.
- headers->RemoveHeader(HttpRequestHeaders::kOrigin);
-}
-
// TODO(battre): Delete this, see http://crbug.com/89321:
// This counter keeps track of the identifiers used for URL requests so far.
// 0 is reserved to represent an invalid ID.
-uint64 g_next_url_request_identifier = 1;
+uint64_t g_next_url_request_identifier = 1;
// This lock protects g_next_url_request_identifier.
base::LazyInstance<base::Lock>::Leaky
g_next_url_request_identifier_lock = LAZY_INSTANCE_INITIALIZER;
// Returns an prior unused identifier for URL requests.
-uint64 GenerateURLRequestIdentifier() {
+uint64_t GenerateURLRequestIdentifier() {
base::AutoLock lock(g_next_url_request_identifier_lock.Get());
return g_next_url_request_identifier++;
}
@@ -216,7 +210,7 @@ void URLRequest::AppendChunkToUpload(const char* bytes,
}
void URLRequest::set_upload(scoped_ptr<UploadDataStream> upload) {
- upload_data_stream_ = upload.Pass();
+ upload_data_stream_ = std::move(upload);
}
const UploadDataStream* URLRequest::get_upload() const {
@@ -295,7 +289,7 @@ scoped_ptr<base::Value> URLRequest::GetStateAsValue() const {
for (const GURL& url : url_chain_) {
list->AppendString(url.possibly_invalid_spec());
}
- dict->Set("url_chain", list.Pass());
+ dict->Set("url_chain", std::move(list));
}
dict->SetInteger("load_flags", load_flags_);
@@ -330,7 +324,7 @@ scoped_ptr<base::Value> URLRequest::GetStateAsValue() const {
}
if (status_.error() != OK)
dict->SetInteger("net_error", status_.error());
- return dict.Pass();
+ return std::move(dict);
}
void URLRequest::LogBlockedBy(const char* blocked_by) {
@@ -400,6 +394,12 @@ void URLRequest::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
*load_timing_info = load_timing_info_;
}
+void URLRequest::PopulateNetErrorDetails(NetErrorDetails* details) const {
+ if (!job_)
+ return;
+ return job_->PopulateNetErrorDetails(details);
+}
+
bool URLRequest::GetRemoteEndpoint(IPEndPoint* endpoint) const {
if (!job_)
return false;
@@ -474,6 +474,11 @@ void URLRequest::set_first_party_url_policy(
first_party_url_policy_ = first_party_url_policy;
}
+void URLRequest::set_initiator(const url::Origin& initiator) {
+ DCHECK(!is_pending_);
+ initiator_ = initiator;
+}
+
void URLRequest::set_method(const std::string& method) {
DCHECK(!is_pending_);
method_ = method;
@@ -495,10 +500,14 @@ void URLRequest::set_referrer_policy(ReferrerPolicy referrer_policy) {
}
void URLRequest::set_delegate(Delegate* delegate) {
+ DCHECK(!delegate_);
+ DCHECK(delegate);
delegate_ = delegate;
}
void URLRequest::Start() {
+ DCHECK(delegate_);
+
// TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed.
tracked_objects::ScopedTracker tracking_profile(
FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start"));
@@ -623,7 +632,7 @@ void URLRequest::StartJob(URLRequestJob* job) {
&url(), &method_, load_flags_, priority_,
upload_data_stream_ ? upload_data_stream_->identifier() : -1));
- job_ = job;
+ job_.reset(job);
job_->SetExtraRequestHeaders(extra_request_headers_);
job_->SetPriority(priority_);
@@ -693,6 +702,24 @@ void URLRequest::CancelWithSSLError(int error, const SSLInfo& ssl_info) {
void URLRequest::DoCancel(int error, const SSLInfo& ssl_info) {
DCHECK(error < 0);
+ // ~500,000 ERR_ABORTED < 100ms in Canary channel a day. Sample .01% to get
+ // ~50 reports a day.
+ // TODO(csharrison) Remove this code when crbug.com/557430 is resolved.
+ int64_t request_time =
+ (base::TimeTicks::Now() - creation_time_).InMilliseconds();
+ if (!has_notified_completion_ && error == ERR_ABORTED &&
+ request_time <= 100 && load_flags_ & LOAD_MAIN_FRAME &&
+ base::RandDouble() < .00001) {
+ static int dump_times = 0;
+ if (dump_times < 5) {
+ char url_copy[256] = {0};
+ strncpy(url_copy, url().spec().c_str(), sizeof(url_copy));
+ base::debug::Alias(&url_copy);
+ base::debug::Alias(&request_time);
+ base::debug::DumpWithoutCrashing();
+ dump_times++;
+ }
+ }
// If cancelled while calling a delegate, clear delegate info.
if (calling_delegate_) {
LogUnblocked();
@@ -776,7 +803,7 @@ void URLRequest::NotifyReceivedRedirect(const RedirectInfo& redirect_info,
this, network_delegate_, redirect_info.new_url);
if (job) {
RestartWithJob(job);
- } else if (delegate_) {
+ } else {
OnCallToDelegate();
delegate_->OnReceivedRedirect(this, redirect_info, defer_redirect);
// |this| may be have been destroyed here.
@@ -784,7 +811,7 @@ void URLRequest::NotifyReceivedRedirect(const RedirectInfo& redirect_info,
}
void URLRequest::NotifyBeforeNetworkStart(bool* defer) {
- if (delegate_ && !notified_before_network_start_) {
+ if (!notified_before_network_start_) {
OnCallToDelegate();
delegate_->OnBeforeNetworkStart(this, defer);
if (!*defer)
@@ -814,23 +841,21 @@ void URLRequest::NotifyResponseStarted() {
if (job) {
RestartWithJob(job);
} else {
- if (delegate_) {
- // In some cases (e.g. an event was canceled), we might have sent the
- // completion event and receive a NotifyResponseStarted() later.
- if (!has_notified_completion_ && status_.is_success()) {
- if (network_delegate_)
- network_delegate_->NotifyResponseStarted(this);
- }
-
- // Notify in case the entire URL Request has been finished.
- if (!has_notified_completion_ && !status_.is_success())
- NotifyRequestCompleted();
-
- OnCallToDelegate();
- delegate_->OnResponseStarted(this);
- // Nothing may appear below this line as OnResponseStarted may delete
- // |this|.
+ // In some cases (e.g. an event was canceled), we might have sent the
+ // completion event and receive a NotifyResponseStarted() later.
+ if (!has_notified_completion_ && status_.is_success()) {
+ if (network_delegate_)
+ network_delegate_->NotifyResponseStarted(this);
}
+
+ // Notify in case the entire URL Request has been finished.
+ if (!has_notified_completion_ && !status_.is_success())
+ NotifyRequestCompleted();
+
+ OnCallToDelegate();
+ delegate_->OnResponseStarted(this);
+ // Nothing may appear below this line as OnResponseStarted may delete
+ // |this|.
}
}
@@ -855,10 +880,11 @@ void URLRequest::CancelAuth() {
job_->CancelAuth();
}
-void URLRequest::ContinueWithCertificate(X509Certificate* client_cert) {
+void URLRequest::ContinueWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key) {
DCHECK(job_.get());
- job_->ContinueWithCertificate(client_cert);
+ job_->ContinueWithCertificate(client_cert, client_private_key);
}
void URLRequest::ContinueDespiteLastError() {
@@ -889,9 +915,6 @@ void URLRequest::PrepareToRestart() {
}
void URLRequest::OrphanJob() {
- if (network_delegate_)
- network_delegate_->NotifyURLRequestJobOrphaned(this);
-
// When calling this function, please check that URLRequestHttpJob is
// not in between calling NetworkDelegate::NotifyHeadersReceived receiving
// the call back. This is currently guaranteed by the following strategies:
@@ -901,7 +924,6 @@ void URLRequest::OrphanJob() {
// NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate
// that the callback becomes invalid.
job_->Kill();
- job_->DetachRequest(); // ensures that the job will not call us again
job_ = NULL;
}
@@ -939,13 +961,18 @@ int URLRequest::Redirect(const RedirectInfo& redirect_info) {
if (redirect_info.new_method != method_) {
// TODO(davidben): This logic still needs to be replicated at the consumers.
if (method_ == "POST") {
- // If being switched from POST, must remove headers that were specific to
- // the POST and don't have meaning in other methods. For example the
- // inclusion of a multipart Content-Type header in GET can cause problems
- // with some servers:
- // http://code.google.com/p/chromium/issues/detail?id=843
- StripPostSpecificHeaders(&extra_request_headers_);
+ // If being switched from POST, must remove Origin header.
+ // TODO(jww): This is Origin header removal is probably layering violation
+ // and
+ // should be refactored into //content. See https://crbug.com/471397.
+ extra_request_headers_.RemoveHeader(HttpRequestHeaders::kOrigin);
}
+ // The inclusion of a multipart Content-Type header can cause problems with
+ // some
+ // servers:
+ // http://code.google.com/p/chromium/issues/detail?id=843
+ extra_request_headers_.RemoveHeader(HttpRequestHeaders::kContentLength);
+ extra_request_headers_.RemoveHeader(HttpRequestHeaders::kContentType);
upload_data_stream_.reset();
method_ = redirect_info.new_method;
}
@@ -986,8 +1013,8 @@ const URLRequestContext* URLRequest::context() const {
return context_;
}
-int64 URLRequest::GetExpectedContentSize() const {
- int64 expected_content_size = -1;
+int64_t URLRequest::GetExpectedContentSize() const {
+ int64_t expected_content_size = -1;
if (job_.get())
expected_content_size = job_->expected_content_size();
@@ -1011,7 +1038,7 @@ void URLRequest::SetPriority(RequestPriority priority) {
priority_ = priority;
if (job_.get()) {
net_log_.AddEvent(NetLog::TYPE_URL_REQUEST_SET_PRIORITY,
- NetLog::IntegerCallback("priority", priority_));
+ NetLog::IntCallback("priority", priority_));
job_->SetPriority(priority_);
}
}
@@ -1070,8 +1097,7 @@ void URLRequest::NotifyAuthRequiredComplete(
case NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION:
// Defer to the URLRequest::Delegate, since the NetworkDelegate
// didn't take an action.
- if (delegate_)
- delegate_->OnAuthRequired(this, auth_info.get());
+ delegate_->OnAuthRequired(this, auth_info.get());
break;
case NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH:
@@ -1090,14 +1116,12 @@ void URLRequest::NotifyAuthRequiredComplete(
void URLRequest::NotifyCertificateRequested(
SSLCertRequestInfo* cert_request_info) {
- if (delegate_)
- delegate_->OnCertificateRequested(this, cert_request_info);
+ delegate_->OnCertificateRequested(this, cert_request_info);
}
void URLRequest::NotifySSLCertificateError(const SSLInfo& ssl_info,
bool fatal) {
- if (delegate_)
- delegate_->OnSSLCertificateError(this, ssl_info, fatal);
+ delegate_->OnSSLCertificateError(this, ssl_info, fatal);
}
bool URLRequest::CanGetCookies(const CookieList& cookie_list) const {
@@ -1138,8 +1162,7 @@ void URLRequest::NotifyReadCompleted(int bytes_read) {
if (bytes_read > 0 && !was_cached())
NetworkChangeNotifier::NotifyDataReceived(*this, bytes_read);
- if (delegate_)
- delegate_->OnReadCompleted(this, bytes_read);
+ delegate_->OnReadCompleted(this, bytes_read);
// Nothing below this line as OnReadCompleted may delete |this|.
}
diff --git a/chromium/net/url_request/url_request.h b/chromium/net/url_request/url_request.h
index 9209697d0cf..1a174704c6c 100644
--- a/chromium/net/url_request/url_request.h
+++ b/chromium/net/url_request/url_request.h
@@ -12,7 +12,7 @@
#include "base/debug/leak_tracker.h"
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/supports_user_data.h"
@@ -22,6 +22,7 @@
#include "net/base/completion_callback.h"
#include "net/base/load_states.h"
#include "net/base/load_timing_info.h"
+#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
#include "net/base/network_delegate.h"
#include "net/base/request_priority.h"
@@ -33,6 +34,7 @@
#include "net/socket/connection_attempts.h"
#include "net/url_request/url_request_status.h"
#include "url/gurl.h"
+#include "url/origin.h"
namespace base {
class Value;
@@ -52,6 +54,7 @@ struct LoadTimingInfo;
struct RedirectInfo;
class SSLCertRequestInfo;
class SSLInfo;
+class SSLPrivateKey;
class UploadDataStream;
class URLRequestContext;
class URLRequestJob;
@@ -172,8 +175,9 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// Called when we receive an SSL CertificateRequest message for client
// authentication. The delegate should call
// request->ContinueWithCertificate() with the client certificate the user
- // selected, or request->ContinueWithCertificate(NULL) to continue the SSL
- // handshake without a client certificate.
+ // selected and its private key, or request->ContinueWithCertificate(NULL,
+ // NULL)
+ // to continue the SSL handshake without a client certificate.
virtual void OnCertificateRequested(
URLRequest* request,
SSLCertRequestInfo* cert_request_info);
@@ -252,7 +256,8 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
const GURL& url() const { return url_chain_.back(); }
// The URL that should be consulted for the third-party cookie blocking
- // policy.
+ // policy, as defined in Section 2.1.1 and 2.1.2 of
+ // https://tools.ietf.org/html/draft-west-first-party-cookies.
//
// WARNING: This URL must only be used for the third-party cookie blocking
// policy. It MUST NEVER be used for any kind of SECURITY check.
@@ -263,6 +268,11 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// a security check, an attacker might try to get around this check
// by starting from some page that redirects to the
// host-to-be-attacked.
+ //
+ // TODO(mkwst): Convert this to a 'url::Origin'. Several callsites are using
+ // this value as a proxy for the "top-level frame URL", which is simply
+ // incorrect and fragile. We don't need the full URL for any //net checks,
+ // so we should drop the pieces we don't need. https://crbug.com/577565
const GURL& first_party_for_cookies() const {
return first_party_for_cookies_;
}
@@ -277,6 +287,26 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
}
void set_first_party_url_policy(FirstPartyURLPolicy first_party_url_policy);
+ // The origin of the context which initiated the request. This is distinct
+ // from the "first party for cookies" discussed above in a number of ways:
+ //
+ // 1. The request's initiator does not change during a redirect. If a form
+ // submission from `https://example.com/` redirects through a number of
+ // sites before landing on `https://not-example.com/`, the initiator for
+ // each of those requests will be `https://example.com/`.
+ //
+ // 2. The request's initiator is the origin of the frame or worker which made
+ // the request, even for top-level navigations. That is, if
+ // `https://example.com/`'s form submission is made in the top-level frame,
+ // the first party for cookies would be the target URL's origin. The
+ // initiator remains `https://example.com/`.
+ //
+ // This value is used to perform the cross-origin check specified in Section
+ // 4.3 of https://tools.ietf.org/html/draft-west-first-party-cookies.
+ const url::Origin& initiator() const { return initiator_; }
+ // This method may only be called before Start().
+ void set_initiator(const url::Origin& initiator);
+
// The request method, as an uppercase string. "GET" is the default value.
// The request method may only be changed before Start() is called and
// should only be assigned an uppercase value.
@@ -296,8 +326,9 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
ReferrerPolicy referrer_policy() const { return referrer_policy_; }
void set_referrer_policy(ReferrerPolicy referrer_policy);
- // Sets the delegate of the request. This value may be changed at any time,
- // and it is permissible for it to be null.
+ // Sets the delegate of the request. This is only to allow creating a request
+ // before creating its delegate. |delegate| must be non-NULL and the request
+ // must not yet have a Delegate set.
void set_delegate(Delegate* delegate);
// Indicates that the request body should be sent using chunked transfer
@@ -455,6 +486,10 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// non-cached HTTP responses.
void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
+ // Gets the networkd error details of the most recent origin that the network
+ // stack makes the request to.
+ void PopulateNetErrorDetails(NetErrorDetails* details) const;
+
// Gets the remote endpoint of the most recent socket that the network stack
// used to make this request.
//
@@ -509,10 +544,11 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
const URLRequestStatus& status() const { return status_; }
// Returns a globally unique identifier for this request.
- uint64 identifier() const { return identifier_; }
+ uint64_t identifier() const { return identifier_; }
// This method is called to start the request. The delegate will receive
- // a OnResponseStarted callback when the request is started.
+ // a OnResponseStarted callback when the request is started. The request
+ // must have a delegate set before this method is called.
void Start();
// This method may be called at any time after Start() has been called to
@@ -582,7 +618,8 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// This method can be called after the user selects a client certificate to
// instruct this URLRequest to continue with the request with the
// certificate. Pass NULL if the user doesn't have a client certificate.
- void ContinueWithCertificate(X509Certificate* client_cert);
+ void ContinueWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key);
// This method can be called after some error notifications to instruct this
// URLRequest to ignore the current error and continue with the request. To
@@ -595,7 +632,7 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
const BoundNetLog& net_log() const { return net_log_; }
// Returns the expected content size if available
- int64 GetExpectedContentSize() const;
+ int64_t GetExpectedContentSize() const;
// Returns the priority level for this request.
RequestPriority priority() const { return priority_; }
@@ -609,23 +646,20 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// due to HSTS. If so, |redirect_url| is rewritten to the new HTTPS URL.
bool GetHSTSRedirect(GURL* redirect_url) const;
- // TODO(willchan): Undo this. Only temporarily public.
- bool has_delegate() const { return delegate_ != NULL; }
-
// NOTE(willchan): This is just temporary for debugging
// http://crbug.com/90971.
// Allows to setting debug info into the URLRequest.
void set_stack_trace(const base::debug::StackTrace& stack_trace);
const base::debug::StackTrace* stack_trace() const;
- void set_received_response_content_length(int64 received_content_length) {
+ void set_received_response_content_length(int64_t received_content_length) {
received_response_content_length_ = received_content_length;
}
// The number of bytes in the raw response body (before any decompression,
// etc.). This is only available after the final Read completes. Not available
// for FTP responses.
- int64 received_response_content_length() const {
+ int64_t received_response_content_length() const {
return received_response_content_length_;
}
@@ -684,6 +718,7 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// paused).
void BeforeRequestComplete(int error);
+ // TODO(mmenke): Make this take a scoped_ptr.
void StartJob(URLRequestJob* job);
// Restarting involves replacing the current job with a new one such as what
@@ -713,9 +748,8 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// occurs.
void NotifyResponseStarted();
- // These functions delegate to |delegate_| and may only be used if
- // |delegate_| is not NULL. See URLRequest::Delegate for the meaning
- // of these functions.
+ // These functions delegate to |delegate_|. See URLRequest::Delegate for the
+ // meaning of these functions.
void NotifyAuthRequired(AuthChallengeInfo* auth_info);
void NotifyAuthRequiredComplete(NetworkDelegate::AuthRequiredResponse result);
void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info);
@@ -746,7 +780,7 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// Tracks the time spent in various load states throughout this request.
BoundNetLog net_log_;
- scoped_refptr<URLRequestJob> job_;
+ scoped_ptr<URLRequestJob> job_;
scoped_ptr<UploadDataStream> upload_data_stream_;
// TODO(mmenke): Make whether or not an upload is chunked transparent to the
// URLRequest.
@@ -754,6 +788,7 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
std::vector<GURL> url_chain_;
GURL first_party_for_cookies_;
+ url::Origin initiator_;
GURL delegate_redirect_url_;
std::string method_; // "GET", "POST", etc. Should be all uppercase.
std::string referrer_;
@@ -805,7 +840,7 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// needs to be done outside of the URLRequest anyway. Therefore, this
// identifier should be deleted here. http://crbug.com/89321
// A globally unique identifier for this request.
- const uint64 identifier_;
+ const uint64_t identifier_;
// True if this request is currently calling a delegate, or is blocked waiting
// for the URL request or network delegate to resume it.
@@ -834,7 +869,7 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
AuthCredentials auth_credentials_;
scoped_refptr<AuthChallengeInfo> auth_info_;
- int64 received_response_content_length_;
+ int64_t received_response_content_length_;
base::TimeTicks creation_time_;
diff --git a/chromium/net/url_request/url_request_backoff_manager.cc b/chromium/net/url_request/url_request_backoff_manager.cc
index f1010ef5d14..86fa9650dca 100644
--- a/chromium/net/url_request/url_request_backoff_manager.cc
+++ b/chromium/net/url_request/url_request_backoff_manager.cc
@@ -12,9 +12,9 @@
namespace net {
-const uint16 URLRequestBackoffManager::kMinimumBackoffInSeconds = 1;
-const uint16 URLRequestBackoffManager::kMaximumBackoffInSeconds = 50000;
-const uint16 URLRequestBackoffManager::kNewEntriesBetweenCollecting = 200;
+const uint16_t URLRequestBackoffManager::kMinimumBackoffInSeconds = 1;
+const uint16_t URLRequestBackoffManager::kMaximumBackoffInSeconds = 50000;
+const uint16_t URLRequestBackoffManager::kNewEntriesBetweenCollecting = 200;
URLRequestBackoffManager::URLRequestBackoffManager()
: new_entries_since_last_gc_(0) {
@@ -113,7 +113,7 @@ bool URLRequestBackoffManager::GetBackoffTime(HttpResponseHeaders* headers,
std::string value;
void* iter = NULL;
while (headers->EnumerateHeader(&iter, name, &value)) {
- int64 seconds;
+ int64_t seconds;
base::StringToInt64(value, &seconds);
if (seconds >= kMinimumBackoffInSeconds &&
seconds <= kMaximumBackoffInSeconds) {
diff --git a/chromium/net/url_request/url_request_backoff_manager.h b/chromium/net/url_request/url_request_backoff_manager.h
index 232ebdc02b6..2aceb742c98 100644
--- a/chromium/net/url_request/url_request_backoff_manager.h
+++ b/chromium/net/url_request/url_request_backoff_manager.h
@@ -5,10 +5,12 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_BACKOFF_MANAGER_H_
#define NET_URL_REQUEST_URL_REQUEST_BACKOFF_MANAGER_H_
+#include <stdint.h>
+
#include <map>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
@@ -40,11 +42,11 @@ class NET_EXPORT URLRequestBackoffManager
public NetworkChangeNotifier::ConnectionTypeObserver {
public:
// Minimum number of seconds that a Backoff header can specify.
- static const uint16 kMinimumBackoffInSeconds;
+ static const uint16_t kMinimumBackoffInSeconds;
// Maximum number of seconds that a Backoff header can specify.
- static const uint16 kMaximumBackoffInSeconds;
+ static const uint16_t kMaximumBackoffInSeconds;
// Number of throttled requests that will be made between garbage collection.
- static const uint16 kNewEntriesBetweenCollecting;
+ static const uint16_t kNewEntriesBetweenCollecting;
URLRequestBackoffManager();
~URLRequestBackoffManager() override;
diff --git a/chromium/net/url_request/url_request_context.cc b/chromium/net/url_request/url_request_context.cc
index b83cf023be3..e9ab617dd58 100644
--- a/chromium/net/url_request/url_request_context.cc
+++ b/chromium/net/url_request/url_request_context.cc
@@ -94,14 +94,12 @@ void URLRequestContext::AssertNoURLRequests() const {
char url_buf[128];
const URLRequest* request = *url_requests_->begin();
base::strlcpy(url_buf, request->url().spec().c_str(), arraysize(url_buf));
- bool has_delegate = request->has_delegate();
int load_flags = request->load_flags();
base::debug::StackTrace stack_trace(NULL, 0);
if (request->stack_trace())
stack_trace = *request->stack_trace();
base::debug::Alias(url_buf);
base::debug::Alias(&num_requests);
- base::debug::Alias(&has_delegate);
base::debug::Alias(&load_flags);
base::debug::Alias(&stack_trace);
CHECK(false) << "Leaked " << num_requests << " URLRequest(s). First URL: "
diff --git a/chromium/net/url_request/url_request_context.h b/chromium/net/url_request/url_request_context.h
index b9f1276d6b7..bb1486e0157 100644
--- a/chromium/net/url_request/url_request_context.h
+++ b/chromium/net/url_request/url_request_context.h
@@ -13,6 +13,7 @@
#include <set>
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/net/url_request/url_request_context_builder.cc b/chromium/net/url_request/url_request_context_builder.cc
index e2c77e9da77..3112f1f017e 100644
--- a/chromium/net/url_request/url_request_context_builder.cc
+++ b/chromium/net/url_request/url_request_context_builder.cc
@@ -5,10 +5,13 @@
#include "net/url_request/url_request_context_builder.h"
#include <string>
+#include <utility>
+#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
@@ -28,6 +31,7 @@
#include "net/http/http_server_properties_manager.h"
#include "net/http/transport_security_persister.h"
#include "net/http/transport_security_state.h"
+#include "net/quic/quic_stream_factory.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
#include "net/ssl/ssl_config_service_defaults.h"
@@ -149,7 +153,7 @@ class ContainerURLRequestContext : public URLRequestContext {
void set_transport_security_persister(
scoped_ptr<TransportSecurityPersister> transport_security_persister) {
- transport_security_persister = transport_security_persister.Pass();
+ transport_security_persister_ = std::move(transport_security_persister);
}
private:
@@ -178,20 +182,15 @@ URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams()
next_protos(NextProtosDefaults()),
use_alternative_services(true),
enable_quic(false),
- enable_insecure_quic(false) {}
+ quic_max_server_configs_stored_in_properties(0),
+ quic_delay_tcp_race(false),
+ quic_max_number_of_lossy_connections(0),
+ quic_packet_loss_threshold(1.0f),
+ quic_idle_connection_timeout_seconds(kIdleConnectionTimeoutSeconds) {}
URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams()
{}
-URLRequestContextBuilder::SchemeFactory::SchemeFactory(
- const std::string& auth_scheme,
- HttpAuthHandlerFactory* auth_handler_factory)
- : scheme(auth_scheme), factory(auth_handler_factory) {
-}
-
-URLRequestContextBuilder::SchemeFactory::~SchemeFactory() {
-}
-
URLRequestContextBuilder::URLRequestContextBuilder()
: data_enabled_(false),
#if !defined(DISABLE_FILE_SUPPORT)
@@ -242,9 +241,14 @@ void URLRequestContextBuilder::SetSpdyAndQuicEnabled(bool spdy_enabled,
http_network_session_params_.enable_quic = quic_enabled;
}
+void URLRequestContextBuilder::SetCertVerifier(
+ scoped_ptr<CertVerifier> cert_verifier) {
+ cert_verifier_ = std::move(cert_verifier);
+}
+
void URLRequestContextBuilder::SetInterceptors(
- ScopedVector<URLRequestInterceptor> url_request_interceptors) {
- url_request_interceptors_ = url_request_interceptors.Pass();
+ std::vector<scoped_ptr<URLRequestInterceptor>> url_request_interceptors) {
+ url_request_interceptors_ = std::move(url_request_interceptors);
}
void URLRequestContextBuilder::SetCookieAndChannelIdStores(
@@ -252,7 +256,7 @@ void URLRequestContextBuilder::SetCookieAndChannelIdStores(
scoped_ptr<ChannelIDService> channel_id_service) {
DCHECK(cookie_store);
cookie_store_ = cookie_store;
- channel_id_service_ = channel_id_service.Pass();
+ channel_id_service_ = std::move(channel_id_service);
}
void URLRequestContextBuilder::SetFileTaskRunner(
@@ -260,9 +264,14 @@ void URLRequestContextBuilder::SetFileTaskRunner(
file_task_runner_ = task_runner;
}
+void URLRequestContextBuilder::SetHttpAuthHandlerFactory(
+ scoped_ptr<HttpAuthHandlerFactory> factory) {
+ http_auth_handler_factory_ = std::move(factory);
+}
+
void URLRequestContextBuilder::SetHttpServerProperties(
scoped_ptr<HttpServerProperties> http_server_properties) {
- http_server_properties_ = http_server_properties.Pass();
+ http_server_properties_ = std::move(http_server_properties);
}
scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
@@ -275,7 +284,7 @@ scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
if (!network_delegate_)
network_delegate_.reset(new BasicNetworkDelegate);
- storage->set_network_delegate(network_delegate_.Pass());
+ storage->set_network_delegate(std::move(network_delegate_));
if (net_log_) {
// Unlike the other builder parameters, |net_log_| is not owned by the
@@ -288,7 +297,7 @@ scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
if (!host_resolver_) {
host_resolver_ = HostResolver::CreateDefaultResolver(context->net_log());
}
- storage->set_host_resolver(host_resolver_.Pass());
+ storage->set_host_resolver(std::move(host_resolver_));
if (!proxy_service_) {
// TODO(willchan): Switch to using this code when
@@ -301,26 +310,24 @@ scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
}
#endif // !defined(OS_LINUX) && !defined(OS_ANDROID)
proxy_service_ = ProxyService::CreateUsingSystemProxyResolver(
- proxy_config_service_.Pass(),
+ std::move(proxy_config_service_),
0, // This results in using the default value.
context->net_log());
}
- storage->set_proxy_service(proxy_service_.Pass());
+ storage->set_proxy_service(std::move(proxy_service_));
storage->set_ssl_config_service(new SSLConfigServiceDefaults);
- scoped_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_registry_factory(
- HttpAuthHandlerRegistryFactory::CreateDefault(context->host_resolver()));
- for (size_t i = 0; i < extra_http_auth_handlers_.size(); ++i) {
- http_auth_handler_registry_factory->RegisterSchemeFactory(
- extra_http_auth_handlers_[i].scheme,
- extra_http_auth_handlers_[i].factory);
+
+ if (!http_auth_handler_factory_) {
+ http_auth_handler_factory_ =
+ HttpAuthHandlerRegistryFactory::CreateDefault(context->host_resolver());
}
- storage->set_http_auth_handler_factory(
- http_auth_handler_registry_factory.Pass());
+
+ storage->set_http_auth_handler_factory(std::move(http_auth_handler_factory_));
if (cookie_store_) {
storage->set_cookie_store(cookie_store_.get());
- storage->set_channel_id_service(channel_id_service_.Pass());
+ storage->set_channel_id_service(std::move(channel_id_service_));
} else {
storage->set_cookie_store(new CookieMonster(NULL, NULL));
// TODO(mmenke): This always creates a file thread, even when it ends up
@@ -330,8 +337,7 @@ scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
}
if (sdch_enabled_) {
- storage->set_sdch_manager(
- scoped_ptr<net::SdchManager>(new SdchManager()).Pass());
+ storage->set_sdch_manager(scoped_ptr<net::SdchManager>(new SdchManager()));
}
storage->set_transport_security_state(
@@ -346,13 +352,17 @@ scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
}
if (http_server_properties_) {
- storage->set_http_server_properties(http_server_properties_.Pass());
+ storage->set_http_server_properties(std::move(http_server_properties_));
} else {
storage->set_http_server_properties(
scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
}
- storage->set_cert_verifier(CertVerifier::CreateDefault());
+ if (cert_verifier_) {
+ storage->set_cert_verifier(std::move(cert_verifier_));
+ } else {
+ storage->set_cert_verifier(CertVerifier::CreateDefault());
+ }
if (throttling_enabled_) {
storage->set_throttler_manager(
@@ -381,32 +391,47 @@ scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
http_network_session_params_.trusted_spdy_proxy;
network_session_params.next_protos = http_network_session_params_.next_protos;
network_session_params.enable_quic = http_network_session_params_.enable_quic;
- network_session_params.enable_insecure_quic =
- http_network_session_params_.enable_insecure_quic;
+ network_session_params.quic_max_server_configs_stored_in_properties =
+ http_network_session_params_.quic_max_server_configs_stored_in_properties;
+ network_session_params.quic_delay_tcp_race =
+ http_network_session_params_.quic_delay_tcp_race;
+ network_session_params.quic_max_number_of_lossy_connections =
+ http_network_session_params_.quic_max_number_of_lossy_connections;
+ network_session_params.quic_packet_loss_threshold =
+ http_network_session_params_.quic_packet_loss_threshold;
+ network_session_params.quic_idle_connection_timeout_seconds =
+ http_network_session_params_.quic_idle_connection_timeout_seconds;
network_session_params.quic_connection_options =
http_network_session_params_.quic_connection_options;
+ network_session_params.quic_host_whitelist =
+ http_network_session_params_.quic_host_whitelist;
+
+ storage->set_http_network_session(
+ make_scoped_ptr(new HttpNetworkSession(network_session_params)));
scoped_ptr<HttpTransactionFactory> http_transaction_factory;
if (http_cache_enabled_) {
- HttpCache::BackendFactory* http_cache_backend = NULL;
- if (http_cache_params_.type == HttpCacheParams::DISK) {
- http_cache_backend = new HttpCache::DefaultBackend(
- DISK_CACHE, CACHE_BACKEND_DEFAULT, http_cache_params_.path,
- http_cache_params_.max_size, context->GetFileTaskRunner());
+ scoped_ptr<HttpCache::BackendFactory> http_cache_backend;
+ if (http_cache_params_.type != HttpCacheParams::IN_MEMORY) {
+ BackendType backend_type =
+ http_cache_params_.type == HttpCacheParams::DISK
+ ? CACHE_BACKEND_DEFAULT
+ : CACHE_BACKEND_SIMPLE;
+ http_cache_backend.reset(new HttpCache::DefaultBackend(
+ DISK_CACHE, backend_type, http_cache_params_.path,
+ http_cache_params_.max_size, context->GetFileTaskRunner()));
} else {
http_cache_backend =
HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size);
}
- http_transaction_factory.reset(
- new HttpCache(network_session_params, http_cache_backend));
+ http_transaction_factory.reset(new HttpCache(
+ storage->http_network_session(), std::move(http_cache_backend), true));
} else {
- scoped_refptr<HttpNetworkSession> network_session(
- new HttpNetworkSession(network_session_params));
-
- http_transaction_factory.reset(new HttpNetworkLayer(network_session.get()));
+ http_transaction_factory.reset(
+ new HttpNetworkLayer(storage->http_network_session()));
}
- storage->set_http_transaction_factory(http_transaction_factory.Pass());
+ storage->set_http_transaction_factory(std::move(http_transaction_factory));
URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl;
if (data_enabled_)
@@ -435,18 +460,17 @@ scoped_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
if (!url_request_interceptors_.empty()) {
// Set up interceptors in the reverse order.
- for (ScopedVector<net::URLRequestInterceptor>::reverse_iterator i =
- url_request_interceptors_.rbegin();
+ for (auto i = url_request_interceptors_.rbegin();
i != url_request_interceptors_.rend(); ++i) {
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
- top_job_factory.Pass(), make_scoped_ptr(*i)));
+ std::move(top_job_factory), std::move(*i)));
}
- url_request_interceptors_.weak_clear();
+ url_request_interceptors_.clear();
}
- storage->set_job_factory(top_job_factory.Pass());
+ storage->set_job_factory(std::move(top_job_factory));
// TODO(willchan): Support sdch.
- return context.Pass();
+ return std::move(context);
}
} // namespace net
diff --git a/chromium/net/url_request/url_request_context_builder.h b/chromium/net/url_request/url_request_context_builder.h
index ba5b3f6a447..b955c96c797 100644
--- a/chromium/net/url_request/url_request_context_builder.h
+++ b/chromium/net/url_request/url_request_context_builder.h
@@ -14,14 +14,15 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_H_
#define NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_H_
+#include <stdint.h>
#include <string>
-#include <vector>
+#include <unordered_map>
+#include <utility>
-#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
#include "net/base/network_delegate.h"
@@ -52,8 +53,12 @@ class NET_EXPORT URLRequestContextBuilder {
public:
struct NET_EXPORT HttpCacheParams {
enum Type {
+ // In-memory cache.
IN_MEMORY,
+ // Disk cache using "default" backend.
DISK,
+ // Disk cache using "simple" backend (SimpleBackendImpl).
+ DISK_SIMPLE,
};
HttpCacheParams();
@@ -77,13 +82,18 @@ class NET_EXPORT URLRequestContextBuilder {
// These fields mirror those in HttpNetworkSession::Params;
bool ignore_certificate_errors;
HostMappingRules* host_mapping_rules;
- uint16 testing_fixed_http_port;
- uint16 testing_fixed_https_port;
+ uint16_t testing_fixed_http_port;
+ uint16_t testing_fixed_https_port;
NextProtoVector next_protos;
std::string trusted_spdy_proxy;
bool use_alternative_services;
bool enable_quic;
- bool enable_insecure_quic;
+ int quic_max_server_configs_stored_in_properties;
+ bool quic_delay_tcp_race;
+ int quic_max_number_of_lossy_connections;
+ std::unordered_set<std::string> quic_host_whitelist;
+ float quic_packet_loss_threshold;
+ int quic_idle_connection_timeout_seconds;
QuicTagVector quic_connection_options;
};
@@ -102,10 +112,10 @@ class NET_EXPORT URLRequestContextBuilder {
// set, will be used to construct a ProxyService.
void set_proxy_config_service(
scoped_ptr<ProxyConfigService> proxy_config_service) {
- proxy_config_service_ = proxy_config_service.Pass();
+ proxy_config_service_ = std::move(proxy_config_service);
}
void set_proxy_service(scoped_ptr<ProxyService> proxy_service) {
- proxy_service_ = proxy_service.Pass();
+ proxy_service_ = std::move(proxy_service);
}
// Call these functions to specify hard-coded Accept-Language
@@ -145,24 +155,23 @@ class NET_EXPORT URLRequestContextBuilder {
// By default host_resolver is constructed with CreateDefaultResolver.
void set_host_resolver(scoped_ptr<HostResolver> host_resolver) {
- host_resolver_ = host_resolver.Pass();
+ host_resolver_ = std::move(host_resolver);
}
// Uses BasicNetworkDelegate by default. Note that calling Build will unset
// any custom delegate in builder, so this must be called each time before
// Build is called.
void set_network_delegate(scoped_ptr<NetworkDelegate> delegate) {
- network_delegate_ = delegate.Pass();
+ network_delegate_ = std::move(delegate);
}
- // Adds additional auth handler factories to be used in addition to what is
- // provided in the default |HttpAuthHandlerRegistryFactory|. The auth |scheme|
- // and |factory| are provided. The builder takes ownership of the factory and
- // Build() must be called after this method.
- void add_http_auth_handler_factory(const std::string& scheme,
- HttpAuthHandlerFactory* factory) {
- extra_http_auth_handlers_.push_back(SchemeFactory(scheme, factory));
- }
+ // Sets a specific HttpAuthHandlerFactory to be used by the URLRequestContext
+ // rather than the default |HttpAuthHandlerRegistryFactory|. The builder
+ // takes ownership of the factory and will eventually transfer it to the new
+ // URLRequestContext. Note that since Build will transfer ownership, the
+ // custom factory will be unset and this must be called before the next Build
+ // to set another custom one.
+ void SetHttpAuthHandlerFactory(scoped_ptr<HttpAuthHandlerFactory> factory);
// By default HttpCache is enabled with a default constructed HttpCacheParams.
void EnableHttpCache(const HttpCacheParams& params);
@@ -183,16 +192,44 @@ class NET_EXPORT URLRequestContextBuilder {
void SetSpdyAndQuicEnabled(bool spdy_enabled,
bool quic_enabled);
- void set_enable_insecure_quic(bool enable_insecure_quic) {
- http_network_session_params_.enable_insecure_quic = enable_insecure_quic;
- }
-
void set_quic_connection_options(
const QuicTagVector& quic_connection_options) {
http_network_session_params_.quic_connection_options =
quic_connection_options;
}
+ void set_quic_max_server_configs_stored_in_properties(
+ int quic_max_server_configs_stored_in_properties) {
+ http_network_session_params_.quic_max_server_configs_stored_in_properties =
+ quic_max_server_configs_stored_in_properties;
+ }
+
+ void set_quic_delay_tcp_race(bool quic_delay_tcp_race) {
+ http_network_session_params_.quic_delay_tcp_race = quic_delay_tcp_race;
+ }
+
+ void set_quic_max_number_of_lossy_connections(
+ int quic_max_number_of_lossy_connections) {
+ http_network_session_params_.quic_max_number_of_lossy_connections =
+ quic_max_number_of_lossy_connections;
+ }
+
+ void set_quic_packet_loss_threshold(float quic_packet_loss_threshold) {
+ http_network_session_params_.quic_packet_loss_threshold =
+ quic_packet_loss_threshold;
+ }
+
+ void set_quic_idle_connection_timeout_seconds(
+ int quic_idle_connection_timeout_seconds) {
+ http_network_session_params_.quic_idle_connection_timeout_seconds =
+ quic_idle_connection_timeout_seconds;
+ }
+
+ void set_quic_host_whitelist(
+ const std::unordered_set<std::string>& quic_host_whitelist) {
+ http_network_session_params_.quic_host_whitelist = quic_host_whitelist;
+ }
+
void set_throttling_enabled(bool throttling_enabled) {
throttling_enabled_ = throttling_enabled;
}
@@ -201,8 +238,10 @@ class NET_EXPORT URLRequestContextBuilder {
backoff_enabled_ = backoff_enabled;
}
+ void SetCertVerifier(scoped_ptr<CertVerifier> cert_verifier);
+
void SetInterceptors(
- ScopedVector<URLRequestInterceptor> url_request_interceptors);
+ std::vector<scoped_ptr<URLRequestInterceptor>> url_request_interceptors);
// Override the default in-memory cookie store and channel id service.
// |cookie_store| must not be NULL. |channel_id_service| may be NULL to
@@ -235,14 +274,6 @@ class NET_EXPORT URLRequestContextBuilder {
scoped_ptr<URLRequestContext> Build();
private:
- struct NET_EXPORT SchemeFactory {
- SchemeFactory(const std::string& scheme, HttpAuthHandlerFactory* factory);
- ~SchemeFactory();
-
- std::string scheme;
- HttpAuthHandlerFactory* factory;
- };
-
std::string accept_language_;
std::string user_agent_;
// Include support for data:// requests.
@@ -272,8 +303,9 @@ class NET_EXPORT URLRequestContextBuilder {
scoped_ptr<NetworkDelegate> network_delegate_;
scoped_refptr<CookieStore> cookie_store_;
scoped_ptr<FtpTransactionFactory> ftp_transaction_factory_;
- std::vector<SchemeFactory> extra_http_auth_handlers_;
- ScopedVector<URLRequestInterceptor> url_request_interceptors_;
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
+ scoped_ptr<CertVerifier> cert_verifier_;
+ std::vector<scoped_ptr<URLRequestInterceptor>> url_request_interceptors_;
scoped_ptr<HttpServerProperties> http_server_properties_;
DISALLOW_COPY_AND_ASSIGN(URLRequestContextBuilder);
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 e37b51e6b36..e4f04f5be3e 100644
--- a/chromium/net/url_request/url_request_context_builder_unittest.cc
+++ b/chromium/net/url_request/url_request_context_builder_unittest.cc
@@ -7,9 +7,10 @@
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "net/base/request_priority.h"
+#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -26,8 +27,8 @@ namespace {
class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
public:
- explicit MockHttpAuthHandlerFactory(int return_code) :
- return_code_(return_code) {}
+ MockHttpAuthHandlerFactory(std::string supported_scheme, int return_code)
+ : return_code_(return_code), supported_scheme_(supported_scheme) {}
~MockHttpAuthHandlerFactory() override {}
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
@@ -38,27 +39,29 @@ class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
const BoundNetLog& net_log,
scoped_ptr<HttpAuthHandler>* handler) override {
handler->reset();
- return return_code_;
+
+ return challenge->scheme() == supported_scheme_
+ ? return_code_
+ : ERR_UNSUPPORTED_AUTH_SCHEME;
}
private:
int return_code_;
+ std::string supported_scheme_;
};
class URLRequestContextBuilderTest : public PlatformTest {
protected:
- URLRequestContextBuilderTest()
- : test_server_(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath(
- FILE_PATH_LITERAL("net/data/url_request_unittest"))) {
+ URLRequestContextBuilderTest() {
+ 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(make_scoped_ptr(
new ProxyConfigServiceFixed(ProxyConfig::CreateDirect())));
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
}
- SpawnedTestServer test_server_;
+ EmbeddedTestServer test_server_;
URLRequestContextBuilder builder_;
};
@@ -68,7 +71,7 @@ TEST_F(URLRequestContextBuilderTest, DefaultSettings) {
scoped_ptr<URLRequestContext> context(builder_.Build());
TestDelegate delegate;
scoped_ptr<URLRequest> request(context->CreateRequest(
- test_server_.GetURL("echoheader?Foo"), DEFAULT_PRIORITY, &delegate));
+ test_server_.GetURL("/echoheader?Foo"), DEFAULT_PRIORITY, &delegate));
request->set_method("GET");
request->SetExtraRequestHeaderByName("Foo", "Bar", false);
request->Start();
@@ -83,7 +86,7 @@ TEST_F(URLRequestContextBuilderTest, UserAgent) {
scoped_ptr<URLRequestContext> context(builder_.Build());
TestDelegate delegate;
scoped_ptr<URLRequest> request(
- context->CreateRequest(test_server_.GetURL("echoheader?User-Agent"),
+ context->CreateRequest(test_server_.GetURL("/echoheader?User-Agent"),
DEFAULT_PRIORITY, &delegate));
request->set_method("GET");
request->Start();
@@ -91,15 +94,25 @@ TEST_F(URLRequestContextBuilderTest, UserAgent) {
EXPECT_EQ("Bar", delegate.data_received());
}
-TEST_F(URLRequestContextBuilderTest, ExtraHttpAuthHandlerFactory) {
+TEST_F(URLRequestContextBuilderTest, DefaultHttpAuthHandlerFactory) {
+ GURL gurl("www.google.com");
+ scoped_ptr<HttpAuthHandler> handler;
+ scoped_ptr<URLRequestContext> context(builder_.Build());
+
+ // Verify that the default basic handler is present
+ EXPECT_EQ(OK,
+ context->http_auth_handler_factory()->CreateAuthHandlerFromString(
+ "basic", HttpAuth::AUTH_SERVER, gurl, BoundNetLog(), &handler));
+}
+
+TEST_F(URLRequestContextBuilderTest, CustomHttpAuthHandlerFactory) {
GURL gurl("www.google.com");
const int kBasicReturnCode = OK;
- MockHttpAuthHandlerFactory* mock_factory_basic =
- new MockHttpAuthHandlerFactory(kBasicReturnCode);
scoped_ptr<HttpAuthHandler> handler;
- builder_.add_http_auth_handler_factory("ExtraScheme", mock_factory_basic);
+ builder_.SetHttpAuthHandlerFactory(make_scoped_ptr(
+ new MockHttpAuthHandlerFactory("ExtraScheme", kBasicReturnCode)));
scoped_ptr<URLRequestContext> context(builder_.Build());
- // Verify that a handler is returned for and added scheme.
+ // Verify that a handler is returned for a custom scheme.
EXPECT_EQ(kBasicReturnCode,
context->http_auth_handler_factory()->CreateAuthHandlerFromString(
"ExtraScheme",
@@ -107,6 +120,12 @@ TEST_F(URLRequestContextBuilderTest, ExtraHttpAuthHandlerFactory) {
gurl,
BoundNetLog(),
&handler));
+
+ // Verify that the default basic handler isn't present
+ EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
+ context->http_auth_handler_factory()->CreateAuthHandlerFromString(
+ "basic", HttpAuth::AUTH_SERVER, gurl, BoundNetLog(), &handler));
+
// Verify that a handler isn't returned for a bogus scheme.
EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
context->http_auth_handler_factory()->CreateAuthHandlerFromString(
diff --git a/chromium/net/url_request/url_request_context_storage.cc b/chromium/net/url_request/url_request_context_storage.cc
index 451fa967e54..399bc47caab 100644
--- a/chromium/net/url_request/url_request_context_storage.cc
+++ b/chromium/net/url_request/url_request_context_storage.cc
@@ -4,6 +4,8 @@
#include "net/url_request/url_request_context_storage.h"
+#include <utility>
+
#include "base/logging.h"
#include "net/base/network_delegate.h"
#include "net/base/sdch_manager.h"
@@ -34,37 +36,37 @@ URLRequestContextStorage::~URLRequestContextStorage() {}
void URLRequestContextStorage::set_net_log(scoped_ptr<NetLog> net_log) {
context_->set_net_log(net_log.get());
- net_log_ = net_log.Pass();
+ net_log_ = std::move(net_log);
}
void URLRequestContextStorage::set_host_resolver(
scoped_ptr<HostResolver> host_resolver) {
context_->set_host_resolver(host_resolver.get());
- host_resolver_ = host_resolver.Pass();
+ host_resolver_ = std::move(host_resolver);
}
void URLRequestContextStorage::set_cert_verifier(
scoped_ptr<CertVerifier> cert_verifier) {
context_->set_cert_verifier(cert_verifier.get());
- cert_verifier_ = cert_verifier.Pass();
+ cert_verifier_ = std::move(cert_verifier);
}
void URLRequestContextStorage::set_channel_id_service(
scoped_ptr<ChannelIDService> channel_id_service) {
context_->set_channel_id_service(channel_id_service.get());
- channel_id_service_ = channel_id_service.Pass();
+ channel_id_service_ = std::move(channel_id_service);
}
void URLRequestContextStorage::set_http_auth_handler_factory(
scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory) {
context_->set_http_auth_handler_factory(http_auth_handler_factory.get());
- http_auth_handler_factory_ = http_auth_handler_factory.Pass();
+ http_auth_handler_factory_ = std::move(http_auth_handler_factory);
}
void URLRequestContextStorage::set_proxy_service(
scoped_ptr<ProxyService> proxy_service) {
context_->set_proxy_service(proxy_service.get());
- proxy_service_ = proxy_service.Pass();
+ proxy_service_ = std::move(proxy_service);
}
void URLRequestContextStorage::set_ssl_config_service(
@@ -76,12 +78,12 @@ void URLRequestContextStorage::set_ssl_config_service(
void URLRequestContextStorage::set_network_delegate(
scoped_ptr<NetworkDelegate> network_delegate) {
context_->set_network_delegate(network_delegate.get());
- network_delegate_ = network_delegate.Pass();
+ network_delegate_ = std::move(network_delegate);
}
void URLRequestContextStorage::set_http_server_properties(
scoped_ptr<HttpServerProperties> http_server_properties) {
- http_server_properties_ = http_server_properties.Pass();
+ http_server_properties_ = std::move(http_server_properties);
context_->set_http_server_properties(http_server_properties_->GetWeakPtr());
}
@@ -93,43 +95,48 @@ void URLRequestContextStorage::set_cookie_store(CookieStore* cookie_store) {
void URLRequestContextStorage::set_transport_security_state(
scoped_ptr<TransportSecurityState> transport_security_state) {
context_->set_transport_security_state(transport_security_state.get());
- transport_security_state_ = transport_security_state.Pass();
+ transport_security_state_ = std::move(transport_security_state);
+}
+
+void URLRequestContextStorage::set_http_network_session(
+ scoped_ptr<HttpNetworkSession> http_network_session) {
+ http_network_session_ = std::move(http_network_session);
}
void URLRequestContextStorage::set_http_transaction_factory(
scoped_ptr<HttpTransactionFactory> http_transaction_factory) {
context_->set_http_transaction_factory(http_transaction_factory.get());
- http_transaction_factory_ = http_transaction_factory.Pass();
+ http_transaction_factory_ = std::move(http_transaction_factory);
}
void URLRequestContextStorage::set_job_factory(
scoped_ptr<URLRequestJobFactory> job_factory) {
context_->set_job_factory(job_factory.get());
- job_factory_ = job_factory.Pass();
+ job_factory_ = std::move(job_factory);
}
void URLRequestContextStorage::set_throttler_manager(
scoped_ptr<URLRequestThrottlerManager> throttler_manager) {
context_->set_throttler_manager(throttler_manager.get());
- throttler_manager_ = throttler_manager.Pass();
+ throttler_manager_ = std::move(throttler_manager);
}
void URLRequestContextStorage::set_backoff_manager(
scoped_ptr<URLRequestBackoffManager> backoff_manager) {
context_->set_backoff_manager(backoff_manager.get());
- backoff_manager_ = backoff_manager.Pass();
+ backoff_manager_ = std::move(backoff_manager);
}
void URLRequestContextStorage::set_http_user_agent_settings(
scoped_ptr<HttpUserAgentSettings> http_user_agent_settings) {
context_->set_http_user_agent_settings(http_user_agent_settings.get());
- http_user_agent_settings_ = http_user_agent_settings.Pass();
+ http_user_agent_settings_ = std::move(http_user_agent_settings);
}
void URLRequestContextStorage::set_sdch_manager(
scoped_ptr<SdchManager> sdch_manager) {
context_->set_sdch_manager(sdch_manager.get());
- sdch_manager_ = sdch_manager.Pass();
+ sdch_manager_ = std::move(sdch_manager);
}
} // namespace net
diff --git a/chromium/net/url_request/url_request_context_storage.h b/chromium/net/url_request/url_request_context_storage.h
index 8e2bf0eab3d..f05e186001f 100644
--- a/chromium/net/url_request/url_request_context_storage.h
+++ b/chromium/net/url_request/url_request_context_storage.h
@@ -5,7 +5,7 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_CONTEXT_STORAGE_H_
#define NET_URL_REQUEST_URL_REQUEST_CONTEXT_STORAGE_H_
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -18,6 +18,7 @@ class CookieStore;
class FtpTransactionFactory;
class HostResolver;
class HttpAuthHandlerFactory;
+class HttpNetworkSession;
class HttpServerProperties;
class HttpTransactionFactory;
class HttpUserAgentSettings;
@@ -59,6 +60,8 @@ class NET_EXPORT URLRequestContextStorage {
void set_cookie_store(CookieStore* cookie_store);
void set_transport_security_state(
scoped_ptr<TransportSecurityState> transport_security_state);
+ void set_http_network_session(
+ scoped_ptr<HttpNetworkSession> http_network_session);
void set_http_transaction_factory(
scoped_ptr<HttpTransactionFactory> http_transaction_factory);
void set_job_factory(scoped_ptr<URLRequestJobFactory> job_factory);
@@ -70,6 +73,12 @@ class NET_EXPORT URLRequestContextStorage {
scoped_ptr<HttpUserAgentSettings> http_user_agent_settings);
void set_sdch_manager(scoped_ptr<SdchManager> sdch_manager);
+ // Everything else can be access through the URLRequestContext, but this
+ // cannot. Having an accessor for it makes usage a little cleaner.
+ HttpNetworkSession* http_network_session() const {
+ return http_network_session_.get();
+ }
+
private:
// We use a raw pointer to prevent reference cycles, since
// URLRequestContextStorage can often be contained within a URLRequestContext
@@ -92,6 +101,10 @@ class NET_EXPORT URLRequestContextStorage {
scoped_refptr<CookieStore> cookie_store_;
scoped_ptr<TransportSecurityState> transport_security_state_;
+ // Not actually pointed at by the URLRequestContext, but may be used (but not
+ // owned) by the HttpTransactionFactory.
+ scoped_ptr<HttpNetworkSession> http_network_session_;
+
scoped_ptr<HttpTransactionFactory> http_transaction_factory_;
scoped_ptr<URLRequestJobFactory> job_factory_;
scoped_ptr<URLRequestThrottlerManager> throttler_manager_;
diff --git a/chromium/net/url_request/url_request_data_job.h b/chromium/net/url_request/url_request_data_job.h
index 0b3c7fad1e2..9fb033d669e 100644
--- a/chromium/net/url_request/url_request_data_job.h
+++ b/chromium/net/url_request/url_request_data_job.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_simple_job.h"
diff --git a/chromium/net/url_request/url_request_data_job_unittest.cc b/chromium/net/url_request/url_request_data_job_unittest.cc
index 8c6d09398cd..b12bcb7c7d7 100644
--- a/chromium/net/url_request/url_request_data_job_unittest.cc
+++ b/chromium/net/url_request/url_request_data_job_unittest.cc
@@ -29,7 +29,7 @@ TEST(BuildResponseTest, Simple) {
EXPECT_EQ("US-ASCII", charset);
EXPECT_EQ("Hello", data);
- const HttpVersion& version = headers->GetParsedHttpVersion();
+ const HttpVersion& version = headers->GetHttpVersion();
EXPECT_EQ(1, version.major_value());
EXPECT_EQ(1, version.minor_value());
EXPECT_EQ("OK", headers->GetStatusText());
diff --git a/chromium/net/url_request/url_request_error_job.cc b/chromium/net/url_request/url_request_error_job.cc
index efbf4247d31..c2a75c1eff2 100644
--- a/chromium/net/url_request/url_request_error_job.cc
+++ b/chromium/net/url_request/url_request_error_job.cc
@@ -28,6 +28,11 @@ void URLRequestErrorJob::Start() {
base::Bind(&URLRequestErrorJob::StartAsync, weak_factory_.GetWeakPtr()));
}
+void URLRequestErrorJob::Kill() {
+ weak_factory_.InvalidateWeakPtrs();
+ URLRequestJob::Kill();
+}
+
void URLRequestErrorJob::StartAsync() {
NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error_));
}
diff --git a/chromium/net/url_request/url_request_error_job.h b/chromium/net/url_request/url_request_error_job.h
index 059db266f3c..efd6b6696e8 100644
--- a/chromium/net/url_request/url_request_error_job.h
+++ b/chromium/net/url_request/url_request_error_job.h
@@ -21,6 +21,7 @@ class NET_EXPORT URLRequestErrorJob : public URLRequestJob {
int error);
void Start() override;
+ void Kill() override;
private:
~URLRequestErrorJob() override;
diff --git a/chromium/net/url_request/url_request_file_dir_job.cc b/chromium/net/url_request/url_request_file_dir_job.cc
index 64597d569e7..b331e442765 100644
--- a/chromium/net/url_request/url_request_file_dir_job.cc
+++ b/chromium/net/url_request/url_request_file_dir_job.cc
@@ -12,9 +12,8 @@
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "net/base/directory_listing.h"
#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "net/url_request/url_request_status.h"
#include "url/gurl.h"
@@ -66,23 +65,19 @@ void URLRequestFileDirJob::Kill() {
weak_factory_.InvalidateWeakPtrs();
}
-bool URLRequestFileDirJob::ReadRawData(IOBuffer* buf, int buf_size,
- int* bytes_read) {
- DCHECK(bytes_read);
- *bytes_read = 0;
-
+int URLRequestFileDirJob::ReadRawData(IOBuffer* buf, int buf_size) {
if (is_done())
- return true;
+ return 0;
- if (FillReadBuffer(buf->data(), buf_size, bytes_read))
- return true;
+ int bytes_read = 0;
+ if (FillReadBuffer(buf->data(), buf_size, &bytes_read))
+ return bytes_read;
// We are waiting for more data
read_pending_ = true;
read_buffer_ = buf;
read_buffer_length_ = buf_size;
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- return false;
+ return ERR_IO_PENDING;
}
bool URLRequestFileDirJob::GetMimeType(std::string* mime_type) const {
@@ -131,40 +126,45 @@ void URLRequestFileDirJob::OnListFile(
data.info.GetLastModifiedTime()));
// TODO(darin): coalesce more?
- CompleteRead();
+ CompleteRead(OK);
}
void URLRequestFileDirJob::OnListDone(int error) {
DCHECK(!canceled_);
- if (error != OK) {
- read_pending_ = false;
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, error));
- } else {
+ DCHECK_LE(error, OK);
+ if (error == OK)
list_complete_ = true;
- CompleteRead();
- }
+ CompleteRead(static_cast<Error>(error));
}
URLRequestFileDirJob::~URLRequestFileDirJob() {}
-void URLRequestFileDirJob::CompleteRead() {
- if (read_pending_) {
- int bytes_read;
+void URLRequestFileDirJob::CompleteRead(Error status) {
+ DCHECK_LE(status, OK);
+ DCHECK_NE(status, ERR_IO_PENDING);
+
+ // Do nothing if there is no read pending.
+ if (!read_pending_)
+ return;
+
+ int result = status;
+ if (status == OK) {
+ int filled_bytes = 0;
if (FillReadBuffer(read_buffer_->data(), read_buffer_length_,
- &bytes_read)) {
+ &filled_bytes)) {
+ result = filled_bytes;
// We completed the read, so reset the read buffer.
- read_pending_ = false;
read_buffer_ = NULL;
read_buffer_length_ = 0;
-
- SetStatus(URLRequestStatus());
- NotifyReadComplete(bytes_read);
} else {
NOTREACHED();
// TODO: Better error code.
- NotifyDone(URLRequestStatus::FromError(ERR_FAILED));
+ result = ERR_FAILED;
}
}
+
+ read_pending_ = false;
+ ReadRawDataComplete(result);
}
bool URLRequestFileDirJob::FillReadBuffer(char* buf, int buf_size,
diff --git a/chromium/net/url_request/url_request_file_dir_job.h b/chromium/net/url_request/url_request_file_dir_job.h
index dfb2d746dc4..a5db178b009 100644
--- a/chromium/net/url_request/url_request_file_dir_job.h
+++ b/chromium/net/url_request/url_request_file_dir_job.h
@@ -8,8 +8,10 @@
#include <string>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/directory_lister.h"
+#include "net/base/net_errors.h"
#include "net/url_request/url_request_job.h"
namespace net {
@@ -29,7 +31,7 @@ class URLRequestFileDirJob
// Overridden from URLRequestJob:
void Start() override;
void Kill() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
bool GetMimeType(std::string* mime_type) const override;
bool GetCharset(std::string* charset) override;
@@ -45,10 +47,10 @@ class URLRequestFileDirJob
// When we have data and a read has been pending, this function
// will fill the response buffer and notify the request
// appropriately.
- void CompleteRead();
+ void CompleteRead(Error error);
// Fills a buffer with the output.
- bool FillReadBuffer(char *buf, int buf_size, int *bytes_read);
+ bool FillReadBuffer(char* buf, int buf_size, int* bytes_read);
DirectoryLister lister_;
base::FilePath dir_path_;
@@ -67,6 +69,7 @@ class URLRequestFileDirJob
bool read_pending_;
scoped_refptr<IOBuffer> read_buffer_;
int read_buffer_length_;
+
base::WeakPtrFactory<URLRequestFileDirJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(URLRequestFileDirJob);
diff --git a/chromium/net/url_request/url_request_file_job.cc b/chromium/net/url_request/url_request_file_job.cc
index b035c0d701b..d853c9fd519 100644
--- a/chromium/net/url_request/url_request_file_job.cc
+++ b/chromium/net/url_request/url_request_file_job.cc
@@ -33,7 +33,6 @@
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/mime_util.h"
-#include "net/base/net_errors.h"
#include "net/filter/filter.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request_error_job.h"
@@ -63,6 +62,7 @@ URLRequestFileJob::URLRequestFileJob(
stream_(new FileStream(file_task_runner)),
file_task_runner_(file_task_runner),
remaining_bytes_(0),
+ range_parse_result_(OK),
weak_ptr_factory_(this) {}
void URLRequestFileJob::Start() {
@@ -83,22 +83,17 @@ void URLRequestFileJob::Kill() {
URLRequestJob::Kill();
}
-bool URLRequestFileJob::ReadRawData(IOBuffer* dest,
- int dest_size,
- int* bytes_read) {
+int URLRequestFileJob::ReadRawData(IOBuffer* dest, int dest_size) {
DCHECK_NE(dest_size, 0);
- DCHECK(bytes_read);
DCHECK_GE(remaining_bytes_, 0);
if (remaining_bytes_ < dest_size)
- dest_size = static_cast<int>(remaining_bytes_);
+ dest_size = remaining_bytes_;
// If we should copy zero bytes because |remaining_bytes_| is zero, short
// circuit here.
- if (!dest_size) {
- *bytes_read = 0;
- return true;
- }
+ if (!dest_size)
+ return 0;
int rv = stream_->Read(dest,
dest_size,
@@ -106,20 +101,11 @@ bool URLRequestFileJob::ReadRawData(IOBuffer* dest,
weak_ptr_factory_.GetWeakPtr(),
make_scoped_refptr(dest)));
if (rv >= 0) {
- // Data is immediately available.
- *bytes_read = rv;
remaining_bytes_ -= rv;
DCHECK_GE(remaining_bytes_, 0);
- return true;
}
- // Otherwise, a read error occured. We may just need to wait...
- if (rv == ERR_IO_PENDING) {
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- } else {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
- }
- return false;
+ return rv;
}
bool URLRequestFileJob::IsRedirectResponse(GURL* location,
@@ -147,7 +133,7 @@ bool URLRequestFileJob::IsRedirectResponse(GURL* location,
bool resolved;
resolved = base::win::ResolveShortcut(new_path, &new_path, NULL);
- // If shortcut is not resolved succesfully, do not redirect.
+ // If shortcut is not resolved successfully, do not redirect.
if (!resolved)
return false;
@@ -179,7 +165,10 @@ void URLRequestFileJob::SetExtraRequestHeaders(
const HttpRequestHeaders& headers) {
std::string range_header;
if (headers.GetHeader(HttpRequestHeaders::kRange, &range_header)) {
- // We only care about "Range" header here.
+ // This job only cares about the Range header. This method stashes the value
+ // for later use in DidOpen(), which is responsible for some of the range
+ // validation as well. NotifyStartError is not legal to call here since
+ // the job has not started.
std::vector<HttpByteRange> ranges;
if (HttpUtil::ParseRangeHeader(range_header, &ranges)) {
if (ranges.size() == 1) {
@@ -189,15 +178,13 @@ void URLRequestFileJob::SetExtraRequestHeaders(
// because we need to do multipart encoding here.
// TODO(hclam): decide whether we want to support multiple range
// requests.
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
- ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ range_parse_result_ = net::ERR_REQUEST_RANGE_NOT_SATISFIABLE;
}
}
}
}
-void URLRequestFileJob::OnSeekComplete(int64 result) {
-}
+void URLRequestFileJob::OnSeekComplete(int64_t result) {}
void URLRequestFileJob::OnReadComplete(IOBuffer* buf, int result) {
}
@@ -251,13 +238,19 @@ void URLRequestFileJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) {
void URLRequestFileJob::DidOpen(int result) {
if (result != OK) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
+ return;
+ }
+
+ if (range_parse_result_ != net::OK) {
+ NotifyStartError(
+ URLRequestStatus(URLRequestStatus::FAILED, range_parse_result_));
return;
}
if (!byte_range_.ComputeBounds(meta_info_.file_size)) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
- ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
@@ -282,11 +275,11 @@ void URLRequestFileJob::DidOpen(int result) {
}
}
-void URLRequestFileJob::DidSeek(int64 result) {
+void URLRequestFileJob::DidSeek(int64_t result) {
OnSeekComplete(result);
if (result != byte_range_.first_byte_position()) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
- ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
+ ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
@@ -295,8 +288,7 @@ void URLRequestFileJob::DidSeek(int64 result) {
}
void URLRequestFileJob::DidRead(scoped_refptr<IOBuffer> buf, int result) {
- if (result > 0) {
- SetStatus(URLRequestStatus()); // Clear the IO_PENDING status
+ if (result >= 0) {
remaining_bytes_ -= result;
DCHECK_GE(remaining_bytes_, 0);
}
@@ -304,13 +296,7 @@ void URLRequestFileJob::DidRead(scoped_refptr<IOBuffer> buf, int result) {
OnReadComplete(buf.get(), result);
buf = NULL;
- if (result == 0) {
- NotifyDone(URLRequestStatus());
- } else if (result < 0) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
- }
-
- NotifyReadComplete(result);
+ ReadRawDataComplete(result);
}
} // namespace net
diff --git a/chromium/net/url_request/url_request_file_job.h b/chromium/net/url_request/url_request_file_job.h
index 0436dac5698..6aa2bbef287 100644
--- a/chromium/net/url_request/url_request_file_job.h
+++ b/chromium/net/url_request/url_request_file_job.h
@@ -5,12 +5,16 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_FILE_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_FILE_JOB_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/files/file_path.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "net/base/net_errors.h"
#include "net/base/net_export.h"
#include "net/http/http_byte_range.h"
#include "net/url_request/url_request.h"
@@ -38,20 +42,20 @@ class NET_EXPORT URLRequestFileJob : public URLRequestJob {
// URLRequestJob:
void Start() override;
void Kill() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
bool IsRedirectResponse(GURL* location, int* http_status_code) override;
Filter* SetupFilter() const override;
bool GetMimeType(std::string* mime_type) const override;
void SetExtraRequestHeaders(const HttpRequestHeaders& headers) override;
// An interface for subclasses who wish to monitor read operations.
- virtual void OnSeekComplete(int64 result);
+ virtual void OnSeekComplete(int64_t result);
virtual void OnReadComplete(IOBuffer* buf, int result);
protected:
~URLRequestFileJob() override;
- int64 remaining_bytes() const { return remaining_bytes_; }
+ int64_t remaining_bytes() const { return remaining_bytes_; }
// The OS-specific full path name of the file
base::FilePath file_path_;
@@ -64,7 +68,7 @@ class NET_EXPORT URLRequestFileJob : public URLRequestJob {
FileMetaInfo();
// Size of the file.
- int64 file_size;
+ int64_t file_size;
// Mime type associated with the file.
std::string mime_type;
// Result returned from GetMimeTypeFromFile(), i.e. flag showing whether
@@ -88,7 +92,7 @@ class NET_EXPORT URLRequestFileJob : public URLRequestJob {
// Callback after seeking to the beginning of |byte_range_| in the file
// on a background thread.
- void DidSeek(int64 result);
+ void DidSeek(int64_t result);
// Callback after data is asynchronously read from the file into |buf|.
void DidRead(scoped_refptr<IOBuffer> buf, int result);
@@ -97,8 +101,11 @@ class NET_EXPORT URLRequestFileJob : public URLRequestJob {
FileMetaInfo meta_info_;
const scoped_refptr<base::TaskRunner> file_task_runner_;
+ std::vector<HttpByteRange> byte_ranges_;
HttpByteRange byte_range_;
- int64 remaining_bytes_;
+ int64_t remaining_bytes_;
+
+ Error range_parse_result_;
base::WeakPtrFactory<URLRequestFileJob> weak_ptr_factory_;
diff --git a/chromium/net/url_request/url_request_file_job_unittest.cc b/chromium/net/url_request/url_request_file_job_unittest.cc
index 06acd3283c6..d8e0691d548 100644
--- a/chromium/net/url_request/url_request_file_job_unittest.cc
+++ b/chromium/net/url_request/url_request_file_job_unittest.cc
@@ -6,6 +6,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
@@ -21,62 +22,72 @@ namespace net {
namespace {
-// A URLRequestFileJob for testing OnSeekComplete / OnReadComplete callbacks.
-class URLRequestFileJobWithCallbacks : public URLRequestFileJob {
+// A URLRequestFileJob for testing values passed to OnSeekComplete and
+// OnReadComplete.
+class TestURLRequestFileJob : public URLRequestFileJob {
public:
- URLRequestFileJobWithCallbacks(
- URLRequest* request,
- NetworkDelegate* network_delegate,
- const base::FilePath& file_path,
- const scoped_refptr<base::TaskRunner>& file_task_runner)
+ // |seek_position| will be set to the value passed in to OnSeekComplete.
+ // |observed_content| will be set to the concatenated data from all calls to
+ // OnReadComplete.
+ TestURLRequestFileJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const base::FilePath& file_path,
+ const scoped_refptr<base::TaskRunner>& file_task_runner,
+ int64_t* seek_position,
+ std::string* observed_content)
: URLRequestFileJob(request,
network_delegate,
file_path,
file_task_runner),
- seek_position_(0) {
+ seek_position_(seek_position),
+ observed_content_(observed_content) {
+ *seek_position_ = 0;
+ observed_content_->clear();
}
- int64 seek_position() { return seek_position_; }
- const std::vector<std::string>& data_chunks() { return data_chunks_; }
+ ~TestURLRequestFileJob() override {}
protected:
- ~URLRequestFileJobWithCallbacks() override {}
-
- void OnSeekComplete(int64 result) override {
- ASSERT_EQ(seek_position_, 0);
- seek_position_ = result;
+ void OnSeekComplete(int64_t result) override {
+ ASSERT_EQ(*seek_position_, 0);
+ *seek_position_ = result;
}
void OnReadComplete(IOBuffer* buf, int result) override {
- data_chunks_.push_back(std::string(buf->data(), result));
+ observed_content_->append(std::string(buf->data(), result));
}
- int64 seek_position_;
- std::vector<std::string> data_chunks_;
+ int64_t* const seek_position_;
+ std::string* const observed_content_;
};
-// A URLRequestJobFactory that will return URLRequestFileJobWithCallbacks
-// instances for file:// scheme URLs.
-class CallbacksJobFactory : public URLRequestJobFactory {
+// A URLRequestJobFactory that will return TestURLRequestFileJob instances for
+// file:// scheme URLs. Can only be used to create a single job.
+class TestJobFactory : public URLRequestJobFactory {
public:
- class JobObserver {
- public:
- virtual void OnJobCreated(URLRequestFileJobWithCallbacks* job) = 0;
- };
-
- CallbacksJobFactory(const base::FilePath& path, JobObserver* observer)
- : path_(path), observer_(observer) {
+ TestJobFactory(const base::FilePath& path,
+ int64_t* seek_position,
+ std::string* observed_content)
+ : path_(path),
+ seek_position_(seek_position),
+ observed_content_(observed_content) {
+ CHECK(seek_position_);
+ CHECK(observed_content_);
}
- ~CallbacksJobFactory() override {}
+ ~TestJobFactory() override {}
URLRequestJob* MaybeCreateJobWithProtocolHandler(
const std::string& scheme,
URLRequest* request,
NetworkDelegate* network_delegate) const override {
- URLRequestFileJobWithCallbacks* job = new URLRequestFileJobWithCallbacks(
- request, network_delegate, path_, base::ThreadTaskRunnerHandle::Get());
- observer_->OnJobCreated(job);
+ CHECK(seek_position_);
+ CHECK(observed_content_);
+ URLRequestJob* job = new TestURLRequestFileJob(
+ request, network_delegate, path_, base::ThreadTaskRunnerHandle::Get(),
+ seek_position_, observed_content_);
+ seek_position_ = nullptr;
+ observed_content_ = nullptr;
return job;
}
@@ -105,8 +116,11 @@ class CallbacksJobFactory : public URLRequestJobFactory {
}
private:
- base::FilePath path_;
- JobObserver* observer_;
+ const base::FilePath path_;
+
+ // These are mutable because MaybeCreateJobWithProtocolHandler is const.
+ mutable int64_t* seek_position_;
+ mutable std::string* observed_content_;
};
// Helper function to create a file in |directory| filled with
@@ -124,20 +138,6 @@ bool CreateTempFileWithContent(const std::string& content,
return base::WriteFile(*path, content.c_str(), content.length());
}
-class JobObserverImpl : public CallbacksJobFactory::JobObserver {
- public:
- void OnJobCreated(URLRequestFileJobWithCallbacks* job) override {
- jobs_.push_back(job);
- }
-
- typedef std::vector<scoped_refptr<URLRequestFileJobWithCallbacks> > JobList;
-
- const JobList& jobs() { return jobs_; }
-
- protected:
- JobList jobs_;
-};
-
// A simple holder for start/end used in http range requests.
struct Range {
int start;
@@ -169,7 +169,6 @@ class URLRequestFileJobEventsTest : public testing::Test {
// observed.
void RunRequest(const std::string& content, const Range* range);
- JobObserverImpl observer_;
TestURLRequestContext context_;
TestDelegate delegate_;
};
@@ -182,51 +181,47 @@ void URLRequestFileJobEventsTest::RunRequest(const std::string& content,
ASSERT_TRUE(directory.CreateUniqueTempDir());
base::FilePath path;
ASSERT_TRUE(CreateTempFileWithContent(content, directory, &path));
- CallbacksJobFactory factory(path, &observer_);
- context_.set_job_factory(&factory);
-
- scoped_ptr<URLRequest> request(context_.CreateRequest(
- FilePathToFileURL(path), DEFAULT_PRIORITY, &delegate_));
- if (range) {
- ASSERT_GE(range->start, 0);
- ASSERT_GE(range->end, 0);
- ASSERT_LE(range->start, range->end);
- ASSERT_LT(static_cast<unsigned int>(range->end), content.length());
- std::string range_value =
- base::StringPrintf("bytes=%d-%d", range->start, range->end);
- request->SetExtraRequestHeaderByName(
- HttpRequestHeaders::kRange, range_value, true /*overwrite*/);
- }
- request->Start();
- base::RunLoop loop;
- loop.Run();
-
- EXPECT_FALSE(delegate_.request_failed());
- int expected_length =
- range ? (range->end - range->start + 1) : content.length();
- EXPECT_EQ(delegate_.bytes_received(), expected_length);
-
- std::string expected_content;
- if (range) {
- expected_content.insert(0, content, range->start, expected_length);
- } else {
- expected_content = content;
+ {
+ int64_t seek_position;
+ std::string observed_content;
+ TestJobFactory factory(path, &seek_position, &observed_content);
+ context_.set_job_factory(&factory);
+
+ scoped_ptr<URLRequest> request(context_.CreateRequest(
+ FilePathToFileURL(path), DEFAULT_PRIORITY, &delegate_));
+ if (range) {
+ ASSERT_GE(range->start, 0);
+ ASSERT_GE(range->end, 0);
+ ASSERT_LE(range->start, range->end);
+ ASSERT_LT(static_cast<unsigned int>(range->end), content.length());
+ std::string range_value =
+ base::StringPrintf("bytes=%d-%d", range->start, range->end);
+ request->SetExtraRequestHeaderByName(HttpRequestHeaders::kRange,
+ range_value, true /*overwrite*/);
+ }
+ request->Start();
+
+ base::RunLoop().Run();
+
+ EXPECT_FALSE(delegate_.request_failed());
+ int expected_length =
+ range ? (range->end - range->start + 1) : content.length();
+ EXPECT_EQ(delegate_.bytes_received(), expected_length);
+
+ std::string expected_content;
+ if (range) {
+ expected_content.insert(0, content, range->start, expected_length);
+ } else {
+ expected_content = content;
+ }
+ EXPECT_TRUE(delegate_.data_received() == expected_content);
+
+ EXPECT_EQ(seek_position, range ? range->start : 0);
+ EXPECT_EQ(expected_content, observed_content);
}
- EXPECT_TRUE(delegate_.data_received() == expected_content);
-
- ASSERT_EQ(observer_.jobs().size(), 1u);
- ASSERT_EQ(observer_.jobs().at(0)->seek_position(), range ? range->start : 0);
-
- std::string observed_content;
- const std::vector<std::string>& chunks =
- observer_.jobs().at(0)->data_chunks();
- for (std::vector<std::string>::const_iterator i = chunks.begin();
- i != chunks.end();
- ++i) {
- observed_content.append(*i);
- }
- EXPECT_EQ(expected_content, observed_content);
+
+ base::RunLoop().RunUntilIdle();
}
// Helper function to make a character array filled with |size| bytes of
diff --git a/chromium/net/url_request/url_request_filter.cc b/chromium/net/url_request/url_request_filter.cc
index e28319d9670..83248e2fba7 100644
--- a/chromium/net/url_request/url_request_filter.cc
+++ b/chromium/net/url_request/url_request_filter.cc
@@ -53,7 +53,7 @@ void URLRequestFilter::AddHostnameInterceptor(
DCHECK(OnMessageLoopForInterceptorAddition());
DCHECK_EQ(0u, hostname_interceptor_map_.count(make_pair(scheme, hostname)));
hostname_interceptor_map_[make_pair(scheme, hostname)] =
- interceptor.release();
+ std::move(interceptor);
#ifndef NDEBUG
// Check to see if we're masking URLs in the url_interceptor_map_.
@@ -71,12 +71,9 @@ void URLRequestFilter::AddHostnameInterceptor(
void URLRequestFilter::RemoveHostnameHandler(const std::string& scheme,
const std::string& hostname) {
DCHECK(OnMessageLoopForInterceptorRemoval());
- HostnameInterceptorMap::iterator it =
- hostname_interceptor_map_.find(make_pair(scheme, hostname));
- DCHECK(it != hostname_interceptor_map_.end());
+ int removed = hostname_interceptor_map_.erase(make_pair(scheme, hostname));
+ DCHECK(removed);
- delete it->second;
- hostname_interceptor_map_.erase(it);
// Note that we don't unregister from the URLRequest ProtocolFactory as
// this would leave no protocol factory for the remaining hostname and URL
// handlers.
@@ -89,7 +86,7 @@ bool URLRequestFilter::AddUrlInterceptor(
if (!url.is_valid())
return false;
DCHECK_EQ(0u, url_interceptor_map_.count(url.spec()));
- url_interceptor_map_[url.spec()] = interceptor.release();
+ url_interceptor_map_.set(url.spec(), std::move(interceptor));
// Check to see if this URL is masked by a hostname handler.
DCHECK_EQ(0u, hostname_interceptor_map_.count(make_pair(url.scheme(),
@@ -100,11 +97,8 @@ bool URLRequestFilter::AddUrlInterceptor(
void URLRequestFilter::RemoveUrlHandler(const GURL& url) {
DCHECK(OnMessageLoopForInterceptorRemoval());
- URLInterceptorMap::iterator it = url_interceptor_map_.find(url.spec());
- DCHECK(it != url_interceptor_map_.end());
-
- delete it->second;
- url_interceptor_map_.erase(it);
+ int removed = url_interceptor_map_.erase(url.spec());
+ DCHECK(removed);
// Note that we don't unregister from the URLRequest ProtocolFactory as
// this would leave no protocol factory for the remaining hostname and URL
// handlers.
@@ -112,8 +106,8 @@ void URLRequestFilter::RemoveUrlHandler(const GURL& url) {
void URLRequestFilter::ClearHandlers() {
DCHECK(OnMessageLoopForInterceptorRemoval());
- STLDeleteValues(&url_interceptor_map_);
- STLDeleteValues(&hostname_interceptor_map_);
+ url_interceptor_map_.clear();
+ hostname_interceptor_map_.clear();
hit_count_ = 0;
}
diff --git a/chromium/net/url_request/url_request_filter.h b/chromium/net/url_request/url_request_filter.h
index 9dfac65c36c..7c460489133 100644
--- a/chromium/net/url_request/url_request_filter.h
+++ b/chromium/net/url_request/url_request_filter.h
@@ -8,6 +8,8 @@
#include <string>
#include "base/containers/hash_tables.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/url_request/url_request_interceptor.h"
@@ -70,10 +72,11 @@ class NET_EXPORT URLRequestFilter : public URLRequestInterceptor {
private:
// scheme,hostname -> URLRequestInterceptor
- typedef std::map<std::pair<std::string, std::string>,
- URLRequestInterceptor* > HostnameInterceptorMap;
+ using HostnameInterceptorMap = std::map<std::pair<std::string, std::string>,
+ scoped_ptr<URLRequestInterceptor>>;
// URL -> URLRequestInterceptor
- typedef base::hash_map<std::string, URLRequestInterceptor*> URLInterceptorMap;
+ using URLInterceptorMap =
+ base::ScopedPtrHashMap<std::string, scoped_ptr<URLRequestInterceptor>>;
URLRequestFilter();
~URLRequestFilter() override;
diff --git a/chromium/net/url_request/url_request_filter_unittest.cc b/chromium/net/url_request/url_request_filter_unittest.cc
index a7f8ca9733c..784f9a65a46 100644
--- a/chromium/net/url_request/url_request_filter_unittest.cc
+++ b/chromium/net/url_request/url_request_filter_unittest.cc
@@ -4,6 +4,7 @@
#include "net/url_request/url_request_filter.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/request_priority.h"
#include "net/url_request/url_request.h"
@@ -66,8 +67,8 @@ TEST(URLRequestFilter, BasicMatching) {
EXPECT_TRUE(filter->AddUrlInterceptor(
kUrl1, scoped_ptr<URLRequestInterceptor>(interceptor)));
{
- scoped_refptr<URLRequestJob> found =
- filter->MaybeInterceptRequest(request1.get(), NULL);
+ scoped_ptr<URLRequestJob> found(
+ filter->MaybeInterceptRequest(request1.get(), NULL));
EXPECT_TRUE(interceptor->WasLastJobCreated(found.get()));
}
EXPECT_EQ(filter->hit_count(), 1);
@@ -89,8 +90,8 @@ TEST(URLRequestFilter, BasicMatching) {
kUrl1.scheme(), kUrl1.host(),
scoped_ptr<URLRequestInterceptor>(interceptor));
{
- scoped_refptr<URLRequestJob> found =
- filter->MaybeInterceptRequest(request1.get(), NULL);
+ scoped_ptr<URLRequestJob> found(
+ filter->MaybeInterceptRequest(request1.get(), NULL));
EXPECT_TRUE(interceptor->WasLastJobCreated(found.get()));
}
EXPECT_EQ(1, filter->hit_count());
diff --git a/chromium/net/url_request/url_request_ftp_job.cc b/chromium/net/url_request/url_request_ftp_job.cc
index 2305c78480a..596363f8535 100644
--- a/chromium/net/url_request/url_request_ftp_job.cc
+++ b/chromium/net/url_request/url_request_ftp_job.cc
@@ -45,8 +45,7 @@ URLRequestFtpJob::URLRequestFtpJob(
}
URLRequestFtpJob::~URLRequestFtpJob() {
- if (pac_request_)
- proxy_service_->CancelPacRequest(pac_request_);
+ Kill();
}
bool URLRequestFtpJob::IsSafeRedirect(const GURL& location) {
@@ -119,6 +118,10 @@ void URLRequestFtpJob::Start() {
}
void URLRequestFtpJob::Kill() {
+ if (pac_request_) {
+ proxy_service_->CancelPacRequest(pac_request_);
+ pac_request_ = nullptr;
+ }
if (ftp_transaction_)
ftp_transaction_.reset();
if (http_transaction_)
@@ -155,7 +158,7 @@ void URLRequestFtpJob::StartFtpTransaction() {
DCHECK(!ftp_transaction_);
ftp_request_info_.url = request_->url();
- ftp_transaction_.reset(ftp_transaction_factory_->CreateTransaction());
+ ftp_transaction_ = ftp_transaction_factory_->CreateTransaction();
// No matter what, we want to report our status as IO pending since we will
// be notifying our consumer asynchronously via OnStartCompleted.
@@ -236,7 +239,7 @@ void URLRequestFtpJob::OnStartCompleted(int result) {
HandleAuthNeededResponse();
return;
} else {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
}
}
@@ -248,15 +251,7 @@ void URLRequestFtpJob::OnStartCompletedAsync(int result) {
void URLRequestFtpJob::OnReadCompleted(int result) {
read_in_progress_ = false;
- if (result == 0) {
- NotifyDone(URLRequestStatus());
- } else if (result < 0) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
- } else {
- // Clear the IO_PENDING status
- SetStatus(URLRequestStatus());
- }
- NotifyReadComplete(result);
+ ReadRawDataComplete(result);
}
void URLRequestFtpJob::RestartTransactionWithAuth() {
@@ -285,6 +280,8 @@ void URLRequestFtpJob::RestartTransactionWithAuth() {
}
LoadState URLRequestFtpJob::GetLoadState() const {
+ if (pac_request_)
+ return proxy_service_->GetLoadState(pac_request_);
if (proxy_info_.is_direct()) {
return ftp_transaction_ ?
ftp_transaction_->GetLoadState() : LOAD_STATE_IDLE;
@@ -347,14 +344,12 @@ UploadProgress URLRequestFtpJob::GetUploadProgress() const {
return UploadProgress();
}
-bool URLRequestFtpJob::ReadRawData(IOBuffer* buf,
- int buf_size,
- int *bytes_read) {
+int URLRequestFtpJob::ReadRawData(IOBuffer* buf, int buf_size) {
DCHECK_NE(buf_size, 0);
- DCHECK(bytes_read);
DCHECK(!read_in_progress_);
int rv;
+
if (proxy_info_.is_direct()) {
rv = ftp_transaction_->Read(buf, buf_size,
base::Bind(&URLRequestFtpJob::OnReadCompleted,
@@ -365,18 +360,9 @@ bool URLRequestFtpJob::ReadRawData(IOBuffer* buf,
base::Unretained(this)));
}
- if (rv >= 0) {
- *bytes_read = rv;
- return true;
- }
-
- if (rv == ERR_IO_PENDING) {
+ if (rv == ERR_IO_PENDING)
read_in_progress_ = true;
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- } else {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
- }
- return false;
+ return rv;
}
void URLRequestFtpJob::HandleAuthNeededResponse() {
diff --git a/chromium/net/url_request/url_request_ftp_job.h b/chromium/net/url_request/url_request_ftp_job.h
index 74caf726448..227a33b036a 100644
--- a/chromium/net/url_request/url_request_ftp_job.h
+++ b/chromium/net/url_request/url_request_ftp_job.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/auth.h"
#include "net/base/net_export.h"
@@ -71,7 +72,7 @@ class NET_EXPORT_PRIVATE URLRequestFtpJob : public URLRequestJob {
// TODO(ibrar): Yet to give another look at this function.
UploadProgress GetUploadProgress() const override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
void HandleAuthNeededResponse();
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 3ea92263af1..cb31ecf5e1b 100644
--- a/chromium/net/url_request/url_request_ftp_job_unittest.cc
+++ b/chromium/net/url_request/url_request_ftp_job_unittest.cc
@@ -4,11 +4,14 @@
#include "net/url_request/url_request_ftp_job.h"
+#include <utility>
+#include <vector>
+
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "net/base/host_port_pair.h"
+#include "net/base/load_states.h"
#include "net/base/request_priority.h"
#include "net/ftp/ftp_auth_cache.h"
#include "net/http/http_transaction_test_util.h"
@@ -32,15 +35,26 @@ namespace {
class MockProxyResolverFactory : public ProxyResolverFactory {
public:
- MockProxyResolverFactory() : ProxyResolverFactory(false) {}
+ MockProxyResolverFactory()
+ : ProxyResolverFactory(false), resolver_(nullptr) {}
+
int CreateProxyResolver(
const scoped_refptr<ProxyResolverScriptData>& pac_script,
scoped_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback,
scoped_ptr<Request>* request) override {
- resolver->reset(new MockAsyncProxyResolver());
+ EXPECT_FALSE(resolver_);
+ scoped_ptr<MockAsyncProxyResolver> owned_resolver(
+ new MockAsyncProxyResolver());
+ resolver_ = owned_resolver.get();
+ *resolver = std::move(owned_resolver);
return OK;
}
+
+ MockAsyncProxyResolver* resolver() { return resolver_; }
+
+ private:
+ MockAsyncProxyResolver* resolver_;
};
} // namespace
@@ -54,13 +68,13 @@ class FtpTestURLRequestContext : public TestURLRequestContext {
: TestURLRequestContext(true),
ftp_protocol_handler_(new FtpProtocolHandler(ftp_transaction_factory)) {
set_client_socket_factory(socket_factory);
- context_storage_.set_proxy_service(proxy_service.Pass());
+ context_storage_.set_proxy_service(std::move(proxy_service));
set_network_delegate(network_delegate);
scoped_ptr<URLRequestJobFactoryImpl> job_factory =
make_scoped_ptr(new URLRequestJobFactoryImpl);
job_factory->SetProtocolHandler("ftp",
make_scoped_ptr(ftp_protocol_handler_));
- context_storage_.set_job_factory(job_factory.Pass());
+ context_storage_.set_job_factory(std::move(job_factory));
Init();
}
@@ -69,7 +83,7 @@ class FtpTestURLRequestContext : public TestURLRequestContext {
}
void set_proxy_service(scoped_ptr<ProxyService> proxy_service) {
- context_storage_.set_proxy_service(proxy_service.Pass());
+ context_storage_.set_proxy_service(std::move(proxy_service));
}
private:
@@ -116,6 +130,7 @@ class TestURLRequestFtpJob : public URLRequestFtpJob {
FtpTransactionFactory* ftp_factory,
FtpAuthCache* ftp_auth_cache)
: URLRequestFtpJob(request, NULL, ftp_factory, ftp_auth_cache) {}
+ ~TestURLRequestFtpJob() override {}
using URLRequestFtpJob::SetPriority;
using URLRequestFtpJob::Start;
@@ -123,12 +138,13 @@ class TestURLRequestFtpJob : public URLRequestFtpJob {
using URLRequestFtpJob::priority;
protected:
- ~TestURLRequestFtpJob() override {}
};
class MockFtpTransactionFactory : public FtpTransactionFactory {
public:
- FtpTransaction* CreateTransaction() override { return NULL; }
+ scoped_ptr<FtpTransaction> CreateTransaction() override {
+ return scoped_ptr<FtpTransaction>();
+ }
void Suspend(bool suspend) override {}
};
@@ -160,8 +176,8 @@ class URLRequestFtpJobPriorityTest : public testing::Test {
// Make sure that SetPriority actually sets the URLRequestFtpJob's
// priority, both before and after start.
TEST_F(URLRequestFtpJobPriorityTest, SetPriorityBasic) {
- scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
- req_.get(), &ftp_factory_, &ftp_auth_cache_));
+ scoped_ptr<TestURLRequestFtpJob> job(
+ new TestURLRequestFtpJob(req_.get(), &ftp_factory_, &ftp_auth_cache_));
EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
job->SetPriority(LOWEST);
@@ -180,8 +196,8 @@ TEST_F(URLRequestFtpJobPriorityTest, SetPriorityBasic) {
// Make sure that URLRequestFtpJob passes on its priority to its
// transaction on start.
TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriorityOnStart) {
- scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
- req_.get(), &ftp_factory_, &ftp_auth_cache_));
+ scoped_ptr<TestURLRequestFtpJob> job(
+ new TestURLRequestFtpJob(req_.get(), &ftp_factory_, &ftp_auth_cache_));
job->SetPriority(LOW);
EXPECT_FALSE(network_layer_.last_transaction());
@@ -195,8 +211,8 @@ TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriorityOnStart) {
// Make sure that URLRequestFtpJob passes on its priority updates to
// its transaction.
TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriority) {
- scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
- req_.get(), &ftp_factory_, &ftp_auth_cache_));
+ scoped_ptr<TestURLRequestFtpJob> job(
+ new TestURLRequestFtpJob(req_.get(), &ftp_factory_, &ftp_auth_cache_));
job->SetPriority(LOW);
job->Start();
ASSERT_TRUE(network_layer_.last_transaction());
@@ -209,8 +225,8 @@ TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriority) {
// Make sure that URLRequestFtpJob passes on its priority updates to
// newly-created transactions after the first one.
TEST_F(URLRequestFtpJobPriorityTest, SetSubsequentTransactionPriority) {
- scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
- req_.get(), &ftp_factory_, &ftp_auth_cache_));
+ scoped_ptr<TestURLRequestFtpJob> job(
+ new TestURLRequestFtpJob(req_.get(), &ftp_factory_, &ftp_auth_cache_));
job->Start();
job->SetPriority(LOW);
@@ -244,19 +260,19 @@ class URLRequestFtpJobTest : public testing::Test {
void AddSocket(MockRead* reads, size_t reads_size,
MockWrite* writes, size_t writes_size) {
- SequencedSocketData* socket_data =
- new SequencedSocketData(reads, reads_size, writes, writes_size);
+ scoped_ptr<SequencedSocketData> socket_data(make_scoped_ptr(
+ new SequencedSocketData(reads, reads_size, writes, writes_size)));
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
- socket_factory_.AddSocketDataProvider(socket_data);
+ socket_factory_.AddSocketDataProvider(socket_data.get());
- socket_data_.push_back(socket_data);
+ socket_data_.push_back(std::move(socket_data));
}
FtpTestURLRequestContext* request_context() { return &request_context_; }
TestNetworkDelegate* network_delegate() { return &network_delegate_; }
private:
- ScopedVector<SequencedSocketData> socket_data_;
+ std::vector<scoped_ptr<SequencedSocketData>> socket_data_;
MockClientSocketFactory socket_factory_;
TestNetworkDelegate network_delegate_;
MockFtpTransactionFactory ftp_transaction_factory_;
@@ -296,21 +312,65 @@ TEST_F(URLRequestFtpJobTest, FtpProxyRequest) {
EXPECT_EQ("test.html", request_delegate.data_received());
}
-// Regression test for http://crbug.com/237526 .
+// Regression test for http://crbug.com/237526.
TEST_F(URLRequestFtpJobTest, FtpProxyRequestOrphanJob) {
+ scoped_ptr<MockProxyResolverFactory> owned_resolver_factory(
+ new MockProxyResolverFactory());
+ MockProxyResolverFactory* resolver_factory = owned_resolver_factory.get();
+
// Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL.
request_context()->set_proxy_service(make_scoped_ptr(new ProxyService(
make_scoped_ptr(new ProxyConfigServiceFixed(
ProxyConfig::CreateFromCustomPacURL(GURL("http://foo")))),
- make_scoped_ptr(new MockProxyResolverFactory), NULL)));
+ std::move(owned_resolver_factory), nullptr)));
TestDelegate request_delegate;
scoped_ptr<URLRequest> url_request(request_context()->CreateRequest(
GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate));
url_request->Start();
- // Now |url_request| will be deleted before its completion,
- // resulting in it being orphaned. It should not crash.
+ // Verify PAC request is in progress.
+ EXPECT_EQ(net::LoadState::LOAD_STATE_RESOLVING_PROXY_FOR_URL,
+ url_request->GetLoadState().state);
+ EXPECT_EQ(1u, resolver_factory->resolver()->pending_requests().size());
+ EXPECT_EQ(0u, resolver_factory->resolver()->cancelled_requests().size());
+
+ // Destroying the request should cancel the PAC request.
+ url_request.reset();
+ EXPECT_EQ(0u, resolver_factory->resolver()->pending_requests().size());
+ EXPECT_EQ(1u, resolver_factory->resolver()->cancelled_requests().size());
+}
+
+// Make sure PAC requests are cancelled on request cancellation. Requests can
+// hang around a bit without being deleted in the cancellation case, so the
+// above test is not sufficient.
+TEST_F(URLRequestFtpJobTest, FtpProxyRequestCancelRequest) {
+ scoped_ptr<MockProxyResolverFactory> owned_resolver_factory(
+ new MockProxyResolverFactory());
+ MockProxyResolverFactory* resolver_factory = owned_resolver_factory.get();
+
+ // Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL.
+ request_context()->set_proxy_service(make_scoped_ptr(new ProxyService(
+ make_scoped_ptr(new ProxyConfigServiceFixed(
+ ProxyConfig::CreateFromCustomPacURL(GURL("http://foo")))),
+ std::move(owned_resolver_factory), nullptr)));
+
+ TestDelegate request_delegate;
+ scoped_ptr<URLRequest> url_request(request_context()->CreateRequest(
+ GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate));
+
+ // Verify PAC request is in progress.
+ url_request->Start();
+ EXPECT_EQ(net::LoadState::LOAD_STATE_RESOLVING_PROXY_FOR_URL,
+ url_request->GetLoadState().state);
+ EXPECT_EQ(1u, resolver_factory->resolver()->pending_requests().size());
+ EXPECT_EQ(0u, resolver_factory->resolver()->cancelled_requests().size());
+
+ // Cancelling the request should cancel the PAC request.
+ url_request->Cancel();
+ EXPECT_EQ(net::LoadState::LOAD_STATE_IDLE, url_request->GetLoadState().state);
+ EXPECT_EQ(0u, resolver_factory->resolver()->pending_requests().size());
+ EXPECT_EQ(1u, resolver_factory->resolver()->cancelled_requests().size());
}
TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAuthNoCredentials) {
diff --git a/chromium/net/url_request/url_request_http_job.cc b/chromium/net/url_request/url_request_http_job.cc
index c317469cb13..c2a70dd3f67 100644
--- a/chromium/net/url_request/url_request_http_job.cc
+++ b/chromium/net/url_request/url_request_http_job.cc
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/file_version_info.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/profiler/scoped_tracker.h"
@@ -51,9 +52,20 @@
#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 "url/origin.h"
static const char kAvailDictionaryHeader[] = "Avail-Dictionary";
+namespace {
+
+// True if the request method is "safe" (per section 4.2.1 of RFC 7231).
+bool IsMethodSafe(const std::string& method) {
+ return method == "GET" || method == "HEAD" || method == "OPTIONS" ||
+ method == "TRACE";
+}
+
+} // namespace
+
namespace net {
class URLRequestHttpJob::HttpFilterContext : public FilterContext {
@@ -67,7 +79,7 @@ class URLRequestHttpJob::HttpFilterContext : public FilterContext {
base::Time GetRequestTime() const override;
bool IsCachedContent() const override;
SdchManager::DictionarySet* SdchDictionariesAdvertised() const override;
- int64 GetByteReadCount() const override;
+ int64_t GetByteReadCount() const override;
int GetResponseCode() const override;
const URLRequestContext* GetURLRequestContext() const override;
void RecordPacketStats(StatisticSelector statistic) const override;
@@ -116,7 +128,7 @@ URLRequestHttpJob::HttpFilterContext::SdchDictionariesAdvertised() const {
return job_->dictionaries_advertised_.get();
}
-int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const {
+int64_t URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const {
return job_->prefilter_bytes_read();
}
@@ -277,11 +289,9 @@ void URLRequestHttpJob::Start() {
}
void URLRequestHttpJob::Kill() {
- if (!transaction_.get())
- return;
-
weak_factory_.InvalidateWeakPtrs();
- DestroyTransaction();
+ if (transaction_)
+ DestroyTransaction();
URLRequestJob::Kill();
}
@@ -415,11 +425,6 @@ void URLRequestHttpJob::NotifyHeadersComplete() {
URLRequestJob::NotifyHeadersComplete();
}
-void URLRequestHttpJob::NotifyDone(const URLRequestStatus& status) {
- DoneWithRequest(FINISHED);
- URLRequestJob::NotifyDone(status);
-}
-
void URLRequestHttpJob::DestroyTransaction() {
DCHECK(transaction_.get());
@@ -481,11 +486,25 @@ void URLRequestHttpJob::MaybeStartTransactionInternal(int result) {
}
void URLRequestHttpJob::StartTransactionInternal() {
+ // This should only be called while the request's status is IO_PENDING.
+ DCHECK_EQ(URLRequestStatus::IO_PENDING, request_->status().status());
+
// NOTE: This method assumes that request_info_ is already setup properly.
// If we already have a transaction, then we should restart the transaction
// with auth provided by auth_credentials_.
+ bool invalid_header_values_in_rfc7230 = false;
+ for (HttpRequestHeaders::Iterator it(request_info_.extra_headers);
+ it.GetNext();) {
+ if (!HttpUtil::IsValidHeaderValueRFC7230(it.value())) {
+ invalid_header_values_in_rfc7230 = true;
+ break;
+ }
+ }
+ UMA_HISTOGRAM_BOOLEAN("Net.HttpRequest.ContainsInvalidHeaderValuesInRFC7230",
+ invalid_header_values_in_rfc7230);
+
int rv;
if (network_delegate()) {
@@ -594,30 +613,37 @@ void URLRequestHttpJob::AddExtraHeaders() {
}
}
+ // Advertise "br" encoding only if transferred data is opaque to proxy.
+ bool advertise_brotli = false;
+ const HttpNetworkSession::Params* network_session_params =
+ request()->context()->GetNetworkSessionParams();
+ if (network_session_params && network_session_params->enable_brotli)
+ advertise_brotli = request()->url().SchemeIsCryptographic();
+
// Supply Accept-Encoding headers first so that it is more likely that they
// will be in the first transmitted packet. This can sometimes make it
// easier to filter and analyze the streams to assure that a proxy has not
// damaged these headers. Some proxies deliberately corrupt Accept-Encoding
// headers.
- if (!advertise_sdch) {
- // Tell the server what compression formats we support (other than SDCH).
+ std::string advertised_encodings = "gzip, deflate";
+ if (advertise_sdch)
+ advertised_encodings += ", sdch";
+ if (advertise_brotli)
+ advertised_encodings += ", br";
+ // Tell the server what compression formats are supported.
+ request_info_.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
+ advertised_encodings);
+
+ if (dictionaries_advertised_) {
request_info_.extra_headers.SetHeader(
- HttpRequestHeaders::kAcceptEncoding, "gzip, deflate");
- } else {
- // Include SDCH in acceptable list.
- request_info_.extra_headers.SetHeader(
- HttpRequestHeaders::kAcceptEncoding, "gzip, deflate, sdch");
- if (dictionaries_advertised_) {
- request_info_.extra_headers.SetHeader(
- kAvailDictionaryHeader,
- dictionaries_advertised_->GetDictionaryClientHashList());
- // Since we're tagging this transaction as advertising a dictionary,
- // we'll definitely employ an SDCH filter (or tentative sdch filter)
- // when we get a response. When done, we'll record histograms via
- // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet
- // arrival times.
- packet_timing_enabled_ = true;
- }
+ kAvailDictionaryHeader,
+ dictionaries_advertised_->GetDictionaryClientHashList());
+ // Since we're tagging this transaction as advertising a dictionary,
+ // we'll definitely employ an SDCH filter (or tentative sdch filter)
+ // when we get a response. When done, we'll record histograms via
+ // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet
+ // arrival times.
+ packet_timing_enabled_ = true;
}
}
@@ -658,13 +684,20 @@ void URLRequestHttpJob::DoLoadCookies() {
CookieOptions options;
options.set_include_httponly();
- // TODO(mkwst): Drop this `if` once we decide whether or not to ship
- // first-party cookies: https://crbug.com/459154
- if (network_delegate() &&
- network_delegate()->FirstPartyOnlyCookieExperimentEnabled())
- options.set_first_party_url(request_->first_party_for_cookies());
- else
- options.set_include_first_party_only();
+ // TODO(mkwst): If first-party-only cookies aren't enabled, pretend the
+ // request is first-party regardless, in order to include all cookies. Drop
+ // this check once we decide whether or not we're shipping this feature:
+ // https://crbug.com/459154
+ url::Origin requested_origin(request_->url());
+ if (!network_delegate() ||
+ !network_delegate()->AreExperimentalCookieFeaturesEnabled()) {
+ options.set_include_first_party_only_cookies();
+ } else if (requested_origin.IsSameOriginWith(
+ url::Origin(request_->first_party_for_cookies())) &&
+ (IsMethodSafe(request_->method()) ||
+ requested_origin.IsSameOriginWith(request_->initiator()))) {
+ options.set_include_first_party_only_cookies();
+ }
request_->context()->cookie_store()->GetCookiesWithOptionsAsync(
request_->url(), options, base::Bind(&URLRequestHttpJob::OnCookiesLoaded,
@@ -750,6 +783,11 @@ void URLRequestHttpJob::SaveNextCookie() {
options.set_include_httponly();
options.set_server_time(response_date_);
+ if (network_delegate() &&
+ network_delegate()->AreStrictSecureCookiesEnabled()) {
+ options.set_enforce_strict_secure();
+ }
+
CookieStore::SetCookiesCallback callback(base::Bind(
&URLRequestHttpJob::OnCookieSaved, weak_factory_.GetWeakPtr(),
save_next_cookie_running, callback_pending));
@@ -925,6 +963,23 @@ void URLRequestHttpJob::OnStartCompleted(int result) {
SetProxyServer(transaction_->GetResponseInfo()->proxy_server);
}
scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
+
+ if (headers) {
+ void* iter = NULL;
+ std::string name;
+ std::string value;
+ bool invalid_header_values_in_rfc7230 = false;
+ while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+ if (!HttpUtil::IsValidHeaderValueRFC7230(value)) {
+ invalid_header_values_in_rfc7230 = true;
+ break;
+ }
+ }
+ UMA_HISTOGRAM_BOOLEAN(
+ "Net.HttpResponse.ContainsInvalidHeaderValuesInRFC7230",
+ invalid_header_values_in_rfc7230);
+ }
+
if (network_delegate()) {
// Note that |this| may not be deleted until
// |on_headers_received_callback_| or
@@ -994,19 +1049,16 @@ void URLRequestHttpJob::OnHeadersReceivedCallback(int result) {
void URLRequestHttpJob::OnReadCompleted(int result) {
read_in_progress_ = false;
+ DCHECK_NE(ERR_IO_PENDING, result);
+
if (ShouldFixMismatchedContentLength(result))
result = OK;
- if (result == OK) {
- NotifyDone(URLRequestStatus());
- } else if (result < 0) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
- } else {
- // Clear the IO_PENDING status
- SetStatus(URLRequestStatus());
- }
+ // EOF or error, done with this job.
+ if (result <= 0)
+ DoneWithRequest(FINISHED);
- NotifyReadComplete(result);
+ ReadRawDataComplete(result);
}
void URLRequestHttpJob::RestartTransactionWithAuth(
@@ -1122,6 +1174,13 @@ int URLRequestHttpJob::GetResponseCode() const {
return GetResponseHeaders()->response_code();
}
+void URLRequestHttpJob::PopulateNetErrorDetails(
+ NetErrorDetails* details) const {
+ if (!transaction_)
+ return;
+ return transaction_->PopulateNetErrorDetails(details);
+}
+
Filter* URLRequestHttpJob::SetupFilter() const {
DCHECK(transaction_.get());
if (!response_info_)
@@ -1254,7 +1313,8 @@ void URLRequestHttpJob::CancelAuth() {
}
void URLRequestHttpJob::ContinueWithCertificate(
- X509Certificate* client_cert) {
+ X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key) {
DCHECK(transaction_.get());
DCHECK(!response_info_) << "should not have a response yet";
@@ -1266,7 +1326,8 @@ void URLRequestHttpJob::ContinueWithCertificate(
// be notifying our consumer asynchronously via OnStartCompleted.
SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- int rv = transaction_->RestartWithCertificate(client_cert, start_callback_);
+ int rv = transaction_->RestartWithCertificate(client_cert, client_private_key,
+ start_callback_);
if (rv == ERR_IO_PENDING)
return;
@@ -1315,7 +1376,8 @@ bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const {
if (rv == ERR_CONTENT_LENGTH_MISMATCH ||
rv == ERR_INCOMPLETE_CHUNKED_ENCODING) {
if (request_ && request_->response_headers()) {
- int64 expected_length = request_->response_headers()->GetContentLength();
+ int64_t expected_length =
+ request_->response_headers()->GetContentLength();
VLOG(1) << __FUNCTION__ << "() "
<< "\"" << request_->url().spec() << "\""
<< " content-length = " << expected_length
@@ -1330,10 +1392,8 @@ bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const {
return false;
}
-bool URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size,
- int* bytes_read) {
+int URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size) {
DCHECK_NE(buf_size, 0);
- DCHECK(bytes_read);
DCHECK(!read_in_progress_);
int rv = transaction_->Read(
@@ -1341,23 +1401,15 @@ bool URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size,
base::Bind(&URLRequestHttpJob::OnReadCompleted, base::Unretained(this)));
if (ShouldFixMismatchedContentLength(rv))
- rv = 0;
+ rv = OK;
- if (rv >= 0) {
- *bytes_read = rv;
- if (!rv)
- DoneWithRequest(FINISHED);
- return true;
- }
+ if (rv == 0 || (rv < 0 && rv != ERR_IO_PENDING))
+ DoneWithRequest(FINISHED);
- if (rv == ERR_IO_PENDING) {
+ if (rv == ERR_IO_PENDING)
read_in_progress_ = true;
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- } else {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
- }
- return false;
+ return rv;
}
void URLRequestHttpJob::StopCaching() {
@@ -1373,7 +1425,7 @@ bool URLRequestHttpJob::GetFullRequestHeaders(
return transaction_->GetFullRequestHeaders(headers);
}
-int64 URLRequestHttpJob::GetTotalReceivedBytes() const {
+int64_t URLRequestHttpJob::GetTotalReceivedBytes() const {
int64_t total_received_bytes =
total_received_bytes_from_previous_transactions_;
if (transaction_)
diff --git a/chromium/net/url_request/url_request_http_job.h b/chromium/net/url_request/url_request_http_job.h
index 4ee4440607f..79b4aa9dfc0 100644
--- a/chromium/net/url_request/url_request_http_job.h
+++ b/chromium/net/url_request/url_request_http_job.h
@@ -5,17 +5,20 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_
+#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "net/base/auth.h"
#include "net/base/completion_callback.h"
+#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
#include "net/base/sdch_manager.h"
#include "net/cookies/cookie_store.h"
@@ -34,6 +37,7 @@ class HttpResponseInfo;
class HttpTransaction;
class HttpUserAgentSettings;
class ProxyInfo;
+class SSLPrivateKey;
class UploadDataStream;
class URLRequestContext;
@@ -78,9 +82,6 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
// Shadows URLRequestJob's version of this method so we can grab cookies.
void NotifyHeadersComplete();
- // Shadows URLRequestJob's method so we can record histograms.
- void NotifyDone(const URLRequestStatus& status);
-
void DestroyTransaction();
void AddExtraHeaders();
@@ -121,6 +122,7 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
bool GetResponseCookies(std::vector<std::string>* cookies) override;
int GetResponseCode() const override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) const override;
Filter* SetupFilter() const override;
bool CopyFragmentOnRedirect(const GURL& location) const override;
bool IsSafeRedirect(const GURL& location) override;
@@ -128,13 +130,14 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
void GetAuthChallengeInfo(scoped_refptr<AuthChallengeInfo>*) override;
void SetAuth(const AuthCredentials& credentials) override;
void CancelAuth() override;
- void ContinueWithCertificate(X509Certificate* client_cert) override;
+ void ContinueWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key) override;
void ContinueDespiteLastError() override;
void ResumeNetworkStart() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
void StopCaching() override;
bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override;
- int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalReceivedBytes() const override;
int64_t GetTotalSentBytes() const override;
void DoneReading() override;
void DoneReadingRedirectResponse() override;
@@ -237,7 +240,7 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
// The number of bytes that have been accounted for in packets (where some of
// those packets may possibly have had their time of arrival recorded).
- int64 bytes_observed_in_packets_;
+ int64_t bytes_observed_in_packets_;
// The request time may not be available when we are being destroyed, so we
// snapshot it early on.
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 dca3e8e979e..713ae608e40 100644
--- a/chromium/net/url_request/url_request_http_job_unittest.cc
+++ b/chromium/net/url_request/url_request_http_job_unittest.cc
@@ -42,14 +42,12 @@ class TestURLRequestHttpJob : public URLRequestHttpJob {
explicit TestURLRequestHttpJob(URLRequest* request)
: URLRequestHttpJob(request, request->context()->network_delegate(),
request->context()->http_user_agent_settings()) {}
+ ~TestURLRequestHttpJob() override {}
using URLRequestHttpJob::SetPriority;
using URLRequestHttpJob::Start;
using URLRequestHttpJob::Kill;
using URLRequestHttpJob::priority;
-
- protected:
- ~TestURLRequestHttpJob() override {}
};
class URLRequestHttpJobTest : public ::testing::Test {
@@ -89,7 +87,7 @@ class URLRequestHttpJobTest : public ::testing::Test {
}
void EnableSdch() {
- context_.SetSdchManager(scoped_ptr<SdchManager>(new SdchManager).Pass());
+ context_.SetSdchManager(scoped_ptr<SdchManager>(new SdchManager));
}
MockNetworkLayer network_layer_;
@@ -134,10 +132,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest,
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
request->Start();
ASSERT_TRUE(request->is_pending());
@@ -165,10 +161,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest,
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
request->Start();
ASSERT_TRUE(request->is_pending());
@@ -198,10 +192,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, TestContentLengthFailedRequest) {
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
request->Start();
ASSERT_TRUE(request->is_pending());
@@ -232,10 +224,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest,
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
delegate.set_cancel_in_received_data(true);
request->Start();
@@ -282,10 +272,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest,
socket_factory_.AddSocketDataProvider(&final_socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.redirect.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.redirect.com"), DEFAULT_PRIORITY, &delegate);
request->Start();
ASSERT_TRUE(request->is_pending());
@@ -316,10 +304,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest,
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
delegate.set_cancel_in_response_started(true);
request->Start();
@@ -343,10 +329,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest,
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
request->Start();
request->Cancel();
@@ -378,9 +362,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeader) {
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate1;
- scoped_ptr<URLRequest> request1 =
- context_->CreateRequest(GURL("https://www.example.com"), DEFAULT_PRIORITY,
- &delegate1).Pass();
+ scoped_ptr<URLRequest> request1 = context_->CreateRequest(
+ GURL("https://www.example.com"), DEFAULT_PRIORITY, &delegate1);
request1->Start();
ASSERT_TRUE(request1->is_pending());
@@ -393,9 +376,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeader) {
// Issue another request, and backoff logic should apply.
TestDelegate delegate2;
- scoped_ptr<URLRequest> request2 =
- context_->CreateRequest(GURL("https://www.example.com"), DEFAULT_PRIORITY,
- &delegate2).Pass();
+ scoped_ptr<URLRequest> request2 = context_->CreateRequest(
+ GURL("https://www.example.com"), DEFAULT_PRIORITY, &delegate2);
request2->Start();
ASSERT_TRUE(request2->is_pending());
@@ -414,11 +396,23 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderUserGesture) {
"Connection: keep-alive\r\n"
"User-Agent:\r\n"
"Accept-Encoding: gzip, deflate\r\n"
- "Accept-Language: en-us,fr\r\n\r\n")};
- MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n"
- "Backoff: 3600\r\n"
- "Content-Length: 9\r\n\r\n"),
- MockRead("test.html")};
+ "Accept-Language: en-us,fr\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
+ "Connection: keep-alive\r\n"
+ "User-Agent:\r\n"
+ "Accept-Encoding: gzip, deflate\r\n"
+ "Accept-Language: en-us,fr\r\n\r\n"),
+ };
+ MockRead reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Backoff: 3600\r\n"
+ "Content-Length: 9\r\n\r\n"),
+ MockRead("test.html"), MockRead("HTTP/1.1 200 OK\r\n"
+ "Backoff: 3600\r\n"
+ "Content-Length: 9\r\n\r\n"),
+ MockRead("test.html"),
+ };
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
ssl_socket_data_provider.SetNextProto(kProtoHTTP11);
@@ -431,10 +425,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderUserGesture) {
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate1;
- scoped_ptr<URLRequest> request1 =
- context_->CreateRequest(GURL("https://www.example.com"), DEFAULT_PRIORITY,
- &delegate1)
- .Pass();
+ scoped_ptr<URLRequest> request1 = context_->CreateRequest(
+ GURL("https://www.example.com"), DEFAULT_PRIORITY, &delegate1);
request1->Start();
ASSERT_TRUE(request1->is_pending());
@@ -445,15 +437,10 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderUserGesture) {
EXPECT_EQ(1, delegate1.received_before_network_start_count());
EXPECT_EQ(1, manager_.GetNumberOfEntriesForTests());
- // Reset socket data provider to replay socket data.
- socket_data.Reset();
-
// Issue a user-initiated request, backoff logic should not apply.
TestDelegate delegate2;
- scoped_ptr<URLRequest> request2 =
- context_->CreateRequest(GURL("https://www.example.com"), DEFAULT_PRIORITY,
- &delegate2)
- .Pass();
+ scoped_ptr<URLRequest> request2 = context_->CreateRequest(
+ GURL("https://www.example.com"), DEFAULT_PRIORITY, &delegate2);
request2->SetLoadFlags(request2->load_flags() | LOAD_MAYBE_USER_GESTURE);
request2->Start();
@@ -480,9 +467,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderNotSecure) {
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_->CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate).Pass();
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
request->Start();
ASSERT_TRUE(request->is_pending());
@@ -515,9 +501,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderCachedResponse) {
socket_factory_.AddSocketDataProvider(&socket_data);
TestDelegate delegate1;
- scoped_ptr<URLRequest> request1 =
- context_->CreateRequest(GURL("https://www.example.com"), DEFAULT_PRIORITY,
- &delegate1).Pass();
+ scoped_ptr<URLRequest> request1 = context_->CreateRequest(
+ GURL("https://www.example.com"), DEFAULT_PRIORITY, &delegate1);
request1->Start();
ASSERT_TRUE(request1->is_pending());
@@ -531,9 +516,8 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderCachedResponse) {
// Backoff logic does not apply to a second request, since it is fetched
// from cache.
TestDelegate delegate2;
- scoped_ptr<URLRequest> request2 =
- context_->CreateRequest(GURL("https://www.example.com"), DEFAULT_PRIORITY,
- &delegate2).Pass();
+ scoped_ptr<URLRequest> request2 = context_->CreateRequest(
+ GURL("https://www.example.com"), DEFAULT_PRIORITY, &delegate2);
request2->Start();
ASSERT_TRUE(request2->is_pending());
@@ -547,10 +531,8 @@ TEST_F(URLRequestHttpJobTest, TestCancelWhileReadingCookies) {
context_.set_cookie_store(new DelayedCookieMonster());
TestDelegate delegate;
- scoped_ptr<URLRequest> request =
- context_.CreateRequest(GURL("http://www.example.com"), DEFAULT_PRIORITY,
- &delegate)
- .Pass();
+ scoped_ptr<URLRequest> request = context_.CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
request->Start();
request->Cancel();
@@ -563,8 +545,7 @@ TEST_F(URLRequestHttpJobTest, TestCancelWhileReadingCookies) {
// Make sure that SetPriority actually sets the URLRequestHttpJob's
// priority, both before and after start.
TEST_F(URLRequestHttpJobTest, SetPriorityBasic) {
- scoped_refptr<TestURLRequestHttpJob> job(
- new TestURLRequestHttpJob(req_.get()));
+ scoped_ptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(req_.get()));
EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
job->SetPriority(LOWEST);
@@ -583,8 +564,7 @@ TEST_F(URLRequestHttpJobTest, SetPriorityBasic) {
// Make sure that URLRequestHttpJob passes on its priority to its
// transaction on start.
TEST_F(URLRequestHttpJobTest, SetTransactionPriorityOnStart) {
- scoped_refptr<TestURLRequestHttpJob> job(
- new TestURLRequestHttpJob(req_.get()));
+ scoped_ptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(req_.get()));
job->SetPriority(LOW);
EXPECT_FALSE(network_layer_.last_transaction());
@@ -598,8 +578,7 @@ TEST_F(URLRequestHttpJobTest, SetTransactionPriorityOnStart) {
// Make sure that URLRequestHttpJob passes on its priority updates to
// its transaction.
TEST_F(URLRequestHttpJobTest, SetTransactionPriority) {
- scoped_refptr<TestURLRequestHttpJob> job(
- new TestURLRequestHttpJob(req_.get()));
+ scoped_ptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(req_.get()));
job->SetPriority(LOW);
job->Start();
ASSERT_TRUE(network_layer_.last_transaction());
@@ -613,8 +592,7 @@ TEST_F(URLRequestHttpJobTest, SetTransactionPriority) {
TEST_F(URLRequestHttpJobTest, SdchAdvertisementGet) {
EnableSdch();
req_->set_method("GET"); // Redundant with default.
- scoped_refptr<TestURLRequestHttpJob> job(
- new TestURLRequestHttpJob(req_.get()));
+ scoped_ptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(req_.get()));
job->Start();
EXPECT_TRUE(TransactionAcceptsSdchEncoding());
}
@@ -623,12 +601,85 @@ TEST_F(URLRequestHttpJobTest, SdchAdvertisementGet) {
TEST_F(URLRequestHttpJobTest, SdchAdvertisementPost) {
EnableSdch();
req_->set_method("POST");
- scoped_refptr<TestURLRequestHttpJob> job(
- new TestURLRequestHttpJob(req_.get()));
+ scoped_ptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(req_.get()));
job->Start();
EXPECT_FALSE(TransactionAcceptsSdchEncoding());
}
+class URLRequestHttpJobWithBrotliSupportTest : public ::testing::Test {
+ protected:
+ URLRequestHttpJobWithBrotliSupportTest()
+ : context_(new TestURLRequestContext(true)) {
+ scoped_ptr<HttpNetworkSession::Params> params(
+ new HttpNetworkSession::Params);
+ params->enable_brotli = true;
+ context_->set_http_network_session_params(std::move(params));
+ context_->set_client_socket_factory(&socket_factory_);
+ context_->Init();
+ }
+
+ MockClientSocketFactory socket_factory_;
+ scoped_ptr<TestURLRequestContext> context_;
+};
+
+TEST_F(URLRequestHttpJobWithBrotliSupportTest, NoBrotliAdvertisementOverHttp) {
+ MockWrite writes[] = {MockWrite(kSimpleGetMockWrite)};
+ MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n"
+ "Content-Length: 12\r\n\r\n"),
+ MockRead("Test Content")};
+ StaticSocketDataProvider socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ TestDelegate delegate;
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("http://www.example.com"), DEFAULT_PRIORITY, &delegate);
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(request->status().is_success());
+ EXPECT_EQ(12, request->received_response_content_length());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ request->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ request->GetTotalReceivedBytes());
+}
+
+TEST_F(URLRequestHttpJobWithBrotliSupportTest, BrotliAdvertisement) {
+ net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.SetNextProto(kProtoHTTP11);
+ ssl_socket_data_provider.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
+ socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
+
+ MockWrite writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
+ "Connection: keep-alive\r\n"
+ "User-Agent:\r\n"
+ "Accept-Encoding: gzip, deflate, br\r\n"
+ "Accept-Language: en-us,fr\r\n\r\n")};
+ MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n"
+ "Content-Length: 12\r\n\r\n"),
+ MockRead("Test Content")};
+ StaticSocketDataProvider socket_data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ TestDelegate delegate;
+ scoped_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("https://www.example.com"), DEFAULT_PRIORITY, &delegate);
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(request->status().is_success());
+ EXPECT_EQ(12, request->received_response_content_length());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ request->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
+ request->GetTotalReceivedBytes());
+}
+
// This base class just serves to set up some things before the TestURLRequest
// constructor is called.
class URLRequestHttpJobWebSocketTestBase : public ::testing::Test {
@@ -747,6 +798,8 @@ class FakeWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
void Drain(HttpNetworkSession* session) override {}
+ void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
+
void SetPriority(RequestPriority priority) override {}
UploadProgress GetUploadProgress() const override {
@@ -765,8 +818,7 @@ class FakeWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
};
TEST_F(URLRequestHttpJobWebSocketTest, RejectedWithoutCreateHelper) {
- scoped_refptr<TestURLRequestHttpJob> job(
- new TestURLRequestHttpJob(req_.get()));
+ scoped_ptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(req_.get()));
job->Start();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(URLRequestStatus::FAILED, req_->status().status());
@@ -774,8 +826,7 @@ TEST_F(URLRequestHttpJobWebSocketTest, RejectedWithoutCreateHelper) {
}
TEST_F(URLRequestHttpJobWebSocketTest, CreateHelperPassedThrough) {
- scoped_refptr<TestURLRequestHttpJob> job(
- new TestURLRequestHttpJob(req_.get()));
+ scoped_ptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(req_.get()));
scoped_ptr<MockCreateHelper> create_helper(
new ::testing::StrictMock<MockCreateHelper>());
FakeWebSocketHandshakeStream* fake_handshake_stream(
diff --git a/chromium/net/url_request/url_request_intercepting_job_factory.cc b/chromium/net/url_request/url_request_intercepting_job_factory.cc
index ea2d1f29d09..3ced003168a 100644
--- a/chromium/net/url_request/url_request_intercepting_job_factory.cc
+++ b/chromium/net/url_request/url_request_intercepting_job_factory.cc
@@ -4,6 +4,8 @@
#include "net/url_request/url_request_intercepting_job_factory.h"
+#include <utility>
+
#include "base/logging.h"
#include "net/url_request/url_request_interceptor.h"
@@ -12,9 +14,8 @@ namespace net {
URLRequestInterceptingJobFactory::URLRequestInterceptingJobFactory(
scoped_ptr<URLRequestJobFactory> job_factory,
scoped_ptr<URLRequestInterceptor> interceptor)
- : job_factory_(job_factory.Pass()),
- interceptor_(interceptor.Pass()) {
-}
+ : job_factory_(std::move(job_factory)),
+ interceptor_(std::move(interceptor)) {}
URLRequestInterceptingJobFactory::~URLRequestInterceptingJobFactory() {}
diff --git a/chromium/net/url_request/url_request_intercepting_job_factory.h b/chromium/net/url_request/url_request_intercepting_job_factory.h
index 056b3859cf5..7dcb353c0b5 100644
--- a/chromium/net/url_request/url_request_intercepting_job_factory.h
+++ b/chromium/net/url_request/url_request_intercepting_job_factory.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/url_request/url_request_job_factory.h"
diff --git a/chromium/net/url_request/url_request_job.cc b/chromium/net/url_request/url_request_job.cc
index f23a3bbda4e..55a4f51e26e 100644
--- a/chromium/net/url_request/url_request_job.cc
+++ b/chromium/net/url_request/url_request_job.cc
@@ -4,6 +4,8 @@
#include "net/url_request/url_request_job.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
@@ -37,7 +39,7 @@ scoped_ptr<base::Value> FiltersSetCallback(
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
event_params->SetString("filters", filter->OrderedFilterList());
- return event_params.Pass();
+ return std::move(event_params);
}
std::string ComputeMethodForRedirect(const std::string& method,
@@ -80,6 +82,12 @@ URLRequestJob::URLRequestJob(URLRequest* request,
power_monitor->AddObserver(this);
}
+URLRequestJob::~URLRequestJob() {
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->RemoveObserver(this);
+}
+
void URLRequestJob::SetUpload(UploadDataStream* upload) {
}
@@ -91,55 +99,55 @@ void URLRequestJob::SetPriority(RequestPriority priority) {
void URLRequestJob::Kill() {
weak_factory_.InvalidateWeakPtrs();
- // Make sure the request is notified that we are done. We assume that the
- // request took care of setting its error status before calling Kill.
- if (request_)
- NotifyCanceled();
-}
-
-void URLRequestJob::DetachRequest() {
- request_ = NULL;
-}
-
-// This function calls ReadData to get stream data. If a filter exists, passes
-// the data to the attached filter. Then returns the output from filter back to
-// the caller.
+ // Make sure the URLRequest is notified that the job is done. This assumes
+ // that the URLRequest took care of setting its error status before calling
+ // Kill().
+ // TODO(mmenke): The URLRequest is currently deleted before this method
+ // invokes its async callback whenever this is called by the URLRequest.
+ // Try to simplify how cancellation works.
+ NotifyCanceled();
+}
+
+// This function calls ReadRawData to get stream data. If a filter exists, it
+// passes the data to the attached filter. It then returns the output from
+// filter back to the caller.
bool URLRequestJob::Read(IOBuffer* buf, int buf_size, int *bytes_read) {
- bool rv = false;
-
DCHECK_LT(buf_size, 1000000); // Sanity check.
DCHECK(buf);
DCHECK(bytes_read);
DCHECK(filtered_read_buffer_.get() == NULL);
DCHECK_EQ(0, filtered_read_buffer_len_);
+ Error error = OK;
*bytes_read = 0;
// Skip Filter if not present.
- if (!filter_.get()) {
- rv = ReadRawDataHelper(buf, buf_size, bytes_read);
+ if (!filter_) {
+ error = ReadRawDataHelper(buf, buf_size, bytes_read);
} else {
// Save the caller's buffers while we do IO
// in the filter's buffers.
filtered_read_buffer_ = buf;
filtered_read_buffer_len_ = buf_size;
- if (ReadFilteredData(bytes_read)) {
- rv = true; // We have data to return.
+ error = ReadFilteredData(bytes_read);
- // It is fine to call DoneReading even if ReadFilteredData receives 0
- // bytes from the net, but we avoid making that call if we know for
- // sure that's the case (ReadRawDataHelper path).
- if (*bytes_read == 0)
- DoneReading();
- } else {
- rv = false; // Error, or a new IO is pending.
- }
+ // Synchronous EOF from the filter.
+ if (error == OK && *bytes_read == 0)
+ DoneReading();
}
- if (rv && *bytes_read == 0)
- NotifyDone(URLRequestStatus());
- return rv;
+ if (error == OK) {
+ // If URLRequestJob read zero bytes, the job is at EOF.
+ if (*bytes_read == 0)
+ NotifyDone(URLRequestStatus());
+ } else if (error == ERR_IO_PENDING) {
+ SetStatus(URLRequestStatus::FromError(ERR_IO_PENDING));
+ } else {
+ NotifyDone(URLRequestStatus::FromError(error));
+ *bytes_read = -1;
+ }
+ return error == OK;
}
void URLRequestJob::StopCaching() {
@@ -186,6 +194,10 @@ bool URLRequestJob::GetResponseCookies(std::vector<std::string>* cookies) {
return false;
}
+void URLRequestJob::PopulateNetErrorDetails(NetErrorDetails* details) const {
+ return;
+}
+
Filter* URLRequestJob::SetupFilter() const {
return NULL;
}
@@ -237,8 +249,8 @@ void URLRequestJob::CancelAuth() {
NOTREACHED();
}
-void URLRequestJob::ContinueWithCertificate(
- X509Certificate* client_cert) {
+void URLRequestJob::ContinueWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key) {
// The derived class should implement this!
NOTREACHED();
}
@@ -257,8 +269,8 @@ void URLRequestJob::FollowDeferredRedirect() {
// will fail inside FollowRedirect. The DCHECK above asserts that we called
// OnReceivedRedirect.
- // It is also possible that FollowRedirect will drop the last reference to
- // this job, so we need to reset our members before calling it.
+ // It is also possible that FollowRedirect will delete |this|, so not safe to
+ // pass along reference to |deferred_redirect_info_|.
RedirectInfo redirect_info = deferred_redirect_info_;
deferred_redirect_info_ = RedirectInfo();
@@ -341,67 +353,42 @@ GURL URLRequestJob::ComputeReferrerForRedirect(
return GURL();
}
-URLRequestJob::~URLRequestJob() {
- base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
- if (power_monitor)
- power_monitor->RemoveObserver(this);
-}
-
void URLRequestJob::NotifyCertificateRequested(
SSLCertRequestInfo* cert_request_info) {
- if (!request_)
- return; // The request was destroyed, so there is no more work to do.
-
request_->NotifyCertificateRequested(cert_request_info);
}
void URLRequestJob::NotifySSLCertificateError(const SSLInfo& ssl_info,
bool fatal) {
- if (!request_)
- return; // The request was destroyed, so there is no more work to do.
-
request_->NotifySSLCertificateError(ssl_info, fatal);
}
bool URLRequestJob::CanGetCookies(const CookieList& cookie_list) const {
- if (!request_)
- return false; // The request was destroyed, so there is no more work to do.
-
return request_->CanGetCookies(cookie_list);
}
bool URLRequestJob::CanSetCookie(const std::string& cookie_line,
CookieOptions* options) const {
- if (!request_)
- return false; // The request was destroyed, so there is no more work to do.
-
return request_->CanSetCookie(cookie_line, options);
}
bool URLRequestJob::CanEnablePrivacyMode() const {
- if (!request_)
- return false; // The request was destroyed, so there is no more work to do.
-
return request_->CanEnablePrivacyMode();
}
void URLRequestJob::NotifyBeforeNetworkStart(bool* defer) {
- if (!request_)
- return;
-
request_->NotifyBeforeNetworkStart(defer);
}
void URLRequestJob::NotifyHeadersComplete() {
- if (!request_ || !request_->has_delegate())
- return; // The request was destroyed, so there is no more work to do.
-
if (has_handled_response_)
return;
// This should not be called on error, and the job type should have cleared
// IO_PENDING state before calling this method.
- DCHECK(request_->status().is_success());
+ // TODO(mmenke): Change this to a DCHECK once https://crbug.com/508900 is
+ // resolved.
+ CHECK(request_->status().is_success());
// Initialize to the current time, and let the subclass optionally override
// the time stamps if it has that information. The default request_time is
@@ -409,17 +396,8 @@ void URLRequestJob::NotifyHeadersComplete() {
request_->response_info_.response_time = base::Time::Now();
GetResponseInfo(&request_->response_info_);
- // When notifying the delegate, the delegate can release the request
- // (and thus release 'this'). After calling to the delgate, we must
- // check the request pointer to see if it still exists, and return
- // immediately if it has been destroyed. self_preservation ensures our
- // survival until we can get out of this method.
- scoped_refptr<URLRequestJob> self_preservation(this);
-
MaybeNotifyNetworkBytes();
-
- if (request_)
- request_->OnHeadersComplete();
+ request_->OnHeadersComplete();
GURL new_location;
int http_status_code;
@@ -428,26 +406,31 @@ void URLRequestJob::NotifyHeadersComplete() {
// so it does not treat being stopped as an error.
DoneReadingRedirectResponse();
+ // When notifying the URLRequest::Delegate, it can destroy the request,
+ // which will destroy |this|. After calling to the URLRequest::Delegate,
+ // pointer must be checked to see if |this| still exists, and if not, the
+ // code must return immediately.
+ base::WeakPtr<URLRequestJob> weak_this(weak_factory_.GetWeakPtr());
+
RedirectInfo redirect_info =
ComputeRedirectInfo(new_location, http_status_code);
bool defer_redirect = false;
request_->NotifyReceivedRedirect(redirect_info, &defer_redirect);
- // Ensure that the request wasn't detached or destroyed in
- // NotifyReceivedRedirect
- if (!request_ || !request_->has_delegate())
+ // Ensure that the request wasn't detached, destroyed, or canceled in
+ // NotifyReceivedRedirect.
+ if (!weak_this || !request_->status().is_success())
return;
- // If we were not cancelled, then maybe follow the redirect.
- if (request_->status().is_success()) {
- if (defer_redirect) {
- deferred_redirect_info_ = redirect_info;
- } else {
- FollowRedirect(redirect_info);
- }
- return;
+ if (defer_redirect) {
+ deferred_redirect_info_ = redirect_info;
+ } else {
+ FollowRedirect(redirect_info);
}
- } else if (NeedsAuth()) {
+ return;
+ }
+
+ if (NeedsAuth()) {
scoped_refptr<AuthChallengeInfo> auth_info;
GetAuthChallengeInfo(&auth_info);
@@ -476,16 +459,25 @@ void URLRequestJob::NotifyHeadersComplete() {
}
request_->NotifyResponseStarted();
+
+ // |this| may be destroyed at this point.
}
-void URLRequestJob::NotifyReadComplete(int bytes_read) {
+void URLRequestJob::ConvertResultToError(int result, Error* error, int* count) {
+ if (result >= 0) {
+ *error = OK;
+ *count = result;
+ } else {
+ *error = static_cast<Error>(result);
+ *count = 0;
+ }
+}
+
+void URLRequestJob::ReadRawDataComplete(int result) {
// TODO(cbentzel): Remove ScopedTracker below once crbug.com/475755 is fixed.
tracked_objects::ScopedTracker tracking_profile(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "475755 URLRequestJob::NotifyReadComplete"));
-
- if (!request_ || !request_->has_delegate())
- return; // The request was destroyed, so there is no more work to do.
+ "475755 URLRequestJob::RawReadCompleted"));
// TODO(darin): Bug 1004233. Re-enable this test once all of the chrome
// unit_tests have been fixed to not trip this.
@@ -495,52 +487,71 @@ void URLRequestJob::NotifyReadComplete(int bytes_read) {
// The headers should be complete before reads complete
DCHECK(has_handled_response_);
- OnRawReadComplete(bytes_read);
+ Error error;
+ int bytes_read;
+ ConvertResultToError(result, &error, &bytes_read);
- // Don't notify if we had an error.
- if (!request_->status().is_success())
- return;
+ DCHECK_NE(ERR_IO_PENDING, error);
- // When notifying the delegate, the delegate can release the request
- // (and thus release 'this'). After calling to the delegate, we must
- // check the request pointer to see if it still exists, and return
- // immediately if it has been destroyed. self_preservation ensures our
- // survival until we can get out of this method.
- scoped_refptr<URLRequestJob> self_preservation(this);
+ // Synchronize the URLRequest state machine with the URLRequestJob state
+ // machine. If this read succeeded, either the request is at EOF and the
+ // URLRequest state machine goes to 'finished', or it is not and the
+ // URLRequest state machine goes to 'success'. If the read failed, the
+ // URLRequest state machine goes directly to 'finished'.
+ //
+ // Update the URLRequest's status first, so that NotifyReadCompleted has an
+ // accurate view of the request.
+ if (error == OK && bytes_read > 0) {
+ SetStatus(URLRequestStatus());
+ } else {
+ NotifyDone(URLRequestStatus::FromError(error));
+ }
- if (filter_.get()) {
- // Tell the filter that it has more data
- FilteredDataRead(bytes_read);
+ GatherRawReadStats(error, bytes_read);
- // Filter the data.
+ if (filter_.get() && error == OK) {
int filter_bytes_read = 0;
- if (ReadFilteredData(&filter_bytes_read)) {
- if (!filter_bytes_read)
- DoneReading();
- request_->NotifyReadCompleted(filter_bytes_read);
- }
+ // Tell the filter that it has more data.
+ PushInputToFilter(bytes_read);
+
+ // Filter the data.
+ error = ReadFilteredData(&filter_bytes_read);
+
+ if (error == OK && !filter_bytes_read)
+ DoneReading();
+
+ DVLOG(1) << __FUNCTION__ << "() "
+ << "\"" << request_->url().spec() << "\""
+ << " pre bytes read = " << bytes_read
+ << " pre total = " << prefilter_bytes_read_
+ << " post total = " << postfilter_bytes_read_;
+ bytes_read = filter_bytes_read;
} else {
- request_->NotifyReadCompleted(bytes_read);
+ DVLOG(1) << __FUNCTION__ << "() "
+ << "\"" << request_->url().spec() << "\""
+ << " pre bytes read = " << bytes_read
+ << " pre total = " << prefilter_bytes_read_
+ << " post total = " << postfilter_bytes_read_;
}
- DVLOG(1) << __FUNCTION__ << "() "
- << "\"" << (request_ ? request_->url().spec() : "???") << "\""
- << " pre bytes read = " << bytes_read
- << " pre total = " << prefilter_bytes_read_
- << " post total = " << postfilter_bytes_read_;
+
+ // NotifyReadCompleted should be called after SetStatus or NotifyDone updates
+ // the status.
+ if (error == OK)
+ request_->NotifyReadCompleted(bytes_read);
+
+ // |this| may be destroyed at this point.
}
void URLRequestJob::NotifyStartError(const URLRequestStatus &status) {
DCHECK(!has_handled_response_);
has_handled_response_ = true;
- if (request_) {
- // There may be relevant information in the response info even in the
- // error case.
- GetResponseInfo(&request_->response_info_);
+ // There may be relevant information in the response info even in the
+ // error case.
+ GetResponseInfo(&request_->response_info_);
- request_->set_status(status);
- request_->NotifyResponseStarted();
- // We may have been deleted.
- }
+ request_->set_status(status);
+ request_->NotifyResponseStarted();
+ // |this| may have been deleted here.
}
void URLRequestJob::NotifyDone(const URLRequestStatus &status) {
@@ -553,39 +564,35 @@ void URLRequestJob::NotifyDone(const URLRequestStatus &status) {
// the response before getting here.
DCHECK(has_handled_response_ || !status.is_success());
- // As with NotifyReadComplete, we need to take care to notice if we were
- // destroyed during a delegate callback.
- if (request_) {
- request_->set_is_pending(false);
- // With async IO, it's quite possible to have a few outstanding
- // requests. We could receive a request to Cancel, followed shortly
- // by a successful IO. For tracking the status(), once there is
- // an error, we do not change the status back to success. To
- // enforce this, only set the status if the job is so far
- // successful.
- if (request_->status().is_success()) {
- if (status.status() == URLRequestStatus::FAILED) {
- request_->net_log().AddEventWithNetErrorCode(NetLog::TYPE_FAILED,
- status.error());
- }
- request_->set_status(status);
+ request_->set_is_pending(false);
+ // With async IO, it's quite possible to have a few outstanding
+ // requests. We could receive a request to Cancel, followed shortly
+ // by a successful IO. For tracking the status(), once there is
+ // an error, we do not change the status back to success. To
+ // enforce this, only set the status if the job is so far
+ // successful.
+ if (request_->status().is_success()) {
+ if (status.status() == URLRequestStatus::FAILED) {
+ request_->net_log().AddEventWithNetErrorCode(NetLog::TYPE_FAILED,
+ status.error());
}
+ request_->set_status(status);
+ }
- // If the request succeeded (And wasn't cancelled) and the response code was
- // 4xx or 5xx, record whether or not the main frame was blank. This is
- // intended to be a short-lived histogram, used to figure out how important
- // fixing http://crbug.com/331745 is.
- if (request_->status().is_success()) {
- int response_code = GetResponseCode();
- if (400 <= response_code && response_code <= 599) {
- bool page_has_content = (postfilter_bytes_read_ != 0);
- if (request_->load_flags() & net::LOAD_MAIN_FRAME) {
- UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentMainFrame",
- page_has_content);
- } else {
- UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentNonMainFrame",
- page_has_content);
- }
+ // If the request succeeded (And wasn't cancelled) and the response code was
+ // 4xx or 5xx, record whether or not the main frame was blank. This is
+ // intended to be a short-lived histogram, used to figure out how important
+ // fixing http://crbug.com/331745 is.
+ if (request_->status().is_success()) {
+ int response_code = GetResponseCode();
+ if (400 <= response_code && response_code <= 599) {
+ bool page_has_content = (postfilter_bytes_read_ != 0);
+ if (request_->load_flags() & net::LOAD_MAIN_FRAME) {
+ UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentMainFrame",
+ page_has_content);
+ } else {
+ UMA_HISTOGRAM_BOOLEAN("Net.ErrorResponseHasContentNonMainFrame",
+ page_has_content);
}
}
}
@@ -601,9 +608,7 @@ void URLRequestJob::NotifyDone(const URLRequestStatus &status) {
void URLRequestJob::CompleteNotifyDone() {
// Check if we should notify the delegate that we're done because of an error.
- if (request_ &&
- !request_->status().is_success() &&
- request_->has_delegate()) {
+ if (!request_->status().is_success()) {
// We report the error differently depending on whether we've called
// OnResponseStarted yet.
if (has_handled_response_) {
@@ -636,11 +641,8 @@ void URLRequestJob::OnCallToDelegateComplete() {
request_->OnCallToDelegateComplete();
}
-bool URLRequestJob::ReadRawData(IOBuffer* buf, int buf_size,
- int *bytes_read) {
- DCHECK(bytes_read);
- *bytes_read = 0;
- return true;
+int URLRequestJob::ReadRawData(IOBuffer* buf, int buf_size) {
+ return 0;
}
void URLRequestJob::DoneReading() {
@@ -650,38 +652,34 @@ void URLRequestJob::DoneReading() {
void URLRequestJob::DoneReadingRedirectResponse() {
}
-void URLRequestJob::FilteredDataRead(int bytes_read) {
+void URLRequestJob::PushInputToFilter(int bytes_read) {
DCHECK(filter_);
filter_->FlushStreamBuffer(bytes_read);
}
-bool URLRequestJob::ReadFilteredData(int* bytes_read) {
+Error URLRequestJob::ReadFilteredData(int* bytes_read) {
DCHECK(filter_);
DCHECK(filtered_read_buffer_.get());
DCHECK_GT(filtered_read_buffer_len_, 0);
DCHECK_LT(filtered_read_buffer_len_, 1000000); // Sanity check.
- DCHECK(!raw_read_buffer_.get());
+ DCHECK(!raw_read_buffer_);
*bytes_read = 0;
- bool rv = false;
+ Error error = ERR_FAILED;
for (;;) {
if (is_done())
- return true;
+ return OK;
if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) {
// We don't have any raw data to work with, so read from the transaction.
int filtered_data_read;
- if (ReadRawDataForFilter(&filtered_data_read)) {
- if (filtered_data_read > 0) {
- // Give data to filter.
- filter_->FlushStreamBuffer(filtered_data_read);
- } else {
- return true; // EOF.
- }
- } else {
- return false; // IO Pending (or error).
- }
+ error = ReadRawDataForFilter(&filtered_data_read);
+ // If ReadRawDataForFilter returned some data, fall through to the case
+ // below; otherwise, return early.
+ if (error != OK || filtered_data_read == 0)
+ return error;
+ filter_->FlushStreamBuffer(filtered_data_read);
}
if ((filter_->stream_data_len() || filter_needs_more_output_space_) &&
@@ -707,7 +705,7 @@ bool URLRequestJob::ReadFilteredData(int* bytes_read) {
filter_needs_more_output_space_ = false;
*bytes_read = filtered_data_len;
postfilter_bytes_read_ += filtered_data_len;
- rv = true;
+ error = OK;
break;
}
case Filter::FILTER_NEED_MORE_DATA: {
@@ -720,7 +718,7 @@ bool URLRequestJob::ReadFilteredData(int* bytes_read) {
if (filtered_data_len > 0) {
*bytes_read = filtered_data_len;
postfilter_bytes_read_ += filtered_data_len;
- rv = true;
+ error = OK;
} else {
// Read again since we haven't received enough data yet (e.g., we
// may not have a complete gzip header yet).
@@ -731,29 +729,27 @@ bool URLRequestJob::ReadFilteredData(int* bytes_read) {
case Filter::FILTER_OK: {
*bytes_read = filtered_data_len;
postfilter_bytes_read_ += filtered_data_len;
- rv = true;
+ error = OK;
break;
}
case Filter::FILTER_ERROR: {
DVLOG(1) << __FUNCTION__ << "() "
- << "\"" << (request_ ? request_->url().spec() : "???")
- << "\"" << " Filter Error";
+ << "\"" << request_->url().spec() << "\""
+ << " Filter Error";
filter_needs_more_output_space_ = false;
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
- ERR_CONTENT_DECODING_FAILED));
- rv = false;
+ error = ERR_CONTENT_DECODING_FAILED;
break;
}
default: {
NOTREACHED();
filter_needs_more_output_space_ = false;
- rv = false;
+ error = ERR_FAILED;
break;
}
}
// If logging all bytes is enabled, log the filtered bytes read.
- if (rv && request() && filtered_data_len > 0 &&
+ if (error == OK && filtered_data_len > 0 &&
request()->net_log().IsCapturing()) {
request()->net_log().AddByteTransferEvent(
NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ, filtered_data_len,
@@ -761,18 +757,18 @@ bool URLRequestJob::ReadFilteredData(int* bytes_read) {
}
} else {
// we are done, or there is no data left.
- rv = true;
+ error = OK;
}
break;
}
- if (rv) {
+ if (error == OK) {
// When we successfully finished a read, we no longer need to save the
// caller's buffers. Release our reference.
filtered_read_buffer_ = NULL;
filtered_read_buffer_len_ = 0;
}
- return rv;
+ return error;
}
void URLRequestJob::DestroyFilters() {
@@ -780,32 +776,26 @@ void URLRequestJob::DestroyFilters() {
}
const URLRequestStatus URLRequestJob::GetStatus() {
- if (request_)
- return request_->status();
- // If the request is gone, we must be cancelled.
- return URLRequestStatus(URLRequestStatus::CANCELED,
- ERR_ABORTED);
+ return request_->status();
}
void URLRequestJob::SetStatus(const URLRequestStatus &status) {
- if (request_) {
- // An error status should never be replaced by a non-error status by a
- // URLRequestJob. URLRequest has some retry paths, but it resets the status
- // itself, if needed.
- DCHECK(request_->status().is_io_pending() ||
- request_->status().is_success() ||
- (!status.is_success() && !status.is_io_pending()));
- request_->set_status(status);
- }
+ // An error status should never be replaced by a non-error status by a
+ // URLRequestJob. URLRequest has some retry paths, but it resets the status
+ // itself, if needed.
+ // TODO(mmenke): Change this to a DCHECK once https://crbug.com/508900 is
+ // resolved.
+ CHECK(request_->status().is_io_pending() || request_->status().is_success() ||
+ (!status.is_success() && !status.is_io_pending()));
+ request_->set_status(status);
}
void URLRequestJob::SetProxyServer(const HostPortPair& proxy_server) {
request_->proxy_server_ = proxy_server;
}
-bool URLRequestJob::ReadRawDataForFilter(int* bytes_read) {
- bool rv = false;
-
+Error URLRequestJob::ReadRawDataForFilter(int* bytes_read) {
+ Error error = ERR_FAILED;
DCHECK(bytes_read);
DCHECK(filter_.get());
@@ -817,29 +807,28 @@ bool URLRequestJob::ReadRawDataForFilter(int* bytes_read) {
if (!filter_->stream_data_len() && !is_done()) {
IOBuffer* stream_buffer = filter_->stream_buffer();
int stream_buffer_size = filter_->stream_buffer_size();
- rv = ReadRawDataHelper(stream_buffer, stream_buffer_size, bytes_read);
+ error = ReadRawDataHelper(stream_buffer, stream_buffer_size, bytes_read);
}
- return rv;
+ return error;
}
-bool URLRequestJob::ReadRawDataHelper(IOBuffer* buf, int buf_size,
- int* bytes_read) {
- DCHECK(!request_->status().is_io_pending());
- DCHECK(raw_read_buffer_.get() == NULL);
+Error URLRequestJob::ReadRawDataHelper(IOBuffer* buf,
+ int buf_size,
+ int* bytes_read) {
+ DCHECK(!raw_read_buffer_);
- // Keep a pointer to the read buffer, so we have access to it in the
- // OnRawReadComplete() callback in the event that the read completes
- // asynchronously.
+ // Keep a pointer to the read buffer, so we have access to it in
+ // GatherRawReadStats() in the event that the read completes asynchronously.
raw_read_buffer_ = buf;
- bool rv = ReadRawData(buf, buf_size, bytes_read);
+ Error error;
+ ConvertResultToError(ReadRawData(buf, buf_size), &error, bytes_read);
- if (!request_->status().is_io_pending()) {
- // If the read completes synchronously, either success or failure,
- // invoke the OnRawReadComplete callback so we can account for the
- // completed read.
- OnRawReadComplete(*bytes_read);
+ if (error != ERR_IO_PENDING) {
+ // If the read completes synchronously, either success or failure, invoke
+ // GatherRawReadStats so we can account for the completed read.
+ GatherRawReadStats(error, *bytes_read);
}
- return rv;
+ return error;
}
void URLRequestJob::FollowRedirect(const RedirectInfo& redirect_info) {
@@ -848,20 +837,26 @@ void URLRequestJob::FollowRedirect(const RedirectInfo& redirect_info) {
NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
}
-void URLRequestJob::OnRawReadComplete(int bytes_read) {
- DCHECK(raw_read_buffer_.get());
- // If |filter_| is non-NULL, bytes will be logged after it is applied instead.
- if (!filter_.get() && request() && bytes_read > 0 &&
- request()->net_log().IsCapturing()) {
+void URLRequestJob::GatherRawReadStats(Error error, int bytes_read) {
+ DCHECK(raw_read_buffer_ || bytes_read == 0);
+ DCHECK_NE(ERR_IO_PENDING, error);
+
+ if (error != OK) {
+ raw_read_buffer_ = nullptr;
+ return;
+ }
+ // If |filter_| is non-NULL, bytes will be logged after it is applied
+ // instead.
+ if (!filter_.get() && bytes_read > 0 && request()->net_log().IsCapturing()) {
request()->net_log().AddByteTransferEvent(
- NetLog::TYPE_URL_REQUEST_JOB_BYTES_READ,
- bytes_read, raw_read_buffer_->data());
+ NetLog::TYPE_URL_REQUEST_JOB_BYTES_READ, bytes_read,
+ raw_read_buffer_->data());
}
if (bytes_read > 0) {
RecordBytesRead(bytes_read);
}
- raw_read_buffer_ = NULL;
+ raw_read_buffer_ = nullptr;
}
void URLRequestJob::RecordBytesRead(int bytes_read) {
@@ -875,7 +870,7 @@ void URLRequestJob::RecordBytesRead(int bytes_read) {
// If prefilter_bytes_read_ is equal to bytes_read, it indicates this is the
// first raw read of the response body. This is used as the signal that
// response headers have been received.
- if (request_ && request_->context()->network_quality_estimator() &&
+ if (request_->context()->network_quality_estimator() &&
prefilter_bytes_read_ == bytes_read) {
request_->context()->network_quality_estimator()->NotifyHeadersReceived(
*request_);
@@ -884,7 +879,7 @@ void URLRequestJob::RecordBytesRead(int bytes_read) {
if (!filter_.get())
postfilter_bytes_read_ += bytes_read;
DVLOG(2) << __FUNCTION__ << "() "
- << "\"" << (request_ ? request_->url().spec() : "???") << "\""
+ << "\"" << request_->url().spec() << "\""
<< " pre bytes read = " << bytes_read
<< " pre total = " << prefilter_bytes_read_
<< " post total = " << postfilter_bytes_read_;
@@ -950,7 +945,7 @@ RedirectInfo URLRequestJob::ComputeRedirectInfo(const GURL& location,
}
void URLRequestJob::MaybeNotifyNetworkBytes() {
- if (!request_ || !network_delegate_)
+ if (!network_delegate_)
return;
// Report any new received bytes.
@@ -958,7 +953,7 @@ void URLRequestJob::MaybeNotifyNetworkBytes() {
DCHECK_GE(total_received_bytes, last_notified_total_received_bytes_);
if (total_received_bytes > last_notified_total_received_bytes_) {
network_delegate_->NotifyNetworkBytesReceived(
- *request_, total_received_bytes - last_notified_total_received_bytes_);
+ request_, total_received_bytes - last_notified_total_received_bytes_);
}
last_notified_total_received_bytes_ = total_received_bytes;
@@ -967,7 +962,7 @@ void URLRequestJob::MaybeNotifyNetworkBytes() {
DCHECK_GE(total_sent_bytes, last_notified_total_sent_bytes_);
if (total_sent_bytes > last_notified_total_sent_bytes_) {
network_delegate_->NotifyNetworkBytesSent(
- *request_, total_sent_bytes - last_notified_total_sent_bytes_);
+ request_, total_sent_bytes - last_notified_total_sent_bytes_);
}
last_notified_total_sent_bytes_ = total_sent_bytes;
}
diff --git a/chromium/net/url_request/url_request_job.h b/chromium/net/url_request/url_request_job.h
index 82b13633cd0..2fbf70e39bc 100644
--- a/chromium/net/url_request/url_request_job.h
+++ b/chromium/net/url_request/url_request_job.h
@@ -10,13 +10,14 @@
#include <string>
#include <vector>
-#include "base/memory/ref_counted.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_observer.h"
#include "net/base/host_port_pair.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/base/upload_progress.h"
@@ -39,19 +40,18 @@ struct LoadTimingInfo;
class NetworkDelegate;
class SSLCertRequestInfo;
class SSLInfo;
+class SSLPrivateKey;
class UploadDataStream;
class URLRequestStatus;
class X509Certificate;
-class NET_EXPORT URLRequestJob
- : public base::RefCounted<URLRequestJob>,
- public base::PowerObserver {
+class NET_EXPORT URLRequestJob : public base::PowerObserver {
public:
explicit URLRequestJob(URLRequest* request,
NetworkDelegate* network_delegate);
+ ~URLRequestJob() override;
- // Returns the request that owns this job. THIS POINTER MAY BE NULL if the
- // request was destroyed.
+ // Returns the request that owns this job.
URLRequest* request() const {
return request_;
}
@@ -95,10 +95,6 @@ class NET_EXPORT URLRequestJob
// one notification must be issued.
virtual void Kill();
- // Called to detach the request from this Job. Results in the Job being
- // killed off eventually. The job must not use the request pointer any more.
- void DetachRequest();
-
// Called to read post-filtered data from this Job, returning the number of
// bytes read, 0 when there is no more data, or -1 if there was an error.
// This is just the backend for URLRequest::Read, see that function for
@@ -149,6 +145,10 @@ class NET_EXPORT URLRequestJob
// useful results once per job.
virtual bool GetResponseCookies(std::vector<std::string>* cookies);
+ // Populates the network error details of the most recent origin that the
+ // network stack makes the request to.
+ virtual void PopulateNetErrorDetails(NetErrorDetails* details) const;
+
// Called to setup a stream filter for this request. An example of filter is
// content encoding/decoding.
// Subclasses should return the appropriate Filter, or NULL for no Filter.
@@ -198,7 +198,8 @@ class NET_EXPORT URLRequestJob
// Display the error page without asking for credentials again.
virtual void CancelAuth();
- virtual void ContinueWithCertificate(X509Certificate* client_cert);
+ virtual void ContinueWithCertificate(X509Certificate* client_cert,
+ SSLPrivateKey* client_private_key);
// Continue processing the request ignoring the last error.
virtual void ContinueDespiteLastError();
@@ -213,8 +214,8 @@ class NET_EXPORT URLRequestJob
bool is_done() const { return done_; }
// Get/Set expected content size
- int64 expected_content_size() const { return expected_content_size_; }
- void set_expected_content_size(const int64& size) {
+ int64_t expected_content_size() const { return expected_content_size_; }
+ void set_expected_content_size(const int64_t& size) {
expected_content_size_ = size;
}
@@ -251,9 +252,6 @@ class NET_EXPORT URLRequestJob
const GURL& redirect_destination);
protected:
- friend class base::RefCounted<URLRequestJob>;
- ~URLRequestJob() override;
-
// Notifies the job that a certificate is requested.
void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info);
@@ -276,23 +274,9 @@ class NET_EXPORT URLRequestJob
// Notifies the job that headers have been received.
void NotifyHeadersComplete();
- // Notifies the request that the job has completed a Read operation.
- void NotifyReadComplete(int bytes_read);
-
// Notifies the request that a start error has occurred.
void NotifyStartError(const URLRequestStatus& status);
- // NotifyDone marks when we are done with a request. It is really
- // a glorified set_status, but also does internal state checking and
- // job tracking. It should be called once per request, when the job is
- // finished doing all IO.
- void NotifyDone(const URLRequestStatus& status);
-
- // Some work performed by NotifyDone must be completed on a separate task
- // so as to avoid re-entering the delegate. This method exists to perform
- // that work.
- void CompleteNotifyDone();
-
// Used as an asynchronous callback for Kill to notify the URLRequest
// that we were canceled.
void NotifyCanceled();
@@ -305,17 +289,19 @@ class NET_EXPORT URLRequestJob
void OnCallToDelegate();
void OnCallToDelegateComplete();
- // Called to read raw (pre-filtered) data from this Job.
- // If returning true, data was read from the job. buf will contain
- // the data, and bytes_read will receive the number of bytes read.
- // If returning true, and bytes_read is returned as 0, there is no
- // additional data to be read.
- // If returning false, an error occurred or an async IO is now pending.
- // If async IO is pending, the status of the request will be
- // URLRequestStatus::IO_PENDING, and buf must remain available until the
- // operation is completed. See comments on URLRequest::Read for more
- // info.
- virtual bool ReadRawData(IOBuffer* buf, int buf_size, int *bytes_read);
+ // Called to read raw (pre-filtered) data from this Job. Reads at most
+ // |buf_size| bytes into |buf|.
+ // Possible return values:
+ // >= 0: Read completed synchronously. Return value is the number of bytes
+ // read. 0 means eof.
+ // ERR_IO_PENDING: Read pending asynchronously.
+ // When the read completes, |ReadRawDataComplete| should be
+ // called.
+ // Any other negative number: Read failed synchronously. Return value is a
+ // network error code.
+ // This method might hold onto a reference to |buf| (by incrementing the
+ // refcount) until the method completes or is cancelled.
+ virtual int ReadRawData(IOBuffer* buf, int buf_size);
// Called to tell the job that a filter has successfully reached the end of
// the stream.
@@ -326,14 +312,14 @@ class NET_EXPORT URLRequestJob
// bodies are never read.
virtual void DoneReadingRedirectResponse();
- // Informs the filter that data has been read into its buffer
- void FilteredDataRead(int bytes_read);
-
- // Reads filtered data from the request. Returns true if successful,
- // false otherwise. Note, if there is not enough data received to
- // return data, this call can issue a new async IO request under
- // the hood.
- bool ReadFilteredData(int *bytes_read);
+ // Reads filtered data from the request. Returns OK if immediately successful,
+ // ERR_IO_PENDING if the request couldn't complete synchronously, and some
+ // other error code if the request failed synchronously. Note that this
+ // function can issue new asynchronous requests if needed, in which case it
+ // returns ERR_IO_PENDING. If this method completes synchronously,
+ // |*bytes_read| is the number of bytes output by the filter chain if this
+ // method returns OK, or zero if this method returns an error.
+ Error ReadFilteredData(int* bytes_read);
// Whether the response is being filtered in this job.
// Only valid after NotifyHeadersComplete() has been called.
@@ -359,25 +345,38 @@ class NET_EXPORT URLRequestJob
// The number of bytes read before passing to the filter. This value reflects
// bytes read even when there is no filter.
- int64 prefilter_bytes_read() const { return prefilter_bytes_read_; }
+ int64_t prefilter_bytes_read() const { return prefilter_bytes_read_; }
// The number of bytes read after passing through the filter. This value
// reflects bytes read even when there is no filter.
- int64 postfilter_bytes_read() const { return postfilter_bytes_read_; }
+ int64_t postfilter_bytes_read() const { return postfilter_bytes_read_; }
+
+ // Turns an integer result code into an Error and a count of bytes read.
+ // The semantics are:
+ // |result| >= 0: |*error| == OK, |*count| == |result|
+ // |result| < 0: |*error| = |result|, |*count| == 0
+ static void ConvertResultToError(int result, Error* error, int* count);
- // The request that initiated this job. This value MAY BE NULL if the
- // request was released by DetachRequest().
+ // Completion callback for raw reads. See |ReadRawData| for details.
+ // |bytes_read| is either >= 0 to indicate a successful read and count of
+ // bytes read, or < 0 to indicate an error.
+ void ReadRawDataComplete(int bytes_read);
+
+ // The request that initiated this job. This value will never be nullptr.
URLRequest* request_;
private:
// When data filtering is enabled, this function is used to read data
- // for the filter. Returns true if raw data was read. Returns false if
- // an error occurred (or we are waiting for IO to complete).
- bool ReadRawDataForFilter(int *bytes_read);
+ // for the filter. Returns a net error code to indicate if raw data was
+ // successfully read, an error happened, or the IO is pending.
+ Error ReadRawDataForFilter(int* bytes_read);
+
+ // Informs the filter chain that data has been read into its buffer.
+ void PushInputToFilter(int bytes_read);
// Invokes ReadRawData and records bytes read if the read completes
// synchronously.
- bool ReadRawDataHelper(IOBuffer* buf, int buf_size, int* bytes_read);
+ Error ReadRawDataHelper(IOBuffer* buf, int buf_size, int* bytes_read);
// Called in response to a redirect that was not canceled to follow the
// redirect. The current job will be replaced with a new job loading the
@@ -386,9 +385,9 @@ class NET_EXPORT URLRequestJob
// Called after every raw read. If |bytes_read| is > 0, this indicates
// a successful read of |bytes_read| unfiltered bytes. If |bytes_read|
- // is 0, this indicates that there is no additional data to read. If
- // |bytes_read| is < 0, an error occurred and no bytes were read.
- void OnRawReadComplete(int bytes_read);
+ // is 0, this indicates that there is no additional data to read. |error|
+ // specifies whether an error occurred and no bytes were read.
+ void GatherRawReadStats(Error error, int bytes_read);
// Updates the profiling info and notifies observers that an additional
// |bytes_read| unfiltered bytes have been read for this job.
@@ -398,6 +397,16 @@ class NET_EXPORT URLRequestJob
// out.
bool FilterHasData();
+ // NotifyDone marks that request is done. It is really a glorified
+ // set_status, but also does internal state checking and job tracking. It
+ // should be called once per request, when the job is finished doing all IO.
+ void NotifyDone(const URLRequestStatus& status);
+
+ // Some work performed by NotifyDone must be completed asynchronously so
+ // as to avoid re-entering URLRequest::Delegate. This method performs that
+ // work.
+ void CompleteNotifyDone();
+
// Subclasses may implement this method to record packet arrival times.
// The default implementation does nothing. Only invoked when bytes have been
// read since the last invocation.
@@ -417,8 +426,8 @@ class NET_EXPORT URLRequestJob
// NotifyDone so that it is kept in sync with the request.
bool done_;
- int64 prefilter_bytes_read_;
- int64 postfilter_bytes_read_;
+ int64_t prefilter_bytes_read_;
+ int64_t postfilter_bytes_read_;
// The data stream filter which is enabled on demand.
scoped_ptr<Filter> filter_;
@@ -443,7 +452,7 @@ class NET_EXPORT URLRequestJob
bool has_handled_response_;
// Expected content size
- int64 expected_content_size_;
+ int64_t expected_content_size_;
// Set when a redirect is deferred.
RedirectInfo deferred_redirect_info_;
diff --git a/chromium/net/url_request/url_request_job_factory.h b/chromium/net/url_request/url_request_job_factory.h
index 96f218a3d27..4df4cd717f7 100644
--- a/chromium/net/url_request/url_request_job_factory.h
+++ b/chromium/net/url_request/url_request_job_factory.h
@@ -7,8 +7,8 @@
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/threading/non_thread_safe.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/url_request/url_request_job_factory_impl.cc b/chromium/net/url_request/url_request_job_factory_impl.cc
index b7024ad8962..58b97f59937 100644
--- a/chromium/net/url_request/url_request_job_factory_impl.cc
+++ b/chromium/net/url_request/url_request_job_factory_impl.cc
@@ -20,9 +20,7 @@ URLRequestInterceptor* g_interceptor_for_testing = NULL;
URLRequestJobFactoryImpl::URLRequestJobFactoryImpl() {}
-URLRequestJobFactoryImpl::~URLRequestJobFactoryImpl() {
- STLDeleteValues(&protocol_handler_map_);
-}
+URLRequestJobFactoryImpl::~URLRequestJobFactoryImpl() {}
bool URLRequestJobFactoryImpl::SetProtocolHandler(
const std::string& scheme,
@@ -34,14 +32,13 @@ bool URLRequestJobFactoryImpl::SetProtocolHandler(
if (it == protocol_handler_map_.end())
return false;
- delete it->second;
protocol_handler_map_.erase(it);
return true;
}
if (ContainsKey(protocol_handler_map_, scheme))
return false;
- protocol_handler_map_[scheme] = protocol_handler.release();
+ protocol_handler_map_[scheme] = std::move(protocol_handler);
return true;
}
diff --git a/chromium/net/url_request/url_request_job_factory_impl.h b/chromium/net/url_request/url_request_job_factory_impl.h
index cba11248ca0..aee73685740 100644
--- a/chromium/net/url_request/url_request_job_factory_impl.h
+++ b/chromium/net/url_request/url_request_job_factory_impl.h
@@ -8,8 +8,8 @@
#include <map>
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/url_request/url_request_job_factory.h"
@@ -51,7 +51,7 @@ class NET_EXPORT URLRequestJobFactoryImpl : public URLRequestJobFactory {
// For testing only.
friend class URLRequestFilter;
- typedef std::map<std::string, ProtocolHandler*> ProtocolHandlerMap;
+ typedef std::map<std::string, scoped_ptr<ProtocolHandler>> ProtocolHandlerMap;
// Sets a global URLRequestInterceptor for testing purposes. The interceptor
// is given the chance to intercept any request before the corresponding
diff --git a/chromium/net/url_request/url_request_job_manager.h b/chromium/net/url_request/url_request_job_manager.h
index 422a9821636..ab67c8a9876 100644
--- a/chromium/net/url_request/url_request_job_manager.h
+++ b/chromium/net/url_request/url_request_job_manager.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "net/base/net_export.h"
#include "net/url_request/url_request.h"
diff --git a/chromium/net/url_request/url_request_job_unittest.cc b/chromium/net/url_request/url_request_job_unittest.cc
index f9ea1fe6170..f3796bdb4c9 100644
--- a/chromium/net/url_request/url_request_job_unittest.cc
+++ b/chromium/net/url_request/url_request_job_unittest.cc
@@ -16,10 +16,20 @@ namespace net {
namespace {
+// Data encoded in kBrotliHelloData.
+const char kBrotliDecodedHelloData[] = "hello, world!\n";
+// kBrotliDecodedHelloData encoded with brotli.
+const char kBrotliHelloData[] =
+ "\033\015\0\0\244\024\102\152\020\111\152\072\235\126\034";
+
// This is a header that signals the end of the data.
const char kGzipData[] = "\x1f\x08b\x08\0\0\0\0\0\0\3\3\0\0\0\0\0\0\0\0";
const char kGzipDataWithName[] =
"\x1f\x08b\x08\x08\0\0\0\0\0\0name\0\3\0\0\0\0\0\0\0\0";
+// Gzip data that contains the word hello with a newline character.
+const char kGzipHelloData[] =
+ "\x1f\x8b\x08\x08\x46\x7d\x4e\x56\x00\x03\x67\x7a\x69\x70\x2e\x74\x78\x74"
+ "\x00\xcb\x48\xcd\xc9\xc9\xe7\x02\x00\x20\x30\x3a\x36\x06\x00\x00\x00";
void GZipServer(const HttpRequestInfo* request,
std::string* response_status,
@@ -28,6 +38,13 @@ void GZipServer(const HttpRequestInfo* request,
response_data->assign(kGzipData, sizeof(kGzipData));
}
+void GZipHelloServer(const HttpRequestInfo* request,
+ std::string* response_status,
+ std::string* response_headers,
+ std::string* response_data) {
+ response_data->assign(kGzipHelloData, sizeof(kGzipHelloData));
+}
+
void BigGZipServer(const HttpRequestInfo* request,
std::string* response_status,
std::string* response_headers,
@@ -36,6 +53,13 @@ void BigGZipServer(const HttpRequestInfo* request,
response_data->insert(10, 64 * 1024, 'a');
}
+void BrotliHelloServer(const HttpRequestInfo* request,
+ std::string* response_status,
+ std::string* response_headers,
+ std::string* response_data) {
+ response_data->assign(kBrotliHelloData, sizeof(kBrotliHelloData) - 1);
+}
+
const MockTransaction kGZip_Transaction = {
"http://www.google.com/gzyp",
"GET",
@@ -56,6 +80,14 @@ const MockTransaction kGZip_Transaction = {
OK,
};
+const MockTransaction kGzip_Slow_Transaction = {
+ "http://www.google.com/gzyp", "GET", base::Time(), "", LOAD_NORMAL,
+ "HTTP/1.1 200 OK",
+ "Cache-Control: max-age=10000\n"
+ "Content-Encoding: gzip\n",
+ base::Time(), "", TEST_MODE_SLOW_READ, &GZipHelloServer, nullptr, 0, 0, OK,
+};
+
const MockTransaction kRedirect_Transaction = {
"http://www.google.com/redirect",
"GET",
@@ -76,6 +108,33 @@ const MockTransaction kRedirect_Transaction = {
OK,
};
+const MockTransaction kEmptyBodyGzip_Transaction = {
+ "http://www.google.com/empty_body",
+ "GET",
+ base::Time(),
+ "",
+ LOAD_NORMAL,
+ "HTTP/1.1 200 OK",
+ "Content-Encoding: gzip\n",
+ base::Time(),
+ "",
+ TEST_MODE_NORMAL,
+ nullptr,
+ nullptr,
+ 0,
+ 0,
+ OK,
+};
+
+const MockTransaction kBrotli_Slow_Transaction = {
+ "http://www.google.com/brotli", "GET", base::Time(), "", LOAD_NORMAL,
+ "HTTP/1.1 200 OK",
+ "Cache-Control: max-age=10000\n"
+ "Content-Encoding: br\n",
+ base::Time(), "", TEST_MODE_SLOW_READ, &BrotliHelloServer, nullptr, 0, 0,
+ OK,
+};
+
} // namespace
TEST(URLRequestJob, TransactionNotifiedWhenDone) {
@@ -187,4 +246,77 @@ TEST(URLRequestJob, TransactionNotCachedWhenNetworkDelegateRedirects) {
RemoveMockTransaction(&kGZip_Transaction);
}
+// Makes sure that ReadRawDataComplete correctly updates request status before
+// calling ReadFilteredData.
+// Regression test for crbug.com/553300.
+TEST(URLRequestJob, EmptyBodySkipFilter) {
+ MockNetworkLayer network_layer;
+ TestURLRequestContext context;
+ context.set_http_transaction_factory(&network_layer);
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ GURL(kEmptyBodyGzip_Transaction.url), DEFAULT_PRIORITY, &d));
+ AddMockTransaction(&kEmptyBodyGzip_Transaction);
+
+ req->set_method("GET");
+ req->Start();
+
+ base::MessageLoop::current()->Run();
+
+ EXPECT_FALSE(d.request_failed());
+ EXPECT_EQ(200, req->GetResponseCode());
+ EXPECT_TRUE(d.data_received().empty());
+ EXPECT_TRUE(network_layer.done_reading_called());
+
+ RemoveMockTransaction(&kEmptyBodyGzip_Transaction);
+}
+
+// Regression test for crbug.com/553300.
+TEST(URLRequestJob, SlowFilterRead) {
+ MockNetworkLayer network_layer;
+ TestURLRequestContext context;
+ context.set_http_transaction_factory(&network_layer);
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ GURL(kGzip_Slow_Transaction.url), DEFAULT_PRIORITY, &d));
+ AddMockTransaction(&kGzip_Slow_Transaction);
+
+ req->set_method("GET");
+ req->Start();
+
+ base::MessageLoop::current()->Run();
+
+ EXPECT_FALSE(d.request_failed());
+ EXPECT_EQ(200, req->GetResponseCode());
+ EXPECT_EQ("hello\n", d.data_received());
+ EXPECT_TRUE(network_layer.done_reading_called());
+
+ RemoveMockTransaction(&kGzip_Slow_Transaction);
+}
+
+TEST(URLRequestJob, SlowBrotliRead) {
+ MockNetworkLayer network_layer;
+ TestURLRequestContext context;
+ context.set_http_transaction_factory(&network_layer);
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ GURL(kBrotli_Slow_Transaction.url), DEFAULT_PRIORITY, &d));
+ AddMockTransaction(&kBrotli_Slow_Transaction);
+
+ req->set_method("GET");
+ req->Start();
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(d.request_failed());
+ EXPECT_EQ(200, req->GetResponseCode());
+ EXPECT_EQ(kBrotliDecodedHelloData, d.data_received());
+ EXPECT_TRUE(network_layer.done_reading_called());
+
+ RemoveMockTransaction(&kBrotli_Slow_Transaction);
+}
+
} // namespace net
diff --git a/chromium/net/url_request/url_request_netlog_params.cc b/chromium/net/url_request/url_request_netlog_params.cc
index 6573f2b04d1..f238b87e5cc 100644
--- a/chromium/net/url_request/url_request_netlog_params.cc
+++ b/chromium/net/url_request/url_request_netlog_params.cc
@@ -4,6 +4,8 @@
#include "net/url_request/url_request_netlog_params.h"
+#include <utility>
+
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "url/gurl.h"
@@ -15,7 +17,7 @@ scoped_ptr<base::Value> NetLogURLRequestStartCallback(
const std::string* method,
int load_flags,
RequestPriority priority,
- int64 upload_id,
+ int64_t upload_id,
NetLogCaptureMode /* capture_mode */) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("url", url->possibly_invalid_spec());
@@ -24,7 +26,7 @@ scoped_ptr<base::Value> NetLogURLRequestStartCallback(
dict->SetString("priority", RequestPriorityToString(priority));
if (upload_id > -1)
dict->SetString("upload_id", base::Int64ToString(upload_id));
- return dict.Pass();
+ return std::move(dict);
}
} // namespace net
diff --git a/chromium/net/url_request/url_request_netlog_params.h b/chromium/net/url_request/url_request_netlog_params.h
index 82c4aaa6da9..13dd2d1b638 100644
--- a/chromium/net/url_request/url_request_netlog_params.h
+++ b/chromium/net/url_request/url_request_netlog_params.h
@@ -5,6 +5,8 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_NETLOG_PARAMS_H_
#define NET_URL_REQUEST_URL_REQUEST_NETLOG_PARAMS_H_
+#include <stdint.h>
+
#include <string>
#include "net/base/net_export.h"
@@ -25,7 +27,7 @@ NET_EXPORT scoped_ptr<base::Value> NetLogURLRequestStartCallback(
const std::string* method,
int load_flags,
RequestPriority priority,
- int64 upload_id,
+ int64_t upload_id,
NetLogCaptureMode /* capture_mode */);
} // namespace net
diff --git a/chromium/net/url_request/url_request_redirect_job.cc b/chromium/net/url_request/url_request_redirect_job.cc
index 1dfb56dc083..5d3fbdb9386 100644
--- a/chromium/net/url_request/url_request_redirect_job.cc
+++ b/chromium/net/url_request/url_request_redirect_job.cc
@@ -36,6 +36,8 @@ URLRequestRedirectJob::URLRequestRedirectJob(URLRequest* request,
DCHECK(!redirect_reason_.empty());
}
+URLRequestRedirectJob::~URLRequestRedirectJob() {}
+
void URLRequestRedirectJob::GetResponseInfo(HttpResponseInfo* info) {
// Should only be called after the URLRequest has been notified there's header
// information.
@@ -83,8 +85,6 @@ int URLRequestRedirectJob::GetResponseCode() const {
return response_code_;
}
-URLRequestRedirectJob::~URLRequestRedirectJob() {}
-
void URLRequestRedirectJob::StartAsync() {
DCHECK(request_);
DCHECK(request_->status().is_success());
diff --git a/chromium/net/url_request/url_request_redirect_job.h b/chromium/net/url_request/url_request_redirect_job.h
index c84759fc0e1..a671844f942 100644
--- a/chromium/net/url_request/url_request_redirect_job.h
+++ b/chromium/net/url_request/url_request_redirect_job.h
@@ -41,6 +41,8 @@ class NET_EXPORT URLRequestRedirectJob : public URLRequestJob {
ResponseCode response_code,
const std::string& redirect_reason);
+ ~URLRequestRedirectJob() override;
+
// URLRequestJob implementation:
void GetResponseInfo(HttpResponseInfo* info) override;
void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
@@ -50,8 +52,6 @@ class NET_EXPORT URLRequestRedirectJob : public URLRequestJob {
int GetResponseCode() const override;
private:
- ~URLRequestRedirectJob() override;
-
void StartAsync();
const GURL redirect_destination_;
diff --git a/chromium/net/url_request/url_request_simple_job.cc b/chromium/net/url_request/url_request_simple_job.cc
index 2fdbef4049a..0f7104ffee4 100644
--- a/chromium/net/url_request/url_request_simple_job.cc
+++ b/chromium/net/url_request/url_request_simple_job.cc
@@ -26,7 +26,7 @@ namespace {
void CopyData(const scoped_refptr<IOBuffer>& buf,
int buf_size,
const scoped_refptr<base::RefCountedMemory>& data,
- int64 data_offset) {
+ int64_t data_offset) {
memcpy(buf->data(), data->front() + data_offset, buf_size);
}
@@ -65,32 +65,20 @@ bool URLRequestSimpleJob::GetCharset(std::string* charset) {
URLRequestSimpleJob::~URLRequestSimpleJob() {}
-bool URLRequestSimpleJob::ReadRawData(IOBuffer* buf, int buf_size,
- int* bytes_read) {
- DCHECK(bytes_read);
- buf_size = static_cast<int>(
- std::min(static_cast<int64>(buf_size),
- byte_range_.last_byte_position() - next_data_offset_ + 1));
- DCHECK_GE(buf_size, 0);
- if (buf_size == 0) {
- *bytes_read = 0;
- return true;
- }
+int URLRequestSimpleJob::ReadRawData(IOBuffer* buf, int buf_size) {
+ buf_size = std::min(static_cast<int64_t>(buf_size),
+ byte_range_.last_byte_position() - next_data_offset_ + 1);
+ if (buf_size == 0)
+ return 0;
// Do memory copy on a background thread. See crbug.com/422489.
GetTaskRunner()->PostTaskAndReply(
FROM_HERE, base::Bind(&CopyData, make_scoped_refptr(buf), buf_size, data_,
next_data_offset_),
- base::Bind(&URLRequestSimpleJob::OnReadCompleted,
+ base::Bind(&URLRequestSimpleJob::ReadRawDataComplete,
weak_factory_.GetWeakPtr(), buf_size));
next_data_offset_ += buf_size;
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- return false;
-}
-
-void URLRequestSimpleJob::OnReadCompleted(int bytes_read) {
- SetStatus(URLRequestStatus());
- NotifyReadComplete(bytes_read);
+ return ERR_IO_PENDING;
}
base::TaskRunner* URLRequestSimpleJob::GetTaskRunner() const {
@@ -121,8 +109,8 @@ void URLRequestSimpleJob::StartAsync() {
return;
if (ranges().size() > 1) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
- ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
+ ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
@@ -142,8 +130,8 @@ void URLRequestSimpleJob::OnGetDataCompleted(int result) {
if (result == OK) {
// Notify that the headers are complete
if (!byte_range_.ComputeBounds(data_->size())) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
- ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
+ ERR_REQUEST_RANGE_NOT_SATISFIABLE));
return;
}
diff --git a/chromium/net/url_request/url_request_simple_job.h b/chromium/net/url_request/url_request_simple_job.h
index 6c9d5e8b929..14f92a9a0b0 100644
--- a/chromium/net/url_request/url_request_simple_job.h
+++ b/chromium/net/url_request/url_request_simple_job.h
@@ -5,6 +5,8 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_SIMPLE_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_SIMPLE_JOB_H_
+#include <stdint.h>
+
#include <string>
#include "base/memory/ref_counted.h"
@@ -28,7 +30,7 @@ class NET_EXPORT URLRequestSimpleJob : public URLRangeRequestJob {
void Start() override;
void Kill() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
bool GetMimeType(std::string* mime_type) const override;
bool GetCharset(std::string* charset) override;
@@ -66,13 +68,12 @@ class NET_EXPORT URLRequestSimpleJob : public URLRangeRequestJob {
private:
void OnGetDataCompleted(int result);
- void OnReadCompleted(int bytes_read);
HttpByteRange byte_range_;
std::string mime_type_;
std::string charset_;
scoped_refptr<base::RefCountedMemory> data_;
- int64 next_data_offset_;
+ int64_t next_data_offset_;
scoped_refptr<base::TaskRunner> task_runner_;
base::WeakPtrFactory<URLRequestSimpleJob> weak_factory_;
};
diff --git a/chromium/net/url_request/url_request_simple_job_unittest.cc b/chromium/net/url_request/url_request_simple_job_unittest.cc
index 1286977b9cd..f123bedc499 100644
--- a/chromium/net/url_request/url_request_simple_job_unittest.cc
+++ b/chromium/net/url_request/url_request_simple_job_unittest.cc
@@ -3,10 +3,11 @@
// found in the LICENSE file.
#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/test/sequenced_worker_pool_owner.h"
#include "base/threading/worker_pool.h"
#include "net/base/request_priority.h"
#include "net/url_request/url_request_job.h"
@@ -114,11 +115,12 @@ class SimpleJobProtocolHandler :
class URLRequestSimpleJobTest : public ::testing::Test {
public:
URLRequestSimpleJobTest()
- : worker_pool_(
- new base::SequencedWorkerPool(1, "URLRequestSimpleJobTest")),
- task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
- worker_pool_->GetSequenceToken(),
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
+ : worker_pool_owner_(1, "URLRequestSimpleJobTest"),
+ task_runner_(worker_pool_owner_.pool()
+ ->GetSequencedTaskRunnerWithShutdownBehavior(
+ worker_pool_owner_.pool()
+ ->GetSequenceToken(),
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
context_(true) {
job_factory_.SetProtocolHandler(
"data", make_scoped_ptr(new SimpleJobProtocolHandler(task_runner_)));
@@ -129,8 +131,6 @@ class URLRequestSimpleJobTest : public ::testing::Test {
context_.CreateRequest(GURL("data:test"), DEFAULT_PRIORITY, &delegate_);
}
- ~URLRequestSimpleJobTest() override { worker_pool_->Shutdown(); }
-
void StartRequest(const HttpRequestHeaders* headers) {
if (headers)
request_->SetExtraRequestHeaders(*headers);
@@ -141,10 +141,8 @@ class URLRequestSimpleJobTest : public ::testing::Test {
EXPECT_FALSE(request_->is_pending());
}
- void TearDown() override { worker_pool_->Shutdown(); }
-
protected:
- scoped_refptr<base::SequencedWorkerPool> worker_pool_;
+ base::SequencedWorkerPoolOwner worker_pool_owner_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
TestURLRequestContext context_;
URLRequestJobFactoryImpl job_factory_;
diff --git a/chromium/net/url_request/url_request_status.cc b/chromium/net/url_request/url_request_status.cc
index 2a6a2fae861..7207df2fa52 100644
--- a/chromium/net/url_request/url_request_status.cc
+++ b/chromium/net/url_request/url_request_status.cc
@@ -46,4 +46,19 @@ URLRequestStatus URLRequestStatus::FromError(int error) {
}
}
+Error URLRequestStatus::ToNetError() const {
+ switch (status_) {
+ case SUCCESS:
+ return OK;
+ case IO_PENDING:
+ return ERR_IO_PENDING;
+ case CANCELED:
+ return ERR_ABORTED;
+ case FAILED:
+ return static_cast<Error>(error_);
+ }
+ NOTREACHED();
+ return ERR_FAILED;
+}
+
} // namespace net
diff --git a/chromium/net/url_request/url_request_status.h b/chromium/net/url_request/url_request_status.h
index 44a5d22bf04..694c51004cf 100644
--- a/chromium/net/url_request/url_request_status.h
+++ b/chromium/net/url_request/url_request_status.h
@@ -5,6 +5,7 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_STATUS_H_
#define NET_URL_REQUEST_URL_REQUEST_STATUS_H_
+#include "net/base/net_errors.h"
#include "net/base/net_export.h"
namespace net {
@@ -41,6 +42,13 @@ class NET_EXPORT URLRequestStatus {
// deprecated. See https://crbug.com/490311.
static URLRequestStatus FromError(int error);
+ // Returns a Error corresponding to |status_|.
+ // OK for OK
+ // ERR_IO_PENDING for IO_PENDING
+ // ERR_ABORTED for CANCELLED
+ // Error for FAILED
+ Error ToNetError() const;
+
Status status() const { return status_; }
int error() const { return error_; }
diff --git a/chromium/net/url_request/url_request_test_job.cc b/chromium/net/url_request/url_request_test_job.cc
index 7530d42bb7a..bd1c9052baa 100644
--- a/chromium/net/url_request/url_request_test_job.cc
+++ b/chromium/net/url_request/url_request_test_job.cc
@@ -17,6 +17,7 @@
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
namespace net {
@@ -75,37 +76,37 @@ std::string URLRequestTestJob::test_data_4() {
// static getter for simple response headers
std::string URLRequestTestJob::test_headers() {
static const char kHeaders[] =
- "HTTP/1.1 200 OK\0"
- "Content-type: text/html\0"
- "\0";
+ "HTTP/1.1 200 OK\n"
+ "Content-type: text/html\n"
+ "\n";
return std::string(kHeaders, arraysize(kHeaders));
}
// static getter for redirect response headers
std::string URLRequestTestJob::test_redirect_headers() {
static const char kHeaders[] =
- "HTTP/1.1 302 MOVED\0"
- "Location: somewhere\0"
- "\0";
+ "HTTP/1.1 302 MOVED\n"
+ "Location: somewhere\n"
+ "\n";
return std::string(kHeaders, arraysize(kHeaders));
}
// static getter for redirect response headers
std::string URLRequestTestJob::test_redirect_to_url_2_headers() {
std::string headers = "HTTP/1.1 302 MOVED";
- headers.push_back('\0');
+ headers.push_back('\n');
headers += "Location: ";
headers += test_url_2().spec();
- headers.push_back('\0');
- headers.push_back('\0');
+ headers.push_back('\n');
+ headers.push_back('\n');
return headers;
}
// static getter for error response headers
std::string URLRequestTestJob::test_error_headers() {
static const char kHeaders[] =
- "HTTP/1.1 500 BOO HOO\0"
- "\0";
+ "HTTP/1.1 500 BOO HOO\n"
+ "\n";
return std::string(kHeaders, arraysize(kHeaders));
}
@@ -149,13 +150,14 @@ URLRequestTestJob::URLRequestTestJob(URLRequest* request,
auto_advance_(auto_advance),
stage_(WAITING),
priority_(DEFAULT_PRIORITY),
- response_headers_(new HttpResponseHeaders(response_headers)),
+ response_headers_(new net::HttpResponseHeaders(
+ net::HttpUtil::AssembleRawHeaders(response_headers.c_str(),
+ response_headers.size()))),
response_data_(response_data),
offset_(0),
async_buf_(NULL),
async_buf_size_(0),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
URLRequestTestJob::~URLRequestTestJob() {
g_pending_jobs.Get().erase(
@@ -185,7 +187,9 @@ void URLRequestTestJob::Start() {
void URLRequestTestJob::StartAsync() {
if (!response_headers_.get()) {
- response_headers_ = new HttpResponseHeaders(test_headers());
+ std::string headers = test_headers();
+ response_headers_ = new HttpResponseHeaders(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
if (request_->url().spec() == test_url_1().spec()) {
response_data_ = test_data_1();
stage_ = DATA_AVAILABLE; // Simulate a synchronous response for this one.
@@ -196,16 +200,18 @@ void URLRequestTestJob::StartAsync() {
} else if (request_->url().spec() == test_url_4().spec()) {
response_data_ = test_data_4();
} else if (request_->url().spec() == test_url_redirect_to_url_2().spec()) {
+ std::string redirect_headers = test_redirect_to_url_2_headers();
response_headers_ =
- new HttpResponseHeaders(test_redirect_to_url_2_headers());
+ new HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
+ redirect_headers.c_str(), redirect_headers.size()));
} else {
AdvanceJob();
// unexpected url, return error
// FIXME(brettw) we may want to use WININET errors or have some more types
// of errors
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
- ERR_INVALID_URL));
+ NotifyStartError(
+ URLRequestStatus(URLRequestStatus::FAILED, ERR_INVALID_URL));
// FIXME(brettw): this should emulate a network error, and not just fail
// initiating a connection
return;
@@ -217,21 +223,15 @@ void URLRequestTestJob::StartAsync() {
this->NotifyHeadersComplete();
}
-bool URLRequestTestJob::ReadRawData(IOBuffer* buf, int buf_size,
- int *bytes_read) {
+int URLRequestTestJob::ReadRawData(IOBuffer* buf, int buf_size) {
if (stage_ == WAITING) {
async_buf_ = buf;
async_buf_size_ = buf_size;
- SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
- return false;
+ return ERR_IO_PENDING;
}
- DCHECK(bytes_read);
- *bytes_read = 0;
-
- if (offset_ >= static_cast<int>(response_data_.length())) {
- return true; // done reading
- }
+ if (offset_ >= static_cast<int>(response_data_.length()))
+ return 0; // done reading
int to_read = buf_size;
if (to_read + offset_ > static_cast<int>(response_data_.length()))
@@ -240,8 +240,7 @@ bool URLRequestTestJob::ReadRawData(IOBuffer* buf, int buf_size,
memcpy(buf->data(), &response_data_.c_str()[offset_], to_read);
offset_ += to_read;
- *bytes_read = to_read;
- return true;
+ return to_read;
}
void URLRequestTestJob::GetResponseInfo(HttpResponseInfo* info) {
@@ -299,16 +298,15 @@ void URLRequestTestJob::ProcessNextOperation() {
stage_ = DATA_AVAILABLE;
// OK if ReadRawData wasn't called yet.
if (async_buf_) {
- int bytes_read;
- if (!ReadRawData(async_buf_, async_buf_size_, &bytes_read))
- NOTREACHED() << "This should not return false in DATA_AVAILABLE.";
- SetStatus(URLRequestStatus()); // clear the io pending flag
+ int result = ReadRawData(async_buf_, async_buf_size_);
+ if (result < 0)
+ NOTREACHED() << "Reads should not fail in DATA_AVAILABLE.";
if (NextReadAsync()) {
// Make all future reads return io pending until the next
// ProcessNextOperation().
stage_ = WAITING;
}
- NotifyReadComplete(bytes_read);
+ ReadRawDataComplete(result);
}
break;
case DATA_AVAILABLE:
diff --git a/chromium/net/url_request/url_request_test_job.h b/chromium/net/url_request/url_request_test_job.h
index db88fb819d0..e733d1c9be9 100644
--- a/chromium/net/url_request/url_request_test_job.h
+++ b/chromium/net/url_request/url_request_test_job.h
@@ -22,7 +22,7 @@ namespace net {
// It will respond to several URLs, which you can retrieve using the test_url*
// getters, which will in turn respond with the corresponding responses returned
// by test_data*. Any other URLs that begin with "test:" will return an error,
-// which might also be useful, you can use test_url_error() to retreive a
+// which might also be useful, you can use test_url_error() to retrieve a
// standard one.
//
// You can override the known URLs or the response data by overriding Start().
@@ -50,14 +50,16 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
bool auto_advance);
// Constructs a job to return the given response regardless of the request
- // url. The headers should include the HTTP status line and be formatted as
- // expected by HttpResponseHeaders.
+ // url. The headers should include the HTTP status line and use CRLF/LF as the
+ // line separator.
URLRequestTestJob(URLRequest* request,
NetworkDelegate* network_delegate,
const std::string& response_headers,
const std::string& response_data,
bool auto_advance);
+ ~URLRequestTestJob() override;
+
// The canned URLs this handler will respond to without having been
// explicitly initialized with response headers and data.
// FIXME(brettw): we should probably also have a redirect one
@@ -111,7 +113,7 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
// Job functions
void SetPriority(RequestPriority priority) override;
void Start() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int ReadRawData(IOBuffer* buf, int buf_size) override;
void Kill() override;
bool GetMimeType(std::string* mime_type) const override;
void GetResponseInfo(HttpResponseInfo* info) override;
@@ -130,8 +132,6 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
// When the stage is DONE, this job will not be put on the queue.
enum Stage { WAITING, DATA_AVAILABLE, ALL_DATA, DONE };
- ~URLRequestTestJob() override;
-
// Call to process the next opeation, usually sending a notification, and
// advancing the stage if necessary. THIS MAY DELETE THE OBJECT.
void ProcessNextOperation();
diff --git a/chromium/net/url_request/url_request_test_util.cc b/chromium/net/url_request/url_request_test_util.cc
index efcc759ba65..b3c03c71164 100644
--- a/chromium/net/url_request/url_request_test_util.cc
+++ b/chromium/net/url_request/url_request_test_util.cc
@@ -4,6 +4,8 @@
#include "net/url_request/url_request_test_util.h"
+#include <utility>
+
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
@@ -22,6 +24,7 @@
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
#include "net/url_request/static_http_user_agent_settings.h"
+#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -108,10 +111,11 @@ void TestURLRequestContext::Init() {
params.network_delegate = network_delegate();
params.http_server_properties = http_server_properties();
params.net_log = net_log();
- context_storage_.set_http_transaction_factory(
- make_scoped_ptr(new HttpCache(new HttpNetworkSession(params),
- HttpCache::DefaultBackend::InMemory(0)))
- .Pass());
+ context_storage_.set_http_network_session(
+ make_scoped_ptr(new HttpNetworkSession(params)));
+ context_storage_.set_http_transaction_factory(make_scoped_ptr(
+ new HttpCache(context_storage_.http_network_session(),
+ HttpCache::DefaultBackend::InMemory(0), false)));
}
// In-memory cookie store.
if (!cookie_store())
@@ -141,7 +145,7 @@ TestURLRequestContextGetter::TestURLRequestContextGetter(
TestURLRequestContextGetter::TestURLRequestContextGetter(
const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner,
scoped_ptr<TestURLRequestContext> context)
- : network_task_runner_(network_task_runner), context_(context.Pass()) {
+ : network_task_runner_(network_task_runner), context_(std::move(context)) {
DCHECK(network_task_runner_.get());
}
@@ -200,7 +204,7 @@ void TestDelegate::OnReceivedRedirect(URLRequest* request,
if (quit_on_redirect_) {
*defer_redirect = true;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
} else if (cancel_in_rr_) {
request->Cancel();
}
@@ -211,7 +215,7 @@ void TestDelegate::OnBeforeNetworkStart(URLRequest* request, bool* defer) {
if (quit_on_before_network_start_) {
*defer = true;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
}
@@ -220,7 +224,7 @@ void TestDelegate::OnAuthRequired(URLRequest* request,
auth_required_ = true;
if (quit_on_auth_required_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
return;
}
if (!credentials_.Empty()) {
@@ -275,6 +279,11 @@ void TestDelegate::OnReadCompleted(URLRequest* request, int bytes_read) {
// It doesn't make sense for the request to have IO pending at this point.
DCHECK(!request->status().is_io_pending());
+ // If the request was cancelled in a redirect, it should not signal
+ // OnReadCompleted. Note that |cancel_in_rs_| may be true due to
+ // https://crbug.com/564848.
+ EXPECT_FALSE(cancel_in_rr_);
+
if (response_started_count_ == 0)
received_data_before_response_ = true;
@@ -310,7 +319,7 @@ void TestDelegate::OnReadCompleted(URLRequest* request, int bytes_read) {
void TestDelegate::OnResponseCompleted(URLRequest* request) {
if (quit_on_complete_)
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
TestNetworkDelegate::TestNetworkDelegate()
@@ -332,7 +341,7 @@ TestNetworkDelegate::TestNetworkDelegate()
has_load_timing_info_before_redirect_(false),
has_load_timing_info_before_auth_(false),
can_access_files_(true),
- first_party_only_cookies_enabled_(false),
+ experimental_cookie_features_enabled_(false),
cancel_request_with_policy_violating_referrer_(false),
will_be_intercepted_on_next_error_(false) {}
@@ -505,15 +514,15 @@ void TestNetworkDelegate::OnResponseStarted(URLRequest* request) {
}
}
-void TestNetworkDelegate::OnNetworkBytesReceived(const URLRequest& request,
+void TestNetworkDelegate::OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) {
- event_order_[request.identifier()] += "OnNetworkBytesReceived\n";
+ event_order_[request->identifier()] += "OnNetworkBytesReceived\n";
total_network_bytes_received_ += bytes_received;
}
-void TestNetworkDelegate::OnNetworkBytesSent(const URLRequest& request,
+void TestNetworkDelegate::OnNetworkBytesSent(URLRequest* request,
int64_t bytes_sent) {
- event_order_[request.identifier()] += "OnNetworkBytesSent\n";
+ event_order_[request->identifier()] += "OnNetworkBytesSent\n";
total_network_bytes_sent_ += bytes_sent;
}
@@ -616,8 +625,12 @@ bool TestNetworkDelegate::OnCanAccessFile(const URLRequest& request,
return can_access_files_;
}
-bool TestNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const {
- return first_party_only_cookies_enabled_;
+bool TestNetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
+ return experimental_cookie_features_enabled_;
+}
+
+bool TestNetworkDelegate::OnAreStrictSecureCookiesEnabled() const {
+ return experimental_cookie_features_enabled_;
}
bool TestNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
@@ -627,19 +640,18 @@ bool TestNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
return cancel_request_with_policy_violating_referrer_;
}
-TestJobInterceptor::TestJobInterceptor() : main_intercept_job_(NULL) {
-}
+TestJobInterceptor::TestJobInterceptor() {}
+
+TestJobInterceptor::~TestJobInterceptor() {}
URLRequestJob* TestJobInterceptor::MaybeCreateJob(
URLRequest* request,
NetworkDelegate* network_delegate) const {
- URLRequestJob* job = main_intercept_job_;
- main_intercept_job_ = NULL;
- return job;
+ return main_intercept_job_.release();
}
-void TestJobInterceptor::set_main_intercept_job(URLRequestJob* job) {
- main_intercept_job_ = job;
+void TestJobInterceptor::set_main_intercept_job(scoped_ptr<URLRequestJob> job) {
+ main_intercept_job_ = std::move(job);
}
} // namespace net
diff --git a/chromium/net/url_request/url_request_test_util.h b/chromium/net/url_request/url_request_test_util.h
index 09d44df254d..1a829d5c12c 100644
--- a/chromium/net/url_request/url_request_test_util.h
+++ b/chromium/net/url_request/url_request_test_util.h
@@ -7,11 +7,10 @@
#include <stdint.h>
#include <stdlib.h>
-
#include <map>
#include <string>
+#include <utility>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -72,11 +71,11 @@ class TestURLRequestContext : public URLRequestContext {
void set_http_network_session_params(
scoped_ptr<HttpNetworkSession::Params> params) {
- http_network_session_params_ = params.Pass();
+ http_network_session_params_ = std::move(params);
}
void SetSdchManager(scoped_ptr<SdchManager> sdch_manager) {
- context_storage_.set_sdch_manager(sdch_manager.Pass());
+ context_storage_.set_sdch_manager(std::move(sdch_manager));
}
private:
@@ -273,8 +272,8 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
void set_can_access_files(bool val) { can_access_files_ = val; }
bool can_access_files() const { return can_access_files_; }
- void set_first_party_only_cookies_enabled(bool val) {
- first_party_only_cookies_enabled_ = val;
+ void set_experimental_cookie_features_enabled(bool val) {
+ experimental_cookie_features_enabled_ = val;
}
void set_cancel_request_with_policy_violating_referrer(bool val) {
@@ -321,10 +320,9 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
GURL* allowed_unsafe_redirect_url) override;
void OnBeforeRedirect(URLRequest* request, const GURL& new_location) override;
void OnResponseStarted(URLRequest* request) override;
- void OnNetworkBytesReceived(const URLRequest& request,
+ void OnNetworkBytesReceived(URLRequest* request,
int64_t bytes_received) override;
- void OnNetworkBytesSent(const URLRequest& request,
- int64_t bytes_sent) override;
+ void OnNetworkBytesSent(URLRequest* request, int64_t bytes_sent) override;
void OnCompleted(URLRequest* request, bool started) override;
void OnURLRequestDestroyed(URLRequest* request) override;
void OnPACScriptError(int line_number, const base::string16& error) override;
@@ -340,7 +338,8 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
CookieOptions* options) override;
bool OnCanAccessFile(const URLRequest& request,
const base::FilePath& path) const override;
- bool OnFirstPartyOnlyCookieExperimentEnabled() const override;
+ bool OnAreExperimentalCookieFeaturesEnabled() const override;
+ bool OnAreStrictSecureCookiesEnabled() const override;
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const URLRequest& request,
const GURL& target_url,
@@ -387,7 +386,7 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
bool has_load_timing_info_before_auth_;
bool can_access_files_; // true by default
- bool first_party_only_cookies_enabled_; // false by default
+ bool experimental_cookie_features_enabled_; // false by default
bool cancel_request_with_policy_violating_referrer_; // false by default
bool will_be_intercepted_on_next_error_;
};
@@ -398,14 +397,15 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
class TestJobInterceptor : public URLRequestJobFactory::ProtocolHandler {
public:
TestJobInterceptor();
+ ~TestJobInterceptor() override;
URLRequestJob* MaybeCreateJob(
URLRequest* request,
NetworkDelegate* network_delegate) const override;
- void set_main_intercept_job(URLRequestJob* job);
+ void set_main_intercept_job(scoped_ptr<URLRequestJob> job);
private:
- mutable URLRequestJob* main_intercept_job_;
+ mutable scoped_ptr<URLRequestJob> main_intercept_job_;
};
} // namespace net
diff --git a/chromium/net/url_request/url_request_throttler_entry.cc b/chromium/net/url_request/url_request_throttler_entry.cc
index 8b7aa79a123..7c85edc10d7 100644
--- a/chromium/net/url_request/url_request_throttler_entry.cc
+++ b/chromium/net/url_request/url_request_throttler_entry.cc
@@ -5,6 +5,7 @@
#include "net/url_request/url_request_throttler_entry.h"
#include <cmath>
+#include <utility>
#include "base/logging.h"
#include "base/metrics/field_trial.h"
@@ -57,7 +58,7 @@ scoped_ptr<base::Value> NetLogRejectedRequestCallback(
dict->SetInteger("num_failures", num_failures);
dict->SetInteger("release_after_ms",
static_cast<int>(release_after.InMilliseconds()));
- return dict.Pass();
+ return std::move(dict);
}
URLRequestThrottlerEntry::URLRequestThrottlerEntry(
@@ -167,7 +168,7 @@ bool URLRequestThrottlerEntry::ShouldRejectRequest(
return reject_request;
}
-int64 URLRequestThrottlerEntry::ReserveSendingTimeForNextRequest(
+int64_t URLRequestThrottlerEntry::ReserveSendingTimeForNextRequest(
const base::TimeTicks& earliest_time) {
base::TimeTicks now = ImplGetTimeNow();
diff --git a/chromium/net/url_request/url_request_throttler_entry.h b/chromium/net/url_request/url_request_throttler_entry.h
index 264766a22a4..bd64c26ed45 100644
--- a/chromium/net/url_request/url_request_throttler_entry.h
+++ b/chromium/net/url_request/url_request_throttler_entry.h
@@ -5,10 +5,12 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_
#define NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_H_
+#include <stdint.h>
+
#include <queue>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/time/time.h"
#include "net/base/backoff_entry.h"
#include "net/log/net_log.h"
@@ -86,7 +88,7 @@ class NET_EXPORT URLRequestThrottlerEntry
// Implementation of URLRequestThrottlerEntryInterface.
bool ShouldRejectRequest(const URLRequest& request) const override;
- int64 ReserveSendingTimeForNextRequest(
+ int64_t ReserveSendingTimeForNextRequest(
const base::TimeTicks& earliest_time) override;
base::TimeTicks GetExponentialBackoffReleaseTime() const override;
void UpdateWithResponse(int status_code) override;
diff --git a/chromium/net/url_request/url_request_throttler_entry_interface.h b/chromium/net/url_request/url_request_throttler_entry_interface.h
index f08d352d1f7..44a56124791 100644
--- a/chromium/net/url_request/url_request_throttler_entry_interface.h
+++ b/chromium/net/url_request/url_request_throttler_entry_interface.h
@@ -5,9 +5,11 @@
#ifndef NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_INTERFACE_H_
#define NET_URL_REQUEST_URL_REQUEST_THROTTLER_ENTRY_INTERFACE_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
@@ -41,7 +43,7 @@ class NET_EXPORT URLRequestThrottlerEntryInterface
// milliseconds. The return value is always positive or 0.
// Although it is not mandatory, respecting the value returned by this method
// is helpful to avoid traffic overload.
- virtual int64 ReserveSendingTimeForNextRequest(
+ virtual int64_t ReserveSendingTimeForNextRequest(
const base::TimeTicks& earliest_time) = 0;
// Returns the time after which requests are allowed.
diff --git a/chromium/net/url_request/url_request_throttler_manager.h b/chromium/net/url_request/url_request_throttler_manager.h
index dbc48ac0061..855ef931d9b 100644
--- a/chromium/net/url_request/url_request_throttler_manager.h
+++ b/chromium/net/url_request/url_request_throttler_manager.h
@@ -9,7 +9,7 @@
#include <set>
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/non_thread_safe.h"
#include "base/threading/platform_thread.h"
diff --git a/chromium/net/url_request/url_request_throttler_simulation_unittest.cc b/chromium/net/url_request/url_request_throttler_simulation_unittest.cc
index 808c6b5c168..d5ef39a13fc 100644
--- a/chromium/net/url_request/url_request_throttler_simulation_unittest.cc
+++ b/chromium/net/url_request/url_request_throttler_simulation_unittest.cc
@@ -17,8 +17,8 @@
#include <vector>
#include "base/environment.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/rand_util.h"
#include "base/time/time.h"
#include "net/base/request_priority.h"
@@ -489,7 +489,7 @@ void SimulateAttack(Server* server,
const size_t kNumClients = 50;
DiscreteTimeSimulation simulation;
URLRequestThrottlerManager manager;
- ScopedVector<Requester> requesters;
+ std::vector<scoped_ptr<Requester>> requesters;
for (size_t i = 0; i < kNumAttackers; ++i) {
// Use a tiny time_between_requests so the attackers will ping the
// server at every tick of the simulation.
@@ -498,13 +498,12 @@ void SimulateAttack(Server* server,
if (!enable_throttling)
throttler_entry->DisableBackoffThrottling();
- Requester* attacker = new Requester(throttler_entry.get(),
- TimeDelta::FromMilliseconds(1),
- server,
- attacker_results);
+ scoped_ptr<Requester> attacker(new Requester(throttler_entry.get(),
+ TimeDelta::FromMilliseconds(1),
+ server, attacker_results));
attacker->SetStartupJitter(TimeDelta::FromSeconds(120));
- requesters.push_back(attacker);
- simulation.AddActor(attacker);
+ simulation.AddActor(attacker.get());
+ requesters.push_back(std::move(attacker));
}
for (size_t i = 0; i < kNumClients; ++i) {
// Normal clients only make requests every 2 minutes, plus/minus 1 minute.
@@ -513,14 +512,13 @@ void SimulateAttack(Server* server,
if (!enable_throttling)
throttler_entry->DisableBackoffThrottling();
- Requester* client = new Requester(throttler_entry.get(),
- TimeDelta::FromMinutes(2),
- server,
- client_results);
+ scoped_ptr<Requester> client(new Requester(throttler_entry.get(),
+ TimeDelta::FromMinutes(2),
+ server, client_results));
client->SetStartupJitter(TimeDelta::FromSeconds(120));
client->SetRequestJitter(TimeDelta::FromMinutes(1));
- requesters.push_back(client);
- simulation.AddActor(client);
+ simulation.AddActor(client.get());
+ requesters.push_back(std::move(client));
}
simulation.AddActor(server);
diff --git a/chromium/net/url_request/url_request_unittest.cc b/chromium/net/url_request/url_request_unittest.cc
index 87ad8ebe878..b1bf6189c02 100644
--- a/chromium/net/url_request/url_request_unittest.cc
+++ b/chromium/net/url_request/url_request_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "build/build_config.h"
#if defined(OS_WIN)
@@ -12,8 +14,8 @@
#include <stdint.h>
#include <algorithm>
+#include <limits>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
@@ -22,6 +24,7 @@
#include "base/format_macros.h"
#include "base/json/json_reader.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -40,6 +43,7 @@
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "net/base/chunked_upload_data_stream.h"
+#include "net/base/directory_listing.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/external_estimate_provider.h"
#include "net/base/load_flags.h"
@@ -77,7 +81,11 @@
#include "net/socket/ssl_client_socket.h"
#include "net/ssl/ssl_cipher_suite_names.h"
#include "net/ssl/ssl_connection_status_flags.h"
+#include "net/ssl/ssl_server_config.h"
#include "net/test/cert_test_util.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/url_request/data_protocol_handler.h"
@@ -222,7 +230,6 @@ void FillBuffer(char* buffer, size_t len) {
}
#endif
-#if !defined(OS_IOS)
void TestLoadTimingCacheHitNoNetwork(
const LoadTimingInfo& load_timing_info) {
EXPECT_FALSE(load_timing_info.socket_reused);
@@ -279,6 +286,27 @@ class TestPowerMonitorSource : public base::PowerMonitorSource {
DISALLOW_COPY_AND_ASSIGN(TestPowerMonitorSource);
};
+// Job that allows monitoring of its priority.
+class PriorityMonitoringURLRequestJob : public URLRequestTestJob {
+ public:
+ // The latest priority of the job is always written to |request_priority_|.
+ PriorityMonitoringURLRequestJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ RequestPriority* request_priority)
+ : URLRequestTestJob(request, network_delegate),
+ request_priority_(request_priority) {
+ *request_priority_ = DEFAULT_PRIORITY;
+ }
+
+ void SetPriority(RequestPriority priority) override {
+ *request_priority_ = priority;
+ URLRequestTestJob::SetPriority(priority);
+ }
+
+ private:
+ RequestPriority* const request_priority_;
+};
+
// Do a case-insensitive search through |haystack| for |needle|.
bool ContainsString(const std::string& haystack, const char* needle) {
std::string::const_iterator it = std::search(
@@ -290,7 +318,7 @@ bool ContainsString(const std::string& haystack, const char* needle) {
scoped_ptr<UploadDataStream> CreateSimpleUploadData(const char* data) {
scoped_ptr<UploadElementReader> reader(
new UploadBytesElementReader(data, strlen(data)));
- return ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0);
+ return ElementsUploadDataStream::CreateWithReader(std::move(reader), 0);
}
// Verify that the SSLInfo of a successful SSL connection has valid values.
@@ -299,8 +327,8 @@ void CheckSSLInfo(const SSLInfo& ssl_info) {
EXPECT_GT(ssl_info.security_bits, 0);
// The cipher suite TLS_NULL_WITH_NULL_NULL (0) must not be negotiated.
- uint16 cipher_suite = SSLConnectionStatusToCipherSuite(
- ssl_info.connection_status);
+ uint16_t cipher_suite =
+ SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
EXPECT_NE(0U, cipher_suite);
}
@@ -315,6 +343,7 @@ void CheckFullRequestHeaders(const HttpRequestHeaders& headers,
EXPECT_EQ("keep-alive", sent_value);
}
+#if !defined(OS_IOS)
bool FingerprintsEqual(const HashValueVector& a, const HashValueVector& b) {
size_t size = a.size();
@@ -582,7 +611,7 @@ NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired(
auth_callback_ = callback;
stage_blocked_for_callback_ = ON_AUTH_REQUIRED;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
return AUTH_REQUIRED_RESPONSE_IO_PENDING;
}
NOTREACHED();
@@ -621,7 +650,7 @@ int BlockingNetworkDelegate::MaybeBlockStage(
callback_ = callback;
stage_blocked_for_callback_ = stage;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::MessageLoop::QuitClosure());
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
return ERR_IO_PENDING;
}
NOTREACHED();
@@ -662,6 +691,12 @@ class MockCertificateReportSender
std::string latest_report_;
};
+class TestExperimentalFeaturesNetworkDelegate : public TestNetworkDelegate {
+ public:
+ bool OnAreExperimentalCookieFeaturesEnabled() const override { return true; }
+ bool OnAreStrictSecureCookiesEnabled() const override { return true; }
+};
+
} // namespace
// Inherit PlatformTest since we require the autorelease pool on Mac OS X.
@@ -804,7 +839,7 @@ TEST_F(URLRequestTest, FileTest) {
base::RunLoop().Run();
- int64 file_size = -1;
+ int64_t file_size = -1;
EXPECT_TRUE(base::GetFileSize(app_path, &file_size));
EXPECT_TRUE(!r->is_pending());
@@ -848,7 +883,7 @@ TEST_F(URLRequestTest, FileTestFullSpecifiedRange) {
GURL temp_url = FilePathToFileURL(temp_path);
EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));
- int64 file_size;
+ int64_t file_size;
EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));
const size_t first_byte_position = 500;
@@ -893,7 +928,7 @@ TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) {
GURL temp_url = FilePathToFileURL(temp_path);
EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));
- int64 file_size;
+ int64_t file_size;
EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));
const size_t first_byte_position = 500;
@@ -937,7 +972,7 @@ TEST_F(URLRequestTest, FileTestMultipleRanges) {
GURL temp_url = FilePathToFileURL(temp_path);
EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));
- int64 file_size;
+ int64_t file_size;
EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));
TestDelegate d;
@@ -1514,7 +1549,7 @@ class URLRequestInterceptorTest : public URLRequestTest {
void SetUpFactory() override {
interceptor_ = new MockURLRequestInterceptor();
job_factory_.reset(new URLRequestInterceptingJobFactory(
- job_factory_.Pass(), make_scoped_ptr(interceptor_)));
+ std::move(job_factory_), make_scoped_ptr(interceptor_)));
}
MockURLRequestInterceptor* interceptor() const {
@@ -2064,9 +2099,14 @@ TEST_F(URLRequestTest, Identifiers) {
ASSERT_NE(req->identifier(), other_req->identifier());
}
-// Check that a failure to connect to the proxy is reported to the network
-// delegate.
-TEST_F(URLRequestTest, NetworkDelegateProxyError) {
+#if defined(OS_IOS)
+// TODO(droger): Check that a failure to connect to the proxy is reported to
+// the network delegate. crbug.com/496743
+#define MAYBE_NetworkDelegateProxyError DISABLED_NetworkDelegateProxyError
+#else
+#define MAYBE_NetworkDelegateProxyError NetworkDelegateProxyError
+#endif
+TEST_F(URLRequestTest, MAYBE_NetworkDelegateProxyError) {
MockHostResolver host_resolver;
host_resolver.rules()->AddSimulatedFailure("*");
@@ -2131,15 +2171,16 @@ TEST_F(URLRequestTest, SetJobPriorityBeforeJobStart) {
GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
EXPECT_EQ(DEFAULT_PRIORITY, req->priority());
- scoped_refptr<URLRequestTestJob> job =
- new URLRequestTestJob(req.get(), &default_network_delegate_);
- AddTestInterceptor()->set_main_intercept_job(job.get());
- EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
+ RequestPriority job_priority;
+ scoped_ptr<URLRequestJob> job(new PriorityMonitoringURLRequestJob(
+ req.get(), &default_network_delegate_, &job_priority));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
+ EXPECT_EQ(DEFAULT_PRIORITY, job_priority);
req->SetPriority(LOW);
req->Start();
- EXPECT_EQ(LOW, job->priority());
+ EXPECT_EQ(LOW, job_priority);
}
// Make sure that URLRequest passes on its priority updates to its
@@ -2149,17 +2190,18 @@ TEST_F(URLRequestTest, SetJobPriority) {
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
- scoped_refptr<URLRequestTestJob> job =
- new URLRequestTestJob(req.get(), &default_network_delegate_);
- AddTestInterceptor()->set_main_intercept_job(job.get());
+ RequestPriority job_priority;
+ scoped_ptr<URLRequestJob> job(new PriorityMonitoringURLRequestJob(
+ req.get(), &default_network_delegate_, &job_priority));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
req->SetPriority(LOW);
req->Start();
- EXPECT_EQ(LOW, job->priority());
+ EXPECT_EQ(LOW, job_priority);
req->SetPriority(MEDIUM);
EXPECT_EQ(MEDIUM, req->priority());
- EXPECT_EQ(MEDIUM, job->priority());
+ EXPECT_EQ(MEDIUM, job_priority);
}
// Setting the IGNORE_LIMITS load flag should be okay if the priority
@@ -2170,9 +2212,10 @@ TEST_F(URLRequestTest, PriorityIgnoreLimits) {
GURL("http://test_intercept/foo"), MAXIMUM_PRIORITY, &d));
EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
- scoped_refptr<URLRequestTestJob> job =
- new URLRequestTestJob(req.get(), &default_network_delegate_);
- AddTestInterceptor()->set_main_intercept_job(job.get());
+ RequestPriority job_priority;
+ scoped_ptr<URLRequestJob> job(new PriorityMonitoringURLRequestJob(
+ req.get(), &default_network_delegate_, &job_priority));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
req->SetLoadFlags(LOAD_IGNORE_LIMITS);
EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
@@ -2182,24 +2225,19 @@ TEST_F(URLRequestTest, PriorityIgnoreLimits) {
req->Start();
EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
- EXPECT_EQ(MAXIMUM_PRIORITY, job->priority());
+ EXPECT_EQ(MAXIMUM_PRIORITY, job_priority);
}
-// TODO(droger): Support SpawnedTestServer on iOS (see http://crbug.com/148666).
-#if !defined(OS_IOS)
namespace {
// Less verbose way of running a simple testserver for the tests below.
-class LocalHttpTestServer : public SpawnedTestServer {
+class LocalHttpTestServer : public EmbeddedTestServer {
public:
- explicit LocalHttpTestServer(const base::FilePath& document_root)
- : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- document_root) {}
- LocalHttpTestServer()
- : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath()) {}
+ explicit LocalHttpTestServer(const base::FilePath& document_root) {
+ AddDefaultHandlers(document_root);
+ }
+
+ LocalHttpTestServer() { AddDefaultHandlers(base::FilePath()); }
};
} // namespace
@@ -2220,7 +2258,7 @@ TEST_F(URLRequestTest, DelayedCookieCallback) {
context.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(context.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
+ test_server.GetURL("/set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -2235,7 +2273,7 @@ TEST_F(URLRequestTest, DelayedCookieCallback) {
context.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(context.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2256,7 +2294,7 @@ TEST_F(URLRequestTest, DoNotSendCookies) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
+ test_server.GetURL("/set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -2270,7 +2308,7 @@ TEST_F(URLRequestTest, DoNotSendCookies) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2286,7 +2324,7 @@ TEST_F(URLRequestTest, DoNotSendCookies) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES);
req->Start();
base::RunLoop().Run();
@@ -2310,7 +2348,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
+ test_server.GetURL("/set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -2326,7 +2364,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
+ test_server.GetURL("/set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
DEFAULT_PRIORITY, &d));
req->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES);
req->Start();
@@ -2345,7 +2383,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2370,7 +2408,7 @@ TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
+ test_server.GetURL("/set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -2385,7 +2423,7 @@ TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2403,7 +2441,7 @@ TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
TestDelegate d;
network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES);
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2415,6 +2453,12 @@ TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
}
}
+// TODO(crbug.com/564656) This test is flaky on iOS.
+#if defined(OS_IOS)
+#define MAYBE_DoNotSaveCookies_ViaPolicy FLAKY_DoNotSaveCookies_ViaPolicy
+#else
+#define MAYBE_DoNotSaveCookies_ViaPolicy DoNotSaveCookies_ViaPolicy
+#endif
TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
LocalHttpTestServer test_server;
ASSERT_TRUE(test_server.Start());
@@ -2425,7 +2469,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
+ test_server.GetURL("/set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -2441,7 +2485,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
TestDelegate d;
network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE);
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
+ test_server.GetURL("/set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
DEFAULT_PRIORITY, &d));
req->Start();
@@ -2457,7 +2501,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2481,7 +2525,7 @@ TEST_F(URLRequestTest, DoNotSaveEmptyCookies) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/set-cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2501,7 +2545,7 @@ TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
+ test_server.GetURL("/set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -2516,7 +2560,7 @@ TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2534,7 +2578,7 @@ TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) {
TestDelegate d;
network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES);
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2556,7 +2600,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
+ test_server.GetURL("/set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -2572,7 +2616,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) {
TestDelegate d;
network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE);
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
+ test_server.GetURL("/set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
DEFAULT_PRIORITY, &d));
req->Start();
@@ -2588,7 +2632,7 @@ TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2606,17 +2650,17 @@ TEST_F(URLRequestTest, FirstPartyOnlyCookiesEnabled) {
LocalHttpTestServer test_server;
ASSERT_TRUE(test_server.Start());
+ TestNetworkDelegate network_delegate;
+ network_delegate.set_experimental_cookie_features_enabled(true);
+ default_context_.set_network_delegate(&network_delegate);
+
// Set up a 'First-Party-Only' cookie (on '127.0.0.1', as that's where
// LocalHttpTestServer points).
{
- TestNetworkDelegate network_delegate;
- network_delegate.set_first_party_only_cookies_enabled(true);
- default_context_.set_network_delegate(&network_delegate);
-
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
test_server.GetURL(
- "set-cookie?FirstPartyCookieToSet=1;First-Party-Only"),
+ "/set-cookie?FirstPartyCookieToSet=1;First-Party-Only"),
DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2627,13 +2671,11 @@ TEST_F(URLRequestTest, FirstPartyOnlyCookiesEnabled) {
// Verify that the cookie is sent for first-party requests.
{
- TestNetworkDelegate network_delegate;
- network_delegate.set_first_party_only_cookies_enabled(true);
- default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
- req->set_first_party_for_cookies(test_server.GetURL(""));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->set_first_party_for_cookies(test_server.GetURL("/"));
+ req->set_initiator(url::Origin(test_server.GetURL("/")));
req->Start();
base::RunLoop().Run();
@@ -2643,15 +2685,48 @@ TEST_F(URLRequestTest, FirstPartyOnlyCookiesEnabled) {
EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
}
- // Verify that the cookie is not-sent for non-first-party requests.
+ // Verify that the cookie is not sent for non-first-party requests.
{
- TestNetworkDelegate network_delegate;
- network_delegate.set_first_party_only_cookies_enabled(true);
- default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->set_first_party_for_cookies(GURL("http://third-party.test/"));
+ req->set_initiator(url::Origin(GURL("http://third-party.test/")));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") ==
+ std::string::npos);
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+
+ // Verify that the cookie is sent for non-first-party initiators when the
+ // method is "safe".
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest(
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->set_first_party_for_cookies(test_server.GetURL("/"));
+ req->set_initiator(url::Origin(GURL("http://third-party.test/")));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_FALSE(d.data_received().find("FirstPartyCookieToSet=1") ==
+ std::string::npos);
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+
+ // Verify that the cookie is not sent for non-first-party initiators when the
+ // method is unsafe (e.g. POST).
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest(
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->set_first_party_for_cookies(test_server.GetURL("/"));
+ req->set_initiator(url::Origin(GURL("http://third-party.test/")));
+ req->set_method("POST");
req->Start();
base::RunLoop().Run();
@@ -2670,13 +2745,13 @@ TEST_F(URLRequestTest, FirstPartyOnlyCookiesDisabled) {
// LocalHttpTestServer points).
{
TestNetworkDelegate network_delegate;
- network_delegate.set_first_party_only_cookies_enabled(false);
+ network_delegate.set_experimental_cookie_features_enabled(false);
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
test_server.GetURL(
- "set-cookie?FirstPartyCookieToSet=1;First-Party-Only"),
+ "/set-cookie?FirstPartyCookieToSet=1;First-Party-Only"),
DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2688,12 +2763,12 @@ TEST_F(URLRequestTest, FirstPartyOnlyCookiesDisabled) {
// Verify that the cookie is sent for first-party requests.
{
TestNetworkDelegate network_delegate;
- network_delegate.set_first_party_only_cookies_enabled(false);
+ network_delegate.set_experimental_cookie_features_enabled(false);
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
- req->set_first_party_for_cookies(test_server.GetURL(""));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->set_first_party_for_cookies(test_server.GetURL("/"));
req->Start();
base::RunLoop().Run();
@@ -2706,17 +2781,216 @@ TEST_F(URLRequestTest, FirstPartyOnlyCookiesDisabled) {
// Verify that the cookie is also sent for non-first-party requests.
{
TestNetworkDelegate network_delegate;
- network_delegate.set_first_party_only_cookies_enabled(false);
+ network_delegate.set_experimental_cookie_features_enabled(false);
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->set_first_party_for_cookies(GURL("http://third-party.test/"));
req->Start();
base::RunLoop().Run();
- EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") !=
- std::string::npos);
+ EXPECT_NE(d.data_received().find("FirstPartyCookieToSet=1"),
+ std::string::npos);
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+}
+
+// Tests that __Secure- cookies can't be set on non-secure origins.
+TEST_F(URLRequestTest, SecureCookiePrefixOnNonsecureOrigin) {
+ 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;
+ TestURLRequestContext context(true);
+ context.set_network_delegate(&network_delegate);
+ context.Init();
+
+ // Try to set a Secure __Secure- cookie.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ http_server.GetURL("/set-cookie?__Secure-nonsecure-origin=1;Secure"),
+ DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+
+ // Verify that the cookie is not set.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ https_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_EQ(d.data_received().find("__Secure-nonsecure-origin=1"),
+ std::string::npos);
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+}
+
+TEST_F(URLRequestTest, SecureCookiePrefixNonsecure) {
+ EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
+ https_server.AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ ASSERT_TRUE(https_server.Start());
+
+ TestNetworkDelegate network_delegate;
+ TestURLRequestContext context(true);
+ context.set_network_delegate(&network_delegate);
+ context.Init();
+
+ // Try to set a non-Secure __Secure- cookie.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(
+ context.CreateRequest(https_server.GetURL("/set-cookie?__Secure-foo=1"),
+ DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+
+ // Verify that the cookie is not set.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ https_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_EQ(d.data_received().find("__Secure-foo=1"), std::string::npos);
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+}
+
+TEST_F(URLRequestTest, SecureCookiePrefixSecure) {
+ EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
+ https_server.AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ ASSERT_TRUE(https_server.Start());
+
+ TestNetworkDelegate network_delegate;
+ TestURLRequestContext context(true);
+ context.set_network_delegate(&network_delegate);
+ context.Init();
+
+ // Try to set a Secure __Secure- cookie.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ https_server.GetURL("/set-cookie?__Secure-bar=1;Secure"),
+ DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+
+ // Verify that the cookie is set.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ https_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_NE(d.data_received().find("__Secure-bar=1"), std::string::npos);
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+}
+
+// Tests that secure cookies can't be set on non-secure origins if strict secure
+// cookies are enabled.
+TEST_F(URLRequestTest, StrictSecureCookiesOnNonsecureOrigin) {
+ 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());
+
+ TestExperimentalFeaturesNetworkDelegate network_delegate;
+ TestURLRequestContext context(true);
+ context.set_network_delegate(&network_delegate);
+ context.Init();
+
+ // Try to set a Secure cookie, with experimental features enabled.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ http_server.GetURL("/set-cookie?nonsecure-origin=1;Secure"),
+ DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+
+ // Verify that the cookie is not set.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ https_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_EQ(d.data_received().find("nonsecure-origin=1"), std::string::npos);
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+}
+
+// Tests that secure cookies can be set on secure origins even if strict secure
+// cookies are enabled.
+TEST_F(URLRequestTest, StrictSecureCookiesOnSecureOrigin) {
+ EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
+ https_server.AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ ASSERT_TRUE(https_server.Start());
+
+ TestExperimentalFeaturesNetworkDelegate network_delegate;
+ TestURLRequestContext context(true);
+ context.set_network_delegate(&network_delegate);
+ context.Init();
+
+ // Try to set a Secure cookie, with experimental features enabled.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ https_server.GetURL("/set-cookie?secure-origin=1;Secure"),
+ DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
+ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
+ }
+
+ // Verify that the cookie is not set.
+ {
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ https_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_NE(d.data_received().find("secure-origin=1"), std::string::npos);
EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
}
@@ -2807,7 +3081,7 @@ TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) {
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
test_server.GetURL(
- "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
+ "/set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2818,7 +3092,7 @@ TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2831,7 +3105,7 @@ TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) {
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
test_server.GetURL(
- "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
+ "/set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2842,7 +3116,7 @@ TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) {
default_context_.set_network_delegate(&network_delegate);
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -2862,7 +3136,7 @@ TEST_F(URLRequestTest, DoNotOverrideReferrer) {
{
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Referer"), DEFAULT_PRIORITY, &d));
req->SetReferrer("http://foo.com/");
HttpRequestHeaders headers;
@@ -2880,7 +3154,7 @@ TEST_F(URLRequestTest, DoNotOverrideReferrer) {
{
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/echoheader?Referer"), DEFAULT_PRIORITY, &d));
HttpRequestHeaders headers;
headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/");
@@ -2920,6 +3194,7 @@ class URLRequestTestHTTP : public URLRequestTest {
HttpRequestHeaders headers;
headers.SetHeader(HttpRequestHeaders::kContentLength,
base::SizeTToString(arraysize(kData) - 1));
+ headers.SetHeader(HttpRequestHeaders::kContentType, "text/plain");
req->SetExtraRequestHeaders(headers);
}
req->Start();
@@ -2929,8 +3204,16 @@ class URLRequestTestHTTP : public URLRequestTest {
EXPECT_EQ(OK, req->status().error());
if (include_data) {
if (request_method == redirect_method) {
+ EXPECT_TRUE(req->extra_request_headers().HasHeader(
+ HttpRequestHeaders::kContentLength));
+ EXPECT_TRUE(req->extra_request_headers().HasHeader(
+ HttpRequestHeaders::kContentType));
EXPECT_EQ(kData, d.data_received());
} else {
+ EXPECT_FALSE(req->extra_request_headers().HasHeader(
+ HttpRequestHeaders::kContentLength));
+ EXPECT_FALSE(req->extra_request_headers().HasHeader(
+ HttpRequestHeaders::kContentType));
EXPECT_NE(kData, d.data_received());
}
}
@@ -2997,7 +3280,7 @@ class URLRequestTestHTTP : public URLRequestTest {
for (int i = 0; i < kIterations; ++i) {
TestDelegate d;
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
+ test_server_.GetURL("/echo"), DEFAULT_PRIORITY, &d));
r->set_method(method.c_str());
r->set_upload(CreateSimpleUploadData(uploadBytes));
@@ -3044,7 +3327,7 @@ class URLRequestTestHTTP : public URLRequestTest {
bool DoManyCookiesRequest(int num_cookies) {
TestDelegate d;
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("set-many-cookies?" +
+ test_server_.GetURL("/set-many-cookies?" +
base::IntToString(num_cookies)),
DEFAULT_PRIORITY, &d));
@@ -3055,35 +3338,50 @@ class URLRequestTestHTTP : public URLRequestTest {
bool is_success = r->status().is_success();
- if (!is_success) {
+ if (!is_success)
EXPECT_TRUE(r->status().error() == ERR_RESPONSE_HEADERS_TOO_BIG);
- // The test server appears to be unable to handle subsequent requests
- // after this error is triggered. Force it to restart.
- EXPECT_TRUE(test_server_.Stop());
- EXPECT_TRUE(test_server_.Start());
- }
return is_success;
}
- LocalHttpTestServer* test_server() {
- return &test_server_;
- }
+ LocalHttpTestServer* http_test_server() { return &test_server_; }
- protected:
+ private:
LocalHttpTestServer test_server_;
};
-// In this unit test, we're using the HTTPTestServer as a proxy server and
+namespace {
+
+scoped_ptr<test_server::HttpResponse> HandleRedirectConnect(
+ const test_server::HttpRequest& request) {
+ if (request.headers.find("Host") == request.headers.end() ||
+ request.headers.at("Host") != "www.redirect.com" ||
+ request.method != test_server::METHOD_CONNECT) {
+ return nullptr;
+ }
+
+ scoped_ptr<test_server::BasicHttpResponse> http_response(
+ new test_server::BasicHttpResponse);
+ http_response->set_code(HTTP_FOUND);
+ http_response->AddCustomHeader("Location",
+ "http://www.destination.com/foo.js");
+ return std::move(http_response);
+}
+
+} // namespace
+
+// In this unit test, we're using the EmbeddedTestServer as a proxy server and
// issuing a CONNECT request with the magic host name "www.redirect.com".
-// The HTTPTestServer will return a 302 response, which we should not
+// The EmbeddedTestServer will return a 302 response, which we should not
// follow.
TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) {
- ASSERT_TRUE(test_server_.Start());
+ http_test_server()->RegisterRequestHandler(
+ base::Bind(&HandleRedirectConnect));
+ ASSERT_TRUE(http_test_server()->Start());
TestNetworkDelegate network_delegate; // Must outlive URLRequest.
TestURLRequestContextWithProxy context(
- test_server_.host_port_pair().ToString(), &network_delegate);
+ http_test_server()->host_port_pair().ToString(), &network_delegate);
TestDelegate d;
{
@@ -3107,11 +3405,11 @@ TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) {
// This is the same as the previous test, but checks that the network delegate
// registers the error.
TEST_F(URLRequestTestHTTP, NetworkDelegateTunnelConnectionFailed) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestNetworkDelegate network_delegate; // Must outlive URLRequest.
TestURLRequestContextWithProxy context(
- test_server_.host_port_pair().ToString(), &network_delegate);
+ http_test_server()->host_port_pair().ToString(), &network_delegate);
TestDelegate d;
{
@@ -3144,7 +3442,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) {
};
static const size_t blocking_stages_length = arraysize(blocking_stages);
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3160,7 +3458,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
for (size_t i = 0; i < blocking_stages_length; ++i) {
@@ -3180,7 +3478,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) {
// Tests that the network delegate can block and cancel a request.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3189,11 +3487,11 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequest) {
network_delegate.set_retval(ERR_EMPTY_RESPONSE);
TestURLRequestContextWithProxy context(
- test_server_.host_port_pair().ToString(), &network_delegate);
+ http_test_server()->host_port_pair().ToString(), &network_delegate);
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3243,66 +3541,66 @@ void NetworkDelegateCancelRequest(BlockingNetworkDelegate::BlockMode block_mode,
// The following 3 tests check that the network delegate can cancel a request
// synchronously in various stages of the request.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously1) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
- test_server_.GetURL(std::string()));
+ http_test_server()->GetURL("/"));
}
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously2) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
- test_server_.GetURL(std::string()));
+ http_test_server()->GetURL("/"));
}
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously3) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
- test_server_.GetURL(std::string()));
+ http_test_server()->GetURL("/"));
}
// The following 3 tests check that the network delegate can cancel a request
// asynchronously in various stages of the request.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously1) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
- test_server_.GetURL(std::string()));
+ http_test_server()->GetURL("/"));
}
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously2) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
- test_server_.GetURL(std::string()));
+ http_test_server()->GetURL("/"));
}
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously3) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
- test_server_.GetURL(std::string()));
+ http_test_server()->GetURL("/"));
}
// Tests that the network delegate can block and redirect a request to a new
// URL.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
BlockingNetworkDelegate::AUTO_CALLBACK);
network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
- GURL redirect_url(test_server_.GetURL("simple.html"));
+ GURL redirect_url(http_test_server()->GetURL("/simple.html"));
network_delegate.set_redirect_url(redirect_url);
TestURLRequestContextWithProxy context(
- test_server_.host_port_pair().ToString(), &network_delegate);
+ http_test_server()->host_port_pair().ToString(), &network_delegate);
{
- GURL original_url(test_server_.GetURL("empty.html"));
+ GURL original_url(http_test_server()->GetURL("/defaultresponse"));
scoped_ptr<URLRequest> r(
context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
@@ -3324,12 +3622,11 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) {
r->FollowDeferredRedirect();
base::RunLoop().Run();
EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
- EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
+ EXPECT_TRUE(r->proxy_server().Equals(http_test_server()->host_port_pair()));
EXPECT_EQ(
1, network_delegate.observed_before_proxy_headers_sent_callbacks());
- EXPECT_TRUE(
- network_delegate.last_observed_proxy().Equals(
- test_server_.host_port_pair()));
+ EXPECT_TRUE(network_delegate.last_observed_proxy().Equals(
+ http_test_server()->host_port_pair()));
EXPECT_EQ(0, r->status().error());
EXPECT_EQ(redirect_url, r->url());
@@ -3344,19 +3641,19 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) {
// Tests that the network delegate can block and redirect a request to a new
// URL by setting a redirect_url and returning in OnBeforeURLRequest directly.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestSynchronously) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
BlockingNetworkDelegate::SYNCHRONOUS);
- GURL redirect_url(test_server_.GetURL("simple.html"));
+ GURL redirect_url(http_test_server()->GetURL("/simple.html"));
network_delegate.set_redirect_url(redirect_url);
TestURLRequestContextWithProxy context(
- test_server_.host_port_pair().ToString(), &network_delegate);
+ http_test_server()->host_port_pair().ToString(), &network_delegate);
{
- GURL original_url(test_server_.GetURL("empty.html"));
+ GURL original_url(http_test_server()->GetURL("/defaultresponse"));
scoped_ptr<URLRequest> r(
context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
@@ -3379,12 +3676,11 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestSynchronously) {
base::RunLoop().Run();
EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
- EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
+ EXPECT_TRUE(r->proxy_server().Equals(http_test_server()->host_port_pair()));
EXPECT_EQ(
1, network_delegate.observed_before_proxy_headers_sent_callbacks());
- EXPECT_TRUE(
- network_delegate.last_observed_proxy().Equals(
- test_server_.host_port_pair()));
+ EXPECT_TRUE(network_delegate.last_observed_proxy().Equals(
+ http_test_server()->host_port_pair()));
EXPECT_EQ(0, r->status().error());
EXPECT_EQ(redirect_url, r->url());
EXPECT_EQ(original_url, r->original_url());
@@ -3397,7 +3693,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestSynchronously) {
// Tests that redirects caused by the network delegate preserve POST data.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
const char kData[] = "hello world";
@@ -3405,7 +3701,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) {
BlockingNetworkDelegate network_delegate(
BlockingNetworkDelegate::AUTO_CALLBACK);
network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
- GURL redirect_url(test_server_.GetURL("echo"));
+ GURL redirect_url(http_test_server()->GetURL("/echo"));
network_delegate.set_redirect_url(redirect_url);
TestURLRequestContext context(true);
@@ -3413,7 +3709,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) {
context.Init();
{
- GURL original_url(test_server_.GetURL("empty.html"));
+ GURL original_url(http_test_server()->GetURL("/defaultresponse"));
scoped_ptr<URLRequest> r(
context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
r->set_method("POST");
@@ -3457,20 +3753,20 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) {
// Tests that the network delegate can block and redirect a request to a new
// URL during OnHeadersReceived.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
BlockingNetworkDelegate::AUTO_CALLBACK);
network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
- GURL redirect_url(test_server_.GetURL("simple.html"));
+ GURL redirect_url(http_test_server()->GetURL("/simple.html"));
network_delegate.set_redirect_on_headers_received_url(redirect_url);
TestURLRequestContextWithProxy context(
- test_server_.host_port_pair().ToString(), &network_delegate);
+ http_test_server()->host_port_pair().ToString(), &network_delegate);
{
- GURL original_url(test_server_.GetURL("empty.html"));
+ GURL original_url(http_test_server()->GetURL("/defaultresponse"));
scoped_ptr<URLRequest> r(
context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
@@ -3478,12 +3774,11 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) {
base::RunLoop().Run();
EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
- EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
+ EXPECT_TRUE(r->proxy_server().Equals(http_test_server()->host_port_pair()));
EXPECT_EQ(
2, network_delegate.observed_before_proxy_headers_sent_callbacks());
- EXPECT_TRUE(
- network_delegate.last_observed_proxy().Equals(
- test_server_.host_port_pair()));
+ EXPECT_TRUE(network_delegate.last_observed_proxy().Equals(
+ http_test_server()->host_port_pair()));
EXPECT_EQ(OK, r->status().error());
EXPECT_EQ(redirect_url, r->url());
@@ -3500,7 +3795,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) {
// handle the challenge, and is passing the buck along to the
// URLRequest::Delegate.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3513,7 +3808,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) {
d.set_credentials(AuthCredentials(kUser, kSecret));
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
@@ -3531,7 +3826,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) {
TEST_F(URLRequestTestHTTP,
NetworkDelegateOnAuthRequiredSyncNoAction_GetFullRequestHeaders) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3544,7 +3839,7 @@ TEST_F(URLRequestTestHTTP,
d.set_credentials(AuthCredentials(kUser, kSecret));
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
@@ -3569,7 +3864,7 @@ TEST_F(URLRequestTestHTTP,
// Tests that the network delegate can synchronously complete OnAuthRequired
// by setting credentials.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncSetAuth) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3585,7 +3880,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncSetAuth) {
context.Init();
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3604,7 +3899,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncSetAuth) {
// headers (for the first or second request) when called at the proper times.
TEST_F(URLRequestTestHTTP,
NetworkDelegateOnAuthRequiredSyncSetAuth_GetFullRequestHeaders) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3620,7 +3915,7 @@ TEST_F(URLRequestTestHTTP,
context.Init();
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3644,7 +3939,7 @@ TEST_F(URLRequestTestHTTP,
// Tests that the network delegate can synchronously complete OnAuthRequired
// by cancelling authentication.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncCancel) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3658,7 +3953,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncCancel) {
context.Init();
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3678,7 +3973,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncCancel) {
// to handle the challenge, and is passing the buck along to the
// URLRequest::Delegate.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncNoAction) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3692,7 +3987,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncNoAction) {
d.set_credentials(AuthCredentials(kUser, kSecret));
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3710,7 +4005,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncNoAction) {
// Tests that the network delegate can asynchronously complete OnAuthRequired
// by setting credentials.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncSetAuth) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3727,7 +4022,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncSetAuth) {
context.Init();
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3746,7 +4041,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncSetAuth) {
// Tests that the network delegate can asynchronously complete OnAuthRequired
// by cancelling authentication.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncCancel) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3760,7 +4055,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncCancel) {
context.Init();
{
- GURL url(test_server_.GetURL("auth-basic"));
+ GURL url(http_test_server()->GetURL("/auth-basic"));
scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3779,7 +4074,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncCancel) {
// waiting for the network delegate.
// Part 1: Request is cancelled while waiting for OnBeforeURLRequest callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting1) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3792,7 +4087,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting1) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3815,7 +4110,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting1) {
// waiting for the network delegate.
// Part 2: Request is cancelled while waiting for OnBeforeSendHeaders callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting2) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3829,7 +4124,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting2) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3852,7 +4147,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting2) {
// waiting for the network delegate.
// Part 3: Request is cancelled while waiting for OnHeadersReceived callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting3) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3865,7 +4160,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting3) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3888,7 +4183,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting3) {
// waiting for the network delegate.
// Part 4: Request is cancelled while waiting for OnAuthRequired callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting4) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
BlockingNetworkDelegate network_delegate(
@@ -3901,7 +4196,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting4) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/auth-basic"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -3920,15 +4215,37 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting4) {
EXPECT_EQ(1, network_delegate.destroyed_requests());
}
-// In this unit test, we're using the HTTPTestServer as a proxy server and
+namespace {
+
+scoped_ptr<test_server::HttpResponse> HandleServerAuthConnect(
+ const test_server::HttpRequest& request) {
+ if (request.headers.find("Host") == request.headers.end() ||
+ request.headers.at("Host") != "www.server-auth.com" ||
+ request.method != test_server::METHOD_CONNECT) {
+ return nullptr;
+ }
+
+ scoped_ptr<test_server::BasicHttpResponse> http_response(
+ new test_server::BasicHttpResponse);
+ http_response->set_code(HTTP_UNAUTHORIZED);
+ http_response->AddCustomHeader("WWW-Authenticate",
+ "Basic realm=\"WallyWorld\"");
+ return std::move(http_response);
+}
+
+} // namespace
+
+// In this unit test, we're using the EmbeddedTestServer as a proxy server and
// issuing a CONNECT request with the magic host name "www.server-auth.com".
-// The HTTPTestServer will return a 401 response, which we should balk at.
+// The EmbeddedTestServer will return a 401 response, which we should balk at.
TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) {
- ASSERT_TRUE(test_server_.Start());
+ http_test_server()->RegisterRequestHandler(
+ base::Bind(&HandleServerAuthConnect));
+ ASSERT_TRUE(http_test_server()->Start());
TestNetworkDelegate network_delegate; // Must outlive URLRequest.
TestURLRequestContextWithProxy context(
- test_server_.host_port_pair().ToString(), &network_delegate);
+ http_test_server()->host_port_pair().ToString(), &network_delegate);
TestDelegate d;
{
@@ -3948,12 +4265,12 @@ TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) {
}
TEST_F(URLRequestTestHTTP, GetTest_NoCache) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -3963,9 +4280,9 @@ TEST_F(URLRequestTestHTTP, GetTest_NoCache) {
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_NE(0, d.bytes_received());
- EXPECT_EQ(test_server_.host_port_pair().host(),
+ EXPECT_EQ(http_test_server()->host_port_pair().host(),
r->GetSocketAddress().host());
- EXPECT_EQ(test_server_.host_port_pair().port(),
+ EXPECT_EQ(http_test_server()->host_port_pair().port(),
r->GetSocketAddress().port());
// TODO(eroman): Add back the NetLog tests...
@@ -3984,7 +4301,7 @@ TEST_F(URLRequestTestHTTP, GetTest_NoCache) {
#define MAYBE_GetTest_ManyCookies GetTest_ManyCookies
#endif // defined(OS_WIN)
TEST_F(URLRequestTestHTTP, MAYBE_GetTest_ManyCookies) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
int lower_bound = 0;
int upper_bound = 1;
@@ -4015,12 +4332,12 @@ TEST_F(URLRequestTestHTTP, MAYBE_GetTest_ManyCookies) {
}
TEST_F(URLRequestTestHTTP, GetTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -4030,19 +4347,19 @@ TEST_F(URLRequestTestHTTP, GetTest) {
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_NE(0, d.bytes_received());
- EXPECT_EQ(test_server_.host_port_pair().host(),
+ EXPECT_EQ(http_test_server()->host_port_pair().host(),
r->GetSocketAddress().host());
- EXPECT_EQ(test_server_.host_port_pair().port(),
+ EXPECT_EQ(http_test_server()->host_port_pair().port(),
r->GetSocketAddress().port());
}
}
TEST_F(URLRequestTestHTTP, GetTest_GetFullRequestHeaders) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
- GURL test_url(test_server_.GetURL(std::string()));
+ GURL test_url(http_test_server()->GetURL("/defaultresponse"));
scoped_ptr<URLRequest> r(
default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
@@ -4057,9 +4374,9 @@ TEST_F(URLRequestTestHTTP, GetTest_GetFullRequestHeaders) {
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_NE(0, d.bytes_received());
- EXPECT_EQ(test_server_.host_port_pair().host(),
+ EXPECT_EQ(http_test_server()->host_port_pair().host(),
r->GetSocketAddress().host());
- EXPECT_EQ(test_server_.host_port_pair().port(),
+ EXPECT_EQ(http_test_server()->host_port_pair().port(),
r->GetSocketAddress().port());
EXPECT_TRUE(d.have_full_request_headers());
@@ -4068,12 +4385,12 @@ TEST_F(URLRequestTestHTTP, GetTest_GetFullRequestHeaders) {
}
TEST_F(URLRequestTestHTTP, GetTestLoadTiming) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -4087,15 +4404,21 @@ TEST_F(URLRequestTestHTTP, GetTestLoadTiming) {
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_NE(0, d.bytes_received());
- EXPECT_EQ(test_server_.host_port_pair().host(),
+ EXPECT_EQ(http_test_server()->host_port_pair().host(),
r->GetSocketAddress().host());
- EXPECT_EQ(test_server_.host_port_pair().port(),
+ EXPECT_EQ(http_test_server()->host_port_pair().port(),
r->GetSocketAddress().port());
}
}
+// TODO(svaldez): Update tests to use EmbeddedTestServer.
+#if !defined(OS_IOS)
TEST_F(URLRequestTestHTTP, GetZippedTest) {
- ASSERT_TRUE(test_server_.Start());
+ SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
+ SpawnedTestServer::kLocalhost,
+ base::FilePath(kTestFilePath));
+
+ ASSERT_TRUE(test_server.Start());
// Parameter that specifies the Content-Length field in the response:
// C - Compressed length.
@@ -4114,9 +4437,8 @@ TEST_F(URLRequestTestHTTP, GetZippedTest) {
for (int i = 0; i < num_tests ; i++) {
TestDelegate d;
{
- std::string test_file =
- base::StringPrintf("compressedfiles/BullRunSpeech.txt?%c",
- test_parameters[i]);
+ std::string test_file = base::StringPrintf(
+ "compressedfiles/BullRunSpeech.txt?%c", test_parameters[i]);
TestNetworkDelegate network_delegate; // Must outlive URLRequest.
TestURLRequestContext context(true);
@@ -4124,7 +4446,7 @@ TEST_F(URLRequestTestHTTP, GetZippedTest) {
context.Init();
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL(test_file), DEFAULT_PRIORITY, &d));
+ test_server.GetURL(test_file), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -4146,9 +4468,10 @@ TEST_F(URLRequestTestHTTP, GetZippedTest) {
}
}
}
+#endif // !defined(OS_IOS)
TEST_F(URLRequestTestHTTP, NetworkQualityEstimator) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
// Enable requests to local host to be used for network quality estimation.
std::map<std::string, std::string> variation_params;
NetworkQualityEstimator estimator(scoped_ptr<net::ExternalEstimateProvider>(),
@@ -4161,10 +4484,10 @@ TEST_F(URLRequestTestHTTP, NetworkQualityEstimator) {
context.set_network_delegate(&network_delegate);
context.Init();
- std::string url = "echo.html";
+ std::string url = "/defaultresponse";
- scoped_ptr<URLRequest> r(
- context.CreateRequest(test_server_.GetURL(url), DEFAULT_PRIORITY, &d));
+ scoped_ptr<URLRequest> r(context.CreateRequest(
+ http_test_server()->GetURL(url), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -4191,11 +4514,11 @@ TEST_F(URLRequestTestHTTP, NetworkQualityEstimator) {
}
TEST_F(URLRequestTestHTTP, RedirectLoadTiming) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL destination_url = test_server_.GetURL(std::string());
+ GURL destination_url = http_test_server()->GetURL("/");
GURL original_url =
- test_server_.GetURL("server-redirect?" + destination_url.spec());
+ http_test_server()->GetURL("/server-redirect?" + destination_url.spec());
TestDelegate d;
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
@@ -4230,13 +4553,13 @@ TEST_F(URLRequestTestHTTP, RedirectLoadTiming) {
}
TEST_F(URLRequestTestHTTP, MultipleRedirectTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL destination_url = test_server_.GetURL(std::string());
+ GURL destination_url = http_test_server()->GetURL("/");
GURL middle_redirect_url =
- test_server_.GetURL("server-redirect?" + destination_url.spec());
- GURL original_url = test_server_.GetURL(
- "server-redirect?" + middle_redirect_url.spec());
+ http_test_server()->GetURL("/server-redirect?" + destination_url.spec());
+ GURL original_url = http_test_server()->GetURL("/server-redirect?" +
+ middle_redirect_url.spec());
TestDelegate d;
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
@@ -4557,7 +4880,7 @@ class AsyncLoggingUrlRequestDelegate : public TestDelegate {
// Tests handling of delegate info before a request starts.
TEST_F(URLRequestTestHTTP, DelegateInfoBeforeStart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate request_delegate;
TestURLRequestContext context(true);
@@ -4567,7 +4890,7 @@ TEST_F(URLRequestTestHTTP, DelegateInfoBeforeStart) {
{
scoped_ptr<URLRequest> r(
- context.CreateRequest(test_server_.GetURL("empty.html"),
+ context.CreateRequest(http_test_server()->GetURL("/defaultresponse"),
DEFAULT_PRIORITY, &request_delegate));
LoadStateWithParam load_state = r->GetLoadState();
EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
@@ -4603,7 +4926,7 @@ TEST_F(URLRequestTestHTTP, DelegateInfoBeforeStart) {
// Tests handling of delegate info from a network delegate.
TEST_F(URLRequestTestHTTP, NetworkDelegateInfo) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate request_delegate;
AsyncLoggingNetworkDelegate network_delegate;
@@ -4614,7 +4937,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateInfo) {
{
scoped_ptr<URLRequest> r(
- context.CreateRequest(test_server_.GetURL("simple.html"),
+ context.CreateRequest(http_test_server()->GetURL("/simple.html"),
DEFAULT_PRIORITY, &request_delegate));
LoadStateWithParam load_state = r->GetLoadState();
EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
@@ -4660,7 +4983,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateInfo) {
// Tests handling of delegate info from a network delegate in the case of an
// HTTP redirect.
TEST_F(URLRequestTestHTTP, NetworkDelegateInfoRedirect) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate request_delegate;
AsyncLoggingNetworkDelegate network_delegate;
@@ -4671,8 +4994,8 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateInfoRedirect) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
- &request_delegate));
+ http_test_server()->GetURL("/server-redirect?simple.html"),
+ DEFAULT_PRIORITY, &request_delegate));
LoadStateWithParam load_state = r->GetLoadState();
EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
EXPECT_EQ(base::string16(), load_state.param);
@@ -4742,7 +5065,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateInfoRedirect) {
// Tests handling of delegate info from a network delegate in the case of HTTP
// AUTH.
TEST_F(URLRequestTestHTTP, NetworkDelegateInfoAuth) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate request_delegate;
AsyncLoggingNetworkDelegate network_delegate;
@@ -4753,7 +5076,7 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateInfoAuth) {
{
scoped_ptr<URLRequest> r(
- context.CreateRequest(test_server_.GetURL("auth-basic"),
+ context.CreateRequest(http_test_server()->GetURL("/auth-basic"),
DEFAULT_PRIORITY, &request_delegate));
LoadStateWithParam load_state = r->GetLoadState();
EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
@@ -4799,9 +5122,15 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateInfoAuth) {
entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
}
+// TODO(svaldez): Update tests to use EmbeddedTestServer.
+#if !defined(OS_IOS)
// Tests handling of delegate info from a URLRequest::Delegate.
TEST_F(URLRequestTestHTTP, URLRequestDelegateInfo) {
- ASSERT_TRUE(test_server_.Start());
+ SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
+ SpawnedTestServer::kLocalhost,
+ base::FilePath(kTestFilePath));
+
+ ASSERT_TRUE(test_server.Start());
AsyncLoggingUrlRequestDelegate request_delegate(
AsyncLoggingUrlRequestDelegate::NO_CANCEL);
@@ -4817,7 +5146,7 @@ TEST_F(URLRequestTestHTTP, URLRequestDelegateInfo) {
// the possibility of multiple reads being combined in the unlikely event
// that it occurs.
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL("chunked?waitBetweenChunks=20"), DEFAULT_PRIORITY,
+ test_server.GetURL("/chunked?waitBetweenChunks=20"), DEFAULT_PRIORITY,
&request_delegate));
LoadStateWithParam load_state = r->GetLoadState();
r->Start();
@@ -4855,11 +5184,12 @@ TEST_F(URLRequestTestHTTP, URLRequestDelegateInfo) {
EXPECT_FALSE(LogContainsEntryWithTypeAfter(
entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE));
}
+#endif // !defined(OS_IOS)
// Tests handling of delegate info from a URLRequest::Delegate in the case of
// an HTTP redirect.
TEST_F(URLRequestTestHTTP, URLRequestDelegateInfoOnRedirect) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
AsyncLoggingUrlRequestDelegate request_delegate(
AsyncLoggingUrlRequestDelegate::NO_CANCEL);
@@ -4870,8 +5200,8 @@ TEST_F(URLRequestTestHTTP, URLRequestDelegateInfoOnRedirect) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
- &request_delegate));
+ http_test_server()->GetURL("/server-redirect?simple.html"),
+ DEFAULT_PRIORITY, &request_delegate));
LoadStateWithParam load_state = r->GetLoadState();
r->Start();
base::RunLoop().Run();
@@ -4915,7 +5245,7 @@ TEST_F(URLRequestTestHTTP, URLRequestDelegateInfoOnRedirect) {
// Tests handling of delegate info from a URLRequest::Delegate in the case of
// an HTTP redirect, with cancellation at various points.
TEST_F(URLRequestTestHTTP, URLRequestDelegateOnRedirectCancelled) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
const AsyncLoggingUrlRequestDelegate::CancelStage kCancelStages[] = {
AsyncLoggingUrlRequestDelegate::CANCEL_ON_RECEIVED_REDIRECT,
@@ -4934,8 +5264,8 @@ TEST_F(URLRequestTestHTTP, URLRequestDelegateOnRedirectCancelled) {
{
scoped_ptr<URLRequest> r(context.CreateRequest(
- test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
- &request_delegate));
+ http_test_server()->GetURL("/server-redirect?simple.html"),
+ DEFAULT_PRIORITY, &request_delegate));
LoadStateWithParam load_state = r->GetLoadState();
r->Start();
base::RunLoop().Run();
@@ -4994,12 +5324,12 @@ class RedirectWithAdditionalHeadersDelegate : public TestDelegate {
} // namespace
TEST_F(URLRequestTestHTTP, RedirectWithAdditionalHeadersTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL destination_url = test_server_.GetURL(
- "echoheader?" + std::string(kExtraHeader));
- GURL original_url = test_server_.GetURL(
- "server-redirect?" + destination_url.spec());
+ GURL destination_url =
+ http_test_server()->GetURL("/echoheader?" + std::string(kExtraHeader));
+ GURL original_url =
+ http_test_server()->GetURL("/server-redirect?" + destination_url.spec());
RedirectWithAdditionalHeadersDelegate d;
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
@@ -5031,12 +5361,12 @@ class RedirectWithHeaderRemovalDelegate : public TestDelegate {
} // namespace
TEST_F(URLRequestTestHTTP, RedirectWithHeaderRemovalTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL destination_url = test_server_.GetURL(
- "echoheader?" + std::string(kExtraHeaderToRemove));
- GURL original_url = test_server_.GetURL(
- "server-redirect?" + destination_url.spec());
+ GURL destination_url = http_test_server()->GetURL(
+ "/echoheader?" + std::string(kExtraHeaderToRemove));
+ GURL original_url =
+ http_test_server()->GetURL("/server-redirect?" + destination_url.spec());
RedirectWithHeaderRemovalDelegate d;
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
@@ -5074,12 +5404,12 @@ TEST_F(URLRequestTestHTTP, CancelTest) {
}
TEST_F(URLRequestTestHTTP, CancelTest2) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/"), DEFAULT_PRIORITY, &d));
d.set_cancel_in_response_started(true);
@@ -5096,12 +5426,12 @@ TEST_F(URLRequestTestHTTP, CancelTest2) {
}
TEST_F(URLRequestTestHTTP, CancelTest3) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/"), DEFAULT_PRIORITY, &d));
d.set_cancel_in_received_data(true);
@@ -5121,12 +5451,12 @@ TEST_F(URLRequestTestHTTP, CancelTest3) {
}
TEST_F(URLRequestTestHTTP, CancelTest4) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -5140,20 +5470,20 @@ TEST_F(URLRequestTestHTTP, CancelTest4) {
}
// expect things to just cleanup properly.
- // we won't actually get a received reponse here because we've never run the
+ // we won't actually get a received response here because we've never run the
// message loop
EXPECT_FALSE(d.received_data_before_response());
EXPECT_EQ(0, d.bytes_received());
}
TEST_F(URLRequestTestHTTP, CancelTest5) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
// populate cache
{
TestDelegate d;
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/cachetime"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
@@ -5163,7 +5493,7 @@ TEST_F(URLRequestTestHTTP, CancelTest5) {
{
TestDelegate d;
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/cachetime"), DEFAULT_PRIORITY, &d));
r->Start();
r->Cancel();
base::RunLoop().Run();
@@ -5176,22 +5506,22 @@ TEST_F(URLRequestTestHTTP, CancelTest5) {
}
TEST_F(URLRequestTestHTTP, PostTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
HTTPUploadDataOperationTest("POST");
}
TEST_F(URLRequestTestHTTP, PutTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
HTTPUploadDataOperationTest("PUT");
}
TEST_F(URLRequestTestHTTP, PostEmptyTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d));
r->set_method("POST");
r->Start();
@@ -5209,36 +5539,36 @@ TEST_F(URLRequestTestHTTP, PostEmptyTest) {
}
TEST_F(URLRequestTestHTTP, PostFileTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d));
r->set_method("POST");
base::FilePath dir;
PathService::Get(base::DIR_EXE, &dir);
base::SetCurrentDirectory(dir);
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
base::FilePath path;
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.Append(kTestFilePath);
path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
- element_readers.push_back(
- new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
- path, 0, kuint64max, base::Time()));
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
+ base::ThreadTaskRunnerHandle::Get().get(), path, 0,
+ std::numeric_limits<uint64_t>::max(), base::Time())));
r->set_upload(make_scoped_ptr<UploadDataStream>(
- new ElementsUploadDataStream(element_readers.Pass(), 0)));
+ new ElementsUploadDataStream(std::move(element_readers), 0)));
r->Start();
EXPECT_TRUE(r->is_pending());
base::RunLoop().Run();
- int64 size64 = 0;
+ int64_t size64 = 0;
ASSERT_EQ(true, base::GetFileSize(path, &size64));
ASSERT_LE(size64, std::numeric_limits<int>::max());
int size = static_cast<int>(size64);
@@ -5258,23 +5588,23 @@ TEST_F(URLRequestTestHTTP, PostFileTest) {
}
TEST_F(URLRequestTestHTTP, PostUnreadableFileTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d));
r->set_method("POST");
- ScopedVector<UploadElementReader> element_readers;
+ std::vector<scoped_ptr<UploadElementReader>> element_readers;
- element_readers.push_back(new UploadFileElementReader(
+ element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
base::ThreadTaskRunnerHandle::Get().get(),
base::FilePath(FILE_PATH_LITERAL(
"c:\\path\\to\\non\\existant\\file.randomness.12345")),
- 0, kuint64max, base::Time()));
+ 0, std::numeric_limits<uint64_t>::max(), base::Time())));
r->set_upload(make_scoped_ptr<UploadDataStream>(
- new ElementsUploadDataStream(element_readers.Pass(), 0)));
+ new ElementsUploadDataStream(std::move(element_readers), 0)));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -5290,12 +5620,12 @@ TEST_F(URLRequestTestHTTP, PostUnreadableFileTest) {
}
TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d));
r->EnableChunkedUpload();
r->set_method("POST");
AddChunksToUpload(r.get());
@@ -5309,12 +5639,12 @@ TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) {
}
TEST_F(URLRequestTestHTTP, TestPostChunkedDataJustAfterStart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d));
r->EnableChunkedUpload();
r->set_method("POST");
r->Start();
@@ -5327,12 +5657,12 @@ TEST_F(URLRequestTestHTTP, TestPostChunkedDataJustAfterStart) {
}
TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d));
r->EnableChunkedUpload();
r->set_method("POST");
r->Start();
@@ -5347,11 +5677,11 @@ TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) {
}
TEST_F(URLRequestTestHTTP, ResponseHeadersTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/with-headers.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/with-headers.html"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -5375,20 +5705,21 @@ TEST_F(URLRequestTestHTTP, ResponseHeadersTest) {
EXPECT_EQ("a, b", header);
}
+// TODO(svaldez): iOS tests are flaky with EmbeddedTestServer and transport
+// security state. (see http://crbug.com/550977).
+#if !defined(OS_IOS)
TEST_F(URLRequestTestHTTP, ProcessSTS) {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
-
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TestDelegate d;
scoped_ptr<URLRequest> request(default_context_.CreateRequest(
- https_test_server.GetURL("files/hsts-headers.html"), DEFAULT_PRIORITY,
- &d));
+ https_test_server.GetURL("/hsts-headers.html"), DEFAULT_PRIORITY, &d));
request->Start();
base::RunLoop().Run();
@@ -5412,22 +5743,20 @@ TEST_F(URLRequestTestHTTP, ProcessSTS) {
}
TEST_F(URLRequestTestHTTP, STSNotProcessedOnIP) {
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::SSLOptions(),
- base::FilePath(kTestFilePath));
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
// Make sure this test fails if the test server is changed to not
// listen on an IP by default.
- ASSERT_TRUE(https_test_server.GetURL("").HostIsIPAddress());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ ASSERT_TRUE(https_test_server.GetURL("/").HostIsIPAddress());
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TestDelegate d;
scoped_ptr<URLRequest> request(default_context_.CreateRequest(
- https_test_server.GetURL("files/hsts-headers.html"), DEFAULT_PRIORITY,
- &d));
+ https_test_server.GetURL("/hsts-headers.html"), DEFAULT_PRIORITY, &d));
request->Start();
base::RunLoop().Run();
-
TransportSecurityState* security_state =
default_context_.transport_security_state();
TransportSecurityState::STSState sts_state;
@@ -5460,22 +5789,20 @@ const char kHPKPReportUri[] = "https://hpkp-report.test";
// validity/expiration.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) {
GURL report_uri(kHPKPReportUri);
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TestDelegate d;
scoped_ptr<URLRequest> request(default_context_.CreateRequest(
- https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY,
- &d));
+ https_test_server.GetURL("/hpkp-headers.html"), DEFAULT_PRIORITY, &d));
request->Start();
base::RunLoop().Run();
-
TransportSecurityState* security_state =
default_context_.transport_security_state();
TransportSecurityState::STSState sts_state;
@@ -5496,15 +5823,14 @@ TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) {
// Tests that reports get sent on HPKP violations when a report-uri is set.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPAndSendReport) {
GURL report_uri(kHPKPReportUri);
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
-
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
// Set up a pin for |test_server_hostname|.
TransportSecurityState security_state;
@@ -5553,7 +5879,7 @@ TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPAndSendReport) {
// Now send a request to trigger the violation.
TestDelegate d;
scoped_ptr<URLRequest> violating_request(context.CreateRequest(
- https_test_server.GetURL("files/simple.html"), DEFAULT_PRIORITY, &d));
+ https_test_server.GetURL("/simple.html"), DEFAULT_PRIORITY, &d));
violating_request->Start();
base::RunLoop().Run();
@@ -5575,15 +5901,14 @@ TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPAndSendReport) {
// Public-Key-Pins-Report-Only headers.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnly) {
GURL report_uri(kHPKPReportUri);
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
-
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TransportSecurityState security_state;
MockCertificateReportSender mock_report_sender;
@@ -5616,7 +5941,7 @@ TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnly) {
// Now send a request to trigger the violation.
TestDelegate d;
scoped_ptr<URLRequest> violating_request(context.CreateRequest(
- https_test_server.GetURL("files/hpkp-headers-report-only.html"),
+ https_test_server.GetURL("/hpkp-headers-report-only.html"),
DEFAULT_PRIORITY, &d));
violating_request->Start();
base::RunLoop().Run();
@@ -5639,15 +5964,14 @@ TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnly) {
// Public-Key-Pins-Report-Only headers that don't have pin violations.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnlyWithNoViolation) {
GURL report_uri(kHPKPReportUri);
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
-
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TransportSecurityState security_state;
MockCertificateReportSender mock_report_sender;
@@ -5665,7 +5989,7 @@ TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnlyWithNoViolation) {
// Now send a request that does not trigger the violation.
TestDelegate d;
scoped_ptr<URLRequest> request(context.CreateRequest(
- https_test_server.GetURL("files/hpkp-headers-report-only.html"),
+ https_test_server.GetURL("/hpkp-headers-report-only.html"),
DEFAULT_PRIORITY, &d));
request->Start();
base::RunLoop().Run();
@@ -5676,19 +6000,18 @@ TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnlyWithNoViolation) {
}
TEST_F(URLRequestTestHTTP, PKPNotProcessedOnIP) {
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::SSLOptions(),
- base::FilePath(kTestFilePath));
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
// Make sure this test fails if the test server is changed to not
// listen on an IP by default.
- ASSERT_TRUE(https_test_server.GetURL("").HostIsIPAddress());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ ASSERT_TRUE(https_test_server.GetURL("/").HostIsIPAddress());
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TestDelegate d;
scoped_ptr<URLRequest> request(default_context_.CreateRequest(
- https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY,
- &d));
+ https_test_server.GetURL("/hpkp-headers.html"), DEFAULT_PRIORITY, &d));
request->Start();
base::RunLoop().Run();
@@ -5700,19 +6023,19 @@ TEST_F(URLRequestTestHTTP, PKPNotProcessedOnIP) {
}
TEST_F(URLRequestTestHTTP, ProcessSTSOnce) {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TestDelegate d;
scoped_ptr<URLRequest> request(default_context_.CreateRequest(
- https_test_server.GetURL("files/hsts-multiple-headers.html"),
- DEFAULT_PRIORITY, &d));
+ https_test_server.GetURL("/hsts-multiple-headers.html"), DEFAULT_PRIORITY,
+ &d));
request->Start();
base::RunLoop().Run();
@@ -5729,19 +6052,19 @@ TEST_F(URLRequestTestHTTP, ProcessSTSOnce) {
}
TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TestDelegate d;
scoped_ptr<URLRequest> request(default_context_.CreateRequest(
- https_test_server.GetURL("files/hsts-and-hpkp-headers.html"),
- DEFAULT_PRIORITY, &d));
+ https_test_server.GetURL("/hsts-and-hpkp-headers.html"), DEFAULT_PRIORITY,
+ &d));
request->Start();
base::RunLoop().Run();
@@ -5773,18 +6096,18 @@ TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) {
// Tests that when multiple HPKP headers are present, asserting different
// policies, that only the first such policy is processed.
TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(kTestFilePath));
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(kTestFilePath));
ASSERT_TRUE(https_test_server.Start());
- std::string test_server_hostname = https_test_server.GetURL("").host();
+ std::string test_server_hostname = https_test_server.GetURL("/").host();
TestDelegate d;
scoped_ptr<URLRequest> request(default_context_.CreateRequest(
- https_test_server.GetURL("files/hsts-and-hpkp-headers2.html"),
+ https_test_server.GetURL("/hsts-and-hpkp-headers2.html"),
DEFAULT_PRIORITY, &d));
request->Start();
base::RunLoop().Run();
@@ -5810,12 +6133,14 @@ TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) {
EXPECT_FALSE(pkp_state.include_subdomains);
}
+#endif // !defined(OS_IOS)
+
TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/content-type-normalization.html"),
+ http_test_server()->GetURL("/content-type-normalization.html"),
DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -5853,11 +6178,11 @@ TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictFileRedirects) {
}
TEST_F(URLRequestTestHTTP, RestrictFileRedirects) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/redirect-to-file.html"), DEFAULT_PRIORITY,
+ http_test_server()->GetURL("/redirect-to-file.html"), DEFAULT_PRIORITY,
&d));
req->Start();
base::RunLoop().Run();
@@ -5868,11 +6193,11 @@ TEST_F(URLRequestTestHTTP, RestrictFileRedirects) {
#endif // !defined(DISABLE_FILE_SUPPORT)
TEST_F(URLRequestTestHTTP, RestrictDataRedirects) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/redirect-to-data.html"), DEFAULT_PRIORITY,
+ http_test_server()->GetURL("/redirect-to-data.html"), DEFAULT_PRIORITY,
&d));
req->Start();
base::MessageLoop::current()->Run();
@@ -5882,11 +6207,11 @@ TEST_F(URLRequestTestHTTP, RestrictDataRedirects) {
}
TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/redirect-to-invalid-url.html"),
+ http_test_server()->GetURL("/redirect-to-invalid-url.html"),
DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -5897,9 +6222,9 @@ TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) {
// Make sure redirects are cached, despite not reading their bodies.
TEST_F(URLRequestTestHTTP, CacheRedirect) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
GURL redirect_url =
- test_server_.GetURL("files/redirect302-to-echo-cacheable");
+ http_test_server()->GetURL("/redirect302-to-echo-cacheable");
{
TestDelegate d;
@@ -5909,7 +6234,7 @@ TEST_F(URLRequestTestHTTP, CacheRedirect) {
base::RunLoop().Run();
EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
EXPECT_EQ(1, d.received_redirect_count());
- EXPECT_EQ(test_server_.GetURL("echo"), req->url());
+ EXPECT_EQ(http_test_server()->GetURL("/echo"), req->url());
}
{
@@ -5929,20 +6254,20 @@ TEST_F(URLRequestTestHTTP, CacheRedirect) {
EXPECT_EQ(1, d.received_redirect_count());
EXPECT_EQ(1, d.response_started_count());
EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
- EXPECT_EQ(test_server_.GetURL("echo"), req->url());
+ EXPECT_EQ(http_test_server()->GetURL("/echo"), req->url());
}
}
// Make sure a request isn't cached when a NetworkDelegate forces a redirect
// when the headers are read, since the body won't have been read.
TEST_F(URLRequestTestHTTP, NoCacheOnNetworkDelegateRedirect) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
// URL that is normally cached.
- GURL initial_url = test_server_.GetURL("cachetime");
+ GURL initial_url = http_test_server()->GetURL("/cachetime");
{
// Set up the TestNetworkDelegate tp force a redirect.
- GURL redirect_to_url = test_server_.GetURL("echo");
+ GURL redirect_to_url = http_test_server()->GetURL("/echo");
default_network_delegate_.set_redirect_on_headers_received_url(
redirect_to_url);
@@ -5973,7 +6298,7 @@ TEST_F(URLRequestTestHTTP, NoCacheOnNetworkDelegateRedirect) {
// Tests that redirection to an unsafe URL is allowed when it has been marked as
// safe.
TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
GURL unsafe_url("data:text/html,this-is-considered-an-unsafe-url");
default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url);
@@ -5982,7 +6307,7 @@ TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) {
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/whatever"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -5999,7 +6324,7 @@ TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) {
// Tests that a redirect to a different unsafe URL is blocked, even after adding
// some other URL to the whitelist.
TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
GURL unsafe_url("data:text/html,something");
GURL different_unsafe_url("data:text/html,something-else");
@@ -6010,7 +6335,7 @@ TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) {
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/whatever"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -6023,9 +6348,9 @@ TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) {
// Redirects from an URL with fragment to an unsafe URL with fragment should
// be allowed, and the reference fragment of the target URL should be preserved.
TEST_F(URLRequestTestHTTP, UnsafeRedirectWithDifferentReferenceFragment) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL original_url(test_server_.GetURL("original#fragment1"));
+ GURL original_url(http_test_server()->GetURL("/original#fragment1"));
GURL unsafe_url("data:,url-marked-safe-and-used-in-redirect#fragment2");
GURL expected_url("data:,url-marked-safe-and-used-in-redirect#fragment2");
@@ -6051,12 +6376,13 @@ TEST_F(URLRequestTestHTTP, UnsafeRedirectWithDifferentReferenceFragment) {
// When a delegate has specified a safe redirect URL, but it does not match the
// redirect target, then do not prevent the reference fragment from being added.
TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragmentAndUnrelatedUnsafeUrl) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL original_url(test_server_.GetURL("original#expected-fragment"));
+ GURL original_url(http_test_server()->GetURL("/original#expected-fragment"));
GURL unsafe_url("data:text/html,this-url-does-not-match-redirect-url");
- GURL redirect_url(test_server_.GetURL("target"));
- GURL expected_redirect_url(test_server_.GetURL("target#expected-fragment"));
+ GURL redirect_url(http_test_server()->GetURL("/target"));
+ GURL expected_redirect_url(
+ http_test_server()->GetURL("/target#expected-fragment"));
default_network_delegate_.set_redirect_on_headers_received_url(redirect_url);
default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url);
@@ -6081,9 +6407,10 @@ TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragmentAndUnrelatedUnsafeUrl) {
// URL should not be changed. In particular, the reference fragment should not
// be modified.
TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragment) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL original_url(test_server_.GetURL("original#should-not-be-appended"));
+ GURL original_url(
+ http_test_server()->GetURL("/original#should-not-be-appended"));
GURL redirect_url("data:text/html,expect-no-reference-fragment");
default_network_delegate_.set_redirect_on_headers_received_url(redirect_url);
@@ -6108,19 +6435,20 @@ TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragment) {
// When a URLRequestRedirectJob is created, the redirection must be followed and
// the reference fragment of the target URL must not be modified.
TEST_F(URLRequestTestHTTP, RedirectJobWithReferenceFragment) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL original_url(test_server_.GetURL("original#should-not-be-appended"));
- GURL redirect_url(test_server_.GetURL("echo"));
+ GURL original_url(
+ http_test_server()->GetURL("/original#should-not-be-appended"));
+ GURL redirect_url(http_test_server()->GetURL("/echo"));
TestDelegate d;
scoped_ptr<URLRequest> r(
default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
- URLRequestRedirectJob* job = new URLRequestRedirectJob(
+ scoped_ptr<URLRequestRedirectJob> job(new URLRequestRedirectJob(
r.get(), &default_network_delegate_, redirect_url,
- URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
- AddTestInterceptor()->set_main_intercept_job(job);
+ URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
r->Start();
base::RunLoop().Run();
@@ -6132,11 +6460,11 @@ TEST_F(URLRequestTestHTTP, RedirectJobWithReferenceFragment) {
}
TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Referer"), DEFAULT_PRIORITY, &d));
req->SetReferrer("http://user:pass@foo.com/");
req->Start();
base::RunLoop().Run();
@@ -6145,11 +6473,11 @@ TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) {
}
TEST_F(URLRequestTestHTTP, NoFragmentInReferrer) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Referer"), DEFAULT_PRIORITY, &d));
req->SetReferrer("http://foo.com/test#fragment");
req->Start();
base::RunLoop().Run();
@@ -6158,11 +6486,11 @@ TEST_F(URLRequestTestHTTP, NoFragmentInReferrer) {
}
TEST_F(URLRequestTestHTTP, EmptyReferrerAfterValidReferrer) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Referer"), DEFAULT_PRIORITY, &d));
req->SetReferrer("http://foo.com/test#fragment");
req->SetReferrer("");
req->Start();
@@ -6174,12 +6502,12 @@ TEST_F(URLRequestTestHTTP, EmptyReferrerAfterValidReferrer) {
// Defer network start and then resume, checking that the request was a success
// and bytes were received.
TEST_F(URLRequestTestHTTP, DeferredBeforeNetworkStart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
d.set_quit_on_network_start(true);
- GURL test_url(test_server_.GetURL("echo"));
+ GURL test_url(http_test_server()->GetURL("/echo"));
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
@@ -6201,14 +6529,15 @@ TEST_F(URLRequestTestHTTP, DeferredBeforeNetworkStart) {
// Check that OnBeforeNetworkStart is only called once even if there is a
// redirect.
TEST_F(URLRequestTestHTTP, BeforeNetworkStartCalledOnce) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
d.set_quit_on_redirect(true);
d.set_quit_on_network_start(true);
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("server-redirect?echo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/server-redirect?echo"), DEFAULT_PRIORITY,
+ &d));
req->Start();
base::RunLoop().Run();
@@ -6236,12 +6565,12 @@ TEST_F(URLRequestTestHTTP, BeforeNetworkStartCalledOnce) {
// Cancel the request after learning that the request would use the network.
TEST_F(URLRequestTestHTTP, CancelOnBeforeNetworkStart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
d.set_quit_on_network_start(true);
- GURL test_url(test_server_.GetURL("echo"));
+ GURL test_url(http_test_server()->GetURL("/echo"));
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
@@ -6261,13 +6590,14 @@ TEST_F(URLRequestTestHTTP, CancelOnBeforeNetworkStart) {
}
TEST_F(URLRequestTestHTTP, CancelRedirect) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
d.set_cancel_in_received_redirect(true);
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/redirect-test.html"), DEFAULT_PRIORITY,
+ &d));
req->Start();
base::RunLoop().Run();
@@ -6279,12 +6609,12 @@ TEST_F(URLRequestTestHTTP, CancelRedirect) {
}
TEST_F(URLRequestTestHTTP, DeferredRedirect) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
d.set_quit_on_redirect(true);
- GURL test_url(test_server_.GetURL("files/redirect-test.html"));
+ GURL test_url(http_test_server()->GetURL("/redirect-test.html"));
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
@@ -6312,12 +6642,12 @@ TEST_F(URLRequestTestHTTP, DeferredRedirect) {
}
TEST_F(URLRequestTestHTTP, DeferredRedirect_GetFullRequestHeaders) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
d.set_quit_on_redirect(true);
- GURL test_url(test_server_.GetURL("files/redirect-test.html"));
+ GURL test_url(http_test_server()->GetURL("/redirect-test.html"));
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
@@ -6334,7 +6664,7 @@ TEST_F(URLRequestTestHTTP, DeferredRedirect_GetFullRequestHeaders) {
req->FollowDeferredRedirect();
base::RunLoop().Run();
- GURL target_url(test_server_.GetURL("files/with-headers.html"));
+ GURL target_url(http_test_server()->GetURL("/with-headers.html"));
EXPECT_EQ(1, d.response_started_count());
EXPECT_TRUE(d.have_full_request_headers());
CheckFullRequestHeaders(d.full_request_headers(), target_url);
@@ -6353,13 +6683,14 @@ TEST_F(URLRequestTestHTTP, DeferredRedirect_GetFullRequestHeaders) {
}
TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
{
d.set_quit_on_redirect(true);
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/redirect-test.html"), DEFAULT_PRIORITY,
+ &d));
req->Start();
base::RunLoop().Run();
@@ -6376,13 +6707,14 @@ TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) {
}
TEST_F(URLRequestTestHTTP, VaryHeader) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
// Populate the cache.
{
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheadercache?foo"), DEFAULT_PRIORITY,
+ &d));
HttpRequestHeaders headers;
headers.SetHeader("foo", "1");
req->SetExtraRequestHeaders(headers);
@@ -6398,7 +6730,8 @@ TEST_F(URLRequestTestHTTP, VaryHeader) {
{
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheadercache?foo"), DEFAULT_PRIORITY,
+ &d));
HttpRequestHeaders headers;
headers.SetHeader("foo", "1");
req->SetExtraRequestHeaders(headers);
@@ -6416,7 +6749,8 @@ TEST_F(URLRequestTestHTTP, VaryHeader) {
{
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheadercache?foo"), DEFAULT_PRIORITY,
+ &d));
HttpRequestHeaders headers;
headers.SetHeader("foo", "2");
req->SetExtraRequestHeaders(headers);
@@ -6432,7 +6766,7 @@ TEST_F(URLRequestTestHTTP, VaryHeader) {
}
TEST_F(URLRequestTestHTTP, BasicAuth) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
// populate the cache
{
@@ -6440,7 +6774,7 @@ TEST_F(URLRequestTestHTTP, BasicAuth) {
d.set_credentials(AuthCredentials(kUser, kSecret));
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/auth-basic"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -6456,7 +6790,7 @@ TEST_F(URLRequestTestHTTP, BasicAuth) {
d.set_credentials(AuthCredentials(kUser, kSecret));
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/auth-basic"), DEFAULT_PRIORITY, &d));
r->SetLoadFlags(LOAD_VALIDATE_CACHE);
r->Start();
@@ -6472,10 +6806,10 @@ TEST_F(URLRequestTestHTTP, BasicAuth) {
// Check that Set-Cookie headers in 401 responses are respected.
// http://crbug.com/6450
TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
GURL url_requiring_auth =
- test_server_.GetURL("auth-basic?set-cookie-if-challenged");
+ http_test_server()->GetURL("/auth-basic?set-cookie-if-challenged");
// Request a page that will give a 401 containing a Set-Cookie header.
// Verify that when the transaction is restarted, it includes the new cookie.
@@ -6532,7 +6866,7 @@ TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) {
// Tests that load timing works as expected with auth and the cache.
TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
// populate the cache
{
@@ -6540,7 +6874,7 @@ TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) {
d.set_credentials(AuthCredentials(kUser, kSecret));
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/auth-basic"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -6572,7 +6906,7 @@ TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) {
d.set_credentials(AuthCredentials(kUser, kSecret));
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/auth-basic"), DEFAULT_PRIORITY, &d));
r->SetLoadFlags(LOAD_VALIDATE_CACHE);
r->Start();
@@ -6596,13 +6930,14 @@ TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) {
// Content-Type header.
// http://code.google.com/p/chromium/issues/detail?id=843
TEST_F(URLRequestTestHTTP, Post302RedirectGet) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
const char kData[] = "hello world";
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("files/redirect-to-echoall"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/redirect-to-echoall"), DEFAULT_PRIORITY,
+ &d));
req->set_method("POST");
req->set_upload(CreateSimpleUploadData(kData));
@@ -6644,11 +6979,11 @@ TEST_F(URLRequestTestHTTP, Post302RedirectGet) {
// https://crbug.com/465517.
TEST_F(URLRequestTestHTTP, Redirect301Tests) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- const GURL url = test_server_.GetURL("files/redirect301-to-echo");
+ const GURL url = http_test_server()->GetURL("/redirect301-to-echo");
const GURL https_redirect_url =
- test_server_.GetURL("files/redirect301-to-https");
+ http_test_server()->GetURL("/redirect301-to-https");
HTTPRedirectMethodTest(url, "POST", "GET", true);
HTTPRedirectMethodTest(url, "PUT", "PUT", true);
@@ -6662,11 +6997,11 @@ TEST_F(URLRequestTestHTTP, Redirect301Tests) {
}
TEST_F(URLRequestTestHTTP, Redirect302Tests) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- const GURL url = test_server_.GetURL("files/redirect302-to-echo");
+ const GURL url = http_test_server()->GetURL("/redirect302-to-echo");
const GURL https_redirect_url =
- test_server_.GetURL("files/redirect302-to-https");
+ http_test_server()->GetURL("/redirect302-to-https");
HTTPRedirectMethodTest(url, "POST", "GET", true);
HTTPRedirectMethodTest(url, "PUT", "PUT", true);
@@ -6680,11 +7015,11 @@ TEST_F(URLRequestTestHTTP, Redirect302Tests) {
}
TEST_F(URLRequestTestHTTP, Redirect303Tests) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- const GURL url = test_server_.GetURL("files/redirect303-to-echo");
+ const GURL url = http_test_server()->GetURL("/redirect303-to-echo");
const GURL https_redirect_url =
- test_server_.GetURL("files/redirect303-to-https");
+ http_test_server()->GetURL("/redirect303-to-https");
HTTPRedirectMethodTest(url, "POST", "GET", true);
HTTPRedirectMethodTest(url, "PUT", "GET", true);
@@ -6698,11 +7033,11 @@ TEST_F(URLRequestTestHTTP, Redirect303Tests) {
}
TEST_F(URLRequestTestHTTP, Redirect307Tests) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- const GURL url = test_server_.GetURL("files/redirect307-to-echo");
+ const GURL url = http_test_server()->GetURL("/redirect307-to-echo");
const GURL https_redirect_url =
- test_server_.GetURL("files/redirect307-to-https");
+ http_test_server()->GetURL("/redirect307-to-https");
HTTPRedirectMethodTest(url, "POST", "POST", true);
HTTPRedirectMethodTest(url, "PUT", "PUT", true);
@@ -6715,11 +7050,11 @@ TEST_F(URLRequestTestHTTP, Redirect307Tests) {
}
TEST_F(URLRequestTestHTTP, Redirect308Tests) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- const GURL url = test_server_.GetURL("files/redirect308-to-echo");
+ const GURL url = http_test_server()->GetURL("/redirect308-to-echo");
const GURL https_redirect_url =
- test_server_.GetURL("files/redirect308-to-https");
+ http_test_server()->GetURL("/redirect308-to-https");
HTTPRedirectMethodTest(url, "POST", "POST", true);
HTTPRedirectMethodTest(url, "PUT", "PUT", true);
@@ -6735,10 +7070,10 @@ TEST_F(URLRequestTestHTTP, Redirect308Tests) {
// Certain legacy apis that pre-date the response code expect this behavior
// (Like Google Drive).
TEST_F(URLRequestTestHTTP, NoRedirectOn308WithoutLocationHeader) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
- const GURL url = test_server_.GetURL("files/308-without-location-header");
+ const GURL url = http_test_server()->GetURL("/308-without-location-header");
scoped_ptr<URLRequest> request(
default_context_.CreateRequest(url, DEFAULT_PRIORITY, &d));
@@ -6753,10 +7088,11 @@ TEST_F(URLRequestTestHTTP, NoRedirectOn308WithoutLocationHeader) {
}
TEST_F(URLRequestTestHTTP, Redirect302PreserveReferenceFragment) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL original_url(test_server_.GetURL("files/redirect302-to-echo#fragment"));
- GURL expected_url(test_server_.GetURL("echo#fragment"));
+ GURL original_url(
+ http_test_server()->GetURL("/redirect302-to-echo#fragment"));
+ GURL expected_url(http_test_server()->GetURL("/echo#fragment"));
TestDelegate d;
{
@@ -6775,9 +7111,9 @@ TEST_F(URLRequestTestHTTP, Redirect302PreserveReferenceFragment) {
}
TEST_F(URLRequestTestHTTP, RedirectPreserveFirstPartyURL) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL url(test_server_.GetURL("files/redirect302-to-echo"));
+ GURL url(http_test_server()->GetURL("/redirect302-to-echo"));
GURL first_party_url("http://example.com");
TestDelegate d;
@@ -6797,11 +7133,11 @@ TEST_F(URLRequestTestHTTP, RedirectPreserveFirstPartyURL) {
}
TEST_F(URLRequestTestHTTP, RedirectUpdateFirstPartyURL) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
- GURL url(test_server_.GetURL("files/redirect302-to-echo"));
+ GURL url(http_test_server()->GetURL("/redirect302-to-echo"));
GURL original_first_party_url("http://example.com");
- GURL expected_first_party_url(test_server_.GetURL("echo"));
+ GURL expected_first_party_url(http_test_server()->GetURL("/echo"));
TestDelegate d;
{
@@ -6822,13 +7158,13 @@ TEST_F(URLRequestTestHTTP, RedirectUpdateFirstPartyURL) {
}
TEST_F(URLRequestTestHTTP, InterceptPost302RedirectGet) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
const char kData[] = "hello world";
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
req->set_method("POST");
req->set_upload(CreateSimpleUploadData(kData));
HttpRequestHeaders headers;
@@ -6836,10 +7172,11 @@ TEST_F(URLRequestTestHTTP, InterceptPost302RedirectGet) {
base::SizeTToString(arraysize(kData) - 1));
req->SetExtraRequestHeaders(headers);
- URLRequestRedirectJob* job = new URLRequestRedirectJob(
- req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
- URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
- AddTestInterceptor()->set_main_intercept_job(job);
+ scoped_ptr<URLRequestRedirectJob> job(new URLRequestRedirectJob(
+ req.get(), &default_network_delegate_,
+ http_test_server()->GetURL("/echo"),
+ URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
req->Start();
base::RunLoop().Run();
@@ -6847,13 +7184,13 @@ TEST_F(URLRequestTestHTTP, InterceptPost302RedirectGet) {
}
TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
const char kData[] = "hello world";
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
req->set_method("POST");
req->set_upload(CreateSimpleUploadData(kData));
HttpRequestHeaders headers;
@@ -6861,11 +7198,12 @@ TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) {
base::SizeTToString(arraysize(kData) - 1));
req->SetExtraRequestHeaders(headers);
- URLRequestRedirectJob* job = new URLRequestRedirectJob(
- req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
+ scoped_ptr<URLRequestRedirectJob> job(new URLRequestRedirectJob(
+ req.get(), &default_network_delegate_,
+ http_test_server()->GetURL("/echo"),
URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
- "Very Good Reason");
- AddTestInterceptor()->set_main_intercept_job(job);
+ "Very Good Reason"));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
req->Start();
base::RunLoop().Run();
@@ -6875,7 +7213,7 @@ TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) {
// Check that default A-L header is sent.
TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
StaticHttpUserAgentSettings settings("en", std::string());
TestNetworkDelegate network_delegate; // Must outlive URLRequests.
@@ -6886,7 +7224,8 @@ TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) {
TestDelegate d;
scoped_ptr<URLRequest> req(context.CreateRequest(
- test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Accept-Language"),
+ DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
EXPECT_EQ("en", d.data_received());
@@ -6894,7 +7233,7 @@ TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) {
// Check that an empty A-L header is not sent. http://crbug.com/77365.
TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
std::string empty_string; // Avoid most vexing parse on line below.
StaticHttpUserAgentSettings settings(empty_string, empty_string);
@@ -6908,7 +7247,8 @@ TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) {
TestDelegate d;
scoped_ptr<URLRequest> req(context.CreateRequest(
- test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Accept-Language"),
+ DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
EXPECT_EQ("None", d.data_received());
@@ -6917,11 +7257,12 @@ TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) {
// Check that if request overrides the A-L header, the default is not appended.
// See http://crbug.com/20894
TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Accept-Language"),
+ DEFAULT_PRIORITY, &d));
HttpRequestHeaders headers;
headers.SetHeader(HttpRequestHeaders::kAcceptLanguage, "ru");
req->SetExtraRequestHeaders(headers);
@@ -6932,11 +7273,12 @@ TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) {
// Check that default A-E header is sent.
TEST_F(URLRequestTestHTTP, DefaultAcceptEncoding) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Accept-Encoding"),
+ DEFAULT_PRIORITY, &d));
HttpRequestHeaders headers;
req->SetExtraRequestHeaders(headers);
req->Start();
@@ -6947,11 +7289,12 @@ TEST_F(URLRequestTestHTTP, DefaultAcceptEncoding) {
// Check that if request overrides the A-E header, the default is not appended.
// See http://crbug.com/47381
TEST_F(URLRequestTestHTTP, OverrideAcceptEncoding) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Accept-Encoding"),
+ DEFAULT_PRIORITY, &d));
HttpRequestHeaders headers;
headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, "identity");
req->SetExtraRequestHeaders(headers);
@@ -6963,11 +7306,12 @@ TEST_F(URLRequestTestHTTP, OverrideAcceptEncoding) {
// Check that setting the A-C header sends the proper header.
TEST_F(URLRequestTestHTTP, SetAcceptCharset) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?Accept-Charset"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?Accept-Charset"),
+ DEFAULT_PRIORITY, &d));
HttpRequestHeaders headers;
headers.SetHeader(HttpRequestHeaders::kAcceptCharset, "koi-8r");
req->SetExtraRequestHeaders(headers);
@@ -6978,11 +7322,12 @@ TEST_F(URLRequestTestHTTP, SetAcceptCharset) {
// Check that default User-Agent header is sent.
TEST_F(URLRequestTestHTTP, DefaultUserAgent) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?User-Agent"), DEFAULT_PRIORITY,
+ &d));
req->Start();
base::RunLoop().Run();
EXPECT_EQ(default_context_.http_user_agent_settings()->GetUserAgent(),
@@ -6991,12 +7336,19 @@ TEST_F(URLRequestTestHTTP, DefaultUserAgent) {
// Check that if request overrides the User-Agent header,
// the default is not appended.
-TEST_F(URLRequestTestHTTP, OverrideUserAgent) {
- ASSERT_TRUE(test_server_.Start());
+// TODO(crbug.com/564656) This test is flaky on iOS.
+#if defined(OS_IOS)
+#define MAYBE_OverrideUserAgent FLAKY_OverrideUserAgent
+#else
+#define MAYBE_OverrideUserAgent OverrideUserAgent
+#endif
+TEST_F(URLRequestTestHTTP, MAYBE_OverrideUserAgent) {
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/echoheader?User-Agent"), DEFAULT_PRIORITY,
+ &d));
HttpRequestHeaders headers;
headers.SetHeader(HttpRequestHeaders::kUserAgent, "Lynx (textmode)");
req->SetExtraRequestHeaders(headers);
@@ -7009,7 +7361,7 @@ TEST_F(URLRequestTestHTTP, OverrideUserAgent) {
// User-Agent header to be sent but does not send the Accept-Language and
// Accept-Charset headers.
TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestNetworkDelegate network_delegate; // Must outlive URLRequests.
TestURLRequestContext context(true);
@@ -7022,14 +7374,14 @@ TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) {
struct {
const char* request;
const char* expected_response;
- } tests[] = { { "echoheader?Accept-Language", "None" },
- { "echoheader?Accept-Charset", "None" },
- { "echoheader?User-Agent", "" } };
+ } tests[] = {{"/echoheader?Accept-Language", "None"},
+ {"/echoheader?Accept-Charset", "None"},
+ {"/echoheader?User-Agent", ""}};
for (size_t i = 0; i < arraysize(tests); i++) {
TestDelegate d;
scoped_ptr<URLRequest> req(context.CreateRequest(
- test_server_.GetURL(tests[i].request), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL(tests[i].request), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
EXPECT_EQ(tests[i].expected_response, d.data_received())
@@ -7040,30 +7392,31 @@ TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) {
// Make sure that URLRequest passes on its priority updates to
// newly-created jobs after the first one.
TEST_F(URLRequestTestHTTP, SetSubsequentJobPriority) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
EXPECT_EQ(DEFAULT_PRIORITY, req->priority());
- scoped_refptr<URLRequestRedirectJob> redirect_job =
- new URLRequestRedirectJob(
- req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
- URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
- AddTestInterceptor()->set_main_intercept_job(redirect_job.get());
+ scoped_ptr<URLRequestRedirectJob> redirect_job(new URLRequestRedirectJob(
+ req.get(), &default_network_delegate_,
+ http_test_server()->GetURL("/echo"),
+ URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"));
+ AddTestInterceptor()->set_main_intercept_job(std::move(redirect_job));
req->SetPriority(LOW);
req->Start();
EXPECT_TRUE(req->is_pending());
- scoped_refptr<URLRequestTestJob> job =
- new URLRequestTestJob(req.get(), &default_network_delegate_);
- AddTestInterceptor()->set_main_intercept_job(job.get());
+ RequestPriority job_priority;
+ scoped_ptr<URLRequestJob> job(new PriorityMonitoringURLRequestJob(
+ req.get(), &default_network_delegate_, &job_priority));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
// Should trigger |job| to be started.
base::RunLoop().Run();
- EXPECT_EQ(LOW, job->priority());
+ EXPECT_EQ(LOW, job_priority);
}
// Check that creating a network request while entering/exiting suspend mode
@@ -7071,22 +7424,12 @@ TEST_F(URLRequestTestHTTP, SetSubsequentJobPriority) {
// does not return an HttpTransaction.
TEST_F(URLRequestTestHTTP, NetworkSuspendTest) {
// Create a new HttpNetworkLayer that thinks it's suspended.
- HttpNetworkSession::Params params;
- params.host_resolver = default_context_.host_resolver();
- params.cert_verifier = default_context_.cert_verifier();
- params.transport_security_state = default_context_.transport_security_state();
- params.proxy_service = default_context_.proxy_service();
- params.ssl_config_service = default_context_.ssl_config_service();
- params.http_auth_handler_factory =
- default_context_.http_auth_handler_factory();
- params.network_delegate = &default_network_delegate_;
- params.http_server_properties = default_context_.http_server_properties();
- scoped_ptr<HttpNetworkLayer> network_layer(
- new HttpNetworkLayer(new HttpNetworkSession(params)));
+ scoped_ptr<HttpNetworkLayer> network_layer(new HttpNetworkLayer(
+ default_context_.http_transaction_factory()->GetSession()));
network_layer->OnSuspend();
- HttpCache http_cache(network_layer.release(), default_context_.net_log(),
- HttpCache::DefaultBackend::InMemory(0));
+ HttpCache http_cache(std::move(network_layer),
+ HttpCache::DefaultBackend::InMemory(0), true);
TestURLRequestContext context(true);
context.set_http_transaction_factory(&http_cache);
@@ -7103,44 +7446,75 @@ TEST_F(URLRequestTestHTTP, NetworkSuspendTest) {
EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error());
}
-// Check that creating a network request while entering/exiting suspend mode
-// fails as it should in the case there is no cache. This is the only case
-// where an HttpTransactionFactory does not return an HttpTransaction.
-TEST_F(URLRequestTestHTTP, NetworkSuspendTestNoCache) {
- // Create a new HttpNetworkLayer that thinks it's suspended.
- HttpNetworkSession::Params params;
- params.host_resolver = default_context_.host_resolver();
- params.cert_verifier = default_context_.cert_verifier();
- params.transport_security_state = default_context_.transport_security_state();
- params.proxy_service = default_context_.proxy_service();
- params.ssl_config_service = default_context_.ssl_config_service();
- params.http_auth_handler_factory =
- default_context_.http_auth_handler_factory();
- params.network_delegate = &default_network_delegate_;
- params.http_server_properties = default_context_.http_server_properties();
- HttpNetworkLayer network_layer(new HttpNetworkSession(params));
- network_layer.OnSuspend();
+namespace {
+
+// HttpTransactionFactory that synchronously fails to create transactions.
+class FailingHttpTransactionFactory : public HttpTransactionFactory {
+ public:
+ explicit FailingHttpTransactionFactory(HttpNetworkSession* network_session)
+ : network_session_(network_session) {}
+
+ ~FailingHttpTransactionFactory() override {}
+
+ // HttpTransactionFactory methods:
+ int CreateTransaction(RequestPriority priority,
+ scoped_ptr<HttpTransaction>* trans) override {
+ return ERR_FAILED;
+ }
+ HttpCache* GetCache() override { return nullptr; }
+
+ HttpNetworkSession* GetSession() override { return network_session_; }
+
+ private:
+ HttpNetworkSession* network_session_;
+
+ DISALLOW_COPY_AND_ASSIGN(FailingHttpTransactionFactory);
+};
+
+} // namespace
+
+// Check that when a request that fails to create an HttpTransaction can be
+// cancelled while the failure notification is pending, and doesn't send two
+// failure notifications.
+//
+// This currently only happens when in suspend mode and there's no cache, but
+// just use a special HttpTransactionFactory, to avoid depending on those
+// behaviors.
+TEST_F(URLRequestTestHTTP, NetworkCancelAfterCreateTransactionFailsTest) {
+ FailingHttpTransactionFactory http_transaction_factory(
+ default_context_.http_transaction_factory()->GetSession());
TestURLRequestContext context(true);
- context.set_http_transaction_factory(&network_layer);
+ context.set_http_transaction_factory(&http_transaction_factory);
+ context.set_network_delegate(default_network_delegate());
context.Init();
TestDelegate d;
scoped_ptr<URLRequest> req(
context.CreateRequest(GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d));
+ // Don't send cookies (Collecting cookies is asynchronous, and need request to
+ // try to create an HttpNetworkTransaction synchronously on start).
+ req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES);
req->Start();
+ req->Cancel();
base::RunLoop().Run();
+ // Run pending error task, if there is one.
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(d.request_failed());
- EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
- EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
+
+ // NetworkDelegate should see the cancellation, but not the error.
+ EXPECT_EQ(1, default_network_delegate()->canceled_requests());
+ EXPECT_EQ(0, default_network_delegate()->error_count());
}
TEST_F(URLRequestTestHTTP, NetworkAccessedSetOnNetworkRequest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
- GURL test_url(test_server_.GetURL(std::string()));
+ GURL test_url(http_test_server()->GetURL("/"));
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
@@ -7151,12 +7525,12 @@ TEST_F(URLRequestTestHTTP, NetworkAccessedSetOnNetworkRequest) {
}
TEST_F(URLRequestTestHTTP, NetworkAccessedClearOnCachedResponse) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
// Populate the cache.
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/cachetime"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -7164,7 +7538,7 @@ TEST_F(URLRequestTestHTTP, NetworkAccessedClearOnCachedResponse) {
EXPECT_TRUE(req->response_info().network_accessed);
EXPECT_FALSE(req->response_info().was_cached);
- req = default_context_.CreateRequest(test_server_.GetURL("cachetime"),
+ req = default_context_.CreateRequest(http_test_server()->GetURL("/cachetime"),
DEFAULT_PRIORITY, &d);
req->Start();
base::RunLoop().Run();
@@ -7175,10 +7549,10 @@ TEST_F(URLRequestTestHTTP, NetworkAccessedClearOnCachedResponse) {
}
TEST_F(URLRequestTestHTTP, NetworkAccessedClearOnLoadOnlyFromCache) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
- GURL test_url(test_server_.GetURL(std::string()));
+ GURL test_url(http_test_server()->GetURL("/"));
scoped_ptr<URLRequest> req(
default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
req->SetLoadFlags(LOAD_ONLY_FROM_CACHE);
@@ -7200,7 +7574,7 @@ class URLRequestInterceptorTestHTTP : public URLRequestTestHTTP {
void SetUpFactory() override {
interceptor_ = new MockURLRequestInterceptor();
job_factory_.reset(new URLRequestInterceptingJobFactory(
- job_factory_.Pass(), make_scoped_ptr(interceptor_)));
+ std::move(job_factory_), make_scoped_ptr(interceptor_)));
}
MockURLRequestInterceptor* interceptor() const {
@@ -7217,11 +7591,11 @@ TEST_F(URLRequestInterceptorTestHTTP,
interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers());
interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data());
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context().CreateRequest(
- test_server()->GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/redirect-test.html"), DEFAULT_PRIORITY, &d));
req->Start();
base::RunLoop().Run();
@@ -7248,11 +7622,11 @@ TEST_F(URLRequestInterceptorTestHTTP,
interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
default_network_delegate()->set_can_be_intercepted_on_error(true);
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context().CreateRequest(
- test_server()->GetURL("files/two-content-lengths.html"), DEFAULT_PRIORITY,
+ http_test_server()->GetURL("/two-content-lengths.html"), DEFAULT_PRIORITY,
&d));
req->set_method("GET");
req->Start();
@@ -7281,11 +7655,11 @@ TEST_F(URLRequestInterceptorTestHTTP,
// Intercept with a real URLRequestHttpJob.
interceptor()->set_use_url_request_http_job(true);
- ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(http_test_server()->Start());
TestDelegate d;
scoped_ptr<URLRequest> req(default_context().CreateRequest(
- test_server()->GetURL("files/simple.html"), DEFAULT_PRIORITY, &d));
+ http_test_server()->GetURL("/simple.html"), DEFAULT_PRIORITY, &d));
req->set_method("GET");
req->Start();
base::RunLoop().Run();
@@ -7309,29 +7683,35 @@ class URLRequestTestReferrerPolicy : public URLRequestTest {
public:
URLRequestTestReferrerPolicy() {}
- void InstantiateSameOriginServers(SpawnedTestServer::Type origin_type) {
- origin_server_.reset(new SpawnedTestServer(
- origin_type, SpawnedTestServer::kLocalhost,
- origin_type == SpawnedTestServer::TYPE_HTTPS
- ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
- : base::FilePath(kTestFilePath)));
+ void InstantiateSameOriginServers(net::EmbeddedTestServer::Type type) {
+ origin_server_.reset(new EmbeddedTestServer(type));
+ if (type == net::EmbeddedTestServer::TYPE_HTTPS) {
+ origin_server_->AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ } else {
+ origin_server_->AddDefaultHandlers(base::FilePath(kTestFilePath));
+ }
ASSERT_TRUE(origin_server_->Start());
}
- void InstantiateCrossOriginServers(SpawnedTestServer::Type origin_type,
- SpawnedTestServer::Type destination_type) {
- origin_server_.reset(new SpawnedTestServer(
- origin_type, SpawnedTestServer::kLocalhost,
- origin_type == SpawnedTestServer::TYPE_HTTPS
- ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
- : base::FilePath(kTestFilePath)));
+ void InstantiateCrossOriginServers(net::EmbeddedTestServer::Type origin_type,
+ net::EmbeddedTestServer::Type dest_type) {
+ origin_server_.reset(new EmbeddedTestServer(origin_type));
+ if (origin_type == net::EmbeddedTestServer::TYPE_HTTPS) {
+ origin_server_->AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ } else {
+ origin_server_->AddDefaultHandlers(base::FilePath(kTestFilePath));
+ }
ASSERT_TRUE(origin_server_->Start());
- destination_server_.reset(new SpawnedTestServer(
- destination_type, SpawnedTestServer::kLocalhost,
- destination_type == SpawnedTestServer::TYPE_HTTPS
- ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
- : base::FilePath(kTestFilePath)));
+ destination_server_.reset(new EmbeddedTestServer(dest_type));
+ if (dest_type == net::EmbeddedTestServer::TYPE_HTTPS) {
+ destination_server_->AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ } else {
+ destination_server_->AddDefaultHandlers(base::FilePath(kTestFilePath));
+ }
ASSERT_TRUE(destination_server_->Start());
}
@@ -7342,10 +7722,10 @@ class URLRequestTestReferrerPolicy : public URLRequestTest {
// if the origins are meant to be distinct. Otherwise, we'll use the
// |origin_server_| for both endpoints.
GURL destination_url =
- destination_server_ ? destination_server_->GetURL("echoheader?Referer")
- : origin_server_->GetURL("echoheader?Referer");
+ destination_server_ ? destination_server_->GetURL("/echoheader?Referer")
+ : origin_server_->GetURL("/echoheader?Referer");
GURL origin_url =
- origin_server_->GetURL("server-redirect?" + destination_url.spec());
+ origin_server_->GetURL("/server-redirect?" + destination_url.spec());
TestDelegate d;
scoped_ptr<URLRequest> req(
@@ -7368,175 +7748,151 @@ class URLRequestTestReferrerPolicy : public URLRequestTest {
EXPECT_EQ(expected.spec(), d.data_received());
}
- SpawnedTestServer* origin_server() const { return origin_server_.get(); }
+ EmbeddedTestServer* origin_server() const { return origin_server_.get(); }
private:
- scoped_ptr<SpawnedTestServer> origin_server_;
- scoped_ptr<SpawnedTestServer> destination_server_;
+ scoped_ptr<EmbeddedTestServer> origin_server_;
+ scoped_ptr<EmbeddedTestServer> destination_server_;
};
TEST_F(URLRequestTestReferrerPolicy, HTTPToSameOriginHTTP) {
- InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTP);
+ InstantiateSameOriginServers(net::EmbeddedTestServer::TYPE_HTTP);
VerifyReferrerAfterRedirect(
URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(
URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(
URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
}
-// Can't spin up more than one SpawnedTestServer on Android.
-#if defined(OS_ANDROID)
-#define MAYBE_HTTPToCrossOriginHTTP DISABLED_HTTPToCrosOriginHTTP
-#else
-#define MAYBE_HTTPToCrossOriginHTTP HTTPToCrossOriginHTTP
-#endif
-TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPToCrossOriginHTTP) {
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::TYPE_HTTP);
+TEST_F(URLRequestTestReferrerPolicy, HTTPToCrossOriginHTTP) {
+ InstantiateCrossOriginServers(net::EmbeddedTestServer::TYPE_HTTP,
+ net::EmbeddedTestServer::TYPE_HTTP);
VerifyReferrerAfterRedirect(
URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(
URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL(std::string()));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/"));
VerifyReferrerAfterRedirect(
URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL(std::string()));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/"));
VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
}
TEST_F(URLRequestTestReferrerPolicy, HTTPSToSameOriginHTTPS) {
- InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTPS);
+ InstantiateSameOriginServers(net::EmbeddedTestServer::TYPE_HTTPS);
VerifyReferrerAfterRedirect(
URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(
URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(
URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
}
-// Can't spin up more than one SpawnedTestServer on Android.
-#if defined(OS_ANDROID)
-#define MAYBE_HTTPSToCrossOriginHTTPS DISABLED_HTTPSToCrosOriginHTTPS
-#else
-#define MAYBE_HTTPSToCrossOriginHTTPS HTTPSToCrossOriginHTTPS
-#endif
-TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPSToCrossOriginHTTPS) {
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::TYPE_HTTPS);
+TEST_F(URLRequestTestReferrerPolicy, HTTPSToCrossOriginHTTPS) {
+ InstantiateCrossOriginServers(net::EmbeddedTestServer::TYPE_HTTPS,
+ net::EmbeddedTestServer::TYPE_HTTPS);
VerifyReferrerAfterRedirect(
URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(
URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL(std::string()));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/"));
VerifyReferrerAfterRedirect(
URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL(std::string()));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/"));
VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
}
-// Can't spin up more than one SpawnedTestServer on Android.
-#if defined(OS_ANDROID)
-#define MAYBE_HTTPToHTTPS DISABLED_HTTPToHTTPS
-#else
-#define MAYBE_HTTPToHTTPS HTTPToHTTPS
-#endif
-TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPToHTTPS) {
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP,
- SpawnedTestServer::TYPE_HTTPS);
+TEST_F(URLRequestTestReferrerPolicy, HTTPToHTTPS) {
+ InstantiateCrossOriginServers(net::EmbeddedTestServer::TYPE_HTTP,
+ net::EmbeddedTestServer::TYPE_HTTPS);
VerifyReferrerAfterRedirect(
URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
VerifyReferrerAfterRedirect(
URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL(std::string()));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/"));
VerifyReferrerAfterRedirect(
URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL(std::string()));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/"));
VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
}
-// Can't spin up more than one SpawnedTestServer on Android.
-#if defined(OS_ANDROID)
-#define MAYBE_HTTPSToHTTP DISABLED_HTTPSToHTTP
-#else
-#define MAYBE_HTTPSToHTTP HTTPSToHTTP
-#endif
-TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPSToHTTP) {
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::TYPE_HTTP);
+TEST_F(URLRequestTestReferrerPolicy, HTTPSToHTTP) {
+ InstantiateCrossOriginServers(net::EmbeddedTestServer::TYPE_HTTPS,
+ net::EmbeddedTestServer::TYPE_HTTP);
VerifyReferrerAfterRedirect(
URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
- origin_server()->GetURL("path/to/file.html"), GURL());
+ origin_server()->GetURL("/path/to/file.html"), GURL());
VerifyReferrerAfterRedirect(
URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"), GURL());
+ origin_server()->GetURL("/path/to/file.html"), GURL());
VerifyReferrerAfterRedirect(
URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL(std::string()));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/"));
VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
- origin_server()->GetURL("path/to/file.html"),
- origin_server()->GetURL("path/to/file.html"));
+ origin_server()->GetURL("/path/to/file.html"),
+ origin_server()->GetURL("/path/to/file.html"));
}
class HTTPSRequestTest : public testing::Test {
@@ -7553,16 +7909,15 @@ class HTTPSRequestTest : public testing::Test {
};
TEST_F(HTTPSRequestTest, HTTPSGetTest) {
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(test_server.Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -7580,11 +7935,9 @@ TEST_F(HTTPSRequestTest, HTTPSGetTest) {
}
TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+ test_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(test_server.Start());
@@ -7594,7 +7947,7 @@ TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
{
d.set_allow_certificate_errors(err_allowed);
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -7615,11 +7968,9 @@ TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
}
TEST_F(HTTPSRequestTest, HTTPSExpiredTest) {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_EXPIRED);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
+ test_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(test_server.Start());
@@ -7631,7 +7982,7 @@ TEST_F(HTTPSRequestTest, HTTPSExpiredTest) {
{
d.set_allow_certificate_errors(err_allowed);
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -7651,55 +8002,16 @@ TEST_F(HTTPSRequestTest, HTTPSExpiredTest) {
}
}
-// Tests that servers which require a deprecated cipher suite still work.
-TEST_F(HTTPSRequestTest, CipherFallbackTest) {
- TestNetLog net_log;
- default_context_.set_net_log(&net_log);
-
- SpawnedTestServer::SSLOptions ssl_options;
- ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_RC4;
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options,
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
- ASSERT_TRUE(test_server.Start());
-
- TestDelegate d;
- scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
- r->Start();
- EXPECT_TRUE(r->is_pending());
-
- base::RunLoop().Run();
-
- EXPECT_EQ(1, d.response_started_count());
- EXPECT_FALSE(d.received_data_before_response());
- EXPECT_NE(0, d.bytes_received());
- CheckSSLInfo(r->ssl_info());
- EXPECT_EQ(test_server.host_port_pair().host(), r->GetSocketAddress().host());
- EXPECT_EQ(test_server.host_port_pair().port(), r->GetSocketAddress().port());
-
- // No version downgrade should have been necessary.
- EXPECT_FALSE(r->ssl_info().connection_status &
- SSL_CONNECTION_VERSION_FALLBACK);
- EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_2,
- SSLConnectionStatusToVersion(r->ssl_info().connection_status));
-
- TestNetLogEntry::List entries;
- net_log.GetEntries(&entries);
- ExpectLogContainsSomewhere(entries, 0, NetLog::TYPE_SSL_CIPHER_FALLBACK,
- NetLog::PHASE_NONE);
-}
-
+// TODO(svaldez): iOS tests are flaky with EmbeddedTestServer and transport
+// security state. (see http://crbug.com/550977).
+#if !defined(OS_IOS)
// This tests that a load of www.google.com with a certificate error sets
// the |certificate_errors_are_fatal| flag correctly. This flag will cause
// the interstitial to be fatal.
TEST_F(HTTPSRequestTest, HTTPSPreloadedHSTSTest) {
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+ test_server.ServeFilesFromSourceDirectory("net/data/ssl");
ASSERT_TRUE(test_server.Start());
// We require that the URL be www.google.com in order to pick up the
@@ -7738,12 +8050,9 @@ TEST_F(HTTPSRequestTest, HTTPSPreloadedHSTSTest) {
TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) {
// The actual problem -- CERT_MISMATCHED_NAME in this case -- doesn't
// matter. It just has to be any error.
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+ test_server.ServeFilesFromSourceDirectory("net/data/ssl");
ASSERT_TRUE(test_server.Start());
// We require that the URL be www.google.com in order to pick up the static
@@ -7815,18 +8124,15 @@ TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) {
TEST_F(HTTPSRequestTest, HSTSPreservesPosts) {
static const char kData[] = "hello world";
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_OK);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(test_server.Start());
// Per spec, TransportSecurityState expects a domain name, rather than an IP
// address, so a MockHostResolver is needed to redirect www.somewhere.com to
- // the SpawnedTestServer. By default, MockHostResolver maps all hosts
+ // the EmbeddedTestServer. By default, MockHostResolver maps all hosts
// to 127.0.0.1.
MockHostResolver host_resolver;
@@ -7874,17 +8180,14 @@ TEST_F(HTTPSRequestTest, HSTSPreservesPosts) {
TEST_F(HTTPSRequestTest, HSTSCrossOriginAddHeaders) {
static const char kOriginHeaderValue[] = "http://www.example.com";
- SpawnedTestServer::SSLOptions ssl_options(
- SpawnedTestServer::SSLOptions::CERT_OK);
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.ServeFilesFromSourceDirectory("net/data/ssl");
ASSERT_TRUE(test_server.Start());
// Per spec, TransportSecurityState expects a domain name, rather than an IP
// address, so a MockHostResolver is needed to redirect example.net to the
- // SpawnedTestServer. MockHostResolver maps all hosts to 127.0.0.1 by default.
+ // EmbeddedTestServer. MockHostResolver maps all hosts to 127.0.0.1 by
+ // default.
MockHostResolver host_resolver;
TransportSecurityState transport_security_state;
@@ -7967,7 +8270,7 @@ class SSLClientAuthTestDelegate : public TestDelegate {
void OnCertificateRequested(URLRequest* request,
SSLCertRequestInfo* cert_request_info) override {
on_certificate_requested_count_++;
- base::MessageLoop::current()->Quit();
+ base::MessageLoop::current()->QuitWhenIdle();
}
int on_certificate_requested_count() {
return on_certificate_requested_count_;
@@ -7984,18 +8287,18 @@ class SSLClientAuthTestDelegate : public TestDelegate {
// - Getting a certificate request in an SSL renegotiation sending the
// HTTP request.
TEST_F(HTTPSRequestTest, ClientAuthTest) {
- SpawnedTestServer::SSLOptions ssl_options;
- ssl_options.request_client_certificate = true;
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- ssl_options,
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ net::SSLServerConfig ssl_config;
+ ssl_config.require_client_cert = true;
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
+ test_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(test_server.Start());
SSLClientAuthTestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/defaultresponse"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -8009,7 +8312,7 @@ TEST_F(HTTPSRequestTest, ClientAuthTest) {
// Send no certificate.
// TODO(davidben): Get temporary client cert import (with keys) working on
// all platforms so we can test sending a cert as well.
- r->ContinueWithCertificate(NULL);
+ r->ContinueWithCertificate(nullptr, nullptr);
base::RunLoop().Run();
@@ -8147,11 +8450,10 @@ TEST_F(HTTPSRequestTest, SSLSessionCacheShardTest) {
default_context_.http_auth_handler_factory();
params.network_delegate = &default_network_delegate_;
params.http_server_properties = default_context_.http_server_properties();
- params.ssl_session_cache_shard = "alternate";
+ HttpNetworkSession network_session(params);
scoped_ptr<HttpCache> cache(new HttpCache(
- new HttpNetworkSession(params),
- HttpCache::DefaultBackend::InMemory(0)));
+ &network_session, HttpCache::DefaultBackend::InMemory(0), false));
default_context_.set_http_transaction_factory(cache.get());
@@ -8200,15 +8502,13 @@ TEST_F(HTTPSRequestTest, DisableECDSAOnXP) {
return;
}
- SpawnedTestServer test_server(
- SpawnedTestServer::TYPE_HTTPS,
- SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.ServeFilesFromSourceDirectory("net/data/ssl");
ASSERT_TRUE(test_server.Start());
TestDelegate d;
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server.GetURL("client-cipher-list"), DEFAULT_PRIORITY, &d));
+ test_server.GetURL("/client-cipher-list"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -8240,11 +8540,9 @@ class TestSSLConfigService : public SSLConfigService {
min_version_(kDefaultSSLVersionMin),
fallback_min_version_(kDefaultSSLVersionFallbackMin) {}
- void set_min_version(uint16 version) {
- min_version_ = version;
- }
+ void set_min_version(uint16_t version) { min_version_ = version; }
- void set_fallback_min_version(uint16 version) {
+ void set_fallback_min_version(uint16_t version) {
fallback_min_version_ = version;
}
@@ -8270,8 +8568,8 @@ class TestSSLConfigService : public SSLConfigService {
const bool ev_enabled_;
const bool online_rev_checking_;
const bool rev_checking_required_local_anchors_;
- uint16 min_version_;
- uint16 fallback_min_version_;
+ uint16_t min_version_;
+ uint16_t fallback_min_version_;
};
class FallbackTestURLRequestContext : public TestURLRequestContext {
@@ -8279,7 +8577,7 @@ class FallbackTestURLRequestContext : public TestURLRequestContext {
explicit FallbackTestURLRequestContext(bool delay_initialization)
: TestURLRequestContext(delay_initialization) {}
- void set_fallback_min_version(uint16 version) {
+ void set_fallback_min_version(uint16_t version) {
TestSSLConfigService *ssl_config_service =
new TestSSLConfigService(true /* check for EV */,
false /* online revocation checking */,
@@ -8307,14 +8605,14 @@ class HTTPSFallbackTest : public testing::Test {
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(test_server.Start());
- request_ = context_.CreateRequest(test_server.GetURL(std::string()),
- DEFAULT_PRIORITY, &delegate_);
+ request_ = context_.CreateRequest(test_server.GetURL("/"), DEFAULT_PRIORITY,
+ &delegate_);
request_->Start();
base::RunLoop().Run();
}
- void set_fallback_min_version(uint16 version) {
+ void set_fallback_min_version(uint16_t version) {
context_.set_fallback_min_version(version);
}
@@ -8463,7 +8761,7 @@ TEST_F(HTTPSRequestTest, FallbackProbeNoCache) {
context.set_fallback_min_version(SSL_PROTOCOL_VERSION_TLS1_2);
context.Init();
scoped_ptr<URLRequest> request(context.CreateRequest(
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &delegate));
+ test_server.GetURL("/"), DEFAULT_PRIORITY, &delegate));
request->Start();
base::RunLoop().Run();
@@ -8638,8 +8936,8 @@ class HTTPSOCSPTest : public HTTPSRequestTest {
TestDelegate d;
d.set_allow_certificate_errors(true);
- scoped_ptr<URLRequest> r(context_.CreateRequest(
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
+ scoped_ptr<URLRequest> r(
+ context_.CreateRequest(test_server.GetURL("/"), DEFAULT_PRIORITY, &d));
r->Start();
base::RunLoop().Run();
@@ -9135,9 +9433,9 @@ class URLRequestTestFTP : public URLRequestTest {
public:
URLRequestTestFTP()
: ftp_transaction_factory_(&host_resolver_),
- test_server_(SpawnedTestServer::TYPE_FTP,
- SpawnedTestServer::kLocalhost,
- base::FilePath(kTestFilePath)) {
+ ftp_test_server_(SpawnedTestServer::TYPE_FTP,
+ SpawnedTestServer::kLocalhost,
+ base::FilePath(kTestFilePath)) {
// Can't use |default_context_|'s HostResolver to set up the
// FTPTransactionFactory because it hasn't been created yet.
default_context_.set_host_resolver(&host_resolver_);
@@ -9165,7 +9463,7 @@ class URLRequestTestFTP : public URLRequestTest {
MockHostResolver host_resolver_;
FtpNetworkLayer ftp_transaction_factory_;
- SpawnedTestServer test_server_;
+ SpawnedTestServer ftp_test_server_;
};
// Make sure an FTP request using an unsafe ports fails.
@@ -9188,12 +9486,12 @@ TEST_F(URLRequestTestFTP, UnsafePort) {
}
TEST_F(URLRequestTestFTP, FTPDirectoryListing) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL("/"), DEFAULT_PRIORITY, &d));
+ ftp_test_server_.GetURL("/"), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9203,20 +9501,20 @@ TEST_F(URLRequestTestFTP, FTPDirectoryListing) {
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_LT(0, d.bytes_received());
- EXPECT_EQ(test_server_.host_port_pair().host(),
+ EXPECT_EQ(ftp_test_server_.host_port_pair().host(),
r->GetSocketAddress().host());
- EXPECT_EQ(test_server_.host_port_pair().port(),
+ EXPECT_EQ(ftp_test_server_.host_port_pair().port(),
r->GetSocketAddress().port());
}
}
TEST_F(URLRequestTestFTP, FTPGetTestAnonymous) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, &d));
+ ftp_test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9226,22 +9524,22 @@ TEST_F(URLRequestTestFTP, FTPGetTestAnonymous) {
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_EQ(GetTestFileContents(), d.data_received());
- EXPECT_EQ(test_server_.host_port_pair().host(),
+ EXPECT_EQ(ftp_test_server_.host_port_pair().host(),
r->GetSocketAddress().host());
- EXPECT_EQ(test_server_.host_port_pair().port(),
+ EXPECT_EQ(ftp_test_server_.host_port_pair().port(),
r->GetSocketAddress().port());
}
}
TEST_F(URLRequestTestFTP, FTPGetTest) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
TestDelegate d;
{
- scoped_ptr<URLRequest> r(
- default_context_.CreateRequest(test_server_.GetURLWithUserAndPassword(
- kFtpTestFile, "chrome", "chrome"),
- DEFAULT_PRIORITY, &d));
+ scoped_ptr<URLRequest> r(default_context_.CreateRequest(
+ ftp_test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
+ "chrome"),
+ DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9251,9 +9549,9 @@ TEST_F(URLRequestTestFTP, FTPGetTest) {
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_EQ(GetTestFileContents(), d.data_received());
- EXPECT_EQ(test_server_.host_port_pair().host(),
+ EXPECT_EQ(ftp_test_server_.host_port_pair().host(),
r->GetSocketAddress().host());
- EXPECT_EQ(test_server_.host_port_pair().port(),
+ EXPECT_EQ(ftp_test_server_.host_port_pair().port(),
r->GetSocketAddress().port());
LoadTimingInfo load_timing_info;
@@ -9263,13 +9561,13 @@ TEST_F(URLRequestTestFTP, FTPGetTest) {
}
TEST_F(URLRequestTestFTP, FTPCheckWrongPassword) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
- "wrong_password"),
+ ftp_test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
+ "wrong_password"),
DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9284,7 +9582,7 @@ TEST_F(URLRequestTestFTP, FTPCheckWrongPassword) {
}
TEST_F(URLRequestTestFTP, FTPCheckWrongPasswordRestart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
TestDelegate d;
// Set correct login credentials. The delegate will be asked for them when
@@ -9292,8 +9590,8 @@ TEST_F(URLRequestTestFTP, FTPCheckWrongPasswordRestart) {
d.set_credentials(AuthCredentials(kChrome, kChrome));
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
- "wrong_password"),
+ ftp_test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
+ "wrong_password"),
DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9308,13 +9606,13 @@ TEST_F(URLRequestTestFTP, FTPCheckWrongPasswordRestart) {
}
TEST_F(URLRequestTestFTP, FTPCheckWrongUser) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
TestDelegate d;
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURLWithUserAndPassword(kFtpTestFile, "wrong_user",
- "chrome"),
+ ftp_test_server_.GetURLWithUserAndPassword(kFtpTestFile, "wrong_user",
+ "chrome"),
DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9329,7 +9627,7 @@ TEST_F(URLRequestTestFTP, FTPCheckWrongUser) {
}
TEST_F(URLRequestTestFTP, FTPCheckWrongUserRestart) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
TestDelegate d;
// Set correct login credentials. The delegate will be asked for them when
@@ -9337,8 +9635,8 @@ TEST_F(URLRequestTestFTP, FTPCheckWrongUserRestart) {
d.set_credentials(AuthCredentials(kChrome, kChrome));
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURLWithUserAndPassword(kFtpTestFile, "wrong_user",
- "chrome"),
+ ftp_test_server_.GetURLWithUserAndPassword(kFtpTestFile, "wrong_user",
+ "chrome"),
DEFAULT_PRIORITY, &d));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9353,15 +9651,15 @@ TEST_F(URLRequestTestFTP, FTPCheckWrongUserRestart) {
}
TEST_F(URLRequestTestFTP, FTPCacheURLCredentials) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
scoped_ptr<TestDelegate> d(new TestDelegate);
{
// Pass correct login identity in the URL.
- scoped_ptr<URLRequest> r(
- default_context_.CreateRequest(test_server_.GetURLWithUserAndPassword(
- kFtpTestFile, "chrome", "chrome"),
- DEFAULT_PRIORITY, d.get()));
+ scoped_ptr<URLRequest> r(default_context_.CreateRequest(
+ ftp_test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
+ "chrome"),
+ DEFAULT_PRIORITY, d.get()));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9377,7 +9675,7 @@ TEST_F(URLRequestTestFTP, FTPCacheURLCredentials) {
{
// This request should use cached identity from previous request.
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, d.get()));
+ ftp_test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, d.get()));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9391,7 +9689,7 @@ TEST_F(URLRequestTestFTP, FTPCacheURLCredentials) {
}
TEST_F(URLRequestTestFTP, FTPCacheLoginBoxCredentials) {
- ASSERT_TRUE(test_server_.Start());
+ ASSERT_TRUE(ftp_test_server_.Start());
scoped_ptr<TestDelegate> d(new TestDelegate);
// Set correct login credentials. The delegate will be asked for them when
@@ -9399,8 +9697,8 @@ TEST_F(URLRequestTestFTP, FTPCacheLoginBoxCredentials) {
d->set_credentials(AuthCredentials(kChrome, kChrome));
{
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
- "wrong_password"),
+ ftp_test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
+ "wrong_password"),
DEFAULT_PRIORITY, d.get()));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9420,7 +9718,7 @@ TEST_F(URLRequestTestFTP, FTPCacheLoginBoxCredentials) {
// Don't pass wrong credentials in the URL, they would override valid cached
// ones.
scoped_ptr<URLRequest> r(default_context_.CreateRequest(
- test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, d.get()));
+ ftp_test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, d.get()));
r->Start();
EXPECT_TRUE(r->is_pending());
@@ -9487,23 +9785,21 @@ TEST_F(URLRequestTest, NetworkAccessedSetOnHostResolutionFailure) {
EXPECT_TRUE(req->response_info().network_accessed);
}
-// Test that URLRequest is canceled correctly and with detached request
-// URLRequestRedirectJob does not crash in StartAsync.
+// Test that URLRequest is canceled correctly.
// See http://crbug.com/508900
-TEST_F(URLRequestTest, URLRequestRedirectJobDetachRequestNoCrash) {
+TEST_F(URLRequestTest, URLRequestRedirectJobCancelRequest) {
TestDelegate d;
scoped_ptr<URLRequest> req(default_context_.CreateRequest(
GURL("http://not-a-real-domain/"), DEFAULT_PRIORITY, &d));
- URLRequestRedirectJob* job = new URLRequestRedirectJob(
+ scoped_ptr<URLRequestRedirectJob> job(new URLRequestRedirectJob(
req.get(), &default_network_delegate_,
GURL("http://this-should-never-be-navigated-to/"),
- URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "Jumbo shrimp");
- AddTestInterceptor()->set_main_intercept_job(job);
+ URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "Jumbo shrimp"));
+ AddTestInterceptor()->set_main_intercept_job(std::move(job));
req->Start();
req->Cancel();
- job->DetachRequest();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
EXPECT_EQ(0, d.received_redirect_count());
diff --git a/chromium/net/url_request/view_cache_helper.h b/chromium/net/url_request/view_cache_helper.h
index 18db22e29ce..4ab0031fe42 100644
--- a/chromium/net/url_request/view_cache_helper.h
+++ b/chromium/net/url_request/view_cache_helper.h
@@ -5,8 +5,11 @@
#ifndef NET_URL_REQUEST_VIEW_CACHE_HELPER_H_
#define NET_URL_REQUEST_VIEW_CACHE_HELPER_H_
+#include <stddef.h>
+
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
diff --git a/chromium/net/url_request/view_cache_helper_unittest.cc b/chromium/net/url_request/view_cache_helper_unittest.cc
index 284482ac988..96717006259 100644
--- a/chromium/net/url_request/view_cache_helper_unittest.cc
+++ b/chromium/net/url_request/view_cache_helper_unittest.cc
@@ -31,8 +31,9 @@ class TestURLRequestContext : public URLRequestContext {
};
TestURLRequestContext::TestURLRequestContext()
- : cache_(new MockNetworkLayer(), NULL,
- HttpCache::DefaultBackend::InMemory(0)) {
+ : cache_(make_scoped_ptr(new MockNetworkLayer()),
+ HttpCache::DefaultBackend::InMemory(0),
+ true) {
set_http_transaction_factory(&cache_);
}
diff --git a/chromium/net/websockets/websocket_basic_handshake_stream.cc b/chromium/net/websockets/websocket_basic_handshake_stream.cc
index a909892ae94..92af20cb2d8 100644
--- a/chromium/net/websockets/websocket_basic_handshake_stream.cc
+++ b/chromium/net/websockets/websocket_basic_handshake_stream.cc
@@ -4,14 +4,15 @@
#include "net/websockets/websocket_basic_handshake_stream.h"
+#include <stddef.h>
#include <algorithm>
#include <iterator>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "base/base64.h"
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
@@ -357,7 +358,7 @@ int WebSocketBasicHandshakeStream::SendRequest(
scoped_ptr<WebSocketHandshakeRequestInfo> request(
new WebSocketHandshakeRequestInfo(url_, base::Time::Now()));
request->headers.CopyFrom(enriched_headers);
- connect_delegate_->OnStartOpeningHandshake(request.Pass());
+ connect_delegate_->OnStartOpeningHandshake(std::move(request));
return parser()->SendRequest(
state_.GenerateRequestLine(), enriched_headers, response, callback);
@@ -438,6 +439,11 @@ bool WebSocketBasicHandshakeStream::GetRemoteEndpoint(IPEndPoint* endpoint) {
return state_.connection()->socket()->GetPeerAddress(endpoint) == OK;
}
+void WebSocketBasicHandshakeStream::PopulateNetErrorDetails(
+ NetErrorDetails* /*details*/) {
+ return;
+}
+
void WebSocketBasicHandshakeStream::Drain(HttpNetworkSession* session) {
HttpResponseBodyDrainer* drainer = new HttpResponseBodyDrainer(this);
drainer->Start(session);
@@ -476,11 +482,11 @@ scoped_ptr<WebSocketStream> WebSocketBasicHandshakeStream::Upgrade() {
WebSocketDeflater::NUM_CONTEXT_TAKEOVER_MODE_TYPES);
return scoped_ptr<WebSocketStream>(new WebSocketDeflateStream(
- basic_stream.Pass(), extension_params_->deflate_parameters,
+ std::move(basic_stream), extension_params_->deflate_parameters,
scoped_ptr<WebSocketDeflatePredictor>(
new WebSocketDeflatePredictorImpl)));
} else {
- return basic_stream.Pass();
+ return basic_stream;
}
}
diff --git a/chromium/net/websockets/websocket_basic_handshake_stream.h b/chromium/net/websockets/websocket_basic_handshake_stream.h
index 1984f3cc60e..d84ef22bc8f 100644
--- a/chromium/net/websockets/websocket_basic_handshake_stream.h
+++ b/chromium/net/websockets/websocket_basic_handshake_stream.h
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -65,6 +66,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
bool GetRemoteEndpoint(IPEndPoint* endpoint) override;
void Drain(HttpNetworkSession* session) override;
void SetPriority(RequestPriority priority) override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) override;
UploadProgress GetUploadProgress() const override;
HttpStream* RenewStreamForAuth() override;
diff --git a/chromium/net/websockets/websocket_basic_stream.cc b/chromium/net/websockets/websocket_basic_stream.cc
index 54f3cbf7a98..c54ef71611e 100644
--- a/chromium/net/websockets/websocket_basic_stream.cc
+++ b/chromium/net/websockets/websocket_basic_stream.cc
@@ -4,12 +4,14 @@
#include "net/websockets/websocket_basic_stream.h"
+#include <stddef.h>
+#include <stdint.h>
#include <algorithm>
#include <limits>
#include <string>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
@@ -24,9 +26,9 @@ namespace net {
namespace {
-// This uses type uint64 to match the definition of
+// This uses type uint64_t to match the definition of
// WebSocketFrameHeader::payload_length in websocket_frame.h.
-const uint64 kMaxControlFramePayload = 125;
+const uint64_t kMaxControlFramePayload = 125;
// The number of bytes to attempt to read at a time.
// TODO(ricea): See if there is a better number or algorithm to fulfill our
@@ -40,24 +42,21 @@ const uint64 kMaxControlFramePayload = 125;
// packet sizes / encryption block sizes / IPC alignment issues, etc.
const int kReadBufferSize = 32 * 1024;
-typedef ScopedVector<WebSocketFrame>::const_iterator WebSocketFrameIterator;
-
// Returns the total serialized size of |frames|. This function assumes that
// |frames| will be serialized with mask field. This function forces the
// masked bit of the frames on.
int CalculateSerializedSizeAndTurnOnMaskBit(
- ScopedVector<WebSocketFrame>* frames) {
- const uint64 kMaximumTotalSize = std::numeric_limits<int>::max();
+ std::vector<scoped_ptr<WebSocketFrame>>* frames) {
+ const uint64_t kMaximumTotalSize = std::numeric_limits<int>::max();
- uint64 total_size = 0;
- for (WebSocketFrameIterator it = frames->begin(); it != frames->end(); ++it) {
- WebSocketFrame* frame = *it;
+ uint64_t total_size = 0;
+ for (const auto& frame : *frames) {
// Force the masked bit on.
frame->header.masked = true;
// We enforce flow control so the renderer should never be able to force us
// to cache anywhere near 2GB of frames.
- uint64 frame_size = frame->header.payload_length +
- GetWebSocketFrameHeaderSize(frame->header);
+ uint64_t frame_size = frame->header.payload_length +
+ GetWebSocketFrameHeaderSize(frame->header);
CHECK_LE(frame_size, kMaximumTotalSize - total_size)
<< "Aborting to prevent overflow";
total_size += frame_size;
@@ -73,7 +72,7 @@ WebSocketBasicStream::WebSocketBasicStream(
const std::string& sub_protocol,
const std::string& extensions)
: read_buffer_(new IOBufferWithSize(kReadBufferSize)),
- connection_(connection.Pass()),
+ connection_(std::move(connection)),
http_read_buffer_(http_read_buffer),
sub_protocol_(sub_protocol),
extensions_(extensions),
@@ -86,8 +85,9 @@ WebSocketBasicStream::WebSocketBasicStream(
WebSocketBasicStream::~WebSocketBasicStream() { Close(); }
-int WebSocketBasicStream::ReadFrames(ScopedVector<WebSocketFrame>* frames,
- const CompletionCallback& callback) {
+int WebSocketBasicStream::ReadFrames(
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
+ const CompletionCallback& callback) {
DCHECK(frames->empty());
// If there is data left over after parsing the HTTP headers, attempt to parse
// it as WebSocket frames.
@@ -98,7 +98,7 @@ int WebSocketBasicStream::ReadFrames(ScopedVector<WebSocketFrame>* frames,
scoped_refptr<GrowableIOBuffer> buffered_data;
buffered_data.swap(http_read_buffer_);
DCHECK(http_read_buffer_.get() == NULL);
- ScopedVector<WebSocketFrameChunk> frame_chunks;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frame_chunks;
if (!parser_.Decode(buffered_data->StartOfBuffer(),
buffered_data->offset(),
&frame_chunks))
@@ -132,8 +132,9 @@ int WebSocketBasicStream::ReadFrames(ScopedVector<WebSocketFrame>* frames,
}
}
-int WebSocketBasicStream::WriteFrames(ScopedVector<WebSocketFrame>* frames,
- const CompletionCallback& callback) {
+int WebSocketBasicStream::WriteFrames(
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
+ const CompletionCallback& callback) {
// This function always concatenates all frames into a single buffer.
// TODO(ricea): Investigate whether it would be better in some cases to
// perform multiple writes with smaller buffers.
@@ -145,8 +146,7 @@ int WebSocketBasicStream::WriteFrames(ScopedVector<WebSocketFrame>* frames,
char* dest = combined_buffer->data();
int remaining_size = total_size;
- for (WebSocketFrameIterator it = frames->begin(); it != frames->end(); ++it) {
- WebSocketFrame* frame = *it;
+ for (const auto& frame : *frames) {
WebSocketMaskingKey mask = generate_websocket_masking_key_();
int result =
WriteWebSocketFrameHeader(frame->header, &mask, dest, remaining_size);
@@ -157,7 +157,8 @@ int WebSocketBasicStream::WriteFrames(ScopedVector<WebSocketFrame>* frames,
dest += result;
remaining_size -= result;
- CHECK_LE(frame->header.payload_length, static_cast<uint64>(remaining_size));
+ CHECK_LE(frame->header.payload_length,
+ static_cast<uint64_t>(remaining_size));
const int frame_size = static_cast<int>(frame->header.payload_length);
if (frame_size > 0) {
const char* const frame_data = frame->data->data();
@@ -191,9 +192,9 @@ WebSocketBasicStream::CreateWebSocketBasicStreamForTesting(
const std::string& extensions,
WebSocketMaskingKeyGeneratorFunction key_generator_function) {
scoped_ptr<WebSocketBasicStream> stream(new WebSocketBasicStream(
- connection.Pass(), http_read_buffer, sub_protocol, extensions));
+ std::move(connection), http_read_buffer, sub_protocol, extensions));
stream->generate_websocket_masking_key_ = key_generator_function;
- return stream.Pass();
+ return stream;
}
int WebSocketBasicStream::WriteEverything(
@@ -237,14 +238,14 @@ void WebSocketBasicStream::OnWriteComplete(
int WebSocketBasicStream::HandleReadResult(
int result,
- ScopedVector<WebSocketFrame>* frames) {
+ std::vector<scoped_ptr<WebSocketFrame>>* frames) {
DCHECK_NE(ERR_IO_PENDING, result);
DCHECK(frames->empty());
if (result < 0)
return result;
if (result == 0)
return ERR_CONNECTION_CLOSED;
- ScopedVector<WebSocketFrameChunk> frame_chunks;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frame_chunks;
if (!parser_.Decode(read_buffer_->data(), result, &frame_chunks))
return WebSocketErrorToNetError(parser_.websocket_error());
if (frame_chunks.empty())
@@ -253,21 +254,17 @@ int WebSocketBasicStream::HandleReadResult(
}
int WebSocketBasicStream::ConvertChunksToFrames(
- ScopedVector<WebSocketFrameChunk>* frame_chunks,
- ScopedVector<WebSocketFrame>* frames) {
+ std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames) {
for (size_t i = 0; i < frame_chunks->size(); ++i) {
scoped_ptr<WebSocketFrame> frame;
- int result = ConvertChunkToFrame(
- scoped_ptr<WebSocketFrameChunk>((*frame_chunks)[i]), &frame);
- (*frame_chunks)[i] = NULL;
+ int result = ConvertChunkToFrame(std::move((*frame_chunks)[i]), &frame);
if (result != OK)
return result;
if (frame)
- frames->push_back(frame.Pass());
+ frames->push_back(std::move(frame));
}
- // All the elements of |frame_chunks| are now NULL, so there is no point in
- // calling delete on them all.
- frame_chunks->weak_clear();
+ frame_chunks->clear();
if (frames->empty())
return ERR_IO_PENDING;
return OK;
@@ -349,10 +346,10 @@ int WebSocketBasicStream::ConvertChunkToFrame(
// header. A check for exact equality can only be used when the whole frame
// arrives in one chunk.
DCHECK_GE(current_frame_header_->payload_length,
- base::checked_cast<uint64>(chunk_size));
+ base::checked_cast<uint64_t>(chunk_size));
DCHECK(!is_first_chunk || !is_final_chunk ||
current_frame_header_->payload_length ==
- base::checked_cast<uint64>(chunk_size));
+ base::checked_cast<uint64_t>(chunk_size));
// Convert the chunk to a complete frame.
*frame = CreateFrame(is_final_chunk, data_buffer);
@@ -393,7 +390,7 @@ scoped_ptr<WebSocketFrame> WebSocketBasicStream::CreateFrame(
// belong to it.
if (is_final_chunk)
current_frame_header_.reset();
- return result_frame.Pass();
+ return result_frame;
}
void WebSocketBasicStream::AddToIncompleteControlFrameBody(
@@ -411,9 +408,10 @@ void WebSocketBasicStream::AddToIncompleteControlFrameBody(
incomplete_control_frame_body_->set_offset(new_offset);
}
-void WebSocketBasicStream::OnReadComplete(ScopedVector<WebSocketFrame>* frames,
- const CompletionCallback& callback,
- int result) {
+void WebSocketBasicStream::OnReadComplete(
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
+ const CompletionCallback& callback,
+ int result) {
result = HandleReadResult(result, frames);
if (result == ERR_IO_PENDING)
result = ReadFrames(frames, callback);
diff --git a/chromium/net/websockets/websocket_basic_stream.h b/chromium/net/websockets/websocket_basic_stream.h
index d456d8d694c..d035639b685 100644
--- a/chromium/net/websockets/websocket_basic_stream.h
+++ b/chromium/net/websockets/websocket_basic_stream.h
@@ -6,11 +6,11 @@
#define NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_H_
#include <string>
+#include <vector>
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/websockets/websocket_frame_parser.h"
#include "net/websockets/websocket_stream.h"
@@ -43,10 +43,10 @@ class NET_EXPORT_PRIVATE WebSocketBasicStream : public WebSocketStream {
~WebSocketBasicStream() override;
// WebSocketStream implementation.
- int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+ int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override;
- int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override;
void Close() override;
@@ -78,14 +78,16 @@ class NET_EXPORT_PRIVATE WebSocketBasicStream : public WebSocketStream {
// Attempts to parse the output of a read as WebSocket frames. On success,
// returns OK and places the frame(s) in |frames|.
- int HandleReadResult(int result, ScopedVector<WebSocketFrame>* frames);
+ int HandleReadResult(int result,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames);
// Converts the chunks in |frame_chunks| into frames and writes them to
// |frames|. |frame_chunks| is destroyed in the process. Returns
// ERR_WS_PROTOCOL_ERROR if an invalid chunk was found. If one or more frames
// was added to |frames|, then returns OK, otherwise returns ERR_IO_PENDING.
- int ConvertChunksToFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks,
- ScopedVector<WebSocketFrame>* frames);
+ int ConvertChunksToFrames(
+ std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames);
// Converts a |chunk| to a |frame|. |*frame| should be NULL on entry to this
// method. If |chunk| is an incomplete control frame, or an empty middle
@@ -113,7 +115,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicStream : public WebSocketStream {
// Called when a read completes. Parses the result and (unless no complete
// header has been received) calls |callback|.
- void OnReadComplete(ScopedVector<WebSocketFrame>* frames,
+ void OnReadComplete(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback,
int result);
diff --git a/chromium/net/websockets/websocket_basic_stream_test.cc b/chromium/net/websockets/websocket_basic_stream_test.cc
index 9426f59cb7e..d7796d3886c 100644
--- a/chromium/net/websockets/websocket_basic_stream_test.cc
+++ b/chromium/net/websockets/websocket_basic_stream_test.cc
@@ -8,13 +8,15 @@
#include "net/websockets/websocket_basic_stream.h"
+#include <stddef.h>
#include <stdint.h>
#include <string.h> // for memcpy() and memset().
-
#include <string>
+#include <utility>
+#include <vector>
-#include "base/basictypes.h"
#include "base/big_endian.h"
+#include "base/macros.h"
#include "net/base/test_completion_callback.h"
#include "net/log/test_net_log.h"
#include "net/socket/socket_test_util.h"
@@ -132,7 +134,7 @@ class WebSocketBasicStreamSocketTest : public WebSocketBasicStreamTest {
CompletionCallback(),
&pool_,
bound_net_log_.bound());
- return transport_socket.Pass();
+ return transport_socket;
}
void SetHttpReadBuffer(const char* data, size_t size) {
@@ -165,7 +167,7 @@ class WebSocketBasicStreamSocketTest : public WebSocketBasicStreamTest {
MockClientSocketFactory factory_;
MockTransportClientSocketPool pool_;
BoundTestNetLog(bound_net_log_);
- ScopedVector<WebSocketFrame> frames_;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_;
TestCompletionCallback cb_;
scoped_refptr<GrowableIOBuffer> http_read_buffer_;
std::string sub_protocol_;
@@ -253,7 +255,7 @@ class WebSocketBasicStreamSocketWriteTest
header.final = true;
header.masked = true;
header.payload_length = payload_size;
- frames_.push_back(frame.Pass());
+ frames_.push_back(std::move(frame));
}
// Creates a stream that expects the listed writes.
@@ -795,7 +797,7 @@ TEST_F(WebSocketBasicStreamSocketChunkedReadTest, OneMegFrame) {
// This should be equal to the definition of kReadBufferSize in
// websocket_basic_stream.cc.
const int kReadBufferSize = 32 * 1024;
- const uint64 kPayloadSize = 1 << 20;
+ const uint64_t kPayloadSize = 1 << 20;
const size_t kWireSize = kPayloadSize + kLargeFrameHeaderSize;
const size_t kExpectedFrameCount =
(kWireSize + kReadBufferSize - 1) / kReadBufferSize;
@@ -895,8 +897,8 @@ TEST_F(WebSocketBasicStreamSocketWriteTest, WriteNullPong) {
header.final = true;
header.masked = true;
header.payload_length = 0;
- ScopedVector<WebSocketFrame> frames;
- frames.push_back(frame.Pass());
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
+ frames.push_back(std::move(frame));
EXPECT_EQ(OK, stream_->WriteFrames(&frames, cb_.callback()));
}
@@ -920,7 +922,7 @@ TEST_F(WebSocketBasicStreamSocketTest, WriteNonNulMask) {
header.final = true;
header.masked = true;
header.payload_length = payload_size;
- frames_.push_back(frame.Pass());
+ frames_.push_back(std::move(frame));
EXPECT_EQ(OK, stream_->WriteFrames(&frames_, cb_.callback()));
}
diff --git a/chromium/net/websockets/websocket_channel.cc b/chromium/net/websockets/websocket_channel.cc
index 0237ca10330..3018088db35 100644
--- a/chromium/net/websockets/websocket_channel.cc
+++ b/chromium/net/websockets/websocket_channel.cc
@@ -4,22 +4,23 @@
#include "net/websockets/websocket_channel.h"
+#include <stddef.h>
#include <limits.h> // for INT_MAX
#include <algorithm>
#include <deque>
+#include <utility>
+#include <vector>
-#include "base/basictypes.h" // for size_t
#include "base/big_endian.h"
#include "base/bind.h"
-#include "base/compiler_specific.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"
#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -70,7 +71,7 @@ const size_t kMaximumCloseReasonLength = 125 - kWebSocketCloseCodeLength;
// used for close codes received from a renderer that we are intending to send
// out over the network. See ParseClose() for the restrictions on incoming close
// codes. The |code| parameter is type int for convenience of implementation;
-// the real type is uint16. Code 1005 is treated specially; it cannot be set
+// the real type is uint16_t. Code 1005 is treated specially; it cannot be set
// explicitly by Javascript but the renderer uses it to indicate we should send
// a Close frame with no payload.
bool IsStrictlyValidCloseStatusCode(int code) {
@@ -138,21 +139,21 @@ class WebSocketChannel::SendBuffer {
void AddFrame(scoped_ptr<WebSocketFrame> chunk);
// Return a pointer to the frames_ for write purposes.
- ScopedVector<WebSocketFrame>* frames() { return &frames_; }
+ std::vector<scoped_ptr<WebSocketFrame>>* frames() { return &frames_; }
private:
// The frames_ that will be sent in the next call to WriteFrames().
- ScopedVector<WebSocketFrame> frames_;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_;
// The total size of the payload data in |frames_|. This will be used to
// measure the throughput of the link.
// TODO(ricea): Measure the throughput of the link.
- uint64 total_bytes_;
+ uint64_t total_bytes_;
};
void WebSocketChannel::SendBuffer::AddFrame(scoped_ptr<WebSocketFrame> frame) {
total_bytes_ += frame->header.payload_length;
- frames_.push_back(frame.Pass());
+ frames_.push_back(std::move(frame));
}
// Implementation of WebSocketStream::ConnectDelegate that simply forwards the
@@ -163,7 +164,7 @@ class WebSocketChannel::ConnectDelegate
explicit ConnectDelegate(WebSocketChannel* creator) : creator_(creator) {}
void OnSuccess(scoped_ptr<WebSocketStream> stream) override {
- creator_->OnConnectSuccess(stream.Pass());
+ creator_->OnConnectSuccess(std::move(stream));
// |this| may have been deleted.
}
@@ -174,12 +175,12 @@ class WebSocketChannel::ConnectDelegate
void OnStartOpeningHandshake(
scoped_ptr<WebSocketHandshakeRequestInfo> request) override {
- creator_->OnStartOpeningHandshake(request.Pass());
+ creator_->OnStartOpeningHandshake(std::move(request));
}
void OnFinishOpeningHandshake(
scoped_ptr<WebSocketHandshakeResponseInfo> response) override {
- creator_->OnFinishOpeningHandshake(response.Pass());
+ creator_->OnFinishOpeningHandshake(std::move(response));
}
void OnSSLCertificateError(
@@ -187,8 +188,8 @@ class WebSocketChannel::ConnectDelegate
ssl_error_callbacks,
const SSLInfo& ssl_info,
bool fatal) override {
- creator_->OnSSLCertificateError(
- ssl_error_callbacks.Pass(), ssl_info, fatal);
+ creator_->OnSSLCertificateError(std::move(ssl_error_callbacks), ssl_info,
+ fatal);
}
private:
@@ -217,7 +218,7 @@ class WebSocketChannel::HandshakeNotificationSender
void set_handshake_request_info(
scoped_ptr<WebSocketHandshakeRequestInfo> request_info) {
- handshake_request_info_ = request_info.Pass();
+ handshake_request_info_ = std::move(request_info);
}
const WebSocketHandshakeResponseInfo* handshake_response_info() const {
@@ -226,7 +227,7 @@ class WebSocketChannel::HandshakeNotificationSender
void set_handshake_response_info(
scoped_ptr<WebSocketHandshakeResponseInfo> response_info) {
- handshake_response_info_ = response_info.Pass();
+ handshake_response_info_ = std::move(response_info);
}
private:
@@ -254,14 +255,16 @@ ChannelState WebSocketChannel::HandshakeNotificationSender::SendImmediately(
WebSocketEventInterface* event_interface) {
if (handshake_request_info_.get()) {
- if (CHANNEL_DELETED == event_interface->OnStartOpeningHandshake(
- handshake_request_info_.Pass()))
+ if (CHANNEL_DELETED ==
+ event_interface->OnStartOpeningHandshake(
+ std::move(handshake_request_info_)))
return CHANNEL_DELETED;
}
if (handshake_response_info_.get()) {
- if (CHANNEL_DELETED == event_interface->OnFinishOpeningHandshake(
- handshake_response_info_.Pass()))
+ if (CHANNEL_DELETED ==
+ event_interface->OnFinishOpeningHandshake(
+ std::move(handshake_response_info_)))
return CHANNEL_DELETED;
// TODO(yhirano): We can release |this| to save memory because
@@ -275,8 +278,8 @@ WebSocketChannel::PendingReceivedFrame::PendingReceivedFrame(
bool final,
WebSocketFrameHeader::OpCode opcode,
const scoped_refptr<IOBuffer>& data,
- uint64 offset,
- uint64 size)
+ uint64_t offset,
+ uint64_t size)
: final_(final),
opcode_(opcode),
data_(data),
@@ -290,7 +293,7 @@ void WebSocketChannel::PendingReceivedFrame::ResetOpcode() {
opcode_ = WebSocketFrameHeader::kOpCodeContinuation;
}
-void WebSocketChannel::PendingReceivedFrame::DidConsume(uint64 bytes) {
+void WebSocketChannel::PendingReceivedFrame::DidConsume(uint64_t bytes) {
DCHECK_LE(offset_, size_);
DCHECK_LE(bytes, size_ - offset_);
offset_ += bytes;
@@ -299,14 +302,14 @@ void WebSocketChannel::PendingReceivedFrame::DidConsume(uint64 bytes) {
WebSocketChannel::WebSocketChannel(
scoped_ptr<WebSocketEventInterface> event_interface,
URLRequestContext* url_request_context)
- : event_interface_(event_interface.Pass()),
+ : event_interface_(std::move(event_interface)),
url_request_context_(url_request_context),
send_quota_low_water_mark_(kDefaultSendQuotaLowWaterMark),
send_quota_high_water_mark_(kDefaultSendQuotaHighWaterMark),
current_send_quota_(0),
current_receive_quota_(0),
- closing_handshake_timeout_(base::TimeDelta::FromSeconds(
- kClosingHandshakeTimeoutSeconds)),
+ closing_handshake_timeout_(
+ base::TimeDelta::FromSeconds(kClosingHandshakeTimeoutSeconds)),
underlying_connection_close_timeout_(base::TimeDelta::FromSeconds(
kUnderlyingConnectionCloseTimeoutSeconds)),
has_received_close_frame_(false),
@@ -360,55 +363,51 @@ bool WebSocketChannel::InClosingState() const {
return state_ == SEND_CLOSED || state_ == CLOSE_WAIT || state_ == CLOSED;
}
-void WebSocketChannel::SendFrame(bool fin,
- WebSocketFrameHeader::OpCode op_code,
- const std::vector<char>& data) {
+WebSocketChannel::ChannelState WebSocketChannel::SendFrame(
+ bool fin,
+ WebSocketFrameHeader::OpCode op_code,
+ const std::vector<char>& data) {
if (data.size() > INT_MAX) {
NOTREACHED() << "Frame size sanity check failed";
- return;
+ return CHANNEL_ALIVE;
}
if (stream_ == NULL) {
LOG(DFATAL) << "Got SendFrame without a connection established; "
<< "misbehaving renderer? fin=" << fin << " op_code=" << op_code
<< " data.size()=" << data.size();
- return;
+ return CHANNEL_ALIVE;
}
if (InClosingState()) {
DVLOG(1) << "SendFrame called in state " << state_
<< ". This may be a bug, or a harmless race.";
- return;
+ return CHANNEL_ALIVE;
}
if (state_ != CONNECTED) {
NOTREACHED() << "SendFrame() called in state " << state_;
- return;
+ return CHANNEL_ALIVE;
}
if (data.size() > base::checked_cast<size_t>(current_send_quota_)) {
// TODO(ricea): Kill renderer.
- ignore_result(
- FailChannel("Send quota exceeded", kWebSocketErrorGoingAway, ""));
+ return FailChannel("Send quota exceeded", kWebSocketErrorGoingAway, "");
// |this| has been deleted.
- return;
}
if (!WebSocketFrameHeader::IsKnownDataOpCode(op_code)) {
LOG(DFATAL) << "Got SendFrame with bogus op_code " << op_code
<< "; misbehaving renderer? fin=" << fin
<< " data.size()=" << data.size();
- return;
+ return CHANNEL_ALIVE;
}
if (op_code == WebSocketFrameHeader::kOpCodeText ||
(op_code == WebSocketFrameHeader::kOpCodeContinuation &&
sending_text_message_)) {
StreamingUtf8Validator::State state =
- outgoing_utf8_validator_.AddBytes(vector_as_array(&data), data.size());
+ outgoing_utf8_validator_.AddBytes(data.data(), data.size());
if (state == StreamingUtf8Validator::INVALID ||
(state == StreamingUtf8Validator::VALID_MIDPOINT && fin)) {
// TODO(ricea): Kill renderer.
- ignore_result(
- FailChannel("Browser sent a text frame containing invalid UTF-8",
- kWebSocketErrorGoingAway,
- ""));
+ return FailChannel("Browser sent a text frame containing invalid UTF-8",
+ kWebSocketErrorGoingAway, "");
// |this| has been deleted.
- return;
}
sending_text_message_ = !fin;
DCHECK(!fin || state == StreamingUtf8Validator::VALID_ENDPOINT);
@@ -420,11 +419,11 @@ void WebSocketChannel::SendFrame(bool fin,
// server is not saturated.
scoped_refptr<IOBuffer> buffer(new IOBuffer(data.size()));
std::copy(data.begin(), data.end(), buffer->data());
- ignore_result(SendFrameFromIOBuffer(fin, op_code, buffer, data.size()));
+ return SendFrameFromIOBuffer(fin, op_code, buffer, data.size());
// |this| may have been deleted.
}
-void WebSocketChannel::SendFlowControl(int64 quota) {
+void WebSocketChannel::SendFlowControl(int64_t quota) {
DCHECK(state_ == CONNECTING || state_ == CONNECTED || state_ == SEND_CLOSED ||
state_ == CLOSE_WAIT);
// TODO(ricea): Kill the renderer if it tries to send us a negative quota
@@ -436,9 +435,9 @@ void WebSocketChannel::SendFlowControl(int64 quota) {
}
while (!pending_received_frames_.empty() && quota > 0) {
PendingReceivedFrame& front = pending_received_frames_.front();
- const uint64 data_size = front.size() - front.offset();
- const uint64 bytes_to_send =
- std::min(base::checked_cast<uint64>(quota), data_size);
+ const uint64_t data_size = front.size() - front.offset();
+ const uint64_t bytes_to_send =
+ std::min(base::checked_cast<uint64_t>(quota), data_size);
const bool final = front.final() && data_size == bytes_to_send;
const char* data =
front.data().get() ? front.data()->data() + front.offset() : NULL;
@@ -470,7 +469,7 @@ void WebSocketChannel::SendFlowControl(int64 quota) {
// |this| may have been deleted.
}
-void WebSocketChannel::StartClosingHandshake(uint16 code,
+void WebSocketChannel::StartClosingHandshake(uint16_t code,
const std::string& reason) {
if (InClosingState()) {
// When the associated renderer process is killed while the channel is in
@@ -558,12 +557,9 @@ void WebSocketChannel::SendAddChannelRequestWithSuppliedCreator(
socket_url_ = socket_url;
scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate(
new ConnectDelegate(this));
- stream_request_ = creator.Run(socket_url_,
- requested_subprotocols,
- origin,
- url_request_context_,
- BoundNetLog(),
- connect_delegate.Pass());
+ stream_request_ = creator.Run(socket_url_, requested_subprotocols, origin,
+ url_request_context_, BoundNetLog(),
+ std::move(connect_delegate));
SetState(CONNECTING);
}
@@ -571,7 +567,7 @@ void WebSocketChannel::OnConnectSuccess(scoped_ptr<WebSocketStream> stream) {
DCHECK(stream);
DCHECK_EQ(CONNECTING, state_);
- stream_ = stream.Pass();
+ stream_ = std::move(stream);
SetState(CONNECTED);
@@ -618,7 +614,7 @@ void WebSocketChannel::OnSSLCertificateError(
const SSLInfo& ssl_info,
bool fatal) {
ignore_result(event_interface_->OnSSLCertificateError(
- ssl_error_callbacks.Pass(), socket_url_, ssl_info, fatal));
+ std::move(ssl_error_callbacks), socket_url_, ssl_info, fatal));
}
void WebSocketChannel::OnStartOpeningHandshake(
@@ -627,7 +623,7 @@ void WebSocketChannel::OnStartOpeningHandshake(
// Because it is hard to handle an IPC error synchronously is difficult,
// we asynchronously notify the information.
- notification_sender_->set_handshake_request_info(request.Pass());
+ notification_sender_->set_handshake_request_info(std::move(request));
ScheduleOpeningHandshakeNotification();
}
@@ -637,7 +633,7 @@ void WebSocketChannel::OnFinishOpeningHandshake(
// Because it is hard to handle an IPC error synchronously is difficult,
// we asynchronously notify the information.
- notification_sender_->set_handshake_response_info(response.Pass());
+ notification_sender_->set_handshake_response_info(std::move(response));
ScheduleOpeningHandshakeNotification();
}
@@ -675,7 +671,7 @@ ChannelState WebSocketChannel::OnWriteDone(bool synchronous, int result) {
switch (result) {
case OK:
if (data_to_send_next_) {
- data_being_sent_ = data_to_send_next_.Pass();
+ data_being_sent_ = std::move(data_to_send_next_);
if (!synchronous)
return WriteFrames();
} else {
@@ -740,9 +736,7 @@ ChannelState WebSocketChannel::OnReadDone(bool synchronous, int result) {
DCHECK(!read_frames_.empty())
<< "ReadFrames() returned OK, but nothing was read.";
for (size_t i = 0; i < read_frames_.size(); ++i) {
- scoped_ptr<WebSocketFrame> frame(read_frames_[i]);
- read_frames_[i] = NULL;
- if (HandleFrame(frame.Pass()) == CHANNEL_DELETED)
+ if (HandleFrame(std::move(read_frames_[i])) == CHANNEL_DELETED)
return CHANNEL_DELETED;
}
read_frames_.clear();
@@ -768,7 +762,7 @@ ChannelState WebSocketChannel::OnReadDone(bool synchronous, int result) {
stream_->Close();
SetState(CLOSED);
- uint16 code = kWebSocketErrorAbnormalClosure;
+ uint16_t code = kWebSocketErrorAbnormalClosure;
std::string reason = "";
bool was_clean = false;
if (has_received_close_frame_) {
@@ -815,7 +809,7 @@ ChannelState WebSocketChannel::HandleFrameByState(
const WebSocketFrameHeader::OpCode opcode,
bool final,
const scoped_refptr<IOBuffer>& data_buffer,
- uint64 size) {
+ uint64_t size) {
DCHECK_NE(RECV_CLOSED, state_)
<< "HandleFrame() does not support being called re-entrantly from within "
"SendClose()";
@@ -852,7 +846,7 @@ ChannelState WebSocketChannel::HandleFrameByState(
// the renderer, then the renderer should not receive an
// OnClosingHandshake or OnDropChannel IPC until the queued message has
// been completedly transmitted.
- uint16 code = kWebSocketNormalClosure;
+ uint16_t code = kWebSocketNormalClosure;
std::string reason;
std::string message;
if (!ParseClose(data_buffer, size, &code, &reason, &message)) {
@@ -925,7 +919,7 @@ ChannelState WebSocketChannel::HandleDataFrame(
WebSocketFrameHeader::OpCode opcode,
bool final,
const scoped_refptr<IOBuffer>& data_buffer,
- uint64 size) {
+ uint64_t size) {
if (state_ != CONNECTED) {
DVLOG(3) << "Ignored data packet received in state " << state_;
return CHANNEL_ALIVE;
@@ -1001,7 +995,7 @@ ChannelState WebSocketChannel::SendFrameFromIOBuffer(
bool fin,
WebSocketFrameHeader::OpCode op_code,
const scoped_refptr<IOBuffer>& buffer,
- uint64 size) {
+ uint64_t size) {
DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
DCHECK(stream_);
@@ -1019,17 +1013,17 @@ ChannelState WebSocketChannel::SendFrameFromIOBuffer(
// quota appropriately.
if (!data_to_send_next_)
data_to_send_next_.reset(new SendBuffer);
- data_to_send_next_->AddFrame(frame.Pass());
+ data_to_send_next_->AddFrame(std::move(frame));
return CHANNEL_ALIVE;
}
data_being_sent_.reset(new SendBuffer);
- data_being_sent_->AddFrame(frame.Pass());
+ data_being_sent_->AddFrame(std::move(frame));
return WriteFrames();
}
ChannelState WebSocketChannel::FailChannel(const std::string& message,
- uint16 code,
+ uint16_t code,
const std::string& reason) {
DCHECK_NE(FRESHLY_CONSTRUCTED, state_);
DCHECK_NE(CONNECTING, state_);
@@ -1051,12 +1045,12 @@ ChannelState WebSocketChannel::FailChannel(const std::string& message,
return result;
}
-ChannelState WebSocketChannel::SendClose(uint16 code,
+ChannelState WebSocketChannel::SendClose(uint16_t code,
const std::string& reason) {
DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
DCHECK_LE(reason.size(), kMaximumCloseReasonLength);
scoped_refptr<IOBuffer> body;
- uint64 size = 0;
+ uint64_t size = 0;
if (code == kWebSocketErrorNoStatusReceived) {
// Special case: translate kWebSocketErrorNoStatusReceived into a Close
// frame with no payload.
@@ -1080,8 +1074,8 @@ ChannelState WebSocketChannel::SendClose(uint16 code,
}
bool WebSocketChannel::ParseClose(const scoped_refptr<IOBuffer>& buffer,
- uint64 size,
- uint16* code,
+ uint64_t size,
+ uint16_t* code,
std::string* reason,
std::string* message) {
reason->clear();
@@ -1101,7 +1095,7 @@ bool WebSocketChannel::ParseClose(const scoped_refptr<IOBuffer>& buffer,
}
const char* data = buffer->data();
- uint16 unchecked_code = 0;
+ uint16_t unchecked_code = 0;
base::ReadBigEndian(data, &unchecked_code);
static_assert(sizeof(unchecked_code) == kWebSocketCloseCodeLength,
"they should both be two bytes");
@@ -1133,7 +1127,7 @@ bool WebSocketChannel::ParseClose(const scoped_refptr<IOBuffer>& buffer,
}
ChannelState WebSocketChannel::DoDropChannel(bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) {
if (CHANNEL_DELETED ==
notification_sender_->SendImmediately(event_interface_.get()))
diff --git a/chromium/net/websockets/websocket_channel.h b/chromium/net/websockets/websocket_channel.h
index bc585745c84..7f341950244 100644
--- a/chromium/net/websockets/websocket_channel.h
+++ b/chromium/net/websockets/websocket_channel.h
@@ -5,17 +5,18 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_
#define NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_
+#include <stdint.h>
+
#include <queue>
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h" // for WARN_UNUSED_RESULT
#include "base/i18n/streaming_utf8_validator.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/net_export.h"
@@ -53,6 +54,11 @@ class NET_EXPORT WebSocketChannel {
const BoundNetLog&,
scoped_ptr<WebSocketStream::ConnectDelegate>)> WebSocketStreamCreator;
+ // 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;
+
// Creates a new WebSocketChannel in an idle state.
// SendAddChannelRequest() must be called immediately afterwards to start the
// connection process.
@@ -66,25 +72,25 @@ class NET_EXPORT WebSocketChannel {
const std::vector<std::string>& requested_protocols,
const url::Origin& origin);
- // Sends a data frame to the remote side. The frame should usually be no
- // larger than 32KB to prevent the time required to copy the buffers from from
- // unduly delaying other tasks that need to run on the IO thread. This method
- // has a hard limit of 2GB. It is the responsibility of the caller to ensure
- // that they have sufficient send quota to send this data, otherwise the
- // connection will be closed without sending. |fin| indicates the last frame
- // in a message, equivalent to "FIN" as specified in section 5.2 of
- // RFC6455. |data| is the "Payload Data". If |op_code| is kOpCodeText, or it
- // is kOpCodeContinuation and the type the message is Text, then |data| must
- // be a chunk of a valid UTF-8 message, however there is no requirement for
- // |data| to be split on character boundaries.
- void SendFrame(bool fin,
- WebSocketFrameHeader::OpCode op_code,
- const std::vector<char>& data);
+ // Sends a data frame to the remote side. It is the responsibility of the
+ // caller to ensure that they have sufficient send quota to send this data,
+ // otherwise the connection will be closed without sending. |fin| indicates
+ // the last frame in a message, equivalent to "FIN" as specified in section
+ // 5.2 of RFC6455. |data| is the "Payload Data". If |op_code| is kOpCodeText,
+ // or it is kOpCodeContinuation and the type the message is Text, then |data|
+ // must be a chunk of a valid UTF-8 message, however there is no requirement
+ // for |data| to be split on character boundaries. Calling SendFrame may
+ // result in synchronous calls to |event_interface_| which may result in this
+ // object being deleted. In that case, the return value will be
+ // CHANNEL_DELETED.
+ ChannelState SendFrame(bool fin,
+ WebSocketFrameHeader::OpCode op_code,
+ const std::vector<char>& data);
// Sends |quota| units of flow control to the remote side. If the underlying
// transport has a concept of |quota|, then it permits the remote server to
// send up to |quota| units of data.
- void SendFlowControl(int64 quota);
+ void SendFlowControl(int64_t quota);
// Starts the closing handshake for a client-initiated shutdown of the
// connection. There is no API to close the connection without a closing
@@ -95,7 +101,13 @@ class NET_EXPORT WebSocketChannel {
// This does *not* trigger the event OnClosingHandshake(). The caller should
// assume that the closing handshake has started and perform the equivalent
// processing to OnClosingHandshake() if necessary.
- void StartClosingHandshake(uint16 code, const std::string& reason);
+ void StartClosingHandshake(uint16_t code, const std::string& reason);
+
+ // Returns the current send quota. This value is unsafe to use outside of the
+ // browser IO thread because it changes asynchronously. The value is only
+ // valid for the execution of the current Task or until SendFrame() is called,
+ // whichever happens sooner.
+ int current_send_quota() const { return current_send_quota_; }
// Starts the connection process, using a specified creator callback rather
// than the default. This is exposed for testing.
@@ -135,8 +147,8 @@ class NET_EXPORT WebSocketChannel {
PendingReceivedFrame(bool final,
WebSocketFrameHeader::OpCode opcode,
const scoped_refptr<IOBuffer>& data,
- uint64 offset,
- uint64 size);
+ uint64_t offset,
+ uint64_t size);
~PendingReceivedFrame();
bool final() const { return final_; }
@@ -144,10 +156,10 @@ class NET_EXPORT WebSocketChannel {
// ResetOpcode() to Continuation.
void ResetOpcode();
const scoped_refptr<IOBuffer>& data() const { return data_; }
- uint64 offset() const { return offset_; }
- uint64 size() const { return size_; }
+ uint64_t offset() const { return offset_; }
+ uint64_t size() const { return size_; }
// Increase |offset_| by |bytes|.
- void DidConsume(uint64 bytes);
+ void DidConsume(uint64_t bytes);
// This object needs to be copyable and assignable, since it will be placed
// in a std::queue. The compiler-generated copy constructor and assignment
@@ -159,16 +171,11 @@ class NET_EXPORT WebSocketChannel {
scoped_refptr<IOBuffer> data_;
// Where to start reading from data_. Everything prior to offset_ has
// already been sent to the browser.
- uint64 offset_;
+ uint64_t offset_;
// The size of data_.
- uint64 size_;
+ uint64_t size_;
};
- // 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.
- typedef WebSocketEventInterface::ChannelState ChannelState;
-
// The object passes through a linear progression of states from
// FRESHLY_CONSTRUCTED to CLOSED, except that the SEND_CLOSED and RECV_CLOSED
// states may be skipped in case of error.
@@ -260,11 +267,10 @@ class NET_EXPORT WebSocketChannel {
// Handles a single frame depending on the current state. It's used by the
// HandleFrame() method.
- ChannelState HandleFrameByState(
- const WebSocketFrameHeader::OpCode opcode,
- bool final,
- const scoped_refptr<IOBuffer>& data_buffer,
- uint64 size) WARN_UNUSED_RESULT;
+ ChannelState HandleFrameByState(const WebSocketFrameHeader::OpCode opcode,
+ bool final,
+ const scoped_refptr<IOBuffer>& data_buffer,
+ uint64_t size) WARN_UNUSED_RESULT;
// Forward a received data frame to the renderer, if connected. If
// |expecting_continuation| is not equal to |expecting_to_read_continuation_|,
@@ -272,7 +278,7 @@ class NET_EXPORT WebSocketChannel {
ChannelState HandleDataFrame(WebSocketFrameHeader::OpCode opcode,
bool final,
const scoped_refptr<IOBuffer>& data_buffer,
- uint64 size) WARN_UNUSED_RESULT;
+ uint64_t size) WARN_UNUSED_RESULT;
// Low-level method to send a single frame. Used for both data and control
// frames. Either sends the frame immediately or buffers it to be scheduled
@@ -282,7 +288,7 @@ class NET_EXPORT WebSocketChannel {
ChannelState SendFrameFromIOBuffer(bool fin,
WebSocketFrameHeader::OpCode op_code,
const scoped_refptr<IOBuffer>& buffer,
- uint64 size) WARN_UNUSED_RESULT;
+ uint64_t size) WARN_UNUSED_RESULT;
// Performs the "Fail the WebSocket Connection" operation as defined in
// RFC6455. A NotifyFailure message is sent to the renderer with |message|.
@@ -294,14 +300,14 @@ class NET_EXPORT WebSocketChannel {
// returns CHANNEL_DELETED. It is not valid to access any member variables or
// methods after calling FailChannel().
ChannelState FailChannel(const std::string& message,
- uint16 code,
+ uint16_t code,
const std::string& reason) WARN_UNUSED_RESULT;
// 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
// kWebSocketErrorNoStatusReceived will create a Close frame with no payload;
// this is symmetric with the behaviour of ParseClose.
- ChannelState SendClose(uint16 code,
+ ChannelState SendClose(uint16_t code,
const std::string& reason) WARN_UNUSED_RESULT;
// Parses a Close frame payload. If no status code is supplied, then |code| is
@@ -311,8 +317,8 @@ class NET_EXPORT WebSocketChannel {
// then false is returned and |message| is set to an appropriate console
// message.
bool ParseClose(const scoped_refptr<IOBuffer>& buffer,
- uint64 size,
- uint16* code,
+ uint64_t size,
+ uint16_t* code,
std::string* reason,
std::string* message);
@@ -322,7 +328,7 @@ class NET_EXPORT WebSocketChannel {
//
// Always returns CHANNEL_DELETED.
ChannelState DoDropChannel(bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason);
// Called if the closing handshake times out. Closes the connection and
@@ -351,7 +357,7 @@ class NET_EXPORT WebSocketChannel {
scoped_ptr<SendBuffer> data_to_send_next_;
// Destination for the current call to WebSocketStream::ReadFrames
- ScopedVector<WebSocketFrame> read_frames_;
+ std::vector<scoped_ptr<WebSocketFrame>> read_frames_;
// Frames that have been read but not yet forwarded to the renderer due to
// lack of quota.
@@ -373,7 +379,7 @@ class NET_EXPORT WebSocketChannel {
int current_send_quota_;
// The remaining amount of quota that the renderer will allow us to send on
// this logical channel (quota units).
- uint64 current_receive_quota_;
+ uint64_t current_receive_quota_;
// Timer for the closing handshake.
base::OneShotTimer close_timer_;
@@ -389,7 +395,7 @@ class NET_EXPORT WebSocketChannel {
// arrives until the connection is closed and they are passed to
// OnDropChannel().
bool has_received_close_frame_;
- uint16 received_close_code_;
+ uint16_t received_close_code_;
std::string received_close_reason_;
// The current state of the channel. Mainly used for sanity checking, but also
diff --git a/chromium/net/websockets/websocket_channel_test.cc b/chromium/net/websockets/websocket_channel_test.cc
index 3c8a7f1e4a3..fabd81d7a91 100644
--- a/chromium/net/websockets/websocket_channel_test.cc
+++ b/chromium/net/websockets/websocket_channel_test.cc
@@ -5,18 +5,20 @@
#include "net/websockets/websocket_channel.h"
#include <limits.h>
+#include <stddef.h>
#include <string.h>
-
#include <iostream>
+#include <iterator>
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
@@ -69,25 +71,25 @@ std::ostream& operator<<(std::ostream& os, const WebSocketFrame& frame) {
return os << "NULL}";
}
-std::ostream& operator<<(std::ostream& os,
- const ScopedVector<WebSocketFrame>& vector) {
+std::ostream& operator<<(
+ std::ostream& os,
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames) {
os << "{";
bool first = true;
- for (ScopedVector<WebSocketFrame>::const_iterator it = vector.begin();
- it != vector.end();
- ++it) {
+ for (const auto& frame : frames) {
if (!first) {
os << ",\n";
} else {
first = false;
}
- os << **it;
+ os << *frame;
}
return os << "}";
}
-std::ostream& operator<<(std::ostream& os,
- const ScopedVector<WebSocketFrame>* vector) {
+std::ostream& operator<<(
+ std::ostream& os,
+ const std::vector<scoped_ptr<WebSocketFrame>>* vector) {
return os << '&' << *vector;
}
@@ -136,7 +138,7 @@ const int kVeryBigTimeoutMillis = 60 * 60 * 24 * 1000;
const int kVeryTinyTimeoutMillis = 1;
// Enough quota to pass any test.
-const int64 kPlentyOfQuota = INT_MAX;
+const int64_t kPlentyOfQuota = INT_MAX;
typedef WebSocketEventInterface::ChannelState ChannelState;
const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE;
@@ -158,11 +160,11 @@ class MockWebSocketEventInterface : public WebSocketEventInterface {
ChannelState(bool,
WebSocketMessageType,
const std::vector<char>&)); // NOLINT
- MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT
+ MOCK_METHOD1(OnFlowControl, ChannelState(int64_t)); // NOLINT
MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT
MOCK_METHOD1(OnFailChannel, ChannelState(const std::string&)); // NOLINT
MOCK_METHOD3(OnDropChannel,
- ChannelState(bool, uint16, const std::string&)); // NOLINT
+ ChannelState(bool, uint16_t, const std::string&)); // NOLINT
// We can't use GMock with scoped_ptr.
ChannelState OnStartOpeningHandshake(
@@ -204,13 +206,13 @@ class FakeWebSocketEventInterface : public WebSocketEventInterface {
const std::vector<char>& data) override {
return CHANNEL_ALIVE;
}
- ChannelState OnFlowControl(int64 quota) 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 code,
+ uint16_t code,
const std::string& reason) override {
return CHANNEL_DELETED;
}
@@ -244,12 +246,12 @@ class FakeWebSocketStream : public WebSocketStream {
const std::string& extensions)
: protocol_(protocol), extensions_(extensions) {}
- int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+ int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
return ERR_IO_PENDING;
}
- int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
return ERR_IO_PENDING;
}
@@ -319,9 +321,9 @@ std::ostream& operator<<(std::ostream& os, const InitFrame (&frames)[N]) {
// Convert a const array of InitFrame structs to the format used at
// runtime. Templated on the size of the array to save typing.
template <size_t N>
-ScopedVector<WebSocketFrame> CreateFrameVector(
- const InitFrame (&source_frames)[N]) {
- ScopedVector<WebSocketFrame> result_frames;
+std::vector<scoped_ptr<WebSocketFrame>> CreateFrameVector(
+ const InitFrame(&source_frames)[N]) {
+ std::vector<scoped_ptr<WebSocketFrame>> result_frames;
result_frames.reserve(N);
for (size_t i = 0; i < N; ++i) {
const InitFrame& source_frame = source_frames[i];
@@ -336,9 +338,9 @@ ScopedVector<WebSocketFrame> CreateFrameVector(
result_frame->data = new IOBuffer(frame_length);
memcpy(result_frame->data->data(), source_frame.data, frame_length);
}
- result_frames.push_back(result_frame.Pass());
+ result_frames.push_back(std::move(result_frame));
}
- return result_frames.Pass();
+ return result_frames;
}
// A GoogleMock action which can be used to respond to call to ReadFrames with
@@ -352,19 +354,20 @@ ACTION_P(ReturnFrames, source_frames) {
}
// The implementation of a GoogleMock matcher which can be used to compare a
-// ScopedVector<WebSocketFrame>* against an expectation defined as an array of
-// InitFrame objects. Although it is possible to compose built-in GoogleMock
-// matchers to check the contents of a WebSocketFrame, the results are so
-// unreadable that it is better to use this matcher.
+// std::vector<scoped_ptr<WebSocketFrame>>* against an expectation defined as an
+// array of InitFrame objects. Although it is possible to compose built-in
+// GoogleMock matchers to check the contents of a WebSocketFrame, the results
+// are so unreadable that it is better to use this matcher.
template <size_t N>
-class EqualsFramesMatcher
- : public ::testing::MatcherInterface<ScopedVector<WebSocketFrame>*> {
+class EqualsFramesMatcher : public ::testing::MatcherInterface<
+ std::vector<scoped_ptr<WebSocketFrame>>*> {
public:
EqualsFramesMatcher(const InitFrame (*expect_frames)[N])
: expect_frames_(expect_frames) {}
- virtual bool MatchAndExplain(ScopedVector<WebSocketFrame>* actual_frames,
- ::testing::MatchResultListener* listener) const {
+ virtual bool MatchAndExplain(
+ std::vector<scoped_ptr<WebSocketFrame>>* actual_frames,
+ ::testing::MatchResultListener* listener) const {
if (actual_frames->size() != N) {
*listener << "the vector size is " << actual_frames->size();
return false;
@@ -419,8 +422,8 @@ class EqualsFramesMatcher
// The definition of EqualsFrames GoogleMock matcher. Unlike the ReturnFrames
// action, this can take the array by reference.
template <size_t N>
-::testing::Matcher<ScopedVector<WebSocketFrame>*> EqualsFrames(
- const InitFrame (&frames)[N]) {
+::testing::Matcher<std::vector<scoped_ptr<WebSocketFrame>>*> EqualsFrames(
+ const InitFrame(&frames)[N]) {
return ::testing::MakeMatcher(new EqualsFramesMatcher<N>(&frames));
}
@@ -456,30 +459,32 @@ class ReadableFakeWebSocketStream : public FakeWebSocketStream {
// |async| is SYNC, the response will be returned synchronously. |error| is
// returned directly from ReadFrames() in the synchronous case, or passed to
// the callback in the asynchronous case. |frames| will be converted to a
- // ScopedVector<WebSocketFrame> and copied to the pointer that was passed to
- // ReadFrames().
+ // std::vector<scoped_ptr<WebSocketFrame>> and copied to the pointer that was
+ // passed to ReadFrames().
template <size_t N>
void PrepareReadFrames(IsSync async,
int error,
const InitFrame (&frames)[N]) {
- responses_.push_back(new Response(async, error, CreateFrameVector(frames)));
+ responses_.push_back(
+ make_scoped_ptr(new Response(async, error, CreateFrameVector(frames))));
}
// An alternate version of PrepareReadFrames for when we need to construct
// the frames manually.
void PrepareRawReadFrames(IsSync async,
int error,
- ScopedVector<WebSocketFrame> frames) {
- responses_.push_back(new Response(async, error, frames.Pass()));
+ std::vector<scoped_ptr<WebSocketFrame>> frames) {
+ responses_.push_back(
+ make_scoped_ptr(new Response(async, error, std::move(frames))));
}
// Prepares a fake error response (ie. there is no data).
void PrepareReadFramesError(IsSync async, int error) {
- responses_.push_back(
- new Response(async, error, ScopedVector<WebSocketFrame>()));
+ responses_.push_back(make_scoped_ptr(
+ new Response(async, error, std::vector<scoped_ptr<WebSocketFrame>>())));
}
- int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+ int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
CHECK(!read_frames_pending_);
if (index_ >= responses_.size())
@@ -497,7 +502,7 @@ class ReadableFakeWebSocketStream : public FakeWebSocketStream {
}
private:
- void DoCallback(ScopedVector<WebSocketFrame>* frames,
+ void DoCallback(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) {
read_frames_pending_ = false;
frames->swap(responses_[index_]->frames);
@@ -506,18 +511,20 @@ class ReadableFakeWebSocketStream : public FakeWebSocketStream {
}
struct Response {
- Response(IsSync async, int error, ScopedVector<WebSocketFrame> frames)
- : async(async), error(error), frames(frames.Pass()) {}
+ Response(IsSync async,
+ int error,
+ std::vector<scoped_ptr<WebSocketFrame>> frames)
+ : async(async), error(error), frames(std::move(frames)) {}
IsSync async;
int error;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
private:
// Bad things will happen if we attempt to copy or assign |frames|.
DISALLOW_COPY_AND_ASSIGN(Response);
};
- ScopedVector<Response> responses_;
+ std::vector<scoped_ptr<Response>> responses_;
// The index into the responses_ array of the next response to be returned.
size_t index_;
@@ -533,7 +540,7 @@ class ReadableFakeWebSocketStream : public FakeWebSocketStream {
// synchronously.
class WriteableFakeWebSocketStream : public FakeWebSocketStream {
public:
- int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
return OK;
}
@@ -542,7 +549,7 @@ class WriteableFakeWebSocketStream : public FakeWebSocketStream {
// A FakeWebSocketStream where writes always fail.
class UnWriteableFakeWebSocketStream : public FakeWebSocketStream {
public:
- int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
return ERR_CONNECTION_RESET;
}
@@ -558,17 +565,19 @@ class EchoeyFakeWebSocketStream : public FakeWebSocketStream {
public:
EchoeyFakeWebSocketStream() : read_frames_(NULL), done_(false) {}
- int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
+ stored_frames_.insert(stored_frames_.end(),
+ std::make_move_iterator(frames->begin()),
+ std::make_move_iterator(frames->end()));
+ frames->clear();
// Users of WebSocketStream will not expect the ReadFrames() callback to be
// called from within WriteFrames(), so post it to the message loop instead.
- stored_frames_.insert(stored_frames_.end(), frames->begin(), frames->end());
- frames->weak_clear();
PostCallback();
return OK;
}
- int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+ int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
read_callback_ = callback;
read_frames_ = frames;
@@ -597,13 +606,11 @@ class EchoeyFakeWebSocketStream : public FakeWebSocketStream {
// Copy the frames stored in stored_frames_ to |out|, while clearing the
// "masked" header bit. Returns true if a Close Frame was seen, false
// otherwise.
- bool MoveFrames(ScopedVector<WebSocketFrame>* out) {
+ bool MoveFrames(std::vector<scoped_ptr<WebSocketFrame>>* out) {
bool seen_close = false;
- *out = stored_frames_.Pass();
- for (ScopedVector<WebSocketFrame>::iterator it = out->begin();
- it != out->end();
- ++it) {
- WebSocketFrameHeader& header = (*it)->header;
+ *out = std::move(stored_frames_);
+ for (const auto& frame : *out) {
+ WebSocketFrameHeader& header = frame->header;
header.masked = false;
if (header.opcode == WebSocketFrameHeader::kOpCodeClose)
seen_close = true;
@@ -611,10 +618,10 @@ class EchoeyFakeWebSocketStream : public FakeWebSocketStream {
return seen_close;
}
- ScopedVector<WebSocketFrame> stored_frames_;
+ std::vector<scoped_ptr<WebSocketFrame>> stored_frames_;
CompletionCallback read_callback_;
// Owned by the caller of ReadFrames().
- ScopedVector<WebSocketFrame>* read_frames_;
+ std::vector<scoped_ptr<WebSocketFrame>>* read_frames_;
// True if we should close the connection.
bool done_;
};
@@ -630,7 +637,7 @@ class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream {
public:
ResetOnWriteFakeWebSocketStream() : closed_(false), weak_ptr_factory_(this) {}
- int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -645,7 +652,7 @@ class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream {
return ERR_IO_PENDING;
}
- int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+ int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override {
read_callback_ = callback;
return ERR_IO_PENDING;
@@ -671,10 +678,10 @@ class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream {
class MockWebSocketStream : public WebSocketStream {
public:
MOCK_METHOD2(ReadFrames,
- int(ScopedVector<WebSocketFrame>* frames,
+ int(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback));
MOCK_METHOD2(WriteFrames,
- int(ScopedVector<WebSocketFrame>* frames,
+ int(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback));
MOCK_METHOD0(Close, void());
MOCK_CONST_METHOD0(GetSubProtocol, std::string());
@@ -695,7 +702,7 @@ struct ArgumentCopyingWebSocketStreamCreator {
this->origin = origin;
this->url_request_context = url_request_context;
this->net_log = net_log;
- this->connect_delegate = connect_delegate.Pass();
+ this->connect_delegate = std::move(connect_delegate);
return make_scoped_ptr(new WebSocketStreamRequest);
}
@@ -746,7 +753,7 @@ class WebSocketChannelTest : public ::testing::Test {
// Most tests aren't concerned with flow control from the renderer, so allow
// MAX_INT quota units.
channel_->SendFlowControl(kPlentyOfQuota);
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
}
// Returns a WebSocketEventInterface to be passed to the WebSocketChannel.
@@ -761,7 +768,7 @@ class WebSocketChannelTest : public ::testing::Test {
// will have unpleasant compile errors.
template <class T>
void set_stream(scoped_ptr<T> stream) {
- stream_ = stream.Pass();
+ stream_ = std::move(stream);
}
// A struct containing the data that will be used to connect the channel.
@@ -856,7 +863,7 @@ class ChannelDeletingFakeWebSocketEventInterface
return fixture_->DeleteIfDeleting(EVENT_ON_DATA_FRAME);
}
- ChannelState OnFlowControl(int64 quota) override {
+ ChannelState OnFlowControl(int64_t quota) override {
return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL);
}
@@ -869,7 +876,7 @@ class ChannelDeletingFakeWebSocketEventInterface
}
ChannelState OnDropChannel(bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) override {
return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL);
}
@@ -938,7 +945,7 @@ class WebSocketChannelStreamTest : public WebSocketChannelTest {
: mock_stream_(new StrictMock<MockWebSocketStream>) {}
void CreateChannelAndConnectSuccessfully() override {
- set_stream(mock_stream_.Pass());
+ set_stream(std::move(mock_stream_));
WebSocketChannelTest::CreateChannelAndConnectSuccessfully();
}
@@ -967,10 +974,10 @@ class WebSocketChannelFlowControlTest
protected:
// Tests using this fixture should use CreateChannelAndConnectWithQuota()
// instead of CreateChannelAndConnectSuccessfully().
- void CreateChannelAndConnectWithQuota(int64 quota) {
+ void CreateChannelAndConnectWithQuota(int64_t quota) {
CreateChannelAndConnect();
channel_->SendFlowControl(quota);
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
}
virtual void CreateChannelAndConnectSuccesfully() { NOTREACHED(); }
@@ -1039,7 +1046,7 @@ TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_DATA_FRAME;
CreateChannelAndConnectSuccessfully();
@@ -1052,7 +1059,7 @@ TEST_F(WebSocketChannelDeletingTest, OnDataFrameAsync) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_DATA_FRAME;
CreateChannelAndConnectSuccessfully();
@@ -1088,7 +1095,7 @@ TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_CLOSING_HANDSHAKE;
CreateChannelAndConnectSuccessfully();
EXPECT_EQ(NULL, channel_.get());
@@ -1101,7 +1108,7 @@ TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeAsync) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_CLOSING_HANDSHAKE;
CreateChannelAndConnectSuccessfully();
ASSERT_TRUE(channel_);
@@ -1124,7 +1131,7 @@ TEST_F(WebSocketChannelDeletingTest, OnDropChannelReadError) {
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_FAILED);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_DROP_CHANNEL;
CreateChannelAndConnectSuccessfully();
ASSERT_TRUE(channel_);
@@ -1138,7 +1145,7 @@ TEST_F(WebSocketChannelDeletingTest, OnNotifyStartOpeningHandshakeError) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_START_OPENING_HANDSHAKE;
CreateChannelAndConnectSuccessfully();
@@ -1156,7 +1163,7 @@ TEST_F(WebSocketChannelDeletingTest, OnNotifyFinishOpeningHandshakeError) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FINISH_OPENING_HANDSHAKE;
CreateChannelAndConnectSuccessfully();
@@ -1189,7 +1196,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelInOnReadDone) {
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_WS_PROTOCOL_ERROR);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
ASSERT_TRUE(channel_);
@@ -1203,7 +1210,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueToMaskedFrame) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1216,7 +1223,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrame) {
static const InitFrame frames[] = {
{FINAL_FRAME, 0xF, NOT_MASKED, ""}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1230,7 +1237,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrameNull) {
static const InitFrame frames[] = {
{FINAL_FRAME, 0xF, NOT_MASKED, NULL}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1245,7 +1252,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterClose) {
CLOSE_DATA(NORMAL_CLOSURE, "Success")},
{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1260,7 +1267,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterCloseNull) {
CLOSE_DATA(NORMAL_CLOSURE, "Success")},
{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, NULL}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1272,7 +1279,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCode) {
new ReadableFakeWebSocketStream);
static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, ""}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1284,7 +1291,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCodeNull) {
new ReadableFakeWebSocketStream);
static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, NULL}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1298,7 +1305,7 @@ TEST_F(WebSocketChannelDeletingTest, FailChannelDueInvalidCloseReason) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
deleting_ = EVENT_ON_FAIL_CHANNEL;
CreateChannelAndConnectSuccessfully();
@@ -1314,7 +1321,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) {
CreateChannelAndConnect();
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
}
TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) {
@@ -1361,7 +1368,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1386,7 +1393,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_CONNECTION_CLOSED);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1408,7 +1415,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionCloseAfterHandshake) {
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_CONNECTION_CLOSED);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1429,7 +1436,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) {
// until we expect it to be.
Checkpoint checkpoint;
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1459,7 +1466,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "WORLD"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1);
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames2);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1501,7 +1508,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, FragmentedMessage) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1);
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2);
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1539,7 +1546,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NullMessage) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, NULL}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(
@@ -1554,7 +1561,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncAbnormalClosure) {
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_CONNECTION_CLOSED);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1573,7 +1580,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionReset) {
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_CONNECTION_RESET);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1594,7 +1601,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1617,7 +1624,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) {
static const InitFrame frames[] = {{FINAL_FRAME, 4, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1648,7 +1655,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1);
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2);
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1675,7 +1682,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, PongWithNullData) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, NULL}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
@@ -1693,7 +1700,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, " WORLD"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -1722,7 +1729,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, SmallWriteDoesntUpdateQuota) {
channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("B"));
}
-// If we send enough to go below send_quota_low_water_mask_ we should get our
+// If we send enough to go below |send_quota_low_water_mark_| we should get our
// quota refreshed.
TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) {
set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream));
@@ -1868,7 +1875,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_CONNECTION_CLOSED);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(*event_interface_, OnClosingHandshake());
@@ -1888,7 +1895,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_CONNECTION_CLOSED);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(*event_interface_, OnClosingHandshake());
@@ -1905,7 +1912,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, SyncProtocolErrorGivesStatus1002) {
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_WS_PROTOCOL_ERROR);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
@@ -1920,7 +1927,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncProtocolErrorGivesStatus1002) {
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_WS_PROTOCOL_ERROR);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
@@ -1944,7 +1951,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, StartHandshakeRequest) {
new WebSocketHandshakeRequestInfo(GURL("ws://www.example.com/"),
base::Time()));
connect_data_.creator.connect_delegate->OnStartOpeningHandshake(
- request_info.Pass());
+ std::move(request_info));
base::MessageLoop::current()->RunUntilIdle();
}
@@ -1968,7 +1975,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, FinishHandshakeRequest) {
response_headers,
base::Time()));
connect_data_.creator.connect_delegate->OnFinishOpeningHandshake(
- response_info.Pass());
+ std::move(response_info));
base::MessageLoop::current()->RunUntilIdle();
}
@@ -1995,8 +2002,8 @@ TEST_F(WebSocketChannelEventInterfaceTest, FailJustAfterHandshake) {
"OK",
response_headers,
base::Time()));
- connect_delegate->OnStartOpeningHandshake(request_info.Pass());
- connect_delegate->OnFinishOpeningHandshake(response_info.Pass());
+ connect_delegate->OnStartOpeningHandshake(std::move(request_info));
+ connect_delegate->OnFinishOpeningHandshake(std::move(response_info));
connect_delegate->OnFailure("bye");
base::MessageLoop::current()->RunUntilIdle();
@@ -2012,7 +2019,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataAfterCloseIsRejected) {
CLOSE_DATA(NORMAL_CLOSURE, "OK")},
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "Payload"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
@@ -2034,7 +2041,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, OneByteClosePayloadMessage) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, "\x03"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(
@@ -2054,7 +2061,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadReservedStatusMessage) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(ABNORMAL_CLOSURE, "Not valid on wire")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(
@@ -2074,7 +2081,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadInvalidReason) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(
@@ -2095,11 +2102,12 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReservedBitsMustNotBeSet) {
NOT_MASKED, "sakana"}};
// It is not worth adding support for reserved bits to InitFrame just for this
// one test, so set the bit manually.
- ScopedVector<WebSocketFrame> raw_frames = CreateFrameVector(frames);
+ std::vector<scoped_ptr<WebSocketFrame>> raw_frames =
+ CreateFrameVector(frames);
raw_frames[0]->header.reserved1 = true;
- stream->PrepareRawReadFrames(
- ReadableFakeWebSocketStream::SYNC, OK, raw_frames.Pass());
- set_stream(stream.Pass());
+ stream->PrepareRawReadFrames(ReadableFakeWebSocketStream::SYNC, OK,
+ std::move(raw_frames));
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(*event_interface_,
@@ -2118,7 +2126,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
new ReadableFakeWebSocketStream);
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_IO_PENDING);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
// This checkpoint object verifies that the OnDropChannel message comes after
@@ -2155,7 +2163,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
Checkpoint checkpoint;
@@ -2191,11 +2199,11 @@ TEST_F(WebSocketChannelStreamTest, FlowControlEarly) {
EXPECT_CALL(checkpoint, Call(2));
}
- set_stream(mock_stream_.Pass());
+ set_stream(std::move(mock_stream_));
CreateChannelAndConnect();
channel_->SendFlowControl(kPlentyOfQuota);
checkpoint.Call(1);
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
checkpoint.Call(2);
}
@@ -2216,9 +2224,9 @@ TEST_F(WebSocketChannelStreamTest, FlowControlLate) {
EXPECT_CALL(checkpoint, Call(2));
}
- set_stream(mock_stream_.Pass());
+ set_stream(std::move(mock_stream_));
CreateChannelAndConnect();
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
checkpoint.Call(1);
channel_->SendFlowControl(kPlentyOfQuota);
checkpoint.Call(2);
@@ -2234,10 +2242,10 @@ TEST_F(WebSocketChannelStreamTest, FlowControlStopsReadFrames) {
EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
.WillOnce(ReturnFrames(&frames));
- set_stream(mock_stream_.Pass());
+ set_stream(std::move(mock_stream_));
CreateChannelAndConnect();
channel_->SendFlowControl(4);
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
}
// Providing extra quota causes ReadFrames() to be called again.
@@ -2257,10 +2265,10 @@ TEST_F(WebSocketChannelStreamTest, FlowControlStartsWithMoreQuota) {
.WillOnce(Return(ERR_IO_PENDING));
}
- set_stream(mock_stream_.Pass());
+ set_stream(std::move(mock_stream_));
CreateChannelAndConnect();
channel_->SendFlowControl(4);
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
checkpoint.Call(1);
channel_->SendFlowControl(4);
}
@@ -2284,10 +2292,10 @@ TEST_F(WebSocketChannelStreamTest, ReadFramesNotCalledUntilQuotaAvailable) {
.WillOnce(Return(ERR_IO_PENDING));
}
- set_stream(mock_stream_.Pass());
+ set_stream(std::move(mock_stream_));
CreateChannelAndConnect();
channel_->SendFlowControl(2);
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
checkpoint.Call(1);
channel_->SendFlowControl(2);
checkpoint.Call(2);
@@ -2302,7 +2310,7 @@ TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitSync) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -2333,7 +2341,7 @@ TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitAsync) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
Checkpoint checkpoint;
{
InSequence s;
@@ -2380,7 +2388,7 @@ TEST_F(WebSocketChannelFlowControlTest, MultipleFrameSplit) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
NOT_MASKED, "FINAL FRAME IS 24 BYTES."}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -2424,7 +2432,7 @@ TEST_F(WebSocketChannelFlowControlTest, EmptyMessageNoQuota) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText,
NOT_MASKED, "THIRD MESSAGE"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
{
InSequence s;
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
@@ -2520,7 +2528,7 @@ TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) {
// We store the parameters that were passed to ReadFrames() so that we can
// call them explicitly later.
CompletionCallback read_callback;
- ScopedVector<WebSocketFrame>* frames = NULL;
+ std::vector<scoped_ptr<WebSocketFrame>>* frames = NULL;
// These are not interesting.
EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
@@ -2702,7 +2710,7 @@ TEST_F(WebSocketChannelStreamTest, PongInTheMiddleOfDataMessage) {
static const InitFrame expected3[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
MASKED, "World"}};
- ScopedVector<WebSocketFrame>* read_frames;
+ std::vector<scoped_ptr<WebSocketFrame>>* read_frames;
CompletionCallback read_callback;
EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber());
@@ -2823,7 +2831,7 @@ TEST_F(WebSocketChannelStreamTest, SendGoingAwayOnRendererQuotaExceeded) {
// protocol also has Binary frames and those need to be 8-bit clean. For the
// sake of completeness, this test verifies that they are.
TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) {
- ScopedVector<WebSocketFrame>* frames = NULL;
+ std::vector<scoped_ptr<WebSocketFrame>>* frames = NULL;
EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber());
@@ -2838,7 +2846,7 @@ TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) {
std::vector<char>(kBinaryBlob, kBinaryBlob + kBinaryBlobSize));
ASSERT_TRUE(frames != NULL);
ASSERT_EQ(1U, frames->size());
- const WebSocketFrame* out_frame = (*frames)[0];
+ const WebSocketFrame* out_frame = (*frames)[0].get();
EXPECT_EQ(kBinaryBlobSize, out_frame->header.payload_length);
ASSERT_TRUE(out_frame->data.get());
EXPECT_EQ(0, memcmp(kBinaryBlob, out_frame->data->data(), kBinaryBlobSize));
@@ -2853,13 +2861,13 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) {
frame_header.payload_length = kBinaryBlobSize;
frame->data = new IOBuffer(kBinaryBlobSize);
memcpy(frame->data->data(), kBinaryBlob, kBinaryBlobSize);
- ScopedVector<WebSocketFrame> frames;
- frames.push_back(frame.Pass());
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
+ frames.push_back(std::move(frame));
scoped_ptr<ReadableFakeWebSocketStream> stream(
new ReadableFakeWebSocketStream);
- stream->PrepareRawReadFrames(
- ReadableFakeWebSocketStream::SYNC, OK, frames.Pass());
- set_stream(stream.Pass());
+ stream->PrepareRawReadFrames(ReadableFakeWebSocketStream::SYNC, OK,
+ std::move(frames));
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(_));
EXPECT_CALL(*event_interface_,
@@ -2975,7 +2983,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReceivedInvalidUtf8) {
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xff"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota));
@@ -3167,7 +3175,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, BogusContinuation) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText,
NOT_MASKED, "frame2"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota));
@@ -3191,7 +3199,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, MessageStartingWithContinuation) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
NOT_MASKED, "continuation"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota));
@@ -3212,7 +3220,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataFramesNonEmptyOrFinal) {
NOT_MASKED, ""},
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, ""}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(stream.Pass());
+ set_stream(std::move(stream));
EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota));
@@ -3238,7 +3246,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, OnSSLCertificateErrorCalled) {
CreateChannelAndConnect();
connect_data_.creator.connect_delegate->OnSSLCertificateError(
- fake_callbacks.Pass(), ssl_info, fatal);
+ std::move(fake_callbacks), ssl_info, fatal);
}
// If we receive another frame after Close, it is not valid. It is not
@@ -3296,14 +3304,14 @@ class WebSocketChannelStreamTimeoutTest : public WebSocketChannelStreamTest {
WebSocketChannelStreamTimeoutTest() {}
void CreateChannelAndConnectSuccessfully() override {
- set_stream(mock_stream_.Pass());
+ set_stream(std::move(mock_stream_));
CreateChannelAndConnect();
channel_->SendFlowControl(kPlentyOfQuota);
channel_->SetClosingHandshakeTimeoutForTesting(
TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis));
channel_->SetUnderlyingConnectionCloseTimeoutForTesting(
TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis));
- connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass());
+ connect_data_.creator.connect_delegate->OnSuccess(std::move(stream_));
}
};
@@ -3380,7 +3388,7 @@ TEST_F(WebSocketChannelStreamTimeoutTest, ConnectionCloseTimesOut) {
EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber());
TestClosure completion;
- ScopedVector<WebSocketFrame>* read_frames = NULL;
+ std::vector<scoped_ptr<WebSocketFrame>>* read_frames = NULL;
CompletionCallback read_callback;
{
InSequence s;
@@ -3413,5 +3421,28 @@ TEST_F(WebSocketChannelStreamTimeoutTest, ConnectionCloseTimesOut) {
completion.WaitForResult();
}
+// Verify that current_send_quota() returns a non-zero value for a newly
+// connected channel.
+TEST_F(WebSocketChannelTest, CurrentSendQuotaNonZero) {
+ CreateChannelAndConnectSuccessfully();
+ EXPECT_GT(channel_->current_send_quota(), 0);
+}
+
+// Verify that current_send_quota() is updated when SendFrame() is called.
+TEST_F(WebSocketChannelTest, CurrentSendQuotaUpdated) {
+ const int kMessageSize = 5;
+ set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream));
+ CreateChannelAndConnectSuccessfully();
+
+ int initial_send_quota = channel_->current_send_quota();
+ EXPECT_GE(initial_send_quota, kMessageSize);
+
+ channel_->SendFrame(
+ true, WebSocketFrameHeader::kOpCodeText,
+ std::vector<char>(static_cast<size_t>(kMessageSize), 'a'));
+ int new_send_quota = channel_->current_send_quota();
+ EXPECT_EQ(kMessageSize, initial_send_quota - new_send_quota);
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/websockets/websocket_deflate_parameters.h b/chromium/net/websockets/websocket_deflate_parameters.h
index a377e523a91..1898e1d7a12 100644
--- a/chromium/net/websockets/websocket_deflate_parameters.h
+++ b/chromium/net/websockets/websocket_deflate_parameters.h
@@ -6,6 +6,7 @@
#define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_
#include <stdint.h>
+
#include <string>
#include "base/logging.h"
diff --git a/chromium/net/websockets/websocket_deflate_predictor.h b/chromium/net/websockets/websocket_deflate_predictor.h
index c786d805b56..38566ddfa50 100644
--- a/chromium/net/websockets/websocket_deflate_predictor.h
+++ b/chromium/net/websockets/websocket_deflate_predictor.h
@@ -5,8 +5,11 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PREDICTOR_H_
#define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PREDICTOR_H_
-#include "base/basictypes.h"
-#include "base/memory/scoped_vector.h"
+#include <stddef.h>
+
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
namespace net {
@@ -38,7 +41,7 @@ class NET_EXPORT_PRIVATE WebSocketDeflatePredictor {
// but future frames may contain control message frames.
// |frames[frame_index]| cannot be recorded yet and all preceding
// data frames have to be already recorded when this method is called.
- virtual Result Predict(const ScopedVector<WebSocketFrame>& frames,
+ virtual Result Predict(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
size_t frame_index) = 0;
// Records frame data for future prediction.
diff --git a/chromium/net/websockets/websocket_deflate_predictor_impl.cc b/chromium/net/websockets/websocket_deflate_predictor_impl.cc
index 0d1a5c20258..77366070e9b 100644
--- a/chromium/net/websockets/websocket_deflate_predictor_impl.cc
+++ b/chromium/net/websockets/websocket_deflate_predictor_impl.cc
@@ -9,7 +9,7 @@ namespace net {
typedef WebSocketDeflatePredictor::Result Result;
Result WebSocketDeflatePredictorImpl::Predict(
- const ScopedVector<WebSocketFrame>& frames,
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames,
size_t frame_index) {
return DEFLATE;
}
diff --git a/chromium/net/websockets/websocket_deflate_predictor_impl.h b/chromium/net/websockets/websocket_deflate_predictor_impl.h
index 680ec56290a..6086431010f 100644
--- a/chromium/net/websockets/websocket_deflate_predictor_impl.h
+++ b/chromium/net/websockets/websocket_deflate_predictor_impl.h
@@ -5,9 +5,11 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PREDICTOR_IMPL_H_
#define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PREDICTOR_IMPL_H_
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_vector.h"
+#include <stddef.h>
+
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_deflate_predictor.h"
@@ -20,7 +22,7 @@ class NET_EXPORT_PRIVATE WebSocketDeflatePredictorImpl
public:
~WebSocketDeflatePredictorImpl() override {}
- Result Predict(const ScopedVector<WebSocketFrame>& frames,
+ Result Predict(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
size_t frame_index) override;
void RecordInputDataFrame(const WebSocketFrame* frame) override;
void RecordWrittenDataFrame(const WebSocketFrame* frame) override;
diff --git a/chromium/net/websockets/websocket_deflate_predictor_impl_test.cc b/chromium/net/websockets/websocket_deflate_predictor_impl_test.cc
index 79c54e10d06..279ca48f50d 100644
--- a/chromium/net/websockets/websocket_deflate_predictor_impl_test.cc
+++ b/chromium/net/websockets/websocket_deflate_predictor_impl_test.cc
@@ -4,8 +4,8 @@
#include "net/websockets/websocket_deflate_predictor_impl.h"
-#include "base/basictypes.h"
-#include "base/memory/scoped_vector.h"
+#include <vector>
+
#include "net/websockets/websocket_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,8 +17,9 @@ typedef WebSocketDeflatePredictor::Result Result;
TEST(WebSocketDeflatePredictorImpl, Predict) {
WebSocketDeflatePredictorImpl predictor;
- ScopedVector<WebSocketFrame> frames;
- frames.push_back(new WebSocketFrame(WebSocketFrameHeader::kOpCodeText));
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
+ frames.push_back(
+ make_scoped_ptr(new WebSocketFrame(WebSocketFrameHeader::kOpCodeText)));
Result result = predictor.Predict(frames, 0);
EXPECT_EQ(WebSocketDeflatePredictor::DEFLATE, result);
diff --git a/chromium/net/websockets/websocket_deflate_stream.cc b/chromium/net/websockets/websocket_deflate_stream.cc
index cf169035653..798d9b7d462 100644
--- a/chromium/net/websockets/websocket_deflate_stream.cc
+++ b/chromium/net/websockets/websocket_deflate_stream.cc
@@ -4,14 +4,16 @@
#include "net/websockets/websocket_deflate_stream.h"
+#include <stdint.h>
#include <algorithm>
#include <string>
+#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -38,14 +40,14 @@ WebSocketDeflateStream::WebSocketDeflateStream(
scoped_ptr<WebSocketStream> stream,
const WebSocketDeflateParameters& params,
scoped_ptr<WebSocketDeflatePredictor> predictor)
- : stream_(stream.Pass()),
+ : stream_(std::move(stream)),
deflater_(params.client_context_take_over_mode()),
inflater_(kChunkSize, kChunkSize),
reading_state_(NOT_READING),
writing_state_(NOT_WRITING),
current_reading_opcode_(WebSocketFrameHeader::kOpCodeText),
current_writing_opcode_(WebSocketFrameHeader::kOpCodeText),
- predictor_(predictor.Pass()) {
+ predictor_(std::move(predictor)) {
DCHECK(stream_);
DCHECK(params.IsValidAsResponse());
int client_max_window_bits = 15;
@@ -59,8 +61,9 @@ WebSocketDeflateStream::WebSocketDeflateStream(
WebSocketDeflateStream::~WebSocketDeflateStream() {}
-int WebSocketDeflateStream::ReadFrames(ScopedVector<WebSocketFrame>* frames,
- const CompletionCallback& callback) {
+int WebSocketDeflateStream::ReadFrames(
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
+ const CompletionCallback& callback) {
int result = stream_->ReadFrames(
frames,
base::Bind(&WebSocketDeflateStream::OnReadComplete,
@@ -75,8 +78,9 @@ int WebSocketDeflateStream::ReadFrames(ScopedVector<WebSocketFrame>* frames,
return InflateAndReadIfNecessary(frames, callback);
}
-int WebSocketDeflateStream::WriteFrames(ScopedVector<WebSocketFrame>* frames,
- const CompletionCallback& callback) {
+int WebSocketDeflateStream::WriteFrames(
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
+ const CompletionCallback& callback) {
int result = Deflate(frames);
if (result != OK)
return result;
@@ -96,7 +100,7 @@ std::string WebSocketDeflateStream::GetExtensions() const {
}
void WebSocketDeflateStream::OnReadComplete(
- ScopedVector<WebSocketFrame>* frames,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback,
int result) {
if (result != OK) {
@@ -110,30 +114,29 @@ void WebSocketDeflateStream::OnReadComplete(
callback.Run(r);
}
-int WebSocketDeflateStream::Deflate(ScopedVector<WebSocketFrame>* frames) {
- ScopedVector<WebSocketFrame> frames_to_write;
+int WebSocketDeflateStream::Deflate(
+ std::vector<scoped_ptr<WebSocketFrame>>* frames) {
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_write;
// Store frames of the currently processed message if writing_state_ equals to
// WRITING_POSSIBLY_COMPRESSED_MESSAGE.
- ScopedVector<WebSocketFrame> frames_of_message;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_of_message;
for (size_t i = 0; i < frames->size(); ++i) {
DCHECK(!(*frames)[i]->header.reserved1);
if (!WebSocketFrameHeader::IsKnownDataOpCode((*frames)[i]->header.opcode)) {
- frames_to_write.push_back((*frames)[i]);
- (*frames)[i] = NULL;
+ frames_to_write.push_back(std::move((*frames)[i]));
continue;
}
if (writing_state_ == NOT_WRITING)
OnMessageStart(*frames, i);
- scoped_ptr<WebSocketFrame> frame((*frames)[i]);
- (*frames)[i] = NULL;
+ scoped_ptr<WebSocketFrame> frame(std::move((*frames)[i]));
predictor_->RecordInputDataFrame(frame.get());
if (writing_state_ == WRITING_UNCOMPRESSED_MESSAGE) {
if (frame->header.final)
writing_state_ = NOT_WRITING;
predictor_->RecordWrittenDataFrame(frame.get());
- frames_to_write.push_back(frame.Pass());
+ frames_to_write.push_back(std::move(frame));
current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation;
} else {
if (frame->data.get() &&
@@ -162,7 +165,7 @@ int WebSocketDeflateStream::Deflate(ScopedVector<WebSocketFrame>* frames) {
} else {
DCHECK_EQ(WRITING_POSSIBLY_COMPRESSED_MESSAGE, writing_state_);
bool final = frame->header.final;
- frames_of_message.push_back(frame.Pass());
+ frames_of_message.push_back(std::move(frame));
if (final) {
int result = AppendPossiblyCompressedMessage(&frames_of_message,
&frames_to_write);
@@ -180,8 +183,9 @@ int WebSocketDeflateStream::Deflate(ScopedVector<WebSocketFrame>* frames) {
}
void WebSocketDeflateStream::OnMessageStart(
- const ScopedVector<WebSocketFrame>& frames, size_t index) {
- WebSocketFrame* frame = frames[index];
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames,
+ size_t index) {
+ WebSocketFrame* frame = frames[index].get();
current_writing_opcode_ = frame->header.opcode;
DCHECK(current_writing_opcode_ == WebSocketFrameHeader::kOpCodeText ||
current_writing_opcode_ == WebSocketFrameHeader::kOpCodeBinary);
@@ -204,7 +208,7 @@ void WebSocketDeflateStream::OnMessageStart(
int WebSocketDeflateStream::AppendCompressedFrame(
const WebSocketFrameHeader& header,
- ScopedVector<WebSocketFrame>* frames_to_write) {
+ std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write) {
const WebSocketFrameHeader::OpCode opcode = current_writing_opcode_;
scoped_refptr<IOBufferWithSize> compressed_payload =
deflater_.GetOutput(deflater_.CurrentOutputSize());
@@ -224,13 +228,13 @@ int WebSocketDeflateStream::AppendCompressedFrame(
current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation;
predictor_->RecordWrittenDataFrame(compressed.get());
- frames_to_write->push_back(compressed.Pass());
+ frames_to_write->push_back(std::move(compressed));
return OK;
}
int WebSocketDeflateStream::AppendPossiblyCompressedMessage(
- ScopedVector<WebSocketFrame>* frames,
- ScopedVector<WebSocketFrame>* frames_to_write) {
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write) {
DCHECK(!frames->empty());
const WebSocketFrameHeader::OpCode opcode = current_writing_opcode_;
@@ -242,9 +246,9 @@ int WebSocketDeflateStream::AppendPossiblyCompressedMessage(
return ERR_WS_PROTOCOL_ERROR;
}
- uint64 original_payload_length = 0;
+ uint64_t original_payload_length = 0;
for (size_t i = 0; i < frames->size(); ++i) {
- WebSocketFrame* frame = (*frames)[i];
+ WebSocketFrame* frame = (*frames)[i].get();
// Asserts checking that frames represent one whole data message.
DCHECK(WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode));
DCHECK_EQ(i == 0,
@@ -254,15 +258,14 @@ int WebSocketDeflateStream::AppendPossiblyCompressedMessage(
original_payload_length += frame->header.payload_length;
}
if (original_payload_length <=
- static_cast<uint64>(compressed_payload->size())) {
+ static_cast<uint64_t>(compressed_payload->size())) {
// Compression is not effective. Use the original frames.
for (size_t i = 0; i < frames->size(); ++i) {
- WebSocketFrame* frame = (*frames)[i];
- frames_to_write->push_back(frame);
- predictor_->RecordWrittenDataFrame(frame);
- (*frames)[i] = NULL;
+ scoped_ptr<WebSocketFrame> frame = std::move((*frames)[i]);
+ predictor_->RecordWrittenDataFrame(frame.get());
+ frames_to_write->push_back(std::move(frame));
}
- frames->weak_clear();
+ frames->clear();
return OK;
}
scoped_ptr<WebSocketFrame> compressed(new WebSocketFrame(opcode));
@@ -274,16 +277,17 @@ int WebSocketDeflateStream::AppendPossiblyCompressedMessage(
compressed->header.payload_length = compressed_payload->size();
predictor_->RecordWrittenDataFrame(compressed.get());
- frames_to_write->push_back(compressed.Pass());
+ frames_to_write->push_back(std::move(compressed));
return OK;
}
-int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) {
- ScopedVector<WebSocketFrame> frames_to_output;
- ScopedVector<WebSocketFrame> frames_passed;
+int WebSocketDeflateStream::Inflate(
+ std::vector<scoped_ptr<WebSocketFrame>>* frames) {
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_passed;
frames->swap(frames_passed);
for (size_t i = 0; i < frames_passed.size(); ++i) {
- scoped_ptr<WebSocketFrame> frame(frames_passed[i]);
+ scoped_ptr<WebSocketFrame> frame(std::move(frames_passed[i]));
frames_passed[i] = NULL;
DVLOG(3) << "Input frame: opcode=" << frame->header.opcode
<< " final=" << frame->header.final
@@ -291,7 +295,7 @@ int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) {
<< " payload_length=" << frame->header.payload_length;
if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
- frames_to_output.push_back(frame.Pass());
+ frames_to_output.push_back(std::move(frame));
continue;
}
@@ -313,7 +317,7 @@ int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) {
if (frame->header.final)
reading_state_ = NOT_READING;
current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation;
- frames_to_output.push_back(frame.Pass());
+ frames_to_output.push_back(std::move(frame));
} else {
DCHECK_EQ(reading_state_, READING_COMPRESSED_MESSAGE);
if (frame->data.get() &&
@@ -357,7 +361,7 @@ int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) {
<< " final=" << inflated->header.final
<< " reserved1=" << inflated->header.reserved1
<< " payload_length=" << inflated->header.payload_length;
- frames_to_output.push_back(inflated.Pass());
+ frames_to_output.push_back(std::move(inflated));
current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation;
if (is_final)
break;
@@ -371,7 +375,7 @@ int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) {
}
int WebSocketDeflateStream::InflateAndReadIfNecessary(
- ScopedVector<WebSocketFrame>* frames,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) {
int result = Inflate(frames);
while (result == ERR_IO_PENDING) {
diff --git a/chromium/net/websockets/websocket_deflate_stream.h b/chromium/net/websockets/websocket_deflate_stream.h
index e69a89d01c7..6143d0d1d7c 100644
--- a/chromium/net/websockets/websocket_deflate_stream.h
+++ b/chromium/net/websockets/websocket_deflate_stream.h
@@ -5,11 +5,13 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_
#define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_
+#include <stddef.h>
+
#include <string>
+#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_deflater.h"
@@ -46,9 +48,9 @@ class NET_EXPORT_PRIVATE WebSocketDeflateStream : public WebSocketStream {
~WebSocketDeflateStream() override;
// WebSocketStream functions.
- int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+ int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override;
- int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) override;
void Close() override;
std::string GetSubProtocol() const override;
@@ -69,23 +71,25 @@ class NET_EXPORT_PRIVATE WebSocketDeflateStream : public WebSocketStream {
};
// Handles asynchronous completion of ReadFrames() call on |stream_|.
- void OnReadComplete(ScopedVector<WebSocketFrame>* frames,
+ void OnReadComplete(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback,
int result);
// This function deflates |frames| and stores the result to |frames| itself.
- int Deflate(ScopedVector<WebSocketFrame>* frames);
- void OnMessageStart(const ScopedVector<WebSocketFrame>& frames, size_t index);
- int AppendCompressedFrame(const WebSocketFrameHeader& header,
- ScopedVector<WebSocketFrame>* frames_to_write);
+ int Deflate(std::vector<scoped_ptr<WebSocketFrame>>* frames);
+ void OnMessageStart(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
+ size_t index);
+ int AppendCompressedFrame(
+ const WebSocketFrameHeader& header,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write);
int AppendPossiblyCompressedMessage(
- ScopedVector<WebSocketFrame>* frames,
- ScopedVector<WebSocketFrame>* frames_to_write);
+ std::vector<scoped_ptr<WebSocketFrame>>* frames,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write);
// This function inflates |frames| and stores the result to |frames| itself.
- int Inflate(ScopedVector<WebSocketFrame>* frames);
+ int Inflate(std::vector<scoped_ptr<WebSocketFrame>>* frames);
- int InflateAndReadIfNecessary(ScopedVector<WebSocketFrame>* frames,
+ int InflateAndReadIfNecessary(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback);
const scoped_ptr<WebSocketStream> stream_;
diff --git a/chromium/net/websockets/websocket_deflate_stream_test.cc b/chromium/net/websockets/websocket_deflate_stream_test.cc
index 4d5d9f26748..a470e2a2a9d 100644
--- a/chromium/net/websockets/websocket_deflate_stream_test.cc
+++ b/chromium/net/websockets/websocket_deflate_stream_test.cc
@@ -4,15 +4,18 @@
#include "net/websockets/websocket_deflate_stream.h"
+#include <stddef.h>
#include <stdint.h>
#include <deque>
+#include <iterator>
#include <string>
+#include <utility>
+#include <vector>
-#include "base/basictypes.h"
#include "base/bind.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -73,7 +76,11 @@ std::string ToString(const WebSocketFrame* frame) {
: "";
}
-void AppendTo(ScopedVector<WebSocketFrame>* frames,
+std::string ToString(const scoped_ptr<WebSocketFrame>& frame) {
+ return ToString(frame.get());
+}
+
+void AppendTo(std::vector<scoped_ptr<WebSocketFrame>>* frames,
WebSocketFrameHeader::OpCode opcode,
FrameFlag flag,
const std::string& data) {
@@ -82,24 +89,26 @@ void AppendTo(ScopedVector<WebSocketFrame>* frames,
frame->header.reserved1 = (flag & kReserved1);
frame->data = ToIOBuffer(data);
frame->header.payload_length = data.size();
- frames->push_back(frame.release());
+ frames->push_back(std::move(frame));
}
-void AppendTo(ScopedVector<WebSocketFrame>* frames,
+void AppendTo(std::vector<scoped_ptr<WebSocketFrame>>* frames,
WebSocketFrameHeader::OpCode opcode,
FrameFlag flag) {
scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode));
frame->header.final = (flag & kFinal);
frame->header.reserved1 = (flag & kReserved1);
- frames->push_back(frame.release());
+ frames->push_back(std::move(frame));
}
class MockWebSocketStream : public WebSocketStream {
public:
- MOCK_METHOD2(ReadFrames, int(ScopedVector<WebSocketFrame>*,
- const CompletionCallback&));
- MOCK_METHOD2(WriteFrames, int(ScopedVector<WebSocketFrame>*,
- const CompletionCallback&));
+ MOCK_METHOD2(ReadFrames,
+ int(std::vector<scoped_ptr<WebSocketFrame>>*,
+ const CompletionCallback&));
+ MOCK_METHOD2(WriteFrames,
+ int(std::vector<scoped_ptr<WebSocketFrame>>*,
+ const CompletionCallback&));
MOCK_METHOD0(Close, void());
MOCK_CONST_METHOD0(GetSubProtocol, std::string());
MOCK_CONST_METHOD0(GetExtensions, std::string());
@@ -125,7 +134,7 @@ class WebSocketDeflatePredictorMock : public WebSocketDeflatePredictor {
}
// WebSocketDeflatePredictor functions.
- Result Predict(const ScopedVector<WebSocketFrame>& frames,
+ Result Predict(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
size_t frame_index) override {
return result_;
}
@@ -179,13 +188,14 @@ class WebSocketDeflatePredictorMock : public WebSocketDeflatePredictor {
}
frames_written_.pop_front();
}
- void AddFramesToBeInput(const ScopedVector<WebSocketFrame>& frames) {
+ void AddFramesToBeInput(
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames) {
for (size_t i = 0; i < frames.size(); ++i)
- AddFrameToBeInput(frames[i]);
+ AddFrameToBeInput(frames[i].get());
}
- void VerifySentFrames(const ScopedVector<WebSocketFrame>& frames) {
+ void VerifySentFrames(const std::vector<scoped_ptr<WebSocketFrame>>& frames) {
for (size_t i = 0; i < frames.size(); ++i)
- VerifySentFrame(frames[i]);
+ VerifySentFrame(frames[i].get());
}
// Call this method in order to disable checks in the destructor when
// WriteFrames fails.
@@ -280,7 +290,7 @@ class WebSocketDeflateStreamWithClientWindowBitsTest
}
protected:
- ScopedVector<WebSocketFrame> frames_;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_;
};
// ReadFrameStub is a stub for WebSocketStream::ReadFrames.
@@ -290,12 +300,13 @@ class ReadFramesStub {
public:
explicit ReadFramesStub(int result) : result_(result) {}
- ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output)
+ ReadFramesStub(int result,
+ std::vector<scoped_ptr<WebSocketFrame>>* frames_to_output)
: result_(result) {
frames_to_output_.swap(*frames_to_output);
}
- int Call(ScopedVector<WebSocketFrame>* frames,
+ int Call(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) {
DCHECK(frames->empty());
frames_passed_ = frames;
@@ -305,16 +316,16 @@ class ReadFramesStub {
}
int result() const { return result_; }
- const CompletionCallback callback() const { return callback_; }
- ScopedVector<WebSocketFrame>* frames_passed() {
+ const CompletionCallback& callback() const { return callback_; }
+ std::vector<scoped_ptr<WebSocketFrame>>* frames_passed() {
return frames_passed_;
}
private:
int result_;
CompletionCallback callback_;
- ScopedVector<WebSocketFrame> frames_to_output_;
- ScopedVector<WebSocketFrame>* frames_passed_;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output_;
+ std::vector<scoped_ptr<WebSocketFrame>>* frames_passed_;
};
// WriteFramesStub is a stub for WebSocketStream::WriteFrames.
@@ -326,28 +337,29 @@ class WriteFramesStub {
int result)
: result_(result), predictor_(predictor) {}
- int Call(ScopedVector<WebSocketFrame>* frames,
+ int Call(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) {
- frames_.insert(frames_.end(), frames->begin(), frames->end());
- frames->weak_clear();
+ frames_.insert(frames_.end(), std::make_move_iterator(frames->begin()),
+ std::make_move_iterator(frames->end()));
+ frames->clear();
callback_ = callback;
predictor_->VerifySentFrames(frames_);
return result_;
}
int result() const { return result_; }
- const CompletionCallback callback() const { return callback_; }
- ScopedVector<WebSocketFrame>* frames() { return &frames_; }
+ const CompletionCallback& callback() const { return callback_; }
+ std::vector<scoped_ptr<WebSocketFrame>>* frames() { return &frames_; }
private:
int result_;
CompletionCallback callback_;
- ScopedVector<WebSocketFrame> frames_;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_;
WebSocketDeflatePredictorMock* predictor_;
};
TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
CompletionCallback callback;
{
InSequence s;
@@ -358,13 +370,13 @@ TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
}
TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kFinal,
"hello");
ReadFramesStub stub(OK, &frames_to_output);
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -382,7 +394,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) {
TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) {
ReadFramesStub stub(ERR_IO_PENDING);
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
MockCallback mock_callback, checkpoint;
CompletionCallback callback =
base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
@@ -413,7 +425,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) {
TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) {
ReadFramesStub stub(ERR_IO_PENDING);
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
MockCallback mock_callback, checkpoint;
CompletionCallback callback =
base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
@@ -439,14 +451,14 @@ TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) {
}
TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameImmediately) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kFinal | kReserved1,
std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -465,7 +477,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameAsync) {
MockCallback mock_callback, checkpoint;
CompletionCallback callback =
base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -492,7 +504,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameAsync) {
TEST_F(WebSocketDeflateStreamTest,
ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
const std::string data1("\xf2", 1);
const std::string data2("\x48\xcd\xc9\xc9\x07\x00", 6);
AppendTo(&frames_to_output,
@@ -503,7 +515,7 @@ TEST_F(WebSocketDeflateStreamTest,
MockCallback mock_callback, checkpoint;
CompletionCallback callback =
base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -533,14 +545,14 @@ TEST_F(WebSocketDeflateStreamTest,
TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) {
const std::string data("\xf2\x48\xcdINVALID", 10);
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kFinal | kReserved1,
data);
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -555,7 +567,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) {
TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
const std::string data1("\xf2\x48\xcd", 3);
const std::string data2("\xc9\xc9\x07\x00", 4);
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kReserved1,
@@ -566,7 +578,7 @@ TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
data2);
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -582,7 +594,7 @@ TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
}
TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kNoFlag);
@@ -591,7 +603,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
kFinal);
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -612,7 +624,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
}
TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kReserved1,
@@ -622,7 +634,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
kFinal);
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -640,7 +652,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
TEST_F(WebSocketDeflateStreamTest,
ReadCompressedFrameFollowedByEmptyFrame) {
const std::string data("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kReserved1,
@@ -650,7 +662,7 @@ TEST_F(WebSocketDeflateStreamTest,
kFinal);
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -668,7 +680,7 @@ TEST_F(WebSocketDeflateStreamTest,
TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) {
const std::string data1("\xf2\x48\xcd", 3);
const std::string data2("\xc9\xc9\x07\x00", 4);
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kReserved1,
@@ -677,7 +689,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) {
AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodeText, kFinal, data2);
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -703,7 +715,7 @@ TEST_F(WebSocketDeflateStreamTest, SplitToMultipleFramesInReadFrames) {
deflater.AddBytes(original_data.data(), original_data.size());
deflater.Finish();
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeBinary,
kFinal | kReserved1,
@@ -711,7 +723,7 @@ TEST_F(WebSocketDeflateStreamTest, SplitToMultipleFramesInReadFrames) {
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -745,7 +757,7 @@ TEST_F(WebSocketDeflateStreamTest, InflaterInternalDataCanBeEmpty) {
deflater.AddBytes(original_data.data(), original_data.size());
deflater.Finish();
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeBinary,
kReserved1,
@@ -757,7 +769,7 @@ TEST_F(WebSocketDeflateStreamTest, InflaterInternalDataCanBeEmpty) {
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -783,7 +795,7 @@ TEST_F(WebSocketDeflateStreamTest,
Reserved1TurnsOnDuringReadingCompressedContinuationFrame) {
const std::string data1("\xf2\x48\xcd", 3);
const std::string data2("\xc9\xc9\x07\x00", 4);
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kReserved1,
@@ -794,7 +806,7 @@ TEST_F(WebSocketDeflateStreamTest,
data2);
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -807,7 +819,7 @@ TEST_F(WebSocketDeflateStreamTest,
TEST_F(WebSocketDeflateStreamTest,
Reserved1TurnsOnDuringReadingUncompressedContinuationFrame) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kNoFlag,
@@ -818,7 +830,7 @@ TEST_F(WebSocketDeflateStreamTest,
"world");
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -830,7 +842,7 @@ TEST_F(WebSocketDeflateStreamTest,
}
TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kFinal | kReserved1,
@@ -842,7 +854,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
std::string("\x4a\x86\x33\x8d\x00\x00", 6));
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -862,7 +874,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
}
TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kFinal,
@@ -873,7 +885,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
"uncompressed2");
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -894,7 +906,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
TEST_F(WebSocketDeflateStreamTest,
ReadCompressedMessageThenUncompressedMessage) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kFinal | kReserved1,
@@ -906,7 +918,7 @@ TEST_F(WebSocketDeflateStreamTest,
"uncompressed");
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -927,7 +939,7 @@ TEST_F(WebSocketDeflateStreamTest,
TEST_F(WebSocketDeflateStreamTest,
ReadUncompressedMessageThenCompressedMessage) {
- ScopedVector<WebSocketFrame> frames_to_output;
+ std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
AppendTo(&frames_to_output,
WebSocketFrameHeader::kOpCodeText,
kFinal,
@@ -939,7 +951,7 @@ TEST_F(WebSocketDeflateStreamTest,
"\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
ReadFramesStub stub(OK, &frames_to_output);
CompletionCallback callback;
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
@@ -960,21 +972,21 @@ TEST_F(WebSocketDeflateStreamTest,
// This is a regression test for crbug.com/343506.
TEST_F(WebSocketDeflateStreamTest, ReadEmptyAsyncFrame) {
- ScopedVector<ReadFramesStub> stub_vector;
- stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING));
- stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING));
+ std::vector<scoped_ptr<ReadFramesStub>> stub_vector;
+ stub_vector.push_back(make_scoped_ptr(new ReadFramesStub(ERR_IO_PENDING)));
+ stub_vector.push_back(make_scoped_ptr(new ReadFramesStub(ERR_IO_PENDING)));
MockCallback mock_callback;
CompletionCallback callback =
base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
- .WillOnce(Invoke(stub_vector[0], &ReadFramesStub::Call));
+ .WillOnce(Invoke(stub_vector[0].get(), &ReadFramesStub::Call));
EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
- .WillOnce(Invoke(stub_vector[1], &ReadFramesStub::Call));
+ .WillOnce(Invoke(stub_vector[1].get(), &ReadFramesStub::Call));
EXPECT_CALL(mock_callback, Call(OK));
}
@@ -996,7 +1008,7 @@ TEST_F(WebSocketDeflateStreamTest, ReadEmptyAsyncFrame) {
}
TEST_F(WebSocketDeflateStreamTest, WriteEmpty) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
CompletionCallback callback;
{
InSequence s;
@@ -1006,7 +1018,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteEmpty) {
}
TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
CompletionCallback callback;
{
InSequence s;
@@ -1021,7 +1033,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
}
TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
CompletionCallback callback;
WriteFramesStub stub(predictor_, OK);
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
@@ -1032,7 +1044,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(1u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1046,7 +1058,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
MockCallback mock_callback, checkpoint;
CompletionCallback callback =
base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
{
InSequence s;
EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
@@ -1061,7 +1073,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
checkpoint.Call(0);
stub.callback().Run(OK);
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(1u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1071,7 +1083,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
}
TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel");
AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal);
AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo");
@@ -1085,7 +1097,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(2u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode);
EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1098,7 +1110,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
}
TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal);
predictor_->AddFramesToBeInput(frames);
WriteFramesStub stub(predictor_, OK);
@@ -1110,7 +1122,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(1u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1119,7 +1131,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
}
TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA");
AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA");
predictor_->AddFramesToBeInput(frames);
@@ -1134,7 +1146,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(2u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
EXPECT_FALSE(frames_passed[0]->header.final);
@@ -1159,12 +1171,12 @@ TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
.WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call));
}
- ScopedVector<WebSocketFrame> total_compressed_frames;
+ std::vector<scoped_ptr<WebSocketFrame>> total_compressed_frames;
deflater.Initialize(kWindowBits);
while (true) {
bool is_final = (total_compressed_frames.size() >= 2);
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
std::string data;
for (size_t i = 0; i < size; ++i)
data += static_cast<char>(lcg.Generate());
@@ -1173,17 +1185,18 @@ TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data);
predictor_->AddFramesToBeInput(frames);
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- total_compressed_frames.insert(total_compressed_frames.end(),
- stub.frames()->begin(),
- stub.frames()->end());
- stub.frames()->weak_clear();
+ total_compressed_frames.insert(
+ total_compressed_frames.end(),
+ std::make_move_iterator(stub.frames()->begin()),
+ std::make_move_iterator(stub.frames()->end()));
+ stub.frames()->clear();
if (is_final)
break;
}
deflater.Finish();
std::string total_deflated;
for (size_t i = 0; i < total_compressed_frames.size(); ++i) {
- WebSocketFrame* frame = total_compressed_frames[i];
+ WebSocketFrame* frame = total_compressed_frames[i].get();
const WebSocketFrameHeader& header = frame->header;
if (i > 0) {
EXPECT_EQ(header.kOpCodeContinuation, header.opcode);
@@ -1203,7 +1216,7 @@ TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
}
TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
predictor_->AddFramesToBeInput(frames);
@@ -1216,7 +1229,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(2u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1231,7 +1244,7 @@ TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
WriteMultipleMessages) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
predictor_->AddFramesToBeInput(frames);
@@ -1244,7 +1257,7 @@ TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(2u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1262,7 +1275,7 @@ TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
// "PossiblyCompressedMessage"s, we test various messages at one test case.
TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
WritePossiblyCompressMessages) {
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He");
AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo");
AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA");
@@ -1280,7 +1293,7 @@ TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(5u, frames_passed.size());
EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
@@ -1322,7 +1335,7 @@ TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits8) {
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(1u, frames_passed.size());
EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
"(?7\xb3\x34\x17\x00", 21),
@@ -1341,7 +1354,7 @@ TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits10) {
.WillOnce(Invoke(&stub, &WriteFramesStub::Call));
}
ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
- const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+ const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
ASSERT_EQ(1u, frames_passed.size());
EXPECT_EQ(
std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
diff --git a/chromium/net/websockets/websocket_deflater.h b/chromium/net/websockets/websocket_deflater.h
index 1b631e2663e..9b34c8574ca 100644
--- a/chromium/net/websockets/websocket_deflater.h
+++ b/chromium/net/websockets/websocket_deflater.h
@@ -5,10 +5,12 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATER_H_
#define NET_WEBSOCKETS_WEBSOCKET_DEFLATER_H_
+#include <stddef.h>
+
#include <deque>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/websockets/websocket_end_to_end_test.cc b/chromium/net/websockets/websocket_end_to_end_test.cc
index 0dfa60cc671..bb1d9519b18 100644
--- a/chromium/net/websockets/websocket_end_to_end_test.cc
+++ b/chromium/net/websockets/websocket_end_to_end_test.cc
@@ -8,12 +8,14 @@
// inefficient. However, it makes these tests a good fit for scenarios which
// require special server configurations.
+#include <stdint.h>
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -23,6 +25,7 @@
#include "net/base/network_delegate.h"
#include "net/base/test_data_directory.h"
#include "net/proxy/proxy_service.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/url_request/url_request_test_util.h"
#include "net/websockets/websocket_channel.h"
@@ -68,12 +71,12 @@ class ConnectTestingEventInterface : public WebSocketEventInterface {
WebSocketMessageType type,
const std::vector<char>& data) override;
- ChannelState OnFlowControl(int64 quota) override;
+ ChannelState OnFlowControl(int64_t quota) override;
ChannelState OnClosingHandshake() override;
ChannelState OnDropChannel(bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) override;
ChannelState OnFailChannel(const std::string& message) override;
@@ -141,7 +144,7 @@ ChannelState ConnectTestingEventInterface::OnDataFrame(
return CHANNEL_ALIVE;
}
-ChannelState ConnectTestingEventInterface::OnFlowControl(int64 quota) {
+ChannelState ConnectTestingEventInterface::OnFlowControl(int64_t quota) {
return CHANNEL_ALIVE;
}
@@ -151,7 +154,7 @@ ChannelState ConnectTestingEventInterface::OnClosingHandshake() {
ChannelState ConnectTestingEventInterface::OnDropChannel(
bool was_clean,
- uint16 code,
+ uint16_t code,
const std::string& reason) {
return CHANNEL_DELETED;
}
@@ -387,22 +390,22 @@ TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(TruncatedResponse)) {
// Regression test for crbug.com/455215 "HSTS not applied to WebSocket"
TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsHttpsToWebSocket)) {
+ EmbeddedTestServer https_server(net::EmbeddedTestServer::Type::TYPE_HTTPS);
+ https_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_server.ServeFilesFromSourceDirectory("net/data/url_request_unittest");
+
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options,
- base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
GetWebSocketTestDataDirectory());
- ASSERT_TRUE(https_server.StartInBackground());
- ASSERT_TRUE(wss_server.StartInBackground());
- ASSERT_TRUE(https_server.BlockUntilStarted());
- ASSERT_TRUE(wss_server.BlockUntilStarted());
+ ASSERT_TRUE(https_server.Start());
+ ASSERT_TRUE(wss_server.Start());
InitialiseContext();
// Set HSTS via https:
TestDelegate delegate;
- GURL https_page = https_server.GetURL("files/hsts-headers.html");
+ GURL https_page = https_server.GetURL("/hsts-headers.html");
scoped_ptr<URLRequest> request(
context_.CreateRequest(https_page, DEFAULT_PRIORITY, &delegate));
request->Start();
@@ -417,17 +420,17 @@ TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsHttpsToWebSocket)) {
}
TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsWebSocketToHttps)) {
+ EmbeddedTestServer https_server(net::EmbeddedTestServer::Type::TYPE_HTTPS);
+ https_server.SetSSLConfig(
+ net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ https_server.ServeFilesFromSourceDirectory("net/data/url_request_unittest");
+
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
- SpawnedTestServer https_server(
- SpawnedTestServer::TYPE_HTTPS, ssl_options,
- base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
SpawnedTestServer wss_server(SpawnedTestServer::TYPE_WSS, ssl_options,
GetWebSocketTestDataDirectory());
- ASSERT_TRUE(https_server.StartInBackground());
- ASSERT_TRUE(wss_server.StartInBackground());
- ASSERT_TRUE(https_server.BlockUntilStarted());
- ASSERT_TRUE(wss_server.BlockUntilStarted());
+ ASSERT_TRUE(https_server.Start());
+ ASSERT_TRUE(wss_server.Start());
InitialiseContext();
// Set HSTS via wss:
GURL wss_url = wss_server.GetURL("set-hsts");
@@ -436,7 +439,7 @@ TEST_F(WebSocketEndToEndTest, DISABLED_ON_ANDROID(HstsWebSocketToHttps)) {
// Verify via http:
TestDelegate delegate;
GURL http_page =
- ReplaceUrlScheme(https_server.GetURL("files/simple.html"), "http");
+ ReplaceUrlScheme(https_server.GetURL("/simple.html"), "http");
scoped_ptr<URLRequest> request(
context_.CreateRequest(http_page, DEFAULT_PRIORITY, &delegate));
request->Start();
diff --git a/chromium/net/websockets/websocket_event_interface.h b/chromium/net/websockets/websocket_event_interface.h
index 08592544a19..25e12a057e9 100644
--- a/chromium/net/websockets/websocket_event_interface.h
+++ b/chromium/net/websockets/websocket_event_interface.h
@@ -5,11 +5,13 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_EVENT_INTERFACE_H_
#define NET_WEBSOCKETS_WEBSOCKET_EVENT_INTERFACE_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/compiler_specific.h" // for WARN_UNUSED_RESULT
+#include "base/macros.h"
#include "net/base/net_export.h"
class GURL;
@@ -52,7 +54,7 @@ class NET_EXPORT WebSocketEventInterface {
// 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 quota) WARN_UNUSED_RESULT = 0;
+ virtual ChannelState OnFlowControl(int64_t quota) WARN_UNUSED_RESULT = 0;
// Called when the remote server has Started the WebSocket Closing
// Handshake. The client should not attempt to send any more messages after
@@ -76,7 +78,7 @@ class NET_EXPORT WebSocketEventInterface {
// 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 code,
+ uint16_t code,
const std::string& reason)
WARN_UNUSED_RESULT = 0;
diff --git a/chromium/net/websockets/websocket_extension_parser.h b/chromium/net/websockets/websocket_extension_parser.h
index 007040de291..365cbf60683 100644
--- a/chromium/net/websockets/websocket_extension_parser.h
+++ b/chromium/net/websockets/websocket_extension_parser.h
@@ -5,10 +5,13 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_EXTENSION_PARSER_H_
#define NET_WEBSOCKETS_WEBSOCKET_EXTENSION_PARSER_H_
+#include <stddef.h>
+
#include <string>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_extension.h"
diff --git a/chromium/net/websockets/websocket_frame.cc b/chromium/net/websockets/websocket_frame.cc
index 3782f282cbf..da596d8b63d 100644
--- a/chromium/net/websockets/websocket_frame.cc
+++ b/chromium/net/websockets/websocket_frame.cc
@@ -4,9 +4,9 @@
#include "net/websockets/websocket_frame.h"
+#include <stddef.h>
#include <algorithm>
-#include "base/basictypes.h"
#include "base/big_endian.h"
#include "base/logging.h"
#include "base/rand_util.h"
@@ -17,15 +17,30 @@ namespace net {
namespace {
-const uint8 kFinalBit = 0x80;
-const uint8 kReserved1Bit = 0x40;
-const uint8 kReserved2Bit = 0x20;
-const uint8 kReserved3Bit = 0x10;
-const uint8 kOpCodeMask = 0xF;
-const uint8 kMaskBit = 0x80;
-const uint64 kMaxPayloadLengthWithoutExtendedLengthField = 125;
-const uint64 kPayloadLengthWithTwoByteExtendedLengthField = 126;
-const uint64 kPayloadLengthWithEightByteExtendedLengthField = 127;
+// GCC (and Clang) can transparently use vector ops. Only try to do this on
+// architectures where we know it works, otherwise gcc will attempt to emulate
+// the vector ops, which is unlikely to be efficient.
+// TODO(ricea): Add ARCH_CPU_ARM_FAMILY when arm_neon=1 becomes the default.
+#if defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY) && !defined(OS_NACL)
+
+using PackedMaskType = uint32_t __attribute__((vector_size(16)));
+
+#else
+
+using PackedMaskType = size_t;
+
+#endif // defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY) &&
+ // !defined(OS_NACL)
+
+const uint8_t kFinalBit = 0x80;
+const uint8_t kReserved1Bit = 0x40;
+const uint8_t kReserved2Bit = 0x20;
+const uint8_t kReserved3Bit = 0x10;
+const uint8_t kOpCodeMask = 0xF;
+const uint8_t kMaskBit = 0x80;
+const uint64_t kMaxPayloadLengthWithoutExtendedLengthField = 125;
+const uint64_t kPayloadLengthWithTwoByteExtendedLengthField = 126;
+const uint64_t kPayloadLengthWithEightByteExtendedLengthField = 127;
inline void MaskWebSocketFramePayloadByBytes(
const WebSocketMaskingKey& masking_key,
@@ -44,7 +59,7 @@ inline void MaskWebSocketFramePayloadByBytes(
scoped_ptr<WebSocketFrameHeader> WebSocketFrameHeader::Clone() const {
scoped_ptr<WebSocketFrameHeader> ret(new WebSocketFrameHeader(opcode));
ret->CopyFrom(*this);
- return ret.Pass();
+ return ret;
}
void WebSocketFrameHeader::CopyFrom(const WebSocketFrameHeader& source) {
@@ -69,9 +84,9 @@ WebSocketFrameChunk::~WebSocketFrameChunk() {}
int GetWebSocketFrameHeaderSize(const WebSocketFrameHeader& header) {
int extended_length_size = 0;
if (header.payload_length > kMaxPayloadLengthWithoutExtendedLengthField &&
- header.payload_length <= kuint16max) {
+ header.payload_length <= UINT16_MAX) {
extended_length_size = 2;
- } else if (header.payload_length > kuint16max) {
+ } else if (header.payload_length > UINT16_MAX) {
extended_length_size = 8;
}
@@ -85,9 +100,9 @@ int WriteWebSocketFrameHeader(const WebSocketFrameHeader& header,
int buffer_size) {
DCHECK((header.opcode & kOpCodeMask) == header.opcode)
<< "header.opcode must fit to kOpCodeMask.";
- DCHECK(header.payload_length <= static_cast<uint64>(kint64max))
+ DCHECK(header.payload_length <= static_cast<uint64_t>(INT64_MAX))
<< "WebSocket specification doesn't allow a frame longer than "
- << "kint64max (0x7FFFFFFFFFFFFFFF) bytes.";
+ << "INT64_MAX (0x7FFFFFFFFFFFFFFF) bytes.";
DCHECK_GE(buffer_size, 0);
// WebSocket frame format is as follows:
@@ -106,7 +121,7 @@ int WriteWebSocketFrameHeader(const WebSocketFrameHeader& header,
int buffer_index = 0;
- uint8 first_byte = 0u;
+ uint8_t first_byte = 0u;
first_byte |= header.final ? kFinalBit : 0u;
first_byte |= header.reserved1 ? kReserved1Bit : 0u;
first_byte |= header.reserved2 ? kReserved2Bit : 0u;
@@ -115,11 +130,11 @@ int WriteWebSocketFrameHeader(const WebSocketFrameHeader& header,
buffer[buffer_index++] = first_byte;
int extended_length_size = 0;
- uint8 second_byte = 0u;
+ uint8_t second_byte = 0u;
second_byte |= header.masked ? kMaskBit : 0u;
if (header.payload_length <= kMaxPayloadLengthWithoutExtendedLengthField) {
second_byte |= header.payload_length;
- } else if (header.payload_length <= kuint16max) {
+ } else if (header.payload_length <= UINT16_MAX) {
second_byte |= kPayloadLengthWithTwoByteExtendedLengthField;
extended_length_size = 2;
} else {
@@ -130,7 +145,7 @@ int WriteWebSocketFrameHeader(const WebSocketFrameHeader& header,
// Writes "extended payload length" field.
if (extended_length_size == 2) {
- uint16 payload_length_16 = static_cast<uint16>(header.payload_length);
+ uint16_t payload_length_16 = static_cast<uint16_t>(header.payload_length);
base::WriteBigEndian(buffer + buffer_index, payload_length_16);
buffer_index += sizeof(payload_length_16);
} else if (extended_length_size == 8) {
@@ -163,7 +178,7 @@ WebSocketMaskingKey GenerateWebSocketMaskingKey() {
}
void MaskWebSocketFramePayload(const WebSocketMaskingKey& masking_key,
- uint64 frame_offset,
+ uint64_t frame_offset,
char* const data,
int data_size) {
static const size_t kMaskingKeyLength =
@@ -171,16 +186,14 @@ void MaskWebSocketFramePayload(const WebSocketMaskingKey& masking_key,
DCHECK_GE(data_size, 0);
- // Most of the masking is done one word at a time, except for the beginning
- // and the end of the buffer which may be unaligned. We use size_t to get the
- // word size for this architecture. We require it be a multiple of
- // kMaskingKeyLength in size.
- typedef size_t PackedMaskType;
- PackedMaskType packed_mask_key = 0;
+ // Most of the masking is done in chunks of sizeof(PackedMaskType), except for
+ // the beginning and the end of the buffer which may be unaligned.
+ // PackedMaskType must be a multiple of kMaskingKeyLength in size.
+ PackedMaskType packed_mask_key;
static const size_t kPackedMaskKeySize = sizeof(packed_mask_key);
static_assert((kPackedMaskKeySize >= kMaskingKeyLength &&
kPackedMaskKeySize % kMaskingKeyLength == 0),
- "word size is not a multiple of mask length");
+ "PackedMaskType size is not a multiple of mask length");
char* const end = data + data_size;
// If the buffer is too small for the vectorised version to be useful, revert
// to the byte-at-a-time implementation early.
diff --git a/chromium/net/websockets/websocket_frame.h b/chromium/net/websockets/websocket_frame.h
index c9d8b976926..7e85a3c9230 100644
--- a/chromium/net/websockets/websocket_frame.h
+++ b/chromium/net/websockets/websocket_frame.h
@@ -5,9 +5,11 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_FRAME_H_
#define NET_WEBSOCKETS_WEBSOCKET_FRAME_H_
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
@@ -83,7 +85,7 @@ struct NET_EXPORT WebSocketFrameHeader {
bool reserved3;
OpCode opcode;
bool masked;
- uint64 payload_length;
+ uint64_t payload_length;
private:
DISALLOW_COPY_AND_ASSIGN(WebSocketFrameHeader);
@@ -186,7 +188,7 @@ NET_EXPORT WebSocketMaskingKey GenerateWebSocketMaskingKey();
// used for unmasking a WebSocket frame.
NET_EXPORT void MaskWebSocketFramePayload(
const WebSocketMaskingKey& masking_key,
- uint64 frame_offset,
+ uint64_t frame_offset,
char* data,
int data_size);
diff --git a/chromium/net/websockets/websocket_frame_parser.cc b/chromium/net/websockets/websocket_frame_parser.cc
index 40d7e8a6e10..7c2a075eada 100644
--- a/chromium/net/websockets/websocket_frame_parser.cc
+++ b/chromium/net/websockets/websocket_frame_parser.cc
@@ -6,30 +6,30 @@
#include <algorithm>
#include <limits>
+#include <utility>
+#include <vector>
-#include "base/basictypes.h"
#include "base/big_endian.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/io_buffer.h"
#include "net/websockets/websocket_frame.h"
namespace {
-const uint8 kFinalBit = 0x80;
-const uint8 kReserved1Bit = 0x40;
-const uint8 kReserved2Bit = 0x20;
-const uint8 kReserved3Bit = 0x10;
-const uint8 kOpCodeMask = 0xF;
-const uint8 kMaskBit = 0x80;
-const uint8 kPayloadLengthMask = 0x7F;
-const uint64 kMaxPayloadLengthWithoutExtendedLengthField = 125;
-const uint64 kPayloadLengthWithTwoByteExtendedLengthField = 126;
-const uint64 kPayloadLengthWithEightByteExtendedLengthField = 127;
+const uint8_t kFinalBit = 0x80;
+const uint8_t kReserved1Bit = 0x40;
+const uint8_t kReserved2Bit = 0x20;
+const uint8_t kReserved3Bit = 0x10;
+const uint8_t kOpCodeMask = 0xF;
+const uint8_t kMaskBit = 0x80;
+const uint8_t kPayloadLengthMask = 0x7F;
+const uint64_t kMaxPayloadLengthWithoutExtendedLengthField = 125;
+const uint64_t kPayloadLengthWithTwoByteExtendedLengthField = 126;
+const uint64_t kPayloadLengthWithEightByteExtendedLengthField = 127;
-} // Unnamed namespace.
+} // namespace.
namespace net {
@@ -47,7 +47,7 @@ WebSocketFrameParser::~WebSocketFrameParser() {}
bool WebSocketFrameParser::Decode(
const char* data,
size_t length,
- ScopedVector<WebSocketFrameChunk>* frame_chunks) {
+ std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks) {
if (websocket_error_ != kWebSocketNormalClosure)
return false;
if (!length)
@@ -72,7 +72,7 @@ bool WebSocketFrameParser::Decode(
scoped_ptr<WebSocketFrameChunk> frame_chunk =
DecodeFramePayload(first_chunk);
DCHECK(frame_chunk.get());
- frame_chunks->push_back(frame_chunk.Pass());
+ frame_chunks->push_back(std::move(frame_chunk));
if (current_frame_header_.get()) {
DCHECK(current_read_pos_ == buffer_.size());
@@ -109,8 +109,8 @@ void WebSocketFrameParser::DecodeFrameHeader() {
if (end - current < 2)
return;
- uint8 first_byte = *current++;
- uint8 second_byte = *current++;
+ uint8_t first_byte = *current++;
+ uint8_t second_byte = *current++;
bool final = (first_byte & kFinalBit) != 0;
bool reserved1 = (first_byte & kReserved1Bit) != 0;
@@ -119,11 +119,11 @@ void WebSocketFrameParser::DecodeFrameHeader() {
OpCode opcode = first_byte & kOpCodeMask;
bool masked = (second_byte & kMaskBit) != 0;
- uint64 payload_length = second_byte & kPayloadLengthMask;
+ uint64_t payload_length = second_byte & kPayloadLengthMask;
if (payload_length == kPayloadLengthWithTwoByteExtendedLengthField) {
if (end - current < 2)
return;
- uint16 payload_length_16;
+ uint16_t payload_length_16;
base::ReadBigEndian(current, &payload_length_16);
current += 2;
payload_length = payload_length_16;
@@ -134,10 +134,10 @@ void WebSocketFrameParser::DecodeFrameHeader() {
return;
base::ReadBigEndian(current, &payload_length);
current += 8;
- if (payload_length <= kuint16max ||
- payload_length > static_cast<uint64>(kint64max)) {
+ if (payload_length <= UINT16_MAX ||
+ payload_length > static_cast<uint64_t>(INT64_MAX)) {
websocket_error_ = kWebSocketErrorProtocolError;
- } else if (payload_length > static_cast<uint64>(kint32max)) {
+ } else if (payload_length > static_cast<uint64_t>(INT32_MAX)) {
websocket_error_ = kWebSocketErrorMessageTooBig;
}
}
@@ -173,9 +173,9 @@ scoped_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload(
bool first_chunk) {
// The cast here is safe because |payload_length| is already checked to be
// less than std::numeric_limits<int>::max() when the header is parsed.
- int next_size = static_cast<int>(std::min(
- static_cast<uint64>(buffer_.size() - current_read_pos_),
- current_frame_header_->payload_length - frame_offset_));
+ int next_size = static_cast<int>(
+ std::min(static_cast<uint64_t>(buffer_.size() - current_read_pos_),
+ current_frame_header_->payload_length - frame_offset_));
scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk);
if (first_chunk) {
@@ -204,7 +204,7 @@ scoped_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload(
frame_offset_ = 0;
}
- return frame_chunk.Pass();
+ return frame_chunk;
}
} // namespace net
diff --git a/chromium/net/websockets/websocket_frame_parser.h b/chromium/net/websockets/websocket_frame_parser.h
index 52e6f85a6bb..250541b816a 100644
--- a/chromium/net/websockets/websocket_frame_parser.h
+++ b/chromium/net/websockets/websocket_frame_parser.h
@@ -5,12 +5,14 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_FRAME_PARSER_H_
#define NET_WEBSOCKETS_WEBSOCKET_FRAME_PARSER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_errors.h"
#include "net/websockets/websocket_frame.h"
@@ -38,7 +40,7 @@ class NET_EXPORT WebSocketFrameParser {
// websocket_frame.h for more details.
bool Decode(const char* data,
size_t length,
- ScopedVector<WebSocketFrameChunk>* frame_chunks);
+ std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks);
// Returns kWebSocketNormalClosure if the parser has not failed to decode
// WebSocket frames. Otherwise returns WebSocketError which is defined in
@@ -75,7 +77,7 @@ class NET_EXPORT WebSocketFrameParser {
WebSocketMaskingKey masking_key_;
// Amount of payload data read so far for the current frame.
- uint64 frame_offset_;
+ uint64_t frame_offset_;
WebSocketError websocket_error_;
diff --git a/chromium/net/websockets/websocket_frame_parser_test.cc b/chromium/net/websockets/websocket_frame_parser_test.cc
index 868d6510126..095578525c0 100644
--- a/chromium/net/websockets/websocket_frame_parser_test.cc
+++ b/chromium/net/websockets/websocket_frame_parser_test.cc
@@ -8,10 +8,7 @@
#include <algorithm>
#include <vector>
-#include "base/basictypes.h"
-#include "base/memory/scoped_vector.h"
#include "net/base/io_buffer.h"
-#include "net/websockets/websocket_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -19,18 +16,18 @@ namespace net {
namespace {
const char kHello[] = "Hello, world!";
-const uint64 kHelloLength = arraysize(kHello) - 1;
+const uint64_t kHelloLength = arraysize(kHello) - 1;
const char kHelloFrame[] = "\x81\x0DHello, world!";
-const uint64 kHelloFrameLength = arraysize(kHelloFrame) - 1;
+const uint64_t kHelloFrameLength = arraysize(kHelloFrame) - 1;
const char kMaskedHelloFrame[] =
"\x81\x8D\xDE\xAD\xBE\xEF"
"\x96\xC8\xD2\x83\xB1\x81\x9E\x98\xB1\xDF\xD2\x8B\xFF";
-const uint64 kMaskedHelloFrameLength = arraysize(kMaskedHelloFrame) - 1;
+const uint64_t kMaskedHelloFrameLength = arraysize(kMaskedHelloFrame) - 1;
struct FrameHeaderTestCase {
const char* frame_header;
size_t frame_header_length;
- uint64 frame_length;
+ uint64_t frame_length;
WebSocketError error_code;
};
@@ -53,11 +50,11 @@ const int kNumFrameHeaderTests = arraysize(kFrameHeaderTests);
TEST(WebSocketFrameParserTest, DecodeNormalFrame) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
EXPECT_TRUE(parser.Decode(kHelloFrame, kHelloFrameLength, &frames));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
ASSERT_EQ(1u, frames.size());
- WebSocketFrameChunk* frame = frames[0];
+ WebSocketFrameChunk* frame = frames[0].get();
ASSERT_TRUE(frame != NULL);
const WebSocketFrameHeader* header = frame->header.get();
EXPECT_TRUE(header != NULL);
@@ -79,12 +76,12 @@ TEST(WebSocketFrameParserTest, DecodeNormalFrame) {
TEST(WebSocketFrameParserTest, DecodeMaskedFrame) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
EXPECT_TRUE(
parser.Decode(kMaskedHelloFrame, kMaskedHelloFrameLength, &frames));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
ASSERT_EQ(1u, frames.size());
- WebSocketFrameChunk* frame = frames[0];
+ WebSocketFrameChunk* frame = frames[0].get();
ASSERT_TRUE(frame != NULL);
const WebSocketFrameHeader* header = frame->header.get();
EXPECT_TRUE(header != NULL);
@@ -138,19 +135,19 @@ TEST(WebSocketFrameParserTest, DecodeManyFrames) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
EXPECT_TRUE(parser.Decode(&input.front(), input.size(), &frames));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
ASSERT_EQ(static_cast<size_t>(kNumInputs), frames.size());
for (int i = 0; i < kNumInputs; ++i) {
- WebSocketFrameChunk* frame = frames[i];
+ WebSocketFrameChunk* frame = frames[i].get();
EXPECT_TRUE(frame != NULL);
if (!frame)
continue;
EXPECT_TRUE(frame->final_chunk);
ASSERT_EQ(kInputs[i].expected_payload_length,
- static_cast<uint64>(frame->data->size()));
+ static_cast<uint64_t>(frame->data->size()));
EXPECT_TRUE(std::equal(
kInputs[i].expected_payload,
kInputs[i].expected_payload + kInputs[i].expected_payload_length,
@@ -184,13 +181,13 @@ TEST(WebSocketFrameParserTest, DecodePartialFrame) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames1;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames1;
EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
EXPECT_EQ(1u, frames1.size());
if (frames1.size() != 1u)
continue;
- WebSocketFrameChunk* frame1 = frames1[0];
+ WebSocketFrameChunk* frame1 = frames1[0].get();
EXPECT_TRUE(frame1 != NULL);
if (!frame1)
continue;
@@ -214,13 +211,13 @@ TEST(WebSocketFrameParserTest, DecodePartialFrame) {
EXPECT_FALSE(header1->masked);
EXPECT_EQ(kHelloLength, header1->payload_length);
- ScopedVector<WebSocketFrameChunk> frames2;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames2;
EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
EXPECT_EQ(1u, frames2.size());
if (frames2.size() != 1u)
continue;
- WebSocketFrameChunk* frame2 = frames2[0];
+ WebSocketFrameChunk* frame2 = frames2[0].get();
EXPECT_TRUE(frame2 != NULL);
if (!frame2)
continue;
@@ -228,7 +225,7 @@ TEST(WebSocketFrameParserTest, DecodePartialFrame) {
if (expected2.size() == 0) {
EXPECT_EQ(NULL, frame2->data.get());
} else {
- ASSERT_EQ(expected2.size(), static_cast<uint64>(frame2->data->size()));
+ ASSERT_EQ(expected2.size(), static_cast<uint64_t>(frame2->data->size()));
EXPECT_TRUE(
std::equal(expected2.begin(), expected2.end(), frame2->data->data()));
}
@@ -251,13 +248,13 @@ TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames1;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames1;
EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
EXPECT_EQ(1u, frames1.size());
if (frames1.size() != 1u)
continue;
- WebSocketFrameChunk* frame1 = frames1[0];
+ WebSocketFrameChunk* frame1 = frames1[0].get();
EXPECT_TRUE(frame1 != NULL);
if (!frame1)
continue;
@@ -265,7 +262,7 @@ TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) {
if (expected1.size() == 0) {
EXPECT_EQ(NULL, frame1->data.get());
} else {
- ASSERT_EQ(expected1.size(), static_cast<uint64>(frame1->data->size()));
+ ASSERT_EQ(expected1.size(), static_cast<uint64_t>(frame1->data->size()));
EXPECT_TRUE(
std::equal(expected1.begin(), expected1.end(), frame1->data->data()));
}
@@ -281,13 +278,13 @@ TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) {
EXPECT_TRUE(header1->masked);
EXPECT_EQ(kHelloLength, header1->payload_length);
- ScopedVector<WebSocketFrameChunk> frames2;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames2;
EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
EXPECT_EQ(1u, frames2.size());
if (frames2.size() != 1u)
continue;
- WebSocketFrameChunk* frame2 = frames2[0];
+ WebSocketFrameChunk* frame2 = frames2[0].get();
EXPECT_TRUE(frame2 != NULL);
if (!frame2)
continue;
@@ -295,7 +292,7 @@ TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) {
if (expected2.size() == 0) {
EXPECT_EQ(NULL, frame2->data.get());
} else {
- ASSERT_EQ(expected2.size(), static_cast<uint64>(frame2->data->size()));
+ ASSERT_EQ(expected2.size(), static_cast<uint64_t>(frame2->data->size()));
EXPECT_TRUE(
std::equal(expected2.begin(), expected2.end(), frame2->data->data()));
}
@@ -308,17 +305,17 @@ TEST(WebSocketFrameParserTest, DecodeFramesOfVariousLengths) {
for (int i = 0; i < kNumFrameHeaderTests; ++i) {
const char* frame_header = kFrameHeaderTests[i].frame_header;
size_t frame_header_length = kFrameHeaderTests[i].frame_header_length;
- uint64 frame_length = kFrameHeaderTests[i].frame_length;
+ uint64_t frame_length = kFrameHeaderTests[i].frame_length;
std::vector<char> input(frame_header, frame_header + frame_header_length);
// Limit the payload size not to flood the console on failure.
- static const uint64 kMaxPayloadSize = 200;
- uint64 input_payload_size = std::min(frame_length, kMaxPayloadSize);
+ static const uint64_t kMaxPayloadSize = 200;
+ uint64_t input_payload_size = std::min(frame_length, kMaxPayloadSize);
input.insert(input.end(), input_payload_size, 'a');
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
EXPECT_EQ(kFrameHeaderTests[i].error_code == kWebSocketNormalClosure,
parser.Decode(&input.front(), input.size(), &frames));
EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error());
@@ -329,7 +326,7 @@ TEST(WebSocketFrameParserTest, DecodeFramesOfVariousLengths) {
}
if (frames.size() != 1u)
continue;
- WebSocketFrameChunk* frame = frames[0];
+ WebSocketFrameChunk* frame = frames[0].get();
EXPECT_TRUE(frame != NULL);
if (!frame)
continue;
@@ -343,7 +340,7 @@ TEST(WebSocketFrameParserTest, DecodeFramesOfVariousLengths) {
EXPECT_EQ(NULL, frame->data.get());
} else {
ASSERT_EQ(expected_payload.size(),
- static_cast<uint64>(frame->data->size()));
+ static_cast<uint64_t>(frame->data->size()));
EXPECT_TRUE(std::equal(expected_payload.begin(),
expected_payload.end(),
frame->data->data()));
@@ -366,11 +363,11 @@ TEST(WebSocketFrameParserTest, DecodePartialHeader) {
for (int i = 0; i < kNumFrameHeaderTests; ++i) {
const char* frame_header = kFrameHeaderTests[i].frame_header;
size_t frame_header_length = kFrameHeaderTests[i].frame_header_length;
- uint64 frame_length = kFrameHeaderTests[i].frame_length;
+ uint64_t frame_length = kFrameHeaderTests[i].frame_length;
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
// Feed each byte to the parser to see if the parser behaves correctly
// when it receives partial frame header.
size_t last_byte_offset = frame_header_length - 1;
@@ -393,7 +390,7 @@ TEST(WebSocketFrameParserTest, DecodePartialHeader) {
}
if (frames.size() != 1u)
continue;
- WebSocketFrameChunk* frame = frames[0];
+ WebSocketFrameChunk* frame = frames[0].get();
EXPECT_TRUE(frame != NULL);
if (!frame)
continue;
@@ -440,7 +437,7 @@ TEST(WebSocketFrameParserTest, InvalidLengthEncoding) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
EXPECT_FALSE(parser.Decode(frame_header, frame_header_length, &frames));
EXPECT_EQ(kWebSocketErrorProtocolError, parser.websocket_error());
@@ -489,13 +486,13 @@ TEST(WebSocketFrameParserTest, FrameTypes) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
EXPECT_EQ(1u, frames.size());
if (frames.size() != 1u)
continue;
- WebSocketFrameChunk* frame = frames[0];
+ WebSocketFrameChunk* frame = frames[0].get();
EXPECT_TRUE(frame != NULL);
if (!frame)
continue;
@@ -545,13 +542,13 @@ TEST(WebSocketFrameParserTest, FinalBitAndReservedBits) {
WebSocketFrameParser parser;
- ScopedVector<WebSocketFrameChunk> frames;
+ std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
EXPECT_EQ(1u, frames.size());
if (frames.size() != 1u)
continue;
- WebSocketFrameChunk* frame = frames[0];
+ WebSocketFrameChunk* frame = frames[0].get();
EXPECT_TRUE(frame != NULL);
if (!frame)
continue;
diff --git a/chromium/net/websockets/websocket_frame_perftest.cc b/chromium/net/websockets/websocket_frame_perftest.cc
index 98ea624ac14..bd1de1c61d3 100644
--- a/chromium/net/websockets/websocket_frame_perftest.cc
+++ b/chromium/net/websockets/websocket_frame_perftest.cc
@@ -53,6 +53,14 @@ TEST_F(WebSocketFrameTestMaskBenchmark, BenchmarkMaskLongPayload) {
Benchmark("Frame_mask_long_payload", &payload.front(), payload.size());
}
+// A 31-byte payload is guaranteed to do 7 byte mask operations and 3 vector
+// mask operations with an 8-byte vector. With a 16-byte vector it will fall
+// back to the byte-only code path and do 31 byte mask operations.
+TEST_F(WebSocketFrameTestMaskBenchmark, Benchmark31BytePayload) {
+ std::vector<char> payload(31, 'a');
+ Benchmark("Frame_mask_31_payload", &payload.front(), payload.size());
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/websockets/websocket_frame_test.cc b/chromium/net/websockets/websocket_frame_test.cc
index ac35d90342c..04c10d22b55 100644
--- a/chromium/net/websockets/websocket_frame_test.cc
+++ b/chromium/net/websockets/websocket_frame_test.cc
@@ -8,7 +8,7 @@
#include <algorithm>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/aligned_memory.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,7 +21,7 @@ TEST(WebSocketFrameHeaderTest, FrameLengths) {
struct TestCase {
const char* frame_header;
size_t frame_header_length;
- uint64 frame_length;
+ uint64_t frame_length;
};
static const TestCase kTests[] = {
{ "\x81\x00", 2, UINT64_C(0) },
@@ -59,7 +59,7 @@ TEST(WebSocketFrameHeaderTest, FrameLengthsWithMasking) {
struct TestCase {
const char* frame_header;
size_t frame_header_length;
- uint64 frame_length;
+ uint64_t frame_length;
};
static const TestCase kTests[] = {
{ "\x81\x80\xDE\xAD\xBE\xEF", 6, UINT64_C(0) },
@@ -179,7 +179,7 @@ TEST(WebSocketFrameHeaderTest, FinalBitAndReservedBits) {
TEST(WebSocketFrameHeaderTest, InsufficientBufferSize) {
struct TestCase {
- uint64 payload_length;
+ uint64_t payload_length;
bool masked;
size_t expected_header_size;
};
@@ -218,7 +218,7 @@ TEST(WebSocketFrameHeaderTest, InsufficientBufferSize) {
TEST(WebSocketFrameTest, MaskPayload) {
struct TestCase {
const char* masking_key;
- uint64 frame_offset;
+ uint64_t frame_offset;
const char* input;
const char* output;
size_t data_length;
diff --git a/chromium/net/websockets/websocket_handshake_constants.h b/chromium/net/websockets/websocket_handshake_constants.h
index f52f5136952..6b17be0ac5d 100644
--- a/chromium/net/websockets/websocket_handshake_constants.h
+++ b/chromium/net/websockets/websocket_handshake_constants.h
@@ -12,7 +12,8 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_CONSTANTS_H_
#define NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_CONSTANTS_H_
-#include "base/basictypes.h"
+#include <stddef.h>
+
#include "net/base/net_export.h"
// This file plases constants inside the ::net::websockets namespace to avoid
diff --git a/chromium/net/websockets/websocket_handshake_request_info.h b/chromium/net/websockets/websocket_handshake_request_info.h
index e5ef3369b2a..871d130f506 100644
--- a/chromium/net/websockets/websocket_handshake_request_info.h
+++ b/chromium/net/websockets/websocket_handshake_request_info.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/http/http_request_headers.h"
diff --git a/chromium/net/websockets/websocket_handshake_response_info.h b/chromium/net/websockets/websocket_handshake_response_info.h
index 66aff4417b7..42a2662d021 100644
--- a/chromium/net/websockets/websocket_handshake_response_info.h
+++ b/chromium/net/websockets/websocket_handshake_response_info.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/websockets/websocket_handshake_stream_base.h b/chromium/net/websockets/websocket_handshake_stream_base.h
index a858febe0bc..dda9f3d10b2 100644
--- a/chromium/net/websockets/websocket_handshake_stream_base.h
+++ b/chromium/net/websockets/websocket_handshake_stream_base.h
@@ -11,7 +11,7 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
diff --git a/chromium/net/websockets/websocket_handshake_stream_create_helper.cc b/chromium/net/websockets/websocket_handshake_stream_create_helper.cc
index 2bd59a12532..e8985a1babc 100644
--- a/chromium/net/websockets/websocket_handshake_stream_create_helper.cc
+++ b/chromium/net/websockets/websocket_handshake_stream_create_helper.cc
@@ -4,6 +4,8 @@
#include "net/websockets/websocket_handshake_stream_create_helper.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -35,13 +37,9 @@ WebSocketHandshakeStreamCreateHelper::CreateBasicStream(
// method.
std::vector<std::string> extensions(
1, "permessage-deflate; client_max_window_bits");
- WebSocketBasicHandshakeStream* stream =
- new WebSocketBasicHandshakeStream(connection.Pass(),
- connect_delegate_,
- using_proxy,
- requested_subprotocols_,
- extensions,
- failure_message_);
+ WebSocketBasicHandshakeStream* stream = new WebSocketBasicHandshakeStream(
+ std::move(connection), connect_delegate_, using_proxy,
+ requested_subprotocols_, extensions, failure_message_);
OnStreamCreated(stream);
stream_ = stream;
return stream;
diff --git a/chromium/net/websockets/websocket_handshake_stream_create_helper.h b/chromium/net/websockets/websocket_handshake_stream_create_helper.h
index 83bb1ac7561..2494f1406cf 100644
--- a/chromium/net/websockets/websocket_handshake_stream_create_helper.h
+++ b/chromium/net/websockets/websocket_handshake_stream_create_helper.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_handshake_stream_base.h"
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 17a388a43e1..ffdbfe2ebfa 100644
--- a/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
+++ b/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -5,8 +5,10 @@
#include "net/websockets/websocket_handshake_stream_create_helper.h"
#include <string>
+#include <utility>
#include <vector>
+#include "base/macros.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
@@ -46,7 +48,7 @@ class MockClientSocketHandleFactory {
CompletionCallback(),
&pool_,
BoundNetLog());
- return socket_handle.Pass();
+ return socket_handle;
}
private:
@@ -92,7 +94,7 @@ class WebSocketHandshakeStreamCreateHelperTest : public ::testing::Test {
WebSocketStandardResponse(extra_response_headers));
scoped_ptr<WebSocketHandshakeStreamBase> handshake(
- create_helper.CreateBasicStream(socket_handle.Pass(), false));
+ create_helper.CreateBasicStream(std::move(socket_handle), false));
// If in future the implementation type returned by CreateBasicStream()
// changes, this static_cast will be wrong. However, in that case the test
diff --git a/chromium/net/websockets/websocket_inflater.h b/chromium/net/websockets/websocket_inflater.h
index fdfa7624fef..e695fa1da30 100644
--- a/chromium/net/websockets/websocket_inflater.h
+++ b/chromium/net/websockets/websocket_inflater.h
@@ -5,11 +5,13 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_
#define NET_WEBSOCKETS_WEBSOCKET_INFLATER_H_
+#include <stddef.h>
+
#include <deque>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/websockets/websocket_stream.cc b/chromium/net/websockets/websocket_stream.cc
index 1a72a93676d..6e6ae09d9b8 100644
--- a/chromium/net/websockets/websocket_stream.cc
+++ b/chromium/net/websockets/websocket_stream.cc
@@ -4,6 +4,8 @@
#include "net/websockets/websocket_stream.h"
+#include <utility>
+
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
@@ -88,7 +90,7 @@ class StreamRequestImpl : public WebSocketStreamRequest {
: delegate_(new Delegate(this)),
url_request_(
context->CreateRequest(url, DEFAULT_PRIORITY, delegate_.get())),
- connect_delegate_(connect_delegate.Pass()),
+ connect_delegate_(std::move(connect_delegate)),
create_helper_(create_helper.release()) {
create_helper_->set_failure_message(&failure_message_);
HttpRequestHeaders headers;
@@ -114,7 +116,7 @@ class StreamRequestImpl : public WebSocketStreamRequest {
DCHECK(timer);
base::TimeDelta timeout(base::TimeDelta::FromSeconds(
kHandshakeTimeoutIntervalInSeconds));
- timer_ = timer.Pass();
+ timer_ = std::move(timer);
timer_->Start(FROM_HERE, timeout,
base::Bind(&StreamRequestImpl::OnTimeout,
base::Unretained(this)));
@@ -336,14 +338,11 @@ scoped_ptr<WebSocketStreamRequest> WebSocketStream::CreateAndConnectStream(
scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper(
new WebSocketHandshakeStreamCreateHelper(connect_delegate.get(),
requested_subprotocols));
- scoped_ptr<StreamRequestImpl> request(
- new StreamRequestImpl(socket_url,
- url_request_context,
- origin,
- connect_delegate.Pass(),
- create_helper.Pass()));
+ scoped_ptr<StreamRequestImpl> request(new StreamRequestImpl(
+ socket_url, url_request_context, origin, std::move(connect_delegate),
+ std::move(create_helper)));
request->Start(scoped_ptr<base::Timer>(new base::Timer(false, false)));
- return request.Pass();
+ return std::move(request);
}
// This is declared in websocket_test_util.h.
@@ -355,14 +354,11 @@ scoped_ptr<WebSocketStreamRequest> CreateAndConnectStreamForTesting(
const BoundNetLog& net_log,
scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
scoped_ptr<base::Timer> timer) {
- scoped_ptr<StreamRequestImpl> request(
- new StreamRequestImpl(socket_url,
- url_request_context,
- origin,
- connect_delegate.Pass(),
- create_helper.Pass()));
- request->Start(timer.Pass());
- return request.Pass();
+ scoped_ptr<StreamRequestImpl> request(new StreamRequestImpl(
+ socket_url, url_request_context, origin, std::move(connect_delegate),
+ std::move(create_helper)));
+ request->Start(std::move(timer));
+ return std::move(request);
}
void WebSocketDispatchOnFinishOpeningHandshake(
diff --git a/chromium/net/websockets/websocket_stream.h b/chromium/net/websockets/websocket_stream.h
index 713205a104d..8a2b371c3f7 100644
--- a/chromium/net/websockets/websocket_stream.h
+++ b/chromium/net/websockets/websocket_stream.h
@@ -8,11 +8,10 @@
#include <string>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/time/time.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -159,7 +158,7 @@ class NET_EXPORT_PRIVATE WebSocketStream {
// Extensions which use reserved header bits should clear them when they are
// set correctly. If the reserved header bits are set incorrectly, it is okay
// to leave it to the caller to report the error.
- virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+ virtual int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) = 0;
// Writes WebSocket frame data.
@@ -176,7 +175,7 @@ class NET_EXPORT_PRIVATE WebSocketStream {
// object. Implementations of WriteFrames() should be robust against
// this. This generally means returning to the event loop immediately after
// calling the callback.
- virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+ virtual int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
const CompletionCallback& callback) = 0;
// Closes the stream. All pending I/O operations (if any) are cancelled
diff --git a/chromium/net/websockets/websocket_stream_cookie_test.cc b/chromium/net/websockets/websocket_stream_cookie_test.cc
index 0e65ba783bf..c45fac4956d 100644
--- a/chromium/net/websockets/websocket_stream_cookie_test.cc
+++ b/chromium/net/websockets/websocket_stream_cookie_test.cc
@@ -118,7 +118,7 @@ class WebSocketStreamServerSetCookieTest
TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
// For wss tests.
- ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK));
+ ssl_data_.push_back(make_scoped_ptr(new SSLSocketDataProvider(ASYNC, OK)));
CookieStore* store =
url_request_context_host_.GetURLRequestContext()->cookie_store();
@@ -151,7 +151,7 @@ TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
TEST_P(WebSocketStreamServerSetCookieTest, ServerSetCookie) {
// For wss tests.
- ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK));
+ ssl_data_.push_back(make_scoped_ptr(new 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 387ce8a9531..4211e1a485c 100644
--- a/chromium/net/websockets/websocket_stream_create_test_base.cc
+++ b/chromium/net/websockets/websocket_stream_create_test_base.cc
@@ -4,7 +4,10 @@
#include "net/websockets/websocket_stream_create_test_base.h"
+#include <utility>
+
#include "base/callback.h"
+#include "base/macros.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/websockets/websocket_basic_handshake_stream.h"
@@ -61,14 +64,14 @@ class WebSocketStreamCreateTestBase::TestConnectDelegate
scoped_ptr<WebSocketHandshakeRequestInfo> request) override {
// Can be called multiple times (in the case of HTTP auth). Last call
// wins.
- owner_->request_info_ = request.Pass();
+ owner_->request_info_ = std::move(request);
}
void OnFinishOpeningHandshake(
scoped_ptr<WebSocketHandshakeResponseInfo> response) override {
if (owner_->response_info_)
ADD_FAILURE();
- owner_->response_info_ = response.Pass();
+ owner_->response_info_ = std::move(response);
}
void OnSSLCertificateError(
@@ -76,7 +79,7 @@ class WebSocketStreamCreateTestBase::TestConnectDelegate
ssl_error_callbacks,
const SSLInfo& ssl_info,
bool fatal) override {
- owner_->ssl_error_callbacks_ = ssl_error_callbacks.Pass();
+ owner_->ssl_error_callbacks_ = std::move(ssl_error_callbacks);
owner_->ssl_info_ = ssl_info;
owner_->ssl_fatal_ = fatal;
}
@@ -100,10 +103,9 @@ void WebSocketStreamCreateTestBase::CreateAndConnectStream(
const url::Origin& origin,
scoped_ptr<base::Timer> timer) {
for (size_t i = 0; i < ssl_data_.size(); ++i) {
- scoped_ptr<SSLSocketDataProvider> ssl_data(ssl_data_[i]);
- url_request_context_host_.AddSSLSocketDataProvider(ssl_data.Pass());
+ url_request_context_host_.AddSSLSocketDataProvider(std::move(ssl_data_[i]));
}
- ssl_data_.weak_clear();
+ ssl_data_.clear();
scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate(
new TestConnectDelegate(this, connect_run_loop_.QuitClosure()));
WebSocketStream::ConnectDelegate* delegate = connect_delegate.get();
@@ -111,10 +113,10 @@ void WebSocketStreamCreateTestBase::CreateAndConnectStream(
new DeterministicKeyWebSocketHandshakeStreamCreateHelper(delegate,
sub_protocols));
stream_request_ = CreateAndConnectStreamForTesting(
- GURL(socket_url), create_helper.Pass(), origin,
+ GURL(socket_url), std::move(create_helper), origin,
url_request_context_host_.GetURLRequestContext(), BoundNetLog(),
- connect_delegate.Pass(),
- timer ? timer.Pass()
+ std::move(connect_delegate),
+ timer ? std::move(timer)
: scoped_ptr<base::Timer>(new base::Timer(false, false)));
}
diff --git a/chromium/net/websockets/websocket_stream_create_test_base.h b/chromium/net/websockets/websocket_stream_create_test_base.h
index 70451ef72f2..ca4d8505713 100644
--- a/chromium/net/websockets/websocket_stream_create_test_base.h
+++ b/chromium/net/websockets/websocket_stream_create_test_base.h
@@ -9,8 +9,8 @@
#include <utility>
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "base/timer/timer.h"
#include "net/base/net_export.h"
@@ -70,7 +70,7 @@ class WebSocketStreamCreateTestBase {
scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> ssl_error_callbacks_;
SSLInfo ssl_info_;
bool ssl_fatal_;
- ScopedVector<SSLSocketDataProvider> ssl_data_;
+ std::vector<scoped_ptr<SSLSocketDataProvider>> ssl_data_;
// This temporarily sets WebSocketEndpointLockManager unlock delay to zero
// during tests.
diff --git a/chromium/net/websockets/websocket_stream_test.cc b/chromium/net/websockets/websocket_stream_test.cc
index 439304963b5..a5f5f4185e0 100644
--- a/chromium/net/websockets/websocket_stream_test.cc
+++ b/chromium/net/websockets/websocket_stream_test.cc
@@ -10,7 +10,7 @@
#include <vector>
#include "base/compiler_specific.h"
-#include "base/memory/scoped_vector.h"
+#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/statistics_recorder.h"
@@ -51,7 +51,7 @@ scoped_ptr<SequencedSocketData> BuildSocketData(
scoped_ptr<SequencedSocketData> socket_data(
new SequencedSocketData(reads, reads_count, writes, writes_count));
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
- return socket_data.Pass();
+ return socket_data;
}
// Builder for a SequencedSocketData that expects nothing. This does not
@@ -98,7 +98,7 @@ class WebSocketStreamCreateTest : public ::testing::Test,
WebSocketStandardRequest(socket_path, socket_host, origin,
extra_request_headers),
response_body);
- CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass());
+ CreateAndConnectStream(socket_url, sub_protocols, origin, std::move(timer));
}
// |extra_request_headers| and |extra_response_headers| must end in "\r\n" or
@@ -115,7 +115,7 @@ class WebSocketStreamCreateTest : public ::testing::Test,
CreateAndConnectCustomResponse(
socket_url, socket_host, socket_path, sub_protocols, origin,
extra_request_headers,
- WebSocketStandardResponse(extra_response_headers), timer.Pass());
+ WebSocketStandardResponse(extra_response_headers), std::move(timer));
}
void CreateAndConnectRawExpectations(
@@ -124,13 +124,13 @@ class WebSocketStreamCreateTest : public ::testing::Test,
const url::Origin& origin,
scoped_ptr<SequencedSocketData> socket_data,
scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) {
- AddRawExpectations(socket_data.Pass());
- CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass());
+ AddRawExpectations(std::move(socket_data));
+ CreateAndConnectStream(socket_url, sub_protocols, origin, std::move(timer));
}
// Add additional raw expectations for sockets created before the final one.
void AddRawExpectations(scoped_ptr<SequencedSocketData> socket_data) {
- url_request_context_host_.AddRawExpectations(socket_data.Pass());
+ url_request_context_host_.AddRawExpectations(std::move(socket_data));
}
};
@@ -520,7 +520,7 @@ TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) {
WaitUntilConnectDone();
ASSERT_TRUE(stream_);
- ScopedVector<WebSocketFrame> frames;
+ std::vector<scoped_ptr<WebSocketFrame>> frames;
CompletionCallback callback;
ASSERT_EQ(OK, stream_->ReadFrames(&frames, callback));
ASSERT_EQ(1U, frames.size());
@@ -804,7 +804,7 @@ TEST_F(WebSocketStreamCreateTest, ConnectionFailure) {
socket_data->set_connect_data(
MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass());
+ LocalhostOrigin(), std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED",
@@ -819,7 +819,7 @@ TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) {
socket_data->set_connect_data(
MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT));
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass());
+ LocalhostOrigin(), std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT",
@@ -833,8 +833,8 @@ TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) {
scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass(),
- timer.Pass());
+ LocalhostOrigin(), std::move(socket_data),
+ std::move(timer));
EXPECT_FALSE(has_failed());
ASSERT_TRUE(weak_timer.get());
EXPECT_TRUE(weak_timer->IsRunning());
@@ -855,7 +855,7 @@ TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) {
CreateAndConnectStandard("ws://localhost/", "localhost", "/",
NoSubProtocols(), LocalhostOrigin(), "", "",
- timer.Pass());
+ std::move(timer));
ASSERT_TRUE(weak_timer);
EXPECT_TRUE(weak_timer->IsRunning());
@@ -874,8 +874,8 @@ TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) {
scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass(),
- timer.Pass());
+ LocalhostOrigin(), std::move(socket_data),
+ std::move(timer));
ASSERT_TRUE(weak_timer.get());
EXPECT_TRUE(weak_timer->IsRunning());
@@ -892,7 +892,7 @@ TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) {
scoped_ptr<SequencedSocketData> socket_data(BuildNullSocketData());
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass());
+ LocalhostOrigin(), std::move(socket_data));
stream_request_.reset();
// WaitUntilConnectDone doesn't work in this case.
base::RunLoop().RunUntilIdle();
@@ -932,7 +932,7 @@ TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
scoped_ptr<SequencedSocketData> socket_data(BuildSocketData(reads, writes));
SequencedSocketData* socket_data_raw_ptr = socket_data.get();
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass());
+ LocalhostOrigin(), std::move(socket_data));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed());
stream_request_.reset();
@@ -973,7 +973,7 @@ TEST_F(WebSocketStreamCreateTest, NoResponse) {
scoped_ptr<SequencedSocketData> socket_data(BuildSocketData(reads, writes));
SequencedSocketData* socket_data_raw_ptr = socket_data.get();
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass());
+ LocalhostOrigin(), std::move(socket_data));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed());
EXPECT_TRUE(has_failed());
@@ -984,14 +984,15 @@ TEST_F(WebSocketStreamCreateTest, NoResponse) {
}
TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) {
- ssl_data_.push_back(
- new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
+ ssl_data_.push_back(make_scoped_ptr(
+ new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)));
ssl_data_[0]->cert =
ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
ASSERT_TRUE(ssl_data_[0]->cert.get());
scoped_ptr<SequencedSocketData> raw_socket_data(BuildNullSocketData());
CreateAndConnectRawExpectations("wss://localhost/", NoSubProtocols(),
- LocalhostOrigin(), raw_socket_data.Pass());
+ LocalhostOrigin(),
+ std::move(raw_socket_data));
// WaitUntilConnectDone doesn't work in this case.
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(has_failed());
@@ -1008,9 +1009,9 @@ TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) {
ssl_data->cert =
ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
ASSERT_TRUE(ssl_data->cert.get());
- ssl_data_.push_back(ssl_data.Pass());
+ ssl_data_.push_back(std::move(ssl_data));
ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK));
- ssl_data_.push_back(ssl_data.Pass());
+ ssl_data_.push_back(std::move(ssl_data));
url_request_context_host_.AddRawExpectations(BuildNullSocketData());
CreateAndConnectStandard("wss://localhost/", "localhost", "/",
NoSubProtocols(), LocalhostOrigin(), "", "");
@@ -1161,7 +1162,7 @@ TEST_F(WebSocketStreamCreateTest, HandleErrConnectionClosed) {
scoped_ptr<SequencedSocketData> socket_data(BuildSocketData(reads, writes));
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass());
+ LocalhostOrigin(), std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
}
@@ -1186,7 +1187,7 @@ TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) {
scoped_ptr<SequencedSocketData> socket_data(BuildSocketData(reads, writes));
url_request_context_host_.SetProxyConfig("https=proxy:8000");
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), socket_data.Pass());
+ LocalhostOrigin(), std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Establishing a tunnel via proxy server failed.",
diff --git a/chromium/net/websockets/websocket_test_util.cc b/chromium/net/websockets/websocket_test_util.cc
index fd5421a59b3..3b7ad10eb45 100644
--- a/chromium/net/websockets/websocket_test_util.cc
+++ b/chromium/net/websockets/websocket_test_util.cc
@@ -4,12 +4,11 @@
#include "net/websockets/websocket_test_util.h"
+#include <stddef.h>
#include <algorithm>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
-#include "base/memory/scoped_vector.h"
-#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/socket_test_util.h"
@@ -18,20 +17,21 @@
namespace net {
namespace {
-const uint64 kA =
- (static_cast<uint64>(0x5851f42d) << 32) + static_cast<uint64>(0x4c957f2d);
-const uint64 kC = 12345;
-const uint64 kM = static_cast<uint64>(1) << 48;
+
+const uint64_t kA = (static_cast<uint64_t>(0x5851f42d) << 32) +
+ static_cast<uint64_t>(0x4c957f2d);
+const uint64_t kC = 12345;
+const uint64_t kM = static_cast<uint64_t>(1) << 48;
} // namespace
-LinearCongruentialGenerator::LinearCongruentialGenerator(uint32 seed)
+LinearCongruentialGenerator::LinearCongruentialGenerator(uint32_t seed)
: current_(seed) {}
-uint32 LinearCongruentialGenerator::Generate() {
- uint64 result = current_;
+uint32_t LinearCongruentialGenerator::Generate() {
+ uint64_t result = current_;
current_ = (current_ * kA + kC) % kM;
- return static_cast<uint32>(result >> 16);
+ return static_cast<uint32_t>(result >> 16);
}
std::string WebSocketStandardRequest(const std::string& path,
@@ -86,8 +86,8 @@ struct WebSocketMockClientSocketFactoryMaker::Detail {
std::string return_to_read;
std::vector<MockRead> reads;
MockWrite write;
- ScopedVector<SequencedSocketData> socket_data_vector;
- ScopedVector<SSLSocketDataProvider> ssl_socket_data_vector;
+ std::vector<scoped_ptr<SequencedSocketData>> socket_data_vector;
+ std::vector<scoped_ptr<SSLSocketDataProvider>> ssl_socket_data_vector;
MockClientSocketFactory factory;
};
@@ -125,23 +125,22 @@ void WebSocketMockClientSocketFactoryMaker::SetExpectations(
kHttpStreamParserBufferSize),
sequence++));
}
- scoped_ptr<SequencedSocketData> socket_data(
- new SequencedSocketData(vector_as_array(&detail_->reads),
- detail_->reads.size(), &detail_->write, 1));
+ scoped_ptr<SequencedSocketData> socket_data(new SequencedSocketData(
+ detail_->reads.data(), detail_->reads.size(), &detail_->write, 1));
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
- AddRawExpectations(socket_data.Pass());
+ AddRawExpectations(std::move(socket_data));
}
void WebSocketMockClientSocketFactoryMaker::AddRawExpectations(
scoped_ptr<SequencedSocketData> socket_data) {
detail_->factory.AddSocketDataProvider(socket_data.get());
- detail_->socket_data_vector.push_back(socket_data.Pass());
+ detail_->socket_data_vector.push_back(std::move(socket_data));
}
void WebSocketMockClientSocketFactoryMaker::AddSSLSocketDataProvider(
scoped_ptr<SSLSocketDataProvider> ssl_socket_data) {
detail_->factory.AddSSLSocketDataProvider(ssl_socket_data.get());
- detail_->ssl_socket_data_vector.push_back(ssl_socket_data.Pass());
+ detail_->ssl_socket_data_vector.push_back(std::move(ssl_socket_data));
}
WebSocketTestURLRequestContextHost::WebSocketTestURLRequestContextHost()
@@ -153,12 +152,12 @@ WebSocketTestURLRequestContextHost::~WebSocketTestURLRequestContextHost() {}
void WebSocketTestURLRequestContextHost::AddRawExpectations(
scoped_ptr<SequencedSocketData> socket_data) {
- maker_.AddRawExpectations(socket_data.Pass());
+ maker_.AddRawExpectations(std::move(socket_data));
}
void WebSocketTestURLRequestContextHost::AddSSLSocketDataProvider(
scoped_ptr<SSLSocketDataProvider> ssl_socket_data) {
- maker_.AddSSLSocketDataProvider(ssl_socket_data.Pass());
+ maker_.AddSSLSocketDataProvider(std::move(ssl_socket_data));
}
void WebSocketTestURLRequestContextHost::SetProxyConfig(
diff --git a/chromium/net/websockets/websocket_test_util.h b/chromium/net/websockets/websocket_test_util.h
index f620f18d6b4..054c6766e74 100644
--- a/chromium/net/websockets/websocket_test_util.h
+++ b/chromium/net/websockets/websocket_test_util.h
@@ -5,9 +5,11 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
#define NET_WEBSOCKETS_WEBSOCKET_TEST_UTIL_H_
+#include <stdint.h>
+
#include <string>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/url_request/url_request_test_util.h"
#include "net/websockets/websocket_stream.h"
@@ -33,11 +35,11 @@ class URLRequestContext;
class LinearCongruentialGenerator {
public:
- explicit LinearCongruentialGenerator(uint32 seed);
- uint32 Generate();
+ explicit LinearCongruentialGenerator(uint32_t seed);
+ uint32_t Generate();
private:
- uint64 current_;
+ uint64_t current_;
};
// Generates a standard WebSocket handshake request. The challenge key used is